diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..a85e0e9ed --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +# Local volumes +/config +/data +/db + +# Updated through volumes +Server/data +Server/worldprops + +# Env files containing secrets +/.env +/*.env + +# Log files +logs +*.log + +# Git files +.git +.gitattributes +.gitignore + +# Basic stuff +*.md +LICENSE +.gitlab-ci.yml + +# Docker files +docker-compose.yml +Dockerfile diff --git a/.gitignore b/.gitignore index e1cc944e2..6ecd66985 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,8 @@ Server/data/global_kill_stats.json Server/ge_test.db Server/latestdump.txt Management-Server/managementprops/ -Server/worldprops/ +Server/worldprops/* +!Server/worldprops/default.conf **/.idea/workspace.xml **/.idea/tasks.xml @@ -32,3 +33,12 @@ gradle build/kotlin/sessions/ **/*.iml Server/hasRan.txt + +# Local volumes +/config +/data +/db + +# Env files containing secrets +/.env +/*.env diff --git a/.gitlab/.gitkeep b/.gitlab/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.gitlab/issue_templates/.gitkeep b/.gitlab/issue_templates/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.gitlab/issue_templates/Default.md b/.gitlab/issue_templates/Default.md new file mode 100644 index 000000000..051106623 --- /dev/null +++ b/.gitlab/issue_templates/Default.md @@ -0,0 +1,17 @@ +What I did: + +What I expected to happen: + +What actually happened: + +IDs of related NPCs/items: + +2009-era source (if relevant): + +Screenshots or video: + +LIVE SERVER username affected by this issue: + +**Bug reports are not accepted by SP users. SP is often out of date and results in invalid bug reports.** + +**If the bug is exploitable make sure you tick the confidential checkbox below** \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7078b8c93..5195e5bf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,14 +4,8 @@ FROM maven:3-openjdk-11-slim # Set working directory to /app WORKDIR /app -# Update apt; install git and git-lfs -RUN apt-get update && apt-get -qq -y install git git-lfs - -# Clone the 2009scape repository -RUN git clone --depth=1 https://gitlab.com/2009scape/2009scape.git - -# Fake it til you make it - let's go home -WORKDIR /app/2009scape +# Copy all sources etc +COPY . . # Make sure ./run has permissions RUN chmod +x run diff --git a/README.md b/README.md index 63fff0083..60054bcf8 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ * [Prerequisites](#prerequisites) * [Project Setup](#project-setup) * [Running the project](#running-the-project) + * [Browser WebSocket Transport](#browser-websocket-transport) * [License](#license) * [Contact](#contact) @@ -125,6 +126,112 @@ Start the game server with the included run script. Use `./run -h` for more info Start the game server with `run-server.bat` +#### Browser WebSocket Transport + +Enable the listener in `Server/worldprops/default.conf`: + +```properties +websocket_enabled = true +websocket_port = 0 +``` + +When `websocket_port = 0`, the listener uses `53594 + world_id`. For world `1`, that is `53595`. + +Both plain WebSocket (`ws://`) and secure WebSocket (`wss://`) are supported. Use `ws://` for local HTTP testing. PWA requires HTTPS/WSS. + +Enable WSS with a Java keystore: + +```properties +websocket_tls_enabled = true +websocket_tls_keystore_path = "certs/dev-wss.p12" +websocket_tls_keystore_password = "" +``` + +The keystore password is optional. Leave `websocket_tls_keystore_password` blank when using a PKCS12 file exported with an empty password: + +```bash +openssl pkcs12 -export \ + -in fullchain.pem \ + -inkey privkey.pem \ + -out certs/dev-wss.p12 \ + -name websocket \ + -passout pass: +``` + +For local WSS development, create a certificate for your hostname or LAN IP that the browser will use, then point the server at a PKCS12 keystore. For production, use a normal certificate from certbot. Plain WS does not require a certificate. + +#### Docker + +Make sure [Docker Engine](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) plugin are installed first: + +Go to the project root where the git repository is cloned into: + +```bash +cd /path/to/project-dir +``` + +To configure the database, copy the mysql env file template to a env file in the project root: + +```bash +cp mysql.env.example mysql.env +``` + +Customize the env file however necessary. + +Create a new directory called 'config' into the project root. + +```bash +mkdir config +``` + +Copy the server config file template in the config directory: + +```bash +cp Server/worldprops/default.conf config/default.conf +``` + +Edit the server configuration file as per needed. + +Go to the project root directory and execute: + +```bash +docker compose up --build +``` + +Which will build the docker image using the local Dockerfile and starts the server and database containers. + +The previous up command should be run every time the server sources are modified to propagate the changes to the container. + +For the first time, the server compilation process takes a long time. Grab some coffee in the meanwhile. + +You can check (and follow) the containers logs by running the following in the project root directory (-f for follow and Ctrl+C to stop): + +```bash +docker compose logs -f +``` + +Any compilation or runtime errors will be logged here. + +If you have already compiled the server and made no changes to the sources, you can simply run without the build option (however it will be cached anyways): + +```bash +docker compose up +``` + +To later restart the server to apply simple configuration changes, in the project root directory run: + +```bash +docker compose restart server +``` + +To shut down / take down the server, in the project root directory run: + +```bash +docker compose up --build +``` + +The database files, build cache and config files will be persisted on the host filesystem for easy backup management. + ### License We use the AGPL 3.0 license, which can be found [here](https://www.gnu.org/licenses/agpl-3.0.en.html). Please be sure to read and understand the license. Failure to follow the guidelines outlined in the license will result in legal action. If you know or hear of anyone breaking this license, please send a report, with proof, to Red Bracket#8151, ceikry#2724, or woahscam#8535 on discord or email woahscam@hotmail.com. **We WILL NOT change the license to fit your needs.** @@ -149,4 +256,4 @@ These credits can be spent in the 2009Scape Reward Shop. It's important to be cl Testers are not the only people who can gain credits - other ways of earning credits can be found on [the 2009Scape website](https://2009scape.org/site/game_guide/credits.html). -Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded. +Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded. \ No newline at end of file diff --git a/Server/.gitignore b/Server/.gitignore index f22e9f978..a9a29cad7 100644 --- a/Server/.gitignore +++ b/Server/.gitignore @@ -2,6 +2,7 @@ bin/** out/** data/logs/** data/profile/** +data/playerstats/** .idea/** /bin .DS_Store** diff --git a/Server/data/ObjectParser.xml b/Server/data/ObjectParser.xml index b10a0d445..bfd1c5167 100644 --- a/Server/data/ObjectParser.xml +++ b/Server/data/ObjectParser.xml @@ -11,7 +11,6 @@ - diff --git a/Server/data/botdata/bot_dialogue.json b/Server/data/botdata/bot_dialogue.json index 4f3a510fc..c225b117e 100644 --- a/Server/data/botdata/bot_dialogue.json +++ b/Server/data/botdata/bot_dialogue.json @@ -257,7 +257,7 @@ "What do you think @name?", "How does that sound @name?", "That sounds great @name.", - "I’m learning English.", + "I'm learning English.", "I don't understand.", "Could you repeat that please @name?", "Could you please talk slower @name?", @@ -301,7 +301,7 @@ "Always check announcments", "We thrivin", "Ship @name", - "Dont forget to vote 2009Scape!", + "Dont forget to vote 2009scape!", "Kermit is too legit 2 quit", "Out here on the range we are having fun", "I am hank steel", @@ -338,7 +338,7 @@ "I couldn't agree more @name", "It cost me a fortune @name", "I am dog tired", - "Don’t take it personally", + "Don't take it personally", "We will be having a good time", "Same as always @name", "No problem", @@ -367,33 +367,16 @@ "May Guthix bring you balance.", "May Guthix bring you balance.", "May Guthix bring you balance.", - "Thy death was not in vain, for it brought some balance to the world. May Guthix bring you rest.", - "May you walk the path, and never fall, for Guthix walks beside thee on thy journey. May Guthix bring you peace.", - "All things must end, as all begin; Only Guthix knows the role thou must play. May Guthix bring you balance.", - "In life, in death, in joy, in sorrow: May thine experience show thee balance. May Guthix bring you balance.", - "Thou must do as thou must, no matter what. Thine actions bring balance to this world. May Guthix bring you balance.", - "The river flows, the sun ignites, May you stand with Guthix in thy fights. May Guthix bring you balance.", "A journey of a single step, May take thee over a thousand miles. May Guthix bring you balance.", "Zamorak give me strength!", "Zamorak give me strength!", "Zamorak give me strength!", - "May your bloodthirst never be sated, and may all your battles be glorious. Zamorak bring you strength.", - "There is no opinion that cannot be proven true...by crushing those who choose to disagree with it. Zamorak give me strength!", - "Battles are not lost and won; They simply remove the weak from the equation. Zamorak give me strength!", - "Those who fight, then run away, shame Zamorak with their cowardice. Zamorak give me strength!", - "Battle is by those who choose to disagree with it. Zamorak give me strength!", - "Strike fast, strike hard, strike true: The strength of Zamorak will be with you. Zamorak give me strength!", "The weak deserve to die, so the strong may flourish. This is the creed of Zamorak.", "This is Saradomin's wisdom.", "This is Saradomin's wisdom.", "This is Saradomin's wisdom.", "Go in peace in the name of Saradomin; may his glory shine upon you like the sun.", "Thy cause was false, thy skills did lack; See you in Lumbridge when you get back.", - "Protect your self, protect your friends. Mine is the glory that never ends. This is Saradomin's wisdom.", - "The darkness in life may be avoided, by the light of wisdom shining. This is Saradomin's wisdom.", - "Show love to your friends, and mercy to your enemies, and know that the wisdom of Saradomin will follow. This is Saradomin's wisdom.", - "A fight begun, when the cause is just, will prevail over all others. This is Saradomin's wisdom.", - "The currency of goodness is honour; It retains its value through scarcity. This is Saradomin's wisdom.", "For Camelot!", "Firmly grasp it!", "My legs!", @@ -496,21 +479,525 @@ "Shlisshalpshlaap", "Somebody call for an exterminator?", "Decisive action. Should work.", - "R E A D Y T O R A I S E S O M E H E L L", "Darkness overpowering.", "Got any questions about propane? Or propane accessories?", "When someone asks me if I am a god, I say Y E S!!!", "You run out of Marines?", - "Goliath Online", - "I'm escaping to the one place that hasn't been corrupted by Capitalism. Lunar Isle!", "Selling wildy protection, 100k gp", - "Can’t we get you on Mastermind, @name? Next contestant – @name from Lumbridge. Special subject – the bleedin’ obvious.", - "Oh, you’re German! I’m sorry, I thought there was something wrong with you.", - "Listen, don’t mention the war! I mentioned it once, but I think I got away with it all right.", + "Can't we get you on Mastermind, @name?", + "Listen, don't mention the war! I mentioned it once, but I think I got away with it all right.", "Cunnilingus and psychiatry brought us to this.", - "Oh, poor baby. What do you want, a Brimstail's Sampler?", - "There's an old TzHarrian saying, you fuck up once, you lose two teeth.", - "The lineup consisted simply of six hydrocoptic marzelvanes so fitted to the ambifacient lunar waneshaft that sidefumbling was prevented." + "Ah, the Wilderness... where dreams of riches meet a swift demise.", + "Who needs a quest guide? I've got the whole wiki memorized.", + "Buying GF 10k coins. Must have at least 70 Agility.", + "I swear, the goblins in Goblin Village have it out for me.", + "Why do wizards always hang out in towers? Is it a zoning thing?", + "I'm training my Construction skill. My house is gonna be lit!", + "The GE is like the stock market, but with dragon bones.", + "Why do we need a cabbage patch in Draynor? Seriously.", + "I've been mining rune essence for hours. My pickaxe hates me.", + "@name hit 99 Cooking. Time to open a gourmet restaurant in Varrock.", + "I'm convinced the @name is actually a time-traveling wizard.", + "Anyone up for a Castle Wars match? I need that decorative armor.", + "Accidentally clicked Attack on a guard. Now I'm a wanted criminal.", + "Why do we even have a Duel Arena? It's just a fancy boxing ring.", + "I've got a stack of burnt lobsters. Anyone want to buy them?", + "Greetings, @name! Looking for a quest?", + "Just got a rare drop! The RNG gods are smiling upon me!", + "Anyone need help with a boss fight? I've got my dragon dagger ready.", + "Buying feathers! Will pay top price!", + "The Lumbridge cows are my favorite training spot.", + "Who needs a teleport? I've got my magic runes stocked.", + "@name hit 99 Woodcutting. Time to chop some yews!", + "Anyone seen the Wise Old Man lately? I owe him a visit.", + "Selling lobsters! Freshly caught from Catherby.", + "Swear, the Wilderness is scarier than my nightmares.", + "Looking for a clan to join. Any takers?", + "I'm an ironman, so no trading for me!", + "Anyone up for a Castle Wars match?", + "The Grand Exchange prices are crashing. Panic sell!", + "Who else remembers the Falador Massacre?", + "I'm saving up for a party hat. Wish me luck!", + "Barrows runs are my addiction. Those crypts are spooky.", + "I'm convinced the Wise Old Man is secretly Zamorak.", + "I'm a completionist, so I'm grinding out all the achievements.", + "The music in this game is surprisingly epic.", + "Tried to trade with a tree... It didn't go well.", + "My bank is like a black hole. Items disappear forever.", + "I'm convinced the Wise Old Man is just a confused tourist.", + "My character's fashion sense? Let's just say it's 'unique.'", + "Challenged a cow to a dance-off. It won.", + "Why does the Lumbridge Guide always look so lost?", + "I'm training Agility, but my real-life agility is zero.", + "Tried to fish in the desert. Sandfish are elusive.", + "The Grand Exchange is like a chaotic stock market.", + "I'm a master at clicking 'Continue' during quests.", + "I'm convinced the chickens are plotting world domination.", + "I'm a woodcutter, but I've never seen a talking tree.", + "I'm a vegetarian, except when it comes to killing dragons.", + "Why do wizards wear pointy hats? Is it a fashion statement?", + "Challenged a guard to a staring contest. He won.", + "I'm collecting cabbage. It's a noble pursuit.", + "Accidentally set my cat on fire. It's now a firecat.", + "I'm convinced the Wise Old Man is secretly a time traveler.", + "I'm a quest completionist, but I still can't find my keys.", + "I'm convinced the ducks are spying on us.", + "I'm a pro at avoiding the Lumbridge swamp. Too many frogs.", + "Hey, can someone lend me 10k? I promise I'll pay it back... eventually.", + "Why do I always find the one square where the random event spawns?", + "I'm training Prayer by burying bones. It's like a spiritual workout.", + "The Wise Old Man's fashion sense is questionable.", + "I'm convinced the ducks are secretly plotting world domination.", + "Why do wizards wear pointy hats? Is it a dress code?", + "I'm collecting cabbage. It's a noble pursuit, really.", + "I'm a vegetarian, except when it comes to killing dragons.", + "Why does the Lumbridge Guide always look so lost?", + "Training Agility, but my real-life agility is zero.", + "I'm convinced the Wise Old Man is secretly a time traveler.", + "Tried to mine air. It's an untapped resource.", + "I'm a quest completionist, but I still can't find my keys.", + "Challenged a guard to a staring contest. He won.", + "I'm saving up for a party hat. Priorities, you know?", + "Why do goblins drop coins? Do they moonlight as accountants?", + "I'm convinced the chickens are plotting something.", + "Clicked 'Attack' on a chicken. Now I'm a poultry murderer.", + "My character's fashion sense? Let's just say it's 'unique.'", + "Do you know where I can find the entrance to the Taverley Dungeon?", + "Hey, anyone here familiar with the Barrows? I need some tips.", + "Is there a bank nearby? My inventory is overflowing with loot", + "I'm clueless about clue scrolls", + "Where's the best spot to catch sharks? I'm aiming for 99 Fishing.", + "Is there a shortcut to the Karamja Volcano?", + "Can someone explain the mechanics of the Jad fight in the Fight Caves?", + "I'm stuck on the Elemental Workshop quest. Any hints?", + "Where can I find a loom to spin flax into bowstrings?", + "What's the best gear setup for killing dragons? I want that visage drop!", + "I'm trying to unlock the fairy rings", + "How do I recharge my amulet of glory?", + "Why do goblins drop coins?", + "The Grand Exchange is like the stock market", + "My real-life agility is more like a lumbering tortoise.", + "The Wise Old Man's fashion sense is like Woahs", + "I challenged a cow to a dance off, surprisingly smooth mooves.", + "Why does the Lumbridge Guide always look lost?", + "I'm convinced the ducks in Lumbridge are plotting world domination!", + "I accidentally ate my prayer potion I'm blessed with heartburn", + "I'm a vegetarian, except when it comes to slaying dragons.", + "Why do wizards wear pointy hats? Is it a magical dress code?", + "I'm a quest completionist, but I still can't find my keys in real life.", + "I challenged a guard to a staring contest. He won.", + "I'm saving up for a party hat. Priorities, ya know?", + "What's the deal with the Wilderness?", + "I'm convinced the chickens are secretly plotting world domination!", + "Accidentally clicked 'Attack' on a guard. Now I'm on a watchlist.", + "My character's fashion sense? Let's just say it's 'unique'", + "Lobsters heal my soul", + "Trimmed armor or bust!", + "Wilderness: Where friendships go to die", + "Buying gf 10k", + "Dancing for coins at Lumbridge", + "Wearing full rune like a boss", + "Teleporting to Camelot for quests", + "Fishing for hours at Catherby", + "PKing with a rune 2h", + "World 1 Falador Park parties", + "Staking my bank at the Duel Arena", + "Dying to Elvarg's fiery breath sums up my life", + "Got the Quest cape finally on my main!", + "Wearing a party hat with pride", + "Castle Wars: Red vs Blue", + "Trading in Varrock Square", + "Barrows runs for that sweet loot", + "Spending hours in Pest Control is life", + "Killing cows for leather armor is a good start", + "Farming herbs in Ardougne can be good money", + "Clan chat drama LOL", + "Mining rune essence endlessly", + "Agility courses: A love-hate relationship", + "Dueling for honor.... and GP", + "Buying runes from Aubury is decent money", + "Chasing the Easter Bunny like a scam", + "Wearing a skillcape with pride", + "Fletching yew longbows for profit", + "Going to implings in Puro-Puro", + "Castle Wars barricade wars", + "Dropping party hats at drop parties like pennies", + "Killing lesser demons in Karamja is part of my holy conquest", + "@name lures noobs into the Wilderness", + "Farming ranarrs for cash", + "Getting lost in the Underground Pass", + "Selling coal at the Grand Exchange", + "Fighting the Kalphite Queen", + "Picking flax in Seers' Village", + "Begging for free stuff in Lumbridge", + "Smithing rune platebodies for profit", + "Logging out in Lumbridge Castle", + "Hey @name, how do I get to the Grand Exchange?", + "Veteran here! @name, what's your favorite quest?", + "@name, how do I make money fast?", + "Hey @name, what's the best combat style for bossing?", + "@name, always carry an emergency teleport!", + "New player here! @name, what's the Wilderness like?", + "Hey @name, how do I join a clan?", + "@name, prioritize Prayer levels!", + "@name, what's the best way to train Agility?", + "Hey @name, what's your favorite minigame?", + "@name, never trust a PKer in Lumbridge!", + "@name, how do I get a fire cape?", + "Hey @name, what's the fastest way to level up Magic?", + "@name, try the Barrows tunnels!", + "@name, what's the deal with Pest Control?", + "Hey @name, how do I unlock the Fairy Rings?", + "@name, remember the old random events?", + "@name, should I train Strength or Attack first?", + "Hey @name, what's your favorite skillcape?", + "@name, can't do the Fight Caves!", + "@name, how do I get a pet?", + "Hey @name, what's the best food for boss fights?", + "@name, Castle Wars or Clan Wars?", + "@name, what's a clue scroll?", + "Hey @name, how do I defeat Jad?", + "@name, use Protect from Melee at KBD!", + "@name, should I train Ranged or Magic?", + "Hey @name, what's the best way to level up Crafting?", + "@name, don't forget your anti-dragon shield!", + "@name, what's the Stronghold of Security?", + "Hey @name, how do I access the Legends' Guild?", + "@name, remember the old PvP worlds?", + "@name, how do I get a dragon defender?", + "Hey @name, what's the best way to level up Herblore?", + "@name, always carry a charged amulet of glory!", + "@name, should I train Fishing or Cooking?", + "Hey @name, how do I defeat the Chaos Elemental?", + "@name, try the TzHaar Fight Pit!", + "@name, what's the best way to level up Smithing?", + "Hey @name, what's your favorite Slayer master?", + "@name, use the Ardougne cloak teleports!", + "@name, what's the Legends' Quest about?", + "Hey @name, how do I unlock the Ancient Magicks?", + "@name, remember the old Pest Control boats?", + "@name, what's the best way to level up Construction?", + "Hey @name, what's the fastest way to level up Prayer?", + "@name, the old Duel Arena stakes!", + "@name, what's the Warriors' Guild?", + "Hey @name, how do I defeat the Kalphite Queen?", + "@name, use the fairy ring code BIP!", + "@name, should I train Attack or Defense first?", + "Hey @name, what's the best way to level up Thieving?", + "@name, don't forget your charged glory amulet!", + "@name, what's the Legends' Cape?", + "Hey @name, how do I access the Heroes' Guild?", + "@name, remember the old Pest Control void gear?", + "@name, how do I get a firemaking skillcape?", + "Buying gf 10k", + "Trimming armor for free!", + "Wanna join my clan? We're called The Mighty Cabbages'!", + "I'll meet you at the Falador Party Room!", + "Dancing for coins in Varrock Square!", + "Remember when the Wilderness was dangerous?", + "I got a rune scimitar drop from Lesser Demons!", + "Lumbridge Swamp is haunted!", + "Anyone up for Castle Wars?", + "I miss the old random events!", + "World 2 is the trading hub!", + "I'm going to train my Agility at the Gnome Stronghold!", + "I just got 99 Cooking!", + "Fishing lobsters at Catherby is life!", + "The Legends' Guild is so exclusive!", + "Who needs a quest guide? I'll figure it out!", + "I'm mining rune essence for hours!", + "Barrows armor looks sick!", + "I'm stuck in the Underground Pass!", + "The Stronghold of Security taught me about account security!", + "I'm going to farm herbs in Ardougne!", + "I'm getting my fire cape!", + "I love the music in RuneScape!", + "I'm alching my maple longbows!", + "I'm doing the Recipe for Disaster subquests!", + "I'm going to train my combat stats at the Rock Crabs!", + "I'm going for the Quest Cape!", + "I'm going to mine pure essence!", + "I'm hunting chinchompas in the Feldip Hills!", + "I'm going to train my Woodcutting at Seers' Village!", + "I'm going to fish sharks at the Fishing Guild!", + "I'm going to train my Thieving at Ardougne Knights!", + "I'm going to hunt implings in Puro-Puro!", + "I'm going to train my Hunter at the Falconry!", + "I'm smithing rune platebodies!", + "I'm going to train my Farming at the Tree Gnome Stronghold!", + "I'm going to hunt red chinchompas in the Wilderness!", + "I'm doing the Underground Pass quest!", + "I'm going to fish monkfish in Piscatoris!", + "Meet me in Varrock, @name, for an epic trade", + "@name, join my clan; we'll conquer the Wilderness together!", + "Beware the dragons, @name, they're fiercer than you think", + "Crafting runes with @name, the best mage in Gielinor", + "Fishing lobsters with @name, the sea's no match for us", + "@name, your swordsmanship at Duel Arena is unmatched!", + "Questing through dark caves, @name always leads the way", + "Share your wisdom, @name, how'd you master those spells?", + "Legends speak of @name bravery at the God Wars", + "Need more arrows, @name? I've got plenty to spare", + "Cooking's a breeze when @name around, no burnt lobsters!", + "Mining together, @name and I strike gold every time", + "@name, let's barter; your herbs for my potions?", + "Training agility with @name, leaping like graceful gazelles", + "Heard @name got the best magic beans in town", + "Fletching bows with @name, aiming for perfection", + "Smithing with @name, our anvils never cool down", + "Adventuring with @name, every quest is a thrill", + "Battling demons, @name courage inspires us all", + "Slaying dragons, @name the hero we need", + "Gathering at Falador, @name party room is legendary", + "Hunting chinchompas, @name traps are always full", + "Farming's fun with @name, our crops never fail", + "Brewing potions, @name mixtures are magical", + "Casting spells with @name, we're invincible", + "Building fires, @name flames warm the coldest nights", + "Sailing to Pest Control, @name our fearless captain", + "Trading runes, @name deals are the fairest", + "Exploring dungeons, @name the light in the darkness", + "Charging orbs with @name, our energy knows no bounds", + "Dancing in Draynor, @name moves are enchanting", + "Playing Gnomeball, @name the star player", + "Harvesting willows, @name axe swings true", + "Enchanting jewelry, @name touch turns copper to gold", + "Summoning familiars, @name spirit wolf leads the pack", + "Thieving from stalls, @name hands are lightning-fast", + "Crafting runes, @name essence never runs dry", + "Fishing at Catherby, @name catch feeds us all", + "Cooking feasts, @name dishes delight the gods", + "Mining runite, @name pickaxe strikes rich veins", + "Bartering at Grand Exchange, @name a trading master", + "Training prayer, @name piety moves mountains", + "Fighting revenants, @name valor shines bright", + "Building homes, @name construction is flawless", + "Hunting imps, @name net is always full", + "Brewing ale, @name tavern is the town's favorite", + "Casting high alchemy, @name turns junk into treasure", + "Sailing to Karamja, @name adventures are legendary", + "Forging alliances, @name charisma unites clans", + "Defeating bosses, @name name echoes in legends", + "Are you mewing @name???", + "Check out that gyatt @name", + "Bruhhhhh @name got that rizz", + "@name rizzing up the bots", + "Ironman? More like copperboy LOL", + "What that gyatt do @name", + "He's got the zoomies!", + "@name likes pickles and dipped in mayo", + "Lmaaooooooo", + "Bruh she said she loved me...", + "I caught @name rizzing a mewing teacher", + "What that mouth do bb", + "Ayo tf he say", + "Ayo", + "Ayo @name a freak lowkey", + "Ayo tf", + "@name catch me outside howbout that", + "Wasssssuuuuppppppp", + "Knock knock @name", + "Oh boy howdy do i have a surprise for you", + "Noooooo", + "What do you mean I haven't done anything wtf", + "Redrocket redrocket!!!", + "I made 20,000 crochet sock puppets for ceikry", + "Come on @name", + "Are we rading tonight @name?", + "Why would he say that", + "Penguins are technically reptiles", + "Brb smell something burning", + "Need pest control partner, you handle the portals, i will afk", + "Bruhhhh the skibiddi rizz in my gyatt makes my mewing sesh rough", + "@name jajajajaja", + "Wait, I can't raid tonight @name", + "Brb, pizza's here. Hope they ask why I'm a grown man dressed like an elf", + "Sorry, gotta go AFK. My dog just ate my gaming headset.", + "Brb, my grandma just fell down the stairs", + "Hold on, the baby's crying, aka @name", + "Oops, spilled my drink", + "Guys, I need to log off, my plants are staging a revolt for not watering them", + "AFK a sec, my neighbor's llama is in my backyard again", + "My pizza rolls are ready", + "Lost track of time, i'm late for my own wedding", + "Sorry, can't hear you over the sound of my laundry", + "Turn HDR off in windows @name", + "Www. no one cares .com", + "Hey @name www dot stfu dot com", + "Like pitching a tent in a pair of britches", + "Mad as a bag of ferrets", + "I dont think beavers built the hoover dam", + "How do beavers get the concrete for dams?", + "@name show me the way", + "@name onwards brutha", + "@name eats fried rat tails", + "@name is a rat", + "Why are there so many people farming right now", + "@name fuck the police", + "@name says the like pickles on their hotdogs", + "Fuck the guards, free woah in varrock prison", + "Ayo fuck u mean", + "Woop woop thats da sound of the beast", + "How are you the way that you are", + "She sells seashells by the sea shore", + "@name certified rat", + "@name buys skimmed milk", + "Got milk?", + "Are you JSON because i want you to get array from me", + "@name likes string manipulation", + "@name sells legos", + "JUST DO IT", + "Why are there so many motherfucking options", + "Just hit the fucking auto hide thing", + "Just play", + "Hell no this shit is fuzzy as balls", + "@name is fuzzy as balls", + "Turn your brightness up @name", + "On my pc it runs perfectly", + "I know why mine seems a little jumpy", + "Stream the window not the monitor", + "Discords a bitch", + "Why are there so many handsome people at the ge like @name", + "I'll make you squeel of fortune", + "You will get it in due time @name", + "I was one turn away", + "It do be pipe time @name", + "Sometimes i like to cover myself in vaseline and pretend i'm a slug", + "Woah is a greased pig", + "Sometimes i dig holes in my backyard and pretend i'm a carrot", + "It's pipe time @name", + "If i am not pipe timing i am programming", + "Yes i have thigh high socks, no you cannot have them", + "I scream when i wear my programming socks", + "Anyone wanna buy @name's bathwater?", + "Anyone wanna buy my used socks?", + "@name be getting bags", + "What the fuck is this", + "Hi i noticed you haven't taken a break in hours @name", + "I really am seething rn", + "I am so fucking tilted", + "Go back to your fucking frogs", + "Life is simple as frog farmer", + "A q p", + "Oooooh that's a first", + "Been a minute @name", + "Hey @name", + "Oh shit it's @name", + "Hey @name wyd today?", + "Ayo @name", + "Wyd @name", + "Wbu @name?", + "Good fuck em, that's what they get", + "Deathknight lookin rat ass mf @name", + "@name sucks slugs", + "Brb gotta take a shit", + "@name will brb went to take a shit", + "Tell me when he is coming", + "This guy is being incredibly based", + "@name is based af", + "Taking l's all day today @name", + "That sucks massive dongus", + "Ah i was about to type that", + "Where is stormwind?", + "How do i buy gold", + "@name sells gold", + "@name is a gold digger", + "Ayo @name wanna buy some frog legs?", + "Brb fucking burnt my pizza rolls", + "I swear @name if you need roll again", + "@name you are a hunter you don't need plate armor", + "Dragonriding is satisfying", + "There's an old TzHarrian saying, you fuck up once, you lose two teeth", + "FUCK", + "@name i am ready when you are", + "Anyone selling logs?", + "That is hilarious @name", + "Alright @name", + "I need to go get my quest cape", + "500 barrows runs dry", + "Back to back to back barrows items, easy game", + "@name did you know them?", + "@name sucks eggs", + "@name eats snails", + "Who is that?", + "I've gotta go in 20 minutes", + "Bonk", + "Gtg in 30 minutes", + "They left 50 minutes ago", + "I think it's just gonna be us", + "Who is that?", + "Stop following me", + "@name stop following me", + "I think @name is watching me", + "@name wouldn't let me get a hit in at clan wars", + "Clan wars and chill?", + "Quick mewing sesh", + "Don't you stickbug me", + "Get stick bugged", + "Wtf why are you a dragon", + "Fun fact, woah eats eggs whole like a snake", + "Ceikys there's a rare over there", + "Where is goldshire?", + "How long have you played @name?", + "Wanna quest?", + "TROGDORRRRRR", + "Fuck this shit i'm out", + "Wait till you get your first 99", + "How is that even possible", + "That's the max", + "@name is trying to max", + "Complesionist cape?", + "How can you increase your run speed?", + "@name where is barrows?", + "@name where are rune rocks?", + "@name where is yanille?", + "@name how long have you played for?", + "Yes these quotes were hand typed", + "Kermit was here", + "World of Warcraft died after Wrath", + "Ceikry needs to add talent trees", + "How do you get to the wilderness?", + "Anyone tryna lure @name?", + "@name tried to lure me", + "@name bots all the time", + "Anyone want chicken tendies", + "Brb foods ready", + "Brb", + "Gotta go get food", + "Anyone else from northern alaska?", + "Fishing 4 gp", + "Looking for gf", + "Anyone wanna be my discord kitten?", + "Selling discord kittens", + "@name is a discord kitten", + "Add me on discord", + "Are you in the 09discord", + "Where are you going @name?", + "Idk what i am going to cook today", + "What should i eat tonight", + "He is in the cave", + "Don't forget to save game before logging out", + "American horror story died after season 1", + "Prequels are better than the sequels", + "Disney star wars is the best star wars", + "Halo 5 sucked", + "Selling xbox live gold and 1600 microsoft points for 50k gp", + "Buying gf 25gp and a bucket", + "@name i heard evilwaffles bots", + "@name hopefully ceikry doesn't find out about evilwaffles", + "Honk honk", + "Where is the road to mordor?", + "Golem lookin ass bitch", + "@name rat looking mf", + "@name uses sand paper to wipe", + "@name said Woah is cute", + "You need 25 of 40 to do that", + "Over 1000 unique lines of dialogue", + "What should i get to eat", + "Ge be poppin today", + "Where all the woahs at", + "Ayo woahscam got that gyatt", + "That is one i haven't seen before" ], "halloween": [ "Trick or treat!!!", @@ -521,9 +1008,9 @@ "Costume party at my P O H!! Follow me!", "Trick, then!", "Brrrainssssssss...", - "'Cause this is thriller, thriller night, and no one's gonna save you from the beast about to strike!", - "This is Hallowe'en, this is Hallowe'en, pumpkins scream in the dead of night!", - "This is Hallowe'en, everybody make a scene, Trick or treat till the neighbors gonna die of fright!", + "'Cause this is thriller, thriller night!", + "This is Hallowe'en, this is Hallowe'en!", + "This is Hallowe'en, everybody make a scene!", "In this town we call home, everyone hail to the pumpkin song!", "Watch out for Skeleton Jack!", "The headless-what-man? Horse? Never heard of those.", diff --git a/Server/data/botdata/botnames.txt b/Server/data/botdata/botnames.txt index 3024122cc..22c5715a8 100644 --- a/Server/data/botdata/botnames.txt +++ b/Server/data/botdata/botnames.txt @@ -1,766 +1,1992 @@ +-Kevo +0 S O +0 4 1 1 +0 4 7 +0 HBK 0 +0 Khan 0 +0 LM +0 Quest Ptz +0 Undead 532 +0 hits +0 s m a n +0-0000000000 +00 zarour 00 +000eggs +004 n +007 Double O +007Banshee +00eeeee58 +00eeeeeHC +00oo00oo00z +010elpibexx0 014ankh 01690 +017Lucas 01Ares +01eon +01ogre 020893 024elyograG +02RS +02homestar +031 +0315 0416347345 +054 +055027584 +05miller5 05venom04 +06 59 0600 +06sz +07 Account +07 Adept +07 Ashley +07 Clinton +07 Ezra +07 Gizzy +07 Main +07 Nihilist +07 Officer +07 Rz +07 Sicario +07 T Bone +07 iron +07 kiero X +07 nice jake +070623 +07Ashley +07Ben +07Geno +07Jack +07Lax +07Panda +07Paul +07RS Suck +07Rockysbudy +07coco +07guthix07 +07wan +080 +0800 +0800952449 +0837 +09 +0920 09Ash 09Ashley 09Ato09 09Chris 09Dans 09Paul +09Reaper +09Rhys +09Rvape 09Skillerino 09TroyScape 09milo456 09scaping 09wan -0800 -0837 -0920 0BAMA +0Behind0You0 0CdanC0 +0G 0GCore 0Giesel42O +0IIll0llIIII +0JL 0Joker0 +0KAT 0LKI +0MEGA PVM +0MG ST3PSIS +0MW2PVM +0Manbearpig0 +0MrJ +0PC +0Pwnseason +0S Iluvatar +0SFX 0Tempest0 +0WEK 0X010 +0_BADASS_0 0anabanthis0 0bD0G 0bankspace 0bby +0bby Man 0belix +0bscure0ne +0ctopus +0dds r u win +0desza 0dexy 0dyssey +0ff Task 0ffline 0g_player +0gden 0ggyy +0gie +0h Hi Mark +0h4Sure +0hh 0hmMyGod +0hp +0im2old4this 0inke +0k +0l +0l m +0ld Mate +0leaguespace +0li 0livers 0livias +0lki +0llieNorth +0llies +0lmet +0lofmeister 0lurker0 0mfgcows +0mg A Baboon +0mg A Scimmy 0miseGo 0mnisciens +0n Time 0nMyWay2Max +0na +0nenonen 0neski 0netruememe 0niichan 0njon +0nlyClouds +0nmy 0ops 0oqs 0pSe 0pen +0pen Al +0pi ates 0pportunity 0riole 0rjan +0rl +0rnstein 0rphaned 0samaBdabbin +0sc4r 0smasher0 +0so 0ssimpwner +0syb +0t 0taku +0taylor +0verHyped 0verdrinking 0verhaul +0vershield 0viBeSo 0vyy +0wnag3s +0wnage_2017 0wnagedaddy 0wned 0wns +0wnu1h1t +0x Good x0 +0x05 +0xBitcoin 0xocube +0xp Fail 0xygen +1 +1 0 1 0 +1 1 4 +1 2 2 +1 337 +1 3s +1 4 11 +1 54 +1 9 7 +1 A M O R +1 A N D 1 +1 Account +1 Corin 6 9 +1 DC +1 Flicki Boi +1 Free Ryde +1 Ham +1 K0 Is Back +1 Line +1 Lion Tell +1 P P 1 +1 Percent +1 Waffle +1 and only +1 is ln of e +1 kc 1 pet +1 parhaista +1 s t Blood +1-800DILLDOE +1-GrayStone +10 Four +100 Duke 1000 Antz +1000 Eyes +1000 Ways 10000Fists 1000PingOnly 100Cl 100Grabb 100g 100kyews +100m gp 100xcoin +101000101010 +1017Trev 101e 101evil101 +101rootbeer +104512 +105 107M 1085 1099s +10Hz +10R80 +10b +10cc +10lachs +10mm mafia +10th Reaper 10v10 10v10v +10v10v10v +10x Brew +1101953119 +1111 +11111111111d 111fishkite1 +112OceanAve +116 +116 123 1183kenny +118s 11inchlimp 11l1 +12 +12 49 +12 XP +12 hours 120u 1212ajs2 +123 Zeus +123456205 +123Four 123bear5 +123tseemijni 1272172 +1288 12bar 12bar_ty +12blackeagle 12boo8 12earlycob +12in +12millionGP +12oss 12oz 12th +13 37 +13 Daas 1300 130SS 130rk 1312AFCA +1313 +131kg +1337 af +1337Trevor 1350 138hans +13D 13LACK0N3 +13O 13alerion +13ayek +13ehh 13ert1 13ig 13igdog +13kc Corp +13oneZ 13purecs +13ruce +13th Witness +14 wides 1400 +14060M +144 1441 +144forever +1453 FSM 149122089147 +14Fre-e +14GT 14Words +15 min Break +150 kilos 1520sedgwick +15b name +15mg +16 Fly Tell +16 Fps 1602 +16bumpysnow 16lB 16le +17 76 +170 IQ 17222 +1780 17Kc 17_FLHXS +17rune2277 +18 Or Older +18 Points +18 girlll +18-06-2022 x 1800BetsOff 1802M 180555 +181 1817 1827 1845 184910381412 +187 +187 781 1877 187PIGMORGUE 187er +1889 18cast1935 18hr 18killz +18s +19 KAPLAN 05 19088ml 1942 1948 +199 1992 1994 19O7 +19edgebee +19puxx +1AB +1After909 1Alfa 1Ali1Plane 1BGP 1Bio 1Buck1Love +1C2R +1C3 W4RR10R 1CuteBot 1Fbs +1G1D +1GramIronMan 1Hit2Lum 1Hunnid +1I1I1IIll1l +1InchWalrus +1Iron Reborn 1Kyle +1Lank 1ManGangBang +1Mayze +1NANO +1NU 1Nikolai +1Nut Dude +1O1Barz +1Ogp +1P Game +1Parthannax2 +1RlE +1ST KC +1Shadow9Fist 1Shark +1Stunner ISU +1Swan 1TapDirtNap 1Tick +1Tick 2 Slow 1TickShit +1Unforgiven8 +1_BLEED_BLUE +1ars 1badprogram +1bankingnoob 1blackhawk17 +1blk eye r2 1cooking 1da5 +1dan2 1day +1day iwas pk 1eat 1einad +1eyeNinja +1god max1 1grootfeest 1hundrednite +1imp1jar 1isa +1itemtbow 1jbone 1john +1k no zik +1kDuramax +1kMaster QXD 1k_0 +1kc myself 1kctobpet 1kill3dsanta 1kk3 +1kkc 1kona 1llmatic +1llusionss +1mforest +1nOnlyBigB 1nVaSioN +1ndy +1ne life 1nfiniti 1nsane str5 1nv1s +1nvercargill +1o 8 +1ocation +1please 1powerhydra +1r0nRyan 1rock23 1savage +1st Frans +1st ed mint +1st son 1stHCwasPKED 1stlrfan 1stnoob7 +1t8w 1tapaturma 1tickspecwep 1trueMortyy +1ucif3ro +1v1d a sedan 1w1lll0se 1wayEscape +1wwdwd2e21ed 1yfe +1zet +2 0 1 4 +2 1Savage +2 2 7 7 +2 2 8 9 +2 3 7 5 +2 9 +2 Big tities +2 Brothers +2 Much Tuna +2 P A C +2 Rich 4 Dis +2 Silent 540 +2 Smooth +2 ball cane +2 funny bro +2 grls 1 Jad 2 h p +2 in +2 kups +2 lN +2 more min +20 20 vision +20 Agi irl +20 On Pump 3 +200 +200 Cook 2000 +2001Arwen 2006nope +2007scape +2008Anthony 2009Anthony +200MXP Cook +200m for Olm +200mDefence +200marchalt 200mslay1day 2011Turmoil +2013 Rt +20130406655 +20136 +2027Parzival +202o2 +204 Wootang +205alphago +208 209th 20Four 20I0 20JuanSavag3 +20ms +21 5 +21 Average +21 Musketeer +21 Savage +2137 gp +215O +2173 +21JJ 21SavageX2C +21unit +22 69 +22 Geese +22 Gz +22 darnoc 22 +22 day fury 220mg +226559 +227 7 2277 +2277 Beast +2277 Soon TM +2277MaybeNvr +2277kg +22O5 +22X7 22btc 22harry +22mario 22whitewolf +23 x 3 232o2oo +234071973416 +23463564 +235iii6i666i +2376Total +2376ed 23847239571 23CD +23I +23coalcare +24 Hour 24000 +241 241196 +2424 +245 +247 365 +2488 24YO 24l7 +24w +25 S 25simulator +26 th 260sheepdog +265344626546 +26ll98 26pandas 26th +27 5 +27 M +271MPN 27ml 2841280 28BagsOfSalt 28goldpieces 290x +29384652 2996 +29Pons30 29enchant821 29robdead +2B Nier +2Broke4Coke +2C-T-2 +2D E F2 +2D pantsut 2Edgy4Meme 2Far 2Fast2Fuego 2GIRLS +2GLE 2Girls +2Goblins1Jug 2Guys1Wyvern 2Guys1dds 2I40 +2InchLift 2InchPnisher +2JZ GTE +2JZ Soup +2JZ-GTE Mk4 +2Jerry 2Lit 2M0X1 2MIN 2Men 2MinNoodles +2O xp +2O07 2OO7 +2QC +2Rare2Die 2Secs 2Sparks 2TH3MAX +2Tbows51Kc 2Tits +2TonHoneyBun +2VX +2amtossedher 2anmlsglued 2beFrank +2buttedgoat 2cbrein 2coldkillaa 2cool4u +2cythe +2d irl 2danny1 2dslap +2fastkilzz 2g0ds1cup 2girls1Kyle +2girls1Tbow 2girls1bed 2girls1troll 2girlz1jbird 2gurls1tick +2h ur azzzzz 2hopp +2hot2touch +2hot2touch2 +2hs +2id 2kav +2late2team +2logx +2nd Marksman +2nd Max Cape +2nd Sucks 2ndpanz 2olon 2oul 2pac 2pacs +2plush +2sm0keyyyyyy +2steps 2th7 2tickin 2tti 2two77 +2uBz 2ual 2ugi 2woke 2x92is99 +2ze 2zick1zussy +3 Hit V +3 5 P +3 50 +3 77 +3 Moons +3 S I X E S +3 SwordStyle +3 T C +3 arcanes ty +3 me0 3-age +30 yo b00mer +300m MPS +3019 30FF 30SHOTFOCUS +30XY +30thNovember 30zl +311s +3155 +315lbs 315squatreps +3160 316Austin +32 kay 320m +33 Dust Cat 335K +33jf 33zero2 +3400 341all +34241245321 345138 +34HL6432G6L2 +34T 34rj394thgro 351329 +35ankoumoon +35cm bicep +360 Labels +360backhand +365 day +369x +36ACT 36answersay +379 37Kg +37kg +381N 38CoolestMan 38drivelift +39 PETS 3BigDoobie +3D AnimeTits +3D Dorito +3E8 +3G 3III 3L1QZaD +3LetterName 3Miller3 3TicYaMum +3TickEat 3Ticks +3WordName +3a B0ng 3aly 3amf +3arbeed +3ash 3awe +3b 3bay 3bobyshmurda +3d age boots +3d354 3dderino 3erzerk +3h scimitar 3ibal0e9 3inchsoft +3ioc 3iron5u +3km +3lPatron +3lack 3litz 3lilbirbs 3lit3 3liteSupreme 3lven +3lyrie 3lys +3niZ 3nosedmonkey 3nps 3oh5 3pic 3ragesave +3rd Age Ryan +3rd Age THC +3rd Age Toes +3rd Age Wife +3rd Hunter +3rd Mage Owl +3rd X +3rdAgeHolds +3rdAgeHunt 3rdAgeSlayer +3rdMistake +3sd +3sl 3stripe +3uck +3uzi +3verD3ad 3vil +3vil Giraffe +3vil Lawyer +3we 3x3i 3xDestroyer +3xtra-1arge 3yes +3zR +3zi +4 Bros Info +4 Man Nex +4 inch demon +4 inches now +40 IQ +400L +400s +403 b +40699 Crabs 40Atk 40ms 40oz +412087542131 +413 JokeR +416MiIf Jade +41O +42 Mime 2462 +42 Reasons +42 skankhunt +420 Perkele +420 Sam +420 kc +420 lobster +420-2-Day 420Arch420 420Every +420Hellz 420LavarBall +420Pixels +420cyguy +420licious 420michael13 420tarmslyng +42342343342 +42Def 42O42O 42nd +432andone 43technetium +44 bot +4400 +44444444444 +45 fail +4500c +4564 +457 45smith2345 478k +47an 47th +48H +48hour +49 r +492117837813 +49forcerage +4ALLYaYa03 4D Entity 4EverAlone +4HeadScape 4Hymnz +4IQ Idiot +4K MrKrabs +4KT Youngboy 4Kath +4L O K O +4LDO 4LeafCIover +4Lt Goon Bag 4MoistScoops +4Nick8 +4STER 4Sale399 +4TheGalaxy 4The_Horde 4Tune +4V2Coldplay +4_Th3_mAiN +4are 4asphalt4 4biddin3 4cof 4dan2 +4dapigs 4dosemonster 4ever 4everdry +4got2pull0ut 4gottenvoid +4hQ +4hit pl0x 4holyhydra +4iend 4lex4nder +4litraa 4mag1996 4otobemaG +4pf PvM Lao +4pf danaw1te 4plate +4rKsTon3 +4sen +4th lesson +4th8 4the 4themininoob 4thunderbolt +4ur Elise +4werty4 +5 56 +5 Nine +5 Oh +5 mil +5 ms +5-Bet Fold +50 DKP Minus +500 BJ +5000men4 +505 +50Dkp_Minus +50TintenUwMa 50bitsnka +510 51Highlander 51xp +528racklover +5304 +530pm +53R10U5 53m0g +54 Slayer +548 55mg +562 5639 56667 56771910 +56O 570215 +5771 +57tallfred +57wraith2076 +5876 58th 59OG +5ADx 5Aces +5BY5 +5G fries 5GCovidTower 5H4NKS +5IRLOIN +5Id3Track +5M3H 5M9SNH31KAOI +5NAX +5OP 5Orudis5 5UBLlME +5a9 5alood +5alve 5ammito +5dudes1bank +5eekingdeath +5eizures +5g Internet 5gum 5harp5hoota 5hauny 5hayWh1te +5head +5inch Floppy +5is +5j5 +5kc Zulrah +5l9 5lNS +5lap +5nis 5parrow 5quid +5st +5t h +5th Blessing +5th hcim LUL 5trm +5wan 5wattia +5x3 5xr2 +6 57 +6 9buttholes +6 Donuts +6 Drive Fox +6 Foot 5 +6 I X GOD +6 M +6 Mil +6 Qp +600 Years +605 +60min is 1hr +617 +61V +6264 +629fm 62steeplist +6384 +647 +64DD +64th 6535 6620 +666 317 +666 J +666 is leet +666Ds 666Duuvel666 +666drkwizard +66Cute +66sick +675 +67M 67jj6j7 +68 savage +6822ii +68pickleman +69 L OR D 69 +6942O +69KolaOlli73 +69Skrrt420 +69bbygurl +69maryj420 6Dukke +6ESkarmory 6LACKY 6PaperJoint +6R6 6T9sofine 6TMG +6Tilbud 6UGG 6cansOfBeer +6cythe 6dr3w9 +6e +6enny +6ess +6et Schwifty +6h Logout +6in9 +6ix 6ixty 6ixx 6jadkiller +6km +6lb brownie 6mat 6ong 6p8o6 6pathsofpein +6qp +6shooter +6uapo +6uh 6utt9lug 6y6y6y2 +7 7 MAFIA +7 Curry +7 DeadlySins +7 Fat Drake +7 Of Nine 7 Trouts +7 pets chimp +7 seconds 7042 +70Point1 lol 70rangeboy 70to120 +710 710 710 +716 718m 71rc +72005sc +73 and Kree 734590325839 +737 73Head 73HoundKey +73gp 742617OOOO27 74ChaosLTUU +75 IQ 76frozen44 +76ms +7738 777slayer777 77Dunamis77 77Stingray +77ms +782 +784162 79giantfoot 7AYL0R +7D9 7Esconar7 7Ethereal +7F9 +7GB 7God +7H3 7J4FXEL7YFW5 7Lazy7 +7RAC +7T +7TF +7Vick 7Viggie +7ZP 7abibi 7amowdahli +7aq 7asty 7ate9 +7axy 7bazillion 7ckng +7ckng Mad 7claudia7 +7crypto7 7emo 7emp 7emptest 7fisherdog +7havage 7min 7mins +7mni +7om 7ourney +7out 7rad3 +7raphouse +7rev 7ridley 7scaryfire +7th Chamber 7th February +7uP joAo 7wizard10 7xshadowx7 +8 1 O +8 3B +8 Sue Build +8 alien 8 +8 bit bling +8 oh 8 8008tator 808Southside 80leavefox +82 Sue Say 8282 +831pride 832arba +8485 +849 +84Bandit +85 N 8502 +852K +858 +85U 85dakota85 +88 Odd Wand +8800 8885 +88gg 89devoid1329 +8ASS +8BootRaw6220 8ElMandinga8 +8J8 8O8O8O8O8O8O 8ass 8balknowsall +8balled +8eauty +8h of sleep 8ind 8l0wm3 8lackMamba24 +8loodrune +8lue Phat +8owser +8qxkf02v +8tail +8uD +8yrs +9 9 Problems +9 B 0 +9 DUIS +9 Tick Brain +9 mb +900mexp +901Grizzlies +90804 +9092514 90tegguy +91 +91 Tin Idea +911_Nate 91414 91CAL 91flip +92 way there +920 Bdops +9227 +9297 +92t 92times2is99 +94 xp +94AR BTW 95EliasAw +95LH +95p7 +96 WINDSTAR 9687 96fastfrog 97DEF +97ccman97 97fsh +98 BEDARD +98 Civic +982 +98Bn 98max1 +99 Doobies +99 Grill +99 Grinding +99 Mage +99 Rats +99 StaKe LvL +99 Steeze +99 oz +99 rwt +991atatime +9991499 99BnkStnding 99Juuling +99Lives 99S2HP +99Scents +99Scotting 99Slayer +99Souls3Days 99Victim +99_Maxed 99bottin +99charming 99hh +99moretimes +99ox 99problems4 +99ss +99sweatlvl 99wc500m +9Bar +9Barr +9CX 9D9Skillzz 9Dimensional +9GAG Reflex +9JR 9KL00AZIIZ9K +9O 9 +9PetsSoFar +9T3 +9TY9_Sailing +9UNIT +9cansRavioli +9ieman 9inchStepBro +9mm ko +9mmlesah +9ne +9ond +9till5slave 9ussy 9yearoldpops +A 2 The Aron +A 3 +A 45 +A 7 F O L D +A Articuno +A Bad IGN +A Bad Meme +A Big Hippo +A Big Leap +A Blind Man +A Booty Clap +A Born King +A Boss +A Bozo +A Bozz +A Bronze man +A Butcher +A Catowl +A Cityzen +A Claptrap +A Classy Boy +A Crazy Cook +A Crisp Sock +A Curry +A Cute Snail +A Dreamer +A Drunk Beer +A Du Ma +A F K Scape +A F KING +A F M Scape +A Fat Deer +A Fat Pike +A Fat Swede +A Gauss +A Girthy Boi +A Godsword +A H Fire +A Half Fool +A Hofasho +A I D E N +A I I e n +A II D +A Iron Yoshi +A J +A JJug +A Jack O Lit +A Jug +A Kimura +A L 3 X +A L C A P WN +A L E K S +A L I S H A +A L T A Lava Lamp +A LifeTime +A Lilypad +A Little Lit +A Llama +A Long Story +A Loose Seal +A Mattias +A Maxed Iron +A MaxedBeard A MeatStick +A Melic Poet +A Message +A Moist One +A Moot +A Nathan +A New Area +A Newbi +A P R O X +A Panther +A Pauled +A Pixxel +A Pkr +A Plush +A Poothy +A Pot Head +A Psy +A Quest God +A Quickie +A R H +A R Z +A Raccoon +A Random 4nr +A Real Bamf +A Revuelto +A Rocky Road +A Scylla +A Sly Deity +A Snorelax +A Sofa +A Soft Spoon +A Solo Slave +A Soul Rune +A SpaceFox +A Spaceman +A TRX +A Tonk +A Towel +A Tuxedo Guy +A U G +A V T U R A WILDR0NNY +A White Girl +A Wiki +A Wild Nolan +A Wise Sloth +A X Y S +A Yang +A Yep +A Zee +A Zeer +A Zoo Keeper +A Zuk +A Zuzakini +A aron +A bit north +A broke 126 +A capybara +A cclimation +A d e b y +A dam +A damm +A dammmm +A e d o +A e s i r +A f r a i d +A gg +A lba +A ll F +A llan +A llstar +A ltar +A m a nd a +A n d re +A nz +A rdy +A rmin +A rmoa +A rrow +A stoner guy +A to teh Jay +A ug +A y s a +A z k e n +A z t e r +A-Chronic +A-F-Kaveman +A123 A13X +A15 A1KMAN A1nz00alGown A1rhook +A2 A22Y +A47 Soldier +A543 A7MED +A84 +AAA GG AAAAAFK +AAAAAddy AAIGHT +AAsamba +AB Dash +AB84 ABEC +ABG Huntr ABILITEETTI +ABearCat ABlazys97 ABlueShirt +AC Dicing +AC TEMP IQ +AC0T +ACDC +ACatGirl uwu +AColdBeer AComp ACucumber ADACardano +ADAMB73 +ADHDerral +ADRlAN +AD_inc ADankTank +ADirtyDan ADrugTaker +AE2AW AEKDB AER0B +AER1410 AFCA +AFCA CBS +AFCA SCHOREM +AFGard AFJay +AFK Always +AFK Kay +AFK Liam +AFK SCO +AFK Spoon +AFK twigz +AFKJOHN +AFKaas +AFKarl +AFKevv AFKolby +AFKspiracy AFTW +AFX64 AFrickinLion +AGIT8 AGP3 AGRONOMlST +AGSpec +AGWA AGlassOfH2O AGorski AH Energy +AH64 Apache AHHSCHMEEEEE +AHK XD AHMETJACKSON AHarmlesKitn AHlager AHriMTaLeZ +AI Fighter +AI0 +AII 99 +AIchemyz +AIecko +AIeksib AIexmeister AIixs +AIlByMyself +AIm23ARDesti +AIways sm1le +AJ R +AJ Skills +AJ4J AJTracey AJ_24 +AJisHere93 AJsk +AK Alpha +AK Sam AK47 +AK4LF AK5C AKI-47 AKK1E +AKM +AKSpring AKinkyMonkey +AL-Trojans +AL3CX +AL7 +ALBlNO ALEXppresso ALLCAPS +ALLEGATlONS ALLTY4 ALSO +ALT Lurer ALargeMudkip ALevel115 +ALevel126 +ALittleLofty ALittleLogan ALonelyKurt ALonelySpoon ALonelyTaco ALv3Magikarp AMAWM +AMC Millions +AMD352 +AMDOSRSIRON2 AMGS65 AMRSY AMST +AN07HER AN0NYM0OOOUS AN1MAL1ST1SK ANDERDAPLUG +ANDR3 +ANDREVVTATE +ANDROlD 18 +ANGL0 SAX0N +ANGRY BL0KE +ANGRY N3RD ANIKV ANNA7AR ANNOYYEED ANON +ANRH ANUBlS +AOMA Doomfox +AOT GOAT +APC L000000L +APTZ27 +APrince AQ COCUGU AQMD +AQUAMARROCKZ +AR Brah +AR Fifteen AR15ONA AR1F +AR53 +ARCANO RS ARCHER ARCHIT3CTS ARESCREED23 ARNGCantrell ARRIVISTEZ ARRRot +ARTHURSHLBY ARTIZN +ARZ Ranger ARandyCat ASAP +ASAP Decky ASDQ ASH88 +ASIAN CHAD +ASIANBABIE ASMR AScrubIsHere +ASkillersAlt ASpacejunky ASuperDood ASuperior +AT-AT ATAR96 +ATEIROMU ATLx +ATR ATastyPastry +ATurboVirgin AU6URY +AUD1O AURl AUSLANDER AUSTlN +AUTOart AUTUMNELEGY +AUT_Alex +AUT_KoDeD +AV1 AVATARRR +AVE MARlA AVICll AVOCAD0O00OO AVlCII +AWW CRIKEY +AX0L0TL +AXL gun ROSE +AYRI DMM AZER AZNPanda +A_G_4 A_Wuh AaaBiiCee Aaalmost Aadalyn +AadreNaline +Aahatto +AakieSnaakie +Aaking AangTurambar AardbeiSoep +Aardwormpie Aaren Aargh Aarhus +Aarmir Aaro236 Aaron +Aaron 23 +Aaron Btw +Aaron Quiz +Aaron Samuel Aaron11700 AaronJMLP AaronPVM Aarsworm +Aarti Aary Aaryn +AashUnce +Aastradsen +AatroxLife +Aauburn +AavikonGaara Aayraz +AbInito +Abaay Abacraumbii +Abaiz Abaker Abaqus +Abariel +Abbas Elect Abbey +Abbey Ruins +Abbo baker +Abbyscimmy +Abc easy as +Abdallah6 Abdirahman +Abe lnnkon +Abe numse AbeTheHobo +Abengers Abernasty AbiChillii Abide +Abido +Abigayyl Abismaalinen Abito Abiuro Ablazin Abnegation +Abnxy Abocrate Abolish +Abolish NFA Abool +Aboriginal +Aborts Abortuary +Aboss Abou3Fiddy Abov Above AboveAvgGoat AboveHonor +Abpor Abr19 +Abradolf +Abrafebre +Abrakadaddy Abrakadino19 Abree107 Abridgetolum Abrils Abritrage Abruaa +Abruzi AbsentPray Absol Absol-EX +Absolut1on +Absolute POS +Absolute St8 Absolutism +Absolver Absorpt Absoullutely +Abstand Abstergo +AbstractNay +Abstractable AbsurdGreek +Absurdly Gay Absynthial +Abu Chungus +Abu Salih +Abuk +Abulssoni Abuv Abyission AbysmalGrind +Abyss Laps +Abyss Whip AbyssFreaks AbyssWalkerr AbyssaI Abyssal +Abyssal Roar +Abyssal Sire +Abyssal Wook AbyssalEmu AbyssalTrout AbyssalWrath +Abysse +Abyzz Acady Acai +Acai Berries +Acamarine +Acan D Acardi AccessPoint +Acciainoli Accio +Accio Bond AccioHorcrux +Accolades +Accountant 0 Accursio +Ace Kills +Ace12209 +Ace123445678 Ace2cool AceAlexander AceArcaneon AceOfSevens +AceTenSuited AceTookUOut Acefalcon3 Acekicker +Acemachine Acemanjam Acenr Acer Aces +Aces x3 +Acesuke +Acesupersoak +Acetazolamid +Acha9 Achaeos Ache +Achenar Achernar Achievement Achievements +Achilles Low +Achilles XXI AchillesFist Acholight Achuu11 Acid +Acid Cat420 +Acid Christ +Acid Dab +Acid Frick +Acid II +Acid Lunatic +Acid Magick +Acid Reducer +AcidBxbies +AcidHouse Acide Acidic Acidylia Acir +Ack Varmland Acke +AckeSSBM Ackman67 Acko Aclu +Aclyss Acolytes +Acorn Potat AcornHunter1 +Acoustics +Acquila Acquilar +Act Ov Vodka Actaeor +Actan Action +Action Dwarf +Action Movie Active +Active Whale Active-Bombi ActiveRecord +ActivelySent Activeshot Activis +Actor Actt Actual +Actual Bald +Actual Yak ActualName Actually Actw Acuila +Acumen OSRS AcuraIntegra AcuteSloth +Ad Pulvurum Ad0pted Adachigahara Adada62 +Adalman Adam +Adam pd1 Adam8 AdamBonar +AdamInAtl +AdamPwnz +AdamTehMong Adamant Adamanta +Adamantoise Adamchrisp Adammmmmmm +Adamp1 Adampewpew +AdamsMain +Adamskieh Adamy Adaptations +Add Jisuke Addderall +AdderLord Adderall Addi +Addicted Tom +Addicted2Rs +AddictedIM +AddictedSoul +Addlero Addycusfinch Addytt1 +Adee3 Adeeb Adelaw +Adele Adelier +Adeliya +Ademon66 +Adenocard Adept +Adept Brick +Adeptus W40k Adeq Adeus AdeyP Adgoar +Adhd Adam Adhurim +Adi Laser Adic Adiieu Adil Adin +Adios Punani +Adiosk8r AdjacentAce +Adjudicatior Adjusted Adjustmyfan +Adkille +Adley Admetis Admirable Admiral +Admiral Addy +Admiral Kev +Admiral Nano Ado12322 Adogg0323 Adolari @@ -769,46 +1995,85 @@ AdonisUkko Adorak Adorations Adore +Adornare +Adr Iron Adrean Adrian AdrianMMO Adriatik Adriatik7 +Adrik Adriyxs +Adroid +Adskip Adss Adstar +Adster98 Aduadu Adust +Adusy +Advance2Max +Advanced Rat +AdvancedOwen +Adventure On AdversY +Advvil +Adwan +Adyn1 Adz92 Adzyy +Adzz +Ae rith Aeariyion +Aeckersss +Aecyra Aedon Aedreius Aeganor Aegislash Aegon Aeikora +Aejayem Aelin +AelitenRS Aelos +Aemil +Aent Aeon AeonsOG +Aequites +Aerack +Aerdont +Aergius +Aeric Shun +Aerith 68 +Aerivas Aerj Aero +Aeroaxe +Aerocity Aerohead50 Aerolustly +Aeromi +Aerosol AeroxAces Aerros +Aeryen Aerzo Aestana Aesthetiix Aeterni +Aetharan +Aetharyn AetherEra Aethyrs Aeugh +Aev Aeyriex Aezolix +Aff it Affaires +Affan Khan Affect Affectie Affidra @@ -817,95 +2082,191 @@ Affirmed AfghanisDan Afghanistan Aficionado +Afk Blake +Afk Jasper +Afk N Scape +Afk Ray +Afk Scape +Afk To Smoke +Afk em +Afk is EZ AfkBandos AfkGod +AfkMachine +AfkTbh Afked AfkforGainz Afkillz Afkin +Afkoelen Afkstar Afkwarrio6 Aflamed +Afnacho1 +Afonso Afperser Afrecan AfricaSavior Africagamer1 AfricanMelon Afrie +Afrikka +Afriquee Afro +Afro Deagle +AfroFishh +AfroShay Afrojofe +Afroman +Afromann Afromouse87 Afrothunder Aft3rmath +After Dark +After3Scoops +AfterLike Afterlife Aftermatter +Aftermax Aftex Aftyr Afx31 Ag0b Ag3nte +AgagaWeeWee +Aganis +Agaperik Agatsuma +Age Forever +Age of Hell Aged Agenda21 Agent +Agent 3 +Agent Jass +Agent Slidt Agent805 Agent94 AgentFluff2 AgentOrnox Agentbunny1 +AgenteGanso Agentlobster +Aggressox +Aghiestic67 AgiNagii Agil +Agil Tank Agile +Agile AI +Agile Rob +Agile Tom AgileAllMile AgileFlea53 AgileLlama AgileRj +Agilities Agility Agitare +Agmaur Agnar472 Agni Agnoscere Agnykai +Agoge Agressie +Agroni Agronox Agronyss +Ags G Maul +Agsungg +Agua Diablo Aguanator +Agv +AhaShakes Ahab Ahav Ahegao AhegaoShawty +AhegaoxDrool +Ahero Knitly AhiPoke +Ahjin Ahkscape Ahkward +Ahlaundoh Ahmishcyborg Ahol Ahoyhoy +Ahreams +Ahri babe +Ahriah +Ahrim Job420 +Ahrou Ahvexx +Ai Haibara +Ai activated +Ai u +AiMienOortje +AiNebesvaik AiXiao Aiai8 Aian +AiasIM +Aiayu Aid12100 Aidann +Aidens Iron Aidios +Aife Aigua +Aiii Guey Aiikis0 +Aila Aillwynd Aimbot77 Aimdur AimenForFun AimenForYou +Ain Zak +Aina Vapaa Aintos Ainu +Air Aaron +Air Bison +Air Cube +Air Hawkz +Air Nimbus +Air Up There +AirAction +AirRin +AirWindSurge Airborne +Aircendition Airexz Airforcin Airomatren +Aironmaen +Airorider1 +Airplanez +AirsickMold +Airskipper +Airstone Airstrike +Airstrikes Airwalk Airwipp +Aishi owo Aisyah +Aivery +Aiwe +Aixaa +Aixleft +Aiyaaaa Aiyzer +Aizor +Aizzz +Aj Blitz Ajamian Ajarn Ajaxius @@ -914,99 +2275,193 @@ Ajeh Ajeti Ajikk Ajinz +Ajt141 +Ajushox Ajuus +Ajx +Ak 4854 Ak5u +Aka God AkaSpecs +Akadian +Akagi +Akali Akalron +Akarema +AkaseAkari Akasha Akashy Akatsuki Akaza +Akduman +Akeno +Akhasa +Akhavan Akhotha Akiha +Akihiko Main Akilled Akimbo Gmaul +Akira28 Akirakiyomi +Akka Flakka Akkaido +Akkezander27 +Akkhai Akmore720 +Akn Magic Akogare Akolyta Akomatic +Akomatk Akowii AkraLaDragon Akropolis Akshan Aksu Aksu596 +AksuRS Aktii +Aktivaros +Aku Megami AkumaPenguin Akunte +Akushizu Akusti +Akustic +Akvarij Akyba Akyle +Al Go Rhythm +Al e x x +Al ex G +Al-Kimiya AlCaponee AlFromOhio +AlIigator AlMusallam95 Alabandus +Alabarce Aladfar Alak4zam +Alakazoom +Alakazzaror Alameda Alamittainen Alan Alan200414 +Alandar Alanowsky Alantiwa +Alasse +Alaurise +AlbaisBack +Albananaa Albanoi +Albatrossse +Albatrox +Albert 1888 +Albert Klett AlbertaDean +AlbertasRec Alberthorn +Alberto +Alberto P Albertttt AlbiBambi Albin0z +Albinos10 +AlboBloodZ Alboy +AlbusTheDood Albuun +Alc1 +Alcadeias Alcado Alcarnia Alcatres Alcatrez +Alceini Alcerathe +Alch O Holic AlchKids4Gp Alchaline AlchedMyLife AlchedMyM0M AlchedMyNuts AlchedYaNan +Alcheimers +Alchemical A +Alchemicc +Alchemisten +Alchemize AlchemstDefi +Alchemyst +Alchhorn +Alchulon +Alckx +AlcoSkillz +Alcond Alcool Alcoz Aldastro Aldecaldos AldenolcyCB +Aldi Knight +Aldit0r3 Aldol +Alduiin +Aldwin Mose +Alec +Alec-kun +Aleck_l2 Aleffy Alegrete +AleizzleX +Alekja Aleks Aleksi Aleksib +Aleliumbis Alem Alemao Alenac Aleous Alerio Alessan +AletosCR Alex +Alex Blaze +Alex Cartman +Alex Grey +Alex IV +Alex Meret +Alex Power3 +Alex V2 +Alex Welshy +Alex Zander +Alex from IT +Alex the dad Alex12161 Alex3 +AlexDirty AlexHill AlexODaGreat +AlexSpkt +AlexV Alexa Alexander0k +Alexandre M Alexbrave2 Alexbrock +Alexis2Pro Alexmeister Alexnchill +Alexownsmatt Alexr0 Alexx Alexx2G +Alexxandraa AlexxisTexas Alexzilla Alf11 @@ -1015,51 +2470,95 @@ AlfaQ Alfahane Alfahanne Alfication +Alfie 96 Alfonga +Alfonso AlfonsoKhan +AlfredTB +Alfrid +Alfuh +Algiebeer Alharbi Alhyrr +Ali Shuffle +AliThePvmer +Alibaba Alicander Alicc Alice +Alice x +AliceOMalice +Alicent Alicezero1 +Alicola Alien AlienAntFarm AlienTTmilk +AlienVoucher Alienmage +Aliens +Aliii33 Alijr AliksOh Alioman +AlistarTb21 +Aliste +Alive Bozo +Alive Seb +Alive Vein +Alive18 AlivenHappy Alixz +Aljase Alkan Alkene +Alki Holic Alkkor Alkoholismi Alkymo +Alkyne +All Blue +All Darn Day All Fore One +All Frosty +All Peachy +All There +All a Bone AllRubyMoi +AllThePain AllTimeNo AllYourBase +AllaBarri Allabaster Allan +Allan man +Allards Allcreation Allday Alldays +Alldogg AllegedTheif +AllegedTree Allen Allerb +AllesPaletti Alleviate +AllexWx +Allext Alligaattori Alligamanor Alligood Allisun Allkune +Allky AlllySpawn +Allmethyst Allo Allomantic Allon +Allonsmoke Allowe +Allowed to Allscreen4 Allsen AllstarTb21 @@ -1070,54 +2569,105 @@ Ally Alma Almahh Almighty +Almighty2277 AlmightyMilo +AlmondJoy AlmostHadMee +AlmostSavvy Almost_124 Almosttheir Alno Aloha Alohas +Aloise Aloittelija Alondraj Alone +Alone CRNA +Alone RS AloneHeWalks +AlonelyPlace Along +Alonzo520 +Alonzo52O +Aloqab Alosthawaiin Alov Alow +Aloxc +Aloysius Alozaps Alpaca +Alpaca B0ng +Alpaca Lips AlpacaMyBags +AlpacaMyBowl +Alpacaliptic +Alpedocles Alpha +Alpha Cygni AlphaCoderXI AlphaFeeb AlphaMathic +AlphaSeraph +Alpha_Scott Alpharma Alphonse Alphray AlphusBrah +Alpine Climb Alpinetree +Alpoopi +Alppiruusu Alprazoland Already Alright +Alright Mom +AlrightBucko Alrite Alry Alsatian +Alsatians Also +Also Jack +Also Luci +Also Lucky +Also Nexxtar +Also Noexi +Also Schlak +Also kawkky +AlsoAlso +AlsoRabbit Alst +Alston +Alt Ctrl +Alt G boys +Alt Juana +Alt Redshok +Alt prepot +Alt3rbridg3 AltOclock AltSkillsDoe Altairre Altamonte Altchilly100 +Altcliffe +Altdunk +Altemeier Altenan Alter Alteraga Alternate +AlternateArt Alternatee +Alterones +Althamen Althornson Altifueled +AltimateRalf Alting +Altkandos +Altnik Altonorin Altruistic Altus @@ -1126,154 +2676,305 @@ Alucks Aluspalvelu Alvaaro Alvarreth +Alveoli Alvislt +Alvx Always +Always Alex +Always Awake +Always Harm +Always Late0 +AlwaysByrnes +AlwaysDNS AlwaysLost AlwaysPoor AlwaysQuest +AlwaysSunny +Alwayscuffed AlwayzJarvin AlwayzSol Alwex123321 +Alwin S Alxs +Alyks +Alysanne +Alyv Alzad +Alzuraak Alzz +Am eer +Am ity +Am ln Danger AmCatWhatDo +Ama zon +AmaAvenger Amadeux Amaiya Amak Amalie Amanda +Amanda Btw Amandelbrod Amarantine +Amarok Moon +Amasclit +Amateur Amathyn Amatsukaze Amatus Amazarashi +Amazaro Amazing +Amazon Power +Amazonia Amb3rLeaf AmberTheCat Ambik Ambion +Ambipom Ambisagrus +Ambition IRL +Ambition98 +Ambitioned Ambrose34 Amcaroz AmcyC37 +Amd27 +Ame Hara AmeJoyRock +Amean +Ameero7 Amel +Amelia Beth Amen +Amend Amenity +Ameno l +Americlaps +AmiableDingo +Amibis Amida Amigeau Amigo +Amigos +Amillie +Amin +Amir Psycho Amis Amitwin +Amityz AmixBeast +Amjad Amjar +Amka0s +Amkings Amlodipinee +Ammastian +Amnesiia +Amnios AmoMeuFilho +Amoei +Amon Amarth +Among Dead +AmongUs R34 +Amongst It +Amordrise Amos1500 Amper +Amperes Law +Ampiainen +Ampilify Ample +Amplify Ampura +Amsclarke +Amsterdamage Amty +Amused Fonty +Amuzements +Amuzzr Amuzzzr +Amy Sonck AmyMacdonald Amygdala Amylit Amyshaw123 +An Amputee +An Animal +An Ebony BBW +An Old Chum +An epic OAP An old Gnome +An0mandaris An0niminis +An6ers AnActualHorn AnAmerican +AnEnginerd AnEpicWookie +AnEskimo AnExperiment +AnEyeOhLate AnOldTank +Ana D Armas AnaWynn Anabella28 Anabolic Anabolic h1t +Anabowlen +AnaklusmosAN Anao Anaphylaxiss Anarchy +Anarchy870 AnarchyOS Anari AnataNoWaifu Anbu +Anbu_Mobb +AncIrew Ancalagon Ancastry AnchorMann Ancient +Ancient Fury +Ancient fir +Ancient hil +Ancient soul AncientFreak AncientLamb6 AncientMagus AncientOath +AncientP Ancientgh0st Anciento +Ancientz pal Ancitif +Ancona +Ancow +And e +And r ew AndSo +AndYetISmile Andardenn +Ander5 Anderave +Andericus Anders375 AndersenXo Anderssen Andhra AndiCandy AndiVT +Andiamo98 Andipyrus Andirath +Anditre +Andj Andoyen +Andrade149 +AndreasBL5 Andremagico7 AndresVZLA +Andrethyst Andrew +Andrew Marr +Andrew OG AndrewWigins Andrewjaay AndrewsMeat Andrezee Andrezz Andri02 +Andrian Andrick Andrishh +Andrius X +AndriusBykas Androgenic +Android Iron AndroidFox Andromed1k +Andsaca +Andx Andy +Andy Candy +Andy Ops +Andy Salrem +Andy btw Andy2 Andy2511 +Andy43229 AndyG223 +AndyIsComing +AndyL AndyMcbob4 +Andydiaz Andyfromvent Andyn9 Andyooi Andyvns +Anele Boy +Aneluy AnemicIzzy Anesics Anetha Aneurin +Anez +Ang3li Angalad Angel +Angel Advise +Angel Allie +Angel Gabe +Angel Martyr Angel Vlad Angel4killin Angel5 +AngelOfZeal AngelOrHour +Angelic Lust +AngelicOrb AngelicVixen +Angelisimo +Angell SL AngelsCrys Anger +Angerfish208 +Anghelic One +Angie Bos +Angl 0f War Anglerstein AngloSamson +Angoose Angry +Angry Bison1 +Angry Child +Angry Thumb AngryHusky24 AngryMvP +AngryNachos AngryPickle AngryScape AngryWizard +Angsti AngusM +AnhTaDuong +Anhedoniaa +Anid +Anida Hanjab Anidien +Anieli Aniheyu +Anim Anima Animal +Animal feces +Animalia Animation Animations Anime +Anime Nips AnimeExpert AnimeMilkers AnimeWaifus @@ -1281,51 +2982,95 @@ Animorph Animos Animosity Anion +Aniril x +Anita Dong +Anita M Wynn AniviaKush +Aniwave Anja +Anja Rubik AnjaPija Anjigami +Anjru +AnkaraAisa Ankedia +Ankka51 Ankn +Ankou btw AnkouClothes Ankougnu +Ankourule243 Anlaku Anlex Anmah Anmokyu +Anna Huikka +Anna Liebert +Anna Planks Anna Rosanna +Annavvaa +Anne Puppy +AnneWB Annero +Annhilate0 Annihilated +Annihilation Annihilative +Annna Puu +Annoys Anoie AnomalousFox +Anon E Maus AnonDoctore Anonim +Anons Anonymiity +Anonymous aF +Anonymousse +Anoobass1 Anooge Anoomliebird Anor +Anotha Skar Another +Another Name AnotherCsTa AnotherDoor AnotherGamer AnotherName +AnotherPb +Anouar +Anoubis Ansaittu +Anscombe +AnselAdams Ansoil +Ansovs Ansuz +Ant M8 +Ant a AntRIP +Antartsant12 Antast Ante Antee294 Antelope123 +Antex +Anth x Anth52 Anthiex Anthilll Anthony +Anthony Btw +Anthony I Anthony5002 Anthoons +Anthooony Anthorak Anti +Anti Drop +Anti PK G0D +Anti002 AntiFuh AntiVaxMothr Antidope @@ -1333,59 +3078,102 @@ Antifa4figs Antifire Antiflag42 Antiguy24 +Antinyte Antipathic Antipixel AntiqueRS Antiqxx +Antireflex Antis Antiserum420 Antixan Antiyano +Antlers +Antmix Anto Anton +Anton T Antonio Antonn Antony +Antony1202 Antony142pay Antoun +Antracid +Antron Antstolis Anttila Antweezy +Antz Xii +AnuBi 1337 Anub1s Anubis +Anubis ex +AnubisT3 +Anuj Anul AnullSecs Anv1k Anve Anxi Anxiety +AnxietyBTW Anxious +Anxious Mess AnxiousDoggy AnyDrops AnyLesS +AnyQuestions +AnyScrolls Anze +AnzheliK Anzie Anzied Anzu +Anzypoo +AoA Jammer AobaJohsai +Aog +Aoh +Aohc +Aohu +Aoi Tetsu Aokijahr Aokijii AonEne Aonyx AoooA +Aorpheat +Aosrs Aowi +Aozaa +Ap0logy Ap0phis Ap3x Ap870 +ApRoMn Apaat +Apaatje Apache +Apache30 +Aparlo ApartAbyss Apathetik +ApdoJ +Apdomine +Ape Cape +Ape Dos Mil ApeAtoll Apetamer +ApetimusPrym Apex +Apex Pro +Apex-scaper +ApexGT +Apexflashy Apexist Apgujeong +Apherna Aphex Aphroditeee Apimer @@ -1394,74 +3182,136 @@ Apldale Apm90x Apoc Apoc142 +Apocriya Apocryphe +Apolliox +Apollo Beach +Apollo13th +Apolytos Apop +Apophiss Apor +Apostasie Apotoxin App3lflap AppaYipYip +Apparat Apparitionn +Appeasive +Appel Farm Applauder Apple +Apple A Day +Apple Mart +AppleBluue Appleboss +Applecus +Applejuiceaj Applemaxx Applev2 Applied +Applul Apportant +Apprenti1 +ApprenticeRS Approval ApprovuL AppySauce4 +Apqle Aprella April April 8 1997 +April twenty Aproximity +Apsa Larr Apteryx +Apteryx luna +ApuHapu Apul Apullu +Apyon Aqew +Aqizu Aqtive AquaUnit Aquah Aquaileo +Aquajd Aqualetics Aquamation +Aquamentus9 Aquascaped +Aquaticbob Aquatik Aquellex +Aqueueser +AquiIa Aquilo +Aqva Babe +Ar ex +ArA100 +ArKadeeee +Arab Frieza Arabian Arada Araet +Aragonx Aragornmv +Aragornous +Aramaki Araman +Aramex Arandae Aranna Aranruth +Araq Araqon Arasex Arashikato Arastaiel Arathir Araur +Aravt Araysen Arazz Arb4n +Arbator +Arbenn Arbin Arbyy +Arc1s +Arcade firee +Arcadian96 Arcane +Arcane Grima +Arcane Queen +ArcaneApollo ArcaneBear Arcanezeus Arcangel +Arcangel IX Arcanic +Arcanox Sad +Arcanum XIII Arcas3 +Arced RS Arceneus Arch +Arch RS +Arch er Arch3nLight +ArchFarmer ArchX Archaea582 Archahl +Archaic Wolf Archaiden199 Archanjel +Archas +Archavia +ArchbishopC +Archduke Btw +Archelon Archer ArcherYew Archie @@ -1473,6 +3323,9 @@ ArckenSphere Arclight Arcnan Arctic +Arctic Roach +Arctic Vaggy +ArcticCamel ArcticMank ArcticTitan Arcticas @@ -1482,8 +3335,16 @@ Arda Ardaddy Ardames ArdenDZY +ArdestRange +Ardilos +Ardougn e +Arduino69 ArdumTheMain +Ardumm Ardy +Are Dry +Are ng +Are you well AreYouMyMumm AreYouPepega Area @@ -1491,12 +3352,17 @@ Areimer0606 Arekusei Arena ArenaRebuild +Arend Nest +AreolaArnold Areolas Areoloth +Areow Ares +Ares 3060 Ares1701 AresArmy AresKnight +Arescoth Aretx Arezrazer Arfex @@ -1505,282 +3371,534 @@ Argawan Argent Arghoslent Argilla +Argo Vesta +Argonuts +Argory +Argov +Argyle Sock +Argyle Socks ArgyleGrandt Arhedel +Ari AriSlash Aria +ArianDRZ Ariana +Arias star +Ariazel Arid ArieMoon AriesWarrior +ArieyaeIron +Arifureta Arigorn Arigorn55 Arihant Arillian Aris +Arisen I +Aristo +Aristokratas Arisu +Arith1um Arithe Arizotal Arjoon Ark9tog +ArkAngel029 +Arka91 +Arkaniz +Arkantos51 +Arkaros Arkavos +Arkaynine Arkeela +Arkells +Arkem +Arkemir +Arkend Arketryx Arkevin +Arkhero +Arkizah +Arkki +Arkonka1 +Arkonknight Arkvasal Arkysh Arlind ArloTheBrave Arlorict Arlyeaxn +Arlyse +Arm Chair +Arm Guy +Arma Frost Armadexx Armado Armadomin +Armadyl king +ArmadylPker Armadyllo Armament +Armanyte Armapickle +Armas Chosen Armchairs Armerak +Arminius Sol ArmisticeDay Armo ArmoBlood +ArmoMike Armoah +Armondega +ArmorHelmet3 +ArmorSeeds Armourer Armsdray +Armweak55 Armysam Arna +Arndas Arnear +Arnhems Arnie Arnold +Arnor +Arnthor Arntj Arobpl Arod Arodaz Aromipesa Aron +Aronya Aroorin Arousen +Arousin +Aroyu Arpang Arpegio Arptacular Arr n Geesus Arrandarls +Arrasca +Arrazha +Arre10 Arrizu +ArrowHaste ArrowTank Arrowmind +Arrows Myth +Arrowtower +Ars Nova Arsaydar Arsenals +Arsene rar Arsenic +ArsenicEyes +Arsenn Arshal +Arsi Arslen Arson ArsonScape +Arst +Arstan Selmy Art Dayne +Art Star +ArtIsHard ArtStylerzz Artces +Artegal Artenmis Artesna +Artezor +Artful Dodgr +Arthaniel Arthesus Arthropods Arthur Arthven +Artic0 +Articuno1991 +Artidote Artillion1 Artipeng Artisaani +Arto Lauri ArtofKush ArtoriaSiff Artoriias28 +Arts +Artu12v Arturis Artychurro Artz +Aru Arumen Arunas Arusas +Aruwyn_Xi Arve +Arvinthir Arviragus +Arvns +Arvsta Won +Arvx +Arwe +Arwon Arxanec Arya Aryabhata Aryuts +Aryzha +Arzemnieks Arzi +Arzna AsalentBlaze Asami +Asami Sato Asap +AsapLamb Asbi Asbloodfalls Asbur +Ascadex Ascanliss Ascended +Aschen +Ascii You Asda +Asdasd107 +Asdewq +Ase Aseae Ased Asfixiator +Ash K +Ash Solo +Ash Wreckum +Ash l AshBash AshEvillDead +AshKetchum00 AshLad94 +Ashabee Ashandarei0 +Ashcroft Ashealia Ashen +Ashen Bride +Ashen Heart +Ashen One AshenSughar +AsherMentuI Ashes Ashes630 Asheviere +Asheville +Ashhh Ashieboyyy Ashikaru38 Ashington +Ashkelmek Ashkii +Ashkyn Ashleigh Ashley AshleyNZ +Ashleyi Ashlyce +Ashmeow Ashn Ashoo Ashsole Ashton +Ashura Bakke Ashwin09 +Ashy joey +AshyKneecapz Ashyy Asian +AsianGrinder +Asics +Ask Oziach AskMeDolCare Askraf Askumi AslanMaximus Aslywyn +Asmir9990 Asorf Asos +Asot +Aspen +Asper Aspestia Asphyi +Asphyi Xate +Ass Balm +Ass Clams +Ass Drill +Ass Rocker +Ass locator +AssClapping +AssMcButt Assasindie73 +Assasintoad Assassinado Assaulted +Asshats R Us +Assktchum +Asstain Ast 360 Astan +Astaro +Astartes +AstartesXIII AsterSG Asterlad Asterlyte Asterus Astiminate Astoia +Aston Fartin AstraDan93 Astraea +Astral Queen +Astral laws Astrali +Astrals +Astray +Astrayus Astro +Astro Dust +Astro O7 +AstroKP AstroXgK AstroYogurt +Astroflare +Astronaut Al +AstrooWRLD Astrophe Astrostone +Astylez Asubu +AsuhDude Asuka AsukaLangely +AsukaYenOSRS Asukas Asumaton Asumistuki Asuna Asunnn Asura +Asus bl +AsylumTRAV Asymmetry Asyn +Asynergy Aszalem +Aszard +Aszension At0mic +Atacrite +Atar Ataraxia +Ateo +AthIetic Athaw +Athe na Athedeia Athena +AthenaOfOsrs +Athenaloki +Athi Athire +Athius Atika Atilio +Atin +Ativan IM Atlamillian Atlantic AtlasErol +AtlasUsurper Atlashi +Atleast Atli567 Atmosfare +Ato m +Atolla Atolli Atom Atomic AtomicFlux +Atomicdomb2 +Atomikaust Atomsk Atomyze Atonic Atorvastatin Atouk +Atoxicary Atoz +Atriades +AtriummDream Atrixas +Atro phy Atroo Atroph +AttackMoons Attard +AttemptedUwU Attic +Attic Ghost +Attic Witch Attics Attikos Atton +Attuned Atuking +Atvinnulaus +Atylos +Atza +Au 0srs +Au 1 +Au Bar +Au Barrett +Au Joel +Au Shooty Au92 AuRoyce AuStarZ Aubrey +Aubrey UIM +AubsG +Auburn Lax Aubzzz Auclaw Auctionable +Aud AudacityOP +Auddax Audi +Audi Nurse +Audi Reach +Audo +Audronan Audtnec Audylinks Augment AugstBrnsRed Augurk +Augury Tank August AugustAmes Augustiner16 +Augutis Auhdy Auja3 AuksoAlt Aulono +Aumoki +Aunonen +Aunt Wu Auntie +Auntie Mabel AuraBeast AuraSissari +Aurah +Aurelia AurelionROW AurelionVM Aurelya Aureou +Aurgodi AuriZed Auriana Aurionx +Aurizon Aurorin +Aurrok Aurtle AurumFoxfire +Auryn +Aus +Aus 2277 +Aus Shizam +AusBruto +AusGram Ause +AusieBumpkin Ausripper Aussie +Aussie Jay +Aussie Luke +AussieKunt +AussieOandE AussieSparta Aussome +Aussybear +Aust Terps Austie Austiiizy Austin +Austin Ames +Austin is 1 Austin296 +Austiz +AustlnPowers Australia +Australians Australiaz AustrianOak +Austs Austyn Autchin +Authorized +Authorizer Autickstic Autilon Autism AutismeKnaap Autist Autistic +AutisticAndy +Auto Tuned +AutoBonsai AutoEmp +AutoLoot EXE +Autoacid AutomailArm Automonteur Autophagy +Autorotate +Auts Man Autumn AutumnKevegy Autzerk Auuustin Auuuv AuzReaper13 +Auzium +Av o +Av3z Str +AvC OSRS +Ava End Avaetar +Avaigo Avatar +Avatar Evan +Avatar Magni +AvatarBean69 AvatarShakur Avedon +Aveng +Avengerous Aventy Aver4ge Average @@ -1792,7 +3910,14 @@ Avernic Avero Avertehs Avest09 +AvestGIM Avex +Avexaon +Avfc Holte +Avg Tom +AvgMG +AvgScape +Aviaatar Avian AvidTech Aviiation @@ -1801,85 +3926,154 @@ Avinosis Avir Aviron Avlek +Avocatocat Avoidable Avoinmieli +Avonak Avondale +Avouch Avrahm Avsendesora Avysto +Avze +Awadi69 Awaiting +Awaiting 126 Awaits Awaiyume +Awakened Olm Awarde +AweJeez Awendana Awesome +AwesomeBros AwesomeJared Awezm Awful +Awful Name +Awfully +Awh DB +Awh Nuggets Awies Awilkins4231 +Awkquavian +Awkventurer3 Awkward Awowegei +Awowo Gay +Awry +Awtangg AwwSeriously Awwdiddums Awwtis +Awyr +Ax3 +Axayre Axdrew +Axely +AxemPink Axeo +Axhers Axies Axillaa AximusMax Axiom +Axlerod +Axleson +Axodyi +Axolotl +Axsentz Axton Axylix +Ay Monk +Ay Ron Man Ay3m AyAyRon AyB33 +AyJae +Ayafuyuzu AyameDespair +Ayatan +Aybills +Ayd +Aye Sip AyeBaddaBing +AyeePizza Ayeeet +Ayema IM +Ayenull Ayetg Ayfi Aylia +Aylward Ayman +Ayo4Yayo AyoSteeze Ayoe +Ayonikz Ayra Ayri +Ayrton +Aysuu Ayveros +Ayy Nakana +Ayy bae bae +Ayy q p Ayyye Ayyyon Ayzo Az PVM +Aza zel Azad +Azad Kashmir Azala Azami +Azandari Azathor Azathoth26 +Azathrir +Azazel OSRS +Azeenil Azemu Azerma Azez Azimut Azimuthaal Aziz +Aziz7 Azkaton Azken Azkybot Azlo Azmataz +Aznbabe Aznmixboy Azom AzorAhaiBTW Azotize Azoxy +Azpa +AzraelReaper Azriiele Azryel +Azs +Azshara +AztecLT +Aztra Azula +Azula Whip +Azur Lane Azur_I Azure Azure23782 AzureSpirit +Azuredadi Azuremadi +Azuretiger Azuuure +Azynn +Azyrith +Azza Bear Azzaar Azzaboy100 Azzakel @@ -1888,100 +4082,257 @@ Azzanadraa Azzax Azzgarnia Azzz +B 0 B S +B 0 S S +B 0 U J E E +B 3R +B 58 +B A F F E Y +B A MF +B A U W S +B B Bouncy +B C 2 +B C M +B CA +B D Y +B E E G +B E R T A +B E R t I 3 +B ELA +B Gates +B Gonkeybron +B I G G L E +B I R T +B Ian +B J O R N +B L 4 N K +B L A D E Z +B L A N E +B L A Y E D +B L ANK +B L I X T +B Milesy B Minor +B O G S +B O O T H +B O Y E A +B R A l N +B R II A N +B R l C E +B S +B SlDE +B T J B Victor B +B W 1 +B W A K +B aylor +B aze +B ecky +B eeez +B iggles +B la z e +B las +B r a g g +B r eezy +B rads +B raes i +B ruised Lee +B u bs +B ug +B un +B utt +B w +B-0-SS-M-A-N +B-Dollaz B-Lal +B00 KAW KEY B00Lici0us +B00MERAT3R B00ST B00SY +B00tlicker B0ARD +B0B The Cat B0BaH B0GLA B0ND +B0NERCRUSHER +B0NGRIPS42O B0OP B0aty B0atyquila +B0bz BurGerz +B0dka +B0n3z84 +B0nes2Weed B0rders B0rn B0rn2bking B0rnas +B0tched B14cksh4d0w +B1G BAD CHAD B1G8 +B1GARMS +B1GBOB +B1GGY B1G_D1ESEL +B1G_SW1GS B1RDUP +B1Te Me +B1ack Lotus B1ackJack B1asphemy B1gTTgothGF +B1gd0wg B1ink +B1mboBambi B1zrme B2AD +B2F +B2J3 B2bZeroSpecs +B2rad +B3A5T +B3CK B3NJAMOON +B3NT D0ver +B3TTERLUCK +B3Y0ND B3njamima +B3njamin +B3nny Blanco +B46 +B4RR +B4S B4llista +B6a +B6i +B70 B747B +B8 H8ER +BACKURBOI +BACONisgd4me BADASS BADDONE BADPanda2 BADUPDATES BAKED +BALD n DUMB BAMF BAMFnificent BARBARlANS BARRAGENOW BARRON24 +BASED DMM +BASEDQwert BATATUNGA BATH0RY BAYLlFE +BBBBBONKA BBGL +BBK BBKwenie +BBL RIZZY +BBQs +BBW Pizza BBarnzeyy +BBeepLettuce +BBoys Father BCBDestroyer +BCC YT BCDOJRP +BCK CigButts +BCMagoo BDCMatt BDrichard +BEANS9991119 BEARDED +BEAST ARCHER BEATONiT +BEBELAC28 +BEEA BEG0N BEG0NE BEINGMAXDSUX +BELSJ BEMBOU BEST +BET5 +BEYFYBOI +BFKay BHAFC +BIG ASHL3Y +BIG C0X LUVR +BIG HIT GOOD +BIG pontifex BIGBADWILLY +BIGD05 BIGDROPHUNTR +BIGFERGLOAD BIGHEADSMASH BIGJP BIGMINK +BIGSITUATI0N BIKlIllIlIIE +BILR0Y +BIOATED +BIRD SHlT BIRP BIRWAAA +BIS Monster BIaded BIadet BIapa +BIood Prince +BJ Applegate +BJ M +BJPlaysRS +BKBB +BKK BKLN +BL00DANG3L BL33DPL34S3 +BL3SS3D4LIFE +BLACK DOG NI BLASE BLGesus BLICKYSTIFFI +BLOBi WRX BLOOD BLUEPIZZAMAN BLXCKPINK +BLYATMOTOR BLlNKY +BMEUR +BMooldijk BMrgn BO0MERSO0NER +BOA Liger BOBGIGALUCKY BOBYAHMDGECI +BOER KAMIEL +BOGOBoneless +BOL0CKS BOLSOONARO BOMBAKLAP +BOMBU +BONITA 02 BOOPlNG BOOTTYBANDIT +BORDEN DAIRY BOSNIAQUE BOSS +BOSS OG +BOSSMANHOG BOlNEXTDOOR +BPNS Hawk +BPTheIronOne BPrimitive +BR0 BRO BR00KES BR0CE +BR0ER BR0THERS BR3AKABLE BRA71L @@ -1990,16 +4341,34 @@ BRAMMOSOVIC BRANDONSMlTH BRCH4 BREJCHA +BRUTAL BRabbit25 +BRlOCHE +BSB Howie BSNR +BST Steve +BSickler BSven-B BTCEUR +BTKMGJKL +BTMillz +BTW Beirre +BTW idgaf +BTW vs RNG BTWSaberlion +BTWsanta +BU1MER +BUHLL BUILD BUILD PONYS +BULLlSH BUNDHA BUNStheGOD +BUR13D AL1VE +BURYT0MORROW +BUSS IT BUTTB0NERED +BUTTCOlN BV Martyr BWheatZ BYEq @@ -2008,101 +4377,219 @@ Ba1i Ba5b0y Ba6y Ba77erY +Baa m +Baaaats +Baal157 BaalZvuv Baals Baalthas Baamf Baami +Baandos +Baarb Lahey Baas Baba +Baba Booey9 +Baba Borgar +BabaLovesKos +BabaSlaaf +BabaSleep BabaTarzan Babafasa +Babayaga-9 +Babayaga2121 +Baberrandrid +Babica Mraz Babiez +Babocat Baboosh +Babs221 BabsCox Baby +Baby Bear +Baby Bobby +Baby Boeing +Baby Daphne +Baby Houdini +Baby Motel +Baby1400 BabyB BabyDogeCoin BabyDogeFTW BabyGroot BabyHat +BabyHewy BabyHiggy BabyJIREN +BabyLinga BabyPandaa3 BabySas BabyTamer Babycerasaux Babydump +BabyfaceBill Babyjoker828 Bac0n BaccaM Bachelour Bachuras17 +Bachus67 Back +Back Jauer +Back Seater Back2Backk Back2ourdays BackInTime +BackToBambi +BackToOwn +BackelsOSRS Backinthe09RS Backlit +Backspace +Backsterr Backus Baco +Bacodie Bacoid1 Bacon +Bacon Glizzy +Bacon24717 BaconBlunts +Baconcannon +Baconist Baconlord100 Baconpancake Baconstrike Bacteria Bactomet Bacun +Bad Advice +Bad Ape +Bad Axe +Bad Day +Bad Fruits +Bad Kind +Bad Kuip +Bad Mario +Bad McNamey +Bad Mistake +Bad Name Now +Bad Robert +Bad Weather +Bad exp Bad2dabone30 BadAndB0ujee +BadAss_oO +BadChicken +BadChronic +BadDecision +BadIdeaDog BadIllusions +BadInIronMan +BadInNames +BadMamaJama +BadMannerz +BadSass +BadSpalling +Badaping Badass +Badass Fe +Badass Iron +Badass Rs +BadassIron +BadassPotato Badasseness Badaxx BaddieDragon Badgalriri +Badger Bush +BadgerInABag Badgerq97 Badical Badman +Badman ET +Badoodle Badora +Badora II +Baduk +Badvask +Bae-Kun8er Baeby Baekah +Bag it +Bag of Yay +BagFryLife Bagadigi +Bagan Bageera BagelSpanker Bagels Baggyshaw +Baghdad Baginga +Bagis +Bagokk Bags +Bags n Beer Bagsnacks +Bagz BahRitTanEe4 BahamutLimit Bahn Bahnzeen +Bahp +Bai Ningyang +Baib +Bail Jait Baileys Bailsby Bailz Baimonnnn +Baines +Baino BainoLad +Bainz Bairac +Baites +Baja Baja +Bajan Bajart Bajcolado +Bajela Bajere Bajhole +Bajista +Bajji Bajkami +Bajsanus Baju +Bak cornet +BakIron +Baka Mop +Baka Prase +BakaOsaka +BakaPho Bakazuro Baked +Baked Mage +Baked Saiyan BakedVandon Baked_Beagle Bakedd +Bakedmuffins BakeonBits +Baker Bully +Bakerloo +Bakers Baked Baketto +Bakhmut +Baki Hanma +Bakingsodah +Bakingsweets Bakkis Bakllava Bakron +Bakthawar Baku Bakuchiol Bakusho @@ -2110,49 +4597,100 @@ Bakuthedrunk BalIsackt1ts Baladend Balan +Balan Dinh Balar Balarezo +BalazinGIM +Balboa Park +Balbuli Bald +Bald Arab +Bald Male +Bald Shupa +Bald Sicknez +Bald To Bold +Bald Wookiee +Bald at 29 +BaldKnees +BaldMansKenn Baldfuc +BaldheadBill +Baldoc Baldorr +Baldrake Baldras Balerion Baliboosca Balkan +Balkenende Ball BallOfCotton Balla +Ballack342 +Ballade No 3 Ballcheck369 +Ballenaso Baller006 Ballerina Ballesekk +Ballet BallinBamf Ballotaa +Ballroom Bally +Ballztacular Ballzy Balmung311 Balneum Anas +Balob Balontra Balou +Balrogs Hell +Balthazar BL +Baltimohr +Baltimore MD Baltoth Baltramiejus +Baltzerboii Balu +Balu Titan +Baluk +Bam Achilles +Bam Grizz Bambi0326 BambiSlayer Bamboo +Bamboo James +BambooPandas +Bambuliuss Bamf BamfJoe Bamfbeav +Bamiman +Bamse Bamztile Banan Banefish Banerz +Banio +Bank Stander Bankaiz +Banki 1 1 Banzu +Bape +BapeNation +Bapelsin +BaphometsLov +Baptor Baqels +BarShake +BarSmash Baraek Barakoli +Baratheon +Barathrum BarbaariJuho +Barbatos Barbose Barbwiire Barbyte97 @@ -2160,60 +4698,105 @@ Barca Barca230492 Barcodes Barcoding +Barcy Bardimuss +BardleDooDoo Bare +Barely High +Barely Legal BarelyBusy BarelyDecent +Barfallonyou Barfs Barfy +Bargli Barhoor Bariviera49 +Bark sample Barkki BarnVo +Barncle Boy Barneey +Barnet Ftw Barney12370 +BarneyKing +Barneylover Barnez10 +Barnyard Boy Barnz BaroBro +Barometz Baron +Baron Iron +Baron Timmy BaronConey BaronGiraffe BaronVonGeeb +Baroondon Barqueefa +Barr +BarracuDro +Barraggah Barrako +Barrel Flop Barricade Barrowry Barry +Barry Koota +Barry0408 BarryBanaan BarsasBoom Barstukas Bart +Bart Heredit BartBelly BartSimps +BartenderBTW +Bartheez Bartholomeii Bartje +Bartol Bartycool Barzhal +Bas +Bas Waterpas Bas481 +Basant Base +Base 99s +Base Skills Based +Based Evan +Based Kyoko +Based Miyagi BasedGob BasedHeru BasedScape +Basement Dad +Baseplate86 Bash BashinBosses BashiraTHC +Bashram2 Bashx Basic +Basic Drop BasicBilbo BasicIronman Basil +Basil Hiiri Basileia +Basilikos12 Baska +Baskervilla Basket Basketballer Baskie Baskrans +Basmah +Bassaidai2 +Bassey +Basshu Fon Basshunter Bassilliaux Basstomouth @@ -2221,42 +4804,71 @@ BastasRemmen Bastermate Bastiao Bastidaz +Bastin101 Baszist +Bat Fastard +Bat Kills Bat418 +BatChatillon BatFat Batbot101 Bateau BatedUrGonna Batesanator Batgirl +Batin +Batistaisraw Batleris Batmain +Batmam Batman Batmanlul Bats BatsVsChina Batsborkair Batsmattie +BattDoode Batter +Batter Cake +Battle Jack Battousai +Battousai09 +Batu +Batussy +Batzch Batzz Bauchop +Baulsacky Bautista I +Bav Bavaria +Bawdlands Bawjaws Bawn +Bawwz DeadAf Bawz +Bax2 +Baxi 247 Baxxis +Bay +BaySeoul BayaniSenpai Bayern_pvm1 Bayes Baykr +Bayle Domon Bayleef180 Baylin Baylon +Baylon rs BaylyBoyBro Bayman +Bayou Bengal +Bayside +Baza +Baza NZ Bazilijus +Bazimga Bazmobile Bazoo415 Bazoomaster @@ -2265,45 +4877,96 @@ Bazukashrimp Bazz0r Bazzak BazzleB +BazzleBTW Bazzooi BbDontHurtMe +Bbase12 Bbaws Bboygainz +Bbubbsy +BcShane Bcgod +BchImaBus +BckOFFRTRD BckScratcher +Bcowzy Bdawg +Bdub187 +Be Aware +Be Rad +Be Strong +Be X Unlucky +Be as t +BeEzyMan2 BeFawn BeThankfulll BeTy BeaTee Beaan +Beak er +Beaken Beaky Beamesy77 +Beaming Beamo +Beams btw +Bean +Bean Bunn +Bean Slapper +Beanieus Beanis Beanisdead BeanozZ +Beanpot Beans1991 Bear +Bear Downn +Bear Finale +Bear IV +Bear Jake Bear Savage +Bear W Scarf Bear0nBeer Bear32 +BearByBlood BearByte +BearDown80 +BearGrillz BearImmunity Bearac +Beardboy Bearded +Bearded Hick +BeardedGummy +Beardedwick +Beardilizer +Bearing Down +Bearly Iron +Bearopenart +Bearrito42 BearsBeetsBG Bearsarefrie Bearsfan5455 Bearshot +Bearsome BearsyXL +Beary Beast +Beast Guard +Beast Things Beast1Range1 +Beasted Main Beastgriff +BeastieBoy31 Beastied +Beastley BeastlyGinge +BeastlyMuff Beastman642 +BeastyY69 Beat +Beat Tit +Beat my Wifi BeatboxRS Beatdown115 BeaterGod @@ -2311,34 +4974,73 @@ BeatmyJonson Beatrix Beatz Beau +Beau Ryan Beau1o Beaukaki +Beautifull Beaver +Beaver Booty +BeaverSweat +Beaverr +Beavers79 +Beavis 420 Beavis825 Bebbie Bebe BebeAtron Bebexx Bebo294 +BeboKAhnung Beckerr +Beckovas Beckyboo308 +Beckymikyu Become +Becoming Becton22 +Bed +BedByDaylite +BedForSale +Bedanc Bedeh +Beden Bedevil Bedni1 +BedtimeHERO +Bedwoods +Bee Butts +Bee Keep +BeebeM Beef +Beef Mince +Beef Squirt +BeefBottom Beefense Beefs Beefy +Beefy Potato +Beefy Treat +Beefycopter Beeg +Beeg splat +BeegeKhaos Beeghs +Beeks Beeky Beeline Beelzebubba Beelzebubby5 Been +Been Mobile +Been Poor +Beepern Beer +Beer Diet +Beer Is Cool +Beer Pong +Beer Tankard +Beer gut Jim +Beer n Blow BeerIsGood Beerchamp1 Beerfest @@ -2346,397 +5048,886 @@ Beerhana Beershits Beersmack Beerzinnss +Bees169 Beest Beestig Beeswakka BeetchAustin BeetchJeemmy Beetle +Beetus93 +BeeyondBeef BefJekyll Befkeuning +Before Snow BeforeDeth +Befsnor Ben +Begani +Begave +Beget Begin Beginning Beginnings +Beh +Behaarde lul Behemoth Behhnchod Beholder24 +Beibs Beidou +Beige Carpet +Beikengaut +Beikenost BeirH Beirreee +Beirut BekanTering +Bekfist +Bekk Bekkie Bekske Bekt Bekutma +Bel Lando +Belaa +Belamylinds Beleid Belenthir Belgarathion BelgianBeast Belgiium Belgique +Beliefofmine Belindaa BellWoods Bellatrix +BelleBeans +Bellebutties Bellerin Bellfontaine Bellicus BellsOfWar Bellum50 BellyEscobar +Bellzbellz +Belorca Beloved BelowAvrge +BelowMe +Belsassar Belsey Belsfyre Belsyn +Belt +Belt vs Kids +Beluge Belzebu Belzeddarr +Bemerson Bemke Bempii Bempire +Ben Babeslay +Ben Behling +Ben Bekkuman +Ben C H +Ben Jay +Ben Jones +Ben Kingsley +Ben Manolo +Ben Salden Ben Standish +Ben di +Ben1kzeker +BenDjammin BenDover321 +BenKuro +BenLevensMoe +BenQ Smasher BenRobbo06 BenShapirOwO BenWithJam Benarends +Benbooo Benching +BendOverBabe Bendak +Bendeguz BenderBuilda Bendigo +Bendigo Man Bendo +Bendos Hilt +Bendude +Bendyruler Bendzo Benedict Beneee Benefitz +Beneh Benelovent +BengtBreak +Bengtsson Beni +Beni Siitoin +Benifax +Benifird +Benis Hammer BenisTechTip +Benisbringer +Benja1666 Benji +Benji Stax +Benji189 Benjiii Benllech Benman Benmiester44 Benneta +Benni234 Benni2345 Bennie +Bennie Lam Bennis Bennny0_o +Benny Sins +Benny Stacks +Benny Yuh +Benny p mage Benny1175 BennyBeeee +BennyQ Bennybooom Bennyz Benocotch +Benoid +Benononono Benoragon +Benoxo Benqqu Benquad Bens +BensBent +Bensmom7 +Bensos Benstjohn Bentso Benvil Benyy +Benza Benzema1 Benzine +Benzoed +Benzylll Benzz +Beopia +Beozqt +BeppaPig BeppsaN +Ber Berada Beralf Bercuckle Berd +BerettaM9A4 +Berettapwnge BergJr +Bergheimen Bergkamp +Bergr Berk Berkan Berkis Berkven +Bermaitha Bermbommert Bernache +Bernie Mac +Berno +BernyMadoff +Beroepskech +Berraok BerrieFan Berrr Berry +Berry Carry +Berry Soap +BerryBus BerryInBooty Berrys Berrzerk Bersbillus +Berserk FTW +Bert Curtis +Bert NUFC +BertMacklin +Berta B0y Bertie Bertje Bertow +BerttDog Bervoets +Berzerking Berzurkah +Bes +Besin +Besseggen +BesselJ Bessone Best +Best Kio1 +Best Lolz +Best Murmeli +Best Nher yh +Best Realtor +Best Whilbur +BestCat BestDIzzyNA +BestFioraNA +BestHouse +BestInSloth BestJester BestMommyGF BestSenpai +BestVersion +Bestia Solus Besties +Bestkilnot Bestoladec Besty +Besynderligt +BethMeow +Bethany +Bethell Bethevoid Bethrezen +Betray Betta1009 BetterCookie +BettsISale1 Bettuh +BeugLizard Beuglord Beugsmate +BeunDeHaas Beunhaas053 Bevaun Bevelle +Bever Mama BeverGT +BeverlyPils Bevers +Beverst Bevruchter Bevvy Bewaker +Bewq Beyond +Beyond Max +Beyond Mind +BeyondKenzie +Beyond_blitz Beyta Bezbi +Bezdzwieczny Bezeo +BezosTezos +Bferg3 Bfh1master Bfood BgoinHAM +Bhaals Rage Bhakli Bhalobashi Bhangre Bhench0d +Bhillup Bhongk Bhoy Bhrad +Bht Bhuggy +Bi BiBi +BiGtOkEsBrUh BiZaAr3 BiZaM BiZoNaDe +BiasVariance Bibbit7 BibleThump BibleTrump +Bic +Biccins +Bice Bucket +Bicep Peak +Bicep Smooch +Biceps Btw +Bicho BichoFeote Bichslap +BickyChicken Bictim +Bid Whist +BidaFire Biddah +Biddiss Biden +Bidens Slow Bidensity +Bideo_Gabes BieBras +Biebje Biebop Bierliebe BierryTaudet Bierscape09 Biffo89 Biffsy +Bifking Bifta89 +Big Armpit Big Arms Ben +Big Ass Turd +Big Baby Boy +Big Bearius +Big Beets +Big Bennys Big Binotte +Big Boi Ian +Big Boone +Big Brane +Big Bruno +Big Buffalo +Big Buzz OG +Big Bwana +Big C +Big C A S H +Big Calquat +Big Cat Fan +Big Chest +Big Chugger +Big Crafter2 +Big Cypress +Big D Brasco +Big Dav II +Big Delts +Big Discus +Big Dog Sly +Big Donads +Big Dumb Zac +Big Eazy +Big Erecshun +Big Genitals +Big Geordie +Big Gol +Big Gorg Big Grorb +Big Guy Hax +Big Hingus +Big Hoss Lad +Big Jake +Big Jezza +Big Jim Hun +Big Johnnyy +Big Josher +Big Krukke +Big Latvian +Big Lesbo +Big Lew +Big Mag +Big Meth Big Mike +Big Mo +Big Mooch +Big N LilCox +Big O Wiener +Big Ole +Big Ole Dog +Big Pancaker +Big Poopa +Big Rek +Big Sage +Big Scoops +Big Seaweed +Big Shaq +Big Slick +Big Slurpp +Big Smi +Big Stivz +Big Suze +Big T +Big Tanz +Big Tripod +Big Zaff +Big mfkn Obi +Big ol Bag +Big rOve Big0neNC +BigBad Matt BigBadPurps BigBaller BigBallsagna BigBankTake +BigBantonio BigBaseNZ +BigBear675 BigBenPies +BigBinkus BigBlackCats +BigBlueCox +BigBoiiiBuzz +BigBoyBorri +BigBrad Wolf BigBrownMan +BigBtheOG BigBug +BigBulli BigBustUp BigBwanaCox +BigChinger +BigChuggen +BigChung99 +BigCitta BigCoatBrum +BigCruch +BigD Randy +BigDSurgery BigDaddyBomb BigDaddyEddy +BigDaddyMeme BigDaddyNate BigDaddyT85 +BigDick Q +BigDillz +BigDonKeedic BigDrizzleRS BigDug4U BigEar +BigEgoSmolPP +BigGreenEgg BigGuy +BigHatxLogan +BigHeadPG +BigHootyBoot +BigIronPanda +BigKusa BigLemonTree +BigLez71 +BigLiftsDad +BigLoadOfOof +BigLovve +BigLuke69420 +BigMainKilla BigMav0416 BigMilkerz BigMo +BigNerdd BigPapaDank +BigPapaya BigPepega +BigQuadric3p +BigRaph +BigRat17 BigRedDog +BigRedRodney +BigRickusTra BigRodger +BigSack2 +BigSammyD BigSappas +BigShot BTW BigSikTv BigSpook BigTastyy BigTimmy +BigUp01 BigX BigYitties +BigZikEnergy +Big_B0g +Big_Beard Bigballsac Bigbenslayer Bigborncrazy +Bigboy0007 +Bigboytec Bigcros Bigdaddy Bigdrongo +Bigex Bigg +BiggSackss +Bigga Boi +BiggerNDumbr Biggie +BiggieChonks +BiggieMcLarg +Biggieeeeeee +Biggiemollz +Biggies Maul +Biggums +Biggumz +Biggus +BiggusSnails Biggy BiggySauce Bighomiedebo +Bigjwood +Biglex GIM Bigmet +Bignoob80 +BignoseChris Bigred8616 Bigrigcoin +Bigripper420 Bigrobowskki +Bigtor Bigwildo010 Bigwilly597 +BigxFisch Bigz +Biic Biig +Biig Boobies BiigHatLogan +Biig_Boi +Biiggg B Biitter +BijnaMax +Bijstandswet Bijuzin +Biked Biku Bikura +Bil28 +Bilal Awan +Bilbalbek Bilbo +Bilbo Dabins +Bilbo55510 Bilboro Bilby Bilde Bilie +Bilk Mowl +Bilkos_Ices Bill +Bill Niah +Bill Smiff +Bill Ward +Bill Wigly Billa Billest +Billfish1 Billgodyz +Billie Boi +Billie Gin Billiee Billington Billjetti Billogbfd BillowyMilk +Bills Late +Bills PC BillsITIafia Billy +Billy Blunts +Billy Buchu +Billy H-M +Billy Joe77 +Billy Plates +Billy Tonka BillyBob546 +BillyBonka +BillyMav BillyNotRlly BillyRay Billyn +Billyreino +Billz xd BillzNSkillz +Bily Mavrick Bilybil +Bimmers Bingerss Bingo +Bingo Carla BingoBango Bingus +Bingy lol Binki2021 +Binkleborp +BinksBrew +Binky Stinky Binneli Binny +Bins78 +Binv +Bio s BioCosmic BioFrank +BioMasterZap Bioavailable Bioch +BiofieldMage Biohazard541 +Biomutant +Bionic Muse BionicKing +BionicalWolf Bionicle1395 Bionycle +Biosafety +Bioterrorism Bip0lar BipedalBear Bird +Bird Ibex +Bird Tickler BirdFactsr +BirdFarmRun Birdger +Birdie Train +Birdie713 +Birdies +Birdman +Birdman593 BirdmanZ17 +Birdmanjr07 Birdnesto Birds +BirdsNotRea1 +BirdyguyFe Birelis +Birjeldadge Birk +Birkenau88 +Birkenstock Birkenstocks +BiroGanda Birth +Birthfather +Bis +Biscape Bisccy +Biscuit +Biscuit Cats Biscuitnipz +Bishbasher +Bishbosch Bisher +Bishop Shane +Biskante +BiskyRizness Bison Bisq Bisse Bisun +Bit Bald BitScottish +Bitcoin Z Bitdefender1 Bitesized Bitey Bithc Bits +Bits Init +Bitsy Bee Bitte +Bitterkoekje +Bittles +Bitttimon +Bittykat +Bitwalker +Bitza BixT +Bizanovic +Bizarre Hobo +Bizk Bizness +Bizotic +Bizoune +Bizwald Bj0rnsson Bjarne +Bjarngrim +Bjergstroem +Bjonny +Bjorhn Bjorn +Bjorn XXVI +Bk BkGime Bkedlikelays +Bkeezy +Bken Bkguytd6 Bkostas Bl0od +Bl0od Legion +Bl0odFenix +BlG FROSTY +BlG MOBY +BlG POO +BlG WOODY +BlNA +BlSHNU BlZZ Blaaaaake Blaack +Blablibla101 Blac +Blaccy1 Black +Black Atlass +Black Bears +Black Bro +Black Caucus +Black Fuel +Black Hole +Black Hunlef +Black R X +Black Rifle +Black Upa +Black User +Black lv +BlackAliss BlackAwaken +BlackCawfee BlackCloud BlackHawkEye +BlackNuget BlackPyramid BlackTurtles BlackWidowM +Blacka +Blackasses3 Blackbandits Blackbelt Blackberry +BlackdRedHed Blackdahlia1 +Blacked Out Blackeye603 +Blackking435 BlacklMamba Blacklmp Blacknight +Blackout20XX +Blackpak Blackplosive Blacksamuri2 +Blackstar755 Blacktide1 Bladbro BladeTongue +BladeWizz24 +BladeXFury +Bladeboy6 Blademail +Bladenight69 +BladesEspada Bladypus Blaest +Blaf +Blag0 Blainyckz BlairChan +Blairzy Blaise +Blaise Green +Blaise22689 BlaiseDebest Blak +Blak Deshi +Blak Hawk987 BlakHammah BlakTooth Blakaraknid Blakdragon Blake +Blake Bar +BlakeOCE Blakeboi Blakeeeeee Blakely +Blakerke +Blakey3 Blakk Blakkeyy Blakpn0y Blame +Blame Blitz +Blame Dave Blamed +Blamer Blamp +Blank Face +BlankTree +Blanka1990 Blanke +Blankfillin +Blanks +Blap Blapa +BlaqBeard Blard +Blare Blaser Blasphemy Blast +Blast Bepe +Blastoise Blastrune995 Blaszczy16 Blattermans +Blauwe Brief Blaze +Blaze Hooker +Blaze King +BlazeBaked BlazeItDad +BlazeThatSht BlazeWhale Blazed +Blazed GIM BlazedRanarr +Blazed_Chip +Blazer Kdog +Blazer-31 +BlazerSven +Blazikenite +Blazin Blazinbiscut +BlazingGood BlazingREAPZ BlazingSid Blck +Bleak Days Bleak House Bleakair Bleasi BledReborn Bleekybleeky +BleepMyBloop Blehalol Bleidas +Bleiesnus Bleifuss +Bleken88 +BlendedWhale Blendon BlessOneTime BlessTime +Blessdd Blessed +Blessed IM +Blessed N L +Blessedcrypt Blessin +Blessnt +Bleuski Blevins33 Blew Bleyage @@ -2746,72 +5937,155 @@ Blije Blimey Blimpie33 Blimpysaur +Blind Yeti +Blind1 BlindByron BlindSamael Blindblinker +Blindeyy Blindspott +Blindwizard Blingblin255 Blinger Blink +Blinx337 +Blioneer +BlissWarrior BlissfulDrgn BlissfulIron Blisss +Blista Blistered Blithering +BlitzJuuls Blitze BlitzedBoss Blixtslag +BlizSukzNuts BlizZinski +Blizz of Ozz +Blizzard343 Blizzartd +Blk Kush Blkbeard22 Blkup Bloat Bloated +Bloats hard Blob Blobman1 Block +Block XD Blockhead +Blodmire +Blodreiina +Blodreina 1 +Blody Mess 2 +Bloedkuul +Bloeps +Blogmas +Bloke Kisser +Blom Blombo Blommer1 Blonde +Blonde Don Blonket +Bloo2 Blood +Blood Face09 +Blood Lotion +Blood Man478 +Blood Moor +Blood Rift +Blood Spawn +Blood Spawns +Blood Turd +Blood Vials +Blood Voss +Blood Wyrm +Blood0fhell Blood4Peace BloodWarzz Bloodfan0 Bloodgeon Bloodiedawn +Bloodlet +Bloodmaged +Bloodrave182 Bloodraven +Bloodredmano Bloodshade +Bloodsheds Bloodsportt +Bloody Scarf +BloodyMurder +Bloodyengine +Bloodyrootz Bloodytem BloomBouquet Blooms +Bloons TD +Blops Far +Blorgons +Blosh Blote Blouch +Blow Off +BlowBiden Blowd +Blowin Ohs +BlowingPipe Blown BlownbyTwins +Blowup Dolz BlowyBarry +Blu Ocean +Blu3Mink96 +Blu3print Blu3s BluAnimal +BluNightfall BluSPANKSyou BluSlidePark +Blubberboy BludMaul +Bludclat Bludgeoner0 +Bludime504 Blue +Blue 420 +Blue Atmos +Blue Fox 64 +Blue Inn +Blue Jay +Blue Legend +Blue Limes +Blue Nahuatl +Blue Osiris1 +Blue Oyster +Blue Summer +Blue Trex +Blue Winds +Blue Ziv +Blue305 BlueBoat +BlueBorough BlueCashews BlueDHYDshld BlueFrogsOP +BlueGwapes BlueHawkie +BlueHornet BlueJob BlueLegendzz BlueLemon66 BlueLine BlueLite +BlueMandril BlueMeanEyes BlueMuff1n +BlueOverkill BlueRanger BlueRose91 BlueTyphoon @@ -2820,61 +6094,108 @@ Bluebears Bluebury Bluecaps09 Blued +Blueface G Bluefir Blueluna Bluemoon97 Blueprint19 Blueqerry Bluerope14 +Blues 1 Clue Bluescreen +Blueshores +Bluestopher Bluetiger919 Bluewarthog +Bluexy +Blueyy04 Bluez Bluezaros Bluff Blufire +Blumkohl +Blump King Blunt +BluntBird +BluntSurgeon BluntTaster Bluntmore Bluntobject Bluntology Blunts +Blunty Pyro BluntzyMcGee +BlurOfLight +Blurr62 Blurred +Blurtt Blusaunders +Blut Arteiri Bluternite +Bluutooth +BluzCluzz +Blxke Blyat Blyckertski +Blyocr +Blze Bmart Bmaylor +Bmeg Bmoot +BmwNerd +BnB Bnaar +Bo Ed +Bo Selecta +Bo0nies +BoBgss126 +BoBoTaeTo Boa92 Boabs Boagrious Boang Boas +Boater lad +Boats N Hoos +Bob Blinger +Bob Burglar +Bob Kelso +Bob Lebowski +Bob Marley +Bob Shermon +Bob Violet Bob11790 Bob19922 Bob44th +BobBojangles +BobCatMilk BobGuenille BobNegao BobRossDied BobTheDaddy BobaNeZmogus Bobakadush +BobbaStanley Bobbanxd Bobbiie Bobby Bobby Brawl +Bobby JoJo +Bobby Lash7 BobbyBigLips +BobbyBonk +BobbyShurda BobbySmooth Bobbyccf Bobbydrake09 +Bobbysweggg BobbyyHill Bobi Bobicles2 Bobidabob +Bobite92 +Bobo Bagins Bobrobber Bobrusu Bobs @@ -2882,45 +6203,82 @@ Bobsaytoad Bobtunafish Bobvill Boca +Boca Raton +Bocaj +Boccle Bockovie +BockyOG Bodaajamies Bodacious Boddy +Bodhy BodisDelotis Bodjery Bodlamadrid Body +Body Kit +BodyRune +Bodyart +Bodybuilding Bodyguerdson +Boe f Boed Boeing Boeing MAX Boekanier +Boemsjaka Boer +Boer Salad +BoerJohannes Boerboel +Bofad Esnuts +Bofas Boff +Bog Jr BogDomen +Bogalog Bogart +Bogby Bogchamp +Bogged Dacks +Boggmonster +Boggsy III Bogi153 Boginskaya Bogmellon +Bogusbart +Bohachii Boham Bohejmen Bohn BohneSaw +BohnerSoup BoilerMakerr Boints +Boise Bronco +Bojaroff +BokOrmen +Bokbok9 Bokeva Bokje1 Boko BolaRobin Bold +Bold Smut +BoldPelipper BoldandBrash BoldupG Bolibomba BolleBenny +Bollieflex +Bologang +BolsaDeCoco +Bolsta +Boltagon +BoltonRamsay Boltzzzzz Bomb +Bomb Squad Bombergray Bomboy Bombu @@ -2928,76 +6286,171 @@ Bomer Bommerche Bommijn Bompa +Bompanero +Bompton Bomtastic +Bon Pa Tin +Bon fee BonQong Bonar +Bonar Slayer Bond +Bond Digger +Bond Huntin Bond09 +Bond4MyIron +BondBought BondedLiam +Bondegang Bonden +Bondi altti +Bondify Bondkyle +Bondoos Bonduwel Bondz +Bone Hawk +Bone Man +Bone Medic +Bone Thugsz Bone Ur Hole +BoneSurgeon Bonecrushing Bonedork Bonehead Bonen2 +BonerMachine Bones2Peach BonesNAltars +Bonez III +Bonfire1 +Bonfire237 +Bong Lenis +Bong Quixote +Bong Squats +BongAppetite +BongSec +BongTokez +BongZiller +Bonglefin +Bongletopper +Bonglewongle +BongoBasse78 BongoRider +Bongobodil +Bongotree +Bonh +Bonjwa1 +Bonk Weekly Bonkers517 +Bonkeykong Bonnaroovian BonnieTHICCC Bonnyjoy1 +Bonnyyyyy Bonus Bony +Boo Duh Boo5tn +BooBaker +Boob +Boob Dragon +Boob Slip +Boob zilla +Boobini Booblee +Boobs Mom BoobyHill +Booca +Booduh +Booffee +Boofqueefius Booger +Booger Ballz BoogerSnacks +Boogeyman Boogie +Boogie339 +BoogieCorgi Boogieman +BoogurBoy Booiesblazin Boojwazee +Book +Book of Sand +Bookie Killa Bookless +Booksmart BooleanSpl1t BoolinScape Booll05 Booloo +BoomBangPow8 +BoomFire69 BoomFloof +BoomMatt Boomdead123 +Boomerclicks +Boomfire2 Boomfire9 +Boomhakik +Boomjuice Boomstick08 Boondow +Booney Tunes Boookuh +BoopBeepBeep Booped +Boopette Boopie +Booping +BooptSnoot +Boorrie Boost Boost736 +Boosted six +BoostedBruh Boostedd Boostergold Boostify BoostyBetard Boot +Booteelick Boothanqq Boothyy BootieMix +Booties Bootihole Bootlesape Bootsjunge Booty +Booty Dishes +Booty Kev +Booty McDab +Booty Sensei +BootyCheek +BootyGod Zac +BootyNasty +Bootypixels Booxia3 +Booyeh Booze Boozem +Boozeobagins BoozyBirdy BoozyXander +Bop +Bopla +Bopoman +Boppin Bora Borads +Boramoss Borderguard Boreall Bored +Bored Idea +Bored Ingame BoredMalamut Bored_IRon5 BorenZo @@ -3006,8 +6459,13 @@ Borgiie Boriix BoringName Boris +Boris King7 +Boris sfisgh +Borkiin BorkingCorp Born +Born Abroad +Born to Hodl BornToTrade BornTwoGrind BornofDragon @@ -3017,203 +6475,421 @@ Boromer23 Borring Borsten Borussia +Bos Marmot Bos9 +BosNaes +Bosco Wong Bosh Boshby Bosif +Bosnald Bosnian Bosnier Boson Boss +Boss 4 Pet +Boss Biz +Boss Fights +Boss Mati +Boss Mei +Boss Rarkley +Boss Slayer Boss4Days BossMan BossMann +BossOnly100 +Bossalinie Bosses +Bossin x Bossk +BossmanJCriz Bossnian BossyEnemy +Bostin Loyd +Boston Tony Bosw8er +Bot Detected +Bot Matt +Bot Owen +Bot To 2277 +Bot for dayz +Bot player BotBooster Bothbalgone +Botman1431 Botsii Botsji Bottatrice +Bottlewin BottnScheise Bottrill +Botty Boub Bought +Bought Cape +Bought Gear +Boules Boulli120 Bouncy +Bound Books +Bounzy +Bourbon Time Bourgeoiis +Bournos Boutopia Bouwkundige +Bouwmans Boven Bovine +Bovyy +Bow And K0 Bow1ng Bow2ThyQueen +BowIads Bowbby Bower +Bowfa Barry +Bowfa Dees Bowin Bowinkle +Bowjacked Bowl BowlCutMonty BowlNutta BowlPacked +BowlResin Bowlcut +Bowleo +BowlerBTW +Bowlhead Bown Bownerator +Bowny20 +BowsB4Hose Bowse +Bowser Jr BowserSideB Bowwsy +Box Art +Box Office +Box T +Box Therapy +Box of Rain +BoxOGnomes Boxacle Boxedup +Boxer +Boxic BoxingNugget Boxio Boxse Boxxie Boxxy +Boxy +Boy Mobile +Boy Wonder +Boydem Boydie4427 +Boyfredaaa +BoylifeInNZ Boys +Boys Broke +Boys No Good +BoysAndGirls +BoysenBill Boysennn Boyyo Boze +Boze Worm +Boze mol BozeOog +Bozut +Br ay +Br ibb +Br yan Br00dje +Br0ox +Br0wnSpit Br3ws +Br4dders Br4w Br5andon BraBraBrad +Braaamps +Brabbss Brad +Brad RS +Brad T King +Brad017 BradIsAChad BradIsChad +BradKavanagh BraddahPoppz Braddahoodz +Braddict Brader +Bradj_55 +Bradlem95 +Bradleyussy +Bradlio Bradolai +Brads Wrath +BradyDezNutz +Bradycus Bragon Brah +Brahamus Brahu +Brain Drill +Brain Kancer +Brain Stim +Brain Sucker Brainiac2018 +BrainrotMaxx Brainsquash Braithy Brajen Brak Brakathor +Brakence +Brakke Bever +Brakza +Brallerx Bram +Bram91 BramDx Brambickle Brambo100 +Bramboo +Brammie +Bramxoo Bramziee Bran +Bran dont +BranDaMfMan +Branch Brand +BrandNewHere Branden +Brandi Rose Brandir Brandish Brando +Brando n +Brando23x Brandog Brandon +Brandon 126 +Brandon TJ Brandon9250 BrandonLarge Brandonp32 Brandonx188 Branflakez +Brannttt +Bransk +Bransterdamn Brap BrasilHemp +BraskaDad Brass +Brassy Bird BrastaSauce +BratusB +BraunBrains +BravSlav BraveBear +Bravenewfy +Braves Bravest Bravo +Bravo Eagle +Bravo Lv +Bravo8 Scav +Brawl Brawlers +BraxMax +Braxt +Bray0420 Braydons Braylor Brazden +Brazeheart Brazzerker +Brb Delivery Brblol +Brdy Breaches Bread +Bread Again +Bread Dead +Bread Init +Breadatour Breadhats +Break3r Gabe Breakchance Breakdownz +Breaver Brech Bredbeddle Breeann Breeno Breenus +Breeoh +Breez +Breezeeh Breezy +Breezy Jai +Breezy2277 +BreezyMT Breffest Breivig +BrejchaBoris Brejin +Brelinguette Bremen71 +Brendann Brendvn +Brenkku Brenkolovski +Brennzo +Brent Ham Brent4000100 Brentiscoool +Brenty88 +Breskvice +Bressjul Bret BretHammy24 Breth +Brett who +Brett6910 +BrettThePunk Brettdog Bretz +Brevetted Brew +Brew Dr +Brew IPA +BrewceWillis Brewdo +Brewin BrewskiGod Brewsley Brewsy +Brex Brexit Brezell Brezzy +Brian Dub Brian-senpai +Brian1234146 +Brian4755 Brian8781 Brianmyth +Brick Brick Brick49 Brickerino +Brickhead +Brickhooouse Brickhouse +Bridding +BridgeFourr +Bridger +Brie Larson +Brieenne Brief +Briefly +Briggs +Bright Day22 Brightest +Brightly +Brihyun +Briickzz Briidi Brin Brinfish Bring Bringtheheat +Brinkler Brinkosaurus Brinsgr Brisiinger +Briskly Brispy +Brist Brit Brite +British Diet +British bamf Britswelll Brittanys +Brittanyx Brlm BrntSausages +Bro bee +BroTwoTher BroUFailLol +Broad Broadboat +Broadday Brobasaurus Brobible +Brobin +Brocadillo Brocaine +BroccCheddar BroccoIi BroceanMan Brocepticon Brocknation +Brocolis +BroderPierre Brodie Brodie410 Brodie827 +Brodisi Jr +Brododore +Brodus Clay Brodymon316 +Broekloos +Broficiency +Broft Brogfrogdog +Broha +Brohard Broiled +Broken Cpu +Broken DPS +Broken Hip +Broken Top BrokenBones Brokenn +Brokensunset Brokk +BrokkMachine +BroknScrotum Broko Brolic Broly Bromagic +Bromatron Bromerly +Bromosapienn +Bromz +Bron Yr Aur2 Bronkey Bront +Bronxie Bronxy +Bronze Cow +Bronze Eel +Bronze Moose Bronze5 BronzeDong BronzeWorthy +Bronzegnu199 +Bronzr Bronzy BrooceWillis Broodje @@ -3221,38 +6897,69 @@ Broodoos Brooke Brookesbeast Brookfield +Brooksher +Brooksy BroomInBum Broomi Brootloops +Brootuss +Broque Bros Brosaph +Brosoul +Brossy Brotatochip +BrothaForest Brother BrotherChong +Brothermon Brotherr +Brotholomew Brown +Brown692 GIM +BrownTree +BrownTree63 Brownecakes Brownmo +Brrandon +Brrd +Brrinn +Brrr Zeus +Brthdy +Bru now Bruce +Bruce Jenr BruceJennder BruceNutty BruceWayme Bruceh +BruciebearTV Bruenor +Bruffell +Bruges Bruh Bruhh +BruhhChungus +Bruhs Bruiser Brumaks Brumle Brundeen Brundles +Brundo Brungoil +Bruno p15 Brus Brutal Brute Brutescape +Bruthar +Brutified +Brutzli Bruut +Bruva Eww Brvte +Brwny-mix Bryan BryanFury Bryannn @@ -3261,88 +6968,152 @@ Bryce Brychu Bryci Brycikins +Bryham0 +Brynildsen +Brynmor Brys Journey Bryson Brysons Brystreams Bryu Bryymstick +Bsakke Bsaunders0 +Bse +Bsgs Bsketbl +Bskli +Bslayer Bthomson Btownballer Btrec +Btv +Btw Das +Btw Guy +Btw tietjes +BtwBallo BtwImJoe BtwTradeMe +Bu nny Bu11itt +Bu11seye00 BuBszs +BuDzNBooze +BuLLeT PVM Bub Josh +Bub389 Bubba +Bubba Gage +Bubba Watson Bubbateux +Bubbba Bubble +Bubble Butts +Bubble Tea65 BubbleBlob BubbleJuice BubbleOLuke Bubbleguy Bubblenab BubblesGO +Bubblies Bubbo Bubbz +Bubgi moment +Bubo Bubu Bubzs +Bucc ees +Buccsta Buchu +Buchu Bong +Buchu Daddy Bucito Buck +Buck Oakly BuckNastyy Buckeye BuckinThanos +Buckjames Buckner1 Buckner20 +Bud Right BudLightBtls +BudSake Budabupbup Buddaball BuddahCheese +Buddeke BuddhaPuck +Buddweiiser Buddy +Buddy Waters BuddyGuy +BuddyJ Budgen Budget Budgets Budjeke Budpotamous +Buds Bud +Budsteel Budster Buduhhh +Budward Budwise +Budzinski Budzliteyear +Budzyn Buff +Buff Bezos +Buff Mafia +BuffFridge Buffel +Buffel x Bufubu +Bug V2 +Bugalado +Bugaloo Bugazzi +BugcatMoo Bugg +Bugg XO +Bugis x Bugs +Bugs c Bugsaur +Bugyo Bugyy +Bugziee Bugzy Buhe Buhnuhnuh Buhole Build3d Built +Built Dfrnt +BuiltToSpill BukesCarKey Bukkakey +Bukkele +Bukmyhr +BukseFar Bukt Bula +Bulb_a_saur Bulba BulbaThor Buli Bulk Bulkier BulkyTrout46 +Bull Shifter BullSharkBob Bulldawg1289 Bulldogs815 Bulldozer297 BulleT1017 +Bullerbyn Bullet135191 BulletBlitz Bullschiff @@ -3351,91 +7122,180 @@ Bulltill Buloz Bultac Bulte +Bum Hole +Bum Vinegar BumPounder Bumble +Bumblethumps Bumjam +Bummer +Bummholee +Bumveld +BunanaMuffin +BunanuhBread Bunceylad Bundle +Bundy red +Bungle Bug +Bungstar BungusBoi +Bunion Bunjamino +Bunni Pig Bunns +Bunns Dying Bunny +Bunny DeIron +BunnyRabb1t Bunnytrack +Bunq Bunryl Buns Buntian +Bunty Boy Bunzosteele +Buorin +Bup Buqqi Bur eye on +Bur y +Burak I Buray Burec Burens +Burensbd Bureze Burezz +Burg de Rott Burger +Burgerb0y Burgerr +Buri Burial Burials +Buried Mole Buriial Burkekey +Burkkle Burly +Burlyy +Burmecia Burn +Burn Herbal +Burn With Me +Burn t BurnMyChi1d +Burna Boy Burnardo Burnari Burnceller Burned BurnedIron Burners +Burnetplanet BurnhamAll12 Burnin +BurninOctane BurninStarIV BurningBrian +BurningCole BurningFight BurningKushh Burningdavid Burninghippo +Burnley Burns +Burns Green Burnstown Burnt +Burnt Bonez +Burnt Bunz +Burnt Senpai +Burnt cod +Burnt lol BurntT +Burntmeat BurnzWhnIPvp +Burnzaloree Burnzie Burp +Burpenen Burpsy Burrkle Burst +Bursts Burwell Bury BuryMeDeep Busch +Busch Ebba Buschhhhhhhh Buschhuscher +Buschkilla Bushbaby Bushido +Bushido Jack +BushidoNegro Bussch Bussino +Bussy Bwana Bust Bustard Busted +Busted Shaft +BusterBlader +Busternut +Bustinbibear +BustyBarry +BustySaurus +Busy Phat BusyDayToday BusyRightNow ButMuhMain +Buthole +Butinz +Butje Kef Butlergunner +Butt Clouds +Butt King +Butt Liquor +Butt Plog +ButtChugr +ButtExpert Butter +Butter Sock +ButterSirup ButterSyrup Butterbur Butters +Buttgers Butthxle ButtnCLICKER +Buttt Mud Butzaf06 +Buu Blat +Buuloki +Buurtpooier Buus Buutsika Buwuchu Buwuchuu +Buxi +Buxom Lady +Buy Wards +BuyBitcoin01 +BuyGF_1GP +Buyer Beware Buying +Buying IG GF +Buying gf 2M +Buying99rc BuyingRsGfs +Buzi Mi Daj +Buzi Syrom Buzin +Buzin Benji +Buzy BuzzL1teBeer BuzzMax Buzzard @@ -3444,121 +7304,294 @@ Buzzlghtbeer Buzzzwin Bvanana Bville23 +Bwan a Bwana +Bwana Brah +Bwana Haz +Bwana I +Bwana Rat +Bwana TK +Bwana Zander Bwana-senpai BwanaObama +BwanaOnDrugs +Bwanah Bwananabread Bwanario Bwanner +Bwarath Bwekfast Bwekfeest Bwie +Bwila Bwse +Bxao Bxdhi +Bxo +ByDesign +Bye Felicia +Bye Friend +Byles Bynguyen Byrd +Byrd Gang +Byrd Park Byrne ByteMeM8 Byzo Bztm +C 678 +C A M R O N +C A R S 0 N +C A R S O N +C Biologist +C D C D C D +C H l S E L +C H l Z E L +C HARL IE +C HlCKEN +C J 102 +C L A M P +C L U E 5 +C Maelstrom +C Mauricio +C OLLINGWOOD +C R I X US +C RoyMustang +C Rx +C S +C Sol +C Trafalgar +C W +C Wills +C a c h e +C a le b +C a r lo +C a sp er +C alvarium +C amel +C e v +C eej +C h a ds +C hap +C hristt +C ip +C itadel +C lhris +C nr +C ntmaster +C o r a l +C oach +C orgi +C osmos +C oty +C rafter +C raig +C raiig +C rux +C u r t +C x L C-11 +C-53 C-Dom +C-Stones +C-bat +C00RS Light C00per +C0Dl +C0LTE +C0MBAT 126 +C0RAZON +C0SA C0WK C0XG0BBLER +C0Xsuka4gp C0YS C0c0nUt +C0dy +C0dyssey C0nner C0wanz C11 H15 NO2 +C137 Beth +C18 C18H27NO3 +C204 C2okies +C3 P0 +C33 C3Pz +C4 RL C450 +C4L1BRE C4RL C4RNAG3 +C8M +C9rl CA5E CAKESNIFFER CALL +CAMBO D N CAMEL0T CANNONlNG +CANT SPEAK 0 CAPITALIST CAPSLOCK +CARAPlLS CARDlFF CARROLLYZER +CATS GO NYA CATsmoothies +CBC +CBD Brownie CBK20 CBMPeterson CBas CBomb +CC 9 +CC HM CCCCFF CCCO CCatt CChuk +CConnor CDKein +CDR +CDRMark +CDawg420 CEClL +CEL4L +CEO OF ARK +CEO of TOB +CF5 CFoodBisc CFour CG MindPr0 +CGA +CGC Zeus +CGR +CGoldy CH1P CH3CKMYSW4G +CH4OS_REIGNS CHATBN +CHEEFO CHIEF CHIEFWHALE +CHIEFxKEETH CHOF28 CHOLEZmusic CHOPSTlCKS CHOSENBYNAME +CHR187IAN +CHRlS PRATT +CHRlSDUDE +CHUCKDABANK +CHUDZY CHULIGAN911 +CHURNlN +CHlC-FlL-A CHlCKENS +CHlCKNUGGET CHlLDS +CIA GF PsyOp +CJ McCreery +CJ2K +CJB_01 +CJPez CJlivin11 CJoaboneP +CK the Wise +CK2 +CK9 CKSKEE CKVY171 +CL0wn Inc CL3O CLIIllIIllIT +CMBloodcraft CMER CMMCTk +CMU Chips CMoneyTwo CN77 CNC2112 +CNGT +CO maxplayer +CO0RS CO1N +COKECOKECOKE COLE COM3THAZINE +COM3TS CONFlDENT CORONA CORP +COTTONPlCK3R COVID +COX Kane +COYM COYMauves +CP8 +CPA Scape +CPR +CPT Morghun +CPT-Rock69 +CQJB +CR1SPY_BAC0N CR4ZYH34D +CR7 +CRAI9 CRLmastrFlex CRSSD CRTS CRUSlR CRY0GENIC +CRlMP CRlP CRlSTO CRlTIC CRtallboy +CS6 +CSG0 +CSchicky CT42 CTFU +CV90 CVID +CVTRILLOG +CYP 3A4 CYP450 +CZHANG +C_mrade +Ca 11 +Ca m el Ca3ino +CaL4MiiTYxX CaMOOflaged +CaPl Caam Caater +Cab Up +CabbageSeeds +Cabbi_cs +Cabdi Cabela Cabido +Cabinetsalt +Caboose121 Caboucha Cabouchi Cachalot Cache Cachet +CacklingMagi Cacoadragon Cactus Cactus9k +Cactusaak +Cadallic0 +CadmiumBird Cadov Caduzitcho Cadzie @@ -3567,143 +7600,290 @@ Caelanity Caelums013 Caerus Caesar +Caesar Pasta +Cafe Fraiche +CafeZing +Caffeine +Caffeine Use Caffeiner +Cages +Cagrets Cahors +Cahsmo Caide +Caifan Caifanes +Caillou hobo +Cailthun Cainie Cainn Caio +Cairn08 Cairo Caiser +Caitlin Rice Cajjj Cajun +Cajun Blood +Cajun Fox +Cajun Fries +CajunCrimson Cake +Cake qp CakeBoss1337 +Cakeboy 43 +Cakefound +Caketins +Cal Fong +Cal l u m +Cal-Mag +Cal_C +CalamityD Calamityy Calb_Potta Calbod Calcab Calcd +CalciferGIM +Calcio CalculateWhy Calcusource +Cald0g +Caldaris Caleb +Caleb o_o Caleeba Calf15 Caliace Calibeafall Calibrated +Calibur CaliburZ Calico +Calierazon +Califaa +Califauxeous +Califirona Calimandro Calipha Calipso +Calist0 Calisterie +Calivego Call +Call Me Milo +Call me Cham +Call me m16 +Call0 CallMeCletus CallMeGeorge CallMeJAS CallMeJoey CallMeKeen CallMeKeezy +CallMeLeger +CallMeNoLuck CallMeSofD CallMeStevo CallMeTipz +CallMeow +Call_Me_Arty +Callaghxn777 +Callboy Calliburr +Calliott Callisto +Callisto Cub CallmeZach Callmekee +CallumTM +Calluum +Calm Chris CalmCombo CalmDownSon CalmYourBits Calmoran +Calo3 +Calquat +CalquatFruit Calster26 Calu Calum Calvi +Calvi n Calvin +Calvin924 Calyxsys Calzano Calzone +CalzonePizza +Cam Jong-Fe +Cam Jong-Un +Cam Rebuild +CamAlot_iron CamDeezy CamLite +Camakie Camaniack +Camargue +Camb o Cambeezy +CamboSliice Cambridge +Cambulance +Camdenan +Camel Glue +Camel Neckit +CamelActive +Camelm8 +Camerocity CameronNeal Camhanaich +Camil Camion Camise Camm +Cammo545 Cammy +Cammy Ded Camosaur +CampBingBong Campbell Camperfish CampinOnline +Campisii +Campus Crew Camsdadddy Camshows Can Berry +Can Fe Spoon +Can U C Me7 +Can it Bozo +Can0fBeans CanChem CanMJ +CanManCannon +CanOManBFTM +CanUGetAway Canada CanadaBawd +CanadaGuuse +CanadaScape2 CanadasChief Canadian +Canadian Bc +CanadianDevi CanadianYeti Canadiehn Canadiian +Canan32 +Canberk +Cancel Cancelled +Cancelled It Cancer7 +Cancerfree24 Cancerios +Canderos +Candlebox Candrok Candy CandyFlipin CandyKing42 -Capt -Capt420 +CandyKing420 +CaneCorso Canear Canehdiann Canibalistic Caniz Cann +Cannabinoidz +Canned Beer +CannibalGK Cannibble CannoliBoi +Cannolis Cannondorf Cannot +Cannot Login +Cannrrrr +Canon Bob Canook Canowhoopazz Canserber0 Cant +Cant Quit 07 CantCasino +CantMaxBc69 +CantTalkPerm CantThink +CantTradeTho Canta Cantaloupe +Cantclik4sht Canter Cantina +Canting Cantu +Canyonranger CaoFasho +Caoe +Cap E Bara Cap10 +Capalotty +Cape Fear +Cape Max +Cape Seller CapeScape +CapeZer0 Caped Capez CapiiTano CapitalGainz Capitalise +Capitalist34 +Capn Wahle CapnCookd CapnMeliodas Capniq +Capnplant +Capo Yamato Capone Capos +Capotia Cappe Cappei +Cappie Greek +Capreol Capriccio Caprius Caprix Capsule +Capt +Capt Bobette +Capt Bumi +Capt Dave +Capt G +Capt Halo +Capt Hootler +Capt Kenway +Capt King +Capt Kumquat +Capt Murdoc +Capt Plank +Capt420 CaptHardon CaptLongJon +CaptPleb CaptZilyana Captain +Captain Jack +Captain Lev1 +Captain Tast +Captain Tec +Captain Y +Captain Zoso +CaptainAlice CaptainCanto CaptainCox CaptainDom @@ -3711,6 +7891,7 @@ CaptainDredd CaptainLuker CaptainOboy CaptainObvio +CaptainWalt Captainshiny Captainzzz Captan @@ -3718,44 +7899,62 @@ Captcha CaptinA CaptinKorasi Captinrandom +Captiva Captn +Captn Bear +Captn P00F +Captn Sqirk CaptnCommand CaptnMittens Capu Capussi +CapybaraDung +Car Ram Rod CarNalgas CaraDuraMC Caracal Carademlof CaramelSlice Caratheodory +Carbo Cat Carbolic Carbon +Carbon K CarbonCarbon Carbonist +Carbos Carbyne Carcinoid Carde +Carden CardiacKemba +Cardinxl1 +CardyZ Main Care Carea Caregiver Careo +Caricapaya Cariej CarimsEygon Carino +CarjUIM Carjacking Carked Carkis Carkosa Carl +Carl Sagan CarlBarker CarlDerp CarlSagan80 Carleton789 Carlin +Carlingue +Carlitos Carlo CarlosM +Carlosjavily Carlrip Carls453 Carly @@ -3763,6 +7962,7 @@ Carlyle Carmillae Carna Carnadova +CarneGrande Carnie CarnifexVeil Carnitas @@ -3771,93 +7971,188 @@ Carnzlo Carolan Carp3di3m13 Carpe +Carpenters Carpi Carr CarrickDaddy CarriedBayo +Carrot s +CarrotMilker +Carrs Pasty +Carrutt Carry +Carry Yak +Carry9otter Cars +Cars Suck Carsillas Carsten10 +Carterfish +Cartman Carton +Cartzy +Caru +Carvdogg17 +Carve +Caryopsis +Cas1a CasZeal +Casamigos +Casawn +Casc Casca +Cascola Casell +Caseten CaseyWaff Cash +Cash two Casherbob Cashewk +Cashlemke +Cashs Main Casino +Casino Sand CasinoProblm Casketball Casmatos +Cass Cath CassTheGod Cassarole Cassath Casserolio Cassidyy +Cassie Aram +Cassim +Cassirer Cast +Cast Rate +Cast Turbo Castello Castilla Castorly +Castrophany Casual +Casual Man CasualChris CasualGrinds CasualPete CasualStorm +Casualdkdk +Casualty +Casvel +Casviel +Cat Man1001 +Cat Nips +Cat Shaped +Cat Smuggler +Cat Snacks +Cat Soup +Cat Woman +Cat got out +Cat shirt +CatBoyInHeat +CatPandas CatPissRNG CatSaysMeow +Cataclysm55 +Catala Catalepsy +Catalyticx Catan CatchTheDrop Catchin +Catchin Pets Catchlove Catdog1280 +Catechism +Cater Champ +Catfish Rock Catflap +Catgirl Cafe +CatgirlSan Cath Catharina Cathays Cather Catherbae Cathuntdog +Catman31 Catnip +Catnip Cutie Catnor Catomic123 +Catra Meow +CatsnCars +Catsnarterrr +Catspeak +CattoKitty3 +CauZ Cauldrons Caulf1eld +CaulkPushUps +Caustic Cauterised Cavaleiro888 Cave +Cave Closer +Cave Horror Cavern +Cavern Freak Caves Cavos Cavs Cavsy +Cawrin +Cayk +Cayman 07 Cayrus +Caza Lowell +Cazaq2 Cazik Cazos Cazum Cazwise Cazzakin Cazzy +Cba Ofc +Cba To Carry +Cba To Share CbarDaKing +Cbetrs +Cbf Playing Cbot05 Cc17wo +Ccn Cd777 Cdale +Cdoc +Ceana +Ceb Ceber +Ceceil10 Cecetra CedIsMySon +Cedty +Cee real +Cee-Jay +Ceebooty CeeeHooo +Ceeege +Ceejaydjj +Ceekay Ceeon Ceeps Cefiro Ceio CekicGuc Celach +Celach 2 Celadus24 Celazer Celebio +Celer0 +Celesdel CelestialSun Celestive Celestron @@ -3865,130 +8160,229 @@ Celhon Celi0 Celiac Celikanen +Celine Dijon +Cell Saga +Cell Z Saga +CellaDwella Cellectric Celli Cellmate Celms +Celrisen CeltBrenny Celtic +Celtic Hero +Celtic555 Celtica Celyzh +Cemen Demon Cengkeh +Cennolink Cenpie +Censor +Centac +Centennials +Center Fit Centers +Centershot5 CentraIka +Central CentralC +Centrimag Centropy +Ceo of Timbs +Ceoe +Cephalopods Cepp Ceppt Irn +Cepxy Cera Ceraseus Cerati Cerb +Cerb R Us Cerberus Cerberus98 Cercle Cerea +CerealGuy +Cerebro +Cerenade CeriGG +Cerkev Cermi Cerpin +Cerpin Taxt +Cerpooch Cersey +Cersky +CertIronBoy +CertifiedPoS Cervantes18 CesarPalace Cesema Cetr Cets +Cev Cevap Cevarus Ceverie Cewl +Cewl Hwip +Cexilius Ceyyl +Cf b4 Cfretz244 +Ch i +Ch i c k en +Ch ief Ch00bies Ch0c0tac0 +Ch1cag0 Bear Ch1mes +Ch1noLf +Ch1zz Ch33sy Ch3ckMat3 Ch3spy +ChNPP +Cha rles Cha0ticAngel ChaCha +ChaCha Benny ChaSniff +Chaavez Chaboud Chaboul +Chacaliando +Chacksen Chad +Chad Draven +Chad Stride +Chad Vibes +Chad Wardn +Chad again +Chad isAFK +Chad okeefe +ChadBehavior +ChadCor ChadFratStar ChadMadLad34 +ChadR3333 Chadacas +ChadamantBar Chadders Chadding +Chaddyboy Chadga +Chadieus Chadkiller76 ChadronX +Chaehee Chael +Chaendo G Chaewon +Chaga Chai Chain +Chain Mace Chainn Chainsaw +Chainsaw Guy Chair ChairmanMao +Chaiyse Chaken +Chakleton +Chakra Monk +Chal1ce Chalba +ChaldeanGIM +Chalgrove +Chalk Bar Chalked Challandria Challll Chalva +Cham Cham +Chamariapero ChamberBeast Champ +Champ Ryan +ChampGaryOak Champagnole Champiion +Champion910 Championship Championz Chance2Skill +Chanced Chancellor +Chancie Chandler737 Chando ChangWu Change Changebear Changes +ChangrOfName Chanios +Channel +Channon Chaos +Chaos River ChaosBandego ChaosCleric +ChaosD00M +ChaosGIM +ChaosInbound ChaosJS ChaosedElf1 Chaosfish33 Chaoslynx +Chaotic Cole ChaoticH0B0 ChaoticMoott +ChaoticScorp Chaotixx Chaottic Chaoz Chap Zachman +Chap em up Chapels Chaplain +Chapo Chapoo Chapp +Chappe Chappers Chapter +Char Zeta +Char lang +CharL-32 Character252 Charamio Charatcur Charben Chardonn ChargeN +Chargez Chariot Chariten +Charitonin Charizardz Charlez +CharlieFTG CharlieFine CharlieOHair +CharlieScene CharlieTheIV CharlieWork Charlieb9 +CharliesFE Charloi Charlotta Charltonb +CharlyDarwin Charm Charmey Charmin12 @@ -3996,208 +8390,374 @@ Charmos Charmoul Charms Charmy +Charon0 Charor +Charred Yews Charrysteas +Chartart +Chase Goals +Chase Jones +Chase Riley ChaseGuy ChaseNBake ChasePP Chaser959 +Chasing Pets +ChasingDragz Chasmata +Chasse +Chastised Chatorbait Chattanugget Chatto +Chatty ChaukletZ +Chauman0819 Chauska Chavi Chaz +ChazMac Chazzdiddy ChazzedBangr Chazzy +Chazzy Paws +Cheah +Cheaps Check +Check Point CheckAndMate CheckRaiseHS CheckTheWiki CheckWikiPls +CheckWikiPlz +Checkaaa Checker +Checkley Checkmate CheddLaurent Chedda Chee CheecHnChong +Cheech Blaze +Cheeek Cheeks Cheeky +Cheeky Peeky +Cheeky Prawn +Cheeky Tom CheekyBanter +CheekyCheeto +CheekyDrop Cheelee Cheeno Cheepnis Cheermancy Cheers Cheese +Cheese Borgr +Cheese Slice +CheeseTax +Cheesebubby +Cheeseilton Cheeseit32 +Cheesteri Cheeswiz +CheesySweet Cheesyrice Cheetas CheetoRatFan +Cheetu +Cheex +Cheez-Zits +Cheeze Caper +Cheeze Nepz +CheezeOx Cheezer2000 Cheezewiz0 Cheezo +Cheezuz Cheezyboy25 Chef Chef Bu Fang +Chef Malone +Chef Mihali +Chef Peter +Chef Poopy +Chef Special ChefBoiRJay +Cheff Zaya Cheffrey Cheffy95 +Chefs Cheif Cheimuu +Cheiquispir ChelTheNelf +Chelate_D +Chello Sexy Chellyy +Chelsea Bot Chelsko +Chelsy Chelx Chemanelo ChemicalFade Chemleech +Chems +Chen Luu +Chendlar +Chenzooo +Cheomeister Cherba Cherisu Cherno-byl Chernoblyat +Chernobyl +Cherri Bomb Cherry +Cherry Field Cherrydown CherryxPiex Chesco +Cheshmate Chesscape420 ChessyQ18 Chessyboi Chestbrah +Chestbroh +Chester63 Chesterfi3ld Chestickles +Chestnut Chestodor Chet +Chet Baker +Chet Max +Chet Ripley +Chettos Chevaliers Chevrolet Chevron ChevyB1998 Chew +Chewbacca No Chewbakkaah Chewby +Chewby Lt Chewed Chewitt88 Chewy Chey +Chi hiro +Chi11 Wi11 ChiCity +ChiIdo ChiLongQua +ChiamataM +Chibattagreg +Chibber +Chiboubo Chicanery Chiccbacca ChichaBabby +Chichhuve ChickeNOG Chicken +Chicken Cat Chicken996 ChickenRings Chickenelli Chickenneth +Chickens Inc Chickensnout Chickerolies ChickinNugie +Chico Bean +Chico Cool5 Chicold Chicopee +Chid Heredit Chie ChieFbLuntz Chief +Chief Checka +Chief Gordy +Chief Herres +Chief Otaku +Chief Seneca +Chief Sound +Chief Toxine +Chief812 +ChiefBobert ChiefSmakaHo Chiefss ChieftonP Chiekz +Chiester 45 Chigginwangs Chiiiraq Chika +ChikenLiro Chikinbone Chiksan +Chikupa Chilasr Chilaxinman Chilcos +Childhoods Childish Chilgamesh Chili +Chili Pepper +Chili Popper ChiliTurd Chilibean ChilidogBank Chilidoger +Chilipupper Chill +Chill Mate +Chill Maxxy +Chill Zege ChillAssGuy +ChillHill +ChillScape Chillagalet Chilled Chilli +Chilli Ramen +Chilli dong +ChilliPesto +Chilliam +Chilliburns Chillmitch Chillrend +Chilly +ChillyPolarB ChimJongUn +Chimbilin Chimera364 Chimire Chimmy +Chimneybob +Chimp10n +Chimpywimp ChinStar China ChinaInBox17 ChinaSupaman Chinanumber1 Chinchompin +Chinchonkerz Chinchoopa +Chinegroe Chingie +ChingwaChing +Chinley Chinolc +Chinook Bram +Chinquila Chintan +Chio Bu +Chionophobia Chip Chip Black +Chip Skylark ChipRain +Chipotl e +ChippedHam ChipperyChip Chippy +Chippy btw +Chipsbok +Chipsncrackr Chipster321 Chipz Chisa Chisels +Chiswick +Chitus ChivZz +Chiw ChixDigTbows +Chiyo-Father +Chizle +Chizzet Chkn ChloeTragedy +Chloemacmate Chloes +Chloramine +Chnce +ChoNaWiadro +Chob Choccazz Choche +Choco Flex +ChocoMeteor Chocoblow Chocobo Chocobos Chocomalo14 +Chocys Chodemate +Chodless Chofl Chohanzzz Choi Choicess +Choke Daddy ChoklatMoose Chola Cholesterol Chom +Chombe +ChompVonDile Chompadile +Chompakilla Chompy +Chompy chick Chompys Chon ChonYee +ChonerScaper +Chongsy +ChonkPenguin Chonksta +Chonky Duck +Choobage Choobcob Choochy Chooks Choomb Choooooooch Chop +Chop Rips ChopSthix Chopemania Chopin ChopinDolphy +Chopinaway +Choppa ChoppinWork Chordes Choreboy Chornflakes Choronzon Chosen +Chosh Chow Chowfun +Choybin Choz ChozenGod +Chozen_Azn Chozo +Chozo Lite +Chozo Statue +Chqse +Chr Mck +Chr0nl Chranic ChrdyMcDenis Chri5ty @@ -4205,11 +8765,21 @@ Chriiiis Chriisgg Chrimon Chris +Chris F +Chris JR +Chris Luxon +Chris P3 +Chris Slays +Chris xD Chris0527 Chris1f +ChrisCleans +ChrisFate ChrisHanson ChrisKringle +ChrisOnTilt ChrisTheUnit +ChrisThomps Chrisadk Chrisha Chrishowe @@ -4217,67 +8787,122 @@ Chrisible Chrisjay Chriskies Chrisob +Chrisog Chrispy +Chrispy-sama Chriss +ChrissPIBass Chrissy +Chrissy Tooh +Chrissyx Christ +Christ an +ChristFarley Christiannnn Christidog Christlan +Christmonkee Christoffer Christoker +Christopher ChristyCloud +Chrisxmas Chriz +Chriz297 Chrizzoz95 Chrl Chroist Chromadorr Chromalox Chromatica +Chromi ChromieOX Chromixe Chronepsis Chroner Chronic +Chronic Jack +ChronicChris Chronicflame ChronnerBro +Chrono Aeon ChronoKiller Chronoburn Chronomancer Chronorage Chronos +Chronosanity +Chrostopher +Chrunndle +Chrusee +Chrysaorr Chrysaros Chryserys Chub Chub n Tuck +Chubafet Chubby +Chubby Nomad +Chubs-Magee +Chubsy Bubsy +Chuchin Chuck +Chuck Hoots +Chuck Prime +Chuck truck ChuckChan ChuckDogg +ChuckMeDaddy +ChuckNat ChuckSpedina ChuckTesta Chuckerberg +Chucky Chuda007 Chug +Chug Butt +Chug KoolAid ChugMyPPot +Chugg Jugg Chugga Chugger Chugging +ChumSlugger +Chuml +Chump +Chumpingham ChunchuloX +Chunetops Chung +Chung us +Chungus-kun ChungusClam Chunk +ChunkiCinni +ChunkmanFYB +Chunksy +Chunky Nan +ChunkyGimp Chunkybudda +Chupa Chupperino +Chur Broo +ChurchMouse ChurchTuring Churchfield +Churchieboy +Churd Churlrunone +Churnin Chuzyz +Chvrles Chxmpanzee Chyky Chyna +Chyurr CiSCii Ciamballer +Ciaphas Cain Ciastkowy Cic321 Cicely @@ -4286,241 +8911,447 @@ Cici Cicindelinae Cider CieloQueen +Cigarettez +Cigblaster +Cigggy +Ciggitybutts Cighan +Cignii Ciji +Cim Cimakas Cimelia +Cinamin Cincinnatus Cinderal Cinderhulker +Cindirty +Cinemaxxin CinmarRS +Cinoxe +Cinqoo Cinquain +Ciomsa +Circle Pea +CircleStrafe +Circleone58 +Circomcised +CircularSaw +Circumflexx +Circus Clown Circuz Ciresidnal +Cirexi Cirez Cirmit +Cirn0 +Ciroren +Cirrus Virus +Cirth Ciryatur Cisco +Cisk Cisplatin Ciszak1996 +Cit Funt Citadel +Citadel Wyrm +Citate CitizenTay CitrusLemons +CitrusTree City +City Limits +City Morgue +City Perks Civeo +Civz +Ciziin +Cizre Cizzakillss +Cjg117 Ckale +ClGARO +Cla ws Claca Claco Claiborne +ClairDeLune +ClaireFarr0n Clambam Clamburglar2 +Clan thmoker ClanChats +Clan_Daddy ClankImaTank Clannyy Clanworld Clap3d +ClapMaster4K ClapMeMommy +ClapYouDown +Claptrap ClarKah Clardy2 Clarisse +Clark C +Clarkey BTW Clarky +Clasherz Clasico Classic +Classic Max +ClassicTrap +ClassicVibes Classically Classickxd Classsikh ClassyCod +Claudenstein Claudiu Claw Clawdius Clawsie +Clay Nasty +ClayNugget Claymor Claypops +Clayters Claytn Clayton Clazerbeam Clean +Clean Dishes CleanSleeve CleanedBown Cleann Cleanst Clear +ClearEyes Clearly Cleatis Cleaver CleaverGreen Cledos Clefable +Clefairy +Cleg Drop Cleible Clem Clem585 ClemFandango CleoTehCat +Cleopatraa Cleoxc +Clerric Clethbery ClevelandOH Clevey ClexOrie +Cleyra +Clff Cliche Click +Click Bosses +Click hero ClickAndChil +ClickB8 Clickbait21 +Clicks0nMobs +Cliffder Clifferd +CliffyOG Cliffyy ClimateChang ClimberAZ +Clingy +Clinician +Clinicwater Clint Clinttt Cliphanger1 Clipper +ClipseZ Clipz +Clipz Ahoy CliveTrotter +Clix Cload +Clockwise Clod +Clogged King +Cloggin +Clogging Cloistered Clone +Clone bone ClosedLoop Closertohell Closeshots Closofy +Clotert ClottedCream Cloud +Cloud Cover +Cloud Els +Cloud Griega +Cloud Nine +Cloud Stairs +Cloud Surge +Cloud y +Cloud1K CloudSoftass CloudT +Cloudhill +Cloudi Boi Cloudjumper9 Clouds +Clouds_Song Cloudy +Cloudy Boi +Cloudy Sleep +Cloudy Wolf CloudyOcean Cloudys +Cloudystrife Clouted Clovie Clown +Clown Around Clown0164 +Clownfart7 +Clryy Clss CltRain ClubBruggeKV ClubWolf Clue +Clue More +Clue Relic +Clue box +Cluebringer +Clueful +CluelessKook +Cluer Clues +Clues Hunter +Clumpey Clumsy Clunker ClutchFlipsy Clutchy +Clyde Cooter ClydeBarrow Clynelish Clyps +Cmallz02 CmarBeast Cmndrcool222 +CmokinSrack Cmon +CmptrGmr +Cnbl +Cnhil +Cnr Cnwalker CoFlack +CoKMcGay +CoX Mentor +CoX ToB ToA CoXAcc Co_do_blyat +Coa Coach +Coach Trip +Coach Wright +CoachJal Coachsharter Coal +Coal ore Coan +Coat Throat +Cob Web Cobab Cobalt +CobaltKings CobbMorty +Cobba +Cobplacecow Cobra +CobraChickn Cobreu Cocajumba Coco +CocoGetsLoot +CocoaPuff +CocosLilSimp Codai Code +Code Mellow Codemax Coder00d Coderedcfc Coders Codfish808 Codi +Codonz Cody +Cody Smith +Cody The IM +Cody The M +CodyBeaumont +Codys Nuts Codyx Coeeyyy Coekebakker Coenzyme +Coex +Cofeni +Coffaholic +Coffe277 +Coffee Latte +Coffee Love +Coffee Robot Coffee94 CoffeeAndExp CoffeeBarrel CoffeeIsBest +CoffeeKitty +CoffeeMafia CoffeeQ888 CoffeeSlayer +Coffey +Coffin Cape +Cogelon +Coggle Cogstyle +Coheed Coherent Coilman Coin +CoinToss +Coinism Coipo CokeHogan CokeShoveler +Cokebro +CokedPepsi Col10 ColVolgin Cola +Cola Flesje +Colaboks +Colb y Cold +Cold Bowl +Cold Ham +Cold Hash +Cold Hemp +Cold War Cold1 ColdReign Coldhound591 Coldpiee +Coldraze +Coldrootbeer Coldshop Coldstream +Coldvayne Coldvepz +Coldwar +Coldwoods Cole10083 +ColeEleven ColeQuil +ColeVeryBakd +ColectionPog Colee +Colei Coleus Colgate777 Colienergia Colin Colins +Colivanov +Collan33 CollectMemes +CollectibIes CollectionIM Collectively +Collector of Collega +Collier Collierss +Colliflopter Collin892 CollioKey +Colom ColonColitis Colonel +Colonello ColonialDank Colonne +Color Climax ColorBlindHC ColorMeBlind +Coloradodo ColorfulE Colossus 5 Colossvs Colt +Colt trigger Coltan +Colthound +Coltn Coltrainz1 +Coltsfan1996 Columbot Columbus175 +ColumbusCrew +Colxman Colzy Coma Combaed +Combat Phase +CombatStudy Combatking13 Combibo Comboed Combos Come +Come Loads ComeAtMeBruh Comet Cometz +Comex Comfort Comfortably Comfy +Comfy Butt +Comfy hug Comic +Comic Books ComicalBust Comicmaster0 +ComingHome +Comiya Comlidor +Comm Zilyana +Command Grab +Commander Fh +Commander Ra Commas Commiefornia Common +Common Drop CommonGinger CommunistMoo CommunistPig CompactSugar Companiion Companion +Compd +Compe Compgeek Compilacion Complain @@ -4529,346 +9360,707 @@ CompleteAss CompleteSpud Completes Complex +ComplexTree +Complextro Composing +Composites Comptons Compy +Compyclon ComradSergey +Comrade Hanz +ComradeCas ComradeCovid +ComradeMule +ComradePugs +Con JD +Con Safos +Con ner ConKlave ConaAmadora +Conaizy +Conal +Conceited Concentrates Conchrist Concritus +Conductor4 Cone01 Conedinho +Confederacy Conficker Confidentiel Confined Conflamit +Conflate +Conflict Confuze +Congest Congetus +CongiestMunt Congra ConicLight Conjay +Conjo Conman Connavar +Connee Conner +Conner OK +Connerr Connerxx +Connor M +Connor xv +Connzy Conor +Conor J +Conor07 Conpetgrebe Conqo Conquar +Conquers Conquestions +Conquestti ConradK Consan Considerable Conskis +ConstantZero Constantnips Constellar +Constence Constricted Constructeur +Consumption Contaminate +Contant Geld Contendedd Conterfeit Contes +Contrabant +Contract M +Contradicted ControlAll +Controller Controlllers ControneX Contyy Conventicle +Converter Conway Conydriving +Conyon +Conzila +Conzine +Coob Lad Coogs Cooj Cook4everu Cookdaburra +Cooked Chook +Cooked Sinus Cookedvomit Cooki3Crumb CookiMan Cookie +Cookie Cake +Cookie O_o Cookie904 CookieKid00 +CookieSpec CookieV3 +Cookiers +Cookiezi Cool +Cool Raccoon +Cool Yak 496 +CoolAssName +CoolG WC +CoolNameBrah Coolair Coolavatar1 +Coolboy_cal Cooldesert2 +Coolest91 CoolestCow +Coolio +CoolmanCool Coolmanafo +Coolminer685 Coolmintoreo +Coolmonkey50 +Coolsniper Coolster Coolxkidz Coom Coomcoomber Coonrade Coopa +CoopaTroopah Cooper Cooperative +Coopr Coopsz +Coors Light +CoorsRight +Coorsy Coos +Cooter +Cooter Kick Cootie Coozn Copytopy Coquettish +CorCam Corabex +CoralCastlez CoralFire +CoralReef Corbi +Corbula CorbyTheLad +Cord Core OS Coree +Coreey +Coreling jr Corena Corey CoreyCarlaw CoreyNKH +Coreyeroc Corgi +Corgi Puppy +CorgisIron Corgo +Corinnna Corizz Corleone +Corley Corn +Corn x Holio Cornbuddy +Corndoq +CorneliusIII Cornflake Cornie Cornilius Cornish Cornwall94 Cornwalll +Corny10k Cornye +Corona +Corona Bat +Corona Case Coronad1 Corp -CorpToMax -Corpletics +Corp Scape Corp09RS +CorpLeecher +CorpRng +CorpSlapper +CorpToMax +Corping Bro +Corpletics +CorporalWolf +Correy Lahey +Correyyy CorruptDingo +Cors Corsa Corsetti Cortes +Cortex +Cortica Cortistatin +Cortsen +Corun +Corvanjer +Corvisquire Corvitolis +Corvo Corvoo Corvus +Corvus enca Corwin Corydonn Coryy Corzappy +Cos A Nostra Cosaintus Coseph Coshie Cosmic +Cosmic Booty +Cosmic Star +CosmicPebble +Cosmiclaws +Cosmog Costa +Costah +Costcutters +Costi CostlyOne Costom +Costs Cotched Cotopaxi Cotstini Cottee Cotton +Cottrell Cotty2Hotty +Couch Frame Couchie +Coughey +Count 2Three +Count Cranz +Count Dookie CountCuckula CountDrugula +Counterspell +Countries Country +Country Song Countwert Coupland Coures +CourtnyGears Couscous Cousin +Cousins Couzens90 +Cove Coventrians Coventry Covert +Covert Blade Covid +CovidFree Covvboyz +Cow Door Mat +Cow Foo +Cow Pet +Cow Tongue +Cow Wizard Cow395 CowChum +CowMr101 +CowSalsa +CowVein Cowa +Cowabungalow CowboyK1ller +CowboyKaroo +Cowdenbeath +Cowlories Cowrat +Cowsburp +Cowtongue CowzGoMoopy +Cox out boys +Coxed +CoyieGod +Coz +Cozmic_Raven Cozy Cozzza +Cpl Gaz +Cpl Seeder +Cpt Doobie +Cpt Fail +Cpt Kokopuff +Cpt Mellow +Cpt Mina +Cpt One Eye +Cpt Pepe +Cpt Pop Tart +Cpt Shanks +Cpt TRICKS +Cpt Unclutch +Cpt Wally CptAceRimmer CptKyle +CptRileyy CptRom CptSankara CptSmackAHo +CptUzu Cptainseveto Cptn +Cptn Jack +Cptn Murica +CptnBuckaroo +Cpunek +Cqrl +Cr o Cr0be Cr0codile Cr0z Cr4zyLuck +CrAzY HoRnEt Crab +Crab Emoji +Crab Jazlo +Crab Leaker Crabalt Crabby Crabcore Crader Craft +Craft Brew +Craft Guild +CraftPure +Crafter Jr Craftes Craftsmen Crafty +Crafty Man CraftyRunes +Cragyl Craig +Craig Dawson +Craighead18 +Craizy 8 Craizy9 +Crakced +Crammerr +CranadosX Cranberry Crangus Crank Cranke Cranky +Cranky Cows +CrankyScream +Crantock Crapicorn +Crapping +Crappy Luck CrappyScape Craqers Crash +Crash Crann +Crash Cymbal +Crash Site Crashbot Crashendo +Crashticles +Crateapa +Crateaqa +Cratzi Duhuh Crave +Crave Me +Crave to Max +Craw +Crawfish Crawl2033 Crawn +CrawsBow CrawsMain CrayQuaza Crayons +Crayy Crayzee +Craze NL +Crazed Man CrazedAfro CrazedAgain +Crazedmonkee +CraziKido Crazie Crazy +Crazy 859 +Crazy Canada +Crazy Sam +Crazy Skull +Crazy5115 CrazyDieMan +CrazyDryMan CrazyDutchy CrazyIron85 CrazyShrimp CrazyStuff Crazya0 +Crazyb00b Crazyhalo +Crazys Crazystevee Crazytree Crazzy +Crazzy Ivan +Crcsh CreaMiJeans Cream +Cream City +Cream Guzzle +Cream21 CreamFreesh CreamingPies Creamp +Creamy Fella +Creamy Whole +Creasential +Creat Steal Create CreateNoPain +Created +Creating6 Creator1212 Creator409 CreatorJR +Creaturree Creazy7 +Crecker Fux Crecket Credibility +Credito Creel Creenen Creepy Creezy CreightonRS +Crem Fraiche Cremator Crenoc Crescent +Cressp Cresss +Creston fftp Crevis6 CrewDoe Crewcial Crickets +Crickss Crier Crimewave Crimeway1991 Crimin +Criminaldmge +Criminalised Crimp Crimson CrimsonCow CrimsonDDS +CrimsonJayce CrimsonLily CrimsonRogu3 +CrimsonScape +CrimsonTide CrimsonU +CrimsonWic Crimsoncaim +Crimz0n Crinath +Cringy Grump +Cringy af +CrinsomX +Cripler Cripple Crippled +CrippledKev Crippler +Cripty Cris Crisby Crispiessss Crispy Crispy Bac0n +Crispy I CrispyBreast Crissco515 CristalAlken +Cristierra CriticalX +Criticizer +Critter J Crittx Crixos +Crixus x Criyosphinx Crna +Crna Gora CrnerMcGregr +Croc +CrocDanDee 1 Crocalu +Crocketeere +CrocoMaster Cromeh +Croney +Cronsus Cronus Cronz +Croogus +Crooked Path Crooklyn +Crooshtwoost +Crosby Alt +Crosem Cross +Cross Me Crosswinds Crouchling +Croupz Crow +Crow Mn CrowBox Crown +CrownConvict +CrownRoyal84 Crownescent Crowride1873 +Crowther Croww +Croxy Crozier CrspyPigeon Crudelismo Crudivore +Crue Xena Cruel Cub +Cruel Irony CruelVictory +Cruelcanary Cruixiote +Crumbledoor Crumblers +Crumbways +Crunch7O4 +Crus ty CrusH-HK +CrusadeKlr +Crusadershot +Crush Depth Crushed +Crushed Guam +Crusher9783 +CrusherWake Crushersun Crushertaco +Crushs noob +Crust Cape +Crustie +CrustyDuckr CrustyPusy Crustysnot Crux +Crux da King Crux25 Cruxyy Cruzty +Cruzzetbuzz +Crwfrd Crxk Crxsty +Cry +Cry0nman Cry4help +CryIs0gp +CrySupply Cryge +Crygechamp Crying +Crying Cutie +CrykeeOwO Crynceps Cryo +Cryo Chamber +Cryogen Cryogenica +Cryogenica 2 +Cryogenist +Cryorah Crypthead +CrypticSlays +Cryptling Crypto CryptoKitty CryptoMellow +Cryptonomico Crypzor +Crysaki +Crysh Crystal Crystian +Crzy Mia +Crzyarab +Csajka +Csk x +Cssy CtCandyRandy +Ctclaire999 +Cteel Ctep31 +Cth ulhu Cthrek Ctrengereid Ctrl +Ctrl F +CtrlAltDel x Cuada +Cuat3 Cuatche +Cuattr0 +Cub Will +Cuba Sybre Cubans +Cubed +Cubet +CuckChuck +CuckW +Cuckgex +Cucumbers CudddlyBear +Cujoh +Culemborg +Culinair Culls +Culltist +Cultured +Cultzy +CumHeretic43 +CumanderZili +Cummy Sigil +Cumpaska +Cunnavathing Cunny +Cuno Cuolua +Cuong +Cup Noodle +Cup Of Chai +Cupaplayer Cupcakess Cuppalimmy +Cuppi Cups Cupthebooty +Curaga +Curble +CurdTuttrboi +CuriPolymath Curll +Curls +Curlx Curly CurlyTwist Currancy Curry Storm +Curryleaf Curse +Curse on me Cursed +Cursed Chump +Cursed Nm +Cursed Side +Cursed ll +CursedOwned +CursedRNG oO Cursedpotato Curt +Curtis Jones Curve CurvedHorn CurvyChcken @@ -4876,32 +10068,64 @@ Curzonn Cushco Cushdy Custom +Custom Jr +Custom Sock +Custom TK CustomGFX Cute +Cute Cat lol +Cute Paunch +Cute n o o b CuteClit Cutegirluwu Cuti +Cuties +Cuttableedge +Cutting edge +Cuttl +Cuttle +Cutty Sarks Cuuap Cuult +Cuz im Jones +Cuz im jesus +Cuztom Cuzzo94 +Cuzzu +Cvanz Cvbgn Cvrkster Cvrsn Cw90 Cwab +Cwazza Cweavy Cwer Cwick Cwioktopus Cxffee +Cxld +Cxnnor CyaCyaCyaCya Cyal8rnub Cyan +Cyan Ablaze +Cyasoon +Cybb +Cyber Mind +Cyber n Bug +Cyber172 +CyberJesus CyberSlave18 Cybernautron Cybernike +Cyberpope +Cyborg Musk CyborgHex +Cybron Cycling +Cycling Road +Cyclogy Cyclone2498 Cycloner5 Cyclopedia @@ -4911,227 +10135,534 @@ Cygni CykPyk CykaNuggetzz Cyldan +Cym Cymatics +Cymbaline +CymricCat Cyn2k CynAcolyte Cyncess Cynda +Cyndaquiill +Cyndee +Cyndrakial Cynhi Cynic CynicalSilas Cynocephali +Cynognathus Cynosure +Cynox Cynthaen +Cyodot Cyous Cyox Cypersilver +Cypher Blue Cypress +Cypress H1ll Cyralx Cyrax Cyrax314 Cyriel +Cyrodiil22 Cyroenix Cyruscomrad +Cytain +Cytryn7 Cyuh +Cyum Czacha Czar +Czar I +Czar Trump +Czechmate +Czha Czivend123 +Czk +D A I J I N +D A L M +D A M 0 +D A M I A N D A M N L0L +D A N G I T +D A N N Yy +D A T H I T +D B A +D B Z pker +D Blo +D Clawz +D Darkblader D Derbles +D Dragon124 +D Duberstein +D E C O +D E F Q 0 N D E F Q O N +D E R P +D E V I N +D F U Q +D I Q +D I R T Y Ko +D J Diddles +D Long +D M T Elves +D O D +D O M M E L +D R 6 K E +D R l Z Z T +D Rack4 +D S A V +D Squarius +D U R K +D Wilson +D Wreck +D a mo +D a r t s +D a rk +D a u t o +D a v i d +D amz +D arking +D arkoz +D as +D ashing +D avey +D axe +D db +D ebol +D ecimate +D eej +D eek +D eep +D eez +D en +D enial +D entist +D i l a n +D i x o n +D i zz y +D iesel +D iizzy +D imi +D imitri +D onda +D onger +D oo l ey +D op e +D utchgr +D-D-A D00DLES +D00dey9 D0CTOR D0GS0NG D0NE0 D0NPABLO D0PESIC D0any +D0inkleberg +D0lNK +D0llynho +D0n vi0lad0r D0nte +D1APAM D1GG00BIITTI +D1P D1ZZY +D1ngu5555 D1no D24L D2Aina D2nzo +D2theOnTRUMP +D3 Washup D33L1N D3ATHBYPI3 +D3ATHVENG +D3C D3C0D3D D3DW8 +D3IVY OSRS +D3VONSHIRE +D3ZZi5 D3ceptions +D3precated D3thbyzebra D3v1lBoy D3vilmar3 D3zert D4H4EK3YSM +D4TE D4VO D4n0118 +D4ng3r Suca D4nkmemel0rd D4nnyy +D4rels D4rk D4rth D7NNY +D9 +D9R +DA ODB KIDZ +DA0IST +DA3N33RY DA4N +DAD563884271 +DADDYS IR0N +DAHDB +DARCHANG3L +DARGON DASH DAWGPOUND +DArtspret +DBA Paulo DBKangaroo +DBO90 +DBOL TRICEPS +DBUZZ +DC Flubber +DC-8-51 DCreek +DD 214 +DD G DD2I4 +DDAlt +DDSurWrists DDandy +DDoS Wildy +DDune DEFENDPOPPNK DEFlNE +DEM0L DEM0NIC +DEPRINS +DESPA SIITTO +DESPAlRGE DESTYLAT DFez +DG 00 DGAF +DH Marker +DH btw +DHIBZ DHSC4EVER +DHally +DHlN +DHoShow DIDZZ DIETDRDIET +DINGO SCUM +DIORITIC +DIORITlC DIRTYags DISAPRIN DITMANM0DE DIVINExNOVA DIY Ele +DIY Jamie +DIY Salsa +DIY Shane +DIY Steo DIYIronFeBTW DIYRevelled +DJ Bop +DJ Cranston +DJ Heiko +DJ Korsakoff +DJ Llama +DJ Pen is +DJEDDIK +DJK Daniel +DJKALLE ANKA DJKrampz DJMileyCyrus DJMuscleBram DJOFULLIN +DJSeinfeld +DKHo +DKJN +DMM 2 07 +DMM Gp Swap +DMM Ryu +DMT Dad +DMT Satan DMTDAN +DMTe +DMagnum 10 +DMessengerS +DN Atro DN20 +DNFL DNLD +DO0FY DOGELII DOITESTEVEN +DON FIJI +DON VALTEE +DONG GOLEM +DONJOHNNNY DOOMBRlNGER DOOMSlayer DOSNE DP776 +DPRNS +DPS Disciple DPvM +DPvM Jordan +DQ9 +DR PAAAK +DR VABA DRAEG0 DRANG3 DRD31 +DRFL DRGNSLAYER85 +DRIEST RNG DRL0NGD0NG +DRLGspace +DRNKN DWARF DROPPEDITALL DRTY +DRUNKIDIOT +DReelest DRegi +DS Stolen +DSHeavy +DStat DStroud DSyndrome +DT5 DUMB DUSKBLADEL0L +DV 8 DV trekpik +DVa +DW Gunthie DW24 DWlGHT DXQIWOL +DXXM DYao +DZ o_o +Da Bomb 149 +Da Buddah +Da Iron Jedi +Da Man 65 +Da Nils +Da Puppy13 +Da Sniper007 +Da T Virus +Da d dy +Da t +Da then bh +Da1ton DaBears DaBoz +DaBurg DaCatBeam DaCigarMan +DaCuddy +DaCult +DaDangus DaDude DaFatManDan +DaFeesh DaHumanClown +DaIronBooty DaIton DaJaVu DaLegendary +DaPootz DaRKi +DaSernet DaSheepFtClb DaTr3w +DaVinciss DaaChronic Daaak Daallas Daan +Daanilio Daanncorr +Daavos +Dab Thirty +Dab then pvm +Dab0mba DabANOMICS1 +DabDabDan DabInMyEye +DabTornado Dab_nScape Dabbadank +Dabbe +Dabbers +Dabbie Duck +Dabbin Dolo DabbinDonut +DabbingBrb Dabe +Dabe Sucks Dabei +Dabomb 13 Daborn92 +Dabos Weenie DabsWithDan Dabsmoke Dabsncats Dabsndogs Dabton +Dabvape420 +Dacaedia +Dacc +Dachowski Dackel Dackenerino Dacune +Dad Goals +Dad Sean +DadBurrys +DadGoingMad DadLeft DadRanarrWay DadamoSte +Dadbackward Dadbackwards +Dadbod4lyfe Daddaforce Daddy +Daddy Bundy +Daddy Chaman +Daddy Chubs +Daddy Danger +Daddy Dead +Daddy Drow +Daddy Oreo +Daddy Smit +Daddy Spoon +Daddy Yurdle +Daddy sandro +DaddyDeagz DaddyDylo DaddyLemming DaddyMac DaddyMars +DaddyNemmy +DaddyPig406 +DaddyTowel +Daddyfied Daddyplease DaddysLoad Daddyspie DaddyyDong Daddyz +Daddyz Clean Dadevil1616 +Dadfield Dadi415 +Dadorii Dadosaur Dads +Dadukez DadurQa +Dadyankee3 DaemonGunner DaemonTool Daemonmage +Daemonrds Daenrys Daep Daewolo +Daeyalt Ess +Daeye +Daez 95 +Daf Arch +Dafetsch Dafney Dafo322 +Daft Punked DaftDemon DaftPun Daftmoul DafttPunk +Dafuggg Dafy +Dag DaLooter +Dagannot hs Dagannuts +Daganoth Rex +Dagathar1 +Dagburn DaggaNOTKlNG Dagger93 +Dagggg +Daggou Daggz Dagin DagkingV2 +Dagnel Daddi Dago +DagobertTT +Dagoth Vemyn Dagsi27 +Daguar Dahlareen Dahls +Dahlson Dahmonkey Dahrmata +Dahrr Dahumbug Daijoukay +Daiju Spede Daiktusrenku Daileee Dailiana +Daily Grind +DailyDoomer DailyDosage +DailyPog DailyScape99 DailySharts +DailyShelfer Dailytoker Dain +Dainius Dains +Daipers Dairychuk DaisOfHavoc Daiseido Daiski +DaisukeJigen +DaisyApple DaivdFW +Daiw +Dajmkryss Daka +Daka Alt +Dakai +Dakay Daklozenkrat Dakotas Daksu Dal3y +Dalacks DalaiLlama +Dalanes +Dale Dobec +Dale G +Dale HC BTW +Dale Winton Dale1612 Daleferd Dalejamesw Dalek +Dalek Cookie Daley_Dose Dali176 Dalkz +Dalls Beep Dalmatian Daloomi Dalrak @@ -5139,6 +10670,7 @@ Dalski Daltficiency Dalton Dalton4theft +Dalton_LB Daltonnn Dalundo Dalzii @@ -5146,60 +10678,134 @@ DamDude DamSplash Damage Damarquis +Damberson +Damen +Dameon xd +Dami +Dami-an Damiaen +Damian_Xx Damish Damlotz DammitHarry +Damn Evil +Damn God +Damn its Sam DamnItHarlod +DamnSexy +DamnViton Damned +DamnedDaniel Damngoodsoup +Damni t Damo +Damo is free Damon +Damp Memes DampBucket DampForklift +DampMongot94 +Dampener Damzos +Dan Bad +Dan Craig +Dan Daoud +Dan Gleesac +Dan H +Dan M +Dan S +Dan xo Dan-Reijden Dan120201 +Dan452 +Dan646464 +Dan91 +DanAsker DanAye DanBTW +DanChan1101 +DanGreenFan DanGur27 DanMaxd DanMingo +DanO_o +DanOfCumelot +DanPJ DanRickshaw DanTheM4N +DanTofoo Danboy Dance +Dance for XP +Danced DancingForGP +DancingRa1n +Danco +Dandrikis +Dandwc88 +DaneDaddy99s Danea +Danelele DanernesLys Danex85 Dang +Dang It +DangFloopity +Dangelboi +Danger Swign +Danger Zoneh DangerBear DangerGlutes +Dangerouz Dangeruss +Dangerxi +Dangerz0ne15 DangitBobby Dani +Dani Cute +Dani D +Dani Dark 0p Dani007 Dania Danieelius Daniel +Daniel Mcc44 +Daniel OSRS Daniel12xx +DanielSumtin +Danielbisgod Daniella +DanielleOfc +Danielmcken1 Daniels +Danielwat +Daniiieell Danijenn1211 Danilin Danimal DanisH96 +DanishAdonis +DanishGoat Danje Dank +Dank Chef +Dank Exp +Dank Perp Dank Tigzy DankDylShpil +DankMagic +DankSavage99 +Dank_Mcnasty Dankdank96 Dankdog Dankdynasty +Dankey Dankfool +Dankleburgh Dankstanky Danktrees +DankumZ +Danky Kwuarm Danletics Danleypa Danlord3222 @@ -5214,32 +10820,51 @@ Dannk Dannny Dannum Danny +Danny Dubs +Danny Dvito +Danny Mate +Danny P +Danny Pudi +Danny m8 +Danny wtf DannyDeleto6 DannyK +DannyKjr DannyPho +Dannygem Dannytrol +Dannyw Danog Danoj Danol Danomeva +Danoontje Danozz +Danratty Danrow Danrue Dans Dansayeagle +Danski261 +DanteExitium Danxdoo1 DanykaNadeau Danzai Danzig Danzoler Daofather +Daoko X Dapper +Dapper Hades +Dapper Jr +Dappest Dappi DaquanNiguan Daquantaro Daquicker Darbinism Darc +Darc Sport Darcy Darda09 Daredevil595 @@ -5247,128 +10872,294 @@ Dareme95 Daremo Dareya2 DarfPlageus +DarfWantWarp +Darimy Dario +Dario hax +Darion Dariukas Dark +Dark X +Dark Alcyte +Dark Aloy +Dark Curtain +Dark Iron69 +Dark Jaxol +Dark Kadabra +Dark Kill L +Dark Knig ht +Dark Kurama +Dark Peter10 +Dark Rabbit +Dark Ranqe +Dark Side +Dark Specter +Dark Stone66 +Dark Tetrad +Dark Totem +Dark Uzi +Dark Veidar +Dark Wegener +Dark Xarpus +Dark kamui +Dark lll +Dark1437 +DarkAether DarkEater +DarkElf135 DarkEmerald DarkGraceful +DarkHoodGIM +DarkKn1ghts DarkMerliin DarkNut393 DarkOwI DarkReapingX DarkReign DarkWizard +DarkXiphles9 +DarkZulu97 Dark_Auth Darkang3lpkx Darkao Darkarmy40 +Darkbox777 Darkbright +Darke Hand Darkemissery +Darken Devil DarkenRahlrs Darker +Darkest Kind +Darkest Syde Darkfanime Darkflash15 +Darkgutz Darkhal +Darkine Darklord4211 Darknapster Darkp0wnz Darkphil007 Darkpupitar2 +Darkrai Darkraven368 +Darkscorpio5 Darkseance Darksense Darksim10 Darkskiller Darksn0w Darksnoweb +Darksocks1 Darkst4ar +Darkstar078 Darkturbo Darktyranno Darkwrath43 +Darkyr +Darlin g +Darling27 +Darma +Darnic Darquain Darras +Darren T Darrens Darriann Darse Darsehole +Dart Slayer Darth +Darth Kas +Darth Shiroo +Darth Spade +Darth Val DarthNevidia DarthSpliffs +DarthWrecker Darthe Darthodium Darthonion90 Darthrodger +Darthruneis Darthshea Darucell Darush Daryl Darz Darzix +Darzo5 +Das Idle +Das It Maine DasGoose DasReich88 +Daschiva +Dascrez Dasgirl09 +Daspwn +Dasrx RNG +Daszler +Dat Geezer Dat2eWoord +DatBoiNibbe DatBoyLoy DatGuySteve +DatIronNinja DatNeck +DatPeko DatYeet Data +Data Diddler +Data Privacy +DataDruid +Datadyne Datames Datcookie34 Date Dathx Datis +Datoxicate Dats Datskai +Datting +Dattos +Datuk +DaturaTrip Daubs +Daud +Daughters +Daunt Dauntless +DauntlessXav +Dauth Elda +DavSko Davaflav Davai +Davantage Dave +Dave From Au +Dave Hooray +Dave J +Dave Mario +Dave Senpai +Dave The Egg +DaveAckery DaveDaBeast +DaveDorvis DaveLister DaveYognaut Davebarbaren Davedication Davedude +Davej86 Daveken +Davesty +DaveyB0nes DaveyWSM David +David Co +David Duffs +David Ortiz +David R333 +David007 David2699 +David4755 +DavidKinaMan DavidPH Davidisiscoo Davidopathy +Davis751 Davlan Davo Davord +Davoron +Davros70 Davshing +Davu +Dawaj Lama +Dawg Dynasty +Dawkins Dawn +Dawn Destiny +Dawn Era +Dawn Summers +Dawn Wall +DawnEverbane +DawnSwanMon Dawna DawnfaIl Dawson141 Dawtrix +Daxidol Daxon +Daxx95 Daxxzy +Day Dreams Day Lightz +Day1ofNoFap Day6 DayJarVu DayOff2JOff +DayStar Turk +Daydrifta +Daye Xero Daykillz +Dayman_GIM Daymien +Daynnn +Daysi Darcey +Daystar +Daytrip +Dayuf +Dayveeeee +Dayz of Iron +Dayzd1 Daz3dnBlaz3d +Daze +DazedDave DazednConfsd +Dazzler95 Dazzz Dbeatz +Dbewt Dbmx +Dboot Dbricke +Dbz Pride +Dc B L I N D +Dc Hakkarn +Dc IronMan +Dcaravan Dced +Dced at Corp Dception +Dcing Dday6Jun1944 +Ddestroyer56 Ddos Dds4theko Ddsing +Ddsme +De Algerijn +De Baardman +De Eryngy +De Fishy Guy +De Gennaro +De Hoppert +De Jam +De Krikke +De La Trey +De Marco +De Max +De Mechelaar +De Pette 69 +De Redacteur +De Sam Matie +De monic De stoutsten +De us +De1icioso DeAndre DeDawgTubb DeEgis @@ -5387,38 +11178,80 @@ DeTrixzz De_lemme10 DeaTH Deacey +DeaconDrew Dead +Dead Baldy +Dead Bozo +Dead Chilli +Dead Easy +Dead HC Here +Dead Her0 +Dead I Guess +Dead Mum +Dead Policaj +Dead Psyc +Dead Sellout +Dead Ticks +Dead XVIII DeadDogRed +DeadGhost DeadKelly +DeadNowM9 DeadPickle DeadPower DeadPuto DeadRealSoon +DeadSanson DeadSlice +DeadSmog3 DeadWife Deadarrow99 Deadbeater +Deadblinx Deadened +Deadfallen Deadlft +Deadlift Deadliftjr Deadly +Deadly Pixel +DeadlyAnt DeadlyBatz DeadlyDJ +DeadlyDrinkr DeadlyHit DeadlyNecros +Deadman AF Deadness Deadpaal +Deadrango +Deadwool DeadxProof Deaf +Deaf Person +Deaf RScaper +Deafmau5 Deafs +Deakien Deakz +Deal or nah Dealing Dean +Dean Jac DeanRs Deandelouest Deantotheo +Deaptic Dear +Dear Deer +Dear no one Death +Death Devil +Death Eaters +Death Is Fun +Death Loco +Death Qweef +Death Rainer Death0fyou DeathByRC DeathPanda @@ -5427,133 +11260,224 @@ DeathSurgenc Deathbyclick Deathcloude Deathcore +Deathduspart Deathfuzz13 Deathhope666 +Deathism Deathit55 +Deathmast333 +Deathomen Deathrattle +DeathsCaII DeathsCoffer Deathscyt56 +Deathstarlol Deatths +Deb0wer Debauchery Debb Debdu +Debil Missed +Debiruss Deborla Debug Debwani Deca +Decapacitate +Decard Cain +Decarium Decath DecayedWrath Decca +Dece1ve Deceive +Decent Drugs Decerate Dechmann Decides Decim +Decim-san Decimate +Decius Maxim +Deckiez +Deckler Declare Declined +Deco Himself Decolonize Decomposed +Decon Decs +Dectron1 +Ded Ronald +Ded Smithy DedClicks DedVittu DedWilson DedZap DedZeppelin7 +Deddo92 Dedfin +Dedge Inside +Dediabl0 Dedicated +Dedicated XP Dedmoo Dedressing DedsetLegend Dedville Dedzone +Dee DeeLizard DeeLuxe DeeZe +Deedeedee630 Deedlebees Deeego DeeezNats Deejay +Deeku vaan DeelDoughs Deemush Deep +Deep Medi DeepInUrMum +Deepika P +Deepinuh Deepnsider Deerboy7I7 Deerhunt03 +Deerkl Deerski Deerskin18 Deevos Deeyja +Deez Mangoes +Deezima Deeztroyer Deezy44D Defaultbomb +Defaulted +Defeat Evil Defeater Defektas Defelorn Defence42 Defensief +Deffi +Defib +Define Pain Deflexus Defloat +Deflorator +DefoNotKiwi DefoNotSpoon Defog Deformedhell +Defqonlord Defrosted Deft Deftones Defund +Defunto2 +Defy Limit +Defyinq +Degak +Deganti Upe Degas +Degen Darra +Degen Ryu +DegenGod DegenRetard Degeneraatio +Degenic Neet +Degenomics Degradedd Deguns DeiAx Deidera Deifi Deimoss +Deinsmeins +Deiron Tyson Deitonus Deive +Deiviiz +Deivis +Dejagoo +Dekeyser +Dekkens Deko Dekul +Dekylex Del1nquent Del4no +DelaIron +Delaey Delay Delciotto Deldeen Dele +Deleted +DeleuzeSucks Deleven +Delga +Delger +Delhaize +DeliMeats Delic +Delicoffee Delimain +Delirah +Deliyria +Delkku2 Dell +Dell De Dul +DellaRS Dellamor Dellies +Delmar Delmaro Delonius Delphan09 Delskiii Delsym Delta +Delta 516 DeltaCloud DeltaEpsilon DeltaPapa Deltaskull +Deltawye Delten Delusional Delusionnn +Deluthul Deluvial +Deluxe5 +Delvex DemSkillsDoe Demander Demboo Demco Demerlay +Demetre130 Demi DemiGodKempo +DemigodI Demising +Demmegod Demolidor Demon +Demon Albarn +Demon Flare Demon Plate +Demon RS Demon1793 +DemonWolf1 +Demon_Matrix Demonaly +Demonas Demonboys1 Demoni Demonic @@ -5562,14 +11486,31 @@ Demonleader8 Demonslay335 Demonteats Demoted +Dempa Dempeanut +DempseyRoll +Dempsters Dempsu +Demyze +Den Bever +Den Duivel +Den Illya Den1z +DenZelouZ +Denaelc +Dench Bee Denclosure Denferok +Denfoe +Denggly Denglish +Denis Denix6 Denizenn +Denkil +Denkue +Denmarkian +Dennaro Denneny Dennis DennisWilbur @@ -5577,9 +11518,12 @@ Dennisfr Dennispanda1 Denny Dennyispro +Denonweff DenouncedGod Denoxite +DenseLayer Denssoni +Densu DentalMental Dented Dentistry @@ -5587,50 +11531,88 @@ Dently DenverHockey Deny Deny92345 +Denza93 Deon Deoo +Deoxy_19 Deoxys39 Depdada007 +DependaAF Depends +Depenenkal +Depletion Deplox +Deprimes Deprimir +Depster DepthStryder +Deputy Mibo DeputyDwigt +Der Hungrige +Der Panda DerPunkt31 Derbados DerbyDerbs Derdel DerekBarnett DerekEmKay +DerekWins Derenity Derick +Derived Hope +Derk Danger +Derkalurka +Derkila +Derkle Dermijiny +Dern Swan Derot +Deroy DerpCanin +DerpDeezy Derpmoil Derptimusbro DerpyClayDog Derrick +Derrick Rose +DerrickC145 Derrik Derrin +Dertay Des0rg +Desaus +Descendence +Desconectado +Desear Desert +DesertAmulet DesertEagle +DesertFlower Deserve Desi Desigium Desinger +Desinteresse Desire Desk Desley +Desn1q Desoroth Desper Desperados +Despitous Despot Dest +Destab Destinneh +Destiny Goat Destr0i +DestroyButts +Destructoid Desuelle +Desuhmate +Det BabyLegs +DetRedWings Detain Detects Detectum @@ -5639,219 +11621,416 @@ Detonati Detone Detriment Detrimental +DetroitSux Deugeniet Deunek +Deur NL Deurloos Deus +Deus Esq +Deus leto +Deus lux est DeusFerox DeusXQuinoa Deuxth +Dev Jacob +DevMoney420 +Devanar Devb0t Develinside9 +Develique +Devidedby0 +Devika Devil +Devil Horns +Devil lnside Devil9394 DevilOfheavn Devildog Devilege Devilgod +Devilish Deviljin583 Devilman Devils Devilsbkb0ne +Devilsjoker DevinTheDude Devinchi Devious +Devise Devizer Devo +Devon Btw +Devoted I Devotion Devoured Devourkitty +Devry Cain Devstated +Devv N +Devvy UwU Dewa +Dewarping Dewiro Dewitten420 Dewk Dewrunk Dewsk1 +Dewts Deww +Dex Territy Dexby Dexderp Dexlan Dexter +Dexter Lou Dexterity Dexxaz +Dexxtrouss +Dexy Fiend +DexyDean +Deykota Deyou Deyron Deysean +Deyvyejones Dezerthuntar Dezi-VII Dezkor2 +Dezmezz Deztroyer +Deztroyer 0 +Dezzu +Dflow023 +Dfs Sfs +Dfuks +Dfw Dgalaga Dgref DhRecka Dhae +Dhaegar57 Dhaeqriyil +Dhaggz +Dhalsim +Dharek +Dharma Van Dharoc Dharok +Dharok 0bama +Dharok Derek +DharokHardOn Dharokbomber +Dharoker +Dharokz Dhavy +Dhides +DhingusKhan Dhon +Dhon Do Dhor +Dhr Leon +Di vau vand DiaRelent DiaThresh +Diabalo DiabeticKid DiabeticPhuk +Diabetucus Diablo Diablo47741 Diablosis DiabolicDead Diade Diagnosis +Diagonlane +Diah Diako +Diako Gyan Dialga +Diam0nd01 +Diamega Diamond +Diamond D +Diamond Jozu Diamond2192 DiamondScott Diamondback Diamonds +Diamonds Jr Diamonds lit Diamoniakmep Diampromidi +Dianakins DianasaurEgg Diane Diapeetikko +Diaper Dan Diaresta Diariez Diarrhea +Diarrhea Tom Diart DiaryNoob +Dibbo Dibbu Dibidos Dibidus Dibsis +Dibsis CoMa DibtheLegend +Dibudabudi +Dibyel DiccEat +DicedBrotito +Dicer +Dicey ReRoll Dicio +Dick Jones +DickNBallin +Dickbruiser +Dickeroo +Dicko Diclo Force Dicnar +Dicso DictatorNL +Did You Fart +Did You Try DidAnalOnce DidISayWeast DidNotDieBtw DidUJustBgs +Didavoo +Diddle Drip Diddlybopp Diddmeister Didi Didnt +DidntAsk Didny +Didsome1say +Die hard 66 DieAntwoord +Dieby Died4Hides DiedRank DiedSierra +Diedrrr027 +Diegoide +Dien0 Dieno Diesel +Diesel Bill DieselPump +Diet Andy +DietSquid Dietch Dieu +Diffindo +Diffy +Dig Bick 420 DigBicker +DigDaniel DigOlBick Digestive Digger Diggernick32 Digghass +Diggy Digi1al DigiDestined DigiFlisp Digifreak045 Digironimo +Digit28 Digital +Digital Age +Digital day DigitalGamer DigitalKillz +Diglett Dave +Dignace Dignity +Digtalcarrot +Digweed Digyeety Dihl DiiK Diiferent DiiirtyDog +Diisphoria Dija +Dikk Mabbutt +Dikkaz Dikke +Dikke Hobbit +Dikke Kei Dikken +Dikuufd +Dil Pickle +Dilbo +DildoBagguns +Dilexro +Dilfslayer Dill0n +Dillaz Dillbert +DilleFlute Dillhen +Dillon DillontheFox +Dillusion94 Dilly Dillywacka Dillzpickl +Dilogos +Dilph Diluzion +Dilvy +Dilx +DimDimz DimJangle +DimKills Dimaa +Dimathys Dime +Dime Daddy +Dime Skate +Dimebag217 +DimitriosMVP Dimmu +Dimmy Dimples +Dimwits +DinFulaJavel +Dinamite +Dinari Dindu DinduNuffen Diner Ding-A-Ling2 +DingDong DingDongDell +Dingbat Rat Dinger30 +Dingle Eater Dingus +Dinh Dinho1 +Dinieras +DinkeLBerrG1 Dinkerwoltz +Dinkis DinkleBrrgh +Dinkleberg DinoBoy7 DinoSnore +Dinomite Dinoparrot91 +Dinorock +Dinosaur Dinostrong +DioBrandoXx Dioden +Diogaite Diogo Diogun +Dioor DiorTemplar +DiorTheGreat Dios +Dios world +Diosdado_12 Dioxins Dioxis6 Dipdadronan +Dipical Dipli Dipolio DippaDave Dippoldism +Dippy +DippyMcshit +Dipshit Dan Dipyo +Diq-In-A-Box +DirectDesire DirectDsLcul Direwolf Dirk +Dirk Stryker +DirkDigglr Dirkieflurky Dirol Dirt +Dirt Shark DirtAss +Dirtbag Dirtbikerpro Dirtboy345 Dirtjogger Dirty +Dirty Dozen +Dirty Nuts +Dirty Nwah +Dirty Pack +Dirty Tampon +Dirty Wit +Dirty Wookie +DirtyDoc DirtyGeUsers +DirtyGlock DirtyKo DirtyLube +DirtyOldMan +DirtyShire +DirtySouthNz +DirtySpade +DirtyWata +DirtyyIron Dirun +Disabled Disaster0 Disasterolgy +Disastro +Disbeliefs +Disc +Disc Chucker DiscGG +Disclosing +Disclosure Disco +Disco Mayhem +Disco PvM DiscoDarwin DiscoFever DiscoLars DiscoTronix +Discoburger Discodoris Disconnecct +Disconootje Discord Discordian +Discounted Discoveredx +Discretions Disentombed +Disfunctie Disgusting Diskmedel +Disloyal Disneyland +Disodrer +Disorderly Disperse Disprivilag +DissTeam Dissidence +DissyReborn +Distained Distanc3 Distard DistinctEvil @@ -5860,219 +12039,482 @@ Distroyer972 Disturbed Ditherman Ditt +Ditt o Ditto Ditty +DitzyGranny +Dive Ball DiveMedic Divertus +DividedSky +Dividends Divin3RS Divine +Divine Dream +Divine Fenix +Divine Furby +Divine Mass +Divine One +Divine Oodle +Divine Sveta +Divine Zaros +DivineLegend +DivineRhythm +DivineShine +Divinenro Divines +Divinethug Divinez Diving +Divinitii068 Divoky +Divorce +Divxd Dixed Dixie +Dixie Pixies +Dixin Yass +Dixon +Dixon Planks Dixxy +Dixy Wrecked +Diy Dan Diz_OG Dizho Dizk Dizstruxshon Dizza Dizzleslayer +DizzyDan +DizzyPanda DizzyRnG Dizzzzy +Dj Dimu +Dj Jordi +Dj Ju +DjNateP DjSpicyNuts DjWalkzz +Djacquays94 +Djagzar Djahat +Djauw +Djavul +Djbeejay99 DjenCraw DjentleSoul Djl0077 +Djmx1000 +Djoefer Djozztico +Djscoobsta_X Djunya +Djurfan +DjustinT DkPepper Dkafeine Dkzz DlAMONDS +DlBz +DlCKE DlCTATOR DlDS +DlE MACHlNE DlNNER DlONNE DlPLO DlRECT +DlSCONNECTED DlTTO +DlXON Dlghorner DliveMarc Dlorean +Dm8 +DmVinny Dmage Dmante Dmfs +Dmgp Dmhc Dmi11z +Dmitri333 +DmkFight DmkKilla Dmoe +Dmt Kitty +Dn Dayander +Dn Havoc +DnB Fanatic +Dnc +Dnv +Do It Best +Do It Myself +Do You Zerk +Do ur Best DoDArmy +DoHerbRuns DoKZx +DoMeDirty035 DoMeHardNan DoSoQi +DoUEvenTank +DoWerkSonn Doadles Doajiggi +Dob Au Dobar +Dobby Hanzo DobbyGotPwnd +DobbyTheSock Doboner Dobster +Doc Doc +Doc Heart +Doc k i n g +DocDingle DocGiggles +DocMonocle DocVamp +DocYouSign Doc_Hershey +Docere Docs Docta +Docta Mantis +Docta dean +Docter Brule Doctor +Doctor Ace +Doctor Bubca +Doctor Exx +Doctor Fail +Doctor Funk +Doctor Fuzz +Doctor Iron +Doctor Krieg +Doctor Luck +Doctor Oby +Doctor Swag +Doctor WormP +Doctor Wylie +Doctor Zeh DoctorCoc DoctorHeiter +DoctorKraft +DoctorNutz +DoctorRex +DoctorSquat DoctorTsom DoctuhDrew Docxm Doddi +Doddy8D Dodge +Dodge Feet +Dodger995 DodgersBRAH Dodgy +Dodgy Player +Dodgy Todge Dodjomaster +Dodko Dodo134 Dodokipje Dodol Dodose +DodusNet Doefos +Doeidoei +Doep Doesnt +Doesnt Trade +Doetje Dofric +Dog Fart Net +Dog Myrnac +Dog The Frog +Dog did Meow +DogDiet DogFlyRatCow DogLogNogJog +DogShitter1 DogSoldier29 +DogTag Dogan +Dogannn Dogax Doge +Doge Caravan Dogecoin100x +Dogesaurus +Dogessa Dogestyle +Dogfruit1555 Doggiezz Doggoat +Doggshit +Doglinsheran Doglips +Doglover7004 DogmanJones +Dogplaceman Dogpoop +Dogres Dogs +Dogsh1t Main +Dogshit Rick Dogslayer420 Dogsume +Dogtogod Dogzie Dohace +Dohdee Dohenus Dohero Dohski +Doin It Raw +DoinGodsWork Doiran99 Doiu +Doja Chompy +Doja Shark Dokarius Dokdo Doken +DokeyPickle +DokiToast +Dokter Klok +Doktor Onion DoktorBarber +Dokuganryu +Dokuhime +Dokusei +Dol +Dol Alt Dolce +Dolerkyo +Dolf Dolham Doll +Doll of Evil Dolle Dolly Dollynho +Dollynho Bro Dolomite Dolormight Dolph DolphinAnus DolphinPucci Dolphinl1ck +Dom R +Dom Wong DomGaz +DomLaurencio DomYouAll Domanater105 Domantass +Domatic +Domccas Domeeee +DomiGothMomi Domiinant Domika Domimic +Dominate Jr Dominaton +Dominator541 +Dominatorrz Dominikus67 Dominionmake DominoTerry Dominos +Dominus Omni Domiros +Domixin Domke25 +Domknit +Dommie 07 Dommy +DommyDucky +Domo Teddy +Domoralized Domoszlo Doms +Domstad Slay +Domtoren +Don Abuja +Don Bob +Don Boki +Don Con +Don DingDong +Don Dotta +Don Huono +Don Matt +Don Moochie +Don Persian +Don Robb +Don Sebitas +Don Serrano +Don callum +DonB0t +DonBroco DonDennis94 +DonMarcino +DonThinKill5 DonWonTon420 Donair +Donair Dude Donal Donald Donald Dumps +DonaldTrump Donaldfact DonaledTrump +Donantelo +Donate Here +DonateBond Donato Donchz +Donda +Dondd +Donderschok +Done enough +DoneThat Dong +Dong Chan +Dong em Down DongActual +DongCowboy DongEater +Donger Lord +Dongi Donging +Dongolark +Dongs Ahoy Dongsalad Dongu Dongus +Donkerblauw Donkere +Donkernick +Donkey Kink +Donkey Squid DonkeySocks +Donkhu DonldTrumpet Donnatello DonnieAssie Donnieduke Dono DonoWho +Donology +DonovanRS +Donsalt Dont +Dont Be Pked +Dont Heal +Dont Sir Me +Dont You Shy +Dont do dat +Dont skill +DontBeMad DontBotNerds +DontDieMase DontDieSans +DontEatMyDog DontGetDrops DontHoldBack +DontJump +DontPanicPlx DontSassMe1 +DontStarve2 DontTellFeds DontTouchIt DontUseFKeys +DontWarnMe +Dontneedbp Dontyoudoit1 Donuhtzz Donut +Donut181 +Donutman +Donvys Donwcpot +Doob Doobe +Doobie Doo +DoobleDecker +Doodle Bob73 DoodleCraver DoodleTheGod Doodled +Doodledash +Doodoolist Doodslag +Doof Doofe +Doofensmirtz Doofy +Doogl3 Doogyplumm Dookami Dookers Dookie Doom +Doom Bar +Doom Metal +Doom Raiser7 DoomDoomDoom DoomFruit Doomblade Doomed +Doomed Necro +DoomiShroomi +Doomkid50 +Doon +Doooooobie +DoorDshGamer +DoorTech +DoorToLight +Doorknob +Dooz 12 Dopamemes +DopaminAbxsr Dopamine +Dopamine OD Dopatopia Dope +Dope Doc +Dope Plugs +Dope Sweater +Dope btw DopeAnteater DopeCalippo +DopeDrop Dopedrift Dopeturtle Dopeules +Dopey Iron +Doppa +Doppleganger +Doppleladler DopplerDank +DoraDaExplra DoraSweetass +Dordin Dore +Dorede Dorg +DorgonPocket Dorgoroth Dorito Doritomancer Doriva Dorkydevil93 Dorman Jr +Dormant Evil DormiNdaExp Dorohedoro Doronn @@ -6080,39 +12522,126 @@ Dorp Dorse DorseHong Dorthea +DortyKil Dorvagten +Dory364 +Dos STI DosEquis DosKadenas +Dosia Dosk Doss +Dostalgia +Dot Death +Dot Head Dot_Tea Dothalican +DottySloth Douane Double +Double CupMc +Double Drop +Double Take +Double agent +DoubleBrowns DoubleDeezus Doubleb011 Doubledonk +Doubt +Doubt It +Doubted Pyro Doug +Doug Salt +Douglasotto2 Dougoboy Doujinmoe Douq +Douyin +Dova_sage Dovahkiintim Dovahkyng +Dovitello Dovydas54 Dowatnow Down +Down Vote Me +DowniePatrol Downland Downlifter Download Downtown +Downworld +Dowzi +Doxus Doxxme Doxy Doye +Doyer1 +Doyers Dozck Dozerdayne Dozerrrr DpittmanIM Dqzi +Dr 7 +Dr Atsum +Dr B3rry +Dr Bading +Dr Barty +Dr Butt Love +Dr Caccon +Dr Camembert +Dr Cremaster +Dr Crumpet +Dr DO0M +Dr Edy +Dr Flipflops +Dr Gainz +Dr Geyseks +Dr Glottis +Dr Gotham +Dr Gulak +Dr Harry Nut +Dr Ivar +Dr Jago +Dr Jerry +Dr Kenchi +Dr La Scotte +Dr Lulu +Dr Madv +Dr Mawffle +Dr Melons +Dr Mikey +Dr MonaLaser +Dr Mustacho +Dr Mustard +Dr NFC +Dr Neuron +Dr No Life +Dr Oreo +Dr PFAFF +Dr Phil +Dr Plebeian +Dr Quirke +Dr Rave +Dr Robster +Dr Rum +Dr Shook +Dr Siesta +Dr Slayer +Dr Stamps +Dr Swaggins +Dr T e a r +Dr Tanner +Dr Volts +Dr Will MM +Dr Yosty +Dr Zeby +Dr Zeh +Dr Zimm +Dr obZen +Dr smithing2 +DrAsTiiC DrBeast DrBen50 DrBigSang @@ -6121,96 +12650,197 @@ DrBlumpkinz DrBuckFitchs DrButter DrC0X +DrChezz DrCrunch13 DrDRespect +DrDankMan +DrDankRip +DrDemitrius +DrDennisMD +DrDitalini +DrDoddi DrDruen DrEfficient DrFlobe +DrFognog DrHugecookie +DrJoose +DrKayzed +DrKevinn DrKiloGram +DrKush69 DrKushBurner +DrLoomis +DrLuckyacorn DrMatthie +DrNachtiga DrOly +DrPeppermmm +DrPhil2019 +DrPhineas DrPoopstein DrProfess0r +DrRift DrRipStudwel DrSevens +DrSkunkPhD DrSquanto +DrSwag +DrWodahs DrWoolyNips Dr_Olusegun DraCoNiiaN +Draacaryss +DraakSeviper +Draakmonkey Drac0claws Dracarus Dracaryys +Draccnor +Drache104 Draciel Drack3d Drackon Draco +DracoGhost Draconian111 +Dracote Dracts Dracula50125 +Draeghem +Drag Puff +DragSyndrome Dragen +Dragen Ballz +Dragers DraggSlayaa Dragnarok Dragneel Dragnipurake +Dragnkllr233 Dragon +Dragon Boots +Dragon Brew +Dragon Gras +Dragon Imp +Dragon Not 6 +Dragon Sword +Dragon Those +Dragon7998 DragonAxePlx DragonDrew +DragonKlaas DragonPrime +DragonSpayer Dragonbait4 Dragonboy691 Dragoncore74 +Dragonfeir +Dragonflew Dragonheat46 +Dragonkin892 +Dragonkingiq Dragonlear1 +Dragonluv16 Dragonmake DragonoidA2 +Dragonrains Dragonrune16 +Dragons Iron +Dragonslayaz +Dragonstompy Dragonstone Dragonvirse Dragonz +Dragonz Fury Dragoon +Dragoon0517 Dragoonalfa Dragoonhuntz +Dragoonnoth +Dragoscale03 +Dragq +Dragster5300 Draind Drairi +Draiserman Draithus Drakanelf +Draken Feest +Drakenwold Drakesh12 Draket +Drakhom Drakken Draknar DrakoVamp01 Drakonid +DrakosWrath +Drakuonis Dramyre +Dranasty Dranty Drap Drapht +Draugadroid +Drava +Drawbridge72 Drawde Drawll +Drax +Drayden Drayheart +Draynth Drazar Drazart5 Drazhe +Drazzo Drbeto11 +Dre Skrila Dread +DreadPandora +Dreadfvl +Dreadnott173 +Dreadnough77 Dreadnoughtt Dreadnuts +Dreadzie Dreagation +Dreak Dream +Dream Deeply +Dream Delve +Dream Plan +Dream Queen +Dream Realm +Dream Tempo Dream-layer DreamJT Dreamboats +Dreamcatcher +Dreamchasr +Dreamfreeze Dreamguy +DreamingLily DreamingNote +DreamisBack +Dreams Real Dreamscape Dreamstain +Dreamvil +Dreamy Ku DreamzRs Drecy +Dredd Dreddshott Drednok Dreek +Dreepy885 +Dreeww +Dregulle Drei +Dremarial +Drenthe Drenz Drenzek Drenzi @@ -6221,78 +12851,167 @@ Drew89 DrewNG DrewToshiro Drewbber +Drewbob24464 +Drewby Drewcas Drewfuss32 DrewsHotMom +Dreww +Drex +DrezaR Drezilith Drfannypack Drgreenthumz +Drie Fristi +Dries D-P +Driesca Driest Driewieler Drift +DriftTap DriftVolvo Driftzzilla Driger +Driger F +Driink +Drijf Hout Drikett Drikon +Drill n Fill Drink +Drink 4 Loko +Drink Empty +Drink Local +DrinkCheap DrinkPapaMlk DrinkSlinger Drinkability +Drinker +Drinkin Pete Drip Drip To Hard +Dripping Gut DrippingSack +Drive Stick Driver193 Drivious +Drizzy Drake +DrkMstr89 Drkfirelord2 +Drlime +Dro0 +Dro268 +Droefto3ter Droge +Droge Dackel DrogeBanane +Droid Dromedario Drommy Dromy +Dron Iick +Drone Reed Drone347 +Droog Meneer Droom Droopy Drop +Drop Acid +Drop Brews +Drop Please +Drop Rates +DropGetter DropMeUrPet DropTheFlop DropTopWizop +Dropko +Dropletics Drops DropsWhen +Drosaire Droski +Drouter Drri Drrrrunk Drswole DrtyBusDr1vr +Drtyhnddog Drudenhaus +DrudgeMunkey Drug +Drug Test DrugProblems +Drugged Out Drugonaut +Drugs Hurt DrugsArBadMK DrugsHere +Drui +Druknr +Drukzah +Drum +DrumBarrel +Drumaz Drummaboy276 Drummadr Drummerz Drums +Drums X +Drums of War DrumsSpace +Drumz Drunk +Drunk CCTV +Drunk CJ Drunk Jake +Drunk Mimic +Drunk Pastor +Drunk gaming +Drunk n High DrunkAssassn DrunkDriving +DrunkGhillie +Drunken +Drunken Monk +Drunken org Drunkfam +Drunkiin +Drunkn Fun Drunknerd Drunknhiiiii +Drwe +Dry 4 Hilt +Dry Cleaner +Dry Dong +Dry Hard +Dry Hardcore +Dry Soup +Dry Trip +Dry on stuff +Dry so I Cry +Dry x DryBandit DryWolf Dryhump +DryksMuseum Dryness Drynx +Dryron Man Dryskies +Drysol +Dryune999 Dryya +DshubaMisfit +Dsk 10 DssHimself Dstroyed +Dt2m +DtWoofles Dtjenl Dton +Du +Du Old Pker +Du lourd Du5tin 3 DuTson DuYorick @@ -6300,231 +13019,489 @@ Dual Dualerz Dualicious Duaneker +Duarterecife Duathlon +Dub Season +DubC Brownie +Dubalonius Dubber +Dubbers15 +Dube Dubie +DubieDebies Dubios Dublestuffed Dublet Dubs +Dubs_789 Dubsake Dubspeck DubstepsDead Dubu +Dubu Dahyun Dubz4Dayz Dubzy91 +Duc +Ducid Lream Duck +Duck Sucker +Duck Tape +DuckEnte +DuckNoSmoke7 +DuckSick Duckcited +Ducklovesyou Duckreas +Ducks Quac +Ducks U +DucksFatha +Ducky HVIII +DuckyTears Duckzi11a Dudash Dude +Dude Come On Dude12677 Dude9103 DudeAtHome +DudeItsMikey +DudeWD40 +Dudefish64e Dudeimblazez +Dudenmi Dudetastic +Dudification DuelKing +Dufendr Duff +Duff Daddy +Duff Groupie +DuffHeavy Duffmanas Duffs Duffy234 +Duffybroh Dufwha +Duggie Dugong1338 +Dugsie +Duh Kota +Duhstin Duhul +DuiBuQiShaBi +Duindorp +Duk Me Hard +Duke Ag +Duke Babylon +Duke Roland +DukeBaird +Dukino +DukkuTzi Dularian +Dulezburg Duli +Dullskie Dulwich +Duly Ignored +Dum n dumr DumFuknIdiot Dumb +Dumb Alien +Dumb Ass Dan +Dumb Drunk DumbDog DumbMatt DumbThiccAss Dumbaneering Dumbass +Dumbass 69 +Dumbass Tony Dumbells Dumber Dumbfounded +Dumbfuk +Dumbi +Dumbledore +Dumesday80 +Dumfries Dumle +Dumoo Dumpert +Dumpsterjed1 Dumwood +DunJunn Dunadane +Dunbahn Dunc95 Duncan +Dunco Dundasso Dundefeated +DunderHonung +DunderLadd +Dundiez Dundonian Dundrift +Dundrturken +Dune dain +Dungfung Dunghead Dunizz Dunjins +Dunjun +Dunkbox Dunked +Dunked on +Dunkies +Dunkle Sonne +DunknDink +Dunkston Dunlaf DunneDone709 Dunnill Dunwall +Duo Armadyl +Duo Elysian Duodenum Duoing Duoli DupaMuck +Dupe Holder +Duper +Dupey Duplicated Dupy007 Duqq +DuraDoobs Duracell Duracell321 +Duradad Duradal Duradels Duradyl +Durag Pat +Duramax +Durant Duravillidad Durex Durexslayer +Duri Durial Durial32won Durialives Duriel1 Duriul321 Durkburt +Durlz Durni +Durns Main Durocher Durooo +Durtsa +Durtsamang +Durtstar Durty DurtyFish DurtyFish HC Durukah Durumfe Durumoomoo +Durza Spy +Dus1O Dusansss Duseballs2 +Dushie +Dusk Summers Duskel +Dust in Dusted Dusters Dustielle +Dustin Rush +Dustinant5 Dustinn +Dustins Main Dusto56 Dustpan18 Dustt +Dusturbia Dusty +Dusty cones +DustyNoods DustyPope +Dustyin Dutch +Dutch Diablo +Dutch Dog +Dutch GOdz +Dutch Genius +Dutch Quin +Dutch RvG +Dutch girls2 +DutchEnergy DutchStuff68 +Dutchbobby +Dutchie +Dutchtin DutchtinOS +DutchtinsAlt DutchyCrazy +Duty Dutzu Duuni-Pete Duva Duvel +Duvelicious Duvl +Duwua Lipa +Dux Sauce Duxt Duztin Dvaergen Dvdasa831 Dven Dvlkid +Dvn Dvsk Dvst +Dw b happy +Dw ight +Dwagos 2 Dwake +Dwaki Dwarf DwarfSailing Dwarfoox Dwarfson +Dwarve Mage Dwaybe +DwerlzCH Dwibbel +Dwight Sn00t +Dworf Dxnnis Dxscoveries +Dxue Dxukko Dydapynk +DyePhix +DyinToLive DykeMenace +Dyl Dough +Dyl Gates Dyla +Dyla n +Dylan Du Sol +Dylan Iron +DylanCarl DylanFx DylanWad Dylanimal Dylanm504 Dylann070 +Dylano Dylbots +DyldoGreat +Dylectable Dylian +Dyllann Dylrex +Dyls Dylshanwang +Dylson +Dylsy Dymass Dymenshun Dymosh DynamicDuo +Dynamicdan47 Dynasty Dynloris Dynomite +Dynstyreborn Dyonutborne +Dyonysos Dyoung116 Dypso Dyrakos +DyreBatt +Dyreshot Dyrus +Dysae +Dyslexic gg DyslexicTree +Dyslexual +Dysliexc +Dyspnea Dystopias +Dysturbed Dystxpian +Dyth +Dyvv +Dyy Dyzurah Dz03 +DzRz +Dzakar Dzangg Dzentelmenas +Dzievan +DzintarsOls +Dzoseris +DzsungelTyuk Dzud +Dzun +E D V +E Fox +E MB +E N I M A +E R A +E S H +E SL +E V 0 L +E Z I O +E hm C uee +E ldest +E lixor +E lvarg +E lves +E mni +E mpathy +E njoy +E nvy +E p i i +E r ic +E th +E thy +E volve +E-Dawg478 +E-Grill E-Hubble E-S-T19XX +E1K E4as EA888 EARLYoCUYLER EBDB EBIDABLAY +EBZ ECCIES ECH0 +EC_Legends +EDATERHG69 EDGV1L +EDM Erik +EDM Playlist +EDMJo +EF tanq +EFFlClENT +EFILLAICOSON +EFL EG6808 +EGA EGIRLSIMPER +EGirl Marcy EHPause EHstro EIGRP EIessar +EIithi +EJ 207 +EJackUL8 +EL BULLYS +EL GA TO +EL Guuapo ELCAMI ELFlikeaBOSS ELITE +ELJosh ELUSIVE +ELVD +EMIYA Alter +EMPER0R95 +EMaes32 +EN X ENAC ENimmo +EOCscape +EOD20 EODdv EPLS +EREXI0N ERGENEKON ERJ145XR +ERRIE HERRIE ERRORMONSTER +ESCEDDIE +ESP Zone ESPARG0 +ESPORZUL51 +ETE76 ETHIOPIAN ETurns +EV6A +EVA ELFlE EVE0 EVScape EWFPLMFRLRLF +EXECUT0RZ +EXTT EXpoZuR +EZ Tag +EZ Till Dead EZ-Y EZBar EZnvm +EaTZyourOReO Eac63 +Eadgars Ruse Eadles Eagel89 Eager Eagle +Eagle Eye EagleSafari EaglesWentz +Eairj Eajk +Eara1 +Earendil Earl131 EarlRico EarlVincent Earll +Earll Ragnar EarnNest +Earth rune +Earth1ing +Earthling Em +Earz +EasY FraG Ease East EastEnders EastSyde +EastWho +Eastlakeclub +Eastment Easy +Easy Girls Easy1 +EasyDingMike EasyFro +EasyJet EasyNoRoids EasyRNG EasyTurbo EasyWhale +Easycore +Easyskillszs +Eat Crow +Eat God +Eat Hot Chip +Eat Tacos XD +EatBrick Kid +EatMoreGlue EatNutsGegex EatSand EatSleepPlay @@ -6532,43 +13509,84 @@ EatULive_666 Eatbananana Eathan EatingBigD +Eatpiebro +Eats Pant EatsPoop Eatu Eazie Eazy +Eazy AF +Eazy Rat +EazyGam3 Eazy_Peazy16 +Eazymon +Eb Marah Ebbitten +Eberebus Ebgame2 Ebinki Ebisumaru +Ebola +Ebolapaska Ebp90 Ebrahem2004 +Eburr +Ec0 +Ecahs +Eccles Alt Ecdubs Echo +Echo GIM +Echo Justice +Echo Slam Echo4211 +Echo_XVII +Echte Belg +Ecko RS Eckou Eclardyne EclecticDern Ecnubsirhc EcoLite +EconPhD +Ecs Nick +Ectuu +Ecxes +Ed Dobalina +Ed Si +Ed Word EdEddndEddy +Edd Gein Eddapt Edde7000 +Eddi e +Eddie GGs +Eddie MLG Eddie1402 EddieMercury EddieTross EddieVanHalo +Eddoz +Ede n Edelbae Edelweise +Eden XD Edga64 +EdgaRyto Edgar EdgarAlnGrow EdgarKing +Edgarr Edge +Edge c dr +Edge51 Edgelord +Edgerunner Edgevill Edgeville Edghill +EdgingGod +Edgy Boss Edgykid Edgynald EdibleChickn @@ -6576,22 +13594,48 @@ EdibleSnow Edisx13 Ediverse Edje +Edjob +Edmund +Edn +Ednnnx0 EdoKirurari +Edocsil Domi +Edocsil IRON EdotheJew +Edoxa +Edpls_o Edson Edspresso Edsy +Eduardo II +Eduardoo II Eduasia1 +Edunu +Eduzey Edvin +Edvius GO Edvyno1 Edwald0 +Edward Teach +Edward phish Edwarriorx Edwin Ownz +Eeeeeeeman Eeeeera +Eeekpenguin +Eeepen +Eek The Nub Eeli EelsUpInside +Eem lekker EenViezeVent +Eend btw +Eendsaurus +Eernegem Eeveeeee +EeveyBee +Eexhausted +EfORya Efendi EfficientBot EffinNips @@ -6599,63 +13643,147 @@ Effril Efnie Eform Eftur +Egg Boy +Egg Olmlet +Egg rolls +EggInTheRain Egganator1 +Eggs 11 +Eggs N Bacey +EggscapeRoom +Eggspert +Eggssmells Eggsy Eggtooth1 Eggy +EggyChipz +Eggzotic +Eglerz +EgoTeri Egoistic Egoran Egorous Egotistixal +Eh MapleTree Ehdjsnd +EhhFK +Ehms Ehnra EhpEhbGrind +Ehpatrick +Ehpriori EhrenSpoon Ehunter +Ei hekille +Eidolonvool Eientei +Eigenspace +Eigenvalues Eight +Eight_10 +Eigma +Eihwaz EikAyZ Eikel +Eilfs Eimp +EinBerlin3r Einar Einaras +Eindbaas +EindelijkMax Eingebildet Einsteins +Einswarior3 +Einyel Einzelkampf Eirik Eisen +Eisengor Eitsei Ejiogbe88 Ejjj1000 Ejma +Ejx +Ekali Ekim +Ekim117 EkkoThresh Eklof +Eklofs Ekonomisti +Ekovo +Ekstra +Eksynet +Ekwendeni Ekxo +El Arana +El Blame +El Blaze +El Boppo +El Chip +El Ghost +El Guapo +El Panache +El PapiTrump +El Pato lOko +El Patolino +El Pinguino2 +El Podger +El Scouse +El Smurf 370 +El WarLord +El Znorro +El-Fahoum ElBlancooo91 +ElGatoGris +ElGreg_4 +ElHash ElJReezy ElJohnny ElOso ElPoyoSenpai +El_Pickle69 Elaedor +Elano Elasticy +Elatedscarab +ElationArrow +ElbartoOSRS +Elbowd +Elbows Out Elbs Elchapo24 +Eldasero +Elder Coal +Elder Siroj +Elder nerd +ElderMoth ElderRyu Eldereon Elderpliney +Eldest Sense Eldia +Eldin Eldonskii Eldoubleyou Eldrek +EldridPenny Eldritch +EldritchMage +Elduz Eleandil Elebit Electr0lysis Electric +Electric Mud +Electric cat +Electrics Electrike +Electro Beat +Elektr0nas Element +Element Sk8 Elementality Elementhur Elementiix @@ -6668,57 +13796,97 @@ Elendaro Elenion Elephanten Elephants +Elephantz Elephent Elev +ElevatedLife ElevatedSoul Eleven Elevennn Elevil Elevo Elexuitt +Eley Elezar Elf King Leg +Elf u +Elfess Elfie +Elfinsocks Elfire626 ElfsWordFly +Elgifted Elgingo1 +Elgstant +Eli Ancients +Eli Fe +Eli Junior Elia135792 Eliass +Elice +ElichikAyase Elicit Elif +Eligos +Elijah Who Elilia Eliot Elipson Eliptats +Elirond Eliseuh Elit +Elitaire Lul Elitarisme Elite +Elite HIT +Elite Moscu +Elite Sendi +Elite Slayer Elite387 +EliteJager ElitePvmer EliteScaper +Elite_Quests Eliteisftw ElitesEyes ElitesFinest +Elitist Weeb +Eliwin Eliwood225 Elixir Elizabethboy ElizeRyd Eljaaa +Elkanath Elkias +Ell1eScape +Ellakazam Elliebus23 Elliot727 Ellise29 Elliterate Ello +Ello Ron Ellphie +Elly Dog ElmSpringsTN Elmatron Elmo +Elmo Narca +Elmos Wrld +Elmswood +Elnaphant Elnuma +Elo Luigi +Elo Solo EloJimmini Elocuente +Elodie +Elon M9sk Elons +Elox7 +Elpis Elppu Elqnaattori Elrebririand @@ -6728,56 +13896,121 @@ ElroyFTW Elryeth Elsa Elshak +Elsheshima Elshi +Elshire +Elsworth +Eltader2 +Eltry Eltuu +Elucidation +ElunedsSong +Eluniel Elusive +Elusive Drop Elusive818 +ElusiveOne +Eluti Eluw Elve +Elve Alt1 +Elve Elve +Elveiq Elven +Elven Durant +Elven Lamp +Elvenborn Elverum Elvey Elviax +Elvin Elvis +Elvis Crespo +ElvisArt069 Elvs +Elvyn Frenzy +Elvz Elwood +Ely the Man +ElyGoulding Elyam +Elyaris +Elyas5 +Elyas_Max +Elycal +Elyes Elyixa Elynescence Elyphosani +Elyqs +Elyrion +Elysi Elysian +Elysian Brew +Elysian OSRS ElysianError ElysianOP ElysianTank Elysianlove Elysianz Elysion +Elysiuhm +ElysiumFalls Elyte Elyxr Elyysian +Elyzarin +Elz +Em il +EmTvLive +EmaBeast OS EmaRae +Emacity momo Emad EmagndiM11 +Emalexa Emanated +Emanuel Emasterone +Ember +Ember of Ash +Embereus Embossis Emce +Emeowtion Emerald +Emerald Jack +Emeraldx Emergency Emericanpkur +Emerickb93 +Emeritas EmeritusD +Emhrys Emiel +Emiel Btw EmielM +Emielos +Emiit Emilharen Emilis +Emilliio Emilozz +Emilozzz +Eminem Yupp +Emirdagli Emirdagliii Emithyst +Emiya Shiro Emma +Emma Main +Emma Q1 +Emma epsi Emma1020 EmmaCn132 EmmaEmma EmmaRose +Emma_RC Emmaes Emmalitarosa Emmet1156 @@ -6785,28 +14018,52 @@ Emmet20 Emnay Emnicious Emnitylol +Emo Bee +Emo King Emoness Emoticon Emoyy +Empathy TKE Empathys Emperor +Emperor Elo +Emperor Xau EmperorBuggy Empery Empire +Empire State +Empireglorth Empirix Empty +Empty Box EmptyB EmptyBox Emptyhalo +Emptynogin Empyre +Empyrius882 +Emriat +Emu War +Emumafia Emus +Emylia En Jernmand +En ki +En oo vajaa En99omgangen +EnCue Enabled Enabler Enanthat +Enbrel +EnbyDeal Encrypted +Encryptiron +Encyclopedie +End Goals +End Grind End1ess +EndOnDeath Endanged Endem1c EnderMart @@ -6814,134 +14071,266 @@ Enderofwar Endgame Endgameplzz Endgegner +EndingTime Endir Endl3ss EndlesNights Endless +Endless Dawn +Endless RNG +Endlingg Endo Endor +Endos +Enedal Enemez +Enemm Enemyboy +Energie +Energise Energy +Energy Dave +Enert Enes Enfers +Enfes +EnforcerOP Eng1and Engage +Engagement EngelNacht Engen Enginaer Enginarc Enginear +Engineer Sam +Engineered Enginerd09 +Engl1sh Englandwon Englebassen +Englehr English +English Sir +English noob Enhtitled EnigmaCoder EnigmaWR +EnigmaZen +Enis Kanter +Enivid Enjoi EnjoiAssault Enjoy +Enjoy It +Enjoy Today Enjoymydhide Enjoys +EnjoysQuests +Enk rypted Enkaidu Enkeltje +Enkh Enki +Enkidu260 EnlargedNads EnlargedNut +Enmios +Enora Nyx FE Enoran Enormous +Enormous Hog +Enos EnoughGfuel +Enoux Enphadei Enraged +Enraged Crow +Enraged Lamp +Enranged Enrich Enrico Enrik Enroza Ensanguined Enshu +Ensnare +Ensomhet +Ent Sapling +Ent1tle Enterprise +Enthusigasm Entitled +Entiy Envello +Envidius Envied Envil Envious Envvi +Envx Envx1 Envy +Envy S +Envy lul +Envyctus EnvyouS Envys Envyy +Enza Denino Enzed +Enzel Enziguru Enzyme EoMeri EocBlowsNuts Eodwyn +Eol Ivan +Eos Adamm +Eos Mark Eostrix +Eowy +Ep1breren +Epaah Eperz +EphermalGoat +Ephi +Ephrayim Epiales Epic +Epic Nom +Epic Popo77 +Epic Specz +Epic Star +EpicGamer69 EpicReefer +EpicSalmon +EpicSpasms EpicToaster9 +EpicTomato EpicX Epic_Knight0 +Epicderk Epicoz Epicurus4 Epicvoid Epicx +Epigraphs Epiixx +Epikki Episodic +Epitohm EpitomeSlay Epix_x Epiyon Epods WifeY +Epoinen9 Eponas Eposs +Eppdawg Eppers Epping +Epson Eco +Epyll +Eq Equilibria +Equilities Equnox Eqwity +Er0l +Er1kasss ErBr +Era EraJorma Erabeus +Erad Eradicus +Eragon 1 Eragondragen Erase +EraseThat Erased Eray +Erbal ErbearIV +Erbiboar Erbyss +Erdi Erebus +Erect Chair +Erect Diglet Erectus Croc +Eredln +Eren The Nub +Eren Yaegar Erg129 +EriUmi Eric +Eric Brad +Eric Dingus +Eric Hansen +Eric RS +Eric V +EricN7 EricPrydz +EricR95 EricTheNoob +Erica +Erican Maxos Ericc +Ericgone13 +Erichilles +Erics Pixels +Ericsurf6 Eriction Erie Erijk Erik +Erik Ryatal ErikProbably +Erikaugust Erikci Jr Erikito09 +Erikkert +Eriknau +Erikoisjouko Erikoiskahvi +Eriksen14 +Erikske89 +Erikv28 Erinus +Eriscord +Erixzo Erkki +Erkki Pers +Erkkiks Erlid +Erlin Erlksson +Erm its me +Ermac +Ermafrodita Erna +Ernestaiii Ernesto056 Ernsour +Ero Erock2828 Erocktastic +Erodel +Erodoris Erony Eros Erosei +Erotic Maid +Eroxtroy Error +Error 510 +Error X Life +Error812 +ErrorSeven Errric +Errrr Ersei Ershayz Ershayzz @@ -6950,29 +14339,44 @@ Ertsu Eruni Eruptingcat Erwin +Erwin J ErzaGames ErzaScarlet +Es0x Luc1us EsArTee +EsJayW EsXP EsbenViking Esbuh +Esc anor Escalation Escaline Escanor1994 EscapeMaIron +EscapeWhere Escension +Escha Escnirp Esconex +Escot +Esd +Ese Burrito Esham +Esheme Sen Esimies +Esinaahka Eskalt Eskandar Eskeleto9 Eskett +Eskett II +Eskib0y Eskii Eskild Eskimeme +Eskimo EskimoFro +Eskizzibur Esko79 Eslamm Eslihero @@ -6985,10 +14389,16 @@ Espuky Espyria Esquelito Essencehour +Essex RS Essylle +Est Bellum Estafeta1 +Estar +Estebaan +Esteedee Esteeme Esteet +Esteffano 3d EsterKai Esterbrook Estetica @@ -6996,20 +14406,33 @@ EstevamStain Estiem Estonia9184 Estra +Estrogenizer +Estus Estusin Esya +Etakenai Etardoron EtchaSketcho Eternal +Eternal Envy +Eternal Max +Eternal NEET +Eternal Orb +Eternal Qt +Eternal Riw EternalGuide EternalHeart EternalPants +EternalSin9 Eternalfury2 Eternalgod99 Eternity +EternityAP EternityEndz Ethaan Ethan +Ethan Hunt +EthanMcSexy Ethanol EthansMain Ethel @@ -7018,157 +14441,304 @@ EtherBunny Etherealist Ethereous Ethernet3 +Etherscan Ethoxide +Ethread Ethwin Etikk Etis Etkzera +Etna Etnie0 Etobicoke Etrengereid EttLitetHus Etuovi Etyaz +Etymology +Eu_Matheus Euanx Eucaryptus Eucleides Euclidian +Euclipenguin +Euf +Eugenepickl3 +Euhem +Euhh Eukaryote +Eukko +Eulers Eagle Eulogise Eunbiii +Eunie Xeno Eunx Euphael +Eupharu Euphorion9 +Euphoriotic Euro +Euro Centric +EuroGarden Eurovizija Eusheen Eusiriito Euthia +Euxii +Euxy Eva-O1 Evadari +Evaiv EvanWilliams +Evanz40 Evaptix Evawe +Evdog +Evelynn UwU Evemarner +Even2000 Even3518 EvenMater +Evenepoel Evening +Eventyrlig Ever +Ever so Dark +EverSingular Everglow +EveronSky Eversiction +Every Color +Every Word +EverybodyZuk +Evette Evictus Evil +Evil Buu +Evil H +Evil Inari +Evil Kenevil +Evil Lizard +Evil Lord +Evil Nishiki +Evil Oak +Evil Twin +Evil Zayne +Evil-Mind69 Evil3yez EvilCopycat +EvilDeeds +EvilDegen EvilFootLong EvilH4mmy +EvilOwen01 EvilTriumphs Evilaz +Evildoer +Evilegod2 +Evilelfy Evilhammer +Eviljay Evillized Evilstar34 Eviltroll648 +Eviran Evirane Evnn Evo9 +EvoSlacker EvoSlayz +EvoeHalt Evoke Evolooner Evolution Evolved +Evra Evrs Evrybodypays Evse Evuk +Evultion +Evylix Evytt Evzmac +Ew Its Mike Ewan BTW +Ewang +Ewiiyar Ewmu Ewos +Ewya +Ex Files +Ex Holy +Ex Port +Ex Sythe +Ex-Slur Ex3rt Ex903 +ExHCMangy +ExMachina +ExMaxxed ExPro +ExPsi +ExQ Bratan +ExSevenTech +ExShiron +Exa OuO +Exaalt ExamJ +Exambient +ExamineCoins +Examines Examon +Exanso Exarch +Exasperation Exaz +Exbos Excadrill Excaria ExcelIsLife Excellarate +Excellini +Excinium Excise Exclude Exclusic Excody0 ExcuseMyStr +Execrating +Executed Executes Exella +Exem Exercise Exero Exflacto Exhaust Exhibition Exhumed +Exi Sisukas Exia Exile +Exile Vision Exile88 +Exile_vChad +Exiled Noobi +Exiled Peon +Exiled Slay Exileeeee Exiquio Exiriam Exiting Exmigrant1 +Exminer +Exo25 +Exoden Exodusty Exonaut Exor +Exorcism Exoristic Exorzist Exotic +Exotic Xenon +Exotica +Exotick +Exp Jesus +Exp Nerd +Exp Wasting Expaaja Expansa Expansce Expanse Expensive +Experience +Expl0it Explaindeath ExplicitPvm +Explodet +Explodium +Exploiter +Explorer +Explorifice Explosia Expochan Export +Expozz Expressed +Expressen Exright +Extella +Extended C Extile Extinct +ExtinctDecay +Extinguished +Extortionate Extra +Extra Chance +Extra Droog +Extra Poor +Extra Shadow +ExtraRNG ExtractorX +Extranjer0 Extreemkills Extrem3b0y Extreme +Extreme JeJe +Extreme Moo +Extreme Pray ExtremeJokeR +Extremterms Extrim Extrovert Extubation +Exty Exultia Exume Exus +Exus De Exustron Exwalker +Exxtinct Exynyt +Exz0 +Exzacly +Exzactly Exzakly +Exzian +Ey1 +Eye patch +EyeBDaMan EyeHaveToPoo EyeMakeYouQQ Eyeless +Eyelessjohn Eyeofdeath3 +Eyeron E +Eyes Inside EyesLowIndo EyezClosed +Eyggs Eylix Eymox +Eyrfire +Eyup xD +Ez Klaplong Ez4Peru +Ez4u2nv Ez4u2say EzBot EzCashin +EzSlayEzLife EzUnReal Ezarc HCIM Ezdrae +Ezero Br Ezey +Ezfart Ezia Ezra Ezup @@ -7177,117 +14747,299 @@ Ezxkiel Ezzardx300 Ezzi Ezzuna +F 3 4 R +F 0 N Z Y +F 3 R R U M +F A C E +F A N TT I +F E L I CYA +F For Flash +F I X E D +F L A T +F M L +F R A T +F Ribeiro F SONY +F T P +F You Bro +F athlete +F e e b s +F l a n Cat +F l u f fy +F l ux +F loofy +F reeze +F u z Z e +F ury +F-16 +F-ck Bleed +F-ck Irons +F00DCOMA F00F +F0O F0REIN F0ZI +F0cus Me F0rtune +F0sta F0xBr34d +F1 Mercedes +F104 +F19 +F1REWIND F1nalHour F1rst F1skemann +F1tn3ssWorld F20z F23A +F2L +F2P Waifu 07 +F34r My B0w F34rcr4ds +F3ARCE +F3LINA +F3lo F4DE +F4TB0Y +F4ust F4xi F7VD3 F80Scott +F8n +F8tz +F9 +FA DY +FA Joel FA1Z +FAILED ZEUS FALLGIRL1029 +FASHl0NSCAPE +FASTBLAST I FATHER +FATHER RANCH +FAlRWEATHER +FBD +FBGM 101 +FBGMi +FC Groningen +FC Liverpool FD3S_RX7 +FE AltScape +FE Cerise +FE Endeavor +FE Mazoku +FE Smore +FE wretch +FE80 Seal +FEJMBE FER00 FER0C1OUS +FERTILE DONG FEstlkerpeng +FFA +FFA Everyday +FFASplit +FFIE go brr +FFS Sam +FFV FF_GhiLLi +FFelidae FGHTIN +FHV +FIDADDY +FIFG Phat FILLME +FIRE 0F FIRESlTE +FISHY au +FIV3 FIying +FJ +FK Corp +FK TURAEL +FK1 +FKGlory +FKN RAPTOR +FKRA +FL jit +FL0CK FL3XPL3K +FLAPPYLIPZ +FLC L FLOR1DA FLYGOD FLYING FLgoob FLoKii +FM DOOM FMGbrien FMLshes17 FMarshalBill FN2187 +FNA +FNEkkGKGKWGK FO-LAZY FOES FOLEM FONKY +FONNlX FOSTEEEEZY FOUO +FOUR GATSU +FOV90slider +FOXBRAH +FP Engineer FR1T +FRAQSTAR +FREEBABA +FREED0M 1776 +FRIENDSHRIMP +FROM ICELAND FROO00OO0ZEN +FROSTYFOO +FROXBURG +FSK Gaz +FSW 2JZGTE +FTI FULGRlM FUTRHNDRX FUTillIFU FVChallenger +FW HYPZ +FX Teddy FXF_Tails +FYXON +Fa k er FaBeSCa FaNNtastix FaZe Faabio +Faalk Faardo +Faarihn +Faathos Fabario FabiScape Fabiann +Fabidjann Fabiiano +Fabioso Fabled +Fabled Fox Fabreezy +Fabretzio +Fabsitz +Fabulence Face +Face Seat Face9 FaceHook FaceTheFacts +FacedBased Facehuntter FacelessBoyd +Facilis Facing +Fack Russia +Factual +FadaPDF Fade +Fade Lightly +Fade zz +Faded Crook +Faded Focus +Faded Lungz +Faded Past +FadedFace Faderfouras Fadfats Fadge7 Fading +Faeanaro Faebat Faeles Faerindel +Faested +Faf FahQ +Fahim +Fahrbot +Fai1ure +Fail Be Dont +Fail Friday +Fail Stacks FailFish +FailedNoob FailedZerk Failing +Failocity +FailsauceFTW Faint +Faint Dallas Fair +Fair Folk +Fair Luck +Fairburn Fairex FairiesBane +FairlyDecent Fairr Fairr Enough Fairwolf139I FairyFeind FairyVeiler +Faith xd Faiu Fakdo Fake +Fake Chad +Fake Dylan +Fake ID +Fake Levi +Fake Pobble +Fake Suffer +Fake Will FakeBallots FakeGirl +FakeNews_CNN FakeNudez Fakent +Fakeppa +Fakez07 Fakezgen +Fakn Oats Faknius +Faku +Fal +Fal7 Falabar247 Faladalore Faladas +Faladoor +Falador +Falador Sq FaladorabIe +Faladorks +Faladussy Falcon Falconf1 Falconr Falconz420 +Faleis +Falestine Falkenberg +Falkuntpunch +FallOfSolace +Fallacy i Falladis +Falldyl Fallen +Fallen Dark +Fallen Hopes +Fallen Noble FallenBlur +FallenGods FallenOutlaw FallenSlayer Fallenchamps @@ -7300,152 +15052,395 @@ Fallon Fallout Falloutah Falls +Falls Apart +Falls Road +FallyFiddler +Fals FalscherHase False +False 9 +False Boon +False Divine +False News FalseGod Falsemorels Falubo +Fam Fam Chi Boy +FamIso Famcloth +Fame is +Famexx1337 +Famfrit +Familia +Familie +Family Crest +Famished Fe +FamishedNine Famjam +Famoose +FamousBowl +FamousBowls FamousPixels Famuel +Fan +Fanatic Est Fanatiker Fanawr Fancys +Fandri Fanfiction +Fang Dude +FangJo Fangsie +FannyPaca +Fantasieloos +Fantastik Fantikerz Fantomine +Fantrix +Fany Pack Fanzi Fappel +Fapperd +Fapple Bees Fapricorn Fapworthy +Far Alone FarAke FarFarOut +FarNear +Farages Army +Faragi Farah +Faramir +Faran Farao Faraolorddd +Farcry25 Fareham Farelinho +Farenru +Farewell Bud Farfire +Farid Lord +Faridi +Farigno Farkle +Farkwar +Farlz Farm +Farm Strong Farm11m Farm3r +FarmHub +FarmRun Clay Farmance Farmay7 +Farmelot +Farmenheimer Farmer +Farmer Blake +Farmer Crab +Farmer Dannn +Farmer Jayy +Farmer Johnx +Farmer McGee +Farmer Santa +Farmer Wull +Farmer Zach +Farmer Zratz Farmers Farmertree Farmin Farming +Farming Arma +Farming Moe Farmingfoxx +Farmingtool Faroeallstar Faron Faror Farpoint09 Farqin Farrier +Farron08 Farseer +Farseer Hat Farsight2 +Farssi +Fart Gunner +Fart Shartly +Fart Weed +FartInMyGob +FartSymphony +Farthinder +FartinLKing +FartinLuther +Farting cat +FartingCow +Farts2Wet +Farty Ass +Farukoo FasTLT Fascia +FashionBTW +FashionPig +Fashy Fast +Fast AF +Fastenal Fasterman Fastly Fastmagepk1 Fastmaniac +Fat Bawlsack +Fat Boobs +Fat Cat +Fat Clouds +Fat Fur +Fat Goombah +Fat Jonny +Fat Leb +Fat Maniac +Fat Mat +Fat Moron +Fat Nymph +Fat Rackz +Fat Ralph +Fat Salesman +Fat Swaggy +Fat Thin +Fat Waddle +Fat Wirgin +Fat Wrath FatBIunt +FatBurgerKid FatClock FatGreasyGuy FatITguy +FatKidBrett FatKidHougie +FatMonkey +FatSlutKing +Fatafeat Fatal +Fatal Cazual +Fatal Psycho FatalReign FatalXfire FatalisRS +Fatalsystem Fataltorment FatboislimOS Fatboy6 +Fatcav2 +Fatceps +Fatdogs11 +Fate Gu +Fate Z +Fateq FatesWarning +Fatez Fathead Father +Father Of 3 +Father Of M0 +Father Tacos Fathey +Fatmat +Fatrekt Fatso Fatstinkysak +Fatterhead +Fatty Combat +Fatty Park +Fatty-Kent Fatty380 +FattyIsntFat FattySupreme FattyTerps +Fattybanger Fattymcdugal Faultty +Fausto +FautleferQC +Fave +Favelador +Favion +Faw OCE Fawka516 Fawn1460 Fawz Faxon +Fayl Fayumi +Fayv FazTazTic +FazeQ FazeSkilling Fazebook +Fazed Imp Fazist +Fcape +Fcbfan1994 Fctillidie +Fe AND17 +Fe Adex +Fe Alma +Fe Anakin +Fe Bastok +Fe Carter +Fe Clay8 +Fe Cremator +Fe Dahje +Fe Dentyste +Fe Dopamine +Fe Gangsta +Fe Grom +Fe Gson Fe Hellpuppy +Fe Hucks Fe KabooM +Fe Kiteman +Fe Kyle Fe +Fe Liquid +Fe Logix +Fe Louis +Fe MGTOW +Fe MagicMan +Fe Monkey +Fe Mulks Fe Nail +Fe Nini +Fe Nocturne +Fe Nylost +Fe Oakdice +Fe Papi +Fe Patrick +Fe Pvm Tiger Fe Pyles XV Fe Qlimax +Fe Republic +Fe Rex +Fe Sav +Fe Setting +Fe Skilleye +Fe Slammed +Fe Sten +Fe Tentacles +Fe Thijssie +Fe Tomie +Fe UIM +Fe Viraxic +Fe Werty +Fe X AE A-Xi +Fe Xems +Fe Zachpnnc +Fe Zelta +Fe anor +Fe ared +Fe depressed +Fe elsBadMan +Fe il +Fe lonies +Fe lungs +Fe lyne +Fe r a t +Fe rgy +Fe ta Fe-ranator +Fe0xi +Fe20 Fe26 FeBriZley +FeCapedSloth FeCrab FeDestroyed +FeDyl FeFiFoFum FeFireTruck FeFlo FeFox FeIII +FeJonnisjoen FeKyle +FeMale Chris FeManlett FeMattsheets +FeMoist +FeMudcheck +FeNote FeOx +FePash FePinkviini FeReelix FeShane FeSolaris FeSynical FeTaeliah +FeUIMIronBTW +Fe_Schrute69 +Fe_StarLord +Fe_Symphony FeaR +Feaaar FeagMeister Fear +Fear Fun FearKev FearMyTM26 +FearOfChange +FearSamurai FearTheBear FearThyDoom FearTurkey Fearengineer Feargasm FearlessFudu +Fearmaker1 Fearrod +FearzebuJr Feasted Feather +Feather Bug Feathereli Febelz +Febreezio +FecesFyrHose +Fedad Feded Federal +Federated +Fedji Fedo +Fedooool Fedt Feebee Feebz +Feed Forward FeedMePlants Feedback +Feedle +Feek 1 +Feel Ya +FeelMyBirdie Feelin +Feelin Fine +Feelin It FeelinHappy Feelmygame Feelosophy Feels +Feels Lonely +FeelsDuBis Feelsbadkapp FeelslronMan +FeelzBradMan Feen +Feet Watcher +FeetFunGoose +FeetPic Fefe3 FefilleLaDur Fegicaly @@ -7453,48 +15448,96 @@ Fegoob Feint Feisty Feit +Feitn +Fel FelNeck Felamar Feldip Felgenhauer +Feli-Marie +Feliaff Felinaed +Feline Feast Felix2 Felixa +Felixigor6 +Feller Crus +Feller Magic Fellow +Fellow Fool +Fellowships Felmyst +Felon +Felonies +FeloniousHam +Felony Ruler +Felted Female Henry +Fembo y Femboi +FemboyFloppa +Fementedspaq Femister Femke +Femke Bol Femkekos +Femstiq Fencig5 +Fencingduck Fencko Fender +Fender Axes +Fender Twin +Fendoral +Fene77 Fenerbahce +Feniks366 Fenix Downs +Fenix Kiros Fenkat Fennikel +Fenny RS Fenomeno11 +Fenothiazine +FenrilasIM +Fenrirs Fall Fens +Fenshy Fenske +Fented +Fentenal Fenternal Fenyxgreen +Fenzo +Fenzy +Fequites +Feral Wiki FeralFiddler Feralblood +Feraligatr44 Feraliigatr Feratzu +Ferbzy FerdaWoox Ferduh Fereekelor Ferlide +Fermeon Fernando-Frv Fernie Ferny Fero217 +Ferocious J Ferocious97 +Feroos +Ferousity +Ferpderp Ferrarezi +Ferrari +Ferrari Enzo FerrariScape Ferrat +Ferrdie Ferreklop FerretFoSho Ferrex @@ -7504,117 +15547,216 @@ Ferring Ferrinheight Ferro FerroPlanty +Ferrothan Ferrothorn Ferrous +Ferrous Frog +Ferrous Hugs +FerrousBoii FerrousWheel FerrousWolfe +Ferrowing Ferrum +Ferrum-56 FerrumPawn Fersapian Ferus +Ferus Ferrum +Fervor Ferynys Fesan Fesenko Festis Festiva +Fesu FetaCheese Fetetchie Fettisdagen Fetus Feudal +Feunk Fewest Fewideahide +Feydx Feyenoord36 Feylon Ffilteg FfsImAfk FgtBob +Fhil +Fhk Trudeau Fhpure1 +Fibeer Fiberlight +Fibix +Ficc Ficomon +FiddlesLeaf +Fidds93 +Fiddy Ate +Fiddy Bag +FiddyDuddy FiddySweens +Fidelity Fiege +Fielacius +Fielde FiendinLo +FiendsDream +Fierce some Fiero Fiets +Fiets opa Fietsen +Fiff Fifflaren Fifth +Fifth Herald Fifty +Fifty 5O +Fifty Cent FiftyFive FiftyForty +FiftyStones FigaroTheCat Figes Fight +Fight 04 +Fight For Jk +FightMiIk +Fighta +FighterSE +Figless Duck Figmentx +Fignootters Figpig +FigsNotPigs +Figure +Figwit Fiiderino Fiiggy +Filed +FiletOFlesh FilipTelford Filippia Fillifjonken FillyFilly12 Fillzu Filmmaker +Filo Legolas +Filofteia +Filoksenia +Filson-zzZ +Filth0 Filthy Filthy Bird +Filthy Clam +Filthy Pesnt +Filthy Santa +Filthy Weeb +Filthy istik Filthy4Iron +FilthyDane FilthyDingus FilthyOreo FilthyPixels +Filthy_Stew Filz +FimiWolf +Fin Vader +Fin219 FinPunisher Final +Final Redux +Final playz +FinalBossUIM +Finalbang Finalbrk +FinalityB Finally Finaltank Finch +Fincher Find +Find mucking +FindTheTeemo Findawg56 +Finding Dory +FindingDory Finding_Mary +Fineillspoon +Finem Mundo Finesse Finessing +Finex FingerBang +Fingerdfilly Fingered Fingerlegs FinickySquid Finish +Finish Flash FinishedLog Finishzuelan Finklestein FinkyFink Finlan Finland +Finlanderi Finlanders Finlays +Finlunch Finn1309 FinnelCake Finnica Finnish +Finnkie Finral Finrufa Finsho Finsta +Fintiaani +Finutty Fiola34 Fiora +Fipimuesi +Fir3bird85 Firat +Firben Fire +Fire 745 +Fire 961 +Fire Captain +Fire Chiller Fire Fiesta +Fire Fist +Fire Galley Fire Kaped +Fire Kittie +Fire Tune Fire10910 FireAF FireAnRescue FireGiant +FireKornez FireOnRs +FireReid FireTruckBoy FireWolf28r +Firebelly Firebuggy +Firebwans +Firecan1314 Firedevil +Firedrake658 +Firehawk746 Fireheart470 +Firein12 Firejax Firekirbyeli Fireknight0 Fireman +Fireman Sam Firemanzz Firemutt Firenova @@ -7624,116 +15766,201 @@ Firesmash Firestarone FireyDragons Firko +Firnik First +First Bozz +First Up FirstBathTub +FirstBlood 1 +FirstIron +FirstRS First_Viking Firulay18 Fish +Fish Cow Dog +Fish Keeper +Fish Nibba FishFingerz FishGoBlub +Fishcake +FishesBmine Fishey Fishie +Fishling Fishoii Fishstickz +Fishsword389 +Fishvaulter FishyBrines Fisicas Fiskhue +Fisna Fist FistMeTrump Fister +Fit Jr +FitAid +Fitdis Fitis Fitsit +Fitty Tyson FittyBuck +Fitzy Smalls Fiurio Five +Five Demands FiveManSplit FivePaws FivePointOh +Fivee Skinn Fiveskin FixationRS Fixed FixedCost FixedMain +FixedWing Fixions Fizbin +Fizg0d +Fizz Khalifa Fizzed Fizzle +Fizzy Glizzy FizzyGuzzler Fjala +Fjala r Fjalee Fjollan Fjolle Mate Fjomp +Fk RS L +Fk W Da Woo +FkingEzeKial Fkking Fklostmybnk Fkluzac +FknDeece FknDreaming +Fkuru +Fl y FlLTHYYYYYY FlNARKY FlTTY +FlTZ +Flabaghast +Flaboogles Flaccid +Flaccid RNG +Flaccid Semi FlaccidWhip Flacid +Flackyo Fladra +Flagaria Flagrance +Flagrant 2 +Flagz Flaherdog FlailTheKing +FlailingGoat +Flair Viper +Flakelar Flakey Flakeydude Flakkas Flakto Flamaha +Flame Lurker +Flame0fUdun Flame29 +FlameSoother Flamed Flamel Flamepistol +Flames4 Ever +FlamingPee +Flamingfox +Flamingguy7 +Flaminold Flaminrofls +Flammbam Flanelli Flap +Flap Slap +FlapJackals +Flapple +Flapsian Flare Flare Grylls +Flareblade Flareon +Flarez Flarp Flash +Flash Voyage Flash3200 FlashYellow Flashbane +Flashbang +Flashcards Flaskepost Flat +Flat Eric FlatAssPlank FlatEarth361 +Flatback Flatlandah Flatorbrush +Flaunt Flava Flavaaaaa +Flavie +Flavour Trip +FlavouredDav Flavur Flaw Flawd Flawed +Flawed Bliss +Flawless xD Flawnn Flawzin +Flax Pickerr Flaze Fleaa +Fled 6ymcric Fleeson +Flemingo Flemino Fleruas +Flesh Forest Fleshgod +Fleshpound Fletch2 Fletched0 Fletcher +Fletcher 06 Fleton +Fletz Fleurescent Flex +Flex Wayne +Flex1bel Flex1bility +FlexCity FlexSeal Flexatronic +Fli pper FliPancakes Flick FlickMyTick +Flicker 06 FlidFlop Fliga Flight FlikAwrist +Flikker +Flikker Kind Flimmyflan Flimpy Flimsywhale @@ -7741,83 +15968,147 @@ Flimzy Flinch FlingDragon Flint +Flint RS +Flint Water Flintstoned +FlipDaddy +Flipdam +Flipje Flipman24 Flippa +Flippa Monk Flippar Flippers Flippin +Flipsen07 Flipzzzup Flirz +Flit Wick Flix +Flixy +Flizz xd Flllllllllll Float +Floater eyes Floatzelo Floballer Flock43 +Floeter +Floki loki +Flomple Flonza +Floody +FloofyTurtle +FloofyWaffle Flooga Floogan33 +Floopyboople FloorTwenty Floot +FlopLord Flopez Floppy +Floppy Boaby +FloppyDongle Florian +Florian_1988 Florida Floth +Flover Flow +Flow it +FlowMafiaaa FlowState Flowah Flowen0ne Flower +Flowerm00se Flowiey +FlownbyFire Flowtown +Floww-Grown +Flowwar Flowzyy +Floxin Floy Floyx +Fludds Fluenz +FluffPandaSr Fluffafluff Fluffalo +FlufflePluff Fluffy Fluffy chair FluffyTater Fluffypony44 Fluga +Flugel25 Flugenhorn1 Fluid +Fluid Voyage +Fluke Jr Fluminense Flunc +Flunt Capz Fluoroform Fluorophore Flupbaster Flurius +Flushiz FluteBand Flutlicht Fluxee Fluxery +Fluxion +Fluxx V2 +Flvd +Fly an High +Fly by N7ght +Fly in Fly-TheW +FlyLo FlyPap3rr FlySunyQuest Flyboyray Flydol +FlydonWayno Flyeeee Flyer +Flyer TMT +Flyer W Iron Flyern Flyguy13 Flyhll Flying +Flying Pingu +Flying Swede FlyingBobcat +FlyingIrish +Flymi +Flymzy Flynny Flynsquirrel Flynt Flyonwings Flyvende +Flyvende Ged Flyy +Fml IronMan +Fml Its Adam +Fml Its Carl FnHit +Fnatic +Fo Ring +FoRbeZiiLLa +Foam Corner FoamDemon1 +FoamShrimp +Foamshire Fobu Fockwolf1 Focus +Focus73 FocusOnGoals Focusor Foen @@ -7830,78 +16121,157 @@ Fohmie FoiledSoftly Fojin Fokjefe +Folayyy +Foleshill +Folesy Folfox +Folieo Folk Folk169 Folktale FollieRS +Followed +Follower Folwifuswalo +Folxi Fomble +Fomid +Fondle FondleMyIron Fong Fonnis FonsJ +Foo I I Food +Food For Me FoodEmperor +FoodStampGod +Foodfoodfood Foodie +Foofickle FookOffNerd Fool +Fool Senpai +FoolFighters +Foolery +Foolingling +FoolishHeart +Fools +Fools Errand +Fools Switch +FoolsErrand +Foomp Foooman Foose Foosyy Foot +Foot Ball242 +Foot Magnet FootLocker Footaphiliac +FootlongMike Fooz +For +For Karamja +For My Block ForDaScratch ForKrimpt ForNostalgi +ForRusssia ForWeAreMany Forbe ForbiddenCry Forbids Force +ForceZero +Forcekid Ford +Ford Racing Forearm ForeignBoris Foreigner Foreknown +Forerunner40 +Forescimitar Forest93 +Foresteris +Foreva +Forever Wild +ForeverAlone +ForeverClone ForeverLost Foreverett ForgetThePet Forgetmenot Forgetpluto +Forgettios Forgive Forgived +ForgottedPin Forgotten ForgottenRNG Forkbomb +Forkers +Forkmitt +Forks Out Forma +Formal +FormalPotato Formaldhyde +Former Nub FormerDivine +FormerSeaman +FormuIa 1 +Fornuis +Forresten Forsaken +Forsakens Forsworn66 Fort +Fort Chronos Forteh +Fortified +Fortify +Fortimuss +Fortis Lupus +Fortjent FortniteRox Fortran95 Fortress +Fortunes Forty Forza +Forza Derby ForzaGTx +Forzam Fosh +Fossa69 +Fossil Rock +Fossul +FosterXP Fostret +Fosz +Foton Fotty Foumy6 +Found Prawn +Found3Groots FoundABaby Four +Four One 6 +FourB FourZone3 Fourlifee Fourloco Fournlock FourthChance +FourthPower +Fowke +Fox Enjoyer +Fox Two +Fox Zebra Fox243 +FoxStevenson FoxTherapy FoxVex Foxall @@ -7909,152 +16279,281 @@ Foxe Foxerx1 Foxes Foxfiend +Foxfire +FoxfireStyle Foxi +Foxing Foxtrot +Foxx OG +Foxxwild Foxy +Foxy Rebel +Foxy SuzyQ FoxyBaphomet FoxySquid +FoxzHound +Fozbert64 +Fozie FpsMichael +FpsWheelerrx +Fpsallday +Fr anci5 +Fr ankie +Fr0 Fr0zEn111 Fr1ckingH3ck Fr1xioN +Fr3Pa1est1n4 FraJoLaaa Fraagile +Fraazzy Frab Frac +Fractals Son Fractuality +Fraggiux Fraggle FragmentedX +Fragmentizer +Frags Frail Framed FramedJunior +Frames Wolfe Framingham +Franche420 Francine1225 +Francis0wns FranciscoJ32 Franco Franf10 Frank +Frank Donner +Frank Is Dog +Frank Lin +Frank White +Frank-sama +Frank836 +FrankMadeME FrankTTank Frankers FrankieFlow FrankiesAlt +Frankinspank Franklin1O1 FrankyFish32 +FrankyLeGros FrankyyTanky +Frantiks +Franwan Frappacholo +Fraqqer +Fraser +Fraser840 +Fraspex Frassboss Frate Fratto +Fratty Flows +Fraud Thurgo Fraught Frauwz +Fravvomaxx +Frayhalla +Frazer Frazia Frazoo Frazze +Frazzlewagg Frazzt +Frchtzcker +Fre d Freaak Freak +Freako07 Freako09 Freaks Freakxx +Freaky Peet +FreakyWajt Fred +Fred J Frost +Fred Solo FredMaxedALT +Fredagsgroda Fredanbetty +Freddi Freddiep +Freddy CEO +Freddy ownz Fredericton +Frederizz Fredla +Fredleif +Fredo Fredric Fredriks +Freds Breads Free +Free Dumb +Free Minded +Free O9 +Free lootkey FreeFreeze FreeFryBread FreeHongK0ng FreeKoolaid FreeTeli2Lum +FreeTheRealD Freebooterv +Freeczs BTC Freedom Freedom06 FreedomJust FreedomUP Freee +Freehky +Freek 1 FreekALeak Freekkittens Freelo Freeman Freepop +Freerangee Freesoul Freest Freestylin Freeway Freeze +Freeze M E Freezes Fregion Frei Frekitohh +Freky FrenchBuoy +Frendi Frenek +Frenkurt Frenmiir Frenzy +Frenzy4 FreonPays Fresaaaa Fresco Fresh +Fresh Cheese +Fresh Pesto FreshPotsRS +Freshly +Freshske +Frette Freud Frevlin Frewdy Freya +Freyas BTW +Frez +FriarNation Fricas +FriccKip Frickin +Frickn Playa FridayDa13th +FridayMojito Fridelis Fridfoolium Fried +Fried Erik +FriedRicePls +Friede Friend FriendlyJo Frietjecurry Frieza +Frieza Saga +Friezerik Friggn +Friggy +Friibag Friisby +Fris +Frisdrank Jr +Frisky Lime FriskyBiznaz FriskyJews FriskyPainal +Fritszon +Frittered Fritz Fritz94 +Frix Frkn +Frnds FrobroSwagin +FrochioRS Frodo +Frodo Bagger +FrodoBagGims FrodoBogues FrodoRS Frodoinc1 Froemelke +Froemeltchhh Froez66 Frofuzz Frog +Frog Blog +FrogBoySlim +Frogfish12 +Froggiefish Froggit +FroggyBro Frogmann +Frogone9 +Frogsforjp Frogtelllow +Frogtoken Frogwork Frohobo Froloox From +From Beyond +From Florida +From Lebanon +From Nz FromNewWorld FromSoftware Front +FrontBottoms FrontierEdge +Froobing Frooby Froomey +Froot Loop +Frootata +Froppy Tsuyu Fropul Frosht42 Frost +Frost JTS +Frost Mages Frost_PvM Frostbiter +FrostedBow Frostmourne Frostserpent Frosty +Frosty E +Frosty Gay +Frosty6570 Frosty751 +FrostyPea43 +FrostySurge Frostyfuz Frostyyyman Frote +Frotzr Frovz Froya Froyotech @@ -8062,221 +16561,604 @@ Froz09 Frozah Froze Frozen +Frozen Crown +Frozen Rain +FrozenKing FrozenMosin +Frozencarrot +Frozenn Dusk +Frozty Feet Frrrozn +Fru Katt Frufoo Frugal Frugtmanden Fruh +Fruit Crepes +Fruit Dryer +Fruit Munch Fruit1824 Fruit1846 Fruitbooting +Fruitje +Fruitloop8 Frunk FrunktheHunk Fruta Frvnk +Frxnk White +Frxnklin +Fry B +Frysta +Fsaze +FtheFrench73 FuAiluue FuNrikoz FuRiouSs +Fubar3d Fubini +Fubuki +Fubuking +FucDPS FucNorfKorea FucaDuc +Fuchsiger +Fudeath36 +Fudg3 Fudge Fudgie Fuel +Fuel Ex Fuertote_17 +Fuetakishi +Fug +Fug sakes FugDisFugDat Fugedit FuggleQuest +FuggnIronBtw Fuglemanden +Fuhni Fuhrerengel Fujimator Fujk FukYeaChina Fukahi Fukinnnn +Fukn Lit Btw Fuktflekken FulMomentum Fula FulgBTW Fuliss Full +Full 3A +Full AD Vlad +Full Boost +Full Moot +Full Tilt +Full of Wo0d +FullGraceful +FullSendGoat +FullTimeNerd FullTryHard FullerACL Fully +Fully Mobile Fullysick Fulsh +Fumblebag Fumblers Fumbles12 Fumin +FumingMe +Fun Guy mhm +Fun Sucker +Fun1nFunera1 +FunHotBox +FunWithFire +FunctioningC Fund Fundo +FuneRune Funeral Fungi Funk +Funk Head +Funk Mastah FunkBondMule Funkafiend FunkiPorcini Funkiboy2 FunkiiMonkii +FunkleRoy +Funkr +Funkshun +Funkworks Funky FunkyBoy4444 FunkyDiddler +FunkySlut +Funky_Hunk +FunnelCaker Funni +Funni Memmer Funny Funny-King03 +FunnyAndEpic +Funobu Funpeople5 +Funrun123456 Funzip Fuorra +FuqAgility FurMissile Furbs +Furi Potion Furious FuriousPower Furiri Furo Furox Furry +Furry Wall FurryDemon Furrykins +FursonaHaver +FurtleTurtle Furty Furu Fury +Fury DnT +Fury Lord FuryJunky FuryL0rd Furyian Fuse +Fuse is HARD +Fuseton Fusiiion +Fusion Aurum +FusionGT2 +FussyParter FutchDuck Futex +Futss Future +Future Tense FutureKaiden +Futureruler9 Futures +Futures Main +Fuuwah +Fuxley Fuze +Fuzz Man FuzzManPeach Fuzzums4 Fuzzy +Fuzzy Sox +Fuzzy jaw95 Fuzzy1918 FuzzyDonkey FuzzyFudgey FuzzyMWV +Fuzzy_NooT +Fuzzybear65 Fuzzyblaa56 +Fuzzykitty Fuzzzy +FvS Love +Fweafwe +Fxked +Fxob +Fxrgus +Fxrret +Fy six Fy12e +Fyitz +Fylberg +Fylize +Fym +Fyr +Fyr Tornado Fyresam Fyri +Fyrinlight Fyron +Fyrox Fyszz +Fyzio Fziaa +G +G 0 A T +G A F F E R +G Alfansos G Ape +G B S +G Check +G Fruit +G GAMER GIRL +G I M Danny +G Iron Adam +G L E N +G L H F +G M B +G Man9822 +G Mauls +G O O D +G O O S E Y +G R E E N +G R I L L O +G Terminator +G X F C +G Zus +G a r t y +G a t t s u +G ante +G dot C +G e n g a r +G eeb +G i j s +G i l b o +G iG +G imme +G iooo +G l R L +G laze +G no Z +G o G G u +G o h o +G o th i X +G oldd +G oldeen +G oofy +G ozz +G rafix +G ronimo27 +G root +G shi +G u a m s +G unitt +G-F-M +G-IronKuv +G-Thug Nasty +G-knowww +G-rivs +G0AT JUICE G0ATWRANGLER G0D Richard G0DLY +G0LD3N G0LDC0AST G0LDEN G0LDENB0Y G0LDIE G0NGSHOW +G0OEY +G0TH ANGEL G0TTY +G0blineer +G0dr3kt G0dsnotdead G0ing G0ld G0lden +G0rillaJesus +G1C G1adiador G1edrelis +G1izzyGob1in +G1m Luna G3RM4N +G3ZZ4 G4M3OV3R G4RG0YLE G4UAFS +G4YLORD G4de +G59 Awol +G6E Turbo G6Wizard +G80 +G99s GAAANNNGGG GABBAGE +GAGGED N +GALO9A GAMMAGARD +GAMxJAKE +GANONd0rf GAOKNMxzHR +GARDlNER GATECRASH GATTl +GB Amarok GBJackieWang GCMidlane +GDG +GE IS WACK +GE to FE GE0RG3WKUSH GEARLE55 GEEZ0 +GERANUS GERRIEE GEtItFrAnK GFHL +GFe Aang GFmanbearpig +GG Joe +GG McCloud +GG Sofie +GG Wped GG6HJA9KSDHJ +GGGGGGGGanta GGGskywalker +GGW Limit +GGW Thanos +GGf1cation GGtoHH +GH05T DUDE GH95 GHEEESE GHETT0JESUS +GI GN +GI Lewis +GI Lucky +GI Madras +GI Mohib +GIANT HENO +GIANT ITIOLE GIBBO96 +GIGAGUMPH +GIM 0dawg +GIM 2nd +GIM Albin +GIM Aperture +GIM BTWW +GIM Ballak +GIM Barkless +GIM Baylis +GIM Bunzz +GIM C J +GIM CgIsEasy +GIM Composer +GIM Conkers +GIM Cris +GIM DareDev +GIM Derek +GIM Dionysus +GIM Dormant +GIM FatLion +GIM Fearzzy +GIM Ganther +GIM Glalie +GIM Globi +GIM Hatred +GIM Hola +GIM LWE +GIM Lasse_ju +GIM Lazyguy +GIM Lxxs +GIM Lyon +GIM M0FFY +GIM Madac +GIM Magneto +GIM Malphite +GIM Martas +GIM Maudi +GIM Mcstro +GIM Me STD +GIM Mecknon +GIM Mirasei +GIM Moith +GIM NewPorts +GIM OatBloke +GIM Obvious +GIM Or715 +GIM Philrat +GIM Player02 +GIM Qtpie +GIM RWT +GIM RagePope +GIM Raheem +GIM Rakfaan +GIM Ring +GIM Schaa +GIM Schnei +GIM Sense +GIM Snax +GIM Stinks +GIM Stompy +GIM Stoney P +GIM Stu +GIM TUT +GIM Terix +GIM Tman +GIM Tobi +GIM Toe Pic +GIM Ved +GIM Viklok +GIM Wife +GIM Zork +GIM atomic +GIM bad ass +GIM brutal +GIM kerma +GIM poy249 +GIM sabinsky +GIM xDist +GIM-Topsu +GIMAerospace +GIMButcha +GIMFunder +GIMME CLAW +GIMP Crystal +GIMP DlCC +GIMP Jonny +GIMP Suns +GIMP Toast +GIMP Will +GIMP Zuzu +GIMPlayer69 +GIMRavenKing +GIMTruck-Kun +GIM_NoRun +GIM_Snowwolf +GIM_tybraun +GIMcardellio +GIMonster +GIMp Brian +GIMpope +GIMxH2 +GIRTH CHECK +GIronPPVibes +GL GETTIN IN +GL on Purple GL78 +GLG Sophie +GLUS GLWeAllDie +GM Matt +GMEMan8000 +GMKirby GNULinux +GOAT GOD 420 +GODSOMBRA SL GOGETA +GOLOVOLOMKEE GOOD +GOODGAMEGGXD +GOP DUMB +GOZERGAST +GPA +GPWASTER +GR0OOT +GR1NCH GRAB-A-LEAF GRAN1T3 GRAND GRAPHISTED GREIV0US GREIVUOS +GRIMSTAIN +GRINGOLAO GRUMPY +GRUMPY BSTRD +GRUMPY PAPAW +GRYGRY GRiMZ +GRiMZ 420 GRlM +GRlM REEFER +GS Concerta GSAileen +GSW Shane GSwolls GT350 +GTA SA GTFOIMGAMIN +GTOD +GTRKingZilla GUBIDUBII +GUCCI SENPAI +GUCCl GUJ0 GUNMAN683 GURRD GUUMBY GVSU GYDtown +GZA +GZX +Ga l +Ga7ba Gaara +Gaara Sand Gaarden +Gaarise +Gaarlokiin +Gab al Ghul +Gabagoo l Gabber +Gabber NaTaN +Gabberboy15 +Gabble Gabe Gabe020 +Gaberoks Gabesz Gabo +Gabrahanth Gabriel61198 +Gabris +GabyabyxD Gacha Gaddgedlar Gadrak Gadwall Gaerolth +GaethjeKO Gaga +Gaga Iron +Gage S +Gageks +Gagne Gahbo Gain +Gain exp +Gainful Grey +Gains alot +Gainz Godz +Gainz Nerd GainzForHire +GainzWorld +Gainzvill +Gainzville GaiusTavi Gaiy GalGadotsBF +Gala G Galamx Galandorf1 Galar Galava Galaxia +Galaxiancam +Galaxies Galaxy +Galbazeek1 +Galderr Galdysa Galgenbrok +GalickGunner Galilee Gallaxy Galleta Gallium +Gallowbell +Galon Garuda Galon1 Galow +Galton +Galvatron Galwic +Galyam +Galzuk +Gam Gamaiiron Gambinahuora Gambino +Gambit +Gambit Ghoul Gamblerz Gamboy46 Game +Game Clown +Game Name +Game Of Olms +GameBot2000 GameOvaries3 GameStop Gameboto4 @@ -8284,36 +17166,63 @@ Gameboyjr Gameboylight Gamelia7 Gamer +Gamer Log +Gamer Worded Gamer4Life +Gamercutie Gamerplaya7 +Gamerr +Games Rigged +Gameshow Gamesman Gaming GamingLover GamingVapor +Gamir Von Gammel Mand Gamorrah +Ganandalf +GandaIfNoir Gandalf +Gandalf staf +Gandalf3602 GandalfBalle Gandhi Gandolf +Gandolpeeni +Gandon12840 Gandulff Gane Gang +Gang Goblin +Gangbarang Gangnrad +Gangris +Gangry Gangsta Ganj GanjaGhandhi GanjaRhino +Ganjoefarner +Gankicus Gankster +Ganna Bogdan Gannicus Gannicusproo +Gannnon Ganooch Gansa0 Ganta Gantee Ganthorains +Gantre +Ganzaxuz +Ganze +Gap Tester Gaping +GaratholX7 Garbage +Garbage Life GarbageEater Garbagexd Garbar6 @@ -8321,140 +17230,268 @@ Garboh Garbug Gardenia Gardening +Garder1968 Garena Garfinator Gargano Gargaspoon Gargath286 +Gargathon Gargleon Gargoyle79 Garlic +Garnat Garnet Gust Garp +Garrb3ar Garrett Garretttt Garrothis Garthoon +Garvis Gary +Gary Ghee +Gary Giggles +Gary Guldske +Gary Linkov +Gary Wang GaryDabs GarySmokeOak Garyjayjay Garysson +Gasconade x +Gash Pasher GashBndicoot Gashtag Gassy +Gassy Cat GassyFlaps +Gastje888 Gastronaught Gate Gateofdoom +Gath Gato GatoNaranja Gator +Gator Bob Jr +Gator Papi Gatorboiz +Gatorian176 Gatorslyr GatrsNTaters +Gau Cho Gauntlet +Gaur Gura Gauss Gautstafer +Gauvin Gavbin Gavi Gavii +Gavin Dance Gavita Gavrot +Gavussy Gavy +Gawd Bodi +Gawk5000 Gawkes Gawkss Gawt Gawz +Gay 4 Guthix +Gay Bear +Gay Bear Cub +Gay Farm +Gay Fieri +Gay Framed +Gay Holly +Gay Impling +Gay Liam +Gay Male69 +Gay Snake +Gay Squire +Gay Vermin +Gay Wimp +Gay450Bucks +Gay4Ketchup +GayWalrus69 +Gayblade +GaylsHaram +Gayme Gayron +Gaz GazGoon Gazaman11 +Gazan Gazd Gazed +Gazed Soul Gazelle2211 +Gazru Gaztok +Gazza +Gbax-Style Gdey56 Ge0rgeburton GeChallengeM GeTLeFt1 +Gear 5th +Gear Carried +Gear Fear +Gear Sekando Geard +Gearfried +GearheadSTL GebwellB +Geck-o +GeckoDad +Gedmuush GeeHasMews GeeStreet Geeb Geebs Geebster +Geef Bier +Geegles Geeker Geeknip +Geeman125 Geen +GeenBankMan Geera +Geerin GeertWillows Geestig +Geeving +Geewd +Gefilus666 GeggaMoya Gehrman GeilTijgerke GeilePaddo Geitekaas +Gekido GekkaJohn Gekke +Gekke Farmer +Gekke Nelis +Gekke Pablo +Gekkesmurf +Gekoh Gekolian +Geks GelZmog Gelawynn +Gelderlander Gelezis +Gelijk Geliquideerd Gellaitry +Geller Bing Gelly +Gelmar +Gem +GeminitusII +Gemlingur Gemsbok +Gen Kokopuff +Gen4 UU GenCoupeGang +GenFormat GenGraardor +Genabackis +Genann +Genaron +Gene Shorts GeneBelcher GeneDenim GeneKapp +GeneVieve_SL General +General Aldo +General Bigi +General Iroh +General NL GeneralJosh GeneralLudd +GeneralMcRib GeneralMo GeneralMoist +GeneralNASTY GeneralPlay +GeneralStore Generall +Generall_xx Generalton Generol55 +Genesee +Genesis G80 Genetiics Genetiz +Genga r Gengahr Gengerbred Geni +Genie Magick +Genie Talls GenitalsHead +Genix +Genjitatsumi +Genk Gennie +Gennu Geno +Geno RS Geno2566 GenoJuice Genocidal +Genovan Genres Gensha Gentileza Gentle +Gentle Death +Gentle Gypsy +Gentleman J Gentlemanfox Genty Genuine GenuineDude Genus +Geo Fe Geo Geo GeoDuuud Geoculus Geodark +Geof Sux 666 +Geoff_Failed Geoffry +Geography +Geoguess +Geoide Geologistic +Geomatic Geonde Geordie George +George 36th +George F M +George Vv GeorgeJx93 +GeorgeVork Georgey +Georgezs +Georgies +Georgopol Geoso Geotechnicki Geovanna GerAmi +Gera1d Gerald +Geralt Nivea Gerb3 Gerberos Gerbs @@ -8465,47 +17502,92 @@ Gerjan GerksShirts Germaan GermanGuyRS +Germanic Germaphobic Germimo Gernoazi +Gero Geroko +Gerr Hurka +Gerrido Gerrmz +Gerroes4GIM +Gerry Bud Gershboon Gert GertrudeSimp +GertrudesAss +Gery07 +Gesaldo +Gese Geskar +Geso Gesoz +Gestetner +Get A Life B +Get Back Son +Get Bread +Get Exp +Get Fukt Pal +Get Pho +Get Syked Get0nMyHorse GetABeerInYa GetATapWater +GetAclick GetDatXp GetMeOut +GetMeOutHere GetOnMyLvl +GetOverlt +GetPets12 GetSkipped GetThatUpYaa +GetTogether GetUrWild0n GetWreckdSon Getdolphined Getfck3dup Getlow777 +Getplayed Getsu +GettinTanked +GeudensK +Geuld +Gew Gewoon Gezang +Gf g Gf4tiuser GfRsIGotAGf +Gfi +Gh3t0 T4nk3r Ghafir +Ghaipol +Ghandizy Ghandy +Gharron Ghckkrchkrer Ghda +Gheed Ghentiana Gherkins Ghetto +Ghhjgwsr +Ghidorah +Ghillie Suit Ghilly Ghoosted Ghorraka Ghosnik Ghost +Ghost 311 +Ghost Ahoy +Ghost Fe +Ghost XP +GhostAralein GhostHouse +GhostOrchids GhostTank GhostXD Ghostas @@ -8513,305 +17595,675 @@ Ghosteeen Ghostfice Ghostflips Ghostiami1 +Ghostly Taco GhostlyFetus Ghostlyowns Ghostninja +Ghostsu +Ghostwish492 +Ghosty +Ghoul Intent +Ghoul Zeta +Ghraz Ghruntsarokk Ght179 +Ghurrix +Ghuuneiboi Ghxul +Gi Lew +Gi bbo Giallo Giant +Giant Ego +Giant Gochu +Giant Killer +Giant Peenos +Giant Plums +Giant Trunks +Giant spider +Giant235 GiantConker +GiantShafty Giantesss +Giaveri +Gib bread GibMePets Gibbed Gibberish Gibboh +Gibbon +Gibbon girl Gibby Gibby0712 Gibbzzy +Gibsky +Gibsmeister +Gibson Giddy Cowboy +Giddy Yup Gidejong Gidionn +Gidle Soyeon Giebu Gielinor +GielinorGage +GielinorGoat +Gielinord +Gielinored +Giena +Gier Gierige +Giffaro +Gifgas GigaBinary +GigaChad FSW Gigabit +Gigantic Nut +Gigantic Owl +Giganttio +Gigashit +Giggel Boy +Giggety +GiggleFailer +GiggySmalls Gigi Gigime +Gigs x0rz +Giiblo Giiirtz +Giitzy Gijoe184 Gijs Gijsbart +Gilan Gilbert +Gildart_91 Gilded +Gilded Gucci +Gilded Robes +GildeddGuppy +Gilenoth +Gilesy_93 GilgaGaming Gilindur +Giljom Gillan +Gillbert44 Gille Gilles Gillisuit +GillyChop +Gillyjj Gilnash Gils +Gilthresa +Gim Balboa +Gim Mayhem +Gim Reaper x +Gim Rickard +Gim Sahara +Gim Synicals +Gim ckn +GimJonel Gimaralas Gimbli102 Gimlocke Gimme +Gimme Pixels GimmeDatWAP +Gimmie 500k +Gimp Charona +Gimp George +Gimp Rachau +Gimp Sage +Gimperfect +Gimpgas +Gimptan +Gin N pizza +Gin Theory GinValid +Gina Linetti Ginekologs +GingaFe +Gingaaaaa Ginger +Ginger Elvis +Ginger KG GingerUnit49 GingerZ94 +Ginger_Men Gingerbeefe Gingr +Gingr Snaps +Gingyge +Ginjaah +Ginko Sora Ginny Ginobeatsss Ginyuu +Gioarcher69 Giorgi +Gios Ladder +Giovanniam Giovano +Gippeo Gipson Giraaa GiraffeLord Giraffeneck Girl +Girl10116 +GirlGamer420 +GirlLoveeee Girls +Girls Add Me Girlygurl420 Giroza +GirrthBrooks +Girsu Girth +GirthBeast +GirthMatters +Girthy Bunny GirthyBaboon +GirthySack Giskardr +Gist Gistermorgen +Git Ducked +Git Gudr +Gity +Giuuntas Give +Give Advice +Give Er +Give Me Kith +Give Purple +Give Purples GiveMeMaul +GiveMutagen Given +Given Bow +Given Power Givera0 +Giville Giving Givox +Gixerikan Gizmoed +Gizmoo247 +Gizzy-71 +Gj nice Gjerloew Gjonunaki +Gktr +Gl Bob +Gl Im Dandy +Gl Im Tom +Gl0ver GlLDARTS +GlM Sam +GlMKingCole +GlMP Blue +GlMP Purpp GlNGER GlRLS +GlTHUB +GlUwUten +Glaceon Girl Glacial +Glacial Fog GlacieredTig GladePlugIns +GladeSONPT Gladeandy +Gladiator12 Gladiator4x4 Gladpootje Glads +Glaeser +Glaive Rush Glance +GlasMelk +Glasabarn Glashute +Glass talons +GlassIsrael +Glassblow Me +Glassface +Glava Glavas Glazmeister Glazyy +Glcnn +Glcnn II +Glcsw Gleassi Gleddified Gleep +Gleesoman123 +Glejak Glen +Glen Cook +Glen Kenobi +Glen OSRS +Glenbobis +Glennis25 Glennitals Glennyboy Glennzii +GleuberBTW Gleythar +Glicky +GlideWho Glierieman GlitCH1221 Glitchfather +Glitchxd +Glitterix Glo-Tank +Glob Master +Globalled +Globby Gloc Glock +Glock 48 GlockHoliday Glockford +Glocktopuss +Glocs +Glod Gloei +Gloei Lampje Gloom Gloop Glopyz Glorfsaus Glories Glorious +Glorpy Glorp Glossay Glou +Glough Gloves Glow +Glowing Dawn +Glowing Ray Gloyer +GlucGluc9000 Glue +Glue Scroll GlueInhaler Gluehbirne Gluest1ck +Gluhh Glukoosi Gluons Glut +Gluteeni +Gluten ei Gluteous +GluteyIM +Gluurbuur Gluurder +Glyn Glyo Glys +Gmackie1 +Gmic +Gnaes +GnakNim Gnarkotics +Gnarled Gnarles +Gnarly Nacho Gnarlysurfer Gnarmato Gnarnold Gnarwhal +Gnashit GngBng +Gnge Gnight Gniles Gnoblin Gnome +Gnome Ass +Gnome nz GnomeBustas +GnomeChompii +GnomeFN +GnomeScarf +Gnome_child1 +Gnomeball Me +Gnomedalf Gnomeopathy Gnomeplay Gnomeputone Gnomerex Gnomeruno +Gnomes +GnomesDid911 +Gnomonkey +Gnomuim Gnon +Gnoob Gnorc Gnos +Gnosticz Gnotyep +Go Already +Go Die Go Do One M8 +Go FF +Go Outdoors +Go Outside +Go Rogue +Go Thanos +Go ask Wiki Go2HornyJail +Go4Stonks GoBearsUA GoBiiii +GoDhAsCoMe2u GoDrinkWater GoGGu +GoIsland GoPlayOutsid +GoSlow +GoToBedKids Goads Goal2Max Goalkeeper54 Goals Goat +Goat Toes Goat512 GoatAteMySon GoatOfWar GoatStank +Goatbigboy Goaticorn +Goatman Goatmelk +Goatrilla Goats +Goatsky Gobbie Gobiasinds Goblin +GoblinBreath GoblinLevel1 Goblinborn +Goblinchips +GoblinxSlaya Goby358 +Gochancee1 +God 126 +God Aye +God Bjorn +God Flax +God Forgave +God Like PvM +God Of Chips +God Of Hatrd +God Of Lamps +God Of W13 +God Pandora +God Ranger90 +God Tier +God of Walls GodDmntNappa GodEmpsTrump GodHalfMercy GodKingJT +GodLovesG4ys GodM GodOfCats GodOfTorment GodSaidGrind +GodSaved GodSlayer422 +GodSoge +GodTierAcct GodTormentor Godaa Godcody +Godd Is Good Goddaz GoddessAmaya GoddessHylia Godenzonen +Godeso Godezzo +Godfather TR +Godfather9 4 Godis Godkip +Godleh +Godlike Nico GodlikeOne Godly GodlyLeecher GodlyThug GodofAhri +Godofore +Godofyou2 +Godric777 +Godrics Gods +Gods Madness +Gods Plans +Gods Savage +Gods Taint +Gods Word GodsBlackSon GodsSniper GodsSyndrome GodsZombies +Godsent GodsentHero Godspade +Godss Angel Godstrong +Godswordl +Godte +Godumas +Godvermomme +Godwar Godwise GodzFear Godzilla Godzilla1282 Goed +Goed Gedaan +Goed stinke Goedaardig +Goedgemutst +Goeie Sannie Goeman Goes +Goggoli Gogo +Gogo Gorilla Gogojuice +Gogoud GogurtYogurt Gohan +Gohanski Gohler +Goiij +Goilin +Goin +Goin Slayin +Going HCIm +GoingBald130 +GoingBonkers Goinvokeman Gojam +Goji Berries +Gok Wan k +Gokillanoob Goku +Goku 420 +Goku Nazz Goku3ss3 Gokuu +Gol +Gol D Stocks Gold +Gold Avocado +Gold Devill +Gold Golem +Gold Lynx Gold M40A3 +Gold N Mole +Gold Ox +Gold Ruler +Gold Scrap Gold-Ileana GoldTracerR1 Goldclaw30 Golden +Golden Acorn +Golden Dunes +Golden Eyes +Golden Power Golden2Aim GoldenArm647 +GoldenGoose GoldenMinion Goldendev +Goldendrgn GoldfarmCOX Goldie47 GoldieOne +Goldiekk +Goldkimono Goldless Goldmagic +Goldmagic 1 +Goldminer727 Golds +Golduck +Goldy Mox Golem +GolemDuoGIM Golemantium Golembaby Golf +Golf Socks Golfcarts Golfje92 Golfkarton Gollito GolloSam +Gomardo Gomham Gomsugo Gomut +Gon GonDaba GonFeeshin +Gonah Gonapappa Gondort Gone +Gone9237 +GoneClear +GoneFarming +GoneInDry GonjaMon +GonnaSleep +Gont Gontr +Gonyor Gonzalo +Gonzra +Goo Cat GooMoonRyong +Gooball Gooberz +GoobledeGoop +Goobtacular Good +Good Bull +Good Creb +Good Cuxt +Good Darts +Good Duck +Good Ironman +Good Natured +Good Pho You +Good Potato +Good Voodoo +Good lol GoodFight +GoodGuyJosh +GoodOlBussy +GoodSkinCare +GoodTalk BRO +GoodVibes Gooda4 +Gooday2uall Goodbye +Goodbye game Goodcents +Gooddeerend +Gooder Album GooderB0aty +GoodlyKi56 Goodole Goodpizza +Goodriver Goodwin +Gooey Bace Goofy +Goofy Kitten GoofyLlama +Goofzillers Googagoogago Googie +Googii Google +Google Plus +Google THC Googleisme Googs +Gool164 +Goomy +Goon Galore +Goon Rangoon +GoonRNG +Gooner Gooneshy Gooney Goooby Gooochy +GooodO1dDays Goopbandit +GoopityGlorp Goose +Goose Field +Goose World GooseAlmyti +Goosebottle +Goosecaboos Goosely Gooshus +Goostafus Goothan Gooziky Goph +Gopherpaws Gophurr Gopuppy +GorGorDon16 Goragtong +Gorak +Gorastaman Gorathe +Gorazdus Gord Gordi Gords @@ -8819,68 +18271,133 @@ Gore GoreTexZ Gorehogthot Gorg +Gorge002 Gorgeous +Gorgeous Vin +Gorgeous War Gorgonsolo +Gorgoth +Gorila911 +GorillaChad +GorillaHaze GorillaMon3Y +Gorillr Goriox GorkOfGuthix GorogSmash Goromi +Gorons Ruby +Gorpie GorskiGG +Gortron +Gory Figment +Gorzie Goshiki Gossip Gosustyle +Got Mad Nugz Got my DD214 GotABigDoing +GotItAll99 GotTheTool GotchuXL +Goteborg Gotemburgo +Gotham Steel +Gothic Mommy GothicHippy Gothicking70 +Gotta +Gotta B Dope GottaSlay Gottaburn +Gougar Gountor5 +Gourd GourdPicker +Gourmandise Gourmet +Goy Boyy +Goy Oy Vey Gozi Gozpot Gp On Me +Gr OO7 Gr0tti +Gr33n +Gr3at Noob +Gr4naat Gr4p3 +Gr4y W0lf Gr8Legacy +Graaf Mol +Graardad +Graarp +Graav Grab +GrabAColdOne GrabbaLeaff +GrabsPeePee +GraciousHeeb +Grade I Graenmeti Grafie Grafvs Graham47 Grain +GrainUhSalt Grainfedbeef Grainter +Grainwave Grainys +Grakron +Grallham +Gram othy Gram0fDabs Gramalio +Grambo Grammar +Grammar Naxi GrampaDreami GramsaySan Gran +Gran t +Granbyboys69 Grand +Grand Magpie +Grand Tree +Grand mb GrandErected +GrandSlash +GrandVince +GrandWizard +Grander LTU Grandikid GrandmasterT Grandmasters Grandpa +Grandpa H Grandwarlike Graniitti +Granite God1 +Grannolegs Grannt +Granny Tiddy +Grant +Grant LLKL Granto +Grantos1993 Grants2004 Grape Graphics +Grappleshot Graros Grasp +Grass Nugs Grasshoppper +Grassman-420 Grast1z +GratefulFunk Gratefulfunk Gratis Gratitheode @@ -8888,178 +18405,360 @@ Graudalin GraveDiqqer Gravecan Graveless +Gravenor Graves Gravew0rm +Gravitrons +GravityPulse GravyTugboat Grawgar Gray +Gray Goo +Gray Icon +Gray Nine +Gray Owl +Gray Sails +Gray Wolf31 +GrayXOF +Graybanns Grayden Graymarrow Grayola +Grays Peak +Grayv +Grazalay +Grazia Grazing +Grazing Goat Grazium +Grazuz +Grazy Killah Grazzak GrcRevisited +GreFunky Greally +GreasierNerd Greasy +Greasy Nerds GreasyGoose +GreasyKnucks Great +Great Catto +Great Dain +Great Sneeze GreatBritain +GreatFambino GreatGinGin7 GreatNorth +Greater Rev Greaterbeing +Greaterwang Greatgranpa Greatwhite62 +Gredhkj GreedyFox GreedyG4me Greek +Greek Bust Green +Green Floyd +Green Gh0st Green Guru42 +Green HoHo +Green Molly +Green O +Green Theory +Green noob Green0ktober GreenBstard GreenClue GreenCortex +GreenMonstah Green_Matcha Greenbeens1 +Greenboy638 Greendor +Greene Daeye Greenikulas Greenmusiq Greenwell Greenwolf666 Greg +Greg Bcknghm +Greg M +Greg NM +Greg Why +GregLAD Greggery Gregley +Gregobeast69 +Gregor itos GregorJesk Gregornaut Gregory +Gregoryxo +Gregreg Gregsdabomb +Gregy165 +Greh Greig +Greil +Grej Gremlin Gremoir GremorysPawn Grena +Grenadev Grenenjah Grenthyl Gressaker +Grewal +Grey Beards +GreyCheddar GreyStation2 +Greyballes +Greybird +Greyhound00 +Greyhounds Greyhunter +Greytness Grider Griefstonks Grieve +Grieve r Grieve4Nieve Grievedd +GrifSpice +Griff Please +Griff6GG Griffey +Griffeydor Griffimano Griffin +Griffin 900 +Griffinerr Griffoo Grifo Grifwin Grihm Grilby +Grill Bears +GrilledNem Grim +Grim Lahey +Grim Reapr Grim1O GrimR GrimRequiem Grimalkinn +Grimby +Grimescene +Grimey17 +Grimfeather +Grimhimblem Grimm +Grimm Malice Grimmauld Grimmij0w +Grimmjaww +GrimmjowCero Grimmlie Grimms Baane Grimnitro Grimple Grimreaper22 Grimsomebody +Grimwar Grimwold2 Grimy +Grimy Elf +Grimy Ghetto +Grimy Guamay Grimy H +Grimy Lord +Grimy Oppie GrimyBuchu GrimyIndica +GrimyPussy +GrimyRanarrs +GrimyTorstol +Grimz Reapin +Grimzyy +Grinchy Grind +Grind 4 Max +Grind 4 Pets +Grind Time Grind4Life2k +GrindAndGame +GrindFaster Grindcorr Grinder GrinderTo99s Grindin Grindinator Grindius +Grindlwald Gringotts GrinoReigns +Gripzakje +Gris Moor +GrittyTacos +Griz mobile +Grizmatik Grizzley +Grizzly +Grizzly Rock GrizzlyCares GrmblGrombl +GrnBstrdO_o Grobar20 Grobaz Grod15 +Groen Hertje Groene Groesbeek Groet +Grog Dog +Grog Mobster Grogget Groleo +Gromada GrommrUK +Gromp Love Gronk Gronky +Gronky Mutt +GroogeN +Groot Lol GrootPool GropeJelly Gros Gross +Grosyte +Grot I +Grotegelds Grotkop Grotty Grottyzilla +Ground Hawk +GroundGolem GroundRanarr +Group Int +Group Pig +GroupAaronMn +GroupSexyMan +Groupie Hugs +GroupieSheep +GroupyCoopy +Groves +Grow Culture +Grow a Set Grown +Grown ups 2 Grrh Grrim Grrr17 Grrrrrrr +Grubbfoot +GrubbyNative +Grubumas Grucci Gruglio Grum Grummmy Grumpy +Grumpy Bear +Grumpy Dane +Grumpy Rock +GrumpyBean GrumpyFire +GrumpySkelly +Grumtuque +Grunderzz +Gruntlife +Grupopo Grwl Gryff1n Gryygeri Grze100 Gschlez Gsef +Gsuz +Gtacoolz GtheSquid Gtotgt +Gtr Zilla +GuBoki Guadanha Guak Guaka Guala Guam +Guam Autism +Guam Extract +Guam Leaf +GuamFarm +Guapify Guar GuardMaze Guardhakan +Guardiaaan Guardian726 Guardy Guason Guataca Gubrew Gucci +Gucci Print +Gucci Sheets +Gucci Skrrt Gucci0 GucciBalboa +GucciChris GucciDang GucciDragon +GucciMedHelm +Guccifi GucciiFlops Guckle Gudfad3rn +Gudge +Gudginator +Gudmen Gudomligt +Gudown Guelph +Guernicaa +Guess I Did Guest738 Gufix +Gugaru Guidebook +Guidefox +Guido Bwana +Guildboss Guile Guilles123 Guillotine Guilou3 +Guimmy GuineaHorn +Guizompaz +Gukkiman GulTraktor Gulf +Gulmek +Gulpar +Gulpin Gulsaft +Gum +GumGum B +GumGum Fruit +Gumat0s +GumbleChunky +Gumbygerkin +Gumbygrump Gumbygusher Gumbypriest Gumiibear @@ -9068,12 +18767,19 @@ Gummibier Gummy GummyTushie Gumpie123 +Gumri +Gun +Gunalations Gunci +GundarV Gundrace Gundrak Gune Gunfire +Gunite Gunjamini +Gunman +Gunn a Gunna Gunnar Gunnawr @@ -9082,156 +18788,351 @@ Gunnolvur Gunny GunnyGuest Guns +Guns Up +Guns n Rozes GunsN +GunsN Roses +Gunshow36 Gunsmith95 GunsonGurner +Gunta Guy +Gunter +Gunteria GuntherNese Gunthie Guntilius +Guntown Gunvald1 Gunwil +Gunzyx +Gupto3 Gura GuraChan +Gurahka Gurchh Guren +Gurenz Guri77 Gurilovich +Gurke Gurkes Gurnie GurningPills +Gurnsy Gurog Gurp +Gurp Gork +Guru Pathik GuruOz3 +Gus is Maxed GusMagnel +Gushing Thot +Gusmamba Gustav +Gusten +Gustice Gustie1 +Gusty x GuteArbeiter Gutenberg +Gutenberger +Guthiccz Guthix +Guthix Boss +Guthix San GuthixIsBae GuthixVapes Gutti +Guuds +Guus geIuk +Guusman Guwaap Guwapp +Guwgle +Guy Shishioh +Guy Williams +Guy in hat +GuyBillNye GuyDude GuyHarvey GuyInReaLife GuyOnaBear +GuyOverThere +GuyintheChat Guyringo Guzas +Guzman Loer Guzzle Gvjordan Gvzy +Gwaas Gwas +Gwas BE GwasMaster Gwasha Gwasing +Gwaztec +Gwd Gweav +Gween Dwagon +Gweeve Gwellz +Gwenchanaa +GwigMate Gwimer Gwinter225 +Gws 2 +Gwu +Gwublin Gwyn +Gwynrwyn +Gxhost Gyanzin +Gyga +Gym Beam +Gym Is Home +Gym then GYG +Gymming Gymp +Gynn GypsyAvenger +GypsyTears Gyrati0n Gyro Gyroman +Gyrotta Gytisr9 Gyts Gyym +Gz Parsec GzBs +H 0 U N D +H 2R +H A D O +H A I D E S +H A M M E H +H A R L S +H A T +H A X 3 D +H D M P +H E A L E R +H E J S A N +H O L M E +H Q Killer +H S 7 +H U L K K +H U N A J A +H a t y +H a w n y +H abs +H alo +H ch +H e c t o r +H i n e s +H l E U +H obbs +H owl +H rekDoer +H uff +H-tsi H0B0 H0DEX +H0LINESS H0NA H0PES H0RSEFIGHTER +H0RY +H0j +H0j00 H0lyPorkyPig H0me H0nestyBe +H0wy H1GH H1gh H1gs +H2 Ninja +H20magic H22a H2GivesUTheD H2HO H2Okt +H2R H3AV3N1Y H3NNESSEY H3adBurner H3ll H3llg0g H3nti3 +H3rbMaXD H3rbs H3rioon H3xxar +H4RD P V M +H4RD PVM +H4wk0n H501 +H61 +H8 +H8rry +HA RD HACHE HADYYY +HAHA CODY +HAMMY P0TTER HANDLEwCARE HAOKIMALONE HARVEY HARYWERNASDA HASA +HAUS DOSAN +HAWGCRANKD HAXERFUGGv2 +HBPandox +HBTFD HBTurpin +HC DVS HC Diego +HC H R A D +HC HALLEN +HC J P +HC Lone +HC Nitsy +HC PogChamp +HC Tehl0rd +HCByTheWay HCIM +HCIM Freak +HCIM Telmo HCJynkky +HCTHB HCaturbate HCgenes HClM HCmunchies +HCquitter HCsndr HDGamerLewis HDarcticus +HEAD TURNER HEADLlNES HEAVYWElGHT HEAVYWORK +HEJNUS HEL1O HELPPOLOTO HELl0S +HEMSKl +HEMULIN LADA +HER0X HEREforPETS HERYWERNASDA +HEWlTT +HEXISZ7N510Q +HElMDALLR HElSENBERG +HFH141 HGCduke +HGHZ HHans +HI IM XP +HI lM SATAN HICK +HIHIHl HIKI VALUU +HIM thespaz +HINEaKIN +HKD HL8ight +HM-O3 +HM01Urself +HM01Yourself HM02YouFools HM05 +HM05 Flash +HMFIC +HMR9 +HMS Bass +HMTickle +HMWRCKR +HO NK +HOB0MAN +HODL DEEZ HOKIE +HOKIE II +HOLDUP +HOMIE_SNKE HOOD HOOLlGANS +HQ140 +HR palvelut HRVRD +HRZ Dennys +HReversti HT Hero King +HTKBeast HTTP HUGE +HULKSMASH +HULL CI TY +HUMANATSIGHT HUMPING HUUTIS HVSG73373535 +HWFG Jordan +HYDROPWN1C +HYPEHYPEHYPE +HYPERTAIKURI +HYPOXD +Ha Tsjoe +Ha Yea +Ha rrison +Ha ss +Ha1fWayCrook HaClintondix +HaKooro +HaMwise HaNamer Haaaa Haaaydeez +Haar-Xil-MES +Haarde Knud Haardest Haarvey Haavard Habaneros +Habbitatt Habib HabsWin2021 Hachune +Hacien +Hacis Zone +Hack McGraw +Hackdash Hacked +Hacked Here +HackermanJS Hackett116 Hackie +Hacklang Hacky +Had Enough +Had2hurt HaddlingOS Hadeees Hadei Haderlumpen Hades +Hades m8 +Hadezzz +Hadhod46 +Hadies205 +Hads MC +Hadyen +Haelendur Haell +Haemogobl1n +Haertyew Hafco Hafcos Hafdis @@ -9241,22 +19142,42 @@ Hagaar Hagedis Hagenau Hagenees +HaggisChaser +HagridGone Haha +Haha noob +HahaBonk HahaYes Hahaha +Hahalord888 HahnSuperDry +Hahru HaiDiLao +HaiHai +HaiIZaros Haiaf +Haiden Haidynn Haighy +Hail to Pitt HailYeah +Hailie Jade +Haio Hair +HairNotFound Hairy +Hairy Batman +Hairy Dery +Hairy Hobbit +Hairy Hooker HairyCave +HairyGirls76 HairyLatino +HairysJungle Hairyteddybe Haissi20 Haiten +Haitze Haizet Hajduk Hajj12 @@ -9265,28 +19186,49 @@ HakGwai Hakafissken Hakala HakanTheMad +Hakaniemi +Hakattu Hakeem +Hakkie Hakkua Hakozuka HakunaWHO Hakuryuu Hakwai +Hal Jordan +Halaal +Halal 1 +Halal Burger HalalSnakbar +Halaladdin +Halbrand3791 +Halcony +Halcyon Myth +Haldir Haldir140 +Haldun Hale +Hale End Half Half Volley +Half a Cig +Half a Worm HalfAb0rted HalfHawaiian Halfdanger Halfway HalfwayOkay Haliax +Halibelle Halipatsuife Hall +Hall of Fame Halla +Halla-Aho +Hallako Halleloja Haller +Hallo Knul Halloman71 Hallonkram Hallowed @@ -9294,74 +19236,156 @@ Halls104 Hallucianter Hallucin8d Hallufauz +Halluusio Halo HaloMisfit +Haloboy Haloking176 +Haloman6666 Haloo +Halseys Halsly +Haltrek +Halujo HaluunKeksin Halve +Ham Dip +Ham Turkey +Ham r +HamHawk +Hamada +Hamaken Hamataka +Hambam55 +Hamburgor Hambzy +Hamdulilah Hamed +Hamel Hamii Hamis +Hamlee +Hamm HammZ Hammer +Hammer Man +Hammer4422 Hammer4442 HammerTime29 HammerTine Hammered +Hammertime Hammond +HamnerTime HamoodyShimy Hamp +Hampton Bays Hampus +Hamrocks Hamsterslayr +Hamstr Hamudiy +Hana the Mad +Hanashee +Hand Puppet HandTuggy Hande +Handecapped +Handex Handicap HandleofJD Handley Handphone Hands +Hands Hurt Handsome +Handsome Rob Haneet +HanekawaSimp +Hanfkeks Hang +Hang em high HangChowCrow Hangin +Hangin Nuts Hanhen +Hani +Hanikala +Hank Jackson +Hank T Tank +Hank343 HankTheTank2 Hankanini +Hankk1 HankoAJ Hankzilla Hannah Hannh +Hannibal GIM Hanno Hannu +Hannu Poika +Hannu Soolo +Hannys Main Hanoi +Hanoi Rocks +Hanoob btw +Hans Glans Hansen Hansern +Hansiil +Hansonville Hansy +Hantarded Hanwi Hanzino HaochengZ Haole Haphazzardz Hapoton +Happ1RS Happier Happiikhat Happy +Happy Beluga +Happy Dappy +Happy Feet +Happy Josh +Happy Kitty +Happy Light +Happy Meal +Happy Prayer +Happy Tj +Happy exSlut +Happy2DaCore Happy420 +HappyMeds HappyPandaXD +HappyScape +Happydud01 Happyfrog12 Happyguy +Happypurpday +Happytoy +HapuApu Hapukurk HarKieren +HarO Reborn +Hara YEP +HaraHachiBu Haraket Harambe +Harambro +Harash Harassment +Harbix +Harbor 2567 Hard +Hard Chance +Hard Clue +Hard Filmur1 +Hard Kinta +Hard TeK HardFormed HardHatJeffy HardMannetje @@ -9370,13 +19394,22 @@ HardRazer Hardc0reBruh Hardcome Hardcrux +Harde Pik HardeSnikkel +HardenedRS Harder +Hardeschijf Hardie +Harding Hardlesas Hardman +Hardon hank +Hardstyle IM Hardwaring +Hardwell420 +Hare Danger Harem +Harem Isekai Harja Hark Harka @@ -9384,122 +19417,236 @@ Harken Harken21 Harlekin Harlem +Harley Nz +Harleyrox +Harlie Harlot Harm Harmala Harmentje +Harming +HarmlessTwig +Harmon Angel +Harmoniiumm Harmonized Harmony +Harmonyy Harmr Harms +Harms Whey +HarpoonMyAss Harraggen Harresvela Harri +Harri Hylje Harriganrace +Harris0n Harrithon +Harrods Fish Harrris Harry +Harry Bucket +Harry Dirty +Harry Hendo +HarryPoppa HarryTheGOD HarryTheWhte Harryalt +Harryguy23 Harryindacut +Harses +Harsh Times Harshhashh HartIess Hartlepool Hartree +Hartreni Haruka +Haruka Meh +Harus Ranger Harutikk Haruto Haruuki +Harvahammas Harvardista +Harveytec +HaryLongWood Has2BeSHiFtY +Has547 +HasOneLegacy Hasballa +Hasbullah Hasek Hash +Hash Browns +Hash House +Hash One M8 +Hash katchum Hash1 +Hash1Aussie HashHund HashIsLife +HashTagYou Hashh Hashiiirama +Hashimm +Hashlife HashtagGOALS Hashtagz +Hasloa Hass +Hassall Hassis Hassoni Hastings +Hasty Power +Hat i +Hat tis HatchetOG +Hatchkat17 +Hatchling +Hathrow HatiFnattt +HatoradeJack Hats Hatsune +Hatsune Miko Hatsy Hatte +Hattibagen Hattnn +Hattuviilari +Haubjerg +Hauki0nFive Hauki0nIron Hauki0nNoob Hauki0nUlti +Haunleff Hauntedfury Haunter12123 Hauntya HausHausHaus +HautaNorsu +Hautboi HavU Havac +Havard Havawk Have +Have Sabr HaveAGood1 +Havendare +Havenmeester +Havi k +Havidex +Havoc Grasp HavocRavage +HavocThomas Havok Havottaja Havzzter +Haw +Haw4iiankush Hawaii +Hawaii Ice HawaiiMadez Hawaiian +Hawasser Hawes Hawk +Hawk Driver Hawkear Hawkes +Hawkeye87 Hawkit HawkofLight HawksMama +Hawkwound +Hawkzrael +Hawler12 Hawolt +HaxY Haxd +Haxident +Haxixero Haxn Haxnoiz Haxoonie +HayHay Hayabusa +Hayaku Hayasaca +Hayasaka +Hayboo Hayden3 +Haydenl451 Haydenss +Haydern Haydor Hayesy Hayfield Hayirlisi HayleyQuinn Haylz +Haynex +Haz-zy +Haz2 HazDownz Hazade +Hazardless Hazardouss +Hazards Haze +HazeCloud99 +HazeMePls HazePGN Hazed Hazeley +Hazezor Hazla Hazsle +Haztraz +Hazy Sparrow HazyHerb +HazyHour HazzFive +Hc OffWhite +Hc Oh Wait +Hc Toleranss +HcFlex004 v4 HcGon HcHoopla +HcimTironade Hcimdiot +Hckie +He Adventure +He Pinky +He Who Iron +He nry He11zdone HeSmokesBud Head +HeadBear HeadHuunter +HeadOverseer +Headache +Headenforcer Headgaskets Headleya +Headliners Headlines +Headlines v2 +Headshotting +Headwipe +Healers +Healty Heard +Heard Chef Hearne +Heart Please Hearted Hearten +Heartlesdude Heartlock Heartquake Hearts @@ -9511,154 +19658,299 @@ Heat HeatSeekr187 Heated Heathen +Heathenry +Heather x3 +Heatmyser HeatproofIM Heav7n +HeavenIyGard +Heavener HeavenlyBlue Heavens +Heavens Feel +HeavensDao HeavensStorm +Heavensdown Heavy +HeavyBowGun +Heb0 +Hecec Heck +HeckIron +HeckinWoofer HeckingFish HecklerNKoch Heckstrm Hecote Hectic Mic HecticGinger +HecticHerb +HecticKebab +Hectoplasma Hedge +Hedralx +Heebie Heedbo Heee Heel Heeling +Hefboom HeftyFlan HegXDXD Hege Hegelund Hegert Hegesy +HehtoLerssi +Hei Kneuter +Heifetz +Heightenings HeikkiPentti Heil +Heil Pierce +Heil Vegeta Heilios +Heill Ragnar Heinamies Heineken +Heinekentje Heinered Heinzzel +Heir HeirHead +Heisbergh HeisenBergW +Heisenber9 +Heist Music +Hej hej +HejBrink +Hekaton Hekdik Hekla Heko +HektikBadger +Helbur Heldip HelemaalMooi Helesta Helium +Hell ETC +Hell Kitt3n +Hell ffa HellAngel HellBlood Hella +Hella Tonk +Hellabad Hellafly +Hellagaybtw Hellandnz Helldog946 Hellhaunted +HellianV Hellinferno4 Hellixx64 Helllblazer +Hellmo Hello +Hello Bel +Hello Friend Hello6 +HelloBot9000 HelloDottie Hellodummy Hellrain962 Hellrazorr +Hells 10hp +Hells Chance +Hells Godz +Hells Puppet +Hells doggy HellsRavage2 +Hellwater Hellz Helm Helmoid Help +Help Autism +Help I Gay +Help my +HelpImStupid HelpLahh HelpTheNoobs +Helpful +Helpless Ale Helson Ryse Helta9 Helx +Hema roids Heme2 HemeSupreme Hemiptera Hemmii +Hemmur HemoGlobe Hemp +Hemp product Hempopotamus +Hempwick Hems +Hen Ac Araf HenaQ +Henbane0 +Hendo Au Henee +Henehh Henfami Hengecobdig +Hengggga +HenkDeTanker HenkdePlank +Henkka Btw +Henkka242 Henkkawaa +Henkkiiieee Henkleebruce +Henko420GB +Henktius Henlo +Henners Hennesssssy Henni Henniejj Hennssey +Henri380 +Henry Fe +Henry XV Henry14 Hens +Hensel +Henslord +Hensta +Hentai Daddy +HentaiMaiden +HentaiMusic +Henu OG +Henzone58 Heolis HephaestusRS +Her Gay HerAddiction Herb +Herb Deen +Herb Lab +Herb Quest +Herb box Herbacist Herbaderb HerbalKing +HerbalTeabag Herbalicious Herbby Herbilicious Herblore Herbmania +Herbmatic Herbogus +HerbsnSpicer HerculesLoyd Herculooo HereFor_Beer HereSomeDank HeresALlama HeresySlayer +Herk +Herkko +Herkko32 +Herkku Herkules Herky Herm10ne Hermanni +Hermaus M +Herminator0 Hermit +Hermit Jack Hermitian +Hermot palaa Hero +Hero Extreme +Hero Kid +Hero vs Hero HeroDan +HeroGenos HeroToby Heroed Heroic +Heroic Hope HeroicDesire +Heroicjesus +Heron Bird Herp Herpa HerpaGnome HerpesNo Herpesbek +Herpito +Herr Gaucho +Herr Luc Herra +Herra Beavis +HerraBonsai Herrits +Herrmann3 Hesienberg Hesitation +Hesmander Hespori +Hespori KC +HesporisSeed Hespus Hess Hesson +Het Heden +Hetdorp +Hetebeir +Hetehaan +Hetimos +Hets Capture Hetumo Hetzer Heuha Heur +Heuro Heuvel +Heuvel Reus +Hevenlys Hever Hevi +Hevi Luumu Heving +Hewy +Hex Is Maxed HexMage Hexadecimal +Hexagon Heat +Hexalogy +Hexedited Hexenblut666 Hexenkonig Hexication +Hexos +Hexphase Hextale Hextra0rdnry +Hexun Hexxjan +Hey B +Hey Bob +Hey Cheems +Hey Im Dylan +Hey J +Hey Jase +Hey Jay +Hey Mills +Hey Ubba HeyBeautiful HeyBigDaddy HeyDaddy @@ -9666,42 +19958,103 @@ HeyFonte HeyHowsLife HeyItsLachy HeyLuffy +HeyThatsLife +Hey_Duck +Heymakerz +Heyman Heywaddup +HeyyDivine Hezbullah +Hezr HgH2 Hhmm45 Hhmora +Hi Cookie +Hi Im Ant +Hi Im Duncan +Hi Im Emil +Hi Im Frak +Hi Im Ken +Hi Im Pei +Hi Im Stevo +Hi Im Vitao +Hi ImMrRight +Hi Lvl Ideas +Hi Opal +Hi Ren +Hi Suka xD +Hi Tyler +Hi im Gin +Hi im Savage +Hi im Shar +Hi im Yellow +Hi lm Paul +Hi lm Sk8 HiDyvvnBDP HiGHFLYER +HiHowAreYa HiImIronRick HiImNicole HiLumbridge +HiNebb +Hiarii Hibbetts +Hiben75 +Hibernal Hick Hickery Hicu Hidaki Hidden +Hidden Power +Hidden one1 Hiddenn +Hiddinkiwi Hiddy +Hide Ink 207 +Hide Ya Kids Hidekia Hideo +Hideopenend Hider HidesHerEyes +Hidi Hidole555 +Hidro Hieroglyfic Hifter13 Higgens High +High Content +High Halpert +High Hustler +High Knight +High On Cake +High Ronnie +High Score +High Snorse +High Up Here +High as Zuk +High lm hi +HighAsF Bruh +HighBacon HighMeatloaf HighNoobJhin HighOnPlants HighProbably +Highbury Highcaalibex +Higher Force +Highestarchy Highfish +Highjacurmum +Highland +Highly Faded Highmountain HighonCash +Highs Highscaping +Hightierian Highway2Hell Higlen Higu @@ -9709,144 +20062,253 @@ HihoMenono HiiddeN HiipFiire Hiisgreat +Hiit Man Hiiz Hijack778 Hijsbergh Hiker Hikiukko Hikizato +Hikmet +Hilarious +Hilda Garde Hildr Hilge +Hilipilli Hilk +Hillhouse +Hillpker Hillram HilltopHick Hillzy Hilo +Himala +Himaster +Himtheguy +Himy +Hina Suguta Hincarpie +Hinchers Hindi +Hindle Hinny +Hinss +Hintai +Hiopeer +Hip Fe Hop +HipSlippers Hiphop Hiphopdude0 +Hipiguy48 Hipnodiskd4 Hippeis HippieLexy Hippies +HippoBlunts +Hiqhlife Hirae2 Hiria1 Hiroble Hiroticus +Hiroyuki Isa +His Faithful HisHungness HisLordship Hisano Hisblore +Hislordship HisokaX4 Hispeeed +Hissi-Timo +Hit U +Hit By Car +Hit Points +Hit The Guam HitMyVape HitOnRun +HitOrange HitTheVape Hitagi Hitch350 Hitchens HitherDither +Hitman Style +Hitme8 Hitmonchans Hits +Hits Like +Hitsumaru Hittimestari Hitz +Hiva Hiya Hiyouri HjaIIe Hjaldr HlKEN HlMBO +Hladomor +Hlata Hldz Hlep +Hlnub +Hm +Hmg Hawj Str +Hmm Fr Bruh HmmKoekjes +Hmmer Hmmingbird Hmmk Hmmm +HntrBTW +Ho Chi Meme +Ho LiFuk HoButter HoFkee +HoLeShite HoarderMan +Hob Ralford +Hobbi Hobbit +Hobby Jogger Hobex +Hobgoblinas Hobgoblins +Hobgrot Hobie Hobo Hobodude67 Hock Baws +Hockney Hocky Hocpuck +Hocus POTUS HodamOS +Hodeman +Hodge5 Hodgetwin Hodort Hodvik Hoffmanator +Hoffmanbmx Hoffsworth Hofus +Hog HogPacker70 +Hogboar +Hogboy Hoggormen +Hognag Hogo Hogsen Hogskoleprov Hoheti Hohhenheim Hohhoijjaaaa +Hoi An Hoilam Hoix Hokage +Hokage Jason +Hokage Sama HokageRS Hokiako Hokie +Hokiee +Hokies HolaBurrito Holbox Hold +Hold My Gun Hold3nMc +HoldMyShrimp +HoldenBallz Hole HoleNewName Holenes Holidayz Holiest +Holiidayyy Holisti Hollar Hollington24 Hollow +Hollowed One Hollsyy +HoloTheDrunk +HololiveOS +Holoubek Holsey3126 +Holt +Holtsen +Holunder Holy +Holy Cheetos +Holy Druid +Holy Jandals +Holy Moses +Holy Plan +Holy Rock91 +Holy Scrotum +HolyChrist HolyColt HolyDugong HolyElixir HolyEntity HolyGhost HolyHerb +HolyIronmoly +HolyMould HolySaints HolySkittles +Holycaw Holyfuk Holyhonza Holykana Holyshmokez Holyzuk Hom3r +Homage48 +Hombelkei Home +Home Boy +Home Office +Home Page +Home Plug +Home Run26 Homealot +Homebad Homefront Homegrowe Homelander Homeless +Homeowner Homepage Homer +Homer LT 0_o Homestead Homicide Homie Homies556 Homingstats Homlepung +HommeDeFer Hompski +Hon Honaz +Honchcrow +Honda Coupes +HondaXJ20 Honden +Hondo Ohnaka +Hondsvot Honest +HonestThomas +Honestben +Honestidade Honeytrippin Honeyyyy +HonkMyClussy Honket HonkeyKong Honkitonki1 @@ -9854,37 +20316,61 @@ Honko Honkys Honler Honor +Honourable Honq +Honra Honru +Hoo Lee Fook Hooba Hoobloob HoochFighter Hood +Hood Rat HoodBrothers Hoodaloo Hooded HoodedDeath Hooder Hoodieninja +Hoodless +Hoodlum_94 Hoodrat +Hoodstar XD HoofHarted +Hoogbegaafd +Hook +Hook N Arrow +Hookah Hookin4GP Hookr Hooleys +Hooofer Hoooka HooorrraaaH +Hoop Snake HoopaLoopz +Hoopdie Hoopre Hoopti Hoorus +Hooryu +Hootenanny +Hooyaah Hoozio +Hop Loser HopNowNoob Hope Hope4TheBest HopeSmolDicc +Hopeless +Hopelite22 Hopeu98 Hopian Hoppa +Hopper727 +Hoppip +Hoppipolla +Hops World Hoptilicus Horatio Horatioat @@ -9893,27 +20379,60 @@ Hord Hordalad Hordaland Hordelli +Horey Horizons +Horizons End +Horme HornDawgx Horned Horns +Horny4Herbs Horny4Hunlef Horozu +Horppi +Horrific Rat Horriser +Horros +Horrow jr Horse +Horse Tock Horselord +Horshock +Horsley park Horstel +Horus Hyla Horus1701 HoshizoraRin Hospitaliano +Hoss +Host Proctix HostileBoss +HostileCloud HostileEx Hostiles +Hot Ass +Hot Box +Hot Boxing +Hot Chesters +Hot Choco +Hot Chook +Hot Dog 1995 +Hot Dog Guy +Hot Girl +Hot Glacier +Hot Gril +Hot Hemp +Hot Shop +Hot Since 82 +Hot Stepdadi +Hot nurse HotAsianCuti HotCocoa HotCuppaT HotDoggWater HotManCurry +HotMaxCurry +HotPud HotSaus123 HotSnow Hot_Farmer99 @@ -9922,180 +20441,342 @@ Hotandhorny Hotbox Hotchelli Hotdog +Hotdog Timmy Hotdog655 +HotdogGravy Hotdogit101 +Hotdogwhat Hotel Hotkeys +Hotline Juan +Hotot +Hotputhy +Hotrod-Matt Hots Hotsbo +Hotse Hotsgonwild +Hotshotz61 Hotslol Hotwheeler Houdinski Houndstooth Houowvwvv +Hourlies +HoursAndy Hous House House748 +HouseSniffer +Houseman45 Housewife +Houston713 Houstoned Houstonnnn +Hovis +Hovland Hovmeizter +How do I win +How to quit How2Boss How2username HowAboutNeup +HowDoDisWork +HowHardd HowIing HowIsDis +HowLee +HowSway Howde Howland +Howler Head Howlini Hows +Howsey Howson HoySmallFry +Hoya Markus +Hoyaa Hoyah Hoyiron Hoyryjyra +Hoyyehh +Hp x Hp +Hr Banan4 +Hr CarlSmart +Hr KalZ +Hr Pagulane +HrMystik +Hra Amiraali +HraMajuri +Hraerekkrr Hrafnagud +Hrag +Hrathix +Hrry Hrungiir HshBrwnClwn +Hsilver +Hska HsrFresh +Htine +HuZ Ryan Huaraaturpaa Huard Hub3r +Hubbbzzzz Hubbz216 Hubeeb +Hubie +Hubiera Hubli +Huby K +Huck HuckUsAHandy +Huckn +Huddo Hudsy Huebs Huevote +HueycoatI +Huffers +Hug A Mudkip +Hug my cat Hugakitty Huge +Huge Coom +Huge Mudkip +HugeCcret +HugeCox HugeMike HugeSimp HugeSquanch +HugeXpWaste Hugh +Hugh Jannob +Hugh Jas Hugh Jazzhol HughAreMyron +HughJastle +Hughes Luck Hugo +Hugo Baws +Hugo C Hugodzilla Hugos Hugoslavic Hugotec +HugsTibbers Hugsi +Hugsqtface +Huhi Huhm0ng +Huhmble Huhu +Huidskleur Huiliuiliu Huilu Huinca Hukka Hulagu +Huler Hulk +HulkSmaash Hullcity25 Hulll Hulluke Hulluurpo Hulvatonta +Hulyx Human +Human Knight +Human Reject +HumanMalware +HumanSl0th HumanToxin Humanist Humanityy +Humanoid Rat Humb +Humb RS Humbabe Humberto Humble +Humble Finn +Humble Husk +Humble Otter +Humble RNG +Humble lp HumbleCanoe HumbleCrab +HumbleFarmer HumblePlayer Humblee +Humblegods Humbleherb Humblenobody Humbles +Humboy +Humgrump Humid +Humiliation +Humji +Hummbinger Hummerspeck HumperT Humpletics Humu +Hunajamurune Hundjagare Hundred +Hung Opossum +Hung Pikachu +Hung Zebra HungLow30 HungSolo45 Hungarry208 HungerRee Hungry +Hungry as fk +HungrySponge HuniePop Hunkadoris +Hunks +Hunlef Hunnets +Hunni Bunny Hunpy +Hunt Mike Huntarr Huntdragimps Hunter Hunter10139 +Hunter4056 HunterPandav +HunterXosrs +Hunters Main Hunterz +Huntin Specs Huntindawg Huntindawg2 Hunting HuntingGirls +HuntingPets +Huntinrox Huntinthotts +Huntiritox HuntnCoFTB +Huntsin Hunyadi +Huolon +Hupipelaaja Huppis +HuppuKostaja +Hups +Huqin Hurlae Hurleee Hurley +Hurley24 Hurlock Hurri +Hurrisun +Hurs 1 Hurtigmads HurtsDonut Huscarl +HuseG00SE Huseyin31 +Hush Pup Husker HuskerFool Huskieeeee +Huskvarna +Huskyskills +Hussar1683 Husse1n Husseinn Hustensaft Hustlez Huswan Hutchens +HutchoAU Hutros Huts +Hutula +HuugeCok Huugo35 Huule Huumepoliisl +Huupee Huutiset Huutoripuli Huviksee +Huxley King +Huxtap Huxtin Huzeyfe +HvH Hvale +Hvale Kongen Hvorfor +Hwael +HwbrangerUIM +Hwzrs +Hxc Ironfail Hxcmackin +Hxpeful Hxrm Hxrsey +Hy a Hy3RoGeN +Hy3RoGeN x HyAcey +HyDrooo +Hybernated Hybrid +Hybrid Hurtz +Hybrid Mech HybridSanta HydG +Hydi Hydr0nate +Hydr0p0nic Hydra +Hydra Ikkle +Hydra Spoon +Hydra_Lerna Hydraletics +Hydras Daddy Hydration Hydraxon +Hydrerion +Hydro-Quebec HydroBlast +HydroC +HydroGasMask +Hydrocarbons Hydroe Hydrofiner HydrosFather +Hyemi +Hyfens HyggeDansker +Hyi Hykd HylianLink +HylianLombax Hylkon +Hymy Hyosin +Hyough HypaDunkTv +HypaZestay HypeLad Hyper +Hyper 212 +Hyper Threat +Hyper autist Hypercam Hypercoaster Hyperdeath20 @@ -10103,68 +20784,310 @@ Hypermole Hypersomnia Hypertroll Hypertrophic +Hyperversity Hyphen +Hyphen-ated Hyphenated +HyphyRS Hypn0se Hypocriet +Hyprocrisy Hysteric4l +Hytrogod Hyttynen +Hyula Hyun Hyxbe +Hyze +Hyzers +I M +I Skilz I +I ADK I +I AM DROID +I Am Arun +I Am Calysto +I Am Cicu +I Am Dave +I Am Eugene +I Am Malenia +I Am Mathew +I Am Mizzou +I Am Times +I Am Vexed I Am Vono +I Am Xyience +I Am Yesac +I B Z +I Barak I +I Be Vibing +I Be Yankin +I BenJammin +I Bryce I +I Buy Bulks +I Buy You +I Call BS +I Cant Veng +I Chance I +I Chaz I +I Chop Life +I DanWise I +I Daniella I +I Decimate +I Descend I Dizz I +I Dont Gnome +I Dont Know +I Dont Weld +I Drink T +I Drive Jeep +I Duck Hunt +I ELITE I +I ET BBIES +I Emu I +I Enjoy Butt +I Faheem I +I Farm On Rs +I Flick Bean +I Gem I +I Genesis l +I Go Noob +I Gribben I +I Grind it +I H8 GAGEX +I Haros I +I Have Quit +I Heal DHers +I Herb Store +I Hunt Pets +I Hustle Man +I I ODIN I I +I JANGLER I +I Judgee Yu +I Ko U Lol 1 +I L0ve Lolis I LOTR I +I LV PEACH X +I Lezima I +I Liam I +I Liamz6 I +I Like Cake +I Like JoJo +I Lov3 Pho +I Love DILFS +I Love Kinja +I Love Kylie +I Love Muff +I Love You +I Luci +I Luhhya +I Luv tSwift +I M A P nuss +I M Ket +I M S N Y +I M The Weed +I Maxed OSRS +I May Be +I MoF +I Mograine I +I N D I A N +I Need 1M +I Need Succ +I Need aBeer +I Novato I +I Nz I +I OX +I Owning +I P0 +I P0KY I +I Parry I +I Peter I +I Pk In Monk +I Plank Lots +I Play Aegis +I Pod335 +I Pri +I Q T I R N B R U +I R O N 99 +I RC +I ReAPeR I +I Roll Need +I Ron Man +I Ruin Holes +I Run East 2 +I Sharted +I Smiteyou I +I Smoke Irit +I Specs I +I Spied +I Strangles +I Taka Hujit +I Teller I +I Tricky I +I Tuscan I +I Valknir +I Vape Lube +I Viral +I Want 60FPS +I Would Rage +I Xl I I Xl +I Yogurt +I Yoshitsune +I am Anyone +I am Bryce +I am DB o +I am Elk +I am Future +I am Glynny +I am J M E +I am Jedi +I am Niels +I am Nyheim +I am Olive +I am Ry +I am SHODAN +I am Saitama +I am Shiny +I am Shogun +I am Simon +I am Soloing +I am Twiggy +I am a wreck +I am aRusher +I am drunk +I am groot B +I ate +I bad Guy +I desire God +I do be Iron +I eat peach I h8 farming +I have egg73 +I have poon +I have rng I ll fail +I love me +I love yew +I m Dave +I m Kenpachi +I m an Angel +I matchjad I +I mpling +I n b 4 +I ndy +I nspire +I rvin +I sak +I smell zaza +I so pale +I squared R +I t I s +I tbag cows +I used to Rc +I van +I vinrox +I w4ste xp +I wana dew u +I want wings +I-IEEBO +I-Iulk I00OOOOOO00I +I2P +I2m +I2ocky +I2ossiiii I3ET I3WANA +I3ooth +I3ow Hunter I3ox I3rucex I3ubbles I3ulow +I7I +I7iablo +IA +IAM HARDWELL IAMBillNye +IAMDouble_C IAlwaysBurn IAmArcade +IAmArchangel IAmBabyYoda IAmBinx IAmEcliptic IAmFaptastic IAmFrampt +IAmJacbo IAmRichard IAmSlimShady IAmStyle IAmUnbound IAmWaffles +IAreTazz IB4I +IBB Baskani IBIoodRose IBaIance IBangBBWs +IBardak +IBloodwing +IBuyGF5GP IBuyPowers +IBuyShungite +IC 3 +IC XC NI KA +ICE GIANTT ICNK +ICantFit ICauseRage ICrazyCamelI +ID theft IDEPOCIEBIE +IDSilver IDark IDiabloI +IDustie IEATEDYU +IFALL3NI +IFIFIFFIFIF +IFIFIFIFFIFI +IFIFIFlFIFIF IFRC IFRS +IFRS 9 +IFartOnBaby IFernedYou +IFistBonk +IFoundABaby +IG0R II IGN0RANCE IGoogledIt IHQueenI IHasHips IHaveAWifey +IHaveChicken IHaveToQuit +IHobbitI +IHopFromNo1 IHuntKoalas +II Fabi II +II Gots Piie +II Mossy II +II TurMz II0III II0v0II IICyRaNoKII +III SLAYR +III jin III IIIBCIII +IIIGavinIII IIIel0n +IIIusionist +IIKOO +IIPAC IIPrincesaII +II_Blanx_II IIamaman IIflemishII IIlIIAS @@ -10174,24 +21097,119 @@ IIlllllIIlIl IIndy IIrisviel IIsaac +IIx Link xII +IJzer Bal IJzermeneer +IK Pegasi +IKotol +ILL M1ND ILLUMINATIS ILOVEUBRAT +ILVI ILike +ILikeKorone +ILizzy +ILostMySock ILostMyTalk ILoveAstolfo ILoveSeaFood +ILoveYasmin +IM Adept +IM BLUE DA +IM Bazlish +IM Big N8 +IM Bjakke +IM Bolle Ui +IM Butchh +IM CSI +IM Cares +IM Chaudoin +IM Corita +IM Dahak +IM Damy +IM Dislectyc +IM Dodgypig +IM Donactro +IM Drone +IM Dutch Dog +IM EL Clawo +IM Envy +IM Erlandu +IM GERRALD95 +IM Gekko +IM Gokhan +IM Guilty +IM HEEM +IM Hail +IM Harnas +IM Hulkeen +IM Infested +IM Jap1 +IM Jenskee +IM Kat +IM Knol +IM Krona +IM M U R P H +IM M0A IM Maccy +IM MajorRat +IM Maninja +IM Musa +IM Noddy +IM Ong Gia +IM PVM BRADY +IM PapaBless +IM Peach Man +IM Pepekage +IM Perp +IM Phubz +IM RICO_1 +IM Rampage +IM Reiner +IM Rome +IM Ruinscape +IM ST0NED +IM Sebaa +IM Soad +IM Spooned +IM Super AFK +IM Tank OG +IM ThiccSucc +IM Tipz +IM Toon +IM Walnut +IM Witt +IM Zoot +IM a pansy +IM blazeit +IM sanderve +IM spen IMAEATURASSS IMAFKNNONCE2 +IMGOKU1 IMHankey +IMHky IMJeffG +IMMezzo +IMNagrom +IMPERlO IMPlayerjohn +IMSOULSHADOW IMSausjegeit +IMSkrt +IMWaldorf IM_Queeffing +IMa Planker +IMakeUBegKid +IMevil yoshi IMissNieve IMnotQ +IMoIVoxide IMsmits +IN A FERRARI +IN PRISON RN +INCEL839273 +INCreate INDICA INFERNALMAX INTERMEDlATE @@ -10199,130 +21217,249 @@ INYOURTS INeedABump IOHBOY IOnSpacezI +IP6 IPkdYourBank IPlayForPeso +IPlayHigh +IPonderosa +IProGuthix IPumpkin IPunchKids IQUICA +IR Hardcore IR0N +IR0N BOND IR0NMAN +IR4Q +IRL Femboy IRON +IRON BYRNS +IRON DlOXlDE +IRON NOT HOT +IRONMAN ADO IReallyLikeU +IRework IRidePipe +IRoldy IRowForUCD +ISAPOOPS +ISO PEE ISOMAN12 +ISQQC +ISTRA +IScottGame +ISjorsI +ISmokeABit ISoLaTIIon +ISquirk ISuperStarI +ITIB +ITIISERY ITIOMME ITIace ITIaddy ITIagicka +ITIagicks ITIajestic ITIallen ITIasKilleR ITIassacre +ITIatty ITIerica +ITIiko ITIoj +ITIoosh ITIr ITSPYRO +ITV X +IThe Beatles +ITrimGlories +ITurtlekunI +IUR IUntradeable +IV Luke +IV skin +IVI V G IVICMXCIII IVIE0W IVIacaroni IVIaybe +IVIeesa +IVIeredith IVIesprit IVIetallica IVIidget IVIooN +IVIowlzy IVIugginz +IVIush IVIxtthew +IVOXYGEN +IW Lytheria IW4M +IWGP +I_Eat_Ass04 +I_Inity +I_Noodz_I +I_make_noise +Iacto Iaculch Iaffan Iafs +IaintHiding +Iam Bald IamAjewBoy +IamBowser IamBruun IamCheesin IamCrazyBoy IamDuru IamErect +IamGossip IamNSFW +IamNotHodor IamRichPutin IamSneak +IamThaLiquor IamXerxes +Iambadhaha +Iamcruxer Iamearth Iaminsanemax Iammooted Iammtpjr Iamstepbro +Iamthestars +IamthyPope +Ian Beale +Ian Rush IanT Ianalan Ianbird Ianeke Ianeke4 Ianyaboii +Ianz +Iax 2000 +Ibanezx88 Ibanezx99 +Ibans Fe nix IbansPheonix Ibarbo +Ibb +Iberis +Ibexleave Iblushh +Ibn Ibrahimovic +Ibugppl Jr +Ibunaaru Ibuprofen800 IcEyCuDa Icanfixthat +Icarius Fell IcarusRS +Icaruz Icculus1 +Ice 9112 +Ice Barrage +Ice Caves +Ice Gengar +Ice King +Ice clap +Ice giants Ice in Vodka +Ice5566 IceBarraging IceCreamDog IceDesert +IceFoxZero IceH +IceIceChooky IceNineKiIIs +IcePrisonMe IceSparro Iceb Icebeam Iceburghomie +Iced 0ut IcedOutDrip IcedScrabble Icedeadmage Icee +Icefirezz Icehound Iceid +Icejawa Iceland Iceleag Iceliang530 +Icelight +Icemonkeyz +Icen Icesoze Icespeller +Icetaylor Icey +Icey Lunaris +Icey M Iceyou90 Ichi Ichi6an +IchikaNagano Iciclez +Ico n +IconPara +Iconiic Iconoclasmic Icookpeople Icoz IctCat +Icy Duck +Icy Tires IcyFear IcyTowerr Icyene +Icyene Hero Icyenicblood Icyflowers Icyx +Id Tele Too +Id Yak It Idaho IdahoTaters IdcGoAway Idea +Ideaal Ideekay Idepredad0rI Ididit33 Idk Why PvM +Idle GE +Idle Melvor IdleWhale +Idlibi +Idna Supafly +Idol Namib Idont Idontlikejad +Idopk1 Iecysoda +Ienjoisk8ing +Iern +If I Succeed +Iffi Iffyz +Igge +Iggy Ontario Igloocold +Igmere Ignace Ignent +IgnisDraco22 +IgnobleSolid +Igor Krutoy +Igor Mang IgorBogdanof Igorr Igot99failin @@ -10332,87 +21469,261 @@ Ih8myRNG Ihan Ihana Ihme +Ihnigmakage IiIy +IidaEmilia +Iilqtforeva Iimel IisRaDiO Iisalmi Iivomon Ijoinedthis Ijusheadshot +Ijzer tekort +Ik Geef Bon +IkBenWeg Ikastovizski IkeJEI Ikhela Ikillu247 IkkeVincent Ikkle +Ikkle Hydra +Ikkle v Pain +IkkleHorvick +Il +Il MrBorn lI IlIBooieIlI IlIIIIlIIIlI +IlIIlIllIlII IlINard0IlI IlRisklIlIlI +Ileeze Ilija +Ill Ko You +Ill Effect Illbeyourcat +Illegal Char Illest Logic +IllestEver +Illinoisan +Illithid69 +Illlenium Illumee +Illuminatorr IlluminumRS +Illusionist +Illusivezz +Illustration +Illuzory Illwil +Illyrian +Illyrian TSX +Ilmer +Ilotalo Ilovethewar IlpOG Ilsaldur Iltasanomat Iluredyou +Ilusm +Iluvahrim +Iluvitar Eru IlyrianBlood +Im 85 Slayr +Im A Saint +Im Am Die +Im Ami +Im Anabolic +Im Annoyed +Im Artur +Im Ash +Im Asking +Im Aspergers +Im BackUp +Im Baguette +Im Barlow +Im Behemoth +Im Benough +Im Blastoise +Im Bo Licht +Im Brills +Im Burnz +Im CG +Im Chal Im Christian +Im Courage +Im Dino +Im Dr Afk +Im Easy Exp +Im Elyk +Im Excalibur +Im Fabulous +Im Fever +Im Finnish +Im From Jax +Im Gainz +Im Gippin +Im Gutfor +Im Hawkward +Im Hersh +Im Huck +Im Hunta +Im Hussain +Im Iron +Im Iron WTF +Im Jags +Im Jokers +Im Jovian +Im Just Ken +Im Krazy +Im Kyle Btw +Im Legacy XD +Im Los t +Im Luis +Im McGriddle +Im Missle +Im Moist 4 U +Im Moore +Im Mr Josh +Im Nate +Im Nathan x +Im Newschool +Im Nice +Im Not Okayy +Im Not lron +Im Nzmitch +Im Off Chops +Im On A Yak +Im On Point +Im Only +Im Orc Im Outt +Im Pogi +Im Qwerty +Im Ron BTW +Im Rus +Im Savage +Im Scoob +Im Secor +Im Shambles +Im Single AF +Im Smexy +Im Snake A +Im So Vayne +Im Songs +Im Spirit +Im Stig +Im Symb +Im Tainted +Im Tame +Im Temppay +Im Terrible5 +Im TheBeast Im Tibbz +Im Travis +Im Triz +Im Tyl3rr +Im Whey +Im Ya Papa +Im Your Babe +Im Your Dad +Im Yui +Im Zac +Im Ze 0wner +Im alex btw +Im just Cody +Im not FBI Im relapsing +Im tall af +Im wokeup +Im-Crowess +Im2good4u2nv Im45defence +Im4everlucky ImALilPigBoy ImASthhnake ImAdam ImAl0ne +ImAn Ironman +ImBaldFromRS +ImBobbyrayj +ImBoredOfRS ImCharky +ImChuckBass +ImClueless ImCravenTim ImDaPlugLLC ImDaved ImDaviie +ImDirtyyyDan +ImDoctaWhom +ImEmilyy +ImEric ImFinnish ImFlizz ImGodd +ImGodly ImHavingFun +ImHellaHigh ImHighASFSry +ImHisBae ImIncredible +ImInfested ImIntense +ImJames ImJebbe +ImJinxed +ImJordon ImJustLonely +ImJustRaging +ImKnotSimple ImLarge ImLeeuwarden ImLikeRlyBad +ImLukesGIM ImMAdBro +ImMajesticAf ImMaxy ImMilky ImNewbie +ImNoobK ImNooblit ImNotAfriend ImNotHumble +ImNotLost ImNotThien ImPaul +ImPaulAlt ImQuorra ImRyboy ImSane ImShreksDad ImSixteen +ImSnoop +ImSoGodlyy ImSoVulgar +ImStormmm ImTaegan ImTayla ImTinyRiick ImTipsy ImToFrosty +ImTooGucci +ImTwisted +ImVanilla +ImWargasm ImWilbur ImYourDadBTW ImZe ImZorp Im_Stone126 +Ima Guy +Ima Lil High +Ima Maleman +Ima lron man ImaCraftHor +ImaMainbtw Imack Imafore Images @@ -10420,17 +21731,33 @@ Imaginable Imagine Imakuni0 Imalooter +Iman103 +Imangry20 +Imanity +Imanubnoob +Imar Pussay Imasecretspy Imasin Imawizardm8 Imazamox Imblim +Imblim Area +Imbrochavel +Imbue +Imbued Haert +Imbuing Imbune ImeshuggahI Imgrazy +Imhellgracio Imidril +ImiteBurDADY +Imitus +Imm Mad Bro Imma ImmaSkill +Immaturity +Immediate W Immense Immer Immerseus @@ -10439,60 +21766,126 @@ Immortal Immortal91 ImmortalK12 ImmortanMike +Immxnse Immys +Imnotahuman +ImoChase +Imoinu +Imotay ImpactPewPew +Impale Her Impared Impeccable Impedance +Impede Imperdoavel +Imperfecto Imperfekt ImperialQc +Impietyy Impish +Impish Ace Impishhh +Imposter Jon Impriznd Improv +Improved +Impulsive Au Impurest678 +Imql +Imre Imsain Imsokwtie +Imstratss +ImtheAnimal +ImtheCARRYv2 Imthick Imtoob +Imuhbeast +Imuripieru Imus +ImxricK +In Game Life +In Menu Andy +In My Shadow +In Recovery +In Seconds +In2cept InCyson +InDaCouch666 InDespair +InFemous InGameLies +InTawlerable InThe90s +InTolu +InTransition +InXanee +InYaShower Inaaya +Inactive Acc +Inar +Inavi Jones Inbow Inbred Incapacitory +Incendia Vir +Inch95 +Incin3rat3 X +Inco-san +Incoherent +Incomes IncomingBeef IncomingGank IncredblDino +Incumbency Indain IndawrCrwdad Indcsn +Indecisive +IndecisiveO +Indemise +IndexNull Indian +Indian Chad IndianCat +IndianaJones Indicates Indicator IndieGarri Indigo640 +Indivi2you +Indoktrinera +IndominusAsh +Indoor Scape +IndoorsOnly Indoorsman Indrado Indrias1 +Indy Ju +Inecstatic Inedibles IneedPVM +Ineff icient Inefishient +IneptEwok +InfIuenced Infaam +InfallibleX2 InfamousAB InfamousEvil InfamousMain +Infantiel Infase Infectus +InferiorRNG InfernOwl Infernadev Infernal +InfernalChef +InfernalLuke InfernalPRO +Infernax Inferneo Inferno InfernoTism @@ -10501,18 +21894,23 @@ Infero Infesmati Infin1te Infinate +Infininth InfinitiGX InfinityMan Infirme Inflnite Influx Info +Info Kiosk Infobese Infor +Infora Treat Ingeb +Ingenious G Ingeniously Inglane Ingleburn +Inhaled Inhinyero InhumanBTW Inimene1020 @@ -10522,38 +21920,68 @@ Iniys Inkedsaint Inko Inksane95 +Inkwes Inner +Inner Brian +Inner Peace InnerBliss Innvision +Inori xdd +Inosuke xo Inqku Inri Insafi Insane +Insane Iron InsaneBobbie InsaneFruit InsaneIee InsanePerson +Insaneglutes +Insanewolfy Insaniack InsanityNix +Insanityx Insanityzz +Insatiate +Inse +Insectkoala InsertGold Insluiper +Insomnia Insomnist +Insomnity Inspection +Insta +Insta Spec +Instabox +Instagrem Instail Instinct Instro +Instruct Insucc +Insulter Insulting +Insulting MF +Insurgence Insurgent Int0mieli Integration +Intel6 +IntelManiac +Intellectual +Intendi IntenseRage Intensifyyy Intentional Intercept0r +Interchange +Intermk Internal +Internal Max Interracial +Interronator Intherial Intier Intimate @@ -10563,154 +21991,542 @@ IntoInfinite Intoner Intresant Intresenting +Ints Intubator Intuition Inubashiri +Inukal +Inuouk +Inur InvTagsBad Inva Invalar Invercargill +Inversives Invert +InvertedDuck Inveterate +Invierno Invisa +Invisa Scav +Invisa-Veng Invisioners Invokers Involk Invoryy +Inwu Inxo +Io Jah Pul +IoB Sylarke +Iock +Ion Benny Ion870 IonCannon Ionia Iono +Iou689 Iowa146 IowaCJ Ioyal +Ioyins IpeeInTheSea Ipod5412 +IpotYouDrop Ippe +Ipswich +Ipswich FC +Ir JWWillem +Ir Phys Ir0n +Ir0n Bot +Ir0n b00k Ir0nMammoth +Ir0nMish +Ir0nPuma Ir0nRagnarok IrDA Iralimir +Irha Irid Irie IrieLuDa Irinichina +Iris Elea Iris_1904 Irish Irithe +Irl Baller Irmak Irobar +Iroff SGDaht +Iroflman +Iroh Bison Iroha +Iroic +Irom Typo Iron +Iron 0lm +Iron 2DWaifu +Iron 2b +Iron 3 Hit +Iron ABC +Iron Achael +Iron Aeolian Iron Alabama +Iron Alee +Iron Aloha +Iron Aloodum +Iron Alpha +Iron Anaerob +Iron Anno +Iron Anonymo +Iron Antzz +Iron Areolas +Iron Arnoud +Iron Arzka +Iron Assface +Iron Ayen +Iron Azshara +Iron B O D Y +Iron B0yx +Iron BDN +Iron BLK +Iron Bart +Iron Baskan +Iron Bawlsak +Iron Bawsss Iron Beabs +Iron Beeto +Iron Besu +Iron Bezem +Iron Bibi2u +Iron Biddys +Iron Bloke +Iron Bogmac +Iron Book +Iron Boomz +Iron Booxia +Iron Borrrby +Iron Brevik Iron Brinnie +Iron BryconC +Iron Buchu +Iron Buckc +Iron Bucket +Iron Bumko +Iron Burrata +Iron Buuh +Iron Byld +Iron Caddy +Iron Calquat +Iron Carly +Iron Carmine +Iron Carna +Iron Cerv +Iron Cevol +Iron Chaw +Iron Chemic +Iron Chkn +Iron Cholby Iron Chombre +Iron Chrisss +Iron Coby +Iron Coin +Iron Coronao +Iron D Luffy +Iron D Natsu +Iron D Zeref +Iron DJG +Iron DSC +Iron DVS +Iron Daniel +Iron Deku +Iron Denal +Iron Deroq +Iron Destr0i +Iron Dipshit +Iron Dixi +Iron Domi +Iron Dumontx +Iron Dylnn +Iron E +Iron E s s +Iron E z +Iron Eagah Iron Elyon +Iron Equity +Iron Excal +Iron Exed +Iron FFrenzy +Iron Fe +Iron Ferro +Iron Filthy +Iron Fioxxu +Iron Fire 75 +Iron Floor +Iron Forgy Iron Franchi +Iron Frodo +Iron Fuhrers +Iron G Zeus Iron G0liath +Iron Gaan +Iron Gamerz +Iron Gayness Iron Ghosgar +Iron Ginto Iron Gios +Iron Go +Iron Godley +Iron Godly +Iron Golem +Iron Goth GF +Iron Greg +Iron Grind20 Iron Griss +Iron Haze +Iron Hoiy +Iron Holub +Iron Hookkan +Iron Hossi Iron Hroth Iron Hugge +Iron Husky +Iron Hydros +Iron Hyger +Iron IPvMI +Iron Insaneo +Iron Jakob +Iron Jal-Nib +Iron Jeref +Iron Jeroen +Iron JimmyJ +Iron Jizzman +Iron Jss +Iron K3 Iron Kalde +Iron Kaleef +Iron Kapkeik +Iron Karjala +Iron Katniss +Iron Kayn +Iron Keagan +Iron Kess +Iron Kiwii Iron Kngs +Iron Knipp +Iron Kodie +Iron Koopsy +Iron Kornie +Iron Krijn +Iron Krikke Iron Laplace +Iron Laxor +Iron Layfe +Iron Letski +Iron Liber +Iron Lose +Iron Lungsta Iron MTUT +Iron Mamma +Iron Mammal Iron Mapes +Iron Marie26 +Iron Marlon +Iron Martin +Iron Masori Iron Masuli +Iron Matt +Iron Matt NZ +Iron Matty W +Iron Matuba +Iron Maxvoid +Iron Mellem Iron Meydon +Iron Miguel +Iron Mikebor +Iron Milan +Iron Mimal +Iron Miro +Iron Moardus +Iron Mossyy +Iron Munted +Iron Mystip +Iron Nap Iron Nellz +Iron Nick +Iron Nimmi +Iron Nobody +Iron Noe +Iron Nuclide +Iron Nuuby +Iron O Brien +Iron Oak +Iron Oboi Iron Ohboy +Iron Ohgodno +Iron Ohzone +Iron Opto +Iron Ores +Iron Pandis +Iron Parkour +Iron Patches Iron Peg +Iron Pge +Iron Phe +Iron Plague +Iron Pothead +Iron Praxis +Iron Pwn +Iron Pwnstar +Iron RNGsus +Iron Rakey +Iron Randall +Iron Randyy +Iron Reedzy +Iron Rekkr Iron Request Iron Rikyu +Iron Rind +Iron Roach +Iron Robsham +Iron Roof +Iron Rushy +Iron Rybread +Iron Ryuuga +Iron S t i g +Iron SSJ +Iron Sagga +Iron Samiria +Iron Santus Iron Scolew +Iron Scran Iron Seagz +Iron Seha +Iron Shaikh +Iron Shavers +Iron Sheik +Iron Shnapi +Iron Siem +Iron Sioux +Iron Skoptsy +Iron Skroten +Iron Skydive +Iron Slash +Iron Slaya83 +Iron Sloth 2 +Iron Smoke94 +Iron Snypah +Iron Sparco +Iron Splat +Iron Stannrs Iron SteveB +Iron Stomp +Iron Stronq +Iron Stw +Iron Sullo +Iron Susu +Iron Svampe +Iron Swaffle +Iron Swag +Iron Takumi +Iron Tango +Iron Tanzim +Iron Tbar +Iron Terboo +Iron Teun +Iron Thi3ves +Iron Tiffers +Iron Tigr +Iron Tigran Iron Tinman +Iron TomT0m +Iron Tonkin Iron Tonski +Iron Tonymaa +Iron Torfi +Iron Toxxic +Iron Trashua +Iron Trixx +Iron Tudder Iron Tutnin +Iron Tweeker +Iron Tyrans +Iron Tyrant +Iron UIM Iron Uakti +Iron Unam +Iron Varuna +Iron Vatti +Iron Venema Iron Vexzed +Iron VickD Iron W1nk +Iron Weather +Iron Wespula +Iron Wii +Iron WindJr +Iron Woofy +Iron Wu5 +Iron XIIIV +Iron Xellana +Iron Xire +Iron YEE +Iron Yangus +Iron Z4ppie +Iron Zephyx +Iron Zeraph +Iron Zerg Iron Zilong +Iron Zinoto +Iron Zoha +Iron Zol +Iron Zrysen Iron Zul Mox +Iron anrowi +Iron d0gz +Iron da ddy +Iron dols +Iron dry +Iron feens +Iron flynn +Iron instead +Iron kitcat Iron l2asta +Iron ona Mac +Iron pappal +Iron werty +Iron whiff +Iron wiper +Iron x wolf Iron xyN +Iron-Ximena Iron10203 Iron2Pickaxe +Iron619 IronAgentP IronAjandre1 +IronAkleiss IronAlblad IronAlufolie IronAngst IronAnnaMay IronApples +IronAsbe +IronAssHole IronAussieM8 +IronAxe +IronBadAtPvm IronBankFull IronBeanz +IronBeerad IronBiGuyBtw +IronBistchul IronBobbyjoe +IronBoink IronBosse IronBound IronBrad +IronBrand21 IronBrick +IronBruBrah IronBuriedNU IronBurnsRed +IronC1aws +IronCagedRat +IronCemile +IronChillii IronChirpOTK +IronChompers IronChrisKin IronClarkey IronCoX IronComedy IronCooter IronCozza +IronCraiger +IronDab 710 IronDakotas +IronDandaman IronDavid IronDeadBoy +IronDefiant +IronDeredas +IronDethaele +IronDodo420 IronDog777 IronDong +IronDravekD +IronDringus +IronDtrex +IronDubble IronDubzy IronDudde +IronDunceCap +IronDurrrrr IronEagles IronEkakerta +IronEso +IronEtch IronFefe +IronFigment IronForFunnn IronForged99 +IronForyn +IronFrenzey IronFrogMan IronFungi IronGalihand +IronGatr44 +IronGear CEO IronGez IronGodsword +IronGoliathX IronGoneNorm IronGow +IronGuh IronHammy +IronHasta IronHomer IronIDKFA +IronInsano +IronIogibear IronIsNoJoke IronJValor IronJakeT +IronJames IronJamesG IronJarod +IronJeffZ +IronJenga +IronJezz IronJoint +IronJosehiha +IronJosephxo IronJuji IronKaboom IronKaiser IronKapp +IronKayodee +IronKest +IronKingdoms IronKukk IronKyloman +IronLadBtw IronLadel IronLaffin IronLankzey +IronLazure IronLegend +IronLegocy IronLepaus IronLifting +IronLionMAIN IronLucas IronLuckPlz IronMadePure +IronMagick +IronMainOx IronMan IronManBow IronManJar @@ -10718,17 +22534,26 @@ IronManSux IronMango IronMarius IronMarty +IronMason +IronMathwin IronMatty +IronMayne IronMetknot +IronMikado IronMinion +IronMitchKun +IronMollusk IronMountain IronMugz +IronMushy IronNWord IronNachos +IronNantt1 IronNateDogg IronNazguls IronNexuss IronNeya +IronNibletz IronNihilm IronNinja13 IronNord @@ -10737,11 +22562,19 @@ IronOdum IronOldBoy IronOnPatch IronOrca +IronOreAgate IronOsiriss IronOxideMan +IronOxidizer +IronPangtar +IronParis +IronPeteMan IronPills IronPrice +IronPrickles +IronProf IronPumitaz +IronQben IronQli IronQueen IronRait @@ -10754,83 +22587,168 @@ IronSantaMan IronSchmieds IronShadow5 IronSikruz +IronSkaro IronSly IronSmurfff +IronSparrow IronSpiderZ +IronSpitfire IronSplats IronSpoNeD IronSpoony IronSpray IronSquidly +IronSteve-O +IronStronky +IronSurf +IronSylar +IronSystolic +IronTarnum +IronTasseron IronTau +IronTedBundi +IronTeste +IronTestedRB +IronTimTim IronToff +IronTulio +IronTyson IronUnkilled IronVegtable +IronVib3s IronVikinng IronVikzo +IronVinda +IronViolette IronW3LEGEND IronWafflee IronWallnut +IronWantsRNG IronWayneker +IronWidovv IronWush +IronYoerik +IronYugo IronZettrox IronZong +Iron_ProDabs Iron_Slippy Iron_Sukulo +Ironarcanic +Ironatica +Ironator Ironblood7 Ironboba9993 +Ironbobsaget Ironborn +Ironborn PVM Ironbutcher +Ironclad Sac Ironed +IronedSwift +IronendJr Ironeyy Ironflox Ironfur +Irongrazvis +Irongusty +Ironiam Vir Ironic +Ironic Force +Ironic Kill +Ironic Name IronicBenson IronicSwag93 +IronicViking Ironicer +Ironiical +Ironija +Ironik 20 IroningB0red IroningSucks +IronishSana Ironkaka Ironmacman +Ironmale Ironman +Ironman Daff +Ironman Jase Ironman Jowe +Ironman Wit Ironman idk IronmanFookz +IronmanHutch Ironmanerno Ironmeme +Ironmeme Cx +Ironmeme Lol +Ironmies Ironmimmi +Ironmorriz23 Ironn +Ironn Yoshii +Ironnesses Ironpasta1 +Ironqa Ironred33 +Ironriwer +Irons suck +Ironshore Ironsoul2 Ironstone +Irontownhero +Ironwind747 Ironwinter Ironwork4eva IronxElite Irony +Irony Nib Ironylion +Ironyx +Ironzi Ironzilla +Irrelevant Irrumated +Iru +Irulon +Irxn Irxnized +Is E_wen +Is Idle +Is Slikker +Is a bich +Is this you IsAlexOk +IsButters +IsChazCool +IsDomIsGood +IsYaBoyDoive Isaac +Isaki Magari Isbjorn Isganytojas +Ishigo1992 +IshmaelDonny +Ishrandom Ishzn +IsidoroM Iskemia Iskolar Iskon Iskra Islaal +Islami Islefalls Isleview +IsmackfaceI Ismelitooo Ismo54 IsoG +IsoKitty IsoP Isoga Isoleucine +Isootoonik Isoptox Isosami IsraVM @@ -10838,51 +22756,141 @@ Israels IssaEly IssaStiffler Issard +Ist M Istanbulite +Istasher Istaxit +Isvig +It Slaps +It is Rex +ItBeJacK ItBurns ItIsWedsDude +ItPol ItWasntMe007 Itaky Ital Italian +Italian roxx ItalianAJ +Itaochi +Itchweedy +Itcoto +Iteyx Ithero Ithlinee +Itik +Itinkinou +Its Absol +Its Almog +Its Arj +Its B0B +Its Brother +Its Canadian +Its Conrad +Its Da J00z +Its Dally +Its Dyl +Its Hash +Its Jon btw +Its Jst Skin +Its Kaylee +Its Libo Its Me Dave +Its Me Q +Its Me Suns +Its Misha +Its Nipo +Its Peter +Its Rigged +Its Sebas +Its Sense +Its Seth +Its Smooth +Its Teddy +Its Wolfie +Its Yama +Its Zammy +Its a Shame +Its claw +Its me Josh +Its me eden +Its rob +ItsAboutTime +ItsAirdog ItsAllOgreM8 ItsAnobrain +ItsBarcus ItsBigNasty ItsBlitzyy +ItsBrtnyBch +ItsBru ItsClout ItsDende +ItsDynasty ItsFinn ItsFlooo +ItsHoggle ItsHosef +ItsInThePast +ItsKenshi +ItsLitttFam +ItsMarc ItsMeBlaze ItsMeDog ItsMev +ItsMrSir2u ItsNiels ItsOleGreg ItsOwenM8 +ItsRainor +ItsSirTech +ItsSkells +ItsSyn1k +ItsTaylen ItsTerpsWrld +ItsUnruly +ItsWeinstein ItsWicked Its_A45c Its_Fonte +ItsaTommyGun +Itse rauta +Itsemurha Itsmeborrid +ItsoktoGIM Itsssjustice +Itsy Bitsy Itupakointi +Itx +ItxJustin +Itz Haydn1 +Itz Hickton +Itz Kodiak +Itz Nate +Itz Scrubz +ItzAtlass ItzElise +ItzJroc +ItzKat ItzLogikal ItzMrNick +Itzla Itzvenom +Itzzz B +Iuc Iuckk Iulz +Iussy Iustrous Iuxio IvIegaDan +IvIr Wize Ivain Ivaink +Ivalice XIV +Ivan Knjklj +IvanEOD IvanMullet Ivanckonia Ivanka @@ -10890,167 +22898,448 @@ Ivansaccount IvelJet Iveljetorox Ivoos +Ivory Tower Ivryk +Iwanbro IxHunt3rxI +IxVenom Ixala IxonnoxI +Ixyc +Iz0p +Izaa +Izac +Izanani Izbec +Izhmash +Izi Claps Izone_Kev Izuria Izvorul Izzy +IzzyBigBoy Izzyboy300 +J 0 S H Y +J 0 S H l +J 4 6 +J 4 K E +J 6 +J A B S +J A I D A N +J A M A L +J A N K I +J A U N U S +J A W D +J Breezi +J C Trousers +J D +J D Ballew +J Dahmer +J E E V E 5 +J E T +J F +J Fred Run +J I M M +J I MM Y +J Kole +J Kribzz +J L A +J MF B +J Neat +J O E G +J O L T I K +J O T A +J O3Y +J R O C +J R V +J Rat Cow J S 2 M +J S Z M +J Saints +J Suave +J U S T A S +J U Z +J a c k a l +J a c k son +J a c k y +J a mie +J a n i +J ackal +J al +J ameper +J anii +J appie +J asnah +J ason +J asyra +J ayson +J bellfortt +J bird shady +J e sse +J eff +J effy +J ensen +J esse +J essica +J imme +J imy +J imz +J ipr +J lMM Y +J o b e +J o e +J o ey +J o f +J o s h y +J oep +J ohannes +J ointz +J oke R +J or G +J oshh +J oshhh +J osie +J u wu +J ung +J unko +J utch +J uun +J uwu +J x B +J yy +J-2tha-R-O-C +J-Man 93 +J-Turn +J-Yeezy J001_jf1 +J0DYY +J0E +J0E REAL +J0EEY +J0NE J0UF +J0YBOY LUFFY J0YRYDE J0dz J0hnnyQ J0ng J0ngeBV J0ppy +J0rdanDv J0rdo117 J0se +J0se Dtown +J0se Dtuwnn J0seph +J0shh +J1MB0H +J1NBE J1ub J2TR J2caine45 J2ck +J328 +J3Ciron +J3JU J3S5E J3rkkuHD J41AL J45e0wns J4QS +J4S J4gga J4my +J95 +JAABASNABBA JACK3DJOHNNY +JACKYOUNG93 +JAG0705 +JAI MA KALI +JAMA Open +JAUH0JENGI +JAVON 9-INCH JAYJ51 +JAYR0CKBABY JAlDYN +JB 2K +JB87 JBGard JBrody JBuck057 JBux +JC-1989 +JCS07 JCole JCon JCutler +JD MD +JD4 JDBass JDEP JDFlaSh JDJM JDez JDlion +JDredd66 +JDuck +JE B +JEEZE JENNY +JENNY DEATH +JERN SVIN TO JETSNBEERS +JF Kennedy +JFB +JFCK +JFK gone AFK JFKautopilot +JFL JField +JFrog JFryGuy +JGIRONTG JGIV JGlen97 JH3305 +JH91xx +JHINitalia +JIGGYWIGGY JIIVEE94 +JJ-M JJ23 +JJAAKKO +JJBW +JJPowers JJROCKETS JJRicky +JJS BBQ +JJSM_Dulker JJchris66 +JJoe +JJumalwelho +JK Rowling JKMi JKTimbo +JKUR ON 40S +JKeM JKingJ777 JKrollin JKuyaa +JLG JLowe +JLsone +JMI NG +JMTaipei JMack JMiddd +JOBBO JOCKO00O0O0O +JOE EROTIC +JOKER 709 +JON3ZYY94 +JORlCK +JORlS +JP Kotsnek +JP17 +JPB at Large +JPI +JPS Daytona JPant1ess JPantless +JPatness JPence JPountney +JPudz JR05E +JR0D +JRBeast +JRC Crypto +JROGU JRxs +JS Xpress +JSL34 JSLatvala +JSPACER +JS_Terminal JSco +JShep23 +JSilvester08 +JSlice94 JSplash JStepho +JT5 +JTAG +JTCS +JTI ain JTIAIC JTM33 JTscape JUGIB +JUIBE +JUICEWRLD9 9 +JULlAN JUST +JUST A HlPPO +JUST Nikk JUSTICE JWRLD +JXJ +JZB JZX1O0 +Ja k ey +Ja m e s +Ja mes A +Ja se +Ja sn JaBouris JaDig JaStraater +Ja_Fireking +Jaaaakkoooo Jaac JaackGP +Jaager Jack +Jaagmu +Jaahee Jaakako Jaalva Jaamm Jaant0 +Jaapievecht +Jaay G JaayC JabHook +JabbaU JabbasHut +Jabbaw0cky +Jaber +Jabesol +Jabiborinoni +JablezGIM +Jablooze +Jabo b Jabopanda Jabroni Jabroniii +Jabrs +Jabuz +Jac o b Jacckk +Jace C +Jacerhapsody Jacey Jacinto Jack +Jack Dyer +Jack Htoo +Jack Hughes +Jack Mac +Jack Maz +Jack Par-O Jack Reipan Jack1 +Jack12Broke +JackBadasson +JackBass4 +JackBlade +JackDanielsH +JackHammr +JackKnight +JackKvorkian JackMayte JackOscar JackRod +Jack_Herer9 Jacka JackandCoke Jackass +Jackass Sean +Jackazzz1 +Jackblaze +Jackbtw Jacke +Jacked Jackie +Jackingten Jackisbanana JacknHookers +Jacko Bei JackoPogU Jackoo Jackos Jackoz Jacks +Jacks0n Jackson +Jackspyrow Jackyboiii Jacob +JacobGhosty +JacobIsTaken +JacobT789 +Jacobb Jacobieus Jacobro Jacobs +Jacobwins1 Jacupy Jacy59 +Jad slides JadMaister Jada Jadakiss Jadavius Jaddok +Jaddy Chill Jade +JadedRapture Jadeine +JadenM Jads +JadsVag Jaecob JaegerBoom +Jaeson Jafacakeman Jafanto +JafarTooHigh +Jaffa Jake Jaffar +Jaffywaffy +Jafsx Jagdpanther JagerBombski +JagerIron Jagermeister Jagged +Jaggen +Jaghatai K +Jagoodiii +Jah toch JahIthBer Jahaerhys +Jahaok +Jaharred Jahbby JahgexPlzzz +Jahmay Jahmerica +Jahngles +JaiSiaRamJai Jaiden184 Jailbreak455 +Jaime 427 Jaimeebear +Jak Maximus JakMetalHead Jaka On Can Jake +Jake C +Jake D Snake +Jake Muzzin +Jake OC +Jake Scapes +Jake Solo JakeState68 JakeSteFarm Jakedajackal @@ -11062,64 +23351,127 @@ JakesSolo Jakesonville JaketheSnake Jakey +Jakey C Jakeyosaurus +Jakeyz +Jaknop Jakrem Jakrojan +Jakuli226 +Jal-Nib-Jmal JalNib Jalduii +Jaleesa +Jales +Jalim Rabei Jalite Jaljif Jalla Jalo Jaloenow +Jalordom Jalou +Jalzas +Jam Flex +JamBandDad +Jamaikietis JamalBobaman +Jamango +Jamania64 +Jamar +Jamaul Jr Jambaica Jamblaster +Jambreak +Jamburano +Jamchu Jameo James +James 6000x +James Comey +James Kakadu +James Kelp +James Poncho +James PvE +James Rolfe +James c +James osrs +James1087 James2709 James9 +James945848 +James9520 JamesBondss JamesCUFC JamesDaWizar JamesHaliday JamesJ2019 JamesLango +JamesMaynard +JamesNI JamesPratt94 JamesShotGG +James_22 Jamesay Jamesbombom Jamesrb1 Jamess Jamesy JamiBear +Jamiboy Jamie +Jamie Tacos +Jamie W +JamieJams JamieOliver JamieXV +Jamilan +Jaminnnn Jamixa +Jamjac Jamlicking Jammie +Jammmy +Jammoose +Jammy Dogger +Jammy Scone Jamn Jamosbondos Jamppa Jampy +Jampyre Jamuli +Jamurazi +Jamwa Jamyroo531 Jamzylockz Jamzz +Jan +Jan Griffith +Jan en Karel +Jan100000 JanHenkD JanVanLeiden +JanXtian +Jananas3 Janar +Jancentp Jandaer +Jandhob Jandie5 Jane Janer Janes +Janes Bond +Jango Style2 +Jango fet310 +Jangsta23 Janice Janikowski +Janissary90 Jank Jankk +Jankko Janksky JannaMain73 Jannanas @@ -11130,81 +23482,171 @@ Jansky Jansz101 Jante Jantex +JantheBear Jaooa Japanese +Japhur Japiohh +Japles1 Japoolie Jappieee +Jappieness Jappo +Jaqen +Jaqquu +Jar Of Pets +Jar Uh Dirt +Jar of Pukes +Jar of Swamp +Jar ofc um Jar3y JarOfCookies +JarOfH0les JarOfSmORC Jarab +Jare d JareZki Jared1234 Jareds134 JarlCantBank JarlEarlKing +JarlVaarg Jarnemelk +Jarnie Dimon +JarnoMirma Jarnte Jarra +Jarre Jarredn +Jarreelll Jarskie Jarsse Jaru Jarvis Jarx +Jas Melody Jasberg +Jaseel Jasey +Jasey Rae +Jashin Jasinador +Jaskanpaska Jason +Jason In Max +Jason73 JasonJ +JasonLRG +JasonRises +JasonSkillz +JasonT20015 +JasonVorheez +Jasonn +Jasonnn Jasperw90 Jaspi +Jasthew +JasuzChrist Jasyre +Jauneri Jaunius +Jav Jave +Javert +Javier Pwns +Javve Javvymuis +Jaw +Jawaloso +Jawgasm +Jawmac +Jawniz Jawntista +Jawor Jaws +Jaws 2 75 +Jawshy +Jax Evasion +Jax Teller +JaximusIV +Jaxy22 +Jay Ayy Why +Jay Baby +Jay Exotic +Jay Hughes +Jay M +Jay RZ +Jay Show +Jay Sparks69 +Jay United +Jay b1zzle +Jay kell Jay024 +Jay357 JayDaddy313 JayEngineer JayFlow +JayJee +JayKay Okay JayLunar JayManzarek JayMaster +JayMe x JayMuthaFknC JayPortal JayRu7 JayTheBurnt +JayTheRunner +Jaybiz Jayden Jayders +Jaydey Jaydia +Jaydo x +Jaydonn Jaydos +Jayeden Jayhawk225 +Jayhawkers Jayi JayjayNeo01 Jayksie Jayman +Jaymeh Lee +Jaymo123 Jaymyson +JaysATank +Jayshuunn +Jayspoks +Jayster Jaytea Jayteaf Jaytee1262 Jaywub Jayy +Jayy Slays +Jayy x Jayzar +Jaz Coleman Jazo Jazpurs Jazz JazzFlap JazzMaster09 +Jazzeh Jazzjr89 +Jazzly Jazzy JazzyFlips +Jb Godranger +Jba123 +Jbevzzz Jblieves88 +Jbob72 +Jbt Jbvff Jc_TheCops +Jcb4646 Jcdelavici Jchn Jcmalone23 @@ -11213,223 +23655,454 @@ Jcourt1 Jdaws Jdidy Jdoggy2018 +Jdp3 +Je nny +Je pppe +JeBoyHiddema +JeIlo +JeIly Man JeJoat +JeK0 Jean +Jean belette +Jean man Jeangaboudle +Jeankeh Jeari +Jeavoni +Jebaited825 Jebiii Jebrim Jebroid Jebroni +Jecht Shot Jecob +JedMosley Jedah JedaiKnight Jedi +Jedi Drue Jeebiez Jeebz +Jeefro +Jeek Jeemis Jeep Jeesuhs Jeet Jeeve Jeez +Jeez Christ +Jef fy JefFamous Jeff +Jeff Aero +Jeff C +Jeff pls go +Jeff says +Jeff the Cat +JeffEHPstein +JeffG JeffMusk JeffWiki Jeffermus +Jeffica Jeffie381 Jeffmyster5 Jeffre +Jeffrey Z JeffreyFNV +Jeffreypoe Jeffro Jeffy +Jeffy xD JeffyTheDahm +Jeffzuaos +JefriEpstin Jefry +Jeft Jefy Jeggesen +Jeguelson Jehdin +Jehobo Jehtty +Jeikeorb Jeimi JeisBtw Jejex +Jekd Jekquesting +Jelbishi Jelbringer +Jelen +Jelenner Jelior Jella Jelle +Jelle Bouma Jellie40 Jellisme_99 +Jellitots +Jellough Jelluh Jelly +Jelly Bears +Jelly Booty +Jelly Dub +Jelly Sucks JellyBeanRs JellyGenix +Jellydonuts Jellyfishes +Jelziin +Jelzini +Jemades Jemelope +Jemile +Jen na Jen0va JenaTulwarts Jenessa +JenfoxxSub +Jenicek Jeniuss +Jenkiins Jenla +Jenna Taylia +JennaHeather Jennacydal JenniTolls +Jennie Jennn Jenny JennyElina +Jensen641 JensenRS Jenskee +Jenten +Jeometri Jepp89 +Jeppe Jeppeonkurre Jeppie +Jepppe Jepppu Jepuzeka Jepz +JerBearGrizz +JerBearOmfg Jerak Jerayou +Jerbelle +Jerbil Jerec Jereh24 Jeremiahlewi Jeremy +Jeremy 2007 +Jeremy Ray +Jergs Jeri +Jerm +Jermothy +Jerms Pro +Jern Jan Jern Tarzan Jerne Jernladden +Jernlund Jernpung +Jero +Jeroen 31 Jerom21 +Jerrbear69 Jerre26 Jerrin +Jerrwie Jerry +Jerry Alan +Jerry Maine JerryChinger JerryMina +Jerryy Jers +Jers Knot Jersh +Jershawerr Jersion +Jertz Jeru +Jerunox Jerusalenm Jerziii Jerzy +Jes2x +Jeseeka +Jesh g +Jesh-mar JeshusChrist +Jesiah Jesk +Jesliq +Jesper Bratt +Jesper135 +Jesperyo Jess Jesse +Jesse Top Jesseq Jessica Jessie +Jessie Jones Jesspresso Jessy +JessyTrip +JessycaOSRS +Jester Head +Jesterbubba Jesus +Jesus I love +Jesus MPhys +Jesus Saved JesusComing JesusRedeems +Jet Jaguar8D Jet3010 JetFlame Jeththe +Jetlag Jetma Jetridder11 +Jetski Jetsmoke +Jettiesimp Jettrider +Jeugd Jev21 Jevel +JewFroBro Jewbaaca Jewbakah Jewbang +JewishRob Jewy +Jexlad Jexlo Jeyos +Jeyzuz Jezeus Jezkoz Jezuux JezzaripHD Jezzie +Jezzx +Jf-n03 Jfleeze +Jfrith +Jfuzzy Jglove +Jgus88 Jgy1889 +Jhackal +Jhb Jhebs Jhny +Jhonlovin +Jhoocy +Jhoocy Moot JhormanCovid JhosS +Jhow +Ji bs +Ji m m +Jia Lissa Jian +Jiara Jibajaba Jibberflexed +Jibbllyy +JibinSui +Jibneh JibrilMaster +Jiffee +Jig Bugs +Jiga Chad +Jiggalagg JiggerJoe +Jiggity Jigglyboy Jigglywoo +Jiggypufff +Jignite +Jigoogly +Jih +Jihe +Jihne +JiiU +Jiiko +Jiim Lahey +Jiiraiiya JikdarShark Jikkurr Jiklim +Jill Hyde +Jille Man +Jim +Jim Sauce +Jim Shorts Jim0k +Jim2k1 Jim38iron JimAdler JimTheGing Jimb0bMaster +JimballSlice +Jimbeamtndew Jimbi Jimbly +Jimbo Sween JimboJamzAF JimboQuan +JimboSlice21 Jimbob3005 Jimbogun Jimboi +Jimbub JimcakeKong +Jimdawgy Jimi Jiminuatron +Jiminy49 +Jimm JimmahDean Jimmerik Jimmi +Jimmi Lipper +Jimmmm Jimmy +Jimmy Jumper +Jimmy Plays +Jimmy Scimmy +Jimmy Wooo +Jimmy1408 +Jimmy3rdBase +JimmyBullard JimmyBuns +JimmyCarter +JimmyGrimble +JimmyStubble JimmyValmer7 +Jimmybe +Jimmygk +Jimmylovecox +Jimmynyge Jimmyo Jimosine Jimpertje Jimpiix +Jims Goon +Jims Ironing Jimsterjim +Jimver Jin Oh +Jin R n G JinDoritos +JinJ0 nJuice +Jinb +JingleBiloba +Jingy Jinimy +Jinjaman Jinkers Jinko +Jinkys +JinnyChatBot +Jinpa +Jinsinny Jinte +Jinxed Jake +Jinzo Doku +Jinzo Jinzo JioGetsMoney Jion +Jions Alt +Jipser +Jipske Jiqonix +Jiqura +Jiraiya +Jiraiyeah +Jirakh Jiren Jirka Jirou Kyouka +Jisska Jitaxia Jithra +JiveChompy Jixoxx Jixr +Jixx0x +Jiyool +Jizt +Jj Dynomite +Jj Jerk2 Jjar127 Jjjjjj210 Jjozzie +Jk Esq Jkdogg Jkhby +Jkl Kalja Jkolrur +Jkrexx Jku45 +Jl-SOO +JlGA JlLLY JlMMB0 JlZZB0SS Jlarge Jlova Jmagelssen +Jman021 Jmar Jmaster402 Jmbryn Jmca +Jmca Savage Jmen Jmies Jmjake Jmonelite Jmudford44 +Jmz Jnas +JnrSeneca +Jnsthenx +Jnup Jnwp +Jo Pain +Jo de Coeckh +Jo h 2 +Jo iron +Jo rd an +Jo shua +Jo we Jo0l +Jo3 H Jo3p Jo5p +Jo6p Jo711 +JoE ShMoee JoEiSaFiShEr +JoJi JoJo +JoJo Skriver JoJo79 +JoJoJoUrBoat JoKerRtheGOD JoMoe JoRouss @@ -11437,84 +24110,168 @@ JoWie JoXuh Joacco Joao +Joao EV +Joao Paulo Jobac Jobann Jobard93 Jobber +Jobbes Jobbits +JobbySkelper +Jobbydrinker Jobbyqq Jobless Jockward Jocqui Jodenzaad +JodioJoestar Jodon +Joe 7 +Joe Kronic +Joe Lol +Joe Mangina +Joe Mclaren +Joe Muggs +Joe Potato +Joe Schwa +Joe TheBeard Joe56543 Joe56780 +JoeBidens Bf +JoeEldenring JoeFoe JoeGas +JoeInglesGod +JoeJunk +JoeMothers +JoeStudd JoeTheGod JoeWoody +Joebie Joebobinator Joecuster +Joedaschmoe +Joee P +Joeholding +Joekle Joel +Joel 9444 +Joel In Pain +Joel Lobster JoelBtw +Joelemz Joell +Joenage +Joenly Joered40 +Joeri Joes Joeshmo Joestar Joey +Joey Diaz +Joey Mobile +Joey RS +Joey069 JoeyDabs +JoeyGatto +JoeyP +JoeySlays +Joey_1993 +Joeyboy +JoeyboySucks +Joeychh Joeydarebel Joeyer5 Joeyfernando Joeyjoe600 +Jofa Joferr Joffa +JoffreyLupul Joggaplanten Johan +Johan Cruyff Johanbtw +JohannesN JohannesRRL Joherk John +John Bilos +John C +John Cena +John China +John D4rk +John Ironman +John Mayer +John McCain +John Mugwump John Muir +John Paul +John Penn +John Sal JohnChaptr15 JohnDaBoss JohnGilespie JohnNoyes +JohnRambo43 JohnWLennon JohnWick39 +John_Wick007 +Johnathan Johnbovi JohndemenBTW Johnletics +Johnmcdodger Johnny +Johnny Chinn +Johnny Dinh +Johnny Lyu JohnnyBeanz JohnnyChimpo JohnnyHart +JohnnyLoco JohnnyMellow +JohnnyQuest JohnnySXC Johnnypants +Johnnys +Johno381982 JohnoMate Johns +Johns bad ma +Johnsons +Johnsters4 Johny +Johny Aus JohnyLocoo Johnyy Johuab Johzyn Joizz Jojis +Jojj Jojkan +Jojo Rabbit Jojora Jojy +Jok Jokar Joke +Joke xD +Jokelanopein Joker JokerzDice Jokinq +Jokkepappa JokuHeppu +JokuVaan Jokurul Jole JolliJolli +Jollyfarms +Jolonerz Jolteon Jolting Joltism @@ -11523,100 +24280,198 @@ Jombsy Jomer Jommann Jomoba +Jomppaa Jomppei +Jon +Jon Eusebius +Jon Meades +Jon Snow +Jon ny +Jon10 JonHDgamer +JonMarston JonOn JonVV +Jonadwyn +Jonahams808 Jonahcart Jonanism Jonas Jonas9115 +JonasLietuva +Jonas_Butte Jonasbroh +Jonassau +Jonatan Jo +JonathanRoid +Jonaz +Jonbaron Jonboy +Joncc Jondog JoneNikula +JoneZii +Jonesing Jonessy +JonesyBadger +Jonetsa Jonezey3 Jongo Joni +Jonibo +Jonie D JonisBaisus JonisSniegas Jonjo12knees Jonko +Jonko lover Jonn +Jonnay +Jonne r Jonnems Jonnisan Jonnisjoen +Jonno1789 Jonny +JonnyBiggles JonnyBoii +JonnyL2020 +JonnyLots +JonnyM Jonnybak Jonnybowler8 Jonnysniper Jonsamma +Jonsed +Jontzzz Jonxsy Jony Jonzza +Joo Potato +JooOvenPizza Jooe +JoojoThePk8r JoonSoo Joonas Joonayoyo Jooni Joontah +Jooogijuuu +Jooohnny +Joop Mgoon Joopaul Joose3 +Jooshica +Joosst +Joostvd17 +Jooxan Jophatmama Joptvajiumat +Jor dinh +Jor dy +JorVa Osj Jord +Jord 0_o +Jord Croft +Jord idk +Jord xD +Jord y +Jord z JordHarris +Jord_96 +Jordan 1 +Jordan 7218 +Jordan KY Jordan030592 +Jordan07 Jordan1063 Jordaneee +Jordanite +Jordans Jordany5b Jordavitch Jorden JordenFCB +Jordinee Jordnn +Jordo Am JordyM JordyMcSheep +Jordynn +Jordysteen Jordz_King +Jore Jorenator +Jorgeme +Jorgos +Joricki +JorkinMyWorm Jorkkelis Jorlund +Jornaleiro JoroEdde Jorsne Jorster Jorttis Jorzki +Jos Bezos +Jos de Mutn Josavi JoseLargeD +JosefStaIin +Joseluis1 +Joselyn Leo Josen Joseph +Joseph Sam2 Josh +Josh 2277 +Josh Jones Josh Tsutola +Josh x +Josh013 Josh2Godly JoshD +JoshDagainz JoshGymnast JoshMarksman +JoshYewAhh +Joshalog +Joshan Joshery Joshh +Joshhhh Joshii Joshimitzu Joshism +Joshjoshin Joshmaster31 +Joshpaul Joshua Joshuaaaah JoshyCii +Josiah Higha Josiahs Josoust +Joss +Josse +Jostavo +Josti O_o Jostle Josue Josukes Josylvio +Jota_420 Jote +Jothha Jotjemenotje +Jotq +Jottini Jotunheimar +Jotwe Joueur4376 Joulaha +Jovial Jovilius JovyGaming Jowah @@ -11624,43 +24479,86 @@ Jowalll JowatBTW Jowel Jowitt +JoyOfSatan Joycey1997 +Joynzz +Joystick +Joyun II Joz6 +Jozi Blue Jozu +Jpan1 +Jpellican +Jpq +Jqwss Jr Metro +Jr Muffin +Jr Stigel Jr2k13 Jrabbat Jrby +Jrdn Jreppks +Jrey Jroanirr Jrodjok Jrogo +JsJays JsN4 Jsag +Jsi7111 Jsnn Jsony +Jspot +Jsq Jstnn +Jstrife9 +Jthrust Jtownironman +Ju mala +JuGgLe BuG +JuJuzzz +Juan Dangle +JuanTalon +Juandissimo +Juaneria +Juanreliable Jubaah +Jubarte JubbaTheHut Jubilations Jubita Jublian +Jubster +Jubtus Jubu +Jubz Judah +Judas wept Judddy Jude +Judge +JudgeDredd +Judgewalker Judie Judies Judlmin JudoChop +Juduel +Judus Judybats +Juedons Juezz90 Juffo +Jug001 +JugMilk +Juga JR Jugalator +Juganog Jugernought Juggalo09R Juggerthot +Jugimaster JuhQ Juheniqus Juhhu @@ -11672,22 +24570,52 @@ Juhve94 JuiBoi Juib Juice +Juice W RL D +Juice WRLD +JuiceRock JuiceUSA +Juiceb0x44 +Juiceful +Juicewayne +Juicieee +Juicing Juicy +Juicy BIG +Juicy Jorma +Juicy Lil D +Juicy Pair +Juicy XPs +JuicyBigNut +JuicyJesusFE +JuicyJocelyn +JuicyJones +JuicyLap JuicyTear +JuicyTigr +JuicyWetNut +Juicy_Newfie JuiicyAF Juikki Juint +Juipp_Iron Juisy +Juk e +JukeLess Jukebot Juked +JukeduM Juko Juktes +Jul es Jules +Julesbak Julia JuliaFlorida JulieFromHR +Julieekins Julien +Julio Cesar +JuliusHotdog Julley Julma JulmaJoe @@ -11695,42 +24623,93 @@ Julmarsson Julpa Jumal Jumanji +Jumbalia420 Jumbo +Jumbo Joe +Jumpcut JumpingBean +Juncker June +June bug Junexo JungJulius Jungkook Jungle +Jungle Georg +Jungle Jepa +Jungle Jim +Jungle Wreck Jungle175 JungleKitty +JunglinTunes +Juniortank25 Junk168 Junmai +Junsimu Juntti463 +Juo Juoda +Juoppis JuostenKustu Jup1Ko1r4 +Juppi Juqqernaut Juranja Jurassix +Jurble Juri +Juri M +Jurikka +Jurisdiction Jurky Jurmalainen +Jurrie Jurtaani JuryRigging +JusAmain101 JusCauz +JusDoMe +JusPourVous Jusfat +JussJoshinYa Jussi Just Just Alright +Just Alt F4 +Just BeingMe +Just Bones +Just Bryce +Just Champ3 +Just Creepin +Just Dank +Just De-Iron +Just Jacob +Just Keith +Just Kurt +Just Logan +Just Malone +Just Milton +Just Mitch +Just Neptune +Just Reacher +Just Treason +Just a Dilf +Just a main +Just aFacade +Just for Fun Just1n Sane Just3lis444 JustAAPotato +JustADowny +JustAFroggy JustBob JustChillins JustDevon +JustDrew JustFollow JustGoInDry +JustIan +JustJS JustJake JustKidStuff JustLucky @@ -11739,14 +24718,25 @@ JustPeachy JustPertti JustRenne JustRoW +JustSarge JustSinful +JustTaxLand +JustTheFool JustTheTip +JustToast +JustTrynaMax +JustVibeWMe +JustVinny +Justa Wake JustaStar Justass +Justice v1 JusticeSven +Justicemoose Justiciaro Justified Justin +Justin NT JustinBieber JustinFromVA Justinkai @@ -11755,66 +24745,178 @@ Justins007 Justlfied Justnexuss Justo80 +Justorr +Justryin +Justyfi +Justyn Jusus Jutendouji +Jutku +Jutkunmetku +Jutter +Jutti +Jutty Ruckus JuuNinJi Juugmasta Juul +Juulxodia +Juun Solo Juuna +Juunaz2chips Juustis +Juuzo Juvi Juvian +Juzzy +Jvzy Jwad +Jwcsg +Jwd Jwett +Jwu JxJxV JxcelD +Jxck Jxcx Jxdidiah Jxdooo +Jxhnn Jxke +Jxmeson Jxnas Jxni +Jxstxn +Jxxst JxyStorm +Jy Jybais Jyeronese Jygers +Jyhlln Jyhy +Jype Jyppedi1992 Jysk Jyura +Jyy Jyypy JyzzBrah +Jz +Jzbeta +K 1 L L A +K 1 P +K AMI +K B D autism +K E K E B +K E L A +K E T CHUM +K E V 0_O +K Hades +K K Boef +K NW +K O L L I +K O M P I S +K OOOOOOOOOO +K P N +K P Sweet +K Smalls +K W +K W A L A +K Y Y +K a l e w i +K a z a +K aarel +K ayyla +K eller +K elvin +K en +K etaminer +K ev +K iNG IRON +K idd +K ilo +K im +K l 9 +K l N G S +K nauss +K nut +K o j o +K o o s a +K ohen +K orruptt +K ree +K rs +K t r n e +K una +K ushi +K uz +K voth e +K y u m a +K yogre K-Diddy K-epan +K-market +K0 +K0 4 K00LBR33ZE +K0F K0L0S K0NING +K0USE K0bus +K0edinator +K0ju Balius K0lbi K0ndemned K0rky +K0rnuit K0tleciokas K0veras K0zor +K19 +K1ERZ K1LLY K1ddl3 K1ller5169 K1ng +K1ngo +K1ngshredder +K1r1t0123 +K2 Jung +K32 +K38 K3KSE +K3U S2 K3azkoks K3fka +K3kt K3mi K3nn3d K44K K4IF20 K8iee +K99 2 +K9Father K9lenny +K9rk +KA97 KABBABEAST KAKAGUATE0 KAKERANDELIN KAL-JML KAMlX +KAT alyzt +KB1988 +KBARAKAT +KBX0 +KC Chiefz +KC M0 +KC8 +KCRB +KChiefn KDOG1419 +KDOT_OSRS +KDark22 KDrizzy KEEPOUNDING KEEPTHATSHIT @@ -11822,73 +24924,164 @@ KEEZY10 KEIF KEKDUBYA KEKLERO +KENTUCKYBLUE +KEllis KFBal +KFC CAMDEN +KFC EMPL0YEE +KFC OG KFCatz +KFChompy +KGBK KGCine +KGP KGee +KGoldy KHADER KIIIIIIIIIIH +KILLER COMBO KILO KIMB0 KING +KING GAYWAD +KING VILO KING332 +KINGNERON +KINGstayMAX KINGxGIZZARD KINNTO KIPPER +KIVI 420 +KIWI Stu +KIitor IS +KJ 2 +KJ6 KJLS +KKayK +KKela KKona +KKona USA KKrazyAl +KKronas KKurtiz KL93 +KLB +KLS +KM 30 +KMW +KN0G KNIKERSNIFFA +KO CANE +KOK enjoyer KOKAOKAA +KONMAI +KOS OVO KOlRA KQSS +KR Zangetsu +KR0VALI +KRN +KRON1C 420 +KRYMK +KRYPTONlAN +KRlT KRonHusker KS04rs1 +KSP +KSaucee +KT Ferrie +KT Tape KU51 +KUAY KUAYx KURD1STAN +KVM8 KVRPT +KXNG Razing +KXNGVEGETA K_sak +Ka0s50 +Ka92 +KaChiuSa KaIOKENRAGE KaMi KaMi_RnG KaTFeniX Kaan +Kaan Frog +Kaarel55555 +Kaaris95 +Kaarv +Kaasbaap +Kaasboom Kaasmantel +Kaaswater +Kaaz Channel +Kabatlor +Kachhow Kacinova Kacy Kacyy +KadHead Kadabara Kadan Kadarlu +Kadett Opel Kadeyr1 Kadocc +KaeBtw Kaelin Kaempen Kaepls +Kaer +Kaesar KafHaYaAinSa +Kafaei Kaffah +Kafficko Kage Boshi +Kahdoom +Kahis +Kahlx +Kahto Kahuna +Kahur111 Kahvikuppi +Kahvimaa +Kahvo Kahwoozy +Kai ri +KaiHos19 KaiXin Kaibaman +Kaif Kaihn +Kaiirl +Kaila Kails Kaimanll3kav Kaimorten Kainahuulio Kaine +Kaioken x420 KaiokenRyan Kaion Kaiser +KaiserBruno KaiserRS Kaister +Kaitaia KaitoSun Kaiven +Kaizen Reign +Kaizen Soji +KaizennxX +Kaizloh +Kaizooka +Kajbanan +Kajgils Far +Kakariiiiick +Kakarrot Kake Kaker Kakerandeli @@ -11897,84 +25090,144 @@ Kakoji Kakor Kaksitoista Kaku +Kaku bakudan Kakua +Kakuri +Kal9000 Kalakoi +Kalas Kalash556 Kalashnikova Kalavothe +Kalb Kale +Kale Henk +Kale vader +KaleKikker92 +KaleRS +Kaley Cuoco KaleyFan Kalezki Kalfite +Kali Maaaa +Kali Roses Kaliaa Kalico Cat Kalideos Kalihi Kalikow +Kalima Kalis Kaliumoxide Kallateral Kalle +Kalle Anka Kalleee Kalmaars Kaloex +KalopsiaSix +Kaloua Kaltsu Kalu1337 Kalub +Kalvaaja Kalveo Kalystas +Kam +Kam Lok Lam Kamal63 +Kamchi Kamelinpiaru Kamelovsky +Kamelze Kamen +Kami_no_majo Kamiel +Kamii Dad +Kamijou Kamikazi Kamino +Kamino Kage +Kammorie Kamp Kampest Kamphuijs Kanagawa Kanao Kanapius +Kanapizza +Kanbu Kandarin Kandeeh +Kandid GG Kandonesys +KandrakarsNX Kane +Kane 7687 +Kaneelkameel KanekiKun Kaneohe Kangru Kangst3r Kani +Kaninka Kanned KannonBalker Kannski +Kansas +Kansas Bill +Kansas State Kanseim Kansi +Kansloos Kant +Kantinejuf Kantoo Kantrimees Kanttis +Kanuk Kanye +Kanyeetzy +Kanzeigan Kaolo +Kaolo Spoon +KaozerMauser +Kapaa Kapakala KapeVing Kaphu +Kapiling +Kapitalisti Kapitein Kapiten Kapkeik +Kapkkha Kaporkchop +Kapot +Kapot Slecht +Kappa 73 +Kappa monkaS +Kappa xD +KappaZilla +Kappala +Kappalism Kapsaluun +Kapsones +KaptainPurp Kaptainkilla Kaptains KapteinK Kapten +Kaptn skev KarQ Karaboudjan Karaf Karagoz Karamjob Karans +KarateKon KarazySS4 +Karc KareemPie1 Kareir Karekano @@ -11982,73 +25235,118 @@ Karen KarenMaskin Karethaeis Kargas +Karhu48 +Karhuboiii Karhulohi81 Kari +KariJuice Karies +KariimsPik KarilSummer Karils Karim4lol Karkanii Karkotaseet +Karkov Karl +Karl The SUV +Karl1s KarlS282 Karlee +Karliah Karlit Karlology +KarlosBro Karlteine Karma KarmaRush Karmaa Karmadyl +Karmafox Karmah Karmas +KarnMother1 Karnivore Karnyx Karolik +Karolus6 +KarpyCarpe +Karrak7 KarsanHAM +Karsk kopp Karskeinmies Karso +Karsta Anne Kartelrand +Kartoesh Kartoma Karukas0 +Karumba Karumi Karuu +KarvaBanaani Karvajarru KarvaneMees Karvatatti +Karwos +Kasane +Kasdeya x Kasei +Kaseii 1 Kasejas +Kasen Kaser Kashak +Kasihan Gua +Kasoku Tesla Kasp +Kasperjus Kasprzak1 Kaspuhh Kasraa +Kass Glimmer Kassipotku Kassu +Kassu C Kasuel Kasugano Kasvikko Kat1nr +KatBeatitude Katagon Kataphatic Kate +Kate Bush KateTiffany Katenkos Katetuotto Katfishh Katiensam +Katikene Katikene0 +Katinas +Katiopeia +Katlink5 +KatnissGray +Katraenia +Katrielle Katski Katsuo666 +Katt 90 KattNiP Kattarui +Kattnakken5 Kattnis +Katze btw Katzes +Kauhee Hiki Kaukeneris +Kauldron Kaunas +Kaunas_Rulz Kaunopihlaja Kautschuk +Kavz KawaBonga Kawactus Kawaii @@ -12057,35 +25355,61 @@ Kawaiisaki Kawakuboku Kawkaw Kawked +Kawtik +Kay D KayJ KayWhyPee +Kayazy Kayback +Kaybizzle Kayden +Kayden Boy Kayen Kayla +Kayla Swift +Kaylidascope Kaylizz Kaylon Kayluh +Kayns Main KayranFootly +Kayso Kaytok +KayyPlz Kayzielol +Kayzo Kazatan1245 Kazave Kazaz +Kazcade95 Kazching Kaze8HerOut +Kazify +Kazuma Moon +Kazunni Kazuuhiro +Kc Collector Kcnny Kdash +Kdaw Kdens +Kdragons +Ke bajo +Ke era +Ke nt KeB4NG KeRah Keabler +KeanuCat Keasbey Kebab +Kebab Ari +Kebab Store KebabGuy93 KebabWrap +Kebabov iron Kebbabhallal +Kebbby Kebbe Kebintotero Kebs @@ -12094,35 +25418,62 @@ Kedakaki Kedirav Keebler Keef Supreme +Keef_Man Keegi100 +Keekar Keekers +Keel Keela Keelay Keenar +Keep Le Fe +KeepCup +KeepDistance KeepItWicKeD Keeper1OS KeepitStoney Keepo KeepoKeisari +KeepoNoIron Keepomaster Kees KeesCanadees +Keeslp09 +Keetgracht +Keevon Man Keff +Kegaz Kegern +Kegs +Kegse +Keh O Brien Kehaline1 +Kehno Keiala Keidy9 Keifay Keikoh Keinas18 Keiran +Keiran Perch +Keironn Keisari Keisarinna +Keister Egg Keit KeithMcChief Keithii +Keittokuppi Keizer +Kekaha +KekeLovesMe +Kekkonen +Kekkonen69 +Keksiviikko +Kel Darsam Kela +Kela maksaa +Kela-Olli Kelagang Kelb Kelbikers @@ -12133,11 +25484,14 @@ Kelgone Kelh Kellarivelho Keller +Kells o_o Kelly Kellycollin2 Kelohonka Keloo +Kelps Kelso523 +Kelso561 Keltik KeltonThaGod Keltuzazz @@ -12146,106 +25500,182 @@ Kelvin2GWW Kelvino Kelwus3 KempBush +KempDaShrimp +Kempisch Kempset +Kempy x +Ken +Ken Bolka +Ken Griffey +Ken Kill U +Ken RS +Ken Ten +Ken141 KenBone KenKaniffCT +KenPerm +Kendal x Kendal68 Kendlang1 +Kendrick3691 Kenery Kenesu +Kenfernal Kenleyy Kenleyy_TM Kenmaster Kenn +Kenn y +Kenna Kenndu Kennedy Kenny +Kenny Deez Kenny121 Kenny6397 +KennyKSD +KennyS KennyWhopper Kennyollie Kennypower5 Kennyyyyyyy Kenozh Kenpo +Kensan-7 +Kenshiro Kent KentWasTaken Kentacus +Kentarokins +Kentish Hops Kentucky Kenwood +KenyanChild Kenyann +Kenze +Keonii +Keox +Kep Kephan Keplunk Keppi +Keppi Einari Kepra Kepuck +KerZam Keraliix +Keratin Kerbeth KerfDaddy Keri +Keric Kerk Kerkerino Kermajorma Kermit +KermitTheRob Kernalpotato +Kernautist Keromasev +Kerrr Kertar Kerzara +Kes Sittus +Kesc Kesekui Kesohs +Ket +Ket Baggie +Ket Schep +Ket Uh Mean KetaKnallt +KetaYours Ketabar Ketanator Ketch Ketho Ketnet Ketonall +Ketsah Kettaz Kettu Kettyman Ketwards Keudel Keunic +Kev The Tonk +Kevain69 Kevali Kevb0t Kevbro9 Kevichan Kevin +Kevin Booker +Kevin Framed +Kevin Nguyen +Kevin5-0 +KevinDurant +KevinLawrune +KevinOSeven KevinTes +KevinTheGOAT +Kevinspostal Kevinw20 KevlarX KevolutionX +Kevsin2 Kevsin3 +Kevslays +Kevstrong Kevthebos Kevva +Kevve +Kevzy Kewl Kewlaidman Kewnsauce +Kewwl Kexkaka +Key Concept KeyNoir Keyashes Keydiss +Keyfob Keylock +Keylord Keyney Keyoh Keyori +Keyose Keywork Keyzz Kez0 Keza132 Kezmaya +Keztra +KezzerQ Kezzerina +Kgb Spy +Kgsnipe +Kha Zx Khaant Khabib Khader +Khajgold Khal +Khal Bow Khaled Khaleeeesi Khaleesi1113 +Khalesar Khalisee Khamoshi +Khan of Iron +KhanhDung +Khans Wrath Khanzed Khao +Kharium94 Kharjo Kharn Kharos @@ -12254,10 +25684,15 @@ KhatrickZain Khayri Demon Khazad Khazad Dum +Khazanedar Khazu +Khealim Khest +Khint +Khirean Khiru Khleb +KhooNBust Khoosh Khoppa Khornebull @@ -12265,16 +25700,31 @@ Khovansky Khride Khrollo Khryptik +Khrysus Khufu Khune +Khunt Flapz +Ki Adi Fundi +Ki Arts +Ki Stu GSK +KiD BeeR KiIIa4realz KiLn +KiSMET6 +Kia Jon Kiarama Kibb +Kibeleza Kibisai +Kibito Kai +Kibra Kick KickarseCale +Kickback Dw +Kickbums Kicker +Kickrolls +Kid Inferno Kid K O N G KidClutch17 KidLeaderKTY @@ -12282,237 +25732,482 @@ KidSativa Kidalien Kidchilly100 Kidd +Kidlizard KidneyBean Kids +Kids Bong Kidtrilogy Kidur +Kie Kiedis +Kieftron +Kiek um goan +Kieken +Kiekkoilija +Kiera Kiero Kierzo +Kiewit +Kifooo Kifsa KiiDSKOLiO +Kiinja +Kiinnostaa Kiirii +Kiisu Kiivi Kiiwityty Kiizoru Kijucatm +Kikikissa Kikiniki2 +Kikkel Kikkertje Kikyo101 +Kil U +KilIerDaddy Kilamanjaro +Kilbot0 Kiliann Kill +Kill Crazy10 +Kill Credit +Kill the GE KillConfirmd KillSwitch26 Killa +Killa Cam +Killa Kamali Killa213 KillaSilence Killab0rtion Killabrew Killadelphia +Killadeuce Killamemsta Killaowns Killatonicus Killed +Killed Elmo Killed145 +Killekalekoe Killemall Killer +Killer Jr +Killer Kurce Killer7502 +Killer81093 +Killer9823 KillerFlix KillerSlee +KillerVibes +Killerank202 Killercaster Killerdog HC Killerdustyn Killerkotti Killermatt +Killeroh Killers455 Killertribes Killgor138 Killi +KillianRS Killing KillinxLivin Killjoy4fun +Killjoyer2 Killmankind +Killme5551 +Killmelol Killnloot2 +Killoah +Killsw1tched Killswitch83 Killua +KilluaSam Killzone +Kilminater +Kilo Meter +Kilodoreo +Kilograms KiluaZoldyk +Kim +Kim Chungha +Kim Trails +KimKallstrom Kima +Kima Ronso Kimano Kimbr0 Kimbu +Kimex +Kimi Hendrix Kimoja +Kimosabii KimtonLe Kina Kinaesthetic +Kinboat Kind Kinda +Kinda Blue +Kinda Sinful KindaDerpy Kindaddy Kindom Kindoou Kindozsodln +Kineettinen +Kinetic King +King 0f Gout +King Ankle +King Aussie +King AvonIV +King Blob +King Boned +King Bud +King Bugs +King Chev +King Dong +King Dongo +King Edolus +King Elf +King Elon +King Emurxer +King Flipsta +King Frodon +King Green 2 +King H0d0r +King Ian +King Junkie +King Kabanos +King Kenneth +King Lexius +King Mariin +King Milky +King Nino 1 +King No Fear +King Noc +King Paf +King Rabbit +King Rayman +King Redeem +King Rico +King Runs +King Ruonis +King Seb +King Seneca +King Size V +King Slime +King Snowman +King Spudz +King Swine +King Tsar +King Westor +King XRPL +King Zaros +King davey +King of Imps +King of PvM +King0fHelll King0fSkane King1631 KingAcorn85 +KingAwowogay KingBOO KingBailey KingBoo +KingBuliwyf +KingClark KingCudii +KingCurtis11 +KingDarkVII KingDweebus KingEider KingFlugal KingGoblin09 KingGrekus KingGunshow +KingHawk O_o +KingInYellow KingJacula KingJelore +KingJoey +KingKahuna KingKlick373 +KingKlye KingKongKoen +KingKong_Qc KingLeonidas KingMikeyD KingMongo KingMonk KingMook +KingNate1 KingNathanx KingOfIron +KingOfQuests KingParcival +KingPatVII KingPlAnchor +KingPractice KingRobStark KingRustyVII KingSandCrab +KingScribles KingSizeD1CK KingSoge KingSpirel +KingStyle KingTheGreat +KingTsjubbie +KingValencio KingYoshi KingZac KingZerka +King_Kerran Kingaroo +Kingben +Kingbuddy40 +Kingdom Rush +KingdomBlade Kingeri Kingg +Kinggg +Kingism Kingjake18 Kingmonkey23 Kingofhearts Kingpfx2 Kingpin +Kingpin Xp Kingpk3r +Kingrobster7 +Kingruler456 +Kings67 KingsBluue +KingsGrace Kingspadex42 Kingsta +Kingsthor KingstoAces KingstonWall +Kingsty +Kingz Haki +KingzWorld Kinjello Kink +KinkerScaper +Kinkers Kinky +Kinky Kenny +Kinky Scr Kinkybuns Kinkytoast Kinkyy +Kinno +Kinobles Kinokird +KinokoZoku Kinp +Kinsaic Kintoki300 Kiopley2 Kiox +Kipee Anneli Kiplup Kipnuggets Kippenbro +Kipsel +Kiptandori Kiqz +Kiraci Kiraga Kiraly +Kirara +Kirbi Smart Kirbngo +Kirbsey +Kirby Kirby7670 +Kirchberg +Kire1n +Kiree +Kiriel Kirimah Kirito +Kirk4 +Kirk97 Kirkburton1 KirkyBeast +Kirne Kirrion Kirry Kirstin Kirthor +Kirumibe Kiruzonu +Kirx125 +Kirz Kisa +Kiseki Kisizel Kisle +Kiso Valley Kiss +Kiss Kiss +KissMeHomies +KissOfFire +KissOfFury +Kissahomie69 Kissanpentu Kissmyase111 Kist +Kit Fistoo +Kit10Kat Kita +Kitashan +Kite Solo Kiteman +Kitfox IV Kitsch KitsiKitty Kitsune +Kitsune Kami +Kitsune Ness Kitsunemimi Kitten +Kittenz Kitties +Kittle Bits +Kittoh Kitty +Kitty Perry +Kitty v2 KittyMeow83 +Kittymouse 1 +Kittys Newb Kiusatus Kivespulla +Kivick Kiwa Kiweh Kiwi +Kiwi Icons +Kiwi Stona +KiwiIskadda KiwiMacJ +KiwiSteve +KiwiTheBot Kiwiana Kiwidude Kiwiskurt Kiwwion +Kiyak Kiyoko +KizJ Kizminsky Kizone +Kizz mo Kizza +Kj Kai KjellEllen +Kjellberg94 +Kjomo Kjottfifaan Kkobe +Kkobugi +Kkokkom +Kkoppa Kl2AZY Kl3RAN +KlDDO KlLL +KlLL 4 BONES KlMI +KlMpossible KlND KlNG +KlNG MlKE KlNGY Klaar +Klaarkomer +Klaasie Klacky Klanezy Klanks +Klankss Klapzak +Klarence Klariany Klarna Klaskdeng +Klassic +Klassified Klatscher +KlausLittle +Klaussie Klavan +Klavelon KlazBooy Kleatus Klebold Kleened Kleiades +Kleine bolle Klementtii +KlemmDawg17 Klemonhaze Klengie +Kleo +Klepdiezle03 +Klepp Kleptic Kletz KlewKlew KliKlack +Kliewer Kliffa +Klik gebit +Klikke +Klingons Klippzz +Klo0 Kloefklapper Klogin Klonzyon +Kloofiool Kloorijoodik +Kloot-Zuk Kloover KloreCore +Klotho +KlovneKrabbe Klowdstr1fe +Klub Dubx Kluftritter +Klumpy Klumsie Klunchkey +KlungePlunge Klunkii +KlutzyKay +Kluuntje +Klvtz +Klyd Kmac KmartWorker +Kmd +Kmie +Kmk_Yawgmoth +Kmorken Kmtfwtm +KnD xP Knaap Knabbelbaars +Knabbernossi Knacker Knakenstein Knaksaucage @@ -12524,77 +26219,146 @@ Knaught Kndd Knead Kneeeled +Knewby8 KngBlkDrogon +Knickers +KnicksNati0n Knife +KnifeStory Kniffes Knight +Knight Crip +Knight Drake +Knight Jo +Knight Mors +Knight of 3 Knight50 +Knight522 Knight5247 +KnightKettle KnightMike KnightO +Knightcrawle Knightenator +Knightlock +Knightmare +KnightmareNL Knightrainy Knightromite Kniili Knikkerbal Knivezii +Knob End +Knobin Hood +Knod with Me +Knoo +Knospi KnowMadss KnowPurpose Knowing Knowledge Known +KnowsNoFear Knoxville333 Knuckle +Knuckles +Knulle Knummi Knurrbauch KnusCaboose Knusseprulle +Knut Knut +Knwn +Ko Addiction +Ko D Ur Dead +Ko0tje KoBe +KoH Zoro +KoPvM +Koa +Koak Koala +KoalaBear819 KoalaBwala +KoalaHeist +Koalarobe +Kob Bryant Kob3oshii +Kobakat +Kobayashi89 Kobe Kobenna +Kobi btw Kobold Kobushi Kochelas +KochiiBear Kocjancic +Kocyte Kodai Kodak Kodax Kodeth Kodfunk +Kodie Kodipar +Kodo +Kody IRL Kodywithac Koekebakker +Koekenpan Koekienator Koelkast1 +Koelkast3120 +Koelogg +Koemi +Koenfu +Koeppy +Koerdistan Koff +Kofferbak Koffie +Koffie Shop KoffieBoer Koffiekan Kofnx +Koga09 Kogarah +Koge +Kognito +Kogsin +Koh Me Lo Kohda +Kohrosian +Koii Diva Koka Koki KokiriSword +Kokki Kokkue Kokkugoburin Koko10tkd +Kokoftu Kokou Kolade123 Kolariah +Kolarino Kolbot +Kold Pizza69 Koldbetrayal +Koldz +Kolicee Kolmay Kolmiojuuri Kolodinsky +Kolomit Kolton Komai Komarov26 Komijn +KomisarzFlak Kommunist +Komog Kompact Kompania KomradeScape @@ -12602,61 +26366,125 @@ Komugi KonDaTV KonKai Kona +KonaTheCake KonaTheGent Konami +KonarMilkies Koncept Kong Kongen3609 +Kongherodes Kongklunk Kongmoakim +Kongon Musta Kongz +Konigs Tiger Konigsblau +Koningnoob +Konjakkia Konkelbearet Konkuuu Konnie +Konnor Ray +Konny KonosubaAqua Konroy11 +Konstiq +Kont Crumbs KonteNeuker Kontentti Kontoret +Kontrafakt +Konu Kony +Kony4ever +KonyRomo +Konya Slayer +Koo +Koob +Kooben Kooch50 +Koochie +Koogs +Kooiker +KookieDough +Kooky Kal +Kool Aid76 +Kool Hwhip Kool Iron KoolKriegs +Kooleey Koollpop +Kooloo Limpa +Koomar Koomorang +KoontzyJr +Kooopa Koopa +Koopa Kash Koopatrol Koopley +Koops +Koothi Jr Kop0nen +Kopet +Kopites +Kopn Alt +Kopoes +Koppa Olutta +Kopra_0nu +Kopzilla0 KoqPuuser Korado Korail +Koral64 Korangarr +Korasko +Korazi +Korbet KorbolJestem +Korby_K +Korea KoreaBread Korean +Korean Neet Korelivia Korihoko Korisas +Korkesh101 +Kormulus Korneel +Kornettos Korok Korpokkur Korravalvur Korsair +Korsan Kortti KosChiquiss +Kosaki +KosarevSpawn KosenRS Kosey +Kosha Engler +Kosken Kovin Kosmckid +Kosmo +Kosra Kosst Kossukissa Kostaja123 Kosteezer Kotaki95 +Kothfan2 Kothfan3 Kothu +Kotimaista Kotkatapult +Kotoe +Kotov +Kottis +Kotze Koucii Kouen Kouhais @@ -12665,111 +26493,227 @@ Koulupummi Kourend Kourk Kov0s +Kova Kova Kovacs +Kovacs Bela Kovaley +Kovalux KovidKai Kovit +Kow +Kowawa Koxu +Koy +Koy5 +Koyix +Kozileks +Kozmic +Kozojebec Kozyshack +Kpiy Kprs +KpyosX +Kq Kr0jm +Kr149 Kr1sten Krab +KrabbiePatty +KrackScape +Kradoth +Kraff +Kraft Slave Kraftra Krafty Kragjay +Kragwa +Krahhling KrakaJ Kraken +Kraken Beerz +KrakenSnacks +Krakenarse +Krakenmom +Krakkars Kralik Kralovna +Krammetje +Krana +Kranky Kraut Kranox +Kransie KrapNSchitz +Krapinschitz Krappa Kraq +Krasznahorka +Kratic Kratje Kratos Kratos-Arepa +Kraujukaz Kravcik +Krawall +Kray +Kraytoast +Krayz818 Kraz3d +Krazed Zen Krazezor Krazy +Krazy Kramer +KrazyKillah3 Kream +Kream PIE KreampieKing Kreams Kree +KreeM_Pies4U Krel +Kreme Krispy +Krepe +Kreshink +Kreupel hond +Kribo KriegFleisch Krigare Krigersej Krigsgaldr +Krikkos Krile Krillin +Krillin It Kriltar +KrimenReborn +Krios Kriptog +Kris 2 +Kris Kross +Kris Tis +Kris Toffer KrispCowMilk KrispyCow +KrispyJello +Krispz +Kriss42 +Krisse Krisstian +Krisstof Kristina Kristo1337 +Kristoh +Kristops KristySlays +Kristya Kriszx Krith +Kritters Krizalid Krizee Krllykins +Kro Kroeg +Kroekoek Kroer1 +Krogan +Krohmos +Kroketten +Krombop Mike Kromuh Kron0 KronScape +KroniKStyL Kronic KronicPlague +Kronic_gtt7 Kronjuvel Kronoryx +Kronstedt123 Krontio +Kropium Kross +Krownax +KrthisIrnhrt +Kruber KruimeIkoek Kruisboog Kruizar +Kruncha +Krusch Qc Krusk09 Krustorb KruttGutten Kruuxt +Krvavec +Krw Kryder Kryderman95 +Kryl +Kryllz Kryoge777 Krypsiss Kryptanite Kryptic +Krypto Pup Krypz Krystalbead Krystalized +Krystie Krytl0rd +Kryxon KryyptCeepR Kscott +Ksed Ksteg Ktran4 +Ku Kuaalo Kuanta +Kubanna Kubfu +Kubiak +Kuchera Kudos +Kudra Shade Kudsk Kudt +Kuemper Kufke +Kuger +Kugi Kuha +Kuhis Kuhki +Kuhnlicious Kuhvon +KuhwazyyPVM Kuhz +KuidaoreTaro Kuistikopone Kuittis +Kuji Otoya +Kukii +Kukko +Kuksukka Kulak Kuler Kuli +Kullilutku +Kullirausku +Kumara Fries +Kumduh Kumeku +Kumetis +KumikoOkada Kummars +Kummens Kumoga +Kumonyru +Kunakana Kunaphela +Kundalini888 Kung +Kung Aguero KungFuKennyy KungFuhr3r KungFury01 @@ -12778,18 +26722,25 @@ Kungler Kungzaki Kunie Kunkku289 +Kunkulu Kunsel +KunukGL Kuola +Kuollu Homer +Kupla +Kuppi KurSiens Kuran Kurasaki21 Kurask +Kuratus Kurayamii Kurdishtan Kurfue Kurgan Kurib0hh Kurim +Kurios Kurko Kuro Kuro6757 @@ -12798,141 +26749,368 @@ Kurohige-Jm Kuroma Kuroshin4 Kursdragon +Kurt Cocaine +Kurt1sdbr +KurtMaxed Kurtan +Kurtismo789 +Kurtiz +Kurtowogei Kuru Kurumin +Kurums Kurune Kurza Kurzgesagt Kurzi Kurzol +KusOnRNG +Kusai Kush +Kush 999 +Kush Grey +Kush Nerd KushWizdom +KushalaDaora Kushanada KushedKnight Kushies +Kushioned Kushkhalifa +Kushmooms Kushtyyy Kusiaks Kusimuna +Kusimuna JR Kusle KusmarPavola +Kuso Saiko +Kut Jack +KutInternet Kutasy +Kuthay +Kutirons +Kutkip +Kutori Kutunawa KuuDuu Kuudere +Kuulus +Kuuw Kuvakei Kuwolski +Kuxx +Kuykendoll +Kuzh +Kuzi +KuzzzTruckin +Kvacky Kvamsdal +Kvaoathe +Kvzy Kwadraat +Kwakske Kwambam Kwan +KwanDynasty3 +Kwani Kwarkark Kwastaken +Kweem Kwei +Kwep Kwieppie Kwintal Kwondeo +Kwong Kwongo KwuarmFarm KxKxW KxNoTTz KyIll +KyPolar +KyWi Kyaandere +Kyafa Kyberpaavi +Kye187 +Kyeb KyeeG +Kyelee Kyersago Kygehn Kygesm Kyhlen Kylanater Kyle +Kyle 8990 +Kyle Esq +Kyle G +Kyle Kmac +Kyle VA KyleFammm KyleGrounded +Kyledog829 Kyler +Kyler Moss +Kyles Cute +Kyles GIM +Kylesteven +Kylewwashere +Kylex Kylianvb +Kylliel Kyloman Kymeister +Kynodontas +KyotoSadness Kyouan Kyouko Kyouma +Kyouna Kyouran +Kyphrus +Kyps +Kyr0s +KyraXIV +Kyrakishuun Kyrdaar Kyrie Kyrist KyroThanatos +Kyroba Kyronius +Kys Ironmen Kyski +Kytkinpommi KyuubiKurama +Kywt Kyykin +Kzyl +L 0 S T Y +L 3 G 4 C Y +L 67 +L A R A M S +L Ben +L CBO +L D A +L E G E N D +L E G O +L E L O +L E P I +L F C +L FC +L Hus +L I N U X +L I V M +L OAFS +L S Q +L U I G +L U U K E +L X R D S +L achie +L aika +L aka +L ama +L ang +L apras +L atias +L aw Rune +L aze +L e an +L eafErikson +L egs +L ek +L emaster +L ev +L i m a a +L iamm +L iar +L ilo +L inox +L ions +L o w g +L ockdown +L ofty +L osi +L paradoxum +L u m i +L u mi +L u x +L ucas +L unatic +L00000 +L00M L00OL0OO00OL +L00T SNIPER +L00tacr1s L00termember L0G0 +L0GI +L0L L0L0LL0L00LL +L0RA L0RD L0RDGAINS +L0ST S0UL +L0Z L0kur L0rd +L0rd Arthur L0rdMullett L0st +L0vecraft L0ves2Splooj L109 L115Squirtle +L1L GN0ME +L1ghtweaver +L1l bits L1ncoln +L1ndman +L2 L2Crash L2D3 L2Loki L2love L2mmutaja +L2sit L2tankbandos L2tob +L337 GodHand +L3RKON +L3V3L L3apOfFa1th L3gg0 L3mur +L3prec0n L3sius L3tMeBreath +L4D2 Enjoyer L4rry L4st +L522 +L64 +L86A2 +L8CP +L8ers L8rT8r +LADFS LAMAFAO LAMARJACKS0N LASBE +LAUFY +LAZY88 +LB9 +LBS M +LBaccer +LC33 +LCpl +LE0 MESSI +LE54SON LEARNINGTHIS +LEGOSl LEN0 LENZ +LET ME COOK +LEWlS +LF Content +LFG 69 LFGrills +LG 8anter LGBTQLMNOP +LIL BLESSED +LIL PRINCE +LILKHALAMARI +LIMEWORLD LIQUICITY LITEIT LITHITS +LJ 8 +LJAP +LJPalmer LKIT +LL Trigger +LLAMA_ears93 +LLIRSHSLSIEi +LLY Duramax LLeffe +LLich LLol +LMAO LOL KEK +LMAOImDying +LMFAO IRL LMFAOIRL LMNOP3 +LMParrot +LN41 +LOADED_AR +LOGAN109 +LOGlC LOH3 +LOL BMW +LOL MAD LOOP1456 LOOSECOOCHlE LOSTinGAMES +LOUlSlANA +LOWIQXD LP Smokie +LRG LRGD LRichyy +LS1 +LS3D +LSD-25 LSDDS LSDe +LSDeezNutttz LSDonny +LSDreamy LSxD LTUD3stroy3r +LTapperz +LUBRICAT0R +LUKA DONClC +LUR3ME +LURED BY ROT +LUTlN +LVN iZN0 +LWE +LXFY +LYAM femboy +La Benezra +La Bollita +La Brebis +La Croix +La Fiesta031 +La Frontera +La Moo +La Porta +La Sopa +La7itude LaCroisssant LaFroob LaLegende LaMachCaron +LaMarii LaPichula +LaRS 07 LaYdlN Laaban +Laadvermogen Laady +Laagvliet +Laaki +Labas Utak LabbatBlue LabbattSplat Labbis +Labor +Labstev +Labundo +LacDeaths +LacedKoolAid Lacedonian Laceinyoface Lachosocko @@ -12940,82 +27118,160 @@ LachysMain LacinorI Lack Lacking +Lacking IQ Lacoline Lacraio Lacrymosa Lactosite +LacusClyne +Lad J Ladbrook Laderstall Ladme +Ladrian Lads Lady +Lady Calais1 +Lady Chompa +Lady Devil +Lady Porky +Lady Storms +Lady2022 +LadyBuck +LadyGagaTbh LadyJan +LadyJan BTW LadyJessicaL LadyMidn1ght LadyOfCyprus LadyOfMagick LadyPidge +LadySaurus94 LadyStarlite LadyStorm83 +LadyVamperic Ladydoll Laedzter Laeretes +Laethia2 +Laetor +Laf +Laffam Laffy +Laffy Taffy +Lafondaa Laftonn +Lag out LagArtist +LageLanden Lagerhaus +Lageri Lagg Laggbeer +Laggro +Laggy Brain +Laggy Clicks Laglet +Lago +Lagodzacy +Lagomancer Lagoon Lagrange Lagscape +Lagu +Lagwagon +Lah Di Dah Laharl +Lahn +Laid +Laid bare +Laika Wolf LaiskaJake Laiskiainen4 Laitoin Laitti +Laitue +Lajer +Lajfi Lake +Lake Show +Lake Valor LakeMonYew Laker Lakeshire +Lakka +Lakonic Laksa Laku +Lakuni +Lakupiippu Lala +Lalochazia Lalundi +Lam lul +Lam_12 Lama Lamanent Lamb1237 Lambretta62 Lambs +Lambzilla Lame +LamePuttE10 Lamented +Lamfear +Lamh Lamie Lamiia Lammen Lammy +Lamns Lamp +Lamp Burner +Lamp master Lampepit Lampyy +Lampzki +Lamshnarf +LanJiaoDuaKi Lana +LanaLuna +LanceDaPantz +Lanco Lancy Land Lander Landeskoging Landlord Landofzoa +Landucey19 Landyll Laneeta +Lanell Latta +Lanesstee +Lang Chang +LangeNieWies +Langeboy Langecries Langner Langosman Langscape Langtu102 +Langutan +Langzzy +Lanier +LankFrampard LankaKekw Lanky +Lanky Josh +Lankyfeed Lann +Lanny Pan +Lanoue +Lanpzki Lanrico LantadymeRey +Lantern Snow Lanx Lanzlol Laogai @@ -13025,69 +27281,142 @@ Lap0tai Lape Laphloredos Lapsa +Lapsapp Lapsivesi Lapua +Lapuz +Lapy +LaquishaBaby +Lar0i +Laraelias Larcadum Larcenex +Lard Jaysus Lare Lare240 +Larecia Larecio +Larenz Tate Large +Large Chompy +Large D +Large Npc +Large Tasty +Large Toads LargeExpLamp +LargeGrandma +LargeZock +Largelad2 +Largeprune Larie Larissa +LarksTongues Larkypoo Larotux +Larrey Larry +Larry 0G +LarryB LarryIsHere Larrys +Larrys btw Larryz +Lars Ohly +Larser +Larsinosrs Larsjns Larso +Lartsi +Laruka +LasBoi Lascooby +LaserLad LaserSchlong +Laserati +Lashi Lasjstts Laska +Laska Siara +Laski +Laskii +Lasne LasoliLeiffi +LassT Last +Last Bison +Last King +Last N1te +Last Stages +Last Texan LastAttempt +LastBoss LastHours +LastMark LastRecalI LastTexan +LastWookiee Lastinis +Lastkaiii Latanoprost Late +LateKnight LateOwl Lateksiuljas +Latelaturi Latero123 Latias Latins Latissimus Latitude Latompachy +Laturaivo +Lau396 LauQT +Laudine +Laufeyson965 +LaughTale XD Laughed Laukage Laukie +Laukki1 Laundry +Laundry Room LaupieLaupie Laur +Laur ex core Laura +Laura J +Laura uwu +Laurat J Lauren +Laurentina Lautanen Lauw LauweEgberts +Lav x Lava +Lava Buster +Lava rune +LavaFountain LavaKitty Lavadude42 Lavafrost +Lavagirl420 Lavak +Lavak Bob +Lavanis Lavasat LavendrGoons +Lavigne +Lavina26 +Lavios Laviuthen Lavvv LawOfBirds +Lawesy Lawfox +Lawhrer +LawlAsYouDie Lawlie Lawliet Lawlimon @@ -13096,96 +27425,221 @@ Lawn LawnChair48 Lawncat Lawnmower73 +Lawre nce +Lawsilk Lawson +Lawyer JD +LawyerGirl24 +Lax_315 Laxar Laxx +Lay +LayDead Layden +Laydwnandr0t Laydyn Layes +Layes X +Layezy Laylaa +Lays Layzi +Laz GIM +Laz Lo Mein Laz2510 +Laza Ferro Lazer +LazerVizion LazerWork +Lazgo Laziest Lazikiel LazloDaLlama Lazy +Lazy Fare +Lazy Jazz +Lazy Lump +Lazy Matt +Lazy Mauler +Lazy Moo +Lazy Shell +Lazy Soul +Lazy Stona +Lazy XP LazyB0y +LazyBoneZone LazyDevon LazyFarmer LazyOwner +LazyThom LazyTurtleRS +Lazydrink Lazyie_KiD +Lazysmokes LazyyySloth Lblacc Lbuzz +Lck Lda237 Lder +Lds +Le Bibu +Le Biff +Le Big Sad +Le Catptain +Le Doda +Le Foole +Le Gio +Le H0NK +Le Jeffeh +Le Peanut +Le Petit BH +Le Pogo +Le Reject +Le Stu +Le Sus +Le Tom +Le von +Le4f +LeAUD +LeB0ng James LeBlownGames +LeBoobie LeBrianJames +LeDamos LeDerpski +LeIronJims LeKinguin LeLuuk +LeMontBlanc LeMoonMan LeMoopey +LeNnEeX +LePeach +LeVarrock Lead Leader9922 Leaderless Leadfeathers Leadley +Leads Dead Leaf +Leaf 7 +Leaf Parker +Leaf998 LeafStoneDab +Leafffy +Leafpool Leafyshade +Leaga +League Brain +Leak +LeakedDMs Leaks Lean +LeanFavaBean Leanlce44 LearnCatMeow +Learningosrs Learti Lease0fLife +Leather Top LeatherJan +LeatherRat Leatherr +Leaux Key Leavepigrun +Leb Crotch +Leb Man +Lebanesee +Lebennn +Lebor +Lebowski2033 Lebrons +Lebusoft Lebzima LeccaJr Leckie12 +Leclerc 2024 Lectaminol +Lectosh +Lectrix +Led2000 +LedXia Ledgendairy Ledning +Ledu +Lee +Lee Ratt +LeeFelix LeeGavGav LeeHen +LeeV_V Leecherboy Leechy2399 +LeedsUnited Leegotalo +Leeleebug210 +Leemer +Leemi +Leemo Leer0y Leerjet Leeroyy +Leers OSRS +Leeshore LeesusChrist Leet +Leet Blues +Leet Bug Leetroopa Leeuwarden Leevar Leezy Lefonzeee +Left gf 4 Xp +Left inPeace +LeftFistt +LeftHerFor07 +LeftHerForRs +LeftTwix Leftist +Leftwich22 Lefty +Lefty-x +LeftyWarrior Leftytexan +Leg Day 99 Legacy-Blade LegacyOfErik +LegalCounsel Legalism Legally +Legally Dumb +LegallyAfk +Lege Legend +Legend 0007 LegendHarold +LegendKingz LegendOfShao LegendSuz LegendaryDTM LegendaryFoe +LegendaryLVP +LegendaryMe LegendaryRS LegendarySte +LegendaryZ0 +Legenddiary Legenddreams Legendelek +Legendish +Legends Epic +Legendsam7 Legened248 +Legggggooooo +Leggo Leggy Leggz Legikt @@ -13194,17 +27648,29 @@ Legion2410 Legionals Legislatore Legit +Legit Ape +LegitGarbage LegitSamuel +Legitidrown +Lego Brick Lego Fisher +Lego Mania X LegoMyBob +Legolas +Legolas I Legolic Legoliker999 Legosas11 +Legosaur +Leguminati +Leha +Lehawek Lehmo Lehnert Lehoir Leid Leider +Leidmavo Leif LeifBestLord Leiff @@ -13212,16 +27678,27 @@ Leigh Leilin Leimstiift Leion +Leist1nas +Leistus Leito +Leitwolf +Leivermorale Leivonnaiset Leiza +Lejj BTW Lejoon +Leka xo +Lekira97 +LekkerMoeder Lekkeri +Lekray Leky LelSickMeme Lelalt Lelbow Leldorin +Leldra +Lell Lelott LelouchV Lelysia @@ -13229,113 +27706,230 @@ Lemako Lemillion141 Lemiy Lemke +Lemmelleni Lemmy LemmyThePerv Lemon Lemon5000123 +Lemon9000000 +LemonTart +Lemonade max +Lemonguin Lemonmooffin +Lemonowo Lemonrider +Lemony Earl Lemonz +Lemosgomes Lemphys Lempsu Lemurcow Lemuria88 Lemursnore +Lendtable +Lenegis +Lenel Devel Lengzz +Leni Epiza Lenience3 +Lenify Lenlami +Lenn375 Lennie Lenning +Lenny Euler LennyPro +Lenovel Lenreys +Lenses Lentiano1 Lentil LenvisCZE +Lenya +Leo Gagner +Leo Messi +Leo The Fish +Leo12_1993 Leo2 Leo96 Leodero Leoma Leonatwo +Leonbozz LeonidasIV +LeonidasThor LeonidasXCIV Leonl Leontje Leorio Lepek38 Lepkilla +Lepra Leprechau Leprincias Lerch +Lernaean +LeroyDanknz Leroyvdk +Lerzbot LesGetIt +Lesbean Lesen Leshrac +LesleySnipez Less LessIsMore Lessar +Lesser Gods +Lessking +Lestamsakul Lestersaurus +Lesva +Let Us Dream LetBrettBang +LetJimCook Lethal +Lethal Blade +LethalClick LethalMortal Lethally +Letharil +Lethwei +Letits now LetrahL Lets +Lets Blaze +Lets Boss +Lets Glide +Lets Plop OK +Lets Ride +Lets See +Lets Toke +Lets Ziggy +Lets pep LetsGetSmity +LetsGetem LetsRouQ +LetsgoDaddy Letsjjj +Letspoint Lettersloth LettuceLegs +LettuceLime +LettuceNut Lettuce_8 Lettulainen +Leturpentinr Letz +Leukaremmi +LeukemiaLord +Levante Frog Level +Level Denel +Levelations +Leveldegree Levi +Levi Squad +Levi lmao Leviate +Levibeelevi +Leviud +Levven +Levyiah +Lew Sanus +Lew sid +Lewd Queen LewdTouchMe Lewdberrypie Lewey Lewf Lewfu +Lewhh Lewir Lewis LewisMcLaren +Lewis_y Lewism22 Lewison +Lewiss Lewithetui +Lewu +Lewwiis LexaSteel +Lexatrax Lexay Lexdegekte Lexer +Lexington73 Lexkai Lexxi Lexy +Leyon +Leyr +Leysim Leyton Leyzen +Lezio7 Lezley +Lfts +Lhk +Li am +LiI Tii Lii +LiT Clutch +LiT on Dabs LiTxEXODlAx +Liam McPoyl +Liam1994 Liam6780 +LiamLate +LiamLollypop +Liamas Liberate Liberaxa Liberty +Liberty Cap Libolik +Libracorn Librain +LichKiing +LichOneeChan +Licharus Licht +LichterLo +Lichtert +Licitness Lick +Lick My Wyrm +Lick Time LickAhrim +LickMcFicks Lickeris Lickilicky Lickumss +LidawgMcChad +Lidless +Lidlman +Lie Lie4it +Liebzer +Lies of S +Liet Katsu Lietuviskass Lietuvisz4 +Lieve +Lieven Lif3 Lifal Life +Life Road +LifeInsAgent LifeIsBaked LifeIsRockie Lifeform Lifehunt +Lifeisnow13 Lifeliners +Lifelulz Lifes Lifes12Rules Lifesteal @@ -13343,247 +27937,528 @@ Lifestyle Lifewaste Lifezajoke Lifticus +Lifting Fe +Liggen Lighning Light +Light Ace +Light Shell +Light age II +Light1324 LightAura LightB0ne LightRigger +Lightarrg255 Lightaxo Lighten LightenUp Lighter Lighterfalz +Lightfister Lightg0d Lighthead45 +Lightlord440 +Lightning MF +Lightningess Lightqt Lightstoria +Lightww +Ligma Balzaq +LigmaMufin +Ligt Lihatanko Lihtnenolife Lihtsurelik Lihu +Liiga-Ari +LiikeAGlove +Liite Liitokissa +Lijk +Lik me knie LikMijnRaid +Lika C Likalatopus Likark Like +Like Saint LikeABrother LikeAGloveee LikeCinnamon LikeToetally Liketocombat +Liko Likrot +Lil Callisto +Lil Dickyy +Lil Donut +Lil Dor +Lil Doss +Lil Eso +Lil Fika +Lil Garbo +Lil Hogg +Lil Knight +Lil Koda +Lil Lilyxo +Lil Lotus +Lil MCM4A1 +Lil Moe +Lil NllLO22 +Lil Rat Mann +Lil Roli +Lil Shay +Lil Stoma +Lil Tragic +Lil Weeezy +Lil Woowoo +Lil Yeeter +Lil Yungen +Lil Zeusy +Lil Ziik +Lil Zimp +Lil parasite LilBirb +LilBlueMew LilBobbi +LilFaulk LilGBigThing +LilGay btw LilHorny LilMissSlays +LilNubbins +LilPeepBoi +LilSeany LilSquidgy +LilSteamBoat LilStonks +LilSuzieVert LilUziBlyat LilWitness +LilYungChitn Lila +Lilac Devil Lilangrydude Lilbobsters Lilchris Lildirt +Lildischarge Liles Lilhotshotv2 Lilinss Lilith +Lillia n Lillie Lillyz +Lilmoose99 Lilnenedemon Lilqtforeva +Lilsauce72 +Lilsutts Lily +Lily Mayy Lilyalatea +LilyaxD +Lilypily0 +Lilysaurs +Limb +Lime Light +Lime Season Limed +Limeguy21 +Limewire +Limit Form +Limited Room +Limiwinkz +Limiy Limmert +Limmy Limo Limp +Limp Lime +Limpsioo Limpwurt +Limyt Linalool +LincolnButt +Lind say Linda +Linda Lou Lindegaard +Lindewyn Lindsey Linearr LinedFury +Linelis99 Linen +Linen Cry Linerz +Linewa Liney Lingwood Linh +Linhson Link +Link Adam +Link Click +Link Noises +Link Tribute LinkKing +LinkTheIron LinkedList Linkedln +Linkin Boy33 +Linkinaz Linkmoon Linkseratten +Linkv21 Linnara Linsey Linsunt +Lintell-lad5 LinusEkedahl +Linxis Lion +Lion Gin Lion-021 Lion0fZion Lionbatdog Lioncheart +Lionclaw Lionelliee +Lionheart +Lionheart Xl Lionhrt +Lionyxia +Lioui +LipShits +Lipalow Lipperr +Lippy Jimmy +Liqu +Liquar Liquicity46 Liquid +Liquid Apple +Liquid CSGO +Liquid GZA +Liquid Mire +Liquid Nexus +Liquid Reign Liquid8 LiquidRmt LiquidTheory LiquidTrails Liquidat0r +Liquidated +LiquidatorRS +Liquidwood0 Liquified Liquir LiquorGrain +Liqwid +Liridon Lirrix Lishenna Lisica +Lisle Liso +Lissino Lissoms Listeffect Listen2me ListenMorty +Listerine_TC Listics +Listifyy Lisuna +Lit Dawg +Lit Guy +Litas +LiteForge +Litefooted Litelii +Litem Liten +LiteralCow +Literic +Lites Evil +Litey Liteyr +Lithassa Lithuano Littens +LittieTover LittjeterRS Little +Little Allie +Little Flirt +Little Jaxon +Little Knob +Little Sloth Little Snor +Little Ticks +Little Twig +Little meow LittleGhosty +LittleIron +LittleNudger +LittleTrev8 +LittleWillis +LittleZorro Littlebluefe Littleblueju Littlechirru Littlefarms1 +Littlefire01 Littleguyz +Littletickle +Litto +LittyNoCap Litvintroll +Lium Liuo Liutkemenas +Livahpewl +Livand Live +Live Jaked +Live Moose Live2Win Live4thefigh LiveItRight LiveLoveAsap LiveYourLife +Livedasniper Livepan +Liverpewle +Livey +LividPharm Living +Living Life +Living Lust +Livingenemy +Liviu230 Livvii LivyLo Liwyn +Liyum +Lizard Siege +Lizily Lizinginis +Ljb Ljudmila Ljuu Lkarch +Lkky +Lkn Lkoi +Lkue LlHAPIIRAKKA +LlLY ALLEN LlLYUFFIE88 +LlMEWlRE +LlNT LlON +LlSA ANN FAN LlTEWORK LlTT +Ll_lK3 Lla234 Llama +Llama BTW +Llama Pharm LlamaDawg LlamaMcfenis +Lleucu Ann Llirik Lloydyy +Lluuk1 +Llychlynwr Lmao Lmaz +Lmfao Lmlxlk +Lmmortai 07 Lmsjfjksdnhb +Lmurs Lncln +Lng +Lo Kii +Lo My God +Lo cation Lo07er Lo0pyy LoGiiKBah LoPintos LoadMySkeng +Loaded Loadizzle Loadstar LoafOCelery +Loathed Kmd +Loathing +Lobb Dad Lobby +Lobby Two +Lobo Blanco +Lobo Sonora LoboStark1 +Lobot96 +Lobotomizer +Lobstars +Lobster12 Lobstero Local +Local FEmale +Local Idiot LocalHero7 LocalJoint +Locale Lochi LockDownLife +Lockdown v2 Locko Lockpicks Lockski +Locksnap Lockssley +LocoDoritos LocoHamsterz Locococonut +Locothegenie +Locrian +Locton +Loda Lodarion Loders Lodestar Lodestones +Lodgehunter +Lodiedoo +Loebas Loeffen +Loez +LofaBred Lofi Log62 LogHog8 +LogHunterKaz Logan Logan2x Loganator34 +LogansPrayer Logavano LogiTekton +Logia LogicTerror +Logical God Login +Logitech +Logitekton Logless Logos13 LogsKnog Lohan Lohkey Lohruken +Lohwi Loikoi +Loikoi Lee LoisGriffin1 +LokieDokie +Lokolow Lokos +Lokrand Lokur +Lol Ur Dead Lol466 Loladactylll +Loldg Lolek +Loli Cox +Loli Neko +Loli Pantsuu Loli-Remain LoliChan LoliElie LoliStrangla Lolicons +Loligagging Lolipoparty Lolitsleeroy +Lolmanever Lolmc Lolopipop Lolwierdo Lolwuts +LomLy Lombachs Lombardi Lomborghini +Lome +Lomobuu Lompardo Lon3y Lonan +Lonan Arikos Lone +Lone Gym Rat +Lone Lee Axi +Lone Pop +Lone Requiem +Lone runkero LoneCorp LoneMage LoneStarWit Loneful +Lonehenge922 Lonely +Lonely Eevee +Lonely Neo +Lonely Norms +Lonely Ride +Lonely Salty +Lonely Slave +Lonely Table +Lonely Tugs +LonelyLight LonelyOnT0p LonelyRS +LonelyTugs Lonelyy +LonerSushi +LonesomeSoep +Lonewolf117 Long +Long 4skin +Long Demon +Long Ol Dong +LongBoneee +LongRodGod +LongSnapper +Longbow +Longest Head +Longie Longjohnz +Longmeatlog +Longnech +Longo Doggo +Longstaf +Longsword950 +Longview Longwave +LongySlongy Lonjick Lonksu Lonz +Loo p LoofiePoofie +Loofoo +Loogs Loogy Look +Look out bro Looked Lookin Lookingman @@ -13591,62 +28466,166 @@ Lookn4Puzzy Lookout Lookup Loon +Loon Master +Loonetick jr +Looney278 +Loongstickyy Loonlette Loony +Loony RS +LoonyLunar Loonykilla +Loonyluke5 +Looolo LoopGoon +LoopSwoop Loophole336 LoopieFish Loopy586 Loose +LooseAnos LooseLesley +LoosebuLdge +Loosh +Loot Chemist +Loot Party Lootcifer Looted Lootedyou2 +Lootorz Lootrich Lootsharing +Lootsi +Lootski +Loox +Lopmkinjubhy +Loppy Killer +Loquwsea321 Lord +Lord Amonite +Lord Bees Lord Buud +Lord Bv +Lord Caldlow +Lord Conte +Lord Cryer +Lord Cypher +Lord Devil +Lord Doofy +Lord Elfen3 +Lord Extropy +Lord Grefven +Lord Grim +Lord Grofyth +Lord Guam +Lord Hents +Lord Jebbe +Lord Joona2 +Lord Jostyh +Lord Keithus +Lord Kratos +Lord Loss +Lord M0RG0TH +Lord Mantra +Lord Masonic Lord Mjosh +Lord Of Cows +Lord Pengu1n +Lord Pillow +Lord Richie +Lord Runes +Lord Shayne Lord Tarkus +Lord Valzin Lord Vioarr +Lord Vishnu +Lord Xeth +Lord Yaksha +Lord Zq +Lord iFlex +Lord kuro +Lord polak LordArtonius LordAusticus +LordBaphomet LordCoffee2k +LordCorreia +LordDanko +LordDaxel +LordEpic69 +LordFarquxd LordFoxy LordGuthanPK +LordJRazE +LordJuba LordLambo91 LordMullett LordNorden LordOfHarems LordOfOtakus LordPh1L +LordPolgoth LordQuinker +LordScoobert LordShrubber +LordSloppy LordThyas +LordUSA LordYawgmoth LordZahard Lordalbert0 +Lorddraconal Lorde Lordjoeman +Lordkaes Lordstails Lordtwinky +Lordy Flame +Lordy608 Lordza Loredon +Lorehold Loreland Lorencia Lorenz +Lorenzoh sr +Lorenzokazoo +Lorithean Lorkaa Lorki +LorqueldIM +Lorre46 +Lorry +LortJob Lorttomies99 +Lorvikatari Lorwic LosAngeles Lose Losel +LoserKid Loshambo +LosinAllHope Losing +Losing Fat +LosingXP +Loss1525 Lost +Lost Angel +Lost Baby +Lost Baggage +Lost Logan +Lost My Baby +Lost My Sock +Lost Oliver +Lost On You +Lost Roomba +Lost Snail Lost Tadpole +Lost Weed +LostBank +LostBankKey +LostChad LostCloss LostDude28 LostHalls @@ -13655,258 +28634,608 @@ LostMoon LostOcean LostOnThePCT LostSauce +LostStatus LostVorki +LostandFound +Lostdog03 LostlSoul +Lostpetrock Lostplzhelp Lostrelic93 +Losty99 +Lot of Beans Lothariou +Lotilyx Lotion +Lots of Eggs +Lotsa Regret +LotsaOSRS LottaPotAgo Lotto Lotu15 +Lotus bless LotusKid +Lotwik +Lou Le Dur +Lou Red Wood +Lou Sputho1e +Lou Surr +LouBug LouSass +Louezzi Loug Lougle LouiVui +Louie Bags LouieMurphy Louiec3 +Louiseyy Lounckie +Loupak +Lousy Drunk +LouvicDank +Louzy +Lov ed Love +Love Caley +Love M Poker +Love Roman +Love Taylor +Love Yourz +Love me +LoveMyAnzaa LoveThat +Loveable Lovelili Lovely +Lovely Clawz +Lovely Cola Lovepoot +Loverboy Loveskillin Lovexdragon Lovey +Loveyan823 +Low Alched +Low Chief +LowBaller LowKeyPickle +LowLifes +LowPines LowPower +LowRunEnergy +Lowanse Lowballz Lowercase Lowery +Lowfield19 LowkeyBallin Lowlander +Lowlife121 Lowlux Lowner +Lowrey73 +Lowstar1 Lowtempterps Lowy +LoxoJ +Loxtos +Loyal2pvm Loyalcaptain +Loyd Nichols Loze +Lpfan Lrauq +Lrian +Lric Eotter Lron Lronic +Ls4 LsummerC +Lsv +Lt Burgers +Lt Golpar II +Lt Mantas +Lt Purekarys +Lt-Iron-Lt6 LtCastiel LtJan +LtRemigijus Lt_Torch +Ltfreggin +Ltk Iron Ltman42 Ltmf +Ltufighterlt +Lu Diabla +Lu be +Lu0nto +LuauKing +Lub Lub3edUp +Lubbz Lubed LubinLen +Lubos +Lubosek Luc4rio LucSynthesis Luca +Lucaemar +LucarioLVL X Lucas +Lucas Solo +Lucas1192 Lucasmelo11 Luccaa Lucho Luchtloper +Luciah Lucid +Lucid Cynic +Lucid Dream +Lucid Josh +Lucid Meme +Lucid Truths +LucidFeels +LucidPie Lucidcr Lucidfever LucidityX Lucie SkyDia +Lucifenrir +Lucifer v2 Lucifer06 +Lucifer4Real Lucifer_link Luciifer Lucil +Lucina +Lucipur Lucivert Luck +Luck Lost +Luck Voltla LuckRunsAlt +Luckario Luckd0ut Luckeh Lucker LuckieStein Luckless Luckpvm +Luckscaper Lucky +Lucky Arian +Lucky B Boss +Lucky Bambam +Lucky Baws +Lucky Cash +Lucky Chance +Lucky Clover +Lucky Clown +Lucky Duck +Lucky Greg +Lucky Kev +Lucky Link +Lucky Lombax Lucky Lukey +Lucky Mofo +Lucky Rabbit +Lucky Sofa +Lucky Yoru +Lucky skrue +Lucky when LuckyAce LuckyDog +LuckyDog x LuckyEmerald LuckyKroketa LuckyLackey LuckyMatch +LuckyNrSeven +LuckyVic Luckybamboo1 Luckynuts Luckyxx +LucoUK Lucyfer22 +Luczzs +Lud a +Luda-Dan Luderan Ludo +Ludo Sand3rs Ludomo +Lueis +Lueke LuffyAce LuffyDMonkey Lufidius Lufue +Lug RS +Lugal Ki En +LugiaWaifu Luglys Lugs Luider Luigihbk Luis +Luis Anico +Luis Antonio +Luis Dk LuisFarm +Luis_Vzla Luka LukaBrasi Lukas +LukasFlux Lukaz Luke +Luke S Luke3 LukeOS Lukeee LukefonFabre +Lukeh Lukeicth +Lukesfish LuketheDM Lukey294 +LukeyUK Lukezz LukiOne Lukiekuipie +Lukio W Lukiss Lukoo911 Lukse Lukytisz +Lulani 13 +Lulla Lullie +LuluTheCat +Luluca Lulucifer +Lumber Yak LumberStevo +Lumbidge Lumbo Lumby +LumbyCalled LumbyCastle +Lumbys Waits Lumiaris Lumifrost Lumimies +Luminatti +Lumm1475 Lummer Lumo +LumpiaFan69 +Lumpqua +LumpsMcgooey Luna +Luna Koneko +Luna Lucero +Luna Mexi Lunacy +Lunaec +Lunamarie Lunar +Lunar Haze +Lunar Lotus +Lunar Tear +Lunar Tones +Lunar Ursa LunarDemon99 LunarEquinox LunarSC2 +LunarTheCat LunarTigerr +Lunarann +Lunarcrow614 Lunardini Lunarism +Lunarmoat638 Lunate Lunati Lunaticmo1 Lunatric +Lunaverse Lunch +LunchboxLLC Lunchtime007 Lund LundXCV Lundh Luneasa LuneyTunez +LungTied +Luni +Luniaxis Lunie +Lunier Lunis Lunizzzz +Lunytic +Luonteri Luonto Lupah Luper +Lupi +Lupo +Lupuloid Lure2G +Lurjus LurkinTurd +Luru +Lush Vibes Lusitropy Luskidoo +Lussen1 +Lustwaffle Lusu LusyTheGoat Lutha Luthien +Luthien T2 Luthors Luthstorm Lutinrouge Luucy Luud Luukie +Luuloterve Luuseri +Luuuseri Luuuuna Luuwana +Luv2spuj +Luver Focker Luvholic Luviii +Luwucy +Lux Please Lux211 Lux7thSaga Luxatio +Luxeo +Luxilie Luxire +Luxoul +Luxumine Luxury +Luya Luzu +Lv ranger +Lv 5 Psyduck +Lv Camo Lv100 +Lv100 Raichu +Lv5 Treecko LvI3stak3 +Lv_1_Mew +Lvcretivs +Lvl 1 +Lvl 3 Nub20 +Lvl 99 Goon Lvl100cheese Lvl30Ditto Lvl99 Lvl99Docking LvlUpUrself +Lvls Up Lvqquvs +Lwy Lx1I +Lxbe +Lxfleur +Lxnes +Lycix +Lycoe Lycstoned Lyct LydeZGrod +Lyderis Lydia +Lydia Kenney Lydmix +Lyfe Tyme Lyin +Lyin Eyes +Lyke625 +Lyks +Lymaks +Lymez +LynX ZrLeX Lyna Lynamet +Lynching Leo Lyngo +Lyni Lynics Lynx +Lynx Jitan +Lynx Tiger +Lynx Titan LynxTitan Lynxes +Lynxy LyraLyraLyra +Lyrad002 Lyrich Lyricidal +Lyrilusc Lyron Lysandra +Lysdexic4986 Lyse +Lysmann +Lyyli PL +Lyzu Lzin +Lzs +M A G 3 +M 1 KE +M 3 3 P +M 4 T R I X +M 8 A 1 +M A D O X +M A D Storm +M A T E J +M A X O U T +M A X PAYNE +M B Z +M E H I S +M E L D O +M E T R O +M E X I +M I K B A R M I T H O X +M I U M I Z Z O U +M INDGAME +M Itty +M K J +M O B I L 3 +M O C 0 +M O C H +M O ID O K +M R NaCl +M Super Buu +M T C +M U D K l P +M X G P +M a V 3 Rick +M a d Shrumn +M a k a i +M age +M aikel +M ak0 +M ammoth +M ana +M ankDemes +M anu +M aples +M arcel +M arquim +M artin +M ask +M athis +M axou +M azzz +M c +M elz +M enzy +M ga +M gh +M i t c h y +M i y a +M ikasa +M ike +M imik +M int +M itchel +M ittens +M l Q Q +M merz poL9 +M o C e +M o r t e n +M oist +M onkfish +M orytania +M the Maxed +M ugger +M ulas +M urphy 2 +M usashi +M-theory +M00CHIE +M00SE M00SE +M01 M0IST +M0IST B0X M0LE M0NALISA +M0NEYM1TCH3 +M0NST3R1PP3R M0ON M0ONCAKES +M0R TEN M0RG0TH M0RGE +M0SS3Y +M0ST D0PE +M0hannad M0ist +M0ist Midget +M0ney Swag +M0nk3y DLufy +M0nke y +M0nkey15 M0nsterTuk +M0obs +M0resheth M0rningstr +M0use M11CK +M11ka M1911A1 +M1GU M1NG3_GOO +M1TTLE +M1ch M1gos M1ke50 +M1ksu +M1nd Master +M1ntberry C +M1ss Di0r +M1stak3nly +M26 +M3 L M30W M30z +M3GAD0UCH3 M3L10DA5 M3MEL0RXD +M3MoRY M3X1CO M3XICO +M3ch4nics M3ll3 M3lllll M3lviin +M3ntal M3rking +M3ry +M3t4l1n1S M40A M4D399 +M4g3 +M4g4z M4gnus666 M4k3d0 M4tte M4xt0R +M5 +M52 M523 +M6 Mill +M6N +M7J +M7TT M855A1 M8NoFreebies M8TT +MA N E MAAAAK +MAAGES MACKOGNEUR MADLADz MADRNGJACK +MAESTR0FRESH MAFKINCHAMP MAGA MAGA1292011 @@ -13919,140 +29248,275 @@ MANT4S MARCOPOLO MARLB0RO MARMlTAO +MAS0N MASKED +MASSGAINER32 +MASTER DREAM +MASTER J0KER MATUTVlTTUUN MAURERA79 MAUROPICOTTO MAX3D MAXABILITY +MAXED PINOY +MAXXEDDADDY +MAX_HER0X +MAXlME MAlNEVENT MAlNTENANCE MC Cheep +MC catheter MCBURNOUT MCHammered MCKenny91 +MCSIZZLE +MCmattt +MD7 +MD96 +MDE Presents MDPS +MDaher +MDucks +MEAT G0D +MEAT HEAD36 MEGATRON MEK4KK4KK4KK MELAN00MA MELT METM0NKEY +METR0lD +METS0 +MEV4NS MF DC +MF MORTEN +MF SofaKing +MF TEE +MFE +MFKU +MFLI MFSTEVE +MG5 MGFS +MGKRevs +MGM WAY +MGreengrass +MH Therapist +MHA C +MHBC +MHS MIDAs MILFmauler MILSHAKE MINH +MISOGl MISSYGAMlNG MIST MITCHY MIX0R MJ23 +MJKaboose2 +MJT MK-HARDSTYLE +MK6R MKAM +MLB +MLTEEZY +MLaidman +MMMahogany +MMORPGenius MMTera MMitchh +MMtheMachine +MOABDADDY MOMHUNTER666 MON5TER +MOODSWlNGS MOOSEM3AT MOTM MP17 +MP9 +MPB +MR JOHN WlCK +MR LETHAL2u +MR REET +MR TMR MR UDZ +MR556A1 MRButter +MRC Tugboat MRGAMEZ MRHD +MRLARGE +MRM MRPlZZAPRIZE MRWHlTE MR_MAITO +MSPaint64 +MSceneFF MSpacePotato MStarkz MTBMB +MTPETE +MTV CRlBS +MTXP MUISSS911 MULHERndaEXP MUMM0 MURMELl MUSK MUSK0KA +MUSUMUMM MUZAMMIL +MV Flow +MV Welshy MVIII +MVKirby +MVP HERO +MVP Mahomes MVRDA MVTIASD MWwarzone +MY L U N A +MYRSKYVIITTA MYTHICROYXLE M_Sariol +Ma Band +Ma Dood +Ma Titi +Ma t t h e w +Ma5onx Ma7e +MaCoMb MaHeelsHurt MaJeShTic MaQtPie MaX662 +MaXam00se +MaXeDSani +MaXx0wnage Maacc +Maake88 Maanman Maasegyr +Maax2 +Maaxiking Maazako +Mabbbs Mabbs Mabel MableLake Maboe +Mac Diver +Mac Donald +Mac Garfield +MacDuff MacFredrik +MacFredrique MacMillers MacMoblins +MacRae MacSandwich MacTheRipper Maca +MacaFazoL Macabre +Macaron +Macaroni 73 Macaronni5 MaccaM +Maccaroni Macduffe +Mace Windu Macedo +Mach Sigma +MachV2 Machado Machfredy +Machine Girl +MachoTimo Machtig +Machtige Machtigeman Machtigemeid Machto Mack +Mack x +MackD +Mackadactyl Mackadee Mackdizzle99 Mackeo +Mackerel Sky +Mackerels MackhNL +MacksEntropy MacksIsland +Maclairin123 Maclas Macoinho Macre demia MacreedyLove Macromage1 +Mad Dog Eris +Mad Flavour +Mad Krampus +Mad Max 20 +Mad Papper +Mad Suss +Mad Vlad +Mad Watson +Mad X +Mad arrows12 +Mad as heck MadBoy20 +MadBruh +MadCanadian +MadChemist8 MadD0g11 +MadD0gL4d69 MadDogged +MadJeffs MadKingMikey MadMaxMan +MadPubes MadSnowman23 MadaRook Madaddam Madam305 +Madarah +Madd177 MaddAntelope +MaddMann5 Maddape Madddiieee Madden +Maddie Baddy Maddogjr Maddux Maddy +Made of Sand Made4Slaying MadeInAfrica +MadeYouClick MadeinTYO Madeiraa +Madeleine Madeweine Madhu Madlaina Madmaxie +Madness Max +Madodee Madona +Madra Madrock01 MadsG Madsenn Madsermad +Madshatter71 Madskillz756 Madslasher30 +Madslax2 Madsosaur Madula Madvantage @@ -14062,48 +29526,83 @@ Madysen Madza Madzilla Maeda +Maegera Maela MaerlinTaz Maertynas Maester +Maester Trea Maestro +Maestro Heil +Maestro1 +Mafia-BP MafiaMan MafiosiDad Mafooma Mag1c Mag1cJohnny Mag1c_W33d +Maga Kahn Magalator +Magani C Magawie Magc Mage +Mage Eh +Mage Kume +Mage N Skil Mage7master7 MageFish MageHax +MagePriece +Mager Magerold Magers Mages350 +Magestus +Magethirst Magezi +Magggorical +Magginator Maggot MagiTurtle Magic +Magic Bonus +Magic Clicks +Magic Mackee +Magic Moose +Magic Rino +Magic Tree +Magic Wand +Magic fTail MagicAppel +MagicMemorys MagicPanda91 MagicSchoBus MagicSilver Magic_Elmo1 Magical MagicalRuby +Magican Magicarp Magicbox Magicdefence Magicken +Magicx +Magija +Magik Magik773 Magikilo Magiok +Magisteerial +Maglet Magma +Magnaboy +Magnati Magnautism Magnesium +Magnesium J +MagnesiumIV Magneticism Magnetite Magni99 @@ -14111,99 +29610,217 @@ Magnifice Magnilo Magnis Magnu +Magnus Gram Magnusungam +Mago +Magsd1 Maguneru +Maguro Magus +MagusChum Magyk +Magzem +Mah Jae +Mah Jong MahSeed Mahalusa Mahanimal +Mahe Mahkelroy +Mahler +Mahmoud Mahogany +Mahomes +Mahonoken Mahtitykki Mahzius +Mahzka +Mai kel +Maiba +Maide +Maidenheir +Maignansdead +Maikel J Maikhol +MailTime Mailor Main +Main 3s +Main Cactus +Main Ginger +Main J0urney +Main Mynt +Main Natey +Main Pando +Main Path +Main Product +Main Twiddle +Main Wario MainCharlie +MainCoach +MainCringe +MainDong MainForever +MainHamendex MainHolm +MainJ +MainMan_Mads MainNudley MainPurp MainSt MainStand +MainStreamx MainWabbit Maind Maindeer +MaineDeno +Mainline Mainly +Mainly Pure +Mainly Ricky Mains +Mainslet +Mainuru Mainz +Mainz Gainz3 Mair +Mair017 Maisa +Maisa Torppa Maisteri +MaitoRimpula +Maix +Maizon Maizpilao01 +MajMischief MajQ Majakanvahti Majcew +Majcew 2 Majehjk +Majer4 +Majin Buuwu +Majinbooo Majinjon +Majki Majokko Majooty Major +Major Damien +Major Gains +MajorEar MajorMammoth +MajorObesity MajorOwnz MajorSnizz +Majora MajoraMasked +Majoras WRLD Majzako7 +Maka +Maka2201 +Makagago Makaule Makaveli +Makaveli I +Makaveli II +Makaveli l Make +Make A Pile Make Carrion MakeItStack +MakeMeKing MakeNotes Makeboy +Makeeesful Maken +Maken Gainz MakenMakkara +Makenna +Makhachev +Maki Makilake +MakinExcuses Makiverem Makk Makke Makkeii +Makker Benja +Makker Trane Makkiavelli +Mako Nox +Makoea +Maks Cape +Maksimit +Maksoinvelat Maksuamet +Maksui Maksukka +Makzd MalaLechita +Malachai Maladec Maladiec +Malagah Malbec Malboulgea +Malcz Malding Male Maleurous Malfoy +Malhavic +Mali RS MalibuMan96 Malibuux +Malignant00 Malik Malinerix +Malitiae +Malkav Mall +Mall Gang +MallbuRo Malleus Malli +Mallieero69 Malloc +Mallomar Malmi Malmot +Malomalo +Maloo Malqy Malse Malt +Maltapkiller Malteadita +Malter +Malterz Malucoftw +Malurian283 Malvian +Malvidus Malvoliuus Malware Mamachii +Mamas Meat Mamba +Mambaaaaaa MambasWRLD +Mambo No5 +Mamboita Mammad +Mamoul Mamupatja +Man Asian +Man Bag +Man Killa77 +Man Kip +Man Raccoon +Man Throater +Man gos +Man-Yak ManBearPiggy ManGoBzzzt ManOfGold @@ -14213,20 +29830,30 @@ ManWT ManWoox Manaburna Manafont +Manakiel ManakuraJP Manantti123 Manantti321 Manardog Manawatu +Manby +Mancandy +Manchest Mancino Mancunion92 Mand1ng0 Mandelbrot +ManderSala +MandoCheese Mandor1 Mandred Mandulorian Mane Manegaming +Maneirinho +Manelzera +Maneter56 +Manevolent Manfa MangJoe MangeMeister @@ -14234,95 +29861,179 @@ Mangle Mangled Manglican Mango +Mango Monkey +Mango Rat +Mango Season Mango10 Mango1997 +Mangobnana +Mangostangos Manhoos Manhunt +ManiacBison +ManicNode ManicRS Maniek Manila Maniwani +Manju Manke Mankitten +Manlanter Manletti Manly Mannekeuh +Manni Penny Mannie +Mannix270 Mannjpip +Mannnekala Mannowrath +Manny21 +Manokin Manor +Manorvic MansaMusa Manser2300 Mansup5 +Manswarm Manswers Manta +Manta Wray2 +Mantarayo MantasA +Mantaslocoo Mantelio8 +ManteliseXe +Manthe MantorokDIA +Mantoshka Manttt Manuelh3 Manumatti +Manx_Scaper Many +Many Walrus Manyi Manyvids ManzGotViewz Manzo +Maose +Maozn +Mapanza1 Maple +Maple Jay +MaplePoutine +MapleRoyals +MapledOaf Maplejuana Mapletech Mapne Mappl1n +Mappzz Mar0e Mar782 Mara +Maracruz Maradonaa Marassa Marathonius Maraud Marblez Marc +Marc NL +Marc Paul +Marc Spac MarcVinicius Marchmello Marchuk +Marcia Ress Marcikarp +Marcilicious +Marcius 7 +Marco225 +Marco7k Marcoli64 +Marcoo Marcooow +Marcos Vibe +Marcski +Marcussius Mardiie Marducas +Mardy O G Mardzz Mare +Marenki +Maret Marg3 Margana Marganer +Margiella Margins +Margodx +Margon +Margonite Xu +Marguana Marheim Mari Marianas +Mariano 1 +Mariasonic +Marib +Marijuano +Marikadere Marines Marinez +Mario Bros +Mario Goatse +MarioKartDD MarioTennis Marioh MarioisKewl +Marioman Marioneta MariosPeach +Maritime +Maritozzo +Marjapuuro +Marjatta +Mark Pledger +Mark Swenson +Mark-777 +Mark-Zuk +Mark0vDeath Mark12387 Mark1ta +Mark5Barki MarkBuns +MarkJongejan Markald87 Marke Markerr +MarkhamON Markie994 Markipedia +Markku Marklyft +MarkoOSRS Markop100 Markovia64 +Marks Main +Marks Phone +Marks lron Markus +Markus Stier +Marky428 Marlbrozo Marleth Marleyy Marlin1993 +Marlon0817 MarlonisGod +Marlooo Marlopped +Marluxia Pwn Marmita99 Marmp Marms @@ -14332,40 +30043,66 @@ Marni Maro202 MaroO Maroj +Marokkaan Marokkaantje +Maroko111 Maroon5 Marpollo MarquiseDmnd MarrCuzz +Marrcy +Marreldil +Marrer Married Marrio +Marrius Marro75 Marsal Marsalkka +Marsel Marsg Marsgl +Marsh Marrow Marsha Marshal Marshall1 +Marshmont Marshyy MarskiLark Marsmash +Marsovec +Marstead +Marswatt Mart0103 Marten +Marten x MarthProMonk Martial +MartianLynch +Martiba +Martiiian +Martijn Martika Martin +Martin 2007 MartinGameTV +Martindeq Martinjsh Martinkyle20 Martins Martinside +Martip MartnShkreli +Marty +Marty150 MartyG MartynMage +Martyr Main +Maruna Marv Marvelli +Marvick +Marvins Dad Marwan Marwin MarxRoux @@ -14373,16 +30110,22 @@ MarxTheMyth Mary j4n3 Maryj Maryland +Marylandd Marzcorw +Marzeo Marzhy +Masaca Masacre599 +Masade Masago Masakado Masandalf Maschok Masconomet +MaseLitt Maserati Mash +MashedOP Mashimarq Mashiwo Masin @@ -14390,31 +30133,57 @@ Masiron Maskedpump Maskin Masochisttwo +Mason OSRS MasonJarr Masonatorr Masonitte +Masons Dong +Masoo MasquedMan +Masryy +Massa +Massacre Fc +MassageMan97 Massif +Massimo130 Massinissa7 Massive +Massive Noob +MassiveJonas Masss Massterduel +Mast3rOogway MastaHeff Master +Master Bakes +Master Bogs +Master Byro +Master Garni +Master Jos +Master M V +Master Riven +Master Skizz +Master Vates MasterB1994 +MasterBarter MasterBlazee MasterDragxn MasterGrogu MasterKiefff +MasterMake +MasterMasa2 MasterNeigh MasterOzzy +MasterPanda MasterPookie MasterRooshi +MasterSlayrr MasterThresh MasterX Masteragota Masterbihno Mastercat +Masterdemon4 Masterflick Masteri MasteriMori @@ -14422,43 +30191,79 @@ Masterkindem Masterrgod Mastervile Mastirida +Masturbeerke +Masurda Masuro Masylvain +Mat 1 +Mat Jacko +Mat Share +Mat thew11 +Matchbox 20 Mate Matematikk +Materium Mateusz1210 Math +Math Is Fun +Math ematic MathVibes Mathcore +Mathematics Matheor Mathers Mathers1996 Mathew Mathias +Mathias Nemo Mathisse Mathmic Matholemeu +Mathrotus Matieus Matix +Matkijanarhi Matmo +Mato Seihei MatoPotato Matoaca Matrak +Matreex Matrix Matrixpachi Matruusi2 Mats +Matsu Matsuri Matsyir Matt +Matt 162 +Matt Bman +Matt CFK +Matt Cat +Matt GIM +Matt K +Matt Lad +Matt Mo +Matt Slay +Matt Smash +Matt V +Matt Wy +Matt1494 MattLeedz MattMattBro +MattNDew MattRanger MattRoux MattSeal7 +MattStyle +MattWallet Mattaclysmic +Mattakuda Mattam66 +Mattaroo Mattec +Matteos1 MatterOfTime Matternot Mattex @@ -14468,29 +30273,52 @@ MatthewDK MatthewRS Matthewwww Matthidan +Matthis +Mattias Mattice +Mattie osrs Mattie43 +Mattj Mattniss Matto +Mattor Mattorel Mattrate Matts +Matts RNG Mattsbro Matttbob Matttt +Mattty +Mattus50 Mattx1 Matty +Matty A Matty Gibbs +Matty Ic3 +Matty467 +MattyChasee +MattyLight91 +MattyNW +Mattych Mattyflight Mattys +Mattyz6 +Matu btw Matuba Mature Matwo +Matygoyo Matz +Maub1 +Maucca Mauddibb Maui MauiBeach +MauiMallard Mauidude +Maukas +Maukka MaukuMaija Maul 0n Top Mauler4500 @@ -14500,80 +30328,234 @@ Mauna Mauno Mauricio555 Maury +Mauvayy +Mauvier +Mavdagin Mavel Maven Maver Maveric Maverrick +MavicAir +Maviie Mawch Maween +Mawie +Mawlocke +Mawn +Mawsen +Max 4 Mikey +Max Ape +Max Attacken +Max BD +Max Blacks +Max Botter +Max Cape +Max Deiron +Max Eff +Max Entropy +Max Gadget +Max Gav +Max Here4Pet +Max House +Max Karma +Max Klett +Max Methi +Max NoLyfer +Max O7 +Max Obi +Max Pkr +Max Puffs +Max Re3oo +Max Relax +Max Scape +Max Snek +Max Temper +Max The Hero +Max Tilting +Max Tonks +Max Vandal +Max Weezy +Max Wotif +Max XP +Max Zack +Max Zeus +Max btw +Max cape 420 +Max hits +Max killz6 +Max plus +Max uwu +MaxAchoo +MaxAnarchy MaxBTW +MaxBadAss +MaxBear MaxHare MaxHaus +MaxHomieJose MaxIgnorance +MaxIrl +MaxKhalifa +MaxMainJake +MaxMuffin MaxNeander MaxSAVAGERY MaxTix MaxTurbo +Maxchar +Maxd Maxe2968 Maxeado Maxed +Maxed Beans +Maxed Code +Maxed Egirl +Maxed Emm +Maxed Eric +Maxed Groot +Maxed Hippo +Maxed II3en +Maxed Jeff +Maxed Kiraly +Maxed Loser +Maxed M0bile +Maxed MVP +Maxed Masak +Maxed Newfie +Maxed POH +Maxed Phells +Maxed Rat +Maxed Rob +Maxed Scaper +Maxed Spyike +Maxed Total +Maxed Twice +Maxed Velho +Maxed Whip +Maxed Zeb +Maxed Zuk +Maxed osrs +Maxed when +MaxedActuary +MaxedBruh +MaxedBurnout +MaxedButPoor +MaxedFrog MaxedIn2074 +MaxedInDa6ix MaxedMain MaxedMax751 MaxedMike +MaxedMobile +MaxedNbored MaxedPleb +MaxedRepel MaxedYP Maxedlegacy +Maxedtoasty +Maxedwell Maxell Maxerder Maxiboy4a9 +Maxidy Maxime5100 Maximonster Maximum +Maximum Tier Maximumist +MaximusAM +Maxinator87 +Maxing zzz +MaxingMyMain +MaxingSucked +Maxingthis Maxiorek1200 +Maxisbaws +Maxisen +Maxitaxi777 Maxiu Maxjuhhhh19 +Maxkenzi Maxmemix Maxnominus Maxo +MaxoBlasto +Maxoou +Maxpappy Maxpro Maxst Maxstalker67 +Maxstatz +MaxtanosXD Maxwall Maxx +Maxx y +Maxxed Alt +Maxxed Dusty +Maxxed Trash MaxxedNoob +Maxzet MayanFuror +Mayate +Maybe CIA +Maybe Idiot +Maybe Jeff +Maybe Shady MaybeMason MaybeMitch Maybemnam Maybez +Maybizzle Maybon Maydole +Mayerdynn +Mayhaps Mayhem +Mayhem Maker MayhemMakers Mayl Maylive +Mayo +MayoForFunds Mayonaz Mayor +Mayor Jiwana Maytona +Mayuri +Mayushii Mayvex Mayweather Maz0n1k Maza Mazala +Mazande Mazariner +Mazauu +Mazda168 +Mazdan +Mazdaspeeed3 +Mazdraith +Maze +Maze of Iron +Mazel613 Mazersyy Mazhar Mazlol +Mazmarazor Mazoni Mazpls Mazta Mazuma +Mazz y Mazzacre +Mbox Mbyoo +Mc Dragans +Mc Florry +Mc Red McAlakazam +McAsssBlast McBurn McCheddabomb McChimkenGOD @@ -14581,204 +30563,402 @@ McChubbin McCllin McConaughey McCreJ +McCringle McCune McDanky42O McDizzle15 McDongles +McDoodle_21 McDouble McFantasy McFizzleDady +McFly93 +McFozzar McGooser +McGorm McGregor60gs McGruff +McHammock McIllu +McIronLeech +McKennon +McKerma +McLOVlN +McLaeNz McLeaNz +McLemore +McLovin707 +McLowry McMeekin McMillan McNeal +McNoob10 McNoodle +McNorm McNugget McP0P0 McQuaker McQueensy McRibs +McRibs Back +McRip +McSchloogan +McShrubbery McSomf +McSplitter McStarley McSuperNoob McTaskupillu McThomzie +McVittties +McWeaksauce +Mcards Mcbelsito Mcberra Mcdally Mcgingerpony +Mcgregorini Mckelvie Mckinconn Mclaren88 +Mcneill Mcpatrice12 Mcpielover Mcturdson Mcwaffle1 +Mcy +Mderg +Mdub Suhh Mdzvwz +Me Acoustic +Me Ca +Me Dead +Me No Brains +Me Woody +Me and Jr +Me lvin +Me phisto Me3lem +MeBigPoppa +MeBlast MeMillionthD MeThudZ +MeTwo MeadowFall Meadows MeagerSkills +Meals Mean +Mean Crusher +Mean Street Meano +MeanrangerFE Meap Mearm +Mears Measles Meat +Meat Rat +Meat Shank +Meats Meatspot MeatyLoaf +Meauner +Mebo Mech +MechantBozzo +Mechaodin Mechelen +Mechvengance +Mecidon Mecone Mectofion +Meddler +Meddlr +Medi Mobile +Medi i +Medi ocre +Medical Herb Medicate Medicides Medicinal +Medicore +Medievh MediocreMatt MediocreRye MediocreTime Medispensary Meditations +Medium Cloo +Medler Medoletics Medon Medorable Medusa228 MedwayDragon MeechIsCute +Meechy Dark Meeeseek Meelays +MeenBeans +MeepBeepMeep +Meeran Meerca +Meerkz Mees126 MeesKees MeetMyMeat +Meetti Meew +Meewerp +Mefaustofele +Mefco Meftah Mefy +Meg 3 Mega +Mega Butt +Mega Farce +Mega Kyle +Mega Mort +Mega konn MegaAmpharos +MegaDoris MegaDrive MegaMustarn MegaNaziHatr Megabyte6 Megadwarf47 Megalo +Megalodont +Megamanyo Megamind +Megamind Jr Megans Megaronii +Megastoffe +Megatortle Megatrax +Megis Megnificent +Megpan Megumin Megustio +Meh Noob +Mehrunes Mehts Mehuelin +Mehuo MeideC94_BB +Meido Mein lron +Meinkul +Meiousei +Meister Sho +Meiyo +Mek +Mekaanik Meklo Meksa +Mel Meow +Mel Yakutia +Mel btw +Melanderr Melanoma +Melayna +Melc0n Melchuzz Melcoor Meldianx +Meldynoir Melee Melee_Range +Meleny Meleven Melhoop +Meliodas420 +Meliodin Melisma Melk +Melkin Melktietje +Melkzuurtje Mellakka Melleruds Melling +Mello Gello +Mello Yello +Mellodynamic +Mellow Jingy +Mellow Tones Mellow6 MellowSoul MellowTokes Melly +Melly YNW Melo +Melodicolt Meloenschijf +Melongrab +Melotoninn Melpan +MeltedCash Meltman Meltok +Meltryllis +Melvin dew +MelvinTheOK MemberBerry Memberlist Meme +Meme Loord +MemeDoge111 +MemeVendor +Memedalorian +Memem3 Memeologist Memeshake +Memmor Memory MemoryCard MemoryWorm +Memphis lol +MemryLoss Mena Menap Menaza Mend +Mendicant Mendieton +Mendokusai +Mendota Meneer +Meneer Nijn +Menesus Menetoeihin +Menial Luck +Mennie Menrey +Mensphysique +Mental Coach Mental4Metal MentalAbacus Mentally Moo Mentalmissy +Mentoes +Menyu Menza +Menzola +Meoooow +Meow Ghost +Meow Im Hawk +Meow Softly MeowKiki Meowed +Meowgi +Meowler Meowmagic +Meowrijuana +Meowskeys Meowtheduck +Meowzer7 +Mepiff +Mepn Mepthadr0ne Mer Train +Merami fan Meramon +Meraxus +Merbz +Merc-Raa +Merc_Lobo +Mercedes F1 +Mercenary V Merces +Merch MerchantUrch +MerciTwingo Merciulago +Mercphobia Mercules +Mercury Owl Mercury15 Mercy +Mercy Osrs +MercyfulFate Mercys +Merderr +Mergician Meric Meridians +Meris Merisalu Merisorax Merkdalat +Merke +Merked Ko Merksick Merlin +Merlin Otter MerlinMonroe MerlinPT Merloc21 Merlucius +Merlvin Merricat Merry MerryTuesday +Mersunperse Merten Mertguy2p0 Mertiin +Mertjaars Mervyn Meryam Meryath Meryl +MesH3aL Mesa +Meshi510 +Meshkot +Mesin +Mesmeriize +Meso cyclone Meson +Messaa Messersmitti +Messi Messias +Messorium Mestari +Mestaristick +Mester B MesterAbekat MestreGlados +Met Promise MetDoobie Meta +Meta Mammoth +Meta l +MetaCTF +MetabolicPro Metadragon Metafisico3 Metagel Metal +Metal Booty +Metal Little +Metal Shad0w MetalGear +MetalMaiden3 +Metalest Metaling +Metallic Neb Metallifog MetallikDeth Metallproz Metalproz +Metamorphic Metamorphs Metamushroom Metaphwoar @@ -14787,45 +30967,89 @@ Metaxia Metbol Meteora Meteoriitti +Meth Teeth +Methal Methodical +Methusal Methylanara Metix Metoprolol Metropolia +Metsavaras Metselaar Metsiq Metters +Metukka +Metzifer Metzz +Meulendijks4 +Meune Meuosh Meur +Meuyou +Mevvz MewIlicious +MewPulse Mewby +Mewli Mewllicious Mewrad Mewtwo MewtwoKing Mewww +Mex Arkantos +Mex_N_Flex Mexicanchild MexiePie +Mexlet123 +Mextex +Meykaa Meymer Mez-qt Mezane Mezecs +Mezenburn Mezeroth Meziriti +Mezmereye +Mezomel Mezy Mezzalarry Mezzito +Mf Fe +Mfey +Mfin Taylor +MfknNewports +MgZz +Mglegolas +Mgn +Mhh +Mi Hoy Minoy +Mi1os +Mi3pelst3in +MiAdidas MiIIenia MiIIers MiQuu MiTDro +Mia Kalphite +Miacon +Miami 305 +Miami Cane +Miami Rebels Miasm +Miawnation +Mibs +Micaso +Miccolo3 MiceMan +Micecream Micella Mich +Mich Bz Mich49 Michael +Michael4655 Michael67676 MichaelB MichaelScarn @@ -14838,103 +31062,203 @@ Michanderma Michano1992 Michaud Michel647 +Michelau +Michelle jnr Michiel +Michiel_96 +Michinaki +Michism Michlenn +Michxa +Michy Man +MickZagger Mickael +MickeyJoe Mickeyr4nge Mickul Mickyy Micosa Micro +Micro Cosmic +Micro Nerd +MicroButt420 MicroShrooms Microdot +Microgolf +Microman0000 Micromelo1 +Microo +Micropyle +Microsoft22 +Mictie +Micxyz +Mid Fade +Mid Pack +MidValley +Midareru Midas224 Midday +Middelkerke Midget +Midget Bones +Midget Rave MidniteGreen Midori +Midori Enju Midside +Midway16 +Midweeks +Midwife Dan Miega +Miegalius Miekka Mier Mierdapier Mies +Mies Lapsi +Mig Wizard Migalos Miggles Mighty +Mighty King +Mighty MP1 +Mighty Milk +Mighty Oak +MightyDolt MightyNemo MightyOrange MightyPieBoy MightySlappe +Mightyfrosty Migjiris Migou +Migrainelife Migraines +MiguelDyson Miguu Migy Migzee +Mihu o_o +Miiammi +Miig +Miiiild +Miika +MiikeyG Miillls Miiori MiissMandii Miitt +Mij +Mijae +Mijniebelle Mijuzo +Mik +MikTheKing +Mika Kuwait +Mika x +MikaDMM Mikael Mikasana MikazuAugus Mike +Mike DIY +Mike Davis +Mike Hochuli +Mike Hunt +Mike Mike +Mike Unit +Mike Xp +Mike-NL Mike1 Mike745638 MikeChang +MikeConleyJR MikeDangr MikeDitka +MikeHasMoobs MikeM MikeMontana MikePunts +Mike_Oxmaul Mikebaker417 Mikeey Mikeje13 MikelCz Mikemyers31 Mikerockshhh +Mikeroscape Mikeroscope +Mikes1995 Mikethafarm Mikey +Mikey B +Mikey Bai +Mikey Hey +Mikey Milk +Mikey x Mikey1plate Mikey47745 +MikeyBigDick MikeyPat Mikeygirl94 Mikeyscape MikeyyG +Mikezalwinnu Mikezilla Mikezzup +Miki4 Mikilly Mikki Mikkon +Mikouich Mikrobangine MiksuBTW Miksuuu MikuNakanoxx +Miky852 Mikzel +Mil Z +Mil ky Mila +Milagre Milaz MildRussia +Mile Stoner +Mileage MilesQPR +Miley Cyrush +Milfcocktail Milfguardian Milhous Mili +Milico +Milieu +Milieudienst +Milimoowolf +Miljoona Milk +Milk Energy +Milk Expert Milk Sausage +Milk my milk MilkDaughter MilkMan227C MilkOhh MilkToast +Milked Cox Milkki Milkless +Milkmate +Milkn Tiddys Milkopia +Milkraze Milky MilkyGalaxy +Mill Reef Mill385 +Millbrook92 Milleks +Miller 40 MillerLatte Millerlite40 Millerlite95 @@ -14943,37 +31267,82 @@ MilliMillzy Millie Millionsppl Millkk +Milllf MillsMCR Millsbay +MillzyRS +Milo +Milo Iced +Milo Monster Milol Milpe Milsurp Miltank Milton Mim3r +Mimahh +Mime Tan +Mimi20 MimiKe +Mimic +Mimori +Min Botter +Min XD Minalinsky Minar +Minazuki Mincene Mind +Mind C Crew +Mind F-ed +Mind of me +MindBender84 MindYoStep Minde Minde0777 Mindf4ck7 +Mindforce MindfulGnome +Mindgrnd Mindhead Mindlet +Mindreaver +Minds Hunter Mindys +Mine is frai +Miner00 +MinerMvp Mineraal +Minerii Minerock +Minerock Man Minesweeperx +Mineta +Miney Minfri +Minga Minga Mingdee +MingeKing Mingerd +MinhteaFresh Mini +Mini Aurelia +Mini Biceps +Mini Chocobo +Mini Elba +Mini Hazy +Mini Jaack +Mini K +Mini M +Mini Misty +Mini Van +Mini Xander +Mini o MiniBuilt +MiniBundy04 MiniCoat MiniDrew +MiniDuckling MiniNinjo MiniSoMini MiniStew @@ -14981,96 +31350,201 @@ MiniToast Minibini Minidefiant Miniglass +Miniguez Minijazz Minimaps +Minimizing Minimum Mining +Mining Runes +Minioz1 MinipeTh Minirio Miniscus +Minish Gal +Minisnacks +Miniuzy +Minix Mink +MinkMiller Minkyeung +Minnesoooota Minnick Minnie Minski Minslee +Minstrel RS Mint +Mint1s MintEastwood +MintSoldier MintWestwood +Mintaras Minton Mintvolcano +Minty Elder +Minty Rogue Minty28 MintyBeaver MintyBreath +MintyFreshFe +Minty_Duos +Mintyyyy +Minu Kamp MinusMinitia Minyons Minzy130 +Mio Magic Mioceen Mipu Miqdad Miqote Miquuw Miracle +Miracle Grip +Miracle Sun MiracleToy Miraculous MiramiS +Miran a +Mirana Mirari +Mire Mirek +Mirepoix +Miriage Mirin_Gloots Mirith +Mirize Mirk Mirkat +Mirkoi +Mirkys +MiroSemberac +Miroh Miroki Mirthless Miruki +Mirxcle MisClickPro +MisLilToe +Misaka 10032 Misakipillow Misano +Misantrofia +Miscellaneum +Mischief Miscrint +Miscy Misdeal +MisfitGrinds Mish +Mishie x +Mishigamaa Mishkkal Misimo Miskil +Misks MiskySam Mislabeled +Miso Horney Miss +Miss Amanda +Miss Amped +Miss Beth +Miss Clover +Miss Inform +Miss Judging +Miss Kipatzu +Miss Kitty +Miss Nothing +Miss Piggy +Miss Tinaa +MissArcane MissMockingJ MissMystique MissRosie +MissTowlie +MissTwistedx +Missandrist MissclickGG +Missel0 Missen MissinTicks Missing MissingRNG +Mission +Missu +Missus Missvmk Missy +Missy Cee Mista Mista 1337 +Mista Wright +MistaPhelps +MistaWubz +Mistagainz Mister +Mister Chill +Mister Ex +Mister Gone +Mister Jar +Mister KJ +Mister Texas +Mister Tiger +Mister Xanny +MisterBass MisterBensy +MisterBidoof MisterCobb +MisterGurn MisterJager +MisterPatego +MisterStats MisterTrump +MisterWhale +MisteruDongu Misterwieb1 Mistheos Misticwok Mistify +Mistik Soda +Mistio +Misto-Flies +Mistr Morale +MistrGiggity Mistral +Mistre Apple +Mistres Pres Misty Misty12 Misty7632 Misuryu Mitabi Mitch +Mitch Gate +Mitch Izle +Mitch Peters +Mitch W MitchHardo MitchRap Mitchggee +Mitchman987 +Mitchs 2nd +Mitchys Iron Mith +Mith Man214 +Mith Scimmy +MitherHobo Mithoon Mithrality +Mithralking8 +Mithrane +Mithter T Mito Mitologas +Mitqh Mittag MittensRS Mittum @@ -15079,18 +31553,26 @@ Mituse Mitver Mitzchy Miuted +Miuw Mivo50 +Miwi +MixBro MixKit MixTapeFiya +Mixes Mixieg Mixtape +Mixun Mixxush +Miyags Miyui Mizis Mizo Mizro Mizty +Mizuno Akane Mizusawa +Mizz Horror MizzFrizz Mizzzura Mjay @@ -15101,57 +31583,130 @@ Mk60 MkLeo Mkiller120 MknlC +MlCOOL +MlDGARD MlKE +MlKEL MlLFnCOOKIE +MlLLlSECOND MlLO999 +MlXOR MlZORE Mlao +Mlddel1 +Mlopes Mmgmike24 Mmichel +Mmkbro +Mmm Food +Mmm Mushroom +Mmm Xp +MmmBathSalts +MmmButter +Mmmmm Bacon Mmorpg +Mmu Mmurder825 +Mmv Mnemic +Mnir MnkyDLufy +Mnmnnmnm +Mnts +Mo Fo Sho +Mo Hit +Mo slays +MoFo Boss MoIon Iabe +MoMoYaP1972 MoPhobia +Moathog63 MoaxD +Mob Partyhat +Mob Punch +Mob Up +MobILe_Own3R +Moba All Day MobbDeep +MobbyWang Moberger Mobiel Mobile +Mobile Data +Mobile Maxin +Mobile Rng +Mobile Skiff +MobilePlayin +MobileSkeng +MobileXPOnly +Mobilekraan Mobilist Mobiusyellow Mobo Mobs MobyWoby Mobz +Moca Pet Moccamuna +Moccies Moccona Mochasins +Mochi Donuts +Mochyy +Moe Amien +Moe Is Back +Moe You Up +MoeCipher +MoeTx Moeberg MoedZhafa +Moedameyer +Moefugganutz Moepog Moer Moes +Moestieee +MoetIkLopen Mofaer45 MoffelRS Mofleminator +Mofo Lt +Mofo Shadow +MofoMo92 Mofoe +Mog Time xD Mogcow Moggok Mogtime +Moh Mohahm Mohamedss Mohanad +Mohannah +Moheed +Mohh Mohib +Mohlo Mohnday +Mohphy +Moiqol Moist +Moist Dreamz +Moist Holy +Moist Maori +Moist3allsac +MoistButh0le MoistMaker MoistPainal +MoistWreck +Moistium Mojimot0 Mojito +Mojo Fiki Mojojojo171 Moju +Moju GG +Mojurico Mojzis Mok101 Moka @@ -15160,78 +31715,149 @@ Mokkasiini Mokke-senpai Mokkis Moksa +Moksu Moku Mokum +Mokum Syl +Mola +Molag x Bal +Molars +Moldy Nuts MoldyChips Mole +Mole Slides Mole1 +MoleMan-II Molemountain +Moles Rule Molinas +Molkkipo Molle Mollem +Mollium MolllyPop +Molloyo Mollt MollyLlama Molokotorby +Molotoffer +Moltea Molten +Molten B +Moltenclawz +Moltres X +Mom Hunter +Mom Madness MomICantPaus Moments MomentsApart MommaCuz Mommy +MommyMish +Mommys Hand +Momoh flip Moms +MomsLasagna Moms_Spagett +Mon key +Mon3yy Mona +Monarchis +Monarchy Monday +Monde MonehBabeh Money +Money BTW +Money Bagz +Money Grabs +Money Mann10 +Money tyven MoneyMalone Moneyman +Moneyman 199 Mongke +Mongrel Hick +Mongstaman Moniez +Monika Liu Moniosaaja +Monitor Monk +Monk Fists MonkFishking Monka +Monka Blunts +MonkaFront +MonkaGrizz +MonkaSFish MonkaZter Monkadile Monke Monkees80 Monkey +Monkey D C +Monkey News +Monkey Pox +MonkeyDGazoo MonkeyHeadAF +Monkeyannie +Monkeyboy991 +Monkeydodo45 +Monkeyhug +Monkeys Ass +Monkeysick Monkie +Monkphish Monksmen Monkster MonnerMads +Monnivalas Monnual Monny Mono +Mono Y Mono Monopoly +Monopoly Mvp +Monotone 07 MonrealkaAfk +Monroejo Monsemand92 Monsilly Monsta Monstaarr +Monster Hog +Monster Tits Monster333 +MonsterKush +MonsterTrain Monsterofpk Monstrius Monstrocity Monsutaa Montagne +Montak +Montanaro Monterey +MonthOldMilk Monty +Monty Jr Monumental Monuu Monxanvrooo +MooGoo Mooch Moocow910 Moodeer +Moodoo Mooffa MoofinnMan +Moogly Moohcake Mooi Mooie Mooing +Mooing Cow Moojin Mookinater Mooksy @@ -15239,58 +31865,98 @@ Moon Moon688 Moon7I8 MoonCard +MoonDunes +MoonStaIlion +MoonWolf MoonYagami Mooncrafting Mooner Moongazing Moonish +Moonish Ale Moonjock Moonlightcb +MoonlitNika +Moonly Moonman392 +Moonr0cks +Moonshadow18 +MooonCakeee +Mooony Moopy +Mooqie Moordaap3 +MooreNoyce Moorleey Moortgat Moose +Moose Land +Moose713 +MooseEatBear Moosecup +Moosefangs Mooseheads Mooserini +Moosewizza +Mooseyt Moosy Moot Moowi Mooyee +Mopdussy Mopeds Mopedstian Moppeharry +Moppy +Moq puW +Mor Ul Neck Moral Morales Morally Moray Morbid +MorbinThyme Morch MordLacaroni +Mordacai Mordenumero2 +Morder-Biest MordinSolus Mordy More +More AFK +More Chillli +More Coala +MoreThermite +Moredots92 Morelos +Morfeusz +Morgan Donor +Morgan69 MorganAtkins MorganaTits Morghuan +Morghulish Morgo +Morgoth Man Morgue Morguhh12 +Mori Memento Morijo Moriquendi Moritz Morkius Morkret +Morkula37 +Morland Morlun Morlyx MormonFTP21 Morniingstar Moronavirus Morot +Morph1ng +Morpheus Aus Morphing Morphogene Morpice @@ -15300,71 +31966,311 @@ MorrisTheCat Morsey Morski Mort +Mort Eater +Mort Rigo Mortal +Mortal Coil +Mortalize MortarMan MortemPlaga +Mortituros +Mortle2 +MortonRamsey +Mortonnizer +MortresxD s1 +MorttMoryt Morue +Morvas Morytania +Mosade Mosaq Mosbol Moscosung Moseley Mosess +MoshPitJosh2 Mosio Mosiph Moska +Mosmo +MossadKiller Mosse +Mossels +Mossgiant +Mossy +Mossy Taint Most MostDreaded +Mostly Godly Mostoes +Mosychuk Moteha +MothQueen +Moth_29 +Mothafuqueur +MotherFigure Mothless Motikeli +Motion1010 +MotivaSean Motivated Motmans +Motochorro +Motor +Motse Mottis Mottly Mottookaa Motx Motyas Motzimoo +Moubu Mougi +Moukie Moul Mouldied +Mouldy Lamp +Mouley Mount Mountain +Mountan Drew Mourn Mourners +Mournhold Mous +Mousecream Mousekeys Mouselifter Mouseman298 Mousenn Mousie23 Mouteo +Mouthful Pip Move +Move Over +Move Ziggy Move2791 +Movember +Moviestar Moving Moving20 +Mow on mate Mowgli13 Mowk Mowt +Mox +Moxy Senpai +Moyaha5 Moyd +Moyis Moysey MozDef Mptrj +Mq4 +Mr 0wnage +Mr 223 +Mr 7o7o +Mr 9ine +Mr A +Mr Airborne +Mr Alba +Mr Alex +Mr Ashh +Mr Ayye +Mr Bagel +Mr Baggy +Mr Barakas +Mr Bazzi +Mr Beefman +Mr Beekman +Mr Believe +Mr Biceps +Mr Bijpakken +Mr Bond +Mr Boogley +Mr Brunoo +Mr Burton x +Mr C0KE +Mr CHM +Mr Chonky +Mr Chopz +Mr Comrade +Mr Costy +Mr Count Up +Mr Cryin +Mr Dan Solo +Mr Darzelis +Mr Deivis LT +Mr DirtyDan +Mr Dong322 +Mr Dreamcast +Mr Dry +Mr Dudeicus +Mr Dumbiller +Mr Durian +Mr Dylesxic +Mr Easyscape +Mr Egret +Mr Elmar +Mr Elysian +Mr EsKei +Mr Fathead +Mr Father +Mr Foe +Mr Freezie3 +Mr Fridge +Mr Funguses +Mr Geese +Mr General +Mr Gentil +Mr Ghillie +Mr Ghizar +Mr GnW +Mr GodLuck +Mr Hanki6 +Mr Hassan Fe +Mr Hollowx +Mr Hrodbert +Mr Hulbert +Mr Infinity +Mr Iron Bar +Mr Iron Gray +Mr Iron Owl +Mr Iron Poo +Mr IronAss +Mr Jacko +Mr Jam10 +Mr Jam1O +Mr Jasperr +Mr Johbi +Mr Jonh L +Mr Jordy +Mr Joshing +Mr Jot +Mr Kaasmof +Mr Kato +Mr Keyss +Mr KingCobra +Mr Kirbo +Mr Kiwi Bird +Mr Kman +Mr Kodai +Mr Kokkok +Mr Krabbsss +Mr L0af +Mr Laser +Mr Laz +Mr Leeee +Mr Looch +Mr Loser +Mr Lysol +Mr Mackie +Mr Manual +Mr Martel +Mr McCune +Mr Mentos +Mr Mikers +Mr Missiles +Mr Miyagy +Mr Moncler +Mr Mordacai +Mr MrX +Mr Nagoh +Mr Nasty Kev +Mr Nate +Mr Nebs Main +Mr Neckless +Mr No Rift +Mr No Sleep +Mr NoMates +Mr Nonya +Mr Ohio +Mr Oizo +Mr OldSchool +Mr Osc ar +Mr Ozzy +Mr Palm +Mr Pandaz +Mr Pastorius +Mr Peggers +Mr Phelipe +Mr Pita +Mr Platypus +Mr Pondman +Mr Poup +Mr Pretzels +Mr Questerr +Mr RaWaR +Mr Rebirth +Mr Rich T +Mr Robert +Mr Romm +Mr Ryker B +Mr S N S +Mr SZX +Mr Sasquatch +Mr Shaman +Mr Siege +Mr Sighco +Mr Slabs +Mr Slaw20 +Mr Spark +Mr Splitter +Mr Squicky +Mr Stan Man +Mr Syvan +Mr T C +Mr Takoya +Mr Tbh +Mr Teej +Mr Thornbery +Mr Troll +Mr Trump +Mr Untainted +Mr Vaidys +Mr Vanhanen +Mr Veegs +Mr Wieler +Mr Wild x +Mr Woods +Mr World 420 +Mr Woz +Mr Wumbo +Mr Xray +Mr XuRu +Mr Yozef +Mr Yum +Mr Yzi +Mr Zevosh +Mr Zio +Mr ensayne Mr noli Fe +Mr rubler +Mr spikey +Mr stony +Mr2ndPlace +Mr44 MrAlcotester MrAmazing MrAmbaal MrAngelxz2 +MrAngerfist MrAnkan MrAwesomeNL +MrB1u3 +MrBananaJoe +MrBeadyEyes +MrBeastly MrBeerNTits +MrBic MrBigLoads MrBigPecs +MrBigWheels +MrBingly MrBlueScreen MrBooBlocca +MrBorreby +MrBouncyButt MrBraa MrBry MrBryne @@ -15377,36 +32283,62 @@ MrCivilian MrCoolSkills MrCoook MrCoopahh +MrCowey MrDTails MrDairyHeir +MrDaive MrDarkBlue +MrDarkSide76 MrDarling MrDashwood +MrDeadInside MrDevice MrDevour +MrDoake MrDoofes +MrDraconite +MrDumbaldore MrEasty +MrEdgaras +MrEmerica +MrEnd +MrEwan MrExterm +MrFANG MrFancyboots MrFarrell MrFlizz MrFluffy97 +MrFreakyFrog MrFrizzesh MrFro +MrFrogRS +MrFuack MrGaalis MrGainz MrGanksta +MrGatorGnash +MrGeeeeeee MrGibbletts MrGixxer MrGodBrand +MrGoodbye +MrGraveLord MrGrind +MrGurbz MrGurn +MrGustuv +MrHatN Clogs +MrHeftyBag MrHobokian MrHummus +MrHypeK0 MrIWontMax MrIronChef MrJTheIron MrJad +MrJargon +MrJermu MrJoestar MrJohnnyx MrJonMan @@ -15414,17 +32346,32 @@ MrKadir007 MrKerrie MrKevinR MrKoalas +MrKyle +MrLaffy +MrMag MrManny +MrMatchett MrMaxLvl99 +MrMayhem +MrMeeseek420 +MrMeeseexs MrMell0w MrMime +MrMonkeyJock +MrMonopoly MrMonsterrr MrMooCows MrMose911 MrNL +MrNaf1 MrNatee +MrNeverWrong +MrNice98 +MrNieksas MrNikeKush MrNoBank +MrNoFgiven +MrNoFilter MrNoLove MrNook MrNorwayOS @@ -15433,75 +32380,169 @@ MrOceanic MrOctapus MrOngh MrOriginal25 +MrPK74 +MrPaip +MrPapaJoe MrPezcu MrPige0nz +MrPiggles +MrPlasters MrPoopiehead MrPork +MrPotionz MrPowers MrPutterLite MrQuaker MrQuick1 MrRaidUrGirl +MrRakoon +MrRangingElf +MrRawDog +MrRiceBucket MrRidder MrRight4U MrRobinHood6 MrRoboto MrRocco +MrRodgersHD +MrRojo31 +MrRumarak +MrRuneDrag +MrRyo +MrSanta94 MrScape2Much MrSensimilla +MrShneeeebly +MrShoarma MrSimQn MrSirOne +MrSkydive MrSlongerton MrSmiiLey +MrSmikkel MrSocorelis MrSolo MrSteelYoRNG MrStickyBudz +MrSucellus +MrSuibhne +MrSupo MrSusans +MrSwift00 +MrTanglez MrTibberfitz +MrTickMaster MrToad +MrTobyG +MrTooSerious +MrTough rs +MrTrashclikz +MrTryHard69 +MrTurds MrVillanelle MrVitable +MrWallnutt +MrWeageZ0311 +MrWest +MrWhetFartz +MrWobble420 MrWorldwidee MrYachie +MrZandra +Mr_B1ff +Mr_Hairless Mr_Kadir007 +Mr_Kapoo Mr_Manchello +Mr_Ostroum Mr_Schmeckle +Mr_Scoff Mrawrs +Mrbadwrench +Mrbaird +Mrbd Mrburnsss +Mrcoconut22 Mrdeemoney +Mrevil1 +Mrfuntime517 Mrfuzzy Mrglex +Mrhood +Mrjellyfish Mrjli Mrloonetick Mrm0rm0r +Mrmagoo0 Mrmanguy Mrn1ceguy89 +Mrpokoz +Mrpoopyface1 +Mrs Budie +Mrs Pure Cut +MrsFabler MrsJonesUFT +MrsMushrooms MrsPurpTurt +MrsSocorelis Mrslipkn0t Mrwaffleses +Ms Goblin +Ms K +Ms Lizziard +Ms Trap +Ms Zik +MsAnderzen +MsArachnea +MsBoothanqq MsFreakyFrog +MsGroves MsSev +MsethOWarq p +Mssp +Mstr Postman +Mt Eben +Mt Olympus +Mthrfckrmike Mthw +Mtn Dew Dew +MtnDewford MtnGoat +Mtp69 +Mtra +Mtv Cribs 07 Muad_Dib +Muahahaha45 Muahhahaa Muahuahuahua +Muas MuasBtw +Muay Mat Muaythai +Muc Gib +MuchBetta MuchGpWaste Muchly MuchosAssias +Muchy Muckball +Muco +Mud Cricket +Mud Temple Mud9 MudCatBigDog +Mudda Focha +Muddas Main +Muddy patch Mudguard +Mudkins Mudkip +Mudmur Mueezy MuerteBella Mues Mufasa +Mufasa IXI MufffinKing Mufficer MuffinActual @@ -15513,7 +32554,9 @@ Mugarooni Mugen Mugge Muggerman3 +Muggled Muggles +Muggtjuven Mugrub Mugy Mugzy @@ -15521,116 +32564,232 @@ Muhaji Muhamed Muhfn Muhkea +Mui Gokuu Muilpeer Muki Mukkaram7861 +Mukkey Muktheduck +MulasRevenge +Mulberry Mtn Muleleaveox +Mulky Mulle-mek +Mullet Mafia +Mullishus Mullvaden Mully MullyMammoth Multi +Multiloquent MultipleRats Multiplying Multitalent Multiway +Multizeta Multrix Mulugga +Mum3nRider +MumBanker Mumble Mumbles +MumblinSloth +Mummzy Mumriken Mums Mumspaghetti Munansurvain +Munchise +Munder Mundt Mungles Mungoe Mungu +Munia15 Munich Munire Munk Munkea +Munkefar Munkinut +Munky Munk MunkyBizness MunkyKnuckle Munn +Munnchicles Munqqi4862 +Munqqii +Munshae Muparadzi +Muphat Muppz +Murasa Murbez +Murda Turk Murder +Murdered +Murderings Murdimius Murdock Murdur +Murgambit +Muri Murilokooo +Murimekko +MurkWahlberg +MurlokMurlok Murogrim MurphRS Murphys +Murphys Lag +Murpman Murray +Murray 1991 Murre Murrloc Murrrum +Murt15 +Murtti +Murzum +MuscleNation Musftw Mushmom Mushroom +Mushroom Mtn Mushrooms1 +Mushtime MushuPorkPls +Musi c Music Musica MusicalMurdR MusicalStory +MusiclRevivl +Musicpunk Muskets +Muskintine Muskogee +Musky Whale +Muslimi Musschoot Mussy Must +Must Slay MustBeGanja +MustKillBill Musta Mustachio +Mustamae +MustangYak1 +Mustangs Mustard +MustardXD17 Mustasurma Mustekala MusterShelby +Musto Task +Musty Ropes +Musty Sailor MustyToofer Musuwu +Mut3dHasselt MutaNep Mutants Mutapets Mutated +Mute Pker Muteself Mutilated Mutsurini +Mutt a dile Muttadale Muttadiddle +Muttadude +Muttallica +Muugz +Muumipappa +Muunchyy +Muurxi +Muushuu Muutz +Muws +Muy Booty Muzbo Muzi +Muziek Smurf Muzket Muzz Muzzle +Mv P +MvP ov RnG +Mvk +Mvko +Mvp Scrub Mvvs +Mw2 +MxMay +MxSloot +Mxb36 Mxffin +Mxr Mxteorites +Mxtta +My Damie +My Dark Hell +My Dark Soul +My Death Bed +My Demons +My Dont We +My Dumb Iron +My Faith +My Fantasy +My GF isMILF My Gentiles +My God +My Iron Man +My Ironmain +My Ki +My Kill +My Kingz +My Limp GIMP +My Main Game +My Maine +My Mate Elm +My Name Vyga +My Pet Mocha +My Rng Ass +My Sana +My Secrets +My Ticks Now +My Ult +My pp stink MyAssLucky MyCatKillsMe +MyCtyNeedsMe +MyDuck MyElyNow MyFitPal +MyHandyMan MyIiu MyLastGo MyLoveFaith +MyMercy MyNAm3BubBA MyNameIs MyNameIsCole MyNameIsKent +MyNameIsTina MyNameIsTrev MyOSAccount +MyPetRicky MyProject MyRifleMyGun +MyRight Nut MySeed +MySkillsKill MyStinkHurts MyTakao +MyWanderlust MyWyvernAlt Myams Myat @@ -15639,88 +32798,240 @@ Mycreation1 Mydlong Mydragon8u2 Myers +Mygary Mygraine +Mykeh Mylar Myles +Myles_008 Mylifeisless +MylilBrony +Mylle Mylo +Mylo 7 Mylos Mylosas Myndemo Myoboku +Myosarcoma +Myoshi Myotoxin Myriadic +Myrm Myron MyronAynes Myrupz Mystearica Myster +Mystery Btw +Mystery X MysteryGifts MystiCool Mystic +Mystic Mak +Mystic Pizza +Mystic Voke MysticChompy MysticDrift MysticErebos MysticRiver MysticStrega +Mysticpuffer Mysticrobe +Mystics Main Mysticvaa Mystiic Myth +MythCerix MythCraft Mythic +Mythic Hiero Mythicat +Mythrin III Myto +Myuf Myuk Mywa +Myz Myzi +Mzaa +Mziy +Mzr +Mztar +N 10 +N 55 +N A l N E R +N E L L +N E N E +N Gallagher +N I GH T96 +N I N O X +N I S H +N ICK Y +N O B S Y +N U B U +N W M +N a t t z +N ang +N anko +N arb +N dejay p +N e a k i le +N e i l +N e0 +N iall +N ibbler +N ightgleam +N l C K O +N l E V E +N o m a d +N occo +N oggin +N u d +N uggies +N-J-R N0 H34RT +N0 Invictus +N0 pid +N00biistyl +N00bslayer27 N04me N0B4Marri4g3 +N0Ballz N0ID +N0LlMlT N0OneCares +N0T HC N0XPWaste N0blelegend N0llie +N0obalhao N0rse_k1ng +N0sie +N0t Maxed +N0t special N0tliketh1s N0ul +N1 CK +N17 Jake +N1C3 N1NJASK1LLZZ +N1ckai +N1cwho +N1nja N1njaCat +N3XX +N3p N3se +N3x +N4L +N4ruto +N4styNat3 +N7N +N8vy +N9NE420 +N9T7 +N9U +NABEEL RJ +NAGAKAMAL +NANORA NARPslayer +NASDBOY +NASSERN NASTY NAVl +NB8K 2K13 +NBA +NBA NewMain +NBA Youngb0i +NC90 +NCG +NCG 2 +NCPS +NEBR0SKY NECR0DANCER NEEDAMETHYST NEENEE NEET +NEET forever +NELSONORS +NENOS NEONiC NEWBEYE NEWFISHMATE +NEX IS WET +NEXFARMER NEYOVIC NFed +NHL Blues NHrn +NIIXIIK +NINJABLEV1NS +NINJATMNT NITR00 +NJC20 NJWW +NKJ +NL Chronos +NL Gilbert NLDeluXe NLFreakky +NMM Jaoel NMOS_giant NMZLetics +NO 1s SAFE +NO CHlLL +NO FEEL +NO MlDS +NO N R G +NO PlD NOAH +NOMETHESPORT NOOOOOOOOOO NORTHSEA NOSTALGlA +NOTTDY +NOTaPancake +NOmki +NPC Healer +NPC Icedrake +NPYJ +NRA NSFL +NSHN +NST Praise +NT FiSHvv +NT Y NTBeerBandit +NTMR RADIO NUEL NULLI +NULLlN KUPPl NUTSHOT +NVQ NWHL +NWI 219 RAT +NY +NY C +NY G +NY x LEGiiT +NZ Dave +NZL +N_MB +N_other_day +Na Mn Or I NaCl +NaCl Sprite +NaCl is salt +NaQ Naaath +Naafiri +Naais Naakkeri94 Naakt +Naaon +Naautilus +NabD Rank 5 Nabroleon Nabshadow Nabss @@ -15728,191 +33039,375 @@ Nabua NabyLad Nach NachB +Nachitto Nacho +Nacho Alt Nacho2030 +NachoByte NachoDragon +NachoPapi +Nacht Nachtkastje NachuiTuda +Nadaa +Nadeo +Nader +Nadsage Nadund +Naethera Naftininkas Naga +Naga Morich Nagisa +Nags NagyonJo Nagyung +Nah0824 +Nahida +Nahiida Nahkamestari Nahuel +Nahyol +Nahyun NaiiSha Nailbox Nailed Hard +Naimsen +Nainenoon +Nairda Niam +Nairda Nori Nairino +Naisu Najda +Nakal +Nakama NakedTwister +NakednFeared Nakke176 +Nakkee +Nakkesleijer Nakkimauno +Naksitr6ll +Naku Nakuz Nakuz0r +Nalle Puh FT +Nallieheai Nalsara +Nam +Namcel Name +NameECJ NameRjected NameWasBannd +Named NamedGenius Namelessdude Namelus NamesAreMeh NamesHisoka +Namine Silke +Namir Nammer Namuko Nana +Nana Steel Nanado Nanciscor Nancyy Nander +Nandos +Nandos Man +NangMan Nangdalorian +Nanimavi +Naniva Nannertee Nanno +Nannu Baba +NannyCam69 +Nanoh +Nanoman360 Nanonymouse +Nanook IV +Nanoray +Nanotech Nans NansBeaver +NansCumTowel NantaoL +Nanyts Naoe +Naoe Y +Naoe Yamato NaofumiLTU Naoka Naow +Nap Tackle +Napaaaaaaaaa Napalm Napanderii Napettaja +Naphtic NapkinFork +Napnapnap8 NapoleanBra +Napoleon +Nappy Head Napsutaja Naqu +Nara ven Naradas +Narbose Narby +Narcan Saves +NardDog +Nareg +Narel1a +Narendradath Narg +Nargarothian Narked Narkon NarnodesNono Narrative Narry Nartens +Narth Calior Narthalion Naru808 Naruto Narval Narvalow Narwallus +Narwhal1731 Narx4 +Nas is like Nasa Nasaman +Nascar Naseeph +Nashh Nashluffy +Nashonic Nashy +Naskarsdad +Nasko 07 Nasper Nasrullah Nasseee Nassim Nast +Nastacov Nastie +Nastik Nasty +Nasty107red7 NastyAss +NastyCasual NastyDonger +NastyGarbage +NastyGeUsers NastyV6 Nasuuu +Nat Scheetje Natalie +Natby Nate +Nate Dogg g +Nate Joggers NateDoge +NateStayLove +Natebroh +Natedog 1104 Naternater +NatesOSRSAcc +Nath Meister +Nath btw NathJeaL Nathan +Nathan A +Nathan Lyon +Nathan Novak +NathanTurn +Nathandrthal Nathanyuelle +Nathn Nationwide Native +Nato is Jake +Nato888 +Natoh +Natoroid Natrox999 Nats Natsu +NattNub Natte +Natte Dop +Natte Dream +Nattetid +Nattkungen +Nattmara Nattraps Natu +NaturalBeaut Naturally +Naturally Me Nature +Nature B0Y NatureNymph +Naturealis Naturejacks Nauce +Naudra +Naught Good Naughtpure +NaughtyPanda +Naukahtaa +Naukkiss Nautis +Nauuyn Navas +Navbrah NaviRio Naviaux +Navidson1 +Navn Navraj Navtik Navy NavyDD214RET +NavyLight +NavyPunk +Navyseals199 +Nawberry +NawtyMonkey Nawus +Nax Naxacid Naxiius Naxito Naxos Naxtzi +Nay RS +Nay0101 Nayna Nayrus +Nayrus Love +NazTehRpR Nazgul Nazty Nbba Nbcw +Nbsniper69 Ncpure Ncrr +Ne x is Ne3po Ne86 +Neak +Nealonl4 Nealos Neals +Nealvy Neanderthal Nearly Nearomancer Neatkii Neav Neb0lith +Nebb Nebbo +NebbyGo2Bag +Nebezaidu Nebijok Nebrosky +Neccto Nechromancer Nechryass Nechs NechtKnecht +NeckBat Neckbeardis Necksnipped NecroEric +NecrodedGSF Necrokingns +Necromatus +Necromooser +Necronomist Necrophorum Necrosauruss Ned1991 +Neddam NederweertV2 Neduks Nedus +Nedved Nedward +Neeby Need +Need 2m +Need A Pint +Need Femboy +Need GP Now +Need Protein +Need Rogaine +Need Spoon NeedInternet +NeedMoore +NeedPurp4Bed Needs +Needs Coffee NeedsADad Needtomboy +Neeech Neefey +Neeisnet +Neekkoco NeekoNeekoNl Neekomata Neekss +Neelen +Neems +NeetScape +Neetman +Nefarious fe NeferSeti +Nefereous Neffiz Neg14 +NegAttiveI Negan Neganeogami Neghed +Nego Baby +Negrong Nehxy Neil +Neilthedead +Neintein +Neitiznut +Neitiznut Jr +Nej tak Nejvalt Nejvash +Nekalbink +Nekkopanda +Neko Inori NekoSayNyaa +Nekomata Nia Nekomimi +Nekromant Cz +Nekrukeisari +Nelaimingas Neleron Nelhium Nelkirr +Nelli Matula Nelliell +Nellysan Nelox Nels0N Nelsi @@ -15926,154 +33421,295 @@ Nemaksciai Nemba Nemerrr Nemesis +Nemesis2020 Nemf +Nemijin +Nemipro Nemisys +Nemj Nemmo Nemo +Nemo_o Nemonia +Nemoven Nenah Nendou +Neng_Thao02 Nengah +NeniHead Nenio Nentsukka +Neo +Neojoramony Neon +Neon Christ +Neon Juan +Neon Slinky +Neon Volts +Neon xxv NeonChilli +NeonGenxsis NeonM1d +NeonO7 NeonPaladin NeonRhythm11 Neonik Neonke Neopia +Neoplasia Nephedes Nephyrion Neppe +Neptune169 +Ner +Nera Obuoliu NerbBlaster Nerbles +Nerbs Nerd +Nerd Body +Nerd Owns +Nerd Stone Nerda +Nerdbob Nerdcore +Nerdier +Nerdpuff +Nerf Bowfa +Nerf Coffee +Nerf Th1s NerfMePlz NerfTG Nergegante Nergg +Nerio x +Nerithma +Nermzz7 Neroxcen +Nerraw +Nershi Nerve +Nerve Cell Nesk +Nesquiik KlD Nesretep Ness Nestedloops +Nesties Nestl3 +Nestorianos Nesuvarzytas NetTrap +Netamu Netanelba +Neteroem +Netgear Nethada +NetherToxin Netho Netjes Netmn15 Neto +Nettipoliisi NetturDab Neturtingas Neural +Neuro Lepsis +Neuro-Tomb +Neurologist Neurophys Neurovelho +Neut +Neutral Game +Neutralised Neutrally Neutronas +Nevar89 +Nevena Never +Never Die113 +Never Spoon +Never die +Never2Clever NeverAssume +NeverBudge NeverEnding NeverFreeze NeverGetRift NeverGunaMax +NeverImprove NeverLateWiz +NeverMoves +NeverMyFault NeverQuest NeverRespawn +NeverSailing NeverSober NeverTrading Neverender27 +Nevermaker Neverover Nevi Nevik94 Nevinnn +Nevit +New Monkey +New Tooka +New journey +NewAgsWhoDis NewBoy4321 NewDad NewFavorite +NewHobby +NewMobWhoDis NewPlayerx13 +NewToBossing NewWrldHodor +NewZealands Newb +Newb Ranger Newbillnye +Newby NewcastleFC NewfieTinMan Newfiebanger Newguy2003 Newleesh +Newlut NewrockkuOS Newst0nekid +Newt Jacuzzi Newtman907 +Newton 1 +Neww Zealand +Nex Afg +Nex FFA King Nex Is My X +Nex Minion +Nex Myself +Nex leecher Nex1s Nex2169 +Nexarion Nexcellent Nexeiy +Nexfinity Nexgen Nexi Nexil Next +Next Day NextPet +Nexus Sire Nexx +Neya Neyburr Neye +Neyes Neyugn NezFix Nezqi Neztea +Nezuk o NghtPnda Ngis +Ngyessiree +Nh3r NhaleXhale Nhan +Nhest Cutter Nhimzo Nhouse20 Nhyrenn +Ni +Ni ke Niahl +Niall x Niawag +NibblyTitter +Nibbyus Nibexx NiblaNoss +Nic +Nic Machine +Nic Nasty +Nic Nerc +Nic co NicMachine Nicannand +Nicao Beck Nicashi Nicathan Nice +Nice Adept +Nice Caulk +Nice Iron +Nice Nice +Nice One +Nice Peaks +Nice Pets +Nice try guy +NiceGuy Edy NiceGuyEddyy NiceMarkMark +NicePotatoes +Nicely High +Nichohls NicholasRage +Nicholaswei Nichy NiciValbuena Nick +Nick Grows +Nick Ints +Nick Lopes +Nick Sellers +Nick X10 Nick0hwolf +Nick1234101 +NickChubb24 +NickReady +NickScape NickSpoof NickTSMITW NickVo NickaClassic Nickernack55 Nicki +Nicki Menage NickisBackyo Nickk Nickmitz23 +NickmyKnack Nicknao +Nickolai Lol Nickool4 Nickos +Nickoss +Nickoudbier1 Nickroo1234 Nicks +Nicks OSRS NicksNipples NickyPunky Nickynice23 Nickyy +Nickyy G Nico +Nico BE +Nico Le Chef +NicoFreakOh NicoIas NicolaSturge Nicolai +Nicolaj Nicolas +Nicoo +Nicophilia +Nicsyth NidaNewName Nidalee +Nidgen Nidh Nidhogs Nidk @@ -16081,26 +33717,45 @@ Nidmann Nidoking110 Nidraugas NieI +Nief Niefable Nielaahh Niels1608 +Nielscorn +Nielsen9312 +Nielssjeee Niely +Nieman NietzscheJR Nieve +Nieve Hamtaa +Nieve Rivers +Nieve Task NieveIrwin NieveIsBad NieveIsThic NieveMeAlone +NieveTitties Nieves +Nieves Bean +Nieves Boob +Nieves Butt +NievesDead NievesThighs Nifelhiem +NifkeCove +Nifty Gifty Nigel Nighlist Night +Night Elf45 +Night Shade NightNurse +Night_Furor Nightbass Nighter Nightmare +Nightmare CX Nightmare028 NightmareSHW Nightolas @@ -16108,174 +33763,354 @@ Nights9 Nightsharp Nighttman NightxxShade +Nightz Watch Nihilismi NihilistScum +Nihplod Niihilism +Niiick +Nijah123 +Nijn +Nik-fil-A +Nikab Nikco Nike NikeOnMyFeet Nikez Nikit Nikkerpoo +NikkiJaxx NikkiQT +NikkisDD +Nikkisaur Nikko Niknea +Niko Solo NikolasOG Nikoo Nikronic +Nikskill Nikumei +Nikun +Nikz Niley +Nilitsu Nilpferd +Nils +Nilwh NilzZ +NimaNaruto Nimajineb +Nimble Snail Nimbubu Nimex Nimismies2 Nimlasher234 Nimloth_666 +Nimma Crew Nimmongel Nimrod Nina +Nina Dobrev +Ninanunana +Nine E L NineTs +Ninef +Ninesax +Ninetails Ninetales4 Ninevolz2 Ninfia Ningaa +Nini N Kiki Ninja +Ninja Bamsen Ninja Cow Jr +Ninja Rasta +Ninja1978 Ninja66 +NinjaNoodles NinjaPunch72 NinjaSpeed NinjaTurt Ninjaloff NinjasDark3 +Ninjee xo +NinjerNick Ninjunzo Ninjymate Ninook Ninorc Nintendogz +Nipaahv Nipes Nipitipi Nipp +Nipp-on +NippleSundae Nippppppppee Nipps89 NipseyHpvm Niseraru +Nishax Niskha Nismo +Nismo Ranqe +Nisramont Nissan NisseIadden +Nissmo Nistipata78 Nitefall3n +Nitepearlz +Nitetrip +Nith Nithe Niton +Nitro Crate +Nitro Dax +Nitro Rng +Nitro306 NitroCrate Nitroalkenes +Nitrognhorse Nitros +NitrosOxide +Nitrous Bro Nitsch +Nitsuj42 Nitt +Nittany +NitwitSchool +Niukkis Niva Nivex Nivory Nixby Nixi_NL +Nixiro +NixonsJowls +Nixvet +Nixxay Iron Nixy NixzTez Nizqa Nj0y Nkpi NlCK +NlCKT +NlLREM NlMBY NlSO NllCK NllL022 NlppleX +Nmf Euphoric Nmofm +Nnavs Nnoitra +No 1 There +No 99s btw +No Arcane No +No Autoclick +No Basic +No Death Tax +No DexL +No Diff +No Emphasis +No Fear X +No Fkeys +No Honor Yah +No Joggers +No Kwuarms +No Legs Lazy +No Logic +No Lucko +No Means Ya +No Meds +No More Bugs +No Much Bulk +No Normies +No Old +No Pets +No Rationale +No Rugrats +No Saint +No Senpai +No Sleepin +No Souldier +No Splits +No Submit +No Tax Due +No Tbow Andy +No To War +No Xp Waste +No Zily Luck +No ah +No toleranss +No ur roll No0dlehead No53 +No7 NoAntiVenom NoBankIRL +NoBanksNoThx NoBans NoBp +NoCreamy NoDayMercy NoDealEU NoDropForMe NoDurex4you +NoEdge707 NoFame +NoFang Wizza +NoFapp +NoFlipZone NoGoodSkills NoHelp +NoHesitation +NoInferno +NoIronManBTW +NoLife4Him2 NoLifeCue +NoLifeLevi NoLifeMain NoLifeMcgee +NoLifeScape NoLifeSincRS +NoLiferSoul +NoLimit NoLootBag NoLootNoWoot NoLove +NoLuck Mario +NoLuckBearku +NoMarinero +NoMercyUIM NoMo NoMore NoMoreTrades NoNumbers4me +NoOlmletSig +NoPainNoMain NoPolnT +NoPrims2k_kc NoPurpleAku NoRNGsmalle +NoScyOrStaf NoShit +NoSprayNoLay NoStore NoStrategy NoStress2Day +NoTangleroot NoTank4U +NoTexture +NoTradeBrad NoTradeForMe +NoVa ITI +NoVow +NoWaR +NoXpWast3 NoXpWasted NoZulrahIM +No_Dumping +No_Remedii Noah +Noah Dinnae +Noah G +Noah Luvs U +NoahB NoahGriffith +Noahfireball Noahs +Noam Chompy Noamonts Nobber Nobbys Nobelanerr +NobilityTorn Noble +Noble Gage +Noble Oats +Noble Sticre NobleCorey NobleVespo NoblesForRec +Noblood +Nobody Good Nobodyz Nobrain +Nobu +Nobudy Nobularlol Nocando Nocarred Nochill NocnyKoszmar Noco +Noctivagous Nocturnal +Nocturnal RS Nocturnal024 +NocwocDaLord +Nodens +Nodonge5 Nodorcro NoeLT Noeka Noem +NoemMeJePapi Noexi +Nofolkn whey +Nogal +Nogi Nogoodnms NoiScape Noig +NoirSandy +Noiserv Noisy +Noisy Luigi +Noita-akka +Noith NoizRock Noizex +Nokil Nokiny NolanAlpha +Nolch +Nole Jr +Noley Nolifepvm Nolifer +Nolifer 28 Nolly +NoloadRIP Nolungs Nolzeyy Nolzzz +Nom C +Nom Ruby NomCensurer +NomNomSoulz +NomadForseti +NomadRek NomadsLife Nommmy +Nomoenoobs Nomonater Nomskichooo +Nomtiq Non5ens31 +Noname Nate Nonc None +None Feared +NoneOther Nonke +Nonni Nonplayer Nonreal Nonsense @@ -16283,29 +34118,50 @@ Nonstop Nonvalid Nonwestlee96 Nonwitzki +Noo Promises Noob +Noob Man +Noob N Smoke +NoobHey NoobPkedMe NoobWrecker Noobacleese Noobalhao +Noobe15 Noobest Noobicidal +Noobike00525 +Noobirini NoobishAct2 Noobs +Noobsscape +Noobtyle Noobtype +Nooby Noodle +Noodle Dude +Noodle Me Noodle Soups Noodles +Noodlike Noodz Nooki Noolbort Noon Noons +Noonshake Noopi757 Noorbee +Noorden +Noosii +Nooster Noot NopePope +Noportals NorCalGreens +Nora Flora +Norbet +Norbsi Norchis Nordas Nordfeir @@ -16316,270 +34172,660 @@ Nordstrand Norfok Norge Norhig +Nori Nitsuj Norilsk Norimasa NormHadAFarm +Normabel NormanBates +Normans Normie +Normie Main +Normie helm +NormieDalzii +NormieFYI Normies +Normy Narked +Norn Norqe +NorrSken +Norska +Nortenosk North +North No 2 +North Rmmbr +North1ane Northerly Northfork Northic +Northnewfy +Northrod +Northtoeast +Northxy +Norti Norton Norton_Gman +Nortoon +Nortron +Noscythe bad Nose +Nose Beerz +Nose Puncher NoseBeersies Nosetkl Nosevesey NosferatuBoi Nosni +Nosnorb Nosorow Nost4lgia95 +NostalgiaNp +Nostalgic +Nostalgic00 Nostalgimon Nostos +Nostrily +Not 0A +Not A Lover +Not A Robot +Not Bad +Not Brizz +Not Carlyle +Not Cynical +Not Dzop +Not Eternal +Not Flicking +Not Frac +Not Gaming +Not Ice +Not Internal +Not Ketho +Not Level +Not Lime +Not Lorppe +Not Med +Not Mesijus +Not Mikers +Not Muppet +Not Muppz +Not Panik +Not Perry +Not Rudy +Not Ryu +Not Salinger +Not Schuproo +Not Sharp +Not Soft Yet +Not Sotetseg +Not Tanzu +Not Tarczon +Not Tarny +Not Twistie +Not Vaxx +Not Yakosu +Not Your Nan +Not ZB +Not Zema +Not a Fan +Not a UIM +Not all +Not an elf +Not enough +Not even Dan +Not main btw +Not rn Babe +Not trivial +Not wow man +Not-afraidem NotAFKenough +NotAJ +NotALurer532 NotASkrub NotAStreamer NotAlright NotBiabanana +NotBot893294 +NotEp3 +NotEvenRare +NotGilthresa +NotHCJames NotKD +NotKailey +NotKnowMadss NotLefty +NotMatched +NotMaxinSoon NotMinty +NotN07NeMo NotNecro NotPker +NotPlateWolf NotReady NotShaneska +NotSoCasual NotSoHCZoro NotThaFather +NotUIM NotUrAvgTim NotUrBisnis NotValidName NotYerGuyPal NotaCola +Notanedgepkr Notanoob12 +Notfatprism Nothard +Nothin Lasts Nothing +Nothing Sold +Nothing2die4 NothingMate +NothinqThere Notjoeybloom Notlayla Notmyrsname Notori Notorious +Notorious N1 +NotoriousALB Nottarg +Nottingham +Notutoring +Notwind Notz +NouGIM Nour +Nouvelle Vag +Nov Nova +Nova Lova +Nova NK Nova Rez +Nova X1 NovaDragonX +NovaNovNov NovaNova_v1 +NovaaDay +Novacult Novahearts Novahria Novalisky +Novamus Novaqueen +Novaspell +Novelled Novem +November Air Novesey NovicePlayer +Novist Novizy +Now Boarding Nowa +Nowa Lyfe Nowlan2 Nowoxifer Nowt Nowuh +Nox Irea Nox1de +Noxai +Noxeek Noxelder Noxia Noxied +Noxif +Noxifer Nino +Noxifer Noob Noxifers Noxiti Noxitrall +Noy rs +Noys NozFox +Nozel +Nozzie +Nozzles +Npc Contact Nppb +Npzu +Nrsa Nrse +NsG Flames Nshit +Nsns khalifa Nsoak +Nsor Nssc +Nstfu Nt0y NtQuiteRamb0 Ntsf +Nu ff +Nub Cakes +Nub Cape +Nub Die Plx +Nub II Elite +Nub at PvM Nubby +Nubby Nubnub NubbyOtter +Nubciclez Nube Nube101 Nubje +Nubslie +Nubthhh Nubutraum +Nuc1ear Nuck +Nuck Formies Nuckie34 +NuckinPhutty +NuckkinFuts +NuclearDron3 NuclearShift +Nucleons Nucleotide Nucu +Nue +Nuffedyr +Nuffers Nuffyz Nuffz +Nuge Hews Nugget +Nugget Farm +Nugget8453 +Nuggo Nugs Nuhapiippu Nuigaia Nuirokay +Nuk3rO +Nuke Nuke Rofl NukeDuke98 Nukkumassa +Nukooa +Nukster +Null God +Null Quiet +Null Scaper NullObject +NullTalisman +Nulliko Nullish Nullly Nuloh +Nulsen +Nuluki +Num1 StepSis NumTaker Numazu +Numb God +Numb Too +NumbButWhole +NumbaWanGIM Number +Number Forty +Number is 47 Number1 +Number1 Bass Numbermatch Numel Numenor21 Numerater0 +Numerikaali Numidium +Numinious Numismatist Numpad +NunWithAGun Nuna Nunac Nunc Nuno NunsRtight Nunsbox +Nuoli Z +Nuori Karhu Nuparu22 Nupayne Nupiso Nuqubba +Nuqx NuranJeezes +Nurco Nurdal NurgleBurgle +Nurrminatorr Nurse +Nurse Turbo Nurselie +Nursering Nusky Nussi Nust +Nut Nut +Nut on Nieve NutStains +NutZak +Nutgood +Nutipaa +Nutjes Nutrino +Nutta Nutu Nutviper +Nutwic Nuubby1 Nuubi85 Nuuh Nuuhi Nuux Nuwanda +NvMe NvMy +NvMy Madness NvUs +Nvh Nvidas +Nvious7 +Nvr Ironman Nvsh Nwkz Nxcv1 +Ny e +NyThinIsFine Nyaa Nyalesh Nyam2 Nyannoid +NyarkThunaki +Nybocs +Nydarb +Nydde Nydloh Nyesqui +Nyholmeen +Nyk X1 Nykat Nyler +Nymlonn Nymph Nyppe96 Nyquistt +Nyranger99 Nyraxion Nyrkki +Nystuen +Nythan Nythos +Nythsama Nytrate +Nytrogen Nyula +Nyx Avatar Nyx296 +Nyx_TrueShot NyxxiePixxie +Nz Str +Nz Boy 96 +Nz Str Nzfisher +NzhiaT Nzpkers +Nzz +O C M W +O E M +O G Herbs +O G RasTa +O K E Y +O L D Z E +O Lewis +O N W +O O 9 +O O O O O O +O Rodrigo +O TUGA LINDO +O X Y G 3 N +O ctopus +O dhran +O hio O l m e w +O m a r +O o g a +O s s e +O stake +O-Scape +O-Six Newb +O-SobaMask O0BY +O5O5 +O64 +O7 offroad +O93 OBD2 +OBGYN doc +OBKush69 +OBLV Empson +OBLV KKRKAT +OBLVPIPEBOMB +OButterstick OCBP OConnell ODarnUFail +OEM +OFFS NFS +OFS I +OG AlanEspo +OG BlowsCOX +OG Boney +OG Ezena +OG Germ +OG Greenery OG H4zed +OG Horizon +OG IronAaron +OG K1ng +OG Kassu +OG Kenobi +OG Mr Crispy +OG PvMer +OG SUOMINEN +OG Sage +OG Soul +OG StrongBoy +OG Totti +OG not OJ +OG-Bebardo +OG2 OGBloodFam +OGJezus +OGKingRavenZ OGLman416 OGRockstar OGTeacher OGThicPickle OGWhitePanda OG_Westside +OH NO PLZ +OHC +OHP +OH_mes OHv3rdose +OINK OINK XD +OId Nite OJ AVENGER OK Thug +OLD MAKAVELI OLUTMIES +OLY Krzanich +OLlVER +OMEGAPEG +OMG U DID IT +OMG a GIM +OMGstepbwana OMNIV0RE +OMX OMYLANTAAAA ONCES ONDERBOKSEM +ONE EYE Q ONEBIGJOKE ONEM0REBEER +OON HUMALASA OOOGAABUNGA +OP Yoyoei +OPEN NA N00R OPIronman OPName +OPP2 +OREG0N ORLZU ORlCHALCOS +OS Anthony +OS BAKA +OS Badger +OS Flexin +OS Gdtn +OS Glory +OS Hadley +OS Iron Life +OS Jordan +OS Lou +OS Maroko111 +OS Masochist +OS Nat +OS Reecy +OS Versace +OS Weesh +OS dah +OSBudknight OSBug OSCannabis OSCastleWars OSColbyStock OSGingerkiin +OSGraham OSGrindscape +OSHH OSRASS -09Reaper -09Rhys -09Rvape +OSRS +OSRS Brody +OSRS Cyze +OSRS DANI +OSRS Denmark +OSRS Dresse +OSRS Hostage +OSRS Jim +OSRS Joshua +OSRS Keegs +OSRS Moey +OSRS Rapaaja +OSRS STIMPY +OSRS TOBI +OSRS Tired +OSRS Zezima +OSReaper OSSD OSSoulwars +OS_AndyB +OS_Jazzy OSzerox +OTF SPRINKLE +OUTSlDERS +OWE N OZANN +O_o +OachKatzal +Oak Cliff +Oak Tree Ted +Oaonui +OasisRS Oathbringer Oathh +Oatmels +Oatre OavTXXrC2Bc +Ob1tuary ObZenpai Obama Obama2014 Obanana Obby +Obby Apples Obby Cam +Obby Cape +Obby z +Obby200 Obedar +Obelisks +Oberschicht Obese +Obese Scrub +ObeseMaurice ObeyBdubb +ObeydaWalrus +Obfuscatiion +ObiHiGround +Obib Object62 +Objection +Objektas Objektijuht Oblitergator +Obliticks +Oblivion Oblodzisz +Obloid Oblv +Oblv Jass +Oblv mobi +Obnoxious Oboi +Obos +ObscureFruit ObscureHeart ObscureLogic Obscuremelon Obsel Obsidian Obsidian222 +Obtain Shade Obvious Obviouseboyz OcaJomba Ocachobee Ocara +Ocara Debrew +Ocarious 2 Occ0x Occcy +OccrumsRazor Occulent92 Occupation Occupational Ocean +Ocean Fog OceanMachine Oceanside Oceanux +Oced Ocellari +Ocelvon +Ocg +Och Ochen Ochit Ochrie +Ockult +Oclusvision Ocra Ocst +Octagawn +Octane07 Octane09 Octanes OctarineJake @@ -16587,155 +34833,375 @@ Octave Octavia Octet October +October 12th +Octoberain Octopossy Octoppus +Ocuflox +Ocular Rift +Oculist +Ocyd +Odang +Odawg121 +Odd Focus OddPhallus +OddSaus OddSnipa +Oddjob46 +Oddloop Oddni Odeee +OdenKozuki OdensWinterG Odeon Oder Odezt Odin +Odin Slayin +Odissious +Odiums Champ Odlaw Odonodb +Odophru +Odors Odssy Odsza +Odyssey Fe Odyssey310 Odysseyyy Oenhausen Oenonymaus +Oepeloetje +Oepsie +OetOet Oetje +Of The Rune +OfThePirates +Off Pace +Off Rate +Off a Bar OffMyChest +OffPeesh Offer Offering Offers +OfficerTFist Offka +Offlime +Offret Offset OffsetPaul +Og Voldemort OgAcco OgChrisCudi OgDankRiddim OgHood +OgSephiroth Ogazumu Ogg25 +Ogisek +Ogkek +Oglong King Ogmj Ogopogo5000 Ogre Oguussie +Oh Bee One +Oh Billy +Oh Canadian +Oh Daddy Yes +Oh Edgeville +Oh Gzuss +Oh Hi Marc +Oh Im Ben +Oh Its Toast +Oh No Oreo +Oh So Alone +Oh Tylor +Oh Vacancy +Oh sh Oh4Sure OhDannyBoii OhEmGe OhHaiMark OhHeyGrant +OhIScott +OhItsMatt OhJezuz +OhLookABot OhManOhJeez OhMyJosh OhMyShoulder OhNo OhNoMyHymen OhTurtle +Ohbi +Oheck Im Fe OhhCaleb +OhhMikey OhhTiS Ohio +OhioTexas +Ohlander +Ohm Calvin +Ohm Free Ohpiate Ohseeya Ohtoodles +Oi +Oi Matey +Oi You +Oie Oifey +Oij Oikeisto Oikis +OilHawk +Oiler1k Oilertay +Oilux OilyMeat Oinky Oishii +OisnesA Oispa +Oispa Kaljaa OjibweJohn +Ojigkwanong +Ojman +Ok Bud +Ok G +Ok Jose +Ok a y +Ok-sail zip +OkYh +Okadolf +Okageo Okaiko Okay +Okay Mommy +Okay Papi +OkayCCal OkayTwilly +Okeechobee Okeydoke Okino +Okke +Oklahoma Rat +Oksa Okupant +OkzobRS +Ol Mucker +Ol Salty Dog +Ola Nordmann Olajuwon +Olav Jr Olav2002 Olaveraaa +Olaviitsio Olbyy +Old 9m9a9 +Old Abe 101 +Old Anao +Old Beer +Old Bill +Old Birdy +Old Boy +Old Champ +Old Dabs +Old Delf +Old Dry KBAC +Old El Paso +Old G ordao +Old Greggg +Old Jedi +Old Lancer +Old Man Bob +Old Man Cris +Old Man Rabb +Old Maxie +Old Mog +Old Monkey3 +Old NlCO +Old Nutbag +Old Olorin +Old Pixels +Old Player22 +Old Rangoon +Old Sbi +Old Schooled +Old Toaster +Old Yammu +Old man Kent OldBae OldBlueish +OldBruce +OldDirtyMan +OldFishLife +OldGamma OldHitta +OldHulver +OldQwaltz +OldRzzlTrog +OldSkewlRS OldSkoolKush OldSteinlein +Oldbaldman5 Oldburnzy Olde +Olde Nite Oldemark +Oldinsh Oldizjr Oldman +OldmanP +Oldmanhandz Oldschool Oldschools OldskuleRS +Oldsusik +Oldtimate +Oldwhiteman +Ole +Ole IrIsh +Ole Martin OleFrumpacus +OleMusky +OleStinkBait +OleTejas Oleg Olei Olemand8 Olen +Olen Iron +Olenpromees Olertomb Oles OlesDpaul Olette Olfre31 +Oli +Oli xo +OliTheFarmer Oliivi +Oliivi Rouva Olimpus Olios Olivas Olive +Olive You +Oliveinho +Oliver GIM +Oliver The G Olivia Olkikalsar +Ollie 01 +Ollivanders Ollonjonny Olly +Olm Alone +Olm Likes me +Olm Nut +OlmMyGod +Olmar Olmek +Olmie Wolmie Olminous Olmlet Olmlit Olms +Olms Daddy OlmsNutz Olmsbish +Olmspetwhale +Olobor Olrox +Olspa Rahkaa +Oltsu Olvi +Olympic 33 Olysian Olze +Oma r +Omaci Omar +Omar Kai +Omar Khaldun +Omar Uchiha Omarinski +Omatunto Omaxiu +Ome Sjors Omega OmegaBeast OmegaRs3LuL +Omegathletic +Omegatron +Omen Forrest +Omena3 +Omerta Omfg +Omhellz yea +OminousMan Ommetje Ommy Omne Omni +OmniRick Omnicide97 +Omnient Omnivaw +Omolon +Ompikuusi +Omroep Max +On Blocks +On Rate +On Steven Dr +On Tv +On a Bar +On the alt +OnAMeme OnDeaTHrow +OnPoint OnRedPanda OnTheEdge +On_log_n +Onana Onbekend Onbekende Once +Oncey Onchune Oncle +Oncle Jazz +Onderwerp +One Arm Chin +One Eyed Owl +One Lazy Cat +One Leaf +One Off +One Piece X +One Record +One United +One Wolf +One au One life lad OneBadNWord +OneBoxBox +OneCallBTW OneClickMan +OneDayIs2Day OneFalseStep OneFive +OneForAll8th OneFunkies OneInchDong OneInchPeen OneJohn +OneLeg1 OneLifeGiven OneLostMain +OneManBand OneManBucket OneManNoob OneManTeam @@ -16748,201 +35214,383 @@ OneSillyBoi OneSnappyBoi OneTera OneTickAway +OneTickBrick +OneTickyBoi +OneWhoKnox +OneWish Onebuc +Onedeadthing Onehidefrog +Onelaughbob Onesecafk +Onesome Onetick Onexia +Onfight +Ong Gia Onidhre Onika OnionGoggles Onism +Onitir +Onkdah +Onke +Onkel Dunkel Onkelleif +Onkologen +Online Coach Only +Only 1 Iron +Only Bussy +Only Crazy +Only Fight8 +Only Scotch +Only Victims +OnlyBans OnlyBrand +OnlyChompies OnlyCraig +OnlyDanss +OnlyDrags OnlyFFAns OnlyFans OnlyFansss +OnlyFlies +OnlyGain +OnlyJars +OnlyJoel +OnlyJordann OnlyKingKoob +OnlyKisses +OnlyKnuup OnlyPepsiMax OnlyRussell +OnlySolos OnlyTheCold +OnlyWithTime Onlyfans Onlyfarm OnlyyMike +Onn Onno Onoezeleer Onoin Onox OnthatGrindd +Onu-sama +Onubis +Onus Onuzq +Onxaba Onya Onyksi Onyx +Onyx Farming +Onyxe Onze +Oo Step Back Oodenssiii Ooelluoo +Oof Dankus Ooft Oofus +Ooga Booga C +Ooh Skill Em Oohf Oohfunkyme +Ooiboi OokOokStrats Ookfried Ooktism +Oomp Oompy +Oooh Baby +OopsiePoopsy +Oopsralla Ooskabible +Oouu Weee Ooyf Ooze Oozymooz +Op Closed +Op Wout +OpGetGood +Opa Bravo +Opa Snipes OpaJei +Opacki +Opal Mafia +Opalfruen Opatsuno +Opel Vivaro Open +Open GL +Open osrs +OpenAI GPT4 OpenTheTill +Openpuppygo Opera Operacional Operetta Opex Opgezwolle Ophelia +Ophelia Prim Opiez +Opihr Opinionated +Opitz OpiumWard +Opkikkeren Oponn OppaSky +Oppai Heart +Oppai OwO Oppanox Oppheng +Opposite OppositePoop Oprego +Opreus +Ops +Opt Optic +OpticAGS +Optical itch Opticplex Opticplex09 +OptimistLuke Optimus +Optimus Pork +Optiver Opts +Optus Optyfen Optyfengauww +Opus Deo +Opus149 Opus22 +Opyomi +Oqagin-san Oqlak OracleOf +OracleStud Oraclez Orange1213 Orangeboy333 +Oranje Panda Oranqe +OrbWeaver Orca Orcanater +Orch Orchazm Orchid Orchidzx OreSpasm Oreano +Oreeezy +Oregon Weed Oreinstein +Oreo Empire +Oreo UwU +Oreo Wafer Oreos OreosInMilk Oretizm Oreton Orezzer Organic +Organic Hemp OrganicOnion Organics Orgasmique +Orgo +Ori lion Oriaks Orienterare +Origens +Origin Puff +Original BA +Original Blu OriginalGoat Originaljim Originexo Orilion +Oringl Wafle +OriobanaOuhi +Oriole Orioles OrionDragon OrionRenegd Orjan +Ork Merchant Ormi +OrngFish OrngeManBad Orodyn +Oronius +Orphaaan +Orphaan Orphan +Orphan Annie +Orphan Soul +Orphan Twin +Orphan8r +Orpheus +Orpoerpo Orrey +Ors striker Orthago Orthiss OrthodoxJoo OrthopodMD +Orvud +Oryx Aksis +OryxZebu +Os Him +Os Hitman +Os Rolex Os SMDJ OsBlackBolt OsBrody OsBudknight +OsDave +OsIronCrash +OsRs Vibes Osav +Osbenji +Oscar Jacob Oscarnight90 Oscietra Osdorp +Osetek Osgu Osgub Oshawnasi +Osidric Osimhen Osiris Osjuicey Oskar +Oskar XVII Oskari Oskinathor Osmo +Osrs Bane +Osrs Dimitri +Osrs Goku +Osrs Mistren +Osrs Woolley +Osrs2007 +OsrsBawlz +OsrsDavid +OsrsVibes +OsrsWiki +Osrshabibi Osscar69 Osseb Ossi666 OstBakarn Ostengar +Ostentatio OsteoSoon +Osteonics Ostidecriss4 +Ostmumten Ostracized Ostrich Osumi +Osvo1d Oswaldorun +Oswin Oswald +Osxu47 +Osykoo Osyrs +Otago Nz +Otakar Otaku +Otan Olutta +OtarsBeast +Othantos Othelllo OtherJackets +OtherWize Otho +Otomycosis Ottarl Ottchy Otter OtterMG OtterMan Otto +OttokarIII +Ottoman1907 Ottwanbre Ottzor Otyugh +OuchIFarted1 Oucho +Oud Nieuws Oudenophobic Ought OuiDaddy Ouija +Oukashi Oulusta +Oumaji Oumarou Oumu Ounaaja Ouncie +Our ClapTrap +Our Kid +OurLordAllah OurPage +OurTbow +Out Of Herbs +Out of Town OutOfBreath OutOnBail OutR Outbid +Outblasted Outblasting Outbox +Outbreak46 +OuterBodyXP +OuterShock +Outgrinded Outie OutlawBTW OutofQontrol +Outofcontrol Outohere Outperform +Outplayy Outra +Outs Outsider058 OutsidrR OuttaThePan Ouze Ouzi +OvO Ovaryacted Ovaryacting Ovela +Oven Dish +OvenGold +Ovenschotel Over +OverRoid +Overburner67 Overcame Overclockers +Overdose1911 Overhand OverkillWill +Overklokkd Overlegen Overload Overload_inc @@ -16953,155 +35601,334 @@ OverpowTV Overprepared Overrated Oversight +Overspan +Overspec +OvertPyro Overtaxed Overthinker Overtus Ovid +Ovl +OvrLrd Zaros +Owed OwenFever +Owip +Owl Full +Owl MD OwlMyLove +Owlea +Owlpeth +Owlson +Owly +Own Risk +Own Skillz70 Own617 Ownage Ownd Owned OwnedByMK +Owner Previn +Owning Owning4babes +Ownsz Ownt Ownyouall6 +Owusu Owwi +Ox Prez +Ox0 Ko0ol O0 Ox310 +OxStache Oxct +Oxcy +Oxeon OxideIon +Oxidising +Oxidizing Oxiduck Oximas Oxit Oxium +Oxjenks +Oxoi +OxyCottN OxyDream Oxycotton Oxyoxyoxyoxy Oyrn Oyster +Oyster37 Oyugock Oyvin Ozaiii +Ozak Ozcred Ozeana +Ozenc Oziarch +Ozin OzirisRS Ozium Ozmone +Oznerbon +OzokuLight Ozuhan OzyMex +OzzMate +Ozzb0 Ozzerro Ozzie Ozziemate Ozzio Ozzy +Ozzy Hobbit +Ozzykye Ozzys Ozzzyy +P 0 W N E D +P 0 E F +P 0 R G I E +P A M K A +P A P Z +P A R N Y +P DIRTY SODA +P EDRAO +P Eng +P I T +P K +P O L I S H +P O T A T O +P O V I +P Purts +P R O X +P R S +P V M Lew +P W A Y +P Y R O +P a n x o +P eachy +P erfect Ten +P h Z o r o +P i +P ix +P ixe l +P o z e +P oH +P ockets +P r o g r am +P udding +P ure +P uss Wizard +P00ksalukes P0CKETPUSSI +P0ES P0PE +P0RKB0I +P0ST HUMAN +P0TIONS +P0TTER P0TUS P0ddy +P0nti4c P1CC0L0 P1CK3R1NG P1Hat +P1SSBANDIT +P1ZZA EATER +P1ZZY +P1ckleR11ck +P1ssDr1nk3r +P1stols +P1tts P1zzaTheHutt +P1zzaa P2Chill P2D2 +P2P Race Car +P2w Scape +P3C P3RKELE P3RLICH P3RMMUT3D +P3T3 IS G0D P3TAR P3aceful +P3loce P3rcy +P46 +P4CK P4DLA P4RKER04 P4cH P4sk P5ythix +P6D +P7DRO +P9 +PA N I C +PACK WATCH +PACKETLOSS +PACTV PALAK1KO +PALL3N +PALSAM PALSANMAKI +PANTY DROPER PAPA +PASTORIKONE PATPATMAX PATRlOOT PAUL +PAULWALKER +PB Barbie +PB Dauntless +PB J +PBT Yumi PBTM +PBnJ +PC PrincipIe +PC0TE PCCZ +PCDO +PCE PDGA PDizzleworth +PE strategy +PE3ST +PEAMINlSTER PEARSON92 +PEC Zwolle PEEKYNUMBER1 +PEEinAcup PERMA +PERSE PET3R +PET3R PAN PETEAIR +PF Killaz +PFOF PFalciparum +PG MAIN +PG-13 +PGA_Pope PGMid PGmeupe93 PH1SH3DB4N +PHGomes PHLP +PHURY PIAN0 PICC +PIITAA PING +PINKYxBRAIN PITFIGHT PJ Salt +PJRovers +PK NOOB BR 2 +PK Shark PKTHEOTHER PKing PL4T1N4 +PLANET SHlT +PLAYER827324 +PLAZID PLSDONTPLANK POGPOGPOG POGvM POMP3Y +PONYRIDER73 POTTER +POTUS DJT +PPale PPorappippam +PQMF PQWNEM12XXSS PRADA PRAISE +PRAISE FOOT +PRAISEHELIX PRETTY +PREW0RKOUT PRIM0B0LAN +PRIZ0NM1KE +PRODaintOFFu +PRlNCEE +PSMark +PSO Pokie PSRB PSTjager +PSY OPERATOR PSacz PTKNT PTMN PUBG PULL +PULL A GLOCK PUNANYCEZZ PUNANYMASSIF +PUPPY SIT +PURP xx +PURPLE MAN X PUSHUPS PV60 +PVM PLUS PVP +PVM Zem +PVM lifee PVMGrim PVMramranch PVPJACKUS PWNJoLee PWNl +P_rple +PaIe Nimbus PaIm PaJau PaPaSaucee +PaPePiPoPuPy +PaR0 PaShango PaTeraNauu +Paaaants Paaatriick +Paarse Kat Paarty +Paatse PabIoEscobar Pablana +Pablo Q +PacDan PacYakJack Paca Pace +PaceYourself Pacellino Paciar +Pacifico0ler +Pacifist Pack +Pack Yarack PackAnother1 +PackYakistan Packapunchd Packers +Packers Ammy +Packfan35 PackingCope Packmanjr PacksOfBagel +Paco 41 Pactii +Pad of Note +Paddy Simcox +Pademelon Padge Padraig Padrew Paduann Paehkisfe Paem +Pafffy Paffio Pagan PaganFox @@ -17110,60 +35937,115 @@ Page Pagman73 Pahapukki Pahizz +Pahys +Paid 4 Paike Pain deliver +PainInTheAx +PainRain Painb0ws Painovoima PaintBoxx Painta Painted +Painz Wrath +PairODocks Paixo +Paiyrd Paizuri Pajaaay +Pajama0sam Pajaripipari Pajita Pakaika Pakanajumala +PakasteOlut Pakford Pakmaniac +Pakr04 Palabutoh Palad1um +Paladijn Mb Palapak +Palataan Palatro Pale +Pale Marble +Pale Player PaleCocoon +Paledeano +Paleek +Paleek sucks Palenaatio +PaleoRanger PalestineHC +PaliRebel Paliperidone +Paljad Pallas +Pallas Cat +Palle Panik +PalliJarn Pallihintti Palllister +Pallof Palmboom +Palmboom95 Palt +Palworld CEO Paly PamPams Pamdora +Pamela Isley Pampas +Pamz +Pan Biceps +Pan Jawel +Pana Sicknez Panacea +Panal +Panarin +PancakeOSRS +Pancaker Pancakey Pancukeshi Panda Panda Godz +Panda Pride +Panda Rua +Panda Seany PandaBier PandaBrommer +PandaKIKI PandaMan PandaMcfanda PandaPowa +Pandasadge Pandaux Pandaz Pandeh +Pandemicbowl +Panderal Pandiman +Pandini_O +PandorazBox +Panelka Panera +Panesii +Panette Panferno7 Pangolins +Pangs Panic +Panic King +Panic Papi +Panic Switch +PanicThenRun +Panicupdate +Panini Panixate Pankekee +Pankki on Panky Pannu Pano @@ -17171,32 +36053,82 @@ Panoople Panorramix Panqueques Pans_Gaming +Pansendoras PansophicaI Pantaloon +Pantelic Pantera1230 PanteraWalk Panthalassa +Panther_Cap +Panties D0WN Pantix +PantlessDuck +PantsShitter PanzerMarkV +PaoZi41 Paoul +Pap Smoke Papa +Papa Beat Me +Papa Beer +Papa Chibs +Papa Falco +Papa Glock +Papa Hitman +Papa John +Papa Kev +Papa Peck +Papa Penguin +Papa Raniel +Papa Rook3 +Papa Scape +Papa Shaydee +Papa Sheek +Papa Snacks +Papa YY +Papa Zuk +Papa jinx +Papa tim PapaCart +PapaFozzy PapaJohn PapaJoyce13 +PapaMoxie +PapaParsley +PapaSarducci Papabeer +Papagecko Papaija Papalotee Papapa Papaya +Papaya Pete +PapayaGod PapayaPetee Papegaaitje Paper +Paperbag Papi +Papi Baz +Papi Chop +Papi Feb +Papi Fish +Papi Gains +Papi Okapi +Papi Sam +Papi Sean +Papi Six +PapiTron Papicito +Papicodone +Papido PapieLexus PapierHier +Papierschere Papii Paplip +Papo Sauce Pappa Mauly PappaPizza Pappanopolis @@ -17204,65 +36136,120 @@ PapperNapper PaprikaBoi PapuIsThatU Papukaia +Papyea Fruit +Papz Mage Paqan +ParKy_ParK +Parabhjeet Parabolic Paracleis +Paradoos Paradox +Paradox 2277 +ParadoxAU +ParadoxCrux Paradoxal Paralimpian Parameters Paramost +Parandrus Paranosys +ParaplegicIM Parappa ParasiteHunt Parasitoid ParasoxX Parazino Parc +Parc Ferme +ParchedToast Parciparla Parent +Parfour Parhaat Pari +Pariera +PariguayoGL Parikh +Parikkala Parish +Parjesh Park +Parkchae Parkehh +Parker177 Parker1770 ParkerSquats Parkerrr Parkuh Parky Parkz +Parley0 ParmsG8 +Paroni007 +Paront +Parotis Parox3tine Parrot +Parrot Champ +Parrot Le Fe +Parrot Poop +Parsecs Partey Parth4903 Parthnix +Particulae Partly +Partonax Parttime Party +Party Fraud +Party Pete +PartyRock +Partyhaty Partynexdor ParuParu Parvovirus +Parx98 +Parxe kurita +Parzival32 Pasadinas PashkaPushka Pashmina Pasianssi Pasiiba90 Pasikaustes +Pasito PasitoBandit Pasje +PaskaJatka69 PaskaneHomo +Paskie Paskis Pasmo +Pasrules Pasta +Pasta Lance +Pasta Mancer +PastaShel Pastabrain +Pastafreezer Pastagonia +Pasticcione Pastor Pastry Pasu +Pasza1357 +Pat NoScythe +Pat The Nerd +Pat the Cat +Pat twumasi +Pat_y +Pata2006 +Patalopodus +PatchRS Patchley +Patdog666 Pate Patella PatentedName @@ -17271,6 +36258,7 @@ PathTracker Pathogen Pathways Patio +Patious Patmantheman PatoVelaz9 Patojo @@ -17279,19 +36267,34 @@ Patrexion Patrician Patrick PatrickClick +PatrickLaine Patrickp35 +Patrik Laine +Patriot88 +Patriotscape Patriotsp +Patriottj +Patrolliin Patronique Patrouski +Patryk 1 Pats Patsey PattMyGun Patta1 +Patte Pattos +Patty C +Pattycakes19 Pattyrick8 +Patyfatycake Pau1ekas Pauk Paul +Paul 0 +Paul Beer +Paul Ski +Paul0 H Paul007 Paul90333 PaulD @@ -17299,13 +36302,23 @@ PaulOH10 PaulTheRabbi Paulchritude Pauleee +Paulest Paul PauletteRose Paulius +Paulk23 Paulrat +Paulrat 3 +PaulyNFS +Paum No Xeem +PauperPlayer Paupy +PauseGuy Pauwels +Pauwels v2 +Pavies Pavio Pavla +Pavlacci Pavlvs Pawggrs Pawgz @@ -17313,46 +36326,80 @@ Pawko Pawlmeister Pawlu Pawlzer +Pawn 69 +Pawn M8 +Pawrie Pawwsy +Pax Mundus Paxin Paxy +Pay2ClickLol PayMyDeedFWD Payne_Trayne Paznos6 Pazuta Pazzo-Repack Pb Fe +Pb and Jd Pbby Pbkillua +PbyOne PdaddyReborn +PdfPKerNoGF +PdiddyReborn +Pe en +Pe t er +Pe1ipp3r Peabody PeacandLove Peace PeaceNLove31 +PeaceOfMind Peacebuild +Peaceer Peacefrog +Peach s PeachKing +Peaches5000 Peachh Peachhh +Peachy Tank +PeachyBrute PeachyDean +Peaco Peacoat Peak +Peakado Peake +Peake7 Peakleaf Peaky +PeanutBTW Pear +PearOfApples +PearlNechlis +PearlWeed +Pearlito Pearshaped9 Peasant +Peasyy PeatMoss Peatie Peba +Pebbex Pebblez PebisGuan Pebl +Pebu Pebz PecanBread11 +Pecker Punch +PeckerFish +Peckerflexer Pecki Peco +Pecs +Pectorialis Pecuni75 Peddler Pederbuus @@ -17360,30 +36407,57 @@ Pedestrian01 Pedro Pedro5901 Pedtato +Pee Jay Salt +Pee Kay Err +Pee Mud +Pee On Irons PeeJayPlayz PeePee Peeanut +Peeble +Peeeeeekaaaa +Peeke Peel +PeelMyCarrot PeeledBanana Peely Peen PeenLover61 +Peep Taimla Peepo +Peepo Parker +PeepoPants +PeepoRiot420 +Peeps Cx +Peepzilla PeerTheSeer Peernicus Peeshuuu +Peest PeetrusEst +Peevish Peevy Peezerthecat +Peg Boots +Peg My Arse +Pegasian Pegasians +Pegasus51C Pegi18 +Peha Pehkis Pehmolelu +Pei898 +Peighniss Peiin Pein Peipeilaile +Peipi Pekaia +Pekays Pekdon +Pekka Elo +Pekka-Eric Pekka557 Pekkaa Pekkaad @@ -17393,105 +36467,211 @@ Peksaad Pelaa Pelaaja1 Pelco +Pele Marreta +Peli Moapa Peligroso Pelikaen Pelippper +Pelirroja Pelmee Pelosi +PeltiPirkka Peltolammi +Pemiel +Pen Sir Pena +Penally GIM +Penance Boom Pencelis PencilVesta Pendax PendulumC Penetrader +Peng Lightey PengMaster +Penge1616 Penguin +PenguinBelly Penguino Pengwim +PeniAnus +Peniel Peninsula Pennstate Pennsylvania PennyPinchnJ Pennybag +Pennycord Pennywise Pennywise070 Pentagrammi +Pentektonyx Penthera +Penthrox Penthus Pentu +Penward Peopledud Peoples111 +Peor +Pep Kroket Pepar +Pepar Kakan Pepclub101 Pepco PepeGUH PepeHang PepeLaughing PepegaScape +Pepeh Pepemiguel +Pepo Is Me Peppey +Peppi PeppiEnSossi +Peppusieni +Peppy Pete Pepsi +Pepsi Maxed +Pepsi Maxia +Pepsi575 +PepsiMaxL1me PepsiTwist Pepsies Pepsipowars Pept +PeptoGlizmol Pepuszka126 Pequenaud Pequette +Per Ke Le +Perc 3m +Perceive +Perceptivity +Perch Curry Perchlorate +Percy Grail +Percy Nash +Percy Turner +Perduh +Peremees Perfect +Perfect Dark +PerfectCurse +PerfectJerni PerfectProof +Perfectaaa +Performax Perfringens Pergert +PerhapsGuy Peridots Perikles460 Peril Perkinatored Perky +PerkyPorker Perlen +Perm II Mu8e +Permabulk Permded +Permedd +Permer Permuh Pernix +Pero Scoped +Perox Perp67 Perpl +Perplox Perrault +Perrif +Perry Hubes +Perry T Persephatta Perseveranca Persian +Persilja +Perspective +Pert +Perterritus +Perth +Pervy x Sage Pesiz Pesoprkl Pessimism Pest +PestGodd Pestilance7 +Pestilent Bt Pestle +Pet Alpaca +Pet Awowogei +Pet Cape +Pet Crusader +Pet Eric +Pet Hunta +Pet KBD +Pet King +Pet Luck +Pet Meowtain +Pet Smuggler +Pet The Cats +Pet Ty +PetBoost PetCorp +PetHuntBrad PetHuntGrind PetHunta PetHunting PetPlease +PetSpooner PetUrSausage +Petal Petalite +Petar228 Petarss +Petched +Petchy inis +Petcord PeteRePete +Pete_901 Petega +Petelgeuse1 +Peteniice Peter +Peter DIY +Peter Dupas +Peter Kent +Peter97 +PeterLimbeek +PeterPlanker PeterRS PeterTheSalt +Peterh Peterm +Peterszoees +Petey pleb Petit PetitKeBeQ Petite +Petite Poire Petless +Petooted Petpet +Petrenkovitz +Petricsh Petriq PetroX77 Petrosian +Petting GIM PettyName Petuhh Petz +Peuramaa PewTheMeow +Peweherman +Pewming Pex3 PexBoi Pexci @@ -17499,56 +36679,97 @@ Pexezz Pexterity Pextill PeytyPoo +Pez xX +Pez za Pezy Pfiny Pfister Pfle Ph0g +PhD Fred +PhD Funk +PhD in TCG PhaMaTics +Phader Phaero Phai Phainesthai +Phalamon Phallic PhallusBigus Phamia Phamit Phant +PhantomDred PhantomFiend +PhantomLogic PhantomVS +Phantombear7 Phanton PhappleSauce +Pharaoh Chad +Pharaoh Ion Pharmafia +Pharqen Phase +Phasedd Phasing Phasmatus Phasmatys Phat +Phat Dik +Phat Pat PhatAsher +PhatFrat Phathead Phatman348 +Phats PhatsoCallum Phatt Phatty Phattyftboy Phaxe +Phd n Arteez Pheasant +Pheasant Egg +Phels PhenXX +Pheniex2 Phenomenal +Phensa +Pheonixess +Pher Phernix Phetty Pheus Phex Phi184 +Phibes Phil +Phil Coulson +Phil Mcrakin Philip +Philip424 Philipp Philkwl +Phille +Philli Blunt +Phillies +Philliez Phillip +Phillip R Phillipp Philly +Philly Sucks +PhillyFiller +Philoi Philosophia +Philou +PhilsBent +PhilsUnlucky Philth Philtration +Phin_C Phinxu Phinz Phipple @@ -17556,90 +36777,181 @@ Phishn Phizo Phlaja Phlegmy +Phlemming Phloppster +Phlopsy +Pho Z Phobias PhobosDeimos Phoibos Phonatik Phone +Phone Number +Phone Scaper PhoneHC Phonebook Phoneman +Phools Phoque +Phor Skin Phosani Phossa +Phostus Photographs Photon Photonic +Photos +Phragasm Phrak +Phrexyian +Phrez PhriarPhace +Phrizo +Phrocks Phsteven +Phug +Phugma Phuke Phuket Phwan +Phxrm Phylum +Phyrlo Phyro Phyronex Physics +Physics Jedi +Phytz Phyzxs +Pianio +Piano Hands +Pianoanddrum +Piantissimo Piasa +Pic of Feet +Picante Piccoloownsu Piccy +Pichi Slayer Pickl3Lover +Pickle Josh +Pickle Vick PickleKez +PickleSaucy +PickledWater Pickles4Me +Pickles69314 Picklzz PicnicBomber +PicoDico Picolo PictureID +Picuu +Picuwu +Pidbull +Pidbull 1 +Pidgeot18 Pidgey +Pidgy Pidiot +Pidrux +Pie +Pie Dish +PieGPT Piecekeeper2 +Pieces Pieck +Pieerio Piemaksa Piemans +PiemieJurrie Pieper +Piepieweenie +Pier Just +Pierced Wolf +Pierenbadje Pierniczek00 +Piestove Piet +Piet 21 PietKrediet Pieter +Pieter Zwart +PieterPep Pieterjan Pietermans Pietn4 +Pietrangelo +Pietrnogiets Piety Piety Prease Pieza +Pieza de oro Piffen Pigeon +Pigeon Soup +Pigeonmight +Piggi Smalls Pigi373 Piglette +Pigman461 +Pigmeu +Pigpikerush Pigpuffer Pigs Pigwardfrog Pihl +Piip MEEGA +Piipar Piirivalvur +PikaChar222 +PikaChin +Pikachewed Pikachos Pikachu +Pikachu87 +Pikachurine Pikachuz Pikkets +Pikkett +Pikku +PikkuSheikki Pikkupbrix Pile +Pile O Poo +Pile o Dirt Pilgrimage Pili +Pilli +Pilliad Pillifnutten PillowBoy PillowCowCow +Pillukarva23 Pilmir Pilodro PilsToTheMax Pilsners +Pilum +Pim Pam +Pimay +Pimfortune Pimp +Pimp Ralpert +PimpWeazel +PimpWhistle Pimpert +Pimpin Thots Pindaro Ping PingFlopped Pingu Pink +Pink Avocado +Pink Bar +Pink Cow34 +Pink Iron +Pink Lube PinkDrinkSip PinkShopRag PinkVoidZ @@ -17650,99 +36962,205 @@ Pinkywinky9b Pinkyx0xo PinndOutGoon PinnkBunny +Pinnn Pinpi Pinquana Pinsamt +PintOfMilf Pintel +Pinterests +Pinu +Piolin +Pioniers Piovendo +Piparikissa PipeQlo +Pipluppp +Pipo-badeend Pippinmary PippleNinchy Pipposan Pippuri +Pir Alain +Pirat Pirate +Pirate Kanye +Pirate Patch Piratey Pirelly Piri +Pirig0 Pirihuora666 Piripaque +Piripippeli +Pirjo +Pirjo69 +Pirk the pk +Pirkka Olut +PirkkaJokeri +Pirkkamies +Piroskinha PirpleSlirpy Pirres +Pirulitim Pisatronas Pisau +Piscarallius Piscis Piscolaz Pistacchio Pistoliftero +Pit Stain +PitGamin1311 +Pita Diver +Pitbulterje Pitby Pitchfork Pithikos +Piticarus Pitiless Pitinator Pitt +Pittaaaaa PitterPattr +Pittsburqh +Pitudin +Pivach +Pix Pixelle +PixarMarsTTV Pixel +PixelMuffin +Pixie Henge Pixieragnar Pixkekoa +Pizdec Pizza +Pizza Addict +Pizza Box +Pizza Flip +Pizza Mang +Pizza Patron PizzaDaHutt +Pizzaman5510 +PizzasIron +Pizzler +Pj The Pj +Pjotr +Pjt77 +Pjumi +Pk Bot 37 +Pk M4ster007 +Pk Wit P Hat +Pk3iru_Osrs Pk3r Range 7 Pk996 PkGoW PkMeIfUgey PkTheKid +Pker nr 1337 +PkerTrysHard PkforFun Pking +Pkingranged9 PkmnTrnrRED +Pkmort Pksorwd +Pkyr Pl0xed Pl3b PlELS +PlFFMAN PlGGY +PlHLAJA +PlMP PlMPPl +PlMl PlPPY +PlRATE KING PlSS +Plaagen Plaasda Plaat Placedoemax +Plaeggs +Plaid10 PlaidMarquis Plain +PlainIronMan +PlainNoGood Plaininsane +Plamt Plan +Plan B-gs Plane4611 Planet001 +PlanetPaul Plank +Plank Egger +Plank Sodplo Plank2G PlankForBank +PlankTan Planken bos +Planker +Planking Brb +Plankrunner8 PlanktSoms +Plant Herbs +Plantdaddyy Plap +Plasma Taco Plasmore +Plastikos +Plastiscines +Plat Kont PlatGX +PlatScrub Platinum2008 PlatinumHerb +PlatinumSage PlatinumSeif Platnuim Platnum112 Platpus3000 +Platyroo Play +Play Lazy +PlaySoloBro PlayToAFK Playbunny +PlayedBe4EOC Player +Player 0ne +Player 4519 +Player Gap +Player Name Player235711 Player35254 +PlayerIsBusy +PlayerSlayaa +Playpro5 +Plays high +Playtest Playthious Pleasantries +Please pot Pleasurehole +Pleb Nick +Plebbocs Plebiside +Pleblio Plebnex +Plebs Plebz Plece Plegh Plexasaurus Plexx Plez +Pliemp Pliep +Pliep Ploep Plips Plisski Plixious @@ -17750,210 +37168,412 @@ Plocc Plogbilen Plogdog Plomono +Ploop Plootbot +Plop deez Plopi +Plopr +Plopzorg Plorky Plorr Plostic Plot786 +PlovasYonder +Plovilas Plow Plowthrough PlsAName Plsmrlizard Pluc321 +Pluckky +Plug In Baby Plugatron Plugged Pluggen Pluhdl +Plukketje PlumTickler +PlumbThatA +PlumpGiraffe Plumper +Plundered Plunkton Plunukki +Plupian Plus +Plus Vite PlusZack +Plush Mole Pluto Plutonium +Plutonium 94 +Plym Plz LD Nat5 +PlzGiveBonds PlzRnGesus +PlzSpoonFeed +Pm Me Imps +Pm me to spy +Pm4 eloboost PmFun Pmy39 Pnak PneFc Pnia +PnutButtrJly PoachedLion +PoakedSussy +PoaneFoane PoarIIneemn +Pocholo Pocket +Pocket Cards PocketBandit PocketSock +Pockipickle Pocy2 +Pod x +Podvodnik +Poeiermolke Poem Poenes +Poephoofd Poepi12 +Poepjong +Poepsiee +Poerto Poet1321 Pofka +Pog Dog +Pog isma +Pog-kek-Lul PogChampagne PogMeister PogTato +PogTato Iron Pogba +PogoPochette Pogsled +Pogue4Lyfe Poikanen Point +Point Guards PointTax +Pointstormy +Poison Ives +Poison x Ivy +PoisonCobra PoisonX7 Poisonblack Poisonous Pokaroo2 +Poke Champ3 +Pokeaotics +PokedexNo258 Pokefreud11 Pokemaster Pokemon +Pokemon Ruby +PokemonScape +Pokemonguy16 +PokerPro +Pokerboy19 Pokergod720 +Pokifeet +PokimanesBF +Pokoloko +Pol o Polaar PolakYT +Polar PolarTrip Polarin Polarisi888 Polarus Polarward PolderLatina +Pole Met +PoleVault Polio23 Polish +Polish Eagle Polite +Politoed Polixo Polkapolkka Polkastarter Poll +Pollar i Pollekeuh +PollenJ0ck Polllie +Polllo420 Pollnivneach +Pollo Dry PolloGrande Pollofrit0 Pollum Pollywog PoloG +Poloskyy Polter +Polyamorous +Polycoffin +Polyesterday +Polygonise +Polyhedra Polynomail Polyphobia +Polywoggle +Pomi Xd Pommy Pompeyo Pomposity Ponas +Pond Scum +Pondres +Ponkito +Ponobi Pont Ponti +Pontifex Pony PonyOwner938 +PonyPorker +Ponzy FTW +Poo Socks PooAtPVM +Poobanans +Pooby Bag +Poodle Poofpooh +Poogen +Poogster Pooh +Pooh Breezy +Pooh Say Poohead92 Poohsea Poojabber364 Pook +PookiDaPooki +PookieB3ar +PookieBearOG +Pool Noodlez +Pool Toucher PoolboyFiji Poon +Poon Lips +PoonHandleMe +PoonTangPie PoonTappa Poonanjo Pooned Poonjuu +Pooohie +Poop +Poop Shidder +PoopyRico Poor +Poor Advice +Poor Clicker +Poor Content +Poor Nooby +Poor You Poortom24 Pooscaper PootLoops Pootzie +Pootzie_xox +Pop In Smoke +Pop N +Pop-up ad +PopTheIron Popcornachi Pope +Pope VI +PopeChamp +PopeDenis Popeet +Popepu +PopeyezGain Popfumes Popkorni +Poplo Popovich +Popoyoi Poppa +Poppa Bev PoppaChoonie Poppajohns +Poppin Awf +Poppscotti Poppy Poppymatt Pops24 +Popstar2 Popular PopyHarlow +PorWrx +Pordiosero +Pore +Pork Jerry +PorkCH0PZ Porkkanakana +Porksters +Porrie Porsche +PorscheDaddy +Port Khazard +PortUnionMan Porta Pro +Portal of I +PorterRobnsn Portrays Portsari Portuguese Portvakt +Porunga +Porygon-Z PoseidonDrip Posemann Posh PoshPenguin Poshker +Poshki +Poshkii +Posino Positivar Positive +Positivehp Possessed +PossiblyAFK PossumPally Possumi Post +Post Malone +Post Max +Post-Absurd PostCodee Postie PostmanPatt PostureCheck Posty2k +Pot Gatherer +Pot Of Greed +Pot Often +Pot Sharer +Pot cms +Pot v X PotScape +PotScape CC +Potapto Potato +Potato D Ben +PotatoButGay PotatoLlorch PotatoRangr Potatoqueenn +Potecito jr +PotentJay Potezny +Potge Pothaaai PotionFayD Potland +Potland o_0 PotoSekwati Potoo PotsAlots Potsi +Pottawatomie +Potter Paypa Potth Pottieface +Pottsi +PottuTatti +Potzy Poucher +Pouches +Poucie +Pounake +PoundSandNub PourMeBleach +Poussemoila Poutz Poverty +Povvo Powacat Power +Power Aid 4 +Power H +Power Outage +Power Surge PowerJoe +Powerade Powerdude153 Powerful +PowerfulBram Powerfull Powerlines Poweron6 +Poww LUIS +Powwil +Powxrs Poxuistas Poyig Pozar +Ppl +Pposkyor +Pql +Pr0 Ph3t +Pr0pvm Pr0way Pr1MaL +Pr3par3 2die Pr3ttyW0man9 +Pr3y Pra1seTheSun Practical +Prada Praecellemus Praedy +Praenthos Praes Praestantia Praetor +Prage699 Prahlad +Prairiez PraiseCorn Praisemyrng +Pramikon Prankzy Prari Praskle +Pratt Mario Praxahr Praxys Pray +Pray Salah +Pray for me +Pray t o God Pray4TheWin +Pray4me PrayForDeath +PrayForYou +PrayToAres PrayarN +Prayer Pro Prayerr +Prayis +Praynr PreMDPepper PreNew PreRuined Precise Precixion +Precondition Predaxx Predicition Preedy @@ -17961,12 +37581,21 @@ Pregnant PregnantSock Prelash Prelet +Prelex +Prellifunky +Prem PrematureNut Premie +PremierZarry +Premium Dude Premz Prep Prepared2 Preposo0 +Prepotting +PresPoon +Presearing +Preserve PresidentMo Presley93 Presley93BTW @@ -17977,42 +37606,90 @@ Prestor Pretendy Preternal Preto +Preto Ownsss +Pretten Pretty +Pretty God +Pretty moist +PrettyGood +Prettyokqt Pretved Pretz Prevengeance +Previn Prey Prey4Pocius +Preying +Priapismi +Pricy Priestopher +Prif Daddy +Prifddinas +Priide +Priimitive Prilliam Prim Prima Primacy Primal +Primal gain Prime PrimeSeries +PrimeToaster Primed +Primetime190 +Primetime829 +Primevil PrimexReborn +Primid Primiitive +Primilivum Primitive +PrimoVG Primordial Primster Prince +Prince Drt +Prince Ferro +Prince Mate +Prince Tuten +PrinceCrypto +PrinceJozef PrinceZuko Pringle287 Pringles Prins +Prins Pi1s Prinses PrintedCash +Prion Priority +Priorrr +Priselac Prisimenu Prismalitic Prison +Prison Joe +Prison M1ke +Prison Soap Pritje PrityBoiSwag PrivateSmorc +Prix Prixma Prncss +Prncss II +PrntScr +Pro Flicks +Pro Per UIM +Pro SKiiLLz +Pro Slacka +Pro Slacker +Pro Tanto +Pro Tato +Pro Zoe +Pro twin33 +Pro-tag ProForm ProFortnite ProLegend @@ -18020,18 +37697,30 @@ ProSKatona ProSups ProTweakius Proba +Probability Problemski +ProbzDrunk Procedures Proclivitas3 +Procoptodon Proctiv Procts ProddyP Prodigy 99 +Prodigy Matt ProdigyTape ProdigyThief +Prodigy_77 Prodoughtype +Product99 Prof +Prof Bruce +Prof Cheese +Prof Ribeiro +Prof Shroom ProfGanon +Prof_Plums +Prof_Snack ProfanityBox Professa ProfessorBot @@ -18039,50 +37728,85 @@ Proficent ProfoundPnda Prog Project +Project Deku +Project Paat +Project Sept ProjectGamma +ProjektUri Proklus Prokopios +Prolapsi +Prolly High +Proly high +Promacta Promepheus +Promise +Promtel Prone Prongs97 +Pronx Proots +Prop Gun Propagate Propas Proper +Proper bald ProperTroll Prophecy +ProphetSnayk Prophylax +Proponi Propulsions Prosit +Prospicktor Pross +Proster Protagg +Protanopia +Protassium +Protease ProtectdLeft Protectlilb9 Protectorate Protege Proteiini +Protixen Protlong Protocell +Proton Drum +Protopteryx PrototypeGOD Protox +Prouser +Provei ProvidenceL +Providential Proviro +Provoke Rage Provokeskill Provoxo +Prowz ProxDemSox Proxeum Proximitus +Proxymine3 +Prozac Manic +Prozac Peter PrrMeowPrr Prro Prrr +Prrr Perry Prryvdoof Pruillip Prune +Prune Slayer PruneHub PrusaSlicer Prutturp Pryn Pryxl +Pryypsas +Pryza91 PsYcHo130 Psalm Psalms116 @@ -18092,219 +37816,435 @@ Pseudo Pseudomonas Pseudonimas PsiTempest +Psichedeliks Psiki Psiklone Psmaster +Psoup Psuedoniem +Psy0tic Psy13m PsyDellic PsyWaps Psybae Psyc Psyc Paladin +Psyc0-I Psyched PsychicL10n PsychicType Psychinis Psycho +Psycho Fungi Psycho11111 PsychoPatty Psychodeathk Psychohexane +Psychokilla PsychoxX Psyco Psycub420 +Psydvekoosi +Psygo PsyhexGOD +Psykoz Psylocin +Psyminds +Psynar +Psyqualogy Psysyk +Psytoro +Psytrnce +Psyyke +Pt 79 Ptalm +PteShank Ptfo +Ptol +Ptopaz Ptyh Pu-94 Pubeless PubicThumb +Pubicon +Public NJP Publics Publuske PuchaLibre Puck Pudding +Pudding Man +Puddingdude +Puddingtons Pudge +Pudge Pudge +PudgeJackie Pudgeegee Pudnik Pudota +Pudota basso +Puerto Varas +Puff Daddy Puffed Pufffml Puffy +Puffy xx +Pufr +Pug +Pug Boots +Pug Champ +PugToots Pugasaur Puggin Puggzy Puglet Pugna Pugsyy +Pugwest Pugy +Puhd Puhd1staja Puhuri +Pui Puin PuinguimGOD Pukeking +Pukeko Puli1111 Pulkjes Pull +PullOutKing PullOutRange Pulli Pulma1 PulpFlctlon Pulza +PumGiver Pumba +Pumba Bot Pumba89 PumpUpTheJam Pumper +Pumper Joe +Pumpflexin Pumpkin PumpkinLatte Pumpui Pumuckl +Punani MD Puncakes Punch +Punch Main +Punched Pundareen Punde Pune +Pune rouch Punegonde +Pung +PunishinBird PunjabSamosa +Punk-06 PunkPang +Punkt Punt +Puntenjagert +Puntje ket +Puny Duck +Pup +Pup in a Cup +Puppadile Puppana Pupper1 +PuppySeal +Puppysaysftw Pur3 +Pur3 Bow99 Pur3death2 PurMain Purate Purcey Purcs Pure +Pure Evil99 +Pure Great1 +Pure Hunk +Pure Paprika +PureBread +PureFilth PureIronEyyy PureOGIronMn +PureOwner +PureWax Pureanger728 +Purebas alt Purebasalt Purebish +Purell Pureloot21 Purely Purelybo0ty6 Purenerd +Purepappa Purepappa66 Purescarybuu +Purey Arcane +PurgatoryBro +Purgy +Purifyin +Purjj Purka11 Purkkatukka +Purkkaukko Purkkius Purko Purnex +Purolator Pl Purp +Purp Nasty +Purp Nips +Purp Please +Purp or Bust +Purp where Purp1eWizard PurpLightPlz +Purpl3 Lean Purple +Purple Flap +Purple Meeep Purple-Broly PurpleDabz +PurpleGoat PurpleHippoo +PurpleMurple PurpleNinjja PurplePlez PurpleTeemo PurpleThorax +PurpleVex PurpleWhaki Purpledile +Purplefox Purplekills Purplemudkip +Purpleowns Purppurainen +Purpsauce PurrPig +Purse seine PursuantACE Pursuedd Purtherapist Pusat +PuscSquirt Puse PuseSlayer Pushgold +Pushovermage +Pushy Bubes Puss +Pustut +Put Me 4th PutMeInCo4ch +Putaria +Puthiegh Puthy +Putkipommi Putrescent Putse Putyte1 PutziVikat Puud Puujalka10 +Puukko Pekka PuuluuP +Puumba Puuteri Puylayer +Puzzle Drops +PuzzleTheCat +Pv Was Here +PvEmerald +PvM Andrew +PvM Beireh +PvM Bhunt3r +PvM Blake PvM Boganeer +PvM Cas +PvM ColdBeer +PvM Crooky +PvM David +PvM Eestlane +PvM Gemeos +PvM Grindz +PvM Hawk +PvM Hero92 +PvM Items +PvM Jack +PvM MeK +PvM Miku H +PvM Muzzy +PvM Nex +PvM Nug +PvM Oliver +PvM Packers +PvM Panda +PvM Rev +PvM Rin +PvM Spectral +PvM Tom +PvM Wiz +PvM guy +PvM zoom +PvMAlone PvMCerlow PvMKoala PvMNightmare PvMNotorious PvMProfessor PvM_Nugg +PvMalexDR PvManchester PvMs +PvP +PvP Master PvPRoTiGy PvPete +PvPs Pvkk +Pvm 4 Pets +Pvm Aero +Pvm Demigod +Pvm Garley Pvm M0lz2 +Pvm MageBoss +Pvm Runeboyz +Pvm Tigers +PvmBrad PvmQ PvmRNGesus Pvmpets Pvoet PvtStevens Pvul +Pw4 PwDhorizons Pwca Pwdz Pweet Pwew +PwincessK +Pwn Dat Noob PwnTommy Pwnage Pwnbaa Pwnd +Pwnna +Pwnnzz +Pwno +PwnrPizzaman Pwnslayibex Pwpw +Pwxn Px_7UX8Cy8 +Pxcs +Pxie Pxtrick +Pxxch +Pxzls +Pyet Pyfa Pygmysteaks +Pyia +Pyjamas99 Pyki Pyloric Pylseboden +Pyocola +Pyra +Pyrate Aeon +Pyre Lord3 +Pyre Mouse Pyretic Pyrl Pyro238 +PyroEagle13 +PyroF3AR Pyro_OO1 Pyrocore Pyrotemplar PyrrosDimas Pyssu Pyst +Python +Pythonx135 Pyux Pyykki Pyyli Pyzdalupi +PzK +Pzju PzzaPredator +Q 1 +Q K M Nophis +Q Proserpina +Q S L +Q cs +Q l ii Ma X +Q of Spade +Q uincy +Q-Dance Jr +Q-Qs Q1NH4N Q33N +Q53 +Q60 +Q7L +Q8 I +Q8vv QAWSED +QGM QIKNQFRDNUQF +QKen +QPR QPness +QQ3 +QQQ Gang QQQQQQRRRRRR QQuaLLeH +QRcoding +QT Bri +QT0 QTRDS +QTY1 QTZedd QTom +QU0TE ME +QU42TION QWIWRDIGIDFG Qadir Qaem +Qaidos Qajvha +Qapz Qash +Qc power1 Qc-Elfmage Qeassaris +QeeQ Qego +Qeko +Qeln Qemi +Qeni +Qenobii +Qi Kua Mai +Qi Ling QiangxD +Qilat +Qiok QlKNQFRDNUQF +Qlhp xD Qlioux Qmain QnBumbleBee @@ -18312,38 +38252,79 @@ Qnon Qoil Qoki Qombat +Qosmio +QpSc +Qpaki +QpzQ +Qragon +Qrax +Qridan Qrischin +Qrollop Qrwewa Qryptic Qtey +Qtreb +Qu3stm4st3r Quacamole +Quack Attk +Quack Boom QuackForMe +Quacka +Quacker +QuadJake +Quadder 4444 +Quadralobsta Quadrifoglio Quadrioo2 Quaerd +QuaffPotion Quaffle9 Quahzai +Quakbou +Quakenet +Quakoss Qualitative Qualities +Quality Kek +Quality Name QualitySleep Quang Quantities +Quantization Quantuh Quantum QuantumTurtl Quarentitty +Quarks +QuarterToBen +Quarterback Quarters +Quartia Quav Quawka +Quazi +Qucks Qucu QueBolaAsere +QueefInMyEar QueefMaestro +QueefWiggum QueefedOnYou Queeffing Queen +Queen De +Queen Juggle +Queen Keegs +Queen of CoX +Queen0fScots +QueenBadJuju QueenJada QueenOfCorn +Queenmystque +Queenn Elsa Queer +Queer Peter Queerzzly Queijo9 Quelana @@ -18351,131 +38332,329 @@ Quenched Quero Quessswho Quest +Quest Dodger +Quest Giver +Quest Lckd +Quest Noobi +Quest Person +Quest Plug Questikels +QuestsAreBad Quety +Queue Pea +Queueie Quew Quey Quezzimoto +Quf +Qui GonJinn Quica +Quick200 QuickClicks +QuickELMN8 +QuickNDeadly QuickShot +QuickShot x Quicken +Quickman1000 +Quickshot343 Quiddich Quiet +Quiet Place +Quiet Please +Quiet Toot QuietStorm44 +Quiettravlr Quikstache00 +Quilicura Quillninety3 Quimbo +Quinker Quinncidence Quinnyb0y Quintendo Quirkless24 +QuirkyBeaver QuirkyPurple +Quit 4 iron QuitForIron QuitForRS3 Quite +Quite Shy Quitegoddish Quitoris +Quitting Alc Quiz +Quizav Quizzy Dee +QukinoTe Quonloo Quorhum +Qureshi Quria Qurix Quti Qutie +Quukske Quvma Quweix Quyron +Quz Quzzini Qverkuz +Qwagmire Qwaltz +Qwd Qwezz +Qwibz Qwinny Qwinoa Qwozii Qxevym1 +Qzbxd +Qzst +R 0 E +R 0 w d y +R A L L S +R A V I +R A Z T A +R E +R H Y T H M +R I J K A R +R I K +R I P B R O +R L +R N G Pwnz5 +R N Geo +R O B B IE +R O E L +R O O N +R O X +R P N +R S J +R S Life +R S M +R U A Terd +R U MAD BRU +R Y A N +R Y D +R You Jelly +R a uL +R a z u z +R ack +R amon +R eece +R em +R hin o +R i a d +R ift +R l C H +R mr +R o r o no a +R ob +R obert +R oger +R osss +R uiN +R ya n +R yun +R-66Y R00M +R00P R00SE +R00T R0AD R0B0C0P R0BBO +R0FL AT L1FE R0GAN R0KKIN R0LX R0MICH +R0NES R0NNIEB0Y R0OZ R0R0R +R0Y R0YAL R0ad R0bain R0bbby +R0binho R0n13L +R0seofthorns R0yksopp +R14H R1CO +R1chs R1ghtupth3r3 +R1ku R1ng +R2TB +R32 N Z R33c0NN +R34 R3Dtjee R3d3mtion +R3dlegend R3vq +R4 n g 3 r z R4LLY +R4g4n4 R4ndomUs3r +R4ndyM0n +R4ndy_lahey R4ng3 +R4ng3 Nubie +R4ng3r 00 +R4nge +R4nge 2 Lpk +R4re Pepe +R4v2n +R6boi R8nny +RA NG ED RAB9 RACELIS24 +RAD x GLiDeR +RADATOUILLE RADlATAstory +RAFA LOKO +RAG YOUR A55 RAKETTAA +RAPPUHN +RATMON3Y RAUTA ARTO +RAlN +RAlSED RBNY RBeardWBrow +RC Blows RC350 +RC93 RCFreak +RCW +RCY +RD Alten RDHG RDJ94 +RDT King +RDW_Dark +RE2PECT RE4LG4LIFE +REALLY RITCH REBOOTING REC0N +RECEPTED +RED DEM0N +REDBUHLL REDD0GJR REDLlNE +REDRACECAR99 REEEject +REEEsuns REINCARN4TE REKNAW REKTmlg99op REMAlN +REMIIIX +REN0 REZlN +RElNHARDT +RF Bushee +RF Genesis +RFDesigner +RGB Titties RGGregar RGet RHCP-Solo RHK Ezze +RI Sleepy +RIP Base +RIP Meme Man +RIP Mitch +RIP Pork Pie +RIP life +RIPAUGUST +RIPAccount94 RIPT4H +RIPgirthgirl +RIllipieru RIpuim +RJCI +RJE RJL129 RKBM2 +RKN RKOd +RKOd My Mum +RKTA +RKZY +RL Adam +RL Wolf RLBurnside RMAC-97 +RMF Dead +RMG solo +RMax +RNG Alche +RNG GOD +RNG Kevin +RNG MAD +RNG Msg Me +RNG Replace +RNG Tomas +RNG dez nuts +RNG9518 RNGBandit RNGVRNG +RNGiesi +RNGrim +RNGsetMeFree +RNJohn +RNJoseph ROADTO100B +ROBAlN ROBBOsickdog ROCCAT ROCKYY +RODRlCK ROF0LFOR ROFOLFOR ROHTEENMUTSI ROKO +ROLL TlDE ROLLinPEACE +ROMBU +RONNIE COLE +RONZE ROR0 ROSTA +ROT LOST 6K ROVANIEMl +RR Fourshore +RR55 +RRAMPIDD RREKKLES +RRX YY RRX RRayhan +RRevelation RRickkert RRobert +RRocket02 +RS Bread +RS Cinema +RS Jesus +RS Myrthe +RS Nico +RS SLAG +RS UFC NRL +RS ape +RS2 Legend +RS3 Refugee RS3izBetter +RS6 Quattro +RSB Fox RSBadLifeBad RSDonny RSGO @@ -18483,231 +38662,462 @@ RSLtSgtZen RSMAXD RSPSisBETTER RSPup +RSQT +RS_Tytin RSfork +RSmake RStrength99 +RSuomivihu +RTGoldleader +RTK86 RTLadNumber4 +RU B Y +RU Petrified +RUBBERI +RUUNIKUNN +RU_Engineer RUlS +RWB Codeine RWSDOUG +RX S +RX7 FC3S +RXen0 +RY N0 +RY P RYAN RYN16 RZAlex +R_D TRAJANO R_andy13 +Ra +Ra fi Ra1d RaMR0D +RaRaJuana +RaSToG RaaWa Raaagnaar Raab Raaban +Raahe Raahh Raakanipsu +Raamsdonkje Raanduin Raassig +RabarberBarb +Rabbagust Rabbie +Rabbit MD RabbitFlats +Rabbitdude RabbitsDong +RabidDolphin Rabidherring Rabiosa +Rabrt +Rabs xo RacccAttack Raccoon +Raccoon King Raccooncow +Raccoonus Race Rachael +Rachey B +Racholini +Rachscape +Racteal +Rad Renegade RadFeenix Radacia +Radaenne Radar Radeo Radia7ion Radiance +Radiant Lux +RadiantSkye Radiator Radini Radio +Radio DJ Dan +Radio Love Radiohead66 Radiologics +Radish55 Radja333 RadoslavvBG Radrieldor Radsurlak Radsy Radtastic +Radusa-Two Raeghal +Raelir Raen +Raf0da Rafaael +Raffealy +Rafff +Raffineret +Rafi Tafy +Rafiniya +Rafn Rafnar0G Raft15 +Rafy +Rag +Rag Demon +Rag Doll +Rag Gdz +Rag List RagToRiches Ragani Rage +Rage Fuel +Rage233 RageCold +RageCombo RagedIronMan Ragefire1 +Ragegold1163 +Ragez Fury Ragga +Ragga Muffyn Raggedy Jeeb Raggers +Raggnag +Raggy Reapzz +RaginBatts RagingK9Fury RagingReddit RagingTroll +Ragingg Ragnar +RagnarOsborn Ragnariukas Ragnarok96 Ragnell56 Ragni RagsIIRichez RagucciRafa +Ragurain +Ragy rag Rahamasin Rahamies +Raharu RahbHurt Rahdyxc +Rahedo +Rahimo +Rahis Rahjer +Rahy King +Rai Rai_3 +Raibu +Raichue Raicun Raid +Raid Lewis +Raid My Body Raideris Raiderrediar +RaidriarTGK Raien Raihan +Raihou Raii +Raiicrow Raikesy Railee Raimar1 Raimiss Rain +Rain Days +Rain Please +Rain ee +Rainbird +Rainbow RainbowBeast Raine Rainer Rainforest Raining Rainingbroz +Rainingmeltz Rainman446 +Rainnos Rainold +Rainshower Raintown17 Raisedbycows Raiskausrapu Raisson +Raisson X Raistlin RaistlinFasa +Raisya Raivan90 Raizerr Rajat76 Raje +Rajgo +Rajs +Rajvir Rakaah RakadB3 +Rakblood +Rake +Rake ur weed Rakettikala RakiRaki +Rakiata +RakingPurple +Rakkir Rakoins +Rakru1 Rakuko Rakun Rakan Rakupenda +Ralalallei +Ralgurr Ralle1208 Rallis RalorLeetor +Ralos Rise Ralp +RalphLauren Ralphed Ralphie3 +Ralphy Jnr Raltsz RalvekZul RamYe +Ramae +Ramallah Ramathorn +Rambling Rambo +Rambo Prods +Rambo The 3 +Rambo The 4 +RamboBrad RamboDaddy +RamboKiddo +RamboOmega +RamboSambo +Rame +Rame s Ramen +Rameses B Rami +Rami Tsunami Ramleh Rammdude +Rammmsteinn RamonZera Ramonix Rampa +RampageOnly Rampauttaja +Rampenisse Ramrod Ramsas +Ramsay RamsayGrejoy +Ramxious Ramzis Ramztad +Ran-D RanShakHazar +Rana pipiens Ranamen7 Ranarr +Ranarr Bowl +Ranarr Czar RanarrScape RanarrSmoke +Ranarrjuice Ranarrseole Randalf Randalfen Randalicious +RandallOG +Randdall Randeaux Randecker Randinator42 +RandlesAlt +Random Day +Random763 +RandomGuy771 RandomLemon1 Randomguy38 Randomized +Randomkul Randomojojo +Randsoms +Randy Rawdog Randy Rolex RandyBanger Randyke +Randys +Ranestumies Rang +Rang3d Xp +RangPang Rangahhh +Rangatan44 Range +Range 4 mage +Range AR +Range Kiing2 Range4Free RangeGawd RangePs Rangeddddddd Rangedly Ranger +Ranger Fain +Ranger Hood +Ranger Uhle Ranger82592 RangerBoots +RangerFain Rangerofgold +Rangerrr Rangish +RangoII RanjaForLife Rank +Rank 1 +Rank 1 Gamer +Rank 1 Korea +Rank 1 Norge +Rank 1337 Rank1Espada Rank1NA +Rank350 Rank62 RankOneTurk +Ranox Ranty +Ranul Oracle +Ranusian +Ranzo +Raoul +Rap50Cents Rapasuu +Rapid RapidCycling +RapidPancake +Rapidd Rapiers Rapolas Rapolu +Rapt0ram +Rapterzz99 Rapthor Raptor +Raptor Jesuz RaptorLuck Raptorcaw +Raptorjk +Raptorman Raptorsin6ix Raptz Rapu +Raquelo Rare +Rare Arugula +Rare Chance +Rare Doggo +Rare Hat +Rare Panda +Rare Pets +Rare Vibes +Rareinpepe Raresocks Rarity +Rarity Belle +Rarma Rasa Rascus +Raseni +Rasenkage Rashford +Raskasta Raspatil Rasput1n2k13 RaspyLemon +Rassaasolo +Rasta Panda Rastaclat +Rastafarlion Rastamain Rastaman +Rat Digward +Rat Flicker +Rat Has Dice +Rat Hunter23 +Rat L Traps +Rat Lettuce +Rat Sensei +RatKing365 +RatWithAGat +Rata +Ratchet48 Ratcliffe +Ratdrin +Ratenda RathianSP Rathmai +Ratikka07 +Ratlifenerd Ratlordmax Ratm +Ratpno Ratrace12345 Ratrero +Ratsy J RattleSsnake +Rattled Rattlerskill Rattlesnake +Rauhanrekka Rauokse Raur +Raurshank +Rauski696 +Rauss Rauta +Rauta Juoppo +Rauta Sorsa +Rauta Tuomo +Rauta Urho +RautaGoblin +RautaLeksa +RautaPertti +RautaPizza +Rauta_Kessu Rautafantic Rautakuma Rautis +Rauzee Ravac +Ravangerous Ravanth +Rave Pants +RaveBoy21k Ravedeath Ravemaste476 Raven +Raven Frost Ravency Ravensword +Raventodt Ravers Ravesyy Raving @@ -18717,119 +39127,267 @@ Ravlar Ravs RawPhazon RawRyan +RawToast_13 +Rawbean +Rawduggie Rawest +Rawke Rawr RawrItsKirby Rawrr Rawsome Rawssss Rawst +Rawwr Austin Raxen Light +Raxorn +Ray Btw +Ray Kurzweil +Ray Rwars +Ray Sensei +Ray Squared +RayCon +RayMarshall Rayfort +RayiiRios Rayjin_Storm +Raykin Rayleighs Rayleight RaymanXo +Raymo Raymone Rayne +Rayne Drop +Raynel Raynelie Rayner91 +Rayo McFly RayofLight2 +Raypac +Rayrunner +Rays Max +Rayye +Raz Wolf +Razaia +Raze +RazenOh Razer +Razer Elite Razeren +Razguld Razie +Razih RazleBadazle Razor +Razor Beast Razor654991 Razorblat Razoriginal +Razorshark +Razrback Razz1eDazz1e +Razzle Razzzoor +Rb Salvation Rb2790 +Rc +Rc Dark Rang +Rc_Power +Rcardio Rcer +Rckr Rddrz +Rds 44 +Rds Nerd +Rdushi ReDrOc +ReFueld RePeTiiTioN +ReRemakeAndy +Re_Rauzo ReachAround Reachinator +Reactate +Reaction Tec Reactionary +Reactionss +Reactor15 +Read Art +Ready 123 Ready4pwnage ReadyToReap Reah Reaks Real +Real Cute +Real Earth +Real Friends +Real Jesiah +Real Kev +Real Me +Real Reasonn +Real Skyline +Real Umbreon +Real Unlucky +RealAndBased +RealBoobs +RealBruceU +RealDrSeuss RealJonner RealKing11 +RealKingBee +RealLifeBot +RealLyre RealMemeVPJr +RealPeelBoat RealRicFlair RealScythe RealShyGuy +RealSpeed RealStoney Realcorkpig Realdent Realflamesss Realismi Realissm +Realist Knut +Realistg +Reality RealitysGod Really +Really Spicy +ReallyToxic Realpk2004 +Realtank +Realtor R1 Reap Reapa Reaper Reaper0321 ReaperLucid Reaperkiller +Reaping Inc +Rearrange +Reaver Tru5t +Reavus +Rebaulten Rebel +Rebel Serj +Rebelatto9 Rebelgian Rebelican +Rebellgutt Rebelqt +Rebir7h Rebirth +RebirthFlame +Rebis +ReboKhaihang +Rebooting Reborn +RebornMuscle +RebornNips +Reborninc +Rebounder234 Rebuild Rebuild4free RebuildLewi RebuildMitch Rebuildep Rebuilders +Recable RecentKill +Recess Recharge +Recited +Recker1o1 Reckless +Reckless Ell +Reckless Fyb +Reckless Lad Reclaimar Reclaiming +Recline +Reclined +Recnamalad +Reco Fam +Recolddone Reconjack Recore Recover +RectalRoni RectalRumble Rectophobia Recuder +RecyclePls Recyr +Red Asia +Red Cavalier +Red Courier +Red Duke +Red Hick +Red Hippo +Red Hood +Red Hot Go +Red Kool-Aid +Red Nine +Red Osrs +Red Pepper65 +Red Rays +Red Rockin +Red Simon +Red Staal +Red Style +Red The Pom +Red Wings +Red XIII FF7 +Red hat +Red partyhat Red3 +Red6 RedCavalier RedDwarf RedGraceful +RedMare +RedRambler RedRatedGame +RedRathalos RedRegent RedRusker RedTwisted RedWarlock31 +RedWol +Red__Mage9 Redael +Redarekun +Redbackpker Redben45 +RedberryLean Redbull +Redbull Od Reddo Reddragon884 Redflame +Redgit Redikarp +Redisleft Redius RedkaWodbull Redland +Redlonghorn RedneckYoshi +Rednecks Rednex +Redninja02 Rednipplee Redo +Redo Undo Redouan94 Redrevolve11 Reds Redshapes +Redshok Redshoker Redsk1ns Redskin @@ -18838,12 +39396,16 @@ Reduced Reductive Redus Redux +Redux Lux Redz Redza14 +Ree Mastered Reeb Reececup Reecesoa +Reecie ReedBadass +Reee Reeebow ReeeeZ Reeeps @@ -18854,7 +39416,10 @@ ReefyReefer Reel_Arphios Reels Reemov3d +Reer Reeyu +Reeze Tech +Reflection44 Refleksfrode Refleksi Refluxerino @@ -18863,168 +39428,346 @@ Reformer Refried Regal Regan +Regelios Regement +Regent Pve +ReggieWeggie +Reggin Cx Regie +Regiis +Regio Regular +Regular Iron RegularJerry RegularPlank +RegulusAurum +Rehbein RehlapzZ Rehoboam +Rehst +Rehzzy Rei-chan Reibnitz Reichart Reidar +Reids +Reidtheweed Reign ReignInBlood ReignOfThor Reigns +ReikenGIMP Reimie0x Reimo ReimuHakurei +ReinLassen ReinMoose Reince +Reinkmyster Reipas Reisnom Reisy +Reita Reizzaz +Reject q p +Rejected Alt +Rejected Son +Rejected btw Rejects +Rejet-01 Rejey8 Rejuvenating +RekaScape +Rekans Rekenz Rekkaboi Rekkerta Rekkt +Reklats +Rekna +Rekt +RektHavok Rekunleashed +Relaaax +Relapse Relapses Relative Relatived +Relax to Alt +Relent1ess +Relevancys Relianah +Reliefed ReligionBad Reliinqish Relik Relinquishh +Relit RelivinYouth Relizent +Relizent2 +Relizents Rellnquish Relloktion +Relmu Reload ReloadFaster Reloox Relrekis +Reluctants +Rem Dogg +Rembs Remcodingho Remedial Remiejj-BV +Remiel Remillia +Reminded Reminiscon Remitin Remix +Remixed +Remmos +Remmyy +Remn +Remo Remorsed Remspoor +Remtar74 +Remvrkable +Remylz +Remytouille +Ren to RenLady +RenZelus Ren_Otori Renacan +Renall Renarin Renas Renato Renauddd +ReneeIsMaxed Renegor Renesau Renewed +Rengar +Rengeki Renger +RengokuRS +RengokuSmile +Renixion Rennuts Rennz Renovato +Rensafari Rent +Rentb0y +Renzo Bamf +Repathor Repeats +Rephia Replayroyke +Replenished Replikantti Replo +Reply To Me +Report Biden Reported +Reporting U Reppin519 RepresentRS +Reprexain Reps4Jesuz Reptile +Reptile God Reptiliano Reptillian +Republic55 +RepublicofRS Reputism Reqtile Requaahv Requilog Requin RequireBone +Reredrum +Rero +Resallude ResenBallZ +Resentfully Reseriant Reserv3D +Reshop Resident +ResignWonki Resilient +Resistzz Resizable +Resk +Resoluutio Respaze +Respeat +RespecTheMax +Respect Me +RespectMyDab Respek Respire +Responders +Respy +Respyy ResrvdFinest +Ressara RestIess RestInPce +RestTooLaid Restinp3ace +Restless99 RestoredIron Restrial +Restrio +Resultss Resultzs Resupplying Retendous Rethie +Retired Dead +RetiredMaboe +RetiredStic +Retr0virus11 Retro +Retro PvM +RetroDeviant +RetroRaz +Retrohiili +Retrovision Rettent +RetuKettu Retupelle ReturnToOne Reub +Reubon +Reuborn +Reudo +Rev Hayter +RevDragon RevZamorak Revamp +Revamp cF Revanche +Revellius Revelwood +Revenant MKX +Revenant Rag RevenantBoy RevengerII Revent ReveredB3ard Reverenciar Reverenz +ReverieDC +ReversEffort +Reversedd Revi21 +Revilia Revofev Revoke Revolted Revolving Revs +RevsRebuild Revus +Revvanth Revx Revzvy +Revzy +Rewbs +Rewinds Iron Rewnlite Rewns +Rewo +Rewriting +RexCox RexM +RexMouser Rexicur +Rexkat Rexun +RexxNotReal +Rexxasaurus +Rexxer69 +Reyes407 Reyko ReynoldsWrap +Reystov +Reyswaldo +Rez X +Rezi +Rezident Rezka +Rezki +Reznx +Rezy +Rezz Main Rezz79 +Rezzn +Rfsu +Rgimenez007 +Rgk +Rgnfrg Rhaegalion Rhaegar Rhaegard +Rhaegor +Rhagaea +Rhastae +Rhcprule6 +Rheal Rheece Rhette +Rhezmyn +Rhianne +Rhien +Rhiley +Rhino +Rhino Art +Rhino Prime RhinoNuts +Rhit Rhiyia +Rhk +Rho Ur Boat Rhoads +Rhocky Rhodesia Rhogue Rhondda +Rhorrn +RhuBarb3 +Rhubarbino Rhuina +Rhyio Rhyl +Rhyme Rhyming +Rhyninn Rhynoob +Rhys Irl +Rhys25 RhysieBoy Rhysos Rhythm +Rhythm Games Rhythms +Rhyw Peth +Ri v en +RiJect RiKoCheP +Riaever +Riamo +Rias Ribb +Ribeye1611 Ribinha Ribitz Riboku @@ -19038,30 +39781,63 @@ Riccario Rice RiceAndTacos RiceWrangler +Ricefishie +Ricepicker89 Rich +Rich 1 Hita +Rich Noob +Rich Snoe +Rich13 RichAround RichGuy X RichHarambe9 +RichMansDrip +Richaard Richard +Richard Baer +Richard Moss +Richard12391 Richards2705 +Richart 123 Richguy3213 Richie Richterr +Richxrd Richy +Richy Rich Rick +Rick scape0 RickAndVorki +RickDeckard RickEscobar RickRab +Rick_NLD +Rickard +Rickeh 1 +RicketyReck Rickhs +Rickky Bobbi +Ricklet +Ricklewinks +Rickness666 +RicknessAlt Rickolas +Rickos Ricksking +Rickstaverse Ricky +Ricky Bob E RickydeRoach +Rickyj13 +Rickyrevine +RicoMangos Ricoo Ricotayqueso Riddim RidePine +Ridemyhomies Rider +Rider Galara RiderOfRohan Rider_99 RidgeRacerR4 @@ -19070,166 +39846,309 @@ Ridley Ridley1990 Ridored Rie1yReid +Riektanminol Ries2 +RiesBatsbak +Rif +Rif T +Rifampicin Rifen +Rift Archer RiftOversoul +Rig Pig Riga +Rigelius +Riggas Rigged1 Riggerlyworm +Righ Right RightKnight5 Rightthisway +Rigid Tony Riglr +Rigondead Rigondeaux Rigourlas Rigr Rigtop25 Rihmakallo5 +Rihsky Riickkert Riiggs Riii +Riiico Suave +RiimuRatigan Riippptttt Riisi Riitasointu Rijst +Rik M +RikCastle RikSavage +Rikador Rikalero +Rikeez +Rikka-kun +Rikka-san +Rikky Flames +Riksaah btw +Rikten X +Riku887 RikuLehDeku RikuRNG RikvWesting Rilah1212 +Riled Up RilesWright +Riles_Nation +Riley Mort +Riley1098 RileyReidx RileyVoelkel +Riltor Storm Rimbton Rimorix +Rimppa97 +Rimuru BTW +Rinby Rindos Ringboi5 +Rinhx +Rini Keeper +Rinky +Rinoa Rinrus Rinsumageast +Rio-Dono Riolu +Riona Riot +Riot Breaker +Riot Starter Riotdeath +Riotz v4 +Riou Riouha +Rip David +Rip25kChins RipBigDoinks +RipFeKeenan RipLo RipMagikarp RipRoidie RipSnorter46 +RipTheBilly Ripd RipePineappl Ripper Ripperhino RippleBear +Rippn Ripsin Ripstart Ripulieinari Ripulirulla Riri488 RiseOfTerror +Risencambrie +Rishhh Rishloo +Rising serum RisingHonour Risingodslay Risk Risker RiskinPixelz +Riskule +Risky Pete +Risky Ryan +Riskz92 Rislearn Rismani +Risotto Risperdal +Risque Moose Risqy +Ritchi026 Ritle Ritopikachu Ritrole1 +Ritthback Rittz Riubuli RivalIron +RivalTitan Rivalguy25 Rive RivenGasm +River Kelda +River OSRS RiverOfIron RiverOut +RiverToSea +Riveriea RiverzRaging Rivy Riwer Rixhy +Riyazzz RiyuK RizeNSkrine +Rizi Bizi +Rizla King Rizos +RizzardWizrd Rizzhole +Rizzzoo Rizzzyisback Rj8532 Rjtyyi +Rkaksi RlCE +RlCEHEAD RlFK RlGBY +RlP Harambe RlPMYMANX +Rlly G Rmus1 +Rmve RnBieber +RnGator +RnGisFocked +Rndl +Rng Depleted +Rng Maestro +Rng Rami Rng4Display RngIshit Rngclown Rnjeesus +Rnkji Ro The Boat +Ro s Ro2no RoBoRhino +RoBoat RoNNalDis RoSki +RoT Nick +RoT is GAY Roach Road +Road Run +Road sign 73 +Road to kek RoadBoat RoadSpartan RoadToALLPet Roadbiker15 +RoadetoMax +Roadways Roadz Roam +Roaming Sky Roanen97 Roastedsteak +Rob Aero +Rob Hot Dog +Rob Iron +Rob Pooner +Rob Zombie +Rob2G +Rob94401 RobDirkson RobThePole +RobWilliams RobWorker Robb +Robb uwu Robbbana +Robbbbb Robbiboi +Robbie EN +RobbieJ547 Robbin +RobbinDaHood Robbo Robby +RobbyMatrix +RobbyRott3n Robeartoe Robejose Roben +Roben Jr Robert +Robert Pires +Robert Stein +Robert T +Robert1f Roberto700 +Robidoux Robigo Robin +Robin Van H +Robin564 Robinhoodnow Robjee +Robjon7 +Roblit Robln +Robln l-l00d +Robodinho Robodyx Robok0p +Robokiller86 Robolisten Robologist Robot Robpar6 RobsonV +Robtoe123 Robust Robyn550 +Roc3 RocheLimit Rochette Rock +Rock Knight +Rock Nin +Rock Rage +Rock The Red +Rock Wizard3 +Rockabbages Rockadelic Rockafellah1 RocketRock88 Rockfists1 Rockford +RockfordT Rockin +Rockin Ness Rockland Rocklore +Rockmaker Rockrets +Rocktail +Rockwell Rocky +Rocky 1535 +RockyYourMom +Rockydig Rocokoko Roczor +Rod Goesinya +Rod Man +Rod Monan +Rod My O +Rod i +Rodefe Rodeva Rodimus55 +Rodje Rodney +Rodney Farva Rodnirt Rodnizzle Rodrick @@ -19238,77 +40157,133 @@ Roe2 RoeGut Roebie1 Roei +Roekoeloos Roel Roerbakei +Roexzy Roff +RoffXD +Roffie Roffy Rofie RoflOs +Roflaye Roflmao +Roflmaomg Roflologist Roga Rogerthatxd +Rogier504 Rogiertjuuuh RogretheOger Rogue Rogue nr2 +RogueSoul03 Roguestoney +Roguor +Rohafin Rohekonn +Rohman Rohmu +Rohr Roice Roid Roidsy +Roihuvuori +Roithamer +Roixie +Rojas +Rokec993 Rokki Rokushoo Rolann +Rolav +Rold Rolde Roldeh Roldie Rolex +RollOurOwnJs Rolla +RollandSmash +Rolleston Rollin +Rollin Clean Rolling +Rolling Kush Rolling2Hard Rollingo +Rolls Rollsie Rolluik Rolly83 +Rolpharoni Rolson +Rom3 Roma Romad +Romare Romarigo +Romboy619 Rome +Romein Romen +Romen Ranges +Romeo for u +Romeos GIM RomeowL Romic Romka Romo RompLord Rompmaninov +Romway +Ron Swansong RonBurgundy +RonCumtastic Ronald +RonaldReagan Ronbiara Ronch Ronco6 +RondVierkant Rondey +RoneRackal Ronescape +Ronggo Rongor Rongrongie +Roni Hagert RoniKysh +Ronn Coleman Ronnicle Ronnie +Ronnie Fe +Ronnie Ponny Ronnie518 RonnieKray +Ronniebob Ronny Ronokroo +Ronpoo Ronti Rony Ronz Roof +Rooftop Laps +RooieRotzak +Roolon +Roomhoorntje Roommaster1 +Roon2h +RooneyDUNX +Roonscape Roosa Roosevelt19 +Roosevelt69 Roosevelt79 +Roost Coffee +Root Exoi Rootman34 Roover Rooxy @@ -19316,77 +40291,146 @@ Roozom Rope RopeDart88 Ropemaker +Ropew +RoqeSVK +RorannoaZ +Rorek RorekMalc Rorr Rorvis +Rory Gall +Rory Stone RoryBurnout +RoryJb Rorys +Rosalktha +Rosco Jenkn Rose +Rose Fritz +Rose of May +Rose tiara RoseGold_A +RoseOnCasket +Roseanne +Rosemarrie Rosemary +Roses R Red +RosetaStoned Roshidragon +Roshyz RosieBtw +Rosieflower +Rosin0nly RosinHead710 RosinScape +Roskamaster Ross +RossOSRS Rossaboy Rossed Rossssi Rossys +Rosters +RostiKz Rosv0 Rot3x +RotJofaJofa Rotagilla +Rotated Rotation +Rotelli Rothen RothesLatrin +Rothgor RotiPrata Rotiforms Rotom Rotta Rottapoju Rotten +Rotten Vale +Rotten Wang +RottenEyeMoe +RottenGurl Rottencotten +Rottenzotten +Rotterdam +Rotzschrank Rouge RougeDev RougeManiac RougeThief02 Rough +Rough Games RoughINSERT Rounded +Rounded Xp Rounder +Rounding Rousey Rousseau88 Route Rova Rove +Rovicus +Rovka +Row Sripple +Rowdy Tobias +Rowe5000 Roweeee Rowg +Rowinovich92 Rowls Rowoep RoxanX Roxasroxs564 Roxer +Roxie Valor +Roxxe Roy385 RoyLay RoyZay Roya2Face Royal +Royal 69 +Royal Chief +Royal Death +Royal Rain +Royal Violet +Royal Wax RoyalD3sire RoyalMess RoyalPurps RoyalRolf +RoyalScumbag RoyalShaco +Royal_Shock +Royal_inc Royan +Royboy16 Roye +Royo Royollie Roysrols Roytang5 RoyyyAfca +Rozensho +RozirPanda Rozkol Rozlucka Roztomily Rozzaa RricketyREKT +Rro +Rs Bartender +Rs But Afk +Rs D +Rs God +Rs Jamal +Rs Kajcsa +Rs Olm +Rs Pikachu +Rs Wiki RsBryce RsGoku RsOverGirls @@ -19396,59 +40440,116 @@ Rs_ReeCe Rsanaded Rsebb Rset +Rsh Katje Rsh10 +Rsky B +Rsn Kmt +Rsn_Adam Rsn_Dillon Rtlo18918B +Rtslash +Rty +Ru Ru +Ru2uo +Ru6 RuMoRRs +RuRu-nyan RuRu09 +Ruan Rubber +Rubber Alt +Rubber Apple +Rubber Luffy RubberApple Rubbery +Rubbery Ra Rubee RubenD +Rubenich RubiconGuy +RubikMouse +Rubinx81 Rubish Rubrek RubsSandwich Rubss Ruby +Ruby Opal +Ruby Runes Ruby5001 RubyBlue RubyBoltSpec RubyEvelyn RubyLvledUp +Rubystealer +Ruck +Rucked Faw Ruckus Ructions Rudadoodadoo Rude +RudeBoiElj Rudekid1035 Rudetopia +Rudi Andre +Rudii Rudin +Rudin Alt Rudolph Rudy RudyGiuliani Rueben +Ruel Rufie +Rufles Rufu +Rufus Shaw +Rufus xD +Rug Klachten Ruge Rugg0064 +Rugpijn Rugrat Ruhl +Ruhpetitive Ruhtrik +Rui HIMimura +Rui Sand RuiMariz Ruimte RuimteMan Ruinationnn +Ruined +Ruined Kap +Ruint +Ruizoeki Ruk1a +Rukavi Ruker +Rukias Feet Rukusama +Ruky +Rule Elite +Rule34 Grogu Rulesy Rulesyy Rullmane +Rum Lad +RumJeDobry +Rumble519 RumbleYT +Rump +Rump Kicker +Rumpetask +Rumpkondens Rumpleminze Rumpstag +Run Alt +Run Down Mid +Run n Alch Run1t3 +Run1t3 Cape +Run2paradise RunCMP RunFreek RunNhideZom @@ -19459,104 +40560,199 @@ Runcatsmith Rundamental Rundi Rune +Rune Scimmy6 +Rune Strg +Rune Toi +Rune Trophy +Rune Tunes +Rune Woolf +Rune l Scape +Rune lennyFe +Rune mendigo +Rune-Taneli RuneAlt1 RuneArguero RuneBri RuneFiend RuneKing2h +RuneLight RunePuuro +RuneShape +RuneWeems Runebie93 Runeblaizer +Runebryter Runechi Runecraft +Runecrafts +Runed Ltd Runeiro Runely Runeman3134 +RunenSohn Runepalmu Runeranta1 RunesCrafted RunescepxD RunescepxDD +Runeshaft16 +Runesniffer2 +Runesr4nerds Runester9999 Runeukko431 +Runeveeti +Runeventure Runey +Runey Toons Rungne14 RunicXanadu Runita Runite +Runite Ricky RuniteNerves +RunkoPalkki RunnerTwoD2 RunninBlood1 Runnn +Runny Rectum Runnynumber2 +Runolf Runs +Runs Laps Runtellthat4 +Runtu Reiska +Rup +RupOSRS +Rupea Ruperd +Rupert Whale Rupiss +Ruptured +Rupus +RureScape Ruri +Rus s Rush618 +RushAl0t Rushana Rushflame555 +Rushing RushnSuch +Rushoo Rusinahousu +Rusinapulla Ruskajan +Ruskeareika +Russano RussianLives +Russian_Fire Russkill1000 Rust +Rust Oxide RustLasagna +Rustaaaagh Rusted +Rusted Ape Rustee +Rusticis Rusticus Rustig Rustigggggg Rustix Rustu Rusty +Rusty Spoons Rusty99 RustyFoot +RustyPlastic RustySimon RustyStipps RustyTuna +Rustydog125 Rustynice Rustyw Rusy002 Rut469 +Rutgar +Ruthacus Ruthers +Rutje Ruto +Rutten +Ruttuperse Rutu +Ruudcz +Ruuddie +Ruup Ruut Ruutana +Ruwe Dollo Ruzafa Ruzy +Rvght Rvilleboy +Rvndy +RvneHQ RvrseGiraffe +Rvsta +Rvvvy Rwkw +Rwolfe +Rx bones Rx-ll +RxHarmacist +Rx_Sparky +Rxscro +Rxzm Ry Jones 21 +Ry T +Ry n +Ry-07 RyGuyyy1 +RyKush RyQzz +RyRgrMcFrly +Ryaite Ryalae Ryan +Ryan 178 Ryan8529 RyanApollo +RyanC203 +RyanFar25 RyanKristoph +RyanNagato +RyanPick RyanTW Ryanandneal Ryaneal RyangalO +Ryanmattin0 Ryann737 Ryanpage RyansRebuild Ryanwouldsay +Ryawh08 +Rybizzle Ryca +Rycerz Arek +Ryd Ryder Ryders +Ryderwear +Rydwarf RyeAnn RyeEx +RyePie +RyeYun +Ryeron +Rygelon Rygo111 Ryhan +Ryi Ryjgar Ryking +RylanIsLive Ryleegh Ryley Rylios @@ -19568,76 +40764,216 @@ Ryokojin Ryolm Ryoma Ryougi +Ryougi Shiki +Ryouma Ryoush +Ryronman +Rystaloid +RystyRane Rytacus +Rytis +Ryu Deadass +Ryu L Ryugo Ryuk Ryukiral +Ryuko +Ryul Silvyr Ryvik Ryxidius +Ryyd Ryzelf Ryzema Ryzho Ryzloh Ryzou Rzasa +Rzy4k +S 0 R A +S A S H O +S A VV A G E +S C N +S C U Z Z +S E T C H +S G M B +S I N +S J H +S M A S H ER +S M I L E S +S O Z O +S P E E E D +S Q5 +S Rye +S Spirit +S T ACK E D +S T E F AN +S T E N +S T I L L +S T R 4 ever +S T R Pwnz5 +S U F F +S V N E +S W A N N +S a z z y +S acrificed +S aevar +S aii +S ammmy +S co t t +S cruffy +S e 7 e n s +S e a f o +S e e j +S ebbe +S emi +S enu +S err +S h a n e oo +S hadw +S hayzz +S hea +S hep +S imply +S k u ll y +S kari +S l M B A +S l3 +S nipz +S ofa +S offa +S ofus +S orrow +S oulz +S outh +S p00ky +S secy dy +S t e v e n +S t i +S t i g +S t i x +S tas +S u b j e ct +S uffa +S unz +S wan S-525 +S-Market ll S00000O0000k +S0FTPUPPY S0L0 +S0L0 SL0AN S0MALISLAYER S0O0O0O0O00S +S0S JERRY +S0UVLAKI +S0Z4 S0ar +S0ciety +S0dra +S0gg3 S0ldern S0lomon44 S0lty +S0nical S0phie S0tg +S0thra +S11om +S1MPSLAYER S1N6 +S1NA +S1ORM S1SU +S1ayzAllDay S1n0fWrath S1ngul4rity +S287 S2u2 +S3 Matt S3ID S3W3RSLVT +S3n4_Hc +S3oulful S4M0HT +S4M20N +S4v4s S5peedy S60RDesign +S7arburst +SA alter ego SAAB_Toxic SAAIXX SAGLAM SAINt +SAINt Steff SALM00O00N SALM00OOON SAMCRO SAMMMMMY +SANDFROG53 +SANFEWLUVR78 SANO +SANRIPOSYCHO SANTERCOMTER +SANTO5 +SANYANOSTRAH SAPl SARAH SARPBC +SATAN GOD +SATORIIN SAUCEnJUICE SAVVON SAWPREME SAlNT SAlNTS +SAlYAJlN +SB DRIFT +SB Luke +SB Mac +SB Mully SB2K SBSBSBSBSBSB +SC0V SCARED SCHOOTSFIRED SCOTUS John +SCR0TUM +SCRAMMMBLED SCRIMS +SCRT SAUCE SCYukino +SC_Josh +SClarky +SDC Thursday +SDV SDVX SDemotivated +SE Alaska +SE N SE SECDEF SELF +SEMI CHUB ON +SEMl DEAD SEPTlC +SESACO SETU +SEXY GRETA +SFTYALWYSOFF +SG +SGNG SGTA +SGTX SH333S +SH5 SHAD0WBANN +SHAGED +SHANK SAMA SHELDOR +SHERMnNATOR +SHElD-HEDA SHIA +SHIA_WIRE SHIDDED0N SHIIIELDS SHINY @@ -19645,76 +40981,143 @@ SHINZ0N SHOTGUNSUGE SHRIIlIlIIMP SHlESTY +SHlFTER SHlNl SHlVER SIBS SIDB +SIGMA MALE69 SIGNZ SIKKaudio SILENT SIMAA +SIR KIRSI +SIR_WHAT_NOW SISDIS +SIayer +SIoopie +SJ7 +SK octorock SKBToast +SKBerk +SKD +SKDMRX +SKDee +SKEEZUZ SKKi63 +SKlDMARK SKlNNY +SKlTZO SL0AN SL1T +SL3DNECK SL3VEN +SL90 +SLAAYEEER SLAP +SLAP A SL0TH SLAY SLAYER +SLBM +SLE Casper2 SLEEEZY +SLNT SLOpro +SLV +SM Esura +SM Tech N9ne SM0KE SMANisonfire +SMEGMAEATER +SMGO SMHeMbRBoB +SMKoolin SMOrc +SMOrc Weeds SMOrc3000 +SMRT KO SN0W SN0WBUSH SN3AKBO SNAX SNAlIlIlIlIL +SNUIVEEEEEH +SOCIAL SCARE +SOLO D0L0 +SOLlD SOMALISTEVE9 +SOUL MASTER +SP1NK +SPAICC SPANKWlRE SPLEEBTEZ SPLODGE +SPOODERMENNN SPOOKAH SPlCER +SPlCY RAMEN +SPlDER-MAN +SQLite SQSHD SR0o0RM SR20 +SRH IM +SRSwiper +SS Iron +SSF Fe BTW +SSJ2 GhostMO SSS-Latch SSamm SSco0by1 SSironMage +SSlavic +SSnakeling ST0n3 ST3AKS STAIGZOR STALlN STAMPEE +STARSZSZ +STAUNCHEST STEEZ +STEEZ UwU STERGS +STEVEYZERMAN STEVIO STElNSGATE +STElNSGATE 0 STIFT +STM32 F103 +STOERE OMA +STPN +STR m8 +STRZI STRlCKEN STRlDERMAN STSTSTSTSTST +STUB0RN STYG STZY STlFFMElSTER +STlNGRAY SUBAROO +SUJET0 +SUP3RCLAUDIA SUPA SUPERSET q SUPERTAIKURI SUPREME SURPRlSED +SV_Exon +SW3GG3RZ SWAGL0RD +SWE4TY +SWlPE LEFT SYMBI0TE SYMPATHY SYRpaperclip SZP-Qlimax +S_nacky SaHiB SaItbender SaSoeur @@ -19723,61 +41126,144 @@ SaZz Saagarius SaakeliMies Saambellah +Saaq Saarinen Saassz +Sabba Sabbatix +Sabbelaar +Sabeket Sabel26 Sabelt +Sabeltann26 Saber +Saber Alter +Saber Lilli +Saber Six Saberloco +Saberos +Sabich Sabina +Sabitoo Sabler Sabo +Sabor Fresa +Sabotaging +Sabre Doge Sabretooth Sabu549 +Sabuwu +Sac Sacck +Sacha Boeyy Sachets +Sack 2 Dirty Sack_Lunch Sackofeyes +Sacolyn +Sacre Sacred +Sacred Eli +SacredArtist +Sacrificed +Sad Boi J +Sad Fat Ugly +Sad Juggler +Sad Leaf +Sad43 SadClownP +SadJB +SadPanda94 SadWhiteFalc SadamBHangin Sadass Sadcatxd +Sadge Izzy +Sadge2407 +SadgeCry +Sadgetseg Sadiq Sadism +Sadistic Sadivy Sadness +Sadting Sadystic Sadz +Sadz Rax +Sae Bae +Saena +Saenmin Saeph Saerdna97 Saerom +Saetama Saetre +Safavid +Safcon +Safe N Sound SafeFromWork +SafeUp YOLO Safecamp +Safelyfast +Saff +Saffat Saffi Safiir +Saftsack8 +Saga +Sagar Sage +Sage Lao Tzu +Sage Lily +Sage North Sage Vegas SageO6 Sageinventor Sageme Sager +Sager Main +Sagev Saggy +Saggy Weenis +Sagittarios Sags +Saguaro Joe +Sah D +Sahin +Sahonym Sahra +Sai +Sai Chosis +Sai Saici Sai1420 +SaiPhai Said Saifphire +Saigyouji Saiin Saika Saikoh +Saikoo +Saikou Saikshin +Sail Door +Sailing Prod Sain Sainola Saint +Saint 7 +Saint Acura +Saint Andrew +Saint Bjorn +Saint Fabioo +Saint Fellow +Saint Hatred +Saint Hyde +Saint JJJ +Saint Silver +Saint Tmi +Saint Zero SaintBurgs SaintDienda SaintDovey @@ -19786,253 +41272,466 @@ SaintMilk SaintPablo68 SaintShiba Sainted +Saintri Saitam Saitama Saivaa Saiyajin Saiyan +SaiyanSkinn Saiyanns Saiyans Sajjad +Sajzi Sakhmett +Saki Nikaido +Sakix Sakk +Sakke Sakkyun +Sakobi SakooR Saksa +Sakuragi +Sal Magluta SalBobo Salacity Salad +Salad Car +Salad Kareem Saladhead25 Saladsoup SalamPacanam Salamalion98 +Salbo Salcal Salda Saledor Saleen Salford +SaliBronze +Salih +Salii +Saliis Main Salista Sallad +Sallariina +Salllamander Salma Salmelainen Salmo Salmon +Salmon Ikura SalmonCookr7 +SalmonsRule Salmos33 Salms Salomon Salomon666 +Salone Salorassi Salsa SalsaMurango Salt +Salt Mines SaltInTheCut SaltPJ SaltasVolfas Salte 55 SaltedCorona +Salten Saltia Saltigast Salty +Salty 4 Life +Salty Cris +Salty First +Salty Fooker +Salty Gimp +Salty Guava +Salty Slimy +SaltyNakul SaltyPears SaltyPilgrim SaltyQuackr +SaltyShrimp +Saltydivo Saltzpyre +Saluskenas +Salvats +Sam Biddle +Sam F +Sam II +Sam Knight +Sam S +Sam Tha Man +Sam Zi +Sam btw +Sam1 Sam5453 SamFC +SamGaspacho SamManSnow SamV007 SamW +SamWisely +Sama ntha Samadier Samadieron Samaji Samalorian Samanthix +Samantics Samay Samb0Slice +Sambal Sauce Samblader +Sambwo +Same Deal +Same Kid +Same Thanks +SameerM0 +Sameling Samfew Samfundet Samgonz3 SammGemm Sammi80 +SammieRose Sammito2 Sammjoey +Sammstera Sammuel +SammyGer Samo Samoski +Samphet +Sample size SampleText Samprini Samps0n Sampson Samqqa Samri +Sams Main +Samsara Kama Samsoniene Samsora +Samster8812 +Samu Saukko Samubidladin +Samuel Hall +SamuelBrian +SamuelP223 +Samuell C Samurai Samusar7481 Samwse Samxy Samzh +Samzju Samzor +Samzy +San Quentin San0 +San200 SanHolo SanPaid SanSheng SanTie +Sana Sanada +Sanark +Sanbir Sancta Sancte Sand +Sand Raider +Sand Shrew +Sandal Slap Sandbar +Sanddemon527 Sandelzi +Sanderr +SandhillFrog Sandhog +Sandhur Sandiey Sandman1 Sandmannen9 Sandogan Sandokan +Sandoval Btw Sands +Sandviper40 SandwichBag Sandwichfish Sandy +Sandy Claps +Sandy Land +Sandy OS +SandyLand +SandyMonkey SandyWexler +Sane Panda +SanePizza +Sanellyyy +Sanfew Serun Sangers +Sangi Sangotha Sangtuary +Sanguinala +SanguineHawk Sanguinezti +SanguisDurus +Sanitary Poo SanityCntrl Sanjachi +Sanjai13 Sanjin +Sanka +Sanka93 SanodersNL Sanoske13 +Sanphew +Sans Soleil Sanshou Sansos Santa +Santa 07 +Santa Chielt +SantaChristo +Santapwner Santasos Santeri Santeri333 Santhacine Sanzoku +Sanzoku HC +Sanzu_o SaoriHayami Saoro Saosiiin +SaphiTheBear Saphie +Saphirakush Saphiro Sapin +SapphicDiana +SapphicEmmmy +SapphicJade Sapphirebear +Sapphirelove SappieWappie +Sappihron Sappphire +Sappx +Saqi Saqib +Sar a Sara +SaraNotDomin Saradominas Saradontmin +Saragomin Sarah +Sarah Hagan SarahWalker +Sarahsaurus Saraie Saran +Saran07 +Sarangae Saraph +Saras BBD Saratomi Saraziel Sarbles +Sarcasmder Sarctopus +Sarcy Csp Sardaukar Sardlz +Sarecren Sarfar Sarge +Sargon III Sariel Sarkie Sarmagedonas +Sarms Knight +Sarodin Sarrafo +Sarrdukar +Sarri Sarriesque Sarro Sarrz +SarthaMewart Sarthe +Sarthinox Sarthorm Sarumite Saryit +Sarytis Sascha +Saserdoti Sash Sashadow Saskel SaskiaNaka Sasser Sasslax +Sasssie Sassy +Sassy Rookie Satada88 Satamari Satan +Satan Claus SatanSquared +SatanarchyXX SatanicGrill +Sataniciocus +Satans Ktten Satchmoi Satchyl Satisfyed +SativaDreams Satizfy +Satoo +Saturdayxz SaturnHippo Saty +SauLau +Sauce McBoss +Saucestad +SauceyFox +SauceyHorsey Saucy Saug +Saugy Saul +Saul Bloom +Saul Pvm SaulMozarela Sault Sauna +SaunaPaska Saund Saunders SaundersRNG0 Saundo Saunty92 Saurogar +Sauroiv SauronsTower Saus +SausageRyder +Savabeel Savage +Savage City +Savage Gamer +Savage Kush Savage Mind +Savage Pimpn +Savage Titan +Savage izJkD +SavageBigL SavageSource Savaged Savakuda Savalar Saved +Saved Me Savg Savilahti99 Savior +Saviour +Savj Savjry Savoureux Savpryan Savu +Savu Nahka Savustettu +Savvo +Savvune +Savvvy Savvy Savy +Savy Neals +Saw Em Off +Saw Siege Sawanne Sawaz1 +Sawbonez Sawdey +Sawrik Sawzall12 +Sax +Saxerpillar +Saxlord2500 Saxon +Saxon_knight +Say Allo +Say Freeze +Say Geronimo +Say Go Put +Say Gz Rn +Say aligh SayMyName +SayNo2Ebola Saya Sayadzin Sayersi +Saylorbtw Saymouseart Sayonara +Sayooo +Saypa Sayrim Sayrr +SaysNiceAlot +Sazch +Sazere Sazme Sazzarull +Sboy_90 Sbraga +Sc ruffy +Sc0nesy Sc0ttishDave Sc1ttl3 ScOx +ScOx ChrisM +Scabrick Scaf Scaggy +Scaha ScalerSlut +Scales +Scampr ScandalousHC ScannerBen Scape +Scape Jam +Scape Snake +Scape Steve +ScapeChad ScapesGhxst Scapeskater +Scapin Scaping Scar +Scar TNL +Scar of Time +Scarb OS Scare077 Scared +Scared Jr +Scared Zebra ScaredOfAll Scarfade Scargut @@ -20041,63 +41740,99 @@ Scarlett ScarredScape Scarsx Scarves +Scary Face +Scary Me +Scary Parrot +ScaryBrandon ScaryShadows ScaryTerry ScaryVacoom Scat Scat19 +Scatheful +Scatter +Scea +Scemblix SceneGfX Sceneryy Sceptile Scew Schaapers +Schams Scharnhorst +Scheemz +Schepo Scheubz Schienenwulf SchijnWerper +Schildkroote Schildpad +Schileru Schiller1994 Schimy Schiphol +Schismo +Schizphrenia +Schlaide Schlak182 Schlanged +SchlipityDop +Schlitz Schlock Schlowmo Schlynn Schmaltz +Schmelting Schmidtty641 Schmokeyboii Schmoovin +Schmuck Schmuel Schmuk +Schneemann90 +Schnei Yo Schneidster7 Schneyy Schnitzel Schnitzl +Schnocks +Schnoob Schnops Schnozz Scholi Schoolies Schools +SchoonCombat Schooner Schoonzoon Schoopity Schorr Schout Schovaval +Schretty +Schricky +Schrodingus Schuabinator Schuck Schuyler SchwanzLord +Schweiaos Schweigende +Schwiemann Schwingy +Schwog Schwoopity +SciCloan +Sciamachy Sciario Scids Scils Scimi +Scimista Scimmy2face +Scion 1T ScizR +Scizorp Sclass707 Scodran Scoffs @@ -20105,79 +41840,160 @@ Scofiz ScoobaQ ScoobiedO0 Scooby +Scooby T1 +Scooby Yew +ScoobySnack +ScoobySnacks +ScoochPoooch Scoopie Scoops12 +Scooter999 +Scootr +Scoots Scoped Scorchbeast Score +Scoreox +Scoreyy +Scori +Scorial Scorialator Scorlibran Scorpiex ScorpioBoy +Scorpslay +Scorqion Scortyx +Scot ty ScotianHerbz Scotse Scott +Scott 0888 +Scott Men ScottJ +ScottKZ Scotteh Scottie ScottieP ScottsTotlol +Scottsdale +Scottvc Scotty ScottyPippen +ScottyThrall Scottyx Scourging +Scouse Lyfe +ScouseBandit +ScouseThanos Scout +Scout Dorvis +Scout Troopr +Scout a raid +Scouting UIM ScoutnStake Scowder +Scp-2786 Scr0t Scradmaster Scraex +Scrafo Scrambledleg Scrap Scrappy666 +ScratchGolfr Scratchzilla +ScreamIM ScreamSavor Screeb Screen Screws +Screws Floor ScrewstonTex +Scrig +Scringo Scrkidzl12 Scrotboy +Scrotetseg Scrruff Scrub Scruba10 +Scrubgod Scruffy +Scrums Scryzen SctyDsntKnow +Scuba Steev7 ScubaSnacks +ScubaSteveOG +ScubaStweeb Scuff Scuffed +Scuffed Jesu +Scuffed Ming +Scuffed Sire ScuffedGoose +Scuggie ScumBagAlex Scumbag +Scumbag Joe Scummy ScummyMonkey +Scumpi Scurlll +Scuro Scurrilous Scuto ScuttleAway +Scuzz OS Scvthe Scwubs Scybin +Scyld Scythe ScytheOrNeck +ScytheShreds +Scytheer Scytheplease Scythes Sdelta230 +Sdsdsd789 Sduckk +Se Ki +Se rena +Se7en Rye SeBambi +SeDzz SeLeV +Sea 7urtle +Sea Anemone +Sea Buoy +Sea Hawkins +Sea Lobster +Sea Monk +Sea More +Sea Saint +Sea Slugs +Sea Turtle +Sea Turtles +SeaManTaster +SeaShanty +SeaShellKing Seagal +Seagaru +Seagate Seal Sealab +Sealegs Btw +Seamlessly +Sean E +Sean Is Sean278 +SeanIsHiding +SeanRich1 +Sean_C Seande4 +Seangie 91 Seanii Seantjl Seany4444 @@ -20185,22 +42001,54 @@ Seanye Seanz Seapy Searched +SearingPain +Searob Seas +SeasTheDay +SeatGeek +Seated Seater +Seater HC Seath1552 +Seatoad Seaweed +Seazeee +Seb Fe +Seb Lt +Seb Sob +SebBTW +Seba Iron +Sebis Sebla +Seboeber +Seboobs +Sebukai +Sebzy +SecBongToke Secho +SecondMars SecondStage +Secondary +Secondes Secret +SecretlyACat Secretly_Bad +Sectokin +Sector Six Seculish Secwai Sedap Sedentary +Sedlom +Sedrf23 +See Too Far +See u em +SeeMeGoing SeeYou Seed +Seed Of Dee Seed386 +Seeeek Seeejay Seek SeekerofIron @@ -20208,222 +42056,425 @@ Seekerz Seeking Seeliss Seems +Seems Legit SeemsFair Seen +Seen A Babe Seenoevil +Seery Seerz Seffer Kover +Sefirah +Sefka Sil +Segelpaatti +Segma Sego +Segs69 SeibaRaion +Seifeltz +Seifer666666 Seig91 Seighilde +Seigneur5000 +Sein Blut Seiskalehti Seiverna +Seiya216 +Seize Sejaeek +Seje Sejj SejjNesta +Sek Loso +Sekaiyatra +Sekava Seko SektorQ Selaphiell +Selastiri +Selbyen Seldrium Selectic +Selena Gomes +Selesi Self +Self Attempt SelfStanding Selfie +Selina Kyle Selj SellMaxMain +Sellerz Selling ROTS +Sello_Hunter Sellu Selmer Selostaja +Selyk +Semantic +Sembient +Seme Semestro Semeul Semi +Semi-Stable SemiReliable Semih Seminary Seministi Seminoles +Semirare Semlan +Semours Semper SemperOP +Semperlex Senarii Senbonzakra Sencillo +Send Backup SendItKing +Sengster Senhor +Senhor Prego Senia +Seniab88 Senior +Senior Wells +SeniorCui SeniorLep +Senis6 Senjor Senkaiye Senkuu +Sennno +Senny Bridge +Seno 45 Senor +Senor Grumpy +Senor Nub +Senor Patata SenorMarcSux Senpai +Senpai Avv SenpaiDecer SenpaiiGod +Senpenbanka Senpukyaku +Sens Army Sens249 +Sensas Senses +Senses Fail Senses12 +Sensie SensualSnail Sentinel Sentristi Sentrosi Senturia Senzel +Seoyeonnie +Separi Sephiore +Sepi testaa Sepper Seppiee +Seps +September 26 Septic Septimus +Sepv +Sequenced Sequin Sequinex Sequissimo SequissuAnau +Ser Bone +Ser Boris +Ser Kelvin +Ser Paddles +Ser Percy +Ser dracarys Seracid +Seraff Fe Seraph +Seraphine BF +Serblicious SerenShadows +SereneMarine Serenity +Serenity Now +Sereri +Serfival SergeiSativa +Sergonomicus Serial +Serialist Serine +Serioga One SerionKiller SeriousLip Seriousruss +Serkr Serkus +Serls +Sernara Sero87 +Seroplex Serori SerotoninBTW +Serpent Sin +Serpico Serpula +Serpy +Serros SertCocuk Server Servia Service +Service Jobs +Service user Sese Sese778 Sesil +Sessanna +Set h SetItToWumbo Seta Seth +Seth1711 Seth6191 +SethH350 Sethalas Sethliu Sethmare +Setko Seto292 Settled +Setzal Seut Sevadeg Sevalt Seved223 +Sevenation Seventh +Seventh Son Seveoon Seveoonn +Severith Sevie Sevvy Sewdri +Sex Beast +Sex Gods +Sex Sea +Sex Vibe +SexEZ SexFerguson +Sexi Rat +Sexperience +Sexsi Sext0n Sextor +Sextuple +Sexy Carl +Sexy Cholo +Sexy Style +Sexy Will +SexyFatGirls +SexyLefty +SexyPeaches +SexyShooterr +Sexyteurs +SeymourAses Seyriu +Seytan Sfa05 Sfannie +Sfd Sfen +Sfouf +Sg Mini +Sgn +Sgs flames +Sgt +Sgt J0hns0n +Sgt Jacques +Sgt Moogoo +Sgt Ru642 +Sgt Salliss +Sgt SaltySac +Sgt-Sub0_99s SgtBuurman +SgtSausy +SgtSlaughtur +Sgtbea93 Sgtfatboy Sgtsoldier Sh00t3r2O2O +Sh0rt Lived Sh0rty Sh0w Sh3pathome Sh4d0w009 Sh4dowfox Sh4rice +Sha r k Shaan ShabooBopWoW Shabot +Shaboun Shabuski Shaco +Shaco Bot ShaddyB +Shade T ShadeSlay +ShadedWizard Shadedmedic Shadeknightt +Shadesypoo Shado +Shado Man69 +Shadonnon Shadow Shadow Flare +Shadow Left +Shadow Specs ShadowBobado ShadowBoy001 +ShadowFink +ShadowGodEU +ShadowJosh ShadowMakerz +ShadowPrism9 ShadowSinz ShadowSniper +Shadow_006R Shadowclysm Shadowcra Shadowlimes +Shadowmax666 +Shadows Fall Shadowscreen +Shadowsun +Shadowwheel Shadsnp2017 +Shadum ShadwRoca Shady +Shady 716 +Shady Glade +Shady Shin +Shady417 Shady78 ShadyMilkMan +ShadyMinkins +Shadys Bro +Shadysider ShaftyKrafty Shafu Shagnarok +Shags Bussy Shagzy +Shahe D +Shahub ShakaLakaInU Shake +Shakeem +Shakeman ShakenSoda Shakkas Shakuuuur +Shalamaar Shalendra Shallistera +Shalomga +Shalysa +Sham on Osrs +ShamSavior Shaman ShamanJon ShamanLizard Shamanletics Shambler96 Shame +Shamiina Shampoe +Shampoo Shamsal +Shamu +Shandaie +Shandooobie Shane +Shane F3 ShaneSJ Shanee-oo +Shanem24co Shaneobrahhh Shaner Shanfew Shania +Shania Twain +Shanizmo Shanked +Shanked it Shanks +Shanks Haki Shanksen +Shantaaa +Shantar +Shanteven Shantideva +Shapalo Shapaz Shape Shaper Shapii Shaqs +Shaqster1k +Shaquayquay Shard +Shard 2 +Share E R +Share Sucks Shareit Sharing Sharingan +Sharingan x SharishaXd Shark SharkTheBait +SharkiFan Sharkie200 +Sharkie92 Sharktail Sharkyyyyy Sharmac Sharmz +Sharn Sharoxi Sharp Sharpeyy Sharpgut +Sharpi e +Sharpie Sharpman767 SharpyClaw Shart +ShartEnjoyer +Sharven +Shasan501 +Shat 2 Hard Shatllef Shatter +Shatter Day Shaun +Shaun R Shaun135961 +Shauna Vayne +Shaunhunni Shaunni1 Shaunrnm3 Shaunyx @@ -20434,234 +42485,460 @@ ShawnBW ShawnBay ShawnXL Shawni +Shawnoh +Shawrysx +Shay Kirbuti Shaya +Shaya Rene +Shayd Shaykolade Shaymuz ShaynRS Shayne +Shayne 1 +Shayne Topp +ShayneW +Shaziyen +Shaznon Shazu00 Shazzys +Shckizm +She Moist +She Slackin +She is lvl18 +Sheashanera Shebbi +Sheep SheepKhalifa SheepTrainer +Sheepi Sheeppo +Sheer freeze +SheeshSkicka +Sheeshlor Sheetm3tal Sheetz +Sheev +Sheff-Rah +ShegoSimp Sheguey +Sheikk Sheilaaaa2 Sheivattu +Shelbgasm Shelbi +Shelburz Sheldore Sheldozer Sheli Shelios +Shelkun ShellBeRight ShellLeeBee Shelldunk Shen +Shen Btw +Shen-pai Shenfu Shenkie Shep +ShepShep95 +Shepher +Shepherdess Sheq +Sherbert96 +Sherkey Sherlock +Sherlock 07 +Sherlockness +Shernz Sherry +Shertie +Shes Nasty +Shes Royal +Shesterkin Shev64 +Shevzzz +Shewolf Nova Shezwick +Shh +Shh Im Maxed ShiaLaBuff Shiba +Shiba Miyuki +Shibidy Shiddy +Shieldy +ShiftWorker +Shifteroo +Shifterr Shiftless Shifty Shiftynifty Shiftyy Shifu +Shigure +Shihyi Shiifty Shiiftyy Shiit +Shiit head Shikhar Shilo +Shilo Void Shilomies +Shilvah +Shimmeister Shimosh +Shin Nohara ShinMalphur Shinchi +Shine tales Shing +Shinichiro Shinigami +Shinigami 07 +Shininess ShiningStar0 +Shining_Bind ShinnGee Shino +Shinobi Shinook +Shinox Shintaz Shintygod Shiny +Shiny Dragon +Shiny Glue +Shiny Mew +Shiny Olm ShinyMimikyu ShinyNoctowl ShinyShyvana Shionono +Shioshii +Ship I +Ship s +ShipCaptCrew +Shipoden +Shipppo +Shippy +Shir +Shir0u Emiya +Shirakami Shiramasen Shiranaii +Shire Fox +Shiredragon Shiri +Shirlan Shirts +Shishkemax Shiskey +Shiv HD +Shivals Shivered +Shiveron Shivers888 Shivoc +Shiyah +Shizlo +Shizzus +Shmazza +Shmeckington +Shmecko +Shmelf +Shmerlin +Shmew +Shmexy +Shmidtie +Shmo Shmoah7 +Shneeb Shnoobed +ShoToy +Shoarma Shoarmadyl Shocka +Shocked Shockedme +ShockerMe +Shockzeyy Shogaol +Shompy Shongrislomg Shonion +ShooK em Shoog +Shook Shoopdiesel ShootYaSkool Shootem40 +Shooty Tater Shop +Shopferix Shora57 Shore +Shorelyy +Shorez Short +Short Mike +Short Tale ShortHoppe +Shortec Shortguy Shortstop819 +Shortz360 Shot Shot1200 Shotixx Shotoer +Shotzz +Shoulderr Shouto Show +ShowFeet +ShowUrPits Showby14 Shower +Shower Maxed Shown Showtek Shozen Shpee Shpikey +Shpongle +Shrabbaa Shran Shredded +ShreddedMD Shregz Shreikkiller Shrek +Shrek 6 +Shrek BTW +Shrek2 ShrekLovr +ShrekazoidPR Shreksalot Shrik Shrikems +Shrimp 72 ShrimpForx ShrimpStick Shrimpa +Shrimping Shrimpster Shrimpy5 Shroden +ShrogTheBarb Shromik Shromu +Shroom God +ShroomLord17 Shroomjak Shrtct +Shrumes Shtankybruce +ShuZ Shuaston Shuckle Shuddie Shuffleee Shuiin Shultzy +Shun Conery +Shundo Mew +Shungite Bar Shuno +Shunolog Shunpown Shunrai Shunseh Shupa +Shure Shurty Shut +Shut Up Megg +Shut Up Mmeg Shutnik +Shv Shvne Shwift +Shwiftzy741 +Shwoompy Shwoop +Shxtn +Shy Kirino +Shy Mew +ShyElfTrap ShySphincter +Shyhorsegirl +Shyphii +Shypsena +Si Ya +Si d +Si mp SiFu +SiIver Fang SiRzZ Zeref +Sia +Siallus +Siamees SiameseCat Siamogale +Siane +Sianna Siber Sibling +Sic Mundus SicSolaFide +Sicariiarum Sicily Sick +Sick Degen +Sick Ego +Sick Giraffe +Sick Irony +Sick Main +Sick Mark +Sick Pet +Sick Skill +SickFam +SickGainsBru SickNasty SickPete +SickPump Sicka Sicker Sickhuman +Sickhunt +Sickle76 Sicknez Sicko +Sicko Stronk +Sickvibe +Sicxness +Sid and Geno Sidabras +Side B +SideChump +SideMeatt +Sidecutters Sides Sidewinder15 Sidge SidijuS +Sidin1 +Sidka60 Sido Sidocahn +Sidro +Sie SiebScho +Siegmeyer14 +Sielunveli +Siemke SiennaEhtycs +Sierra Echo Sierzant Sierzy Siesta Sifu +SifuPlankton +Sig Man +SigSauer Sigarda206 +SigeFrid +Sigefride Siggen Siggie Sigh Sighlent SightUn +SightUn Seen Sighted SightlessDog Sightlines Sigiis Sigin +Sigma Blood +Sigma Oasis +Sigma Seven +Sigmarz Sigmazeous Sigmet Sign Signd0g +Signoth +Sigrudson Sihana +Sihl SihuiRS Sihva +Sihva Dark Siida +Siiiiiiix Siimon3 Siimse Sijmen Sika Sika-Mika Sikauss +Sikerrim Sikko +Sikko NL Sikkosaurus Sikn Sikruz Siks Sikskilla Silanz +Silasco Silavex Silcaria Silcooper Sild SilenceSC2 +SilencedAF Silent +Silent Sky Silent too SilentEnmity SilentFabric SilentFaux +SilentQ Silentzsword Silicon Z +Silinsh Silixi Silky +Silky Beauts Silly +Silly Asian +Silly Kev +Silly Rum +Silly Virgin +Silly Zilly SillyPsybin Sillyibexe Silmarilli +Siloxane SilvaAlzir42 Silvaa Silvado +Silvanla Silver +Silver Cave +Silver King +Silver Lugia SilverForM SilverLining +SilverPuni SilverRizlas SilverTeej +Silverado Silverang Silverbluds Silvercrux @@ -20671,89 +42948,244 @@ Silverimo Silverxlion Silviii Silvoan +SilvrLining Sim Aero Simeeon Simel Simetra +Similuck +Simmcheck Simmi091 +Simmie Simmololol +Simmondz +Simmumah +Simno Karys +Simoggy +Simon Bruh Simon Jnrr SimonCookie +SimonCowell +Simone Weil +Simp Andy +Simp4Jessy +Simp4Science Simp4Tanz +Simpa +Simpinz Simple +Simple Helm +SimpleSlays +Simplekinz Simplest +Simplex +SimplexDabs Simplicitey Simplicityx Simply +Simply Quiet +Simply Sam +SimplyBadass SimplyBetter SimplyFresh SimplyLlama +SimplyNikki SimplyPro +SimplyRiolu SimplySendIt +Simply_JS +SimppCatcher +Simpson +Simse SimulatedYou Simutrans +Sin Cena +Sin Cere +Sin City +Sin Dragon Sin0fWrath SinCrux +Sinappihauki Sinasappel Sinatra Sinbad Sinbvd Since SinceOldDays +Sinclair Oil Sincoura Sindo +Sinefeld Sinerule Sinetine +Sinferna SinfulDesire +SinfulDingo Singerderek +Singulares +SingulariTx +Singularry +SinikOG Sinister +Sinister C6Z +Sinister Key SinisterLeft Sinisterz06 +Sinistr Dave Sinitank Sinixx Sink Sinka +SinkingUnder +SinnerUK Sinner_Blue Sins +Sins of Thor +Sint Truien Sinta +Sinterglass +SiontC100mph Siorri Sioux +Sip Cleeko +Sipa SippinBeers Sippy +Sippy 1 +Sipsta +Sipuliparoni +Sir Zhao +Sir 0wnalot +Sir Ali +Sir Ante +Sir Boberton +Sir Botje +Sir Brandito +Sir Burritoe +Sir Chancho +Sir Colossos +Sir Daven +Sir Deedge +Sir Delwin +Sir Doland +Sir Doobies +Sir Elusive Sir Epic 3rd +Sir Ferreus +Sir Fire Ki +Sir Frekkel +Sir Fudmire +Sir FurDude +Sir Galleth +Sir Godfree +Sir Graj +Sir Ial +Sir Idwaly +Sir Iron 4th +Sir Jamie N +Sir Jinhai +Sir Junn +Sir LafaLafa +Sir Lanofg +Sir Leadfoot +Sir Lidd +Sir Lobster +Sir Luke1627 +Sir Max Tb +Sir Mordacai +Sir Mr Bro I +Sir Nak Sir NichoIas +Sir Nuggers +Sir O Tonin +Sir One Shot +Sir Peg +Sir Poisonfa +Sir Pur Paul +Sir Queeffin +Sir Reflex +Sir Reos Lee +Sir Rhaenir +Sir Rolf exe +Sir Seifer +Sir Shrimps +Sir Slyck +Sir Son Goku +Sir Sparhawk +Sir Stidi +Sir Stitch +Sir Sucellus +Sir Sven +Sir Tanner +Sir Ton4 +Sir Towliee +Sir Truble +Sir Var4 +Sir Ving +Sir Vkk +Sir Whipit +Sir Wismar +Sir Wojtek +Sir Zakar +Sir friezer +Sir philippe +SirAirik SirAmikVarze SirAngo SirArcAngel +SirArimal +SirBabbers SirBerus +SirBjustice SirBoma +SirBoopin SirBroderick SirCapper +SirChknNuget SirCoolAsian +SirCumsAlil +SirDanSolo55 SirDarrBear SirDeimos +SirDouglass SirDougles +SirDoyvid +SirDude SirEfficient +SirEskimo +SirFroggits +SirGillespie SirGoki +SirGrimsby SirGrizzly SirHines SirHmm SirHollywood SirHumanBean +SirIronyMan SirKakoiml SirKefir SirKill SirKulls +SirLarry55 SirLoinalot0 SirLunarias SirNexALot +SirOcean +SirPegAsians +SirPhockQ SirPoo SirPwn SirRebs +SirRuck +SirSanders +SirSchmoopy SirShakes SirSilky SirSlayalot SirSpicius +SirSplinge +SirSunTitan SirSwaggzz SirTrea SirVenompool @@ -20763,49 +43195,92 @@ SirYiffer Sir_massmo Siraxis3310 Siraz +Sircamm +Sircarenot2 +Sirdedalot +Sire Edward SireSucks +SirenMan Sirhca Sirius Sirixen +Sirjoshihad2 +Sirkuspelle Sirlagger Sirlightboy Sirmordred44 Sirnuclear +Sirroyce +Sirsa +Sirsteve99 Sirstynkalot Sirswish4 Sirtippy23 +SisiJones Siste +Sit Quietly +Sit xD +Sita Koll +Sita Rama +Sitharii Sithlord Sitinduck Sitt +SiuMan Sivior000 +Six 3 Ohh +Six Dix +Six Kills +Six Seasons +Six Sen6e +SixFootAmigo SixOhFour Sixcess +Sixfoot0001 Sixint Sixpkabs Sixpounders +Sixten106 +Sixthflag Sixty +Sixty N9ne SixtyNine73 +Siynistr Sizashi SizeMan Sizer +Sizzle Cat +Sjaak +Sjak Sjakk +Sjakk Spill Sjappy Sjeb Sjele Sjenjatje Sjenkie +Sjokoladebit Sjoni SjonnieDon +Sjonsen Sjotha Sjulstad99 +Sk Gollum +Sk Scooter +Sk ky +Sk u lly Sk1llzy_RS Sk1ttlz Sk8rgrl474 SkHiCharisma +Skaaddoosh +Skaane Skachoo Skada +Skada N +Skade Skaduw99 +Skaf SkaffeAgent Skaicius Skaikru @@ -20813,69 +43288,124 @@ Skailas Skakkae Skal95 Skanderbeg +Skank Hunt32 +Skarboeblie +Skarking SkarmBliss +Skars Iron Skaryth Skate +Skate Squirt +Skatemyboard +Skater 1299 +SkaterJord SkaterSkillz Skatergod Skaterlegs Skaterune3 +Skaufel +Skcoot +Skedeby Skedsauce Skeeb Skeer +Skeesh +Skeeterstein SkeetlzPopz Skeff Skeggy Skelebral Skelethon +SkeletonSex Skelex Skelnik +Skelpy Skely527 +Skelytom +Skepp +SkeptasMum +Skeptical +SkepticalSol Skere +Skere Bert Skermy Skerp_Perp Skertt Sketch1e +Sketchiin +Sketti Water +Skewp Skezi +Ski Gim +Skiba +Skibidi Tob Skibidibills Skidoodlee SkiemLord Skifree +Skilane Skill +Skill Will +Skill issues +SkillFatigue SkilldSkitzo Skilldriver Skilled +Skilled Boof +Skilled Roy Skiller SkillerC4 +Skillerbabes +Skillersj +Skilless +Skillexi Skillhunter1 Skillian89 Skillius Skilll +Skilllzdan Skilln +Skillpace Skillpadden Skills +Skills Ahoy +Skills Boss +SkillsPets SkillzGainz SkillzLmao Skillza Skillzzz Skilor +Skimer SkinStitches SkinTone5 SkinnedYoshi Skinny +Skinny Mage Skinthix Skinyoualive +SkipTheTask Skipi Skipper996 +SkipperMcgoo SkipperPing Skippy +Skiptutorial +Skito +Skittlz Doc SkitzRs +Skitzad Skitzpatrick +Skizzles +Skj Skjaera Skjeberg Skjelve Skkarpz +Sknnywhteboy Sknor +Sko Birds +SkoalSnus Skodem Skoh Skol @@ -20883,6 +43413,7 @@ Skold Skolder Skolzera SkoobiDooby +Skooier Bibs SkoomaPls Skopix Skopusnik @@ -20892,22 +43423,37 @@ Skorne Skorned Skotten Skov +Skovduen Skovtt +Skox +Skral +Skramlan99 Skreecher Skreeeech +Skreeeech Z Skriptz Skritman Skrl SkroTam +Skroooodge Skrote +Skrrrtle Skrudzas Skruf SkrumpKing Skrychi Skryze +Skubert Skuddar +Skul SkulbIaka Skuldebrev +Skull 2148 +Skull Cove +Skull64 +SkullDemise +SkullFkdNex +SkullFricker SkullTrailYT SkullTricked Skulled @@ -20915,46 +43461,77 @@ Skullhead6 Skullking199 Skullpit Skulls +Skulls Jr +Skumbag Xell Skummi Skummy Skumpy Skundos Skunk +SkunkAsylum +Skunkerinho Skunkieblow +Skwat MD +Skwurtle +Sky BIues +Sky Em +Sky Mages +Sky Satan +Sky VR46 +Sky and Sea +Sky is mine SkyBouncer +SkyBroadband SkyFlyPie SkyKnight +SkyRizzy1 SkySailing SkySkyClover +Skyblownet +Skybussa Skyda SkyeKuro Skyenss +Skygirl Tami Skyleosaurus Skymonster77 Skymore Skynet1188 +Skyom +Skype Call Skyreacher Skyrider Skyrider50 Skyrion993 Skywalkingyo Sl yx +SlGURD SlGlL SlLPH +SlRCUMSlZE Slaats SlabOfCorona Slabs Slackington Slacky +Sladdbarn Slade9100 +Sladist +Slagter Slain +SlainThemis +Slaked Slakito Slakje Slakoth Slam +Slam Daddy Slambo +Slamdabooty +Slamdark Slamer1993 SlammDaddy +SlammalS Slamz Slance Slap @@ -20963,35 +43540,71 @@ SlapShot777 Slapen Slaphead28 Slapmeister +SlappChopped SlappaBogan +SlappeStront Slappenn +Slappers SlappinMango +SlappybagsFC Slaps +Slaps Nuts Slapzinger Slaqk +Slarkan Slash Slasher +Slasher z99 Slasher0708 Slaskepott +Slate Snake +Slats Slaughta +Slaughtered +SlaughtrMeat +Slav Kings Slava Slave Slavish Slavtonio Slay +Slay Addict +Slay More +Slay Or Bust +Slay Pets +Slay R +Slay Tim Slay0rDie Slay3rmate SlayAChicken SlayEeryDay SlayForFame SlayForJoy +SlayImpulses SlayIsMyfame SlaySir +SlayToSkill Slayaholic Slayborhood Slaycation +Slaydenoob Slaydo +Slayem Maul Slayer +Slayer 247 +Slayer 267O +Slayer Azye +Slayer Clues +Slayer Helmz +Slayer King +Slayer L0G +Slayer Mid +Slayer Rome +Slayer Shark +Slayer Task +Slayer XPs +Slayer bond +Slayer n gp Slayer314 Slayer360 Slayer7515 @@ -21000,6 +43613,8 @@ SlayerKingv2 SlayerRyan Slayerburger Slayerdog +Slayerg1g +SlayerisGame Slayerknox Slayerman Slayers @@ -21009,22 +43624,32 @@ Slayhades383 Slayic Slayin SlayinSkills +Slaying Poon SlayingBooty SlayingDave Slayingit14 Slayn +Slayology Slayosaur Slayr Slays SlaysIronman +Slayscaped +Slayter +Slaytr +Slayv Slaywolf Slayyer59 SlayzyDayz +Slck Mark SleanClate SleazySEAL +Sleazyscape Sledgendaddy Sleeep Sleep +Sleep Cycle +Sleep When Sleepercell Sleepgoood Sleepierz @@ -21032,181 +43657,376 @@ Sleepiness Sleeping SleepingCow Sleepinonice +SleeplessC47 +Sleepnaut Sleeps Sleepy +Sleepy Fr0st +Sleepy Hoop +Sleepy Mulli +Sleepy Tired +Sleepy sound SleepyPlantz SleepySus Sleepybear Sleepzy31 Sleet56 Sleete +Sleighbor Sleightyyy +Sleighyour Slemmy Slender SlepinHose +Slepinn Slepping123 +SleppySnek +Sletmar Kets +Slettenbak +Sleuth +Slev711 +Sleve +Slevenderrrr Slewwyy Sleya +Slibbon Slice +Slice Dice85 +Sliced1Bread +Slicer3 0 Sliceseau Slick +Slickslipply +Slicore +Slidecast Slides Slidpanther Slidz +SlieNinja +Slienced +Slievemore +SlihgtyWrong +Slikjee Slim +Slim Gandalf +Slim Paul +Slim Yogurt SlimJD +SlimeShat +Slimey Fish +Slimjim Slimy +Slimy Uim +Slingin Slinkeh Slinky +Slioter +Slipery Peet Slipory SlipperySnek Slise745 Slit Slizzle +Sll8 SlnOfWrath +Slo Slo w th +Sloanee SlobOnMy +Slojsarn Slokei Sloopie Sloothy Sloper +Sloppy Joey +Sloppy WAP +Sloppy Zoot +SloppyGnomes +Sloppyninj Slorkie +Sloshpack +Slotche +Sloth +Slothenly +Slothery Slothhs +Slothly Sloths Slothy SlottedPig +Slough Slow +Slow Down +Slow Spirits +Slow blow +SlowRoaster +Slowky +Slowly Dying Slowpoke SlowrolI +Slowxpgamer Sludgy1 +Slug Kiss +Slugggy +Slugjob Slugr +Slum Village SlumberGoose Slumptality Slurggi +SlurmsMcnzie +Slurmz +SlurpDaTerp Slurpez +SlurpinBrews Slus Slush Slushhy Slushii Slushiiii Slushyy +Slusserbust Sluthra Slutism +Slutzilla Sluwe +Sluwe Odin Slxpz +Sly CHRlS +Sly Guy Matt +Sly Shy Guy +Sly Spyro +SlyPancakes Slyfocs Slyjack Slymax Slypes Slythiren +Slyzuh Sm0keyMcpot +Sm0rc420 +Sm1thyy +Sm6 +Sm8 AJ +Smaarips Smac +Smack Snr +Smacka Fish +Smackatosh +Smacking 0s Smackintoshh Smaeow +Smai Smajli +Smal Iron Small +Small Chief +Small Idea +Small Iron +Small Paul Small3y SmallBlock SmallBrained +SmallPepino +Smallemans +Smalley +Sman Smang +Smart Dog +Smart Foam +Smart One Smartbabe SmarteeRS SmarterMop +Smartfon Smartiest Smartyross +Smash Vials Smashing Smaug SmaugSlayer +Sme Cape Smeared Smecher +Smeeezy Smeegoles +SmegGIM Gr8 Smeggyweggie SmegmaJesus SmegmaL0rd66 Smegmatism +Smegmboy123 +Smekkes Smeklius Smeli0das Smelix3 SmellMyClam +SmellingMill Smelly +Smelly Butt +Smelly Guy +Smelly Kip SmellyGymSox +Smellyjeans Smellypillow Smess +Smetvrees +SmexyBaker +Smezzie SmiTHSaNiTy Smiddels Smiddle Smidjorgen Smii Smil +Smil3r +Smile My Boy SmileBro Smiled +Smilee Smiles +Smiley AK SmileyCyrus +SmileymanTim Smilf +Smiliprophet Smilts +Smimi Smumu SmiqelAngelo +Smirk Smit +Smite Bait Smite4Ags SmiteForAgs +Smited Time +Smites Smith +Smith Inc +Smith a Cat Smith2109 SmithRebirth Smithin +SmithingWhip Smithinz Smithoxmagic Smithy +Smithy NZ Smittyk15 +Smo3 Smoak Smob +Smoel Dicht SmoggyB +Smokahontaz Smoke +Smoke A Bag +Smoke Brb +Smoke J Brb +Smoke Oil Smoke2Fly +SmokeChedFTM +SmokeCheds +SmokeM0B SmokeSocial +SmokeandCum +Smoked Bacon +Smoked Ed 92 Smokedale Smokee SmokeeLoki SmokerOfDank Smokes Smokey +Smokey Eyes Smokey201 +Smokeynutz Smokeynz +Smokiecat +Smokin Clans +Smokin Perks SmokinBlunts SmokinChills Smoking +Smoking Hash SmokingFlax SmoknDReefer Smol +Smol Big Toe +Smol Kupo +Smol Lyra +Smol Pikachu +SmolDeer Smoland +Smolrice Smooooove Smooth +Smooth Draft +SmoothRabbi +Smoothlu Smoothpossum +SmoqueWeed +Smork It +Smoss +Smot Poking Smpli Smuddy Smug +Smug Advice +Smug Grin +Smulknul Smurf +Smurfboard Smurfed Smurfingt0n +Smurfman254 Smurfukas +Smurghilda +Smurky Maart Smurphington +Smush +Smush Things +Smushma SmushyCows +Smuvies +Smuzzle +Smythy Sn0op Sn0rkath420 +Sn0wb4ll Sn1p3 SnYp Snabba +Snack Bar SnackJack +Snackspace Snacktime SnafuPC Snaggapus +Snaghyrnd +SnailNipples Snake +Snake Boss +Snake Jazz SnakeSpec Snakebite37 +Snakebites Snakedeath2 Snakedogbear Snakeling +SnakeskinRag +Snaks Snaky +Snaky Snake SnapMyCarot +Snapa7 +Snapboog1e +Snape Grass +Snapeeh +SnapperSnafu +SnappySplash SnarTheCook +Snarbo +Snarf Snarflaxus Snarfsnah Snarglefox @@ -21214,62 +44034,110 @@ Snarl Snarx SnaszAndrejj Snatchquatch +SnazzyLt Sneak Dissin SneakEnergy SneakKhajit +Sneakbo Sneakee Sneaky +Sneaky Chair +Sneaky IM +Sneaky Shark +Sneaky47 SneakyBaloup SneakyCake SneakyEmu +SneakyFrogg SneakyGnomne SneakyOD SneakyPete SneakyTay +SneakyZoot Sneakymag3 Sneakyvicn Sneakywaffle +Sneakz Snee Sneekerz Sneekey SneekyBeeky +Sneekydied +Sneeuwpoeper Snefnuk +Sneide O_o +Snek zy SnekInMyBewt Snekkerboden Snekling Snekty +Snekty Jr +Snelms Deep Snelmz Snibzy Snickers Snickersbite +Snicklesz Snide +Snide Senpai +Sniff K +Sniff this L +Sniffi +Sniffin 24-7 +Sniffin Bags SniffinBags +SniffingClue Snifflematt SniffmySmoje SniffyMonkey Snike4 Snikepaven Snipe +SnipeOne045 Sniper +Sniperfrank1 Sniping Snipor +SnkyGreninja +Snlly +Snny SnoWorm Snobby +Snobby Elite Snoep +Snollen Snoobsteri +Snoogens +Snookies Snoop +Snoop D9 +SnoopSiah +Snoopfyzle Snoopy Snoot Boops +SnoozeBolton SnoozingBear +Snoper +SnoreLunaLax Snorff1 Snorklarn Snorlax Snorlax9030 +Snorlaxz iLy Snorona Snot +Snotlapje Snow +Snow Day +Snow Poff +SnowBunnyhvn +SnowEmpress6 +SnowManSam +Snowangel18 Snowballerz +Snowbaru Snowclub +Snowdaze Snowearth Snowelle Snowfall @@ -21279,71 +44147,144 @@ Snowiest Snowii Snowmen Snowscythe +Snowsmith43 Snowvof +Snowy Winter Snowy2653 Snowyo26 +Snowys Main SnuSnuShi Snubby +SnugLikeABug Snuge +SnuggleSnail Snugglez +Snugins Snuift +Snuite SnusMumr1ken Snuskig +Snusti +Snuup Snuus Snuuska +Snype_U +So Far To Go +So Flattered +So Inagawa +So Iron BRUH +So Jamiezing +So OSRS +So Quiche +So Warm SoHighhhh +SoLoH DoLoH SoMoist SoSimPol SoSleepy SoStronk SoUhBtw SoVeryInvis +Soaa7 Soad +Soally Soap013 Soaphia +Soapybubble Sobe +Sobe VII Sober SoberFarmer +Sobibor +Sobotka Soburin +Sobzy Socca Soccerc12 Soccermom02 +Soccy SocialAnxty +Socialism SocialistGuy +Sociality +Sock Jesus +Sock Starch +Sock Stealer Socket +Sockks Socks Sockum Socrates Socrates001 +Socratestes Soctch +SodaGrab SodaLambz SodaPopPunk Sodaseg Sodasokwa +Sodd +Sodo Pop Sodobrasil1 +Soecara +SoegLeppel SofaKingHI6H +Sofakingdom Soffachka Sofia +Sofia Cooper +SofiaVergara Sofiero +Sofoni Soft +Soft Chicken Soft Dump +Soft Geeves +Soft Jesus +Soft to Hard +Softboil +Softcorejmac Softer Softest +SoftestFox +Softice SogSteelrock Sogeking Soggy +Soggy Napkin SogxNeutro Sohcahtoa090 Sohh Sohl Sohrac +Soi +Soi Cowboy Soija +Soisox +Soivio Sojuah +Sol Buendia +Sol Heredic +Sol Heretit +Sol Leo +Sol Rock +Sol o +SolTeevo +SolaDuaeManu +Solakoust Solan +Solar Stone +Solar754 +Solarized +Solarrr Solaryohm Solarys +SolasLexeth Sold +Sold GF 4Gp +Sold My Name SoldMyRNG +SoldMyWife SoldUrDad4GP Soldaat Soldaat824 @@ -21352,80 +44293,169 @@ Soldjer Soldtheman Sole226 Solek +Solely Soley Solibiobois Solid +Solid Snack Solid Stache SolidSnape +Solidtag Soliform +Solimanx Solitary +Solkrieg +Sollor +Solmlet Solo +Solo A7X +Solo Aero +Solo Arron +Solo Blitzy +Solo CM +Solo Chumb +Solo Dani +Solo Foxy +Solo Geeber +Solo Gira48 +Solo H3llz +Solo Hayden +Solo Herbo +Solo Idenn +Solo Jawn +Solo Jones +Solo Jord +Solo Kev +Solo Mace +Solo Mus +Solo Road +Solo Romte +Solo Russian +Solo Sieb Solo Sirva +Solo Trojan +Solo Umbreon +Solo Ward +Solo Wind Solo Xenopus +Solo Yoyo +Solo kris +Solo snapper Solo2424 +SoloBandit +SoloBongo SoloCanadian SoloDeicide +SoloDeth SoloDynamix SoloFireFist +SoloFlar SoloFletcher +SoloHotDog +SoloIron30 +SoloMerx SoloMishMosh SoloMission +SoloNotAlone SoloProject SoloRob SoloShow SoloSloop SoloSmackbar SoloSnhaas +SoloSupOnly SoloTibbs Soloable +Solobussy +Solocek +SolohellRat SoloingLife Soloman50 Solomasi +Solomon +Solomon Kane +Solomopp +Solos Turn Solowerkz Soloyo Solsa +Solucki +Solufana Solus +Solus RS Solvent +Solvent less +Soly Handal SomalianRats Somalor +Somavrana Some +Some Pets +Some Ranger +Some Use Some mad dog +Some1youno SomeDirtyOar SomeGoldDust SomeRSIdiot Somix +Somniac One Somnolent +Somoshoho Somppup +Son Goku MF +Son Huntr +Son LeGeND +Son o Rous +Son of Akkha +Son of Hail SonArtorias SonBuns SonIron +SonNamedBort SonOfDecay SonOfGandalf SonOfWright SonVsStepmom +Son_Jo Sonc +Sondey +Sondr Sondra Sonekta Sonett Song +Songs Of +Songsteel Sonhov +Sonia Strumm +Sonic 513 +Sonic Kp3 +SonicYouth Sonicgg1 Sonics +Sonics Alt +Sonidoo Sonjini SonneTeufel +Sonol Sonsofkyuss +Sonx SonyVegas17 Sonycboom SooCrispyy SooUnlucky +Sookadiik Soolo Soon SoonAHusband Soonifer +Soop Pock Soop3rpig SootSpritez Soothe SootyWhale32 +Soph Sophinx Sophlex Sophomaniac @@ -21436,18 +44466,31 @@ Sora Soraaxle Soradin Sorado6 +Sorarpegius Sorbits Sorbosander Sorcere10 Sorcerer5555 SorcererOdin +Sorcerio SorceryFish +Sordnatra +Sore Sorec +Sorenisbad Sorenn +Sorgrum +Sorinvv +Sormeton Sorose Sorry +Sorry Iron +Sorry1mLate +Sorryganster Sortable Sorted +SorthIon +Soruve SosBoerrr Sosig Soskiller6k @@ -21456,131 +44499,244 @@ Sosraid Soss Sossukorva Sossumafia +Sosuke Aizen +Sotamage +Sotetseg Sothe1 +SotonSteve +Sottetseg Soujy Soul +Soul Burger +Soul Scaper +Soul Sleep +Soul v9 SoulEater957 +SoulMadness +SoulOfMidir SoulSteala SoulUnleash +Soulbarrier Soulbearer +Soulcape +Souldia +Souled 0ut +Soulja Lance Soulkilled3 Soulkn +Soulles SoullessMask SoullessWood +Souloh0 Soulololol Soulplay Gee +Souls Mate +SoulsRampart +Soultiller Soulxicution +Sound Soul Soundbar +SoundsOfSoul Soup +SoupEyes +SoupOfTheDay +SoupTheDuck +Soupshi Sour Sourzilla SousChefLuna Sousse South +South Dakota +South Park55 SouthPillar SouthSide Southampton Southenders Southern +Southp0le Souvenierr Souvis +Souvis5 Soux +Sovacam Sovakat Soveth +Sovetskie +Sovi Soviet +Soviet Union Sovryn Sow Love Sowodasoap Sox207 +Soxinder +Soy Duro +Soy Sauce +SoyBhoy SoyJuanEuro SoySoySoySoy Soyez +Soylemagne Soylo +Soz Misclick Sozan Sp00n Sp1cy +Sp1cy Ramen +Sp1cyAvocado +Sp33Dkillz Sp33dy +Sp3c Deck Sp3nC SpARioN SpBongile +Spaar Lampje Spaca Space +Space Bussy +Space Lily +Space Marine +Space Orbs SpaceC +SpaceEnter +SpaceScape SpaceToker Spacealt +SpacedPinata +SpaceeCowboy +Spacejumper0 +Spacing Outt +Spade-e Spadey Spag +SpagBolCol SpagHacked Spaget1111 Spagett Spajina Spalling +Spam Lite SpangeBerb Spangebob Spangl +Spangledbun Spanish +Spanish Dave +SpankFox +Spankies Lit Spanky +Spann Sparacino916 Sparc +Sparc Mac SpardaWallet Spare Spark +SparkRS Sparkles Sparklesbean +Sparky3433 +SparkyD5 Sparkyo +Sparre +Sparta2 +Spartac_us +Spartacus855 SpartanDrgon SpartanSheep SpartanSlick +Sparte Spartin028 Sparty Spasian +Spat Fastic +SpatialMagic +Spattu +Spaustin80 +Spauz Spaynce Spctwm +SpdrBiteJosh Speak Speakerbocks +SpearRue Speat +Speats +Spebi +Spec A Ho +Spec Master +SpecAgent713 Special SpecialBus SpecialGuest SpecialPVM Speciiik +Speckles SpectrlHeist Specz Speechwriter +Speed Colas +Speed Wobble SpeedPony44 +SpeedSouls +Speedalot ak Speedball1 Speede +Speedlund +Speedrun Speedster +Speedy Cd +Speedy Click +Speedy Rulzz Speedy9921 SpeedySpider Speeldoos +Speen Big Speeze SpejsonNM Spek +SpekKas Spektur Spellgoth Spenc +SpenceSuh +Spencee Spenceey Spencer +Spencer O Spencerr Spencerz Spend +Spendlove Spengineer Spennel +Spennel V2 +Spenno 1 +Spensaurus Sper Spermlet Spero Speshal +Speshl +Spesho Spettkaka1 +Spewis Spewler +Spewlie Spezza Sphere Sphinx +Sphinx66 Sphooner Spice +SpicelessJoe SpiceyBoy39 Spici +Spici Boi Spicy +Spicy Noods +Spicy Rahman SpicyMemeGod SpicyMoney SpicyPepe @@ -21588,41 +44744,71 @@ SpicyVitus Spide Spider Spider1357 +SpiderPhenom Spiderhead +Spiderpig Spidersnot8 Spiderw5 +Spiderz 3 SpideyC +Spidoo +Spiering +Spierpijn +Spigniv +Spike05 +SpikesterHC +Spillage +Spillingx Spin911 Spineweilder +Spinkle +Spinnenking Spinnenweb Spinolyp Spirit +Spirit Box +Spirit Cube +Spirit Owner +Spirit Rok +Spirit Sin Spiritcraft Spisek +Spit man SpitfireSR +Spitiz Spizazzy SpizzyMarz Splarf Splarn +Splash LT Splash-8 Splashattak +Splashcarrot Splasher +Splashes Splashley Splashworlds Splasion Splatter300 Spleaner +Splessp +Splezaa SpliceTFY6H Splidge SpliffMaster +Spliffore +Spliiffy Splinta +Splinterhand Splitarellie Splitfaction Sploof +Spluge Splyce Spo0n Spocuch Spodey +Spoice Spoilted Spoka Sponch @@ -21631,17 +44817,36 @@ Sponkz Spoodersussi Spoog Spookachtig +Spookadoodle Spookfish +SpookiBoogi9 +Spooky Beech +Spooky Ramen SpookyCarl SpookyMain Spookyou Spookytoot Spoon +Spoon Full +SpoonFedFred +SpoonFedii +SpoonMePlz +SpoonTracker Spoonay +Spooncera Spoondow Spooned +Spooned Simp +SpoonedBunni +SpoonedNormi +SpoonedWhen +Spoonfed BTW Spoonihomo +Spoonku +Spoonletics Spoonmannn +Spoons +Spoood Spoookems SpoopyDooToo SpoopyNooper @@ -21649,191 +44854,365 @@ Spoorwijk Spooxky Spop Sporer +Sport Leader +Sport425 +Sports Bike +Sportsnut911 Spotifee +Spotmaster 5 SpottedBass Spottednoble SpotterN Spottie SpowSaus +Spr1ditis SprLemonHaze Spraahz Sprattet SprayM0re +SpraynMantis SpreadButter +Spreader Spria Sprice Springer Springii +Sprinty +Spritbilist +Spro max +Sprog Legend +Sprogdor Sprooti Spruit Spry Spubb Spud +Spudalumps Spudge Spudinator Spuge +Spuhcific +Spuhgetti +Spuitopbruid Spunknik SpunkyLlama Spurted +SputtyBTW +Spyder Sin +Spydig Spyike270 +SpykeZim Spykes Spyriano Spyro +Spyro 3 Spyrooooooo Spytech44 +Sq Head Sqe3zy Sqeat Sqiit +Sqix +Sqoub +Sqreech +Sqrwl +Squab Cat Squabs +Squad of one Squadleader +Squaire Squall Squall44444 Squallicious +SquanUK +Squanch Rat Squanchhy Square +Square One Squarebodies +Squat Slav SquatCobbler SquatJogsBro SquatNation Squatting Squaw Squeakes_x +Squeaky Cow +Squeedly +Squeeeegs SqueegeeLord Squeeze +SquidNumber0 SquidSquad +SquidTofu Squidby Squiddle +Squidgling Squidie +Squidler +Squigiglius Squigs +Squigtime +Squinch +Squinch Alt +Squinton Squintts SquintyNinja +Squire Yaper Squirlruler +Squirly69 +Squirrel +Squirrel Pop SquirrelTM Squirreled8 +Squirrely W +Squirt2God +SquirtsAlot SquirtyHersh SquirtyMcD +SquishySir Squonking Sqwalle Sqwarka SqwezMyLemon +Sr Dipper Sr8d +SrBambino SrMick SrMuerte Sraracha +Srelek +Sri Srogi Wujek +Srs SrslyTired SryAFK +Sshscaptain Sshuggi05 +Sssnakepit +St Chrewin +St Liam +St Newman +St eve +St itch +St un +St0kStaartj3 St0ney St0oge St4bU +St4rCh11d +St8hunter +StBasilthGr8 StDecker +Sta Mama StaIemate StaJeOvo Staasi Stab3r +Stabalot +Stabobis Stacii100 Stackdude +Stackey Stackieks Stackin Dosh +StagBeer Stagden Stagmuss StagnantAlt Stagnation Stago +Stahlinski +Stain Master Stak +Stake Me StakeOrQuit +Stakebril Stakens Staker +StakerOhWait Stalactites Stale +Stale Chips +Stale Dough +StaleBagle Stalefloe Staley +Stalifax Stalk +Staller Stalline Stalphie Stamin +Stamina Pot +Stamkoz Stammer +Stampie Stams Stamuhnuh Stan StancedMK Standard +Stanimal Stanimal244 +Stanjuuh Stank +Stank Rat StankBreath +Stankfist Stanley Stanleye Stanlux Staparik +Staparik Lt Stapper6 Star +Star Doctor +Star Say 962 +Star Scourge +Star Spoon +Star zy StarDreamSam StarFell StarGlimmy StarKist +StarSnitcher Starboyyyyy +Starbuckss Starcharts +Starchild Starcry Starfallx +Starfight789 +Starfish +Starjoker8 +Stark Btw +Starlette Starlighte +Starmaker Starmemoria Staropramen Starr Starrlightss Starryfina Stars +Stars Hockey +Starshark +Start Game +Started Late StarvedLlama +Starvi Starwulf +Starzhine Stash +Stashes Stasik25 +Stasik77 Static +Static Peak +Staticshook Statoke StatsisZero Stattelsson Statuhs +Status Bar Statutory Statykk +Statzy +Staubach +Staunch +Staunch_BJD +Stax I Stay +Stay Breezy +Stay Frosty +Stay Hurt +Stay Hustlin +Stay Ready +Stay Salty +Stay Shady +Stay Sic +Stay West +Stay wise +StayFinessed StayPulls +StayPullsBTW +StayThirsty +StayinClassy StaysmallEZ +Ste Gerrard +Ste f SteSkillalt Steady +Steady Loot +Steady Mobn +SteadyFlexin SteadyetiBTW +Steak Ramen +SteakWitWiz +Steaked +StealCutOats +Steals +StealsThings Stealth +Stealth Ownz StealthChop Stealthcy Stealthi Stealthweed +Stealthwolf Stealy Stealy Boi Steam +SteamboatJim +Steamed H4ms +Steamfitting +Steammm +SteamyBuns SteamyCreams Steanox +Steb Stedy Steeam Steebert Steeermy +Steekkha Steel +Steel Gods +Steel Stud +Steel Tarkus +Steel VIK SteelRoxas +Steelbird16 +Steeleos +Steelpan Steen Steenkoe Steezed0ut Steezi Stef +Stef West Stefan StefanLivNo1 +Stefar Stefen Steff SteffenHax Stefo +Stego +Steiger Steikluet +Steinbeck Steinphite Stela +Stelisss Stellacea +Stellamara StellarLG StellarWhey Stellard +Stellas Dad +Stelli StembaWalker Stenfen Stengo @@ -21841,21 +45220,43 @@ Stenicki Stenny Stenuism Step +Step Barrow +Step mummy StepBroHung +StepBroImZuk +StepDabs +Stepbro +Stepbro Paul +Steph Browne +Steph a nee Stephan +Stephand Stephane Stephen9320 StephenMoore Stephenns StephhRS +Steppage Steppaz Steppenwulf +Stepy Stereofuzz Sterlander Sterlington Sterrenstof +Stervolz15 +Stetko +Steum Stev +Stev en Steve +Steve Beanie +Steve Tobs +Steve Tombs +Steve Zissou +Steve ffs +Steve is Pro +Steve07 Steve51 SteveAustin SteveChamp @@ -21864,38 +45265,66 @@ SteveMCOG SteveMerch SteveOwner09 SteveSnow15 +SteveStamos +SteveTheGimp SteveTheMuss Stevee Stevefr3nch Stevemck Stevenrds +Steves Blade Stevet7125 Stevey +Stevie ESQ Stevo +Stevo Lad Stevo29 Stevoguy +Stewge Stexie Stian +Stian Olsen Stian2 Stibby +Stickasaurus +Sticker Stickers Stickman +Stickman Zeb Stickman0011 Stickmeister SticksNbugs Sticky +Sticky Icky +Sticky Nut StickyBeardo +StickyShroom +Sticky_BIBLE +Sticky_Lip Stickypooman +Stickz Alt StierK +Stieren Lul +Stiffies Stiffish +Stifighter X +Stiflers mum +Stigel Stigiam +Stigmaster Stijco +Stijf Stefke Stijin StikSt0f +Stikjob Stil Still +StillANormie +StillCoughin +StillFap2ash StillFarmin StillNoBan +StillNoTBOW StillRemains Stillblazing Stillen @@ -21905,16 +45334,24 @@ Stiltz Stimu Stimulated Stin +Stindebinde StingWisher Stingy Stink +Stink Soep Stinka Stinker Stinks Stinkwiener Stinky +Stinky Adam +Stinky Wench StinkyFatBoy +Stinkyfeat1 +Stinkypooper Stinkywon +Stino33 +Stiorra Stipples StirG29 Stirner @@ -21922,118 +45359,222 @@ Stitcha Stiven117 Stixc Stiznai +StlthyPanda Stnmn Stnyzky StockMyRam +StockOlm +Stocker T +Stockphish +Stocksund Stocktone +Stockyard Stodie Stoel +Stoere Kip +Stoerebos11 +Stoern Stoffer Stoffins +Stoggy188 +Stoic Christ +Stoic Sloth +StoicGod Stoke +StokedMaggot Stolen +Stolen Ego Stolen Grunt Stolen Herbs Stoli +Stoli za Stolid Stolpz Stolte +Stoltzkin +StolzRS +StompaHhh +Stompadile +Stompea +Stomped +Ston3d Arrow Stone StoneDwarf StoneOkami Stoneator Stonebeech Stoned +Stoned Abra +Stoned Sober +StonedGSXR +StonedNormie StonedTTD +StonedTurtle Stonedtime +Stoneplus Stoner +Stoner Morty +Stoner Pov +StonerGod +StonerL0ve +Stonerling Stonesoul15 Stoneyvangel Stonkx +Stony 420 Stoobie Stoogaroni Stooley +Stoolz Stoonly Stoopy +Stoopy Scape +Stoovey Stop +Stop Acts +Stop Mules +Stop Now +Stop StepDad +StopCapping +StopDabs StopDontDoIt +StopStepSis Stopitjoe Storgie Stories Storkie Storm +Storm Monkey +StormFly +Stormlight +Stormmaker98 +Stormy RS Stormzy Storn42 Stortford Story +Story Arc +Story of Man Storybot StoryofPete Storys +Stothelayer Stouse +Stouty +Stovall_9 Stover +Stovete +Stowa Stowty Stox7k +Str Owner07 +Str Takes U Str0ng8ad Str8 +Str8 Maxed Str8backatya Strabz Stradarts +Stradinger Straf Strafe +Strafes +Straffen +Strafi n StraightSimp +Straighter +Straka Stralia +StralianBtw +StrangeChris +Stranger bud Stranger56 +Strangerz Stranges10 Strangler Strap Stratazz +Straton Stratty StratusQc Straubrey Strauss Strav Straven89 +StrawHatMatt +Strawbs +Strawhat01 Straya Strayday Straynaneeee +Streakin +Streammmmmmz +Streammz Streepken419 Street +Street Fever +StreetSweepa +Strefi Stregano Strelitzea StrenIron Strength +Strength Lvl Strengthy43 Strepski Stresset Stretch +Stretch 07 Stretchy Strickend +StrictNein Strictly Striddle +Strideless Strife Strijden Strijder Strikedown +Striker796 Striker8 +Striker8 0 Strikes Strikingvipr +String Benis StringsLogic +Strip Club x +Stripa +Stripgwyn +Stripred +Strive Strix Tactic +Stro Sr Strobax Strocks3 Strocules +Strohs StrokeMuh StrokeMyWand Strokemon StrokmyGroot Stroller StrollerBaby +Stroma Stromboli +Strong Chonk +Strong Left StrongKush Stronger +Strongman613 Strongrune +Strongsad Jr Strongtank11 +Stronkmoscle Stronku +Stroople +Stroppy +Strosity +Stroxers Strr Strubber Strudelis @@ -22044,47 +45585,82 @@ StrydarGrim Strykijzer Stryneguten2 Strytegy +Stu Pid +StuartLittle +Stubo Stud +StudMonster Studderd Student +Student t +Student tort +Study Hours +Stuffe Stuffed +Stuffed Hog Stuffmypanda +StufnDatMufn Stugey Stuggo +StuieShadez Stukatz Stuksken Stumbles +Stunflame +Stunlax +Stunnaz Stunts +StunuuR Stupendous +Stupid My +Stupid Swagg +Stupid444 StupidMagnet +StupidTrader Stupidcoin2 Stupsus +Sturdy Base +Sturdy Wrist +StureStork Stureplan Sturminator3 Stussy Stuxi +Stuzington StvnSmth +Stvx Stxrbursts Stye Style StylesP +Stylistx StyxHatred SuBRifleS SuNnY_AuStiN SuRviVoR SuaNorte Suadela +Suavity +Sub Ironman +Sub Taz +Sub3Marathon SubEntity Sub_Void Subaru +Subaru Bow Subarue Subarus Subatinijo SubiSpeed Subiaco +Subiaco Oval Subie +Subie_rex22 +Subigrl +Subkultured Sublanza Sublimation6 +Submerging Submug Subnautica Subnet @@ -22095,56 +45671,103 @@ SubtleAsnTrt Subtotal Suburu Subwaysurfer +Subwooferman Subwrx +Suc +SuccMyMilk Succeed Successful Succulent Such +Such Mlg Suchislifee Sucjk +Suck At Zuk +Suck my dig +SuckItBrandn SuckMyBot SuckMyDuels SuckTube Suckle +SucksTehSuck SucksToSuck +Sucuk Sudan7a7 +Sudas SudoBash SudoFox +Sudsy Mule +Sudz +Sue Lynder Suede Suedezor +Suemi +Suephoria Suffer Sufferance +Sufferi +Suffering +Suffi Sufflavus +Suffspector Sufwah SugaNoCoffee +Sugab Sugar +Sugar Leafs +Sugar Lily +Sugar STR +Sugar Shilo SugarDaddyNL SugarFr3 +SugarFre +Sugarbunny +Sugaree Sugarly Sugge +Sugma Newt Sugmabum +Sugru Suhado Suhec Suhgundees +SuhhP Suhk +Suhkmedaddy Sui29 +SuiSaii Suikerwafel Suing Suited +Suizy +Sujn +Suket +Sukit Trevek +Sukiti SukkerLyn Sukondikis Sukoru_VIII Sukotto-Sama Sukz +Sulcius +Suldan Serar Sulg Sulliusceps Sully +Sully Bear +Sult an Sultan +SultricMY Sulu34 +Sum +Sum 1 +Sum Tuum Sum41 +SumBeers Sumh Sumin Sumlettuce +Summ Summah Summer Summerson1 @@ -22152,8 +45775,16 @@ Summit Summit603 Summon Summond +Summoneering Sumper1 Sumuinen +SumwanSpeshl +Sun Devi1 +Sun Isukki +Sun Muijja +Sun Riser +Sun Rising +Sun Sioux SunBar SunG0han SunaLAD @@ -22161,34 +45792,84 @@ Sunbite Sunchester Sunda0wner1 Sunday +Sundo +Sundxy SundyWundy SunflowerMan +Sungravel +Sunguinesti +Sunine +Sunky Kong +Sunlust Sunni Sunny +Sunny Boy +Sunny Coast +Sunny Otso +Sunnyi +Sunoric +SunriseEagle +Sunrises +Suns in 2025 SunsShine Sunsa Sunscape6 +Sunset +Sunset Riot +Sunshadow Sunshine +SunshineBus +Sunskit Sunta Sunti Sunuwar Sunyikata +Sunzz Suola Suolane Suolitussari Suomen SuomiKP Suomiprkl +Sup Mike +Sup3r Ziko +SupAndSupply SupDutch Supa +Supa Saper +SupaHottFiya +SupaWarmFire +Supaidahman Supdude Supeerbusy Super +Super 16 +Super Bossy +Super Cinos +Super Cool +Super Duke +Super Fish +Super Fr3ak +Super Katze +Super Tails Super4 +SuperChunk3 +SuperFlow SuperHeroWiz +SuperJoy SuperJuicy +SuperKoi +SuperKriss +SuperMcFresh +SuperMiika +SuperMuffins SuperNJ +SuperNinja0 +SuperPPMan +SuperPochaco SuperScaper7 +SuperSem1 +SuperShane SuperShif SuperT0aster SuperTussu @@ -22198,351 +45879,759 @@ Superb Superbigblnt Superbusy Superdoer +Superdrol 50 Superfire444 +Superguaygix Superior Superjim111 Superjoden +Superkman12 Superkoi3000 Supernate91 Supernatti Supernova Supersam142 +Superstition Superstuffz +Superwarz96 +Superzu 0ne Supo +Suppertmain +Supple Flaps +Suppp Suppression Supra Supra2JZ SupraTurbo +Supragirl94 Supreeme Supreme +Supreme Iron +Supreme NYC SupremeDanz SupremeSpike SupremeTeam +SupremeWoody +Suprie Suprreme Supsep +Supultura +Suq Maddic +SurNtly +Sura Lust +Suraato +Surah An-Nas Suraii Sure SureDeth +Sureal Surfboarder Surg1n Surge SurgeHunter +Suricate Suris +Suriv Surkastunut +Surkee pelaa Surlygrump2 Surok Surrey Suruinen +Surullista +Susan Boyle Suse +Susej Dog Susell +Sushi Cult +Sushi Eater +Sushi Life +Sushi Water +SushiToyota Sushidame Susilapsi +Suspence Suspiria +Susser Tod Susurrous Sutdellen Sutho15 Sutty +Suur L6vi +Suvalkietis Suvorexant Suxe Suzakuin Suzn Suzshenron +Sv +Svampus SvartaOdhner Svartalvheim Sveden Sveitsi +Sveka Sven +Sven med D Svenpai Svenskafyren Sverd Svetta +Svikkipedia +Svinepels +Svisha +Svt500 +Svurt +SvvK +Sw0llenPlums Sw3Frost Swaars +Swabby Swabski Swacked Swadloon +Swaffeldomin Swag +Swag Ponu Swag420 Swagbopeep Swageroneus Swagex +Swagg Goat Swagger +Swagger Pkr +Swaggy Ballz SwaggyMaggee +Swagittarius +Swagohod +Swagomancer Swagslicer Swagturtle Swagunit Swahilson SwamiNate +SwammyHolds5 Swamp +Swamp Crotch +Swamp People Swampy +Swampy Sloth +SwampyAce Swan +SwangleSauce Swanheart Swanney +Swanni D Swanny Swapski Swarm243 Swarme +Swarme d Swarmyard Swatfighter7 Swatson Swaxel +Swe Flame +Swe Fred +Swe Jerry +Sweatiest Xp Sweatscaper Sweaty +Sweaty G0OCH +Sweaty King +Sweaty Nurse +SweatyBeard +SweatyBurger +SweatyMoobs +SweatyScrot SweatySockZz SweatySunday Sweden Swedgeville Swedish +Swedish Fika +Swedish Myth Swedushi Sweensicle +Sweepstakes Sweepyjoe +Sweeqy Sweet +Sweet Boyy +Sweet Dee +Sweet Es Mmm +Sweet Guy 94 +Sweet Pigeon +Sweet Potato +Sweet Vodka +SweetSugR SweetVan420 +Sweetchild0m Sweetermanz Swell Swer Swerve Swerve0311 SwerveJ +Swervy +Swerze Swift +Swift btw Swift738 SwiftCobra08 SwiftSteps Swiftamine +Swiftly546 Swiftmend Swiggitywall SwiggyMcSwig +Swiigs +Swiim Shady +Swiirl Swild0 Swilza Swimfatman +Swimmor908 Swimpa Swine Swingers +Swip3rR +SwipeMyCard Swirly Swirly248 Swishers SwissPigeon +Switch Dropz SwoIe +Swole Milk SwoleBadguy Swolerbear SwoleyGhost +Swolga +Swoli SwollSoul Swollbroham Swolverine Swoofii +Swootz Sword +SwordBoy110 +Swordcode205 Swordied Swordillo3 Swordlord524 Swordman1173 Swordmank Swordmast756 +Swordmother Swords +Sworzis +Swoule +Swown Swtbnd +Swtshrt +Swuido Swurl Swxv +Swyxia +Sxng +Sxrup Sxstyl Sxves +Sy Syaniide Sybe Sybke +Sybr Sycamore +Syche Sycily Syck Memes Sycrem Sycther Syed +Syfer +Syh Syjac Sykeaux Sykes +Sykes Xo +Sykes33 +Sykezer Syliith Sylist +Sylite Sylixx13 Sylosis Sylph Rings Sylth +Sylthrakis +Sylvaria +Sylvee Serum Sylveon700 Sylveonn Sylvian +Sylwia Symb Symba12 Symblic Sympathize Symphonicx Symtai +Syn-er-gy +SynGates07 SynTechRS Synacyde +Synaii Synced +Synchronizer +Synchronous Syncire Syncronia Syncshot Synd +SyndaXatrix Syndalen +Syndicete Syndok Syndra Syndrious Synepxd Synepxo +Synergy Sam Synesthesian Synfidel +Synister9090 +Synizta SynkNZ Synn Synnri +Synoz Synq Syntax +Synthy Syntipukki +Synyster +Sypanite Syphikins Syracusa Syrile Syrilius +Syringe Syrius Syrups Syrus +Syrus Virus +SyrusDaVirus +SysTeM 07 Sysf +Sysfea +Syssla System_Fail +Syte +Syvette +Syzgy +SzechuanJuan +Szenarien +Szethe +Sznd Sztarky +Sztr +Szyrup +Szyther +T 0 0 A S T +T 0 B +T 1 ta n i c +T A B S +T A R O +T Bagmotion +T C 3 +T C J +T D +T E L O +T H C +T H O R M +T IV +T McLeod +T Montana +T Nymphadora +T O M M M Y +T O N N l +T O N Y N Z +T OXI C +T P I E +T R A V +T R U 3 +T S M +T S O M +T Shadow T +T T E X X +T U B M A N +T U R K 96 +T U U M A +T W I S T Y +T W l C E +T a v e r +T alon +T aqn +T emby +T enrin +T h a w +T imboy +T imm +T omahawk +T otem +T otz +T r as h +T rigger +T ripwyre +T rist an +T u m p p i +T ubby +T ylor +T yrr +T-A nina +T-BONE STEAK T-Hugs +T-Lai +T-Rabb T-city +T0 BE FRANK +T00K3N +T00LB0X T00ManyCooks T0AD +T0KEN T0KK +T0M +T0M ATO +T0RB3N +T0RlN T0bbbE +T0ber +T0fi T0ilah +T0lne T0mbak +T0mz +T0oth T0othbrush T0ry +T0tally lll T0vergasje +T1gBits +T1m +T1mmaayy +T2NK T3KT0N +T3T +T3URASTAJA46 T3mu T3vas +T4TE +T4a +T7 +T70TYE T7mon +T8OW +TA Greenie +TA xBravo TAA66 TAARA +TABS1E +TANK ED TANKTOPTIGER TANRfromHS +TARFUII +TARV05 +TATERT1TS04 TB12 +TB3N +TBA Ness +TBA Poppi +TBAC TBNinja TBOW +TBSE Stupid TBSG-Baine TBonFirstCoX TBoneZzzz TBoyd4138 +TC NeverLift TCHAMl TDPred TDRS TDie +TDog +TE Omni +TE-toimisto +TEAMFORTDUDE +TEATMCBRIEF +TEAxBAGGER +TEBA +TEDDl +TEEMUXXD TERMlNATE +TERRORHYPE +TESTOKEIJU +TFS TFreeze +TGCONCEPTION TGDekuTree +TGI Vendredi TGOBS +TGSH TGSpaghettiM +TH0MAS TH0MM0 +TH0TDETECT0R +TH5 +THA CHR0NIC THANIT0 +THANKS D0C THATSCARCASM +THAl LADYB0Y +THC BOOSTED +THC and EXP THCGods +THCiron +THE CH1N0 +THE JEDl +THE MOOR +THE MUUMI +THE TOSH THEHAZE THEIKOS THEST0RM +THEchronic 8 THICC +THICC UIM +THICCCBWANA +THIIIIITH THRALLGOBRRR +THT THUMBTHUCKER TIIIIIIK +TIM BEREN TIMBO TIOTEEE +TITr fishy +TJ UCF TJay +TKO Rage +TKOsh TKfromNC TLT5 TLTBT +TM Riddle +TM8 +TNA INUS +TNDSH +TNF +TNT Stealth TN_Biscuits +TOA Main +TOA Rebuild +TOA3 TOASTA +TOB Inc TOBplank +TOHIGH2FLY TOLIPTSET +TOM RlDDLE TOMMMY +TOMMYSHELBEY TOMMonyzzz +TONNI re mix +TOOlateN0B +TOR0 +TORVA BTW +TPD-Vladik TPGG +TR Ugur +TR0UT CURS0R TR0X +TR3N ABUS3R TR75 +TR9 +TRABZ10 +TRAJANO RD +TRAPH0UZE +TRAPorGTFO +TRAVllS +TRCSup TRESTOLONE TRI0DE TRIPPlE TRUMP +TRUMPbtw +TRUTH OF JFK +TRXeatsRAPTR TRYNAHANGWU +TSA +TSI TSMCharizard TSMsOAZ +TSR Mishiah +TST TSWRX +TSwiftSucks +TT17 TTBtw +TTT TTTSpiceTTT TTTTT TTVCardyUK TTVPandaBear +TTommynator +TTurret +TTyrannical +TULK4S +TURBOPEN59 TURDENATOR TURK +TURKISH HERO TURM0IL22 TVAnime +TWISTED T TWITTERSUPP +TWL +TWO000 +TWlNKE +TX Bonefrog +TX-15 +TXR3 +TYC Beatrice TYCANN TYEY +TYL0RD +TYTYTYYYTTYT +TZTOKHUGEKOK +T_ShelbyLtd T_Swishh +T_apka +Ta C oS +Ta ks +Ta1ntzilla Ta2kaz +Ta7e +Taakxic +Taargus Taathum Taavik6iv +Taavit Tabagie TabascoGrind Tabbed Tabbscoot +Tabby Cat4 +TabbyCat97 Taberknackle Tabesco +Tabiun +TableLamp +Taboo Tim +Tac +Tach +Tachr Tachycardy +TackTick Tacklebox Taco +Taco Bit +Taco Krydder +Taco Log +Taco Paws +TacoCat +TacoKittenz +TacoTimma TacoWithGuac +Tacos Pump Tacotueaday Tactic TacticNoodle Tactical-RSP Tactics +Tactics Ogre Taders +Tadz Taekwon-Do +Taekwondoo +Taelium Taelos +Tafboy Taffarell +Tafff +Tag 7 Tagei Taggeman Tagi +Tagz Tahdeton +Tahdonvoima +Tahfi +Tahimik +Tahm83 +Tahuna Beach +Tahx +Tai +Tai Mai Shuu Taikajim Taikanz Taikapoika +Tail Gory +Tail Raiser Tailight Tails Tailsnake Tainoo1 Taint +TaintFondler +Taintedhappy +Taintehds Tairoun Taiwan Taiyi2 Taizur +Taj Mahballz +Takalaaaa Takaloo Take +Take My Sp3c +TakeARedPill TakeNaps TakeUhSeat Takea12 +Takedown Jr Takeitilslay Takens +Takeout24 Taker Takfil Takimoto +TakingADab Takis Takji +Takobocchi +Taks Taky Talal +Talaxim Talcron +Taleah +TalenteDK Tali Talia Talito Talk +Talkamar TT +TalkingMoose +Tall Greg +Tall Vince TallChair TallPaul24 Talla +Talla Keyali Tallented TallerKiwi Tallink @@ -22551,57 +46640,104 @@ Tally Taloroar101 Talos Talppa +Talrith +Taltt4 Talu Talvedon +Talviel Taly +Talzn +Tam Ranch +Tam The Bae +Tam k0nijn +Tamacti Tamadra Tamaki Tamale +Tamara +Tamaraa +Tamayura Tamber +Tamberi Tame Tamerr +Tamis Tamjam Tamlin Tammii Tamminga +Tammy TampaTHC +Tampered +Tan Toad +TanDumb Tanatos +Tandanus Tanden +Tanduay Rum +Taneesha +Tang Eater Tangar +Tangela +Tangelo T TangerineFly +Tangibility Tangle +Tangle Root +TangleEllis +Tangleboot Tangledroot Tango +Tangshan Tangzu +Tanie +Tanime +Tanis513 +Tanjiro Tank +Tank VS Bear TankMageJon TankProphecy Tankarino Tanked TankedAgain Tanker +Tanker 685 Tanker773 +Tankerton +Tankkimies Tankky +Tanknique69 Tankster360 Tankytank +Tanna Tannnk Tanny Tanoak +Tanoak alt TanqueRamos +TantusV Tantza +Tanuliina Tanz +Tanz Mutagen +TanzFang Tanza Tanzagen TanzerReborn Tanzoo Tanzu Taozi +Tapanui Tapas Tapdaddy Tape Tapir +Tapir Squad Tapirslayer6 Taplop +Taplu +TapoinItteni Tapu Taqi Taradrial @@ -22610,122 +46746,262 @@ Tardysoap Tarezed Taringa Tarki +Tarkista Hv Tarlach Tarns Taro +Taro Buns TaronRS +Taroshik69 +Tarouco Tarpon Tarroo TarzanNinja Tarzzan Tasarorm +Tascar +Tase T Tashee Tashkas 007 TaskMan +Tasset Man Tassoth Tassy +TastefulNote Tasty +Tasty Burger +Tasty Nan TastyBoiMilk TastyKnight TastyToilet Tata Tataa Tatanchis +Tatankaa Tatapie Tatepon Tater +Tatertots Tatimary Tato +Tatorz Tattoo +TattrTots Tatuu +Tau Lord45 +Tau Neutrino +Tau Tau Taucher +TaunkChicken +Tauno Taunos Taurideum Tauros Taut Tautvif Tava +Tava Monster +Tavern slut +Tavernic Tavi Tawa Tawakoni Tawer +Tawhid Tawny +Tax Audit +Tax Wax +Tax Wizard +Taxing +Tay Lore Tay3rell TayMoney Tayleth Taylor Taylor672 TaylorMarcus +Taylort07 Tayluh +Taynq +Tayri Tays +Tayunu Taz762009 +Tazmina90 +Tazner +Tazplan Tazy420 +Tazz2006 +Tazzin +TazzoTezz +Tb knakworst +Tbix +Tbk Tbone5876 Tbow +Tbow Joe +Tbow Todd +TbowCourtois Tbrs6 +Tchambz +TdTapsa +Tdblindmonke Tddun +Tdmiro Tdogg31 Tdurocher +Te +Te Awa +Te x a s +Te zzz TeBroHimself TeCurt TeJay TeMuD +TeQuiL A +Tea Farmer +Tea Witch +Tea n Milk +Tea on Wayne +TeaIe +TeaMerchant +Teaandliquor Teabz Teachan +Teadribble69 +Teafuse Teagan TeagueDaBoss +Teal AV Tealer Team +Team Chubby +Team Flow +Team Rocket +TeamCleaned +TeamJono TeamSoloMid +TeamVaChimpy Teamwork +Teand Tears +Tears of Avo +TearsOfWeezy +Teazor Tebal1 Tebowowns +Tebus +Tec-Grind-95 +Tecc Legacy Tecco +TechCo +TechColor TechContraps +TechFreakTwo +TechOnMaxed +Techart TechiePicker Techmenjoe +Technician Techno177 Techno9 +Techo +Techtonique +Teckczar Teckerz Teckie16 +Tector OSRS +Ted Beneke +Ted Striker +TedRS +Teddii Bear Teddy +Teddy Brum +Teddybareman TeddysMoo +Tedication Tedsticles +Tedua +Tedzudo +TeeBee +TeeBee11 TeeSchaf +TeeTee1772 +Teebo 727 Teegious +Teegzie +Teekiz Teemu +Teemu126 +Teemuz +Teena +Teenagers Teenyduck +Teequoze Teeqy Teeray Teetoh +Tefak Teff +Tefilah TeflonCancer +TeflonJavon TegridyF4rmz +Tegriidy Teh Only God +Teh W H I P +Teh Yumm +TehBigNub TehBriBri +TehKillaaa +TehPum TehShowerMan +Tehebow Tehh +Teigur Teittinen +Teivanna Teixo Tejmaster +Tekannan +Teke Toucher +Tekkenfury Tekkies +Tekkies nub Tekknow Tekkuza Teknoid Tekoflex +Tekryael +TekstPlekshT Teksti-TV666 +Tektiny +Tektom Tektonio Tektons TektonsTaint +Tektos +Tel3 Telboy Teledogs Telee +Teleport 125 +Teleportoise TelesBehindU +Telesh69 +Tellum Telluric +Telope +TemBROross +Temdom Temeria +Temmer +Temmie TempVVS +Tempal2 Tempest +Tempesta1 +Tempick Templaris Temple Templooit @@ -22734,177 +47010,477 @@ Tempoctrl Temponazz TemporaryBls Temppuliina +TempstRimuru Tempthric Tempz +Ten Letters TenOnTheFlop TenPieceNug +TenPly Bud Tenacious +Tender Nuts Tenderrrrr Tendinosis TendoTheTux +Tendulkun +Tenebri TenebrisMeam +Tenenwasser Tenereus Tenga Tenh1s Tenhou Tennis +Tennis Socks TennisLad +Tennnessee +Tennu Tennysee Tenorman Tenraikash1 +TenryuuKaiNi +Tensilean Tensor +Tensor Trace +Tentacle +Tentpolepie Tenya Teotl +Tep3lstreel Tepeksi +Tepezki +Teplan +Tepoa Tepponen Teqila Teqq TeraLokien +TeraVit Teras Terbleg Terial117 Tering +Tering Tiete Term Termite Termiz TermnaLcpL Termoil Tero +TerpWrangler Terpedout +Terpily +Terppa1775 TerpySlurpy TerraToffey +TerraTony TerresFatum +Terrible Edd +Terro Terror +Terror Earth +TerrorJaxx Terrorise Terroristi Terry +Terry Munro +Terry61RS Terrybear Terva Tes Iron Tesaticles +Tesco Teserve +Tesla bot TeslaDiva +TeslaHero +Tesni +Tessei Tesseria +Tessies Bits Test +Test Dummy +Test Strip TestStrip Testate TesticularCa +Testikeln +Testoepa +Testsubject TetYun +Tete3 0 Tetragrams +Tetrah Blue Tetsu +Tetsu Nurtaw +Tetsu Steel Tetsu2 Tetsunohigan Tettekop +Tettezotteke Teurastamo Teus Teus777 Tev0 +Tevreden Tewocp +Tewty Tewwer +Tex Zen TexanzOS Texas +Texas Hou +TexasAggie TexasPlayer +Texasholdems +Texastea2 Texman Text Texx Teyrill +Teyzr +Tezyn Tflo +Tfue Tfulkyou +TgMofo +Th Abigor +Th0m +Th3 K1ng P1n +Th3 Wolf Th3IronMan Th3KiNG +Th3KiNG_Paul +Th3Tool +Th3Villager +Th3_DoN Th3uns +ThAngelSlayr ThEDievolved +ThSheerman +Tha Bser +Tha Crazy L +Tha Decided ThaDankantor ThaDragonSM +ThaGiz ThaLawl +ThaNewArcher +ThaRealRambo ThaStepBro ThaaMunchies +ThaaOne Thaerokem Thai +Thai Girl +Thai ler Thaichili Thalarios ThaliN1 Thamasta47 Thameslink ThanaWee +ThanatosRise Thangkang Thanked Thanks +Thanks Jeans +Thanks4Pet +Thankz Mom +Thano +Thanos btw ThanosIsLife Tharendel Tharic +Tharin +Tharok +Tharrogant +Thasos That +That Noob +That RNG ThatBoiii ThatBoyBurly +ThatDamAss ThatFishhGuy +ThatGuyGoob ThatGuyJordy +ThatLipGrip ThatLuck +ThatManBez ThatOldskool +ThatOlmlet +ThatOneAsian ThatSandNoob ThatSickBoi +Thatonesock Thats +Thats Gang +Thats Not PC +Thats Thicc ThatsNotRite +Thaumat +Thaurison Thav022 +Thawk410 +The 0ld Nite +The 0xymoron +The 1 liquid +The 11th +The 2nd GIM +The 3rd Main +The 90s +The Actuary +The Aegis +The Aod +The Apina +The Atreus +The BPO +The Baad Man +The Big Chum +The Bleez +The Blue Owl +The Blyat +The Bonk +The Booger +The Boys +The Brawler +The Broskie +The Bubbsy +The Buffalo +The Cage +The Catowl +The Champy +The Chopper +The Cleaned +The Cleaning +The Coffin +The Comeup The Crogamer +The Crows +The Dabbler +The Danny +The Dark +The Dark165 +The Data Guy +The Debated +The Decided +The Deli +The Diamond +The Dink +The Dipshit +The Dothraki +The DrNick +The Dragona +The Dre +The DripLord +The Duffman +The DwOrfe +The Echo +The Eco +The Effected +The Em8 +The End +The Engine +The Ex Zerkr +The Expanse +The Fat Toad +The Fe Woman +The Fig +The Fisher +The Fugitive +The Gas Tank +The Ginga +The Giznooch +The Grouch +The Grower +The Guppy +The HRE +The Half Man +The Harambae +The Havok +The Hibbs +The Hivemind The Hobo +The Hoffner +The Hundred +The Hunter +The I Am +The Iron Cpt The Iron Era +The Is0lated +The Jedi Way +The King 023 +The Kiwi +The Labfreak +The Lager +The Last Act +The Latvian +The Law 98 +The Locust +The Logger +The Long Day +The Lope +The Lord Ra +The Lovers +The Lurifax +The MCG +The Magic +The Maiden +The Marco +The Maskara +The Matth +The Mediator +The Midlands +The Mks +The Mouldy +The Mr Spec +The Murder21 +The Muscles +The Nexian +The Nicollai +The Noob +The OSU +The Office +The Old Fonz +The Old Kite +The Old Mike +The Omun +The Onceler +The Only Sin +The OnlyPyro +The Paladin +The Peak Pro +The Pet Farm +The Playoffs +The Pocket +The Proline +The Prophet +The Ptolemy +The Pwnes +The Qwinner +The Real Cat +The Sabre5 +The Sarge +The Schnopps +The Sea Bee +The Seahawks +The Serval +The Shy Guy +The Shy Oni +The Sly Fox +The Snail34 +The Snapback +The Steele +The Steward +The Stranger +The Surveyor +The Tardis +The Thanator +The Tils +The Tiny Dog +The Trap +The Triple T +The Use +The Victory +The W0rst +The Wael +The Warp +The Wraith +The Wupp +The keho +The thin 1ce +The-Wind-Up The0G The1 +The1_2watch +The1stmage +The3dge The3rdOlive +The3rdTrike The888 TheAdzz TheAirIsDead TheAlbatross TheAllSorts TheApe +TheArcheType +TheArchthief +TheAsic TheAssailant +TheAusSpade TheAvenger56 TheAvgJon TheAzimuth TheBandit777 TheBassIsRaw +TheBazaBrown TheBean TheBearJ3w +TheBeltMan TheBezal TheBidness +TheBigShield TheBigZofNYC +TheBlackest TheBlindy +TheBlueShore +TheBlueWrath TheBoltzy TheBoomfire TheBopp10 TheBotReaper TheBowJob +TheBrain +TheBranFlake TheBrundone TheBudWiser +TheC0W +TheCanada TheCapist +TheCarrotMan TheCaseAce TheCheezywiz +TheChosnOnes TheCokeFiend TheCollected TheCondemned TheCorrupt TheCuckening +TheCzarnian TheDaedalus TheDalek TheDampBush +TheDangs TheDankShow TheDawg +TheDayWalker TheDayman TheDeadMann +TheDeadTeam TheDeen TheDisgusten TheDog +TheDoubee TheDreamKing TheDrips +TheDry TheDuckChris +TheDuckDaddy TheDucksNut TheDuud TheDyr61 +TheEricShaun TheEstonian +TheEvaElfie TheEvlManRay +TheExtracted +TheF0rg0ten9 TheF1ash TheFabDabber +TheFallen1x TheFeOdyssey +TheFeres TheFizzCC TheFlammers TheFlopyTaco @@ -22916,51 +47492,78 @@ TheFunkyHomo TheFunnyLove TheFuzzball TheGaGee +TheGaryy TheGiggleMan TheGlawce +TheGodFathxr TheGodGuthix TheGodfather +TheGoodLife TheGoonie TheGordinfla +TheGoryGlory TheGr8Jimbo TheGrainGoat TheGreat +TheGreat One TheGreatThor TheGreenBowl TheGugguru +TheGurrag +TheHabduL TheHackedOne +TheHapa TheHartstopr TheHerbSack +TheHuffDaddy +TheHugLife TheHungOne TheHungRoid +TheHydra69 TheInilator +TheIronBarra +TheIronBoy TheIronDolan +TheIronHoser +TheIronMouse TheIronTwist TheIronVault TheIronZoid TheIsamaru +TheJele TheJosephe +TheKappaCorn TheKhun TheKid TheKillerB TheKnight TheKnightman TheKolector +TheKop +TheLaggyDad TheLampKing +TheLastTheef +TheLaxBrah TheLazyNinja TheLewhole TheLionn TheMaadKing TheMachine39 TheMadWolf +TheMainZeus TheMamba TheManInBush +TheManJordo TheManatee +TheMaskie TheMavrick TheMaxPvMer TheMayne +TheMetaNow TheMikkel +TheMorloc8 TheMuel +TheMuffin8or TheMursk TheNegative TheNerve @@ -22968,47 +47571,80 @@ TheNewLue220 TheNewMonkey TheNexu TheNinjaH0b0 +TheNoPurp +TheNooby +TheOG Logo TheOGGrimm +TheOGslacker +TheOSRSWiki +TheOllieBoi TheOlmlet +TheOne772 TheOneMatrix TheOperative ThePTWY +ThePaceAce ThePardos +ThePariah +ThePerfect G +ThePolak +ThePraetors ThePrenti +ThePrestiege +ThePrideS1n TheProfess0r TheProvider ThePureRingR TheRanger +TheRealBean TheRealBew TheRealDest TheRealIdean TheRealKanye +TheRealKush +TheRealKyle TheRealKyle9 TheRealMidus TheRealShway TheRedNas +TheRedRaider TheRevRip +TheRewriter +TheRobin129 TheRoulette TheRsBug TheSaggyOne +TheSaltyYew +TheSandFoxx TheShadyMile TheShyFn TheSimpSonny TheSinner TheSkippyBoy +TheSlim1 +TheSneakyOne TheSoggyOne +TheSoloHades +TheSpaceSaus TheStonedElf +TheSwumpMan +TheTKsmith TheTankProd TheTerug +TheTimeLord TheTinPeach +TheToyMaster TheTree7 +TheTrue Goku TheTrueNorth +TheTrueOOGA TheTrueSatan TheTruthOnly TheUnbeloved TheUndified TheUnluckyIM TheValuable +TheVerve TheVeryBest TheVnom TheVoodoo2 @@ -23016,313 +47652,603 @@ TheW1tcher TheWerebear TheWetDuck TheWhlteWolf +TheWiseLoner TheWitcherr TheWizaad TheWrongName +TheYahtzee TheYak +TheYimYim TheYugo TheZoracks TheZurvan The_Dave666 The_Dunster +The_Eoline The_Hillboy The_Jimmy +The_Krang +The_Man146 +The_Sturg The_Zob +Thea1a Theatres Thebano +Thebig76 Thecascade +TheclawMVP Theconn Thedriesj11 +Thedyolf +Thee Khed TheeMohican TheeSkill +Theel Theem Theeweaver Theez +Theezak Thefunto Theguymann Thejessman1 ThelAvent +Thelastmane +Thelegend4uk +Thelmacat342 Thelvereas ThemanwhoisB Themenchman Thengalin Theoatrix +Theodensa +Theodora605 Theohhhh Theoklitos Theoneburger Theophobia +Theorized +Theory Theoryist +Thepawgchamp Thepiefour +Theracords +Theralion +TherapyGroup +Theravasa ThereTheyre Therealhook Therens1 +Therer Thermynator Theruler333 Thery Thesaurusus +These +Thesonicking +Thespok Theunfrgiven Thew Thewoodle They TheyTukMyJob +TheyXciteMe +Theynika +Thgll Thibaut Thibi +Thic Glizzy ThicBudget +ThicCreature ThicKoontang Thicc +Thicc Aku +Thicc Budget +Thicc Fil A +Thicc Flair +Thicc Momma ThiccBird91 +ThiccCowboys ThiccDaddyXL ThiccDonut +ThiccQueen ThiccSkips ThiccZwans Thiccapedia Thick +Thick Cut +Thick Nick +Thick Red +Thick nun Thick2g Thick4Head +ThickGlute +ThickIronBum +ThickMike ThickSenpai ThickSpak +Thickenei Thickest Thickkmommy Thics +Thiery Thies Thiesen +Thievette ThievinKills ThievingL +Thievs Thigh Thighhighs ThiiComplex +Thiibaut Thillam +ThinBlueL1ne ThinPeepoSad ThinkB4Hit Thinkoclet +Thinxo Third +Third-ages +ThirdAge ThirdAgeBoss ThirdEye Thirdborn +Thirsty 4PvM +Thirtys This +This Gimp +This Leo +This Schmuck ThisAint +ThisAint-Wow ThisAintSkil +ThisGuySkip ThisPieIsDry Thisious +Thissa Thlrd Thoakline +Thocasu Thogdad +Thogidar +Thohon Thom Thomarse Thomas +Thomas Juice ThomasticIM +Thomastic_1 +Thombstone +ThomiusTeGr8 Thommetje +Thommyy Thonack Thonq Thoomin Thor Thoradin +Thoraldd ThoraxPurple Thordej +Thorgal +Thorgoth1 Thorkar96 +Thorn Thornet Thornnforge +ThorntonM Thorvesta +Thot Jadiels Thotalopolis Thoth +Thotmince48 Thotscape +Thoughting +Thoughtseize Thounde Thoupeppi Thrasmion +Thrax OS +Three Twelve ThreeOneNine +Threemars +Threesunders +Threkeld Threno ThreshDaOg Thrihyrne Thrilbo +Thrilerrr Thrillhousee +Thrisel Thrivaldi Thrlll Throat +ThrobGodTod Throbba Throbbing Thrombi +Thromur +Throupled +ThrownFury +Throxx Thru +Thru ur poo ThruDaStorm Thrust Thrustaxe1 Thueh Thug +Thug bone4 Thugbug808 Thugg +Thugge ThugsBunny +Thugsbunny73 Thulean Thumb ThumbBwana +Thumper +Thunadaja +ThundaBear ThundaJunk +Thundac Thundahcatz4 Thunder Dog Thunder Gate +Thunder Nerd +Thunder Zeus ThunderBirdz ThunderRolts +Thunderbo1tz Thundercat Thunderite +Thunderoxgod Thunderpb28 +Thunderst0rm +Thundito +Thur go Thurbs Thurison Thusly Thutmose +Thuvian Thuzd Thve1ivan +Thwart +Thy Odama +Thy Victory ThyIronGiant +ThyLegend ThyVonR +Thybo Thyclops Thyhead +Thyming +Thyreus +Thys Thysa Thyymabotnus +Ti Blade TiXN +Tia Tiaan Tiaeuth +Tiafoe +TiagoM Tiak +Tian Guo +Tianzi Tiazen +Tibadis Tibador +Tibaul +Tibbsyy +Tiberium SvK +Tiboot +Tic Fart +TicImperfect TicTacSensei Ticano Tice300 Ticina Tick +Tick Behind +Tick Ma Nip +Tick Manips TickAteUrMom TickTickRun Tickable +TicketGoblin Tickets +Tickflow +TicklMySickl TickleBerry +TicklesIM Tickmark Ticks +Ticks missed Tict Tictacdingus +Tid Eez Tidders Tiddy +Tiddy Winks TiddyLactate Tidev Tidy Tiedemanns +Tiedustelija +Tiegra Tielemans Tier +Tier 05 Tierney +Tierra Bella +Tiesto +TifaL123 Tiffs Tiftanlar +Tig Bittty TigTheWelder +Tigas TT Tiger +Tiger Tea +Tiger Trap +TigerYouDied +Tigerheart07 Tigerheart09 Tigerlady Tigerlady203 Tigerr Tigersrule23 Tigerwolf +TiggoGnomes +Tiggrat +Tighe Tight +Tight Helmet +TightSpace42 +Tigor +TigreRosso Tigrio +Tigy +Tiiimon +Tiimari Tiistai Tiistia +Tiit Hepa Tiivo Tijmen Tijn040 Tijs Tijskid Tijuude +Tiki Haha TikiTyrant Tikk1s +Tikka +Tikkix Tikru Tiktok +Tikwah +Tila Tilburg +Tild0 +Tilfreds +Tilidin +Till Bored Tillah +TillerPloww Tillykke Tilted +Tilted I Am +TiltedGoblin +TiltedIM Tilur +Tim Pedwar +Tim Puri +Tim The Jedi +Tim bo Slice +Tim-O-thy +TimShutDown TimSkilling +TimTheLegend +Timaaaay +Timaaay +TimbaWimba Timbeettius Timber +Timbertail Timbito Timboball +Timbuktu25 +Timbulz Time +Time For Me +Time Leap +Time Voyager Time2Lose1 TimeFlies +TimeIsStrnge TimeLion TimeMuffins +TimeSink2000 +TimeSpan TimeZebra +TimedxBeast Timespacing Timetokill19 Timew8ster Timex +Timex 07 Timka Timkempp Timm Timmay111865 Timmeh Timmies +Timmuuhh Timmy +Timmy Jim +Timmy Tbow +Timmy Tiime TimmysCoffee TimnI2 +Timonkey Timos TimosTime +Timotej Timsey +Timzee +TinFoil Joe TinHongetech +Tincoinco Tincup +Tindatinn Tindell23 +Tinder lvl 1 TinderMatch Tine Tinfawn TinfoiledHat Tinfoilhat +TingSumWong TingleTingle +TingleUwU Tingot +Tingsha Tink Tink200345 +Tinkelsia +Tinmanone +TinnMan +Tinnitus Tinsmith +Tinted Rock Tintti218 +Tinuvial +Tinvicuna Tiny Tiny Bagel +Tiny Buddha +Tiny Bun +Tiny Dck +Tiny Feet +Tiny Lego +Tiny Secrets +Tiny Teemo +Tiny Triceps TinyFnRick +TinyIronDong TinyLebowski +TinyLes +TinyTaro TinyToasters TinymafaRick Tinypns +Tinytiger17 Tinzo +Tip Zee +Tip of Dik TipTheTank +TipeF Tipeeee Tipit +Tipoz Tipper +Tippin_toes +Tips Iron +Tips Touched +Tipsy PvMer TipsyBeard +TiptopSundae Tipu Tiqu +Tiques TiramisuTart +Tire Slayer Tired +Tired Hero +Tired of IRL TiredPidgeon +Tirex Tiring TirmenaT TironTula Tironade +Tirpz +Tirsonek Tisalia Tisch +Tism Tanner +Tit Bow TitMcghee TitPoker Titan +Titan Luke TitaniteSlab +Titanium Mag +Titas P TitePoire Title +Title Fight Titsferdayz Tittsnbiches +Tittyboi5 Titus +Titus Furius +Tivaaa Tivinter +Tizra +Tizzcdn +Tj Russo +Tj Watt +Tj0epert +Tjaa Tjabalabaaa +Tjalo Tjar Tjarie +Tjarles Tjbakel +Tjf12 +Tjob TjockaBengt +Tjs109 Tjuv Tkit Tksquad Tktn +TlCK LOST +TlLLER +TlLT +TlME 2 QUlT +TlNUS +TlTANlC Tliltocatl TmSmT Tman Tmarvy +Tmilllz +Tmm +Tmmm Tmoe Tmoe123 +Tmoneyyyy123 +Tmppa +Tmtiger16 +Tnt Harder +To Ashes +To Be Sure +ToAPlanker +ToBeAgile +ToLoNi +ToMyTailFin +ToNFisKrs07 ToTheRanch +Toad Pond +ToadKar TV Toas20 Toast ToastBTW @@ -23335,125 +48261,239 @@ Toasterly Toastie Toasty Toat +Tob Braidy +Tob Carvery +Tob Marley +TobOnMyCox +TobSpoon69 +Tobak +Tobbeloba Tobias TobiasFate +Tobiasz Toboogan3 Tobser Toby +Toby Raz3 +Toby1889 TobyMcCrier +TobyRax +TodWhispers +Todays N00B Toddlet Toddo25 +Todt Thot +Toe Biden +Toe Crocs +Toe Moss +ToeRag +Toedeloe Toedels +Toeh5 Toek +Toekie +Toeristje +Toermalijn +Toes B4 Bros Toets Toews Toffenboi Toffer_99 +Toffffu +Toffoli Tofs4pk +Tofthagen Tofu +Tofu Python +Tog +Toge6343 +Togepi +Togica +Togo Mouri +Tohni Tohveli Toilet +Toilet Humor ToiletBowlbb +Toiletpaper9 Toimin +Toiney Toinzy Toivo_43 Tojosodope +Tok in +Tok-xik-Hex TokHaar Tokah Toke +TokeSevere Tokedaddy Toker11 Tokin +Tokin Ranarr Tokin99 TokkHaar Tokkie01 +Tokonu +Tokoya Tokoya11 +Toktz-ma-cox Tokyo +Tokyo Ghost +Tokyo Prose +Toldasor +Tolhuis ToljaSo +Tolo Ar Nin +Tolweg +Tom Adamo +Tom Cx +Tom Decoene Tom Fn Brady +Tom Is Huge +Tom Shanks +Tom T +Tom Vercetti +Tom Waited +Tom btw +Tom from 561 +Tom is Sharp +Tom o_0 +Tom vs Log Tom9 TomAce +TomFlinn7 TomHilRigour TomMazilian TomMerrilin TomOfTheWest TomTehCat Toma +TomaMvp +Tomaatti169 Tomarti Tomastor TomatoAndEgg +TomatoFarm19 TomatoTom9 Tomazon +Tomb +TombLooter +Tomba Tombalo Tombat Tombazv2 Tombea09 +Tombing Tomdabom +Tomdoc14 +Tome TomehhG TomiL Tomiee Tomik85 +Tomlyn Tomm TommieSalami +Tommm Tommmo Tommy +Tommy 901 +Tommy J C Tommy2Tick TommyGunn204 TommyJay TommyTalapia Tommyhawk Tommyyy +Tomn Tomo Tomori Tomorrowlxnd Tompi +Tompp1 Tompsi Toms +Toms PvM Tomsdk Tomson177 Tomtastrophe Tomtom032 Tomukas +Tomvdh Tomxi +TomzodoubleO +Tond3 TondeK18 Tone +Toneez Tonester03 Tonfa Tong Tongo +Tongue Baths Toni Tonicto +Tonk A Wiz Tonka742 +Tonkade TonkatsuLife +TonkerEx Tonnie Tony +Tony D +Tony Gwynn +Tony P +Tony Soap +Tony Soprano +Tony Tuna Tony23 TonyCaawk Tonyde Tonydidles Tonyhood Tonzaww +Too Original TooBasic TooBigDad +TooManyCooks +TooManyKinks TooMuchIan +TooMuchSauce TooMuchTuna TooReal TooShredded +TooWhite4You Toobias +ToogaTank Tooheys Tookkul +TookyDaWooky +Tool Toolbox +Tools1977 ToomBooii Toomas +Toomi Toonic Tooodley Tooomo Tooq +Tooqan Toortles Toostie Tooterz +ToothhurtyPM Tooves +Top Gear +Top Glock Top Milk +Top Monents +Top Mong +Top Trends +Top V1 +Top Vestain +Top10 Top5Worst TopGlitch TopGunt @@ -23463,34 +48503,58 @@ Topez Topgolf Topi Topkeklethal +Topkerel Topman Toppavenger Topstad TopsyTurve +Tor Btw +Tor Cool Guy +TorBlueJays +Torag Tony Torags +Torags The C Torchbringer +Torchfall Torchiclover Torchpix +Tordenknold Tordue Toreador Toreransu +Torgonis Tori Torille +Torille btw Toris Torkoal +Torky Bow +Torlux +Torm TormentingU +Tormood +Tornaddyne +Tornado Kim TornadoGang TornadoShit Torned Tornjak TornoDB +Torok Toronto TorontoOVO Torr3nHunt3r Torra +TorraTwo +Torretto +Torrfly +Torrud Torsinclair Torso +Torstol +Torstol Todd Tortanium +Tortcher Tortelini Tortew TortiIIa @@ -23498,36 +48562,68 @@ TortillaChip Torttunaama TortugaBooga Tortugas +Tortuous +Torture Iron +Torva boy Torvee Torvesta +Toseki Tosetti +Toshiba +Tossin Tostada +Tot1 Total +Total Lvl Total Pede +Total Spoof +Total Vanity +Total Zero Totaldumm Totaled3 Totalis +Totallymad20 +Totalxq +Totato Tote +Totemas Totnum +Tott +Totti +Tottie Toucan Toucann +Touch My Wii +Touch Tablet +Touch Touch TouchPinis TouchedByXp Touchkin Touchmydig Touchpad +TougeAttack Tough Tounii +Tour Guide Tourino Tournx72 Tousart Tove Towely +Tower Guard TowerOfGod Towerbros Town +Town Square +Towney Stark +Towton II Toxic +Toxic Dice Toxic Emre +Toxic Joda +Toxic Mfer +Toxic Outlaw +Toxic Waltz Toxic017 Toxic125 ToxicBropipe @@ -23535,12 +48631,22 @@ ToxicDroPipe ToxicKenny ToxicSimp ToxicWaster +Toxzeek +Toy Chest Toycutter Toyger Toyne Toyocoma ToysRusK1d Toysalami +TozzinSalads +Tpc Chris +Tpc Jimmy +Tpc Ken +Tqnks +Tqrb +Tr Farmer +Tr hoca Tr0gdor Tr1ckyD1cky Trabelco @@ -23548,85 +48654,164 @@ Trac Trace Tracing Trackpad +Tracktix Trackzor +Tracto r +Tractorjoe13 +Tracxy Trad Trade +Trade Me 70k +Trade Parade +TradeForItem TradeMeBro TradeMeUWont +Tradebarrier Tradeophobia Trae47 +Traenalai +Trage Gast Tragick +Tragon33X +Trail +Trail Sodas +Train Track +Traincore Trained Fish Trainer +Trainer Bad Trainin +TrainingDay TrainingDays +TrainingWill +Trainor BTW Trains Traiths +Trakiya Traktori Traktorman Tralan +Tralfamadori Tramayne Tramfix Trample +TranSfused Trance +Trance Heals +Trance666 TranquilGod +TranquilHaze Tranquillia Transfer Transgressor +Transpiler Transpose Tranziztance Trap +Trap Carrot +Trap the Cat +Trap-A-Holic TrapGdReptar TrapGood93 Trap_Capo Trapking +Trapking 8 +Trapping Trapski Trasclart Trash +Trash Pvmer +TrashBlast +TrashManJ0hn +TrashServers Trashu2 +Trashua Trashy Traumahh Travee Traveler Travis +Travis 42 +Travis on Rs Travis473 TravisThott Travish Travor TravviePatty +Travy D Law +Traxic Traxxed +Trayvon King Trazaeth +Trazez +Trazza001 Trebluh Trebyzond +Tredderss Tree +Tree Form +Tree Oils +Tree43210 Tree50 TreeNut11 +TreeTopsFart +TreeWeasel +Treedemption +Treehuggers Treelo23 Treenut Treinen +Treio Trejoracine Trekhoar +Treldinn +Trem Bao Uai +TremensInc Tremorx00 +Tremzy +Tren Culture +Tren Hex TrenbolonAce +Trench Ben Trendeon +Trendiness Trenl Trennel7 Treno Trensational +Trentovitch Trentt Trepa Trepador Treps Tresemmee Trev +Trev the dog +Trevenant Trevo Trevor +Trevor Died +Trevor M +Trewg +Trews Trey +Trey is Treygor +Treyvor +Trezler +Trgx2 +Tri Flamingo +Tri-P0LAR Tri9py_J TriBalanced +TriFlea Tribe +Tribe Leader +Tribe of 123 +Tribryd26 Trick +Trick Blue +Trick Statue Trick-demon TrickRoom Trickiac @@ -23636,11 +48821,15 @@ Trickster122 Tricomb Trictagon1 Trictagon2 +Tricx +Trid3nt Trieuce Triforce13 Trigamy +TriggaTriggs Triggadd Triggahappy +Trigger Me TriggeredMot Triggeredm3 Triggering @@ -23650,22 +48839,44 @@ TrikiRiki TrikyCutworm Trikzed Tril +Trilipe Trilligy +Trillogy Trillotani +Trilogies TrilogyXO Trim +Trim Jr +TrimmedGrimm Trimmedguy TrinitySauce Trinix Trio +Trio MF Trip +Trip Machine +Trip Masta +TripEatIRL +TripJaw +TripSquad Tripachu +Tripae Triple +Triple Deuce +Triple Dex +Triple U TripleBeans +TripleHyphen +TripleNeck Triplet +Tripod Neb TripodDog +Trippie Damo Trippinsac +TrippleMarty Trippy +Trippy Mind +Trippy Troll TrippyReefer TrippyScapee TrippyTony @@ -23673,78 +48884,155 @@ Trips TripssAcid TrisomyMumky Triss123456 +Trissee TristV1 Tristann +Trito +Triton Blue +TritonSaber Triumph Trivi Beast Trivit Trivium Trixcet Trizak +Trizepz Trldude7 TrocSan +Trocko4 TrodOnLego Troetelbeer Trogbite +Trojan Steed Trok +Trolerage +Troll Chad +Troll464 TrolleVV TrolletTruls +Trollevv +Trollface +Trollheimusk +Trolli TrollinPony TrollinTony +Trollinguy +Trollzzy Trololosaur Tromal +Trombalski +TronixxIM +Tronkshark Tronse +TroopIronman Trooperke Tropec TrophieTyler Tropical97 +Tropicaux +Tropidelics Tropsic Troskals Tross Trottero Trottington +Troulis180 Trounced TrousrMonstr +Trout Wallet +Trovam +Trovo +Troxicus +Troy Buckle +TroyPolamalu +Trreezz Trrrpfosdss +Tru3Iron +Trublians Truce TruckTruck +TruckYacht +TruckerLiam +TruckerTuck TruckersLife +Trucki +Truckstop0 True +True Flex +True Joker +True Knight +True Owl +True Repent +True Tones TrueBadApple TrueBank +TrueNorth95 +TrueSatan TrueTech TrueTeller77 +TrueYoshi Truegreed Trueplaya +Truers Trueth Trulieve Truly +Truly Lifted +Truly Loving TrulyForever +Trump TrumpCard TrumpSuxAss Trumpet +Trundholm Trunker Truno Trunsa +Trusejageren TrustIssues +TrustNoOne Trusted Trustifarian +Trustin +TrustyThrust +Truth Hurtts +Truth Seekir +Truxy One +TrveKvlt +Try Casual +Try Die Cry +Try Hard Jr Try2IronMan TryAltF4 +TryCBD TryHard +TryHard DBag TryHardi Tryactin +TrygveLegend Tryh4rder Tryhard +TryinNot2Die +Trym +TrymeTrick +Tryna Max +Tryna match +Tryndaflex77 Trynottodie2 Trypophobia Tryptamind Tryptopane Tryuumph +Trzaskowski +Ts Danne +Ts Me +TsMaxed Tsakahele Tsar +Tsar Douglas Tsarina Tschinelas +Tshotz Tsiquli Tsitika Tsjok @@ -23758,27 +49046,42 @@ Tsudo TsukasaS TsukiAkuma Tsukihi +TsukikoBaka Tsukiya Tsuku +Tsuku yomi Tsukuyomi Tsumikitty +Tsumoso +Tsurubebi Tsyphoid Ttffdd Ttoz TuNxZbs Tubbless +Tubbzzy +Tube Dood021 Tubmasta95 +Tubs Tubz Tuca +Tucker Jeb Tuckerajf +TudoLaDentro Tuerro Tuexo Tufan Tuffa Tufs +TugBoatWilly +TugMeTwice +TugMyCox +Tuga9 Tugboat Tugboats +Tuii Tuisku +Tuittu Tukeldaja Tukkairti Tulf @@ -23786,20 +49089,37 @@ Tulip Tulipssonmyd Tully03 Tulppu +Tumbdownlog TumbleDore +TumblingSand +Tumeken Tay +TumekenToday +Tumma Paahto +Tumms +Tumnus Tumppe Tuna +Tuna Juice +Tuna Shuffle Tunaking420 +Tunasafarii Tunda TunderBog Tundra +Tunez Tung +Tung Fu Rue Tungsten +TungstenGyro +Tunguska +Tunkky Tunnellord Tunppii Tunsberg Tuntun +Tuoppi1230 TupacShaakur +Tupackid Tupakki Tupeli Tuperrovski @@ -23807,97 +49127,188 @@ Tupla Olut Tuplaa Tupoopsa Tuppu +Tuppu hoitaa +Tuppuu +Turambarr TurangaNui +Turb0uu Turbanator Turbie +Turbin Turbo +Turbo IM +Turbo Junkie +Turbo Toes +Turbo Zero TurboMilf +TurboSoak +TurboTez TurboWet Turbokjepp +Turbotymer +TurdFlicker TurdFurgeson Tured Turha Turiak +Turjilin +Turk Monsta Turk3H +Turk3HH TurkBird +TurkeyPro +Turkije +Turkish One Turkish3agle Turkled Turkos06 Turks Turn +Turn It Left TurnMagic +Turnalar Turner Coach Turnii Turnt +Turqish +Turqy Turri Turrner Turrox Turskaa Turso +Turssuttaja +Turtelloo Turtle +Turtle Rak +Turtle s Turtle7 +TurtleCoddlr TurtleWurdle Turtlebutt +Turtledog Turtleliest +TurtlesClimb TurtlesRdank Turtleso3o +Turts +Turuii +Turvasana Tusc +Tushy Taker +Tusk Tusondude25 Tusseladd92 +Tustea Kossu +Tutorial Tutoroo +Tutta Tutter TuttiFruttii +Tuttimango Tuttimelon Tuuri +Tuuri haukka Tuvisitt +Tux Tuxy Tuya Tuzle +Tvanderlaan1 +Tvb Cx +Tw0Pack Tw1ZzT +Tw1nsPurr +Tw1nz +Tw1st3d_B0W Tw1stedBow TwTv Twald10 Twas +Twas Xmas +Twashua Twaste +Tweaky +Twee Barkie Tweeder Tweek +Tweekzor Tweetart Tweeznap +Tweezr TweezyShadow Twelvyy +Twenie Wan Twerk +Twerk 132 Twet Twice +Twice Flo TwickerTweet Twiddle +Twiddle Twix +Twidgets +Twiested +Twift Twigbert +Twigglet TwiggyC Twigler Twigster Twiisted Twilight2326 TwilightPony +Twilly Spree +Twillz Twin +Twin Fists +Twin Kinz +Twin Peaks Twinflip +Twinick Twink +Twink Ripper Twinkle +Twinkle Park +Twinklekat Twinr0va Twins +Twist2K Twist3d Twist3dData Twisted +Twisted Boog +Twisted Bung +Twisted Cook +Twisted Echo +Twisted Jam +Twisted Matt +Twisted Titt +Twisted cat +Twisted garg TwistedAegis +TwistedBeer +TwistedBerns +TwistedBowlz TwistedBr0 TwistedCybrg TwistedGuard TwistedHeart +TwistedLike TwistedOffer TwistedWally Twisted_Ry +Twisted_newf TwistedxAura +Twister Nips +Twister XIII Twistertjeee +Twistie TwistsedT Twitch +Twitch Fear +Twitch simp +Twitch507 TwitchFear TwitchSeljan Twitchen004 @@ -23905,220 +49316,491 @@ Twitchin TwixTM Twizler74 Twizzlers88 +Twnkles Twntythree23 +Two Elites +Two Fears +Two Ounces +Two2SixToo TwoBeerBuzz TwoDigitJish TwoDogs TwoInTheSink TwoLegedDog TwoShue +TwoTwentyTwo +Twoconch TwojaStara +Twoy Twpz Twstd Twum +Tx2 +Tx3 Poseidon +TxNock +Txbor Txfr Txga +Txh +Txlon +Txture +TxunaTuna Txyus +Ty +Ty God +Ty Sit Idiot +Ty bears Ty1er Ty4F +TyDyPooFingr +TySkidmore23 Tybear575 Tyberium +Tybones Tycen +Tycens Tydigidy Tydollatree TyeMeUp Tyelca Tyepo +Tyfr Tyfus +Tyfus Bende +Tyfus Mug Tyfuslija Tyga +Tygr +Tyhger Tyin Tyixx +Tyjes1 Tykaman +Tyl r Tyler +Tyler Razz +Tyler Stone Tyler051095 +Tyler4rs +TylerGBR +TylerMike Tylerknight3 Tylerton +TylerxBandit +Tylo54 Tylooor Tylz2 Tym8 +Tyney +Tyngre Tyom Tyontaja +TypOneg4tive Typhose Typical Typisch +Typto +Typtooka +Tyq +Tyr 24 +Tyr Ara Tyra Tyrael +Tyrael OG Tyran88bid +Tyraniana Tyranids TyrannicaI Tyrants Tyrep +Tyrex Tyro Tyrus Tysh Tyskie +Tyskie38 Tyskn Tysn +Tyson11 Tysonn Tyst +Tysterisk +Tytastic Tythle +Tytto Tywonia +Tz-Kek-Twang Tz-Ket-Kush TzCal TzCok +TzCok-Hard TzDeez +TzDeez-Nuts TzHaar +TzHaar Meej +TzHaar-Doug TzJal TzKal +TzKal Majora +TzKal-AszZuk +TzKal-Cumsok +TzKal-Gio +TzKal-Mike +TzKal-Thad +TzKal-Zuky TzKalFatkok TzKalSuk TzKarl +TzSuk-Dis2 TzTok +TzTok Chris TzTok-1gBud +TzTok-Fart +TzTok-Flame +TzTok-Izzy +TzTok-Jaffa +TzTok-Jahd TzTok-Jeffy TzTok-Joka +TzTok-Kekw +TzTok-KetKok TzTok-Ladz +TzTokTitties Tzek +Tzhaar Bower +TzhaarThicc +Tzhaar_PvP Tzharzh +Tziis Tzikit +Tzkal Edgar +Tzkal Tygo +Tzkal-Reborn +Tzok-GigaKok Tzoski +Tztok Shaz Tztok-Met-Al +Tzuyuwu +U A E +U A V Online U Ded Boi +U Mirin Brah U N X +U R Lame +U Tele Nub +U W8 +U n I f Y +U nknown +U0Q U0sunpeh +U3 +U4 +U71Q +UAWMAN UB02 +UBWare UBaKr UConn UENDELIG +UFOTurtle UFOs +UG Juppa UGLYMONKEY58 UGLYS UGam3zOS +UI GOKUU +UI UC +UIM BUTT3RS +UIM Brah +UIM Burni +UIM Chayula +UIM Illusive +UIM Liar +UIM Lobotomy +UIM Log +UIM Loki +UIM Nathanjb +UIM Ori +UIM Paperbag UIM Pepper +UIM Pidbull +UIM Shen +UIM Shrift +UIM Sorrows +UIM Spongie +UIM Stephan UIM Thor +UIM Vas +UIM Warriorh +UIM Wedey +UIM Yoga +UIM Zoldyck +UIM whozan +UIM7 +UIMBerg +UIMaqtpai +UIMatti +UIMpostor +UIPanda +UIdahoKush +UIspice +UKB0b449 UKnowItsB +UL7RA +ULF Tagger ULTMA ULTRA +UN-FAZED UNBIQUOUS UNC0RN UNCEL UNCLE +UNCLE LEET +UNCLESAMY +UNDEAD EXO +UNDERURBED4 UNEX1ST UNH0IY UNLOADED999 +UPDOGS +UPSdeliveree +UQV +UR 0 HP LMAO +URA Noob URAMESHl URSS +US Postal +USA Tyler +USA USA USA +USA is Dev1l USAF USAO USBthe2th USMARINEHYDE +USNavyOver70 USSpaceForce USTreasury +USirHaveLost USirHaveWon +UTT +UWCB +UWF +UWUSTELIJA +UZY VS JAD Ualt +Uamee Ubar Ubaru Uber Uber Logan +Uber Yeats Uberamazing +Ubersmind +Ubicorn +Ubu +Uccino Uchiwa +Uchr Udacity +Uderp Udhariol2 Udingus +Ufda +Uffe Persson UgliestIncel Ugly +Ugly Hipster +UglyFishArm Uglybeetle27 Uglyyo93 UgranDag +Ugursuz IT Uh-0h Uhbove UhhhBoneless +Uhhhh Wut +Uhm Uhscended +Uidi One +Uim Beyonce +Uim IRL also +Uim Zuko UimSian +Uimakoulu +Uk Bristol +Uki Kukkamaa +Uki Skillz Ukko +Ukko-Pekka +Ukkonenn +Uknow Yunho UknowPotter Ukonvasara +Ulappa +Ulibarri +Ulik madiq +Ulillillia Uliss Ulizius +Ullerton UltDrewes +UltRise Ultebor +Ulthane120 Ultima +Ultimat3ly Ultimate +Ultimate Low +UltimateH0bo UltimateSami +UltimateWare +UltimateZe Ultist Ultistic +Ultorman Ultra +Ultra Miami +Ultra Primal +Ultra Sloth +Ultra Space +Ultra Teuz +UltraGOOP UltraJack UltrasTomi +Ulvhilde Ulyanyx UmUUmuUmU +Umarra Umbr +Umbrah Umea Umek Umiland +Ummfufu +Ummz +Un Dutchable +Un M-U-T-3-D +Un puma +Un-Expected UnDutchable +UnGoof UnHoLyxMaTTy +UnOrderly +UnRuleD +UnTaMed X +Una999 Unacceptab1e +Unaclogger +Unaided Unass1sted Unassisted Unavailable Unbacked +Unbann me Unbiased +UnboundLeaf Unbreakable Unc1e +UncJo Uncaged1776 UncagedOne Uncandled Uncel +Uncel Ben +Unchunk Man Uncle +Uncle Exci +Uncle Julien +Uncle Rocho +Uncle Solo +Uncle Somnus +Uncle THC +Uncle Trippy +UncleBigBob1 +UncleCuckle UncleDaddiii +UncleGuy UncleSlappy1 +Unclear +Unclesam137 Uncode UncomfyPants Uncommon Uncooker +Uncool Gary +Uncr3at1ve Uncut Uncy Duncy Und3r0ath Undead UndeadElk333 +UndeadYenny Undeadd Undefeated +Undelivered Undeniable Under UnderExiled +Underaged Undercatt Underlogged Underoos +Underrs +Understars Understated Underverse Undine Undoubtful +Undra +UndrgrndSalt Undulaatti94 Unemati02 +Unemployed Unequalized Uneven +Uneven Mango +Unexposed Unfair Unfearful +Unfergetable +Unfi +Unfollowing Unfriended +Unfunno +Ung Ungolianty Unhappy +Unhapytuna Unhealthy UnhingedE Unho +Unholy Bains +Unholy Cult UnholyAbyss Unholybucket +Uni Mike +UniQ +Unicat Unicorn Unids Unii +Unik +Unimaginary +Unimander Unintended +Union Dixie +Uniqlorn Unique +Unique Am I Unit +Unit Tests United +UnitedLeeds Uniteds +Unity 3D Universe Unkh +UnkindPastry UnkindledTwo Unknown UnknownBeing @@ -24127,158 +49809,353 @@ UnknownValue Unknownchuck UnkoPlayer Unkoly +Unkownkiller +Unlash Unlds +UnlimitedHC +Unlit Sky +Unlock Death +Unluckerdile Unluckers Unlucky +Unlucky Jord +Unlucky lmp +UnluckyNGay +Unlugy +Unluigi Unmasked Unmaxed Unmerkable Unmoist Unnerving Unohdettu2 +Unomia +UnorthodoxGF Unorthodoxfo +Unown397 Unprofitable +Unread +UnrealGecko +Unrecord +Unreliab1e Unrot Unruliest Unsafest Unsainted +Unsavior Unscuff +Unscythed Unseen +Unshaven Cat +UnstopFork Unstrung +Unsubscribed Unsung Untameable +Unthinkable Until +Until Dawn +UntrimCraft Untrimmed +Unus Divinus +Unv +Unwiii Unzkiboi +Uoziz +Uozu +Up N Ur Mom +Up ya mom jr +UpBad +UpNorthCha UpRoaRs UpThaSaints Upeo +Upi Uploading Upluk +Upper Four +Uppercuts +Uppotukki Upriser Uprising Uproot Upsi +Upthe1rons Uptime +Ur Exp 2 Me +Ur Obsession +Ur a baish UrASalmon UrBabyzDaddy +UrBoyBilbo +UrDadsLov3r UrJustXpToMe UrMomLvedIt UrNansMan UrPureSucks UrScr3wed +UrSuchaShita +UrWifeLuvzMe +UrYe UrZoggy +Ura Juanker +Uragaan Dude Urakas Urakkapallo +Urallia +Uran ium Uranus UrbanMerza Urbdayy +Urbn Urdead Urea Urek +Urekzera +Urfe +Urheiluiatka Urheilujatka +UricOddball Urkchar +Urked Urkerhard Urock16 +Uross +Urotsuki +Urpokarhu +Urri +Urs +Ursa UrsaOmega +Urskog Urthron +Uru p +UsainBloat +Usb Doe Tin +Usb Flies +Use +Use Tongue +Use2bHC UseToBeGood Useable +Usecsythang UsedApplePie +UsedLube +UsedRubbers Useless +Useless Main User +User 27 UserApproved +Useranme Usos Ussin +UsualAntZ Usva +Utahime +Utahn Utareita Utca Utini Utis Utsuwu Utter +Utter Pleb Utvisa Uunijutsku Uunipelti +Uuo +Uus kaust Uuti3 +UwU Leo +UwU Noctis +UwU Otaku UxXwpasdiioa +Uzin Uzot +UzrielBoi Uzunar +V 3 +V 9 +V A K U +V A L O R +V A M 0 S +V A N D E R +V Bros +V E F +V E H +V G +V GK +V Gamemaniac +V L A D Y +V Lestat V +V NL +V Nichushkin +V OO D 00 +V R I L +V e c n a +V endetta +V ergetend +V ezi +V i 1 e +V r o l ij k +V the Victim +V-43 +V-EuSoto +V-SaTanjiro9 +V-Tek +V-olRagnarok V043 +V0F +V0WZ V0XA +V1BER V2int5 V3NQM +V3XY V3lnias V3n3natis +V3rtigo btw +V43 V4SKI V4sia +V5C 2 +VAIDUOKL1S +VALH0WLA +VALHA LL A VALK0 VALORANTJETT +VAMPYRlC +VANlLLA RUM +VB TINNS VB24PK +VBoss +VBsec +VDB Niffooo VDHG VEDA VEGANDIET +VEN0M13 +VENNY MOCKER +VERYBANANNA +VET DMaZ +VHS or DVD +VIAL1 +VIE T +VIII +VIIVII +VIKING0 +VILIONKKAA VLEERMUlS +VODKANATOR +VODs VOIVID VOREVERAIONV VORKl +VOlDWAKER +VP N1ck +VPSxSam VPixels VRScotty +VS0P VS367 VUNDA VVDance VVJuul +VVS1 VVStoner +VVade VVanderer VVarden +VVeems +VVhite0ut VViggle +VVilson +VVinni +VVintage VVona VVoods +VW Crafter Va1ynx Vaal Vaalbara9 Vaalberg Vaandah +Vaca Preta +Vacant V Vache +Vache Verte Vad3 Vader Vado Vaealin +Vaelleruen +Vaelte Peter Vafan +Vafthruthnir +VagAngler +Vagabond +Vagina Bad +Vahagis +Vahagn Vahidil Vahlyte +Vahn +Vaikuttava Vailokas Vain Vainis Vaishe +Vaisu VaitkiS Vaizki Vajengo +Vakstu +Val Rex +Val3ntlne +ValOnMyChest Vala Valadrak +Valarfax Valaron Valdevon Valdomiro B +Valdyra Valendale +Valentijn +ValentinaLuv Valete ValgeHunt09 ValheraUK Valhk +Valiant Nite +Validde Valiente +Valienton Valiiim Valiralith +Valirion Valivill Valknir +Valkore +ValkyraeS1MP +Valkyrie btw +Valkyrie xo ValkyrieNora Vall Valliance +Valliate +Vallies Vallk Valluu Valmar +Valmora Valo +Valo Ville Valo247 Valor ValorantJohn +Valorate Valorisatie Valorise Valorpoint @@ -24288,10 +50165,17 @@ Valverdi Valxn Valzar Valzor +Vam pire Vamo Vampeodia +Vampire Bob +Vampirehunt Vampiress Vampurr +Vampyire +Vampza +Van Cold +Van Hellsing VanDarkhome VanHeisma Vanaic @@ -24300,79 +50184,154 @@ Vandahl Vandaine Vandalize Vandalized +Vanderhek +Vanderstorm +Vandery Vandetto Vandmand Vandorann Vanek +Vanek-26 Vang Vanh0 VanhaKettu Vanhal000 +Vanilla Best +VanillaBum VanillaDonut +VanillaFlow VanillaSwirl +Vanillawaifu Vanity +Vanity Fair +VanityNugett +VanityRS +Vanityyh Vanja +Vanja M +Vanki +Vannara +Vanskid Vanss Vantiron Vanupimphi Vape99 VapeMonster +VapeNGapeLLC Vapeape1 Vaperan +Vapid H VapinTiger +Vaping Cloud +Vaporion Vaporized +Vapsjeeee +Var Laslore +Varamyr +Vardorfister +VardorvisSux +Vardovish +Varduka +Varenagan +Vargen96 +Vargo +Vargrmoon Variabulls Varixed +Varlanazz +Varlot4 Varm +Varm Kaffe Varnilla VarockVirgin +Varonom +Varpu +Varradero +Varro Varrock +Varrok Obama Varroq +VarrrokObama Varsa Varsii +Varthon Varulven Varxas Varz +Vas R Vasar23 Vasd Vasdeffernce Vaskapotti Vaskekort Vasquez +Vassaa +Vassago0111 +Vassal +Vastrakal +Vastuuvapaus Vasuki Vasyliev +Vatenkeist Vatix Vauderus Vaull +Vault Hunter +VaultTecs +Vautumn +Vaux +Vava471 Vaveti +VawnHeuf Vaxx +Vaxxil +Vaxyr VayQ Vayda Vaynon98 Vaz0r +Vazier Vazoo +Vb Panther Vbiqve +VeKnow +VeZuu Veas Vector +Vedam Veddunreal Vedroulian +Veecal Veeena +Veekkuu +Veerpalu Veersnof Veetu76 Vefsn +Vegabond Vegakargdon Vegan +VeganFemboy VeganVibes Veganstho Vegard Vegas +Vegas Gunman +Vegas Mike +Vege-Mauri Vegeetta Vegeta +Vegeta MF Vegetah +Vegetas Veng Vegetunks +Veggie Mate Veghan +Vegitation Vegito +Vegito Meta Vegolse +Vehicle Tech Vehms Vehru Vehtamin @@ -24382,205 +50341,416 @@ Veinin VeitiKKa Vekie Vekuuu +Velaynx Velbain +Veld Velegro Velek Velgreed +Velhote Veli +Veli Iron +Velikan Veliki +Velite12 +Velkennar Velkija Velli Velmir +Velociraptor +Veloxrapt0r Velreth +Veltsi +Velvetgunner +Velvsy +Velzun +Vemba Venado Vendall2 +Vender Venderik Vendet27 +Vendum +Venemies Venenatis +Venerate Venereology Venetsia +Venfour Veng +Veng BTW +Veng Me Not +Veng Waster VengDeezNutz Venganza +VengeMeDaddy Vengeance013 VengeanceTR Vengeancen Vengeful +Venizar +Venkeltje +Vennythizer Vennyv99 Venom +Venom Vegeta Venom00 VenomTears +Venomousbite +Venomxkillz +Venous Cobra +Venpu +Ventia Ventile +Ventril0qist +Venus Nyan +Venzdroid Venze +Venzy +Veo s Veos +Verac Obama +Veracs Veracthus +Veraen Veratyr +Verbac Verbal +Verbal Kint +VerbalIrony +Verbia Verbo Verche Verdantys +Verdoemd Verdux Vereco Verelya +Vereoris +Vergi Drakan +Veri Eze +Vericity +Verify Verin +Verissimum Veritasium Verity +Verix Verjj Verkyz +Verliax +Vermachelen +Vermeill +Vermithrax91 +Vermont Iron +Vermyapyre +Vern29 +VernalTDevil +Vernon +Vernossiel +Vernyxitas +Vernz1337 Verokostaja +Veromnis +Verrario Verrtus +Verruckt VersGrind +Versacce VersaceGuap +VersaceSofa Versalix Versatio Versily +Vertigo 2 +Vertsu1 +Vervyyy Verweel VerxaRS Very +Very AFK +Very Typical VeryAvgRNG VeryGoodRNG +VeryLarry VeryLilRng Veryloo Verysharp988 +Verywarm2246 +Veryx +Verzicky Verzik +Verzik BTW +VerzikDaCuck +Verzika Verzy +Verzy Werzy Vesal Vesaris Vesipiisami Vesku Vesley +Vespina Vespulia Vesqu Vesryn +Vessim Vest +Vesta 1000 Veste Vestergaard +Vestorius Vesture +Vesunna +Vetala +Vetem VeteranGamer +Vetilation +Vetinari37 +Vetionarian +Vetr Skaoi +VettePolle +Vex Viper +Vex Virus Vex8 Vexare +Vexed Viper +Vexeed +Vexer07 Vexero Vexers +Vexflame Vexing Vexinity Vexrip +Vexstrom Veylantz Veyron Veysel +VezTa Vezka +Vezon +VgbndUnicorn ViIlageIdiot +ViaCarter Vial +Viallinen Viat +Vib3Ch3ck3r Vib8 Vibby Vibe +VibeCentral +Vibeke Gar +Vibeology +Vibes Check VibesTooWavy +Vicardi +Viccuri Vicente1111 +Vicenza 173 Vices +Vicious Dest +ViciousPawg Vickies Vicky VictheStud +Victimised Victor +Victor Dogg +Victor Lim VictorHo +Victorize Victorp75 Victoryw Victreebel +Victur Vida Vidacks +Viddii +Video Gamic +Videogam3r +Vidlmao Vidy Vidz Viech +Viema Vienas Viera22 +Viesker Viesty Vietnamees View +View Bot View0 ViezNegertje +Vieze Jongen Viggi +Vigi V Vigilamus +Vigly Viguro Vii23 +ViiPV ViiViiVii Viiduus Viiiral +Viikonloppu Viiksi-Vallu ViinaGoblin Viinakramppi ViisYsiKuus +Vijand Vijay +VikSC Vikat VikeSkol Vikerne666 +VikiLord Viking +Viking Dad +Viking768 +VikingKnees Vikingfe +VikkiVance +Viklok Vikram Viktor +Viktor Wins VilainLutin Vilbeee Vile +Vile Arcane +Vile Cabbage +Vile Squid Vileblood Vilemaw +Viliant Vilke +Villagers +Villain Dude +VillainLife Villanovaguy Villanovan Ville Ville921 +VilleGallle Villix Villllu +Villosa +Villrix Vilnis Vilty Vilunki Vimpsen Vims +Vin 08 +Vin B +Vin Vista +Vinaegre +Vinbum43 +VinceBennett +VinceOfMince Vincen Vincent +Vincent D2 VincentDaMan +Vincentimetr +Vinceut Vinchops +Vindi IM +Vindruen +Vindruva +Vinh y +Vinish Vinkmaster1 Vinland +Vinloxx +Vinn28 +VinnFrazz Vinneh Vinnie +Vinnie Dabs +Vinnie Pazz Vinnie526 Vinny +Vinny NZ +Vinny Speedy +Vinny Verac +Vinny-G +Vinnyaldo Vinoloog Vinopenkki Vinostondis Vinous VinsanityGG Vintage +Vintages Vintner +Vinxe +Vinxion x Violas Violent +ViolentPudd +ViolentToxin ViolentWaves Violetti +Violon +VipStar Viper +Viper Aurora +Viper G40 VirZuk Viral +Virbatum Virbliud +Virelith +Virgin Creep VirginGirl +VirginHunteh +VirginUwU +Virginism +Viriato VirtRemnants Virtaheepo Virtuaalnuss +Virtual +VirtualAhri Virtuart Virtuous Virunypel Virus +Virus LSSZ +Virus Soup +Viruss ViruzTehNub +Virzik VisagePlease +Visarin +Viscera Viscx Visdom Vishno +Vishnu Visibly Visigothic Visine Vision +Viskan +VismaBlet +Vister Vistopherson VisuallyMatt Viswiel Vita VitaLemonTea VitaMineralz +Vital Dude +Vital Hope +Vitality +Vitamin See +VitaminCnote +Vithark Vito Vitor Vitreous @@ -24588,260 +50758,533 @@ Vitrified Vitruvio2 Vitryssen Viturbio +Viturscy Viva +Viva La Vida +Viva Mehico VivaLaWeegee Vivalask8r Vivalla Vivants +Vivascape VividAzura VividDreamss +Vivido +Vivij +Vivk +VivziePop +Vixca Viyrew Vize Senpai +Vizima +Viziyo +Vjee +Vk VlBZ +VlGGAN VlNTER +VlRAL +VlVID VlaamsePlank Vlad +VladTheBwana +VladThePaler Vlada Vladek284 Vladi Vladibjoern Vladictorian +Vlaendren Vlambare Vlast1n +Vlncent Vloxx +VnG Lynds +VnG Zenyte +Vnce VngH +VnilaGorilla +Vo Amice VoHiYo_Nami Vobia Vocaloida +Vodbi Vodec Vodka +Vodka ice VodkaBarrage +VodkaBreath VodkaPlz Vodke Voekus Voetbalkous +Vogefur Vogues +Vogven Void +Void Fanatic +Void XVII +Void-Cho VoidMySoul +VoidOnyx22 VoidWraith Voidberg Voidnight Voidpaw +Voidrow Voidseeker +Voidwaker op Voittosumma Vokon +VolProMan Volai Volantis Volary +Volblaffen +Volc Volcan +Volcance Volcanos +Volco Volcwinder Voldesad Volgos Volkert +Volkie Volkrah Volkzy Volmortt Volrod Volrum +Volt +Volt OSRS +Volt268 +Voltimolt Voltz Tzkek Volucris +Volunteer Volux +Volzo Vomiting +Vomiting Cat +Vompiainen Vomuao +Vomure +Von Beck +Von Dylan 2 +Von Locke +Von Reibnitz VonThaine Vonbony Vonderhaar +Vondoom Voneirus +Vonhinten Vono +VonoV +Vonschatten +Vonsv Vonty VooLis VoodooCells Voodookie Voorheees Vopi +Vor The Ape VorGole Vorare +Vorarlberg +Vorcan +Vorikar Vork +Vork Planker VorkathsMate Vorki VorkiAlt Vorkscaping +Voroth Vorpal Vorpeo +Vorsamu Vorschlag Vorso Vortob4 +VosOc +Voss V2 Vossen +Vosty Voted4Kanye +Vovi +Vox Whoppa +VoxMachina Voxna Vozion Vpdz +Vrauri Vrayl Vreaper Vref +Vrekked Vriendschap Vriix +Vrijer +Vrillionaire +Vroeg VroomMasheen Vrzn +Vsian Vsmoke +Vsnn Vt Flavourss +Vt99 Vuallis +Vubbe +Vud Vueko Vukodlak +Vuku Doll Vulcan Vulcant +VulcunLogik Vule Vuleka +VulfRS +Vulia +Vulklet +Vulm +Vulo Lives Vulp Vulpes +Vulpes Audax +Vuohi Vurx +Vurzik +Vus Vusa +Vuto +Vutox +Vuuln Vuur Vuuututututu +VvM Otter +Vxmm +Vxus Vyagruhh +Vyaraeaen Vyaza Vyby +Vycarious Vycos +Vyluxian Vymera Vynlx +Vyrelady Em Vyrza Vysaraine Vyseri +Vytauts +Vyukris +Vzb Vzla +Vzr +W 0 R D +W A G M I +W A G U S +W A V V E S +W E K A +W I L L 777 +W I N 3 D +W J M V +W L F +W O W S K I +W Rizz +W a r s +W ak +W amo +W anted +W e r +W elfare +W i i +W i l l y +W i r e tap +W ifi +W iggly +W illy +W ilmer +W l S E +W ll Z A R D +W olf +W orx +W-2 Form +W-A-M-M-E-R W00D +W00DINTUNA +W00X W0N DMM W0MB +W0RY W0SS W0fle W0nderwall +W0t Rng +W141 Legends W1ETzakje +W1F +W1G +W1Z3 W1ldman W1nch +W1ngedDragon +W2P_III W330 +W349 W370 +W3SL3T7 W3ST0RZ -W4R3 W420 +W489 +W4R3 +W4T3RM3L0N +W4Wumbo +W56 W5O7 W7uQs7s1uKyS W7uQsTu1KsyS +W8 letme pot +W88SSKILLER +W8ST UF TIME +W8ing4Name +W91 forever +WA2 WAGINGWARS +WAKANDA JEFF WAKEUPSWEATN +WAP Munchlax WAQQQ WARLOCKTIN WAZABl +WAxsTAche +WBA Scott +WBMA WE0DEND +WE3N +WEEDY Woody WEGOINGCRAZY WEGSIR +WFH Gains WFTWP +WG Affect +WGWGWGW6W6W6 WH1TECHAP3L +WHITE E92 WHITEEEEEEEY +WIMThighs WINNINGrng +WIRE PULLING +WISEB0LDMAN WIZRD6 +WLJ +WM94 +WMAF +WMATA WO0DSIE WOMYNAREDUMB WONT +WOOGLlN +WPNsuper +WS Hubris +WS Kyzza +WS Phora WSOP +WTB GF 1 GP +WTF No Luck +WTF S7VEN +WUDS +WV Boi +WW I +WW2 Champs WYBD +WYD STEP M0M WYDStpSis +WZ95 Wa Wa Master +Wa t WaIk WaVy +Waaaan WaaduuuHek +Waafty Waager +Waai Do +Waassssaaap +Wabanaki Son Wabbert +Wabo +Wack Sparrow +Wackabie +Wacko Swaami Wacoltx Wadbot Waddlez +Wadee Wadeo369 Waderik +Waem Wafcfreak +Wafe +Waffle Cone +Waffle Jr Waffleboy +Waffleici Wafflekin Waffles700 +WafflesYo Wagada +Wagblump Waggit WaggsTheDog Waggz Wagit Wagn1984 WagnBurner +Wagyu Wahb Wahido11 +Wahpahp Wahpan Waifuism Waifus WaikatoChris +Waikit8 +Waine Wait +Wait Quick +Waitforit14 Waitin Wajiiro Wake +Wake Boarder WakeAndDrake +WakeUpF1lthy +WakeUpGirl +Wakey Wines Wakisaka +Walborg Waldrin Waldron530 +Wales164 Walker Walkin +Walkofshane WalksOG Walktellfox +Wall-enberg Wallabies +Wallabillah +Wallace D S WallaceTusk +Wallah Krise +Wallah Lag +Wallahper Walleen Wallerz Wallex Walli +Wallstboi69 +Wallsunny WallyGator Walnutt +Walo CZ +Walpie6 +Walsamer Walshy Walshy00 Walshyo +WaltJnr Walter WaltersPub +Waltt Waltzz Waluigi +Walzu Wampire +Wan E WanPanMan Wandel +WanderTheSee Wandereer +Wanem WangSohLong +Wanhe +Wanistan Wanna WannaBeE-tje WannaGetABag +Wannebet Want Want2beIron Want2mess2 +WantTacos Wantsome909 Waonnman Wapf +WapitiSmackr +Wapol Wapsi +War Dwr +War Force War12Ready WarFawk +WarHawKVJ WarOnOurMind WarSoc +War_x Warbler Warchee +Warcloud Warclown +WarcraftOSRS Ward988 Warden +WardensFe Wardle101 +Wardless 1 +Wardy791 +Ware Adelaar Warfeh +Warforged Warg Wargames11 Wargowitto Warhammer70 WarheadZ91 +Warking 5099 +Warlolz Warlord +Warlord Kek +Warlord Oli +Warlord Papi +Warlord Sage +Warlord Tyth Warlordjinx Warm +Warm Alfredo +Warm Beer +Warm Donuts +Warm Pasta +Warm Pillows WarmLoaf WarmManBlast Warmantus Warmly +Warmongoloid Warmouth Warnac +Warney Warnings +WarpedDeath WarpedMatrix Warph +WarrgMG Warrior Warrior09rs WarriorHome @@ -24853,41 +51296,66 @@ WartoysCandy Wartt Warwick 1080 WasHcimLoL +Wasabeh Wasbeertjes WashMachine +Washed CJ Washyleopard Waspoeder Waspraa Wasserohne Wassillie +Wasstyr WasteOfBond Wasted +Wasted Toxic +Wasted Xj +WastedSpecs +Wastedgr1ny WastingTicks Wastinmylyfe Wastoid Wasup725 +WasupMyBwana Watafara Watamei Watamelun Watanuki +Watardid Water +Water Skink +Water-T Waterbender Waterbury +Watercress +Waterdrop WatermelonTV +Waterpijp +WaterrBoy +WatersHorse Watertodt +Waterwraith Watr Watschi Watson92 Wattledaub WattsyMain +Wattua Waugh Waulez Wauzemaus +Wave 10 +Wave 69 WaveBtw WaveSkill WavesOnMars Wavezz Wavy +Wax Dabs +Wax i +Waxby +WaxbyDonkey +Waxing Sun Waxtap Waxy WayOfKings @@ -24898,113 +51366,240 @@ Wayabove Wayde Waydens Wayert +Wayfarers +Waylor Wayne +Wayne1149 WayneBretzky +WayneMain WayneStated Wayney WayofWonder +Waypanaator +Waypastfear +Wayt Wayward +Wayward Soul +Waza131 Wazp +Wazup31 Wazupfighter Wazzlewop +Wbd +Wcrocks Wcs139 +Wct +Wdfamidoing +Wdges +We B Trollin +We Feed +We Grinded +We Guard +We Love Dogs +We Tad +We The Team +We sley +We0921 WeAllGucci WeAreDoomed WeAreGroot WeAreMoksi WeChat +WeDaBstMusic +WeLoveToB WeRageAsTwo +WeTheCha WeTsHaDoW +WeWanking +Wea Boo WeaIth +Weak Iaugh +Weak Mindset +Weak Terror +Weak Wrists WeakLesss +WeakSpot Weakcob Weaker +Weaki Weaky +Wealth herbs Wealthy +Wealthy Pro +WeaponNovice WeardBeird Wearwolf +Weasel07 Weasel09 WeaselToast +WeaselTuco Weaselious +Weatherwatch +Weatherzx Weav +Web 2 Webb +Webbe +Webben Webdow Webs Webstar +Webtastic +Weby Elite Wecanmakeit Weddn Weder WedhusGembel +Wee Wee Seapy WeeDRekT +WeeMissSlays +WeeWab Weebcrusher Weebmurderer +Weed +Weed B0Y +Weed Barrage +Weed Farm +Weed OG +Weed PhD +Weed Strains +Weed VIII +WeedWizzard +Weedbucks +Weedle +WeeeWoooo +WeekndWorior +Weel Weelechts WeenieHut Weeperz +Wehby3K Wehsing +Weichey Weight Weighting +Weightless Weighty WeirdChimp Weirhere +Weis578 +Weistalief Weki WelbyBree +Welcome +Welcome Beck Weld +Weld Arc Weldar +Welfare PvM +Well Done +Well-ChromeD +Wellar21 Wellbutrin Welld Wellfence18 Wellpower10 +Wellrun1076 +Wellschit WellyWonka +Weloy +Welp Welsh +WelshNProud +Welshfuryy Welshhy +Welshy 07 +Welshy94 WelshyRhys +Wemh Wench +Wendy Page Wendyy Weng Wenja Wenkey +Wenzhou Were2341 +WereWaffles +WereWolf II Werebanana +Werk +Werknemer +Wermin +Werrett Werrtus +Weru Wery Wesh Weshzz Weslee Wesley +Wesper Wessen +Wesss West +West Mids +West Shiv +West Tigers +West Varrock WestFlag WestTxBoyz +Westardythot Western +Western PA WesternBlot Westleafer Westly Westwich Weszie +Wet Boxes +Wet Garbage +Wet Land +Wet Ottr +Wet P +Wet Sneeze +Wet Thot +Wet and oily WetDreamMeme WetForPet WetRnG Wetex Wetone2880p +Wetta +WetterPussy +Wevile Wexom +Wexs +Wexxorz Weyerbacher Wezl Wh1teSox WhaIe +Whaddup +Whag Whai Whale WhaleeWatch +Whaletorsk Whalkatraz +Whamburgers +Wharebadjer Wharncliffe +What Da Hell +What if WhatASpoon WhatAThot +WhatAreDrops WhatItDoBoo WhatSheZed WhatTheDaze Whatapure101 Whats +Whats Canada +Whats Good +Whats Reddit +Whats Trade WhatsHonour WhatsRsSober WhatsThisRNG @@ -25015,262 +51610,501 @@ Whavenlad Whaxt Wheatleyprop Wheel +Wheelchair +Wheelied Wheelies152 +Whees +Wheesnaw WhenPigsFly WhenRuneLife WhenYouCute Whensfull +Where is GE WhereAreWe WhereIsPeace WhereTheCats +Whereisme7 Wheremeballs +WheresMyPets +WheresMyPurp +WheresMyRNG WheresPurple WhersMyPet Whesh Whey +Whey God Whiff +WhiityTosser WhilyWhip Whimsicat Whina Whinnie +Whipppy WhippyMong Whipsaw Whiskerfish Whiskey +WhiskeyWhip WhiskyVault Whiskywayne Whisp3r +Whisper_2 Whitah White +White Beauty +White Mage +White Mantis +White Owl +White Rnger +White Shark +White Soul +White Wolf WhiteBTW +WhiteBoySam +WhiteChuky +WhiteCricket +WhiteDeathh1 WhiteMagnet +WhiteMaleHre WhitePilled WhiteProdigy WhiteWolf216 WhiteZephyr +WhiteZetsu Whiteboy016 +Whitecoast +Whitecrow Whitefire68 Whiteflashh Whitemambz +Whitetoes +WhizsuJr +Who Add +Who Nose +Who8mypaint +WhoDatDJ WhoDoICatch +WhoHaxdMe WhoLikesIron Whoa +Whoa Gaming WhoaKemosabe Whole +Wholelottabk Whomp923 Whomst +Whomst MD Whoratile +Whorrid Whos +Whos Jo3 +WhosUrDabby +Whosjason Whosyourmac Whothehell +Whruum +WhtKndofCake +WhteLilySeed Whuo Whurse +Whurse Meat +Why 8ank +Why Play +Why SkaR +Why Try Guy +Why are u ge +Why u N0ob WhyBank WhyCantIPick WhyIsRumGone +WhyNevaLucky +WhyRyan WhySleeping +WhyTryAtOsrs +Whyase Whydoubother +Whymcie +WhyteGoodman +Whyto +Wibbity +Wibbix Wibbleforce Wicea +Wichel +Wick3d Bet Wickaboag WickedKlowns +Wict Widdly Wide +Wide Client +Wide Vibe +WideBoyy +WideDommy Widmee +Widows Kiss +WiebMasterly Wiebah Wiebere Wiebren Wiebstar003 Wiegedood +Wielebny WienerWipe +Wierie +Wiesel Wife +Wife or RS Wifi +Wifi Beater +Wig Lops WigWacker Wigan WiganRS +Wiggety Wiggie WiggleMcTuff Wiggly +Wiggly Woo Wiggoth Wigins +Wihbane +Wihwy +Wiigg Wiiillllsonn Wiiize +Wiji Wijji Wijsheid +Wikas1337 +Wiki Flipper WikiLiex WikiWorm +Wikinger Wikingpedia +Wikked +WikuliK +Wilby Wild +Wild Bill 71 +Wild Clicks +Wild Cowboys +Wild Fury +Wild Orange +Wild Pump +Wild Raven Wild Rivers +Wild Spirit +Wild Squidi +Wild Stylez +Wild Whim +Wild chickie WildAbandon +WildGothGirl WildSF WildSnorlax +WildTokes Wilda83as7 Wildapple +Wildbasher Wildboy181 +Wildcard +Wildcatface +Wilde Bizon Wildfire Wildlands Wildly Wildmon +Wildy Back Wilk Will +Will Compton +Will Smif +Will T +Will i b +Will man +WillCosby69 WillG WillNight +Willasaurus WillfulNomad WillfulTiger +Willi William +William Way William2133 +WilliamChris Williamsburg Williamwrc +Williamwurld +Willianderma Williard Willicous Willie WillieP +Willlowsap Willo +Willoweeper2 Willowisp +Willsy_828 +Willy WillyMonka +WillySneeze WillyTickles WillyVanilly +Willyams Willymule WilmaCokfit Wilnafe +Wilpu Wilro +Wilso Wilson +WilsonBro WilsousGoods Wilters Wiltings +Wilwork4stuf Wilza Wilzy Wimm +Wimpy Hulk +Wimpy Worm +Wimpy127 Winanda Wind +Wind River +Wind the ham Windal +Winded +WindexWipes Windi +WindmillBoy Windowpie Windows10 Windrun +Winds Tormnt Windwaker Wine Wineapple Winedolphin WinexBlaze +Wing Daddy +Wing Reaper +WingToe Winged +Wingedlemur Wingednebula Wingknutts Wingless +Wingman Skre Wingmanfire +Wingmastah Wingnut Wingnut277v2 Wingoficarus WingsXIcarus Wingz Wink +Winner Chris Winner1Class +Winning Life Wintage +Wintaj Winter +Winter Slays +Winter Woede +Winter mage Winterpropht +Wintersaurus +Wintertarwe Wintertoad +Wintis WintonOS Winze Wipe WipeRZ +Wippy Spuds Wipzed +Wirbi Wirusas14 +Wis +WisCheez Wisdem Wise +Wise Andy +Wise Bloke +Wise New Man +Wise OlMan +Wise Old Guy +Wise Old Roy +Wise Pug +Wise Up +Wise9884 +WiseBlackMan WiseOIdMan WiseOld +WiseOldCam WiseOldNeef +WiseOldNut WiseOldSimp +WiseOldWench +WiseYoungOne +Wish +Wishen Wishidie +Wishies +Wishwandewe +Wishy Walshy +Wispa WispyWolf Wissfx1 +Wisundaz Witch +Witch Aileen +Witch Elf +Witchkraft +Witchprick +Witchz +Witeout LLC +With Skills Witha +WithoutAGe +Witicism Witkus WitlessFox Witness +Witte WitteLijnen Witteri +Wittu Wittytoad Wixsie Wixxa +Wiz master WizKaleeba WizKawifa Wizard +Wizard Weird +Wizard of Oz Wizard012345 +WizardFish11 WizardIRL WizardKing WizardMascot WizardSleeve +Wizardmatt6 Wizardspike Wizfujin Wizidross Wizreefer +Wizyweirdo +Wizz Z Wizzie Wizzti Wizzy Wizzypoop Wizzzard +Wkd Br0 +Wkedjester +Wkndr WlLDERSGEERT WlLL +WlLL1am WlLSO +Wlatt Wlsperingeye +WnB WnnB +Woadblu Woah +WoahDudeNice Wobbery WobbleyPOP +Woblin Wobos Wobs Wobufett +Wocka Wocky Wodka +Wodka Orange +Woe Woe Woedipoe Woemance +Woeppa Woes Wofford +Wofford2 Wohdii Wohrx Woikaz +WojoWins Wojtas WokeUp Wokkel +Wokki Wolf +Wolf Berserk +Wolf66 WolfApple WolfLucifer Wolf_Hunter Wolfazal Wolfboi70 Wolfboy1209 +Wolfden95 Wolfeena Wolferno +WolfgarrX +Wolfgarth Wolfhearth Wolfie +Wolfie Daddy Wolfiezzz Wolfinger +Wolfique Wolfjob Wolfman +Wolfman00777 Wolfmans WolfnBane WolframOxide Wolfshade Wolfshook +Wolfspeed Wolfy3777 Wolfz Wolles +Wolq poW +Wolverine V8 Wolvesy Wolwa WomanScorn +Womaz WombatLife +Wombats Wombayaga +Won Alll Day Wonderful +Wondo +Wonka44 WonkyShlonky +Wonn Wonnawonka +WonterJodt +Woo Hee +WooGGi Wood Wood Choppin +Wood Scimmy +Wood Style +Wood VI Wood4all WoodJablowm3 Woodcrest +WoodcutterQw +WoodenSword Woodland Woodsboro Woodson @@ -25279,31 +52113,57 @@ WoodsySmells Woody Woody540 Woody8 +WoodyBussy69 Woodys Woodz90 Woof +Woof Woof Jr Woofaire +Woofi Wooh +WookieBread +Wool Socks +Wool Tar +Wooli +WoollffMain Woolly +Wooo Blod +Wooody125 +Woooglets +Wooogy Wooooo91 +Woopie Doop Woopsx10 Woopuh Woord +Woorm +Woos Woosa Woot Woowoh Woox +WooxFromWlSH Wooz Woozie400 +Wophel Iron Word +Word Bird Word2urmum +WordCheck Work +WorkUkko Workahaulix Workath Workin +Working Man +Working Poor Workouts Worland World +World 46 +World 526 +World 61 +World Of Rat World345 WorldEndero WorldWarTwo @@ -25313,23 +52173,39 @@ WormInHeaven Wormeater66 Worms Worning +Worning Mood +Worst Herp +Worzo Worzord +Wosby Woshy +Woste Wostyn WotCee +Wotnel +Woudie Woul Wounded +Wounds Wourlow WouterMarni +WouterPils Woutertje +Woutertje 93 WowAUnicorn WowDerek +WowoW Woww Wowzer1482 +Woz X +Wozi +Wozol Wozzah +Wozzy Wqlq Wrackbar WraithSx +Wramn Wrap Wrap5 Wrath @@ -25337,11 +52213,17 @@ Wrath0fMath Wrathchildxd Wrathinsea Wrav +WreXham AFC +Wreck These +WreckAndRoll Wreckage Wreckanism +Wrecked Wreckfull Wreckin4Days Wreckon +Wreckonize +Wrecky Wreckzu Wrekdum Wrektem @@ -25349,139 +52231,283 @@ WrektumRalph Wrenny Wrigzer Wrijo +Wrinkle Meat Wripzi +Writing +Written +WrmFzy +Wroggi Wrong +Wrong Focus Wrot Wruumze Wryd +Wrynn Wsupden +Wtf Burgers +Wtf Bwana +Wtf Is Elmo +Wtf Michael +Wtf happen WtfJad Wtf_Stake +Wtfisabook Wtfxcreepy1 +WuLuZ +WuTangDan WuTangRs WuTangflame WubbaRs Wubj +WuceBrayne +WuckFeeaboos Wucky Wudkip +Wueu Wuhan Wulfeh Wulkanaz Wullets +Wulong Rush +Wumbolii +Wumox Wundy Wungz +Wunk +Wuntch Meat Wur1 Wurgon Wurj +Wurrior Wurstfest Wurtziite Wuteng Wutlife Wutru +Wutta Beast Wuuluu +Wuz H Wuzn Wuzzi99 Wwalrus Wwarlock Wxll Wxyz +Wy 1853 Wyan Wyard +Wyatte +Wybb Wybo Wyborowa +Wyd +Wydie +Wyel +Wyiphi Wyldar WyldeKirito Wylie Wyliecoyote2 Wylyne Wynand +Wynmao123 WyoFletch WyrdStoned +Wyrlor WyvernBreath +WyvernMage WyvernSlayer +Wz Karmish Wzurd +X X V +X 0H +X Axis +X Bullet X +X Dsmith X +X E L E X +X E R 0 +X Ecuted +X I L E +X Ice Break +X Japan +X King Jehu +X Landie X +X Mars +X Mathiew X +X OUT OF RS +X Robert X +X Rorschach +X SUR X13 +X Seabridge +X WAVE 70 X +X Y P O +X e x i m +X pelz +X-Jabs +X-Man +X-SVNTH +X0N3X X1xfa11enx1x +X65 +X9Y XAAXAA +XANSEB XARlQUE XATHD XAyYxlMaOxX XCShark XCortezX +XD XDDD XD XD8D +XDQ XDamage XERTNARG +XESPIS XEback XFitVapeVegn +XHCD +XI J +XI5 +XIBT +XIX Zeta XIX +XIXIXIXVXIVI XIXXI +XJT XKappaX +XL Peen +XL Succ +XL itikka +XMR XNovaCainX XOBLIN XORB +XP All Night +XP Hobo +XP Jake +XP Thieving +XP for gains +XPOQ +XRP Glandorf +XRV +XRay Mike +XS3X XSandwich18 XSapocalypse XTCarlo XTIF XUJ0RKI XV73J +XXGrimorgXX +XXTENTACI0N +XXaan XXera +XZoTicTB +X_Ouchies_X +X_Streetz +Xa1e Xaaan +Xaberphel +Xadia +Xaeram Xafirox +Xahp +Xaint +Xalastar +Xalcvs Xalrir +Xam Renz Xambitz +Xamphion +Xan Gogh +XanaxXR +Xandahr +Xandayn +Xanefeo Xanfan Xann +XanomaliuX Xanq Xanthophylle +XanthousKing Xantiasto +Xar Xarigue Xarious +Xarkus Xarnathos Xarov +Xarpus Decay +Xarqn +Xartes253 Xaryn Xasdaxs XaskiM +Xasthur Xatar Xaud Xaussiemaulx Xav777 +XavieerL Xavieerr Xayrus Xazz12 Xbalan Xbogaerts Xbox +Xbox Account Xbox kid 99 Xboxkid33 +XcL ady kila XcalenX Xcalumet Xcelorin Xcuuuse XeNeaxaxa +Xebstrika Xecki +Xedoria Xeem +Xeet +Xefi +Xefn Xelas Xelcab Xeldin Xelian Xelzathar +Xemnax +Xems Xen0phyte XenaDior Xenastry Xendel +Xenece Xenethos Xenfire +Xeniat +XenithStar +Xenlon +Xennofobia +Xeno X Human Xenofiel Xenofile Xenoforms +Xenorith XenoviaZhao +Xenria Xenses Xentric +Xentric I Xenzah XeoX Xeqo Xeretus Xeric Xerics +Xerics Exile +Xerics Solo +Xerile +Xerkom Xerloz Xero XeroBlitzAce @@ -25491,14 +52517,25 @@ Xerona Xeroscape Xerosenkio Xeroso +Xerphias Xertrius +Xerxe Xestox +Xetarillos +Xewne +Xeyler Xfebruari23X Xflowerz1 Xgen2004 Xghostbx XgodofironX +Xhaloz +Xhq +Xi Bogan iX +Xianerth Xiang +Xiang Ying +Xiao Wei Xick XicoDoAnzoL Xidos @@ -25506,19 +52543,37 @@ Xielt Xiff XigZig Xiglaan +Xijaxer Xilamz Xillious Xilphy XinXani +Xinbonddon Xinck Xiom +Xiphoz +Xipi +Xipo +Xirenia +Xists +Xityx +Xiuol Xizor +Xizxuka Xizz +Xj Driver +Xl Pat lX +Xl Tango lX +Xlarss +Xlogmore +Xmas Santa +Xmasvibes Xmerl Xnam Xname4 Xniklaz XoXdr34mzXoX +Xofal Xoir Xojix Xolca @@ -25530,319 +52585,739 @@ Xoobs Xorphas Xorx XoutofRunes +XpTitan +Xpect2die Xpelz Xperiencer Xplay2slayX +Xplicits +XploitClamps +Xpm +Xpreme +Xqcksilverx Xqkiller Xquick +XrRipple Xsk1l3rX Xskillz XslayerkingX +Xsy +Xtan +Xterioz +Xternal VZ +Xteven +Xth +Xtian Xtopheris +Xtreme Kill +Xu +Xu3 +XuRuP1Ta Xufo Xuhe +Xulaa Xulreh Xupafion +Xuro Xutera +Xuxe Xuxy97 XvalQ +XvalentiX XvegetaX Xvim +Xwb Xwoprl +Xx A ll y xX XxBABY +XxBriDGExX XxCoponerxX XxJIMBUSKID XxKaakkimusx +XxMOPExX XxPoliSwagxX XxRXZ60xX Xxhel +Xxpyroxx20 XxrigourXx +Xxsagexx30 +Xyagrius +Xylarium Xyler Xylr +Xylym_pilot Xymox Xynamic Xyrath Xyresic Xyryu Xyzcanon +Xz8 Xzavier Xzil +Xzpect +Y DynHaearn +Y Fx +Y O D A +Y O K A I +Y arok +Y ellow +Y em +Y ogo +Y oshi Y0N3 Y0l0mees Y0usless +Y2K38 +Y2k Survivor Y3RBA +Y3w +Y4P +YBank_Mak 69 YCTH +YCantPigsFly YChewyYOS +YEEEZY YERTII +YExTI +YGBigTank +YKW +YM +YMJFL +YNW Kushy YOKiki +YONGWOLRANG +YOOOH JOEE +YORJ YOTJ YOUR +YOURMOMSMAN +YS3 +YSL +YSL for Life +YSinpo +YTPO YTrySoHard +YUSEF +YWM +YYST YYose +Ya Boi Suff +Ya Boy Lachy +Ya Boy Ryan +Ya9 +YaBoiCrisps YaBoiSlip YaBoiWestie +YaBoiiQuan YaBoyCosmo +YaDoons YaLilMupp1t YaOldHeffer +YaSillyRAT +Yabai +Yabbary +Yabbie Pump Yaboiskee Yaboitrek Yaboku Yabui Yachi Yachiri +Yackill +Yackity Yak +Yackley C Yagyu +YahRamen Yahe +Yahtz3 Yahtz3e Yahya10100 Yaik +Yaimzz +Yak Elves +Yak of Iron YakYak +YakimaValey +Yakka Stacka Yakosu +Yakushima +Yakuza +YakuzaDragon +Yalazar +Yall Raycist Yalloune Yalomi +YamR6 +Yama XCII Yamagata Yamakato Yamata Yamda Yami +Yami Bakura +Yammed Yampay +Yampay II Yamsaretasty YanKeDooDle +Yand0 Yang Yangtze Yangus456 Yani +Yanilla +Yanilla Kush +Yank on This +Yankee Run C +Yann78 Yannick177 +YannickH Yannis +Yao Yo Xin +Yaossynx +Yaprakdal +Yardi +Yarfn Yaribel Yarne Yarny +Yaseki +Yasen 105 Yasuos +Yasuuo Yato1God +Yaukai Yauz Yavrum Yawan Yawgg YawningPanda +Yawp +Yaxfe YayItzTyler +Yaysuo +YazanBates Yaziro Yazo Yazuki Yberi Ycinho +Ydmyk Ydorog Ydrasil +Ye Magekilla +Ye Mate +Ye Olde Ace +Ye Olde Ned +Ye Olde Oak +Ye ti YeBankWicked YeBoi +Yea UrBanned YeaAiiiiite +YeahIMineIM +Year YearUp YeastPocket YeastyPussey +Yeblehs +Yechs Yeda YeebusGeebus +Yeeeeehaww Yeeetist Yeeetscape +Yeern 101 Yeeska +Yeet Dan +Yeet Thyself YeetMemes +Yeeted One +Yeetu +Yeezy YefTalks Yefim Yehtii Yeiw +Yek Yekhsad Yekouri +Yeland YeldariIII Yeli +Yelling YelllowFlash Yellow +YellowForest +Yellowfox21 Yellowhoody +Yem o +Yemly +Yemrisnen +Yenie +Yenil +Yenofthunder Yenom Yentelke1998 Yeoubi Yeoz +Yep Cup +Yerbal Tea Yerd +Yeren Yerico Tsu Yerkinoff +Yerm da worm Yeroen YerrBanned +Yerradu Yerrrrey +Yes Click Me +Yes No Maybe YesOk +YesYesYall +YeshuaShalom +Yeso Pro Yessir Yesze Yetagaindied Yeteri Yeti +Yetiburger +Yetlon +Yetsu Yettiez +Yetzne +Yevop +Yevral +Yew 2 +Yew Burn +Yew Root +Yew Tree +Yew Wu +Yew a sloot +YewEssBee +YewGnomeSayn Yewcutter Yewise Yewna Yewp +Yews pnas Yewsanity Yewse YexaC Yezzi +Yfer +Yffud Gnik +Yggdrasverre +Ygh +Ygritte8686 +Yharnam Soul +Yhul Yiatse +Yid +Yidy +YikesScooby +Yilver Yimo +Yinlin Simp +Yippe +Yippiyak +Yisabela +Yja +Yke Ykeykey YlFF Ylikivaa +Yllattyneet Yllig Ylmn +Ylpistynyt Ylulawo +YmanThe1 Ymbyydi +Ynastra +Yne +Yng Xehanort Ynka +Ynun +Ynza +Yo Caspian +Yo Griff +Yo Its Devo +Yo Kev +Yo L +Yo MyUSD +Yo Soy Dios +Yo lm Lee +Yo uu +Yo wyd Yo2021 +YoCerberus +YoGurttt YoHighRoller YoHimiiTsu YoIronManBtw +YoKristaps +YoMomsFavBF YoSinNow +Yobew Yocan +Yoco Yoda +Yoda Adf +Yoda Corona +Yoda NSZ YodaEvans +YodaPen +Yodamainn YodasNo1Fan YodasYoda +Yodasquad Yodati +Yoder +Yoerias Yoeshua Yofang Yoghurtis Yogi +Yogi DMT +Yogi Surfer Yogololo +Yogusun Yohny Yoink +YoinkYoink Yojak3 Yokie Yolkysky YoloSwagHope +Yolp +Yolvert +Yomaku YomamaPro +Yomashu Yomdo Yondu +Yondu Poppin +Yonemid +YongZhong +YongZonnegod +Yonkers +Yonko Buggy +YooDuragon Yoodish +Yoooord Yoorah +Yor Yorga Yorick Yorick095 YorickMorty +Yoriichan Yorinky +York Rite +Yorkson Yoru Yosep Yoshi +Yoshi Man17 +Yoshi Suyumi Yoshi6380 +YoshiThick YoshisStory +Yoshiwaptor +Yoshizilla +Yotaak +Yoteii +Yotsuya Miko +Yottie +You Are Zach +You Be Love +You Die71 +You Ok Fam +You R D3d +You rc 2 +YouGotRoll3d YouGotSeabed YouNeverKnow YouOverThink +YouSuck YouWontScare YouareGE Youbartonz +Youme +Youncies Young +Young Bucket +Young G4 +Young Guthix +Young Krazed +Young Logic +Young Mooch +Young Mullet Young Tango +Young li +YoungCatFish +YoungNoot +YoungScuba YoungThugga +Youngdaddyg Younge +Younglleff +Youngn Youngsters Youngvet Your Your Amity +Your Future +Your Idol +Your Misery +Your Mom67 +Your Mothers +Your Toilet YourDadIsMe YourFrenRen YourObsessed YourPaperm8 YourSolution +Youre Joshin YoureAllTalk YoureIgnored YoureMySam +YoureSoCool Youssef +Youthful +Youtube Luck Youwillcower Youxi37 Yowarrior40 +Yowch Yowzer Yoxz Yoyaaaaaaaaa Yoyo Yoyo502 +Yoyoma007 +Yrasa +Yrdna +Yre Yrjo +Yrok +Yrrabo +YsL Dom Ysdragos +Yshtola +Ysr Yster +Yster Bunny +Ysuke +Yu Seolha Yu Stinkipu2 +Yu Zi Jiang Yubs +Yubz +Yucan Tucan Yuck +Yuck Aroma YuckFou YuckMouth +YuckNoYums Yudi Yuengllng +Yug Cipe +YugiMoto666 Yugioh +Yuhai Yuigahama +Yuiii Yuiku Yuipster +Yuka Takaya Yukaiaiaiai +Yuki Kitsume Yukika Yukionna YuliusCaesar Yulong +YumYumSauce +Yuma az +Yumaad Yumbo +Yumhumgao Yumiko Yummy Yumped Yundastan +Yundruh +Yuneekh Yunery Yung +Yung Belial +Yung Birdie +Yung Deaner +Yung Nice +Yung Swoosh +Yung Zach +YungDuski +YungIron YungMoistGod YungPredator +YungSlick YungThimothy YungTungsten YungWhiteBoy Yungsik +Yungsingteng +Yungyonder YunnT Yuno +Yuno Yuno Yunozen +Yunq Yunthers +Yuoni YupImMadBro Yupal +Yuqi Dab +YuqiShuhua Yurimo Yurix +Yuriy Yusaris Yusko Yutorgborm +Yutzz Yuudachi YuugeJohnson Yuuki Yuuma +Yuuuuurd me Yuuzu Yuyevon2003 +Yuyu Shirai +Yuzumii Yveaux Yvno +Yvoa100 Yvon +Yvuar +YxY Yxskaft +Yzanagi +Yzap Yzyszn8 +Z 0 D I A C +Z 84 +Z A D O +Z A R G O T +Z A V Y +Z Barrows +Z E R0 +Z I K O +Z Jay +Z M P +Z O R 0 +Z O V K O +Z O ZO +Z Rowz +Z a a K i R +Z aeBae +Z e e e f +Z e x +Z ebak +Z edd +Z erkie +Z ev +Z i g g e h +Z igZag +Z ion +Z y g y +Z ygis Z-TheReaper +Z00STER +Z0K0 Z0MBI3 +Z0MBIFIED +Z0NK3D +Z0RB0 Z0bbey +Z0deac Z0ops Z1pn Z1pn_xD +Z26 Man +Z3 +Z3FRAN +Z3R0 CO0L Z3ds +Z3ymour1 Z4phy +Z4ppie +Z6L Z7Z7Z777ZZ +Z900 +ZACCU +ZADDYGANG ZALCANOPET ZALGlRlS +ZAQWRY ZB84 +ZBLOCKA ZEIVI ZEKEDAFREAK ZELDRIS0 +ZER0 EHP +ZER0Z +ZGJ +ZHG ZIARED ZILLER +ZJ +ZL1 Devin +ZLA +ZMB Scary ZMithrilMan +ZNDX +ZOEY 101 FAN ZPWUZZLED122 +ZRegi +ZSYD230207 ZUCK +ZUK EXPERT ZUwUBI ZWUNK +ZWlFT +ZX +ZY +ZZ +Z_Z ZaPhiRoxD +ZaadTeef Zaane Zaanstad +Zaatar Zabe +Zabey Zabini +Zabky Zaboxi ZacAynsley +ZacBallsHard +ZacFx +Zacariah D +Zaccchhh +Zaccy Zacflame Zach +Zach 6464 +Zach Patino +Zach est13 +Zach q p +Zach07 Zach314 +Zach4211 Zachagawea Zachatank Zachawy @@ -25852,38 +53327,86 @@ Zachs ZachsAccount Zachulous Zack0ry +Zack504 +ZackAsch ZackSparrow ZackWasTaken +Zackary +Zackle Berry Zackly Zackman Zackology +Zackree +Zacky P Zacoron +Zacxion +Zaddy Bully +Zaddy Zo +ZaddyCool +Zadek Zadior Zadok +Zae +Zae The Bae +Zaenil +Zaeres +Zaf Zafaron Zaff +Zafrot +Zaga911 Zaggly +Zagustin +Zagz +Zahard Army ZahellGlarus Zahellina +Zahiirr Zahnae +Zahrani +Zaion Zairin Zairx Zaitsev Zaixii +Zaixyyuu +Zakhary +Zakje Pep +Zaku Rs Zakz +Zala +Zalaberto Zalar +Zalat Zaleander Zalen Zalerae +Zalotus Zalphyrus +Zalse +ZaltyPretzel Zalux +Zam ZamPeZu +Zaman Zamanr Zameul +Zami Zamianx +Zamicxus +Zamirok +Zammiy Slay Zammy ZammyHasjta +ZammyJesus +Zammys Flame Zamorak +Zamorak 61 +Zamorak Book +Zamorak Tome +Zamorak808 +ZamorakBrews +Zamorakz Zamorangue Zamorizzle Zamowrecked @@ -25897,225 +53420,461 @@ Zandous Zane Zanfew Zanfis +ZangKeera Zangola Zaniels +Zanimoto Zanithic Zanity +ZannyBatsbak Zanryu +Zans Zansus Zantaril Zanwk +Zanzu +Zaom Zaon ZapWasTakn +Zapah +Zapatos +ZaphiasTM Zaphyan +Zaphyrim +Zapii Zapio Zapky Zapleno Zapletics +Zappaforever Zappman123 Zapppy +ZappyLand +ZappyWabbit +Zapsticle +Zaque +Zara Mobile Zaraffa Zararod Zarasth Zarathos +Zarchonias Zardee Zardua +Zarf +Zarfa +Zargole +Zariah +Zariky +Zariser +Zarke +Zarkh +Zarkino Zarkoz +Zarley Zarliona +Zarmos Zaro +Zaro M +Zaroki Zaros +Zaros2k +ZarosCorrupt +ZarosRex Zarosadomin +Zarosian Rat +Zaroux Zarov Zarpedon +Zarrix +Zarude +Zarvern Zary +ZaryteKnight Zasi +Zasilus +Zastava Ak47 +Zastavo +Zatailex Zatch175 Zathul Zatom +Zattix Zauberbiest +Zausbaus Zav555 Zavaren +Zavikk Zavilia Zavinor Zavorak +Zavvia +ZavylonCG +Zawro +Zawts Zaxbys Zaxcord Zaxm1 Zaxxxsoldier Zaza9119 Zazian +ZbraCakez Zbychu +Zch +Zcj +Zcu +Zdawg +Ze Golo +Ze Own +Ze Punheteir +Ze Ubernoob ZeOblitz +ZeProx +ZeQuYaa +ZeZienMaar +Ze_balla Zea1ous Zeal +Zealandra Zealea Zealicious Zealoe +Zealous Love +Zeals Max Zeather +Zeb Slays +Zebak +Zebak Acid +Zebaks Jugs +Zebedank +Zebede Zebest605 Zebras +Zebs main +Zebs scuffed Zebu Zebuck +Zecca Zechuchith Zect +Zed7 +Zed_11 Zedanko Zedar Zedd +Zedd UwU Zedd180 Zedek Zedirex Zeds +Zedz ZeeAyyBee ZeeEL +ZeeZeeZee Zeebers +Zeec Zeedith +Zeehox +Zeeke Zeekheart Zeelmaekers +Zeemoee +Zeeny +Zeeon +Zeep +Zeepra Zeerkel +Zeeshan Zeeshan01 +Zeeuun Zeeuws +Zeeuws Tuig Zeeve Zeeyk Zeezki Zeffe +Zefrank +ZefyX3 Zegetable +Zeh Zimah ZehThijs Zehbu +Zehf +Zehiret Zehv +Zeilex Zeinovyah +Zeious +Zeitgaist Zeithex Zeken +ZekimusPrime Zekje Zekkels +Zekley Zeko01 +Zekrom ZelaooReturn Zelatrix +Zelcano Zelcode Zelda +ZeldaHaxor42 +Zeldamen Zeldaza +Zelle Me GP Zelnite53 +Zelroy2 +Zelten +Zelzoy +Zemiak +Zemie Zemix Zemmy Zemoko Zemps +Zemyrrah +Zen Moments +ZenBtw +ZenRaidz +Zena96 +Zenathrius +Zenci Zenearys +Zenemz +Zenez Zenfor +Zeni Master Zenithina +Zenitsu +Zenium Zenki +Zenki RS +Zennyte Zeno +Zeno Pho Bia +Zenoce Zenpep +Zenqii +Zenqs +Zenrrrr +Zensai +Zentae Zentra Zenytum Zenzulo +Zeon Clone +Zeorun +Zeos Zeoth +Zeou Zeoxr Zeph Zeph0s Zepher138 +Zepherahs +Zephere16 Zephrinne +Zephxa Zephylius Zephyren +Zephyrhills +Zephyric Zephyrot Zeplin1 +Zeppelin IV Zer0Requiem Zer0Tw0 Zer0mancer ZerUmh +Zeratul259 +Zerbeh +Zerberous +Zeref Zerendipity +Zergonaut +Zeri0n ZerkByDay ZerkInDaYard +ZerkMeOffPlz +Zerkeee Zerker +Zerker fe Zerkism +Zerkom Zernag Zero +Zero Cals +Zero DeNiros +Zero Saber +Zero Scope +Zero Suit +Zero Talent +Zero Tol +Zero Zeros Zero92922 ZeroAltruism +ZeroBodies +ZeroCake ZeroDignity +ZeroFox8576 ZeroGravity3 ZeroHour +ZeroHpAgain +ZeroTheKing +ZeroValor ZeroXJD ZeroZero Zerobeat Zerodareborn Zeroeagle +Zeroen +Zerololz Zeroly2 Zeroswift Zerq Zerrilis Zerro +Zersers +ZertUwU +Zerx +Zesima Zeskater Zesty +Zesty Bvrnsy +Zesty Senpai +Zesu +Zet_RS Zetani Zetardo Zetore Zetreker Zetrus +ZetsuboSekai Zetsubou Zetta Zettty Zeug Zeus +Zeus Jr +Zeus07 Zeus09 Zeusvdl +Zeven Zeveria +Zevlim Zevosh Zevvo Zewx +Zexma +Zexra +Zexual +Zeyora Zeyzima +Zezaroth Zezergz +Zezima Simp +Zezima W q p +Zezimaislife Zezimas Zezime +Zezus +Zezynx +Zfg Fan Girl Zfsalt +ZgeL Zgrite +Zgzi Zhacarn Zhaoyl Zhava Zhinky Zhiqth +Zhonny +Zhops +Zhotaro Zhqith +Zhuxiong Zhuzh Zhykiel ZhyloFlex +Zi P +Zi1y +ZiNikor Ziauze +Zick Licker +Ziclone Zidi Ziega +Zierikzee +Zigfrid +Ziggey Ziggurattus Ziggydog7 +Ziglar +Zigory Zigzagoonfmt Ziicatela +Ziidz Ziinc Ziincor +Ziisus69 +Zijwiel Iron Zikry +Zil o Zilandraa Zilanthra Zilex +Zilexion777 Zilly ZillyLovesMe Zillya Zilpha Zilvia Zilyana +Zilyana Gr +Zilyana Jr +Zilyanas Dad +Zilyarma +Zim Zim8 ZimFlare0003 +Zimak +Zimaterasu +Ziminiar +ZimnyZielony +Zimpathizer Zinc Zinct Zing Zingg Zinixon Ziniy +Ziniyy +Zinnialexis Zinogre Zinoto +Zinryia +Zinshaw +Zinsmaster +Zinsmeistro Zioh Zion +Zion Fire Zioo Zip Lynx +Zipacna Zipit +Zipm Zipo259 +Zipp0Fluid Zippeeee +ZipperTrout Zippy909090 Zipsap Ziqs Zireal +Zireb ZireneV2 Zirkisi Zirn @@ -26123,74 +53882,143 @@ Ziron Zirrub Zirvzaa Zisam +Zitaya +Ziti Sauce +Zitri Zittte +Zivile Zixcon +Zixon Zixxen +Zixxty Ziyai +ZizZazZuz Zizarius Zizou Zizzle +Zji +Zjoelini +Zkilrr +Zkyui ZlGGEY ZlNQK +ZlZl Zlap Zlatan +Zleek +Zleepeey +Zlig +Zlomble Zlote +Zlug Zmancool Zmanonthego +Zmazek ZmaziWasHere ZmbieShepard Znked Znorox +Zo e y +Zo m B +Zo nk Zo7al Zoak Zoanthids Zoaxyl Zobbe +Zobny Zoca +Zoca BD +Zodden ZodiacIsTed Zoeh Zoet Zoey Zofad +Zofu +Zogggii +Zoggy Marley +Zogloid Zogurk +Zohi +Zoik Zoil +Zojun +Zok +Zoka Zolarf +Zolaris Zolcome +Zoli +Zolkaria Zollo Zolon Zolrisma Zolruh +Zolt09 +Zoltan Uk Zoltanious +ZolwoZ Zombah +Zombi Zack Zombie +Zombie Cody +Zombie Zack Zombiezparty +Zomboide +Zombrons Zomi Zomimi +Zomp +Zone Red ZonichGG Zonir +ZonlyAlex +Zonnedael +ZonoxRS Zonse Zonum_Knight +Zoo Orleans +Zoo scape +Zoobloo7 +Zookly +Zool +Zoolander Zoolander011 +Zoom Zooming Zoommaster97 +Zoonix +Zooted Zoppy Zorb49 Zorblet +Zorcar Zoret Zorg Zorh +Zorie Zorin +Zorkath +Zorkz ZornDurag ZoroRoronoa Zorolith +Zoros son Zorrac Zorrita Zorros Zoryov +Zos +Zosc +Zossssssssss Zostok Zoteize Zotetz Zoudrex +Zoumok +Zouns +Zown Zowski Zozma Zozo1232 @@ -26198,54 +54026,116 @@ Zpizz Zqw6 ZrankerF Zrax +Zriv +Zrr Zsedcx +Ztneff +Ztxch9 +Zubaritis Zubora +Zubsolv Zuburus Zucchini3 +Zuchini +ZuckZyZock Zucu +Zuel +Zuened Zuggster +Zugmah Zugs Zuibbi +Zuiox Zuipe Zuipen Zuipvlek +Zuk +Zuk Bot +Zuk Cucker +Zuk Meh Off +Zuk My Toa +Zuk Sucks +Zuk a Duck +Zuk a Zik +Zuk at 1 Kc +Zuk my Tzok +Zuk was here +ZukDisLilZik ZukMadic +ZukMyAss ZukOrBust +Zukala Zukmos +ZukoTheMcoon +Zul-Bot Farm +Zul-tul +Zulandra Zulax Zulex Zullander Zullrah Zullu +Zulrah Goat ZulrahSlave Zultora Zulu ZuluLippen +Zum Zumaz +Zumaz Her +Zumb ass +Zumwalt Zundaddy Zundix Zunkrah +Zup Rap1 +Zurad +Zuramaru Zurcal +Zure Kut Zuremate Zuriel Zuriel321 Zurius Zurkzes +Zurlofix +Zurn +Zurper Zurqos +Zurthur +Zurvan +Zurxas Zuubi Zuuqe +Zuurkast +Zuv Arik +Zuviel +Zuwy Zuxar +Zuxf +Zuxi Zuzad Zuzas23 +Zvg Zvirbulis +Zvotne Zw3d Zw4rtjoekel +Zwabba +ZwangerePapa Zwanneke +Zwartbeast Zwartbest +Zwarte Iron +Zwarte dief +ZwarteAapMan +Zwartehand Zwef ZweiBeer Zwei_02 Zwerky +Zwette Draak +Zwieber Vos Zwiers Zwift13 Zwijg @@ -26254,65 +54144,152 @@ Zwimps Zwinter Zwlr Zwwwnbeast +Zx J3SS3 xZ +ZxFe +ZxbeeRs +Zxeon Zxirl Zyad Zybes +Zyck o Zydecolarry Zyer Zyev Zygalo +Zygameux Zygy Zykaite Zykonic +Zyl Zylco Zyleta +Zyliana +Zyllami +ZynGardener Zynerith +Zynnocent Zynthe Zyntixero Zyper89 +Zyrem +Zyrinth Zyrok +Zyrona Zyrpex ZyruviasDied +Zyunkko Zyxla Zyxuz Zyyra +Zyz Zyzziima +Zyzzy +Zyzzz brahh +ZzJ0SH Zzanoss Zzayo +Zzuma6 Zzyzzx Zzzax Zzzd ZzzzG +[#OA0VWICQ8] +[#SG1JGUXTW] +_Untrimmah +_gria +a Cairn +a Dang +a Mikey +a Miko +a Venenatis +a Venny +a Weeman +a bean +a black cod +a casul +a cooky +a cool bug +a eu +a f o +a gentle sir +a little sad +a ndo +a p p l e +a pathetic +a pb +a sad kraken +a sad waffle +a sk y +a the sniper +a tnQ +a trash cat +a zo +a-x51 +a07 +a1liez +aDome +aDuNaz aGamerGaming +aGamingDad +aGlasgowGrin +aGoober aIIfather +aKSU nPC aKash20i3 +aMiniDude aMiniGorilla +aMiniHitMark +aNERDYsloth +aNStarFury aPinkBunny +aPinkKitten +aShavedLlama aSnowTiger aSunnyPotato aSwiftyBoi aThoms aTinyChimp +aVolk aWildSeal a_SaladKing +a_duncan +aa noob +aaah aaahChu aalucard +aanmaken +aanwaz1g +aaron_diaz aaronparkerr +aatudoz aaty ab0u +aballer09 abbruzi +abbruzie abcz abdi abdimajiid abdulllah abis +abk144 abni +about blank +abqve abra238 +abrakadabraZ +abray +abu hassani acceleratism +ace375 acecoffee2 acerkush achillies +achillies zy +achinadav +achterkamer acidshit +actionbob actlater actofvalor24 acuile @@ -26320,41 +54297,78 @@ adPEXtwinDnG addaaam adem6792 adizzle444 +adogg0323 adopt adrian adsdadasdgtd +adsh55 +adue adul +adul t +advia +advies +advit +aeej +aeggefar aejfd aenpaa aezthetic1 +afatslug aferraro +afh +afk 2 2277 +afk a bunch +afk n doc +afkayscape afkdontattac afkingRS afkvsehp afkwarriorzz +aflk afraid2boss afraid2boss2 african aftrthxght +afzi agent_of_fox +agentdd_4 agfdbzIM +aggain agic +agieee agoraphob1a +agrovation agsmanpro11 +agytagtyewaq +ah oh uh ahahah ahippi3 ahokusa ahrlhyrslylh +ai eye q ai3i42Iaaskl +aiden m8 aidibohx +air strikes +airborn frog aito +aitoBeruna +aiwodas +ajiffniff ak47afghan1 +ak47ags akaExploit akaNorman akae akbennyboy +akeep +akidnamdjrmy akipf +akirahokuto +akkha kum akleb +akq +akspew aksta aku aku1212 al0x @@ -26362,82 +54376,139 @@ alabasta1 alabthemoola alans alaric +alaxam +albersson albiguerra albioon alchetraz alders0n +aldi warrior aldrichmax +aldrichs alecbeats aledank +alexjberroc +alexlangman alexs99s alfafa20 alfhershey algotrader +alias ilias alic3 alimpweenus +alipandh alittlepig alkaizerx alkkis +alkkis pk +all en +all love man +all to 200m +all4four20 +allcaps +allebylund +allenbb3 allez allluminati +allomax3 allora76 allowitplz allzeras +almoggar +alpacathund1 +alpacka toke alpalmchal alpha alphabosss already also alsobosspros +alt f4 gn +alt maxed +alt rite alt0n +alt2kil +altairanezio altehnub altforusa altiarblade +alvexn ltu alvinhic +always win alwayscurius alwrighty +am sam +am so sleepy amagna amay +amfoine +amheeh +amikiri ampharos61 amputated anasacez21 ancapistan anchor +anchor seb +ancientskye andhetakes andhim +andmcadams andreable andriuttt +andtony +andynew2007 anelebar +angel995 angeline1711 angrydump +aniki chan anime +anime member animeF3tish animegirl73 anizan +anklez ankou4smokin annie +annie r u ok +annni annull anoldfatdude +anon1606 +anotha 0ne +another gay anti antibully +antituuri antivaxer antombomb anttimage3 anxiousbeef +any1 anygirls +anyma +ao aocha +aod retired ap1ska +ap3xOo apacifist789 +apcays apeman8731 apenzoon +aperts aphr0 +apikeppa apina apiph3ny apou appelkneuz applee +aqp frog aqqqqqqqqqqq aquafx +araenel13 aratsanus arcane archyiop @@ -26445,342 +54516,692 @@ arcvnaxiii arcwriter ard lad 06 ardazz +ardy guardy arengs +arevles arexmeister arfih argilah +ari abdul +ari shaffir ariman22 +arkoudaphile +armadyyyyldo armyofkids +arnr +arocardo arookie +arouze arreydn arrowbob2 +arrows2ashes +art possible +artaax artan arteefact +arth urr +arthadeos arthurdebart +artist_60 +artizia +artogoes arvothepure arzier ascipulus ascott1 +asdafsdafsd asdasdasdf1 asdsdafsa asedviss asfand ashster25 asian +asianbunnyx asibioass +asidb +asm asmoooo +ason jones aspiraring1 asrdftgffdsh +ass chance +ass jiggles assaultvests +assbergerler +assdrag +asseaterbtw assoffire +astgferallah asuhcuh +at0 +atob7 atoma619 attaaM attack2much auditore28 audrey +audrey horne auma +aus j osh +aussieyobbo +aut AT5 aut1st1c autism +autisticboiz autumnbound +av av av8bgo +avantoeftish avewy +avg Jake +avg gov ee +avg idiot +avikntos avmech31 avocabo awple +aww fk +axeleebob +axeli +axetoons axoblaster axperson808 ay96 aydrian +ayeetbix +ayhank aynull +ayos ayo +ayrball +ayshinx ayte ayvz ayyreynolds +az3r bulbul +azerke azilim +aziz8mohd +azj azura +b a g +b a l r a j +b b o x x +b eeg +b enjy +b ezos +b i g s t +b kuz +b l u rr +b oe +b on ass +b oo n +b ooth +b u l +b ulba b-ray29 b00ty +b00tyw1zard b0btehcool +b0dybilder +b0gadu +b0nelesstofu b0rn2grill +b0urb0n_kid b1ackcoxdown b1apoody +b2bpurple b2bs +b33 rabbit +b39 b3cc b3kiy +b3rgo b4Mb00B0NGG0 +b4iforget b4nyluckypvm b5 s4 0000 bIack bIrkaoff bLeatzker +bMat95 bSteeezy bVibin bZabii +ba1tti +baIIs3 +baami +babewatch babstah babugo baby +baby peb +baby peba babybuffalo babygirl +bacbacbacbac +baccybaxter backseatrs bacodie +bacroonX +bad bee +bad boy602 +bad british +bad data badalts +badass1337 badat3tick badcold611 +badderjari +baddspella +badger fan 7 badsadmac +badtechnique +bag milk +bagans baglokale bahumat baile +baile y baitmem8 +baj69 +bajadam bajj +bak3d bean5 bakareru bakesome bakkerbtw +bakplaat11 balding +balisongg +balkare ballenbak +ballerbebbo +balsson +bam bam-BA-lamb +bambera2 bamfhitman bamsi banana bantrok +baraho barakozle +barcrestboy bard006 bardj +baritone888 +bark bark +bark f0r 0ff +barkirion rs barkmeat +baron nash +barou barry +barrybacon +barrysdad barryslet bartelbarel based +based af +bash the rat bashong basic basically basiel +basispiloot6 bassdrum bassfortexx +basspro76 bastukid +bat flack di batchela batdog183 bates batje vier batseflats +batterym1es +battlebus33 +battleman36 battried +baumannii bawky bawsi +bawz zaa +baywest +bazjunior +bbALL +bbb bbest bblood bbones bboyalec bbtarget +bbully +bc22 bcguppy +bck2kickass bcollier94 +bdb +bdw reborn +be one +bean flick3r beanbag173 beanieton beanskunk bear +bear66881 +beard3djesus beardZy +bearia +bearitimus bearjack +bearplusiron beatthebot +beaver 5 +beaver 9 +beaver win beaverboy47 +beavitte bec0me +becarius +becca boooo beckles96 +bedabin247 bedburn bedtime beech beeelake beenus42 +beer sweats beggar +behaardezak belanin belgibeer beliver96 +belizianos bellatarius +bello0 +belub bemw bendy +bengnomonkey +benisbutts69 benjabii +benjimin benjiswaggod +benlovesyo +benrj91 +benroxo bent benyatta1 berd007 berkut87 berrytrials +berseke1 +berserkbear +berserkku bertucci2575 berzerks +besouley +best bojji +betleejuice betonimuna +betty wu +beverlly beverwijk bevh +bevsteve +bff +bfxrturbo +bg s +bgs ownez +bhicks bhuffs3434 +bibilush +biccc bicycle666 +bidls bidof bieltanman +biffsy bifket +big bad jon big bojangle +big gay ig +big gmbino +big head +big man shaq +big rart +big snood big tree 63 +bigbadheskey +bigbig horse bigbigbone bigblade28 bigbluntbrnr bigbologna31 +bigboybarlow +bigboybrips +bigboymansir +bigbud bigchoocher +bigcuff bigdbandioto bigdoggtrock +bigdoinks42 +bigg bud biggest +biggest fan +biggiefries7 biggledoinkz biggreenbush biggs +bigjuicybutt bigl +biglenz +bigmoney jim bignipnik bigonevs +bigotslayer +bigpkz bigpompom +bigreddogV2 bigschlong33 bigsee bigshrub45 +bigsnail +bigspick +bigsugoi bigtuner bigz4p bike +bike trail +bilbsay bilet92 bilfey +bill one +billbosaurus +billsta46 billy +billy g0at +billy mayne billy5454 +billyj0e billyjoewo +bilo xd +bimblebunk +binaev12 binch bincho420 bindi bingels binkie +biolemonhaze biozahard +bipiee bipoc +biq pp gamer +bir d birbeon +birdieputt birkki +bisp +bisse bitten by bitter +bitter fruit bj0rne bjassen bjpc bjuti +bkguytd6 +bl00d twinz bl00dShaman bl0wMyPlpe +bl0wdakushh +bl4ckdelt4 black +black coffee +black cum24 +blackbelt blackburrito +blackedmarko +blacksshad0w +blackstyl579 blackzranger blade2k9 +bladee blaktraksoot +blame war blankownz blarbydoo blastmaster6 +blawblaw +blazar58 blaze59 blazed blazekin blazertrail4 +bleenkie +blessn bleu +bleu kayn +bleubeard bliksem269 bliksuiker blind +blind idiot +blink 1 8 2 blinkforlife +bliss blky bloQQe blobaman +blockteleing blonkie45 bloo37 blood bloodhound96 bloodrain202 +bloodredd bloodtheatre blothbather +blowmebuddy blubbystr699 blue +blue in vain +blue max6 +blueTofu blueWagonMan bluebean2596 +blueberry624 +blueberrydev bluebop blueergon059 +bluetrane bluewahfull +blunt tank +blurite boy4 blutorch blvckstvrr blynaas +bman5 +bmeow bnff +bnndt +bnqy +bo bby +bo nk bo2Lawrence bo3rke bo4r +bob bob bob +bobby ross bobby45153 +bobbyb727 bobbyitsme bobbyjoe +bobbytronx +bober vvittu +bobfish66 +bobness +bobondowski bobsushi6396 boer bofflepopper bogie297 +boglad4ket boident +boinkerton +boke smowls +boksepoeper1 bollocksed +boltwitdick +boltzy bombadinski bombycrahan +bon4ri +bonSwole bond bondalorian +bonderoeven +bonelessrice +bonfire bongohonkers bonkbonk bonna1994 boo0ty +boob boob +boob nut boodje1993 boofablebass +book of ra boom boomboom booogieoogie +boooosh +boorito boosbear +bootn98 bootylips +bootyters boratas13 bored +boring hobby born +borpxatu borsi boss +boss hogs +bossboy420 bosscat56 bossdemon88 +bossdog99 +bossedit123 bossy momma +bostonbb2g +bosway bota2 +botchx +botilabaca +botleFluff bottleo +bottn bottomfeed bottypedpsw +bounsn bouquetboy bouwjaar1990 +bouzouki +bowfa bob +bowfaaddict bowl +bowl loaded +bownd boxofbears +boxtrapgod boycie420 +boydi +boydt +boyuniverse +boz pwr boze +bozo +bp9 br0wnardRS +braap poster +bradrian bragegutten brain +brain rotted brainbusterr +branderx gim +brandom lol +bratnt brawling +brb cigy bread breakingood brecht181 bree breeze +brejch +brekitutta brett +brett 69 bretthomas3 brettiz +brettjournal brettmanx7 brettrae +brew bar brewi brexit +brian285 +brian289 brianknight7 briareus brics bridder bridgeport brika +bring ya ass brisingr vin briskyhot +brixs22 brizzle +brky +bro its hamz +brock soup broetie broker +bronson99 +bronzelvl bronzenohkie brooskii +brotha in Ra brotherkjell brothervoid7 brown brownell brownjesus brtsbrg +bruh +brushy1 brutals bryike +bsavs bsct +bskiller10 +btc btd6king +btw Im Nakey +btway +bu bla buIberpikmin bubbakush +bubbith +buckethead12 bucketnipple buckul budabaii @@ -26789,47 +55210,108 @@ budge1 budhato buds buff +buff T O N Y +buff boobies +buff outlaw +bug salesman +bugeye freak bugsijs +buhm buldog89 +bulk up +bulpster +bumbler bumpyD +bumpywalnut8 +bunchface0 +bundun bungaku +buornos +burakaflocka burlyman +burnedpotato burnindank burnsalinas +burntfish55 +burntjar burt buryafriend bushkada +bussi eater bussmandrew +busta bunny butlesha +butt boobies +butt chug +buttercord +buttonbags buup buurman111 buurtvader2 buwatt +buying ai gf +buying girls +buying sloth +buzzin +bwaby +bwana69man bxhxdir +bxmbi little +bxther +by Juddy byEmilsson +byll byrny bzerk +c a b l a y +c bro +c greyson +c h u c kles +c hainz +c j t +c m l +c o 1 a +c onorr +c rompt +c ubic +c xx zz c c-ross93 +c00lbeer c0vid c11ntz +c3h8 seller +c95 c9hype cBold cDive cFraze cMehuu +cMoney62 +cRunX +cT Kura +ca mel caaaazaaa cache cad5112 +cadeano +caesarsantin cafedenbas +cagasaurio cage cagesitter caiomhinnn cajzbi +cakemusclez cakepillows +cala mity +calamity meg calgore10 +calisme call +call me Q callbackc4ll calliott14 +callmedaddie callmeqel callmeson callum23394 @@ -26839,148 +55321,291 @@ calvo camberland cameindamail cameliorate +camellia +camognome camrbidge +can o fish +can smoker canadian canalope cancer +cancer ruin canman794 +cannot pvp cantgetdrops cantsoloraid +canyon crab +cap byakuya cap3r +cape kraken capinkiller1 cappin captn_dabbin car oussel +carbonclock carefree +carltonking1 carlwalter +carmito999 +caronita carrotepic carrus65 +carti stan +carx casadri cash pls +cash19400 +cashcache +cashflowgwap +caspar O8 casperium +cass cassa +cassidyz +cast iron 99 +cat goose +cat the rat +cat yo quack catJAMgif catdog183 +catdog184 caterpie +catgirl41 catlice catlover68 +catmummy18 cats +cats go meow catsandogs catsarepeopl catsntatts +cattierjam cattsts causey +cave zizil5 +cawn man caykk +caza +cb0ndy cbbr +cbf maxing +ccc kyle ccc kyle BTW +cccccc +cce ccoinstar ccvtw +cdryz +ceef ceerial ceh9 +celery dog +celestial177 celliott94 certifythat +cestlez ceus +cgmirin +ch oi ch00s3n chach47 +chadduker +chadmaro chadsmurfin chaffedlips chakra +chamby +champagnedon champinjon champions champrocks chamskillz +changa nndmt changemyrng +chao keng +chaossarim2 +chaoswizzard +chaps on chargnar +charliety charlyzard charred chat chatandinan +chats 0ff +chavito_mobi +chazsti +cheapscape +cheddaphile cheekraider +cheenos cheese +cheese nuts +cheese tots cheesed cheesesmoka +cheesesnake +cheesie odst cheesy05 cheetboyx90 +cheetodust cheffffffa chemistmike chemistryphd +chenswok chent +chenzoh +cherenkov +cherrygrove chessboxing chewbacca814 chewybeaver +chi huahua chickenarise chickenbyrd +chickennug74 chicknsoup3 +chicknugets chicom +chicom shill chidavantlez chie +chie na wei +chien belge +chigas +chilli chillimayo chillscape99 chillummen +chimney15 chimonas +chinchinchin chinkbox chinorondon1 +chipndale chirspls +chisssa +chlodotexe +chnged +chobby bong +chochise +chodell13 chogey chokemepleas chokemysword choobocka5 chook1e choppers +chopsbwana +chorkin +chr0nic k0 chris chriscrossz3 chrisdude +chriskr9 chriskys christimgood christinet +chronicwax +chuI2ch +chubbybeagle chubysack +chum god +chumboyee chunkydaddy +chvi123 chxpo +ciggen3 +cigonusargas +cimmins cimsoK +cindur +cinekmiszcz cinim circa445 cityless +civo cjim +cjrr3 cjskillet cjuul clabby clac clancy272 +clangy544 +clara ravens +clardiiii claryzz class1k clayylmao cleanhell +cleann +cleanscape clevesbch2 click +click boss +clickin boss +clickrtraind +clienting cliff clifsideGang +clig fish +clini +clippng +clodoaldo23 +clogs please closeline194 cloudroamer clouds +clownViking +clownsrus2 +clownzeta +clrjones964 clubsammich cluemaster7 +cmer cmiite +cmiuehye cml852 cmm6364 coatria +coats cobrafrost cobraslyer coco +coco coconut +cocoa codga123 +cody curls +coffeechuno coffeemug91 +coin btw +cojestkuwa colafanboy +colb 45 coldumber coleeeeee colekay +colemak +collect butt collessin colon colt +coltsfan1287 +coma afk come +come in bum commandrsnow +compact cat +concert conig connie connor420sit +connorkwl +connorosrs containment +content days +continental contra145 conww cookiedunker @@ -26988,59 +55613,118 @@ cookiekill cookieman cookys cooldude2845 +cooleodotty coolgasje +coolish funt +coop ananas +coozin_killa copy166 +cor tapijt cordnog core63 corgi +corgi fan73 +corgsterr corn +corn8holio7 +cornstarchII coronel coronieverus corps corpse +corpslave18 +correctmymis cosec cosineeee cosmic cosmicphetus +coszzyy +council pops +count beck +countjupiter covid covidconvict covidsurvivo +cow abandon +cow cede +cow20 +cowpigj cowpker4life cowpoo99 +cowpuncher19 +cows +cox finisher +cox for cash coxchambers +coxfcksme +coxnass +cp5 cpenn +cpt-cujo +cr ai g +crZbY crab +crad le guy cradleguys +crag slayer +craigbr-1994 craigobaker +craigs cool craj +crajan crannerz crash +crayfish1 crazecanuck crazycow913 +crazyloLer14 +crcsofkrks +creamiboi crenux1st crep +crevebach crew-z +criddd +crimsonlily +cringis khan +crinkes cripsystrips +cris7ronaldo +crisVao +crisp damage criticism critiode cross crownchyfled +crppironman +crueship cruisingmap +crumble +crunchyfrog6 +crunchyrolll crushsquid crustymcfk cruuton crybcdry +cryme wave crypto crystalbluu crzybrady cskt csramsus +cstk1Ng ctmv +ctq ctraltdelet +ctsRasta +cu ck cub1c +cubbear cubezor99 cucked +cumstrosity cunnys +cupma cupofpeepee cups cursed_angeI @@ -27048,43 +55732,94 @@ curt cus345 cuscusrevers cute +cute lil elf +cutekitten7 cutemuppit +cutepenguin9 cutetoeluvr +cutie cat24 +cutie frog cuvae +cvbj +cvl +cwazi +cxir cyanicide cyberdunk cyberyux +cyi +cynth ia cyxxa czaroiemao czechit +d arb +d e v o u t +d io r +d urrin +d y lan d00she +d0g eat d0g +d0gz +d0nnie-d0rk0 +d0rq d0ugjudy d1sh +d216 +d2n d3mot10n d4rkk +dDillyDilly dEAd0dhz dEdjamaL dXLeamXb da jiin +da ph da6god daMteG daPeanut +dab 710 +dab face +dab marino +dabaig +dabbtheslab +dabilitation daboiz daboo420 +dabs n smoke dabtchel +dad bad +dad tree +dadcoma +daddds +daddy sharky daddyfred daddys daddywaluigi +dadfcker69 +dads bulge +dadsbelt dadsilou +dadson23 daedbent +daft plonker +dagens mand dagg3 +daggry daghostwoman +dagond0rk1 +dahhyunnee dahlinho +dahlukeh dainiux2014 daisyfletchy dallas +dallee +dalunk +dalvik +damage222 damo332 dan73 +dan_hua dance dancol00 dandy man @@ -27092,51 +55827,89 @@ danielccm danielfanacc dank dankburgers +dankin606 +danklingt0n danliciouso +danny4490 dannytjuhhh danthebankid danzing +dapipelaya daprincess21 +daredevildog +daretodair darigondeath darius_v_2 dark +dark binding dark hays dark0hawk dark5pac3r darkandrew7 +darkanimal86 darkclues +darkcyco darkgirl79 darkhex0 darkjustin54 +darklordc +darkmagicdad darkness darkstagx darkxaotik darkyChao +darranegobli +darranekarhu +darranekives +darth gainz darthbuddatv darthv102 +darvan +dascarytaco dasor012 dataenz datakrash +datalogi datboi2456 +datstonerlal datweekaz74 davadof daveb123 +david442p +davidpain dawaj dawningofwar +dawnsend4 +dawocar +day of dog dayoh +daysack daystar +daystar 0-0 +daz 11 +dballl dbau +dbopp dbow4pking dbstf94 dc22000 +dc22000_1509 dcPain dcfgs4 +dcing always +dcross9999 ddSyndrome dddvlot +ddr ddsfornubs +de Fe Dad +de em tee +de metro de00 deZoet +de_rono dead +dead tee dead2Mfarmer deadazztec deadcentred @@ -27148,69 +55921,157 @@ deadmeadow deadskiller7 deadwildyXD dear +dear sleeper +dearlola1 death +death to wdr death0183 deathax10 deathchecks deathe +deathlifiron debbie +deci m8 deciphered +declaw3d +decoy110 +ded R N G +ded pixels +dedarec +dedcell +dedfin +dee2801 +deeezey deep +deepbowlz deeptechouse deesnertz deetuu +deez ntz +defblacklawl +defender3355 defenderCX degie degraded degryser dehula deivvn +dekane deketamingo deku delboy1964 delete +delete from demaguz +demerstrand +demon ssss +den n y dennyispro densenuggett denver +denver nugs denzarr +departusa deperni Jr +derdepoging derrybarry +des9re +deserved pet +desksitter despotroast dessverre desteezdubs +detnia f +detrater mi +detzy detzy +deuce +deuzzz +dev rat devils +devilz ashes +devious man devonjt1 dewsh dexaur +dexless 4eva +dfkjgkjfdgj +dfordumm1ed dftba +dg eco +dgndfgjnmfdh dgro dgwiD dharokjonsin +dhe +dhl +di Trevi +diK +diabolicdth diamanda +dibdabber33 dibdibdibdib +dickchair +dickenbals +dickfield +dickin +didak +diddy420 +didnt rwt dids didugetrekt +dieHosen +dies at zuk +dietc0ke +difjnuee +difluenz +digigrind +digimonOtis digthat diguper dikke +dikke vogel dikorbut +dilaudid dad +dilbertt dill +dill picklez +dinklebrah +dinwy dioshka +dirt box dirty +dirty rat420 +dirtyman +dirtyydan +disc o +disco sminny disdudsauf disease disrespected distracktion diti +diu nay lomo dive divibee +dixon butts +dizma +dizzee l0l +dj en sander +dj poolboi +dj roblox +dj1111 dj_khaaaled +djawns djerfen +djfistingodx djhonnyc22 +djk1168 +djm 0813 djschaum dkb15 dkirk +dlaldus +dmersaregay dmgx dmh3464 dmmeguy @@ -27218,170 +56079,340 @@ dmmskuhled dmolishall dmorgzz dmxbutwhite +dnb demon +dnd5 +do o d +dobiz +doctorbeefus doctorkrysis doctorstig +doeby1 doesnt +dog dog baby +dog rs +dog yum dog22 dogGoesMeow +dogluvr42 dogofrivers +dogongod +doing time +dokus dom1nation97 dominicpm008 +domiuxas52 dommegekke1 +don paro +don3tsc3m donaldsocool +dong bone +dongiebong +donkeykong2 donmaners donnyr2hcim +donohuey dont +dont eatass +dont relax dontiane dontpickme24 +dontsmokemid donzy doobie8 +doogleweed dookie +dooknukem3d doom +doomcat67 doominizer +doomsiclepop doorbel doors +doot scooter +dop dopa +dopey smurfy dopeyaf +doris negra dorkSine +dormanth +dorschbag10 +doteslintrrc double99 +doublecross +doublegulps +dox +doyc15 dp23wnnabe +dpi +dps7 +dr crabman +dr evil +dr smurf dr3wst3rk dr4ll1m drag drag0n dragneel132 +drago_jr555 dragonizer11 dragtom draind drakh drakonic +dratini213 draxyboo drazil7 drdrinkwater +dreads iron +dreadthefate dreamworld +dreiph +drewsky drickvatten drillbit_10 +drink toilet dripcuck drogodon +droidfarmer +droopsnoot drotRS drouzeee drphil10203 +druedainx drug_yew +drugandbass drugs drugsrbad drunk +drunk f00l drunkwpants drwilly92 drxfluffeeee dssctn +dstortion +dstroyd dsvgs +dt duby dtfmslogan duMonster +dubba z dubdubbronco +dubies4days +duckwax +dudash dude duder +dudrid BTW dudylson +duedeman duel duets +duette duff skill duffman1992 duhpho +duked +dulitrai +dull needle +dulle00 dumb +dumbass hick +dumbweeb22 +dumple +dumpy rat +dun2kaz +duncan c +dunerat +dung_eater31 dunnman +dunt +duo virgin +durche93 durgs duriol +durkology +dusp dusq +duve melker +dvnny +dwarFcaNnOn4 dwayne +dwvb +dylaaan6 +dyldied +dylodide +dymo dynastyzero +dyrachyo +dyskletiker dyssection +dyzi dzhy +dzmomolungma +e LFa s +e acc +e c e e R +e c stasy +e ji +e med e pinke +e rui +e031420e e1ght +e50 e500 +e621net eKaleb +eL Lavish eLSD +eLas eLeeT eLqTLN +eM Be +eMiSk AU eNCH ePicnicEMan +eSquence eStimatic +eXtr3Mer btw eacy eaekk eagl393 +eagle shed +easily thero easterparty easyMEDIA +eat a udon +eat my bewty eatcox +eathelwulf eatmyfries +eatmypie +eatsdonut49 eazybreazy eazygps eazyws ebbe ebijah +eboy gamer57 ecce +echo cooks +eckla ecofine +eddimunstr +eddyb edgarsjm edible +edilot +edmu edunit +eegor +eek monkey +een pint aub eenzeven eerx +eesau eetbordleeg eetuliiniBTW +efcherry +efci effectiiveRS +effing sheet +efog efren189 egcept +eggo death +eggu eggzotic egirl qt314 +egirl tile egirl73 egyptasaurus egypton egzoff ehdion ehoov92 +eiaraieaieai +eid ola +eiflA eigh +eilhart +ein Bier +einu miegot ejobs ekcivtec +ekhoplex +ekm +el Laneo +el is +el peppo +el tubo elDiablo666 elGoblino elbo +eldanari +elden lawd elder +elder jam +elder poul elderimpking eldestlance +eldrich ball elefantsrul elfje185 elitharion +elkcarc elkcark +elletwo elli +ellias elliott1650 +ellipsism ello ellran elm43 elmeroguero elon eloquent +elsieh +eltomatero12 elyaxo email12345 emaq emaru emaw emiiru +emilviperHIM emilyqt666 emiracle +emm +emokid93 emopapi emptyhead emptysoul88 emuulzzz emvelienenko +en Au encoa endless endlessgrnd +eneco enemy2mad269 +enen energymango +eneslannn +engrave +enjoiskate enlmatek enlot enneUni enormousguy +enservices +entiesman envetoids eocri +eow btw epcr epic epickayle @@ -27390,62 +56421,123 @@ epocsorekiM eptul er2002 eraie +eric verdonc erik020 +erikj20 +erilthil +erk is cute +erlendolstad ermer +ermer fudd ernestoch ernieK erniethecat +erpponen +errikkold5 error +error nope +error occurd errorwithnam +ersatzquatch +eruze ervin +erzin +esc eseeg +esportspker espress +esssaa +estra jen +eteelS eternatus etha +ether-or +etsii naista eujamaispkei euonym +euphoria btw +eureka 4 euxy +ev tesla evanthenewb evidencez evil +evil drudge +evils ault evirgin evoL evol evonaabi evoshiva +ew its paul +ewechoose ewenn ewgility +ewmu +ewvn ex0dus ex_shadow +excalipoodle excitedz exila exile exodiass exolyte +exp waste 07 extesyturtle extinct extra +extra big pp extrastark extratrippy +eyes fire2 +eygs +eyniss ezAce +ezzychu ezzymc +f a r r r +f ainted +f c gee +f d b +f ern +f q +f r o st y +f reS +f0r 20 f0rbes f0rev3r +f0rzca f1elder +f1ll2 +f1oh f1sh1ngcrazy f2pkiller420 f3n1kz +f41r unknown +f4az +f4fight +f8 fEmshi fJack fa1lure fa2kil +fa43ws5gdrxn fabsku +faceeee +facehunt fadc2 failbloug +fairies ring +faiyaz911 +faka jackson fake +fakeironman +falcon30040 fallen fallenbouse fallengodxx +falneek falsehope familypp22 famousbutnot @@ -27453,61 +56545,123 @@ famousdavies famwell fan3to fancybunny84 +fanof +fanook kill +fansh +fapital one +fapyqt +farmerman111 +fart taker farth4lyf +fartypants64 farva5001 fastfoodguy fastsalmon34 +fat bish0p +fat miso +fat n ugly fatalzgs fatalzick92 +fatblimp +fatcactus99 fatdabz fatdemon +fatfish44 fatiimma fatpapi fatrat095 fattig fatty +fatty_ironmn fattymcthick fawaka fawkin fawnt +fayeuk +fayfey fazIlioilol fbah2 fcemee +fdegierr fdsd +fe ar none +fe fi fo ben +fe fleton +fe hessu +fe shredder +fe unclefro +fe-ma-le +feaker fearma +fearnooaths +fearsome +fech +fed the rat +fedposting +feed water +feet r neat +feet shui +feet tickle fegorus feinkostbob fellman250 felsic +femaledhide +femboy fever femiketyson +femra fems +femtanyl fenimore133 fenty +ferbies +ferderb fergina ferkyy fernezi fernibosh +ferric thane +ferrotopamin +ferrousnub fettnerd +ffa btw +ffakin roids +ffs cmon ffun15 +fghtmeirl +fhb ruby fhisher9 +fi1LMma8Ke7R fiddy +fieryflame55 fifiz +figey figgiolly +fighter8888 fighttme fighu figit fiiks +fiishcat +fijurgt fiko +fikset fill2 +filma kraken filnrozdor +filthiefrank +fin hupu final dip finalkid finally +finance king +findmydog4 finerunes7 finfinnegan fingerd finn fire +fire skull99 firebrotha2 firebwan fireflyman3 @@ -27515,67 +56669,145 @@ firemadara firewood149 firework19 first +fish cook +fish slut34 +fishbomb83 +fisher ilhan +fishfiinger fishnforfun fist +fist n twist fistaah fistofzeuz +fitjamal +fixedmanose +fixx ur face fizoo +fjuc +fk bud +fkMushrooms +fkWiiz fkn seale fl0ppy +fl0rals fl0xen flabb flaccid +flacidzillaa flaggeding flaminstu flapdrol2000 flatbroke +flatjack78 flatpancakes +flawskee flax somker +flenis +fleqk +flexmaniac flexxygreen +fligh4 +flimzzy +flink1145 flint +flip555 flipdoggydog flipouu +flipperkid69 +flke +floch floie floopily +florda v2 +florida1992 flow +flow states flowerbunz +flowers +flowerworks +flowing past +flpi fluffy +flunkerr +flwc flyingfather flyingpigs +flymouse +flywoodhead fmPalm fo77y +fo_of +focusor foldoutchair +folklore +fondledeez fonytergus0n food +foom +foookz +foot fe tish footbag +footgobble9 +forbiddengol forcestealer forevercc +forfun_ED +forgeleader4 forkheals formazion +formerly act fornitesweat forrestriley forss1 +fortnitecuum forty7 fortyfour44 fortyfours fotjonxd +found RS2019 fourecks +fowrt +foxMcCl0udd +foxair foxdude909 +foxi melissa +foxmr2 foxological +foxspirit foxxit +fp fp4bank +fpsbowser +fr0stys fr0zen46 +fractalion +frail +franklinzule frantam +frawzti +fredz1 free +free rations +free willy1 freeheadbutt freekek freekface99 freepknub337 freeze4peeps +fremenik +freshaf +freshdougie fressi +friccSailing +friday x +friedz friendlyduck +frierenfan69 +frodobaggens +frog37 frogggggggg7 frogmeme420x +frogposting froock frootl00p233 froppy @@ -27583,147 +56815,269 @@ frosteazz frostfire089 frostkatss frothsy +froxey frozen +frqke fruitdeeps fryguy20 frzen +fskencha219 +fsnack fsteve fsxd ftSlimShady +ftmg fubar fudkingname +fuhrari fukduelarena fuktig +full service +fullrune383 +fun e name +fund issues +funk +funk it funky +furi xD +fusarium5 +future days +fuwamoco fan fuzzlumpkin fuzzydenuts +fuzzypapi +fuzzypupz +fwapdokopjai fwft09 +fwip fxck fxck versace +fxdb fyfaen +fymcgee +fyr irony fyromaniac +g arre g o o w +g u L z g00dz +g0_ober g0d slayer19 g0dofgames +g0dz target g0ld +g0rgelzak g1g1tyg0o0 g1n00tj3 +g1o +g4rug gIassy gOWObs +ga zr gaaaaleth gabba-jabba gabbe314 gadnukB0W gaffel +gagifidi gaht +gaht dangit +gainsaid gainz +gainz no gainztrain9 +gallidogs galx37 game +gamedbroski gamelsbad gamer gamer63738 gamerb0y +games sheet gamesalright +gamin hard gang +gang gastino ganger34u +gangstersfly ganjah lord ganoze +gapin ass gaping +gargalonmyd +garn woolies +garra +garymunzen +gas watah gasang +gatekeepr gatlin +gatorbait61 gatorclue +gaumcat14 gavin +gay avenger +gay corn +gb +gd5 ge1uk gecs gege4646 +gegebee geitz4 general_a3 generalneos genghys +geniuswinner gentle geof +georgemonger gerdlol gestrikt +get pregnant +getcance +geten30 getpixelz getsnipez getting geusjj +geve en neme gewoonhendri gezzle +gfink +gg Goombas gggochu ggremlin ggroeffus +ggrr ggwpezgame +gherkins +ghliz ghost +ghost of CVS +ghostlyjon ghostmahi +ghrimdrakan +ghxstboy gianni025 +giannnnni giant giantsbane10 +gibsons dog +giffnamepls giga +giga zooted +gigglybear gijsro gilgir +gim Bam +gim ajuin +gim so bad +gimeurgpm8 +gimhunter02 +gimmey bear +gimpeta gimpinator14 +gimtmbj gingasnapz +gingerr ginjembre gino2315 gintoki +gioh girl girlbossed girthing +git gud kekw give +give in +give me 1 gp giveortake givmemonyplz giza gizmywizz +gkfdhsjbgpas +gl barnie +gl gf i win +gl lmfao gl0s2n gladwin97 glazura glgl glica glingster +glitch1128 +glooboowhoo glotis420 glowmastree glumburger +gmac33 gmtn +gnak +gnariska gnarrrkilll +gnobo +gnome pegger goGETTER87 +goal freak goat goated goatflocker goblinsyler +gochugaru +godblaster69 godfreeB godmiljaar godmysavior godofvoid +godsdankweed godss godver +going2maxnow +gokhanakan goku9172 +gokublk409 golaguard +goldenN0B0DY +goldest cat2 goldiepawper gomikasu +gon dor gonarusinat +gone numb +gonewild gonsoLE +gonz o good +good duck 4 +goodboi525 goodlife +goonette goontuna gooootsby +goos fah bah goose goosegoose22 gor7 goranfr +goreshitfan +gorgewkush goroka +got u m8 +goth mime gothic gothorian gotmadtree gotoschool gottaRash gotzeeben +goy street gp294 gpawshaft02 gpf93 gr0ve +grace life graftosh gramss gran chorizo @@ -27731,310 +57085,648 @@ grandp4 grandpa grandpashome grandslamhit +graphist II grashuis +grass hopper gratis gravetheif +gray ass +greasy bacon greasyguy19 great +great bazza +great blazer +great keith +great pkay greeaf green greenbuds1 greenfleet1 greenie14 greenm4444 +greeny4 +greenzyyy greg +greg btw grey +grilecheese +grillmagnum grindin2bond grinschen grizzy77 grlobe +grogybog12 gronoc +groogns +grossedinde6 gruelsipper grumpyy +gt i gtrpower3 +guardy gucci guirkle gularies gulibleidiot +gullefjun2 +gulp my knob +gumlord54 +gunbladelh gungaman3 +gunnmoses gunnybear gunzip +gurz guttsberserk +guuvin +guy123452345 +guyfranklin guyhasaname +guyladriel +guzzlinbrews gvfsa +gwaph gwaphics +gwapo gwapo +gwb +gwen-artemis +gwiffdakid +gwogoudain +gwug gypzys +gyxl +h ertog +h re +h ugo h00cares h0rseZ +h2j h3hz +h4h4h h4ndshake +h8browns +h8dip +h9g hEAdGLiTcH hOsujaRS +haaksrikko +haam habitus hacchi hackening hadibaam hagerlund haha +haha lul +haha nice xd hahaLMAOlol hahaa +hahaa-ukko hahaha +hahaha LOL +haiiG hairahcaz hairy hairyraccoon hairytaent haistavittu9 +hakuikoyori +hakumaata halal +haldfhaklfa2 half halfcrimp +halfrightfox +halftimegod halling1 halo +halo 238 +halo is scum +haloumbs hamdrip hamers +hamhand hamilton +hamilton fan hammade hammershark hammu666 hamptonboys hamthenoob hamzullah +han sohee hanakarjala +handi 0_0 handi9900 +hangry_bird hanh +happi hippo +happyprophet +har tig hard3x hardcoresque +hardstuck gp +hareby harelmatlaw1 +haringbata hark harleybegum +harmony +harmony w harrpp harryderoest harts0295 harziol +hasansahl hasbulla hash hassbulla +hat foe +haterz havfherter +haw yee hawkesbay +hayati enta +hayden787 +hazel nut +hc pilszen hc_karadeniz hcgoldslaye +hcim gud btw hclirongang hcmemekiller hdhd +he a 1O but +he box jonge +he r b +he4 +heGee hear +heartvessels +heast oida +heatassnugs +heatwave305 +heavygim +heavyiron94 +hebrewmytea heca +heckn frick hedonismbot +hee haw 255 heegeer heel heelgoed heeming heeyhallozeg +heftZEUS hehe +hehe heheh hehehehe hei954 +heimy22 +heizenberg11 helgrimm +helicopta12 hellobob488 hellofpures hellohello +hellohelloom +hellper hellreaper25 help +helpa +helpusobi1 +hembree +hemmingsson +hemmy +hemran +hemstad henkka89 henkleingeld +hennnin henson23 henzer heppytako +her mager herb +herb btw +herb l0rd +herb l0rd jr +herbdean0981 herbi herbibear here herezacsko herkimer heros +herrasmies68 +hesedona +hesi pullup hestakuken heuj speulen hexergeralt +hexxers +hexzie +hey axel hey im ben +hey its zul +hey_imgrump +hey_rayray heywoodya +hh r hhdrgu +hi im miku +hidde xddd hiddeboven +hidesonkush hidlandboys high +high bonsai +highIMcamila highelolux +higher man +highfly94 highprice +highright highsassy hightoo99 highventure +hih hiiggiinss_5 hiirihaukka hikipastori +himokarpaasi himself99 +hiphopdied hipocracy +hippofart27 hippyjump3 hippytrippin hirai +hirai momo his7 +hit trees hitchclimber +hitsumabushi hitto hitz hiunknown +hiya jase +hizli maymun +hlen +hlua hlucky hm08 +hn k +hnge +hnsky hoangbach456 +hobbit head hobosloveme +hodl link hoffnungslos +hol my got holdadoor holden21 holdenrulz6 +holidayRus +hollowking holonomy holy +holy chad +holyfizz holypalo +home2get homestank homie jaquan +hompkerbenis honda honeywheat honourpig48 +honscy hooah89D hooliganism +hoonyboony hoosier4life +hootis4 hopOFFbish +hopeakettu25 hopeless0ne horkkaaja18 horror horsedik7 +hos hoswoo +hot otter hotdogmum99 hotpants +hotyogapants +how 2 use ge +howliett +hows it garn howyadurrr +howyodo hrby +hrsn +hs +hs3 huang9296 hub154 +huealldaym8 huge +huge cog +huge man big +huge ovaries hugh +hugh_who +hugheberto hughjazznut hugjam02 +hulikopteeri hulikopteri hulken532 hulrikon94 +human6000 humble +humjiboi +hummerspeck humpmedumpty hunden +hungrypit hungwonglow hunter +hunter01132 +hunter123216 +huntin_pets +huor4hansu +huoranpenska hurt +hurtswhenip +husbandowo hush huskyheaven +hut dugs huutonaurua hwow +hxdd +hxzy +hyasf +hycoda hydra hydraboss hymke hypez hyphynx +hypofelix10 hyprmax hyung +hyvintoimii hzpascal i 0nly skill +i Bmx +i C D +i Kelly +i Kyle +i Shin Chan +i Spartan i Stugbert i +i URNn +i Val +i am hua ren +i am iron xd +i am nickle +i am rocky +i am soo dry +i bets i +i ch i +i dandy +i dcd 4 sets +i disabled +i done +i eat noods +i forte +i gag +i gor +i got dust +i grug +i hit 420z +i i i i +i john 96 +i look great +i lose gp +i need top +i need you +i ok can win +i poop alone i praise mvp +i preferhead i r muffin +i r4piid i +i ronman +i vexterr i-i-istutter i0 strength i0am0the0one +i126 i2eally i2legit i2me +i3nd Legends i420u +i50 +i8 2 l8 +i9 iAIex +iAM Pleb iAUSSIE iAdriaan iAlch +iAlchedNieve +iAmNotSharky +iAmaWiseAss +iAmen +iAttributes +iB Lifted +iBal iBallr +iBeDorky iBeanie93 +iBeast It Up iBeatNavy +iBeleti +iBelg +iBlack Zeus iBlake +iBloodsicle iBlurks iBosstastic iBoughtpizza +iBrandon iBukowski iBunZoot +iBurkie +iBurn Dro iBustedaNUT +iCakoRS iCarna iCbarr93 iCh0sen +iChangeling iCheezedOff iCheze +iChugBleach +iCiga +iClickYellow iCmurda +iCoconut +iCrank a lot iCrash +iCreeme iCyantist +iD Dazza +iDH +iDabbedOut iDan iDanny13oy +iDark Jesus iDashio iDashwood iDeathlok iDerpo +iDez +iDo RageQuit iDoNot iDontWinSad iDrankCOFFEE iDrebin +iDrexler +iDrops +iDuiveltje +iElfy +iElysian iEmery iEpa iEprod iEuph iEuroVamp iEvergarden +iFailAgainnn iFatalFoei iFerrumMan +iFeud +iFightClouds +iFightGiants iFire +iFoRGe +iFrads +iFradz +iFrogs +iFry +iFucter iFukFatChix +iFurb +iGab +iGarns +iGlaceon +iGlitched iGlowGreen iGohan iGotDds +iGotDibs iGotem iGreig +iGuDMaFF iGuessUrNew +iHazelnut iHenrie iHenry +iHiyori iHockey +iHolydude +iHuntie iHydroxity +iHydroxityv2 +iIimesiahiIi +iJ0HN +iJ4CK +iJCLEE X iJake iJamPancake iJesslag +iJezuss iJfr iJohn +iJomm iJwu iKHole iKILLN +iKantu iKarl1s iKerry iKitch iKitz +iKonijn iKoning +iKozak iKristov iKurko iKushUp +iLEFTmyGF4RS +iLL Sushi iLeftHer4XP +iLegacyX20 +iLetaker +iLeveled +iLikeTacos +iLikeTheStok iLikeuAlatte iLoner iLove iLoveYou3OOO iLuckout +iLuv Pandas iLuvMyMilf +iLuvSubs +iM3RKEDu iMADbro iMahjarrat iManiac +iMark 1 +iMarkl iMartin11 iMatey +iMeeger iMellek iMelli iMementoMori iMeo iMichaelN +iMikail +iMikey +iMogUCope +iMotown +iMushh +iMuste +iMx +iN3K0 +iNamaste iNeedBeaver iNeverMor3 +iNewbcake +iNewton +iNibble Bats +iNz +iOPeveryday +iOhmz +iOsmumten iOwl iOwnU4ss +iP1 iPIMP iPKedEpstein +iPacmanSam iPaki +iPalumor iPatrickN iPegAsians iPerfectoX @@ -28044,6 +57736,7 @@ iPink iPlugg iPod iPop +iPray_Guthix iPresident iPunchCones iPure @@ -28056,9 +57749,14 @@ iQuittedCiao iRNGizzed iRekt iRepToronto +iReue +iRev Man iRezlo +iRoN cUj0 iRoNmAnSdUmB +iRonAllot iRunTh3World +iRunzo iRycoda iSaran iScape @@ -28068,115 +57766,255 @@ iScream03 iScrewedUp iShibby iSkane +iSkript +iSlay Girls iSlayCookies iSlayGoat +iSlenderMann +iSmashUrGF iSniffCows +iSnowmobile iSoulReap +iSpare iStayLowKey iStealSex iSteele +iStick2Corp +iStonee iStream +iStreetfight +iSuhdle +iSwarly +iSweat +iSweatyYeti iT0m +iTan +iTaz +iTed2cold +iTheDarkKing +iTheodore iThiellie iTisk iTmetzo +iToxic +iTrin iTunder +iTw1sted iTyler +iTz Command +iTz Frosty +iTzBoo420 iTzGoinInDry iTzKATalyzt iTzSnypah +iTzTurtlexD iTzTyLeRXD +iTzWho iTzZ +iTzxLiMiiTz iTzzVanquish iUberz +iUsed2Corp +iUub +iWilkel +iWillz +iWithdrawal +iWonderWhy iWyatt iYahwehi +iYellowClick iYunis +iZ4 iZorru +iZuny +i_murder_bh iafx iain19 +iamAFK iamCanadian iamMcLovin iamfish +iamfried247 +iamfuss0100 iamgreatrng iamlucas19 iamonfiyaaaa iamperkins +iamvery cool iamvoldemort iamzed +iandrehehexD iateyourpie ibbenbueren +ibn Mukhtar +iboomedyou +iboyfly ibr4him iburythebone +ibushmani ic3d +ic3d c0ffee icannotboss +icanread321 icantspelle +ice beam +ice juice +ice-nine9 +icearrow28 icebolt19987 iceburg189 icecoldbreez iced +iced marbles iceman000 icewall0w +ichau icjbi +icky sticky icutL0g5 +icy ded ppl icyT icydilldos +icypolarbear +id c +idc idcy +idfap +ididnthither idiedonmyhc +idiom idiot +idiot game +idiothead +idk chill idkgoogleit +idkh0wtoplay +idkwhatdo idle +idle1 idpoen idrater +iduggz10 +iekaajer iekgaa +ienai +ifantomas6 +ifarted42000 ifootfondle +ight igiddeni +iglo16 igotdaice igotnolifee igotnoolife +igotwingz igotyour99s +igrimmerz +igugh ih8urkind ihan ihaveanxiety ihavitunopee +iheartBBLs +ihopeurope +ii Sahir ii +ii am teaser +ii bad guy +ii forte ii +ii love cats +iiBink iiDivine iiDrackidii iiGallardoo iiHydra +iiLuckyVibes +iiTz Nothing +iiZEEii +iiZno +ii_TrYHaRd iiaannaa +iiiRood +iijelloo +iikasoyi +iimperious +iinsin iioktb iirc +iitsjarod +iitz deebz +iitzz Ryan +iivy11 iizoneout +ijoinedthis ijust ijustgotreal +ijzer ali +ijzer vreter ijzeren ijzerenman1 +ik itachi ik ikea ikeep1r0lled ikil ikillstuff +ikiroz ikoyouboy +ikp0wnsz +ikpakjou ikrr iksalion iksd iksdeee +il malocchio ila161 ilapaR ileax ileft ilegalTruble ileppmot +ilfi ilike2gamble ililliiilli +iljang +ill Dottore +ill-Money illadelph illenials +illisible +illmaister +illmatic +illmindhop5 illotex illumea illuminavi illyreia +illysia +ilookcat +ilovecitywok +iloveinsulin ilswisa +iluvducks +ily stepmom ilyakchuk +im 1v9 +im Jaacob +im Noah +im Z a n e +im a learner +im a pur8 +im at cox +im bad tbh +im batu kham +im cats +im dandy +im huge +im in charge +im nlf +im pogging +im ruben im solo rose +im tr4vis +im ttZ im4everxerox imAcidic imAhri @@ -28187,123 +58025,302 @@ imJT imNEWY imPapu imStef +imWebby +im_pro_jones +ima big boy +ima survivor imafatscaper +imago loop imaybegod imbaconyum +imbueddog212 imbutz imbuyingf +imcahos imcaprise +imdrunkashit imdud +imfi imflavio imho imhuge iminarager +imjeremy +immachin +immaturely immef +immirgant +immmersion immortalz +imnotdani impaired impartial +impek +imteddybear +imthenalls +imtogepi +imusualyhigh +imzahikell +in africa +inSec inTheSlum +inb4elysian +inc incant +incci +inclibe includingtea +ind +indebara +indian inescate +inf nick infamousO775 +infamousjew +infare +infernalwhen +infessian infragant +initiator iniu inject +injinourme inked inldgwetrust innSink +inner child insaned17 +instagation +intja intwystis +invictecum +invirtua +invisybl +invynsable inwervs inwnucleus inxx +ioe iojerfwpjiof ioliteKnight iolm +ioncolliderz ionlypickadc +ionman iorcsrox +iownw69 +ipfreely939 +ipwnkthxbai ir0nschlong +irak93 +ireq +irhunter +iriee NZ iron +iron Dreven +iron Fapkin +iron Nido +iron bewts +iron carly65 +iron chur g +iron colb iron cuzibro +iron d +iron dafanek +iron dumle +iron evoo +iron gariks +iron grogu +iron hobbs +iron i jad i +iron imp 89 +iron kobe +iron kydrol +iron mazie +iron nakno +iron nkellen +iron sfgiant +iron snak3s +iron snurd +iron t2 +iron te_un +iron to main +iron tylerr1 +iron veil902 +iron veyydot +iron vow iron xarcher iron0 +iron0_o ironBellukka iron_day54 ironandwhine +ironarrow ironbandiit ironbass +ironclimber1 irond ironderp +irondude686 ironerextion ironerrosann ironeye +ironfara +ironfather8 +ironfyi irongaga +ironguxiz +ironhuuu +ironic it is ironikcronik ironinfinite ironjssnoob ironjustice +ironjutku ironkendall +ironkevkev ironlizrdfuk +ironlog215 ironlooks +ironly fans ironmortel85 +ironoujust ironpower29 ironpuni ironskunkki ironspig irontsuki +ironvesku ironwortel ironwoss irradiated +irregularly +iruste +is an option is skimpin isCatrileo +isayswegyolo +isleepwith3s islugo +isoPROpain istealyoloot isuwu +it do be +it ends now it0b it0keup itachi9113 itbch +itirof +itisdre +itmeautim +itroy v2 +its Bread +its DeFib +its Hoffman +its Knetter +its Mewtwo +its Polle +its a ginger +its aight +its an 8th +its leviosaa +its not mine +its the game +its20after4 +itsAden +itsErnie itsGLD itsJayy itsNoki +itsSt1cky itsWum +itsa itsa_feature itsaart +itsalic +itsbenny itsbill +itsdanlol +itself +itsfwhobar itsmewarreng +itspajamaday itsthedirtyJ +itwasme ityttmom +itz Ozie +itz Tastey itzjaycie +iua iusedtosleep ivao ivibondivi ivlr +iw iwearIRONirl iwinulosety +ix7 +ixGOONIExi ixJake ixoniron iyyghg izmibence j e company +j o h n z +j o l s +j sta1in +j uddr +j wet j0rd +j0rdb98 j0shNZ +j0shwah +j1nx +j311yb311y97 +j3ffmaill3 +j3rvi5 +jDaledge +j_mes jaakqoo +jaatzy +jackBingus jackLonghorn jackancoke7 jackjester +jacksonlol +jacola +jae Bee jaguarundi +jagweed +jagweedle jahan +jahmelo jahnjo jahrezeiten +jaitt075 jajademonrat +jajajad jake92 +jake9549 +jakeyvil jakkaru +jakste r +jaksterlite +jakuusa24 +jallon jalucox jamaz8 james1234269 james68889 +james9f +jamesishere +jamesw jamflex +jamgyo +jamie g 456 +jamjarrrs +jamm janguy jani jankywanky @@ -28312,50 +58329,104 @@ jaq0 jargonship jarjoevis jarngrimre +jarno561 jarnrisi +jarnwoodchck +jarsko jaseDemon +jaseGrumpy +jauu +jaxta +jay 6ird +jay oh kay jayst1n +jayveedee jaza +jaza maxwell +jbirrd +jd345 +jdockett jdore jdsgsxrthou jeREEEEEmy jedi +jeeeeee jeep jeezuschrxst jef skhiii jeff jeffswifty jegerklog +jehhjr jekkujaba +jellyfish49 +jellyjam20 +jem is cool jerome +jerrys ags +jerrys venny jerzieboy18 +jesjesjo +jesus bone +jesus vape jesus4gives jesusiswrong +jesust +jetalexnder +jettyrr +jewellski jewjoking jfan +jfc +jfrank127 +jfy +jfyulopaef jheezuz +jhinnessy jhonlee48 +jhoog +ji mbo jibmask +jicc +jigx +jihal2020 +jikrak jiksee +jim jones it jimbob1 jimbobeda jimdeut06 jimmy +jinjji jippey +jjammerweer +jjerrbo +jjingx jjpanther95 +jkfizzy jkre jkthekilla jman +jmjmjt01 jmusilli11 jmw1031 +jndi +jnjo +jnlffs +jnyjny jobljobl123 jochieboy6 jodilynne +jodo wollos +joe the pop4 +joepie +joestrider2 joey0343 joeyisstoned johhny2hatz johndalton95 johnnyandtam +johnsmain johnstaLoL joje9 joji @@ -28363,7 +58434,10 @@ jojojo357 jokaranpampu jokemyster jokerpoker +jokkefar jokr +jolle rmm +jon ko jonehehe jones jonk33n @@ -28371,56 +58445,106 @@ jonko jonnetuinen1 jonnywormy99 jonppeli +jonwillbert +jonyants jonzii90 joohhhnnn joop59 jordaaaan jordlar jords +jordy8878 jordymans jorfee +jorge w +jorma heat jortdebonobo +josheroni joshuab98 joshy872 +joshykun uwu jossejoks123 +jossiee9 joster jouv +jovic joygi +jozn +jp s +jpjpj +jpmonkeyboy +jpruee jqzz jre257 +jrwheelyy +jslashk +jsoaksdawg jstrot jta1992 ju1ce +juaco torta juan09gon jubbediah juggernaught +jugiwow juice juicy jones juicyj03 +juicyjoystic juju +juke +juketsauli13 juks +julia uwu jullbrew +jumpe jumpshot7 +junami14 jungle jupi234 +jupilersjuk jupl234 jusiuke just +just living just2own justJust justLush +just_willie justamemerr +justaname20 +justapethunt +justarabbit +justin5454 justinttu +justluxy +justsomenoob justsomewood justwin4head +justwitching jutku22 +jutmeister juwgrehg8w30 +jwalty jwheaties900 +jwles jwov +jxdoo +jye2014 jynzziii jyripetteri jyyhnas +jzhua jzm0 +k a p s +k anao +k e y e r +k ep +k ian +k oga +k u h +k um man +k-rock94 k0ed y0oh k0mpact k0nch @@ -28428,73 +58552,145 @@ k0nna k0rrup7i0n k1dnam3dcud1 k1lla +k1lla cam +k1ngzinho k3yblade +k6k3 k80may k9k9k9k9k9k +kFlipsta kMikey kUwUmiko +ka r el +ka vi +ka wa +kaaf kaali +kaalwo +kaaskrok3t +kab000m123 kabal1995 +kacy +kaffetime kahleparta kahvi kahzaohimark +kaii tangata +kaimann kaiokenz +kaizen1 +kajyboyyy +kak_kis kakes kako666 +kako666 ii kaksaking +kalacaodan kalev +kalijaveikko kaljunaama kaloopsia +kalusto123 +kalxb kamekazi +kamerucito kamika kammoooooon +kanchazi +kandids +kanga roe kangaroo kannv +kanyefan22 kapot +kappachino +kappaross420 +karambamb karelzzzz karibola karil +karilol +karma dies kaspery0 kasperyo1 kasrug +kassi kastekann007 +katelate +katiegore katinnekke +kavachi kavinskie +kawasakki kawi kawkky +kawnoz kaynori kayxiv kbest777 kbuns +kc3 +kc3477 kcaaJ kcmeatlover +kdani +kdawg710 +kdog420 kdw27 +ke-bun keatonboss keegan789 keekluulz keep +keep going33 +keepitdedpls keesie7 keezuth kehd keilaaa +keiniks keittokinkku keittoo +keiwa kejo kekipua +kekw9001 kela +kela fan kelan +kelan miehii +kellapea +kemabi kembot +kemosabi kempster8 +kenchuuuu +kendawwwg kennynoodles +kenya help kepijuku keppuli +kepwontmax +kerekewere +kerm jump kerwin +keskorian567 +ket boof +ketaccino ketawuss ketchupfles kevin +kevinator41 +kevinnnggg kevpurp +kevvaGG +keyggre +kferd +khaki cuffs khxn +kiba420 kibeleza +kibsy kica7 kickback kiddoseta @@ -28502,98 +58698,166 @@ kids kidsteve18 kidz kiefcheef +kiiiiiiiiid kiix +kil lu a kill kill3r killah +killakristy +killanoob93 killconey84 +killcrab killd0zer666 killedual0t killerline +killnack killthatree +killwi5e killy kilpi +kimachevich kimbo kimpsa +kinako4 kind +kinda soft kindaanxious kindocool king +king lee166 +king stuff1 +king-tiddus +king420smokn kingblackops kingcuzh +kingdaddyIM kingdale26 kingerr +kinghrvatska kingknightf3 kingkong1211 kingofmanse +kingprince kingrizzla2 kingsardine9 kingsje kingswood kingvoid1083 +kinky fish kinobi kinzyyy kipitril kirby421blzt kire7693 +kireeh kiri2kun kirkaye +kirky 127 kisipicka kisses kissmyassetz kitashan +kitkats GIM kittymeow556 +kivipaska kiwidson kiwie +kiwiibear +kjekken kjellingeee kjeltringen kjems +kk lol kkDV kkangaroo +kkarl kkjamin +kkman45 kl00g +klaaore klacen klampo +klankerclean +klassiskt klef +kleshkebem kleu klexosfox +kleyver22 +kliefhead kll4mee9 kloh510 klojo103 klojo105 klopt +kluizen klycko +kms fast lol +kn0ws beers knani +kneel2me kneeslapperr +knickname +knifemanha knight +knightnate8 knobb knobby knokro +knotts knox kodakid98 +kofelad +kojak1211 kokimon kokinaattori kolb komari_k +konar simp +konb konch99 +koning broer +kontiainen +kony +koo de gras +kooks only +kooltrickz +koronaaaa kosiq koudekroket kounga koyhalaulaa kozel +kozina +kozzuu +kpt +krZ +krab meat krad +krakenwsn +krakim krakkakkak krakodile krat +krazyfaken +krb 16 +kreepingdeth kreeq +kreesie +krewl krikenator krillzscape krioyo kripu krisaaferfi +krnjellytv +krobi kronicganj kronopes kroodjebaass +krp +kruizin kruuuuben krxW kryptocookie @@ -28604,157 +58868,344 @@ ksubbi ktsmo kudryavtseva kugelencas +kujan2 kukerino +kukko soosi kukrishikari kulers +kulers bsk kulju kulso kulwreck +kumiko okada +kurasaki21 kurdikana kuro 275 +kuromi irl +kursa sucks kurtebener kush +kush tacos kushmas +kusib kusimursu24 kuvaiti +kuwait333 kveemanne kwak +kwak eend +kwall +kwarkje kwdn kwinus +kwuantadyme +kxde +kxlle +kxzu kyaa +kyanochaites kybl kyfu +kyle of pvm kylehwog kyles kylop kyssysmeua kyurem_vrah kyykanhenki +l Am Mathew +l Athena l +l BTW Envy l +l Buzzsaw l +l Click l +l Darken l +l EARN MAN +l Elija +l Fam l +l Feather l +l Floss Fish +l Flynn +l Freya le +l Hav Ligma +l Kelpie l +l Killua l +l Lena +l Love You +l Macca l +l Misfit l +l Mister l +l Nz l +l RSK l +l RWT l +l Snus l +l Steph l +l Succubus l +l Sw0rdm3n l +l Viz l +l am RON +l am cute +l cup +l failex +l lemon +l u g i a +l unchbo x +l-LEVY-l +l-Relinquish l-l-L_l-lL_l l0H3aV3nLy0l l0ne0ne l0rellai +l21 +l23 +l33tsuperh4x l3LACK l3W0FPI +l3en l3enjie +l3ezzerk l3ishop +l4n +l5h l7ivine l8tenite l995 +lA R R O Wl +lAlexAnderl lAnomaIy lBaecob +lBakin lBrent lCEBERGSLIM +lCONlC +lD an +lDFC lDalel lDanilo lDark +lDark ice lDerby lDezzy lDokkum +lE N VY lGuess lHawke +lHong Kongl +lI pv M l +lIHlIIlHIllI lIIIlIlIIII +lIIlllllIlll lJWl lJoynerl +lKanel +lKeith +lKenna lKenny +lKlas +lKyle +lLY Harambe lLewis +lLupo +lM Nathan lMarkl +lMercyl +lMr Zaros +lNSF +lNTOXlCATlNG lNerdRage lNolan +lPaleHorsel +lParticle lPeriphery +lPoe +lR0NM4N lREKEEN lReece +lRossy lRyan +lSaiyanl +lSellFeetPix +lSkinny +lSlayer +lTS ON SIGHT lTedl lTextbookl lTlTITlTlTIT +lVIaGiK +lVictorl lVitor lVlango lYungPlaguel l_Thunder_l +l_wyverns_l +la flare +lacefield07 lactosebad +ladsquiron lady-yoshi78 ladyspartin +lafreniere13 lagamuffin +laggium lakde99 +lakey peak +lakeypooh laks +lala u death lamJason +lambar lambreturns lame lamepun3than +lamironben lamshnarf +lamyourdeath +lanch +lanthe +lapyflapy laqsative lardosio large +large moist +large nob large pox +largewillow9 larinen larl larsbeuk99 larsnjun larvacorium lash209 +lasseboi last +last katana lastdcplz lasyy +later gater +latinamx +laughingbisc laura +laura froggy lawkingkong +lawo1 +laxasia lazarus +lazy aiz +lazydj2 lazyhitman lazzabazza11 +lcefiend lckle +ldy +le iromax leafsevens +leak organs +learncox123 +least toxic leather74 +lebanon d0n lebusoft +ledy0710 leech +leech iron +leech keeper leechyGP +leehi +leesha locks leetjojo leevi22 leewhiffy leewi leggie +legioen +legionbgbear leglizeRanch +legn-dary legohuis99 leipo leivonnainen lejhobs +lejhonni +lekkergras +leld +leliwuz1837 lellikedraak lemeborrowgp +lemm y lemon +lemon 25 +lemon cookie lenda +lengf +leo vzla +leos main +leoshnoire lepetitpois +lepicklenick lepo +lerpledore +lesel +letos111 lettam +lettername level-103 +level-125 level-596 levendi levon lewcifer8118 +lewdogg lexi +lexi bell3 lexicon7 lguana +lhommerun liamde +libad5343 libertador liberteeeee +licdik21 lick +lick my chad +life is shit lifesalaugh lifter light +light year lightfader96 lightningess ligma ligma2 ligmadich lihaamm +lihavadino69 +liisa liisankissa +lijkenpikker +like cooking +lil Mamacita +lil b +lil bumpp +lil chris 15 +lil ducky69 +lil gay cat +lil jev +lil mage013 +lil zeze +lil zuck lilBula +lilJacklil lilNoob2341 lilbitlifted lilchiken +lilcjay11 lilcuff lilgreasy +lilkcough +lill misfit lillelar92 lilliilillil lilmasterOG +lilmuscles lilseveron lilsquiddy liltunechi @@ -28763,195 +59214,385 @@ lima limona5 lindyman line +linebacker linkhg100 linlithgow lintydeer linusforsman lionking-PVM +lip length +liquidchese +lirska lisher100 +listentonano +litger litheum +litranmaito +littering an +little boat +little man 9 littlebumble +littleman699 littlemc14 liubei4444 livdumb livil liz_mar70 ljjjt +ljzerenmes lkalgo lkaoz +lkeaurhteakl lkigai lkjhsdfglkjh +lkkle +ll Grey ll +ll Zeke ll +ll jacob ll +llBear llIIIlIIIlII +llIIllIIll llKaren +llKris +llNephilim +llRevenantll llStevell llab +llaurune llerb +lletya sugma lleygo llhan +lliigmanuts +llitl +lllIlIlIll lllPeppalll lllnifflll lllogical +lllustrious +llo yd +lloytronn lluH +lm Drunk69 +lm H o T +lm Jard +lm Scoob +lm Stark +lm Washed +lm batman +lm scrub lm2fas4u lmAddicted lmBarryAllen +lmTrash lmao +lmaonation +lmfao ffs lmgur +lmmorral +lmmortall +lmpart +lmpatiences lmperishable +lmplication lmplode +lmpostar lmposter +lnSpectre lnYourDreams +lnc +lncendie +lncest Steve +lncestralTop lncline +lncredibilis lndain lndecisive lndika lnfa lnfernal +lnfiltrate lnfinitesoul lnformed lnitial +lnitialed lnkd lnquisitor lnsanewolfy +lnsec lnsertname lnspect lnspiration +lnv lnvictxs lnya +lo0o0lo0o0l loadedhuggie loadingman loasted lobi +lobssss +lobster pot4 +lobswordie local +lockluster +lococonut92 lococsgo +locustchrist +lofi cow +log item logMs logger2222 +loggiee logic +login down loginxtor +loisakurvi +lokdead +lolaskiller lolbert +loldatfunny +lolekx6969x +lolerrofl loli loliconflict loliron2main +loller63 lollydeepthr +lolnicebank loloharqia lolol +lolw +lolwhoplays1 lolxdmeme lolzzii lone lonely +lonely rider +lonelybutter lonewolf200s +lonewolf99s long +long hcaeb longbodd +longlabia lonko look1nAzz look2thepast look4clues +looking ass loopyloos loose +loota-criss lootshark loox lopiwer lopldopl loraxkiller lord +lord bimby +lord boozer +lordlazzy lordrandomZE lordrunekeys lordsamzju lordzyzzbrah lore2 lory +losbandito losee1 losing lost +lost to time lostchuck +lostingame lostpanda21 +lostwithiel +lotion on my loucks loueyyy +louisa loumit louw love +love bees +love haaze loveNfungus loveT0spooge loveablepand +lovebeastx +lovebite lovegoroe loveh8hero +loves a beug +loves moms +loveyoub1tc8 lovezz2pwn +low lQ gamer +lower caste +lowlyworm +lowrandom +lowstat lowwpower lpman +lreful lrin lron +lron Bladder +lron Fill +lron Kev +lron Mar +lron Mennis +lron Paladin +lron PvM +lron Taint +lron Tom +lron patriot lronBud lronConquer lronman +lronmanBtw lronmanCraig +lronnan ls32o0 lsdx lssabella ltachi +ltachi_01 ltaychi ltsJor +ltsJustified ltsMiller ltsYaBoi ltsYourBoi ltsuki +lu is +lu1gi00 +luc1d dream +lucaniste lucid +lucid olm lucifer290 +luck wheelie +luckeG +luckey7744 +lucknesshcim lucky lucky female +lucky never luckyweeb13 +luckyy vii lucuh lucyramon ludaftpitbul +lufteohl +luierick luis lukas +lukas2518 +luke the npc lukehm8o lukek22 +lukem0n lukewarmrod lukey +lukey pookey lukis159 +lukutty +lulllopiet +lulu +lummby fam lummywk17 lunamelina +lunar frost lunch roll lunchbox lung luolapeikko luthas luut +luv da grind luwl +luxyy +lv ie lvan lvarLothbrok +lvl 1 sleep lvl3 +lvon +lwesche lweyffaM lxli lymitz +lynx zan +lynxix13 lysander640 lyzolda lzrdlvr1 +m 62 +m e e p y +m i d s +m i n i m +m i t s u +m inimum +m miq +m nice guy +m x e m-moi +m00fen +m00fin +m00nrock +m0ker m0mentum +m0saic +m0stert m1ssing m1xos +m3g4m4n +m3nd3nhall m3rkzz m3tku m4ge4life4 m4gi +m4n m4ttay +m5q +m6ngel112 m8tio m8zi +mBucket +mGu +ma shnibbla +ma61187 +ma7shee +maadar sag maahhtt maawee mabeltwinkle mac_moneyy macflag +macgleeznorg machurrohard +macjonge mackbhamRS macke064 +maclean93 +mad bor +mad dogs son +mad hjorn +mad4cashh madara666 +madeustilde +madgamer45 madhat86 +madironman45 madman456789 +madmat38 madnijz madpaul1 madwebbie +mady I green +madzey maeonia mafiaz mafiz @@ -28960,16 +59601,25 @@ magerageftw7 magesticx maggpagg magic +magic me92 +magicarp420 +magick pp magicmike117 +magiskt het magnacarta +magnum0008 magnumdong94 magyarok3 +mah nickel +mahamoho1 maiden mainCallum mainyMCmain +maiy makarena makemon makenator +makkan69 makosoup maksavelat malfoy @@ -28978,57 +59628,103 @@ malmstrom malte313 mamadou11 mamatriceps +man spreader +manaakitanga +manameisjeff mangkj mango +mangocry +mangoszn manmeowmagic +mansbridge mantequille +manwhofish +manxster manyfac3god +mao maon maori maplegamer6 +mapletits maqr marbelo +marchdog marcinrulz marcmaralou marcwins123 marioflame marioswe7 +mark uk marketmoney +markobae markypoo +marmO0n +marmalarm +marr66 marrab marrciee +marrrcoman marshyymarsh marth2king +martickle marvypoo +mas koff +masdebator +masonkillem +masta132 mastafarmer master master9782 +master_box masterloveme +mastermisch masterpi314 masterseppi masteryi01 +matata23 +matiks matis6080 matiteusz mats +mats643 matsxe matt182xx +matteuce W matthew6500 matthoot88 +mattrabbit mattv matzRRR matzkia1 mauberries +maulnak maupz +mauriveitaas mausre +mav daddy mavrooo +max acc btw +max all max +max pet hunt +max yet jake maxcapealt7 maxed +maxed nelis +maxedtheaxe +maxgt96 +maxiicano maxiwiz +maxiyogi +maxplayer maxrevenue +may him +may lay +may thai maybe maybejarrod mayhemrs mazzahS +mb mcbig12 mcbreeeeee mcdonald @@ -29036,231 +59732,502 @@ mcgigity mcmadpac mcnuggetcons mcrane1202 +mcsoftee mdawg +me disabled +me espresso +me handicap +me ineffable +me no bueno +meOwNYXx +meat jun +meatball47 +mebigbob mechmillz +medicmain +medictbh +medium cloos +medium unit +meds bad meekmook +meemimestari meepify meerks meermaijer meetoihi22 mega +megabass megajoeck megatricks megoodpvmer megret +megxolotl mehloncoly +mehmuss mehunder +mei meinen +melangina melborn44 +meldrahn meleonlyslay mellaa98 +mellagro mellonman +mellow jack +melncholy melog +melog dog +melvin quit memephis +menaceirl +menarehot69 +mendier btw +mentasltu +meow for gp +meow for raf +meowthc +meowtism merryrice meskil +metblo meth0d +methcathione +method888 +mettleman149 meurtpo +mewby mezins +mf Catleesi +mf Giggle +mf neeko +mf yappin mfHank +mfHank Hill +mferJones +mg mhe00 miTzy +mia celtic7 +miaka yuki +mianbaoroll +miceworkteam +michaelma4 micheal michixranged +microham 69 microwave62 +mid clicker +midget man +midzy mie19 +mielas +migboincan +migidi migilicuty mihalys mikbea +mike 6 mike2290 mikefizzled mikeohtran mikh +mikko2112 mikkoyy miko mikomiko miksuwu +miku qwq milahreigne mild farm +mildMuscaria milfnmybed +milkpatty milkthegoat milkuwu milkybestdog +million sof miltryguy248 mims2dank4me +minato minatokill +mind goblin +mindislost +mini booty +mini r00d +mini rocklee +miningas +mininimum +minit +minky +minmax +minni mile +minor flex +minorhazzard +minsy minty1981 +mintyale mintyclintyy minus +minus Left minyhitsk0 miokaen mippim miqli +miramyra +miregal1 mirhagk +miriti +mis +misery2018 missingIink +missuy mister +mitchelle1 mitchrocks mitchvvs +mixed snacky +mk6 +mkden2 mkl782 mks200 +mksu +mkvo +mlars300 mlbg mlgb mlgkittycat mlkia09 mlong06 +mmaxie mmigo +mmmkay02 mmmmmmmmhmm mmmmmmnmmnm mmmuurrddaaa +mndo mniml +mno +mnt +mo an mobile +moer +mogwire mohak45 mohrs0 moist +moist P00P +moistSwan43 +moistcltoras +moithab mokkakulli44 moksi +mol 99 moldsack mole moleflair molkyrion mologgi +molten ass mombasaa +mombasaa D mondklapje +monero gay moneybandz moneypants +mongelman11 monkaS +monkasusdog +monkegrip monkey +monkeybisz +monkeymatt monkeywilly monkieturd monnan56 +monstaa +monsterje11 montaxus monteurtje +moo vo4life mooblesyrup +mooch86 moocowfish +moogz mooiboy +mookixx moomoocrab moonlighterr +moonona +moonpapa +moonrat2 +moonwyrms mooofy moor morPL8morD8S +morgan renee morgf morsotiikeri morty mortymoo +mos f +moscuz moska most +mostalpha +mothaload motmyfanny +motorbichael mountcaedo mpathetic +mpel +mpxd +mpz00ne mqaccat +mr atheist +mr boobrie +mr buying gf +mr mage t +mr pink1 +mr rob iron mr shroom +mr triggerd mr10inches mr12345 mrDragon2009 +mr_adore mrb97 mrbreadst1ck +mrdickbals +mrfox2 +mrgeck mrkaramazov +mrpurpdrank mrvortex3 mrwoffy2 msHyde +msb2595 msimmo93 +mss mstfu +mstr nay nay mtash96 +mthic +muchderanged mucserup mudbitedlite mufassa muffing muggfac mugii +muh +muh sheen muhName muhnamezjeff +muhnkydluffy +muin101 mulletman360 +multi genius +mum ranger +munalutkutin +mungero +mungkee munney munoz316 muovaz murders murphy +murphy XD musashi2109 musei +mushpinator +musnew +musta_matto mustaa +mustardsurma +musterdsauce +musty04 mustypill0w muta mutanen mutsCateer muufaanchu +muy bien +mv3 +mvgatron +mx mxgali41 +mxpurp +mxq +my fruit myballskin mychaelven +mycrazy life +mydmallsick myexdidntrs +mygf mykohchoo +mymoonkeyz +myname Borat mynamesDog +mypp +myrtlecat +mys_try mystic myturngranny mzsc +n a g a +n k h +n o m i s +n oge +n os +n00b tax n00btube +n00dIe n0DaT +n0n Believer n0ns3nse n0rthmemphis +n1ch0las n1ghtmares n3cromans3r +n4ts +n8m +n8n +nSubordinate nVox +nYer +n_koo +na cba naamarihomo +naapurintati +nabritches +nachoss +nae drops nagezz +nagoog +nah cba tbh nahbo nahhhh nahka +nahkasaurus1 nahkasohva nakneemo naksuu89 +naldy nalon34 +nalyD yrraB nambourian +name is damo namelessRS +nami skin namnori00 namtar elite +nancyy naner +naniichan naomi +naoshika napkins r us nappera +narbsta +nas xy +nashmvpx2 naskend +nassikka nasty natalya nathank498 +nattte krant +natty nest natur3za naturesque +natuurhuisje +naughty ruz naunas naven +navi my dude +nawilsi +naxe nayo123jo +nbyo ndrs +ne cro +ne hi +nebegyd1k nebula3 +nechs minute +neck bungee +neckals +nedpvm +nee ceri +neebzor need +need drops +need panoche +needs tips +neeeefe +neeloy neenisneen +neeshmow +negative neggibo neil +neil v neiti +neitsytkulli +nekemaribo nelrb nemofishtits neocritter +neoneu +neophyte8 +nerdneck irl nerf nerpkin netsh neuber +neukbare neutekind neuz +never lucker +never s0ber +never subtle +neverblume nevercash +neverenought +neviilz +new pfp newaccbtch newallmaster +news +newt merch next +next 99 nexus +ney spook +nezumileo +nfandango +nh0x nhy0x +ni ox niaya +nibbla nice +nice to game +nicelah niceslime nick +nick at nite nickdv nickel nickfx +nicky +nicnad nico nicoxpico +nieve nooooo +nightmareram nigriV nikhil nikler @@ -29272,20 +60239,53 @@ nimlif nioem nipsunaapuri nishkid64 +nisq nitro nitsuj315 nivk420 nizmoNL +njitram +nk spy +nko +nl Airo +nmb nmhbu +nmzcow nnick999 +nnko nnmf +no birds +no engraving +no flek zone +no gag +no gay ok +no l00t +no purp bug +no use +no1evrnos69 noDDD +noTheOwNeR noThumbz +no_odles noahcous nobankpin +nobjockey400 +nochoc +nodeLT +nodropman noek1 +noeyi +noice garrry +noiteerIW +noki keppi noldaddy +nomiS +nominMaxCape +nomlaS norI nomorelies22 +nona nona +nonamechange +nondedjuu nont0xic nonuboko noob @@ -29295,21 +60295,41 @@ noodle noong nopies noplanhere +nor so osrs +norI Ryan +nora cat nori +norm HARDY normal normie nornavsoc norrisi +nos nosemar nosepack noskilljoe nosnhojgib +nosoberday nostalgiaeng noswaL +not Duncan +not chop +not cumingbk +not gods +not heppi +not herbo +not him dude +not shaken +not tiv +not tk +not today m9 +not ual not1stepbak notEdited notPape notRoyal +notanjiro +notazerk notbennie notdead91 notefficient @@ -29317,54 +60337,119 @@ notepad0164 notepad14 notlikedis notsoB +notsosmart11 nottrade +notwack noutonme novali1 +novike +novikid nrakneS +nrdz +nt combos ntarallucci nthing +ntrstng +nucnad nufnufaz nuggeets nugs +nullbeing nulluserid +numb3r go up number +number 11 +numbly numnut +nuoli tulta nuopisa nurbaya nurriez nusta +nusta but +nut low +nut5ack nutes +nutpeanut +nuubbaa +nuubii +nvcu +nvrpurplight +nwate nyareet +nyc ramme nyet +nymue nysyGG nzskater +o Buffy o +o Galaxy +o Jay o +o NEK o +o Pug o +o SiLeNce o +o Steven o +o c c u l t +o chem +o n e i n v +o tp +o tu +o0 Rang0r 0o o00dan00o o0Ganktank0o o0mni +o3d +o9 oAQu1LeSs oAlsen +oAmber oBugz +oBuster +oChezzeRo oClairebearo oClay +oColeeey +oDemko +oDriew +oDrizzyyy oFelipe +oGMRKay oGreene +oGun Smokeo +oHEXo oHoriizon oHxD +oIce Teak oKsirf oMDmA +oMalevolence oMoJo oOGeorgeOo oORagnarOo oOoITITIoOo +oRonde +oSanta +oSea oSpecialx +oTARNAo +oWags +o_o SEMA o_o +oaenii oaflion oaisjgljlak +oaj +oakypinkre oatenz obama +obamas ass +obbE x obees +obej +obese_man61 obican obitokun obosk +obvi_no_gf ocbslim ocian ocruT @@ -29372,100 +60457,222 @@ octazookaa94 octopussi11 od1np1ck odafan +odd woof oddfinn +oddniffler odenthas +odinsjourney odio odlolien +odty odyssey oerinn +of a china +of booze +off balance +offends offshore +og kasi +ogag +ogbrittney +ogeesus ogg25the2nd ogned ogogog ogteleblock +oh no fuse +ohSmelly +ohai ohai oheesnose ohgoshyjoshy ohh_man200 +ohhh nooooo ohhnnnoooo ohia +ohio is for ohioisonfire ohiostate347 +ohly +ohmyrod ohtukurva +ohyep +oi ranga oids +oigia +oily rod +oilysurprise +oixi +ok baba okannah +oke oksen32 +ol Twizted1 +ol kq +ol pleb +ol_l olatrekuk +old Soul rs +old kind 911 +old man agst +old man zedd +old meat +old mem older +older fruit oldsports oleNeilyBob +olen lahe olindaelostz oljon112 ollie +olliedamage olliethekat olllllllo +olllllllo TJ olmec olmmmmm +olms beach +olovi kolome olsyboi +olvia omavi omegaOnepump +omff +omgbabestop omgimacarrot +ompahelppoo omrip96 +omwtotob +omyefge +on 9 +on the fella onalite +onbak1992 oncenterlink +one 69 +one1one1one oneblade onelifehaze onespringday oneticktony onex +ongelmanuori +onizuka onle onlinetares only only4pvm +onnetar +ons va +onthebook +ontspan maat ontv1992 onyo +onyx no oo7jordan oobent ooblued +oof mikael +oofbored +ooi +ook Thunder +ookbye ooli +ooo Papi oooRush99ooo +ooooby oooopsiee +op +op P openyoarmpit +opiumwet ii opneemvot opticsnail opzu +orangeluke orangetree34 orb in bag +orb knob ordy orebac +oreo lil oreru +orexinergic orez66 +org asms +orgasmdonor +orielor orig +orir +oritx orkans +orkut +ormz +orophyr +orra orrichimaru +os SlayScape osJuhiss osbhuda ose420 +osmati +osn +ososrswhen +osquiver +osrs Apathy +osrs MCFS +osrsbilly ossaciM +osu +osynlig otallone +otdog +oteb otherguy3668 otoboR +ottledread ottx +ouic +oum ouououuoouuu outohere2k +outsmart3d outsourced ouwe +ovas bis +overact +oversize rat ovox +owen4boro owenwilson ownsome1 +ownt by flan owo0 +ox +oxifaze oxoxoxoxox +oxtale +oxyy +oysni tu ozos +ozztrevor +p hd +p n g +p x v x m +p000r +p0ge +p0tat0_baked p0w3r p0werSinn +p0werliftin p2pell +pAj4ri pHqiXfQb5rpO pRandgris pRiesty +p_tane +paatttxxi +pacack pacbackpack paccerz pack @@ -29477,18 +60684,29 @@ padq pagakoning pahe painter2020 +pajiaobin pakgg +pakkohoito pakoonjuokse +pakwatch palacePier paladylan panda pandahands +pandas flail pandascapes +panel v2 +panelupgrade +papa jjinx papaisthatu papatec paper +paperbutter parB para1911 +parsakeito +party-joiker +partyinferno partymonkey partypooyan partypossum @@ -29496,6 +60714,8 @@ pashol pasismi paskapylly6 pastry +pat summitt +patbeerpants patches4623 patnazNkryme patriciogmz @@ -29503,9 +60723,18 @@ patrol paul94nl paulimvitor paulmacawk +paw fetish +pay peru payout pazmar +pb tiramisu +pbagel +pbj eater pbjt +pcce +pd3 +pdi +peace love h peaceofbread peaceoverwar peacsenur @@ -29513,151 +60742,280 @@ peajy peakyberry pebbles256 pecemker99 +pecker neck pecko517 pedagoog peeje peenwa +peepeepeepe peepichu peepoGamer +peepoParker peerks pegfemboys +pegge jr peksi pelaan peliken2 pellemaailma +pelmot +pemmex +pen gee23 penakonda penally +penile pain +penny 4 thot penteroinen +peoples0123 +pepe max +perc ceo +perc5 perckey +perigor22 perlecta perm +pernieuw +pernix +persepullo persesreign +persisted person personajay22 personal +pesto pasta +pet melon +pet my mole +petc0 +peternguin petesmcskeet petlucksucks +pettyrogue pewbs +pezzler pfiati phatpunch +phatsocallum phattymaster phen0mXD phenotype pheras phetagoras +pheyyw phinex +phlayme phonon phoop phorme photolstamp +pi n g pibbi +pickle llama pieater_314 pierke pietu pietun pieww +pigeonkisser pigeontoeman +piggybosspen pigusvaistai +pihseurc +piia potka +piie pikir +pikknu +pikkukala +pikkupeppi pillman +pilludemoni +pimmscup +pineapples56 +pink soup +pink spoon7 +pink4 pinkdragon76 pinna67 piomon +pipiopi +pippelisurma +pippy 429 pipratoos pir0tekniq +piraat bwana +piratedog7 +pisk naxui pixelpeat +pixiedrank +pizano pizzaforce33 pizzaloksi pizzalord321 pizzerr pj137137 +pjmonkey03 pk3rsh34v3ns +pk_all_pk1 pk_by_me +pkdrwho2 pkdude116 pker +pker ice pkerdude559 pkew pkpk +pkshitomario +pkwy +pl33k_supa pl3d plaatshouder planetflat +plank r +plankforsure platygirl play player198792 +plea pleadingface pleadtha5th please pleasebuyckb +pleb Remains pleb166 +pleben plebminister pletsjer ploomert plopko plszulpet +plum lee +pluma plumb +plumb bum420 +plumit +plumpy nut +plz dont kry plzl +plzvenmome +pm 2 spy +pm4 boost +pmax pmmefeetpics +pneck +pnn +po0z +poachpenguin +pocar +podginator +podolskee poesiewoesi poesiwoesie poffdragon1 +pogarmyy +pogdoor poggersgif poggie pogglewogger pohaku +pohwe pointn +pointright +poire +pok758758 pokas pokemonsunim +polentusmax politieman +polo gee poly ponderer pontlarge +ponyika +poo from bum poobutton pooga poohwell poolbadger +poon fisher +poon nanny poop81 poopeepeeman poopsm0ke +poorlyhung pop-tato pope popstantot popwig porkchop-kun +porkchop87 +poro600500 +porpleRanger poseidon0928 post +post nut sad potato +potato pleb +potatogod62 +potatolove20 potatoplayer potholderz potionsell3r power +power helmie +powercheck6 +powerpluging powerslide +pp 73 +ppb +ppdandelions ppengu ppfighter +ppidd pr0jectcarry +pr0kkeh pr1est +prQmethazine practice +praskiepas +prayfx preachably pregnant pretty prillage +princesstktk pripps0 prkr prncss pro90 problitz1 +progmog +project eggs prom +prostate proud2bbalin prtck prut257 +ps1 jrpg +pshot25 +psp 11O6 pssssssh psykotic12 pt37 +ptdn pubnroh +puddskape69 pudgy pugginSpooky +pugmen +puhkipantu +pul uk +pulinaseppo +puljulaine +pullo viinaa pulpfree +pumiss pummi984 pumpkinslaye +puncher punchlineNL pungur punken @@ -29665,63 +61023,137 @@ puny pur3gh0st99 purEvil808 pure +pure owns al +pure wood23 pure10693 pureblackid puregluttony +purity purpfanatic +pusha tree pvm bioodz pvm-owning +pvmingbr0 pvmrob pvpmirage +pvtRyansPvts pvvm +pwn me plox pwn0grapphy pwn2b3w1ld pwnnya +pwuh px yra pxls +pxtchy +py ze pynergy pyro pyro255 +pyromaangast +pyttyyn +pz pzqlpwbma +q Aleks +q Nossie p +q b0nkerz q +q f z +q l l u +q sl +q-Mini-p +q0k q9q9q qJezza qOsMoSiSq qPepsi qQazp qTiger +qazi qazio +qbc +qbi +qbt qckr +qerw22 +qez +qi e +qiany qiunc qiyamah qlxxlp qnzjosh +qoao +qooo +qop +qorbin +qp +qpwoei1029 +qqgoat qsse +qtAlice +qtb qtei quazepam +quekchose +questarila queundas +quickiies +quickmoist quickster61 +quit afking +quit cry quitb42k quiver81 quky +qwaylub +qwerps qwertralph +qwerty2431 +qwertyboll93 qwertyuiozxc +qwl 2 +qwopr8 qwruqwpourqr +qy +qz qzxz +r a i n i n +r a i q +r d x +r eflex +r ehab +r i ley +r n g o d +r o c h i +r pt +r u a pussy r0adh0g r0jasss r0mera +r0p3_tv r0yalrag3r +r1ch3r mitch +r1chmond +r1ddlbox +r1z1n r3laxed +r3mov3k3bab r4cky rAEbl88 +rIcHmAn4 rMatey rVino +r_rl +raando rabid +raccy rac +rackee chan rackelzz rackemballz rackzcity racoon96 raddawgg +rademakertj3 radox rafa2424 rafnek1 @@ -29731,28 +61163,45 @@ ragegoon206 raid raiden raildex +raisin canes rakete +rallikaar ralliss +ram this +ramafie ramblin +rambo 1206 rambombon +rambroze +ramjamyelham ramsesthecat ranarr ranarrbiss random rang2d range +rangedp00wns rangoraus ransty +rarefleas rarekia rarru rarurrer +rat catcher4 +rat ritual ratboysteve rateddd +ratirl +ratirlAlfred rats +rattiyanee ratzzzzzzzzz +rautamon +raves m4ck raving ravioliwren rawheadshot +rawkneedong rawr rawrsmashh rayhoon @@ -29760,31 +61209,56 @@ raymanvh razorwheels1 razzdnutz razzex +razzmatazz23 +rb winter rbjk rbootsGOD +rcr333 +rcyy rdrluvr77 +re-frozen reBoosted real boyo real-derin realAxu +reallityfail reallyhigh realpcooktho reamillion rebirthofyay rebuildd +rec me reclinedgmr recognizable +reconjack +red eye jedi +red fox8 red504 +redank redberry redditlucio +reddragon950 +redeye q p redgorilla12 +redhunter193 redman211 +redpatch redracecar27 +redrumyliad +redsheik redsox216 +redsp3c redwagon9 +reenur reese +reetznutz reflexlols refurb99 +reggie v2 +reggieblunts +regorydog +regular ph +rei1315 reikimastr reilaria reistje @@ -29794,298 +61268,604 @@ rekrog rektum relac relaxed +relaxed now +rellu riku +reluf +remind remind309498 +remko maxed +renaissance +renasue +renruB +reopened +report you +reptil51 +reptile reas reptilepoop8 +repulz resU resetcentral +resupplyalt +retern retrrd +retuson retzc reznas5 +rezpek +rfr0sti +rg44 rgfji rhey rhiller83 rhygan1 +rhys c ribalibali +ribe4 ricard0live ricardos78 richarb14 richy +richy rain rickrko +rickthick73 +rickystackss +ridewitme riilis +riipx +rikkertik riksa123 riku230 +rikuirl riller rils2 rimpati +ringo794 ringosting0 rino +rip dj ripHuyy11 ripbobthecat +ripend +ripsrc +risbarn +riskbizz +risker +ritcey rithvik ritotrisoto riuCooler +rizn +rjh300 rjweb rl9g10rs +rlkgfseorhfe rnatt +rng god x +rng limey rnom rnue +rnv +ro0b0 road2broke rob nagle +robbinator27 +robhode robilo123 robinchris robo +robombalt +rockcrabpvmr rockeroHN +rocketberg rockhead7746 +rockstarwht +rocky leeg rockyandtaz +rockyou 2 +roest roflbaker roggy roldan_one roldunogene +rollsyy +rommmey romper +roofy rornburst +ros n +rosati924 +roshambee rossdark1234 +rossmain rostiefrosti +rosullivan8 +rot popstar +rotceleS rouge +round cat +round kc +royalpanda53 +royce ranger rqkrtzjvbsuh rrautamies +rriot rrrpR rrrrrrc rryutie +rs3 blows +rs3dansgame rsoby rsruinmelife +rstr expert +rsyux rthgo200 +ru-ne rubengouveia rubikslayer rubj3llyonme rubtuge +ruck ur dad +ruding ruikkuapina +rukdingme +rullakebaani +run amuk +run its bc +runaru +runaway iron rune +rune dogger +rune enjoyer +rune poon runedongs783 runedragslay +runeferyearz runehol1st1 runeika runep3 runequeen163 +runesc4pe +runesoftime runetraction runite +runite bars rupt +russien rusted +rusted shaft +rustigggggg +rustinged +rustys word rusvet rvrse rxbi +rxylvrn ry1n +ryh ryppyreika rythail1 +s h l o o p +s hok +s i r tinly +s k i p o w +s laack +s n u f f e +s nekk +s t i l +s tress +s0spwnz s0uln0te s0ultage s10w s11gm4 s1ayerg0d +s1pa +s1r maximus +s3fa s3nna s3nt s3ppa s3vuu s4mu +s4nc s7v7nty +s7vey +sCUM Runner sKDestine +sNEXyBaker sSahm sSpring +sTs W33D sTxje +sYo +s_ck it +sa ko +sa-ku +sabfas +sackiltrog22 +sackmen sackmyduck +sacredchange +sad nmad saddest sadgeboi sadnmad sadnmad666 +safe bunnys safermoon saffyO1 saffyO2 safino saguyuyu saiko +sailsouls saintffs saiyansmithy +saknoM rD +sakuyaaa salad +saltia saltycups saltynads saltypepper +saltysealife +sam ofc samdegreat same +same hada +samo0o +samoht10 samothon samqwop samtatt1 samuraigod13 samwise1133 +sandai korky +sande108 sanooJ +santa cloud +santa ho ho +santorio saphinix sara +sara 35 +saralandry sarcasmz +sari essayah +sarppatsu sashamii saskecas1 +sassy fool +satisfried +satsuJima +saturos159 +sauna41 sausage savPalestine +savage_grey +savi 2 +savukorilas sawb +sawb0ssnl +sawl7 +sawshoulders sawyfabj +saynototofu sayyless sbrand0n8300 +sburzz +sc arlett sc00ben scaffidi scallicci scape for 1 scape4ever20 +scapey123 +scaredbunny1 +scat wagon +scb +sccrub +sce nes scerp +schaamlap scherzmfromz schetts +schiggs schildknaap schmashmu +schneeple schneky +schnibbyy schzu scidder123 +scitles scnick scone99 scoobydooby9 scoobysdooby +scotian 902 +scottslipper scottuzamaki +scottydo27 scout +scout robot +scrollspirit +scrotumfart scrubEE scuffedbrain scuffi +scumbag 66 scuterholmes scythe scytheXI sdfsd125 +sdotmaxedout sdzl +seBlait +sea owl +seabird seachrome +seacowcow seamondemon +search0 seared +seawolfsam +sebbe osrs secs securite +see attached +see me whip +see4limbs +seepah seetod sefeeee +seffimz seizure sekkuso selfShow selfcurse +selfish coal selling +sembino semper +semperstrik3 senZe senapsgasen sendu2edge +sendykap +senggg senpai +senpai btw senseyf +sentterih seppem seppes121 seppevb seppohaa septynetas +ser angus +ser tugger +seraphine jo +serbuttkiss serious seriouslee98 serpentSmelt +servix +sessarrow settyboy66 +settyz +sex mum +sexy skuxz sexypersian seyed +sezery94 +sfinx71 sfnative sfsdfg +sgaben +sgf419 sgg9779 +sgk +sgq +sgurdevolii +sh-Y-ft sh1nan1gans +sh1ttyrng sha0ski sha7y shabado +shad y shadex94 shadow +shadow brr +shadow btw shadow77440 +shadow926629 +shadowarmy +shadracker +shafli +shakedabooti +shaking irl +shamabeast shamans +shambbles shanemck shantyklawsh +shape share sharingbox +sharkey_32 sharpshot776 sharto86 +sharyn cox shasd whip shawnn1 +shayge +she btw +shed dabber +sheep5 sheev85 shekelgoblin +shelfy 2 +shents +shere khan1 +shes sleepy shezze shhit +shiddingpant +shields_zzz +shift drop shifty +shiftydaboss shigha +shiky shio +shishiodoshi shisui +shizcake +shkoB0 shliure shmoopaladoo +shnizzlebear shoarmamama shokki +shoopa shoot162 +shordilele +shore +shortsleeves shortstroked shower +shoyu shreddin shredness +shredskater shrek5 +shrigma shrlmp +shrooon shroooooooms +shrootfarm shroudyroudy +shtos +shturpants shumili shushlik shvxstxchla shxg +shxyzzz +shy lo siNusas +sibeepboop sickGeneral sicklyhare sideways640 sidney3241 sienna +sienna sleep sieracki sigh sign0ut siik siimzz97 +siiz +sikatopi62 +sikazz +silburr +silemani +silenthenk69 silentical +silenttrew +silim acac silk +silly cowboy silvar93 +silver bean1 silveraze123 +silverwar33 +silvethril +silvio lol +simi sai simmeg +simp 4 life +simple +sims Hsp +simz +sinannani sinappi688 sindicalism +sindulis sinfulnature +singlemom34 sinsofmany sippin siptar +sir ecnar sir skau sirlotje +sirmesoulier sirpaul sirpoopball5 sissijuustox sisuwu sitonmaface7 +six2midnight sixanddagger sixerr sixovercrest sjaq sk0me +sk1rttt sk9bord skaiii +skaios24 skandaali +skaring kids +skateenjoi skaterdogz skatermatt91 skatterpunk1 +skaugi +skcusxegaj +skedie +skeide skek skeletoon skeli sketchdreams +ski skidipoppop skilgrave skill +skillachris2 skiller270 +skilleuhjong skillmaster +skillngbot41 skills2millz +skillz davoo +skin suit skinny227419 skinnypimp71 skipz1419 +skittels +skittlesour +skiu_21 skizzurp +skizzy sammy sknzor +skoalintry +skoowu skorthen +skowotek skranzii +skrenne skrtskrtpvdb +sks110 skuccy +skuirk +skunk nugs +skunkpaste skunkskillzz skyE skyelar27 @@ -30093,50 +61873,101 @@ skyffoxx skyz skzs912lav slaack +slack austin +slacky456 slajdaren +slap her box +slappfisken slartiste slavhouse slay +slayJTIaster slayer slayer92 slayerfrog57 +slayerxp +slayetd slayhore slaying +slayzerot sle3k +sleek2d +sleepinonice sleept1ght +sleepy 940 sleepysleeky sleepyweasel +sleightest +slemgaedda slice +slice O pie +slickstick21 +slickvick21 slidesteps slidtegitte slight slight7 sliginz sliim +slim in dar +slim j3sus slimski +slinnGimme +slippaa +slipstrides slobthyknob +slowmopwns sludgebag +slundersc0re +slurpeeboi9 slurpeeking9 slurpy40 slurpydong15 sluz +slvtty slvt +sly seyda +slyhitman slypupper +slyr4ng3d +sm0ke herbs sm0kebeers smChi smackbo +smaddz +smaggd +smalcano +small boaty smallmichell smallppbigxp +smalsey smasher12121 +smasher95 smaugs +smbonn2005 +smeerpijper smel +smelly fuss smellyducks +smerq +smettjes1 +smh Monkey smiithy smirqqel smithdarts smittty2009 smoe smoke +smoke buds +smokesIetsgo smokin +smokin turdz +smokingalone +smol bat +smol chris +smolBen29 +smoothcamel +smoothlover +smote smoug007 smrgn smuqu @@ -30144,142 +61975,276 @@ smurfrookie smurpfy smushman snaggle +snagnURkill snailydog snakehuntr94 snakenbaked +snaplocket +snapped neck snarfoo snck +sneakY geeB +sneakyleazrd +sneakyyj +sneekeysnek sneeky snek +snek killa69 +snek man_44 +snidletics sniff sniffmapouch snikkels +snipper143 +snoogensss snoppen97 +snorlax481 +snot aap +snow dude678 +snowdance +snowfild +snowkeepuh snowy +snowyhawk45 snowysonic snoxxyl +snp500 snubsnub +snurtfe snuskfet +snuskukken +snusnuending +snygg o smal +so joe +so jung mijo +so much ass +soarix +sobsk soccerdog +soccermom82 soccerrad177 sock socopb sodChamp +soderfalk sodynamic soft +soft dab +softer bugg +sofus64 soggybread4u soggywaffel9 +sohju soiled sojraal +sokoudjou solfam solidon solo solodiyloner +solodoloyolo +soloeraut solopops solos solost7 +sombb +somber some some1saybags someBODY325 +somos papaya sondrep sonera +sonoboymw +sonofablitz +soobli +soombie +soon2bxwife +sophiebear69 soppel +sorris alt +sorry +sorry pls no sorrymatey +sotaneekeri soul +soul et luna souldrainer soulkamikazi soulkra +soundspeeds +soupnbannock +sourkraut soxx +sp3edie +spOnsOrr +space craft +spacemanriff spaceonion44 +spagh bol spam123 spangulation spankmoi sparkoftruth +spartan1137 +sparterrang9 +special k258 +specialton specuri speed speeder269 +speedtrain speeeeeen spell +spenmaso spete +sphicologo spiLLLLL spicke21 +spiderman 13 +spidey spigems spinova +spiwit twee spladay +spleiner spletcher2 spliffens sploobie +spoiled mayo +spondonicles +spooki xd spookib spoon +spoondrngplz spoonfed +spoontarded spoonyg +spoooficus spootineftw spord8 spozz +sppak sppoh +spratel springAnonce springplant springsteen3 +sprite zero spritelum sprits +sprsp +spudmyster +spugEddi spunkontitz +spyde96 +spyrolegend4 +sq shield sqad +sqrls +squareheadfk squatlownslo squidnstab +squirrel1991 +squirt fan +squirts +sralisas +sray +srd srgynt +ssA taE ssei +ssh keys ssj3 sspiriNut sssu ssttaann ssyd +st aeryn st4k3l0rd staarii stabbycut stabekk stackables +stackagawea +stahldog stainalt +staleburrit0 +stan darshhh +stannaz +stannum star starcrosdlvr +starfalI starknightsy starshoppinn +starvn-marvn +static void steadiskill stealthwolf steckubnU steel +steel slime +steeljake steelplums steeveee steezybear +steezyledge stefanopt +steflon don stekkeT stella1 stepbro +steph n stephvn steponnopets +stereos sterre1ch +stertanz steveagogoo stevenovak6 +stew thru stewiii stfn sticc stickuppix sticky clay sticky holes +stickygirl stiff +stig sucks +stiice +stikybandit3 still +stingray2018 stinky +stinkybunny9 +stinkymooner +stokstaart stoned stoned84 stonedowned +stonerwelds +stoneybolgne stony stoodzy +stop log +stopbegging +stopy wersow +stor m storkis95 storm stormynight +stouterikk +stp3ach str3tch33 +str8 balling straangeDayz +stradiSlay stranglege +strap locks strateigo +straw cup strawbery strawnk5 streetshark2 @@ -30288,63 +62253,125 @@ striker strnagetamer stroudlee strp0tzz +stugex +stuntti stupid +stupid game stupidcape stupot845 stylebend3r styrkekram styxRYAN +sub merge sub2purple sublime +submunculus subooptimal +substring subzero +suchti +sudden sloth suga +sugar d0nkey sugarfreeman +sugarwater +sugme nob +suheil69 suhuan123 +sukau sukc +sukidarkra sukii +sullz +sum1elsecall summa +summa arte +sumsy +sun delusion sunaert +sunday tea +sundburgaren +sung101 sunkir +sunkirrr sunny +sunny sponge +sunrakuz +sunris +sunu +suolahappo +sup J sup3r0n3 supagorilla +supalordwar supbruh super +super slooow +super system +super-thoms superbuds supercolds superj4 +superlisko superlonely supermanJJ +supermarket supermaxx +supermoist superr supnoobs10 suppertmain +suppus supra surfboardcat susanno +susdog +suspect12 suss suwo +suxc +suzuky svedanya svennepen svenskeren80 +svettnisse +svimmelskam svoji svrN +svstre +svti svver +sw x swag +swag dr +swagburgler +swaggabawz93 swaggb0y0wnz swaggie365 swagscape666 +swake420 swamp +swamp man_43 swampertman8 swampwitchx +swampy fool +swansoup +swasian sweaty swed +swed 420 +sweet ass sweetpissin +sweety 77 sweggdaddy1 +swerve q p +swfc50 swfc51 swftz +swiet +swiftmango21 swissbagette +swol swolelord swooinc sword @@ -30352,130 +62379,256 @@ swordngun3 swordsplay62 swxasxx sxkes +sxtt0 +sxybro sycp +syklo symmm synack +syndra007 +synnistra synterrafox syua syytu +szer szeth17 sztuk +t iel +t imbo +t r a m +t rio +t u k e +t ux +t-Wrench t-painn +t0_valhalla +t0ast mal0ne t0c00l t0nni +t0xicpoptart +t1n3 t1tz1 t4aker +t4t frot dog tOxI tRIPdoubt tRNA +tSessa tZiMiNt +ta det lugnt taasen +tabbionny +tabulast taco +tad3j +taeyeon tage3xx +tak0981 take +takimoto +takotime +tala 7t talinklion talisam tallest +tallwhitebr1 +tamesh +tandem dooks tanfastics tanguay478 tanklesss tankyster tanuliina +tanzfangplz +tar targ119 targa tarpGC +tastenz tatarsauce tatuwah taxed2 taybonejones +taysmehu tayyab +tazzen +tazzzz31 +tb 3O3 tbaballers tbach tboowscouter tbow +tbradz tbrey24 +tcorky tcroft +tdawgthekid tdoe +tdogtsw +tdslaterG tdufflebags +teagantime teakte00 +techev techeverria technitions +teem0her0 teemerco +teh_new_guy tehe302 tehskoozy teini_horo +tellymantel +temmi69 temx tenac tentacion +tentacruel38 tepaseohijo terenerd teroy terrence +terroristiI9 +terrryfold +tescoworker6 +tess tlckles +testokersa +tetinhaaa tetsundo teum +tevlevdeR +tewwowism tezje tfortal3nt tfsi +tfw +tfzx tgchick3n +tgkiller +th0my188 +th3engineers th3m0nrr0 +th3physicis7 thaiboygoon thajokerkid +thames1000 thasonn that1stoner +thatbaldkid1 +thatbuttguy thats +thats bone thatthicksix +the 2 of us +the G herbo +the Unreal +the Zec +the afg-gun +the assail +the big girl +the capt +the creaper +the girls +the kleeborp +the lupo +the lurkkii +the mighty R +the ocean +the suns theDazzling theFish theH0witzer +theHNC theMatan123 theSuperb0wl theWOODchpr +the_blindguy theachaian thealemdar92 thebestgf thebrucelee +thecoolbro97 thecwakecake +thedamoes +thedarclit thedarklit thedyermaker theebeker +theeib +theforkster +thefunkmonk thegamebad +theguyman160 +thehow112 theironlotus thejonsson +thekingkane1 thelanco theletterbla themaestrox thematrixgg themrgiggles +theon theonebrova thepirateman therangetank +thereal bi n +therealAxu +therealchr1s +therealinfex +therealramba therminy thes5016 +thesavior315 theserpent +thesmurfster +thetibo thetoday thewooshh +they gave up thezucc thhxd +thicassglass +thicc dady thicccc thicchode thiever05 +thijssb thinker thinky this +this blunder +this gu y thiseku thisthat2019 thongmasterb +thoomed +thosma777 thot +thot tub834 thotortiana thoughtz thrakataluk +thrashcan86 +three2one0 +thricer +throat queen thrynandwen +thug z9 thugger +thugli thundeman999 +thurgo pie +thwison thx4zloot +tibbs plural +ticklemesack +tidnabregdab tienermoeder +tigerturtle0 tightteen97 tijgertje3 +tiktok rizz timaye56 timejumpsolo timmaxio @@ -30486,187 +62639,376 @@ timmyjoe643O tinmer tinnaytookit tintaria13 +tippystick tipua +tipyt0p tire +tiredcloth tisbea tissiliisa +titches wit titsanddrags titty tittyjuggler +tj44 tjappko +tjcombro tjd1233 tjomka tksnevrlucky tmahones tmeer +tmeer 18 +tmjdx tmued +to dd to0Oldf0r1t to_o toad toad03 +toasted max toastfinder toastypoast +toatsme42 +tobiasalex4r tobinoo +todd crosset todtplanker +toe2 toebumper +toes +toesmeller87 toff +toff haha +toffelboy +toffij tojo228 toks +tolerable 24 +tom hutch +tom widdle tombaum tombradynfl tominator87 tommybun +tommys488 tomrichmond9 tomriddle09 +tonko tonttitonder +tony danza tony el gros +too bad +too known +toolbar toomastoomas toonits tooowise toot +top her 1000 +topdollar topgun 17 topgun343 +topie +toptom90 toqs1986 +torfy tormutrose +toronomans torpedox1 +tosspot12 +tossta tostaempo +totip46 +tottti touhutimppa +touma +toxi +toxicburn13 +toxiclun toxicsaitama +toy Owner +tozmic +tq tr0nberg tr0nd tra1nwr3ck13 trade tradescreen +trading law traevitz traffic +trafficly trainman222 +tramayne +tranquiltoad tranqzz +trans trapbag +trapizium01 trashy trattqunnar +trav50 travym66 +trcky americ treboolks treetardo +treezy tremmu +trenboloneyy trevor4ever trevs +trevs iron +treyblob triangle28 +trickyerrr trickyricky +trickytoad59 triggaevery1 trikyricky trilla tripin +triple fin triple pre +triple zero triplefiter triplelmao +trippel agen +triv hamzy trojan break troll trolling +tropiiix trout troutking96 +troy the mak trso tru3 trucker74 truskey trustfundcat trustsfund +truucas +try the wiki +trying2quit +tryksta trytohuntme +ts4ever +tsqq tstrong5689 tsukemen +tsumino tsurie +tsw tswiftfan82 tthe ttnq +tubu +tuggly tuhdhuderr +tulieee tum0ppi +tumeken jyra +tumme tummytickler +tumunduktu tunalife tunnepelaaja turban911 turbo +turbo nut +turboChett +turboboost93 turboed son +turbogamer12 turbojoey turbothots turkishh +turkles ahmo turn the 6 +turnt turntBurrito turntgod711 turtl111 tututu tuumas +tv_vt tvmv twasnotready +twelve bags +twelvecharac +twelveswords twiceascool +twink irl +twinr0va +twisted tina +twistedgirls twisty twitterclans +twixinthemix twiztid5000 two4nine +twohandedfap +twotoedsloth twrangles +twubble +ty RuneLite +ty zmith ty4flail tyguy tyler1041 tylorLotus +typage typedef typto tyrant +tz13 +tztok-worm tzuyah tzuyufan14 u dead now09 +u got a dart +u got beaned +u itachi +u kno de wae +u r gay 4 rs +u0h uEnv uKnoTheRules uLiveButOnce +uRattt uSnAvYsEaLs7 uTBER +u_u sunshine +uberHasu btw uberstunts ubiquitous96 ubug +uchar +udq +udr uetzcayotl +ufnn +uganstolfin ugivahrimjob +ugly 67 uglyandfat +uiaF +uiliuiliu +uilz +uimi +ukn0w ukwolf1 ukzharry ulab +uliuli reps +ult u fk jzs ultimo0se +ultracet +um Cya +uma pyoi +umer +umexx +umr +umw +un deux un1versa1 +unFolly +unaroc unawareaxe +unazegamoth uncle +unclefro uncleskrt +und und3adedd undeadgun underslept +undoc uneek2you +ungafknbunga +unholyblood unitewankers unkyjay unla unless unlucky2020 +unluki unravel +unravelslapz +unreaL294 unrequited +unsoy +untc untilnextyea untitled unwarranted +unzips uppahoods upset +upset berry upwindnofear +uqx +ur a bird +ur buttugly +ur cool +ur so mad +ur stinky +ur6 +urBunsRDone urNANS +urano O_o +urashitpker urfault urgirlisf2p +urgnah8me urondelekk +urqt urvinis1 urza +usainb0ltrag +uselessbozo +uselessmap +user187 usergoeshere +userjman1428 +usinlefthand usma6100 +utiliser +utpaatur utsw +uu Sauce +uub uubaidaus +uul uuuoouuououo +uuuuhhh +uwja +uwu merchant +uwu noises +uwu24 uxbridgekid +uyakO +uz x uzei +uzis akimbo +uzui +v Simba v +v olksu +v oltage +v tsng +v uka +v yp v-yordan0702 v0i kehveli v0mbat +v13 v3kz v453 +vAnthony +vBlankie vCamel +vDragzi vFoley vJace vJordxn @@ -30675,310 +63017,662 @@ vLeqacy vNicholas vPikis vRoso +vSnoop vSpectre vTaqq vaderex-1 +vaflyga vageet vaghairs +vagtap +val val val valeriaT3amo valithi +vallihauta96 +vampfrog vampir vampiremiyo +van est +van soi vanVoren +vanacis vanacularr +varla phase vasia +vasxx +vaux One +vavmaster +vb cannsss +vb1 vbehn44 vbhos +vc +vcl +vcnyew +vcw +veEXP veergolio +veetuli10 vega591 +vegiebobs vegiitto +vekter1 veldow +velek +ven g +venazuelan vene venefae veneruuti venezuelan76 +vengedclaws vengedurmom +vennie123 +venom nate vent venturo venzano vepie +veri2222 verlord vernonb2688 versacejean5 versatility4 +vertigo love vertztheone +verychillguy +verzikius +vesikulho22 vesq vestapol +vftvmv vgtrs +vibe check vibing victoriauwu video +video peli videogamer +viento suave +vierges +viet dragon +vieze sjomp vigilant +vihervasuri +viikzt +viilipytty viki +viktor main viktoras300 +villavolta80 villeh vinigha +vinke00 vippaa virtualsucks +visdayox viserbro +vislegis vispikauha vissiman visualduck visuna vitunhomo +vitunkoyha +vitunneekers +vitur scythe vitutor +vituvahe35 vivaa vizzN +vkt vlaamsbelang +vlees petje vllekoo vlyn +vmooo829 vmxn +voddeman vodka vodkapro vodke +voi vattu void-e-d void5 +volconhammer voldersnort volga34 vomax vork4sh vorosity +vosol +vougz +voui voxi6 +voyage_zjo +voyej vpxl +vraakmanus +vriskafan888 +vro +vubervos vulnaamin vulxe vunts vuokko22 vurn +vursa vutr vuur +vuzvuz +vvBearded vval vvtt +vw +vzi +vzkg +w Danko +w e b r l +w en +w ert +w vy +w00_88 +w00d pecker +w00tgh0st +w00x titan +w00xy +w0Ive +w0ked +w0lcomcz +w33dplanter +w3n +w4kenbak3 +w5s +w6rst wYungen waaayneee +waaluigii +wack pack +wacup +waga iron wagen wagween waitwhyudead +wakecub +wakingupsad wakuser walk +walker80 +walli +walloftime39 wallyally13 +walmart nuts +walmart used walnutmonkey +waltjrs legs +wanShy +wana corp +wanna quit wanolo wapwap warcauser33 +warcraftgame +wardongs warestoteles +warface125 warm +warm cuddles +warm is vuur +warmclouds warrior warteryyy +waseem76786 +waste of alt watch +watch hp ty +waterbender +waterdrink +wathx +wavej4 wawuweewa waxRS +waxhitwonder +wayabove +wayne s new +wcdak +wdx +we died fast +weThoom +weak dummy weaknd +wealldiesoon wealthletics weaponman54 +wear croc +weary pigeon wechilling wednesdvy weeb +weeb doggo weebew +weedkillsppl +weegthe32nd +weekendfun weenscape weh8ironmen +wehde weight4 weir19 +weirdo +wekkes +wenwick weoh weppend weregild werkd +wermz8 +werndoggaa wertyer2 wesley 256 +wesley biets +wesrrules92 westsider011 +wet da bed +wet oven weve weweweweoox wewkek +wf_solo123 +wfh atm +wfsdfvwwfsdq +wfsn wh1tey95 whale +whale come +whathitu whatiswork whats +whats skills +whatsoup when +when I chant where +where ask +where moon +where noon +where yat +wheresyaboy whip2b whipbanned whiskey bow +whisoserious whispery white +whitedog8 +whitless +whizprjazpxr +whk +who is react whoawhoami +whodo +whodoyouknow whololo30 whoopdidy whoppinknob whoscherry +whotf whtmicrowave +whuchaka v +why afk +why ego whyaintyoume whyamisofat whynotp2p +whyuboolyme whyzerkbro +wi f +wibeton widefang +wiegehtsmir wienerbread wife4sale wifes wifibananas +wiidziss wikedfix +wil je ket wildarko +wildberryRS wildcheery77 wildystuff6 will +will vv +will win 2 will_mello willc893 willeehawk willie432 willis28 +willmissit willmott willsand2405 willsuck4GMK win we must +winnur +winterburnI winterdaze +wiseguy2187 +wiseoldPapi wiseoldnam wispykarma +wistfulgyre witchbladezz witeboi +witenry with +witnesspower +wiw wizard129 +wizardyoda7 wizkid499 wjsn wkurtin wlkerTXrangr wndow +wndy +wngo woah wocket +wodg woesh0 wohc +wokkejzzbak +wolfbless wolfy +wolrus wombo_zombo womp wonder_wenis wonnie wonniwonkaka woodchopp +woofmaster +wooohooo wooooom woopingcrab +wooski43 +wootex woox woox10k +wormple woshishabi +wowda woxzard +wrdd wrdflexoke wrong ranger wrsrule +wruhtra wsodonnell76 +wsvolt wtbzenyte +wtffixthis wtfix wubzh8black +wucebrilllis +wuckedenergy +wucy +wudi +wudup9696 +wuil10 wulfwulfson wussupfool wutzgood wutzit wwTakun wweadge2 +www +wwwMusic-Map wyat wyattearp99 wyked wytch wyverns4days +wzav423 wzrdddddyo +wzrds +wzs +x 0lev x +x ABBlE +x Argonath x +x Chainz x +x Chelli +x D E E x +x Dante +x Fabinho +x FiFi +x Flux x GS Cookies +x Haste +x Kane x +x Kierac x +x L i o n +x Lady +x Lafferty x +x LostBoy +x Mayhem +x Ndo +x Nex +x Not blue x +x Nym +x Pho +x Red Rum +x Ryu +x Ryuu +x Sorvete +x Verzik x x Zela +x Zink +x a t +x e l a b +x gladiat0r +x husla x iNtrigue +x iyad x +x lollage x +x mk ultra +x preska x +x r +x warri0r121 +x zi +x zn +x073x +x0Mag x0Tub x12ob1n +x1deag +x1flyx +x235 +x2u mania +x3 nuzzle +x7 Curvelo +x86 +x8737 x8mz3hg7zm5f +xAFK_BTWx +xAbysss xAddictive +xAeroWolf +xAndrew +xBL00DSTREAM xBaNeSoldier +xBarlah xBayLiss +xBeefStonks xBeerbear xBehavior xBellax xBenny xBlackDahlia +xBongzilla +xBootySlayer xBottleCap +xBotty +xBowlofPhox xBrendyy +xBrimz xBrown xBusse +xCUFFSx xCallT0Armsx +xCarter +xCastiiel xCheeseheadx +xChemistry +xCherish +xChew xChiro +xChyeaa xClf +xClifffff xCloudie xCodeh xComposure +xD1E xDCx152 +xDOMIN1C +xDRAYx xDab of Iron +xDaf xDagon +xDapzz xDat xDevastor +xDevil +xDied xDieter xDijon +xDilexro +xDingy +xDora +xDoremonx xDrawingDead xDuckyV xET99 +xElliott xElsa +xEnforcerx +xEtiquette xExclusive xFMSx xFailBoatx +xFirespiritx +xFlea +xFloaty +xFranku xFraz +xFremmy xFruity xGallarzax xGigz xGoat +xGongo xGrant xGusBus xH1ckz xH4rry xHades xHamzha +xHannna xHartliss xHarty +xHayez +xHearTBow +xHerp xHmongHerox +xHugsi xHussla xI3reeze +xIron Senpai +xJeb xJiren xJlN +xJolt xJord xJordd xJulia xJuve +xKAJJEx +xKadi +xKdpunx xKing xKodai xKrab +xKril +xL2MUZZx +xLayLay +xLelooToo +xLester +xLrc xLuXx xLumby xLunatiQ xLynn xMBx xMEKANIKx +xMMGx xMardy xMarkos +xMassx xMatah +xMatty +xMedicate xMentalXx +xMetharos +xMewzic +xMochiix xMonkey +xMp5 xMyrupz +xN I K Ex +xNatureladx xNeilzus xNerevar +xNgocdol +xNickaap xNova +xO Poe xOBG +xOG420 xOnetickFap xPager +xPedu xPhil +xPortgas +xPussSmasher xQSS xQuantumxx +xRICK OWENSx +xRadagonx xRakine xRaptor +xReaperx666x xReckless +xRedGlow +xRefactor +xRektByAMain xRemyLacroix xRipple +xRivv xRobdebankx xRobertox22 +xRobscapes xRxmeo xSPAGHETTIx xSamR xScooter +xScribbz +xScrimp xSecret xSeized xServing @@ -30992,184 +63686,419 @@ xSleepgoodx xSlysoft xSnaytronSx xSnvw +xSoKi +xSteezy xSweetHopex xSword +xSxAxMx xSynn +xT o m +xT0A +xTERRIBLEx xTKOx xTWM xTerpenes +xThirlmere +xTopher +xTorsti xTransfer xTrigger xTwister xVektor xVenomx9 xVoidRange +xW R A T Hx +xWANNTEDx xWar +xWarface +xWillowTreex xWillx93 xWoke xWoodChopx +xX Bez Xx xXBlitzO xXCaBiDeXx +xXDurryXx +xXGIMP420Xx xXJoshUKXxHD +xXNaliXx xXightx +xXshadowz7Xx +xYogibear xZAKATAKx xZCH xZITOx +xZayin +xZeeBaby xZuk x_Goddess_xz +x_Huzy_x +x_Theron +x_x Fish +x_xMGKx_x +xaa2 +xaarpus +xal din +xangoose xansinmybody xaoeu xapd xaro xaxon xbox +xboxkid xc00lxDawgx +xceasea xcoda +xcrolles xcvbg +xd domi +xd jumper +xdamanx +xeem xegaF +xemulate +xenaines xeney +xenomuslol xenvzi xeravier xerkin +xexezinh0 +xfishngrillx +xfxe xgamerxx +xhamstr xhard82x xhennamariax xhoq +xi execut3 x +xi li er +xiBubbax +xiaohongshu +xiaolingxiao +xienn +ximix +xinnox xir0nm4skx +xirampagezz xironluckx +xiwitl +xjawz1e +xl Aaron lx +xl cook +xlDerekxl +xlReversal xlibrio xlr704 +xlxl xlxl +xmikeyx +xmxxmx56 xoKt xoRUNExo +xolindseyxo +xoreZ xoro xoxoverdose xozoca +xp per hour +xp waster 47 +xpabax +xpcumsez xpeyotex +xplo it +xpoltergiest xpwast3d +xrated xslayerbobx xson xspacedoll xstic xtcoming999 +xthn +xtothedee xttx xtyrantix +xvn +xvrph +xvza +xwl xwuwesxdrf +xx darkminer xxDerp xxMatter +xxREVENANTxx xxSabin09xx xxSe7en +xxTanner +xxcombatgodx +xxero +xxok xxpurskillxx xxx2sp3cuxxx +xyujah xyzn +xzanle +xzb +xzizzil +xzn 2 +xzwu +y om +y w +y0y0keepitup +y37ir y8s1 +yTried +ya pig +ya winning yaJaeT yaboyalex +yack daniels yacobson99 +yae yahn yai5 yamawaro yamb0 +yamsauze yankmynads yannickal4 +yanq10 +yaowiee +yapgragim +yasuo god69 yayasquirrel ydoc +ye idc +ye ki M +ye p to +yea im jebus yeahboi9992 +yeahsmitty +yeahyoink yearstowaste +yeastyboys yechu +yedgy +yee yee fkrs yeet +yellow car01 yeniL yerrakunt yesigame yesy0u yinghao870 +yinksnerf yinonormal yipcl yippie1317 yispaulcute +ykO Ops +ykeL +yleisradio ylliB +ym y ymca4life +yna +yo eight +yo itz ep +yobacha yodA yoda +yoda monkey yohaha123 yolomuffin +yonex +yonghoon +yooyeet +yorkietootz +yorue +you died123 +you r a qt youb1n +youneedcope +young meows +young vibby +youngbriks +youngmachine youngtrop21 youngwings +youpougou your +your thrall youralterego +youssef +yowasupppbra +yoyoma361 +yp +ypoodle +ypool4 ypools +yragbackward +yrhs yribbles +ytsud mi +ytuiop +yugiiii +yuh huh +yum +yummybolete yung +yung chubs +yung cody yung inf +yungando +yungcozzy +yuor yurciq +yuy165 +yves klein +yvonko ywwoT yxow +yyknaH J +yyttam yyzanadu94 +yzyzyzy +z 5 x +z Animal z +z Rhodes +z Shane +z a p s +z iQ +z man827 z0nk +z0rrda z0up +z1ftz +z4np +z5p +z7co +zBando zBenn zBonesz zCocoa zDaremeth zDeku +zFalcone68 +zGameDance +zGanj +zGibao +zGz zJenga zKamp +zKno zKuru zLost +zMonchi +zNico +zNolan zRarePiece +zRavenx zSlay +zSpaceRaptor +zSwanny zTitan zWxLF +za2 za33erklan zaaza zacharial +zachhy zachte zack +zack_0333 +zacyy zaddy +zak vol zalm zakaru9999 +zakk0 +zakrey +zakrobgames zalem +zancan2 +zapper920 zarehp zarfeq +zartrez zasmaru +zatch_maxed +zazalover69 +zazazhizhma zazyga +zbra zclx zcollins +zdi zdin +zdya ze4l zeKrD zeachh zeall +zeano +zebakkes +zeccStake +zedabranca zeddicus676 zedisabled zedzke +zeeebak zeeno zegg +zehstee +zeikhannes zeker zeldris +zelo1 zendendead zenmort zensix +zenuk zay zenyte4money +zeppelin0ooh zeqha zer0 zer0sirisFHK +zerker seven zerkhelm zero zero gd +zero u_u +zeroblade81 zeroixx zerotwonine zeroz136 zerzerz +zeus energy zewos +zewzh +zhengu +zhipowerz zi0n1 +zibri7 +ziewe zifyr +ziggy man 77 +ziily zilyana zina +zina n chill zinax +ziniD +zinzares +zionari +zippp zirreael +ziurbtw +ziuys ziyi_wangler +zjh +zjind +zlayaa zlink10 zlliM +zlowden zmakisan znap5 zoan @@ -31177,35 +64106,55 @@ zoboz zohcysp zokunashi zole +zomff zomgrick zonares zookwaa zoomixd zop1 zorkie +zoro u zouse +zparky +zppr +zq0 zreL +zrl zruG zrzwns ztaM ztkfps +zu b zubor1 zuenzima +zujal +zuk a cuck +zuk xd +zuk2hard4me +zukushichi +zulogz zulrah zuluTriPig zummorak zurcc zurlond zuuryy +zw zwah zwint zwolle zwqpDEOXl23 +zxpf zyeetz +zygarde92 zygis323 +zykez zymaa zymz zysuna +zzad zzai +zzben zzero zzigma +zzzJonno diff --git a/Server/data/cache/main_file_cache.dat2 b/Server/data/cache/main_file_cache.dat2 index 376fd9153..245fa6081 100644 --- a/Server/data/cache/main_file_cache.dat2 +++ b/Server/data/cache/main_file_cache.dat2 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6b92de1ed8601bc3961de4466e961cffe5777887cb87c7ffed1d466a3d08491 -size 91621090 +oid sha256:b5431211b019b9403b4cfca933f4c9635c1d5278d3730995dced0d8672b1cc91 +size 91702293 diff --git a/Server/data/cache/main_file_cache.idx255 b/Server/data/cache/main_file_cache.idx255 index a437d6da5..6e504259a 100644 --- a/Server/data/cache/main_file_cache.idx255 +++ b/Server/data/cache/main_file_cache.idx255 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86269328a9c606c683569c2d9ea200a391e08c04c1591071aaed9a36978b744b +oid sha256:83a2292c515596af0423764c48e41dfe1aac482920dca0b89ecb343db6dd4c30 size 174 diff --git a/Server/data/cache/main_file_cache.idx5 b/Server/data/cache/main_file_cache.idx5 index dad8dfec7..f19fd00c7 100644 --- a/Server/data/cache/main_file_cache.idx5 +++ b/Server/data/cache/main_file_cache.idx5 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ef6807f6653e09be9b6e2299055f1132c34dc6108e8b92fbae5add2233c2d64 -size 22092 +oid sha256:32bda84b31731cd60f7bc4e90caf7d55671e966fa958d60f2ec91da16340743d +size 22188 diff --git a/Server/data/configs/ammo_configs.json b/Server/data/configs/ammo_configs.json index 4cc7dbc0a..47da425c3 100644 --- a/Server/data/configs/ammo_configs.json +++ b/Server/data/configs/ammo_configs.json @@ -125,7 +125,7 @@ "start_graphic": "232,96", "darkbow_graphic": "", "projectile": "226,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "813", @@ -133,7 +133,7 @@ "start_graphic": "233,96", "darkbow_graphic": "", "projectile": "227,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "814", @@ -141,7 +141,7 @@ "start_graphic": "234,96", "darkbow_graphic": "", "projectile": "228,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "815", @@ -149,7 +149,7 @@ "start_graphic": "235,96", "darkbow_graphic": "", "projectile": "229,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "816", @@ -157,7 +157,7 @@ "start_graphic": "236,96", "darkbow_graphic": "", "projectile": "230,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "817", @@ -165,7 +165,7 @@ "start_graphic": "237,96", "darkbow_graphic": "", "projectile": "231,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "825", @@ -221,7 +221,7 @@ "start_graphic": "206,96", "darkbow_graphic": "", "projectile": "200,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "832", @@ -229,7 +229,7 @@ "start_graphic": "207,96", "darkbow_graphic": "", "projectile": "201,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "833", @@ -237,7 +237,7 @@ "start_graphic": "208,96", "darkbow_graphic": "", "projectile": "202,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "834", @@ -245,7 +245,7 @@ "start_graphic": "209,96", "darkbow_graphic": "", "projectile": "203,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "835", @@ -253,7 +253,7 @@ "start_graphic": "210,96", "darkbow_graphic": "", "projectile": "204,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "836", @@ -261,7 +261,7 @@ "start_graphic": "211,96", "darkbow_graphic": "", "projectile": "205,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "863", @@ -325,7 +325,7 @@ "start_graphic": "219,96", "darkbow_graphic": "", "projectile": "212,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "871", @@ -333,7 +333,7 @@ "start_graphic": "220,96", "darkbow_graphic": "", "projectile": "213,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "872", @@ -341,7 +341,7 @@ "start_graphic": "221,96", "darkbow_graphic": "", "projectile": "214,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "873", @@ -349,7 +349,7 @@ "start_graphic": "223,96", "darkbow_graphic": "", "projectile": "216,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "874", @@ -357,7 +357,7 @@ "start_graphic": "222,96", "darkbow_graphic": "", "projectile": "215,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "875", @@ -365,7 +365,7 @@ "start_graphic": "224,96", "darkbow_graphic": "", "projectile": "217,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "876", @@ -373,7 +373,7 @@ "start_graphic": "225,96", "darkbow_graphic": "", "projectile": "218,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "877", @@ -389,7 +389,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "879", @@ -421,7 +421,7 @@ "start_graphic": "19,96", "darkbow_graphic": "1104,96", "projectile": "10,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "884", @@ -437,7 +437,7 @@ "start_graphic": "18,96", "darkbow_graphic": "1105,96", "projectile": "9,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "886", @@ -453,7 +453,7 @@ "start_graphic": "20,96", "darkbow_graphic": "1106,96", "projectile": "11,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "888", @@ -469,7 +469,7 @@ "start_graphic": "21,96", "darkbow_graphic": "1107,96", "projectile": "12,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "890", @@ -485,7 +485,7 @@ "start_graphic": "22,96", "darkbow_graphic": "1108,96", "projectile": "13,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "892", @@ -501,7 +501,7 @@ "start_graphic": "24,96", "darkbow_graphic": "1109,96", "projectile": "15,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "2532", @@ -565,7 +565,7 @@ "start_graphic": "273,96", "darkbow_graphic": "", "projectile": "227,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "4160", @@ -725,7 +725,7 @@ "start_graphic": "19,96", "darkbow_graphic": "1104,96", "projectile": "10,40,36,41,46,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5617", @@ -733,7 +733,7 @@ "start_graphic": "18,96", "darkbow_graphic": "1105,96", "projectile": "9,40,36,41,46,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5618", @@ -741,7 +741,7 @@ "start_graphic": "20,96", "darkbow_graphic": "1106,96", "projectile": "11,40,36,41,46,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5619", @@ -749,7 +749,7 @@ "start_graphic": "21,96", "darkbow_graphic": "1107,96", "projectile": "12,40,36,41,46,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5620", @@ -757,7 +757,7 @@ "start_graphic": "22,96", "darkbow_graphic": "1108,96", "projectile": "13,40,36,41,46,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5621", @@ -773,7 +773,7 @@ "start_graphic": "19,96", "darkbow_graphic": "1104,96", "projectile": "10,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5623", @@ -781,7 +781,7 @@ "start_graphic": "18,96", "darkbow_graphic": "1105,96", "projectile": "9,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5624", @@ -789,7 +789,7 @@ "start_graphic": "20,96", "darkbow_graphic": "1106,96", "projectile": "11,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5625", @@ -797,7 +797,7 @@ "start_graphic": "21,96", "darkbow_graphic": "1107,96", "projectile": "12,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5626", @@ -805,7 +805,7 @@ "start_graphic": "22,96", "darkbow_graphic": "1108,96", "projectile": "13,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5627", @@ -813,7 +813,7 @@ "start_graphic": "24,96", "darkbow_graphic": "1109,96", "projectile": "15,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5628", @@ -821,7 +821,7 @@ "start_graphic": "232,96", "darkbow_graphic": "", "projectile": "226,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5629", @@ -829,7 +829,7 @@ "start_graphic": "233,96", "darkbow_graphic": "", "projectile": "227,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5630", @@ -837,7 +837,7 @@ "start_graphic": "235,96", "darkbow_graphic": "", "projectile": "229,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5631", @@ -845,7 +845,7 @@ "start_graphic": "273,96", "darkbow_graphic": "", "projectile": "227,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5633", @@ -853,7 +853,7 @@ "start_graphic": "236,96", "darkbow_graphic": "", "projectile": "230,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5634", @@ -861,7 +861,7 @@ "start_graphic": "237,96", "darkbow_graphic": "", "projectile": "231,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5635", @@ -869,7 +869,7 @@ "start_graphic": "232,96", "darkbow_graphic": "", "projectile": "226,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5636", @@ -877,7 +877,7 @@ "start_graphic": "233,96", "darkbow_graphic": "", "projectile": "227,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5637", @@ -885,7 +885,7 @@ "start_graphic": "234,96", "darkbow_graphic": "", "projectile": "228,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5638", @@ -893,7 +893,7 @@ "start_graphic": "273,96", "darkbow_graphic": "", "projectile": "227,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5639", @@ -901,7 +901,7 @@ "start_graphic": "235,96", "darkbow_graphic": "", "projectile": "229,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5640", @@ -909,7 +909,7 @@ "start_graphic": "236,96", "darkbow_graphic": "", "projectile": "230,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5641", @@ -917,7 +917,7 @@ "start_graphic": "237,96", "darkbow_graphic": "", "projectile": "231,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5642", @@ -925,7 +925,7 @@ "start_graphic": "206,96", "darkbow_graphic": "", "projectile": "200,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5643", @@ -933,7 +933,7 @@ "start_graphic": "207,96", "darkbow_graphic": "", "projectile": "201,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5644", @@ -941,7 +941,7 @@ "start_graphic": "208,96", "darkbow_graphic": "", "projectile": "202,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5645", @@ -949,7 +949,7 @@ "start_graphic": "209,96", "darkbow_graphic": "", "projectile": "203,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5646", @@ -957,7 +957,7 @@ "start_graphic": "210,96", "darkbow_graphic": "", "projectile": "204,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5647", @@ -965,7 +965,7 @@ "start_graphic": "211,96", "darkbow_graphic": "", "projectile": "205,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5648", @@ -973,7 +973,7 @@ "start_graphic": "206,96", "darkbow_graphic": "", "projectile": "200,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5649", @@ -981,7 +981,7 @@ "start_graphic": "207,96", "darkbow_graphic": "", "projectile": "201,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5650", @@ -989,7 +989,7 @@ "start_graphic": "208,96", "darkbow_graphic": "", "projectile": "202,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5651", @@ -997,7 +997,7 @@ "start_graphic": "209,96", "darkbow_graphic": "", "projectile": "203,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5652", @@ -1005,7 +1005,7 @@ "start_graphic": "210,96", "darkbow_graphic": "", "projectile": "204,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5653", @@ -1013,7 +1013,7 @@ "start_graphic": "211,96", "darkbow_graphic": "", "projectile": "205,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5654", @@ -1021,7 +1021,7 @@ "start_graphic": "219,96", "darkbow_graphic": "", "projectile": "212,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5655", @@ -1029,7 +1029,7 @@ "start_graphic": "220,96", "darkbow_graphic": "", "projectile": "213,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5656", @@ -1037,7 +1037,7 @@ "start_graphic": "221,96", "darkbow_graphic": "", "projectile": "214,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5657", @@ -1045,7 +1045,7 @@ "start_graphic": "223,96", "darkbow_graphic": "", "projectile": "216,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5658", @@ -1053,7 +1053,7 @@ "start_graphic": "222,96", "darkbow_graphic": "", "projectile": "215,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5659", @@ -1061,7 +1061,7 @@ "start_graphic": "224,96", "darkbow_graphic": "", "projectile": "217,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5660", @@ -1069,7 +1069,7 @@ "start_graphic": "225,96", "darkbow_graphic": "", "projectile": "218,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "5661", @@ -1077,7 +1077,7 @@ "start_graphic": "219,96", "darkbow_graphic": "", "projectile": "212,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5662", @@ -1085,7 +1085,7 @@ "start_graphic": "220,96", "darkbow_graphic": "", "projectile": "213,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5663", @@ -1093,7 +1093,7 @@ "start_graphic": "221,96", "darkbow_graphic": "", "projectile": "214,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5664", @@ -1101,7 +1101,7 @@ "start_graphic": "223,96", "darkbow_graphic": "", "projectile": "216,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5665", @@ -1109,7 +1109,7 @@ "start_graphic": "222,96", "darkbow_graphic": "", "projectile": "215,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5666", @@ -1117,7 +1117,7 @@ "start_graphic": "224,96", "darkbow_graphic": "", "projectile": "217,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "5667", @@ -1125,7 +1125,7 @@ "start_graphic": "225,96", "darkbow_graphic": "", "projectile": "218,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "6061", @@ -1133,7 +1133,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "6062", @@ -1141,7 +1141,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "6522", @@ -1293,7 +1293,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "9287", @@ -1301,7 +1301,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "9288", @@ -1309,7 +1309,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "9289", @@ -1317,7 +1317,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "9290", @@ -1325,7 +1325,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "9291", @@ -1333,7 +1333,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "9293", @@ -1341,7 +1341,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "9294", @@ -1349,7 +1349,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "9295", @@ -1357,7 +1357,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "9296", @@ -1365,7 +1365,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "9297", @@ -1373,7 +1373,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "9298", @@ -1381,7 +1381,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "9300", @@ -1389,7 +1389,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "9301", @@ -1397,7 +1397,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "9302", @@ -1405,7 +1405,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "9303", @@ -1413,7 +1413,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "9304", @@ -1421,7 +1421,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "9305", @@ -1429,7 +1429,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "9335", @@ -1557,7 +1557,7 @@ "start_graphic": "1116,96", "darkbow_graphic": "1114,96", "projectile": "1120,40,36,41,46,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "11228", @@ -1565,7 +1565,7 @@ "start_graphic": "1116,96", "darkbow_graphic": "1114,96", "projectile": "1120,40,36,41,46,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "11229", @@ -1573,7 +1573,7 @@ "start_graphic": "1116,96", "darkbow_graphic": "1114,96", "projectile": "1120,40,36,41,46,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "11230", @@ -1589,7 +1589,7 @@ "start_graphic": "1123,96", "darkbow_graphic": "", "projectile": "1122,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "11233", @@ -1597,7 +1597,7 @@ "start_graphic": "1123,96", "darkbow_graphic": "", "projectile": "1122,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "11234", @@ -1605,7 +1605,7 @@ "start_graphic": "1123,96", "darkbow_graphic": "", "projectile": "1122,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "13083", @@ -1621,7 +1621,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "13085", @@ -1629,7 +1629,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "13086", @@ -1637,7 +1637,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "27,38,36,41,32,5,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "13280", @@ -1661,7 +1661,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "1837,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "13881", @@ -1669,7 +1669,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "1837,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "13882", @@ -1677,7 +1677,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "1837,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "13883", @@ -1701,7 +1701,7 @@ "start_graphic": "-1,0", "darkbow_graphic": "", "projectile": "1837,40,36,32,32,15,0", - "poison_damage": "28" + "poison_damage": "10" }, { "itemId": "13955", @@ -1709,7 +1709,7 @@ "start_graphic": "1837,96", "darkbow_graphic": "", "projectile": "1840,40,36,32,32,15,0", - "poison_damage": "38" + "poison_damage": "15" }, { "itemId": "13956", @@ -1717,7 +1717,7 @@ "start_graphic": "1837,96", "darkbow_graphic": "", "projectile": "1840,40,36,32,32,15,0", - "poison_damage": "48" + "poison_damage": "20" }, { "itemId": "13957", diff --git a/Server/data/configs/door_configs.json b/Server/data/configs/door_configs.json index 8d6a61db5..f342b1856 100644 --- a/Server/data/configs/door_configs.json +++ b/Server/data/configs/door_configs.json @@ -301,7 +301,7 @@ }, { "id": "2025", - "replaceId": "1534", + "replaceId": "2026", "fence": "false", "metal": "false" }, @@ -312,7 +312,7 @@ "metal": "false" }, { - "id": "2036", + "id": "1530", "replaceId": "1531", "fence": "false", "metal": "false" @@ -343,7 +343,7 @@ }, { "id": "2054", - "replaceId": "24375", + "replaceId": "2055", "fence": "false", "metal": "false" }, @@ -419,18 +419,6 @@ "fence": "false", "metal": "false" }, - { - "id": "2391", - "replaceId": "1561", - "fence": "false", - "metal": "true" - }, - { - "id": "2392", - "replaceId": "1561", - "fence": "false", - "metal": "true" - }, { "id": "2397", "replaceId": "24383", @@ -925,7 +913,7 @@ }, { "id": "3747", - "replaceId": "1534", + "replaceId": "3748", "fence": "false", "metal": "false" }, @@ -943,7 +931,7 @@ }, { "id": "4148", - "replaceId": "4248", + "replaceId": "4246", "fence": "false", "metal": "false" }, @@ -1439,6 +1427,12 @@ "fence": "false", "metal": "false" }, + { + "id": "11470", + "replaceId": "11471", + "fence": "false", + "metal": "false" + }, { "id": "11483", "replaceId": "11708", @@ -1759,7 +1753,7 @@ }, { "id": "14245", - "replaceId": "14248", + "replaceId": "14246", "fence": "true", "metal": "false" }, @@ -1984,16 +1978,14 @@ "replaceId": "28518", "fence": "false", "metal": "true", - "autowalk": "true", - "questRequirement": "Icthlarin's Little Helper" + "autowalk": "true" }, { "id": "28514", "replaceId": "28518", "fence": "false", "metal": "true", - "autowalk": "true", - "questRequirement": "Icthlarin's Little Helper" + "autowalk": "true" }, { "id": "21065", @@ -2165,7 +2157,7 @@ }, { "id": "24376", - "replaceId": "24377", + "replaceId": "24375", "fence": "false", "metal": "false" }, diff --git a/Server/data/configs/drop_tables.json b/Server/data/configs/drop_tables.json index 9c905f6cb..2b5926e69 100644 --- a/Server/data/configs/drop_tables.json +++ b/Server/data/configs/drop_tables.json @@ -3262,7 +3262,7 @@ } ], "charm": [], - "ids": "73,74,75,419,420,421,422,423,424,1826,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131", + "ids": "73,74,75,419,420,421,422,423,424,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131", "description": "", "main": [ { @@ -5858,205 +5858,165 @@ "charm": [ { "minAmount": "1", - "weight": "100.0", - "id": "12158", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "12159", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "12160", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "12163", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5600.0", + "weight": "1000.0", "id": "0", "maxAmount": "1" } ], + "tertiary": [ + { + "minAmount": "1", + "weight": "4986.5", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.5", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "10977", + "maxAmount": "1" + } + ], "ids": "114", "description": "", "main": [ { "minAmount": "1", - "weight": "50.0", - "id": "7844", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "10977", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "10976", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5323", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5298", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5281", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5301", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5280", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5294", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5297", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5104", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5100", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5106", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "12176", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5293", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5296", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5311", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5105", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "5292", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "5295", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "5303", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "5302", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "5321", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "5299", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "31", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "0", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "3.0", + "weight": "39.0625", "id": "6666", "maxAmount": "1" }, { "minAmount": "1", - "weight": "3.0", + "weight": "78.125", "id": "6665", "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "14430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "327", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "156.25", + "id": "372", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "360", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "331", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "156.25", + "id": "313", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "1511", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "1383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "78.125", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "78.125", + "id": "402", + "maxAmount": "8" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "555", + "maxAmount": "18" + }, + { + "minAmount": "3", + "weight": "78.125", + "id": "6664", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "401", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "6667", + "maxAmount": "1" } ] }, @@ -8061,16 +8021,9 @@ } ], "charm": [], - "ids": "128,1479,1875,4343", + "ids": "128,1479,1875", "description": "", - "main": [ - { - "minAmount": "1", - "weight": "25.0", - "id": "7862", - "maxAmount": "1" - } - ] + "main": [] }, { "default": [ @@ -8400,6 +8353,20 @@ "description": "", "main": [] }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1329", + "description": "", + "main": [] + }, { "default": [ { @@ -11426,47 +11393,11 @@ "weight": "100.0", "id": "526", "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "1506", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "6065", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "6067", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "6069", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "6068", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "6070", - "maxAmount": "1" } ], "charm": [], - "ids": "347,348,357,369,370,371,372,717,718,719,2349,2350,2351,2373,2374,2784,3216", - "description": "", + "ids": "370,357,348,369,347,371", + "description": "all combat mourners", "main": [] }, { @@ -18161,7 +18092,7 @@ "maxAmount": "1" } ], - "ids": "1183,1184,1201,2359,2360,2361,2362,7438,7439,7440,7441", + "ids": "1183,1184,1201,2359,2360,2361,2362,2373,7438,7439,7440,7441", "description": "", "main": [ { @@ -18425,7 +18356,7 @@ { "minAmount": "1", "weight": "5.0", - "id": "5733", + "id": "12070", "maxAmount": "1" }, { @@ -19767,7 +19698,14 @@ ] }, { - "default": [], + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], "charm": [], "ids": "1307", "description": "", @@ -20143,6 +20081,208 @@ } ] }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1338", + "description": "Chaos Tunnels / Lighthouse Dagannoths", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "886", + "maxAmount": "15" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "828", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "301", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "4.0", + "id": "345", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "327", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "311", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "314", + "maxAmount": "15" + }, + { + "minAmount": "50", + "weight": "2.0", + "id": "313", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "2.0", + "id": "402", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "413", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "411", + "maxAmount": "2" + }, + { + "minAmount": "56", + "weight": "29.0", + "id": "995", + "maxAmount": "56" + }, + { + "minAmount": "25", + "weight": "9.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "44", + "weight": "8.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "41", + "weight": "6.0", + "id": "995", + "maxAmount": "41" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "45", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, { "default": [ { @@ -25464,8 +25604,8 @@ "maxAmount": "1" } ], - "ids": "1665,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6212,6213", - "description": "", + "ids": "6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6212,6213", + "description": "Werewolves (and human form for Canifis)", "main": [ { "minAmount": "5", @@ -26042,12 +26182,6 @@ "id": "686", "maxAmount": "1" }, - { - "minAmount": "1", - "weight": "5.0", - "id": "4170", - "maxAmount": "1" - }, { "minAmount": "1", "weight": "25.0", @@ -26328,12 +26462,6 @@ "id": "1129", "maxAmount": "1" }, - { - "minAmount": "1", - "weight": "5.0", - "id": "4170", - "maxAmount": "1" - }, { "minAmount": "2", "weight": "50.0", @@ -28355,60 +28483,10 @@ "maxAmount": "1" } ], - "charm": [ - { - "minAmount": "1", - "weight": "85.8093", - "id": "0", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "10.9113", - "id": "12158", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "1.6775", - "id": "12159", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "1.6019", - "id": "12160", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "0.0", - "id": "12163", - "maxAmount": "1" - } - ], - "ids": "2044,2045,2046,2047,2048,2049,2051,2052,2053,2054,2055", + "charm": [], + "ids": "2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057", "description": "", - "main": [ - { - "minAmount": "1", - "weight": "1.0", - "id": "1", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "124.0", - "id": "0", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "3.0", - "id": "7848", - "maxAmount": "1" - } - ] + "main": [] }, { "default": [ @@ -29753,10 +29831,10 @@ "maxAmount": "1" }, { - "minAmount": "1", + "minAmount": "2", "weight": "100.0", "id": "12161", - "maxAmount": "1" + "maxAmount": "2" }, { "minAmount": "1", @@ -31596,7 +31674,7 @@ { "minAmount": "1", "weight": "100.0", - "id": "532", + "id": "526", "maxAmount": "1" } ], @@ -31632,26 +31710,6 @@ "maxAmount": "1" } ], - "tertiary": [ - { - "minAmount": "1", - "weight": "9973.0", - "id": "0", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "10976", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "2.0", - "id": "10977", - "maxAmount": "1" - } - ], "ids": "2783", "description": "", "main": [ @@ -36414,12 +36472,6 @@ "weight": "100.0", "id": "532", "maxAmount": "1" - }, - { - "minAmount": "3", - "weight": "100.0", - "id": "526", - "maxAmount": "3" } ], "charm": [], @@ -37667,12 +37719,6 @@ "id": "1129", "maxAmount": "1" }, - { - "minAmount": "1", - "weight": "5.0", - "id": "4170", - "maxAmount": "1" - }, { "minAmount": "2", "weight": "50.0", @@ -39709,7 +39755,20 @@ ] }, { - "default": [], + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "9080", + "maxAmount": "1" + } + ], "charm": [ { "minAmount": "1", @@ -41137,7 +41196,7 @@ { "minAmount": "1", "weight": "5.0", - "id": "1", + "id": "12070", "maxAmount": "1" }, { @@ -43345,280 +43404,6 @@ } ] }, - { - "default": [ - { - "minAmount": "1", - "weight": "100.0", - "id": "2859", - "maxAmount": "1" - } - ], - "charm": [ - { - "minAmount": "1", - "weight": "100.0", - "id": "12158", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "12159", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "12160", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "12163", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5600.0", - "id": "0", - "maxAmount": "1" - } - ], - "ids": "6028", - "description": "", - "main": [ - { - "minAmount": "5", - "weight": "50.0", - "id": "2138", - "maxAmount": "5" - }, - { - "minAmount": "5", - "weight": "50.0", - "id": "2132", - "maxAmount": "5" - }, - { - "minAmount": "5", - "weight": "50.0", - "id": "2136", - "maxAmount": "5" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "1993", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "1325", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "1353", - "maxAmount": "1" - }, - { - "minAmount": "50", - "weight": "25.0", - "id": "886", - "maxAmount": "50" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "1157", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "1329", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "1181", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "1109", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "1147", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "830", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "203", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "199", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "201", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "207", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "211", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "215", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "205", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "25.0", - "id": "209", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "213", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "2485", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "217", - "maxAmount": "1" - }, - { - "minAmount": "10", - "weight": "50.0", - "id": "995", - "maxAmount": "10" - }, - { - "minAmount": "90", - "weight": "50.0", - "id": "995", - "maxAmount": "90" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "6814", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "958", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "7868", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "50.0", - "id": "227", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "1", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "245", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "983", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "239", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "1925", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "440", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "5.0", - "id": "31", - "maxAmount": "1" - }, - { - "minAmount": "1", - "weight": "100.0", - "id": "0", - "maxAmount": "1" - } - ] - }, { "default": [], "charm": [], @@ -58954,5 +58739,73 @@ "ids": "3672,3673,5168,5169,5170", "description": "Ram", "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1583", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6108", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [], + "ids": "795", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1580", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "8127", + "description": "Dark energy core", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "6287", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4343", + "description": "", + "main": [] } ] \ No newline at end of file diff --git a/Server/data/configs/ground_spawns.json b/Server/data/configs/ground_spawns.json index 506e0ddec..1893b6df3 100644 --- a/Server/data/configs/ground_spawns.json +++ b/Server/data/configs/ground_spawns.json @@ -141,11 +141,11 @@ }, { "item_id": "401", - "loc_data": "{1,2959,2959,0,160}-{1,2943,2950,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-" + "loc_data": "{1,2959,2959,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2943,2950,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-" }, { "item_id": "444", - "loc_data": "{1,3231,3739,0,250}-{1,3236,3741,0,250}-{1,3195,9821,0,150}-" + "loc_data": "{1,3231,3739,0,250}-{1,3236,3741,0,250}-{1,3195,9821,0,150}-{1,2732,3224,0,250}-" }, { "item_id": "480", @@ -207,6 +207,10 @@ "item_id": "590", "loc_data": "{1,2368,3135,0,140}-{1,2431,3072,0,140}-{1,3112,3369,2,140}-{1,3209,3734,0,100}-" }, + { + "item_id": "600", + "loc_data": "{1,2438,3187,0,200}-" + }, { "item_id": "677", "loc_data": "{1,3369,3378,0,150}-" @@ -233,7 +237,7 @@ }, { "item_id": "946", - "loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-" + "loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,2700,3407,0,100}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,2653,9767,0,30}-{1,3218,9887,0,33}-" }, { "item_id": "952", @@ -241,7 +245,7 @@ }, { "item_id": "954", - "loc_data": "{1,2094,3152,0,150}-" + "loc_data": "{1,2094,3152,0,150}-{1,2785,3279,0,150}-{1,2786,3287,0,150}-{1,2786,3286,0,150}-" }, { "item_id": "960", @@ -339,6 +343,14 @@ "item_id": "1422", "loc_data": "{1,3320,3137,0,150}-" }, + { + "item_id": "1467", + "loc_data": "{1,2784,3289,0,0}-" + }, + { + "item_id": "1469", + "loc_data": "{1,2766,3277,0,100}-{1,2766,3289,0,100}-" + }, { "item_id": "1510", "loc_data": "{1,2576,3334,0,100}-" @@ -357,7 +369,7 @@ }, { "item_id": "1573", - "loc_data": "{1,2559,2975,0,10}-{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-" + "loc_data": "{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2559,2975,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-" }, { "item_id": "1590", @@ -403,10 +415,22 @@ "item_id": "1755", "loc_data": "{1,2935,3286,0,90}-" }, + { + "item_id": "1773", + "loc_data": "{1,2563,3261,0,100}-" + }, { "item_id": "1785", "loc_data": "{1,2822,3355,0,150}-" }, + { + "item_id": "1812", + "loc_data": "{1,2747,3579,0,100}-" + }, + { + "item_id": "1813", + "loc_data": "{1,2746,3578,0,100}-" + }, { "item_id": "1856", "loc_data": "{1,2638,3292,0,150}-" @@ -449,7 +473,7 @@ }, { "item_id": "1931", - "loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-" + "loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-{1,2918,10191,1,90}-" }, { "item_id": "1935", @@ -457,11 +481,11 @@ }, { "item_id": "1939", - "loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-" + "loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3428,3322,0,45}-{1,3436,3311,0,45}-{1,3437,3298,0,45}-{1,3428,3293,0,45}-{1,3422,3286,0,45}-{1,3451,3320,0,45}-{1,3434,3277,0,45}-{1,3446,3281,0,45}-{1,3447,3269,0,45}-{1,3450,3359,0,45}-{1,3451,3359,0,45}-{1,3452,3379,0,45}-{1,3452,3380,0,45}-{1,3438,3379,0,45}-{1,3440,3377,0,45}-{1,3414,3367,0,45}-{1,3409,3363,0,45}-{1,3452,3390,0,45}-{1,3452,3391,0,45}-{1,3466,3377,0,45}-{1,3460,3374,0,45}-{1,3459,3370,0,45}-{1,3469,3363,0,45}-{1,3476,3365,0,45}-{1,3460,3353,0,45}-{1,3462,3349,0,45}-{1,3472,3344,0,45}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-{1,3464,3432,0,45}-{1,3469,3434,0,45}-{1,3473,3435,0,45}-{1,3471,3430,0,45}-{1,3478,3440,0,45}-{1,3477,3444,0,45}-{1,3472,3447,0,45}-{1,3458,3418,0,45}-{1,3460,3414,0,45}-{1,3467,3417,0,45}-{1,3472,3419,0,45}-{1,3474,3415,0,45}-{1,3480,3419,0,45}-{1,3481,3427,0,45}-{1,3460,3406,0,45}-{1,3471,3403,0,45}-{1,3428,3437,0,45}-{1,3434,3433,0,45}-{1,3435,3425,0,45}-{1,3441,3438,0,45}-{1,3445,3435,0,45}-{1,3449,3434,0,45}-{1,3448,3430,0,45}-{1,3454,3441,0,45}-{1,3441,3415,0,45}-{1,3442,3414,0,45}-{1,3436,3403,0,45}-{1,3432,3402,0,45}-{1,3450,3416,0,45}-{1,3445,3405,0,45}-{1,3453,3402,0,45}-" }, { "item_id": "1944", - "loc_data": "{1,3191,3276,0,35}-{1,3229,3299,0,35}-{1,3226,3301,0,35}-{1,3015,3295,0,30}-{1,3016,3295,0,30}-{1,2853,3370,0,35}-{1,2852,3369,0,35}-{1,2851,3372,0,35}-" + "loc_data": "{1,3191,3276,0,35}-{1,3229,3299,0,35}-{1,3226,3301,0,35}-{1,3015,3295,0,30}-{1,3016,3295,0,30}-{1,2853,3370,0,35}-{1,2852,3369,0,35}-{1,2851,3372,0,35}-{1,2453,4476,0,1}-" }, { "item_id": "1955", @@ -589,7 +613,7 @@ }, { "item_id": "3138", - "loc_data": "{1,3463,9478,2,45}-{1,3461,9480,2,45}-{1,3461,9482,2,45}-{1,3461,9484,2,45}-" + "loc_data": "{1,3461,9480,2,30}-{1,3460,9484,2,30}-{1,3465,9477,2,30}-{1,3467,9493,0,30}-{1,3486,9517,0,30}-{1,3474,9509,0,30}-{1,3470,9502,0,30}-{1,3480,9483,0,30}-" }, { "item_id": "3711", @@ -619,6 +643,10 @@ "item_id": "4707", "loc_data": "{1,3571,3312,0,40}-" }, + { + "item_id": "4838", + "loc_data": "{1,2593,3103,1,40}-" + }, { "item_id": "5008", "loc_data": "{1,3230,9609,0,44}-" @@ -627,6 +655,10 @@ "item_id": "5523", "loc_data": "{1,2935,3282,1,90}-" }, + { + "item_id": "5586", + "loc_data": "{1,2473,4941,0,90}-" + }, { "item_id": "6291", "loc_data": "{1,2681,3111,0,30}-{1,2673,3112,0,30}-{1,2674,3094,0,30}-{1,2671,3089,0,30}-" @@ -647,6 +679,10 @@ "item_id": "11065", "loc_data": "{1,2928,3289,0,90}-" }, + { + "item_id": "11656", + "loc_data": "{1,2438,3185,0,200}-" + }, { "item_id": "12494", "loc_data": "{1,2762,2973,0,60}-" diff --git a/Server/data/configs/interface_configs.json b/Server/data/configs/interface_configs.json index 50a5a64ed..4377daff0 100644 --- a/Server/data/configs/interface_configs.json +++ b/Server/data/configs/interface_configs.json @@ -95,6 +95,30 @@ "walkable": "false", "tabIndex": "-1" }, + { + "id": "68", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "69", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "70", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "71", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, { "id": "74", "interfaceType": "4", @@ -365,6 +389,30 @@ "walkable": "false", "tabIndex": "-1" }, + { + "id": "245", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "246", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "247", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "248", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, { "id": "256", "interfaceType": "8", @@ -491,6 +539,12 @@ "walkable": "true", "tabIndex": "-1" }, + { + "id": "375", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, { "id": "377", "interfaceType": "8", diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json index 14fe33cfe..b928857e7 100644 --- a/Server/data/configs/item_configs.json +++ b/Server/data/configs/item_configs.json @@ -1,131034 +1,125300 @@ [ { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "The body of a Dwarf savaged by Goblins.", - "durability": null, + "id": "0", "name": "Dwarf remains", - "tradeable": "false", - "destroy": "true", + "examine": "The body of a Dwarf savaged by Goblins.", "archery_ticket_price": "0", - "two_handed": "true", - "id": "0" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "two_handed": "true" }, { - "destroy_message": "I got this from Captain Lawgof.", - "shop_price": "1", - "examine": "Good for repairing a broken cannon.", - "durability": null, + "id": "1", "name": "Toolkit", - "tradeable": "false", + "examine": "Good for repairing a broken cannon.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1" - }, - { - "shop_price": "5", - "ge_buy_limit": "10000", - "examine": "Ammo for the Dwarf Cannon.", - "grand_exchange_price": "381", + "destroy_message": "I got this from Captain Lawgof.", "durability": null, - "name": "Cannonball", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2" - }, - { "shop_price": "1", - "examine": "Construction notes for Dwarf cannon ammo.", - "durability": null, - "name": "Nulodion's notes", - "weight": "0.02", - "archery_ticket_price": "0", - "id": "3" + "tradeable": "false", + "weight": "0.4" }, { + "id": "2", + "name": "Cannonball", + "examine": "Ammo for the Dwarf Cannon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "3", + "name": "Nulodion's notes", + "examine": "Construction notes for Dwarf cannon ammo.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "weight": "0.02" + }, + { + "id": "4", + "name": "Ammo mould", + "examine": "Used to make cannon ammunition.", + "archery_ticket_price": "0", "requirements": "{13,35}", "shop_price": "5", - "examine": "Used to make cannon ammunition.", - "name": "Ammo mould", - "weight": "4.5", - "archery_ticket_price": "0", - "id": "4" + "weight": "4.5" }, { - "shop_price": "20", - "examine": "An old note book.", - "durability": null, + "id": "5", "name": "Instruction manual", - "weight": "0.51", + "examine": "An old note book.", "archery_ticket_price": "0", - "id": "5" + "durability": null, + "shop_price": "20", + "weight": "0.51" }, { - "shop_price": "187500", - "ge_buy_limit": "10", + "id": "6", + "name": "Cannon base", "examine": "The cannon is built on this.", - "grand_exchange_price": "189000", - "durability": null, - "name": "Cannon base", - "tradeable": "true", - "weight": "7", "archery_ticket_price": "0", - "id": "6" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true", + "weight": "7" }, { - "shop_price": "187500", - "ge_buy_limit": "10", - "grand_exchange_price": "189000", - "durability": null, + "id": "7", "name": "Cannon base", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true" }, { - "shop_price": "187500", - "ge_buy_limit": "10", + "id": "8", + "name": "Cannon stand", "examine": "The mounting for the multicannon.", - "grand_exchange_price": "185000", - "durability": null, - "name": "Cannon stand", - "tradeable": "true", - "weight": "7", "archery_ticket_price": "0", - "id": "8" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true", + "weight": "7" }, { - "shop_price": "187500", - "ge_buy_limit": "10", - "grand_exchange_price": "185000", - "durability": null, + "id": "9", "name": "Cannon stand", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true" }, { - "shop_price": "187500", - "ge_buy_limit": "10", + "id": "10", + "name": "Cannon barrels", "examine": "The barrels for the multicannon.", - "grand_exchange_price": "187000", - "durability": null, - "name": "Cannon barrels", - "tradeable": "true", - "weight": "7", "archery_ticket_price": "0", - "id": "10" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true", + "weight": "7" }, { - "shop_price": "187500", - "ge_buy_limit": "10", - "grand_exchange_price": "187000", - "durability": null, + "id": "11", "name": "Cannon barrels", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true" }, { - "shop_price": "187500", - "ge_buy_limit": "10", + "id": "12", + "name": "Cannon furnace", "examine": "This powers the multicannon.", - "grand_exchange_price": "175200", - "durability": null, - "name": "Cannon furnace", - "tradeable": "true", - "weight": "7", "archery_ticket_price": "0", - "id": "12" - }, - { - "shop_price": "187500", + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "175200", - "durability": null, + "shop_price": "187500", + "tradeable": "true", + "weight": "7" + }, + { + "id": "13", "name": "Cannon furnace", - "tradeable": "true", "archery_ticket_price": "0", - "id": "13" + "durability": null, + "ge_buy_limit": "10", + "shop_price": "187500", + "tradeable": "true" }, { - "shop_price": "1", - "examine": "A metal railing replacement.", - "durability": null, + "id": "14", "name": "Railing", + "examine": "A metal railing replacement.", "archery_ticket_price": "0", - "id": "14" + "durability": null, + "shop_price": "1" }, { - "examine": "A cloth given to me by Sir Galahad.", - "durability": null, + "id": "15", "name": "Holy table napkin", + "examine": "A cloth given to me by Sir Galahad.", "archery_ticket_price": "0", - "id": "15" + "durability": null }, { - "examine": "A small tin whistle.", - "durability": null, + "id": "16", "name": "Magic whistle", - "weight": "0.2", + "examine": "A small tin whistle.", "archery_ticket_price": "0", - "id": "16" + "durability": null, + "weight": "0.2" }, { - "examine": "I wonder what happens when I ring it?", - "durability": null, + "id": "17", "name": "Grail bell", + "examine": "I wonder what happens when I ring it?", "archery_ticket_price": "0", - "id": "17" + "durability": null }, { - "examine": "It will point the way for me.", - "durability": null, + "id": "18", "name": "Magic gold feather", + "examine": "It will point the way for me.", "archery_ticket_price": "0", - "id": "18" + "durability": null }, { - "examine": "A cog from some machinery.", - "durability": null, + "id": "20", "name": "White cog", - "weight": "1", + "examine": "A cog from some machinery.", "archery_ticket_price": "0", - "id": "20" + "durability": null, + "weight": "1" }, { - "examine": "A cog from some machinery.", - "durability": null, + "id": "21", "name": "Black cog", - "weight": "1", + "examine": "A cog from some machinery.", "archery_ticket_price": "0", - "id": "21" + "durability": null, + "weight": "1" }, { - "examine": "A cog from some machinery.", - "durability": null, + "id": "22", "name": "Blue cog", - "weight": "1", - "archery_ticket_price": "0", - "id": "22" - }, - { "examine": "A cog from some machinery.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "23", "name": "Red cog", - "weight": "1", + "examine": "A cog from some machinery.", "archery_ticket_price": "0", - "id": "23" + "durability": null, + "weight": "1" }, { - "examine": "Doesn't look very tasty.", - "durability": null, + "id": "24", "name": "Rat poison", - "weight": "0.1", + "examine": "Doesn't look very tasty.", "archery_ticket_price": "0", - "id": "24" + "durability": null, + "weight": "0.1" }, { - "examine": "Wormy.", - "durability": null, + "id": "25", "name": "Red vine worm", + "examine": "Wormy.", "archery_ticket_price": "0", - "id": "25" + "durability": null }, { - "examine": "Hemenster fishing contest trophy.", - "durability": null, + "id": "26", "name": "Fishing trophy", + "examine": "Hemenster fishing contest trophy.", "archery_ticket_price": "0", - "id": "26" + "durability": null }, { - "examine": "Pass to the Hemenster fishing contest.", - "durability": null, + "id": "27", "name": "Fishing pass", + "examine": "Pass to the Hemenster fishing contest.", "archery_ticket_price": "0", - "id": "27" + "durability": null }, { - "shop_price": "121", - "examine": "Drives away all known 6 legged creatures.", - "durability": null, + "id": "28", "name": "Insect repellent", + "examine": "Drives away all known 6 legged creatures.", "archery_ticket_price": "0", - "id": "28" + "durability": null, + "shop_price": "121" }, { - "examine": "It's a bucket of wax.", - "durability": null, + "id": "30", "name": "Bucket of wax", - "weight": "2.5", + "examine": "It's a bucket of wax.", "archery_ticket_price": "0", - "id": "30" + "durability": null, + "weight": "2.5" }, { - "examine": "You shouldn't have this.", + "id": "31", "name": "RDT Slot", - "id": "31" + "examine": "You shouldn't have this." }, { - "shop_price": "3", - "examine": "A spooky candle.", - "durability": null, + "id": "32", "name": "Lit black candle", + "examine": "A spooky candle.", "archery_ticket_price": "0", - "id": "32" - }, - { - "shop_price": "24", - "examine": "A candle.", - "grand_exchange_price": "104", "durability": null, - "name": "Lit candle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "33" + "shop_price": "3" }, { - "shop_price": "24", + "id": "33", + "name": "Lit candle", "examine": "A candle.", - "grand_exchange_price": "104", - "durability": null, - "name": "Lit candle", - "tradeable": "true", "archery_ticket_price": "0", - "id": "34" + "durability": null, + "shop_price": "24", + "tradeable": "true" }, { - "shop_price": "200", + "id": "34", + "name": "Lit candle", + "examine": "A candle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "24", + "tradeable": "true" + }, + { + "id": "35", + "name": "Excalibur", "examine": "This used to belong to King Arthur.", - "has_special": "true", - "durability": null, - "weight": "2.2", - "attack_speed": "5", - "weapon_interface": "6", - "render_anim": "2554", - "defence_anim": "397", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "390,390,381,390", "attack_audios": "2500,2500,2517,2500", - "name": "Excalibur", - "archery_ticket_price": "0", - "id": "35", - "bonuses": "20,29,-2,0,0,0,3,2,1,0,0,25,0,0,0" + "attack_speed": "5", + "bonuses": "20,29,-2,0,0,0,3,2,1,0,0,25,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "2554", + "shop_price": "200", + "weapon_interface": "6", + "weight": "2.2" }, { - "shop_price": "24", - "ge_buy_limit": "100", + "id": "36", + "name": "Candle", "examine": "A candle.", - "grand_exchange_price": "119", - "durability": null, - "name": "Candle", - "tradeable": "true", "archery_ticket_price": "0", - "id": "36" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "119", - "durability": null, + "shop_price": "24", + "tradeable": "true" + }, + { + "id": "37", "name": "Candle", - "tradeable": "true", "archery_ticket_price": "0", - "id": "37" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "3", - "examine": "A spooky candle.", - "durability": null, + "id": "38", "name": "Black candle", + "examine": "A spooky candle.", "archery_ticket_price": "0", - "id": "38" + "durability": null, + "shop_price": "3" }, { - "shop_price": "10", - "ge_buy_limit": "10000", - "examine": "I can make an arrow with these.", - "grand_exchange_price": "16", - "durability": null, + "id": "39", "name": "Bronze arrowtips", - "tradeable": "true", + "examine": "I can make an arrow with these.", "archery_ticket_price": "0", - "id": "39" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "10", + "tradeable": "true" }, { - "shop_price": "26", - "ge_buy_limit": "10000", - "examine": "I can make an arrow with these.", - "grand_exchange_price": "23", - "durability": null, + "id": "40", "name": "Iron arrowtips", - "tradeable": "true", + "examine": "I can make an arrow with these.", "archery_ticket_price": "0", - "id": "40" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "26", + "tradeable": "true" }, { - "shop_price": "36", - "ge_buy_limit": "10000", - "examine": "I can make an arrow with these.", - "grand_exchange_price": "63", - "durability": null, + "id": "41", "name": "Steel arrowtips", - "tradeable": "true", + "examine": "I can make an arrow with these.", "archery_ticket_price": "0", - "id": "41" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "36", + "tradeable": "true" }, { - "shop_price": "68", - "ge_buy_limit": "10000", - "examine": "I can make an arrow with these.", - "grand_exchange_price": "74", - "durability": null, + "id": "42", "name": "Mithril arrowtips", - "tradeable": "true", + "examine": "I can make an arrow with these.", "archery_ticket_price": "0", - "id": "42" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "68", + "tradeable": "true" }, { - "shop_price": "160", - "ge_buy_limit": "10000", - "examine": "I can make an arrow with these.", - "grand_exchange_price": "185", - "durability": null, + "id": "43", "name": "Adamant arrowtips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "43" - }, - { - "shop_price": "460", - "ge_buy_limit": "10000", "examine": "I can make an arrow with these.", - "grand_exchange_price": "839", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "shop_price": "160", + "tradeable": "true" + }, + { + "id": "44", "name": "Rune arrowtips", - "tradeable": "true", + "examine": "I can make an arrow with these.", "archery_ticket_price": "0", - "id": "44" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "460", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Opal bolt tips.", - "grand_exchange_price": "1", - "durability": null, + "id": "45", "name": "Opal bolt tips", - "tradeable": "true", + "examine": "Opal bolt tips.", "archery_ticket_price": "0", - "id": "45" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Pearl bolt tips.", - "grand_exchange_price": "5", - "durability": null, + "id": "46", "name": "Pearl bolt tips", - "tradeable": "true", + "examine": "Pearl bolt tips.", "archery_ticket_price": "0", - "id": "46" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "114", - "ge_buy_limit": "10000", - "examine": "I can make bolts with these.", - "grand_exchange_price": "44", - "durability": null, + "id": "47", "name": "Barb bolttips", - "tradeable": "false", - "destroy": "true", + "examine": "I can make bolts with these.", "archery_ticket_price": "5", - "id": "47" + "destroy": "true", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "114", + "tradeable": "false" }, { - "ge_buy_limit": "10000", + "id": "48", + "name": "Longbow (u)", "examine": "An unstrung longbow; I need a bowstring for this.", - "grand_exchange_price": "14", - "durability": null, - "name": "Longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "48" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "14", - "durability": null, + "id": "49", "name": "Longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "49" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "50", + "name": "Shortbow (u)", "examine": "I need to find a string for this.", - "grand_exchange_price": "5", - "durability": null, - "name": "Shortbow (u)", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "50" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "5", - "durability": null, - "name": "Shortbow (u)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "51" + "weight": "1" }, { - "ge_buy_limit": "20000", - "examine": "A wooden arrow shaft", - "grand_exchange_price": "21", + "id": "51", + "name": "Shortbow (u)", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "52", "name": "Arrow shaft", - "tradeable": "true", + "examine": "A wooden arrow shaft", "archery_ticket_price": "0", - "id": "52" - }, - { + "durability": null, "ge_buy_limit": "20000", - "examine": "A wooden arrow shaft with flights attached.", - "grand_exchange_price": "56", - "durability": null, + "tradeable": "true" + }, + { + "id": "53", "name": "Headless arrow", - "tradeable": "true", + "examine": "A wooden arrow shaft with flights attached.", "archery_ticket_price": "0", - "id": "53" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" }, { - "shop_price": "50", - "ge_buy_limit": "10000", + "id": "54", + "name": "Oak shortbow (u)", "examine": "An unstrung oak bow; I need a bowstring for this.", - "grand_exchange_price": "7", - "durability": null, - "name": "Oak shortbow (u)", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "54" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "50", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "7", - "durability": null, + "id": "55", "name": "Oak shortbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "55" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "56", + "name": "Oak longbow (u)", "examine": "An unstrung oak longbow; I need a bowstring for this.", - "grand_exchange_price": "20", - "durability": null, - "name": "Oak longbow (u)", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "56" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "20", - "durability": null, + "id": "57", "name": "Oak longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "57" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "64", - "ge_buy_limit": "10000", + "id": "58", + "name": "Willow longbow (u)", "examine": "An unstrung willow longbow; I need a bowstring for this.", - "grand_exchange_price": "46", - "durability": null, - "name": "Willow longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "58" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "64", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "46", - "durability": null, + "id": "59", "name": "Willow longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "59" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "16", - "ge_buy_limit": "10000", + "id": "60", + "name": "Willow shortbow (u)", "examine": "An unstrung willow shortbow; I need a bowstring for this.", - "grand_exchange_price": "20", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "shop_price": "16", + "tradeable": "true" + }, + { + "id": "61", "name": "Willow shortbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "60" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "20", - "durability": null, - "name": "Willow shortbow (u)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "61" - }, - { - "ge_buy_limit": "10000", - "examine": "An unstrung maple bow; I need a bowstring for this.", - "grand_exchange_price": "94", - "durability": null, + "id": "62", "name": "Maple longbow (u)", - "tradeable": "true", - "weight": "1.2", - "archery_ticket_price": "0", - "id": "62" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "94", - "durability": null, - "name": "Maple longbow (u)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "63" - }, - { - "ge_buy_limit": "10000", "examine": "An unstrung maple bow; I need a bowstring for this.", - "grand_exchange_price": "56", - "durability": null, - "name": "Maple shortbow (u)", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "64" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.2" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "56", - "durability": null, - "name": "Maple shortbow (u)", - "tradeable": "true", + "id": "63", + "name": "Maple longbow (u)", "archery_ticket_price": "0", - "id": "65" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { + "id": "64", + "name": "Maple shortbow (u)", + "examine": "An unstrung maple bow; I need a bowstring for this.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "65", + "name": "Maple shortbow (u)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "66", + "name": "Yew longbow (u)", "examine": "An unstrung yew longbow; I need a bowstring for this.", - "grand_exchange_price": "468", - "durability": null, - "name": "Yew longbow (u)", - "tradeable": "true", - "weight": "1.32", "archery_ticket_price": "0", - "id": "66" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.32" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "468", - "durability": null, + "id": "67", "name": "Yew longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "67" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "68", + "name": "Yew shortbow (u)", "examine": "An unstrung yew shortbow; I need a bowstring for this.", - "grand_exchange_price": "158", - "durability": null, - "name": "Yew shortbow (u)", - "tradeable": "true", - "weight": "1.32", "archery_ticket_price": "0", - "id": "68" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.32" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "158", - "durability": null, + "id": "69", "name": "Yew shortbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "69" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "931", - "ge_buy_limit": "10000", + "id": "70", + "name": "Magic longbow (u)", "examine": "An unstrung magic longbow; I need a bowstring for this.", - "grand_exchange_price": "1246", - "durability": null, - "name": "Magic longbow (u)", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "70" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "931", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1246", - "durability": null, + "id": "71", "name": "Magic longbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "71" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "890", - "ge_buy_limit": "10000", + "id": "72", + "name": "Magic shortbow (u)", "examine": "An unstrung magic shortbow; I need a bowstring for this.", - "grand_exchange_price": "745", - "durability": null, - "name": "Magic shortbow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "72" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "745", - "durability": null, - "name": "Magic shortbow (u)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "73" + "shop_price": "890", + "tradeable": "true" }, { + "id": "73", + "name": "Magic shortbow (u)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "74", + "name": "Khazard helmet", + "examine": "A helmet, as worn by the minions of General Khazard.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,4,5,3,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "I can borrow another from the armoury near the Fight Arena.", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "shop_price": "10", - "examine": "A helmet, as worn by the minions of General Khazard.", - "durability": null, - "weight": "2.7", - "destroy": "true", - "equipment_slot": "0", - "destroy_message": "I can borrow another from the armoury near the Fight Arena.", - "name": "Khazard helmet", "tradeable": "false", - "archery_ticket_price": "0", - "id": "74", - "bonuses": "0,0,0,0,0,4,5,3,0,0,0,0,0,0,0" + "weight": "2.7" }, { - "shop_price": "12", - "examine": "Armour, as worn by the minions of General Khazard.", - "durability": null, - "weight": "0.5", - "destroy": "true", - "equipment_slot": "4", - "destroy_message": "I can borrow another from the armoury near the Fight Arena.", - "remove_sleeves": "true", - "name": "Khazard armour", - "tradeable": "false", - "archery_ticket_price": "0", "id": "75", - "bonuses": "0,0,0,0,0,9,11,10,0,0,0,0,0,0,0" + "name": "Khazard armour", + "examine": "Armour, as worn by the minions of General Khazard.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,11,10,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "I can borrow another from the armoury near the Fight Arena.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "12", + "tradeable": "false", + "weight": "0.5" }, { - "destroy_message": "The lazy guard probably has a spare set...", - "examine": "These keys open the cells at the Khazard Fight Arena. (Fight Arena)", - "durability": null, + "id": "76", "name": "Khazard cell keys", - "tradeable": "false", - "destroy": "true", + "examine": "These keys open the cells at the Khazard Fight Arena. (Fight Arena)", "archery_ticket_price": "0", - "id": "76" + "destroy": "true", + "destroy_message": "The lazy guard probably has a spare set...", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Angor, the Khazard barman, has a stock of Khali brew.", - "shop_price": "5", - "examine": "A bottle of Khazard's worst brew.", - "durability": null, + "id": "77", "name": "Khali brew", - "tradeable": "false", + "examine": "A bottle of Khazard's worst brew.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "77" - }, - { - "destroy_message": "Can only be fired from yew, magic, dark or twisted bows.", - "shop_price": "2", - "examine": "Can only be fired from yew, magic, or dark bows.", + "destroy_message": "Angor, the Khazard barman, has a stock of Khali brew.", "durability": null, - "name": "Ice arrows", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "78", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { - "examine": "A lever to open something perhaps?", - "durability": null, - "name": "Lever", - "archery_ticket_price": "0", - "id": "83" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "The power in this staff causes it to vibrate gently.", - "durability": null, - "name": "Staff of armadyl", - "tradeable": "false", - "destroy": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "84", - "render_anim": "2553" - }, - { - "examine": "It catches the light! (Temple of Ikov)", - "durability": null, - "name": "Shiny key", - "archery_ticket_price": "0", - "id": "85" - }, - { - "examine": "An amulet made by Lucien.", - "durability": null, - "name": "Pendant of lucien", - "archery_ticket_price": "0", - "id": "86", - "equipment_slot": "2" - }, - { - "examine": "Yet another amulet.", - "durability": null, - "name": "Armadyl pendant", - "archery_ticket_price": "0", - "id": "87", - "equipment_slot": "2" - }, - { - "examine": "Magic boots that make you lighter than normal.", - "durability": null, - "name": "Boots of lightness", - "weight": "-4.5", - "archery_ticket_price": "0", - "id": "88", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "examine": "Magic boots that make you lighter than normal.", - "durability": null, - "name": "Boots of lightness", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "89", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "examine": "It's very soft!", - "durability": null, - "name": "Child's blanket", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "90" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this guam potion.", - "grand_exchange_price": "285", - "durability": null, - "name": "Guam potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "91" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "285", - "durability": null, - "name": "Guam potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "92" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this marrentill potion.", - "grand_exchange_price": "43", - "durability": null, - "name": "Marrentill potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "93" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "43", - "durability": null, - "name": "Marrentill potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "94" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this tarromin potion.", - "grand_exchange_price": "287", - "durability": null, - "name": "Tarromin potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "95" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "287", - "durability": null, - "name": "Tarromin potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "96" - }, - { - "shop_price": "64", - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this potion.", - "grand_exchange_price": "435", - "durability": null, - "name": "Harralander potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "97" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "435", - "durability": null, - "name": "Harralander potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "98" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this ranarr potion.", - "grand_exchange_price": "4823", - "durability": null, - "name": "Ranarr potion(unf)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "99" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4823", - "durability": null, - "name": "Ranarr potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "100" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this irit potion.", - "grand_exchange_price": "2243", - "durability": null, - "name": "Irit potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "101" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2243", - "durability": null, - "name": "Irit potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "102" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this avantoe potion.", - "grand_exchange_price": "3831", - "durability": null, - "name": "Avantoe potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "103" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3831", - "durability": null, - "name": "Avantoe potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "104" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this kwuarm potion.", - "grand_exchange_price": "1833", - "durability": null, - "name": "Kwuarm potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "105" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1833", - "durability": null, - "name": "Kwuarm potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "106" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this cadantine potion.", - "grand_exchange_price": "1844", - "durability": null, - "name": "Cadantine potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "107" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1844", - "durability": null, - "name": "Cadantine potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "108" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this dwarf weed potion.", - "grand_exchange_price": "6740", - "durability": null, - "name": "Dwarf weed potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "109" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6740", - "durability": null, - "name": "Dwarf weed potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "110" - }, - { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this torstol potion.", - "grand_exchange_price": "14500", - "durability": null, - "name": "Torstol potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "111" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "14500", - "durability": null, - "name": "Torstol potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "112" - }, - { - "shop_price": "780", - "ge_buy_limit": "100", - "examine": "4 doses of Strength potion.", - "grand_exchange_price": "1041", - "durability": null, - "name": "Strength potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "113" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1041", - "durability": null, - "name": "Strength potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "114" - }, - { - "shop_price": "780", - "ge_buy_limit": "100", - "examine": "3 doses of Strength potion.", - "grand_exchange_price": "812", - "durability": null, - "name": "Strength potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "115" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "812", - "durability": null, - "name": "Strength potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "116" - }, - { - "shop_price": "780", - "ge_buy_limit": "100", - "examine": "2 doses of Strength potion.", - "grand_exchange_price": "656", - "durability": null, - "name": "Strength potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "117" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "656", - "durability": null, - "name": "Strength potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "118" - }, - { - "shop_price": "780", - "ge_buy_limit": "100", - "examine": "1 dose of Strength potion.", - "grand_exchange_price": "355", - "durability": null, - "name": "Strength potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "119" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "355", - "durability": null, - "name": "Strength potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "120" - }, - { - "shop_price": "560", - "ge_buy_limit": "100", - "examine": "3 doses of Attack potion.", - "grand_exchange_price": "195", - "durability": null, - "name": "Attack potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "121" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "195", - "durability": null, - "name": "Attack potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "122" - }, - { - "shop_price": "560", - "ge_buy_limit": "100", - "examine": "2 doses of Attack potion.", - "grand_exchange_price": "113", - "durability": null, - "name": "Attack potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "123" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "113", - "durability": null, - "name": "Attack potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "124" - }, - { - "shop_price": "560", - "ge_buy_limit": "100", - "examine": "1 dose of Attack potion.", - "grand_exchange_price": "197", - "durability": null, - "name": "Attack potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "125" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "197", - "durability": null, - "name": "Attack potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "126" - }, - { - "shop_price": "139", - "ge_buy_limit": "100", - "examine": "3 doses of restore potion.", - "grand_exchange_price": "59", - "durability": null, - "name": "Restore potion(3)", - "tradeable": "true", - "weight": "0.03", - "archery_ticket_price": "0", - "id": "127" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "59", - "durability": null, - "name": "Restore potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "128" - }, - { - "shop_price": "139", - "ge_buy_limit": "100", - "examine": "2 doses of restore potion.", - "grand_exchange_price": "35", - "durability": null, - "name": "Restore potion(2)", - "tradeable": "true", - "weight": "0.03", - "archery_ticket_price": "0", - "id": "129" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "35", - "durability": null, - "name": "Restore potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "130" - }, - { - "shop_price": "139", - "ge_buy_limit": "100", - "examine": "1 dose of restore potion.", - "grand_exchange_price": "21", - "durability": null, - "name": "Restore potion(1)", - "tradeable": "true", - "weight": "0.03", - "archery_ticket_price": "0", - "id": "131" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "21", - "durability": null, - "name": "Restore potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "132" - }, - { - "shop_price": "114", - "ge_buy_limit": "100", - "examine": "3 doses of Defence Potion.", - "grand_exchange_price": "323", - "durability": null, - "name": "Defence potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "133" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "323", - "durability": null, - "name": "Defence potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "134" - }, - { - "shop_price": "114", - "ge_buy_limit": "100", - "examine": "2 doses of Defence Potion.", - "grand_exchange_price": "247", - "durability": null, - "name": "Defence potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "135" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "247", - "durability": null, - "name": "Defence potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "136" - }, - { - "shop_price": "114", - "ge_buy_limit": "100", - "examine": "1 dose of Defence Potion.", - "grand_exchange_price": "148", - "durability": null, - "name": "Defence potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "137" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "148", - "durability": null, - "name": "Defence potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "138" - }, - { - "ge_buy_limit": "100", - "examine": "3 doses of Prayer restore potion.", - "grand_exchange_price": "4134", - "durability": null, - "name": "Prayer potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "139" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4134", - "durability": null, - "name": "Prayer potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "140" - }, - { - "ge_buy_limit": "100", - "examine": "2 doses of Prayer restore potion.", - "grand_exchange_price": "2868", - "durability": null, - "name": "Prayer potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "141" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2868", - "durability": null, - "name": "Prayer potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "142" - }, - { - "ge_buy_limit": "100", - "examine": "1 dose of Prayer restore potion.", - "grand_exchange_price": "1353", - "durability": null, - "name": "Prayer potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "143" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1353", - "durability": null, - "name": "Prayer potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "144" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of super Attack potion.", - "grand_exchange_price": "691", - "durability": null, - "name": "Super attack(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "145" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "691", - "durability": null, - "name": "Super attack(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "146" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of super Attack potion.", - "grand_exchange_price": "451", - "durability": null, - "name": "Super attack(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "147" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "451", - "durability": null, - "name": "Super attack(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "148" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of super Attack potion.", - "grand_exchange_price": "243", - "durability": null, - "name": "Super attack(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "149" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "243", - "durability": null, - "name": "Super attack(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "150" - }, - { - "ge_buy_limit": "100", - "examine": "3 doses of Fishing potion.", - "grand_exchange_price": "40", - "durability": null, - "name": "Fishing potion(3)", - "tradeable": "true", - "weight": "0.03", - "archery_ticket_price": "0", - "id": "151" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "40", - "durability": null, - "name": "Fishing potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "152" - }, - { - "ge_buy_limit": "100", - "examine": "2 doses of Fishing potion.", - "grand_exchange_price": "56", - "durability": null, - "name": "Fishing potion(2)", - "tradeable": "true", - "weight": "0.03", - "archery_ticket_price": "0", - "id": "153" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "56", - "durability": null, - "name": "Fishing potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "154" - }, - { - "ge_buy_limit": "100", - "examine": "1 dose of Fishing potion.", - "grand_exchange_price": "87", - "durability": null, - "name": "Fishing potion(1)", - "tradeable": "true", - "weight": "0.03", - "archery_ticket_price": "0", - "id": "155" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "87", - "durability": null, - "name": "Fishing potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "156" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of super Strength potion.", - "grand_exchange_price": "1679", - "durability": null, - "name": "Super strength(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "157" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1679", - "durability": null, - "name": "Super strength(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "158" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of super Strength potion.", - "grand_exchange_price": "1164", - "durability": null, - "name": "Super strength(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "159" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1164", - "durability": null, - "name": "Super strength(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "160" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of super Strength potion.", - "grand_exchange_price": "603", - "durability": null, - "name": "Super strength(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "161" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "603", - "durability": null, - "name": "Super strength(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "162" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of super Defence potion.", - "grand_exchange_price": "113", - "durability": null, - "name": "Super defence(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "163" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "113", - "durability": null, - "name": "Super defence(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "164" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of super Defence potion.", - "grand_exchange_price": "65", - "durability": null, - "name": "Super defence(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "165" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "65", - "durability": null, - "name": "Super defence(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "166" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of super Defence potion.", - "grand_exchange_price": "41", - "durability": null, - "name": "Super defence(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "167" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "41", - "durability": null, - "name": "Super defence(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "168" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of ranging potion.", - "grand_exchange_price": "6224", - "durability": null, - "name": "Ranging potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "169" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "6224", - "durability": null, - "name": "Ranging potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "170" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of ranging potion.", - "grand_exchange_price": "4330", - "durability": null, - "name": "Ranging potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "171" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "4330", - "durability": null, - "name": "Ranging potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "172" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of ranging potion.", - "grand_exchange_price": "2068", - "durability": null, - "name": "Ranging potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "173" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2068", - "durability": null, - "name": "Ranging potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "174" - }, - { - "shop_price": "375", - "ge_buy_limit": "1000", - "examine": "3 doses of antipoison potion.", - "grand_exchange_price": "1239", - "durability": null, - "name": "Antipoison(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "175" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1239", - "durability": null, - "name": "Antipoison(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "176" - }, - { - "shop_price": "375", - "ge_buy_limit": "1000", - "examine": "2 doses of antipoison potion.", - "grand_exchange_price": "822", - "durability": null, - "name": "Antipoison(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "177" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "822", - "durability": null, - "name": "Antipoison(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "178" - }, - { - "shop_price": "375", - "ge_buy_limit": "1000", - "examine": "1 dose of antipoison potion.", - "grand_exchange_price": "460", - "durability": null, - "name": "Antipoison(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "179" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "460", - "durability": null, - "name": "Antipoison(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "180" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of super anti poison potion.", - "grand_exchange_price": "872", - "durability": null, - "name": "Super antipoison(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "181" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "872", - "durability": null, - "name": "Super antipoison(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "182" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of super anti poison potion.", - "grand_exchange_price": "509", - "durability": null, - "name": "Super antipoison(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "183" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "509", - "durability": null, - "name": "Super antipoison(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "184" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of super anti poison potion.", - "grand_exchange_price": "366", - "durability": null, - "name": "Super antipoison(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "185" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "366", - "durability": null, - "name": "Super antipoison(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "186" - }, - { - "ge_buy_limit": "1000", - "examine": "For use on daggers and projectiles.", - "grand_exchange_price": "33", - "durability": null, - "name": "Weapon poison", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "187" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "33", - "durability": null, - "name": "Weapon poison", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "188" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of Zamorak brew.", - "grand_exchange_price": "1818", - "durability": null, - "name": "Zamorak brew(3)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "189" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1818", - "durability": null, - "name": "Zamorak brew(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "190" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of Zamorak brew.", - "grand_exchange_price": "1004", - "durability": null, - "name": "Zamorak brew(2)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "191" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1004", - "durability": null, - "name": "Zamorak brew(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "192" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of Zamorak brew.", - "grand_exchange_price": "1175", - "durability": null, - "name": "Zamorak brew(1)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "193" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1175", - "durability": null, - "name": "Zamorak brew(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "194" - }, - { - "ge_buy_limit": "100", - "examine": "This is meant to be good for spots.", - "grand_exchange_price": "117", - "durability": null, - "name": "Potion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "195" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "117", - "durability": null, - "name": "Potion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "196" - }, - { - "shop_price": "39", - "ge_buy_limit": "100", - "examine": "Stankers gives out these strange cocktails for free.", - "grand_exchange_price": "124", - "durability": null, - "name": "Poison chalice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "197" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "124", - "durability": null, - "name": "Poison chalice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "198" - }, - { - "requirements": "{3,15}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "150", - "durability": null, - "name": "Grimy guam", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "199" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "155", - "durability": null, - "name": "Grimy guam", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "200" - }, - { - "requirements": "{5,15}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "150", - "durability": null, - "name": "Grimy marrentill", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "201" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "26", - "durability": null, - "name": "Grimy marrentill", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "202" - }, - { - "requirements": "{11,15}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "150", - "durability": null, - "name": "Grimy tarromin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "203" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "151", - "durability": null, - "name": "Grimy tarromin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "204" - }, - { - "requirements": "{20,15}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "300", - "durability": null, - "name": "Grimy harralander", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "205" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "275", - "durability": null, - "name": "Grimy harralander", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "206" - }, - { - "requirements": "{15,25}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "1300", - "durability": null, - "name": "Grimy ranarr", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "207" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "4909", - "durability": null, - "name": "Grimy ranarr", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "208" - }, - { - "requirements": "{15,40}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "900", - "durability": null, - "name": "Grimy irit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "209" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2034", - "durability": null, - "name": "Grimy irit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "210" - }, - { - "requirements": "{15,48}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "500", - "durability": null, - "name": "Grimy avantoe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "211" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "3789", - "durability": null, - "name": "Grimy avantoe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "212" - }, - { - "requirements": "{15,54}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "900", - "durability": null, - "name": "Grimy kwuarm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "213" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1665", - "durability": null, - "name": "Grimy kwuarm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "214" - }, - { - "requirements": "{15,65}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "900", - "durability": null, - "name": "Grimy cadantine", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "215" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1582", - "durability": null, - "name": "Grimy cadantine", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "216" - }, - { - "requirements": "{15,70}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "1300", - "durability": null, - "name": "Grimy dwarf weed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "217" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "6934", - "durability": null, - "name": "Grimy dwarf weed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "218" - }, - { - "requirements": "{15,75}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "3200", - "durability": null, - "name": "Grimy torstol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "219" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "35800", - "durability": null, - "name": "Grimy torstol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "220" - }, - { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "It seems to be looking at me.", - "grand_exchange_price": "27", - "durability": null, - "name": "Eye of newt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "221" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "27", - "durability": null, - "name": "Eye of newt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "222" - }, - { - "ge_buy_limit": "10000", - "examine": "Ewww!", - "grand_exchange_price": "888", - "durability": null, - "name": "Red spiders' eggs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "223" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "888", - "durability": null, - "name": "Red spiders' eggs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "224" - }, - { - "ge_buy_limit": "10000", - "examine": "The root of a limpwurt plant.", - "grand_exchange_price": "1984", - "durability": null, - "name": "Limpwurt root", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "225" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1984", - "durability": null, - "name": "Limpwurt root", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "226" - }, - { - "shop_price": "10", - "ge_buy_limit": "10000", - "examine": "A glass vial containing water.", - "grand_exchange_price": "35", - "durability": null, - "name": "Vial of water", - "tradeable": "true", - "weight": "0.02", - "archery_ticket_price": "0", - "id": "227" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "35", - "durability": null, - "name": "Vial of water", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "228" - }, - { "shop_price": "5", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "78", + "name": "Ice arrows", + "examine": "Can only be fired from yew, magic, or dark bows.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "destroy": "true", + "destroy_message": "Can only be fired from yew, magic, dark or twisted bows.", + "durability": null, + "equipment_slot": "13", + "shop_price": "2", + "tradeable": "false" + }, + { + "id": "83", + "name": "Lever", + "examine": "A lever to open something perhaps?", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "84", + "name": "Staff of armadyl", + "examine": "The power in this staff causes it to vibrate gently.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "render_anim": "2553", + "tradeable": "false", + "weight": "5" + }, + { + "id": "85", + "name": "Shiny key", + "examine": "It catches the light! (Temple of Ikov)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "86", + "name": "Pendant of lucien", + "examine": "An amulet made by Lucien.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2" + }, + { + "id": "87", + "name": "Armadyl pendant", + "examine": "Yet another amulet.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2" + }, + { + "id": "88", + "name": "Boots of lightness", + "examine": "Magic boots that make you lighter than normal.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "weight": "-4.5" + }, + { + "id": "89", + "name": "Boots of lightness", + "examine": "Magic boots that make you lighter than normal.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "weight": "0.3" + }, + { + "id": "90", + "name": "Child's blanket", + "examine": "It's very soft!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "91", + "name": "Guam potion(unf)", + "examine": "I need another ingredient to finish this guam potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "92", + "name": "Guam potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "93", + "name": "Marrentill potion(unf)", + "examine": "I need another ingredient to finish this marrentill potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "94", + "name": "Marrentill potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "95", + "name": "Tarromin potion(unf)", + "examine": "I need another ingredient to finish this tarromin potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "96", + "name": "Tarromin potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "97", + "name": "Harralander potion(unf)", + "examine": "I need another ingredient to finish this potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "64", + "tradeable": "true" + }, + { + "id": "98", + "name": "Harralander potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "99", + "name": "Ranarr potion(unf)", + "examine": "I need another ingredient to finish this ranarr potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "100", + "name": "Ranarr potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "101", + "name": "Irit potion(unf)", + "examine": "I need another ingredient to finish this irit potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "102", + "name": "Irit potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "103", + "name": "Avantoe potion(unf)", + "examine": "I need another ingredient to finish this avantoe potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "104", + "name": "Avantoe potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "105", + "name": "Kwuarm potion(unf)", + "examine": "I need another ingredient to finish this kwuarm potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "106", + "name": "Kwuarm potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "107", + "name": "Cadantine potion(unf)", + "examine": "I need another ingredient to finish this cadantine potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "108", + "name": "Cadantine potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "109", + "name": "Dwarf weed potion(unf)", + "examine": "I need another ingredient to finish this dwarf weed potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "110", + "name": "Dwarf weed potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "111", + "name": "Torstol potion(unf)", + "examine": "I need another ingredient to finish this torstol potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "112", + "name": "Torstol potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "113", + "name": "Strength potion(4)", + "examine": "4 doses of Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "780", + "tradeable": "true" + }, + { + "id": "114", + "name": "Strength potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "115", + "name": "Strength potion(3)", + "examine": "3 doses of Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "780", + "tradeable": "true" + }, + { + "id": "116", + "name": "Strength potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "117", + "name": "Strength potion(2)", + "examine": "2 doses of Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "780", + "tradeable": "true" + }, + { + "id": "118", + "name": "Strength potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "119", + "name": "Strength potion(1)", + "examine": "1 dose of Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "780", + "tradeable": "true" + }, + { + "id": "120", + "name": "Strength potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "121", + "name": "Attack potion(3)", + "examine": "3 doses of Attack potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "560", + "tradeable": "true" + }, + { + "id": "122", + "name": "Attack potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "123", + "name": "Attack potion(2)", + "examine": "2 doses of Attack potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "560", + "tradeable": "true" + }, + { + "id": "124", + "name": "Attack potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "125", + "name": "Attack potion(1)", + "examine": "1 dose of Attack potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "560", + "tradeable": "true" + }, + { + "id": "126", + "name": "Attack potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "127", + "name": "Restore potion(3)", + "examine": "3 doses of restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "139", + "tradeable": "true", + "weight": "0.03" + }, + { + "id": "128", + "name": "Restore potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "129", + "name": "Restore potion(2)", + "examine": "2 doses of restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "139", + "tradeable": "true", + "weight": "0.03" + }, + { + "id": "130", + "name": "Restore potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "131", + "name": "Restore potion(1)", + "examine": "1 dose of restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "139", + "tradeable": "true", + "weight": "0.03" + }, + { + "id": "132", + "name": "Restore potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "133", + "name": "Defence potion(3)", + "examine": "3 doses of Defence Potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "114", + "tradeable": "true" + }, + { + "id": "134", + "name": "Defence potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "135", + "name": "Defence potion(2)", + "examine": "2 doses of Defence Potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "114", + "tradeable": "true" + }, + { + "id": "136", + "name": "Defence potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "137", + "name": "Defence potion(1)", + "examine": "1 dose of Defence Potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "114", + "tradeable": "true" + }, + { + "id": "138", + "name": "Defence potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "139", + "name": "Prayer potion(3)", + "examine": "3 doses of Prayer restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "140", + "name": "Prayer potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "141", + "name": "Prayer potion(2)", + "examine": "2 doses of Prayer restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "142", + "name": "Prayer potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "143", + "name": "Prayer potion(1)", + "examine": "1 dose of Prayer restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "144", + "name": "Prayer potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "145", + "name": "Super attack(3)", + "examine": "3 doses of super Attack potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "146", + "name": "Super attack(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "147", + "name": "Super attack(2)", + "examine": "2 doses of super Attack potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "148", + "name": "Super attack(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "149", + "name": "Super attack(1)", + "examine": "1 dose of super Attack potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "150", + "name": "Super attack(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "151", + "name": "Fishing potion(3)", + "examine": "3 doses of Fishing potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.03" + }, + { + "id": "152", + "name": "Fishing potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "153", + "name": "Fishing potion(2)", + "examine": "2 doses of Fishing potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.03" + }, + { + "id": "154", + "name": "Fishing potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "155", + "name": "Fishing potion(1)", + "examine": "1 dose of Fishing potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.03" + }, + { + "id": "156", + "name": "Fishing potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "157", + "name": "Super strength(3)", + "examine": "3 doses of super Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "158", + "name": "Super strength(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "159", + "name": "Super strength(2)", + "examine": "2 doses of super Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "160", + "name": "Super strength(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "161", + "name": "Super strength(1)", + "examine": "1 dose of super Strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "162", + "name": "Super strength(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "163", + "name": "Super defence(3)", + "examine": "3 doses of super Defence potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "164", + "name": "Super defence(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "165", + "name": "Super defence(2)", + "examine": "2 doses of super Defence potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "166", + "name": "Super defence(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "167", + "name": "Super defence(1)", + "examine": "1 dose of super Defence potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "168", + "name": "Super defence(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "169", + "name": "Ranging potion(3)", + "examine": "3 doses of ranging potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "170", + "name": "Ranging potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "171", + "name": "Ranging potion(2)", + "examine": "2 doses of ranging potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "172", + "name": "Ranging potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "173", + "name": "Ranging potion(1)", + "examine": "1 dose of ranging potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "174", + "name": "Ranging potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "175", + "name": "Antipoison(3)", + "examine": "3 doses of antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "375", + "tradeable": "true" + }, + { + "id": "176", + "name": "Antipoison(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "177", + "name": "Antipoison(2)", + "examine": "2 doses of antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "375", + "tradeable": "true" + }, + { + "id": "178", + "name": "Antipoison(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "179", + "name": "Antipoison(1)", + "examine": "1 dose of antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "375", + "tradeable": "true" + }, + { + "id": "180", + "name": "Antipoison(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "181", + "name": "Super antipoison(3)", + "examine": "3 doses of super anti poison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "182", + "name": "Super antipoison(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "183", + "name": "Super antipoison(2)", + "examine": "2 doses of super anti poison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "184", + "name": "Super antipoison(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "185", + "name": "Super antipoison(1)", + "examine": "1 dose of super anti poison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "186", + "name": "Super antipoison(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "187", + "name": "Weapon poison", + "examine": "For use on daggers and projectiles.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "188", + "name": "Weapon poison", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "189", + "name": "Zamorak brew(3)", + "examine": "3 doses of Zamorak brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "190", + "name": "Zamorak brew(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "191", + "name": "Zamorak brew(2)", + "examine": "2 doses of Zamorak brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "192", + "name": "Zamorak brew(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "193", + "name": "Zamorak brew(1)", + "examine": "1 dose of Zamorak brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "194", + "name": "Zamorak brew(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "195", + "name": "Potion", + "examine": "This is meant to be good for spots.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "196", + "name": "Potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "197", + "name": "Poison chalice", + "examine": "Stankers gives out these strange cocktails for free.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "39", + "tradeable": "true" + }, + { + "id": "198", + "name": "Poison chalice", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "199", + "name": "Grimy guam", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", + "requirements": "{3,15}", + "tradeable": "true" + }, + { + "id": "200", + "name": "Grimy guam", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "201", + "name": "Grimy marrentill", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{5,15}", + "tradeable": "true" + }, + { + "id": "202", + "name": "Grimy marrentill", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "203", + "name": "Grimy tarromin", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{11,15}", + "tradeable": "true" + }, + { + "id": "204", + "name": "Grimy tarromin", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "205", + "name": "Grimy harralander", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{20,15}", + "tradeable": "true" + }, + { + "id": "206", + "name": "Grimy harralander", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "207", + "name": "Grimy ranarr", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,25}", + "tradeable": "true" + }, + { + "id": "208", + "name": "Grimy ranarr", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "209", + "name": "Grimy irit", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,40}", + "tradeable": "true" + }, + { + "id": "210", + "name": "Grimy irit", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "211", + "name": "Grimy avantoe", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,48}", + "tradeable": "true" + }, + { + "id": "212", + "name": "Grimy avantoe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "213", + "name": "Grimy kwuarm", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,54}", + "tradeable": "true" + }, + { + "id": "214", + "name": "Grimy kwuarm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "215", + "name": "Grimy cadantine", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,65}", + "tradeable": "true" + }, + { + "id": "216", + "name": "Grimy cadantine", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "217", + "name": "Grimy dwarf weed", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,70}", + "tradeable": "true" + }, + { + "id": "218", + "name": "Grimy dwarf weed", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "219", + "name": "Grimy torstol", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{15,75}", + "tradeable": "true" + }, + { + "id": "220", + "name": "Grimy torstol", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "221", + "name": "Eye of newt", + "examine": "It seems to be looking at me.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "222", + "name": "Eye of newt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "223", + "name": "Red spiders' eggs", + "examine": "Ewww!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "224", + "name": "Red spiders' eggs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "225", + "name": "Limpwurt root", + "examine": "The root of a limpwurt plant.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "226", + "name": "Limpwurt root", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "227", + "name": "Vial of water", + "examine": "A glass vial containing water.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "10", + "tradeable": "true", + "weight": "0.02" + }, + { + "id": "228", + "name": "Vial of water", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "229", + "name": "Vial", "examine": "An empty glass vial.", - "grand_exchange_price": "2", - "durability": null, - "name": "Vial", - "tradeable": "true", "archery_ticket_price": "0", - "id": "229" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "5", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "2", - "durability": null, + "id": "230", "name": "Vial", - "tradeable": "true", "archery_ticket_price": "0", - "id": "230" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "67", - "ge_buy_limit": "10000", + "id": "231", + "name": "Snape grass", "examine": "Strange spiky grass.", - "grand_exchange_price": "318", - "durability": null, - "name": "Snape grass", - "tradeable": "true", "archery_ticket_price": "0", - "id": "231" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "318", - "durability": null, - "name": "Snape grass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "232" + "shop_price": "67", + "tradeable": "true" }, { - "shop_price": "4", - "ge_buy_limit": "1000", + "id": "232", + "name": "Snape grass", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "233", + "name": "Pestle and mortar", "examine": "I can grind things for potions in this.", - "grand_exchange_price": "38", - "durability": null, - "name": "Pestle and mortar", - "tradeable": "true", - "weight": "0.05", "archery_ticket_price": "0", - "id": "233" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "38", - "durability": null, + "shop_price": "4", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "234", "name": "Pestle and mortar", - "tradeable": "true", "archery_ticket_price": "0", - "id": "234" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "235", + "name": "Unicorn horn dust", "examine": "Finely ground horn of Unicorn.", - "grand_exchange_price": "2460", - "durability": null, - "name": "Unicorn horn dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "235" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "2460", - "durability": null, + "id": "236", "name": "Unicorn horn dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "236" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "237", + "name": "Unicorn horn", "examine": "This horn has restorative properties.", - "grand_exchange_price": "2481", - "durability": null, - "name": "Unicorn horn", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "237" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "2481", - "durability": null, + "id": "238", "name": "Unicorn horn", - "tradeable": "true", "archery_ticket_price": "0", - "id": "238" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "239", + "name": "White berries", "examine": "Sour berries, used in potions.", - "grand_exchange_price": "1438", - "durability": null, - "name": "White berries", - "tradeable": "true", "archery_ticket_price": "0", - "id": "239" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1438", - "durability": null, + "id": "240", "name": "White berries", - "tradeable": "true", "archery_ticket_price": "0", - "id": "240" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "241", + "name": "Dragon scale dust", "examine": "Finely ground scale of Dragon.", - "grand_exchange_price": "1336", - "durability": null, - "name": "Dragon scale dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "241" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1336", - "durability": null, + "id": "242", "name": "Dragon scale dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "242" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "243", + "name": "Blue dragon scale", "examine": "A large shiny scale.", - "grand_exchange_price": "1244", - "durability": null, - "name": "Blue dragon scale", - "tradeable": "true", - "weight": "0.01", "archery_ticket_price": "0", - "id": "243" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.01" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1244", - "durability": null, + "id": "244", "name": "Blue dragon scale", - "tradeable": "true", "archery_ticket_price": "0", - "id": "244" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "245", + "name": "Wine of zamorak", "examine": "An evil wine that is often found in chaos temples.", - "grand_exchange_price": "2768", - "durability": null, - "name": "Wine of zamorak", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "245" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "2768", - "durability": null, + "id": "246", "name": "Wine of zamorak", - "tradeable": "true", "archery_ticket_price": "0", - "id": "246" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "247", + "name": "Jangerberries", "examine": "They don't look very ripe.", - "grand_exchange_price": "83", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "248", "name": "Jangerberries", - "tradeable": "true", "archery_ticket_price": "0", - "id": "247" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "83", - "durability": null, - "name": "Jangerberries", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "248" - }, - { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "182", - "durability": null, + "id": "249", "name": "Clean guam", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "249" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "182", - "durability": null, + "id": "250", "name": "Clean guam", - "tradeable": "true", "archery_ticket_price": "0", - "id": "250" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "23", - "durability": null, + "id": "251", "name": "Clean marrentill", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "251" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "23", - "durability": null, + "id": "252", "name": "Clean marrentill", - "tradeable": "true", "archery_ticket_price": "0", - "id": "252" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "144", - "durability": null, + "id": "253", "name": "Clean tarromin", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "253" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "144", - "durability": null, + "id": "254", "name": "Clean tarromin", - "tradeable": "true", "archery_ticket_price": "0", - "id": "254" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "275", - "durability": null, + "id": "255", "name": "Clean harralander", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "255" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "275", - "durability": null, + "id": "256", "name": "Clean harralander", - "tradeable": "true", "archery_ticket_price": "0", - "id": "256" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "4930", - "durability": null, + "id": "257", "name": "Clean ranarr", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "257" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "4930", - "durability": null, + "id": "258", "name": "Clean ranarr", - "tradeable": "true", "archery_ticket_price": "0", - "id": "258" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "2072", - "durability": null, + "id": "259", "name": "Clean irit", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "259" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "2072", - "durability": null, + "id": "260", "name": "Clean irit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "260" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "3812", - "durability": null, + "id": "261", "name": "Clean avantoe", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "261" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "3812", - "durability": null, + "id": "262", "name": "Clean avantoe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "262" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "1641", - "durability": null, + "id": "263", "name": "Clean kwuarm", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "263" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1641", - "durability": null, + "id": "264", "name": "Clean kwuarm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "264" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "1585", - "durability": null, + "id": "265", "name": "Clean cadantine", - "tradeable": "true", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "265" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1585", - "durability": null, + "id": "266", "name": "Clean cadantine", - "tradeable": "true", "archery_ticket_price": "0", - "id": "266" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "6925", - "durability": null, + "id": "267", "name": "Clean dwarf weed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "267" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "6925", - "durability": null, - "name": "Clean dwarf weed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "268" - }, - { - "ge_buy_limit": "10000", "examine": "A fresh herb.", - "grand_exchange_price": "8400", - "durability": null, - "name": "Clean torstol", - "tradeable": "true", "archery_ticket_price": "0", - "id": "269" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "35900", - "durability": null, - "name": "Clean torstol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "270" + "tradeable": "true" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "It looks like part of a machine", + "id": "268", + "name": "Clean dwarf weed", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "269", + "name": "Clean torstol", + "examine": "A fresh herb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "270", + "name": "Clean torstol", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "271", "name": "Pressure gauge", + "examine": "It looks like part of a machine", "archery_ticket_price": "0", - "id": "271" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A box of fish food / Keeps your pet fish strong and healthy.", - "durability": null, - "name": "Fish food", - "archery_ticket_price": "0", "id": "272", + "name": "Fish food", + "examine": "A box of fish food / Keeps your pet fish strong and healthy.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "5" }, { - "destroy_message": "You'll have to make more in Draynor Manor.", - "examine": "This isn't good for fish.", - "durability": null, - "name": "Poisoned fish food", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "274" + "id": "273", + "name": "Poison", + "examine": "This stuff looks nasty." }, { - "destroy_message": "You can reclaim this item from the place you found it.", + "id": "274", + "name": "Poisoned fish food", + "examine": "This isn't good for fish.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to make more in Draynor Manor.", "durability": null, + "tradeable": "false" + }, + { + "id": "275", "name": "Key", "archery_ticket_price": "0", - "id": "275" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "It's slightly charred.", - "durability": null, + "id": "276", "name": "Rubber tube", + "examine": "It's slightly charred.", "archery_ticket_price": "0", - "id": "276" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "It's pretty full.", - "durability": null, + "id": "277", "name": "Oil can", - "tradeable": "false", + "examine": "It's pretty full.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "277" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "A sharp cattleprod.", - "durability": null, - "name": "Cattleprod", - "weight": "0.4", - "archery_ticket_price": "0", "id": "278", - "weapon_interface": "5", + "name": "Cattleprod", + "examine": "A sharp cattleprod.", + "archery_ticket_price": "0", "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0", - "equipment_slot": "3" + "durability": null, + "equipment_slot": "3", + "weapon_interface": "5", + "weight": "0.4" }, { - "examine": "Councillor Halgrive gave me this to kill some sheep.", - "durability": null, + "id": "279", "name": "Sheep feed", - "weight": "2.2", + "examine": "Councillor Halgrive gave me this to kill some sheep.", "archery_ticket_price": "0", - "id": "279" + "durability": null, + "weight": "2.2" }, { - "examine": "The suspicious-looking remains of a suspicious-looking sheep.", - "durability": null, + "id": "280", "name": "Sheep bones (1)", + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", "archery_ticket_price": "0", - "id": "280" + "durability": null }, { - "examine": "The suspicious-looking remains of a suspicious-looking sheep.", - "durability": null, + "id": "281", "name": "Sheep bones (2)", + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", "archery_ticket_price": "0", - "id": "281" + "durability": null }, { - "examine": "The suspicious-looking remains of a suspicious-looking sheep.", - "durability": null, + "id": "282", "name": "Sheep bones (3)", - "archery_ticket_price": "0", - "id": "282" - }, - { "examine": "The suspicious-looking remains of a suspicious-looking sheep.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "283", "name": "Sheep bones (4)", + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", "archery_ticket_price": "0", - "id": "283" + "durability": null }, { - "remove_sleeves": "true", - "examine": "This should protect me from the plague, I hope!", - "durability": null, - "name": "Plague jacket", - "weight": "2.2", - "archery_ticket_price": "0", "id": "284", - "equipment_slot": "4" + "name": "Plague jacket", + "examine": "This should protect me from the plague, I hope!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2.2" }, { - "examine": "A thick pair of leather trousers. or These should protect me from the plague, I hope!", - "durability": null, - "name": "Plague trousers", - "weight": "2.2", - "archery_ticket_price": "0", "id": "285", - "equipment_slot": "7" + "name": "Plague trousers", + "examine": "A thick pair of leather trousers. or These should protect me from the plague, I hope!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "2.2" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Orange goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "286", - "equipment_slot": "4" + "name": "Orange goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Blue goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "287", - "equipment_slot": "4" - }, - { - "shop_price": "16", - "ge_buy_limit": "100", + "name": "Blue goblin mail", "examine": "Armour designed to fit goblins.", - "grand_exchange_price": "398", - "durability": null, - "name": "Goblin mail", - "tradeable": "true", - "weight": "3.6", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" + }, + { "id": "288", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "398", - "durability": null, "name": "Goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "16", "tradeable": "true", - "archery_ticket_price": "0", - "id": "289" + "weight": "3.6" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This contains some vital research results.", + "id": "289", + "name": "Goblin mail", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "290", "name": "Research package", - "weight": "1", + "examine": "This contains some vital research results.", "archery_ticket_price": "0", - "id": "290" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "weight": "1" + }, + { + "id": "291", "name": "Notes", "archery_ticket_price": "0", - "id": "291" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "examine": "A book on elven history in northern 2009Scape.", - "durability": null, + "id": "292", "name": "Book on baxtorian", + "examine": "A book on elven history in northern 2009Scape.", "archery_ticket_price": "0", - "id": "292" + "durability": null }, { - "examine": "A small pebble with elven inscription.", - "durability": null, + "id": "293", + "name": "A key", + "examine": "This will unlock something. (Waterfall Quest)", + "archery_ticket_price": "0", + "tradeable": "false", + "weight": "0.01" + }, + { + "id": "294", "name": "Glarial's pebble", + "examine": "A small pebble with elven inscription.", "archery_ticket_price": "0", - "id": "294" + "durability": null }, { - "examine": "A bright green gem set in a necklace.", - "durability": null, - "name": "Glarial's amulet", - "archery_ticket_price": "0", "id": "295", + "name": "Glarial's amulet", + "examine": "A bright green gem set in a necklace.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "examine": "An urn containing Glarial's ashes./An empty urn made for Glarial's ashes.", - "durability": null, + "id": "296", "name": "Glarial's urn", - "archery_ticket_price": "0", - "id": "296" - }, - { "examine": "An urn containing Glarial's ashes./An empty urn made for Glarial's ashes.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "297", "name": "Glarial's urn", + "examine": "An urn containing Glarial's ashes./An empty urn made for Glarial's ashes.", "archery_ticket_price": "0", - "id": "297" + "durability": null }, { - "shop_price": "300", - "ge_buy_limit": "5000", - "examine": "Magical seeds in a mithril case.", - "grand_exchange_price": "623", - "durability": null, - "name": "Mithril seeds", - "tradeable": "true", + "id": "298", + "name": "A key", + "examine": "This will unlock something. (Waterfall dungeon)", "archery_ticket_price": "0", - "id": "299" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A bit of rat.", - "durability": null, - "name": "Rat's tail", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "300" + "weight": "0.01" }, { + "id": "299", + "name": "Mithril seeds", + "examine": "Magical seeds in a mithril case.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "300", + "name": "Rat's tail", + "examine": "A bit of rat.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "301", + "name": "Lobster pot", + "examine": "Useful for catching lobsters.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{10,40}", "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Useful for catching lobsters.", - "grand_exchange_price": "100", - "durability": null, - "name": "Lobster pot", "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "301" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "100", - "durability": null, + "id": "302", "name": "Lobster pot", - "tradeable": "true", "archery_ticket_price": "0", - "id": "302" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "40", - "ge_buy_limit": "100", + "id": "303", + "name": "Small fishing net", "examine": "Useful for catching small fish.", - "grand_exchange_price": "397", - "durability": null, - "name": "Small fishing net", - "tradeable": "true", - "weight": "4.5", "archery_ticket_price": "0", - "id": "303" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "397", - "durability": null, - "name": "Small fishing net", + "shop_price": "40", "tradeable": "true", - "archery_ticket_price": "0", - "id": "304" + "weight": "4.5" }, { + "id": "304", + "name": "Small fishing net", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "305", + "name": "Big fishing net", + "examine": "Useful for catching lots of fish.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{16,10}", "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Useful for catching lots of fish.", - "grand_exchange_price": "329", - "durability": null, - "name": "Big fishing net", "tradeable": "true", - "weight": "8.1", - "archery_ticket_price": "0", - "id": "305" + "weight": "8.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "329", - "durability": null, + "id": "306", "name": "Big fishing net", - "tradeable": "true", "archery_ticket_price": "0", - "id": "306" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "307", + "name": "Fishing rod", + "examine": "Useful for catching sardine or herring.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{5,10}", "shop_price": "5", - "ge_buy_limit": "100", - "examine": "Useful for catching sardine or herring.", - "grand_exchange_price": "74", - "durability": null, - "name": "Fishing rod", "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "307" + "weight": "1.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "74", - "durability": null, + "id": "308", "name": "Fishing rod", - "tradeable": "true", "archery_ticket_price": "0", - "id": "308" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "309", + "name": "Fly fishing rod", + "examine": "Useful for catching salmon or trout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{20,10}", "shop_price": "5", - "ge_buy_limit": "100", - "examine": "Useful for catching salmon or trout.", - "grand_exchange_price": "123", - "durability": null, - "name": "Fly fishing rod", "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "309" + "weight": "1.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "123", - "durability": null, + "id": "310", "name": "Fly fishing rod", - "tradeable": "true", "archery_ticket_price": "0", - "id": "310" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "311", + "name": "Harpoon", + "examine": "Useful for catching big fish.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", "requirements": "{10,35}", "shop_price": "45", - "ge_buy_limit": "5000", - "examine": "Useful for catching big fish.", - "grand_exchange_price": "235", - "durability": null, - "name": "Harpoon", "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "311" + "weight": "1.3" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "235", - "durability": null, + "id": "312", "name": "Harpoon", - "tradeable": "true", "archery_ticket_price": "0", - "id": "312" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "For use with a fishing rod.", - "grand_exchange_price": "3", - "durability": null, + "id": "313", "name": "Fishing bait", - "tradeable": "true", + "examine": "For use with a fishing rod.", "archery_ticket_price": "0", - "id": "313" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" }, { - "shop_price": "6", - "ge_buy_limit": "10000", - "examine": "Used for fly fishing.", - "grand_exchange_price": "24", - "durability": null, + "id": "314", "name": "Feather", - "tradeable": "true", + "examine": "Used for fly fishing.", "archery_ticket_price": "0", - "id": "314" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "6", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "315", + "name": "Shrimps", "examine": "Some nicely cooked shrimp.", - "grand_exchange_price": "9", - "durability": null, - "name": "Shrimps", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "315" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "9", - "durability": null, - "name": "Shrimps", "tradeable": "true", - "archery_ticket_price": "0", - "id": "316" + "weight": "0.5" }, { - "shop_price": "6", - "ge_buy_limit": "20000", + "id": "316", + "name": "Shrimps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "317", + "name": "Raw shrimps", "examine": "I should try cooking this.", - "grand_exchange_price": "7", - "durability": null, - "name": "Raw shrimps", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "317" - }, - { + "durability": null, "ge_buy_limit": "20000", - "grand_exchange_price": "7", - "durability": null, - "name": "Raw shrimps", + "shop_price": "6", "tradeable": "true", - "archery_ticket_price": "0", - "id": "318" + "weight": "0.5" }, { - "ge_buy_limit": "10000", + "id": "318", + "name": "Raw shrimps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "319", + "name": "Anchovies", "examine": "Some nicely cooked anchovies.", - "grand_exchange_price": "26", - "durability": null, - "name": "Anchovies", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "319" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "26", - "durability": null, - "name": "Anchovies", "tradeable": "true", - "archery_ticket_price": "0", - "id": "320" + "weight": "0.1" }, { - "shop_price": "16", - "ge_buy_limit": "20000", + "id": "320", + "name": "Anchovies", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "321", + "name": "Raw anchovies", "examine": "I should try cooking this.", - "grand_exchange_price": "11", - "durability": null, - "name": "Raw anchovies", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "321" - }, - { + "durability": null, "ge_buy_limit": "20000", - "grand_exchange_price": "11", - "durability": null, + "shop_price": "16", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "322", "name": "Raw anchovies", - "tradeable": "true", "archery_ticket_price": "0", - "id": "322" - }, - { "durability": null, - "name": "Burnt fish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "324" + "ge_buy_limit": "20000", + "tradeable": "true" }, { - "shop_price": "10", - "ge_buy_limit": "10000", + "id": "324", + "name": "Burnt fish", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "325", + "name": "Sardine", "examine": "Some nicely cooked Sardines.", - "grand_exchange_price": "12", - "durability": null, - "name": "Sardine", - "tradeable": "true", - "weight": "0.12", "archery_ticket_price": "0", - "id": "325" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "12", - "durability": null, - "name": "Sardine", + "shop_price": "10", "tradeable": "true", - "archery_ticket_price": "0", - "id": "326" + "weight": "0.12" }, { - "shop_price": "7", - "ge_buy_limit": "20000", + "id": "326", + "name": "Sardine", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "327", + "name": "Raw sardine", "examine": "I should try cooking this.", - "grand_exchange_price": "31", - "durability": null, - "name": "Raw sardine", - "tradeable": "true", - "weight": "0.12", "archery_ticket_price": "0", - "id": "327" - }, - { + "durability": null, "ge_buy_limit": "20000", - "grand_exchange_price": "31", - "durability": null, - "name": "Raw sardine", + "shop_price": "7", "tradeable": "true", - "archery_ticket_price": "0", - "id": "328" + "weight": "0.12" }, { - "shop_price": "88", - "ge_buy_limit": "10000", + "id": "328", + "name": "Raw sardine", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "329", + "name": "Salmon", "examine": "Some nicely cooked salmon.", - "grand_exchange_price": "278", - "durability": null, - "name": "Salmon", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "329" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "278", - "durability": null, - "name": "Salmon", + "shop_price": "88", "tradeable": "true", - "archery_ticket_price": "0", - "id": "330" + "weight": "0.5" }, { + "id": "330", + "name": "Salmon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "331", + "name": "Raw salmon", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", "shop_price": "36", - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "172", - "durability": null, - "name": "Raw salmon", "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "331" + "weight": "0.5" }, { - "ge_buy_limit": "20000", - "grand_exchange_price": "172", - "durability": null, + "id": "332", "name": "Raw salmon", - "tradeable": "true", "archery_ticket_price": "0", - "id": "332" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" }, { - "shop_price": "7", - "ge_buy_limit": "10000", + "id": "333", + "name": "Trout", "examine": "Some nicely cooked trout.", - "grand_exchange_price": "172", - "durability": null, - "name": "Trout", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "333" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "172", - "durability": null, - "name": "Trout", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "334" - }, - { "shop_price": "7", - "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "334", + "name": "Trout", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "335", + "name": "Raw trout", "examine": "I should try cooking this.", - "grand_exchange_price": "67", - "durability": null, - "name": "Raw trout", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "335" - }, - { + "durability": null, "ge_buy_limit": "20000", - "grand_exchange_price": "67", - "durability": null, - "name": "Raw trout", + "shop_price": "7", "tradeable": "true", - "archery_ticket_price": "0", - "id": "336" + "weight": "0.4" }, { - "examine": "Some nicely cooked giant carp.", + "id": "336", + "name": "Raw trout", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "337", "name": "Giant carp", + "examine": "Some nicely cooked giant carp.", "archery_ticket_price": "0", - "id": "337" + "durability": null }, { - "examine": "I should try cooking this.", - "durability": null, + "id": "338", "name": "Raw giant carp", + "examine": "I should try cooking this.", "archery_ticket_price": "0", - "id": "338" + "durability": null }, { - "shop_price": "49", - "ge_buy_limit": "10000", + "id": "339", + "name": "Cod", "examine": "Some nicely cooked fish.", - "grand_exchange_price": "19", - "durability": null, - "name": "Cod", - "tradeable": "true", - "weight": "0.33", "archery_ticket_price": "0", - "id": "339" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "19", - "durability": null, - "name": "Cod", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "340" - }, - { "shop_price": "49", - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "29", - "durability": null, - "name": "Raw cod", "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "341" + "weight": "0.33" }, { - "ge_buy_limit": "20000", - "grand_exchange_price": "29", - "durability": null, - "name": "Raw cod", - "tradeable": "true", + "id": "340", + "name": "Cod", "archery_ticket_price": "0", - "id": "342" - }, - { "durability": null, - "name": "Burnt fish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "344" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "63", - "durability": null, - "name": "Raw herring", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "345" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "63", - "durability": null, - "name": "Raw herring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "346" - }, - { - "shop_price": "6", "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "341", + "name": "Raw cod", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "shop_price": "49", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "342", + "name": "Raw cod", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "344", + "name": "Burnt fish", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "345", + "name": "Raw herring", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "346", + "name": "Raw herring", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "347", + "name": "Herring", "examine": "Some nicely cooked herring.", - "grand_exchange_price": "23", - "durability": null, - "name": "Herring", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "347" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "23", - "durability": null, - "name": "Herring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "348" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "72", - "durability": null, - "name": "Raw pike", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "349" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "72", - "durability": null, - "name": "Raw pike", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "350" - }, - { - "ge_buy_limit": "10000", - "examine": "Some nicely cooked pike.", - "grand_exchange_price": "94", - "durability": null, - "name": "Pike", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "351" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "94", - "durability": null, - "name": "Pike", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "352" - }, - { - "shop_price": "26", - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "14", - "durability": null, - "name": "Raw mackerel", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "353" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "14", - "durability": null, - "name": "Raw mackerel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "354" - }, - { - "shop_price": "23", - "ge_buy_limit": "10000", - "examine": "Some nicely cooked fish.", - "grand_exchange_price": "5", - "durability": null, - "name": "Mackerel", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "355" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "5", - "durability": null, - "name": "Mackerel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "356" - }, - { - "durability": null, - "name": "Burnt fish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "358" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "210", - "durability": null, - "name": "Raw tuna", - "tradeable": "true", - "weight": "0.379", - "archery_ticket_price": "0", - "id": "359" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "210", - "durability": null, - "name": "Raw tuna", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "360" - }, - { - "shop_price": "126", - "ge_buy_limit": "10000", - "examine": "Wow, this is a big fish.", - "grand_exchange_price": "281", - "durability": null, - "name": "Tuna", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "361" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "281", - "durability": null, - "name": "Tuna", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "362" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "490", - "durability": null, - "name": "Raw bass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "363" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "490", - "durability": null, - "name": "Raw bass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "364" - }, - { - "shop_price": "270", - "ge_buy_limit": "10000", - "examine": "Wow, this is a big fish.", - "grand_exchange_price": "330", - "durability": null, - "name": "Bass", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "365" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "330", - "durability": null, - "name": "Bass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "366" - }, - { - "durability": null, - "name": "Burnt fish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "368" - }, - { - "durability": null, - "name": "Burnt fish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "370" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "513", - "durability": null, - "name": "Raw swordfish", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "371" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "513", - "durability": null, - "name": "Raw swordfish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "372" - }, - { - "shop_price": "400", - "ge_buy_limit": "10000", - "examine": "I'd better be careful eating this!", - "grand_exchange_price": "501", - "durability": null, - "name": "Swordfish", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "373" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "501", - "durability": null, - "name": "Swordfish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "374" - }, - { - "durability": null, - "name": "Burnt swordfish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "376" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "322", - "durability": null, - "name": "Raw lobster", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "377" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "322", - "durability": null, - "name": "Raw lobster", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "378" - }, - { - "shop_price": "107", - "ge_buy_limit": "10000", - "examine": "This looks tricky to eat.", - "grand_exchange_price": "334", - "durability": null, - "name": "Lobster", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "379" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "334", - "durability": null, - "name": "Lobster", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "380" - }, - { - "durability": null, - "name": "Burnt lobster", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "382" - }, - { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "1615", - "durability": null, - "name": "Raw shark", - "tradeable": "true", - "weight": "0.7", - "archery_ticket_price": "0", - "id": "383" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "1615", - "examine": "", - "durability": null, - "name": "Raw shark", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "384" - }, - { - "ge_buy_limit": "10000", - "examine": "I'd better be careful eating this.", - "grand_exchange_price": "1682", - "durability": null, - "name": "Shark", - "tradeable": "true", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "385" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1682", - "durability": null, - "name": "Shark", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "386" - }, - { - "durability": null, - "name": "Burnt shark", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "388" - }, - { - "ge_buy_limit": "20000", - "examine": "A rare catch.", - "grand_exchange_price": "2114", - "durability": null, - "name": "Raw manta ray", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "389" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "2114", - "durability": null, - "name": "Raw manta ray", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "390" - }, - { - "ge_buy_limit": "10000", - "examine": "Mmmm...this looks tasty!", - "grand_exchange_price": "2552", - "durability": null, - "name": "Manta ray", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "391" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2552", - "durability": null, - "name": "Manta ray", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "392" - }, - { - "durability": null, - "name": "Burnt manta ray", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "394" - }, - { - "ge_buy_limit": "20000", - "examine": "A rare catch.", - "grand_exchange_price": "2397", - "durability": null, - "name": "Raw sea turtle", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "395" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "2397", - "durability": null, - "name": "Raw sea turtle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "396" - }, - { - "ge_buy_limit": "10000", - "examine": "Tasty!", - "grand_exchange_price": "2486", - "durability": null, - "name": "Sea turtle", - "tradeable": "true", - "weight": "0.35", - "archery_ticket_price": "0", - "id": "397" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2486", - "durability": null, - "name": "Sea turtle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "398" - }, - { - "durability": null, - "name": "Burnt sea turtle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "400" - }, - { - "shop_price": "5", - "ge_buy_limit": "10000", - "examine": "Slightly damp seaweed.", - "grand_exchange_price": "780", - "durability": null, - "name": "Seaweed", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "401" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "780", - "durability": null, - "name": "Seaweed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "402" - }, - { - "ge_buy_limit": "10000", - "examine": "Slightly damp seaweed.", - "grand_exchange_price": "291", - "durability": null, - "name": "Edible seaweed", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "403" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "291", - "durability": null, - "name": "Edible seaweed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "404" - }, - { - "ge_buy_limit": "100", - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "4162", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "405" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4162", - "durability": null, - "name": "Casket", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "406" - }, - { - "ge_buy_limit": "500", - "examine": "Its a rare oyster.", - "grand_exchange_price": "23", - "durability": null, - "name": "Oyster", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "407" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "23", - "durability": null, - "name": "Oyster", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "408" - }, - { - "shop_price": "5", - "examine": "Aww, it's empty.", - "durability": null, - "name": "Empty oyster", - "tradeable": "true", - "weight": "0.08", - "archery_ticket_price": "0", - "id": "409" - }, - { - "durability": null, - "name": "Empty oyster", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "410" - }, - { - "shop_price": "44", - "ge_buy_limit": "500", - "examine": "I could work wonders with a chisel on this pearl.", - "grand_exchange_price": "18", - "durability": null, - "name": "Oyster pearl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "411", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "18", - "durability": null, - "name": "Oyster pearl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "412" - }, - { - "ge_buy_limit": "500", - "examine": "I could work wonders with a chisel on these pearls.", - "grand_exchange_price": "639", - "durability": null, - "name": "Oyster pearls", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "413", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "639", - "durability": null, - "name": "Oyster pearls", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "414" - }, - { - "examine": "An expensive colourless liquid.", - "durability": null, - "name": "Ethenea", - "archery_ticket_price": "0", - "id": "415" - }, - { - "examine": "This isn't worth much.", - "durability": null, - "name": "Liquid honey", - "archery_ticket_price": "0", - "id": "416" - }, - { - "examine": "It's highly poisonous.", - "durability": null, - "name": "Sulphuric broline", - "weight": "1", - "archery_ticket_price": "0", - "id": "417" - }, - { - "examine": "Probably best I don't keep this too long.", - "durability": null, - "name": "Plague sample", - "archery_ticket_price": "0", - "id": "418" - }, - { - "examine": "A special kind of paper.", - "durability": null, - "name": "Touch paper", - "archery_ticket_price": "0", - "id": "419" - }, - { - "examine": "Apparently it distills.", - "durability": null, - "name": "Distillator", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "420" - }, - { - "examine": "Yup. It's an amulet.", - "durability": null, - "name": "Lathas' amulet", - "archery_ticket_price": "0", - "id": "421", - "equipment_slot": "2" - }, - { - "examine": "Birds love this stuff!", - "durability": null, - "name": "Bird feed", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "422" - }, - { - "examine": "(empty) It's empty... (full) It's full of pigeons.", - "durability": null, - "name": "Pigeon cage", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "424" - }, - { - "examine": "(empty) It's empty... (full) It's full of pigeons.", - "durability": null, - "name": "Pigeon cage", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "425" - }, - { - "ge_buy_limit": "100", - "shop_price": "5", - "examine": "Top half of a priest suit.", - "durability": null, - "weight": "2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "55", - "name": "Priest gown", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "426", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,3,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "55", - "durability": null, - "name": "Priest gown", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "427" - }, - { - "ge_buy_limit": "100", - "shop_price": "5", - "examine": "Bottom half of a priest suit.", - "grand_exchange_price": "14", - "durability": null, - "name": "Priest gown", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "428", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,3,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "14", - "durability": null, - "name": "Priest gown", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "429" - }, - { - "remove_sleeves": "true", - "examine": "Medical looking.", - "durability": null, - "name": "Doctors' gown", - "weight": "1", - "archery_ticket_price": "0", - "id": "430", - "equipment_slot": "4" - }, - { - "shop_price": "27", - "examine": "A very strong spirit brewed in Karamja.", - "durability": null, - "name": "Karamjan rum", - "archery_ticket_price": "0", - "id": "431" - }, - { - "examine": "Pirates don't have the best handwriting...", - "durability": null, - "name": "Pirate message", - "weight": "1", - "archery_ticket_price": "0", - "id": "433" - }, - { - "ge_buy_limit": "25000", - "examine": "Some hard dry clay.", - "grand_exchange_price": "150", - "durability": null, - "name": "Clay", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "434" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "406", - "durability": null, - "name": "Clay", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "435" - }, - { - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "80", - "tokkul_price": "4", - "durability": null, - "name": "Copper ore", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "436" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "58", - "durability": null, - "name": "Copper ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "437" - }, - { "shop_price": "6", - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "80", - "tokkul_price": "4", - "durability": null, - "name": "Tin ore", "tradeable": "true", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "438" + "weight": "0.5" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "46", + "id": "348", + "name": "Herring", + "archery_ticket_price": "0", "durability": null, - "name": "Tin ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "439" - }, - { - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "204", - "tokkul_price": "25", - "durability": null, - "name": "Iron ore", - "tradeable": "true", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "440" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "396", - "durability": null, - "name": "Iron ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "441" - }, - { - "shop_price": "82", - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "180", - "tokkul_price": "112", - "durability": null, - "name": "Silver ore", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "442" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "205", - "durability": null, - "name": "Silver ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "443" - }, - { - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "311", - "tokkul_price": "225", - "durability": null, - "name": "Gold ore", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "444" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "319", - "durability": null, - "name": "Gold ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "445" - }, - { - "examine": "This needs refining.", - "durability": null, - "name": "'perfect' gold ore", - "archery_ticket_price": "0", - "id": "446" - }, - { - "shop_price": "243", - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "420", - "tokkul_price": "243", - "durability": null, - "name": "Mithril ore", - "tradeable": "true", - "weight": "1.75", - "archery_ticket_price": "0", - "id": "447" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "369", - "durability": null, - "name": "Mithril ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "448" - }, - { - "shop_price": "1300", - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "1160", - "tokkul_price": "600", - "durability": null, - "name": "Adamantite ore", - "tradeable": "true", - "weight": "2.7", - "archery_ticket_price": "0", - "id": "449" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "1622", - "durability": null, - "name": "Adamantite ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "450" - }, - { - "ge_buy_limit": "25000", - "examine": "This needs refining.", - "grand_exchange_price": "10300", - "tokkul_price": "4800", - "durability": null, - "name": "Runite ore", - "tradeable": "true", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "451" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "10300", - "durability": null, - "name": "Runite ore", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "452" - }, - { - "ge_buy_limit": "25000", - "examine": "Hmm a non-renewable energy source!", - "grand_exchange_price": "320", - "tokkul_price": "67", - "durability": null, - "name": "Coal", - "tradeable": "true", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "453" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "315", - "durability": null, - "name": "Coal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "454" - }, - { - "examine": "The official Alfred Grimhand bar crawl card.", - "durability": null, - "name": "Barcrawl card", - "archery_ticket_price": "0", - "id": "455" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "456" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "457" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "458" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "459" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "460" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "461" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "462" - }, - { - "destroy_message": "You will need to speak to Thormac to get another cage.", - "examine": "It's empty!", - "durability": null, - "name": "Scorpion cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "463" - }, - { "ge_buy_limit": "10000", - "examine": "Found on strange plants that grow around Karamja.", - "grand_exchange_price": "403", - "durability": null, - "name": "Strange fruit", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "464" + "tradeable": "true" }, { + "id": "349", + "name": "Raw pike", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "350", + "name": "Raw pike", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "351", + "name": "Pike", + "examine": "Some nicely cooked pike.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "403", - "durability": null, - "name": "Strange fruit", "tradeable": "true", - "archery_ticket_price": "0", - "id": "465" + "weight": "0.5" }, { - "shop_price": "1", - "examine": "Useless without the head.", - "attack_audios": "2508,0,0,0", + "id": "352", + "name": "Pike", + "archery_ticket_price": "0", "durability": null, - "name": "Pickaxe handle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "466", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Pickaxe handle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "467" - }, - { - "examine": "Nurmof can fix this for me.", - "attack_audios": "2508,0,0,0", - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "468", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "469" - }, - { - "examine": "Nurmof can fix this for me.", - "attack_audios": "2508,0,0,0", - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "470", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "471" - }, - { - "examine": "Nurmof can fix this for me.", - "attack_audios": "2508,0,0,0", - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "472", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "473" - }, - { - "examine": "Nurmof can fix this for me.", - "attack_audios": "2508,0,0,0", - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "474", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "475" - }, - { - "examine": "Nurmof can fix this for me.", - "attack_audios": "2508,0,0,0", - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "476", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "477" - }, - { - "examine": "Nurmof can fix this for me.", - "attack_audios": "2508,0,0,0", - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "478", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "479" - }, - { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, - "name": "Bronze pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "480" - }, - { - "durability": null, - "name": "Bronze pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "481" - }, - { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, - "name": "Iron pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "482" - }, - { - "durability": null, - "name": "Iron pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "483" - }, - { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, - "name": "Steel pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "484" - }, - { - "durability": null, - "name": "Steel pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "485" - }, - { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, - "name": "Mithril pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "486" - }, - { - "durability": null, - "name": "Mithril pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "487" - }, - { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, - "name": "Adamant pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "488" - }, - { - "durability": null, - "name": "Adamant pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "489" - }, - { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, - "name": "Rune pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "490" - }, - { - "durability": null, - "name": "Rune pick head", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "491" - }, - { - "examine": "Useless without the head.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "492", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "493" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "494", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "495" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "496", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "497" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "498", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "499" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "500", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "501" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "502", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "503" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "504", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "505" - }, - { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "506", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Broken axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "507" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "508" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "509" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "510" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "511" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "512" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "513" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "514" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "515" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "516" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "517" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "518" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "519" - }, - { - "examine": "A piece of ancient goblin axe.", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "520" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "521" - }, - { - "examine": "I don't fancy eating this now.", - "durability": null, - "name": "Enchanted beef", - "archery_ticket_price": "0", - "id": "522" - }, - { - "examine": "I don't fancy eating this now.", - "durability": null, - "name": "Enchanted rat meat", - "archery_ticket_price": "0", - "id": "523" - }, - { - "examine": "I don't fancy eating this now.", - "durability": null, - "name": "Enchanted bear meat", - "archery_ticket_price": "0", - "id": "524" - }, - { - "examine": "I don't fancy eating this now.", - "durability": null, - "name": "Enchanted chicken", - "weight": "1", - "archery_ticket_price": "0", - "id": "525" - }, - { - "shop_price": "190", "ge_buy_limit": "10000", - "grand_exchange_price": "190", - "examine": "Bones are for burying!", - "durability": null, - "name": "Bones", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "526" + "tradeable": "true" }, { - "shop_price": "190", + "id": "353", + "name": "Raw mackerel", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "shop_price": "26", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "354", + "name": "Raw mackerel", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "355", + "name": "Mackerel", + "examine": "Some nicely cooked fish.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "190", - "durability": null, - "name": "Bones", + "shop_price": "23", "tradeable": "true", - "archery_ticket_price": "0", - "id": "527" + "weight": "0.3" }, { + "id": "356", + "name": "Mackerel", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "examine": "Bones are for burying!", - "grand_exchange_price": "329", - "durability": null, - "name": "Burnt bones", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "528" + "tradeable": "true" }, { + "id": "358", + "name": "Burnt fish", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "359", + "name": "Raw tuna", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.379" + }, + { + "id": "360", + "name": "Raw tuna", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "361", + "name": "Tuna", + "examine": "Wow, this is a big fish.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "329", - "durability": null, - "name": "Burnt bones", + "shop_price": "126", "tradeable": "true", - "archery_ticket_price": "0", - "id": "529" + "weight": "0.4" }, { + "id": "362", + "name": "Tuna", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "examine": "Ew it's a pile of bones.", - "grand_exchange_price": "354", - "durability": null, - "name": "Bat bones", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "530" + "tradeable": "true" }, { + "id": "363", + "name": "Raw bass", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "364", + "name": "Raw bass", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "365", + "name": "Bass", + "examine": "Wow, this is a big fish.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "354", - "durability": null, - "name": "Bat bones", + "shop_price": "270", "tradeable": "true", - "archery_ticket_price": "0", - "id": "531" + "weight": "0.3" }, { - "shop_price": "593", + "id": "366", + "name": "Bass", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "examine": "Normal: Ew, it's a pile of bones.", - "grand_exchange_price": "593", - "durability": null, - "name": "Big bones", - "tradeable": "true", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "532" + "tradeable": "true" }, { - "shop_price": "593", + "id": "368", + "name": "Burnt fish", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "370", + "name": "Burnt fish", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "371", + "name": "Raw swordfish", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "372", + "name": "Raw swordfish", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "373", + "name": "Swordfish", + "examine": "I'd better be careful eating this!", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "593", - "durability": null, - "name": "Big bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "533" - }, - { - "ge_buy_limit": "10000", - "examine": "Ew, it's a pile of bones.", - "grand_exchange_price": "1357", - "durability": null, - "name": "Babydragon bones", - "tradeable": "true", - "weight": "0.7", - "archery_ticket_price": "0", - "id": "534" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1357", - "durability": null, - "name": "Babydragon bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "535" - }, - { - "ge_buy_limit": "10000", - "examine": "These would feed a dog for months!", - "grand_exchange_price": "1300", - "durability": null, - "name": "Dragon bones", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "536" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "4065", - "durability": null, - "name": "Dragon bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "537" - }, - { - "ge_buy_limit": "100", - "examine": "Keeps a druid's knees nice and warm.", - "grand_exchange_price": "168", - "durability": null, - "name": "Druid's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "538", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "168", - "durability": null, - "name": "Druid's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "539" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "examine": "I feel closer to the gods when I am wearing this.", - "grand_exchange_price": "328", - "durability": null, - "name": "Druid's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "540", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "328", - "durability": null, - "name": "Druid's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "541" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "528", - "durability": null, - "name": "Monk's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "542", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "528", - "durability": null, - "name": "Monk's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "543" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "grand_exchange_price": "1495", - "durability": null, - "name": "Monk's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "544", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,6,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1495", - "durability": null, - "name": "Monk's robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "545" - }, - { - "remove_sleeves": "true", - "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", - "durability": null, - "name": "Shade robe", - "weight": "2", - "archery_ticket_price": "0", - "id": "546", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "4" - }, - { - "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", - "durability": null, - "name": "Shade robe", - "weight": "2", - "archery_ticket_price": "0", - "id": "548", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "Issued by 2009Scape Council to all new citizens.", - "grand_exchange_price": "123", - "durability": null, - "name": "Newcomer map", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "550" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "123", - "durability": null, - "name": "Newcomer map", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "551" - }, - { - "examine": "It lets me talk to ghosts.", - "durability": null, - "name": "Ghostspeak amulet", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "552", - "equipment_slot": "2" - }, - { - "destroy_message": "If you get rid of the skull you'll have to search for it again.", - "examine": "Ooooh spooky!", - "durability": null, - "name": "Ghost's skull", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "553" - }, - { - "shop_price": "17", - "ge_buy_limit": "25000", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "18", - "tokkul_price": "6", - "durability": null, - "name": "Fire rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "554" - }, - { - "shop_price": "17", - "ge_buy_limit": "25000", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "18", - "tokkul_price": "6", - "durability": null, - "name": "Water rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "555" - }, - { - "shop_price": "17", - "ge_buy_limit": "25000", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "18", - "tokkul_price": "6", - "durability": null, - "name": "Air rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "556" - }, - { - "shop_price": "17", - "ge_buy_limit": "25000", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "18", - "tokkul_price": "6", - "durability": null, - "name": "Earth rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "557" - }, - { - "shop_price": "17", - "ge_buy_limit": "25000", - "examine": "Used for basic missile spells.", - "grand_exchange_price": "18", - "tokkul_price": "4", - "durability": null, - "name": "Mind rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "558" - }, - { - "shop_price": "16", - "ge_buy_limit": "25000", - "examine": "Used for Curse spells", - "grand_exchange_price": "16", - "tokkul_price": "4", - "durability": null, - "name": "Body rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "559" - }, - { - "shop_price": "310", - "ge_buy_limit": "25000", - "examine": "Used for medium missile spells.", - "grand_exchange_price": "320", - "durability": null, - "tokkul_price": "270", - "name": "Death rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "560" - }, - { - "shop_price": "372", - "ge_buy_limit": "25000", - "examine": "Used for alchemy spells.", - "grand_exchange_price": "380", - "durability": null, - "name": "Nature rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "561" - }, - { - "shop_price": "140", - "ge_buy_limit": "25000", - "examine": "Used for small missile spells.", - "grand_exchange_price": "140", - "durability": null, - "tokkul_price": "135", - "name": "Chaos rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "562" - }, - { - "shop_price": "378", - "ge_buy_limit": "25000", - "examine": "Used for teleport spells.", - "grand_exchange_price": "380", - "durability": null, - "name": "Law rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "563" - }, - { - "shop_price": "232", - "ge_buy_limit": "25000", - "examine": "Used for enchant spells.", - "grand_exchange_price": "240", - "durability": null, - "name": "Cosmic rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "564" - }, - { - "shop_price": "550", - "ge_buy_limit": "25000", - "examine": "Used for large missile spells.", - "grand_exchange_price": "560", - "durability": null, - "name": "Blood rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "565" - }, - { "shop_price": "400", - "ge_buy_limit": "25000", - "examine": "Used for high level curse spells.", - "grand_exchange_price": "420", - "durability": null, - "name": "Soul rune", "tradeable": "true", - "archery_ticket_price": "0", - "id": "566" + "weight": "0.5" }, { - "ge_buy_limit": "5000", - "examine": "I'd prefer it if it was powered.", - "grand_exchange_price": "561", - "durability": null, - "name": "Unpowered orb", - "tradeable": "true", - "weight": "0.4", + "id": "374", + "name": "Swordfish", "archery_ticket_price": "0", - "id": "567" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "561", - "durability": null, - "name": "Unpowered orb", - "tradeable": "true", + "id": "376", + "name": "Burnt swordfish", "archery_ticket_price": "0", - "id": "568" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "A magic glowing orb.", - "grand_exchange_price": "2346", - "durability": null, - "name": "Fire orb", - "tradeable": "true", - "weight": "0.4", + "id": "377", + "name": "Raw lobster", + "examine": "I should try cooking this.", "archery_ticket_price": "0", - "id": "569" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2346", - "durability": null, - "name": "Fire orb", - "tradeable": "true", + "id": "378", + "name": "Raw lobster", "archery_ticket_price": "0", - "id": "570" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "A magic glowing orb.", - "grand_exchange_price": "2024", - "durability": null, - "name": "Water orb", - "tradeable": "true", - "weight": "0.4", + "id": "379", + "name": "Lobster", + "examine": "This looks tricky to eat.", "archery_ticket_price": "0", - "id": "571" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "107", + "tradeable": "true", + "weight": "0.3" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2024", - "durability": null, - "name": "Water orb", - "tradeable": "true", + "id": "380", + "name": "Lobster", "archery_ticket_price": "0", - "id": "572" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "A magic glowing orb.", - "grand_exchange_price": "2162", - "durability": null, - "name": "Air orb", - "tradeable": "true", - "weight": "0.4", + "id": "382", + "name": "Burnt lobster", "archery_ticket_price": "0", - "id": "573" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2162", - "durability": null, - "name": "Air orb", - "tradeable": "true", + "id": "383", + "name": "Raw shark", + "examine": "I should try cooking this.", "archery_ticket_price": "0", - "id": "574" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.7" }, { - "ge_buy_limit": "5000", - "examine": "A magic glowing orb.", - "grand_exchange_price": "2208", - "durability": null, - "name": "Earth orb", - "tradeable": "true", - "weight": "0.4", + "id": "384", + "name": "Raw shark", + "examine": "", "archery_ticket_price": "0", - "id": "575" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2208", - "durability": null, - "name": "Earth orb", - "tradeable": "true", + "id": "385", + "name": "Shark", + "examine": "I'd better be careful eating this.", "archery_ticket_price": "0", - "id": "576" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.6" }, { - "shop_price": "4", - "ge_buy_limit": "100", - "examine": "I can do magic better in this.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "1840", - "name": "Wizard robe", - "tradeable": "true", + "id": "386", + "name": "Shark", "archery_ticket_price": "0", - "id": "577", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1840", - "durability": null, - "name": "Wizard robe", - "tradeable": "true", + "id": "388", + "name": "Burnt shark", "archery_ticket_price": "0", - "id": "578" + "durability": null, + "tradeable": "true" }, { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "durability": null, - "weight": "0.45", - "equipment_slot": "0", - "grand_exchange_price": "361", - "name": "Wizard hat", - "tradeable": "true", + "id": "389", + "name": "Raw manta ray", + "examine": "A rare catch.", "archery_ticket_price": "0", - "hat": "true", - "id": "579", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "2", - "ge_buy_limit": "100", - "grand_exchange_price": "361", - "durability": null, - "name": "Wizard hat", - "tradeable": "true", + "id": "390", + "name": "Raw manta ray", "archery_ticket_price": "0", - "id": "580" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" }, { + "id": "391", + "name": "Manta ray", + "examine": "Mmmm...this looks tasty!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "392", + "name": "Manta ray", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "394", + "name": "Burnt manta ray", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "395", + "name": "Raw sea turtle", + "examine": "A rare catch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "396", + "name": "Raw sea turtle", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "397", + "name": "Sea turtle", + "examine": "Tasty!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.35" + }, + { + "id": "398", + "name": "Sea turtle", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "400", + "name": "Burnt sea turtle", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "401", + "name": "Seaweed", + "examine": "Slightly damp seaweed.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", "shop_price": "5", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "402", + "name": "Seaweed", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "403", + "name": "Edible seaweed", + "examine": "Slightly damp seaweed.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "404", + "name": "Edible seaweed", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "405", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "examine": "I can do magic better in this.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "1364", - "name": "Black robe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "581", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + "weight": "5" }, { + "id": "406", + "name": "Casket", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1364", + "tradeable": "true" + }, + { + "id": "407", + "name": "Oyster", + "examine": "Its a rare oyster.", + "archery_ticket_price": "0", "durability": null, - "name": "Black robe", + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "408", + "name": "Oyster", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "409", + "name": "Empty oyster", + "examine": "Aww, it's empty.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5", "tradeable": "true", - "archery_ticket_price": "0", - "id": "582" + "weight": "0.08" }, { - "shop_price": "10", - "examine": "Empty: It's a bailing bucket. Full: It's a bailing bucket full of salty water.", - "durability": null, - "name": "Bailing bucket", - "tradeable": "true", - "weight": "1", + "id": "410", + "name": "Empty oyster", "archery_ticket_price": "0", - "id": "583" + "durability": null, + "tradeable": "true" }, { - "durability": null, - "name": "Bailing bucket", - "tradeable": "true", + "id": "411", + "name": "Oyster pearl", + "examine": "I could work wonders with a chisel on this pearl.", "archery_ticket_price": "0", - "id": "584" + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "500", + "shop_price": "44", + "tradeable": "true" }, { - "shop_price": "10", - "examine": "Empty: It's a bailing bucket. Full: It's a bailing bucket full of salty water.", - "durability": null, - "name": "Bailing bucket", - "tradeable": "true", - "weight": "1", + "id": "412", + "name": "Oyster pearl", "archery_ticket_price": "0", - "id": "585" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "durability": null, - "name": "Bailing bucket", - "tradeable": "true", + "id": "413", + "name": "Oyster pearls", + "examine": "I could work wonders with a chisel on these pearls.", "archery_ticket_price": "0", - "id": "586" + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "500", + "tradeable": "true" }, { - "examine": "A strange glowing green orb.", - "durability": null, - "name": "Orb of protection", - "weight": "1", + "id": "414", + "name": "Oyster pearls", "archery_ticket_price": "0", - "id": "587" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "examine": "Two strange glowing green orbs.", - "durability": null, - "name": "Orbs of protection", + "id": "415", + "name": "Ethenea", + "examine": "An expensive colourless liquid.", "archery_ticket_price": "0", - "id": "588" + "durability": null }, { - "examine": "It's an amulet of protection given to me by the Gnomes.", - "durability": null, - "name": "Gnome amulet", + "id": "416", + "name": "Liquid honey", + "examine": "This isn't worth much.", "archery_ticket_price": "0", - "id": "589", - "bonuses": "0,0,0,0,0,13,13,13,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "417", + "name": "Sulphuric broline", + "examine": "It's highly poisonous.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "418", + "name": "Plague sample", + "examine": "Probably best I don't keep this too long.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "419", + "name": "Touch paper", + "examine": "A special kind of paper.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "420", + "name": "Distillator", + "examine": "Apparently it distills.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "421", + "name": "Lathas' amulet", + "examine": "Yup. It's an amulet.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "shop_price": "1", - "ge_buy_limit": "5000", - "examine": "Useful for lighting a fire.", - "grand_exchange_price": "118", - "durability": null, - "name": "Tinderbox", - "tradeable": "true", - "weight": "0.05", + "id": "422", + "name": "Bird feed", + "examine": "Birds love this stuff!", "archery_ticket_price": "0", - "id": "590" + "durability": null, + "weight": "0.1" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "118", - "durability": null, - "name": "Tinderbox", - "tradeable": "true", + "id": "424", + "name": "Pigeon cage", + "examine": "(empty) It's empty... (full) It's full of pigeons.", "archery_ticket_price": "0", - "id": "591" + "durability": null, + "weight": "0.1" }, { + "id": "425", + "name": "Pigeon cage", + "examine": "(empty) It's empty... (full) It's full of pigeons.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "426", + "name": "Priest gown", + "examine": "Top half of a priest suit.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,3,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "5", + "tradeable": "true", + "weight": "2" + }, + { + "id": "427", + "name": "Priest gown", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "428", + "name": "Priest gown", + "examine": "Bottom half of a priest suit.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,3,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true", + "weight": "2" + }, + { + "id": "429", + "name": "Priest gown", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "430", + "name": "Doctors' gown", + "examine": "Medical looking.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "1" + }, + { + "id": "431", + "name": "Karamjan rum", + "examine": "A very strong spirit brewed in Karamja.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "27" + }, + { + "id": "433", + "name": "Pirate message", + "examine": "Pirates don't have the best handwriting...", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "434", + "name": "Clay", + "examine": "Some hard dry clay.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "435", + "name": "Clay", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "436", + "name": "Copper ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tokkul_price": "4", + "tradeable": "true", + "weight": "2" + }, + { + "id": "437", + "name": "Copper ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "438", + "name": "Tin ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "6", + "tokkul_price": "4", + "tradeable": "true", + "weight": "2.25" + }, + { + "id": "439", + "name": "Tin ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "440", + "name": "Iron ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tokkul_price": "25", + "tradeable": "true", + "weight": "2.25" + }, + { + "id": "441", + "name": "Iron ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "442", + "name": "Silver ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "82", + "tokkul_price": "112", + "tradeable": "true", + "weight": "2" + }, + { + "id": "443", + "name": "Silver ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "444", + "name": "Gold ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tokkul_price": "225", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "445", + "name": "Gold ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "446", + "name": "'perfect' gold ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "447", + "name": "Mithril ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "243", + "tokkul_price": "243", + "tradeable": "true", + "weight": "1.75" + }, + { + "id": "448", + "name": "Mithril ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "449", + "name": "Adamantite ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "1300", + "tokkul_price": "600", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "450", + "name": "Adamantite ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "451", + "name": "Runite ore", + "examine": "This needs refining.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tokkul_price": "4800", + "tradeable": "true", + "weight": "2.25" + }, + { + "id": "452", + "name": "Runite ore", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "453", + "name": "Coal", + "examine": "Hmm a non-renewable energy source!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tokkul_price": "67", + "tradeable": "true", + "weight": "2.25" + }, + { + "id": "454", + "name": "Coal", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "455", + "name": "Barcrawl card", + "examine": "The official Alfred Grimhand bar crawl card.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "456", + "name": "Scorpion cage", + "examine": "It's empty!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.15" + }, + { + "id": "457", + "name": "Scorpion cage", + "examine": "There is 1 scorpion inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.175" + }, + { + "id": "458", + "name": "Scorpion cage", + "examine": "There are 2 scorpions inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "459", + "name": "Scorpion cage", + "examine": "There is 1 scorpion inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.175" + }, + { + "id": "460", + "name": "Scorpion cage", + "examine": "There are 2 scorpions inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "461", + "name": "Scorpion cage", + "examine": "There is 1 scorpion inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.175" + }, + { + "id": "462", + "name": "Scorpion cage", + "examine": "There are 2 scorpions inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "463", + "name": "Scorpion cage", + "examine": "There are 3 scorpions inside.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Thormac to get another cage.", + "durability": null, + "tradeable": "false", + "weight": "0.225" + }, + { + "id": "464", + "name": "Strange fruit", + "examine": "Found on strange plants that grow around Karamja.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "examine": "A heap of ashes.", - "grand_exchange_price": "368", - "durability": null, - "name": "Ashes", "tradeable": "true", - "weight": "0.056", - "archery_ticket_price": "0", - "id": "592" + "weight": "1" }, { + "id": "465", + "name": "Strange fruit", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "368", - "durability": null, - "name": "Ashes", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "593" - }, - { - "examine": "A lit home-made torch.", - "durability": null, - "name": "Lit torch", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "594" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "An unlit home-made torch.", - "grand_exchange_price": "1", - "durability": null, - "name": "Unlit torch", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "596" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, - "name": "Unlit torch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "597" - }, - { - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with bronze heads and oil-soaked cloth. lit: An easy to make, bronze-headed fire arrow.", - "grand_exchange_price": "162", - "durability": null, - "name": "Bronze fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "598", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A book on the history of astronomy in 2009Scape.", - "grand_exchange_price": "658", - "durability": null, - "name": "Astronomy book", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "600" - }, - { - "destroy_message": "You'll have to find another, down in the dungeon.", - "examine": "A small key for a large door.", - "durability": null, - "name": "Goblin kitchen key", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "601" - }, - { - "destroy_message": "You'll have to get another down in the Dungeon", - "examine": "An unusual clay mould in the shape of a disc.", - "durability": null, - "name": "Lens mould", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "602" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A perfectly circular disc of glass.", - "durability": null, - "name": "Observatory lens", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "603" - }, - { - "shop_price": "160", - "examine": "A slender bone shard given to you by Zadimus.", - "durability": null, - "name": "Bone shard", - "archery_ticket_price": "0", - "id": "604" - }, - { - "shop_price": "100", - "examine": "A key fashioned from a shard of bone. (Shilo Village)", - "durability": null, - "name": "Bone key", - "archery_ticket_price": "0", - "id": "605" - }, - { - "examine": "A stone plaque with carved letters in it.", - "durability": null, - "name": "Stone-plaque", - "archery_ticket_price": "0", - "id": "606" - }, - { - "examine": "An ancient tattered scroll.", - "durability": null, - "name": "Tattered scroll", - "archery_ticket_price": "0", - "id": "607" - }, - { - "shop_price": "100", - "examine": "An ancient crumpled scroll.", - "durability": null, - "name": "Crumpled scroll", - "archery_ticket_price": "0", - "id": "608" - }, - { - "examine": "The remains of the Zombie Queen.", - "durability": null, - "name": "Rashiliyia corpse", - "archery_ticket_price": "0", - "id": "609" - }, - { - "examine": "The remains of Zadimus.", - "durability": null, - "name": "Zadimus corpse", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "610" - }, - { - "examine": "A magical crystal sphere.", - "durability": null, - "name": "Locating crystal", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "611" - }, - { - "examine": "A magical crystal sphere.", - "durability": null, - "name": "Locating crystal", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "612" - }, - { - "examine": "A magical crystal sphere.", - "durability": null, - "name": "Locating crystal", - "weight": "0.9", + "id": "466", + "name": "Pickaxe handle", + "examine": "Useless without the head.", "archery_ticket_price": "0", - "id": "613" - }, - { - "examine": "A magical crystal sphere.", - "durability": null, - "name": "Locating crystal", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "614" - }, - { - "examine": "A magical crystal sphere.", - "durability": null, - "name": "Locating crystal", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "615" - }, - { - "destroy_message": "You made the beads of the dead during the Shilo Village quest. You can get another from Yanni Salika in Shilo Village for 1200 gold.", - "shop_price": "1200", - "examine": "A curious looking neck ornament.", - "durability": null, - "name": "Beads of the dead", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "616", - "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,1,0,0", - "equipment_slot": "2" - }, - { - "bankable": "false", - "examine": "Lovely money!", - "durability": null, - "name": "Coins", - "archery_ticket_price": "0", - "id": "617" - }, - { - "examine": "Beads carved out of a bone.", - "durability": null, - "name": "Bone beads", - "archery_ticket_price": "0", - "id": "618" - }, - { - "shop_price": "35", - "examine": "Allows you to rest in the luxurious Paramayer[sic] Inn.", - "durability": null, - "name": "Paramaya ticket", - "archery_ticket_price": "0", - "id": "619" - }, - { - "shop_price": "35", - "examine": "Allows you to rest in the luxurious Paramayer[sic] Inn.", - "durability": null, - "name": "Paramaya ticket", - "archery_ticket_price": "0", - "id": "620" - }, - { - "examine": "Sold in Shilo Village for passage on the 'Lady of the Waves'.", - "durability": null, - "name": "Ship ticket", - "archery_ticket_price": "0", - "id": "621" - }, - { - "examine": "An ivory sword pommel.", - "durability": null, - "name": "Sword pommel", - "archery_ticket_price": "0", - "id": "623" - }, - { - "examine": "Notes taken from the tomb of Bervirius.", - "durability": null, - "name": "Bervirius notes", - "archery_ticket_price": "0", - "id": "624" - }, - { - "examine": "A decorated belt used to trade information between distant villages.", - "durability": null, - "name": "Wampum belt", - "archery_ticket_price": "0", - "id": "625" - }, - { - "ge_buy_limit": "100", - "shop_price": "200", - "examine": "They're soft, silky and pink.", - "grand_exchange_price": "558", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "626", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "558", - "durability": null, - "name": "Boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "627" - }, - { - "ge_buy_limit": "100", - "shop_price": "200", - "examine": "They're soft, silky and green.", - "grand_exchange_price": "397", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "628", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "397", - "durability": null, - "name": "Boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "629" - }, - { - "ge_buy_limit": "100", - "shop_price": "200", - "examine": "They're soft, silky and blue.", - "grand_exchange_price": "612", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "630", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "612", - "durability": null, - "name": "Boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "631" - }, - { - "ge_buy_limit": "100", - "shop_price": "200", - "examine": "They're soft, silky and cream.", - "grand_exchange_price": "496", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "632", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "496", - "durability": null, - "name": "Boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "633" - }, - { - "ge_buy_limit": "100", - "shop_price": "200", - "examine": "They're soft, silky and turquoise.", - "grand_exchange_price": "226", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "634", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "226", - "durability": null, - "name": "Boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "635" - }, - { - "shop_price": "180", - "ge_buy_limit": "100", - "examine": "The ultimate in gnome design, now in pink.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "265", - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "636", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "265", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "637" - }, - { - "shop_price": "180", - "ge_buy_limit": "100", - "examine": "The ultimate in gnome design, now in green.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "235", - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "638", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "235", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "639" - }, - { - "shop_price": "180", - "ge_buy_limit": "100", - "examine": "The ultimate in gnome design, now in blue.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "447", - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "640", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "447", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "641" - }, - { - "shop_price": "180", - "ge_buy_limit": "100", - "examine": "The ultimate in gnome design, now in cream.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "396", - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "642", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "396", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "643" - }, - { - "shop_price": "180", - "ge_buy_limit": "100", - "examine": "The ultimate in gnome design, now in turquoise.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "70", - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "644", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "70", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "645" - }, - { - "ge_buy_limit": "100", - "shop_price": "180", - "examine": "Made by tree gnomes with a thing for pink.", - "grand_exchange_price": "249", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "646", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "249", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "647" - }, - { - "ge_buy_limit": "100", - "shop_price": "180", - "examine": "Made by tree gnomes with a thing for green.", - "grand_exchange_price": "210", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "648", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "210", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "649" - }, - { - "ge_buy_limit": "100", - "shop_price": "180", - "examine": "Made by tree gnomes with a thing for blue.", - "grand_exchange_price": "453", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "650", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "453", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "651" - }, - { - "ge_buy_limit": "100", - "shop_price": "180", - "examine": "Made by tree gnomes with a thing for cream.", - "grand_exchange_price": "348", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "652", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "348", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "653" - }, - { - "ge_buy_limit": "100", - "shop_price": "180", - "examine": "Made by tree gnomes with a thing for turquoise.", - "grand_exchange_price": "92", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "654", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "92", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "655" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "677", - "examine": "A silly, pink pointed hat.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.4", - "hat": "true", - "id": "656", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "677", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "657" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "480", - "examine": "A silly, green pointed hat.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.4", - "hat": "true", - "id": "658", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "480", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "659" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "421", - "examine": "A silly, blue pointed hat.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.4", - "hat": "true", - "id": "660", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "421", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "661" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1102", - "examine": "A silly, cream pointed hat.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.4", - "hat": "true", - "id": "662", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1102", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "663" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "295", - "examine": "A silly, turquoise pointed hat.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.4", - "hat": "true", - "id": "664", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "295", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "665" - }, - { - "examine": "Picture of a posing Paladin.", - "durability": null, - "name": "Portrait", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "666" - }, - { - "turn90cw_anim": "821", - "examine": "A Faladian Knight's sword.", - "walk_anim": "819", + "attack_audios": "2508,0,0,0", "durability": null, - "weight": "1", - "turn90ccw_anim": "822", - "attack_speed": "5", - "weapon_interface": "6", - "turn180_anim": "820", - "render_anim": "292", - "defence_anim": "397", "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "stand_anim": "809", - "attack_audios": "2500,2500,2517,2500", - "name": "Blurite sword", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "667", - "stand_turn_anim": "823", - "bonuses": "9,14,-2,0,0,0,3,2,0,0,0,10,0,0,0" + "shop_price": "1", + "tradeable": "true" }, { - "examine": "Definitely blue.", - "durability": null, - "name": "Blurite ore", - "weight": "2.2", + "id": "467", + "name": "Pickaxe handle", "archery_ticket_price": "0", - "id": "668" + "durability": null, + "tradeable": "true" }, { - "examine": "A receptacle for specimens!", - "durability": null, - "name": "Specimen jar", + "id": "468", + "name": "Broken pickaxe", + "examine": "Nurmof can fix this for me.", "archery_ticket_price": "0", - "id": "669" - }, - { - "examine": "A small brush used to clean rock samples.", + "attack_audios": "2508,0,0,0", "durability": null, - "name": "Specimen brush", - "archery_ticket_price": "0", - "id": "670" - }, - { - "examine": "A carefully-kept-safe skull sample.", - "durability": null, - "name": "Animal skull", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "671" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A special cup.", - "durability": null, - "name": "Special cup", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "672" - }, - { - "examine": "A lucky mascot.", - "durability": null, - "name": "Teddy", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "673" - }, - { - "examine": "A roughly shaped piece of rock.", - "durability": null, - "name": "Cracked sample", + "equipment_slot": "3", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "674" + "weight": "0.2" }, { - "examine": "A small pick for digging.", - "durability": null, - "name": "Rock pick", + "id": "469", + "name": "Broken pickaxe", "archery_ticket_price": "0", - "id": "675", - "equipment_slot": "3" + "durability": null, + "tradeable": "true" }, { - "examine": "Used for digging!", - "durability": null, - "name": "Trowel", + "id": "470", + "name": "Broken pickaxe", + "examine": "Nurmof can fix this for me.", "archery_ticket_price": "0", - "id": "676" - }, - { - "examine": "An empty tray for panning.", + "attack_audios": "2508,0,0,0", "durability": null, - "name": "Panning tray", - "archery_ticket_price": "0", - "id": "677" - }, - { - "examine": "This tray contains gold nuggets.", - "durability": null, - "name": "Panning tray", - "archery_ticket_price": "0", - "id": "678" - }, - { - "examine": "This tray contains mud.", - "durability": null, - "name": "Panning tray", - "archery_ticket_price": "0", - "id": "679" - }, - { - "examine": "Pure, lovely gold!", - "durability": null, - "name": "Nuggets", - "archery_ticket_price": "0", - "id": "680" - }, - { - "examine": "An unusual symbol as yet unidentified by the archaeological expert.", - "durability": null, - "name": "Ancient talisman", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "681" - }, - { - "examine": "A letter waiting to be stamped.", - "durability": null, - "name": "Unstamped letter", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "682" - }, - { - "examine": "A sealed letter of recommendation.", - "durability": null, - "name": "Sealed letter", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "683" - }, - { - "examine": "Used to hold up trousers!", - "durability": null, - "name": "Belt buckle", - "weight": "1", - "archery_ticket_price": "0", - "id": "684" - }, - { - "examine": "Phew!", - "durability": null, - "name": "Old boot", - "archery_ticket_price": "0", - "id": "685" - }, - { - "examine": "A decent-enough weapon gone rusty.", - "durability": null, - "name": "Rusty sword", - "weight": "2", - "archery_ticket_price": "0", - "id": "686" - }, - { - "examine": "This must have been shot at high speed.", - "durability": null, - "name": "Broken arrow", - "archery_ticket_price": "0", - "id": "687" - }, - { - "examine": "Not Dick Whittington's helper at all!", - "durability": null, - "name": "Buttons", - "archery_ticket_price": "0", - "id": "688" - }, - { - "examine": "I pity the poor person beaten with this!", - "attack_audios": "2555,0,0,0", - "durability": null, - "name": "Broken staff", + "equipment_slot": "3", "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "689" + "weight": "0.2" }, { - "examine": "Smashed glass.", + "id": "471", + "name": "Broken pickaxe", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "472", + "name": "Broken pickaxe", + "examine": "Nurmof can fix this for me.", + "archery_ticket_price": "0", + "attack_audios": "2508,0,0,0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "473", + "name": "Broken pickaxe", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "474", + "name": "Broken pickaxe", + "examine": "Nurmof can fix this for me.", + "archery_ticket_price": "0", + "attack_audios": "2508,0,0,0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "475", + "name": "Broken pickaxe", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "476", + "name": "Broken pickaxe", + "examine": "Nurmof can fix this for me.", + "archery_ticket_price": "0", + "attack_audios": "2508,0,0,0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "477", + "name": "Broken pickaxe", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "478", + "name": "Broken pickaxe", + "examine": "Nurmof can fix this for me.", + "archery_ticket_price": "0", + "attack_audios": "2508,0,0,0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "479", + "name": "Broken pickaxe", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "480", + "name": "Bronze pick head", + "examine": "It's missing a handle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "481", + "name": "Bronze pick head", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "482", + "name": "Iron pick head", + "examine": "It's missing a handle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "483", + "name": "Iron pick head", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "484", + "name": "Steel pick head", + "examine": "It's missing a handle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "485", + "name": "Steel pick head", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "486", + "name": "Mithril pick head", + "examine": "It's missing a handle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "487", + "name": "Mithril pick head", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "488", + "name": "Adamant pick head", + "examine": "It's missing a handle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "489", + "name": "Adamant pick head", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "490", + "name": "Rune pick head", + "examine": "It's missing a handle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "491", + "name": "Rune pick head", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "492", + "name": "Picture", + "examine": "Useless without the head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true" + }, + { + "id": "493", "name": "Picture", "archery_ticket_price": "0", - "id": "690" + "durability": null, + "tradeable": "true" }, { - "examine": "The owner has passed Earth Sciences Level 1 exam.", - "durability": null, - "name": "Level 1 certificate", + "id": "494", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "691" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "The owner has passed Earth Sciences Level 2 exam.", - "durability": null, - "name": "Level 2 certificate", + "id": "495", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "692" + "durability": null, + "tradeable": "true" }, { - "examine": "The owner has passed Earth Sciences Level 3 exam.", - "durability": null, - "name": "Level 3 certificate", + "id": "496", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "693" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "Smashing!", - "durability": null, - "name": "Ceramic remains", + "id": "497", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "694" + "durability": null, + "tradeable": "true" }, { - "examine": "Now, if I could just find a tooth fairy to sell this to...", - "durability": null, - "name": "Old tooth", + "id": "498", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "695" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "A letter inviting me to use the private digging shafts.", - "durability": null, - "name": "Invitation letter", - "tradeable": "false", - "destroy": "true", + "id": "499", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "696" + "durability": null, + "tradeable": "true" }, { - "examine": "It would be hard to repair this!", - "durability": null, - "name": "Damaged armour", - "weight": "7.75", + "id": "500", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "697" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "Armour left over from a great fight.", - "durability": null, - "name": "Broken armour", - "weight": "8", + "id": "501", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "698" + "durability": null, + "tradeable": "true" }, { - "examine": "An old stone slab with writing on it.", - "durability": null, - "name": "Stone tablet", + "id": "502", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "699" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "An acrid chemical.", - "durability": null, - "name": "Chemical powder", + "id": "503", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "700" + "durability": null, + "tradeable": "true" }, { - "examine": "An acrid chemical.", - "durability": null, - "name": "Ammonium nitrate", + "id": "504", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "701" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "A strong chemical.", - "durability": null, - "name": "Unidentified liquid", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "id": "505", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "702" + "durability": null, + "tradeable": "true" }, { - "shop_price": "1", - "examine": "A strong chemical.", - "durability": null, - "name": "Nitroglycerin", - "weight": "1", + "id": "506", + "name": "Broken axe", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "703" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { - "examine": "Charcoal - crushed to small pieces!", - "durability": null, - "name": "Ground charcoal", + "id": "507", + "name": "Broken axe", "archery_ticket_price": "0", - "id": "704" + "durability": null, + "tradeable": "true" }, { - "shop_price": "1", - "examine": "A mixture of strong chemicals.", - "durability": null, - "name": "Mixed chemicals", - "weight": "0.03", + "id": "508", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", "archery_ticket_price": "0", - "id": "705" + "durability": null }, { - "shop_price": "1", - "examine": "A mixture of strong chemicals.", - "durability": null, - "name": "Mixed chemicals", - "weight": "0.035", + "id": "509", + "name": "Picture", "archery_ticket_price": "0", - "id": "706" + "durability": null, + "tradeable": "true" }, { - "examine": "A mixture of strong chemicals.", - "durability": null, - "name": "Chemical compound", - "weight": "0.035", + "id": "510", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", "archery_ticket_price": "0", - "id": "707" + "durability": null }, { - "examine": "The root of an arcenia plant.", - "durability": null, - "name": "Arcenia root", + "id": "511", + "name": "Picture", "archery_ticket_price": "0", - "id": "708" + "durability": null, + "tradeable": "true" }, { - "examine": "An unusually shaped vase. You can see something glinting inside.", - "durability": null, - "name": "Vase", + "id": "512", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", "archery_ticket_price": "0", - "id": "710" + "durability": null }, { - "examine": "It's about chemicals, judging from its cover.", - "durability": null, - "name": "Book on chemicals", - "weight": "0.5", + "id": "513", + "name": "Picture", "archery_ticket_price": "0", - "id": "711" + "durability": null, + "tradeable": "true" }, { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", + "id": "514", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "515", + "name": "Picture", + "archery_ticket_price": "0", "durability": null, - "name": "Cup of tea", + "tradeable": "true" + }, + { + "id": "516", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "517", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "518", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "519", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "520", + "name": "Picture", + "examine": "A piece of ancient goblin axe.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "521", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "522", + "name": "Enchanted beef", + "examine": "I don't fancy eating this now.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "523", + "name": "Enchanted rat meat", + "examine": "I don't fancy eating this now.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "524", + "name": "Enchanted bear meat", + "examine": "I don't fancy eating this now.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "525", + "name": "Enchanted chicken", + "examine": "I don't fancy eating this now.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "526", + "name": "Bones", + "examine": "Bones are for burying!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "190", "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "712" + "weight": "0.5" }, { - "examine": "Notes given to you by Radimus Erkle, it includes a partially completed map.", - "durability": null, - "name": "Radimus notes", + "id": "527", + "name": "Bones", "archery_ticket_price": "0", - "id": "714" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "190", + "tradeable": "true" }, { - "examine": "Notes given to you by Radimus Erkle, it includes a partially completed map.", - "durability": null, - "name": "Radimus notes", + "id": "528", + "name": "Burnt bones", + "examine": "Bones are for burying!", "archery_ticket_price": "0", - "id": "715" - }, - { - "examine": "It makes a loud but interesting sound when swung in the air.", "durability": null, - "name": "Bull roarer", - "archery_ticket_price": "0", - "id": "716" - }, - { - "examine": "A scrawled note with spidery writing on it.", - "durability": null, - "name": "Scrawled note", - "archery_ticket_price": "0", - "id": "717" - }, - { - "examine": "A scrawled note with spidery writing on it.", - "durability": null, - "name": "A scribbled note", - "archery_ticket_price": "0", - "id": "718" - }, - { - "examine": "A scrawled note with spidery writing on it.", - "durability": null, - "name": "Scrumpled note", - "archery_ticket_price": "0", - "id": "719" - }, - { - "examine": "A rough sketch of a bowl shaped vessel given to you by Gujuo.", - "durability": null, - "name": "Sketch", - "archery_ticket_price": "0", - "id": "720" - }, - { - "examine": "A specially made bowl constructed out of pure gold.", - "durability": null, - "name": "Gold bowl", - "archery_ticket_price": "0", - "id": "721" - }, - { - "examine": "A specially made bowl constructed out of pure gold and blessed.", - "durability": null, - "name": "Blessed gold bowl", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "722" - }, - { - "examine": "A blessed golden bowl. It has pure sacred water in it.", - "durability": null, - "name": "Golden bowl", - "weight": "1", - "archery_ticket_price": "0", - "id": "723" - }, - { - "examine": "A blessed golden bowl. It has pure sacred water in it.", - "durability": null, - "name": "Golden bowl", - "weight": "1", - "archery_ticket_price": "0", - "id": "724" - }, - { - "examine": "A blessed golden bowl. It has pure sacred water in it.", - "durability": null, - "name": "Golden bowl", - "weight": "1", - "archery_ticket_price": "0", - "id": "725" - }, - { - "examine": "A blessed golden bowl. It has pure sacred water in it.", - "durability": null, - "name": "Golden bowl", - "weight": "1", - "archery_ticket_price": "0", - "id": "726" - }, - { - "examine": "One of nature's pipes.", - "durability": null, - "name": "Hollow reed", - "weight": "0.012", - "archery_ticket_price": "0", - "id": "727" - }, - { - "examine": "One of nature's pipes.", - "durability": null, - "name": "Hollow reed", - "weight": "0.012", - "archery_ticket_price": "0", - "id": "728" - }, - { - "examine": "It looks like the Shamans personal notes...", - "durability": null, - "name": "Shamans tome", - "archery_ticket_price": "0", - "id": "729" - }, - { - "examine": "An ancient tome on Demonology.", - "durability": null, - "name": "Binding book", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "730" - }, - { - "shop_price": "160", - "examine": "An enchanted empty glass vial.", - "durability": null, - "name": "Enchanted vial", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "731" - }, - { - "examine": "A vial of holy water, good against certain demons.", - "durability": null, - "name": "Holy water", - "archery_ticket_price": "0", - "id": "732", - "weapon_interface": "18", - "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,24", - "equipment_slot": "3" - }, - { - "examine": "Fragments of a broken container.", - "durability": null, - "name": "Smashed glass", - "archery_ticket_price": "0", - "id": "733" - }, - { - "examine": "These need to be germinated before they can be used. / These are germinated and ready to be planted in fertile soil.", - "durability": null, - "name": "Yommi tree seeds", - "archery_ticket_price": "0", - "id": "735" - }, - { - "examine": "These need to be germinated before they can be used. / These are germinated and ready to be planted in fertile soil.", - "durability": null, - "name": "Yommi tree seeds", - "archery_ticket_price": "0", - "id": "736" - }, - { - "examine": "A Snakeweed mixture, needs another ingredient.", - "durability": null, - "name": "Snakeweed mixture", - "weight": "1", - "archery_ticket_price": "0", - "id": "737" - }, - { - "examine": "It's a mixture of ardrigal and water. Needs another ingredient.", - "durability": null, - "name": "Ardrigal mixture", - "archery_ticket_price": "0", - "id": "738" - }, - { - "examine": "A bravery potion for which Gujuo gave you the details, let's hope it works.", - "durability": null, - "name": "Bravery potion", - "archery_ticket_price": "0", - "id": "739" - }, - { - "shop_price": "160", - "examine": "A silly, blue pointed hat.", - "grand_exchange_price": "472", - "durability": null, - "name": "Blue hat", + "ge_buy_limit": "10000", "tradeable": "true", - "weight": "0.4", + "weight": "0.2" + }, + { + "id": "529", + "name": "Burnt bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "530", + "name": "Bat bones", + "examine": "Ew it's a pile of bones.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "531", + "name": "Bat bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "532", + "name": "Big bones", + "examine": "Normal: Ew, it's a pile of bones.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "593", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "533", + "name": "Big bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "593", + "tradeable": "true" + }, + { + "id": "534", + "name": "Babydragon bones", + "examine": "Ew, it's a pile of bones.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.7" + }, + { + "id": "535", + "name": "Babydragon bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "536", + "name": "Dragon bones", + "examine": "These would feed a dog for months!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.5" + }, + { + "id": "537", + "name": "Dragon bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "538", + "name": "Druid's robe", + "examine": "Keeps a druid's knees nice and warm.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "539", + "name": "Druid's robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "540", + "name": "Druid's robe", + "examine": "I feel closer to the gods when I am wearing this.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true" + }, + { + "id": "541", + "name": "Druid's robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "542", + "name": "Monk's robe", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "543", + "name": "Monk's robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "544", + "name": "Monk's robe", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,6,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true" + }, + { + "id": "545", + "name": "Monk's robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "546", + "name": "Shade robe", + "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2" + }, + { + "id": "548", + "name": "Shade robe", + "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", + "durability": null, + "equipment_slot": "7", + "weight": "2" + }, + { + "id": "550", + "name": "Newcomer map", + "examine": "Issued by 2009Scape Council to all new citizens.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "551", + "name": "Newcomer map", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "552", + "name": "Ghostspeak amulet", + "examine": "It lets me talk to ghosts.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "553", + "name": "Ghost's skull", + "examine": "Ooooh spooky!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "If you get rid of the skull you'll have to search for it again.", + "durability": null, + "tradeable": "false" + }, + { + "id": "554", + "name": "Fire rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "17", + "tokkul_price": "6", + "tradeable": "true" + }, + { + "id": "555", + "name": "Water rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "17", + "tokkul_price": "6", + "tradeable": "true" + }, + { + "id": "556", + "name": "Air rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "17", + "tokkul_price": "6", + "tradeable": "true" + }, + { + "id": "557", + "name": "Earth rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "17", + "tokkul_price": "6", + "tradeable": "true" + }, + { + "id": "558", + "name": "Mind rune", + "examine": "Used for basic missile spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "17", + "tokkul_price": "4", + "tradeable": "true" + }, + { + "id": "559", + "name": "Body rune", + "examine": "Used for Curse spells", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "16", + "tokkul_price": "4", + "tradeable": "true" + }, + { + "id": "560", + "name": "Death rune", + "examine": "Used for medium missile spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "310", + "tokkul_price": "270", + "tradeable": "true" + }, + { + "id": "561", + "name": "Nature rune", + "examine": "Used for alchemy spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "372", + "tradeable": "true" + }, + { + "id": "562", + "name": "Chaos rune", + "examine": "Used for small missile spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "140", + "tokkul_price": "135", + "tradeable": "true" + }, + { + "id": "563", + "name": "Law rune", + "examine": "Used for teleport spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "378", + "tradeable": "true" + }, + { + "id": "564", + "name": "Cosmic rune", + "examine": "Used for enchant spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "232", + "tradeable": "true" + }, + { + "id": "565", + "name": "Blood rune", + "examine": "Used for large missile spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "550", + "tradeable": "true" + }, + { + "id": "566", + "name": "Soul rune", + "examine": "Used for high level curse spells.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "400", + "tradeable": "true" + }, + { + "id": "567", + "name": "Unpowered orb", + "examine": "I'd prefer it if it was powered.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "568", + "name": "Unpowered orb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "569", + "name": "Fire orb", + "examine": "A magic glowing orb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "570", + "name": "Fire orb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "571", + "name": "Water orb", + "examine": "A magic glowing orb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "572", + "name": "Water orb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "573", + "name": "Air orb", + "examine": "A magic glowing orb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "574", + "name": "Air orb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "575", + "name": "Earth orb", + "examine": "A magic glowing orb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "576", + "name": "Earth orb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "577", + "name": "Wizard robe", + "examine": "I can do magic better in this.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "4", + "tradeable": "true", + "weight": "1" + }, + { + "id": "578", + "name": "Wizard robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "579", + "name": "Wizard hat", + "examine": "A silly pointed hat.", "archery_ticket_price": "0", - "hat": "true", - "id": "740", "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "examine": "It looks like it's been snapped off of something.", "durability": null, - "name": "Chunk of crystal", - "archery_ticket_price": "0", - "id": "741" - }, - { - "examine": "It looks like it's been snapped off of something.", - "durability": null, - "name": "Hunk of crystal", - "archery_ticket_price": "0", - "id": "742" - }, - { - "examine": "It looks like it's been snapped off of something.", - "durability": null, - "name": "Lump of crystal", - "archery_ticket_price": "0", - "id": "743" - }, - { - "examine": "A heart shaped crystal.", - "durability": null, - "name": "Heart crystal", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "744" - }, - { - "examine": "A heart shaped crystal.", - "durability": null, - "name": "Heart crystal", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "745" - }, - { - "attack_anims": "400,400,400,400", - "examine": "A black obsidian dagger, it has a strange aura about it.", - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Dark dagger", - "archery_ticket_price": "0", - "id": "746", - "weapon_interface": "5", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,0,0,0,0", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3" - }, - { - "examine": "A black obsidian dagger, it has a strange aura about it - it seems to be glowing.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,400,400", - "attack_audios": "2517,2517,2500,2517", - "name": "Glowing dagger", - "archery_ticket_price": "0", - "id": "747", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,0,0,0,0" - }, - { - "examine": "A powerful spell for good.", - "durability": null, - "name": "Holy force", - "archery_ticket_price": "0", - "id": "748" - }, - { - "examine": "A well carved totem pole made from the trunk of a Yommi tree.", - "durability": null, - "name": "Yommi totem", - "weight": "3", - "archery_ticket_price": "0", - "id": "749" - }, - { - "examine": "A gilded totem pole from the Kharazi tribe.", - "durability": null, - "name": "Gilded totem", - "archery_ticket_price": "0", - "id": "750" - }, - { - "examine": "A common gnomeball, obtained by playing gnomeball.", - "durability": null, - "name": "Gnomeball", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "751", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Gnomeball", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "752" - }, - { + "equipment_slot": "0", "ge_buy_limit": "100", - "examine": "Poisonous berries.", - "grand_exchange_price": "42", - "durability": null, - "name": "Cadava berries", + "hat": "true", + "shop_price": "2", "tradeable": "true", - "archery_ticket_price": "0", - "id": "753" + "weight": "0.45" }, { + "id": "580", + "name": "Wizard hat", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "42", - "durability": null, - "name": "Cadava berries", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "754" + "shop_price": "2", + "tradeable": "true" }, { + "id": "581", + "name": "Black robe", + "examine": "I can do magic better in this.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "5", + "tradeable": "true", + "weight": "1" + }, + { + "id": "582", + "name": "Black robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "583", + "name": "Bailing bucket", + "examine": "Empty: It's a bailing bucket. Full: It's a bailing bucket full of salty water.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "10", + "tradeable": "true", + "weight": "1" + }, + { + "id": "584", + "name": "Bailing bucket", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "585", + "name": "Bailing bucket", + "examine": "Empty: It's a bailing bucket. Full: It's a bailing bucket full of salty water.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "10", + "tradeable": "true", + "weight": "1" + }, + { + "id": "586", + "name": "Bailing bucket", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "587", + "name": "Orb of protection", + "examine": "A strange glowing green orb.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "588", + "name": "Orbs of protection", + "examine": "Two strange glowing green orbs.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "589", + "name": "Gnome amulet", + "examine": "It's an amulet of protection given to me by the Gnomes.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,13,13,13,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "2" + }, + { + "id": "590", + "name": "Tinderbox", + "examine": "Useful for lighting a fire.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", "shop_price": "1", - "examine": "This potion will most certainly almost kill you.", - "durability": null, - "name": "Cadava potion", - "archery_ticket_price": "0", - "id": "756" - }, - { - "examine": "Phoenix Gang weapon store key.", - "durability": null, - "name": "Weapon store key", "tradeable": "true", - "archery_ticket_price": "0", - "id": "759" + "weight": "0.05" }, { + "id": "591", + "name": "Tinderbox", + "archery_ticket_price": "0", "durability": null, - "name": "Weapon store key", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "592", + "name": "Ashes", + "examine": "A heap of ashes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "760" + "weight": "0.056" }, { - "destroy_message": "You'll have to kill Jonny the beard in order to get another one.", - "examine": "An intelligence report.", + "id": "593", + "name": "Ashes", + "archery_ticket_price": "0", "durability": null, - "name": "Intel report", - "destroy": "true", - "archery_ticket_price": "0", - "id": "761" + "ge_buy_limit": "10000", + "tradeable": "true" }, { + "id": "594", + "name": "Lit torch", + "examine": "A lit home-made torch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "596", + "name": "Unlit torch", + "examine": "An unlit home-made torch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "597", + "name": "Unlit torch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "598", + "name": "Bronze fire arrows", + "examine": "unlit: Arrows with bronze heads and oil-soaked cloth. lit: An easy to make, bronze-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "600", + "name": "Astronomy book", + "examine": "A book on the history of astronomy in 2009Scape.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "601", + "name": "Goblin kitchen key", + "examine": "A small key for a large door.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to find another, down in the dungeon.", + "durability": null, + "tradeable": "false" + }, + { + "id": "602", + "name": "Lens mould", + "examine": "An unusual clay mould in the shape of a disc.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to get another down in the dungeon.", + "durability": null, + "tradeable": "false" + }, + { + "id": "603", + "name": "Observatory lens", + "examine": "A perfectly circular disc of glass.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Half of the Shield of Arrav.", "durability": null, - "name": "Broken shield", - "destroy": "true", - "weight": "2.7", - "archery_ticket_price": "0", - "id": "763" + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Half of the Shield of Arrav.", - "durability": null, - "name": "Broken shield", - "destroy": "true", - "weight": "2.7", + "id": "604", + "name": "Bone shard", + "examine": "A slender bone shard given to you by Zadimus.", "archery_ticket_price": "0", - "id": "765" + "durability": null, + "shop_price": "160" }, { - "turn90cw_anim": "821", - "examine": "Second-rate crossbow, former property of the Phoenix Gang.", - "walk_anim": "4226", + "id": "605", + "name": "Bone key", + "examine": "A key fashioned from a shard of bone. (Shilo Village)", + "archery_ticket_price": "0", "durability": null, - "weight": "3", - "turn90ccw_anim": "822", - "attack_speed": "6", - "weapon_interface": "17", - "turn180_anim": "4227", - "render_anim": "175", - "defence_anim": "424", + "shop_price": "100" + }, + { + "id": "606", + "name": "Stone-plaque", + "examine": "A stone plaque with carved letters in it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "607", + "name": "Tattered scroll", + "examine": "An ancient tattered scroll.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "608", + "name": "Crumpled scroll", + "examine": "An ancient crumpled scroll.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "100" + }, + { + "id": "609", + "name": "Rashiliyia corpse", + "examine": "The remains of the Zombie Queen.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "610", + "name": "Zadimus corpse", + "examine": "The remains of Zadimus.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "611", + "name": "Locating crystal", + "examine": "A magical crystal sphere.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "612", + "name": "Locating crystal", + "examine": "A magical crystal sphere.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "613", + "name": "Locating crystal", + "examine": "A magical crystal sphere.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "614", + "name": "Locating crystal", + "examine": "A magical crystal sphere.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "615", + "name": "Locating crystal", + "examine": "A magical crystal sphere.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "616", + "name": "Beads of the dead", + "examine": "A curious looking neck ornament.", + "archery_ticket_price": "0", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,1,0,0", + "destroy": "true", + "destroy_message": "You made the beads of the dead during the Shilo Village quest. You can get another from Yanni Salika in Shilo Village for 1200 gold.", + "durability": null, + "equipment_slot": "2", + "shop_price": "1200", + "tradeable": "false" + }, + { + "id": "617", + "name": "Coins", + "examine": "Lovely money!", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "618", + "name": "Bone beads", + "examine": "Beads carved out of a bone.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "619", + "name": "Paramaya ticket", + "examine": "Allows you to rest in the luxurious Paramayer Inn.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "35" + }, + { + "id": "620", + "name": "Paramaya ticket", + "examine": "Allows you to rest in the luxurious Paramayer Inn.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "35" + }, + { + "id": "621", + "name": "Ship ticket", + "examine": "Sold in Shilo Village for passage on the 'Lady of the Waves'.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "623", + "name": "Sword pommel", + "examine": "An ivory sword pommel.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "624", + "name": "Bervirius notes", + "examine": "Notes taken from the tomb of Bervirius.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "625", + "name": "Wampum belt", + "examine": "A decorated belt used to trade information between distant villages.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "626", + "name": "Boots", + "examine": "They're soft, silky and pink.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "627", + "name": "Boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "628", + "name": "Boots", + "examine": "They're soft, silky and green.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "629", + "name": "Boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "630", + "name": "Boots", + "examine": "They're soft, silky and blue.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "631", + "name": "Boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "632", + "name": "Boots", + "examine": "They're soft, silky and cream.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "633", + "name": "Boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "634", + "name": "Boots", + "examine": "They're soft, silky and turquoise.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "635", + "name": "Boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "636", + "name": "Robe top", + "examine": "The ultimate in gnome design, now in pink.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "637", + "name": "Robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "638", + "name": "Robe top", + "examine": "The ultimate in gnome design, now in green.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "639", + "name": "Robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "640", + "name": "Robe top", + "examine": "The ultimate in gnome design, now in blue.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "641", + "name": "Robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "642", + "name": "Robe top", + "examine": "The ultimate in gnome design, now in cream.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "643", + "name": "Robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "644", + "name": "Robe top", + "examine": "The ultimate in gnome design, now in turquoise.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "645", + "name": "Robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "646", + "name": "Robe bottoms", + "examine": "Made by tree gnomes with a thing for pink.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "647", + "name": "Robe bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "648", + "name": "Robe bottoms", + "examine": "Made by tree gnomes with a thing for green.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "649", + "name": "Robe bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "650", + "name": "Robe bottoms", + "examine": "Made by tree gnomes with a thing for blue.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "651", + "name": "Robe bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "652", + "name": "Robe bottoms", + "examine": "Made by tree gnomes with a thing for cream.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "653", + "name": "Robe bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "654", + "name": "Robe bottoms", + "examine": "Made by tree gnomes with a thing for turquoise.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "180", + "tradeable": "true", + "weight": "1" + }, + { + "id": "655", + "name": "Robe bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "656", + "name": "Hat", + "examine": "A silly, pink pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "657", + "name": "Hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "658", + "name": "Hat", + "examine": "A silly, green pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "659", + "name": "Hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "660", + "name": "Hat", + "examine": "A silly, blue pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "661", + "name": "Hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "662", + "name": "Hat", + "examine": "A silly, cream pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "663", + "name": "Hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "664", + "name": "Hat", + "examine": "A silly, turquoise pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "665", + "name": "Hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "666", + "name": "Portrait", + "examine": "Picture of a posing Paladin.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1.3" + }, + { + "id": "667", + "name": "Blurite sword", + "examine": "A Faladian Knight's sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "9,14,-2,0,0,0,3,2,0,0,0,10,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "stand_anim": "4591", - "attack_audios": "2700,0,0,0", - "name": "Phoenix crossbow", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "767", + "render_anim": "292", + "run_anim": "824", + "stand_anim": "809", "stand_turn_anim": "823", - "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1" }, { - "durability": null, - "name": "Phoenix crossbow", - "tradeable": "true", + "id": "668", + "name": "Blurite ore", + "examine": "Definitely blue.", "archery_ticket_price": "0", - "id": "768" + "durability": null, + "weight": "2.2" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Entrance certificate to the Imperial Guard.", - "durability": null, - "name": "Certificate", + "id": "669", + "name": "Specimen jar", + "examine": "A receptacle for specimens!", "archery_ticket_price": "0", - "id": "769" + "durability": null }, { - "destroy_message": "You can get another branch if you chop the dramen tree underneath Entrana again.", - "examine": "A limb of the fabled Dramen tree.", - "durability": null, - "name": "Dramen branch", - "tradeable": "false", + "id": "670", + "name": "Specimen brush", + "examine": "A small brush used to clean rock samples.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "671", + "name": "Animal skull", + "examine": "A carefully-kept-safe skull sample.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "771" + "durability": null, + "tradeable": "false" }, { - "turn90cw_anim": "1207", - "examine": "Crafted from a Dramen tree branch.", - "walk_anim": "1205", + "id": "672", + "name": "Special cup", + "examine": "A special cup.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "673", + "name": "Teddy", + "examine": "A lucky mascot.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "674", + "name": "Cracked sample", + "examine": "A roughly shaped piece of rock.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "675", + "name": "Rock pick", + "examine": "A small pick for digging.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "676", + "name": "Trowel", + "examine": "Used for digging!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "677", + "name": "Panning tray", + "examine": "An empty tray for panning.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "678", + "name": "Panning tray", + "examine": "This tray contains gold nuggets.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "679", + "name": "Panning tray", + "examine": "This tray contains mud.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "680", + "name": "Nuggets", + "examine": "Pure, lovely gold!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "681", + "name": "Ancient talisman", + "examine": "An unusual symbol as yet unidentified by the archaeological expert.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.2" + }, + { + "id": "682", + "name": "Unstamped letter", + "examine": "A letter waiting to be stamped.", + "archery_ticket_price": "0", + "destroy": "true", "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Dramen staff", "tradeable": "false", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "772", - "stand_turn_anim": "1209", - "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + "weight": "1" }, { - "examine": "A perfect ruby ring.", - "durability": null, - "name": "'perfect' ring", + "id": "683", + "name": "Sealed letter", + "examine": "A sealed letter of recommendation.", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "684", + "name": "Belt buckle", + "examine": "Used to hold up trousers!", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "685", + "name": "Old boot", + "examine": "Phew!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "686", + "name": "Rusty sword", + "examine": "A decent-enough weapon gone rusty.", + "archery_ticket_price": "0", + "durability": null, + "weight": "2" + }, + { + "id": "687", + "name": "Broken arrow", + "examine": "This must have been shot at high speed.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "688", + "name": "Buttons", + "examine": "Not Dick Whittington's helper at all!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "689", + "name": "Broken staff", + "examine": "I pity the poor person beaten with this!", + "archery_ticket_price": "0", + "attack_audios": "2555,0,0,0", + "durability": null, + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "690", + "name": "Picture", + "examine": "Smashed glass.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "691", + "name": "Level 1 certificate", + "examine": "The owner has passed Earth Sciences Level 1 exam.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "692", + "name": "Level 2 certificate", + "examine": "The owner has passed Earth Sciences Level 2 exam.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "693", + "name": "Level 3 certificate", + "examine": "The owner has passed Earth Sciences Level 3 exam.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "694", + "name": "Ceramic remains", + "examine": "Smashing!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "695", + "name": "Old tooth", + "examine": "Now, if I could just find a tooth fairy to sell this to...", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "696", + "name": "Invitation letter", + "examine": "A letter inviting me to use the private digging shafts.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "697", + "name": "Damaged armour", + "examine": "It would be hard to repair this!", + "archery_ticket_price": "0", + "durability": null, + "weight": "7.75" + }, + { + "id": "698", + "name": "Broken armour", + "examine": "Armour left over from a great fight.", + "archery_ticket_price": "0", + "durability": null, + "weight": "8" + }, + { + "id": "699", + "name": "Stone tablet", + "examine": "An old stone slab with writing on it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "700", + "name": "Chemical powder", + "examine": "An acrid chemical.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "701", + "name": "Ammonium nitrate", + "examine": "An acrid chemical.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "702", + "name": "Unidentified liquid", + "examine": "A strong chemical.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "703", + "name": "Nitroglycerin", + "examine": "A strong chemical.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "weight": "1" + }, + { + "id": "704", + "name": "Ground charcoal", + "examine": "Charcoal - crushed to small pieces!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "705", + "name": "Mixed chemicals", + "examine": "A mixture of strong chemicals.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "weight": "0.03" + }, + { + "id": "706", + "name": "Mixed chemicals", + "examine": "A mixture of strong chemicals.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "weight": "0.035" + }, + { + "id": "707", + "name": "Chemical compound", + "examine": "A mixture of strong chemicals.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.035" + }, + { + "id": "708", + "name": "Arcenia root", + "examine": "The root of an arcenia plant.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "709", + "name": "Chest key", + "examine": "This key opens a chest in the Carnillean household." + }, + { + "id": "710", + "name": "Vase", + "examine": "An unusually shaped vase. You can see something glinting inside.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "711", + "name": "Book on chemicals", + "examine": "It's about chemicals, judging from its cover.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "712", + "name": "Cup of tea", + "examine": "A nice cup of tea.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "10", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "714", + "name": "Radimus notes", + "examine": "Notes given to you by Radimus Erkle, it includes a partially completed map.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "715", + "name": "Radimus notes", + "examine": "Notes given to you by Radimus Erkle, it includes a partially completed map.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "716", + "name": "Bull roarer", + "examine": "It makes a loud but interesting sound when swung in the air.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "717", + "name": "Scrawled note", + "examine": "A scrawled note with spidery writing on it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "718", + "name": "A scribbled note", + "examine": "A scrawled note with spidery writing on it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "719", + "name": "Scrumpled note", + "examine": "A scrawled note with spidery writing on it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "720", + "name": "Sketch", + "examine": "A rough sketch of a bowl shaped vessel given to you by Gujuo.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "721", + "name": "Gold bowl", + "examine": "A specially made bowl constructed out of pure gold.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "722", + "name": "Blessed gold bowl", + "examine": "A specially made bowl constructed out of pure gold and blessed.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.8" + }, + { + "id": "723", + "name": "Golden bowl", + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "724", + "name": "Golden bowl", + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "725", + "name": "Golden bowl", + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "726", + "name": "Golden bowl", + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "727", + "name": "Hollow reed", + "examine": "One of nature's pipes.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.012" + }, + { + "id": "728", + "name": "Hollow reed", + "examine": "One of nature's pipes.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.012" + }, + { + "id": "729", + "name": "Shamans tome", + "examine": "It looks like the Shamans personal notes...", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "730", + "name": "Binding book", + "examine": "An ancient tome on Demonology.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "731", + "name": "Enchanted vial", + "examine": "An enchanted empty glass vial.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "shop_price": "160", + "tradeable": "false" + }, + { + "id": "732", + "name": "Holy water", + "examine": "A vial of holy water, good against certain demons.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,24", + "durability": null, + "equipment_slot": "3", + "weapon_interface": "18" + }, + { + "id": "733", + "name": "Smashed glass", + "examine": "Fragments of a broken container.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "735", + "name": "Yommi tree seeds", + "examine": "These need to be germinated before they can be used. / These are germinated and ready to be planted in fertile soil.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "736", + "name": "Yommi tree seeds", + "examine": "These need to be germinated before they can be used. / These are germinated and ready to be planted in fertile soil.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "737", + "name": "Snakeweed mixture", + "examine": "A Snakeweed mixture, needs another ingredient.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "738", + "name": "Ardrigal mixture", + "examine": "It's a mixture of ardrigal and water. Needs another ingredient.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "739", + "name": "Bravery potion", + "examine": "A bravery potion for which Gujuo gave you the details, let's hope it works.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "740", + "name": "Blue hat", + "examine": "A silly, blue pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "hat": "true", + "shop_price": "160", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "741", + "name": "Chunk of crystal", + "examine": "It looks like it's been snapped off of something.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "742", + "name": "Hunk of crystal", + "examine": "It looks like it's been snapped off of something.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "743", + "name": "Lump of crystal", + "examine": "It looks like it's been snapped off of something.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "744", + "name": "Heart crystal", + "examine": "A heart shaped crystal.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "745", + "name": "Heart crystal", + "examine": "A heart shaped crystal.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "746", + "name": "Dark dagger", + "examine": "A black obsidian dagger, it has a strange aura about it.", + "archery_ticket_price": "0", + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,0,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "747", + "name": "Glowing dagger", + "examine": "A black obsidian dagger, it has a strange aura about it - it seems to be glowing.", + "archery_ticket_price": "0", + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "6", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,0,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "748", + "name": "Holy force", + "examine": "A powerful spell for good.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "749", + "name": "Yommi totem", + "examine": "A well carved totem pole made from the trunk of a Yommi tree.", + "archery_ticket_price": "0", + "durability": null, + "weight": "3" + }, + { + "id": "750", + "name": "Gilded totem", + "examine": "A gilded totem pole from the Kharazi tribe.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "751", + "name": "Gnomeball", + "examine": "A common gnomeball, obtained by playing gnomeball.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "752", + "name": "Gnomeball", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "753", + "name": "Cadava berries", + "examine": "Poisonous berries.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "754", + "name": "Cadava berries", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "756", + "name": "Cadava potion", + "examine": "This potion will most certainly almost kill you.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "759", + "name": "Weapon store key", + "examine": "Phoenix Gang weapon store key.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "760", + "name": "Weapon store key", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "761", + "name": "Intel report", + "examine": "An intelligence report.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to kill Jonny the beard in order to get another one.", + "durability": null + }, + { + "id": "763", + "name": "Broken shield", + "examine": "Half of the Shield of Arrav.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "2.7" + }, + { + "id": "765", + "name": "Broken shield", + "examine": "Half of the Shield of Arrav.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "2.7" + }, + { + "id": "767", + "name": "Phoenix crossbow", + "examine": "Second-rate crossbow, former property of the Phoenix Gang.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "175", + "run_anim": "4228", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "3" + }, + { + "id": "768", + "name": "Phoenix crossbow", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "769", + "name": "Certificate", + "examine": "Entrance certificate to the Imperial Guard.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "771", + "name": "Dramen branch", + "examine": "A limb of the fabled Dramen tree.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another branch if you chop the dramen tree underneath Entrana again.", + "durability": null, + "tradeable": "false", + "weight": "2.2" + }, + { + "id": "772", + "name": "Dramen staff", + "examine": "Crafted from a Dramen tree branch.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "4", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "1.8" + }, + { "id": "773", + "name": "'perfect' ring", + "examine": "A perfect ruby ring.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "12" }, { - "examine": "A perfect ruby necklace.", - "durability": null, - "name": "'perfect' necklace", - "archery_ticket_price": "0", "id": "774", + "name": "'perfect' necklace", + "examine": "A perfect ruby necklace.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "destroy_message": "You can obtain another set of Cooking gauntlets from Dimintheis.", - "examine": "These gauntlets empower with a greater ability to cook fish.", - "durability": null, - "name": "Cooking gauntlets", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "775", + "name": "Cooking gauntlets", + "examine": "These gauntlets empower with a greater ability to cook fish.", + "archery_ticket_price": "0", "bonuses": "2,2,2,0,0,8,9,7,0,0,3,2,0,0,0", - "equipment_slot": "9" + "destroy": "true", + "destroy_message": "You can obtain another set of Cooking gauntlets from Dimintheis.", + "durability": null, + "equipment_slot": "9", + "tradeable": "false", + "weight": "0.2" }, { - "destroy_message": "You can obtain another set of Goldsmith gauntlets from Dimintheis.", - "examine": "These gauntlets empower the bearer whilst making gold.", - "durability": null, - "name": "Goldsmith gauntlets", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "776", + "name": "Goldsmith gauntlets", + "examine": "These gauntlets empower the bearer whilst making gold.", + "archery_ticket_price": "0", "bonuses": "2,2,2,0,0,8,9,7,0,0,3,2,0,0,0", - "equipment_slot": "9" + "destroy": "true", + "destroy_message": "You can obtain another set of Goldsmith gauntlets from Dimintheis.", + "durability": null, + "equipment_slot": "9", + "tradeable": "false" }, { - "destroy_message": "You can obtain another set of Chaos gauntlets from Dimintheis.", - "examine": "These gauntlets empower spell casters.", - "durability": null, - "name": "Chaos gauntlets", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "777", + "name": "Chaos gauntlets", + "examine": "These gauntlets empower spell casters.", + "archery_ticket_price": "0", "bonuses": "2,2,2,0,0,8,9,7,0,0,3,2,0,0,0", - "equipment_slot": "9" + "destroy": "true", + "destroy_message": "You can obtain another set of Chaos gauntlets from Dimintheis.", + "durability": null, + "equipment_slot": "9", + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "My reward for assisting the Fitzharmon family.", - "durability": null, - "name": "Family gauntlets", - "weight": "1", - "archery_ticket_price": "0", "id": "778", + "name": "Family gauntlets", + "examine": "My reward for assisting the Fitzharmon family.", + "archery_ticket_price": "0", "bonuses": "2,2,2,0,0,8,9,7,0,0,0,2,0,0,0", - "equipment_slot": "9" - }, - { - "examine": "A fragment of the Fitzharmon family crest.", - "durability": null, - "name": "Crest part", - "archery_ticket_price": "0", - "id": "779" - }, - { - "examine": "A fragment of the Fitzharmon family crest.", - "durability": null, - "name": "Crest part", - "archery_ticket_price": "0", - "id": "780" - }, - { - "examine": "A fragment of the Fitzharmon family crest.", - "durability": null, - "name": "Crest part", - "archery_ticket_price": "0", - "id": "781" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A sample of the bark from the Grand Tree.", "durability": null, + "equipment_slot": "9", + "weight": "1" + }, + { + "id": "779", + "name": "Crest part", + "examine": "A fragment of the Fitzharmon family crest.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "780", + "name": "Crest part", + "examine": "A fragment of the Fitzharmon family crest.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "781", + "name": "Crest part", + "examine": "A fragment of the Fitzharmon family crest.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "783", "name": "Bark sample", + "examine": "A sample of the bark from the Grand Tree.", "archery_ticket_price": "0", - "id": "783" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A book to translate the ancient gnome language into English.", - "durability": null, + "id": "784", "name": "Translation book", + "examine": "A book to translate the ancient gnome language into English.", "archery_ticket_price": "0", - "id": "784" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Perhaps I should read it and see what Glough is up to!", - "durability": null, + "id": "785", "name": "Glough's journal", + "examine": "Perhaps I should read it and see what Glough is up to!", "archery_ticket_price": "0", - "id": "785" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Hazelmere wrote something down on this scroll.", - "durability": null, + "id": "786", "name": "Hazelmere's scroll", + "examine": "Hazelmere wrote something down on this scroll.", "archery_ticket_price": "0", - "id": "786" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "An order from the Karamja shipyard.", - "durability": null, + "id": "787", "name": "Lumber order", + "examine": "An order from the Karamja shipyard.", "archery_ticket_price": "0", - "id": "787" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "The key to Glough's chest.", - "durability": null, + "id": "788", "name": "Glough's key", - "weight": "1", + "examine": "The key to Glough's chest.", "archery_ticket_price": "0", - "id": "788" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "1" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Twigs bound together in the shape of a (Z/U/T/O).", - "durability": null, + "id": "789", "name": "Twigs", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "789" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", "examine": "Twigs bound together in the shape of a (Z/U/T/O).", - "durability": null, - "name": "Twigs", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "790" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", + "id": "790", + "name": "Twigs", "examine": "Twigs bound together in the shape of a (Z/U/T/O).", - "durability": null, - "name": "Twigs", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "791" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", + "id": "791", + "name": "Twigs", "examine": "Twigs bound together in the shape of a (Z/U/T/O).", - "durability": null, - "name": "Twigs", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "792" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { + "id": "792", + "name": "Twigs", + "examine": "Twigs bound together in the shape of a (Z/U/T/O).", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "An ancient rock with strange magical properties.", "durability": null, + "tradeable": "false" + }, + { + "id": "793", "name": "Daconia rock", - "tradeable": "false", - "destroy": "true", - "weight": "3", + "examine": "An ancient rock with strange magical properties.", "archery_ticket_price": "0", - "id": "793" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "These are plans for an invasion!", - "durability": null, + "id": "794", "name": "Invasion plans", - "tradeable": "false", + "examine": "These are plans for an invasion!", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "794" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A model of a Karamja warship", "durability": null, + "tradeable": "false" + }, + { + "id": "795", "name": "War ship", - "weight": "0.01", + "examine": "A model of a Karamja warship", "archery_ticket_price": "0", - "id": "795" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "0.01" + }, + { + "id": "799", + "name": "C. Ele Minor Drop Table", + "examine": "Item container for C. Ele Minor Drop Table. You should not be able to obtain this item." }, { - "shop_price": "4", - "ge_buy_limit": "1000", - "examine": "A finely balanced throwing axe.", - "durability": null, - "attack_speed": "5", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "3", - "name": "Bronze thrownaxe", - "tradeable": "true", - "archery_ticket_price": "0", "id": "800", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,5" - }, - { - "shop_price": "13", - "ge_buy_limit": "1000", + "name": "Bronze thrownaxe", "examine": "A finely balanced throwing axe.", - "durability": null, - "attack_speed": "5", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "14", - "name": "Iron thrownaxe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "801", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,7" + "attack_anims": "806,806,806,806", + "attack_audios": "2706,2706,2706", + "attack_speed": "5", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,5", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "4", + "tradeable": "true", + "weapon_interface": "18" }, { + "id": "801", + "name": "Iron thrownaxe", + "examine": "A finely balanced throwing axe.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2706,2706,2706", + "attack_speed": "5", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "13", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "802", + "name": "Steel thrownaxe", + "examine": "A finely balanced throwing axe.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2706,2706,2706", + "attack_speed": "5", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,11", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,5}", "shop_price": "38", - "ge_buy_limit": "1000", - "examine": "A finely balanced throwing axe.", - "durability": null, - "attack_speed": "5", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "60", - "name": "Steel thrownaxe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "802", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,11" + "weapon_interface": "18" }, { + "id": "803", + "name": "Mithril thrownaxe", + "examine": "A finely balanced throwing axe.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2706,2706,2706", + "attack_speed": "5", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,16", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,20}", "shop_price": "105", - "ge_buy_limit": "1000", - "examine": "A finely balanced throwing axe.", - "durability": null, - "attack_speed": "5", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "135", - "name": "Mithril thrownaxe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "803", - "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,16" + "weapon_interface": "18" }, { + "id": "804", + "name": "Adamant thrownaxe", + "examine": "A finely balanced throwing axe.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2706,2706,2706", + "attack_speed": "5", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,23", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,30}", "shop_price": "262", - "ge_buy_limit": "1000", - "examine": "A finely balanced throwing axe.", - "durability": null, - "attack_speed": "5", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "138", - "name": "Adamant thrownaxe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "804", - "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,23" + "weapon_interface": "18" }, { + "id": "805", + "name": "Rune thrownaxe", + "examine": "A finely balanced throwing axe.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2706,2706,2706", + "attack_speed": "5", + "bonuses": "0,0,0,0,26,0,0,0,0,0,0,0,0,0,36", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "has_special": "true", "requirements": "{4,40}", "shop_price": "698", - "ge_buy_limit": "1000", - "examine": "A finely balanced throwing axe.", - "has_special": "true", - "durability": null, - "attack_speed": "5", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "243", - "name": "Rune thrownaxe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "805", - "bonuses": "0,0,0,0,26,0,0,0,0,0,0,0,0,0,36" + "weapon_interface": "18" }, { - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a bronze tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "53", - "attack_audios": "2547,0,0,0", - "name": "Bronze dart", - "tradeable": "true", - "archery_ticket_price": "0", "id": "806", - "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" - }, - { - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with an iron tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "59", - "attack_audios": "2547,0,0,0", - "name": "Iron dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "807", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { - "requirements": "{4,5}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a steel tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "50", - "attack_audios": "2547,0,0,0", - "name": "Steel dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "808", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a mithril tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "68", - "attack_audios": "2547,0,0,0", - "name": "Mithril dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "809", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with an adamantite tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "96", - "attack_audios": "2547,0,0,0", - "name": "Adamant dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "810", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a rune tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "122", - "attack_audios": "2547,0,0,0", - "name": "Rune dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "811", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "ge_buy_limit": "1000", + "name": "Bronze dart", "examine": "A deadly throwing dart with a bronze tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "66", - "attack_audios": "2547,0,0,0", - "name": "Bronze dart(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "812", - "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" }, { - "ge_buy_limit": "1000", + "id": "807", + "name": "Iron dart", "examine": "A deadly throwing dart with an iron tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "66", - "attack_audios": "2547,0,0,0", - "name": "Iron dart(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "813", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" }, { - "requirements": "{4,5}", - "ge_buy_limit": "1000", + "id": "808", + "name": "Steel dart", "examine": "A deadly throwing dart with a steel tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "75", - "attack_audios": "2547,0,0,0", - "name": "Steel dart(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "814", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "tradeable": "true", + "weapon_interface": "18" }, { - "requirements": "{4,20}", - "ge_buy_limit": "1000", + "id": "809", + "name": "Mithril dart", "examine": "A deadly throwing dart with a mithril tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "65", - "attack_audios": "2547,0,0,0", - "name": "Mithril dart(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "815", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" }, { - "requirements": "{4,30}", - "ge_buy_limit": "1000", + "id": "810", + "name": "Adamant dart", "examine": "A deadly throwing dart with an adamantite tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "75", - "attack_audios": "2547,0,0,0", - "name": "Adamant dart(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "816", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,40}", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a rune tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "110", - "attack_audios": "2547,0,0,0", - "name": "Rune dart(p)", + "requirements": "{4,30}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "817", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + "weapon_interface": "18" }, { + "id": "811", + "name": "Rune dart", + "examine": "A deadly throwing dart with a rune tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "812", + "name": "Bronze dart(p)", + "examine": "A deadly throwing dart with a bronze tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "813", + "name": "Iron dart(p)", + "examine": "A deadly throwing dart with an iron tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "814", + "name": "Steel dart(p)", + "examine": "A deadly throwing dart with a steel tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "815", + "name": "Mithril dart(p)", + "examine": "A deadly throwing dart with a mithril tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "816", + "name": "Adamant dart(p)", + "examine": "A deadly throwing dart with an adamantite tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "817", + "name": "Rune dart(p)", + "examine": "A deadly throwing dart with a rune tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "818", "name": "Poisoned dart(p)", "archery_ticket_price": "0", - "id": "818", + "attack_audios": "2547,0,0,0", + "durability": null, + "equip_audio": "2244", "equipment_slot": "3" }, { - "ge_buy_limit": "5000", - "examine": "A deadly looking dart tip made of bronze - needs feathers for flight.", - "grand_exchange_price": "24", - "attack_audios": "2547,0,0,0", - "durability": null, + "id": "819", "name": "Bronze dart tip", - "tradeable": "true", + "examine": "A deadly looking dart tip made of bronze - needs feathers for flight.", "archery_ticket_price": "0", - "id": "819" - }, - { - "ge_buy_limit": "5000", - "examine": "A deadly looking dart tip made of iron - needs feathers for flight.", - "grand_exchange_price": "19", "attack_audios": "2547,0,0,0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "820", "name": "Iron dart tip", - "tradeable": "true", + "examine": "A deadly looking dart tip made of iron - needs feathers for flight.", "archery_ticket_price": "0", - "id": "820" - }, - { - "ge_buy_limit": "5000", - "examine": "A deadly looking dart tip made of steel - needs feathers for flight.", - "grand_exchange_price": "66", "attack_audios": "2547,0,0,0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "821", "name": "Steel dart tip", - "tradeable": "true", + "examine": "A deadly looking dart tip made of steel - needs feathers for flight.", "archery_ticket_price": "0", - "id": "821" - }, - { - "ge_buy_limit": "5000", - "examine": "A deadly looking dart tip made of mithril - needs feathers for flight.", - "grand_exchange_price": "97", "attack_audios": "2547,0,0,0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "822", "name": "Mithril dart tip", - "tradeable": "true", + "examine": "A deadly looking dart tip made of mithril - needs feathers for flight.", "archery_ticket_price": "0", - "id": "822" - }, - { - "ge_buy_limit": "5000", - "examine": "A deadly looking dart tip made of adamantite - needs feathers for flight.", - "grand_exchange_price": "212", "attack_audios": "2547,0,0,0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "823", "name": "Adamant dart tip", - "tradeable": "true", + "examine": "A deadly looking dart tip made of adamantite - needs feathers for flight.", "archery_ticket_price": "0", - "id": "823" - }, - { - "ge_buy_limit": "5000", - "examine": "A deadly looking dart tip made of runite - needs feathers for flight.", - "grand_exchange_price": "498", "attack_audios": "2547,0,0,0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "824", "name": "Rune dart tip", - "tradeable": "true", + "examine": "A deadly looking dart tip made of runite - needs feathers for flight.", "archery_ticket_price": "0", - "id": "824" + "attack_audios": "2547,0,0,0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "6", - "ge_buy_limit": "1000", - "examine": "A bronze-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "6", - "name": "Bronze javelin", - "tradeable": "true", - "archery_ticket_price": "0", "id": "825", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" - }, - { - "shop_price": "8", - "ge_buy_limit": "1000", - "examine": "An iron-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "2", - "name": "Iron javelin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "826", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,5}", - "shop_price": "37", - "ge_buy_limit": "1000", - "examine": "A steel-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "19", - "name": "Steel javelin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "827", - "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" - }, - { - "requirements": "{4,20}", - "shop_price": "79", - "ge_buy_limit": "1000", - "examine": "A mithril tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "25", - "name": "Mithril javelin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "828", - "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" - }, - { - "requirements": "{4,30}", - "shop_price": "100", - "ge_buy_limit": "1000", - "examine": "An adamant tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "51", - "name": "Adamant javelin", - "tradeable": "true", - "archery_ticket_price": "100", - "id": "829", - "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" - }, - { - "requirements": "{4,40}", - "shop_price": "624", - "ge_buy_limit": "1000", - "examine": "A rune tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "186", - "name": "Rune javelin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "830", - "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" - }, - { - "shop_price": "6", - "ge_buy_limit": "1000", + "name": "Bronze javelin", "examine": "A bronze-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "19", - "name": "Bronze javelin(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "831", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" - }, - { - "shop_price": "8", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", "ge_buy_limit": "1000", - "examine": "An iron-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "19", - "name": "Iron javelin(p)", + "shop_price": "6", "tradeable": "true", - "archery_ticket_price": "0", - "id": "832", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" + "weapon_interface": "18" }, { + "id": "826", + "name": "Iron javelin", + "examine": "An iron-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "8", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "827", + "name": "Steel javelin", + "examine": "A steel-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,5}", "shop_price": "37", - "ge_buy_limit": "1000", - "examine": "A steel-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "34", - "name": "Steel javelin(p)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "833", - "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" + "weapon_interface": "18" }, { + "id": "828", + "name": "Mithril javelin", + "examine": "A mithril tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,20}", "shop_price": "79", - "ge_buy_limit": "1000", - "examine": "A mithril tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "44", - "name": "Mithril javelin(p)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "834", - "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" + "weapon_interface": "18" }, { + "id": "829", + "name": "Adamant javelin", + "examine": "An adamant tipped javelin.", + "archery_ticket_price": "100", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,30}", "shop_price": "100", - "ge_buy_limit": "1000", - "examine": "An adamant tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "88", - "name": "Adamant javelin(p)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "835", - "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" + "weapon_interface": "18" }, { + "id": "830", + "name": "Rune javelin", + "examine": "A rune tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{4,40}", "shop_price": "624", - "ge_buy_limit": "1000", - "examine": "A rune tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "831", + "name": "Bronze javelin(p)", + "examine": "A bronze-tipped javelin.", + "archery_ticket_price": "0", "attack_anims": "806,806,806,806", - "grand_exchange_price": "256", - "name": "Rune javelin(p)", + "attack_speed": "6", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "6", "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "832", + "name": "Iron javelin(p)", + "examine": "An iron-tipped javelin.", "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "8", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "833", + "name": "Steel javelin(p)", + "examine": "A steel-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "shop_price": "37", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "834", + "name": "Mithril javelin(p)", + "examine": "A mithril tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "shop_price": "79", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "835", + "name": "Adamant javelin(p)", + "examine": "An adamant tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "shop_price": "100", + "tradeable": "true", + "weapon_interface": "18" + }, + { "id": "836", - "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" + "name": "Rune javelin(p)", + "examine": "A rune tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,40}", + "shop_price": "624", + "tradeable": "true", + "weapon_interface": "18" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "This fires crossbow bolts.", - "walk_anim": "4226", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "4227", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "276", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", "id": "837", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0", - "shop_price": "70", - "durability": null, - "weight": "8", - "weapon_interface": "17", - "render_anim": "175", - "attack_audios": "2700,0,0,0", - "name": "Crossbow" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "276", - "durability": null, "name": "Crossbow", - "tradeable": "true", + "examine": "This fires crossbow bolts.", "archery_ticket_price": "0", - "id": "838" - }, - { - "ge_buy_limit": "5000", - "turn90cw_anim": "821", - "examine": "A nice sturdy bow.", - "walk_anim": "819", - "turn90ccw_anim": "822", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "820", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0", "defence_anim": "424", + "durability": null, + "equip_audio": "2244", "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "55", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "839", + "ge_buy_limit": "100", + "render_anim": "175", + "run_anim": "4228", + "shop_price": "70", + "stand_anim": "4591", "stand_turn_anim": "823", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", - "shop_price": "80", - "durability": null, - "weight": "1.8", - "weapon_interface": "16", - "render_anim": "1", - "attack_audios": "2700,0,0,0", - "name": "Longbow" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "55", - "durability": null, - "name": "Longbow", "tradeable": "true", - "archery_ticket_price": "0", - "id": "840" - }, - { - "ge_buy_limit": "5000", - "turn90cw_anim": "821", - "examine": "A shortbow made of wood.", - "walk_anim": "819", + "turn180_anim": "4227", "turn90ccw_anim": "822", - "attack_speed": "4", - "two_handed": "true", - "turn180_anim": "820", - "defence_anim": "424", - "equipment_slot": "3", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "8" + }, + { + "id": "838", + "name": "Crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "839", + "name": "Longbow", + "examine": "A nice sturdy bow.", + "archery_ticket_price": "0", "attack_anims": "426,426,426,426", - "grand_exchange_price": "79", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "841", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", - "shop_price": "50", - "durability": null, - "weight": "1.33", - "weapon_interface": "16", - "render_anim": "1", "attack_audios": "2700,0,0,0", - "name": "Shortbow" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "79", + "attack_speed": "6", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", "durability": null, - "name": "Shortbow", + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "render_anim": "1", + "run_anim": "824", + "shop_price": "80", + "stand_anim": "808", + "stand_turn_anim": "823", "tradeable": "true", - "archery_ticket_price": "0", - "id": "842" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "two_handed": "true", + "walk_anim": "819", + "weapon_interface": "16", + "weight": "1.8" }, { + "id": "840", + "name": "Longbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "841", + "name": "Shortbow", + "examine": "A shortbow made of wood.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "render_anim": "1", + "run_anim": "824", + "shop_price": "50", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "two_handed": "true", + "walk_anim": "819", + "weapon_interface": "16", + "weight": "1.33" + }, + { + "id": "842", + "name": "Shortbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "843", + "name": "Oak shortbow", + "examine": "A shortbow made out of oak, still effective.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "render_anim": "2588", "requirements": "{4,5}", "shop_price": "164", - "ge_buy_limit": "5000", - "examine": "A shortbow made out of oak, still effective.", - "durability": null, - "weight": "1.8", - "attack_speed": "4", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "54", - "attack_audios": "2700,0,0,0", - "name": "Oak shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "843", - "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "54", + "id": "844", + "name": "Oak shortbow", + "archery_ticket_price": "0", "durability": null, - "name": "Oak shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "844" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "845", + "name": "Oak longbow", + "examine": "A nice sturdy bow made out of oak.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "render_anim": "2588", "requirements": "{4,5}", "shop_price": "160", - "ge_buy_limit": "5000", - "examine": "A nice sturdy bow made out of oak.", - "durability": null, - "weight": "2", - "attack_speed": "6", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "132", - "attack_audios": "2700,0,0,0", - "name": "Oak longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "845", - "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0" + "weight": "2" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "132", + "id": "846", + "name": "Oak longbow", + "archery_ticket_price": "0", "durability": null, - "name": "Oak longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "846" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "847", + "name": "Willow longbow", + "examine": "A nice sturdy bow made out of willow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "render_anim": "2588", "requirements": "{4,20}", "shop_price": "320", - "ge_buy_limit": "5000", - "examine": "A nice sturdy bow made out of willow.", - "durability": null, - "weight": "1.5", - "attack_speed": "6", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "132", - "attack_audios": "2700,0,0,0", - "name": "Willow longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "847", - "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,0" + "weight": "1.5" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "132", + "id": "848", + "name": "Willow longbow", + "archery_ticket_price": "0", "durability": null, - "name": "Willow longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "848" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "849", + "name": "Willow shortbow", + "examine": "A shortbow made out of willow, still effective.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "render_anim": "2588", "requirements": "{4,20}", "shop_price": "200", - "ge_buy_limit": "5000", - "examine": "A shortbow made out of willow, still effective.", - "durability": null, - "weight": "1", - "attack_speed": "4", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "106", - "attack_audios": "2700,0,0,0", - "name": "Willow shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "849", - "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,0" + "weight": "1" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "106", + "id": "850", + "name": "Willow shortbow", + "archery_ticket_price": "0", "durability": null, - "name": "Willow shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "850" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "851", + "name": "Maple longbow", + "examine": "A nice sturdy bow made out of maple.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "lendable": "true", + "render_anim": "2588", "requirements": "{4,30}", "shop_price": "640", - "ge_buy_limit": "5000", - "examine": "A nice sturdy bow made out of maple.", - "durability": null, - "weight": "1.8", - "attack_speed": "6", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "320", - "attack_audios": "2700,0,0,0", - "name": "Maple longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "851", - "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "320", + "id": "852", + "name": "Maple longbow", + "archery_ticket_price": "0", "durability": null, - "name": "Maple longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "852" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "853", + "name": "Maple shortbow", + "examine": "A shortbow made out of maple, still effective.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "lendable": "true", + "render_anim": "2588", "requirements": "{4,30}", "shop_price": "400", - "ge_buy_limit": "5000", - "examine": "A shortbow made out of maple, still effective.", - "durability": null, - "weight": "1", - "attack_speed": "4", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "290", - "attack_audios": "2700,0,0,0", - "name": "Maple shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "853", - "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" + "weight": "1" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "290", + "id": "854", + "name": "Maple shortbow", + "archery_ticket_price": "0", "durability": null, - "name": "Maple shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "854" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "855", + "name": "Yew longbow", + "examine": "A nice sturdy bow made out of yew.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "lendable": "true", + "render_anim": "2588", "requirements": "{4,40}", "shop_price": "674", - "ge_buy_limit": "5000", - "examine": "A nice sturdy bow made out of yew.", - "durability": null, - "weight": "1.8", - "attack_speed": "6", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "706", - "attack_audios": "2700,0,0,0", - "name": "Yew longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "855", - "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "706", - "durability": null, + "id": "856", "name": "Yew longbow", - "tradeable": "true", "archery_ticket_price": "0", - "id": "856" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{4,40}", - "ge_buy_limit": "5000", - "examine": "A shortbow made out of yew, still effective.", - "durability": null, - "weight": "1", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "422", - "attack_audios": "2700,0,0,0", - "name": "Yew shortbow", - "tradeable": "true", - "archery_ticket_price": "0", "id": "857", - "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "422", - "durability": null, "name": "Yew shortbow", - "tradeable": "true", + "examine": "A shortbow made out of yew, still effective.", "archery_ticket_price": "0", - "id": "858" + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "lendable": "true", + "render_anim": "2588", + "requirements": "{4,40}", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "16", + "weight": "1" }, { + "id": "858", + "name": "Yew shortbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "859", + "name": "Magic longbow", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "has_special": "true", + "lendable": "true", + "render_anim": "2588", "requirements": "{4,50}", "shop_price": "1270", - "ge_buy_limit": "5000", - "examine": "A nice sturdy magical bow.", - "has_special": "true", - "durability": null, - "weight": "1.8", - "attack_speed": "6", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "1437", - "attack_audios": "2700,0,0,0", - "name": "Magic longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "859", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1437", + "id": "860", + "name": "Magic longbow", + "archery_ticket_price": "0", "durability": null, - "name": "Magic longbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "860" + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "861", + "name": "Magic shortbow", + "examine": "Short and magical, but still effective.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "5000", + "has_special": "true", + "lendable": "true", + "render_anim": "2588", "requirements": "{4,50}", "shop_price": "5600", - "ge_buy_limit": "5000", - "examine": "Short and magical, but still effective.", - "has_special": "true", - "durability": null, - "weight": "1.3", - "attack_speed": "4", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "959", - "attack_audios": "2700,0,0,0", - "name": "Magic shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "861", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + "weight": "1.3" }, { + "id": "862", + "name": "Magic shortbow", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "959", - "durability": null, - "name": "Magic shortbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "862" + "tradeable": "true" }, { - "shop_price": "58", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "87", - "attack_audios": "2704,0,0,0", - "name": "Iron knife", - "tradeable": "true", - "archery_ticket_price": "0", "id": "863", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" - }, - { - "shop_price": "14", - "ge_buy_limit": "10000", + "name": "Iron knife", "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "73", - "attack_audios": "2704,0,0,0", - "name": "Bronze knife", - "tradeable": "true", "archery_ticket_price": "0", - "id": "864", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { - "requirements": "{4,5}", - "shop_price": "68", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "136", - "attack_audios": "2704,0,0,0", - "name": "Steel knife", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "865", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "201", - "attack_audios": "2704,0,0,0", - "name": "Mithril knife", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "866", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "421", - "attack_audios": "2704,0,0,0", - "name": "Adamant knife", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "867", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1132", - "attack_audios": "2704,0,0,0", - "name": "Rune knife", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "868", - "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" - }, - { - "requirements": "{4,10}", - "shop_price": "15", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "95", - "attack_audios": "2704,0,0,0", - "name": "Black knife", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "869", - "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" - }, - { - "shop_price": "14", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "73", - "attack_audios": "2704,0,0,0", - "name": "Bronze knife(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "870", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { "shop_price": "58", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "88", - "attack_audios": "2704,0,0,0", - "name": "Iron knife(p)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "871", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + "weapon_interface": "18" }, { + "id": "864", + "name": "Bronze knife", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "14", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "865", + "name": "Steel knife", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", "requirements": "{4,5}", "shop_price": "68", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "866", + "name": "Mithril knife", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "124", - "attack_audios": "2704,0,0,0", - "name": "Steel knife(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "872", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { "requirements": "{4,20}", - "ge_buy_limit": "100", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "226", - "attack_audios": "2704,0,0,0", - "name": "Mithril knife(p)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "873", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + "weapon_interface": "18" }, { + "id": "867", + "name": "Adamant knife", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "868", + "name": "Rune knife", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "869", + "name": "Black knife", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", "requirements": "{4,10}", "shop_price": "15", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "69", - "attack_audios": "2704,0,0,0", - "name": "Black knife(p)", "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "870", + "name": "Bronze knife(p)", + "examine": "A finely balanced throwing knife.", "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "14", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "871", + "name": "Iron knife(p)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "58", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "872", + "name": "Steel knife(p)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "shop_price": "68", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "873", + "name": "Mithril knife(p)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" + }, + { "id": "874", - "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" + "name": "Black knife(p)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,10}", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "18" }, { - "requirements": "{4,30}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "503", - "attack_audios": "2704,0,0,0", - "name": "Adamant knife(p)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "875", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "10000", + "name": "Adamant knife(p)", "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "806,806,806,806", - "grand_exchange_price": "1374", "attack_audios": "2704,0,0,0", - "name": "Rune knife(p)", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,30}", "tradeable": "true", - "archery_ticket_price": "0", + "weapon_interface": "18" + }, + { "id": "876", - "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" + "name": "Rune knife(p)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" }, { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "Bronze crossbow bolts.", - "grand_exchange_price": "12", - "durability": null, - "name": "Bronze bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "877", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "shop_price": "3", - "ge_buy_limit": "10000", + "name": "Bronze bolts", "examine": "Bronze crossbow bolts.", - "grand_exchange_price": "38", - "durability": null, - "name": "Bronze bolts(p)", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" + }, + { "id": "878", + "name": "Bronze bolts(p)", + "examine": "Bronze crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" }, { - "ge_buy_limit": "25000", - "examine": "Opal tipped bronze crossbow bolts", - "grand_exchange_price": "5", - "durability": null, - "name": "Opal bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "879", + "name": "Opal bolts", + "examine": "Opal tipped bronze crossbow bolts", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,14", - "equipment_slot": "13" - }, - { - "requirements": "{4,26}", + "durability": null, + "equipment_slot": "13", "ge_buy_limit": "25000", - "examine": "Pearl tipped Iron crossbow bolts.", - "grand_exchange_price": "32", - "durability": null, - "name": "Pearl bolts", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "880", + "name": "Pearl bolts", + "examine": "Pearl tipped Iron crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,48", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,26}", + "tradeable": "true" }, { - "shop_price": "80", - "ge_buy_limit": "10000", - "examine": "Great if you have a crossbow!", - "grand_exchange_price": "42", - "durability": null, - "name": "Barbed bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "881", + "name": "Barbed bolts", + "examine": "Great if you have a crossbow!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,12", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "80", + "tradeable": "true" }, { - "shop_price": "7", - "ge_buy_limit": "10000", - "examine": "Arrows with bronze heads.", - "grand_exchange_price": "10", - "durability": null, - "name": "Bronze arrow", - "tradeable": "true", - "archery_ticket_price": "0", "id": "882", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" - }, - { - "shop_price": "7", - "ge_buy_limit": "10000", + "name": "Bronze arrow", "examine": "Arrows with bronze heads.", - "grand_exchange_price": "39", - "durability": null, - "name": "Bronze arrow(p)", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "7", + "tradeable": "true" + }, + { "id": "883", + "name": "Bronze arrow(p)", + "examine": "Arrows with bronze heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "7", + "tradeable": "true" }, { - "shop_price": "20", - "ge_buy_limit": "10000", - "examine": "Arrows with iron heads.", - "grand_exchange_price": "10", - "durability": null, - "name": "Iron arrow", - "tradeable": "true", - "archery_ticket_price": "0", "id": "884", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "shop_price": "20", - "ge_buy_limit": "10000", + "name": "Iron arrow", "examine": "Arrows with iron heads.", - "grand_exchange_price": "41", - "durability": null, - "name": "Iron arrow(p)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "885", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true" }, { - "requirements": "{4,5}", - "shop_price": "46", - "ge_buy_limit": "10000", - "examine": "Arrows with steel heads.", - "grand_exchange_price": "25", - "durability": null, - "name": "Steel arrow", - "tradeable": "true", + "id": "885", + "name": "Iron arrow(p)", + "examine": "Arrows with iron heads.", "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true" + }, + { "id": "886", + "name": "Steel arrow", + "examine": "Arrows with steel heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,5}", "shop_price": "46", - "ge_buy_limit": "10000", - "examine": "Arrows with steel heads.", - "grand_exchange_price": "69", - "durability": null, - "name": "Steel arrow(p)", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "887", + "name": "Steel arrow(p)", + "examine": "Arrows with steel heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "shop_price": "46", + "tradeable": "true" }, { - "requirements": "{4,20}", - "shop_price": "76", - "ge_buy_limit": "10000", - "examine": "Arrows with mithril heads.", - "grand_exchange_price": "30", - "durability": null, - "name": "Mithril arrow", - "tradeable": "true", - "archery_ticket_price": "0", "id": "888", + "name": "Mithril arrow", + "examine": "Arrows with mithril heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,20}", "shop_price": "76", - "ge_buy_limit": "10000", - "examine": "Arrows with mithril heads.", - "grand_exchange_price": "69", - "durability": null, - "name": "Mithril arrow(p)", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "889", + "name": "Mithril arrow(p)", + "examine": "Arrows with mithril heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,20}", + "shop_price": "76", + "tradeable": "true" }, { - "requirements": "{4,30}", - "shop_price": "172", - "ge_buy_limit": "10000", - "examine": "Arrows with adamantite heads.", - "grand_exchange_price": "111", - "durability": null, - "name": "Adamant arrow", - "tradeable": "true", - "archery_ticket_price": "0", "id": "890", + "name": "Adamant arrow", + "examine": "Arrows with adamantite heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,30}", "shop_price": "172", - "ge_buy_limit": "10000", - "examine": "Arrows with adamantite heads.", - "grand_exchange_price": "109", - "durability": null, - "name": "Adamant arrow(p)", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "891", + "name": "Adamant arrow(p)", + "examine": "Arrows with adamantite heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "shop_price": "172", + "tradeable": "true" }, { - "requirements": "{4,40}", - "shop_price": "510", - "ge_buy_limit": "10000", - "examine": "Arrows with rune heads.", - "grand_exchange_price": "212", - "durability": null, - "name": "Rune arrow", - "tradeable": "true", - "archery_ticket_price": "40", "id": "892", + "name": "Rune arrow", + "examine": "Arrows with rune heads.", + "archery_ticket_price": "40", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,40}", "shop_price": "510", - "ge_buy_limit": "10000", - "examine": "Arrows with rune heads.", - "grand_exchange_price": "257", - "durability": null, - "name": "Rune arrow(p)", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "893", + "name": "Rune arrow(p)", + "examine": "Arrows with rune heads.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", "ge_buy_limit": "10000", - "examine": "unlit: Arrows with bronze heads and oil-soaked cloth. lit: An easy to make, bronze-headed fire arrow.", - "grand_exchange_price": "228", - "durability": null, - "name": "Bronze fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", + "requirements": "{4,40}", + "shop_price": "510", + "tradeable": "true" + }, + { "id": "942", + "name": "Bronze fire arrows", + "examine": "unlit: Arrows with bronze heads and oil-soaked cloth. lit: An easy to make, bronze-headed fire arrow.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "0", + "id": "943", + "name": "Worm", "examine": "Ugh! It's wriggling!", - "durability": null, - "name": "Worm", - "tradeable": "true", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "943" + "durability": null, + "shop_price": "0", + "tradeable": "true" }, { - "durability": null, + "id": "944", "name": "Worm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "944" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "945", "name": "Throwing rope", "archery_ticket_price": "0", - "id": "945", + "durability": null, "equipment_slot": "3" }, { - "shop_price": "25", - "ge_buy_limit": "100", + "id": "946", + "name": "Knife", "examine": "A dangerous looking knife.", - "grand_exchange_price": "32", - "durability": null, - "name": "Knife", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "946" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "32", - "durability": null, - "name": "Knife", + "shop_price": "25", "tradeable": "true", - "archery_ticket_price": "0", - "id": "947" + "weight": "0.4" }, { + "id": "947", + "name": "Knife", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "948", + "name": "Bear fur", + "examine": "This would make warm clothing.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "shop_price": "4", - "ge_buy_limit": "100", - "examine": "This would make warm clothing.", - "grand_exchange_price": "9", - "durability": null, - "name": "Bear fur", "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "948" + "weight": "3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "9", - "durability": null, + "id": "949", "name": "Bear fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "949" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "21", - "ge_buy_limit": "100", + "id": "950", + "name": "Silk", "examine": "It's a sheet of silk.", - "grand_exchange_price": "27", - "durability": null, - "name": "Silk", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "950" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "21", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "27", - "durability": null, + "id": "951", "name": "Silk", - "tradeable": "true", "archery_ticket_price": "0", - "id": "951" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "5", - "ge_buy_limit": "100", + "id": "952", + "name": "Spade", "examine": "A slightly muddy spade. / Popular with farmers and treasure hunters.", - "grand_exchange_price": "117", - "durability": null, - "name": "Spade", - "tradeable": "true", - "weight": "1.8", "archery_ticket_price": "0", - "id": "952" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "117", - "durability": null, + "id": "953", "name": "Spade", - "tradeable": "true", "archery_ticket_price": "0", - "id": "953" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "18", - "ge_buy_limit": "100", + "id": "954", + "name": "Rope", "examine": "A coil of rope.", - "grand_exchange_price": "96", - "durability": null, - "name": "Rope", - "tradeable": "true", - "weight": "1.3", "archery_ticket_price": "0", - "id": "954" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "96", - "durability": null, - "name": "Rope", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "955" - }, - { - "examine": "Get your axes from Bob's Axes.", - "durability": null, - "name": "Flier", - "archery_ticket_price": "0", - "id": "956" - }, - { - "shop_price": "70", - "ge_buy_limit": "100", - "examine": "This would make warm clothing.", - "grand_exchange_price": "34", - "durability": null, - "name": "Grey wolf fur", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "958" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "34", - "durability": null, - "name": "Grey wolf fur", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "959" - }, - { - "shop_price": "100", - "ge_buy_limit": "10000", - "examine": "A plank of wood!", - "grand_exchange_price": "234", - "durability": null, - "name": "Plank", - "tradeable": "true", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "960" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "234", - "durability": null, - "name": "Plank", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "961" - }, - { - "ge_buy_limit": "2", - "examine": "I need to pull this.", - "grand_exchange_price": "15", - "durability": null, - "name": "Christmas cracker", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "962" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1900000000", - "durability": null, - "name": "Christmas cracker", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "963" - }, - { - "examine": "A fraction of a roof.", - "durability": null, - "name": "Tile", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "966" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", - "examine": "Used for making notes.", - "grand_exchange_price": "153", - "durability": null, - "name": "Papyrus", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "970" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "153", - "durability": null, - "name": "Papyrus", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "971" - }, - { - "shop_price": "15", - "examine": "Used for making notes.", - "grand_exchange_price": "163", - "durability": null, - "name": "Papyrus", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "972" - }, - { - "shop_price": "45", - "ge_buy_limit": "100", - "examine": "A lump of charcoal.", - "grand_exchange_price": "272", - "durability": null, - "name": "Charcoal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "973" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "272", - "durability": null, - "name": "Charcoal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "974" - }, - { - "shop_price": "52", - "ge_buy_limit": "100", - "examine": "A jungle specific slashing device.", - "durability": null, - "weight": "1.3", - "attack_speed": "5", - "weapon_interface": "6", - "render_anim": "2554", - "equipment_slot": "3", - "grand_exchange_price": "619", - "name": "Machete", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "975", - "bonuses": "0,6,-2,0,0,0,0,0,0,0,0,5,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "619", - "durability": null, - "name": "Machete", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "976" - }, - { - "durability": null, - "name": "Cooking pot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "978" - }, - { - "shop_price": "10", - "ge_buy_limit": "2", - "examine": "Used to get out of Thordur's blackhole.", - "grand_exchange_price": "298000000", - "durability": null, - "name": "Disk of returning", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "981" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "298000000", - "durability": null, - "name": "Disk of returning", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "982" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "A key found on the floor of Edgeville Dungeon.", - "grand_exchange_price": "547", - "durability": null, - "name": "Brass key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "983" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "547", - "durability": null, - "name": "Brass key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "984" - }, - { - "ge_buy_limit": "100", - "examine": "The tooth end of the mysterious Crystal key. Can you find the other half?", - "grand_exchange_price": "24900", - "durability": null, - "name": "Tooth half of a key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "985" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "24900", - "durability": null, - "name": "Tooth half of a key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "986" - }, - { - "ge_buy_limit": "100", - "examine": "The loop end of the mysterious Crystal key. Can you find the other half?", - "grand_exchange_price": "21100", - "durability": null, - "name": "Loop half of a key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "987" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "21100", - "durability": null, - "name": "Loop half of a key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "988" - }, - { - "ge_buy_limit": "100", - "examine": "A mysterious key for a mysterious chest.", - "grand_exchange_price": "48700", - "durability": null, - "name": "Crystal key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "989" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "48700", - "durability": null, - "name": "Crystal key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "990" - }, - { - "ge_buy_limit": "100", - "examine": "It looks like the key to a chest", - "grand_exchange_price": "4971", - "durability": null, - "name": "Muddy key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "991" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4971", - "durability": null, - "name": "Muddy key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "992" - }, - { - "ge_buy_limit": "100", - "examine": "You get a sense of dread from this key.", - "grand_exchange_price": "54600", - "durability": null, - "name": "Sinister key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "993" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "54600", - "durability": null, - "name": "Sinister key", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "994" - }, - { - "examine": "Lovely money!", - "durability": null, - "name": "Coins", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "995" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A mostly clean apron.", - "grand_exchange_price": "93", - "durability": null, - "name": "White apron", - "tradeable": "true", - "weight": "0.45", - "archery_ticket_price": "0", - "id": "1005", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "93", - "durability": null, - "name": "White apron", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1006" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A bright red cape.", - "grand_exchange_price": "187", - "durability": null, - "name": "Cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1007", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "187", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1008" - }, - { - "ge_buy_limit": "100", - "examine": "I'd prefer a gold one.", - "grand_exchange_price": "65", - "durability": null, - "name": "Brass necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1009", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "65", - "durability": null, - "name": "Brass necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1010" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "Leg covering favored by women and wizards.", - "grand_exchange_price": "208", - "durability": null, - "name": "Blue skirt", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1011", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "208", - "durability": null, - "name": "Blue skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1012" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A ladies skirt.", - "grand_exchange_price": "216", - "durability": null, - "name": "Pink skirt", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1013", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "216", - "durability": null, - "name": "Pink skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1014" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "Clothing favoured by women and dark wizards.", - "grand_exchange_price": "30", - "durability": null, - "name": "Black skirt", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1015", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "30", - "durability": null, - "name": "Black skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1016" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "grand_exchange_price": "280", - "durability": null, - "name": "Wizard hat", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": "true", - "id": "1017", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "280", - "durability": null, - "name": "Wizard hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1018" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A warm black cape.", - "grand_exchange_price": "209", - "durability": null, - "name": "Cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1019", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "209", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1020" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A thick blue cape.", - "grand_exchange_price": "504", - "durability": null, - "name": "Cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1021", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "504", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1022" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A thick yellow cape.", - "grand_exchange_price": "439", - "durability": null, - "name": "Cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1023", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "439", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1024" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A black piece of cloth on a string.", - "grand_exchange_price": "111", - "durability": null, - "name": "Eyepatch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1025", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "111", - "durability": null, - "name": "Eyepatch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1026" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A thick green cape.", - "grand_exchange_price": "1061", - "durability": null, - "name": "Cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1027", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1061", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1028" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A thick purple cape.", - "grand_exchange_price": "955", - "durability": null, - "name": "Cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1029", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "955", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1030" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A thick orange cape.", - "durability": null, - "destroy": "true", - "weight": "0.4", - "equipment_slot": "1", - "grand_exchange_price": "1656", - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1031", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1656", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1032" - }, - { - "shop_price": "30", - "ge_buy_limit": "2", - "examine": "A robe worn by worshippers of Zamorak.", - "grand_exchange_price": "2481", - "durability": null, - "name": "Zamorak robe", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1033", - "bonuses": "0,0,0,2,0,0,0,0,3,0,0,0,3,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2481", - "durability": null, - "name": "Zamorak robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1034" - }, - { - "shop_price": "40", - "ge_buy_limit": "2", - "examine": "A robe worn by worshippers of Zamorak.", - "durability": null, - "weight": "0.9", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "1259", - "name": "Zamorak robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1035", - "bonuses": "0,0,0,2,0,0,0,0,3,0,3,0,3,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1259", - "durability": null, - "name": "Zamorak robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1036" - }, - { - "destroy_message": "You can get a replacement from Diango.", - "shop_price": "1", - "examine": "A rabbit-like adornment.", - "durability": null, - "name": "Bunny ears", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "1037", - "equipment_slot": "0" - }, - { - "lendable": "true", - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "10", - "durability": null, - "name": "Red partyhat", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1038", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1500000000", - "durability": null, - "name": "Red partyhat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1039" - }, - { - "lendable": "true", - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "10", - "durability": null, - "name": "Yellow partyhat", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1040", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1200000000", - "durability": null, - "name": "Yellow partyhat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1041" - }, - { - "lendable": "true", - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "10", - "durability": null, - "name": "Blue partyhat", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1042", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2100000000", - "durability": null, - "name": "Blue partyhat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1043" - }, - { - "lendable": "true", - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "10", - "durability": null, - "name": "Green partyhat", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1044", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1300000000", - "durability": null, - "name": "Green partyhat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1045" - }, - { - "lendable": "true", - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "10", - "durability": null, - "name": "Purple partyhat", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1046", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1000000000", - "durability": null, - "name": "Purple partyhat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1047" - }, - { - "lendable": "true", - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "10", - "durability": null, - "name": "White partyhat", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1048", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2000000000", - "durability": null, - "name": "White partyhat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1049" - }, - { - "shop_price": "1", - "ge_buy_limit": "2", - "examine": "It's a Santa hat.", - "durability": null, - "weight": "0.1", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "5", - "name": "Santa hat", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": "true", - "id": "1050" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "112600000", - "durability": null, - "name": "Santa hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1051" - }, - { - "shop_price": "450", - "examine": "The cape worn by members of the Legends Guild.", - "durability": null, - "name": "Cape of legends", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "1052", - "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", - "equipment_slot": "1" - }, - { - "remove_head": "true", - "shop_price": "15", - "ge_buy_limit": "2", - "examine": "Aaaarrrghhh ... I'm a monster.", - "durability": null, - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "98000000", - "name": "Green h'ween mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1053" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "98000000", - "durability": null, - "name": "Green h'ween mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1054" - }, - { - "remove_head": "true", - "shop_price": "15", - "ge_buy_limit": "2", - "examine": "Aaaarrrghhh ... I'm a monster.", - "durability": null, - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "115900000", - "name": "Blue h'ween mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1055" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "115900000", - "durability": null, - "name": "Blue h'ween mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1056" - }, - { - "remove_head": "true", - "shop_price": "15", - "ge_buy_limit": "2", - "examine": "Aaaarrrghhh ... I'm a monster.", - "durability": null, - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "154300000", - "name": "Red h'ween mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1057" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "154300000", - "durability": null, - "name": "Red h'ween mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1058" - }, - { - "shop_price": "6", - "ge_buy_limit": "5000", - "examine": "These will keep my hands warm!", - "grand_exchange_price": "12", - "durability": null, - "name": "Leather gloves", - "tradeable": "true", - "weight": "0.23", - "archery_ticket_price": "0", - "id": "1059", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "12", - "durability": null, - "name": "Leather gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1060" - }, - { - "shop_price": "6", - "ge_buy_limit": "5000", - "examine": "Comfortable leather boots.", - "grand_exchange_price": "144", - "durability": null, - "name": "Leather boots", - "tradeable": "true", - "weight": "0.34", - "archery_ticket_price": "0", - "id": "1061", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "144", - "durability": null, - "name": "Leather boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1062" - }, - { "shop_price": "18", - "ge_buy_limit": "5000", - "examine": "Better than no armour!", - "grand_exchange_price": "13", - "durability": null, - "name": "Leather vambraces", "tradeable": "true", - "weight": "0.22", + "weight": "1.3" + }, + { + "id": "955", + "name": "Rope", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "956", + "name": "Flier", + "examine": "Get your axes from Bob's Axes.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "958", + "name": "Grey wolf fur", + "examine": "This would make warm clothing.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "70", + "tradeable": "true", + "weight": "3" + }, + { + "id": "959", + "name": "Grey wolf fur", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "960", + "name": "Plank", + "examine": "A plank of wood!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "100", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "961", + "name": "Plank", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "962", + "name": "Christmas cracker", + "examine": "I need to pull this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "963", + "name": "Christmas cracker", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "966", + "name": "Tile", + "examine": "A fraction of a roof.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.6" + }, + { + "id": "970", + "name": "Papyrus", + "examine": "Used for making notes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "971", + "name": "Papyrus", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "972", + "name": "Papyrus", + "examine": "Used for making notes.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "973", + "name": "Charcoal", + "examine": "A lump of charcoal.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "45", + "tradeable": "true" + }, + { + "id": "974", + "name": "Charcoal", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "975", + "name": "Machete", + "examine": "A jungle specific slashing device.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,6,-2,0,0,0,0,0,0,0,0,5,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2554", + "shop_price": "52", + "tradeable": "true", + "weapon_interface": "6", + "weight": "1.3" + }, + { + "id": "976", + "name": "Machete", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "978", + "name": "Cooking pot", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "981", + "name": "Disk of returning", + "examine": "Used to get out of Thordur's blackhole.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "shop_price": "10", + "tradeable": "true", + "weight": "2" + }, + { + "id": "982", + "name": "Disk of returning", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "983", + "name": "Brass key", + "examine": "A key found on the floor of Edgeville Dungeon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "984", + "name": "Brass key", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "985", + "name": "Tooth half of a key", + "examine": "The tooth end of the mysterious Crystal key. Can you find the other half?", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "986", + "name": "Tooth half of a key", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "987", + "name": "Loop half of a key", + "examine": "The loop end of the mysterious Crystal key. Can you find the other half?", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "988", + "name": "Loop half of a key", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "989", + "name": "Crystal key", + "examine": "A mysterious key for a mysterious chest.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "990", + "name": "Crystal key", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "991", + "name": "Muddy key", + "examine": "It looks like the key to a chest", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "992", + "name": "Muddy key", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "993", + "name": "Sinister key", + "examine": "You get a sense of dread from this key.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "994", + "name": "Sinister key", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "995", + "name": "Coins", + "examine": "Lovely money!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1005", + "name": "White apron", + "examine": "A mostly clean apron.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "0.45" + }, + { + "id": "1006", + "name": "White apron", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1007", + "name": "Cape", + "examine": "A bright red cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1008", + "name": "Cape", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1009", + "name": "Brass necklace", + "examine": "I'd prefer a gold one.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1010", + "name": "Brass necklace", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1011", + "name": "Blue skirt", + "examine": "Leg covering favored by women and wizards.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1012", + "name": "Blue skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1013", + "name": "Pink skirt", + "examine": "A ladies skirt.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1014", + "name": "Pink skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1015", + "name": "Black skirt", + "examine": "Clothing favoured by women and dark wizards.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1016", + "name": "Black skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1017", + "name": "Wizard hat", + "examine": "A silly pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "1018", + "name": "Wizard hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1019", + "name": "Cape", + "examine": "A warm black cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1020", + "name": "Cape", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1021", + "name": "Cape", + "examine": "A thick blue cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1022", + "name": "Cape", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1023", + "name": "Cape", + "examine": "A thick yellow cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1024", + "name": "Cape", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1025", + "name": "Eyepatch", + "examine": "A black piece of cloth on a string.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "1026", + "name": "Eyepatch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1027", + "name": "Cape", + "examine": "A thick green cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1028", + "name": "Cape", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1029", + "name": "Cape", + "examine": "A thick purple cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1030", + "name": "Cape", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1031", + "name": "Cape", + "examine": "A thick orange cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1032", + "name": "Cape", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1033", + "name": "Zamorak robe", + "examine": "A robe worn by worshippers of Zamorak.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,3,0,0,0,3,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "shop_price": "30", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1034", + "name": "Zamorak robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1035", + "name": "Zamorak robe", + "examine": "A robe worn by worshippers of Zamorak.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,3,0,3,0,3,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "shop_price": "40", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1036", + "name": "Zamorak robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1037", + "name": "Bunny ears", + "examine": "A rabbit-like adornment.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get a replacement from Diango.", + "durability": null, + "equipment_slot": "0", + "shop_price": "1", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "1038", + "name": "Red partyhat", + "examine": "A nice hat from a cracker.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1039", + "name": "Red partyhat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1040", + "name": "Yellow partyhat", + "examine": "A nice hat from a cracker.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1041", + "name": "Yellow partyhat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1042", + "name": "Blue partyhat", + "examine": "A nice hat from a cracker.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1043", + "name": "Blue partyhat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1044", + "name": "Green partyhat", + "examine": "A nice hat from a cracker.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1045", + "name": "Green partyhat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1046", + "name": "Purple partyhat", + "examine": "A nice hat from a cracker.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1047", + "name": "Purple partyhat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1048", + "name": "White partyhat", + "examine": "A nice hat from a cracker.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1049", + "name": "White partyhat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1050", + "name": "Santa hat", + "examine": "It's a Santa hat.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": "true", + "lendable": "true", + "shop_price": "1", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1051", + "name": "Santa hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1052", + "name": "Cape of legends", + "examine": "The cape worn by members of the Legends Guild.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "shop_price": "450", + "weight": "1.8" + }, + { + "id": "1053", + "name": "Green h'ween mask", + "examine": "Aaaarrrghhh ... I'm a monster.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "1054", + "name": "Green h'ween mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1055", + "name": "Blue h'ween mask", + "examine": "Aaaarrrghhh ... I'm a monster.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "1056", + "name": "Blue h'ween mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1057", + "name": "Red h'ween mask", + "examine": "Aaaarrrghhh ... I'm a monster.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "1058", + "name": "Red h'ween mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1059", + "name": "Leather gloves", + "examine": "These will keep my hands warm!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "6", + "tradeable": "true", + "weight": "0.23" + }, + { + "id": "1060", + "name": "Leather gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1061", + "name": "Leather boots", + "examine": "Comfortable leather boots.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "5000", + "shop_price": "6", + "tradeable": "true", + "weight": "0.34" + }, + { + "id": "1062", + "name": "Leather boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "1063", - "bonuses": "0,0,0,0,4,2,2,1,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "13", - "durability": null, "name": "Leather vambraces", - "tradeable": "true", + "examine": "Better than no armour!", "archery_ticket_price": "0", - "id": "1064" + "bonuses": "0,0,0,0,4,2,2,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "18", + "tradeable": "true", + "weight": "0.22" }, { + "id": "1064", + "name": "Leather vambraces", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1065", + "name": "Green d'hide vambraces", + "examine": "Made from 100% real dragonhide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,3,2,4,2,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "5000", + "lendable": "true", "requirements": "{4,40}", "shop_price": "2500", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", - "durability": null, - "weight": "0.28", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "1407", - "name": "Green d'hide vambraces", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1065", - "bonuses": "0,0,0,-10,8,3,2,4,2,0,0,0,0,0,0" + "weight": "0.28" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1407", - "durability": null, + "id": "1066", "name": "Green d'hide vambraces", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1066" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "280", - "ge_buy_limit": "100", - "examine": "These look pretty heavy.", - "durability": null, - "weight": "9", - "absorb": "1,0,1", - "equipment_slot": "7", - "grand_exchange_price": "55", - "name": "Iron platelegs", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1067", - "bonuses": "0,0,0,-21,-7,11,10,10,-4,10,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "55", - "durability": null, "name": "Iron platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1068" - }, - { - "requirements": "{1,5}", - "shop_price": "1000", - "ge_buy_limit": "100", "examine": "These look pretty heavy.", - "durability": null, - "weight": "9", "absorb": "1,0,1", - "equipment_slot": "7", - "grand_exchange_price": "426", - "name": "Steel platelegs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1069", - "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "426", - "durability": null, - "name": "Steel platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1070" - }, - { - "requirements": "{1,20}", - "shop_price": "2600", - "ge_buy_limit": "100", - "examine": "These look pretty heavy.", - "durability": null, - "weight": "7.7", - "absorb": "1,0,2", - "equipment_slot": "7", - "grand_exchange_price": "1391", - "name": "Mithril platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1071", - "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1391", - "durability": null, - "name": "Mithril platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1072" - }, - { - "requirements": "{1,30}", - "shop_price": "6464", - "ge_buy_limit": "100", - "examine": "These look pretty heavy.", - "durability": null, - "weight": "10", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "3649", - "name": "Adamant platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1073", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3649", - "durability": null, - "name": "Adamant platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1074" - }, - { - "shop_price": "80", - "ge_buy_limit": "100", - "examine": "These look pretty heavy.", - "grand_exchange_price": "34", - "durability": null, - "name": "Bronze platelegs", - "tradeable": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "1075", - "bonuses": "0,0,0,-21,-7,8,7,6,-4,7,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "34", - "durability": null, - "name": "Bronze platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1076" - }, - { - "requirements": "{1,10}", - "shop_price": "1920", - "ge_buy_limit": "100", - "examine": "These look pretty heavy", - "durability": null, - "weight": "9", - "absorb": "1,0,2", - "equipment_slot": "7", - "grand_exchange_price": "4995", - "name": "Black platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1077", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4995", - "durability": null, - "name": "Black platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1078" - }, - { - "requirements": "{1,40}", - "shop_price": "64000", - "ge_buy_limit": "100", - "examine": "These look pretty heavy.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "38500", - "name": "Rune platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1079", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "38500", - "durability": null, - "name": "Rune platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1080" - }, - { - "shop_price": "280", - "ge_buy_limit": "100", - "examine": "Designer leg protection.", - "grand_exchange_price": "86", - "durability": null, - "name": "Iron plateskirt", - "tradeable": "true", - "weight": "8.1", - "archery_ticket_price": "0", - "id": "1081", "bonuses": "0,0,0,-21,-7,11,10,10,-4,10,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "86", "durability": null, - "name": "Iron plateskirt", + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "280", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1082" + "weight": "9" }, { + "id": "1068", + "name": "Iron platelegs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1069", + "name": "Steel platelegs", + "examine": "These look pretty heavy.", + "absorb": "1,0,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "100", "requirements": "{1,5}", "shop_price": "1000", - "ge_buy_limit": "100", - "examine": "Designer leg protection.", + "tradeable": "true", + "weight": "9" + }, + { + "id": "1070", + "name": "Steel platelegs", + "archery_ticket_price": "0", "durability": null, - "weight": "8.1", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1071", + "name": "Mithril platelegs", + "examine": "These look pretty heavy.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0", + "durability": null, + "equip_audio": "2242", "equipment_slot": "7", - "grand_exchange_price": "514", - "name": "Steel plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1083", - "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "514", - "durability": null, - "name": "Steel plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1084" - }, - { "requirements": "{1,20}", "shop_price": "2600", - "ge_buy_limit": "100", - "examine": "Designer leg protection.", + "tradeable": "true", + "weight": "7.7" + }, + { + "id": "1072", + "name": "Mithril platelegs", + "archery_ticket_price": "0", "durability": null, - "weight": "7.2", - "absorb": "1,0,2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1073", + "name": "Adamant platelegs", + "examine": "These look pretty heavy.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "durability": null, + "equip_audio": "2242", "equipment_slot": "7", - "grand_exchange_price": "1339", - "name": "Mithril plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1085", - "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1339", - "durability": null, - "name": "Mithril plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1086" - }, - { - "shop_price": "80", - "ge_buy_limit": "100", - "examine": "Designer leg protection.", - "grand_exchange_price": "113", - "durability": null, - "name": "Bronze plateskirt", - "tradeable": "true", - "weight": "8.1", - "archery_ticket_price": "0", - "id": "1087", - "bonuses": "0,0,0,-21,-7,8,7,6,-4,7,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "113", - "durability": null, - "name": "Bronze plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1088" - }, - { - "requirements": "{1,10}", - "shop_price": "1920", - "ge_buy_limit": "100", - "examine": "Designer leg protection.", - "durability": null, - "weight": "8", - "absorb": "1,0,2", - "equipment_slot": "7", - "grand_exchange_price": "2180", - "name": "Black plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1089", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2180", - "durability": null, - "name": "Black plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1090" - }, - { "requirements": "{1,30}", "shop_price": "6464", - "ge_buy_limit": "100", - "examine": "Designer leg protection.", + "tradeable": "true", + "weight": "10" + }, + { + "id": "1074", + "name": "Adamant platelegs", + "archery_ticket_price": "0", "durability": null, - "weight": "9", - "absorb": "1,0,3", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1075", + "name": "Bronze platelegs", + "examine": "These look pretty heavy.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,8,7,6,-4,7,0,0,0,0,0", + "durability": null, + "equip_audio": "2242", "equipment_slot": "7", - "grand_exchange_price": "3610", - "name": "Adamant plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1091", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "3610", - "durability": null, - "name": "Adamant plateskirt", + "shop_price": "80", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1092" + "weight": "9" }, { + "id": "1076", + "name": "Bronze platelegs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1077", + "name": "Black platelegs", + "examine": "These look pretty heavy", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,10}", + "shop_price": "1920", + "tradeable": "true", + "weight": "9" + }, + { + "id": "1078", + "name": "Black platelegs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1079", + "name": "Rune platelegs", + "examine": "These look pretty heavy.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", "requirements": "{1,40}", "shop_price": "64000", + "tradeable": "true", + "weight": "9" + }, + { + "id": "1080", + "name": "Rune platelegs", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1081", + "name": "Iron plateskirt", "examine": "Designer leg protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,11,10,10,-4,10,0,0,0,0,0", "durability": null, - "weight": "8", - "absorb": "2,0,4", "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "38100", - "name": "Rune plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1093", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "38100", + "shop_price": "280", + "tradeable": "true", + "weight": "8.1" + }, + { + "id": "1082", + "name": "Iron plateskirt", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1083", + "name": "Steel plateskirt", + "examine": "Designer leg protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,5}", + "shop_price": "1000", + "tradeable": "true", + "weight": "8.1" + }, + { + "id": "1084", + "name": "Steel plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1085", + "name": "Mithril plateskirt", + "examine": "Designer leg protection.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,20}", + "shop_price": "2600", + "tradeable": "true", + "weight": "7.2" + }, + { + "id": "1086", + "name": "Mithril plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1087", + "name": "Bronze plateskirt", + "examine": "Designer leg protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,8,7,6,-4,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "80", + "tradeable": "true", + "weight": "8.1" + }, + { + "id": "1088", + "name": "Bronze plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1089", + "name": "Black plateskirt", + "examine": "Designer leg protection.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,10}", + "shop_price": "1920", + "tradeable": "true", + "weight": "8" + }, + { + "id": "1090", + "name": "Black plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1091", + "name": "Adamant plateskirt", + "examine": "Designer leg protection.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,30}", + "shop_price": "6464", + "tradeable": "true", + "weight": "9" + }, + { + "id": "1092", + "name": "Adamant plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1093", "name": "Rune plateskirt", - "tradeable": "true", + "examine": "Designer leg protection.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "1094" + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}", + "shop_price": "64000", + "tradeable": "true", + "weight": "8" }, { - "shop_price": "23", - "ge_buy_limit": "5000", - "examine": "Better than no armour!", - "grand_exchange_price": "5", - "durability": null, - "name": "Leather chaps", - "tradeable": "true", - "weight": "3", + "id": "1094", + "name": "Rune plateskirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1095", - "bonuses": "0,0,0,0,4,2,2,1,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "5", - "durability": null, "name": "Leather chaps", - "tradeable": "true", + "examine": "Better than no armour!", "archery_ticket_price": "0", - "id": "1096" + "bonuses": "0,0,0,0,4,2,2,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "5000", + "shop_price": "23", + "tradeable": "true", + "weight": "3" }, { + "id": "1096", + "name": "Leather chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1097", + "name": "Studded chaps", + "examine": "Those studs should provide a bit more protection.", + "absorb": "0,2,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "1000", "requirements": "{4,20}", "shop_price": "750", - "ge_buy_limit": "1000", - "examine": "Those studs should provide a bit more protection.", + "tradeable": "true", + "weight": "4.5" + }, + { + "id": "1098", + "name": "Studded chaps", + "archery_ticket_price": "0", "durability": null, - "weight": "4.5", - "absorb": "0,2,1", + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1099", + "name": "Green d'hide chaps", + "examine": "100% real dragonhide.", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "7", - "grand_exchange_price": "377", - "name": "Studded chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1097", - "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "377", - "durability": null, - "name": "Studded chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1098" - }, - { + "ge_buy_limit": "5000", + "lendable": "true", "requirements": "{4,40}", "shop_price": "3900", - "ge_buy_limit": "5000", - "examine": "100% real dragonhide.", - "durability": null, - "weight": "5.4", - "absorb": "0,4,2", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "2228", - "name": "Green d'hide chaps", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1099", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0" + "weight": "5.4" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2228", - "durability": null, + "id": "1100", "name": "Green d'hide chaps", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1100" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "210", - "ge_buy_limit": "100", - "examine": "A series of connected metal rings.", - "grand_exchange_price": "76", - "durability": null, - "name": "Iron chainbody", - "tradeable": "true", - "weight": "6.8", - "archery_ticket_price": "0", "id": "1101", - "bonuses": "0,0,0,-15,0,10,15,19,-3,12,5,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "76", - "durability": null, "name": "Iron chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1102" - }, - { - "shop_price": "60", - "ge_buy_limit": "100", "examine": "A series of connected metal rings.", - "grand_exchange_price": "37", - "durability": null, - "name": "Bronze chainbody", - "tradeable": "true", - "weight": "6.8", "archery_ticket_price": "0", - "id": "1103", - "bonuses": "0,0,0,-15,0,7,11,13,-3,9,5,0,0,0,0", - "equipment_slot": "4" - }, - { + "bonuses": "0,0,0,-15,0,10,15,19,-3,12,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", "ge_buy_limit": "100", - "grand_exchange_price": "37", - "durability": null, - "name": "Bronze chainbody", + "shop_price": "210", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1104" + "weight": "6.8" }, { + "id": "1102", + "name": "Iron chainbody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1103", + "name": "Bronze chainbody", + "examine": "A series of connected metal rings.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,7,11,13,-3,9,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "60", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "1104", + "name": "Bronze chainbody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1105", + "name": "Steel chainbody", + "examine": "A series of connected metal rings.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,17,25,30,-3,19,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", "requirements": "{1,5}", "shop_price": "750", + "tradeable": "true", + "weight": "6" + }, + { + "id": "1106", + "name": "Steel chainbody", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1107", + "name": "Black chainbody", "examine": "A series of connected metal rings.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,22,32,39,-3,24,10,0,0,0,0", "durability": null, - "weight": "6", "equipment_slot": "4", - "grand_exchange_price": "265", - "name": "Steel chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1105", - "bonuses": "0,0,0,-15,0,17,25,30,-3,19,5,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "265", - "durability": null, - "name": "Steel chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1106" - }, - { "requirements": "{1,10}", "shop_price": "1440", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "1108", + "name": "Black chainbody", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1109", + "name": "Mithril chainbody", "examine": "A series of connected metal rings.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,25,35,42,-3,27,20,0,0,0,0", "durability": null, - "weight": "6.8", - "absorb": "1,0,2", "equipment_slot": "4", - "grand_exchange_price": "961", - "name": "Black chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1107", - "bonuses": "0,0,0,-15,0,22,32,39,-3,24,10,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "961", - "durability": null, - "name": "Black chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1108" - }, - { "requirements": "{1,20}", "shop_price": "1950", + "tradeable": "true", + "weight": "5.8" + }, + { + "id": "1110", + "name": "Mithril chainbody", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1111", + "name": "Adamant chainbody", "examine": "A series of connected metal rings.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,36,50,61,-3,38,30,0,0,0,0", "durability": null, - "weight": "5.8", - "absorb": "1,0,3", "equipment_slot": "4", - "grand_exchange_price": "963", - "name": "Mithril chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1109", - "bonuses": "0,0,0,-15,0,25,35,42,-3,27,20,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "963", - "durability": null, - "name": "Mithril chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1110" - }, - { "requirements": "{1,30}", "shop_price": "4800", + "tradeable": "true", + "weight": "7.7" + }, + { + "id": "1112", + "name": "Adamant chainbody", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1113", + "name": "Rune chainbody", "examine": "A series of connected metal rings.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,63,72,78,-3,65,40,0,0,0,0", "durability": null, - "weight": "7.7", - "absorb": "2,0,4", "equipment_slot": "4", - "grand_exchange_price": "2731", - "name": "Adamant chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1111", - "bonuses": "0,0,0,-15,0,36,50,61,-3,38,30,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "2731", - "durability": null, - "name": "Adamant chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1112" - }, - { + "lendable": "true", "requirements": "{1,40}", "shop_price": "50000", - "ge_buy_limit": "100", - "examine": "A series of connected metal rings.", - "durability": null, - "weight": "6.8", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "grand_exchange_price": "29800", - "name": "Rune chainbody", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1113", - "bonuses": "0,0,0,-15,0,63,72,78,-3,65,40,0,0,0,0" + "weight": "6.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "29800", - "durability": null, + "id": "1114", "name": "Rune chainbody", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1114" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "560", - "ge_buy_limit": "500", - "examine": "Provides excellent protection.", - "durability": null, - "weight": "9.95", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "434", - "name": "Iron platebody", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1115", - "bonuses": "0,0,0,-30,-10,21,20,12,-6,20,5,0,0,0,0" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "434", - "durability": null, "name": "Iron platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1116" - }, - { - "shop_price": "160", - "ge_buy_limit": "500", "examine": "Provides excellent protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,21,20,12,-6,20,5,0,0,0,0", "durability": null, - "weight": "9.5", + "equip_audio": "2239", "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "36", - "name": "Bronze platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1117", - "bonuses": "0,0,0,-30,-10,15,14,9,-6,14,5,0,0,0,0" - }, - { "ge_buy_limit": "500", - "grand_exchange_price": "36", - "durability": null, - "name": "Bronze platebody", + "remove_sleeves": "true", + "shop_price": "560", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1118" + "weight": "9.95" }, { + "id": "1116", + "name": "Iron platebody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1117", + "name": "Bronze platebody", + "examine": "Provides excellent protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,15,14,9,-6,14,5,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "500", + "remove_sleeves": "true", + "shop_price": "160", + "tradeable": "true", + "weight": "9.5" + }, + { + "id": "1118", + "name": "Bronze platebody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1119", + "name": "Steel platebody", + "examine": "Provides excellent protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "500", + "remove_sleeves": "true", "requirements": "{1,5}", "shop_price": "2000", + "tradeable": "true", + "weight": "9.9" + }, + { + "id": "1120", + "name": "Steel platebody", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1121", + "name": "Mithril platebody", "examine": "Provides excellent protection.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,0,0,0", "durability": null, - "weight": "9.9", + "equip_audio": "2239", "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "1077", - "name": "Steel platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1119", - "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0" - }, - { "ge_buy_limit": "500", - "grand_exchange_price": "1077", - "durability": null, - "name": "Steel platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1120" - }, - { + "remove_sleeves": "true", "requirements": "{1,20}", "shop_price": "5200", + "tradeable": "true", + "weight": "8.6" + }, + { + "id": "1122", + "name": "Mithril platebody", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1123", + "name": "Adamant platebody", "examine": "Provides excellent protection.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0", "durability": null, - "weight": "8.6", - "absorb": "1,0,3", + "equip_audio": "2239", "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "2965", - "name": "Mithril platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1121", - "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,0,0,0" - }, - { "ge_buy_limit": "500", - "grand_exchange_price": "2965", - "durability": null, - "name": "Mithril platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1122" - }, - { + "remove_sleeves": "true", "requirements": "{1,30}", "shop_price": "16256", - "ge_buy_limit": "500", - "examine": "Provides excellent protection.", + "tradeable": "true", + "weight": "11" + }, + { + "id": "1124", + "name": "Adamant platebody", + "archery_ticket_price": "0", "durability": null, - "weight": "11", - "absorb": "2,0,4", + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1125", + "name": "Black platebody", + "examine": "Provides Excellent protection.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "9790", - "name": "Adamant platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1123", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0" - }, - { "ge_buy_limit": "500", - "grand_exchange_price": "9790", - "durability": null, - "name": "Adamant platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1124" - }, - { + "remove_sleeves": "true", "requirements": "{1,10}", "shop_price": "3840", - "ge_buy_limit": "500", - "examine": "Provides Excellent protection.", + "tradeable": "true", + "weight": "9.9" + }, + { + "id": "1126", + "name": "Black platebody", + "archery_ticket_price": "0", "durability": null, - "weight": "9.9", - "absorb": "1,0,2", + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1127", + "name": "Rune platebody", + "examine": "Provides excellent protection.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", + "ge_buy_limit": "100", + "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "4915", - "name": "Black platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1125", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "4915", - "durability": null, - "name": "Black platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1126" - }, - { "requirements": "{1,40}", "shop_price": "65000", - "ge_buy_limit": "100", - "examine": "Provides excellent protection.", - "durability": null, - "weight": "9.9", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "38800", - "name": "Rune platebody", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1127", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + "weight": "9.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "38800", - "durability": null, + "id": "1128", "name": "Rune platebody", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1128" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "20", - "ge_buy_limit": "1000", - "examine": "Better than no armour!", - "grand_exchange_price": "34", - "durability": null, - "name": "Leather body", - "tradeable": "true", - "weight": "2.7", - "archery_ticket_price": "0", "id": "1129", - "bonuses": "0,0,0,-2,2,8,9,10,4,9,5,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "34", - "durability": null, "name": "Leather body", - "tradeable": "true", + "examine": "Better than no armour!", "archery_ticket_price": "0", - "id": "1130" + "bonuses": "0,0,0,-2,2,8,9,10,4,9,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "1000", + "shop_price": "20", + "tradeable": "true", + "weight": "2.7" }, { + "id": "1130", + "name": "Leather body", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1131", + "name": "Hardleather body", + "examine": "Harder than normal leather.", + "absorb": "0,2,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-4,8,12,15,18,6,15,10,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "1000", "requirements": "{1,10}", "shop_price": "170", - "ge_buy_limit": "1000", - "examine": "Harder than normal leather.", + "tradeable": "true", + "weight": "3.6" + }, + { + "id": "1132", + "name": "Hardleather body", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1133", + "name": "Studded body", + "examine": "These studs should provide a bit more protection.", + "absorb": "0,3,1", + "archery_ticket_price": "150", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0", "durability": null, - "weight": "3.6", - "absorb": "0,2,1", "equipment_slot": "4", - "grand_exchange_price": "43", - "name": "Hardleather body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1131", - "bonuses": "0,0,0,-4,8,12,15,18,6,15,10,0,0,0,0" - }, - { "ge_buy_limit": "1000", - "grand_exchange_price": "43", - "durability": null, - "name": "Hardleather body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1132" - }, - { "requirements": "{1,20}-{4,20}", "shop_price": "850", - "ge_buy_limit": "1000", - "examine": "These studs should provide a bit more protection.", - "durability": null, - "weight": "5", - "absorb": "0,3,1", - "equipment_slot": "4", - "grand_exchange_price": "414", - "name": "Studded body", "tradeable": "true", - "archery_ticket_price": "150", - "id": "1133", - "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0" + "weight": "5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "414", - "durability": null, + "id": "1134", "name": "Studded body", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1134" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "1135", + "name": "Green d'hide body", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "2400", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "5000", + "lendable": "true", "requirements": "{1,40}-{4,40}", "shop_price": "7800", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", - "durability": null, - "weight": "6.8", - "absorb": "0,6,3", - "equipment_slot": "4", - "lendable": "true", - "grand_exchange_price": "4544", - "name": "Green d'hide body", "tradeable": "true", - "archery_ticket_price": "2400", - "id": "1135", - "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0" + "weight": "6.8" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "4544", - "durability": null, + "id": "1136", "name": "Green d'hide body", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1136" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "1137", + "name": "Iron med helm", + "examine": "A medium sized helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "shop_price": "84", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "1138", + "name": "Iron med helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1139", + "name": "Bronze med helm", "examine": "A medium sized helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,3,4,2,-1,3,0,0,0,0,0", "durability": null, - "weight": "1.8", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "22", - "name": "Iron med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1137", - "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "22", - "durability": null, - "name": "Iron med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1138" - }, - { "remove_head": "true", "shop_price": "24", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "1140", + "name": "Bronze med helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1141", + "name": "Steel med helm", "examine": "A medium sized helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,3,0,0,0,0", "durability": null, - "weight": "1.8", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "39", - "name": "Bronze med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1139", - "bonuses": "0,0,0,-3,-1,3,4,2,-1,3,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "39", - "durability": null, - "name": "Bronze med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1140" - }, - { "remove_head": "true", "requirements": "{1,5}", "shop_price": "300", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "1142", + "name": "Steel med helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1143", + "name": "Mithril med helm", "examine": "A medium sized helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,10,11,9,-1,10,5,0,0,0,0", "durability": null, - "weight": "1.8", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "52", - "name": "Steel med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1141", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,3,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "52", - "durability": null, - "name": "Steel med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1142" - }, - { "remove_head": "true", "requirements": "{1,20}", "shop_price": "780", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "1144", + "name": "Mithril med helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1145", + "name": "Adamant med helm", "examine": "A medium sized helmet.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0", "durability": null, - "weight": "1.3", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "272", - "name": "Mithril med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1143", - "bonuses": "0,0,0,-3,-1,10,11,9,-1,10,5,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "272", - "durability": null, - "name": "Mithril med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1144" - }, - { "remove_head": "true", "requirements": "{1,30}", "shop_price": "1920", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "1146", + "name": "Adamant med helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1147", + "name": "Rune med helm", "examine": "A medium sized helmet.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,22,23,21,-1,22,7,0,0,0,0", "durability": null, - "weight": "1.8", - "absorb": "1,0,2", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "1024", - "name": "Adamant med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1145", - "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1024", - "durability": null, - "name": "Adamant med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1146" - }, - { + "lendable": "true", "remove_head": "true", "requirements": "{1,40}", "shop_price": "19200", - "ge_buy_limit": "100", - "examine": "A medium sized helmet.", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "1148", + "name": "Rune med helm", + "archery_ticket_price": "0", "durability": null, - "weight": "1.8", - "absorb": "1,0,3", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1149", + "name": "Dragon med helm", + "examine": "Makes the wearer pretty intimidating.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "11400", - "name": "Rune med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1147", - "bonuses": "0,0,0,-3,-1,22,23,21,-1,22,7,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "11400", - "durability": null, - "name": "Rune med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1148" - }, - { + "lendable": "true", "remove_head": "true", "requirements": "{1,60}", - "ge_buy_limit": "100", - "examine": "Makes the wearer pretty intimidating.", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "1150", + "name": "Dragon med helm", + "archery_ticket_price": "0", "durability": null, - "weight": "1.3", - "absorb": "2,0,4", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1151", + "name": "Black med helm", + "examine": "A medium sized helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "60500", - "name": "Dragon med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1149", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "60500", - "durability": null, - "name": "Dragon med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1150" - }, - { "remove_head": "true", "requirements": "{1,10}", "shop_price": "530", - "ge_buy_limit": "100", - "examine": "A medium sized helmet.", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "1152", + "name": "Black med helm", + "archery_ticket_price": "0", "durability": null, - "weight": "1.8", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1153", + "name": "Iron full helm", + "examine": "A full face helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,6,7,5,-1,6,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "242", - "name": "Black med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1151", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,4,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "242", - "durability": null, - "name": "Black med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1152" - }, - { + "remove_beard": "true", "remove_head": "true", "shop_price": "61", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1154", + "name": "Iron full helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1155", + "name": "Bronze full helm", "examine": "A full face helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,4,5,3,-1,4,0,0,0,0,0", "durability": null, - "weight": "2.7", - "remove_beard": "true", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "56", - "name": "Iron full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1153", - "bonuses": "0,0,0,-6,-2,6,7,5,-1,6,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "56", - "durability": null, - "name": "Iron full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1154" - }, - { + "remove_beard": "true", "remove_head": "true", "shop_price": "44", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1156", + "name": "Bronze full helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1157", + "name": "Steel full helm", "examine": "A full face helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", "durability": null, - "weight": "2.7", - "remove_beard": "true", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "67", - "name": "Bronze full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1155", - "bonuses": "0,0,0,-6,-2,4,5,3,-1,4,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "67", - "durability": null, - "name": "Bronze full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1156" - }, - { + "remove_beard": "true", "remove_head": "true", "requirements": "{1,5}", "shop_price": "550", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1158", + "name": "Steel full helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1159", + "name": "Mithril full helm", "examine": "A full face helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,13,14,11,-1,13,5,0,0,0,0", "durability": null, - "weight": "2.7", - "remove_beard": "true", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "195", - "name": "Steel full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1157", - "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "195", - "durability": null, - "name": "Steel full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1158" - }, - { + "remove_beard": "true", "remove_head": "true", "requirements": "{1,20}", "shop_price": "1430", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "1160", + "name": "Mithril full helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1161", + "name": "Adamant full helm", "examine": "A full face helmet.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", "durability": null, - "weight": "2.2", - "remove_beard": "true", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "675", - "name": "Mithril full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1159", - "bonuses": "0,0,0,-6,-2,13,14,11,-1,13,5,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "675", - "durability": null, - "name": "Mithril full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1160" - }, - { + "remove_beard": "true", "remove_head": "true", "requirements": "{1,30}", "shop_price": "3520", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1162", + "name": "Adamant full helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1163", + "name": "Rune full helm", "examine": "A full face helmet.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", "durability": null, - "weight": "2.7", - "absorb": "1,0,2", - "remove_beard": "true", + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "1911", - "name": "Adamant full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1161", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1911", - "durability": null, - "name": "Adamant full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1162" - }, - { + "lendable": "true", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1164", + "name": "Rune full helm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1165", + "name": "Black full helm", "examine": "A full face helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", "durability": null, - "weight": "2.7", - "absorb": "1,0,3", - "remove_beard": "true", + "equip_audio": "2240", "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "20900", - "name": "Rune full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1163", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "20900", - "durability": null, - "name": "Rune full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1164" - }, - { + "remove_beard": "true", "remove_head": "true", "requirements": "{1,10}", "shop_price": "1372", - "ge_buy_limit": "100", - "examine": "A full face helmet.", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1166", + "name": "Black full helm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1167", + "name": "Leather cowl", + "examine": "Better than no armour!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,1,2,3,4,2,3,0,0,0,0,0", "durability": null, - "weight": "2.7", - "remove_beard": "true", "equipment_slot": "0", - "grand_exchange_price": "731", - "name": "Black full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1165", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "731", - "durability": null, - "name": "Black full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1166" - }, - { + "ge_buy_limit": "5000", "remove_head": "true", "shop_price": "24", - "ge_buy_limit": "5000", - "examine": "Better than no armour!", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1168", + "name": "Leather cowl", + "archery_ticket_price": "0", "durability": null, - "weight": "0.9", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1169", + "name": "Coif", + "examine": "Light weight head protection.", + "archery_ticket_price": "100", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,5,0,0,0,0", + "durability": null, + "equip_audio": "2238", "equipment_slot": "0", - "grand_exchange_price": "9", - "name": "Leather cowl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1167", - "bonuses": "0,0,0,0,1,2,3,4,2,3,0,0,0,0,0" - }, - { "ge_buy_limit": "5000", - "grand_exchange_price": "9", - "durability": null, - "name": "Leather cowl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1168" - }, - { "remove_head": "true", "requirements": "{4,20}", "shop_price": "200", - "ge_buy_limit": "5000", - "examine": "Light weight head protection.", - "durability": null, - "weight": "0.9", - "equipment_slot": "0", - "grand_exchange_price": "56", - "name": "Coif", "tradeable": "true", - "archery_ticket_price": "100", - "id": "1169", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,5,0,0,0,0" + "weight": "0.9" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "56", - "durability": null, + "id": "1170", "name": "Coif", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1170" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "A solid wooden shield.", - "grand_exchange_price": "483", - "durability": null, - "name": "Wooden shield", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1171", - "bonuses": "0,0,0,0,0,4,5,3,1,4,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "483", - "durability": null, "name": "Wooden shield", - "tradeable": "true", + "examine": "A solid wooden shield.", "archery_ticket_price": "0", - "id": "1172" + "bonuses": "0,0,0,0,0,4,5,3,1,4,0,0,0,0,0", + "durability": null, + "equip_audio": "2250", + "equipment_slot": "5", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true" }, { - "shop_price": "48", - "ge_buy_limit": "100", - "examine": "A medium square shield.", - "grand_exchange_price": "12", - "durability": null, - "name": "Bronze sq shield", - "tradeable": "true", - "weight": "3", + "id": "1172", + "name": "Wooden shield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1173", - "bonuses": "0,0,0,-6,-2,5,6,4,0,5,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12", - "durability": null, "name": "Bronze sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1174" - }, - { - "shop_price": "168", - "ge_buy_limit": "100", "examine": "A medium square shield.", - "grand_exchange_price": "39", - "durability": null, - "name": "Iron sq shield", - "tradeable": "true", - "weight": "3.6", "archery_ticket_price": "0", - "id": "1175", - "bonuses": "0,0,0,-6,-2,8,9,7,0,8,1,0,0,0,0", - "equipment_slot": "5" - }, - { + "bonuses": "0,0,0,-6,-2,5,6,4,0,5,0,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "ge_buy_limit": "100", - "grand_exchange_price": "39", - "durability": null, - "name": "Iron sq shield", + "shop_price": "48", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1176" + "weight": "3" }, { + "id": "1174", + "name": "Bronze sq shield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1175", + "name": "Iron sq shield", + "examine": "A medium square shield.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,8,9,7,0,8,1,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", + "shop_price": "168", + "tradeable": "true", + "weight": "3.6" + }, + { + "id": "1176", + "name": "Iron sq shield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1177", + "name": "Steel sq shield", + "examine": "A medium square shield.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,11,0,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", "requirements": "{1,5}", "shop_price": "600", + "tradeable": "true", + "weight": "3" + }, + { + "id": "1178", + "name": "Steel sq shield", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1179", + "name": "Black sq shield", "examine": "A medium square shield.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,15,16,14,0,15,9,0,0,0,0", "durability": null, - "weight": "3", + "equip_audio": "2245", "equipment_slot": "5", - "grand_exchange_price": "185", - "name": "Steel sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1177", - "bonuses": "0,0,0,-6,-2,12,13,11,0,12,4,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "185", - "durability": null, - "name": "Steel sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1178" - }, - { "requirements": "{1,10}", "shop_price": "1463", + "tradeable": "true", + "weight": "4" + }, + { + "id": "1180", + "name": "Black sq shield", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1181", + "name": "Mithril sq shield", "examine": "A medium square shield.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,17,19,15,0,17,18,0,0,0,0", "durability": null, - "weight": "4", - "absorb": "1,0,2", + "equip_audio": "2245", "equipment_slot": "5", - "grand_exchange_price": "511", - "name": "Black sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1179", - "bonuses": "0,0,0,-6,-2,15,16,14,0,15,9,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "511", - "durability": null, - "name": "Black sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1180" - }, - { "requirements": "{1,20}", "shop_price": "1560", - "ge_buy_limit": "100", - "examine": "A medium square shield.", - "durability": null, - "weight": "3.1", - "absorb": "2,0,4", - "equipment_slot": "5", - "grand_exchange_price": "744", - "name": "Mithril sq shield", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1181", - "bonuses": "0,0,0,-6,-2,17,19,15,0,17,18,0,0,0,0" + "weight": "3.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "744", - "durability": null, + "id": "1182", "name": "Mithril sq shield", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1182" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,30}", - "ge_buy_limit": "100", - "examine": "A medium square shield.", - "durability": null, - "weight": "4", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2136", - "name": "Adamant sq shield", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1183", - "bonuses": "0,0,0,-6,-2,24,26,22,0,24,25,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2136", - "durability": null, "name": "Adamant sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1184" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "100", "examine": "A medium square shield.", - "durability": null, - "weight": "3.64", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "22800", - "name": "Rune sq shield", - "tradeable": "true", + "absorb": "3,0,6", "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,24,26,22,0,24,25,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "4" + }, + { + "id": "1184", + "name": "Adamant sq shield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1185", - "bonuses": "0,0,0,-6,-2,38,40,36,0,38,35,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "22800", - "durability": null, "name": "Rune sq shield", - "tradeable": "true", + "examine": "A medium square shield.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "1186" - }, - { - "requirements": "{1,60}", - "ge_buy_limit": "10", - "examine": "An ancient and powerful looking Dragon Square shield.", + "bonuses": "0,0,0,-6,-2,38,40,36,0,38,35,0,0,0,0", "durability": null, - "weight": "3", - "absorb": "5,0,11", + "equip_audio": "2245", "equipment_slot": "5", + "ge_buy_limit": "100", "lendable": "true", - "grand_exchange_price": "431900", - "name": "Dragon sq shield", + "requirements": "{1,40}", "tradeable": "true", + "weight": "3.64" + }, + { + "id": "1186", + "name": "Rune sq shield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1187", - "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "431900", - "durability": null, "name": "Dragon sq shield", - "tradeable": "true", + "examine": "An ancient and powerful looking Dragon Square shield.", + "absorb": "5,0,11", "archery_ticket_price": "0", - "id": "1188" + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "10", + "lendable": "true", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "3" }, { - "shop_price": "86", - "ge_buy_limit": "100", - "examine": "A large metal shield.", - "grand_exchange_price": "18", - "durability": null, - "name": "Bronze kiteshield", - "tradeable": "true", - "weight": "5.4", + "id": "1188", + "name": "Dragon sq shield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "1189", - "bonuses": "0,0,0,-8,-2,5,7,6,-1,6,1,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "18", - "durability": null, "name": "Bronze kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1190" - }, - { - "shop_price": "233", - "ge_buy_limit": "100", "examine": "A large metal shield.", - "grand_exchange_price": "57", - "durability": null, - "name": "Iron kiteshield", - "tradeable": "true", - "weight": "5.4", "archery_ticket_price": "0", - "id": "1191", - "bonuses": "0,0,0,-8,-2,8,10,9,-1,9,2,0,0,0,0", - "equipment_slot": "5" - }, - { + "bonuses": "0,0,0,-8,-2,5,7,6,-1,6,1,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "ge_buy_limit": "100", - "grand_exchange_price": "57", - "durability": null, - "name": "Iron kiteshield", + "shop_price": "86", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1192" + "weight": "5.4" }, { + "id": "1190", + "name": "Bronze kiteshield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1191", + "name": "Iron kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,8,10,9,-1,9,2,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", + "shop_price": "233", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "1192", + "name": "Iron kiteshield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1193", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", "requirements": "{1,5}", "shop_price": "850", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "1194", + "name": "Steel kiteshield", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1195", + "name": "Black kiteshield", "examine": "A large metal shield.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", "durability": null, - "weight": "5.4", + "equip_audio": "2245", "equipment_slot": "5", - "grand_exchange_price": "354", - "name": "Steel kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1193", - "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "354", - "durability": null, - "name": "Steel kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1194" - }, - { "requirements": "{1,10}", "shop_price": "2121", - "ge_buy_limit": "100", - "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "3311", - "name": "Black kiteshield", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1195", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + "weight": "5.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3311", - "durability": null, + "id": "1196", "name": "Black kiteshield", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1196" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,20}", - "ge_buy_limit": "100", - "examine": "A large metal shield.", - "durability": null, - "weight": "4.5", - "absorb": "2,0,4", - "equipment_slot": "5", - "grand_exchange_price": "1128", - "name": "Mithril kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1197", - "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1128", - "durability": null, "name": "Mithril kiteshield", - "tradeable": "true", + "examine": "A large metal shield.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "1198" + "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,20}", + "tradeable": "true", + "weight": "4.5" }, { - "requirements": "{1,30}", - "ge_buy_limit": "100", - "examine": "A large metal shield.", - "durability": null, - "weight": "5.8", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "3066", - "name": "Adamant kiteshield", - "tradeable": "true", + "id": "1198", + "name": "Mithril kiteshield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1199", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3066", - "durability": null, "name": "Adamant kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1200" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "100", "examine": "A large metal shield.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", "durability": null, - "weight": "5.4", - "absorb": "3,0,7", + "equip_audio": "2245", "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "35600", - "name": "Rune kiteshield", + "ge_buy_limit": "100", + "requirements": "{1,30}", "tradeable": "true", + "weight": "5.8" + }, + { + "id": "1200", + "name": "Adamant kiteshield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1201", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "35600", - "durability": null, "name": "Rune kiteshield", - "tradeable": "true", + "examine": "A large metal shield.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "1202" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" }, { - "shop_price": "38", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "35", - "attack_audios": "2517,2517,2500,2517", - "name": "Iron dagger", - "tradeable": "true", + "id": "1202", + "name": "Rune kiteshield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1203", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "35", - "durability": null, "name": "Iron dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1204" - }, - { - "shop_price": "11", - "ge_buy_limit": "100", "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "400,400,401,400", - "grand_exchange_price": "105", "attack_audios": "2517,2517,2500,2517", - "name": "Bronze dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1205", - "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "105", - "durability": null, - "name": "Bronze dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1206" - }, - { - "requirements": "{0,5}", - "shop_price": "135", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", "defence_anim": "378", + "durability": null, + "equip_audio": "2248", "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "17", - "attack_audios": "2517,2517,2500,2517", - "name": "Steel dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1207", - "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "17", - "durability": null, - "name": "Steel dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1208" - }, - { - "requirements": "{0,20}", - "shop_price": "130", - "ge_buy_limit": "100", - "examine": "A dangerous dagger.", - "durability": null, - "weight": "0.3", - "attack_speed": "4", - "weapon_interface": "5", "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "71", - "attack_audios": "2517,2517,2500,2517", - "name": "Mithril dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1209", - "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "71", - "durability": null, - "name": "Mithril dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1210" - }, - { - "requirements": "{0,30}", - "shop_price": "816", - "ge_buy_limit": "100", - "examine": "Short and deadly.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "300", - "attack_audios": "2517,2517,2500,2517", - "name": "Adamant dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1211", - "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "300", - "durability": null, - "name": "Adamant dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1212" - }, - { - "requirements": "{0,40}", - "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "lendable": "true", - "grand_exchange_price": "4642", - "attack_audios": "2517,2517,2500,2517", - "name": "Rune dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1213", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4642", - "durability": null, - "name": "Rune dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1214" - }, - { - "requirements": "{0,60}", - "shop_price": "60000", - "ge_buy_limit": "10", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "396,396,395,396", - "lendable": "true", - "grand_exchange_price": "17700", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1215", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "17700", - "durability": null, - "name": "Dragon dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1216" - }, - { - "requirements": "{0,10}", - "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious black dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "79", - "attack_audios": "2517,2517,2500,2517", - "name": "Black dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1217", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "79", - "durability": null, - "name": "Black dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1218" - }, - { "shop_price": "38", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "56", - "attack_audios": "2517,2517,2500,2517", - "name": "Iron dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1219", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "56", + "id": "1204", + "name": "Iron dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Iron dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1220" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1205", + "name": "Bronze dagger", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "shop_price": "11", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "86", - "attack_audios": "2517,2517,2500,2517", - "name": "Bronze dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1221", - "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "86", + "id": "1206", + "name": "Bronze dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Bronze dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1222" + "equip_audio": "", + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1207", + "name": "Steel dagger", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,5}", "shop_price": "135", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "98", - "attack_audios": "2517,2517,2500,2517", - "name": "Steel dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1223", - "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "98", + "id": "1208", + "name": "Steel dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Steel dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1224" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1209", + "name": "Mithril dagger", + "examine": "A dangerous dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,20}", "shop_price": "130", - "ge_buy_limit": "100", - "examine": "A dangerous dagger.", - "durability": null, - "weight": "0.3", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "129", - "attack_audios": "2517,2517,2500,2517", - "name": "Mithril dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1225", - "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" + "weight": "0.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "129", + "id": "1210", + "name": "Mithril dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Mithril dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1226" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1211", + "name": "Adamant dagger", + "examine": "Short and deadly.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,30}", "shop_price": "816", - "ge_buy_limit": "100", - "examine": "Short and deadly.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "365", - "attack_audios": "2517,2517,2500,2517", - "name": "Adamant dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1227", - "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "365", + "id": "1212", + "name": "Adamant dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Adamant dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1228" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1213", + "name": "Rune dagger", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "2584", "requirements": "{0,40}", "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "lendable": "true", - "grand_exchange_price": "4831", - "attack_audios": "2517,2517,2500,2517", - "name": "Rune dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1229", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "4831", + "id": "1214", + "name": "Rune dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Rune dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1230" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1215", + "name": "Dragon dagger", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "2584", "requirements": "{0,60}", "shop_price": "60000", - "ge_buy_limit": "10", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "396,396,395,396", - "lendable": "true", - "grand_exchange_price": "17600", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1231", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "17600", + "id": "1216", + "name": "Dragon dagger", + "archery_ticket_price": "0", "durability": null, - "name": "Dragon dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1232" + "ge_buy_limit": "10", + "tradeable": "true" }, { + "id": "1217", + "name": "Black dagger", + "examine": "A vicious black dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,10}", "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious black dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "grand_exchange_price": "67", - "attack_audios": "2517,2517,2500,2517", - "name": "Black dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1233", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" + "weight": "0.4" }, { + "id": "1218", + "name": "Black dagger", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "67", - "durability": null, - "name": "Black dagger(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1234" + "tradeable": "true" }, { + "id": "1219", + "name": "Iron dagger(p)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "defence_anim": "378", "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "shop_price": "38", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1220", + "name": "Iron dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1221", + "name": "Bronze dagger(p)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "shop_price": "11", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1222", + "name": "Bronze dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1223", + "name": "Steel dagger(p)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,5}", + "shop_price": "135", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1224", + "name": "Steel dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1225", + "name": "Mithril dagger(p)", + "examine": "A dangerous dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,20}", + "shop_price": "130", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.3" + }, + { + "id": "1226", + "name": "Mithril dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1227", + "name": "Adamant dagger(p)", + "examine": "Short and deadly.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,30}", + "shop_price": "816", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1228", + "name": "Adamant dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1229", + "name": "Rune dagger(p)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "2584", + "requirements": "{0,40}", + "shop_price": "8000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1230", + "name": "Rune dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1231", + "name": "Dragon dagger(p)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "2584", + "requirements": "{0,60}", + "shop_price": "60000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1232", + "name": "Dragon dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "1233", + "name": "Black dagger(p)", + "examine": "A vicious black dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,10}", + "shop_price": "240", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "1234", + "name": "Black dagger(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1235", "name": "Poisoned dagger(p)", "archery_ticket_price": "0", - "id": "1235", + "durability": null, "render_anim": "2584" }, { - "durability": null, + "id": "1236", "name": "Poisoned dagger(p)", "archery_ticket_price": "0", - "id": "1236" + "durability": null }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "858", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "1237", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", - "shop_price": "26", - "durability": null, - "weight": "2.2", - "weapon_interface": "14", - "render_anim": "28", - "name": "Bronze spear" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "858", - "durability": null, "name": "Bronze spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1238" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "209", - "stand_anim": "813", - "tradeable": "true", - "name": "Iron spear", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1239", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "209", - "durability": null, - "name": "Iron spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1240" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "340", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1241", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", - "requirements": "{0,5}", - "durability": null, - "weight": "2.2", - "weapon_interface": "14", - "render_anim": "28", - "name": "Steel spear" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "340", - "durability": null, - "name": "Steel spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1242" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "353", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1243", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", - "requirements": "{0,20}", - "durability": null, - "weight": "1.8", - "weapon_interface": "14", - "render_anim": "28", - "name": "Mithril spear" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "353", - "durability": null, - "name": "Mithril spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1244" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "1191", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1245", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", - "requirements": "{0,30}", - "durability": null, - "weight": "2", - "weapon_interface": "14", - "render_anim": "28", - "name": "Adamant spear" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1191", - "durability": null, - "name": "Adamant spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1246" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "12200", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1247", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", - "requirements": "{0,40}", - "durability": null, - "weight": "2.2", - "weapon_interface": "14", - "render_anim": "28", - "lendable": "true", - "name": "Rune spear" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12200", - "durability": null, - "name": "Rune spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1248" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "A dragon tipped spear.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "37200", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1249", - "stand_turn_anim": "1209", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", - "requirements": "{0,60}", - "durability": null, - "weight": "2", - "weapon_interface": "14", - "render_anim": "28", - "lendable": "true", - "name": "Dragon spear" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "37200", - "durability": null, - "name": "Dragon spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1250", - "defence_anim": "2079" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", "examine": "A bronze tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "428,2081,429,428", - "grand_exchange_price": "389", - "stand_anim": "813", - "tradeable": "true", - "name": "Bronze spear(p)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1251", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "389", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "defence_anim": "2079", "durability": null, - "name": "Bronze spear(p)", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "26", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1252" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { + "id": "1238", + "name": "Bronze spear", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "turn90cw_anim": "1207", + "tradeable": "true" + }, + { + "id": "1239", + "name": "Iron spear", "examine": "An iron tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "428,2081,429,428", - "grand_exchange_price": "212", - "stand_anim": "813", - "tradeable": "true", - "name": "Iron spear(p)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1253", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "212", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "defence_anim": "2079", "durability": null, - "name": "Iron spear(p)", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1254" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "requirements": "{0,5}", + "id": "1240", + "name": "Iron spear", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "turn90cw_anim": "1207", + "tradeable": "true" + }, + { + "id": "1241", + "name": "Steel spear", "examine": "A steel tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "428,2081,429,428", - "grand_exchange_price": "136", - "stand_anim": "813", - "tradeable": "true", - "name": "Steel spear(p)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1255", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "136", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "defence_anim": "2079", "durability": null, - "name": "Steel spear(p)", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1256" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { + "id": "1242", + "name": "Steel spear", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "turn90cw_anim": "1207", + "tradeable": "true" + }, + { + "id": "1243", + "name": "Mithril spear", "examine": "A mithril tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "350", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", "archery_ticket_price": "0", - "id": "1257", - "stand_turn_anim": "1209", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", "requirements": "{0,20}", - "durability": null, - "weight": "1.8", - "weapon_interface": "14", - "render_anim": "28", - "name": "Mithril spear(p)" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "350", - "durability": null, - "name": "Mithril spear(p)", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1258" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" }, { + "id": "1244", + "name": "Mithril spear", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "turn90cw_anim": "1207", + "tradeable": "true" + }, + { + "id": "1245", + "name": "Adamant spear", "examine": "An adamant tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "1004", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", "archery_ticket_price": "0", - "id": "1259", - "stand_turn_anim": "1209", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", "requirements": "{0,30}", - "durability": null, - "weight": "2", - "weapon_interface": "14", - "render_anim": "28", - "name": "Adamant spear(p)" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1004", - "durability": null, - "name": "Adamant spear(p)", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1260" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" }, { + "id": "1246", + "name": "Adamant spear", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "turn90cw_anim": "1207", + "tradeable": "true" + }, + { + "id": "1247", + "name": "Rune spear", "examine": "A rune tipped spear.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "12400", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", "archery_ticket_price": "0", - "id": "1261", - "stand_turn_anim": "1209", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", - "requirements": "{0,40}", - "durability": null, - "weight": "2.2", - "weapon_interface": "14", - "render_anim": "28", - "lendable": "true", - "name": "Rune spear(p)" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12400", - "durability": null, - "name": "Rune spear(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1262" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "A dragon tipped spear.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "428,2081,429,428", - "grand_exchange_price": "39700", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1263", - "stand_turn_anim": "1209", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", - "requirements": "{0,60}", "durability": null, - "weight": "2", - "weapon_interface": "14", - "render_anim": "28", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", "lendable": "true", - "name": "Dragon spear(p)" + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { + "id": "1248", + "name": "Rune spear", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1249", + "name": "Dragon spear", + "examine": "A dragon tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", "ge_buy_limit": "10", - "grand_exchange_price": "39700", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "1250", + "name": "Dragon spear", + "archery_ticket_price": "0", + "defence_anim": "2079", "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "1251", + "name": "Bronze spear(p)", + "examine": "A bronze tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "1252", + "name": "Bronze spear(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1253", + "name": "Iron spear(p)", + "examine": "An iron tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "1254", + "name": "Iron spear(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1255", + "name": "Steel spear(p)", + "examine": "A steel tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "1256", + "name": "Steel spear(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1257", + "name": "Mithril spear(p)", + "examine": "A mithril tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "1258", + "name": "Mithril spear(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1259", + "name": "Adamant spear(p)", + "examine": "An adamant tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "1260", + "name": "Adamant spear(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1261", + "name": "Rune spear(p)", + "examine": "A rune tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "1262", + "name": "Rune spear(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1263", "name": "Dragon spear(p)", - "tradeable": "true", + "examine": "A dragon tipped spear.", "archery_ticket_price": "0", - "id": "1264" + "attack_anims": "428,2081,429,428", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" }, { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "Used for mining.", - "durability": null, - "weight": "2.25", - "attack_speed": "5", - "weapon_interface": "4", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "17", - "attack_audios": "2508,2508,2508,2508", - "name": "Bronze pickaxe", - "tradeable": "true", + "id": "1264", + "name": "Dragon spear(p)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "1265", - "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "17", - "durability": null, "name": "Bronze pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1266" - }, - { - "shop_price": "140", - "ge_buy_limit": "100", "examine": "Used for mining.", - "durability": null, - "weight": "2.25", - "attack_speed": "5", - "weapon_interface": "4", - "defence_anim": "403", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "401,401,400,401", - "grand_exchange_price": "200", "attack_audios": "2508,2508,2508,2508", - "name": "Iron pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1267", - "bonuses": "5,-2,3,0,0,0,1,0,0,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "200", + "attack_speed": "5", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0", + "defence_anim": "403", "durability": null, - "name": "Iron pickaxe", + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "1", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1268" + "weapon_interface": "4", + "weight": "2.25" }, { + "id": "1266", + "name": "Bronze pickaxe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1267", + "name": "Iron pickaxe", + "examine": "Used for mining.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,2508,2508", + "attack_speed": "5", + "bonuses": "5,-2,3,0,0,0,1,0,0,0,0,7,0,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "140", + "tradeable": "true", + "weapon_interface": "4", + "weight": "2.25" + }, + { + "id": "1268", + "name": "Iron pickaxe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1269", + "name": "Steel pickaxe", + "examine": "Used for mining.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,2508,2508", + "attack_speed": "5", + "bonuses": "8,-2,6,0,0,0,1,0,0,0,0,9,0,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,5}", "shop_price": "500", - "ge_buy_limit": "100", - "examine": "Used for mining.", - "durability": null, - "weight": "2.25", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "4", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "571", - "attack_audios": "2508,2508,2508,2508", - "name": "Steel pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1269", - "bonuses": "8,-2,6,0,0,0,1,0,0,0,0,9,0,0,0" + "weight": "2.25" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "571", + "id": "1270", + "name": "Steel pickaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Steel pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1270" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1271", + "name": "Adamant pickaxe", + "examine": "Used for mining.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,2508,2508", + "attack_speed": "5", + "bonuses": "17,-2,15,0,0,0,1,0,0,0,0,19,0,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,30}-{14,31}", "shop_price": "3200", - "ge_buy_limit": "100", - "examine": "Used for mining.", - "durability": null, - "weight": "2.7", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "4", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "1782", - "attack_audios": "2508,2508,2508,2508", - "name": "Adamant pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1271", - "bonuses": "17,-2,15,0,0,0,1,0,0,0,0,19,0,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1782", + "id": "1272", + "name": "Adamant pickaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Adamant pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1272" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1273", + "name": "Mithril pickaxe", + "examine": "Used for mining.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,2508,2508", + "attack_speed": "5", + "bonuses": "12,-2,10,0,0,0,1,0,0,0,0,13,0,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,20}", "shop_price": "1300", - "ge_buy_limit": "100", - "examine": "Used for mining.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "4", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "611", - "attack_audios": "2508,2508,2508,2508", - "name": "Mithril pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1273", - "bonuses": "12,-2,10,0,0,0,1,0,0,0,0,13,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "611", + "id": "1274", + "name": "Mithril pickaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Mithril pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1274" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1275", + "name": "Rune pickaxe", + "examine": "Used for mining.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,2508,2508", + "attack_speed": "5", + "bonuses": "26,-2,24,0,0,0,1,0,0,0,0,29,0,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", "requirements": "{0,40}-{14,41}", "shop_price": "32000", - "ge_buy_limit": "100", - "examine": "Used for mining.", - "durability": null, - "weight": "2.2", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "4", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "lendable": "true", - "grand_exchange_price": "19500", - "attack_audios": "2508,2508,2508,2508", - "name": "Rune pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1275", - "bonuses": "26,-2,24,0,0,0,1,0,0,0,0,29,0,0,0" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "19500", + "id": "1276", + "name": "Rune pickaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Rune pickaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1276" + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "13", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", "id": "1277", - "stand_turn_anim": "823", - "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", - "shop_price": "33", - "durability": null, - "weight": "1", - "weapon_interface": "5", - "render_anim": "1381", - "attack_audios": "2500,2500,2517,2500", - "name": "Bronze sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "13", - "durability": null, "name": "Bronze sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "1278" + "attack_anims": "381,381,390,381", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1381", + "run_anim": "824", + "shop_price": "33", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "17", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", + "id": "1278", + "name": "Bronze sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1279", - "stand_turn_anim": "823", - "bonuses": "6,4,-2,0,0,0,2,1,0,0,0,7,0,0,0", - "shop_price": "91", - "durability": null, - "weight": "1.8", - "weapon_interface": "5", - "render_anim": "1381", - "attack_audios": "2500,2500,2517,2500", - "name": "Iron sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "17", - "durability": null, "name": "Iron sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "1280" + "attack_anims": "381,381,390,381", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "6,4,-2,0,0,0,2,1,0,0,0,7,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1381", + "run_anim": "824", + "shop_price": "91", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "79", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", + "id": "1280", + "name": "Iron sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1281", - "stand_turn_anim": "823", - "bonuses": "11,8,-2,0,0,0,2,1,0,0,0,12,0,0,0", - "requirements": "{0,5}", - "shop_price": "412", - "durability": null, - "weight": "1", - "weapon_interface": "5", - "render_anim": "1381", - "attack_audios": "2500,2500,2517,2500", - "name": "Steel sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "79", - "durability": null, "name": "Steel sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "1282" + "attack_anims": "381,381,390,381", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "11,8,-2,0,0,0,2,1,0,0,0,12,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1381", + "requirements": "{0,5}", + "run_anim": "824", + "shop_price": "412", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "197", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", + "id": "1282", + "name": "Steel sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1283", - "stand_turn_anim": "823", - "bonuses": "14,10,-2,0,0,0,2,1,0,0,0,12,0,0,0", - "requirements": "{0,10}", - "shop_price": "624", - "durability": null, - "weight": "1", - "weapon_interface": "5", - "render_anim": "1381", - "attack_audios": "2500,2500,2517,2500", - "name": "Black sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "197", - "durability": null, "name": "Black sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "1284" + "attack_anims": "381,381,390,381", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "14,10,-2,0,0,0,2,1,0,0,0,12,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1381", + "requirements": "{0,10}", + "run_anim": "824", + "shop_price": "624", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "313", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", + "id": "1284", + "name": "Black sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1285", - "stand_turn_anim": "823", - "bonuses": "16,11,-2,0,0,0,2,1,0,0,0,17,0,0,0", - "requirements": "{0,20}", - "shop_price": "266", - "durability": null, - "weight": "1.5", - "weapon_interface": "5", - "render_anim": "1381", - "attack_audios": "2500,2500,2517,2500", - "name": "Mithril sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "313", - "durability": null, "name": "Mithril sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "1286" + "attack_anims": "381,381,390,381", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "16,11,-2,0,0,0,2,1,0,0,0,17,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1381", + "requirements": "{0,20}", + "run_anim": "824", + "shop_price": "266", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1.5" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "1046", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", + "id": "1286", + "name": "Mithril sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1287", - "stand_turn_anim": "823", - "bonuses": "23,18,-2,0,0,0,2,1,0,0,0,24,0,0,0", - "requirements": "{0,30}", - "shop_price": "2080", - "durability": null, - "weight": "1", - "weapon_interface": "5", - "render_anim": "1381", - "attack_audios": "2500,2500,2517,2500", - "name": "Adamant sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1046", - "durability": null, "name": "Adamant sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1288" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "381,381,390,381", - "grand_exchange_price": "12300", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "1289", - "stand_turn_anim": "823", - "bonuses": "38,26,-2,0,0,0,2,1,0,0,0,39,0,0,0", - "requirements": "{0,40}", - "shop_price": "20800", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "23,18,-2,0,0,0,2,1,0,0,0,24,0,0,0", + "defence_anim": "397", "durability": null, - "weight": "1.8", - "weapon_interface": "5", + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", "render_anim": "1381", - "lendable": "true", - "attack_audios": "2500,2500,2517,2500", - "name": "Rune sword" + "requirements": "{0,30}", + "run_anim": "824", + "shop_price": "2080", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "12300", + "id": "1288", + "name": "Adamant sword", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1289", "name": "Rune sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "1290" + "attack_anims": "381,381,390,381", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "4", + "bonuses": "38,26,-2,0,0,0,2,1,0,0,0,39,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "1381", + "requirements": "{0,40}", + "run_anim": "824", + "shop_price": "20800", + "stand_anim": "813", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "14", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1290", + "name": "Rune sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1291", - "stand_turn_anim": "823", - "bonuses": "4,5,-2,0,0,0,3,2,0,0,0,7,0,0,0", - "shop_price": "23", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Bronze longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "14", - "durability": null, "name": "Bronze longsword", - "tradeable": "true", + "examine": "A razor sharp longsword.", "archery_ticket_price": "0", - "id": "1292" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "4,5,-2,0,0,0,3,2,0,0,0,7,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "run_anim": "824", + "shop_price": "23", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "22", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1292", + "name": "Bronze longsword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1293", - "stand_turn_anim": "823", - "bonuses": "6,8,-2,0,0,0,3,2,0,0,0,10,0,0,0", - "shop_price": "177", - "durability": null, - "weight": "2", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Iron longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "22", - "durability": null, "name": "Iron longsword", - "tradeable": "true", + "examine": "A razor sharp longsword.", "archery_ticket_price": "0", - "id": "1294" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "6,8,-2,0,0,0,3,2,0,0,0,10,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "run_anim": "824", + "shop_price": "177", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "147", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1294", + "name": "Iron longsword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1295", - "stand_turn_anim": "823", - "bonuses": "9,14,-2,0,0,0,3,2,0,0,0,16,0,0,0", - "requirements": "{0,5}", - "shop_price": "500", - "durability": null, - "weight": "2", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Steel longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "147", - "durability": null, "name": "Steel longsword", - "tradeable": "true", + "examine": "A razor sharp longsword.", "archery_ticket_price": "0", - "id": "1296" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "9,14,-2,0,0,0,3,2,0,0,0,16,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,5}", + "run_anim": "824", + "shop_price": "500", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "384", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1296", + "name": "Steel longsword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1297", - "stand_turn_anim": "823", - "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,0,0,0", - "requirements": "{0,10}", - "shop_price": "960", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Black longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "384", - "durability": null, "name": "Black longsword", - "tradeable": "true", + "examine": "A razor sharp longsword.", "archery_ticket_price": "0", - "id": "1298" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,10}", + "run_anim": "824", + "shop_price": "960", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "602", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1298", + "name": "Black longsword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1299", - "stand_turn_anim": "823", - "bonuses": "15,20,-2,0,0,0,3,2,0,0,0,22,0,0,0", - "requirements": "{0,20}", - "shop_price": "1074", - "durability": null, - "weight": "1.5", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Mithril longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "602", - "durability": null, "name": "Mithril longsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1300" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "1808", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "15,20,-2,0,0,0,3,2,0,0,0,22,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,20}", + "run_anim": "824", + "shop_price": "1074", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.5" + }, + { + "id": "1300", + "name": "Mithril longsword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1301", - "stand_turn_anim": "823", - "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0", - "requirements": "{0,30}", - "shop_price": "3200", - "durability": null, - "weight": "2", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Adamant longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1808", - "durability": null, "name": "Adamant longsword", - "tradeable": "true", + "examine": "A razor sharp longsword.", "archery_ticket_price": "0", - "id": "1302" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,30}", + "run_anim": "824", + "shop_price": "3200", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "19000", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1302", + "name": "Adamant longsword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1303", - "stand_turn_anim": "823", - "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0", - "requirements": "{0,40}", - "shop_price": "32000", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "lendable": "true", - "attack_audios": "2500,2500,2517,2500", - "name": "Rune longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "19000", - "durability": null, "name": "Rune longsword", - "tradeable": "true", + "examine": "A razor sharp longsword", "archery_ticket_price": "0", - "id": "1304" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A very powerful sword.", - "walk_anim": "1146", - "has_special": "true", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", "attack_anims": "390,390,381,390", - "grand_exchange_price": "60200", - "stand_anim": "809", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1305", - "stand_turn_anim": "823", - "bonuses": "58,69,-2,0,0,0,3,2,0,0,0,71,0,0,0", - "requirements": "{0,60}", - "shop_price": "100000", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1426", - "lendable": "true", "attack_audios": "2500,2500,2517,2500", - "name": "Dragon longsword" + "attack_speed": "5", + "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "1", + "requirements": "{0,40}", + "run_anim": "824", + "shop_price": "32000", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "60200", + "id": "1304", + "name": "Rune longsword", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1305", "name": "Dragon longsword", - "tradeable": "true", + "examine": "A very powerful sword.", "archery_ticket_price": "0", - "id": "1306" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "58,69,-2,0,0,0,3,2,0,0,0,71,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "1426", + "requirements": "{0,60}", + "run_anim": "1210", + "shop_price": "100000", + "stand_anim": "809", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1146", + "weapon_interface": "6", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two-handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "89", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", + "id": "1306", + "name": "Dragon longsword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "1307", - "stand_turn_anim": "7040", - "bonuses": "-4,9,8,-4,0,0,0,0,0,-1,0,10,0,0,0", - "shop_price": "160", - "durability": null, - "weight": "3.6", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "Bronze 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "89", - "durability": null, "name": "Bronze 2h sword", - "tradeable": "true", + "examine": "A two-handed sword.", "archery_ticket_price": "0", - "id": "1308" + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,9,8,-4,0,0,0,0,0,-1,0,10,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "run_anim": "7039", + "shop_price": "160", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "32", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", + "id": "1308", + "name": "Bronze 2h sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1309", - "stand_turn_anim": "7040", - "bonuses": "-4,13,10,-4,0,0,0,0,0,-1,0,14,0,0,0", - "shop_price": "260", - "durability": null, - "weight": "3.6", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "Iron 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "32", - "durability": null, "name": "Iron 2h sword", - "tradeable": "true", + "examine": "A two handed sword.", "archery_ticket_price": "0", - "id": "1310" + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,13,10,-4,0,0,0,0,0,-1,0,14,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "run_anim": "7039", + "shop_price": "260", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "411", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", + "id": "1310", + "name": "Iron 2h sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1311", - "stand_turn_anim": "7040", - "bonuses": "-4,21,16,-4,0,0,0,0,0,-1,0,22,0,0,0", - "requirements": "{0,5}", - "shop_price": "1000", - "durability": null, - "weight": "3", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "Steel 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "411", - "durability": null, "name": "Steel 2h sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1312" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two-handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "1031", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "1313", - "stand_turn_anim": "7040", - "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,26,0,0,0", - "requirements": "{0,10}", - "shop_price": "2400", - "durability": null, - "weight": "3.6", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "Black 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1031", - "durability": null, - "name": "Black 2h sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1314" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two-handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "1396", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "1315", - "stand_turn_anim": "7040", - "bonuses": "-4,30,24,-4,0,0,0,0,0,-1,0,31,0,0,0", - "requirements": "{0,20}", - "shop_price": "3000", - "durability": null, - "weight": "3.1", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "Mithril 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1396", - "durability": null, - "name": "Mithril 2h sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1316" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two-handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "3577", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "1317", - "stand_turn_anim": "7040", - "bonuses": "-4,43,30,-4,0,0,0,0,0,-1,0,44,0,0,0", - "requirements": "{0,30}", - "shop_price": "6400", - "durability": null, - "weight": "4", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "Adamant 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3577", - "durability": null, - "name": "Adamant 2h sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1318" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", "examine": "A two handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "38200", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "1319", - "stand_turn_anim": "7040", - "bonuses": "-4,69,50,-4,0,0,0,0,0,-1,0,70,0,0,0", - "requirements": "{0,40}", - "shop_price": "40000", - "durability": null, - "weight": "3.6", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", "attack_audios": "2503,0,2504,0", - "name": "Rune 2h sword" + "attack_speed": "7", + "bonuses": "-4,21,16,-4,0,0,0,0,0,-1,0,22,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "requirements": "{0,5}", + "run_anim": "7039", + "shop_price": "1000", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "38200", + "id": "1312", + "name": "Steel 2h sword", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1313", + "name": "Black 2h sword", + "examine": "A two-handed sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,26,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "requirements": "{0,10}", + "run_anim": "7039", + "shop_price": "2400", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" + }, + { + "id": "1314", + "name": "Black 2h sword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1315", + "name": "Mithril 2h sword", + "examine": "A two-handed sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,30,24,-4,0,0,0,0,0,-1,0,31,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "requirements": "{0,20}", + "run_anim": "7039", + "shop_price": "3000", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.1" + }, + { + "id": "1316", + "name": "Mithril 2h sword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1317", + "name": "Adamant 2h sword", + "examine": "A two-handed sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,43,30,-4,0,0,0,0,0,-1,0,44,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "requirements": "{0,30}", + "run_anim": "7039", + "shop_price": "6400", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "4" + }, + { + "id": "1318", + "name": "Adamant 2h sword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1319", "name": "Rune 2h sword", - "tradeable": "true", + "examine": "A two handed sword.", "archery_ticket_price": "0", - "id": "1320" + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,69,50,-4,0,0,0,0,0,-1,0,70,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "124", + "requirements": "{0,40}", + "run_anim": "7039", + "shop_price": "40000", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "13", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1320", + "name": "Rune 2h sword", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1321", - "stand_turn_anim": "823", - "bonuses": "1,7,-2,0,0,0,1,0,0,0,0,6,0,0,0", - "shop_price": "40", - "durability": null, - "weight": "1", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,0,2517,0", - "name": "Bronze scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "13", - "durability": null, "name": "Bronze scimitar", - "tradeable": "true", + "examine": "A vicious, curved sword.", "archery_ticket_price": "0", - "id": "1322" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "1,7,-2,0,0,0,1,0,0,0,0,6,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "run_anim": "824", + "shop_price": "40", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "30", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1322", + "name": "Bronze scimitar", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1323", - "stand_turn_anim": "823", - "bonuses": "2,10,-2,0,0,0,1,0,0,0,0,9,0,0,0", - "shop_price": "112", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,0,2517,0", - "name": "Iron scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "30", - "durability": null, "name": "Iron scimitar", - "tradeable": "true", + "examine": "A vicious, curved sword.", "archery_ticket_price": "0", - "id": "1324" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "2,10,-2,0,0,0,1,0,0,0,0,9,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "run_anim": "824", + "shop_price": "112", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "101", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", + "id": "1324", + "name": "Iron scimitar", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1325", - "stand_turn_anim": "823", - "bonuses": "3,15,-2,0,0,0,1,0,0,0,0,14,0,0,0", - "requirements": "{0,5}", - "shop_price": "400", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,0,2517,0", - "name": "Steel scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "101", - "durability": null, "name": "Steel scimitar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1326" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "390,390,381,390", - "grand_exchange_price": "4498", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "1327", - "stand_turn_anim": "823", - "bonuses": "4,19,-2,0,0,0,1,0,0,0,0,14,0,0,0", - "requirements": "{0,10}", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", "attack_audios": "2500,0,2517,0", - "name": "Black scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4498", - "durability": null, - "name": "Black scimitar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1328" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", "attack_speed": "4", - "turn180_anim": "820", + "bonuses": "3,15,-2,0,0,0,1,0,0,0,0,14,0,0,0", "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "469", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "1329", - "stand_turn_anim": "823", - "bonuses": "5,21,-2,0,0,0,1,0,0,0,0,20,0,0,0", - "requirements": "{0,20}", - "shop_price": "1040", "durability": null, - "weight": "1.5", - "weapon_interface": "6", + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", "render_anim": "1", - "attack_audios": "2500,0,2517,0", - "name": "Mithril scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "469", - "durability": null, - "name": "Mithril scimitar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1330" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A viciously curved sword", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "1525", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "1331", - "stand_turn_anim": "823", - "bonuses": "6,29,-2,0,0,0,1,0,0,0,0,28,0,0,0", - "requirements": "{0,30}", - "shop_price": "2304", - "durability": null, - "weight": "2", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,0,2517,0", - "name": "Adamant scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1525", - "durability": null, - "name": "Adamant scimitar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1332" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "15200", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "1333", - "stand_turn_anim": "823", - "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0", - "requirements": "{0,40}", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "lendable": "true", - "attack_audios": "2500,0,2517,0", - "name": "Rune scimitar" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "15200", - "durability": null, - "name": "Rune scimitar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1334" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "20", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1335", - "stand_turn_anim": "823", - "bonuses": "-4,-4,11,-4,0,0,0,0,0,0,0,9,0,0,0", - "shop_price": "224", - "durability": null, - "weight": "1.8", - "weapon_interface": "10", - "render_anim": "1430", - "attack_audios": "2504,0,0,0", - "name": "Iron warhammer" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, - "name": "Iron warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1336" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "16", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1337", - "stand_turn_anim": "823", - "bonuses": "-4,-4,10,-4,0,0,0,0,0,0,0,8,0,0,0", - "shop_price": "59", - "durability": null, - "weight": "1", - "weapon_interface": "10", - "render_anim": "1430", - "attack_audios": "2504,0,0,0", - "name": "Bronze warhammer" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "16", - "durability": null, - "name": "Bronze warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1338" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "283", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1339", - "stand_turn_anim": "823", - "bonuses": "-4,-4,18,-4,0,0,0,0,0,0,0,16,0,0,0", "requirements": "{0,5}", - "shop_price": "832", - "durability": null, - "weight": "1", - "weapon_interface": "10", - "render_anim": "1430", - "attack_audios": "2504,0,0,0", - "name": "Steel warhammer" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "283", - "durability": null, - "name": "Steel warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1340" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "562", + "run_anim": "824", + "shop_price": "400", "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1341", "stand_turn_anim": "823", - "bonuses": "-4,-4,22,-4,0,0,0,0,0,0,0,19,0,0,0", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" + }, + { + "id": "1326", + "name": "Steel scimitar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1327", + "name": "Black scimitar", + "examine": "A vicious, curved sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "4,19,-2,0,0,0,1,0,0,0,0,14,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", "requirements": "{0,10}", - "shop_price": "1274", - "durability": null, - "weapon_interface": "10", - "render_anim": "1430", - "attack_audios": "2504,0,0,0", - "name": "Black warhammer" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "562", - "durability": null, - "name": "Black warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1342" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "1071", + "run_anim": "824", "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1343", "stand_turn_anim": "823", - "bonuses": "-4,-4,25,-4,0,0,0,0,0,0,0,20,0,0,0", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" + }, + { + "id": "1328", + "name": "Black scimitar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1329", + "name": "Mithril scimitar", + "examine": "A vicious, curved sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "5,21,-2,0,0,0,1,0,0,0,0,20,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", "requirements": "{0,20}", - "shop_price": "2158", - "durability": null, - "weight": "1.5", - "weapon_interface": "10", - "render_anim": "1430", - "attack_audios": "2504,0,0,0", - "name": "Mithril warhammer" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1071", - "durability": null, - "name": "Mithril warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1344" - }, - { - "ge_buy_limit": "1000", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "2996", + "run_anim": "824", + "shop_price": "1040", "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1345", "stand_turn_anim": "823", - "bonuses": "-4,-4,33,-4,0,0,0,0,0,0,0,31,0,0,0", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.5" + }, + { + "id": "1330", + "name": "Mithril scimitar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1331", + "name": "Adamant scimitar", + "examine": "A viciously curved sword", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "6,29,-2,0,0,0,1,0,0,0,0,28,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", "requirements": "{0,30}", - "shop_price": "5356", - "durability": null, - "weight": "2", - "weapon_interface": "10", - "render_anim": "1430", - "attack_audios": "2504,0,0,0", - "name": "Adamant warhammer" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2996", - "durability": null, - "name": "Adamant warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1346" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "I don't think it's intended for joinery.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "24600", + "run_anim": "824", + "shop_price": "2304", "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1347", "stand_turn_anim": "823", - "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", - "requirements": "{0,40}", - "shop_price": "41000", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "2" + }, + { + "id": "1332", + "name": "Adamant scimitar", + "archery_ticket_price": "0", "durability": null, - "weight": "1.8", - "weapon_interface": "10", - "render_anim": "1430", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1333", + "name": "Rune scimitar", + "examine": "A vicious, curved sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", "lendable": "true", + "render_anim": "1", + "requirements": "{0,40}", + "run_anim": "824", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" + }, + { + "id": "1334", + "name": "Rune scimitar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1335", + "name": "Iron warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", "attack_audios": "2504,0,0,0", - "name": "Rune warhammer" + "attack_speed": "6", + "bonuses": "-4,-4,11,-4,0,0,0,0,0,0,0,9,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1430", + "run_anim": "1210", + "shop_price": "224", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "24600", + "id": "1336", + "name": "Iron warhammer", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1337", + "name": "Bronze warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,10,-4,0,0,0,0,0,0,0,8,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1430", + "run_anim": "1210", + "shop_price": "59", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "1" + }, + { + "id": "1338", + "name": "Bronze warhammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1339", + "name": "Steel warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,18,-4,0,0,0,0,0,0,0,16,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1430", + "requirements": "{0,5}", + "run_anim": "1210", + "shop_price": "832", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "1" + }, + { + "id": "1340", + "name": "Steel warhammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1341", + "name": "Black warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,22,-4,0,0,0,0,0,0,0,19,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1430", + "requirements": "{0,10}", + "run_anim": "1210", + "shop_price": "1274", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10" + }, + { + "id": "1342", + "name": "Black warhammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1343", + "name": "Mithril warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,25,-4,0,0,0,0,0,0,0,20,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1430", + "requirements": "{0,20}", + "run_anim": "1210", + "shop_price": "2158", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "1.5" + }, + { + "id": "1344", + "name": "Mithril warhammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1345", + "name": "Adamant warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,33,-4,0,0,0,0,0,0,0,31,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "render_anim": "1430", + "requirements": "{0,30}", + "run_anim": "1210", + "shop_price": "5356", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "2" + }, + { + "id": "1346", + "name": "Adamant warhammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1347", "name": "Rune warhammer", - "tradeable": "true", + "examine": "I don't think it's intended for joinery.", "archery_ticket_price": "0", - "id": "1348" + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "1430", + "requirements": "{0,40}", + "run_anim": "1210", + "shop_price": "41000", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "1.8" }, { - "shop_price": "56", - "ge_buy_limit": "100", - "examine": "A woodcutter's axe.", - "durability": null, - "weight": "1.3", - "attack_speed": "5", - "weapon_interface": "2", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "8", - "attack_audios": "2498,2498,2497,2498", - "name": "Iron axe", - "tradeable": "true", + "id": "1348", + "name": "Rune warhammer", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1349", - "bonuses": "-2,5,3,0,0,0,1,0,0,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, "name": "Iron axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1350" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", "examine": "A woodcutter's axe.", - "durability": null, - "weight": "1.35", - "attack_speed": "5", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "395,395,401,395", - "grand_exchange_price": "44", "attack_audios": "2498,2498,2497,2498", - "name": "Bronze axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1351", - "bonuses": "-2,4,2,0,0,0,1,0,0,0,0,5,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "44", + "attack_speed": "5", + "bonuses": "-2,5,3,0,0,0,1,0,0,0,0,7,0,0,0", + "defence_anim": "397", "durability": null, - "name": "Bronze axe", + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "56", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1352" + "weapon_interface": "2", + "weight": "1.3" }, { + "id": "1350", + "name": "Iron axe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1351", + "name": "Bronze axe", + "examine": "A woodcutter's axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "5", + "bonuses": "-2,4,2,0,0,0,1,0,0,0,0,5,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", + "shop_price": "20", + "tradeable": "true", + "weapon_interface": "2", + "weight": "1.35" + }, + { + "id": "1352", + "name": "Bronze axe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1353", + "name": "Steel axe", + "examine": "A woodcutter's axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "5", + "bonuses": "-2,8,6,0,0,0,1,0,0,0,0,9,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,5}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "A woodcutter's axe.", - "durability": null, - "weight": "1.3", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "36", - "attack_audios": "2498,2498,2497,2498", - "name": "Steel axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1353", - "bonuses": "-2,8,6,0,0,0,1,0,0,0,0,9,0,0,0" + "weight": "1.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "36", + "id": "1354", + "name": "Steel axe", + "archery_ticket_price": "0", "durability": null, - "name": "Steel axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1354" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1355", + "name": "Mithril axe", + "examine": "A powerful axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "5", + "bonuses": "-2,12,10,0,0,0,1,0,0,0,0,13,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,20}", "shop_price": "660", - "ge_buy_limit": "100", - "examine": "A powerful axe.", - "durability": null, - "weight": "1.1", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "141", - "attack_audios": "2498,2498,2497,2498", - "name": "Mithril axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1355", - "bonuses": "-2,12,10,0,0,0,1,0,0,0,0,13,0,0,0" + "weight": "1.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "141", + "id": "1356", + "name": "Mithril axe", + "archery_ticket_price": "0", "durability": null, - "name": "Mithril axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1356" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1357", + "name": "Adamant axe", + "examine": "A powerful axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "5", + "bonuses": "-2,17,15,0,0,0,1,0,0,0,0,19,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,30}-{8,31}", "shop_price": "1625", - "ge_buy_limit": "100", - "examine": "A powerful axe.", - "durability": null, - "weight": "2", - "attack_speed": "5", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "592", - "attack_audios": "2498,2498,2497,2498", - "name": "Adamant axe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1357", - "bonuses": "-2,17,15,0,0,0,1,0,0,0,0,19,0,0,0" + "weapon_interface": "2", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "592", - "durability": null, + "id": "1358", "name": "Adamant axe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1358" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,40}-{8,41}", - "ge_buy_limit": "100", - "examine": "A powerful axe.", - "durability": null, - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "7495", - "attack_audios": "2498,2498,2497,2498", - "name": "Rune axe", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1359", - "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7495", - "durability": null, "name": "Rune axe", - "tradeable": "true", + "examine": "A powerful axe.", "archery_ticket_price": "0", - "id": "1360" + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", + "requirements": "{0,40}-{8,41}", + "tradeable": "true", + "weapon_interface": "2" }, { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "examine": "A sinister looking axe.", - "durability": null, - "weight": "2", - "attack_speed": "5", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "335", - "attack_audios": "2498,2498,2497,2498", - "name": "Black axe", - "tradeable": "true", + "id": "1360", + "name": "Rune axe", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1361", - "bonuses": "-2,10,8,0,0,0,1,0,0,0,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "335", - "durability": null, "name": "Black axe", - "tradeable": "true", + "examine": "A sinister looking axe.", "archery_ticket_price": "0", - "id": "1362" - }, - { - "shop_price": "182", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "2.7", - "attack_speed": "6", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", "attack_anims": "395,395,401,395", - "grand_exchange_price": "21", "attack_audios": "2498,2498,2497,2498", - "name": "Iron battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1363", - "bonuses": "-2,8,5,0,0,0,0,0,0,-1,0,13,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "21", + "attack_speed": "5", + "bonuses": "-2,10,8,0,0,0,1,0,0,0,0,12,0,0,0", + "defence_anim": "397", "durability": null, - "name": "Iron battleaxe", + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", + "requirements": "{0,10}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1364" + "weapon_interface": "2", + "weight": "2" }, { + "id": "1362", + "name": "Black axe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1363", + "name": "Iron battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,8,5,0,0,0,0,0,0,-1,0,13,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", + "shop_price": "182", + "tradeable": "true", + "weapon_interface": "2", + "weight": "2.7" + }, + { + "id": "1364", + "name": "Iron battleaxe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1365", + "name": "Steel battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,16,11,0,0,0,0,0,0,-1,0,20,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,5}", "shop_price": "650", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "2.7", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "208", - "attack_audios": "2498,2498,2497,2498", - "name": "Steel battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1365", - "bonuses": "-2,16,11,0,0,0,0,0,0,-1,0,20,0,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "208", + "id": "1366", + "name": "Steel battleaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Steel battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1366" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1367", + "name": "Black battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,20,15,0,0,0,0,0,0,-1,0,24,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,10}", "shop_price": "1248", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "2.7", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "556", - "attack_audios": "2498,2498,2497,2498", - "name": "Black battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1367", - "bonuses": "-2,20,15,0,0,0,0,0,0,-1,0,24,0,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "556", + "id": "1368", + "name": "Black battleaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Black battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1368" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1369", + "name": "Mithril battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,22,17,0,0,0,0,0,0,-1,0,29,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,20}", "shop_price": "1690", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "2", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "809", - "attack_audios": "2498,2498,2497,2498", - "name": "Mithril battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1369", - "bonuses": "-2,22,17,0,0,0,0,0,0,-1,0,29,0,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "809", + "id": "1370", + "name": "Mithril battleaxe", + "archery_ticket_price": "0", "durability": null, - "name": "Mithril battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1370" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1371", + "name": "Adamant battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,31,26,0,0,0,0,0,0,-1,0,41,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,30}", "shop_price": "4160", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "3", - "attack_speed": "6", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "2311", - "attack_audios": "2498,2498,2497,2498", - "name": "Adamant battleaxe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1371", - "bonuses": "-2,31,26,0,0,0,0,0,0,-1,0,41,0,0,0" + "weapon_interface": "2", + "weight": "3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2311", - "durability": null, + "id": "1372", "name": "Adamant battleaxe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1372" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "2", - "attack_speed": "6", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "lendable": "true", - "grand_exchange_price": "24800", - "attack_audios": "2498,2498,2497,2498", - "name": "Rune battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1373", - "bonuses": "-2,48,43,0,0,0,0,0,0,-1,0,64,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "24800", - "durability": null, "name": "Rune battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1374" - }, - { - "shop_price": "52", - "ge_buy_limit": "100", "examine": "A vicious looking axe.", - "durability": null, - "weight": "2.7", - "attack_speed": "6", - "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "395,395,401,395", - "grand_exchange_price": "15", "attack_audios": "2498,2498,2497,2498", - "name": "Bronze battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1375", - "bonuses": "-2,6,3,0,0,0,0,0,0,-1,0,9,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "15", + "attack_speed": "6", + "bonuses": "-2,48,43,0,0,0,0,0,0,-1,0,64,0,0,0", + "defence_anim": "397", "durability": null, - "name": "Bronze battleaxe", + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "2586", + "requirements": "{0,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1376" + "weapon_interface": "2", + "weight": "2" }, { + "id": "1374", + "name": "Rune battleaxe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1375", + "name": "Bronze battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,6,3,0,0,0,0,0,0,-1,0,9,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", + "shop_price": "52", + "tradeable": "true", + "weapon_interface": "2", + "weight": "2.7" + }, + { + "id": "1376", + "name": "Bronze battleaxe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1377", + "name": "Dragon battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "2586", "requirements": "{0,60}", "shop_price": "200000", - "ge_buy_limit": "10", - "examine": "A vicious looking axe.", - "has_special": "true", - "durability": null, - "weight": "2.7", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "lendable": "true", - "grand_exchange_price": "123200", - "attack_audios": "2498,2498,2497,2498", - "name": "Dragon battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1377", - "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0" + "weight": "2.7" }, { - "requirements": "{0,60}", - "ge_buy_limit": "10", - "grand_exchange_price": "123200", - "durability": null, - "name": "Dragon battleaxe", - "tradeable": "true", - "weight": "2.7", - "archery_ticket_price": "0", "id": "1378", - "defence_anim": "397" + "name": "Dragon battleaxe", + "archery_ticket_price": "0", + "defence_anim": "397", + "durability": null, + "ge_buy_limit": "10", + "requirements": "{0,60}", + "tradeable": "true", + "weight": "2.7" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "37", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "1379", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", - "shop_price": "15", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "37", - "durability": null, "name": "Staff", - "tradeable": "true", + "examine": "It's a slightly magical stick.", "archery_ticket_price": "0", - "id": "1380" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "15", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A Magical staff.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "784", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "1380", + "name": "Staff", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1381", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,10,0,2,3,1,10,0,0,3,0,0,0", - "shop_price": "1500", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Staff of air" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "784", - "durability": null, "name": "Staff of air", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1382" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", "examine": "A Magical staff.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "890", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", "archery_ticket_price": "0", - "id": "1383", - "stand_turn_anim": "1209", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", "bonuses": "0,-1,7,10,0,2,3,1,10,0,0,3,0,0,0", - "shop_price": "1500", + "defence_anim": "420", "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Staff of water" + "run_anim": "1210", + "shop_price": "1500", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "890", + "id": "1382", + "name": "Staff of air", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1383", "name": "Staff of water", - "tradeable": "true", + "examine": "A Magical staff.", "archery_ticket_price": "0", - "id": "1384" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "0,-1,7,10,0,2,3,1,10,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "1500", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A Magical staff.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "879", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "1384", + "name": "Staff of water", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1385", - "stand_turn_anim": "1209", - "bonuses": "1,-1,9,10,0,2,3,1,10,0,0,5,0,0,0", - "shop_price": "1500", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Staff of earth" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "879", - "durability": null, "name": "Staff of earth", - "tradeable": "true", + "examine": "A Magical staff.", "archery_ticket_price": "0", - "id": "1386" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "1,-1,9,10,0,2,3,1,10,0,0,5,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "1500", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A Magical staff.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "1330", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "1386", + "name": "Staff of earth", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1387", - "stand_turn_anim": "1209", - "bonuses": "3,-1,9,10,0,2,3,1,10,0,0,6,0,0,0", - "shop_price": "1500", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Staff of fire" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1330", - "durability": null, "name": "Staff of fire", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1388" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", "examine": "A Magical staff.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "58", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", "archery_ticket_price": "0", - "id": "1389", - "stand_turn_anim": "1209", - "bonuses": "2,-1,10,10,0,2,3,1,10,0,0,7,0,0,0", - "shop_price": "200", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "render_anim": "28", + "attack_anims": "419,419,419,419", "attack_audios": "2555,0,0,0", - "name": "Magic staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "58", - "durability": null, - "name": "Magic staff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1390" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", "attack_speed": "5", - "turn180_anim": "1206", + "bonuses": "3,-1,9,10,0,2,3,1,10,0,0,6,0,0,0", "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "7963", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1391", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,12,0,2,3,1,12,0,0,32,0,0,0", - "requirements": "{0,30}-{6,30}", - "shop_price": "7000", "durability": null, - "weight": "2.25", - "weapon_interface": "1", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Battlestaff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7963", - "durability": null, - "name": "Battlestaff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1392" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "9113", - "stand_anim": "813", - "tradeable": "true", "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1393", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", - "shop_price": "19600", - "durability": null, - "weight": "2.25", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Fire battlestaff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9113", - "durability": null, - "name": "Fire battlestaff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1394" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "9122", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1395", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Water battlestaff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9122", - "durability": null, - "name": "Water battlestaff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1396" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "8982", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1397", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", - "shop_price": "7000", - "durability": null, - "weight": "2.25", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Air battlestaff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8982", - "durability": null, - "name": "Air battlestaff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1398" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "9041", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1399", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", "shop_price": "1500", - "durability": null, - "weight": "2.2", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Earth battlestaff" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "9041", + "id": "1388", + "name": "Staff of fire", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1389", + "name": "Magic staff", + "examine": "A Magical staff.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "2,-1,10,10,0,2,3,1,10,0,0,7,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "200", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "1390", + "name": "Magic staff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1391", + "name": "Battlestaff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,25,12,0,2,3,1,12,0,0,32,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "shop_price": "7000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.25" + }, + { + "id": "1392", + "name": "Battlestaff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1393", + "name": "Fire battlestaff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "shop_price": "19600", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.25" + }, + { + "id": "1394", + "name": "Fire battlestaff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1395", + "name": "Water battlestaff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "1396", + "name": "Water battlestaff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1397", + "name": "Air battlestaff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "shop_price": "7000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.25" + }, + { + "id": "1398", + "name": "Air battlestaff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1399", "name": "Earth battlestaff", - "tradeable": "true", + "examine": "It's a slightly magical stick.", "archery_ticket_price": "0", - "id": "1400" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "shop_price": "1500", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "25400", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "1400", + "name": "Earth battlestaff", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1401", - "stand_turn_anim": "1209", - "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", - "requirements": "{0,40}-{6,40}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Mystic fire staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "25400", - "durability": null, "name": "Mystic fire staff", - "tradeable": "true", + "examine": "It's a slightly magical stick.", "archery_ticket_price": "0", - "id": "1402" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" }, { - "requirements": "{0,40}-{6,40}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "24800", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "tradeable": "true", - "name": "Mystic water staff", - "run_anim": "1210", + "id": "1402", + "name": "Mystic fire staff", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1403", - "stand_turn_anim": "1209", - "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "24800", - "durability": null, "name": "Mystic water staff", - "tradeable": "true", + "examine": "It's a slightly magical stick.", "archery_ticket_price": "0", - "id": "1404" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "25100", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "1404", + "name": "Mystic water staff", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "1405", - "stand_turn_anim": "1209", - "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", - "requirements": "{0,40}-{6,40}", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Mystic air staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "25100", - "durability": null, "name": "Mystic air staff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1406" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "25400", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", "archery_ticket_price": "0", - "id": "1407", - "stand_turn_anim": "1209", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", - "requirements": "{0,40}-{6,40}", - "shop_price": "40000", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Mystic earth staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "25400", - "durability": null, - "name": "Mystic earth staff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1408" - }, - { - "turn90cw_anim": "1207", - "examine": "An ancient staff, formerly the property of Iban.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", "defence_anim": "420", + "durability": null, + "equip_audio": "2247", "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Iban's staff", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", "run_anim": "1210", - "archery_ticket_price": "0", - "id": "1409", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0" + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "examine": "An ancient staff, formerly the property of Iban.", + "id": "1406", + "name": "Mystic air staff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1407", + "name": "Mystic earth staff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "defence_anim": "420", "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", + "run_anim": "1210", + "shop_price": "40000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "1408", + "name": "Mystic earth staff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1409", "name": "Iban's staff", - "weight": "2.2", + "examine": "An ancient staff, formerly the property of Iban.", "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", "attack_speed": "5", + "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { "id": "1410", - "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0" + "name": "Iban's staff", + "examine": "An ancient staff, formerly the property of Iban.", + "archery_ticket_price": "0", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0", + "durability": null, + "weight": "2.2" }, { - "durability": null, + "id": "1412", "name": "Farmer's fork", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1412" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "1413", "name": "Halberd", "archery_ticket_price": "0", "attack_speed": "7", - "id": "1413" + "durability": null }, { - "durability": null, + "id": "1414", "name": "Halberd", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1414" + "durability": null, + "tradeable": "true" }, { + "id": "1415", + "name": "Warhammer", + "archery_ticket_price": "0", "attack_audios": "2504,0,0,0", - "durability": null, - "name": "Warhammer", - "archery_ticket_price": "0", "attack_speed": "6", - "id": "1415" + "durability": null }, { - "durability": null, + "id": "1416", "name": "Warhammer", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1416" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "1417", "name": "Javelin", "archery_ticket_price": "0", "attack_speed": "6", - "id": "1417" + "durability": null }, { - "durability": null, + "id": "1418", "name": "Javelin", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1418" + "durability": null, + "tradeable": "true" }, { - "turn90cw_anim": "821", - "examine": "It's a Scythe.", - "walk_anim": "819", - "durability": null, - "weight": "3", - "turn90ccw_anim": "822", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "22", - "turn180_anim": "820", - "render_anim": "1383", - "defence_anim": "383", - "equipment_slot": "3", - "attack_anims": "382,382,382,382", - "stand_anim": "847", - "name": "Scythe", - "run_anim": "824", - "archery_ticket_price": "0", "id": "1419", + "name": "Scythe", + "examine": "It's a Scythe.", + "archery_ticket_price": "0", + "attack_anims": "440,440,438,382", + "attack_audios": "2524,2524,2522,2524", + "attack_speed": "7", + "bonuses": "3,8,3,0,0,0,3,1,0,0,0,10,0,0,0", + "defence_anim": "383", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "1383", + "run_anim": "824", + "stand_anim": "847", "stand_turn_anim": "823", - "bonuses": "3,8,3,0,0,0,3,1,0,0,0,10,0,0,0" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "two_handed": "true", + "walk_anim": "819", + "weapon_interface": "22", + "weight": "3" }, { - "shop_price": "80", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "7", - "name": "Iron mace", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1420", - "bonuses": "4,-2,9,0,0,0,0,0,0,0,0,7,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7", - "durability": null, "name": "Iron mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1421" - }, - { - "shop_price": "18", - "ge_buy_limit": "100", "examine": "A spiky mace.", - "durability": null, - "weight": "1.79", - "attack_speed": "5", - "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "401,401,400,401", - "grand_exchange_price": "12", - "name": "Bronze mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1422", - "bonuses": "1,-2,6,0,0,0,0,0,0,0,0,5,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "4,-2,9,0,0,0,0,0,0,0,0,7,1,0,0", + "defence_anim": "403", "durability": null, - "name": "Bronze mace", + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "80", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1423" + "weapon_interface": "8", + "weight": "1.8" }, { + "id": "1421", + "name": "Iron mace", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1422", + "name": "Bronze mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "1,-2,6,0,0,0,0,0,0,0,0,5,1,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "18", + "tradeable": "true", + "weapon_interface": "8", + "weight": "1.79" + }, + { + "id": "1423", + "name": "Bronze mace", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1424", + "name": "Steel mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "7,-2,13,0,0,0,0,0,0,0,0,11,2,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,5}", "shop_price": "225", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "1.79", - "attack_speed": "5", - "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "31", - "name": "Steel mace", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1424", - "bonuses": "7,-2,13,0,0,0,0,0,0,0,0,11,2,0,0" + "weapon_interface": "8", + "weight": "1.79" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "31", - "durability": null, + "id": "1425", "name": "Steel mace", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1425" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "1.79", - "attack_speed": "5", - "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "954", - "name": "Black mace", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1426", - "bonuses": "8,-2,16,0,0,0,0,0,0,0,0,13,2,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "954", - "durability": null, "name": "Black mace", - "tradeable": "true", + "examine": "A spiky mace.", "archery_ticket_price": "0", - "id": "1427" + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "8,-2,16,0,0,0,0,0,0,0,0,13,2,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{0,10}", + "tradeable": "true", + "weapon_interface": "8", + "weight": "1.79" }, { + "id": "1427", + "name": "Black mace", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1428", + "name": "Mithril mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "11,-2,18,0,0,0,0,0,0,0,0,16,3,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,20}", "shop_price": "585", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "1.5", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "157", - "name": "Mithril mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1428", - "bonuses": "11,-2,18,0,0,0,0,0,0,0,0,16,3,0,0" + "weight": "1.5" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "157", + "id": "1429", + "name": "Mithril mace", + "archery_ticket_price": "0", "durability": null, - "name": "Mithril mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1429" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1430", + "name": "Adamant mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "13,-2,25,0,0,0,0,0,0,0,0,23,3,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,30}", "shop_price": "1440", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "2", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "grand_exchange_price": "673", - "name": "Adamant mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1430", - "bonuses": "13,-2,25,0,0,0,0,0,0,0,0,23,3,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "673", + "id": "1431", + "name": "Adamant mace", + "archery_ticket_price": "0", "durability": null, - "name": "Adamant mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1431" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1432", + "name": "Rune mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,4,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", "requirements": "{0,40}", "shop_price": "14400", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "1.79", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "lendable": "true", - "grand_exchange_price": "8380", - "name": "Rune mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1432", - "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + "weight": "1.79" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8380", + "id": "1433", + "name": "Rune mace", + "archery_ticket_price": "0", "durability": null, - "name": "Rune mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1433" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "1434", + "name": "Dragon mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "40,-2,60,0,0,0,0,0,0,0,0,55,5,0,0", + "defence_anim": "403", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", "requirements": "{0,60}", "shop_price": "50000", - "ge_buy_limit": "10", - "examine": "A spiky mace.", - "has_special": "true", - "durability": null, - "weight": "1.8", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "8", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,400,401", - "lendable": "true", - "grand_exchange_price": "29300", - "name": "Dragon mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1434", - "bonuses": "40,-2,60,0,0,0,0,0,0,0,0,55,5,0,0" + "weight": "1.8" }, { - "requirements": "{0,60}", + "id": "1435", + "name": "Dragon mace", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "29300", - "durability": null, - "name": "Dragon mace", + "requirements": "{0,60}", "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "1435" + "weight": "1.8" }, { - "shop_price": "1", - "ge_buy_limit": "25000", + "id": "1436", + "name": "Rune essence", "examine": "An uncharged Rune Stone.", - "grand_exchange_price": "40", - "durability": null, - "name": "Rune essence", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1436" - }, - { + "durability": null, "ge_buy_limit": "25000", - "grand_exchange_price": "40", - "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "1437", "name": "Rune essence", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1437" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "shop_price": "50", - "ge_buy_limit": "500", + "id": "1438", + "name": "Air talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "404", - "durability": null, - "name": "Air talisman", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "1438" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "404", - "durability": null, - "name": "Air talisman", + "shop_price": "50", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1439" + "weight": "1" }, { + "id": "1439", + "name": "Air talisman", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1440", + "name": "Earth talisman", + "examine": "A mysterious power emanates from the talisman...", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", "requirements": "{9,20}", "shop_price": "50", + "tradeable": "true" + }, + { + "id": "1441", + "name": "Earth talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1442", + "name": "Fire talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "785", - "durability": null, - "name": "Earth talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1440" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "785", - "durability": null, - "name": "Earth talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1441" - }, - { "requirements": "{14,20}", "shop_price": "50", + "tradeable": "true" + }, + { + "id": "1443", + "name": "Fire talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1444", + "name": "Water talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "4140", - "durability": null, - "name": "Fire talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1442" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "4140", - "durability": null, - "name": "Fire talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1443" - }, - { "requirements": "{5,20}", "shop_price": "50", + "tradeable": "true" + }, + { + "id": "1445", + "name": "Water talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1446", + "name": "Body talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "7975", - "durability": null, - "name": "Water talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1444" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "7975", - "durability": null, - "name": "Water talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1445" - }, - { "requirements": "{20,20}", "shop_price": "50", + "tradeable": "true" + }, + { + "id": "1447", + "name": "Body talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1448", + "name": "Mind talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "1373", - "durability": null, - "name": "Body talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1446" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "1373", - "durability": null, - "name": "Body talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1447" - }, - { "requirements": "{2,20}", "shop_price": "50", + "tradeable": "true" + }, + { + "id": "1449", + "name": "Mind talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1450", + "name": "Blood talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "285", - "durability": null, - "name": "Mind talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1448" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "285", - "durability": null, - "name": "Mind talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1449" - }, - { "requirements": "{20,77}", + "tradeable": "true" + }, + { + "id": "1451", + "name": "Blood talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1452", + "name": "Chaos talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "3178", - "durability": null, - "name": "Blood talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1450" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "3178", - "durability": null, - "name": "Blood talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1451" - }, - { "requirements": "{20,35}", "shop_price": "125", + "tradeable": "true" + }, + { + "id": "1453", + "name": "Chaos talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1454", + "name": "Cosmic talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "605", - "durability": null, - "name": "Chaos talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1452" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "605", - "durability": null, - "name": "Chaos talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1453" - }, - { "requirements": "{20,27}", "shop_price": "125", + "tradeable": "true" + }, + { + "id": "1455", + "name": "Cosmic talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1456", + "name": "Death talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "785", - "durability": null, - "name": "Cosmic talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1454" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "785", - "durability": null, - "name": "Cosmic talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1455" - }, - { "requirements": "{20,65}", + "tradeable": "true" + }, + { + "id": "1457", + "name": "Death talisman", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1458", + "name": "Law talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "2501", - "durability": null, - "name": "Death talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1456" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "2501", - "durability": null, - "name": "Death talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1457" - }, - { "requirements": "{20,54}", "shop_price": "125", - "ge_buy_limit": "500", - "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "1219", - "durability": null, - "name": "Law talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1458" + "tradeable": "true" }, { - "ge_buy_limit": "500", - "grand_exchange_price": "1219", - "durability": null, + "id": "1459", "name": "Law talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1459" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "durability": null, + "id": "1461", "name": "Soul talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1461" + "durability": null, + "tradeable": "true" }, { + "id": "1462", + "name": "Nature talisman", + "examine": "A mysterious power emanates from the talisman...", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", "requirements": "{20,44}", "shop_price": "125", - "ge_buy_limit": "500", - "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "1596", - "durability": null, - "name": "Nature talisman", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1462" + "tradeable": "true" }, { - "ge_buy_limit": "500", - "grand_exchange_price": "1596", - "durability": null, + "id": "1463", "name": "Nature talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1463" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "I can exchange this for equipment.", - "grand_exchange_price": "9", - "durability": null, + "id": "1464", "name": "Archery ticket", - "tradeable": "true", + "examine": "I can exchange this for equipment.", "archery_ticket_price": "0", - "id": "1464" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "examine": "For use on daggers and projectiles.", - "grand_exchange_price": "36", - "durability": null, + "id": "1465", "name": "Weapon poison", - "tradeable": "true", + "examine": "For use on daggers and projectiles.", "archery_ticket_price": "0", - "id": "1465" + "durability": null, + "tradeable": "true" }, { - "examine": "Some damp wooden sticks.", - "durability": null, + "id": "1467", "name": "Damp sticks", + "examine": "Some damp wooden sticks.", "archery_ticket_price": "0", - "id": "1467" + "durability": null }, { - "examine": "Some dry wooden sticks.", - "durability": null, + "id": "1468", "name": "Dry sticks", + "examine": "Some dry wooden sticks.", "archery_ticket_price": "0", - "id": "1468" + "durability": null }, { - "examine": "Smashed glass.", - "durability": null, + "id": "1469", "name": "Broken glass", + "examine": "Smashed glass.", "archery_ticket_price": "0", - "id": "1469" + "durability": null }, { - "ge_buy_limit": "100", + "id": "1470", + "name": "Red bead", "examine": "A small round red bead.", - "grand_exchange_price": "169", - "durability": null, - "name": "Red bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1470" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "169", - "durability": null, + "id": "1471", "name": "Red bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1471" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "1472", + "name": "Yellow bead", "examine": "A small round yellow bead.", - "grand_exchange_price": "249", - "durability": null, - "name": "Yellow bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1472" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "249", - "durability": null, + "id": "1473", "name": "Yellow bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1473" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "1474", + "name": "Black bead", "examine": "A small round black bead.", - "grand_exchange_price": "229", - "durability": null, - "name": "Black bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1474" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "229", - "durability": null, + "id": "1475", "name": "Black bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1475" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "1476", + "name": "White bead", "examine": "A small round white bead.", - "grand_exchange_price": "1530", - "durability": null, - "name": "White bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1476" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1530", - "durability": null, + "id": "1477", "name": "White bead", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1477" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "1000", - "ge_buy_limit": "100", - "examine": "Wizard Mizgog sells these aim-enhancing amulets.", - "grand_exchange_price": "2870", - "durability": null, - "name": "Amulet of accuracy", - "tradeable": "true", - "archery_ticket_price": "0", "id": "1478", - "bonuses": "4,4,4,4,4,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2870", - "durability": null, "name": "Amulet of accuracy", - "tradeable": "true", + "examine": "Wizard Mizgog sells these aim-enhancing amulets.", "archery_ticket_price": "0", - "id": "1479" + "bonuses": "4,4,4,4,4,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "shop_price": "1000", + "tradeable": "true" }, { - "examine": "A magical sphere that glimmers within.", + "id": "1479", + "name": "Amulet of accuracy", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1480", + "name": "Rock", + "examine": "A chunk of rock." + }, + { + "id": "1481", "name": "Orb of light", - "weight": "5", - "archery_ticket_price": "0", - "id": "1481" - }, - { "examine": "A magical sphere that glimmers within.", - "durability": null, - "name": "Orb of light", - "weight": "5", "archery_ticket_price": "0", - "id": "1482" + "durability": null, + "weight": "5" }, { + "id": "1482", + "name": "Orb of light", "examine": "A magical sphere that glimmers within.", - "durability": null, - "name": "Orb of light", - "weight": "5", "archery_ticket_price": "0", - "id": "1483" + "durability": null, + "weight": "5" }, { + "id": "1483", + "name": "Orb of light", "examine": "A magical sphere that glimmers within.", - "durability": null, - "name": "Orb of light", - "weight": "5", "archery_ticket_price": "0", - "id": "1484" + "durability": null, + "weight": "5" }, { - "examine": "A damp, wet cloth.", + "id": "1484", + "name": "Orb of light", + "examine": "A magical sphere that glimmers within.", + "archery_ticket_price": "0", "durability": null, + "weight": "5" + }, + { + "id": "1485", "name": "Damp cloth", + "examine": "A damp, wet cloth.", "archery_ticket_price": "0", - "id": "1485" + "durability": null }, { - "examine": "A broken piece of railing.", - "durability": null, + "id": "1486", "name": "Piece of railing", - "weight": "2", + "examine": "A broken piece of railing.", "archery_ticket_price": "0", - "id": "1486" + "durability": null, + "weight": "2" }, { - "examine": "This horn has restorative properties.", - "grand_exchange_price": "1159", - "durability": null, + "id": "1487", "name": "Unicorn horn", + "examine": "This horn has restorative properties.", + "archery_ticket_price": "0", + "durability": null, "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1487" + "weight": "1" }, { - "examine": "A coat of arms of the Ardougne Paladins.", - "durability": null, + "id": "1488", "name": "Paladin's badge", - "archery_ticket_price": "0", - "id": "1488" - }, - { "examine": "A coat of arms of the Ardougne Paladins.", - "durability": null, - "name": "Paladin's badge", "archery_ticket_price": "0", - "id": "1489" + "durability": null }, { + "id": "1489", + "name": "Paladin's badge", "examine": "A coat of arms of the Ardougne Paladins.", - "durability": null, - "name": "Paladin's badge", "archery_ticket_price": "0", - "id": "1490" + "durability": null }, { - "examine": "On the ground: Curiosity has yet to kill this one...", - "durability": null, + "id": "1490", + "name": "Paladin's badge", + "examine": "A coat of arms of the Ardougne Paladins.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1491", "name": "Witch's cat", - "weight": "1.2", + "examine": "On the ground: Curiosity has yet to kill this one...", "archery_ticket_price": "0", - "id": "1491" + "durability": null, + "weight": "1.2" }, { - "examine": "A simple doll with Iban's likeness.", - "durability": null, + "id": "1492", "name": "Doll of iban", - "weight": "1", + "examine": "A simple doll with Iban's likeness.", "archery_ticket_price": "0", - "id": "1492" + "durability": null, + "weight": "1" }, { - "examine": "An account of the last times of someone.", - "durability": null, + "id": "1493", "name": "Old journal", + "examine": "An account of the last times of someone.", "archery_ticket_price": "0", - "id": "1493" + "durability": null }, { - "examine": "The tale of Iban.", - "durability": null, + "id": "1494", "name": "History of iban", - "weight": "0.2", + "examine": "The tale of Iban.", "archery_ticket_price": "0", - "id": "1494" + "durability": null, + "weight": "0.2" }, { - "shop_price": "5000", - "examine": "Strong dwarvish gloves.", - "durability": null, - "name": "Klank's gauntlets", - "weight": "0.2", - "archery_ticket_price": "0", "id": "1495", + "name": "Klank's gauntlets", + "examine": "Strong dwarvish gloves.", + "archery_ticket_price": "0", "bonuses": "2,2,2,0,0,8,9,7,0,0,5,2,0,0,0", - "equipment_slot": "9" + "durability": null, + "equipment_slot": "9", + "shop_price": "5000", + "weight": "0.2" }, { - "examine": "I thought you only saw these in pairs?", - "durability": null, + "id": "1496", "name": "Iban's dove", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "I thought you only saw these in pairs?", "archery_ticket_price": "0", - "id": "1496" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "A mystical demonic amulet.", - "durability": null, + "id": "1497", "name": "Amulet of othanian", + "examine": "A mystical demonic amulet.", "archery_ticket_price": "0", - "id": "1497" + "durability": null }, { - "examine": "A mystical demonic amulet.", - "durability": null, + "id": "1498", "name": "Amulet of doomion", - "archery_ticket_price": "0", - "id": "1498" - }, - { "examine": "A mystical demonic amulet.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1499", "name": "Amulet of holthion", + "examine": "A mystical demonic amulet.", "archery_ticket_price": "0", - "id": "1499" + "durability": null }, { - "examine": "A strange dark liquid.", - "durability": null, + "id": "1500", "name": "Iban's shadow", + "examine": "A strange dark liquid.", "archery_ticket_price": "0", - "id": "1500" + "durability": null, + "equip_audio": "" }, { - "examine": "Smells stronger than most spirits.", - "durability": null, + "id": "1501", "name": "Dwarf brew", + "examine": "Smells stronger than most spirits.", "archery_ticket_price": "0", - "id": "1501" + "durability": null }, { - "examine": "The burnt remains of Iban.", - "durability": null, + "id": "1502", "name": "Iban's ashes", - "weight": "0.056", + "examine": "The burnt remains of Iban.", "archery_ticket_price": "0", - "id": "1502" + "durability": null, + "weight": "0.056" }, { - "examine": "A search warrant for a house in West Ardougne.", - "durability": null, + "id": "1503", "name": "Warrant", + "examine": "A search warrant for a house in West Ardougne.", "archery_ticket_price": "0", - "id": "1503" + "durability": null }, { - "examine": "It doesn't look very tasty.", - "durability": null, + "id": "1504", "name": "Hangover cure", - "weight": "2", + "examine": "It doesn't look very tasty.", "archery_ticket_price": "0", - "id": "1504" + "durability": null, + "weight": "2" }, { - "examine": "Maybe I should read this...", - "durability": null, + "id": "1505", "name": "A magic scroll", + "examine": "Maybe I should read this...", "archery_ticket_price": "0", - "id": "1505" + "durability": null, + "tradeable": "false" }, { - "remove_head": "true", - "examine": "Stops me from breathing nasty stuff!", - "durability": null, - "name": "Gas mask", - "weight": "0.25", - "archery_ticket_price": "0", "id": "1506", + "name": "Gas mask", + "examine": "Stops me from breathing nasty stuff!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "weight": "0.25" }, { - "examine": "Quite a small key (Plague City).", - "durability": null, + "id": "1507", "name": "A small key", + "examine": "Quite a small key.", "archery_ticket_price": "0", - "id": "1507" + "durability": null }, { - "examine": "It seems to say \"hongorer lure\"...", - "durability": null, + "id": "1508", "name": "A scruffy note", + "examine": "It seems to say \"hongorer lure\"...", "archery_ticket_price": "0", - "id": "1508" + "durability": null }, { - "examine": "Turnip growing for beginners.", - "durability": null, + "id": "1509", "name": "Book", + "examine": "Turnip growing for beginners.", "archery_ticket_price": "0", - "id": "1509" + "durability": null }, { - "examine": "A picture of a lady called Elena.", - "durability": null, + "id": "1510", "name": "Picture", - "weight": "0.4", + "examine": "A picture of a lady called Elena.", "archery_ticket_price": "0", - "id": "1510" + "durability": null, + "weight": "0.4" }, { - "shop_price": "4", - "ge_buy_limit": "25000", + "id": "1511", + "name": "Logs", "examine": "A number of wooden logs.", - "grand_exchange_price": "120", - "durability": null, - "name": "Logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "1511" + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "4", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "279", - "durability": null, + "id": "1512", "name": "Logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1512" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "25000", + "id": "1513", + "name": "Magic logs", "examine": "Logs cut from a magic tree.", - "grand_exchange_price": "680", - "durability": null, - "name": "Magic logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "1513" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "1581", - "durability": null, + "id": "1514", "name": "Magic logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1514" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "25000", + "id": "1515", + "name": "Yew logs", "examine": "Logs cut from a yew tree.", - "grand_exchange_price": "320", - "durability": null, - "name": "Yew logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "1515" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "532", - "durability": null, + "id": "1516", "name": "Yew logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1516" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "25000", + "id": "1517", + "name": "Maple logs", "examine": "Logs cut from a maple tree.", - "grand_exchange_price": "160", - "durability": null, - "name": "Maple logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "1517" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "20", - "durability": null, + "id": "1518", "name": "Maple logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1518" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "25000", + "id": "1519", + "name": "Willow logs", "examine": "Logs cut from a willow tree.", - "grand_exchange_price": "80", - "durability": null, - "name": "Willow logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "1519" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "11", - "durability": null, + "id": "1520", "name": "Willow logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1520" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "25000", + "id": "1521", + "name": "Oak logs", "examine": "Logs cut from an Oak Tree.", - "grand_exchange_price": "140", - "durability": null, - "name": "Oak logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "1521" - }, - { + "durability": null, "ge_buy_limit": "25000", - "grand_exchange_price": "153", - "durability": null, + "tradeable": "true", + "weight": "2" + }, + { + "id": "1522", "name": "Oak logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1522" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "shop_price": "20", - "ge_buy_limit": "100", + "id": "1523", + "name": "Lockpick", "examine": "For picking tough locks.", - "grand_exchange_price": "1311", - "durability": null, - "name": "Lockpick", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1523" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1311", - "durability": null, - "name": "Lockpick", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1524" + "shop_price": "20", + "tradeable": "true" }, { - "examine": "I need to clean this herb before I can use it.", + "id": "1524", + "name": "Lockpick", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1525", "name": "Grimy snake weed", + "examine": "I need to clean this herb before I can use it.", "archery_ticket_price": "0", - "id": "1525" + "durability": null }, { - "examine": "A fresh herb.", - "durability": null, + "id": "1526", "name": "Clean snake weed", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "1526" + "durability": null }, { - "examine": "I need to clean this herb before I can use it.", - "durability": null, + "id": "1527", "name": "Grimy ardrigal", - "weight": "0.2", + "examine": "I need to clean this herb before I can use it.", "archery_ticket_price": "0", - "id": "1527" + "durability": null, + "weight": "0.2" }, { - "examine": "A fresh herb.", - "durability": null, + "id": "1528", "name": "Clean ardrigal", - "weight": "0.2", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "1528" + "durability": null, + "weight": "0.2" }, { - "examine": "I need to clean this herb before I can use it.", - "durability": null, + "id": "1529", "name": "Grimy sito foil", + "examine": "I need to clean this herb before I can use it.", "archery_ticket_price": "0", - "id": "1529" + "durability": null }, { - "examine": "A fresh herb.", - "durability": null, + "id": "1530", "name": "Clean sito foil", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "1530" + "durability": null }, { - "examine": "I need to clean this herb before I can use it.", - "durability": null, + "id": "1531", "name": "Grimy volencia moss", - "archery_ticket_price": "0", - "id": "1531" - }, - { - "examine": "A fresh herb.", - "durability": null, - "name": "Clean volencia moss", - "archery_ticket_price": "0", - "id": "1532" - }, - { "examine": "I need to clean this herb before I can use it.", - "durability": null, - "name": "Grimy rogue's purse", "archery_ticket_price": "0", - "id": "1533" + "durability": null }, { + "id": "1532", + "name": "Clean volencia moss", "examine": "A fresh herb.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1533", + "name": "Grimy rogue's purse", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1534", "name": "Clean rogue's purse", + "examine": "A fresh herb.", "archery_ticket_price": "0", - "id": "1534" + "durability": null }, { - "examine": "A piece of map.", - "durability": null, + "id": "1535", "name": "Map part", - "archery_ticket_price": "0", - "id": "1535" - }, - { "examine": "A piece of map.", - "durability": null, - "name": "Map part", "archery_ticket_price": "0", - "id": "1536" + "durability": null }, { + "id": "1536", + "name": "Map part", "examine": "A piece of map.", - "durability": null, - "name": "Map part", "archery_ticket_price": "0", - "id": "1537" + "durability": null }, { - "examine": "A map of the route to Crandor.", - "durability": null, + "id": "1537", + "name": "Map part", + "examine": "A piece of map.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1538", "name": "Crandor map", + "examine": "A map of the route to Crandor.", "archery_ticket_price": "0", - "id": "1538" + "durability": null }, { - "shop_price": "52", - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "59", - "durability": null, + "id": "1539", "name": "Steel nails", - "tradeable": "true", + "examine": "Keeps things in place fairly permanently.", "archery_ticket_price": "0", - "id": "1539" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "52", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "This provides partial protection from dragon-breath attacks.", - "grand_exchange_price": "637", - "durability": null, - "name": "Anti-dragon shield", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", "id": "1540", - "bonuses": "0,0,0,0,0,7,9,8,2,8,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "637", - "durability": null, "name": "Anti-dragon shield", - "tradeable": "true", + "examine": "This provides partial protection from dragon-breath attacks.", "archery_ticket_price": "0", - "id": "1541" + "bonuses": "0,0,0,0,0,7,9,8,2,8,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "5.4" }, { - "shop_price": "1", - "examine": "A key to Melzar's Maze.", + "id": "1541", + "name": "Anti-dragon shield", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1542", "name": "Maze key", + "examine": "A key to Melzar's Maze.", "archery_ticket_price": "0", - "id": "1542" + "durability": null, + "shop_price": "1" }, { - "destroy_message": "You can get another from Dr Harlow in the Blue Moon Inn of Varrock.", - "examine": "A very pointy stick.", - "durability": null, - "name": "Stake", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "1549", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "examine": "Deters vampires.", - "grand_exchange_price": "20", - "durability": null, - "name": "Garlic", - "tradeable": "true", + "name": "Stake", + "examine": "A very pointy stick.", "archery_ticket_price": "0", - "id": "1550" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, - "name": "Garlic", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1551" - }, - { - "examine": "Sardine flavoured with doogle leaves.", - "durability": null, - "name": "Doogle sardine", - "tradeable": "false", "destroy": "true", - "archery_ticket_price": "0", - "id": "1552" + "destroy_message": "You can get another from Dr Harlow in the Blue Moon Inn of Varrock.", + "durability": null, + "equipment_slot": "5", + "tradeable": "false" }, { - "examine": "This kitten seems to like you.", + "id": "1550", + "name": "Garlic", + "examine": "Deters vampires.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1551", + "name": "Garlic", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1552", + "name": "Doogle sardine", + "examine": "Sardine flavoured with doogle leaves.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1555", "name": "Pet kitten", - "archery_ticket_price": "0", - "id": "1555" - }, - { "examine": "This kitten seems to like you.", - "durability": null, - "name": "Pet kitten", "archery_ticket_price": "0", - "id": "1556" + "durability": null }, { + "id": "1556", + "name": "Pet kitten", "examine": "This kitten seems to like you.", - "durability": null, - "name": "Pet kitten", "archery_ticket_price": "0", - "id": "1557" + "durability": null }, { + "id": "1557", + "name": "Pet kitten", "examine": "This kitten seems to like you.", - "durability": null, - "name": "Pet kitten", "archery_ticket_price": "0", - "id": "1558" + "durability": null }, { + "id": "1558", + "name": "Pet kitten", "examine": "This kitten seems to like you.", - "durability": null, - "name": "Pet kitten", "archery_ticket_price": "0", - "id": "1559" + "durability": null }, { + "id": "1559", + "name": "Pet kitten", "examine": "This kitten seems to like you.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1560", "name": "Pet kitten", + "examine": "This kitten seems to like you.", "archery_ticket_price": "0", - "id": "1560" + "durability": null }, { - "examine": "This cat definitely likes you.", - "durability": null, + "id": "1561", "name": "Pet cat", - "archery_ticket_price": "0", - "id": "1561" - }, - { "examine": "This cat definitely likes you.", - "durability": null, - "name": "Pet cat", "archery_ticket_price": "0", - "id": "1562" + "durability": null }, { + "id": "1562", + "name": "Pet cat", "examine": "This cat definitely likes you.", - "durability": null, - "name": "Pet cat", "archery_ticket_price": "0", - "id": "1563" + "durability": null }, { + "id": "1563", + "name": "Pet cat", "examine": "This cat definitely likes you.", - "durability": null, - "name": "Pet cat", "archery_ticket_price": "0", - "id": "1564" + "durability": null }, { + "id": "1564", + "name": "Pet cat", "examine": "This cat definitely likes you.", - "durability": null, - "name": "Pet cat", "archery_ticket_price": "0", - "id": "1565" + "durability": null }, { + "id": "1565", + "name": "Pet cat", "examine": "This cat definitely likes you.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1566", "name": "Pet cat", + "examine": "This cat definitely likes you.", "archery_ticket_price": "0", - "id": "1566" + "durability": null }, { - "examine": "This cat is so well fed it can hardly move.", - "durability": null, + "id": "1567", "name": "Overgrown cat", - "archery_ticket_price": "0", - "id": "1567" - }, - { "examine": "This cat is so well fed it can hardly move.", - "durability": null, - "name": "Overgrown cat", "archery_ticket_price": "0", - "id": "1568" + "durability": null }, { + "id": "1568", + "name": "Overgrown cat", "examine": "This cat is so well fed it can hardly move.", - "durability": null, - "name": "Overgrown cat", "archery_ticket_price": "0", - "id": "1569" + "durability": null }, { + "id": "1569", + "name": "Overgrown cat", "examine": "This cat is so well fed it can hardly move.", - "durability": null, - "name": "Overgrown cat", "archery_ticket_price": "0", - "id": "1570" + "durability": null }, { + "id": "1570", + "name": "Overgrown cat", "examine": "This cat is so well fed it can hardly move.", - "durability": null, - "name": "Overgrown cat", "archery_ticket_price": "0", - "id": "1571" + "durability": null }, { + "id": "1571", + "name": "Overgrown cat", "examine": "This cat is so well fed it can hardly move.", - "durability": null, - "name": "Overgrown cat", "archery_ticket_price": "0", - "id": "1572" + "durability": null }, { - "examine": "A tasty herb good for seasoning.", - "durability": null, + "id": "1572", + "name": "Overgrown cat", + "examine": "This cat is so well fed it can hardly move.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1573", "name": "Doogle leaves", + "examine": "A tasty herb good for seasoning.", "archery_ticket_price": "0", - "id": "1573" + "durability": null }, { - "examine": "For feline training expertise.", - "durability": null, - "name": "Cat training medal", - "archery_ticket_price": "0", "id": "1575", + "name": "Cat training medal", + "examine": "For feline training expertise.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { + "id": "1577", + "name": "Pete's candlestick", "examine": "Candlestick used during Heroes' Quest.", - "durability": null, - "name": "Pete's candlestick", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1577" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "1578", "name": "Pete's candlestick", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1578" + "durability": null, + "tradeable": "true" }, { - "examine": "This denotes a Master Thief.", - "durability": null, + "id": "1579", "name": "Thieves' armband", + "examine": "This denotes a Master Thief.", "archery_ticket_price": "0", - "id": "1579" + "durability": null }, { - "examine": "These will keep my hands cold!", - "durability": null, - "name": "Ice gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "1580", + "name": "Ice gloves", + "examine": "These will keep my hands cold!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,3,4,0,2,2,0,0,0,0", - "equipment_slot": "9" + "durability": null, + "equipment_slot": "9", + "weight": "0.2" }, { - "examine": "Yuck.", - "durability": null, + "id": "1581", "name": "Blamish snail slime", - "weight": "1", + "examine": "Yuck.", "archery_ticket_price": "0", - "id": "1581" + "durability": null, + "weight": "1" }, { - "examine": "Made from the finest snail slime.", - "durability": null, + "id": "1582", "name": "Blamish oil", + "examine": "Made from the finest snail slime.", "archery_ticket_price": "0", - "id": "1582" + "durability": null }, { - "examine": "Firebird feather.", - "durability": null, + "id": "1583", "name": "Fire feather", + "examine": "Firebird feather.", "archery_ticket_price": "0", - "id": "1583" + "durability": null }, { - "examine": "Apparently my name is Hartigan", - "durability": null, + "id": "1584", "name": "Id papers", - "tradeable": "false", + "examine": "Apparently my name is Hartigen.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "1584" + "durability": null, + "tradeable": "false" }, { - "examine": "Useful for catching lava eels.", - "durability": null, + "id": "1585", "name": "Oily fishing rod", - "weight": "1", + "examine": "Useful for catching lava eels.", "archery_ticket_price": "0", - "id": "1585" + "durability": null, + "weight": "1" }, { + "id": "1586", + "name": "Miscellaneous key", "examine": "This is of use in completing Heroes' Quest. (Heroes' Quest)", - "durability": null, - "name": "Miscellaneous key", - "tradeable": "true", - "weight": "0.01", "archery_ticket_price": "0", - "id": "1586" + "durability": null, + "tradeable": "true", + "weight": "0.01" }, { - "durability": null, + "id": "1587", "name": "Miscellaneous key", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1587" + "durability": null, + "tradeable": "true" }, { - "examine": "The key I got from Grip. (Heroes' Quest)", - "durability": null, + "id": "1588", "name": "Grips' key ring", + "examine": "The key I got from Grip. (Heroes' Quest)", "archery_ticket_price": "0", - "id": "1588" + "durability": null }, { - "shop_price": "1", - "examine": "I wonder what this unlocks. (Heroes' Quest)", - "durability": null, + "id": "1590", "name": "Dusty key", + "examine": "I wonder what this unlocks. (Heroes' Quest)", "archery_ticket_price": "0", - "id": "1590" + "durability": null, + "shop_price": "1" }, { - "examine": "Key to a cell. (Heroes' Quest)", - "durability": null, + "id": "1591", "name": "Jail key", + "examine": "Key to a cell. (Heroes' Quest)", "archery_ticket_price": "0", - "id": "1591" + "durability": null }, { - "shop_price": "5", - "ge_buy_limit": "100", + "id": "1592", + "name": "Ring mould", "examine": "Used to make gold rings.", - "grand_exchange_price": "316", - "durability": null, - "name": "Ring mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "1592" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "316", - "durability": null, - "name": "Ring mould", + "shop_price": "5", "tradeable": "true", - "archery_ticket_price": "0", - "id": "1593" + "weight": "0.4" }, { - "examine": "Used to make unholy symbols.", + "id": "1593", + "name": "Ring mould", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1594", "name": "Unholy mould", + "examine": "Used to make unholy symbols.", "archery_ticket_price": "0", - "id": "1594" + "durability": null }, { - "shop_price": "5", - "ge_buy_limit": "100", + "id": "1595", + "name": "Amulet mould", "examine": "Used to make gold amulets.", - "grand_exchange_price": "288", - "durability": null, - "name": "Amulet mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "1595" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "288", - "durability": null, - "name": "Amulet mould", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1596" - }, - { "shop_price": "5", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1596", + "name": "Amulet mould", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1597", + "name": "Necklace mould", "examine": "Used to make gold necklaces.", - "grand_exchange_price": "269", - "durability": null, - "name": "Necklace mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "1597" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "269", - "durability": null, - "name": "Necklace mould", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1598" - }, - { "shop_price": "5", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1598", + "name": "Necklace mould", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1599", + "name": "Holy mould", "examine": "Used to make holy symbols of Saradomin.", - "grand_exchange_price": "504", - "durability": null, - "name": "Holy mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "1599" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "504", - "durability": null, + "shop_price": "5", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1600", "name": "Holy mould", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1600" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "500", + "id": "1601", + "name": "Diamond", "examine": "This looks valuable.", - "grand_exchange_price": "14800", - "durability": null, - "name": "Diamond", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1601" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "14800", - "durability": null, - "name": "Diamond", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1602" + "tradeable": "true" }, { + "id": "1602", + "name": "Diamond", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1603", + "name": "Ruby", + "examine": "This looks valuable.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", "shop_price": "400", + "tradeable": "true" + }, + { + "id": "1604", + "name": "Ruby", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1605", + "name": "Emerald", "examine": "This looks valuable.", - "grand_exchange_price": "1598", - "durability": null, - "name": "Ruby", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1603" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "1598", - "durability": null, - "name": "Ruby", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1604" - }, - { "shop_price": "350", + "tradeable": "true" + }, + { + "id": "1606", + "name": "Emerald", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1607", + "name": "Sapphire", "examine": "This looks valuable.", - "grand_exchange_price": "853", - "durability": null, - "name": "Emerald", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1605" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "853", - "durability": null, - "name": "Emerald", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1606" - }, - { "shop_price": "175", - "ge_buy_limit": "1000", - "examine": "This looks valuable.", - "grand_exchange_price": "520", - "durability": null, - "name": "Sapphire", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1607" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "520", - "durability": null, + "id": "1608", "name": "Sapphire", - "tradeable": "true", "archery_ticket_price": "0", - "id": "1608" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "1609", + "name": "Opal", + "examine": "A semi precious stone.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", "shop_price": "100", - "examine": "A semi precious stone.", - "grand_exchange_price": "44", - "durability": null, - "name": "Opal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1609" + "tradeable": "true" }, { + "id": "1610", + "name": "Opal", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "41", - "durability": null, - "name": "Opal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1610" + "tradeable": "true" }, { + "id": "1611", + "name": "Jade", + "examine": "A semi precious stone.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", "shop_price": "150", - "grand_exchange_price": "84", - "examine": "A semi precious stone.", - "durability": null, - "name": "Jade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1611" + "tradeable": "true" }, { + "id": "1612", + "name": "Jade", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "83", - "durability": null, - "name": "Jade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1612" + "tradeable": "true" }, { + "id": "1613", + "name": "Red topaz", + "examine": "A semi precious stone.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", "shop_price": "200", - "examine": "A semi precious stone.", - "grand_exchange_price": "120", - "durability": null, - "name": "Red topaz", "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "1613" + "weight": "0.2" }, { + "id": "1614", + "name": "Red topaz", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "103", - "durability": null, - "name": "Red topaz", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1614" + "tradeable": "true" }, { - "shop_price": "75000", - "ge_buy_limit": "100", + "id": "1615", + "name": "Dragonstone", "examine": "This looks valuable.", - "grand_exchange_price": "27400", - "durability": null, - "name": "Dragonstone", - "tradeable": "true", - "weight": "0.3", "archery_ticket_price": "0", - "id": "1615" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "27400", - "durability": null, - "name": "Dragonstone", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1616" - }, - { - "ge_buy_limit": "500", - "examine": "An uncut diamond.", - "grand_exchange_price": "2160", - "tokkul_price": "300", - "durability": null, - "name": "Uncut diamond", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1617" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "20000", - "durability": null, - "name": "Uncut diamond", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1618" - }, - { - "ge_buy_limit": "1000", - "examine": "An uncut ruby.", - "grand_exchange_price": "1140", - "tokkul_price": "150", - "durability": null, - "name": "Uncut ruby", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1619" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "4970", - "durability": null, - "name": "Uncut ruby", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1620" - }, - { - "shop_price": "50", - "ge_buy_limit": "1000", - "examine": "An uncut emerald.", - "grand_exchange_price": "580", - "tokkul_price": "75", - "durability": null, - "name": "Uncut emerald", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1621" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2621", - "durability": null, - "name": "Uncut emerald", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1622" - }, - { - "shop_price": "25", - "ge_buy_limit": "1000", - "examine": "An uncut sapphire.", - "grand_exchange_price": "420", - "tokkul_price": "37", - "durability": null, - "name": "Uncut sapphire", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1623" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1851", - "durability": null, - "name": "Uncut sapphire", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1624" - }, - { - "ge_buy_limit": "1000", - "examine": "An uncut opal.", - "grand_exchange_price": "65", - "durability": null, - "name": "Uncut opal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1625" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "65", - "durability": null, - "name": "Uncut opal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1626" - }, - { - "ge_buy_limit": "1000", - "examine": "An uncut jade.", - "grand_exchange_price": "138", - "durability": null, - "name": "Uncut jade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1627" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "138", - "durability": null, - "name": "Uncut jade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1628" - }, - { - "ge_buy_limit": "1000", - "examine": "An uncut red topaz.", - "grand_exchange_price": "279", - "durability": null, - "name": "Uncut red topaz", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "1629" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "279", - "durability": null, - "name": "Uncut red topaz", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1630" - }, - { "shop_price": "75000", - "ge_buy_limit": "100", - "examine": "An uncut dragonstone.", - "grand_exchange_price": "31700", - "tokkul_price": "1500", - "durability": null, - "name": "Uncut dragonstone", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1631" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "31700", - "durability": null, - "name": "Uncut dragonstone", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1632" - }, - { - "examine": "This gem is crushed and broken.", - "durability": null, - "name": "Crushed gem", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1633" - }, - { - "durability": null, - "name": "Crushed gem", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1634" - }, - { - "ge_buy_limit": "5000", - "examine": "A valuable ring.", - "grand_exchange_price": "165", - "durability": null, - "name": "Gold ring", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "id": "1635", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "165", - "durability": null, - "name": "Gold ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1636" - }, - { - "ge_buy_limit": "5000", - "examine": "A valuable ring.", - "grand_exchange_price": "561", - "durability": null, - "name": "Sapphire ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1637", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "561", - "durability": null, - "name": "Sapphire ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1638" - }, - { - "ge_buy_limit": "5000", - "examine": "A valuable ring.", - "grand_exchange_price": "884", - "durability": null, - "name": "Emerald ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1639", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "884", - "durability": null, - "name": "Emerald ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1640" - }, - { - "shop_price": "2025", - "ge_buy_limit": "5000", - "examine": "A valuable ring.", - "grand_exchange_price": "1110", - "durability": null, - "name": "Ruby ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1641", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1110", - "durability": null, - "name": "Ruby ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1642" - }, - { - "shop_price": "3172", - "ge_buy_limit": "5000", - "examine": "A valuable ring.", - "grand_exchange_price": "4416", - "durability": null, - "name": "Diamond ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1643", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "4416", - "durability": null, - "name": "Diamond ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1644" - }, - { - "shop_price": "7750", - "ge_buy_limit": "100", - "examine": "A valuable ring.", - "grand_exchange_price": "26700", - "durability": null, - "name": "Dragonstone ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1645", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "26700", - "durability": null, - "name": "Dragonstone ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1646" - }, - { - "examine": "A valuable ring.", - "grand_exchange_price": "547", - "durability": null, - "name": "Sapphire ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1649" - }, - { - "examine": "A valuable ring.", - "grand_exchange_price": "993", - "durability": null, - "name": "Emerald ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1650" - }, - { - "shop_price": "2025", - "examine": "A valuable ring.", - "grand_exchange_price": "1125", - "durability": null, - "name": "Ruby ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1651" - }, - { - "shop_price": "3172", - "examine": "A valuable ring.", - "grand_exchange_price": "3622", - "durability": null, - "name": "Diamond ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1652" - }, - { - "shop_price": "7750", - "examine": "A valuable ring.", - "grand_exchange_price": "19606", - "durability": null, - "name": "Dragonstone ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1653" - }, - { - "shop_price": "450", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "185", - "durability": null, - "name": "Gold necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1654", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "185", - "durability": null, - "name": "Gold necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1655" - }, - { - "shop_price": "945", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "534", - "durability": null, - "name": "Sapphire necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1656", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "534", - "durability": null, - "name": "Sapphire necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1657" - }, - { - "shop_price": "1425", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "781", - "durability": null, - "name": "Emerald necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1658", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "781", - "durability": null, - "name": "Emerald necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1659" - }, - { - "shop_price": "870", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Ruby necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1660", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1276", - "durability": null, - "name": "Ruby necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1661" - }, - { - "shop_price": "3307", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "14300", - "durability": null, - "name": "Diamond necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1662", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "14300", - "durability": null, - "name": "Diamond necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1663" - }, - { - "ge_buy_limit": "100", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "26000", - "durability": null, - "name": "Dragon necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1664", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "26000", - "durability": null, - "name": "Dragon necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1665" - }, - { - "shop_price": "945", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "532", - "durability": null, - "name": "Sapphire necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1668" - }, - { - "shop_price": "1425", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "741", - "durability": null, - "name": "Emerald necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1669" - }, - { - "shop_price": "870", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "1194", - "durability": null, - "name": "Ruby necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1670" - }, - { - "shop_price": "3307", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "9795", - "durability": null, - "name": "Diamond necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1671" - }, - { - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "23010", - "durability": null, - "name": "Dragon necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1672" - }, - { - "shop_price": "350", - "ge_buy_limit": "5000", - "examine": "A plain gold amulet.", - "grand_exchange_price": "172", - "durability": null, - "name": "Gold amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1673" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "172", - "durability": null, - "name": "Gold amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1674" - }, - { - "shop_price": "810", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "473", - "durability": null, - "name": "Sapphire amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1675" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "473", - "durability": null, - "name": "Sapphire amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1676" - }, - { - "shop_price": "1147", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "695", - "durability": null, - "name": "Emerald amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1677" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "695", - "durability": null, - "name": "Emerald amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1678" - }, - { - "shop_price": "2025", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "1268", - "durability": null, - "name": "Ruby amulet", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1679" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1268", - "durability": null, - "name": "Ruby amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1680" - }, - { - "shop_price": "3307", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "3359", - "durability": null, - "name": "Diamond amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1681" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3359", - "durability": null, - "name": "Diamond amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1682" - }, - { - "ge_buy_limit": "100", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "26900", - "durability": null, - "name": "Dragonstone ammy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1683" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "26900", - "durability": null, - "name": "Dragonstone ammy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1684" - }, - { - "shop_price": "810", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "417", - "durability": null, - "name": "Sapphire amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1687" - }, - { - "shop_price": "1147", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "648", - "durability": null, - "name": "Emerald amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1688" - }, - { - "shop_price": "2025", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "1098", - "durability": null, - "name": "Ruby amulet", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1689" - }, - { - "shop_price": "3307", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "1993", - "durability": null, - "name": "Diamond amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1690" - }, - { - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "18436", - "durability": null, - "name": "Dragonstone ammy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1691" - }, - { - "shop_price": "350", - "ge_buy_limit": "5000", - "examine": "A plain gold amulet.", - "grand_exchange_price": "137", - "durability": null, - "name": "Gold amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1692", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "137", - "durability": null, - "name": "Gold amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1693" - }, - { - "shop_price": "810", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "435", - "durability": null, - "name": "Sapphire amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1694", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "435", - "durability": null, - "name": "Sapphire amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1695" - }, - { - "shop_price": "1147", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "659", - "durability": null, - "name": "Emerald amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1696", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "659", - "durability": null, - "name": "Emerald amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1697" - }, - { - "shop_price": "2025", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "1115", - "durability": null, - "name": "Ruby amulet", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1698", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1115", - "durability": null, - "name": "Ruby amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1699" - }, - { - "shop_price": "3307", - "ge_buy_limit": "5000", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "2706", - "durability": null, - "name": "Diamond amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1700", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2706", - "durability": null, - "name": "Diamond amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1701" - }, - { - "ge_buy_limit": "100", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "27100", - "durability": null, - "name": "Dragonstone ammy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1702", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "27100", - "durability": null, - "name": "Dragonstone ammy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1703" - }, - { - "ge_buy_limit": "100", - "examine": "A very powerful dragonstone amulet.", - "grand_exchange_price": "28000", - "durability": null, - "name": "Amulet of glory", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1704", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "28000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1705" - }, - { - "examine": "A dragonstone amulet with 1 magic charge.", - "grand_exchange_price": "1", - "durability": null, - "name": "Amulet of glory(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1706", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1707" - }, - { - "examine": "A dragonstone amulet with 2 magic charges.", - "grand_exchange_price": "1", - "durability": null, - "name": "Amulet of glory(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1708", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1709" - }, - { - "examine": "A dragonstone amulet with 3 magic charges.", - "grand_exchange_price": "1", - "durability": null, - "name": "Amulet of glory(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1710", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1711" - }, - { - "ge_buy_limit": "100", - "examine": "A dragonstone amulet with 4 magic charges.", - "grand_exchange_price": "29300", - "durability": null, - "name": "Amulet of glory(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1712", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "29300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1713" - }, - { - "shop_price": "200", - "ge_buy_limit": "5000", - "examine": "It needs a string so I can wear it.", - "grand_exchange_price": "83", - "durability": null, - "name": "Unstrung symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1714" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "83", - "durability": null, - "name": "Unstrung symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1715" - }, - { - "shop_price": "120", - "ge_buy_limit": "5000", - "examine": "A symbol of Saradomin.", - "grand_exchange_price": "29", - "durability": null, - "name": "Unblessed symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1716", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "29", - "durability": null, - "name": "Unblessed symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1717" - }, - { - "shop_price": "300", - "ge_buy_limit": "5000", - "examine": "A blessed holy symbol of Saradomin.", - "grand_exchange_price": "88", - "durability": null, - "name": "Holy symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1718", - "bonuses": "0,0,0,0,0,2,2,2,2,2,3,0,8,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "88", - "durability": null, - "name": "Holy symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1719" - }, - { - "ge_buy_limit": "5000", - "examine": "It needs a string so I can wear it.", - "grand_exchange_price": "178", - "durability": null, - "name": "Unstrung emblem", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1720" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "178", - "durability": null, - "name": "Unstrung emblem", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1721" - }, - { - "shop_price": "120", - "ge_buy_limit": "5000", - "examine": "An unholy symbol of Zamorak.", - "grand_exchange_price": "24", - "durability": null, - "name": "Unpowered symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1722", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "24", - "durability": null, - "name": "Unpowered symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1723" - }, - { - "shop_price": "135", - "ge_buy_limit": "5000", - "examine": "An unholy symbol of Zamorak.", - "grand_exchange_price": "57", - "durability": null, - "name": "Unholy symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1724", - "bonuses": "2,2,2,2,2,0,0,0,0,0,0,0,8,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "examine": "An enchanted ruby amulet.", - "grand_exchange_price": "1247", - "durability": null, - "name": "Amulet of strength", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1725", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1247", - "durability": null, - "name": "Amulet of strength", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1726" - }, - { - "shop_price": "900", - "ge_buy_limit": "5000", - "examine": "An enchanted sapphire amulet of magic.", - "grand_exchange_price": "519", - "durability": null, - "name": "Amulet of magic", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1727", - "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "519", - "durability": null, - "name": "Amulet of magic", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1728" - }, - { - "shop_price": "1275", - "ge_buy_limit": "5000", - "examine": "An enchanted emerald amulet of protection.", - "grand_exchange_price": "721", - "durability": null, - "name": "Amulet of defence", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1729", - "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "721", - "durability": null, - "name": "Amulet of defence", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1730" - }, - { - "shop_price": "3525", - "ge_buy_limit": "5000", - "examine": "An enchanted diamond amulet of power.", - "grand_exchange_price": "2573", - "durability": null, - "name": "Amulet of power", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1731", - "bonuses": "6,6,6,6,6,6,6,6,6,6,6,6,1,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2573", - "durability": null, - "name": "Amulet of power", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1732" - }, - { - "shop_price": "1", - "ge_buy_limit": "5000", - "examine": "Used with a thread to make clothes.", - "grand_exchange_price": "5", - "durability": null, - "name": "Needle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1733" - }, - { - "shop_price": "4", - "ge_buy_limit": "10000", - "examine": "Use with a needle to make clothes.", - "grand_exchange_price": "7", - "durability": null, - "name": "Thread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1734" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "For shearing sheep.", - "grand_exchange_price": "76", - "durability": null, - "name": "Shears", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1735" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "76", - "durability": null, - "name": "Shears", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1736" - }, - { - "ge_buy_limit": "5000", - "examine": "I think this came from a sheep.", - "grand_exchange_price": "160", - "durability": null, - "name": "Wool", - "tradeable": "true", - "weight": "0.14", - "archery_ticket_price": "0", - "id": "1737" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "160", - "durability": null, - "name": "Wool", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1738" - }, - { - "ge_buy_limit": "10000", - "examine": "I should take this to the tannery.", - "grand_exchange_price": "140", - "durability": null, - "name": "Cowhide", - "tradeable": "true", - "weight": "2.7", - "archery_ticket_price": "0", - "id": "1739" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "516", - "durability": null, - "name": "Cowhide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1740" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a piece of leather.", - "grand_exchange_price": "638", - "durability": null, - "name": "Leather", - "tradeable": "true", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "1741" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "638", - "durability": null, - "name": "Leather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1742" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a piece of hard leather.", - "grand_exchange_price": "640", - "durability": null, - "name": "Hard leather", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "1743" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "640", - "durability": null, - "name": "Hard leather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1744" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a piece of prepared green dragon hide.", - "grand_exchange_price": "2237", - "durability": null, - "name": "Green d-leather", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "1745" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2237", - "durability": null, - "name": "Green d-leather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1746" - }, - { - "ge_buy_limit": "10000", - "examine": "The scaly rough hide from a Black Dragon.", - "grand_exchange_price": "5802", - "durability": null, - "name": "Black dragonhide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "1747" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "5802", - "durability": null, - "name": "Black dragonhide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1748" - }, - { - "ge_buy_limit": "10000", - "examine": "The scaly rough hide from a red dragon.", - "grand_exchange_price": "3539", - "durability": null, - "name": "Red dragonhide", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "1749" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "3539", - "durability": null, - "name": "Red dragonhide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1750" - }, - { - "ge_buy_limit": "10000", - "examine": "The scaly rough hide from a blue dragon.", - "grand_exchange_price": "2473", - "durability": null, - "name": "Blue dragonhide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "1751" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2473", - "durability": null, - "name": "Blue dragonhide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1752" - }, - { - "ge_buy_limit": "10000", - "examine": "The scaly rough hide from a green dragon.", - "grand_exchange_price": "1000", - "durability": null, - "name": "Green dragonhide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "1753" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1933", - "durability": null, - "name": "Green dragonhide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1754" - }, - { - "shop_price": "14", - "ge_buy_limit": "100", - "examine": "Good for detailed crafting.", - "grand_exchange_price": "20", - "durability": null, - "name": "Chisel", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1755" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, - "name": "Chisel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1756" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A mostly clean apron.", - "grand_exchange_price": "74", - "durability": null, - "name": "Brown apron", - "tradeable": "true", - "weight": "0.45", - "archery_ticket_price": "0", - "id": "1757", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "74", - "durability": null, - "name": "Brown apron", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1758" - }, - { - "ge_buy_limit": "5000", - "examine": "Spun from sheeps' wool.", - "grand_exchange_price": "115", - "durability": null, - "name": "Ball of wool", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1759" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "115", - "durability": null, - "name": "Ball of wool", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1760" - }, - { - "ge_buy_limit": "10000", - "examine": "Clay soft enough to mould.", - "grand_exchange_price": "487", - "durability": null, - "name": "Soft clay", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1761" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "487", - "durability": null, - "name": "Soft clay", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1762" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A little bottle of red dye.", - "grand_exchange_price": "1374", - "durability": null, - "name": "Red dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1763" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1374", - "durability": null, - "name": "Red dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1764" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A little bottle of yellow dye.", - "grand_exchange_price": "549", - "durability": null, - "name": "Yellow dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1765" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "549", - "durability": null, - "name": "Yellow dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1766" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A little bottle of blue dye", - "grand_exchange_price": "642", - "durability": null, - "name": "Blue dye", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1767" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "642", - "durability": null, - "name": "Blue dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1768" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A little bottle of orange dye.", - "grand_exchange_price": "1258", - "durability": null, - "name": "Orange dye", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1769" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1258", - "durability": null, - "name": "Orange dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1770" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A little bottle of green dye.", - "grand_exchange_price": "503", - "durability": null, - "name": "Green dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1771" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "503", - "durability": null, - "name": "Green dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1772" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A little bottle of purple dye.", - "grand_exchange_price": "288", - "durability": null, - "name": "Purple dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1773" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "288", - "durability": null, - "name": "Purple dye", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1774" - }, - { - "ge_buy_limit": "10000", - "examine": "Hot glass ready to be blown into useful objects.", - "grand_exchange_price": "924", - "durability": null, - "name": "Molten glass", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1775" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "924", - "durability": null, - "name": "Molten glass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1776" - }, - { - "ge_buy_limit": "10000", - "examine": "I need a bow stave to attach this to.", - "grand_exchange_price": "240", - "durability": null, - "name": "Bow string", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1777" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "223", - "durability": null, - "name": "Bow string", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1778" - }, - { - "shop_price": "73", - "ge_buy_limit": "25000", - "examine": "A plant cultivated for fibres (ground); I should use this with a spinning wheel (item).", - "grand_exchange_price": "73", - "durability": null, - "name": "Flax", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1779" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "73", - "durability": null, - "name": "Flax", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1780" - }, - { - "ge_buy_limit": "10000", - "examine": "One of the ingredients for making glass.", - "grand_exchange_price": "575", - "durability": null, - "name": "Soda ash", - "tradeable": "true", - "weight": "0.09", - "archery_ticket_price": "0", - "id": "1781" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "575", - "durability": null, - "name": "Soda ash", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1782" - }, - { - "ge_buy_limit": "10000", - "examine": "One of the ingredients for making glass.", - "grand_exchange_price": "265", - "durability": null, - "name": "Bucket of sand", - "tradeable": "true", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "1783" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "265", - "durability": null, - "name": "Bucket of sand", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1784" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "Used to form molten glass into useful items.", - "grand_exchange_price": "195", - "durability": null, - "name": "Glassblowing pipe", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1785" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "195", - "durability": null, - "name": "Glassblowing pipe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1786" - }, - { - "ge_buy_limit": "100", - "examine": "I need to put this in a pottery oven.", - "grand_exchange_price": "53", - "durability": null, - "name": "Unfired pot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1787" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "53", - "durability": null, - "name": "Unfired pot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1788" - }, - { - "ge_buy_limit": "100", - "examine": "I need to put this in a pottery oven.", - "grand_exchange_price": "96", - "durability": null, - "name": "Unfired pie dish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1789" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "96", - "durability": null, - "name": "Unfired pie dish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1790" - }, - { - "shop_price": "32", - "ge_buy_limit": "100", - "examine": "I need to put this in a pottery oven.", - "grand_exchange_price": "194", - "durability": null, - "name": "Unfired bowl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1791" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "194", - "durability": null, - "name": "Unfired bowl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1792" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", - "examine": "A slightly bluish leaf.", - "grand_exchange_price": "57", - "durability": null, - "name": "Woad leaf", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1793" - }, - { - "ge_buy_limit": "100", - "examine": "Useful for crafting items.", - "grand_exchange_price": "249", - "durability": null, - "name": "Bronze wire", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1794" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "249", - "durability": null, - "name": "Bronze wire", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1795" - }, - { - "examine": "Anna's shiny silver coated necklace.", - "durability": null, - "name": "Silver necklace", - "weight": "1", - "archery_ticket_price": "0", - "id": "1796", - "equipment_slot": "2" - }, - { - "examine": "Anna's shiny silver coated necklace.", - "durability": null, - "name": "Silver necklace", - "weight": "1", - "archery_ticket_price": "0", - "id": "1797", - "equipment_slot": "2" - }, - { - "examine": "Bob's shiny silver coated tea cup.", - "durability": null, - "name": "Silver cup", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1798" - }, - { - "examine": "Bob's shiny silver coated tea cup.", - "durability": null, - "name": "Silver cup", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1799" - }, - { - "examine": "Carol's shiny silver coated bottle.", - "durability": null, - "name": "Silver bottle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1800" - }, - { - "examine": "Carol's shiny silver coated bottle.", - "durability": null, - "name": "Silver bottle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1801" - }, - { - "examine": "David's shiny silver coated book.", - "durability": null, - "name": "Silver book", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1802" - }, - { - "examine": "David's shiny silver coated book.", - "durability": null, - "name": "Silver book", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1803" - }, - { - "examine": "Elizabeth's shiny silver coated needle.", - "durability": null, - "name": "Silver needle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1804" - }, - { - "examine": "Elizabeth's shiny silver coated needle.", - "durability": null, - "name": "Silver needle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1805" - }, - { - "examine": "Frank's shiny silver coated pot.", - "durability": null, - "name": "Silver pot", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1806" - }, - { - "examine": "Frank's shiny silver coated pot.", - "durability": null, - "name": "Silver pot", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1807" - }, - { - "examine": "Some (colour) thread found at the murder scene.", - "durability": null, - "name": "Criminal's thread", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1808" - }, - { - "examine": "Some (colour) thread found at the murder scene.", - "durability": null, - "name": "Criminal's thread", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1809" - }, - { - "examine": "Some (colour) thread found at the murder scene.", - "durability": null, - "name": "Criminal's thread", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1810" - }, - { - "examine": "A piece of fly paper. It's sticky.", - "durability": null, - "name": "Flypaper", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1811" - }, - { - "examine": "A pot found at the murder scene, with a sickly odour.", - "durability": null, - "name": "Pungent pot", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1812" - }, - { - "examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.", - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Criminal's dagger", - "archery_ticket_price": "0", - "id": "1813" - }, - { - "examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.", - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Criminal's dagger", - "archery_ticket_price": "0", - "id": "1814" - }, - { - "examine": "The fingerprints of the murderer.", - "durability": null, - "name": "Killer's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1815" - }, - { - "examine": "An imprint of Anna's fingerprint.", - "durability": null, - "name": "Anna's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1816" - }, - { - "examine": "An imprint of Bob's fingerprint.", - "durability": null, - "name": "Bob's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1817" - }, - { - "examine": "An imprint of Carol's fingerprint.", - "durability": null, - "name": "Carol's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1818" - }, - { - "examine": "An imprint of David's fingerprint.", - "durability": null, - "name": "David's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1819" - }, - { - "examine": "An imprint of Elizabeth's fingerprint.", - "durability": null, - "name": "Elizabeth's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1820" - }, - { - "examine": "An imprint of Frank's fingerprint.", - "durability": null, - "name": "Frank's print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1821" - }, - { - "examine": "An unidentified fingerprint taken from the murder weapon.", - "durability": null, - "name": "Unknown print", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1822" - }, - { - "shop_price": "30", - "ge_buy_limit": "100", - "examine": "A full waterskin with four portions of water.", - "grand_exchange_price": "184", - "durability": null, - "name": "Waterskin(4)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1823" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "184", - "durability": null, - "name": "Waterskin(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1824" - }, - { - "shop_price": "30", - "examine": "A nearly full waterskin with three portions of water.", - "grand_exchange_price": "4", - "durability": null, - "name": "Waterskin(3)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1825" - }, - { - "durability": null, - "name": "Waterskin(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1826" - }, - { - "shop_price": "30", - "examine": "A half empty waterskin with two portions of water.", - "grand_exchange_price": "4", - "durability": null, - "name": "Waterskin(2)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1827" - }, - { - "durability": null, - "name": "Waterskin(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1828" - }, - { - "shop_price": "30", - "examine": "A nearly empty waterskin with one portion of water.", - "grand_exchange_price": "4", - "durability": null, - "name": "Waterskin(1)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1829" - }, - { - "durability": null, - "name": "Waterskin(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1830" - }, - { - "shop_price": "30", - "ge_buy_limit": "100", - "examine": "A completely empty waterskin - you'll need to fill it up.", - "grand_exchange_price": "93", - "durability": null, - "name": "Waterskin(0)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1831" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "93", - "durability": null, - "name": "Waterskin(0)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1832" - }, - { - "remove_sleeves": "true", - "shop_price": "40", - "ge_buy_limit": "100", - "examine": "A cool, light desert shirt.", - "grand_exchange_price": "93", - "durability": null, - "name": "Desert shirt", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1833", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "93", - "durability": null, - "name": "Desert shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1834" - }, - { - "shop_price": "40", - "ge_buy_limit": "100", - "examine": "A cool, light desert robe.", - "grand_exchange_price": "74", - "durability": null, - "name": "Desert robe", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1835", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "74", - "durability": null, - "name": "Desert robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1836" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Comfortable desert shoes.", - "grand_exchange_price": "257", - "durability": null, - "name": "Desert boots", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "1837", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "257", - "durability": null, - "name": "Desert boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1838" - }, - { - "examine": "This key is crudely made. It came from the mining camp Mercenary Captain.", - "durability": null, - "name": "Metal key", - "archery_ticket_price": "0", - "id": "1839" - }, - { - "examine": "A metallic key, usually used by prison guards. (Tourist Trap)", - "durability": null, - "name": "Cell door key", - "archery_ticket_price": "0", - "id": "1840" - }, - { - "examine": "An empty barrel/A Splendid barrel.", - "grand_exchange_price": "206", - "durability": null, - "name": "Barrel", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "1841" - }, - { - "examine": "Inventory: A mining barrel with Ana in it.While in the mine cart: It's Ana... in a barrel... in a mine cart.", - "durability": null, - "name": "Ana in a barrel", - "weight": "32", - "archery_ticket_price": "0", - "id": "1842" - }, - { - "examine": "This key unlocks a very sturdy gate. Ana gave me this key. (Tourist Trap)", - "durability": null, - "name": "Wrought iron key", - "archery_ticket_price": "0", - "id": "1843" - }, - { - "remove_sleeves": "true", - "examine": "A filthy, smelly, flea infested shirt.", - "durability": null, - "name": "Slave shirt", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1844", - "equipment_slot": "4" - }, - { - "examine": "A filthy, smelly, flea infested robe.", - "durability": null, - "name": "Slave robe", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1845", - "equipment_slot": "7" - }, - { - "examine": "A set of filthy, smelly, flea infested desert slave boots.", - "durability": null, - "name": "Slave boots", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "1846", - "equipment_slot": "10" - }, - { - "examine": "A piece of paper with barely legible writing - looks like a recipe!", - "durability": null, - "name": "Scrumpled paper", - "archery_ticket_price": "0", - "id": "1847" - }, - { - "shop_price": "5", - "examine": "Very important information.", - "durability": null, - "name": "Shantay disclaimer", - "archery_ticket_price": "0", - "id": "1848" - }, - { - "examine": "A prototype throwing dart.", - "attack_audios": "2547,0,0,0", - "durability": null, - "name": "Prototype dart", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1849" - }, - { - "examine": "Plans of a technical nature.", - "durability": null, - "name": "Technical plans", - "weight": "1", - "archery_ticket_price": "0", - "id": "1850" - }, - { - "examine": "The most delicious of pineapples.", - "durability": null, - "name": "Tenti pineapple", - "weight": "1", - "archery_ticket_price": "0", - "id": "1851" - }, - { - "examine": "A key to the chest in Captain Siad's room.", - "durability": null, - "name": "Bedabin key", - "archery_ticket_price": "0", - "id": "1852" - }, - { - "examine": "A protoype dart tip - it looks deadly.", - "attack_audios": "2547,0,0,0", - "durability": null, - "name": "Prototype dart tip", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1853" - }, - { - "shop_price": "5", - "examine": "Allows you to pass through the Shantay pass into the Kharid Desert.", - "durability": null, - "name": "Shantay pass", - "archery_ticket_price": "0", - "id": "1854" - }, - { - "examine": "A Tourist's Guide to Ardougne.", - "durability": null, - "name": "Guide book", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "1856" - }, - { - "examine": "The Rantuki tribe's totem.", - "durability": null, - "name": "Totem", - "weight": "3", - "archery_ticket_price": "0", - "id": "1857" - }, - { - "examine": "It says 'To Lord Handelmort, Handelmort Mansion'.", - "durability": null, - "name": "Address label", - "archery_ticket_price": "0", - "id": "1858" - }, - { - "ge_buy_limit": "1000", - "examine": "I need to cook this first.", - "grand_exchange_price": "486", - "durability": null, - "name": "Raw ugthanki meat", - "tradeable": "true", - "weight": "0.75", - "archery_ticket_price": "0", - "id": "1859" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "486", - "durability": null, - "name": "Raw ugthanki meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1860" - }, - { - "ge_buy_limit": "1000", - "examine": "I need to cook this first / Freshly cooked ugthanki meat.", - "grand_exchange_price": "687", - "durability": null, - "name": "Ugthanki meat", - "tradeable": "true", - "weight": "0.75", - "archery_ticket_price": "0", - "id": "1861" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "687", - "durability": null, - "name": "Ugthanki meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1862" - }, - { - "shop_price": "9", - "ge_buy_limit": "1000", - "examine": "I need to cook this.", - "grand_exchange_price": "90", - "durability": null, - "name": "Pitta dough", - "tradeable": "true", - "weight": "0.14", - "archery_ticket_price": "0", - "id": "1863" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "90", - "durability": null, - "name": "Pitta dough", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1864" - }, - { - "ge_buy_limit": "1000", - "examine": "Nicely baked pitta bread. Needs more ingredients to make a kebab.", - "grand_exchange_price": "22", - "durability": null, - "name": "Pitta bread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1865" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "22", - "durability": null, - "name": "Pitta bread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1866" - }, - { - "examine": "It's all burnt.", - "durability": null, - "name": "Burnt pitta bread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1867" - }, - { - "durability": null, - "name": "Burnt pitta bread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1868" - }, - { - "ge_buy_limit": "1000", - "examine": "A mixture of tomatoes in a bowl.", - "grand_exchange_price": "90", - "durability": null, - "name": "Chopped tomato", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "1869" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "90", - "durability": null, - "name": "Chopped tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1870" - }, - { - "ge_buy_limit": "1000", - "examine": "A mixture of onions in a bowl.", - "grand_exchange_price": "142", - "durability": null, - "name": "Chopped onion", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1871" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "142", - "durability": null, - "name": "Chopped onion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1872" - }, - { - "ge_buy_limit": "1000", - "examine": "Strips of ugthanki meat in a bowl.", - "grand_exchange_price": "348", - "durability": null, - "name": "Chopped ugthanki", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1873" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "348", - "durability": null, - "name": "Chopped ugthanki", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1874" - }, - { - "ge_buy_limit": "1000", - "examine": "A mixture of chopped onions and tomatoes in a bowl", - "grand_exchange_price": "31", - "durability": null, - "name": "Onion & tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1875" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "31", - "durability": null, - "name": "Onion & tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1876" - }, - { - "shop_price": "26", - "ge_buy_limit": "1000", - "examine": "A mixture of chopped onions and ugthanki meat in a bowl.", - "grand_exchange_price": "330", - "durability": null, - "name": "Ugthanki & onion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1877" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "330", - "durability": null, - "name": "Ugthanki & onion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1878" - }, - { - "ge_buy_limit": "10000", - "examine": "A mixture of chopped tomatoes and ugthanki meat in a bowl.", - "grand_exchange_price": "331", - "durability": null, - "name": "Ugthanki & tomato", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "1879" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "331", - "durability": null, - "name": "Ugthanki & tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1880" - }, - { - "ge_buy_limit": "1000", - "examine": "A mixture of chopped tomatoes, onions and ugthanki meat in a bowl", - "grand_exchange_price": "412", - "durability": null, - "name": "Kebab mix", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1881" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "412", - "durability": null, - "name": "Kebab mix", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1882" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2027", - "durability": null, - "name": "Ugthanki kebab", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1883" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2027", - "durability": null, - "name": "Ugthanki kebab", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1884" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1499", - "durability": null, - "name": "Ugthanki kebab", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1885" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1499", - "durability": null, - "name": "Ugthanki kebab", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1886" - }, - { - "shop_price": "10", - "ge_buy_limit": "100", - "examine": "Useful for baking cakes.", - "grand_exchange_price": "20", - "durability": null, - "name": "Cake tin", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1887" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, - "name": "Cake tin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1888" - }, - { - "ge_buy_limit": "1000", - "examine": "Now all I need to do is cook it.", - "grand_exchange_price": "559", - "durability": null, - "name": "Uncooked cake", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1889" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "559", - "durability": null, - "name": "Uncooked cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1890" - }, - { - "shop_price": "50", - "ge_buy_limit": "1000", - "examine": "A plain sponge cake.", - "grand_exchange_price": "155", - "durability": null, - "name": "Cake", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1891" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "155", - "durability": null, - "name": "Cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1892" - }, - { - "shop_price": "50", - "ge_buy_limit": "1000", - "examine": "A plain sponge cake.", - "grand_exchange_price": "39", - "durability": null, - "name": "2/3 cake", "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1893" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "39", - "durability": null, - "name": "2/3 cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1894" - }, - { - "shop_price": "50", - "ge_buy_limit": "1000", - "examine": "A plain sponge cake.", - "grand_exchange_price": "32", - "durability": null, - "name": "Slice of cake", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1895" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "32", - "durability": null, - "name": "Slice of cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1896" - }, - { - "ge_buy_limit": "1000", - "examine": "This looks very tasty.", - "grand_exchange_price": "416", - "durability": null, - "name": "Chocolate cake", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1897" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "416", - "durability": null, - "name": "Chocolate cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1898" - }, - { - "ge_buy_limit": "1000", - "examine": "This looks very tasty.", - "grand_exchange_price": "181", - "durability": null, - "name": "2/3 chocolate cake", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1899" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "181", - "durability": null, - "name": "2/3 chocolate cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1900" - }, - { - "ge_buy_limit": "1000", - "examine": "This looks very tasty.", - "grand_exchange_price": "13", - "durability": null, - "name": "Chocolate slice", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1901" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "13", - "durability": null, - "name": "Chocolate slice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1902" - }, - { - "durability": null, - "name": "Burnt cake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1904" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "190", - "durability": null, - "name": "Asgarnian ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1905" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "190", - "durability": null, - "name": "Asgarnian ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1906" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "It's got strange bubbles in it.", - "grand_exchange_price": "171", - "durability": null, - "name": "Wizard's mind bomb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1907" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "171", - "durability": null, - "name": "Wizard's mind bomb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1908" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "828", - "durability": null, - "name": "Greenman's ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1909" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "828", - "durability": null, - "name": "Greenman's ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1910" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of bitter.", - "grand_exchange_price": "487", - "durability": null, - "name": "Dragon bitter", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1911" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "487", - "durability": null, - "name": "Dragon bitter", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1912" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A pint of thick dark beer.", - "grand_exchange_price": "212", - "durability": null, - "name": "Dwarven stout", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1913" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "212", - "durability": null, - "name": "Dwarven stout", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1914" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A murky glass full of your average, everyday pirate slosh.", - "grand_exchange_price": "19", - "durability": null, - "name": "Grog", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "1915" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, - "name": "Grog", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1916" - }, - { - "ge_buy_limit": "100", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "202", - "durability": null, - "name": "Beer", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1917", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "202", - "durability": null, - "name": "Beer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1918" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "I need to fill this with beer.", - "grand_exchange_price": "10", - "durability": null, - "name": "Beer glass", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "1919" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10", - "durability": null, - "name": "Beer glass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1920" - }, - { - "ge_buy_limit": "100", - "examine": "It's a bowl of water.", - "grand_exchange_price": "97", - "durability": null, - "name": "Bowl of water", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "1921" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "97", - "durability": null, - "name": "Bowl of water", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1922" - }, - { - "shop_price": "4", - "ge_buy_limit": "100", - "examine": "Useful for mixing things.", - "grand_exchange_price": "34", - "durability": null, - "name": "Bowl", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1923" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "34", - "durability": null, - "name": "Bowl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1924" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "It's an empty bucket.", - "grand_exchange_price": "30", - "durability": null, - "name": "Bucket", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1925" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "30", - "durability": null, - "name": "Bucket", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1926" - }, - { - "shop_price": "12", - "ge_buy_limit": "1000", - "examine": "It's a bucket of milk.", - "grand_exchange_price": "103", - "durability": null, - "name": "Bucket of milk", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "1927" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "103", - "durability": null, - "name": "Bucket of milk", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1928" - }, - { - "ge_buy_limit": "100", - "examine": "It's a bucket of water.", - "grand_exchange_price": "72", - "durability": null, - "name": "Bucket of water", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "1929" + "weight": "0.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "72", - "durability": null, - "name": "Bucket of water", - "tradeable": "true", + "id": "1616", + "name": "Dragonstone", "archery_ticket_price": "0", - "id": "1930" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "This pot is empty.", - "grand_exchange_price": "6", "durability": null, - "name": "Empty pot", - "tradeable": "true", - "weight": "0.45", - "archery_ticket_price": "0", - "id": "1931" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "6", - "durability": null, - "name": "Empty pot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1932" - }, - { - "shop_price": "14", - "ge_buy_limit": "1000", - "examine": "There is flour in this pot.", - "grand_exchange_price": "172", - "durability": null, - "name": "Pot of flour", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "1933" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "172", - "durability": null, - "name": "Pot of flour", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1934" - }, - { - "shop_price": "1", - "ge_buy_limit": "10000", - "examine": "This jug is empty.", - "grand_exchange_price": "29", - "durability": null, - "name": "Jug", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1935" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "29", - "durability": null, - "name": "Jug", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1936" - }, - { - "shop_price": "1", - "ge_buy_limit": "10000", - "examine": "It's full of water.", - "grand_exchange_price": "87", - "durability": null, - "name": "Jug of water", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1937" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "87", - "durability": null, - "name": "Jug of water", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1938" - }, - { - "ge_buy_limit": "5000", - "examine": "A foul smelling thick tar like substance.", - "grand_exchange_price": "103", - "durability": null, - "name": "Swamp tar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1939" + "tradeable": "true" }, { - "shop_price": "38", - "ge_buy_limit": "5000", - "examine": "A tar-like substance mixed with flour and warmed.", - "grand_exchange_price": "342", - "durability": null, - "name": "Raw swamp paste", - "tradeable": "true", + "id": "1617", + "name": "Uncut diamond", + "examine": "An uncut diamond.", "archery_ticket_price": "0", - "id": "1940" - }, - { - "shop_price": "38", - "ge_buy_limit": "100", - "examine": "A tar-like substance mixed with flour and warmed.", - "grand_exchange_price": "1", "durability": null, - "name": "Swamp paste", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1941" - }, - { - "shop_price": "11", "ge_buy_limit": "500", - "examine": "This could be used to make a good stew.", - "grand_exchange_price": "91", - "durability": null, - "name": "Potato", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1942" + "tokkul_price": "300", + "tradeable": "true" }, { + "id": "1618", + "name": "Uncut diamond", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "91", - "durability": null, - "name": "Potato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1943" + "tradeable": "true" }, { - "shop_price": "1", + "id": "1619", + "name": "Uncut ruby", + "examine": "An uncut ruby.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "examine": "A nice fresh egg.", - "grand_exchange_price": "99", - "durability": null, - "name": "Egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1944" + "tokkul_price": "150", + "tradeable": "true" }, { + "id": "1620", + "name": "Uncut ruby", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "99", - "durability": null, - "name": "Egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1945" + "tradeable": "true" }, { - "shop_price": "14", - "examine": "There is flour in this pot.", - "grand_exchange_price": "162", - "durability": null, - "name": "Flour", - "tradeable": "true", - "weight": "1.3", + "id": "1621", + "name": "Uncut emerald", + "examine": "An uncut emerald.", "archery_ticket_price": "0", - "id": "1946" - }, - { - "shop_price": "2", + "durability": null, "ge_buy_limit": "1000", - "examine": "Some wheat heads.", - "grand_exchange_price": "7", - "durability": null, - "name": "Grain", - "tradeable": "true", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "1947" + "shop_price": "50", + "tokkul_price": "75", + "tradeable": "true" }, { + "id": "1622", + "name": "Uncut emerald", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "7", - "durability": null, - "name": "Grain", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1948" + "tradeable": "true" }, { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "What a silly hat.", - "grand_exchange_price": "233", - "durability": null, - "name": "Chef's hat", - "tradeable": "true", - "weight": "0.9", + "id": "1623", + "name": "Uncut sapphire", + "examine": "An uncut sapphire.", "archery_ticket_price": "0", - "id": "1949", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "233", "durability": null, - "name": "Chef's hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1950" - }, - { - "shop_price": "3", "ge_buy_limit": "1000", - "examine": "Very bright red berries.", - "grand_exchange_price": "337", - "durability": null, - "name": "Redberries", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "1951" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "337", - "durability": null, - "name": "Redberries", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1952" - }, - { - "ge_buy_limit": "1000", - "examine": "Potentially pastry.", - "grand_exchange_price": "433", - "durability": null, - "name": "Pastry dough", - "tradeable": "true", - "weight": "0.16", - "archery_ticket_price": "0", - "id": "1953" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "433", - "durability": null, - "name": "Pastry dough", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1954" - }, - { - "shop_price": "36", - "ge_buy_limit": "1000", - "examine": "Keeps the doctor away.", - "grand_exchange_price": "353", - "durability": null, - "name": "Cooking apple", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1955" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "353", - "durability": null, - "name": "Cooking apple", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1956" - }, - { - "shop_price": "12", - "ge_buy_limit": "1000", - "examine": "A strong smelling onion.", - "grand_exchange_price": "8", - "durability": null, - "name": "Onion", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1957" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "8", - "durability": null, - "name": "Onion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1958" - }, - { - "ge_buy_limit": "2", - "examine": "Happy Halloween.", - "grand_exchange_price": "273600000", - "durability": null, - "name": "Pumpkin", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "1959" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "273600000", - "durability": null, - "name": "Pumpkin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1960" - }, - { - "ge_buy_limit": "2", - "examine": "Happy Easter.", - "grand_exchange_price": "80400000", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1961" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "80400000", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1962" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "Mmm this looks tasty.", - "grand_exchange_price": "263", - "durability": null, - "name": "Banana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1963", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "263", - "durability": null, - "name": "Banana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1964" - }, - { - "ge_buy_limit": "1000", - "examine": "On ground: Cabbage... yuck!In inventory: Yuck, I don't like cabbage.", - "grand_exchange_price": "41", - "durability": null, - "name": "Cabbage", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1965" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "41", - "durability": null, - "name": "Cabbage", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1966" - }, - { - "examine": "On ground: Cabbage... yuck!In inventory: Yuck, I don't like cabbage.", - "grand_exchange_price": "55", - "durability": null, - "name": "Cabbage", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "1967" - }, - { - "durability": null, - "name": "Cabbage", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1968" - }, - { - "shop_price": "1", - "examine": "A home made spinach thing.", - "durability": null, - "name": "Spinach roll", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1969" - }, - { - "shop_price": "1", - "ge_buy_limit": "1000", - "examine": "A meaty kebab.", - "grand_exchange_price": "97", - "durability": null, - "name": "Kebab", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1971" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "97", - "durability": null, - "name": "Kebab", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1972" - }, - { - "shop_price": "20", - "ge_buy_limit": "10000", - "examine": "Mmmmmmm chocolate.", - "grand_exchange_price": "295", - "durability": null, - "name": "Chocolate bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1973", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "295", - "durability": null, - "name": "Chocolate bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1974" - }, - { - "shop_price": "20", - "ge_buy_limit": "10000", - "examine": "It's ground-up chocolate.", - "grand_exchange_price": "370", - "durability": null, - "name": "Chocolate dust", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1975" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "370", - "durability": null, - "name": "Chocolate dust", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1976" - }, - { - "examine": "Milk with chocolate in it.", - "durability": null, - "name": "Chocolatey milk", - "weight": "2", - "archery_ticket_price": "0", - "id": "1977" - }, - { - "shop_price": "10", - "ge_buy_limit": "1000", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "1978" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1979" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "An empty cup.", - "grand_exchange_price": "5", - "durability": null, - "name": "Empty cup", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1980" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5", - "durability": null, - "name": "Empty cup", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1981" - }, - { "shop_price": "25", - "ge_buy_limit": "10000", - "examine": "This would make good ketchup.", - "grand_exchange_price": "159", - "durability": null, - "name": "Tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1982" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "159", - "durability": null, - "name": "Tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1983" - }, - { - "shop_price": "1", - "examine": "Rotten to the core!", - "durability": null, - "name": "Rotten apple", - "archery_ticket_price": "0", - "id": "1984" - }, - { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "It's got holes in it.", - "grand_exchange_price": "188", - "durability": null, - "name": "Cheese", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "1985" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "188", - "durability": null, - "name": "Cheese", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1986" - }, - { - "shop_price": "1", - "ge_buy_limit": "1000", - "examine": "Good grapes for wine making.", - "grand_exchange_price": "1510", - "durability": null, - "name": "Grapes", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "1987" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1510", - "durability": null, - "name": "Grapes", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1988" - }, - { - "ge_buy_limit": "2", - "examine": "An optimist would say it is half full.", - "grand_exchange_price": "227700000", - "durability": null, - "name": "Half full wine jug", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1989" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "227700000", - "durability": null, - "name": "Half full wine jug", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1990" - }, - { - "examine": "Oh dear, this wine is terrible!", - "durability": null, - "name": "Jug of bad wine", - "weight": "1", - "archery_ticket_price": "0", - "id": "1991" - }, - { - "examine": "Oh dear, this wine is terrible!", - "durability": null, - "name": "Jug of bad wine", - "weight": "1", - "archery_ticket_price": "0", - "id": "1992" - }, - { - "shop_price": "128", - "ge_buy_limit": "1000", - "examine": "It's full of wine.", - "grand_exchange_price": "36", - "durability": null, - "name": "Jug of wine", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "1993" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "36", - "durability": null, - "name": "Jug of wine", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1994" - }, - { - "examine": "This wine needs to ferment before it can be drunk.", - "durability": null, - "name": "Unfermented wine", - "weight": "1", - "archery_ticket_price": "0", - "id": "1995" - }, - { - "examine": "This wine needs to ferment before it can be drunk.", - "durability": null, - "name": "Unfermented wine", - "weight": "1", - "archery_ticket_price": "0", - "id": "1996" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "177", - "durability": null, - "name": "Incomplete stew", - "archery_ticket_price": "0", - "id": "1997" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "177", - "durability": null, - "name": "Incomplete stew", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "1998" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "210", - "durability": null, - "name": "Incomplete stew", - "archery_ticket_price": "0", - "id": "1999" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "210", - "durability": null, - "name": "Incomplete stew", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2000" - }, - { - "shop_price": "1", - "ge_buy_limit": "200", - "examine": "I need to cook this.", - "grand_exchange_price": "600", - "durability": null, - "name": "Uncooked stew", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2001" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "600", - "durability": null, - "name": "Uncooked stew", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2002" - }, - { - "shop_price": "20", - "ge_buy_limit": "200", - "examine": "It's a meat and potato stew.", - "grand_exchange_price": "1133", - "durability": null, - "name": "Stew", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "2003" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "1133", - "durability": null, - "name": "Stew", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2004" - }, - { - "durability": null, - "name": "Burnt stew", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2006" - }, - { - "shop_price": "230", - "ge_buy_limit": "1000", - "examine": "This could liven up an otherwise bland stew.", - "grand_exchange_price": "277", - "durability": null, - "name": "Spice", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2007" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "277", - "durability": null, - "name": "Spice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2008" - }, - { - "ge_buy_limit": "200", - "examine": "I need to cook this.", - "grand_exchange_price": "1382", - "durability": null, - "name": "Uncooked curry", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2009" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "1382", - "durability": null, - "name": "Uncooked curry", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2010" - }, - { - "ge_buy_limit": "200", - "examine": "It's a spicy hot curry.", - "grand_exchange_price": "1001", - "durability": null, - "name": "Curry", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "2011" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "1001", - "durability": null, - "name": "Curry", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2012" - }, - { - "examine": "Eew, it's horribly burnt.", - "durability": null, - "name": "Burnt curry", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2013" - }, - { - "durability": null, - "name": "Burnt curry", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2014" - }, - { - "shop_price": "5", - "ge_buy_limit": "1000", - "examine": "An absolutely clear spirit sold by well-stocked bars.", - "grand_exchange_price": "366", - "durability": null, - "name": "Vodka", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "2015" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "366", - "durability": null, - "name": "Vodka", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2016" - }, - { - "shop_price": "5", - "ge_buy_limit": "1000", - "examine": "This Draynor malt is sold by well-stocked bars.", - "grand_exchange_price": "68", - "durability": null, - "name": "Whisky", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2017" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "68", - "durability": null, - "name": "Whisky", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2018" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "A strong spirit that tastes of Juniper; sold at well-stocked bars.", - "grand_exchange_price": "184", - "durability": null, - "name": "Gin", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2019" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "184", - "durability": null, - "name": "Gin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2020" - }, - { - "shop_price": "6", - "ge_buy_limit": "1000", - "examine": "A strong spirit best served in a large glass.", - "grand_exchange_price": "146", - "durability": null, - "name": "Brandy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2021" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "146", - "durability": null, - "name": "Brandy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2022" - }, - { - "shop_price": "5", - "examine": "A book on tree gnome cocktails.", - "durability": null, - "name": "Cocktail guide", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2023" - }, - { - "durability": null, - "name": "Cocktail guide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2024" - }, - { - "shop_price": "2", - "examine": "Used for mixing cocktails.", - "durability": null, - "name": "Cocktail shaker", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2025" - }, - { - "shop_price": "1", - "examine": "For sipping cocktails.", - "durability": null, - "name": "Cocktail glass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2026" - }, - { - "durability": null, - "name": "Cocktail glass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2027" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A premade Blurberry Special.", - "grand_exchange_price": "70", - "durability": null, - "name": "Premade blurb' sp.", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2028" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "70", - "durability": null, - "name": "Premade blurb' sp.", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2029" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A premade Chocolate Saturday.", - "grand_exchange_price": "13", - "durability": null, - "name": "Premade choc s'dy", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2030" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "13", - "durability": null, - "name": "Premade choc s'dy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2031" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A premade Drunk Dragon.", - "grand_exchange_price": "34", - "durability": null, - "name": "Premade dr' dragon", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2032" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "34", - "durability": null, - "name": "Premade dr' dragon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2033" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A premade Fruit Blast.", - "grand_exchange_price": "48", - "durability": null, - "name": "Premade fr' blast", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2034" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "48", - "durability": null, - "name": "Premade fr' blast", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2035" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A premade Pineapple Punch.", - "grand_exchange_price": "40", - "durability": null, - "name": "Premade p' punch", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2036" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "40", - "durability": null, - "name": "Premade p' punch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2037" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A premade Short Green Guy.", - "grand_exchange_price": "33", - "durability": null, - "name": "Premade sgg", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2038" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "33", - "durability": null, - "name": "Premade sgg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2039" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "A Premade Wizard Blizzard.", - "grand_exchange_price": "26", - "durability": null, - "name": "Premade wiz blz'd", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2040" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "26", - "durability": null, - "name": "Premade wiz blz'd", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2041" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2042" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2043" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2044" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2045" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2046" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2047" - }, - { - "shop_price": "28", - "ge_buy_limit": "1000", - "examine": "A fresh healthy fruit mix.", - "grand_exchange_price": "285", - "durability": null, - "name": "Pineapple punch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2048" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "285", - "durability": null, - "name": "Pineapple punch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2049" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2050" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2051" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2052" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2053" - }, - { - "shop_price": "28", - "ge_buy_limit": "1000", - "examine": "This looks like a strange mix.", - "grand_exchange_price": "774", - "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2054" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "774", - "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2055" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2056" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2057" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2058" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2059" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2060" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2061" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2062" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2063" - }, - { - "shop_price": "30", - "ge_buy_limit": "1000", - "examine": "Looks good... smells strong.", - "grand_exchange_price": "5468", - "durability": null, - "name": "Blurberry special", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2064" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "5468", - "durability": null, - "name": "Blurberry special", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2065" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2066" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2067" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2068" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2069" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2070" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2071" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2072" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2073" - }, - { - "shop_price": "28", - "ge_buy_limit": "1000", - "examine": "A warm creamy alcoholic beverage", - "grand_exchange_price": "272", - "durability": null, - "name": "Choc saturday", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2074" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "272", - "durability": null, - "name": "Choc saturday", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2075" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2076" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2077" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2078" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2079" - }, - { - "shop_price": "28", - "ge_buy_limit": "1000", - "examine": "A Short Green Guy... looks good.", - "grand_exchange_price": "756", - "durability": null, - "name": "Short green guy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2080" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "756", - "durability": null, - "name": "Short green guy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2081" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2082" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2083" - }, - { - "shop_price": "28", - "ge_buy_limit": "1000", - "examine": "A cool refreshing fruit mix.", - "grand_exchange_price": "1802", - "durability": null, - "name": "Fruit blast", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2084" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1802", - "durability": null, - "name": "Fruit blast", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2085" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2086" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2087" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2088" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2089" - }, - { - "examine": "This cocktail is just missing those little finishing touches.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2090" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2091" - }, - { - "shop_price": "28", - "ge_buy_limit": "1000", - "examine": "A warm creamy alcoholic beverage", - "grand_exchange_price": "506", - "durability": null, - "name": "Drunk dragon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2092" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "506", - "durability": null, - "name": "Drunk dragon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2093" - }, - { - "examine": "I'm not completely sure what this contains.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2094" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2095" - }, - { - "examine": "I'm not completely sure what this contains.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2096" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2097" - }, - { - "examine": "I'm not completely sure what this contains.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2098" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2099" - }, - { - "examine": "I'm not completely sure what this contains.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2100" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2101" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "A common fruit, popularly used in cocktails.", - "grand_exchange_price": "86", - "durability": null, - "name": "Lemon", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2102" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "86", - "durability": null, - "name": "Lemon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2103" - }, - { - "ge_buy_limit": "1000", - "examine": "The not-too-surprising result of using a knife with a lemon!", - "grand_exchange_price": "29", - "durability": null, - "name": "Lemon chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2104" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "29", - "durability": null, - "name": "Lemon chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2105" - }, - { - "ge_buy_limit": "1000", - "examine": "The not-too-surprising result of using a knife with a lemon!", - "grand_exchange_price": "16", - "durability": null, - "name": "Lemon slices", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2106" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "16", - "durability": null, - "name": "Lemon slices", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2107" - }, - { - "shop_price": "70", - "ge_buy_limit": "1000", - "examine": "A common fruit.", - "grand_exchange_price": "930", - "durability": null, - "name": "Orange", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2108" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "930", - "durability": null, - "name": "Orange", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2109" - }, - { - "ge_buy_limit": "1000", - "examine": "Fresh chunks of orange.", - "grand_exchange_price": "46", - "durability": null, - "name": "Orange chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2110" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "46", - "durability": null, - "name": "Orange chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2111" - }, - { - "ge_buy_limit": "1000", - "examine": "Fresh orange slices.", - "grand_exchange_price": "163", - "durability": null, - "name": "Orange slices", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2112" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "163", - "durability": null, - "name": "Orange slices", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2113" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "It can be cut up into something more manageable with a knife.", - "grand_exchange_price": "45", - "durability": null, - "name": "Pineapple", - "tradeable": "true", - "weight": "0.15", - "archery_ticket_price": "0", - "id": "2114" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "45", - "durability": null, - "name": "Pineapple", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2115" - }, - { - "ge_buy_limit": "1000", - "examine": "Fresh chunks of pineapple.", - "grand_exchange_price": "86", - "durability": null, - "name": "Pineapple chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2116" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "86", - "durability": null, - "name": "Pineapple chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2117" - }, - { - "ge_buy_limit": "1000", - "examine": "The not-too-surprising result of using a knife with a pineapple!", - "grand_exchange_price": "25", - "durability": null, - "name": "Pineapple ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2118" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "25", - "durability": null, - "name": "Pineapple ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2119" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "A common fruit, popularly used in cocktails.", - "grand_exchange_price": "78", - "durability": null, - "name": "Lime", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2120" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "78", - "durability": null, - "name": "Lime", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2121" - }, - { - "ge_buy_limit": "1000", - "examine": "Fresh chunks of lime.", - "grand_exchange_price": "16", - "durability": null, - "name": "Lime chunks", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2122" + "tokkul_price": "37", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "16", - "durability": null, - "name": "Lime chunks", - "tradeable": "true", + "id": "1624", + "name": "Uncut sapphire", "archery_ticket_price": "0", - "id": "2123" - }, - { - "ge_buy_limit": "1000", - "examine": "The not-too-surprising result of using a knife with a lime!", - "grand_exchange_price": "25", "durability": null, - "name": "Lime slices", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2124" - }, - { "ge_buy_limit": "1000", - "grand_exchange_price": "25", - "durability": null, - "name": "Lime slices", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2125" - }, - { - "shop_price": "10", - "ge_buy_limit": "10000", - "examine": "Some rather pretty blue berries picked from a dwellberry bush.", - "grand_exchange_price": "144", - "durability": null, - "name": "Dwellberries", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2126" + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "144", - "durability": null, - "name": "Dwellberries", - "tradeable": "true", + "id": "1625", + "name": "Uncut opal", + "examine": "An uncut opal.", "archery_ticket_price": "0", - "id": "2127" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "A common ingredient in gnome cuisine.", - "grand_exchange_price": "275", "durability": null, - "name": "Equa leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2128" - }, - { "ge_buy_limit": "1000", - "grand_exchange_price": "275", - "durability": null, - "name": "Equa leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2129" - }, - { - "shop_price": "2", - "ge_buy_limit": "10000", - "examine": "Fresh cream.", - "grand_exchange_price": "58", - "durability": null, - "name": "Pot of cream", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2130" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "58", - "durability": null, - "name": "Pot of cream", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2131" + "tradeable": "true" }, { - "shop_price": "58", - "ge_buy_limit": "1000", - "examine": "I need to cook this first.", - "grand_exchange_price": "282", - "durability": null, - "name": "Raw beef", - "tradeable": "true", - "weight": "0.3", + "id": "1626", + "name": "Uncut opal", "archery_ticket_price": "0", - "id": "2132" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "282", "durability": null, - "name": "Raw beef", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2133" - }, - { - "shop_price": "1", "ge_buy_limit": "1000", - "examine": "I need to cook this first.", - "grand_exchange_price": "85", - "durability": null, - "name": "Raw rat meat", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2134" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "85", - "durability": null, - "name": "Raw rat meat", - "tradeable": "true", + "id": "1627", + "name": "Uncut jade", + "examine": "An uncut jade.", "archery_ticket_price": "0", - "id": "2135" - }, - { - "shop_price": "8", - "ge_buy_limit": "1000", - "examine": "I need to cook this first.", - "grand_exchange_price": "307", "durability": null, - "name": "Raw bear meat", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2136" - }, - { "ge_buy_limit": "1000", - "grand_exchange_price": "307", - "durability": null, - "name": "Raw bear meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2137" + "tradeable": "true" }, { - "shop_price": "60", - "ge_buy_limit": "1000", - "examine": "I need to cook this first.", - "grand_exchange_price": "386", - "durability": null, - "name": "Raw chicken", - "tradeable": "true", - "weight": "0.15", + "id": "1628", + "name": "Uncut jade", "archery_ticket_price": "0", - "id": "2138" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "386", "durability": null, - "name": "Raw chicken", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2139" - }, - { - "shop_price": "5", "ge_buy_limit": "1000", - "examine": "Mmm this looks tasty.", - "grand_exchange_price": "70", - "durability": null, - "name": "Cooked chicken", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2140" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "70", - "durability": null, - "name": "Cooked chicken", - "tradeable": "true", + "id": "1629", + "name": "Uncut red topaz", + "examine": "An uncut red topaz.", "archery_ticket_price": "0", - "id": "2141" - }, - { - "shop_price": "5", - "ge_buy_limit": "1000", - "examine": "Mmm this looks tasty.", - "grand_exchange_price": "111", "durability": null, - "name": "Cooked meat", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "2142" - }, - { "ge_buy_limit": "1000", - "grand_exchange_price": "111", - "durability": null, - "name": "Cooked meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2143" - }, - { - "durability": null, - "name": "Burnt chicken", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2145" - }, - { - "examine": "Oh dear, it's totally burnt!", - "durability": null, - "name": "Burnt meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2146" - }, - { - "durability": null, - "name": "Burnt meat", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2147" - }, - { - "examine": "A very strange eel.", - "durability": null, - "name": "Raw lava eel", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2148" - }, - { - "examine": "Strange, it looks cooler now it's been cooked.", - "durability": null, - "name": "Lava eel", - "weight": "0.15", - "archery_ticket_price": "0", - "id": "2149" - }, - { - "ge_buy_limit": "10000", - "examine": "A slippery little blighter.", - "grand_exchange_price": "750", - "durability": null, - "name": "Swamp toad", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2150" + "weight": "0.2" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "750", - "durability": null, - "name": "Swamp toad", - "tradeable": "true", + "id": "1630", + "name": "Uncut red topaz", "archery_ticket_price": "0", - "id": "2151" - }, - { - "ge_buy_limit": "1000", - "examine": "They're a gnome delicacy apparently.", - "grand_exchange_price": "661", "durability": null, - "name": "Toad's legs", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2152" - }, - { "ge_buy_limit": "1000", - "grand_exchange_price": "661", - "durability": null, - "name": "Toad's legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2153" - }, - { - "examine": "They're a gnome delicacy apparently.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2154" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2155" - }, - { - "examine": "They're a gnome delicacy apparently.", - "durability": null, - "name": "Spicy toad's legs", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2156" - }, - { - "durability": null, - "name": "Spicy toad's legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2157" - }, - { - "examine": "They're a gnome delicacy apparently.", - "durability": null, - "name": "Seasoned legs", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2158" - }, - { - "durability": null, - "name": "Seasoned legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2159" + "tradeable": "true" }, { - "examine": "They're a gnome delicacy apparently.", - "durability": null, - "name": "Spicy worm", - "tradeable": "true", - "weight": "0.1", + "id": "1631", + "name": "Uncut dragonstone", + "examine": "An uncut dragonstone.", "archery_ticket_price": "0", - "id": "2160" - }, - { "durability": null, - "name": "Spicy worm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2161" - }, - { "ge_buy_limit": "100", - "examine": "They're a gnome delicacy apparently.", - "grand_exchange_price": "24", - "durability": null, - "name": "King worm", + "shop_price": "75000", + "tokkul_price": "1500", "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2162" + "weight": "0.3" }, { + "id": "1632", + "name": "Uncut dragonstone", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "24", - "durability": null, - "name": "King worm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2163" + "tradeable": "true" }, { - "shop_price": "1", - "examine": "A deep tin used to make gnome battas in.", - "durability": null, - "name": "Batta tin", - "tradeable": "true", - "weight": "0.1", + "id": "1633", + "name": "Crushed gem", + "examine": "This gem is crushed and broken.", "archery_ticket_price": "0", - "id": "2164" + "durability": null, + "tradeable": "true" }, { - "shop_price": "10", - "examine": "A shallow tray used to make crunchies in.", - "durability": null, - "name": "Crunchy tray", - "tradeable": "true", - "weight": "0.1", + "id": "1634", + "name": "Crushed gem", "archery_ticket_price": "0", - "id": "2165" + "durability": null, + "tradeable": "true" }, { - "shop_price": "10", - "examine": "A large ovenproof bowl.", - "durability": null, - "name": "Gnomebowl mould", - "tradeable": "true", - "weight": "0.1", + "id": "1635", + "name": "Gold ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2166" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "examine": "Aluft Gianne's favourite dishes.", - "durability": null, - "name": "Gianne's cook book", - "tradeable": "true", - "weight": "0.5", + "id": "1636", + "name": "Gold ring", "archery_ticket_price": "0", - "id": "2167" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Gianne's cook book", - "tradeable": "true", + "id": "1637", + "name": "Sapphire ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2168" + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "It's Aluft Gianne's secret mix of spices.", - "grand_exchange_price": "28", - "durability": null, - "name": "Gnome spice", - "tradeable": "true", - "weight": "0.14", + "id": "1638", + "name": "Sapphire ring", "archery_ticket_price": "0", - "id": "2169" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "28", - "durability": null, - "name": "Gnome spice", - "tradeable": "true", + "id": "1639", + "name": "Emerald ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2170" + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "It's made from a secret recipe.", - "grand_exchange_price": "13", - "durability": null, - "name": "Gianne dough", - "tradeable": "true", - "weight": "0.5", + "id": "1640", + "name": "Emerald ring", "archery_ticket_price": "0", - "id": "2171" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "13", - "durability": null, - "name": "Gianne dough", - "tradeable": "true", + "id": "1641", + "name": "Ruby ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2172" + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "5000", + "shop_price": "2025", + "tradeable": "true" }, { - "examine": "This gnome bowl doesn't look very appetizing.", - "durability": null, - "name": "Picture", - "weight": "1", + "id": "1642", + "name": "Ruby ring", "archery_ticket_price": "0", - "id": "2173" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1643", + "name": "Diamond ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2174" + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "5000", + "shop_price": "3172", + "tradeable": "true" }, { - "durability": null, - "name": "Burnt gnomebowl", - "tradeable": "true", + "id": "1644", + "name": "Diamond ring", "archery_ticket_price": "0", - "id": "2176" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "examine": "This gnomebowl is in the early stages of preparation.", - "durability": null, - "name": "Half baked bowl", - "weight": "0.2", + "id": "1645", + "name": "Dragonstone ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2177" + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "shop_price": "7750", + "tradeable": "true" }, { - "examine": "This gnomebowl needs cooking.", - "durability": null, - "name": "Raw gnomebowl", - "tradeable": "true", + "id": "1646", + "name": "Dragonstone ring", "archery_ticket_price": "0", - "id": "2178" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "This unfinished XX needs YY.", - "durability": null, - "name": "Picture", + "id": "1649", + "name": "Sapphire ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2179" + "durability": null, + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1650", + "name": "Emerald ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2180" + "durability": null, + "tradeable": "true" }, { - "examine": "This unfinished XX needs YY.", - "durability": null, - "name": "Picture", + "id": "1651", + "name": "Ruby ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2181" + "durability": null, + "shop_price": "2025", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1652", + "name": "Diamond ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2182" + "durability": null, + "shop_price": "3172", + "tradeable": "true" }, { - "examine": "This unfinished XX needs YY.", - "durability": null, - "name": "Picture", + "id": "1653", + "name": "Dragonstone ring", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "2183" + "durability": null, + "shop_price": "7750", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1654", + "name": "Gold necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2184" - }, - { + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", "shop_price": "450", - "ge_buy_limit": "1000", - "examine": "Full of creamy, chocolately goodness.", - "grand_exchange_price": "4400", - "durability": null, - "name": "Chocolate bomb", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "2185" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "4400", - "durability": null, - "name": "Chocolate bomb", - "tradeable": "true", + "id": "1655", + "name": "Gold necklace", "archery_ticket_price": "0", - "id": "2186" - }, - { - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "2321", "durability": null, - "name": "Tangled toads' legs", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "2187" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "2321", - "durability": null, - "name": "Tangled toads' legs", - "tradeable": "true", + "id": "1656", + "name": "Sapphire necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2188" - }, - { - "examine": "This unfinished XX needs YY.", "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "2189" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "945", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1657", + "name": "Sapphire necklace", "archery_ticket_price": "0", - "id": "2190" - }, - { - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "454", "durability": null, - "name": "Worm hole", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2191" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "454", - "durability": null, - "name": "Worm hole", - "tradeable": "true", + "id": "1658", + "name": "Emerald necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2192" - }, - { - "examine": "This unfinished XX needs YY.", "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "2193" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "1425", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1659", + "name": "Emerald necklace", "archery_ticket_price": "0", - "id": "2194" - }, - { - "ge_buy_limit": "1000", - "examine": "This looks pretty healthy.", - "grand_exchange_price": "481", "durability": null, - "name": "Veg ball", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2195" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "481", - "durability": null, - "name": "Veg ball", - "tradeable": "true", + "id": "1660", + "name": "Ruby necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2196" - }, - { - "examine": "These crunchies don't look very appetising.", "durability": null, - "name": "Odd crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2197" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "870", + "tradeable": "true" }, { - "durability": null, - "name": "Odd crunchies", - "tradeable": "true", + "id": "1661", + "name": "Ruby necklace", "archery_ticket_price": "0", - "id": "2198" - }, - { "durability": null, - "name": "Burnt crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2200" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "examine": "This crunchy is in the early stages of preparation.", - "durability": null, - "name": "Half baked crunchy", - "tradeable": "true", + "id": "1662", + "name": "Diamond necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2201" - }, - { - "ge_buy_limit": "1000", - "examine": "These crunchies need cooking.", - "grand_exchange_price": "163", "durability": null, - "name": "Raw crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2202" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "3307", + "tradeable": "true" }, { - "examine": "This XX crunchy needs garnishing with YY.", - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1663", + "name": "Diamond necklace", "archery_ticket_price": "0", - "id": "2203" - }, - { "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2204" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "80", - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "255", - "durability": null, - "name": "Worm crunchies", - "tradeable": "true", + "id": "1664", + "name": "Dragon necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2205" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "255", "durability": null, - "name": "Worm crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2206" + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "This XX crunchy needs garnishing with YY.", - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1665", + "name": "Dragon necklace", "archery_ticket_price": "0", - "id": "2207" - }, - { "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2208" + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "70", - "ge_buy_limit": "1000", - "examine": "Yum... smells good.", - "grand_exchange_price": "816", - "durability": null, - "name": "Chocchip crunchies", - "tradeable": "true", + "id": "1668", + "name": "Sapphire necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2209" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "816", "durability": null, - "name": "Chocchip crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2210" + "shop_price": "945", + "tradeable": "true" }, { - "examine": "This XX crunchy needs garnishing with YY.", - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1669", + "name": "Emerald necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2211" - }, - { "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2212" - }, - { - "shop_price": "70", - "ge_buy_limit": "1000", - "examine": "Yum...smells spicy.", - "grand_exchange_price": "101", - "durability": null, - "name": "Spicy crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2213" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "101", - "durability": null, - "name": "Spicy crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2214" - }, - { - "examine": "This XX crunchy needs garnishing with YY.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2215" + "shop_price": "1425", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2216" - }, - { - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "1228", - "durability": null, - "name": "Toad crunchies", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2217" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1228", - "durability": null, - "name": "Toad crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2218" - }, - { - "ge_buy_limit": "1000", - "examine": "A premade Worm Batta.", - "grand_exchange_price": "130", - "durability": null, - "name": "Premade w'm batta", - "tradeable": "true", - "weight": "0.2", + "id": "1670", + "name": "Ruby necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2219" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "130", "durability": null, - "name": "Premade w'm batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2220" + "shop_price": "870", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A Premade Toad Batta.", - "grand_exchange_price": "127", - "durability": null, - "name": "Premade t'd batta", - "tradeable": "true", - "weight": "0.2", + "id": "1671", + "name": "Diamond necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2221" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "127", "durability": null, - "name": "Premade t'd batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2222" + "shop_price": "3307", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A Premade Cheese and Tomato Batta.", - "grand_exchange_price": "137", - "durability": null, - "name": "Premade c+t batta", - "tradeable": "true", - "weight": "0.2", + "id": "1672", + "name": "Dragon necklace", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "2223" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "137", "durability": null, - "name": "Premade c+t batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2224" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A premade Fruit Batta.", - "grand_exchange_price": "131", - "durability": null, - "name": "Premade fr't batta", - "tradeable": "true", - "weight": "0.2", + "id": "1673", + "name": "Gold amulet", + "examine": "It needs a string so I can wear it.", "archery_ticket_price": "0", - "id": "2225" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "131", "durability": null, - "name": "Premade fr't batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2226" + "ge_buy_limit": "5000", + "shop_price": "350", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A Premade Vegetable Batta.", - "grand_exchange_price": "134", - "durability": null, - "name": "Premade veg batta", - "tradeable": "true", - "weight": "0.2", + "id": "1674", + "name": "Gold amulet", "archery_ticket_price": "0", - "id": "2227" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "134", "durability": null, - "name": "Premade veg batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2228" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A premade Chocolate Bomb.", - "grand_exchange_price": "1227", - "durability": null, - "name": "Premade choc bomb", - "tradeable": "true", - "weight": "0.2", + "id": "1675", + "name": "Sapphire amulet", + "examine": "It needs a string so I can wear it.", "archery_ticket_price": "0", - "id": "2229" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1227", "durability": null, - "name": "Premade choc bomb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2230" + "ge_buy_limit": "5000", + "shop_price": "810", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A premade Tangled Toads Legs.", - "grand_exchange_price": "867", - "durability": null, - "name": "Premade ttl", - "tradeable": "true", - "weight": "0.2", + "id": "1676", + "name": "Sapphire amulet", "archery_ticket_price": "0", - "id": "2231" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "867", "durability": null, - "name": "Premade ttl", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2232" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A premade Worm Hole.", - "grand_exchange_price": "237", - "durability": null, - "name": "Premade worm hole", - "tradeable": "true", - "weight": "0.2", + "id": "1677", + "name": "Emerald amulet", + "examine": "It needs a string so I can wear it.", "archery_ticket_price": "0", - "id": "2233" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "237", "durability": null, - "name": "Premade worm hole", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2234" + "ge_buy_limit": "5000", + "shop_price": "1147", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A premade Vegetable Ball.", - "grand_exchange_price": "233", - "durability": null, - "name": "Premade veg ball", - "tradeable": "true", - "weight": "0.2", + "id": "1678", + "name": "Emerald amulet", "archery_ticket_price": "0", - "id": "2235" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "233", "durability": null, - "name": "Premade veg ball", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2236" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "Some Premade Worm Crunchies.", - "grand_exchange_price": "76", - "durability": null, - "name": "Premade w'm crun", - "tradeable": "true", - "weight": "0.2", + "id": "1679", + "name": "Ruby amulet", + "examine": "It needs a string so I can wear it.", "archery_ticket_price": "0", - "id": "2237" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "76", + "destroy": "true", "durability": null, - "name": "Premade w'm crun", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2238" + "ge_buy_limit": "5000", + "shop_price": "2025", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "Some Premade chocchip crunchies.", - "grand_exchange_price": "95", - "durability": null, - "name": "Premade ch' crunch", - "tradeable": "true", - "weight": "0.2", + "id": "1680", + "name": "Ruby amulet", "archery_ticket_price": "0", - "id": "2239" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "95", "durability": null, - "name": "Premade ch' crunch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2240" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "Some premade Spicy Crunchies.", - "grand_exchange_price": "103", - "durability": null, - "name": "Premade s'y crunch", - "tradeable": "true", - "weight": "0.2", + "id": "1681", + "name": "Diamond amulet", + "examine": "It needs a string so I can wear it.", "archery_ticket_price": "0", - "id": "2241" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "103", "durability": null, - "name": "Premade s'y crunch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2242" + "ge_buy_limit": "5000", + "shop_price": "3307", + "tradeable": "true" }, { - "shop_price": "80", - "ge_buy_limit": "1000", - "examine": "Some premade Toad Crunchies.", - "grand_exchange_price": "43", - "durability": null, - "name": "Premade t'd crunch", - "tradeable": "true", - "weight": "0.2", + "id": "1682", + "name": "Diamond amulet", "archery_ticket_price": "0", - "id": "2243" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "43", "durability": null, - "name": "Premade t'd crunch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2244" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "examine": "This batta doesn't look very appetising.", - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1683", + "name": "Dragonstone ammy", + "examine": "It needs a string so I can wear it.", "archery_ticket_price": "0", - "id": "2245" - }, - { "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2246" + "ge_buy_limit": "100", + "tradeable": "true" }, { - "durability": null, - "name": "Burnt batta", - "tradeable": "true", + "id": "1684", + "name": "Dragonstone ammy", "archery_ticket_price": "0", - "id": "2248" - }, - { - "examine": "This gnome batta is in the early stages of preparation.", "durability": null, - "name": "Half baked batta", - "archery_ticket_price": "0", - "id": "2249" + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "1", - "examine": "This gnome batta needs cooking.", - "durability": null, - "name": "Raw batta", + "id": "1687", + "name": "Sapphire amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2250" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "2251" + "shop_price": "810", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1688", + "name": "Emerald amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2252" - }, - { - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "140", "durability": null, - "name": "Worm batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2253" + "shop_price": "1147", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "140", - "durability": null, - "name": "Worm batta", - "tradeable": "true", + "id": "1689", + "name": "Ruby amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2254" - }, - { - "shop_price": "78", - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "271", + "destroy": "true", "durability": null, - "name": "Toad batta", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2255" + "shop_price": "2025", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "271", - "durability": null, - "name": "Toad batta", - "tradeable": "true", + "id": "1690", + "name": "Diamond amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2256" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "2257" + "shop_price": "3307", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1691", + "name": "Dragonstone ammy", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2258" - }, - { - "ge_buy_limit": "1000", - "examine": "This smells really good.", - "grand_exchange_price": "260", "durability": null, - "name": "Cheese+tom batta", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2259" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "260", - "durability": null, - "name": "Cheese+tom batta", - "tradeable": "true", + "id": "1692", + "name": "Gold amulet", + "examine": "A plain gold amulet.", "archery_ticket_price": "0", - "id": "2260" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2261" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "350", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1693", + "name": "Gold amulet", "archery_ticket_price": "0", - "id": "2262" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2263" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1694", + "name": "Sapphire amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2264" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2265" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "810", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1695", + "name": "Sapphire amulet", "archery_ticket_price": "0", - "id": "2266" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2267" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1696", + "name": "Emerald amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2268" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2269" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "1147", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1697", + "name": "Emerald amulet", "archery_ticket_price": "0", - "id": "2270" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2271" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1698", + "name": "Ruby amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2272" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", + "destroy": "true", "durability": null, - "name": "Unfinished batta", - "archery_ticket_price": "0", - "id": "2273" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "2025", + "tradeable": "true" }, { - "durability": null, - "name": "Unfinished batta", - "tradeable": "true", + "id": "1699", + "name": "Ruby amulet", "archery_ticket_price": "0", - "id": "2274" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "2275" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1700", + "name": "Diamond amulet", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2276" - }, - { - "ge_buy_limit": "1000", - "examine": "It actually smells quite good.", - "grand_exchange_price": "303", "durability": null, - "name": "Fruit batta", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2277" + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "3307", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "303", - "durability": null, - "name": "Fruit batta", - "tradeable": "true", + "id": "1701", + "name": "Diamond amulet", "archery_ticket_price": "0", - "id": "2278" - }, - { - "shop_price": "1", - "examine": "This XX batta needs garnishing with YY.", "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "2279" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "durability": null, - "name": "Picture", - "tradeable": "true", + "id": "1702", + "name": "Dragonstone ammy", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "2280" - }, - { - "ge_buy_limit": "1000", - "examine": "Well... It looks healthy.", - "grand_exchange_price": "240", "durability": null, - "name": "Vegetable batta", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2281" + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "240", - "durability": null, - "name": "Vegetable batta", - "tradeable": "true", + "id": "1703", + "name": "Dragonstone ammy", "archery_ticket_price": "0", - "id": "2282" - }, - { - "shop_price": "4", - "ge_buy_limit": "1000", - "examine": "I need to add some tomato next.", - "grand_exchange_price": "418", "durability": null, - "name": "Pizza base", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2283" + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "418", - "durability": null, - "name": "Pizza base", - "tradeable": "true", + "id": "1704", + "name": "Amulet of glory", + "examine": "A very powerful dragonstone amulet.", "archery_ticket_price": "0", - "id": "2284" - }, - { - "ge_buy_limit": "1000", - "examine": "I need to add some cheese next.", - "grand_exchange_price": "366", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", "durability": null, - "name": "Incomplete pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2285" + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "366", + "id": "1705", + "name": "Amulet of glory", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Incomplete pizza", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2286" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "This needs cooking.", - "grand_exchange_price": "1141", - "durability": null, - "name": "Uncooked pizza", - "tradeable": "true", + "id": "1706", + "name": "Amulet of glory(1)", + "examine": "A dragonstone amulet with 1 magic charge.", "archery_ticket_price": "0", - "id": "2287" + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1141", + "id": "1707", + "name": "Amulet of glory(1)", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Uncooked pizza", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2288" + "durability": null, + "tradeable": "true" }, { + "id": "1708", + "name": "Amulet of glory(2)", + "examine": "A dragonstone amulet with 2 magic charges.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "1709", + "name": "Amulet of glory(2)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1710", + "name": "Amulet of glory(3)", + "examine": "A dragonstone amulet with 3 magic charges.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "1711", + "name": "Amulet of glory(3)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1712", + "name": "Amulet of glory(4)", + "examine": "A dragonstone amulet with 4 magic charges.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1713", + "name": "Amulet of glory(4)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1714", + "name": "Unstrung symbol", + "examine": "It needs a string so I can wear it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", "shop_price": "200", - "ge_buy_limit": "1000", - "examine": "A cheese and tomato pizza.", - "grand_exchange_price": "1357", - "durability": null, - "name": "Plain pizza", - "tradeable": "true", - "weight": "0.66", - "archery_ticket_price": "0", - "id": "2289" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1357", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Plain pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2290" - }, - { - "shop_price": "200", - "ge_buy_limit": "1000", - "examine": "Half of this plain pizza has been eaten.", - "grand_exchange_price": "238", - "durability": null, - "name": "1/2 plain pizza", - "tradeable": "true", - "weight": "0.66", - "archery_ticket_price": "0", - "id": "2291" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "238", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "1/2 plain pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2292" - }, - { - "ge_buy_limit": "1000", - "examine": "A pizza with bits of meat on it.", - "grand_exchange_price": "1012", - "durability": null, - "name": "Meat pizza", - "tradeable": "true", - "weight": "0.83", - "archery_ticket_price": "0", - "id": "2293" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1012", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Meat pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2294" - }, - { - "ge_buy_limit": "1000", - "examine": "Half of this meat pizza has been eaten.", - "grand_exchange_price": "339", - "durability": null, - "name": "1/2 meat pizza", - "tradeable": "true", - "weight": "0.83", - "archery_ticket_price": "0", - "id": "2295" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "339", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "1/2 meat pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2296" - }, - { - "ge_buy_limit": "1000", - "examine": "A pizza with anchovies.", - "grand_exchange_price": "1573", - "durability": null, - "name": "Anchovy pizza", - "tradeable": "true", - "weight": "0.83", - "archery_ticket_price": "0", - "id": "2297" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1573", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Anchovy pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2298" - }, - { - "ge_buy_limit": "1000", - "examine": "Half of this anchovy pizza has been eaten.", - "grand_exchange_price": "44", - "durability": null, - "name": "1/2 anchovy pizza", - "tradeable": "true", - "weight": "0.83", - "archery_ticket_price": "0", - "id": "2299" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "44", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "1/2 anchovy pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2300" - }, - { - "ge_buy_limit": "1000", - "examine": "A pizza with bits of pineapple on it.", - "grand_exchange_price": "1469", - "durability": null, - "name": "Pineapple pizza", - "tradeable": "true", - "weight": "0.83", - "archery_ticket_price": "0", - "id": "2301" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1469", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Pineapple pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2302" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "156", - "examine": "Half of this pineapple pizza has been eaten.", - "durability": null, - "name": "1/2 p'apple pizza", - "archery_ticket_price": "0", - "id": "2303" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "156", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "1/2 p'apple pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2304" - }, - { - "examine": "Oh dear!", - "durability": null, - "name": "Burnt pizza", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2306" - }, - { - "ge_buy_limit": "1000", - "examine": "Some uncooked dough.", - "grand_exchange_price": "158", - "durability": null, - "name": "Bread dough", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2307" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "158", - "durability": null, - "name": "Bread dough", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2308" - }, - { - "shop_price": "24", - "ge_buy_limit": "1000", - "examine": "Nice crispy bread.", - "grand_exchange_price": "110", - "durability": null, - "name": "Bread", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2309" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "110", - "durability": null, - "name": "Bread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2310" - }, - { - "durability": null, - "name": "Burnt bread", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2312" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "Deceptively pie shaped.", - "grand_exchange_price": "174", - "durability": null, - "name": "Pie dish", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2313" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "174", - "durability": null, - "name": "Pie dish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2314" - }, - { - "ge_buy_limit": "1000", - "examine": "I need to find a filling for this pie.", - "grand_exchange_price": "887", - "durability": null, - "name": "Pie shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2315" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "887", - "durability": null, - "name": "Pie shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2316" - }, - { - "ge_buy_limit": "1000", - "examine": "This would be much tastier cooked.", - "grand_exchange_price": "781", - "durability": null, - "name": "Uncooked apple pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2317" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "781", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Uncooked apple pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2318" - }, - { - "ge_buy_limit": "1000", - "examine": "This would be much healthier cooked.", - "grand_exchange_price": "747", - "durability": null, - "name": "Uncooked meat pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2319" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "747", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Uncooked meat pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2320" - }, - { - "ge_buy_limit": "1000", - "examine": "This would be much more appetising cooked.", - "grand_exchange_price": "802", - "durability": null, - "name": "Uncooked berry pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2321" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "802", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Uncooked berry pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2322" - }, - { - "shop_price": "140", - "ge_buy_limit": "1000", - "examine": "Mmm Apple pie.", - "grand_exchange_price": "246", - "durability": null, - "name": "Apple pie", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2323" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "246", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Apple pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2324" - }, - { - "ge_buy_limit": "1000", - "examine": "Looks tasty.", - "grand_exchange_price": "534", - "durability": null, - "name": "Redberry pie", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2325" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "534", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Redberry pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2326" - }, - { - "shop_price": "16", - "ge_buy_limit": "1000", - "grand_exchange_price": "160", - "examine": "Not for vegetarians.", - "durability": null, - "name": "Meat pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2327" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "160", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Meat pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2328" - }, - { - "examine": "I think I left it on the stove too long.", - "durability": null, - "name": "Burnt pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2330" - }, - { - "shop_price": "16", - "ge_buy_limit": "1000", - "grand_exchange_price": "174", - "examine": "Half of it is suitable for vegetarians.", - "durability": null, - "name": "Half a meat pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2331" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "174", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half a meat pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2332" - }, - { - "ge_buy_limit": "1000", - "examine": "So tasty I kept some for later.", - "grand_exchange_price": "248", - "durability": null, - "name": "Half a redberry pie", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2333" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "248", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half a redberry pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2334" - }, - { - "shop_price": "140", - "ge_buy_limit": "1000", - "examine": "Mmm half an apple pie.", - "grand_exchange_price": "146", - "durability": null, - "name": "Half an apple pie", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2335" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "146", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half an apple pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2336" - }, - { - "ge_buy_limit": "1000", - "examine": "Raw meat from the oomlie bird.", - "grand_exchange_price": "155", - "durability": null, - "name": "Raw oomlie", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2337" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "155", - "durability": null, - "name": "Raw oomlie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2338" - }, - { - "examine": "A thick green palm leaf used by natives to cook meat.", - "durability": null, - "name": "Palm leaf", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2339" - }, - { - "examine": "A thick green palm leaf used by natives to cook meat.", - "durability": null, - "name": "Palm leaf", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2340" - }, - { - "ge_buy_limit": "1000", - "examine": "Oomlie meat in a palm leaf pouch. It just needs to be cooked.", - "grand_exchange_price": "814", - "durability": null, - "name": "Wrapped oomlie", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "2341" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "814", - "durability": null, - "name": "Wrapped oomlie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2342" - }, - { - "ge_buy_limit": "1000", - "examine": "Deliciously cooked oomlie meat in a palm leaf pouch.", - "grand_exchange_price": "1126", - "durability": null, - "name": "Cooked oomlie wrap", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "2343" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1126", - "durability": null, - "name": "Cooked oomlie wrap", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2344" - }, - { - "durability": null, - "name": "Burnt oomlie wrap", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2346" - }, - { - "shop_price": "13", - "ge_buy_limit": "1000", - "examine": "Good for hitting things!", - "grand_exchange_price": "37", - "durability": null, - "name": "Hammer", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "2347" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "37", - "durability": null, - "name": "Hammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2348" - }, - { - "shop_price": "10", - "ge_buy_limit": "10000", - "examine": "It's a bar of bronze.", - "grand_exchange_price": "268", - "durability": null, - "name": "Bronze bar", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "2349" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "268", - "durability": null, - "name": "Bronze bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2350" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a bar of iron.", - "grand_exchange_price": "493", - "durability": null, - "name": "Iron bar", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "2351" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "493", - "durability": null, - "name": "Iron bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2352" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a bar of steel.", - "grand_exchange_price": "1266", - "durability": null, - "name": "Steel bar", - "tradeable": "true", - "weight": "1.81", - "archery_ticket_price": "0", - "id": "2353" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1266", - "durability": null, - "name": "Steel bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2354" + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "It's a bar of silver.", - "grand_exchange_price": "274", - "durability": null, - "name": "Silver bar", - "tradeable": "true", - "weight": "1.81", + "id": "1715", + "name": "Unstrung symbol", "archery_ticket_price": "0", - "id": "2355" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "274", "durability": null, - "name": "Silver bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2356" + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "It's a bar of gold.", - "grand_exchange_price": "107", - "durability": null, - "name": "Gold bar", - "tradeable": "true", - "weight": "1.81", + "id": "1716", + "name": "Unblessed symbol", + "examine": "A symbol of Saradomin.", "archery_ticket_price": "0", - "id": "2357" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "107", "durability": null, - "name": "Gold bar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2358" - }, - { + "equipment_slot": "2", + "ge_buy_limit": "5000", "shop_price": "120", + "tradeable": "true" + }, + { + "id": "1717", + "name": "Unblessed symbol", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1718", + "name": "Holy symbol", + "examine": "A blessed holy symbol of Saradomin.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,2,2,2,2,2,3,0,8,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "1719", + "name": "Holy symbol", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1720", + "name": "Unstrung emblem", + "examine": "It needs a string so I can wear it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1721", + "name": "Unstrung emblem", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1722", + "name": "Unpowered symbol", + "examine": "An unholy symbol of Zamorak.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "1723", + "name": "Unpowered symbol", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1724", + "name": "Unholy symbol", + "examine": "An unholy symbol of Zamorak.", + "archery_ticket_price": "0", + "bonuses": "2,2,2,2,2,0,0,0,0,0,0,0,8,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "135", + "tradeable": "true" + }, + { + "id": "1725", + "name": "Amulet of strength", + "examine": "An enchanted ruby amulet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1726", + "name": "Amulet of strength", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1727", + "name": "Amulet of magic", + "examine": "An enchanted sapphire amulet of magic.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "900", + "tradeable": "true" + }, + { + "id": "1728", + "name": "Amulet of magic", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1729", + "name": "Amulet of defence", + "examine": "An enchanted emerald amulet of protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "1275", + "tradeable": "true" + }, + { + "id": "1730", + "name": "Amulet of defence", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1731", + "name": "Amulet of power", + "examine": "An enchanted diamond amulet of power.", + "archery_ticket_price": "0", + "bonuses": "6,6,6,6,6,6,6,6,6,6,6,6,1,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "shop_price": "3525", + "tradeable": "true" + }, + { + "id": "1732", + "name": "Amulet of power", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1733", + "name": "Needle", + "examine": "Used with a thread to make clothes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "1734", + "name": "Thread", + "examine": "Use with a needle to make clothes.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", + "shop_price": "4", + "tradeable": "true" + }, + { + "id": "1735", + "name": "Shears", + "examine": "For shearing sheep.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1736", + "name": "Shears", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1737", + "name": "Wool", + "examine": "I think this came from a sheep.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.14" + }, + { + "id": "1738", + "name": "Wool", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1739", + "name": "Cowhide", + "examine": "I should take this to the tannery.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "1740", + "name": "Cowhide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1741", + "name": "Leather", + "examine": "It's a piece of leather.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "2.25" + }, + { + "id": "1742", + "name": "Leather", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1743", + "name": "Hard leather", + "examine": "It's a piece of hard leather.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "1744", + "name": "Hard leather", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1745", + "name": "Green d-leather", + "examine": "It's a piece of prepared green dragon hide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "1746", + "name": "Green d-leather", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1747", + "name": "Black dragonhide", + "examine": "The scaly rough hide from a Black Dragon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "1748", + "name": "Black dragonhide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1749", + "name": "Red dragonhide", + "examine": "The scaly rough hide from a red dragon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3" + }, + { + "id": "1750", + "name": "Red dragonhide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1751", + "name": "Blue dragonhide", + "examine": "The scaly rough hide from a blue dragon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "1752", + "name": "Blue dragonhide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1753", + "name": "Green dragonhide", + "examine": "The scaly rough hide from a green dragon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "1754", + "name": "Green dragonhide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1755", + "name": "Chisel", + "examine": "Good for detailed crafting.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "14", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1756", + "name": "Chisel", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1757", + "name": "Brown apron", + "examine": "A mostly clean apron.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "0.45" + }, + { + "id": "1758", + "name": "Brown apron", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1759", + "name": "Ball of wool", + "examine": "Spun from sheeps' wool.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1760", + "name": "Ball of wool", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1761", + "name": "Soft clay", + "examine": "Clay soft enough to mould.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1762", + "name": "Soft clay", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1763", + "name": "Red dye", + "examine": "A little bottle of red dye.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true" + }, + { + "id": "1764", + "name": "Red dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1765", + "name": "Yellow dye", + "examine": "A little bottle of yellow dye.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true" + }, + { + "id": "1766", + "name": "Yellow dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1767", + "name": "Blue dye", + "examine": "A little bottle of blue dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true", + "weight": "1" + }, + { + "id": "1768", + "name": "Blue dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1769", + "name": "Orange dye", + "examine": "A little bottle of orange dye.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1770", + "name": "Orange dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1771", + "name": "Green dye", + "examine": "A little bottle of green dye.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true" + }, + { + "id": "1772", + "name": "Green dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1773", + "name": "Purple dye", + "examine": "A little bottle of purple dye.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true" + }, + { + "id": "1774", + "name": "Purple dye", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1775", + "name": "Molten glass", + "examine": "Hot glass ready to be blown into useful objects.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1776", + "name": "Molten glass", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1777", + "name": "Bow string", + "examine": "I need a bow stave to attach this to.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1778", + "name": "Bow string", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1779", + "name": "Flax", + "examine": "A plant cultivated for fibres (ground); I should use this with a spinning wheel (item).", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "73", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1780", + "name": "Flax", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "1781", + "name": "Soda ash", + "examine": "One of the ingredients for making glass.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.09" + }, + { + "id": "1782", + "name": "Soda ash", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1783", + "name": "Bucket of sand", + "examine": "One of the ingredients for making glass.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "2.5" + }, + { + "id": "1784", + "name": "Bucket of sand", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1785", + "name": "Glassblowing pipe", + "examine": "Used to form molten glass into useful items.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1786", + "name": "Glassblowing pipe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1787", + "name": "Unfired pot", + "examine": "I need to put this in a pottery oven.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1788", + "name": "Unfired pot", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1789", + "name": "Unfired pie dish", + "examine": "I need to put this in a pottery oven.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1790", + "name": "Unfired pie dish", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1791", + "name": "Unfired bowl", + "examine": "I need to put this in a pottery oven.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "32", + "tradeable": "true" + }, + { + "id": "1792", + "name": "Unfired bowl", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1793", + "name": "Woad leaf", + "examine": "A slightly bluish leaf.", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "1794", + "name": "Bronze wire", + "examine": "Useful for crafting items.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1795", + "name": "Bronze wire", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1796", + "name": "Silver necklace", + "examine": "Anna's shiny silver coated necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "1" + }, + { + "id": "1797", + "name": "Silver necklace", + "examine": "Anna's shiny silver coated necklace coated with a thin layer of flour.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "1" + }, + { + "id": "1798", + "name": "Silver cup", + "examine": "Bob's shiny silver coated tea cup.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1799", + "name": "Silver cup", + "examine": "Bob's shiny silver coated tea cup coated with a thin layer of flour.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1800", + "name": "Silver bottle", + "examine": "Carol's shiny silver coated bottle.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1801", + "name": "Silver bottle", + "examine": "Carol's shiny silver coated bottle coated with a thin layer of flour.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1802", + "name": "Silver book", + "examine": "David's shiny silver coated book.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1803", + "name": "Silver book", + "examine": "David's shiny silver coated book coated with a thin layer of flour.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1804", + "name": "Silver needle", + "examine": "Elizabeth's shiny silver coated needle.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1805", + "name": "Silver needle", + "examine": "Elizabeth's shiny silver coated needle coated with a thin layer of flour.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1806", + "name": "Silver pot", + "examine": "Frank's shiny silver coated pot.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1807", + "name": "Silver pot", + "examine": "Frank's shiny silver coated pot coated with a thin layer of flour.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1808", + "name": "Criminal's thread", + "examine": "Some red thread found at the murder scene.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1809", + "name": "Criminal's thread", + "examine": "Some green thread found at the murder scene.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1810", + "name": "Criminal's thread", + "examine": "Some blue thread found at the murder scene.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1811", + "name": "Flypaper", + "examine": "A piece of fly paper. It's sticky.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1812", + "name": "Pungent pot", + "examine": "A pot found at the murder scene, with a sickly odour.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1813", + "name": "Criminal's dagger", + "examine": "A flimsy-looking dagger found at the crime scene.", + "archery_ticket_price": "0", + "attack_audios": "2517,2517,2500,2517", + "durability": null + }, + { + "id": "1814", + "name": "Criminal's dagger", + "examine": "A flimsy looking dagger found at the crime scene coated with a thin layer of flour.", + "archery_ticket_price": "0", + "attack_audios": "2517,2517,2500,2517", + "durability": null + }, + { + "id": "1815", + "name": "Killer's print", + "examine": "The fingerprints of the murderer.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1816", + "name": "Anna's print", + "examine": "An imprint of Anna's fingerprint.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1817", + "name": "Bob's print", + "examine": "An imprint of Bob's fingerprint.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1818", + "name": "Carol's print", + "examine": "An imprint of Carol's fingerprint.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1819", + "name": "David's print", + "examine": "An imprint of David's fingerprint.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1820", + "name": "Elizabeth's print", + "examine": "An imprint of Elizabeth's fingerprint.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1821", + "name": "Frank's print", + "examine": "An imprint of Frank's fingerprint.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1822", + "name": "Unknown print", + "examine": "An unidentified fingerprint taken from the murder weapon.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1823", + "name": "Waterskin(4)", + "examine": "A full waterskin with four portions of water.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "30", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1824", + "name": "Waterskin(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1825", + "name": "Waterskin(3)", + "examine": "A nearly full waterskin with three portions of water.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "30", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1826", + "name": "Waterskin(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1827", + "name": "Waterskin(2)", + "examine": "A half empty waterskin with two portions of water.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "30", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1828", + "name": "Waterskin(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1829", + "name": "Waterskin(1)", + "examine": "A nearly empty waterskin with one portion of water.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "30", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1830", + "name": "Waterskin(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1831", + "name": "Waterskin(0)", + "examine": "A completely empty waterskin - you'll need to fill it up.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "30", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1832", + "name": "Waterskin(0)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1833", + "name": "Desert shirt", + "examine": "A cool, light desert shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "40", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1834", + "name": "Desert shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1835", + "name": "Desert robe", + "examine": "A cool, light desert robe.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "40", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1836", + "name": "Desert robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1837", + "name": "Desert boots", + "examine": "Comfortable desert shoes.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "1838", + "name": "Desert boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1839", + "name": "Metal key", + "examine": "This key is crudely made. It came from the mining camp Mercenary Captain.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1840", + "name": "Cell door key", + "examine": "A metallic key, usually used by prison guards. (Tourist Trap)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1841", + "name": "Barrel", + "examine": "An empty barrel/A Splendid barrel.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "10" + }, + { + "id": "1842", + "name": "Ana in a barrel", + "examine": "Inventory: A mining barrel with Ana in it.While in the mine cart: It's Ana... in a barrel... in a mine cart.", + "archery_ticket_price": "0", + "durability": null, + "weight": "32" + }, + { + "id": "1843", + "name": "Wrought iron key", + "examine": "This key unlocks a very sturdy gate. Ana gave me this key. (Tourist Trap)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1844", + "name": "Slave shirt", + "examine": "A filthy, smelly, flea infested shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "0.9" + }, + { + "id": "1845", + "name": "Slave robe", + "examine": "A filthy, smelly, flea infested robe.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "0.9" + }, + { + "id": "1846", + "name": "Slave boots", + "examine": "A set of filthy, smelly, flea infested desert slave boots.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "10", + "weight": "0.6" + }, + { + "id": "1847", + "name": "Scrumpled paper", + "examine": "A piece of paper with barely legible writing - looks like a recipe!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1848", + "name": "Shantay disclaimer", + "examine": "Very important information.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5" + }, + { + "id": "1849", + "name": "Prototype dart", + "examine": "A prototype throwing dart.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1850", + "name": "Technical plans", + "examine": "Plans of a technical nature.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "1851", + "name": "Tenti pineapple", + "examine": "The most delicious of pineapples.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "1852", + "name": "Bedabin key", + "examine": "A key to the chest in Captain Siad's room.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1853", + "name": "Prototype dart tip", + "examine": "A protoype dart tip - it looks deadly.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1854", + "name": "Shantay pass", + "examine": "Allows you to pass through the Shantay pass into the Kharid Desert.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5" + }, + { + "id": "1856", + "name": "Guide book", + "examine": "A Tourist's Guide to Ardougne.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "1857", + "name": "Totem", + "examine": "The Rantuki tribe's totem.", + "archery_ticket_price": "0", + "durability": null, + "weight": "3" + }, + { + "id": "1858", + "name": "Address label", + "examine": "It says 'To Lord Handelmort, Handelmort Mansion'.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "1859", + "name": "Raw ugthanki meat", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.75" + }, + { + "id": "1860", + "name": "Raw ugthanki meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1861", + "name": "Ugthanki meat", + "examine": "I need to cook this first / Freshly cooked ugthanki meat.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.75" + }, + { + "id": "1862", + "name": "Ugthanki meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1863", + "name": "Pitta dough", + "examine": "I need to cook this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "9", + "tradeable": "true", + "weight": "0.14" + }, + { + "id": "1864", + "name": "Pitta dough", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1865", + "name": "Pitta bread", + "examine": "Nicely baked pitta bread. Needs more ingredients to make a kebab.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1866", + "name": "Pitta bread", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1867", + "name": "Burnt pitta bread", + "examine": "It's all burnt.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1868", + "name": "Burnt pitta bread", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1869", + "name": "Chopped tomato", + "examine": "A mixture of tomatoes in a bowl.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "1870", + "name": "Chopped tomato", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1871", + "name": "Chopped onion", + "examine": "A mixture of onions in a bowl.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1872", + "name": "Chopped onion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1873", + "name": "Chopped ugthanki", + "examine": "Strips of ugthanki meat in a bowl.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1874", + "name": "Chopped ugthanki", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1875", + "name": "Onion & tomato", + "examine": "A mixture of chopped onions and tomatoes in a bowl", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1876", + "name": "Onion & tomato", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1877", + "name": "Ugthanki & onion", + "examine": "A mixture of chopped onions and ugthanki meat in a bowl.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "26", + "tradeable": "true" + }, + { + "id": "1878", + "name": "Ugthanki & onion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1879", + "name": "Ugthanki & tomato", + "examine": "A mixture of chopped tomatoes and ugthanki meat in a bowl.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "1880", + "name": "Ugthanki & tomato", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1881", + "name": "Kebab mix", + "examine": "A mixture of chopped tomatoes, onions and ugthanki meat in a bowl", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1882", + "name": "Kebab mix", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1883", + "name": "Ugthanki kebab", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1884", + "name": "Ugthanki kebab", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1885", + "name": "Ugthanki kebab", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1886", + "name": "Ugthanki kebab", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1887", + "name": "Cake tin", + "examine": "Useful for baking cakes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "10", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1888", + "name": "Cake tin", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1889", + "name": "Uncooked cake", + "examine": "Now all I need to do is cook it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1890", + "name": "Uncooked cake", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1891", + "name": "Cake", + "examine": "A plain sponge cake.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "50", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1892", + "name": "Cake", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1893", + "name": "2/3 cake", + "examine": "A plain sponge cake.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "50", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1894", + "name": "2/3 cake", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1895", + "name": "Slice of cake", + "examine": "A plain sponge cake.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "50", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1896", + "name": "Slice of cake", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1897", + "name": "Chocolate cake", + "examine": "This looks very tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1898", + "name": "Chocolate cake", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1899", + "name": "2/3 chocolate cake", + "examine": "This looks very tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1900", + "name": "2/3 chocolate cake", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1901", + "name": "Chocolate slice", + "examine": "This looks very tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1902", + "name": "Chocolate slice", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1904", + "name": "Burnt cake", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1905", + "name": "Asgarnian ale", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "1906", + "name": "Asgarnian ale", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1907", + "name": "Wizard's mind bomb", + "examine": "It's got strange bubbles in it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "1908", + "name": "Wizard's mind bomb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1909", + "name": "Greenman's ale", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "1910", + "name": "Greenman's ale", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1911", + "name": "Dragon bitter", + "examine": "A glass of bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "1912", + "name": "Dragon bitter", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1913", + "name": "Dwarven stout", + "examine": "A pint of thick dark beer.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "1914", + "name": "Dwarven stout", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1915", + "name": "Grog", + "examine": "A murky glass full of your average, everyday pirate slosh.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true", + "weight": "2" + }, + { + "id": "1916", + "name": "Grog", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1917", + "name": "Beer", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "1918", + "name": "Beer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1919", + "name": "Beer glass", + "examine": "I need to fill this with beer.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "1920", + "name": "Beer glass", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1921", + "name": "Bowl of water", + "examine": "It's a bowl of water.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1922", + "name": "Bowl of water", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1923", + "name": "Bowl", + "examine": "Useful for mixing things.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "4", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1924", + "name": "Bowl", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1925", + "name": "Bucket", + "examine": "It's an empty bucket.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "1926", + "name": "Bucket", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1927", + "name": "Bucket of milk", + "examine": "It's a bucket of milk.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "12", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "1928", + "name": "Bucket of milk", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1929", + "name": "Bucket of water", + "examine": "It's a bucket of water.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3" + }, + { + "id": "1930", + "name": "Bucket of water", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1931", + "name": "Empty pot", + "examine": "This pot is empty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.45" + }, + { + "id": "1932", + "name": "Empty pot", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1933", + "name": "Pot of flour", + "examine": "There is flour in this pot.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "14", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "1934", + "name": "Pot of flour", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1935", + "name": "Jug", + "examine": "This jug is empty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "1", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1936", + "name": "Jug", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1937", + "name": "Jug of water", + "examine": "It's full of water.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "1", + "tradeable": "true", + "weight": "1" + }, + { + "id": "1938", + "name": "Jug of water", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1939", + "name": "Swamp tar", + "examine": "A foul smelling thick tar like substance.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "1940", + "name": "Raw swamp paste", + "examine": "A tar-like substance mixed with flour and warmed.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "38", + "tradeable": "true" + }, + { + "id": "1941", + "name": "Swamp paste", + "examine": "A tar-like substance mixed with flour and warmed.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "38", + "tradeable": "true" + }, + { + "id": "1942", + "name": "Potato", + "examine": "This could be used to make a good stew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "shop_price": "11", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1943", + "name": "Potato", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "1944", + "name": "Egg", + "examine": "A nice fresh egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "1945", + "name": "Egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1946", + "name": "Flour", + "examine": "There is flour in this pot.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "14", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "1947", + "name": "Grain", + "examine": "Some wheat heads.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.6" + }, + { + "id": "1948", + "name": "Grain", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1949", + "name": "Chef's hat", + "examine": "What a silly hat.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "1950", + "name": "Chef's hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1951", + "name": "Redberries", + "examine": "Very bright red berries.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "3", + "tradeable": "true", + "weight": "1" + }, + { + "id": "1952", + "name": "Redberries", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1953", + "name": "Pastry dough", + "examine": "Potentially pastry.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.16" + }, + { + "id": "1954", + "name": "Pastry dough", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1955", + "name": "Cooking apple", + "examine": "Keeps the doctor away.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "36", + "tradeable": "true" + }, + { + "id": "1956", + "name": "Cooking apple", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1957", + "name": "Onion", + "examine": "A strong smelling onion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "12", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1958", + "name": "Onion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1959", + "name": "Pumpkin", + "examine": "Happy Halloween.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "1960", + "name": "Pumpkin", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1961", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1962", + "name": "Easter egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1963", + "name": "Banana", + "examine": "Mmm this looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "1964", + "name": "Banana", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1965", + "name": "Cabbage", + "examine": "Yuck, I don't like cabbage.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1966", + "name": "Cabbage", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1967", + "name": "Cabbage", + "examine": "Yuck, a cabbage from Draynor Manor. I don't like cabbage.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "1968", + "name": "Cabbage", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "1969", + "name": "Spinach roll", + "examine": "A home made spinach thing.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "weight": "0.1" + }, + { + "id": "1971", + "name": "Kebab", + "examine": "A meaty kebab.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "1972", + "name": "Kebab", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1973", + "name": "Chocolate bar", + "examine": "Mmmmmmm chocolate.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "1974", + "name": "Chocolate bar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1975", + "name": "Chocolate dust", + "examine": "It's ground-up chocolate.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "1976", + "name": "Chocolate dust", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1977", + "name": "Chocolatey milk", + "examine": "Milk with chocolate in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "2" + }, + { + "id": "1978", + "name": "Cup of tea", + "examine": "A nice cup of tea.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "10", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "1979", + "name": "Cup of tea", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1980", + "name": "Empty cup", + "examine": "An empty cup.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "1981", + "name": "Empty cup", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "1982", + "name": "Tomato", + "examine": "This would make good ketchup.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "25", + "tradeable": "true" + }, + { + "id": "1983", + "name": "Tomato", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1984", + "name": "Rotten apple", + "examine": "Rotten to the core!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "1985", + "name": "Cheese", + "examine": "It's got holes in it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "1986", + "name": "Cheese", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "1987", + "name": "Grapes", + "examine": "Good grapes for wine making.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "1", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "1988", + "name": "Grapes", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1989", + "name": "Half full wine jug", + "examine": "An optimist would say it is half full.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1990", + "name": "Half full wine jug", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "1991", + "name": "Jug of bad wine", + "examine": "Oh dear, this wine is terrible!", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "1992", + "name": "Jug of bad wine", + "examine": "Oh dear, this wine is terrible!", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "1993", + "name": "Jug of wine", + "examine": "It's full of wine.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "128", + "tradeable": "true", + "weight": "1.5" + }, + { + "id": "1994", + "name": "Jug of wine", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "1995", + "name": "Unfermented wine", + "examine": "This wine needs to ferment before it can be drunk.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "1996", + "name": "Unfermented wine", + "examine": "This wine needs to ferment before it can be drunk.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "1997", + "name": "Incomplete stew", + "examine": "I need to add some meat too.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "1998", + "name": "Incomplete stew", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "1999", + "name": "Incomplete stew", + "examine": "I need to add some potato too.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2000", + "name": "Incomplete stew", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2001", + "name": "Uncooked stew", + "examine": "I need to cook this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "shop_price": "1", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2002", + "name": "Uncooked stew", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2003", + "name": "Stew", + "examine": "It's a meat and potato stew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "shop_price": "20", + "tradeable": "true", + "weight": "1.5" + }, + { + "id": "2004", + "name": "Stew", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2006", + "name": "Burnt stew", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2007", + "name": "Spice", + "examine": "This could liven up an otherwise bland stew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "230", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2008", + "name": "Spice", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2009", + "name": "Uncooked curry", + "examine": "I need to cook this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2010", + "name": "Uncooked curry", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2011", + "name": "Curry", + "examine": "It's a spicy hot curry.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true", + "weight": "1.5" + }, + { + "id": "2012", + "name": "Curry", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "2013", + "name": "Burnt curry", + "examine": "Eew, it's horribly burnt.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2014", + "name": "Burnt curry", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2015", + "name": "Vodka", + "examine": "An absolutely clear spirit sold by well-stocked bars.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "2016", + "name": "Vodka", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2017", + "name": "Whisky", + "examine": "This Draynor malt is sold by well-stocked bars.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2018", + "name": "Whisky", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2019", + "name": "Gin", + "examine": "A strong spirit that tastes of Juniper; sold at well-stocked bars.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2020", + "name": "Gin", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2021", + "name": "Brandy", + "examine": "A strong spirit best served in a large glass.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "6", + "tradeable": "true" + }, + { + "id": "2022", + "name": "Brandy", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2023", + "name": "Cocktail guide", + "examine": "A book on tree gnome cocktails.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2024", + "name": "Cocktail guide", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2025", + "name": "Cocktail shaker", + "examine": "Used for mixing cocktails.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2026", + "name": "Cocktail glass", + "examine": "For sipping cocktails.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "2027", + "name": "Cocktail glass", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2028", + "name": "Premade blurb' sp.", + "examine": "A premade Blurberry Special.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2029", + "name": "Premade blurb' sp.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2030", + "name": "Premade choc s'dy", + "examine": "A premade Chocolate Saturday.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2031", + "name": "Premade choc s'dy", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2032", + "name": "Premade dr' dragon", + "examine": "A premade Drunk Dragon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2033", + "name": "Premade dr' dragon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2034", + "name": "Premade fr' blast", + "examine": "A premade Fruit Blast.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2035", + "name": "Premade fr' blast", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2036", + "name": "Premade p' punch", + "examine": "A premade Pineapple Punch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2037", + "name": "Premade p' punch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2038", + "name": "Premade sgg", + "examine": "A premade Short Green Guy.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2039", + "name": "Premade sgg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2040", + "name": "Premade wiz blz'd", + "examine": "A Premade Wizard Blizzard.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2041", + "name": "Premade wiz blz'd", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2042", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2043", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2044", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2045", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2046", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2047", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2048", + "name": "Pineapple punch", + "examine": "A fresh healthy fruit mix.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "28", + "tradeable": "true" + }, + { + "id": "2049", + "name": "Pineapple punch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2050", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2051", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2052", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2053", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2054", + "name": "Wizard blizzard", + "examine": "This looks like a strange mix.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "28", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2055", + "name": "Wizard blizzard", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2056", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2057", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2058", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2059", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2060", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2061", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2062", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2063", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2064", + "name": "Blurberry special", + "examine": "Looks good... smells strong.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "2065", + "name": "Blurberry special", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2066", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2067", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2068", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2069", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2070", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2071", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2072", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2073", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2074", + "name": "Choc saturday", + "examine": "A warm creamy alcoholic beverage", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "28", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2075", + "name": "Choc saturday", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2076", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2077", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2078", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2079", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2080", + "name": "Short green guy", + "examine": "A Short Green Guy... looks good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "28", + "tradeable": "true" + }, + { + "id": "2081", + "name": "Short green guy", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2082", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2083", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2084", + "name": "Fruit blast", + "examine": "A cool refreshing fruit mix.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "28", + "tradeable": "true" + }, + { + "id": "2085", + "name": "Fruit blast", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2086", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2087", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2088", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2089", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2090", + "name": "Picture", + "examine": "This cocktail is just missing those little finishing touches.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2091", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2092", + "name": "Drunk dragon", + "examine": "A warm creamy alcoholic beverage", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "28", + "tradeable": "true" + }, + { + "id": "2093", + "name": "Drunk dragon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2094", + "name": "Picture", + "examine": "I'm not completely sure what this contains.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2095", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2096", + "name": "Picture", + "examine": "I'm not completely sure what this contains.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2097", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2098", + "name": "Picture", + "examine": "I'm not completely sure what this contains.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2099", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2100", + "name": "Picture", + "examine": "I'm not completely sure what this contains.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2101", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2102", + "name": "Lemon", + "examine": "A common fruit, popularly used in cocktails.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2103", + "name": "Lemon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2104", + "name": "Lemon chunks", + "examine": "The not-too-surprising result of using a knife with a lemon!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2105", + "name": "Lemon chunks", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2106", + "name": "Lemon slices", + "examine": "The not-too-surprising result of using a knife with a lemon!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2107", + "name": "Lemon slices", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2108", + "name": "Orange", + "examine": "A common fruit.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "70", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2109", + "name": "Orange", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2110", + "name": "Orange chunks", + "examine": "Fresh chunks of orange.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2111", + "name": "Orange chunks", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2112", + "name": "Orange slices", + "examine": "Fresh orange slices.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2113", + "name": "Orange slices", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2114", + "name": "Pineapple", + "examine": "It can be cut up into something more manageable with a knife.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.15" + }, + { + "id": "2115", + "name": "Pineapple", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2116", + "name": "Pineapple chunks", + "examine": "Fresh chunks of pineapple.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2117", + "name": "Pineapple chunks", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2118", + "name": "Pineapple ring", + "examine": "The not-too-surprising result of using a knife with a pineapple!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2119", + "name": "Pineapple ring", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2120", + "name": "Lime", + "examine": "A common fruit, popularly used in cocktails.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2121", + "name": "Lime", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2122", + "name": "Lime chunks", + "examine": "Fresh chunks of lime.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2123", + "name": "Lime chunks", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2124", + "name": "Lime slices", + "examine": "The not-too-surprising result of using a knife with a lime!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2125", + "name": "Lime slices", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2126", + "name": "Dwellberries", + "examine": "Some rather pretty blue berries picked from a dwellberry bush.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "2127", + "name": "Dwellberries", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2128", + "name": "Equa leaves", + "examine": "A common ingredient in gnome cuisine.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "2129", + "name": "Equa leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2130", + "name": "Pot of cream", + "examine": "Fresh cream.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2131", + "name": "Pot of cream", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2132", + "name": "Raw beef", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "58", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "2133", + "name": "Raw beef", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2134", + "name": "Raw rat meat", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "1", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2135", + "name": "Raw rat meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2136", + "name": "Raw bear meat", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "8", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2137", + "name": "Raw bear meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2138", + "name": "Raw chicken", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "60", + "tradeable": "true", + "weight": "0.15" + }, + { + "id": "2139", + "name": "Raw chicken", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2140", + "name": "Cooked chicken", + "examine": "Mmm this looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2141", + "name": "Cooked chicken", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2142", + "name": "Cooked meat", + "examine": "Mmm this looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "2143", + "name": "Cooked meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2145", + "name": "Burnt chicken", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2146", + "name": "Burnt meat", + "examine": "Oh dear, it's totally burnt!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2147", + "name": "Burnt meat", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2148", + "name": "Raw lava eel", + "examine": "A very strange eel.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.2" + }, + { + "id": "2149", + "name": "Lava eel", + "examine": "Strange, it looks cooler now it's been cooked.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.15" + }, + { + "id": "2150", + "name": "Swamp toad", + "examine": "A slippery little blighter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2151", + "name": "Swamp toad", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2152", + "name": "Toad's legs", + "examine": "They're a gnome delicacy apparently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2153", + "name": "Toad's legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2154", + "name": "Picture", + "examine": "They're a gnome delicacy apparently.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2155", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2156", + "name": "Spicy toad's legs", + "examine": "They're a gnome delicacy apparently.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2157", + "name": "Spicy toad's legs", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2158", + "name": "Seasoned legs", + "examine": "They're a gnome delicacy apparently.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2159", + "name": "Seasoned legs", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2160", + "name": "Spicy worm", + "examine": "They're a gnome delicacy apparently.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2161", + "name": "Spicy worm", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2162", + "name": "King worm", + "examine": "They're a gnome delicacy apparently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2163", + "name": "King worm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2164", + "name": "Batta tin", + "examine": "A deep tin used to make gnome battas in.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2165", + "name": "Crunchy tray", + "examine": "A shallow tray used to make crunchies in.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "10", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2166", + "name": "Gnomebowl mould", + "examine": "A large ovenproof bowl.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "10", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2167", + "name": "Gianne's cook book", + "examine": "Aluft Gianne's favourite dishes.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2168", + "name": "Gianne's cook book", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2169", + "name": "Gnome spice", + "examine": "It's Aluft Gianne's secret mix of spices.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.14" + }, + { + "id": "2170", + "name": "Gnome spice", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2171", + "name": "Gianne dough", + "examine": "It's made from a secret recipe.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2172", + "name": "Gianne dough", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2173", + "name": "Picture", + "examine": "This gnome bowl doesn't look very appetizing.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "2174", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2176", + "name": "Burnt gnomebowl", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2177", + "name": "Half baked bowl", + "examine": "This gnomebowl is in the early stages of preparation.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.2" + }, + { + "id": "2178", + "name": "Raw gnomebowl", + "examine": "This gnomebowl needs cooking.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2179", + "name": "Picture", + "examine": "This unfinished XX needs YY.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2180", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2181", + "name": "Picture", + "examine": "This unfinished XX needs YY.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2182", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2183", + "name": "Picture", + "examine": "This unfinished XX needs YY.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2184", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2185", + "name": "Chocolate bomb", + "examine": "Full of creamy, chocolately goodness.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "450", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "2186", + "name": "Chocolate bomb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2187", + "name": "Tangled toads' legs", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "2188", + "name": "Tangled toads' legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2189", + "name": "Picture", + "examine": "This unfinished XX needs YY.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2190", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2191", + "name": "Worm hole", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2192", + "name": "Worm hole", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2193", + "name": "Picture", + "examine": "This unfinished XX needs YY.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2194", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2195", + "name": "Veg ball", + "examine": "This looks pretty healthy.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2196", + "name": "Veg ball", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2197", + "name": "Odd crunchies", + "examine": "These crunchies don't look very appetising.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2198", + "name": "Odd crunchies", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2200", + "name": "Burnt crunchies", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2201", + "name": "Half baked crunchy", + "examine": "This crunchy is in the early stages of preparation.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2202", + "name": "Raw crunchies", + "examine": "These crunchies need cooking.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2203", + "name": "Picture", + "examine": "This XX crunchy needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2204", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2205", + "name": "Worm crunchies", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "80", + "tradeable": "true" + }, + { + "id": "2206", + "name": "Worm crunchies", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2207", + "name": "Picture", + "examine": "This XX crunchy needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2208", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2209", + "name": "Chocchip crunchies", + "examine": "Yum... smells good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "70", + "tradeable": "true" + }, + { + "id": "2210", + "name": "Chocchip crunchies", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2211", + "name": "Picture", + "examine": "This XX crunchy needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2212", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2213", + "name": "Spicy crunchies", + "examine": "Yum...smells spicy.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "70", + "tradeable": "true" + }, + { + "id": "2214", + "name": "Spicy crunchies", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2215", + "name": "Picture", + "examine": "This XX crunchy needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2216", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2217", + "name": "Toad crunchies", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2218", + "name": "Toad crunchies", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2219", + "name": "Premade w'm batta", + "examine": "A premade Worm Batta.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2220", + "name": "Premade w'm batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2221", + "name": "Premade t'd batta", + "examine": "A Premade Toad Batta.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2222", + "name": "Premade t'd batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2223", + "name": "Premade c+t batta", + "examine": "A Premade Cheese and Tomato Batta.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2224", + "name": "Premade c+t batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2225", + "name": "Premade fr't batta", + "examine": "A premade Fruit Batta.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2226", + "name": "Premade fr't batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2227", + "name": "Premade veg batta", + "examine": "A Premade Vegetable Batta.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2228", + "name": "Premade veg batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2229", + "name": "Premade choc bomb", + "examine": "A premade Chocolate Bomb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2230", + "name": "Premade choc bomb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2231", + "name": "Premade ttl", + "examine": "A premade Tangled Toads Legs.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2232", + "name": "Premade ttl", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2233", + "name": "Premade worm hole", + "examine": "A premade Worm Hole.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2234", + "name": "Premade worm hole", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2235", + "name": "Premade veg ball", + "examine": "A premade Vegetable Ball.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2236", + "name": "Premade veg ball", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2237", + "name": "Premade w'm crun", + "examine": "Some Premade Worm Crunchies.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2238", + "name": "Premade w'm crun", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2239", + "name": "Premade ch' crunch", + "examine": "Some Premade chocchip crunchies.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2240", + "name": "Premade ch' crunch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2241", + "name": "Premade s'y crunch", + "examine": "Some premade Spicy Crunchies.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2242", + "name": "Premade s'y crunch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2243", + "name": "Premade t'd crunch", + "examine": "Some premade Toad Crunchies.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "80", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2244", + "name": "Premade t'd crunch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2245", + "name": "Picture", + "examine": "This batta doesn't look very appetising.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2246", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2248", + "name": "Burnt batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2249", + "name": "Half baked batta", + "examine": "This gnome batta is in the early stages of preparation.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2250", + "name": "Raw batta", + "examine": "This gnome batta needs cooking.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2251", + "name": "Picture", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2252", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2253", + "name": "Worm batta", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2254", + "name": "Worm batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2255", + "name": "Toad batta", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "78", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2256", + "name": "Toad batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2257", + "name": "Picture", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2258", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2259", + "name": "Cheese+tom batta", + "examine": "This smells really good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2260", + "name": "Cheese+tom batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2261", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2262", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2263", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2264", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2265", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2266", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2267", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2268", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2269", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2270", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2271", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2272", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2273", + "name": "Unfinished batta", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2274", + "name": "Unfinished batta", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2275", + "name": "Picture", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2276", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2277", + "name": "Fruit batta", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2278", + "name": "Fruit batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2279", + "name": "Picture", + "examine": "This XX batta needs garnishing with YY.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "2280", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2281", + "name": "Vegetable batta", + "examine": "Well... It looks healthy.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2282", + "name": "Vegetable batta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2283", + "name": "Pizza base", + "examine": "I need to add some tomato next.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "4", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2284", + "name": "Pizza base", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2285", + "name": "Incomplete pizza", + "examine": "I need to add some cheese next.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2286", + "name": "Incomplete pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2287", + "name": "Uncooked pizza", + "examine": "This needs cooking.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2288", + "name": "Uncooked pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2289", + "name": "Plain pizza", + "examine": "A cheese and tomato pizza.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "200", + "tradeable": "true", + "weight": "0.66" + }, + { + "id": "2290", + "name": "Plain pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2291", + "name": "1/2 plain pizza", + "examine": "Half of this plain pizza has been eaten.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "200", + "tradeable": "true", + "weight": "0.66" + }, + { + "id": "2292", + "name": "1/2 plain pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2293", + "name": "Meat pizza", + "examine": "A pizza with bits of meat on it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.83" + }, + { + "id": "2294", + "name": "Meat pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2295", + "name": "1/2 meat pizza", + "examine": "Half of this meat pizza has been eaten.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.83" + }, + { + "id": "2296", + "name": "1/2 meat pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2297", + "name": "Anchovy pizza", + "examine": "A pizza with anchovies.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.83" + }, + { + "id": "2298", + "name": "Anchovy pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2299", + "name": "1/2 anchovy pizza", + "examine": "Half of this anchovy pizza has been eaten.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.83" + }, + { + "id": "2300", + "name": "1/2 anchovy pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2301", + "name": "Pineapple pizza", + "examine": "A pizza with bits of pineapple on it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.83" + }, + { + "id": "2302", + "name": "Pineapple pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2303", + "name": "1/2 p'apple pizza", + "examine": "Half of this pineapple pizza has been eaten.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000" + }, + { + "id": "2304", + "name": "1/2 p'apple pizza", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2306", + "name": "Burnt pizza", + "examine": "Oh dear!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2307", + "name": "Bread dough", + "examine": "Some uncooked dough.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2308", + "name": "Bread dough", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2309", + "name": "Bread", + "examine": "Nice crispy bread.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "24", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2310", + "name": "Bread", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2312", + "name": "Burnt bread", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2313", + "name": "Pie dish", + "examine": "Deceptively pie shaped.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "2314", + "name": "Pie dish", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2315", + "name": "Pie shell", + "examine": "I need to find a filling for this pie.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2316", + "name": "Pie shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2317", + "name": "Uncooked apple pie", + "examine": "This would be much tastier cooked.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2318", + "name": "Uncooked apple pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2319", + "name": "Uncooked meat pie", + "examine": "This would be much healthier cooked.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2320", + "name": "Uncooked meat pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2321", + "name": "Uncooked berry pie", + "examine": "This would be much more appetising cooked.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2322", + "name": "Uncooked berry pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2323", + "name": "Apple pie", + "examine": "Mmm Apple pie.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "140", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2324", + "name": "Apple pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2325", + "name": "Redberry pie", + "examine": "Looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2326", + "name": "Redberry pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2327", + "name": "Meat pie", + "examine": "Not for vegetarians.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "16", + "tradeable": "true" + }, + { + "id": "2328", + "name": "Meat pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2330", + "name": "Burnt pie", + "examine": "I think I left it on the stove too long.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2331", + "name": "Half a meat pie", + "examine": "Half of it is suitable for vegetarians.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "16", + "tradeable": "true" + }, + { + "id": "2332", + "name": "Half a meat pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2333", + "name": "Half a redberry pie", + "examine": "So tasty I kept some for later.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2334", + "name": "Half a redberry pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2335", + "name": "Half an apple pie", + "examine": "Mmm half an apple pie.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "140", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2336", + "name": "Half an apple pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2337", + "name": "Raw oomlie", + "examine": "Raw meat from the oomlie bird.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2338", + "name": "Raw oomlie", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2339", + "name": "Palm leaf", + "examine": "A thick green palm leaf used by natives to cook meat.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "2340", + "name": "Palm leaf", + "examine": "A thick green palm leaf used by natives to cook meat.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "2341", + "name": "Wrapped oomlie", + "examine": "Oomlie meat in a palm leaf pouch. It just needs to be cooked.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "2342", + "name": "Wrapped oomlie", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2343", + "name": "Cooked oomlie wrap", + "examine": "Deliciously cooked oomlie meat in a palm leaf pouch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "2344", + "name": "Cooked oomlie wrap", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2346", + "name": "Burnt oomlie wrap", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2347", + "name": "Hammer", + "examine": "Good for hitting things!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "13", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "2348", + "name": "Hammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2349", + "name": "Bronze bar", + "examine": "It's a bar of bronze.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "10", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "2350", + "name": "Bronze bar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2351", + "name": "Iron bar", + "examine": "It's a bar of iron.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "2352", + "name": "Iron bar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2353", + "name": "Steel bar", + "examine": "It's a bar of steel.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.81" + }, + { + "id": "2354", + "name": "Steel bar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2355", + "name": "Silver bar", + "examine": "It's a bar of silver.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.81" + }, + { + "id": "2356", + "name": "Silver bar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2357", + "name": "Gold bar", + "examine": "It's a bar of gold.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.81" + }, + { + "id": "2358", + "name": "Gold bar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2359", + "name": "Mithril bar", "examine": "It's a bar of mithril.", - "grand_exchange_price": "1920", - "durability": null, - "name": "Mithril bar", - "tradeable": "true", - "weight": "1.6", "archery_ticket_price": "0", - "id": "2359" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "120", + "tradeable": "true", + "weight": "1.6" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1920", - "durability": null, + "id": "2360", "name": "Mithril bar", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2360" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "2361", + "name": "Adamantite bar", "examine": "It's a bar of adamant.", - "grand_exchange_price": "3306", - "durability": null, - "name": "Adamantite bar", - "tradeable": "true", - "weight": "2.04", "archery_ticket_price": "0", - "id": "2361" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "2.04" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "3306", - "durability": null, + "id": "2362", "name": "Adamantite bar", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2362" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "2363", + "name": "Runite bar", "examine": "It's a bar of rune.", - "grand_exchange_price": "13300", - "durability": null, - "name": "Runite bar", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "2363" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "13300", - "durability": null, + "tradeable": "true", + "weight": "2" + }, + { + "id": "2364", "name": "Runite bar", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2364" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "examine": "It's a 'perfect' golden bar.", - "durability": null, + "id": "2365", "name": "'perfect' gold bar", - "weight": "2", + "examine": "It's a 'perfect' golden bar.", "archery_ticket_price": "0", - "id": "2365" + "durability": null, + "weight": "2" }, { - "requirements": "{13,60}", - "ge_buy_limit": "100", + "id": "2366", + "name": "Shield left half", "examine": "The left half of a Dragon Square Shield.", - "grand_exchange_price": "65800", - "durability": null, - "name": "Shield left half", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "2366" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "65800", - "durability": null, - "name": "Shield left half", + "requirements": "{13,60}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2367" + "weight": "2" }, { + "id": "2367", + "name": "Shield left half", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2368", + "name": "Shield right half", + "examine": "The right half of a dragon square shield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{13,60}", "shop_price": "750000", - "ge_buy_limit": "100", - "examine": "The right half of a dragon square shield.", - "grand_exchange_price": "743100", - "durability": null, - "name": "Shield right half", "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "2368" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "743100", - "durability": null, + "id": "2369", "name": "Shield right half", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2369" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "100", - "ge_buy_limit": "5000", + "id": "2370", + "name": "Steel studs", "examine": "A set of studs for leather armour.", - "grand_exchange_price": "792", - "durability": null, - "name": "Steel studs", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "2370" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "792", - "durability": null, + "shop_price": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2371", "name": "Steel studs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2371" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "destroy_message": "This item will likely break if you put it down, and you will have to go looking for another one.", - "examine": "An old statue of an ogre warrior.", - "durability": null, + "id": "2372", "name": "Ogre relic", - "tradeable": "false", - "destroy": "true", - "weight": "3", + "examine": "An old statue of an ogre warrior.", "archery_ticket_price": "0", - "id": "2372" + "destroy": "true", + "destroy_message": "This item will likely break if you put it down, and you will have to go looking for another one.", + "durability": null, + "tradeable": "false", + "weight": "3" }, { - "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", - "examine": "Part of an ogre relic.", - "durability": null, + "id": "2373", "name": "Relic part 1", - "tradeable": "false", - "destroy": "true", + "examine": "Part of an ogre relic.", "archery_ticket_price": "0", - "id": "2373" + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", - "examine": "Part of an ogre relic.", - "durability": null, + "id": "2374", "name": "Relic part 2", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "2374" - }, - { - "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", "examine": "Part of an ogre relic.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", "durability": null, + "tradeable": "false" + }, + { + "id": "2375", "name": "Relic part 3", - "tradeable": "false", - "destroy": "true", + "examine": "Part of an ogre relic.", "archery_ticket_price": "0", - "id": "2375" + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", - "examine": "It's a map.", - "durability": null, + "id": "2376", "name": "Skavid map", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "It's a map.", "archery_ticket_price": "0", - "id": "2376" + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", - "examine": "Very tooth-like.", - "durability": null, + "id": "2377", "name": "Ogre tooth", - "tradeable": "false", - "destroy": "true", + "examine": "Very tooth-like.", "archery_ticket_price": "0", - "id": "2377" + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", - "examine": "Formerly the property of the ogre, Toban", - "durability": null, + "id": "2378", "name": "Toban's key", - "tradeable": "false", + "examine": "Formerly the property of the ogre, Toban", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "2378" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Handy if you want to break all your teeth.", - "durability": null, - "name": "Rock cake", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "2379" - }, - { - "destroy_message": "This item will likely break if you put it down here, and you will have to go looking for another.", - "examine": "Eeeeyeeew!", - "durability": null, - "name": "Fingernails", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "2384" - }, - { - "examine": "I can't wear this old thing.", - "durability": null, - "name": "Old robe", - "weight": "1", - "archery_ticket_price": "0", - "id": "2385" - }, - { - "examine": "Looks kind of useless.", - "durability": null, - "name": "Unusual armour", - "weight": "4", - "archery_ticket_price": "0", - "id": "2386" - }, - { - "examine": "Pointy.", - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Damaged dagger", - "archery_ticket_price": "0", - "id": "2387" - }, - { - "examine": "Useless as an eye patch.", - "durability": null, - "name": "Tattered eye patch", - "archery_ticket_price": "0", - "id": "2388" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "An empty glass vial.", - "grand_exchange_price": "1", - "durability": null, - "name": "Vial", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2389" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "An empty glass vial.", - "grand_exchange_price": "1", - "durability": null, - "name": "Vial", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2390" - }, - { - "ge_buy_limit": "100", - "examine": "Let's see it fly, now!", - "grand_exchange_price": "350", - "durability": null, - "name": "Ground bat bones", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2391" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "350", - "durability": null, - "name": "Ground bat bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2392" - }, - { "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", - "examine": "It's a stolen bar of gold.", "durability": null, - "name": "Toban's gold", - "tradeable": "false", + "tradeable": "false" + }, + { + "id": "2379", + "name": "Rock cake", + "examine": "Handy if you want to break all your teeth.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "2393" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This is meant to be good for spots.", - "grand_exchange_price": "157", + "id": "2384", + "name": "Fingernails", + "examine": "Eeeeyeeew!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here, and you will have to go looking for another.", "durability": null, - "name": "Potion", + "tradeable": "false" + }, + { + "id": "2385", + "name": "Old robe", + "examine": "I can't wear this old thing.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "2386", + "name": "Unusual armour", + "examine": "Looks kind of useless.", + "archery_ticket_price": "0", + "durability": null, + "weight": "4" + }, + { + "id": "2387", + "name": "Damaged dagger", + "examine": "Pointy.", + "archery_ticket_price": "0", + "attack_audios": "2517,2517,2500,2517", + "durability": null + }, + { + "id": "2388", + "name": "Tattered eye patch", + "examine": "Useless as an eye patch.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2389", + "name": "Vial", + "examine": "An empty glass vial.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "2390", + "name": "Vial", + "examine": "An empty glass vial.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "2391", + "name": "Ground bat bones", + "examine": "Let's see it fly, now!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2394" + "weight": "0.1" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A dangerous magical liquid.", - "durability": null, - "name": "Magic ogre potion", + "id": "2392", + "name": "Ground bat bones", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2393", + "name": "Toban's gold", + "examine": "It's a stolen bar of gold.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "2394", + "name": "Potion", + "examine": "This is meant to be good for spots.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { "id": "2395", + "name": "Magic ogre potion", + "examine": "A dangerous magical liquid.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "examine": "A spell is written on this parchment.", - "durability": null, + "id": "2396", "name": "Spell scroll", + "examine": "A spell is written on this parchment.", "archery_ticket_price": "0", - "id": "2396" + "durability": null }, { - "examine": "A tattered old robe.", - "durability": null, + "id": "2397", "name": "Shaman robe", - "weight": "2", + "examine": "A tattered old robe.", "archery_ticket_price": "0", - "id": "2397" + "durability": null, + "weight": "2" }, { - "examine": "Deadly.", - "durability": null, + "id": "2398", "name": "Cave nightshade", + "examine": "Deadly.", "archery_ticket_price": "0", - "id": "2398" + "durability": null }, { - "turn90cw_anim": "821", - "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", - "walk_anim": "819", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "822", - "attack_speed": "5", - "weapon_interface": "6", - "turn180_anim": "820", - "render_anim": "1", - "defence_anim": "388", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "stand_anim": "808", - "name": "Silverlight", - "run_anim": "824", - "archery_ticket_price": "0", "id": "2402", + "name": "Silverlight", + "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "5", + "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0", + "defence_anim": "388", + "durability": null, + "equipment_slot": "3", + "render_anim": "1", + "run_anim": "824", + "stand_anim": "808", "stand_turn_anim": "823", - "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" }, { - "examine": "Scroll containing a powerful enchantment of restoration.", - "durability": null, + "id": "2403", "name": "Hazeel scroll", - "weight": "1", + "examine": "Scroll containing a powerful enchantment of restoration.", "archery_ticket_price": "0", - "id": "2403" + "durability": null, + "weight": "1" }, { - "remove_sleeves": "true", - "examine": "Decorative armour; an heirloom of the Carnillean family.", - "durability": null, - "name": "Carnillean armour", - "weight": "9", - "archery_ticket_price": "0", "id": "2405", + "name": "Carnillean armour", + "examine": "Decorative armour; an heirloom of the Carnillean family.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,20,14,8,0,0,5,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "9" }, { - "examine": "A sign of my commitment to Hazeel.", - "durability": null, - "name": "Hazeel's mark", - "archery_ticket_price": "0", "id": "2406", + "name": "Hazeel's mark", + "examine": "A sign of my commitment to Hazeel.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "examine": "A child's ball.", - "durability": null, + "id": "2407", "name": "Ball", + "examine": "A child's ball.", "archery_ticket_price": "0", - "id": "2407" + "durability": null }, { - "examine": "A key to the Witch's house's front door. (Witch's House)", - "durability": null, + "id": "2409", "name": "Door key", + "examine": "A key to the Witch's house's front door. (Witch's House)", "archery_ticket_price": "0", - "id": "2409" + "durability": null }, { - "examine": "A very attractive magnet.", - "durability": null, + "id": "2410", "name": "Magnet", + "examine": "A very attractive magnet.", "archery_ticket_price": "0", - "id": "2410" + "durability": null }, { - "examine": "A cape from the almighty god Saradomin.", - "durability": null, - "name": "Saradomin cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "2412", + "name": "Saradomin cape", + "examine": "A cape from the almighty god Saradomin.", + "archery_ticket_price": "0", "bonuses": "0,0,0,10,0,1,1,2,10,0,5,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "0.4" }, { - "examine": "A cape from the almighty god Guthix.", - "durability": null, - "name": "Guthix cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "2413", + "name": "Guthix cape", + "examine": "A cape from the almighty god Guthix.", + "archery_ticket_price": "0", "bonuses": "0,0,0,10,0,1,1,2,10,0,5,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "0.4" }, { - "examine": "A cape from the almighty god Zamorak.", - "durability": null, - "name": "Zamorak cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "2414", + "name": "Zamorak cape", + "examine": "A cape from the almighty god Zamorak.", + "archery_ticket_price": "0", "bonuses": "0,0,0,10,0,1,1,2,10,0,5,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "0.4" }, { - "shop_price": "80000", - "examine": "A magical staff imbued with the power of Saradomin.", - "durability": null, - "weight": "2.2", - "attack_speed": "4", - "weapon_interface": "1", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "attack_audios": "2555,0,0,0", - "name": "Saradomin staff", - "tradeable": "false", - "archery_ticket_price": "0", "id": "2415", - "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0" - }, - { - "shop_price": "80000", - "examine": "A magical staff imbued with the power of Guthix.", - "durability": null, - "weight": "2", - "attack_speed": "4", - "weapon_interface": "1", - "defence_anim": "420", - "equipment_slot": "3", + "name": "Saradomin staff", + "examine": "A magical staff imbued with the power of Saradomin.", + "archery_ticket_price": "0", "attack_anims": "419,419,419,419", "attack_audios": "2555,0,0,0", - "name": "Guthix staff", + "attack_speed": "4", + "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "shop_price": "80000", "tradeable": "false", - "archery_ticket_price": "0", + "weapon_interface": "1", + "weight": "2.2" + }, + { "id": "2416", - "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0" - }, - { - "shop_price": "80000", - "turn90cw_anim": "1207", - "examine": "A magical staff imbued with the power of Zamorak.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", + "name": "Guthix staff", + "examine": "A magical staff imbued with the power of Guthix.", + "archery_ticket_price": "0", "attack_anims": "419,419,419,419", - "stand_anim": "813", "attack_audios": "2555,0,0,0", + "attack_speed": "4", + "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "shop_price": "80000", "tradeable": "false", - "name": "Zamorak staff", - "run_anim": "1210", - "archery_ticket_price": "0", + "weapon_interface": "1", + "weight": "2" + }, + { "id": "2417", + "name": "Zamorak staff", + "examine": "A magical staff imbued with the power of Zamorak.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "4", + "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "80000", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0" + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "examine": "A heavy key made of bronze. (Prince Ali Rescue).", - "durability": null, + "id": "2418", "name": "Bronze key", + "examine": "A heavy key made of bronze. (Prince Ali Rescue).", "archery_ticket_price": "0", - "id": "2418" + "durability": null }, { - "examine": "A grey woollen wig.", - "durability": null, + "id": "2419", "name": "Wig", - "archery_ticket_price": "0", - "id": "2419" - }, - { "examine": "A grey woollen wig.", - "durability": null, - "name": "Wig", "archery_ticket_price": "0", - "id": "2421" + "durability": null }, { - "lendable": "true", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "2147483647", - "durability": null, + "id": "2421", + "name": "Wig", + "examine": "A grey woollen wig.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2422", "name": "Blue partyhat", + "examine": "A nice hat from a cracker.", "archery_ticket_price": "0", - "id": "2422" + "durability": null, + "lendable": "true" }, { - "examine": "Imprint of a key in a lump of clay.", - "durability": null, + "id": "2423", "name": "Key print", + "examine": "Imprint of a key in a lump of clay.", "archery_ticket_price": "0", - "id": "2423" + "durability": null }, { - "examine": "A bottle of skin coloured paste.", - "durability": null, + "id": "2424", "name": "Paste", + "examine": "A bottle of skin coloured paste.", "archery_ticket_price": "0", - "id": "2424" + "durability": null }, { - "attack_audios": "2704,0,0,0", - "durability": null, + "id": "2425", "name": "Picture", "archery_ticket_price": "0", - "id": "2425" + "attack_audios": "2704,0,0,0", + "durability": null }, { - "durability": null, + "id": "2427", "name": "Burnt oomlie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2427" + "durability": null, + "tradeable": "true" }, { - "shop_price": "8002", - "ge_buy_limit": "100", + "id": "2428", + "name": "Attack potion(4)", "examine": "4 doses of Attack potion.", - "grand_exchange_price": "275", - "durability": null, - "name": "Attack potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2428" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "8002", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "275", - "durability": null, + "id": "2429", "name": "Attack potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2429" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "139", - "ge_buy_limit": "100", + "id": "2430", + "name": "Restore potion(4)", "examine": "4 doses of restore potion.", - "grand_exchange_price": "101", - "durability": null, - "name": "Restore potion(4)", - "tradeable": "true", - "weight": "0.03", "archery_ticket_price": "0", - "id": "2430" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "139", + "tradeable": "true", + "weight": "0.03" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "101", - "durability": null, + "id": "2431", "name": "Restore potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2431" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "7832", - "ge_buy_limit": "100", + "id": "2432", + "name": "Defence potion(4)", "examine": "4 doses of Defence Potion.", - "grand_exchange_price": "448", - "durability": null, - "name": "Defence potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2432" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "7832", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "448", - "durability": null, + "id": "2433", "name": "Defence potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2433" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2434", + "name": "Prayer potion(4)", "examine": "4 doses of Prayer restore potion.", - "grand_exchange_price": "5687", - "durability": null, - "name": "Prayer potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2434" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "5687", - "durability": null, - "name": "Prayer potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2435" + "tradeable": "true" }, { - "shop_price": "8000", - "ge_buy_limit": "1000", + "id": "2435", + "name": "Prayer potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2436", + "name": "Super attack(4)", "examine": "4 doses of super Attack potion.", - "grand_exchange_price": "898", - "durability": null, - "name": "Super attack(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2436" - }, - { - "shop_price": "8000", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "898", - "durability": null, - "name": "Super attack(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2437" + "shop_price": "8000", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2437", + "name": "Super attack(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "8000", + "tradeable": "true" + }, + { + "id": "2438", + "name": "Fishing potion(4)", "examine": "4 doses of Fishing potion.", - "grand_exchange_price": "73", - "durability": null, - "name": "Fishing potion(4)", - "tradeable": "true", - "weight": "0.03", "archery_ticket_price": "0", - "id": "2438" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "73", - "durability": null, - "name": "Fishing potion(4)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2439" + "weight": "0.03" }, { - "shop_price": "8000", - "ge_buy_limit": "1000", + "id": "2439", + "name": "Fishing potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2440", + "name": "Super strength(4)", "examine": "4 doses of super Strength potion.", - "grand_exchange_price": "2278", - "durability": null, - "name": "Super strength(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2440" - }, - { + "durability": null, + "ge_buy_limit": "1000", "shop_price": "8000", - "ge_buy_limit": "1000", - "grand_exchange_price": "2278", - "durability": null, + "tradeable": "true" + }, + { + "id": "2441", "name": "Super strength(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2441" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "8000", + "tradeable": "true" }, { - "shop_price": "7000", - "ge_buy_limit": "1000", + "id": "2442", + "name": "Super defence(4)", "examine": "4 doses of super Defence potion.", - "grand_exchange_price": "153", - "durability": null, - "name": "Super defence(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2442" - }, - { + "durability": null, + "ge_buy_limit": "1000", "shop_price": "7000", - "ge_buy_limit": "1000", - "grand_exchange_price": "153", - "durability": null, + "tradeable": "true" + }, + { + "id": "2443", "name": "Super defence(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2443" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "7000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "2444", + "name": "Ranging potion(4)", "examine": "4 doses of ranging potion.", - "grand_exchange_price": "8317", - "durability": null, - "name": "Ranging potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2444" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "8317", - "durability": null, + "id": "2445", "name": "Ranging potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2445" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "shop_price": "375", - "ge_buy_limit": "1000", + "id": "2446", + "name": "Antipoison(4)", "examine": "4 doses of antipoison potion.", - "grand_exchange_price": "1624", - "durability": null, - "name": "Antipoison(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2446" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "375", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1624", - "durability": null, + "id": "2447", "name": "Antipoison(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2447" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "2448", + "name": "Super antipoison(4)", "examine": "4 doses of super anti poison potion.", - "grand_exchange_price": "1062", - "durability": null, - "name": "Super antipoison(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2448" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1062", - "durability": null, + "id": "2449", "name": "Super antipoison(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2449" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "2450", + "name": "Zamorak brew(4)", "examine": "4 doses of Zamorak brew.", - "grand_exchange_price": "2838", - "durability": null, - "name": "Zamorak brew(4)", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "2450" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "2838", - "durability": null, + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2451", "name": "Zamorak brew(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2451" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2452", + "name": "Antifire potion(4)", "examine": "4 doses of anti-firebreath potion.", - "grand_exchange_price": "4743", - "durability": null, - "name": "Antifire potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2452" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "4743", - "durability": null, + "id": "2453", "name": "Antifire potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2453" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2454", + "name": "Antifire potion(3)", "examine": "3 doses of anti-firebreath potion.", - "grand_exchange_price": "3518", - "durability": null, - "name": "Antifire potion(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2454" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3518", - "durability": null, + "id": "2455", "name": "Antifire potion(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2455" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2456", + "name": "Antifire potion(2)", "examine": "2 doses of anti-firebreath potion.", - "grand_exchange_price": "2291", - "durability": null, - "name": "Antifire potion(2)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2456" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2291", - "durability": null, + "id": "2457", "name": "Antifire potion(2)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2457" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2458", + "name": "Antifire potion(1)", "examine": "1 dose of anti-firebreath potion.", - "grand_exchange_price": "1099", - "durability": null, - "name": "Antifire potion(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2458" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1099", - "durability": null, + "id": "2459", "name": "Antifire potion(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2459" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "15", - "ge_buy_limit": "100", - "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "704", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", "id": "2460", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "704", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2461" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "704", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2461", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2462", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "704", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2463" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "638", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2463", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2464", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "638", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2465" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "629", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2465", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2466", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "629", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2467" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "639", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2467", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2468", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "639", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2469" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "613", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2469", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2470", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "613", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2471" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "711", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2471", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2472", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "711", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2473" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "48700", - "attack_audios": "2566", - "name": "Flowers", - "tradeable": "true", "archery_ticket_price": "0", + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2473", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2474", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "48700", - "durability": null, "name": "Flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2475" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", "examine": "A posy of flowers.", - "durability": null, - "weight": "0.02", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "403", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "381,381,381,381", - "fun_weapon": "true", - "grand_exchange_price": "5975", "attack_audios": "2566", - "name": "Flowers", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" + }, + { + "id": "2475", + "name": "Flowers", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2476", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5975", - "durability": null, "name": "Flowers", - "tradeable": "true", + "examine": "A posy of flowers.", "archery_ticket_price": "0", - "id": "2477" + "attack_anims": "381,381,381,381", + "attack_audios": "2566", + "attack_speed": "4", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "fun_weapon": "true", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "12", + "weight": "0.02" }, { - "ge_buy_limit": "10000", + "id": "2477", + "name": "Flowers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2481", + "name": "Clean lantadyme", "examine": "A fresh herb.", - "grand_exchange_price": "7274", - "durability": null, - "name": "Clean lantadyme", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2481" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "7274", - "durability": null, - "name": "Clean lantadyme", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2482" + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2482", + "name": "Clean lantadyme", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2483", + "name": "Lantadyme potion(unf)", "examine": "I need another ingredient to finish this lantadyme potion.", - "grand_exchange_price": "6940", - "durability": null, - "name": "Lantadyme potion(unf)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2483" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "6940", - "durability": null, + "tradeable": "true" + }, + { + "id": "2484", "name": "Lantadyme potion(unf)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2484" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{15,67}", - "ge_buy_limit": "10000", + "id": "2485", + "name": "Grimy lantadyme", "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "900", - "durability": null, - "name": "Grimy lantadyme", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2485" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "7210", - "durability": null, - "name": "Grimy lantadyme", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2486" + "requirements": "{15,67}", + "tradeable": "true" }, { - "requirements": "{4,50}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", - "durability": null, - "weight": "0.2", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "1705", - "name": "Blue d'hide vamb", - "tradeable": "true", + "id": "2486", + "name": "Grimy lantadyme", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { "id": "2487", - "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1705", - "durability": null, "name": "Blue d'hide vamb", - "tradeable": "true", + "examine": "Made from 100% real dragonhide.", "archery_ticket_price": "0", - "id": "2488" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "5000", - "examine": "Vambraces made from 100% real dragonhide.", + "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,0,0,0,0", "durability": null, - "weight": "0.25", + "equip_audio": "2241", "equipment_slot": "9", + "ge_buy_limit": "5000", "lendable": "true", - "grand_exchange_price": "2046", - "name": "Red d'hide vamb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2489", - "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2046", - "durability": null, - "name": "Red d'hide vamb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2490" - }, - { - "requirements": "{4,70}", - "ge_buy_limit": "5000", - "examine": "Vambraces made from 100% real dragonhide.", - "durability": null, - "weight": "0.25", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "2506", - "name": "Black d'hide vamb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2491", - "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2506", - "durability": null, - "name": "Black d'hide vamb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2492" - }, - { "requirements": "{4,50}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2488", + "name": "Blue d'hide vamb", + "archery_ticket_price": "0", "durability": null, - "weight": "5.4", - "absorb": "0,5,2", - "equipment_slot": "7", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2489", + "name": "Red d'hide vamb", + "examine": "Vambraces made from 100% real dragonhide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "5000", "lendable": "true", - "grand_exchange_price": "2504", - "name": "Blue d'hide chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2493", - "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2504", - "durability": null, - "name": "Blue d'hide chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2494" - }, - { "requirements": "{4,60}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "2490", + "name": "Red d'hide vamb", + "archery_ticket_price": "0", "durability": null, - "weight": "5.4", - "absorb": "0,6,3", - "equipment_slot": "7", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2491", + "name": "Black d'hide vamb", + "examine": "Vambraces made from 100% real dragonhide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "5000", "lendable": "true", - "grand_exchange_price": "3142", - "name": "Red d'hide chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2495", - "bonuses": "0,0,0,-10,14,28,22,30,20,28,25,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3142", - "durability": null, - "name": "Red d'hide chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2496" - }, - { "requirements": "{4,70}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "2492", + "name": "Black d'hide vamb", + "archery_ticket_price": "0", "durability": null, - "weight": "5.4", - "absorb": "0,7,3", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2493", + "name": "Blue d'hide chaps", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "7", + "ge_buy_limit": "5000", "lendable": "true", - "grand_exchange_price": "4744", - "name": "Black d'hide chaps", + "requirements": "{4,50}", "tradeable": "true", + "weight": "5.4" + }, + { + "id": "2494", + "name": "Blue d'hide chaps", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2495", + "name": "Red d'hide chaps", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,14,28,22,30,20,28,25,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "5000", + "lendable": "true", + "requirements": "{4,60}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "2496", + "name": "Red d'hide chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "2497", - "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "4744", - "durability": null, "name": "Black d'hide chaps", - "tradeable": "true", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,7,3", "archery_ticket_price": "0", - "id": "2498" + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "5000", + "lendable": "true", + "requirements": "{4,70}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,40}-{4,50}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", - "durability": null, - "weight": "6.8", - "absorb": "0,6,3", - "equipment_slot": "4", - "lendable": "true", - "grand_exchange_price": "5420", - "name": "Blue d'hide body", - "tradeable": "true", + "id": "2498", + "name": "Black d'hide chaps", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "2499", - "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "5420", - "durability": null, "name": "Blue d'hide body", - "tradeable": "true", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", "archery_ticket_price": "0", - "id": "2500" + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "5000", + "lendable": "true", + "requirements": "{1,40}-{4,50}", + "tradeable": "true", + "weight": "6.8" }, { - "requirements": "{1,40}-{4,60}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide.", - "durability": null, - "weight": "6.8", - "absorb": "0,6,3", - "equipment_slot": "4", - "lendable": "true", - "grand_exchange_price": "6680", - "name": "Red d'hide body", - "tradeable": "true", + "id": "2500", + "name": "Blue d'hide body", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "2501", - "bonuses": "0,0,0,-15,25,50,42,55,40,50,50,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "6680", - "durability": null, "name": "Red d'hide body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2502" - }, - { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "5000", "examine": "Made from 100% real dragonhide.", - "durability": null, - "weight": "6.8", "absorb": "0,6,3", - "equipment_slot": "4", - "lendable": "true", - "grand_exchange_price": "8098", - "name": "Black d'hide body", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,25,50,42,55,40,50,50,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "5000", + "lendable": "true", + "requirements": "{1,40}-{4,60}", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "2502", + "name": "Red d'hide body", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "2503", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "8098", - "durability": null, "name": "Black d'hide body", - "tradeable": "true", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", "archery_ticket_price": "0", - "id": "2504" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a piece of prepared blue dragonhide.", - "grand_exchange_price": "2888", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0", "durability": null, - "name": "Blue d-leather", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "2505" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2888", - "durability": null, - "name": "Blue d-leather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2506" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a piece of prepared red dragonhide.", - "grand_exchange_price": "4464", - "durability": null, - "name": "Red dragon leather", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "2507" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "4464", - "durability": null, - "name": "Red dragon leather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2508" - }, - { - "ge_buy_limit": "10000", - "examine": "It's a piece of prepared black dragonhide.", - "grand_exchange_price": "6664", - "durability": null, - "name": "Black d-leather", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "2509" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "6664", - "durability": null, - "name": "Black d-leather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2510" - }, - { - "shop_price": "4", - "examine": "A number of wooden logs.", - "grand_exchange_price": "124", - "durability": null, - "name": "Logs", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "2511" - }, - { - "lendable": "true", - "examine": "A series of connected metal rings.", - "grand_exchange_price": "2902937", - "rare_item": "true", - "durability": null, - "name": "Dragon chainbody", - "tradeable": "true", - "weight": "6.8", - "archery_ticket_price": "0", - "id": "2513", - "absorb": "4,0,9", - "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" - }, - { - "shop_price": "6", - "examine": "I should try cooking this.", - "grand_exchange_price": "6", - "durability": null, - "name": "Raw shrimps", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2514" - }, - { - "durability": null, - "name": "Raw shrimps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2515" - }, - { - "shop_price": "14", - "examine": "There is flour in this pot.", - "grand_exchange_price": "162", - "durability": null, - "name": "Pot of flour", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "2516" - }, - { - "durability": null, - "name": "Pot of flour", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2517" - }, - { - "shop_price": "1", - "examine": "Pretty smelly.", - "durability": null, - "name": "Rotten tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2518" - }, - { - "durability": null, - "name": "Rotten tomato", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2519" - }, - { - "shop_price": "150", - "examine": "An inexpensive white/black/grey/brown toy horse.", - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2520" - }, - { - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2521" - }, - { - "shop_price": "150", - "examine": "An inexpensive white/black/grey/brown toy horse.", - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2522" - }, - { - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2523" - }, - { - "shop_price": "150", - "examine": "An inexpensive white/black/grey/brown toy horse.", - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2524" - }, - { - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2525" - }, - { - "shop_price": "150", - "examine": "An inexpensive white/black/grey/brown toy horse.", - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2526" - }, - { - "durability": null, - "name": "Toy horsey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2527" - }, - { - "bankable": "false", - "examine": "Wonder what happens if I rub it...", - "durability": null, - "name": "Lamp", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2528" - }, - { - "examine": "A magical sphere that glimmers within.", - "durability": null, - "name": "Orb of light", - "weight": "5", - "archery_ticket_price": "0", - "id": "2529" - }, - { - "shop_price": "140", - "grand_exchange_price": "140", - "examine": "Bones are for burying!", - "durability": null, - "name": "Bones", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "2530" - }, - { - "durability": null, - "name": "Bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2531" - }, - { - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with iron heads and oil-soaked cloth. lit: An easy to make, iron-headed fire arrow.", - "grand_exchange_price": "316", - "durability": null, - "name": "Iron fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2532", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with iron heads and oil-soaked cloth. lit: An easy to make, iron-headed fire arrow.", - "grand_exchange_price": "305", - "durability": null, - "name": "Iron fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2533", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "requirements": "{4,5}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with steel heads and oil-soaked cloth. lit: An easy to make, steel-headed fire arrow.", - "grand_exchange_price": "325", - "durability": null, - "name": "Steel fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2534", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { - "requirements": "{4,5}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with steel heads and oil-soaked cloth. lit: An easy to make, steel-headed fire arrow.", - "grand_exchange_price": "327", - "durability": null, - "name": "Steel fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2535", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with mithril heads and oil-soaked cloth. lit: An easy to make, mithril-headed fire arrow.", - "grand_exchange_price": "9", - "durability": null, - "name": "Mithril fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2536", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with mithril heads and oil-soaked cloth. lit: An easy to make, mithril-headed fire arrow.", - "grand_exchange_price": "63", - "durability": null, - "name": "Mithril fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2537", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with adamant heads and oil-soaked cloth.lit: An easy-to-make, Adamant-headed fire arrow.", - "grand_exchange_price": "90", - "durability": null, - "name": "Adamant fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2538", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with adamant heads and oil-soaked cloth.lit: An easy-to-make, Adamant-headed fire arrow.", - "grand_exchange_price": "127", - "durability": null, - "name": "Adamant fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2539", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "10000", - "examine": "An easy to make, rune-headed fire arrow.", - "grand_exchange_price": "539", - "durability": null, - "name": "Rune fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2540", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "10000", - "examine": "An easy to make, rune-headed fire arrow.", - "grand_exchange_price": "682", - "durability": null, - "name": "Rune fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2541", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { - "ge_buy_limit": "5000", - "examine": "An enchanted ring.", - "grand_exchange_price": "943", - "durability": null, - "name": "Ring of recoil", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2550", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "943", - "durability": null, - "name": "Ring of recoil", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2551" - }, - { - "shop_price": "770", - "ge_buy_limit": "10000", - "examine": "An enchanted ring.", - "grand_exchange_price": "1237", - "durability": null, - "name": "Ring of duelling(8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2552", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1237", - "durability": null, - "name": "Ring of duelling(8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2553" - }, - { - "shop_price": "770", - "examine": "An enchanted ring.", - "grand_exchange_price": "8", - "durability": null, - "name": "Ring of duelling(7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2554", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of duelling(7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2555" - }, - { - "shop_price": "770", - "examine": "An enchanted ring.", - "grand_exchange_price": "8", - "durability": null, - "name": "Ring of duelling(6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2556", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of duelling(6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2557" - }, - { - "shop_price": "770", - "examine": "An enchanted ring.", - "grand_exchange_price": "8", - "durability": null, - "name": "Ring of duelling(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2558", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of duelling(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2559" - }, - { - "shop_price": "770", - "examine": "An enchanted ring.", - "grand_exchange_price": "8", - "durability": null, - "name": "Ring of duelling(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2560", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of duelling(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2561" - }, - { - "shop_price": "770", - "examine": "An enchanted ring.", - "grand_exchange_price": "8", - "durability": null, - "name": "Ring of duelling(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2562", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of duelling(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2563" - }, - { - "shop_price": "770", - "examine": "An enchanted ring.", - "grand_exchange_price": "8", - "durability": null, - "name": "Ring of duelling(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2564", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of duelling(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2565" - }, - { - "shop_price": "770", - "ge_buy_limit": "10000", - "examine": "An enchanted ring.", - "grand_exchange_price": "594", - "durability": null, - "name": "Ring of duelling(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2566", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "594", - "durability": null, - "name": "Ring of duelling(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2567" - }, - { - "ge_buy_limit": "10000", - "examine": "An enchanted ring.", - "grand_exchange_price": "1103", - "durability": null, - "name": "Ring of forging", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2568", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1103", - "durability": null, - "name": "Ring of forging", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2569" - }, - { - "shop_price": "3000", - "ge_buy_limit": "10000", - "examine": "An enchanted ring.", - "grand_exchange_price": "4540", - "durability": null, - "name": "Ring of life", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2570", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "4540", - "durability": null, - "name": "Ring of life", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2571" - }, - { - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of wealth", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2572", - "equipment_slot": "12" - }, - { - "durability": null, - "name": "Ring of wealth", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2573" - }, - { - "examine": "Used by navigators to find their position in 2009Scape.", - "durability": null, - "name": "Sextant", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "2574" - }, - { - "examine": "A fine looking time piece.", - "durability": null, - "name": "Watch", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "2575" - }, - { - "examine": "A navigator's chart of 2009Scape.", - "durability": null, - "name": "Chart", - "archery_ticket_price": "0", - "id": "2576" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "2", - "examine": "Lightweight boots ideal for rangers.", - "durability": null, - "weight": "0.2", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "13900000", - "name": "Ranger boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2577", - "bonuses": "0,0,0,-10,8,2,3,4,2,0,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "13900000", - "durability": null, - "name": "Ranger boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2578" - }, - { - "requirements": "{6,20}", - "ge_buy_limit": "2", - "examine": "Slightly magical boots.", - "durability": null, - "weight": "1", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "747300", - "name": "Wizard boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2579", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "747300", - "durability": null, - "name": "Wizard boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2580" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "2", - "examine": "Endorsed by Robin Hood.", - "durability": null, - "weight": "0.2", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "4400000", - "name": "Robin hood hat", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": "true", - "id": "2581", - "bonuses": "0,0,0,-10,8,4,6,8,4,4,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "4400000", - "durability": null, - "name": "Robin hood hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2582" - }, - { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black platebody with trim.", - "durability": null, - "weight": "9.07", - "absorb": "1,0,2", + "equip_audio": "2241", "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "74900", - "name": "Black platebody (t)", + "ge_buy_limit": "5000", + "lendable": "true", + "requirements": "{1,40}-{4,70}", "tradeable": "true", + "weight": "6.8" + }, + { + "id": "2504", + "name": "Black d'hide body", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2505", + "name": "Blue d-leather", + "examine": "It's a piece of prepared blue dragonhide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "2506", + "name": "Blue d-leather", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2507", + "name": "Red dragon leather", + "examine": "It's a piece of prepared red dragonhide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3" + }, + { + "id": "2508", + "name": "Red dragon leather", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2509", + "name": "Black d-leather", + "examine": "It's a piece of prepared black dragonhide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "2510", + "name": "Black d-leather", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2511", + "name": "Logs", + "examine": "A number of wooden logs.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "4", + "tradeable": "true", + "weight": "2" + }, + { + "id": "2513", + "name": "Dragon chainbody", + "examine": "A series of connected metal rings.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0", + "durability": null, + "lendable": "true", + "rare_item": "true", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "2514", + "name": "Raw shrimps", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "6", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2515", + "name": "Raw shrimps", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2516", + "name": "Pot of flour", + "examine": "There is flour in this pot.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "14", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "2517", + "name": "Pot of flour", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2518", + "name": "Rotten tomato", + "examine": "Pretty smelly.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "2519", + "name": "Rotten tomato", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2520", + "name": "Toy horsey", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "2521", + "name": "Toy horsey", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2522", + "name": "Toy horsey", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "2523", + "name": "Toy horsey", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2524", + "name": "Toy horsey", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "2525", + "name": "Toy horsey", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2526", + "name": "Toy horsey", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "2527", + "name": "Toy horsey", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2528", + "name": "Lamp", + "examine": "Wonder what happens if I rub it...", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "weight": "0.1" + }, + { + "id": "2529", + "name": "Orb of light", + "examine": "A magical sphere that glimmers within.", + "archery_ticket_price": "0", + "durability": null, + "weight": "5" + }, + { + "id": "2530", + "name": "Bones", + "examine": "Bones are for burying!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "140", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "2531", + "name": "Bones", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2532", + "name": "Iron fire arrows", + "examine": "unlit: Arrows with iron heads and oil-soaked cloth. lit: An easy to make, iron-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2533", + "name": "Iron fire arrows", + "examine": "unlit: Arrows with iron heads and oil-soaked cloth. lit: An easy to make, iron-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2534", + "name": "Steel fire arrows", + "examine": "unlit: Arrows with steel heads and oil-soaked cloth. lit: An easy to make, steel-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "tradeable": "true" + }, + { + "id": "2535", + "name": "Steel fire arrows", + "examine": "unlit: Arrows with steel heads and oil-soaked cloth. lit: An easy to make, steel-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "tradeable": "true" + }, + { + "id": "2536", + "name": "Mithril fire arrows", + "examine": "unlit: Arrows with mithril heads and oil-soaked cloth. lit: An easy to make, mithril-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,20}", + "tradeable": "true" + }, + { + "id": "2537", + "name": "Mithril fire arrows", + "examine": "unlit: Arrows with mithril heads and oil-soaked cloth. lit: An easy to make, mithril-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,20}", + "tradeable": "true" + }, + { + "id": "2538", + "name": "Adamant fire arrows", + "examine": "unlit: Arrows with adamant heads and oil-soaked cloth.lit: An easy-to-make, Adamant-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "tradeable": "true" + }, + { + "id": "2539", + "name": "Adamant fire arrows", + "examine": "unlit: Arrows with adamant heads and oil-soaked cloth.lit: An easy-to-make, Adamant-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "tradeable": "true" + }, + { + "id": "2540", + "name": "Rune fire arrows", + "examine": "An easy to make, rune-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "tradeable": "true" + }, + { + "id": "2541", + "name": "Rune fire arrows", + "examine": "An easy to make, rune-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "tradeable": "true" + }, + { + "id": "2550", + "name": "Ring of recoil", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2551", + "name": "Ring of recoil", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "2552", + "name": "Ring of duelling(8)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10000", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2553", + "name": "Ring of duelling(8)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2554", + "name": "Ring of duelling(7)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2555", + "name": "Ring of duelling(7)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2556", + "name": "Ring of duelling(6)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2557", + "name": "Ring of duelling(6)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2558", + "name": "Ring of duelling(5)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2559", + "name": "Ring of duelling(5)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2560", + "name": "Ring of duelling(4)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2561", + "name": "Ring of duelling(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2562", + "name": "Ring of duelling(3)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2563", + "name": "Ring of duelling(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2564", + "name": "Ring of duelling(2)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2565", + "name": "Ring of duelling(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2566", + "name": "Ring of duelling(1)", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10000", + "shop_price": "770", + "tradeable": "true" + }, + { + "id": "2567", + "name": "Ring of duelling(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2568", + "name": "Ring of forging", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2569", + "name": "Ring of forging", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2570", + "name": "Ring of life", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10000", + "shop_price": "3000", + "tradeable": "true" + }, + { + "id": "2571", + "name": "Ring of life", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2572", + "name": "Ring of wealth", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "tradeable": "true" + }, + { + "id": "2573", + "name": "Ring of wealth", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2574", + "name": "Sextant", + "examine": "Used by navigators to find their position in 2009Scape.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.2" + }, + { + "id": "2575", + "name": "Watch", + "examine": "A fine looking time piece.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "2576", + "name": "Chart", + "examine": "A navigator's chart of 2009Scape.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2577", + "name": "Ranger boots", + "examine": "Lightweight boots ideal for rangers.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,2,3,4,2,0,10,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{4,40}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2578", + "name": "Ranger boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2579", + "name": "Wizard boots", + "examine": "Slightly magical boots.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{6,20}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2580", + "name": "Wizard boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2581", + "name": "Robin hood hat", + "examine": "Endorsed by Robin Hood.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,4,6,8,4,4,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": "true", + "lendable": "true", + "requirements": "{4,40}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "2582", + "name": "Robin hood hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2583", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "74900", - "durability": null, "name": "Black platebody (t)", - "tradeable": "true", + "examine": "Black platebody with trim.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "2584" - }, - { + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black platelegs with trim.", - "grand_exchange_price": "39900", - "durability": null, - "name": "Black platelegs (t)", "tradeable": "true", - "weight": "9", + "weight": "9.07" + }, + { + "id": "2584", + "name": "Black platebody (t)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2585", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "39900", - "durability": null, "name": "Black platelegs (t)", - "tradeable": "true", + "examine": "Black platelegs with trim.", "archery_ticket_price": "0", - "id": "2586" + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "9" }, { + "id": "2586", + "name": "Black platelegs (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2587", + "name": "Black full helm(t)", + "examine": "Black full helmet with trim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,10}", - "ge_buy_limit": "100", - "examine": "Black full helmet with trim.", - "durability": null, - "weight": "2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "82200", - "name": "Black full helm(t)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2587", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "82200", - "durability": null, + "id": "2588", "name": "Black full helm(t)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2588" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "2589", + "name": "Black kiteshield (t)", + "examine": "Black kiteshield with trim.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", "requirements": "{1,10}", "shop_price": "2072", - "ge_buy_limit": "2", - "examine": "Black kiteshield with trim.", - "durability": null, - "weight": "5", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "73000", - "name": "Black kiteshield (t)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2589", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + "weight": "5" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "73000", - "durability": null, + "id": "2590", "name": "Black kiteshield (t)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2590" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black platebody with gold trim.", - "durability": null, - "weight": "9.07", - "absorb": "1,0,2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "589000", - "name": "Black platebody (g)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "2591", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "589000", - "durability": null, "name": "Black platebody (g)", - "tradeable": "true", + "examine": "Black platebody with gold trim.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "2592" + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "9.07" }, { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black platelegs with gold trim.", - "grand_exchange_price": "216700", - "durability": null, - "name": "Black platelegs (g)", - "tradeable": "true", - "weight": "9", + "id": "2592", + "name": "Black platebody (g)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2593", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "216700", - "durability": null, "name": "Black platelegs (g)", - "tradeable": "true", + "examine": "Black platelegs with gold trim.", "archery_ticket_price": "0", - "id": "2594" + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "9" }, { - "remove_head": "true", - "requirements": "{1,10}", - "ge_buy_limit": "100", - "examine": "Black full helmet with gold trim.", - "durability": null, - "weight": "2.7", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "364800", - "name": "Black full helm(g)", - "tradeable": "true", + "id": "2594", + "name": "Black platelegs (g)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2595", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "364800", - "durability": null, "name": "Black full helm(g)", - "tradeable": "true", + "examine": "Black full helmet with gold trim.", "archery_ticket_price": "0", - "id": "2596" - }, - { + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_beard": "true", + "remove_head": "true", "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black kiteshield with gold trim.", - "durability": null, - "weight": "5", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "355600", - "name": "Black kiteshield (g)", "tradeable": "true", + "weight": "2.7" + }, + { + "id": "2596", + "name": "Black full helm(g)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2597", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "355600", - "durability": null, "name": "Black kiteshield (g)", - "tradeable": "true", + "examine": "Black kiteshield with gold trim.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "2598" + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant platebody with trim.", - "durability": null, - "weight": "9.07", - "absorb": "2,0,4", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "104000", - "name": "Adam platebody (t)", - "tradeable": "true", + "id": "2598", + "name": "Black kiteshield (g)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2599", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "104000", - "durability": null, "name": "Adam platebody (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2600" - }, - { - "requirements": "{1,30}", - "shop_price": "6464", - "ge_buy_limit": "2", - "examine": "These look heavy", - "durability": null, - "weight": "10", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "23200", - "name": "Adam platelegs (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2601", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "23200", - "durability": null, - "name": "Adam platelegs (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2602" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A large metal shield.", - "durability": null, - "weight": "5.8", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "49100", - "name": "Adam kiteshield (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2603", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "49100", - "durability": null, - "name": "Adam kiteshield (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2604" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant full helm with trim", - "durability": null, - "weight": "2.7", - "absorb": "1,0,2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "85000", - "name": "Adam full helm(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2605", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "85000", - "durability": null, - "name": "Adam full helm(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2606" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant platebody with gold trim.", - "durability": null, - "weight": "9.07", + "examine": "Adamant platebody with trim.", "absorb": "2,0,4", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "359500", - "name": "Adam platebody (g)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2607", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "359500", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0", "durability": null, - "name": "Adam platebody (g)", + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,30}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2608" + "weight": "9.07" }, { + "id": "2600", + "name": "Adam platebody (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2601", + "name": "Adam platelegs (t)", + "examine": "These look heavy", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", "requirements": "{1,30}", "shop_price": "6464", - "ge_buy_limit": "2", - "examine": "Adamant platelegs with gold trim.", - "durability": null, - "weight": "10", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "94300", - "name": "Adam platelegs (g)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2609", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + "weight": "10" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "94300", - "durability": null, - "name": "Adam platelegs (g)", - "tradeable": "true", + "id": "2602", + "name": "Adam platelegs (t)", "archery_ticket_price": "0", - "id": "2610" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant kiteshield with gold trim.", - "durability": null, - "weight": "6", + "id": "2603", + "name": "Adam kiteshield (t)", + "examine": "A large metal shield.", "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "170100", - "name": "Adam kiteshield (g)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2611", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "170100", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", "durability": null, - "name": "Adam kiteshield (g)", + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2612" + "weight": "5.8" }, { + "id": "2604", + "name": "Adam kiteshield (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2605", + "name": "Adam full helm(t)", + "examine": "Adamant full helm with trim", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant full helmet with gold trim.", - "durability": null, - "weight": "2.7", - "absorb": "1,0,2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "222400", - "name": "Adam full helm(g)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2613", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "222400", - "durability": null, - "name": "Adam full helm(g)", - "tradeable": "true", + "id": "2606", + "name": "Adam full helm(t)", "archery_ticket_price": "0", - "id": "2614" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platebody with gold trim.", + "id": "2607", + "name": "Adam platebody (g)", + "examine": "Adamant platebody with gold trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0", "durability": null, - "weight": "9.07", - "absorb": "3,0,6", + "equip_audio": "2239", "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "9.07" + }, + { + "id": "2608", + "name": "Adam platebody (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2609", + "name": "Adam platelegs (g)", + "examine": "Adamant platelegs with gold trim.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "shop_price": "6464", + "tradeable": "true", + "weight": "10" + }, + { + "id": "2610", + "name": "Adam platelegs (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2611", + "name": "Adam kiteshield (g)", + "examine": "Adamant kiteshield with gold trim.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "2612", + "name": "Adam kiteshield (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2613", + "name": "Adam full helm(g)", + "examine": "Adamant full helmet with gold trim.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "2614", + "name": "Adam full helm(g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2615", + "name": "Rune platebody (g)", + "examine": "Rune platebody with gold trim.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "426200", - "name": "Rune platebody (g)", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2615", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + "weight": "9.07" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "426200", + "id": "2616", + "name": "Rune platebody (g)", + "archery_ticket_price": "0", "durability": null, - "name": "Rune platebody (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2616" + "ge_buy_limit": "2", + "tradeable": "true" }, { + "id": "2617", + "name": "Rune platelegs (g)", + "examine": "Rune platelegs with gold trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", "requirements": "{1,40}", "shop_price": "64000", - "ge_buy_limit": "2", - "examine": "Rune platelegs with gold trim.", + "tradeable": "true", + "weight": "9" + }, + { + "id": "2618", + "name": "Rune platelegs (g)", + "archery_ticket_price": "0", "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2619", + "name": "Rune full helm(g)", + "examine": "Rune full helmet with gold trim.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "100", "lendable": "true", - "grand_exchange_price": "243400", - "name": "Rune platelegs (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2617", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "243400", - "durability": null, - "name": "Rune platelegs (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2618" - }, - { + "remove_beard": "true", "remove_head": "true", "requirements": "{1,40}", "shop_price": "35000", - "ge_buy_limit": "100", - "examine": "Rune full helmet with gold trim.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "506800", - "name": "Rune full helm(g)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2619", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "506800", - "durability": null, + "id": "2620", "name": "Rune full helm(g)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2620" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune kiteshield with gold trim", - "durability": null, - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "392700", - "name": "Rune kiteshield (g)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "2621", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "392700", - "durability": null, "name": "Rune kiteshield (g)", - "tradeable": "true", + "examine": "Rune kiteshield with gold trim", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "2622" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platebody with trim.", - "durability": null, - "weight": "9.07", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "162700", - "name": "Rune platebody (t)", - "tradeable": "true", + "id": "2622", + "name": "Rune kiteshield (g)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2623", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "162700", - "durability": null, "name": "Rune platebody (t)", - "tradeable": "true", + "examine": "Rune platebody with trim.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "2624" + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9.07" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platelegs with trim!", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "95400", - "name": "Rune platelegs (t)", - "tradeable": "true", + "id": "2624", + "name": "Rune platebody (t)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2625", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "95400", - "durability": null, "name": "Rune platelegs (t)", - "tradeable": "true", + "examine": "Rune platelegs with trim!", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "2626" + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" }, { - "remove_head": "true", - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune full helmet with trim.", - "durability": null, - "weight": "2.7", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "216600", - "name": "Rune full helm (t)", - "tradeable": "true", + "id": "2626", + "name": "Rune platelegs (t)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2627", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "216600", - "durability": null, "name": "Rune full helm (t)", - "tradeable": "true", + "examine": "Rune full helmet with trim.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "2628" + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.7" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A large, metal shield with a nice trim.", - "durability": null, - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "160300", - "name": "Rune kiteshield (t)", - "tradeable": "true", + "id": "2628", + "name": "Rune full helm (t)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2629", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "160300", - "durability": null, "name": "Rune kiteshield (t)", - "tradeable": "true", + "examine": "A large, metal shield with a nice trim.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "2630" + "attack_anims": "", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "Your money or your life!", - "grand_exchange_price": "83500", - "durability": null, - "name": "Highwayman mask", - "tradeable": "true", + "id": "2630", + "name": "Rune kiteshield (t)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2631", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "83500", - "durability": null, "name": "Highwayman mask", - "tradeable": "true", + "examine": "Your money or your life!", "archery_ticket_price": "0", - "id": "2632" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "Parlez-vous francais? (Do you speak French?)", - "grand_exchange_price": "34300", - "durability": null, - "name": "Blue beret", - "tradeable": "true", + "id": "2632", + "name": "Highwayman mask", "archery_ticket_price": "0", - "hat": true, + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2633", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "34300", - "durability": null, "name": "Blue beret", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2634" - }, - { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "Parlez-vous francais?(Do you speak French?)", - "grand_exchange_price": "117500", - "durability": null, - "name": "Black beret", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": true, - "id": "2635", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "117500", - "durability": null, - "name": "Black beret", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2636" - }, - { - "lendable": "true", - "ge_buy_limit": "2", "examine": "Parlez-vous francais? (Do you speak French?)", - "grand_exchange_price": "328000", - "durability": null, - "name": "White beret", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", "hat": true, + "lendable": "true", + "tradeable": "true" + }, + { + "id": "2634", + "name": "Blue beret", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2635", + "name": "Black beret", + "examine": "Parlez-vous francais?(Do you speak French?)", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": true, + "lendable": "true", + "tradeable": "true" + }, + { + "id": "2636", + "name": "Black beret", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2637", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "328000", - "durability": null, "name": "White beret", - "tradeable": "true", + "examine": "Parlez-vous francais? (Do you speak French?)", "archery_ticket_price": "0", - "id": "2638" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": true, + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "All for one and one for all!", - "grand_exchange_price": "29100", - "durability": null, - "name": "Tan cavalier", - "tradeable": "true", + "id": "2638", + "name": "White beret", "archery_ticket_price": "0", - "hat": true, + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2639", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "29100", - "durability": null, "name": "Tan cavalier", - "tradeable": "true", + "examine": "All for one and one for all!", "archery_ticket_price": "0", - "id": "2640" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": true, + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "All for one and one for all!", - "grand_exchange_price": "23600", - "durability": null, - "name": "Dark cavalier", - "tradeable": "true", + "id": "2640", + "name": "Tan cavalier", "archery_ticket_price": "0", - "hat": true, + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2641", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "23600", - "durability": null, "name": "Dark cavalier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2642" - }, - { - "lendable": "true", - "ge_buy_limit": "2", "examine": "All for one and one for all!", - "grand_exchange_price": "384500", - "durability": null, - "name": "Black cavalier", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", "hat": true, + "lendable": "true", + "tradeable": "true" + }, + { + "id": "2642", + "name": "Dark cavalier", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2643", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "384500", - "durability": null, "name": "Black cavalier", - "tradeable": "true", + "examine": "All for one and one for all!", "archery_ticket_price": "0", - "id": "2644" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": true, + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "A minimalist's hat.", - "grand_exchange_price": "91300", - "durability": null, - "name": "Red headband", - "tradeable": "true", + "id": "2644", + "name": "Black cavalier", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2645", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "91300", - "durability": null, "name": "Red headband", - "tradeable": "true", + "examine": "A minimalist's hat.", "archery_ticket_price": "0", - "id": "2646" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "A minimalist's hat.", - "grand_exchange_price": "32900", - "durability": null, - "name": "Black headband", - "tradeable": "true", + "id": "2646", + "name": "Red headband", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2647", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "32900", - "durability": null, "name": "Black headband", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2648" - }, - { - "lendable": "true", - "ge_buy_limit": "2", "examine": "A minimalist's hat.", - "grand_exchange_price": "17800", - "durability": null, - "name": "Brown headband", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true" + }, + { + "id": "2648", + "name": "Black headband", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2649", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "17800", - "durability": null, "name": "Brown headband", - "tradeable": "true", + "examine": "A minimalist's hat.", "archery_ticket_price": "0", - "id": "2650" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "Shiver me timbers!", - "grand_exchange_price": "82500", - "durability": null, - "name": "Pirate's hat", - "tradeable": "true", + "id": "2650", + "name": "Brown headband", "archery_ticket_price": "0", - "hat": "true", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2651", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "82500", - "durability": null, "name": "Pirate's hat", - "tradeable": "true", + "examine": "Shiver me timbers!", "archery_ticket_price": "0", - "id": "2652" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": "true", + "tradeable": "true" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platebody in the colours of Zamorak.", - "durability": null, - "weight": "9", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "809000", - "name": "Zamorak platebody", - "tradeable": "true", + "id": "2652", + "name": "Pirate's hat", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2653", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "809000", - "durability": null, "name": "Zamorak platebody", - "tradeable": "true", + "examine": "Rune platebody in the colours of Zamorak.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "2654" + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platelegs in the colours of Zamorak.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "281500", - "name": "Zamorak platelegs", - "tradeable": "true", + "id": "2654", + "name": "Zamorak platebody", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2655", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "281500", - "durability": null, "name": "Zamorak platelegs", - "tradeable": "true", + "examine": "Rune platelegs in the colours of Zamorak.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "2656" + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" }, { - "remove_head": "true", - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A full helmet in the colours of Zamorak.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "601500", - "name": "Zamorak full helm", - "tradeable": "true", + "id": "2656", + "name": "Zamorak platelegs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2657", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,1" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "601500", - "durability": null, "name": "Zamorak full helm", - "tradeable": "true", + "examine": "A full helmet in the colours of Zamorak.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "2658" + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,1", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A Rune kiteshield in the colours of Zamorak.", - "durability": null, - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "499500", - "name": "Zamorak kiteshield", - "tradeable": "true", + "id": "2658", + "name": "Zamorak full helm", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2659", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "499500", - "durability": null, "name": "Zamorak kiteshield", - "tradeable": "true", + "examine": "A Rune kiteshield in the colours of Zamorak.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "2660" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platebody in the colours of Saradomin.", - "durability": null, - "weight": "9.07", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "1600000", - "name": "Saradomin platebody", - "tradeable": "true", + "id": "2660", + "name": "Zamorak kiteshield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "2661", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1600000", - "durability": null, "name": "Saradomin platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2662" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platelegs in the colours of Saradomin.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "444000", - "name": "Saradomin platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2663", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "444000", - "durability": null, - "name": "Saradomin platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2664" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune full helmet in the colours of Saradomin.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "1100000", - "name": "Saradomin full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2665", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1100000", - "durability": null, - "name": "Saradomin full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2666" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune kiteshield in the colours of Saradomin.", - "durability": null, - "weight": "5.4", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "795900", - "name": "Saradomin kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2667", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "795900", - "durability": null, - "name": "Saradomin kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2668" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platebody in the colours of Guthix.", - "durability": null, - "weight": "9.07", + "examine": "Rune platebody in the colours of Saradomin.", "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", + "ge_buy_limit": "2", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "307900", - "name": "Guthix platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2669", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "307900", - "durability": null, - "name": "Guthix platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2670" - }, - { "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platelegs in the colours of Guthix.", + "tradeable": "true", + "weight": "9.07" + }, + { + "id": "2662", + "name": "Saradomin platebody", + "archery_ticket_price": "0", "durability": null, - "weight": "9", + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2663", + "name": "Saradomin platelegs", + "examine": "Rune platelegs in the colours of Saradomin.", "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "169900", - "name": "Guthix platelegs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2671", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "169900", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", "durability": null, - "name": "Guthix platelegs", + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2672" + "weight": "9" }, { + "id": "2664", + "name": "Saradomin platelegs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2665", + "name": "Saradomin full helm", + "examine": "Rune full helmet in the colours of Saradomin.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune full helmet in the colours of Guthix.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "323100", - "name": "Guthix full helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2673", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,1,0,0" + "weight": "2" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "323100", - "durability": null, - "name": "Guthix full helm", - "tradeable": "true", + "id": "2666", + "name": "Saradomin full helm", "archery_ticket_price": "0", - "id": "2674" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune kiteshield in the colours of Guthix.", - "durability": null, - "weight": "5.4", + "id": "2667", + "name": "Saradomin kiteshield", + "examine": "Rune kiteshield in the colours of Saradomin.", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "247300", - "name": "Guthix kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2675", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { "ge_buy_limit": "2", - "grand_exchange_price": "247300", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "2668", + "name": "Saradomin kiteshield", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2669", + "name": "Guthix platebody", + "examine": "Rune platebody in the colours of Guthix.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9.07" + }, + { + "id": "2670", + "name": "Guthix platebody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2671", + "name": "Guthix platelegs", + "examine": "Rune platelegs in the colours of Guthix.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "2672", + "name": "Guthix platelegs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2673", + "name": "Guthix full helm", + "examine": "A rune full helmet in the colours of Guthix.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,1,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "2674", + "name": "Guthix full helm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2675", "name": "Guthix kiteshield", + "examine": "Rune kiteshield in the colours of Guthix.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2676" + "weight": "5.4" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", + "id": "2676", + "name": "Guthix kiteshield", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "2677", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2677" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2678" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2678", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2679" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2679", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2680" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2680", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2681" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2681", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2682" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2682", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2683" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2683", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2684" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2684", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2685" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2685", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2686" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2686", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2687" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2687", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2688" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2688", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2689" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2689", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2690" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2690", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2691" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2691", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2692" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2692", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2693" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2693", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2694" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2694", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2695" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2695", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2696" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2696", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2697" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2697", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2698" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2698", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2699" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2699", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2700" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2700", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2701" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2701", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2702" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2702", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2703" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2703", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2704" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2704", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2705" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2705", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2706" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2706", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2707" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2707", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2708" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2708", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2709" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2709", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2710" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2710", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2711" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2711", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2712" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2712", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2713" + "durability": null, + "shop_price": "5000" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "id": "2713", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "2714", "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2714" - }, - { "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2715" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2716" + "weight": "5" }, { + "id": "2715", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", "archery_ticket_price": "0", - "id": "2717" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "2716", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2717", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2718" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2719" + "weight": "5" }, { + "id": "2718", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", "archery_ticket_price": "0", - "id": "2720" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "2719", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2720", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2721" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2722" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2723" + "weight": "5" }, { + "id": "2721", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2724" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2722", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2725" + "durability": null, + "shop_price": "5000" }, { + "id": "2723", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2724", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2726" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2725", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2727" + "durability": null, + "shop_price": "5000" }, { + "id": "2726", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2728" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2727", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2729" + "durability": null, + "shop_price": "5000" }, { + "id": "2728", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2730" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2729", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2731" + "durability": null, + "shop_price": "5000" }, { + "id": "2730", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2732" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2731", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2733" + "durability": null, + "shop_price": "5000" }, { + "id": "2732", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2734" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2733", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2735" + "durability": null, + "shop_price": "5000" }, { + "id": "2734", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2736" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2735", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2737" + "durability": null, + "shop_price": "5000" }, { + "id": "2736", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2738" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2737", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2739" + "durability": null, + "shop_price": "5000" }, { + "id": "2738", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2740" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2739", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2741" + "durability": null, + "shop_price": "5000" }, { + "id": "2740", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2742" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2741", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2743" + "durability": null, + "shop_price": "5000" }, { + "id": "2742", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2744" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2743", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2745" + "durability": null, + "shop_price": "5000" }, { + "id": "2744", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2746" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2745", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2747" + "durability": null, + "shop_price": "5000" }, { + "id": "2746", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2748" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2747", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2773" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2774" + "durability": null, + "shop_price": "5000" }, { + "id": "2748", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2775" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2773", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2776" + "durability": null, + "shop_price": "5000" }, { + "id": "2774", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2775", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2777" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2776", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2778" + "durability": null, + "shop_price": "5000" }, { + "id": "2777", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2779" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2778", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2780" + "durability": null, + "shop_price": "5000" }, { + "id": "2779", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2781" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2780", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2782" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2783" + "durability": null, + "shop_price": "5000" }, { + "id": "2781", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2784" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2782", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2785" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2786" + "durability": null, + "shop_price": "5000" }, { + "id": "2783", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2784", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2787" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2785", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2788" + "durability": null, + "shop_price": "5000" }, { + "id": "2786", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2787", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2789" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2788", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2790" + "durability": null, + "shop_price": "5000" }, { + "id": "2789", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2791" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2790", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2792" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2793" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2791", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "2792", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2794" + "durability": null, + "shop_price": "5000" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", + "id": "2793", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "2794", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2795", "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "2795" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2796" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2797" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", "archery_ticket_price": "0", - "id": "2798" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2799" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", "durability": null, + "shop_price": "5" + }, + { + "id": "2796", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2797", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2798", "name": "Puzzle box", + "examine": "I need to solve this.", "archery_ticket_price": "0", - "id": "2800" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2799", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2801" + "durability": null, + "shop_price": "5000" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "id": "2800", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "shop_price": "5" + }, + { + "id": "2801", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2802", "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2802" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2803" - }, - { "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2804" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2803", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2805" + "durability": null, + "shop_price": "5000" }, { + "id": "2804", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2806" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2805", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2807" + "durability": null, + "shop_price": "5000" }, { + "id": "2806", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2808" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2807", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2809" + "durability": null, + "shop_price": "5000" }, { + "id": "2808", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2810" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2809", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2811" + "durability": null, + "shop_price": "5000" }, { + "id": "2810", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2812" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2811", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2813" + "durability": null, + "shop_price": "5000" }, { + "id": "2812", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2814" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2813", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2815" + "durability": null, + "shop_price": "5000" }, { + "id": "2814", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2816" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2815", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2817" + "durability": null, + "shop_price": "5000" }, { + "id": "2816", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2818" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2817", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2819" + "durability": null, + "shop_price": "5000" }, { + "id": "2818", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2820" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2819", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2821" + "durability": null, + "shop_price": "5000" }, { + "id": "2820", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2822" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2821", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2823" + "durability": null, + "shop_price": "5000" }, { + "id": "2822", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2824" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2823", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2825" + "durability": null, + "shop_price": "5000" }, { + "id": "2824", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2826" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2825", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2827" + "durability": null, + "shop_price": "5000" }, { + "id": "2826", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2828" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2827", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2829" + "durability": null, + "shop_price": "5000" }, { + "id": "2828", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "2830" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2829", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2831" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2833" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2830", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "2831", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2835" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2833", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2837" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2835", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2839" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2837", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2841" + "durability": null, + "shop_price": "5000" }, { - "examine": "I need to answer this correctly.", + "id": "2839", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "2841", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2842", "name": "Challenge scroll", - "archery_ticket_price": "0", - "id": "2842" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2843" - }, - { "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "2844" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2843", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2845" + "durability": null, + "shop_price": "5000" }, { + "id": "2844", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2845", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "2846", "name": "Challenge scroll", - "archery_ticket_price": "0", - "id": "2846" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2847" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2848" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2849" - }, - { "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "2850" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2847", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2851" + "durability": null, + "shop_price": "5000" }, { + "id": "2848", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2849", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2850", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "2852" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2851", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "2853" + "durability": null, + "shop_price": "5000" }, { + "id": "2852", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2853", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "2854", "name": "Challenge scroll", + "examine": "I need to answer this correctly.", "archery_ticket_price": "0", - "id": "2854" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "2855", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "2855" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2856" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2856", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2857" + "durability": null, + "shop_price": "5000" }, { - "shop_price": "5000", + "id": "2857", + "name": "Clue scroll", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "2858" + "durability": null, + "shop_price": "5000" }, { - "ge_buy_limit": "1000", + "id": "2858", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "2859", + "name": "Wolf bones", "examine": "Bones of a recently slain wolf.", - "grand_exchange_price": "1266", - "durability": null, - "name": "Wolf bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "2859" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1266", - "durability": null, + "id": "2860", "name": "Wolf bones", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2860" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "shop_price": "5", - "ge_buy_limit": "1000", - "examine": "I can make an ogre arrow with these.", - "grand_exchange_price": "5", - "durability": null, + "id": "2861", "name": "Wolfbone arrowtips", - "tradeable": "true", + "examine": "I can make an ogre arrow with these.", "archery_ticket_price": "0", - "id": "2861" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true" }, { - "ge_buy_limit": "25000", + "id": "2862", + "name": "Achey tree logs", "examine": "These logs are longer than normal.", - "grand_exchange_price": "169", - "durability": null, - "name": "Achey tree logs", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "2862" - }, - { + "durability": null, "ge_buy_limit": "25000", - "grand_exchange_price": "169", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "2863", "name": "Achey tree logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2863" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A wooden arrow shaft", - "grand_exchange_price": "47", - "durability": null, + "id": "2864", "name": "Ogre arrow shaft", - "tradeable": "true", + "examine": "A wooden arrow shaft", "archery_ticket_price": "0", - "id": "2864" - }, - { - "ge_buy_limit": "1000", - "examine": "An ogre arrow with four flights attached.", - "grand_exchange_price": "172", "durability": null, - "name": "Flighted ogre arrow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2865" + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "2865", + "name": "Flighted ogre arrow", + "examine": "An ogre arrow with four flights attached.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "2866", + "name": "Ogre arrow", + "examine": "A large ogre arrow with a bone tip.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", "requirements": "{4,30}", "shop_price": "25", - "ge_buy_limit": "1000", - "examine": "A large ogre arrow with a bone tip.", - "grand_exchange_price": "49", - "durability": null, - "name": "Ogre arrow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2866", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" + "tradeable": "true" }, { - "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", - "durability": null, - "name": "Ogre bellows", - "archery_ticket_price": "0", "id": "2871", + "name": "Ogre bellows", + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "3" }, { - "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", - "durability": null, + "id": "2872", "name": "Ogre bellows (3)", + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", "archery_ticket_price": "0", - "id": "2872" + "durability": null }, { - "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", - "durability": null, + "id": "2873", "name": "Ogre bellows (2)", - "archery_ticket_price": "0", - "id": "2873" - }, - { "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2874", "name": "Ogre bellows (1)", + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", "archery_ticket_price": "0", - "id": "2874" + "durability": null }, { - "bankable": "false", - "examine": "An inflated toad.", - "durability": null, + "id": "2875", "name": "Bloated toad", - "tradeable": "false", + "examine": "An inflated toad.", + "archery_ticket_price": "0", + "bankable": "false", "destroy": "true", - "weight": "0.7", - "archery_ticket_price": "0", - "id": "2875" + "durability": null, + "tradeable": "false", + "weight": "0.7" }, { - "ge_buy_limit": "10000", + "id": "2876", + "name": "Raw chompy", "examine": "I need to cook this first.", - "grand_exchange_price": "2145", - "durability": null, - "name": "Raw chompy", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "2876" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "2145", - "durability": null, + "tradeable": "true", + "weight": "10" + }, + { + "id": "2877", "name": "Raw chompy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2877" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "130", - "ge_buy_limit": "1000", + "id": "2878", + "name": "Cooked chompy", "examine": "It might look delicious to an ogre.Roasted chompy bird.", - "grand_exchange_price": "95", - "durability": null, - "name": "Cooked chompy", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "2878" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "95", - "durability": null, + "shop_price": "130", + "tradeable": "true", + "weight": "10" + }, + { + "id": "2879", "name": "Cooked chompy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2879" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "durability": null, + "id": "2881", "name": "Ruined chompy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2881" - }, - { - "examine": "It has been deliciously seasoned to taste wonderful for ogres.", "durability": null, - "name": "Seasoned chompy", - "weight": "10", - "archery_ticket_price": "0", - "id": "2882" + "tradeable": "true" }, { + "id": "2882", + "name": "Seasoned chompy", + "examine": "It has been deliciously seasoned to taste wonderful for ogres.", + "archery_ticket_price": "0", + "durability": null, + "weight": "10" + }, + { + "id": "2883", + "name": "Ogre bow", + "examine": "More powerful than a normal bow, useful against large game birds.", + "archery_ticket_price": "0", + "attack_audios": "2700,0,0,0", + "attack_speed": "8", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", "requirements": "{4,30}", "shop_price": "500", - "examine": "More powerful than a normal bow, useful against large game birds.", - "durability": null, - "weight": "1", - "attack_speed": "8", "two_handed": "true", "weapon_interface": "16", - "equipment_slot": "3", - "attack_audios": "2700,0,0,0", - "name": "Ogre bow", - "archery_ticket_price": "0", - "id": "2883", - "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,0" + "weight": "1" }, { - "examine": "Book of the elemental shield.", - "durability": null, + "id": "2886", "name": "Battered book", + "examine": "Book of the elemental shield.", "archery_ticket_price": "0", - "id": "2886" + "durability": null }, { - "examine": "An old battered key. (Elemental Workshop I)", - "durability": null, + "id": "2887", "name": "Battered key", + "examine": "An old battered key. (Elemental Workshop I)", "archery_ticket_price": "0", - "id": "2887" + "durability": null }, { - "examine": "This is an empty stone bowl. / This is a stone bowl full of lava.", - "durability": null, - "name": "A stone bowl", - "archery_ticket_price": "0", "id": "2888", - "equipment_slot": "3" - }, - { - "examine": "This is an empty stone bowl. / This is a stone bowl full of lava.", - "durability": null, "name": "A stone bowl", + "examine": "This is an empty stone bowl. / This is a stone bowl full of lava.", "archery_ticket_price": "0", - "id": "2889", + "durability": null, "equipment_slot": "3" }, { - "shop_price": "2000", - "ge_buy_limit": "100", - "examine": "A shield made in the Elemental Workshop.", - "grand_exchange_price": "709", - "durability": null, - "name": "Elemental shield", - "tradeable": "true", - "weight": "0.2", + "id": "2889", + "name": "A stone bowl", + "examine": "This is an empty stone bowl. / This is a stone bowl full of lava.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { "id": "2890", - "bonuses": "0,0,0,0,0,0,0,0,6,0,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "709", - "durability": null, "name": "Elemental shield", - "tradeable": "true", + "examine": "A shield made in the Elemental Workshop.", "archery_ticket_price": "0", - "id": "2891" + "bonuses": "0,0,0,0,0,0,0,0,6,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "shop_price": "2000", + "tradeable": "true", + "weight": "0.2" }, { - "examine": "This needs refining.", + "id": "2891", + "name": "Elemental shield", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2892", "name": "Elemental ore", - "weight": "2.2", + "examine": "This needs refining.", "archery_ticket_price": "0", - "id": "2892" + "durability": null, + "weight": "2.2" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Very stylish!", - "grand_exchange_price": "1570", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", "id": "2894", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1570", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Boots", - "tradeable": "true", + "examine": "Very stylish!", "archery_ticket_price": "0", - "id": "2895" + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.3" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Some fine werewolf clothing.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "867", - "name": "Robe top", - "tradeable": "true", + "id": "2895", + "name": "Boots", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2896", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "867", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Robe top", - "tradeable": "true", + "examine": "Some fine werewolf clothing.", "archery_ticket_price": "0", - "id": "2897" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Made by werewolves for werewolves.", - "grand_exchange_price": "741", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", + "id": "2897", + "name": "Robe top", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2898", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "741", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Robe bottoms", - "tradeable": "true", + "examine": "Made by werewolves for werewolves.", "archery_ticket_price": "0", - "id": "2899" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "durability": null, - "weight": "0.4", - "equipment_slot": "0", - "grand_exchange_price": "844", - "name": "Hat", - "tradeable": "true", + "id": "2899", + "name": "Robe bottoms", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "hat": "true", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2900", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "844", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Hat", - "tradeable": "true", + "examine": "A silly pointed hat.", "archery_ticket_price": "0", - "id": "2901" + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "650", - "ge_buy_limit": "10", - "examine": "These gloves from Canifis will keep my hands warm!", - "grand_exchange_price": "1039", - "durability": null, - "name": "Gloves", - "tradeable": "true", - "weight": "0.4", + "id": "2901", + "name": "Hat", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2902", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1039", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Gloves", - "tradeable": "true", + "examine": "These gloves from Canifis will keep my hands warm!", "archery_ticket_price": "0", - "id": "2903" + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Very stylish!", - "grand_exchange_price": "1359", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", + "id": "2903", + "name": "Gloves", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "2904", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1359", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Boots", - "tradeable": "true", + "examine": "Very stylish!", "archery_ticket_price": "0", - "id": "2905" + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.3" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Some fine werewolf clothing.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "958", - "name": "Robe top", - "tradeable": "true", + "id": "2905", + "name": "Boots", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2906", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "958", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Robe top", - "tradeable": "true", + "examine": "Some fine werewolf clothing.", "archery_ticket_price": "0", - "id": "2907" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Made by werewolves for werewolves.", - "grand_exchange_price": "474", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", + "id": "2907", + "name": "Robe top", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2908", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "474", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Robe bottoms", - "tradeable": "true", + "examine": "Made by werewolves for werewolves.", "archery_ticket_price": "0", - "id": "2909" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "durability": null, - "weight": "0.4", - "equipment_slot": "0", - "grand_exchange_price": "1445", - "tradeable": "true", - "name": "Hat", + "id": "2909", + "name": "Robe bottoms", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "hat": "true", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2910", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1445", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Hat", - "tradeable": "true", + "examine": "A silly pointed hat.", "archery_ticket_price": "0", - "id": "2911" + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "650", - "ge_buy_limit": "10", - "examine": "These gloves from Canifis will keep my hands warm!", - "grand_exchange_price": "1254", - "durability": null, - "name": "Gloves", - "tradeable": "true", - "weight": "0.4", + "id": "2911", + "name": "Hat", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2912", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1254", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Gloves", - "tradeable": "true", + "examine": "These gloves from Canifis will keep my hands warm!", "archery_ticket_price": "0", - "id": "2913" + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Very stylish!", - "grand_exchange_price": "1054", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", + "id": "2913", + "name": "Gloves", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "2914", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1054", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Boots", - "tradeable": "true", + "examine": "Very stylish!", "archery_ticket_price": "0", - "id": "2915" + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.3" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Some fine werewolf clothing.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "789", - "name": "Robe top", - "tradeable": "true", + "id": "2915", + "name": "Boots", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2916", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "789", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Robe top", - "tradeable": "true", + "examine": "Some fine werewolf clothing.", "archery_ticket_price": "0", - "id": "2917" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Made by werewolves for werewolves.", - "grand_exchange_price": "603", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", + "id": "2917", + "name": "Robe top", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2918", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "603", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Robe bottoms", - "tradeable": "true", + "examine": "Made by werewolves for werewolves.", "archery_ticket_price": "0", - "id": "2919" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "durability": null, - "weight": "0.4", - "equipment_slot": "0", - "grand_exchange_price": "997", - "name": "Hat", - "tradeable": "true", + "id": "2919", + "name": "Robe bottoms", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "hat": "true", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2920", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "997", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Hat", - "tradeable": "true", + "examine": "A silly pointed hat.", "archery_ticket_price": "0", - "id": "2921" + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "650", - "ge_buy_limit": "10", - "examine": "These gloves from Canifis will keep my hands warm!", - "grand_exchange_price": "1221", - "durability": null, - "name": "Gloves", - "tradeable": "true", - "weight": "0.4", + "id": "2921", + "name": "Hat", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2922", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1221", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Gloves", - "tradeable": "true", + "examine": "These gloves from Canifis will keep my hands warm!", "archery_ticket_price": "0", - "id": "2923" + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Very stylish!", - "grand_exchange_price": "737", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", + "id": "2923", + "name": "Gloves", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "2924", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "737", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2925" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Some fine werewolf clothing.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "504", - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2926", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "504", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2927" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Made by werewolves for werewolves.", - "grand_exchange_price": "637", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2928", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "637", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2929" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "durability": null, - "weight": "0.4", - "equipment_slot": "0", - "grand_exchange_price": "925", - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": "true", - "id": "2930", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "925", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2931" - }, - { - "shop_price": "650", - "ge_buy_limit": "10", - "examine": "These gloves from Canifis will keep my hands warm!", - "grand_exchange_price": "1829", - "durability": null, - "name": "Gloves", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2932", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1829", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2933" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", "examine": "Very stylish!", - "grand_exchange_price": "988", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.3", "archery_ticket_price": "0", - "id": "2934", "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "988", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, + "id": "2925", "name": "Boots", - "tradeable": "true", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "id": "2935" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "650", - "ge_buy_limit": "100", + "id": "2926", + "name": "Robe top", "examine": "Some fine werewolf clothing.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "925", - "name": "Robe top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2936", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "925", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2937" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Made by werewolves for werewolves.", - "grand_exchange_price": "927", - "durability": null, - "name": "Robe bottoms", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "2938", "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "927", + "id": "2927", + "name": "Robe top", "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2928", "name": "Robe bottoms", - "tradeable": "true", + "examine": "Made by werewolves for werewolves.", "archery_ticket_price": "0", - "id": "2939" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "650", + "id": "2929", + "name": "Robe bottoms", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2930", + "name": "Hat", "examine": "A silly pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", "durability": null, - "weight": "0.4", "equipment_slot": "0", - "grand_exchange_price": "1209", - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": "true", - "id": "2940", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1209", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2941" - }, - { + "hat": "true", "shop_price": "650", - "ge_buy_limit": "10", - "examine": "These gloves from Canifis will keep my hands warm!", - "grand_exchange_price": "634", - "durability": null, - "name": "Gloves", "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2942", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" + "weight": "0.4" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "634", + "id": "2931", + "name": "Hat", "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2932", "name": "Gloves", + "examine": "These gloves from Canifis will keep my hands warm!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "650", "tradeable": "true", - "archery_ticket_price": "0", - "id": "2943" + "weight": "0.4" }, { - "examine": "A key made from solid gold", + "id": "2933", + "name": "Gloves", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "2934", + "name": "Boots", + "examine": "Very stylish!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "2935", + "name": "Boots", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2936", + "name": "Robe top", + "examine": "Some fine werewolf clothing.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2937", + "name": "Robe top", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2938", + "name": "Robe bottoms", + "examine": "Made by werewolves for werewolves.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "1" + }, + { + "id": "2939", + "name": "Robe bottoms", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2940", + "name": "Hat", + "examine": "A silly pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2941", + "name": "Hat", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2942", + "name": "Gloves", + "examine": "These gloves from Canifis will keep my hands warm!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2943", + "name": "Gloves", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "2944", "name": "Golden key", + "examine": "A key made from solid gold", "archery_ticket_price": "0", - "id": "2944" + "durability": null }, { - "examine": "A key made of solid iron.", - "durability": null, + "id": "2945", "name": "Iron key", + "examine": "A key made of solid iron.", "archery_ticket_price": "0", - "id": "2945" + "durability": null }, { - "examine": "A replica tinderbox made of solid gold.", - "durability": null, + "id": "2946", "name": "Golden tinderbox", + "examine": "A replica tinderbox made of solid gold.", "archery_ticket_price": "0", - "id": "2946" + "durability": null }, { - "examine": "A replica candle made of solid gold.", - "durability": null, + "id": "2947", "name": "Golden candle", - "tradeable": "false", - "destroy": "true", + "examine": "A replica candle made of solid gold.", "archery_ticket_price": "0", - "id": "2947" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A replica pot made of solid gold.", - "durability": null, + "id": "2948", "name": "Golden pot", + "examine": "A replica pot made of solid gold.", "archery_ticket_price": "0", - "id": "2948" + "durability": null }, { - "examine": "A replica hammer made of solid gold.", - "durability": null, + "id": "2949", "name": "Golden hammer", - "tradeable": "false", + "examine": "A replica hammer made of solid gold.", + "archery_ticket_price": "0", + "attack_speed": "4", "destroy": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "2949" + "durability": null, + "tradeable": "false", + "weight": "0.9" }, { - "examine": "A replica needle made of solid gold.", - "durability": null, + "id": "2951", "name": "Golden needle", + "examine": "A replica needle made of solid gold.", "archery_ticket_price": "0", - "id": "2951" + "durability": null }, { + "id": "2952", + "name": "Wolfbane", "examine": "A silver dagger that can prevent werewolves changing form.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "400,400,401,400", "attack_audios": "2517,2517,2500,2517", - "name": "Wolfbane", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "2952", - "bonuses": "11,5,-4,1,0,0,0,0,1,0,1,10,5,0,0" - }, - { - "examine": "It's a bucket of water.", - "grand_exchange_price": "74", + "attack_speed": "4", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,1,10,5,0,0", + "defence_anim": "378", "durability": null, - "name": "Bucket of water", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "2953" - }, - { - "examine": "It's a bucket of water.", - "grand_exchange_price": "74", - "durability": null, - "name": "Bucket of water", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "2954" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A foul smelling brew.", - "grand_exchange_price": "16", - "durability": null, - "name": "Moonlight mead", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2955" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "16", - "durability": null, - "name": "Moonlight mead", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2956" - }, - { - "examine": "An empty druid pouch.", - "durability": null, - "name": "Druid pouch", - "archery_ticket_price": "0", - "id": "2957" - }, - { - "examine": "A druid pouch.", - "durability": null, - "name": "Druid pouch", - "archery_ticket_price": "0", - "id": "2958" - }, - { - "examine": "Erhhh! It stinks.", - "durability": null, - "name": "Rotten food", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "2959" - }, - { - "durability": null, - "name": "Rotten food", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2960" - }, - { - "ge_buy_limit": "100", - "examine": "It's a silver sickle.", - "durability": null, - "weight": "1.6", - "weapon_interface": "6", - "defence_anim": "397", "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "28", - "name": "Silver sickle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2961", - "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,0,0,0" + "render_anim": "2584", + "tradeable": "false", + "weapon_interface": "5", + "weight": "0.4" }, { + "id": "2953", + "name": "Bucket of water", + "examine": "It's a bucket of water.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "3" + }, + { + "id": "2954", + "name": "Bucket of water", + "examine": "It's a bucket of water.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "3" + }, + { + "id": "2955", + "name": "Moonlight mead", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "28", - "durability": null, - "name": "Silver sickle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2962" + "shop_price": "5", + "tradeable": "true" }, { - "attack_anims": "390,390,381,390", - "examine": "It's a blessed silver sickle.", - "durability": null, - "name": "Silver sickle(b)", - "weight": "1.5", + "id": "2956", + "name": "Moonlight mead", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "2957", + "name": "Druid pouch", + "examine": "An empty druid pouch.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2958", + "name": "Druid pouch", + "examine": "A druid pouch.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "2959", + "name": "Rotten food", + "examine": "Erhhh! It stinks.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "2960", + "name": "Rotten food", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "2961", + "name": "Silver sickle", + "examine": "It's a silver sickle.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "tradeable": "true", "weapon_interface": "6", + "weight": "1.6" + }, + { + "id": "2962", + "name": "Silver sickle", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "2963", + "name": "Silver sickle(b)", + "examine": "It's a blessed silver sickle.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,5,0,0", "defence_anim": "397", - "equipment_slot": "3" + "durability": null, + "equipment_slot": "3", + "weapon_interface": "6", + "weight": "1.5" }, { - "shop_price": "1", - "examine": "Used for washing your face, amongst other things.", - "durability": null, + "id": "2964", "name": "Washing bowl", - "weight": "0.4", + "examine": "Used for washing your face, amongst other things.", "archery_ticket_price": "0", - "id": "2964" + "durability": null, + "shop_price": "1", + "weight": "0.4" }, { - "examine": "A small mirror, probably used for grooming.", - "durability": null, + "id": "2966", "name": "Mirror", - "weight": "0.2", + "examine": "A small mirror, probably used for grooming.", "archery_ticket_price": "0", - "id": "2966" + "durability": null, + "weight": "0.2" }, { - "examine": "A druidic spell given to you freely by the spirit of Filliman Tarlock.", - "durability": null, + "id": "2968", "name": "Druidic spell", + "examine": "A druidic spell given to you freely by the spirit of Filliman Tarlock.", "archery_ticket_price": "0", - "id": "2968" + "durability": null }, { - "examine": "A used druidic spell given to you freely by the spirit of Filliman Tarlock.", - "durability": null, + "id": "2969", "name": "A used spell", + "examine": "A used druidic spell given to you freely by the spirit of Filliman Tarlock.", "archery_ticket_price": "0", - "id": "2969" + "durability": null }, { - "ge_buy_limit": "10000", + "id": "2970", + "name": "Mort myre fungus", "examine": "A mushroom from the swamps of Mort Myre.", - "grand_exchange_price": "915", - "durability": null, - "name": "Mort myre fungus", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2970" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "915", - "durability": null, - "name": "Mort myre fungus", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2971" + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2971", + "name": "Mort myre fungus", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "2972", + "name": "Mort myre stem", "examine": "A cutting from a budding branch.", - "grand_exchange_price": "338", - "durability": null, - "name": "Mort myre stem", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2972" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "338", - "durability": null, + "id": "2973", "name": "Mort myre stem", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2973" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "2974", + "name": "Mort myre pear", "examine": "A pear picked from a dying bush in Mort Myre.", - "grand_exchange_price": "975", - "durability": null, - "name": "Mort myre pear", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "2974" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "975", - "durability": null, + "id": "2975", "name": "Mort myre pear", - "tradeable": "true", "archery_ticket_price": "0", - "id": "2975" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "10", - "ge_buy_limit": "100", + "id": "2976", + "name": "Sickle mould", "examine": "Used to make sickles.", - "grand_exchange_price": "498", - "durability": null, - "name": "Sickle mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "2976" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "498", - "durability": null, - "name": "Sickle mould", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2977" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2978", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2979", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2980", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2981", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2982", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2983", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2984", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2985", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2986", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2987", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2988", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2989", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2990", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2991", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2992", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2993", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2994", - "equipment_slot": "0" - }, - { - "examine": "A symbol of your chompy bird hunting prowess.", - "durability": null, - "name": "Chompy bird hat", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "2995", - "equipment_slot": "0" - }, - { - "examine": "I can exchange these for further experience or items.", - "durability": null, - "name": "Agility arena ticket", - "archery_ticket_price": "0", - "id": "2996" - }, - { - "shop_price": "800", - "ge_buy_limit": "10", - "examine": "You should see the shark...", - "grand_exchange_price": "1500000", - "durability": null, - "name": "Pirate's hook", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "2997", - "bonuses": "0,0,0,0,0,1,5,3,0,0,1,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "4056", - "durability": null, - "name": "Clean toadflax", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2998" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "4056", - "durability": null, - "name": "Clean toadflax", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "2999" - }, - { "shop_price": "10", - "ge_buy_limit": "10000", - "examine": "A fresh herb.", - "grand_exchange_price": "10500", - "durability": null, - "name": "Clean snapdragon", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3000" + "weight": "0.4" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "10500", - "durability": null, - "name": "Clean snapdragon", - "tradeable": "true", + "id": "2977", + "name": "Sickle mould", "archery_ticket_price": "0", - "id": "3001" - }, - { + "durability": null, "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this toadflax potion.", - "grand_exchange_price": "3988", - "durability": null, - "name": "Toadflax potion(unf)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "3002" + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3988", - "durability": null, - "name": "Toadflax potion(unf)", - "tradeable": "true", + "id": "2978", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3003" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this snapdragon potion.", - "grand_exchange_price": "9588", - "durability": null, - "name": "Snapdragon potion(unf)", - "tradeable": "true", + "id": "2979", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3004" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "9588", - "durability": null, - "name": "Snapdragon potion(unf)", - "tradeable": "true", + "id": "2980", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3005" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "150", - "examine": "Keep out of reach of children and familiars.", - "durability": null, - "name": "Firework", - "tradeable": "true", + "id": "2981", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3006" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "durability": null, - "name": "Firework", - "tradeable": "true", + "id": "2982", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3007" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "145", - "ge_buy_limit": "100", - "examine": "4 doses of energy potion.", - "grand_exchange_price": "33", - "durability": null, - "name": "Energy potion(4)", - "tradeable": "true", + "id": "2983", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3008" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "33", - "durability": null, - "name": "Energy potion(4)", - "tradeable": "true", + "id": "2984", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3009" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "145", - "ge_buy_limit": "100", - "examine": "3 doses of energy potion.", - "grand_exchange_price": "18", - "durability": null, - "name": "Energy potion(3)", - "tradeable": "true", + "id": "2985", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3010" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "18", - "durability": null, - "name": "Energy potion(3)", - "tradeable": "true", + "id": "2986", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3011" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "145", - "ge_buy_limit": "100", - "examine": "2 doses of energy potion.", - "grand_exchange_price": "11", - "durability": null, - "name": "Energy potion(2)", - "tradeable": "true", + "id": "2987", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3012" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "11", - "durability": null, - "name": "Energy potion(2)", - "tradeable": "true", + "id": "2988", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3013" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "145", - "ge_buy_limit": "100", - "examine": "1 dose of energy potion.", - "grand_exchange_price": "25", - "durability": null, - "name": "Energy potion(1)", - "tradeable": "true", + "id": "2989", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3014" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "25", - "durability": null, - "name": "Energy potion(1)", - "tradeable": "true", + "id": "2990", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3015" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "4000", - "ge_buy_limit": "1000", - "examine": "4 doses of super energy potion.", - "grand_exchange_price": "3088", - "durability": null, - "name": "Super energy(4)", - "tradeable": "true", + "id": "2991", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3016" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "shop_price": "4000", - "ge_buy_limit": "1000", - "grand_exchange_price": "3088", - "durability": null, - "name": "Super energy(4)", - "tradeable": "true", + "id": "2992", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3017" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "1000", - "examine": "3 doses of super energy potion.", - "grand_exchange_price": "2485", - "durability": null, - "name": "Super energy(3)", - "tradeable": "true", + "id": "2993", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3018" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "2485", - "durability": null, - "name": "Super energy(3)", - "tradeable": "true", + "id": "2994", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3019" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "1000", - "examine": "2 doses of super energy potion.", - "grand_exchange_price": "1592", - "durability": null, - "name": "Super energy(2)", - "tradeable": "true", + "id": "2995", + "name": "Chompy bird hat", + "examine": "A symbol of your chompy bird hunting prowess.", "archery_ticket_price": "0", - "id": "3020" + "durability": null, + "equipment_slot": "0", + "weight": "0.33" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1592", - "durability": null, - "name": "Super energy(2)", - "tradeable": "true", + "id": "2996", + "name": "Agility arena ticket", + "examine": "I can exchange these for further experience or items.", "archery_ticket_price": "0", - "id": "3021" + "durability": null }, { - "ge_buy_limit": "1000", - "examine": "1 dose of super energy potion.", - "grand_exchange_price": "1432", - "durability": null, - "name": "Super energy(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3022" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1432", - "durability": null, - "name": "Super energy(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3023" - }, - { - "shop_price": "12000", - "ge_buy_limit": "1000", - "examine": "4 doses of super restore potion.", - "grand_exchange_price": "11500", - "durability": null, - "name": "Super restore(4)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "3024" - }, - { - "shop_price": "12000", - "ge_buy_limit": "1000", - "grand_exchange_price": "11500", - "durability": null, - "name": "Super restore(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3025" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of super restore potion.", - "grand_exchange_price": "8690", - "durability": null, - "name": "Super restore(3)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "3026" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "8690", - "durability": null, - "name": "Super restore(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3027" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of super restore potion.", - "grand_exchange_price": "5637", - "durability": null, - "name": "Super restore(2)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "3028" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "5637", - "durability": null, - "name": "Super restore(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3029" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of super restore potion.", - "grand_exchange_price": "2606", - "durability": null, - "name": "Super restore(1)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "3030" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2606", - "durability": null, - "name": "Super restore(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3031" - }, - { - "ge_buy_limit": "100", - "examine": "4 doses of Agility potion.", - "grand_exchange_price": "276", - "durability": null, - "name": "Agility potion(4)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "3032" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "276", - "durability": null, - "name": "Agility potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3033" - }, - { - "ge_buy_limit": "100", - "examine": "3 doses of Agility potion.", - "grand_exchange_price": "148", - "durability": null, - "name": "Agility potion(3)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "3034" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "148", - "durability": null, - "name": "Agility potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3035" - }, - { - "ge_buy_limit": "100", - "examine": "2 doses of Agility potion.", - "grand_exchange_price": "115", - "durability": null, - "name": "Agility potion(2)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "3036" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "115", - "durability": null, - "name": "Agility potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3037" - }, - { - "ge_buy_limit": "100", - "examine": "1 dose of Agility potion.", - "grand_exchange_price": "306", - "durability": null, - "name": "Agility potion(1)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "3038" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "306", - "durability": null, - "name": "Agility potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3039" - }, - { - "ge_buy_limit": "100", - "examine": "4 doses of Magic potion.", - "grand_exchange_price": "7214", - "durability": null, - "name": "Magic potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3040" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7214", - "durability": null, - "name": "Magic potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3041" - }, - { - "ge_buy_limit": "100", - "examine": "3 doses of Magic potion.", - "grand_exchange_price": "5285", - "durability": null, - "name": "Magic potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3042" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5285", - "durability": null, - "name": "Magic potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3043" - }, - { - "ge_buy_limit": "100", - "examine": "2 doses of Magic potion.", - "grand_exchange_price": "3697", - "durability": null, - "name": "Magic potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3044" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3697", - "durability": null, - "name": "Magic potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3045" - }, - { - "ge_buy_limit": "100", - "examine": "1 dose of Magic potion.", - "grand_exchange_price": "1826", - "durability": null, - "name": "Magic potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3046" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1826", - "durability": null, - "name": "Magic potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3047" - }, - { - "durability": null, + "id": "2997", "name": "Pirate's hook", - "tradeable": "true", + "examine": "You should see the shark...", "archery_ticket_price": "0", - "id": "3048" + "bonuses": "0,0,0,0,0,1,5,3,0,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "800", + "tradeable": "true", + "weight": "0.3" }, { + "id": "2998", + "name": "Clean toadflax", + "examine": "A fresh herb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "2999", + "name": "Clean toadflax", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3000", + "name": "Clean snapdragon", + "examine": "A fresh herb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "3001", + "name": "Clean snapdragon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3002", + "name": "Toadflax potion(unf)", + "examine": "I need another ingredient to finish this toadflax potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "3003", + "name": "Toadflax potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3004", + "name": "Snapdragon potion(unf)", + "examine": "I need another ingredient to finish this snapdragon potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3005", + "name": "Snapdragon potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3006", + "name": "Firework", + "examine": "Keep out of reach of children and familiars.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "3007", + "name": "Firework", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3008", + "name": "Energy potion(4)", + "examine": "4 doses of energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "145", + "tradeable": "true" + }, + { + "id": "3009", + "name": "Energy potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3010", + "name": "Energy potion(3)", + "examine": "3 doses of energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "145", + "tradeable": "true" + }, + { + "id": "3011", + "name": "Energy potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3012", + "name": "Energy potion(2)", + "examine": "2 doses of energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "145", + "tradeable": "true" + }, + { + "id": "3013", + "name": "Energy potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3014", + "name": "Energy potion(1)", + "examine": "1 dose of energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "145", + "tradeable": "true" + }, + { + "id": "3015", + "name": "Energy potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3016", + "name": "Super energy(4)", + "examine": "4 doses of super energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "4000", + "tradeable": "true" + }, + { + "id": "3017", + "name": "Super energy(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "4000", + "tradeable": "true" + }, + { + "id": "3018", + "name": "Super energy(3)", + "examine": "3 doses of super energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3019", + "name": "Super energy(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3020", + "name": "Super energy(2)", + "examine": "2 doses of super energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3021", + "name": "Super energy(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3022", + "name": "Super energy(1)", + "examine": "1 dose of super energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3023", + "name": "Super energy(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3024", + "name": "Super restore(4)", + "examine": "4 doses of super restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "12000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "3025", + "name": "Super restore(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "12000", + "tradeable": "true" + }, + { + "id": "3026", + "name": "Super restore(3)", + "examine": "3 doses of super restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "3027", + "name": "Super restore(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3028", + "name": "Super restore(2)", + "examine": "2 doses of super restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "3029", + "name": "Super restore(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3030", + "name": "Super restore(1)", + "examine": "1 dose of super restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "3031", + "name": "Super restore(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3032", + "name": "Agility potion(4)", + "examine": "4 doses of Agility potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "3033", + "name": "Agility potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3034", + "name": "Agility potion(3)", + "examine": "3 doses of Agility potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "3035", + "name": "Agility potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3036", + "name": "Agility potion(2)", + "examine": "2 doses of Agility potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "3037", + "name": "Agility potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3038", + "name": "Agility potion(1)", + "examine": "1 dose of Agility potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "3039", + "name": "Agility potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3040", + "name": "Magic potion(4)", + "examine": "4 doses of Magic potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3041", + "name": "Magic potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3042", + "name": "Magic potion(3)", + "examine": "3 doses of Magic potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3043", + "name": "Magic potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3044", + "name": "Magic potion(2)", + "examine": "2 doses of Magic potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3045", + "name": "Magic potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3046", + "name": "Magic potion(1)", + "examine": "1 dose of Magic potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3047", + "name": "Magic potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3048", + "name": "Pirate's hook", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3049", + "name": "Grimy toadflax", + "examine": "I need to clean this herb before I can use it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", "requirements": "{15,30}", + "tradeable": "true" + }, + { + "id": "3050", + "name": "Grimy toadflax", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3051", + "name": "Grimy snapdragon", "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "3996", - "durability": null, - "name": "Grimy toadflax", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3049" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "3996", - "durability": null, - "name": "Grimy toadflax", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3050" - }, - { "requirements": "{15,59}", - "ge_buy_limit": "10000", - "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "10500", - "durability": null, - "name": "Grimy snapdragon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3051" + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "10500", - "durability": null, + "id": "3052", "name": "Grimy snapdragon", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3052" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "9985", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "3053", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Lava battlestaff" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "34100", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3054", - "stand_turn_anim": "1209", - "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", - "requirements": "{0,40}-{6,40}", - "shop_price": "160", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Mystic lava staff" - }, - { - "durability": null, "name": "Lava battlestaff", - "tradeable": "true", + "examine": "It's a slightly magical stick.", "archery_ticket_price": "0", - "id": "3055" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "durability": null, + "id": "3054", "name": "Mystic lava staff", - "tradeable": "true", + "examine": "It's a slightly magical stick.", "archery_ticket_price": "0", - "id": "3056" + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", + "run_anim": "1210", + "shop_price": "160", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" }, { - "examine": "A mime would wear this.", - "durability": null, - "name": "Mime mask", + "id": "3055", + "name": "Lava battlestaff", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3056", + "name": "Mystic lava staff", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3057", + "name": "Mime mask", + "examine": "A mime would wear this.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "0" }, { - "remove_sleeves": "true", - "examine": "A mime would wear these.", - "durability": null, - "name": "Mime top", - "archery_ticket_price": "0", "id": "3058", - "equipment_slot": "4" + "name": "Mime top", + "examine": "A mime would wear these.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { - "examine": "A mime would wear these.", - "durability": null, - "name": "Mime legs", - "archery_ticket_price": "0", "id": "3059", + "name": "Mime legs", + "examine": "A mime would wear these.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "7" }, { - "examine": "A mime would wear these.", - "durability": null, - "name": "Mime gloves", - "archery_ticket_price": "0", "id": "3060", + "name": "Mime gloves", + "examine": "A mime would wear these.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "9" }, { - "examine": "A mime would wear these.", - "durability": null, - "name": "Mime boots", - "weight": "0.5", - "archery_ticket_price": "0", "id": "3061", - "equipment_slot": "10" + "name": "Mime boots", + "examine": "A mime would wear these.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "10", + "weight": "0.5" }, { - "examine": "It seems to be humming...", - "durability": null, + "id": "3062", "name": "Strange box", - "tradeable": "false", + "examine": "It seems to be humming...", + "archery_ticket_price": "0", "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3062" + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "requirements": "{4,10}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a black tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "628", - "attack_audios": "2547,0,0,0", - "name": "Black dart", - "tradeable": "true", - "archery_ticket_price": "0", "id": "3093", - "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" - }, - { - "requirements": "{4,10}", - "ge_buy_limit": "1000", + "name": "Black dart", "examine": "A deadly throwing dart with a black tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "582,582,582,582", - "grand_exchange_price": "740", "attack_audios": "2547,0,0,0", - "name": "Black dart(p)", + "attack_speed": "3", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,10}", "tradeable": "true", - "archery_ticket_price": "0", + "weapon_interface": "18" + }, + { "id": "3094", - "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" + "name": "Black dart(p)", + "examine": "A deadly throwing dart with a black tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,10}", + "tradeable": "true", + "weapon_interface": "18" }, { - "shop_price": "48", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "durability": null, - "weight": "0.9", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "702", - "name": "Bronze claws", - "tradeable": "true", - "archery_ticket_price": "0", "id": "3095", - "bonuses": "3,4,-4,0,0,1,2,1,0,0,0,5,0,0,0" - }, - { - "shop_price": "50", - "ge_buy_limit": "100", + "name": "Bronze claws", "examine": "A set of fighting claws.", - "durability": null, - "weight": "0.9", + "archery_ticket_price": "0", + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", "attack_speed": "4", + "bonuses": "3,4,-4,0,0,1,2,1,0,0,0,5,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2583", + "shop_price": "48", + "tradeable": "true", "two_handed": "true", "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "13", - "name": "Iron claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3096", - "bonuses": "4,6,-4,0,0,2,3,1,0,0,0,7,0,0,0" + "weight": "0.9" }, { + "id": "3096", + "name": "Iron claws", + "examine": "A set of fighting claws.", + "archery_ticket_price": "0", + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "4,6,-4,0,0,2,3,1,0,0,0,7,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2583", + "shop_price": "50", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "9", + "weight": "0.9" + }, + { + "id": "3097", + "name": "Steel claws", + "examine": "A set of fighting claws.", + "archery_ticket_price": "0", + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "8,11,-4,0,0,3,6,2,0,0,0,12,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2583", "requirements": "{0,5}", "shop_price": "175", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "durability": null, - "weight": "0.9", - "attack_speed": "4", + "tradeable": "true", "two_handed": "true", "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "20", - "name": "Steel claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3097", - "bonuses": "8,11,-4,0,0,3,6,2,0,0,0,12,0,0,0" + "weight": "0.9" }, { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "durability": null, - "weight": "6", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "940", - "name": "Black claws", - "tradeable": "true", - "archery_ticket_price": "0", "id": "3098", - "bonuses": "10,14,-4,0,0,4,7,2,0,0,0,14,0,0,0" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "durability": null, - "weight": "0.9", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "114", - "name": "Mithril claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3099", - "bonuses": "11,16,-4,0,0,4,8,2,0,0,0,17,0,0,0" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "durability": null, - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "649", - "name": "Adamant claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3100", - "bonuses": "18,23,-4,0,0,6,12,3,0,0,0,24,0,0,0" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "has_special": "true", - "durability": null, - "weight": "0.9", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "lendable": "true", - "grand_exchange_price": "6939", - "name": "Rune claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3101", - "bonuses": "26,38,-4,0,0,10,19,5,0,0,0,39,0,0,0" - }, - { - "examine": "The combination to Burthorpe Castle's equipment room.", - "durability": null, - "name": "Combination", - "archery_ticket_price": "0", - "id": "3102" - }, - { - "examine": "The guard wrote the IOU on the back of some paper.", - "durability": null, - "name": "Iou", - "archery_ticket_price": "0", - "id": "3103" - }, - { - "examine": "This map shows the secret way up to Death Plateau.", - "durability": null, - "name": "Secret way map", - "archery_ticket_price": "0", - "id": "3104" - }, - { - "shop_price": "1900", - "ge_buy_limit": "100", - "examine": "Boots made for general climbing; rocks a speciality.", - "durability": null, - "destroy": "true", - "weight": "0.3", - "equipment_slot": "10", - "grand_exchange_price": "51400", - "name": "Climbing boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3105", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,2,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "51400", - "durability": null, - "name": "Climbing boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3106" - }, - { - "examine": "Climbing boots with spikes.", - "durability": null, - "name": "Spiked boots", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "3107", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,2,0,0,0", - "equipment_slot": "10" - }, - { - "examine": "Place on the stone mechanism in the right order to open the door.", - "durability": null, - "name": "Stone ball", - "archery_ticket_price": "0", - "id": "3109" - }, - { - "examine": "Place on the stone mechanism in the right order to open the door.", - "durability": null, - "name": "Stone ball", - "archery_ticket_price": "0", - "id": "3110" - }, - { - "examine": "Place on the stone mechanism in the right order to open the door.", - "durability": null, - "name": "Stone ball", - "archery_ticket_price": "0", - "id": "3111" - }, - { - "examine": "Place on the stone mechanism in the right order to open the door.", - "durability": null, - "name": "Stone ball", - "archery_ticket_price": "0", - "id": "3112" - }, - { - "examine": "Place on the stone mechanism in the right order to open the door.", - "durability": null, - "name": "Stone ball", - "archery_ticket_price": "0", - "id": "3113" - }, - { - "examine": "Entrance certificate to the Imperial Guard.", - "durability": null, - "name": "Certificate", - "archery_ticket_price": "0", - "id": "3114" - }, - { - "durability": null, - "name": "Bronze claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3115" - }, - { - "durability": null, - "name": "Iron claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3116" - }, - { - "durability": null, - "name": "Steel claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3117" - }, - { - "durability": null, "name": "Black claws", - "tradeable": "true", + "examine": "A set of fighting claws.", "archery_ticket_price": "0", - "id": "3118" + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "10,14,-4,0,0,4,7,2,0,0,0,14,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2583", + "requirements": "{0,10}", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "9", + "weight": "6" }, { - "durability": null, + "id": "3099", "name": "Mithril claws", - "tradeable": "true", + "examine": "A set of fighting claws.", "archery_ticket_price": "0", - "id": "3119" - }, - { + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "11,16,-4,0,0,4,8,2,0,0,0,17,0,0,0", + "defence_anim": "397", "durability": null, - "name": "Adamant claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3120" - }, - { - "durability": null, - "name": "Rune claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3121" - }, - { - "requirements": "{1,50}-{2,50}", - "ge_buy_limit": "10", - "examine": "A solid stone shield.", - "durability": null, - "weight": "6.8", - "absorb": "5,0,10", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "34800", - "name": "Granite shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3122", - "bonuses": "0,0,0,-12,-8,40,42,38,0,65,50,0,0,0,0" - }, - { - "ge_buy_limit": "10000", - "examine": "Large glistening bones which glow with a pale yellow aura.", - "grand_exchange_price": "1975", - "durability": null, - "name": "Shaikahan bones", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "3123" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1975", - "durability": null, - "name": "Shaikahan bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3124" - }, - { - "ge_buy_limit": "10000", - "examine": "Fairly big bones which smell distinctly of Jogre.", - "grand_exchange_price": "1023", - "durability": null, - "name": "Jogre bones", - "tradeable": "true", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3125" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1023", - "durability": null, - "name": "Jogre bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3126" - }, - { - "examine": "These blackened Jogre bones have been somehow burnt.", - "durability": null, - "name": "Burnt jogre bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3127" - }, - { - "examine": "Burnt Jogre bones smothered with raw Karambwanji Paste.", - "durability": null, - "name": "Pasty jogre bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3128" - }, - { - "examine": "Burnt Jogre bones smothered with cooked Karambwanji paste.", - "durability": null, - "name": "Pasty jogre bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3129" - }, - { - "examine": "Burnt Jogre bones marinated in a lovely Karambwanji sauce. Perfect.", - "durability": null, - "name": "Marinated j' bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3130" - }, - { - "examine": "Jogre bones smothered with raw Karambwanji paste.", - "durability": null, - "name": "Pasty jogre bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3131" - }, - { - "examine": "Jogre bones smothered with cooked Karambwanji paste.", - "durability": null, - "name": "Pasty jogre bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3132" - }, - { - "examine": "Jogre Bones marinated in Karambwanji sauce. Not quite right.", - "durability": null, - "name": "Marinated j' bones", - "tradeable": "false", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "3133" - }, - { - "durability": null, - "name": "Granite shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3134" - }, - { - "shop_price": "1", - "examine": "The key to the troll prison.", - "durability": null, - "name": "Cell key 1", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3136" - }, - { - "examine": "The key to the troll prison.", - "durability": null, - "name": "Cell key 2", - "weight": "1", - "archery_ticket_price": "0", - "id": "3137" - }, - { - "ge_buy_limit": "10000", - "examine": "How am I supposed to eat that?!", - "grand_exchange_price": "1834", - "durability": null, - "name": "Potato cactus", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "3138" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1834", - "durability": null, - "name": "Potato cactus", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3139" - }, - { - "requirements": "{1,60}", - "ge_buy_limit": "10", - "examine": "A series of connected metal rings.", - "rare_item": "true", - "durability": null, - "weight": "6.8", - "absorb": "4,0,9", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "4300000", - "name": "Dragon chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3140", - "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "4300000", - "durability": null, - "name": "Dragon chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3141" - }, - { - "shop_price": "440", - "ge_buy_limit": "20000", - "examine": "A raw green octopus.", - "grand_exchange_price": "1775", - "durability": null, - "name": "Raw karambwan", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "3142" - }, - { - "ge_buy_limit": "20000", - "grand_exchange_price": "1775", - "durability": null, - "name": "Raw karambwan", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3143" - }, - { - "shop_price": "460", - "ge_buy_limit": "10000", - "examine": "Cooked octopus.", - "grand_exchange_price": "1455", - "durability": null, - "name": "Cooked karambwan", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "3144" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1455", - "durability": null, - "name": "Cooked karambwan", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3145" - }, - { - "examine": "Cooked octopus. It looks poorly cooked and quite dangerous.", - "durability": null, - "name": "Poison karambwan", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "3146" - }, - { - "shop_price": "460", - "examine": "Cooked octopus.", - "grand_exchange_price": "906", - "durability": null, - "name": "Cooked karambwan", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "3147" - }, - { - "durability": null, - "name": "Burnt karambwan", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3149" - }, - { - "examine": "Small brightly coloured tropical fish.", - "durability": null, - "name": "Raw karambwanji", - "archery_ticket_price": "0", - "id": "3150" - }, - { - "examine": "Small brightly coloured tropical fish.", - "durability": null, - "name": "Karambwanji", - "weight": "0.99", - "archery_ticket_price": "0", - "id": "3151" - }, - { - "examine": "Freshly made octopus paste. It smells quite nauseating.", - "durability": null, - "name": "Karambwan paste", - "archery_ticket_price": "0", - "id": "3152" - }, - { - "examine": "Freshly made octopus paste. It smells quite nauseating.", - "durability": null, - "name": "Karambwan paste", - "archery_ticket_price": "0", - "id": "3153" - }, - { - "examine": "Freshly made octopus paste. It smells quite nauseating.", - "durability": null, - "name": "Karambwan paste", - "archery_ticket_price": "0", - "id": "3154" - }, - { - "examine": "This paste smells of raw fish./This paste smells of cooked fish.", - "durability": null, - "name": "Karambwanji paste", - "archery_ticket_price": "0", - "id": "3155" - }, - { - "examine": "This paste smells of raw fish./This paste smells of cooked fish.", - "durability": null, - "name": "Karambwanji paste", - "archery_ticket_price": "0", - "id": "3156" - }, - { - "requirements": "{10,65}", - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A wide bodied and thin necked vessel, encrusted with sea salt. / The Karambwan Vessel is loaded with Karambwanji", - "grand_exchange_price": "221", - "durability": null, - "name": "Karambwan vessel", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "3157", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "221", - "durability": null, - "name": "Karambwan vessel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3158" - }, - { - "requirements": "{10,65}", - "shop_price": "5", - "examine": "A wide bodied and thin necked vessel, encrusted with sea salt. / The Karambwan Vessel is loaded with Karambwanji", - "grand_exchange_price": "240", - "durability": null, - "name": "Karambwan vessel", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "3159" - }, - { - "durability": null, - "name": "Karambwan vessel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3160" - }, - { - "examine": "A set of instructions explaining how to construct a Karambwan vessel", - "durability": null, - "name": "Crafting manual", - "archery_ticket_price": "0", - "id": "3161" - }, - { - "ge_buy_limit": "100", - "examine": "You swear you had more than three slices before.", - "grand_exchange_price": "38", - "durability": null, - "name": "Sliced banana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3162" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "38", - "durability": null, - "name": "Sliced banana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3163" - }, - { - "shop_price": "27", - "examine": "A very strong spirit brewed in Karamja.", - "durability": null, - "name": "Karamjan rum", - "archery_ticket_price": "0", - "id": "3164" - }, - { - "shop_price": "27", - "examine": "A very strong spirit brewed in Karamja.", - "durability": null, - "name": "Karamjan rum", - "archery_ticket_price": "0", - "id": "3165" - }, - { - "examine": "It's the body of a dead monkey.", - "durability": null, - "name": "Monkey corpse", - "weight": "1", - "archery_ticket_price": "0", - "id": "3166" - }, - { - "examine": "It's the skin of a (hopefully) dead monkey.", - "durability": null, - "name": "Monkey skin", - "archery_ticket_price": "0", - "id": "3167" - }, - { - "examine": "A 'Seaweed in Monkey Skin' sandwich. Perfect for statue repair.", - "durability": null, - "name": "Seaweed sandwich", - "archery_ticket_price": "0", - "id": "3168" - }, - { - "examine": "A body of a dead monkey, tastefully stuffed with seaweed.", - "durability": null, - "name": "Stuffed monkey", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3169" - }, - { - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned bronze tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", + "equip_audio": "1003", "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "266", - "stand_anim": "813", - "name": "Bronze spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3170", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned iron tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "304", - "stand_anim": "813", - "name": "Iron spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3171", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" - }, - { - "requirements": "{0,5}", - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned steel tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "503", - "stand_anim": "813", - "name": "Steel spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3172", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" - }, - { + "ge_buy_limit": "100", + "render_anim": "2583", "requirements": "{0,20}", - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned mithril tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", + "tradeable": "true", "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "368", - "stand_anim": "813", - "name": "Mithril spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3173", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0" + "weapon_interface": "9", + "weight": "0.9" }, { + "id": "3100", + "name": "Adamant claws", + "examine": "A set of fighting claws.", + "archery_ticket_price": "0", + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "18,23,-4,0,0,6,12,3,0,0,0,24,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2583", "requirements": "{0,30}", - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned adamant tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", + "tradeable": "true", "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "1093", - "stand_anim": "813", - "name": "Adamant spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3174", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0" + "weapon_interface": "9" }, { - "requirements": "{0,40}", - "turn90cw_anim": "1207", - "examine": "\tA Karambwan poisoned rune tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "12089", - "stand_anim": "813", - "name": "Rune spear(kp)", - "run_anim": "1210", + "id": "3101", + "name": "Rune claws", + "examine": "A set of fighting claws.", "archery_ticket_price": "0", - "id": "3175", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" - }, - { - "requirements": "{0,60}", - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned dragon tipped spear.", - "walk_anim": "1205", + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "26,38,-4,0,0,10,19,5,0,0,0,39,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", "has_special": "true", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", + "lendable": "true", + "render_anim": "2583", + "requirements": "{0,40}", + "tradeable": "true", "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "37446", - "stand_anim": "813", - "name": "Dragon spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3176", - "stand_turn_anim": "1209", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + "weapon_interface": "9", + "weight": "0.9" }, { + "id": "3102", + "name": "Combination", + "examine": "The combination to Burthorpe Castle's equipment room.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3103", + "name": "Iou", + "examine": "The guard wrote the IOU on the back of some paper.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3104", + "name": "Secret way map", + "examine": "This map shows the secret way up to Death Plateau.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3105", + "name": "Climbing boots", + "examine": "Boots made for general climbing; rocks a speciality.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,2,0,0,0", + "destroy": "true", "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "1900", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "3106", + "name": "Climbing boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3107", + "name": "Spiked boots", + "examine": "Climbing boots with spikes.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,2,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "weight": "0.3" + }, + { + "id": "3109", + "name": "Stone ball", + "examine": "Place on the stone mechanism in the right order to open the door.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3110", + "name": "Stone ball", + "examine": "Place on the stone mechanism in the right order to open the door.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3111", + "name": "Stone ball", + "examine": "Place on the stone mechanism in the right order to open the door.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3112", + "name": "Stone ball", + "examine": "Place on the stone mechanism in the right order to open the door.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3113", + "name": "Stone ball", + "examine": "Place on the stone mechanism in the right order to open the door.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3114", + "name": "Certificate", + "examine": "Entrance certificate to the Imperial Guard.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3115", + "name": "Bronze claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3116", + "name": "Iron claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3117", + "name": "Steel claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3118", + "name": "Black claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3119", + "name": "Mithril claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3120", + "name": "Adamant claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3121", + "name": "Rune claws", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3122", + "name": "Granite shield", + "examine": "A solid stone shield.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-12,-8,40,42,38,0,65,50,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", + "lendable": "true", + "requirements": "{1,50}-{2,50}", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "3123", + "name": "Shaikahan bones", + "examine": "Large glistening bones which glow with a pale yellow aura.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.5" + }, + { + "id": "3124", + "name": "Shaikahan bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3125", + "name": "Jogre bones", + "examine": "Fairly big bones which smell distinctly of Jogre.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "3126", + "name": "Jogre bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3127", + "name": "Burnt jogre bones", + "examine": "These blackened Jogre bones have been somehow burnt.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3128", + "name": "Pasty jogre bones", + "examine": "Burnt Jogre bones smothered with raw Karambwanji Paste.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3129", + "name": "Pasty jogre bones", + "examine": "Burnt Jogre bones smothered with cooked Karambwanji paste.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3130", + "name": "Marinated j' bones", + "examine": "Burnt Jogre bones marinated in a lovely Karambwanji sauce. Perfect.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3131", + "name": "Pasty jogre bones", + "examine": "Jogre bones smothered with raw Karambwanji paste.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3132", + "name": "Pasty jogre bones", + "examine": "Jogre bones smothered with cooked Karambwanji paste.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3133", + "name": "Marinated j' bones", + "examine": "Jogre Bones marinated in Karambwanji sauce. Not quite right.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false", + "weight": "0.8" + }, + { + "id": "3134", + "name": "Granite shield", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3136", + "name": "Cell key 1", + "examine": "The key to the troll prison.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "shop_price": "1", + "tradeable": "false" + }, + { + "id": "3137", + "name": "Cell key 2", + "examine": "The key to the troll prison.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "3138", + "name": "Potato cactus", + "examine": "How am I supposed to eat that?!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "3139", + "name": "Potato cactus", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3140", + "name": "Dragon chainbody", + "examine": "A series of connected metal rings.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "remove_sleeves": "true", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "3141", + "name": "Dragon chainbody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "3142", + "name": "Raw karambwan", + "examine": "A raw green octopus.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "shop_price": "440", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "3143", + "name": "Raw karambwan", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "3144", + "name": "Cooked karambwan", + "examine": "Cooked octopus.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "460", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "3145", + "name": "Cooked karambwan", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3146", + "name": "Poison karambwan", + "examine": "Cooked octopus. It looks poorly cooked and quite dangerous.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "3147", + "name": "Cooked karambwan", + "examine": "Cooked octopus.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "460", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "3149", + "name": "Burnt karambwan", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3150", + "name": "Raw karambwanji", + "examine": "Small brightly coloured tropical fish.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3151", + "name": "Karambwanji", + "examine": "Small brightly coloured tropical fish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.99" + }, + { + "id": "3152", + "name": "Karambwan paste", + "examine": "Freshly made octopus paste. It smells quite nauseating.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3153", + "name": "Karambwan paste", + "examine": "Freshly made octopus paste. It smells quite nauseating.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3154", + "name": "Karambwan paste", + "examine": "Freshly made octopus paste. It smells quite nauseating.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3155", + "name": "Karambwanji paste", + "examine": "This paste smells of raw fish./This paste smells of cooked fish.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3156", + "name": "Karambwanji paste", + "examine": "This paste smells of raw fish./This paste smells of cooked fish.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3157", + "name": "Karambwan vessel", + "examine": "A wide bodied and thin necked vessel, encrusted with sea salt. / The Karambwan Vessel is loaded with Karambwanji", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{10,65}", + "shop_price": "5", + "tradeable": "true", + "weight": "3" + }, + { + "id": "3158", + "name": "Karambwan vessel", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3159", + "name": "Karambwan vessel", + "examine": "A wide bodied and thin necked vessel, encrusted with sea salt. / The Karambwan Vessel is loaded with Karambwanji", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{10,65}", + "shop_price": "5", + "tradeable": "true", + "weight": "3" + }, + { + "id": "3160", + "name": "Karambwan vessel", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3161", + "name": "Crafting manual", + "examine": "A set of instructions explaining how to construct a Karambwan vessel", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3162", + "name": "Sliced banana", + "examine": "You swear you had more than three slices before.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3163", + "name": "Sliced banana", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3164", + "name": "Karamjan rum", + "examine": "A very strong spirit brewed in Karamja.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "27" + }, + { + "id": "3165", + "name": "Karamjan rum", + "examine": "A very strong spirit brewed in Karamja.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "27" + }, + { + "id": "3166", + "name": "Monkey corpse", + "examine": "It's the body of a dead monkey.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "3167", + "name": "Monkey skin", + "examine": "It's the skin of a (hopefully) dead monkey.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3168", + "name": "Seaweed sandwich", + "examine": "A 'Seaweed in Monkey Skin' sandwich. Perfect for statue repair.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3169", + "name": "Stuffed monkey", + "examine": "A body of a dead monkey, tastefully stuffed with seaweed.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "3170", + "name": "Bronze spear(kp)", + "examine": "A Karambwan poisoned bronze tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "3171", + "name": "Iron spear(kp)", + "examine": "A Karambwan poisoned iron tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "3172", + "name": "Steel spear(kp)", + "examine": "A Karambwan poisoned steel tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "3173", + "name": "Mithril spear(kp)", + "examine": "A Karambwan poisoned mithril tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "3174", + "name": "Adamant spear(kp)", + "examine": "A Karambwan poisoned adamant tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "3175", + "name": "Rune spear(kp)", + "examine": "\tA Karambwan poisoned rune tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "3176", + "name": "Dragon spear(kp)", + "examine": "A Karambwan poisoned dragon tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "requirements": "{0,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "3177", "name": "Picture", "archery_ticket_price": "0", - "id": "3177", + "durability": null, "equipment_slot": "5" }, { - "durability": null, + "id": "3178", "name": "Picture", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3178" + "durability": null, + "tradeable": "true" }, { + "id": "3179", + "name": "Monkey bones", "examine": "These are smallish monkey bones.", - "grand_exchange_price": "383", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3179" + "durability": null, + "tradeable": "true", + "weight": "0.5" }, { + "id": "3180", + "name": "Monkey bones", "examine": "These are medium sized monkey bones.", - "grand_exchange_price": "383", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3180" + "durability": null, + "tradeable": "true", + "weight": "0.5" }, { + "id": "3181", + "name": "Monkey bones", "examine": "These are quite large monkey bones.", - "grand_exchange_price": "383", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3181" + "durability": null, + "tradeable": "true", + "weight": "0.5" }, { + "id": "3182", + "name": "Monkey bones", "examine": "These are quite large monkey bones.", - "grand_exchange_price": "383", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3182" + "durability": null, + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "10000", + "id": "3183", + "name": "Monkey bones", "examine": "These are small monkey bones.", - "grand_exchange_price": "588", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3183" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "588", - "durability": null, - "name": "Monkey bones", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3184" + "weight": "0.5" }, { + "id": "3184", + "name": "Monkey bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3185", + "name": "Monkey bones", "examine": "These are smallish monkey bones. They smell extremely nauseating.", - "grand_exchange_price": "383", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3185" + "durability": null, + "tradeable": "true", + "weight": "0.5" }, { + "id": "3186", + "name": "Monkey bones", "examine": "These are small monkey bones. They smell extremely nauseating.", - "grand_exchange_price": "383", - "durability": null, - "name": "Monkey bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3186" + "durability": null, + "tradeable": "true", + "weight": "0.5" }, { - "shop_price": "140", - "grand_exchange_price": "140", - "durability": null, + "id": "3187", "name": "Bones", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "3187" + "durability": null, + "shop_price": "140", + "tradeable": "true", + "weight": "0.5" }, { - "shop_price": "60", - "ge_buy_limit": "100", + "id": "3188", + "name": "Cleaning cloth", "examine": "A piece of silk which can be used to remove poison from weapons.", - "grand_exchange_price": "286", - "durability": null, - "name": "Cleaning cloth", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "3188" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "60", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "286", - "durability": null, + "id": "3189", "name": "Cleaning cloth", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3189" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "522", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "3190", - "stand_turn_anim": "1209", - "bonuses": "7,8,0,-4,0,-1,1,2,0,0,0,8,0,0,0", - "shop_price": "104", - "durability": null, - "weight": "3", - "weapon_interface": "15", - "render_anim": "28", - "name": "Bronze halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "522", - "durability": null, "name": "Bronze halberd", - "tradeable": "true", + "examine": "A bronze halberd.", "archery_ticket_price": "0", - "id": "3191" + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "7,8,0,-4,0,-1,1,2,0,0,0,8,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "104", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "124", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "3191", + "name": "Bronze halberd", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3192", - "stand_turn_anim": "1209", - "bonuses": "9,12,0,-4,0,-1,1,2,0,0,0,12,0,0,0", - "shop_price": "364", - "durability": null, - "weight": "3.1", - "weapon_interface": "15", - "render_anim": "28", - "name": "Iron halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "124", - "durability": null, "name": "Iron halberd", - "tradeable": "true", + "examine": "An iron halberd.", "archery_ticket_price": "0", - "id": "3193" + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "9,12,0,-4,0,-1,1,2,0,0,0,12,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "364", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3.1" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "726", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "3193", + "name": "Iron halberd", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3194", - "stand_turn_anim": "1209", - "bonuses": "14,19,0,-4,0,-1,2,3,0,0,0,20,0,0,0", - "requirements": "{0,5}", - "shop_price": "1300", - "durability": null, - "weight": "3", - "weapon_interface": "15", - "render_anim": "28", - "name": "Steel halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "726", - "durability": null, "name": "Steel halberd", - "tradeable": "true", + "examine": "A steel halberd.", "archery_ticket_price": "0", - "id": "3195" + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "14,19,0,-4,0,-1,2,3,0,0,0,20,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "shop_price": "1300", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A black halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "4344", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "3195", + "name": "Steel halberd", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3196", - "stand_turn_anim": "1209", - "bonuses": "19,25,0,-4,0,-1,2,3,0,0,0,20,0,0,0", - "requirements": "{0,5}-{2,10}", - "shop_price": "2496", - "durability": null, - "weight": "3", - "weapon_interface": "15", - "render_anim": "28", - "name": "Black halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4344", - "durability": null, "name": "Black halberd", - "tradeable": "true", + "examine": "A black halberd.", "archery_ticket_price": "0", - "id": "3197" + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "19,25,0,-4,0,-1,2,3,0,0,0,20,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}-{2,5}", + "run_anim": "1210", + "shop_price": "2496", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "6995", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "3197", + "name": "Black halberd", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3198", - "stand_turn_anim": "1209", - "bonuses": "22,28,0,-4,0,-1,2,4,0,0,0,29,0,0,0", - "requirements": "{0,20}-{2,10}", - "shop_price": "3380", - "durability": null, - "weight": "2.7", - "weapon_interface": "15", - "render_anim": "28", - "name": "Mithril halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6995", - "durability": null, "name": "Mithril halberd", - "tradeable": "true", + "examine": "A mithril halberd.", "archery_ticket_price": "0", - "id": "3199" + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "22,28,0,-4,0,-1,2,4,0,0,0,29,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}-{2,10}", + "run_anim": "1210", + "shop_price": "3380", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "2.7" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "4690", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "3199", + "name": "Mithril halberd", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3200", - "stand_turn_anim": "1209", - "bonuses": "28,41,0,-4,0,-1,3,4,0,0,0,42,0,0,0", - "requirements": "{0,30}-{2,15}", - "shop_price": "8320", - "durability": null, - "weight": "3.6", - "weapon_interface": "15", - "render_anim": "28", - "name": "Adamant halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4690", - "durability": null, "name": "Adamant halberd", - "tradeable": "true", + "examine": "An adamant halberd.", "archery_ticket_price": "0", - "id": "3201" + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "28,41,0,-4,0,-1,3,4,0,0,0,42,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}-{2,15}", + "run_anim": "1210", + "shop_price": "8320", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3.6" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "77100", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "3201", + "name": "Adamant halberd", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3202", - "stand_turn_anim": "1209", - "bonuses": "48,67,0,-4,0,-1,4,5,0,0,0,68,0,0,0", - "requirements": "{0,40}-{2,20}", - "shop_price": "128000", - "durability": null, - "weight": "3", - "weapon_interface": "15", - "render_anim": "28", - "lendable": "true", - "name": "Rune halberd" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "77100", - "durability": null, "name": "Rune halberd", - "tradeable": "true", + "examine": "A rune halberd.", "archery_ticket_price": "0", - "id": "3203" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "A dragon halberd.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", - "equipment_slot": "3", "attack_anims": "440,440,412,440", - "grand_exchange_price": "201000", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "3204", - "stand_turn_anim": "1209", - "bonuses": "70,95,0,-4,0,-1,4,5,0,0,0,89,0,0,0", - "requirements": "{0,60}-{2,30}", - "shop_price": "325000", + "attack_speed": "7", + "bonuses": "48,67,0,-4,0,-1,4,5,0,0,0,68,0,0,0", + "defence_anim": "430", "durability": null, - "weight": "3.1", - "weapon_interface": "15", - "render_anim": "28", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", "lendable": "true", - "name": "Dragon halberd" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "201000", - "durability": null, - "name": "Dragon halberd", + "render_anim": "28", + "requirements": "{0,40}-{2,20}", + "run_anim": "1210", + "shop_price": "128000", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3205" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3" }, { - "examine": "A summons from King Lathas.", + "id": "3203", + "name": "Rune halberd", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3204", + "name": "Dragon halberd", + "examine": "A dragon halberd.", + "archery_ticket_price": "0", + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "70,95,0,-4,0,-1,4,5,0,0,0,89,0,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,60}-{2,30}", + "run_anim": "1210", + "shop_price": "325000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3.1" + }, + { + "id": "3205", + "name": "Dragon halberd", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "3206", "name": "King's message", + "examine": "A summons from King Lathas.", "archery_ticket_price": "0", - "id": "3206" + "durability": null }, { - "examine": "A letter for King Lathas from Lord Iorwerth.", - "durability": null, + "id": "3207", "name": "Iorwerths message", + "examine": "A letter for King Lathas from Lord Iorwerth.", "archery_ticket_price": "0", - "id": "3207" + "durability": null }, { - "examine": "Lord Iorwerth's crystal pendant.", - "durability": null, - "name": "Crystal pendant", - "archery_ticket_price": "0", "id": "3208", + "name": "Crystal pendant", + "examine": "Lord Iorwerth's crystal pendant.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "examine": "A piece of chemical formation.", - "durability": null, + "id": "3209", "name": "Sulphur", - "weight": "0.6", + "examine": "A piece of chemical formation.", "archery_ticket_price": "0", - "id": "3209" + "durability": null, + "weight": "0.6" }, { - "shop_price": "4", - "ge_buy_limit": "10000", + "id": "3211", + "name": "Limestone", "examine": "Some limestone.", - "grand_exchange_price": "238", - "durability": null, - "name": "Limestone", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "3211" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "238", - "durability": null, + "shop_price": "4", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "3212", "name": "Limestone", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3212" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "examine": "Some quicklime.", - "durability": null, + "id": "3213", "name": "Quicklime", - "weight": "2.2", + "examine": "Some quicklime.", "archery_ticket_price": "0", - "id": "3213" + "durability": null, + "weight": "2.2" }, { - "examine": "A pot of ground quicklime.", - "durability": null, + "id": "3214", "name": "Pot of quicklime", + "examine": "A pot of ground quicklime.", "archery_ticket_price": "0", - "id": "3214" + "durability": null }, { - "shop_price": "160", - "examine": "A pile of ground sulphur.", - "durability": null, + "id": "3215", "name": "Ground sulphur", - "weight": "0.5", + "examine": "A pile of ground sulphur.", "archery_ticket_price": "0", - "id": "3215" + "durability": null, + "shop_price": "160", + "weight": "0.5" }, { - "ge_buy_limit": "100", + "id": "3216", + "name": "Barrel", "examine": "An empty barrel/A Splendid barrel.", - "grand_exchange_price": "207", - "durability": null, - "name": "Barrel", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "3216" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "207", - "durability": null, - "name": "Barrel", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3217" + "weight": "10" }, { - "examine": "A fused barrel full of fire oil.", + "id": "3217", + "name": "Barrel", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3218", "name": "Barrel bomb", - "weight": "32", - "archery_ticket_price": "0", - "id": "3218" - }, - { "examine": "A fused barrel full of fire oil.", - "durability": null, - "name": "Barrel bomb", - "weight": "32", "archery_ticket_price": "0", - "id": "3219" + "durability": null, + "weight": "32" }, { - "examine": "A barrel full of coal-tar.", + "id": "3219", + "name": "Barrel bomb", + "examine": "A fused barrel full of fire oil.", + "archery_ticket_price": "0", "durability": null, + "weight": "32" + }, + { + "id": "3220", "name": "Barrel of coal-tar", - "weight": "32", + "examine": "A barrel full of coal-tar.", "archery_ticket_price": "0", - "id": "3220" + "durability": null, + "weight": "32" }, { - "examine": "A barrel full of naphtha.", - "durability": null, + "id": "3221", "name": "Barrel of naphtha", - "weight": "32", + "examine": "A barrel full of naphtha.", "archery_ticket_price": "0", - "id": "3221" + "durability": null, + "weight": "32" }, { - "examine": "A barrel full of naphtha and sulphur./A barrel full of naphtha and quicklime.", - "durability": null, + "id": "3222", "name": "Naphtha mix", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3222" - }, - { "examine": "A barrel full of naphtha and sulphur./A barrel full of naphtha and quicklime.", - "durability": null, - "name": "Naphtha mix", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "3223" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A strip of cloth.", + "id": "3223", + "name": "Naphtha mix", + "examine": "A barrel full of naphtha and sulphur./A barrel full of naphtha and quicklime.", + "archery_ticket_price": "0", + "destroy": "true", "durability": null, + "tradeable": "false" + }, + { + "id": "3224", "name": "Strip of cloth", + "examine": "A strip of cloth.", "archery_ticket_price": "0", - "id": "3224" + "durability": null }, { - "shop_price": "67", - "ge_buy_limit": "5000", + "id": "3226", + "name": "Raw rabbit", "examine": "Might taste better cooked.", - "grand_exchange_price": "312", - "durability": null, - "name": "Raw rabbit", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "3226" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "312", - "durability": null, + "shop_price": "67", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "3227", "name": "Raw rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3227" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "19", - "ge_buy_limit": "1000", + "id": "3228", + "name": "Cooked rabbit", "examine": "Mmm this looks tasty.", - "grand_exchange_price": "35", - "durability": null, - "name": "Cooked rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3228" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "35", - "durability": null, + "shop_price": "19", + "tradeable": "true" + }, + { + "id": "3229", "name": "Cooked rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3229" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "examine": "A book by Mel Achy.", - "durability": null, + "id": "3230", "name": "Big book of bangs", - "weight": "0.2", + "examine": "A book by Mel Achy.", "archery_ticket_price": "0", - "id": "3230" - }, - { "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3232" + "weight": "0.2" }, { + "id": "3232", + "name": "Picture", + "archery_ticket_price": "0", "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3234" + "tradeable": "true" }, { + "id": "3234", + "name": "Picture", + "archery_ticket_price": "0", "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3236" + "tradeable": "true" }, { + "id": "3236", + "name": "Picture", + "archery_ticket_price": "0", "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3238" + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "3238", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3239", + "name": "Bark", "examine": "Bark from a hollow tree.", - "grand_exchange_price": "23", - "durability": null, - "name": "Bark", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "3239" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "23", - "durability": null, - "name": "Bark", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3240" + "weight": "1" }, { - "examine": "One of 2009Scape's many citizens.", + "id": "3240", + "name": "Bark", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3241", "name": "Man", + "examine": "One of 2009Scape's many citizens.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "3241" + "durability": null }, { - "examine": "He grows crops in the area.", - "durability": null, + "id": "3243", "name": "Farmer", + "examine": "He grows crops in the area.", "archery_ticket_price": "0", - "id": "3243" + "durability": null }, { - "examine": "Rogueish.", - "durability": null, + "id": "3247", "name": "Rogue", + "examine": "Rogueish.", "archery_ticket_price": "0", - "id": "3247" + "durability": null }, { - "examine": "Varies, refer below.", - "durability": null, + "id": "3249", "name": "Guard", + "examine": "Varies, refer below.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "3249" + "durability": null }, { - "examine": "A member of Ardougne's militia.", - "durability": null, + "id": "3251", "name": "Knight of ardougne", + "examine": "A member of Ardougne's militia.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "3251" + "durability": null }, { - "examine": "The strong arm of the law.", - "durability": null, + "id": "3253", "name": "Watchman", + "examine": "The strong arm of the law.", "archery_ticket_price": "0", - "id": "3253" + "durability": null }, { - "examine": "A holy warrior.", - "durability": null, + "id": "3255", "name": "Paladin", + "examine": "A holy warrior.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "3255" + "durability": null }, { - "examine": "Heroic!", - "durability": null, + "id": "3259", "name": "Hero", + "examine": "Heroic!", "archery_ticket_price": "0", "attack_speed": "5", - "id": "3259" + "durability": null }, { - "examine": "A pale, tough looking herb.", - "durability": null, + "id": "3261", "name": "Goutweed", + "examine": "A pale, tough looking herb.", "archery_ticket_price": "0", - "id": "3261" + "durability": null }, { - "examine": "It's tough and spiky.", - "durability": null, + "id": "3262", "name": "Troll thistle", + "examine": "It's tough and spiky.", "archery_ticket_price": "0", - "id": "3262" + "durability": null }, { - "examine": "It'll be easier to grind now.", - "durability": null, + "id": "3263", "name": "Dried thistle", - "tradeable": "false", - "destroy": "true", + "examine": "It'll be easier to grind now.", "archery_ticket_price": "0", - "id": "3263" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "It's ready for mixing.", - "durability": null, + "id": "3264", "name": "Ground thistle", - "tradeable": "false", - "destroy": "true", + "examine": "It's ready for mixing.", "archery_ticket_price": "0", - "id": "3264" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "It's part of Eadgar's plan.", - "durability": null, + "id": "3265", "name": "Troll potion", - "tradeable": "false", - "destroy": "true", + "examine": "It's part of Eadgar's plan.", "archery_ticket_price": "0", - "id": "3265" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "It's rather drunk.", - "durability": null, + "id": "3266", "name": "Drunk parrot", + "examine": "It's rather drunk.", "archery_ticket_price": "0", - "id": "3266" + "durability": null }, { - "examine": "It's dirty and smelly.", - "durability": null, + "id": "3267", "name": "Dirty robe", + "examine": "It's dirty and smelly.", "archery_ticket_price": "0", - "id": "3267" + "durability": null }, { - "examine": "It's good enough to fool a troll.", - "durability": null, + "id": "3268", "name": "Fake man", + "examine": "It's good enough to fool a troll.", "archery_ticket_price": "0", - "id": "3268" + "durability": null }, { - "examine": "The key to the Trollheim storeroom.", - "durability": null, + "id": "3269", "name": "Storeroom key", - "tradeable": "false", + "examine": "The key to the Trollheim storeroom.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "3269" + "durability": null, + "tradeable": "false" }, { - "examine": "Pineapple chunks dipped in a strong liquor.", - "durability": null, + "id": "3270", "name": "Alco-chunks", + "examine": "Pineapple chunks dipped in a strong liquor.", "archery_ticket_price": "0", - "id": "3270" + "durability": null }, { - "ge_buy_limit": "5000", + "id": "3325", + "name": "Vampire dust", "examine": "That used to be a vampyre!", - "grand_exchange_price": "381", - "durability": null, - "name": "Vampire dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3325" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "381", - "durability": null, + "tradeable": "true" + }, + { + "id": "3326", "name": "Vampire dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3326" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "An easy-to-make, marshy-coloured, Mort Myre snail shell helmet.", - "grand_exchange_price": "56", - "durability": null, - "name": "Myre snelm", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "3327", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "56", - "durability": null, "name": "Myre snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3328" - }, - { - "remove_head": "true", - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "Rounded: A red and black snail shell helmet. Pointed: A red and black pointed snail shell helmet.", - "durability": null, - "weight": "2", - "equipment_slot": "0", - "grand_exchange_price": "291", - "name": "Blood'n'tar snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3329", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "291", - "durability": null, - "name": "Blood'n'tar snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3330" - }, - { - "remove_head": "true", - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell helmet.", - "grand_exchange_price": "57", - "durability": null, - "name": "Ochre snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3331", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "57", - "durability": null, - "name": "Ochre snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3332" - }, - { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "A moody blue snail shell helmet, mort myre snail shell helm", - "grand_exchange_price": "73", - "durability": null, - "name": "Bruise blue snelm", - "tradeable": "true", - "weight": "1.9", - "archery_ticket_price": "0", - "id": "3333", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "73", - "durability": null, - "name": "Bruise blue snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3334" - }, - { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "An easy-to-make, orange-and-bark coloured, Mort Myre snail shell helmet.", - "grand_exchange_price": "63", - "durability": null, - "name": "Broken bark snelm", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "3335", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "63", - "durability": null, - "name": "Broken bark snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3336" - }, - { - "remove_head": "true", - "ge_buy_limit": "100", "examine": "An easy-to-make, marshy-coloured, Mort Myre snail shell helmet.", - "grand_exchange_price": "58", - "durability": null, - "name": "Myre snelm", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "3337", "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "58", "durability": null, - "name": "Myre snelm", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3338" + "weight": "2" }, { - "remove_head": "true", - "shop_price": "300", + "id": "3328", + "name": "Myre snelm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3329", + "name": "Blood'n'tar snelm", "examine": "Rounded: A red and black snail shell helmet. Pointed: A red and black pointed snail shell helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", "durability": null, - "weight": "2", "equipment_slot": "0", - "grand_exchange_price": "147", - "name": "Blood'n'tar snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3339", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "147", - "durability": null, - "name": "Blood'n'tar snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3340" - }, - { "remove_head": "true", "shop_price": "300", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3330", + "name": "Blood'n'tar snelm", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3331", + "name": "Ochre snelm", "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell helmet.", - "grand_exchange_price": "54", - "durability": null, - "name": "Ochre snelm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3341", "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "54", "durability": null, - "name": "Ochre snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3342" - }, - { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "A moody blue snail shell helmet, mort myre snail shell helm", - "grand_exchange_price": "248", - "durability": null, - "name": "Bruise blue snelm", - "tradeable": "true", - "weight": "1.9", - "archery_ticket_price": "0", - "id": "3343", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "248", - "durability": null, - "name": "Bruise blue snelm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3344" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, 'myre'-coloured, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "155", - "durability": null, - "name": "Blamish myre shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3345" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "155", - "durability": null, - "name": "Blamish myre shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3346" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, red, Mort myre snail shell; looks protective.", - "grand_exchange_price": "590", - "durability": null, - "name": "Blamish red shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3347" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "590", - "durability": null, - "name": "Blamish red shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3348" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "134", - "durability": null, - "name": "Blamish ochre shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3349" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "134", - "durability": null, - "name": "Blamish ochre shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3350" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, blue, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "230", - "durability": null, - "name": "Blamish blue shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3351" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "230", - "durability": null, - "name": "Blamish blue shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3352" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, bark-coloured, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "195", - "durability": null, - "name": "Blamish bark shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3353" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "195", - "durability": null, - "name": "Blamish bark shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3354" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, 'myre'-coloured, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "145", - "durability": null, - "name": "Blamish myre shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3355" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "145", - "durability": null, - "name": "Blamish myre shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3356" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, red, Mort myre snail shell; looks protective.", - "grand_exchange_price": "614", - "durability": null, - "name": "Blamish red shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3357" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "614", - "durability": null, - "name": "Blamish red shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3358" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "173", - "durability": null, - "name": "Blamish ochre shell", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "3359" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "173", - "durability": null, - "name": "Blamish ochre shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3360" - }, - { - "ge_buy_limit": "100", - "examine": "An easy-to-make, blue, Mort Myre snail shell; looks protective.", - "grand_exchange_price": "874", - "durability": null, - "name": "Blamish blue shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3361" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "874", - "durability": null, - "name": "Blamish blue shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3362" - }, - { - "shop_price": "74", - "ge_buy_limit": "10000", - "examine": "The thin, slimy corpse of a deceased giant snail.", - "grand_exchange_price": "2047", - "durability": null, - "name": "Thin snail", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "3363" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2047", - "durability": null, - "name": "Thin snail", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3364" - }, - { - "ge_buy_limit": "1000", - "examine": "The lean, slimy corspe of a dead snail.", - "grand_exchange_price": "958", - "durability": null, - "name": "Lean snail", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "3365" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "958", - "durability": null, - "name": "Lean snail", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3366" - }, - { - "shop_price": "160", - "ge_buy_limit": "10000", - "examine": "The fat, slimy, corpse of a deceased giant snail.", - "grand_exchange_price": "971", - "durability": null, - "name": "Fat snail", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3367" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "971", - "durability": null, - "name": "Fat snail", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3368" - }, - { - "ge_buy_limit": "10000", - "examine": "A succulently slimy piece of sumptuous snail.", - "grand_exchange_price": "833", - "durability": null, - "name": "Thin snail meat", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "3369" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "833", - "durability": null, - "name": "Thin snail meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3370" - }, - { - "ge_buy_limit": "10000", - "examine": "A succulently slimey slice of sumptuous snail.", - "grand_exchange_price": "251", - "durability": null, - "name": "Lean snail meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3371" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "251", - "durability": null, - "name": "Lean snail meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3372" - }, - { - "ge_buy_limit": "10000", - "examine": "A succulently slimy slice of sumptuous snail.", - "grand_exchange_price": "603", - "durability": null, - "name": "Fat snail meat", - "tradeable": "true", - "weight": "4.5", - "archery_ticket_price": "0", - "id": "3373" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "603", - "durability": null, - "name": "Fat snail meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3374" - }, - { - "durability": null, - "name": "Burnt snail", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3376" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "An empty sample bottle.", - "grand_exchange_price": "14", - "durability": null, - "name": "Sample bottle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3377" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "14", - "durability": null, - "name": "Sample bottle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3378" - }, - { - "ge_buy_limit": "1000", - "examine": "A slime covered eel - yuck!", - "grand_exchange_price": "358", - "durability": null, - "name": "Slimy eel", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "3379" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "358", - "durability": null, - "name": "Slimy eel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3380" - }, - { - "ge_buy_limit": "1000", - "examine": "A cooked slimy eel - not delicious, but pretty nutritious.", - "grand_exchange_price": "274", - "durability": null, - "name": "Cooked slimy eel", - "tradeable": "true", - "destroy": "false", - "weight": "2", - "archery_ticket_price": "0", - "id": "3381" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "274", - "durability": null, - "name": "Cooked slimy eel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3382" - }, - { - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "A wooden helmet.", - "durability": null, - "weight": "0.9", - "absorb": "3,1,0", "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "5993", - "name": "Splitbark helm", - "tradeable": "true", + "ge_buy_limit": "100", + "remove_head": "true", + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "3332", + "name": "Ochre snelm", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3333", + "name": "Bruise blue snelm", + "examine": "A moody blue snail shell helmet, mort myre snail shell helm", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "1.9" + }, + { + "id": "3334", + "name": "Bruise blue snelm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3335", + "name": "Broken bark snelm", + "examine": "An easy-to-make, orange-and-bark coloured, Mort Myre snail shell helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3336", + "name": "Broken bark snelm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3337", + "name": "Myre snelm", + "examine": "An easy-to-make, marshy-coloured, Mort Myre snail shell helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3338", + "name": "Myre snelm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3339", + "name": "Blood'n'tar snelm", + "examine": "Rounded: A red and black snail shell helmet. Pointed: A red and black pointed snail shell helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3340", + "name": "Blood'n'tar snelm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3341", + "name": "Ochre snelm", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "3342", + "name": "Ochre snelm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3343", + "name": "Bruise blue snelm", + "examine": "A moody blue snail shell helmet, mort myre snail shell helm", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "1.9" + }, + { + "id": "3344", + "name": "Bruise blue snelm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3345", + "name": "Blamish myre shell", + "examine": "An easy-to-make, 'myre'-coloured, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3346", + "name": "Blamish myre shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3347", + "name": "Blamish red shell", + "examine": "An easy-to-make, red, Mort myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3348", + "name": "Blamish red shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3349", + "name": "Blamish ochre shell", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3350", + "name": "Blamish ochre shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3351", + "name": "Blamish blue shell", + "examine": "An easy-to-make, blue, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3352", + "name": "Blamish blue shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3353", + "name": "Blamish bark shell", + "examine": "An easy-to-make, bark-coloured, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3354", + "name": "Blamish bark shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3355", + "name": "Blamish myre shell", + "examine": "An easy-to-make, 'myre'-coloured, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3356", + "name": "Blamish myre shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3357", + "name": "Blamish red shell", + "examine": "An easy-to-make, red, Mort myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3358", + "name": "Blamish red shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3359", + "name": "Blamish ochre shell", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" + }, + { + "id": "3360", + "name": "Blamish ochre shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3361", + "name": "Blamish blue shell", + "examine": "An easy-to-make, blue, Mort Myre snail shell; looks protective.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3362", + "name": "Blamish blue shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3363", + "name": "Thin snail", + "examine": "The thin, slimy corpse of a deceased giant snail.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "74", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3364", + "name": "Thin snail", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3365", + "name": "Lean snail", + "examine": "The lean, slimy corspe of a dead snail.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3366", + "name": "Lean snail", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3367", + "name": "Fat snail", + "examine": "The fat, slimy, corpse of a deceased giant snail.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "160", + "tradeable": "true" + }, + { + "id": "3368", + "name": "Fat snail", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3369", + "name": "Thin snail meat", + "examine": "A succulently slimy piece of sumptuous snail.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3" + }, + { + "id": "3370", + "name": "Thin snail meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3371", + "name": "Lean snail meat", + "examine": "A succulently slimey slice of sumptuous snail.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3372", + "name": "Lean snail meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3373", + "name": "Fat snail meat", + "examine": "A succulently slimy slice of sumptuous snail.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "4.5" + }, + { + "id": "3374", + "name": "Fat snail meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3376", + "name": "Burnt snail", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3377", + "name": "Sample bottle", + "examine": "An empty sample bottle.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "3378", + "name": "Sample bottle", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3379", + "name": "Slimy eel", + "examine": "A slime covered eel - yuck!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3380", + "name": "Slimy eel", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3381", + "name": "Cooked slimy eel", + "examine": "A cooked slimy eel - not delicious, but pretty nutritious.", + "archery_ticket_price": "0", + "destroy": "false", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3382", + "name": "Cooked slimy eel", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { "id": "3385", - "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5993", - "durability": null, "name": "Splitbark helm", - "tradeable": "true", + "examine": "A wooden helmet.", + "absorb": "3,1,0", "archery_ticket_price": "0", - "id": "3386" + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}-{6,40}", + "tradeable": "true", + "weight": "0.9" }, { - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "Provides good protection.", + "id": "3386", + "name": "Splitbark helm", + "archery_ticket_price": "0", "durability": null, - "weight": "4.5", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3387", + "name": "Splitbark body", + "examine": "Provides good protection.", "absorb": "6,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,10,-10,36,26,42,15,0,40,0,0,0,0", + "durability": null, "equipment_slot": "4", + "ge_buy_limit": "100", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "26700", - "name": "Splitbark body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3387", - "bonuses": "0,0,0,10,-10,36,26,42,15,0,40,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "26700", - "durability": null, - "name": "Splitbark body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3388" - }, - { "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "These should protect my legs.", - "durability": null, - "weight": "3.6", - "absorb": "4,2,0", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "43700", - "name": "Splitbark legs", "tradeable": "true", + "weight": "4.5" + }, + { + "id": "3388", + "name": "Splitbark body", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3389", - "bonuses": "0,0,0,7,-7,22,20,25,10,0,15,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "43700", - "durability": null, "name": "Splitbark legs", - "tradeable": "true", + "examine": "These should protect my legs.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "3390" + "bonuses": "0,0,0,7,-7,22,20,25,10,0,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}-{6,40}", + "tradeable": "true", + "weight": "3.6" }, { - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "These should keep my hands safe.", - "durability": null, - "weight": "0.9", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "2786", - "name": "Splitbark gauntlets", - "tradeable": "true", + "id": "3390", + "name": "Splitbark legs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3391", - "bonuses": "0,0,0,2,-1,3,2,4,2,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2786", - "durability": null, "name": "Splitbark gauntlets", - "tradeable": "true", + "examine": "These should keep my hands safe.", "archery_ticket_price": "0", - "id": "3392" - }, - { + "bonuses": "0,0,0,2,-1,3,2,4,2,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "lendable": "true", "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "Wooden foot protection.", - "durability": null, - "weight": "0.9", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "3808", - "name": "Splitbark boots", "tradeable": "true", + "weight": "0.9" + }, + { + "id": "3392", + "name": "Splitbark gauntlets", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "3393", - "bonuses": "0,0,0,2,-1,3,2,4,2,0,9,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3808", - "durability": null, "name": "Splitbark boots", - "tradeable": "true", + "examine": "Wooden foot protection.", "archery_ticket_price": "0", - "id": "3394" - }, - { - "ge_buy_limit": "1000", - "examine": "The remains of a deadly shade.", - "grand_exchange_price": "18", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,9,0,0,0,0", "durability": null, - "name": "Loar remains", - "tradeable": "true", - "weight": "1.35", - "archery_ticket_price": "0", - "id": "3396" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "18", - "durability": null, - "name": "Loar remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3397" - }, - { - "ge_buy_limit": "1000", - "examine": "The remains of a deadly shade.", - "grand_exchange_price": "249", - "durability": null, - "name": "Phrin remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3398" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "249", - "durability": null, - "name": "Phrin remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3399" - }, - { - "ge_buy_limit": "1000", - "examine": "The remains of a deadly shade.", - "grand_exchange_price": "138", - "durability": null, - "name": "Riyl remains", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3400" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "138", - "durability": null, - "name": "Riyl remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3401" - }, - { - "ge_buy_limit": "1000", - "examine": "The remains of a deadly shade.", - "grand_exchange_price": "334", - "durability": null, - "name": "Asyn remains", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3402" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "334", - "durability": null, - "name": "Asyn remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3403" - }, - { - "ge_buy_limit": "1000", - "examine": "The remains of a deadly shade.", - "grand_exchange_price": "5264", - "durability": null, - "name": "Fiyr remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3404" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "5264", - "durability": null, - "name": "Fiyr remains", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3405" - }, - { + "equip_audio": "2237", + "equipment_slot": "10", "ge_buy_limit": "100", - "examine": "I need another ingredient to finish this potion.", - "grand_exchange_price": "137", - "durability": null, - "name": "Ash potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3406" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "137", - "durability": null, - "name": "Ash potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3407" - }, - { - "examine": "4 doses serum 207 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 207 (4)", - "archery_ticket_price": "0", - "id": "3408" - }, - { - "examine": "3 doses serum 207 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 207 (3)", - "archery_ticket_price": "0", - "id": "3410" - }, - { - "examine": "2 doses serum 207 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 207 (2)", - "archery_ticket_price": "0", - "id": "3412" - }, - { - "examine": "1 dose serum 207 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 207 (1)", - "archery_ticket_price": "0", - "id": "3414" - }, - { - "shop_price": "208", - "examine": "3 doses permanent serum 208 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 208 (4)", - "archery_ticket_price": "0", - "id": "3416" - }, - { - "shop_price": "208", - "examine": "3 doses permanent serum 208 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 208 (3)", - "archery_ticket_price": "0", - "id": "3417" - }, - { - "shop_price": "208", - "examine": "2 doses permanent serum 208 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 208 (2)", - "archery_ticket_price": "0", - "id": "3418" - }, - { - "shop_price": "208", - "examine": "1 dose permanent serum 208 as described in Herbi Flax's diary.", - "durability": null, - "name": "Serum 208 (1)", - "archery_ticket_price": "0", - "id": "3419" - }, - { - "shop_price": "21", - "ge_buy_limit": "10000", - "examine": "A well carved limestone brick.", - "grand_exchange_price": "178", - "durability": null, - "name": "Limestone brick", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3420" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "178", - "durability": null, - "name": "Limestone brick", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3421" - }, - { - "shop_price": "26", - "ge_buy_limit": "1000", - "examine": "4 doses of olive oil.", - "grand_exchange_price": "678", - "durability": null, - "name": "Olive oil(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3422" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "678", - "durability": null, - "name": "Olive oil(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3423" - }, - { - "shop_price": "26", - "ge_buy_limit": "1000", - "examine": "3 doses of olive oil.", - "grand_exchange_price": "413", - "durability": null, - "name": "Olive oil(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3424" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "413", - "durability": null, - "name": "Olive oil(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3425" - }, - { - "shop_price": "26", - "ge_buy_limit": "1000", - "examine": "2 doses of olive oil.", - "grand_exchange_price": "173", - "durability": null, - "name": "Olive oil(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3426" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "173", - "durability": null, - "name": "Olive oil(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3427" - }, - { - "shop_price": "26", - "ge_buy_limit": "1000", - "examine": "1 dose of olive oil.", - "grand_exchange_price": "110", - "durability": null, - "name": "Olive oil(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3428" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "110", - "durability": null, - "name": "Olive oil(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3429" - }, - { - "ge_buy_limit": "1000", - "examine": "Sacred oil.", - "grand_exchange_price": "3587", - "durability": null, - "name": "Sacred oil(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3430" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3587", - "durability": null, - "name": "Sacred oil(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3431" - }, - { - "ge_buy_limit": "1000", - "examine": "Sacred oil.", - "grand_exchange_price": "2596", - "durability": null, - "name": "Sacred oil(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3432" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2596", - "durability": null, - "name": "Sacred oil(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3433" - }, - { - "ge_buy_limit": "1000", - "examine": "Sacred oil.", - "grand_exchange_price": "1713", - "durability": null, - "name": "Sacred oil(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3434" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1713", - "durability": null, - "name": "Sacred oil(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3435" - }, - { - "ge_buy_limit": "1000", - "examine": "Sacred oil.", - "grand_exchange_price": "1846", - "durability": null, - "name": "Sacred oil(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3436" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1846", - "durability": null, - "name": "Sacred oil(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3437" - }, - { - "ge_buy_limit": "25000", - "examine": "Funeral logs used for burning loars.", - "grand_exchange_price": "853", - "durability": null, - "name": "Pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3438" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "853", - "durability": null, - "name": "Pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3439" - }, - { - "ge_buy_limit": "1000", - "examine": "Oak logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "1122", - "durability": null, - "name": "Oak pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3440" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1122", - "durability": null, - "name": "Oak pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3441" - }, - { - "ge_buy_limit": "1000", - "examine": "Willow logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "1164", - "durability": null, - "name": "Willow pyre logs", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3442" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1164", - "durability": null, - "name": "Willow pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3443" - }, - { - "ge_buy_limit": "1000", - "examine": "Maple logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "3313", - "durability": null, - "name": "Maple pyre logs", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3444" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3313", - "durability": null, - "name": "Maple pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3445" - }, - { - "ge_buy_limit": "1000", - "examine": "Yew logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "4424", - "durability": null, - "name": "Yew pyre logs", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3446" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "4424", - "durability": null, - "name": "Yew pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3447" - }, - { - "ge_buy_limit": "1000", - "examine": "Magic logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "5611", - "durability": null, - "name": "Magic pyre logs", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3448" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "5611", - "durability": null, - "name": "Magic pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3449" - }, - { - "examine": "A bronze key with a blood-red painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Bronze key red", - "archery_ticket_price": "0", - "id": "3450" - }, - { - "examine": "A bronze key with a brown painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Bronze key brown", - "archery_ticket_price": "0", - "id": "3451" - }, - { - "examine": "A bronze key with a crimson painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Bronze key crimson", - "archery_ticket_price": "0", - "id": "3452" - }, - { - "examine": "A bronze key with a black painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Bronze key black", - "archery_ticket_price": "0", - "id": "3453" - }, - { - "examine": "A bronze key with a purple painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Bronze key purple", - "archery_ticket_price": "0", - "id": "3454" - }, - { - "examine": "A steel key with a blood-red painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Steel key red", - "archery_ticket_price": "0", - "id": "3455" - }, - { - "examine": "A steel key with a brown painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Steel key brown", - "archery_ticket_price": "0", - "id": "3456" - }, - { - "examine": "A steel key with a crimson painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Steel key crimson", - "archery_ticket_price": "0", - "id": "3457" - }, - { - "examine": "A steel key with a black painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Steel key black", - "archery_ticket_price": "0", - "id": "3458" - }, - { - "examine": "A steel key with a purple painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Steel key purple", - "archery_ticket_price": "0", - "id": "3459" - }, - { - "examine": "A black key with a blood-red painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Black key red", - "archery_ticket_price": "0", - "id": "3460" - }, - { - "examine": "A black key with a brown painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Black key brown", - "archery_ticket_price": "0", - "id": "3461" - }, - { - "examine": "A black key with a crimson painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Black key crimson", - "archery_ticket_price": "0", - "id": "3462" - }, - { - "examine": "A black key with a black painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Black key black", - "archery_ticket_price": "0", - "id": "3463" - }, - { - "examine": "A black key with a purple painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Black key purple", - "archery_ticket_price": "0", - "id": "3464" - }, - { - "examine": "A silver key with a blood-red painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Silver key red", - "archery_ticket_price": "0", - "id": "3465" - }, - { - "examine": "A silver key with a brown painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Silver key brown", - "archery_ticket_price": "0", - "id": "3466" - }, - { - "examine": "A silver key with a crimson painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Silver key crimson", - "archery_ticket_price": "0", - "id": "3467" - }, - { - "examine": "A silver key with a black painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Silver key black", - "archery_ticket_price": "0", - "id": "3468" - }, - { - "examine": "A silver key with a purple painted eyelet. (Shades of Mort'ton)", - "durability": null, - "name": "Silver key purple", - "archery_ticket_price": "0", - "id": "3469" - }, - { - "ge_buy_limit": "1000", - "examine": "Amazingly untouched by time.", - "grand_exchange_price": "956", - "durability": null, - "name": "Fine cloth", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3470" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "956", - "durability": null, - "name": "Fine cloth", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3471" - }, - { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black plateskirt with trim.", - "grand_exchange_price": "3077", - "durability": null, - "name": "Black plateskirt (t)", - "tradeable": "true", - "weight": "8", - "archery_ticket_price": "0", - "id": "3472", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "Black plateskirt with gold trim.", - "grand_exchange_price": "10600", - "durability": null, - "name": "Black plateskirt (g)", - "tradeable": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "3473", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant plateskirt with trim.", - "durability": null, - "weight": "9", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "4403", - "name": "Adam plateskirt (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3474", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant plateskirt with gold trim.", - "durability": null, - "weight": "9", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "11000", - "name": "Adam plateskirt (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3475", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune plateskirt with gold trim.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", "lendable": "true", - "grand_exchange_price": "42500", - "name": "Rune plateskirt (g)", + "requirements": "{1,40}-{6,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3476", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + "weight": "0.9" }, { + "id": "3394", + "name": "Splitbark boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3396", + "name": "Loar remains", + "examine": "The remains of a deadly shade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.35" + }, + { + "id": "3397", + "name": "Loar remains", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3398", + "name": "Phrin remains", + "examine": "The remains of a deadly shade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3399", + "name": "Phrin remains", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3400", + "name": "Riyl remains", + "examine": "The remains of a deadly shade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "3401", + "name": "Riyl remains", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3402", + "name": "Asyn remains", + "examine": "The remains of a deadly shade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "3403", + "name": "Asyn remains", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3404", + "name": "Fiyr remains", + "examine": "The remains of a deadly shade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3405", + "name": "Fiyr remains", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3406", + "name": "Ash potion(unf)", + "examine": "I need another ingredient to finish this potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3407", + "name": "Ash potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3408", + "name": "Serum 207 (4)", + "examine": "4 doses serum 207 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3410", + "name": "Serum 207 (3)", + "examine": "3 doses serum 207 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3412", + "name": "Serum 207 (2)", + "examine": "2 doses serum 207 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3414", + "name": "Serum 207 (1)", + "examine": "1 dose serum 207 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3416", + "name": "Serum 208 (4)", + "examine": "3 doses permanent serum 208 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "208" + }, + { + "id": "3417", + "name": "Serum 208 (3)", + "examine": "3 doses permanent serum 208 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "208" + }, + { + "id": "3418", + "name": "Serum 208 (2)", + "examine": "2 doses permanent serum 208 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "208" + }, + { + "id": "3419", + "name": "Serum 208 (1)", + "examine": "1 dose permanent serum 208 as described in Herbi Flax's diary.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "208" + }, + { + "id": "3420", + "name": "Limestone brick", + "examine": "A well carved limestone brick.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "21", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "3421", + "name": "Limestone brick", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3422", + "name": "Olive oil(4)", + "examine": "4 doses of olive oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "26", + "tradeable": "true" + }, + { + "id": "3423", + "name": "Olive oil(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3424", + "name": "Olive oil(3)", + "examine": "3 doses of olive oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "26", + "tradeable": "true" + }, + { + "id": "3425", + "name": "Olive oil(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3426", + "name": "Olive oil(2)", + "examine": "2 doses of olive oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "26", + "tradeable": "true" + }, + { + "id": "3427", + "name": "Olive oil(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3428", + "name": "Olive oil(1)", + "examine": "1 dose of olive oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "26", + "tradeable": "true" + }, + { + "id": "3429", + "name": "Olive oil(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3430", + "name": "Sacred oil(4)", + "examine": "Sacred oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3431", + "name": "Sacred oil(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3432", + "name": "Sacred oil(3)", + "examine": "Sacred oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3433", + "name": "Sacred oil(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3434", + "name": "Sacred oil(2)", + "examine": "Sacred oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3435", + "name": "Sacred oil(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3436", + "name": "Sacred oil(1)", + "examine": "Sacred oil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3437", + "name": "Sacred oil(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3438", + "name": "Pyre logs", + "examine": "Funeral logs used for burning loars.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "3439", + "name": "Pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "3440", + "name": "Oak pyre logs", + "examine": "Oak logs prepared with sacred oil for a funeral pyre.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3441", + "name": "Oak pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3442", + "name": "Willow pyre logs", + "examine": "Willow logs prepared with sacred oil for a funeral pyre.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "3443", + "name": "Willow pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3444", + "name": "Maple pyre logs", + "examine": "Maple logs prepared with sacred oil for a funeral pyre.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "3445", + "name": "Maple pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3446", + "name": "Yew pyre logs", + "examine": "Yew logs prepared with sacred oil for a funeral pyre.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "3447", + "name": "Yew pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3448", + "name": "Magic pyre logs", + "examine": "Magic logs prepared with sacred oil for a funeral pyre.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "3449", + "name": "Magic pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3450", + "name": "Bronze key red", + "examine": "A bronze key with a blood-red painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3451", + "name": "Bronze key brown", + "examine": "A bronze key with a brown painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3452", + "name": "Bronze key crimson", + "examine": "A bronze key with a crimson painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3453", + "name": "Bronze key black", + "examine": "A bronze key with a black painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3454", + "name": "Bronze key purple", + "examine": "A bronze key with a purple painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3455", + "name": "Steel key red", + "examine": "A steel key with a blood-red painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3456", + "name": "Steel key brown", + "examine": "A steel key with a brown painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3457", + "name": "Steel key crimson", + "examine": "A steel key with a crimson painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3458", + "name": "Steel key black", + "examine": "A steel key with a black painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3459", + "name": "Steel key purple", + "examine": "A steel key with a purple painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3460", + "name": "Black key red", + "examine": "A black key with a blood-red painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3461", + "name": "Black key brown", + "examine": "A black key with a brown painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3462", + "name": "Black key crimson", + "examine": "A black key with a crimson painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3463", + "name": "Black key black", + "examine": "A black key with a black painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3464", + "name": "Black key purple", + "examine": "A black key with a purple painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3465", + "name": "Silver key red", + "examine": "A silver key with a blood-red painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3466", + "name": "Silver key brown", + "examine": "A silver key with a brown painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3467", + "name": "Silver key crimson", + "examine": "A silver key with a crimson painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3468", + "name": "Silver key black", + "examine": "A silver key with a black painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3469", + "name": "Silver key purple", + "examine": "A silver key with a purple painted eyelet. (Shades of Mort'ton)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3470", + "name": "Fine cloth", + "examine": "Amazingly untouched by time.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "3471", + "name": "Fine cloth", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3472", + "name": "Black plateskirt (t)", + "examine": "Black plateskirt with trim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "8" + }, + { + "id": "3473", + "name": "Black plateskirt (g)", + "examine": "Black plateskirt with gold trim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "3474", + "name": "Adam plateskirt (t)", + "examine": "Adamant plateskirt with trim.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "3475", + "name": "Adam plateskirt (g)", + "examine": "Adamant plateskirt with gold trim.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "3476", + "name": "Rune plateskirt (g)", + "examine": "Rune plateskirt with gold trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "3477", + "name": "Rune plateskirt (t)", + "examine": "Rune plateskirt with trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", "requirements": "{1,40}", "shop_price": "81280", - "ge_buy_limit": "2", - "examine": "Rune plateskirt with trim.", - "durability": null, - "weight": "8", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "38300", - "name": "Rune plateskirt (t)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3477", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + "weight": "8" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune plateskirt in the colours of Zamorak.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "42000", - "name": "Zamorak plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", "id": "3478", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune plateskirt in the colours of Saradomin.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "44000", - "name": "Saradomin plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3479", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune plateskirt in the colours of Guthix.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "39100", - "name": "Guthix plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3480", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platebody with complete gold trim & plating.", - "durability": null, - "weight": "10", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "2500000", - "name": "Gilded platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3481", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2500000", - "durability": null, - "name": "Gilded platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3482" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune platelegs with gold plate.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "2200000", - "name": "Gilded platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3483", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2200000", - "durability": null, - "name": "Gilded platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3484" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune plateskirt with gold plate.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "162300", - "name": "Gilded plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3485", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune full helmet with gold plate.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "477200", - "name": "Gilded full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3486", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "477200", - "durability": null, - "name": "Gilded full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3487" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Rune kiteshield with gold plate.", - "durability": null, - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "515400", - "name": "Gilded kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3488", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "515400", - "durability": null, - "name": "Gilded kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3489" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3490" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3491" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3492" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3493" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3494" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3495" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3496" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3497" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3498" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3499" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3500" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3501" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3502" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3503" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3504" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3505" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3506" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3507" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3508" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3509" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3510" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3511" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3512" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3513" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3514" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3515" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3516" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3517" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3518" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3519" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3520" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3521" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3522" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3523" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3524" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3525" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3526" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3527" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3528" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3529" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3530" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3531" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3532" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3533" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3534" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3535" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3536" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3537" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3538" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3539" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3540" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3541" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3542" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3543" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3544" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3545" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3546" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3547" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3548" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3549" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3550" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3551" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3552" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3553" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3554" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3555" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3556" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3557" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3558" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3559" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3560" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3561" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3562" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3563" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3564" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "3565" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3566" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "3567" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3568" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "3569" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3570" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "3571" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3572" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3573" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3574" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3575" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "3576" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3577" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "3578" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3579" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3580" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3581" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3582" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3583" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3584" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3585" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3586" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3587" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3588" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3589" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3590" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3591" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3592" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3593" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3594" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3595" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3596" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3597" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3598" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3599" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3600" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3601" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3602" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3603" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3604" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3605" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3607" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3609" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3610" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3611" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3612" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3613" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3614" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3615" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3616" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3617" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "3618" - }, - { - "durability": null, - "name": "Black plateskirt (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3668" - }, - { - "durability": null, - "name": "Black plateskirt (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3669" - }, - { - "durability": null, - "name": "Adam plateskirt (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3670" - }, - { - "durability": null, - "name": "Adam plateskirt (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3671" - }, - { - "durability": null, - "name": "Rune plateskirt (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3672" - }, - { - "durability": null, - "name": "Rune plateskirt (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3673" - }, - { - "durability": null, "name": "Zamorak plateskirt", - "tradeable": "true", + "examine": "Rune plateskirt in the colours of Zamorak.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "3674" + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" }, { - "durability": null, + "id": "3479", "name": "Saradomin plateskirt", - "tradeable": "true", + "examine": "Rune plateskirt in the colours of Saradomin.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "3675" + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "9" }, { - "durability": null, + "id": "3480", "name": "Guthix plateskirt", - "tradeable": "true", + "examine": "Rune plateskirt in the colours of Guthix.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "3676" - }, - { + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", "durability": null, - "name": "Gilded plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3677" - }, - { - "shop_price": "13000", - "examine": "An exquisitely shaped tool specially designed for fixing temples.", - "durability": null, - "name": "Flamtaer hammer", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "3678" - }, - { - "examine": "A sealed letter of recommendation.", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3685" - }, - { - "examine": "It's almost a musical instrument.", - "durability": null, - "name": "Unstrung lyre", - "weight": "1", - "archery_ticket_price": "0", - "id": "3688", - "equipment_slot": "3" - }, - { - "examine": "A musical intrument that I can magically play.", - "durability": null, - "name": "Lyre", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "3689", - "equipment_slot": "3" - }, - { - "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "3690", - "equipment_slot": "3" - }, - { - "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre(1)", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "3691", - "equipment_slot": "3" - }, - { - "examine": "I can use this to make a lyre.", - "durability": null, - "name": "Branch", - "weight": "1", - "archery_ticket_price": "0", - "id": "3692" - }, - { - "shop_price": "1000", - "examine": "I can spin this into golden wool.", - "durability": null, - "name": "Golden fleece", - "weight": "1", - "archery_ticket_price": "0", - "id": "3693" - }, - { - "examine": "I can use this to make a lyre.", - "durability": null, - "name": "Golden wool", - "weight": "1", - "archery_ticket_price": "0", - "id": "3694" - }, - { - "turn90cw_anim": "6662", - "examine": "The lowest maintenance pet you will ever have.", - "walk_anim": "6658", - "durability": null, - "weight": "1", - "turn90ccw_anim": "6663", - "two_handed": "true", - "turn180_anim": "6659", - "render_anim": "792", - "equipment_slot": "3", - "stand_anim": "6657", - "name": "Pet rock", - "run_anim": "6660", - "archery_ticket_price": "0", - "id": "3695", - "stand_turn_anim": "6661" - }, - { - "examine": "Talisman to bind the Draugen.", - "durability": null, - "name": "Hunters' talisman", - "archery_ticket_price": "0", - "id": "3696" - }, - { - "examine": "Talisman to bind the Draugen.", - "durability": null, - "name": "Hunters' talisman", - "archery_ticket_price": "0", - "id": "3697" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some flowers from a distant land.", - "durability": null, - "name": "Exotic flower", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3698" - }, - { - "examine": "A hauntingly beautiful love ballad.", - "durability": null, - "name": "Fremennik ballad", - "archery_ticket_price": "0", - "id": "3699" - }, - { - "examine": "A pair of sturdy made custom boots.", - "durability": null, - "name": "Sturdy boots", - "archery_ticket_price": "0", - "id": "3700" - }, - { - "examine": "Could probably be a bit clearer?", - "durability": null, - "name": "Tracking map", - "archery_ticket_price": "0", - "id": "3701" - }, - { - "examine": "A finely crafted string for a custom bow", - "durability": null, - "name": "Custom bow string", - "archery_ticket_price": "0", - "id": "3702" - }, - { - "examine": "An extremely odd, non-edible fish.", - "durability": null, - "name": "Unusual fish", - "archery_ticket_price": "0", - "id": "3703" - }, - { - "examine": "Map showing the best fishing spots out at sea.", - "durability": null, - "name": "Sea fishing map", - "archery_ticket_price": "0", - "id": "3704" - }, - { - "examine": "An estimate of expected local weather conditions.", - "durability": null, - "name": "Weather forecast", - "archery_ticket_price": "0", - "id": "3705" - }, - { - "examine": "Shows the wearer is worthy of the Champions table.", - "durability": null, - "name": "Champions token", - "archery_ticket_price": "0", - "id": "3706" - }, - { - "examine": "Probably the greatest cocktail in the world.", - "durability": null, - "name": "Legendary cocktail", - "archery_ticket_price": "0", - "id": "3707" - }, - { - "examine": "A signed statement promising a reduction on sales tax.", - "durability": null, - "name": "Fiscal statement", - "archery_ticket_price": "0", - "id": "3708" - }, - { - "shop_price": "5000", - "examine": "A legally binding contract promising not to enter the longhall.", - "durability": null, - "name": "Promissory note", - "archery_ticket_price": "0", - "id": "3709" - }, - { - "examine": "This employment contract is for a warrior to act as a bodyguard.", - "durability": null, - "name": "Warriors' contract", - "archery_ticket_price": "0", - "id": "3710" - }, - { - "shop_price": "325", - "examine": "A lot of beer in a barrel.", - "grand_exchange_price": "1555", - "durability": null, - "name": "Keg of beer", - "tradeable": "true", - "weight": "20", - "archery_ticket_price": "0", - "id": "3711" - }, - { - "examine": "Suspiciously close to beer, but without the side effects.", - "durability": null, - "name": "Low alcohol keg", - "weight": "20", - "archery_ticket_price": "0", - "id": "3712" - }, - { - "examine": "It's some kind of weird little parcel thing.", - "durability": null, - "name": "Strange object", - "archery_ticket_price": "0", - "id": "3713" - }, - { - "examine": "It's some kind of weird little parcel thing.", - "durability": null, - "name": "Lit strange object", - "archery_ticket_price": "0", - "id": "3714" - }, - { - "examine": "A red coloured disk, apparently made out of wood.", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3715" - }, - { - "examine": "A red coloured disk, apparently made out of wood.", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3716" - }, - { - "examine": "A very attractive magnet.", - "durability": null, - "name": "Magnet", - "archery_ticket_price": "0", - "id": "3718" - }, - { - "examine": "Some blue thread.", - "durability": null, - "name": "Thread", - "archery_ticket_price": "0", - "id": "3719" - }, - { - "examine": "A small pick for cracking small objects.", - "durability": null, - "name": "Pick", - "archery_ticket_price": "0", - "id": "3720" - }, - { - "examine": "Might be fun to play with in the bath.", - "durability": null, - "name": "Ship toy", - "archery_ticket_price": "0", - "id": "3721" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "It's a bucket of salty water.", - "durability": null, - "name": "Full bucket", - "archery_ticket_price": "0", - "id": "3722" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This bucket is eighty percent full. It has a 5 painted on its side.", - "durability": null, - "name": "4/5ths full bucket", - "archery_ticket_price": "0", - "id": "3723" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This bucket is sixty percent full. It has a 5 painted on its side.", - "durability": null, - "name": "3/5ths full bucket", - "archery_ticket_price": "0", - "id": "3724" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This bucket is forty percent full. It has a 5 painted on its side.", - "durability": null, - "name": "2/5ths full bucket", - "archery_ticket_price": "0", - "id": "3725" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This bucket is twenty percent full. It has a 5 painted on its side.", - "durability": null, - "name": "1/5ths full bucket", - "archery_ticket_price": "0", - "id": "3726" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "2", - "examine": "It's an empty bucket.", - "grand_exchange_price": "50", - "durability": null, - "name": "Empty bucket", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3727" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This bucket of water is frozen solid.", - "durability": null, - "name": "Frozen bucket", - "archery_ticket_price": "0", - "id": "3728" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This jug is completely full. It has a 3 painted on its side.", - "durability": null, - "name": "Full jug", - "archery_ticket_price": "0", - "id": "3729" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This jug is two thirds full. It has a 3 painted on its side.", - "durability": null, - "name": "2/3rds full jug", - "archery_ticket_price": "0", - "id": "3730" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This jug is one third full. It has a 3 painted on its side.", - "durability": null, - "name": "1/3rds full jug", - "archery_ticket_price": "0", - "id": "3731" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "1", - "examine": "This jug is empty.", - "grand_exchange_price": "164", - "durability": null, - "name": "Empty jug", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "3732" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This jug of water is frozen solid.", - "durability": null, - "name": "Frozen jug", - "archery_ticket_price": "0", - "id": "3733" - }, - { - "examine": "An unusually shaped vase. You can see something glinting inside.", - "durability": null, - "name": "Vase", - "archery_ticket_price": "0", - "id": "3734" - }, - { - "examine": "An unusually shaped vase full of water. You can see something glinting inside.", - "durability": null, - "name": "Vase of water", - "archery_ticket_price": "0", - "id": "3735" - }, - { - "examine": "An unusually shaped vase full of ice. You can see something glinting inside.", - "durability": null, - "name": "Frozen vase", - "archery_ticket_price": "0", - "id": "3736" - }, - { - "examine": "This looks like a lid to some kind of container.", - "durability": null, - "name": "Vase lid", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3737" - }, - { - "examine": "The lid is screwed on tightly. ", - "durability": null, - "name": "Sealed vase", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3738" - }, - { - "examine": "The lid is screwed on tightly. It is full of water.", - "durability": null, - "name": "Sealed vase", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3739" - }, - { - "examine": "The lid is screwed on tightly. It is very cold. ", - "durability": null, - "name": "Sealed vase", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3740" - }, - { - "examine": "A small, cold key.", - "durability": null, - "name": "Frozen key", - "archery_ticket_price": "0", - "id": "3741" - }, - { - "examine": "The colouring on it seems to be some kind of sticky goop.", - "durability": null, - "name": "Red herring", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3742" - }, - { - "examine": "A red coloured disk, apparently made out of wood.", - "durability": null, - "name": "Red disk", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3743" - }, - { - "examine": "A simple looking disk made of wood.", - "durability": null, - "name": "Wooden disk", - "archery_ticket_price": "0", - "id": "3744" - }, - { - "shop_price": "27", - "examine": "The key to leave the Seer's house.", - "durability": null, - "name": "Seer's key", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "3745" - }, - { - "examine": "Yup, it's sticky, it's red and it's goop.", - "durability": null, - "name": "Sticky red goop", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "3746" - }, - { - "durability": null, - "name": "Sticky red goop", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3747", - "alchemizable": "true" - }, - { - "remove_head": "true", - "examine": "A sturdy helm worn only by Fremennik clan members.", - "durability": null, - "name": "Fremennik helm", - "weight": "2.7", - "archery_ticket_price": "0", - "id": "3748", - "absorb": "1,0,2", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", - "alchemizable": "true", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,45}", - "shop_price": "78000", - "ge_buy_limit": "100", - "examine": "This helmet is worn by archers.", - "durability": null, - "weight": "2", - "absorb": "0,3,1", - "equipment_slot": "0", + "equipment_slot": "7", + "ge_buy_limit": "2", "lendable": "true", - "grand_exchange_price": "48900", - "name": "Archer helm", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3749", - "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" + "weight": "9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "48900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Archer helm", - "tradeable": "true", + "id": "3481", + "name": "Gilded platebody", + "examine": "Rune platebody with complete gold trim & plating.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "3750" - }, - { - "remove_head": "true", - "requirements": "{1,45}", - "shop_price": "78000", - "ge_buy_limit": "100", - "examine": "This helmet is worn by berserkers.", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", "durability": null, - "weight": "2.7", - "absorb": "1,0,3", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "60900", - "name": "Berserker helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3751", - "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "60900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Berserker helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3752" - }, - { - "remove_head": "true", - "requirements": "{1,45}", - "shop_price": "78000", - "ge_buy_limit": "100", - "examine": "This helm is worn by warriors.", - "durability": null, - "weight": "2.7", - "absorb": "1,0,3", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "50700", - "name": "Warrior helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3753", - "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "50700", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Warrior helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3754" - }, - { - "remove_head": "true", - "requirements": "{1,45}", - "shop_price": "78000", - "ge_buy_limit": "100", - "examine": "This helm is worn by farseers.", - "durability": null, - "weight": "2.7", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "47900", - "name": "Farseer helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3755", - "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "47900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Farseer helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3756" - }, - { - "examine": "A sword used only by Fremennik warriors.", - "durability": null, - "weight": "1.8", - "attack_speed": "4", - "weapon_interface": "6", - "alchemizable": "true", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "name": "Fremennik blade", - "archery_ticket_price": "0", - "id": "3757", - "bonuses": "6,29,-2,0,0,0,1,0,0,0,0,28,0,0,0" - }, - { - "examine": "A shield worn by Fremennik warriors.", - "durability": null, - "name": "Fremennik shield", - "destroy": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "3758", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", - "alchemizable": "true", - "equipment_slot": "5" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "697", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3759", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "697", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3760" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "54", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3761", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "54", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3762" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "581", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3763", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "581", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3764" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "912", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3765", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "912", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3766" - }, - { - "remove_sleeves": "true", - "shop_price": "325", - "ge_buy_limit": "100", - "examine": "The latest in Fremennik fashion.", - "grand_exchange_price": "100", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3767", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "100", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3768" - }, - { - "remove_sleeves": "true", - "shop_price": "325", - "ge_buy_limit": "100", - "examine": "The latest in Fremennik fashion.", - "grand_exchange_price": "486", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3769", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "486", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3770" - }, - { - "remove_sleeves": "true", - "shop_price": "325", - "ge_buy_limit": "100", - "examine": "The latest in Fremennik fashion.", - "grand_exchange_price": "242", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3771", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "242", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3772" - }, - { - "remove_sleeves": "true", - "shop_price": "325", - "ge_buy_limit": "100", - "examine": "The latest in Fremennik fashion.", - "grand_exchange_price": "500", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3773", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "500", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3774" - }, - { - "remove_sleeves": "true", - "shop_price": "325", - "ge_buy_limit": "100", - "examine": "The latest in Fremennik fashion.", - "grand_exchange_price": "450", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3775", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "450", - "durability": null, - "name": "Fremennik shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3776" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "674", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3777", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "674", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3778" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "809", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3779", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "809", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3780" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "632", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3781", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "632", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3782" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "517", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3783", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "517", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3784" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "398", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3785", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "398", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3786" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "283", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3787", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "283", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3788" - }, - { - "shop_price": "325", - "ge_buy_limit": "1000", - "examine": "The latest fashion in Rellekka.", - "grand_exchange_price": "966", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3789", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "966", - "durability": null, - "name": "Fremennik cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3790" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "Very stylish!", - "grand_exchange_price": "205", - "durability": null, - "name": "Fremennik boots", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "3791", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "205", - "durability": null, - "name": "Fremennik boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3792" - }, - { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "The latest fashion of Rellekka.", - "durability": null, - "weight": "0.9", + "equip_audio": "2239", "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "1191", - "name": "Fremennik robe", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3793", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + "weight": "10" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1191", + "id": "3482", + "name": "Gilded platebody", + "archery_ticket_price": "0", "durability": null, - "name": "Fremennik robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3794" + "ge_buy_limit": "2", + "tradeable": "true" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "The latest fashion of Rellekka.", - "grand_exchange_price": "663", + "id": "3483", + "name": "Gilded platelegs", + "examine": "Rune platelegs with gold plate.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", "durability": null, - "name": "Fremennik skirt", + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "3795", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" + "weight": "9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "663", + "id": "3484", + "name": "Gilded platelegs", + "archery_ticket_price": "0", "durability": null, - "name": "Fremennik skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3796" + "ge_buy_limit": "2", + "tradeable": "true" }, { - "shop_price": "650", - "ge_buy_limit": "100", - "examine": "A silly pointed hat.", - "grand_exchange_price": "2380", + "id": "3485", + "name": "Gilded plateskirt", + "examine": "Rune plateskirt with gold plate.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", "durability": null, - "name": "Fremennik hat", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "3797", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" + "weight": "9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2380", + "id": "3486", + "name": "Gilded full helm", + "examine": "Rune full helmet with gold plate.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", "durability": null, - "name": "Fremennik hat", + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3798" + "weight": "2" }, { - "ge_buy_limit": "10", - "shop_price": "650", - "examine": "These will keep my hands warm!", - "grand_exchange_price": "172", + "id": "3487", + "name": "Gilded full helm", + "archery_ticket_price": "0", "durability": null, - "name": "Gloves", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "3799", - "bonuses": "0,0,0,0,0,0,1,2,0,0,1,0,0,0,0", - "equipment_slot": "9" + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "172", + "id": "3488", + "name": "Gilded kiteshield", + "examine": "Rune kiteshield with gold plate.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", "durability": null, - "name": "Gloves", + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "3800" + "weight": "5" }, { + "id": "3489", + "name": "Gilded kiteshield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "3490", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3491", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3492", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3493", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3494", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3495", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3496", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3497", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3498", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3499", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3500", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3501", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3502", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3503", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3504", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3505", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3506", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3507", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3508", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3509", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3510", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3511", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3512", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3513", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3514", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3515", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3516", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3517", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3518", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3519", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3520", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3521", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3522", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3523", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3524", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3525", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3526", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3527", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3528", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3529", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3530", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3531", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3532", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3533", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3534", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3535", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3536", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3537", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3538", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3539", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3540", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3541", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3542", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3543", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3544", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3545", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3546", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3547", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3548", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3549", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3550", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3551", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3552", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3553", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3554", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3555", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3556", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3557", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3558", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3559", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3560", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3561", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3562", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3563", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3564", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3565", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "3566", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3567", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "3568", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3569", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "3570", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3571", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "3572", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3573", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3574", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3575", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3576", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "3577", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3578", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "3579", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3580", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3581", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3582", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3583", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3584", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3585", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3586", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3587", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3588", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3589", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3590", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3591", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3592", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3593", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3594", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3595", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3596", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3597", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3598", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3599", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3600", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3601", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3602", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3603", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "3604", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3605", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3607", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3609", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3610", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3611", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3612", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3613", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3614", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3615", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3616", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3617", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3618", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3668", + "name": "Black plateskirt (t)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3669", + "name": "Black plateskirt (g)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3670", + "name": "Adam plateskirt (t)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3671", + "name": "Adam plateskirt (g)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3672", + "name": "Rune plateskirt (g)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3673", + "name": "Rune plateskirt (t)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3674", + "name": "Zamorak plateskirt", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3675", + "name": "Saradomin plateskirt", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3676", + "name": "Guthix plateskirt", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3677", + "name": "Gilded plateskirt", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3678", + "name": "Flamtaer hammer", + "examine": "An exquisitely shaped tool specially designed for fixing temples.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "13000", + "weight": "1.3" + }, + { + "id": "3685", + "name": "Picture", + "examine": "A sealed letter of recommendation.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3688", + "name": "Unstrung lyre", + "examine": "It's almost a musical instrument.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1" + }, + { + "id": "3689", + "name": "Lyre", + "examine": "A musical intrument that I can magically play.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1.8" + }, + { + "id": "3690", + "name": "Enchanted lyre", + "examine": "This will teleport me to Rellekka when I play it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1.8" + }, + { + "id": "3691", + "name": "Enchanted lyre(1)", + "examine": "This will teleport me to Rellekka when I play it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1.8" + }, + { + "id": "3692", + "name": "Branch", + "examine": "I can use this to make a lyre.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "3693", + "name": "Golden fleece", + "examine": "I can spin this into golden wool.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1000", + "weight": "1" + }, + { + "id": "3694", + "name": "Golden wool", + "examine": "I can use this to make a lyre.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "3695", + "name": "Pet rock", + "examine": "The lowest maintenance pet you will ever have.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "792", + "run_anim": "6660", + "stand_anim": "6657", + "stand_turn_anim": "6661", + "turn180_anim": "6659", + "turn90ccw_anim": "6663", + "turn90cw_anim": "6662", + "two_handed": "true", + "walk_anim": "6658", + "weight": "1" + }, + { + "id": "3696", + "name": "Hunters' talisman", + "examine": "Talisman to bind the Draugen.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3697", + "name": "Hunters' talisman", + "examine": "Talisman to bind the Draugen.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3698", + "name": "Exotic flower", + "examine": "Some flowers from a distant land.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "3699", + "name": "Fremennik ballad", + "examine": "A hauntingly beautiful love ballad.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3700", + "name": "Sturdy boots", + "examine": "A pair of sturdy made custom boots.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3701", + "name": "Tracking map", + "examine": "Could probably be a bit clearer?", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3702", + "name": "Custom bow string", + "examine": "A finely crafted string for a custom bow", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3703", + "name": "Unusual fish", + "examine": "An extremely odd, non-edible fish.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3704", + "name": "Sea fishing map", + "examine": "Map showing the best fishing spots out at sea.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3705", + "name": "Weather forecast", + "examine": "An estimate of expected local weather conditions.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3706", + "name": "Champions token", + "examine": "Shows the wearer is worthy of the Champions table.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3707", + "name": "Legendary cocktail", + "examine": "Probably the greatest cocktail in the world.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3708", + "name": "Fiscal statement", + "examine": "A signed statement promising a reduction on sales tax.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3709", + "name": "Promissory note", + "examine": "A legally binding contract promising not to enter the longhall.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "3710", + "name": "Warriors' contract", + "examine": "This employment contract is for a warrior to act as a bodyguard.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3711", + "name": "Keg of beer", + "examine": "A lot of beer in a barrel.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "325", + "tradeable": "true", + "weight": "20" + }, + { + "id": "3712", + "name": "Low alcohol keg", + "examine": "Suspiciously close to beer, but without the side effects.", + "archery_ticket_price": "0", + "durability": null, + "weight": "20" + }, + { + "id": "3713", + "name": "Strange object", + "examine": "It's some kind of weird little parcel thing.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3714", + "name": "Lit strange object", + "examine": "It's some kind of weird little parcel thing.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3715", + "name": "Picture", + "examine": "A red coloured disk, apparently made out of wood.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3716", + "name": "Picture", + "examine": "A red coloured disk, apparently made out of wood.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3718", + "name": "Magnet", + "examine": "A very attractive magnet.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3719", + "name": "Thread", + "examine": "Some blue thread.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3720", + "name": "Pick", + "examine": "A small pick for cracking small objects.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3721", + "name": "Ship toy", + "examine": "Might be fun to play with in the bath.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3722", + "name": "Full bucket", + "examine": "It's a bucket of salty water.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3723", + "name": "4/5ths full bucket", + "examine": "This bucket is eighty percent full. It has a 5 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3724", + "name": "3/5ths full bucket", + "examine": "This bucket is sixty percent full. It has a 5 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3725", + "name": "2/5ths full bucket", + "examine": "This bucket is forty percent full. It has a 5 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3726", + "name": "1/5ths full bucket", + "examine": "This bucket is twenty percent full. It has a 5 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3727", + "name": "Empty bucket", + "examine": "It's an empty bucket.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "3728", + "name": "Frozen bucket", + "examine": "This bucket of water is frozen solid.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3729", + "name": "Full jug", + "examine": "This jug is completely full. It has a 3 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3730", + "name": "2/3rds full jug", + "examine": "This jug is two thirds full. It has a 3 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3731", + "name": "1/3rds full jug", + "examine": "This jug is one third full. It has a 3 painted on its side.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3732", + "name": "Empty jug", + "examine": "This jug is empty.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "1", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "3733", + "name": "Frozen jug", + "examine": "This jug of water is frozen solid.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "3734", + "name": "Vase", + "examine": "An unusually shaped vase. You can see something glinting inside.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3735", + "name": "Vase of water", + "examine": "An unusually shaped vase full of water. You can see something glinting inside.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3736", + "name": "Frozen vase", + "examine": "An unusually shaped vase full of ice. You can see something glinting inside.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3737", + "name": "Vase lid", + "examine": "This looks like a lid to some kind of container.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "3738", + "name": "Sealed vase", + "examine": "The lid is screwed on tightly. ", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3739", + "name": "Sealed vase", + "examine": "The lid is screwed on tightly. It is full of water.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3740", + "name": "Sealed vase", + "examine": "The lid is screwed on tightly. It is very cold. ", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3741", + "name": "Frozen key", + "examine": "A small, cold key.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3742", + "name": "Red herring", + "examine": "The colouring on it seems to be some kind of sticky goop.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3743", + "name": "Red disk", + "examine": "A red coloured disk, apparently made out of wood.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "3744", + "name": "Wooden disk", + "examine": "A simple looking disk made of wood.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "3745", + "name": "Seer's key", + "examine": "The key to leave the Seer's house.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "shop_price": "27", + "tradeable": "false" + }, + { + "id": "3746", + "name": "Sticky red goop", + "examine": "Yup, it's sticky, it's red and it's goop.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "3747", + "name": "Sticky red goop", + "alchemizable": "true", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "3748", + "name": "Fremennik helm", + "examine": "A sturdy helm worn only by Fremennik clan members.", + "absorb": "1,0,2", + "alchemizable": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "2.7" + }, + { + "id": "3749", + "name": "Archer helm", + "examine": "This helmet is worn by archers.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", "ge_buy_limit": "100", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "3750", + "name": "Archer helm", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3751", + "name": "Berserker helm", + "examine": "This helmet is worn by berserkers.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "3752", + "name": "Berserker helm", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3753", + "name": "Warrior helm", + "examine": "This helm is worn by warriors.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "3754", + "name": "Warrior helm", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3755", + "name": "Farseer helm", + "examine": "This helm is worn by farseers.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "3756", + "name": "Farseer helm", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3757", + "name": "Fremennik blade", + "examine": "A sword used only by Fremennik warriors.", + "alchemizable": "true", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "4", + "bonuses": "6,29,-2,0,0,0,1,0,0,0,0,28,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "weapon_interface": "6", + "weight": "1.8" + }, + { + "id": "3758", + "name": "Fremennik shield", + "examine": "A shield worn by Fremennik warriors.", + "alchemizable": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "5", + "weight": "2.2" + }, + { + "id": "3759", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3760", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3761", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3762", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3763", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3764", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3765", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3766", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3767", + "name": "Fremennik shirt", + "examine": "The latest in Fremennik fashion.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3768", + "name": "Fremennik shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3769", + "name": "Fremennik shirt", + "examine": "The latest in Fremennik fashion.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3770", + "name": "Fremennik shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3771", + "name": "Fremennik shirt", + "examine": "The latest in Fremennik fashion.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3772", + "name": "Fremennik shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3773", + "name": "Fremennik shirt", + "examine": "The latest in Fremennik fashion.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3774", + "name": "Fremennik shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3775", + "name": "Fremennik shirt", + "examine": "The latest in Fremennik fashion.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3776", + "name": "Fremennik shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3777", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3778", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3779", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3780", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3781", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3782", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3783", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3784", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3785", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3786", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3787", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3788", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3789", + "name": "Fremennik cloak", + "examine": "The latest fashion in Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "1000", + "shop_price": "325", + "tradeable": "true" + }, + { + "id": "3790", + "name": "Fremennik cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "3791", + "name": "Fremennik boots", + "examine": "Very stylish!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "3792", + "name": "Fremennik boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3793", + "name": "Fremennik robe", + "examine": "The latest fashion of Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "650", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "3794", + "name": "Fremennik robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3795", + "name": "Fremennik skirt", + "examine": "The latest fashion of Rellekka.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "3796", + "name": "Fremennik skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3797", + "name": "Fremennik hat", + "examine": "A silly pointed hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "650", + "tradeable": "true", + "weight": "1" + }, + { + "id": "3798", + "name": "Fremennik hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "3799", + "name": "Gloves", + "examine": "These will keep my hands warm!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "shop_price": "650", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "3800", + "name": "Gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "3801", + "name": "Keg of beer", "examine": "A lot of beer in a barrel. Beer in a barrel - a specialty of the Fremennik Province.", - "grand_exchange_price": "1817", - "durability": null, - "name": "Keg of beer", - "tradeable": "true", - "weight": "20", "archery_ticket_price": "0", - "id": "3801" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "325", + "tradeable": "true", + "weight": "20" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1817", - "durability": null, + "id": "3802", "name": "Keg of beer", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3802" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "3803", + "name": "Beer", "examine": "A glass of frothy ale.", - "grand_exchange_price": "393", - "durability": null, - "name": "Beer", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "3803" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "393", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "3804", "name": "Beer", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3804" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "26", + "id": "3805", + "name": "Tankard", "examine": "A big cup for a big thirst.", - "durability": null, - "name": "Tankard", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3805" + "durability": null, + "shop_price": "26", + "tradeable": "true" }, { - "durability": null, + "id": "3806", "name": "Tankard", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3806" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "1400000", - "durability": null, + "id": "3827", "name": "Saradomin page 1", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3827" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "686000", - "durability": null, + "id": "3828", "name": "Saradomin page 2", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3828" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "522800", - "durability": null, + "id": "3829", "name": "Saradomin page 3", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3829" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "629500", - "durability": null, + "id": "3830", "name": "Saradomin page 4", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3830" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "7100000", - "durability": null, + "id": "3831", "name": "Zamorak page 1", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3831" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "5400000", - "durability": null, + "id": "3832", "name": "Zamorak page 2", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3832" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "4700000", - "durability": null, + "id": "3833", "name": "Zamorak page 3", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3833" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "5900000", - "durability": null, + "id": "3834", "name": "Zamorak page 4", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3834" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "1200000", - "durability": null, + "id": "3835", "name": "Guthix page 1", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3835" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "997100", - "durability": null, + "id": "3836", "name": "Guthix page 2", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3836" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "953100", - "durability": null, + "id": "3837", "name": "Guthix page 3", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3837" - }, - { - "ge_buy_limit": "2", "examine": "This seems to have been torn from a book...", - "grand_exchange_price": "1000000", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "3838", "name": "Guthix page 4", - "tradeable": "true", + "examine": "This seems to have been torn from a book...", "archery_ticket_price": "0", - "id": "3838" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "shop_price": "5000", - "examine": "An incomplete book of Saradomin.", - "durability": null, - "name": "Damaged book", - "weight": "1", - "archery_ticket_price": "0", "id": "3839", + "name": "Damaged book", + "examine": "An incomplete book of Saradomin.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "shop_price": "5000", + "weight": "1" }, { - "shop_price": "5000", - "examine": "The Holy book of Saradomin.", - "durability": null, - "name": "Holy book", - "weight": "1", - "archery_ticket_price": "0", "id": "3840", + "name": "Holy book", + "examine": "The Holy book of Saradomin.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,8,8,8,8,8,8,0,5,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "shop_price": "5000", + "weight": "1" }, { - "shop_price": "5000", - "examine": "An incomplete book of Zamorak.", - "durability": null, - "name": "Damaged book", - "weight": "1", - "archery_ticket_price": "0", "id": "3841", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "5" - }, - { - "examine": "The unholy book of Zamorak.", - "durability": null, - "name": "Unholy book", - "weight": "1", - "archery_ticket_price": "0", - "id": "3842", - "bonuses": "8,8,8,8,8,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "5" - }, - { - "shop_price": "5000", - "examine": "An incomplete book of Guthix.", - "durability": null, "name": "Damaged book", - "weight": "1", + "examine": "An incomplete book of Zamorak.", "archery_ticket_price": "0", - "id": "3843", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "shop_price": "5000", + "weight": "1" }, { - "examine": "The holy book of Guthix.", - "durability": null, - "name": "Book of balance", - "weight": "1", + "id": "3842", + "name": "Unholy book", + "examine": "The unholy book of Zamorak.", "archery_ticket_price": "0", + "bonuses": "8,8,8,8,8,0,0,0,0,0,0,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "weight": "1" + }, + { + "id": "3843", + "name": "Damaged book", + "examine": "An incomplete book of Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "shop_price": "5000", + "weight": "1" + }, + { "id": "3844", + "name": "Book of balance", + "examine": "The holy book of Guthix.", + "archery_ticket_price": "0", "bonuses": "4,4,4,4,4,4,4,4,4,4,4,0,5,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "weight": "1" }, { - "examine": "Looks like some kind of manual.", - "durability": null, + "id": "3847", "name": "Manual", - "tradeable": "false", - "destroy": "true", - "weight": "0.5", + "examine": "Looks like some kind of manual.", "archery_ticket_price": "0", - "id": "3847" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "0.5" }, { - "examine": "A key to the front door of the lighthouse. (Horror from the Deep)", - "durability": null, + "id": "3848", "name": "Lighthouse key", + "examine": "A key to the front door of the lighthouse. (Horror from the Deep)", "archery_ticket_price": "0", - "id": "3848" + "durability": null }, { - "examine": "Looks old and rusty...", - "durability": null, + "id": "3849", "name": "Rusty casket", - "tradeable": "false", + "examine": "Looks old and rusty...", + "archery_ticket_price": "0", "destroy": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "3849" + "durability": null, + "tradeable": "false", + "weight": "5" }, { - "durability": null, + "id": "3852", "name": "Unholy symbol", - "tradeable": "true", "archery_ticket_price": "0", - "id": "3852" + "durability": null, + "tradeable": "true" }, { - "shop_price": "490", - "ge_buy_limit": "10000", - "examine": "An enchanted necklace.", - "grand_exchange_price": "852", - "durability": null, - "name": "Games necklace(8)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "3853", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "852", - "durability": null, "name": "Games necklace(8)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3854" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "10000", + "shop_price": "490", + "tradeable": "true" }, { - "shop_price": "490", - "examine": "An enchanted necklace.", - "grand_exchange_price": "8", - "durability": null, - "name": "Games necklace(7)", - "tradeable": "true", + "id": "3854", + "name": "Games necklace(8)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { "id": "3855", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Games necklace(7)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3856" + "durability": null, + "equipment_slot": "2", + "shop_price": "490", + "tradeable": "true" }, { - "shop_price": "490", - "examine": "An enchanted necklace.", - "grand_exchange_price": "8", - "durability": null, - "name": "Games necklace(6)", - "tradeable": "true", + "id": "3856", + "name": "Games necklace(7)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3857", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Games necklace(6)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3858" + "durability": null, + "equipment_slot": "2", + "shop_price": "490", + "tradeable": "true" }, { - "shop_price": "490", - "examine": "An enchanted necklace.", - "grand_exchange_price": "8", - "durability": null, - "name": "Games necklace(5)", - "tradeable": "true", + "id": "3858", + "name": "Games necklace(6)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3859", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Games necklace(5)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3860" + "durability": null, + "equipment_slot": "2", + "shop_price": "490", + "tradeable": "true" }, { - "shop_price": "490", - "examine": "An enchanted necklace.", - "grand_exchange_price": "8", - "durability": null, - "name": "Games necklace(4)", - "tradeable": "true", + "id": "3860", + "name": "Games necklace(5)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3861", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Games necklace(4)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3862" + "durability": null, + "equipment_slot": "2", + "shop_price": "490", + "tradeable": "true" }, { - "shop_price": "490", - "examine": "An enchanted necklace.", - "grand_exchange_price": "8", - "durability": null, - "name": "Games necklace(3)", - "tradeable": "true", + "id": "3862", + "name": "Games necklace(4)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3863", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Games necklace(3)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3864" + "durability": null, + "equipment_slot": "2", + "shop_price": "490", + "tradeable": "true" }, { - "shop_price": "490", - "examine": "An enchanted necklace.", - "grand_exchange_price": "8", - "durability": null, - "name": "Games necklace(2)", - "tradeable": "true", + "id": "3864", + "name": "Games necklace(3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3865", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Games necklace(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "3866" - }, - { - "shop_price": "490", - "ge_buy_limit": "10000", "examine": "An enchanted necklace.", - "grand_exchange_price": "2093", - "durability": null, - "name": "Games necklace(1)", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "shop_price": "490", + "tradeable": "true" + }, + { + "id": "3866", + "name": "Games necklace(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "3867", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2093", - "durability": null, "name": "Games necklace(1)", - "tradeable": "true", + "examine": "An enchanted necklace.", "archery_ticket_price": "0", - "id": "3868" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "10000", + "shop_price": "490", + "tradeable": "true" }, { + "id": "3868", + "name": "Games necklace(1)", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "3893", "name": "Stool", "archery_ticket_price": "0", - "id": "3893", + "durability": null, "equipment_slot": "3" }, { - "examine": "It's not very good.", - "durability": null, + "id": "3894", "name": "Awful anthem", - "tradeable": "false", - "destroy": "true", + "examine": "It's not very good.", "archery_ticket_price": "0", - "id": "3894" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "Much better.", - "durability": null, + "id": "3895", "name": "Good anthem", - "tradeable": "false", - "destroy": "true", + "examine": "Much better.", "archery_ticket_price": "0", - "id": "3895" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "Just needs the King's signature.", - "durability": null, + "id": "3896", "name": "Treaty", + "examine": "Just needs the King's signature.", "archery_ticket_price": "0", - "id": "3896" + "durability": null }, { - "examine": "For making a giant pen.", - "durability": null, + "id": "3897", "name": "Giant nib", + "examine": "For making a giant pen.", "archery_ticket_price": "0", - "id": "3897" + "durability": null }, { - "examine": "The king should be able to use this.", - "durability": null, + "id": "3898", "name": "Giant pen", + "examine": "The king should be able to use this.", "archery_ticket_price": "0", - "id": "3898" + "durability": null }, { - "shop_price": "15", - "examine": "Not as good as a pet frog.", - "durability": null, - "name": "Iron sickle", - "weight": "1.6", - "archery_ticket_price": "0", "id": "3899", - "weapon_interface": "6", + "name": "Iron sickle", + "examine": "Not as good as a pet frog.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,0,0,0", - "equipment_slot": "3" - }, - { - "examine": "Managing Thine Kingdom for Noobes by A. Ghrim.", "durability": null, - "name": "Ghrim's book", - "weight": "1", - "archery_ticket_price": "0", - "id": "3901" - }, - { - "examine": "A pile of gout tubers suitable for use in mountainous terrain.", - "durability": null, - "name": "Hardy gout tuber", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "4001" - }, - { - "examine": "It looks like some kind of control panel.", - "durability": null, - "name": "Spare controls", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "4002" - }, - { - "examine": "It's the official Gnome Royal Seal, signed by King Narode Shareen.", - "durability": null, - "name": "Gnome royal seal", - "archery_ticket_price": "0", - "id": "4004" - }, - { - "shop_price": "160", - "examine": "Unreadable orders handwritten by King Narnode Shareen.", - "durability": null, - "name": "Narnode's orders", - "archery_ticket_price": "0", - "id": "4005" - }, - { - "shop_price": "10", - "examine": "Magical monkey talking dentures! What more can we say? Ook!", - "durability": null, - "name": "Monkey dentures", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "4006" - }, - { - "examine": "A gold bar with a talkative monkey spirit.", - "durability": null, - "name": "Enchanted bar", - "weight": "2", - "archery_ticket_price": "0", - "id": "4007" - }, - { - "shop_price": "3", - "examine": "It's... the eye of a gnome! Now what on earth could one do with this?", - "durability": null, - "name": "Eye of gnome", - "weight": "1", - "archery_ticket_price": "0", - "id": "4008" - }, - { - "shop_price": "3", - "examine": "It's... the eye of a gnome! Now what on earth could one do with this?", - "durability": null, - "name": "Eye of gnome", - "weight": "1", - "archery_ticket_price": "0", - "id": "4009" - }, - { - "shop_price": "3", - "examine": "They are Monkey Nuts. Yummy.", - "durability": null, - "name": "Monkey nuts", - "archery_ticket_price": "0", - "id": "4012" - }, - { - "shop_price": "50", - "examine": "It's a monkey bar. It looks highly nutritious.", - "durability": null, - "name": "Monkey bar", - "archery_ticket_price": "0", - "id": "4014" - }, - { - "shop_price": "300", - "examine": "It's a bowl full of mushy banana", - "durability": null, - "name": "Banana stew", - "archery_ticket_price": "0", - "id": "4016" - }, - { - "examine": "It's an amulet mould shaped like a monkey head.", - "durability": null, - "name": "M'amulet mould", - "weight": "1", - "archery_ticket_price": "0", - "id": "4020" - }, - { - "examine": "It's an Amulet of Monkey Speak. It makes vague chattering noises.", - "durability": null, - "name": "M'speak amulet", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4021", - "equipment_slot": "2" - }, - { - "examine": "It's an unstrung Amulet of Monkey Speak. It makes vague chattering noises.", - "durability": null, - "name": "M'speak amulet", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4022" - }, - { - "shop_price": "1000", - "examine": "A magic talisman in shape of a monkey head.", - "durability": null, - "name": "Monkey talisman", - "weight": "1.25", - "archery_ticket_price": "0", - "id": "4023" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4024", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4025", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4026", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4027", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4028", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4029", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4030", - "equipment_slot": "3" - }, - { - "examine": "A magical talisman in the shape of a Karamjan monkey head.", - "durability": null, - "name": "Monkey greegree", - "archery_ticket_price": "0", - "id": "4031", - "equipment_slot": "3" - }, - { - "examine": "I can train on this", - "durability": null, - "name": "Dummy", - "archery_ticket_price": "0", - "id": "4032" - }, - { - "examine": "It's a very ancient skull from some kind of ape.", - "durability": null, - "name": "Monkey skull", - "archery_ticket_price": "0", - "id": "4034" - }, - { - "examine": "It is the official sigil of the 10th squad of the Royal Guard.", - "durability": null, - "name": "10th squad sigil", - "archery_ticket_price": "0", - "id": "4035", - "equipment_slot": "2" - }, - { - "turn90cw_anim": "1424", - "examine": "The Holy Team Standard", - "walk_anim": "1422", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", "equipment_slot": "3", - "stand_anim": "1421", - "name": "Saradomin banner", - "tradeable": "false", - "run_anim": "1427", - "archery_ticket_price": "0", - "id": "4037", - "stand_turn_anim": "1426" - }, - { - "durability": null, - "name": "Saradomin banner", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "4038" - }, - { - "turn90cw_anim": "1424", - "examine": "The Zamorak team's flag.", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Zamorak banner", - "tradeable": "false", - "run_anim": "1427", - "archery_ticket_price": "0", - "id": "4039", - "stand_turn_anim": "1426" - }, - { - "durability": null, - "name": "Zamorak banner", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "4040" - }, - { - "examine": "The colours of Saradomin/Zamorak.", - "durability": null, - "name": "Hooded cloak", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4041", - "equipment_slot": "1" - }, - { - "examine": "The colours of Saradomin/Zamorak.", - "durability": null, - "name": "Hooded cloak", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4042", - "equipment_slot": "1" - }, - { - "durability": null, - "name": "Rock", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4044" - }, - { - "examine": "I could use this to destroy things...", - "durability": null, - "name": "Explosive potion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4045" - }, - { - "durability": null, - "name": "Explosive potion", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4046" - }, - { - "examine": "A coil of rope.", - "durability": null, - "name": "Climbing rope", - "archery_ticket_price": "0", - "id": "4047" - }, - { - "durability": null, - "name": "Climbing rope", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4048" - }, - { - "examine": "A box of bandages for healing.", - "durability": null, - "name": "Bandages", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4049" - }, - { - "durability": null, - "name": "Bandages", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4050" - }, - { - "examine": "Good for repairing a broken cannon.", - "durability": null, - "name": "Toolkit", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "4051" - }, - { - "durability": null, - "name": "Toolkit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4052" - }, - { - "examine": "Handy for hindering the enemy team's movement.", - "durability": null, - "name": "Barricade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4053" - }, - { - "durability": null, - "name": "Barricade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4054" - }, - { - "shop_price": "5", - "examine": "It's a manual for Castle Wars", - "durability": null, - "name": "Castlewars manual", - "weight": "1", - "archery_ticket_price": "0", - "id": "4055" - }, - { - "examine": "I can exchange these for further items.", - "durability": null, - "name": "Castle wars ticket", - "archery_ticket_price": "0", - "id": "4067" - }, - { - "requirements": "{0,5}", - "shop_price": "50", - "turn90cw_anim": "821", - "examine": "A very decorative sword.", - "walk_anim": "819", - "durability": null, - "weight": "1", - "turn90ccw_anim": "822", + "shop_price": "15", "weapon_interface": "6", - "turn180_anim": "820", - "render_anim": "1", - "castle_wars_ticket_price": "5", - "equipment_slot": "3", - "stand_anim": "808", - "name": "Decorative sword", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "4068", - "stand_turn_anim": "823", - "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,0,0,0" + "weight": "1.6" }, { - "remove_sleeves": "true", - "requirements": "{1,5}", + "id": "3901", + "name": "Ghrim's book", + "examine": "Managing Thine Kingdom for Noobes by A. Ghrim.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "4001", + "name": "Hardy gout tuber", + "examine": "A pile of gout tubers suitable for use in mountainous terrain.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "4002", + "name": "Spare controls", + "examine": "It looks like some kind of control panel.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.2" + }, + { + "id": "4004", + "name": "Gnome royal seal", + "examine": "It's the official Gnome Royal Seal, signed by King Narode Shareen.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4005", + "name": "Narnode's orders", + "examine": "Unreadable orders handwritten by King Narnode Shareen.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160" + }, + { + "id": "4006", + "name": "Monkey dentures", + "examine": "Magical monkey talking dentures! What more can we say? Ook!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "10", + "weight": "0.2" + }, + { + "id": "4007", + "name": "Enchanted bar", + "examine": "A gold bar with a talkative monkey spirit.", + "archery_ticket_price": "0", + "durability": null, + "weight": "2" + }, + { + "id": "4008", + "name": "Eye of gnome", + "examine": "It's... the eye of a gnome! Now what on earth could one do with this?", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "3", + "weight": "1" + }, + { + "id": "4009", + "name": "Eye of gnome", + "examine": "It's... the eye of a gnome! Now what on earth could one do with this?", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "3", + "weight": "1" + }, + { + "id": "4012", + "name": "Monkey nuts", + "examine": "They are Monkey Nuts. Yummy.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "3" + }, + { + "id": "4014", + "name": "Monkey bar", + "examine": "It's a monkey bar. It looks highly nutritious.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "50" + }, + { + "id": "4016", + "name": "Banana stew", + "examine": "It's a bowl full of mushy banana", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "300" + }, + { + "id": "4020", + "name": "M'amulet mould", + "examine": "It's an amulet mould shaped like a monkey head.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "4021", + "name": "M'speak amulet", + "examine": "It's an Amulet of Monkey Speak. It makes vague chattering noises.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "1.3" + }, + { + "id": "4022", + "name": "M'speak amulet", + "examine": "It's an unstrung Amulet of Monkey Speak. It makes vague chattering noises.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1.3" + }, + { + "id": "4023", + "name": "Monkey talisman", + "examine": "A magic talisman in shape of a monkey head.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1000", + "weight": "1.25" + }, + { + "id": "4024", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4025", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4026", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4027", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4028", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4029", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4030", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4031", + "name": "Monkey greegree", + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4032", + "name": "Dummy", + "examine": "I can train on this", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4034", + "name": "Monkey skull", + "examine": "It's a very ancient skull from some kind of ape.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4035", + "name": "10th squad sigil", + "examine": "It is the official sigil of the 10th squad of the Royal Guard.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2" + }, + { + "id": "4037", + "name": "Saradomin banner", + "examine": "The Holy Team Standard", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "tradeable": "false", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "4038", + "name": "Saradomin banner", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "4039", + "name": "Zamorak banner", + "examine": "The Zamorak team's flag.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "tradeable": "false", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" + }, + { + "id": "4040", + "name": "Zamorak banner", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "4041", + "name": "Hooded cloak", + "examine": "The colours of Saradomin/Zamorak.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "1" + }, + { + "id": "4042", + "name": "Hooded cloak", + "examine": "The colours of Saradomin/Zamorak.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "1" + }, + { + "id": "4044", + "name": "Rock", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4045", + "name": "Explosive potion", + "examine": "I could use this to destroy things...", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4046", + "name": "Explosive potion", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4047", + "name": "Climbing rope", + "examine": "A coil of rope.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4048", + "name": "Climbing rope", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4049", + "name": "Bandages", + "examine": "A box of bandages for healing.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4050", + "name": "Bandages", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4051", + "name": "Toolkit", + "examine": "Good for repairing a broken cannon.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "4052", + "name": "Toolkit", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4053", + "name": "Barricade", + "examine": "Handy for hindering the enemy team's movement.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4054", + "name": "Barricade", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4055", + "name": "Castlewars manual", + "examine": "It's a manual for Castle Wars", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5", + "weight": "1" + }, + { + "id": "4067", + "name": "Castle wars ticket", + "examine": "I can exchange these for further items.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4068", + "name": "Decorative sword", + "examine": "A very decorative sword.", + "archery_ticket_price": "0", + "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,0,0,0", + "castle_wars_ticket_price": "5", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1", + "requirements": "{0,5}", + "run_anim": "824", + "shop_price": "50", + "stand_anim": "808", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1" + }, + { + "id": "4069", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "4069", "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", "castle_wars_ticket_price": "8", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,5}" }, { - "requirements": "{1,5}", - "durability": null, + "id": "4070", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "4070", "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0", "castle_wars_ticket_price": "6", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,5}" }, { + "id": "4071", + "name": "Decorative helm", + "examine": "A very decorative helm.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,3,0,0,0,0", + "castle_wars_ticket_price": "4", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,5}", "shop_price": "40", - "examine": "A very decorative helm.", - "durability": null, - "name": "Decorative helm", - "weight": "1", - "archery_ticket_price": "0", - "id": "4071", - "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,3,0,0,0,0", - "castle_wars_ticket_price": "4", - "equipment_slot": "0" + "weight": "1" }, { - "requirements": "{1,5}", - "shop_price": "60", - "examine": "A very decorative shield.", - "durability": null, - "name": "Decorative shield", - "archery_ticket_price": "0", "id": "4072", + "name": "Decorative shield", + "examine": "A very decorative shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", "castle_wars_ticket_price": "6", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "requirements": "{1,5}", + "shop_price": "60" }, { + "id": "4073", + "name": "Damp tinderbox", "examine": "Not so useful for lighting a fire.", - "durability": null, - "name": "Damp tinderbox", "archery_ticket_price": "0", - "id": "4073" + "durability": null }, { - "durability": null, + "id": "4074", "name": "Damp tinderbox", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4074" + "durability": null, + "tradeable": "true" }, { - "examine": "A bizarre fungus. It glows with a pale blue light.", - "durability": null, + "id": "4075", "name": "Glowing fungus", + "examine": "A bizarre fungus. It glows with a pale blue light.", "archery_ticket_price": "0", - "id": "4075" + "durability": null }, { - "examine": "A key I found in the lower levels of the Morytanian mines. (Haunted Mine) / As the 'Innocent-looking key': A shiny key sitting quietly on a crate.", - "durability": null, + "id": "4077", "name": "Crystal-mine key", + "examine": "A key I found in the lower levels of the Morytanian mines. (Haunted Mine) / As the 'Innocent-looking key': A shiny key sitting quietly on a crate.", "archery_ticket_price": "0", - "id": "4077" + "durability": null }, { - "examine": "I stole this from a Saradominist I met South of Mort'ton.", - "durability": null, + "id": "4078", "name": "Zealot's key", + "examine": "I stole this from a Saradominist I met South of Mort'ton.", "archery_ticket_price": "0", - "id": "4078" + "durability": null }, { - "examine": "A gift from Santa.", - "durability": null, + "id": "4079", "name": "Yo-yo", + "examine": "A gift from Santa.", "archery_ticket_price": "0", - "id": "4079" + "durability": null }, { - "examine": "Increases the wearer's strength and accuracy by 15% when fighting the undead.", - "durability": null, - "name": "Salve amulet", - "weight": "0.6", - "archery_ticket_price": "0", "id": "4081", - "bonuses": "0,0,0,0,0,3,3,3,0,0,3,0,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "An unstrung crystal imbued with the power of Saradomin.", - "durability": null, - "name": "Salve shard", + "name": "Salve amulet", + "examine": "Increases the wearer's strength and accuracy by 15% when fighting the undead.", "archery_ticket_price": "0", - "id": "4082" + "bonuses": "0,0,0,0,0,3,3,3,0,0,3,0,3,0,0", + "durability": null, + "equipment_slot": "2", + "weight": "0.6" }, { - "examine": "Unwaxed: It needs waxing before I can use it. Waxed: A waxed sled.", - "durability": null, + "id": "4082", + "name": "Salve shard", + "examine": "An unstrung crystal imbued with the power of Saradomin.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4083", "name": "Sled", + "examine": "Unwaxed: It needs waxing before I can use it. Waxed: A waxed sled.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4083", + "durability": null, "equipment_slot": "3" }, { - "turn90cw_anim": "1468", - "examine": "Unwaxed: It needs waxing before I can use it. Waxed: A waxed sled.", - "walk_anim": "1468", - "durability": null, - "turn90ccw_anim": "1468", - "attack_speed": "4", - "two_handed": "true", - "turn180_anim": "1468", - "render_anim": "1119", - "equipment_slot": "3", - "stand_anim": "1461", - "name": "Sled", - "run_anim": "1468", - "archery_ticket_price": "0", "id": "4084", - "stand_turn_anim": "1468" + "name": "Sled", + "examine": "Unwaxed: It needs waxing before I can use it. Waxed: A waxed sled.", + "archery_ticket_price": "0", + "attack_speed": "4", + "durability": null, + "equipment_slot": "3", + "render_anim": "1119", + "run_anim": "1468", + "stand_anim": "1461", + "stand_turn_anim": "1468", + "turn180_anim": "1468", + "turn90ccw_anim": "1468", + "turn90cw_anim": "1468", + "two_handed": "true", + "walk_anim": "1468" }, { - "examine": "I can use this to wax my sled.", - "durability": null, - "name": "Wax", - "archery_ticket_price": "0", "id": "4085", + "name": "Wax", + "examine": "I can use this to wax my sled.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "5" }, { - "examine": "These pale flowers have a pungent odour.", - "durability": null, + "id": "4086", "name": "Trollweiss", + "examine": "These pale flowers have a pungent odour.", "archery_ticket_price": "0", "attack_speed": "5", - "id": "4086", - "weapon_interface": "12", "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", - "equipment_slot": "3" + "durability": null, + "equipment_slot": "3", + "weapon_interface": "12" }, { - "requirements": "{1,60}", - "ge_buy_limit": "10", - "examine": "Looks pretty heavy.", - "durability": null, - "weight": "9", - "absorb": "3,0,6", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "190500", - "name": "Dragon platelegs", - "tradeable": "true", - "archery_ticket_price": "0", "id": "4087", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "190500", - "durability": null, "name": "Dragon platelegs", - "tradeable": "true", + "examine": "Looks pretty heavy.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "4088" + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "9" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "15000", - "ge_buy_limit": "100", - "examine": "Blue: A magical hat. ", - "durability": null, - "weight": "0.4", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "13700", - "name": "Mystic hat", - "tradeable": "true", + "id": "4088", + "name": "Dragon platelegs", "archery_ticket_price": "0", - "hat": true, + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4089", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "13700", - "durability": null, "name": "Mystic hat", - "tradeable": "true", + "examine": "Blue: A magical hat. ", + "absorb": "3,1,0", "archery_ticket_price": "0", - "id": "4090" + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": true, + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "tradeable": "true", + "weight": "0.4" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "120000", - "ge_buy_limit": "100", - "examine": "The upper half of a magical robe.", - "durability": null, - "weight": "2.7", - "absorb": "3,1,0", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "72100", - "name": "Mystic robe top", - "tradeable": "true", + "id": "4090", + "name": "Mystic hat", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4091", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "72100", - "durability": null, "name": "Mystic robe top", - "tradeable": "true", + "examine": "The upper half of a magical robe.", + "absorb": "3,1,0", "archery_ticket_price": "0", - "id": "4092" + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "tradeable": "true", + "weight": "2.7" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "80000", - "ge_buy_limit": "100", - "examine": "The lower half of a magical robe.", - "durability": null, - "absorb": "4,2,0", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "47700", - "name": "Mystic robe bottom", - "tradeable": "true", + "id": "4092", + "name": "Mystic robe top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4093", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "47700", - "durability": null, "name": "Mystic robe bottom", - "tradeable": "true", + "examine": "The lower half of a magical robe.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "4094" + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "tradeable": "true" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "Magical gloves.", - "durability": null, - "weight": "0.4", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "5913", - "name": "Mystic gloves", - "tradeable": "true", + "id": "4094", + "name": "Mystic robe bottom", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4095", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5913", - "durability": null, "name": "Mystic gloves", - "tradeable": "true", + "examine": "Magical gloves.", "archery_ticket_price": "0", - "id": "4096" - }, - { + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "lendable": "true", "requirements": "{1,20}-{6,40}", "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "Magical boots.", - "durability": null, - "weight": "0.4", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "6303", - "name": "Mystic boots", "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4096", + "name": "Mystic gloves", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4097", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6303", - "durability": null, "name": "Mystic boots", - "tradeable": "true", + "examine": "Magical boots.", "archery_ticket_price": "0", - "id": "4098" + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "tradeable": "true", + "weight": "0.4" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "15000", - "ge_buy_limit": "100", - "examine": "Black: A magical hat. ", - "durability": null, - "weight": "0.4", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "16700", - "name": "Mystic hat", - "tradeable": "true", + "id": "4098", + "name": "Mystic boots", "archery_ticket_price": "0", - "hat": true, + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4099", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "16700", - "durability": null, "name": "Mystic hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4100" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "120000", - "ge_buy_limit": "100", - "examine": "The upper half of a magical robe.", - "durability": null, - "weight": "2.7", + "examine": "Black: A magical hat. ", "absorb": "3,1,0", - "equipment_slot": "4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": true, "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "75100", - "name": "Mystic robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4101", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "75100", - "durability": null, - "name": "Mystic robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4102" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "80000", - "ge_buy_limit": "100", - "examine": "The lower half of a magical robe.", - "durability": null, - "absorb": "4,2,0", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "50700", - "name": "Mystic robe bottom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4103", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "50700", - "durability": null, - "name": "Mystic robe bottom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4104" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "Dark magical gloves.", - "durability": null, - "weight": "0.4", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "8913", - "name": "Mystic gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4105", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8913", - "durability": null, - "name": "Mystic gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4106" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "Magical boots.", - "durability": null, - "weight": "0.4", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "9303", - "name": "Mystic boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4107", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9303", - "durability": null, - "name": "Mystic boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4108" - }, - { "requirements": "{1,20}-{6,40}", "shop_price": "15000", - "ge_buy_limit": "100", - "examine": "White: A magical hat. ", - "durability": null, - "weight": "0.4", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "16700", - "name": "Mystic hat", "tradeable": "true", - "archery_ticket_price": "0", - "hat": true, - "id": "4109", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "16700", - "durability": null, + "id": "4100", "name": "Mystic hat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4110" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "120000", - "ge_buy_limit": "100", + "id": "4101", + "name": "Mystic robe top", "examine": "The upper half of a magical robe.", - "durability": null, - "weight": "2.7", "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "durability": null, "equipment_slot": "4", + "ge_buy_limit": "100", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "75100", - "name": "Mystic robe top", + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4111", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "75100", + "id": "4102", + "name": "Mystic robe top", + "archery_ticket_price": "0", "durability": null, - "name": "Mystic robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4112" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "4103", + "name": "Mystic robe bottom", + "examine": "The lower half of a magical robe.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", "requirements": "{1,20}-{6,40}", "shop_price": "80000", - "ge_buy_limit": "100", - "examine": "The lower half of a magical robe.", - "durability": null, - "absorb": "4,2,0", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "50700", - "name": "Mystic robe bottom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4113", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "50700", - "durability": null, + "id": "4104", "name": "Mystic robe bottom", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4114" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,20}-{6,40}", - "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "Bright magical gloves.", + "id": "4105", + "name": "Mystic gloves", + "examine": "Dark magical gloves.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", "durability": null, - "weight": "0.4", "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "8913", - "name": "Mystic gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4115", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "8913", - "durability": null, - "name": "Mystic gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4116" - }, - { + "lendable": "true", "requirements": "{1,20}-{6,40}", "shop_price": "10000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4106", + "name": "Mystic gloves", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4107", + "name": "Mystic boots", "examine": "Magical boots.", - "durability": null, - "weight": "0.4", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "9303", - "name": "Mystic boots", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4108", + "name": "Mystic boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4109", + "name": "Mystic hat", + "examine": "White: A magical hat. ", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": true, + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4110", + "name": "Mystic hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4111", + "name": "Mystic robe top", + "examine": "The upper half of a magical robe.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "4112", + "name": "Mystic robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4113", + "name": "Mystic robe bottom", + "examine": "The lower half of a magical robe.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "tradeable": "true" + }, + { + "id": "4114", + "name": "Mystic robe bottom", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4115", + "name": "Mystic gloves", + "examine": "Bright magical gloves.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4116", + "name": "Mystic gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4117", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9303", - "durability": null, "name": "Mystic boots", - "tradeable": "true", + "examine": "Magical boots.", "archery_ticket_price": "0", - "id": "4118" - }, - { - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "grand_exchange_price": "359", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", "durability": null, - "name": "Bronze boots", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4119", - "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "359", - "durability": null, - "name": "Bronze boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4120" - }, - { - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "grand_exchange_price": "17000", - "durability": null, - "name": "Iron boots", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4121", - "bonuses": "0,0,0,-3,-1,2,3,4,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "17000", - "durability": null, - "name": "Iron boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4122" - }, - { - "requirements": "{1,5}", - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "grand_exchange_price": "258", - "durability": null, - "name": "Steel boots", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4123", - "bonuses": "0,0,0,-3,-1,5,6,7,0,0,5,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "258", - "durability": null, - "name": "Steel boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4124" - }, - { - "requirements": "{1,10}", - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "grand_exchange_price": "317", - "durability": null, - "name": "Black boots", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4125", - "bonuses": "0,0,0,-3,-1,7,8,9,0,0,7,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "317", - "durability": null, - "name": "Black boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4126" - }, - { - "requirements": "{1,20}", - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "grand_exchange_price": "580", - "durability": null, - "name": "Mithril boots", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4127", - "bonuses": "0,0,0,-3,-1,8,9,10,0,0,8,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "580", - "durability": null, - "name": "Mithril boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4128" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "grand_exchange_price": "1336", - "durability": null, - "name": "Adamant boots", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4129", - "bonuses": "0,0,0,-3,-1,10,11,12,0,0,9,1,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1336", - "durability": null, - "name": "Adamant boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4130" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "durability": null, - "weight": "1.3", "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "7474", - "name": "Rune boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4131", - "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "7474", - "durability": null, - "name": "Rune boots", + "lendable": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4132" + "weight": "0.4" }, { + "id": "4118", + "name": "Mystic boots", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4119", + "name": "Bronze boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "4120", + "name": "Bronze boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4121", + "name": "Iron boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,2,3,4,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "4122", + "name": "Iron boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4123", + "name": "Steel boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,5,6,7,0,0,5,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "requirements": "{1,5}", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "4124", + "name": "Steel boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4125", + "name": "Black boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,9,0,0,7,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "4126", + "name": "Black boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4127", + "name": "Mithril boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,8,9,10,0,0,8,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "requirements": "{1,20}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "4128", + "name": "Mithril boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4129", + "name": "Adamant boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,10,11,12,0,0,9,1,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "4130", + "name": "Adamant boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4131", + "name": "Rune boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "4132", + "name": "Rune boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4133", "name": "Crawling hand", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4133" + "durability": null }, { - "examine": "A spiky crawling critter. (level 23) Not very tasty-looking. (level 138)", - "durability": null, + "id": "4134", "name": "Cave crawler", + "examine": "A spiky crawling critter. (level 23) Not very tasty-looking. (level 138)", "archery_ticket_price": "0", "attack_speed": "3", - "id": "4134" + "durability": null }, { - "examine": "A tortured screaming soul.", - "durability": null, + "id": "4135", "name": "Banshee", + "examine": "A tortured screaming soul.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4135" + "durability": null }, { - "examine": "The slime of evil.", - "durability": null, + "id": "4136", "name": "Rockslug", + "examine": "The slime of evil.", "archery_ticket_price": "0", - "id": "4136" + "durability": null }, { - "examine": "The winged reptile.", - "durability": null, + "id": "4137", "name": "Cockatrice", + "examine": "The winged reptile.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4137" + "durability": null }, { - "examine": "A small fire demon.", - "durability": null, + "id": "4138", "name": "Pyrefiend", + "examine": "A small fire demon.", "archery_ticket_price": "0", - "id": "4138" + "durability": null }, { - "examine": "The eyes of evil.", - "durability": null, + "id": "4139", "name": "Basilisk", + "examine": "The eyes of evil.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4139" + "durability": null }, { - "examine": "An evil magic user.", - "durability": null, + "id": "4140", "name": "Infernal mage", + "examine": "An evil magic user.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4140" + "durability": null }, { - "examine": "The tongue of evil.", - "durability": null, + "id": "4141", "name": "Bloodveld", + "examine": "The tongue of evil.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4141" + "durability": null }, { - "examine": "• Needs cream.....• Wibbly.• Wobbly...• There's always room for jelly.• Doesn't look so tough...• Looks scared to see me.", - "durability": null, + "id": "4142", "name": "Jelly", + "examine": "• Needs cream.....• Wibbly.• Wobbly...• There's always room for jelly.• Doesn't look so tough...• Looks scared to see me.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4142" + "durability": null }, { - "durability": null, + "id": "4143", "name": "Turoth", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4143" + "durability": null }, { - "examine": "A very smelly ghost.", - "durability": null, + "id": "4144", "name": "Abberant spectre", + "examine": "A very smelly ghost.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4144" + "durability": null }, { - "examine": "The vacuumed face of evil.", - "durability": null, + "id": "4145", "name": "Dust devil", + "examine": "The vacuumed face of evil.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4145" + "durability": null }, { - "durability": null, + "id": "4146", "name": "Kurask", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4146" + "durability": null }, { - "examine": "Flies like a rock.", - "durability": null, + "id": "4147", "name": "Gargoyle", + "examine": "Flies like a rock.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4147" + "durability": null }, { - "durability": null, + "id": "4148", "name": "Nechryael", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4148" + "durability": null }, { - "examine": "A denizen of the Abyss!", - "durability": null, + "id": "4149", "name": "Abyssal demon", + "examine": "A denizen of the Abyss!", "archery_ticket_price": "0", "attack_speed": "4", - "id": "4149" + "durability": null }, { - "shop_price": "90", - "examine": "Arrows with a wider than normal tip.", - "durability": null, - "name": "Broad arrows", - "archery_ticket_price": "0", "id": "4150", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,28,0,0" + "name": "Broad arrows", + "examine": "Arrows with a wider than normal tip.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,28,0,0", + "durability": null, + "shop_price": "90" }, { - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A weapon from the Abyss.", - "walk_anim": "1660", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "1659", - "equipment_slot": "3", - "attack_anims": "1658,1658,1658,1658", - "grand_exchange_price": "413500", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "1661", - "archery_ticket_price": "0", "id": "4151", - "stand_turn_anim": "823", - "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0", - "requirements": "{0,70}", - "durability": null, - "weight": "0.45", - "weapon_interface": "11", - "equip_audio": "2249", - "render_anim": "620", - "lendable": "true", - "attack_audios": "2720,0,0,0", - "name": "Abyssal whip" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "413500", - "durability": null, "name": "Abyssal whip", - "tradeable": "true", + "examine": "A weapon from the Abyss.", "archery_ticket_price": "0", - "id": "4152" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1663", - "examine": "Simplicity is the best weapon.", - "walk_anim": "1663", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "1663", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1663", - "defence_anim": "1666", + "attack_anims": "1658,1658,1658,1658", + "attack_audios": "2720,0,0,0", + "attack_speed": "4", + "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0", + "defence_anim": "1659", + "durability": null, + "equip_audio": "2249", "equipment_slot": "3", - "attack_anims": "1665,1665,1665,1665", - "grand_exchange_price": "29900", - "stand_anim": "1662", - "tradeable": "true", - "run_anim": "1664", - "archery_ticket_price": "0", - "id": "4153", - "stand_turn_anim": "823", - "bonuses": "0,0,81,0,0,0,0,0,0,0,0,79,0,0,0", - "requirements": "{0,50}-{2,50}", - "durability": null, - "weight": "4.5", - "weapon_interface": "10", - "render_anim": "27", - "lendable": "true", - "attack_audios": "2714,0,0,0", - "name": "Granite maul" - }, - { "ge_buy_limit": "10", - "grand_exchange_price": "29900", - "durability": null, - "name": "Granite maul", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "620", + "requirements": "{0,70}", + "run_anim": "1661", + "stand_anim": "808", + "stand_turn_anim": "823", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4154" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1660", + "weapon_interface": "11", + "weight": "0.45" }, { - "shop_price": "1", - "examine": "I can contact the Slayer Masters with this.", + "id": "4152", + "name": "Abyssal whip", + "archery_ticket_price": "0", "durability": null, - "name": "Enchanted gem", - "archery_ticket_price": "0", - "id": "4155" + "ge_buy_limit": "10", + "tradeable": "true" }, { + "id": "4153", + "name": "Granite maul", + "examine": "Simplicity is the best weapon.", + "archery_ticket_price": "0", + "attack_anims": "1665,1665,1665,1665", + "attack_audios": "2714,0,0,0", + "attack_speed": "7", + "bonuses": "0,0,81,0,0,0,0,0,0,0,0,79,0,0,0", + "defence_anim": "1666", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "27", + "requirements": "{0,50}-{2,50}", + "run_anim": "1664", + "stand_anim": "1662", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1663", + "turn90ccw_anim": "1663", + "turn90cw_anim": "1663", + "two_handed": "true", + "walk_anim": "1663", + "weapon_interface": "10", + "weight": "4.5" + }, + { + "id": "4154", + "name": "Granite maul", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4155", + "name": "Enchanted gem", + "examine": "I can contact the Slayer Masters with this.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "4156", + "name": "Mirror shield", + "examine": "I can just about see things in this shield's reflection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,5,5,10,5,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", "requirements": "{1,20}-{18,25}", "shop_price": "5000", - "ge_buy_limit": "100", - "examine": "I can just about see things in this shield's reflection.", - "durability": null, - "weight": "2.2", - "equipment_slot": "5", - "grand_exchange_price": "3318", - "name": "Mirror shield", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4156", - "bonuses": "0,0,0,0,0,10,15,5,5,10,5,0,0,0,0" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3318", - "durability": null, + "id": "4157", "name": "Mirror shield", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4157" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,55}-{18,50}", - "shop_price": "31000", - "turn90cw_anim": "1207", - "examine": "A spear with a leaf-shaped point.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "stand_anim": "813", - "name": "Leaf-bladed spear", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4158", + "name": "Leaf-bladed spear", + "examine": "A spear with a leaf-shaped point.", + "alchemizable": "true", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "47,42,36,0,0,1,1,0,0,0,0,50,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,55}-{18,50}", + "run_anim": "1210", + "shop_price": "31000", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "47,42,36,0,0,1,1,0,0,0,0,50,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" }, { - "requirements": "{0,55}-{18,50}", - "shop_price": "31000", - "examine": "A spear with a leaf-shaped point.", - "durability": null, + "id": "4159", "name": "Leaf-bladed spear", - "weight": "2", + "examine": "A spear with a leaf-shaped point.", "archery_ticket_price": "0", "attack_speed": "5", - "id": "4159", - "equipment_slot": "3" + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "requirements": "{0,55}-{18,50}", + "shop_price": "31000", + "weight": "2" }, { - "requirements": "{18,55}-{4,50}", - "shop_price": "90", - "examine": "Arrows with a wider than normal tip.", - "durability": null, - "name": "Broad arrow", - "archery_ticket_price": "0", "id": "4160", + "name": "Broad arrow", + "examine": "Arrows with a wider than normal tip.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "requirements": "{18,55}-{4,50}", + "shop_price": "90" }, { - "shop_price": "10", - "ge_buy_limit": "100", - "examine": "A bag of salt.", - "grand_exchange_price": "1", - "durability": null, + "id": "4161", "name": "Bag of salt", - "tradeable": "true", + "examine": "A bag of salt.", "archery_ticket_price": "0", - "id": "4161" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "10", + "tradeable": "true" }, { - "shop_price": "500", - "ge_buy_limit": "100", - "examine": "I can even smash stone with this.", - "grand_exchange_price": "140", - "durability": null, - "name": "Rock hammer", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", "id": "4162", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "140", - "durability": null, "name": "Rock hammer", - "tradeable": "true", + "examine": "I can even smash stone with this.", "archery_ticket_price": "0", - "id": "4163" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "500", + "tradeable": "true", + "weight": "2.2" }, { + "id": "4163", + "name": "Rock hammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4164", + "name": "Face mask", + "examine": "Stops me breathing in too much dust.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "requirements": "{18,10}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "Stops me breathing in too much dust.", - "grand_exchange_price": "615", - "durability": null, - "name": "Face mask", "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "4164", - "equipment_slot": "0" + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "615", - "durability": null, + "id": "4165", "name": "Face mask", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4165" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "4166", + "name": "Earmuffs", + "examine": "These will protect my ears from loud noise.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "requirements": "{18,15}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "These will protect my ears from loud noise.", - "grand_exchange_price": "484", - "durability": null, - "name": "Earmuffs", "tradeable": "true", - "weight": "2.6", - "archery_ticket_price": "0", - "id": "4166", - "equipment_slot": "0" + "weight": "2.6" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "484", - "durability": null, + "id": "4167", "name": "Earmuffs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4167" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "4168", + "name": "Nose peg", + "examine": "Protects me from any bad smells.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "requirements": "{18,60}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "Protects me from any bad smells.", - "grand_exchange_price": "523", - "durability": null, - "name": "Nose peg", "tradeable": "true", - "weight": "8", - "archery_ticket_price": "0", - "id": "4168", - "equipment_slot": "0" + "weight": "8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "523", - "durability": null, + "id": "4169", "name": "Nose peg", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4169" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An old and magical staff.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "12100", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4170", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,12,0,2,3,1,10,0,0,35,0,0,0", - "requirements": "{18,55}-{6,50}", - "shop_price": "21000", - "durability": null, - "weight": "1.8", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Slayer's staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12100", - "durability": null, "name": "Slayer's staff", - "tradeable": "true", + "examine": "An old and magical staff.", "archery_ticket_price": "0", - "id": "4171" - }, - { - "shop_price": "90", - "examine": "Arrows with a wider than normal tip.", - "durability": null, - "name": "Broad arrows", - "archery_ticket_price": "0", - "id": "4172", - "equipment_slot": "13" - }, - { - "shop_price": "90", - "examine": "Arrows with a wider than normal tip.", - "durability": null, - "name": "Broad arrows", - "archery_ticket_price": "0", - "id": "4173", - "equipment_slot": "13" - }, - { - "shop_price": "90", - "examine": "Arrows with a wider than normal tip.", - "durability": null, - "name": "Broad arrows", - "archery_ticket_price": "0", - "id": "4174", - "equipment_slot": "13" - }, - { - "shop_price": "90", - "examine": "Arrows with a wider than normal tip.", - "durability": null, - "name": "Broad arrows", - "archery_ticket_price": "0", - "id": "4175", - "equipment_slot": "13" - }, - { - "examine": "A weapon from the Abyss.", - "rare_item": "true", - "durability": null, - "weight": "0.45", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", "attack_speed": "4", - "render_anim": "620", - "lendable": "true", - "grand_exchange_price": "388392", - "name": "Abyssal whip", + "bonuses": "7,-1,25,12,0,2,3,1,10,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{18,55}-{6,50}", + "run_anim": "1210", + "shop_price": "21000", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4178", - "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "1.8" }, { - "examine": "A big, bad troll.", + "id": "4171", + "name": "Slayer's staff", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4172", + "name": "Broad arrows", + "examine": "Arrows with a wider than normal tip.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "13", + "shop_price": "90" + }, + { + "id": "4173", + "name": "Broad arrows", + "examine": "Arrows with a wider than normal tip.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "13", + "shop_price": "90" + }, + { + "id": "4174", + "name": "Broad arrows", + "examine": "Arrows with a wider than normal tip.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "13", + "shop_price": "90" + }, + { + "id": "4175", + "name": "Broad arrows", + "examine": "Arrows with a wider than normal tip.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "13", + "shop_price": "90" + }, + { + "id": "4178", + "name": "Abyssal whip", + "examine": "A weapon from the Abyss.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0", + "durability": null, + "lendable": "true", + "rare_item": "true", + "render_anim": "620", + "tradeable": "true", + "weight": "0.45" + }, + { + "id": "4179", "name": "Stick", + "examine": "A big, bad troll.", "archery_ticket_price": "0", "attack_speed": "6", - "id": "4179" + "durability": null }, { - "lendable": "true", - "examine": "Looks pretty heavy.", - "grand_exchange_price": "165900", - "durability": null, - "name": "Dragon platelegs", - "tradeable": "true", - "weight": "9", - "archery_ticket_price": "0", "id": "4180", + "name": "Dragon platelegs", + "examine": "Looks pretty heavy.", "absorb": "3,0,6", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "durability": null, + "lendable": "true", + "tradeable": "true", + "weight": "9" }, { - "durability": null, + "id": "4181", "name": "Mouth grip", "archery_ticket_price": "0", - "id": "4181", + "durability": null, "equipment_slot": "3" }, { - "examine": "A pale, tough looking herb.", - "durability": null, + "id": "4182", "name": "Goutweed", + "examine": "A pale, tough looking herb.", "archery_ticket_price": "0", - "id": "4182" + "durability": null }, { - "examine": "A six-pointed marble and obsidian amulet", - "durability": null, + "id": "4183", "name": "Star amulet", + "examine": "A six-pointed marble and obsidian amulet", "archery_ticket_price": "0", - "id": "4183" + "durability": null }, { - "examine": "Upon close examination, this seems to be a key.", - "durability": null, + "id": "4184", "name": "Cavern key", + "examine": "Upon close examination, this seems to be a key.", "archery_ticket_price": "0", - "id": "4184" + "durability": null }, { - "examine": "Upon close examination, this seems to be a key.", - "durability": null, + "id": "4185", "name": "Tower key", - "archery_ticket_price": "0", - "id": "4185" - }, - { "examine": "Upon close examination, this seems to be a key.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4186", "name": "Shed key", + "examine": "Upon close examination, this seems to be a key.", "archery_ticket_price": "0", - "id": "4186" + "durability": null }, { - "examine": "Triangular in shape, made from marble, and as large as your hand.", - "durability": null, + "id": "4187", "name": "Marble amulet", + "examine": "Triangular in shape, made from marble, and as large as your hand.", "archery_ticket_price": "0", - "id": "4187" + "durability": null }, { - "examine": "Triangular in shape, made from obsidian, and as large as your hand.", - "durability": null, + "id": "4188", "name": "Obsidian amulet", + "examine": "Triangular in shape, made from obsidian, and as large as your hand.", "archery_ticket_price": "0", - "id": "4188" + "durability": null }, { - "examine": "A length of garden cane.", - "durability": null, + "id": "4189", "name": "Garden cane", - "weight": "0.1", + "examine": "A length of garden cane.", "archery_ticket_price": "0", - "id": "4189" + "durability": null, + "weight": "0.1" }, { - "examine": "A typical garden brush.", - "durability": null, + "id": "4190", "name": "Garden brush", - "weight": "1", + "examine": "A typical garden brush.", "archery_ticket_price": "0", - "id": "4190" + "durability": null, + "weight": "1" }, { + "id": "4191", + "name": "Extended brush", "examine": "A typical garden brush, with a cane tied to it.", - "durability": null, - "name": "Extended brush", - "weight": "1", "archery_ticket_price": "0", - "id": "4191" + "durability": null, + "weight": "1" }, { + "id": "4192", + "name": "Extended brush", "examine": "A typical garden brush, with two canes tied to it.", - "durability": null, - "name": "Extended brush", - "weight": "1", "archery_ticket_price": "0", - "id": "4192" + "durability": null, + "weight": "1" }, { - "examine": "A typical garden brush, with three canes tied to it.", - "durability": null, - "name": "Extended brush", - "weight": "1", - "archery_ticket_price": "0", "id": "4193", - "equipment_slot": "3" + "name": "Extended brush", + "examine": "A typical garden brush, with three canes tied to it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1" }, { - "examine": "A pair of limp, dead arms.", - "durability": null, - "name": "Arms", - "weight": "2", - "archery_ticket_price": "0", "id": "4195", - "alchemizable": "true" + "name": "Arms", + "examine": "A pair of limp, dead arms.", + "alchemizable": "true", + "archery_ticket_price": "0", + "durability": null, + "weight": "2" }, { - "examine": "A pair of lifeless, rotting legs.", - "durability": null, - "name": "Legs", - "archery_ticket_price": "0", "id": "4196", - "alchemizable": "true" + "name": "Legs", + "examine": "A pair of lifeless, rotting legs.", + "alchemizable": "true", + "archery_ticket_price": "0", + "durability": null }, { - "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", - "durability": null, - "name": "Decapitated head", - "weight": "3", - "archery_ticket_price": "0", "id": "4197", - "alchemizable": "true" - }, - { - "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", - "durability": null, "name": "Decapitated head", - "weight": "3", + "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", + "alchemizable": "true", "archery_ticket_price": "0", + "durability": null, + "weight": "3" + }, + { "id": "4198", - "alchemizable": "true" + "name": "Decapitated head", + "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", + "alchemizable": "true", + "archery_ticket_price": "0", + "durability": null, + "weight": "3" }, { - "shop_price": "50", - "examine": "A pickled brain, submerged inside a jar of vinegar.", - "durability": null, - "name": "Pickled brain", - "archery_ticket_price": "0", "id": "4199", - "alchemizable": "true" + "name": "Pickled brain", + "examine": "A pickled brain, submerged inside a jar of vinegar.", + "alchemizable": "true", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "50" }, { - "examine": "A mould for making silver lightning conductors.", - "durability": null, + "id": "4200", "name": "Conductor mould", + "examine": "A mould for making silver lightning conductors.", "archery_ticket_price": "0", - "id": "4200" + "durability": null }, { - "examine": "A silver lightning conductor.", - "durability": null, + "id": "4201", "name": "Conductor", - "weight": "4", + "examine": "A silver lightning conductor.", "archery_ticket_price": "0", - "id": "4201" + "durability": null, + "weight": "4" }, { - "destroy_message": "Another can be received from pickpocketing Dr. Fenkenstrain in the tower.", - "examine": "Unactivated: The Ring of charos.Activated: The power within this ring has been activated.", - "durability": null, - "name": "Ring of charos", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "4202", - "equipment_slot": "12" - }, - { - "examine": "This consecration seed looks grey and dead.", - "durability": null, - "name": "Consecration seed", + "name": "Ring of charos", + "examine": "The Ring of charos", "archery_ticket_price": "0", - "id": "4205" - }, - { - "examine": "This consecration seed looks grey and dead.", + "destroy": "true", + "destroy_message": "Another can be received from pickpocketing Dr. Fenkenstrain in the tower.", "durability": null, - "name": "Consecration seed", - "archery_ticket_price": "0", - "id": "4206" + "equipment_slot": "12", + "tradeable": "false" }, { - "ge_buy_limit": "10", + "id": "4205", + "name": "Consecration seed", + "examine": "This consecration seed looks grey and dead.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4206", + "name": "Consecration seed", + "examine": "This consecration seed looks grey and dead.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4207", + "name": "Crystal seed", "examine": "This crystal seed looks grey and dead.", - "grand_exchange_price": "92600", - "durability": null, - "name": "Crystal seed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4207" - }, - { + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "92600", - "durability": null, - "name": "Crystal seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4208" + "tradeable": "true" }, { - "examine": "A book on Cadarn clan history.", + "id": "4208", + "name": "Crystal seed", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4209", "name": "Cadarn lineage", + "examine": "A book on Cadarn clan history.", "archery_ticket_price": "0", - "id": "4209" + "durability": null }, { - "requirements": "{4,70}-{16,50}", - "shop_price": "900000", - "ge_buy_limit": "10", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "905300", - "attack_audios": "2700,0,0,0", - "name": "New crystal bow", - "tradeable": "true", - "archery_ticket_price": "0", "id": "4212", - "bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "905300", - "durability": null, "name": "New crystal bow", - "tradeable": "true", + "examine": "A nice sturdy magical bow.", "archery_ticket_price": "0", - "id": "4213" - }, - { + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow full", + "weight": "1.8" + }, + { + "id": "4213", + "name": "New crystal bow", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4214", - "bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" - }, - { + "name": "Crystal bow full", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 9/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4215", - "bonuses": "0,0,0,0,96,0,0,0,0,0,0,0,0,0,68" - }, - { + "name": "Crystal bow 9/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,96,0,0,0,0,0,0,0,0,0,68", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 8/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4216", - "bonuses": "0,0,0,0,92,0,0,0,0,0,0,0,0,0,66" - }, - { + "name": "Crystal bow 8/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,92,0,0,0,0,0,0,0,0,0,66", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 7/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4217", - "bonuses": "0,0,0,0,88,0,0,0,0,0,0,0,0,0,64" - }, - { + "name": "Crystal bow 7/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,88,0,0,0,0,0,0,0,0,0,64", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 6/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4218", - "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,62" - }, - { + "name": "Crystal bow 6/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,62", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 5/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4219", - "bonuses": "0,0,0,0,80,0,0,0,0,0,0,0,0,0,60" - }, - { + "name": "Crystal bow 5/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,80,0,0,0,0,0,0,0,0,0,60", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 4/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4220", - "bonuses": "0,0,0,0,76,0,0,0,0,0,0,0,0,0,58" - }, - { + "name": "Crystal bow 4/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,76,0,0,0,0,0,0,0,0,0,58", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 3/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4221", - "bonuses": "0,0,0,0,72,0,0,0,0,0,0,0,0,0,56" - }, - { + "name": "Crystal bow 3/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,72,0,0,0,0,0,0,0,0,0,56", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 2/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4222", - "bonuses": "0,0,0,0,68,0,0,0,0,0,0,0,0,0,54" - }, - { + "name": "Crystal bow 2/10", + "examine": "A nice sturdy magical bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,68,0,0,0,0,0,0,0,0,0,54", + "defence_anim": "424", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", "requirements": "{4,70}-{16,50}", "shop_price": "900000", - "examine": "A nice sturdy magical bow.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "901019", - "attack_audios": "2700,0,0,0", - "name": "Crystal bow 1/10", - "archery_ticket_price": "0", + "weight": "1.8" + }, + { "id": "4223", - "bonuses": "0,0,0,0,64,0,0,0,0,0,0,0,0,0,52" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "ge_buy_limit": "10", - "examine": "A nice sturdy crystal shield.", - "durability": null, - "weight": "2", - "absorb": "6,0,12", - "equipment_slot": "5", - "grand_exchange_price": "756900", - "name": "New crystal shield", - "tradeable": "true", + "name": "Crystal bow 1/10", + "examine": "A nice sturdy magical bow.", "archery_ticket_price": "0", - "id": "4224", - "bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", + "attack_anims": "426,426,426,426", + "attack_audios": "1352,1352,1352,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,64,0,0,0,0,0,0,0,0,0,52", + "defence_anim": "424", "durability": null, - "name": "Crystal shield full", - "weight": "2", - "archery_ticket_price": "0", - "id": "4225", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 9/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4226", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,49,52,51,0,78,68,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 8/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4227", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,47,50,49,0,76,66,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 7/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4228", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,45,48,47,0,74,65,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 6/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4229", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,43,46,45,0,72,63,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 5/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4230", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,41,44,43,0,70,61,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 4/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4231", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,39,42,41,0,68,59,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 3/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4232", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,37,40,39,0,66,58,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 2/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4233", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,35,38,37,0,64,56,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,70}-{16,50}", - "shop_price": "750000", - "examine": "A nice sturdy crystal shield.", - "grand_exchange_price": "749305", - "durability": null, - "name": "Crystal shield 1/10", - "weight": "2", - "archery_ticket_price": "0", - "id": "4234", - "absorb": "6,0,12", - "bonuses": "0,0,0,-10,-10,33,36,35,0,62,54,0,0,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "New crystal shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4235" - }, - { - "requirements": "{4,5}", - "examine": "This bow has been signed by Robin, Master Bowman.", - "durability": null, - "weight": "2", - "attack_speed": "6", + "equip_audio": "2238", + "equipment_slot": "3", + "render_anim": "2588", + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "equipment_slot": "3", - "name": "Signed oak bow", + "weight": "1.8" + }, + { + "id": "4224", + "name": "New crystal shield", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "4225", + "name": "Crystal shield full", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4226", + "name": "Crystal shield 9/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,49,52,51,0,78,68,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4227", + "name": "Crystal shield 8/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,47,50,49,0,76,66,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4228", + "name": "Crystal shield 7/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,45,48,47,0,74,65,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4229", + "name": "Crystal shield 6/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,43,46,45,0,72,63,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4230", + "name": "Crystal shield 5/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,41,44,43,0,70,61,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4231", + "name": "Crystal shield 4/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,39,42,41,0,68,59,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4232", + "name": "Crystal shield 3/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,37,40,39,0,66,58,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4233", + "name": "Crystal shield 2/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,35,38,37,0,64,56,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4234", + "name": "Crystal shield 1/10", + "examine": "A nice sturdy crystal shield.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,33,36,35,0,62,54,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "weight": "2" + }, + { + "id": "4235", + "name": "New crystal shield", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "4236", - "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0" + "name": "Signed oak bow", + "examine": "This bow has been signed by Robin, Master Bowman.", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "2588", + "requirements": "{4,5}", + "two_handed": "true", + "weapon_interface": "16", + "weight": "2" }, { - "examine": "It's a bowl of water, with some nettles in it.", - "durability": null, + "id": "4237", "name": "Nettle-water", - "weight": "0.9", + "examine": "It's a bowl of water, with some nettles in it.", "archery_ticket_price": "0", - "id": "4237" + "durability": null, + "weight": "0.9" }, { - "examine": "It's a bowl of (milky) nettle tea.", - "durability": null, + "id": "4239", "name": "Nettle tea", - "weight": "0.9", + "examine": "It's a bowl of nettle tea.", "archery_ticket_price": "0", - "id": "4239" + "durability": null, + "weight": "0.9" }, { - "examine": "It's a bowl of (milky) nettle tea.", - "durability": null, + "id": "4240", "name": "Nettle tea", - "weight": "0.9", + "examine": "It's a bowl of milky nettle tea.", "archery_ticket_price": "0", - "id": "4240" + "durability": null, + "weight": "0.9" }, { - "examine": "(In inventory) A handful of nettles (In ground) I better not get stung/I wouldn't like to get stung/I wish I could sting other people/Dock leaves at the ready/These may hurt/nettles sting my leggies(Draynor Village nettles)", - "durability": null, + "id": "4241", "name": "Nettles", + "examine": "A handful of nettles.", "archery_ticket_price": "0", - "id": "4241" + "durability": null }, { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, + "id": "4242", "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", + "examine": "A nice cup of nettle tea.", "archery_ticket_price": "0", - "id": "4242" - }, - { + "durability": null, "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "4243" + "tradeable": "false", + "weight": "0.1" }, { - "examine": "A porcelain cup.", + "id": "4243", + "name": "Cup of tea", + "examine": "A milky cup of nettle tea.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "4244", "name": "Porcelain cup", + "examine": "A porcelain cup.", "archery_ticket_price": "0", - "id": "4244" + "durability": null }, { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, + "id": "4245", "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", + "examine": "Some nettle tea in a porcelain cup.", "archery_ticket_price": "0", - "id": "4245" - }, - { + "durability": null, "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "4246" + "tradeable": "false", + "weight": "0.1" }, { - "examine": "The Robes of Necrovarus.", + "id": "4246", + "name": "Cup of tea", + "examine": "Some milky nettle tea in a porcelain cup.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "4247", "name": "Mystical robes", - "weight": "2.3", + "examine": "The Robes of Necrovarus.", "archery_ticket_price": "0", - "id": "4247" + "durability": null, + "weight": "2.3" }, { - "examine": "The Book of Haricanto.", - "durability": null, + "id": "4248", "name": "Book of haricanto", - "weight": "2", + "examine": "The Book of Haricanto.", "archery_ticket_price": "0", - "id": "4248" + "durability": null, + "weight": "2" }, { - "shop_price": "32", - "examine": "A translation manual.", - "durability": null, + "id": "4249", "name": "Translation manual", - "weight": "1", + "examine": "A translation manual.", "archery_ticket_price": "0", - "id": "4249" + "durability": null, + "shop_price": "32", + "weight": "1" }, { - "examine": "The amulet of ghostspeak glows green from the crone's enchantment.", - "durability": null, - "name": "Ghostspeak amulet", - "archery_ticket_price": "0", "id": "4250", + "name": "Ghostspeak amulet", + "examine": "The amulet of ghostspeak glows green from the crone's enchantment.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "destroy_message": "The Ectophial will smash if you drop it. Velorina can replace it.", - "examine": "The Ectophial.", - "durability": null, + "id": "4251", "name": "Ectophial", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "4251" - }, - { - "destroy_message": "The Ectophial will smash if you drop it. Velorina can replace it.", "examine": "The Ectophial.", + "archery_ticket_price": "0", + "destroy_message": "The Ectophial will smash if you drop it. Velorina can replace it.", "durability": null, + "tradeable": "false" + }, + { + "id": "4252", "name": "Ectophial", - "tradeable": "false", + "examine": "The Ectophial.", "archery_ticket_price": "0", - "id": "4252" - }, - { - "examine": "A small wooden ship. / A small wooden ship with a silk flag.", + "destroy_message": "The Ectophial will smash if you drop it. Velorina can replace it.", "durability": null, - "name": "Model ship", - "archery_ticket_price": "0", - "id": "4253" + "tradeable": "false" }, { + "id": "4253", + "name": "Model ship", "examine": "A small wooden ship. / A small wooden ship with a silk flag.", - "durability": null, - "name": "Model ship", "archery_ticket_price": "0", - "id": "4254" + "durability": null }, { + "id": "4254", + "name": "Model ship", + "examine": "A small wooden ship. / A small wooden ship with a silk flag.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4255", + "name": "Bonemeal", "examine": "A pot of crushed bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4255" + "durability": null, + "weight": "1" }, { + "id": "4256", + "name": "Bonemeal", "examine": "A pot of crushed small ninja monkey bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4256" + "durability": null, + "weight": "1" }, { + "id": "4257", + "name": "Bonemeal", "examine": "A pot of crushed wolf bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4257" + "durability": null, + "weight": "1" }, { + "id": "4258", + "name": "Bonemeal", "examine": "A pot of crushed burnt bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4258" + "durability": null, + "weight": "1" }, { + "id": "4259", + "name": "Bonemeal", "examine": "A pot of crushed burnt jogre bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4259" + "durability": null, + "weight": "1" }, { + "id": "4260", + "name": "Bonemeal", "examine": "A pot of crushed monkey bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4260" + "durability": null, + "weight": "1" }, { + "id": "4261", + "name": "Bonemeal", "examine": "A pot of crushed bat bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4261" + "durability": null, + "weight": "1" }, { + "id": "4262", + "name": "Bonemeal", "examine": "A pot of crushed big bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4262" + "durability": null, + "weight": "1" }, { + "id": "4263", + "name": "Bonemeal", "examine": "A pot of crushed jogre bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4263" + "durability": null, + "weight": "1" }, { + "id": "4264", + "name": "Bonemeal", "examine": "A pot of crushed zogre bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4264" + "durability": null, + "weight": "1" }, { + "id": "4265", + "name": "Bonemeal", "examine": "A pot of crushed shaikahan bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4265" + "durability": null, + "weight": "1" }, { + "id": "4266", + "name": "Bonemeal", "examine": "A pot of crushed baby dragon bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4266" + "durability": null, + "weight": "1" }, { + "id": "4267", + "name": "Bonemeal", "examine": "A pot of crushed wyvern bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4267" + "durability": null, + "weight": "1" }, { + "id": "4268", + "name": "Bonemeal", "examine": "A pot of crushed dragon bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4268" + "durability": null, + "weight": "1" }, { + "id": "4269", + "name": "Bonemeal", "examine": "A pot of crushed [type of bones].", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4269" + "durability": null, + "weight": "1" }, { + "id": "4270", + "name": "Bonemeal", "examine": "A pot of crushed medium ninja monkey bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4270" + "durability": null, + "weight": "1" }, { + "id": "4271", + "name": "Bonemeal", "examine": "A pot of crushed Dagannoth-king bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4271" + "durability": null, + "weight": "1" }, { - "shop_price": "100", - "examine": "A key fashioned from a shard of bone. (Shilo Village)", - "durability": null, + "id": "4272", "name": "Bone key", + "examine": "A key fashioned from a shard of bone. (Shilo Village)", "archery_ticket_price": "0", - "id": "4272" + "durability": null, + "shop_price": "100" }, { - "examine": "A section from some kind of map.", - "durability": null, + "id": "4274", "name": "Map scrap", - "archery_ticket_price": "0", - "id": "4274" - }, - { "examine": "A section from some kind of map.", - "durability": null, - "name": "Map scrap", "archery_ticket_price": "0", - "id": "4275" + "durability": null }, { + "id": "4275", + "name": "Map scrap", "examine": "A section from some kind of map.", - "durability": null, - "name": "Map scrap", "archery_ticket_price": "0", - "id": "4276" + "durability": null }, { - "examine": "A complete treasure map.", - "durability": null, + "id": "4276", + "name": "Map scrap", + "examine": "A section from some kind of map.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4277", "name": "Treasure map", + "examine": "A complete treasure map.", "archery_ticket_price": "0", - "id": "4277" + "durability": null }, { - "examine": "A token with ectoplasm on it.", - "durability": null, + "id": "4278", "name": "Ecto-token", - "tradeable": "false", + "examine": "A token with ectoplasm on it.", "archery_ticket_price": "0", - "id": "4278" + "durability": null, + "tradeable": "false" }, { - "examine": "A scroll of paper containing signatures.", - "durability": null, + "id": "4283", "name": "Petition form", + "examine": "A scroll of paper containing signatures.", "archery_ticket_price": "0", - "id": "4283" + "durability": null }, { - "examine": "Before Ectofuntus: It's a bedsheet.After Ectofuntus: It's an ectoplasm-covered bedsheet.", - "durability": null, - "name": "Bedsheet", - "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", "id": "4284", - "equipment_slot": "0" - }, - { - "examine": "Before Ectofuntus: It's a bedsheet.After Ectofuntus: It's an ectoplasm-covered bedsheet.", - "durability": null, "name": "Bedsheet", - "tradeable": "false", - "weight": "1", + "examine": "Before Ectofuntus: It's a bedsheet.After Ectofuntus: It's an ectoplasm-covered bedsheet.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "1" + }, + { "id": "4285", - "equipment_slot": "0" + "name": "Bedsheet", + "examine": "Before Ectofuntus: It's a bedsheet.After Ectofuntus: It's an ectoplasm-covered bedsheet.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "1" }, { - "examine": "It's a bucket of ectoplasm.", - "durability": null, + "id": "4286", "name": "Bucket of slime", - "weight": "3", + "examine": "It's a bucket of ectoplasm.", "archery_ticket_price": "0", - "id": "4286" + "durability": null, + "weight": "3" }, { + "id": "4287", + "name": "Raw beef", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", "shop_price": "58", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "4288", + "name": "Raw beef", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4289", + "name": "Raw chicken", "examine": "I need to cook this first.", - "grand_exchange_price": "440", - "durability": null, - "name": "Raw beef", - "tradeable": "true", - "weight": "0.3", "archery_ticket_price": "0", - "id": "4287" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "440", - "durability": null, - "name": "Raw beef", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4288" - }, - { "shop_price": "60", - "ge_buy_limit": "1000", - "examine": "I need to cook this first.", - "grand_exchange_price": "263", - "durability": null, + "tradeable": "true", + "weight": "0.15" + }, + { + "id": "4290", "name": "Raw chicken", - "tradeable": "true", - "weight": "0.15", "archery_ticket_price": "0", - "id": "4289" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "263", - "durability": null, - "name": "Raw chicken", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4290" - }, - { - "shop_price": "5", - "ge_buy_limit": "1000", - "examine": "Mmm this looks tasty.", - "grand_exchange_price": "59", - "durability": null, + "id": "4291", "name": "Cooked chicken", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "4291" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "59", - "durability": null, - "name": "Cooked chicken", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4292" - }, - { - "shop_price": "5", - "ge_buy_limit": "1000", "examine": "Mmm this looks tasty.", - "grand_exchange_price": "74", - "durability": null, - "name": "Cooked meat", - "tradeable": "true", - "weight": "0.25", "archery_ticket_price": "0", - "id": "4293" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "74", - "durability": null, - "name": "Cooked meat", + "shop_price": "5", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4294" + "weight": "0.1" }, { - "examine": "A member of the 'Humans Against Monsters' group.", + "id": "4292", + "name": "Cooked chicken", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4293", + "name": "Cooked meat", + "examine": "Mmm this looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "4294", + "name": "Cooked meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4295", "name": "Female h.a.m.", - "archery_ticket_price": "0", - "id": "4295" - }, - { "examine": "A member of the 'Humans Against Monsters' group.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4297", "name": "Male h.a.m.", + "examine": "A member of the 'Humans Against Monsters' group.", "archery_ticket_price": "0", - "id": "4297" + "durability": null }, { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", - "grand_exchange_price": "19", - "durability": null, - "name": "Ham shirt", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", "id": "4298", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, "name": "Ham shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4299" - }, - { - "ge_buy_limit": "100", "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", - "grand_exchange_price": "11", - "durability": null, - "name": "Ham robe", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4300", "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "11", + "id": "4299", + "name": "Ham shirt", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4300", "name": "Ham robe", - "tradeable": "true", + "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", "archery_ticket_price": "0", - "id": "4301" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.9" }, { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "Light-weight head protection and eye shield.", - "grand_exchange_price": "400", - "durability": null, - "name": "Ham hood", - "tradeable": "true", - "weight": "0.4", + "id": "4301", + "name": "Ham robe", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4302", - "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "400", - "durability": null, "name": "Ham hood", - "tradeable": "true", + "examine": "Light-weight head protection and eye shield.", "archery_ticket_price": "0", - "id": "4303" + "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "examine": "A HAM cape.", - "grand_exchange_price": "25", - "durability": null, - "name": "Ham cloak", - "tradeable": "true", - "weight": "0.4", + "id": "4303", + "name": "Ham hood", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4304", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "25", - "durability": null, "name": "Ham cloak", - "tradeable": "true", + "examine": "A HAM cape.", "archery_ticket_price": "0", - "id": "4305" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "examine": "A badge for the HAM cult.", - "grand_exchange_price": "63", - "durability": null, - "name": "H.a.m logo", - "tradeable": "true", + "id": "4305", + "name": "Ham cloak", "archery_ticket_price": "0", - "weight": "0.5", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4306", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "63", - "durability": null, "name": "H.a.m logo", - "tradeable": "true", + "examine": "A badge for the HAM cult.", "archery_ticket_price": "0", - "id": "4307" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "10", - "examine": "Gloves worn by the Humans Against Monsters group.", - "grand_exchange_price": "59", - "durability": null, - "name": "Gloves", - "tradeable": "true", - "weight": "0.4", + "id": "4307", + "name": "H.a.m logo", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4308", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "59", - "durability": null, "name": "Gloves", - "tradeable": "true", + "examine": "Gloves worn by the Humans Against Monsters group.", "archery_ticket_price": "0", - "id": "4309" + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "examine": "Boots worn by the Humans Against Monsters group.", - "grand_exchange_price": "323", - "durability": null, - "name": "Boots", - "tradeable": "true", - "weight": "0.4", + "id": "4309", + "name": "Gloves", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4310", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "323", - "durability": null, "name": "Boots", - "tradeable": "true", + "examine": "Boots worn by the Humans Against Monsters group.", "archery_ticket_price": "0", - "id": "4311" + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "", + "equipment_slot": "10", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.4" }, { - "examine": "A book on elven crystal.", + "id": "4311", + "name": "Boots", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4313", "name": "Crystal of seren", - "tradeable": "true", + "examine": "A book on elven crystal.", "archery_ticket_price": "0", - "id": "4313" + "durability": null, + "tradeable": "true" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "2342", - "durability": null, - "name": "Team-1 cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", "id": "4315", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2342", - "durability": null, "name": "Team-1 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4316" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1145", - "durability": null, - "name": "Team-2 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4316", + "name": "Team-1 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4317", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1145", - "durability": null, "name": "Team-2 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4318" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "141", - "durability": null, - "name": "Team-3 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4318", + "name": "Team-2 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4319", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "141", - "durability": null, "name": "Team-3 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4320" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "973", - "durability": null, - "name": "Team-4 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4320", + "name": "Team-3 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4321", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "973", - "durability": null, "name": "Team-4 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4322" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1294", - "durability": null, - "name": "Team-5 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4322", + "name": "Team-4 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4323", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1294", - "durability": null, "name": "Team-5 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4324" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "124", - "durability": null, - "name": "Team-6 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4324", + "name": "Team-5 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4325", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "124", - "durability": null, "name": "Team-6 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4326" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1264", - "durability": null, - "name": "Team-7 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4326", + "name": "Team-6 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4327", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1264", - "durability": null, "name": "Team-7 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4328" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1824", - "durability": null, - "name": "Team-8 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4328", + "name": "Team-7 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4329", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1824", - "durability": null, "name": "Team-8 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4330" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "841", - "durability": null, - "name": "Team-9 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4330", + "name": "Team-8 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4331", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "841", - "durability": null, "name": "Team-9 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4332" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1127", - "durability": null, - "name": "Team-10 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4332", + "name": "Team-9 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4333", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1127", - "durability": null, "name": "Team-10 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4334" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "2011", - "durability": null, - "name": "Team-11 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4334", + "name": "Team-10 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4335", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2011", - "durability": null, "name": "Team-11 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4336" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1591", - "durability": null, - "name": "Team-12 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4336", + "name": "Team-11 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4337", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1591", - "durability": null, "name": "Team-12 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4338" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "308", - "durability": null, - "name": "Team-13 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4338", + "name": "Team-12 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4339", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "308", - "durability": null, "name": "Team-13 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4340" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1504", - "durability": null, - "name": "Team-14 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4340", + "name": "Team-13 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4341", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1504", - "durability": null, "name": "Team-14 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4342" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1462", - "durability": null, - "name": "Team-15 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4342", + "name": "Team-14 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4343", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1462", - "durability": null, "name": "Team-15 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4344" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "313", - "durability": null, - "name": "Team-16 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4344", + "name": "Team-15 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4345", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "313", - "durability": null, "name": "Team-16 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4346" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1231", - "durability": null, - "name": "Team-17 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4346", + "name": "Team-16 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4347", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1231", - "durability": null, "name": "Team-17 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4348" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1678", - "durability": null, - "name": "Team-18 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4348", + "name": "Team-17 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4349", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1678", - "durability": null, "name": "Team-18 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4350" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1041", - "durability": null, - "name": "Team-19 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4350", + "name": "Team-18 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4351", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1041", - "durability": null, "name": "Team-19 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4352" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "703", - "durability": null, - "name": "Team-20 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4352", + "name": "Team-19 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4353", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "703", - "durability": null, "name": "Team-20 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4354" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1292", - "durability": null, - "name": "Team-21 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4354", + "name": "Team-20 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4355", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1292", - "durability": null, "name": "Team-21 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4356" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1368", - "durability": null, - "name": "Team-22 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4356", + "name": "Team-21 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4357", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1368", - "durability": null, "name": "Team-22 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4358" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "280", - "durability": null, - "name": "Team-23 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4358", + "name": "Team-22 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4359", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "280", - "durability": null, "name": "Team-23 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4360" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1512", - "durability": null, - "name": "Team-24 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4360", + "name": "Team-23 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4361", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1512", - "durability": null, "name": "Team-24 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4362" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1395", - "durability": null, - "name": "Team-25 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4362", + "name": "Team-24 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4363", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1395", - "durability": null, "name": "Team-25 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4364" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "191", - "durability": null, - "name": "Team-26 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4364", + "name": "Team-25 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4365", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "191", - "durability": null, "name": "Team-26 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4366" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1420", - "durability": null, - "name": "Team-27 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4366", + "name": "Team-26 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4367", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1420", - "durability": null, "name": "Team-27 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4368" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1920", - "durability": null, - "name": "Team-28 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4368", + "name": "Team-27 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4369", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1920", - "durability": null, "name": "Team-28 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4370" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1175", - "durability": null, - "name": "Team-29 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4370", + "name": "Team-28 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4371", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1175", - "durability": null, "name": "Team-29 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4372" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "552", - "durability": null, - "name": "Team-30 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4372", + "name": "Team-29 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4373", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "552", - "durability": null, "name": "Team-30 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4374" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1385", - "durability": null, - "name": "Team-31 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4374", + "name": "Team-30 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4375", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1385", - "durability": null, "name": "Team-31 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4376" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1168", - "durability": null, - "name": "Team-32 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4376", + "name": "Team-31 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4377", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1168", - "durability": null, "name": "Team-32 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4378" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "211", - "durability": null, - "name": "Team-33 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4378", + "name": "Team-32 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4379", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "211", - "durability": null, "name": "Team-33 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4380" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1128", - "durability": null, - "name": "Team-34 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4380", + "name": "Team-33 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4381", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1128", - "durability": null, "name": "Team-34 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4382" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1140", - "durability": null, - "name": "Team-35 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4382", + "name": "Team-34 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4383", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1140", - "durability": null, "name": "Team-35 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4384" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "84", - "durability": null, - "name": "Team-36 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4384", + "name": "Team-35 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4385", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "84", - "durability": null, "name": "Team-36 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4386" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1010", - "durability": null, - "name": "Team-37 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4386", + "name": "Team-36 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4387", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1010", - "durability": null, "name": "Team-37 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4388" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1833", - "durability": null, - "name": "Team-38 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4388", + "name": "Team-37 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4389", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1833", - "durability": null, "name": "Team-38 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4390" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "914", - "durability": null, - "name": "Team-39 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4390", + "name": "Team-38 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4391", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "914", - "durability": null, "name": "Team-39 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4392" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "582", - "durability": null, - "name": "Team-40 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4392", + "name": "Team-39 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4393", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "582", - "durability": null, "name": "Team-40 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4394" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1471", - "durability": null, - "name": "Team-41 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4394", + "name": "Team-40 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4395", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1471", - "durability": null, "name": "Team-41 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4396" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1072", - "durability": null, - "name": "Team-42 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4396", + "name": "Team-41 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4397", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1072", - "durability": null, "name": "Team-42 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4398" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "298", - "durability": null, - "name": "Team-43 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4398", + "name": "Team-42 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4399", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "298", - "durability": null, "name": "Team-43 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4400" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1268", - "durability": null, - "name": "Team-44 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4400", + "name": "Team-43 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4401", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1268", - "durability": null, "name": "Team-44 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4402" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1371", - "durability": null, - "name": "Team-45 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4402", + "name": "Team-44 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4403", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1371", - "durability": null, "name": "Team-45 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4404" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "140", - "durability": null, - "name": "Team-46 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4404", + "name": "Team-45 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4405", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "140", - "durability": null, "name": "Team-46 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4406" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1233", - "durability": null, - "name": "Team-47 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4406", + "name": "Team-46 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4407", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1233", - "durability": null, "name": "Team-47 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4408" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1836", - "durability": null, - "name": "Team-48 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4408", + "name": "Team-47 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4409", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1836", - "durability": null, "name": "Team-48 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4410" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "1185", - "durability": null, - "name": "Team-49 cape", - "tradeable": "true", - "weight": "0.4", + "id": "4410", + "name": "Team-48 cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "4411", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1185", - "durability": null, "name": "Team-49 cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4412" - }, - { - "shop_price": "50", - "ge_buy_limit": "100", "examine": "Ooohhh look at the pretty colours...", - "grand_exchange_price": "708", - "durability": null, - "name": "Team-50 cape", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "4413", "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "708", + "id": "4412", + "name": "Team-49 cape", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4413", "name": "Team-50 cape", - "tradeable": "true", + "examine": "Ooohhh look at the pretty colours...", "archery_ticket_price": "0", - "id": "4414" + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" }, { - "examine": "A jungle forester's blunt axe.", + "id": "4414", + "name": "Team-50 cape", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4415", "name": "Blunt axe", - "weight": "1.3", + "examine": "A jungle forester's blunt axe.", "archery_ticket_price": "0", - "id": "4415" + "durability": null, + "weight": "1.3" }, { - "examine": "A strong medicinal brew for heavy chests.", - "durability": null, + "id": "4416", "name": "Herbal tincture", - "weight": "0.1", + "examine": "A strong medicinal brew for heavy chests.", "archery_ticket_price": "0", - "id": "4416" + "durability": null, + "weight": "0.1" }, { - "ge_buy_limit": "100", - "examine": "A cup of Guthix rest.", - "grand_exchange_price": "223", - "durability": null, + "id": "4417", "name": "Guthix rest(4)", - "tradeable": "true", + "examine": "A cup of Guthix rest.", "archery_ticket_price": "0", - "id": "4417" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "223", - "durability": null, + "id": "4418", "name": "Guthix rest(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4418" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A cup of Guthix rest.", - "grand_exchange_price": "134", - "durability": null, + "id": "4419", "name": "Guthix rest(3)", - "tradeable": "true", + "examine": "A cup of Guthix rest.", "archery_ticket_price": "0", - "id": "4419" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "134", - "durability": null, + "id": "4420", "name": "Guthix rest(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4420" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A cup of Guthix rest.", - "grand_exchange_price": "83", - "durability": null, + "id": "4421", "name": "Guthix rest(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4421" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "83", - "durability": null, - "name": "Guthix rest(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4422" - }, - { - "ge_buy_limit": "100", "examine": "A cup of Guthix rest.", - "grand_exchange_price": "44", - "durability": null, - "name": "Guthix rest(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4423" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "44", - "durability": null, - "name": "Guthix rest(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4424" + "tradeable": "true" }, { - "examine": "A half-filled feather mattress.", + "id": "4422", + "name": "Guthix rest(2)", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4423", + "name": "Guthix rest(1)", + "examine": "A cup of Guthix rest.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4424", + "name": "Guthix rest(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4425", "name": "Stodgy mattress", - "weight": "10", + "examine": "A half-filled feather mattress.", "archery_ticket_price": "0", - "id": "4425" + "durability": null, + "weight": "10" }, { - "examine": "A comfy-looking feather mattress.", - "durability": null, + "id": "4426", "name": "Comfy mattress", - "weight": "15", + "examine": "A comfy-looking feather mattress.", "archery_ticket_price": "0", - "id": "4426" + "durability": null, + "weight": "15" }, { - "examine": "Looks like a bunch of rust to me.", - "durability": null, + "id": "4427", "name": "Iron oxide", - "weight": "1", + "examine": "Looks like a bunch of rust to me.", "archery_ticket_price": "0", - "id": "4427" + "durability": null, + "weight": "1" }, { - "examine": "An animate rock spell is written on this parchment.", - "durability": null, + "id": "4428", "name": "Animate rock scroll", + "examine": "An animate rock spell is written on this parchment.", "archery_ticket_price": "0", - "id": "4428" + "durability": null }, { - "examine": "The weathervane directions should now work.", - "durability": null, + "id": "4430", "name": "Directionals", + "examine": "The weathervane directions should now work.", "archery_ticket_price": "0", - "id": "4430" + "durability": null }, { - "examine": "A fixed weathervane ornament.", - "durability": null, + "id": "4432", "name": "Ornament", + "examine": "A fixed weathervane ornament.", "archery_ticket_price": "0", - "id": "4432" + "durability": null }, { - "examine": "A fixed weathervane rotating pillar.", - "durability": null, + "id": "4434", "name": "Weathervane pillar", + "examine": "A fixed weathervane rotating pillar.", "archery_ticket_price": "0", - "id": "4434" + "durability": null }, { - "examine": "Clear skies ahead, with some chance of showers, thunderstorms, ice and hail.", - "durability": null, + "id": "4435", "name": "Weather report", + "examine": "Clear skies ahead, with some chance of showers, thunderstorms, ice and hail.", "archery_ticket_price": "0", - "id": "4435" + "durability": null }, { - "ge_buy_limit": "100", + "id": "4436", + "name": "Airtight pot", "examine": "This is pretty well sealed.", - "grand_exchange_price": "245", - "durability": null, - "name": "Airtight pot", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "4436" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "245", - "durability": null, + "id": "4437", "name": "Airtight pot", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4437" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4438", + "name": "Unfired pot lid", "examine": "This needs firing, then it should fit on a normal-sized pot.", - "grand_exchange_price": "16", - "durability": null, - "name": "Unfired pot lid", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4438" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "16", - "durability": null, + "id": "4439", "name": "Unfired pot lid", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4439" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4440", + "name": "Pot lid", "examine": "This should fit on a normal-sized pot.", - "grand_exchange_price": "5", - "durability": null, - "name": "Pot lid", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4440" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "5", - "durability": null, - "name": "Pot lid", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4441" + "tradeable": "true" }, { - "examine": "An airtight pot with something inside, most likely breathing salts.", + "id": "4441", + "name": "Pot lid", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4442", "name": "Breathing salts", + "examine": "An airtight pot with something inside, most likely breathing salts.", "archery_ticket_price": "0", - "id": "4442" + "durability": null }, { - "examine": "A large cage for transporting chickens.", - "durability": null, + "id": "4443", "name": "Chicken cage", - "weight": "1", + "examine": "A large cage for transporting chickens.", "archery_ticket_price": "0", - "id": "4443" + "durability": null, + "weight": "1" }, { - "examine": "A jungle forester's super sharp axe.", - "durability": null, + "id": "4444", "name": "Sharpened axe", - "weight": "1.3", + "examine": "A jungle forester's super sharp axe.", "archery_ticket_price": "0", - "id": "4444" + "durability": null, + "weight": "1.3" }, { - "examine": "Some mahogany logs which have been professionally cured.", - "durability": null, + "id": "4445", "name": "Red mahogany log", - "weight": "1.3", + "examine": "Some mahogany logs which have been professionally cured.", "archery_ticket_price": "0", - "id": "4445" + "durability": null, + "weight": "1.3" }, { - "destroy_message": "You can get another key ring from Yanni Salika in Shilo Village.", - "shop_price": "500", - "examine": "I can store my keys here.", - "durability": null, + "id": "4446", "name": "Steel key ring", - "tradeable": "false", - "destroy": "true", + "examine": "I can store my keys here.", "archery_ticket_price": "0", - "id": "4446" + "destroy": "true", + "destroy_message": "You can get another key ring from Yanni Salika in Shilo Village.", + "durability": null, + "shop_price": "500", + "tradeable": "false" }, { - "examine": "I wonder what happens if I rub it.", - "durability": null, + "id": "4447", "name": "Antique lamp", - "tradeable": "false", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4447" + "durability": null, + "tradeable": "false" }, { - "ge_buy_limit": "100", + "id": "4456", + "name": "Bowl of hot water", "examine": "It's a bowl of hot water.", - "grand_exchange_price": "111", - "durability": null, - "name": "Bowl of hot water", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4456" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "111", - "durability": null, + "id": "4457", "name": "Bowl of hot water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4457" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4458", + "name": "Cup of water", "examine": "A cup of water.", - "grand_exchange_price": "36", - "durability": null, - "name": "Cup of water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4458" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "36", - "durability": null, + "id": "4459", "name": "Cup of water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4459" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4460", + "name": "Cup of hot water", "examine": "It's hot!", - "grand_exchange_price": "102", - "durability": null, - "name": "Cup of hot water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4460" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "102", - "durability": null, - "name": "Cup of hot water", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4461" + "tradeable": "true" }, { + "id": "4461", + "name": "Cup of hot water", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4462", + "name": "Ruined herb tea", "examine": "A ruined herb tea.", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "4463", "name": "Ruined herb tea", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4462" - }, - { "durability": null, - "name": "Ruined herb tea", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4463" + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4464", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "13", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4464" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "13", - "durability": null, + "id": "4465", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4465" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4466", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "13", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4466" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "13", - "durability": null, + "id": "4467", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4467" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4468", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "19", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4468" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, + "id": "4469", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4469" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4470", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "19", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4470" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, + "id": "4471", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4471" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4472", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "17", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4472" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "17", - "durability": null, + "id": "4473", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4473" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4474", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "18", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4474" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "18", - "durability": null, + "id": "4475", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4475" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4476", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "18", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4476" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "18", - "durability": null, + "id": "4477", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4477" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4478", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "46", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4478" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "46", - "durability": null, + "id": "4479", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4479" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4480", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "41", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4480" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "41", - "durability": null, + "id": "4481", "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4481" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4482", + "name": "Herb tea mix", "examine": "See article", - "grand_exchange_price": "43", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4482" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "43", - "durability": null, - "name": "Herb tea mix", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4483" + "tradeable": "true" }, { - "shop_price": "160", - "examine": "The strange characters supposedly grant Svidi safe passage into Rellekka.", + "id": "4483", + "name": "Herb tea mix", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4484", "name": "Safety guarantee", + "examine": "The strange characters supposedly grant Svidi safe passage into Rellekka.", "archery_ticket_price": "0", - "id": "4484" + "durability": null, + "shop_price": "160" }, { - "examine": "This fruit is known as White Pearl. Should taste good.", - "durability": null, + "id": "4485", "name": "White pearl", - "weight": "1", + "examine": "This fruit is known as White Pearl. Should taste good.", "archery_ticket_price": "0", - "id": "4485" + "durability": null, + "weight": "1" }, { - "examine": "You can grow this seed even in cold mountain ranges!", - "durability": null, + "id": "4486", "name": "White pearl seed", + "examine": "You can grow this seed even in cold mountain ranges!", "archery_ticket_price": "0", - "id": "4486" + "durability": null }, { - "examine": "It's a piece of the Ancient Rock of the mountain people. It's still just a stone.", - "durability": null, + "id": "4487", "name": "Half a rock", - "weight": "1", + "examine": "It's a piece of the Ancient Rock of the mountain people. It's still just a stone.", "archery_ticket_price": "0", - "id": "4487" + "durability": null, + "weight": "1" }, { - "examine": "The corpse of a woman who died long ago.", - "durability": null, + "id": "4488", "name": "Corpse of woman", - "weight": "1", + "examine": "The corpse of a woman who died long ago.", "archery_ticket_price": "0", - "id": "4488" + "durability": null, + "weight": "1" }, { - "examine": "This used to belong to Asleif, daughter of the mountain camp chieftain.", - "durability": null, + "id": "4489", "name": "Asleif's necklace", + "examine": "This used to belong to Asleif, daughter of the mountain camp chieftain.", "archery_ticket_price": "0", - "id": "4489" + "durability": null }, { - "examine": "Marginally better than egg on your face.", - "durability": null, + "id": "4490", "name": "Mud", + "examine": "Marginally better than egg on your face.", "archery_ticket_price": "0", - "id": "4490" + "durability": null }, { - "examine": "A muddy rock.", - "durability": null, + "id": "4492", "name": "Muddy rock", - "weight": "1", + "examine": "A muddy rock.", "archery_ticket_price": "0", - "id": "4492" + "durability": null, + "weight": "1" }, { - "examine": "It's just a long stick, really.", - "durability": null, + "id": "4494", "name": "Pole", - "archery_ticket_price": "0", - "id": "4494" - }, - { "examine": "It's just a long stick, really.", - "durability": null, - "name": "Pole", "archery_ticket_price": "0", - "id": "4495" + "durability": null }, { - "examine": "Splintered into pieces, it has become completely useless to you.", - "durability": null, + "id": "4495", + "name": "Pole", + "examine": "It's just a long stick, really.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4496", "name": "Broken pole", + "examine": "Splintered into pieces, it has become completely useless to you.", "archery_ticket_price": "0", - "id": "4496" + "durability": null }, { - "shop_price": "18", - "examine": "A coil of rope.", - "grand_exchange_price": "101", - "durability": null, - "name": "Rope", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", "id": "4498", - "equipment_slot": "3" - }, - { - "durability": null, "name": "Rope", + "examine": "A coil of rope.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "shop_price": "18", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4499" + "weight": "1.3" }, { - "examine": "It's just a long stick, really.", - "durability": null, - "name": "Pole", + "id": "4499", + "name": "Rope", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "4500", - "equipment_slot": "3" - }, - { - "examine": "It's just a long stick, really.", - "durability": null, "name": "Pole", + "examine": "It's just a long stick, really.", "archery_ticket_price": "0", - "id": "4501", + "durability": null, "equipment_slot": "3" }, { + "id": "4501", + "name": "Pole", + "examine": "It's just a long stick, really.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "4502", + "name": "Bearhead", + "examine": "Quite ferocious looking.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-3,12,14,10,7,9,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Hamal, the Chieftain of the Mountain Camp, can replace this.", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "shop_price": "3000", - "examine": "Quite ferocious looking.", - "durability": null, - "destroy": "true", - "weight": "0.4", - "equipment_slot": "0", - "destroy_message": "Hamal, the Chieftain of the Mountain Camp, can replace this.", - "name": "Bearhead", "tradeable": "false", - "archery_ticket_price": "0", - "id": "4502", - "bonuses": "0,0,0,-3,-3,12,14,10,7,9,0,0,0,0,0" + "weight": "0.4" }, { - "requirements": "{0,20}", - "shop_price": "50", - "turn90cw_anim": "821", - "examine": "A very decorative sword.", - "walk_anim": "819", - "durability": null, - "weight": "1", - "turn90ccw_anim": "822", - "weapon_interface": "6", - "turn180_anim": "820", - "render_anim": "1", - "defence_anim": "397", - "castle_wars_ticket_price": "50", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "stand_anim": "808", - "name": "Decorative sword", - "run_anim": "824", - "archery_ticket_price": "0", "id": "4503", + "name": "Decorative sword", + "examine": "A very decorative sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "bonuses": "15,20,-2,0,0,0,3,2,0,0,0,22,0,0,0", + "castle_wars_ticket_price": "50", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1", + "requirements": "{0,20}", + "run_anim": "824", + "shop_price": "50", + "stand_anim": "808", "stand_turn_anim": "823", - "bonuses": "15,20,-2,0,0,0,3,2,0,0,0,22,0,0,0" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1" }, { - "remove_sleeves": "true", - "requirements": "{1,20}", - "durability": null, + "id": "4504", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "4504", "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,0,0,0", "castle_wars_ticket_price": "80", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}" }, { - "requirements": "{1,20}", - "durability": null, + "id": "4505", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "4505", "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0", "castle_wars_ticket_price": "60", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}" }, { - "remove_head": "true", - "requirements": "{1,20}", - "shop_price": "40", - "examine": "A very decorative helm.", - "durability": null, - "name": "Decorative helm", - "weight": "1", - "archery_ticket_price": "0", "id": "4506", + "name": "Decorative helm", + "examine": "A very decorative helm.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-3,-1,10,11,9,-1,10,5,0,0,0,0", "castle_wars_ticket_price": "40", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "40", + "weight": "1" }, { - "requirements": "{1,20}", - "shop_price": "60", - "examine": "A very decorative shield.", - "durability": null, - "name": "Decorative shield", - "archery_ticket_price": "0", "id": "4507", + "name": "Decorative shield", + "examine": "A very decorative shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,0,0,0", "castle_wars_ticket_price": "60", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "requirements": "{1,20}", + "shop_price": "60" }, { - "requirements": "{0,30}", - "shop_price": "50", - "turn90cw_anim": "821", - "examine": "A very decorative sword.", - "walk_anim": "819", - "durability": null, - "weight": "1", - "turn90ccw_anim": "822", - "weapon_interface": "6", - "turn180_anim": "820", - "render_anim": "1", - "defence_anim": "397", - "castle_wars_ticket_price": "500", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "stand_anim": "808", - "name": "Decorative sword", - "run_anim": "824", - "archery_ticket_price": "0", "id": "4508", + "name": "Decorative sword", + "examine": "A very decorative sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0", + "castle_wars_ticket_price": "500", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1", + "requirements": "{0,30}", + "run_anim": "824", + "shop_price": "50", + "stand_anim": "808", "stand_turn_anim": "823", - "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1" }, { - "remove_sleeves": "true", - "requirements": "{1,30}", - "durability": null, + "id": "4509", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "4509", "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0", "castle_wars_ticket_price": "800", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,30}" }, { - "requirements": "{1,30}", - "durability": null, + "id": "4510", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "4510", "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", "castle_wars_ticket_price": "600", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,30}" }, { + "id": "4511", + "name": "Decorative helm", + "examine": "A very decorative helm.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0", + "castle_wars_ticket_price": "400", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,30}", "shop_price": "40", - "examine": "A very decorative helm.", - "durability": null, - "name": "Decorative helm", - "weight": "1", - "archery_ticket_price": "0", - "id": "4511", - "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0", - "castle_wars_ticket_price": "400", - "equipment_slot": "0" + "weight": "1" }, { - "requirements": "{1,30}", - "shop_price": "60", - "examine": "A very decorative shield.", - "durability": null, - "name": "Decorative shield", - "archery_ticket_price": "0", "id": "4512", + "name": "Decorative shield", + "examine": "A very decorative shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", "castle_wars_ticket_price": "600", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "requirements": "{1,30}", + "shop_price": "60" }, { - "remove_head": "true", - "durability": null, - "name": "Castlewars hood", - "archery_ticket_price": "0", "id": "4513", - "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", - "castle_wars_ticket_price": "10", - "equipment_slot": "0" - }, - { - "durability": null, - "name": "Castlewars cloak", - "archery_ticket_price": "0", - "id": "4514", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "castle_wars_ticket_price": "10", - "equipment_slot": "1" - }, - { - "remove_head": "true", - "durability": null, "name": "Castlewars hood", "archery_ticket_price": "0", - "id": "4515", "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", "castle_wars_ticket_price": "10", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "remove_head": "true" }, { - "durability": null, + "id": "4514", "name": "Castlewars cloak", "archery_ticket_price": "0", - "id": "4516", "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", "castle_wars_ticket_price": "10", + "durability": null, "equipment_slot": "1" }, { - "ge_buy_limit": "1000", + "id": "4515", + "name": "Castlewars hood", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", + "castle_wars_ticket_price": "10", + "durability": null, + "equipment_slot": "0", + "remove_head": "true" + }, + { + "id": "4516", + "name": "Castlewars cloak", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "castle_wars_ticket_price": "10", + "durability": null, + "equipment_slot": "1" + }, + { + "id": "4517", + "name": "Giant frog legs", "examine": "This could feed a family of gnomes for a week!", - "grand_exchange_price": "970", - "durability": null, - "name": "Giant frog legs", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "4517" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "970", - "durability": null, + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4518", "name": "Giant frog legs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4518" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "4522", + "name": "Oil lamp", + "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{12,11}", "shop_price": "10", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4523", + "name": "Oil lamp", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4524", + "name": "Oil lamp", "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", - "grand_exchange_price": "1575", - "durability": null, - "name": "Oil lamp", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "4522" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1575", "durability": null, - "name": "Oil lamp", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4523" - }, - { "shop_price": "10", - "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", - "grand_exchange_price": "2", - "durability": null, - "name": "Oil lamp", "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "4524" + "weight": "0.4" }, { + "id": "4525", + "name": "Oil lamp", + "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{12,11}", "shop_price": "10", - "ge_buy_limit": "100", - "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", - "grand_exchange_price": "2", - "durability": null, + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "4526", "name": "Oil lamp", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "4525" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2", "durability": null, - "name": "Oil lamp", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4526" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "4527", + "name": "Candle lantern", + "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{4,11}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "4528", + "name": "Candle lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4529", + "name": "Candle lantern", "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", - "grand_exchange_price": "39", - "durability": null, - "name": "Candle lantern", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4527" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "39", - "durability": null, - "name": "Candle lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4528" - }, - { "requirements": "{4,11}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "4530", + "name": "Candle lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4531", + "name": "Candle lantern", "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", - "grand_exchange_price": "431", - "durability": null, - "name": "Candle lantern", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4529" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "431", - "durability": null, + "id": "4532", "name": "Candle lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4530" - }, - { "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", - "grand_exchange_price": "1", - "durability": null, - "name": "Candle lantern", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4531" - }, - { + "durability": null, "requirements": "{4,11}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "4533", + "name": "Candle lantern", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4534", + "name": "Candle lantern", "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", - "grand_exchange_price": "1", - "durability": null, - "name": "Candle lantern", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4532" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { - "durability": null, - "name": "Candle lantern", - "tradeable": "true", + "id": "4535", + "name": "Oil lantern", + "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", "archery_ticket_price": "0", - "id": "4533" - }, - { - "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", - "grand_exchange_price": "1", "durability": null, - "name": "Candle lantern", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "4534" - }, - { + "ge_buy_limit": "100", "requirements": "{11,26}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "4536", + "name": "Oil lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4537", + "name": "Oil lantern", "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", - "grand_exchange_price": "12", - "durability": null, - "name": "Oil lantern", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4535" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "12", - "durability": null, - "name": "Oil lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4536" - }, - { "requirements": "{11,26}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "4538", + "name": "Oil lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4539", + "name": "Oil lantern", "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", - "grand_exchange_price": "218", - "durability": null, - "name": "Oil lantern", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "4537" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "218", - "durability": null, - "name": "Oil lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4538" - }, - { - "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", - "grand_exchange_price": "198", - "durability": null, - "name": "Oil lantern", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "4539" - }, - { - "shop_price": "43", - "ge_buy_limit": "100", + "id": "4540", + "name": "Oil lantern frame", "examine": "Add the glass to complete.", - "grand_exchange_price": "8", - "durability": null, - "name": "Oil lantern frame", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4540" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "43", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, + "id": "4541", "name": "Oil lantern frame", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4541" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "88", - "ge_buy_limit": "100", + "id": "4542", + "name": "Lantern lens", "examine": "A roughly circular disc of glass.", - "grand_exchange_price": "1", - "durability": null, - "name": "Lantern lens", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4542" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "88", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "4543", "name": "Lantern lens", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4543" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "400", - "ge_buy_limit": "100", + "id": "4544", + "name": "Bullseye lantern", "examine": "You need to add a lens before you can use it.", - "grand_exchange_price": "88", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "4544" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "88", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4545" - }, - { - "requirements": "{11,49}", "shop_price": "400", + "tradeable": "true", + "weight": "1" + }, + { + "id": "4545", + "name": "Bullseye lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4546", + "name": "Bullseye lantern", "examine": "You need to add lamp oil before you can use it.", - "grand_exchange_price": "158", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "4546" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "158", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4547" - }, - { "requirements": "{11,49}", "shop_price": "400", + "tradeable": "true", + "weight": "1" + }, + { + "id": "4547", + "name": "Bullseye lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4548", + "name": "Bullseye lantern", "examine": "A sturdy steel lantern.", - "grand_exchange_price": "1345", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "4548" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1345", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4549" - }, - { + "requirements": "{11,49}", "shop_price": "400", - "examine": "A sturdy steel lantern casting a bright beam.", - "grand_exchange_price": "1235", - "durability": null, - "name": "Bullseye lantern", - "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "4550" + "tradeable": "true", + "weight": "1" }, { + "id": "4549", + "name": "Bullseye lantern", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4550", + "name": "Bullseye lantern", + "examine": "A sturdy steel lantern casting a bright beam.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "400", + "tradeable": "false", + "weight": "1" + }, + { + "id": "4551", + "name": "Spiny helmet", + "examine": "You don't want to wear it inside-out.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,5}", "shop_price": "650", - "ge_buy_limit": "100", - "examine": "You don't want to wear it inside-out.", - "durability": null, - "weight": "2.2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "774", - "name": "Spiny helmet", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4551", - "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "774", - "durability": null, + "id": "4552", "name": "Spiny helmet", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4552" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "Remember to brush after eating!", - "durability": null, + "id": "4558", "name": "Blue sweets", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "4558" + "durability": null }, { - "examine": "Remember to brush after eating!", - "durability": null, + "id": "4559", "name": "Deep blue sweets", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "4559" + "durability": null }, { - "examine": "Remember to brush after eating!", - "durability": null, + "id": "4560", "name": "White sweets", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "4560" + "durability": null }, { - "examine": "Remember to brush after eating!", - "grand_exchange_price": "10037", - "durability": null, + "id": "4561", "name": "Purple sweets", - "tradeable": "true", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "4561" + "durability": null, + "tradeable": "true" }, { - "examine": "Remember to brush after eating!", - "durability": null, + "id": "4562", "name": "Red sweets", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "4562" + "durability": null }, { - "examine": "Remember to brush after eating!", - "durability": null, + "id": "4563", "name": "Green sweets", - "archery_ticket_price": "0", - "id": "4563" - }, - { "examine": "Remember to brush after eating!", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4564", "name": "Pink sweets", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "4564" + "durability": null }, { - "bankable": "true", - "turn90cw_anim": "821", - "examine": "Hand them out to spread the Easter happiness.", - "walk_anim": "1836", - "durability": null, - "destroy": "true", - "turn90ccw_anim": "822", - "weapon_interface": "12", - "turn180_anim": "820", - "render_anim": "594", - "equipment_slot": "3", - "fun_weapon": "true", - "stand_anim": "1837", - "name": "Basket of eggs", - "tradeable": "false", - "run_anim": "1836", - "archery_ticket_price": "0", "id": "4565", - "stand_turn_anim": "823" - }, - { - "examine": "Perhaps not the most powerful weapon in 2009Scape.", + "name": "Basket of eggs", + "examine": "Hand them out to spread the Easter happiness.", + "archery_ticket_price": "0", + "bankable": "true", + "destroy": "true", "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "12", - "defence_anim": "1834", "equipment_slot": "3", - "attack_anims": "1833,1833,1833,1833", "fun_weapon": "true", - "name": "Rubber chicken", - "archery_ticket_price": "0", - "id": "4566", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "remove_head": "true", - "examine": "Made of gold and white gold.", - "durability": null, - "name": "Gold helmet", - "weight": "31.7", - "archery_ticket_price": "0", - "id": "4567", - "bonuses": "0,0,0,0,0,0,10,20,0,10,6,0,0,0,0", - "equipment_slot": "0" - }, - { - "examine": "This book is almost falling apart, you'll have to handle it quite carefully.", - "durability": null, - "name": "Dwarven lore", - "archery_ticket_price": "0", - "id": "4568" - }, - { - "examine": "A missing page from Rolad's book! It seems to be the first one.", - "durability": null, - "name": "Book page 1", - "archery_ticket_price": "0", - "id": "4569" - }, - { - "examine": "A missing page from Rolad's book! It seems to be the second one.", - "durability": null, - "name": "Book page 2", - "archery_ticket_price": "0", - "id": "4570" - }, - { - "examine": "A missing page from Rolad's book! It seems to be the third one.", - "durability": null, - "name": "Book page 3", - "archery_ticket_price": "0", - "id": "4571" - }, - { - "examine": "A collection of missing pages from Rolad's book!", - "durability": null, - "name": "Pages", - "archery_ticket_price": "0", - "id": "4572" - }, - { - "examine": "A collection of missing pages from Rolad's book!", - "durability": null, - "name": "Pages", - "archery_ticket_price": "0", - "id": "4573" - }, - { - "examine": "These are the base schematics of a dwarven multicannon.", - "durability": null, - "name": "Base schematics", - "archery_ticket_price": "0", - "id": "4574" - }, - { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A black tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "536", - "stand_anim": "813", - "tradeable": "true", - "name": "Black spear", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4580", - "stand_turn_anim": "1209", - "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "536", - "durability": null, - "name": "Black spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4581" - }, - { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A black tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "2808", - "stand_anim": "813", - "tradeable": "true", - "name": "Black spear(p)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4582", - "stand_turn_anim": "1209", - "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2808", - "durability": null, - "name": "Black spear(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4583" - }, - { - "requirements": "{0,10}", - "turn90cw_anim": "1207", - "examine": "A Karambwan poisoned black tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "309", - "stand_anim": "813", - "name": "Black spear(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4584", - "stand_turn_anim": "1209", - "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" - }, - { - "requirements": "{1,60}", - "ge_buy_limit": "10", - "examine": "This looks pretty heavy.", - "durability": null, - "weight": "9", - "absorb": "3,0,6", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "161000", - "name": "Dragon plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4585", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "161000", - "durability": null, - "name": "Dragon plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4586" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "has_special": "true", - "turn90ccw_anim": "822", - "attack_speed": "4", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "65400", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "4587", + "render_anim": "594", + "run_anim": "1836", + "stand_anim": "1837", "stand_turn_anim": "823", - "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0", - "requirements": "{0,60}", - "shop_price": "100000", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "lendable": "true", - "attack_audios": "2500,0,2517,0", - "name": "Dragon scimitar" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "65400", - "durability": null, - "name": "Dragon scimitar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4588" - }, - { - "examine": "Keys to the Mayor's house. (The Feud)", - "durability": null, - "name": "Keys", - "archery_ticket_price": "0", - "id": "4589" - }, - { - "examine": "The Mayor of Pollnivneach's wife's jewels.", - "durability": null, - "name": "Jewels", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "4590" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1836", + "weapon_interface": "12" }, { - "shop_price": "1", - "examine": "Wear it on your head.", - "durability": null, - "name": "Karidian headpiece", + "id": "4566", + "name": "Rubber chicken", + "examine": "Perhaps not the most powerful weapon in 2009Scape.", "archery_ticket_price": "0", - "id": "4591" - }, - { - "shop_price": "1", - "examine": "Makes me itch.", - "durability": null, - "name": "Fake beard", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4593" - }, - { - "shop_price": "160", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Note", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4597" - }, - { - "shop_price": "160", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Note", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4598" - }, - { - "shop_price": "1", - "examine": "A handy little club made out of oak.", - "durability": null, - "weight": "1.8", + "attack_anims": "1833,1833,1833,1833", + "attack_audios": "2257,2257,2257", "attack_speed": "4", - "weapon_interface": "10", - "defence_anim": "425", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "defence_anim": "1834", + "durability": null, + "equip_audio": "2238", "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "name": "Oak-blackjack", - "archery_ticket_price": "0", - "id": "4599", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,2,0,0,0" + "fun_weapon": "true", + "weapon_interface": "12", + "weight": "0.4" }, { - "shop_price": "600", - "ge_buy_limit": "100", - "examine": "A handy little club made out of willow.", + "id": "4567", + "name": "Gold helmet", + "examine": "Made of gold and white gold.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,10,20,0,10,6,0,0,0,0", "durability": null, - "weight": "1", - "attack_speed": "4", - "weapon_interface": "10", - "defence_anim": "425", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "321", - "name": "Willow-blackjack", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4600", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,8,0,0,0" - }, - { - "examine": "Dung of the Camelus Horribleus variety.", - "durability": null, - "name": "Ugthanki dung", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "4601" - }, - { - "examine": "Dung of the Camelus Horribleus variety.", - "durability": null, - "name": "Ugthanki dung", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "4602" - }, - { - "shop_price": "2", - "examine": "A receipt for one 'Camelus Horribleus", - "durability": null, - "name": "Receipt", - "archery_ticket_price": "0", - "id": "4603" - }, - { - "examine": "A red viscous liquid in a vial.", - "durability": null, - "name": "Hag's poison", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4604" - }, - { - "examine": "Makes a hissing sound.", - "durability": null, - "name": "Snake charm", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "4605", - "equipment_slot": "3" - }, - { - "examine": "This is used to hold snakes.", - "durability": null, - "name": "Snake basket", - "archery_ticket_price": "0", - "id": "4606" - }, - { - "examine": "This basket contains a snake.", - "durability": null, - "name": "Snake basket full", - "weight": "1", - "archery_ticket_price": "0", - "id": "4607" - }, - { - "shop_price": "5", - "ge_buy_limit": "1000", - "examine": "A meaty and very hot kebab.", - "grand_exchange_price": "403", - "durability": null, - "name": "Super kebab", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "4608" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "403", - "durability": null, - "name": "Super kebab", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4609" - }, - { - "examine": "The bottle feels warm.", - "durability": null, - "name": "Red hot sauce", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "4610" - }, - { + "equipment_slot": "0", "remove_head": "true", - "examine": "A disguise suitable for the desert.", - "durability": null, - "name": "Desert disguise", - "archery_ticket_price": "0", - "id": "4611", - "remove_beard": "true", - "equipment_slot": "0" + "weight": "31.7" }, { + "id": "4568", + "name": "Dwarven lore", + "examine": "This book is almost falling apart, you'll have to handle it quite carefully.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4569", + "name": "Book page 1", + "examine": "A missing page from Rolad's book! It seems to be the first one.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4570", + "name": "Book page 2", + "examine": "A missing page from Rolad's book! It seems to be the second one.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4571", + "name": "Book page 3", + "examine": "A missing page from Rolad's book! It seems to be the third one.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4572", + "name": "Pages", + "examine": "A collection of missing pages from Rolad's book!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4573", + "name": "Pages", + "examine": "A collection of missing pages from Rolad's book!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4574", + "name": "Base schematics", + "examine": "These are the base schematics of a dwarven multicannon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4580", + "name": "Black spear", + "examine": "A black tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0", "durability": null, - "name": "Willow-blackjack", + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4612" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "shop_price": "75", - "examine": "It has a picture of a dragon on it.", - "durability": null, - "name": "Spinning plate", + "id": "4581", + "name": "Black spear", "archery_ticket_price": "0", - "id": "4613" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "Alas...", - "durability": null, - "name": "Broken plate", + "id": "4582", + "name": "Black spear(p)", + "examine": "A black tipped spear.", "archery_ticket_price": "0", - "id": "4614" + "attack_speed": "5", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "examine": "An archaeologist's notes.", - "durability": null, - "name": "Varmen's notes", + "id": "4583", + "name": "Black spear(p)", "archery_ticket_price": "0", - "id": "4616" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "The museum curator's key (The Golem).", - "durability": null, - "name": "Display cabinet key", + "id": "4584", + "name": "Black spear(kp)", + "examine": "A Karambwan poisoned black tipped spear.", "archery_ticket_price": "0", - "id": "4617" + "attack_speed": "5", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,10}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "examine": "It's pretty, but you wish you knew what it was.", - "durability": null, - "name": "Strange implement", + "id": "4585", + "name": "Dragon plateskirt", + "examine": "This looks pretty heavy.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "4619" + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "9" }, { - "examine": "It looks horrible.On ground: Not good for eating.", - "durability": null, - "name": "Black mushroom", - "weight": "1", + "id": "4586", + "name": "Dragon plateskirt", "archery_ticket_price": "0", - "id": "4620" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "examine": "A long feather patterned like a flame.", - "durability": null, - "name": "Phoenix feather", + "id": "4587", + "name": "Dragon scimitar", + "examine": "A vicious, curved sword.", "archery_ticket_price": "0", - "id": "4621" + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "1", + "requirements": "{0,60}", + "run_anim": "824", + "shop_price": "100000", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" }, { - "examine": "Black ink made out of mushrooms.", - "durability": null, - "name": "Black mushroom ink", - "weight": "1", + "id": "4588", + "name": "Dragon scimitar", "archery_ticket_price": "0", - "id": "4622" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "examine": "A phoenix feather dipped in ink.", - "durability": null, - "name": "Phoenix quill pen", + "id": "4589", + "name": "Keys", + "examine": "Keys to the Mayor's house. (The Feud)", "archery_ticket_price": "0", - "id": "4623" + "durability": null }, { - "examine": "It reads 'YOUR TASK IS DONE'.", - "durability": null, - "name": "Golem program", - "tradeable": "false", + "id": "4590", + "name": "Jewels", + "examine": "The Mayor of Pollnivneach's wife's jewels.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4624" + "durability": null, + "tradeable": "false" }, { - "shop_price": "650", + "id": "4591", + "name": "Karidian headpiece", + "examine": "Wear it on your head.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1" + }, + { + "id": "4593", + "name": "Fake beard", + "examine": "Makes me itch.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true", + "weight": "1" + }, + { + "id": "4597", + "name": "Note", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "tradeable": "true" + }, + { + "id": "4598", + "name": "Note", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "tradeable": "true" + }, + { + "id": "4599", + "name": "Oak-blackjack", + "examine": "A handy little club made out of oak.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,2,0,0,0", + "defence_anim": "425", + "durability": null, + "equipment_slot": "3", + "shop_price": "1", + "weapon_interface": "10", + "weight": "1.8" + }, + { + "id": "4600", + "name": "Willow-blackjack", + "examine": "A handy little club made out of willow.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,8,0,0,0", + "defence_anim": "425", + "durability": null, + "equipment_slot": "3", "ge_buy_limit": "100", + "shop_price": "600", + "tradeable": "true", + "weapon_interface": "10", + "weight": "1" + }, + { + "id": "4601", + "name": "Ugthanki dung", + "examine": "Dung of the Camelus Horribleus variety.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.4" + }, + { + "id": "4602", + "name": "Ugthanki dung", + "examine": "Dung of the Camelus Horribleus variety.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.4" + }, + { + "id": "4603", + "name": "Receipt", + "examine": "A receipt for one 'Camelus Horribleus", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2" + }, + { + "id": "4604", + "name": "Hag's poison", + "examine": "A red viscous liquid in a vial.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "4605", + "name": "Snake charm", + "examine": "Makes a hissing sound.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "0.1" + }, + { + "id": "4606", + "name": "Snake basket", + "examine": "This is used to hold snakes.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4607", + "name": "Snake basket full", + "examine": "This basket contains a snake.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "4608", + "name": "Super kebab", + "examine": "A meaty and very hot kebab.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "5", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "4609", + "name": "Super kebab", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4610", + "name": "Red hot sauce", + "examine": "The bottle feels warm.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "4611", + "name": "Desert disguise", + "examine": "A disguise suitable for the desert.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true" + }, + { + "id": "4612", + "name": "Willow-blackjack", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "4613", + "name": "Spinning plate", + "examine": "It has a picture of a dragon on it.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "75" + }, + { + "id": "4614", + "name": "Broken plate", + "examine": "Alas...", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4616", + "name": "Varmen's notes", + "examine": "An archaeologist's notes.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4617", + "name": "Display cabinet key", + "examine": "The museum curator's key (The Golem).", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4619", + "name": "Strange implement", + "examine": "It's pretty, but you wish you knew what it was.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4620", + "name": "Black mushroom", + "examine": "It looks horrible.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "4621", + "name": "Phoenix feather", + "examine": "A long feather patterned like a flame.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4622", + "name": "Black mushroom ink", + "examine": "Black ink made out of mushrooms.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "4623", + "name": "Phoenix quill pen", + "examine": "A phoenix feather dipped in ink.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4624", + "name": "Golem program", + "examine": "It reads 'YOUR TASK IS DONE'.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "4627", + "name": "Bandit's brew", "examine": "A cheeky little lager from the Bandit Camp.", - "grand_exchange_price": "1133", - "durability": null, - "name": "Bandit's brew", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4627" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1133", - "durability": null, + "shop_price": "650", + "tradeable": "true" + }, + { + "id": "4628", "name": "Bandit's brew", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4628" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "A copy of the engravings found on a mysterious stone tablet.", - "durability": null, + "id": "4654", "name": "Etchings", + "examine": "A copy of the engravings found on a mysterious stone tablet.", "archery_ticket_price": "0", - "id": "4654" + "durability": null }, { - "examine": "A rough translation made from archaeological etchings.", - "durability": null, + "id": "4655", "name": "Translation", - "weight": "1", + "examine": "A rough translation made from archaeological etchings.", "archery_ticket_price": "0", - "id": "4655" + "durability": null, + "weight": "1" }, { - "examine": "This key is unusally warm to the touch.", - "durability": null, + "id": "4656", "name": "Warm key", + "examine": "This key is unusally warm to the touch.", "archery_ticket_price": "0", - "id": "4656" + "durability": null }, { - "examine": "A ring that allows you to see things that are normally invisible.", - "durability": null, - "name": "Ring of visibility", - "archery_ticket_price": "0", "id": "4657", + "name": "Ring of visibility", + "examine": "A ring that allows you to see things that are normally invisible.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "12" }, { - "examine": "Frank's shiny silver coated pot.", - "durability": null, + "id": "4658", "name": "Silver pot", - "tradeable": "false", + "examine": "A silver pot made by Ruantun.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4658" + "durability": null, + "tradeable": "false" }, { - "examine": "A silver pot made by Ruantun and blessed on Entrana.", - "durability": null, + "id": "4659", "name": "Blessed pot", - "weight": "2", + "examine": "A silver pot made by Ruantun and blessed on Entrana.", "archery_ticket_price": "0", - "id": "4659" + "durability": null, + "weight": "2" }, { - "examine": "Frank's shiny silver coated pot.", - "durability": null, + "id": "4660", "name": "Silver pot", - "tradeable": "false", + "examine": "A silver pot made by Ruantun filled with your blood.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4660" + "durability": null, + "tradeable": "false" }, { - "examine": "A silver pot made by Ruantun and blessed on Entrana.", - "durability": null, + "id": "4661", "name": "Blessed pot", - "weight": "2", + "examine": "A blessed silver pot made by Ruantun filled with your blood.", "archery_ticket_price": "0", - "id": "4661" + "durability": null, + "weight": "2" }, { - "examine": "Frank's shiny silver coated pot.", - "durability": null, + "id": "4662", "name": "Silver pot", - "tradeable": "false", + "examine": "A silver pot made by Ruantun filled with blood and garlic.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4662" + "durability": null, + "tradeable": "false" }, { - "examine": "A silver pot made by Ruantun and blessed on Entrana.", - "durability": null, + "id": "4663", "name": "Blessed pot", - "weight": "2", + "examine": "A blessed silver pot filled with blood and garlic.", "archery_ticket_price": "0", - "id": "4663" + "durability": null, + "weight": "2" }, { - "examine": "Frank's shiny silver coated pot.", - "durability": null, + "id": "4664", "name": "Silver pot", - "tradeable": "false", + "examine": "A silver pot made by Ruantun filled with blood and spices.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4664" + "durability": null, + "tradeable": "false" }, { - "examine": "A silver pot made by Ruantun and blessed on Entrana.", - "durability": null, + "id": "4665", "name": "Blessed pot", - "weight": "2", + "examine": "A blessed silver pot filled with blood and spices.", "archery_ticket_price": "0", - "id": "4665" + "durability": null, + "weight": "2" }, { - "examine": "Frank's shiny silver coated pot.", - "durability": null, + "id": "4666", "name": "Silver pot", - "tradeable": "false", + "examine": "A silver pot made by Ruantun filled with blood, garlic and spices.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "4666" + "durability": null, + "tradeable": "false" }, { - "examine": "A silver pot made by Ruantun and blessed on Entrana.", - "durability": null, + "id": "4667", "name": "Blessed pot", - "weight": "2", + "examine": "A blessed silver pot filled with blood, garlic and spices.", "archery_ticket_price": "0", - "id": "4667" + "durability": null, + "weight": "2" }, { - "examine": "Finely ground garlic powder.", - "durability": null, + "id": "4668", "name": "Garlic powder", + "examine": "Finely ground garlic powder.", "archery_ticket_price": "0", - "id": "4668" + "durability": null }, { - "examine": "The Diamond of Blood.", - "durability": null, + "id": "4670", "name": "Blood diamond", + "examine": "The Diamond of Blood.", "archery_ticket_price": "0", - "id": "4670" + "durability": null }, { - "examine": "The Diamond of Ice.", - "durability": null, + "id": "4671", "name": "Ice diamond", + "examine": "The Diamond of Ice.", "archery_ticket_price": "0", - "id": "4671" + "durability": null }, { - "examine": "The Diamond of Smoke.", - "durability": null, + "id": "4672", "name": "Smoke diamond", - "weight": "1", + "examine": "The Diamond of Smoke.", "archery_ticket_price": "0", - "id": "4672" + "durability": null, + "weight": "1" }, { - "examine": "The Diamond of Shadow.", - "durability": null, + "id": "4673", "name": "Shadow diamond", - "weight": "1", + "examine": "The Diamond of Shadow.", "archery_ticket_price": "0", - "id": "4673" + "durability": null, + "weight": "1" }, { - "examine": "An old and strangely shaped metal cross.", - "durability": null, + "id": "4674", "name": "Gilded cross", + "examine": "An old and strangely shaped metal cross.", "archery_ticket_price": "0", - "id": "4674" + "durability": null }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A magical staff of ancient origin...", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "59300", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4675", - "stand_turn_anim": "1209", - "bonuses": "10,-1,40,15,0,2,3,1,15,0,0,50,-1,0,0", - "requirements": "{0,50}-{6,50}", - "shop_price": "80000", - "durability": null, - "weight": "2.25", - "weapon_interface": "1", - "render_anim": "28", - "lendable": "true", - "attack_audios": "2555,0,0,0", - "name": "Ancient staff" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "59300", - "durability": null, "name": "Ancient staff", - "tradeable": "true", + "examine": "A magical staff of ancient origin...", "archery_ticket_price": "0", - "id": "4676" - }, - { - "examine": "It's an amulet of cat speak. It makes vague purring noises.", - "durability": null, - "name": "Catspeak amulet", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4677", - "equipment_slot": "2" - }, - { - "examine": "Varies. See Types", - "durability": null, - "name": "Canopic jar", - "weight": "4", - "archery_ticket_price": "0", - "id": "4678" - }, - { - "examine": "Varies. See Types", - "durability": null, - "name": "Canopic jar", - "weight": "4", - "archery_ticket_price": "0", - "id": "4679" - }, - { - "examine": "Varies. See Types", - "durability": null, - "name": "Canopic jar", - "weight": "4", - "archery_ticket_price": "0", - "id": "4680" - }, - { - "examine": "Varies. See Types", - "durability": null, - "name": "Canopic jar", - "weight": "4", - "archery_ticket_price": "0", - "id": "4681" - }, - { - "shop_price": "300", - "examine": "A blessed holy symbol of Saradomin.", - "grand_exchange_price": "112", - "durability": null, - "name": "Holy symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4682", - "bonuses": "0,0,0,0,0,2,2,2,2,2,3,0,0,8,0" - }, - { - "shop_price": "135", - "examine": "An unholy symbol of Zamorak.", - "grand_exchange_price": "52", - "durability": null, - "name": "Unholy symbol", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4683", - "bonuses": "2,2,2,2,2,0,0,0,0,0,0,0,0,8,0" - }, - { - "shop_price": "30", - "examine": "One sheet of mummy wrap.", - "durability": null, - "name": "Linen", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "4684" - }, - { - "examine": "Little book of embalming by Bod E. Wrapper.", - "durability": null, - "name": "Embalming manual", - "archery_ticket_price": "0", - "id": "4686" - }, - { - "examine": "It's a bucket of sap.", - "durability": null, - "name": "Bucket of sap", - "weight": "2", - "archery_ticket_price": "0", - "id": "4687" - }, - { - "examine": "A little heap of salt.", - "durability": null, - "name": "Pile of salt", - "archery_ticket_price": "0", - "id": "4689" - }, - { - "examine": "Miniature golden statue of a sphinx.", - "durability": null, - "name": "Sphinx's token", - "archery_ticket_price": "0", - "id": "4691" - }, - { - "shop_price": "130000", - "examine": "A very delicate sheet of gold.", - "grand_exchange_price": "132580", - "durability": null, - "name": "Gold leaf", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4692" - }, - { - "examine": "It's a bucket of salty water.", - "durability": null, - "name": "Full bucket", - "archery_ticket_price": "0", - "id": "4693" - }, - { - "shop_price": "11151", - "ge_buy_limit": "25000", - "examine": "A combined Water and Fire Rune.", - "grand_exchange_price": "48", - "durability": null, - "name": "Steam rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4694" - }, - { - "shop_price": "11151", - "ge_buy_limit": "25000", - "examine": "A combined air and water rune.", - "grand_exchange_price": "249", - "durability": null, - "name": "Mist rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4695" - }, - { - "shop_price": "11151", - "ge_buy_limit": "25000", - "examine": "A combined Air and Earth Rune.", - "grand_exchange_price": "20", - "durability": null, - "name": "Dust rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4696" - }, - { - "shop_price": "11151", - "ge_buy_limit": "25000", - "examine": "A combined Air and Fire Rune.", - "grand_exchange_price": "148", - "durability": null, - "name": "Smoke rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4697" - }, - { - "shop_price": "11151", - "ge_buy_limit": "25000", - "examine": "A combined Earth and Water rune.", - "grand_exchange_price": "657", - "durability": null, - "name": "Mud rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4698" - }, - { - "shop_price": "11151", - "ge_buy_limit": "25000", - "examine": "A combined earth and fire rune.", - "grand_exchange_price": "49", - "durability": null, - "name": "Lava rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4699" - }, - { - "examine": "You need to add lamp oil before you can use it.", - "durability": null, - "name": "Sapphire lantern", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4700" - }, - { - "examine": "A bullseye lantern with a sapphire for a lens.", - "durability": null, - "name": "Sapphire lantern", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4701" - }, - { - "examine": "A lantern casting a bright blue beam.", - "durability": null, - "name": "Sapphire lantern", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "4702" - }, - { - "shop_price": "975000", - "examine": "A magic stone to make high-level furniture.", - "grand_exchange_price": "977755", - "durability": null, - "name": "Magic stone", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "4703" - }, - { - "turn90cw_anim": "821", - "examine": "A magic stone bowl for catching the tears of Guthix.", - "walk_anim": "819", - "durability": null, - "destroy": "true", - "weight": "1.8", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "1", - "equipment_slot": "3", - "stand_anim": "808", - "name": "Stone bowl", - "tradeable": "false", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "4704", - "stand_turn_anim": "823" - }, - { - "examine": "This book must be really old!", - "durability": null, - "name": "Crumbling tome", - "archery_ticket_price": "0", - "id": "4707" - }, - { - "remove_head": "true", - "requirements": "{1,70}-{6,70}", - "ge_buy_limit": "10", - "examine": "Ahrim the Blighted's leather hood.", - "durability": null, - "rare_item": "true", - "weight": "0.9", - "absorb": "5,2,0", - "equipment_slot": "0", - "grand_exchange_price": "94300", - "name": "Ahrim's hood", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4708", - "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "94300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ahrim's hood", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4709" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "Ahrim the Blighted's quarterstaff.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", "attack_anims": "419,419,419,419", - "grand_exchange_price": "69500", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4710", - "stand_turn_anim": "1209", - "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", - "requirements": "{0,70}-{6,70}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", "attack_audios": "2555,0,0,0", - "name": "Ahrim's staff" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "69500", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ahrim's staff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4711" - }, - { - "requirements": "{1,70}-{6,70}", - "ge_buy_limit": "10", - "examine": "Ahrim the Blighted's armoured robe top.", - "durability": null, - "rare_item": "true", - "weight": "5", - "absorb": "10,5,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "1000000", - "name": "Ahrim's robetop", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4712", - "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1000000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ahrim's robetop", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4713" - }, - { - "requirements": "{1,70}-{6,70}", - "ge_buy_limit": "10", - "examine": "Ahrim the Blighted's armoured robe skirt.", - "durability": null, - "rare_item": "true", - "weight": "12", - "absorb": "7,3,0", - "equipment_slot": "7", - "grand_exchange_price": "1700000", - "name": "Ahrim's robeskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4714", - "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1700000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ahrim's robeskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4715" - }, - { - "remove_head": "true", - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Dharok the Wretched's helm.", - "durability": "1", - "rare_item": "true", - "weight": "1", - "absorb": "2,0,5", - "equipment_slot": "0", - "grand_exchange_price": "1300000", - "name": "Dharok's helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4716", - "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1300000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dharok's helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4717" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "Dharok the Wretched's greataxe.", - "walk_anim": "2064", - "rare_item": "true", - "turn90ccw_anim": "822", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "820", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2067,2067,2066,2067", - "grand_exchange_price": "516900", - "stand_anim": "2065", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "4718", - "stand_turn_anim": "823", - "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", - "requirements": "{0,70}-{2,70}", - "durability": null, - "weight": "13", - "weapon_interface": "2", - "render_anim": "134", - "name": "Dharok's greataxe" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "516900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dharok's greataxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4719" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Dharok the Wretched's platebody armour.", - "durability": null, - "rare_item": "true", - "weight": "9.9", - "absorb": "5,0,10", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "511400", - "name": "Dharok's platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4720", - "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "511400", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dharok's platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4721" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Dharok the Wretched's plate leg armour.", - "durability": null, - "rare_item": "true", - "weight": "10", - "absorb": "3,0,7", - "equipment_slot": "7", - "grand_exchange_price": "748800", - "name": "Dharok's platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4722", - "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "748800", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dharok's platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4723" - }, - { - "remove_head": "true", - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Guthan the Infested's helm", - "durability": null, - "rare_item": "true", - "weight": "2", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "396300", - "name": "Guthan's helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4724", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "396300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Guthan's helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4725" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "Guthan the Infested's warspear.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "588400", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4726", - "stand_turn_anim": "1209", - "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", - "requirements": "{0,70}", - "durability": null, - "weight": "2.2", - "weapon_interface": "14", - "render_anim": "28", - "name": "Guthan's warspear" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "588400", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Guthan's warspear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4727" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Guthan the Infested's platebody armour.", - "durability": null, - "rare_item": "true", - "weight": "9", - "absorb": "5,0,10", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "316800", - "name": "Guthan's platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4728", - "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "316800", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Guthan's platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4729" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Guthan the Infested's chainskirt.", - "durability": null, - "rare_item": "true", - "weight": "8", - "absorb": "3,0,7", - "equipment_slot": "7", - "grand_exchange_price": "315600", - "name": "Guthan's chainskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4730", - "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "315600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Guthan's chainskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4731" - }, - { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "1", - "examine": "Karil the Tainted's coif.", - "durability": null, - "rare_item": "true", - "absorb": "0,5,2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "38900", - "name": "Karil's coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4732", - "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "38900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karil's coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4733" - }, - { - "ge_buy_limit": "1", - "turn90cw_anim": "2076", - "examine": "Karil the Tainted's repeating crossbow.", - "walk_anim": "2076", - "rare_item": "true", - "turn90ccw_anim": "2076", "attack_speed": "4", - "two_handed": "true", - "turn180_anim": "2076", - "defence_anim": "424", + "bonuses": "10,-1,40,15,0,2,3,1,15,0,0,50,-1,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", "equipment_slot": "3", - "attack_anims": "2075,2075,2075,2075", - "grand_exchange_price": "188000", - "stand_anim": "2074", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,50}-{6,50}", + "run_anim": "1210", + "shop_price": "80000", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "run_anim": "2077", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.25" + }, + { + "id": "4676", + "name": "Ancient staff", "archery_ticket_price": "0", - "id": "4734", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4677", + "name": "Catspeak amulet", + "examine": "It's an amulet of cat speak. It makes vague purring noises.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "1.3" + }, + { + "id": "4678", + "name": "Canopic jar", + "examine": "Varies. See Types", + "archery_ticket_price": "0", + "durability": null, + "weight": "4" + }, + { + "id": "4679", + "name": "Canopic jar", + "examine": "Varies. See Types", + "archery_ticket_price": "0", + "durability": null, + "weight": "4" + }, + { + "id": "4680", + "name": "Canopic jar", + "examine": "Varies. See Types", + "archery_ticket_price": "0", + "durability": null, + "weight": "4" + }, + { + "id": "4681", + "name": "Canopic jar", + "examine": "Varies. See Types", + "archery_ticket_price": "0", + "durability": null, + "weight": "4" + }, + { + "id": "4682", + "name": "Holy symbol", + "examine": "A blessed holy symbol of Saradomin.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,2,2,2,2,2,3,0,0,8,0", + "durability": null, + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "4683", + "name": "Unholy symbol", + "examine": "An unholy symbol of Zamorak.", + "archery_ticket_price": "0", + "bonuses": "2,2,2,2,2,0,0,0,0,0,0,0,0,8,0", + "durability": null, + "shop_price": "135", + "tradeable": "true" + }, + { + "id": "4684", + "name": "Linen", + "examine": "One sheet of mummy wrap.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "30", + "weight": "0.9" + }, + { + "id": "4686", + "name": "Embalming manual", + "examine": "Little book of embalming by Bod E. Wrapper.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4687", + "name": "Bucket of sap", + "examine": "It's a bucket of sap.", + "archery_ticket_price": "0", + "durability": null, + "weight": "2" + }, + { + "id": "4689", + "name": "Pile of salt", + "examine": "A little heap of salt.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4691", + "name": "Sphinx's token", + "examine": "Miniature golden statue of a sphinx.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4692", + "name": "Gold leaf", + "examine": "A very delicate sheet of gold.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "130000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "4693", + "name": "Full bucket", + "examine": "It's a bucket of salty water.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4694", + "name": "Steam rune", + "examine": "A combined Water and Fire Rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "11151", + "tradeable": "true" + }, + { + "id": "4695", + "name": "Mist rune", + "examine": "A combined air and water rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "11151", + "tradeable": "true" + }, + { + "id": "4696", + "name": "Dust rune", + "examine": "A combined Air and Earth Rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "11151", + "tradeable": "true" + }, + { + "id": "4697", + "name": "Smoke rune", + "examine": "A combined Air and Fire Rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "11151", + "tradeable": "true" + }, + { + "id": "4698", + "name": "Mud rune", + "examine": "A combined Earth and Water rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "11151", + "tradeable": "true" + }, + { + "id": "4699", + "name": "Lava rune", + "examine": "A combined earth and fire rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "11151", + "tradeable": "true" + }, + { + "id": "4700", + "name": "Sapphire lantern", + "examine": "You need to add lamp oil before you can use it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1.3" + }, + { + "id": "4701", + "name": "Sapphire lantern", + "examine": "A bullseye lantern with a sapphire for a lens.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1.3" + }, + { + "id": "4702", + "name": "Sapphire lantern", + "examine": "A lantern casting a bright blue beam.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1.3" + }, + { + "id": "4703", + "name": "Magic stone", + "examine": "Doesn't look very special.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "false", + "weight": "2.267" + }, + { + "id": "4704", + "name": "Stone bowl", + "examine": "A magic stone bowl for catching the tears of Guthix.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "render_anim": "1", + "run_anim": "824", + "stand_anim": "808", "stand_turn_anim": "823", - "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,70}", - "durability": null, - "weight": "2", - "weapon_interface": "17", - "render_anim": "372", - "attack_audios": "2700,0,0,0", - "name": "Karil's crossbow" + "tradeable": "false", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weight": "1.8" }, { - "ge_buy_limit": "1", - "grand_exchange_price": "188000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karil's crossbow", - "tradeable": "true", + "id": "4707", + "name": "Crumbling tome", + "examine": "This book must be really old!", "archery_ticket_price": "0", - "id": "4735" + "durability": null }, { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "10000", - "examine": "Karil the Tainted's leather body armour.", + "id": "4708", + "name": "Ahrim's hood", + "examine": "Ahrim the Blighted's leather hood.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", "rare_item": "true", - "weight": "6", - "absorb": "0,10,5", + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "4709", + "name": "Ahrim's hood", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4710", + "name": "Ahrim's staff", + "examine": "Ahrim the Blighted's quarterstaff.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,70}-{6,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "4711", + "name": "Ahrim's staff", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4712", + "name": "Ahrim's robetop", + "examine": "Ahrim the Blighted's armoured robe top.", + "absorb": "10,5,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", + "durability": null, "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "1800000", - "name": "Karil's leathertop", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4736", - "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1800000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karil's leathertop", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4737" - }, - { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "10000", - "examine": "Karil the Tainted's leather skirt.", - "durability": null, + "ge_buy_limit": "10", "rare_item": "true", - "weight": "2", - "absorb": "0,7,3", - "equipment_slot": "7", - "grand_exchange_price": "217000", - "name": "Karil's leatherskirt", + "remove_sleeves": "true", + "requirements": "{1,70}-{6,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4738", - "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0" + "weight": "5" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "217000", + "id": "4713", + "name": "Ahrim's robetop", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karil's leatherskirt", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4739" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { + "id": "4714", + "name": "Ahrim's robeskirt", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "absorb": "7,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,70}-{6,70}", + "tradeable": "true", + "weight": "12" + }, + { + "id": "4715", + "name": "Ahrim's robeskirt", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4716", + "name": "Dharok's helm", + "examine": "Dharok the Wretched's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0", + "durability": "1", + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "10", + "rare_item": "true", + "remove_head": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "4717", + "name": "Dharok's helm", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4718", + "name": "Dharok's greataxe", + "examine": "Dharok the Wretched's greataxe.", + "archery_ticket_price": "0", + "attack_anims": "2067,2067,2066,2067", + "attack_speed": "7", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "10", + "rare_item": "true", + "render_anim": "134", + "requirements": "{0,70}-{2,70}", + "run_anim": "824", + "stand_anim": "2065", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "two_handed": "true", + "walk_anim": "2064", + "weapon_interface": "2", + "weight": "13" + }, + { + "id": "4719", + "name": "Dharok's greataxe", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4720", + "name": "Dharok's platebody", + "examine": "Dharok the Wretched's platebody armour.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "10", + "rare_item": "true", + "remove_sleeves": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9.9" + }, + { + "id": "4721", + "name": "Dharok's platebody", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4722", + "name": "Dharok's platelegs", + "examine": "Dharok the Wretched's plate leg armour.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "durability": null, + "equip_audio": "2243", + "equipment_slot": "7", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "10" + }, + { + "id": "4723", + "name": "Dharok's platelegs", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4724", + "name": "Guthan's helm", + "examine": "Guthan the Infested's helm", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "10", + "rare_item": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "4725", + "name": "Guthan's helm", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4726", + "name": "Guthan's warspear", + "examine": "Guthan the Infested's warspear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "4727", + "name": "Guthan's warspear", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4728", + "name": "Guthan's platebody", + "examine": "Guthan the Infested's platebody armour.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "10", + "rare_item": "true", + "remove_sleeves": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "4729", + "name": "Guthan's platebody", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4730", + "name": "Guthan's chainskirt", + "examine": "Guthan the Infested's chainskirt.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "8" + }, + { + "id": "4731", + "name": "Guthan's chainskirt", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4732", + "name": "Karil's coif", + "examine": "Karil the Tainted's coif.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "1", + "rare_item": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true" + }, + { + "id": "4733", + "name": "Karil's coif", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "4734", + "name": "Karil's crossbow", + "examine": "Karil the Tainted's repeating crossbow.", + "archery_ticket_price": "0", + "attack_anims": "2075,2075,2075,2075", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1", + "rare_item": "true", + "render_anim": "372", + "requirements": "{4,70}", + "run_anim": "2077", + "stand_anim": "2074", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "2076", + "turn90ccw_anim": "2076", + "turn90cw_anim": "2076", + "two_handed": "true", + "walk_anim": "2076", + "weapon_interface": "17", + "weight": "2" + }, + { + "id": "4735", + "name": "Karil's crossbow", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "4736", + "name": "Karil's leathertop", + "examine": "Karil the Tainted's leather body armour.", + "absorb": "0,10,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "10000", + "rare_item": "true", + "remove_sleeves": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "4737", + "name": "Karil's leathertop", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4738", + "name": "Karil's leatherskirt", + "examine": "Karil the Tainted's leather skirt.", + "absorb": "0,7,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "7", + "ge_buy_limit": "10000", + "rare_item": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "4739", + "name": "Karil's leatherskirt", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4740", + "name": "Bolt rack", + "examine": "Must need a special type of crossbow to use this.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,55", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,70}", "shop_price": "420", - "ge_buy_limit": "10000", - "examine": "Must need a special type of crossbow to use this.", - "grand_exchange_price": "238", - "durability": null, - "name": "Bolt rack", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4740", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,55", - "equipment_slot": "13" + "tradeable": "true" }, { + "id": "4745", + "name": "Torag's helm", + "examine": "Torag the Corrupted's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "10", + "rare_item": "true", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Torag the Corrupted's helm.", - "durability": null, - "rare_item": "true", - "weight": "5", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "139000", - "name": "Torag's helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4745", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + "weight": "5" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "139000", + "id": "4746", + "name": "Torag's helm", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Torag's helm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4746" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "requirements": "{0,70}-{2,70}", - "ge_buy_limit": "1000", + "id": "4747", + "name": "Torag's hammers", "examine": "Torag the Corrupted's twin hammers.", - "durability": null, - "rare_item": "true", - "weight": "3", + "archery_ticket_price": "0", + "attack_anims": "2068,2068,2068,2068", + "attack_audios": "1332,0,0,0", "attack_speed": "5", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "rare_item": "true", + "requirements": "{0,70}-{2,70}", + "tradeable": "true", "two_handed": "true", "weapon_interface": "10", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2068,2068,2068,2068", - "grand_exchange_price": "111600", - "attack_audios": "1332,0,0,0", - "name": "Torag's hammers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4747", - "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" + "weight": "3" }, { + "id": "4748", + "name": "Torag's hammers", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "111600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Torag's hammers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4748" + "tradeable": "true" }, { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Torag the Corrupted's platebody armour.", - "durability": null, - "rare_item": "true", - "weight": "9", - "absorb": "5,0,10", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "346200", - "name": "Torag's platebody", - "tradeable": "true", - "archery_ticket_price": "0", "id": "4749", - "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "346200", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Torag's platebody", - "tradeable": "true", + "examine": "Torag the Corrupted's platebody armour.", + "absorb": "5,0,10", "archery_ticket_price": "0", - "id": "4750" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Torag the Corrupted's plate leg armour.", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "10", "rare_item": "true", - "weight": "9", - "absorb": "3,0,7", - "equipment_slot": "7", - "grand_exchange_price": "427200", - "name": "Torag's platelegs", + "remove_sleeves": "true", + "requirements": "{1,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4751", - "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0" + "weight": "9" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "427200", + "id": "4750", + "name": "Torag's platebody", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Torag's platelegs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4752" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { + "id": "4751", + "name": "Torag's platelegs", + "examine": "Torag the Corrupted's plate leg armour.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "4752", + "name": "Torag's platelegs", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4753", + "name": "Verac's helm", + "examine": "Verac the Defiled's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "10", + "rare_item": "true", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Verac the Defiled's helm.", - "durability": null, - "rare_item": "true", - "weight": "1", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "687200", - "name": "Verac's helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4753", - "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" + "weight": "1" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "687200", + "id": "4754", + "name": "Verac's helm", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Verac's helm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4754" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "ge_buy_limit": "10", - "turn90cw_anim": "2060", - "examine": "Verac the Defiled's flail.", - "walk_anim": "1830", - "rare_item": "true", - "turn90ccw_anim": "2060", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "2060", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2062,2062,2062,2062", - "grand_exchange_price": "135500", - "stand_anim": "1832", - "tradeable": "true", - "run_anim": "1831", - "archery_ticket_price": "0", "id": "4755", - "stand_turn_anim": "823", - "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", - "requirements": "{0,70}", - "durability": null, - "weight": "2", - "weapon_interface": "8", - "render_anim": "1426", - "attack_audios": "1323,0,0,0", - "name": "Verac's flail" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "135500", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Verac's flail", - "tradeable": "true", + "examine": "Verac the Defiled's flail.", "archery_ticket_price": "0", - "id": "4756" + "attack_anims": "2062,2062,2062,2062", + "attack_audios": "1323,0,0,0", + "attack_speed": "5", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "10", + "rare_item": "true", + "render_anim": "1426", + "requirements": "{0,70}", + "run_anim": "1831", + "stand_anim": "1832", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "2060", + "turn90ccw_anim": "2060", + "turn90cw_anim": "2060", + "two_handed": "true", + "walk_anim": "1830", + "weapon_interface": "8", + "weight": "2" }, { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Verac the Defiled's brassard.", - "durability": null, - "rare_item": "true", - "weight": "5", - "absorb": "5,0,10", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "270000", - "name": "Verac's brassard", - "tradeable": "true", + "id": "4756", + "name": "Verac's flail", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4757", - "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "270000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Verac's brassard", - "tradeable": "true", + "examine": "Verac the Defiled's brassard.", + "absorb": "5,0,10", "archery_ticket_price": "0", - "id": "4758" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", - "examine": "Verac the Defiled's plate skirt.", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "10", "rare_item": "true", - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "7", - "grand_exchange_price": "411400", - "name": "Verac's plateskirt", + "remove_sleeves": "true", + "requirements": "{1,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4759", - "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0" + "weight": "5" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "411400", + "id": "4758", + "name": "Verac's brassard", "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4759", "name": "Verac's plateskirt", - "tradeable": "true", + "examine": "Verac the Defiled's plate skirt.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "4760" + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "Blunt bronze arrow...ouch", - "grand_exchange_price": "39", - "durability": null, - "name": "Bronze brutal", - "tradeable": "true", + "id": "4760", + "name": "Verac's plateskirt", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4773", + "name": "Bronze brutal", + "examine": "Blunt bronze arrow...ouch", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,11", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true" }, { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "Blunt iron arrow...ouch", - "grand_exchange_price": "14", - "durability": null, - "name": "Iron brutal", - "tradeable": "true", - "archery_ticket_price": "0", "id": "4778", + "name": "Iron brutal", + "examine": "Blunt iron arrow...ouch", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,13", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true" }, { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "Blunt steel arrow...ouch", - "grand_exchange_price": "20", - "durability": null, - "name": "Steel brutal", - "tradeable": "true", - "archery_ticket_price": "0", "id": "4783", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,19", - "equipment_slot": "13" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "Blunt black arrow...ouch", - "grand_exchange_price": "63", - "durability": null, - "name": "Black brutal", - "tradeable": "true", + "name": "Steel brutal", + "examine": "Blunt steel arrow...ouch", "archery_ticket_price": "0", - "id": "4788", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,19", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true" }, { + "id": "4788", + "name": "Black brutal", + "examine": "Blunt black arrow...ouch", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true" + }, + { + "id": "4793", + "name": "Mithril brutal", + "examine": "Blunt mithril arrow...ouch", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,34", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", "requirements": "{4,30}", "shop_price": "20", - "ge_buy_limit": "1000", - "examine": "Blunt mithril arrow...ouch", - "grand_exchange_price": "80", - "durability": null, - "name": "Mithril brutal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4793", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,34", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "Blunt adamant arrow...ouch", - "grand_exchange_price": "154", - "durability": null, - "name": "Adamant brutal", - "tradeable": "true", - "archery_ticket_price": "0", "id": "4798", + "name": "Adamant brutal", + "examine": "Blunt adamant arrow...ouch", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,45", - "equipment_slot": "13" - }, - { - "requirements": "{4,30}", - "shop_price": "180", + "durability": null, + "equipment_slot": "13", "ge_buy_limit": "1000", - "examine": "Blunt rune arrow...ouch", - "grand_exchange_price": "188", - "durability": null, - "name": "Rune brutal", - "tradeable": "true", - "archery_ticket_price": "0", + "requirements": "{4,30}", + "tradeable": "true" + }, + { "id": "4803", + "name": "Rune brutal", + "examine": "Blunt rune arrow...ouch", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "examine": "A very black prism.", "durability": null, - "name": "Black prism", - "archery_ticket_price": "0", - "id": "4808" - }, - { - "examine": "A half torn necromantic page.", - "durability": null, - "name": "Torn page", - "archery_ticket_price": "0", - "id": "4809" - }, - { - "examine": "It's about to fall apart.", - "durability": null, - "name": "Ruined backpack", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "4810" - }, - { - "examine": "A white ceramic mug with a dragon insignia.", - "durability": null, - "name": "Dragon inn tankard", - "archery_ticket_price": "0", - "id": "4811" - }, - { - "ge_buy_limit": "10000", - "examine": "A pile of Zombie Ogre bones.", - "grand_exchange_price": "1167", - "durability": null, - "name": "Zogre bones", - "tradeable": "true", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "4812" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1167", - "durability": null, - "name": "Zogre bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4813" - }, - { - "examine": "A classic realist charcoal portrait of Sithik.", - "durability": null, - "name": "Sithik portrait", - "archery_ticket_price": "0", - "id": "4814" - }, - { - "examine": "A classic realist charcoal portrait of Sithik.", - "durability": null, - "name": "Sithik portrait", - "archery_ticket_price": "0", - "id": "4815" - }, - { - "examine": "A signed classic realist charcoal portrait of Sithik.", - "durability": null, - "name": "Signed portrait", - "archery_ticket_price": "0", - "id": "4816" - }, - { - "examine": "A book explaining the art of portraiture.", - "durability": null, - "name": "Book of portraiture", - "weight": "1", - "archery_ticket_price": "0", - "id": "4817", - "equipment_slot": "5" - }, - { - "examine": "An ancient ogre artefact-resembling a large heavy helm.", - "durability": null, - "name": "Ogre artefact", - "archery_ticket_price": "0", - "id": "4818" - }, - { - "shop_price": "4", - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "16", - "durability": null, - "name": "Bronze nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4819" - }, - { - "shop_price": "33", - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "16", - "durability": null, - "name": "Iron nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4820" - }, - { - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "13", - "durability": null, - "name": "Black nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4821" - }, - { - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "35", - "durability": null, - "name": "Mithril nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4822" - }, - { - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "87", - "durability": null, - "name": "Adamantite nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4823" - }, - { - "ge_buy_limit": "10000", - "examine": "Keeps things in place fairly permanently.", - "grand_exchange_price": "114", - "durability": null, - "name": "Rune nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4824" - }, - { - "ge_buy_limit": "100", - "examine": "An unstrung composite ogre bow.", - "grand_exchange_price": "447", - "durability": null, - "name": "Unstrung comp bow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4825" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "447", - "durability": null, - "name": "Unstrung comp bow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4826" - }, - { + "equipment_slot": "13", + "ge_buy_limit": "1000", "requirements": "{4,30}", "shop_price": "180", - "ge_buy_limit": "100", - "examine": "A composite ogre bow.", + "tradeable": "true" + }, + { + "id": "4808", + "name": "Black prism", + "examine": "A very black prism.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4809", + "name": "Torn page", + "examine": "A half torn necromantic page.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4810", + "name": "Ruined backpack", + "examine": "It's about to fall apart.", + "archery_ticket_price": "0", + "destroy": "true", "durability": null, - "weight": "1.8", + "tradeable": "false" + }, + { + "id": "4811", + "name": "Dragon inn tankard", + "examine": "A white ceramic mug with a dragon insignia.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4812", + "name": "Zogre bones", + "examine": "A pile of Zombie Ogre bones.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "4813", + "name": "Zogre bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4814", + "name": "Sithik portrait", + "examine": "A classic realist charcoal portrait of Sithik.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4815", + "name": "Sithik portrait", + "examine": "A classic realist charcoal portrait of Sithik.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4816", + "name": "Signed portrait", + "examine": "A signed classic realist charcoal portrait of Sithik.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4817", + "name": "Book of portraiture", + "examine": "A book explaining the art of portraiture.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "weight": "1" + }, + { + "id": "4818", + "name": "Ogre artefact", + "examine": "An ancient ogre artefact-resembling a large heavy helm.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "4819", + "name": "Bronze nails", + "examine": "Keeps things in place fairly permanently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "4", + "tradeable": "true" + }, + { + "id": "4820", + "name": "Iron nails", + "examine": "Keeps things in place fairly permanently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "33", + "tradeable": "true" + }, + { + "id": "4821", + "name": "Black nails", + "examine": "Keeps things in place fairly permanently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4822", + "name": "Mithril nails", + "examine": "Keeps things in place fairly permanently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4823", + "name": "Adamantite nails", + "examine": "Keeps things in place fairly permanently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4824", + "name": "Rune nails", + "examine": "Keeps things in place fairly permanently.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4825", + "name": "Unstrung comp bow", + "examine": "An unstrung composite ogre bow.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4826", + "name": "Unstrung comp bow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4827", + "name": "Comp ogre bow", + "examine": "A composite ogre bow.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", "attack_speed": "5", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,30}", + "shop_price": "180", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "225", - "attack_audios": "2700,0,0,0", - "name": "Comp ogre bow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4827", - "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,0" + "weight": "1.8" }, { + "id": "4828", + "name": "Comp ogre bow", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "225", - "durability": null, - "name": "Comp ogre bow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4828" + "tradeable": "true" }, { - "examine": "A book of H.A.M. affiliation", - "durability": null, - "name": "Book of 'h.a.m", - "archery_ticket_price": "0", "id": "4829", + "name": "Book of 'h.a.m", + "examine": "A book of H.A.M. affiliation", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "5" }, { - "ge_buy_limit": "10000", - "examine": "Ancient ogre bones from the ogre burial tomb.", - "grand_exchange_price": "5931", - "durability": null, + "id": "4830", "name": "Fayrg bones", - "tradeable": "true", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "4830" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "5931", - "durability": null, - "name": "Fayrg bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4831" - }, - { - "ge_buy_limit": "10000", "examine": "Ancient ogre bones from the ogre burial tomb.", - "grand_exchange_price": "7093", - "durability": null, - "name": "Raurg bones", - "tradeable": "true", - "weight": "0.8", "archery_ticket_price": "0", - "id": "4832" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.8" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "7093", - "durability": null, - "name": "Raurg bones", - "tradeable": "true", + "id": "4831", + "name": "Fayrg bones", "archery_ticket_price": "0", - "id": "4833" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { + "id": "4832", + "name": "Raurg bones", + "examine": "Ancient ogre bones from the ogre burial tomb.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "4833", + "name": "Raurg bones", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4834", + "name": "Ourg bones", "examine": "Ancient ogre bones from the burial tomb.", - "grand_exchange_price": "16300", - "durability": null, - "name": "Ourg bones", - "tradeable": "true", - "weight": "0.8", "archery_ticket_price": "0", - "id": "4834" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "16300", - "durability": null, - "name": "Ourg bones", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4835" + "weight": "0.8" }, { - "examine": "Some strange liquid given to you by Zavistic Rarve.", + "id": "4835", + "name": "Ourg bones", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "4836", "name": "Strange potion", + "examine": "Some strange liquid given to you by Zavistic Rarve.", "archery_ticket_price": "0", - "id": "4836" + "durability": null }, { - "examine": "A book of necromantic spells.", - "durability": null, - "name": "Necromancy book", - "archery_ticket_price": "0", "id": "4837", + "name": "Necromancy book", + "examine": "A book of necromantic spells.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "5" }, { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, + "id": "4838", "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", + "examine": "A nice cup of tea.", "archery_ticket_price": "0", - "id": "4838" + "durability": null, + "shop_price": "10", + "tradeable": "true", + "weight": "0.1" }, { - "examine": "A key to some sort of special tomb area.", - "durability": null, + "id": "4839", "name": "Ogre gate key", + "examine": "A key to some sort of special tomb area.", "archery_ticket_price": "0", - "id": "4839" + "durability": null }, { - "ge_buy_limit": "100", + "id": "4840", + "name": "Rogue's purse potion(unf)", "examine": "I need another ingredient to finish this rogue's purse potion.", - "grand_exchange_price": "2194", - "durability": null, - "name": "Rogue's purse potion(unf)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4840" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "2194", - "durability": null, - "name": "Rogue's purse potion(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4841" + "tradeable": "true" }, { - "shop_price": "200", - "ge_buy_limit": "1000", + "id": "4841", + "name": "Rogue's purse potion(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "4842", + "name": "Relicym's balm(4)", "examine": "4 doses of Relicym's balm, which helps cure disease.", - "grand_exchange_price": "1430", - "durability": null, - "name": "Relicym's balm(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4842" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "1430", - "durability": null, - "name": "Relicym's balm(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4843" - }, - { "shop_price": "200", + "tradeable": "true" + }, + { + "id": "4843", + "name": "Relicym's balm(4)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4844", + "name": "Relicym's balm(3)", "examine": "3 doses of Relicym's balm, which helps cure disease.", - "grand_exchange_price": "654", - "durability": null, - "name": "Relicym's balm(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4844" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "654", - "durability": null, - "name": "Relicym's balm(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4845" - }, - { "shop_price": "200", + "tradeable": "true" + }, + { + "id": "4845", + "name": "Relicym's balm(3)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4846", + "name": "Relicym's balm(2)", "examine": "2 doses of Relicym's balm, which helps cure disease.", - "grand_exchange_price": "325", - "durability": null, - "name": "Relicym's balm(2)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4846" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "325", - "durability": null, - "name": "Relicym's balm(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4847" - }, - { "shop_price": "200", + "tradeable": "true" + }, + { + "id": "4847", + "name": "Relicym's balm(2)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4848", + "name": "Relicym's balm(1)", "examine": "1 dose of Relicym's balm, which helps cure disease.", - "grand_exchange_price": "204", - "durability": null, - "name": "Relicym's balm(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4848" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "204", - "durability": null, - "name": "Relicym's balm(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4849" + "shop_price": "200", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "4849", + "name": "Relicym's balm(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "4850", + "name": "Ogre coffin key", "examine": "A key which opens a coffin!", - "grand_exchange_price": "1963", - "durability": null, - "name": "Ogre coffin key", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4850" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1963", - "durability": null, + "tradeable": "true" + }, + { + "id": "4851", "name": "Ogre coffin key", - "tradeable": "true", "archery_ticket_price": "0", - "id": "4851" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "4852", + "name": "Bonemeal", "examine": "A pot of crushed fayrg bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4852" + "durability": null, + "weight": "1" }, { + "id": "4853", + "name": "Bonemeal", "examine": "A pot of crushed raurg bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4853" + "durability": null, + "weight": "1" }, { + "id": "4854", + "name": "Bonemeal", "examine": "A pot of crushed ourg bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4854" + "durability": null, + "weight": "1" }, { + "id": "4855", + "name": "Bonemeal", "examine": "A pot of crushed gorilla monkey bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", "archery_ticket_price": "0", - "id": "4855" + "durability": null, + "weight": "1" }, { - "remove_head": "true", - "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's leather hood.", - "grand_exchange_price": "77678", - "durability": null, - "name": "Ahrim's hood 100", - "weight": "0.9", - "archery_ticket_price": "0", "id": "4856", + "name": "Ahrim's hood 100", + "examine": "Ahrim the Blighted's leather hood.", "absorb": "5,2,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's leather hood.", - "grand_exchange_price": "77678", - "durability": null, - "name": "Ahrim's hood 75", - "weight": "0.9", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "4857", + "name": "Ahrim's hood 75", + "examine": "Ahrim the Blighted's leather hood.", "absorb": "5,2,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's leather hood.", - "grand_exchange_price": "77678", - "durability": null, - "name": "Ahrim's hood 50", - "weight": "0.9", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "4858", + "name": "Ahrim's hood 50", + "examine": "Ahrim the Blighted's leather hood.", "absorb": "5,2,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's leather hood.", - "grand_exchange_price": "77678", - "durability": null, - "name": "Ahrim's hood 25", - "weight": "0.9", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "4859", - "absorb": "5,2,0", - "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,70}-{6,70}", - "ge_buy_limit": "10", + "name": "Ahrim's hood 25", "examine": "Ahrim the Blighted's leather hood.", - "durability": null, - "weight": "0.9", "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", + "durability": null, "equipment_slot": "0", - "grand_exchange_price": "51700", - "name": "Ahrim's hood 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4860" + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "weight": "0.9" }, { + "id": "4860", + "name": "Ahrim's hood 0", + "examine": "Ahrim the Blighted's leather hood.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "ge_buy_limit": "10", - "grand_exchange_price": "51700", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ahrim's hood 0", + "remove_head": "true", + "requirements": "{1,70}-{6,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4861" + "weight": "0.9" }, { - "requirements": "{0,70}-{6,70}", - "turn90cw_anim": "1207", - "examine": "Ahrim the Blighted's quarterstaff.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "50655", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Ahrim's staff 100", - "run_anim": "1210", + "id": "4861", + "name": "Ahrim's hood 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4862", + "name": "Ahrim's staff 100", + "examine": "Ahrim the Blighted's quarterstaff.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}-{6,70}", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" }, { - "requirements": "{0,70}-{6,70}", - "turn90cw_anim": "1207", - "examine": "Ahrim the Blighted's quarterstaff.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "50655", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Ahrim's staff 75", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4863", + "name": "Ahrim's staff 75", + "examine": "Ahrim the Blighted's quarterstaff.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}-{6,70}", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" }, { - "requirements": "{0,70}-{6,70}", - "turn90cw_anim": "1207", - "examine": "Ahrim the Blighted's quarterstaff.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "50655", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Ahrim's staff 50", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4864", - "stand_turn_anim": "1209", - "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" - }, - { - "requirements": "{0,70}-{6,70}", - "turn90cw_anim": "1207", + "name": "Ahrim's staff 50", "examine": "Ahrim the Blighted's quarterstaff.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "419,419,419,419", - "grand_exchange_price": "50655", - "stand_anim": "813", "attack_audios": "2555,0,0,0", - "name": "Ahrim's staff 25", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4865", - "stand_turn_anim": "1209", - "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" - }, - { - "requirements": "{0,70}-{6,70}", - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "Ahrim the Blighted's quarterstaff.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", "attack_speed": "6", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}-{6,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "50600", - "stand_anim": "813", + "weight": "2" + }, + { + "id": "4865", + "name": "Ahrim's staff 25", + "examine": "Ahrim the Blighted's quarterstaff.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", "attack_audios": "2555,0,0,0", - "name": "Ahrim's staff 0", - "tradeable": "true", + "attack_speed": "6", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}-{6,70}", "run_anim": "1210", - "archery_ticket_price": "0", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { "id": "4866", - "stand_turn_anim": "1209" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "50600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Ahrim's staff 0", - "tradeable": "true", + "examine": "Ahrim the Blighted's quarterstaff.", "archery_ticket_price": "0", - "id": "4867" + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "28", + "requirements": "{0,70}-{6,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" }, { - "requirements": "{1,70}-{6,70}", - "remove_sleeves": "true", - "examine": "Ahrim the Blighted's armoured robe top.", - "grand_exchange_price": "1458307", - "durability": null, - "name": "Ahrim's top 100", - "weight": "5", + "id": "4867", + "name": "Ahrim's staff 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4868", + "name": "Ahrim's top 100", + "examine": "Ahrim the Blighted's armoured robe top.", "absorb": "10,5,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}-{6,70}", + "weight": "5" }, { - "requirements": "{1,70}-{6,70}", - "remove_sleeves": "true", - "examine": "Ahrim the Blighted's armoured robe top.", - "grand_exchange_price": "1458307", - "durability": null, - "name": "Ahrim's top 75", - "weight": "5", - "archery_ticket_price": "0", "id": "4869", + "name": "Ahrim's top 75", + "examine": "Ahrim the Blighted's armoured robe top.", "absorb": "10,5,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}-{6,70}", + "weight": "5" }, { - "requirements": "{1,70}-{6,70}", - "remove_sleeves": "true", - "examine": "Ahrim the Blighted's armoured robe top.", - "grand_exchange_price": "1458307", - "durability": null, - "name": "Ahrim's top 50", - "weight": "5", - "archery_ticket_price": "0", "id": "4870", + "name": "Ahrim's top 50", + "examine": "Ahrim the Blighted's armoured robe top.", "absorb": "10,5,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}-{6,70}", + "weight": "5" }, { - "requirements": "{1,70}-{6,70}", - "remove_sleeves": "true", - "examine": "Ahrim the Blighted's armoured robe top.", - "grand_exchange_price": "1458307", - "durability": null, - "name": "Ahrim's top 25", - "weight": "5", - "archery_ticket_price": "0", "id": "4871", - "absorb": "10,5,0", - "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}-{6,70}", - "ge_buy_limit": "10", + "name": "Ahrim's top 25", "examine": "Ahrim the Blighted's armoured robe top.", - "durability": null, - "weight": "5", "absorb": "10,5,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "1100000", - "name": "Ahrim's top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4872" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1100000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ahrim's top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4873" - }, - { "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's armoured robe skirt.", - "grand_exchange_price": "1561591", - "durability": null, - "name": "Ahrim's skirt 100", - "weight": "12", + "weight": "5" + }, + { + "id": "4872", + "name": "Ahrim's top 0", + "examine": "Ahrim the Blighted's armoured robe top.", + "absorb": "10,5,0", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,70}-{6,70}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "4873", + "name": "Ahrim's top 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4874", + "name": "Ahrim's skirt 100", + "examine": "Ahrim the Blighted's armoured robe skirt.", "absorb": "7,3,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,70}-{6,70}", + "weight": "12" }, { - "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's armoured robe skirt.", - "grand_exchange_price": "1561591", - "durability": null, - "name": "Ahrim's skirt 75", - "weight": "12", - "archery_ticket_price": "0", "id": "4875", + "name": "Ahrim's skirt 75", + "examine": "Ahrim the Blighted's armoured robe skirt.", "absorb": "7,3,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,70}-{6,70}", + "weight": "12" }, { - "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's armoured robe skirt.", - "grand_exchange_price": "1561591", - "durability": null, - "name": "Ahrim's skirt 50", - "weight": "12", - "archery_ticket_price": "0", "id": "4876", + "name": "Ahrim's skirt 50", + "examine": "Ahrim the Blighted's armoured robe skirt.", "absorb": "7,3,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,70}-{6,70}", + "weight": "12" }, { - "requirements": "{1,70}-{6,70}", - "examine": "Ahrim the Blighted's armoured robe skirt.", - "grand_exchange_price": "1561591", - "durability": null, - "name": "Ahrim's skirt 25", - "weight": "12", - "archery_ticket_price": "0", "id": "4877", - "absorb": "7,3,0", - "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,70}-{6,70}", - "ge_buy_limit": "10", + "name": "Ahrim's skirt 25", "examine": "Ahrim the Blighted's armoured robe skirt.", - "grand_exchange_price": "1500000", - "durability": null, - "name": "Ahrim's skirt 0", - "tradeable": "true", - "weight": "12", - "archery_ticket_price": "0", - "id": "4878", "absorb": "7,3,0", - "equipment_slot": "7" + "archery_ticket_price": "0", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,70}-{6,70}", + "weight": "12" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "1500000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, + "id": "4878", "name": "Ahrim's skirt 0", - "tradeable": "true", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "absorb": "7,3,0", "archery_ticket_price": "0", - "id": "4879" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,70}-{6,70}", + "tradeable": "true", + "weight": "12" }, { - "remove_head": "true", - "requirements": "{1,70}", - "examine": "Dharok the Wretched's helm.", - "grand_exchange_price": "1355582", - "durability": null, - "name": "Dharok's helm 100", - "weight": "1", + "id": "4879", + "name": "Ahrim's skirt 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4880", + "name": "Dharok's helm 100", + "examine": "Dharok the Wretched's helm.", "absorb": "2,0,5", + "archery_ticket_price": "0", "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,70}", - "examine": "Dharok the Wretched's helm.", - "grand_exchange_price": "1355582", - "durability": null, - "name": "Dharok's helm 75", - "weight": "1", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "4881", + "name": "Dharok's helm 75", + "examine": "Dharok the Wretched's helm.", "absorb": "2,0,5", + "archery_ticket_price": "0", "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,70}", - "examine": "Dharok the Wretched's helm.", - "grand_exchange_price": "1355582", - "durability": null, - "name": "Dharok's helm 50", - "weight": "1", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "4882", + "name": "Dharok's helm 50", + "examine": "Dharok the Wretched's helm.", "absorb": "2,0,5", + "archery_ticket_price": "0", "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,70}", - "examine": "Dharok the Wretched's helm.", - "grand_exchange_price": "1355582", - "durability": null, - "name": "Dharok's helm 25", - "weight": "1", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "4883", - "absorb": "2,0,5", - "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Dharok's helm 25", "examine": "Dharok the Wretched's helm.", - "durability": null, - "weight": "1", "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "1300000", - "name": "Dharok's helm 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4884" + "remove_head": "true", + "requirements": "{1,70}", + "weight": "1" }, { + "id": "4884", + "name": "Dharok's helm 0", + "examine": "Dharok the Wretched's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "ge_buy_limit": "10", - "grand_exchange_price": "1300000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dharok's helm 0", + "remove_head": "true", + "requirements": "{1,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4885" + "weight": "1" }, { - "requirements": "{0,70}-{2,70}", - "turn90cw_anim": "2064", - "examine": "Dharok the Wretched's greataxe.", - "walk_anim": "2064", - "durability": null, - "weight": "13", - "turn90ccw_anim": "2064", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "2", - "turn180_anim": "2064", - "defence_anim": "424", - "render_anim": "134", - "equipment_slot": "3", - "attack_anims": "2067,2067,2066,2067", - "grand_exchange_price": "454500", - "stand_anim": "2065", - "attack_audios": "1320,0,0,0", - "name": "Dharok's axe 100", - "run_anim": "824", + "id": "4885", + "name": "Dharok's helm 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4886", + "name": "Dharok's axe 100", + "examine": "Dharok the Wretched's greataxe.", + "archery_ticket_price": "0", + "attack_anims": "2067,2067,2066,2067", + "attack_audios": "1320,0,0,0", + "attack_speed": "7", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "render_anim": "134", + "requirements": "{0,70}-{2,70}", + "run_anim": "824", + "stand_anim": "2065", "stand_turn_anim": "823", - "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0" + "turn180_anim": "2064", + "turn90ccw_anim": "2064", + "turn90cw_anim": "2064", + "two_handed": "true", + "walk_anim": "2064", + "weapon_interface": "2", + "weight": "13" }, { - "requirements": "{0,70}-{2,70}", - "turn90cw_anim": "2064", - "examine": "Dharok the Wretched's greataxe.", - "walk_anim": "2064", - "durability": null, - "weight": "13", - "turn90ccw_anim": "2064", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "2", - "turn180_anim": "2064", - "defence_anim": "424", - "render_anim": "134", - "equipment_slot": "3", - "attack_anims": "2067,2067,2066,2067", - "grand_exchange_price": "454500", - "stand_anim": "2065", - "attack_audios": "1320,0,0,0", - "name": "Dharok's axe 75", - "run_anim": "824", - "archery_ticket_price": "0", "id": "4887", + "name": "Dharok's axe 75", + "examine": "Dharok the Wretched's greataxe.", + "archery_ticket_price": "0", + "attack_anims": "2067,2067,2066,2067", + "attack_audios": "1320,0,0,0", + "attack_speed": "7", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "render_anim": "134", + "requirements": "{0,70}-{2,70}", + "run_anim": "824", + "stand_anim": "2065", "stand_turn_anim": "823", - "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0" + "turn180_anim": "2064", + "turn90ccw_anim": "2064", + "turn90cw_anim": "2064", + "two_handed": "true", + "walk_anim": "2064", + "weapon_interface": "2", + "weight": "13" }, { - "requirements": "{0,70}-{2,70}", - "turn90cw_anim": "2064", - "examine": "Dharok the Wretched's greataxe.", - "walk_anim": "2064", - "durability": null, - "weight": "13", - "turn90ccw_anim": "2064", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "2", - "turn180_anim": "2064", - "defence_anim": "424", - "render_anim": "134", - "equipment_slot": "3", - "attack_anims": "2067,2067,2066,2067", - "grand_exchange_price": "454500", - "stand_anim": "2065", - "attack_audios": "1320,0,0,0", - "name": "Dharok's axe 50", - "run_anim": "824", - "archery_ticket_price": "0", "id": "4888", - "stand_turn_anim": "823", - "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0" - }, - { - "requirements": "{0,70}-{2,70}", - "turn90cw_anim": "2064", + "name": "Dharok's axe 50", "examine": "Dharok the Wretched's greataxe.", - "walk_anim": "2064", - "durability": null, - "weight": "13", - "turn90ccw_anim": "2064", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "2", - "turn180_anim": "2064", - "defence_anim": "424", - "render_anim": "134", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "2067,2067,2066,2067", - "grand_exchange_price": "454500", - "stand_anim": "2065", "attack_audios": "1320,0,0,0", - "name": "Dharok's axe 25", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "4889", - "stand_turn_anim": "823", - "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0" - }, - { - "requirements": "{0,70}-{2,70}", - "ge_buy_limit": "10", - "turn90cw_anim": "2064", - "examine": "Dharok the Wretched's greataxe.", - "walk_anim": "2064", - "durability": null, - "weight": "13", - "turn90ccw_anim": "2064", "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "2", - "turn180_anim": "2064", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", "render_anim": "134", - "equipment_slot": "3", - "grand_exchange_price": "442600", - "stand_anim": "2065", - "attack_audios": "1320,0,0,0", - "tradeable": "true", - "name": "Dharok's axe 0", + "requirements": "{0,70}-{2,70}", "run_anim": "824", + "stand_anim": "2065", + "stand_turn_anim": "823", + "turn180_anim": "2064", + "turn90ccw_anim": "2064", + "turn90cw_anim": "2064", + "two_handed": "true", + "walk_anim": "2064", + "weapon_interface": "2", + "weight": "13" + }, + { + "id": "4889", + "name": "Dharok's axe 25", + "examine": "Dharok the Wretched's greataxe.", "archery_ticket_price": "0", + "attack_anims": "2067,2067,2066,2067", + "attack_audios": "1320,0,0,0", + "attack_speed": "7", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "render_anim": "134", + "requirements": "{0,70}-{2,70}", + "run_anim": "824", + "stand_anim": "2065", + "stand_turn_anim": "823", + "turn180_anim": "2064", + "turn90ccw_anim": "2064", + "turn90cw_anim": "2064", + "two_handed": "true", + "walk_anim": "2064", + "weapon_interface": "2", + "weight": "13" + }, + { "id": "4890", - "stand_turn_anim": "823" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "442600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Dharok's axe 0", - "tradeable": "true", + "examine": "Dharok the Wretched's greataxe.", "archery_ticket_price": "0", - "id": "4891" + "attack_audios": "1320,0,0,0", + "attack_speed": "7", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "134", + "requirements": "{0,70}-{2,70}", + "run_anim": "824", + "stand_anim": "2065", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "2064", + "turn90ccw_anim": "2064", + "turn90cw_anim": "2064", + "two_handed": "true", + "walk_anim": "2064", + "weapon_interface": "2", + "weight": "13" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Dharok the Wretched's platebody armour.", - "grand_exchange_price": "481600", - "durability": null, - "name": "Dharok's body 100", - "weight": "9.9", + "id": "4891", + "name": "Dharok's axe 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4892", + "name": "Dharok's body 100", + "examine": "Dharok the Wretched's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9.9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Dharok the Wretched's platebody armour.", - "grand_exchange_price": "481600", - "durability": null, - "name": "Dharok's body 75", - "weight": "9.9", - "archery_ticket_price": "0", "id": "4893", + "name": "Dharok's body 75", + "examine": "Dharok the Wretched's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9.9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Dharok the Wretched's platebody armour.", - "grand_exchange_price": "481600", - "durability": null, - "name": "Dharok's body 50", - "weight": "9.9", - "archery_ticket_price": "0", "id": "4894", + "name": "Dharok's body 50", + "examine": "Dharok the Wretched's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9.9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Dharok the Wretched's platebody armour.", - "grand_exchange_price": "481600", - "durability": null, - "name": "Dharok's body 25", - "weight": "9.9", - "archery_ticket_price": "0", "id": "4895", - "absorb": "5,0,10", - "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Dharok's body 25", "examine": "Dharok the Wretched's platebody armour.", - "durability": null, - "weight": "9.9", "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "438200", - "name": "Dharok's body 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4896" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "438200", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dharok's body 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4897" - }, - { "requirements": "{1,70}", - "examine": "Dharok the Wretched's plate leg armour.", - "grand_exchange_price": "897451", - "durability": null, - "name": "Dharok's legs 100", - "weight": "10", + "weight": "9.9" + }, + { + "id": "4896", + "name": "Dharok's body 0", + "examine": "Dharok the Wretched's platebody armour.", + "absorb": "5,0,10", "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9.9" + }, + { + "id": "4897", + "name": "Dharok's body 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4898", + "name": "Dharok's legs 100", + "examine": "Dharok the Wretched's plate leg armour.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2243", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "10" }, { - "requirements": "{1,70}", - "examine": "Dharok the Wretched's plate leg armour.", - "grand_exchange_price": "897451", - "durability": null, - "name": "Dharok's legs 75", - "weight": "10", - "archery_ticket_price": "0", "id": "4899", + "name": "Dharok's legs 75", + "examine": "Dharok the Wretched's plate leg armour.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2243", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "10" }, { - "requirements": "{1,70}", - "examine": "Dharok the Wretched's plate leg armour.", - "grand_exchange_price": "897451", - "durability": null, - "name": "Dharok's legs 50", - "weight": "10", - "archery_ticket_price": "0", "id": "4900", + "name": "Dharok's legs 50", + "examine": "Dharok the Wretched's plate leg armour.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2243", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "10" }, { - "requirements": "{1,70}", - "examine": "Dharok the Wretched's plate leg armour.", - "grand_exchange_price": "897451", - "durability": null, - "name": "Dharok's legs 25", - "weight": "10", - "archery_ticket_price": "0", "id": "4901", - "absorb": "3,0,7", - "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Dharok's legs 25", "examine": "Dharok the Wretched's plate leg armour.", - "grand_exchange_price": "676000", - "durability": null, - "name": "Dharok's legs 0", - "tradeable": "true", - "weight": "10", + "absorb": "3,0,7", "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "durability": null, + "equip_audio": "2243", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "10" + }, + { "id": "4902", - "absorb": "3,0,7", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "676000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Dharok's legs 0", - "tradeable": "true", + "examine": "Dharok the Wretched's plate leg armour.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "4903" + "durability": null, + "equip_audio": "2243", + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "10" }, { - "remove_head": "true", - "requirements": "{1,70}", - "examine": "Guthan the Infested's helm", - "durability": null, - "weight": "2", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "232455", - "name": "Guthan's helm 100", + "id": "4903", + "name": "Dharok's legs 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4904", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { + "name": "Guthan's helm 100", + "examine": "Guthan the Infested's helm", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Guthan the Infested's helm", - "durability": null, - "weight": "2", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "232455", - "name": "Guthan's helm 75", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "4905", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { + "name": "Guthan's helm 75", + "examine": "Guthan the Infested's helm", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Guthan the Infested's helm", - "durability": null, - "weight": "2", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "232455", - "name": "Guthan's helm 50", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "4906", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { + "name": "Guthan's helm 50", + "examine": "Guthan the Infested's helm", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Guthan the Infested's helm", - "durability": null, - "weight": "2", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "232455", - "name": "Guthan's helm 25", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "4907", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Guthan's helm 25", "examine": "Guthan the Infested's helm", - "durability": null, - "weight": "2", "absorb": "2,0,5", - "remove_beard": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "368200", - "name": "Guthan's helm 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4908" + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}", + "weight": "2" }, { + "id": "4908", + "name": "Guthan's helm 0", + "examine": "Guthan the Infested's helm", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "ge_buy_limit": "10", - "grand_exchange_price": "368200", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Guthan's helm 0", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4909" + "weight": "2" }, { - "requirements": "{0,70}", - "turn90cw_anim": "1207", - "examine": "Guthan the Infested's warspear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "371782", - "stand_anim": "813", - "attack_audios": "1316,0,0,0", - "name": "Guthan's spear 100", - "run_anim": "1210", + "id": "4909", + "name": "Guthan's helm 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4910", + "name": "Guthan's spear 100", + "examine": "Guthan the Infested's warspear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_audios": "1316,0,0,0", + "attack_speed": "5", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "requirements": "{0,70}", - "turn90cw_anim": "1207", - "examine": "Guthan the Infested's warspear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "371782", - "stand_anim": "813", - "attack_audios": "1316,0,0,0", - "name": "Guthan's spear 75", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4911", + "name": "Guthan's spear 75", + "examine": "Guthan the Infested's warspear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_audios": "1316,0,0,0", + "attack_speed": "5", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "requirements": "{0,70}", - "turn90cw_anim": "1207", - "examine": "Guthan the Infested's warspear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "371782", - "stand_anim": "813", - "attack_audios": "1316,0,0,0", - "name": "Guthan's spear 50", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "4912", - "stand_turn_anim": "1209", - "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0" - }, - { - "requirements": "{0,70}", - "turn90cw_anim": "1207", + "name": "Guthan's spear 50", "examine": "Guthan the Infested's warspear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "371782", - "stand_anim": "813", "attack_audios": "1316,0,0,0", - "name": "Guthan's spear 25", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "4913", - "stand_turn_anim": "1209", - "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0" - }, - { - "requirements": "{0,70}", - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "Guthan the Infested's warspear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "379500", - "stand_anim": "813", - "attack_audios": "1316,0,0,0", - "tradeable": "true", - "name": "Guthan's spear 0", + "requirements": "{0,70}", "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "4913", + "name": "Guthan's spear 25", + "examine": "Guthan the Infested's warspear.", "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_audios": "1316,0,0,0", + "attack_speed": "5", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { "id": "4914", - "stand_turn_anim": "1209" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "379500", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Guthan's spear 0", - "tradeable": "true", + "examine": "Guthan the Infested's warspear.", "archery_ticket_price": "0", - "id": "4915" + "attack_audios": "1316,0,0,0", + "attack_speed": "5", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "28", + "requirements": "{0,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Guthan the Infested's platebody armour.", - "grand_exchange_price": "241605", - "durability": null, - "name": "Guthan's body 100", - "weight": "9", + "id": "4915", + "name": "Guthan's spear 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4916", + "name": "Guthan's body 100", + "examine": "Guthan the Infested's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Guthan the Infested's platebody armour.", - "grand_exchange_price": "241605", - "durability": null, - "name": "Guthan's body 75", - "weight": "9", - "archery_ticket_price": "0", "id": "4917", + "name": "Guthan's body 75", + "examine": "Guthan the Infested's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Guthan the Infested's platebody armour.", - "grand_exchange_price": "241605", - "durability": null, - "name": "Guthan's body 50", - "weight": "9", - "archery_ticket_price": "0", "id": "4918", + "name": "Guthan's body 50", + "examine": "Guthan the Infested's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Guthan the Infested's platebody armour.", - "grand_exchange_price": "241605", - "durability": null, - "name": "Guthan's body 25", - "weight": "9", - "archery_ticket_price": "0", "id": "4919", - "absorb": "5,0,10", - "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Guthan's body 25", "examine": "Guthan the Infested's platebody armour.", - "durability": null, - "weight": "9", "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "245900", - "name": "Guthan's body 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4920" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "245900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Guthan's body 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4921" - }, - { "requirements": "{1,70}", - "examine": "Guthan the Infested's chainskirt.", - "grand_exchange_price": "224030", - "durability": null, - "name": "Guthan's skirt 100", - "weight": "8", + "weight": "9" + }, + { + "id": "4920", + "name": "Guthan's body 0", + "examine": "Guthan the Infested's platebody armour.", + "absorb": "5,0,10", "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "4921", + "name": "Guthan's body 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4922", + "name": "Guthan's skirt 100", + "examine": "Guthan the Infested's chainskirt.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "8" }, { - "requirements": "{1,70}", - "examine": "Guthan the Infested's chainskirt.", - "grand_exchange_price": "224030", - "durability": null, - "name": "Guthan's skirt 75", - "weight": "8", - "archery_ticket_price": "0", "id": "4923", + "name": "Guthan's skirt 75", + "examine": "Guthan the Infested's chainskirt.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "8" }, { - "requirements": "{1,70}", - "examine": "Guthan the Infested's chainskirt.", - "grand_exchange_price": "224030", - "durability": null, - "name": "Guthan's skirt 50", - "weight": "8", - "archery_ticket_price": "0", "id": "4924", + "name": "Guthan's skirt 50", + "examine": "Guthan the Infested's chainskirt.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "8" }, { - "requirements": "{1,70}", - "examine": "Guthan the Infested's chainskirt.", - "grand_exchange_price": "224030", - "durability": null, - "name": "Guthan's skirt 25", - "weight": "8", - "archery_ticket_price": "0", "id": "4925", - "absorb": "3,0,7", - "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Guthan's skirt 25", "examine": "Guthan the Infested's chainskirt.", - "grand_exchange_price": "240900", - "durability": null, - "name": "Guthan's skirt 0", - "tradeable": "true", - "weight": "8", + "absorb": "3,0,7", "archery_ticket_price": "0", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "8" + }, + { "id": "4926", - "absorb": "3,0,7", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "240900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Guthan's skirt 0", - "tradeable": "true", + "examine": "Guthan the Infested's chainskirt.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "4927" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "8" }, { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's coif.", - "grand_exchange_price": "7520", - "durability": null, - "name": "Karil's coif 100", + "id": "4927", + "name": "Guthan's skirt 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4928", + "name": "Karil's coif 100", + "examine": "Karil the Tainted's coif.", "absorb": "0,5,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "requirements": "{1,70}-{4,70}" }, { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's coif.", - "grand_exchange_price": "7520", - "durability": null, - "name": "Karil's coif 75", - "archery_ticket_price": "0", "id": "4929", + "name": "Karil's coif 75", + "examine": "Karil the Tainted's coif.", "absorb": "0,5,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "requirements": "{1,70}-{4,70}" }, { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's coif.", - "grand_exchange_price": "7520", - "durability": null, - "name": "Karil's coif 50", - "archery_ticket_price": "0", "id": "4930", + "name": "Karil's coif 50", + "examine": "Karil the Tainted's coif.", "absorb": "0,5,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "requirements": "{1,70}-{4,70}" }, { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's coif.", - "grand_exchange_price": "7520", - "durability": null, - "name": "Karil's coif 25", - "archery_ticket_price": "0", "id": "4931", - "absorb": "0,5,2", - "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0", - "remove_beard": "true", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "1", + "name": "Karil's coif 25", "examine": "Karil the Tainted's coif.", - "durability": null, "absorb": "0,5,2", - "remove_beard": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0", + "durability": null, + "equip_audio": "2238", "equipment_slot": "0", - "grand_exchange_price": "7557", - "name": "Karil's coif 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4932" + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}-{4,70}" }, { + "id": "4932", + "name": "Karil's coif 0", + "examine": "Karil the Tainted's coif.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "ge_buy_limit": "1", - "grand_exchange_price": "7557", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karil's coif 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4933" + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true" }, { - "requirements": "{4,70}", - "turn90cw_anim": "2076", - "examine": "Karil the Tainted's repeating crossbow.", - "walk_anim": "2076", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2076", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "17", - "turn180_anim": "2076", - "defence_anim": "424", - "render_anim": "372", - "equipment_slot": "3", - "attack_anims": "2075,2075,2075,2075", - "grand_exchange_price": "108029", - "stand_anim": "2074", - "attack_audios": "2700,0,0,0", - "name": "Karil's x-bow 100", - "run_anim": "2077", + "id": "4933", + "name": "Karil's coif 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { "id": "4934", + "name": "Karil's x-bow 100", + "examine": "Karil the Tainted's repeating crossbow.", + "archery_ticket_price": "0", + "attack_anims": "2075,2075,2075,2075", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "372", + "requirements": "{4,70}", + "run_anim": "2077", + "stand_anim": "2074", "stand_turn_anim": "823", - "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0" + "turn180_anim": "2076", + "turn90ccw_anim": "2076", + "turn90cw_anim": "2076", + "two_handed": "true", + "walk_anim": "2076", + "weapon_interface": "17", + "weight": "2" }, { - "requirements": "{4,70}", - "turn90cw_anim": "2076", - "examine": "Karil the Tainted's repeating crossbow.", - "walk_anim": "2076", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2076", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "17", - "turn180_anim": "2076", - "defence_anim": "424", - "render_anim": "372", - "equipment_slot": "3", - "attack_anims": "2075,2075,2075,2075", - "grand_exchange_price": "108029", - "stand_anim": "2074", - "attack_audios": "2700,0,0,0", - "name": "Karil's x-bow 75", - "run_anim": "2077", - "archery_ticket_price": "0", "id": "4935", + "name": "Karil's x-bow 75", + "examine": "Karil the Tainted's repeating crossbow.", + "archery_ticket_price": "0", + "attack_anims": "2075,2075,2075,2075", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "372", + "requirements": "{4,70}", + "run_anim": "2077", + "stand_anim": "2074", "stand_turn_anim": "823", - "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0" + "turn180_anim": "2076", + "turn90ccw_anim": "2076", + "turn90cw_anim": "2076", + "two_handed": "true", + "walk_anim": "2076", + "weapon_interface": "17", + "weight": "2" }, { - "requirements": "{4,70}", - "turn90cw_anim": "2076", - "examine": "Karil the Tainted's repeating crossbow.", - "walk_anim": "2076", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2076", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "17", - "turn180_anim": "2076", - "defence_anim": "424", - "render_anim": "372", - "equipment_slot": "3", - "attack_anims": "2075,2075,2075,2075", - "grand_exchange_price": "108029", - "stand_anim": "2074", - "attack_audios": "2700,0,0,0", - "name": "Karil's x-bow 50", - "run_anim": "2077", - "archery_ticket_price": "0", "id": "4936", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0" - }, - { - "requirements": "{4,70}", - "turn90cw_anim": "2076", + "name": "Karil's x-bow 50", "examine": "Karil the Tainted's repeating crossbow.", - "walk_anim": "2076", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2076", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "17", - "turn180_anim": "2076", - "defence_anim": "424", - "render_anim": "372", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "2075,2075,2075,2075", - "grand_exchange_price": "108029", - "stand_anim": "2074", "attack_audios": "2700,0,0,0", - "name": "Karil's x-bow 25", - "run_anim": "2077", - "archery_ticket_price": "0", - "id": "4937", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0" - }, - { - "requirements": "{4,70}", - "ge_buy_limit": "10", - "turn90cw_anim": "2076", - "examine": "Karil the Tainted's repeating crossbow.", - "walk_anim": "2076", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2076", "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "17", - "turn180_anim": "2076", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", "render_anim": "372", - "equipment_slot": "3", - "grand_exchange_price": "106300", - "stand_anim": "2074", - "name": "Karil's x-bow 0", - "tradeable": "true", + "requirements": "{4,70}", "run_anim": "2077", + "stand_anim": "2074", + "stand_turn_anim": "823", + "turn180_anim": "2076", + "turn90ccw_anim": "2076", + "turn90cw_anim": "2076", + "two_handed": "true", + "walk_anim": "2076", + "weapon_interface": "17", + "weight": "2" + }, + { + "id": "4937", + "name": "Karil's x-bow 25", + "examine": "Karil the Tainted's repeating crossbow.", "archery_ticket_price": "0", + "attack_anims": "2075,2075,2075,2075", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "372", + "requirements": "{4,70}", + "run_anim": "2077", + "stand_anim": "2074", + "stand_turn_anim": "823", + "turn180_anim": "2076", + "turn90ccw_anim": "2076", + "turn90cw_anim": "2076", + "two_handed": "true", + "walk_anim": "2076", + "weapon_interface": "17", + "weight": "2" + }, + { "id": "4938", - "stand_turn_anim": "823" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "106300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Karil's x-bow 0", - "tradeable": "true", + "examine": "Karil the Tainted's repeating crossbow.", "archery_ticket_price": "0", - "id": "4939" + "attack_speed": "4", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "372", + "requirements": "{4,70}", + "run_anim": "2077", + "stand_anim": "2074", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "2076", + "turn90ccw_anim": "2076", + "turn90cw_anim": "2076", + "two_handed": "true", + "walk_anim": "2076", + "weapon_interface": "17", + "weight": "2" }, { - "requirements": "{1,70}-{4,70}", - "remove_sleeves": "true", - "examine": "Karil the Tainted's leather body armour.", - "grand_exchange_price": "983428", - "durability": null, - "name": "Karil's top 100", - "weight": "6", + "id": "4939", + "name": "Karil's x-bow 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "equip_audio": "", + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4940", + "name": "Karil's top 100", + "examine": "Karil the Tainted's leather body armour.", "absorb": "0,10,5", + "archery_ticket_price": "0", "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}-{4,70}", + "weight": "6" }, { - "requirements": "{1,70}-{4,70}", - "remove_sleeves": "true", - "examine": "Karil the Tainted's leather body armour.", - "grand_exchange_price": "983428", - "durability": null, - "name": "Karil's top 75", - "weight": "6", - "archery_ticket_price": "0", "id": "4941", + "name": "Karil's top 75", + "examine": "Karil the Tainted's leather body armour.", "absorb": "0,10,5", + "archery_ticket_price": "0", "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}-{4,70}", + "weight": "6" }, { - "requirements": "{1,70}-{4,70}", - "remove_sleeves": "true", - "examine": "Karil the Tainted's leather body armour.", - "grand_exchange_price": "983428", - "durability": null, - "name": "Karil's top 50", - "weight": "6", - "archery_ticket_price": "0", "id": "4942", + "name": "Karil's top 50", + "examine": "Karil the Tainted's leather body armour.", "absorb": "0,10,5", + "archery_ticket_price": "0", "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}-{4,70}", + "weight": "6" }, { - "requirements": "{1,70}-{4,70}", - "remove_sleeves": "true", - "examine": "Karil the Tainted's leather body armour.", - "grand_exchange_price": "983428", - "durability": null, - "name": "Karil's top 25", - "weight": "6", - "archery_ticket_price": "0", "id": "4943", - "absorb": "0,10,5", - "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "1", + "name": "Karil's top 25", "examine": "Karil the Tainted's leather body armour.", - "durability": null, - "weight": "6", "absorb": "0,10,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "1500000", - "name": "Karil's top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4944" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "1500000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karil's top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4945" - }, - { "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's leather skirt.", - "grand_exchange_price": "85135", - "durability": null, - "name": "Karil's skirt 100", - "weight": "2", + "weight": "6" + }, + { + "id": "4944", + "name": "Karil's top 0", + "examine": "Karil the Tainted's leather body armour.", + "absorb": "0,10,5", "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "1", + "remove_sleeves": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "4945", + "name": "Karil's top 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { "id": "4946", + "name": "Karil's skirt 100", + "examine": "Karil the Tainted's leather skirt.", "absorb": "0,7,3", + "archery_ticket_price": "0", "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "7", + "requirements": "{1,70}-{4,70}", + "weight": "2" }, { - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's leather skirt.", - "grand_exchange_price": "85135", - "durability": null, - "name": "Karil's skirt 75", - "weight": "2", - "archery_ticket_price": "0", "id": "4947", + "name": "Karil's skirt 75", + "examine": "Karil the Tainted's leather skirt.", "absorb": "0,7,3", + "archery_ticket_price": "0", "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "7", + "requirements": "{1,70}-{4,70}", + "weight": "2" }, { - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's leather skirt.", - "grand_exchange_price": "85135", - "durability": null, - "name": "Karil's skirt 50", - "weight": "2", - "archery_ticket_price": "0", "id": "4948", + "name": "Karil's skirt 50", + "examine": "Karil the Tainted's leather skirt.", "absorb": "0,7,3", + "archery_ticket_price": "0", "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "7", + "requirements": "{1,70}-{4,70}", + "weight": "2" }, { - "requirements": "{1,70}-{4,70}", - "examine": "Karil the Tainted's leather skirt.", - "grand_exchange_price": "85135", - "durability": null, - "name": "Karil's skirt 25", - "weight": "2", - "archery_ticket_price": "0", "id": "4949", - "absorb": "0,7,3", - "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "1", + "name": "Karil's skirt 25", "examine": "Karil the Tainted's leather skirt.", - "grand_exchange_price": "153100", - "durability": null, - "name": "Karil's skirt 0", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "4950", "absorb": "0,7,3", - "equipment_slot": "7" + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "7", + "requirements": "{1,70}-{4,70}", + "weight": "2" }, { - "ge_buy_limit": "1", - "grand_exchange_price": "153100", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, + "id": "4950", "name": "Karil's skirt 0", - "tradeable": "true", + "examine": "Karil the Tainted's leather skirt.", + "absorb": "0,7,3", "archery_ticket_price": "0", - "id": "4951" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "7", + "ge_buy_limit": "1", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "2" }, { - "remove_head": "true", - "requirements": "{1,70}", - "examine": "Torag the Corrupted's helm.", - "durability": null, - "weight": "5", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "71798", - "name": "Torag's helm 100", + "id": "4951", + "name": "Karil's skirt 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { "id": "4952", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { + "name": "Torag's helm 100", + "examine": "Torag the Corrupted's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Torag the Corrupted's helm.", - "durability": null, - "weight": "5", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "71798", - "name": "Torag's helm 75", - "archery_ticket_price": "0", + "weight": "5" + }, + { "id": "4953", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { + "name": "Torag's helm 75", + "examine": "Torag the Corrupted's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Torag the Corrupted's helm.", - "durability": null, - "weight": "5", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "71798", - "name": "Torag's helm 50", - "archery_ticket_price": "0", + "weight": "5" + }, + { "id": "4954", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { + "name": "Torag's helm 50", + "examine": "Torag the Corrupted's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Torag the Corrupted's helm.", - "durability": null, - "weight": "5", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "71798", - "name": "Torag's helm 25", - "archery_ticket_price": "0", + "weight": "5" + }, + { "id": "4955", - "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Torag's helm 25", "examine": "Torag the Corrupted's helm.", - "durability": null, - "weight": "5", "absorb": "2,0,5", - "remove_beard": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "78200", - "name": "Torag's helm 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4956" + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}", + "weight": "5" }, { + "id": "4956", + "name": "Torag's helm 0", + "examine": "Torag the Corrupted's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "ge_buy_limit": "10", - "grand_exchange_price": "78200", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Torag's helm 0", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4957" + "weight": "5" }, { - "requirements": "{0,70}-{2,70}", - "examine": "Torag the Corrupted's twin hammers.", - "durability": null, - "weight": "3", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2068,2068,2068,2068", - "grand_exchange_price": "95800", - "attack_audios": "1332,0,0,0", - "name": "Torag's hammer 100", + "id": "4957", + "name": "Torag's helm 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4958", - "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" - }, - { - "requirements": "{0,70}-{2,70}", + "name": "Torag's hammer 100", "examine": "Torag the Corrupted's twin hammers.", - "durability": null, - "weight": "3", + "archery_ticket_price": "0", + "attack_anims": "2068,2068,2068,2068", + "attack_audios": "1332,0,0,0", "attack_speed": "5", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "requirements": "{0,70}-{2,70}", "two_handed": "true", "weapon_interface": "10", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2068,2068,2068,2068", - "grand_exchange_price": "95800", - "attack_audios": "1332,0,0,0", - "name": "Torag's hammer 75", - "archery_ticket_price": "0", + "weight": "3" + }, + { "id": "4959", - "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" - }, - { - "requirements": "{0,70}-{2,70}", + "name": "Torag's hammer 75", "examine": "Torag the Corrupted's twin hammers.", - "durability": null, - "weight": "3", + "archery_ticket_price": "0", + "attack_anims": "2068,2068,2068,2068", + "attack_audios": "1332,0,0,0", "attack_speed": "5", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "requirements": "{0,70}-{2,70}", "two_handed": "true", "weapon_interface": "10", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2068,2068,2068,2068", - "grand_exchange_price": "95800", - "attack_audios": "1332,0,0,0", - "name": "Torag's hammer 50", - "archery_ticket_price": "0", + "weight": "3" + }, + { "id": "4960", - "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" - }, - { - "requirements": "{0,70}-{2,70}", + "name": "Torag's hammer 50", "examine": "Torag the Corrupted's twin hammers.", - "durability": null, - "weight": "3", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "defence_anim": "424", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "2068,2068,2068,2068", - "grand_exchange_price": "95800", "attack_audios": "1332,0,0,0", - "name": "Torag's hammer 25", - "archery_ticket_price": "0", - "id": "4961", - "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" - }, - { - "requirements": "{0,70}-{2,70}", - "ge_buy_limit": "10", - "examine": "Torag the Corrupted's twin hammers.", - "durability": null, - "weight": "3", "attack_speed": "5", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "requirements": "{0,70}-{2,70}", "two_handed": "true", "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "95600", + "weight": "3" + }, + { + "id": "4961", + "name": "Torag's hammer 25", + "examine": "Torag the Corrupted's twin hammers.", + "archery_ticket_price": "0", + "attack_anims": "2068,2068,2068,2068", "attack_audios": "1332,0,0,0", - "name": "Torag's hammer 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4962" + "attack_speed": "5", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "requirements": "{0,70}-{2,70}", + "two_handed": "true", + "weapon_interface": "10", + "weight": "3" }, { + "id": "4962", + "name": "Torag's hammer 0", + "examine": "Torag the Corrupted's twin hammers.", + "archery_ticket_price": "0", + "attack_audios": "1332,0,0,0", + "attack_speed": "5", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", "ge_buy_limit": "10", - "grand_exchange_price": "95600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Torag's hammer 0", + "requirements": "{0,70}-{2,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4963" + "two_handed": "true", + "weapon_interface": "10", + "weight": "3" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Torag the Corrupted's platebody armour.", - "grand_exchange_price": "297733", - "durability": null, - "name": "Torag's body 100", - "weight": "9", + "id": "4963", + "name": "Torag's hammer 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4964", + "name": "Torag's body 100", + "examine": "Torag the Corrupted's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Torag the Corrupted's platebody armour.", - "grand_exchange_price": "297733", - "durability": null, - "name": "Torag's body 75", - "weight": "9", - "archery_ticket_price": "0", "id": "4965", + "name": "Torag's body 75", + "examine": "Torag the Corrupted's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Torag the Corrupted's platebody armour.", - "grand_exchange_price": "297733", - "durability": null, - "name": "Torag's body 50", - "weight": "9", - "archery_ticket_price": "0", "id": "4966", + "name": "Torag's body 50", + "examine": "Torag the Corrupted's platebody armour.", "absorb": "5,0,10", + "archery_ticket_price": "0", "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Torag the Corrupted's platebody armour.", - "grand_exchange_price": "297733", - "durability": null, - "name": "Torag's body 25", - "weight": "9", - "archery_ticket_price": "0", "id": "4967", - "absorb": "5,0,10", - "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Torag's body 25", "examine": "Torag the Corrupted's platebody armour.", - "durability": null, - "weight": "9", "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "271600", - "name": "Torag's body 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4968" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "271600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Torag's body 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4969" - }, - { "requirements": "{1,70}", - "examine": "Torag the Corrupted's plate leg armour.", - "grand_exchange_price": "384813", - "durability": null, - "name": "Torag's legs 100", - "weight": "9", + "weight": "9" + }, + { + "id": "4968", + "name": "Torag's body 0", + "examine": "Torag the Corrupted's platebody armour.", + "absorb": "5,0,10", "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "4969", + "name": "Torag's body 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4970", + "name": "Torag's legs 100", + "examine": "Torag the Corrupted's plate leg armour.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "examine": "Torag the Corrupted's plate leg armour.", - "grand_exchange_price": "384813", - "durability": null, - "name": "Torag's legs 75", - "weight": "9", - "archery_ticket_price": "0", "id": "4971", + "name": "Torag's legs 75", + "examine": "Torag the Corrupted's plate leg armour.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "examine": "Torag the Corrupted's plate leg armour.", - "grand_exchange_price": "384813", - "durability": null, - "name": "Torag's legs 50", - "weight": "9", - "archery_ticket_price": "0", "id": "4972", + "name": "Torag's legs 50", + "examine": "Torag the Corrupted's plate leg armour.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "9" }, { - "requirements": "{1,70}", - "examine": "Torag the Corrupted's plate leg armour.", - "grand_exchange_price": "384813", - "durability": null, - "name": "Torag's legs 25", - "weight": "9", - "archery_ticket_price": "0", "id": "4973", - "absorb": "3,0,7", - "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Torag's legs 25", "examine": "Torag the Corrupted's plate leg armour.", - "grand_exchange_price": "371300", - "durability": null, - "name": "Torag's legs 0", - "tradeable": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "4974", "absorb": "3,0,7", - "equipment_slot": "7" + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "9" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "371300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, + "id": "4974", "name": "Torag's legs 0", - "tradeable": "true", + "examine": "Torag the Corrupted's plate leg armour.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "4975" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "9" }, { - "remove_head": "true", - "requirements": "{1,70}", - "examine": "Verac the Defiled's helm.", - "durability": null, - "weight": "1", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "459537", - "name": "Verac's helm 100", + "id": "4975", + "name": "Torag's legs 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4976", - "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" - }, - { + "name": "Verac's helm 100", + "examine": "Verac the Defiled's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Verac the Defiled's helm.", - "durability": null, - "weight": "1", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "459537", - "name": "Verac's helm 75", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "4977", - "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" - }, - { + "name": "Verac's helm 75", + "examine": "Verac the Defiled's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Verac the Defiled's helm.", - "durability": null, - "weight": "1", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "459537", - "name": "Verac's helm 50", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "4978", - "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" - }, - { + "name": "Verac's helm 50", + "examine": "Verac the Defiled's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "examine": "Verac the Defiled's helm.", - "durability": null, - "weight": "1", - "absorb": "2,0,5", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "459537", - "name": "Verac's helm 25", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "4979", - "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" - }, - { + "name": "Verac's helm 25", + "examine": "Verac the Defiled's helm.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,70}", - "ge_buy_limit": "10", + "weight": "1" + }, + { + "id": "4980", + "name": "Verac's helm 0", "examine": "Verac the Defiled's helm.", - "durability": null, - "weight": "1", "absorb": "2,0,5", - "remove_beard": "true", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "648900", - "name": "Verac's helm 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4980" - }, - { "ge_buy_limit": "10", - "grand_exchange_price": "648900", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Verac's helm 0", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,70}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "4981" + "weight": "1" }, { - "requirements": "{0,70}", - "turn90cw_anim": "2060", - "examine": "Verac the Defiled's flail.", - "walk_anim": "1830", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2060", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "8", - "turn180_anim": "2060", - "defence_anim": "424", - "render_anim": "1426", - "equipment_slot": "3", - "attack_anims": "2062,2062,2062,2062", - "grand_exchange_price": "95474", - "stand_anim": "1832", - "attack_audios": "1323,0,0,0", - "name": "Verac's flail 100", - "run_anim": "1831", + "id": "4981", + "name": "Verac's helm 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4982", + "name": "Verac's flail 100", + "examine": "Verac the Defiled's flail.", + "archery_ticket_price": "0", + "attack_anims": "2062,2062,2062,2062", + "attack_audios": "1323,0,0,0", + "attack_speed": "5", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "render_anim": "1426", + "requirements": "{0,70}", + "run_anim": "1831", + "stand_anim": "1832", "stand_turn_anim": "823", - "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0" + "turn180_anim": "2060", + "turn90ccw_anim": "2060", + "turn90cw_anim": "2060", + "two_handed": "true", + "walk_anim": "1830", + "weapon_interface": "8", + "weight": "2" }, { - "requirements": "{0,70}", - "turn90cw_anim": "2060", - "examine": "Verac the Defiled's flail.", - "walk_anim": "1830", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2060", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "8", - "turn180_anim": "2060", - "defence_anim": "424", - "render_anim": "1426", - "equipment_slot": "3", - "attack_anims": "2062,2062,2062,2062", - "grand_exchange_price": "95474", - "stand_anim": "1832", - "attack_audios": "1323,0,0,0", - "name": "Verac's flail 75", - "run_anim": "1831", - "archery_ticket_price": "0", "id": "4983", + "name": "Verac's flail 75", + "examine": "Verac the Defiled's flail.", + "archery_ticket_price": "0", + "attack_anims": "2062,2062,2062,2062", + "attack_audios": "1323,0,0,0", + "attack_speed": "5", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "render_anim": "1426", + "requirements": "{0,70}", + "run_anim": "1831", + "stand_anim": "1832", "stand_turn_anim": "823", - "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0" + "turn180_anim": "2060", + "turn90ccw_anim": "2060", + "turn90cw_anim": "2060", + "two_handed": "true", + "walk_anim": "1830", + "weapon_interface": "8", + "weight": "2" }, { - "requirements": "{0,70}", - "turn90cw_anim": "2060", - "examine": "Verac the Defiled's flail.", - "walk_anim": "1830", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2060", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "8", - "turn180_anim": "2060", - "defence_anim": "424", - "render_anim": "1426", - "equipment_slot": "3", - "attack_anims": "2062,2062,2062,2062", - "grand_exchange_price": "95474", - "stand_anim": "1832", - "attack_audios": "1323,0,0,0", - "name": "Verac's flail 50", - "run_anim": "1831", - "archery_ticket_price": "0", "id": "4984", - "stand_turn_anim": "823", - "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0" - }, - { - "requirements": "{0,70}", - "turn90cw_anim": "2060", + "name": "Verac's flail 50", "examine": "Verac the Defiled's flail.", - "walk_anim": "1830", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2060", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "8", - "turn180_anim": "2060", - "defence_anim": "424", - "render_anim": "1426", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "2062,2062,2062,2062", - "grand_exchange_price": "95474", - "stand_anim": "1832", "attack_audios": "1323,0,0,0", - "name": "Verac's flail 25", - "run_anim": "1831", - "archery_ticket_price": "0", - "id": "4985", - "stand_turn_anim": "823", - "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0" - }, - { - "requirements": "{0,70}", - "ge_buy_limit": "10", - "turn90cw_anim": "2060", - "examine": "Verac the Defiled's flail.", - "walk_anim": "1830", - "durability": null, - "weight": "2", - "turn90ccw_anim": "2060", "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "8", - "turn180_anim": "2060", - "render_anim": "1426", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2246", "equipment_slot": "3", - "grand_exchange_price": "95500", - "stand_anim": "1832", - "attack_audios": "1323,0,0,0", - "tradeable": "true", - "name": "Verac's flail 0", + "render_anim": "1426", + "requirements": "{0,70}", "run_anim": "1831", + "stand_anim": "1832", + "stand_turn_anim": "823", + "turn180_anim": "2060", + "turn90ccw_anim": "2060", + "turn90cw_anim": "2060", + "two_handed": "true", + "walk_anim": "1830", + "weapon_interface": "8", + "weight": "2" + }, + { + "id": "4985", + "name": "Verac's flail 25", + "examine": "Verac the Defiled's flail.", "archery_ticket_price": "0", + "attack_anims": "2062,2062,2062,2062", + "attack_audios": "1323,0,0,0", + "attack_speed": "5", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "render_anim": "1426", + "requirements": "{0,70}", + "run_anim": "1831", + "stand_anim": "1832", + "stand_turn_anim": "823", + "turn180_anim": "2060", + "turn90ccw_anim": "2060", + "turn90cw_anim": "2060", + "two_handed": "true", + "walk_anim": "1830", + "weapon_interface": "8", + "weight": "2" + }, + { "id": "4986", - "stand_turn_anim": "823" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "95500", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Verac's flail 0", - "tradeable": "true", + "examine": "Verac the Defiled's flail.", "archery_ticket_price": "0", - "id": "4987" - }, - { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Verac the Defiled's brassard.", - "grand_exchange_price": "177963", + "attack_audios": "1323,0,0,0", + "attack_speed": "5", "durability": null, - "name": "Verac's top 100", - "weight": "5", - "archery_ticket_price": "0", - "id": "4988", - "absorb": "5,0,10", - "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Verac the Defiled's brassard.", - "grand_exchange_price": "177963", - "durability": null, - "name": "Verac's top 75", - "weight": "5", - "archery_ticket_price": "0", - "id": "4989", - "absorb": "5,0,10", - "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Verac the Defiled's brassard.", - "grand_exchange_price": "177963", - "durability": null, - "name": "Verac's top 50", - "weight": "5", - "archery_ticket_price": "0", - "id": "4990", - "absorb": "5,0,10", - "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", - "remove_sleeves": "true", - "examine": "Verac the Defiled's brassard.", - "grand_exchange_price": "177963", - "durability": null, - "name": "Verac's top 25", - "weight": "5", - "archery_ticket_price": "0", - "id": "4991", - "absorb": "5,0,10", - "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,70}", + "equip_audio": "2246", + "equipment_slot": "3", "ge_buy_limit": "10", - "examine": "Verac the Defiled's brassard.", + "render_anim": "1426", + "requirements": "{0,70}", + "run_anim": "1831", + "stand_anim": "1832", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "2060", + "turn90ccw_anim": "2060", + "turn90cw_anim": "2060", + "two_handed": "true", + "walk_anim": "1830", + "weapon_interface": "8", + "weight": "2" + }, + { + "id": "4987", + "name": "Verac's flail 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, - "weight": "5", + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "4988", + "name": "Verac's top 100", + "examine": "Verac the Defiled's brassard.", "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "174000", - "name": "Verac's top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4992" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "174000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Verac's top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "4993" - }, - { "requirements": "{1,70}", - "examine": "Verac the Defiled's plate skirt.", - "grand_exchange_price": "297540", - "durability": null, - "name": "Verac's skirt 100", - "weight": "5", + "weight": "5" + }, + { + "id": "4989", + "name": "Verac's top 75", + "examine": "Verac the Defiled's brassard.", + "absorb": "5,0,10", "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "5" + }, + { + "id": "4990", + "name": "Verac's top 50", + "examine": "Verac the Defiled's brassard.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "5" + }, + { + "id": "4991", + "name": "Verac's top 25", + "examine": "Verac the Defiled's brassard.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,70}", + "weight": "5" + }, + { + "id": "4992", + "name": "Verac's top 0", + "examine": "Verac the Defiled's brassard.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "4993", + "name": "Verac's top 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "4994", + "name": "Verac's skirt 100", + "examine": "Verac the Defiled's plate skirt.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "5" }, { - "requirements": "{1,70}", - "examine": "Verac the Defiled's plate skirt.", - "grand_exchange_price": "297540", - "durability": null, - "name": "Verac's skirt 75", - "weight": "5", - "archery_ticket_price": "0", "id": "4995", + "name": "Verac's skirt 75", + "examine": "Verac the Defiled's plate skirt.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "5" }, { - "requirements": "{1,70}", - "examine": "Verac the Defiled's plate skirt.", - "grand_exchange_price": "297540", - "durability": null, - "name": "Verac's skirt 50", - "weight": "5", - "archery_ticket_price": "0", "id": "4996", + "name": "Verac's skirt 50", + "examine": "Verac the Defiled's plate skirt.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", - "equipment_slot": "7" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "5" }, { - "requirements": "{1,70}", - "examine": "Verac the Defiled's plate skirt.", - "grand_exchange_price": "297540", - "durability": null, - "name": "Verac's skirt 25", - "weight": "5", - "archery_ticket_price": "0", "id": "4997", - "absorb": "3,0,7", - "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", - "equipment_slot": "7" - }, - { - "requirements": "{1,70}", - "ge_buy_limit": "10", + "name": "Verac's skirt 25", "examine": "Verac the Defiled's plate skirt.", - "grand_exchange_price": "321600", - "durability": null, - "name": "Verac's skirt 0", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "4998", "absorb": "3,0,7", - "equipment_slot": "7" + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,70}", + "weight": "5" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "321600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, + "id": "4998", "name": "Verac's skirt 0", - "tradeable": "true", + "examine": "Verac the Defiled's plate skirt.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "4999" + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,70}", + "tradeable": "true", + "weight": "5" }, { - "ge_buy_limit": "1000", + "id": "4999", + "name": "Verac's skirt 0", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "5001", + "name": "Raw cave eel", "examine": "It's incredibly slimy.", - "grand_exchange_price": "373", - "durability": null, - "name": "Raw cave eel", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "5001" - }, - { + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "5003", + "name": "Cave eel", "examine": "It's a bit slimy.", - "grand_exchange_price": "164", - "durability": null, - "name": "Cave eel", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "5003" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "examine": "That's disgusting!", - "durability": null, + "id": "5004", "name": "Frog spawn", + "examine": "That's disgusting!", "archery_ticket_price": "0", - "id": "5004" + "durability": null }, { - "durability": null, + "id": "5005", "name": "Raw cave eel", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5005" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "5006", "name": "Burnt cave eel", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5006" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "5007", "name": "Cave eel", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5007" + "durability": null, + "tradeable": "true" }, { - "examine": "A book about the ancient goblin tribes.", - "durability": null, + "id": "5009", "name": "Goblin symbol book", - "weight": "1", + "examine": "A book about the ancient goblin tribes.", "archery_ticket_price": "0", - "id": "5009" + "durability": null, + "weight": "1" }, { - "examine": "You found the Lumbridge silverware in the HAM cave.", - "durability": null, + "id": "5011", "name": "Silverware", + "examine": "You found the Lumbridge silverware in the HAM cave.", "archery_ticket_price": "0", - "id": "5011" + "durability": null }, { - "examine": "A peace treaty between Lumbridge and the Cave Goblins.", - "durability": null, + "id": "5012", "name": "Peace treaty", + "examine": "A peace treaty between Lumbridge and the Cave Goblins.", "archery_ticket_price": "0", - "id": "5012" + "durability": null }, { - "shop_price": "900", - "examine": "A helmet with a lamp on it.", - "grand_exchange_price": "380", - "durability": null, - "name": "Mining helmet", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "5013", + "name": "Mining helmet", + "examine": "A helmet with a lamp on it.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "shop_price": "900", + "tradeable": "true", + "weight": "1" }, { + "id": "5014", + "name": "Mining helmet", + "examine": "A helmet with an unlit lamp on it.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "requirements": "{11,65}", "shop_price": "900", - "ge_buy_limit": "100", - "examine": "A helmet with an unlit lamp on it.", - "durability": null, - "weight": "1", - "equipment_slot": "0", - "grand_exchange_price": "342", - "name": "Mining helmet", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5014", - "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "342", - "durability": null, + "id": "5015", "name": "Mining helmet", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5015" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "shop_price": "600", - "turn90cw_anim": "1207", - "examine": "Basic but brutal!", - "walk_anim": "1205", - "durability": null, - "weight": "1.3", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "two_handed": "false", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "219", - "stand_anim": "813", - "tradeable": "true", - "name": "Bone spear", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "5016", - "stand_turn_anim": "1209", - "bonuses": "11,11,11,0,0,1,1,0,0,0,0,13,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "219", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Bone spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5017" - }, - { - "shop_price": "600", - "ge_buy_limit": "100", "examine": "Basic but brutal!", - "durability": null, - "weight": "0.9", + "archery_ticket_price": "0", "attack_speed": "6", - "weapon_interface": "10", + "bonuses": "11,11,11,0,0,1,1,0,0,0,0,13,0,0,0", + "durability": null, + "equip_audio": "2247", "equipment_slot": "3", - "grand_exchange_price": "384", - "name": "Bone club", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "600", + "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5018", - "bonuses": "-4,-4,16,-4,0,0,0,0,0,0,0,15,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "384", + "id": "5017", + "name": "Bone spear", "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5018", "name": "Bone club", - "tradeable": "true", + "examine": "Basic but brutal!", "archery_ticket_price": "0", - "id": "5019" - }, - { - "shop_price": "150", - "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "attack_anims": "401,401,400,401", + "attack_speed": "6", + "bonuses": "-4,-4,16,-4,0,0,0,0,0,0,0,15,0,0,0", + "defence_anim": "403", "durability": null, - "name": "Minecart ticket", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5020" - }, - { - "shop_price": "150", - "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", - "durability": null, - "name": "Minecart ticket", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5021" - }, - { - "shop_price": "150", - "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", - "durability": null, - "name": "Minecart ticket", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5022" - }, - { - "shop_price": "150", - "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", - "durability": null, - "name": "Minecart ticket", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5023" - }, - { - "remove_sleeves": "true", - "shop_price": "812", + "equipment_slot": "3", "ge_buy_limit": "100", - "examine": "Far too small to wear.", - "grand_exchange_price": "710", - "durability": null, - "name": "Woven top", + "shop_price": "600", "tradeable": "true", - "weight": "0.1", + "weapon_interface": "10", + "weight": "0.9" + }, + { + "id": "5019", + "name": "Bone club", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5020", + "name": "Minecart ticket", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "weight": "0.1" + }, + { + "id": "5021", + "name": "Minecart ticket", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "weight": "0.1" + }, + { + "id": "5022", + "name": "Minecart ticket", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "weight": "0.1" + }, + { + "id": "5023", + "name": "Minecart ticket", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "150", + "weight": "0.1" + }, + { "id": "5024", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "710", - "durability": null, "name": "Woven top", - "tradeable": "true", + "examine": "Far too small to wear.", "archery_ticket_price": "0", - "id": "5025" - }, - { + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", "remove_sleeves": "true", "shop_price": "812", - "ge_buy_limit": "100", - "examine": "Yellow top, too small for me.", - "grand_exchange_price": "908", - "durability": null, - "name": "Woven top", "tradeable": "true", - "weight": "0.1", + "weight": "0.1" + }, + { + "id": "5025", + "name": "Woven top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5026", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "908", - "durability": null, "name": "Woven top", - "tradeable": "true", + "examine": "Yellow top, too small for me.", "archery_ticket_price": "0", - "id": "5027" - }, - { + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", "remove_sleeves": "true", "shop_price": "812", - "ge_buy_limit": "100", - "examine": "Blue top, very tiny.", - "grand_exchange_price": "1357", - "durability": null, - "name": "Woven top", "tradeable": "true", - "weight": "0.1", + "weight": "0.1" + }, + { + "id": "5027", + "name": "Woven top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5028", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1357", - "durability": null, "name": "Woven top", - "tradeable": "true", + "examine": "Blue top, very tiny.", "archery_ticket_price": "0", - "id": "5029" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "812", + "tradeable": "true", + "weight": "0.1" }, { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "grand_exchange_price": "867", - "examine": "Tiny!", - "durability": null, - "name": "Shirt", - "tradeable": "true", + "id": "5029", + "name": "Woven top", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5030", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "867", - "durability": null, "name": "Shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5031" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "grand_exchange_price": "1023", "examine": "Tiny!", - "durability": null, - "name": "Shirt", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5031", + "name": "Shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5032", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1023", - "durability": null, "name": "Shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5033" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "grand_exchange_price": "1282", "examine": "Tiny!", - "durability": null, - "name": "Shirt", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5033", + "name": "Shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5034", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1282", - "durability": null, "name": "Shirt", - "tradeable": "true", + "examine": "Tiny!", "archery_ticket_price": "0", - "id": "5035" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "746", - "examine": "A pair of long dwarven trousers... long for dwarves, of course.", - "durability": null, - "name": "Trousers", - "tradeable": "true", + "id": "5035", + "name": "Shirt", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5036", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "746", - "durability": null, "name": "Trousers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5037" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "378", "examine": "A pair of long dwarven trousers... long for dwarves, of course.", - "durability": null, - "name": "Trousers", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5037", + "name": "Trousers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5038", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "378", - "durability": null, "name": "Trousers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5039" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "442", "examine": "A pair of long dwarven trousers... long for dwarves, of course.", - "durability": null, - "name": "Trousers", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5039", + "name": "Trousers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5040", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "442", - "durability": null, "name": "Trousers", - "tradeable": "true", + "examine": "A pair of long dwarven trousers... long for dwarves, of course.", "archery_ticket_price": "0", - "id": "5041" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1191", - "examine": "These look great, on dwarves!", - "durability": null, - "name": "Shorts", - "tradeable": "true", + "id": "5041", + "name": "Trousers", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5042", - "equipment_slot": "7" + "name": "Shorts", + "examine": "These look great, on dwarves!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1191", - "durability": null, + "id": "5043", "name": "Shorts", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5043" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1229", - "examine": "Yellow shorts. Far too small for you.", - "durability": null, - "name": "Shorts", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", "id": "5044", - "equipment_slot": "7" + "name": "Shorts", + "examine": "Yellow shorts. Far too small for you.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1229", - "durability": null, + "id": "5045", "name": "Shorts", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5045" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2582", - "examine": "Blue shorts, these would look great on dwarves!", - "durability": null, - "name": "Shorts", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", "id": "5046", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2582", - "durability": null, "name": "Shorts", - "tradeable": "true", + "examine": "Blue shorts, these would look great on dwarves!", "archery_ticket_price": "0", - "id": "5047" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "681", - "examine": "A brown skirt. Size small!", - "durability": null, - "name": "Skirt", - "tradeable": "true", + "id": "5047", + "name": "Shorts", "archery_ticket_price": "0", - "weight": "0.1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5048", - "equipment_slot": "7" + "name": "Skirt", + "examine": "A brown skirt. Size small!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "681", - "durability": null, + "id": "5049", "name": "Skirt", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5049" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1151", - "examine": "A blue skirt.", - "durability": null, - "name": "Skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", "id": "5050", - "equipment_slot": "7" + "name": "Skirt", + "examine": "A blue skirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1151", - "durability": null, + "id": "5051", "name": "Skirt", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5051" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "803", - "examine": "Lilac skirt.", - "durability": null, - "name": "Skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", "id": "5052", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "803", - "durability": null, "name": "Skirt", - "tradeable": "true", + "examine": "Lilac skirt.", "archery_ticket_price": "0", - "id": "5053" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { + "id": "5053", + "name": "Skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5054", + "name": "Dwarf", "examine": "A short angry guy.", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "5055", "name": "Dwarf", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5054" + "durability": null, + "tradeable": "true" }, { - "durability": null, - "name": "Dwarf", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5055" - }, - { - "examine": "This looks very rusty and worn;", - "durability": null, + "id": "5056", "name": "Dwarven battleaxe", + "examine": "This looks very rusty and worn;", "archery_ticket_price": "0", - "id": "5056" + "durability": null }, { - "examine": "This looks very rusty and worn;", - "durability": null, + "id": "5057", "name": "Dwarven battleaxe", + "examine": "This looks very rusty and worn;", "archery_ticket_price": "0", - "id": "5057" + "durability": null }, { - "examine": "This looks very rusty and worn;", - "durability": null, + "id": "5058", "name": "Dwarven battleaxe", + "examine": "This looks very rusty and worn;", "archery_ticket_price": "0", - "id": "5058" + "durability": null }, { - "examine": "This looks very rusty and worn;", - "durability": null, + "id": "5059", "name": "Dwarven battleaxe", + "examine": "This looks very rusty and worn;", "archery_ticket_price": "0", - "id": "5059" + "durability": null }, { - "examine": "This looks very rusty and worn;", - "durability": null, - "name": "Dwarven battleaxe", - "archery_ticket_price": "0", "id": "5060", - "equipment_slot": "3" - }, - { - "examine": "This looks very rusty and worn;", - "durability": null, "name": "Dwarven battleaxe", + "examine": "This looks very rusty and worn;", "archery_ticket_price": "0", - "id": "5061", + "durability": null, + "equip_audio": "2232", "equipment_slot": "3" }, { - "examine": "One of a pair I assume.", + "id": "5061", + "name": "Dwarven battleaxe", + "examine": "This looks very rusty and worn;", + "archery_ticket_price": "0", "durability": null, + "equip_audio": "2232", + "equipment_slot": "3" + }, + { + "id": "5062", "name": "Left boot", - "weight": "0.5", + "examine": "One of a pair I assume.", "archery_ticket_price": "0", - "id": "5062" + "durability": null, + "weight": "0.5" }, { - "examine": "A good looking boot, for the right foot. Literally.", - "durability": null, + "id": "5063", "name": "Right boot", - "weight": "0.5", + "examine": "A good looking boot, for the right foot. Literally.", "archery_ticket_price": "0", - "id": "5063" + "durability": null, + "weight": "0.5" }, { - "examine": "A lovely pair of boots.", - "durability": null, + "id": "5064", "name": "Exquisite boots", - "tradeable": "false", + "examine": "A lovely pair of boots.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5064" + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "An old library book. It bears the title 'Scholars to Dwarven Costumes'.", - "durability": null, + "id": "5065", "name": "Book on costumes", + "examine": "An old library book. It bears the title 'Scholars to Dwarven Costumes'.", "archery_ticket_price": "0", - "id": "5065" + "durability": null }, { - "examine": "These notes are from a meeting of the Keldagrim Consortium.", - "durability": null, + "id": "5066", "name": "Meeting notes", + "examine": "These notes are from a meeting of the Keldagrim Consortium.", "archery_ticket_price": "0", - "id": "5066" + "durability": null }, { - "examine": "Clothes for the sculptor's model.", - "durability": null, + "id": "5067", "name": "Exquisite clothes", + "examine": "Clothes for the sculptor's model.", "archery_ticket_price": "0", - "id": "5067" + "durability": null }, { - "examine": "A master at farming.", - "durability": null, + "id": "5068", "name": "Master farmer", + "examine": "A master at farming.", "archery_ticket_price": "0", - "id": "5068" + "durability": null }, { - "examine": "Full: ", - "durability": null, + "id": "5070", "name": "Bird's nest", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "5070" - }, - { "examine": "Full: ", - "durability": null, - "name": "Bird's nest", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5071" + "durability": null, + "tradeable": "false" }, { + "id": "5071", + "name": "Bird's nest", "examine": "Full: ", - "durability": null, - "name": "Bird's nest", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5072" + "durability": null, + "tradeable": "false" }, { + "id": "5072", + "name": "Bird's nest", "examine": "Full: ", - "durability": null, - "name": "Bird's nest", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5073" + "durability": null, + "tradeable": "false" }, { + "id": "5073", + "name": "Bird's nest", "examine": "Full: ", - "durability": null, - "name": "Bird's nest", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5074" + "durability": null, + "tradeable": "false" }, { + "id": "5074", + "name": "Bird's nest", "examine": "Full: ", - "durability": null, - "name": "Bird's nest", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5075" + "durability": null, + "tradeable": "false" }, { + "id": "5075", + "name": "Bird's nest", + "examine": "Full: ", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "5076", + "name": "Bird's egg", "examine": "A red bird's egg.", - "durability": null, - "name": "Bird's egg", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5076" + "durability": null, + "tradeable": "false" }, { + "id": "5077", + "name": "Bird's egg", "examine": "A blue bird's egg.", - "durability": null, - "name": "Bird's egg", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5077" + "durability": null, + "tradeable": "false" }, { + "id": "5078", + "name": "Bird's egg", "examine": "A green bird's egg.", - "durability": null, - "name": "Bird's egg", - "tradeable": "false", "archery_ticket_price": "0", - "id": "5078" + "durability": null, + "tradeable": "false" }, { + "id": "5096", + "name": "Marigold seed", + "examine": "A marigold seed - plant in flower patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{2,19}", "shop_price": "84", - "ge_buy_limit": "100", - "examine": "A marigold seed - plant in flower patch.", - "grand_exchange_price": "8", - "durability": null, - "name": "Marigold seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5096" + "tradeable": "true" }, { + "id": "5097", + "name": "Rosemary seed", + "examine": "A rosemary seed - plant in flower patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{11,19}", "shop_price": "98", - "ge_buy_limit": "100", - "examine": "A rosemary seed - plant in flower patch.", - "grand_exchange_price": "3", - "durability": null, - "name": "Rosemary seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5097" + "tradeable": "true" }, { + "id": "5098", + "name": "Nasturtium seed", + "examine": "A nasturtium seed - plant in flower patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{24,19}", "shop_price": "14", - "ge_buy_limit": "100", - "examine": "A nasturtium seed - plant in flower patch.", - "grand_exchange_price": "1", - "durability": null, - "name": "Nasturtium seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5098" + "tradeable": "true" }, { - "requirements": "{19,25}", - "ge_buy_limit": "100", - "examine": "A woad seed - plant in flower patch.", - "grand_exchange_price": "1", - "durability": null, + "id": "5099", "name": "Woad seed", - "tradeable": "true", + "examine": "A woad seed - plant in flower patch.", "archery_ticket_price": "0", - "id": "5099" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,25}", + "tradeable": "true" }, { + "id": "5100", + "name": "Limpwurt seed", + "examine": "A limpwurt seed - plant in flower patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,26}", "shop_price": "70", - "ge_buy_limit": "100", - "examine": "A limpwurt seed - plant in flower patch.", - "grand_exchange_price": "273", - "durability": null, - "name": "Limpwurt seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5100" + "tradeable": "true" }, { - "requirements": "{10,19}", - "ge_buy_limit": "100", - "examine": "A redberry seed - Plant in a bush patch.", - "grand_exchange_price": "1", - "durability": null, + "id": "5101", "name": "Redberry seed", - "tradeable": "true", + "examine": "A redberry seed - Plant in a bush patch.", "archery_ticket_price": "0", - "id": "5101" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{10,19}", + "tradeable": "true" }, { - "requirements": "{22,19}", - "ge_buy_limit": "100", - "examine": "A cadavaberry seed - Plant in a bush patch.", - "grand_exchange_price": "1", - "durability": null, + "id": "5102", "name": "Cadavaberry seed", - "tradeable": "true", + "examine": "A cadavaberry seed - Plant in a bush patch.", "archery_ticket_price": "0", - "id": "5102" - }, - { - "requirements": "{19,36}", - "ge_buy_limit": "100", - "examine": "A dwellberry seed - Plant in a bush patch.", - "grand_exchange_price": "1", "durability": null, - "name": "Dwellberry seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5103" + "ge_buy_limit": "100", + "requirements": "{22,19}", + "tradeable": "true" }, { + "id": "5103", + "name": "Dwellberry seed", + "examine": "A dwellberry seed - Plant in a bush patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,36}", + "tradeable": "true" + }, + { + "id": "5104", + "name": "Jangerberry seed", + "examine": "A jangerberry bush seed - plant in a bush patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,48}", "shop_price": "22", - "ge_buy_limit": "100", - "examine": "A jangerberry bush seed - plant in a bush patch.", - "grand_exchange_price": "2", - "durability": null, - "name": "Jangerberry seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5104" + "tradeable": "true" }, { - "requirements": "{19,59}", - "ge_buy_limit": "100", - "examine": "A whiteberry bush seed - plant in a bush patch.", - "grand_exchange_price": "8", - "durability": null, + "id": "5105", "name": "Whiteberry seed", - "tradeable": "true", + "examine": "A whiteberry bush seed - plant in a bush patch.", "archery_ticket_price": "0", - "id": "5105" - }, - { - "requirements": "{19,70}", - "ge_buy_limit": "100", - "examine": "A poison ivy bush seed - plant in a bush patch.", - "grand_exchange_price": "38", "durability": null, - "name": "Poison ivy seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5106" + "ge_buy_limit": "100", + "requirements": "{19,59}", + "tradeable": "true" }, { + "id": "5106", + "name": "Poison ivy seed", + "examine": "A poison ivy bush seed - plant in a bush patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,70}", + "tradeable": "true" + }, + { + "id": "5280", + "name": "Cactus seed", + "examine": "A Cactus seed - plant in a cactus patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,55}", "shop_price": "29", - "ge_buy_limit": "100", - "examine": "A Cactus seed - plant in a cactus patch.", - "grand_exchange_price": "10", - "durability": null, - "name": "Cactus seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5280" + "tradeable": "true" }, { - "requirements": "{19,63}", - "ge_buy_limit": "100", - "examine": "Also known as Deadly Nightshade - plant in a belladonna patch.", - "grand_exchange_price": "24", - "durability": null, + "id": "5281", "name": "Belladonna seed", - "tradeable": "true", + "examine": "Also known as Deadly Nightshade - plant in a belladonna patch.", "archery_ticket_price": "0", - "id": "5281" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,63}", + "tradeable": "true" }, { - "requirements": "{19,53}", - "ge_buy_limit": "100", - "grand_exchange_price": "2", - "durability": null, + "id": "5282", "name": "Mushroom spore", "archery_ticket_price": "0", - "id": "5282" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,53}" }, { - "requirements": "{19,27}", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "4", - "durability": null, + "id": "5283", "name": "Apple tree seed", - "tradeable": "true", + "examine": "Plant this in a plantpot of soil to grow a sapling.", "archery_ticket_price": "0", - "id": "5283" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,27}", + "tradeable": "true" }, { - "requirements": "{19,33}", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "5", - "durability": null, + "id": "5284", "name": "Banana tree seed", - "tradeable": "true", + "examine": "Plant this in a plantpot of soil to grow a sapling.", "archery_ticket_price": "0", - "id": "5284" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,33}", + "tradeable": "true" }, { - "requirements": "{19,39}", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "30", - "durability": null, + "id": "5285", "name": "Orange tree seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5285" - }, - { - "requirements": "{19,42}", - "ge_buy_limit": "100", - "examine": "Plant this in a plant pot of soil to grow a sapling.", - "grand_exchange_price": "265", - "durability": null, - "name": "Curry tree seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5286" - }, - { - "requirements": "{19,51}", - "ge_buy_limit": "100", "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "13700", - "durability": null, - "name": "Pineapple seed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5287" - }, - { - "requirements": "{19,57}", + "durability": null, "ge_buy_limit": "100", - "examine": "Plant this in a plant pot of soil to grow a sapling.", - "grand_exchange_price": "41200", - "durability": null, - "name": "Papaya tree seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5288" + "requirements": "{19,39}", + "tradeable": "true" }, { + "id": "5286", + "name": "Curry tree seed", + "examine": "Plant this in a plant pot of soil to grow a sapling.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,42}", + "tradeable": "true" + }, + { + "id": "5287", + "name": "Pineapple seed", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,51}", + "tradeable": "true" + }, + { + "id": "5288", + "name": "Papaya tree seed", + "examine": "Plant this in a plant pot of soil to grow a sapling.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,57}", + "tradeable": "true" + }, + { + "id": "5289", + "name": "Palm tree seed", + "examine": "Plant in a plantpot of soil to grow a sapling.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,68}", "shop_price": "35000", - "ge_buy_limit": "100", - "examine": "Plant in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "105100", - "durability": null, - "name": "Palm tree seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5289" + "tradeable": "true" }, { + "id": "5290", + "name": "Calquat tree seed", + "examine": "Plant in a plantpot of soil to grow a sapling.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,72}", "shop_price": "35000", - "ge_buy_limit": "100", - "examine": "Plant in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "32000", - "durability": null, - "name": "Calquat tree seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5290" + "tradeable": "true" }, { - "requirements": "{9,19}", - "ge_buy_limit": "100", - "examine": "A guam seed - plant in a herb patch.", - "grand_exchange_price": "5", - "durability": null, + "id": "5291", "name": "Guam seed", - "tradeable": "true", + "examine": "A guam seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5291" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{9,19}", + "tradeable": "true" }, { - "requirements": "{14,19}", - "ge_buy_limit": "100", - "examine": "A marrentill seed - plant in a herb patch.", - "grand_exchange_price": "5", - "durability": null, + "id": "5292", "name": "Marrentill seed", - "tradeable": "true", + "examine": "A marrentill seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5292" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{14,19}", + "tradeable": "true" }, { - "requirements": "{19,19}", - "ge_buy_limit": "100", - "examine": "A tarromin seed - plant in a herb patch.", - "grand_exchange_price": "1", - "durability": null, + "id": "5293", "name": "Tarromin seed", - "tradeable": "true", + "examine": "A tarromin seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5293" - }, - { - "requirements": "{19,26}", - "ge_buy_limit": "100", - "examine": "A harralander seed - plant in a herb patch.", - "grand_exchange_price": "4", "durability": null, - "name": "Harralander seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5294" + "ge_buy_limit": "100", + "requirements": "{19,19}", + "tradeable": "true" }, { + "id": "5294", + "name": "Harralander seed", + "examine": "A harralander seed - plant in a herb patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,26}", + "tradeable": "true" + }, + { + "id": "5295", + "name": "Ranarr seed", + "examine": "A Ranarr seed - plant in a herb patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,32}", "shop_price": "4000", - "ge_buy_limit": "100", - "examine": "A Ranarr seed - plant in a herb patch.", - "grand_exchange_price": "9489", - "durability": null, - "name": "Ranarr seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5295" + "tradeable": "true" }, { - "requirements": "{19,38}", - "ge_buy_limit": "100", - "examine": "A toadflax seed - plant in a herb patch.", - "grand_exchange_price": "2980", - "durability": null, + "id": "5296", "name": "Toadflax seed", - "tradeable": "true", + "examine": "A toadflax seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5296" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,38}", + "tradeable": "true" }, { - "requirements": "{19,44}", - "ge_buy_limit": "100", - "examine": "An irit seed - plant in a herb patch.", - "grand_exchange_price": "181", - "durability": null, + "id": "5297", "name": "Irit seed", - "tradeable": "true", + "examine": "An irit seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5297" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,44}", + "tradeable": "true" }, { - "requirements": "{19,50}", - "ge_buy_limit": "100", - "examine": "An avantoe seed - plant in a herb patch.", - "grand_exchange_price": "2492", - "durability": null, + "id": "5298", "name": "Avantoe seed", - "tradeable": "true", + "examine": "An avantoe seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5298" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,50}", + "tradeable": "true" }, { - "requirements": "{19,56}", - "ge_buy_limit": "100", - "examine": "A kwuarm seed - plant in a herb patch.", - "grand_exchange_price": "537", - "durability": null, + "id": "5299", "name": "Kwuarm seed", - "tradeable": "true", + "examine": "A kwuarm seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5299" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,56}", + "tradeable": "true" }, { - "requirements": "{19,62}", - "ge_buy_limit": "100", - "examine": "A snapdragon seed - plant in a herb patch.", - "grand_exchange_price": "47800", - "durability": null, + "id": "5300", "name": "Snapdragon seed", - "tradeable": "true", + "examine": "A snapdragon seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5300" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,62}", + "tradeable": "true" }, { - "requirements": "{19,67}", - "ge_buy_limit": "100", - "examine": "A cadantine seed - plant in a herb patch.", - "grand_exchange_price": "1253", - "durability": null, + "id": "5301", "name": "Cadantine seed", - "tradeable": "true", + "examine": "A cadantine seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5301" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,67}", + "tradeable": "true" }, { - "requirements": "{19,73}", - "ge_buy_limit": "100", - "examine": "A lantadyme seed - plant in a herb patch.", - "grand_exchange_price": "37100", - "durability": null, + "id": "5302", "name": "Lantadyme seed", - "tradeable": "true", - "weight": "0.1", + "examine": "A lantadyme seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5302" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,73}", + "tradeable": "true", + "weight": "0.1" }, { - "requirements": "{19,79}", - "ge_buy_limit": "100", - "examine": "A dwarf weed seed - plant in a herb patch.", - "grand_exchange_price": "41900", - "durability": null, + "id": "5303", "name": "Dwarf weed seed", - "tradeable": "true", + "examine": "A dwarf weed seed - plant in a herb patch.", "archery_ticket_price": "0", - "id": "5303" - }, - { - "requirements": "{19,85}", - "ge_buy_limit": "100", - "examine": "A Torstol seed - plant in a herb patch.", - "grand_exchange_price": "302300", "durability": null, - "name": "Torstol seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5304" + "ge_buy_limit": "100", + "requirements": "{19,79}", + "tradeable": "true" }, { + "id": "5304", + "name": "Torstol seed", + "examine": "A Torstol seed - plant in a herb patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,85}", + "tradeable": "true" + }, + { + "id": "5305", + "name": "Barley seed", + "examine": "A barley seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{3,19}", "shop_price": "38", - "ge_buy_limit": "100", - "examine": "A barley seed - plant in a hops patch.", - "grand_exchange_price": "1", - "durability": null, - "name": "Barley seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5305" + "tradeable": "true" }, { + "id": "5306", + "name": "Jute seed", + "examine": "A jute seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{13,19}", "shop_price": "86", - "ge_buy_limit": "100", - "examine": "A jute seed - plant in a hops patch.", - "grand_exchange_price": "2", - "durability": null, - "name": "Jute seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5306" + "tradeable": "true" }, { + "id": "5307", + "name": "Hammerstone seed", + "examine": "A hammerstone hop seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{4,19}", "shop_price": "52", - "ge_buy_limit": "100", - "examine": "A hammerstone hop seed - plant in a hops patch.", - "grand_exchange_price": "1", - "durability": null, - "name": "Hammerstone seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5307" + "tradeable": "true" }, { + "id": "5308", + "name": "Asgarnian seed", + "examine": "An Asgarnian hop seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{8,19}", "shop_price": "60", - "ge_buy_limit": "100", - "examine": "An Asgarnian hop seed - plant in a hops patch.", - "grand_exchange_price": "1", - "durability": null, - "name": "Asgarnian seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5308" + "tradeable": "true" }, { + "id": "5309", + "name": "Yanillian seed", + "examine": "A yanillian hop seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{16,19}", "shop_price": "210", - "ge_buy_limit": "100", - "examine": "A yanillian hop seed - plant in a hops patch.", - "grand_exchange_price": "11", - "durability": null, - "name": "Yanillian seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5309" + "tradeable": "true" }, { + "id": "5310", + "name": "Krandorian seed", + "examine": "A krandorian hop seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{21,19}", "shop_price": "8", - "ge_buy_limit": "100", - "examine": "A krandorian hop seed - plant in a hops patch.", - "grand_exchange_price": "1", - "durability": null, - "name": "Krandorian seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5310" + "tradeable": "true" }, { + "id": "5311", + "name": "Wildblood seed", + "examine": "A wildblood hop seed - plant in a hops patch.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{19,28}", "shop_price": "14", - "ge_buy_limit": "100", - "examine": "A wildblood hop seed - plant in a hops patch.", - "grand_exchange_price": "12", - "durability": null, - "name": "Wildblood seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5311" + "tradeable": "true" }, { + "id": "5312", + "name": "Acorn", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{15,19}", "shop_price": "100", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "22", - "durability": null, - "name": "Acorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5312" + "tradeable": "true" }, { - "requirements": "{19,30}", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "945", - "durability": null, + "id": "5313", "name": "Willow seed", - "tradeable": "true", + "examine": "Plant this in a plantpot of soil to grow a sapling.", "archery_ticket_price": "0", - "id": "5313" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,30}", + "tradeable": "true" }, { - "requirements": "{19,45}", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "35400", - "durability": null, + "id": "5314", "name": "Maple seed", - "tradeable": "true", + "examine": "Plant this in a plantpot of soil to grow a sapling.", "archery_ticket_price": "0", - "id": "5314" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,45}", + "tradeable": "true" }, { - "requirements": "{19,60}", - "ge_buy_limit": "100", - "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "81900", - "durability": null, + "id": "5315", "name": "Yew seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5315" - }, - { - "requirements": "{19,75}", - "ge_buy_limit": "100", "examine": "Plant this in a plantpot of soil to grow a sapling.", - "grand_exchange_price": "276900", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,60}", + "tradeable": "true" + }, + { + "id": "5316", "name": "Magic seed", - "tradeable": "true", + "examine": "Plant this in a plantpot of soil to grow a sapling.", "archery_ticket_price": "0", - "id": "5316" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,75}", + "tradeable": "true" }, { - "requirements": "{19,83}", - "shop_price": "55000", - "examine": "Plant this in a plant pot of soil to grow a sapling.", - "durability": null, + "id": "5317", "name": "Spirit seed", + "examine": "Plant this in a plant pot of soil to grow a sapling.", "archery_ticket_price": "0", - "id": "5317" - }, - { - "shop_price": "8", - "ge_buy_limit": "500", - "examine": "A potato seed - plant in an allotment.", - "grand_exchange_price": "1", "durability": null, - "name": "Potato seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5318" + "requirements": "{19,83}", + "shop_price": "55000" }, { + "id": "5318", + "name": "Potato seed", + "examine": "A potato seed - plant in an allotment.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "shop_price": "8", + "tradeable": "true" + }, + { + "id": "5319", + "name": "Onion seed", + "examine": "An onion seed - plant in an allotment.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", "requirements": "{5,19}", "shop_price": "10", - "ge_buy_limit": "500", - "examine": "An onion seed - plant in an allotment.", - "grand_exchange_price": "1", - "durability": null, - "name": "Onion seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5319" + "tradeable": "true" }, { - "requirements": "{20,19}", - "ge_buy_limit": "500", - "examine": "A sweetcorn seed - plant in an allotment.", - "grand_exchange_price": "2", - "durability": null, + "id": "5320", "name": "Sweetcorn seed", - "tradeable": "true", + "examine": "A sweetcorn seed - plant in an allotment.", "archery_ticket_price": "0", - "id": "5320" + "durability": null, + "ge_buy_limit": "500", + "requirements": "{20,19}", + "tradeable": "true" }, { + "id": "5321", + "name": "Watermelon seed", + "examine": "A watermelon seed - plant in an allotment.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", "requirements": "{19,47}", "shop_price": "56", - "ge_buy_limit": "500", - "examine": "A watermelon seed - plant in an allotment.", - "grand_exchange_price": "2491", - "durability": null, - "name": "Watermelon seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5321" + "tradeable": "true" }, { + "id": "5322", + "name": "Tomato seed", + "examine": "A tomato seed - plant in an allotment.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", "requirements": "{12,19}", "shop_price": "10", - "ge_buy_limit": "500", - "examine": "A tomato seed - plant in an allotment.", - "grand_exchange_price": "1", - "durability": null, - "name": "Tomato seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5322" + "tradeable": "true" }, { - "requirements": "{19,31}", - "ge_buy_limit": "500", - "examine": "A strawberry seed - plant in an allotment.", - "grand_exchange_price": "240", - "durability": null, + "id": "5323", "name": "Strawberry seed", - "tradeable": "true", + "examine": "A strawberry seed - plant in an allotment.", "archery_ticket_price": "0", - "id": "5323" + "durability": null, + "ge_buy_limit": "500", + "requirements": "{19,31}", + "tradeable": "true" }, { + "id": "5324", + "name": "Cabbage seed", + "examine": "A cabbage seed - plant in an allotment.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", "requirements": "{7,19}", "shop_price": "25", - "ge_buy_limit": "500", - "examine": "A cabbage seed - plant in an allotment.", - "grand_exchange_price": "1", - "durability": null, - "name": "Cabbage seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5324" + "tradeable": "true" }, { - "shop_price": "12", - "ge_buy_limit": "100", + "id": "5325", + "name": "Gardening trowel", "examine": "Not suitable for archaeological digs.", - "grand_exchange_price": "106", - "durability": null, - "name": "Gardening trowel", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5325" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "106", - "durability": null, - "name": "Gardening trowel", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5326" + "shop_price": "12", + "tradeable": "true" }, { - "examine": "I need to attach this to its head.", + "id": "5326", + "name": "Gardening trowel", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5327", "name": "Spade handle", - "tradeable": "false", + "examine": "I need to attach this to its head.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "5327" + "durability": null, + "tradeable": "false" }, { - "examine": "I need to attach this to its handle.", - "durability": null, + "id": "5328", "name": "Spade head", + "examine": "I need to attach this to its handle.", "archery_ticket_price": "0", - "id": "5328" + "durability": null }, { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "Good for pruning away diseased leaves.", - "grand_exchange_price": "204", - "durability": null, - "name": "Secateurs", - "tradeable": "true", - "archery_ticket_price": "0", "id": "5329", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "204", - "durability": null, "name": "Secateurs", - "tradeable": "true", + "examine": "Good for pruning away diseased leaves.", "archery_ticket_price": "0", - "id": "5330" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" }, { - "shop_price": "8", + "id": "5330", + "name": "Secateurs", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5331", + "name": "Watering can", "examine": "This watering can is empty.", - "grand_exchange_price": "298", - "durability": null, - "name": "Watering can", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.1", - "id": "5331" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "298", - "durability": null, - "name": "Watering can", + "shop_price": "8", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5332" + "weight": "0.1" }, { - "shop_price": "8", - "examine": " This watering can is almost empty.", - "grand_exchange_price": "206", + "id": "5332", + "name": "Watering can", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5333", "name": "Watering can(1)", + "examine": " This watering can is almost empty.", "archery_ticket_price": "0", - "weight": "0.2", - "id": "5333" + "durability": null, + "shop_price": "8", + "weight": "0.2" }, { - "shop_price": "8", - "examine": "This watering can is three-quarters empty.", - "grand_exchange_price": "206", - "durability": null, + "id": "5334", "name": "Watering can(2)", + "examine": "This watering can is three-quarters empty.", "archery_ticket_price": "0", - "weight": "0.3", - "id": "5334" + "durability": null, + "shop_price": "8", + "weight": "0.3" }, { - "shop_price": "8", - "examine": "This watering can is just under half-full.", - "grand_exchange_price": "206", - "durability": null, + "id": "5335", "name": "Watering can(3)", + "examine": "This watering can is just under half-full.", "archery_ticket_price": "0", - "weight": "0.4", - "id": "5335" + "durability": null, + "shop_price": "8", + "weight": "0.4" }, { - "shop_price": "8", - "examine": " Some would say this watering can is half-full, others half-empty.", - "grand_exchange_price": "206", - "durability": null, + "id": "5336", "name": "Watering can(4)", + "examine": " Some would say this watering can is half-full, others half-empty.", "archery_ticket_price": "0", - "weight": "0.5", - "id": "5336" + "durability": null, + "shop_price": "8", + "weight": "0.5" }, { - "shop_price": "8", - "examine": "This watering can is just over half-full.", - "grand_exchange_price": "206", - "durability": null, + "id": "5337", "name": "Watering can(5)", + "examine": "This watering can is just over half-full.", "archery_ticket_price": "0", - "weight": "0.6", - "id": "5337" + "durability": null, + "shop_price": "8", + "weight": "0.6" }, { - "shop_price": "8", - "examine": " This watering can is three quarters full.", - "grand_exchange_price": "206", - "durability": null, + "id": "5338", "name": "Watering can(6)", + "examine": " This watering can is three quarters full.", "archery_ticket_price": "0", - "weight": "0.7", - "id": "5338" + "durability": null, + "shop_price": "8", + "weight": "0.7" }, { - "shop_price": "8", - "examine": " This watering can is almost completely full.", - "grand_exchange_price": "206", - "durability": null, + "id": "5339", "name": "Watering can(7)", + "examine": " This watering can is almost completely full.", "archery_ticket_price": "0", - "weight": "0.8", - "id": "5339" - }, - { + "durability": null, "shop_price": "8", - "examine": " This watering can is completely full.", - "grand_exchange_price": "206", - "durability": null, + "weight": "0.8" + }, + { + "id": "5340", "name": "Watering can(8)", + "examine": " This watering can is completely full.", "archery_ticket_price": "0", - "weight": "0.9", - "id": "5340" + "durability": null, + "shop_price": "8", + "weight": "0.9" }, { - "shop_price": "6", - "ge_buy_limit": "100", + "id": "5341", + "name": "Rake", "examine": "Use this to clear weeds.", - "grand_exchange_price": "99", - "durability": null, - "name": "Rake", - "tradeable": "true", - "weight": "1.3", "archery_ticket_price": "0", - "id": "5341" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "99", - "durability": null, - "name": "Rake", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5342" - }, - { "shop_price": "6", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "5342", + "name": "Rake", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5343", + "name": "Seed dibber", "examine": "Use this to plant seeds with.", - "grand_exchange_price": "117", - "durability": null, - "name": "Seed dibber", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5343" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "117", - "durability": null, + "id": "5344", "name": "Seed dibber", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5344" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A pair of gardening boots.", - "grand_exchange_price": "3186", - "durability": null, - "name": "Gardening boots", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "5345", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3186", - "durability": null, "name": "Gardening boots", - "tradeable": "true", + "examine": "A pair of gardening boots.", "archery_ticket_price": "0", - "id": "5346" + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "examine": "I need to reattach this to its head.", + "id": "5346", + "name": "Gardening boots", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5347", "name": "Rake handle", - "weight": "0.4", + "examine": "I need to reattach this to its head.", "archery_ticket_price": "0", - "id": "5347" + "durability": null, + "weight": "0.4" }, { - "examine": "I need to reattach this to its handle.", - "durability": null, + "id": "5348", "name": "Rake head", - "weight": "0.9", + "examine": "I need to reattach this to its handle.", "archery_ticket_price": "0", - "id": "5348" + "durability": null, + "weight": "0.9" }, { - "shop_price": "1", - "ge_buy_limit": "100", + "id": "5350", + "name": "Plant pot", "examine": "An empty plant pot.", - "grand_exchange_price": "20", - "durability": null, - "name": "Plant pot", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "5350" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, + "id": "5351", "name": "Plant pot", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5351" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "9", - "ge_buy_limit": "100", + "id": "5352", + "name": "Unfired plant pot", "examine": "An unfired plant pot.", - "grand_exchange_price": "7", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "shop_price": "9", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5353", "name": "Unfired plant pot", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "5352" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7", "durability": null, - "name": "Unfired plant pot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5353" + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "1", - "ge_buy_limit": "100", + "id": "5354", + "name": "Plant pot", "examine": "A plant pot filled with soil.", - "grand_exchange_price": "340", - "durability": null, - "name": "Plant pot", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "5354" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "340", - "durability": null, - "name": "Plant pot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5355" - }, - { "shop_price": "1", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5355", + "name": "Plant pot", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5356", + "name": "Plant pot", "examine": "A plant pot filled with soil.", - "grand_exchange_price": "243", + "archery_ticket_price": "0", "durability": null, - "name": "Plant pot", + "shop_price": "1", "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5356" + "weight": "0.9" }, { - "durability": null, + "id": "5357", "name": "Plant pot", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5357" + "durability": null, + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An acorn has been sown and watered in this plant pot.", - "durability": null, + "id": "5358", "name": "Oak seedling", + "examine": "An acorn has been sown in this plant pot.", "archery_ticket_price": "0", - "id": "5358" + "durability": null, + "shop_price": "200" }, { - "examine": "A willow tree seed has been sown and watered in this plant pot", - "durability": null, + "id": "5359", "name": "Willow seedling", - "weight": "0.9", + "examine": "A willow tree seed has been sown in this plant pot.", "archery_ticket_price": "0", - "id": "5359" + "durability": null, + "weight": "0.9" }, { - "examine": "A maple tree has been sown (and watered) in this plant pot.", - "durability": null, + "id": "5360", "name": "Maple seedling", - "weight": "0.9", + "examine": "A maple tree seed has been sown in this plant pot.", "archery_ticket_price": "0", - "id": "5360" + "durability": null, + "weight": "0.9" }, { - "examine": "A yew seed has been sown in the plant pot", - "durability": null, + "id": "5361", "name": "Yew seedling", - "weight": "1", + "examine": "A yew tree seed has been sown in this plant pot.", "archery_ticket_price": "0", - "id": "5361" + "durability": null, + "weight": "1" }, { - "examine": "A magic tree seed has been sown and watered in this plant pot.", - "durability": null, + "id": "5362", "name": "Magic seedling", - "weight": "0.9", + "examine": "A magic tree seed has been sown in this plant pot.", "archery_ticket_price": "0", - "id": "5362" + "durability": null, + "weight": "0.9" }, { - "examine": "A spirit seedling is growing in this pot. It has been sown and watered.", - "durability": null, + "id": "5363", "name": "Spirit seedling", + "examine": "A spirit tree seed has been sown in this plant pot.", "archery_ticket_price": "0", - "id": "5363" + "durability": null }, { - "shop_price": "200", - "examine": "An acorn has been sown and watered in this plant pot.", - "durability": null, + "id": "5364", "name": "Oak seedling", + "examine": "An acorn has been sown and watered in this plant pot.", "archery_ticket_price": "0", - "id": "5364" + "durability": null, + "shop_price": "200" }, { - "examine": "A willow tree seed has been sown and watered in this plant pot", - "durability": null, + "id": "5365", "name": "Willow seedling", - "weight": "0.9", + "examine": "A willow tree seed has been sown and watered in this plant pot.", "archery_ticket_price": "0", - "id": "5365" + "durability": null, + "weight": "0.9" }, { - "examine": "A maple tree has been sown (and watered) in this plant pot.", - "durability": null, + "id": "5366", "name": "Maple seedling", - "weight": "0.9", + "examine": "A maple tree seed has been sown and watered in this plant pot.", "archery_ticket_price": "0", - "id": "5366" + "durability": null, + "weight": "0.9" }, { - "examine": "A yew seed has been sown in the plant pot", - "durability": null, + "id": "5367", "name": "Yew seedling", - "weight": "1", + "examine": "A yew tree seed has been sown and watered in this plant pot.", "archery_ticket_price": "0", - "id": "5367" + "durability": null, + "weight": "1" }, { - "examine": "A magic tree seed has been sown and watered in this plant pot.", - "durability": null, + "id": "5368", "name": "Magic seedling", - "weight": "0.9", + "examine": "A magic tree seed has been sown and watered in this plant pot.", "archery_ticket_price": "0", - "id": "5368" + "durability": null, + "weight": "0.9" }, { - "examine": "A spirit seedling is growing in this pot. It has been sown and watered.", - "durability": null, + "id": "5369", "name": "Spirit seedling", + "examine": "A spirit tree seed has been sown and watered in this plant pot.", "archery_ticket_price": "0", - "id": "5369" + "durability": null }, { - "examine": "This sapling is ready to be planted in a tree patch.", - "durability": null, + "id": "5370", "name": "Oak sapling", - "weight": "0.9", + "examine": "This sapling is ready to be planted in a tree patch.", "archery_ticket_price": "0", - "id": "5370" + "durability": null, + "weight": "0.9" }, { - "examine": "This sapling is ready to be replanted in a tree patch.", - "durability": null, + "id": "5371", "name": "Willow sapling", - "weight": "0.9", + "examine": "This sapling is ready to be replanted in a tree patch.", "archery_ticket_price": "0", - "id": "5371" + "durability": null, + "weight": "0.9" }, { - "examine": "This sapling is ready to be planted in a tree patch.", - "durability": null, + "id": "5372", "name": "Maple sapling", - "weight": "0.9", + "examine": "This sapling is ready to be planted in a tree patch.", "archery_ticket_price": "0", - "id": "5372" + "durability": null, + "weight": "0.9" }, { - "examine": "This sapling is ready to be planted in a tree patch.", - "durability": null, + "id": "5373", "name": "Yew sapling", - "weight": "0.9", + "examine": "This sapling is ready to be planted in a tree patch.", "archery_ticket_price": "0", - "id": "5373" + "durability": null, + "weight": "0.9" }, { - "examine": "This sapling is ready to be planted in a tree patch.", - "durability": null, + "id": "5374", "name": "Magic sapling", - "weight": "0.9", + "examine": "This sapling is ready to be planted in a tree patch.", "archery_ticket_price": "0", - "id": "5374" + "durability": null, + "weight": "0.9" }, { - "examine": "This sapling is ready to be planted in a tree patch.", - "durability": null, + "id": "5375", "name": "Spirit sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5375" - }, - { - "shop_price": "1", - "ge_buy_limit": "1000", - "examine": "An empty fruit basket.", - "grand_exchange_price": "1", - "durability": null, - "name": "Basket", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5376" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1", - "durability": null, - "name": "Basket", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5377" - }, - { - "examine": "A fruit basket filled with apples.", - "grand_exchange_price": "1889", - "durability": null, - "name": "Apples(1)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5378" - }, - { - "durability": null, - "name": "Apples(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5379" - }, - { - "examine": "A fruit basket filled with apples.", - "grand_exchange_price": "1889", - "durability": null, - "name": "Apples(2)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5380" - }, - { - "durability": null, - "name": "Apples(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5381" - }, - { - "examine": "A fruit basket filled with apples.", - "grand_exchange_price": "1889", - "durability": null, - "name": "Apples(3)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5382" - }, - { - "durability": null, - "name": "Apples(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5383" - }, - { - "examine": "A fruit basket filled with apples.", - "grand_exchange_price": "1889", - "durability": null, - "name": "Apples(4)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5384" - }, - { - "durability": null, - "name": "Apples(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5385" - }, - { - "ge_buy_limit": "1000", - "examine": "A fruit basket filled with apples.", - "grand_exchange_price": "2448", - "durability": null, - "name": "Apples(5)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5386" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2448", - "durability": null, - "name": "Apples(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5387" - }, - { - "examine": "A fruit basket filled with oranges", - "grand_exchange_price": "3823", - "durability": null, - "name": "Oranges(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5388" - }, - { - "durability": null, - "name": "Oranges(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5389" - }, - { - "examine": "A fruit basket filled with oranges", - "grand_exchange_price": "3823", - "durability": null, - "name": "Oranges(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5390" - }, - { - "durability": null, - "name": "Oranges(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5391" - }, - { - "examine": "A fruit basket filled with oranges", - "grand_exchange_price": "3823", - "durability": null, - "name": "Oranges(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5392" - }, - { - "durability": null, - "name": "Oranges(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5393" - }, - { - "examine": "A fruit basket filled with oranges", - "grand_exchange_price": "3823", - "durability": null, - "name": "Oranges(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5394" - }, - { - "durability": null, - "name": "Oranges(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5395" - }, - { - "shop_price": "70", - "ge_buy_limit": "1000", - "examine": "A common fruit.", - "grand_exchange_price": "5649", - "durability": null, - "name": "Oranges(5)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5396" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "5649", - "durability": null, - "name": "Oranges(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5397" - }, - { - "examine": "A fruit basket filled with strawberries.", - "grand_exchange_price": "5", - "durability": null, - "name": "Strawberries(1)", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "5398" - }, - { - "durability": null, - "name": "Strawberries(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5399" - }, - { - "examine": "A fruit basket filled with strawberries.", - "grand_exchange_price": "5", - "durability": null, - "name": "Strawberries(2)", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "5400" - }, - { - "durability": null, - "name": "Strawberries(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5401" - }, - { - "examine": "A fruit basket filled with strawberries.", - "grand_exchange_price": "5", - "durability": null, - "name": "Strawberries(3)", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "5402" - }, - { - "durability": null, - "name": "Strawberries(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5403" - }, - { - "examine": "A fruit basket filled with strawberries.", - "grand_exchange_price": "5", - "durability": null, - "name": "Strawberries(4)", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "5404" - }, - { - "durability": null, - "name": "Strawberries(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5405" - }, - { - "ge_buy_limit": "10000", - "examine": "A fruit basket filled with strawberries.", - "grand_exchange_price": "406", - "durability": null, - "name": "Strawberries(5)", - "tradeable": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "5406" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "406", - "durability": null, - "name": "Strawberries(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5407" - }, - { - "examine": "A fruit basket filled with bananas.", - "grand_exchange_price": "1064", - "durability": null, - "name": "Bananas(1)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5408" - }, - { - "durability": null, - "name": "Bananas(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5409" - }, - { - "examine": "A fruit basket filled with bananas.", - "grand_exchange_price": "1064", - "durability": null, - "name": "Bananas(2)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5410" - }, - { - "durability": null, - "name": "Bananas(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5411" - }, - { - "examine": "A fruit basket filled with bananas.", - "grand_exchange_price": "1064", - "durability": null, - "name": "Bananas(3)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5412" - }, - { - "durability": null, - "name": "Bananas(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5413" - }, - { - "shop_price": "2", - "examine": "Mmm this looks tasty.", - "grand_exchange_price": "171", - "durability": null, - "name": "Bananas(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5414" - }, - { - "durability": null, - "name": "Bananas(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5415" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "Mmm this looks tasty.", - "grand_exchange_price": "1637", - "durability": null, - "name": "Bananas(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5416" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1637", - "durability": null, - "name": "Bananas(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5417" - }, - { - "shop_price": "1", - "ge_buy_limit": "100", - "examine": "An empty sack.", - "grand_exchange_price": "45", - "durability": null, - "name": "Empty sack", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "5418" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "45", - "durability": null, - "name": "Empty sack", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5419" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(1)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5420" - }, - { - "durability": null, - "name": "Potatoes(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5421" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(2)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5422" - }, - { - "durability": null, - "name": "Potatoes(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5423" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(3)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5424" - }, - { - "durability": null, - "name": "Potatoes(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5425" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(4)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5426" - }, - { - "durability": null, - "name": "Potatoes(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5427" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(5)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5428" - }, - { - "durability": null, - "name": "Potatoes(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5429" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(6)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5430" - }, - { - "durability": null, - "name": "Potatoes(6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5431" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(7)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5432" - }, - { - "durability": null, - "name": "Potatoes(7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5433" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(8)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5434" - }, - { - "durability": null, - "name": "Potatoes(8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5435" - }, - { - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1276", - "durability": null, - "name": "Potatoes(9)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5436" - }, - { - "durability": null, - "name": "Potatoes(9)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5437" - }, - { - "ge_buy_limit": "1000", - "examine": "There are <number of potatoes> in this sack.", - "grand_exchange_price": "1052", - "durability": null, - "name": "Potatoes(10)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5438" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1052", - "durability": null, - "name": "Potatoes(10)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5439" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(1)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5440" - }, - { - "durability": null, - "name": "Onions(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5441" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(2)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5442" - }, - { - "durability": null, - "name": "Onions(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5443" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(3)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5444" - }, - { - "durability": null, - "name": "Onions(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5445" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(4)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5446" - }, - { - "durability": null, - "name": "Onions(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5447" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(5)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5448" - }, - { - "durability": null, - "name": "Onions(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5449" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(6)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5450" - }, - { - "durability": null, - "name": "Onions(6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5451" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(7)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5452" - }, - { - "durability": null, - "name": "Onions(7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5453" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(8)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5454" - }, - { - "durability": null, - "name": "Onions(8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5455" - }, - { - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "589", - "durability": null, - "name": "Onions(9)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5456" - }, - { - "durability": null, - "name": "Onions(9)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5457" - }, - { - "ge_buy_limit": "1000", - "examine": "There are/is (1-10) onion(s) in this sack.", - "grand_exchange_price": "489", - "durability": null, - "name": "Onions(10)", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5458" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "489", - "durability": null, - "name": "Onions(10)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5459" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5460" - }, - { - "durability": null, - "name": "Cabbages(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5461" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5462" - }, - { - "durability": null, - "name": "Cabbages(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5463" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5464" - }, - { - "durability": null, - "name": "Cabbages(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5465" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5466" - }, - { - "durability": null, - "name": "Cabbages(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5467" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5468" - }, - { - "durability": null, - "name": "Cabbages(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5469" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5470" - }, - { - "durability": null, - "name": "Cabbages(6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5471" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5472" - }, - { - "durability": null, - "name": "Cabbages(7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5473" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5474" - }, - { - "durability": null, - "name": "Cabbages(8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5475" - }, - { - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "1304", - "durability": null, - "name": "Cabbages(9)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5476" - }, - { - "durability": null, - "name": "Cabbages(9)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5477" - }, - { - "ge_buy_limit": "1000", - "examine": "There are <number of cabbages> in this sack.", - "grand_exchange_price": "917", - "durability": null, - "name": "Cabbages(10)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5478" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "917", - "durability": null, - "name": "Cabbages(10)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5479" - }, - { - "examine": "An apple tree has been sown (and watered) in this plant pot.", - "durability": null, - "name": "Apple seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5480" - }, - { - "examine": "A banana tree seed has been sown and watered in this plant pot.", - "durability": null, - "name": "Banana seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5481" - }, - { - "examine": "An orange tree seed has been sown (and watered)in this plant pot.", - "durability": null, - "name": "Orange seedling", - "archery_ticket_price": "0", - "id": "5482" - }, - { - "examine": "A curry seed has been sown and watered in this plant pot.", - "durability": null, - "name": "Curry seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5483" - }, - { - "examine": "A pineapple tree has been sown (and watered) in this plant pot.", - "durability": null, - "name": "Pineapple seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5484" - }, - { - "examine": "This needs watering before it will grow.", - "durability": null, - "name": "Papaya seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5485" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Palm seedling", - "weight": "0.66", - "archery_ticket_price": "0", - "id": "5486" - }, - { - "examine": "A calquat tree has been sown (and watered) in this plant pot.", - "durability": null, - "name": "Calquat seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5487" - }, - { - "examine": "An apple tree has been sown (and watered) in this plant pot.", - "durability": null, - "name": "Apple seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5488" - }, - { - "examine": "A banana tree seed has been sown and watered in this plant pot.", - "durability": null, - "name": "Banana seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5489" - }, - { - "examine": "An orange tree seed has been sown (and watered)in this plant pot.", - "durability": null, - "name": "Orange seedling", - "archery_ticket_price": "0", - "id": "5490" - }, - { - "examine": "A curry seed has been sown and watered in this plant pot.", - "durability": null, - "name": "Curry seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5491" - }, - { - "examine": "A pineapple tree has been sown (and watered) in this plant pot.", - "durability": null, - "name": "Pineapple seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5492" - }, - { - "examine": "This needs watering before it will grow.", - "durability": null, - "name": "Papaya seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5493" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Palm seedling", - "weight": "0.66", - "archery_ticket_price": "0", - "id": "5494" - }, - { - "examine": "A calquat tree has been sown (and watered) in this plant pot.", - "durability": null, - "name": "Calquat seedling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5495" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Apple sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5496" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Banana sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5497" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Orange sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5498" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Curry sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5499" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Pineapple sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5500" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Papaya sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5501" - }, - { - "examine": "This sapling is ready to be replanted in a fruit tree patch.", - "durability": null, - "name": "Palm sapling", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5502" - }, - { "examine": "This sapling is ready to be planted in a tree patch.", + "archery_ticket_price": "0", "durability": null, + "weight": "0.9" + }, + { + "id": "5376", + "name": "Basket", + "examine": "An empty fruit basket.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "5377", + "name": "Basket", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5378", + "name": "Apples(1)", + "examine": "A fruit basket filled with apples.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5379", + "name": "Apples(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5380", + "name": "Apples(2)", + "examine": "A fruit basket filled with apples.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5381", + "name": "Apples(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5382", + "name": "Apples(3)", + "examine": "A fruit basket filled with apples.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5383", + "name": "Apples(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5384", + "name": "Apples(4)", + "examine": "A fruit basket filled with apples.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5385", + "name": "Apples(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5386", + "name": "Apples(5)", + "examine": "A fruit basket filled with apples.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5387", + "name": "Apples(5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5388", + "name": "Oranges(1)", + "examine": "A fruit basket filled with oranges", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5389", + "name": "Oranges(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5390", + "name": "Oranges(2)", + "examine": "A fruit basket filled with oranges", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5391", + "name": "Oranges(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5392", + "name": "Oranges(3)", + "examine": "A fruit basket filled with oranges", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5393", + "name": "Oranges(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5394", + "name": "Oranges(4)", + "examine": "A fruit basket filled with oranges", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5395", + "name": "Oranges(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5396", + "name": "Oranges(5)", + "examine": "A common fruit.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "70", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5397", + "name": "Oranges(5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5398", + "name": "Strawberries(1)", + "examine": "A fruit basket filled with strawberries.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "5399", + "name": "Strawberries(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5400", + "name": "Strawberries(2)", + "examine": "A fruit basket filled with strawberries.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "5401", + "name": "Strawberries(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5402", + "name": "Strawberries(3)", + "examine": "A fruit basket filled with strawberries.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "5403", + "name": "Strawberries(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5404", + "name": "Strawberries(4)", + "examine": "A fruit basket filled with strawberries.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "5405", + "name": "Strawberries(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5406", + "name": "Strawberries(5)", + "examine": "A fruit basket filled with strawberries.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "5407", + "name": "Strawberries(5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5408", + "name": "Bananas(1)", + "examine": "A fruit basket filled with bananas.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5409", + "name": "Bananas(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5410", + "name": "Bananas(2)", + "examine": "A fruit basket filled with bananas.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5411", + "name": "Bananas(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5412", + "name": "Bananas(3)", + "examine": "A fruit basket filled with bananas.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5413", + "name": "Bananas(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5414", + "name": "Bananas(4)", + "examine": "Mmm this looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "5415", + "name": "Bananas(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5416", + "name": "Bananas(5)", + "examine": "Mmm this looks tasty.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "5417", + "name": "Bananas(5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5418", + "name": "Empty sack", + "examine": "An empty sack.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "5419", + "name": "Empty sack", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5420", + "name": "Potatoes(1)", + "examine": "There is one potato in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5421", + "name": "Potatoes(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5422", + "name": "Potatoes(2)", + "examine": "There are two potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5423", + "name": "Potatoes(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5424", + "name": "Potatoes(3)", + "examine": "There are three potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5425", + "name": "Potatoes(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5426", + "name": "Potatoes(4)", + "examine": "There are four potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5427", + "name": "Potatoes(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5428", + "name": "Potatoes(5)", + "examine": "There are five potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5429", + "name": "Potatoes(5)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5430", + "name": "Potatoes(6)", + "examine": "There are six potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5431", + "name": "Potatoes(6)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5432", + "name": "Potatoes(7)", + "examine": "There are seven potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5433", + "name": "Potatoes(7)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5434", + "name": "Potatoes(8)", + "examine": "There are eight potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5435", + "name": "Potatoes(8)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5436", + "name": "Potatoes(9)", + "examine": "There are nine potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5437", + "name": "Potatoes(9)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5438", + "name": "Potatoes(10)", + "examine": "There are ten potatoes in this sack.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5439", + "name": "Potatoes(10)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5440", + "name": "Onions(1)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5441", + "name": "Onions(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5442", + "name": "Onions(2)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5443", + "name": "Onions(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5444", + "name": "Onions(3)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5445", + "name": "Onions(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5446", + "name": "Onions(4)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5447", + "name": "Onions(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5448", + "name": "Onions(5)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5449", + "name": "Onions(5)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5450", + "name": "Onions(6)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5451", + "name": "Onions(6)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5452", + "name": "Onions(7)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5453", + "name": "Onions(7)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5454", + "name": "Onions(8)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5455", + "name": "Onions(8)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5456", + "name": "Onions(9)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5457", + "name": "Onions(9)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5458", + "name": "Onions(10)", + "examine": "There are/is (1-10) onion(s) in this sack.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5459", + "name": "Onions(10)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5460", + "name": "Cabbages(1)", + "examine": "There is one cabbage in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5461", + "name": "Cabbages(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5462", + "name": "Cabbages(2)", + "examine": "There are two cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5463", + "name": "Cabbages(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5464", + "name": "Cabbages(3)", + "examine": "There are three cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5465", + "name": "Cabbages(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5466", + "name": "Cabbages(4)", + "examine": "There are four cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5467", + "name": "Cabbages(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5468", + "name": "Cabbages(5)", + "examine": "There are five cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5469", + "name": "Cabbages(5)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5470", + "name": "Cabbages(6)", + "examine": "There are six cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5471", + "name": "Cabbages(6)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5472", + "name": "Cabbages(7)", + "examine": "There are seven cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5473", + "name": "Cabbages(7)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5474", + "name": "Cabbages(8)", + "examine": "There are eight cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5475", + "name": "Cabbages(8)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5476", + "name": "Cabbages(9)", + "examine": "There are nine cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5477", + "name": "Cabbages(9)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5478", + "name": "Cabbages(10)", + "examine": "There are ten cabbages in this sack.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5479", + "name": "Cabbages(10)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5480", + "name": "Apple seedling", + "examine": "An apple tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5481", + "name": "Banana seedling", + "examine": "A banana tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5482", + "name": "Orange seedling", + "examine": "An orange tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "5483", + "name": "Curry seedling", + "examine": "A curry tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5484", + "name": "Pineapple seedling", + "examine": "A pineapple plant seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5485", + "name": "Papaya seedling", + "examine": "A papaya tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5486", + "name": "Palm seedling", + "examine": "A palm tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.66" + }, + { + "id": "5487", + "name": "Calquat seedling", + "examine": "A calquat tree seed has been sown in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5488", + "name": "Apple seedling", + "examine": "An apple tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5489", + "name": "Banana seedling", + "examine": "A banana tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5490", + "name": "Orange seedling", + "examine": "An orange tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "5491", + "name": "Curry seedling", + "examine": "A curry tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5492", + "name": "Pineapple seedling", + "examine": "A pineapple plant seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5493", + "name": "Papaya seedling", + "examine": "A papaya tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5494", + "name": "Palm seedling", + "examine": "A palm tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.66" + }, + { + "id": "5495", + "name": "Calquat seedling", + "examine": "A calquat tree seed has been sown and watered in this plant pot.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5496", + "name": "Apple sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5497", + "name": "Banana sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5498", + "name": "Orange sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5499", + "name": "Curry sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5500", + "name": "Pineapple sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5501", + "name": "Papaya sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5502", + "name": "Palm sapling", + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "5503", "name": "Calquat sapling", - "weight": "0.9", + "examine": "This sapling is ready to be planted in a tree patch.", "archery_ticket_price": "0", - "id": "5503" + "durability": null, + "weight": "0.9" }, { - "ge_buy_limit": "10000", + "id": "5504", + "name": "Strawberry", "examine": "A freshly picked strawberry.", - "grand_exchange_price": "23", - "durability": null, - "name": "Strawberry", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "5504" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "23", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "5505", "name": "Strawberry", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5505" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "examine": "The Wise Old Man of Draynor Village asked you to take this to someone.", - "durability": null, + "id": "5506", "name": "Old man's message", + "examine": "The Wise Old Man of Draynor Village asked you to take this to someone.", "archery_ticket_price": "0", - "id": "5506" + "durability": null }, { - "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", - "durability": null, + "id": "5507", "name": "Strange book", - "archery_ticket_price": "0", - "id": "5507" - }, - { "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "5508", "name": "Book of folklore", + "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", "archery_ticket_price": "0", - "id": "5508" + "durability": null }, { - "examine": "A small pouch used for storing essence.", - "durability": null, + "id": "5509", "name": "Small pouch", - "weight": "1", + "examine": "A small pouch used for storing essence.", "archery_ticket_price": "0", - "id": "5509" + "durability": null, + "weight": "1" }, { - "examine": "A medium-sized pouch used for storing essence.", - "durability": null, + "id": "5510", "name": "Medium pouch", - "weight": "1", - "archery_ticket_price": "0", - "id": "5510" - }, - { "examine": "A medium-sized pouch used for storing essence.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "5511", "name": "Medium pouch", - "weight": "1", + "examine": "A medium-sized pouch used for storing essence.", "archery_ticket_price": "0", - "id": "5511" + "durability": null, + "weight": "1" }, { - "shop_price": "25000", - "examine": "A large pouch used for storing essence.", - "durability": null, + "id": "5512", "name": "Large pouch", - "weight": "1", - "archery_ticket_price": "0", - "id": "5512" - }, - { - "shop_price": "25000", "examine": "A large pouch used for storing essence.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "25000", + "weight": "1" + }, + { + "id": "5513", "name": "Large pouch", - "weight": "1", + "examine": "A large pouch used for storing essence.", "archery_ticket_price": "0", - "id": "5513" - }, - { - "shop_price": "50000", - "examine": "A giant-sized pouch used for storing essence.", "durability": null, - "name": "Giant pouch", - "weight": "1", - "archery_ticket_price": "0", - "id": "5514" + "shop_price": "25000", + "weight": "1" }, { - "shop_price": "50000", + "id": "5514", + "name": "Giant pouch", "examine": "A giant-sized pouch used for storing essence.", - "durability": null, - "name": "Giant pouch", - "weight": "1", "archery_ticket_price": "0", - "id": "5515" + "durability": null, + "shop_price": "50000", + "weight": "1" }, { - "ge_buy_limit": "500", + "id": "5515", + "name": "Giant pouch", + "examine": "A giant-sized pouch used for storing essence.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "50000", + "weight": "1" + }, + { + "id": "5516", + "name": "Elemental talisman", "examine": "A mysterious power emanates from the talisman...", - "grand_exchange_price": "186900", - "durability": null, - "name": "Elemental talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5516" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "186900", - "durability": null, + "tradeable": "true" + }, + { + "id": "5517", "name": "Elemental talisman", - "tradeable": "true", "archery_ticket_price": "0", - "id": "5517" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { + "id": "5518", + "name": "Scrying orb", "examine": "This contains mystical teleport information...", - "durability": null, - "name": "Scrying orb", - "weight": "1", "archery_ticket_price": "0", - "id": "5518" + "durability": null, + "weight": "1" }, { + "id": "5519", + "name": "Scrying orb", "examine": "This orb apparently contains a cypher spell.", - "durability": null, - "name": "Scrying orb", - "weight": "1", "archery_ticket_price": "0", - "id": "5519" + "durability": null, + "weight": "1" }, { - "examine": "Some research notes on abyssal space.", - "durability": null, + "id": "5520", "name": "Abyssal book", - "tradeable": "true", + "examine": "Some research notes on abyssal space.", "archery_ticket_price": "0", - "id": "5520" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A necklace embedded with mystical power.", - "grand_exchange_price": "720", - "durability": null, - "name": "Binding necklace", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "5521", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "720", - "durability": null, "name": "Binding necklace", - "tradeable": "true", + "examine": "A necklace embedded with mystical power.", "archery_ticket_price": "0", - "id": "5522" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "100", + "id": "5522", + "name": "Binding necklace", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5523", + "name": "Tiara mould", "examine": "A mould for tiaras.", - "grand_exchange_price": "315", - "durability": null, - "name": "Tiara mould", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "5523" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "315", - "durability": null, - "name": "Tiara mould", + "shop_price": "100", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5524" + "weight": "1" }, { - "ge_buy_limit": "1000", - "examine": "Makes me feel like a Princess.", - "grand_exchange_price": "13", - "durability": null, - "name": "Tiara", - "tradeable": "true", - "weight": "1", + "id": "5524", + "name": "Tiara mould", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5525", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "13", - "durability": null, "name": "Tiara", - "tradeable": "true", + "examine": "Makes me feel like a Princess.", "archery_ticket_price": "0", - "id": "5526" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of air.", - "grand_exchange_price": "5", - "durability": null, - "name": "Air tiara", - "tradeable": "true", - "weight": "1", + "id": "5526", + "name": "Tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { "id": "5527", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5", - "durability": null, "name": "Air tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of air.", "archery_ticket_price": "0", - "id": "5528" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of the mind.", - "grand_exchange_price": "10", - "durability": null, - "name": "Mind tiara", - "tradeable": "true", - "weight": "1", + "id": "5528", + "name": "Air tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5529", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10", - "durability": null, "name": "Mind tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of the mind.", "archery_ticket_price": "0", - "id": "5530" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of water.", - "grand_exchange_price": "1351", - "durability": null, - "name": "Water tiara", - "tradeable": "true", - "weight": "1", + "id": "5530", + "name": "Mind tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5531", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1351", - "durability": null, "name": "Water tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of water.", "archery_ticket_price": "0", - "id": "5532" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of the body.", - "grand_exchange_price": "5", - "durability": null, - "name": "Body tiara", - "tradeable": "true", - "weight": "1", + "id": "5532", + "name": "Water tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5533", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5", - "durability": null, "name": "Body tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of the body.", "archery_ticket_price": "0", - "id": "5534" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of the earth.", - "grand_exchange_price": "4", - "durability": null, - "name": "Earth tiara", - "tradeable": "true", - "weight": "1", + "id": "5534", + "name": "Body tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5535", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4", - "durability": null, "name": "Earth tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of the earth.", "archery_ticket_price": "0", - "id": "5536" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of fire.", - "grand_exchange_price": "8", - "durability": null, - "name": "Fire tiara", - "tradeable": "true", - "weight": "1", + "id": "5536", + "name": "Earth tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5537", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, "name": "Fire tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of fire.", "archery_ticket_price": "0", - "id": "5538" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of the cosmos.", - "grand_exchange_price": "8", - "durability": null, - "name": "Cosmic tiara", - "tradeable": "true", - "weight": "1", + "id": "5538", + "name": "Fire tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5539", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, "name": "Cosmic tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of the cosmos.", "archery_ticket_price": "0", - "id": "5540" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of nature.", - "grand_exchange_price": "10", - "durability": null, - "name": "Nature tiara", - "tradeable": "true", - "weight": "1", + "id": "5540", + "name": "Cosmic tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5541", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10", - "durability": null, "name": "Nature tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of nature.", "archery_ticket_price": "0", - "id": "5542" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of chaos.", - "grand_exchange_price": "10", - "durability": null, - "name": "Chaos tiara", - "tradeable": "true", - "weight": "1", + "id": "5542", + "name": "Nature tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5543", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10", - "durability": null, "name": "Chaos tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of chaos.", "archery_ticket_price": "0", - "id": "5544" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of law.", - "grand_exchange_price": "11", - "durability": null, - "name": "Law tiara", - "tradeable": "true", - "weight": "1", + "id": "5544", + "name": "Chaos tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5545", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11", - "durability": null, "name": "Law tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of law.", "archery_ticket_price": "0", - "id": "5546" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of death.", - "grand_exchange_price": "65", - "durability": null, - "name": "Death tiara", - "tradeable": "true", - "weight": "1", + "id": "5546", + "name": "Law tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5547", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "65", - "durability": null, "name": "Death tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of death.", "archery_ticket_price": "0", - "id": "5548" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A tiara infused with the properties of Blood.", - "grand_exchange_price": "1058", - "durability": null, - "name": "Blood tiara", - "tradeable": "true", - "weight": "1", + "id": "5548", + "name": "Death tiara", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5549", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1058", - "durability": null, "name": "Blood tiara", - "tradeable": "true", + "examine": "A tiara infused with the properties of Blood.", "archery_ticket_price": "0", - "id": "5550" - }, - { + "durability": null, + "equipment_slot": "0", "ge_buy_limit": "100", - "examine": " A tiara infused with the properties of the soul.", - "durability": null, - "name": "Soul tiara", "tradeable": "true", + "weight": "1" + }, + { + "id": "5550", + "name": "Blood tiara", "archery_ticket_price": "0", - "weight": "1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "5551", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Soul tiara", + "examine": " A tiara infused with the properties of the soul.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5552" + "weight": "1" }, { - "remove_sleeves": "true", - "examine": "Black banded leather armour, a rogue's dream!", - "durability": null, - "name": "Rogue top", - "weight": "0.4", + "id": "5552", + "name": "Soul tiara", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "5553", + "name": "Rogue top", + "examine": "Black banded leather armour, a rogue's dream!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,10,10,10,10,10,5,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "0.4" }, { - "remove_head": "true", - "examine": "Black banded leather armour, a rogue's dream!", - "durability": null, - "name": "Rogue mask", - "weight": "0.5", - "archery_ticket_price": "0", "id": "5554", - "bonuses": "0,0,0,0,0,5,5,5,5,5,0,0,0,0,0", - "remove_beard": "true", - "equipment_slot": "0" - }, - { + "name": "Rogue mask", "examine": "Black banded leather armour, a rogue's dream!", - "durability": null, - "name": "Rogue trousers", - "weight": "0.4", "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,5,5,5,5,5,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "weight": "0.5" + }, + { "id": "5555", + "name": "Rogue trousers", + "examine": "Black banded leather armour, a rogue's dream!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,7,7,7,7,7,0,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "weight": "0.4" }, { - "examine": "Black banded leather gloves, a rogue's dream!", - "durability": null, - "name": "Rogue gloves", - "weight": "0.4", - "archery_ticket_price": "0", "id": "5556", + "name": "Rogue gloves", + "examine": "Black banded leather gloves, a rogue's dream!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,2,2,2,2,2,2,0,0,0,0", - "equipment_slot": "9" + "durability": null, + "equipment_slot": "9", + "weight": "0.4" }, { - "examine": "Black banded leather boots, a rogue's dream!", - "durability": null, - "name": "Rogue boots", - "weight": "0.4", - "archery_ticket_price": "0", "id": "5557", + "name": "Rogue boots", + "examine": "Black banded leather boots, a rogue's dream!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,2,2,2,2,2,0,0,0,0,0", - "equipment_slot": "10" + "durability": null, + "equipment_slot": "10", + "weight": "0.4" }, { - "shop_price": "35", - "examine": "It can do almost anything!", - "durability": null, + "id": "5558", "name": "Rogue kit", + "examine": "It can do almost anything!", "archery_ticket_price": "0", - "id": "5558" + "durability": null, + "shop_price": "35" }, { - "examine": "A small satchel of bright powder!", - "durability": null, + "id": "5559", "name": "Flash powder", - "weight": "1", + "examine": "A small satchel of bright powder!", "archery_ticket_price": "0", - "id": "5559" + "durability": null, + "weight": "1" }, { - "shop_price": "10", - "examine": "A useful hearing aid.", - "durability": null, - "name": "Stethoscope", - "archery_ticket_price": "0", "id": "5560", - "equipment_slot": "5" + "name": "Stethoscope", + "examine": "A useful hearing aid.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "shop_price": "10" }, { - "examine": "I can escape the Maze with this!", - "durability": null, + "id": "5561", "name": "Mystic jewel", + "examine": "I can escape the Maze with this!", "archery_ticket_price": "0", - "id": "5561" + "durability": null }, { - "examine": "A fraction of a roof.", - "durability": null, + "id": "5568", "name": "Picture", - "weight": "0.6", + "examine": "A fraction of a roof.", "archery_ticket_price": "0", - "id": "5568" + "durability": null, + "weight": "0.6" }, { + "id": "5574", + "name": "Initiate sallet", + "examine": "An initiate Temple Knight's helm.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,13,14,11,-1,13,5,0,3,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,20}", "shop_price": "6000", - "ge_buy_limit": "100", - "examine": "An initiate Temple Knight's helm.", - "durability": null, - "weight": "2.2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "3512", - "name": "Initiate sallet", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5574", - "bonuses": "0,0,0,-6,-2,13,14,11,-1,13,5,0,3,0,0" + "weight": "2.2" }, { + "id": "5575", + "name": "Initiate hauberk", + "examine": "An initiate Temple Knight's Armour.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,6,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", "requirements": "{1,20}", "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "An initiate Temple Knight's Armour.", - "durability": null, - "weight": "8", - "absorb": "1,0,3", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "5776", - "name": "Initiate hauberk", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5575", - "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,6,0,0" + "weight": "8" }, { + "id": "5576", + "name": "Initiate cuisse", + "examine": "An initiate Temple Knight's leg armour.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,5,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", "requirements": "{1,20}", "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "An initiate Temple Knight's leg armour.", - "durability": null, - "weight": "7", - "absorb": "1,0,2", - "equipment_slot": "7", - "grand_exchange_price": "4574", - "name": "Initiate cuisse", "tradeable": "true", - "archery_ticket_price": "0", - "id": "5576", - "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,5,0,0" + "weight": "7" }, { - "examine": "A vial of something labelled 'Cupric Sulfate'.", - "durability": null, + "id": "5577", "name": "Cupric sulphate", - "tradeable": "false", - "destroy": "true", + "examine": "A vial of something labelled 'Cupric Sulfate'.", "archery_ticket_price": "0", - "id": "5577" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A vial of something labelled 'Acetic Acid'.", - "durability": null, + "id": "5578", "name": "Acetic acid", - "tradeable": "false", - "destroy": "true", + "examine": "A vial of something labelled 'Acetic Acid'.", "archery_ticket_price": "0", - "id": "5578" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A vial of something labelled 'Gypsum'.", - "durability": null, + "id": "5579", "name": "Gypsum", - "tradeable": "false", - "destroy": "true", + "examine": "A vial of something labelled 'Gypsum'.", "archery_ticket_price": "0", - "id": "5579" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A vial of something labelled 'Sodium Chloride'.", - "durability": null, + "id": "5580", "name": "Sodium chloride", - "tradeable": "false", - "destroy": "true", + "examine": "A vial of something labelled 'Sodium Chloride'.", "archery_ticket_price": "0", - "id": "5580" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A vial of something labelled 'Nitrous Oxide'.", - "durability": null, + "id": "5581", "name": "Nitrous oxide", - "tradeable": "false", - "destroy": "true", + "examine": "A vial of something labelled 'Nitrous Oxide'.", "archery_ticket_price": "0", - "id": "5581" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A vial of something labelled Dihydrogen Monoxide.", - "durability": null, + "id": "5582", "name": "Vial of liquid", + "examine": "A vial of something labelled Dihydrogen Monoxide.", "archery_ticket_price": "0", - "id": "5582" + "durability": null }, { - "examine": "A vial of something labelled 'Powdered Tin Ore'.", - "durability": null, + "id": "5583", "name": "Tin ore powder", - "tradeable": "false", - "destroy": "true", + "examine": "A vial of something labelled 'Powdered Tin Ore'.", "archery_ticket_price": "0", - "id": "5583" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A vial of something labelled 'Powdered Cupric Ore'.", - "durability": null, + "id": "5584", "name": "Cupric ore powder", - "tradeable": "false", + "examine": "A vial of something labelled 'Powdered Cupric Ore'.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "5584" + "durability": null, + "tradeable": "false" }, { - "examine": "It's a metal spade without a handle.", + "id": "5585", + "name": "Bronze Key", + "examine": "I hope the mould was accurate enough...", + "archery_ticket_price": "0", "durability": null, + "weight": "0.01" + }, + { + "id": "5586", "name": "Metal spade", - "weight": "2.5", + "examine": "It's a metal spade with a wooden handle.", "archery_ticket_price": "0", - "id": "5586" + "durability": null, + "weight": "1.814" }, { - "examine": "It's a metal spade without a handle.", - "durability": null, + "id": "5587", "name": "Metal spade", - "weight": "2.5", + "examine": "It's a metal spade without a handle.", "archery_ticket_price": "0", - "id": "5587" + "durability": null, + "weight": "1.814" }, { - "examine": "Looks like a pretty boring read.", - "durability": null, + "id": "5588", "name": "Alchemical notes", + "examine": "Looks like a pretty boring read.", "archery_ticket_price": "0", - "id": "5588" + "durability": null }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5592", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "A tin layered with some stuff from a vial.", "archery_ticket_price": "0", - "id": "5592" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5593", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "It's full of a white lumpy mixture that seems to be hardening.", "archery_ticket_price": "0", - "id": "5593" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5594", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "There is an impression of a key embedded in it.", "archery_ticket_price": "0", - "id": "5594" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5595", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "There is an impression of a key, filled with tin ore.", "archery_ticket_price": "0", - "id": "5595" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5596", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "There is an impression of a key, filled with copper ore.", "archery_ticket_price": "0", - "id": "5596" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5597", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "There is an impression of a key, filled with tin and copper ore.", "archery_ticket_price": "0", - "id": "5597" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5598", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "There is a bronze key surrounded by plaster in this tin.", "archery_ticket_price": "0", - "id": "5598" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5599", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "There is a strange concoction filling this tin.", "archery_ticket_price": "0", - "id": "5599" + "durability": null, + "shop_price": "20", + "tradeable": "false", + "weight": "0.101" }, { - "shop_price": "6", - "examine": "This needs refining.", - "grand_exchange_price": "42", - "durability": null, + "id": "5600", "name": "Tin", - "tradeable": "true", - "weight": "2.25", + "examine": "I could probably pour something into this.", "archery_ticket_price": "0", - "id": "5600" + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" }, { - "shop_price": "14", - "examine": "Good for detailed crafting.", - "grand_exchange_price": "33", - "durability": null, + "id": "5601", "name": "Chisel", - "tradeable": "true", - "weight": "0.4", + "examine": "Good for detailed crafting.", "archery_ticket_price": "0", - "id": "5601" + "durability": null, + "shop_price": "14", + "tradeable": "true", + "weight": "0.4" }, { - "examine": "Useful for crafting items.", - "grand_exchange_price": "237", - "durability": null, + "id": "5602", "name": "Bronze wire", - "tradeable": "true", + "examine": "Useful for crafting items.", "archery_ticket_price": "0", - "id": "5602" + "durability": null, + "tradeable": "true" }, { - "shop_price": "1", - "examine": "For shearing sheep.", - "grand_exchange_price": "41", - "durability": null, + "id": "5603", "name": "Shears", - "tradeable": "true", - "weight": "0.1", + "examine": "For shearing sheep.", "archery_ticket_price": "0", - "id": "5603" - }, - { - "examine": "A very attractive magnet.", "durability": null, - "name": "Magnet", - "archery_ticket_price": "0", - "id": "5604" - }, - { - "shop_price": "25", - "examine": "A dangerous looking knife.", - "grand_exchange_price": "102", - "durability": null, - "name": "Knife", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "5605" - }, - { - "examine": "I can exchange this for one free makeover with the makeover mage.", - "durability": null, - "name": "Makeover voucher", - "weight": "1", - "archery_ticket_price": "0", - "id": "5606" - }, - { - "shop_price": "2", - "examine": "Some wheat heads.", - "grand_exchange_price": "20", - "durability": null, - "name": "Grain", - "tradeable": "true", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "5607", - "equipment_slot": "1" - }, - { - "examine": "A cunning animal.", - "durability": null, - "name": "Fox", - "archery_ticket_price": "0", - "id": "5608", - "equipment_slot": "3" - }, - { - "examine": "Normal: Yep. Definitely a chicken.", - "durability": null, - "name": "Chicken", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "5609", - "equipment_slot": "5" - }, - { - "examine": "There's not much sand left in the top half...", - "durability": null, - "name": "Hourglass", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "5610" - }, - { - "durability": null, - "name": "Initiate sallet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5611" - }, - { - "durability": null, - "name": "Initiate hauberk", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5612" - }, - { - "durability": null, - "name": "Initiate cuisse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5613" - }, - { - "turn90cw_anim": "330", - "walk_anim": "330", - "durability": null, - "turn90ccw_anim": "330", - "turn180_anim": "330", - "render_anim": "191", - "equipment_slot": "3", - "stand_anim": "330", - "name": "Magic carpet", - "run_anim": "330", - "archery_ticket_price": "0", - "id": "5614", - "stand_turn_anim": "330" - }, - { - "examine": "A pot of crushed bearded gorilla monkey bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", - "archery_ticket_price": "0", - "id": "5615" - }, - { - "shop_price": "7", - "ge_buy_limit": "10000", - "examine": "Arrows with bronze heads.", - "grand_exchange_price": "127", - "durability": null, - "name": "Bronze arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5616", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" - }, - { - "shop_price": "20", - "ge_buy_limit": "10000", - "examine": "Arrows with iron heads.", - "grand_exchange_price": "138", - "durability": null, - "name": "Iron arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5617", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "requirements": "{4,5}", - "shop_price": "46", - "ge_buy_limit": "10000", - "examine": "Arrows with steel heads.", - "grand_exchange_price": "159", - "durability": null, - "name": "Steel arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5618", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { - "requirements": "{4,20}", - "shop_price": "76", - "ge_buy_limit": "10000", - "examine": "Arrows with mithril heads.", - "grand_exchange_price": "176", - "durability": null, - "name": "Mithril arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5619", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" - }, - { - "requirements": "{4,30}", - "shop_price": "172", - "ge_buy_limit": "10000", - "examine": "Arrows with adamantite heads.", - "grand_exchange_price": "211", - "durability": null, - "name": "Adamant arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5620", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" - }, - { - "requirements": "{4,40}", - "shop_price": "510", - "ge_buy_limit": "10000", - "examine": "Arrows with rune heads.", - "grand_exchange_price": "415", - "durability": null, - "name": "Rune arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5621", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { - "shop_price": "7", - "ge_buy_limit": "10000", - "examine": "Arrows with bronze heads.", - "grand_exchange_price": "1076", - "durability": null, - "name": "Bronze arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5622", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" - }, - { - "shop_price": "20", - "ge_buy_limit": "10000", - "examine": "Arrows with iron heads.", - "grand_exchange_price": "1037", - "durability": null, - "name": "Iron arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5623", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "requirements": "{4,5}", - "shop_price": "46", - "ge_buy_limit": "10000", - "examine": "Arrows with steel heads.", - "grand_exchange_price": "1038", - "durability": null, - "name": "Steel arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5624", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { - "requirements": "{4,20}", - "shop_price": "76", - "ge_buy_limit": "10000", - "examine": "Arrows with mithril heads.", - "grand_exchange_price": "718", - "durability": null, - "name": "Mithril arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5625", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" - }, - { - "requirements": "{4,30}", - "shop_price": "172", - "ge_buy_limit": "10000", - "examine": "Arrows with adamantite heads.", - "grand_exchange_price": "101", - "durability": null, - "name": "Adamant arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5626", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" - }, - { - "requirements": "{4,40}", - "shop_price": "510", - "ge_buy_limit": "10000", - "examine": "Arrows with rune heads.", - "grand_exchange_price": "1300", - "durability": null, - "name": "Rune arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5627", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a bronze tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "162", - "attack_audios": "2547,0,0,0", - "name": "Bronze dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5628", - "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" - }, - { - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with an iron tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "164", - "attack_audios": "2547,0,0,0", - "name": "Iron dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5629", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { - "requirements": "{4,5}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a steel tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "173", - "attack_audios": "2547,0,0,0", - "name": "Steel dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5630", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" - }, - { - "requirements": "{4,10}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a black tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "822", - "attack_audios": "2547,0,0,0", - "name": "Black dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5631", - "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a mithril tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "196", - "attack_audios": "2547,0,0,0", - "name": "Mithril dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5632", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with an adamantite tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "244", - "attack_audios": "2547,0,0,0", - "name": "Adamant dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5633", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a rune tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "370", - "attack_audios": "2547,0,0,0", - "name": "Rune dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5634", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a bronze tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "1733", - "attack_audios": "2547,0,0,0", - "name": "Bronze dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5635", - "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" - }, - { - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with an iron tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "1687", - "attack_audios": "2547,0,0,0", - "name": "Iron dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5636", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { - "requirements": "{4,5}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a steel tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "1654", - "attack_audios": "2547,0,0,0", - "name": "Steel dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5637", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" - }, - { - "requirements": "{4,10}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a black tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "2422", - "attack_audios": "2547,0,0,0", - "name": "Black dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5638", - "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a mithril tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "1660", - "attack_audios": "2547,0,0,0", - "name": "Mithril dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5639", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with an adamantite tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "1352", - "attack_audios": "2547,0,0,0", - "name": "Adamant dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5640", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "1000", - "examine": "A deadly throwing dart with a rune tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "582,582,582,582", - "grand_exchange_price": "1109", - "attack_audios": "2547,0,0,0", - "name": "Rune dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5641", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "shop_price": "6", - "ge_buy_limit": "1000", - "examine": "A bronze-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "115", - "name": "Bronze javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5642", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" - }, - { - "shop_price": "8", - "ge_buy_limit": "1000", - "examine": "An iron-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "112", - "name": "Iron javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5643", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,5}", - "shop_price": "37", - "ge_buy_limit": "1000", - "examine": "A steel-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "128", - "name": "Steel javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5644", - "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" - }, - { - "requirements": "{4,20}", - "shop_price": "79", - "ge_buy_limit": "1000", - "examine": "A mithril tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "141", - "name": "Mithril javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5645", - "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "100", - "shop_price": "100", - "examine": "An adamant tipped javelin.", - "durability": null, - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "179", - "name": "Adamant javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5646", - "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" - }, - { - "shop_price": "624", - "ge_buy_limit": "1000", - "examine": "A rune tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "302", - "name": "Rune javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5647", - "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "A bronze-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1755", - "name": "Bronze jav'n(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5648", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" - }, - { - "shop_price": "8", - "ge_buy_limit": "1000", - "examine": "An iron-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1756", - "name": "Iron javelin(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5649", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,5}", - "shop_price": "37", - "ge_buy_limit": "1000", - "examine": "A steel-tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1769", - "name": "Steel javelin(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5650", - "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" - }, - { - "requirements": "{4,20}", - "shop_price": "79", - "ge_buy_limit": "1000", - "examine": "A mithril tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1736", - "name": "Mithril javelin(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5651", - "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "100", - "shop_price": "100", - "examine": "An adamant tipped javelin.", - "durability": null, - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1514", - "name": "Adamant javelin(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5652", - "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" - }, - { - "requirements": "{4,40}", - "shop_price": "624", - "ge_buy_limit": "1000", - "examine": "A rune tipped javelin.", - "durability": null, - "attack_speed": "6", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1521", - "name": "Rune javelin(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5653", - "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" - }, - { - "shop_price": "14", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "164", - "attack_audios": "2704,0,0,0", - "name": "Bronze knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5654", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { - "shop_price": "58", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "170", - "attack_audios": "2704,0,0,0", - "name": "Iron knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5655", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" - }, - { - "requirements": "{4,5}", - "shop_price": "68", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "212", - "attack_audios": "2704,0,0,0", - "name": "Steel knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5656", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "100", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "330", - "attack_audios": "2704,0,0,0", - "name": "Mithril knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5657", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,10}", - "shop_price": "15", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "66", - "attack_audios": "2704,0,0,0", - "name": "Black knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5658", - "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "609", - "attack_audios": "2704,0,0,0", - "name": "Adamant knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5659", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1511", - "attack_audios": "2704,0,0,0", - "name": "Rune knife(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5660", - "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" - }, - { - "shop_price": "14", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1514", - "attack_audios": "2704,0,0,0", - "name": "Bronze knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5661", - "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" - }, - { - "shop_price": "58", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1212", - "attack_audios": "2704,0,0,0", - "name": "Iron knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5662", - "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" - }, - { - "requirements": "{4,5}", - "shop_price": "68", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1579", - "attack_audios": "2704,0,0,0", - "name": "Steel knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5663", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "100", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1368", - "attack_audios": "2704,0,0,0", - "name": "Mithril knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5664", - "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" - }, - { - "requirements": "{4,10}", - "shop_price": "15", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "103", - "attack_audios": "2704,0,0,0", - "name": "Black knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5665", - "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" - }, - { - "requirements": "{4,30}", - "ge_buy_limit": "100", - "examine": "A finely balanced throwing knife.", - "durability": null, - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "1505", - "attack_audios": "2704,0,0,0", - "name": "Adamant knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5666", - "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "10000", - "examine": "A finely balanced throwing knife.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "806,806,806,806", - "grand_exchange_price": "2207", - "attack_audios": "2704,0,0,0", - "name": "Rune knife(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5667", - "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" - }, - { - "shop_price": "38", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "483", - "attack_audios": "2517,2517,2500,2517", - "name": "Iron dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5668", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "483", - "durability": null, - "name": "Iron dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5669" - }, - { - "shop_price": "11", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "350", - "attack_audios": "2517,2517,2500,2517", - "name": "Bronze dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5670", - "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "350", - "durability": null, - "name": "Bronze dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5671" - }, - { - "requirements": "{0,5}", - "shop_price": "135", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "575", - "attack_audios": "2517,2517,2500,2517", - "name": "Steel dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5672", - "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "575", - "durability": null, - "name": "Steel dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5673" - }, - { - "requirements": "{0,20}", - "shop_price": "130", - "ge_buy_limit": "100", - "examine": "A dangerous dagger.", - "durability": null, - "weight": "0.3", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "538", - "attack_audios": "2517,2517,2500,2517", - "name": "Mithril dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5674", - "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "538", - "durability": null, - "name": "Mithril dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5675" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "durability": null, - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "800", - "attack_audios": "2517,2517,2500,2517", - "name": "Adamant dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5676", - "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "800", - "durability": null, - "name": "Adamant dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5677" - }, - { - "requirements": "{0,40}", - "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "lendable": "true", - "grand_exchange_price": "4538", - "attack_audios": "2517,2517,2500,2517", - "name": "Rune dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5678", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4538", - "durability": null, - "name": "Rune dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5679" - }, - { - "requirements": "{0,60}", - "shop_price": "60000", - "ge_buy_limit": "10", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "396,396,395,396", - "lendable": "true", - "grand_exchange_price": "16800", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5680", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "attack_anims": "396,396,395,396", - "ge_buy_limit": "10", - "grand_exchange_price": "16800", - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Dragon dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5681", - "defence_anim": "397" - }, - { - "requirements": "{0,10}", - "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious black dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "664", - "attack_audios": "2517,2517,2500,2517", - "name": "Black dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5682", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "664", - "durability": null, - "name": "Black dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5683" - }, - { - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Poison dagger(p+)", - "archery_ticket_price": "0", - "id": "5684", - "weapon_interface": "5", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", - "render_anim": "2584", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Poison dagger(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5685" - }, - { - "shop_price": "38", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "4128", - "attack_audios": "2517,2517,2500,2517", - "name": "Iron dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5686", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4128", - "durability": null, - "name": "Iron dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5687" - }, - { - "shop_price": "11", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "5088", - "attack_audios": "2517,2517,2500,2517", - "name": "Br'ze dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5688", - "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5088", - "durability": null, - "name": "Br'ze dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5689" - }, - { - "requirements": "{0,5}", - "shop_price": "135", - "ge_buy_limit": "100", - "examine": "Short but pointy.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "4729", - "attack_audios": "2517,2517,2500,2517", - "name": "Steel dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5690", - "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4729", - "durability": null, - "name": "Steel dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5691" - }, - { - "requirements": "{0,20}", - "shop_price": "130", - "ge_buy_limit": "100", - "examine": "A dangerous dagger.", - "durability": null, - "weight": "0.3", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "3476", - "attack_audios": "2517,2517,2500,2517", - "name": "Mithril dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5692", - "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3476", - "durability": null, - "name": "Mithril dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5693" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "durability": null, - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "4612", - "attack_audios": "2517,2517,2500,2517", - "name": "Adamant dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5694", - "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4612", - "durability": null, - "name": "Adamant dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5695" - }, - { - "requirements": "{0,40}", - "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "lendable": "true", - "grand_exchange_price": "5061", - "attack_audios": "2517,2517,2500,2517", - "name": "Rune dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5696", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5061", - "durability": null, - "name": "Rune dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5697" - }, - { - "requirements": "{0,60}", - "shop_price": "60000", - "ge_buy_limit": "10", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "396,396,395,396", - "lendable": "true", - "grand_exchange_price": "20300", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5698", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "attack_anims": "396,396,395,396", - "ge_buy_limit": "10", - "grand_exchange_price": "20300", - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Dragon dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5699", - "defence_anim": "397" - }, - { - "requirements": "{0,10}", - "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious black dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "4921", - "attack_audios": "2517,2517,2500,2517", - "name": "Black dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5700", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4921", - "durability": null, - "name": "Black dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5701" - }, - { - "attack_audios": "2517,2517,2500,2517", - "durability": null, - "name": "Poison dagger(p++)", - "archery_ticket_price": "0", - "id": "5702", - "weapon_interface": "5", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", - "render_anim": "2584", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Poison dagger(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5703" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "861", - "stand_anim": "813", - "name": "Bronze spear(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5704", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "861", - "durability": null, - "name": "Bronze spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5705" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "676", - "stand_anim": "813", - "name": "Iron spear(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5706", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "676", - "durability": null, - "name": "Iron spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5707" - }, - { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "596", - "stand_anim": "813", - "tradeable": "true", - "name": "Steel spear(p+)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5708", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "596", - "durability": null, - "name": "Steel spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5709" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "802", - "stand_anim": "813", - "tradeable": "true", - "name": "Mithril spear(p+)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5710", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "802", - "durability": null, - "name": "Mithril spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5711" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "1394", - "stand_anim": "813", - "tradeable": "true", - "name": "Adamant spear(p+)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5712", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1394", - "durability": null, - "name": "Adamant spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5713" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "lendable": "true", - "grand_exchange_price": "12500", - "stand_anim": "813", - "tradeable": "true", - "name": "Rune spear(p+)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5714", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12500", - "durability": null, - "name": "Rune spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5715" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "A dragon tipped spear.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "41800", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5716", - "stand_turn_anim": "1209", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", - "requirements": "{0,60}", - "durability": null, - "weight": "2", - "weapon_interface": "14", - "render_anim": "28", - "lendable": "true", - "name": "Dragon spear(p+)" - }, - { - "attack_anims": "2080,2081,2082,2080", - "ge_buy_limit": "10", - "grand_exchange_price": "41800", - "durability": null, - "name": "Dragon spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5717", - "defence_anim": "2079" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "7557", - "stand_anim": "813", - "name": "Bronze spear(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5718", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7557", - "durability": null, - "name": "Bronze spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5719" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "8394", - "stand_anim": "813", - "name": "Iron spear(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5720", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8394", - "durability": null, - "name": "Iron spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5721" - }, - { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "8336", - "stand_anim": "813", - "tradeable": "true", - "name": "Steel spear(p++)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5722", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8336", - "durability": null, - "name": "Steel spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5723" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "7035", - "stand_anim": "813", - "tradeable": "true", - "name": "Mithril spear(p++)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5724", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7035", - "durability": null, - "name": "Mithril spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5725" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant tipped spear.", - "walk_anim": "1205", - "durability": null, - "turn90ccw_anim": "1208", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "7530", - "stand_anim": "813", - "name": "Adamant spear(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5726", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7530", - "durability": null, - "name": "Adamant spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5727" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "lendable": "true", - "grand_exchange_price": "17700", - "stand_anim": "813", - "tradeable": "true", - "name": "Rune spear(p++)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5728", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "17700", - "durability": null, - "name": "Rune spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5729" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "A dragon tipped spear.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "37800", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5730", - "stand_turn_anim": "1209", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", - "requirements": "{0,60}", - "durability": null, - "weight": "2", - "weapon_interface": "14", - "render_anim": "28", - "lendable": "true", - "name": "Dragon spear(p++)" - }, - { - "attack_anims": "2080,2081,2082,2080", - "ge_buy_limit": "10", - "grand_exchange_price": "37800", - "durability": null, - "name": "Dragon spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5731", - "defence_anim": "2079" - }, - { - "durability": null, - "name": "Stool", - "archery_ticket_price": "0", - "id": "5732", - "equipment_slot": "5" - }, - { - "examine": "Yuk!", - "durability": null, - "name": "Rotten potato", - "archery_ticket_price": "0", - "id": "5733" - }, - { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A black tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "3351", - "stand_anim": "813", - "tradeable": "true", - "name": "Black spear(p+)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5734", - "stand_turn_anim": "1209", - "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3351", - "durability": null, - "name": "Black spear(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5735" - }, - { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A black tipped spear.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "9065", - "stand_anim": "813", - "tradeable": "true", - "name": "Black spear(p++)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "5736", - "stand_turn_anim": "1209", - "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9065", - "durability": null, - "name": "Black spear(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5737" - }, - { - "shop_price": "15", - "examine": "A slightly bluish leaf.", - "grand_exchange_price": "19", - "durability": null, - "name": "Woad leaf", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5738" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Asgarnian ale.", - "grand_exchange_price": "459", - "durability": null, - "name": "Asgarnian ale(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5739" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "459", - "durability": null, - "name": "Asgarnian ale(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5740" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", - "grand_exchange_price": "1193", - "durability": null, - "name": "Mature wmb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5741" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1193", - "durability": null, - "name": "Mature wmb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5742" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Greenman's Ale.", - "grand_exchange_price": "65400", - "durability": null, - "name": "Greenman's ale(m)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "5743" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "65400", - "durability": null, - "name": "Greenman's ale(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5744" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Dragon Bitter.", - "grand_exchange_price": "2458", - "durability": null, - "name": "Dragon bitter(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5745" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2458", - "durability": null, - "name": "Dragon bitter(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5746" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal dwarven stout.", - "grand_exchange_price": "56400", - "durability": null, - "name": "Dwarven stout(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5747" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "56400", - "durability": null, - "name": "Dwarven stout(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5748" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Moonlight Mead.", - "grand_exchange_price": "19", - "durability": null, - "name": "Moonlight mead(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5749" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, - "name": "Moonlight mead(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5750" - }, - { - "ge_buy_limit": "100", - "examine": "This might help me chop harder.", - "grand_exchange_price": "890", - "durability": null, - "name": "Axeman's folly", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5751" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "890", - "durability": null, - "name": "Axeman's folly", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5752" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than a normal Axeman's Folly.", - "grand_exchange_price": "26000", - "durability": null, - "name": "Axeman's folly(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5753" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "26000", - "durability": null, - "name": "Axeman's folly(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5754" - }, - { - "ge_buy_limit": "100", - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "3694", - "durability": null, - "name": "Chef's delight", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5755" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3694", - "durability": null, - "name": "Chef's delight", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5756" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Chef's Delight.", - "grand_exchange_price": "42800", - "durability": null, - "name": "Chef's delight(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5757" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "42800", - "durability": null, - "name": "Chef's delight(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5758" - }, - { - "ge_buy_limit": "100", - "examine": "Ale with bite.", - "grand_exchange_price": "7", - "durability": null, - "name": "Slayer's respite", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5759" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7", - "durability": null, - "name": "Slayer's respite", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5760" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Slayer's Respite.", - "grand_exchange_price": "1748", - "durability": null, - "name": "Slayer's respite(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5761" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1748", - "durability": null, - "name": "Slayer's respite(m)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5762" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of Cider", - "grand_exchange_price": "1279", - "durability": null, - "name": "Cider", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5763" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1279", - "durability": null, - "name": "Cider", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5764" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal cider.", - "grand_exchange_price": "3614", - "durability": null, - "name": "Mature cider", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5765" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3614", - "durability": null, - "name": "Mature cider", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5766" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A pot filled with ale yeast.", - "grand_exchange_price": "59", - "durability": null, - "name": "Ale yeast", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "5767" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "59", - "durability": null, - "name": "Ale yeast", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5768" - }, - { - "ge_buy_limit": "100", - "examine": "Sliced and hollowed out to form a keg.", - "grand_exchange_price": "8", - "durability": null, - "name": "Calquat keg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5769" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, - "name": "Calquat keg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5770" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A pint of thick dark beer.", - "grand_exchange_price": "1934", - "durability": null, - "name": "Dwarven stout(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5771" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1934", - "durability": null, - "name": "Dwarven stout(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5772" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A pint of thick dark beer.", - "grand_exchange_price": "3214", - "durability": null, - "name": "Dwarven stout(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5773" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3214", - "durability": null, - "name": "Dwarven stout(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5774" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A pint of thick dark beer.", - "grand_exchange_price": "4886", - "durability": null, - "name": "Dwarven stout(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5775" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4886", - "durability": null, - "name": "Dwarven stout(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5776" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "A pint of thick dark beer.", - "grand_exchange_price": "5159", - "durability": null, - "name": "Dwarven stout(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5777" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5159", - "durability": null, - "name": "Dwarven stout(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5778" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "3344", - "durability": null, - "name": "Asgarnian ale(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5779" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3344", - "durability": null, - "name": "Asgarnian ale(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5780" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "6103", - "durability": null, - "name": "Asgarnian ale(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5781" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6103", - "durability": null, - "name": "Asgarnian ale(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5782" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "9230", - "durability": null, - "name": "Asgarnian ale(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5783" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9230", - "durability": null, - "name": "Asgarnian ale(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5784" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "12900", - "durability": null, - "name": "Asgarnian ale(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5785" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12900", - "durability": null, - "name": "Asgarnian ale(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5786" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "3441", - "durability": null, - "name": "Greenmans ale(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5787" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3441", - "durability": null, - "name": "Greenmans ale(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5788" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "4670", - "durability": null, - "name": "Greenmans ale(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5789" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4670", - "durability": null, - "name": "Greenmans ale(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5790" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "7654", - "durability": null, - "name": "Greenmans ale(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5791" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7654", - "durability": null, - "name": "Greenmans ale(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5792" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "6317", - "durability": null, - "name": "Greenmans ale(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5793" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6317", - "durability": null, - "name": "Greenmans ale(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5794" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "It's got strange bubbles in it.", - "grand_exchange_price": "1495", - "durability": null, - "name": "Mind bomb(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5795" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1495", - "durability": null, - "name": "Mind bomb(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5796" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "It's got strange bubbles in it.", - "grand_exchange_price": "2721", - "durability": null, - "name": "Mind bomb(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5797" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2721", - "durability": null, - "name": "Mind bomb(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5798" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "It's got strange bubbles in it.", - "grand_exchange_price": "4038", - "durability": null, - "name": "Mind bomb(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5799" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4038", - "durability": null, - "name": "Mind bomb(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5800" - }, - { - "shop_price": "3", - "ge_buy_limit": "100", - "examine": "It's got strange bubbles in it.", - "grand_exchange_price": "5166", - "durability": null, - "name": "Mind bomb(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5801" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5166", - "durability": null, - "name": "Mind bomb(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5802" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of bitter.", - "grand_exchange_price": "1673", - "durability": null, - "name": "Dragon bitter(1)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5803" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1673", - "durability": null, - "name": "Dragon bitter(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5804" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of bitter.", - "grand_exchange_price": "3259", - "durability": null, - "name": "Dragon bitter(2)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5805" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3259", - "durability": null, - "name": "Dragon bitter(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5806" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of bitter.", - "grand_exchange_price": "4845", - "durability": null, - "name": "Dragon bitter(3)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5807" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4845", - "durability": null, - "name": "Dragon bitter(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5808" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of bitter.", - "grand_exchange_price": "5924", - "durability": null, - "name": "Dragon bitter(4)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5809" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5924", - "durability": null, - "name": "Dragon bitter(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5810" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A foul smelling brew.", - "grand_exchange_price": "1298", - "durability": null, - "name": "Moonlight mead(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5811" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1298", - "durability": null, - "name": "Moonlight mead(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5812" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A foul smelling brew.", - "grand_exchange_price": "2510", - "durability": null, - "name": "Moonlight mead(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5813" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2510", - "durability": null, - "name": "Moonlight mead(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5814" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A foul smelling brew.", - "grand_exchange_price": "3721", - "durability": null, - "name": "Moonlight mead(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5815" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3721", - "durability": null, - "name": "Moonlight mead(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5816" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A foul smelling brew.", - "grand_exchange_price": "4883", - "durability": null, - "name": "Moonlight mead(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5817" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4883", - "durability": null, - "name": "Moonlight mead(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5818" - }, - { - "ge_buy_limit": "100", - "examine": "This might help me chop harder.", - "grand_exchange_price": "3333", - "durability": null, - "name": "Axeman's folly(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5819" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3333", - "durability": null, - "name": "Axeman's folly(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5820" - }, - { - "ge_buy_limit": "100", - "examine": "This might help me chop harder.", - "grand_exchange_price": "6093", - "durability": null, - "name": "Axeman's folly(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5821" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6093", - "durability": null, - "name": "Axeman's folly(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5822" - }, - { - "ge_buy_limit": "100", - "examine": "This might help me chop harder.", - "grand_exchange_price": "8978", - "durability": null, - "name": "Axeman's folly(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5823" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8978", - "durability": null, - "name": "Axeman's folly(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5824" - }, - { - "ge_buy_limit": "100", - "examine": "This might help me chop harder.", - "grand_exchange_price": "9212", - "durability": null, - "name": "Axeman's folly(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5825" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9212", - "durability": null, - "name": "Axeman's folly(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5826" - }, - { - "ge_buy_limit": "100", - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "3851", - "durability": null, - "name": "Chef's delight(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5827" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3851", - "durability": null, - "name": "Chef's delight(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5828" - }, - { - "ge_buy_limit": "100", - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "6589", - "durability": null, - "name": "Chef's delight(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5829" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6589", - "durability": null, - "name": "Chef's delight(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5830" - }, - { - "ge_buy_limit": "100", - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "9536", - "durability": null, - "name": "Chef's delight(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5831" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9536", - "durability": null, - "name": "Chef's delight(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5832" - }, - { - "ge_buy_limit": "100", - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "13200", - "durability": null, - "name": "Chef's delight(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5833" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "13200", - "durability": null, - "name": "Chef's delight(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5834" - }, - { - "ge_buy_limit": "100", - "examine": "Ale with bite.", - "grand_exchange_price": "1127", - "durability": null, - "name": "Slayer's respite(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5835" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1127", - "durability": null, - "name": "Slayer's respite(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5836" - }, - { - "ge_buy_limit": "100", - "examine": "Ale with bite.", - "grand_exchange_price": "2168", - "durability": null, - "name": "Slayer's respite(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5837" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2168", - "durability": null, - "name": "Slayer's respite(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5838" - }, - { - "ge_buy_limit": "100", - "examine": "Ale with bite.", - "grand_exchange_price": "3209", - "durability": null, - "name": "Slayer's respite(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5839" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3209", - "durability": null, - "name": "Slayer's respite(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5840" - }, - { - "ge_buy_limit": "100", - "examine": "Ale with bite.", - "grand_exchange_price": "3582", - "durability": null, - "name": "Slayer's respite(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5841" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3582", - "durability": null, - "name": "Slayer's respite(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5842" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of Cider", - "grand_exchange_price": "6040", - "durability": null, - "name": "Cider(1)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5843" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6040", - "durability": null, - "name": "Cider(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5844" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of Cider", - "grand_exchange_price": "11000", - "durability": null, - "name": "Cider(2)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5845" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11000", - "durability": null, - "name": "Cider(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5846" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of Cider", - "grand_exchange_price": "15400", - "durability": null, - "name": "Cider(3)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5847" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "15400", - "durability": null, - "name": "Cider(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5848" - }, - { - "shop_price": "2", - "ge_buy_limit": "100", - "examine": "A glass of Cider", - "grand_exchange_price": "18900", - "durability": null, - "name": "Cider(4)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5849" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "18900", - "durability": null, - "name": "Cider(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5850" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal dwarven stout.", - "grand_exchange_price": "44600", - "durability": null, - "name": "Dwarven stout(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5851" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "44600", - "durability": null, - "name": "Dwarven stout(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5852" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal dwarven stout.", - "grand_exchange_price": "68900", - "durability": null, - "name": "Dwarven stout(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5853" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "68900", - "durability": null, - "name": "Dwarven stout(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5854" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal dwarven stout.", - "grand_exchange_price": "98800", - "durability": null, - "name": "Dwarven stout(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5855" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "98800", - "durability": null, - "name": "Dwarven stout(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5856" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal dwarven stout.", - "grand_exchange_price": "237400", - "durability": null, - "name": "Dwarven stout(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5857" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "237400", - "durability": null, - "name": "Dwarven stout(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5858" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Asgarnian ale.", - "grand_exchange_price": "1697", - "durability": null, - "name": "Asgarnian ale(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5859" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1697", - "durability": null, - "name": "Asgarnian ale(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5860" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Asgarnian ale.", - "grand_exchange_price": "3307", - "durability": null, - "name": "Asgarnian ale(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5861" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3307", - "durability": null, - "name": "Asgarnian ale(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5862" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Asgarnian ale.", - "grand_exchange_price": "4917", - "durability": null, - "name": "Asgarnian ale(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5863" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4917", - "durability": null, - "name": "Asgarnian ale(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5864" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Asgarnian ale.", - "grand_exchange_price": "6778", - "durability": null, - "name": "Asgarnian ale(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5865" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6778", - "durability": null, - "name": "Asgarnian ale(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5866" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Greenman's Ale.", - "grand_exchange_price": "57600", - "durability": null, - "name": "Greenmans ale(m1)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "5867" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "57600", - "durability": null, - "name": "Greenmans ale(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5868" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Greenman's Ale.", - "grand_exchange_price": "92000", - "durability": null, - "name": "Greenmans ale(m2)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "5869" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "92000", - "durability": null, - "name": "Greenmans ale(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5870" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Greenman's Ale.", - "grand_exchange_price": "136700", - "durability": null, - "name": "Greenmans ale(m3)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "5871" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "136700", - "durability": null, - "name": "Greenmans ale(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5872" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Greenman's Ale.", - "grand_exchange_price": "231700", - "durability": null, - "name": "Greenmans ale(m4)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "5873" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "231700", - "durability": null, - "name": "Greenmans ale(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5874" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", - "grand_exchange_price": "3032", - "durability": null, - "name": "Mind bomb(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5875" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3032", - "durability": null, - "name": "Mind bomb(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5876" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", - "grand_exchange_price": "5977", - "durability": null, - "name": "Mind bomb(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5877" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5977", - "durability": null, - "name": "Mind bomb(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5878" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", - "grand_exchange_price": "8922", - "durability": null, - "name": "Mind bomb(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5879" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8922", - "durability": null, - "name": "Mind bomb(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5880" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", - "grand_exchange_price": "12700", - "durability": null, - "name": "Mind bomb(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5881" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12700", - "durability": null, - "name": "Mind bomb(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5882" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Dragon Bitter.", - "grand_exchange_price": "2125", - "durability": null, - "name": "Dragon bitter(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5883" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2125", - "durability": null, - "name": "Dragon bitter(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5884" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Dragon Bitter.", - "grand_exchange_price": "4163", - "durability": null, - "name": "Dragon bitter(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5885" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4163", - "durability": null, - "name": "Dragon bitter(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5886" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Dragon Bitter.", - "grand_exchange_price": "6201", - "durability": null, - "name": "Dragon bitter(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5887" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6201", - "durability": null, - "name": "Dragon bitter(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5888" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Dragon Bitter.", - "grand_exchange_price": "8834", - "durability": null, - "name": "Dragon bitter(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5889" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8834", - "durability": null, - "name": "Dragon bitter(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5890" - }, - { - "shop_price": "5", - "ge_buy_limit": "100", - "examine": "A foul smelling brew.", - "grand_exchange_price": "1315", - "durability": null, - "name": "M'light mead(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5891" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1315", - "durability": null, - "name": "M'light mead(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5892" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Moonlight Mead.", - "grand_exchange_price": "2543", - "durability": null, - "name": "M'light mead(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5893" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2543", - "durability": null, - "name": "M'light mead(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5894" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Moonlight Mead.", - "grand_exchange_price": "3771", - "durability": null, - "name": "M'light mead(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5895" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3771", - "durability": null, - "name": "M'light mead(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5896" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Moonlight Mead.", - "grand_exchange_price": "5000", - "durability": null, - "name": "M'light mead(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5897" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5000", - "durability": null, - "name": "M'light mead(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5898" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than a normal Axeman's Folly.", - "grand_exchange_price": "13500", - "durability": null, - "name": "Axeman's folly(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5899" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "13500", - "durability": null, - "name": "Axeman's folly(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5900" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than a normal Axeman's Folly.", - "grand_exchange_price": "24800", - "durability": null, - "name": "Axeman's folly(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5901" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "24800", - "durability": null, - "name": "Axeman's folly(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5902" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than a normal Axeman's Folly.", - "grand_exchange_price": "37300", - "durability": null, - "name": "Axeman's folly(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5903" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "37300", - "durability": null, - "name": "Axeman's folly(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5904" - }, - { - "ge_buy_limit": "100", - "examine": "This might help me chop harder.", - "grand_exchange_price": "60700", - "durability": null, - "name": "Axeman's folly(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5905" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "60700", - "durability": null, - "name": "Axeman's folly(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5906" - }, - { - "ge_buy_limit": "100", - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "18000", - "durability": null, - "name": "Chef's delight(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5907" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "18000", - "durability": null, - "name": "Chef's delight(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5908" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Chef's Delight.", - "grand_exchange_price": "34300", - "durability": null, - "name": "Chef's delight(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5909" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "34300", - "durability": null, - "name": "Chef's delight(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5910" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Chef's Delight.", - "grand_exchange_price": "51000", - "durability": null, - "name": "Chef's delight(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5911" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "51000", - "durability": null, - "name": "Chef's delight(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5912" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Chef's Delight.", - "grand_exchange_price": "98600", - "durability": null, - "name": "Chef's delight(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5913" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "98600", - "durability": null, - "name": "Chef's delight(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5914" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Slayer's Respite.", - "grand_exchange_price": "3672", - "durability": null, - "name": "Slayer respite(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5915" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3672", - "durability": null, - "name": "Slayer respite(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5916" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Slayer's Respite.", - "grand_exchange_price": "7258", - "durability": null, - "name": "Slayer respite(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5917" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7258", - "durability": null, - "name": "Slayer respite(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5918" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Slayer's Respite.", - "grand_exchange_price": "10800", - "durability": null, - "name": "Slayer respite(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5919" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10800", - "durability": null, - "name": "Slayer respite(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5920" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal Slayer's Respite.", - "grand_exchange_price": "15300", - "durability": null, - "name": "Slayer respite(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5921" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "15300", - "durability": null, - "name": "Slayer respite(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5922" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal cider.", - "grand_exchange_price": "2966", - "durability": null, - "name": "Cider(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5923" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2966", - "durability": null, - "name": "Cider(m1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5924" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal cider.", - "grand_exchange_price": "5845", - "durability": null, - "name": "Cider(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5925" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5845", - "durability": null, - "name": "Cider(m2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5926" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal cider.", - "grand_exchange_price": "8724", - "durability": null, - "name": "Cider(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5927" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8724", - "durability": null, - "name": "Cider(m3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5928" - }, - { - "ge_buy_limit": "100", - "examine": "This looks a good deal stronger than normal cider.", - "grand_exchange_price": "11900", - "durability": null, - "name": "Cider(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5929" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11900", - "durability": null, - "name": "Cider(m4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5930" - }, - { - "ge_buy_limit": "5000", - "examine": "I can weave this to make sacks.", - "grand_exchange_price": "532", - "durability": null, - "name": "Jute fibre", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "5931" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "532", - "durability": null, - "name": "Jute fibre", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5932" - }, - { - "ge_buy_limit": "200", - "examine": "A branch from a willow tree.", - "grand_exchange_price": "1255", - "durability": null, - "name": "Willow branch", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "5933" - }, - { - "ge_buy_limit": "200", - "grand_exchange_price": "1255", - "durability": null, - "name": "Willow branch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5934" - }, - { - "ge_buy_limit": "10000", - "examine": "A vial filled with coconut milk.", - "grand_exchange_price": "1307", - "durability": null, - "name": "Coconut milk", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5935" - }, - { - "ge_buy_limit": "1000", - "examine": "A vial of extra-strong weapon poison, for spears and daggers.", - "grand_exchange_price": "605", - "durability": null, - "name": "Weapon poison+", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5937" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "605", - "durability": null, - "name": "Weapon poison+", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5938" - }, - { - "ge_buy_limit": "1000", - "examine": "A vial of super strong weapon poison, for spears and daggers.", - "grand_exchange_price": "4817", - "durability": null, - "name": "Weapon poison++", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "5940" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "4817", - "durability": null, - "name": "Weapon poison++", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5941" - }, - { - "ge_buy_limit": "1000", - "examine": "N doses of extra-stong antipoison potion", - "grand_exchange_price": "1032", - "durability": null, - "name": "Antipoison+(4)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5943" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1032", - "durability": null, - "name": "Antipoison+(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5944" - }, - { - "ge_buy_limit": "1000", - "examine": "N doses of extra-stong antipoison potion", - "grand_exchange_price": "1499", - "durability": null, - "name": "Antipoison+(3)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5945" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1499", - "durability": null, - "name": "Antipoison+(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5946" - }, - { - "ge_buy_limit": "1000", - "examine": "N doses of extra-stong antipoison potion", - "grand_exchange_price": "1316", - "durability": null, - "name": "Antipoison+(2)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5947" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1316", - "durability": null, - "name": "Antipoison+(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5948" - }, - { - "ge_buy_limit": "1000", - "examine": "N doses of extra-stong antipoison potion", - "grand_exchange_price": "1599", - "durability": null, - "name": "Antipoison+(1)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5949" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1599", - "durability": null, - "name": "Antipoison+(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5950" - }, - { - "ge_buy_limit": "1000", - "examine": "4 doses of a super-strong antipoison potion.", - "grand_exchange_price": "1138", - "durability": null, - "name": "Antipoison++(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5952" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1138", - "durability": null, - "name": "Antipoison++(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5953" - }, - { - "ge_buy_limit": "1000", - "examine": "3 doses of a super-strong antipoison potion.", - "grand_exchange_price": "1071", - "durability": null, - "name": "Antipoison++(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5954" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1071", - "durability": null, - "name": "Antipoison++(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5955" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of a super-strong antipoison potion.", - "grand_exchange_price": "632", - "durability": null, - "name": "Antipoison++(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5956" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "632", - "durability": null, - "name": "Antipoison++(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5957" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of a super-strong antipoison potion.", - "grand_exchange_price": "821", - "durability": null, - "name": "Antipoison++(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5958" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "821", - "durability": null, - "name": "Antipoison++(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5959" - }, - { - "examine": "A basket filled with tomatoes.", - "grand_exchange_price": "663", - "durability": null, - "name": "Tomatoes(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5960" - }, - { - "durability": null, - "name": "Tomatoes(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5961" - }, - { - "examine": "A basket filled with tomatoes.", - "grand_exchange_price": "663", - "durability": null, - "name": "Tomatoes(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5962" - }, - { - "durability": null, - "name": "Tomatoes(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5963" - }, - { - "examine": "A basket filled with tomatoes.", - "grand_exchange_price": "663", - "durability": null, - "name": "Tomatoes(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5964" - }, - { - "durability": null, - "name": "Tomatoes(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5965" - }, - { - "examine": "A basket filled with tomatoes.", - "grand_exchange_price": "663", - "durability": null, - "name": "Tomatoes(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5966" - }, - { - "durability": null, - "name": "Tomatoes(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5967" - }, - { - "ge_buy_limit": "10000", - "examine": "A basket filled with tomatoes.", - "grand_exchange_price": "335", - "durability": null, - "name": "Tomatoes(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5968" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "335", - "durability": null, - "name": "Tomatoes(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5969" - }, - { - "ge_buy_limit": "5000", - "examine": "I could make a spicy curry with this.", - "grand_exchange_price": "318", - "durability": null, - "name": "Curry leaf", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5970" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "318", - "durability": null, - "name": "Curry leaf", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5971" - }, - { - "ge_buy_limit": "5000", - "examine": "Looks delicious.", - "grand_exchange_price": "2074", - "durability": null, - "name": "Papaya fruit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5972" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2074", - "durability": null, - "name": "Papaya fruit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5973" - }, - { - "ge_buy_limit": "5000", - "examine": "It's a coconut.", - "grand_exchange_price": "2568", - "durability": null, - "name": "Coconut", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5974" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2568", - "durability": null, - "name": "Coconut", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5975" - }, - { - "ge_buy_limit": "5000", - "examine": "It's a coconut.", - "grand_exchange_price": "1258", - "durability": null, - "name": "Coconut", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5976" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1258", - "durability": null, - "name": "Coconut", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5977" - }, - { - "ge_buy_limit": "10000", - "examine": "All the milk has been removed.", - "grand_exchange_price": "54", - "durability": null, - "name": "Coconut shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5978" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "54", - "durability": null, - "name": "Coconut shell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5979" - }, - { - "ge_buy_limit": "100", - "examine": "This is the largest fruit I've ever seen.", - "grand_exchange_price": "43", - "durability": null, - "name": "Calquat fruit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5980" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "43", - "durability": null, - "name": "Calquat fruit", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5981" - }, - { - "shop_price": "48", - "ge_buy_limit": "10000", - "examine": "A juicy watermelon.", - "grand_exchange_price": "41", - "durability": null, - "name": "Watermelon", - "tradeable": "true", - "weight": "0.111", - "archery_ticket_price": "0", - "id": "5982" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "41", - "durability": null, - "name": "Watermelon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5983" - }, - { - "ge_buy_limit": "1000", - "examine": "A slice of watermelon.", - "grand_exchange_price": "40", - "durability": null, - "name": "Watermelon slice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5984" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "40", - "durability": null, - "name": "Watermelon slice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5985" - }, - { - "ge_buy_limit": "10000", - "examine": "Raw sweetcorn.", - "grand_exchange_price": "19", - "durability": null, - "name": "Sweetcorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5986" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "19", - "durability": null, - "name": "Sweetcorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5987" - }, - { - "ge_buy_limit": "10000", - "examine": "Delicious cooked sweetcorn.", - "grand_exchange_price": "15", - "durability": null, - "name": "Cooked sweetcorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5988" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "15", - "durability": null, - "name": "Cooked sweetcorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5989" - }, - { - "durability": null, - "name": "Burnt sweetcorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5991" - }, - { - "ge_buy_limit": "100", - "examine": "A bucket of apple mush.", - "grand_exchange_price": "425", - "durability": null, - "name": "Apple mush", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5992" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "425", - "durability": null, - "name": "Apple mush", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5993" - }, - { - "ge_buy_limit": "1000", - "examine": "A handful of Hammerstone hops.", - "grand_exchange_price": "14", - "durability": null, - "name": "Hammerstone hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5994" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "14", - "durability": null, - "name": "Hammerstone hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5995" - }, - { - "ge_buy_limit": "1000", - "examine": "A handful of Asgarnian hops.", - "grand_exchange_price": "2", - "durability": null, - "name": "Asgarnian hops", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "5996" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2", - "durability": null, - "name": "Asgarnian hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5997" - }, - { - "ge_buy_limit": "1000", - "examine": "A handful of Yanillian hops.", - "grand_exchange_price": "1", - "durability": null, - "name": "Yanillian hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5998" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1", - "durability": null, - "name": "Yanillian hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "5999" - }, - { - "shop_price": "4", - "ge_buy_limit": "1000", - "examine": "A handful of Krandorian hops.", - "grand_exchange_price": "2", - "durability": null, - "name": "Krandorian hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6000" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2", - "durability": null, - "name": "Krandorian hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6001" - }, - { - "ge_buy_limit": "1000", - "examine": "A handful of wildblood hops.", - "grand_exchange_price": "66", - "durability": null, - "name": "Wildblood hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6002" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "66", - "durability": null, - "name": "Wildblood hops", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6003" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "219", - "examine": "A Bittercap Mushroom", - "durability": null, - "name": "Mushroom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6004" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "219", - "durability": null, - "name": "Mushroom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6005" - }, - { - "ge_buy_limit": "1000", - "examine": "A handful of Barley.", - "grand_exchange_price": "211", - "durability": null, - "name": "Barley", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6006" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "211", - "durability": null, - "name": "Barley", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6007" - }, - { - "ge_buy_limit": "1000", - "examine": "A handful of barley malt.", - "grand_exchange_price": "410", - "durability": null, - "name": "Barley malt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6008" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "410", - "durability": null, - "name": "Barley malt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6009" - }, - { - "ge_buy_limit": "1000", - "examine": "A bunch of marigolds.", - "grand_exchange_price": "3326", - "durability": null, - "name": "Marigolds", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6010" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3326", - "durability": null, - "name": "Marigolds", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6011" - }, - { - "ge_buy_limit": "1000", - "examine": "A bunch of nasturtiums.", - "grand_exchange_price": "52", - "durability": null, - "name": "Nasturtiums", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6012" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "52", - "durability": null, - "name": "Nasturtiums", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6013" - }, - { - "ge_buy_limit": "1000", - "examine": "Some rosemary.", - "grand_exchange_price": "29", - "durability": null, - "name": "Rosemary", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6014" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "29", - "durability": null, - "name": "Rosemary", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6015" - }, - { - "ge_buy_limit": "10000", - "examine": "Don't prick yourself with this.", - "grand_exchange_price": "6990", - "durability": null, - "name": "Cactus spine", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6016" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "6990", - "durability": null, - "name": "Cactus spine", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6017" - }, - { - "ge_buy_limit": "10000", - "examine": "They look sweet and juicy, but only a fool would eat them.", - "grand_exchange_price": "399", - "durability": null, - "name": "Poison ivy berries", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6018" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "399", - "durability": null, - "name": "Poison ivy berries", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6019" - }, - { - "ge_buy_limit": "100", - "examine": "A pile of leaves.", - "grand_exchange_price": "152", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6020" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "152", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6021" - }, - { - "ge_buy_limit": "100", - "examine": "A pile of leaves.", - "grand_exchange_price": "27", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6022" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "27", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6023" - }, - { - "ge_buy_limit": "100", - "examine": "A pile of leaves.", - "grand_exchange_price": "21", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6024" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "21", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6025" - }, - { - "ge_buy_limit": "100", - "examine": "A pile of leaves.", - "grand_exchange_price": "7", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6026" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6027" - }, - { - "ge_buy_limit": "100", - "examine": "A pile of leaves.", - "grand_exchange_price": "11", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6028" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6029" - }, - { - "ge_buy_limit": "100", - "examine": "A pile of leaves.", - "grand_exchange_price": "4", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6030" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4", - "durability": null, - "name": "Leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6031" - }, - { - "shop_price": "20", - "ge_buy_limit": "10000", - "examine": "Good for plants, helps them grow.", - "grand_exchange_price": "97", - "durability": null, - "name": "Compost", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6032" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "97", - "durability": null, - "name": "Compost", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6033" - }, - { - "ge_buy_limit": "10000", - "examine": "Super-good for the smallest or largest of plants.", - "grand_exchange_price": "909", - "durability": null, - "name": "Supercompost", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6034" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "909", - "durability": null, - "name": "Supercompost", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6035" - }, - { - "shop_price": "25", - "ge_buy_limit": "100", - "examine": "Use this on plants to cure disease.", - "grand_exchange_price": "170", - "durability": null, - "name": "Plant cure", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6036" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "170", - "durability": null, - "name": "Plant cure", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6037" - }, - { - "ge_buy_limit": "100", - "examine": "I could use this to make jewellery.", - "grand_exchange_price": "1078", - "durability": null, - "name": "Magic string", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6038" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1078", - "durability": null, - "name": "Magic string", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6039" - }, - { - "destroy_message": "You will need to create a new amulet if you destroy this one.", - "examine": "An Amulet of Nature.", - "durability": null, - "name": "Amulet of nature", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6040", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "examine": "Strung with the root of a Magic Tree. If I enchant this it will become an amulet of nature.", - "grand_exchange_price": "1996", - "durability": null, - "name": "Pre-nature amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6041", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1996", - "durability": null, - "name": "Pre-nature amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6042" - }, - { - "ge_buy_limit": "100", - "examine": "The roots of the Oak tree.", - "grand_exchange_price": "60", - "durability": null, - "name": "Oak roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6043" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "60", - "durability": null, - "name": "Oak roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6044" - }, - { - "ge_buy_limit": "100", - "examine": "The roots of the Willow tree.", - "grand_exchange_price": "41", - "durability": null, - "name": "Willow roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6045" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "41", - "durability": null, - "name": "Willow roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6046" - }, - { - "ge_buy_limit": "100", - "examine": "The roots of the Maple tree.", - "grand_exchange_price": "40", - "durability": null, - "name": "Maple roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6047" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "40", - "durability": null, - "name": "Maple roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6048" - }, - { - "ge_buy_limit": "100", - "examine": "The roots of a yew tree", - "grand_exchange_price": "570", - "durability": null, - "name": "Yew roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6049" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "570", - "durability": null, - "name": "Yew roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6050" - }, - { - "ge_buy_limit": "100", - "examine": "The roots of a magic tree.", - "grand_exchange_price": "5853", - "durability": null, - "name": "Magic roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6051" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5853", - "durability": null, - "name": "Magic roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6052" - }, - { - "durability": null, - "name": "Spirit roots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6054" - }, - { "shop_price": "1", - "examine": "A handful of weeds.", - "durability": null, - "name": "Weeds", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6055" - }, - { - "durability": null, - "name": "Weeds", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6056" - }, - { - "examine": "A sack filled with hay. / This sack of hay has a bronze spear sticking through it.", - "durability": null, - "name": "Hay sack", - "archery_ticket_price": "0", - "id": "6057" - }, - { - "examine": "A sack filled with hay. / This sack of hay has a bronze spear sticking through it.", - "durability": null, - "name": "Hay sack", - "archery_ticket_price": "0", - "id": "6058" - }, - { - "examine": "This should scare the birds.", - "durability": null, - "name": "Scarecrow", - "archery_ticket_price": "0", - "id": "6059" - }, - { - "durability": null, - "name": "Stool", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6060" - }, - { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "Bronze crossbow bolts.", - "grand_exchange_price": "134", - "durability": null, - "name": "Bronze bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6061", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "shop_price": "3", - "ge_buy_limit": "10000", - "examine": "Bronze crossbow bolts.", - "grand_exchange_price": "1162", - "durability": null, - "name": "Bronze bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6062", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", - "equipment_slot": "13" - }, - { - "examine": "How do I wash blood stains out?", - "durability": null, - "name": "Bloody mourner top", - "weight": "2.72", - "archery_ticket_price": "0", - "id": "6064" - }, - { - "remove_sleeves": "true", - "examine": "A thick heavy leather top.", - "durability": null, - "name": "Mourner top", - "archery_ticket_price": "0", - "id": "6065", - "equipment_slot": "4" - }, - { - "examine": "Damaged: These are in need of a good tailor.Repaired: A pair of mourner trousers.", - "durability": null, - "name": "Mourner trousers", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "6066" - }, - { - "examine": "Damaged: These are in need of a good tailor.Repaired: A pair of mourner trousers.", - "durability": null, - "name": "Mourner trousers", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "6067", - "equipment_slot": "7" - }, - { - "shop_price": "160", - "examine": "These will keep my hands warm.", - "durability": null, - "name": "Mourner gloves", - "weight": "2.3", - "archery_ticket_price": "0", - "id": "6068", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "160", - "examine": "Comfortable leather boots.", - "durability": null, - "name": "Mourner boots", - "weight": "1.36", - "archery_ticket_price": "0", - "id": "6069", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "examine": "A dull brown cape.", - "durability": null, - "name": "Mourner cloak", - "weight": "2.25", - "archery_ticket_price": "0", - "id": "6070", - "equipment_slot": "1" - }, - { - "shop_price": "160", - "examine": "A letter of recommendation.", - "durability": null, - "name": "Mourner letter", - "archery_ticket_price": "0", - "id": "6071" - }, - { - "examine": "A bar of soap taken from Tegid.", - "durability": null, - "name": "Tegid's soap", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6072" - }, - { - "examine": "A book on the history of Prifddinas.", - "durability": null, - "name": "Prifddinas' history", - "archery_ticket_price": "0", - "id": "6073" - }, - { - "examine": "A book on the exploration of the eastern realm.", - "durability": null, - "name": "Eastern discovery", - "archery_ticket_price": "0", - "id": "6075" - }, - { - "examine": "A book on the settlement of the eastern realm.", - "durability": null, - "name": "Eastern settlement", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6077" + "weight": "0.113" }, { - "examine": "A book about the great divide.", - "durability": null, - "name": "The great divide", - "weight": "0.5", + "id": "5604", + "name": "Magnet", + "examine": "A very attractive magnet.", "archery_ticket_price": "0", - "id": "6079" + "durability": null }, { - "examine": "A strange broken device of gnomic design.", - "durability": null, - "name": "Broken device", - "tradeable": "false", - "destroy": "true", + "id": "5605", + "name": "Knife", + "examine": "A dangerous looking knife.", "archery_ticket_price": "0", - "id": "6081" + "durability": null, + "shop_price": "25", + "tradeable": "true", + "weight": "0.4" }, { - "turn90cw_anim": "2319", - "examine": "A device for firing dye.", - "walk_anim": "2317", + "id": "5606", + "name": "Makeover voucher", + "examine": "I can exchange this for one free makeover with the makeover mage.", + "archery_ticket_price": "0", "durability": null, - "weight": "4", - "turn90ccw_anim": "2320", + "weight": "1" + }, + { + "id": "5607", + "name": "Grain", + "examine": "Some wheat heads.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "1", + "shop_price": "2", + "tradeable": "true", + "weight": "0.6" + }, + { + "id": "5608", + "name": "Fox", + "examine": "A cunning animal.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "5609", + "name": "Chicken", + "examine": "Normal: Yep. Definitely a chicken.", + "archery_ticket_price": "0", "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "20", - "turn180_anim": "2318", - "render_anim": "284", + "durability": null, + "equipment_slot": "5" + }, + { + "id": "5610", + "name": "Hourglass", + "examine": "There's not much sand left in the top half...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "5611", + "name": "Initiate sallet", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5612", + "name": "Initiate hauberk", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5613", + "name": "Initiate cuisse", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5614", + "name": "Magic carpet", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "3", - "stand_anim": "2316", - "name": "Fixed device", - "run_anim": "2322", + "render_anim": "191", + "run_anim": "330", + "stand_anim": "330", + "stand_turn_anim": "330", + "turn180_anim": "330", + "turn90ccw_anim": "330", + "turn90cw_anim": "330", + "walk_anim": "330" + }, + { + "id": "5615", + "name": "Bonemeal", + "examine": "A pot of crushed bearded gorilla monkey bones.", "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "5616", + "name": "Bronze arrow(p+)", + "examine": "Arrows with bronze heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "7", + "tradeable": "true" + }, + { + "id": "5617", + "name": "Iron arrow(p+)", + "examine": "Arrows with iron heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "5618", + "name": "Steel arrow(p+)", + "examine": "Arrows with steel heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "shop_price": "46", + "tradeable": "true" + }, + { + "id": "5619", + "name": "Mithril arrow(p+)", + "examine": "Arrows with mithril heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,20}", + "shop_price": "76", + "tradeable": "true" + }, + { + "id": "5620", + "name": "Adamant arrow(p+)", + "examine": "Arrows with adamantite heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "shop_price": "172", + "tradeable": "true" + }, + { + "id": "5621", + "name": "Rune arrow(p+)", + "examine": "Arrows with rune heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "shop_price": "510", + "tradeable": "true" + }, + { + "id": "5622", + "name": "Bronze arrow(p++)", + "examine": "Arrows with bronze heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "7", + "tradeable": "true" + }, + { + "id": "5623", + "name": "Iron arrow(p++)", + "examine": "Arrows with iron heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "5624", + "name": "Steel arrow(p++)", + "examine": "Arrows with steel heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "shop_price": "46", + "tradeable": "true" + }, + { + "id": "5625", + "name": "Mithril arrow(p++)", + "examine": "Arrows with mithril heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,20}", + "shop_price": "76", + "tradeable": "true" + }, + { + "id": "5626", + "name": "Adamant arrow(p++)", + "examine": "Arrows with adamantite heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "shop_price": "172", + "tradeable": "true" + }, + { + "id": "5627", + "name": "Rune arrow(p++)", + "examine": "Arrows with rune heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "shop_price": "510", + "tradeable": "true" + }, + { + "id": "5628", + "name": "Bronze dart(p+)", + "examine": "A deadly throwing dart with a bronze tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5629", + "name": "Iron dart(p+)", + "examine": "A deadly throwing dart with an iron tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5630", + "name": "Steel dart(p+)", + "examine": "A deadly throwing dart with a steel tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5631", + "name": "Black dart(p+)", + "examine": "A deadly throwing dart with a black tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,10}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5632", + "name": "Mithril dart(p+)", + "examine": "A deadly throwing dart with a mithril tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5633", + "name": "Adamant dart(p+)", + "examine": "A deadly throwing dart with an adamantite tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5634", + "name": "Rune dart(p+)", + "examine": "A deadly throwing dart with a rune tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5635", + "name": "Bronze dart(p++)", + "examine": "A deadly throwing dart with a bronze tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5636", + "name": "Iron dart(p++)", + "examine": "A deadly throwing dart with an iron tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5637", + "name": "Steel dart(p++)", + "examine": "A deadly throwing dart with a steel tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5638", + "name": "Black dart(p++)", + "examine": "A deadly throwing dart with a black tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,10}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5639", + "name": "Mithril dart(p++)", + "examine": "A deadly throwing dart with a mithril tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5640", + "name": "Adamant dart(p++)", + "examine": "A deadly throwing dart with an adamantite tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,30}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5641", + "name": "Rune dart(p++)", + "examine": "A deadly throwing dart with a rune tip.", + "archery_ticket_price": "0", + "attack_anims": "582,582,582,582", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5642", + "name": "Bronze javelin(p+)", + "examine": "A bronze-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "6", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5643", + "name": "Iron javelin(p+)", + "examine": "An iron-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "8", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5644", + "name": "Steel javelin(p+)", + "examine": "A steel-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "shop_price": "37", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5645", + "name": "Mithril javelin(p+)", + "examine": "A mithril tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "shop_price": "79", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5646", + "name": "Adamant javelin(p+)", + "examine": "An adamant tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,30}", + "shop_price": "100", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5647", + "name": "Rune javelin(p+)", + "examine": "A rune tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "624", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5648", + "name": "Bronze jav'n(p++)", + "examine": "A bronze-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6", + "defence_anim": "424", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5649", + "name": "Iron javelin(p++)", + "examine": "An iron-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "shop_price": "8", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5650", + "name": "Steel javelin(p++)", + "examine": "A steel-tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,5}", + "shop_price": "37", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5651", + "name": "Mithril javelin(p++)", + "examine": "A mithril tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,20}", + "shop_price": "79", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5652", + "name": "Adamant javelin(p++)", + "examine": "An adamant tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,30}", + "shop_price": "100", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5653", + "name": "Rune javelin(p++)", + "examine": "A rune tipped javelin.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_speed": "6", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{4,40}", + "shop_price": "624", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5654", + "name": "Bronze knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "14", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5655", + "name": "Iron knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "58", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5656", + "name": "Steel knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "shop_price": "68", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5657", + "name": "Mithril knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5658", + "name": "Black knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,10}", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5659", + "name": "Adamant knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,30}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5660", + "name": "Rune knife(p+)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5661", + "name": "Bronze knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "14", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5662", + "name": "Iron knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "shop_price": "58", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5663", + "name": "Steel knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,5}", + "shop_price": "68", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5664", + "name": "Mithril knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,20}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5665", + "name": "Black knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,10}", + "shop_price": "15", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5666", + "name": "Adamant knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{4,30}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5667", + "name": "Rune knife(p++)", + "examine": "A finely balanced throwing knife.", + "archery_ticket_price": "0", + "attack_anims": "806,806,806,806", + "attack_audios": "2704,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,40}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "5668", + "name": "Iron dagger(p+)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "shop_price": "38", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5669", + "name": "Iron dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5670", + "name": "Bronze dagger(p+)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "shop_price": "11", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5671", + "name": "Bronze dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5672", + "name": "Steel dagger(p+)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,5}", + "shop_price": "135", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5673", + "name": "Steel dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5674", + "name": "Mithril dagger(p+)", + "examine": "A dangerous dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,20}", + "shop_price": "130", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.3" + }, + { + "id": "5675", + "name": "Mithril dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5676", + "name": "Adamant dagger(p+)", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,30}", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "5677", + "name": "Adamant dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5678", + "name": "Rune dagger(p+)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "2584", + "requirements": "{0,40}", + "shop_price": "8000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5679", + "name": "Rune dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5680", + "name": "Dragon dagger(p+)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "2584", + "requirements": "{0,60}", + "shop_price": "60000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5681", + "name": "Dragon dagger(p+)", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "defence_anim": "397", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "5682", + "name": "Black dagger(p+)", + "examine": "A vicious black dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,10}", + "shop_price": "240", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5683", + "name": "Black dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5684", + "name": "Poison dagger(p+)", + "archery_ticket_price": "0", + "attack_audios": "2517,2517,2500,2517", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "5685", + "name": "Poison dagger(p+)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5686", + "name": "Iron dagger(p++)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "shop_price": "38", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5687", + "name": "Iron dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5688", + "name": "Br'ze dagger(p++)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "shop_price": "11", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5689", + "name": "Br'ze dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5690", + "name": "Steel dagger(p++)", + "examine": "Short but pointy.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,5}", + "shop_price": "135", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5691", + "name": "Steel dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5692", + "name": "Mithril dagger(p++)", + "examine": "A dangerous dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,20}", + "shop_price": "130", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.3" + }, + { + "id": "5693", + "name": "Mithril dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5694", + "name": "Adamant dagger(p++)", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,30}", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "5695", + "name": "Adamant dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5696", + "name": "Rune dagger(p++)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "2584", + "requirements": "{0,40}", + "shop_price": "8000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5697", + "name": "Rune dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5698", + "name": "Dragon dagger(p++)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "2584", + "requirements": "{0,60}", + "shop_price": "60000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5699", + "name": "Dragon dagger(p++)", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "defence_anim": "397", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "5700", + "name": "Black dagger(p++)", + "examine": "A vicious black dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", + "requirements": "{0,10}", + "shop_price": "240", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "5701", + "name": "Black dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5702", + "name": "Poison dagger(p++)", + "archery_ticket_price": "0", + "attack_audios": "2517,2517,2500,2517", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "5703", + "name": "Poison dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5704", + "name": "Bronze spear(p+)", + "examine": "A bronze tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5705", + "name": "Bronze spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5706", + "name": "Iron spear(p+)", + "examine": "An iron tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5707", + "name": "Iron spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5708", + "name": "Steel spear(p+)", + "examine": "A steel tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5709", + "name": "Steel spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5710", + "name": "Mithril spear(p+)", + "examine": "A mithril tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "5711", + "name": "Mithril spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5712", + "name": "Adamant spear(p+)", + "examine": "An adamant tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "5713", + "name": "Adamant spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5714", + "name": "Rune spear(p+)", + "examine": "A rune tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5715", + "name": "Rune spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5716", + "name": "Dragon spear(p+)", + "examine": "A dragon tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "5717", + "name": "Dragon spear(p+)", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "defence_anim": "2079", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "5718", + "name": "Bronze spear(p++)", + "examine": "A bronze tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5719", + "name": "Bronze spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5720", + "name": "Iron spear(p++)", + "examine": "An iron tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5721", + "name": "Iron spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5722", + "name": "Steel spear(p++)", + "examine": "A steel tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5723", + "name": "Steel spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5724", + "name": "Mithril spear(p++)", + "examine": "A mithril tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "5725", + "name": "Mithril spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5726", + "name": "Adamant spear(p++)", + "examine": "An adamant tipped spear.", + "archery_ticket_price": "0", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14" + }, + { + "id": "5727", + "name": "Adamant spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5728", + "name": "Rune spear(p++)", + "examine": "A rune tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5729", + "name": "Rune spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5730", + "name": "Dragon spear(p++)", + "examine": "A dragon tipped spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "requirements": "{0,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2" + }, + { + "id": "5731", + "name": "Dragon spear(p++)", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "defence_anim": "2079", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "5732", + "name": "Stool", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5" + }, + { + "id": "5733", + "name": "Rotten potato", + "examine": "Yuk!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "5734", + "name": "Black spear(p+)", + "examine": "A black tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5735", + "name": "Black spear(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5736", + "name": "Black spear(p++)", + "examine": "A black tipped spear.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "5737", + "name": "Black spear(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5738", + "name": "Woad leaf", + "examine": "A slightly bluish leaf.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "5739", + "name": "Asgarnian ale(m)", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5740", + "name": "Asgarnian ale(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5741", + "name": "Mature wmb", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5742", + "name": "Mature wmb", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5743", + "name": "Greenman's ale(m)", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "5744", + "name": "Greenman's ale(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5745", + "name": "Dragon bitter(m)", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5746", + "name": "Dragon bitter(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5747", + "name": "Dwarven stout(m)", + "examine": "This looks a good deal stronger than normal Dwarven Stout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5748", + "name": "Dwarven stout(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5749", + "name": "Moonlight mead(m)", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5750", + "name": "Moonlight mead(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5751", + "name": "Axeman's folly", + "examine": "This might help me chop harder.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5752", + "name": "Axeman's folly", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5753", + "name": "Axeman's folly(m)", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5754", + "name": "Axeman's folly(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5755", + "name": "Chef's delight", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5756", + "name": "Chef's delight", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5757", + "name": "Chef's delight(m)", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5758", + "name": "Chef's delight(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5759", + "name": "Slayer's respite", + "examine": "Ale with bite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5760", + "name": "Slayer's respite", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5761", + "name": "Slayer's respite(m)", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5762", + "name": "Slayer's respite(m)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5763", + "name": "Cider", + "examine": "A glass of Cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5764", + "name": "Cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5765", + "name": "Mature cider", + "examine": "This looks a good deal stronger than normal cider.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5766", + "name": "Mature cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5767", + "name": "Ale yeast", + "examine": "A pot filled with ale yeast.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true", + "weight": "2" + }, + { + "id": "5768", + "name": "Ale yeast", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5769", + "name": "Calquat keg", + "examine": "Sliced and hollowed out to form a keg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5770", + "name": "Calquat keg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5771", + "name": "Dwarven stout(1)", + "examine": "A pint of thick dark beer.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5772", + "name": "Dwarven stout(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5773", + "name": "Dwarven stout(2)", + "examine": "A pint of thick dark beer.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5774", + "name": "Dwarven stout(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5775", + "name": "Dwarven stout(3)", + "examine": "A pint of thick dark beer.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5776", + "name": "Dwarven stout(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5777", + "name": "Dwarven stout(4)", + "examine": "A pint of thick dark beer.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5778", + "name": "Dwarven stout(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5779", + "name": "Asgarnian ale(1)", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5780", + "name": "Asgarnian ale(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5781", + "name": "Asgarnian ale(2)", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5782", + "name": "Asgarnian ale(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5783", + "name": "Asgarnian ale(3)", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5784", + "name": "Asgarnian ale(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5785", + "name": "Asgarnian ale(4)", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5786", + "name": "Asgarnian ale(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5787", + "name": "Greenmans ale(1)", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "5788", + "name": "Greenmans ale(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5789", + "name": "Greenmans ale(2)", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "5790", + "name": "Greenmans ale(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5791", + "name": "Greenmans ale(3)", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "5792", + "name": "Greenmans ale(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5793", + "name": "Greenmans ale(4)", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "5794", + "name": "Greenmans ale(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5795", + "name": "Mind bomb(1)", + "examine": "It's got strange bubbles in it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5796", + "name": "Mind bomb(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5797", + "name": "Mind bomb(2)", + "examine": "It's got strange bubbles in it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5798", + "name": "Mind bomb(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5799", + "name": "Mind bomb(3)", + "examine": "It's got strange bubbles in it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5800", + "name": "Mind bomb(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5801", + "name": "Mind bomb(4)", + "examine": "It's got strange bubbles in it.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "5802", + "name": "Mind bomb(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5803", + "name": "Dragon bitter(1)", + "examine": "A glass of bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5804", + "name": "Dragon bitter(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5805", + "name": "Dragon bitter(2)", + "examine": "A glass of bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5806", + "name": "Dragon bitter(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5807", + "name": "Dragon bitter(3)", + "examine": "A glass of bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5808", + "name": "Dragon bitter(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5809", + "name": "Dragon bitter(4)", + "examine": "A glass of bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5810", + "name": "Dragon bitter(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5811", + "name": "Moonlight mead(1)", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "5812", + "name": "Moonlight mead(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5813", + "name": "Moonlight mead(2)", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "5814", + "name": "Moonlight mead(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5815", + "name": "Moonlight mead(3)", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "5816", + "name": "Moonlight mead(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5817", + "name": "Moonlight mead(4)", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "5818", + "name": "Moonlight mead(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5819", + "name": "Axeman's folly(1)", + "examine": "This might help me chop harder.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5820", + "name": "Axeman's folly(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5821", + "name": "Axeman's folly(2)", + "examine": "This might help me chop harder.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5822", + "name": "Axeman's folly(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5823", + "name": "Axeman's folly(3)", + "examine": "This might help me chop harder.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5824", + "name": "Axeman's folly(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5825", + "name": "Axeman's folly(4)", + "examine": "This might help me chop harder.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5826", + "name": "Axeman's folly(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5827", + "name": "Chef's delight(1)", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5828", + "name": "Chef's delight(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5829", + "name": "Chef's delight(2)", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5830", + "name": "Chef's delight(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5831", + "name": "Chef's delight(3)", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5832", + "name": "Chef's delight(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5833", + "name": "Chef's delight(4)", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5834", + "name": "Chef's delight(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5835", + "name": "Slayer's respite(1)", + "examine": "Ale with bite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5836", + "name": "Slayer's respite(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5837", + "name": "Slayer's respite(2)", + "examine": "Ale with bite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5838", + "name": "Slayer's respite(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5839", + "name": "Slayer's respite(3)", + "examine": "Ale with bite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5840", + "name": "Slayer's respite(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5841", + "name": "Slayer's respite(4)", + "examine": "Ale with bite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5842", + "name": "Slayer's respite(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5843", + "name": "Cider(1)", + "examine": "A glass of Cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5844", + "name": "Cider(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5845", + "name": "Cider(2)", + "examine": "A glass of Cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5846", + "name": "Cider(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5847", + "name": "Cider(3)", + "examine": "A glass of Cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5848", + "name": "Cider(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5849", + "name": "Cider(4)", + "examine": "A glass of Cider", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5850", + "name": "Cider(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5851", + "name": "Dwarven stout(m1)", + "examine": "This looks a good deal stronger than normal Dwarven Stout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5852", + "name": "Dwarven stout(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5853", + "name": "Dwarven stout(m2)", + "examine": "This looks a good deal stronger than normal Dwarven Stout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5854", + "name": "Dwarven stout(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5855", + "name": "Dwarven stout(m3)", + "examine": "This looks a good deal stronger than normal Dwarven Stout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5856", + "name": "Dwarven stout(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5857", + "name": "Dwarven stout(m4)", + "examine": "This looks a good deal stronger than normal Dwarven Stout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5858", + "name": "Dwarven stout(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5859", + "name": "Asgarnian ale(m1)", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5860", + "name": "Asgarnian ale(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5861", + "name": "Asgarnian ale(m2)", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5862", + "name": "Asgarnian ale(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5863", + "name": "Asgarnian ale(m3)", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5864", + "name": "Asgarnian ale(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5865", + "name": "Asgarnian ale(m4)", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5866", + "name": "Asgarnian ale(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5867", + "name": "Greenmans ale(m1)", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "5868", + "name": "Greenmans ale(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5869", + "name": "Greenmans ale(m2)", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "5870", + "name": "Greenmans ale(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5871", + "name": "Greenmans ale(m3)", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "5872", + "name": "Greenmans ale(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5873", + "name": "Greenmans ale(m4)", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "5874", + "name": "Greenmans ale(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5875", + "name": "Mind bomb(m1)", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5876", + "name": "Mind bomb(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5877", + "name": "Mind bomb(m2)", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5878", + "name": "Mind bomb(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5879", + "name": "Mind bomb(m3)", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5880", + "name": "Mind bomb(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5881", + "name": "Mind bomb(m4)", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5882", + "name": "Mind bomb(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5883", + "name": "Dragon bitter(m1)", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5884", + "name": "Dragon bitter(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5885", + "name": "Dragon bitter(m2)", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5886", + "name": "Dragon bitter(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5887", + "name": "Dragon bitter(m3)", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5888", + "name": "Dragon bitter(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5889", + "name": "Dragon bitter(m4)", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5890", + "name": "Dragon bitter(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5891", + "name": "M'light mead(m1)", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "5892", + "name": "M'light mead(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5893", + "name": "M'light mead(m2)", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5894", + "name": "M'light mead(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5895", + "name": "M'light mead(m3)", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5896", + "name": "M'light mead(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5897", + "name": "M'light mead(m4)", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5898", + "name": "M'light mead(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5899", + "name": "Axeman's folly(m1)", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5900", + "name": "Axeman's folly(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5901", + "name": "Axeman's folly(m2)", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5902", + "name": "Axeman's folly(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5903", + "name": "Axeman's folly(m3)", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5904", + "name": "Axeman's folly(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5905", + "name": "Axeman's folly(m4)", + "examine": "This might help me chop harder.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5906", + "name": "Axeman's folly(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5907", + "name": "Chef's delight(m1)", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5908", + "name": "Chef's delight(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5909", + "name": "Chef's delight(m2)", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5910", + "name": "Chef's delight(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5911", + "name": "Chef's delight(m3)", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5912", + "name": "Chef's delight(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5913", + "name": "Chef's delight(m4)", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5914", + "name": "Chef's delight(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5915", + "name": "Slayer respite(m1)", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5916", + "name": "Slayer respite(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5917", + "name": "Slayer respite(m2)", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5918", + "name": "Slayer respite(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5919", + "name": "Slayer respite(m3)", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5920", + "name": "Slayer respite(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5921", + "name": "Slayer respite(m4)", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5922", + "name": "Slayer respite(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5923", + "name": "Cider(m1)", + "examine": "This looks a good deal stronger than normal cider.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5924", + "name": "Cider(m1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5925", + "name": "Cider(m2)", + "examine": "This looks a good deal stronger than normal cider.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5926", + "name": "Cider(m2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5927", + "name": "Cider(m3)", + "examine": "This looks a good deal stronger than normal cider.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5928", + "name": "Cider(m3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5929", + "name": "Cider(m4)", + "examine": "This looks a good deal stronger than normal cider.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5930", + "name": "Cider(m4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5931", + "name": "Jute fibre", + "examine": "I can weave this to make sacks.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "5932", + "name": "Jute fibre", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5933", + "name": "Willow branch", + "examine": "A branch from a willow tree.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "5934", + "name": "Willow branch", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" + }, + { + "id": "5935", + "name": "Coconut milk", + "examine": "A vial filled with coconut milk.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5937", + "name": "Weapon poison+", + "examine": "A vial of extra-strong weapon poison, for spears and daggers.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5938", + "name": "Weapon poison+", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5940", + "name": "Weapon poison++", + "examine": "A vial of super strong weapon poison, for spears and daggers.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "5941", + "name": "Weapon poison++", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5943", + "name": "Antipoison+(4)", + "examine": "N doses of extra-stong antipoison potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5944", + "name": "Antipoison+(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5945", + "name": "Antipoison+(3)", + "examine": "N doses of extra-stong antipoison potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5946", + "name": "Antipoison+(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5947", + "name": "Antipoison+(2)", + "examine": "N doses of extra-stong antipoison potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5948", + "name": "Antipoison+(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5949", + "name": "Antipoison+(1)", + "examine": "N doses of extra-stong antipoison potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5950", + "name": "Antipoison+(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5952", + "name": "Antipoison++(4)", + "examine": "4 doses of a super-strong antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5953", + "name": "Antipoison++(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5954", + "name": "Antipoison++(3)", + "examine": "3 doses of a super-strong antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5955", + "name": "Antipoison++(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5956", + "name": "Antipoison++(2)", + "examine": "2 doses of a super-strong antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5957", + "name": "Antipoison++(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5958", + "name": "Antipoison++(1)", + "examine": "1 dose of a super-strong antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5959", + "name": "Antipoison++(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5960", + "name": "Tomatoes(1)", + "examine": "A basket filled with tomatoes.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5961", + "name": "Tomatoes(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5962", + "name": "Tomatoes(2)", + "examine": "A basket filled with tomatoes.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5963", + "name": "Tomatoes(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5964", + "name": "Tomatoes(3)", + "examine": "A basket filled with tomatoes.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5965", + "name": "Tomatoes(3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5966", + "name": "Tomatoes(4)", + "examine": "A basket filled with tomatoes.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5967", + "name": "Tomatoes(4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5968", + "name": "Tomatoes(5)", + "examine": "A basket filled with tomatoes.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5969", + "name": "Tomatoes(5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5970", + "name": "Curry leaf", + "examine": "I could make a spicy curry with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5971", + "name": "Curry leaf", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5972", + "name": "Papaya fruit", + "examine": "Looks delicious.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5973", + "name": "Papaya fruit", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5974", + "name": "Coconut", + "examine": "It's a coconut.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5975", + "name": "Coconut", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5976", + "name": "Coconut", + "examine": "It's a coconut.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5977", + "name": "Coconut", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "5978", + "name": "Coconut shell", + "examine": "All the milk has been removed.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5979", + "name": "Coconut shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5980", + "name": "Calquat fruit", + "examine": "This is the largest fruit I've ever seen.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5981", + "name": "Calquat fruit", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5982", + "name": "Watermelon", + "examine": "A juicy watermelon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "48", + "tradeable": "true", + "weight": "0.111" + }, + { + "id": "5983", + "name": "Watermelon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5984", + "name": "Watermelon slice", + "examine": "A slice of watermelon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5985", + "name": "Watermelon slice", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5986", + "name": "Sweetcorn", + "examine": "Raw sweetcorn.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5987", + "name": "Sweetcorn", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5988", + "name": "Cooked sweetcorn", + "examine": "Delicious cooked sweetcorn.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5989", + "name": "Cooked sweetcorn", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "5991", + "name": "Burnt sweetcorn", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "5992", + "name": "Apple mush", + "examine": "A bucket of apple mush.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5993", + "name": "Apple mush", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "5994", + "name": "Hammerstone hops", + "examine": "A handful of Hammerstone hops.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5995", + "name": "Hammerstone hops", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5996", + "name": "Asgarnian hops", + "examine": "A handful of Asgarnian hops.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "5997", + "name": "Asgarnian hops", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5998", + "name": "Yanillian hops", + "examine": "A handful of Yanillian hops.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "5999", + "name": "Yanillian hops", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6000", + "name": "Krandorian hops", + "examine": "A handful of Krandorian hops.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "4", + "tradeable": "true" + }, + { + "id": "6001", + "name": "Krandorian hops", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6002", + "name": "Wildblood hops", + "examine": "A handful of wildblood hops.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6003", + "name": "Wildblood hops", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6004", + "name": "Mushroom", + "examine": "A Bittercap Mushroom", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6005", + "name": "Mushroom", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6006", + "name": "Barley", + "examine": "A handful of Barley.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6007", + "name": "Barley", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6008", + "name": "Barley malt", + "examine": "A handful of barley malt.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6009", + "name": "Barley malt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6010", + "name": "Marigolds", + "examine": "A bunch of marigolds.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6011", + "name": "Marigolds", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6012", + "name": "Nasturtiums", + "examine": "A bunch of nasturtiums.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6013", + "name": "Nasturtiums", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6014", + "name": "Rosemary", + "examine": "Some rosemary.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6015", + "name": "Rosemary", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6016", + "name": "Cactus spine", + "examine": "Don't prick yourself with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6017", + "name": "Cactus spine", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6018", + "name": "Poison ivy berries", + "examine": "They look sweet and juicy, but only a fool would eat them.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6019", + "name": "Poison ivy berries", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6020", + "name": "Leaves", + "examine": "A pile of leaves.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6021", + "name": "Leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6022", + "name": "Leaves", + "examine": "A pile of leaves.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6023", + "name": "Leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6024", + "name": "Leaves", + "examine": "A pile of leaves.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6025", + "name": "Leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6026", + "name": "Leaves", + "examine": "A pile of leaves.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6027", + "name": "Leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6028", + "name": "Leaves", + "examine": "A pile of leaves.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6029", + "name": "Leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6030", + "name": "Leaves", + "examine": "A pile of leaves.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6031", + "name": "Leaves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6032", + "name": "Compost", + "examine": "Good for plants, helps them grow.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "20", + "tradeable": "true", + "weight": "3" + }, + { + "id": "6033", + "name": "Compost", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6034", + "name": "Supercompost", + "examine": "Super-good for the smallest or largest of plants.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "3" + }, + { + "id": "6035", + "name": "Supercompost", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6036", + "name": "Plant cure", + "examine": "Use this on plants to cure disease.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "25", + "tradeable": "true" + }, + { + "id": "6037", + "name": "Plant cure", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6038", + "name": "Magic string", + "examine": "I could use this to make jewellery.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6039", + "name": "Magic string", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6040", + "name": "Amulet of nature", + "examine": "An Amulet of Nature.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to create a new amulet if you destroy this one.", + "durability": null, + "equipment_slot": "2", + "tradeable": "false", + "weight": "1" + }, + { + "id": "6041", + "name": "Pre-nature amulet", + "examine": "Strung with the root of a Magic Tree. If I enchant this it will become an amulet of nature.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6042", + "name": "Pre-nature amulet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6043", + "name": "Oak roots", + "examine": "The roots of the Oak tree.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6044", + "name": "Oak roots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6045", + "name": "Willow roots", + "examine": "The roots of the Willow tree.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6046", + "name": "Willow roots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6047", + "name": "Maple roots", + "examine": "The roots of the Maple tree.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6048", + "name": "Maple roots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6049", + "name": "Yew roots", + "examine": "The roots of a yew tree", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6050", + "name": "Yew roots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6051", + "name": "Magic roots", + "examine": "The roots of a magic tree.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6052", + "name": "Magic roots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6054", + "name": "Spirit roots", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6055", + "name": "Weeds", + "examine": "A handful of weeds.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "6056", + "name": "Weeds", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6057", + "name": "Hay sack", + "examine": "A sack filled with hay. / This sack of hay has a bronze spear sticking through it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6058", + "name": "Hay sack", + "examine": "A sack filled with hay. / This sack of hay has a bronze spear sticking through it.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6059", + "name": "Scarecrow", + "examine": "This should scare the birds.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6060", + "name": "Stool", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6061", + "name": "Bronze bolts(p+)", + "examine": "Bronze crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "6062", + "name": "Bronze bolts(p++)", + "examine": "Bronze crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "shop_price": "3", + "tradeable": "true" + }, + { + "id": "6064", + "name": "Bloody mourner top", + "examine": "How do I wash blood stains out?", + "archery_ticket_price": "0", + "durability": null, + "weight": "2.72" + }, + { + "id": "6065", + "name": "Mourner top", + "examine": "A thick heavy leather top.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" + }, + { + "id": "6066", + "name": "Mourner trousers", + "examine": "These are in need of a good tailor.", + "archery_ticket_price": "0", + "durability": null, + "weight": "2.25" + }, + { + "id": "6067", + "name": "Mourner trousers", + "examine": "A pair of mourner trousers.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "2.25" + }, + { + "id": "6068", + "name": "Mourner gloves", + "examine": "These will keep my hands warm.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "shop_price": "160", + "weight": "2.3" + }, + { + "id": "6069", + "name": "Mourner boots", + "examine": "Comfortable leather boots.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "shop_price": "160", + "weight": "1.36" + }, + { + "id": "6070", + "name": "Mourner cloak", + "examine": "A dull brown cape.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "1", + "weight": "2.25" + }, + { + "id": "6071", + "name": "Mourner letter", + "examine": "A letter of recommendation.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160" + }, + { + "id": "6072", + "name": "Tegid's soap", + "examine": "A bar of soap taken from Tegid.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "6073", + "name": "Prifddinas' history", + "examine": "A book on the history of Prifddinas.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6075", + "name": "Eastern discovery", + "examine": "A book on the exploration of the eastern realm.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6077", + "name": "Eastern settlement", + "examine": "A book on the settlement of the eastern realm.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6079", + "name": "The great divide", + "examine": "A book about the great divide.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "6081", + "name": "Broken device", + "examine": "A strange broken device of gnomic design.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { "id": "6082", - "stand_turn_anim": "2321" + "name": "Fixed device", + "examine": "A device for firing dye.", + "archery_ticket_price": "0", + "attack_speed": "4", + "durability": null, + "equipment_slot": "3", + "render_anim": "284", + "run_anim": "2322", + "stand_anim": "2316", + "stand_turn_anim": "2321", + "turn180_anim": "2318", + "turn90ccw_anim": "2320", + "turn90cw_anim": "2319", + "two_handed": "true", + "walk_anim": "2317", + "weapon_interface": "20", + "weight": "4" }, { - "examine": "This key has seen a lot of use. (Mourning's Ends Part I)", - "durability": null, + "id": "6083", "name": "Tarnished key", + "examine": "This key has seen a lot of use. (Mourning's Ends Part I)", "archery_ticket_price": "0", - "id": "6083" + "durability": null }, { - "examine": "A large pair of ogre bellows filled with red dye.", - "durability": null, + "id": "6085", "name": "Red dye bellows", + "examine": "A large pair of ogre bellows filled with red dye.", "archery_ticket_price": "0", - "id": "6085" + "durability": null }, { - "examine": "A large pair of ogre bellows filled with blue dye.", - "durability": null, + "id": "6086", "name": "Blue dye bellows", + "examine": "A large pair of ogre bellows filled with blue dye.", "archery_ticket_price": "0", - "id": "6086" + "durability": null }, { - "examine": "A large pair of ogre bellows filled with yellow dye.", - "durability": null, + "id": "6087", "name": "Yellow dye bellows", + "examine": "A large pair of ogre bellows filled with yellow dye.", "archery_ticket_price": "0", - "id": "6087" + "durability": null }, { - "examine": "A large pair of ogre bellows filled with green dye.", - "durability": null, + "id": "6088", "name": "Green dye bellows", + "examine": "A large pair of ogre bellows filled with green dye.", "archery_ticket_price": "0", - "id": "6088" + "durability": null }, { - "examine": "A blue dye filled toad.", - "durability": null, + "id": "6089", "name": "Blue toad", - "weight": "1", + "examine": "A blue dye filled toad.", "archery_ticket_price": "0", - "id": "6089" + "durability": null, + "weight": "1" }, { - "examine": "A red dye filled toad.", - "durability": null, + "id": "6090", "name": "Red toad", - "weight": "0.7", + "examine": "A red dye filled toad.", "archery_ticket_price": "0", - "id": "6090" + "durability": null, + "weight": "0.7" }, { - "examine": "A yellow dye filled toad.", - "durability": null, + "id": "6091", "name": "Yellow toad", - "weight": "0.7", + "examine": "A yellow dye filled toad.", "archery_ticket_price": "0", - "id": "6091" + "durability": null, + "weight": "0.7" }, { - "examine": "A green dye filled toad.", - "durability": null, + "id": "6092", "name": "Green toad", - "weight": "1", + "examine": "A green dye filled toad.", "archery_ticket_price": "0", - "id": "6092" + "durability": null, + "weight": "1" }, { - "examine": "A barrel full of rotten apples.", - "durability": null, + "id": "6093", "name": "Rotten apples", - "weight": "17", + "examine": "A barrel full of rotten apples.", "archery_ticket_price": "0", - "id": "6093" + "durability": null, + "weight": "17" }, { - "examine": "A barrel full of mushed apples.", - "durability": null, + "id": "6094", "name": "Apple barrel", + "examine": "A barrel full of mushed apples.", "archery_ticket_price": "0", - "id": "6094" + "durability": null }, { - "examine": "A barrel full of rotten apples and naptha.", - "durability": null, + "id": "6095", "name": "Naphtha apple mix", + "examine": "A barrel full of rotten apples and naptha.", "archery_ticket_price": "0", - "id": "6095" + "durability": null }, { - "examine": "A barrel full of toxic naphtha.", - "durability": null, + "id": "6096", "name": "Toxic naphtha", - "weight": "32", + "examine": "A barrel full of toxic naphtha.", "archery_ticket_price": "0", - "id": "6096" + "durability": null, + "weight": "32" }, { - "examine": "It's a sieve.", - "durability": null, + "id": "6097", "name": "Sieve", + "examine": "It's a sieve.", "archery_ticket_price": "0", - "id": "6097" + "durability": null }, { - "examine": "A pile of toxic powder.", - "durability": null, + "id": "6098", "name": "Toxic powder", + "examine": "A pile of toxic powder.", "archery_ticket_price": "0", - "id": "6098" + "durability": null }, { - "examine": "A tiny crystal enchanted to return the user to Lletya.", - "durability": null, + "id": "6099", "name": "Teleport crystal (4)", + "examine": "A tiny crystal enchanted to return the user to Lletya.", "archery_ticket_price": "0", - "id": "6099" + "durability": null }, { - "examine": "A tiny crystal enchanted to return the user to Lletya.", - "durability": null, + "id": "6100", "name": "Teleport crystal (3)", + "examine": "A tiny crystal enchanted to return the user to Lletya.", "archery_ticket_price": "0", - "id": "6100" + "durability": null }, { - "examine": "A tiny crystal enchanted to return the user to Lletya.", - "durability": null, + "id": "6101", "name": "Teleport crystal (2)", - "archery_ticket_price": "0", - "id": "6101" - }, - { "examine": "A tiny crystal enchanted to return the user to Lletya.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6102", "name": "Teleport crystal (1)", + "examine": "A tiny crystal enchanted to return the user to Lletya.", "archery_ticket_price": "0", - "id": "6102" + "durability": null }, { - "examine": "A tiny Elf crystal, I need to have this re-enchanted", - "durability": null, + "id": "6103", "name": "Tiny elf crystal", + "examine": "A tiny Elf crystal, I need to have this re-enchanted", "archery_ticket_price": "0", - "id": "6103" + "durability": null }, { - "examine": "This key is newly cut. (Mourning's Ends Part II)", - "durability": null, + "id": "6104", "name": "New key", - "weight": "0.33", + "examine": "This key is newly cut. (Mourning's Ends Part II)", "archery_ticket_price": "0", - "id": "6104" + "durability": null, + "weight": "0.33" }, { - "examine": "They seem to be not quite of this world...", - "durability": null, - "name": "Ghostly boots", - "archery_ticket_price": "0", "id": "6106", + "name": "Ghostly boots", + "examine": "They seem to be not quite of this world...", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, "equipment_slot": "10" }, { - "remove_sleeves": "true", - "examine": "Varies", - "durability": null, - "name": "Ghostly robe", - "archery_ticket_price": "0", "id": "6107", + "name": "Ghostly robe", + "examine": "Varies", + "archery_ticket_price": "0", "bonuses": "0,0,0,5,0,0,0,0,5,0,5,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { - "examine": "Varies", - "durability": null, - "name": "Ghostly robe", - "archery_ticket_price": "0", "id": "6108", + "name": "Ghostly robe", + "examine": "Varies", + "archery_ticket_price": "0", "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, "equipment_slot": "7" }, { - "remove_head": "true", - "examine": "A ghostly hood, fit for a ghostly head.", - "durability": null, - "name": "Ghostly hood", - "archery_ticket_price": "0", "id": "6109", + "name": "Ghostly hood", + "examine": "A ghostly hood, fit for a ghostly head.", + "archery_ticket_price": "0", "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "remove_head": "true" }, { - "examine": "They seem to fade in and out of existence...", - "durability": null, - "name": "Ghostly gloves", - "archery_ticket_price": "0", "id": "6110", + "name": "Ghostly gloves", + "examine": "They seem to fade in and out of existence...", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, "equipment_slot": "9" }, { - "examine": "Made of a strange, ghostly material...", - "durability": null, - "name": "Ghostly cloak", - "archery_ticket_price": "0", "id": "6111", + "name": "Ghostly cloak", + "examine": "Made of a strange, ghostly material...", + "archery_ticket_price": "0", "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0", + "durability": null, "equipment_slot": "1" }, { - "destroy_message": "Return to the drunken dwarf's drunken relative to get your seeds back.", - "examine": "Kelda hop seeds can only be grown underground!", - "durability": null, + "id": "6112", "name": "Kelda seed", - "tradeable": "false", - "destroy": "true", + "examine": "Kelda hop seeds can only be grown underground!", "archery_ticket_price": "0", - "id": "6112" + "destroy": "true", + "destroy_message": "Return to the drunken dwarf's drunken relative to get your seeds back.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Return to the Keldagrim palace gardener to get your hops back.", - "examine": "A handful of Kelda Hops.", - "durability": null, + "id": "6113", "name": "Kelda hops", - "tradeable": "false", + "examine": "A handful of Kelda Hops.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "0.01", - "archery_ticket_price": "0", - "id": "6113" + "destroy_message": "Return to the Keldagrim palace gardener to get your hops back.", + "durability": null, + "tradeable": "false", + "weight": "0.01" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pint of bluish beer.", - "durability": null, + "id": "6118", "name": "Kelda stout", - "weight": "0.5", + "examine": "A pint of bluish beer.", "archery_ticket_price": "0", - "id": "6118" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "0.5" }, { - "examine": "There is a strange [green/yellow] marking on this stone.", - "durability": null, + "id": "6119", "name": "Square stone", - "weight": "1", - "archery_ticket_price": "0", - "id": "6119" - }, - { "examine": "There is a strange [green/yellow] marking on this stone.", - "durability": null, - "name": "Square stone", - "weight": "1", "archery_ticket_price": "0", - "id": "6120" + "durability": null, + "weight": "1" }, { + "id": "6120", + "name": "Square stone", + "examine": "There is a strange [green/yellow] marking on this stone.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "6122", "name": "A chair", "archery_ticket_price": "0", - "id": "6122", + "durability": null, "equipment_slot": "5" }, { - "shop_price": "1", - "examine": "I need to fill this with beer.", - "grand_exchange_price": "25", - "durability": null, - "name": "Beer glass", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", "id": "6123", - "equipment_slot": "3" + "name": "Beer glass", + "examine": "I need to fill this with beer.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" }, { - "durability": null, + "id": "6124", "name": "Coconut milk", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6124" + "durability": null, + "tradeable": "true" }, { - "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre(2)", - "weight": "1.8", - "archery_ticket_price": "0", "id": "6125", - "equipment_slot": "3" + "name": "Enchanted lyre(2)", + "examine": "This will teleport me to Rellekka when I play it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1.8" }, { - "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre(3)", - "weight": "1.8", - "archery_ticket_price": "0", "id": "6126", - "equipment_slot": "3" - }, - { + "name": "Enchanted lyre(3)", "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre(4)", - "weight": "1.8", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1.8" + }, + { "id": "6127", - "equipment_slot": "3" + "name": "Enchanted lyre(4)", + "examine": "This will teleport me to Rellekka when I play it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1.8" }, { - "remove_head": "true", - "requirements": "{1,40}", - "ge_buy_limit": "100", - "examine": "Protective headwear made from crabs. Better than it sounds.", - "durability": null, - "weight": "2.7", - "absorb": "1,0,3", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "21000", - "name": "Rock-shell helm", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6128", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,6,0,0,0,0" - }, - { - "lendable": "true", - "requirements": "{1,40}", - "remove_sleeves": "true", - "ge_buy_limit": "100", - "grand_exchange_price": "40600", - "durability": null, - "name": "Rock-shell plate", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6129", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,30,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "100", - "examine": "Some tough leggings made from rock crab parts.", - "durability": null, - "weight": "9", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "39400", - "name": "Rock-shell legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6130", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,10,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "100", - "examine": "A helm fit for any Fremennik ranger.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "35800", - "name": "Spined helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6131", - "bonuses": "-6,-6,-6,-6,6,6,6,6,6,0,6,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "35800", - "durability": null, - "name": "Spined helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6132" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "100", - "examine": "A constant reminder that I'm above a Dagannoth in the food chain.", - "durability": null, - "weight": "6", - "absorb": "0,6,3", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "4386", - "name": "Spined body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6133", - "bonuses": "0,0,0,-15,15,40,32,45,20,40,30,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4386", - "durability": null, - "name": "Spined body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6134" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "100", - "examine": "Stylish leg armour for rangers with a lingering smell of raw fish...", - "durability": null, - "weight": "5", - "absorb": "0,4,2", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "2132", - "name": "Spined chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6135", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,10,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2132", - "durability": null, - "name": "Spined chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6136" - }, - { - "remove_head": "true", - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "Make your foes cower by wearing a skull as a helmet!", - "durability": null, - "weight": "1.3", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "29500", - "name": "Skeletal helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6137", - "bonuses": "0,0,0,2,-2,10,9,11,3,0,6,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "29500", - "durability": null, - "name": "Skeletal helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6138" - }, - { - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "The bones in this armour seems to vibrate with a magic quality...", - "durability": null, - "weight": "4.9", - "absorb": "6,3,0", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "27800", - "name": "Skeletal top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6139", - "bonuses": "0,0,0,8,-10,35,25,42,15,0,30,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "27800", - "durability": null, - "name": "Skeletal top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6140" - }, - { - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "A superior set of strengthened slacks for any self respecting seer.", - "durability": null, - "weight": "4", - "absorb": "4,2,0", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "23600", - "name": "Skeletal bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6141", - "bonuses": "0,0,0,6,-7,22,20,24,10,0,10,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "23600", - "durability": null, - "name": "Skeletal bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6142" - }, - { - "lendable": "true", - "ge_buy_limit": "100", - "examine": "Some finely crafted Fremennik boots, made from spined dagannoth hide.", - "grand_exchange_price": "1671", - "durability": null, - "name": "Spined boots", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6143", - "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1671", - "durability": null, - "name": "Spined boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6144" - }, - { - "lendable": "true", - "ge_buy_limit": "100", - "examine": "Some Fremennik boots, made from the shards of a rock crab's shell.", - "grand_exchange_price": "756", - "durability": null, - "name": "Rock-shell boots", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6145", - "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "756", - "durability": null, - "name": "Rock-shell boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6146" - }, - { - "lendable": "true", - "ge_buy_limit": "100", - "examine": "Some finely crafted Fremennik boots, made from the bones of a Wallasalki.", - "grand_exchange_price": "4958", - "durability": null, - "name": "Skeletal boots", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6147", - "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4958", - "durability": null, - "name": "Skeletal boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6148" - }, - { - "lendable": "true", - "ge_buy_limit": "100", - "examine": "Fremennik gloves stitched together from spined dagannoth hide.", - "grand_exchange_price": "955", - "durability": null, - "name": "Spined gloves", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6149", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "955", - "durability": null, - "name": "Spined gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6150" - }, - { - "lendable": "true", - "ge_buy_limit": "100", - "examine": "Fremennik gloves stitched together from rock crab shell shards.", - "grand_exchange_price": "951", - "durability": null, - "name": "Rock-shell gloves", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "6151", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "951", - "durability": null, - "name": "Rock-shell gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6152" - }, - { - "lendable": "true", - "ge_buy_limit": "100", - "examine": "Fremennik gloves stitched together from wallasalki bones fragments.", - "grand_exchange_price": "21800", - "durability": null, - "name": "Skeletal gloves", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6153", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "21800", - "durability": null, - "name": "Skeletal gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6154" - }, - { - "ge_buy_limit": "500", - "examine": "A sturdy piece of dagannoth hide.", - "grand_exchange_price": "3978", - "durability": null, - "name": "Dagannoth hide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6155" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "3978", - "durability": null, - "name": "Dagannoth hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6156" - }, - { - "ge_buy_limit": "100", - "examine": "A spherical chunk of rock-shell.", - "grand_exchange_price": "7371", - "durability": null, - "name": "Rock-shell chunk", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6157" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7371", - "durability": null, - "name": "Rock-shell chunk", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6158" - }, - { - "ge_buy_limit": "100", - "examine": "A curved piece of rock-shell.", - "grand_exchange_price": "11300", - "durability": null, - "name": "Rock-shell shard", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6159" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11300", - "durability": null, - "name": "Rock-shell shard", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6160" - }, - { - "ge_buy_limit": "100", - "examine": "A slim piece of rock-shell.", - "grand_exchange_price": "16100", - "durability": null, - "name": "Rock-shell splinter", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6161" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "16100", - "durability": null, - "name": "Rock-shell splinter", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6162" - }, - { - "ge_buy_limit": "100", - "examine": "A fearsome looking skull.", - "grand_exchange_price": "9859", - "durability": null, - "name": "Skull piece", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6163" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9859", - "durability": null, - "name": "Skull piece", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6164" - }, - { - "ge_buy_limit": "100", - "examine": "A slightly damaged ribcage.", - "grand_exchange_price": "11300", - "durability": null, - "name": "Ribcage piece", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6165" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11300", - "durability": null, - "name": "Ribcage piece", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6166" - }, - { - "ge_buy_limit": "100", - "examine": "An interesting looking bone shard.", - "grand_exchange_price": "10300", - "durability": null, - "name": "Fibula piece", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6167" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10300", - "durability": null, - "name": "Fibula piece", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6168" - }, - { - "ge_buy_limit": "100", - "examine": "A toughened chunk of dagannoth hide.", - "grand_exchange_price": "23400", - "durability": null, - "name": "Circular hide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6169" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "23400", - "durability": null, - "name": "Circular hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6170" - }, - { - "ge_buy_limit": "100", - "examine": "A tattered chunk of dagannoth hide.", - "grand_exchange_price": "502", - "durability": null, - "name": "Flattened hide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6171" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "502", - "durability": null, - "name": "Flattened hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6172" - }, - { - "ge_buy_limit": "100", - "examine": "A weathered chunk of dagannoth hide.", - "grand_exchange_price": "398", - "durability": null, - "name": "Stretched hide", - "tradeable": "true", - "weight": "3.1", - "archery_ticket_price": "0", - "id": "6173" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "398", - "durability": null, - "name": "Stretched hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6174" - }, - { - "durability": null, "name": "Rock-shell helm", - "tradeable": "true", + "examine": "Protective headwear made from crabs. Better than it sounds.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "6175" + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.7" }, { - "examine": "A sturdy body armour made from rock crab pieces.", - "durability": null, + "id": "6129", "name": "Rock-shell plate", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "9", - "id": "6176" + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,30,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}", + "tradeable": "true" }, { - "durability": null, + "id": "6130", "name": "Rock-shell legs", + "examine": "Some tough leggings made from rock crab parts.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6177" + "weight": "9" }, { - "examine": "I need to cook this first.", - "durability": null, - "name": "Raw pheasant", - "weight": "10", + "id": "6131", + "name": "Spined helm", + "examine": "A helm fit for any Fremennik ranger.", + "absorb": "0,3,1", "archery_ticket_price": "0", - "id": "6178" - }, - { - "examine": "I need to cook this first.", + "bonuses": "-6,-6,-6,-6,6,6,6,6,6,0,6,0,0,0,0", "durability": null, - "name": "Raw pheasant", - "weight": "10", - "archery_ticket_price": "0", - "id": "6179" - }, - { - "remove_sleeves": "true", - "examine": "A leather strapped top.", - "durability": null, - "name": "Lederhosen top", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "6180", - "equipment_slot": "4" - }, - { - "examine": "Brown leather shorts with bright white socks?", - "durability": null, - "name": "Lederhosen shorts", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "6181", - "equipment_slot": "7" - }, - { - "remove_head": "true", - "examine": "A hat with a goat's hair attached.", - "durability": null, - "name": "Lederhosen hat", - "weight": "2", - "archery_ticket_price": "0", - "id": "6182", - "equipment_slot": "0" - }, - { - "examine": "I can use this at the Varrock clothes shop.", - "durability": null, - "name": "Frog token", - "archery_ticket_price": "0", - "id": "6183" - }, - { - "remove_sleeves": "true", - "examine": "Very posh!", - "durability": null, - "name": "Prince tunic", - "weight": "2.7", - "archery_ticket_price": "0", - "id": "6184", - "equipment_slot": "4" - }, - { - "examine": "Very posh!", - "durability": null, - "name": "Prince leggings", - "weight": "2", - "archery_ticket_price": "0", - "id": "6185", - "equipment_slot": "7" - }, - { - "remove_sleeves": "true", - "examine": "Very posh!", - "durability": null, - "name": "Princess blouse", - "weight": "2", - "archery_ticket_price": "0", - "id": "6186", - "equipment_slot": "4" - }, - { - "examine": "Very posh!", - "durability": null, - "name": "Princess skirt", - "weight": "2", - "archery_ticket_price": "0", - "id": "6187", - "equipment_slot": "7" - }, - { - "remove_head": "true", - "examine": "Now that's just silly.", - "durability": null, - "name": "Frog mask", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "6188", + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "1" }, { - "examine": "Could there be something valuable in here?", - "durability": null, - "name": "Mystery box", - "weight": "1", + "id": "6132", + "name": "Spined helm", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6133", + "name": "Spined body", + "examine": "A constant reminder that I'm above a Dagannoth in the food chain.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,30,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "6134", + "name": "Spined body", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6135", + "name": "Spined chaps", + "examine": "Stylish leg armour for rangers with a lingering smell of raw fish...", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "6136", + "name": "Spined chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6137", + "name": "Skeletal helm", + "examine": "Make your foes cower by wearing a skull as a helmet!", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,-2,10,9,11,3,0,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,40}-{6,40}", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "6138", + "name": "Skeletal helm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6139", + "name": "Skeletal top", + "examine": "The bones in this armour seems to vibrate with a magic quality...", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,8,-10,35,25,42,15,0,30,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}-{6,40}", + "tradeable": "true", + "weight": "4.9" + }, + { + "id": "6140", + "name": "Skeletal top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6141", + "name": "Skeletal bottoms", + "examine": "A superior set of strengthened slacks for any self respecting seer.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,-7,22,20,24,10,0,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "lendable": "true", + "requirements": "{1,40}-{6,40}", + "tradeable": "true", + "weight": "4" + }, + { + "id": "6142", + "name": "Skeletal bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6143", + "name": "Spined boots", + "examine": "Some finely crafted Fremennik boots, made from spined dagannoth hide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true", + "weight": "3" + }, + { + "id": "6144", + "name": "Spined boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6145", + "name": "Rock-shell boots", + "examine": "Some Fremennik boots, made from the shards of a rock crab's shell.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6146", + "name": "Rock-shell boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6147", + "name": "Skeletal boots", + "examine": "Some finely crafted Fremennik boots, made from the bones of a Wallasalki.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6148", + "name": "Skeletal boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6149", + "name": "Spined gloves", + "examine": "Fremennik gloves stitched together from spined dagannoth hide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true", + "weight": "3" + }, + { + "id": "6150", + "name": "Spined gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6151", + "name": "Rock-shell gloves", + "examine": "Fremennik gloves stitched together from rock crab shell shards.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "6152", + "name": "Rock-shell gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6153", + "name": "Skeletal gloves", + "examine": "Fremennik gloves stitched together from wallasalki bones fragments.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6154", + "name": "Skeletal gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6155", + "name": "Dagannoth hide", + "examine": "A sturdy piece of dagannoth hide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6156", + "name": "Dagannoth hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "6157", + "name": "Rock-shell chunk", + "examine": "A spherical chunk of rock-shell.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3" + }, + { + "id": "6158", + "name": "Rock-shell chunk", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6159", + "name": "Rock-shell shard", + "examine": "A curved piece of rock-shell.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6160", + "name": "Rock-shell shard", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6161", + "name": "Rock-shell splinter", + "examine": "A slim piece of rock-shell.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3" + }, + { + "id": "6162", + "name": "Rock-shell splinter", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6163", + "name": "Skull piece", + "examine": "A fearsome looking skull.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6164", + "name": "Skull piece", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6165", + "name": "Ribcage piece", + "examine": "A slightly damaged ribcage.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6166", + "name": "Ribcage piece", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6167", + "name": "Fibula piece", + "examine": "An interesting looking bone shard.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6168", + "name": "Fibula piece", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6169", + "name": "Circular hide", + "examine": "A toughened chunk of dagannoth hide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6170", + "name": "Circular hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6171", + "name": "Flattened hide", + "examine": "A tattered chunk of dagannoth hide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6172", + "name": "Flattened hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6173", + "name": "Stretched hide", + "examine": "A weathered chunk of dagannoth hide.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "3.1" + }, + { + "id": "6174", + "name": "Stretched hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6175", + "name": "Rock-shell helm", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6176", + "name": "Rock-shell plate", + "examine": "A sturdy body armour made from rock crab pieces.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "9" + }, + { + "id": "6177", + "name": "Rock-shell legs", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6178", + "name": "Raw pheasant", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "weight": "10" + }, + { + "id": "6179", + "name": "Raw pheasant", + "examine": "I need to cook this first.", + "archery_ticket_price": "0", + "durability": null, + "weight": "10" + }, + { + "id": "6180", + "name": "Lederhosen top", + "examine": "A leather strapped top.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2.2" + }, + { + "id": "6181", + "name": "Lederhosen shorts", + "examine": "Brown leather shorts with bright white socks?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "2.2" + }, + { + "id": "6182", + "name": "Lederhosen hat", + "examine": "A hat with a goat's hair attached.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "2" + }, + { + "id": "6183", + "name": "Frog token", + "examine": "I can use this at the Varrock clothes shop.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6184", + "name": "Prince tunic", + "examine": "Very posh!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2.7" + }, + { + "id": "6185", + "name": "Prince leggings", + "examine": "Very posh!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "2" + }, + { + "id": "6186", + "name": "Princess blouse", + "examine": "Very posh!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2" + }, + { + "id": "6187", + "name": "Princess skirt", + "examine": "Very posh!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "2" + }, + { + "id": "6188", + "name": "Frog mask", + "examine": "Now that's just silly.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "weight": "0.4" + }, + { "id": "6199", - "point_price": "2" - }, - { - "destroy_message": "A ghastly fish", - "examine": "A raw...fish? Is this a fish??", - "durability": null, - "name": "Raw fishlike thing", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "name": "Mystery box", + "examine": "Could there be something valuable in here?", "archery_ticket_price": "0", - "id": "6200" + "durability": null, + "point_price": "2", + "weight": "1" }, { - "examine": "Fish-tastic!", + "id": "6200", + "name": "Raw fishlike thing", + "examine": "A raw...fish? Is this a fish??", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "A ghastly fish", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "6201", "name": "Picture", + "examine": "Fish-tastic!", "archery_ticket_price": "0", - "id": "6201" + "durability": null }, { - "destroy_message": "A ghastly fish", - "examine": "It's a fish-like thing that appears to already be cooked. It looks disgusting.", - "durability": null, + "id": "6202", "name": "Fishlike thing", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "It's a fish-like thing that appears to already be cooked. It looks disgusting.", "archery_ticket_price": "0", - "id": "6202" + "destroy": "true", + "destroy_message": "A ghastly fish", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "A ghastly fish", - "examine": "A raw...fish? Is this a fish??", - "durability": null, + "id": "6204", "name": "Raw fishlike thing", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A raw...fish? Is this a fish??", "archery_ticket_price": "0", - "id": "6204" - }, - { + "destroy": "true", "destroy_message": "A ghastly fish", - "examine": "It's a fish-like thing that appears to already be cooked. It looks disgusting.", "durability": null, - "name": "Fishlike thing", "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6206" + "weight": "1" }, { - "examine": "It's an amulet of Man speak. It makes vague grunting noises.", - "durability": null, - "name": "Man speak amulet", + "id": "6206", + "name": "Fishlike thing", + "examine": "It's a fish-like thing that appears to already be cooked. It looks disgusting.", "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "A ghastly fish", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { "id": "6208", + "name": "Man speak amulet", + "examine": "It's an amulet of Man speak. It makes vague grunting noises.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "shop_price": "40", - "examine": "Useful for catching small fish.", - "grand_exchange_price": "433", - "durability": null, + "id": "6209", "name": "Small fishing net", - "tradeable": "true", - "weight": "4.5", + "examine": "Useful for catching small fish.", "archery_ticket_price": "0", - "id": "6209" + "durability": null, + "shop_price": "40", + "tradeable": "true", + "weight": "4.5" }, { - "ge_buy_limit": "1000", + "id": "6211", + "name": "Teak pyre logs", "examine": "Teak logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "3365", - "durability": null, - "name": "Teak pyre logs", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "6211" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "3365", - "durability": null, + "id": "6212", "name": "Teak pyre logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6212" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "6213", + "name": "Mahogany pyre log", "examine": "Mahogany logs prepared with sacred oil for a funeral pyre.", - "grand_exchange_price": "3574", - "durability": null, - "name": "Mahogany pyre log", - "tradeable": "true", - "weight": "1.3", "archery_ticket_price": "0", - "id": "6213" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "3574", - "durability": null, - "name": "Mahogany pyre log", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6214" + "weight": "1.3" }, { - "requirements": "{1,25}-{6,25}", - "ge_buy_limit": "100", - "examine": "A scary broodoo shield.", - "durability": null, - "weight": "5.4", - "absorb": "4,2,0", - "equipment_slot": "5", - "grand_exchange_price": "2007", - "name": "Broodoo shield (10)", - "tradeable": "true", + "id": "6214", + "name": "Mahogany pyre log", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { "id": "6215", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2007", - "durability": null, "name": "Broodoo shield (10)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6216" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (9)", - "tradeable": "true", - "weight": "5.4", + "id": "6216", + "name": "Broodoo shield (10)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6217", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (9)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6218" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (8)", - "tradeable": "true", - "weight": "5.4", + "id": "6218", + "name": "Broodoo shield (9)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6219", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (8)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6220" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (7)", - "tradeable": "true", - "weight": "5.4", + "id": "6220", + "name": "Broodoo shield (8)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6221", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (7)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6222" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (6)", - "tradeable": "true", - "weight": "5.4", + "id": "6222", + "name": "Broodoo shield (7)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6223", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (6)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6224" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (5)", - "tradeable": "true", - "weight": "5.4", + "id": "6224", + "name": "Broodoo shield (6)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6225", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (5)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6226" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (4)", - "tradeable": "true", - "weight": "5.4", + "id": "6226", + "name": "Broodoo shield (5)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6227", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (4)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6228" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (3)", - "tradeable": "true", - "weight": "5.4", + "id": "6228", + "name": "Broodoo shield (4)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6229", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (3)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6230" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (2)", - "tradeable": "true", - "weight": "5.4", + "id": "6230", + "name": "Broodoo shield (3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6231", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (2)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6232" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (1)", - "tradeable": "true", - "weight": "5.4", + "id": "6232", + "name": "Broodoo shield (2)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6233", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (1)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6234" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "ge_buy_limit": "100", - "examine": "A scary broodoo shield.", - "durability": null, - "weight": "5.4", - "absorb": "4,2,0", - "equipment_slot": "5", - "grand_exchange_price": "2572", - "name": "Broodoo shield", - "tradeable": "true", + "id": "6234", + "name": "Broodoo shield (1)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6235", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2572", - "durability": null, "name": "Broodoo shield", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6236" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "ge_buy_limit": "100", - "examine": "A scary broodoo shield.", - "durability": null, - "weight": "5.4", - "absorb": "4,2,0", - "equipment_slot": "5", - "grand_exchange_price": "2200", - "name": "Broodoo shield (10)", - "tradeable": "true", + "id": "6236", + "name": "Broodoo shield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6237", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2200", - "durability": null, "name": "Broodoo shield (10)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6238" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (9)", - "tradeable": "true", - "weight": "5.4", + "id": "6238", + "name": "Broodoo shield (10)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6239", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (9)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6240" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (8)", - "tradeable": "true", - "weight": "5.4", + "id": "6240", + "name": "Broodoo shield (9)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6241", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (8)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6242" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (7)", - "tradeable": "true", - "weight": "5.4", + "id": "6242", + "name": "Broodoo shield (8)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6243", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (7)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6244" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (6)", - "tradeable": "true", - "weight": "5.4", + "id": "6244", + "name": "Broodoo shield (7)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6245", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (6)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6246" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (5)", - "tradeable": "true", - "weight": "5.4", + "id": "6246", + "name": "Broodoo shield (6)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6247", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (5)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6248" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (4)", - "tradeable": "true", - "weight": "5.4", + "id": "6248", + "name": "Broodoo shield (5)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6249", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (4)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6250" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (3)", - "tradeable": "true", - "weight": "5.4", + "id": "6250", + "name": "Broodoo shield (4)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6251", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (3)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6252" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (2)", - "tradeable": "true", - "weight": "5.4", + "id": "6252", + "name": "Broodoo shield (3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6253", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (2)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6254" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (1)", - "tradeable": "true", - "weight": "5.4", + "id": "6254", + "name": "Broodoo shield (2)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6255", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, "name": "Broodoo shield (1)", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6256" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "ge_buy_limit": "100", - "examine": "A scary broodoo shield.", - "durability": null, - "weight": "5.4", - "absorb": "4,2,0", - "equipment_slot": "5", - "grand_exchange_price": "2731", - "name": "Broodoo shield", - "tradeable": "true", + "id": "6256", + "name": "Broodoo shield (1)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6257", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2731", - "durability": null, "name": "Broodoo shield", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6258" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,25}-{6,25}", - "ge_buy_limit": "100", - "examine": "A scary broodoo shield.", - "durability": null, - "weight": "5.4", - "absorb": "4,2,0", - "equipment_slot": "5", - "grand_exchange_price": "1494", - "name": "Broodoo shield (10)", - "tradeable": "true", + "id": "6258", + "name": "Broodoo shield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6259", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" - }, - { - "attack_anims": "7060", - "ge_buy_limit": "100", - "grand_exchange_price": "1494", - "durability": null, "name": "Broodoo shield (10)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6260" - }, - { - "requirements": "{1,25}-{6,25}", "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (9)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6261", "absorb": "4,2,0", + "archery_ticket_price": "0", "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { "durability": null, - "name": "Broodoo shield (9)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6262" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (8)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6263", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (8)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6264" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (7)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6265", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (7)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6266" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (6)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6267", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (6)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6268" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (5)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6269", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6270" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (4)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6271", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6272" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (3)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6273", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6274" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (2)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6275", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6276" - }, - { - "requirements": "{1,25}-{6,25}", - "examine": "A scary broodoo shield.", - "grand_exchange_price": "1", - "durability": null, - "name": "Broodoo shield (1)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "6277", - "absorb": "4,2,0", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "durability": null, - "name": "Broodoo shield (1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6278" - }, - { - "requirements": "{1,25}-{6,25}", - "ge_buy_limit": "100", - "examine": "A scary broodoo shield.", - "durability": null, - "weight": "5.4", - "absorb": "4,2,0", "equipment_slot": "5", - "grand_exchange_price": "2957", - "name": "Broodoo shield", + "ge_buy_limit": "100", + "requirements": "{1,25}-{6,25}", "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6260", + "name": "Broodoo shield (10)", "archery_ticket_price": "0", + "attack_anims": "7060", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6261", + "name": "Broodoo shield (9)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6262", + "name": "Broodoo shield (9)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6263", + "name": "Broodoo shield (8)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6264", + "name": "Broodoo shield (8)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6265", + "name": "Broodoo shield (7)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6266", + "name": "Broodoo shield (7)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6267", + "name": "Broodoo shield (6)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6268", + "name": "Broodoo shield (6)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6269", + "name": "Broodoo shield (5)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6270", + "name": "Broodoo shield (5)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6271", + "name": "Broodoo shield (4)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6272", + "name": "Broodoo shield (4)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6273", + "name": "Broodoo shield (3)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6274", + "name": "Broodoo shield (3)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6275", + "name": "Broodoo shield (2)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6276", + "name": "Broodoo shield (2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6277", + "name": "Broodoo shield (1)", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "6278", + "name": "Broodoo shield (1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6279", - "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2957", - "durability": null, "name": "Broodoo shield", - "tradeable": "true", + "examine": "A scary broodoo shield.", + "absorb": "4,2,0", "archery_ticket_price": "0", - "id": "6280" + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,25}-{6,25}", + "tradeable": "true", + "weight": "5.4" }, { - "ge_buy_limit": "100", - "examine": "A wooden pole for use in primitive construction.", - "grand_exchange_price": "1", - "durability": null, - "name": "Thatch spar light", - "tradeable": "true", - "weight": "0.1", + "id": "6280", + "name": "Broodoo shield", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6281", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, "name": "Thatch spar light", - "tradeable": "true", + "examine": "A wooden pole for use in primitive construction.", "archery_ticket_price": "0", - "id": "6282" + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "examine": "A wooden pole for use in primitive construction.", - "grand_exchange_price": "2", - "durability": null, - "name": "Thatch spar med", - "tradeable": "true", - "weight": "0.1", + "id": "6282", + "name": "Thatch spar light", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6283", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2", - "durability": null, "name": "Thatch spar med", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6284" - }, - { - "ge_buy_limit": "100", "examine": "A wooden pole for use in primitive construction.", - "grand_exchange_price": "3", - "durability": null, - "name": "Thatch spar dense", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "6284", + "name": "Thatch spar med", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6285", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3", - "durability": null, "name": "Thatch spar dense", - "tradeable": "true", + "examine": "A wooden pole for use in primitive construction.", "archery_ticket_price": "0", - "id": "6286" + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "10000", + "id": "6286", + "name": "Thatch spar dense", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6287", + "name": "Snake hide", "examine": "Scaly but not slimy!", - "grand_exchange_price": "2084", - "durability": null, - "name": "Snake hide", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "6287" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "2084", - "durability": null, + "id": "6288", "name": "Snake hide", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6288" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "6289", + "name": "Snakeskin", "examine": "Scaley but not slimy!", - "grand_exchange_price": "2019", - "durability": null, - "name": "Snakeskin", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "6289" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "2019", - "durability": null, - "name": "Snakeskin", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6290" + "weight": "0.5" }, { - "ge_buy_limit": "1000", + "id": "6290", + "name": "Snakeskin", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6291", + "name": "Spider carcass", "examine": "Its creeping days are over!", - "grand_exchange_price": "1949", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "6292", "name": "Spider carcass", - "tradeable": "true", - "weight": "0.8", "archery_ticket_price": "0", - "id": "6291" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1949", "durability": null, - "name": "Spider carcass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6292" + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "shop_price": "50", - "ge_buy_limit": "1000", + "id": "6293", + "name": "Spider on stick", "examine": "Raw: A raw spider threaded onto a skewer stick.Cooked: A nicely roasted spider threaded onto a skewer stick.", - "grand_exchange_price": "207", - "durability": null, - "name": "Spider on stick", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "6293" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "207", - "durability": null, - "name": "Spider on stick", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6294" - }, - { - "shop_price": "40", - "ge_buy_limit": "1000", - "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", - "grand_exchange_price": "106", - "durability": null, - "name": "Spider on shaft", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6295" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "106", - "durability": null, - "name": "Spider on shaft", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6296" - }, - { "shop_price": "50", - "ge_buy_limit": "1000", - "examine": "Raw: A raw spider threaded onto a skewer stick.Cooked: A nicely roasted spider threaded onto a skewer stick.", - "grand_exchange_price": "54", - "durability": null, - "name": "Spider on stick", "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "6297" + "weight": "0.9" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "54", - "durability": null, + "id": "6294", "name": "Spider on stick", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6298" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "shop_price": "40", - "ge_buy_limit": "1000", + "id": "6295", + "name": "Spider on shaft", "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", - "grand_exchange_price": "78", - "durability": null, - "name": "Spider on shaft", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "6299" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "78", - "durability": null, - "name": "Spider on shaft", + "shop_price": "40", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6300" + "weight": "1" }, { + "id": "6296", + "name": "Spider on shaft", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6297", + "name": "Spider on stick", + "examine": "Raw: A raw spider threaded onto a skewer stick.Cooked: A nicely roasted spider threaded onto a skewer stick.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "50", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "6298", + "name": "Spider on stick", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6299", + "name": "Spider on shaft", + "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "40", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6300", + "name": "Spider on shaft", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6302", "name": "Burnt spider", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6302" + "durability": null, + "tradeable": "true" }, { - "shop_price": "40", + "id": "6303", + "name": "Spider on shaft", "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", - "grand_exchange_price": "106", - "durability": null, - "name": "Spider on shaft", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "6303" + "durability": null, + "shop_price": "40", + "tradeable": "true", + "weight": "1" }, { - "durability": null, + "id": "6304", "name": "Spider on shaft", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6304" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A sharp pointed stick, quite resistant to fire.", - "grand_exchange_price": "1", - "durability": null, + "id": "6305", "name": "Skewer stick", - "tradeable": "true", + "examine": "A sharp pointed stick, quite resistant to fire.", "archery_ticket_price": "0", - "id": "6305" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Karamja currency.", - "grand_exchange_price": "2", - "durability": null, + "id": "6306", "name": "Trading sticks", - "tradeable": "true", + "examine": "Karamja currency.", "archery_ticket_price": "0", - "id": "6306" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "6311", + "name": "Gout tuber", "examine": "Plant this in a herb patch to grow Goutweed.", - "grand_exchange_price": "6991", - "durability": null, - "name": "Gout tuber", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "6311" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "6991", - "durability": null, + "id": "6312", "name": "Gout tuber", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6312" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "500", - "ge_buy_limit": "100", - "examine": "A jungle specific slashing device.", - "durability": null, - "weight": "1.35", - "weapon_interface": "6", - "render_anim": "2554", - "equipment_slot": "3", - "grand_exchange_price": "179", - "name": "Opal machete", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6313", - "bonuses": "0,8,-2,0,0,0,1,1,0,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "179", - "durability": null, "name": "Opal machete", - "tradeable": "true", + "examine": "A jungle specific slashing device.", "archery_ticket_price": "0", - "id": "6314" + "bonuses": "0,8,-2,0,0,0,1,1,0,0,0,4,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2554", + "shop_price": "500", + "tradeable": "true", + "weapon_interface": "6", + "weight": "1.35" }, { - "shop_price": "1000", - "ge_buy_limit": "100", - "examine": "A jungle specific slashing device.", - "durability": null, - "weapon_interface": "6", - "render_anim": "2554", - "equipment_slot": "3", - "grand_exchange_price": "4473", - "name": "Jade machete", - "tradeable": "true", + "id": "6314", + "name": "Opal machete", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6315", - "bonuses": "0,11,-2,0,0,0,1,1,0,0,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4473", - "durability": null, "name": "Jade machete", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6316" - }, - { - "shop_price": "2000", - "ge_buy_limit": "100", "examine": "A jungle specific slashing device.", + "archery_ticket_price": "0", + "bonuses": "0,11,-2,0,0,0,1,1,0,0,0,6,0,0,0", "durability": null, - "weight": "1.3", - "attack_speed": "4", - "weapon_interface": "6", - "render_anim": "2554", "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "8774", - "name": "Red topaz machete", + "ge_buy_limit": "100", + "render_anim": "2554", + "shop_price": "1000", "tradeable": "true", + "weapon_interface": "6" + }, + { + "id": "6316", + "name": "Jade machete", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6317", - "bonuses": "0,16,-2,0,0,0,1,1,0,0,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8774", - "durability": null, "name": "Red topaz machete", - "tradeable": "true", + "examine": "A jungle specific slashing device.", "archery_ticket_price": "0", - "id": "6318" - }, - { - "ge_buy_limit": "100", - "examine": "A giant mosquito's proboscis: aerodynamic, sharp and pointy!", - "grand_exchange_price": "9733", + "attack_anims": "390,390,381,390", + "attack_speed": "4", + "bonuses": "0,16,-2,0,0,0,1,1,0,0,0,10,0,0,0", "durability": null, - "name": "Proboscis", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2554", + "shop_price": "2000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6319" + "weapon_interface": "6", + "weight": "1.3" }, { + "id": "6318", + "name": "Red topaz machete", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6319", + "name": "Proboscis", + "examine": "A giant mosquito's proboscis: aerodynamic, sharp and pointy!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6322", + "name": "Snakeskin body", + "examine": "Made from 100% real snakeskin.", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,12,25,28,32,15,35,30,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", "requirements": "{1,30}-{4,30}", "shop_price": "1588", - "ge_buy_limit": "100", - "examine": "Made from 100% real snakeskin.", - "durability": null, - "weight": "10", - "absorb": "0,4,2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "23100", - "name": "Snakeskin body", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6322", - "bonuses": "0,0,0,-5,12,25,28,32,15,35,30,0,0,0,0" + "weight": "10" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "23100", - "durability": null, + "id": "6323", "name": "Snakeskin body", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6323" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,30}-{4,30}", - "ge_buy_limit": "100", - "examine": "Made from 100% real snake.", - "durability": null, - "weight": "3.6", - "absorb": "0,3,1", - "equipment_slot": "7", - "grand_exchange_price": "702", - "name": "Snakeskin chaps", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6324", - "bonuses": "0,0,0,-5,6,8,8,10,4,10,10,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "702", - "durability": null, "name": "Snakeskin chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6325" - }, - { - "remove_head": "true", - "requirements": "{1,30}-{4,30}", - "ge_buy_limit": "100", - "examine": "Lightweight head protection.", - "durability": null, - "weight": "0.9", - "absorb": "0,2,1", - "equipment_slot": "0", - "grand_exchange_price": "871", - "name": "Snakeskin bandana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6326", - "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "871", - "durability": null, - "name": "Snakeskin bandana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6327" - }, - { - "requirements": "{1,30}-{4,30}", - "ge_buy_limit": "100", - "examine": "Made from snakes.", - "grand_exchange_price": "10800", - "durability": null, - "name": "Snakeskin boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "6328", - "bonuses": "0,0,0,-10,3,1,1,2,1,0,9,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10800", - "durability": null, - "name": "Snakeskin boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6329" - }, - { - "requirements": "{1,30}-{4,30}", - "ge_buy_limit": "10000", "examine": "Made from 100% real snake.", - "grand_exchange_price": "914", - "durability": null, - "name": "Snakeskin v'brace", - "tradeable": "true", - "weight": "1", + "absorb": "0,3,1", "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,6,8,8,10,4,10,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,30}-{4,30}", + "tradeable": "true", + "weight": "3.6" + }, + { + "id": "6325", + "name": "Snakeskin chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6326", + "name": "Snakeskin bandana", + "examine": "Lightweight head protection.", + "absorb": "0,2,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "requirements": "{1,30}-{4,30}", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "6327", + "name": "Snakeskin bandana", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6328", + "name": "Snakeskin boots", + "examine": "Made from snakes.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,3,1,1,2,1,0,9,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "requirements": "{1,30}-{4,30}", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "6329", + "name": "Snakeskin boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6330", - "bonuses": "0,0,0,-5,6,2,2,2,1,0,1,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "914", - "durability": null, "name": "Snakeskin v'brace", - "tradeable": "true", + "examine": "Made from 100% real snake.", "archery_ticket_price": "0", - "id": "6331" + "bonuses": "0,0,0,-5,6,2,2,2,1,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10000", + "requirements": "{1,30}-{4,30}", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "25000", - "examine": "Some well-cut mahogany logs.", - "grand_exchange_price": "503", + "id": "6331", + "name": "Snakeskin v'brace", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6332", "name": "Mahogany logs", - "tradeable": "true", - "weight": "1.33", + "examine": "Some well-cut mahogany logs.", "archery_ticket_price": "0", - "id": "6332" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true", + "weight": "1.33" }, { - "ge_buy_limit": "25000", + "id": "6333", + "name": "Teak logs", "examine": "Some well-cut teak logs.", - "grand_exchange_price": "92", - "durability": null, - "name": "Teak logs", - "tradeable": "true", - "weight": "1.35", "archery_ticket_price": "0", - "id": "6333" - }, - { + "durability": null, "ge_buy_limit": "25000", - "grand_exchange_price": "92", - "durability": null, + "tradeable": "true", + "weight": "1.35" + }, + { + "id": "6334", "name": "Teak logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6334" + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A ceremonial wooden mask.", - "grand_exchange_price": "1306", - "durability": null, - "name": "Tribal mask", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "6335", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1306", - "durability": null, "name": "Tribal mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6336" - }, - { - "ge_buy_limit": "100", "examine": "A ceremonial wooden mask.", - "grand_exchange_price": "997", - "durability": null, - "name": "Tribal mask", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" + }, + { + "id": "6336", + "name": "Tribal mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6337", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "997", - "durability": null, "name": "Tribal mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6338" - }, - { - "ge_buy_limit": "100", "examine": "A ceremonial wooden mask.", - "grand_exchange_price": "1018", - "durability": null, - "name": "Tribal mask", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" + }, + { + "id": "6338", + "name": "Tribal mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6339", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1018", - "durability": null, "name": "Tribal mask", - "tradeable": "true", + "examine": "A ceremonial wooden mask.", "archery_ticket_price": "0", - "id": "6340" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "remove_sleeves": "true", - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "Local dress.", - "grand_exchange_price": "3331", - "durability": null, - "name": "Tribal top", - "tradeable": "true", - "weight": "1", + "id": "6340", + "name": "Tribal mask", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6341", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3331", - "durability": null, "name": "Tribal top", - "tradeable": "true", + "examine": "Local dress.", "archery_ticket_price": "0", - "id": "6342" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "250", - "ge_buy_limit": "100", - "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "1382", - "durability": null, - "name": "Villager robe", - "tradeable": "true", - "weight": "2", + "id": "6342", + "name": "Tribal top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6343", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1382", - "durability": null, "name": "Villager robe", - "tradeable": "true", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", "archery_ticket_price": "0", - "id": "6344" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "250", + "tradeable": "true", + "weight": "2" }, { - "shop_price": "200", - "ge_buy_limit": "100", - "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "2337", - "durability": null, - "name": "Villager hat", - "tradeable": "true", - "weight": "1", + "id": "6344", + "name": "Villager robe", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6345", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2337", - "durability": null, "name": "Villager hat", - "tradeable": "true", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", "archery_ticket_price": "0", - "id": "6346" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "150", - "ge_buy_limit": "100", - "examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.", - "grand_exchange_price": "734", - "durability": null, - "name": "Villager armband", - "tradeable": "true", - "weight": "0.5", + "id": "6346", + "name": "Villager hat", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6347", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "734", - "durability": null, "name": "Villager armband", - "tradeable": "true", + "examine": "A brown armband, as worn by the Tai Bwo Wannai locals.", "archery_ticket_price": "0", - "id": "6348" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "shop_price": "150", + "tradeable": "true", + "weight": "0.5" }, { - "shop_price": "100", - "ge_buy_limit": "100", - "examine": "A brightly coloured pair of local sandals.", - "grand_exchange_price": "2793", - "durability": null, - "name": "Villager sandals", - "tradeable": "true", - "weight": "0.6", + "id": "6348", + "name": "Villager armband", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6349", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2793", - "durability": null, "name": "Villager sandals", - "tradeable": "true", + "examine": "A brightly coloured pair of local sandals.", "archery_ticket_price": "0", - "id": "6350" + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "100", + "tradeable": "true", + "weight": "0.6" }, { - "remove_sleeves": "true", - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "Local dress.", - "grand_exchange_price": "3171", - "durability": null, - "name": "Tribal top", - "tradeable": "true", - "weight": "1", + "id": "6350", + "name": "Villager sandals", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6351", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3171", - "durability": null, "name": "Tribal top", - "tradeable": "true", + "examine": "Local dress.", "archery_ticket_price": "0", - "id": "6352" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "250", - "ge_buy_limit": "100", - "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "1416", - "durability": null, - "name": "Villager robe", - "tradeable": "true", - "weight": "2", + "id": "6352", + "name": "Tribal top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6353", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1416", - "durability": null, "name": "Villager robe", - "tradeable": "true", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", "archery_ticket_price": "0", - "id": "6354" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "250", + "tradeable": "true", + "weight": "2" }, { - "shop_price": "200", - "ge_buy_limit": "100", - "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "2785", - "durability": null, - "name": "Villager hat", - "tradeable": "true", - "weight": "1", + "id": "6354", + "name": "Villager robe", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6355", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2785", - "durability": null, "name": "Villager hat", - "tradeable": "true", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", "archery_ticket_price": "0", - "id": "6356" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "100", - "ge_buy_limit": "100", - "examine": "A brightly coloured pair of local sandals.", - "grand_exchange_price": "944", - "durability": null, - "name": "Villager sandals", - "tradeable": "true", - "weight": "0.6", + "id": "6356", + "name": "Villager hat", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6357", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "944", - "durability": null, "name": "Villager sandals", - "tradeable": "true", + "examine": "A brightly coloured pair of local sandals.", "archery_ticket_price": "0", - "id": "6358" + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "100", + "tradeable": "true", + "weight": "0.6" }, { - "shop_price": "150", - "ge_buy_limit": "100", - "examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.", - "grand_exchange_price": "672", - "durability": null, - "name": "Villager armband", - "tradeable": "true", - "weight": "0.5", + "id": "6358", + "name": "Villager sandals", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6359", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "672", - "durability": null, "name": "Villager armband", - "tradeable": "true", + "examine": "A blue armband, as worn by the Tai Bwo Wannai locals.", "archery_ticket_price": "0", - "id": "6360" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "shop_price": "150", + "tradeable": "true", + "weight": "0.5" }, { - "remove_sleeves": "true", - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "Local dress.", - "grand_exchange_price": "2484", - "durability": null, - "name": "Tribal top", - "tradeable": "true", - "weight": "1", + "id": "6360", + "name": "Villager armband", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6361", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2484", - "durability": null, "name": "Tribal top", - "tradeable": "true", + "examine": "Local dress.", "archery_ticket_price": "0", - "id": "6362" - }, - { - "shop_price": "250", - "ge_buy_limit": "100", - "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "499", "durability": null, - "name": "Villager robe", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "6363", - "equipment_slot": "7" - }, - { + "equipment_slot": "4", "ge_buy_limit": "100", - "grand_exchange_price": "499", - "durability": null, - "name": "Villager robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6364" - }, - { - "shop_price": "200", - "ge_buy_limit": "100", - "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "2440", - "durability": null, - "name": "Villager hat", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6365", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2440", - "durability": null, - "name": "Villager hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6366" - }, - { - "shop_price": "100", - "ge_buy_limit": "100", - "examine": "A brightly coloured pair of local sandals.", - "grand_exchange_price": "1479", - "durability": null, - "name": "Villager sandals", - "tradeable": "true", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "6367", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1479", - "durability": null, - "name": "Villager sandals", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6368" - }, - { - "shop_price": "150", - "ge_buy_limit": "100", - "examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.", - "grand_exchange_price": "823", - "durability": null, - "name": "Villager armband", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6369", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "823", - "durability": null, - "name": "Villager armband", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6370" - }, - { "remove_sleeves": "true", "shop_price": "300", - "ge_buy_limit": "100", - "examine": "Local dress.", - "grand_exchange_price": "2683", - "durability": null, - "name": "Tribal top", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6371", - "equipment_slot": "4" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2683", - "durability": null, + "id": "6362", "name": "Tribal top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6372" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "250", - "ge_buy_limit": "100", + "id": "6363", + "name": "Villager robe", "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "331", - "durability": null, - "name": "Villager robe", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "6373", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "250", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "331", - "durability": null, + "id": "6364", "name": "Villager robe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6374" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "200", - "ge_buy_limit": "100", + "id": "6365", + "name": "Villager hat", "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", - "grand_exchange_price": "3010", - "durability": null, - "name": "Villager hat", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "6375", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3010", - "durability": null, + "id": "6366", "name": "Villager hat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6376" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "100", - "ge_buy_limit": "100", + "id": "6367", + "name": "Villager sandals", "examine": "A brightly coloured pair of local sandals.", - "grand_exchange_price": "2310", - "durability": null, - "name": "Villager sandals", - "tradeable": "true", - "weight": "0.6", "archery_ticket_price": "0", - "id": "6377", - "equipment_slot": "10" - }, - { + "durability": null, + "equipment_slot": "10", "ge_buy_limit": "100", - "grand_exchange_price": "2310", - "durability": null, - "name": "Villager sandals", + "shop_price": "100", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6378" + "weight": "0.6" }, { + "id": "6368", + "name": "Villager sandals", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6369", + "name": "Villager armband", + "examine": "A yellow armband, as worn by the Tai Bwo Wannai locals.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", "shop_price": "150", - "ge_buy_limit": "100", - "examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.", - "grand_exchange_price": "1697", - "durability": null, - "name": "Villager armband", "tradeable": "true", - "weight": "0.5", + "weight": "0.5" + }, + { + "id": "6370", + "name": "Villager armband", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6371", + "name": "Tribal top", + "examine": "Local dress.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6372", + "name": "Tribal top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6373", + "name": "Villager robe", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "250", + "tradeable": "true", + "weight": "2" + }, + { + "id": "6374", + "name": "Villager robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6375", + "name": "Villager hat", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6376", + "name": "Villager hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6377", + "name": "Villager sandals", + "examine": "A brightly coloured pair of local sandals.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "100", + "tradeable": "true", + "weight": "0.6" + }, + { + "id": "6378", + "name": "Villager sandals", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6379", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1697", - "durability": null, "name": "Villager armband", - "tradeable": "true", + "examine": "A pink armband, as worn by the Tai Bwo Wannai locals.", "archery_ticket_price": "0", - "id": "6380" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "shop_price": "150", + "tradeable": "true", + "weight": "0.5" }, { - "shop_price": "24", - "ge_buy_limit": "100", - "examine": "A fez hat. Juss like that.", - "grand_exchange_price": "690", - "durability": null, - "name": "Fez", - "tradeable": "true", + "id": "6380", + "name": "Villager armband", "archery_ticket_price": "0", - "hat": true, + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6382", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "690", - "durability": null, "name": "Fez", - "tradeable": "true", + "examine": "A fez hat. Juss like that.", "archery_ticket_price": "0", - "id": "6383" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "hat": true, + "shop_price": "24", + "tradeable": "true" }, { - "remove_sleeves": "true", - "shop_price": "15", - "ge_buy_limit": "100", - "examine": "A bit itchy.", - "grand_exchange_price": "649", - "durability": null, - "name": "Desert top", - "tradeable": "true", - "weight": "1", + "id": "6383", + "name": "Fez", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6384", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "649", - "durability": null, "name": "Desert top", - "tradeable": "true", + "examine": "A bit itchy.", "archery_ticket_price": "0", - "id": "6385" - }, - { - "shop_price": "25", - "ge_buy_limit": "100", - "examine": "Has a coarse hard wearing texture.", - "grand_exchange_price": "533", "durability": null, - "name": "Desert robes", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6386", - "equipment_slot": "7" - }, - { + "equipment_slot": "4", "ge_buy_limit": "100", - "grand_exchange_price": "533", - "durability": null, - "name": "Desert robes", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6387" - }, - { "remove_sleeves": "true", "shop_price": "15", - "ge_buy_limit": "100", - "examine": "A bit itchy.", - "grand_exchange_price": "1016", - "durability": null, - "name": "Desert top", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6388", - "equipment_slot": "4" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1016", - "durability": null, + "id": "6385", "name": "Desert top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6389" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6386", + "name": "Desert robes", + "examine": "Has a coarse hard wearing texture.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", "shop_price": "25", - "ge_buy_limit": "100", - "examine": "Better than factor 50 sun cream.", - "grand_exchange_price": "515", - "durability": null, - "name": "Desert legs", - "tradeable": "true", + "tradeable": "true" + }, + { + "id": "6387", + "name": "Desert robes", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6388", + "name": "Desert top", + "examine": "A bit itchy.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "15", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6389", + "name": "Desert top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6390", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "515", - "durability": null, "name": "Desert legs", - "tradeable": "true", + "examine": "Better than factor 50 sun cream.", "archery_ticket_price": "0", - "id": "6391" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "25", + "tradeable": "true" }, { - "remove_head": "true", - "shop_price": "35", - "ge_buy_limit": "100", - "examine": "Good for keeping the sun off my neck.", - "grand_exchange_price": "531", - "durability": null, - "name": "Menap headgear", - "tradeable": "true", + "id": "6391", + "name": "Desert legs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6392", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "531", - "durability": null, "name": "Menap headgear", - "tradeable": "true", + "examine": "Good for keeping the sun off my neck.", "archery_ticket_price": "0", - "id": "6393" - }, - { - "remove_sleeves": "true", - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Colourful.", - "grand_exchange_price": "650", "durability": null, - "name": "Menaphite top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6394", - "equipment_slot": "4" - }, - { + "equipment_slot": "0", "ge_buy_limit": "100", - "grand_exchange_price": "650", - "durability": null, - "name": "Menaphite top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6395" - }, - { - "shop_price": "40", - "ge_buy_limit": "100", - "examine": "A cool light Menaphite robe.", - "grand_exchange_price": "440", - "durability": null, - "name": "Menaphite robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6396", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "440", - "durability": null, - "name": "Menaphite robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6397" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Look at those nobbily knees.", - "grand_exchange_price": "246", - "durability": null, - "name": "Menap action kilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6398", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "246", - "durability": null, - "name": "Menap action kilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6399" - }, - { "remove_head": "true", "shop_price": "35", - "ge_buy_limit": "100", - "examine": "Good for keeping the sun off my neck.", - "grand_exchange_price": "484", - "durability": null, - "name": "Menap headgear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6400", - "equipment_slot": "0" + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "484", - "durability": null, + "id": "6393", "name": "Menap headgear", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6401" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6394", + "name": "Menaphite top", + "examine": "Colourful.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", "remove_sleeves": "true", "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Colourful.", - "grand_exchange_price": "557", - "durability": null, - "name": "Menaphite top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6402", - "equipment_slot": "4" + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "557", - "durability": null, + "id": "6395", "name": "Menaphite top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6403" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "40", - "ge_buy_limit": "100", + "id": "6396", + "name": "Menaphite robe", "examine": "A cool light Menaphite robe.", - "grand_exchange_price": "449", - "durability": null, - "name": "Menaphite robe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6404", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "40", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "449", - "durability": null, + "id": "6397", "name": "Menaphite robe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6405" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "20", - "ge_buy_limit": "100", + "id": "6398", + "name": "Menap action kilt", "examine": "Look at those nobbily knees.", - "grand_exchange_price": "236", - "durability": null, - "name": "Menap action kilt", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6406", - "equipment_slot": "7" - }, - { + "durability": null, + "equipment_slot": "7", "ge_buy_limit": "100", - "grand_exchange_price": "236", - "durability": null, - "name": "Menap action kilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6407" + "shop_price": "20", + "tradeable": "true" }, { + "id": "6399", + "name": "Menap action kilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6400", + "name": "Menap headgear", + "examine": "Good for keeping the sun off my neck.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "shop_price": "35", + "tradeable": "true" + }, + { + "id": "6401", + "name": "Menap headgear", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6402", + "name": "Menaphite top", + "examine": "Colourful.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "6403", + "name": "Menaphite top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6404", + "name": "Menaphite robe", + "examine": "A cool light Menaphite robe.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "40", + "tradeable": "true" + }, + { + "id": "6405", + "name": "Menaphite robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6406", + "name": "Menap action kilt", + "examine": "Look at those nobbily knees.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "6407", + "name": "Menap action kilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6408", + "name": "Oak blackjack(o)", + "examine": "An offensive blackjack.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,4,0,0,0,0,0,0,0,0,4,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{17,10}-{0,10}", "shop_price": "400", - "ge_buy_limit": "100", - "examine": "An offensive blackjack.", - "durability": null, - "weight": "1", - "attack_speed": "4", - "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "852", - "name": "Oak blackjack(o)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6408", - "bonuses": "0,0,4,0,0,0,0,0,0,0,0,4,0,0,0" + "weapon_interface": "10", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "852", - "durability": null, + "id": "6409", "name": "Oak blackjack(o)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6409" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{17,10}-{1,10}", - "ge_buy_limit": "100", - "examine": "An defensive blackjack.", - "durability": null, - "weight": "1", - "attack_speed": "4", - "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "818", - "name": "Oak blackjack(d)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6410", - "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "818", - "durability": null, "name": "Oak blackjack(d)", - "tradeable": "true", + "examine": "An defensive blackjack.", "archery_ticket_price": "0", - "id": "6411" + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{17,10}-{1,10}", + "tradeable": "true", + "weapon_interface": "10", + "weight": "1" }, { - "requirements": "{17,20}-{0,20}", - "ge_buy_limit": "100", - "examine": "An offensive blackjack.", - "durability": null, - "weight": "1", - "attack_speed": "4", - "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "1418", - "name": "Willow blackjack(o)", - "tradeable": "true", + "id": "6411", + "name": "Oak blackjack(d)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6412", - "bonuses": "0,0,8,0,0,0,0,0,0,0,0,8,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1418", - "durability": null, "name": "Willow blackjack(o)", - "tradeable": "true", + "examine": "An offensive blackjack.", "archery_ticket_price": "0", - "id": "6413" - }, - { - "requirements": "{17,20}-{1,20}", - "ge_buy_limit": "100", - "examine": "A defensive blackjack.", - "durability": null, - "weight": "1", "attack_speed": "4", - "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "1285", - "name": "Willow blackjack(d)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6414", - "bonuses": "0,0,0,0,0,0,0,8,0,0,0,8,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1285", + "bonuses": "0,0,8,0,0,0,0,0,0,0,0,8,0,0,0", "durability": null, - "name": "Willow blackjack(d)", + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{17,20}-{0,20}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6415" + "weapon_interface": "10", + "weight": "1" }, { + "id": "6413", + "name": "Willow blackjack(o)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6414", + "name": "Willow blackjack(d)", + "examine": "A defensive blackjack.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,8,0,0,0,8,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{17,20}-{1,20}", + "tradeable": "true", + "weapon_interface": "10", + "weight": "1" + }, + { + "id": "6415", + "name": "Willow blackjack(d)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6416", + "name": "Maple blackjack", + "examine": "A solid bit of maple.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,20,0,0,0", + "defence_anim": "425", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{17,30}", "shop_price": "1200", - "ge_buy_limit": "100", - "examine": "A solid bit of maple.", - "durability": null, - "weight": "1.8", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "10", - "defence_anim": "425", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "1432", - "name": "Maple blackjack", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6416", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,20,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1432", + "id": "6417", + "name": "Maple blackjack", + "archery_ticket_price": "0", "durability": null, - "name": "Maple blackjack", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6417" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6418", + "name": "Maple blackjack(o)", + "examine": "An offensive blackjack.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,24,0,0,0,0,0,0,0,0,20,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{17,30}-{0,30}", "shop_price": "1600", - "ge_buy_limit": "100", - "examine": "An offensive blackjack.", - "durability": null, - "weight": "1", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "2079", - "name": "Maple blackjack(o)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6418", - "bonuses": "0,0,24,0,0,0,0,0,0,0,0,20,0,0,0" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2079", + "id": "6419", + "name": "Maple blackjack(o)", + "archery_ticket_price": "0", "durability": null, - "name": "Maple blackjack(o)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6419" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6420", + "name": "Maple blackjack(d)", + "examine": "A defensive blackjack.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,24,0,0,0,20,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{17,30}-{1,30}", "shop_price": "952", - "ge_buy_limit": "100", - "examine": "A defensive blackjack.", - "durability": null, - "weight": "1", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "2407", - "name": "Maple blackjack(d)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6420", - "bonuses": "0,0,0,0,0,0,0,24,0,0,0,20,0,0,0" + "weight": "1" }, { + "id": "6421", + "name": "Maple blackjack(d)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "2407", - "durability": null, - "name": "Maple blackjack(d)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6421" + "tradeable": "true" }, { - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "9", - "durability": null, + "id": "6422", "name": "Air rune", - "tradeable": "true", + "examine": "One of the 4 basic elemental Runes.", "archery_ticket_price": "0", - "id": "6422" + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "durability": null, + "id": "6423", "name": "Air rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6423" + "durability": null, + "tradeable": "true" }, { - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "6", - "durability": null, + "id": "6424", "name": "Water rune", - "tradeable": "true", + "examine": "One of the 4 basic elemental Runes.", "archery_ticket_price": "0", - "id": "6424" + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "durability": null, + "id": "6425", "name": "Water rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6425" + "durability": null, + "tradeable": "true" }, { - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "7", - "durability": null, + "id": "6426", "name": "Earth rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6426" - }, - { - "durability": null, - "name": "Earth rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6427" - }, - { - "shop_price": "17", "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "16", - "durability": null, - "name": "Fire rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6428" + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "durability": null, - "name": "Fire rune", - "tradeable": "true", + "id": "6427", + "name": "Earth rune", "archery_ticket_price": "0", - "id": "6429" + "durability": null, + "tradeable": "true" }, { - "shop_price": "140", + "id": "6428", + "name": "Fire rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "17", + "tradeable": "true" + }, + { + "id": "6429", + "name": "Fire rune", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6430", + "name": "Chaos rune", "examine": "Used for small missile spells.", - "grand_exchange_price": "65", - "durability": null, - "name": "Chaos rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6430" + "durability": null, + "shop_price": "140", + "tradeable": "true" }, { - "durability": null, + "id": "6431", "name": "Chaos rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6431" + "durability": null, + "tradeable": "true" }, { - "shop_price": "310", + "id": "6432", + "name": "Death rune", "examine": "Used for medium missile spells.", - "grand_exchange_price": "399", - "durability": null, - "name": "Death rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6432" + "durability": null, + "shop_price": "310", + "tradeable": "true" }, { - "durability": null, + "id": "6433", "name": "Death rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6433" + "durability": null, + "tradeable": "true" }, { - "shop_price": "378", + "id": "6434", + "name": "Law rune", "examine": "Used for teleport spells.", - "grand_exchange_price": "277", - "durability": null, - "name": "Law rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6434" + "durability": null, + "shop_price": "378", + "tradeable": "true" }, { - "durability": null, + "id": "6435", "name": "Law rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6435" + "durability": null, + "tradeable": "true" }, { - "shop_price": "17", + "id": "6436", + "name": "Mind rune", "examine": "Used for basic missile spells.", - "grand_exchange_price": "6", - "durability": null, - "name": "Mind rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6436" + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "durability": null, + "id": "6437", "name": "Mind rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6437" + "durability": null, + "tradeable": "true" }, { - "shop_price": "16", + "id": "6438", + "name": "Body rune", "examine": "Used for Curse spells", - "grand_exchange_price": "6", - "durability": null, - "name": "Body rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6438" + "durability": null, + "shop_price": "16", + "tradeable": "true" }, { - "durability": null, + "id": "6439", "name": "Body rune", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6439" + "durability": null, + "tradeable": "true" }, { - "examine": "A spadeful of refined coal.", - "durability": null, + "id": "6448", "name": "Spadeful of coke", - "weight": "2", + "examine": "A spadeful of refined coal.", "archery_ticket_price": "0", - "id": "6448" + "durability": null, + "weight": "2" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A white rosebush seed.", - "durability": null, + "id": "6453", "name": "White rose seed", - "tradeable": "false", - "destroy": "true", - "weight": "28.928", + "examine": "A white rosebush seed.", "archery_ticket_price": "0", - "id": "6453" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "28.928" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A red rosebush seed.", - "durability": null, + "id": "6454", "name": "Red rose seed", - "tradeable": "false", - "destroy": "true", + "examine": "A red rosebush seed.", "archery_ticket_price": "0", - "id": "6454" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pink rosebush seed.", - "durability": null, + "id": "6455", "name": "Pink rose seed", - "tradeable": "false", - "destroy": "true", + "examine": "A pink rosebush seed.", "archery_ticket_price": "0", - "id": "6455" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get some more Burthorpe vine seeds from Berald in Taverly.", - "examine": "A grapevine seed.", - "durability": null, + "id": "6456", "name": "Vine seed", - "tradeable": "false", - "destroy": "true", + "examine": "A grapevine seed.", "archery_ticket_price": "0", - "id": "6456" + "destroy": "true", + "destroy_message": "You can get some more Burthorpe vine seeds from Berald in Taverly.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A delphinium seed.", - "durability": null, + "id": "6457", "name": "Delphinium seed", - "tradeable": "false", - "destroy": "true", + "examine": "A delphinium seed.", "archery_ticket_price": "0", - "id": "6457" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A snowdrop seed.", - "durability": null, + "id": "6460", "name": "Snowdrop seed", - "tradeable": "false", + "examine": "A snowdrop seed.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "6460" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", - "durability": null, + "id": "6461", "name": "White tree shoot", - "archery_ticket_price": "0", - "id": "6461" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", - "durability": null, - "name": "White tree shoot", "archery_ticket_price": "0", - "id": "6462" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", + "id": "6462", + "name": "White tree shoot", "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", - "durability": null, - "name": "White tree shoot", "archery_ticket_price": "0", - "id": "6463" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { + "id": "6463", + "name": "White tree shoot", + "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A young White Tree sapling", - "durability": null, + "durability": null + }, + { + "id": "6464", "name": "White tree sapling", - "tradeable": "false", - "destroy": "true", - "weight": "0.9", + "examine": "A young White Tree sapling", "archery_ticket_price": "0", - "id": "6464" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "0.9" }, { - "destroy_message": "Another can be received from pickpocketing Dr. Fenkenstrain in the tower.", - "examine": "Unactivated: The Ring of charos.Activated: The power within this ring has been activated.", - "durability": null, - "name": "Ring of charos(a)", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "6465", - "equipment_slot": "12" + "name": "Ring of charos(a)", + "examine": "The power within this ring has been activated.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Another can be received from pickpocketing Dr. Fenkenstrain in the tower.", + "durability": null, + "equipment_slot": "12", + "tradeable": "false" }, { - "examine": "A rune essence chip that has been broken into shards.", - "durability": null, + "id": "6466", "name": "Rune shards", + "examine": "A rune essence chip that has been broken into shards.", "archery_ticket_price": "0", - "id": "6466" + "durability": null }, { - "examine": "Crushed rune essence.", - "durability": null, + "id": "6467", "name": "Rune dust", + "examine": "Crushed rune essence.", "archery_ticket_price": "0", - "id": "6467" + "durability": null }, { - "shop_price": "25", - "examine": "Use this on plants to cure disease.", - "grand_exchange_price": "199", - "durability": null, + "id": "6468", "name": "Plant cure", - "tradeable": "true", + "examine": "Use this on plants to cure disease.", "archery_ticket_price": "0", - "id": "6468" + "durability": null, + "shop_price": "25", + "tradeable": "true" }, { - "examine": "Looks delicious.", - "durability": null, + "id": "6469", "name": "White tree fruit", + "examine": "Looks delicious.", "archery_ticket_price": "0", - "id": "6469" + "durability": null }, { - "ge_buy_limit": "100", - "examine": "Pour this onto compost to make it into super-compost.", - "grand_exchange_price": "11500", - "durability": null, + "id": "6470", "name": "Compost potion(4)", - "tradeable": "true", + "examine": "Pour this onto compost to make it into super-compost.", "archery_ticket_price": "0", - "id": "6470" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "11500", - "durability": null, + "id": "6471", "name": "Compost potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6471" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "Pour this onto compost to make it into super-compost.", - "grand_exchange_price": "6804", - "durability": null, + "id": "6472", "name": "Compost potion(3)", - "tradeable": "true", + "examine": "Pour this onto compost to make it into super-compost.", "archery_ticket_price": "0", - "id": "6472" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "6804", - "durability": null, + "id": "6473", "name": "Compost potion(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6473" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "Pour this onto compost to make it into super-compost.", - "grand_exchange_price": "3338", - "durability": null, + "id": "6474", "name": "Compost potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6474" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3338", - "durability": null, - "name": "Compost potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6475" - }, - { - "ge_buy_limit": "100", "examine": "Pour this onto compost to make it into super-compost.", - "grand_exchange_price": "1734", - "durability": null, - "name": "Compost potion(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6476" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1734", - "durability": null, - "name": "Compost potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6477" + "tradeable": "true" }, { - "destroy_message": "You can get another one from Queen Ellamaria", - "examine": "I can use this to move heavy objects. (or) An empty trolley.", + "id": "6475", + "name": "Compost potion(2)", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6476", + "name": "Compost potion(1)", + "examine": "Pour this onto compost to make it into super-compost.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6477", + "name": "Compost potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6478", "name": "Trolley", - "tradeable": "false", - "destroy": "true", - "weight": "2", + "examine": "I can use this to move heavy objects. (or) An empty trolley.", "archery_ticket_price": "0", - "id": "6478" - }, - { - "destroy_message": "You can get another list from Queen Ellamaria in Varrock", - "examine": "A list of things that I must collect for Queen Ellamaria.", + "destroy": "true", + "destroy_message": "You can get another one from Queen Ellamaria", "durability": null, - "name": "List", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6479" + "weight": "2" }, { + "id": "6479", + "name": "List", + "examine": "A list of things that I must collect for Queen Ellamaria.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another list from Queen Ellamaria in Varrock", + "durability": null, + "tradeable": "false" + }, + { + "id": "6522", + "name": "Toktz-xil-ul", + "examine": "A razor sharp ring of obsidian.", + "archery_ticket_price": "0", + "attack_anims": "2614,2614,2614,2614", + "attack_speed": "4", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,49", + "defence_anim": "424", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{4,60}", "shop_price": "375", - "ge_buy_limit": "100", - "examine": "A razor sharp ring of obsidian.", - "durability": null, "tokkul_price": "375", - "attack_speed": "4", - "weapon_interface": "18", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "2614,2614,2614,2614", - "grand_exchange_price": "340", - "name": "Toktz-xil-ul", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6522", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,49" + "weapon_interface": "18" }, { + "id": "6523", + "name": "Toktz-xil-ak", + "examine": "A razor sharp sword of obsidian.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "4", + "bonuses": "47,38,-2,0,0,2,3,0,0,0,0,49,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", "requirements": "{0,60}", "shop_price": "60000", - "ge_buy_limit": "10", - "examine": "A razor sharp sword of obsidian.", - "durability": null, "tokkul_price": "60000", - "weight": "1.8", - "attack_speed": "4", - "weapon_interface": "5", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "30200", - "name": "Toktz-xil-ak", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6523", - "bonuses": "47,38,-2,0,0,2,3,0,0,0,0,49,0,0,0" + "weapon_interface": "5", + "weight": "1.8" }, { + "id": "6524", + "name": "Toktz-ket-xil", + "examine": "A spiked shield of Obsidian.", + "absorb": "5,0,11", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-12,-8,40,42,38,0,65,60,5,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", "requirements": "{1,60}", "shop_price": "67500", - "ge_buy_limit": "10", - "examine": "A spiked shield of Obsidian.", - "durability": null, "tokkul_price": "67500", - "weight": "3.6", - "absorb": "5,0,11", - "equipment_slot": "5", - "grand_exchange_price": "34700", - "name": "Toktz-ket-xil", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6524", - "bonuses": "0,0,0,-12,-8,40,42,38,0,65,60,5,0,0,0" + "weight": "3.6" }, { + "id": "6525", + "name": "Toktz-xil-ek", + "examine": "A large knife of Obsidian.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "4", + "bonuses": "16,48,0,0,0,0,0,0,0,0,0,39,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "2584", "requirements": "{0,60}", "shop_price": "37500", - "ge_buy_limit": "10", - "examine": "A large knife of Obsidian.", - "durability": null, "tokkul_price": "37500", - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "6", - "render_anim": "2584", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "16900", - "name": "Toktz-xil-ek", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6525", - "bonuses": "16,48,0,0,0,0,0,0,0,0,0,39,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "A staff of obsidian.", - "walk_anim": "1205", - "tokkul_price": "52500", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "26300", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "6526", - "stand_turn_anim": "1209", + "name": "Toktz-mej-tal", + "examine": "A staff of obsidian.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "6", "bonuses": "15,-1,55,15,0,10,15,5,15,0,0,55,5,0,0", - "requirements": "{0,60}-{6,60}", - "shop_price": "52500", + "defence_anim": "397", "durability": null, - "weight": "1", - "weapon_interface": "1", + "equipment_slot": "3", + "ge_buy_limit": "10", "render_anim": "28", - "name": "Toktz-mej-tal" + "requirements": "{0,60}-{6,60}", + "run_anim": "1210", + "shop_price": "52500", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tokkul_price": "52500", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "1" }, { + "id": "6527", + "name": "Tzhaar-ket-em", + "examine": "A mace of obsidian.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "5", + "bonuses": "-4,-4,62,0,0,0,0,0,0,0,0,56,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", "requirements": "{0,60}", "shop_price": "45000", - "ge_buy_limit": "10", - "examine": "A mace of obsidian.", - "durability": null, "tokkul_price": "45000", - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "10", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "22600", - "name": "Tzhaar-ket-em", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6527", - "bonuses": "-4,-4,62,0,0,0,0,0,0,0,0,56,0,0,0" + "weapon_interface": "10", + "weight": "1.8" }, { - "ge_buy_limit": "10", - "turn90cw_anim": "1663", - "examine": "A maul of obsidian.", - "walk_anim": "1663", - "tokkul_price": "75000", - "turn90ccw_anim": "1663", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1663", - "defence_anim": "1666", - "equipment_slot": "3", - "attack_anims": "2661,2661,2661,2661", - "grand_exchange_price": "31000", - "stand_anim": "1662", - "tradeable": "true", - "run_anim": "1664", - "archery_ticket_price": "0", "id": "6528", - "stand_turn_anim": "823", - "bonuses": "0,0,80,-4,0,0,0,0,0,0,0,85,0,0,0", - "requirements": "{2,60}", - "shop_price": "75000", - "durability": null, - "weight": "3.6", - "weapon_interface": "10", - "render_anim": "27", - "attack_audios": "2520,0,0,0", - "name": "Tzhaar-ket-om" - }, - { - "examine": "It's a Token of some kind made from Obsidian.", - "durability": null, - "name": "Tokkul", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "6529" - }, - { - "durability": null, - "name": "Toktz-xil-ak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6535" - }, - { - "durability": null, - "name": "Toktz-ket-xil", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6536" - }, - { - "durability": null, - "name": "Toktz-xil-ek", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6537" - }, - { - "durability": null, - "name": "Toktz-mej-tal", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6538" - }, - { - "durability": null, - "name": "Tzhaar-ket-em", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6539" - }, - { - "durability": null, "name": "Tzhaar-ket-om", - "tradeable": "true", + "examine": "A maul of obsidian.", "archery_ticket_price": "0", - "id": "6540" + "attack_anims": "2661,2661,2661,2661", + "attack_audios": "2520,0,0,0", + "attack_speed": "7", + "bonuses": "0,0,80,-4,0,0,0,0,0,0,0,85,0,0,0", + "defence_anim": "1666", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "27", + "requirements": "{2,60}", + "run_anim": "1664", + "shop_price": "75000", + "stand_anim": "1662", + "stand_turn_anim": "823", + "tokkul_price": "75000", + "tradeable": "true", + "turn180_anim": "1663", + "turn90ccw_anim": "1663", + "turn90cw_anim": "1663", + "two_handed": "true", + "walk_anim": "1663", + "weapon_interface": "10", + "weight": "3.6" }, { - "destroy_message": "You can get a replacement mouse toy by speaking to Bob, the Jagex cat.", - "examine": "An Advanced Combat Training Device.", - "durability": null, - "name": "Mouse toy", - "tradeable": "false", - "destroy": "true", - "weight": "0.1", + "id": "6529", + "name": "Tokkul", + "examine": "It's a Token of some kind made from Obsidian.", "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "6535", + "name": "Toktz-xil-ak", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6536", + "name": "Toktz-ket-xil", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6537", + "name": "Toktz-xil-ek", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6538", + "name": "Toktz-mej-tal", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6539", + "name": "Tzhaar-ket-em", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6540", + "name": "Tzhaar-ket-om", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "6541", - "weapon_interface": "12", + "name": "Mouse toy", + "examine": "An Advanced Combat Training Device.", + "archery_ticket_price": "0", "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", - "equipment_slot": "3" + "destroy": "true", + "destroy_message": "You can get a replacement mouse toy by speaking to Bob, the Jagex cat.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false", + "weapon_interface": "12", + "weight": "0.1" }, { - "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.", - "durability": null, + "id": "6542", "name": "Present", - "tradeable": "false", - "destroy": "true", + "examine": "Thanks for all your help! Love, Bob & Neite.", "archery_ticket_price": "0", - "id": "6542" + "destroy": "true", + "destroy_message": "You will not get a replacement for the present. Open it for your reward.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, + "id": "6543", "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", + "examine": "I wonder what happens if I rub it.", "archery_ticket_price": "0", - "id": "6543" + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another Amulet of Catspeak from the Sphinx in Sophanem.", - "examine": "It's an amulet of cat speak. It makes vague purring noises.", - "durability": null, - "name": "Catspeak amulet(e)", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "6544", - "equipment_slot": "2" + "name": "Catspeak amulet(e)", + "examine": "It's an amulet of cat speak. It makes vague purring noises.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Amulet of Catspeak from the Sphinx in Sophanem.", + "durability": null, + "equipment_slot": "2", + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "You have completed the chores; you can safely destroy the list.", - "examine": "A list of chores that Bob gave you to do.", - "durability": null, + "id": "6545", "name": "Chores", - "tradeable": "false", - "destroy": "true", + "examine": "A list of chores that Bob gave you to do.", "archery_ticket_price": "0", - "id": "6545" + "destroy": "true", + "destroy_message": "You have completed the chores; you can safely destroy the list.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You found the recipe in Unferth's bookcase, which is in his Burthorpe house, you will be able to get a replacement.", - "examine": "It says on the back 'My favourite recipe.", - "durability": null, + "id": "6546", "name": "Recipe", - "tradeable": "false", - "destroy": "true", + "examine": "It says on the back 'My favourite recipe.", "archery_ticket_price": "0", - "id": "6546" + "destroy": "true", + "destroy_message": "You found the recipe in Unferth's bookcase, which is in his Burthorpe house, you will be able to get a replacement.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another Doctor's hat from the Apothecary in Varrock.", - "examine": "A mirror helps reflect light on the subject.", - "durability": null, - "name": "Doctors hat", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "6547", - "equipment_slot": "0" - }, - { - "destroy_message": "You can get another Nurse's hat from the Apothecary in Varrock.", - "examine": "A nurse's hat, but does it have healing powers?", - "durability": null, - "name": "Nurse hat", - "tradeable": "false", + "name": "Doctors hat", + "examine": "A mirror helps reflect light on the subject.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", + "destroy_message": "You can get another Doctor's hat from the Apothecary in Varrock.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false" + }, + { "id": "6548", - "equipment_slot": "0" + "name": "Nurse hat", + "examine": "A nurse's hat, but does it have healing powers?", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Nurse's hat from the Apothecary in Varrock.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false" }, { - "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, + "id": "6549", "name": "Lazy cat", + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", "archery_ticket_price": "0", - "id": "6549" + "durability": null }, { - "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, + "id": "6550", "name": "Lazy cat", + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", "archery_ticket_price": "0", - "id": "6550" + "durability": null }, { - "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, + "id": "6551", "name": "Lazy cat", + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", "archery_ticket_price": "0", - "id": "6551" + "durability": null }, { - "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, + "id": "6552", "name": "Lazy cat", + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", "archery_ticket_price": "0", - "id": "6552" + "durability": null }, { - "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, + "id": "6553", "name": "Lazy cat", + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", "archery_ticket_price": "0", - "id": "6553" + "durability": null }, { - "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, + "id": "6554", "name": "Lazy cat", - "archery_ticket_price": "0", - "id": "6554" - }, - { "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, - "name": "Wily cat", "archery_ticket_price": "0", - "id": "6555" + "durability": null }, { + "id": "6555", + "name": "Wily cat", "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, - "name": "Wily cat", "archery_ticket_price": "0", - "id": "6556" + "durability": null }, { + "id": "6556", + "name": "Wily cat", "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, - "name": "Wily cat", "archery_ticket_price": "0", - "id": "6557" + "durability": null }, { + "id": "6557", + "name": "Wily cat", "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, - "name": "Wily cat", "archery_ticket_price": "0", - "id": "6558" + "durability": null }, { + "id": "6558", + "name": "Wily cat", "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, - "name": "Wily cat", "archery_ticket_price": "0", - "id": "6559" + "durability": null }, { + "id": "6559", + "name": "Wily cat", "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", - "durability": null, - "name": "Wily cat", "archery_ticket_price": "0", - "id": "6560" + "durability": null }, { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "368700", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "6560", + "name": "Wily cat", + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", "archery_ticket_price": "0", + "durability": null + }, + { "id": "6562", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", - "durability": null, - "weight": "2.2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Mud battlestaff" - }, - { - "requirements": "{0,40}-{6,40}", - "ge_buy_limit": "10", - "shop_price": "40000", - "turn90cw_anim": "1207", + "name": "Mud battlestaff", "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "durability": null, - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "423100", - "stand_anim": "813", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", "attack_audios": "2555,0,0,0", - "tradeable": "true", - "name": "Mystic mud staff", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6563", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0" + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "examine": "A valuable ring.", - "grand_exchange_price": "6609743", + "id": "6563", + "name": "Mystic mud staff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", + "run_anim": "1210", + "shop_price": "40000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "6564", "name": "Onyx ring", - "tradeable": "true", + "examine": "A valuable ring.", "archery_ticket_price": "0", - "id": "6564" + "durability": null, + "tradeable": "true" }, { - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "4501000", - "durability": null, + "id": "6565", "name": "Onyx necklace", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "6565" + "durability": null, + "tradeable": "true" }, { - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "9058124", - "durability": null, + "id": "6566", "name": "Onyx amulet", - "tradeable": "true", + "examine": "I wonder if I can get this enchanted.", "archery_ticket_price": "0", - "id": "6566" + "durability": null, + "tradeable": "true" }, { - "shop_price": "90000", - "ge_buy_limit": "100", - "examine": "A cape woven of obsidian plates.", - "durability": null, - "tokkul_price": "90000", - "weight": "1.8", - "equipment_slot": "1", - "lendable": "true", - "grand_exchange_price": "42000", - "name": "Obsidian cape", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6568", - "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "42000", - "durability": null, "name": "Obsidian cape", - "tradeable": "true", + "examine": "A cape woven of obsidian plates.", "archery_ticket_price": "0", - "id": "6569" - }, - { - "examine": "A cape of fire.", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", "durability": null, - "name": "Fire cape", - "tradeable": "false", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "6570", - "bonuses": "1,1,1,1,1,11,11,11,11,11,11,4,2,0,0", - "equipment_slot": "1" - }, - { - "shop_price": "2700000", + "equipment_slot": "1", "ge_buy_limit": "100", - "examine": "An uncut onyx.", - "grand_exchange_price": "10700000", - "tokkul_price": "300000", - "durability": null, - "name": "Uncut onyx", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6571" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10700000", - "durability": null, - "name": "Uncut onyx", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6572" - }, - { - "ge_buy_limit": "100", - "examine": "This looks valuable.", - "grand_exchange_price": "10700000", - "durability": null, - "name": "Onyx", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6573" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10700000", - "durability": null, - "name": "Onyx", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6574" - }, - { - "ge_buy_limit": "100", - "examine": "A valuable ring.", - "grand_exchange_price": "11900000", - "durability": null, - "name": "Onyx ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6575", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "11900000", - "durability": null, - "name": "Onyx ring", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6576" - }, - { - "ge_buy_limit": "100", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "4500000", - "durability": null, - "name": "Onyx necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6577", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4500000", - "durability": null, - "name": "Onyx necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6578" - }, - { - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "9058124", - "durability": null, - "name": "Onyx amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6579" - }, - { - "durability": null, - "name": "Onyx amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6580" - }, - { - "ge_buy_limit": "100", - "examine": "I wonder if I can get this enchanted.", - "grand_exchange_price": "10900000", - "durability": null, - "name": "Onyx amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6581", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10900000", - "durability": null, - "name": "Onyx amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6582" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring.", - "grand_exchange_price": "803700", - "durability": null, - "name": "Ring of stone", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6583", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "803700", - "durability": null, - "name": "Ring of stone", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6584" - }, - { "lendable": "true", - "ge_buy_limit": "100", - "examine": "A very powerful onyx amulet.", - "grand_exchange_price": "9200000", - "durability": null, - "name": "Amulet of fury", + "shop_price": "90000", + "tokkul_price": "90000", "tradeable": "true", + "weight": "1.8" + }, + { + "id": "6569", + "name": "Obsidian cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6570", + "name": "Fire cape", + "examine": "A cape of fire.", + "archery_ticket_price": "0", + "bonuses": "1,1,1,1,1,11,11,11,11,11,11,4,2,0,0", + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "1.8" + }, + { + "id": "6571", + "name": "Uncut onyx", + "examine": "An uncut onyx.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2700000", + "tokkul_price": "300000", + "tradeable": "true" + }, + { + "id": "6572", + "name": "Uncut onyx", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6573", + "name": "Onyx", + "examine": "This looks valuable.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6574", + "name": "Onyx", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6575", + "name": "Onyx ring", + "examine": "A valuable ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6576", + "name": "Onyx ring", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6577", + "name": "Onyx necklace", + "examine": "I wonder if this is valuable.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6578", + "name": "Onyx necklace", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6579", + "name": "Onyx amulet", + "examine": "It needs a string so I can wear it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6580", + "name": "Onyx amulet", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6581", + "name": "Onyx amulet", + "examine": "I wonder if I can get this enchanted.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6582", + "name": "Onyx amulet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6583", + "name": "Ring of stone", + "examine": "An enchanted ring.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6584", + "name": "Ring of stone", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6585", - "bonuses": "10,10,10,10,10,15,15,15,15,15,15,8,5,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9200000", - "durability": null, "name": "Amulet of fury", - "tradeable": "true", + "examine": "A very powerful onyx amulet.", "archery_ticket_price": "0", - "id": "6586" + "bonuses": "10,10,10,10,10,15,15,15,15,15,15,8,5,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "lendable": "true", + "tradeable": "true" }, { + "id": "6586", + "name": "Amulet of fury", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6587", + "name": "White claws", + "examine": "A set of fighting claws.", + "archery_ticket_price": "0", + "attack_anims": "390,390,390,390", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "10,14,-4,0,0,4,7,2,0,0,0,14,1,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2583", "requirements": "{0,10}-{5,10}", "shop_price": "360", - "ge_buy_limit": "100", - "examine": "A set of fighting claws.", - "durability": null, - "attack_speed": "4", + "tradeable": "true", "two_handed": "true", - "weapon_interface": "9", - "equip_audio": "1003", - "render_anim": "2583", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,390,390", - "grand_exchange_price": "1013", - "name": "White claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6587", - "bonuses": "10,14,-4,0,0,4,7,2,0,0,0,14,1,0,0" + "weapon_interface": "9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1013", + "id": "6588", + "name": "White claws", + "archery_ticket_price": "0", "durability": null, - "name": "White claws", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6588" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6589", + "name": "White battleaxe", + "examine": "A vicious looking axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,20,15,0,0,0,0,0,0,-1,0,24,1,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2586", "requirements": "{0,10}-{5,10}", "shop_price": "1248", - "ge_buy_limit": "100", - "examine": "A vicious looking axe.", - "durability": null, - "weight": "2.7", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "2", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "grand_exchange_price": "1459", - "attack_audios": "2498,2498,2497,2498", - "name": "White battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6589", - "bonuses": "-2,20,15,0,0,0,0,0,0,-1,0,24,1,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1459", - "durability": null, + "id": "6590", "name": "White battleaxe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6590" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,10}-{5,10}", - "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious white dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,400,400", - "grand_exchange_price": "479", - "attack_audios": "2517,2517,2500,2517", - "name": "White dagger", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6591", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "479", - "durability": null, "name": "White dagger", - "tradeable": "true", + "examine": "A vicious white dagger.", "archery_ticket_price": "0", - "id": "6592" - }, - { + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,10}-{5,10}", "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious white dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "497", - "attack_audios": "2517,2517,2500,2517", - "name": "White dagger(p)", "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "6592", + "name": "White dagger", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6593", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "497", - "durability": null, "name": "White dagger(p)", - "tradeable": "true", + "examine": "A vicious white dagger.", "archery_ticket_price": "0", - "id": "6594" - }, - { + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,10}-{5,10}", "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious white dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "982", - "attack_audios": "2517,2517,2500,2517", - "name": "White dagger(p+)", "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "6594", + "name": "White dagger(p)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6595", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "982", - "durability": null, "name": "White dagger(p+)", - "tradeable": "true", + "examine": "A vicious white dagger.", "archery_ticket_price": "0", - "id": "6596" - }, - { + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "2584", "requirements": "{0,10}-{5,10}", "shop_price": "240", - "ge_buy_limit": "100", - "examine": "A vicious white dagger.", - "durability": null, - "weight": "0.4", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "render_anim": "2584", - "equipment_slot": "3", - "grand_exchange_price": "8422", - "attack_audios": "2517,2517,2500,2517", - "name": "White dagger(p++)", - "tradeable": "true", + "weight": "0.4" + }, + { + "id": "6596", + "name": "White dagger(p+)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6597", - "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8422", - "durability": null, "name": "White dagger(p++)", - "tradeable": "true", + "examine": "A vicious white dagger.", "archery_ticket_price": "0", - "id": "6598" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A white halberd.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "430", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0", + "durability": null, + "equip_audio": "2248", "equipment_slot": "3", - "attack_anims": "440,440,412,440", - "grand_exchange_price": "1834", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6599", - "stand_turn_anim": "1209", - "bonuses": "19,25,0,-4,0,-1,2,3,0,0,0,20,1,0,0", - "requirements": "{0,10}-{5,10}", - "shop_price": "1920", - "durability": null, - "weight": "3.1", - "weapon_interface": "15", - "render_anim": "28", - "name": "White halberd" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1834", - "durability": null, - "name": "White halberd", + "render_anim": "2584", + "requirements": "{0,10}-{5,10}", + "shop_price": "240", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6600" + "weapon_interface": "5", + "weight": "0.4" }, { + "id": "6598", + "name": "White dagger(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6599", + "name": "White halberd", + "examine": "A white halberd.", + "archery_ticket_price": "0", + "attack_anims": "440,440,412,440", + "attack_speed": "7", + "bonuses": "19,25,0,-4,0,-1,2,3,0,0,0,20,1,0,0", + "defence_anim": "430", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}-{2,5}", + "run_anim": "1210", + "shop_price": "1920", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "15", + "weight": "3.1" + }, + { + "id": "6600", + "name": "White halberd", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6601", + "name": "White mace", + "examine": "A spiky mace.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "8,-2,16,0,0,0,0,0,0,0,0,13,3,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,10}-{5,10}", "shop_price": "432", - "ge_buy_limit": "100", - "examine": "A spiky mace.", - "durability": null, - "weight": "1.8", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "8", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "481", - "name": "White mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6601", - "bonuses": "8,-2,16,0,0,0,0,0,0,0,0,13,3,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "481", - "durability": null, + "id": "6602", "name": "White mace", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6602" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,10}-{5,10}", - "ge_buy_limit": "100", - "shop_price": "200", - "turn90cw_anim": "1207", - "examine": "A Magical staff.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "650", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "tradeable": "true", - "name": "White magic staff", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "6603", - "stand_turn_anim": "1209", - "bonuses": "2,-1,10,10,0,2,3,1,10,0,0,7,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "650", - "durability": null, "name": "White magic staff", - "tradeable": "true", + "examine": "A Magical staff.", "archery_ticket_price": "0", - "id": "6604" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A razor sharp sword.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "defence_anim": "397", + "attack_audios": "2555,0,0,0", + "bonuses": "2,-1,10,10,0,2,3,1,10,0,0,7,1,0,0", + "durability": null, + "equip_audio": "2247", "equipment_slot": "3", - "attack_anims": "381,390,390,390", - "grand_exchange_price": "1187", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,10}-{5,10}", + "run_anim": "1210", + "shop_price": "200", "stand_anim": "813", + "stand_turn_anim": "1209", "tradeable": "true", - "run_anim": "824", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "6604", + "name": "White magic staff", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6605", - "stand_turn_anim": "823", - "bonuses": "14,10,-2,0,0,0,2,1,0,0,0,12,1,0,0", - "requirements": "{0,10}-{5,10}", - "shop_price": "624", - "durability": null, - "weight": "1.8", - "weapon_interface": "5", - "render_anim": "1381", - "name": "White sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1187", - "durability": null, "name": "White sword", - "tradeable": "true", + "examine": "A razor sharp sword.", "archery_ticket_price": "0", - "id": "6606" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A razor sharp longsword.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "2060", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "6607", - "stand_turn_anim": "823", - "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,1,0,0", - "requirements": "{0,10}-{5,10}", - "shop_price": "960", - "durability": null, - "weight": "1.8", - "weapon_interface": "6", - "render_anim": "1", - "name": "White longsword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2060", - "durability": null, - "name": "White longsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6608" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "7044", - "examine": "A two handed sword.", - "walk_anim": "7046", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "4029", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "6609", - "stand_turn_anim": "7040", - "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,26,1,0,0", - "requirements": "{0,10}-{5,10}", - "shop_price": "1920", - "durability": null, - "weight": "3.6", - "weapon_interface": "7", - "render_anim": "124", - "attack_audios": "2503,0,2504,0", - "name": "White 2h sword" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4029", - "durability": null, - "name": "White 2h sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6610" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A vicious, curved sword.", - "walk_anim": "819", - "turn90ccw_anim": "822", + "attack_anims": "381,390,390,390", "attack_speed": "4", - "turn180_anim": "820", + "bonuses": "14,10,-2,0,0,0,2,1,0,0,0,12,1,0,0", "defence_anim": "397", + "durability": null, + "equip_audio": "2248", "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "1404", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "6611", - "stand_turn_anim": "823", - "bonuses": "4,19,-2,0,0,0,1,0,0,0,0,14,1,0,0", - "requirements": "{0,10}-{5,10}", - "shop_price": "768", - "durability": null, - "weight": "1", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,0,2517,0", - "name": "White scimitar" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1404", - "durability": null, - "name": "White scimitar", + "render_anim": "1381", + "requirements": "{0,10}-{5,10}", + "run_anim": "824", + "shop_price": "624", + "stand_anim": "813", + "stand_turn_anim": "823", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6612" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5", + "weight": "1.8" }, { + "id": "6606", + "name": "White sword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6607", + "name": "White longsword", + "examine": "A razor sharp longsword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "5", + "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,1,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,10}-{5,10}", + "run_anim": "824", + "shop_price": "960", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1.8" + }, + { + "id": "6608", + "name": "White longsword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6609", + "name": "White 2h sword", + "examine": "A two handed sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,26,1,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "requirements": "{0,10}-{5,10}", + "run_anim": "7039", + "shop_price": "1920", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" + }, + { + "id": "6610", + "name": "White 2h sword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6611", + "name": "White scimitar", + "examine": "A vicious, curved sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "4,19,-2,0,0,0,1,0,0,0,0,14,1,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,10}-{5,10}", + "run_anim": "824", + "shop_price": "768", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6", + "weight": "1" + }, + { + "id": "6612", + "name": "White scimitar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6613", + "name": "White warhammer", + "examine": "I don't think it's intended for joinery.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,22,-4,0,0,0,0,0,0,0,19,1,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,10}-{5,10}", "shop_price": "980", - "ge_buy_limit": "100", - "examine": "I don't think it's intended for joinery.", - "durability": null, - "weight": "1.8", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "10", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "1178", - "attack_audios": "2504,0,0,0", - "name": "White warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6613", - "bonuses": "-4,-4,22,-4,0,0,0,0,0,0,0,19,1,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1178", + "id": "6614", + "name": "White warhammer", + "archery_ticket_price": "0", "durability": null, - "name": "White warhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6614" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6615", + "name": "White chainbody", + "examine": "A series of connected metal rings.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,0,22,32,39,-3,24,10,0,1,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", "requirements": "{1,10}-{5,10}", "shop_price": "1440", - "ge_buy_limit": "100", - "examine": "A series of connected metal rings.", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "6616", + "name": "White chainbody", + "archery_ticket_price": "0", "durability": null, - "weight": "6.8", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6617", + "name": "White platebody", + "examine": "Provides excellent protection.", "absorb": "1,0,2", - "equipment_slot": "4", - "grand_exchange_price": "788", - "name": "White chainbody", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6615", - "bonuses": "0,0,0,-15,0,22,32,39,-3,24,10,0,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "788", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,1,0,0", "durability": null, - "name": "White chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6616" - }, - { + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", "requirements": "{1,10}-{5,10}", "shop_price": "3840", - "ge_buy_limit": "100", - "examine": "Provides excellent protection.", - "durability": null, - "weight": "9.9", - "absorb": "1,0,2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "5837", - "name": "White platebody", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6617", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,1,0,0" + "weight": "9.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "5837", - "durability": null, + "id": "6618", "name": "White platebody", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6618" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6619", + "name": "White boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,7,8,9,0,0,7,0,1,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", "requirements": "{1,10}-{5,10}", "shop_price": "576", - "ge_buy_limit": "100", - "examine": "These will protect my feet.", - "durability": null, - "weight": "1.3", - "equipment_slot": "10", - "grand_exchange_price": "1016", - "name": "White boots", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6619", - "bonuses": "0,0,0,-3,-1,7,8,9,0,0,7,0,1,0,0" + "weight": "1.3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1016", - "durability": null, + "id": "6620", "name": "White boots", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6620" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6621", + "name": "White med helm", + "examine": "A medium sized helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,4,0,1,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{1,10}-{5,10}", "shop_price": "576", - "ge_buy_limit": "100", - "examine": "A medium sized helmet.", + "tradeable": "true", + "weight": "1.9" + }, + { + "id": "6622", + "name": "White med helm", + "archery_ticket_price": "0", "durability": null, - "weight": "1.9", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6623", + "name": "White full helm", + "examine": "A full face helmet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,1,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", - "grand_exchange_price": "853", - "name": "White med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6621", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,4,0,1,0,0" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "853", - "durability": null, - "name": "White med helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6622" - }, - { + "remove_beard": "true", "remove_head": "true", "requirements": "{1,10}-{5,10}", "shop_price": "1056", - "ge_buy_limit": "100", - "examine": "A full face helmet.", - "durability": null, - "weight": "2.7", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "2624", - "name": "White full helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6623", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,1,0,0" + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2624", - "durability": null, + "id": "6624", "name": "White full helm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6624" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,10}-{5,10}", - "shop_price": "1920", - "ge_buy_limit": "100", - "examine": "Big, white and heavy looking.", - "durability": null, - "weight": "9", - "equipment_slot": "7", - "grand_exchange_price": "2115", - "name": "White platelegs", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6625", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2115", - "durability": null, "name": "White platelegs", - "tradeable": "true", + "examine": "Big, white and heavy looking.", "archery_ticket_price": "0", - "id": "6626" - }, - { + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,1,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", "requirements": "{1,10}-{5,10}", "shop_price": "1920", - "ge_buy_limit": "100", - "examine": "Big, white, and heavy looking.", - "durability": null, - "weight": "8.1", - "equipment_slot": "7", - "grand_exchange_price": "2000", - "name": "White plateskirt", "tradeable": "true", + "weight": "9" + }, + { + "id": "6626", + "name": "White platelegs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "6627", - "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2000", - "durability": null, "name": "White plateskirt", - "tradeable": "true", + "examine": "Big, white, and heavy looking.", "archery_ticket_price": "0", - "id": "6628" + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,1,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,10}-{5,10}", + "shop_price": "1920", + "tradeable": "true", + "weight": "8.1" }, { + "id": "6628", + "name": "White plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6629", + "name": "White gloves", + "examine": "These will keep my hands warm!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,1,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", "requirements": "{1,10}-{5,10}", "shop_price": "6", - "ge_buy_limit": "100", - "examine": "These will keep my hands warm!", - "durability": null, - "weight": "0.2", - "equipment_slot": "9", - "grand_exchange_price": "2036", - "name": "White gloves", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6629", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,1,0,0" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2036", - "durability": null, + "id": "6630", "name": "White gloves", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6630" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "6631", + "name": "White sq shield", + "examine": "A medium square shield.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,15,16,14,0,15,9,0,1,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", "requirements": "{1,10}-{5,10}", "shop_price": "1152", - "ge_buy_limit": "100", - "examine": "A medium square shield.", + "tradeable": "true", + "weight": "3.6" + }, + { + "id": "6632", + "name": "White sq shield", + "archery_ticket_price": "0", "durability": null, - "weight": "3.6", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6633", + "name": "White kiteshield", + "examine": "A large metal shield.", "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "1360", - "name": "White sq shield", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6631", - "bonuses": "0,0,0,-6,-2,15,16,14,0,15,9,0,1,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1360", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,1,0,0", "durability": null, - "name": "White sq shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6632" - }, - { + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "100", "requirements": "{1,10}-{5,10}", "shop_price": "1632", - "ge_buy_limit": "100", - "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "2390", - "name": "White kiteshield", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6633", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,1,0,0" + "weight": "5.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2390", - "durability": null, + "id": "6634", "name": "White kiteshield", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6634" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A Temple Knight Communication Orb. Top Secret! / Use this to stay in touch with Korasi and Jessika. (A Void Dance version) / Tyr's commorb, given to him by Sir Tiffy. (Tyr's commorb)", - "durability": null, + "id": "6635", "name": "Commorb", - "weight": "1", + "examine": "A Temple Knight Communication Orb. Top Secret! / Use this to stay in touch with Korasi and Jessika. (A Void Dance version) / Tyr's commorb, given to him by Sir Tiffy. (Tyr's commorb)", "archery_ticket_price": "0", - "id": "6635" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "1" }, { - "examine": "Proof that I have defeated the evil mage Solus.", - "durability": null, + "id": "6636", "name": "Solus's hat", + "examine": "Proof that I have defeated the evil mage Solus.", "archery_ticket_price": "0", - "id": "6636" + "durability": null }, { - "examine": "From a darker dimension.", - "durability": null, + "id": "6637", "name": "Dark beast", + "examine": "From a darker dimension.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "6637" + "durability": null }, { - "examine": "A key to the nature of light itself. (Mourning's Ends Part II)", - "durability": null, + "id": "6638", "name": "Colour wheel", + "examine": "A key to the nature of light itself. (Mourning's Ends Part II)", "archery_ticket_price": "0", - "id": "6638" + "durability": null }, { - "destroy_message": "Resetting the light maze will generate a new mirror.", - "examine": "A small hand mirror.", - "durability": null, + "id": "6639", "name": "Hand mirror", - "tradeable": "false", - "destroy": "true", + "examine": "A small hand mirror.", "archery_ticket_price": "0", - "id": "6639" + "destroy": "true", + "destroy_message": "Resetting the light maze will generate a new mirror.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Resetting the light maze will generate a new crystal.", - "examine": "A yellow crystal.", - "durability": null, + "id": "6641", "name": "Yellow crystal", - "tradeable": "false", - "destroy": "true", + "examine": "A yellow crystal.", "archery_ticket_price": "0", - "id": "6641" + "destroy": "true", + "destroy_message": "Resetting the light maze will generate a new crystal.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Resetting the light maze will generate a new crystal.", - "examine": "A cyan crystal.", - "durability": null, + "id": "6643", "name": "Cyan crystal", - "tradeable": "false", - "destroy": "true", + "examine": "A cyan crystal.", "archery_ticket_price": "0", - "id": "6643" + "destroy": "true", + "destroy_message": "Resetting the light maze will generate a new crystal.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Resetting the light maze will generate a new crystal.", - "examine": "A blue crystal.", - "durability": null, + "id": "6644", "name": "Blue crystal", - "tradeable": "false", - "destroy": "true", + "examine": "A blue crystal.", "archery_ticket_price": "0", - "id": "6644" - }, - { + "destroy": "true", "destroy_message": "Resetting the light maze will generate a new crystal.", - "examine": "A fractured crystal, one of the edges is clear.", "durability": null, - "name": "Fractured crystal", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6646" + "tradeable": "false" }, { + "id": "6646", + "name": "Fractured crystal", + "examine": "A fractured crystal, one of the edges is clear.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "Resetting the light maze will generate a new crystal.", - "examine": "A fractured crystal, one of the edges is clear.", "durability": null, - "name": "Fractured crystal", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6647" + "tradeable": "false" }, { - "destroy_message": "You can obtain another list from Thorgel.", - "examine": "It's a list of items I need to collect.", + "id": "6647", + "name": "Fractured crystal", + "examine": "A fractured crystal, one of the edges is clear.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Resetting the light maze will generate a new crystal.", "durability": null, + "tradeable": "false" + }, + { + "id": "6648", "name": "Item list", - "tradeable": "false", - "destroy": "true", + "examine": "It's a list of items I need to collect.", "archery_ticket_price": "0", - "id": "6648" + "destroy": "true", + "destroy_message": "You can obtain another list from Thorgel.", + "durability": null, + "tradeable": "false" }, { - "examine": "The journal of Nissyen Edern.", - "durability": null, + "id": "6649", "name": "Edern's journal", - "tradeable": "false", - "destroy": "true", + "examine": "The journal of Nissyen Edern.", "archery_ticket_price": "0", - "id": "6649" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A blackened crystal sample.", - "durability": null, + "id": "6650", "name": "Blackened crystal", + "examine": "A blackened crystal sample.", "archery_ticket_price": "0", - "id": "6650" + "durability": null }, { - "examine": "A newly formed crystal / A warm energy radiates from this crystal.", - "durability": null, + "id": "6651", "name": "Newly made crystal", - "archery_ticket_price": "0", - "id": "6651" - }, - { "examine": "A newly formed crystal / A warm energy radiates from this crystal.", - "durability": null, - "name": "Newly made crystal", "archery_ticket_price": "0", - "id": "6652" + "durability": null }, { - "destroy_message": "You can get another Crystal trinket from Arianwyn in Lletya.", - "examine": "A small Crystal trinket.", - "durability": null, + "id": "6652", + "name": "Newly made crystal", + "examine": "A newly formed crystal / A warm energy radiates from this crystal.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6653", "name": "Crystal trinket", - "tradeable": "false", + "examine": "A small Crystal trinket.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "6653" + "destroy_message": "You can get another Crystal trinket from Arianwyn in Lletya.", + "durability": null, + "tradeable": "false" }, { - "remove_sleeves": "true", - "examine": "Examine what?", - "durability": null, - "name": "Camo top", - "weight": "2.7", - "archery_ticket_price": "0", "id": "6654", - "equipment_slot": "4" - }, - { - "examine": "Examine what?", - "durability": null, - "name": "Camo bottoms", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "6655", - "equipment_slot": "7" - }, - { - "examine": "Examine what?", - "durability": null, - "name": "Camo helmet", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "6656", - "equipment_slot": "0" - }, - { - "remove_sleeves": "true", - "examine": "Examine what?", - "durability": null, "name": "Camo top", - "weight": "2.7", + "examine": "Examine what?", "archery_ticket_price": "0", - "id": "6657", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2.7" }, { - "examine": "Examine what?", - "durability": null, + "id": "6655", "name": "Camo bottoms", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "6658", - "equipment_slot": "7" - }, - { "examine": "Examine what?", + "archery_ticket_price": "0", "durability": null, + "equipment_slot": "7", + "weight": "2.2" + }, + { + "id": "6656", "name": "Camo helmet", - "weight": "2.2", + "examine": "Examine what?", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "weight": "2.2" + }, + { + "id": "6657", + "name": "Camo top", + "examine": "Examine what?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2.7" + }, + { + "id": "6658", + "name": "Camo bottoms", + "examine": "Examine what?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "2.2" + }, + { "id": "6659", - "equipment_slot": "0" - }, - { - "shop_price": "60", - "examine": "The jar keeps shaking... I'm scared.", - "durability": null, - "name": "Fishing explosive", + "name": "Camo helmet", + "examine": "Examine what?", "archery_ticket_price": "0", - "id": "6660" + "durability": null, + "equipment_slot": "0", + "weight": "2.2" }, { - "examine": "An angry Ogre in a funny hat.", + "id": "6660", + "name": "Fishing explosive", + "examine": "The jar keeps shaking... I'm scared.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "60" + }, + { + "id": "6661", "name": "Mogre", + "examine": "An angry Ogre in a funny hat.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "6661" + "durability": null }, { - "examine": "This fishing rod seems to have been bitten in half.", - "durability": null, + "id": "6662", "name": "Broken fishing rod", + "examine": "This fishing rod seems to have been bitten in half.", "archery_ticket_price": "0", - "id": "6662" + "durability": null }, { - "examine": "It seems someone vacated this boot in a hurry.", - "durability": null, + "id": "6663", "name": "Forlorn boot", + "examine": "It seems someone vacated this boot in a hurry.", "archery_ticket_price": "0", - "id": "6663" + "durability": null }, { - "requirements": "{18,32}", - "shop_price": "60", - "examine": "The jar keeps shaking... I'm scared.", - "durability": null, + "id": "6664", "name": "Fishing explosive", + "examine": "The jar keeps shaking... I'm scared.", "archery_ticket_price": "0", - "id": "6664" + "durability": null, + "requirements": "{18,32}", + "shop_price": "60" }, { - "examine": "Fishy, damp and smelly.", - "durability": null, - "name": "Mudskipper hat", - "weight": "1", - "archery_ticket_price": "0", "id": "6665", - "equipment_slot": "0" + "name": "Mudskipper hat", + "examine": "Fishy, damp and smelly.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "weight": "1" }, { - "examine": "Strangely uncomfortable flippers.", - "durability": null, - "name": "Flippers", - "weight": "2", - "archery_ticket_price": "0", "id": "6666", + "name": "Flippers", + "examine": "Strangely uncomfortable flippers.", + "archery_ticket_price": "0", "bonuses": "-2,-2,-2,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "10" + "durability": null, + "equipment_slot": "10", + "weight": "2" }, { - "ge_buy_limit": "10000", + "id": "6667", + "name": "Fishbowl", "examine": "An empty fishbowl.", - "grand_exchange_price": "431", - "durability": null, - "name": "Fishbowl", - "tradeable": "true", - "weight": "1.3", "archery_ticket_price": "0", - "id": "6667" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1.3" }, { + "id": "6668", + "name": "Fishbowl", "examine": "A fishless fishbowl.", - "grand_exchange_price": "619", - "durability": null, - "name": "Fishbowl", - "tradeable": "true", - "weight": "2.3", "archery_ticket_price": "0", - "id": "6668" + "durability": null, + "tradeable": "true", + "weight": "2.3" }, { + "id": "6669", + "name": "Fishbowl", "examine": "A fishless fishbowl with some seaweed.", - "grand_exchange_price": "619", - "durability": null, - "name": "Fishbowl", - "tradeable": "true", - "weight": "2.3", "archery_ticket_price": "0", - "id": "6669" + "durability": null, + "tradeable": "true", + "weight": "2.3" }, { + "id": "6670", + "name": "Fishbowl", "examine": "A fishbowl with a Tiny Bluefish in it.", - "grand_exchange_price": "619", - "durability": null, - "name": "Fishbowl", - "tradeable": "true", - "weight": "2.3", "archery_ticket_price": "0", - "id": "6670" + "durability": null, + "tradeable": "true", + "weight": "2.3" }, { + "id": "6671", + "name": "Fishbowl", "examine": "A fishbowl with a Tiny Greenfish in it.", - "grand_exchange_price": "619", - "durability": null, - "name": "Fishbowl", - "tradeable": "true", - "weight": "2.3", "archery_ticket_price": "0", - "id": "6671" + "durability": null, + "tradeable": "true", + "weight": "2.3" }, { + "id": "6672", + "name": "Fishbowl", "examine": "A fishbowl with a Tiny Spinefish in it.", - "grand_exchange_price": "619", - "durability": null, - "name": "Fishbowl", - "tradeable": "true", - "weight": "2.3", "archery_ticket_price": "0", - "id": "6672" + "durability": null, + "tradeable": "true", + "weight": "2.3" }, { - "examine": "An empty fishbowl in a net.", - "durability": null, + "id": "6673", "name": "Fishbowl and net", - "weight": "2", + "examine": "An empty fishbowl in a net.", "archery_ticket_price": "0", - "id": "6673" + "durability": null, + "weight": "2" }, { - "shop_price": "10", - "examine": "A tiny net for grabbing tiny fish.", - "durability": null, + "id": "6674", "name": "Tiny net", - "tradeable": "false", + "examine": "A tiny net for grabbing tiny fish.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6674" + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "1" }, { - "examine": "'Ingredients: Ground Guam and Ground Seaweed.", - "durability": null, + "id": "6675", "name": "An empty box", + "examine": "'Ingredients: Ground Guam and Ground Seaweed.", "archery_ticket_price": "0", - "id": "6675" + "durability": null }, { - "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Guam Leaf...", - "durability": null, + "id": "6677", "name": "Guam in a box", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6677" - }, - { "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Guam Leaf...", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "6678", "name": "Guam in a box?", - "tradeable": "true", + "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Guam Leaf...", "archery_ticket_price": "0", - "id": "6678" + "durability": null, + "tradeable": "true" }, { - "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Seaweed...", - "durability": null, + "id": "6679", "name": "Seaweed in a box", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6679" - }, - { "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Seaweed...", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "6680", "name": "Seaweed in a box?", - "tradeable": "true", + "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Seaweed...", "archery_ticket_price": "0", - "id": "6680" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "One of the ingredients for making fish food.", - "grand_exchange_price": "1", - "durability": null, + "id": "6681", "name": "Ground guam", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6681" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, - "name": "Ground guam", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6682" - }, - { - "ge_buy_limit": "100", "examine": "One of the ingredients for making fish food.", - "grand_exchange_price": "14", - "durability": null, - "name": "Ground seaweed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6683" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "14", + "tradeable": "true" + }, + { + "id": "6682", + "name": "Ground guam", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6683", "name": "Ground seaweed", - "tradeable": "true", + "examine": "One of the ingredients for making fish food.", "archery_ticket_price": "0", - "id": "6684" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A Saradomin Brew.", - "grand_exchange_price": "15300", + "id": "6684", + "name": "Ground seaweed", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6685", "name": "Saradomin brew(4)", - "tradeable": "true", + "examine": "A Saradomin Brew.", "archery_ticket_price": "0", - "id": "6685" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "15300", - "durability": null, + "id": "6686", "name": "Saradomin brew(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6686" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A Saradomin Brew.", - "grand_exchange_price": "11400", - "durability": null, + "id": "6687", "name": "Saradomin brew(3)", - "tradeable": "true", + "examine": "A Saradomin Brew.", "archery_ticket_price": "0", - "id": "6687" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "11400", - "durability": null, + "id": "6688", "name": "Saradomin brew(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6688" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A Saradomin Brew.", - "grand_exchange_price": "7566", - "durability": null, + "id": "6689", "name": "Saradomin brew(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6689" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "7566", - "durability": null, - "name": "Saradomin brew(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6690" - }, - { - "ge_buy_limit": "1000", "examine": "A Saradomin Brew.", - "grand_exchange_price": "3783", - "durability": null, - "name": "Saradomin brew(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6691" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "3783", - "durability": null, - "name": "Saradomin brew(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6692" + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "6690", + "name": "Saradomin brew(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6691", + "name": "Saradomin brew(1)", + "examine": "A Saradomin Brew.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6692", + "name": "Saradomin brew(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6693", + "name": "Crushed nest", "examine": "It's a crushed bird's nest.", - "grand_exchange_price": "10500", - "durability": null, - "name": "Crushed nest", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6693" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "10500", - "durability": null, - "name": "Crushed nest", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6694" + "tradeable": "true" }, { - "examine": "\"A cold-blooded creature, partial to warmth.", + "id": "6694", + "name": "Crushed nest", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6695", "name": "Desert lizard", + "examine": "\"A cold-blooded creature, partial to warmth.", "archery_ticket_price": "0", - "id": "6695" + "durability": null }, { - "requirements": "{22,18}", - "shop_price": "1", - "examine": "Contains ice-cold water.", - "durability": null, + "id": "6696", "name": "Ice cooler", + "examine": "Contains ice-cold water.", "archery_ticket_price": "0", - "id": "6696" + "durability": null, + "requirements": "{22,18}", + "shop_price": "1" }, { - "shop_price": "5", - "ge_buy_limit": "10000", + "id": "6697", + "name": "Pat of butter", "examine": "A pat of freshly churned butter.", - "grand_exchange_price": "405", - "durability": null, - "name": "Pat of butter", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "6697" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "405", - "durability": null, - "name": "Pat of butter", + "shop_price": "5", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6698" + "weight": "0.2" }, { + "id": "6698", + "name": "Pat of butter", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6700", "name": "Burnt potato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6700" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "6701", + "name": "Baked potato", "examine": "It'd taste even better with some toppings.", - "grand_exchange_price": "326", - "durability": null, - "name": "Baked potato", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "6701" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "326", - "durability": null, + "id": "6702", "name": "Baked potato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6702" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "6703", + "name": "Potato with butter", "examine": "A baked potato with butter.", - "grand_exchange_price": "745", - "durability": null, - "name": "Potato with butter", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "6703" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "745", - "durability": null, + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "6704", "name": "Potato with butter", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6704" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "shop_price": "350", - "ge_buy_limit": "10000", + "id": "6705", + "name": "Potato with cheese", "examine": "A baked potato with butter and cheese.", - "grand_exchange_price": "604", - "durability": null, - "name": "Potato with cheese", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "6705" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "604", - "durability": null, - "name": "Potato with cheese", + "shop_price": "350", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6706" + "weight": "0.5" }, { - "examine": "An amulet of Camel-speak. It makes vague braying noises.", - "durability": null, - "name": "Camulet", + "id": "6706", + "name": "Potato with cheese", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { "id": "6707", + "name": "Camulet", + "examine": "An amulet of Camel-speak. It makes vague braying noises.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "2" }, { - "shop_price": "200", - "examine": "Especially good against diseased arachnids.", - "durability": null, - "name": "Slayer gloves", - "archery_ticket_price": "0", "id": "6708", - "bonuses": "0,0,0,0,0,4,5,3,0,0,1,0,0,0,0" + "name": "Slayer gloves", + "examine": "Especially good against diseased arachnids.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,4,5,3,0,0,1,0,0,0,0", + "durability": null, + "shop_price": "200" }, { - "examine": "A bunch of legs, eyes and teeth.", - "durability": null, + "id": "6709", "name": "Fever spider", + "examine": "A bunch of legs, eyes and teeth.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "6709" + "durability": null }, { - "examine": "A blindweed seed - plant in a Blindweed patch.", - "durability": null, + "id": "6710", "name": "Blindweed seed", + "examine": "A blindweed seed - plant in a Blindweed patch.", "archery_ticket_price": "0", - "id": "6710" + "durability": null }, { - "examine": "An inedible, foul smelling herb.", - "durability": null, + "id": "6711", "name": "Blindweed", + "examine": "An inedible, foul smelling herb.", "archery_ticket_price": "0", - "id": "6711" + "durability": null }, { - "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", - "grand_exchange_price": "74", - "durability": null, + "id": "6712", "name": "Bucket of water", + "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", + "archery_ticket_price": "0", + "durability": null, "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6712" + "weight": "3" }, { - "examine": "A heavy metal wrench.", - "durability": null, + "id": "6713", "name": "Wrench", + "examine": "A heavy metal wrench.", "archery_ticket_price": "0", - "id": "6713" + "durability": null }, { - "examine": "A shining paragon of wrenchly virtue.", - "durability": null, + "id": "6714", "name": "Holy wrench", + "examine": "A shining paragon of wrenchly virtue.", "archery_ticket_price": "0", - "id": "6714" + "durability": null }, { - "examine": "They look at you balefully. 'Feed us...", - "durability": null, + "id": "6715", "name": "Sluglings", + "examine": "They look at you balefully. 'Feed us...", "archery_ticket_price": "0", - "id": "6715" + "durability": null }, { - "examine": "A sinister looking squid.", - "durability": null, + "id": "6716", "name": "Karamthulhu", - "archery_ticket_price": "0", - "id": "6716" - }, - { "examine": "A sinister looking squid.", - "durability": null, - "name": "Karamthulhu", "archery_ticket_price": "0", - "id": "6717" + "durability": null }, { - "examine": "A diseased deceased Fever Spider. Handle with care.", - "durability": null, + "id": "6717", + "name": "Karamthulhu", + "examine": "A sinister looking squid.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6718", "name": "Fever spider body", + "examine": "A diseased deceased Fever Spider. Handle with care.", "archery_ticket_price": "0", - "id": "6718" + "durability": null }, { - "examine": "Sorry, I mean a bucket of 'rum'.", - "durability": null, + "id": "6719", "name": "Unsanitary swill", + "examine": "Sorry, I mean a bucket of 'rum'.", "archery_ticket_price": "0", - "id": "6719" + "durability": null }, { - "requirements": "{18,42}", - "shop_price": "200", - "examine": "Especially good against diseased arachnids.", - "durability": null, - "name": "Slayer gloves", - "archery_ticket_price": "0", "id": "6720", + "name": "Slayer gloves", + "examine": "Especially good against diseased arachnids.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,4,5,3,0,0,1,0,0,0,0", - "equipment_slot": "9" + "durability": null, + "equipment_slot": "9", + "requirements": "{18,42}", + "shop_price": "200" }, { + "id": "6721", + "name": "Rusty scimitar", "examine": "A decent enough weapon gone rusty.", + "archery_ticket_price": "0", "attack_audios": "2500,0,2517,0", "durability": null, - "name": "Rusty scimitar", - "weight": "2", - "archery_ticket_price": "0", - "id": "6721" + "weight": "2" }, { - "examine": "Alas...I hardly knew him.", - "durability": null, + "id": "6722", "name": "Zombie head", + "examine": "Alas...I hardly knew him.", "archery_ticket_price": "0", - "id": "6722" + "durability": null }, { - "durability": null, + "id": "6723", "name": "Fishbowl", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6723" + "durability": null, + "tradeable": "true" }, { - "requirements": "{4,50}", - "ge_buy_limit": "100", + "id": "6724", + "name": "Seercull", "examine": "An ancient Fremennik bow that was once used to battle the Moon Clan.", - "has_special": "true", - "durability": null, - "rare_item": "true", - "weight": "1", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", "attack_speed": "5", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "2588", + "requirements": "{4,50}", + "tradeable": "true", "two_handed": "true", "weapon_interface": "16", - "render_anim": "2588", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "lendable": "true", - "grand_exchange_price": "12200", - "name": "Seercull", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6724", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + "weight": "1" }, { + "id": "6725", + "name": "Seercull", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "12200", - "durability": null, - "name": "Seercull", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6725" + "tradeable": "true" }, { - "durability": null, + "id": "6726", "name": "Mud battlestaff", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6726" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "6727", "name": "Mystic mud staff", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6727" + "durability": null, + "tradeable": "true" }, { - "examine": "A pot of crushed small zombie monkey bones.", - "durability": null, + "id": "6728", "name": "Bonemeal", - "weight": "1", + "examine": "A pot of crushed small zombie monkey bones.", "archery_ticket_price": "0", - "id": "6728" + "durability": null, + "weight": "1" }, { - "ge_buy_limit": "10000", + "id": "6729", + "name": "Dagannoth bones", "examine": "These would feed a dogfish for months!", - "grand_exchange_price": "9616", - "durability": null, - "name": "Dagannoth bones", - "tradeable": "true", - "weight": "1.5", "archery_ticket_price": "0", - "id": "6729" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "9616", - "durability": null, + "tradeable": "true", + "weight": "1.5" + }, + { + "id": "6730", "name": "Dagannoth bones", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6730" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "10", - "examine": "A mysterious ring that can fill the wearer with magical power...", - "grand_exchange_price": "478800", - "rare_item": "true", - "durability": null, - "name": "Seers ring", - "tradeable": "true", - "archery_ticket_price": "0", "id": "6731", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "478800", - "durability": null, "name": "Seers ring", - "tradeable": "true", + "examine": "A mysterious ring that can fill the wearer with magical power...", "archery_ticket_price": "0", - "id": "6732" + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "10", - "examine": "A fabled ring that improves the wearer's skill with a bow...", - "grand_exchange_price": "1400000", - "rare_item": "true", - "durability": null, - "name": "Archers ring", - "tradeable": "true", + "id": "6732", + "name": "Seers ring", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "6733", - "bonuses": "0,0,0,0,4,0,0,0,0,4,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1400000", - "durability": null, "name": "Archers ring", - "tradeable": "true", + "examine": "A fabled ring that improves the wearer's skill with a bow...", "archery_ticket_price": "0", - "id": "6734" + "bonuses": "0,0,0,0,4,0,0,0,0,4,0,0,0,0,0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "tradeable": "true" }, { - "lendable": "true", - "ge_buy_limit": "10", - "examine": "A legendary ring once worn by Fremennik warriors.", - "grand_exchange_price": "178100", - "rare_item": "true", - "durability": null, - "name": "Warrior ring", - "tradeable": "true", + "id": "6734", + "name": "Archers ring", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "6735", - "bonuses": "0,4,0,0,0,0,4,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "178100", - "durability": null, "name": "Warrior ring", - "tradeable": "true", + "examine": "A legendary ring once worn by Fremennik warriors.", "archery_ticket_price": "0", - "id": "6736" - }, - { + "bonuses": "0,4,0,0,0,0,4,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10", "lendable": "true", - "ge_buy_limit": "10", - "examine": "A ring reputed to bring out a berserk fury in its wearer.", - "grand_exchange_price": "2700000", "rare_item": "true", - "durability": null, - "name": "Berserker ring", - "tradeable": "true", + "tradeable": "true" + }, + { + "id": "6736", + "name": "Warrior ring", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "6737", - "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "2700000", - "durability": null, "name": "Berserker ring", - "tradeable": "true", + "examine": "A ring reputed to bring out a berserk fury in its wearer.", "archery_ticket_price": "0", - "id": "6738" + "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "tradeable": "true" }, { - "requirements": "{0,60}", + "id": "6738", + "name": "Berserker ring", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6739", + "name": "Dragon axe", "examine": "A very powerful axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2498,2498,2497,2498", + "bonuses": "-2,38,32,0,0,0,1,0,0,0,0,42,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "ge_buy_limit": "10", "has_special": "true", "rare_item": "true", - "durability": null, - "weapon_interface": "2", "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "grand_exchange_price": "813100", - "attack_audios": "2498,2498,2497,2498", - "name": "Dragon axe", + "requirements": "{0,60}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6739", - "bonuses": "-2,38,32,0,0,0,1,0,0,0,0,42,0,0,0" + "weapon_interface": "2" }, { + "id": "6740", + "name": "Dragon axe", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "813100", - "durability": null, - "name": "Dragon axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6740" + "tradeable": "true" }, { - "examine": "Bob can fix this broken (metal) axe for me.", - "durability": null, - "name": "Broken axe", - "weight": "2.5", - "archery_ticket_price": "0", "id": "6741", - "equipment_slot": "3" - }, - { - "durability": null, "name": "Broken axe", - "tradeable": "true", + "examine": "Bob can fix this broken (metal) axe for me.", "archery_ticket_price": "0", - "id": "6742" + "durability": null, + "equipment_slot": "3", + "weight": "2.5" }, { + "id": "6742", + "name": "Broken axe", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "6744", "name": "Picture", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6744" + "durability": null, + "tradeable": "true" }, { - "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", - "durability": null, - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "6", - "render_anim": "2554", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "name": "Silverlight", - "archery_ticket_price": "0", "id": "6745", - "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0" - }, - { - "examine": "The magical sword Silverlight, enhanced with the blood of Agrith-Naar.", - "has_special": "true", - "durability": null, - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "6", - "render_anim": "2554", - "defence_anim": "397", - "equipment_slot": "3", + "name": "Silverlight", + "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", + "archery_ticket_price": "0", "attack_anims": "390,390,381,390", - "name": "Darklight", - "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "render_anim": "2554", + "weapon_interface": "6", + "weight": "1.8" + }, + { "id": "6746", - "bonuses": "10,16,-2,0,0,0,3,2,2,0,0,13,0,0,0" + "name": "Darklight", + "examine": "The magical sword Silverlight, enhanced with the blood of Agrith-Naar.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "5", + "bonuses": "10,16,-2,0,0,0,3,2,2,0,0,13,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "2554", + "weapon_interface": "6", + "weight": "1.8" }, { - "examine": "Used to make the sigil of the demon Agrith-Naar.", - "durability": null, + "id": "6747", "name": "Demonic sigil mould", + "examine": "Used to make the sigil of the demon Agrith-Naar.", "archery_ticket_price": "0", - "id": "6747" + "durability": null }, { - "examine": "A sigil used for the summoning of the demon Agrith-Naar.", - "durability": null, + "id": "6748", "name": "Demonic sigil", - "weight": "1.8", + "examine": "A sigil used for the summoning of the demon Agrith-Naar.", "archery_ticket_price": "0", - "id": "6748" + "durability": null, + "weight": "1.8" }, { - "examine": "Will this book help in summoning Agrith-Naar?", - "durability": null, + "id": "6749", "name": "Demonic tome", - "weight": "0.4", + "examine": "Will this book help in summoning Agrith-Naar?", "archery_ticket_price": "0", - "id": "6749" + "durability": null, + "weight": "0.4" }, { - "remove_sleeves": "true", - "examine": "A desert shirt stained black with mushroom ink.", - "durability": null, - "name": "Black desert shirt", - "archery_ticket_price": "0", "id": "6750", - "equipment_slot": "4" + "name": "Black desert shirt", + "examine": "A desert shirt stained black with mushroom ink.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { - "examine": "A desert robe stained black with mushroom ink.", - "durability": null, - "name": "Black desert robe", - "archery_ticket_price": "0", "id": "6752", + "name": "Black desert robe", + "examine": "A desert robe stained black with mushroom ink.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "7" }, { - "destroy_message": "Hopefully Erin has a copy!", - "examine": "It changes temperature as I walk. (Meeting History)", - "durability": null, - "name": "Enchanted key", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "6754", - "equipment_slot": "3" + "name": "Enchanted key", + "examine": "It changes temperature as I walk. (Meeting History)", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Hopefully Erin has a copy!", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A Guthix Mjolnir.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "You can reclaim this item from the place you found it.", - "grand_exchange_price": "2875", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "6760", - "stand_turn_anim": "1209", - "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", - "shop_price": "250", - "durability": null, - "weight": "2", - "weapon_interface": "3", - "render_anim": "28", - "name": "Guthix mjolnir" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2875", - "durability": null, "name": "Guthix mjolnir", - "tradeable": "true", + "examine": "A Guthix Mjolnir.", "archery_ticket_price": "0", - "id": "6761" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A Saradomin Mjolnir.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", "attack_anims": "2080,2081,2082,2080", - "destroy_message": "You can reclaim this item from the place you found it.", - "grand_exchange_price": "17200", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6762", - "stand_turn_anim": "1209", + "attack_speed": "5", "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "defence_anim": "2079", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", "shop_price": "250", - "durability": null, - "weight": "2", - "weapon_interface": "3", - "render_anim": "28", - "name": "Saradomin mjolnir" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "17200", - "durability": null, - "name": "Saradomin mjolnir", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6763" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A Zamorak mjolnir.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "You can reclaim this item from the place you found it.", - "grand_exchange_price": "4115", "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6764", "stand_turn_anim": "1209", - "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", - "durability": null, - "weight": "2", - "weapon_interface": "3", - "render_anim": "28", - "name": "Zamorak mjolnir" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4115", - "durability": null, - "name": "Zamorak mjolnir", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6765" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" }, { - "examine": "Antipoison for Pox.", + "id": "6761", + "name": "Guthix mjolnir", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6762", + "name": "Saradomin mjolnir", + "examine": "A Saradomin Mjolnir.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "defence_anim": "2079", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "250", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" + }, + { + "id": "6763", + "name": "Saradomin mjolnir", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6764", + "name": "Zamorak mjolnir", + "examine": "A Zamorak mjolnir.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "defence_anim": "2079", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" + }, + { + "id": "6765", + "name": "Zamorak mjolnir", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6766", "name": "Cat antipoison", + "examine": "Antipoison for Pox.", "archery_ticket_price": "0", - "id": "6766" + "durability": null }, { - "examine": "A little more smelly than usual.", - "durability": null, + "id": "6768", "name": "Poisoned cheese", - "weight": "0.2", + "examine": "A little more smelly than usual.", "archery_ticket_price": "0", - "id": "6768" + "durability": null, + "weight": "0.2" }, { - "destroy_message": "You can obtain another sheet of music by talking to the snakecharmer of Pollnivneach.", - "examine": "Charming.", - "durability": null, + "id": "6769", "name": "Music scroll", - "tradeable": "false", - "destroy": "true", + "examine": "Charming.", "archery_ticket_price": "0", - "id": "6769" + "destroy": "true", + "destroy_message": "You can obtain another sheet of music by talking to the snakecharmer of Pollnivneach.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can obtain another set of directions to the party by talking to Jimmy Dazzler.", - "examine": "Jimmy Dazzler's directions.", - "durability": null, + "id": "6770", "name": "Directions", - "tradeable": "false", + "examine": "Jimmy Dazzler's directions.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "6770" + "destroy_message": "You can obtain another set of directions to the party by talking to Jimmy Dazzler.", + "durability": null, + "tradeable": "false" }, { - "examine": "Contains garden weeds.", - "durability": null, + "id": "6771", "name": "Pot of weeds", + "examine": "Contains garden weeds.", "archery_ticket_price": "0", - "id": "6771" + "durability": null }, { - "examine": "Contains slowly burning garden weeds.", - "durability": null, + "id": "6772", "name": "Smouldering pot", + "examine": "Contains slowly burning garden weeds.", "archery_ticket_price": "0", - "id": "6772" + "durability": null }, { - "turn90cw_anim": "1424", - "examine": "A pole for putting rats on.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Rat pole", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "6773", + "name": "Rat pole", + "examine": "A pole for putting rats on.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" }, { - "turn90cw_anim": "1424", - "examine": "A pole with one rat on it.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Rat pole", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "6774", + "name": "Rat pole", + "examine": "A pole with one rat on it.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" }, { - "turn90cw_anim": "1424", - "examine": "A pole with two rats on it.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Rat pole", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "6775", + "name": "Rat pole", + "examine": "A pole with two rats on it.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" }, { - "turn90cw_anim": "1424", - "examine": "A pole with three rats on it.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Rat pole", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "6776", + "name": "Rat pole", + "examine": "A pole with three rats on it.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" }, { - "turn90cw_anim": "1424", - "examine": "A pole with four rats on it.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Rat pole", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "6777", + "name": "Rat pole", + "examine": "A pole with four rats on it.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" }, { - "turn90cw_anim": "1424", - "examine": "A pole with five rats on it.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Rat pole", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "6778", - "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1424", - "examine": "A pole with six rats on it.", - "walk_anim": "1422", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1425", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "10", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", "name": "Rat pole", + "examine": "A pole with five rats on it.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", "run_anim": "1427", - "archery_ticket_price": "0", - "id": "6779", + "stand_anim": "1421", "stand_turn_anim": "1426", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" }, { - "examine": "Menaphite thug.", + "id": "6779", + "name": "Rat pole", + "examine": "A pole with six rats on it.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "10", + "weight": "2.2" + }, + { + "id": "6780", "name": "Menaphite thug", + "examine": "Menaphite thug.", "archery_ticket_price": "0", - "id": "6780" + "durability": null }, { - "remove_sleeves": "true", - "examine": "This looks quite old.", - "durability": null, - "name": "Robe of elidinis", - "archery_ticket_price": "0", "id": "6786", - "equipment_slot": "4" + "name": "Robe of elidinis", + "examine": "This looks quite old.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { - "examine": "This looks quite old.", - "durability": null, - "name": "Robe of elidinis", - "archery_ticket_price": "0", "id": "6787", + "name": "Robe of elidinis", + "examine": "This looks quite old.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "7" }, { - "examine": "This robe is too torn to wear.", - "durability": null, + "id": "6788", "name": "Torn robe", - "weight": "1", + "examine": "This robe is too torn to wear.", "archery_ticket_price": "0", - "id": "6788" + "durability": null, + "weight": "1" }, { - "examine": "This robe is too torn to wear.", - "durability": null, + "id": "6789", "name": "Torn robe", - "weight": "1", + "examine": "This robe is too torn to wear.", "archery_ticket_price": "0", - "id": "6789" + "durability": null, + "weight": "1" }, { - "durability": null, + "id": "6790", "name": "Shoes", "archery_ticket_price": "0", - "id": "6790", + "durability": null, "equipment_slot": "10" }, { - "examine": "Awusah's Sole.", - "durability": null, + "id": "6791", "name": "Sole", - "weight": "1", + "examine": "Awusah's Sole.", "archery_ticket_price": "0", - "id": "6791" + "durability": null, + "weight": "1" }, { - "examine": "An ancient key from the shrine in Nardah. (Spirits of the Elid)", - "durability": null, + "id": "6792", "name": "Ancestral key", + "examine": "An ancient key from the shrine in Nardah. (Spirits of the Elid)", "archery_ticket_price": "0", - "id": "6792" + "durability": null }, { - "examine": "The Ballad of Jaresh.", - "durability": null, + "id": "6793", "name": "Ballad", + "examine": "The Ballad of Jaresh.", "archery_ticket_price": "0", - "id": "6793" + "durability": null }, { - "shop_price": "30", - "ge_buy_limit": "1000", + "id": "6794", + "name": "Choc-ice", "examine": "A tasty treat from Nardah - better eat this before it melts.", - "grand_exchange_price": "210", - "durability": null, - "name": "Choc-ice", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6794" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "210", - "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "6795", "name": "Choc-ice", - "tradeable": "true", "archery_ticket_price": "0", - "id": "6795" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "bankable": "false", - "examine": "Wonder what happens if I rub it...", - "durability": null, + "id": "6796", "name": "Lamp", - "weight": "0.1", + "examine": "Wonder what happens if I rub it...", "archery_ticket_price": "0", - "id": "6796" + "bankable": "false", + "durability": null, + "weight": "0.1" }, { - "shop_price": "8", - "examine": "See article", - "grand_exchange_price": "206", - "durability": null, + "id": "6797", "name": "Watering can", + "examine": "See article", "archery_ticket_price": "0", - "id": "6797" + "durability": null, + "shop_price": "8" }, { - "examine": "A scroll once used by a champion.", - "durability": null, + "id": "6798", "name": "Champion scroll", - "archery_ticket_price": "0", - "id": "6798" - }, - { "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6799" + "durability": null }, { + "id": "6799", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6800" + "durability": null }, { + "id": "6800", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6801" + "durability": null }, { + "id": "6801", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6802" + "durability": null }, { + "id": "6802", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6803" + "durability": null }, { + "id": "6803", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6804" + "durability": null }, { + "id": "6804", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6805" + "durability": null }, { + "id": "6805", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6806" + "durability": null }, { + "id": "6806", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6807" + "durability": null }, { + "id": "6807", + "name": "Champion scroll", "examine": "A scroll once used by a champion.", - "durability": null, - "name": "Champion scroll", "archery_ticket_price": "0", - "id": "6808" + "durability": null }, { - "requirements": "{1,50}-{2,50}", - "ge_buy_limit": "10", - "examine": "These look pretty heavy.", - "durability": null, - "weight": "15", - "absorb": "2,0,5", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "39400", - "name": "Granite legs", - "tradeable": "true", + "id": "6808", + "name": "Champion scroll", + "examine": "A scroll once used by a champion.", "archery_ticket_price": "0", + "durability": null + }, + { "id": "6809", - "bonuses": "0,0,0,-31,-18,43,45,41,-4,68,20,0,0,0,0" - }, - { - "examine": "A pot of crushed large zombie monkey bones.", - "durability": null, - "name": "Bonemeal", - "weight": "1", + "name": "Granite legs", + "examine": "These look pretty heavy.", + "absorb": "2,0,5", "archery_ticket_price": "0", - "id": "6810" + "bonuses": "0,0,0,-31,-18,43,45,41,-4,68,20,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "lendable": "true", + "requirements": "{1,50}-{2,50}", + "tradeable": "true", + "weight": "15" }, { - "examine": "A very dangerous pile of animated Wyvern bones.", + "id": "6810", + "name": "Bonemeal", + "examine": "A pot of crushed large zombie monkey bones.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "6811", "name": "Skeletal wyvern", + "examine": "A very dangerous pile of animated Wyvern bones.", "archery_ticket_price": "0", "attack_speed": "6", - "id": "6811" + "durability": null }, { - "ge_buy_limit": "1000", + "id": "6812", + "name": "Wyvern bones", "examine": "Bones of a huge flying creature.", - "grand_exchange_price": "4845", - "durability": null, - "name": "Wyvern bones", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6812" - }, - { - "durability": null, - "name": "Granite legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6813" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "This would make warm clothing.", - "grand_exchange_price": "90", - "durability": null, - "name": "Fur", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "6814" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "90", - "durability": null, - "name": "Fur", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6815" - }, - { - "durability": null, - "name": "Wyvern bones", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6816" - }, - { - "turn90cw_anim": "7044", - "examine": "A slender two-handed sword.", - "walk_anim": "7046", - "durability": null, - "destroy": "true", - "weight": "3", - "turn90ccw_anim": "7043", - "two_handed": "true", - "turn180_anim": "7045", - "render_anim": "124", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "7047", - "name": "Slender blade", - "tradeable": "false", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "6817", - "stand_turn_anim": "7040" - }, - { - "turn90cw_anim": "1207", - "examine": "A sharp sword that can also fire arrows.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "3", - "turn90ccw_anim": "1208", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "You can make a replacement.", - "stand_anim": "813", - "name": "Bow-sword", - "tradeable": "false", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6818", - "stand_turn_anim": "1209" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "25000", - "examine": "A large pouch used for storing essence.", - "durability": null, - "name": "Large pouch", - "weight": "1", - "archery_ticket_price": "0", - "id": "6819" - }, - { - "destroy_message": "I can get another from the assassin beside the winch that leads down into Senntisten temple.", - "examine": "It seems to have pieces missing. After Temple at Senntisten quest: The assassin's plunder from the church on Entrana.", - "durability": null, - "name": "Relic", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6820" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This looks valuable.", - "durability": null, - "name": "Orb", - "archery_ticket_price": "0", - "id": "6821" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Star bauble", - "archery_ticket_price": "0", - "id": "6822" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Star bauble", - "archery_ticket_price": "0", - "id": "6823" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Star bauble", - "archery_ticket_price": "0", - "id": "6824" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Star bauble", - "archery_ticket_price": "0", - "id": "6825" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Star bauble", - "archery_ticket_price": "0", - "id": "6826" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Star bauble", - "archery_ticket_price": "0", - "id": "6827" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Box bauble", - "archery_ticket_price": "0", - "id": "6828" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Box bauble", - "archery_ticket_price": "0", - "id": "6829" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Box bauble", - "archery_ticket_price": "0", - "id": "6830" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Box bauble", - "archery_ticket_price": "0", - "id": "6831" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Box bauble", - "archery_ticket_price": "0", - "id": "6832" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Box bauble", - "archery_ticket_price": "0", - "id": "6833" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Diamond bauble", - "archery_ticket_price": "0", - "id": "6834" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Diamond bauble", - "archery_ticket_price": "0", - "id": "6835" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Diamond bauble", - "archery_ticket_price": "0", - "id": "6836" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Diamond bauble", - "archery_ticket_price": "0", - "id": "6837" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Diamond bauble", - "archery_ticket_price": "0", - "id": "6838" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Diamond bauble", - "archery_ticket_price": "0", - "id": "6839" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Tree bauble", - "archery_ticket_price": "0", - "id": "6840" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Tree bauble", - "archery_ticket_price": "0", - "id": "6841" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Tree bauble", - "archery_ticket_price": "0", - "id": "6842" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Tree bauble", - "archery_ticket_price": "0", - "id": "6843" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Tree bauble", - "archery_ticket_price": "0", - "id": "6844" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Tree bauble", - "archery_ticket_price": "0", - "id": "6845" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Bell bauble", - "archery_ticket_price": "0", - "id": "6846" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Bell bauble", - "archery_ticket_price": "0", - "id": "6847" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Bell bauble", - "archery_ticket_price": "0", - "id": "6848" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Bell bauble", - "archery_ticket_price": "0", - "id": "6849" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Bell bauble", - "archery_ticket_price": "0", - "id": "6850" - }, - { - "examine": "See individual articles.", - "durability": null, - "name": "Bell bauble", - "archery_ticket_price": "0", - "id": "6851" - }, - { - "examine": "A box for storing completed puppets.", - "durability": null, - "name": "Puppet box", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6852" - }, - { - "examine": "A box for storing painted baubles.", - "durability": null, - "name": "Bauble box", - "archery_ticket_price": "0", - "id": "6853" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A box for storing completed puppets.", - "durability": null, - "name": "Puppet box", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6854" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A box for storing painted baubles.", - "durability": null, - "name": "Bauble box", - "archery_ticket_price": "0", - "id": "6855" - }, - { - "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", - "examine": "A woolly bobble hat.", - "durability": null, - "name": "Bobble hat", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6856", - "equipment_slot": "0" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A woolly scarf.", - "durability": null, - "name": "Bobble scarf", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6857", - "equipment_slot": "2" - }, - { - "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", - "shop_price": "160", - "examine": "A woolly Jester hat.", - "durability": null, - "name": "Jester hat", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6858", - "equipment_slot": "0" - }, - { - "destroy_message": "You can get another Jester scarf from Diango.", - "examine": "A woolly jester scarf.", - "durability": null, - "name": "Jester scarf", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6859", - "equipment_slot": "2" - }, - { - "destroy_message": "You may get another from Diango in Draynor Village.", - "examine": "A woolly triple bobble jester hat.", - "durability": null, - "name": "Tri-jester hat", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6860", - "equipment_slot": "0" - }, - { - "destroy_message": "You can obtain another jester scarf from Diango in the Draynor Market.", - "examine": "A woolly jester scarf.", - "durability": null, - "name": "Tri-jester scarf", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6861", - "equipment_slot": "2" - }, - { - "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", - "examine": "A woolly tobogganing hat.", - "durability": null, - "name": "Woolly hat", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6862", - "equipment_slot": "0" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A woolly tobogganing scarf.", - "durability": null, - "name": "Woolly scarf", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", - "id": "6863", - "equipment_slot": "2" - }, - { - "examine": "The controlling part of a marionette.", - "durability": null, - "name": "Marionette handle", - "archery_ticket_price": "0", - "id": "6864", - "equipment_slot": "3" - }, - { - "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Blue marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6865" - }, - { - "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Green marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6866" - }, - { - "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Red marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6867" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Blue marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6868" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Green marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6869" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Red marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6870" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Red marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6871" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Red marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6872" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Red marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6873" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Red marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6874" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Blue marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6875" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Blue marionette", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "6876" - }, - { - "examine": "I've got no strings ... oh hang on!", "durability": null, - "name": "Blue marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6877" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Blue marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6878" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Green marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6879" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Green marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6880" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Green marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6881" - }, - { - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Green marionette", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6882" - }, - { - "examine": "A tasty fruit.", - "durability": null, - "name": "Peach", - "archery_ticket_price": "0", - "id": "6883" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A magic training arena progress hat", - "durability": null, - "name": "Progress hat", - "archery_ticket_price": "0", - "id": "6885", - "equipment_slot": "0" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A magic training arena progress hat", - "durability": null, - "name": "Progress hat", - "archery_ticket_price": "0", - "id": "6886", - "equipment_slot": "0" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A magic training arena progress hat", - "durability": null, - "name": "Progress hat", - "archery_ticket_price": "0", - "id": "6887", - "equipment_slot": "0" - }, - { - "bankable": "false", - "examine": "A guardian of the arena.", - "durability": null, - "name": "Guardian statue", - "archery_ticket_price": "0", - "id": "6888" - }, - { - "requirements": "{6,60}", - "ge_buy_limit": "10", - "examine": "The magical book of the Mage.", - "grand_exchange_price": "3800000", - "durability": null, - "name": "Mage's book", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6889", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "3800000", - "durability": null, - "name": "Mage's book", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6890" - }, - { - "shop_price": "200", - "examine": "A book about the Training Arena.", - "durability": null, - "name": "Arena book", - "weight": "1", - "archery_ticket_price": "0", - "id": "6891" - }, - { - "bankable": "false", - "shop_price": "6", - "examine": "Comfortable leather boots.", - "grand_exchange_price": "189", - "durability": null, - "name": "Leather boots", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "6893", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0" - }, - { - "bankable": "false", - "examine": "A large metal shield.", - "grand_exchange_price": "3084", - "durability": null, - "name": "Adamant kiteshield", - "tradeable": "true", - "weight": "5.8", - "archery_ticket_price": "0", - "id": "6894", - "absorb": "3,0,6", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "bankable": "false", - "examine": "A medium sized helmet.", - "grand_exchange_price": "1049", - "durability": null, - "name": "Adamant med helm", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "6895", - "absorb": "1,0,2", - "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0" - }, - { - "bankable": "false", - "shop_price": "350", - "examine": "This looks valuable.", - "grand_exchange_price": "644", - "durability": null, - "name": "Emerald", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6896" - }, - { - "bankable": "false", - "shop_price": "32000", - "examine": "A razor sharp longsword", - "durability": null, - "weight": "1.8", - "attack_speed": "5", - "lendable": "true", - "grand_exchange_price": "18938", - "attack_audios": "2500,2500,2517,2500", - "name": "Rune longsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6897", - "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0" - }, - { - "bankable": "false", - "examine": "A green cylinder", - "durability": null, - "name": "Cylinder", - "archery_ticket_price": "0", - "id": "6898" - }, - { - "bankable": "false", - "examine": "A yellow cube", - "durability": null, - "name": "Cube", - "archery_ticket_price": "0", - "id": "6899" - }, - { - "bankable": "false", - "examine": "A blue icosahedron.", - "durability": null, - "name": "Icosahedron", - "archery_ticket_price": "0", - "id": "6900" - }, - { - "bankable": "false", - "examine": "A red pentamid.", - "durability": null, - "name": "Pentamid", - "archery_ticket_price": "0", - "id": "6901" - }, - { - "bankable": "false", - "examine": "This looks valuable.", - "durability": null, - "name": "Orb", - "archery_ticket_price": "0", - "id": "6902" - }, - { - "bankable": "false", - "examine": "This looks valuable.", - "durability": null, - "name": "Dragonstone", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "6903" - }, - { - "examine": "Various animals' bones.", - "durability": null, - "name": "Animals' bones", - "archery_ticket_price": "0", - "id": "6904" - }, - { - "examine": "Various animals' bones.", - "durability": null, - "name": "Animals' bones", - "archery_ticket_price": "0", - "id": "6905" - }, - { - "examine": "Various animals' bones.", - "durability": null, - "name": "Animals' bones", - "archery_ticket_price": "0", - "id": "6906" - }, - { - "examine": "Various animals' bones.", - "durability": null, - "name": "Animals' bones", - "archery_ticket_price": "0", - "id": "6907" - }, - { - "requirements": "{6,45}", - "shop_price": "303030030", - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A beginner level wand", - "walk_anim": "1146", - "durability": null, - "weight": "0.2", - "turn90ccw_anim": "822", - "weapon_interface": "1", - "turn180_anim": "820", - "render_anim": "1426", - "equipment_slot": "3", - "grand_exchange_price": "11500", - "stand_anim": "809", - "name": "Beginner wand", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6908", - "stand_turn_anim": "823", - "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "11500", - "durability": null, - "name": "Beginner wand", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6909" - }, - { - "requirements": "{6,50}", - "ge_buy_limit": "10", - "shop_price": "606060060", - "turn90cw_anim": "821", - "examine": "An apprentice level wand.", - "walk_anim": "1146", - "durability": null, - "turn90ccw_anim": "822", - "weapon_interface": "1", - "turn180_anim": "820", - "defence_anim": "420", - "render_anim": "1426", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "82000", - "stand_anim": "809", - "tradeable": "true", - "name": "Apprentice wand", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6910", - "stand_turn_anim": "823", - "bonuses": "0,0,0,10,0,0,0,0,10,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "82000", - "durability": null, - "name": "Apprentice wand", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6911" - }, - { - "requirements": "{6,55}", - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A teacher level wand.", - "walk_anim": "1146", - "durability": null, - "turn90ccw_anim": "822", - "weapon_interface": "1", - "turn180_anim": "820", - "render_anim": "1426", - "equipment_slot": "3", - "grand_exchange_price": "944100", - "stand_anim": "809", - "name": "Teacher wand", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6912", - "stand_turn_anim": "823", - "bonuses": "0,0,0,15,0,0,0,0,15,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "944100", - "durability": null, - "name": "Teacher wand", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6913" - }, - { - "requirements": "{6,60}", - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A master level wand.", - "walk_anim": "1146", - "durability": null, - "weight": "0.1", - "turn90ccw_anim": "822", - "weapon_interface": "1", - "turn180_anim": "820", - "defence_anim": "420", - "render_anim": "1426", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "1700000", - "stand_anim": "8980", - "tradeable": "true", - "name": "Master wand", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "6914", - "stand_turn_anim": "823", - "bonuses": "0,0,0,20,0,0,0,0,20,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1700000", - "durability": null, - "name": "Master wand", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6915" - }, - { - "requirements": "{1,25}-{6,50}", - "ge_buy_limit": "10", - "examine": "Mystical robes.", - "durability": null, - "weight": "2.2", - "absorb": "3,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "3300000", - "name": "Infinity top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6916", - "bonuses": "0,0,0,22,0,0,0,0,22,0,20,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "3300000", - "durability": null, - "name": "Infinity top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6917" - }, - { - "requirements": "{1,25}-{6,50}", - "ge_buy_limit": "10", - "examine": "A mystic hat.", - "durability": null, - "weight": "0.4", - "absorb": "1,0,0", - "equipment_slot": "0", - "grand_exchange_price": "1800000", - "name": "Infinity hat", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": true, - "id": "6918", - "bonuses": "0,0,0,6,0,0,0,0,6,0,7,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1800000", - "durability": null, - "name": "Infinity hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6919" - }, - { - "requirements": "{1,25}-{6,50}", - "ge_buy_limit": "10", - "examine": "Mystical boots.", - "durability": null, - "destroy": "true", - "weight": "0.4", - "equipment_slot": "10", - "grand_exchange_price": "1200000", - "name": "Infinity boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6920", - "bonuses": "0,0,0,5,0,0,0,0,5,0,5,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Infinity boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6921" - }, - { - "requirements": "{1,25}-{6,50}", - "ge_buy_limit": "10", - "examine": "Mystical gloves.", - "grand_exchange_price": "1900000", - "durability": null, - "name": "Infinity gloves", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "6922", - "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1900000", - "durability": null, - "name": "Infinity gloves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6923" - }, - { - "requirements": "{1,25}-{6,50}", - "ge_buy_limit": "10", - "examine": "Mystical robes.", - "durability": null, - "weight": "1.8", - "absorb": "2,1,0", - "equipment_slot": "7", - "grand_exchange_price": "2500000", - "name": "Infinity bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6924", - "bonuses": "0,0,0,17,0,0,0,0,17,0,17,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "2500000", - "durability": null, - "name": "Infinity bottoms", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6925" - }, - { - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "983", - "durability": null, - "name": "Bones to peaches", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6926" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A severed hand covered with sand.", - "durability": null, - "name": "Sandy hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6945" - }, - { - "destroy_message": "Speak to the Guard Captain in Yanille to get another beer soaked hand.", - "examine": "A severed hand dripping with beer.", - "durability": null, - "name": "Beer-soaked hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6946" - }, - { - "destroy_message": "Speak to Bert to replace this Rota.", - "examine": "A copy of a work rota.", - "durability": null, - "name": "Bert's rota", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6947" - }, - { - "destroy_message": "Search Sandy's office in Brimhaven for another Rota.", - "examine": "An original work rota.", - "durability": null, - "name": "Sandy's rota", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6948" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Maybe I should read this...", - "durability": null, - "name": "A magic scroll", - "archery_ticket_price": "0", - "id": "6949" - }, - { - "destroy_message": "Speak to Zavistic Rarve to replace your magical orb.", - "examine": "An ordinary looking scrying orb.", - "durability": null, - "name": "Magical orb", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6950" - }, - { - "destroy_message": "Speak to Zavistic Rarve to replace your magical orb.", - "examine": "This magical scrying orb pulsates as it stores information.", - "durability": null, - "name": "Magical orb (a)", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6951" - }, - { - "destroy_message": "Speak to Betty in Port Sarim to get another bottle of truth serum.", - "examine": "Fluid sloshes innocently in this vial.", - "durability": null, - "name": "Truth serum", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6952" - }, - { - "destroy_message": "Speak to Betty in Port Sarim to get another bottle.", - "examine": "A bottle of water.", - "durability": null, - "name": "Bottled water", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6953" - }, - { - "destroy_message": "Speak to Betty in Port Sarim to get another bottle to make some more red berry juice.", - "examine": "Redberry juice sloshes around in this vial, waiting for white berries to be added.", - "durability": null, - "name": "Redberry juice", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6954" - }, - { - "destroy_message": "Speak to Betty in Port Sarim to make more pink dye.", - "shop_price": "20", - "examine": "A vial of pink dye.", - "durability": null, - "name": "Pink dye", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6955" - }, - { - "destroy_message": "Speak to Betty in Port Sarim to get another bottle to make the lens again.", - "examine": "This lens has a pinkish tinge to it.", - "durability": null, - "name": "Rose-tinted lens", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6956", - "equipment_slot": "3" - }, - { - "destroy_message": "Speak to Mazion near the sandpit on Entrana to find the Wizard Head again.", - "examine": "A decapitated, sand-covered head.", - "durability": null, - "name": "Wizard's head", - "tradeable": "false", - "destroy": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "6957" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A handful of sand from Sandy's pocket.", - "durability": null, - "name": "Sand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6958" - }, - { - "shop_price": "20", - "ge_buy_limit": "100", - "examine": "Use pink dye on a cape and this is what you get!", - "durability": null, - "destroy": "true", - "weight": "0.4", - "equipment_slot": "1", - "grand_exchange_price": "919", - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6959", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "919", - "durability": null, - "name": "Cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6960" - }, - { - "examine": "A freshly baked baguette.", - "durability": null, - "name": "Baguette", - "archery_ticket_price": "0", - "id": "6961" - }, - { "ge_buy_limit": "1000", - "examine": "A freshly made triangle sandwich.", - "grand_exchange_price": "110", - "durability": null, - "name": "Triangle sandwich", "tradeable": "true", - "archery_ticket_price": "0", - "id": "6962" + "weight": "0.5" }, { - "examine": "A freshly made roll.", + "id": "6813", + "name": "Granite legs", + "archery_ticket_price": "0", "durability": null, - "name": "Roll", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6963" + "tradeable": "true" }, { - "bankable": "false", - "examine": "Lovely money!", + "id": "6814", + "name": "Fur", + "examine": "This would make warm clothing.", + "archery_ticket_price": "0", "durability": null, - "name": "Coins", - "archery_ticket_price": "0", - "id": "6964" - }, - { - "examine": "A freshly made square sandwich.", - "durability": null, - "name": "Square sandwich", - "archery_ticket_price": "0", - "id": "6965" - }, - { - "lendable": "true", - "examine": "Makes the wearer pretty intimidating.", - "grand_exchange_price": "61200", - "durability": null, - "name": "Dragon med helm", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "6967", - "absorb": "2,0,4", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" - }, - { - "durability": null, - "name": "Triangle sandwich", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6968" - }, - { - "examine": "I'd better be careful eating this.", - "grand_exchange_price": "694", - "durability": null, - "name": "Shark", - "tradeable": "true", - "weight": "0.6", - "archery_ticket_price": "0", - "id": "6969" - }, - { - "examine": "It's a solid gold pyramid!", - "durability": null, - "name": "Pyramid top", - "weight": "11", - "archery_ticket_price": "0", - "id": "6970" - }, - { "ge_buy_limit": "100", - "examine": "A large chunk of sandstone.", - "grand_exchange_price": "4", - "durability": null, - "name": "Sandstone (1kg)", + "shop_price": "20", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6971" + "weight": "0.4" }, { + "id": "6815", + "name": "Fur", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "4", - "durability": null, - "name": "Sandstone (1kg)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6972" + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "A large chunk of sandstone.", - "grand_exchange_price": "27", - "durability": null, - "name": "Sandstone (2kg)", - "tradeable": "true", - "weight": "1", + "id": "6816", + "name": "Wyvern bones", "archery_ticket_price": "0", - "id": "6973" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "27", - "durability": null, - "name": "Sandstone (2kg)", - "tradeable": "true", + "id": "6817", + "name": "Slender blade", + "examine": "A slender two-handed sword.", "archery_ticket_price": "0", - "id": "6974" - }, - { - "ge_buy_limit": "100", - "examine": "A large chunk of sandstone.", - "grand_exchange_price": "30", - "durability": null, - "name": "Sandstone (5kg)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6975" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "30", - "durability": null, - "name": "Sandstone (5kg)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6976" - }, - { - "ge_buy_limit": "100", - "examine": "A large chunk of sandstone.", - "grand_exchange_price": "120", - "durability": null, - "name": "Sandstone (10kg)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "6977" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "120", - "durability": null, - "name": "Sandstone (10kg)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6978" - }, - { - "ge_buy_limit": "10000", - "examine": "See article", - "grand_exchange_price": "304", - "durability": null, - "name": "Granite (500g)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6979" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "304", - "durability": null, - "name": "Granite (500g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6980" - }, - { - "ge_buy_limit": "10000", - "examine": "See article", - "grand_exchange_price": "845", - "durability": null, - "name": "Granite (2kg)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6981" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "845", - "durability": null, - "name": "Granite (2kg)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6982" - }, - { - "ge_buy_limit": "10000", - "examine": "See article", - "grand_exchange_price": "2153", - "durability": null, - "name": "Granite (5kg)", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "6983", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "2153", - "durability": null, - "name": "Granite (5kg)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "6984" - }, - { - "destroy_message": "You can make another 20 kg block by giving enough stone to Lazim.", - "examine": "A huge twenty-kilo block of sandstone.", - "durability": null, - "name": "Sandstone (20kg)", "destroy": "true", - "weight": "20", - "archery_ticket_price": "0", - "id": "6985" - }, - { - "destroy_message": "You can make another 32 kg sandstone block by giving enough stone to Lazim.", - "examine": "A huge thirty-two-kilo block of sandstone.", - "durability": null, - "name": "Sandstone (32kg)", - "destroy": "true", - "weight": "32", - "archery_ticket_price": "0", - "id": "6986" - }, - { - "destroy_message": "You can make another statue body by giving Lazim 20 kg of stone and then crafting it.", - "examine": "The body of a sandstone statue.", - "durability": null, - "name": "Sandstone body", - "destroy": "true", - "archery_ticket_price": "0", - "id": "6987" - }, - { - "destroy_message": "You can make another statue base by giving Lazim 32 kg of stone and then crafting it.", - "examine": "The base and legs of a sandstone statue.", - "durability": null, - "name": "Sandstone base", - "destroy": "true", - "weight": "32", - "archery_ticket_price": "0", - "id": "6988" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A metal sigil in the shape of a Z.", "durability": null, - "name": "Z sigil", - "archery_ticket_price": "0", - "id": "6993" + "equipment_slot": "3", + "render_anim": "124", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "false", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weight": "3" }, { + "id": "6818", + "name": "Bow-sword", + "examine": "A sharp sword that can also fire arrows.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make a replacement.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weight": "3" + }, + { + "id": "6819", + "name": "Large pouch", + "examine": "A large pouch used for storing essence.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A metal sigil in the shape of an M.", "durability": null, - "name": "M sigil", - "archery_ticket_price": "0", - "id": "6994" + "shop_price": "25000", + "weight": "1" }, { + "id": "6820", + "name": "Relic", + "examine": "It seems to have pieces missing. After Temple at Senntisten quest: The assassin's plunder from the church on Entrana.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can get another from the assassin beside the winch that leads down into Senntisten temple.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6821", + "name": "Orb", + "examine": "This looks valuable.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A metal sigil in the shape of an R.", - "durability": null, - "name": "R sigil", - "archery_ticket_price": "0", - "id": "6995" + "durability": null }, { + "id": "6822", + "name": "Star bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6823", + "name": "Star bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6824", + "name": "Star bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6825", + "name": "Star bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6826", + "name": "Star bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6827", + "name": "Star bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6828", + "name": "Box bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6829", + "name": "Box bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6830", + "name": "Box bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6831", + "name": "Box bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6832", + "name": "Box bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6833", + "name": "Box bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6834", + "name": "Diamond bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6835", + "name": "Diamond bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6836", + "name": "Diamond bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6837", + "name": "Diamond bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6838", + "name": "Diamond bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6839", + "name": "Diamond bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6840", + "name": "Tree bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6841", + "name": "Tree bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6842", + "name": "Tree bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6843", + "name": "Tree bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6844", + "name": "Tree bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6845", + "name": "Tree bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6846", + "name": "Bell bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6847", + "name": "Bell bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6848", + "name": "Bell bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6849", + "name": "Bell bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6850", + "name": "Bell bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6851", + "name": "Bell bauble", + "examine": "See individual articles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6852", + "name": "Puppet box", + "examine": "A box for storing completed puppets.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6853", + "name": "Bauble box", + "examine": "A box for storing painted baubles.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6854", + "name": "Puppet box", + "examine": "A box for storing completed puppets.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A metal sigil in the shape of a K.", "durability": null, - "name": "K sigil", - "archery_ticket_price": "0", - "id": "6996" + "tradeable": "false" }, { - "destroy_message": "You can get the statue's left arm back from Lazim.", - "examine": "The left arm of a large stone statue.", - "durability": null, - "name": "Stone left arm", - "tradeable": "false", + "id": "6855", + "name": "Bauble box", + "examine": "A box for storing painted baubles.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "6856", + "name": "Bobble hat", + "examine": "A woolly bobble hat.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "6997" - }, - { - "destroy_message": "You can get the statue's right arm back from Lazim.", - "examine": "The right arm of a large stone statue.", + "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", "durability": null, - "name": "Stone right arm", + "equipment_slot": "0", "tradeable": "false", - "destroy": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "6998" + "weight": "0.25" }, { - "destroy_message": "You can get the statue's left leg back from Lazim.", - "examine": "The left leg of a large stone statue.", + "id": "6857", + "name": "Bobble scarf", + "examine": "A woolly scarf.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, - "name": "Stone left leg", + "equipment_slot": "2", + "weight": "0.25" + }, + { + "id": "6858", + "name": "Jester hat", + "examine": "A woolly Jester hat.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", + "durability": null, + "equipment_slot": "0", + "shop_price": "160", "tradeable": "false", - "destroy": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "6999" + "weight": "0.25" }, { - "destroy_message": "You can get the statue's right leg back from Lazim.", - "examine": "The right leg of a large stone statue.", + "id": "6859", + "name": "Jester scarf", + "examine": "A woolly jester scarf.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Jester scarf from Diango.", "durability": null, - "name": "Stone right leg", + "equipment_slot": "2", "tradeable": "false", - "destroy": "true", - "weight": "9", - "archery_ticket_price": "0", - "id": "7000" + "weight": "0.25" }, { - "destroy_message": "You can make another positive mould by using soft clay on the pedestal in Enakhra's temple.", - "examine": "A positive clay mould of a camel's head.", + "id": "6860", + "name": "Tri-jester hat", + "examine": "A woolly triple bobble jester hat.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You may get another from Diango in Draynor Village.", "durability": null, - "name": "Camel mould (p)", + "equipment_slot": "0", "tradeable": "false", + "weight": "0.25" + }, + { + "id": "6861", + "name": "Tri-jester scarf", + "examine": "A woolly jester scarf.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "7001" + "destroy_message": "You can obtain another jester scarf from Diango in the Draynor Market.", + "durability": null, + "equipment_slot": "2", + "tradeable": "false", + "weight": "0.25" }, { - "remove_head": "true", - "examine": "Blend in in the desert.", - "durability": null, - "name": "Camel mask", - "weight": "0.5", + "id": "6862", + "name": "Woolly hat", + "examine": "A woolly tobogganing hat.", "archery_ticket_price": "0", - "id": "7003", - "equipment_slot": "0" + "destroy": "true", + "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "0.25" }, { - "shop_price": "14", - "examine": "Good for detailed crafting.", - "grand_exchange_price": "33", - "durability": null, - "name": "Chisel", - "tradeable": "true", - "weight": "0.4", + "id": "6863", + "name": "Woolly scarf", + "examine": "A woolly tobogganing scarf.", "archery_ticket_price": "0", - "id": "7004", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "2", + "tradeable": "false", + "weight": "0.25" + }, + { + "id": "6864", + "name": "Marionette handle", + "examine": "The controlling part of a marionette.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "3" }, { + "id": "6865", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6866", + "name": "Green marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6867", + "name": "Red marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6868", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6869", + "name": "Green marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6870", + "name": "Red marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6871", + "name": "Red marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6872", + "name": "Red marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6873", + "name": "Red marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6874", + "name": "Red marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6875", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6876", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6877", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6878", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6879", + "name": "Green marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6880", + "name": "Green marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6881", + "name": "Green marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6882", + "name": "Green marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "6883", + "name": "Peach", + "examine": "A tasty fruit.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6885", + "name": "Progress hat", + "examine": "A magic training arena progress hat", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "0" + }, + { + "id": "6886", + "name": "Progress hat", + "examine": "A magic training arena progress hat", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "0" + }, + { + "id": "6887", + "name": "Progress hat", + "examine": "A magic training arena progress hat", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "0" + }, + { + "id": "6888", + "name": "Guardian statue", + "examine": "A guardian of the arena.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6889", + "name": "Mage's book", + "examine": "The magical book of the Mage.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", + "requirements": "{6,60}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6890", + "name": "Mage's book", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6891", + "name": "Arena book", + "examine": "A book about the Training Arena.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "200", + "weight": "1" + }, + { + "id": "6893", + "name": "Leather boots", + "examine": "Comfortable leather boots.", + "archery_ticket_price": "0", + "bankable": "false", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "6", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "6894", + "name": "Adamant kiteshield", + "examine": "A large metal shield.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bankable": "false", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "durability": null, + "tradeable": "true", + "weight": "5.8" + }, + { + "id": "6895", + "name": "Adamant med helm", + "examine": "A medium sized helmet.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bankable": "false", + "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0", + "durability": null, + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "6896", + "name": "Emerald", + "examine": "This looks valuable.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "350", + "tradeable": "true" + }, + { + "id": "6897", + "name": "Rune longsword", + "examine": "A razor sharp longsword", + "archery_ticket_price": "0", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bankable": "false", + "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0", + "durability": null, + "lendable": "true", + "shop_price": "32000", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "6898", + "name": "Cylinder", + "examine": "A green cylinder", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6899", + "name": "Cube", + "examine": "A yellow cube", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6900", + "name": "Icosahedron", + "examine": "A blue icosahedron.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6901", + "name": "Pentamid", + "examine": "A red pentamid.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6902", + "name": "Orb", + "examine": "This looks valuable.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6903", + "name": "Dragonstone", + "examine": "This looks valuable.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "6904", + "name": "Animals' bones", + "examine": "Various animals' bones.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6905", + "name": "Animals' bones", + "examine": "Various animals' bones.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6906", + "name": "Animals' bones", + "examine": "Various animals' bones.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6907", + "name": "Animals' bones", + "examine": "Various animals' bones.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6908", + "name": "Beginner wand", + "examine": "A beginner level wand", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "1426", + "requirements": "{6,45}", + "run_anim": "1210", + "shop_price": "303030030", + "stand_anim": "809", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1146", + "weapon_interface": "1", + "weight": "0.2" + }, + { + "id": "6909", + "name": "Beginner wand", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6910", + "name": "Apprentice wand", + "examine": "An apprentice level wand.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "bonuses": "0,0,0,10,0,0,0,0,10,0,0,0,0,0,0", + "defence_anim": "420", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "1426", + "requirements": "{6,50}", + "run_anim": "1210", + "shop_price": "606060060", + "stand_anim": "809", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1146", + "weapon_interface": "1" + }, + { + "id": "6911", + "name": "Apprentice wand", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6912", + "name": "Teacher wand", + "examine": "A teacher level wand.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "1426", + "requirements": "{6,55}", + "run_anim": "1210", + "stand_anim": "809", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1146", + "weapon_interface": "1" + }, + { + "id": "6913", + "name": "Teacher wand", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6914", + "name": "Master wand", + "examine": "A master level wand.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "bonuses": "0,0,0,20,0,0,0,0,20,0,0,0,0,0,0", + "defence_anim": "420", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "1426", + "requirements": "{6,60}", + "run_anim": "1210", + "stand_anim": "8980", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "1146", + "weapon_interface": "1", + "weight": "0.1" + }, + { + "id": "6915", + "name": "Master wand", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6916", + "name": "Infinity top", + "examine": "Mystical robes.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,22,0,0,0,0,22,0,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,25}-{6,50}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "6917", + "name": "Infinity top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6918", + "name": "Infinity hat", + "examine": "A mystic hat.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,0,0,0,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "hat": true, + "requirements": "{1,25}-{6,50}", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "6919", + "name": "Infinity hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6920", + "name": "Infinity boots", + "examine": "Mystical boots.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,0,0,0,5,0,5,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "10", + "requirements": "{1,25}-{6,50}", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "6921", + "name": "Infinity boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6922", + "name": "Infinity gloves", + "examine": "Mystical gloves.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "10", + "requirements": "{1,25}-{6,50}", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "6923", + "name": "Infinity gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6924", + "name": "Infinity bottoms", + "examine": "Mystical robes.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,17,0,0,0,0,17,0,17,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,25}-{6,50}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "6925", + "name": "Infinity bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "6926", + "name": "Bones to peaches", + "examine": "A tablet containing a magic spell.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6945", + "name": "Sandy hand", + "examine": "A severed hand covered with sand.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6946", + "name": "Beer-soaked hand", + "examine": "A severed hand dripping with beer.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to the Guard Captain in Yanille to get another beer soaked hand.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6947", + "name": "Bert's rota", + "examine": "A copy of a work rota.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Bert to replace this Rota.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6948", + "name": "Sandy's rota", + "examine": "An original work rota.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Search Sandy's office in Brimhaven for another Rota.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6949", + "name": "A magic scroll", + "examine": "Maybe I should read this...", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "6950", + "name": "Magical orb", + "examine": "An ordinary looking scrying orb.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Zavistic Rarve to replace your magical orb.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6951", + "name": "Magical orb (a)", + "examine": "This magical scrying orb pulsates as it stores information.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Zavistic Rarve to replace your magical orb.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6952", + "name": "Truth serum", + "examine": "Fluid sloshes innocently in this vial.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Betty in Port Sarim to get another bottle of truth serum.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6953", + "name": "Bottled water", + "examine": "A bottle of water.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Betty in Port Sarim to get another bottle.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6954", + "name": "Redberry juice", + "examine": "Redberry juice sloshes around in this vial, waiting for white berries to be added.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Betty in Port Sarim to get another bottle to make some more red berry juice.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6955", + "name": "Pink dye", + "examine": "A vial of pink dye.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Betty in Port Sarim to make more pink dye.", + "durability": null, + "shop_price": "20", + "tradeable": "false" + }, + { + "id": "6956", + "name": "Rose-tinted lens", + "examine": "This lens has a pinkish tinge to it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Betty in Port Sarim to get another bottle to make the lens again.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "6957", + "name": "Wizard's head", + "examine": "A decapitated, sand-covered head.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Speak to Mazion near the sandpit on Entrana to find the Wizard Head again.", + "durability": null, + "tradeable": "false", + "weight": "3" + }, + { + "id": "6958", + "name": "Sand", + "examine": "A handful of sand from Sandy's pocket.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "6959", + "name": "Cape", + "examine": "Use pink dye on a cape and this is what you get!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "shop_price": "20", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "6960", + "name": "Cape", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6961", + "name": "Baguette", + "examine": "A freshly baked baguette.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6962", + "name": "Triangle sandwich", + "examine": "A freshly made triangle sandwich.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "6963", + "name": "Roll", + "examine": "A freshly made roll.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.5" + }, + { + "id": "6964", + "name": "Coins", + "examine": "Lovely money!", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null + }, + { + "id": "6965", + "name": "Square sandwich", + "examine": "A freshly made square sandwich.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "6967", + "name": "Dragon med helm", + "examine": "Makes the wearer pretty intimidating.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "durability": null, + "lendable": "true", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "6968", + "name": "Triangle sandwich", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "6969", + "name": "Shark", + "examine": "I'd better be careful eating this.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "0.6" + }, + { + "id": "6970", + "name": "Pyramid top", + "examine": "It's a solid gold pyramid!", + "archery_ticket_price": "0", + "durability": null, + "weight": "11" + }, + { + "id": "6971", + "name": "Sandstone (1kg)", + "examine": "A large chunk of sandstone.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6972", + "name": "Sandstone (1kg)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6973", + "name": "Sandstone (2kg)", + "examine": "A large chunk of sandstone.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6974", + "name": "Sandstone (2kg)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6975", + "name": "Sandstone (5kg)", + "examine": "A large chunk of sandstone.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6976", + "name": "Sandstone (5kg)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6977", + "name": "Sandstone (10kg)", + "examine": "A large chunk of sandstone.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "6978", + "name": "Sandstone (10kg)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "6979", + "name": "Granite (500g)", + "examine": "See article", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "6980", + "name": "Granite (500g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6981", + "name": "Granite (2kg)", + "examine": "See article", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "6982", + "name": "Granite (2kg)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6983", + "name": "Granite (5kg)", + "examine": "See article", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "6984", + "name": "Granite (5kg)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "6985", + "name": "Sandstone (20kg)", + "examine": "A huge twenty-kilo block of sandstone.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make another 20 kg block by giving enough stone to Lazim.", + "durability": null, + "weight": "20" + }, + { + "id": "6986", + "name": "Sandstone (32kg)", + "examine": "A huge thirty-two-kilo block of sandstone.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make another 32 kg sandstone block by giving enough stone to Lazim.", + "durability": null, + "weight": "32" + }, + { + "id": "6987", + "name": "Sandstone body", + "examine": "The body of a sandstone statue.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make another statue body by giving Lazim 20 kg of stone and then crafting it.", + "durability": null + }, + { + "id": "6988", + "name": "Sandstone base", + "examine": "The base and legs of a sandstone statue.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make another statue base by giving Lazim 32 kg of stone and then crafting it.", + "durability": null, + "weight": "32" + }, + { + "id": "6993", + "name": "Z sigil", + "examine": "A metal sigil in the shape of a Z.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "6994", + "name": "M sigil", + "examine": "A metal sigil in the shape of an M.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "6995", + "name": "R sigil", + "examine": "A metal sigil in the shape of an R.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "6996", + "name": "K sigil", + "examine": "A metal sigil in the shape of a K.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "6997", + "name": "Stone left arm", + "examine": "The left arm of a large stone statue.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get the statue's left arm back from Lazim.", + "durability": null, + "tradeable": "false", + "weight": "9" + }, + { + "id": "6998", + "name": "Stone right arm", + "examine": "The right arm of a large stone statue.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get the statue's right arm back from Lazim.", + "durability": null, + "tradeable": "false", + "weight": "9" + }, + { + "id": "6999", + "name": "Stone left leg", + "examine": "The left leg of a large stone statue.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get the statue's left leg back from Lazim.", + "durability": null, + "tradeable": "false", + "weight": "9" + }, + { + "id": "7000", + "name": "Stone right leg", + "examine": "The right leg of a large stone statue.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get the statue's right leg back from Lazim.", + "durability": null, + "tradeable": "false", + "weight": "9" + }, + { + "id": "7001", + "name": "Camel mould (p)", + "examine": "A positive clay mould of a camel's head.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make another positive mould by using soft clay on the pedestal in Enakhra's temple.", + "durability": null, + "tradeable": "false", + "weight": "0.5" + }, + { + "id": "7003", + "name": "Camel mask", + "examine": "Blend in in the desert.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "0.5" + }, + { + "id": "7004", + "name": "Chisel", + "examine": "Good for detailed crafting.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "shop_price": "14", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "7051", + "name": "Unlit bug lantern", + "examine": "A lantern to aid attacking Harpie bugs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", "requirements": "{18,33}-{11,33}", "shop_price": "130", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "7052", + "name": "Unlit bug lantern", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7053", + "name": "Lit bug lantern", "examine": "A lantern to aid attacking Harpie bugs.", - "grand_exchange_price": "466", - "durability": null, - "name": "Unlit bug lantern", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "7051", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "466", "durability": null, - "name": "Unlit bug lantern", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7052" - }, - { + "equipment_slot": "5", "requirements": "{18,33}", "shop_price": "130", - "examine": "A lantern to aid attacking Harpie bugs.", - "durability": null, - "name": "Lit bug lantern", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "7053", - "equipment_slot": "5" + "weight": "2.2" }, { - "ge_buy_limit": "10000", + "id": "7054", + "name": "Chilli potato", "examine": "A baked potato with chilli con carne", - "grand_exchange_price": "415", - "durability": null, - "name": "Chilli potato", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7054" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "415", - "durability": null, + "id": "7055", "name": "Chilli potato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7055" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "7056", + "name": "Egg potato", "examine": "A baked potato with egg and tomato.", - "grand_exchange_price": "441", - "durability": null, - "name": "Egg potato", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7056" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "441", - "durability": null, + "id": "7057", "name": "Egg potato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7057" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "7058", + "name": "Mushroom potato", "examine": "A baked potato with mushroom and onions.", - "grand_exchange_price": "1165", - "durability": null, - "name": "Mushroom potato", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7058" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "1165", - "durability": null, + "id": "7059", "name": "Mushroom potato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7059" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "7060", + "name": "Tuna potato", "examine": "A baked potato with tuna and sweetcorn.", - "grand_exchange_price": "2134", - "durability": null, - "name": "Tuna potato", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7060" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "2134", - "durability": null, - "name": "Tuna potato", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7061" + "weight": "0.5" }, { - "ge_buy_limit": "1000", + "id": "7061", + "name": "Tuna potato", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "7062", + "name": "Chilli con carne", "examine": "A bowl of meat in chilli-con-carne sauce.", - "grand_exchange_price": "215", - "durability": null, - "name": "Chilli con carne", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7062" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "215", - "durability": null, + "id": "7063", "name": "Chilli con carne", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7063" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7064", + "name": "Egg and tomato", "examine": "A bowl of scrambled eggs and tomato", - "grand_exchange_price": "126", - "durability": null, - "name": "Egg and tomato", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7064" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "126", - "durability": null, + "id": "7065", "name": "Egg and tomato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7065" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7066", + "name": "Mushroom & onion", "examine": "A bowl of fried mushroom and onions.", - "grand_exchange_price": "368", - "durability": null, - "name": "Mushroom & onion", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7066" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "368", - "durability": null, - "name": "Mushroom & onion", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7067" + "weight": "0.5" }, { - "ge_buy_limit": "10000", + "id": "7067", + "name": "Mushroom & onion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7068", + "name": "Tuna and corn", "examine": "A bowl of cooked tuna and sweetcorn.", - "grand_exchange_price": "514", - "durability": null, - "name": "Tuna and corn", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7068" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "514", - "durability": null, - "name": "Tuna and corn", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7069" + "weight": "0.5" }, { - "ge_buy_limit": "1000", + "id": "7069", + "name": "Tuna and corn", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "7070", + "name": "Minced meat", "examine": "A bowl of finely minced meat.", - "grand_exchange_price": "22", - "durability": null, - "name": "Minced meat", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7070" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "22", - "durability": null, + "id": "7071", "name": "Minced meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7071" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7072", + "name": "Spicy sauce", "examine": "A bowl of spicy sauce.", - "grand_exchange_price": "70", - "durability": null, - "name": "Spicy sauce", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7072" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "70", - "durability": null, + "id": "7073", "name": "Spicy sauce", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7073" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7074", + "name": "Chopped garlic", "examine": "A bowl of chopped garlic.", - "grand_exchange_price": "39", - "durability": null, - "name": "Chopped garlic", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7074" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "39", - "durability": null, + "id": "7075", "name": "Chopped garlic", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7075" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7076", + "name": "Uncooked egg", "examine": "A bowl of uncooked egg.", - "grand_exchange_price": "34", - "durability": null, - "name": "Uncooked egg", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7076" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "34", - "durability": null, + "id": "7077", "name": "Uncooked egg", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7077" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7078", + "name": "Scrambled egg", "examine": "A bowl of scrambled egg.", - "grand_exchange_price": "24", - "durability": null, - "name": "Scrambled egg", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7078" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "24", - "durability": null, + "id": "7079", "name": "Scrambled egg", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7079" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7080", + "name": "Sliced mushrooms", "examine": "A bowl of sliced Bittercap mushrooms.", - "grand_exchange_price": "149", - "durability": null, - "name": "Sliced mushrooms", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7080" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "149", - "durability": null, + "id": "7081", "name": "Sliced mushrooms", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7081" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7082", + "name": "Fried mushrooms", "examine": "A bowl of fried Bittercap mushrooms.", - "grand_exchange_price": "189", - "durability": null, - "name": "Fried mushrooms", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7082" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "189", - "durability": null, + "id": "7083", "name": "Fried mushrooms", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7083" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7084", + "name": "Fried onions", "examine": "A bowl of sliced, fried onions.", - "grand_exchange_price": "40", - "durability": null, - "name": "Fried onions", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7084" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "40", - "durability": null, + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7085", "name": "Fried onions", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7085" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", + "id": "7086", + "name": "Chopped tuna", "examine": "A bowl of finely chopped tuna.", - "grand_exchange_price": "233", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7087", "name": "Chopped tuna", - "tradeable": "true", - "weight": "0.5", "archery_ticket_price": "0", - "id": "7086" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "233", - "durability": null, - "name": "Chopped tuna", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7087" - }, - { - "ge_buy_limit": "10000", - "examine": "Raw sweetcorn.", - "grand_exchange_price": "110", - "durability": null, + "id": "7088", "name": "Sweetcorn", - "tradeable": "true", + "examine": "A bowl of cooked sweetcorn.", "archery_ticket_price": "0", - "id": "7088" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "110", - "durability": null, - "name": "Sweetcorn", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7089" + "tradeable": "true" }, { + "id": "7089", + "name": "Sweetcorn", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "7091", "name": "Burnt egg", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7091" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7093", "name": "Burnt onion", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7093" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7095", "name": "Burnt mushroom", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7095" + "durability": null, + "tradeable": "true" }, { - "examine": "Best keep this away from naked flames.", - "durability": null, + "id": "7108", "name": "Gunpowder", - "tradeable": "false", - "destroy": "true", + "examine": "Best keep this away from naked flames.", "archery_ticket_price": "0", - "id": "7108" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A fuse.", - "durability": null, + "id": "7109", "name": "Fuse", - "tradeable": "false", - "destroy": "true", + "examine": "A fuse.", "archery_ticket_price": "0", - "id": "7109" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "shop_price": "300", - "ge_buy_limit": "100", - "grand_exchange_price": "48", - "examine": "A seaworthy grey shirt.", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "7110", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "48", - "durability": null, "name": "Stripy pirate shirt", - "tradeable": "true", + "examine": "A seaworthy grey shirt.", "archery_ticket_price": "0", - "id": "7111" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "300", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "Essential pirate wear.", - "grand_exchange_price": "714", - "durability": null, - "name": "Pirate bandana", - "tradeable": "true", - "weight": "0.1", + "id": "7111", + "name": "Stripy pirate shirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "7112", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "714", - "durability": null, "name": "Pirate bandana", - "tradeable": "true", + "examine": "Essential pirate wear.", "archery_ticket_price": "0", - "id": "7113" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" }, { - "shop_price": "350", - "ge_buy_limit": "100", - "examine": "Not for land lubbers.", - "grand_exchange_price": "2530", - "durability": null, - "name": "Pirate boots", - "tradeable": "true", - "weight": "4", + "id": "7113", + "name": "Pirate bandana", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "7114", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2530", - "durability": null, "name": "Pirate boots", - "tradeable": "true", + "examine": "Not for land lubbers.", "archery_ticket_price": "0", - "id": "7115" + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "4" }, { - "shop_price": "350", - "ge_buy_limit": "100", - "grand_exchange_price": "77", - "examine": "Well, okay, they're beige, but they're part of the white pirate clothing set, so...", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", + "id": "7115", + "name": "Pirate boots", "archery_ticket_price": "0", - "weight": "1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "7116", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "77", - "durability": null, "name": "Pirate leggings", - "tradeable": "true", + "examine": "Well, okay, they're beige, but they're part of the white pirate clothing set, so...", "archery_ticket_price": "0", - "id": "7117" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "1" }, { - "examine": "A cannister holding shrapnel.", + "id": "7117", + "name": "Pirate leggings", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7118", "name": "Canister", - "tradeable": "false", - "destroy": "true", + "examine": "A cannister holding shrapnel.", "archery_ticket_price": "0", - "id": "7118" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "For cleaning and packing the cannon.", - "durability": null, + "id": "7120", "name": "Ramrod", - "tradeable": "false", + "examine": "For cleaning and packing the cannon.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "7120" + "durability": null, + "tradeable": "false", + "weight": "2" }, { - "examine": "A plank of wood to repair the hull with.", - "durability": null, + "id": "7121", "name": "Repair plank", + "examine": "A plank of wood to repair the hull with.", "archery_ticket_price": "0", - "id": "7121" + "durability": null }, { - "shop_price": "300", - "ge_buy_limit": "100", - "grand_exchange_price": "904", - "examine": "A sea worthy shirt.", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "7122", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "904", - "durability": null, "name": "Stripy pirate shirt", - "tradeable": "true", + "examine": "A sea worthy shirt.", "archery_ticket_price": "0", - "id": "7123" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "300", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "Essential pirate wear.", - "grand_exchange_price": "340", - "durability": null, - "name": "Pirate bandana", - "tradeable": "true", - "weight": "0.1", + "id": "7123", + "name": "Stripy pirate shirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "7124", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "340", - "durability": null, "name": "Pirate bandana", - "tradeable": "true", + "examine": "Essential pirate wear.", "archery_ticket_price": "0", - "id": "7125" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" }, { - "shop_price": "350", - "ge_buy_limit": "100", - "grand_exchange_price": "187", - "examine": "A sea worthy pair of trousers.", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", + "id": "7125", + "name": "Pirate bandana", "archery_ticket_price": "0", - "weight": "1", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "7126", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "187", - "durability": null, "name": "Pirate leggings", - "tradeable": "true", + "examine": "A sea worthy pair of trousers.", "archery_ticket_price": "0", - "id": "7127" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "300", - "ge_buy_limit": "100", - "grand_exchange_price": "744", - "examine": "A sea worthy shirt.", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "weight": "1", + "id": "7127", + "name": "Pirate leggings", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "7128", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "744", - "durability": null, "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7129" - }, - { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "Essential pirate wear.", - "grand_exchange_price": "154", - "durability": null, - "name": "Pirate bandana", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7130", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "154", - "durability": null, - "name": "Pirate bandana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7131" - }, - { - "shop_price": "350", - "ge_buy_limit": "100", - "grand_exchange_price": "253", - "examine": "A sea worthy pair of trousers.", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "1", - "id": "7132", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "253", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7133" - }, - { - "shop_price": "300", - "ge_buy_limit": "100", - "grand_exchange_price": "421", "examine": "A sea worthy shirt.", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "7134", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "300", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "421", - "durability": null, + "id": "7129", "name": "Stripy pirate shirt", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7135" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "remove_head": "true", - "ge_buy_limit": "100", + "id": "7130", + "name": "Pirate bandana", "examine": "Essential pirate wear.", - "grand_exchange_price": "469", - "durability": null, - "name": "Pirate bandana", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "7136", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "469", - "durability": null, + "id": "7131", "name": "Pirate bandana", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7137" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "350", - "ge_buy_limit": "100", - "grand_exchange_price": "83", + "id": "7132", + "name": "Pirate leggings", "examine": "A sea worthy pair of trousers.", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "7138", - "equipment_slot": "7" - }, - { + "durability": null, + "equipment_slot": "7", "ge_buy_limit": "100", - "grand_exchange_price": "83", - "durability": null, - "name": "Pirate leggings", + "shop_price": "350", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7139" + "weight": "1" }, { - "shop_price": "2560", - "examine": "Feels quite lucky.", + "id": "7133", + "name": "Pirate leggings", + "archery_ticket_price": "0", "durability": null, - "weight": "1.8", - "attack_speed": "4", - "weapon_interface": "6", - "equipment_slot": "3", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7134", + "name": "Stripy pirate shirt", + "examine": "A sea worthy shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "shop_price": "300", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7135", + "name": "Stripy pirate shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7136", + "name": "Pirate bandana", + "examine": "Essential pirate wear.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "7137", + "name": "Pirate bandana", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7138", + "name": "Pirate leggings", + "examine": "A sea worthy pair of trousers.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7139", + "name": "Pirate leggings", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7140", + "name": "Lucky cutlass", + "examine": "Feels quite lucky.", + "archery_ticket_price": "0", "attack_anims": "390,390,381,390", "attack_audios": "2500,2500,2517,2500", - "name": "Lucky cutlass", - "archery_ticket_price": "0", - "id": "7140", - "bonuses": "5,20,0,-5,0,6,6,6,0,0,0,25,0,0,0" - }, - { - "shop_price": "1040", - "examine": "I hope he doesn't want it back.", - "durability": null, - "name": "Harry's cutlass", - "weight": "1", - "archery_ticket_price": "0", "attack_speed": "4", - "weapon_interface": "6", - "id": "7141", - "bonuses": "3,14,0,-5,0,4,4,4,0,0,0,22,0,0,0", - "equipment_slot": "3" - }, - { - "shop_price": "25600", - "examine": "The very butcher of a silk button.", + "bonuses": "5,20,0,-5,0,6,6,6,0,0,0,25,0,0,0", "durability": null, - "name": "Rapier", - "weight": "1", - "archery_ticket_price": "0", - "attack_speed": "4", - "weapon_interface": "5", - "id": "7142", - "bonuses": "45,7,-2,0,0,0,1,0,0,0,0,44,0,0,0", - "render_anim": "2622", - "equipment_slot": "3" - }, - { - "examine": "Looks valuable.", - "durability": null, - "name": "Plunder", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7143" - }, - { - "examine": "By Cap'n Hook-Hand Morrisane.", - "durability": null, - "name": "Book o' piracy", - "archery_ticket_price": "0", - "id": "7144" - }, - { - "examine": "A working cannon barrel.", - "durability": null, - "name": "Cannon barrel", - "weight": "32", - "archery_ticket_price": "0", - "id": "7145" - }, - { - "examine": "Not likely to work again.", - "durability": null, - "name": "Broken cannon", - "weight": "32", - "archery_ticket_price": "0", - "id": "7146" - }, - { - "examine": "A plank of wood to repair the hull with.", - "durability": null, - "name": "Repair plank", - "archery_ticket_price": "0", - "id": "7148" - }, - { - "examine": "A cannister holding shrapnel.", - "durability": null, - "name": "Canister", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7149" - }, - { - "examine": "Useful for pinning up paintings.", - "durability": null, - "name": "Tacks", - "archery_ticket_price": "0", - "id": "7150" - }, - { - "shop_price": "18", - "examine": "A coil of rope.", - "grand_exchange_price": "101", - "durability": null, - "name": "Rope", - "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "7155" - }, - { - "shop_price": "1", - "examine": "Useful for lighting a fire.", - "grand_exchange_price": "121", - "durability": null, - "name": "Tinderbox", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "7156" - }, - { - "shop_price": "30", - "examine": "I think it is eating through the bottle.", - "durability": null, - "name": "Braindeath 'rum", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7157" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "7044", - "examine": "A two-handed dragon sword.", - "walk_anim": "7046", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "1000000", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "7158", - "stand_turn_anim": "7040", - "bonuses": "-4,92,80,-4,0,0,0,0,0,-1,0,93,0,0,0", - "requirements": "{0,60}", - "durability": null, - "weight": "3", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", - "attack_audios": "2503,0,2504,0", - "name": "Dragon 2h sword" + "shop_price": "2560", + "weapon_interface": "6", + "weight": "1.8" }, { + "id": "7141", + "name": "Harry's cutlass", + "examine": "I hope he doesn't want it back.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,14,0,-5,0,4,4,4,0,0,0,22,0,0,0", + "durability": null, + "equipment_slot": "3", + "shop_price": "1040", + "weapon_interface": "6", + "weight": "1" + }, + { + "id": "7142", + "name": "Rapier", + "examine": "The very butcher of a silk button.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "45,7,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "2622", + "shop_price": "25600", + "weapon_interface": "5", + "weight": "1" + }, + { + "id": "7143", + "name": "Plunder", + "examine": "Looks valuable.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7144", + "name": "Book o' piracy", + "examine": "By Cap'n Hook-Hand Morrisane.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7145", + "name": "Cannon barrel", + "examine": "A working cannon barrel.", + "archery_ticket_price": "0", + "durability": null, + "weight": "32" + }, + { + "id": "7146", + "name": "Broken cannon", + "examine": "Not likely to work again.", + "archery_ticket_price": "0", + "durability": null, + "weight": "32" + }, + { + "id": "7148", + "name": "Repair plank", + "examine": "A plank of wood to repair the hull with.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7149", + "name": "Canister", + "examine": "A cannister holding shrapnel.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "7150", + "name": "Tacks", + "examine": "Useful for pinning up paintings.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7155", + "name": "Rope", + "examine": "A coil of rope.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "18", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "7156", + "name": "Tinderbox", + "examine": "Useful for lighting a fire.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "7157", + "name": "Braindeath 'rum", + "examine": "I think it is eating through the bottle.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "30", + "weight": "0.9" + }, + { + "id": "7158", + "name": "Dragon 2h sword", + "examine": "A two-handed dragon sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "2503,0,2504,0", + "attack_speed": "7", + "bonuses": "-4,92,80,-4,0,0,0,0,0,-1,0,93,0,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "124", + "requirements": "{0,60}", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3" + }, + { + "id": "7159", + "name": "Insulated boots", + "examine": "They're heavily insulated wellies.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,0,0,1,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", "requirements": "{18,37}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "They're heavily insulated wellies.", - "durability": null, - "weight": "1.3", - "equipment_slot": "10", - "grand_exchange_price": "269", - "name": "Insulated boots", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7159", - "bonuses": "0,0,0,0,0,1,1,0,0,1,0,0,0,0,0" + "weight": "1.3" }, { - "examine": "Before being attacked: A ball of Electrical energy.", - "durability": null, + "id": "7160", "name": "Killerwatt", + "examine": "Before being attacked: A ball of Electrical energy.", "archery_ticket_price": "0", "attack_speed": "2", - "id": "7160" + "durability": null }, { - "durability": null, + "id": "7161", "name": "Insulated boots", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7161" + "durability": null, + "tradeable": "true" }, { - "shop_price": "5", - "ge_buy_limit": "100", + "id": "7162", + "name": "Pie recipe book", "examine": "Lots of pie recipes for me to try.", - "grand_exchange_price": "62", - "durability": null, - "name": "Pie recipe book", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7162" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "62", - "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "7163", "name": "Pie recipe book", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7163" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "54", - "ge_buy_limit": "1000", + "id": "7164", + "name": "Part mud pie", "examine": "Still needs two more ingredients.", - "grand_exchange_price": "77", - "durability": null, - "name": "Part mud pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7164" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "77", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part mud pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7165" - }, - { "shop_price": "54", - "ge_buy_limit": "1000", - "examine": "Still needs one more ingredient.", - "grand_exchange_price": "284", - "durability": null, - "name": "Part mud pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7166" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "284", + "id": "7165", + "name": "Part mud pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part mud pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7167" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "7166", + "name": "Part mud pie", + "examine": "Still needs one more ingredient.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "shop_price": "54", + "tradeable": "true" + }, + { + "id": "7167", + "name": "Part mud pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7168", + "name": "Raw mud pie", "examine": "Needs to be baked before I can use it.", - "grand_exchange_price": "1625", - "durability": null, - "name": "Raw mud pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7168" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1625", + "id": "7169", + "name": "Raw mud pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Raw mud pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7169" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "shop_price": "54", - "ge_buy_limit": "1000", - "turn90cw_anim": "821", - "examine": "All the good of the earth.", - "walk_anim": "819", - "durability": null, - "turn90ccw_anim": "822", - "weapon_interface": "13", - "turn180_anim": "820", - "render_anim": "1", - "equipment_slot": "3", - "grand_exchange_price": "2024", - "stand_anim": "808", - "name": "Mud pie", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", "id": "7170", - "stand_turn_anim": "823" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2024", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Mud pie", - "tradeable": "true", + "examine": "All the good of the earth.", "archery_ticket_price": "0", - "id": "7171" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", + "render_anim": "1", + "run_anim": "824", + "shop_price": "54", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "13" }, { + "id": "7171", + "name": "Mud pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7172", + "name": "Part garden pie", "examine": "Still needs two more ingredients.", - "grand_exchange_price": "94", - "durability": null, - "name": "Part garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7172" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "94", + "id": "7173", + "name": "Part garden pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7173" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7174", + "name": "Part garden pie", "examine": "Still needs one more ingredient.", - "grand_exchange_price": "150", - "durability": null, - "name": "Part garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7174" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "150", + "id": "7175", + "name": "Part garden pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7175" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7176", + "name": "Raw garden pie", "examine": "Needs cooking before I eat it.", - "grand_exchange_price": "1052", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7177", "name": "Raw garden pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "7176" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1052", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Raw garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7177" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "What I wouldn't give for a good steak about now...", - "grand_exchange_price": "1667", - "durability": null, + "id": "7178", "name": "Garden pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7178" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1667", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Garden pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7179" - }, - { - "ge_buy_limit": "1000", "examine": "What I wouldn't give for a good steak about now...", - "grand_exchange_price": "442", - "durability": null, - "name": "Half a garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7180" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "442", + "id": "7179", + "name": "Garden pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half a garden pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7181" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "7180", + "name": "Half a garden pie", + "examine": "What I wouldn't give for a good steak about now...", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7181", + "name": "Half a garden pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7182", + "name": "Part fish pie", "examine": "Still needs two more ingredients.", - "grand_exchange_price": "51", - "durability": null, - "name": "Part fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7182" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "51", + "id": "7183", + "name": "Part fish pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7183" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7184", + "name": "Part fish pie", "examine": "Still needs one more ingredient.", - "grand_exchange_price": "691", - "durability": null, - "name": "Part fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7184" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "691", + "id": "7185", + "name": "Part fish pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7185" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7186", + "name": "Raw fish pie", "examine": "Raw fish is risky, better cook it.", - "grand_exchange_price": "1198", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7187", "name": "Raw fish pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "7186" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1198", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Raw fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7187" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "Bounty of the sea.", - "grand_exchange_price": "121", - "durability": null, + "id": "7188", "name": "Fish pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7188" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "121", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Fish pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7189" - }, - { - "ge_buy_limit": "1000", "examine": "Bounty of the sea.", - "grand_exchange_price": "56", - "durability": null, - "name": "Half a fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7190" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "56", + "id": "7189", + "name": "Fish pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half a fish pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7191" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "7190", + "name": "Half a fish pie", + "examine": "Bounty of the sea.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7191", + "name": "Half a fish pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7192", + "name": "Part admiral pie", "examine": "Still needs two more ingredients. ", - "grand_exchange_price": "159", - "durability": null, - "name": "Part admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7192" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "159", + "id": "7193", + "name": "Part admiral pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7193" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7194", + "name": "Part admiral pie", "examine": "Still needs one more ingredient.", - "grand_exchange_price": "537", - "durability": null, - "name": "Part admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7194" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "537", + "id": "7195", + "name": "Part admiral pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7195" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7196", + "name": "Raw admiral pie", "examine": "This would taste a lot better cooked.", - "grand_exchange_price": "1813", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7197", "name": "Raw admiral pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "7196" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1813", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Raw admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7197" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "Much tastier than a normal fish pie.", - "grand_exchange_price": "532", - "durability": null, + "id": "7198", "name": "Admiral pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7198" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "532", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Admiral pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7199" - }, - { - "ge_buy_limit": "1000", "examine": "Much tastier than a normal fish pie.", - "grand_exchange_price": "184", - "durability": null, - "name": "Half an admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7200" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "184", + "id": "7199", + "name": "Admiral pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half an admiral pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7201" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "7200", + "name": "Half an admiral pie", + "examine": "Much tastier than a normal fish pie.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7201", + "name": "Half an admiral pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7202", + "name": "Part wild pie", "examine": "Still needs two more ingredients.", - "grand_exchange_price": "126", - "durability": null, - "name": "Part wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7202" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "126", + "id": "7203", + "name": "Part wild pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7203" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7204", + "name": "Part wild pie", "examine": "Still needs one more ingredient.", - "grand_exchange_price": "1116", - "durability": null, - "name": "Part wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7204" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1116", + "id": "7205", + "name": "Part wild pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7205" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7206", + "name": "Raw wild pie", "examine": "Good as it looks, I'd better cook it.", - "grand_exchange_price": "3787", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7207", "name": "Raw wild pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7206" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3787", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Raw wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7207" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A triumph of man over nature.", - "grand_exchange_price": "1322", - "durability": null, + "id": "7208", "name": "Wild pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7208" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1322", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Wild pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7209" - }, - { - "ge_buy_limit": "1000", "examine": "A triumph of man over nature.", - "grand_exchange_price": "112", - "durability": null, - "name": "Half a wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7210" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "112", + "id": "7209", + "name": "Wild pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half a wild pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7211" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "7210", + "name": "Half a wild pie", + "examine": "A triumph of man over nature.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7211", + "name": "Half a wild pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7212", + "name": "Part summer pie", "examine": "Still needs two more ingredients.", - "grand_exchange_price": "495", - "durability": null, - "name": "Part summer pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7212" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "495", + "id": "7213", + "name": "Part summer pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part summer pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7213" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7214", + "name": "Part summer pie", "examine": "Still needs one more ingredient.", - "grand_exchange_price": "980", - "durability": null, - "name": "Part summer pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7214" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "980", + "id": "7215", + "name": "Part summer pie", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Part summer pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7215" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7216", + "name": "Raw summer pie", "examine": "Fresh fruit may be good for you, but I should really cook this.", - "grand_exchange_price": "2577", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7217", "name": "Raw summer pie", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "7216" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2577", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Raw summer pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7217" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "All the fruits of a very small forest.", - "grand_exchange_price": "1288", - "durability": null, + "id": "7218", "name": "Summer pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7218" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1288", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Summer pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7219" - }, - { - "ge_buy_limit": "1000", "examine": "All the fruits of a very small forest.", - "grand_exchange_price": "430", - "durability": null, - "name": "Half a summer pie", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7220" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "430", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Half a summer pie", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7221" + "tradeable": "true" }, { - "shop_price": "19", + "id": "7219", + "name": "Summer pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7220", + "name": "Half a summer pie", + "examine": "All the fruits of a very small forest.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7221", + "name": "Half a summer pie", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7222", + "name": "Burnt rabbit", "examine": "Mmm this looks tasty.", - "grand_exchange_price": "32", - "durability": null, - "name": "Burnt rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7222" + "durability": null, + "shop_price": "19", + "tradeable": "true" }, { - "shop_price": "25", - "ge_buy_limit": "1000", + "id": "7223", + "name": "Roast rabbit", "examine": "A delicious looking piece of roast rabbit.", - "grand_exchange_price": "37", - "durability": null, - "name": "Roast rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7223" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "25", + "tradeable": "true" }, { - "shop_price": "67", - "ge_buy_limit": "1000", + "id": "7224", + "name": "Skewered rabbit", "examine": "Might taste better cooked.", - "grand_exchange_price": "112", - "durability": null, - "name": "Skewered rabbit", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "7224" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "67", + "tradeable": "true", + "weight": "0.1" }, { - "shop_price": "81", - "ge_buy_limit": "100", + "id": "7225", + "name": "Iron spit", "examine": "An iron spit.", - "grand_exchange_price": "18", - "durability": null, - "name": "Iron spit", - "tradeable": "true", - "weight": "1.5", "archery_ticket_price": "0", - "id": "7225" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "81", + "tradeable": "true", + "weight": "1.5" }, { - "durability": null, + "id": "7227", "name": "Burnt chompy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7227" + "durability": null, + "tradeable": "true" }, { - "shop_price": "130", - "ge_buy_limit": "1000", + "id": "7228", + "name": "Cooked chompy", "examine": "It might look delicious to an ogre.Roasted chompy bird.", - "grand_exchange_price": "164", - "durability": null, - "name": "Cooked chompy", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "7228" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "130", + "tradeable": "true", + "weight": "10" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "164", - "durability": null, + "id": "7229", "name": "Cooked chompy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7229" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "7230", + "name": "Skewered chompy", "examine": "A skewered chompy bird.", - "grand_exchange_price": "294", - "durability": null, - "name": "Skewered chompy", - "tradeable": "true", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "7230" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "durability": null, + "id": "7231", "name": "Burnt rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7231" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7232", "name": "Roast rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7232" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7233", "name": "Skewered rabbit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7233" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7234", "name": "Iron spit", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7234" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7235", "name": "Skewered chompy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7235" + "durability": null, + "tradeable": "true" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7236", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7236" + "durability": null, + "shop_price": "5000" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "7237", "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7237" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7238" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7239" - }, - { "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7240" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7238", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7241" + "durability": null, + "shop_price": "5000" }, { + "id": "7239", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7240", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7242" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7241", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7243" + "durability": null, + "shop_price": "5000" }, { + "id": "7242", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7244" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7243", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7245" + "durability": null, + "shop_price": "5000" }, { + "id": "7244", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7246" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7245", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7247" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "7248" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7249" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7250" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7251" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7252" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7253" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7254" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7255" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7256" + "durability": null, + "shop_price": "5000" }, { + "id": "7246", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7257" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7247", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7258" + "durability": null, + "shop_price": "5000" }, { + "id": "7248", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7249", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7250", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7251", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7252", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7253", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7254", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7255", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7256", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7257", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7259" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7258", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7260" + "durability": null, + "shop_price": "5000" }, { + "id": "7259", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7261" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7260", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7262" + "durability": null, + "shop_price": "5000" }, { + "id": "7261", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7263" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7262", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7264" + "durability": null, + "shop_price": "5000" }, { + "id": "7263", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7265" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7264", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7266" + "durability": null, + "shop_price": "5000" }, { + "id": "7265", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7267" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7266", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7268" + "durability": null, + "shop_price": "5000" }, { - "examine": "I need to answer this correctly.", + "id": "7267", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "7268", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7269", "name": "Challenge scroll", - "archery_ticket_price": "0", - "id": "7269" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7270" - }, - { "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7271" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7270", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7272" + "durability": null, + "shop_price": "5000" }, { + "id": "7271", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7273" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7272", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7274" + "durability": null, + "shop_price": "5000" }, { + "id": "7273", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7275" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7274", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7276" + "durability": null, + "shop_price": "5000" }, { + "id": "7275", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7277" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7276", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7278" + "durability": null, + "shop_price": "5000" }, { + "id": "7277", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7279" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7278", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7280" + "durability": null, + "shop_price": "5000" }, { + "id": "7279", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7281" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7280", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7282" + "durability": null, + "shop_price": "5000" }, { + "id": "7281", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", - "durability": null, - "name": "Challenge scroll", "archery_ticket_price": "0", - "id": "7283" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7282", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7284" + "durability": null, + "shop_price": "5000" }, { + "id": "7283", + "name": "Challenge scroll", "examine": "I need to answer this correctly.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7284", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7285", "name": "Challenge scroll", + "examine": "I need to answer this correctly.", "archery_ticket_price": "0", - "id": "7285" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7286", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7286" + "durability": null, + "shop_price": "5000" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "7287", "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7287" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7288" - }, - { "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7289" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7288", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7290" + "durability": null, + "shop_price": "5000" }, { + "id": "7289", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7291" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7290", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7292" + "durability": null, + "shop_price": "5000" }, { + "id": "7291", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7293" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7292", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7294" + "durability": null, + "shop_price": "5000" }, { + "id": "7293", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "archery_ticket_price": "0", "durability": null, - "name": "Casket", "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7295" + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7294", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7296" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", "archery_ticket_price": "0", - "id": "7298" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7300" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7301" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7303" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7304" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7305" + "durability": null, + "shop_price": "5000" }, { + "id": "7295", + "name": "Casket", "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", "archery_ticket_price": "0", - "id": "7306" + "durability": null, + "tradeable": "true", + "weight": "5" }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "7296", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7307" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7308" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7298", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7309" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7310" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7300", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7311" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7312" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7301", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7313" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7314" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7303", "name": "Clue scroll", - "archery_ticket_price": "0", - "id": "7315" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7316" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7304", "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", - "id": "7317" + "durability": null, + "shop_price": "5000" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", + "id": "7305", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "5000" + }, + { + "id": "7306", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "7318" + "durability": null, + "tradeable": "true", + "weight": "5" }, { - "ge_buy_limit": "2", - "examine": "Stylish!", - "grand_exchange_price": "36600", - "durability": null, - "name": "Red boater", - "tradeable": "true", + "id": "7307", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7308", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "7309", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7310", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "7311", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7312", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "7313", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7314", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "7315", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7316", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "7317", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000" + }, + { + "id": "7318", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { "id": "7319", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "36600", - "durability": null, "name": "Red boater", - "tradeable": "true", + "examine": "Stylish!", "archery_ticket_price": "0", - "id": "7320" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "Stylish!", - "grand_exchange_price": "16600", - "durability": null, - "name": "Orange boater", - "tradeable": "true", + "id": "7320", + "name": "Red boater", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7321", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "16600", - "durability": null, "name": "Orange boater", - "tradeable": "true", + "examine": "Stylish!", "archery_ticket_price": "0", - "id": "7322" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "Stylish!", - "grand_exchange_price": "43000", - "durability": null, - "name": "Green boater", - "tradeable": "true", + "id": "7322", + "name": "Orange boater", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7323", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "43000", - "durability": null, "name": "Green boater", - "tradeable": "true", + "examine": "Stylish!", "archery_ticket_price": "0", - "id": "7324" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "2", - "examine": "Stylish!", - "grand_exchange_price": "37600", - "durability": null, - "name": "Blue boater", - "tradeable": "true", + "id": "7324", + "name": "Green boater", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7325", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "37600", - "durability": null, "name": "Blue boater", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7326" - }, - { - "ge_buy_limit": "2", "examine": "Stylish!", - "grand_exchange_price": "41700", - "durability": null, - "name": "Black boater", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7326", + "name": "Blue boater", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7327", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "41700", - "durability": null, "name": "Black boater", - "tradeable": "true", + "examine": "Stylish!", "archery_ticket_price": "0", - "id": "7328" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "Makes firelighting a lot easier.", - "grand_exchange_price": "93", + "id": "7328", + "name": "Black boater", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7329", "name": "Red firelighter", - "tradeable": "true", + "examine": "Makes firelighting a lot easier.", "archery_ticket_price": "0", - "id": "7329" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "Makes firelighting a lot easier.", - "grand_exchange_price": "94", - "durability": null, + "id": "7330", "name": "Green firelighter", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7330" - }, - { - "ge_buy_limit": "100", "examine": "Makes firelighting a lot easier.", - "grand_exchange_price": "113", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7331", "name": "Blue firelighter", - "tradeable": "true", + "examine": "Makes firelighting a lot easier.", "archery_ticket_price": "0", - "id": "7331" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black kitesheild with a heraldic design.", - "durability": null, - "weight": "4", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "14300", - "name": "Black shield(h1)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "7332", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "14300", - "durability": null, "name": "Black shield(h1)", - "tradeable": "true", + "examine": "A black kitesheild with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "7333" + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "16400", - "name": "Adamant shield(h1)", - "tradeable": "true", + "id": "7333", + "name": "Black shield(h1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7334", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "16400", - "durability": null, "name": "Adamant shield(h1)", - "tradeable": "true", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "7335" + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune kiteshield with a heraldic design.", - "durability": null, - "weight": "5.4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "34200", - "name": "Rune shield(h1)", - "tradeable": "true", + "id": "7335", + "name": "Adamant shield(h1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7336", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "34200", - "durability": null, "name": "Rune shield(h1)", - "tradeable": "true", + "examine": "A rune kiteshield with a heraldic design.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "7337" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black kiteshield with a heraldic design.", - "durability": null, - "weight": "4", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "9797", - "name": "Black shield(h2)", - "tradeable": "true", + "id": "7337", + "name": "Rune shield(h1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7338", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "9797", - "durability": null, "name": "Black shield(h2)", - "tradeable": "true", + "examine": "A black kiteshield with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "7339" + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "3248", - "name": "Adamant shield(h2)", - "tradeable": "true", + "id": "7339", + "name": "Black shield(h2)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7340", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "3248", - "durability": null, "name": "Adamant shield(h2)", - "tradeable": "true", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "7341" + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune kiteshield with a heraldic design.", - "durability": null, - "weight": "5.4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "32400", - "name": "Rune shield(h2)", - "tradeable": "true", + "id": "7341", + "name": "Adamant shield(h2)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7342", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "32400", - "durability": null, "name": "Rune shield(h2)", - "tradeable": "true", + "examine": "A rune kiteshield with a heraldic design.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "7343" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black shield with a heraldic design.", - "durability": null, - "weight": "4", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "7405", - "name": "Black shield(h3)", - "tradeable": "true", + "id": "7343", + "name": "Rune shield(h2)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7344", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7405", - "durability": null, "name": "Black shield(h3)", - "tradeable": "true", + "examine": "A black shield with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "7345" + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "5271", - "name": "Adamant shield(h3)", - "tradeable": "true", + "id": "7345", + "name": "Black shield(h3)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7346", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "5271", - "durability": null, "name": "Adamant shield(h3)", - "tradeable": "true", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "7347" + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune kiteshield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "32700", - "name": "Rune shield(h3)", - "tradeable": "true", + "id": "7347", + "name": "Adamant shield(h3)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7348", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "32700", - "durability": null, "name": "Rune shield(h3)", - "tradeable": "true", + "examine": "A rune kiteshield with a heraldic design.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "7349" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black shield with a heraldic design.", - "durability": null, - "weight": "4", - "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "5572", - "name": "Black shield(h4)", - "tradeable": "true", + "id": "7349", + "name": "Rune shield(h3)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7350", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "5572", - "durability": null, "name": "Black shield(h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7351" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "3366", - "name": "Adamant shield(h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7352", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "3366", - "durability": null, - "name": "Adamant shield(h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7353" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune kiteshield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "32500", - "name": "Rune shield(h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7354", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "32500", - "durability": null, - "name": "Rune shield(h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7355" - }, - { - "requirements": "{1,10}", - "ge_buy_limit": "2", "examine": "A black shield with a heraldic design.", - "durability": null, - "weight": "4", "absorb": "1,0,2", - "equipment_slot": "5", - "grand_exchange_price": "7159", - "name": "Black shield(h5)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7356", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7159", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", "durability": null, - "name": "Black shield(h5)", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,10}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7357" + "weight": "4" }, { - "requirements": "{1,30}", + "id": "7351", + "name": "Black shield(h4)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7352", + "name": "Adamant shield(h4)", "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "6328", - "name": "Adamant shield(h5)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7358", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "6328", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", "durability": null, - "name": "Adamant shield(h5)", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7359" + "weight": "5" }, { - "requirements": "{1,40}", + "id": "7353", + "name": "Adamant shield(h4)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7354", + "name": "Rune shield(h4)", "examine": "A rune kiteshield with a heraldic design.", - "durability": null, - "weight": "5", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", - "grand_exchange_price": "32400", - "name": "Rune shield(h5)", + "ge_buy_limit": "2", + "requirements": "{1,40}", "tradeable": "true", + "weight": "5" + }, + { + "id": "7355", + "name": "Rune shield(h4)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7356", + "name": "Black shield(h5)", + "examine": "A black shield with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" + }, + { + "id": "7357", + "name": "Black shield(h5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7358", + "name": "Adamant shield(h5)", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "7359", + "name": "Adamant shield(h5)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7360", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "", - "ge_buy_limit": "2", - "grand_exchange_price": "32400", - "durability": null, "name": "Rune shield(h5)", - "tradeable": "true", + "examine": "A rune kiteshield with a heraldic design.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "7361" + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,20}-{4,20}", - "ge_buy_limit": "2", - "examine": "Those studs should provide a bit more protection. Nice trim too!", - "durability": null, - "weight": "5.4", - "absorb": "0,3,1", - "equipment_slot": "4", - "grand_exchange_price": "101600", - "name": "Studded body (g)", - "tradeable": "true", + "id": "7361", + "name": "Rune shield(h5)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "", + "tradeable": "true" + }, + { "id": "7362", - "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "101600", - "durability": null, "name": "Studded body (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7363" - }, - { - "requirements": "{1,20}-{4,20}", - "ge_buy_limit": "2", "examine": "Those studs should provide a bit more protection. Nice trim too!", - "durability": null, - "weight": "5.4", "absorb": "0,3,1", - "equipment_slot": "4", - "grand_exchange_price": "27300", - "name": "Studded body (t)", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "requirements": "{1,20}-{4,20}", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "7363", + "name": "Studded body (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "7364", - "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "27300", - "durability": null, "name": "Studded body (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7365" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "2", "examine": "Those studs should provide a bit more protection. Nice trim too!", - "durability": null, - "weight": "4.5", - "absorb": "0,2,1", - "equipment_slot": "7", - "grand_exchange_price": "114600", - "name": "Studded chaps (g)", - "tradeable": "true", + "absorb": "0,3,1", "archery_ticket_price": "0", - "id": "7366", - "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "114600", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0", "durability": null, - "name": "Studded chaps (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7367" - }, - { - "requirements": "{4,20}", - "ge_buy_limit": "2", - "examine": "Those studs should provide a bit more protection. Nice trim, too!", - "durability": null, - "weight": "4.5", - "absorb": "0,2,1", - "equipment_slot": "7", - "grand_exchange_price": "36800", - "name": "Studded chaps (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7368", - "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "36800", - "durability": null, - "name": "Studded chaps (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7369" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "5000", - "examine": "Made from 100% real dragonhide. With colourful trim!", - "grand_exchange_price": "212400", - "durability": null, - "name": "D'hide body(g)", - "tradeable": "true", - "weight": "6", - "archery_ticket_price": "0", - "id": "7370", - "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "212400", - "durability": null, - "name": "D'hide body(g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7371" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide. With colourful trim!", - "grand_exchange_price": "38800", - "durability": null, - "name": "D'hide body (t)", - "tradeable": "true", - "weight": "6", - "archery_ticket_price": "0", - "id": "7372", - "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "38800", - "durability": null, - "name": "D'hide body (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7373" - }, - { - "requirements": "{1,40}-{4,50}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide, with colourful trim!", - "grand_exchange_price": "6883", - "durability": null, - "name": "D'hide body (g)", - "tradeable": "true", - "weight": "6", - "archery_ticket_price": "0", - "id": "7374", - "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "6883", - "durability": null, - "name": "D'hide body (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7375" - }, - { - "requirements": "{1,40}-{4,50}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide, with colourful trim!", - "grand_exchange_price": "5268", - "durability": null, - "name": "D'hide body (t)", - "tradeable": "true", - "weight": "6", - "archery_ticket_price": "0", - "id": "7376", - "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "5268", - "durability": null, - "name": "D'hide body (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7377" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide, with colourful trim!", - "grand_exchange_price": "1300000", - "durability": null, - "name": "D'hide chaps (g)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7378", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1300000", - "durability": null, - "name": "D'hide chaps (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7379" - }, - { - "requirements": "{4,40}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide, with colourful trim!", - "grand_exchange_price": "304300", - "durability": null, - "name": "D'hide chaps (t)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7380", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "304300", - "durability": null, - "name": "D'hide chaps (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7381" - }, - { - "requirements": "{4,50}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide, with colourful trim!", - "grand_exchange_price": "21300", - "durability": null, - "name": "D'hide chaps (g)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7382", - "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "21300", - "durability": null, - "name": "D'hide chaps (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7383" - }, - { - "requirements": "{4,50}", - "ge_buy_limit": "2", - "examine": "Made from 100% real dragonhide, with colourful trim!", - "grand_exchange_price": "2554", - "durability": null, - "name": "D'hide chaps (t)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "7384", - "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2554", - "durability": null, - "name": "D'hide chaps (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7385" - }, - { - "ge_buy_limit": "2", - "examine": "Leg covering favoured by women and wizards. With a colourful trim!", - "grand_exchange_price": "298900", - "durability": null, - "name": "Blue skirt (g)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7386", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "298900", - "durability": null, - "name": "Blue skirt (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7387" - }, - { - "ge_buy_limit": "2", - "examine": "Leg covering favoured by women and wizards. With a colourful trim!", - "grand_exchange_price": "126800", - "durability": null, - "name": "Blue skirt (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "1", - "id": "7388", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "126800", - "durability": null, - "name": "Blue skirt (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7389" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "I can practise magic better in this.", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Wizard robe (g)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7390", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Wizard robe (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7391" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "I can do magic better in this.", - "grand_exchange_price": "244600", - "durability": null, - "name": "Wizard robe (t)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7392", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "244600", - "durability": null, - "name": "Wizard robe (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7393" - }, - { - "ge_buy_limit": "2", - "examine": "A silly pointed hat with colourful trim.", - "grand_exchange_price": "1400000", - "durability": null, - "name": "Wizard hat (g)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "hat": "true", - "id": "7394", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1400000", - "durability": null, - "name": "Wizard hat (g)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7395" - }, - { - "ge_buy_limit": "2", - "examine": "A silly pointed hat, with colourful trim.", - "grand_exchange_price": "352700", - "durability": null, - "name": "Wizard hat (t)", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "hat": "true", - "id": "7396", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "352700", - "durability": null, - "name": "Wizard hat (t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7397" - }, - { - "requirements": "{1,20}-{6,40}", - "ge_buy_limit": "2", - "examine": "Enchanted Wizards robes.", - "durability": null, - "weight": "1.8", - "absorb": "2,1,0", - "equipment_slot": "7", - "grand_exchange_price": "50000", - "name": "Enchanted robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7398", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "requirements": "{1,20}-{6,40}", - "ge_buy_limit": "2", - "examine": "Enchanted Wizards robes.", - "durability": null, - "weight": "1", - "absorb": "3,1,0", "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "75100", - "name": "Enchanted top", + "ge_buy_limit": "2", + "requirements": "{1,20}-{4,20}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7399", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + "weight": "5.4" }, { + "id": "7365", + "name": "Studded body (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7366", + "name": "Studded chaps (g)", + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "absorb": "0,2,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{4,20}", + "tradeable": "true", + "weight": "4.5" + }, + { + "id": "7367", + "name": "Studded chaps (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7368", + "name": "Studded chaps (t)", + "examine": "Those studs should provide a bit more protection. Nice trim, too!", + "absorb": "0,2,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{4,20}", + "tradeable": "true", + "weight": "4.5" + }, + { + "id": "7369", + "name": "Studded chaps (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7370", + "name": "D'hide body(g)", + "examine": "Made from 100% real dragonhide. With colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "5000", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "7371", + "name": "D'hide body(g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "7372", + "name": "D'hide body (t)", + "examine": "Made from 100% real dragonhide. With colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "7373", + "name": "D'hide body (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7374", + "name": "D'hide body (g)", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,50}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "7375", + "name": "D'hide body (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7376", + "name": "D'hide body (t)", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,50}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "7377", + "name": "D'hide body (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7378", + "name": "D'hide chaps (g)", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{4,40}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "7379", + "name": "D'hide chaps (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7380", + "name": "D'hide chaps (t)", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{4,40}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "7381", + "name": "D'hide chaps (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7382", + "name": "D'hide chaps (g)", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{4,50}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "7383", + "name": "D'hide chaps (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7384", + "name": "D'hide chaps (t)", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{4,50}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "7385", + "name": "D'hide chaps (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7386", + "name": "Blue skirt (g)", + "examine": "Leg covering favoured by women and wizards. With a colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7387", + "name": "Blue skirt (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7388", + "name": "Blue skirt (t)", + "examine": "Leg covering favoured by women and wizards. With a colourful trim!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7389", + "name": "Blue skirt (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7390", + "name": "Wizard robe (g)", + "examine": "I can practise magic better in this.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7391", + "name": "Wizard robe (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7392", + "name": "Wizard robe (t)", + "examine": "I can do magic better in this.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7393", + "name": "Wizard robe (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7394", + "name": "Wizard hat (g)", + "examine": "A silly pointed hat with colourful trim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7395", + "name": "Wizard hat (g)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7396", + "name": "Wizard hat (t)", + "examine": "A silly pointed hat, with colourful trim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "hat": "true", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "7397", + "name": "Wizard hat (t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "7398", + "name": "Enchanted robe", + "examine": "Enchanted Wizards robes.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,20}-{6,40}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "7399", + "name": "Enchanted top", + "examine": "Enchanted Wizards robes.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,40}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7400", + "name": "Enchanted hat", + "examine": "A three pointed hat of magic.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,20}-{6,40}", - "ge_buy_limit": "2", - "examine": "A three pointed hat of magic.", - "grand_exchange_price": "8845", - "durability": null, - "name": "Enchanted hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7400", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", - "equipment_slot": "0" + "tradeable": "true" }, { - "durability": null, + "id": "7401", "name": "Enchanted robe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7401" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7402", "name": "Enchanted top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7402" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7403", "name": "Enchanted hat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7403" + "durability": null, + "tradeable": "true" }, { - "examine": "A number of chemical covered wooden logs.", - "durability": null, + "id": "7404", "name": "Red logs", + "examine": "A number of chemical covered wooden logs.", "archery_ticket_price": "0", - "id": "7404" + "durability": null }, { - "examine": "A number of chemical covered wooden logs.", - "durability": null, + "id": "7405", "name": "Green logs", - "weight": "2", - "archery_ticket_price": "0", - "id": "7405" - }, - { "examine": "A number of chemical covered wooden logs.", + "archery_ticket_price": "0", "durability": null, + "weight": "2" + }, + { + "id": "7406", "name": "Blue logs", - "weight": "2", + "examine": "A number of chemical covered wooden logs.", "archery_ticket_price": "0", - "id": "7406" + "durability": null, + "weight": "2" }, { - "durability": null, + "id": "7407", "name": "Dragon 2h sword", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7407" + "durability": null, + "tradeable": "true" }, { - "destroy_message": "I found this in a grave at Draynor Manor.", - "examine": "I shouldn't joke; this is a grave matter.", - "durability": null, + "id": "7408", "name": "Draynor skull", - "tradeable": "false", - "destroy": "true", + "examine": "I shouldn't joke; this is a grave matter.", "archery_ticket_price": "0", - "id": "7408" + "destroy": "true", + "destroy_message": "I found this in a grave at Draynor Manor.", + "durability": null, + "tradeable": "false" }, { - "shop_price": "40000", - "examine": "The only way to kill a Tanglefoot.", - "durability": null, - "destroy": "true", - "weight": "0.4", - "attack_speed": "5", - "weapon_interface": "5", - "equipment_slot": "3", - "destroy_message": "I'll chat to Malignius Mortifer if I want another pair.", - "name": "Magic secateurs", - "tradeable": "false", - "archery_ticket_price": "0", "id": "7409", - "bonuses": "7,9,-5,1,0,0,1,0,1,0,0,1,0,0,0" - }, - { - "destroy_message": "I can always find another Tanglefoot if I need more.", - "examine": "Contains the Fairy Queen's magical essence.", - "durability": null, - "name": "Queen's secateurs", + "name": "Magic secateurs", + "examine": "The only way to kill a Tanglefoot.", "archery_ticket_price": "0", - "id": "7410", - "equipment_slot": "3" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A list of the Fairy Queen's symptoms.", - "durability": null, - "name": "Symptoms list", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7411" - }, - { - "examine": "Full: ", - "durability": null, - "name": "Bird's nest", - "archery_ticket_price": "0", - "id": "7413" - }, - { - "durability": null, - "name": "Paddle", - "archery_ticket_price": "0", - "id": "7414", - "weapon_interface": "1", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Paddle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7415" - }, - { - "ge_buy_limit": "5000", - "examine": "A mole claw.", - "grand_exchange_price": "11800", - "durability": null, - "name": "Mole claw", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7416" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "11800", - "durability": null, - "name": "Mole claw", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7417" - }, - { - "ge_buy_limit": "5000", - "examine": "The skin of a large mole.", - "grand_exchange_price": "12000", - "durability": null, - "name": "Mole skin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7418" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "12000", - "durability": null, - "name": "Mole skin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7419" - }, - { - "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense. (As Fungi) A bouncy fungus. (Level 74) A fun guy. No wait, that's awful.. (Level 86)", - "durability": null, - "name": "Mutated zygomite", - "archery_ticket_price": "0", - "id": "7420" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 10", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7421", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 9", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7422", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 8", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7423", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 7", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7424", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 6", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7425", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 5", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7426", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 4", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7427", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 3", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7428", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 2", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7429", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 1", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7430", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "300", - "turn90cw_anim": "821", - "examine": "Pumps fungicide.", - "walk_anim": "3334", - "durability": null, - "weight": "2", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "618", - "equipment_slot": "3", - "stand_anim": "3332", - "name": "Fungicide spray 0", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7431", - "stand_turn_anim": "823" - }, - { - "requirements": "{18,57}", - "shop_price": "10", - "examine": "Does exactly what it says on the tin. (Kills Fungi.)", - "durability": null, - "name": "Fungicide", - "archery_ticket_price": "0", - "id": "7432" - }, - { - "shop_price": "35", - "ge_buy_limit": "100", - "examine": "Spoooooon!", - "durability": null, - "weight": "0.4", "attack_speed": "5", - "weapon_interface": "6", + "bonuses": "7,9,-5,1,0,0,1,0,1,0,0,1,0,0,0", + "destroy": "true", + "destroy_message": "I'll chat to Malignius Mortifer if I want another pair.", + "durability": null, "equipment_slot": "3", - "grand_exchange_price": "44", - "name": "Wooden spoon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7433", - "bonuses": "4,5,-2,0,0,0,3,2,0,0,0,7,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "44", - "durability": null, - "name": "Wooden spoon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7434" - }, - { - "shop_price": "45", - "ge_buy_limit": "100", - "examine": "A large whisk of death.", - "durability": null, - "attack_speed": "4", + "shop_price": "40000", + "tradeable": "false", "weapon_interface": "5", - "equipment_slot": "3", - "grand_exchange_price": "11", - "name": "Egg whisk", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7435", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "11", + "id": "7410", + "name": "Queen's secateurs", + "examine": "Contains the Fairy Queen's magical essence.", + "archery_ticket_price": "0", + "destroy_message": "I can always find another Tanglefoot if I need more.", "durability": null, - "name": "Egg whisk", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7436" + "equipment_slot": "3" }, { + "id": "7411", + "name": "Symptoms list", + "examine": "A list of the Fairy Queen's symptoms.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "7413", + "name": "Bird's nest", + "examine": "Full: ", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7414", + "name": "Paddle", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weapon_interface": "1" + }, + { + "id": "7415", + "name": "Paddle", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7416", + "name": "Mole claw", + "examine": "A mole claw.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "7417", + "name": "Mole claw", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "7418", + "name": "Mole skin", + "examine": "The skin of a large mole.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "7419", + "name": "Mole skin", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "7420", + "name": "Mutated zygomite", + "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense. (As Fungi) A bouncy fungus. (Level 74) A fun guy. No wait, that's awful.. (Level 86)", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7421", + "name": "Fungicide spray 10", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7422", + "name": "Fungicide spray 9", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7423", + "name": "Fungicide spray 8", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7424", + "name": "Fungicide spray 7", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7425", + "name": "Fungicide spray 6", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7426", + "name": "Fungicide spray 5", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7427", + "name": "Fungicide spray 4", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7428", + "name": "Fungicide spray 3", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7429", + "name": "Fungicide spray 2", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7430", + "name": "Fungicide spray 1", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7431", + "name": "Fungicide spray 0", + "examine": "Pumps fungicide.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "618", + "requirements": "{18,57}", + "run_anim": "824", + "shop_price": "300", + "stand_anim": "3332", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "3334", + "weight": "2" + }, + { + "id": "7432", + "name": "Fungicide", + "examine": "Does exactly what it says on the tin. (Kills Fungi.)", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{18,57}", + "shop_price": "10" + }, + { + "id": "7433", + "name": "Wooden spoon", + "examine": "Spoooooon!", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "4,5,-2,0,0,0,3,2,0,0,0,7,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "35", + "tradeable": "true", + "weapon_interface": "6", + "weight": "0.4" + }, + { + "id": "7434", + "name": "Wooden spoon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7435", + "name": "Egg whisk", + "examine": "A large whisk of death.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "45", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "7436", + "name": "Egg whisk", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7437", + "name": "Spork", + "examine": "Use the spork.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "11,8,-2,0,0,0,2,1,0,0,0,12,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,10}", "shop_price": "292", - "ge_buy_limit": "100", - "examine": "Use the spork.", - "durability": null, - "weight": "1.8", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "5", - "equipment_slot": "3", - "grand_exchange_price": "196", - "name": "Spork", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7437", - "bonuses": "11,8,-2,0,0,0,2,1,0,0,0,12,0,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "196", - "durability": null, + "id": "7438", "name": "Spork", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7438" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,10}", - "ge_buy_limit": "100", - "shop_price": "1728", - "turn90cw_anim": "7044", - "examine": "A large spatula... of doom!", - "walk_anim": "7046", - "durability": null, - "weight": "3.6", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "7", - "turn180_anim": "7045", - "render_anim": "124", - "equipment_slot": "3", - "grand_exchange_price": "953", - "stand_anim": "7047", - "tradeable": "true", - "name": "Spatula", - "run_anim": "7039", - "archery_ticket_price": "0", "id": "7439", - "stand_turn_anim": "7040", - "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,22,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "953", - "durability": null, "name": "Spatula", - "tradeable": "true", + "examine": "A large spatula... of doom!", "archery_ticket_price": "0", - "id": "7440" + "attack_speed": "7", + "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,22,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "124", + "requirements": "{0,10}", + "run_anim": "7039", + "shop_price": "1728", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" }, { + "id": "7440", + "name": "Spatula", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7441", + "name": "Frying pan", + "examine": "Looks like it's non-stick too!", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "-4,-4,25,-4,0,0,0,0,0,0,0,20,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,20}", "shop_price": "1494", - "ge_buy_limit": "100", - "examine": "Looks like it's non-stick too!", - "durability": null, - "weight": "1.5", - "attack_speed": "6", + "tradeable": "true", "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "836", - "name": "Frying pan", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7441", - "bonuses": "-4,-4,25,-4,0,0,0,0,0,0,0,20,0,0,0" + "weight": "1.5" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "836", + "id": "7442", + "name": "Frying pan", + "archery_ticket_price": "0", "durability": null, - "name": "Frying pan", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7442" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "7443", + "name": "Skewer", + "examine": "Generally used for impaling fresh meat.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,30}", "shop_price": "2880", - "ge_buy_limit": "100", - "examine": "Generally used for impaling fresh meat.", - "durability": null, - "weight": "2", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "6", - "equipment_slot": "3", - "grand_exchange_price": "1712", - "name": "Skewer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7443", - "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1712", + "id": "7444", + "name": "Skewer", + "archery_ticket_price": "0", "durability": null, - "name": "Skewer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7444" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "7445", + "name": "Rolling pin", + "examine": "That's how I roll!", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,4,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,40}", "shop_price": "12960", - "ge_buy_limit": "100", - "examine": "That's how I roll!", - "durability": null, - "weight": "1.8", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "8445", - "name": "Rolling pin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7445", - "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + "weight": "1.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8445", + "id": "7446", + "name": "Rolling pin", + "archery_ticket_price": "0", "durability": null, - "name": "Rolling pin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7446" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "7447", + "name": "Kitchen knife", + "examine": "A sharp, dependable knife, for filleting meat.", + "archery_ticket_price": "0", + "attack_audios": "2704,0,0,0", + "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,40}", "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "A sharp, dependable knife, for filleting meat.", - "durability": null, - "attack_speed": "4", - "weapon_interface": "5", - "equipment_slot": "3", - "grand_exchange_price": "4686", - "attack_audios": "2704,0,0,0", - "name": "Kitchen knife", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7447", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + "weapon_interface": "5" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "4686", - "durability": null, + "id": "7448", "name": "Kitchen knife", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7448" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "Often used to soften tough meat up.", - "walk_anim": "819", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "defence_anim": "1666", - "equipment_slot": "3", - "attack_anims": "2067,2066,2068", - "grand_exchange_price": "24700", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", "id": "7449", - "stand_turn_anim": "823", - "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", - "requirements": "{0,40}", - "shop_price": "41500", - "durability": null, - "weight": "1", - "weapon_interface": "10", - "render_anim": "1", - "name": "Meat tenderiser" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "24700", - "durability": null, "name": "Meat tenderiser", - "tradeable": "true", + "examine": "Often used to soften tough meat up.", "archery_ticket_price": "0", - "id": "7450" + "attack_anims": "2067,2066,2068", + "attack_speed": "6", + "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", + "defence_anim": "1666", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1", + "requirements": "{0,40}", + "run_anim": "824", + "shop_price": "41500", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10", + "weight": "1" }, { + "id": "7450", + "name": "Meat tenderiser", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7451", + "name": "Cleaver", + "examine": "An effective tool for chopping tough meat.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "defence_anim": "397", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{0,40}", "shop_price": "24040", - "ge_buy_limit": "100", - "examine": "An effective tool for chopping tough meat.", - "durability": null, - "weight": "0.5", - "attack_speed": "4", + "tradeable": "true", "weapon_interface": "6", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "15000", - "attack_audios": "2500,0,2517,0", - "name": "Cleaver", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7451", - "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0" + "weight": "0.5" }, { + "id": "7452", + "name": "Cleaver", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "15000", - "durability": null, - "name": "Cleaver", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7452" + "tradeable": "true" }, { - "shop_price": "50", - "examine": "A pair of plain gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "7453", + "name": "Gloves", + "examine": "A pair of plain gloves.", + "archery_ticket_price": "0", "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "50", + "weight": "0.2" }, { - "shop_price": "100", - "examine": "A pair of bronze-coloured gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "7454", + "name": "Gloves", + "examine": "A pair of bronze-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "2,2,2,1,2,2,2,2,1,2,1,2,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "100", + "weight": "0.2" }, { - "shop_price": "325", - "examine": "A pair of iron-coloured gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "7455", + "name": "Gloves", + "examine": "A pair of iron-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "3,3,3,2,3,3,3,3,2,3,2,3,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "325", + "weight": "0.2" }, { - "shop_price": "500", - "examine": "A pair of steel-coloured gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "7456", + "name": "Gloves", + "examine": "A pair of steel-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "4,4,4,2,4,4,4,4,2,4,2,4,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "500", + "weight": "0.2" }, { - "shop_price": "1000", - "examine": "A pair of black-coloured gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "7457", + "name": "Gloves", + "examine": "A pair of black-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "5,5,5,3,5,5,5,5,3,5,3,5,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "1000", + "weight": "0.2" }, { - "shop_price": "1500", - "examine": "A pair of mithril-coloured gloves.", - "durability": null, - "name": "Gloves", - "archery_ticket_price": "0", "id": "7458", + "name": "Gloves", + "examine": "A pair of mithril-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "6,6,6,3,6,6,6,6,3,6,3,6,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "1500" }, { - "shop_price": "2500", - "examine": "A pair of adamant-coloured gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", "id": "7459", + "name": "Gloves", + "examine": "A pair of adamant-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "7,7,7,4,7,7,7,7,4,7,4,7,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "shop_price": "2500", + "weight": "0.2" }, { - "requirements": "{1,13}", - "shop_price": "5000", - "examine": "A pair of rune-coloured gloves.", - "durability": null, - "name": "Gloves", - "archery_ticket_price": "0", "id": "7460", + "name": "Gloves", + "examine": "A pair of rune-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "8,8,8,4,8,8,8,8,4,8,4,8,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "requirements": "{1,13}", + "shop_price": "5000" }, { - "requirements": "{1,41}", - "shop_price": "100000", - "examine": "A pair of dragon-coloured gloves.", - "durability": null, - "name": "Gloves", - "archery_ticket_price": "0", "id": "7461", + "name": "Gloves", + "examine": "A pair of dragon-coloured gloves.", + "archery_ticket_price": "0", "bonuses": "9,9,9,5,9,9,9,9,5,9,5,9,0,0,0", - "equipment_slot": "9" + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", + "requirements": "{1,41}", + "shop_price": "100000" }, { + "id": "7462", + "name": "Gloves", + "examine": "A pair of Barrows-themed gloves.", + "archery_ticket_price": "0", + "bonuses": "12,12,12,6,12,12,12,12,6,12,6,12,0,0,0", + "durability": null, + "equip_audio": "2236", + "equipment_slot": "9", "requirements": "{1,41}", "shop_price": "100000", - "examine": "A pair of Barrows-themed gloves.", - "durability": null, - "name": "Gloves", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "7462", - "bonuses": "12,12,12,6,12,12,12,12,6,12,6,12,0,0,0", - "equipment_slot": "9" + "weight": "0.2" }, { - "examine": "It's cornflour in a pot.", - "durability": null, + "id": "7463", "name": "Cornflour", - "weight": "1", + "examine": "It's cornflour in a pot.", "archery_ticket_price": "0", - "id": "7463" + "durability": null, + "weight": "1" }, { - "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", - "durability": null, + "id": "7464", "name": "Book on chickens", + "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", "archery_ticket_price": "0", - "id": "7464" + "durability": null }, { - "examine": "Surprise, it looks like a vanilla pod.", - "durability": null, + "id": "7465", "name": "Vanilla pod", + "examine": "Surprise, it looks like a vanilla pod.", "archery_ticket_price": "0", - "id": "7465" + "durability": null }, { - "examine": "It's cornflour in a pot.", - "durability": null, + "id": "7466", "name": "Cornflour", - "weight": "1", - "archery_ticket_price": "0", - "id": "7466" - }, - { "examine": "It's cornflour in a pot.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "7468", "name": "Pot of cornflour", - "weight": "1", + "examine": "It's cornflour in a pot.", "archery_ticket_price": "0", - "id": "7468" + "durability": null, + "weight": "1" }, { - "destroy_message": "I'll have to get all the ingredients again.", - "examine": "A mixture of milk, cream and cornflour.", - "durability": null, + "id": "7470", "name": "Cornflour mixture", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A mixture of milk, cream and cornflour.", "archery_ticket_price": "0", - "id": "7470" - }, - { + "destroy": "true", "destroy_message": "I'll have to get all the ingredients again.", - "examine": "It's a bucket of milk and cream.", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "7471", "name": "Milky mixture", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "It's a bucket of milk and cream.", "archery_ticket_price": "0", - "id": "7471" + "destroy": "true", + "destroy_message": "I'll have to get all the ingredients again.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "Some cinnamon sticks.", - "durability": null, + "id": "7472", "name": "Cinnamon", + "examine": "Some cinnamon sticks.", "archery_ticket_price": "0", - "id": "7472" + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pot of brulee supreme.", - "durability": null, + "id": "7476", "name": "Brulee supreme", + "examine": "A pot of brulee supreme.", "archery_ticket_price": "0", - "id": "7476" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "What came first, the chicken or...", - "durability": null, + "id": "7477", "name": "Evil chicken's egg", + "examine": "What came first, the chicken or...", "archery_ticket_price": "0", - "id": "7477" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "I got this by killing a Black Dragon. It might be hard to get another one.", - "examine": "It's got a dragon on it.", - "durability": null, + "id": "7478", "name": "Dragon token", - "tradeable": "false", - "destroy": "true", + "examine": "It's got a dragon on it.", "archery_ticket_price": "0", - "id": "7478" + "destroy": "true", + "destroy_message": "I got this by killing a Black Dragon. It might be hard to get another one.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "It's a meat and potato stew with fancy seasoning.", - "durability": null, + "id": "7479", "name": "Spicy stew", - "weight": "1.5", + "examine": "It's a meat and potato stew with fancy seasoning.", "archery_ticket_price": "0", - "id": "7479" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "1.5" }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7480", "name": "Red spice (4)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7480" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7481", "name": "Red spice (3)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7481" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7482", "name": "Red spice (2)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7482" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7483", "name": "Red spice (1)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7483" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7484", "name": "Orange spice (4)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7484" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7485", "name": "Orange spice (3)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7485" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7486", "name": "Orange spice (2)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7486" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7487", "name": "Orange spice (1)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7487" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7488", "name": "Brown spice (4)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7488" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7489", "name": "Brown spice (3)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7489" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7490", "name": "Brown spice (2)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7490" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7491", "name": "Brown spice (1)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7491" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7492", "name": "Yellow spice (4)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7492" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7493", "name": "Yellow spice (3)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7493" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7494", "name": "Yellow spice (2)", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7494" + "durability": null }, { - "examine": "Allows for equal distribution of spice.", - "durability": null, + "id": "7495", "name": "Yellow spice (1)", - "archery_ticket_price": "0", - "id": "7495" - }, - { "examine": "Allows for equal distribution of spice.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7496", "name": "Empty spice shaker", + "examine": "Allows for equal distribution of spice.", "archery_ticket_price": "0", - "id": "7496" + "durability": null }, { - "examine": "A cool refreshing fruit mix. With ash in for some reason.", - "durability": null, + "id": "7497", "name": "Dirty blast", + "examine": "A cool refreshing fruit mix. With ash in for some reason.", "archery_ticket_price": "0", - "id": "7497" + "durability": null }, { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, + "id": "7498", "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", + "examine": "I wonder what happens if I rub it.", "archery_ticket_price": "0", - "id": "7498" + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" }, { - "examine": "He seems to like wearing black.", - "durability": null, + "id": "7499", "name": "Evil dave", + "examine": "He seems to like wearing black.", "archery_ticket_price": "0", - "id": "7499" + "durability": null }, { - "examine": "A short angry guy.", - "durability": null, + "id": "7500", "name": "Dwarf", + "examine": "A short angry guy.", "archery_ticket_price": "0", - "id": "7500" + "durability": null }, { - "examine": "He provides new players with useful information.", - "durability": null, + "id": "7502", "name": "Lumbridge guide", + "examine": "He provides new players with useful information.", "archery_ticket_price": "0", - "id": "7502" + "durability": null }, { - "examine": "He looks a little shifty.", - "durability": null, + "id": "7504", "name": "Osman", + "examine": "He looks a little shifty.", "archery_ticket_price": "0", - "id": "7504" + "durability": null }, { - "examine": "A shifty-looking character.", - "durability": null, + "id": "7505", "name": "Pirate pete", + "examine": "A shifty-looking character.", "archery_ticket_price": "0", - "id": "7505" + "durability": null }, { - "examine": "Leader of the White Knights.", - "durability": null, + "id": "7506", "name": "Sir amik varze", + "examine": "Leader of the White Knights.", "archery_ticket_price": "0", - "id": "7506" + "durability": null }, { - "examine": "He's been frozen in time.", - "durability": null, + "id": "7507", "name": "Skrach", + "examine": "He's been frozen in time.", "archery_ticket_price": "0", - "id": "7507" + "durability": null }, { - "shop_price": "4", - "examine": "There appears to be a coin in the bottom. Liked by dwarves.", - "durability": null, + "id": "7508", "name": "Asgoldian ale", + "examine": "There appears to be a coin in the bottom. Liked by dwarves.", "archery_ticket_price": "0", - "id": "7508" + "durability": null, + "shop_price": "4" }, { + "id": "7509", + "name": "Dwarven rock cake", "examine": "Red hot and glowing, ouch! Only for dwarf consumption.", - "durability": null, - "name": "Dwarven rock cake", - "weight": "8.5", "archery_ticket_price": "0", - "id": "7509" + "durability": null, + "weight": "8.5" }, { + "id": "7510", + "name": "Dwarven rock cake", "examine": "Cool and heavy as a brick. Only for dwarf consumption.", - "durability": null, - "name": "Dwarven rock cake", - "weight": "8.5", "archery_ticket_price": "0", - "id": "7510" + "durability": null, + "weight": "8.5" }, { - "examine": "Two out of two goblin generals prefer it!", - "durability": null, + "id": "7511", "name": "Slop of compromise", + "examine": "Two out of two goblin generals prefer it!", "archery_ticket_price": "0", - "id": "7511" + "durability": null }, { - "examine": "Previously a nice crispy loaf of bread. Now just kind of icky.", - "durability": null, + "id": "7512", "name": "Soggy bread", + "examine": "Previously a nice crispy loaf of bread. Now just kind of icky.", "archery_ticket_price": "0", - "id": "7512" + "durability": null }, { - "examine": "They clearly taste so much better this way!", - "durability": null, + "id": "7513", "name": "Spicy maggots", + "examine": "They clearly taste so much better this way!", "archery_ticket_price": "0", - "id": "7513" + "durability": null }, { - "examine": "Orange slices which have been dyed, but it looks more like they died.", - "durability": null, + "id": "7514", "name": "Dyed orange", - "tradeable": "true", + "examine": "Orange slices which have been dyed, but it looks more like they died.", "archery_ticket_price": "0", - "id": "7514" + "durability": null, + "tradeable": "true" }, { - "examine": "Glad these aren't in my bed.", - "durability": null, + "id": "7515", "name": "Breadcrumbs", + "examine": "Glad these aren't in my bed.", "archery_ticket_price": "0", - "id": "7515" + "durability": null }, { - "examine": "Those leaves look useful!", - "durability": null, + "id": "7516", "name": "Kelp", + "examine": "Those leaves look useful!", "archery_ticket_price": "0", - "id": "7516" + "durability": null }, { - "examine": "Kelp flakes. Smells of the sea.", - "durability": null, + "id": "7517", "name": "Ground kelp", - "weight": "2", + "examine": "Kelp flakes. Smells of the sea.", "archery_ticket_price": "0", - "id": "7517" + "durability": null, + "weight": "2" }, { - "examine": "A smelly meat.", - "durability": null, + "id": "7518", "name": "Crab meat", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7518" - }, - { "examine": "A smelly meat.", + "archery_ticket_price": "0", "durability": null, + "weight": "0.9" + }, + { + "id": "7519", "name": "Crab meat", - "weight": "0.9", + "examine": "A smelly meat.", "archery_ticket_price": "0", - "id": "7519" + "durability": null, + "weight": "0.9" }, { + "id": "7521", + "name": "Cooked crab meat", + "examine": "Nice and Tasty!", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "examine": "Nice and Tasty!", - "grand_exchange_price": "219", - "durability": null, - "name": "Cooked crab meat", "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7521" + "weight": "0.9" }, { + "id": "7522", + "name": "Cooked crab meat", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "219", - "durability": null, - "name": "Cooked crab meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7522" + "tradeable": "true" }, { + "id": "7523", + "name": "Cooked crab meat", "examine": "Nice and Tasty!", - "grand_exchange_price": "226", - "durability": null, - "name": "Cooked crab meat", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "7523" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { + "id": "7524", + "name": "Cooked crab meat", "examine": "Nice and Tasty!", - "grand_exchange_price": "226", - "durability": null, - "name": "Cooked crab meat", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "7524" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { + "id": "7525", + "name": "Cooked crab meat", "examine": "Nice and Tasty!", - "grand_exchange_price": "226", - "durability": null, - "name": "Cooked crab meat", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "7525" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { + "id": "7526", + "name": "Cooked crab meat", "examine": "Nice and Tasty!", - "grand_exchange_price": "226", - "durability": null, - "name": "Cooked crab meat", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "7526" + "durability": null, + "tradeable": "true", + "weight": "0.9" }, { - "examine": "A smelly paste.", - "durability": null, + "id": "7527", "name": "Ground crab meat", - "archery_ticket_price": "0", - "id": "7527" - }, - { "examine": "A smelly paste.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7528", "name": "Ground cod", + "examine": "A smelly paste.", "archery_ticket_price": "0", - "id": "7528" + "durability": null }, { - "examine": "Would taste nicer if I cooked it.", - "durability": null, + "id": "7529", "name": "Raw fishcake", + "examine": "Would taste nicer if I cooked it.", "archery_ticket_price": "0", - "id": "7529" + "durability": null }, { - "examine": "Mmmm, reminds me of the seaside.", - "durability": null, + "id": "7530", "name": "Cooked fishcake", + "examine": "Mmmm, reminds me of the seaside.", "archery_ticket_price": "0", - "id": "7530" + "durability": null }, { - "examine": "Hmmm, what can I use this for?", - "durability": null, + "id": "7532", "name": "Mudskipper hide", - "weight": "1", + "examine": "Hmmm, what can I use this for?", "archery_ticket_price": "0", - "id": "7532" + "durability": null, + "weight": "1" }, { - "remove_head": "true", - "examine": "You'll look daft, but at least you won't drown!", - "durability": null, - "name": "Fishbowl helmet", - "weight": "5", - "archery_ticket_price": "0", "id": "7534", + "name": "Fishbowl helmet", + "examine": "You'll look daft, but at least you won't drown!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { - "examine": "I'll need a helmet to make this work.", - "durability": null, - "name": "Diving apparatus", - "weight": "10", - "archery_ticket_price": "0", - "id": "7535", - "equipment_slot": "1" - }, - { - "examine": "Fresh off the crab itself.", - "durability": null, - "name": "Fresh crab claw", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7536" - }, - { - "examine": "If it is good enough for crabs, it's good enough for me.", - "durability": null, - "name": "Crab claw", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7537", - "bonuses": "0,0,0,0,0,3,4,2,0,0,1,1,0,0,0", - "equipment_slot": "9" - }, - { - "examine": "Fresh off the crab itself.", - "durability": null, - "name": "Fresh crab shell", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7538" - }, - { "remove_head": "true", - "examine": "If it's good enough for crabs, it's good enough for me!", - "durability": null, - "name": "Crab helmet", - "weight": "0.9", + "weight": "5" + }, + { + "id": "7535", + "name": "Diving apparatus", + "examine": "I'll need a helmet to make this work.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "1", + "weight": "10" + }, + { + "id": "7536", + "name": "Fresh crab claw", + "examine": "Fresh off the crab itself.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7537", + "name": "Crab claw", + "examine": "If it is good enough for crabs, it's good enough for me.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,3,4,2,0,0,1,1,0,0,0", + "durability": null, + "equipment_slot": "9", + "weight": "0.9" + }, + { + "id": "7538", + "name": "Fresh crab shell", + "examine": "Fresh off the crab itself.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { "id": "7539", + "name": "Crab helmet", + "examine": "If it's good enough for crabs, it's good enough for me!", + "archery_ticket_price": "0", "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "0.9" }, { - "examine": "Darn, it's useless now.", - "durability": null, + "id": "7540", "name": "Broken crab claw", - "archery_ticket_price": "0", - "id": "7540" - }, - { "examine": "Darn, it's useless now.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7541", "name": "Broken crab shell", + "examine": "Darn, it's useless now.", "archery_ticket_price": "0", - "id": "7541" + "durability": null }, { - "destroy_message": "Maybe Traiborn will have another.", - "examine": "Imbued with knowledge itself.", - "durability": null, + "id": "7542", "name": "Cake of guidance", - "tradeable": "false", - "destroy": "true", + "examine": "Imbued with knowledge itself.", "archery_ticket_price": "0", - "id": "7542" + "destroy": "true", + "destroy_message": "Maybe Traiborn will have another.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Now all I need to do is cook it.", - "durability": null, + "id": "7543", "name": "Raw guide cake", + "examine": "Now all I need to do is cook it.", "archery_ticket_price": "0", - "id": "7543" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Egg containing knowledge.", - "durability": null, + "id": "7544", "name": "Enchanted egg", + "examine": "Egg containing knowledge.", "archery_ticket_price": "0", - "id": "7544" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Guiding milk.", - "durability": null, + "id": "7545", "name": "Enchanted milk", - "weight": "2", + "examine": "Guiding milk.", "archery_ticket_price": "0", - "id": "7545" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pot of special flour.", "durability": null, + "weight": "2" + }, + { + "id": "7546", "name": "Enchanted flour", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A pot of special flour.", "archery_ticket_price": "0", - "id": "7546" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "A druid pouch.", - "durability": null, + "id": "7547", "name": "Druid pouch", + "examine": "A druid pouch.", "archery_ticket_price": "0", - "id": "7547" + "durability": null }, { - "shop_price": "8", + "id": "7548", + "name": "Potato seed", "examine": "A potato seed - plant in an allotment.", - "grand_exchange_price": "1", - "durability": null, - "name": "Potato seed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7548" + "durability": null, + "shop_price": "8", + "tradeable": "true" }, { - "durability": null, + "id": "7549", "name": "Potato seed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7549" + "durability": null, + "tradeable": "true" }, { - "shop_price": "10", + "id": "7550", + "name": "Onion seed", "examine": "An onion seed - plant in an allotment.", - "grand_exchange_price": "1", - "durability": null, - "name": "Onion seed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7550" - }, - { "durability": null, - "name": "Onion seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7551" - }, - { - "shop_price": "76", - "examine": "Arrows with mithril heads.", - "grand_exchange_price": "24", - "durability": null, - "name": "Mithril arrow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7552", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,22,0,0" - }, - { - "durability": null, - "name": "Mithril arrow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7553" - }, - { - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "16", - "durability": null, - "name": "Fire rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7554" - }, - { - "durability": null, - "name": "Fire rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7555" - }, - { - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "6", - "durability": null, - "name": "Water rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7556" - }, - { - "durability": null, - "name": "Water rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7557" - }, - { - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "9", - "durability": null, - "name": "Air rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7558" - }, - { - "durability": null, - "name": "Air rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7559" - }, - { - "shop_price": "140", - "examine": "Used for small missile spells.", - "grand_exchange_price": "65", - "durability": null, - "name": "Chaos rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7560" - }, - { - "durability": null, - "name": "Chaos rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7561" - }, - { "shop_price": "10", + "tradeable": "true" + }, + { + "id": "7551", + "name": "Onion seed", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7552", + "name": "Mithril arrow", + "examine": "Arrows with mithril heads.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,22,0,0", + "durability": null, + "shop_price": "76", + "tradeable": "true" + }, + { + "id": "7553", + "name": "Mithril arrow", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7554", + "name": "Fire rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "17", + "tradeable": "true" + }, + { + "id": "7555", + "name": "Fire rune", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7556", + "name": "Water rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "17", + "tradeable": "true" + }, + { + "id": "7557", + "name": "Water rune", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7558", + "name": "Air rune", + "examine": "One of the 4 basic elemental Runes.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "17", + "tradeable": "true" + }, + { + "id": "7559", + "name": "Air rune", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7560", + "name": "Chaos rune", + "examine": "Used for small missile spells.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "140", + "tradeable": "true" + }, + { + "id": "7561", + "name": "Chaos rune", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7562", + "name": "Tomato seed", "examine": "A tomato seed - plant in an allotment.", - "grand_exchange_price": "1", + "archery_ticket_price": "0", "durability": null, + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "7563", "name": "Tomato seed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7562" + "durability": null, + "tradeable": "true" }, { - "durability": null, - "name": "Tomato seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7563" - }, - { - "examine": "An inflated toad tied to a rock like a balloon.", - "durability": null, + "id": "7564", "name": "Balloon toad", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7564" - }, - { "examine": "An inflated toad tied to a rock like a balloon.", - "durability": null, - "name": "Balloon toad", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "7565" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "ge_buy_limit": "100", + "id": "7565", + "name": "Balloon toad", + "examine": "An inflated toad tied to a rock like a balloon.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "7566", + "name": "Raw jubbly", "examine": "The uncooked meat of a Jubbly bird.", - "grand_exchange_price": "422", - "durability": null, - "name": "Raw jubbly", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "7566" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "10" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "422", - "durability": null, + "id": "7567", "name": "Raw jubbly", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7567" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "7568", + "name": "Cooked jubbly", "examine": "Lovely jubbly!", - "grand_exchange_price": "944", - "durability": null, - "name": "Cooked jubbly", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "7568" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "944", - "durability": null, + "tradeable": "true", + "weight": "10" + }, + { + "id": "7569", "name": "Cooked jubbly", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7569" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "durability": null, + "id": "7571", "name": "Burnt jubbly", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7571" + "durability": null, + "tradeable": "true" }, { - "examine": "Like a banana only redder.", - "durability": null, - "name": "Red banana", - "archery_ticket_price": "0", "id": "7572", + "name": "Red banana", + "examine": "Like a banana only redder.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "5" }, { - "examine": "Like monkey nuts only tchikier.", - "durability": null, + "id": "7573", "name": "Tchiki monkey nuts", + "examine": "Like monkey nuts only tchikier.", "archery_ticket_price": "0", - "id": "7573" + "durability": null }, { - "examine": "Perfect for stuffing snakes.", - "durability": null, + "id": "7574", "name": "Sliced red banana", + "examine": "Perfect for stuffing snakes.", "archery_ticket_price": "0", - "id": "7574" + "durability": null }, { - "examine": "Mixing this with jam would just be wrong.", - "durability": null, + "id": "7575", "name": "Tchiki nut paste", + "examine": "Mixing this with jam would just be wrong.", "archery_ticket_price": "0", - "id": "7575" + "durability": null }, { - "examine": "Like a snake only not alive.", - "durability": null, + "id": "7576", "name": "Snake corpse", - "weight": "3", + "examine": "Like a snake only not alive.", "archery_ticket_price": "0", - "id": "7576" + "durability": null, + "weight": "3" }, { - "examine": "This snake is stuffed right up.", - "durability": null, + "id": "7577", "name": "Raw stuffed snake", - "weight": "3", + "examine": "This snake is stuffed right up.", "archery_ticket_price": "0", - "id": "7577" + "durability": null, + "weight": "3" }, { - "examine": "Is this really what you wanted to do?", - "durability": null, + "id": "7578", "name": "Odd stuffed snake", + "examine": "Is this really what you wanted to do?", "archery_ticket_price": "0", - "id": "7578" + "durability": null }, { - "examine": "Fit for a Monkey King. (cooked)", - "durability": null, + "id": "7579", "name": "Stuffed snake", - "weight": "3", + "examine": "Fit for a Monkey King. (cooked)", "archery_ticket_price": "0", - "id": "7579" + "durability": null, + "weight": "3" }, { - "examine": "Your hellish pet cat!!", - "durability": null, + "id": "7581", "name": "Overgrown hellcat", + "examine": "Your hellish pet cat!!", "archery_ticket_price": "0", - "id": "7581" + "durability": null }, { - "examine": "Your hellish pet cat!!", - "durability": null, + "id": "7582", "name": "Hell cat", + "examine": "Your hellish pet cat!!", "archery_ticket_price": "0", - "id": "7582" + "durability": null }, { - "examine": "Your hellish pet cat!!", - "durability": null, + "id": "7583", "name": "Hell-kitten", - "archery_ticket_price": "0", - "id": "7583" - }, - { "examine": "Your hellish pet cat!!", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7585", "name": "Wily hellcat", + "examine": "Your hellish pet cat!!", "archery_ticket_price": "0", - "id": "7585" + "durability": null }, { - "examine": "I can train on this", - "durability": null, + "id": "7586", "name": "Dummy", + "examine": "I can train on this", "archery_ticket_price": "0", - "id": "7586" + "durability": null }, { - "examine": "Filled with items. Like a bank, but spookier!", - "durability": null, + "id": "7587", "name": "Coffin", - "archery_ticket_price": "0", - "id": "7587" - }, - { "examine": "Filled with items. Like a bank, but spookier!", - "durability": null, - "name": "Coffin", "archery_ticket_price": "0", - "id": "7588" + "durability": null }, { + "id": "7588", + "name": "Coffin", "examine": "Filled with items. Like a bank, but spookier!", - "durability": null, - "name": "Coffin", "archery_ticket_price": "0", - "id": "7589" + "durability": null }, { + "id": "7589", + "name": "Coffin", "examine": "Filled with items. Like a bank, but spookier!", - "durability": null, - "name": "Coffin", "archery_ticket_price": "0", - "id": "7590" + "durability": null }, { + "id": "7590", + "name": "Coffin", "examine": "Filled with items. Like a bank, but spookier!", - "durability": null, - "name": "Coffin", "archery_ticket_price": "0", - "id": "7591" + "durability": null }, { - "examine": "Aside from the braaaains on the lapel, it's still quite good.", - "durability": null, - "name": "Zombie shirt", + "id": "7591", + "name": "Coffin", + "examine": "Filled with items. Like a bank, but spookier!", "archery_ticket_price": "0", + "durability": null + }, + { "id": "7592", + "name": "Zombie shirt", + "examine": "Aside from the braaaains on the lapel, it's still quite good.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "4" }, { - "examine": "Good for a shamble about town.", - "durability": null, - "name": "Zombie trousers", - "archery_ticket_price": "0", "id": "7593", + "name": "Zombie trousers", + "examine": "Good for a shamble about town.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "7" }, { - "remove_head": "true", - "examine": "I look 40,000 years old in this...", - "durability": null, - "name": "Zombie mask", - "archery_ticket_price": "0", "id": "7594", + "name": "Zombie mask", + "examine": "I look 40,000 years old in this...", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true" }, { - "examine": "Smells pretty funky.", - "durability": null, - "name": "Zombie gloves", - "archery_ticket_price": "0", "id": "7595", + "name": "Zombie gloves", + "examine": "Smells pretty funky.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "9" }, { - "shop_price": "160", - "examine": "Thrilling.", - "durability": null, - "name": "Zombie boots", - "archery_ticket_price": "0", "id": "7596", - "equipment_slot": "10" - }, - { - "durability": null, - "name": "Item", - "tradeable": "true", + "name": "Zombie boots", + "examine": "Thrilling.", "archery_ticket_price": "0", - "id": "7597" + "durability": null, + "equipment_slot": "10", + "shop_price": "160" }, { - "durability": null, + "id": "7597", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7598" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7598", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7599" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7599", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7600" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7600", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7601" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7601", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7602" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7602", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7603" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7603", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7604" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7604", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7605" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7605", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7606" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7606", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7607" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7607", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7608" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7608", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7609" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7609", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7610" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7610", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7611" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7611", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7612" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7612", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7613" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7613", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7614" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7614", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7615" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7615", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7616" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7616", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7617" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "7617", "name": "Item", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7618" + "durability": null, + "tradeable": "true" }, { - "examine": "A silvery rod of mithril and silver with sapphire on top.", + "id": "7618", + "name": "Item", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "7620", "name": "Silvthrill rod", + "examine": "A silvery rod of mithril and silver with sapphire on top.", "archery_ticket_price": "0", - "id": "7620" + "durability": null }, { - "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", - "durability": null, + "id": "7622", "name": "Bucket of rubble", - "weight": "2", - "archery_ticket_price": "0", - "id": "7622" - }, - { "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", - "durability": null, - "name": "Bucket of rubble", - "weight": "2", "archery_ticket_price": "0", - "id": "7624" + "durability": null, + "weight": "2" }, { + "id": "7624", + "name": "Bucket of rubble", "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", - "durability": null, - "name": "Bucket of rubble", - "weight": "2", "archery_ticket_price": "0", - "id": "7626" + "durability": null, + "weight": "2" }, { - "destroy_message": "You can get another plaster fragment by exploring near the Inn in Burgh de Rott.", - "examine": "A fragment of plaster with some impressions on it.", + "id": "7626", + "name": "Bucket of rubble", + "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", + "archery_ticket_price": "0", "durability": null, + "weight": "2" + }, + { + "id": "7628", "name": "Plaster fragment", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A fragment of plaster with some impressions on it.", "archery_ticket_price": "0", - "id": "7628" + "destroy": "true", + "destroy_message": "You can get another plaster fragment by exploring near the Inn in Burgh de Rott.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "You can get another scroll by exploring near the Inn in Burgh de Rott.", - "examine": "An ancient tattered scroll.", - "durability": null, + "id": "7629", "name": "Dusty scroll", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient tattered scroll.", "archery_ticket_price": "0", - "id": "7629" + "destroy": "true", + "destroy_message": "You can get another scroll by exploring near the Inn in Burgh de Rott.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another temple key by talking to Drezel.", - "examine": "A key for the Temple Library. (In Aid of the Myreque)", - "durability": null, + "id": "7632", "name": "Temple library key", - "tradeable": "false", - "destroy": "true", + "examine": "A key for the Temple Library. (In Aid of the Myreque)", "archery_ticket_price": "0", - "id": "7632" + "destroy": "true", + "destroy_message": "You can get another temple key by talking to Drezel.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another Ancient Book by searching the library in the temple on the Salve.", - "shop_price": "5000", - "examine": "The unholy book of a forgotten god.", - "durability": null, - "name": "Ancient book", - "weight": "1", - "archery_ticket_price": "0", "id": "7633", - "bonuses": "4,4,4,6,0,4,4,4,6,0,2,0,0,5,0" + "name": "Ancient book", + "examine": "The unholy book of a forgotten god.", + "archery_ticket_price": "0", + "bonuses": "4,4,4,6,0,4,4,4,6,0,2,0,0,5,0", + "destroy_message": "You can get another Ancient Book by searching the library in the temple on the Salve.", + "durability": null, + "shop_price": "5000", + "weight": "1" }, { - "destroy_message": "You can get another Crumbling tome by searching the library in the temple on the Salve.", - "examine": "An ancient history book.", - "durability": null, + "id": "7634", "name": "Battered tome", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient history book.", "archery_ticket_price": "0", - "id": "7634" + "destroy": "true", + "destroy_message": "You can get another Crumbling tome by searching the library in the temple on the Salve.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another Leather book by searching the library in the temple on the Salve.", - "examine": "An ancient leather-bound tome.", - "durability": null, + "id": "7635", "name": "Leather book", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient leather-bound tome.", "archery_ticket_price": "0", - "id": "7635" + "destroy": "true", + "destroy_message": "You can get another Leather book by searching the library in the temple on the Salve.", + "durability": null, + "tradeable": "false" }, { - "examine": "Rod of Ivandis dust.", - "durability": null, + "id": "7636", "name": "Rod dust", + "examine": "Rod of Ivandis dust.", "archery_ticket_price": "0", - "id": "7636" + "durability": null }, { - "examine": "A silvery rod of mithril and silver with sapphire on top.", - "durability": null, - "name": "Silvthrill rod", - "archery_ticket_price": "0", "id": "7637", - "equipment_slot": "3" - }, - { - "examine": "A silvery rod of mithril and silver with sapphire on top.", - "durability": null, "name": "Silvthrill rod", + "examine": "A silvery rod of mithril and silver with sapphire on top.", "archery_ticket_price": "0", - "id": "7638" - }, - { - "turn90cw_anim": "1207", - "examine": "A fully charged rod.", - "walk_anim": "1205", - "has_special": "true", "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(10)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7639", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(9)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7640", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "destroy": "true", - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(8)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7641", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(7)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7642", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(6)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7643", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(5)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7644", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(4)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7645", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(3)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7646", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "2! 2 charges left! Ha Ha Ha.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(2)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7647", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "A partialy charged rod.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "name": "Rod of ivandis(1)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7648", - "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" - }, - { - "destroy_message": "You can make another one of these by using clay on Ivandis' coffin.", - "examine": "A mould of the Rod of Ivandis.", - "durability": null, - "name": "Rod clay mould", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7649" - }, - { - "ge_buy_limit": "1000", - "examine": "It's ground up silver.", - "grand_exchange_price": "316", - "durability": null, - "name": "Silver dust", - "tradeable": "true", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "7650" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "316", - "durability": null, - "name": "Silver dust", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7651" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "96", - "examine": "An unfinished potion.", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7652" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "96", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7653" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "77", - "examine": "An unfinished potion.", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7654" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "77", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7655" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "58", - "examine": "An unfinished potion.", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7656" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "58", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7657" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "30", - "examine": "An unfinished potion.", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7658" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "30", - "durability": null, - "name": "Guthix balance(unf)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7659" - }, - { - "ge_buy_limit": "1000", - "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", - "grand_exchange_price": "140", - "durability": null, - "name": "Guthix balance(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7660" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "140", - "durability": null, - "name": "Guthix balance(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7661" - }, - { - "ge_buy_limit": "1000", - "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", - "grand_exchange_price": "168", - "durability": null, - "name": "Guthix balance(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7662" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "168", - "durability": null, - "name": "Guthix balance(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7663" - }, - { - "ge_buy_limit": "1000", - "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", - "grand_exchange_price": "132", - "durability": null, - "name": "Guthix balance(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7664" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "132", - "durability": null, - "name": "Guthix balance(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7665" - }, - { - "ge_buy_limit": "1000", - "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", - "grand_exchange_price": "66", - "durability": null, - "name": "Guthix balance(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7666" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "66", - "durability": null, - "name": "Guthix balance(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7667" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1663", - "examine": "A specially crafted hammer with strange markings on it.", - "walk_anim": "1663", - "turn90ccw_anim": "1663", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1663", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "1615", - "stand_anim": "1662", - "tradeable": "true", - "run_anim": "1664", - "archery_ticket_price": "0", - "id": "7668", - "stand_turn_anim": "823", - "bonuses": "-4,-4,35,-4,0,0,0,0,0,0,0,35,0,0,0", - "shop_price": "3000", - "durability": null, - "weight": "1.8", - "weapon_interface": "10", - "render_anim": "27", - "name": "Gadderhammer" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1615", - "durability": null, - "name": "Gadderhammer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7669" - }, - { - "turn90cw_anim": "3680", - "examine": "I think they look a bit silly.", - "walk_anim": "3680", - "durability": null, - "weight": "0.4", - "turn90ccw_anim": "3680", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "turn180_anim": "3680", - "render_anim": "1386", - "equipment_slot": "3", - "stand_anim": "3677", - "name": "Boxing gloves", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7671", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" - }, - { - "turn90cw_anim": "3680", - "examine": "I think they look a bit silly.", - "walk_anim": "3680", - "durability": null, - "weight": "0.4", - "turn90ccw_anim": "3680", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "turn180_anim": "3680", - "render_anim": "1386", - "equipment_slot": "3", - "stand_anim": "3677", - "name": "Boxing gloves", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "7673", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" - }, - { - "examine": "A less-than razor sharp sword.", - "durability": null, - "name": "Wooden sword", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "7675", - "weapon_interface": "5", - "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", - "render_anim": "2584", "equipment_slot": "3" }, { + "id": "7638", + "name": "Silvthrill rod", + "examine": "A silvery rod of mithril and silver with sapphire on top.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7639", + "name": "Rod of ivandis(10)", + "examine": "A fully charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7640", + "name": "Rod of ivandis(9)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7641", + "name": "Rod of ivandis(8)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "destroy": "true", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "7642", + "name": "Rod of ivandis(7)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7643", + "name": "Rod of ivandis(6)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7644", + "name": "Rod of ivandis(5)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7645", + "name": "Rod of ivandis(4)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7646", + "name": "Rod of ivandis(3)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7647", + "name": "Rod of ivandis(2)", + "examine": "2! 2 charges left! Ha Ha Ha.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7648", + "name": "Rod of ivandis(1)", + "examine": "A partialy charged rod.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "false", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "7649", + "name": "Rod clay mould", + "examine": "A mould of the Rod of Ivandis.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can make another one of these by using clay on Ivandis' coffin.", + "durability": null + }, + { + "id": "7650", + "name": "Silver dust", + "examine": "It's ground up silver.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.33" + }, + { + "id": "7651", + "name": "Silver dust", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7652", + "name": "Guthix balance(unf)", + "examine": "An unfinished potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7653", + "name": "Guthix balance(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7654", + "name": "Guthix balance(unf)", + "examine": "An unfinished potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7655", + "name": "Guthix balance(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7656", + "name": "Guthix balance(unf)", + "examine": "An unfinished potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7657", + "name": "Guthix balance(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7658", + "name": "Guthix balance(unf)", + "examine": "An unfinished potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7659", + "name": "Guthix balance(unf)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7660", + "name": "Guthix balance(4)", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7661", + "name": "Guthix balance(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7662", + "name": "Guthix balance(3)", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7663", + "name": "Guthix balance(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7664", + "name": "Guthix balance(2)", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7665", + "name": "Guthix balance(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7666", + "name": "Guthix balance(1)", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7667", + "name": "Guthix balance(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "7668", + "name": "Gadderhammer", + "examine": "A specially crafted hammer with strange markings on it.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_speed": "5", + "bonuses": "-4,-4,35,-4,0,0,0,0,0,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "27", + "run_anim": "1664", + "shop_price": "3000", + "stand_anim": "1662", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1663", + "turn90ccw_anim": "1663", + "turn90cw_anim": "1663", + "two_handed": "true", + "walk_anim": "1663", + "weapon_interface": "10", + "weight": "1.8" + }, + { + "id": "7669", + "name": "Gadderhammer", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7671", + "name": "Boxing gloves", + "examine": "I think they look a bit silly.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "1386", + "run_anim": "824", + "stand_anim": "3677", + "stand_turn_anim": "823", + "turn180_anim": "3680", + "turn90ccw_anim": "3680", + "turn90cw_anim": "3680", + "two_handed": "true", + "walk_anim": "3680", + "weapon_interface": "9", + "weight": "0.4" + }, + { + "id": "7673", + "name": "Boxing gloves", + "examine": "I think they look a bit silly.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "1386", + "run_anim": "824", + "stand_anim": "3677", + "stand_turn_anim": "823", + "turn180_anim": "3680", + "turn90ccw_anim": "3680", + "turn90cw_anim": "3680", + "two_handed": "true", + "walk_anim": "3680", + "weapon_interface": "9", + "weight": "0.4" + }, + { + "id": "7675", + "name": "Wooden sword", + "examine": "A less-than razor sharp sword.", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "7676", "name": "Wooden shield", "archery_ticket_price": "0", - "id": "7676", + "durability": null, + "equip_audio": "2250", "equipment_slot": "5" }, { - "examine": "It knows where the treasure is.", - "durability": null, + "id": "7677", "name": "Treasure stone", - "weight": "1.8", + "examine": "It knows where the treasure is.", "archery_ticket_price": "0", - "id": "7677" + "durability": null, + "weight": "1.8" }, { - "shop_price": "160", - "examine": "You can use this to open the prize chest!", - "durability": null, + "id": "7678", "name": "Prize key", - "weight": "1", + "examine": "You can use this to open the prize chest!", "archery_ticket_price": "0", - "id": "7678" + "durability": null, + "shop_price": "160", + "weight": "1" }, { - "examine": "A good tool for bashing someone.", - "durability": null, - "name": "Pugel", - "archery_ticket_price": "0", - "two_handed": "true", "id": "7679", - "weapon_interface": "14", - "equipment_slot": "3" - }, - { - "durability": null, "name": "Pugel", - "tradeable": "true", + "examine": "A good tool for bashing someone.", "archery_ticket_price": "0", - "id": "7680" - }, - { - "examine": "Party Pete's Bumper Book Of Games", "durability": null, - "name": "Game book", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7681" - }, - { - "durability": null, - "name": "Hoop", - "archery_ticket_price": "0", - "id": "7682", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Hoop", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7683" - }, - { - "durability": null, - "name": "Dart", - "archery_ticket_price": "0", - "attack_speed": "3", - "id": "7684", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7685" - }, - { - "durability": null, - "name": "Bow and arrow", - "archery_ticket_price": "0", - "id": "7686", - "weapon_interface": "1", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Bow and arrow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7687" - }, - { - "examine": "The kettle is empty.", - "durability": null, - "name": "Kettle", - "archery_ticket_price": "0", - "id": "7688" - }, - { - "durability": null, - "name": "Kettle", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7689" - }, - { - "examine": "It's full of cold water.", - "durability": null, - "name": "Full kettle", - "archery_ticket_price": "0", - "id": "7690" - }, - { - "examine": "It's full of boiling water.", - "durability": null, - "name": "Hot kettle", - "archery_ticket_price": "0", - "id": "7691" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (4)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7692" - }, - { - "durability": null, - "name": "Pot of tea (4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7693" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (3)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7694" - }, - { - "durability": null, - "name": "Pot of tea (3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7695" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (2)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7696" - }, - { - "durability": null, - "name": "Pot of tea (2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7697" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (1)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7698" - }, - { - "durability": null, - "name": "Pot of tea (1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7699" - }, - { - "examine": "Add boiling water to make a tea.", - "durability": null, - "name": "Teapot with leaves", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7700" - }, - { - "durability": null, - "name": "Teapot with leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7701" - }, - { - "examine": "This teapot is empty.", - "durability": null, - "name": "Teapot", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "7702" - }, - { - "durability": null, - "name": "Teapot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7703" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (4)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7704" - }, - { - "durability": null, - "name": "Pot of tea (4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7705" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (3)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7706" - }, - { - "durability": null, - "name": "Pot of tea (3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7707" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (2)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7708" - }, - { - "durability": null, - "name": "Pot of tea (2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7709" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (1)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7710" - }, - { - "durability": null, - "name": "Pot of tea (1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7711" - }, - { - "examine": "Add boiling water to make a tea.", - "durability": null, - "name": "Teapot with leaves", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7712" - }, - { - "durability": null, - "name": "Teapot with leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7713" - }, - { - "examine": "This teapot is empty.", - "durability": null, - "name": "Teapot", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "7714" - }, - { - "durability": null, - "name": "Teapot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7715" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (4)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7716" - }, - { - "durability": null, - "name": "Pot of tea (4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7717" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (3)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7718" - }, - { - "durability": null, - "name": "Pot of tea (3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7719" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (2)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7720" - }, - { - "durability": null, - "name": "Pot of tea (2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7721" - }, - { - "examine": "I'd really like a nice cup of tea.", - "durability": null, - "name": "Pot of tea (1)", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7722" - }, - { - "durability": null, - "name": "Pot of tea (1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7723" - }, - { - "examine": "Add boiling water to make a tea.", - "durability": null, - "name": "Teapot with leaves", - "tradeable": "true", - "weight": "1.5", - "archery_ticket_price": "0", - "id": "7724" - }, - { - "durability": null, - "name": "Teapot with leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7725" - }, - { - "examine": "This teapot is empty.", - "durability": null, - "name": "Teapot", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "7726" - }, - { - "durability": null, - "name": "Teapot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7727" - }, - { - "shop_price": "1", - "examine": "An empty cup.", - "grand_exchange_price": "7", - "durability": null, - "name": "Empty cup", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7728" - }, - { - "durability": null, - "name": "Empty cup", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7729" - }, - { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7730" - }, - { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7731" - }, - { - "examine": "A porcelain cup.", - "durability": null, - "name": "Porcelain cup", - "archery_ticket_price": "0", - "id": "7732" - }, - { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7733" - }, - { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7734" - }, - { - "examine": "A porcelain cup.", - "durability": null, - "name": "Porcelain cup", - "archery_ticket_price": "0", - "id": "7735" - }, - { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7736" - }, - { - "shop_price": "10", - "examine": "A nice cup of tea.", - "grand_exchange_price": "30", - "durability": null, - "name": "Cup of tea", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "7737" - }, - { - "examine": "Mmm, how about a nice cup of tea?", - "durability": null, - "name": "Tea leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7738" - }, - { - "durability": null, - "name": "Tea leaves", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7739" - }, - { - "examine": "A glass of frothy ale.", - "grand_exchange_price": "151", - "durability": null, - "name": "Beer", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7740" - }, - { - "durability": null, - "name": "Beer", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7741" - }, - { - "shop_price": "1", - "examine": "I need to fill this with beer.", - "grand_exchange_price": "25", - "durability": null, - "name": "Beer glass", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "7742" - }, - { - "durability": null, - "name": "Beer glass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7743" - }, - { - "shop_price": "3", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "131", - "durability": null, - "name": "Asgarnian ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7744" - }, - { - "durability": null, - "name": "Asgarnian ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7745" - }, - { - "shop_price": "2", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "569", - "durability": null, - "name": "Greenman's ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7746" - }, - { - "durability": null, - "name": "Greenman's ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7747" - }, - { - "shop_price": "2", - "examine": "A glass of bitter.", - "grand_exchange_price": "523", - "durability": null, - "name": "Dragon bitter", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7748" - }, - { - "durability": null, - "name": "Dragon bitter", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7749" - }, - { - "shop_price": "5", - "examine": "A foul smelling brew.", - "grand_exchange_price": "14", - "durability": null, - "name": "Moonlight mead", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7750" - }, - { - "durability": null, - "name": "Moonlight mead", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7751" - }, - { - "shop_price": "2", - "examine": "A glass of Cider", - "grand_exchange_price": "1539", - "durability": null, - "name": "Cider", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7752" - }, - { - "durability": null, - "name": "Cider", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7753" - }, - { - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "2371", - "durability": null, - "name": "Chef's delight", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7754" - }, - { - "durability": null, - "name": "Chef's delight", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7755" - }, - { - "durability": null, - "name": "Paintbrush", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7756", - "equipment_slot": "3" - }, - { - "durability": null, - "name": "Paintbrush", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7757" - }, - { - "examine": "A decent-enough weapon gone rusty.", - "durability": null, - "name": "Rusty sword", - "weight": "2", - "archery_ticket_price": "0", - "id": "7758", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "100", - "examine": "Nice bit of crafting.", - "grand_exchange_price": "3140", - "durability": null, - "name": "Toy soldier", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7759" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3140", - "durability": null, - "name": "Toy soldier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7760" - }, - { - "examine": "Nice bit of crafting.", - "grand_exchange_price": "3123", - "durability": null, - "name": "Toy soldier (wound)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7761" - }, - { - "durability": null, - "name": "Toy soldier (wound)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7762" - }, - { - "ge_buy_limit": "100", - "examine": "In inventory: Nice bit of crafting! When released: Nice bit of crafting that...", - "grand_exchange_price": "3236", - "durability": null, - "name": "Toy doll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7763" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3236", - "durability": null, - "name": "Toy doll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7764" - }, - { - "examine": "In inventory: Nice bit of crafting! When released: Nice bit of crafting that...", - "grand_exchange_price": "3289", - "durability": null, - "name": "Toy doll (wound)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7765" - }, - { - "durability": null, - "name": "Toy doll (wound)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7766" - }, - { - "shop_price": "1705", - "ge_buy_limit": "100", - "examine": "Nice bit of crafting!", - "grand_exchange_price": "3384", - "durability": null, - "name": "Toy mouse", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7767" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3384", - "durability": null, - "name": "Toy mouse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7768" - }, - { - "shop_price": "1705", - "examine": "Nice bit of crafting!", - "grand_exchange_price": "3484", - "durability": null, - "name": "Toy mouse (wound)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7769" - }, - { - "durability": null, - "name": "Toy mouse (wound)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7770" - }, - { - "ge_buy_limit": "100", - "examine": "Inventory: Nice bit of crafting!As a follower: An amazing piece of crafting.", - "grand_exchange_price": "2930", - "durability": null, - "name": "Clockwork cat", - "tradeable": "true", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7771" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2930", - "durability": null, - "name": "Clockwork cat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7772" - }, - { - "examine": "I can use this to make a lyre.", - "durability": null, - "name": "Branch", - "weight": "1", - "archery_ticket_price": "0", - "id": "7773", - "equipment_slot": "3" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7774" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7775" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "7776" - }, - { - "examine": "A long section of vine made up of lots of shorter sections.", - "durability": null, - "name": "Long vine", - "archery_ticket_price": "0", - "id": "7777" - }, - { - "examine": "A short section of vines.", - "durability": null, - "name": "Short vine", - "archery_ticket_price": "0", - "id": "7778" - }, - { - "examine": "A tome of learning that focuses on the Fishing skill.", - "durability": null, - "name": "Fishing tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7779" - }, - { - "examine": "A tome of learning that focuses on the Fishing skill.", - "durability": null, - "name": "Fishing tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7780" - }, - { - "examine": "A tome of learning that focuses on the Fishing skill.", - "durability": null, - "name": "Fishing tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7781" - }, - { - "examine": "A tome of learning that focuses on Agility.", - "durability": null, - "name": "Agility tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7782" - }, - { - "examine": "A tome of learning that focuses on Agility.", - "durability": null, - "name": "Agility tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7783" - }, - { - "examine": "A tome of learning that focuses on Agility.", - "durability": null, - "name": "Agility tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7784" - }, - { - "examine": "A tome of learning that focuses on the Thieving skill.", - "durability": null, - "name": "Thieving tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7785" - }, - { - "examine": "A tome of learning that focuses on the Thieving skill.", - "durability": null, - "name": "Thieving tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7786" - }, - { - "examine": "A tome of learning that focuses on the Thieving skill.", - "durability": null, - "name": "Thieving tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7787" - }, - { - "examine": "A tome of learning which focuses on the Slayer skill.", - "durability": null, - "name": "Slayer tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7788" - }, - { - "examine": "A tome of learning which focuses on the Slayer skill.", - "durability": null, - "name": "Slayer tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7789" - }, - { - "examine": "A tome of learning which focuses on the Slayer skill.", - "durability": null, - "name": "Slayer tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7790" - }, - { - "shop_price": "160", - "examine": "A tome of learning that focuses on the Mining skill.", - "durability": null, - "name": "Mining tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7791" - }, - { - "shop_price": "160", - "examine": "A tome of learning that focuses on the Mining skill.", - "durability": null, - "name": "Mining tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7792" - }, - { - "shop_price": "160", - "examine": "A tome of learning that focuses on the Mining skill.", - "durability": null, - "name": "Mining tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7793" - }, - { - "examine": "A tome of learning that focuses on Firemaking.", - "durability": null, - "name": "Firemaking tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7794" - }, - { - "examine": "A tome of learning that focuses on Firemaking.", - "durability": null, - "name": "Firemaking tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7795" - }, - { - "examine": "A tome of learning that focuses on Firemaking.", - "durability": null, - "name": "Firemaking tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7796" - }, - { - "shop_price": "160", - "examine": "A tome of learning that focuses on the Woodcutting skill.", - "durability": null, - "name": "Woodcutting tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7797" - }, - { - "shop_price": "160", - "examine": "A tome of learning that focuses on the Woodcutting skill.", - "durability": null, - "name": "Woodcutting tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7798" - }, - { - "shop_price": "160", - "examine": "A tome of learning that focuses on the Woodcutting skill.", - "durability": null, - "name": "Woodcutting tome", - "weight": "1", - "archery_ticket_price": "0", - "id": "7799" - }, - { - "examine": "A shell from a giant snail.", - "durability": null, - "name": "Snail shell", - "weight": "7", - "archery_ticket_price": "0", - "id": "7800" - }, - { - "ge_buy_limit": "10000", - "examine": "Scaly but not slimy!", - "grand_exchange_price": "1618", - "durability": null, - "name": "Snake hide", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "7801" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1618", - "durability": null, - "name": "Snake hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7802" - }, - { - "shop_price": "100", - "examine": "A non-magical copy of the make-over mage's amulet.", - "durability": null, - "name": "Yin yang amulet", - "archery_ticket_price": "0", - "id": "7803", - "equipment_slot": "2" - }, - { - "turn90cw_anim": "1207", - "walk_anim": "1205", - "durability": null, - "turn90ccw_anim": "1208", - "two_handed": "true", - "weapon_interface": "3", - "turn180_anim": "1206", - "render_anim": "28", "equipment_slot": "3", - "stand_anim": "813", - "name": "Picture", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "7804", - "stand_turn_anim": "1209", - "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0" + "two_handed": "true", + "weapon_interface": "14" }, { + "id": "7680", + "name": "Pugel", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7681", + "name": "Game book", + "examine": "Party Pete's Bumper Book Of Games", + "archery_ticket_price": "0", "durability": null, - "name": "Picture", "tradeable": "true", - "archery_ticket_price": "0", - "id": "7805" + "weight": "1" }, { - "attack_anims": "381,390,390,390", - "examine": "A heavy duty sword.", + "id": "7682", + "name": "Hoop", + "archery_ticket_price": "0", "durability": null, - "name": "Anger sword", + "equipment_slot": "3" + }, + { + "id": "7683", + "name": "Hoop", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7684", + "name": "Dart", "archery_ticket_price": "0", "attack_speed": "3", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3" + }, + { + "id": "7685", + "name": "Dart", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7686", + "name": "Bow and arrow", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weapon_interface": "1" + }, + { + "id": "7687", + "name": "Bow and arrow", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7688", + "name": "Kettle", + "examine": "The kettle is empty.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7689", + "name": "Kettle", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7690", + "name": "Full kettle", + "examine": "It's full of cold water.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7691", + "name": "Hot kettle", + "examine": "It's full of boiling water.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7692", + "name": "Pot of tea (4)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7693", + "name": "Pot of tea (4)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7694", + "name": "Pot of tea (3)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7695", + "name": "Pot of tea (3)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7696", + "name": "Pot of tea (2)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7697", + "name": "Pot of tea (2)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7698", + "name": "Pot of tea (1)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7699", + "name": "Pot of tea (1)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7700", + "name": "Teapot with leaves", + "examine": "Add boiling water to make a tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7701", + "name": "Teapot with leaves", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7702", + "name": "Teapot", + "examine": "This teapot is empty.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "7703", + "name": "Teapot", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7704", + "name": "Pot of tea (4)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7705", + "name": "Pot of tea (4)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7706", + "name": "Pot of tea (3)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7707", + "name": "Pot of tea (3)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7708", + "name": "Pot of tea (2)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7709", + "name": "Pot of tea (2)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7710", + "name": "Pot of tea (1)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7711", + "name": "Pot of tea (1)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7712", + "name": "Teapot with leaves", + "examine": "Add boiling water to make a tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7713", + "name": "Teapot with leaves", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7714", + "name": "Teapot", + "examine": "This teapot is empty.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "7715", + "name": "Teapot", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7716", + "name": "Pot of tea (4)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7717", + "name": "Pot of tea (4)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7718", + "name": "Pot of tea (3)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7719", + "name": "Pot of tea (3)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7720", + "name": "Pot of tea (2)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7721", + "name": "Pot of tea (2)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7722", + "name": "Pot of tea (1)", + "examine": "I'd really like a nice cup of tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7723", + "name": "Pot of tea (1)", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7724", + "name": "Teapot with leaves", + "examine": "Add boiling water to make a tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1.5" + }, + { + "id": "7725", + "name": "Teapot with leaves", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7726", + "name": "Teapot", + "examine": "This teapot is empty.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "7727", + "name": "Teapot", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7728", + "name": "Empty cup", + "examine": "An empty cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "1", + "tradeable": "false" + }, + { + "id": "7729", + "name": "Empty cup", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7730", + "name": "Cup of tea", + "examine": "A nice cup of nettle tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "7731", + "name": "Cup of tea", + "examine": "A milky cup of nettle tea.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "7732", + "name": "Porcelain cup", + "examine": "A porcelain cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7733", + "name": "Cup of tea", + "examine": "Some nettle tea in a porcelain cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "7734", + "name": "Cup of tea", + "examine": "Some milky nettle tea in a porcelain cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "7735", + "name": "Porcelain cup", + "examine": "A porcelain cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7736", + "name": "Cup of tea", + "examine": "Some nettle tea in a porcelain cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "7737", + "name": "Cup of tea", + "examine": "Some milky nettle tea in a porcelain cup.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "10", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "7738", + "name": "Tea leaves", + "examine": "Mmm, how about a nice cup of tea?", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7739", + "name": "Tea leaves", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7740", + "name": "Beer", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "7741", + "name": "Beer", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7742", + "name": "Beer glass", + "examine": "I need to fill this with beer.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "1", + "tradeable": "false", + "weight": "0.05" + }, + { + "id": "7743", + "name": "Beer glass", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7744", + "name": "Asgarnian ale", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "3", + "tradeable": "false" + }, + { + "id": "7745", + "name": "Asgarnian ale", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7746", + "name": "Greenman's ale", + "examine": "A glass of frothy ale.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "2", + "tradeable": "false" + }, + { + "id": "7747", + "name": "Greenman's ale", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7748", + "name": "Dragon bitter", + "examine": "A glass of bitter.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "2", + "tradeable": "false", + "weight": "1" + }, + { + "id": "7749", + "name": "Dragon bitter", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7750", + "name": "Moonlight mead", + "examine": "A foul smelling brew.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "7751", + "name": "Moonlight mead", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7752", + "name": "Cider", + "examine": "A glass of Cider", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "shop_price": "2", + "tradeable": "false", + "weight": "1" + }, + { + "id": "7753", + "name": "Cider", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7754", + "name": "Chef's delight", + "examine": "A fruity, full-bodied ale.", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7755", + "name": "Chef's delight", + "archery_ticket_price": "0", + "bankable": "false", + "durability": null, + "tradeable": "false" + }, + { + "id": "7756", + "name": "Paintbrush", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true" + }, + { + "id": "7757", + "name": "Paintbrush", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7758", + "name": "Rusty sword", + "examine": "A decent-enough weapon gone rusty.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "2" + }, + { + "id": "7759", + "name": "Toy soldier", + "examine": "Nice bit of crafting.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7760", + "name": "Toy soldier", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7761", + "name": "Toy soldier (wound)", + "examine": "Nice bit of crafting.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "true" + }, + { + "id": "7762", + "name": "Toy soldier (wound)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7763", + "name": "Toy doll", + "examine": "Nice bit of crafting!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7764", + "name": "Toy doll", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7765", + "name": "Toy doll (wound)", + "examine": "Nice bit of crafting!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7766", + "name": "Toy doll (wound)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7767", + "name": "Toy mouse", + "examine": "Nice bit of crafting!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1705", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7768", + "name": "Toy mouse", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7769", + "name": "Toy mouse (wound)", + "examine": "Nice bit of crafting!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "1705", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7770", + "name": "Toy mouse (wound)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7771", + "name": "Clockwork cat", + "examine": "Inventory: Nice bit of crafting!As a follower: An amazing piece of crafting.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7772", + "name": "Clockwork cat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7773", + "name": "Branch", + "examine": "I can use this to make a lyre.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1" + }, + { + "id": "7774", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "7775", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "7776", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "7777", + "name": "Long vine", + "examine": "A long section of vine made up of lots of shorter sections.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7778", + "name": "Short vine", + "examine": "A short section of vines.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7779", + "name": "Fishing tome", + "examine": "A tome of learning that focuses on the Fishing skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7780", + "name": "Fishing tome", + "examine": "A tome of learning that focuses on the Fishing skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7781", + "name": "Fishing tome", + "examine": "A tome of learning that focuses on the Fishing skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7782", + "name": "Agility tome", + "examine": "A tome of learning that focuses on Agility.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7783", + "name": "Agility tome", + "examine": "A tome of learning that focuses on Agility.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7784", + "name": "Agility tome", + "examine": "A tome of learning that focuses on Agility.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7785", + "name": "Thieving tome", + "examine": "A tome of learning that focuses on the Thieving skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7786", + "name": "Thieving tome", + "examine": "A tome of learning that focuses on the Thieving skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7787", + "name": "Thieving tome", + "examine": "A tome of learning that focuses on the Thieving skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7788", + "name": "Slayer tome", + "examine": "A tome of learning which focuses on the Slayer skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7789", + "name": "Slayer tome", + "examine": "A tome of learning which focuses on the Slayer skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7790", + "name": "Slayer tome", + "examine": "A tome of learning which focuses on the Slayer skill.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7791", + "name": "Mining tome", + "examine": "A tome of learning that focuses on the Mining skill.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "1" + }, + { + "id": "7792", + "name": "Mining tome", + "examine": "A tome of learning that focuses on the Mining skill.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "1" + }, + { + "id": "7793", + "name": "Mining tome", + "examine": "A tome of learning that focuses on the Mining skill.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "1" + }, + { + "id": "7794", + "name": "Firemaking tome", + "examine": "A tome of learning that focuses on Firemaking.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7795", + "name": "Firemaking tome", + "examine": "A tome of learning that focuses on Firemaking.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7796", + "name": "Firemaking tome", + "examine": "A tome of learning that focuses on Firemaking.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7797", + "name": "Woodcutting tome", + "examine": "A tome of learning that focuses on the Woodcutting skill.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "1" + }, + { + "id": "7798", + "name": "Woodcutting tome", + "examine": "A tome of learning that focuses on the Woodcutting skill.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "1" + }, + { + "id": "7799", + "name": "Woodcutting tome", + "examine": "A tome of learning that focuses on the Woodcutting skill.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "1" + }, + { + "id": "7800", + "name": "Snail shell", + "examine": "A shell from a giant snail.", + "archery_ticket_price": "0", + "durability": null, + "weight": "7" + }, + { + "id": "7801", + "name": "Snake hide", + "examine": "Scaly but not slimy!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "7802", + "name": "Snake hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "7803", + "name": "Yin yang amulet", + "examine": "A non-magical copy of the make-over mage's amulet.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "shop_price": "100" + }, + { + "id": "7804", + "name": "Picture", + "archery_ticket_price": "0", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3" + }, + { + "id": "7805", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "7806", - "weapon_interface": "5", + "name": "Anger sword", + "examine": "A heavy duty sword.", + "archery_ticket_price": "0", + "attack_anims": "381,390,390,390", + "attack_speed": "3", "bonuses": "20,20,20,0,0,0,2,1,0,0,0,5,0,0,0", "defence_anim": "397", - "equipment_slot": "3" + "durability": null, + "equipment_slot": "3", + "weapon_interface": "5" }, { - "attack_anims": "395,395,401,395", - "examine": "A heavy duty axe.", - "durability": null, - "attack_audios": "2498,2498,2497,2498", - "name": "Anger battleaxe", - "archery_ticket_price": "0", "id": "7807", - "weapon_interface": "2", + "name": "Anger battleaxe", + "examine": "A heavy duty axe.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", "bonuses": "20,20,20,0,0,0,0,0,0,-1,0,13,0,0,0", "defence_anim": "397", - "equipment_slot": "3" + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "weapon_interface": "2" }, { - "attack_anims": "390,390,381,390", - "examine": "A heavy duty mace.", - "durability": null, - "name": "Anger mace", - "archery_ticket_price": "0", "id": "7808", - "weapon_interface": "8", + "name": "Anger mace", + "examine": "A heavy duty mace.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", "bonuses": "20,20,20,0,0,0,0,0,0,0,0,5,1,0,0", "defence_anim": "397", - "equipment_slot": "3" - }, - { - "turn90cw_anim": "1207", - "examine": "A heavy duty spear.", - "walk_anim": "1205", "durability": null, - "turn90ccw_anim": "1208", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "defence_anim": "2079", "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "stand_anim": "813", - "name": "Anger spear", - "run_anim": "1210", - "archery_ticket_price": "0", + "weapon_interface": "8" + }, + { "id": "7809", + "name": "Anger spear", + "examine": "A heavy duty spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "bonuses": "20,20,20,0,0,1,1,0,0,0,0,6,0,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "20,20,20,0,0,1,1,0,0,0,0,6,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14" }, { - "shop_price": "1", - "examine": "This wine clearly did not age well.", - "durability": null, + "id": "7810", "name": "Jug of vinegar", - "weight": "1", + "examine": "This wine clearly did not age well.", "archery_ticket_price": "0", - "id": "7810" - }, - { - "examine": "Well, this pot is certainly full of vinegar and no mistake.", "durability": null, - "name": "Pot of vinegar", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "7811" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Goblin skull", - "archery_ticket_price": "0", - "id": "7812" - }, - { - "examine": "There is a goblin bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7813" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Goblin skull", - "archery_ticket_price": "0", - "id": "7814" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Bear ribs", - "archery_ticket_price": "0", - "id": "7815" - }, - { - "examine": "There is a bear bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7816" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Bear ribs", - "archery_ticket_price": "0", - "id": "7817" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Ram skull", - "archery_ticket_price": "0", - "id": "7818" - }, - { - "examine": "There is a ram bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7819" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Ram skull", - "archery_ticket_price": "0", - "id": "7820" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Unicorn bone", - "archery_ticket_price": "0", - "id": "7821" - }, - { - "examine": "There is a unicorn bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7822" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Unicorn bone", - "archery_ticket_price": "0", - "id": "7823" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Giant rat bone", - "archery_ticket_price": "0", - "id": "7824" - }, - { - "examine": "There is a giant rat bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7825" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Giant rat bone", - "archery_ticket_price": "0", - "id": "7826" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Giant bat wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7827" - }, - { - "examine": "There is a giant bat bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7828" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Giant bat wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7829" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Wolf bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7830" - }, - { - "examine": "There is a wolf bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7831" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Wolf bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7832" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Bat wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7833" - }, - { - "examine": "There is a bat bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7834" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Bat wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7835" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Rat bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7836" - }, - { - "examine": "There is a rat bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7837" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Rat bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7838" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Baby dragon bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7839" - }, - { - "examine": "There is a baby blue dragon bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7840" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Baby dragon bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7841" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Ogre ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7842" - }, - { - "examine": "There is a ogre bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7843" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Ogre ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7844" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Jogre bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7845" - }, - { - "examine": "There is a jogre bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7846" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Jogre bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7847" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Zogre bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7848" - }, - { - "examine": "There is a zogre bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7849" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Zogre bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7850" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Mogre bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7851" - }, - { - "examine": "There is a mogre bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7852" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Mogre bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7853" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Monkey paw", - "archery_ticket_price": "0", - "id": "7854" - }, - { - "examine": "There is a monkey bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7855" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Monkey paw", - "archery_ticket_price": "0", - "id": "7856" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Dagannoth ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7857" - }, - { - "examine": "There is a Dagannoth bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7858" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Dagannoth ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7859" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Snake spine", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7860" - }, - { - "examine": "There is a snake bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7861" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Snake spine", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7862" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Zombie bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7863" - }, - { - "examine": "There is a zombie bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7864" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Zombie bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7865" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Werewolf bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7866" - }, - { - "examine": "There is a werewolf bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7867" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Werewolf bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7868" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Moss giant bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7869" - }, - { - "examine": "There is a moss giant bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7870" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Moss giant bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7871" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Fire giant bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7872" - }, - { - "examine": "There is a fire giant bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7873" - }, - { - "examine": "This bone belongs in a museum!", - "durability": null, - "name": "Fire giant bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7874" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Ice giant ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7875" - }, - { - "examine": "There is an ice giant bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7876" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Ice giant ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7877" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Terrorbird wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7878" - }, - { - "examine": "There is a terrorbird bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7879" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Terrorbird wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7880" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Ghoul bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7881" - }, - { - "examine": "There is a ghoul bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7882" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Ghoul bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7883" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Troll bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7884" - }, - { - "examine": "There is a troll bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7885" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Troll bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7886" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Seagull wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7887" - }, - { - "examine": "There is a seagull bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7888" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Seagull wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7889" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Undead cow ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7890" - }, - { - "examine": "There is an undead cow bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7891" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Undead cow ribs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7892" - }, - { - "shop_price": "160", - "examine": "This needs a good polish.", - "durability": null, - "name": "Experiment bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7893" - }, - { - "examine": "There is an experiment bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7894" - }, - { - "shop_price": "160", - "examine": "This belongs in a museum!", - "durability": null, - "name": "Experiment bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7895" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Rabbit bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7896" - }, - { - "examine": "There is a rabbit bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7897" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Rabbit bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7898" - }, - { - "examine": "This bone needs a good polish.", - "durability": null, - "name": "Basilisk bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7899" - }, - { - "examine": "There is a basilisk bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7900" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Basilisk bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7901" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Desert lizard bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7902" - }, - { - "examine": "There is a desert lizard bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7903" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Desert lizard bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7904" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Cave goblin skull", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7905" - }, - { - "examine": "There is a cave goblin bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7906" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Cave goblin skull", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7907" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Big frog leg", - "weight": "1", - "archery_ticket_price": "0", - "id": "7908" - }, - { - "examine": "There is a big frog bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7909" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Big frog leg", - "weight": "1", - "archery_ticket_price": "0", - "id": "7910" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Vulture wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7911" - }, - { - "examine": "There is a vulture bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7912" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Vulture wing", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7913" - }, - { - "examine": "This needs a good polish.", - "durability": null, - "name": "Jackal bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7914" - }, - { - "examine": "There is a jackal bone in here.", - "durability": null, - "name": "Bone in vinegar", - "weight": "1", - "archery_ticket_price": "0", - "id": "7915" - }, - { - "examine": "This belongs in a museum!", - "durability": null, - "name": "Jackal bone", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "7916" - }, - { - "destroy_message": "The ram skull helm looks like it will fall apart if you drop it. You would have to go to the Odd Old Man for a replacement.", - "examine": "Makes me feel baaad to the bone.", - "durability": null, - "name": "Ram skull helm", - "weight": "3", - "archery_ticket_price": "0", - "id": "7917", - "bonuses": "0,0,0,0,-2,19,21,16,0,19,6,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "The bonesack looks like it will fall apart if you drop it. You would have to go to the Odd Old Man for a replacement.", - "examine": "The Bonesack is a little old item that protects like leather.", - "durability": null, - "name": "Bonesack", - "weight": "9", - "archery_ticket_price": "0", - "id": "7918", - "bonuses": "0,0,0,0,0,4,4,4,4,4,4,0,0,0,0", - "equipment_slot": "1" - }, - { - "shop_price": "500", - "examine": "A very good vintage.", - "durability": null, - "name": "Bottle of wine", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "7919" - }, - { - "durability": null, - "name": "Bottle of wine", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7920" - }, - { - "examine": "This one has clearly been taken down and passed around.", - "durability": null, - "name": "Empty wine bottle", - "weight": "1", - "archery_ticket_price": "0", - "id": "7921" - }, - { - "examine": "The money off voucher has expired.", - "durability": null, - "name": "Al kharid flyer", - "archery_ticket_price": "0", - "id": "7922" - }, - { - "examine": "A ring given to you by the Easter Bunny.", - "durability": null, - "name": "Easter ring", - "archery_ticket_price": "0", - "id": "7927" - }, - { - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7928" - }, - { - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7929" - }, - { - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7930" - }, - { - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7931" - }, - { - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7932" - }, - { - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7933" - }, - { - "shop_price": "390", - "ge_buy_limit": "100", - "examine": "A field ration to help your wounds go away.", - "grand_exchange_price": "171", - "durability": null, - "name": "Field ration", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7934" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "171", - "durability": null, - "name": "Field ration", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7935" - }, - { "shop_price": "1", - "ge_buy_limit": "25000", - "examine": "An uncharged Rune Stone of extra capability.", - "grand_exchange_price": "180", - "durability": null, - "name": "Pure essence", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "7936" + "weight": "1" }, { - "ge_buy_limit": "25000", - "grand_exchange_price": "109", - "durability": null, - "name": "Pure essence", - "tradeable": "true", + "id": "7811", + "name": "Pot of vinegar", + "examine": "Well, this pot is certainly full of vinegar and no mistake.", "archery_ticket_price": "0", - "id": "7937" + "durability": null, + "weight": "1.3" }, { - "ge_buy_limit": "5000", - "examine": "A word in your shell-like.", - "grand_exchange_price": "13600", - "durability": null, - "name": "Tortoise shell", - "tradeable": "true", - "weight": "6.8", + "id": "7812", + "name": "Goblin skull", + "examine": "This needs a good polish.", "archery_ticket_price": "0", - "id": "7939" + "durability": null }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "13600", - "durability": null, - "name": "Tortoise shell", - "tradeable": "true", + "id": "7813", + "name": "Bone in vinegar", + "examine": "There is a goblin bone in here.", "archery_ticket_price": "0", - "id": "7940" + "durability": null, + "weight": "1" }, { - "examine": "A sturdy sheet of iron.", - "durability": null, - "name": "Iron sheet", - "weight": "1.75", + "id": "7814", + "name": "Goblin skull", + "examine": "This belongs in a museum!", "archery_ticket_price": "0", - "id": "7941" + "durability": null }, { - "examine": "Perfect for storing. Not so good for eating.", - "durability": null, - "name": "Fresh monkfish", - "weight": "0.8", + "id": "7815", + "name": "Bear ribs", + "examine": "This needs a good polish.", "archery_ticket_price": "0", - "id": "7942" + "durability": null }, { - "examine": "Perfect for storing. Not so good for eating.", - "durability": null, - "name": "Fresh monkfish", - "weight": "0.8", + "id": "7816", + "name": "Bone in vinegar", + "examine": "There is a bear bone in here.", "archery_ticket_price": "0", - "id": "7943" + "durability": null, + "weight": "1" }, { - "ge_buy_limit": "20000", - "examine": "I should try cooking this.", - "grand_exchange_price": "618", - "durability": null, - "name": "Raw monkfish", - "tradeable": "true", - "weight": "0.4", + "id": "7817", + "name": "Bear ribs", + "examine": "This belongs in a museum!", "archery_ticket_price": "0", - "id": "7944" + "durability": null }, { - "ge_buy_limit": "20000", - "grand_exchange_price": "618", - "durability": null, - "name": "Raw monkfish", - "tradeable": "true", + "id": "7818", + "name": "Ram skull", + "examine": "This needs a good polish.", "archery_ticket_price": "0", - "id": "7945" + "durability": null }, { - "ge_buy_limit": "10000", - "examine": "A tasty fish.", - "grand_exchange_price": "617", - "durability": null, - "name": "Monkfish", - "tradeable": "true", - "weight": "0.4", + "id": "7819", + "name": "Bone in vinegar", + "examine": "There is a ram bone in here.", "archery_ticket_price": "0", - "id": "7946" + "durability": null, + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "617", - "durability": null, - "name": "Monkfish", - "tradeable": "true", + "id": "7820", + "name": "Ram skull", + "examine": "This belongs in a museum!", "archery_ticket_price": "0", - "id": "7947" + "durability": null }, { - "durability": null, - "name": "Burnt monkfish", - "tradeable": "true", + "id": "7821", + "name": "Unicorn bone", + "examine": "This needs a good polish.", "archery_ticket_price": "0", - "id": "7949" + "durability": null }, { - "examine": "A highly portable army of skeletal magic.", - "durability": null, - "name": "Bone seeds", + "id": "7822", + "name": "Bone in vinegar", + "examine": "There is a unicorn bone in here.", "archery_ticket_price": "0", - "id": "7950" + "durability": null, + "weight": "1" }, { + "id": "7823", + "name": "Unicorn bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7824", + "name": "Giant rat bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7825", + "name": "Bone in vinegar", + "examine": "There is a giant rat bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7826", + "name": "Giant rat bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7827", + "name": "Giant bat wing", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7828", + "name": "Bone in vinegar", + "examine": "There is a giant bat bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7829", + "name": "Giant bat wing", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7830", + "name": "Wolf bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7831", + "name": "Bone in vinegar", + "examine": "There is a wolf bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7832", + "name": "Wolf bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7833", + "name": "Bat wing", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7834", + "name": "Bone in vinegar", + "examine": "There is a bat bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7835", + "name": "Bat wing", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7836", + "name": "Rat bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7837", + "name": "Bone in vinegar", + "examine": "There is a rat bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7838", + "name": "Rat bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7839", + "name": "Baby dragon bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7840", + "name": "Bone in vinegar", + "examine": "There is a baby blue dragon bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7841", + "name": "Baby dragon bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7842", + "name": "Ogre ribs", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7843", + "name": "Bone in vinegar", + "examine": "There is a ogre bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7844", + "name": "Ogre ribs", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7845", + "name": "Jogre bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7846", + "name": "Bone in vinegar", + "examine": "There is a jogre bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7847", + "name": "Jogre bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7848", + "name": "Zogre bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7849", + "name": "Bone in vinegar", + "examine": "There is a zogre bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7850", + "name": "Zogre bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7851", + "name": "Mogre bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7852", + "name": "Bone in vinegar", + "examine": "There is a mogre bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7853", + "name": "Mogre bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7854", + "name": "Monkey paw", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7855", + "name": "Bone in vinegar", + "examine": "There is a monkey bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7856", + "name": "Monkey paw", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7857", + "name": "Dagannoth ribs", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7858", + "name": "Bone in vinegar", + "examine": "There is a Dagannoth bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7859", + "name": "Dagannoth ribs", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7860", + "name": "Snake spine", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7861", + "name": "Bone in vinegar", + "examine": "There is a snake bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7862", + "name": "Snake spine", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7863", + "name": "Zombie bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7864", + "name": "Bone in vinegar", + "examine": "There is a zombie bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7865", + "name": "Zombie bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7866", + "name": "Werewolf bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7867", + "name": "Bone in vinegar", + "examine": "There is a werewolf bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7868", + "name": "Werewolf bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7869", + "name": "Moss giant bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7870", + "name": "Bone in vinegar", + "examine": "There is a moss giant bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7871", + "name": "Moss giant bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7872", + "name": "Fire giant bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7873", + "name": "Bone in vinegar", + "examine": "There is a fire giant bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7874", + "name": "Fire giant bone", + "examine": "This bone belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7875", + "name": "Ice giant ribs", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7876", + "name": "Bone in vinegar", + "examine": "There is an ice giant bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7877", + "name": "Ice giant ribs", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7878", + "name": "Terrorbird wing", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7879", + "name": "Bone in vinegar", + "examine": "There is a terrorbird bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7880", + "name": "Terrorbird wing", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7881", + "name": "Ghoul bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7882", + "name": "Bone in vinegar", + "examine": "There is a ghoul bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7883", + "name": "Ghoul bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7884", + "name": "Troll bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7885", + "name": "Bone in vinegar", + "examine": "There is a troll bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7886", + "name": "Troll bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7887", + "name": "Seagull wing", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7888", + "name": "Bone in vinegar", + "examine": "There is a seagull bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7889", + "name": "Seagull wing", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7890", + "name": "Undead cow ribs", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7891", + "name": "Bone in vinegar", + "examine": "There is an undead cow bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7892", + "name": "Undead cow ribs", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7893", + "name": "Experiment bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "160", - "examine": "A book taken from the desk of Herman Caranos.", + "weight": "0.9" + }, + { + "id": "7894", + "name": "Bone in vinegar", + "examine": "There is an experiment bone in here.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "7895", + "name": "Experiment bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "160", + "weight": "0.9" + }, + { + "id": "7896", + "name": "Rabbit bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7897", + "name": "Bone in vinegar", + "examine": "There is a rabbit bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7898", + "name": "Rabbit bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7899", + "name": "Basilisk bone", + "examine": "This bone needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7900", + "name": "Bone in vinegar", + "examine": "There is a basilisk bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7901", + "name": "Basilisk bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7902", + "name": "Desert lizard bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7903", + "name": "Bone in vinegar", + "examine": "There is a desert lizard bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7904", + "name": "Desert lizard bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7905", + "name": "Cave goblin skull", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7906", + "name": "Bone in vinegar", + "examine": "There is a cave goblin bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7907", + "name": "Cave goblin skull", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7908", + "name": "Big frog leg", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7909", + "name": "Bone in vinegar", + "examine": "There is a big frog bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7910", + "name": "Big frog leg", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7911", + "name": "Vulture wing", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7912", + "name": "Bone in vinegar", + "examine": "There is a vulture bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7913", + "name": "Vulture wing", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7914", + "name": "Jackal bone", + "examine": "This needs a good polish.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7915", + "name": "Bone in vinegar", + "examine": "There is a jackal bone in here.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7916", + "name": "Jackal bone", + "examine": "This belongs in a museum!", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.9" + }, + { + "id": "7917", + "name": "Ram skull helm", + "examine": "Makes me feel baaad to the bone.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,-2,19,21,16,0,19,6,0,0,0,0", + "destroy_message": "The ram skull helm looks like it will fall apart if you drop it. You would have to go to the Odd Old Man for a replacement.", + "durability": null, + "equipment_slot": "0", + "weight": "3" + }, + { + "id": "7918", + "name": "Bonesack", + "examine": "The Bonesack is a little old item that protects like leather.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,4,4,4,4,4,4,0,0,0,0", + "destroy_message": "The bonesack looks like it will fall apart if you drop it. You would have to go to the Odd Old Man for a replacement.", + "durability": null, + "equipment_slot": "1", + "weight": "9" + }, + { + "id": "7919", + "name": "Bottle of wine", + "examine": "A very good vintage.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "500", + "tradeable": "true", + "weight": "1" + }, + { + "id": "7920", + "name": "Bottle of wine", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7921", + "name": "Empty wine bottle", + "examine": "This one has clearly been taken down and passed around.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "7922", + "name": "Al kharid flyer", + "examine": "The money off voucher has expired.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7927", + "name": "Easter ring", + "examine": "A ring given to you by the Easter Bunny.", + "archery_ticket_price": "0", + "attack_audios": "", + "durability": null, + "equip_audio": "", + "equipment_slot": "12" + }, + { + "id": "7928", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7929", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7930", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7931", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7932", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7933", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7934", + "name": "Field ration", + "examine": "A field ration to help your wounds go away.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "390", + "tradeable": "true" + }, + { + "id": "7935", + "name": "Field ration", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "7936", + "name": "Pure essence", + "examine": "An uncharged Rune Stone of extra capability.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "7937", + "name": "Pure essence", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "7939", + "name": "Tortoise shell", + "examine": "A word in your shell-like.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "6.8" + }, + { + "id": "7940", + "name": "Tortoise shell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "7941", + "name": "Iron sheet", + "examine": "A sturdy sheet of iron.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1.75" + }, + { + "id": "7942", + "name": "Fresh monkfish", + "examine": "Perfect for storing. Not so good for eating.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.8" + }, + { + "id": "7943", + "name": "Fresh monkfish", + "examine": "Perfect for storing. Not so good for eating.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.8" + }, + { + "id": "7944", + "name": "Raw monkfish", + "examine": "I should try cooking this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "7945", + "name": "Raw monkfish", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" + }, + { + "id": "7946", + "name": "Monkfish", + "examine": "A tasty fish.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "7947", + "name": "Monkfish", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "7949", + "name": "Burnt monkfish", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "7950", + "name": "Bone seeds", + "examine": "A highly portable army of skeletal magic.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7951", "name": "Herman's book", - "tradeable": "false", - "destroy": "true", - "weight": "0.09", + "examine": "A book taken from the desk of Herman Caranos.", "archery_ticket_price": "0", - "id": "7951" + "destroy": "true", + "durability": null, + "shop_price": "160", + "tradeable": "false", + "weight": "0.09" }, { - "examine": "Useless without the head.", - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", "id": "7952", - "equipment_slot": "3" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", + "examine": "Useless without the head.", "archery_ticket_price": "0", - "id": "7953" + "durability": null, + "equipment_slot": "3", + "tradeable": "true" }, { + "id": "7953", + "name": "Picture", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "7955", "name": "Burnt shrimp", - "tradeable": "true", "archery_ticket_price": "0", - "id": "7955" + "durability": null, + "tradeable": "true" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "7956", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "7956" + "durability": null, + "tradeable": "true", + "weight": "5" }, { - "shop_price": "2", - "examine": "A mostly clean apron.", - "grand_exchange_price": "169", - "durability": null, + "id": "7957", "name": "White apron", - "tradeable": "true", - "weight": "0.45", + "examine": "A mostly clean apron.", "archery_ticket_price": "0", - "id": "7957" + "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "0.45" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A prop for holding up a tunnel roof.", - "durability": null, + "id": "7958", "name": "Mining prop", - "tradeable": "false", - "destroy": "true", + "examine": "A prop for holding up a tunnel roof.", "archery_ticket_price": "0", - "id": "7958" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get your box back by talking to the guard by the dungeon entrance in Etceteria.", - "examine": "A box full of stolen Etceterian items.", - "durability": null, + "id": "7959", "name": "Heavy box", - "tradeable": "false", - "destroy": "true", + "examine": "A box full of stolen Etceterian items.", "archery_ticket_price": "0", - "id": "7959" + "destroy": "true", + "destroy_message": "You can get your box back by talking to the guard by the dungeon entrance in Etceteria.", + "durability": null, + "tradeable": "false" }, { - "examine": "It says 'To the dungeons' on the side.", - "durability": null, + "id": "7960", "name": "Empty box", + "examine": "It says 'To the dungeons' on the side.", "archery_ticket_price": "0", - "id": "7960" + "durability": null }, { - "examine": "A diary with one/two/three/four/five page(s).", - "durability": null, + "id": "7961", "name": "Burnt diary", - "archery_ticket_price": "0", - "id": "7961" - }, - { "examine": "A diary with one/two/three/four/five page(s).", - "durability": null, - "name": "Burnt diary", "archery_ticket_price": "0", - "id": "7962" + "durability": null }, { + "id": "7962", + "name": "Burnt diary", "examine": "A diary with one/two/three/four/five page(s).", - "durability": null, - "name": "Burnt diary", "archery_ticket_price": "0", - "id": "7963" + "durability": null }, { + "id": "7963", + "name": "Burnt diary", "examine": "A diary with one/two/three/four/five page(s).", - "durability": null, - "name": "Burnt diary", "archery_ticket_price": "0", - "id": "7964" + "durability": null }, { + "id": "7964", + "name": "Burnt diary", "examine": "A diary with one/two/three/four/five page(s).", - "durability": null, - "name": "Burnt diary", "archery_ticket_price": "0", - "id": "7965" + "durability": null }, { - "examine": "A dwarf-made coal engine. It looks very sturdy.", - "durability": null, + "id": "7965", + "name": "Burnt diary", + "examine": "A diary with one/two/three/four/five page(s).", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7967", "name": "Engine", - "tradeable": "false", - "destroy": "true", + "examine": "A dwarf-made coal engine. It looks very sturdy.", "archery_ticket_price": "0", - "id": "7967" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A beam with a pulley attached.", - "durability": null, + "id": "7969", "name": "Pulley beam", + "examine": "A beam with a pulley attached.", "archery_ticket_price": "0", - "id": "7969" + "durability": null }, { - "examine": "A long beam with a pulley attached.", - "durability": null, + "id": "7970", "name": "Long pulley beam", + "examine": "A long beam with a pulley attached.", "archery_ticket_price": "0", - "id": "7970" + "durability": null }, { - "examine": "A very long beam with a pulley attached.", - "durability": null, + "id": "7971", "name": "Longer pulley beam", + "examine": "A very long beam with a pulley attached.", "archery_ticket_price": "0", - "id": "7971" + "durability": null }, { - "examine": "The manual for an AMCE Lift-In-A-Box.", - "durability": null, + "id": "7972", "name": "Lift manual", - "tradeable": "false", - "destroy": "true", + "examine": "The manual for an AMCE Lift-In-A-Box.", "archery_ticket_price": "0", - "id": "7972" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A wooden beam.", - "durability": null, + "id": "7973", "name": "Beam", + "examine": "A wooden beam.", "archery_ticket_price": "0", - "id": "7973" + "durability": null }, { - "durability": null, + "id": "7975", "name": "Crawling hand", + "examine": "I should get it stuffed!", "archery_ticket_price": "0", "attack_speed": "4", - "id": "7975" + "durability": null }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7976", "name": "Cockatrice head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I should get it stuffed!", "archery_ticket_price": "0", - "id": "7976" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7977", "name": "Basilisk head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I should get it stuffed!", "archery_ticket_price": "0", - "id": "7977" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7978", "name": "Kurask head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I should get it stuffed!", "archery_ticket_price": "0", - "id": "7978" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7979", "name": "Abyssal head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I should get it stuffed!", "archery_ticket_price": "0", - "id": "7979" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7980", "name": "Kbd heads", - "tradeable": "false", - "destroy": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "7980" - }, - { "examine": "I should get it stuffed!", - "durability": null, - "name": "Kq head", "archery_ticket_price": "0", - "id": "7981" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "durability": null, + "id": "7981", + "name": "Kq head", + "examine": "I should get it stuffed!", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7982", "name": "Crawling hand", + "examine": "I could mount this on my wall!", "archery_ticket_price": "0", "attack_speed": "4", - "id": "7982" + "durability": null }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7983", "name": "Cockatrice head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I could mount this on my wall!", "archery_ticket_price": "0", - "id": "7983" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7984", "name": "Basilisk head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I could mount this on my wall!", "archery_ticket_price": "0", - "id": "7984" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7985", "name": "Kurask head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I could mount this on my wall!", "archery_ticket_price": "0", - "id": "7985" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7986", "name": "Abyssal head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "I could mount this on my wall!", "archery_ticket_price": "0", - "id": "7986" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7987", "name": "Kbd heads", - "tradeable": "false", + "examine": "I could mount these on my wall!", + "archery_ticket_price": "0", "destroy": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "7987" + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "7988", "name": "Kq head", + "examine": "I could mount this on my wall!", "archery_ticket_price": "0", - "id": "7988" + "durability": null }, { - "examine": "Whopper! I should get this stuffed!", - "durability": null, + "id": "7989", "name": "Big bass", - "weight": "6", + "examine": "Whopper! I should get this stuffed!", "archery_ticket_price": "0", - "id": "7989" + "durability": null, + "weight": "6" }, { - "examine": "Whopper! I should get this stuffed!", - "durability": null, + "id": "7990", "name": "Big bass", - "weight": "6", + "examine": "I should mount this on my wall!", "archery_ticket_price": "0", - "id": "7990" + "durability": null, + "weight": "6" }, { - "examine": "Whopper! I should get this stuffed!", - "durability": null, + "id": "7991", "name": "Big swordfish", - "archery_ticket_price": "0", - "id": "7991" - }, - { "examine": "Whopper! I should get this stuffed!", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "7992", "name": "Big swordfish", + "examine": "I should mount this on my wall!", "archery_ticket_price": "0", - "id": "7992" + "durability": null }, { - "examine": "Its a monster! I should get this stuffed!", - "durability": null, + "id": "7993", "name": "Big shark", - "weight": "0.7", + "examine": "It's a monster! I should get this stuffed!", "archery_ticket_price": "0", - "id": "7993" + "durability": null, + "weight": "0.7" }, { - "examine": "Its a monster! I should get this stuffed!", - "durability": null, + "id": "7994", "name": "Big shark", - "weight": "0.7", + "examine": "I should mount this on my wall!", "archery_ticket_price": "0", - "id": "7994" + "durability": null, + "weight": "0.7" }, { - "examine": "A portrait of King Arthur.", - "durability": null, + "id": "7995", "name": "Arthur portrait", - "weight": "1", + "examine": "A portrait of King Arthur.", "archery_ticket_price": "0", - "id": "7995" + "durability": null, + "weight": "1" }, { - "shop_price": "1000", - "examine": "A portrait of Elena.", - "durability": null, + "id": "7996", "name": "Elena portrait", - "weight": "1", + "examine": "A portrait of Elena.", "archery_ticket_price": "0", - "id": "7996" + "durability": null, + "shop_price": "1000", + "weight": "1" }, { - "examine": "A painting of the staute of King Alvis of Keldagrim", - "durability": null, + "id": "7997", "name": "Keldagrim portrait", - "weight": "1", + "examine": "A painting of the staute of King Alvis of Keldagrim", "archery_ticket_price": "0", - "id": "7997" + "durability": null, + "weight": "1" }, { - "examine": "A portrait of Prince Brand and Princess Astrid of Miscellania.", - "durability": null, + "id": "7998", "name": "Misc. portrait", - "weight": "1", + "examine": "A portrait of Prince Brand and Princess Astrid of Miscellania.", "archery_ticket_price": "0", - "id": "7998" + "durability": null, + "weight": "1" }, { - "shop_price": "2000", - "examine": "The exotic land of the Elves.", - "durability": null, + "id": "8000", "name": "Isafdar painting", + "examine": "The exotic land of the Elves.", "archery_ticket_price": "0", - "id": "8000" + "durability": null, + "shop_price": "2000" }, { - "shop_price": "2000", - "examine": "The tropical coast of karamja.", - "durability": null, + "id": "8001", "name": "Karamja painting", + "examine": "The tropical coast of karamja.", "archery_ticket_price": "0", - "id": "8001" + "durability": null, + "shop_price": "2000" }, { - "shop_price": "2000", - "examine": "Oxtable's famous painting of the Lumbridge water mill.", - "durability": null, + "id": "8002", "name": "Lumbridge painting", - "weight": "1", + "examine": "Oxtable's famous painting of the Lumbridge water mill.", "archery_ticket_price": "0", - "id": "8002" - }, - { + "durability": null, "shop_price": "2000", - "examine": "A painting of the spooky forests of morytania.", - "durability": null, + "weight": "1" + }, + { + "id": "8003", "name": "Morytania painting", - "weight": "1", + "examine": "A painting of the spooky forests of morytania.", "archery_ticket_price": "0", - "id": "8003" + "durability": null, + "shop_price": "2000", + "weight": "1" }, { - "shop_price": "2500", - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1341", - "durability": null, + "id": "8007", "name": "Varrock teleport", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8007" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2500", + "tradeable": "true" }, { - "shop_price": "2500", - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1371", - "durability": null, + "id": "8008", "name": "Lumbridge teleport", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8008" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2500", + "tradeable": "true" }, { - "shop_price": "2500", - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1414", - "durability": null, + "id": "8009", "name": "Falador teleport", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "8009" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2500", + "tradeable": "true" }, { - "shop_price": "2500", - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1369", - "durability": null, + "id": "8010", "name": "Camelot teleport", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8010" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2500", + "tradeable": "true" }, { - "shop_price": "2500", - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1511", - "durability": null, + "id": "8011", "name": "Ardougne teleport", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8011" - }, - { + "durability": null, + "ge_buy_limit": "1000", "shop_price": "2500", - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1025", - "durability": null, + "tradeable": "true" + }, + { + "id": "8012", "name": "Watchtower t'port", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8012" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2500", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "1426", - "durability": null, + "id": "8013", "name": "Teleport to house", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8013" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "200", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "360", - "durability": null, + "id": "8014", "name": "Bones to bananas", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8014" - }, - { + "durability": null, "ge_buy_limit": "200", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "620", - "durability": null, + "tradeable": "true" + }, + { + "id": "8015", "name": "Bones to peaches", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8015" + "durability": null, + "ge_buy_limit": "200", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "343", - "durability": null, + "id": "8016", "name": "Enchant sapphire", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8016" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "409", - "durability": null, + "id": "8017", "name": "Enchant emerald", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8017" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "207", - "durability": null, + "id": "8018", "name": "Enchant ruby", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8018" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "326", - "durability": null, + "id": "8019", "name": "Enchant diamond", - "tradeable": "true", + "examine": "A tablet containing a magic spell.", "archery_ticket_price": "0", - "id": "8019" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "250", - "durability": null, + "id": "8020", "name": "Enchant dragonstn.", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8020" - }, - { - "ge_buy_limit": "1000", "examine": "A tablet containing a magic spell.", - "grand_exchange_price": "31", - "durability": null, - "name": "Enchant onyx", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8021" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "grand_exchange_price": "1918", + "id": "8021", + "name": "Enchant onyx", + "examine": "A tablet containing a magic spell.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "8031", "name": "Wooden bed", "archery_ticket_price": "0", - "id": "8031" + "durability": null }, { - "grand_exchange_price": "1631", - "durability": null, + "id": "8032", "name": "Oak bed", "archery_ticket_price": "0", - "id": "8032" + "durability": null }, { - "grand_exchange_price": "1388", - "durability": null, + "id": "8033", "name": "Large oak bed", "archery_ticket_price": "0", - "id": "8033" + "durability": null }, { - "grand_exchange_price": "1376", - "durability": null, + "id": "8034", "name": "Teak bed", "archery_ticket_price": "0", - "id": "8034" + "durability": null }, { - "grand_exchange_price": "1996", - "durability": null, + "id": "8035", "name": "Large teak bed", "archery_ticket_price": "0", - "id": "8035" + "durability": null }, { - "grand_exchange_price": "1314", - "durability": null, + "id": "8036", "name": "4-poster", "archery_ticket_price": "0", - "id": "8036" + "durability": null }, { - "grand_exchange_price": "274779", - "durability": null, + "id": "8037", "name": "Gilded 4-poster", "archery_ticket_price": "0", - "id": "8037" + "durability": null }, { - "grand_exchange_price": "18", - "durability": null, + "id": "8038", "name": "Shoe box", "archery_ticket_price": "0", - "id": "8038" + "durability": null }, { - "grand_exchange_price": "42", - "durability": null, + "id": "8039", "name": "Oak drawers", "archery_ticket_price": "0", - "id": "8039" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8040", "name": "Oak wardrobe", "archery_ticket_price": "0", - "id": "8040" + "durability": null }, { - "grand_exchange_price": "126", - "durability": null, + "id": "8041", "name": "Teak drawers", "archery_ticket_price": "0", - "id": "8041" + "durability": null }, { - "grand_exchange_price": "12", - "durability": null, + "id": "8042", "name": "Teak wardrobe", "archery_ticket_price": "0", - "id": "8042" + "durability": null }, { - "grand_exchange_price": "102", - "durability": null, + "id": "8043", "name": "Mahogany 'drobe", "archery_ticket_price": "0", - "id": "8043" + "durability": null }, { - "grand_exchange_price": "139452", - "durability": null, + "id": "8044", "name": "Gilded wardrobe", "archery_ticket_price": "0", - "id": "8044" + "durability": null }, { - "grand_exchange_price": "510", - "durability": null, + "id": "8045", "name": "Shaving stand", "archery_ticket_price": "0", - "id": "8045" + "durability": null }, { - "grand_exchange_price": "449", - "durability": null, + "id": "8046", "name": "Oak shaving stand", "archery_ticket_price": "0", - "id": "8046" + "durability": null }, { - "grand_exchange_price": "147", - "durability": null, + "id": "8047", "name": "Oak dresser", "archery_ticket_price": "0", - "id": "8047" + "durability": null }, { - "grand_exchange_price": "478", - "durability": null, + "id": "8048", "name": "Teak dresser", "archery_ticket_price": "0", - "id": "8048" + "durability": null }, { - "grand_exchange_price": "456", - "durability": null, + "id": "8049", "name": "Fancy teak dresser", "archery_ticket_price": "0", - "id": "8049" + "durability": null }, { - "grand_exchange_price": "404", - "durability": null, + "id": "8050", "name": "Mahogany dresser", "archery_ticket_price": "0", - "id": "8050" + "durability": null }, { - "grand_exchange_price": "140594", - "durability": null, + "id": "8051", "name": "Gilded dresser", "archery_ticket_price": "0", - "id": "8051" + "durability": null }, { - "grand_exchange_price": "367", - "durability": null, + "id": "8052", "name": "Oak clock", "archery_ticket_price": "0", - "id": "8052" + "durability": null }, { - "grand_exchange_price": "552", - "durability": null, + "id": "8053", "name": "Teak clock", "archery_ticket_price": "0", - "id": "8053" + "durability": null }, { - "grand_exchange_price": "154310", - "durability": null, + "id": "8054", "name": "Gilded clock", "archery_ticket_price": "0", - "id": "8054" + "durability": null }, { - "examine": "When unanimated: A dusty old suit of armour. When animated: Aaargh, it's alive!", - "durability": null, + "id": "8085", "name": "Suit of armour", + "examine": "When unanimated: A dusty old suit of armour. When animated: Aaargh, it's alive!", "archery_ticket_price": "0", - "id": "8085" + "durability": null }, { - "grand_exchange_price": "13", - "durability": null, + "id": "8108", "name": "Wooden bench", "archery_ticket_price": "0", - "id": "8108" + "durability": null }, { - "grand_exchange_price": "131", - "durability": null, + "id": "8109", "name": "Oak bench", "archery_ticket_price": "0", - "id": "8109" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8110", "name": "Carved oak bench", "archery_ticket_price": "0", - "id": "8110" + "durability": null }, { - "grand_exchange_price": "17", - "durability": null, + "id": "8111", "name": "Teak dining bench", "archery_ticket_price": "0", - "id": "8111" + "durability": null }, { - "grand_exchange_price": "2", - "durability": null, + "id": "8112", "name": "Carved teak bench", "archery_ticket_price": "0", - "id": "8112" + "durability": null }, { - "grand_exchange_price": "145", - "durability": null, + "id": "8113", "name": "Mahogany bench", "archery_ticket_price": "0", - "id": "8113" + "durability": null }, { - "grand_exchange_price": "531526", - "durability": null, + "id": "8114", "name": "Gilded bench", "archery_ticket_price": "0", - "id": "8114" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8115", "name": "Wood dining table", "archery_ticket_price": "0", - "id": "8115" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8116", "name": "Oak dining table", "archery_ticket_price": "0", - "id": "8116" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8117", "name": "Carved oak table", "archery_ticket_price": "0", - "id": "8117" + "durability": null }, { - "grand_exchange_price": "2", - "durability": null, + "id": "8118", "name": "Teak table", "archery_ticket_price": "0", - "id": "8118" + "durability": null }, { - "grand_exchange_price": "249", - "durability": null, + "id": "8119", "name": "Carved teak table", "archery_ticket_price": "0", - "id": "8119" + "durability": null }, { - "grand_exchange_price": "497", - "durability": null, + "id": "8120", "name": "Mahogany table", "archery_ticket_price": "0", - "id": "8120" + "durability": null }, { - "grand_exchange_price": "394177", - "durability": null, + "id": "8121", "name": "Opulent table", "archery_ticket_price": "0", - "id": "8121" + "durability": null }, { - "shop_price": "24", - "examine": "A candle.", - "grand_exchange_price": "104", - "durability": null, + "id": "8128", "name": "Candles", - "tradeable": "true", + "examine": "A candle.", "archery_ticket_price": "0", - "id": "8128" + "durability": null, + "shop_price": "24", + "tradeable": "true" }, { - "durability": null, + "id": "8131", "name": "Skeleton guard", "archery_ticket_price": "0", "attack_speed": "4", - "id": "8131" + "durability": null }, { - "examine": "He doesn't seem pleased to see me./Beware of the dog! (Construction)", - "durability": null, + "id": "8132", "name": "Guard dog", + "examine": "He doesn't seem pleased to see me./Beware of the dog! (Construction)", "archery_ticket_price": "0", - "id": "8132" + "durability": null }, { - "examine": "He doesn't look very welcoming.", - "durability": null, + "id": "8133", "name": "Hobgoblin guard", + "examine": "He doesn't look very welcoming.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "8133" + "durability": null }, { - "examine": "Young but still dangerous.", - "durability": null, + "id": "8134", "name": "Baby red dragon", + "examine": "Young but still dangerous.", "archery_ticket_price": "0", - "id": "8134" + "durability": null }, { - "examine": "No spider could grow that big! It's unrealistic!", - "durability": null, + "id": "8135", "name": "Huge spider", + "examine": "No spider could grow that big! It's unrealistic!", "archery_ticket_price": "0", - "id": "8135" + "durability": null }, { - "examine": "(Level 122)", - "durability": null, + "id": "8137", "name": "Hellhound", + "examine": "(Level 122)", "archery_ticket_price": "0", "attack_speed": "4", - "id": "8137" + "durability": null }, { - "examine": "I don't think insect repellent will work...", - "durability": null, + "id": "8139", "name": "Kalphite soldier", + "examine": "I don't think insect repellent will work...", "archery_ticket_price": "0", "attack_speed": "4", - "id": "8139" + "durability": null }, { - "examine": "The Tok-Xil fires deadly spines out of its arm, projected by its own heat.", - "durability": null, + "id": "8140", "name": "Tok-xil", + "examine": "The Tok-Xil fires deadly spines out of its arm, projected by its own heat.", "archery_ticket_price": "0", - "id": "8140" + "durability": null }, { - "examine": "Its scales seem to be made of steel.", - "durability": null, + "id": "8142", "name": "Steel dragon", + "examine": "Its scales seem to be made of steel.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "8142" + "durability": null }, { - "shop_price": "5000", - "examine": "You can plant this in your garden.", - "durability": null, + "id": "8203", "name": "Thorny hedge", - "tradeable": "true", + "examine": "You can plant this in your garden.", "archery_ticket_price": "0", - "id": "8203" + "durability": null, + "shop_price": "5000", + "tradeable": "true" }, { - "shop_price": "10000", - "examine": "You can plant this in your garden.", - "durability": null, + "id": "8204", "name": "Nice hedge", - "tradeable": "true", + "examine": "You can plant this in your garden.", "archery_ticket_price": "0", - "id": "8204" + "durability": null, + "shop_price": "10000", + "tradeable": "true" }, { - "shop_price": "15000", - "examine": "You can plant this in your garden.", - "durability": null, + "id": "8205", "name": "Small box hedge", - "tradeable": "true", + "examine": "You can plant this in your garden.", "archery_ticket_price": "0", - "id": "8205" + "durability": null, + "shop_price": "15000", + "tradeable": "true" }, { - "shop_price": "20000", - "examine": "You can plant this in your garden.", - "durability": null, + "id": "8206", "name": "Topiary hedge", - "tradeable": "true", - "weight": "10", + "examine": "You can plant this in your garden.", "archery_ticket_price": "0", - "id": "8206" + "durability": null, + "shop_price": "20000", + "tradeable": "true", + "weight": "10" }, { - "shop_price": "25000", - "examine": "You can plant this in your garden.", - "durability": null, + "id": "8207", "name": "Fancy hedge", - "weight": "10", - "archery_ticket_price": "0", - "id": "8207" - }, - { - "shop_price": "50000", "examine": "You can plant this in your garden.", + "archery_ticket_price": "0", "durability": null, + "shop_price": "25000", + "weight": "10" + }, + { + "id": "8208", "name": "Tall fancy hedge", + "examine": "You can plant this in your garden.", "archery_ticket_price": "0", - "id": "8208" + "durability": null, + "shop_price": "50000" }, { - "examine": "Some rosemary.", - "grand_exchange_price": "20", - "durability": null, + "id": "8210", "name": "Rosemary", - "tradeable": "true", + "examine": "Some rosemary.", "archery_ticket_price": "0", - "id": "8210" + "durability": null, + "tradeable": "true" }, { - "examine": "A bunch of marigolds.", - "grand_exchange_price": "3862", - "durability": null, + "id": "8214", "name": "Marigolds", - "tradeable": "true", + "examine": "A bunch of marigolds.", "archery_ticket_price": "0", - "id": "8214" + "durability": null, + "tradeable": "true" }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8239", "name": "Beer barrel", "archery_ticket_price": "0", - "id": "8239" + "durability": null }, { - "grand_exchange_price": "16860", - "durability": null, + "id": "8240", "name": "Cider barrel", "archery_ticket_price": "0", - "id": "8240" + "durability": null }, { - "shop_price": "3", - "examine": "Probably the finest readily-available ale in Asgarnia.", - "grand_exchange_price": "131", - "durability": null, + "id": "8241", "name": "Asgarnian ale", - "tradeable": "true", + "examine": "Probably the finest readily-available ale in Asgarnia.", "archery_ticket_price": "0", - "id": "8241" + "durability": null, + "shop_price": "3", + "tradeable": "true" }, { - "shop_price": "2", - "examine": "A glass of frothy ale.", - "grand_exchange_price": "569", - "durability": null, + "id": "8242", "name": "Greenman's ale", - "tradeable": "true", + "examine": "A glass of frothy ale.", "archery_ticket_price": "0", - "id": "8242" - }, - { + "durability": null, "shop_price": "2", - "examine": "A glass of bitter.", - "grand_exchange_price": "523", - "durability": null, + "tradeable": "true" + }, + { + "id": "8243", "name": "Dragon bitter", - "tradeable": "true", - "weight": "1", + "examine": "A glass of bitter.", "archery_ticket_price": "0", - "id": "8243" + "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "1" }, { - "examine": "A fruity, full-bodied ale.", - "grand_exchange_price": "2371", - "durability": null, + "id": "8244", "name": "Chef's delight", - "tradeable": "true", + "examine": "A fruity, full-bodied ale.", "archery_ticket_price": "0", - "id": "8244" + "durability": null, + "tradeable": "true" }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8246", "name": "Wood kitchen table", "archery_ticket_price": "0", - "id": "8246" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8247", "name": "Oak kitchen table", "archery_ticket_price": "0", - "id": "8247" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8248", "name": "Teak kitchen table", "archery_ticket_price": "0", - "id": "8248" + "durability": null }, { - "durability": null, + "id": "8260", "name": "Crawling hand", + "examine": "A trophy of a mighty slayer!", "archery_ticket_price": "0", "attack_speed": "4", - "id": "8260" + "durability": null }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "8261", "name": "Cockatrice head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "A trophy of a mighty slayer!", "archery_ticket_price": "0", - "id": "8261" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "8262", "name": "Basilisk head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "A trophy of a mighty slayer!", "archery_ticket_price": "0", - "id": "8262" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "8263", "name": "Kurask head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "A trophy of a mighty slayer!", "archery_ticket_price": "0", - "id": "8263" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "8264", "name": "Abyssal head", - "tradeable": "false", - "destroy": "true", - "weight": "10", + "examine": "A trophy of a mighty slayer!!", "archery_ticket_price": "0", - "id": "8264" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "8265", "name": "Kbd heads", - "tradeable": "false", + "examine": "A trophy of a mighty dragon-slayer!", + "archery_ticket_price": "0", "destroy": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "8265" + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "I should get it stuffed!", - "durability": null, + "id": "8266", "name": "Kq head", + "examine": "A trophy of a mighty kalphite slayer!", "archery_ticket_price": "0", - "id": "8266" + "durability": null }, { - "durability": null, - "name": "Runite armour", - "archery_ticket_price": "0", "id": "8272", + "name": "Runite armour", "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null }, { - "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", - "durability": null, - "name": "Silverlight", - "weight": "1.8", - "archery_ticket_price": "0", - "attack_speed": "5", "id": "8279", - "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0" - }, - { - "examine": "This used to belong to King Arthur.", - "durability": null, - "name": "Excalibur", - "weight": "2.2", + "name": "Silverlight", + "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", "archery_ticket_price": "0", "attack_speed": "5", + "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0", + "durability": null, + "weight": "1.8" + }, + { "id": "8280", - "bonuses": "20,29,-2,0,0,0,3,2,1,0,0,25,0,0,0" - }, - { - "examine": "The magical sword Silverlight, enhanced with the blood of Agrith-Naar.", - "durability": null, - "name": "Darklight", - "weight": "1.8", + "name": "Excalibur", + "examine": "This used to belong to King Arthur.", "archery_ticket_price": "0", "attack_speed": "5", + "bonuses": "20,29,-2,0,0,0,3,2,1,0,0,25,0,0,0", + "durability": null, + "weight": "2.2" + }, + { "id": "8281", - "bonuses": "10,16,-2,0,0,0,3,2,2,0,0,13,0,0,0" + "name": "Darklight", + "examine": "The magical sword Silverlight, enhanced with the blood of Agrith-Naar.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "10,16,-2,0,0,0,3,2,2,0,0,13,0,0,0", + "durability": null, + "weight": "1.8" }, { - "examine": "This provides partial protection from dragon-breath attacks.", - "grand_exchange_price": "305", - "durability": null, - "name": "Anti-dragon shield", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", "id": "8282", - "bonuses": "0,0,0,0,0,7,9,8,2,8,0,0,0,0,0" - }, - { - "examine": "A very powerful dragonstone amulet.", - "grand_exchange_price": "1", + "name": "Anti-dragon shield", + "examine": "This provides partial protection from dragon-breath attacks.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,7,9,8,2,8,0,0,0,0,0", "durability": null, - "name": "Amulet of glory", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8283", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,0,3,0" + "name": "Amulet of glory", + "examine": "A very powerful dragonstone amulet.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,0,3,0", + "durability": null, + "tradeable": "true" }, { - "shop_price": "450", - "examine": "The cape worn by members of the Legends Guild.", - "durability": null, - "name": "Cape of legends", - "weight": "1.8", - "archery_ticket_price": "0", "id": "8284", - "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0" + "name": "Cape of legends", + "examine": "The cape worn by members of the Legends Guild.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", + "durability": null, + "shop_price": "450", + "weight": "1.8" }, { - "examine": "Legendary King of the Britons.", - "durability": null, + "id": "8285", "name": "King arthur", + "examine": "Legendary King of the Britons.", "archery_ticket_price": "0", - "id": "8285" + "durability": null }, { - "examine": "She looks concerned.", - "durability": null, + "id": "8286", "name": "Elena", + "examine": "She looks concerned.", "archery_ticket_price": "0", - "id": "8286" + "durability": null }, { - "examine": "It's full of pent-up aggression.", - "durability": null, + "id": "8305", "name": "Rocnar", + "examine": "It's full of pent-up aggression.", "archery_ticket_price": "0", - "id": "8305" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8309", "name": "Crude wooden chair", "archery_ticket_price": "0", - "id": "8309" + "durability": null }, { - "grand_exchange_price": "50", - "durability": null, + "id": "8310", "name": "Wooden chair", "archery_ticket_price": "0", - "id": "8310" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8311", "name": "Rocking chair", "archery_ticket_price": "0", - "id": "8311" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8312", "name": "Oak chair", "archery_ticket_price": "0", - "id": "8312" + "durability": null }, { - "grand_exchange_price": "2", - "durability": null, + "id": "8313", "name": "Oak armchair", "archery_ticket_price": "0", - "id": "8313" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8314", "name": "Teak armchair", "archery_ticket_price": "0", - "id": "8314" + "durability": null }, { - "grand_exchange_price": "8", - "durability": null, + "id": "8315", "name": "Mahogany armchair", "archery_ticket_price": "0", - "id": "8315" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8319", "name": "Wooden bookcase", "archery_ticket_price": "0", - "id": "8319" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "8320", "name": "Oak bookcase", "archery_ticket_price": "0", - "id": "8320" + "durability": null }, { - "grand_exchange_price": "52", - "durability": null, + "id": "8321", "name": "Mahogany b'kcase", "archery_ticket_price": "0", - "id": "8321" + "durability": null }, { + "id": "8417", + "name": "Bagged dead tree", + "examine": "You can plant this in your garden.", + "archery_ticket_price": "0", + "durability": null, "requirements": "{5,22}", "shop_price": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "8418", + "name": "Bagged dead tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8419", + "name": "Bagged nice tree", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged dead tree", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "8417" - }, - { "durability": null, - "name": "Bagged dead tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8418" - }, - { "requirements": "{10,22}", "shop_price": "2000", + "tradeable": "true" + }, + { + "id": "8420", + "name": "Bagged nice tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8421", + "name": "Bagged oak tree", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged nice tree", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8419" - }, - { "durability": null, - "name": "Bagged nice tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8420" - }, - { "requirements": "{15,22}", + "tradeable": "true" + }, + { + "id": "8422", + "name": "Bagged oak tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8423", + "name": "Bagged willow tree", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged oak tree", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8421" - }, - { "durability": null, - "name": "Bagged oak tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8422" - }, - { "requirements": "{22,30}", "shop_price": "10000", + "tradeable": "true" + }, + { + "id": "8424", + "name": "Bagged willow tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8425", + "name": "Bagged maple tree", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged willow tree", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8423" - }, - { "durability": null, - "name": "Bagged willow tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8424" - }, - { "requirements": "{22,45}", "shop_price": "15000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8426", + "name": "Bagged maple tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8427", + "name": "Bagged yew tree", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged maple tree", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8425" - }, - { "durability": null, - "name": "Bagged maple tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8426" - }, - { "requirements": "{22,60}", "shop_price": "20000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8428", + "name": "Bagged yew tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8429", + "name": "Bagged magic tree", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged yew tree", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8427" - }, - { "durability": null, - "name": "Bagged yew tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8428" - }, - { "requirements": "{22,75}", "shop_price": "50000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8430", + "name": "Bagged magic tree", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8431", + "name": "Bagged plant 1", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged magic tree", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8429" - }, - { "durability": null, - "name": "Bagged magic tree", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8430" - }, - { + "ge_buy_limit": "5000", "shop_price": "1000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8432", + "name": "Bagged plant 1", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "8433", + "name": "Bagged plant 2", "examine": "You can plant this in your garden.", - "grand_exchange_price": "1345", - "durability": null, - "name": "Bagged plant 1", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8431" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1345", "durability": null, - "name": "Bagged plant 1", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8432" - }, - { "requirements": "{6,22}", "shop_price": "5000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8434", + "name": "Bagged plant 2", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8435", + "name": "Bagged plant 3", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged plant 2", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8433" - }, - { "durability": null, - "name": "Bagged plant 2", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8434" - }, - { "requirements": "{12,22}", "shop_price": "10000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8436", + "name": "Bagged plant 3", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8437", + "name": "Thorny hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged plant 3", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8435" - }, - { "durability": null, - "name": "Bagged plant 3", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8436" - }, - { "requirements": "{22,56}", "shop_price": "5000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8438", + "name": "Thorny hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8439", + "name": "Nice hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Thorny hedge", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8437" - }, - { "durability": null, - "name": "Thorny hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8438" - }, - { "requirements": "{22,60}", "shop_price": "10000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8440", + "name": "Nice hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8441", + "name": "Small box hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Nice hedge", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8439" - }, - { "durability": null, - "name": "Nice hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8440" - }, - { "requirements": "{22,64}", "shop_price": "15000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8442", + "name": "Small box hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8443", + "name": "Topiary hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Small box hedge", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8441" - }, - { "durability": null, - "name": "Small box hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8442" - }, - { "requirements": "{22,68}", "shop_price": "20000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8444", + "name": "Topiary hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8445", + "name": "Fancy hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Topiary hedge", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8443" - }, - { "durability": null, - "name": "Topiary hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8444" - }, - { "requirements": "{22,72}", "shop_price": "25000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8446", + "name": "Fancy hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8447", + "name": "Tall fancy hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Fancy hedge", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8445" - }, - { "durability": null, - "name": "Fancy hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8446" - }, - { "requirements": "{22,76}", "shop_price": "50000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8448", + "name": "Tall fancy hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8449", + "name": "Tall box hedge", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Tall fancy hedge", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8447" - }, - { "durability": null, - "name": "Tall fancy hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8448" - }, - { "requirements": "{22,80}", "shop_price": "100000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8450", + "name": "Tall box hedge", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8451", + "name": "Bagged rosemary", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Tall box hedge", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8449" - }, - { "durability": null, - "name": "Tall box hedge", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8450" - }, - { "requirements": "{22,66}", "shop_price": "5000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8452", + "name": "Bagged rosemary", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8453", + "name": "Bagged daffodils", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged rosemary", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8451" - }, - { "durability": null, - "name": "Bagged rosemary", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8452" - }, - { "requirements": "{22,71}", "shop_price": "10000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8454", + "name": "Bagged daffodils", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8455", + "name": "Bagged bluebells", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged daffodils", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8453" - }, - { "durability": null, - "name": "Bagged daffodils", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8454" - }, - { "requirements": "{22,76}", "shop_price": "15000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8456", + "name": "Bagged bluebells", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8457", + "name": "Bagged sunflower", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged bluebells", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8455" - }, - { "durability": null, - "name": "Bagged bluebells", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8456" - }, - { "requirements": "{22,66}", "shop_price": "5000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8458", + "name": "Bagged sunflower", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8459", + "name": "Bagged marigolds", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged sunflower", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8457" - }, - { "durability": null, - "name": "Bagged sunflower", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8458" - }, - { "requirements": "{22,71}", "shop_price": "10000", + "tradeable": "true", + "weight": "10" + }, + { + "id": "8460", + "name": "Bagged marigolds", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8461", + "name": "Bagged roses", "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged marigolds", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "10", - "id": "8459" - }, - { "durability": null, - "name": "Bagged marigolds", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8460" - }, - { "requirements": "{22,76}", "shop_price": "15000", - "examine": "You can plant this in your garden.", - "durability": null, - "name": "Bagged roses", "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "8461" + "weight": "10" }, { - "durability": null, + "id": "8462", "name": "Bagged roses", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8462" + "durability": null, + "tradeable": "true" }, { - "shop_price": "160", - "examine": "How to build a house.", - "durability": null, + "id": "8463", "name": "Construction guide", - "tradeable": "true", - "weight": "1", + "examine": "How to build a house.", "archery_ticket_price": "0", - "id": "8463" + "durability": null, + "shop_price": "160", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", "id": "8464", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8466", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8468", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8470", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8472", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8474", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8476", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8478", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8480", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8482", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8484", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8486", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8488", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8490", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8492", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,40}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Rune heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8494", + "name": "Rune heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "requirements": "{1,40}", + "weight": "2.7" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8496", + "name": "Crude wooden chair", "examine": "A ready-to-assemble crude chair.", - "durability": null, - "name": "Crude wooden chair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8496" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8497", "name": "Crude wooden chair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8497" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "53", + "id": "8498", + "name": "Wooden chair", "examine": "A ready-to-assemble wooden chair.", - "durability": null, - "name": "Wooden chair", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8498" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "53", - "durability": null, + "id": "8499", "name": "Wooden chair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8499" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8500", + "name": "Rocking chair", "examine": "A ready-to-assemble rocking chair.", - "durability": null, - "name": "Rocking chair", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8500" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8501", "name": "Rocking chair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8501" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2", + "id": "8502", + "name": "Oak chair", "examine": "A ready-to-assemble oak chair.", - "durability": null, - "name": "Oak chair", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8502" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2", - "durability": null, + "id": "8503", "name": "Oak chair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8503" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8504", + "name": "Oak armchair", "examine": "A ready-to-assemble oak armchair.", - "durability": null, - "name": "Oak armchair", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8504" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8505", "name": "Oak armchair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8505" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8506", + "name": "Teak armchair", "examine": "A ready-to-assemble teak armchair.", - "durability": null, - "name": "Teak armchair", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8506" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8507", "name": "Teak armchair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8507" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8", + "id": "8508", + "name": "Mahogany armchair", "examine": "A ready-to-assemble mahogany armchair.", - "durability": null, - "name": "Mahogany armchair", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8508" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, + "id": "8509", "name": "Mahogany armchair", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8509" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8510", + "name": "Wooden bookcase", "examine": "A ready-to-assemble wooden bookcase.", - "durability": null, - "name": "Wooden bookcase", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8510" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8511", "name": "Wooden bookcase", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8511" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8512", + "name": "Oak bookcase", "examine": "A ready-to-assemble oak bookcase.", - "durability": null, - "name": "Oak bookcase", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8512" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8513", "name": "Oak bookcase", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8513" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "46", + "id": "8514", + "name": "Mahogany b'kcase", "examine": "A ready-to-assemble mahogany bookcase.", - "durability": null, - "name": "Mahogany b'kcase", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8514" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "46", - "durability": null, + "id": "8515", "name": "Mahogany b'kcase", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8515" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8516", + "name": "Beer barrel", "examine": "A ready-to-assemble beer barrel.", - "durability": null, - "name": "Beer barrel", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8516" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8517", "name": "Beer barrel", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8517" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "16900", + "id": "8518", + "name": "Cider barrel", "examine": "A ready-to-assemble cider barrel.", - "durability": null, - "name": "Cider barrel", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8518" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "16900", - "durability": null, + "id": "8519", "name": "Cider barrel", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8519" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "3", - "ge_buy_limit": "100", + "id": "8520", + "name": "Asgarnian ale", "examine": "A ready-to-assemble barrel of Asgarnian Ale.", - "grand_exchange_price": "4586", - "durability": null, - "name": "Asgarnian ale", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8520" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "4586", - "durability": null, + "id": "8521", "name": "Asgarnian ale", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8521" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "2", - "ge_buy_limit": "100", + "id": "8522", + "name": "Greenman's ale", "examine": "A ready-to-assemble barrel of Greenman's Ale.", - "grand_exchange_price": "8875", - "durability": null, - "name": "Greenman's ale", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8522" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "8875", - "durability": null, - "name": "Greenman's ale", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8523" - }, - { "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "8523", + "name": "Greenman's ale", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8524", + "name": "Dragon bitter", "examine": "A ready-to-assemble barrel of Dragon Bitter.", - "grand_exchange_price": "10300", - "durability": null, - "name": "Dragon bitter", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "8524" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "10300", - "durability": null, + "id": "8525", "name": "Dragon bitter", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8525" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "8526", + "name": "Chef's delight", "examine": "A ready-to-assemble barrel of Chef's Delight.", - "grand_exchange_price": "48800", - "durability": null, - "name": "Chef's delight", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8526" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "48800", - "durability": null, + "id": "8527", "name": "Chef's delight", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8527" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8528", + "name": "Wood kitchen table", "examine": "A ready-to-assemble wooden kitchen table.", - "durability": null, - "name": "Wood kitchen table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8528" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8529", "name": "Wood kitchen table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8529" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8530", + "name": "Oak kitchen table", "examine": "A ready-to-assemble oak kitchen table.", - "durability": null, - "name": "Oak kitchen table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8530" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8531", "name": "Oak kitchen table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8531" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8532", + "name": "Teak kitchen table", "examine": "A ready-to-assemble teak kitchen table.", - "durability": null, - "name": "Teak kitchen table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8532" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, - "name": "Teak kitchen table", "tradeable": "true", - "archery_ticket_price": "0", - "id": "8533" + "weight": "1" }, { + "id": "8533", + "name": "Teak kitchen table", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8535", "name": "Oak lectern", "archery_ticket_price": "0", - "id": "8535" + "durability": null }, { - "durability": null, + "id": "8537", "name": "Eagle lectern", "archery_ticket_price": "0", - "id": "8537" + "durability": null }, { - "durability": null, + "id": "8539", "name": "Demon lectern", "archery_ticket_price": "0", - "id": "8539" + "durability": null }, { - "durability": null, + "id": "8541", "name": "Teak eagle lectern", "archery_ticket_price": "0", - "id": "8541" + "durability": null }, { - "durability": null, + "id": "8543", "name": "Teak demon lectern", "archery_ticket_price": "0", - "id": "8543" + "durability": null }, { - "durability": null, + "id": "8545", "name": "Mahogany eagle", "archery_ticket_price": "0", - "id": "8545" + "durability": null }, { - "durability": null, + "id": "8547", "name": "Mahogany demon", "archery_ticket_price": "0", - "id": "8547" + "durability": null }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8548", + "name": "Wood dining table", "examine": "A ready-to-assemble wooden dining table.", - "durability": null, - "name": "Wood dining table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8548" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8549", "name": "Wood dining table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8549" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8550", + "name": "Oak dining table", "examine": "A ready-to-assemble oak dining table.", - "durability": null, - "name": "Oak dining table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8550" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8551", "name": "Oak dining table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8551" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8552", + "name": "Carved oak table", "examine": "A ready-to-assemble carved oak dining table.", - "durability": null, - "name": "Carved oak table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8552" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8553", "name": "Carved oak table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8553" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2", + "id": "8554", + "name": "Teak table", "examine": "A ready-to-assemble teak dining table.", - "durability": null, - "name": "Teak table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8554" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2", - "durability": null, + "id": "8555", "name": "Teak table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8555" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "245", + "id": "8556", + "name": "Carved teak table", "examine": "A ready-to-assemble carved teak dining table.", - "durability": null, - "name": "Carved teak table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8556" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "245", - "durability": null, + "id": "8557", "name": "Carved teak table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8557" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "575", + "id": "8558", + "name": "Mahogany table", "examine": "A ready-to-assemble mahogany dining table.", - "durability": null, - "name": "Mahogany table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8558" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "575", - "durability": null, + "id": "8559", "name": "Mahogany table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8559" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "379100", + "id": "8560", + "name": "Opulent table", "examine": "A ready-to-assemble opulent dining table.", - "durability": null, - "name": "Opulent table", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8560" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "379100", - "durability": null, + "id": "8561", "name": "Opulent table", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8561" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "15", + "id": "8562", + "name": "Wooden bench", "examine": "A ready-to-assemble wooden dining bench.", - "durability": null, - "name": "Wooden bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8562" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "15", - "durability": null, + "id": "8563", "name": "Wooden bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8563" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "137", + "id": "8564", + "name": "Oak bench", "examine": "A ready-to-assemble oak dining bench.", - "durability": null, - "name": "Oak bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8564" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "137", - "durability": null, + "id": "8565", "name": "Oak bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8565" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8566", + "name": "Carved oak bench", "examine": "A ready-to-assemble carved oak dining bench.", - "durability": null, - "name": "Carved oak bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8566" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8567", "name": "Carved oak bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8567" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "18", + "id": "8568", + "name": "Teak dining bench", "examine": "A ready-to-assemble teak dining bench.", - "durability": null, - "name": "Teak dining bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8568" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "18", - "durability": null, + "id": "8569", "name": "Teak dining bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8569" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2", + "id": "8570", + "name": "Carved teak bench", "examine": "A ready-to-assemble carved teak dining bench.", - "durability": null, - "name": "Carved teak bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8570" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2", - "durability": null, + "id": "8571", "name": "Carved teak bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8571" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "126", + "id": "8572", + "name": "Mahogany bench", "examine": "A ready-to-assemble mahogany dining bench.", - "durability": null, - "name": "Mahogany bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8572" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "126", - "durability": null, + "id": "8573", "name": "Mahogany bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8573" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "517600", + "id": "8574", + "name": "Gilded bench", "examine": "A ready-to-assemble gilded mahogany dining bench.", - "durability": null, - "name": "Gilded bench", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8574" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "517600", - "durability": null, + "id": "8575", "name": "Gilded bench", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8575" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1974", + "id": "8576", + "name": "Wooden bed", "examine": "A ready-to-assemble wooden bed.", - "durability": null, - "name": "Wooden bed", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8576" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1974", - "durability": null, + "id": "8577", "name": "Wooden bed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8577" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1775", + "id": "8578", + "name": "Oak bed", "examine": "A ready-to-assemble oak bed.", - "durability": null, - "name": "Oak bed", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8578" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1775", - "durability": null, + "id": "8579", "name": "Oak bed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8579" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1433", + "id": "8580", + "name": "Large oak bed", "examine": "A ready-to-assemble large oak bed.", - "durability": null, - "name": "Large oak bed", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8580" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1433", - "durability": null, + "id": "8581", "name": "Large oak bed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8581" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1442", + "id": "8582", + "name": "Teak bed", "examine": "A ready-to-assemble teak bed.", - "durability": null, - "name": "Teak bed", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8582" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1442", - "durability": null, + "id": "8583", "name": "Teak bed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8583" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2030", + "id": "8584", + "name": "Large teak bed", "examine": "A ready-to-assemble large teak bed.", - "durability": null, - "name": "Large teak bed", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8584" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2030", - "durability": null, + "id": "8585", "name": "Large teak bed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8585" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1401", + "id": "8586", + "name": "4-poster", "examine": "A ready-to-assemble four-poster bed.", - "durability": null, - "name": "4-poster", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8586" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1401", - "durability": null, + "id": "8587", "name": "4-poster", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8587" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "286700", + "id": "8588", + "name": "Gilded 4-poster", "examine": "A ready-to-assemble gilded four-poster bed.", - "durability": null, - "name": "Gilded 4-poster", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8588" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "286700", - "durability": null, + "id": "8589", "name": "Gilded 4-poster", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8589" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "384", + "id": "8590", + "name": "Oak clock", "examine": "A ready-to-assemble oak clock.", - "durability": null, - "name": "Oak clock", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8590" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "384", - "durability": null, + "id": "8591", "name": "Oak clock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8591" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "595", + "id": "8592", + "name": "Teak clock", "examine": "A ready-to-assemble teak clock.", - "durability": null, - "name": "Teak clock", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8592" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "595", - "durability": null, + "id": "8593", "name": "Teak clock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8593" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "156100", + "id": "8594", + "name": "Gilded clock", "examine": "A ready-to-assemble gilded mahogany clock.", - "durability": null, - "name": "Gilded clock", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8594" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "156100", - "durability": null, + "id": "8595", "name": "Gilded clock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8595" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "510", + "id": "8596", + "name": "Shaving stand", "examine": "A ready-to-assemble shaving stand.", - "durability": null, - "name": "Shaving stand", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8596" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "510", - "durability": null, + "id": "8597", "name": "Shaving stand", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8597" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "455", + "id": "8598", + "name": "Oak shaving stand", "examine": "A ready-to-assemble oak shaving stand.", - "durability": null, - "name": "Oak shaving stand", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8598" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "455", - "durability": null, + "id": "8599", "name": "Oak shaving stand", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8599" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "147", + "id": "8600", + "name": "Oak dresser", "examine": "A ready-to-assemble oak dresser.", - "durability": null, - "name": "Oak dresser", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8600" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "147", - "durability": null, + "id": "8601", "name": "Oak dresser", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8601" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "478", + "id": "8602", + "name": "Teak dresser", "examine": "A ready-to-assemble teak dresser.", - "durability": null, - "name": "Teak dresser", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8602" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "478", - "durability": null, + "id": "8603", "name": "Teak dresser", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8603" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "455", + "id": "8604", + "name": "Fancy teak dresser", "examine": "A ready-to-assemble fancy teak dresser.", - "durability": null, - "name": "Fancy teak dresser", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8604" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "455", - "durability": null, + "id": "8605", "name": "Fancy teak dresser", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8605" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "399", + "id": "8606", + "name": "Mahogany dresser", "examine": "A ready-to-assemble mahogany dresser.", - "durability": null, - "name": "Mahogany dresser", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8606" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "399", - "durability": null, + "id": "8607", "name": "Mahogany dresser", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8607" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "138800", + "id": "8608", + "name": "Gilded dresser", "examine": "A ready-to-assemble gilded dresser.", - "durability": null, - "name": "Gilded dresser", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8608" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "138800", - "durability": null, + "id": "8609", "name": "Gilded dresser", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8609" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "21", + "id": "8610", + "name": "Shoe box", "examine": "A ready-to-assemble shoe box.", - "durability": null, - "name": "Shoe box", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8610" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "21", - "durability": null, + "id": "8611", "name": "Shoe box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8611" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "47", + "id": "8612", + "name": "Oak drawers", "examine": "A ready-to-assemble oak chest of drawers.", - "durability": null, - "name": "Oak drawers", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8612" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "47", - "durability": null, + "id": "8613", "name": "Oak drawers", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8613" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "8614", + "name": "Oak wardrobe", "examine": "A ready-to-assemble oak bedroom wardrobe.", - "durability": null, - "name": "Oak wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8614" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "8615", "name": "Oak wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8615" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "132", + "id": "8616", + "name": "Teak drawers", "examine": "A ready-to-assemble teak chest of drawers.", - "durability": null, - "name": "Teak drawers", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8616" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "132", - "durability": null, + "id": "8617", "name": "Teak drawers", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8617" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "13", + "id": "8618", + "name": "Teak wardrobe", "examine": "A ready-to-assemble teak bedroom wardrobe.", - "durability": null, - "name": "Teak wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8618" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "13", - "durability": null, + "id": "8619", "name": "Teak wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8619" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "98", + "id": "8620", + "name": "Mahogany 'drobe", "examine": "A ready-to-assemble mahogany bedroom wardrobe.", - "durability": null, - "name": "Mahogany 'drobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8620" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "98", - "durability": null, + "id": "8621", "name": "Mahogany 'drobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8621" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "137700", + "id": "8622", + "name": "Gilded wardrobe", "examine": "A ready-to-assemble gilded mahogany bedroom wardrobe.", - "durability": null, - "name": "Gilded wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "8622" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "137700", - "durability": null, - "name": "Gilded wardrobe", "tradeable": "true", - "archery_ticket_price": "0", - "id": "8623" + "weight": "1" }, { + "id": "8623", + "name": "Gilded wardrobe", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8625", "name": "Crystal ball", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8625" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8627", "name": "Elemental sphere", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8627" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8629", "name": "Crystal of power", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8629" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8631", "name": "Globe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8631" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8633", "name": "Ornamental globe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8633" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8635", "name": "Lunar globe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8635" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8637", "name": "Celestial globe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8637" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8639", "name": "Armillary sphere", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8639" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8641", "name": "Small orrery", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8641" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8643", "name": "Large orrery", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8643" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8645", "name": "Wooden telescope", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8645" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8647", "name": "Teak telescope", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8647" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8649", "name": "Mahogany 'scope", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8649" + "durability": null, + "tradeable": "true" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8650", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8652", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8654", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8656", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8658", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8660", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8662", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8664", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8666", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8668", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8670", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8672", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8674", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8676", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Banner", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8678", - "stand_turn_anim": "1426" - }, - { - "turn90cw_anim": "1424", - "walk_anim": "1422", - "durability": null, - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", "run_anim": "1427", - "archery_ticket_price": "0", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" + }, + { "id": "8680", - "stand_turn_anim": "1426" + "name": "Banner", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14" }, { - "remove_head": "true", - "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", "id": "8682", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8684", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8686", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8688", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8690", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8692", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8694", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8696", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8698", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8700", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8702", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8704", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8706", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8708", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8710", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" - }, - { "remove_head": "true", "requirements": "{1,5}", - "examine": "The colours represent crest.", - "durability": null, - "name": "Steel heraldic helm", - "weight": "2.7", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "8712", + "name": "Steel heraldic helm", + "examine": "The colours represent crest.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "requirements": "{1,5}", + "weight": "2.7" }, { - "requirements": "{1,40}", - "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", - "absorb": "3,0,7", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", "id": "8714", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8716", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8718", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8720", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8722", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8724", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8726", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8728", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8730", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8732", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8734", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8736", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8738", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8740", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8742", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "requirements": "{1,40}", + "name": "Rune kiteshield", "examine": "A large metal shield.", - "durability": null, - "weight": "5.4", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", "equipment_slot": "5", "lendable": "true", - "grand_exchange_price": "32583", - "name": "Rune kiteshield", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8744", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + "name": "Rune kiteshield", + "examine": "A large metal shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,5}", - "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", "id": "8746", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8748", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8750", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8752", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8754", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8756", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8758", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8760", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8762", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8764", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8766", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8768", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8770", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8772", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8774", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" - }, - { + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,5}", "shop_price": "850", - "examine": "A large metal shield.", - "grand_exchange_price": "346", - "durability": null, - "name": "Steel kiteshield", "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", + "weight": "5.4" + }, + { "id": "8776", + "name": "Steel kiteshield", + "examine": "A large metal shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,5}", + "shop_price": "850", + "tradeable": "true", + "weight": "5.4" }, { - "ge_buy_limit": "10000", + "id": "8778", + "name": "Oak plank", "examine": "A plank of sturdy oak.", - "grand_exchange_price": "660", - "durability": null, - "name": "Oak plank", - "tradeable": "true", - "weight": "0.8", "archery_ticket_price": "0", - "id": "8778" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.8" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "660", - "durability": null, + "id": "8779", "name": "Oak plank", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8779" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "500", - "ge_buy_limit": "10000", + "id": "8780", + "name": "Teak plank", "examine": "A plank of fine teak.", - "grand_exchange_price": "959", - "durability": null, - "name": "Teak plank", - "tradeable": "true", - "weight": "0.8", "archery_ticket_price": "0", - "id": "8780" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "500", + "tradeable": "true", + "weight": "0.8" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "959", - "durability": null, + "id": "8781", "name": "Teak plank", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8781" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "1500", - "ge_buy_limit": "10000", + "id": "8782", + "name": "Mahogany plank", "examine": "A plank of expensive mahogany.", - "grand_exchange_price": "2286", - "durability": null, - "name": "Mahogany plank", - "tradeable": "true", - "weight": "0.8", "archery_ticket_price": "0", - "id": "8782" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "2286", - "durability": null, + "shop_price": "1500", + "tradeable": "true", + "weight": "0.8" + }, + { + "id": "8783", "name": "Mahogany plank", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8783" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "shop_price": "130000", - "ge_buy_limit": "100", + "id": "8784", + "name": "Gold leaf", "examine": "A very delicate sheet of gold.", - "grand_exchange_price": "133800", - "durability": null, - "name": "Gold leaf", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "8784" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "130000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "133800", - "durability": null, + "id": "8785", "name": "Gold leaf", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8785" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "325000", - "ge_buy_limit": "100", + "id": "8786", + "name": "Marble block", "examine": "A beautifully carved marble block.", - "grand_exchange_price": "324800", - "durability": null, - "name": "Marble block", - "tradeable": "true", - "weight": "13.6", "archery_ticket_price": "0", - "id": "8786" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "325000", + "tradeable": "true", + "weight": "13.6" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "324800", - "durability": null, + "id": "8787", "name": "Marble block", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8787" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "975000", - "ge_buy_limit": "100", + "id": "8788", + "name": "Magic stone", "examine": "A magic stone to make high-level furniture.", - "grand_exchange_price": "980300", - "durability": null, - "name": "Magic stone", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "8788" + "durability": null, + "ge_buy_limit": "100", + "shop_price": "975000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "980300", - "durability": null, + "id": "8789", "name": "Magic stone", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8789" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "650", - "ge_buy_limit": "100", + "id": "8790", + "name": "Bolt of cloth", "examine": "A bolt of ordinary cloth.", - "grand_exchange_price": "1090", - "durability": null, - "name": "Bolt of cloth", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "8790" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "1090", - "durability": null, - "name": "Bolt of cloth", + "shop_price": "650", "tradeable": "true", - "archery_ticket_price": "0", - "id": "8791" + "weight": "1" }, { - "ge_buy_limit": "5000", + "id": "8791", + "name": "Bolt of cloth", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8792", + "name": "Clockwork", "examine": "A clockwork mechanism.", - "grand_exchange_price": "1630", - "durability": null, - "name": "Clockwork", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "8792" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "1630", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "8793", "name": "Clockwork", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8793" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "13", - "ge_buy_limit": "100", - "examine": "Good for cutting wood.", - "grand_exchange_price": "64", - "durability": null, - "name": "Saw", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "8794", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "64", - "durability": null, "name": "Saw", - "tradeable": "true", + "examine": "Good for cutting wood.", "archery_ticket_price": "0", - "id": "8795" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "shop_price": "13", + "tradeable": "true", + "weight": "1" }, { + "id": "8795", + "name": "Saw", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8836", "name": "Mahogany logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8836" + "durability": null, + "tradeable": "true" }, { - "shop_price": "1", - "ge_buy_limit": "1000", + "id": "8837", + "name": "Timber beam", "examine": "A hefty beam of timber, perfect for building temples.", - "grand_exchange_price": "29", - "durability": null, - "name": "Timber beam", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8837" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "29", - "durability": null, - "name": "Timber beam", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8838" + "shop_price": "1", + "tradeable": "true" }, { + "id": "8838", + "name": "Timber beam", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "8839", + "name": "Void knight top", + "examine": "Torso armour from the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,45,45,45,45,45,45,0,0,0,0", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", "shop_price": "250", - "examine": "Torso armour from the order of the Void Knights.", - "durability": null, - "name": "Void knight top", "tradeable": "false", - "weight": "6.5", - "archery_ticket_price": "0", - "id": "8839", - "bonuses": "0,0,0,0,0,45,45,45,45,45,45,0,0,0,0", - "equipment_slot": "4" + "weight": "6.5" }, { - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "250", - "examine": "Leg armour of the order of the Void Knights.", - "durability": null, - "name": "Void knight robe", - "tradeable": "false", - "weight": "8", - "archery_ticket_price": "0", "id": "8840", + "name": "Void knight robe", + "examine": "Leg armour of the order of the Void Knights.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,30,30,30,30,30,15,0,0,0,0", - "equipment_slot": "7" - }, - { + "durability": null, + "equipment_slot": "7", "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", "shop_price": "250", - "examine": "A mace used by the order of the Void Knights.", - "durability": null, - "weight": "1", - "attack_speed": "5", - "weapon_interface": "1", - "render_anim": "2553", - "equipment_slot": "3", - "attack_anims": "401,401,401,401", - "name": "Void knight mace", "tradeable": "false", - "archery_ticket_price": "0", - "id": "8841", - "bonuses": "22,0,41,8,0,2,2,2,2,2,0,38,6,0,0" + "weight": "8" }, { + "id": "8841", + "name": "Void knight mace", + "examine": "A mace used by the order of the Void Knights.", + "archery_ticket_price": "0", + "attack_anims": "401,401,401,401", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "22,0,41,8,0,2,2,2,2,2,0,38,6,0,0", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "render_anim": "2553", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "250", + "tradeable": "false", + "weapon_interface": "1", + "weight": "1" + }, + { + "id": "8842", + "name": "Void knight gloves", + "examine": "Gloves as used by the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "durability": null, + "equipment_slot": "9", "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", "shop_price": "150", - "examine": "Gloves as used by the order of the Void Knights.", - "durability": null, - "name": "Void knight gloves", "tradeable": "false", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "8842", - "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", - "equipment_slot": "9" + "weight": "0.5" }, { - "examine": "A defensive weapon.", - "durability": null, - "name": "Bronze defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8844", + "name": "Bronze defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "3,2,1,-3,-2,3,2,1,-3,-2,1,0,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "weight": "0.4" }, { - "examine": "A defensive weapon.", - "durability": null, - "name": "Iron defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8845", + "name": "Iron defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "5,4,3,-3,-2,5,4,3,-3,-2,2,0,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "weight": "0.4" }, { - "requirements": "{0,5}-{1,5}", - "examine": "A defensive weapon.", - "durability": null, - "name": "Steel defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8846", + "name": "Steel defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "7,6,5,-3,-2,7,6,5,-3,-2,3,1,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "requirements": "{0,5}-{1,5}", + "weight": "0.4" }, { - "requirements": "{0,10}-{1,10}", - "examine": "A defensive weapon.", - "durability": null, - "name": "Black defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8847", + "name": "Black defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "9,8,7,-3,-2,9,8,7,-3,-2,4,2,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "requirements": "{0,10}-{1,10}", + "weight": "0.4" }, { - "requirements": "{0,20}-{1,20}", - "examine": "A defensive weapon.", - "durability": null, - "name": "Mithril defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8848", + "name": "Mithril defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "10,9,8,-3,-2,10,9,8,-3,-2,5,3,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "requirements": "{0,20}-{1,20}", + "weight": "0.4" }, { - "requirements": "{0,30}-{1,30}", - "examine": "A defensive weapon.", - "durability": null, - "name": "Adamant defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8849", + "name": "Adamant defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "13,12,11,-3,-2,13,12,11,-3,-2,6,4,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "requirements": "{0,30}-{1,30}", + "weight": "0.4" }, { - "requirements": "{0,40}-{1,40}", - "examine": "A defensive weapon.", - "durability": null, - "name": "Rune defender", - "weight": "0.4", - "archery_ticket_price": "0", "id": "8850", + "name": "Rune defender", + "examine": "A defensive weapon.", + "archery_ticket_price": "0", "bonuses": "20,19,18,-3,-2,20,19,18,-3,-2,8,5,0,0,0", "defence_anim": "4177", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2238", + "equipment_slot": "5", + "requirements": "{0,40}-{1,40}", + "weight": "0.4" }, { - "examine": "Warrior Guild Token.", - "durability": null, + "id": "8851", "name": "Warrior guild token", + "examine": "Warrior Guild Token.", "archery_ticket_price": "0", - "id": "8851" + "durability": null }, { - "examine": "Large, round, heavy shield.", - "durability": null, - "name": "Defensive shield", - "weight": "3.6", - "archery_ticket_price": "0", - "two_handed": "false", "id": "8856", + "name": "Defensive shield", + "examine": "Large, round, heavy shield.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,8,9,7,0,8,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "two_handed": "false", + "weight": "3.6" }, { - "examine": "Just landed 18lb shot.", - "durability": null, + "id": "8858", "name": "18lb shot", - "destroy": "true", + "examine": "Just landed 18lb shot.", "archery_ticket_price": "0", - "id": "8858" + "destroy": "true", + "durability": null }, { - "examine": "Just landed 22lb shot.", - "durability": null, + "id": "8859", "name": "22lb shot", - "destroy": "true", + "examine": "Just landed 22lb shot.", "archery_ticket_price": "0", - "id": "8859" + "destroy": "true", + "durability": null }, { - "examine": "To put on your head.", - "durability": null, - "name": "One barrel", - "destroy": "true", - "weight": "4.5", - "archery_ticket_price": "0", "id": "8860", - "equipment_slot": "0" + "name": "One barrel", + "examine": "To put on your head.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "weight": "4.5" }, { - "examine": "To put on your head.", - "durability": null, - "name": "Two barrels", - "destroy": "true", - "weight": "9", - "archery_ticket_price": "0", "id": "8861", - "equipment_slot": "0" + "name": "Two barrels", + "examine": "To put on your head.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "weight": "9" }, { - "examine": "To put on your head.", - "durability": null, - "name": "Three barrels", - "destroy": "true", - "weight": "13.5", - "archery_ticket_price": "0", "id": "8862", - "equipment_slot": "0" + "name": "Three barrels", + "examine": "To put on your head.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "weight": "13.5" }, { - "examine": "To put on your head.", - "durability": null, - "name": "Four barrels", - "destroy": "true", - "weight": "18.1", - "archery_ticket_price": "0", "id": "8863", - "equipment_slot": "0" - }, - { + "name": "Four barrels", "examine": "To put on your head.", - "durability": null, - "name": "Five barrels", - "destroy": "true", - "weight": "22.6", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "weight": "18.1" + }, + { "id": "8864", - "equipment_slot": "0" - }, - { - "examine": "A heap of finely ground ashes.", - "durability": null, - "name": "Ground ashes", + "name": "Five barrels", + "examine": "To put on your head.", "archery_ticket_price": "0", - "id": "8865" - }, - { - "examine": "A key made of solid iron.", - "durability": null, - "name": "Iron key", - "archery_ticket_price": "0", - "id": "8869" - }, - { - "examine": "See article", - "durability": null, - "name": "Zanik", - "archery_ticket_price": "0", - "id": "8870" - }, - { - "turn90cw_anim": "4194", - "examine": "It's got Zanik in it.", - "walk_anim": "4194", - "durability": null, "destroy": "true", - "weight": "32", - "turn90ccw_anim": "4194", - "turn180_anim": "4194", - "render_anim": "822", - "equipment_slot": "3", - "stand_anim": "4193", - "name": "Crate with zanik", - "tradeable": "false", - "run_anim": "4194", + "durability": null, + "equipment_slot": "0", + "weight": "22.6" + }, + { + "id": "8865", + "name": "Ground ashes", + "examine": "A heap of finely ground ashes.", "archery_ticket_price": "0", + "durability": null + }, + { + "id": "8869", + "name": "Iron key", + "examine": "A key made of solid iron.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "8870", + "name": "Zanik", + "examine": "See article", + "archery_ticket_price": "0", + "durability": null + }, + { "id": "8871", - "stand_turn_anim": "4194" + "name": "Crate with zanik", + "examine": "It's got Zanik in it.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "render_anim": "822", + "run_anim": "4194", + "stand_anim": "4193", + "stand_turn_anim": "4194", + "tradeable": "false", + "turn180_anim": "4194", + "turn90ccw_anim": "4194", + "turn90cw_anim": "4194", + "walk_anim": "4194", + "weight": "32" }, { - "shop_price": "2000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,400,400", - "grand_exchange_price": "2855", - "attack_audios": "2517,2517,2500,2517", - "name": "Bone dagger", - "tradeable": "true", - "archery_ticket_price": "0", "id": "8872", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2855", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Bone dagger", - "tradeable": "true", + "examine": "A powerful dagger.", "archery_ticket_price": "0", - "id": "8873" + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", + "render_anim": "2584", + "shop_price": "2000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" }, { - "shop_price": "2000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,400,400", - "grand_exchange_price": "3033", - "attack_audios": "2517,2517,2500,2517", - "name": "Bone dagger (p)", - "tradeable": "true", + "id": "8873", + "name": "Bone dagger", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "8874", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3033", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Bone dagger (p)", - "tradeable": "true", + "examine": "A powerful dagger.", "archery_ticket_price": "0", - "id": "8875" + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", + "render_anim": "2584", + "shop_price": "2000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" }, { - "shop_price": "2000", - "ge_buy_limit": "100", - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "400,400,400,400", - "grand_exchange_price": "3523", - "attack_audios": "2517,2517,2500,2517", - "name": "Bone dagger (p+)", - "tradeable": "true", + "id": "8875", + "name": "Bone dagger (p)", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "8876", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3523", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Bone dagger (p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8877" - }, - { - "shop_price": "2000", - "ge_buy_limit": "100", "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "400,400,400,400", - "grand_exchange_price": "8337", "attack_audios": "2517,2517,2500,2517", - "name": "Bone dagger (p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8878", - "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8337", - "examine": "Swap this note at any bank for the equivalent item.", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "defence_anim": "378", "durability": null, - "name": "Bone dagger (p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8879" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "This fires crossbow bolts.", - "walk_anim": "4226", - "has_special": "true", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "4227", - "defence_anim": "424", + "equip_audio": "2248", "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "1159", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "8880", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,42,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,28}", - "shop_price": "2000", - "durability": null, - "weight": "2.2", - "weapon_interface": "17", - "render_anim": "175", - "attack_audios": "2700,0,0,0", - "name": "Dorgeshuun c'bow" - }, - { "ge_buy_limit": "100", - "grand_exchange_price": "1159", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dorgeshuun c'bow", + "has_special": "true", + "render_anim": "2584", + "shop_price": "2000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "8881" + "weapon_interface": "5", + "weight": "0.4" }, { + "id": "8877", + "name": "Bone dagger (p+)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8878", + "name": "Bone dagger (p++)", + "examine": "A powerful dagger.", + "archery_ticket_price": "0", + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0", + "defence_anim": "378", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", + "render_anim": "2584", + "shop_price": "2000", + "tradeable": "true", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "8879", + "name": "Bone dagger (p++)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8880", + "name": "Dorgeshuun c'bow", + "examine": "This fires crossbow bolts.", + "archery_ticket_price": "0", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,42,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", + "render_anim": "175", + "requirements": "{4,28}", + "run_anim": "4228", + "shop_price": "2000", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "2.2" + }, + { + "id": "8881", + "name": "Dorgeshuun c'bow", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "8882", + "name": "Bone bolts", + "examine": "Good if you have a bone crossbow!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,28}", "shop_price": "4", - "ge_buy_limit": "10000", - "examine": "Good if you have a bone crossbow!", - "grand_exchange_price": "12", - "durability": null, - "name": "Bone bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8882", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" + "tradeable": "true" }, { - "examine": "See article", - "durability": null, + "id": "8887", "name": "Zanik", + "examine": "See article", "archery_ticket_price": "0", - "id": "8887" + "durability": null }, { - "bankable": "false", - "examine": "Lovely money!", - "durability": null, + "id": "8890", "name": "Coins", + "examine": "Lovely money!", "archery_ticket_price": "0", - "id": "8890" + "bankable": "false", + "durability": null }, { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "durability": null, + "id": "8900", "name": "Cave horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", "archery_ticket_price": "0", - "id": "8900" + "durability": null }, { - "requirements": "{1,20}-{2,10}", - "ge_buy_limit": "10", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "989400", - "durability": null, - "name": "Black mask (10)", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", "id": "8901", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "989400", - "durability": null, "name": "Black mask (10)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8902" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (9)", - "tradeable": "true", - "weight": "10", + "id": "8902", + "name": "Black mask (10)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "8903", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (9)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8904" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (8)", - "tradeable": "true", - "weight": "10", + "id": "8904", + "name": "Black mask (9)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8905", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (8)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8906" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (7)", - "tradeable": "true", - "weight": "10", + "id": "8906", + "name": "Black mask (8)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8907", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (7)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8908" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (6)", - "tradeable": "true", - "weight": "10", + "id": "8908", + "name": "Black mask (7)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8909", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (6)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8910" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (5)", - "tradeable": "true", - "weight": "10", + "id": "8910", + "name": "Black mask (6)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8911", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (5)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8912" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (4)", - "tradeable": "true", - "weight": "10", + "id": "8912", + "name": "Black mask (5)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8913", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (4)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8914" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (3)", - "tradeable": "true", - "weight": "10", + "id": "8914", + "name": "Black mask (4)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8915", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (3)", - "tradeable": "true", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8916" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{1,20}-{2,10}", - "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (2)", - "tradeable": "true", - "weight": "10", + "id": "8916", + "name": "Black mask (3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8917", - "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, "name": "Black mask (2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8918" - }, - { - "requirements": "{1,20}-{2,10}", "examine": "A magic cave horror mask.", - "grand_exchange_price": "583700", - "durability": null, - "name": "Black mask (1)", - "tradeable": "true", - "weight": "10", "archery_ticket_price": "0", - "id": "8919", "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" - }, - { "durability": null, - "name": "Black mask (1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8920" - }, - { + "equipment_slot": "0", "requirements": "{1,20}-{2,10}", - "ge_buy_limit": "10", - "examine": "An inert-seeming cave horror mask.", - "grand_exchange_price": "956100", - "durability": null, - "name": "Black mask", "tradeable": "true", - "weight": "10", + "weight": "10" + }, + { + "id": "8918", + "name": "Black mask (2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8919", + "name": "Black mask (1)", + "examine": "A magic cave horror mask.", "archery_ticket_price": "0", - "id": "8921", "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "956100", + "id": "8920", + "name": "Black mask (1)", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "8921", "name": "Black mask", - "tradeable": "true", + "examine": "An inert-seeming cave horror mask.", "archery_ticket_price": "0", - "id": "8922" + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "requirements": "{1,20}-{2,10}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{18,35}", - "shop_price": "900", - "examine": "A stick on a string... pure style.", - "durability": null, - "name": "Witchwood icon", + "id": "8922", + "name": "Black mask", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "8923", + "name": "Witchwood icon", + "examine": "A stick on a string... pure style.", + "archery_ticket_price": "0", "bonuses": "0,0,0,1,0,0,0,0,0,0,0,0,1,0,0", - "equipment_slot": "2" + "durability": null, + "equipment_slot": "2", + "requirements": "{18,35}", + "shop_price": "900" }, { - "remove_head": "true", - "examine": "A white bandana and a patch for the right eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", "id": "8924", - "equipment_slot": "0" + "name": "Bandana and eyepatch", + "examine": "A white bandana and a patch for the right eye.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" }, { - "remove_head": "true", - "examine": "A red bandana and a patch for the right eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", "id": "8925", - "equipment_slot": "0" + "name": "Bandana and eyepatch", + "examine": "A red bandana and a patch for the right eye.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" }, { - "remove_head": "true", - "examine": "A blue bandana and a patch for the right eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", "id": "8926", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "examine": "A brown bandana and a patch for the right eye.", - "durability": null, "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", + "examine": "A blue bandana and a patch for the right eye.", "archery_ticket_price": "0", - "id": "8927", - "equipment_slot": "0" - }, - { - "examine": "A pirate hat and a patch for the right eye.", "durability": null, - "name": "Hat and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "8928", - "equipment_slot": "0" - }, - { - "shop_price": "800", - "examine": "Tied together so they don't come apart.", - "durability": null, - "name": "Crabclaw and hook", - "weight": "1", - "archery_ticket_price": "0", - "id": "8929", - "bonuses": "0,0,0,0,0,3,5,3,0,0,0,1,0,0,0", - "equipment_slot": "9" - }, - { - "examine": "Crude wooden pipe section.", - "durability": null, - "name": "Pipe section", - "weight": "1", - "archery_ticket_price": "0", - "id": "8930" - }, - { - "durability": null, - "name": "Pipe section", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8931" - }, - { - "examine": "Repairs made with this will be patchy at best.", - "durability": null, - "name": "Lumber patch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8932" - }, - { - "durability": null, - "name": "Lumber patch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8933" - }, - { - "examine": "Slimy logs from the scrapey tree.", - "durability": null, - "name": "Scrapey tree logs", - "archery_ticket_price": "0", - "id": "8934" - }, - { - "durability": null, - "name": "Scrapey tree logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8935" - }, - { - "examine": "Very blue.", - "durability": null, - "name": "Blue flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8936" - }, - { - "durability": null, - "name": "Blue flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8937" - }, - { - "examine": "Very red.", - "durability": null, - "name": "Red flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8938" - }, - { - "durability": null, - "name": "Red flowers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8939" - }, - { - "examine": "Bluuuuuuuue Monkeeeeeeey!", - "durability": null, - "name": "Blue monkey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8943" - }, - { - "examine": "Bluuuuuuuue Monkeeeeeeey!", - "durability": null, - "name": "Blue monkey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8944" - }, - { - "examine": "Bluuuuuuuue Monkeeeeeeey!", - "durability": null, - "name": "Blue monkey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8945" - }, - { - "examine": "A well red monkey.", - "durability": null, - "name": "Red monkey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8946" - }, - { - "examine": "A well red monkey.", - "durability": null, - "name": "Red monkey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8947" - }, - { - "examine": "A well red monkey.", - "durability": null, - "name": "Red monkey", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "8948" - }, - { + "equipment_slot": "0", "remove_head": "true", - "examine": "Essential pirate wear.", - "durability": null, - "name": "Pirate bandana", "tradeable": "true", - "weight": "0.1", + "weight": "0.1" + }, + { + "id": "8927", + "name": "Bandana and eyepatch", + "examine": "A brown bandana and a patch for the right eye.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "8928", + "name": "Hat and eyepatch", + "examine": "A pirate hat and a patch for the right eye.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "8929", + "name": "Crabclaw and hook", + "examine": "Tied together so they don't come apart.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,3,5,3,0,0,0,1,0,0,0", + "durability": null, + "equipment_slot": "9", + "shop_price": "800", + "weight": "1" + }, + { + "id": "8930", + "name": "Pipe section", + "examine": "Crude wooden pipe section.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "8931", + "name": "Pipe section", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8932", + "name": "Lumber patch", + "examine": "Repairs made with this will be patchy at best.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8933", + "name": "Lumber patch", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8934", + "name": "Scrapey tree logs", + "examine": "Slimy logs from the scrapey tree.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "8935", + "name": "Scrapey tree logs", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8936", + "name": "Blue flowers", + "examine": "Very blue.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8937", + "name": "Blue flowers", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8938", + "name": "Red flowers", + "examine": "Very red.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8939", + "name": "Red flowers", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8943", + "name": "Blue monkey", + "examine": "Bluuuuuuuue Monkeeeeeeey!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8944", + "name": "Blue monkey", + "examine": "Bluuuuuuuue Monkeeeeeeey!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8945", + "name": "Blue monkey", + "examine": "Bluuuuuuuue Monkeeeeeeey!", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8946", + "name": "Red monkey", + "examine": "A well red monkey.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8947", + "name": "Red monkey", + "examine": "A well red monkey.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "8948", + "name": "Red monkey", + "examine": "A well red monkey.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "8949", - "equipment_slot": "0" + "name": "Pirate bandana", + "examine": "Essential pirate wear.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "true", + "weight": "0.1" }, { - "examine": "Shiver me timbers!", - "grand_exchange_price": "83200", - "durability": null, - "name": "Pirate hat", - "tradeable": "true", - "archery_ticket_price": "0", "id": "8950", - "equipment_slot": "0" + "name": "Pirate hat", + "examine": "Shiver me timbers!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" }, { - "examine": "Piratical currency.", - "durability": null, + "id": "8951", "name": "Pieces of eight", + "examine": "Piratical currency.", "archery_ticket_price": "0", - "id": "8951" + "durability": null }, { - "remove_sleeves": "true", - "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Blue naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "8952", - "equipment_slot": "4" - }, - { + "name": "Blue naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Green naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "8953", - "equipment_slot": "4" - }, - { + "name": "Green naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Red naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "8954", - "equipment_slot": "4" - }, - { + "name": "Red naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Brown naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "8955", - "equipment_slot": "4" - }, - { + "name": "Brown naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Black naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "8956", - "equipment_slot": "4" - }, - { + "name": "Black naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Purple naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "8957", - "equipment_slot": "4" - }, - { + "name": "Purple naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Grey naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "8958", - "equipment_slot": "4" + "name": "Grey naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "100", + "tradeable": "false" }, { - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Blue tricorn hat", - "archery_ticket_price": "0", "id": "8959", - "equipment_slot": "0" + "name": "Blue tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" }, { - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Green tricorn hat", - "archery_ticket_price": "0", "id": "8960", - "equipment_slot": "0" + "name": "Green tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" }, { - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Red tricorn hat", - "archery_ticket_price": "0", "id": "8961", - "equipment_slot": "0" + "name": "Red tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" }, { - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Brown tricorn hat", - "archery_ticket_price": "0", "id": "8962", - "equipment_slot": "0" + "name": "Brown tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" }, { - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Black tricorn hat", - "archery_ticket_price": "0", "id": "8963", - "equipment_slot": "0" + "name": "Black tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" }, { - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Purple tricorn hat", - "archery_ticket_price": "0", "id": "8964", - "equipment_slot": "0" - }, - { - "shop_price": "50", + "name": "Purple tricorn hat", "examine": "I could never look square in this.", - "durability": null, - "name": "Grey tricorn hat", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" + }, + { "id": "8965", - "equipment_slot": "0" + "name": "Grey tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "shop_price": "50" }, { - "shop_price": "200", - "turn90cw_anim": "1424", - "examine": "The flag of The Cutthroat.", - "walk_anim": "1422", - "durability": null, - "weight": "6", - "turn90ccw_anim": "1425", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Cutthroat flag", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8966", - "stand_turn_anim": "1426" - }, - { + "name": "Cutthroat flag", + "examine": "The flag of The Cutthroat.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", "shop_price": "200", - "turn90cw_anim": "1424", - "examine": "The flag of The Guilded Smile.", - "walk_anim": "1422", - "durability": null, - "weight": "6", - "turn90ccw_anim": "1425", - "attack_speed": "2", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", "stand_anim": "1421", - "name": "Guilded smile flag", - "run_anim": "1427", - "archery_ticket_price": "0", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "6" + }, + { "id": "8967", - "stand_turn_anim": "1426" + "name": "Guilded smile flag", + "examine": "The flag of The Guilded Smile.", + "archery_ticket_price": "0", + "attack_speed": "2", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "shop_price": "200", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "6" }, { - "shop_price": "300", - "turn90cw_anim": "1424", - "examine": "The flag of The Bronze Fist.", - "walk_anim": "1422", - "durability": null, - "weight": "6", - "turn90ccw_anim": "1425", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Bronze fist flag", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8968", - "stand_turn_anim": "1426" + "name": "Bronze fist flag", + "examine": "The flag of The Bronze Fist.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "shop_price": "300", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "6" }, { - "shop_price": "400", - "turn90cw_anim": "1424", - "examine": "The flag of The Lucky Shot.", - "walk_anim": "1422", - "durability": null, - "weight": "6", - "turn90ccw_anim": "1425", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Lucky shot flag", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8969", - "stand_turn_anim": "1426" + "name": "Lucky shot flag", + "examine": "The flag of The Lucky Shot.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "shop_price": "400", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "6" }, { - "shop_price": "500", - "turn90cw_anim": "1424", - "examine": "The flag of The Treasure Trove.", - "walk_anim": "1422", - "durability": null, - "weight": "6", - "turn90ccw_anim": "1425", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", - "equipment_slot": "3", - "stand_anim": "1421", - "name": "Treasure flag", - "run_anim": "1427", - "archery_ticket_price": "0", "id": "8970", - "stand_turn_anim": "1426" - }, - { - "shop_price": "600", - "turn90cw_anim": "1424", - "examine": "The flag of The Phasmatys Pride.", - "walk_anim": "1422", + "name": "Treasure flag", + "examine": "The flag of The Treasure Trove.", + "archery_ticket_price": "0", "durability": null, - "weight": "6", - "turn90ccw_anim": "1425", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "1423", - "render_anim": "131", "equipment_slot": "3", - "stand_anim": "1421", - "name": "Phasmatys flag", + "render_anim": "131", "run_anim": "1427", - "archery_ticket_price": "0", + "shop_price": "500", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "6" + }, + { "id": "8971", - "stand_turn_anim": "1426" + "name": "Phasmatys flag", + "examine": "The flag of The Phasmatys Pride.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "131", + "run_anim": "1427", + "shop_price": "600", + "stand_anim": "1421", + "stand_turn_anim": "1426", + "turn180_anim": "1423", + "turn90ccw_anim": "1425", + "turn90cw_anim": "1424", + "two_handed": "true", + "walk_anim": "1422", + "weapon_interface": "14", + "weight": "6" }, { + "id": "8972", + "name": "Bowl of red water", "examine": "A Bowl of red water.", - "durability": null, - "name": "Bowl of red water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8972" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8973", "name": "Bowl of red water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8973" + "durability": null, + "tradeable": "true" }, { + "id": "8974", + "name": "Bowl of blue water", "examine": "A Bowl of blue water.", - "durability": null, - "name": "Bowl of blue water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8974" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8975", "name": "Bowl of blue water", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8975" + "durability": null, + "tradeable": "true" }, { - "examine": "Monkeys seem to like throwing these.", - "durability": null, + "id": "8976", "name": "Bitternut", + "examine": "Monkeys seem to like throwing these.", "archery_ticket_price": "0", - "id": "8976" + "durability": null }, { + "id": "8977", + "name": "Scrapey bark", "examine": "Greasy bark from the scrapey tree.", - "durability": null, - "name": "Scrapey bark", - "weight": "1.1", "archery_ticket_price": "0", - "id": "8977" + "durability": null, + "weight": "1.1" }, { - "durability": null, + "id": "8978", "name": "Scrapey bark", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8978" + "durability": null, + "tradeable": "true" }, { + "id": "8979", + "name": "Bridge section", "examine": "Caution; not for use over troubled water.", - "durability": null, - "name": "Bridge section", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8979" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8980", "name": "Bridge section", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8980" + "durability": null, + "tradeable": "true" }, { + "id": "8981", + "name": "Sweetgrubs", "examine": "Better than sea slugs.", - "durability": null, - "name": "Sweetgrubs", "archery_ticket_price": "0", - "id": "8981" + "durability": null }, { - "durability": null, + "id": "8982", "name": "Sweetgrubs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8982" + "durability": null, + "tradeable": "true" }, { - "shop_price": "2", - "examine": "It's an empty bucket.", - "grand_exchange_price": "50", - "durability": null, + "id": "8986", "name": "Bucket", - "tradeable": "true", - "weight": "1", + "examine": "It's an empty bucket.", "archery_ticket_price": "0", - "id": "8986" + "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "1" }, { - "durability": null, + "id": "8987", "name": "Torch", "archery_ticket_price": "0", - "id": "8987", + "durability": null, "equipment_slot": "3" }, { - "shop_price": "5", - "examine": "Apparently good for brewing.", - "durability": null, + "id": "8988", "name": "The stuff", - "weight": "0.5", + "examine": "Apparently good for brewing.", "archery_ticket_price": "0", - "id": "8988" + "durability": null, + "shop_price": "5", + "weight": "0.5" }, { - "examine": "A how-to of brewing and arson.", - "durability": null, + "id": "8989", "name": "Brewin' guide", - "archery_ticket_price": "0", - "id": "8989" - }, - { "examine": "A how-to of brewing and arson.", - "durability": null, - "name": "Brewin' guide", "archery_ticket_price": "0", - "id": "8990" + "durability": null }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Blue navy slacks", + "id": "8990", + "name": "Brewin' guide", + "examine": "A how-to of brewing and arson.", "archery_ticket_price": "0", + "durability": null + }, + { "id": "8991", - "equipment_slot": "7" + "name": "Blue navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Green navy slacks", - "archery_ticket_price": "0", "id": "8992", - "equipment_slot": "7" + "name": "Green navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Red navy slacks", - "archery_ticket_price": "0", "id": "8993", - "equipment_slot": "7" + "name": "Red navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Brown navy slacks", - "archery_ticket_price": "0", "id": "8994", - "equipment_slot": "7" + "name": "Brown navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Black navy slacks", - "archery_ticket_price": "0", "id": "8995", - "equipment_slot": "7" + "name": "Black navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Purple navy slacks", - "archery_ticket_price": "0", "id": "8996", - "equipment_slot": "7" - }, - { - "shop_price": "100", + "name": "Purple navy slacks", "examine": "Not for slackers", - "durability": null, - "name": "Grey navy slacks", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" + }, + { "id": "8997", - "equipment_slot": "7" - }, - { - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", + "name": "Grey navy slacks", + "examine": "Not for slackers", "archery_ticket_price": "0", - "id": "8998" + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "durability": null, + "id": "8998", "name": "Bandana and eyepatch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "8999" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "8999", "name": "Bandana and eyepatch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9000" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9000", "name": "Bandana and eyepatch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9001" + "durability": null, + "tradeable": "true" }, { + "id": "9001", + "name": "Bandana and eyepatch", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "9002", "name": "Hat and eyepatch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9002" + "durability": null, + "tradeable": "true" }, { - "shop_price": "2", - "ge_buy_limit": "100", + "id": "9003", + "name": "Security book", "examine": "WARNING: Contains information which could make your account secure!", - "grand_exchange_price": "100", - "durability": null, - "name": "Security book", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9003" - }, - { + "durability": null, "ge_buy_limit": "100", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "9004", + "name": "Stronghold notes", "examine": "Information regarding the Stronghold of Security.", - "grand_exchange_price": "16", - "durability": null, - "name": "Stronghold notes", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9004" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "destroy_message": "You can get another pair of Fancy Boots from the Stronghold of Security", - "examine": "Very nice boots from the Stronghold of Security.", - "durability": null, - "name": "Fancy boots", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "9005", - "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "destroy_message": "You can get another pair of Fighting Boots from the Stronghold of Security.", + "name": "Fancy boots", "examine": "Very nice boots from the Stronghold of Security.", - "durability": null, - "name": "Fighting boots", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "9006", "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", - "equipment_slot": "10" + "destroy": "true", + "destroy_message": "You can get another pair of Fancy Boots from the Stronghold of Security", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "tradeable": "false" }, { - "examine": "Ooooh spooky!", + "id": "9006", + "name": "Fighting boots", + "examine": "Very nice boots from the Stronghold of Security.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another pair of Fighting Boots from the Stronghold of Security.", "durability": null, + "equipment_slot": "10", + "tradeable": "false" + }, + { + "id": "9007", "name": "Right skull half", - "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "9007" - }, - { "examine": "Ooooh spooky!", + "archery_ticket_price": "0", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "9008", "name": "Left skull half", - "tradeable": "false", - "destroy": "true", - "weight": "4", + "examine": "Ooooh spooky!", "archery_ticket_price": "0", - "id": "9008" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "4" }, { - "examine": "Seems to be for use with a staff or sceptre of some sort.", - "durability": null, + "id": "9009", "name": "Strange skull", - "tradeable": "false", - "weight": "1.2", + "examine": "Seems to be for use with a staff or sceptre of some sort.", "archery_ticket_price": "0", - "id": "9009" + "durability": null, + "tradeable": "false", + "weight": "1.2" }, { - "examine": "Top half of a broken sceptre.", - "durability": null, + "id": "9010", "name": "Top of sceptre", - "tradeable": "false", - "weight": "2", + "examine": "Top half of a broken sceptre.", "archery_ticket_price": "0", - "id": "9010" + "durability": null, + "tradeable": "false", + "weight": "2" }, { - "examine": "Bottom half of a broken sceptre.", - "durability": null, + "id": "9011", "name": "Bottom of sceptre", - "tradeable": "false", - "weight": "1.8", + "examine": "Bottom half of a broken sceptre.", "archery_ticket_price": "0", - "id": "9011" + "durability": null, + "tradeable": "false", + "weight": "1.8" }, { - "examine": "Sceptre with runes on it, seems to be missing something.", - "durability": null, + "id": "9012", "name": "Runed sceptre", - "tradeable": "false", - "weight": "3.5", + "examine": "Sceptre with runes on it, seems to be missing something.", "archery_ticket_price": "0", - "id": "9012" + "durability": null, + "tradeable": "false", + "weight": "3.5" }, { - "turn90cw_anim": "1207", - "examine": "A fragile magical Sceptre.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "3", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "You can obtain another Sceptre by collecting all four pieces from the Stronghold of Security.", - "stand_anim": "813", - "name": "Skull sceptre", - "tradeable": "false", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "9013", + "name": "Skull sceptre", + "examine": "A fragile magical Sceptre.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "destroy": "true", + "destroy_message": "You can obtain another Sceptre by collecting all four pieces from the Stronghold of Security.", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "1.8" }, { - "durability": null, + "id": "9014", "name": "Security book", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9014" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9015", "name": "Stronghold notes", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9015" + "durability": null, + "tradeable": "true" }, { - "examine": "Oversized nail clippings.", - "durability": null, + "id": "9016", "name": "Gorak claws", + "examine": "Oversized nail clippings.", "archery_ticket_price": "0", - "id": "9016" + "durability": null }, { - "examine": "A flower with magical properties.", - "durability": null, + "id": "9017", "name": "Star flower", + "examine": "A flower with magical properties.", "archery_ticket_price": "0", - "id": "9017" + "durability": null }, { - "examine": "Ground-down gorak claws.", - "durability": null, + "id": "9018", "name": "Gorak claw powder", - "weight": "1", + "examine": "Ground-down gorak claws.", "archery_ticket_price": "0", - "id": "9018" + "durability": null, + "weight": "1" }, { - "examine": "Contains the Fairy Queen's magical essence.", - "durability": null, - "name": "Queen's secateurs", - "archery_ticket_price": "0", "id": "9020", + "name": "Queen's secateurs", + "examine": "Contains the Fairy Queen's magical essence.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "Maybe I can find another in Fairy Nuff's grotto.", - "examine": "A scroll that says she's a healer, that's Fairy Nuff.", - "durability": null, + "id": "9025", "name": "Nuff's certificate", - "tradeable": "false", - "destroy": "true", + "examine": "A scroll that says she's a healer, that's Fairy Nuff.", "archery_ticket_price": "0", - "id": "9025" + "destroy": "true", + "destroy_message": "Maybe I can find another in Fairy Nuff's grotto.", + "durability": null, + "tradeable": "false" }, { - "ge_buy_limit": "100", + "id": "9026", + "name": "Ivory comb", "examine": "Simon Templeton at the Agility Pyramid will give me 50 coins for this.", - "grand_exchange_price": "187", - "durability": null, - "name": "Ivory comb", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9026" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "187", - "durability": null, + "id": "9027", "name": "Ivory comb", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9027" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9028", + "name": "Golden scarab", "examine": "Simon Templeton at the Agility Pyramid will give me 1000 coins for this.", - "grand_exchange_price": "513", - "durability": null, - "name": "Golden scarab", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9028" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "513", - "durability": null, + "id": "9029", "name": "Golden scarab", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9029" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9030", + "name": "Stone scarab", "examine": "Little ornament in the shape of a scarab.", - "grand_exchange_price": "168", - "durability": null, - "name": "Stone scarab", - "tradeable": "true", - "weight": "0.07", "archery_ticket_price": "0", - "id": "9030" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.07" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "168", - "durability": null, + "id": "9031", "name": "Stone scarab", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9031" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9032", + "name": "Pottery scarab", "examine": "A small pottery scarab.", - "grand_exchange_price": "74", - "durability": null, - "name": "Pottery scarab", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9032" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "74", - "durability": null, + "id": "9033", "name": "Pottery scarab", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9033" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9034", + "name": "Golden statuette", "examine": "A small golden statuette.", - "grand_exchange_price": "740", - "durability": null, - "name": "Golden statuette", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9034" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "740", - "durability": null, + "id": "9035", "name": "Golden statuette", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9035" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9036", + "name": "Pottery statuette", "examine": "A small pottery statuette.", - "grand_exchange_price": "97", - "durability": null, - "name": "Pottery statuette", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "9036" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "97", - "durability": null, + "id": "9037", "name": "Pottery statuette", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9037" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9038", + "name": "Stone statuette", "examine": "A small stone statuette.", - "grand_exchange_price": "193", - "durability": null, - "name": "Stone statuette", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9038" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "193", - "durability": null, + "id": "9039", "name": "Stone statuette", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9039" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9040", + "name": "Gold seal", "examine": "Simon Templeton at the Agility Arena will give me 750 coins for this.", - "grand_exchange_price": "379", - "durability": null, - "name": "Gold seal", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9040" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "379", - "durability": null, + "id": "9041", "name": "Gold seal", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9041" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9042", + "name": "Stone seal", "examine": "Simon Templeton at the Agility Pyramid will give me 150 coins for this.", - "grand_exchange_price": "147", - "durability": null, - "name": "Stone seal", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9042" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "147", - "durability": null, + "tradeable": "true" + }, + { + "id": "9043", "name": "Stone seal", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9043" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{0,30}-{6,30}", - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "This sceptre is fully charged.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "3", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "1000000", - "stand_anim": "813", - "tradeable": "true", - "name": "Pharaoh's sceptre", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "9044", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1000000", - "durability": null, "name": "Pharaoh's sceptre", - "tradeable": "true", + "examine": "This sceptre is fully charged.", "archery_ticket_price": "0", - "id": "9045" - }, - { - "requirements": "{0,30}-{6,30}", - "turn90cw_anim": "1207", - "examine": "This sceptre has two charges left.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "2", - "turn90ccw_anim": "1208", "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "3", - "turn180_anim": "1206", - "render_anim": "28", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0", + "destroy": "true", + "durability": null, "equipment_slot": "3", - "grand_exchange_price": "27", - "stand_anim": "813", - "tradeable": "true", - "name": "Pharaoh's sceptre", + "ge_buy_limit": "10", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" + }, + { + "id": "9045", + "name": "Pharaoh's sceptre", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "9046", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" - }, - { - "durability": null, "name": "Pharaoh's sceptre", - "tradeable": "true", + "examine": "This sceptre has two charges left.", "archery_ticket_price": "0", - "id": "9047" - }, - { - "requirements": "{0,30}-{6,30}", - "turn90cw_anim": "1207", - "examine": "This sceptre has one charge left.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "2", - "turn90ccw_anim": "1208", "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "3", - "turn180_anim": "1206", - "render_anim": "28", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0", + "destroy": "true", + "durability": null, "equipment_slot": "3", - "grand_exchange_price": "27", - "stand_anim": "813", - "tradeable": "true", - "name": "Pharaoh's sceptre", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" + }, + { + "id": "9047", + "name": "Pharaoh's sceptre", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "9048", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" - }, - { - "durability": null, "name": "Pharaoh's sceptre", - "tradeable": "true", + "examine": "This sceptre has one charge left.", "archery_ticket_price": "0", - "id": "9049" - }, - { - "requirements": "{0,30}-{6,30}", - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "This sceptre has no charges left.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "2", - "turn90ccw_anim": "1208", "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "3", - "turn180_anim": "1206", - "render_anim": "28", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0", + "destroy": "true", + "durability": null, "equipment_slot": "3", - "grand_exchange_price": "985800", - "stand_anim": "813", - "tradeable": "true", - "name": "Pharaoh's sceptre", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", "run_anim": "1210", - "archery_ticket_price": "0", - "id": "9050", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "985800", - "durability": null, + "id": "9049", "name": "Pharaoh's sceptre", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9051" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9050", + "name": "Pharaoh's sceptre", + "examine": "This sceptre has no charges left.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "3", + "weight": "2" + }, + { + "id": "9051", + "name": "Pharaoh's sceptre", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "9052", + "name": "Locust meat", "examine": "Delicious and nutritious. Well, nutritious anyway.", - "grand_exchange_price": "68", - "durability": null, - "name": "Locust meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9052" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "68", - "durability": null, + "tradeable": "true" + }, + { + "id": "9053", "name": "Locust meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9053" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Red goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "9054", - "equipment_slot": "4" + "name": "Red goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Black goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "9055", - "equipment_slot": "4" + "name": "Black goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Yellow goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "9056", - "equipment_slot": "4" + "name": "Yellow goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Green goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "9057", - "equipment_slot": "4" + "name": "Green goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Purple goblin mail", - "weight": "3", - "archery_ticket_price": "0", "id": "9058", - "equipment_slot": "4" - }, - { + "name": "Purple goblin mail", "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "Pink goblin mail", - "weight": "3", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" + }, + { "id": "9059", - "equipment_slot": "4" + "name": "Pink goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "A mystical lantern casting a green beam.", - "durability": null, + "id": "9064", "name": "Emerald lantern", - "weight": "1.3", + "examine": "A mystical lantern casting a green beam.", "archery_ticket_price": "0", - "id": "9064" + "durability": null, + "weight": "1.3" }, { - "examine": "A mystical lantern casting a green beam.", - "durability": null, - "name": "Emerald lantern", - "weight": "1.3", - "archery_ticket_price": "0", "id": "9065", - "equipment_slot": "5" + "name": "Emerald lantern", + "examine": "A mystical lantern casting a green beam.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "weight": "1.3" }, { - "examine": "A roughly circular disc of glass.", - "durability": null, + "id": "9066", "name": "Emerald lens", + "examine": "A roughly circular disc of glass.", "archery_ticket_price": "0", - "id": "9066" + "durability": null }, { - "examine": "A log of my thoughts...", - "durability": null, + "id": "9067", "name": "Dream log", - "weight": "1", + "examine": "A log of my thoughts...", "archery_ticket_price": "0", - "id": "9067" + "durability": null, + "weight": "1" }, { - "shop_price": "1000", - "examine": "Mystical headgear.", - "durability": null, - "name": "Moonclan helm", - "archery_ticket_price": "0", "id": "9068", - "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "shop_price": "1000", - "examine": "A mystical hat.", - "durability": null, - "name": "Moonclan hat", - "weight": "1", + "name": "Moonclan helm", + "examine": "Mystical headgear.", "archery_ticket_price": "0", - "id": "9069", "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "shop_price": "1000" }, { + "id": "9069", + "name": "Moonclan hat", + "examine": "A mystical hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "shop_price": "1000", + "weight": "1" + }, + { + "id": "9070", + "name": "Moonclan armour", + "examine": "Provides good protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,-10,5,5,5,5,-10,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "1000", - "examine": "Provides good protection.", - "durability": null, - "name": "Moonclan armour", - "weight": "4", - "archery_ticket_price": "0", - "id": "9070", - "bonuses": "0,0,0,5,-10,5,5,5,5,-10,5,0,0,0,0", - "equipment_slot": "4" + "weight": "4" }, { - "shop_price": "1000", - "examine": "This should protect my legs.", - "durability": null, - "name": "Moonclan skirt", - "weight": "3", - "archery_ticket_price": "0", "id": "9071", + "name": "Moonclan skirt", + "examine": "This should protect my legs.", + "archery_ticket_price": "0", "bonuses": "0,0,0,5,-7,5,5,5,5,-7,0,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "shop_price": "1000", + "weight": "3" }, { - "shop_price": "900", - "examine": "These should keep my hands safe.", - "durability": null, - "name": "Moonclan gloves", - "archery_ticket_price": "0", "id": "9072", + "name": "Moonclan gloves", + "examine": "These should keep my hands safe.", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,-5,2,2,2,2,-5,2,0,0,0,0", - "equipment_slot": "9" + "durability": null, + "equipment_slot": "9", + "shop_price": "900" }, { - "shop_price": "900", - "examine": "Groovy foot protection.", - "durability": null, - "name": "Moonclan boots", - "archery_ticket_price": "0", "id": "9073", + "name": "Moonclan boots", + "examine": "Groovy foot protection.", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,-5,2,2,2,2,-5,0,0,0,0,0", - "equipment_slot": "10" + "durability": null, + "equipment_slot": "10", + "shop_price": "900" }, { - "shop_price": "200", - "examine": "A mystical cape.", - "durability": null, - "name": "Moonclan cape", - "archery_ticket_price": "0", "id": "9074", + "name": "Moonclan cape", + "examine": "A mystical cape.", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,-2,0,1,1,2,-2,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "shop_price": "200" }, { - "shop_price": "220", - "ge_buy_limit": "25000", - "examine": "Used for Lunar Spells", - "grand_exchange_price": "231", - "durability": null, + "id": "9075", "name": "Astral rune", - "tradeable": "true", + "examine": "Used for Lunar Spells", "archery_ticket_price": "0", - "id": "9075" + "durability": null, + "ge_buy_limit": "25000", + "shop_price": "220", + "tradeable": "true" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This needs refining", - "durability": null, + "id": "9076", "name": "Lunar ore", - "weight": "7", + "examine": "This needs refining", "archery_ticket_price": "0", - "id": "9076" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "7" }, { - "destroy_message": "You'll have to mine another lunar ore and smelt it.", - "examine": "It's a bar of magic metal.", - "durability": null, + "id": "9077", "name": "Lunar bar", - "tradeable": "false", - "destroy": "true", + "examine": "It's a bar of magic metal.", "archery_ticket_price": "0", - "id": "9077" + "destroy": "true", + "destroy_message": "You'll have to mine another lunar ore and smelt it.", + "durability": null, + "tradeable": "false" }, { - "examine": "A book of Moonclan history.", - "durability": null, + "id": "9078", "name": "Moonclan manual", - "weight": "1", + "examine": "A book of Moonclan history.", "archery_ticket_price": "0", - "id": "9078" + "durability": null, + "weight": "1" }, { - "examine": "The tooth, the whole tooth, and nothing but the tooth.", - "durability": null, + "id": "9079", "name": "Suqah tooth", + "examine": "The tooth, the whole tooth, and nothing but the tooth.", "archery_ticket_price": "0", - "id": "9079" + "durability": null }, { - "examine": "An untanned piece of suqah hide.", - "durability": null, + "id": "9080", "name": "Suqah hide", + "examine": "An untanned piece of suqah hide.", "archery_ticket_price": "0", - "id": "9080" + "durability": null }, { - "examine": "A piece of Suqah hide that has been expertly tanned into leather.", - "durability": null, + "id": "9081", "name": "Suqah leather", - "weight": "3", + "examine": "A piece of Suqah hide that has been expertly tanned into leather.", "archery_ticket_price": "0", - "id": "9081" + "durability": null, + "weight": "3" }, { - "examine": "A ground Suqah tooth.", - "durability": null, + "id": "9082", "name": "Ground tooth", + "examine": "A ground Suqah tooth.", "archery_ticket_price": "0", - "id": "9082" + "durability": null }, { - "destroy_message": "Brundt the Chieftain will probably have another lying around somewhere anyway...", - "examine": "A seal of passage issued by Brundt the Chieftain of the Fremennik.", - "durability": null, - "name": "Seal of passage", - "tradeable": "false", - "destroy": "true", - "weight": "4.5", - "archery_ticket_price": "0", "id": "9083", - "equipment_slot": "2" + "name": "Seal of passage", + "examine": "A seal of passage issued by Brundt the Chieftain of the Fremennik.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Brundt the Chieftain will probably have another lying around somewhere anyway...", + "durability": null, + "equipment_slot": "2", + "tradeable": "false", + "weight": "4.5" }, { - "requirements": "{6,65}", - "shop_price": "30000", - "turn90cw_anim": "1207", - "examine": "A Moonclan staff.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Lunar staff", - "tradeable": "false", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "9084", + "name": "Lunar staff", + "examine": "A Moonclan staff.", + "archery_ticket_price": "0", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "3,2,16,13,0,2,3,2,13,1,0,15,3,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{6,65}", + "run_anim": "1210", + "shop_price": "30000", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "3,2,16,13,0,2,3,2,13,1,0,15,3,0,0" + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" }, { - "destroy_message": "You'll have to get another from the Oneiromancer.", - "examine": "A vessel for holding liquid.", - "durability": null, + "id": "9085", "name": "Empty vial", - "destroy": "true", + "examine": "A vessel for holding liquid.", "archery_ticket_price": "0", - "id": "9085" + "destroy": "true", + "destroy_message": "You'll have to get another from the Oneiromancer.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "10", - "examine": "A glass vial containing water.", - "grand_exchange_price": "21", - "durability": null, + "id": "9086", "name": "Vial of water", + "examine": "A glass vial containing water.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "10", "tradeable": "true", - "weight": "0.02", - "archery_ticket_price": "0", - "id": "9086" + "weight": "0.02" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A vessel for dreaming while awake!", - "durability": null, + "id": "9087", "name": "Waking sleep vial", + "examine": "A vessel for dreaming while awake!", "archery_ticket_price": "0", - "id": "9087" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A vessel with water and Guam inside.", - "durability": null, + "id": "9088", "name": "Guam vial", + "examine": "A vessel with water and Guam inside.", "archery_ticket_price": "0", - "id": "9088" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A vessel with water and Marrentill inside.", - "durability": null, + "id": "9089", "name": "Marr vial", + "examine": "A vessel with water and Marrentill inside.", "archery_ticket_price": "0", - "id": "9089" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A vessel with water, guam and marrentill inside.", - "durability": null, + "id": "9090", "name": "Guam-marr vial", + "examine": "A vessel with water, guam and marrentill inside.", "archery_ticket_price": "0", - "id": "9090" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "requirements": "{6,65}", - "turn90cw_anim": "1207", - "examine": "A staff enchanted by air.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "1", - "turn90ccw_anim": "1208", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Lunar staff - pt1", - "tradeable": "false", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "9091", + "name": "Lunar staff - pt1", + "examine": "A staff enchanted by air.", + "archery_ticket_price": "0", + "attack_audios": "2555,0,0,0", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{6,65}", + "run_anim": "1210", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "1" }, { - "requirements": "{6,65}", - "turn90cw_anim": "1207", - "examine": "A staff enchanted by air and fire.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "1", - "turn90ccw_anim": "1208", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "name": "Lunar staff - pt2", - "tradeable": "false", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "9092", - "stand_turn_anim": "1209", - "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" - }, - { - "requirements": "{6,65}", - "turn90cw_anim": "1207", - "examine": "A staff enchanted by air, fire and water.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "weight": "1", - "turn90ccw_anim": "1208", - "weapon_interface": "1", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "813", + "name": "Lunar staff - pt2", + "examine": "A staff enchanted by air and fire.", + "archery_ticket_price": "0", "attack_audios": "2555,0,0,0", - "name": "Lunar staff - pt3", - "tradeable": "false", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{6,65}", "run_anim": "1210", - "archery_ticket_price": "0", - "id": "9093", + "stand_anim": "813", "stand_turn_anim": "1209", - "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "1" }, { - "examine": "Small bits of wood from the first magic tree!", + "id": "9093", + "name": "Lunar staff - pt3", + "examine": "A staff enchanted by air, fire and water.", + "archery_ticket_price": "0", + "attack_audios": "2555,0,0,0", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{6,65}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "1" + }, + { + "id": "9094", "name": "Kindling", + "examine": "Small bits of wood from the first magic tree!", "archery_ticket_price": "0", - "id": "9094" + "durability": null }, { - "examine": "Magic wood soaked with a potion of waking sleep. Groovy.", - "durability": null, + "id": "9095", "name": "Soaked kindling", + "examine": "Magic wood soaked with a potion of waking sleep. Groovy.", "archery_ticket_price": "0", - "id": "9095" + "durability": null }, { + "id": "9096", + "name": "Lunar helm", + "examine": "A mystical helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,40}-{6,65}", "shop_price": "15000", - "examine": "A mystical helmet.", - "durability": null, - "destroy": "true", - "weight": "0.9", - "absorb": "3,1,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar helm", "tradeable": "false", - "archery_ticket_price": "0", - "id": "9096", - "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0" + "weight": "0.9" }, { + "id": "9097", + "name": "Lunar torso", + "examine": "Provides good protection.", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,10,-10,34,22,40,12,0,35,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", "requirements": "{1,40}-{6,65}", "shop_price": "120000", - "examine": "Provides good protection.", - "durability": null, - "destroy": "true", - "weight": "4.5", - "absorb": "6,3,0", - "equipment_slot": "4", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "remove_sleeves": "true", - "name": "Lunar torso", "tradeable": "false", - "archery_ticket_price": "0", - "id": "9097", - "bonuses": "0,0,0,10,-10,34,22,40,12,0,35,0,0,0,0" + "weight": "4.5" }, { + "id": "9098", + "name": "Lunar legs", + "examine": "These should protect my legs.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,-7,20,19,23,9,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "7", "requirements": "{1,40}-{6,65}", "shop_price": "80000", - "examine": "These should protect my legs.", - "durability": null, - "destroy": "true", - "weight": "3.65", - "absorb": "4,2,0", - "equipment_slot": "7", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar legs", "tradeable": "false", - "archery_ticket_price": "0", - "id": "9098", - "bonuses": "0,0,0,7,-7,20,19,23,9,0,20,0,0,0,0" + "weight": "3.65" }, { - "requirements": "{1,40}-{6,65}", - "shop_price": "10000", - "examine": "These should keep my hands safe.", - "durability": null, - "destroy": "true", - "weight": "0.9", - "equipment_slot": "9", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar gloves", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9099", - "bonuses": "0,0,0,4,-1,2,1,1,2,0,1,0,0,0,0" - }, - { + "name": "Lunar gloves", + "examine": "These should keep my hands safe.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,-1,2,1,1,2,0,1,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "9", "requirements": "{1,40}-{6,65}", "shop_price": "10000", - "examine": "Mystical foot protection.", - "durability": null, - "destroy": "true", - "weight": "0.9", - "equipment_slot": "10", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar boots", "tradeable": "false", - "archery_ticket_price": "0", - "id": "9100", - "bonuses": "0,0,0,2,-1,1,2,2,2,0,2,0,0,0,0" + "weight": "0.9" }, { + "id": "9100", + "name": "Lunar boots", + "examine": "Mystical foot protection.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,-1,1,2,2,2,0,2,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "10", + "requirements": "{1,40}-{6,65}", + "shop_price": "10000", + "tradeable": "false", + "weight": "0.9" + }, + { + "id": "9101", + "name": "Lunar cape", + "examine": "Oooo pretty!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "1", "requirements": "{1,40}-{6,65}", "shop_price": "12000", - "examine": "Oooo pretty!", - "durability": null, - "destroy": "true", - "weight": "0.4", - "equipment_slot": "1", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar cape", "tradeable": "false", - "archery_ticket_price": "0", - "id": "9101", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0" + "weight": "0.4" }, { + "id": "9102", + "name": "Lunar amulet", + "examine": "Awesome.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "destroy": "true", "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "2", "requirements": "{1,40}-{6,65}", "shop_price": "4000", - "examine": "Awesome.", - "durability": null, - "name": "Lunar amulet", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9102", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "2" + "tradeable": "false" }, { - "destroy_message": "The Oneiromancer might be able to help you get another.", - "examine": "I'll be the talk of the town with this... maybe.", - "durability": null, + "id": "9103", "name": "A special tiara", - "tradeable": "false", - "destroy": "true", + "examine": "I'll be the talk of the town with this... maybe.", "archery_ticket_price": "0", - "id": "9103" + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "tradeable": "false" }, { + "id": "9104", + "name": "Lunar ring", + "examine": "A mysterious ring that can fill the wearer with magical power.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "destroy": "true", "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "12", "requirements": "{1,40}-{6,65}", "shop_price": "2000", - "examine": "A mysterious ring that can fill the wearer with magical power.", - "durability": null, - "name": "Lunar ring", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9104", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", - "equipment_slot": "12" + "tradeable": "false" }, { - "durability": null, + "id": "9106", "name": "Astral tiara", "archery_ticket_price": "0", - "id": "9106", + "durability": null, "equipment_slot": "0" }, { - "requirements": "{4,16}", - "examine": "Blurite crossbow bolts.", - "durability": null, - "name": "Blurite bolts", - "archery_ticket_price": "0", "id": "9139", + "name": "Blurite bolts", + "examine": "Blurite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "requirements": "{4,16}" }, { + "id": "9140", + "name": "Iron bolts", + "examine": "Iron crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,26}", "shop_price": "60", - "ge_buy_limit": "25000", - "examine": "Iron crossbow bolts.", - "grand_exchange_price": "41", - "durability": null, - "name": "Iron bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9140", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", - "equipment_slot": "13" + "tradeable": "true" }, { + "id": "9141", + "name": "Steel bolts", + "examine": "Steel crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,31}", "shop_price": "150", - "ge_buy_limit": "10000", - "examine": "Steel crossbow bolts.", - "grand_exchange_price": "90", - "durability": null, - "name": "Steel bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9141", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", - "equipment_slot": "13" + "tradeable": "true" }, { + "id": "9142", + "name": "Mithril bolts", + "examine": "Mithril crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,36}", "shop_price": "32", - "ge_buy_limit": "10000", - "examine": "Mithril crossbow bolts.", - "grand_exchange_price": "108", - "durability": null, - "name": "Mithril bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9142", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", - "equipment_slot": "13" + "tradeable": "true" }, { + "id": "9143", + "name": "Adamant bolts", + "examine": "Adamantite crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,46}", "shop_price": "23", - "ge_buy_limit": "10000", - "examine": "Adamantite crossbow bolts.", - "grand_exchange_price": "210", - "durability": null, - "name": "Adamant bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9143", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,61}", - "ge_buy_limit": "10000", - "examine": "Runite crossbow bolts.", - "grand_exchange_price": "627", - "durability": null, - "name": "Rune bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9144", + "name": "Rune bolts", + "examine": "Runite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,61}", + "tradeable": "true" }, { + "id": "9145", + "name": "Silver bolts", + "examine": "Silver crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,26}", "shop_price": "6", - "ge_buy_limit": "10000", - "examine": "Silver crossbow bolts.", - "grand_exchange_price": "8", - "durability": null, - "name": "Silver bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9145", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", - "equipment_slot": "13" + "tradeable": "true" }, { - "ge_buy_limit": "500", - "turn90cw_anim": "821", - "examine": "A bronze crossbow.", - "walk_anim": "4226", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "4227", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "29", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", "id": "9174", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,0", - "shop_price": "92", - "durability": null, - "weight": "4", - "weapon_interface": "17", - "render_anim": "175", - "attack_audios": "2700,0,0,0", - "name": "Bronze crossbow" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "29", - "durability": null, "name": "Bronze crossbow", - "tradeable": "true", + "examine": "A bronze crossbow.", "archery_ticket_price": "0", - "id": "9175" + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "500", + "render_anim": "175", + "run_anim": "4228", + "shop_price": "92", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "4" }, { - "requirements": "{4,16}", - "turn90cw_anim": "821", - "examine": "A blurite crossbow.", - "walk_anim": "4226", - "durability": null, - "weight": "4", - "turn90ccw_anim": "822", - "attack_speed": "6", - "weapon_interface": "17", - "turn180_anim": "4227", - "render_anim": "175", - "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "stand_anim": "4591", - "attack_audios": "2700,0,0,0", - "name": "Blurite crossbow", - "run_anim": "4228", + "id": "9175", + "name": "Bronze crossbow", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { "id": "9176", + "name": "Blurite crossbow", + "examine": "A blurite crossbow.", + "archery_ticket_price": "0", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,30,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "175", + "requirements": "{4,16}", + "run_anim": "4228", + "stand_anim": "4591", "stand_turn_anim": "823", - "bonuses": "0,0,0,0,30,0,0,0,0,0,0,0,0,0,0" + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "4" }, { - "ge_buy_limit": "500", - "turn90cw_anim": "821", - "examine": "An iron crossbow.", - "walk_anim": "4226", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "4227", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "20", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", "id": "9177", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,42,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,26}", - "shop_price": "157", - "durability": null, - "weight": "4", - "weapon_interface": "17", - "render_anim": "175", - "attack_audios": "2700,0,0,0", - "name": "Iron crossbow" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "20", - "durability": null, "name": "Iron crossbow", - "tradeable": "true", + "examine": "An iron crossbow.", "archery_ticket_price": "0", - "id": "9178" - }, - { - "ge_buy_limit": "500", - "turn90cw_anim": "821", - "examine": "A steel crossbow.", - "walk_anim": "4226", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "4227", - "defence_anim": "424", - "equipment_slot": "3", "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "99", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "9179", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,54,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,31}", - "durability": null, - "weight": "5", - "weapon_interface": "17", - "render_anim": "175", "attack_audios": "2700,0,0,0", - "name": "Steel crossbow" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "99", - "durability": null, - "name": "Steel crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9180" - }, - { - "ge_buy_limit": "500", - "turn90cw_anim": "821", - "examine": "A mithril crossbow", - "walk_anim": "4226", - "turn90ccw_anim": "822", "attack_speed": "6", - "turn180_anim": "4227", + "bonuses": "0,0,0,0,42,0,0,0,0,0,0,0,0,0,0", "defence_anim": "424", + "durability": null, + "equip_audio": "2244", "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "355", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "9181", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,66,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,36}", - "durability": null, - "weight": "6", - "weapon_interface": "17", + "ge_buy_limit": "500", "render_anim": "175", - "attack_audios": "2700,0,0,0", - "name": "Mith crossbow" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "355", - "durability": null, - "name": "Mith crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9182" - }, - { - "ge_buy_limit": "500", - "turn90cw_anim": "821", - "examine": "An adamantite crossbow.", - "walk_anim": "4226", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "4227", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "905", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "9183", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,78,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,46}", - "shop_price": "2244", - "durability": null, - "weight": "6", - "weapon_interface": "17", - "render_anim": "175", - "attack_audios": "2700,0,0,0", - "name": "Adamant crossbow" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "905", - "durability": null, - "name": "Adamant crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9184" - }, - { - "ge_buy_limit": "500", - "turn90cw_anim": "821", - "examine": "A runite crossbow.", - "walk_anim": "4226", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "4227", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "4230,4230,4230,4230", - "grand_exchange_price": "9706", - "stand_anim": "4591", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "9185", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,61}", - "shop_price": "16200", - "durability": null, - "weight": "6", - "weapon_interface": "17", - "render_anim": "175", - "lendable": "true", - "attack_audios": "2700,0,0,0", - "name": "Rune crossbow" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "9706", - "durability": null, - "name": "Rune crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9186" - }, - { - "ge_buy_limit": "10000", - "examine": "Jade bolt tips.", - "grand_exchange_price": "2", - "durability": null, - "name": "Jade bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9187" - }, - { - "ge_buy_limit": "10000", - "examine": "Red Topaz bolt tips.", - "grand_exchange_price": "2", - "durability": null, - "name": "Topaz bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9188" - }, - { - "ge_buy_limit": "10000", - "examine": "Sapphire bolt tips.", - "grand_exchange_price": "4", - "durability": null, - "name": "Sapphire bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9189" - }, - { - "ge_buy_limit": "10000", - "examine": "Emerald bolt tips.", - "grand_exchange_price": "84", - "durability": null, - "name": "Emerald bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9190" - }, - { - "ge_buy_limit": "10000", - "examine": "Ruby bolt tips.", - "grand_exchange_price": "159", - "durability": null, - "name": "Ruby bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9191" - }, - { - "ge_buy_limit": "10000", - "examine": "Diamond bolt tips.", - "grand_exchange_price": "1289", - "durability": null, - "name": "Diamond bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9192" - }, - { - "ge_buy_limit": "10000", - "examine": "Dragonstone bolt tips.", - "grand_exchange_price": "2477", - "durability": null, - "name": "Dragon bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9193" - }, - { - "shop_price": "13500", - "ge_buy_limit": "10000", - "examine": "Onyx bolt tips.", - "grand_exchange_price": "8096", - "tokkul_price": "1500", - "durability": null, - "name": "Onyx bolt tips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9194" - }, - { - "ge_buy_limit": "25000", - "examine": "Enchanted Opal tipped Bronze Crossbow Bolts.", - "grand_exchange_price": "10", - "durability": null, - "name": "Opal bolts (e)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9236", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,14", - "equipment_slot": "13" - }, - { - "requirements": "{4,15}", - "examine": "Enchanted Jade tipped Blurite Crossbow Bolts.", - "durability": null, - "name": "Jade bolts (e)", - "archery_ticket_price": "0", - "id": "9237", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", - "equipment_slot": "13" - }, - { "requirements": "{4,26}", - "ge_buy_limit": "25000", - "examine": "Enchanted Pearl tipped Iron Crossbow Bolts.", - "grand_exchange_price": "36", - "durability": null, - "name": "Pearl bolts (e)", + "run_anim": "4228", + "shop_price": "157", + "stand_anim": "4591", + "stand_turn_anim": "823", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9238", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,48", - "equipment_slot": "13" + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "4" }, { + "id": "9178", + "name": "Iron crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9179", + "name": "Steel crossbow", + "examine": "A steel crossbow.", + "archery_ticket_price": "0", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,54,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "500", + "render_anim": "175", "requirements": "{4,31}", - "ge_buy_limit": "25000", - "examine": "Enchanted Red Topaz tipped Steel Crossbow Bolts.", - "grand_exchange_price": "44", - "durability": null, - "name": "Topaz bolts (e)", + "run_anim": "4228", + "stand_anim": "4591", + "stand_turn_anim": "823", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9239", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,66", - "equipment_slot": "13" + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "5" }, { + "id": "9180", + "name": "Steel crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9181", + "name": "Mith crossbow", + "examine": "A mithril crossbow", + "archery_ticket_price": "0", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,66,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "500", + "render_anim": "175", + "requirements": "{4,36}", + "run_anim": "4228", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "6" + }, + { + "id": "9182", + "name": "Mith crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9183", + "name": "Adamant crossbow", + "examine": "An adamantite crossbow.", + "archery_ticket_price": "0", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,78,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "500", + "render_anim": "175", + "requirements": "{4,46}", + "run_anim": "4228", + "shop_price": "2244", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "6" + }, + { + "id": "9184", + "name": "Adamant crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9185", + "name": "Rune crossbow", + "examine": "A runite crossbow.", + "archery_ticket_price": "0", + "attack_anims": "4230,4230,4230,4230", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "500", + "lendable": "true", + "render_anim": "175", + "requirements": "{4,61}", + "run_anim": "4228", + "shop_price": "16200", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "6" + }, + { + "id": "9186", + "name": "Rune crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9187", + "name": "Jade bolt tips", + "examine": "Jade bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9188", + "name": "Topaz bolt tips", + "examine": "Red Topaz bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9189", + "name": "Sapphire bolt tips", + "examine": "Sapphire bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9190", + "name": "Emerald bolt tips", + "examine": "Emerald bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9191", + "name": "Ruby bolt tips", + "examine": "Ruby bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9192", + "name": "Diamond bolt tips", + "examine": "Diamond bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9193", + "name": "Dragon bolt tips", + "examine": "Dragonstone bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9194", + "name": "Onyx bolt tips", + "examine": "Onyx bolt tips.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "13500", + "tokkul_price": "1500", + "tradeable": "true" + }, + { + "id": "9236", + "name": "Opal bolts (e)", + "examine": "Enchanted Opal tipped Bronze Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,14", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "9237", + "name": "Jade bolts (e)", + "examine": "Enchanted Jade tipped Blurite Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", + "durability": null, + "equipment_slot": "13", + "requirements": "{4,15}" + }, + { + "id": "9238", + "name": "Pearl bolts (e)", + "examine": "Enchanted Pearl tipped Iron Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,48", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,26}", + "tradeable": "true" + }, + { + "id": "9239", + "name": "Topaz bolts (e)", + "examine": "Enchanted Red Topaz tipped Steel Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,66", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,31}", + "tradeable": "true" + }, + { + "id": "9240", + "name": "Sapphire bolts (e)", + "examine": "Enchanted Sapphire tipped Mithril Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,83", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,36}", "shop_price": "103", - "ge_buy_limit": "25000", - "examine": "Enchanted Sapphire tipped Mithril Crossbow Bolts.", - "grand_exchange_price": "95", - "durability": null, - "name": "Sapphire bolts (e)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9240", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,83", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,36}", - "ge_buy_limit": "25000", - "examine": "Enchanted Emerald tipped Mithril Crossbow Bolts.", - "grand_exchange_price": "304", - "durability": null, - "name": "Emerald bolts (e)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9241", + "name": "Emerald bolts (e)", + "examine": "Enchanted Emerald tipped Mithril Crossbow Bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,85", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,36}", + "tradeable": "true" }, { - "requirements": "{4,46}", - "ge_buy_limit": "25000", - "examine": "Enchanted Ruby tipped Adamantite Crossbow Bolts.", - "grand_exchange_price": "450", - "durability": null, - "name": "Ruby bolts (e)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9242", + "name": "Ruby bolts (e)", + "examine": "Enchanted Ruby tipped Adamantite Crossbow Bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,103", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,46}", - "ge_buy_limit": "25000", - "examine": "Enchanted Diamond tipped Adamantite Crossbow Bolts.", - "grand_exchange_price": "1631", - "durability": null, - "name": "Diamond bolts (e)", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "9243", + "name": "Diamond bolts (e)", + "examine": "Enchanted Diamond tipped Adamantite Crossbow Bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,105", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,46}", + "tradeable": "true" }, { - "requirements": "{4,61}", - "ge_buy_limit": "25000", - "examine": "Enchanted Dragonstone tipped Runite Crossbow Bolts.", - "grand_exchange_price": "3217", - "durability": null, - "name": "Dragon bolts (e)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9244", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,117", - "equipment_slot": "13" - }, - { - "requirements": "{4,61}", - "ge_buy_limit": "25000", - "examine": "Enchanted Onyx tipped runite Crossbow Bolts.", - "grand_exchange_price": "8870", - "durability": null, - "name": "Onyx bolts (e)", - "tradeable": "true", + "name": "Dragon bolts (e)", + "examine": "Enchanted Dragonstone tipped Runite Crossbow Bolts.", "archery_ticket_price": "0", - "id": "9245", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,120", - "equipment_slot": "13" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,117", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,61}", + "tradeable": "true" }, { - "requirements": "{4,16}", + "id": "9245", + "name": "Onyx bolts (e)", + "examine": "Enchanted Onyx tipped runite Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,120", "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,61}", + "tradeable": "true" + }, + { + "id": "9286", "name": "Blurite bolts(p)", "archery_ticket_price": "0", - "id": "9286", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "requirements": "{4,16}" }, { + "id": "9287", + "name": "Iron bolts (p)", + "examine": "Iron crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,26}", "shop_price": "60", - "ge_buy_limit": "25000", - "examine": "Iron crossbow bolts.", - "grand_exchange_price": "88", - "durability": null, - "name": "Iron bolts (p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9287", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,31}", - "ge_buy_limit": "10000", - "examine": "Steel crossbow bolts.", - "grand_exchange_price": "132", - "durability": null, - "name": "Steel bolts (p)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9288", + "name": "Steel bolts (p)", + "examine": "Steel crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,31}", + "tradeable": "true" }, { + "id": "9289", + "name": "Mithril bolts (p)", + "examine": "Mithril crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,36}", "shop_price": "32", - "ge_buy_limit": "10000", - "examine": "Mithril crossbow bolts.", - "grand_exchange_price": "146", - "durability": null, - "name": "Mithril bolts (p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9289", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", - "equipment_slot": "13" + "tradeable": "true" }, { + "id": "9290", + "name": "Adamant bolts (p)", + "examine": "Adamantite crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,46}", "shop_price": "23", - "ge_buy_limit": "10000", - "examine": "Adamantite crossbow bolts.", - "grand_exchange_price": "302", - "durability": null, - "name": "Adamant bolts (p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9290", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,61}", - "ge_buy_limit": "10000", - "examine": "Runite crossbow bolts.", - "grand_exchange_price": "734", - "durability": null, - "name": "Runite bolts (p)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9291", + "name": "Runite bolts (p)", + "examine": "Runite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,61}", + "tradeable": "true" }, { + "id": "9292", + "name": "Silver bolts (p)", + "examine": "Silver crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,26}", "shop_price": "6", - "ge_buy_limit": "10000", - "examine": "Silver crossbow bolts.", - "grand_exchange_price": "34", - "durability": null, - "name": "Silver bolts (p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9292", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,16}", - "durability": null, + "id": "9293", "name": "Blurite bolts(p+)", "archery_ticket_price": "0", - "id": "9293", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "requirements": "{4,16}" }, { + "id": "9294", + "name": "Iron bolts(p+)", + "examine": "Iron crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,26}", "shop_price": "60", - "ge_buy_limit": "25000", - "examine": "Iron crossbow bolts.", - "grand_exchange_price": "185", - "durability": null, - "name": "Iron bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9294", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,31}", - "ge_buy_limit": "10000", - "examine": "Steel crossbow bolts.", - "grand_exchange_price": "215", - "durability": null, - "name": "Steel bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9295", + "name": "Steel bolts(p+)", + "examine": "Steel crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,31}", + "tradeable": "true" }, { + "id": "9296", + "name": "Mithril bolts(p+)", + "examine": "Mithril crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,36}", "shop_price": "32", - "ge_buy_limit": "10000", - "examine": "Mithril crossbow bolts.", - "grand_exchange_price": "296", - "durability": null, - "name": "Mithril bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9296", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,46}", - "ge_buy_limit": "10000", - "grand_exchange_price": "472", - "durability": null, + "id": "9297", "name": "Adamant bolts(p+)", "archery_ticket_price": "0", - "id": "9297", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", - "equipment_slot": "13" - }, - { - "requirements": "{4,61}", - "ge_buy_limit": "10000", - "examine": "Runite crossbow bolts.", - "grand_exchange_price": "1130", "durability": null, - "name": "Runite bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9298", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", - "equipment_slot": "13" + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,46}" }, { + "id": "9298", + "name": "Runite bolts(p+)", + "examine": "Runite crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,61}", + "tradeable": "true" + }, + { + "id": "9299", + "name": "Silver bolts(p+)", + "examine": "Silver crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,26}", "shop_price": "6", - "ge_buy_limit": "10000", - "examine": "Silver crossbow bolts.", - "grand_exchange_price": "129", - "durability": null, - "name": "Silver bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9299", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,16}", - "durability": null, + "id": "9300", "name": "Blurite bolts(p++)", "archery_ticket_price": "0", - "id": "9300", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "requirements": "{4,16}" }, { + "id": "9301", + "name": "Iron bolts(p++)", + "examine": "Iron crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,26}", "shop_price": "60", - "ge_buy_limit": "25000", - "examine": "Iron crossbow bolts.", - "grand_exchange_price": "1136", - "durability": null, - "name": "Iron bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9301", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,31}", - "ge_buy_limit": "10000", - "examine": "Steel crossbow bolts.", - "grand_exchange_price": "1088", - "durability": null, - "name": "Steel bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9302", + "name": "Steel bolts(p++)", + "examine": "Steel crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,31}", + "tradeable": "true" }, { + "id": "9303", + "name": "Mithril bolts(p++)", + "examine": "Mithril crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,36}", "shop_price": "32", - "ge_buy_limit": "10000", - "examine": "Mithril crossbow bolts.", - "grand_exchange_price": "903", - "durability": null, - "name": "Mithril bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9303", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,46}", - "ge_buy_limit": "10000", - "grand_exchange_price": "1043", - "durability": null, + "id": "9304", "name": "Adamant bolts(p++)", "archery_ticket_price": "0", - "id": "9304", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", - "equipment_slot": "13" - }, - { - "requirements": "{4,61}", - "ge_buy_limit": "10000", - "examine": "Runite crossbow bolts.", - "grand_exchange_price": "1581", "durability": null, - "name": "Runite bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9305", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", - "equipment_slot": "13" + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,46}" }, { + "id": "9305", + "name": "Runite bolts(p++)", + "examine": "Runite crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,61}", + "tradeable": "true" + }, + { + "id": "9306", + "name": "Silver bolts(p++)", + "examine": "Silver crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", "requirements": "{4,26}", "shop_price": "6", - "ge_buy_limit": "10000", - "examine": "Silver crossbow bolts.", - "grand_exchange_price": "1211", - "durability": null, - "name": "Silver bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9306", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,16}", - "examine": "Jade tipped blurite bolts.", - "durability": null, - "name": "Jade bolts", - "archery_ticket_price": "0", "id": "9335", + "name": "Jade bolts", + "examine": "Jade tipped blurite bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "requirements": "{4,16}" }, { + "id": "9336", + "name": "Topaz bolts", + "examine": "Red Topaz tipped Steel Crossbow Bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,66", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,31}", "shop_price": "62", - "ge_buy_limit": "25000", - "examine": "Red Topaz tipped Steel Crossbow Bolts.", - "grand_exchange_price": "60", - "durability": null, - "name": "Topaz bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9336", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,66", - "equipment_slot": "13" + "tradeable": "true" }, { - "requirements": "{4,36}", - "ge_buy_limit": "25000", - "examine": "Sapphire tipped Mithril crossbow bolts.", - "grand_exchange_price": "89", - "durability": null, - "name": "Sapphire bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9337", + "name": "Sapphire bolts", + "examine": "Sapphire tipped Mithril crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,83", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,36}", - "ge_buy_limit": "25000", - "examine": "Emerald tipped Mithril crossbow bolts.", - "grand_exchange_price": "177", - "durability": null, - "name": "Emerald bolts", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "9338", + "name": "Emerald bolts", + "examine": "Emerald tipped Mithril crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,85", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,36}", + "tradeable": "true" }, { - "requirements": "{4,46}", - "ge_buy_limit": "25000", - "examine": "Ruby tipped Adamantite crossbow bolts.", - "grand_exchange_price": "408", - "durability": null, - "name": "Ruby bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9339", + "name": "Ruby bolts", + "examine": "Ruby tipped Adamantite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,103", - "equipment_slot": "13" - }, - { + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", "requirements": "{4,46}", - "ge_buy_limit": "25000", - "examine": "Diamond tipped Adamantite crossbow bolts.", - "grand_exchange_price": "1545", - "durability": null, - "name": "Diamond bolts", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "true" + }, + { "id": "9340", + "name": "Diamond bolts", + "examine": "Diamond tipped Adamantite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,105", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,46}", + "tradeable": "true" }, { - "requirements": "{4,61}", - "ge_buy_limit": "25000", - "examine": "Dragonstone tipped Runite crossbow bolts.", - "grand_exchange_price": "3201", - "durability": null, - "name": "Dragon bolts", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9341", + "name": "Dragon bolts", + "examine": "Dragonstone tipped Runite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,117", - "equipment_slot": "13" - }, - { - "requirements": "{4,61}", + "durability": null, + "equipment_slot": "13", "ge_buy_limit": "25000", - "examine": "Onyx tipped Runite crossbow bolts.", - "grand_exchange_price": "8752", - "durability": null, - "name": "Onyx bolts", - "tradeable": "true", - "archery_ticket_price": "0", + "requirements": "{4,61}", + "tradeable": "true" + }, + { "id": "9342", + "name": "Onyx bolts", + "examine": "Onyx tipped Runite crossbow bolts.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,120", - "equipment_slot": "13" + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "25000", + "requirements": "{4,61}", + "tradeable": "true" }, { - "shop_price": "1", - "ge_buy_limit": "10000", - "examine": "Unfeathered bronze crossbow bolts.", - "grand_exchange_price": "3", - "durability": null, + "id": "9375", "name": "Bronze bolts (unf)", - "tradeable": "true", + "examine": "Unfeathered bronze crossbow bolts.", "archery_ticket_price": "0", - "id": "9375" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "1", + "tradeable": "true" }, { - "examine": "Unfeathered blurite crossbow bolts.", - "durability": null, + "id": "9376", "name": "Blurite bolts (unf)", + "examine": "Unfeathered blurite crossbow bolts.", "archery_ticket_price": "0", - "id": "9376" + "durability": null }, { - "shop_price": "2", - "ge_buy_limit": "10000", - "examine": "Unfeathered iron crossbow bolts.", - "grand_exchange_price": "14", - "durability": null, + "id": "9377", "name": "Iron bolts (unf)", - "tradeable": "true", + "examine": "Unfeathered iron crossbow bolts.", "archery_ticket_price": "0", - "id": "9377" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "2", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Unfeathered steel crossbow bolts.", - "grand_exchange_price": "61", - "durability": null, + "id": "9378", "name": "Steel bolts (unf)", - "tradeable": "true", + "examine": "Unfeathered steel crossbow bolts.", "archery_ticket_price": "0", - "id": "9378" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Unfeathered mithril crossbow bolts.", - "grand_exchange_price": "115", - "durability": null, + "id": "9379", "name": "Mithril bolts (unf)", - "tradeable": "true", + "examine": "Unfeathered mithril crossbow bolts.", "archery_ticket_price": "0", - "id": "9379" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Unfeathered adamantite crossbow bolts.", - "grand_exchange_price": "266", - "durability": null, + "id": "9380", "name": "Adamant bolts(unf)", - "tradeable": "true", + "examine": "Unfeathered adamantite crossbow bolts.", "archery_ticket_price": "0", - "id": "9380" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "10000", - "examine": "Unfeathered runite crossbow bolts", - "grand_exchange_price": "1235", - "durability": null, + "id": "9381", "name": "Runite bolts (unf)", - "tradeable": "true", + "examine": "Unfeathered runite crossbow bolts", "archery_ticket_price": "0", - "id": "9381" - }, - { + "durability": null, "ge_buy_limit": "10000", - "examine": "Unfeathered silver crossbow bolts.", - "grand_exchange_price": "2", - "durability": null, + "tradeable": "true" + }, + { + "id": "9382", "name": "Silver bolts (unf)", - "tradeable": "true", + "examine": "Unfeathered silver crossbow bolts.", "archery_ticket_price": "0", - "id": "9382" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "examine": "A mithril grapple tipped bolt with a rope.", - "grand_exchange_price": "1447", - "durability": null, + "id": "9415", "name": "Grapple", - "tradeable": "true", + "examine": "A mithril grapple tipped bolt with a rope.", "archery_ticket_price": "0", - "id": "9415" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9416", + "name": "Mith grapple tip", "examine": "A mithril grapple tip.", - "grand_exchange_price": "461", - "durability": null, - "name": "Mith grapple tip", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9416" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "461", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "9417", "name": "Mith grapple tip", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9417" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A mithril grapple tipped bolt with a rope.", - "grand_exchange_price": "858", - "durability": null, + "id": "9418", "name": "Mith grapple", - "tradeable": "true", + "examine": "A mithril grapple tipped bolt with a rope.", "archery_ticket_price": "0", - "id": "9418" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "A mithril grapple tipped bolt with a rope.", - "grand_exchange_price": "1470", - "durability": null, - "name": "Mith grapple", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9419", - "equipment_slot": "13" + "name": "Mith grapple", + "examine": "A mithril grapple tipped bolt with a rope.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "9420", + "name": "Bronze limbs", + "examine": "A pair of bronze crossbow limbs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "5000", "requirements": "{9,9}", "shop_price": "20", - "ge_buy_limit": "5000", - "examine": "A pair of bronze crossbow limbs.", - "grand_exchange_price": "49", - "durability": null, - "name": "Bronze limbs", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "9420", - "equipment_slot": "5" + "weight": "1" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "49", - "durability": null, + "id": "9421", "name": "Bronze limbs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9421" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{24,9}", - "examine": "A pair of blurite crossbow limbs.", - "durability": null, - "name": "Blurite limbs", - "weight": "1", - "archery_ticket_price": "0", "id": "9422", - "equipment_slot": "5" + "name": "Blurite limbs", + "examine": "A pair of blurite crossbow limbs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "requirements": "{24,9}", + "weight": "1" }, { + "id": "9423", + "name": "Iron limbs", + "examine": "A pair of iron crossbow limbs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "5000", "requirements": "{9,39}", "shop_price": "200", - "ge_buy_limit": "5000", - "examine": "A pair of iron crossbow limbs.", - "grand_exchange_price": "34", - "durability": null, - "name": "Iron limbs", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "9423", - "equipment_slot": "5" + "weight": "1" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "34", - "durability": null, + "id": "9424", "name": "Iron limbs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9424" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "9425", + "name": "Steel limbs", + "examine": "A pair of steel crossbow limbs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "5000", "requirements": "{9,46}", "shop_price": "900", - "ge_buy_limit": "5000", - "examine": "A pair of steel crossbow limbs.", - "grand_exchange_price": "97", - "durability": null, - "name": "Steel limbs", "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "9425", - "equipment_slot": "5" + "weight": "2" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "97", - "durability": null, + "id": "9426", "name": "Steel limbs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9426" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "9427", + "name": "Mithril limbs", + "examine": "A pair of mithril crossbow limbs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "5000", "requirements": "{9,54}", "shop_price": "650", - "ge_buy_limit": "5000", - "examine": "A pair of mithril crossbow limbs.", - "grand_exchange_price": "347", - "durability": null, - "name": "Mithril limbs", "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "9427", - "equipment_slot": "5" + "weight": "2" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "347", - "durability": null, + "id": "9428", "name": "Mithril limbs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9428" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "9429", + "name": "Adamantite limbs", + "examine": "A pair of adamantite crossbow limbs.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "5000", "requirements": "{9,61}", "shop_price": "4800", - "ge_buy_limit": "5000", - "examine": "A pair of adamantite crossbow limbs.", - "grand_exchange_price": "1434", - "durability": null, - "name": "Adamantite limbs", "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "9429", - "equipment_slot": "5" + "weight": "3" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1434", - "durability": null, + "id": "9430", "name": "Adamantite limbs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9430" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{9,69}", - "ge_buy_limit": "5000", - "examine": "A pair of runite crossbow limbs.", - "grand_exchange_price": "9441", - "durability": null, - "name": "Runite limbs", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", "id": "9431", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "9441", - "durability": null, "name": "Runite limbs", - "tradeable": "true", + "examine": "A pair of runite crossbow limbs.", "archery_ticket_price": "0", - "id": "9432" + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "5000", + "requirements": "{9,69}", + "tradeable": "true", + "weight": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "1500", - "examine": "A pouch for storing crossbow bolts.", + "id": "9432", + "name": "Runite limbs", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "9433", "name": "Bolt pouch", - "tradeable": "false", + "examine": "A pouch for storing crossbow bolts.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "9433" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "1500", + "tradeable": "false", + "weight": "1" }, { - "shop_price": "25", - "ge_buy_limit": "100", + "id": "9434", + "name": "Bolt mould", "examine": "A mould for creating silver crossbow bolts.", - "grand_exchange_price": "409", - "durability": null, - "name": "Bolt mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "9434" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "409", - "durability": null, + "shop_price": "25", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "9435", "name": "Bolt mould", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9435" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9436", + "name": "Sinew", "examine": "I can use this to make a crossbow string.", - "grand_exchange_price": "196", - "durability": null, - "name": "Sinew", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9436" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "196", - "durability": null, + "id": "9437", "name": "Sinew", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9437" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9438", + "name": "Crossbow string", "examine": "A string for a crossbow.", - "grand_exchange_price": "203", - "durability": null, - "name": "Crossbow string", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9438" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "203", - "durability": null, - "name": "Crossbow string", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9439" + "tradeable": "true" }, { + "id": "9439", + "name": "Crossbow string", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "9440", + "name": "Wooden stock", + "examine": "A wooden crossbow stock", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{9,9}", "shop_price": "8", - "ge_buy_limit": "1000", - "examine": "A wooden crossbow stock", - "grand_exchange_price": "1", - "durability": null, - "name": "Wooden stock", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9440", - "equipment_slot": "3" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "1", - "durability": null, + "id": "9441", "name": "Wooden stock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9441" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "requirements": "{24,9}", - "ge_buy_limit": "1000", - "examine": "An oak crossbow stock.", - "grand_exchange_price": "1", - "durability": null, - "name": "Oak stock", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", "id": "9442", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1", - "durability": null, "name": "Oak stock", - "tradeable": "true", + "examine": "An oak crossbow stock.", "archery_ticket_price": "0", - "id": "9443" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{24,9}", + "tradeable": "true", + "weight": "3" }, { + "id": "9443", + "name": "Oak stock", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "9444", + "name": "Willow stock", + "examine": "A willow crossbow stock.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{9,39}", "shop_price": "21", - "ge_buy_limit": "1000", - "examine": "A willow crossbow stock.", - "grand_exchange_price": "3", - "durability": null, - "name": "Willow stock", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "9444", - "equipment_slot": "3" + "weight": "1" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "3", - "durability": null, + "id": "9445", "name": "Willow stock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9445" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { + "id": "9446", + "name": "Teak stock", + "examine": "A teak crossbow stock.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", "requirements": "{9,46}", "shop_price": "231", - "ge_buy_limit": "1000", - "examine": "A teak crossbow stock.", - "grand_exchange_price": "6", - "durability": null, - "name": "Teak stock", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9446", - "equipment_slot": "3" + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "6", - "durability": null, + "id": "9447", "name": "Teak stock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9447" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "requirements": "{9,54}", - "ge_buy_limit": "1000", - "examine": "A maple crossbow stock.", - "grand_exchange_price": "7", - "durability": null, - "name": "Maple stock", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9448", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "7", - "durability": null, "name": "Maple stock", - "tradeable": "true", + "examine": "A maple crossbow stock.", "archery_ticket_price": "0", - "id": "9449" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{9,54}", + "tradeable": "true" }, { - "requirements": "{9,61}", - "ge_buy_limit": "1000", - "examine": "A Mahogany crossbow stock.", - "grand_exchange_price": "23", - "durability": null, - "name": "Mahogany stock", - "tradeable": "true", - "weight": "3", + "id": "9449", + "name": "Maple stock", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { "id": "9450", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "23", - "durability": null, "name": "Mahogany stock", - "tradeable": "true", + "examine": "A Mahogany crossbow stock.", "archery_ticket_price": "0", - "id": "9451" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{9,61}", + "tradeable": "true", + "weight": "3" }, { - "requirements": "{9,69}", - "ge_buy_limit": "1000", - "examine": "A yew crossbow stock.", - "grand_exchange_price": "37", - "durability": null, - "name": "Yew stock", - "tradeable": "true", - "weight": "3", + "id": "9451", + "name": "Mahogany stock", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { "id": "9452", - "equipment_slot": "3" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "37", - "durability": null, "name": "Yew stock", - "tradeable": "true", + "examine": "A yew crossbow stock.", "archery_ticket_price": "0", - "id": "9453" + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "1000", + "requirements": "{9,69}", + "tradeable": "true", + "weight": "3" }, { - "shop_price": "27", - "ge_buy_limit": "500", + "id": "9453", + "name": "Yew stock", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "9454", + "name": "Bronze c'bow (u)", "examine": "An unstrung bronze crossbow.", - "grand_exchange_price": "25", - "durability": null, - "name": "Bronze c'bow (u)", - "tradeable": "true", - "weight": "8", "archery_ticket_price": "0", - "id": "9454" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "25", - "durability": null, - "name": "Bronze c'bow (u)", + "shop_price": "27", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9455" + "weight": "8" }, { - "shop_price": "27", - "examine": "An unstrung blurite crossbow.", + "id": "9455", + "name": "Bronze c'bow (u)", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9456", "name": "Blurite c'bow (u)", - "weight": "8", + "examine": "An unstrung blurite crossbow.", "archery_ticket_price": "0", - "id": "9456" + "durability": null, + "shop_price": "27", + "weight": "8" }, { - "ge_buy_limit": "500", + "id": "9457", + "name": "Iron c'bow (u)", "examine": "An unstrung iron crossbow.", - "grand_exchange_price": "26", - "durability": null, - "name": "Iron c'bow (u)", - "tradeable": "true", - "weight": "8", "archery_ticket_price": "0", - "id": "9457" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true", + "weight": "8" }, { - "ge_buy_limit": "500", - "grand_exchange_price": "26", - "durability": null, + "id": "9458", "name": "Iron c'bow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9458" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "shop_price": "27", - "ge_buy_limit": "500", + "id": "9459", + "name": "Steel c'bow (u)", "examine": "An unstrung steel crossbow.", - "grand_exchange_price": "114", - "durability": null, - "name": "Steel c'bow (u)", - "tradeable": "true", - "weight": "8", "archery_ticket_price": "0", - "id": "9459" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "114", - "durability": null, - "name": "Steel c'bow (u)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9460" - }, - { "shop_price": "27", + "tradeable": "true", + "weight": "8" + }, + { + "id": "9460", + "name": "Steel c'bow (u)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "9461", + "name": "Mithril c'bow (u)", "examine": "An unstrung mithril crossbow.", - "grand_exchange_price": "330", - "durability": null, - "name": "Mithril c'bow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9461" + "durability": null, + "ge_buy_limit": "500", + "shop_price": "27", + "tradeable": "true" }, { - "ge_buy_limit": "500", - "grand_exchange_price": "330", - "durability": null, + "id": "9462", "name": "Mithril c'bow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9462" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "shop_price": "693", - "ge_buy_limit": "500", + "id": "9463", + "name": "Adamant c'bow (u)", "examine": "An unstrung adamantite crossbow.", - "grand_exchange_price": "1007", - "durability": null, - "name": "Adamant c'bow (u)", - "tradeable": "true", - "weight": "8", "archery_ticket_price": "0", - "id": "9463" + "durability": null, + "ge_buy_limit": "500", + "shop_price": "693", + "tradeable": "true", + "weight": "8" }, { - "ge_buy_limit": "500", - "grand_exchange_price": "1007", - "durability": null, + "id": "9464", "name": "Adamant c'bow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9464" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "shop_price": "4000", - "ge_buy_limit": "500", + "id": "9465", + "name": "Runite c'bow (u)", "examine": "An unstrung runite crossbow.", - "grand_exchange_price": "9493", - "durability": null, - "name": "Runite c'bow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9465" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "9493", - "durability": null, + "shop_price": "4000", + "tradeable": "true" + }, + { + "id": "9466", "name": "Runite c'bow (u)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9466" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "examine": "It's a bar of blurite.", - "durability": null, + "id": "9467", "name": "Blurite bar", - "weight": "1.8", + "examine": "It's a bar of blurite.", "archery_ticket_price": "0", - "id": "9467" + "durability": null, + "weight": "1.8" }, { - "examine": "What is left over when a log is made into a plank.", - "durability": null, + "id": "9468", "name": "Sawdust", - "weight": "0.5", + "examine": "What is left over when a log is made into a plank.", "archery_ticket_price": "0", - "id": "9468" + "durability": null, + "weight": "0.5" }, { - "ge_buy_limit": "100", - "examine": "A seed pod of the Grand Tree.", - "grand_exchange_price": "16200", - "durability": null, + "id": "9469", "name": "Grand seed pod", - "tradeable": "true", + "examine": "A seed pod of the Grand Tree.", "archery_ticket_price": "0", - "id": "9469" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "10", - "examine": "A scarf. You feel your upper lip stiffening.", - "grand_exchange_price": "1900000", - "durability": null, - "name": "Gnome scarf", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "9470", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1900000", - "durability": null, "name": "Gnome scarf", - "tradeable": "true", + "examine": "A scarf. You feel your upper lip stiffening.", "archery_ticket_price": "0", - "id": "9471" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "10", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "10", - "examine": "Tally Ho!", - "grand_exchange_price": "95800", - "durability": null, - "name": "Gnome goggles", - "tradeable": "true", + "id": "9471", + "name": "Gnome scarf", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "9472", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "95800", - "durability": null, "name": "Gnome goggles", - "tradeable": "true", + "examine": "Tally Ho!", "archery_ticket_price": "0", - "id": "9473" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "tradeable": "true" }, { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "id": "9473", + "name": "Gnome goggles", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "9474", "name": "Reward token", - "tradeable": "false", - "destroy": "true", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", "archery_ticket_price": "0", - "id": "9474" + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" }, { - "ge_buy_limit": "100", + "id": "9475", + "name": "Mint cake", "examine": "It looks very minty.", - "grand_exchange_price": "675", - "durability": null, - "name": "Mint cake", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "9475" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "675", - "durability": null, + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "9476", "name": "Mint cake", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9476" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "You can check on your delivery details here", - "durability": null, + "id": "9477", "name": "Aluft aloft box", + "examine": "You can check on your delivery details here", "archery_ticket_price": "0", - "id": "9477" + "durability": null }, { - "shop_price": "1", + "id": "9478", + "name": "Half made batta", "examine": "This cheese & tomato batta needs baking (and garnishing with equa leaves).", - "durability": null, - "name": "Half made batta", "archery_ticket_price": "0", - "id": "9478" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", + "id": "9479", + "name": "Unfinished batta", "examine": "This cheese & tomato batta needs garnishing with equa leaves.", - "durability": null, - "name": "Unfinished batta", "archery_ticket_price": "0", - "id": "9479" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", + "id": "9480", + "name": "Half made batta", "examine": "This fruit batta needs baking (and garnishing with gnome spices).", - "durability": null, - "name": "Half made batta", "archery_ticket_price": "0", - "id": "9480" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", + "id": "9481", + "name": "Unfinished batta", "examine": "This fruit batta needs garnishing with gnome spices.", - "durability": null, - "name": "Unfinished batta", "archery_ticket_price": "0", - "id": "9481" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", + "id": "9482", + "name": "Half made batta", "examine": "This toad batta needs baking.", - "durability": null, - "name": "Half made batta", "archery_ticket_price": "0", - "id": "9482" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", + "id": "9483", + "name": "Half made batta", "examine": "This veggie batta needs baking (and garnishing with equa leaves).", - "durability": null, - "name": "Half made batta", "archery_ticket_price": "0", - "id": "9483" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", + "id": "9484", + "name": "Unfinished batta", "examine": "This veggie batta needs garnishing with equa leaves.", - "durability": null, - "name": "Unfinished batta", "archery_ticket_price": "0", - "id": "9484" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", - "examine": "This worm batta needs baking (and garnishing with equa leaves).", - "durability": null, + "id": "9485", "name": "Half made batta", + "examine": "This worm batta needs baking (and garnishing with equa leaves).", "archery_ticket_price": "0", - "id": "9485" + "durability": null, + "shop_price": "1" }, { - "shop_price": "1", - "examine": "This worm batta needs garnishing with equa leaves.", - "durability": null, + "id": "9486", "name": "Unfinished batta", + "examine": "This worm batta needs garnishing with equa leaves.", "archery_ticket_price": "0", - "id": "9486" + "durability": null, + "shop_price": "1" }, { - "shop_price": "28", + "id": "9487", + "name": "Wizard blizzard", "examine": "This looks like a strange mix.", - "grand_exchange_price": "740", - "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9487" - }, - { "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9488" - }, - { "shop_price": "28", + "tradeable": "true", + "weight": "1" + }, + { + "id": "9488", + "name": "Wizard blizzard", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9489", + "name": "Wizard blizzard", "examine": "This looks like a strange mix.", - "grand_exchange_price": "740", - "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9489" + "durability": null, + "shop_price": "28", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "28", + "id": "9508", + "name": "Wizard blizzard", "examine": "This looks like a strange mix.", - "grand_exchange_price": "740", - "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9508" - }, - { "durability": null, - "name": "Wizard blizzard", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9509" - }, - { "shop_price": "28", + "tradeable": "true", + "weight": "1" + }, + { + "id": "9509", + "name": "Wizard blizzard", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9510", + "name": "Short green guy", "examine": "A Short Green Guy... looks good.", - "grand_exchange_price": "954", - "durability": null, - "name": "Short green guy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9510" - }, - { "durability": null, - "name": "Short green guy", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9511" - }, - { "shop_price": "28", + "tradeable": "true" + }, + { + "id": "9511", + "name": "Short green guy", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9512", + "name": "Pineapple punch", "examine": "A fresh healthy fruit mix.", - "grand_exchange_price": "287", - "durability": null, - "name": "Pineapple punch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9512" - }, - { "durability": null, - "name": "Pineapple punch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9513" - }, - { "shop_price": "28", + "tradeable": "true" + }, + { + "id": "9513", + "name": "Pineapple punch", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9514", + "name": "Fruit blast", "examine": "A cool refreshing fruit mix.", - "grand_exchange_price": "2276", - "durability": null, - "name": "Fruit blast", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9514" - }, - { "durability": null, - "name": "Fruit blast", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9515" - }, - { "shop_price": "28", + "tradeable": "true" + }, + { + "id": "9515", + "name": "Fruit blast", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9516", + "name": "Drunk dragon", "examine": "A warm creamy alcoholic beverage", - "grand_exchange_price": "577", - "durability": null, - "name": "Drunk dragon", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9516" - }, - { "durability": null, - "name": "Drunk dragon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9517" - }, - { "shop_price": "28", + "tradeable": "true" + }, + { + "id": "9517", + "name": "Drunk dragon", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9518", + "name": "Choc saturday", "examine": "A warm creamy alcoholic beverage", - "grand_exchange_price": "281", - "durability": null, - "name": "Choc saturday", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9518" + "durability": null, + "shop_price": "28", + "tradeable": "true", + "weight": "1" }, { - "durability": null, + "id": "9519", "name": "Choc saturday", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9519" + "durability": null, + "tradeable": "true" }, { - "shop_price": "30", + "id": "9520", + "name": "Blurberry special", "examine": "Looks good... smells strong.", - "grand_exchange_price": "27", + "archery_ticket_price": "0", "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "9521", "name": "Blurberry special", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9520" - }, - { "durability": null, - "name": "Blurberry special", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9521" + "tradeable": "true" }, { - "shop_price": "1", + "id": "9522", + "name": "Batta tin", "examine": "A deep tin used to make gnome battas in.", - "durability": null, - "name": "Batta tin", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "9522" - }, - { "durability": null, - "name": "Batta tin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9523" - }, - { "shop_price": "1", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "9523", + "name": "Batta tin", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9524", + "name": "Batta tin", "examine": "A deep tin used to make gnome battas in.", - "durability": null, - "name": "Batta tin", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", - "id": "9524" + "durability": null, + "shop_price": "1", + "tradeable": "true", + "weight": "0.1" }, { - "durability": null, + "id": "9525", "name": "Batta tin", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9525" + "durability": null, + "tradeable": "true" }, { + "id": "9527", + "name": "Fruit batta", "examine": "It actually smells quite good.", - "grand_exchange_price": "310", - "durability": null, - "name": "Fruit batta", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9527" + "durability": null, + "tradeable": "true", + "weight": "0.2" }, { - "durability": null, + "id": "9528", "name": "Fruit batta", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9528" + "durability": null, + "tradeable": "true" }, { + "id": "9529", + "name": "Toad batta", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "78", - "examine": "It actually smells quite good.", - "grand_exchange_price": "280", - "durability": null, + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "9530", "name": "Toad batta", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9529" - }, - { "durability": null, - "name": "Toad batta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9530" + "tradeable": "true" }, { + "id": "9531", + "name": "Worm batta", "examine": "It actually smells quite good.", - "grand_exchange_price": "148", - "durability": null, - "name": "Worm batta", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9531" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9532", "name": "Worm batta", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9532" + "durability": null, + "tradeable": "true" }, { + "id": "9533", + "name": "Vegetable batta", "examine": "Well... It looks healthy.", - "grand_exchange_price": "240", - "durability": null, - "name": "Vegetable batta", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9533" + "durability": null, + "tradeable": "true", + "weight": "0.2" }, { - "durability": null, + "id": "9534", "name": "Vegetable batta", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9534" + "durability": null, + "tradeable": "true" }, { + "id": "9535", + "name": "Cheese+tom batta", "examine": "This smells really good.", - "grand_exchange_price": "266", - "durability": null, - "name": "Cheese+tom batta", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9535" + "durability": null, + "tradeable": "true", + "weight": "0.2" }, { - "durability": null, + "id": "9536", "name": "Cheese+tom batta", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9536" + "durability": null, + "tradeable": "true" }, { + "id": "9538", + "name": "Toad crunchies", "examine": "It actually smells quite good.", - "grand_exchange_price": "2606", - "durability": null, - "name": "Toad crunchies", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9538" + "durability": null, + "tradeable": "true", + "weight": "0.2" }, { - "durability": null, + "id": "9539", "name": "Toad crunchies", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9539" + "durability": null, + "tradeable": "true" }, { - "shop_price": "70", + "id": "9540", + "name": "Spicy crunchies", "examine": "Yum...smells spicy.", - "grand_exchange_price": "99", - "durability": null, - "name": "Spicy crunchies", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9540" - }, - { "durability": null, - "name": "Spicy crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9541" - }, - { - "shop_price": "80", - "examine": "It actually smells quite good.", - "grand_exchange_price": "255", - "durability": null, - "name": "Worm crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9542" - }, - { - "durability": null, - "name": "Worm crunchies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9543" - }, - { "shop_price": "70", + "tradeable": "true" + }, + { + "id": "9541", + "name": "Spicy crunchies", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9542", + "name": "Worm crunchies", + "examine": "It actually smells quite good.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "80", + "tradeable": "true" + }, + { + "id": "9543", + "name": "Worm crunchies", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "9544", + "name": "Chocchip crunchies", "examine": "Yum... smells good.", - "grand_exchange_price": "889", - "durability": null, - "name": "Chocchip crunchies", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9544" + "durability": null, + "shop_price": "70", + "tradeable": "true" }, { - "durability": null, + "id": "9545", "name": "Chocchip crunchies", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9545" + "durability": null, + "tradeable": "true" }, { + "id": "9547", + "name": "Worm hole", "examine": "It actually smells quite good.", - "grand_exchange_price": "475", - "durability": null, - "name": "Worm hole", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9547" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9548", "name": "Worm hole", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9548" + "durability": null, + "tradeable": "true" }, { + "id": "9549", + "name": "Veg ball", "examine": "This looks pretty healthy.", - "grand_exchange_price": "514", - "durability": null, - "name": "Veg ball", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9549" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9550", "name": "Veg ball", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9550" + "durability": null, + "tradeable": "true" }, { + "id": "9551", + "name": "Tangled toads' legs", "examine": "It actually smells quite good.", - "grand_exchange_price": "2650", - "durability": null, - "name": "Tangled toads' legs", - "tradeable": "true", - "weight": "0.3", "archery_ticket_price": "0", - "id": "9551" + "durability": null, + "tradeable": "true", + "weight": "0.3" }, { - "durability": null, + "id": "9552", "name": "Tangled toads' legs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9552" + "durability": null, + "tradeable": "true" }, { - "shop_price": "450", + "id": "9553", + "name": "Chocolate bomb", "examine": "Full of creamy, chocolately goodness.", - "grand_exchange_price": "4704", - "durability": null, - "name": "Chocolate bomb", - "tradeable": "true", - "weight": "0.3", "archery_ticket_price": "0", - "id": "9553" + "durability": null, + "shop_price": "450", + "tradeable": "true", + "weight": "0.3" }, { - "durability": null, + "id": "9554", "name": "Chocolate bomb", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9554" + "durability": null, + "tradeable": "true" }, { + "id": "9558", + "name": "Half made bowl", "examine": "This unfinished choco bomb needs baking, and final ingredients", - "durability": null, - "name": "Half made bowl", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9558" + "durability": null, + "weight": "0.2" }, { + "id": "9559", + "name": "Half made bowl", "examine": "This unfinished tangled toad legs bowl needs baking, and final ingredients", - "durability": null, - "name": "Half made bowl", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9559" + "durability": null, + "weight": "0.2" }, { + "id": "9560", + "name": "Unfinished bowl", "examine": "This unfinished choc bomb needs cream and chocolate dust.", - "durability": null, - "name": "Unfinished bowl", "archery_ticket_price": "0", - "id": "9560" + "durability": null }, { + "id": "9561", + "name": "Half made bowl", "examine": "This unfinished veggie ball needs baking, and final ingredients", - "durability": null, - "name": "Half made bowl", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9561" + "durability": null, + "weight": "0.2" }, { + "id": "9562", + "name": "Unfinished bowl", "examine": "This unfinished veggie ball needs equa leaves.", - "durability": null, - "name": "Unfinished bowl", "archery_ticket_price": "0", - "id": "9562" + "durability": null }, { - "examine": "This unfinished worm hole needs baking, and final ingredients", - "durability": null, + "id": "9563", "name": "Half made bowl", - "weight": "0.2", + "examine": "This unfinished worm hole needs baking, and final ingredients", "archery_ticket_price": "0", - "id": "9563" + "durability": null, + "weight": "0.2" }, { - "examine": "This unfinished worm hole needs equa leaves.", - "durability": null, + "id": "9564", "name": "Unfinished bowl", + "examine": "This unfinished worm hole needs equa leaves.", "archery_ticket_price": "0", - "id": "9564" + "durability": null }, { - "durability": null, + "id": "9565", "name": "Cocktail shaker", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9565" + "durability": null, + "tradeable": "true" }, { - "examine": "This wizzard blizzard needs pouring, a lime slice, and pineapple chunks.", - "durability": null, + "id": "9566", "name": "Mixed blizzard", + "examine": "This wizzard blizzard needs pouring, a lime slice, and pineapple chunks.", "archery_ticket_price": "0", - "id": "9566" + "durability": null }, { - "examine": "This short green guy cocktail needs pouring, a lime slice and equa leaves.", - "durability": null, + "id": "9567", "name": "Mixed sgg", + "examine": "This short green guy cocktail needs pouring, a lime slice and equa leaves.", "archery_ticket_price": "0", - "id": "9567" + "durability": null }, { - "examine": "This fruit blast cocktail needs pouring and a lemon slice.", - "durability": null, + "id": "9568", "name": "Mixed blast", + "examine": "This fruit blast cocktail needs pouring and a lemon slice.", "archery_ticket_price": "0", - "id": "9568" + "durability": null }, { - "examine": "This pineapple punch needs pouring, lime and pineapple chunks, and a orange slice.", - "durability": null, + "id": "9569", "name": "Mixed punch", + "examine": "This pineapple punch needs pouring, lime and pineapple chunks, and a orange slice.", "archery_ticket_price": "0", - "id": "9569" + "durability": null }, { - "examine": "This blurberry special needs pouring, orange and lemon chunks, a lime slice and equa leaves.", - "durability": null, + "id": "9570", "name": "Mixed blurberry special", + "examine": "This blurberry special needs pouring, orange and lemon chunks, a lime slice and equa leaves.", "archery_ticket_price": "0", - "id": "9570" + "durability": null }, { + "id": "9577", + "name": "Half made crunchy", "examine": "This choco chip crunchy needs baking and garnishing with chocolate dust.", - "durability": null, - "name": "Half made crunchy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9577" + "durability": null, + "tradeable": "true" }, { + "id": "9578", + "name": "Unfinished crunchy", "examine": "This choco chip crunchy needs garnishing with chocolate dust.", - "durability": null, - "name": "Unfinished crunchy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9578" + "durability": null, + "tradeable": "true" }, { + "id": "9579", + "name": "Half made crunchy", "examine": "This spicy crunchy needs baking and garnishing with gnome spices.", - "durability": null, - "name": "Half made crunchy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9579" + "durability": null, + "tradeable": "true" }, { + "id": "9580", + "name": "Unfinished crunchy", "examine": "This spicy crunchy needs garnishing with gnome spices.", - "durability": null, - "name": "Unfinished crunchy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9580" + "durability": null, + "tradeable": "true" }, { + "id": "9581", + "name": "Half made crunchy", "examine": "This toad crunchy needs baking and garnishing with equa leaves.", - "durability": null, - "name": "Half made crunchy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9581" + "durability": null, + "tradeable": "true" }, { + "id": "9582", + "name": "Unfinished crunchy", "examine": "This toad crunchy needs garnishing with equa leaves.", - "durability": null, - "name": "Unfinished crunchy", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9582" + "durability": null, + "tradeable": "true" }, { - "examine": "This worm crunchy needs baking and garnishing with gnome spices.", - "durability": null, + "id": "9583", "name": "Half made crunchy", - "tradeable": "true", + "examine": "This worm crunchy needs baking and garnishing with gnome spices.", "archery_ticket_price": "0", - "id": "9583" + "durability": null, + "tradeable": "true" }, { - "examine": "This worm crunchy needs garnishing with gnome spices.", - "durability": null, + "id": "9584", "name": "Unfinished crunchy", - "tradeable": "true", + "examine": "This worm crunchy needs garnishing with gnome spices.", "archery_ticket_price": "0", - "id": "9584" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9585", "name": "Batta tin", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9585" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9586", "name": "Crunchy tray", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9586" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9587", "name": "Gnomebowl mould", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9587" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9588", "name": "Raw crunchies", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9588" + "durability": null, + "tradeable": "true" }, { + "id": "9589", + "name": "Dossier", + "examine": "A dossier containing info on the Black Knight plot.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "Speak to Sir Amik Varze at the beginning of the Black Knight's Fortress Quest.", - "examine": "A dossier containing info on the Black Knight plot.", "durability": null, - "name": "Dossier", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9589" + "tradeable": "false" }, { - "examine": "A dossier containing info on the Black Knight plot.", - "durability": null, + "id": "9590", "name": "Dossier", - "tradeable": "false", - "destroy": "true", + "examine": "A dossier containing info on the Black Knight plot.", "archery_ticket_price": "0", - "id": "9590" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "Glue made from tree sap and ground mud runes.", - "durability": null, + "id": "9592", "name": "Magic glue", - "weight": "3", + "examine": "Glue made from tree sap and ground mud runes.", "archery_ticket_price": "0", - "id": "9592" + "durability": null, + "weight": "3" }, { - "examine": "This doesn't look like it will do anything interesting.", - "durability": null, + "id": "9593", "name": "Weird gloop", - "tradeable": "false", - "destroy": "true", - "weight": "2.5", + "examine": "This doesn't look like it will do anything interesting.", "archery_ticket_price": "0", - "id": "9593" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "2.5" }, { - "examine": "Mud runes ground into a powder.", - "durability": null, + "id": "9594", "name": "Ground mud runes", - "tradeable": "false", - "destroy": "true", - "weight": "0.1", + "examine": "Mud runes ground into a powder.", "archery_ticket_price": "0", - "id": "9594" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "0.1" }, { - "examine": "A red circular crystalline disc.", - "durability": null, + "id": "9597", "name": "Red circle", + "examine": "A red circular crystalline disc.", "archery_ticket_price": "0", - "id": "9597" + "durability": null }, { - "examine": "A red triangular crystalline disc.", - "durability": null, + "id": "9598", "name": "Red triangle", + "examine": "A red triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9598" + "durability": null }, { - "examine": "A red square-shaped crystalline disc.", - "durability": null, + "id": "9599", "name": "Red square", + "examine": "A red square-shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9599" + "durability": null }, { - "examine": "A red pentagon shaped crystalline disc.", - "durability": null, + "id": "9600", "name": "Red pentagon", + "examine": "A red pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9600" + "durability": null }, { - "examine": "An orange circular crystalline disc.", - "durability": null, + "id": "9601", "name": "Orange circle", + "examine": "An orange circular crystalline disc.", "archery_ticket_price": "0", - "id": "9601" + "durability": null }, { - "examine": "An orange triangular crystalline disc.", - "durability": null, + "id": "9602", "name": "Orange triangle", + "examine": "An orange triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9602" + "durability": null }, { - "examine": "An orange square-shaped crystalline disc.", - "durability": null, + "id": "9603", "name": "Orange square", + "examine": "An orange square-shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9603" + "durability": null }, { - "examine": "An orange pentagon shaped crystalline disc.", - "durability": null, + "id": "9604", "name": "Orange pentagon", + "examine": "An orange pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9604" + "durability": null }, { - "examine": "A yellow circular crystalline disc.", - "durability": null, + "id": "9605", "name": "Yellow circle", + "examine": "A yellow circular crystalline disc.", "archery_ticket_price": "0", - "id": "9605" + "durability": null }, { - "examine": "A yellow triangular crystalline disc.", - "durability": null, + "id": "9606", "name": "Yellow triangle", + "examine": "A yellow triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9606" + "durability": null }, { - "examine": "A yellow square-shaped crystalline disc.", - "durability": null, + "id": "9607", "name": "Yellow square", + "examine": "A yellow square-shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9607" + "durability": null }, { - "examine": "A yellow pentagon shaped crystalline disc.", - "durability": null, + "id": "9608", "name": "Yellow pentagon", + "examine": "A yellow pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9608" + "durability": null }, { - "examine": "A green circular crystalline disc.", - "durability": null, + "id": "9609", "name": "Green circle", + "examine": "A green circular crystalline disc.", "archery_ticket_price": "0", - "id": "9609" + "durability": null }, { - "examine": "A green triangular crystalline disc.", - "durability": null, + "id": "9610", "name": "Green triangle", + "examine": "A green triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9610" + "durability": null }, { - "examine": "A green square shaped crystalline disc.", - "durability": null, + "id": "9611", "name": "Green square", + "examine": "A green square shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9611" + "durability": null }, { - "examine": "A green pentagon shaped crystalline disc.", - "durability": null, + "id": "9612", "name": "Green pentagon", + "examine": "A green pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9612" + "durability": null }, { - "examine": "A blue circular crystalline disc.", - "durability": null, + "id": "9613", "name": "Blue circle", + "examine": "A blue circular crystalline disc.", "archery_ticket_price": "0", - "id": "9613" + "durability": null }, { - "examine": "A blue triangular crystalline disc.", - "durability": null, + "id": "9614", "name": "Blue triangle", + "examine": "A blue triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9614" + "durability": null }, { - "examine": "A blue square shaped crystalline disc.", - "durability": null, + "id": "9615", "name": "Blue square", + "examine": "A blue square shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9615" + "durability": null }, { - "examine": "A blue pentagon shaped crystalline disc.", - "durability": null, + "id": "9616", "name": "Blue pentagon", + "examine": "A blue pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9616" + "durability": null }, { - "examine": "An indigo circular crystalline disc.", - "durability": null, + "id": "9617", "name": "Indigo circle", + "examine": "An indigo circular crystalline disc.", "archery_ticket_price": "0", - "id": "9617" + "durability": null }, { - "examine": "An indigo triangular crystalline disc.", - "durability": null, + "id": "9618", "name": "Indigo triangle", + "examine": "An indigo triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9618" + "durability": null }, { - "examine": "An indigo square shaped crystalline disc.", - "durability": null, + "id": "9619", "name": "Indigo square", + "examine": "An indigo square shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9619" + "durability": null }, { - "examine": "An indigo pentagon shaped crystalline disc.", - "durability": null, + "id": "9620", "name": "Indigo pentagon", + "examine": "An indigo pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9620" + "durability": null }, { - "examine": "A violet circular crystalline disc.", - "durability": null, + "id": "9621", "name": "Violet circle", + "examine": "A violet circular crystalline disc.", "archery_ticket_price": "0", - "id": "9621" + "durability": null }, { - "examine": "A violet triangular crystalline disc.", - "durability": null, + "id": "9622", "name": "Violet triangle", + "examine": "A violet triangular crystalline disc.", "archery_ticket_price": "0", - "id": "9622" + "durability": null }, { - "examine": "A violet square-shaped crystalline disc.", - "durability": null, + "id": "9623", "name": "Violet square", + "examine": "A violet square-shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9623" + "durability": null }, { - "examine": "A violet pentagon shaped crystalline disc.", - "durability": null, + "id": "9624", "name": "Violet pentagon", + "examine": "A violet pentagon shaped crystalline disc.", "archery_ticket_price": "0", - "id": "9624" + "durability": null }, { - "destroy_message": "Maybe Brimstail will have another...", - "examine": "A magical saw.", - "durability": null, - "name": "Crystal saw", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "9625", - "equipment_slot": "3" - }, - { - "destroy_message": "Maybe Brimstail will have another...", - "examine": "This small crystal seed looks grey and dead.", - "durability": null, - "name": "Small crystal seed", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "name": "Crystal saw", + "examine": "A magical saw.", "archery_ticket_price": "0", - "id": "9626" + "destroy": "true", + "destroy_message": "Maybe Brimstail will have another...", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" }, { + "id": "9626", + "name": "Small crystal seed", + "examine": "This small crystal seed looks grey and dead.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Maybe Brimstail will have another...", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "9629", + "name": "Tyras helm", + "examine": "As used by King Tyras personal guard.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{1,5}", "shop_price": "1265", - "ge_buy_limit": "100", - "examine": "As used by King Tyras personal guard.", - "durability": null, - "weight": "0.9", - "equipment_slot": "0", - "grand_exchange_price": "1406", - "name": "Tyras helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9629", - "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" + "weight": "0.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1406", - "durability": null, + "id": "9630", "name": "Tyras helm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9630" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "This needs refining.", - "durability": null, + "id": "9632", "name": "Daeyalt ore", - "tradeable": "false", - "destroy": "true", - "weight": "2", + "examine": "This needs refining.", "archery_ticket_price": "0", - "id": "9632" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "2" }, { - "shop_price": "635", - "ge_buy_limit": "100", - "examine": "Dressing like the Vyrewatch could be a useful disguise in the ghetto of Meiyerditch.", - "durability": null, - "weight": "0.9", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "2160", - "name": "Vyrewatch top", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9634", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2160", - "durability": null, "name": "Vyrewatch top", - "tradeable": "true", + "examine": "Dressing like the Vyrewatch could be a useful disguise in the ghetto of Meiyerditch.", "archery_ticket_price": "0", - "id": "9635" - }, - { - "shop_price": "635", - "ge_buy_limit": "100", - "examine": "Dress like a powerful Vyrewatch!", - "grand_exchange_price": "1204", - "durability": null, - "name": "Vyrewatch legs", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "9636", "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1204", "durability": null, - "name": "Vyrewatch legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9637" - }, - { - "shop_price": "635", - "ge_buy_limit": "100", - "examine": "Dress like a powerful Vyrewatch!", - "grand_exchange_price": "2874", - "durability": null, - "name": "Vyrewatch shoes", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "9638", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2874", - "durability": null, - "name": "Vyrewatch shoes", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9639" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", - "durability": null, - "weight": "0.9", "equipment_slot": "4", + "ge_buy_limit": "100", "remove_sleeves": "true", - "grand_exchange_price": "588", - "name": "Citizen top", + "shop_price": "635", "tradeable": "true", + "weight": "0.9" + }, + { + "id": "9635", + "name": "Vyrewatch top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9636", + "name": "Vyrewatch legs", + "examine": "Dress like a powerful Vyrewatch!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "635", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "9637", + "name": "Vyrewatch legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9638", + "name": "Vyrewatch shoes", + "examine": "Dress like a powerful Vyrewatch!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "635", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "9639", + "name": "Vyrewatch shoes", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "9640", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "588", - "durability": null, "name": "Citizen top", - "tradeable": "true", + "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", "archery_ticket_price": "0", - "id": "9641" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "6", + "tradeable": "true", + "weight": "0.9" }, { - "shop_price": "6", - "ge_buy_limit": "100", - "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", - "grand_exchange_price": "491", - "durability": null, - "name": "Citizen trousers", - "tradeable": "true", - "weight": "0.9", + "id": "9641", + "name": "Citizen top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "9642", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "491", - "durability": null, "name": "Citizen trousers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9643" - }, - { - "shop_price": "6", - "ge_buy_limit": "100", "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", - "grand_exchange_price": "458", - "durability": null, - "name": "Citizen shoes", - "tradeable": "true", - "weight": "0.9", "archery_ticket_price": "0", - "id": "9644", "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { + "durability": null, + "equipment_slot": "7", "ge_buy_limit": "100", - "grand_exchange_price": "458", + "shop_price": "6", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "9643", + "name": "Citizen trousers", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9644", "name": "Citizen shoes", - "tradeable": "true", + "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", "archery_ticket_price": "0", - "id": "9645" + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "6", + "tradeable": "true", + "weight": "0.9" }, { - "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", - "examine": "Northern approach of the castle.", + "id": "9645", + "name": "Citizen shoes", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9646", "name": "Castle sketch 1", - "tradeable": "false", - "destroy": "true", + "examine": "Northern approach of the castle.", "archery_ticket_price": "0", - "id": "9646" + "destroy": "true", + "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", - "examine": "Western approach of the castle.", - "durability": null, + "id": "9647", "name": "Castle sketch 2", - "tradeable": "false", - "destroy": "true", + "examine": "Western approach of the castle.", "archery_ticket_price": "0", - "id": "9647" - }, - { + "destroy": "true", "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", - "examine": "Southern approach of the castle.", "durability": null, + "tradeable": "false" + }, + { + "id": "9648", "name": "Castle sketch 3", - "tradeable": "false", - "destroy": "true", + "examine": "Southern approach of the castle.", "archery_ticket_price": "0", - "id": "9648" + "destroy": "true", + "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A key to some large, strange door.", - "durability": null, + "id": "9651", "name": "Large ornate key", - "tradeable": "false", - "destroy": "true", + "examine": "A key to some large, strange door.", "archery_ticket_price": "0", - "id": "9651" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Unknown You can reclaim this item from the place you found it.", - "examine": "A book called Haemalchemy Volume 1.", - "durability": null, + "id": "9652", "name": "Haemalchemy", - "tradeable": "false", - "destroy": "true", + "examine": "A book called Haemalchemy Volume 1.", "archery_ticket_price": "0", - "id": "9652" + "destroy": "true", + "destroy_message": "Unknown You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Safalaan gave you this message; he would probably write out another one for you.", - "examine": "A sealed message from Safalaan to Valiaf.", - "durability": null, + "id": "9653", "name": "Sealed message", - "tradeable": "false", - "destroy": "true", + "examine": "A sealed message from Safalaan to Valiaf.", "archery_ticket_price": "0", - "id": "9653" + "destroy": "true", + "destroy_message": "Safalaan gave you this message; he would probably write out another one for you.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A key to the Witch's house's front door. (Witch's House)", - "durability": null, + "id": "9654", "name": "Door key", + "examine": "A key to the Witch's house's front door. (Witch's House)", "archery_ticket_price": "0", - "id": "9654" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You found this ladder top on a wall section in the north of Meiyerditch; you can get another one there.", - "examine": "The top part of a ladder.", - "durability": null, + "id": "9655", "name": "Ladder top", - "tradeable": "false", - "destroy": "true", + "examine": "The top part of a ladder.", "archery_ticket_price": "0", - "id": "9655" + "destroy": "true", + "destroy_message": "You found this ladder top on a wall section in the north of Meiyerditch; you can get another one there.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", - "examine": "A tome of experience that awards 2000 XP per chapter.", - "durability": null, + "id": "9656", "name": "Tome of xp (3)", - "tradeable": "false", - "destroy": "true", + "examine": "A tome of experience that awards 2000 XP per chapter.", "archery_ticket_price": "0", - "id": "9656" + "destroy": "true", + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", - "examine": "A tome of experience that awards 2000 XP per chapter.", - "durability": null, + "id": "9657", "name": "Tome of xp (2)", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9657" - }, - { - "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", "examine": "A tome of experience that awards 2000 XP per chapter.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", "durability": null, + "tradeable": "false" + }, + { + "id": "9658", "name": "Tome of xp (1)", - "tradeable": "false", - "destroy": "true", + "examine": "A tome of experience that awards 2000 XP per chapter.", "archery_ticket_price": "0", - "id": "9658" + "destroy": "true", + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", - "grand_exchange_price": "74", - "durability": null, + "id": "9659", "name": "Bucket of water", - "tradeable": "true", - "weight": "3", + "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", "archery_ticket_price": "0", - "id": "9659" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "2", - "examine": "It's an empty bucket.", - "grand_exchange_price": "50", "durability": null, - "name": "Bucket", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "9660" + "weight": "3" }, { - "destroy_message": "Safalaan gave you this key as a reward for helping out in Meiyerditch, you can get another key from him.", - "examine": "A key allowing a shortcut into the Sanguinesti region. (Darkness of Hallowvale)", + "id": "9660", + "name": "Bucket", + "examine": "It's an empty bucket.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "9662", "name": "Shortcut key", - "tradeable": "false", - "destroy": "true", + "examine": "A key allowing a shortcut into the Sanguinesti region. (Darkness of Hallowvale)", "archery_ticket_price": "0", - "id": "9662" + "destroy": "true", + "destroy_message": "Safalaan gave you this key as a reward for helping out in Meiyerditch, you can get another key from him.", + "durability": null, + "tradeable": "false" }, { - "durability": null, + "id": "9665", "name": "Torch", "archery_ticket_price": "0", - "id": "9665", + "durability": null, "equipment_slot": "3" }, { - "shop_price": "25000", - "ge_buy_limit": "100", + "id": "9666", + "name": "Pros'yte harness m", "examine": "Unknown edit", - "grand_exchange_price": "27500", - "durability": null, - "name": "Pros'yte harness m", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "9666" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "27500", - "durability": null, - "name": "Pros'yte harness m", + "shop_price": "25000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9667" + "weight": "2.2" }, { + "id": "9667", + "name": "Pros'yte harness m", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9668", + "name": "Initiate harness m", + "examine": "Unknown edit", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "shop_price": "20000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "9669", + "name": "Initiate harness m", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9670", + "name": "Pros'yte harness f", "examine": "Unknown edit", - "grand_exchange_price": "22700", - "durability": null, - "name": "Initiate harness m", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "9668" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "22700", - "durability": null, - "name": "Initiate harness m", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9669" - }, - { "shop_price": "25000", - "ge_buy_limit": "100", - "examine": "Unknown edit", - "grand_exchange_price": "27900", - "durability": null, - "name": "Pros'yte harness f", "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "9670" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "27900", - "durability": null, + "id": "9671", "name": "Pros'yte harness f", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9671" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "9672", + "name": "Proselyte sallet", + "examine": "A Proselyte Temple Knight's helm.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,4,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,30}-{5,20}", "shop_price": "8000", - "ge_buy_limit": "100", - "examine": "A Proselyte Temple Knight's helm.", - "durability": null, - "weight": "2", - "absorb": "1,0,2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "4619", - "name": "Proselyte sallet", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9672", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,4,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "4619", - "durability": null, + "id": "9673", "name": "Proselyte sallet", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9673" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "9674", + "name": "Proselyte hauberk", + "examine": "A Proselyte Temple Knight's armour.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,8,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", "requirements": "{1,30}-{5,20}", "shop_price": "12000", - "ge_buy_limit": "100", - "examine": "A Proselyte Temple Knight's armour.", - "durability": null, - "weight": "8.6", - "absorb": "2,0,4", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "7076", - "name": "Proselyte hauberk", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9674", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,8,0,0" + "weight": "8.6" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "7076", - "durability": null, + "id": "9675", "name": "Proselyte hauberk", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9675" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,30}-{5,20}", - "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "A Proselyte Temple Knight's leg armour", - "durability": null, - "weight": "7.7", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "5923", - "name": "Proselyte cuisse", - "tradeable": "true", - "archery_ticket_price": "0", "id": "9676", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5923", - "durability": null, "name": "Proselyte cuisse", - "tradeable": "true", + "examine": "A Proselyte Temple Knight's leg armour", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "9677" - }, - { + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,5,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", "requirements": "{1,30}-{5,20}", "shop_price": "10000", - "ge_buy_limit": "100", - "examine": "A Proselyte Temple Knight's leg armour.", - "durability": null, - "weight": "9", - "absorb": "1,0,3", - "equipment_slot": "7", - "grand_exchange_price": "5730", - "name": "Proselyte tasset", "tradeable": "true", + "weight": "7.7" + }, + { + "id": "9677", + "name": "Proselyte cuisse", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "9678", - "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,5,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "5730", - "durability": null, "name": "Proselyte tasset", - "tradeable": "true", + "examine": "A Proselyte Temple Knight's leg armour.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "9679" + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,5,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,30}-{5,20}", + "shop_price": "10000", + "tradeable": "true", + "weight": "9" }, { - "examine": "A rendered down baby sea slug.", + "id": "9679", + "name": "Proselyte tasset", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9680", "name": "Sea slug glue", + "examine": "A rendered down baby sea slug.", "archery_ticket_price": "0", - "id": "9680" + "durability": null }, { - "destroy_message": "As a security precaution, your CommOrb will automatically self", - "examine": "A Temple Knight Communication Orb. Top Secret!", - "durability": null, + "id": "9681", "name": "Commorb v2", + "examine": "A Temple Knight Communication Orb. Top Secret!", "archery_ticket_price": "0", - "id": "9681" + "destroy_message": "As a security precaution, your CommOrb will automatically self", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A copy of the mysterious glyphs.", - "durability": null, + "id": "9682", "name": "Door transcription", + "examine": "A copy of the mysterious glyphs.", "archery_ticket_price": "0", - "id": "9682" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "examine": "Dead sea slug, very sticky.", - "durability": null, + "id": "9683", "name": "Dead sea slug", - "tradeable": "false", - "destroy": "true", + "examine": "Dead sea slug, very sticky.", "archery_ticket_price": "0", - "id": "9683" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get this page from Mayor Hobb's Desk.", - "examine": "A page from Maledict's holy book.", - "durability": null, + "id": "9684", "name": "Page 1", - "tradeable": "false", - "destroy": "true", - "weight": "0.1", + "examine": "A page from Maledict's holy book.", "archery_ticket_price": "0", - "id": "9684" + "destroy": "true", + "destroy_message": "You can get this page from Mayor Hobb's Desk.", + "durability": null, + "tradeable": "false", + "weight": "0.1" }, { - "destroy_message": "You can get this page from Ezekial Lovecraft.", - "examine": "A page from Maledict's holy book.", - "durability": null, + "id": "9685", "name": "Page 2", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9685" - }, - { - "destroy_message": "You will have to get the torn page from Col. O' Niall.", "examine": "A page from Maledict's holy book.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get this page from Ezekial Lovecraft.", "durability": null, + "tradeable": "false" + }, + { + "id": "9686", "name": "Page 3", - "tradeable": "false", - "destroy": "true", + "examine": "A page from Maledict's holy book.", "archery_ticket_price": "0", - "id": "9686" + "destroy": "true", + "destroy_message": "You will have to get the torn page from Col. O' Niall.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A piece of torn page.", - "durability": null, + "id": "9687", "name": "Fragment 1", + "examine": "A piece of torn page.", "archery_ticket_price": "0", - "id": "9687" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A piece of torn page.", - "durability": null, + "id": "9688", "name": "Fragment 2", - "archery_ticket_price": "0", - "id": "9688" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", "examine": "A piece of torn page.", - "durability": null, + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "9689", "name": "Fragment 3", + "examine": "A piece of torn page.", "archery_ticket_price": "0", - "id": "9689" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "Are you sure you wish to destroy this?", - "examine": "A blank water rune.", - "durability": null, + "id": "9690", "name": "Blank water rune", - "tradeable": "false", - "destroy": "true", + "examine": "A blank water rune.", "archery_ticket_price": "0", - "id": "9690" + "destroy": "true", + "destroy_message": "Are you sure you wish to destroy this?", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "6", - "durability": null, + "id": "9691", "name": "Water rune", - "tradeable": "true", + "examine": "One of the 4 basic elemental Runes.", "archery_ticket_price": "0", - "id": "9691" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "destroy_message": "Are you sure you wish to destroy this?", - "examine": "A blank air rune.", - "durability": null, + "id": "9692", "name": "Blank air rune", - "tradeable": "false", - "destroy": "true", + "examine": "A blank air rune.", "archery_ticket_price": "0", - "id": "9692" + "destroy": "true", + "destroy_message": "Are you sure you wish to destroy this?", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "9", - "durability": null, + "id": "9693", "name": "Air rune", - "tradeable": "true", + "examine": "One of the 4 basic elemental Runes.", "archery_ticket_price": "0", - "id": "9693" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "destroy_message": "Are you sure you wish to destroy this?", - "examine": "A blank earth rune.", - "durability": null, + "id": "9694", "name": "Blank earth rune", - "tradeable": "false", - "destroy": "true", + "examine": "A blank earth rune.", "archery_ticket_price": "0", - "id": "9694" + "destroy": "true", + "destroy_message": "Are you sure you wish to destroy this?", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "17", - "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "7", - "durability": null, + "id": "9695", "name": "Earth rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9695" - }, - { - "destroy_message": "Are you sure you wish to destroy this?", - "examine": "A blank mind rune.", - "durability": null, - "name": "Blank mind rune", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9696" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "17", - "examine": "Used for basic missile spells.", - "grand_exchange_price": "6", - "durability": null, - "name": "Mind rune", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9697" - }, - { - "destroy_message": "Are you sure you wish to destroy this?", - "examine": "A blank fire rune.", - "durability": null, - "name": "Blank fire rune", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9698" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "17", "examine": "One of the 4 basic elemental Runes.", - "grand_exchange_price": "16", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "shop_price": "17", + "tradeable": "true" + }, + { + "id": "9696", + "name": "Blank mind rune", + "examine": "A blank mind rune.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you wish to destroy this?", + "durability": null, + "tradeable": "false" + }, + { + "id": "9697", + "name": "Mind rune", + "examine": "Used for basic missile spells.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "17", + "tradeable": "true" + }, + { + "id": "9698", + "name": "Blank fire rune", + "examine": "A blank fire rune.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you wish to destroy this?", + "durability": null, + "tradeable": "false" + }, + { + "id": "9699", "name": "Fire rune", - "tradeable": "true", + "examine": "One of the 4 basic elemental Runes.", "archery_ticket_price": "0", - "id": "9699" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "17", + "tradeable": "true" }, { - "durability": null, + "id": "9701", "name": "Torch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9701" + "durability": null, + "tradeable": "true" }, { - "examine": "A big, bad troll.", - "durability": null, + "id": "9702", "name": "Stick", + "examine": "A big, bad troll.", "archery_ticket_price": "0", "attack_speed": "6", - "id": "9702", - "weapon_interface": "5", - "equipment_slot": "3" + "durability": null, + "equipment_slot": "3", + "weapon_interface": "5" }, { - "shop_price": "35", + "id": "9703", + "name": "Training sword", "examine": "Basic training sword.", - "durability": null, - "weight": "1.8", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "397", - "equipment_slot": "3", + "archery_ticket_price": "0", "attack_anims": "381,390,390,390", "attack_audios": "2500,2500,2517,2500", - "name": "Training sword", - "archery_ticket_price": "0", - "id": "9703", - "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0" - }, - { - "examine": "Made of flimsy painted wood.", - "durability": null, - "name": "Training shield", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "9704", - "bonuses": "0,0,0,0,0,4,5,3,1,4,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "examine": "Light and flexible, good for a beginner.", - "durability": null, - "destroy": "true", - "weight": "1.3", "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "16", - "defence_anim": "424", + "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2248", "equipment_slot": "3", + "render_anim": "2584", + "shop_price": "35", + "weapon_interface": "5", + "weight": "1.8" + }, + { + "id": "9704", + "name": "Training shield", + "examine": "Made of flimsy painted wood.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,4,5,3,1,4,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "weight": "5.4" + }, + { + "id": "9705", + "name": "Training bow", + "examine": "Light and flexible, good for a beginner.", + "archery_ticket_price": "0", "attack_anims": "426,426,426,426", "attack_audios": "2700,0,0,0", - "name": "Training bow", + "attack_speed": "4", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "destroy": "true", + "durability": null, + "equipment_slot": "3", "tradeable": "false", - "archery_ticket_price": "0", - "id": "9705", - "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0" + "two_handed": "true", + "weapon_interface": "16", + "weight": "1.3" }, { - "examine": "Standard training arrows.", - "durability": null, - "name": "Training arrows", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "9706", + "name": "Training arrows", + "examine": "Standard training arrows.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", - "equipment_slot": "13" + "destroy": "true", + "durability": null, + "equipment_slot": "13", + "tradeable": "false" }, { - "examine": "Book of the elemental shield.", - "durability": null, + "id": "9715", "name": "Slashed book", - "weight": "0.1", + "examine": "Book of the elemental shield.", "archery_ticket_price": "0", - "id": "9715" + "durability": null, + "weight": "0.1" }, { - "examine": "Book of the elemental helm.", - "durability": null, + "id": "9717", "name": "Beaten book", - "weight": "0.1", + "examine": "Book of the elemental helm.", "archery_ticket_price": "0", - "id": "9717" + "durability": null, + "weight": "0.1" }, { - "examine": "On the subject of lava dippers.", - "durability": null, + "id": "9718", "name": "Crane schematic", + "examine": "On the subject of lava dippers.", "archery_ticket_price": "0", - "id": "9718" + "durability": null }, { - "examine": "A scroll with a lever schematic drawn on it.", - "durability": null, + "id": "9719", "name": "Lever schematic", + "examine": "A scroll with a lever schematic drawn on it.", "archery_ticket_price": "0", - "id": "9719" + "durability": null }, { - "examine": "A crane claw.", - "durability": null, + "id": "9720", "name": "Crane claw", - "weight": "1", + "examine": "A crane claw.", "archery_ticket_price": "0", - "id": "9720" + "durability": null, + "weight": "1" }, { - "examine": "A pipe that belongs in a cannon stand.", - "durability": null, + "id": "9721", + "name": "Scroll", + "examine": "A scroll with some writing on it." + }, + { + "id": "9722", + "name": "Key", + "examine": "Quite a small key." + }, + { + "id": "9723", "name": "Pipe", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", + "examine": "A pipe that belongs in a cannon stand.", "archery_ticket_price": "0", - "id": "9723" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "0.2" }, { - "examine": "A large cog.", - "durability": null, + "id": "9724", "name": "Large cog", - "weight": "1", + "examine": "A large cog.", "archery_ticket_price": "0", - "id": "9724" + "durability": null, + "weight": "1" }, { - "examine": "A medium cog.", - "durability": null, + "id": "9725", "name": "Medium cog", - "weight": "1", + "examine": "A medium cog.", "archery_ticket_price": "0", - "id": "9725" + "durability": null, + "weight": "1" }, { - "examine": "A small cog.", - "durability": null, + "id": "9726", "name": "Small cog", - "weight": "1", + "examine": "A small cog.", "archery_ticket_price": "0", - "id": "9726" + "durability": null, + "weight": "1" }, { - "examine": "A primed elemental ingot.", - "durability": null, + "id": "9727", "name": "Primed bar", - "weight": "1.8", + "examine": "A primed elemental ingot.", "archery_ticket_price": "0", - "id": "9727" + "durability": null, + "weight": "1.8" }, { - "examine": "An elemental mind ingot.", - "durability": null, + "id": "9728", "name": "Elemental mind bar", - "weight": "1", + "examine": "An elemental mind ingot.", "archery_ticket_price": "0", - "id": "9728" + "durability": null, + "weight": "1" }, { - "ge_buy_limit": "100", - "examine": "A helmet made in the Elemental Workshop.", - "grand_exchange_price": "196", - "durability": null, - "name": "Elemental helmet", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", "id": "9729", - "bonuses": "0,0,0,0,0,0,0,0,4,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "196", - "durability": null, "name": "Elemental helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9730" - }, - { - "ge_buy_limit": "100", - "examine": "A shield made in the Elemental Workshop.", - "grand_exchange_price": "8351", - "durability": null, - "name": "Mind shield", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "9731", - "bonuses": "0,0,0,0,0,0,0,0,9,0,25,0,0,0,0", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8351", - "durability": null, - "name": "Mind shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9732" - }, - { - "shop_price": "1200", - "ge_buy_limit": "100", "examine": "A helmet made in the Elemental Workshop.", - "grand_exchange_price": "1589", - "durability": null, - "name": "Mind helmet", - "tradeable": "true", - "weight": "0.1", "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "9730", + "name": "Elemental helmet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9731", + "name": "Mind shield", + "examine": "A shield made in the Elemental Workshop.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,9,0,25,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "9732", + "name": "Mind shield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "9733", - "bonuses": "0,0,0,0,0,0,0,0,6,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1589", - "durability": null, "name": "Mind helmet", - "tradeable": "true", + "examine": "A helmet made in the Elemental Workshop.", "archery_ticket_price": "0", - "id": "9734" + "bonuses": "0,0,0,0,0,0,0,0,6,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "shop_price": "1200", + "tradeable": "true", + "weight": "0.1" }, { - "ge_buy_limit": "10000", + "id": "9734", + "name": "Mind helmet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9735", + "name": "Desert goat horn", "examine": "Not much good for blowing.", - "grand_exchange_price": "902", - "durability": null, - "name": "Desert goat horn", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "9735" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "10000", + "id": "9736", + "name": "Goat horn dust", "examine": "Finely ground desert goat horn.", - "grand_exchange_price": "1082", - "durability": null, - "name": "Goat horn dust", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "9736" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "1082", - "durability": null, + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "9737", "name": "Goat horn dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9737" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "durability": null, + "id": "9738", "name": "Desert goat horn", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9738" + "durability": null, + "tradeable": "true" }, { - "shop_price": "207", - "ge_buy_limit": "100", + "id": "9739", + "name": "Combat potion(4)", "examine": "4 doses of combat potion.", - "grand_exchange_price": "45", - "durability": null, - "name": "Combat potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9739" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "45", - "durability": null, - "name": "Combat potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9740" - }, - { "shop_price": "207", + "tradeable": "true" + }, + { + "id": "9740", + "name": "Combat potion(4)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9741", + "name": "Combat potion(3)", "examine": "3 doses of combat potion.", - "grand_exchange_price": "25", - "durability": null, - "name": "Combat potion(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9741" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "25", - "durability": null, - "name": "Combat potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9742" - }, - { "shop_price": "207", + "tradeable": "true" + }, + { + "id": "9742", + "name": "Combat potion(3)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9743", + "name": "Combat potion(2)", "examine": "2 doses of combat potion.", - "grand_exchange_price": "19", - "durability": null, - "name": "Combat potion(2)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9743" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, - "name": "Combat potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9744" - }, - { "shop_price": "207", + "tradeable": "true" + }, + { + "id": "9744", + "name": "Combat potion(2)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "9745", + "name": "Combat potion(1)", "examine": "1 dose of combat potion.", - "grand_exchange_price": "72", - "durability": null, - "name": "Combat potion(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9745" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "72", - "durability": null, - "name": "Combat potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9746" + "shop_price": "207", + "tradeable": "true" }, { - "requirements": "{0,99}", - "shop_price": "99000", - "examine": "The cape worn by masters of attack.", - "durability": null, - "name": "Attack cape", - "tradeable": "false", - "weight": "0.4", + "id": "9746", + "name": "Combat potion(1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "9747", + "name": "Attack cape", + "examine": "The cape worn by masters of attack.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{0,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{0,99}", - "durability": null, - "name": "Attack cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9748", + "name": "Attack cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{0,99}", + "tradeable": "false" }, { + "id": "9749", + "name": "Attack hood", + "examine": "Attack skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{0,99}", "shop_price": "99000", - "examine": "Attack skillcape hood.", - "durability": null, - "name": "Attack hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9749", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{2,99}", - "shop_price": "99000", - "examine": "The cape only worn by the strongest people.", - "durability": null, - "name": "Strength cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9750", + "name": "Strength cape", + "examine": "The cape only worn by the strongest people.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{2,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{2,99}", - "durability": null, - "name": "Strength cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9751", + "name": "Strength cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{2,99}", + "tradeable": "false" }, { + "id": "9752", + "name": "Strength hood", + "examine": "Strength skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{2,99}", "shop_price": "99000", - "examine": "Strength skillcape hood.", - "durability": null, - "name": "Strength hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9752", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{1,99}", - "shop_price": "99000", - "examine": "The cape worn by masters of the art of Defence.", - "durability": null, - "name": "Defence cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9753", + "name": "Defence cape", + "examine": "The cape worn by masters of the art of Defence.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{1,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{1,99}", - "durability": null, - "name": "Defence cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9754", + "name": "Defence cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{1,99}", + "tradeable": "false" }, { + "id": "9755", + "name": "Defence hood", + "examine": "Defence skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,99}", "shop_price": "99000", - "examine": "Defence skillcape hood.", - "durability": null, - "name": "Defence hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9755", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{4,99}", - "shop_price": "99000", - "examine": "The cape worn by master archers.", - "durability": null, - "name": "Ranging cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9756", + "name": "Ranging cape", + "examine": "The cape worn by master archers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{4,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{4,99}", - "durability": null, - "name": "Ranging cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9757", + "name": "Ranging cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{4,99}", + "tradeable": "false" }, { + "id": "9758", + "name": "Ranging hood", + "examine": "Range skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{4,99}", "shop_price": "99000", - "examine": "Range skillcape hood.", - "durability": null, - "name": "Ranging hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9758", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{5,99}", - "shop_price": "99000", - "examine": "The cape worn by the most pious of heroes.", - "durability": null, - "name": "Prayer cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9759", + "name": "Prayer cape", + "examine": "The cape worn by the most pious of heroes.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{5,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{5,99}", - "durability": null, - "name": "Prayer cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9760", + "name": "Prayer cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{5,99}", + "tradeable": "false" }, { + "id": "9761", + "name": "Prayer hood", + "examine": "Prayer skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{5,99}", "shop_price": "99000", - "examine": "Prayer skillcape hood.", - "durability": null, - "name": "Prayer hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9761", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{6,99}", - "shop_price": "99000", - "examine": "The cape worn by the most powerful mages.", - "durability": null, - "name": "Magic cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9762", + "name": "Magic cape", + "examine": "The cape worn by the most powerful mages.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{6,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{6,99}", - "durability": null, - "name": "Magic cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9763", + "name": "Magic cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{6,99}", + "tradeable": "false" }, { + "id": "9764", + "name": "Magic hood", + "examine": "Magic skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{6,99}", "shop_price": "99000", - "examine": "Magic skillcape hood.", - "durability": null, - "name": "Magic hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9764", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{20,99}", - "shop_price": "99000", - "examine": "The cape worn by master runecrafters.", - "durability": null, - "name": "Runecraft cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9765", + "name": "Runecraft cape", + "examine": "The cape worn by master runecrafters.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{20,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{20,99}", - "durability": null, - "name": "Runecraft cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9766", + "name": "Runecraft cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{20,99}", + "tradeable": "false" }, { + "id": "9767", + "name": "Runecrafting hood", + "examine": "Runecrafting skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{20,99}", "shop_price": "99000", - "examine": "Runecrafting skillcape hood.", - "durability": null, - "name": "Runecrafting hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9767", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{3,99}", - "shop_price": "99000", - "examine": "The cape worn by well-constituted adventurers.", - "durability": null, - "name": "Hitpoints cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9768", + "name": "Hitpoints cape", + "examine": "The cape worn by well-constituted adventurers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{3,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{3,99}", - "durability": null, - "name": "Hitpoints cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9769", + "name": "Hitpoints cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{3,99}", + "tradeable": "false" }, { + "id": "9770", + "name": "Hitpoints hood", + "examine": "Constitution skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{3,99}", "shop_price": "99000", - "examine": "Constitution skillcape hood.", - "durability": null, - "name": "Hitpoints hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9770", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{16,99}", - "shop_price": "99000", - "examine": "The cape worn by the most agile of heroes.", - "durability": null, - "name": "Agility cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9771", + "name": "Agility cape", + "examine": "The cape worn by the most agile of heroes.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{16,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{16,99}", - "durability": null, - "name": "Agility cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9772", + "name": "Agility cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{16,99}", + "tradeable": "false" }, { + "id": "9773", + "name": "Agility hood", + "examine": "Agility skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{16,99}", "shop_price": "99000", - "examine": "Agility skillcape hood.", - "durability": null, - "name": "Agility hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9773", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{15,99}", - "shop_price": "99000", - "examine": "The cape worn by the most skilled at the art of herblore.", - "durability": null, - "name": "Herblore cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9774", + "name": "Herblore cape", + "examine": "The cape worn by the most skilled at the art of herblore.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{15,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{15,99}", - "durability": null, - "name": "Herblore cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9775", + "name": "Herblore cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{15,99}", + "tradeable": "false" }, { + "id": "9776", + "name": "Herblore hood", + "examine": "Herblore skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{15,99}", "shop_price": "99000", - "examine": "Herblore skillcape hood.", - "durability": null, - "name": "Herblore hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9776", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{17,99}", - "shop_price": "99000", - "examine": "The cape worn by master thieves.", - "durability": null, - "name": "Thieving cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9777", + "name": "Thieving cape", + "examine": "The cape worn by master thieves.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{17,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{17,99}", - "durability": null, - "name": "Thieving cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9778", + "name": "Thieving cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{17,99}", + "tradeable": "false" }, { + "id": "9779", + "name": "Thieving hood", + "examine": "Thieving skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{17,99}", "shop_price": "99000", - "examine": "Thieving skillcape hood.", - "durability": null, - "name": "Thieving hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9779", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{12,99}", - "shop_price": "99000", - "examine": "The cape worn by master craftworkers.", - "durability": null, - "name": "Crafting cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9780", + "name": "Crafting cape", + "examine": "The cape worn by master craftworkers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{12,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{12,99}", - "durability": null, - "name": "Crafting cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9781", + "name": "Crafting cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{12,99}", + "tradeable": "false" }, { + "id": "9782", + "name": "Crafting hood", + "examine": "Crafting skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{12,99}", "shop_price": "99000", - "examine": "Crafting skillcape hood.", - "durability": null, - "name": "Crafting hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9782", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{9,99}", - "shop_price": "99000", - "examine": "The cape worn by the best of fletchers.", - "durability": null, - "name": "Fletching cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9783", + "name": "Fletching cape", + "examine": "The cape worn by the best of fletchers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{9,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{9,99}", - "durability": null, - "name": "Fletching cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9784", + "name": "Fletching cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{9,99}", + "tradeable": "false" }, { + "id": "9785", + "name": "Fletching hood", + "examine": "Fletching skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{9,99}", "shop_price": "99000", - "examine": "Fletching skillcape hood.", - "durability": null, - "name": "Fletching hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9785", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{18,99}", - "shop_price": "99000", - "examine": "The cape worn by slayer masters.", - "durability": null, - "name": "Slayer cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9786", + "name": "Slayer cape", + "examine": "The cape worn by slayer masters.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{18,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{18,99}", - "durability": null, - "name": "Slayer cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9787", + "name": "Slayer cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{18,99}", + "tradeable": "false" }, { + "id": "9788", + "name": "Slayer hood", + "examine": "Slayer skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{18,99}", "shop_price": "99000", - "examine": "Slayer skillcape hood.", - "durability": null, - "name": "Slayer hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9788", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{22,99}", - "shop_price": "99000", - "examine": "The cape worn by master builders.", - "durability": null, - "name": "Construct. cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9789", + "name": "Construct. cape", + "examine": "The cape worn by master builders.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{22,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{22,99}", - "durability": null, - "name": "Construct. cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9790", + "name": "Construct. cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{22,99}", + "tradeable": "false" }, { + "id": "9791", + "name": "Construct. hood", + "examine": "Construction skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{22,99}", "shop_price": "99000", - "examine": "Construction skillcape hood.", - "durability": null, - "name": "Construct. hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9791", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{14,99}", - "shop_price": "99000", - "examine": "The cape worn by the most skilled miners.", - "durability": null, - "name": "Mining cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9792", + "name": "Mining cape", + "examine": "The cape worn by the most skilled miners.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{14,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{14,99}", - "durability": null, - "name": "Mining cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9793", + "name": "Mining cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{14,99}", + "tradeable": "false" }, { + "id": "9794", + "name": "Mining hood", + "examine": "Mining skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{14,99}", "shop_price": "99000", - "examine": "Mining skillcape hood.", - "durability": null, - "name": "Mining hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9794", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{13,99}", - "shop_price": "99000", - "examine": "The cape worn by master smiths.", - "durability": null, - "name": "Smithing cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9795", + "name": "Smithing cape", + "examine": "The cape worn by master smiths.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{13,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{13,99}", - "durability": null, - "name": "Smithing cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9796", + "name": "Smithing cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{13,99}", + "tradeable": "false" }, { + "id": "9797", + "name": "Smithing hood", + "examine": "Smithing skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{13,99}", "shop_price": "99000", - "examine": "Smithing skillcape hood.", - "durability": null, - "name": "Smithing hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9797", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{10,99}", - "shop_price": "99000", - "examine": "The cape worn by the best fishermen.", - "durability": null, - "name": "Fishing cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9798", + "name": "Fishing cape", + "examine": "The cape worn by the best fishermen.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{10,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{10,99}", - "durability": null, - "name": "Fishing cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9799", + "name": "Fishing cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{10,99}", + "tradeable": "false" }, { + "id": "9800", + "name": "Fishing hood", + "examine": "Fishing skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{10,99}", "shop_price": "99000", - "examine": "Fishing skillcape hood.", - "durability": null, - "name": "Fishing hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9800", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{7,99}", - "shop_price": "99000", - "examine": "The cape worn by the world's best chefs.", - "durability": null, - "name": "Cooking cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9801", + "name": "Cooking cape", + "examine": "The cape worn by the world's best chefs.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{7,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{7,99}", - "durability": null, - "name": "Cooking cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9802", + "name": "Cooking cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{7,99}", + "tradeable": "false" }, { + "id": "9803", + "name": "Cooking hood", + "examine": "Cooking skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{7,99}", "shop_price": "99000", - "examine": "Cooking skillcape hood.", - "durability": null, - "name": "Cooking hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9803", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{11,99}", - "shop_price": "99000", - "examine": "The cape worn by master firelighters.", - "durability": null, - "name": "Firemaking cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9804", + "name": "Firemaking cape", + "examine": "The cape worn by master firelighters.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{11,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{11,99}", - "durability": null, - "name": "Firemaking cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9805", + "name": "Firemaking cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{11,99}", + "tradeable": "false" }, { + "id": "9806", + "name": "Firemaking hood", + "examine": "Firemaking skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{11,99}", "shop_price": "99000", - "examine": "Firemaking skillcape hood.", - "durability": null, - "name": "Firemaking hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9806", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{8,99}", - "shop_price": "99000", - "examine": "The cape worn by master woodcutters (Obtaining level 99 skill)", - "durability": null, - "name": "Woodcutting cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9807", + "name": "Woodcutting cape", + "examine": "The cape worn by master woodcutters (Obtaining level 99 skill)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{8,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{8,99}", - "durability": null, - "name": "Woodcut. cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9808", + "name": "Woodcut. cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{8,99}", + "tradeable": "false" }, { + "id": "9809", + "name": "Woodcutting hood", + "examine": "Woodcutting skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{8,99}", "shop_price": "99000", - "examine": "Woodcutting skillcape hood.", - "durability": null, - "name": "Woodcutting hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9809", - "equipment_slot": "0" + "weight": "0.4" }, { - "requirements": "{19,99}", - "shop_price": "99000", - "examine": "The cape worn by master farmers.", - "durability": null, - "name": "Farming cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9810", + "name": "Farming cape", + "examine": "The cape worn by master farmers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{19,99}", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "requirements": "{19,99}", - "durability": null, - "name": "Farming cape(t)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "9811", + "name": "Farming cape(t)", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{19,99}", + "tradeable": "false" }, { + "id": "9812", + "name": "Farming hood", + "examine": "Farming skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{19,99}", "shop_price": "99000", - "examine": "Farming skillcape hood.", - "durability": null, - "name": "Farming hood", "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9812", - "equipment_slot": "0" + "weight": "0.4" }, { - "shop_price": "99000", - "examine": "The cape worn by only the most experienced adventurers.", - "durability": null, - "name": "Quest point cape", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9813", + "name": "Quest point cape", + "examine": "The cape worn by only the most experienced adventurers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "remove_head": "true", - "shop_price": "99000", - "examine": "Quest skillcape hood.", - "durability": null, - "name": "Quest point hood", - "tradeable": "false", - "weight": "0.4", - "archery_ticket_price": "0", "id": "9814", - "equipment_slot": "0" + "name": "Quest point hood", + "examine": "Quest skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "99000", + "tradeable": "false", + "weight": "0.4" }, { - "examine": "A woolly bobble hat.", - "durability": null, - "name": "Bobble hat", - "tradeable": "false", - "destroy": "true", - "weight": "0.25", - "archery_ticket_price": "0", "id": "9815", - "equipment_slot": "0" + "name": "Bobble hat", + "examine": "A woolly bobble hat.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "0.25" }, { - "examine": "A woolly scarf.", - "durability": null, - "name": "Bobble scarf", - "weight": "0.25", - "archery_ticket_price": "0", "id": "9816", - "equipment_slot": "2" + "name": "Bobble scarf", + "examine": "A woolly scarf.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "0.25" }, { - "grand_exchange_price": "1", - "durability": null, + "id": "9817", "name": "Oak cape rack", "archery_ticket_price": "0", - "id": "9817" + "durability": null }, { - "grand_exchange_price": "88", - "durability": null, + "id": "9818", "name": "Teak cape rack", "archery_ticket_price": "0", - "id": "9818" + "durability": null }, { - "grand_exchange_price": "120", - "durability": null, + "id": "9819", "name": "M'gany cape rack", "archery_ticket_price": "0", - "id": "9819" + "durability": null }, { - "grand_exchange_price": "136025", - "durability": null, + "id": "9820", "name": "Gilded cape rack", "archery_ticket_price": "0", - "id": "9820" + "durability": null }, { - "grand_exchange_price": "328598", - "durability": null, + "id": "9821", "name": "Marble cape rack", "archery_ticket_price": "0", - "id": "9821" + "durability": null }, { - "grand_exchange_price": "979747", - "durability": null, + "id": "9822", "name": "Magical cape rack", "archery_ticket_price": "0", - "id": "9822" + "durability": null }, { - "grand_exchange_price": "59", - "durability": null, + "id": "9823", "name": "Oak costume box", "archery_ticket_price": "0", - "id": "9823" + "durability": null }, { - "grand_exchange_price": "122", - "durability": null, + "id": "9824", "name": "Teak costume box", "archery_ticket_price": "0", - "id": "9824" + "durability": null }, { - "grand_exchange_price": "59", - "durability": null, + "id": "9825", "name": "Mahogany cos box", "archery_ticket_price": "0", - "id": "9825" + "durability": null }, { - "grand_exchange_price": "15", - "durability": null, + "id": "9826", "name": "Oak armour case", "archery_ticket_price": "0", - "id": "9826" + "durability": null }, { - "grand_exchange_price": "27", - "durability": null, + "id": "9827", "name": "Teak armour case", "archery_ticket_price": "0", - "id": "9827" + "durability": null }, { - "grand_exchange_price": "90", - "durability": null, + "id": "9828", "name": "M'gany arm'r case", "archery_ticket_price": "0", - "id": "9828" + "durability": null }, { - "grand_exchange_price": "103", - "durability": null, + "id": "9829", "name": "Oak magic wardrobe", "archery_ticket_price": "0", - "id": "9829" + "durability": null }, { - "grand_exchange_price": "1", - "durability": null, + "id": "9830", "name": "Carved oak magic wardrobe", "archery_ticket_price": "0", - "id": "9830" + "durability": null }, { - "grand_exchange_price": "127", - "durability": null, + "id": "9831", "name": "Teak magic wardrobe", "archery_ticket_price": "0", - "id": "9831" + "durability": null }, { - "grand_exchange_price": "13", - "durability": null, + "id": "9832", "name": "Carved teak magic wardrobe", "archery_ticket_price": "0", - "id": "9832" + "durability": null }, { - "grand_exchange_price": "135", - "durability": null, + "id": "9833", "name": "Mahogany magic wardrobe", "archery_ticket_price": "0", - "id": "9833" + "durability": null }, { - "grand_exchange_price": "137267", - "durability": null, + "id": "9834", "name": "Gilded magic wardrobe", "archery_ticket_price": "0", - "id": "9834" + "durability": null }, { - "grand_exchange_price": "341567", - "durability": null, + "id": "9835", "name": "Marble magic wardrobe", "archery_ticket_price": "0", - "id": "9835" + "durability": null }, { - "grand_exchange_price": "21", - "durability": null, + "id": "9836", "name": "Oak toy box", "archery_ticket_price": "0", - "id": "9836" + "durability": null }, { - "grand_exchange_price": "151", - "durability": null, + "id": "9837", "name": "Teak toy box", "archery_ticket_price": "0", - "id": "9837" + "durability": null }, { - "grand_exchange_price": "20", - "durability": null, + "id": "9838", "name": "Mahogany toy box", "archery_ticket_price": "0", - "id": "9838" + "durability": null }, { - "grand_exchange_price": "21", - "durability": null, + "id": "9839", "name": "Oak treasure chest", "archery_ticket_price": "0", - "id": "9839" + "durability": null }, { - "grand_exchange_price": "157", - "durability": null, + "id": "9840", "name": "Teak treas' chest", "archery_ticket_price": "0", - "id": "9840" + "durability": null }, { - "grand_exchange_price": "39", - "durability": null, + "id": "9841", "name": "M'gany treas' chest", "archery_ticket_price": "0", - "id": "9841" + "durability": null }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3", + "id": "9843", + "name": "Oak cape rack", "examine": "A ready-to-assemble oak cape rack.", - "durability": null, - "name": "Oak cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9843" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "92", + "id": "9844", + "name": "Teak cape rack", "examine": "A ready-to-assemble teak cape rack..", - "durability": null, - "name": "Teak cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9844" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "111", + "id": "9845", + "name": "M'gany cape rack", "examine": "A ready-to-assemble mahogany cape rack.", - "durability": null, - "name": "M'gany cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9845" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "130900", + "id": "9846", + "name": "Gilded cape rack", "examine": "A ready-to-assemble gilded mahogany rack.", - "durability": null, - "name": "Gilded cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9846" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "329500", + "id": "9847", + "name": "Marble cape rack", "examine": "A ready-to-assemble marble cape rack.", - "durability": null, - "name": "Marble cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9847" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1000000", + "id": "9848", + "name": "Magical cape rack", "examine": "A ready-to-assemble magic cape rack.", - "durability": null, - "name": "Magical cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9848" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "25", + "id": "9849", + "name": "Oak toy box", "examine": "A ready-to-assemble oak toy box.", - "durability": null, - "name": "Oak toy box", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9849" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "165", + "id": "9850", + "name": "Teak toy box", "examine": "A ready-to-assemble teak toy box.", - "durability": null, - "name": "Teak toy box", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9850" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "20", + "id": "9851", + "name": "Mahogany toy box", "examine": "A ready-to-assemble mahogany toy box.", - "durability": null, - "name": "Mahogany toy box", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9851" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "111", - "examine": "A ready-to-assemble oak magic wardrobe.", - "durability": null, + "id": "9852", "name": "Oak magic wardrobe", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "1", - "id": "9852" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1", "examine": "A ready-to-assemble oak magic wardrobe.", - "durability": null, - "name": "Carved oak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9853" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { + "id": "9853", + "name": "Carved oak magic wardrobe", + "examine": "A ready-to-assemble oak magic wardrobe.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "133", + "tradeable": "true", + "weight": "1" + }, + { + "id": "9854", + "name": "Teak magic wardrobe", "examine": "A ready-to-assemble teak magic wardrobe.", - "durability": null, - "name": "Teak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9854" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "15", + "id": "9855", + "name": "Carved teak magic wardrobe", "examine": "A ready-to-assemble carved teak magic wardrobe.", - "durability": null, - "name": "Carved teak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9855" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "129", + "id": "9856", + "name": "Mahogany magic wardrobe", "examine": "A ready-to-assemble mahogany magic wardrobe.", - "durability": null, - "name": "Mahogany magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9856" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "137700", + "id": "9857", + "name": "Gilded magic wardrobe", "examine": "A ready-to-assemble gilded mahogany magic wardrobe.", - "durability": null, - "name": "Gilded magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9857" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "335800", + "id": "9858", + "name": "Marble magic wardrobe", "examine": "A ready-to-assemble marble magic wardrobe.", - "durability": null, - "name": "Marble magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9858" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "17", + "id": "9859", + "name": "Oak armour case", "examine": "A ready-to-assemble oak armour case.", - "durability": null, - "name": "Oak armour case", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9859" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "29", + "id": "9860", + "name": "Teak armour case", "examine": "A ready-to-assemble teak armour case.", - "durability": null, - "name": "Teak armour case", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9860" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "88", + "id": "9861", + "name": "M'gany arm'r case", "examine": "A ready-to-assemble mahogany armour case.", - "durability": null, - "name": "M'gany arm'r case", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9861" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "24", + "id": "9862", + "name": "Oak treasure chest", "examine": "A ready-to-assemble oak treasure chest.", - "durability": null, - "name": "Oak treasure chest", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9862" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "164", + "id": "9863", + "name": "Teak treas' chest", "examine": "A ready-to-assemble teak treasure chest.", - "durability": null, - "name": "Teak treas' chest", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9863" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "41", + "id": "9864", + "name": "M'gany treas' chest", "examine": "A ready-to-assemble mahogany treasure chest.", - "durability": null, - "name": "M'gany treas' chest", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9864" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "62", - "durability": null, + "id": "9865", "name": "Oak costume box", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9865" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "135", - "durability": null, + "id": "9866", "name": "Teak costume box", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "1", - "id": "9866" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "60", - "durability": null, - "name": "Mahogany cos box", "tradeable": "true", - "archery_ticket_price": "0", - "weight": "1", - "id": "9867" + "weight": "1" }, { + "id": "9867", + "name": "Mahogany cos box", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "9868", "name": "Oak cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9868" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9869", "name": "Teak cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9869" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9870", "name": "M'gany cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9870" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9871", "name": "Gilded cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9871" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9872", "name": "Marble cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9872" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9873", "name": "Magical cape rack", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9873" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9874", "name": "Oak toy box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9874" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9875", "name": "Teak toy box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9875" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9876", "name": "Mahogany toy box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9876" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9877", "name": "Oak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9877" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9878", "name": "Carved oak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9878" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9879", "name": "Teak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9879" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9880", "name": "Carved teak magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9880" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9881", "name": "Mahogany magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9881" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9882", "name": "Gilded magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9882" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9883", "name": "Marble magic wardrobe", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9883" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9884", "name": "Oak armour case", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9884" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9885", "name": "Teak armour case", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9885" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9886", "name": "M'gany arm'r case", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9886" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9887", "name": "Oak treasure chest", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9887" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9888", "name": "Teak treas' chest", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9888" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9889", "name": "M'gany treas' chest", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9889" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9890", "name": "Oak costume box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9890" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9891", "name": "Teak costume box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9891" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "9892", "name": "Mahogany cos box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9892" + "durability": null, + "tradeable": "true" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A lump that at some point might have been a gout tuber.", - "durability": null, + "id": "9901", "name": "Goutweedy lump", - "tradeable": "false", - "destroy": "true", + "examine": "A lump that at some point might have been a gout tuber.", "archery_ticket_price": "0", - "id": "9901" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pile of gout tubers suitable for use in mountainous terrain.", - "durability": null, + "id": "9902", "name": "Hardy gout tubers", - "tradeable": "false", - "destroy": "true", + "examine": "A pile of gout tubers suitable for use in mountainous terrain.", "archery_ticket_price": "0", - "id": "9902" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "My Arm will probably have a spare copy.", - "examine": "Farmer Gricoller's Farming Manual.", - "durability": null, + "id": "9903", "name": "Farming manual", - "tradeable": "false", - "destroy": "true", + "examine": "Farmer Gricoller's Farming Manual.", "archery_ticket_price": "0", - "id": "9903" + "destroy": "true", + "destroy_message": "My Arm will probably have a spare copy.", + "durability": null, + "tradeable": "false" }, { - "examine": "A book for sailors.", - "durability": null, + "id": "9904", "name": "Sailing book", + "examine": "A book for sailors.", "archery_ticket_price": "0", - "id": "9904" + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, - "name": "Ghost buster 500", - "archery_ticket_price": "0", "id": "9906", + "name": "Ghost buster 500", + "examine": "See article", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, - "name": "Ghost buster 500", - "archery_ticket_price": "0", "id": "9907", + "name": "Ghost buster 500", + "examine": "See article", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, - "name": "Ghost buster 500", - "archery_ticket_price": "0", "id": "9908", + "name": "Ghost buster 500", + "examine": "See article", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, - "name": "Ghost buster 500", - "archery_ticket_price": "0", "id": "9909", + "name": "Ghost buster 500", + "examine": "See article", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, - "name": "Ghost buster 500", - "archery_ticket_price": "0", "id": "9910", + "name": "Ghost buster 500", + "examine": "See article", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, - "name": "Ghost buster 500", - "archery_ticket_price": "0", "id": "9911", - "equipment_slot": "3" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "See article", - "durability": null, "name": "Ghost buster 500", + "examine": "See article", "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3" + }, + { "id": "9912", + "name": "Ghost buster 500", + "examine": "See article", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A white destabiliser for use in a ghost buster.", - "durability": null, - "name": "White destabiliser", - "archery_ticket_price": "0", "id": "9913", + "name": "White destabiliser", + "examine": "A white destabiliser for use in a ghost buster.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "5" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A red destabiliser for use in a ghost buster.", - "durability": null, - "name": "Red destabiliser", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "9914", - "equipment_slot": "5" + "name": "Red destabiliser", + "examine": "A red destabiliser for use in a ghost buster.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "5", + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A blue destabiliser for use in a ghost buster.", - "durability": null, - "name": "Blue destabiliser", - "archery_ticket_price": "0", "id": "9915", + "name": "Blue destabiliser", + "examine": "A blue destabiliser for use in a ghost buster.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "5" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A green destabiliser for use in a ghost buster.", - "durability": null, - "name": "Green destabiliser", - "archery_ticket_price": "0", "id": "9916", + "name": "Green destabiliser", + "examine": "A green destabiliser for use in a ghost buster.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "5" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A yellow destabiliser for use in a ghost buster.", - "durability": null, - "name": "Yellow destabiliser", - "archery_ticket_price": "0", "id": "9917", + "name": "Yellow destabiliser", + "examine": "A yellow destabiliser for use in a ghost buster.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "5" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A black destabiliser for use in a ghost buster.", - "durability": null, - "name": "Black destabiliser", - "archery_ticket_price": "0", "id": "9918", + "name": "Black destabiliser", + "examine": "A black destabiliser for use in a ghost buster.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, "equipment_slot": "5" }, { - "examine": "An angry-looking tree root.", - "durability": null, + "id": "9919", "name": "Evil root", + "examine": "An angry-looking tree root.", "archery_ticket_price": "0", - "id": "9919" + "durability": null }, { - "remove_head": "true", - "destroy_message": "Players may get another from Diango in Draynor Village.", - "examine": "Better not light it!", - "durability": null, - "name": "Jack lantern mask", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "9920", + "name": "Jack lantern mask", + "examine": "Better not light it!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Players may get another from Diango in Draynor Village.", + "durability": null, + "equip_audio": "3227", + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Skeleton feet.", - "durability": null, - "name": "Skeleton boots", - "weight": "2", - "archery_ticket_price": "0", "id": "9921", - "equipment_slot": "10" + "name": "Skeleton boots", + "examine": "Skeleton feet.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "10", + "weight": "2" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some skeletal gloves.", - "durability": null, - "name": "Skeleton gloves", - "weight": "2", - "archery_ticket_price": "0", "id": "9922", - "equipment_slot": "9" + "name": "Skeleton gloves", + "examine": "Some skeletal gloves.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", + "weight": "2" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Does my pelvis look big in this?", - "durability": null, - "name": "Skeleton leggings", - "weight": "2", - "archery_ticket_price": "0", "id": "9923", - "equipment_slot": "7" + "name": "Skeleton leggings", + "examine": "Does my pelvis look big in this?", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "7", + "weight": "2" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "remove_sleeves": "true", - "examine": "The shirt of a fully body skeleton costume.", - "durability": null, - "name": "Skeleton shirt", - "weight": "2", - "archery_ticket_price": "0", "id": "9924", - "equipment_slot": "4" - }, - { - "remove_head": "true", + "name": "Skeleton shirt", + "examine": "The shirt of a fully body skeleton costume.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A scary skeleton mask.", "durability": null, - "name": "Skeleton mask", - "weight": "2", - "archery_ticket_price": "0", - "id": "9925", - "equipment_slot": "0" - }, - { - "destroy_message": "You'll have to buy another one from Auguste on Entrana.", - "shop_price": "30000", - "examine": "This sapling is ready to be replanted in a tree patch.", - "durability": null, - "name": "Auguste's sapling", - "tradeable": "false", - "destroy": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "9932" - }, - { - "examine": "An incomplete origami balloon.", - "durability": null, - "name": "Balloon structure", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9933" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Origami balloon", - "archery_ticket_price": "0", - "id": "9934" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Yellow balloon", - "archery_ticket_price": "0", - "id": "9935" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Blue balloon", - "archery_ticket_price": "0", - "id": "9936" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Red balloon", - "archery_ticket_price": "0", - "id": "9937" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Orange balloon", - "archery_ticket_price": "0", - "id": "9938" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Green balloon", - "archery_ticket_price": "0", - "id": "9939" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Purple balloon", - "archery_ticket_price": "0", - "id": "9940" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Pink balloon", - "archery_ticket_price": "0", - "id": "9941" - }, - { - "examine": "An origami balloon.", - "durability": null, - "name": "Black balloon", - "archery_ticket_price": "0", - "id": "9942" - }, - { - "examine": "A bag full of sand.", - "durability": null, - "name": "Sandbag", - "weight": "1", - "archery_ticket_price": "0", - "id": "9943", - "equipment_slot": "3" - }, - { - "destroy_message": "You'll have to visit Auguste on Entrana to get a new jacket.", + "equipment_slot": "4", "remove_sleeves": "true", - "examine": "For all your flying needs.", - "durability": null, - "name": "Bomber jacket", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "9944", - "equipment_slot": "4" + "weight": "2" }, { - "remove_head": "true", - "destroy_message": "You'll have to visit Auguste on Entrana to get a new cap.", - "examine": "The red baron would be jealous.", - "durability": null, - "name": "Bomber cap", - "tradeable": "false", - "destroy": "true", + "id": "9925", + "name": "Skeleton mask", + "examine": "A scary skeleton mask.", "archery_ticket_price": "0", - "id": "9945", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "examine": "For better flying vision.", - "durability": null, - "name": "Cap and goggles", - "archery_ticket_price": "0", - "id": "9946", - "equipment_slot": "0" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A red coloured disk that's seen better days.", "durability": null, - "name": "Old red disk", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "9947" + "equipment_slot": "0", + "remove_head": "true", + "weight": "2" }, { + "id": "9932", + "name": "Auguste's sapling", + "examine": "This sapling is ready to be replanted in a tree patch.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to buy another one from Auguste on Entrana.", + "durability": null, + "shop_price": "30000", + "tradeable": "false", + "weight": "0.9" + }, + { + "id": "9933", + "name": "Balloon structure", + "examine": "An incomplete origami balloon.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "9934", + "name": "Origami balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9935", + "name": "Yellow balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9936", + "name": "Blue balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9937", + "name": "Red balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9938", + "name": "Orange balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9939", + "name": "Green balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9940", + "name": "Purple balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9941", + "name": "Pink balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9942", + "name": "Black balloon", + "examine": "An origami balloon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9943", + "name": "Sandbag", + "examine": "A bag full of sand.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1" + }, + { + "id": "9944", + "name": "Bomber jacket", + "examine": "For all your flying needs.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to visit Auguste on Entrana to get a new jacket.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "1" + }, + { + "id": "9945", + "name": "Bomber cap", + "examine": "The red baron would be jealous.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to visit Auguste on Entrana to get a new cap.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false" + }, + { + "id": "9946", + "name": "Cap and goggles", + "examine": "For better flying vision.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true" + }, + { + "id": "9947", + "name": "Old red disk", + "examine": "A red coloured disk that's seen better days.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "9948", + "name": "Hunter cape", + "examine": "The cape worn by master hunters.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{21,99}", "shop_price": "99000", - "examine": "The cape worn by master hunters.", - "durability": null, - "name": "Hunter cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9948", - "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { - "requirements": "{21,99}", - "durability": null, + "id": "9949", "name": "Hunter cape(t)", "archery_ticket_price": "0", - "id": "9949", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{21,99}" }, { + "id": "9950", + "name": "Hunter hood", + "examine": "Hunter skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{21,99}", "shop_price": "99000", - "examine": "Hunter skillcape hood.", - "durability": null, - "name": "Hunter hood", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "9950", - "equipment_slot": "0" + "weight": "0.4" }, { - "durability": null, + "id": "9952", "name": "Imp", "archery_ticket_price": "0", "attack_speed": "4", - "id": "9952" + "durability": null }, { - "examine": "A little bigger than usual...", - "durability": null, + "id": "9953", "name": "Kebbit", - "archery_ticket_price": "0", - "id": "9953" - }, - { "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9954" + "durability": null }, { + "id": "9954", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9955" + "durability": null }, { + "id": "9955", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9956" + "durability": null }, { + "id": "9956", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9957" + "durability": null }, { + "id": "9957", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9958" + "durability": null }, { + "id": "9958", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9959" + "durability": null }, { + "id": "9959", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9960" + "durability": null }, { + "id": "9960", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9961" + "durability": null }, { + "id": "9961", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9962" + "durability": null }, { + "id": "9962", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9963" + "durability": null }, { + "id": "9963", + "name": "Kebbit", "examine": "A little bigger than usual...", - "durability": null, - "name": "Kebbit", "archery_ticket_price": "0", - "id": "9964" + "durability": null }, { - "examine": "It appears to be protecting the nest.", - "durability": null, + "id": "9964", + "name": "Kebbit", + "examine": "A little bigger than usual...", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "9974", "name": "Giant eagle", + "examine": "It appears to be protecting the nest.", "archery_ticket_price": "0", - "id": "9974" + "durability": null }, { - "examine": "Aww, how cute. ", - "durability": null, + "id": "9975", "name": "Rabbit", + "examine": "Aww, how cute. ", "archery_ticket_price": "0", - "id": "9975" + "durability": null }, { - "examine": "Even more volatile than its vegetarian counterpart.", - "grand_exchange_price": "796", - "durability": null, + "id": "9977", "name": "Red chinchompa", - "tradeable": "true", - "destroy": "true", + "examine": "Even more volatile than its vegetarian counterpart.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "9977", - "bonuses": "0,0,0,0,70,0,0,0,0,0,0,0,15,0,0" + "bonuses": "0,0,0,0,70,0,0,0,0,0,0,0,15,0,0", + "destroy": "true", + "durability": null, + "tradeable": "true" }, { - "shop_price": "63", - "ge_buy_limit": "10000", + "id": "9978", + "name": "Raw bird meat", "examine": "This certainly needs cooking!", - "grand_exchange_price": "204", - "durability": null, - "name": "Raw bird meat", - "tradeable": "true", - "weight": "0.15", "archery_ticket_price": "0", - "id": "9978" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "204", - "durability": null, - "name": "Raw bird meat", + "shop_price": "63", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9979" + "weight": "0.15" }, { - "ge_buy_limit": "1000", + "id": "9979", + "name": "Raw bird meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "9980", + "name": "Roast bird meat", "examine": "A nicely roasted bird.", - "grand_exchange_price": "18", - "durability": null, - "name": "Roast bird meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9980" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "18", - "durability": null, - "name": "Roast bird meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "9981" + "tradeable": "true" }, { + "id": "9981", + "name": "Roast bird meat", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "9983", "name": "Burnt bird meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9983" + "durability": null, + "tradeable": "true" }, { - "shop_price": "63", - "ge_buy_limit": "1000", + "id": "9984", + "name": "Skewered bird meat", "examine": "This certainly needs cooking!", - "grand_exchange_price": "130", - "durability": null, - "name": "Skewered bird meat", - "tradeable": "true", - "weight": "0.15", "archery_ticket_price": "0", - "id": "9984" + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "63", + "tradeable": "true", + "weight": "0.15" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "130", - "durability": null, + "id": "9985", "name": "Skewered bird meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9985" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9986", + "name": "Raw beast meat", "examine": "A slab of raw beast meat.", - "grand_exchange_price": "16", - "durability": null, - "name": "Raw beast meat", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "9986" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "16", - "durability": null, + "id": "9987", "name": "Raw beast meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9987" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9988", + "name": "Roast beast meat", "examine": "A delicious looking slab of roast beast.", - "grand_exchange_price": "42", - "durability": null, - "name": "Roast beast meat", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "9988" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "42", - "durability": null, - "name": "Roast beast meat", "tradeable": "true", - "archery_ticket_price": "0", - "id": "9989" + "weight": "2" }, { + "id": "9989", + "name": "Roast beast meat", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "9991", "name": "Burnt beast meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9991" + "durability": null, + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9992", + "name": "Skewered beast", "examine": "Beast meat on a spit.", - "grand_exchange_price": "97", - "durability": null, - "name": "Skewered beast", - "tradeable": "true", - "weight": "3.5", "archery_ticket_price": "0", - "id": "9992" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "3.5" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "97", - "durability": null, + "id": "9993", "name": "Skewered beast", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9993" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9994", + "name": "Spicy tomato", "examine": "A bowl of chopped tomatoes with an extra kick.", - "grand_exchange_price": "324", - "durability": null, - "name": "Spicy tomato", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "9994" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "1000", - "grand_exchange_price": "324", - "durability": null, + "id": "9995", "name": "Spicy tomato", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9995" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "1000", + "id": "9996", + "name": "Spicy minced meat", "examine": "A bowl of chopped beef with an extra kick.", - "grand_exchange_price": "263", - "durability": null, - "name": "Spicy minced meat", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "9996" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "263", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "9997", "name": "Spicy minced meat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9997" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "9998", + "name": "Hunter potion(4)", "examine": "4 doses of hunter potion.", - "grand_exchange_price": "566", - "durability": null, - "name": "Hunter potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9998" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "566", - "durability": null, + "id": "9999", "name": "Hunter potion(4)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "9999" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10000", + "name": "Hunter potion(3)", "examine": "3 doses of hunter potion.", - "grand_exchange_price": "229", - "durability": null, - "name": "Hunter potion(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10000" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "229", - "durability": null, + "id": "10001", "name": "Hunter potion(3)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10001" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10002", + "name": "Hunter potion(2)", "examine": "2 doses of hunter potion.", - "grand_exchange_price": "159", - "durability": null, - "name": "Hunter potion(2)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10002" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "159", - "durability": null, + "id": "10003", "name": "Hunter potion(2)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10003" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10004", + "name": "Hunter potion(1)", "examine": "1 dose of hunter potion.", - "grand_exchange_price": "148", - "durability": null, - "name": "Hunter potion(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10004" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "148", - "durability": null, + "id": "10005", "name": "Hunter potion(1)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10005" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "6", - "ge_buy_limit": "100", + "id": "10006", + "name": "Bird snare", "examine": "A simple bird catcher./There's something caught in it.", - "grand_exchange_price": "2", - "durability": null, - "name": "Bird snare", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "10006" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "2", - "durability": null, - "name": "Bird snare", + "shop_price": "6", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10007" + "weight": "0.4" }, { + "id": "10007", + "name": "Bird snare", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10008", + "name": "Box trap", + "examine": "If a creature goes inside, then the box should slam shut.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{21,27}", "shop_price": "38", - "ge_buy_limit": "100", - "examine": "If a creature goes inside, then the box should slam shut.", - "grand_exchange_price": "308", - "durability": null, - "name": "Box trap", "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10008" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "308", - "durability": null, + "id": "10009", "name": "Box trap", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10009" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{21,15}", - "shop_price": "24", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "For catching butterflies...", - "walk_anim": "1205", - "durability": null, - "weight": "0.2", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "weapon_interface": "10", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "1", - "stand_anim": "813", - "name": "Butterfly net", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", "id": "10010", - "stand_turn_anim": "1209" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, "name": "Butterfly net", - "tradeable": "true", + "examine": "For catching butterflies...", "archery_ticket_price": "0", - "id": "10011" + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "defence_anim": "403", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{21,15}", + "run_anim": "1210", + "shop_price": "24", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "10", + "weight": "0.2" }, { + "id": "10011", + "name": "Butterfly net", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10012", + "name": "Butterfly jar", + "examine": "It's got little holes at the top.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{21,15}", "shop_price": "1", - "ge_buy_limit": "100", - "examine": "It's got little holes at the top.", - "grand_exchange_price": "156", - "durability": null, - "name": "Butterfly jar", "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.02", - "id": "10012" + "weight": "0.02" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "156", - "durability": null, + "id": "10013", "name": "Butterfly jar", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10013" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "143", + "id": "10014", + "name": "Black warlock", "examine": "There's a black warlock butterfly in here.", - "durability": null, - "name": "Black warlock", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.02", - "id": "10014" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.02" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "143", - "durability": null, + "id": "10015", "name": "Black warlock", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10015" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "227", + "id": "10016", + "name": "Snowy knight", "examine": "There's a snowy knight butterfly in here.", - "durability": null, - "name": "Snowy knight", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.02", - "id": "10016" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.02" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "227", - "durability": null, + "id": "10017", "name": "Snowy knight", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10017" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "180", + "id": "10018", + "name": "Sapphire glacialis", "examine": "There's a sapphire glacialis butterfly in here.", - "durability": null, - "name": "Sapphire glacialis", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.02", - "id": "10018" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.02" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "180", - "durability": null, + "id": "10019", "name": "Sapphire glacialis", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10019" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1270", + "id": "10020", + "name": "Ruby harvest", "examine": "There's a ruby harvest butterfly in here.", - "durability": null, - "name": "Ruby harvest", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "0.02", - "id": "10020" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "1270", - "durability": null, - "name": "Ruby harvest", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10021" + "weight": "0.02" }, { - "shop_price": "500", - "examine": "A very large, single leather glove", - "durability": null, - "name": "Falconer's glove", - "tradeable": "false", - "destroy": "true", - "weight": "1.8", + "id": "10021", + "name": "Ruby harvest", "archery_ticket_price": "0", - "attack_speed": "4", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "10023", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "shop_price": "500", - "turn90cw_anim": "5166", - "examine": "A very large, single leather glove", - "walk_anim": "5164", - "durability": null, - "destroy": "true", - "weight": "1.8", - "turn90ccw_anim": "5167", - "attack_speed": "4", - "turn180_anim": "5165", - "render_anim": "1283", - "equipment_slot": "3", - "stand_anim": "5160", "name": "Falconer's glove", - "tradeable": "false", - "run_anim": "5168", + "examine": "A very large, single leather glove", "archery_ticket_price": "0", - "id": "10024", - "stand_turn_anim": "5161", - "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0" + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "shop_price": "500", + "tradeable": "false", + "weight": "1.8" }, { + "id": "10024", + "name": "Falconer's glove", + "examine": "A very large, single leather glove", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "render_anim": "1283", + "run_anim": "5168", + "shop_price": "500", + "stand_anim": "5160", + "stand_turn_anim": "5161", + "tradeable": "false", + "turn180_anim": "5165", + "turn90ccw_anim": "5167", + "turn90cw_anim": "5166", + "walk_anim": "5164", + "weight": "1.8" + }, + { + "id": "10025", + "name": "Magic box", + "examine": "A magical catching box.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{21,71}", "shop_price": "720", - "ge_buy_limit": "100", - "examine": "A magical catching box.", - "grand_exchange_price": "784", - "durability": null, - "name": "Magic box", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10025" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "784", - "durability": null, + "id": "10026", "name": "Magic box", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10026" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "720", - "examine": "A magical catching box.", - "grand_exchange_price": "743", - "durability": null, + "id": "10027", "name": "Imp-in-a-box(2)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10027" - }, - { - "shop_price": "720", "examine": "A magical catching box.", - "grand_exchange_price": "743", - "durability": null, - "name": "Imp-in-a-box(1)", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "10028" + "durability": null, + "shop_price": "720", + "tradeable": "true", + "weight": "1" }, { + "id": "10028", + "name": "Imp-in-a-box(1)", + "examine": "A magical catching box.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "720", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10029", + "name": "Teasing stick", + "examine": "Reduces the risk of hand severage when poking large, vicious carnivores.", + "archery_ticket_price": "0", + "bonuses": "7,8,0,-4,0,-1,1,2,0,0,0,8,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", "requirements": "{21,31}", "shop_price": "1", - "ge_buy_limit": "100", - "examine": "Reduces the risk of hand severage when poking large, vicious carnivores.", - "durability": null, - "weight": "1", + "tradeable": "true", "weapon_interface": "6", - "equipment_slot": "3", - "grand_exchange_price": "1", - "name": "Teasing stick", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10029", - "bonuses": "7,8,0,-4,0,-1,1,2,0,0,0,8,0,0,0" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", + "id": "10030", + "name": "Teasing stick", + "archery_ticket_price": "0", "durability": null, - "name": "Teasing stick", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10030" + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "10031", + "name": "Rabbit snare", + "examine": "The snare will tighten around animals passing through.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{21,27}", "shop_price": "18", - "ge_buy_limit": "100", - "examine": "The snare will tighten around animals passing through.", - "grand_exchange_price": "1", - "durability": null, - "name": "Rabbit snare", "tradeable": "true", - "weight": "0.02", - "archery_ticket_price": "0", - "id": "10031" + "weight": "0.02" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, + "id": "10032", "name": "Rabbit snare", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10032" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{4,45}", - "ge_buy_limit": "20000", - "turn90cw_anim": "3177", - "walk_anim": "3177", - "durability": null, - "turn90ccw_anim": "3177", - "attack_speed": "4", - "weapon_interface": "19", - "turn180_anim": "3177", - "render_anim": "234", - "equipment_slot": "3", - "grand_exchange_price": "973", - "stand_anim": "3175", - "name": "Chinchompa", - "run_anim": "3178", - "archery_ticket_price": "0", "id": "10033", - "stand_turn_anim": "3177", - "bonuses": "0,0,0,0,45,0,0,0,0,0,0,0,0,0,0" - }, - { - "requirements": "{4,55}", - "ge_buy_limit": "20000", - "turn90cw_anim": "3177", - "examine": "Even more volatile than its vegetarian counterpart.", - "walk_anim": "3177", - "durability": null, - "destroy": "true", - "turn90ccw_anim": "3177", + "name": "Chinchompa", + "archery_ticket_price": "0", "attack_speed": "4", - "weapon_interface": "19", - "turn180_anim": "3177", - "render_anim": "234", + "bonuses": "0,0,0,0,45,0,0,0,0,0,0,0,0,0,0", + "durability": null, "equipment_slot": "3", - "grand_exchange_price": "1382", - "stand_anim": "3175", - "name": "Red chinchompa", - "tradeable": "true", + "ge_buy_limit": "20000", + "render_anim": "234", + "requirements": "{4,45}", "run_anim": "3178", - "archery_ticket_price": "0", - "id": "10034", + "stand_anim": "3175", "stand_turn_anim": "3177", - "bonuses": "0,0,0,0,70,0,0,0,0,0,0,0,0,0,15" + "turn180_anim": "3177", + "turn90ccw_anim": "3177", + "turn90cw_anim": "3177", + "walk_anim": "3177", + "weapon_interface": "19" }, { - "requirements": "{21,52}", - "ge_buy_limit": "100", - "examine": "These should make me harder to spot in polar areas.", - "grand_exchange_price": "449", - "durability": null, - "name": "Kyatt legs", - "tradeable": "true", - "weight": "0.2", + "id": "10034", + "name": "Red chinchompa", + "examine": "Even more volatile than its vegetarian counterpart.", "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,70,0,0,0,0,0,0,0,0,0,15", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "20000", + "render_anim": "234", + "requirements": "{4,55}", + "run_anim": "3178", + "stand_anim": "3175", + "stand_turn_anim": "3177", + "tradeable": "true", + "turn180_anim": "3177", + "turn90ccw_anim": "3177", + "turn90cw_anim": "3177", + "walk_anim": "3177", + "weapon_interface": "19" + }, + { "id": "10035", - "bonuses": "0,0,0,0,-7,11,10,10,0,10,10,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "449", - "durability": null, "name": "Kyatt legs", - "tradeable": "true", + "examine": "These should make me harder to spot in polar areas.", "archery_ticket_price": "0", - "id": "10036" + "bonuses": "0,0,0,0,-7,11,10,10,0,10,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{21,52}", + "tradeable": "true", + "weight": "0.2" }, { - "requirements": "{21,52}", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in polar areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "272", - "name": "Kyatt top", - "tradeable": "true", + "id": "10036", + "name": "Kyatt legs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10037", - "bonuses": "0,0,0,0,0,10,15,19,0,12,20,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "272", - "durability": null, "name": "Kyatt top", - "tradeable": "true", + "examine": "This should make me harder to spot in polar areas.", "archery_ticket_price": "0", - "id": "10038" + "bonuses": "0,0,0,0,0,10,15,19,0,12,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "requirements": "{21,52}", + "tradeable": "true", + "weight": "0.2" }, { + "id": "10038", + "name": "Kyatt top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10039", + "name": "Kyatt hat", + "examine": "This should make me harder to spot in polar areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,-1,4,5,3,0,4,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{21,52}", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in polar areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "0", - "grand_exchange_price": "8338", - "name": "Kyatt hat", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10039", - "bonuses": "0,0,0,0,-1,4,5,3,0,4,3,0,0,0,0" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8338", - "durability": null, + "id": "10040", "name": "Kyatt hat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10040" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{21,28}", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in woodland and jungle areas.", - "grand_exchange_price": "2889", - "durability": null, - "name": "Larupia legs", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10041", - "bonuses": "0,0,0,0,-7,11,10,10,0,10,5,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2889", - "durability": null, "name": "Larupia legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10042" - }, - { - "requirements": "{21,28}", - "ge_buy_limit": "100", "examine": "This should make me harder to spot in woodland and jungle areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "3232", - "name": "Larupia top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10043", - "bonuses": "0,0,0,0,0,10,15,19,0,12,10,0,0,0,0" - }, - { + "bonuses": "0,0,0,0,-7,11,10,10,0,10,5,0,0,0,0", + "durability": null, + "equipment_slot": "7", "ge_buy_limit": "100", - "grand_exchange_price": "3232", - "durability": null, - "name": "Larupia top", + "requirements": "{21,28}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10044" + "weight": "0.2" }, { + "id": "10042", + "name": "Larupia legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10043", + "name": "Larupia top", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,10,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "requirements": "{21,28}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10044", + "name": "Larupia top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10045", + "name": "Larupia hat", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,-1,4,5,3,0,4,5,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{21,28}", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in woodland and jungle areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "0", - "grand_exchange_price": "7237", - "name": "Larupia hat", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10045", - "bonuses": "0,0,0,0,-1,4,5,3,0,4,5,0,0,0,0" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "7237", - "durability": null, + "id": "10046", "name": "Larupia hat", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10046" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "10047", + "name": "Graahk legs", + "examine": "These should make me harder to spot in desert areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,10,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", "requirements": "{21,38}", "shop_price": "150", - "ge_buy_limit": "100", - "examine": "These should make me harder to spot in desert areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "7", - "grand_exchange_price": "266", - "name": "Graahk legs", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10047", - "bonuses": "0,0,0,0,-7,11,10,10,0,10,10,0,0,0,0" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "266", - "durability": null, + "id": "10048", "name": "Graahk legs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10048" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "10049", + "name": "Graahk top", + "examine": "This should make me harder to spot in desert areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,15,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", "requirements": "{21,38}", "shop_price": "300", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10050", + "name": "Graahk top", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10051", + "name": "Graahk headdress", "examine": "This should make me harder to spot in desert areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "252", - "name": "Graahk top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10049", - "bonuses": "0,0,0,0,0,10,15,19,0,12,15,0,0,0,0" - }, - { + "bonuses": "0,0,0,0,-1,4,5,3,0,4,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "ge_buy_limit": "100", - "grand_exchange_price": "252", - "durability": null, - "name": "Graahk top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10050" - }, - { "remove_head": "true", "requirements": "{21,38}", "shop_price": "1", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in desert areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "0", - "grand_exchange_price": "8445", - "name": "Graahk headdress", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10051", - "bonuses": "0,0,0,0,-1,4,5,3,0,4,3,0,0,0,0" + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8445", - "durability": null, + "id": "10052", "name": "Graahk headdress", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10052" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in wooded areas.", - "grand_exchange_price": "3527", - "durability": null, - "name": "Wood camo top", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10053", - "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3527", - "durability": null, "name": "Wood camo top", - "tradeable": "true", + "examine": "This should make me harder to spot in wooded areas.", "archery_ticket_price": "0", - "id": "10054" - }, - { - "ge_buy_limit": "100", - "examine": "These should make me harder to spot in wooded areas.", - "grand_exchange_price": "3228", - "durability": null, - "name": "Wood camo legs", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10055", - "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3228", - "durability": null, - "name": "Wood camo legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10056" - }, - { - "requirements": "{21,4}", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in jungle areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "315", - "name": "Jungle camo top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10057", - "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "315", - "durability": null, - "name": "Jungle camo top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10058" - }, - { - "requirements": "{21,4}", - "ge_buy_limit": "100", - "examine": "These should make me harder to spot in jungle areas.", - "grand_exchange_price": "462", - "durability": null, - "name": "Jungle camo legs", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10059", - "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "462", - "durability": null, - "name": "Jungle camo legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10060" - }, - { - "requirements": "{21,10}", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in desert areas.", - "durability": null, - "weight": "0.2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "541", - "name": "Desert camo top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10061", - "bonuses": "0,0,0,0,0,10,15,19,0,12,10,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "541", - "durability": null, - "name": "Desert camo top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10062" - }, - { - "requirements": "{21,10}", - "ge_buy_limit": "100", - "examine": "These should make me harder to spot in desert areas.", - "grand_exchange_price": "910", - "durability": null, - "name": "Desert camo legs", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10063", - "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "910", - "durability": null, - "name": "Desert camo legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10064" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "100", - "examine": "This should make me harder to spot in polar areas.", - "grand_exchange_price": "7990", - "durability": null, - "name": "Polar camo top", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10065", "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "7990", - "durability": null, - "name": "Polar camo top", - "tradeable": "true", + "id": "10054", + "name": "Wood camo top", "archery_ticket_price": "0", - "id": "10066" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "These should make me harder to spot in polar areas", - "grand_exchange_price": "8389", - "durability": null, - "name": "Polar camo legs", - "tradeable": "true", - "weight": "0.2", + "id": "10055", + "name": "Wood camo legs", + "examine": "These should make me harder to spot in wooded areas.", "archery_ticket_price": "0", - "id": "10067", "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8389", + "id": "10056", + "name": "Wood camo legs", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10057", + "name": "Jungle camo top", + "examine": "This should make me harder to spot in jungle areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "requirements": "{21,4}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10058", + "name": "Jungle camo top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10059", + "name": "Jungle camo legs", + "examine": "These should make me harder to spot in jungle areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{21,4}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10060", + "name": "Jungle camo legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10061", + "name": "Desert camo top", + "examine": "This should make me harder to spot in desert areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,10,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "requirements": "{21,10}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10062", + "name": "Desert camo top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10063", + "name": "Desert camo legs", + "examine": "These should make me harder to spot in desert areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{21,10}", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10064", + "name": "Desert camo legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10065", + "name": "Polar camo top", + "examine": "This should make me harder to spot in polar areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10066", + "name": "Polar camo top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10067", "name": "Polar camo legs", - "tradeable": "true", + "examine": "These should make me harder to spot in polar areas", "archery_ticket_price": "0", - "id": "10068" + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.2" }, { - "requirements": "{21,40}", - "ge_buy_limit": "100", - "examine": "A surprisingly aerodynamic cape.", - "grand_exchange_price": "1140", - "durability": null, - "name": "Spotted cape", - "tradeable": "true", - "weight": "-2.2", + "id": "10068", + "name": "Polar camo legs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10069", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1140", - "durability": null, "name": "Spotted cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10070" - }, - { - "requirements": "{21,66}", - "ge_buy_limit": "100", - "examine": "A really surprisingly aerodynamic cape.", - "grand_exchange_price": "1262", - "durability": null, - "name": "Spottier cape", - "tradeable": "true", - "weight": "-4.5", - "archery_ticket_price": "0", - "id": "10071", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1262", - "durability": null, - "name": "Spottier cape", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10072" - }, - { - "requirements": "{21,40}", "examine": "A surprisingly aerodynamic cape.", - "grand_exchange_price": "951", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "requirements": "{21,40}", + "tradeable": "true", + "weight": "-2.2" + }, + { + "id": "10070", "name": "Spotted cape", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "10073", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{21,66}", - "examine": "A really surprisingly aerodynamic cape.", - "grand_exchange_price": "881", - "durability": null, + "id": "10071", "name": "Spottier cape", - "tradeable": "true", - "weight": "0.4", + "examine": "A really surprisingly aerodynamic cape.", "archery_ticket_price": "0", - "id": "10074", "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "100", + "requirements": "{21,66}", + "tradeable": "true", + "weight": "-4.5" }, { - "requirements": "{21,54}", - "ge_buy_limit": "100", - "examine": "Made from dark kebbit fur, these are perfect for tasks of a stealthier nature.", - "grand_exchange_price": "1063", - "durability": null, - "name": "Gloves of silence", - "tradeable": "true", - "weight": "0.2", + "id": "10072", + "name": "Spottier cape", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10073", + "name": "Spotted cape", + "examine": "A surprisingly aerodynamic cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "requirements": "{21,40}", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10074", + "name": "Spottier cape", + "examine": "A really surprisingly aerodynamic cape.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "requirements": "{21,66}", + "tradeable": "true", + "weight": "0.4" + }, + { "id": "10075", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1063", - "durability": null, "name": "Gloves of silence", - "tradeable": "true", + "examine": "Made from dark kebbit fur, these are perfect for tasks of a stealthier nature.", "archery_ticket_price": "0", - "id": "10076" + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{21,54}", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "100", - "examine": "Attack at your own risk.", - "grand_exchange_price": "80", - "durability": null, - "name": "Spiky vambraces", - "tradeable": "true", - "weight": "1", + "id": "10076", + "name": "Gloves of silence", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10077", - "bonuses": "0,0,0,0,4,2,2,1,0,0,1,2,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "80", - "durability": null, "name": "Spiky vambraces", - "tradeable": "true", + "examine": "Attack at your own risk.", "archery_ticket_price": "0", - "id": "10078" + "bonuses": "0,0,0,0,4,2,2,1,0,0,1,2,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" }, { - "requirements": "{4,40}", - "ge_buy_limit": "100", - "examine": "Made from 100% real dragonhide. Now with added spikiness.", - "grand_exchange_price": "1353", - "durability": null, - "name": "Green spiky vambs", - "tradeable": "true", - "weight": "1", + "id": "10078", + "name": "Spiky vambraces", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10079", - "bonuses": "0,0,0,-10,8,3,2,4,2,0,3,2,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1353", - "durability": null, "name": "Green spiky vambs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10080" - }, - { - "requirements": "{4,50}", - "ge_buy_limit": "100", "examine": "Made from 100% real dragonhide. Now with added spikiness.", - "grand_exchange_price": "1773", - "durability": null, - "name": "Blue spiky vambs", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,3,2,4,2,0,3,2,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{4,40}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10080", + "name": "Green spiky vambs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10081", - "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,2,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1773", - "durability": null, "name": "Blue spiky vambs", - "tradeable": "true", + "examine": "Made from 100% real dragonhide. Now with added spikiness.", "archery_ticket_price": "0", - "id": "10082" + "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,2,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{4,50}", + "tradeable": "true" }, { - "requirements": "{4,60}", - "ge_buy_limit": "100", - "examine": "Vambraces made from 100% real dragonhide. Now with added spikes.", - "grand_exchange_price": "1978", - "durability": null, - "name": "Red spiky vambs", - "tradeable": "true", - "weight": "1", + "id": "10082", + "name": "Blue spiky vambs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10083", - "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,2,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1978", - "durability": null, "name": "Red spiky vambs", - "tradeable": "true", + "examine": "Vambraces made from 100% real dragonhide. Now with added spikes.", "archery_ticket_price": "0", - "id": "10084" + "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,2,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{4,60}", + "tradeable": "true", + "weight": "1" }, { - "requirements": "{4,70}", - "ge_buy_limit": "100", - "examine": "Vambraces made from 100% real dragonhide. Now with added spikiness.", - "grand_exchange_price": "2727", - "durability": null, - "name": "Black spiky vambs", - "tradeable": "true", - "weight": "1", + "id": "10084", + "name": "Red spiky vambs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10085", - "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,2,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2727", - "durability": null, "name": "Black spiky vambs", - "tradeable": "true", + "examine": "Vambraces made from 100% real dragonhide. Now with added spikiness.", "archery_ticket_price": "0", - "id": "10086" + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,2,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{4,70}", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "5000", - "examine": "Attractive to other birds and hunters alike.", - "grand_exchange_price": "20", + "id": "10086", + "name": "Black spiky vambs", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10087", "name": "Stripy feather", - "tradeable": "true", + "examine": "Attractive to other birds and hunters alike.", "archery_ticket_price": "0", - "id": "10087" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "3", - "ge_buy_limit": "5000", - "examine": "A vivid red feather.", - "grand_exchange_price": "23", - "durability": null, + "id": "10088", "name": "Red feather", - "tradeable": "true", + "examine": "A vivid red feather.", "archery_ticket_price": "0", - "id": "10088" + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "3", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "A cool blue feather.", - "grand_exchange_price": "27", - "durability": null, + "id": "10089", "name": "Blue feather", - "tradeable": "true", + "examine": "A cool blue feather.", "archery_ticket_price": "0", - "id": "10089" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "A bright yellow feather.", - "grand_exchange_price": "36", - "durability": null, + "id": "10090", "name": "Yellow feather", - "tradeable": "true", + "examine": "A bright yellow feather.", "archery_ticket_price": "0", - "id": "10090" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "6", - "ge_buy_limit": "5000", - "examine": "A fairly plain feather.", - "grand_exchange_price": "25", - "durability": null, + "id": "10091", "name": "Orange feather", - "tradeable": "true", + "examine": "A fairly plain feather.", "archery_ticket_price": "0", - "id": "10091" + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "6", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10093", + "name": "Tatty larupia fur", "examine": "It's a shabby-looking larupia fur.", - "grand_exchange_price": "1195", - "durability": null, - "name": "Tatty larupia fur", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "10093" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1195", - "durability": null, + "id": "10094", "name": "Tatty larupia fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10094" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10095", + "name": "Larupia fur", "examine": "It's a perfect-looking larupia fur.", - "grand_exchange_price": "4986", - "durability": null, - "name": "Larupia fur", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "10095" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "4986", - "durability": null, + "id": "10096", "name": "Larupia fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10096" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10097", + "name": "Tatty graahk fur", "examine": "It's a shabby-looking graahk fur.", - "grand_exchange_price": "28", - "durability": null, - "name": "Tatty graahk fur", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "10097" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "28", - "durability": null, + "id": "10098", "name": "Tatty graahk fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10098" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10099", + "name": "Graahk fur", "examine": "It's a perfect-looking graahk fur.", - "grand_exchange_price": "7574", - "durability": null, - "name": "Graahk fur", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "10099" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "7574", - "durability": null, + "id": "10100", "name": "Graahk fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10100" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10101", + "name": "Tatty kyatt fur", "examine": "It's a shabby-looking kyatt fur.", - "grand_exchange_price": "23", - "durability": null, - "name": "Tatty kyatt fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10101" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "23", - "durability": null, + "id": "10102", "name": "Tatty kyatt fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10102" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "8000", - "ge_buy_limit": "100", + "id": "10103", + "name": "Kyatt fur", "examine": "It's a perfect-looking kyatt fur.", - "grand_exchange_price": "11100", - "durability": null, - "name": "Kyatt fur", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "10103" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "11100", - "durability": null, + "shop_price": "8000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10104", "name": "Kyatt fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10104" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "These bone spikes are both very tough and very sharp.", - "grand_exchange_price": "154", - "durability": null, + "id": "10105", "name": "Kebbit spike", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10105" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "154", - "durability": null, - "name": "Kebbit spike", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10106" - }, - { - "ge_buy_limit": "5000", "examine": "These bone spikes are both very tough and very sharp.", - "grand_exchange_price": "1619", - "durability": null, - "name": "Long kebbit spike", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10107" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1619", - "durability": null, - "name": "Long kebbit spike", - "tradeable": "true", + "id": "10106", + "name": "Kebbit spike", "archery_ticket_price": "0", - "id": "10108" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { + "id": "10107", + "name": "Long kebbit spike", + "examine": "These bone spikes are both very tough and very sharp.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10108", + "name": "Long kebbit spike", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10109", + "name": "Kebbit teeth", "examine": "A kebbit-sized set of dentures.", - "grand_exchange_price": "894", - "durability": null, - "name": "Kebbit teeth", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10109" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "894", - "durability": null, + "id": "10110", "name": "Kebbit teeth", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10110" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", + "id": "10111", + "name": "Kebbit teeth dust", "examine": "Previously a kebbit-sized set of dentures.", - "grand_exchange_price": "947", - "durability": null, - "name": "Kebbit teeth dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10111" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "947", - "durability": null, + "id": "10112", "name": "Kebbit teeth dust", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10112" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", + "id": "10113", + "name": "Kebbit claws", "examine": "More menacing when attached to the owner.", - "grand_exchange_price": "55", - "durability": null, - "name": "Kebbit claws", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10113" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "55", - "durability": null, + "tradeable": "true" + }, + { + "id": "10114", "name": "Kebbit claws", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10114" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10115", + "name": "Dark kebbit fur", "examine": "Sleek, silent, and furry.", - "grand_exchange_price": "92", - "durability": null, - "name": "Dark kebbit fur", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "10115" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "92", - "durability": null, - "name": "Dark kebbit fur", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10116" + "weight": "1" }, { - "shop_price": "12", - "ge_buy_limit": "175", + "id": "10116", + "name": "Dark kebbit fur", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10117", + "name": "Polar kebbit fur", "examine": "A thick fur for a cold climate.", - "grand_exchange_price": "3862", - "durability": null, - "name": "Polar kebbit fur", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "10117" - }, - { + "durability": null, "ge_buy_limit": "175", - "grand_exchange_price": "3862", - "durability": null, + "shop_price": "12", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10118", "name": "Polar kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10118" + "durability": null, + "ge_buy_limit": "175", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10119", + "name": "Feldip weasel fur", "examine": "Not actually from a weasel, but it is, at least, furry.", - "grand_exchange_price": "3", - "durability": null, - "name": "Feldip weasel fur", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "10119" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "3", - "durability": null, + "id": "10120", "name": "Feldip weasel fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10120" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10121", + "name": "Common kebbit fur", "examine": "Common fur from a common kebbit.", - "grand_exchange_price": "1555", - "durability": null, - "name": "Common kebbit fur", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "10121" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1555", - "durability": null, + "id": "10122", "name": "Common kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10122" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10123", + "name": "Desert devil fur", "examine": "Sandy coloured kebbit fur.", - "grand_exchange_price": "95", - "durability": null, - "name": "Desert devil fur", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "10123" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.4" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "95", - "durability": null, + "id": "10124", "name": "Desert devil fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10124" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10125", + "name": "Spotted kebbit fur", "examine": "Maybe this is why people think furry dice make you go faster.", - "grand_exchange_price": "8", - "durability": null, - "name": "Spotted kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10125" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "8", - "durability": null, + "id": "10126", "name": "Spotted kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10126" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "10127", + "name": "Dashing kebbit fur", "examine": "Nature's equivalent of go-faster stripes.", - "grand_exchange_price": "69", - "durability": null, - "name": "Dashing kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10127" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "69", - "durability": null, + "id": "10128", "name": "Dashing kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10128" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{10,35}", - "ge_buy_limit": "100", - "examine": "A mighty Hunter weapon. One previous owner.", - "durability": null, - "weight": "1.3", - "attack_speed": "5", - "weapon_interface": "5", - "equipment_slot": "3", - "grand_exchange_price": "19", - "name": "Barb-tail harpoon", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10129", - "bonuses": "9,4,-4,0,0,0,0,0,0,0,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "19", - "durability": null, "name": "Barb-tail harpoon", - "tradeable": "true", + "examine": "A mighty Hunter weapon. One previous owner.", "archery_ticket_price": "0", - "id": "10130" + "attack_speed": "5", + "bonuses": "9,4,-4,0,0,0,0,0,0,0,0,6,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "requirements": "{10,35}", + "tradeable": "true", + "weapon_interface": "5", + "weight": "1.3" }, { - "requirements": "{21,24}", - "ge_buy_limit": "100", - "examine": "Not so lucky for the rabbit.", - "grand_exchange_price": "789", - "durability": null, - "name": "Strung rabbit foot", - "tradeable": "true", + "id": "10130", + "name": "Barb-tail harpoon", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "10132", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "789", - "durability": null, "name": "Strung rabbit foot", - "tradeable": "true", + "examine": "Not so lucky for the rabbit.", "archery_ticket_price": "0", - "id": "10133" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "requirements": "{21,24}", + "tradeable": "true" }, { + "id": "10133", + "name": "Strung rabbit foot", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10134", + "name": "Rabbit foot", "examine": "This could be put on a string and worn for luck.", - "grand_exchange_price": "543", - "durability": null, - "name": "Rabbit foot", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10134" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "543", - "durability": null, - "name": "Rabbit foot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10135" + "tradeable": "true" }, { - "shop_price": "48", - "ge_buy_limit": "10000", + "id": "10135", + "name": "Rabbit foot", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10136", + "name": "Rainbow fish", "examine": "Well, this would certainly add some colour to a meal.", - "grand_exchange_price": "99", - "durability": null, - "name": "Rainbow fish", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "10136" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "99", - "durability": null, - "name": "Rainbow fish", + "shop_price": "48", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10137" + "weight": "1" }, { - "ge_buy_limit": "20000", + "id": "10137", + "name": "Rainbow fish", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "10138", + "name": "Raw rainbow fish", "examine": "A colourful fish, attracted to colourful flies.", - "grand_exchange_price": "236", - "durability": null, - "name": "Raw rainbow fish", - "tradeable": "true", - "weight": "5", "archery_ticket_price": "0", - "id": "10138" - }, - { + "durability": null, "ge_buy_limit": "20000", - "grand_exchange_price": "236", - "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "10139", "name": "Raw rainbow fish", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10139" + "durability": null, + "ge_buy_limit": "20000", + "tradeable": "true" }, { - "durability": null, + "id": "10141", "name": "Burnt rainbow fish", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10141" + "durability": null, + "tradeable": "true" }, { - "requirements": "{0,30}-{4,30}-{6,30}", - "ge_buy_limit": "10000", - "examine": "A thick, foul-smelling, tar-like substance with a green tinge", - "grand_exchange_price": "28", - "durability": null, - "name": "Guam tar", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10142", + "name": "Guam tar", + "examine": "A thick, foul-smelling, tar-like substance with a green tinge", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", - "equipment_slot": "13" - }, - { - "requirements": "{0,50}-{4,50}-{6,50}", + "durability": null, + "equipment_slot": "13", "ge_buy_limit": "10000", - "examine": "A thick, foul-smelling, tar-like substance with an orange tinge.", - "grand_exchange_price": "12", - "durability": null, - "name": "Marrentill tar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10143", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", - "equipment_slot": "13" - }, - { - "requirements": "{0,60}-{4,60}-{6,60}", - "ge_buy_limit": "10000", - "examine": "A thick, foul-smelling, tar-like substance with a red tinge.", - "grand_exchange_price": "28", - "durability": null, - "name": "Tarromin tar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10144", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", - "equipment_slot": "13" - }, - { - "requirements": "{0,70}-{4,70}-{6,70}", - "ge_buy_limit": "10000", - "examine": "A dark, thick, foul-smelling, tar-like substance.", - "grand_exchange_price": "47", - "durability": null, - "name": "Harralander tar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10145", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", - "equipment_slot": "13" - }, - { - "ge_buy_limit": "1000", - "turn90cw_anim": "5245", - "examine": "Slightly slimy, but kind of cute.", - "walk_anim": "5245", - "turn90ccw_anim": "5245", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "5245", - "equipment_slot": "3", - "grand_exchange_price": "6", - "stand_anim": "5246", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "10146", - "stand_turn_anim": "823", - "bonuses": "0,19,0,0,29,0,0,0,0,0,0,31,0,0,0", - "requirements": "{0,50}-{4,50}-{6,50}", - "shop_price": "127", - "durability": null, - "destroy": "true", - "weight": "4", - "weapon_interface": "21", - "equip_audio": "732", - "render_anim": "1277", - "attack_audios": "740,735,736,0", - "name": "Orange salamander" - }, - { - "ge_buy_limit": "1000", - "turn90cw_anim": "5245", - "examine": "Slightly slimy but certainly striking.", - "walk_anim": "5245", - "turn90ccw_anim": "5245", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "5245", - "equipment_slot": "3", - "grand_exchange_price": "27", - "stand_anim": "5246", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "10147", - "stand_turn_anim": "823", - "bonuses": "0,37,0,0,47,0,0,0,0,0,0,49,0,0,0", - "requirements": "{0,60}-{4,60}-{6,60}", - "shop_price": "190", - "durability": null, - "destroy": "true", - "weight": "4", - "weapon_interface": "21", - "equip_audio": "732", - "render_anim": "1277", - "attack_audios": "740,735,736,0", - "name": "Red salamander" - }, - { - "ge_buy_limit": "1000", - "turn90cw_anim": "5245", - "examine": "Slightly slimy and somewhat menacing.", - "walk_anim": "5245", - "turn90ccw_anim": "5245", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "5245", - "equipment_slot": "3", - "grand_exchange_price": "124", - "stand_anim": "5246", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "10148", - "stand_turn_anim": "823", - "bonuses": "0,59,0,0,69,0,0,0,0,0,0,71,0,0,0", - "requirements": "{0,70}-{4,70}-{6,70}", - "durability": null, - "destroy": "true", - "weight": "4", - "weapon_interface": "21", - "equip_audio": "732", - "render_anim": "1277", - "attack_audios": "740,735,736,0", - "name": "Black salamander" - }, - { - "ge_buy_limit": "2000", - "turn90cw_anim": "5245", - "examine": "A very slimy and generally disgusting green lizard.", - "walk_anim": "5245", - "turn90ccw_anim": "5245", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "5245", - "equipment_slot": "3", - "grand_exchange_price": "1802", - "stand_anim": "5246", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "10149", - "stand_turn_anim": "823", - "bonuses": "0,10,0,0,20,0,0,0,0,0,0,22,0,0,0", "requirements": "{0,30}-{4,30}-{6,30}", - "durability": null, - "destroy": "true", - "weight": "4", - "weapon_interface": "21", - "equip_audio": "732", - "render_anim": "1277", - "attack_audios": "740,735,736,0", - "name": "Swamp lizard" + "tradeable": "true" }, { - "shop_price": "4", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A noose on a stick.", - "walk_anim": "5250", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "14", - "turn180_anim": "5251", - "render_anim": "1279", - "equipment_slot": "3", - "grand_exchange_price": "1", - "stand_anim": "5254", - "name": "Noose wand", - "tradeable": "true", - "run_anim": "5253", + "id": "10143", + "name": "Marrentill tar", + "examine": "A thick, foul-smelling, tar-like substance with an orange tinge.", "archery_ticket_price": "0", - "id": "10150", - "stand_turn_anim": "5252" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{0,50}-{4,50}-{6,50}", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1", - "durability": null, - "name": "Noose wand", - "tradeable": "true", + "id": "10144", + "name": "Tarromin tar", + "examine": "A thick, foul-smelling, tar-like substance with a red tinge.", "archery_ticket_price": "0", - "id": "10151" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{0,60}-{4,60}-{6,60}", + "tradeable": "true" }, { - "requirements": "{4,50}", - "ge_buy_limit": "100", - "shop_price": "1300", - "turn90cw_anim": "821", - "examine": "A weapon made of bone and wood.", - "walk_anim": "4226", - "durability": null, - "weight": "5", - "turn90ccw_anim": "822", - "attack_speed": "4", - "weapon_interface": "17", - "turn180_anim": "4227", - "render_anim": "175", - "equipment_slot": "3", - "grand_exchange_price": "2496", - "stand_anim": "4591", - "attack_audios": "2700,0,0,0", - "tradeable": "true", - "name": "Hunters' crossbow", - "run_anim": "4228", + "id": "10145", + "name": "Harralander tar", + "examine": "A dark, thick, foul-smelling, tar-like substance.", "archery_ticket_price": "0", - "id": "10156", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,55,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,49", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{0,70}-{4,70}-{6,70}", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "2496", - "durability": null, - "name": "Hunters' crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10157" - }, - { - "requirements": "{4,50}", - "ge_buy_limit": "1000", - "examine": "Bolts made from the spikes of a prickly kebbit.", - "grand_exchange_price": "28", - "durability": null, - "name": "Kebbit bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10158", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", - "equipment_slot": "13" - }, - { - "requirements": "{4,50}", - "ge_buy_limit": "1000", - "examine": "Bolts made from the spikes of a razor-backed kebbit.", - "grand_exchange_price": "352", - "durability": null, - "name": "Long kebbit bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10159", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,38", - "equipment_slot": "13" - }, - { - "durability": null, + "id": "10146", "name": "Orange salamander", - "tradeable": "true", + "examine": "Slightly slimy, but kind of cute.", "archery_ticket_price": "0", - "id": "10160" + "attack_audios": "740,735,736,0", + "attack_speed": "5", + "bonuses": "0,19,0,0,29,0,0,0,0,0,0,31,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "732", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "render_anim": "1277", + "requirements": "{0,50}-{4,50}-{6,50}", + "run_anim": "824", + "shop_price": "127", + "stand_anim": "5246", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "5245", + "turn90ccw_anim": "5245", + "turn90cw_anim": "5245", + "two_handed": "true", + "walk_anim": "5245", + "weapon_interface": "21", + "weight": "4" }, { - "durability": null, + "id": "10147", "name": "Red salamander", - "tradeable": "true", + "examine": "Slightly slimy but certainly striking.", "archery_ticket_price": "0", - "id": "10161" + "attack_audios": "740,735,736,0", + "attack_speed": "5", + "bonuses": "0,37,0,0,47,0,0,0,0,0,0,49,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "732", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "render_anim": "1277", + "requirements": "{0,60}-{4,60}-{6,60}", + "run_anim": "824", + "shop_price": "190", + "stand_anim": "5246", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "5245", + "turn90ccw_anim": "5245", + "turn90cw_anim": "5245", + "two_handed": "true", + "walk_anim": "5245", + "weapon_interface": "21", + "weight": "4" }, { - "durability": null, + "id": "10148", "name": "Black salamander", - "tradeable": "true", + "examine": "Slightly slimy and somewhat menacing.", "archery_ticket_price": "0", - "id": "10162" + "attack_audios": "740,735,736,0", + "attack_speed": "5", + "bonuses": "0,59,0,0,69,0,0,0,0,0,0,71,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "732", + "equipment_slot": "3", + "ge_buy_limit": "1000", + "render_anim": "1277", + "requirements": "{0,70}-{4,70}-{6,70}", + "run_anim": "824", + "stand_anim": "5246", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "5245", + "turn90ccw_anim": "5245", + "turn90cw_anim": "5245", + "two_handed": "true", + "walk_anim": "5245", + "weapon_interface": "21", + "weight": "4" }, { - "durability": null, + "id": "10149", "name": "Swamp lizard", + "examine": "A very slimy and generally disgusting green lizard.", + "archery_ticket_price": "0", + "attack_audios": "740,735,736,0", + "attack_speed": "5", + "bonuses": "0,10,0,0,20,0,0,0,0,0,0,22,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "732", + "equipment_slot": "3", + "ge_buy_limit": "2000", + "render_anim": "1277", + "requirements": "{0,30}-{4,30}-{6,30}", + "run_anim": "824", + "stand_anim": "5246", + "stand_turn_anim": "823", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10163" + "turn180_anim": "5245", + "turn90ccw_anim": "5245", + "turn90cw_anim": "5245", + "two_handed": "true", + "walk_anim": "5245", + "weapon_interface": "21", + "weight": "4" }, { - "examine": "Probably a bit too big for fly fishing.", + "id": "10150", + "name": "Noose wand", + "examine": "A noose on a stick.", + "archery_ticket_price": "0", + "attack_speed": "4", "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "1279", + "run_anim": "5253", + "shop_price": "4", + "stand_anim": "5254", + "stand_turn_anim": "5252", + "tradeable": "true", + "turn180_anim": "5251", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "5250", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "10151", + "name": "Noose wand", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10156", + "name": "Hunters' crossbow", + "examine": "A weapon made of bone and wood.", + "archery_ticket_price": "0", + "attack_audios": "2700,0,0,0", + "attack_speed": "4", + "bonuses": "0,0,0,0,55,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "175", + "requirements": "{4,50}", + "run_anim": "4228", + "shop_price": "1300", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "5" + }, + { + "id": "10157", + "name": "Hunters' crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10158", + "name": "Kebbit bolts", + "examine": "Bolts made from the spikes of a prickly kebbit.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "requirements": "{4,50}", + "tradeable": "true" + }, + { + "id": "10159", + "name": "Long kebbit bolts", + "examine": "Bolts made from the spikes of a razor-backed kebbit.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,38", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "1000", + "requirements": "{4,50}", + "tradeable": "true" + }, + { + "id": "10160", + "name": "Orange salamander", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10161", + "name": "Red salamander", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10162", + "name": "Black salamander", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10163", + "name": "Swamp lizard", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10167", "name": "Eagle feather", + "examine": "Probably a bit too big for fly fishing.", "archery_ticket_price": "0", - "id": "10167" + "durability": null }, { - "examine": "A cape made from giant eagle feathers.", - "durability": null, - "name": "Eagle cape", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10171", - "equipment_slot": "1" + "name": "Eagle cape", + "examine": "A cape made from giant eagle feathers.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "1", + "weight": "0.2" }, { - "examine": "A cheaply made fake beak.", - "durability": null, - "name": "Fake beak", - "archery_ticket_price": "0", "id": "10172", + "name": "Fake beak", + "examine": "A cheaply made fake beak.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "0" }, { - "examine": "The title reads 'William Oddity's Guide to the Avian.", - "durability": null, + "id": "10173", "name": "Bird book", + "examine": "The title reads 'William Oddity's Guide to the Avian.", "archery_ticket_price": "0", - "id": "10173" + "durability": null }, { - "destroy_message": "You can obtain another metal feather from the camp", - "examine": "A small feather made out of some sort of metal. The detail is exquisite.", - "durability": null, + "id": "10174", "name": "Metal feather", - "tradeable": "false", - "destroy": "true", + "examine": "A small feather made out of some sort of metal. The detail is exquisite.", "archery_ticket_price": "0", - "id": "10174" + "destroy": "true", + "destroy_message": "You can obtain another metal feather from the camp", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another by inspecting the opening", - "examine": "An intricate feather crafted from a silver-coloured metal of some sort.", - "durability": null, + "id": "10176", "name": "Silver feather", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "An intricate feather crafted from a silver-coloured metal of some sort.", "archery_ticket_price": "0", - "id": "10176" + "destroy": "true", + "destroy_message": "You can get another by inspecting the opening", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "You can get another by taking from pedestal.", - "examine": "An intricate feather crafted from a bronze-coloured metal of some sort.", - "durability": null, + "id": "10177", "name": "Bronze feather", - "tradeable": "false", + "examine": "An intricate feather crafted from a bronze-coloured metal of some sort.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "10177" + "destroy_message": "You can get another by taking from pedestal.", + "durability": null, + "tradeable": "false" }, { - "examine": "\"It looks like bird seed, but it's not quite right somehow.", - "durability": null, + "id": "10178", "name": "Odd bird seed", + "examine": "\"It looks like bird seed, but it's not quite right somehow.", "archery_ticket_price": "0", - "id": "10178" + "durability": null }, { - "examine": "There's a feather glued to the front. \"Property of Arthur Artimus\".", - "durability": null, + "id": "10179", "name": "Feathered journal", + "examine": "There's a feather glued to the front. \"Property of Arthur Artimus\".", "archery_ticket_price": "0", - "id": "10179" + "durability": null }, { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, + "id": "10180", "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10180" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "10181" - }, - { - "shop_price": "5000", "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", "archery_ticket_price": "0", - "id": "10182" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "10183" - }, - { "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10184" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10181", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10185" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10182", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10186" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10183", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10187" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10184", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10188" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10185", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10189" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10186", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10190" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10187", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10191" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10188", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10192" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10189", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10193" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10190", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10194" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10191", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10195" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10192", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10196" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10193", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10197" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10194", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10198" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10195", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10199" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10196", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10200" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10197", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10201" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10198", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10202" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10199", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10203" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10200", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10204" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10201", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10205" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10202", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10206" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10203", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10207" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10204", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10208" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10205", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10209" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10206", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10210" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10207", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10211" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10208", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10212" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10209", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10213" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10210", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10214" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10211", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10215" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10212", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10216" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10213", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10217" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10214", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10218" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10215", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10219" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10216", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10220" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10217", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10221" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10218", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10222" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10219", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10223" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10220", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10224" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10221", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10225" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10222", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10226" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10223", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10227" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10224", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10228" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10225", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10229" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10226", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10230" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10227", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10231" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10228", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10232" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10229", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10233" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10230", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10234" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10231", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10235" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10232", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10236" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10233", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10237" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10234", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10238" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10235", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10239" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10236", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10240" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10237", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10241" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10238", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10242" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10239", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10243" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10240", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10244" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10241", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10245" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10242", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10246" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10243", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10247" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10244", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10248" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10245", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10249" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10246", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10250" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10247", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10251" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10248", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10252" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10249", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10253" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10250", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10254" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10251", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10255" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10252", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10256" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10253", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10257" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10254", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10258" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10255", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10259" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10256", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10260" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10257", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10261" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10258", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10262" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10259", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10263" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10260", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10264" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10261", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10265" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10262", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10266" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10263", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10267" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10264", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10268" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10265", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10269" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10266", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10270" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10267", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10271" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10268", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10272" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10269", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10273" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10270", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10274" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10271", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10275" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10272", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10276" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10273", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10277" + "durability": null, + "tradeable": "true", + "weight": "5" }, { + "id": "10274", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10278" + "tradeable": "false" }, { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, + "id": "10275", "name": "Casket", - "tradeable": "true", - "weight": "5", + "examine": "I hope there's treasure in it.", "archery_ticket_price": "0", - "id": "10279" + "durability": null, + "tradeable": "true", + "weight": "5" }, { - "ge_buy_limit": "2", - "turn90cw_anim": "1207", - "examine": "A powerful bow made from willow.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "equipment_slot": "3", - "grand_exchange_price": "136", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "10276", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "10277", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "10278", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "10279", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { "id": "10280", - "stand_turn_anim": "1209", - "bonuses": "0,0,0,0,22,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,20}", - "durability": null, - "weight": "1.8", - "weapon_interface": "16", - "render_anim": "28", - "lendable": "true", - "attack_audios": "2700,0,0,0", - "name": "Willow comp bow" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "136", - "durability": null, "name": "Willow comp bow", - "tradeable": "true", + "examine": "A powerful bow made from willow.", "archery_ticket_price": "0", - "id": "10281" + "attack_audios": "2700,0,0,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,22,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "lendable": "true", + "render_anim": "28", + "requirements": "{4,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "16", + "weight": "1.8" }, { - "ge_buy_limit": "2", - "turn90cw_anim": "1207", - "examine": "A powerful bow made from yew wood.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "equipment_slot": "3", - "grand_exchange_price": "876", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", + "id": "10281", + "name": "Willow comp bow", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10282", - "stand_turn_anim": "1209", - "bonuses": "0,0,0,0,49,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,40}", - "durability": null, - "weight": "1.8", - "weapon_interface": "16", - "render_anim": "28", - "lendable": "true", - "attack_audios": "2700,0,0,0", - "name": "Yew comp bow" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "876", - "durability": null, "name": "Yew comp bow", - "tradeable": "true", + "examine": "A powerful bow made from yew wood.", "archery_ticket_price": "0", - "id": "10283" - }, - { - "ge_buy_limit": "2", - "turn90cw_anim": "1207", - "examine": "A powerful bow made from magic wood.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "equipment_slot": "3", - "grand_exchange_price": "1268", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "10284", - "stand_turn_anim": "1209", - "bonuses": "0,0,0,0,71,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,50}", - "durability": null, - "weight": "1.3", - "weapon_interface": "16", - "render_anim": "28", - "lendable": "true", "attack_audios": "2700,0,0,0", - "name": "Magic comp bow" + "attack_speed": "5", + "bonuses": "0,0,0,0,49,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "lendable": "true", + "render_anim": "28", + "requirements": "{4,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "16", + "weight": "1.8" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "1268", + "id": "10283", + "name": "Yew comp bow", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10284", "name": "Magic comp bow", - "tradeable": "true", + "examine": "A powerful bow made from magic wood.", "archery_ticket_price": "0", - "id": "10285" + "attack_audios": "2700,0,0,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,71,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "requirements": "{4,50}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "16", + "weight": "1.3" }, { - "remove_head": "true", - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "23600", - "name": "Rune helm (h1)", - "tradeable": "true", + "id": "10285", + "name": "Magic comp bow", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10286", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "23600", - "durability": null, "name": "Rune helm (h1)", - "tradeable": "true", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "10287" - }, - { + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "20800", - "name": "Rune helm (h2)", - "tradeable": "true", + "tradeable": "true" + }, + { + "id": "10287", + "name": "Rune helm (h1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10288", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "20800", - "durability": null, "name": "Rune helm (h2)", - "tradeable": "true", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "10289" - }, - { + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "4", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "20800", - "name": "Rune helm (h3)", "tradeable": "true", + "weight": "3" + }, + { + "id": "10289", + "name": "Rune helm (h2)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10290", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "20800", - "durability": null, "name": "Rune helm (h3)", - "tradeable": "true", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "10291" - }, - { + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "21100", - "name": "Rune helm (h4)", "tradeable": "true", + "weight": "4" + }, + { + "id": "10291", + "name": "Rune helm (h3)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10292", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "21100", - "durability": null, "name": "Rune helm (h4)", - "tradeable": "true", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "10293" - }, - { + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "24900", - "name": "Rune helm (h5)", "tradeable": "true", + "weight": "2" + }, + { + "id": "10293", + "name": "Rune helm (h4)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10294", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "24900", - "durability": null, "name": "Rune helm (h5)", - "tradeable": "true", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", "archery_ticket_price": "0", - "id": "10295" + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2" }, { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "31500", - "name": "Adamant helm (h1)", - "tradeable": "true", + "id": "10295", + "name": "Rune helm (h5)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10296", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "31500", - "durability": null, "name": "Adamant helm (h1)", - "tradeable": "true", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "10297" - }, - { + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "10100", - "name": "Adamant helm (h2)", "tradeable": "true", + "weight": "3" + }, + { + "id": "10297", + "name": "Adamant helm (h1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10298", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "10100", - "durability": null, "name": "Adamant helm (h2)", - "tradeable": "true", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "10299" - }, - { + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "8797", - "name": "Adamant helm (h3)", "tradeable": "true", + "weight": "3" + }, + { + "id": "10299", + "name": "Adamant helm (h2)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10300", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "8797", - "durability": null, "name": "Adamant helm (h3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10301" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An Adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "10900", - "name": "Adamant helm (h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10302", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "10900", - "durability": null, - "name": "Adamant helm (h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10303" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "17100", - "name": "Adamant helm (h5)", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10301", + "name": "Adamant helm (h3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10302", + "name": "Adamant helm (h4)", + "examine": "An Adamant helmet with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10303", + "name": "Adamant helm (h4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10304", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "17100", - "durability": null, "name": "Adamant helm (h5)", - "tradeable": "true", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", - "id": "10305" + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" }, { - "remove_head": "true", - "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black helmet with a heraldic design.", - "durability": null, - "weight": "1.8", - "equipment_slot": "0", - "grand_exchange_price": "20400", - "name": "Black helm (h1)", - "tradeable": "true", + "id": "10305", + "name": "Adamant helm (h5)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10306", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "20400", - "durability": null, "name": "Black helm (h1)", - "tradeable": "true", + "examine": "A black helmet with a heraldic design.", "archery_ticket_price": "0", - "id": "10307" - }, - { + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black helmet with a heraldic design.", - "durability": null, - "weight": "1.8", - "equipment_slot": "0", - "grand_exchange_price": "7033", - "name": "Black helm (h2)", "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10307", + "name": "Black helm (h1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10308", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7033", - "durability": null, "name": "Black helm (h2)", - "tradeable": "true", + "examine": "A black helmet with a heraldic design.", "archery_ticket_price": "0", - "id": "10309" - }, - { + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black helmet with a heraldic design.", - "durability": null, - "weight": "1.8", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "7574", - "name": "Black helm (h3)", "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10309", + "name": "Black helm (h2)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10310", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7574", - "durability": null, "name": "Black helm (h3)", - "tradeable": "true", + "examine": "A black helmet with a heraldic design.", "archery_ticket_price": "0", - "id": "10311" - }, - { + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black helmet with a heraldic design.", - "durability": null, - "weight": "1.8", - "equipment_slot": "0", - "grand_exchange_price": "10100", - "name": "Black helm (h4)", "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10311", + "name": "Black helm (h3)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10312", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "10100", - "durability": null, "name": "Black helm (h4)", - "tradeable": "true", + "examine": "A black helmet with a heraldic design.", "archery_ticket_price": "0", - "id": "10313" - }, - { + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,10}", - "ge_buy_limit": "2", - "examine": "A black helmet with a heraldic design.", - "durability": null, - "weight": "1.8", - "equipment_slot": "0", - "grand_exchange_price": "10400", - "name": "Black helm (h5)", "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10313", + "name": "Black helm (h4)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10314", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "10400", - "durability": null, "name": "Black helm (h5)", - "tradeable": "true", + "examine": "A black helmet with a heraldic design.", "archery_ticket_price": "0", - "id": "10315" + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.8" }, { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "Bob says: 'Never give your password out to anyone.'", - "grand_exchange_price": "8196", - "durability": null, - "name": "Bob shirt", - "tradeable": "true", - "weight": "2", + "id": "10315", + "name": "Black helm (h5)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10316", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "8196", - "durability": null, "name": "Bob shirt", - "tradeable": "true", + "examine": "Bob says: 'Never give your password out to anyone.'", "archery_ticket_price": "0", - "id": "10317" - }, - { + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "Bob says: 'Always check the second trade screen.'", - "grand_exchange_price": "14700", - "durability": null, - "name": "Bob shirt", "tradeable": "true", - "weight": "2", + "weight": "2" + }, + { + "id": "10317", + "name": "Bob shirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10318", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "14700", - "durability": null, "name": "Bob shirt", - "tradeable": "true", + "examine": "Bob says: 'Always check the second trade screen.'", "archery_ticket_price": "0", - "id": "10319" - }, - { + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "Bob says: 'Never trade in the wilderness!'", - "grand_exchange_price": "8403", - "durability": null, - "name": "Bob shirt", "tradeable": "true", - "weight": "2", + "weight": "2" + }, + { + "id": "10319", + "name": "Bob shirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10320", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "8403", - "durability": null, "name": "Bob shirt", - "tradeable": "true", + "examine": "Bob says: 'Never trade in the wilderness!'", "archery_ticket_price": "0", - "id": "10321" - }, - { + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "Bob says: 'A bank pin will keep your items secure.'", - "grand_exchange_price": "9230", - "durability": null, - "name": "Bob shirt", "tradeable": "true", - "weight": "2", + "weight": "2" + }, + { + "id": "10321", + "name": "Bob shirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10322", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "9230", - "durability": null, "name": "Bob shirt", - "tradeable": "true", + "examine": "Bob says: 'A bank pin will keep your items secure.'", "archery_ticket_price": "0", - "id": "10323" - }, - { + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "Bob says: 'Keep your computer keylogger free and virus scanned.'", - "grand_exchange_price": "8197", - "durability": null, - "name": "Bob shirt", "tradeable": "true", - "weight": "2", + "weight": "2" + }, + { + "id": "10323", + "name": "Bob shirt", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10324", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "8197", - "durability": null, "name": "Bob shirt", - "tradeable": "true", + "examine": "Bob says: 'Keep your computer keylogger free and virus scanned.'", "archery_ticket_price": "0", - "id": "10325" + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "examine": "Makes firelighting a lot easier.", - "grand_exchange_price": "112", + "id": "10325", + "name": "Bob shirt", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10326", "name": "Purple firelighter", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10326" - }, - { - "ge_buy_limit": "100", "examine": "Makes firelighting a lot easier.", - "grand_exchange_price": "167", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10327", "name": "White firelighter", - "tradeable": "true", + "examine": "Makes firelighting a lot easier.", "archery_ticket_price": "0", - "id": "10327" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "A number of chemical covered wooden logs.", - "durability": null, + "id": "10328", "name": "White logs", - "archery_ticket_price": "0", - "id": "10328" - }, - { "examine": "A number of chemical covered wooden logs.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10329", "name": "Purple logs", + "examine": "A number of chemical covered wooden logs.", "archery_ticket_price": "0", - "id": "10329" + "durability": null }, { - "requirements": "{1,45}-{4,65}", - "ge_buy_limit": "2", - "examine": "Ancient range protection crafted from white dragonhide.", - "durability": null, - "weight": "4", - "absorb": "0,6,3", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "33900000", - "name": "3rd age range top", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10330", - "bonuses": "0,0,0,-15,30,55,47,60,60,55,52,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "33900000", - "durability": null, "name": "3rd age range top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10331" - }, - { - "requirements": "{1,45}-{4,65}", - "ge_buy_limit": "2", - "examine": "Fabulously ancient range protection crafted from white dragonhide.", - "durability": null, - "weight": "6", - "absorb": "0,4,2", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "20800000", - "name": "3rd age range legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10332", - "bonuses": "0,0,0,-10,17,31,25,33,30,31,25,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "20800000", - "durability": null, - "name": "3rd age range legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10333" - }, - { - "remove_head": "true", - "requirements": "{1,45}-{4,65}", - "ge_buy_limit": "5000", "examine": "Ancient range protection crafted from white dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "6100000", - "name": "3rd age range coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10334", - "bonuses": "0,0,0,-2,9,4,7,10,5,8,12,0,0,0,0" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "6100000", - "durability": null, - "name": "3rd age range coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10335" - }, - { - "requirements": "{1,45}-{4,65}", - "ge_buy_limit": "2", - "examine": "Fabulously ancient range protection crafted from white dragonhide.", - "durability": null, - "weight": "1", - "equipment_slot": "9", - "lendable": "true", - "grand_exchange_price": "7100000", - "name": "3rd age vambraces", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10336", - "bonuses": "0,0,0,-10,11,6,5,7,9,0,5,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7100000", - "durability": null, - "name": "3rd age vambraces", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10337" - }, - { - "requirements": "{1,30}-{6,65}", - "ge_buy_limit": "2", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "durability": null, - "weight": "2.5", - "absorb": "4,2,0", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "66500000", - "name": "3rd age robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10338", - "bonuses": "0,0,0,24,0,0,0,0,24,0,24,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "66500000", - "durability": null, - "name": "3rd age robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10339" - }, - { - "requirements": "{1,30}-{6,65}", - "ge_buy_limit": "2", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "durability": null, - "weight": "1", - "absorb": "4,2,0", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "31500000", - "name": "3rd age robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10340", - "bonuses": "0,0,0,19,0,0,0,0,19,0,20,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "31500000", - "durability": null, - "name": "3rd age robe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10341" - }, - { - "remove_head": "true", - "requirements": "{1,30}-{6,65}", - "ge_buy_limit": "2", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "durability": null, - "absorb": "2,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "21000000", - "name": "3rd age mage hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10342", - "bonuses": "0,0,0,8,0,0,0,0,8,0,12,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "21000000", - "durability": null, - "name": "3rd age mage hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10343" - }, - { - "lendable": "true", - "requirements": "{1,30}-{6,65}", - "ge_buy_limit": "2", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "grand_exchange_price": "20100000", - "durability": null, - "name": "3rd age amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10344", - "bonuses": "0,0,0,15,0,0,0,0,10,0,0,0,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "20100000", - "durability": null, - "name": "3rd age amulet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10345" - }, - { - "requirements": "{1,65}", - "ge_buy_limit": "2", - "examine": "Ancient armour beaten from magical silver.", - "durability": null, - "weight": "2", - "absorb": "3,0,6", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "92800000", - "name": "3rd age platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10346", - "bonuses": "0,0,0,-25,-2,78,76,83,-5,75,25,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "92800000", - "durability": null, - "name": "3rd age platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10347" - }, - { - "requirements": "{1,65}", - "ge_buy_limit": "2", - "examine": "Ancient armour beaten from magical silver.", - "durability": null, - "weight": "9", - "absorb": "4,0,9", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "86200000", - "name": "3rd age platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10348", - "bonuses": "0,0,0,-20,0,96,108,113,-4,97,52,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "86200000", - "durability": null, - "name": "3rd age platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10349" - }, - { - "remove_head": "true", - "requirements": "{1,65}", - "ge_buy_limit": "2", - "examine": "Ancient armour beaten from magical silver.", - "durability": null, - "weight": "1", - "absorb": "2,0,4", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "41600000", - "name": "3rd age full helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10350", - "bonuses": "0,0,0,-5,-2,47,49,43,-3,48,12,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "41600000", - "durability": null, - "name": "3rd age full helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10351" - }, - { - "requirements": "{1,65}", - "ge_buy_limit": "2", - "examine": "Ancient armour beaten from magical silver.", - "durability": null, - "weight": "2", - "absorb": "5,0,11", - "equipment_slot": "5", - "lendable": "true", - "grand_exchange_price": "65100000", - "name": "3rd age kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10352", - "bonuses": "0,0,0,-10,-4,63,65,61,-3,63,60,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "65100000", - "durability": null, - "name": "3rd age kiteshield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10353" - }, - { - "ge_buy_limit": "100", - "examine": "A dragonstone amulet with 4 magic charges.", - "grand_exchange_price": "233100", - "durability": null, - "name": "Amulet of glory(t4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10354", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "233100", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(t4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10355" - }, - { - "examine": "A dragonstone amulet with 3 magic charges.", - "grand_exchange_price": "1", - "durability": null, - "name": "Amulet of glory(t3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10356", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(t3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10357" - }, - { - "examine": "A dragonstone amulet with 2 magic charges.", - "grand_exchange_price": "1", - "durability": null, - "name": "Amulet of glory(t2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10358", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(t2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10359" - }, - { - "examine": "A dragonstone amulet with 1 magic charge.", - "grand_exchange_price": "1", - "durability": null, - "name": "Amulet of glory(t1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10360", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(t1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10361" - }, - { - "ge_buy_limit": "100", - "examine": "A very powerful dragonstone amulet with a nice trim.", - "grand_exchange_price": "223000", - "durability": null, - "name": "Amulet of glory(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10362", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "223000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Amulet of glory(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10363" - }, - { - "ge_buy_limit": "2", - "examine": "An enchanted ruby amulet with a nice trim.", - "grand_exchange_price": "819400", - "durability": null, - "name": "Strength amulet(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10364", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "819400", - "durability": null, - "name": "Strength amulet(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10365" - }, - { - "ge_buy_limit": "5000", - "examine": "An enchanted sapphire amulet of magic.", - "grand_exchange_price": "128700", - "durability": null, - "name": "Amulet of magic(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10366", - "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "128700", - "durability": null, - "name": "Amulet of magic(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10367" - }, - { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Zamorak blessed dragonhide vambraces.", - "grand_exchange_price": "116200", - "durability": null, - "name": "Zamorak bracers", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10368", - "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "116200", - "durability": null, - "name": "Zamorak bracers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10369" - }, - { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Zamorak blessed dragonhide body armour.", - "durability": null, - "weight": "6", "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,60,55,52,0,0,0,0", + "durability": null, "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "155200", - "name": "Zamorak d'hide", + "requirements": "{1,45}-{4,65}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10370", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + "weight": "4" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "155200", - "durability": null, - "name": "Zamorak d'hide", - "tradeable": "true", + "id": "10331", + "name": "3rd age range top", "archery_ticket_price": "0", - "id": "10371" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Zamorak blessed dragonhide chaps.", - "durability": null, - "weight": "5", + "id": "10332", + "name": "3rd age range legs", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", "absorb": "0,4,2", - "equipment_slot": "7", - "grand_exchange_price": "35100", - "name": "Zamorak chaps", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10372", - "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "35100", + "bonuses": "0,0,0,-10,17,31,25,33,30,31,25,0,0,0,0", "durability": null, - "name": "Zamorak chaps", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,45}-{4,65}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10373" + "weight": "6" }, { + "id": "10333", + "name": "3rd age range legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10334", + "name": "3rd age range coif", + "examine": "Ancient range protection crafted from white dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-2,9,4,7,10,5,8,12,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "5000", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,45}-{4,65}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10335", + "name": "3rd age range coif", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10336", + "name": "3rd age vambraces", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,11,6,5,7,9,0,5,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,45}-{4,65}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10337", + "name": "3rd age vambraces", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10338", + "name": "3rd age robe top", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,24,0,0,0,0,24,0,24,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,30}-{6,65}", + "tradeable": "true", + "weight": "2.5" + }, + { + "id": "10339", + "name": "3rd age robe top", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10340", + "name": "3rd age robe", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,19,0,0,0,0,19,0,20,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,30}-{6,65}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10341", + "name": "3rd age robe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10342", + "name": "3rd age mage hat", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,8,0,0,0,0,8,0,12,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,30}-{6,65}", + "tradeable": "true" + }, + { + "id": "10343", + "name": "3rd age mage hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10344", + "name": "3rd age amulet", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,15,0,0,0,0,10,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,30}-{6,65}", + "tradeable": "true" + }, + { + "id": "10345", + "name": "3rd age amulet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10346", + "name": "3rd age platelegs", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-25,-2,78,76,83,-5,75,25,0,0,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10347", + "name": "3rd age platelegs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10348", + "name": "3rd age platebody", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-20,0,96,108,113,-4,97,52,0,0,0,0", + "durability": null, + "equip_audio": "2234", + "equipment_slot": "4", + "ge_buy_limit": "2", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "9" + }, + { + "id": "10349", + "name": "3rd age platebody", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10350", + "name": "3rd age full helmet", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,-2,47,49,43,-3,48,12,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10351", + "name": "3rd age full helmet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10352", + "name": "3rd age kiteshield", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "5,0,11", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-4,63,65,61,-3,63,60,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10353", + "name": "3rd age kiteshield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10354", + "name": "Amulet of glory(t4)", + "examine": "A dragonstone amulet with 4 magic charges.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10355", + "name": "Amulet of glory(t4)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10356", + "name": "Amulet of glory(t3)", + "examine": "A dragonstone amulet with 3 magic charges.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "10357", + "name": "Amulet of glory(t3)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10358", + "name": "Amulet of glory(t2)", + "examine": "A dragonstone amulet with 2 magic charges.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "10359", + "name": "Amulet of glory(t2)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10360", + "name": "Amulet of glory(t1)", + "examine": "A dragonstone amulet with 1 magic charge.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "10361", + "name": "Amulet of glory(t1)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10362", + "name": "Amulet of glory(t)", + "examine": "A very powerful dragonstone amulet with a nice trim.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10363", + "name": "Amulet of glory(t)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10364", + "name": "Strength amulet(t)", + "examine": "An enchanted ruby amulet with a nice trim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10365", + "name": "Strength amulet(t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10366", + "name": "Amulet of magic(t)", + "examine": "An enchanted sapphire amulet of magic.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10367", + "name": "Amulet of magic(t)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10368", + "name": "Zamorak bracers", + "examine": "Zamorak blessed dragonhide vambraces.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10369", + "name": "Zamorak bracers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10370", + "name": "Zamorak d'hide", + "examine": "Zamorak blessed dragonhide body armour.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "10371", + "name": "Zamorak d'hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10372", + "name": "Zamorak chaps", + "examine": "Zamorak blessed dragonhide chaps.", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "10373", + "name": "Zamorak chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10374", + "name": "Zamorak coif", + "examine": "Zamorak blessed dragonhide coif.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Zamorak blessed dragonhide coif.", - "durability": null, - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "35900", - "name": "Zamorak coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10374", - "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0" + "tradeable": "true" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "35900", - "durability": null, + "id": "10375", "name": "Zamorak coif", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10375" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Guthix blessed dragonhide vambraces.", - "grand_exchange_price": "3181", - "durability": null, - "name": "Guthix bracers", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10376", - "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "3181", - "durability": null, "name": "Guthix bracers", - "tradeable": "true", + "examine": "Guthix blessed dragonhide vambraces.", "archery_ticket_price": "0", - "id": "10377" + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "1" }, { + "id": "10377", + "name": "Guthix bracers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10378", + "name": "Guthix dragonhide", + "examine": "Guthix blessed dragonhide body armour.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", "requirements": "{1,40}-{4,70}", "shop_price": "13", - "ge_buy_limit": "2", - "examine": "Guthix blessed dragonhide body armour.", - "durability": null, - "weight": "6", - "absorb": "0,6,3", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "39800", - "name": "Guthix dragonhide", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10378", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + "weight": "6" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "39800", - "durability": null, + "id": "10379", "name": "Guthix dragonhide", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10379" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Guthix blessed dragonhide chaps.", - "durability": null, - "weight": "5", - "absorb": "0,4,2", - "equipment_slot": "7", - "grand_exchange_price": "7346", - "name": "Guthix chaps", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10380", - "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7346", - "durability": null, "name": "Guthix chaps", - "tradeable": "true", + "examine": "Guthix blessed dragonhide chaps.", + "absorb": "0,4,2", "archery_ticket_price": "0", - "id": "10381" + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "5" }, { + "id": "10381", + "name": "Guthix chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10382", + "name": "Guthix coif", + "examine": "Guthix blessed dragonhide coif.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Guthix blessed dragonhide coif.", - "durability": null, - "weight": "0.85", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "27500", - "name": "Guthix coif", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10382", - "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0" + "weight": "0.85" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "27500", - "durability": null, + "id": "10383", "name": "Guthix coif", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10383" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,70}-{4,40}", - "ge_buy_limit": "2", - "examine": "Saradomin blessed dragonhide vambraces.", - "grand_exchange_price": "70800", - "durability": null, - "name": "Saradomin bracers", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10384", - "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "70800", - "durability": null, "name": "Saradomin bracers", - "tradeable": "true", + "examine": "Saradomin blessed dragonhide vambraces.", "archery_ticket_price": "0", - "id": "10385" + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "9", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "1" }, { + "id": "10385", + "name": "Saradomin bracers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10386", + "name": "Saradomin d'hide", + "examine": "Saradomin blessed dragonhide body armour.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", "requirements": "{1,40}-{4,70}", "shop_price": "13000", - "ge_buy_limit": "2", - "examine": "Saradomin blessed dragonhide body armour.", - "durability": null, - "destroy": "true", - "weight": "6", - "absorb": "0,6,3", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "164100", - "name": "Saradomin d'hide", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10386", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + "weight": "6" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "164100", - "durability": null, + "id": "10387", "name": "Saradomin d'hide", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10387" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Saradomin blessed dragonhide chaps.", - "grand_exchange_price": "36600", - "durability": null, - "name": "Saradomin chaps", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10388", - "absorb": "0,4,2", - "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "36600", - "durability": null, "name": "Saradomin chaps", - "tradeable": "true", + "examine": "Saradomin blessed dragonhide chaps.", + "absorb": "0,4,2", "archery_ticket_price": "0", - "id": "10389" + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0", + "durability": null, + "equip_audio": "2241", + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true" }, { + "id": "10389", + "name": "Saradomin chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10390", + "name": "Saradomin coif", + "examine": "Saradomin blessed dragonhide coif.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "2", "remove_head": "true", "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Saradomin blessed dragonhide coif.", - "durability": null, - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "28000", - "name": "Saradomin coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10390", - "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0" + "tradeable": "true" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "28000", - "durability": null, + "id": "10391", "name": "Saradomin coif", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10391" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "A big 'do about nothing.", - "grand_exchange_price": "45400", - "durability": null, - "name": "A powdered wig", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10392", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "45400", - "durability": null, "name": "A powdered wig", - "tradeable": "true", + "examine": "A big 'do about nothing.", "archery_ticket_price": "0", - "id": "10393" - }, - { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "These'll help me stay alive.", - "grand_exchange_price": "448900", "durability": null, - "name": "Flared trousers", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10394", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "448900", - "durability": null, - "name": "Flared trousers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10395" - }, - { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "Alas, someone has slashed my pantaloons.", - "grand_exchange_price": "9863", - "durability": null, - "name": "Pantaloons", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10396", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "9863", - "durability": null, - "name": "Pantaloons", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10397" - }, - { - "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "A cap for wearing whil...zzzzzzzzz", - "grand_exchange_price": "276400", - "durability": null, - "name": "Sleeping cap", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10398", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "276400", - "durability": null, - "name": "Sleeping cap", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10399" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant mans' black shirt.", - "grand_exchange_price": "921500", - "durability": null, - "name": "Black ele' shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10400", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "921500", - "durability": null, - "name": "Black ele' shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10401" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant black pair of pantaloons.", - "grand_exchange_price": "270700", - "durability": null, - "name": "Black ele' legs", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10402", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "270700", - "durability": null, - "name": "Black ele' legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10403" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant men's red shirt.", - "grand_exchange_price": "118600", - "durability": null, - "name": "Red ele' shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10404", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "118600", - "durability": null, - "name": "Red ele' shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10405" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant red pair of pantaloons.", - "grand_exchange_price": "39400", - "durability": null, - "name": "Red ele' legs", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10406", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "39400", - "durability": null, - "name": "Red ele' legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10407" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant mans' blue shirt.", - "grand_exchange_price": "134700", - "durability": null, - "name": "Blue ele' shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10408", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "134700", - "durability": null, - "name": "Blue ele' shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10409" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant pair of men's blue pantaloons", - "grand_exchange_price": "80700", - "durability": null, - "name": "Blue ele' legs", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10410", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "80700", - "durability": null, - "name": "Blue ele' legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10411" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant men's green shirt.", - "grand_exchange_price": "162600", - "durability": null, - "name": "Green ele' shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10412", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "162600", - "durability": null, - "name": "Green ele' shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10413" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant green pair of men's pantaloons.", - "grand_exchange_price": "36100", - "durability": null, - "name": "Green ele' legs", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10414", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "36100", - "durability": null, - "name": "Green ele' legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10415" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant men's purple shirt.", - "grand_exchange_price": "116200", - "durability": null, - "name": "Purple ele' shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10416", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "116200", - "durability": null, - "name": "Purple ele' shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10417" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant purple pair of pantaloons.", - "grand_exchange_price": "73400", - "durability": null, - "name": "Purple ele' legs", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10418", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "73400", - "durability": null, - "name": "Purple ele' legs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10419" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made ladies' elegant white blouse.", - "grand_exchange_price": "571500", - "durability": null, - "name": "White ele' blouse", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10420", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "571500", - "durability": null, - "name": "White ele' blouse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10421" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant white skirt.", - "grand_exchange_price": "56600", - "durability": null, - "name": "White ele' skirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10422", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "56600", - "durability": null, - "name": "White ele' skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10423" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant ladies' red blouse.", - "grand_exchange_price": "15000", - "durability": null, - "name": "Red ele' blouse", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10424", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "15000", - "durability": null, - "name": "Red ele' blouse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10425" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant Red skirt.", - "grand_exchange_price": "7132", - "durability": null, - "name": "Red ele' skirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10426", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "7132", - "durability": null, - "name": "Red ele' skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10427" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made ladies' elegant blue blouse.", - "grand_exchange_price": "22200", - "durability": null, - "name": "Blue ele' blouse", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10428", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "22200", - "durability": null, - "name": "Blue ele' blouse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10429" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant blue skirt.", - "grand_exchange_price": "12200", - "durability": null, - "name": "Blue ele' skirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10430", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "12200", - "durability": null, - "name": "Blue ele' skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10431" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made ladies' elegant green blouse.", - "grand_exchange_price": "12300", - "durability": null, - "name": "Green ele' blouse", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10432", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "12300", - "durability": null, - "name": "Green ele' blouse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10433" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant green skirt.", - "grand_exchange_price": "10300", - "durability": null, - "name": "Green ele' skirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10434", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "10300", - "durability": null, - "name": "Green ele' skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10435" - }, - { - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "A well made elegant ladies' purple blouse.", - "grand_exchange_price": "22800", - "durability": null, - "name": "Purple ele' blouse", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10436", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "22800", - "durability": null, - "name": "Purple ele' blouse", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10437" - }, - { - "ge_buy_limit": "2", - "examine": "A rather elegant purple skirt.", - "grand_exchange_price": "16700", - "durability": null, - "name": "Purple ele' skirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10438", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "16700", - "durability": null, - "name": "Purple ele' skirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10439" - }, - { - "ge_buy_limit": "2", - "turn90cw_anim": "1207", - "examine": "A Saradomin crozier.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "8611", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "10440", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", - "requirements": "{5,60}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Saradomin crozier" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "8611", - "durability": null, - "name": "Saradomin crozier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10441" - }, - { - "ge_buy_limit": "2", - "turn90cw_anim": "1207", - "examine": "A Guthix crozier.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "2925", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "10442", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", - "requirements": "{5,60}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Guthix crozier" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2925", - "durability": null, - "name": "Guthix crozier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10443" - }, - { - "ge_buy_limit": "2", - "turn90cw_anim": "1207", - "examine": "A Zamorak crozier.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "2794", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "10444", - "stand_turn_anim": "1209", - "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", - "requirements": "{5,60}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Zamorak crozier" - }, - { - "attack_anims": "", - "ge_buy_limit": "2", - "grand_exchange_price": "2794", - "durability": null, - "name": "Zamorak crozier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10445" - }, - { - "requirements": "{5,40}", - "ge_buy_limit": "2", - "examine": "A Saradomin cloak.", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Saradomin cloak", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10446", - "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Saradomin cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10447" - }, - { - "requirements": "{5,40}", - "ge_buy_limit": "2", - "examine": "A Guthix cloak.", - "grand_exchange_price": "391000", - "durability": null, - "name": "Guthix cloak", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10448", - "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "391000", - "durability": null, - "name": "Guthix cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10449" - }, - { - "requirements": "{5,40}", - "ge_buy_limit": "2", - "examine": "A Zamorak cloak.", - "grand_exchange_price": "1000000", - "durability": null, - "name": "Zamorak cloak", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10450", - "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", - "equipment_slot": "1" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1000000", - "durability": null, - "name": "Zamorak cloak", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10451" - }, - { - "remove_head": "true", - "requirements": "{5,40}-{6,40}", - "ge_buy_limit": "2", - "examine": "A Saradomin mitre.", - "grand_exchange_price": "299200", - "durability": null, - "name": "Saradomin mitre", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10452", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "299200", - "durability": null, - "name": "Saradomin mitre", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10453" - }, - { - "remove_head": "true", - "requirements": "{5,40}-{6,40}", - "ge_buy_limit": "2", - "examine": "A Guthix mitre.", - "grand_exchange_price": "130300", - "durability": null, - "name": "Guthix mitre", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10454", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "130300", - "durability": null, - "name": "Guthix mitre", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10455" - }, - { - "remove_head": "true", - "requirements": "{5,40}-{6,40}", - "ge_buy_limit": "2", - "examine": "A Zamorak mitre.", - "durability": null, - "weight": "0.3", "equipment_slot": "0", - "grand_exchange_price": "346500", - "name": "Zamorak mitre", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", "tradeable": "true", + "weight": "2" + }, + { + "id": "10393", + "name": "A powdered wig", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10394", + "name": "Flared trousers", + "examine": "These'll help me stay alive.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10395", + "name": "Flared trousers", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10396", + "name": "Pantaloons", + "examine": "Alas, someone has slashed my pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10397", + "name": "Pantaloons", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10398", + "name": "Sleeping cap", + "examine": "A cap for wearing whil...zzzzzzzzz", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10399", + "name": "Sleeping cap", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10400", + "name": "Black ele' shirt", + "examine": "A well made elegant mans' black shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10401", + "name": "Black ele' shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10402", + "name": "Black ele' legs", + "examine": "A rather elegant black pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10403", + "name": "Black ele' legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10404", + "name": "Red ele' shirt", + "examine": "A well made elegant men's red shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10405", + "name": "Red ele' shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10406", + "name": "Red ele' legs", + "examine": "A rather elegant red pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10407", + "name": "Red ele' legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10408", + "name": "Blue ele' shirt", + "examine": "A well made elegant mans' blue shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10409", + "name": "Blue ele' shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10410", + "name": "Blue ele' legs", + "examine": "A rather elegant pair of men's blue pantaloons", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10411", + "name": "Blue ele' legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10412", + "name": "Green ele' shirt", + "examine": "A well made elegant men's green shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10413", + "name": "Green ele' shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10414", + "name": "Green ele' legs", + "examine": "A rather elegant green pair of men's pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10415", + "name": "Green ele' legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10416", + "name": "Purple ele' shirt", + "examine": "A well made elegant men's purple shirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10417", + "name": "Purple ele' shirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10418", + "name": "Purple ele' legs", + "examine": "A rather elegant purple pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10419", + "name": "Purple ele' legs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10420", + "name": "White ele' blouse", + "examine": "A well made ladies' elegant white blouse.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10421", + "name": "White ele' blouse", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10422", + "name": "White ele' skirt", + "examine": "A rather elegant white skirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10423", + "name": "White ele' skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10424", + "name": "Red ele' blouse", + "examine": "A well made elegant ladies' red blouse.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10425", + "name": "Red ele' blouse", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10426", + "name": "Red ele' skirt", + "examine": "A rather elegant Red skirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10427", + "name": "Red ele' skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10428", + "name": "Blue ele' blouse", + "examine": "A well made ladies' elegant blue blouse.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10429", + "name": "Blue ele' blouse", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10430", + "name": "Blue ele' skirt", + "examine": "A rather elegant blue skirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10431", + "name": "Blue ele' skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10432", + "name": "Green ele' blouse", + "examine": "A well made ladies' elegant green blouse.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10433", + "name": "Green ele' blouse", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10434", + "name": "Green ele' skirt", + "examine": "A rather elegant green skirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10435", + "name": "Green ele' skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10436", + "name": "Purple ele' blouse", + "examine": "A well made elegant ladies' purple blouse.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10437", + "name": "Purple ele' blouse", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10438", + "name": "Purple ele' skirt", + "examine": "A rather elegant purple skirt.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10439", + "name": "Purple ele' skirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10440", + "name": "Saradomin crozier", + "examine": "A Saradomin crozier.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", + "defence_anim": "420", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "render_anim": "28", + "requirements": "{5,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "10441", + "name": "Saradomin crozier", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10442", + "name": "Guthix crozier", + "examine": "A Guthix crozier.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", + "defence_anim": "420", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "render_anim": "28", + "requirements": "{5,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "10443", + "name": "Guthix crozier", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10444", + "name": "Zamorak crozier", + "examine": "A Zamorak crozier.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", + "defence_anim": "420", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "render_anim": "28", + "requirements": "{5,60}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "10445", + "name": "Zamorak crozier", + "archery_ticket_price": "0", + "attack_anims": "", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10446", + "name": "Saradomin cloak", + "examine": "A Saradomin cloak.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "2", + "requirements": "{5,40}", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10447", + "name": "Saradomin cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10448", + "name": "Guthix cloak", + "examine": "A Guthix cloak.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "2", + "requirements": "{5,40}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10449", + "name": "Guthix cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10450", + "name": "Zamorak cloak", + "examine": "A Zamorak cloak.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "2", + "requirements": "{5,40}", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10451", + "name": "Zamorak cloak", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10452", + "name": "Saradomin mitre", + "examine": "A Saradomin mitre.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{5,40}-{6,40}", + "tradeable": "true" + }, + { + "id": "10453", + "name": "Saradomin mitre", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10454", + "name": "Guthix mitre", + "examine": "A Guthix mitre.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{5,40}-{6,40}", + "tradeable": "true" + }, + { + "id": "10455", + "name": "Guthix mitre", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10456", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "346500", - "durability": null, "name": "Zamorak mitre", - "tradeable": "true", + "examine": "A Zamorak mitre.", "archery_ticket_price": "0", - "id": "10457" + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{5,40}-{6,40}", + "tradeable": "true", + "weight": "0.3" }, { - "requirements": "{5,20}", - "remove_sleeves": "true", - "ge_buy_limit": "2", - "examine": "Blessed vestments of Saradomin.", - "grand_exchange_price": "121400", - "durability": null, - "name": "Saradomin robe top", - "tradeable": "true", + "id": "10457", + "name": "Zamorak mitre", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10458", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", - "equipment_slot": "4" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "121400", - "durability": null, "name": "Saradomin robe top", - "tradeable": "true", + "examine": "Blessed vestments of Saradomin.", "archery_ticket_price": "0", - "id": "10459" + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{5,20}", + "tradeable": "true" }, { - "requirements": "{5,20}", - "ge_buy_limit": "2", - "examine": "Zamorak Vestments.", - "durability": null, - "weight": "1", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "154700", - "name": "Zamorak robe top", - "tradeable": "true", + "id": "10459", + "name": "Saradomin robe top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10460", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "154700", - "durability": null, "name": "Zamorak robe top", - "tradeable": "true", + "examine": "Zamorak Vestments.", "archery_ticket_price": "0", - "id": "10461" - }, - { - "requirements": "{5,20}", - "ge_buy_limit": "2", - "examine": "Blessed vestments of Guthix.", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", "durability": null, - "weight": "1", "equipment_slot": "4", + "ge_buy_limit": "2", "remove_sleeves": "true", - "grand_exchange_price": "75200", - "name": "Guthix robe top", + "requirements": "{5,20}", "tradeable": "true", + "weight": "1" + }, + { + "id": "10461", + "name": "Zamorak robe top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10462", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "75200", - "durability": null, "name": "Guthix robe top", - "tradeable": "true", + "examine": "Blessed vestments of Guthix.", "archery_ticket_price": "0", - "id": "10463" + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{5,20}", + "tradeable": "true", + "weight": "1" }, { - "requirements": "{5,20}", - "ge_buy_limit": "2", - "examine": "Leggings from the Saradomin Vestments.", - "grand_exchange_price": "56300", - "durability": null, - "name": "Saradomin robe legs", - "tradeable": "true", + "id": "10463", + "name": "Guthix robe top", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10464", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "56300", - "durability": null, "name": "Saradomin robe legs", - "tradeable": "true", + "examine": "Leggings from the Saradomin Vestments.", "archery_ticket_price": "0", - "id": "10465" + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{5,20}", + "tradeable": "true" }, { - "requirements": "{5,20}", - "ge_buy_limit": "2", - "examine": "Leggings from the Guthix Vestments.", - "grand_exchange_price": "56900", - "durability": null, - "name": "Guthix robe legs", - "tradeable": "true", - "weight": "2", + "id": "10465", + "name": "Saradomin robe legs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10466", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "56900", - "durability": null, "name": "Guthix robe legs", - "tradeable": "true", + "examine": "Leggings from the Guthix Vestments.", "archery_ticket_price": "0", - "id": "10467" - }, - { - "requirements": "{5,20}", - "ge_buy_limit": "2", - "examine": "Legs of the Zamorak Vestments.", - "grand_exchange_price": "79400", - "durability": null, - "name": "Zamorak robe legs", - "tradeable": "true", - "weight": "2.7", - "archery_ticket_price": "0", - "id": "10468", "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{5,20}", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "79400", + "id": "10467", + "name": "Guthix robe legs", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10468", "name": "Zamorak robe legs", - "tradeable": "true", + "examine": "Legs of the Zamorak Vestments.", "archery_ticket_price": "0", - "id": "10469" + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "2", + "requirements": "{5,20}", + "tradeable": "true", + "weight": "2.7" }, { - "requirements": "{5,60}", - "ge_buy_limit": "2", - "examine": "A Saradomin stole.", - "grand_exchange_price": "14000", - "durability": null, - "name": "Saradomin stole", - "tradeable": "true", + "id": "10469", + "name": "Zamorak robe legs", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10470", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "14000", - "durability": null, "name": "Saradomin stole", - "tradeable": "true", + "examine": "A Saradomin stole.", "archery_ticket_price": "0", - "id": "10471" + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "2", + "requirements": "{5,60}", + "tradeable": "true" }, { - "requirements": "{5,60}", - "ge_buy_limit": "2", - "examine": "A blessed stole.", - "grand_exchange_price": "3849", - "durability": null, - "name": "Guthix stole", - "tradeable": "true", + "id": "10471", + "name": "Saradomin stole", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { "id": "10472", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "3849", - "durability": null, "name": "Guthix stole", - "tradeable": "true", + "examine": "A blessed stole.", "archery_ticket_price": "0", - "id": "10473" - }, - { - "requirements": "{5,60}", - "ge_buy_limit": "2", - "examine": "A Zamorak stole.", - "grand_exchange_price": "13700", - "durability": null, - "name": "Zamorak stole", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10474", "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", - "equipment_slot": "2" - }, - { + "durability": null, + "equipment_slot": "2", "ge_buy_limit": "2", - "grand_exchange_price": "13700", + "requirements": "{5,60}", + "tradeable": "true" + }, + { + "id": "10473", + "name": "Guthix stole", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10474", "name": "Zamorak stole", - "tradeable": "true", + "examine": "A Zamorak stole.", "archery_ticket_price": "0", - "id": "10475" + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "2", + "requirements": "{5,60}", + "tradeable": "true" }, { - "ge_buy_limit": "1000", - "examine": "Remember to brush after eating!", - "grand_exchange_price": "22700", + "id": "10475", + "name": "Zamorak stole", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "10476", "name": "Purple sweets", - "tradeable": "true", + "examine": "Remember to brush after eating!", "archery_ticket_price": "0", - "id": "10476" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "durability": null, + "id": "10485", "name": "Scroll", "archery_ticket_price": "0", - "id": "10485", + "durability": null, "equipment_slot": "3" }, { - "shop_price": "1", - "examine": "An empty sack.", - "grand_exchange_price": "30", - "durability": null, + "id": "10486", "name": "Empty sack", - "tradeable": "true", - "weight": "0.4", + "examine": "An empty sack.", "archery_ticket_price": "0", - "id": "10486" + "durability": null, + "shop_price": "1", + "tradeable": "true", + "weight": "0.4" }, { - "turn90cw_anim": "821", - "examine": "Yup, definitely a chicken...an undead chicken.", - "walk_anim": "5364", - "durability": null, - "turn90ccw_anim": "822", - "weapon_interface": "12", - "turn180_anim": "5438", - "equip_audio": "3277", - "render_anim": "1171", - "equipment_slot": "3", - "stand_anim": "5363", - "name": "Undead chicken", - "run_anim": "824", - "archery_ticket_price": "0", "id": "10487", - "stand_turn_anim": "823", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "destroy_message": "The Witch in Draynor supplies these bars.", - "examine": "An iron bar supplied by an insane old crone.", - "durability": null, - "name": "Selected iron", - "tradeable": "false", - "destroy": "true", + "name": "Undead chicken", + "examine": "Yup, definitely a chicken...an undead chicken.", "archery_ticket_price": "0", - "id": "10488", - "equipment_slot": "3" - }, - { - "destroy_message": "I can make another magnet using special bars. The Witch in Draynor supplies these bars.", - "examine": "A magnet designed for undead chicken use.", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", "durability": null, - "name": "Bar magnet", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10489" - }, - { - "destroy_message": "I can chop more wood from undead trees using my blessed axe.", - "examine": "Were they trying to escape just then?", - "durability": null, - "name": "Undead twigs", - "tradeable": "false", - "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10490" - }, - { - "examine": "It radiates purity but can still lop off heads.", - "durability": null, - "destroy": "true", - "weight": "1.1", - "attack_speed": "5", - "weapon_interface": "2", - "render_anim": "2586", + "equip_audio": "3277", "equipment_slot": "3", - "destroy_message": "I can obtain a replacement axe from the Burthorpe Slayer Master.", - "name": "Blessed axe", - "tradeable": "false", + "render_anim": "1171", + "run_anim": "824", + "stand_anim": "5363", + "stand_turn_anim": "823", + "turn180_anim": "5438", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "5364", + "weapon_interface": "12" + }, + { + "id": "10488", + "name": "Selected iron", + "examine": "An iron bar supplied by an insane old crone.", "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "The Witch in Draynor supplies these bars.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "10489", + "name": "Bar magnet", + "examine": "A magnet designed for undead chicken use.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can make another magnet using special bars. The Witch in Draynor supplies these bars.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10490", + "name": "Undead twigs", + "examine": "Were they trying to escape just then?", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can chop more wood from undead trees using my blessed axe.", + "durability": null, + "tradeable": "false", + "weight": "0.4" + }, + { "id": "10491", - "bonuses": "-2,12,10,0,0,0,1,0,0,0,0,13,2,0,0" + "name": "Blessed axe", + "examine": "It radiates purity but can still lop off heads.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "5", + "bonuses": "-2,12,10,0,0,0,1,0,0,0,0,13,2,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "I can obtain a replacement axe from the Burthorpe Slayer Master.", + "durability": null, + "equip_audio": "2229", + "equipment_slot": "3", + "render_anim": "2586", + "tradeable": "false", + "weapon_interface": "2", + "weight": "1.1" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "These make no sense at all.", - "durability": null, + "id": "10492", "name": "Research notes", - "tradeable": "false", - "destroy": "true", + "examine": "These make no sense at all.", "archery_ticket_price": "0", - "id": "10492" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "They still make no sense, but look more meaningful now.", - "durability": null, + "id": "10493", "name": "Translated notes", - "tradeable": "false", - "destroy": "true", + "examine": "They still make no sense, but look more meaningful now.", "archery_ticket_price": "0", - "id": "10493" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Attach tab A to button B then fold along line C...", - "durability": null, + "id": "10494", "name": "A pattern", + "examine": "Attach tab A to button B then fold along line C...", "archery_ticket_price": "0", - "id": "10494" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A desirable residence for discerning, undead chickens.", - "durability": null, + "id": "10495", "name": "A container", - "tradeable": "false", - "destroy": "true", + "examine": "A desirable residence for discerning, undead chickens.", "archery_ticket_price": "0", - "id": "10495" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "examine": "Shiny!", - "durability": null, + "id": "10496", "name": "Polished buttons", - "tradeable": "true", + "examine": "Shiny!", "archery_ticket_price": "0", - "id": "10496" + "durability": null, + "tradeable": "true" }, { - "shop_price": "999", - "examine": "A bagged chicken ready to serve you, magnet in claw.", - "durability": null, - "destroy": "true", - "weight": "4.5", - "equip_audio": "3284", - "equipment_slot": "1", - "destroy_message": "I can buy a replacement from Ava in Draynor Manor; she will charge me 999 coins for this service.", - "name": "Ava's attractor", - "tradeable": "false", - "archery_ticket_price": "0", "id": "10498", - "bonuses": "0,0,0,0,2,0,0,0,2,0,0,0,0,0,0" - }, - { - "shop_price": "999", - "examine": "A superior bagged chicken ready to serve you, magnet in claw.", - "durability": null, + "name": "Ava's attractor", + "examine": "A bagged chicken ready to serve you, magnet in claw.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,2,0,0,0,2,0,0,0,0,0,0", "destroy": "true", - "weight": "4.5", + "destroy_message": "I can buy a replacement from Ava in Draynor Manor; she will charge me 999 coins for this service.", + "durability": null, "equip_audio": "3284", "equipment_slot": "1", - "destroy_message": "I can obtain a replacement for this from Ava in Draynor Manor. She will need 999 coins to buy the lower", - "name": "Ava's accumulator", + "shop_price": "999", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4.5" + }, + { "id": "10499", - "bonuses": "0,0,0,0,4,0,1,0,4,0,0,0,0,0,0" + "name": "Ava's accumulator", + "examine": "A superior bagged chicken ready to serve you, magnet in claw.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,4,0,1,0,4,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "I can obtain a replacement for this from Ava in Draynor Manor. She will need 999 coins to buy the lower", + "durability": null, + "equip_audio": "3284", + "equipment_slot": "1", + "shop_price": "999", + "tradeable": "false", + "weight": "4.5" }, { - "destroy_message": "I can obtain a replacement for this from the crone who lives west of the Port Phasmatys farm.", - "examine": "Allows the ghost farmer to talk to Alice - a breakthrough!", - "durability": null, - "name": "Crone-made amulet", - "tradeable": "false", - "destroy": "true", - "weight": "5", - "archery_ticket_price": "0", "id": "10500", - "equipment_slot": "2" + "name": "Crone-made amulet", + "examine": "Allows the ghost farmer to talk to Alice - a breakthrough!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can obtain a replacement for this from the crone who lives west of the Port Phasmatys farm.", + "durability": null, + "equipment_slot": "2", + "tradeable": "false", + "weight": "5" }, { - "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", - "durability": null, - "name": "Snowball", - "archery_ticket_price": "0", "id": "10501", - "weapon_interface": "18", - "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,1", - "equipment_slot": "3" - }, - { - "examine": "A gublinch frozen and crumbled into shards.", - "durability": null, - "name": "Gublinch shards", - "tradeable": "false", - "destroy": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "10506" - }, - { - "remove_head": "true", - "destroy_message": "You can reclaim this item from the place you found it. this item", - "examine": "A reindeer hat and a matching flashing nose.", - "durability": null, - "name": "Reindeer hat", - "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10507", - "equipment_slot": "0" - }, - { - "destroy_message": "You can get another from Diango in Draynor Village.", - "examine": "A wintumber tree for your player-owned house.", - "durability": null, - "name": "Wintumber tree", - "tradeable": "false", - "destroy": "true", - "weight": "10", - "archery_ticket_price": "0", - "id": "10508" - }, - { + "name": "Snowball", "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", - "durability": null, - "name": "Snowball", - "tradeable": "false", "archery_ticket_price": "0", - "id": "10509" + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,1", + "durability": null, + "equipment_slot": "3", + "weapon_interface": "18" }, { - "durability": null, - "name": "Snowball", - "tradeable": "false", + "id": "10506", + "name": "Gublinch shards", + "examine": "A gublinch frozen and crumbled into shards.", "archery_ticket_price": "0", - "id": "10510" + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "10" }, { - "examine": "They're going to sing to you!", + "id": "10507", + "name": "Reindeer hat", + "examine": "A reindeer hat and a matching flashing nose.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it. this item", "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false", + "weight": "2" + }, + { + "id": "10508", + "name": "Wintumber tree", + "examine": "A wintumber tree for your player-owned house.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "tradeable": "false", + "weight": "10" + }, + { + "id": "10509", + "name": "Snowball", + "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "10510", + "name": "Snowball", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "false" + }, + { + "id": "10511", "name": "Zanaris choir", + "examine": "They're going to sing to you!", "archery_ticket_price": "0", - "id": "10511" + "durability": null }, { - "destroy_message": "Unknown You can reclaim this item from the place you found it.", - "examine": "Some dry crackers.", - "durability": null, + "id": "10513", "name": "Crackers", - "tradeable": "false", - "destroy": "true", + "examine": "Some dry crackers.", "archery_ticket_price": "0", - "id": "10513" + "destroy": "true", + "destroy_message": "Unknown You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A block of tofu.", - "durability": null, + "id": "10514", "name": "Tofu", + "examine": "A block of tofu.", "archery_ticket_price": "0", - "id": "10514" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some meaty worms.", - "durability": null, + "id": "10515", "name": "Worms", - "tradeable": "false", + "examine": "Some meaty worms.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "10515" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Attacker horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10516" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Attacker horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10517" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Attacker horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10518" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Attacker horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10519" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Attacker horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10520" - }, - { - "examine": "A very small/small/medium-sized/large/very large collection bag.", - "durability": null, - "name": "Collection bag", - "archery_ticket_price": "0", - "id": "10521" - }, - { - "examine": "A very small/small/medium-sized/large/very large collection bag.", - "durability": null, - "name": "Collection bag", - "archery_ticket_price": "0", - "id": "10522" - }, - { - "examine": "A very small/small/medium-sized/large/very large collection bag.", - "durability": null, - "name": "Collection bag", - "archery_ticket_price": "0", - "id": "10523" - }, - { - "examine": "A very small/small/medium-sized/large/very large collection bag.", - "durability": null, - "name": "Collection bag", - "archery_ticket_price": "0", - "id": "10524" - }, - { - "examine": "A very small/small/medium-sized/large/very large collection bag.", - "durability": null, - "name": "Collection bag", - "archery_ticket_price": "0", - "id": "10525" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Healer horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10526" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Healer horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10527" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Healer horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10528" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Healer horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10529" - }, - { - "examine": "A horn to call others.", - "durability": null, - "name": "Healer horn", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10530" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Used to poison your enemies!", "durability": null, + "tradeable": "false" + }, + { + "id": "10516", + "name": "Attacker horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10517", + "name": "Attacker horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10518", + "name": "Attacker horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10519", + "name": "Attacker horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10520", + "name": "Attacker horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10521", + "name": "Collection bag", + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10522", + "name": "Collection bag", + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10523", + "name": "Collection bag", + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10524", + "name": "Collection bag", + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10525", + "name": "Collection bag", + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10526", + "name": "Healer horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10527", + "name": "Healer horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10528", + "name": "Healer horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10529", + "name": "Healer horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10530", + "name": "Healer horn", + "examine": "A horn to call others.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10531", "name": "Green egg", + "examine": "Used to poison your enemies!", "archery_ticket_price": "0", - "id": "10531" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Will explode when fired.", - "durability": null, + "id": "10532", "name": "Red egg", + "examine": "Will explode when fired.", "archery_ticket_price": "0", - "id": "10532" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Stun your foes!", - "durability": null, + "id": "10533", "name": "Blue egg", + "examine": "Stun your foes!", "archery_ticket_price": "0", - "id": "10533" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "examine": "A yellow egg; it needs passing to the Healer to be poisoned!", - "durability": null, + "id": "10534", "name": "Yellow egg", + "examine": "A yellow egg; it needs passing to the Healer to be poisoned!", "archery_ticket_price": "0", - "id": "10534" + "durability": null }, { - "examine": "A poisoned yellow egg; pass it to the Attacker for spikes to be added!", - "durability": null, + "id": "10535", "name": "Poisoned egg", - "tradeable": "false", - "destroy": "true", + "examine": "A poisoned yellow egg; pass it to the Attacker for spikes to be added!", "archery_ticket_price": "0", - "id": "10535" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A poisoned, spiky egg; pass to the defender for heating!", - "durability": null, + "id": "10536", "name": "Spiked/pois. egg", - "tradeable": "false", - "destroy": "true", + "examine": "A poisoned, spiky egg; pass to the defender for heating!", "archery_ticket_price": "0", - "id": "10536" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A heated, poisoned, spiky egg; pass to the Collector for loading.", - "durability": null, + "id": "10537", "name": "Omega egg", - "tradeable": "false", - "destroy": "true", + "examine": "A heated, poisoned, spiky egg; pass to the Collector for loading.", "archery_ticket_price": "0", - "id": "10537" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A horn to call others.", - "durability": null, + "id": "10538", "name": "Defender horn", - "tradeable": "false", - "destroy": "true", + "examine": "A horn to call others.", "archery_ticket_price": "0", - "id": "10538" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some poisoned tofu.", - "durability": null, + "id": "10539", "name": "Poisoned tofu", - "tradeable": "false", - "destroy": "true", + "examine": "Some poisoned tofu.", "archery_ticket_price": "0", - "id": "10539" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some poisoned worms.", - "durability": null, + "id": "10540", "name": "Poisoned worms", - "tradeable": "false", - "destroy": "true", + "examine": "Some poisoned worms.", "archery_ticket_price": "0", - "id": "10540" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A poisoned leg of meat.", - "durability": null, + "id": "10541", "name": "Poisoned meat", - "tradeable": "false", - "destroy": "true", + "examine": "A poisoned leg of meat.", "archery_ticket_price": "0", - "id": "10541" - }, - { + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "tradeable": "false" + }, + { + "id": "10542", "name": "Healing vial(4)", "archery_ticket_price": "0", - "id": "10542" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "durability": null, + "id": "10543", "name": "Healing vial(3)", "archery_ticket_price": "0", - "id": "10543" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "durability": null, + "id": "10544", "name": "Healing vial(2)", "archery_ticket_price": "0", - "id": "10544" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "durability": null, + "id": "10545", "name": "Healing vial(1)", "archery_ticket_price": "0", - "id": "10545" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A full healing vial.", - "durability": null, + "durability": null + }, + { + "id": "10546", "name": "Healing vial", - "tradeable": "false", - "destroy": "true", + "examine": "A full healing vial.", "archery_ticket_price": "0", - "id": "10546" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "remove_head": "true", - "requirements": "{1,40}", - "shop_price": "275", - "examine": "A Penance Healer hat.", - "durability": null, - "name": "Healer hat", - "weight": "2", - "archery_ticket_price": "0", "id": "10547", + "name": "Healer hat", + "examine": "A Penance Healer hat.", "absorb": "3,1,0", + "archery_ticket_price": "0", "bonuses": "-5,-5,-5,7,-5,6,8,10,8,0,7,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}", "shop_price": "275", - "examine": "A Penance Fighter hat.", - "durability": null, - "name": "Fighter hat", - "weight": "2", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "10548", + "name": "Fighter hat", + "examine": "A Penance Fighter hat.", "absorb": "1,0,3", + "archery_ticket_price": "0", "bonuses": "5,5,5,-7,-7,30,32,28,-3,28,7,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", "requirements": "{1,40}", "shop_price": "275", - "examine": "A Penance Runner hat.", - "durability": null, - "name": "Runner hat", - "weight": "1", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "10549", + "name": "Runner hat", + "examine": "A Penance Runner hat.", "absorb": "1,0,3", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,30,32,27,1,30,7,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equipment_slot": "0", "requirements": "{1,40}", "shop_price": "275", - "examine": "A Penance ranger hat.", - "durability": null, - "name": "Ranger hat", - "weight": "2", - "archery_ticket_price": "0", - "id": "10550", - "absorb": "0,3,1", - "bonuses": "-5,-5,-5,-5,7,7,10,11,5,9,7,0,0,0,0", - "equipment_slot": "0" + "weight": "1" }, { - "requirements": "{1,40}", - "shop_price": "375", - "examine": "Penance Fighter torso armour.", + "id": "10550", + "name": "Ranger hat", + "examine": "A Penance ranger hat.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,7,7,10,11,5,9,7,0,0,0,0", "durability": null, - "destroy": "true", - "weight": "4", + "equipment_slot": "0", + "requirements": "{1,40}", + "shop_price": "275", + "weight": "2" + }, + { + "id": "10551", + "name": "Fighter torso", + "examine": "Penance Fighter torso armour.", "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,0,66,85,62,-6,67,40,4,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "remove_sleeves": "true", - "name": "Fighter torso", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10551", - "bonuses": "0,0,0,-30,0,66,85,62,-6,67,40,4,0,0,0" - }, - { - "requirements": "{1,40}", - "shop_price": "100", - "examine": "Boots made from a Penance Runner.", - "durability": null, - "name": "Runner boots", - "archery_ticket_price": "0", - "id": "10552", - "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0", - "equipment_slot": "10" - }, - { - "requirements": "{1,40}", - "shop_price": "150", - "examine": "These gloves seem unbelievably light!", - "durability": null, - "name": "Penance gloves", - "weight": "-7", - "archery_ticket_price": "0", - "id": "10553", - "bonuses": "0,0,0,0,0,0,3,4,0,2,2,4,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,40}", - "shop_price": "150", - "examine": "These gloves seem unbelievably light!", - "durability": null, - "name": "Penance gloves", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "10554", - "bonuses": "0,0,0,0,0,0,3,4,0,2,2,4,0,0,0", - "equipment_slot": "9" - }, - { "requirements": "{1,40}", "shop_price": "375", - "examine": "A skirt made from the skin of a Penance Ranger.", - "durability": null, - "name": "Penance skirt", - "weight": "3", + "tradeable": "false", + "weight": "4" + }, + { + "id": "10552", + "name": "Runner boots", + "examine": "Boots made from a Penance Runner.", "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0", + "durability": null, + "equipment_slot": "10", + "requirements": "{1,40}", + "shop_price": "100" + }, + { + "id": "10553", + "name": "Penance gloves", + "examine": "These gloves seem unbelievably light!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,3,4,0,2,2,4,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,40}", + "shop_price": "150", + "weight": "-7" + }, + { + "id": "10554", + "name": "Penance gloves", + "examine": "These gloves seem unbelievably light!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,3,4,0,2,2,4,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,40}", + "shop_price": "150", + "weight": "0.3" + }, + { "id": "10555", + "name": "Penance skirt", + "examine": "A skirt made from the skin of a Penance Ranger.", "absorb": "0,4,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-10,16,26,21,28,19,27,15,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "7", + "requirements": "{1,40}", + "shop_price": "375", + "weight": "3" }, { - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", "id": "10556", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "1" }, { - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", "id": "10557", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "1" }, { - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", "id": "10558", - "equipment_slot": "1" - }, - { - "durability": null, "name": "Picture", "archery_ticket_price": "0", - "id": "10559", + "durability": null, "equipment_slot": "1" }, { - "examine": "A horn for communication with your team members.", + "id": "10559", + "name": "Picture", + "archery_ticket_price": "0", "durability": null, + "equipment_slot": "1" + }, + { + "id": "10560", "name": "Collector horn", - "tradeable": "false", - "destroy": "true", + "examine": "A horn for communication with your team members.", "archery_ticket_price": "0", - "id": "10560" - }, - { - "destroy_message": "You will have to ask Captain Cain for another.", - "shop_price": "160", - "examine": "A book about the Barbarian Assault Queen.", + "destroy": "true", "durability": null, - "name": "Queen help book", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10562" + "tradeable": "false" }, { + "id": "10562", + "name": "Queen help book", + "examine": "A book about the Barbarian Assault Queen.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will have to ask Captain Cain for another.", + "durability": null, + "shop_price": "160", + "tradeable": "false" + }, + { + "id": "10564", + "name": "Granite body", + "examine": "Provides excellent protection.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-22,-5,87,84,79,-6,97,45,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "10", + "lendable": "true", + "remove_sleeves": "true", "requirements": "{1,50}-{2,50}", "shop_price": "95000", - "ge_buy_limit": "10", - "examine": "Provides excellent protection.", - "durability": null, - "weight": "22.6", - "absorb": "4,0,8", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "126800", - "name": "Granite body", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10564", - "bonuses": "0,0,0,-22,-5,87,84,79,-6,97,45,0,0,0,0" + "weight": "22.6" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "126800", - "durability": null, + "id": "10565", "name": "Granite body", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10565" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "examine": "A cape of fire.", - "durability": null, - "name": "Fire cape", - "tradeable": "false", - "weight": "1.8", - "archery_ticket_price": "0", "id": "10566", + "name": "Fire cape", + "examine": "A cape of fire.", + "archery_ticket_price": "0", "bonuses": "1,1,1,1,1,11,11,11,11,11,11,4,2,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "1.8" }, { - "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "10567", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10568" - }, - { "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "10568", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "10569", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10570" - }, - { "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "10570", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "10571", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10572" - }, - { "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "10572", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "10573", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10574" - }, - { "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "10574", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "10575", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10576" - }, - { "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "10576", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "10577", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10578" - }, - { "examine": "Mabob.", - "grand_exchange_price": "2", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "10578", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "10579", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Picture", - "tradeable": "true", + "examine": "Mabob.", "archery_ticket_price": "0", - "id": "10580" - }, - { - "examine": "(Normal) A mystical-feeling dagger. (Poisoned) The twisted blade is covered with a nasty poison.", - "durability": null, "destroy": "true", - "weight": "0.4", - "attack_speed": "4", - "weapon_interface": "5", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3", - "attack_anims": "376,376,377,376", - "destroy_message": "You can obtain another from Osman. You will then need to poison it.", - "name": "Keris", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "10581", - "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0" + "durability": null, + "equipment_slot": "2", + "tradeable": "false" }, { + "id": "10580", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "10581", + "name": "Keris", + "examine": "(Normal) A mystical-feeling dagger. (Poisoned) The twisted blade is covered with a nasty poison.", + "archery_ticket_price": "0", "attack_anims": "376,376,377,376", + "attack_speed": "4", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", + "defence_anim": "378", + "destroy": "true", "destroy_message": "You can obtain another from Osman. You will then need to poison it.", "durability": null, + "equipment_slot": "3", + "render_anim": "2584", + "tradeable": "false", + "weapon_interface": "5", + "weight": "0.4" + }, + { + "id": "10582", "name": "Keris(p)", "archery_ticket_price": "0", - "id": "10582", - "weapon_interface": "5", - "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3" - }, - { "attack_anims": "376,376,377,376", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", + "defence_anim": "378", "destroy_message": "You can obtain another from Osman. You will then need to poison it.", "durability": null, + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "10583", "name": "Keris(p+)", "archery_ticket_price": "0", - "id": "10583", - "weapon_interface": "5", - "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", - "render_anim": "2584", - "defence_anim": "378", - "equipment_slot": "3" - }, - { "attack_anims": "376,376,377,376", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", + "defence_anim": "378", "destroy_message": "You can obtain another from Osman. You will then need to poison it.", "durability": null, + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" + }, + { + "id": "10584", "name": "Keris(p++)", "archery_ticket_price": "0", - "id": "10584", - "weapon_interface": "5", + "attack_anims": "376,376,377,376", "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", - "render_anim": "2584", "defence_anim": "378", - "equipment_slot": "3" + "destroy_message": "You can obtain another from Osman. You will then need to poison it.", + "durability": null, + "equipment_slot": "3", + "render_anim": "2584", + "weapon_interface": "5" }, { - "destroy_message": "You can obtain a replacement lamp from the high priest in Sophanem.", - "examine": "A mystical lamp, engraved with scenes of carnage.", - "durability": null, + "id": "10586", "name": "Combat lamp", - "tradeable": "false", - "destroy": "true", + "examine": "A mystical lamp, engraved with scenes of carnage.", "archery_ticket_price": "0", - "id": "10586" + "destroy": "true", + "destroy_message": "You can obtain a replacement lamp from the high priest in Sophanem.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I got this diary in Tarn's Lair, perhaps I can get another one there.", - "examine": "Tarn Razorlor's diary.", - "durability": null, + "id": "10587", "name": "Tarn's diary", - "tradeable": "false", + "examine": "Tarn Razorlor's diary.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "10587" - }, - { - "examine": "Increases the wearer's Strength and Attack by 20% when fighting the undead.", + "destroy_message": "I got this diary in Tarn's Lair, perhaps I can get another one there.", "durability": null, - "name": "Salve amulet(e)", - "weight": "1", - "archery_ticket_price": "0", - "id": "10588", - "bonuses": "0,0,0,0,0,3,3,3,0,0,3,0,3,0,0", - "equipment_slot": "2" + "tradeable": "false" }, { + "id": "10588", + "name": "Salve amulet(e)", + "examine": "Increases the wearer's Strength and Attack by 20% when fighting the undead.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,3,3,3,0,0,3,0,3,0,0", + "durability": null, + "equipment_slot": "2", + "weight": "1" + }, + { + "id": "10589", + "name": "Granite helm", + "examine": "A stone helmet.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-9,-7,31,33,29,-1,39,9,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "lendable": "true", "remove_head": "true", "requirements": "{1,50}-{2,50}", - "ge_buy_limit": "10", - "examine": "A stone helmet.", - "durability": null, - "weight": "4", - "absorb": "2,0,4", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "28000", - "name": "Granite helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10589", - "bonuses": "0,0,0,-9,-7,31,33,29,-1,39,9,0,0,0,0" + "weight": "4" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "28000", - "durability": null, + "id": "10590", "name": "Granite helm", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10590" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "examine": "A terrifying dog beast.", - "durability": null, + "id": "10591", "name": "Terror dog", + "examine": "A terrifying dog beast.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "10591" + "durability": null }, { - "destroy_message": "You can make another with tanned leather and a mahogany plank.", - "examine": "Small drums.", - "durability": null, + "id": "10592", "name": "Penguin bongos", - "tradeable": "false", - "destroy": "true", + "examine": "Small drums.", "archery_ticket_price": "0", - "id": "10592" + "destroy": "true", + "destroy_message": "You can make another with tanned leather and a mahogany plank.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Every song needs a cowbell.", - "durability": null, + "id": "10593", "name": "Cowbells", - "weight": "2", + "examine": "Every song needs a cowbell.", "archery_ticket_price": "0", - "id": "10593" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A book about clockwork mechanisms.", "durability": null, + "weight": "2" + }, + { + "id": "10594", "name": "Clockwork book", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A book about clockwork mechanisms.", "archery_ticket_price": "0", - "id": "10594" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "You'll have to make another one at your house. Speak to Larry to learn how to make one.", - "examine": "A clockwork penguin suit.", - "durability": null, + "id": "10595", "name": "Clockwork suit", - "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10595" - }, - { - "destroy_message": "You'll have to make another one at your house. Speak to Larry to learn how to make one.", "examine": "A clockwork penguin suit.", - "durability": null, - "name": "Clockwork suit", - "tradeable": "false", - "destroy": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "10596" + "destroy": "true", + "destroy_message": "You'll have to make another one at your house. Speak to Larry to learn how to make one.", + "durability": null, + "tradeable": "false", + "weight": "2" }, { - "destroy_message": "You will need to speak to Noodle to get another.", - "examine": "So you can be a penguin too!", + "id": "10596", + "name": "Clockwork suit", + "examine": "A clockwork penguin suit.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to make another one at your house. Speak to Larry to learn how to make one.", "durability": null, + "tradeable": "false", + "weight": "2" + }, + { + "id": "10600", "name": "Kgp id card", - "tradeable": "false", + "examine": "So you can be a penguin too!", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "10600" + "destroy_message": "You will need to speak to Noodle to get another.", + "durability": null, + "tradeable": "false" }, { - "shop_price": "15000", - "examine": "Blue: A magical hat. ", - "durability": null, - "weight": "0.4", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "1", - "name": "Mystic hat", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10601", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" - }, - { - "shop_price": "15000", + "name": "Mystic hat", "examine": "Blue: A magical hat. ", - "durability": null, - "weight": "0.4", "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "1", - "name": "Mystic hat", + "shop_price": "15000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "0.4" + }, + { "id": "10602", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" - }, - { - "shop_price": "15000", - "examine": "Blue: A magical hat. ", - "durability": null, - "weight": "0.4", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "1", "name": "Mystic hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10603", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "examine": "Make your foes cower by wearing a skull as a helmet!", - "durability": null, - "weight": "1.3", + "examine": "Blue: A magical hat. ", "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "25569", - "name": "Skeletal helm", + "shop_price": "15000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10604", - "bonuses": "0,0,0,2,-2,10,9,11,3,0,0,0,0,0,0" + "weight": "0.4" }, { - "remove_sleeves": "true", - "examine": "Mystical robes.", - "grand_exchange_price": "3932123", - "durability": null, - "name": "Infinity top", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "10605", + "id": "10603", + "name": "Mystic hat", + "examine": "Blue: A magical hat. ", "absorb": "3,1,0", - "bonuses": "0,0,0,22,0,0,0,0,22,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", "lendable": "true", - "examine": "A wooden helmet.", - "grand_exchange_price": "5623", - "durability": null, - "name": "Splitbark helm", + "shop_price": "15000", "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "10606", - "absorb": "3,1,0", - "bonuses": "0,0,0,3,-2,10,9,11,3,0,0,0,0,0,0", - "equipment_slot": "0" + "weight": "0.4" }, { - "examine": "They seem to be not quite of this world...", - "durability": null, - "name": "Ghostly boots", + "id": "10604", + "name": "Skeletal helm", + "examine": "Make your foes cower by wearing a skull as a helmet!", + "absorb": "3,1,0", "archery_ticket_price": "0", + "bonuses": "0,0,0,2,-2,10,9,11,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "10605", + "name": "Infinity top", + "examine": "Mystical robes.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,22,0,0,0,0,22,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "10606", + "name": "Splitbark helm", + "examine": "A wooden helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true", + "weight": "0.9" + }, + { "id": "10607", + "name": "Ghostly boots", + "examine": "They seem to be not quite of this world...", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "durability": null, "equipment_slot": "10" }, { - "shop_price": "1000", - "examine": "A mystical hat.", - "durability": null, - "name": "Moonclan hat", - "weight": "1", - "archery_ticket_price": "0", "id": "10608", + "name": "Moonclan hat", + "examine": "A mystical hat.", + "archery_ticket_price": "0", "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "shop_price": "1000", + "weight": "1" }, { + "id": "10609", + "name": "Lunar helm", + "examine": "A mystical helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "shop_price": "15000", - "examine": "A mystical helmet.", - "durability": null, - "destroy": "true", - "weight": "0.9", - "absorb": "3,1,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar helm", "tradeable": "false", - "archery_ticket_price": "0", - "id": "10609", - "bonuses": "0,0,0,3,-2,8,7,10,2,0,0,0,0,0,0" + "weight": "0.9" }, { - "remove_sleeves": "true", - "durability": null, + "id": "10610", "name": "Decorative armour", "archery_ticket_price": "0", - "id": "10610", "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { + "id": "10611", + "name": "Void knight top", + "examine": "Torso armour from the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,40,40,40,40,40,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", "shop_price": "250", - "examine": "Torso armour from the order of the Void Knights.", - "durability": null, - "name": "Void knight top", "tradeable": "false", - "weight": "6.5", - "archery_ticket_price": "0", - "id": "10611", - "bonuses": "0,0,0,0,0,40,40,40,40,40,0,0,0,0,0", - "equipment_slot": "4" + "weight": "6.5" }, { - "remove_head": "true", - "examine": "Black banded leather armour, a rogue's dream!", - "durability": null, - "name": "Rogue mask", - "weight": "0.5", - "archery_ticket_price": "0", "id": "10612", + "name": "Rogue mask", + "examine": "Black banded leather armour, a rogue's dream!", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,5,5,5,5,5,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "weight": "0.5" }, { - "remove_head": "true", - "requirements": "{1,40}", + "id": "10613", + "name": "Rock-shell helm", "examine": "Protective headwear made from crabs. Better than it sounds.", - "durability": null, - "weight": "2.7", "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "24661", - "name": "Rock-shell helm", + "remove_head": "true", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10613", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + "weight": "2.7" }, { + "id": "10614", + "name": "Spined helm", + "examine": "A helm fit for any Fremennik ranger.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "-6,-6,-6,-6,6,6,6,6,6,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,40}-{4,40}", - "examine": "A helm fit for any Fremennik ranger.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "35640", - "name": "Spined helm", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10614", - "bonuses": "-6,-6,-6,-6,6,6,6,6,6,0,0,0,0,0,0" + "weight": "1" }, { - "examine": "A ceremonial wooden mask.", - "grand_exchange_price": "1021", - "durability": null, - "name": "Tribal mask", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10615", - "equipment_slot": "0" + "name": "Tribal mask", + "examine": "A ceremonial wooden mask.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "2" }, { - "examine": "A ceremonial wooden mask.", - "grand_exchange_price": "1021", - "durability": null, - "name": "Tribal mask", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10616", - "equipment_slot": "0" - }, - { - "examine": "A ceremonial wooden mask.", - "grand_exchange_price": "1021", - "durability": null, "name": "Tribal mask", - "tradeable": "true", - "weight": "2", + "examine": "A ceremonial wooden mask.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "2" + }, + { "id": "10617", - "equipment_slot": "0" + "name": "Tribal mask", + "examine": "A ceremonial wooden mask.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "2" }, { - "shop_price": "3840", - "examine": "Provides excellent protection.", - "durability": null, - "weight": "9.9", - "absorb": "1,0,2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "4595", - "name": "White platebody", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10618", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,1,0,0" - }, - { - "shop_price": "10000", - "examine": "An initiate Temple Knight's Armour.", + "name": "White platebody", + "examine": "Provides excellent protection.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,1,0,0", "durability": null, - "weight": "8", - "absorb": "1,0,3", + "equip_audio": "2239", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "5821", - "name": "Initiate hauberk", + "shop_price": "3840", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "9.9" + }, + { "id": "10619", - "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,0,0,6,0,0" - }, - { - "shop_price": "12000", - "examine": "A Proselyte Temple Knight's armour.", + "name": "Initiate hauberk", + "examine": "An initiate Temple Knight's Armour.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,0,0,6,0,0", "durability": null, - "weight": "8.6", - "absorb": "2,0,4", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "6960", - "name": "Proselyte hauberk", + "shop_price": "10000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "8" + }, + { "id": "10620", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,8,0,0" + "name": "Proselyte hauberk", + "examine": "A Proselyte Temple Knight's armour.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,8,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "12000", + "tradeable": "true", + "weight": "8.6" }, { - "remove_sleeves": "true", - "examine": "A thick heavy leather top.", - "durability": null, - "name": "Mourner top", - "archery_ticket_price": "0", "id": "10621", - "equipment_slot": "4" + "name": "Mourner top", + "examine": "A thick heavy leather top.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { - "remove_sleeves": "true", - "examine": "This should make me harder to spot in polar areas.", - "grand_exchange_price": "216", - "durability": null, - "name": "Kyatt top", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10622", - "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "remove_sleeves": "true", - "examine": "This should make me harder to spot in woodland and jungle areas.", - "grand_exchange_price": "1793", - "durability": null, - "name": "Larupia top", - "tradeable": "true", - "weight": "0.2", + "name": "Kyatt top", + "examine": "This should make me harder to spot in polar areas.", "archery_ticket_price": "0", - "id": "10623", "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" }, { + "id": "10623", + "name": "Larupia top", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10624", + "name": "Graahk top", + "examine": "This should make me harder to spot in desert areas.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "300", - "examine": "This should make me harder to spot in desert areas.", - "grand_exchange_price": "246", - "durability": null, - "name": "Graahk top", "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10624", - "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" + "weight": "0.2" }, { - "remove_sleeves": "true", - "examine": "This should make me harder to spot in wooded areas.", - "grand_exchange_price": "3883", - "durability": null, - "name": "Wood camo top", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10625", + "name": "Wood camo top", + "examine": "This should make me harder to spot in wooded areas.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" }, { - "remove_sleeves": "true", - "examine": "This should make me harder to spot in jungle areas.", - "grand_exchange_price": "325", - "durability": null, - "name": "Jungle camo top", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10626", + "name": "Jungle camo top", + "examine": "This should make me harder to spot in jungle areas.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" }, { - "remove_sleeves": "true", - "examine": "This should make me harder to spot in desert areas.", - "grand_exchange_price": "606", - "durability": null, - "name": "Desert camo top", - "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "10627", + "name": "Desert camo top", + "examine": "This should make me harder to spot in desert areas.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" - }, - { + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", - "examine": "This should make me harder to spot in polar areas.", - "grand_exchange_price": "5614", - "durability": null, - "name": "Polar camo top", "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10628", - "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", - "equipment_slot": "4" + "weight": "0.2" }, { - "examine": "A mime would wear this.", - "durability": null, - "name": "Mime mask", + "id": "10628", + "name": "Polar camo top", + "examine": "This should make me harder to spot in polar areas.", "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.2" + }, + { "id": "10629", + "name": "Mime mask", + "examine": "A mime would wear this.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "0" }, { - "remove_sleeves": "true", - "examine": "Very posh!", - "durability": null, - "name": "Princess blouse", - "weight": "2", - "archery_ticket_price": "0", "id": "10630", - "equipment_slot": "4" + "name": "Princess blouse", + "examine": "Very posh!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2" }, { - "examine": "Aside from the braaaains on the lapel, it's still quite good.", - "durability": null, - "name": "Zombie shirt", - "archery_ticket_price": "0", "id": "10631", + "name": "Zombie shirt", + "examine": "Aside from the braaaains on the lapel, it's still quite good.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "4" }, { - "remove_sleeves": "true", - "examine": "Examine what?", - "durability": null, - "name": "Camo top", - "weight": "2.7", - "archery_ticket_price": "0", "id": "10632", - "equipment_slot": "4" + "name": "Camo top", + "examine": "Examine what?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2.7" }, { - "remove_sleeves": "true", - "examine": "A leather strapped top.", - "durability": null, - "name": "Lederhosen top", - "weight": "2.2", - "archery_ticket_price": "0", "id": "10633", - "equipment_slot": "4" - }, - { + "name": "Lederhosen top", + "examine": "A leather strapped top.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", - "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", - "durability": null, - "name": "Shade robe", - "weight": "2", - "archery_ticket_price": "0", + "weight": "2.2" + }, + { "id": "10634", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", - "equipment_slot": "4" - }, - { - "shop_price": "450", - "examine": "The cape worn by members of the Legends Guild.", - "durability": null, - "name": "Cape of legends", - "tradeable": "false", - "weight": "1.8", + "name": "Shade robe", + "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", "archery_ticket_price": "0", - "id": "10635", - "bonuses": "0,0,0,0,0,7,7,7,7,7,0,0,0,0,0", - "equipment_slot": "1" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2" }, { + "id": "10635", + "name": "Cape of legends", + "examine": "The cape worn by members of the Legends Guild.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,7,7,7,7,7,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "shop_price": "450", + "tradeable": "false", + "weight": "1.8" + }, + { + "id": "10636", + "name": "Obsidian cape", + "examine": "A cape woven of obsidian plates.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "lendable": "true", "shop_price": "90000", - "examine": "A cape woven of obsidian plates.", - "grand_exchange_price": "38500", - "durability": null, - "name": "Obsidian cape", "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10636", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "1.8" }, { - "examine": "A cape of fire.", - "durability": null, - "name": "Fire cape", - "tradeable": "false", - "weight": "1.8", - "archery_ticket_price": "0", "id": "10637", - "bonuses": "1,1,1,1,1,11,11,11,11,11,0,4,2,0,0", - "equipment_slot": "1" - }, - { - "shop_price": "50", - "examine": "Ooohhh look at the pretty colours...", - "durability": null, - "name": "Team-1 cape", - "tradeable": "true", - "weight": "0.4", + "name": "Fire cape", + "examine": "A cape of fire.", "archery_ticket_price": "0", - "id": "10638", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" + "bonuses": "1,1,1,1,1,11,11,11,11,11,0,4,2,0,0", + "durability": null, + "equipment_slot": "1", + "tradeable": "false", + "weight": "1.8" }, { + "id": "10638", + "name": "Team-1 cape", + "examine": "Ooohhh look at the pretty colours...", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10639", + "name": "Attack cape", + "examine": "The cape worn by masters of attack.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{0,99}", "shop_price": "99000", - "examine": "The cape worn by masters of attack.", - "durability": null, - "name": "Attack cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10639", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10640", + "name": "Strength cape", + "examine": "The cape only worn by the strongest people.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{2,99}", "shop_price": "99000", - "examine": "The cape only worn by the strongest people.", - "durability": null, - "name": "Strength cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10640", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10641", + "name": "Defence cape", + "examine": "The cape worn by masters of the art of Defence.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{1,99}", "shop_price": "99000", - "examine": "The cape worn by masters of the art of Defence.", - "durability": null, - "name": "Defence cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10641", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10642", + "name": "Ranging cape", + "examine": "The cape worn by master archers.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{4,99}", "shop_price": "99000", - "examine": "The cape worn by master archers.", - "durability": null, - "name": "Ranging cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10642", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10643", + "name": "Prayer cape", + "examine": "The cape worn by the most pious of heroes.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{5,99}", "shop_price": "99000", - "examine": "The cape worn by the most pious of heroes.", - "durability": null, - "name": "Prayer cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10643", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10644", + "name": "Magic cape", + "examine": "The cape worn by the most powerful mages.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{6,99}", "shop_price": "99000", - "examine": "The cape worn by the most powerful mages.", - "durability": null, - "name": "Magic cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10644", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10645", + "name": "Runecraft cape", + "examine": "The cape worn by master runecrafters.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{20,99}", "shop_price": "99000", - "examine": "The cape worn by master runecrafters.", - "durability": null, - "name": "Runecraft cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10645", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10646", + "name": "Hunter cape", + "examine": "The cape worn by master hunters.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{21,99}", "shop_price": "99000", - "examine": "The cape worn by master hunters.", - "durability": null, - "name": "Hunter cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10646", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10647", + "name": "Hitpoints cape", + "examine": "The cape worn by well-constituted adventurers.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{3,99}", "shop_price": "99000", - "examine": "The cape worn by well-constituted adventurers.", - "durability": null, - "name": "Hitpoints cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10647", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10648", + "name": "Agility cape", + "examine": "The cape worn by the most agile of heroes.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{16,99}", "shop_price": "99000", - "examine": "The cape worn by the most agile of heroes.", - "durability": null, - "name": "Agility cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10648", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10649", + "name": "Herblore cape", + "examine": "The cape worn by the most skilled at the art of herblore.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{15,99}", "shop_price": "99000", - "examine": "The cape worn by the most skilled at the art of herblore.", - "durability": null, - "name": "Herblore cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10649", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10650", + "name": "Thieving cape", + "examine": "The cape worn by master thieves.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{17,99}", "shop_price": "99000", - "examine": "The cape worn by master thieves.", - "durability": null, - "name": "Thieving cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10650", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10651", + "name": "Crafting cape", + "examine": "The cape worn by master craftworkers.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{12,99}", "shop_price": "99000", - "examine": "The cape worn by master craftworkers.", - "durability": null, - "name": "Crafting cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10651", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10652", + "name": "Fletching cape", + "examine": "The cape worn by the best of fletchers.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{9,99}", "shop_price": "99000", - "examine": "The cape worn by the best of fletchers.", - "durability": null, - "name": "Fletching cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10652", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10653", + "name": "Slayer cape", + "examine": "The cape worn by slayer masters.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{18,99}", "shop_price": "99000", - "examine": "The cape worn by slayer masters.", - "durability": null, - "name": "Slayer cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10653", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10654", + "name": "Construct. cape", + "examine": "The cape worn by master builders.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{22,99}", "shop_price": "99000", - "examine": "The cape worn by master builders.", - "durability": null, - "name": "Construct. cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10654", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10655", + "name": "Mining cape", + "examine": "The cape worn by the most skilled miners.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{14,99}", "shop_price": "99000", - "examine": "The cape worn by the most skilled miners.", - "durability": null, - "name": "Mining cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10655", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10656", + "name": "Smithing cape", + "examine": "The cape worn by master smiths.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{13,99}", "shop_price": "99000", - "examine": "The cape worn by master smiths.", - "durability": null, - "name": "Smithing cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10656", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10657", + "name": "Fishing cape", + "examine": "The cape worn by the best fishermen.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{10,99}", "shop_price": "99000", - "examine": "The cape worn by the best fishermen.", - "durability": null, - "name": "Fishing cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10657", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10658", + "name": "Cooking cape", + "examine": "The cape worn by the world's best chefs.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{7,99}", "shop_price": "99000", - "examine": "The cape worn by the world's best chefs.", - "durability": null, - "name": "Cooking cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10658", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10659", + "name": "Firemaking cape", + "examine": "The cape worn by master firelighters.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{11,99}", "shop_price": "99000", - "examine": "The cape worn by master firelighters.", - "durability": null, - "name": "Firemaking cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10659", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10660", + "name": "Woodcutting cape", + "examine": "The cape worn by master woodcutters (Obtaining level 99 skill)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{8,99}", "shop_price": "99000", - "examine": "The cape worn by master woodcutters (Obtaining level 99 skill)", - "durability": null, - "name": "Woodcutting cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10660", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { + "id": "10661", + "name": "Farming cape", + "examine": "The cape worn by master farmers.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{19,99}", "shop_price": "99000", - "examine": "The cape worn by master farmers.", - "durability": null, - "name": "Farming cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10661", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { - "shop_price": "99000", - "examine": "The cape worn by only the most experienced adventurers.", - "durability": null, - "name": "Quest point cape", - "weight": "0.4", - "archery_ticket_price": "0", "id": "10662", + "name": "Quest point cape", + "examine": "The cape worn by only the most experienced adventurers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "shop_price": "99000", + "weight": "0.4" }, { - "examine": "A surprisingly aerodynamic cape.", - "grand_exchange_price": "951", - "durability": null, - "name": "Spotted cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", "id": "10663", + "name": "Spotted cape", + "examine": "A surprisingly aerodynamic cape.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "tradeable": "true", + "weight": "0.4" }, { - "examine": "A really surprisingly aerodynamic cape.", - "grand_exchange_price": "881", - "durability": null, - "name": "Spottier cape", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", "id": "10664", + "name": "Spottier cape", + "examine": "A really surprisingly aerodynamic cape.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "tradeable": "true", + "weight": "0.4" }, { - "requirements": "{1,10}", - "examine": "A black kitesheild with a heraldic design.", - "grand_exchange_price": "15249", - "durability": null, - "name": "Black shield(h1)", - "tradeable": "true", - "weight": "4", - "archery_ticket_price": "0", "id": "10665", + "name": "Black shield(h1)", + "examine": "A black kitesheild with a heraldic design.", "absorb": "1,0,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "16339", - "name": "Adamant shield(h1)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10666", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + "name": "Adamant shield(h1)", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "examine": "A rune kiteshield with a heraldic design.", - "grand_exchange_price": "35300", - "durability": null, - "name": "Rune shield(h1)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", "id": "10667", + "name": "Rune shield(h1)", + "examine": "A rune kiteshield with a heraldic design.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,10}", - "examine": "A black kiteshield with a heraldic design.", - "grand_exchange_price": "9751", - "durability": null, - "name": "Black shield(h2)", - "tradeable": "true", - "weight": "4", - "archery_ticket_price": "0", "id": "10668", + "name": "Black shield(h2)", + "examine": "A black kiteshield with a heraldic design.", "absorb": "1,0,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "3353", - "name": "Adamant shield(h2)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10669", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + "name": "Adamant shield(h2)", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "examine": "A rune kiteshield with a heraldic design.", - "grand_exchange_price": "31903", - "durability": null, - "name": "Rune shield(h2)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", "id": "10670", + "name": "Rune shield(h2)", + "examine": "A rune kiteshield with a heraldic design.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5.4" }, { - "requirements": "{1,10}", - "examine": "A black shield with a heraldic design.", - "grand_exchange_price": "6791", - "durability": null, - "name": "Black shield(h3)", - "tradeable": "true", - "weight": "4", - "archery_ticket_price": "0", "id": "10671", + "name": "Black shield(h3)", + "examine": "A black shield with a heraldic design.", "absorb": "1,0,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equipment_slot": "5", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "5566", - "name": "Adamant shield(h3)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10672", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + "name": "Adamant shield(h3)", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,40}", - "examine": "A rune kiteshield with a heraldic design.", - "grand_exchange_price": "32082", - "durability": null, - "name": "Rune shield(h3)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", "id": "10673", + "name": "Rune shield(h3)", + "examine": "A rune kiteshield with a heraldic design.", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,10}", - "examine": "A black shield with a heraldic design.", - "grand_exchange_price": "5159", - "durability": null, - "name": "Black shield(h4)", - "tradeable": "true", - "weight": "4", - "archery_ticket_price": "0", "id": "10674", - "absorb": "1,0,2", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "3219", - "name": "Adamant shield(h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10675", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" - }, - { - "requirements": "{1,40}", - "examine": "A rune kiteshield with a heraldic design.", - "grand_exchange_price": "32351", - "durability": null, - "name": "Rune shield(h4)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "10676", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,10}", + "name": "Black shield(h4)", "examine": "A black shield with a heraldic design.", - "grand_exchange_price": "8451", - "durability": null, - "name": "Black shield(h5)", - "tradeable": "true", - "weight": "4", - "archery_ticket_price": "0", - "id": "10677", "absorb": "1,0,2", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "A shield with a heraldic design.", "durability": null, - "weight": "5", - "absorb": "3,0,6", "equipment_slot": "5", - "grand_exchange_price": "5905", - "name": "Adamant shield(h5)", + "requirements": "{1,10}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10678", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + "weight": "4" }, { - "requirements": "{1,40}", + "id": "10675", + "name": "Adamant shield(h4)", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "10676", + "name": "Rune shield(h4)", "examine": "A rune kiteshield with a heraldic design.", - "grand_exchange_price": "35200", - "durability": null, - "name": "Rune shield(h5)", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "10679", "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0", - "equipment_slot": "5" + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" }, { - "examine": "Those studs should provide a bit more protection. Nice trim too!", - "grand_exchange_price": "67430", - "durability": null, - "name": "Studded body (g)", - "tradeable": "true", - "weight": "5.4", + "id": "10677", + "name": "Black shield(h5)", + "examine": "A black shield with a heraldic design.", + "absorb": "1,0,2", "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "4" + }, + { + "id": "10678", + "name": "Adamant shield(h5)", + "examine": "A shield with a heraldic design.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "5" + }, + { + "id": "10679", + "name": "Rune shield(h5)", + "examine": "A rune kiteshield with a heraldic design.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "5" + }, + { "id": "10680", - "absorb": "0,3,1", - "bonuses": "0,0,0,-4,8,18,25,22,8,25,0,0,0,0,0", - "equipment_slot": "4" - }, - { + "name": "Studded body (g)", "examine": "Those studs should provide a bit more protection. Nice trim too!", - "grand_exchange_price": "22400", - "durability": null, - "name": "Studded body (t)", - "tradeable": "true", - "weight": "5.4", - "archery_ticket_price": "0", - "id": "10681", "absorb": "0,3,1", + "archery_ticket_price": "0", "bonuses": "0,0,0,-4,8,18,25,22,8,25,0,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "tradeable": "true", + "weight": "5.4" }, { + "id": "10681", + "name": "Studded body (t)", + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,0,0,0,0,0", "durability": null, + "equipment_slot": "4", + "tradeable": "true", + "weight": "5.4" + }, + { + "id": "10682", "name": "D'hide body(g)", "archery_ticket_price": "0", - "id": "10682", "bonuses": "0,0,0,-15,15,40,32,45,20,40,0,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "4" }, { - "durability": null, + "id": "10683", "name": "D'hide body (t)", "archery_ticket_price": "0", - "id": "10683", "bonuses": "0,0,0,-15,15,40,32,45,20,40,0,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "4" }, { - "durability": null, + "id": "10684", "name": "D'hide body (g)", "archery_ticket_price": "0", - "id": "10684", "bonuses": "0,0,0,-15,20,45,37,50,30,45,0,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "4" }, { - "durability": null, + "id": "10685", "name": "D'hide body (t)", "archery_ticket_price": "0", - "id": "10685", "bonuses": "0,0,0,-15,20,45,37,50,30,45,0,0,0,0,0", + "durability": null, + "equip_audio": "2241", "equipment_slot": "4" }, { - "remove_sleeves": "true", - "examine": "I can practise magic better in this.", - "durability": null, - "name": "Wizard robe (g)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10686", + "name": "Wizard robe (g)", + "examine": "I can practise magic better in this.", + "archery_ticket_price": "0", "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "4" + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_sleeves": "true", - "examine": "I can do magic better in this.", - "durability": null, - "name": "Wizard robe (t)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10687", + "name": "Wizard robe (t)", + "examine": "I can do magic better in this.", + "archery_ticket_price": "0", "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,20}-{6,40}", - "examine": "Enchanted Wizards robes.", "durability": null, - "weight": "1", - "absorb": "3,1,0", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "72800", - "name": "Enchanted top", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "10688", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + "name": "Enchanted top", + "examine": "Enchanted Wizards robes.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,40}", + "tradeable": "true", + "weight": "1" }, { - "lendable": "true", - "examine": "Slightly magical boots.", - "grand_exchange_price": "763602", - "durability": null, - "name": "Wizard boots", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10689", + "name": "Wizard boots", + "examine": "Slightly magical boots.", + "archery_ticket_price": "0", "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", - "equipment_slot": "10" + "durability": null, + "equipment_slot": "10", + "lendable": "true", + "tradeable": "true", + "weight": "1" }, { - "requirements": "{1,10}", - "examine": "Black platebody with trim.", - "durability": null, - "weight": "9.07", - "absorb": "1,0,2", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "90744", - "name": "Black platebody (t)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10690", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,0,0,0" - }, - { - "requirements": "{1,10}", - "examine": "Black platebody with gold trim.", - "durability": null, - "weight": "9.07", + "name": "Black platebody (t)", + "examine": "Black platebody with trim.", "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "230800", - "name": "Black platebody (g)", + "requirements": "{1,10}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "9.07" + }, + { "id": "10691", - "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,0,0,0" + "name": "Black platebody (g)", + "examine": "Black platebody with gold trim.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "9.07" }, { - "lendable": "true", - "examine": "Your money or your life!", - "grand_exchange_price": "92519", - "durability": null, - "name": "Highwayman mask", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10692", - "equipment_slot": "0" + "name": "Highwayman mask", + "examine": "Your money or your life!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "examine": "Parlez-vous francais? (Do you speak French?)", - "grand_exchange_price": "64066", - "durability": null, - "name": "Blue beret", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": true, "id": "10693", - "equipment_slot": "0" - }, - { - "lendable": "true", - "examine": "Parlez-vous francais?(Do you speak French?)", - "grand_exchange_price": "158274", - "durability": null, - "name": "Black beret", - "tradeable": "true", - "archery_ticket_price": "0", - "hat": true, - "id": "10694", - "equipment_slot": "0" - }, - { - "lendable": "true", + "name": "Blue beret", "examine": "Parlez-vous francais? (Do you speak French?)", - "grand_exchange_price": "281900", - "durability": null, - "name": "White beret", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "hat": true, - "id": "10695", - "equipment_slot": "0" - }, - { "lendable": "true", - "examine": "Lightweight boots ideal for rangers.", - "grand_exchange_price": "11781186", - "durability": null, - "name": "Ranger boots", - "tradeable": "true", - "weight": "0.2", + "tradeable": "true" + }, + { + "id": "10694", + "name": "Black beret", + "examine": "Parlez-vous francais?(Do you speak French?)", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "hat": true, + "lendable": "true", + "tradeable": "true" + }, + { + "id": "10695", + "name": "White beret", + "examine": "Parlez-vous francais? (Do you speak French?)", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "hat": true, + "lendable": "true", + "tradeable": "true" + }, + { "id": "10696", + "name": "Ranger boots", + "examine": "Lightweight boots ideal for rangers.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-10,8,2,3,4,2,0,0,0,0,0,0", - "equipment_slot": "10" + "durability": null, + "equipment_slot": "10", + "lendable": "true", + "tradeable": "true", + "weight": "0.2" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Adamant platebody with trim.", - "durability": null, - "weight": "9.07", - "absorb": "2,0,4", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "79300", - "name": "Adam platebody (t)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10697", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,0,0,0" + "name": "Adam platebody (t)", + "examine": "Adamant platebody with trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "9.07" }, { - "requirements": "{1,30}", - "ge_buy_limit": "2", + "id": "10698", + "name": "Adam platebody (g)", "examine": "Adamant platebody with gold trim.", - "durability": null, - "weight": "9.07", "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "2", + "remove_sleeves": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "9.07" + }, + { + "id": "10699", + "name": "Black helm (h1)", + "examine": "A black helmet with a heraldic design.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10700", + "name": "Black helm (h2)", + "examine": "A black helmet with a heraldic design.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10701", + "name": "Black helm (h3)", + "examine": "A black helmet with a heraldic design.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10702", + "name": "Black helm (h4)", + "examine": "A black helmet with a heraldic design.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10703", + "name": "Black helm (h5)", + "examine": "A black helmet with a heraldic design.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10704", + "name": "Rune helm (h1)", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true" + }, + { + "id": "10705", + "name": "Rune helm (h2)", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10706", + "name": "Rune helm (h3)", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "4" + }, + { + "id": "10707", + "name": "Rune helm (h4)", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10708", + "name": "Rune helm (h5)", + "examine": "A rune helmet with a heraldic design.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10709", + "name": "Adamant helm (h1)", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10710", + "name": "Adamant helm (h2)", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10711", + "name": "Adamant helm (h3)", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10712", + "name": "Adamant helm (h4)", + "examine": "An Adamant helmet with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10713", + "name": "Adamant helm (h5)", + "examine": "An adamant helmet with a heraldic design.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10714", + "name": "Bob shirt", + "examine": "See table", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "207912", - "name": "Adam platebody (g)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10698", - "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,0,0,0" + "weight": "2" }, { - "remove_head": "true", - "requirements": "{1,10}", - "examine": "A black helmet with a heraldic design.", - "grand_exchange_price": "22022", - "durability": null, - "name": "Black helm (h1)", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10699", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,10}", - "examine": "A black helmet with a heraldic design.", - "grand_exchange_price": "11700", - "durability": null, - "name": "Black helm (h2)", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10700", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,10}", - "examine": "A black helmet with a heraldic design.", - "grand_exchange_price": "10424", - "durability": null, - "name": "Black helm (h3)", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10701", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,10}", - "examine": "A black helmet with a heraldic design.", - "grand_exchange_price": "12717", - "durability": null, - "name": "Black helm (h4)", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10702", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,10}", - "examine": "A black helmet with a heraldic design.", - "grand_exchange_price": "17852", - "durability": null, - "name": "Black helm (h5)", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10703", - "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "examine": "A rune helmet with a heraldic design.", - "grand_exchange_price": "30298", - "durability": null, - "name": "Rune helm (h1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10704", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "26127", - "name": "Rune helm (h2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10705", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "4", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "37333", - "name": "Rune helm (h3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10706", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "29600", - "name": "Rune helm (h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10707", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "examine": "A rune helmet with a heraldic design.", - "durability": null, - "weight": "2", - "absorb": "1,0,3", - "equipment_slot": "0", - "grand_exchange_price": "41325", - "name": "Rune helm (h5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10708", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "28407", - "name": "Adamant helm (h1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10709", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "9839", - "name": "Adamant helm (h2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10710", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "8485", - "name": "Adamant helm (h3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10711", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An Adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "10774", - "name": "Adamant helm (h4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10712", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "An adamant helmet with a heraldic design.", - "durability": null, - "weight": "3", - "absorb": "1,0,2", - "equipment_slot": "0", - "grand_exchange_price": "17390", - "name": "Adamant helm (h5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10713", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" - }, - { - "remove_sleeves": "true", - "examine": "See table", - "grand_exchange_price": "8425", - "durability": null, - "name": "Bob shirt", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10714", - "equipment_slot": "4" - }, - { - "remove_sleeves": "true", - "examine": "See table", - "grand_exchange_price": "8425", - "durability": null, - "name": "Bob shirt", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10715", - "equipment_slot": "4" + "name": "Bob shirt", + "examine": "See table", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "2" }, { - "remove_sleeves": "true", - "examine": "See table", - "grand_exchange_price": "8425", - "durability": null, - "name": "Bob shirt", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10716", - "equipment_slot": "4" + "name": "Bob shirt", + "examine": "See table", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "2" }, { - "remove_sleeves": "true", - "examine": "See table", - "grand_exchange_price": "8425", - "durability": null, - "name": "Bob shirt", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10717", - "equipment_slot": "4" - }, - { - "remove_sleeves": "true", - "examine": "See table", - "grand_exchange_price": "8425", - "durability": null, "name": "Bob shirt", - "tradeable": "true", - "weight": "2", + "examine": "See table", "archery_ticket_price": "0", - "id": "10718", - "equipment_slot": "4" - }, - { - "examine": "A very powerful dragonstone amulet.", - "grand_exchange_price": "1", "durability": null, - "name": "Amulet of glory(t)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10719", - "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", - "equipment_slot": "2" - }, - { - "examine": "A cape from the almighty god Guthix.", - "durability": null, - "name": "Guthix cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10720", - "bonuses": "0,0,0,10,0,1,1,2,10,0,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "remove_head": "true", - "examine": "Now that's just silly.", - "durability": null, - "name": "Frog mask", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10721", - "remove_beard": "true", - "equipment_slot": "0" - }, - { - "destroy_message": "You can get another from Diango in Draynor Village.", - "examine": "A reindeer hat and a matching flashing nose.", - "durability": null, - "name": "Reindeer hat", - "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10722" - }, - { - "remove_head": "true", - "destroy_message": "You may get another from Diango in Draynor Village.", - "examine": "Better not light it!", - "durability": null, - "name": "Jack lantern mask", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10723", - "remove_beard": "true", - "equipment_slot": "0" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Skeleton feet.", - "durability": null, - "name": "Skeleton boots", - "weight": "2", - "archery_ticket_price": "0", - "id": "10724", - "equipment_slot": "10" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some skeletal gloves.", - "durability": null, - "name": "Skeleton gloves", - "weight": "2", - "archery_ticket_price": "0", - "id": "10725", - "equipment_slot": "9" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Does my pelvis look big in this?", - "durability": null, - "name": "Skeleton leggings", - "weight": "2", - "archery_ticket_price": "0", - "id": "10726", - "equipment_slot": "7" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", + "equipment_slot": "4", "remove_sleeves": "true", - "examine": "The shirt of a fully body skeleton costume.", - "durability": null, - "name": "Skeleton shirt", - "weight": "2", - "archery_ticket_price": "0", - "id": "10727", - "equipment_slot": "4" + "tradeable": "true", + "weight": "2" }, { + "id": "10718", + "name": "Bob shirt", + "examine": "See table", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10719", + "name": "Amulet of glory(t)", + "examine": "A very powerful dragonstone amulet.", + "archery_ticket_price": "0", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "10720", + "name": "Guthix cape", + "examine": "A cape from the almighty god Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,10,0,1,1,2,10,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", + "weight": "0.4" + }, + { + "id": "10721", + "name": "Frog mask", + "examine": "Now that's just silly.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A scary skeleton mask.", - "durability": null, - "name": "Skeleton mask", - "weight": "2", - "archery_ticket_price": "0", - "id": "10728", - "equipment_slot": "0" + "weight": "0.4" }, { - "examine": "A ring given to you by the Easter Bunny.", - "durability": null, - "name": "Easter ring", + "id": "10722", + "name": "Reindeer hat", + "examine": "A reindeer hat and a matching flashing nose.", "archery_ticket_price": "0", - "id": "10729" - }, - { - "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", - "examine": "I've got no strings ... oh hang on!", - "durability": null, - "name": "Blue marionette", - "tradeable": "false", "destroy": "true", - "archery_ticket_price": "0", - "id": "10730" + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "tradeable": "false", + "weight": "2" }, { - "examine": "Alas...I hardly knew him.", + "id": "10723", + "name": "Jack lantern mask", + "examine": "Better not light it!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You may get another from Diango in Draynor Village.", "durability": null, + "equip_audio": "3227", + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "tradeable": "false" + }, + { + "id": "10724", + "name": "Skeleton boots", + "examine": "Skeleton feet.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "10", + "weight": "2" + }, + { + "id": "10725", + "name": "Skeleton gloves", + "examine": "Some skeletal gloves.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", + "weight": "2" + }, + { + "id": "10726", + "name": "Skeleton leggings", + "examine": "Does my pelvis look big in this?", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "7", + "weight": "2" + }, + { + "id": "10727", + "name": "Skeleton shirt", + "examine": "The shirt of a fully body skeleton costume.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "2" + }, + { + "id": "10728", + "name": "Skeleton mask", + "examine": "A scary skeleton mask.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "2" + }, + { + "id": "10729", + "name": "Easter ring", + "examine": "A ring given to you by the Easter Bunny.", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "", + "equipment_slot": "" + }, + { + "id": "10730", + "name": "Blue marionette", + "examine": "I've got no strings ... oh hang on!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10731", "name": "Zombie head", + "examine": "Alas...I hardly knew him.", "archery_ticket_price": "0", - "id": "10731" + "durability": null }, { - "turn90cw_anim": "821", + "id": "10732", + "name": "Rubber chicken", "examine": "Perhaps not the most powerful weapon in 2009Scape.", - "walk_anim": "1830", - "durability": null, - "weight": "0.4", - "turn90ccw_anim": "822", + "archery_ticket_price": "0", + "attack_audios": "2257,2257,2257", "attack_speed": "4", - "weapon_interface": "12", - "turn180_anim": "1830", - "render_anim": "182", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "durability": null, + "equip_audio": "2238", "equipment_slot": "3", "fun_weapon": "true", + "render_anim": "182", + "run_anim": "824", "stand_anim": "1832", - "name": "Rubber chicken", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "10732", "stand_turn_anim": "823", - "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" - }, - { - "examine": "A gift from Santa.", - "durability": null, - "name": "Yo-yo", - "archery_ticket_price": "0", - "id": "10733" - }, - { - "examine": "A rabbit-like adornment.", - "durability": null, - "name": "Bunny ears", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10734", - "equipment_slot": "0" - }, - { - "turn90cw_anim": "821", - "examine": "It's a Scythe.", - "walk_anim": "819", - "durability": null, - "weight": "3", + "turn180_anim": "1830", "turn90ccw_anim": "822", - "attack_speed": "7", - "two_handed": "true", - "turn180_anim": "820", - "render_anim": "1383", - "equipment_slot": "3", - "stand_anim": "847", - "name": "Scythe", - "run_anim": "824", + "turn90cw_anim": "821", + "walk_anim": "1830", + "weapon_interface": "12", + "weight": "0.4" + }, + { + "id": "10733", + "name": "Yo-yo", + "examine": "A gift from Santa.", "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10734", + "name": "Bunny ears", + "examine": "A rabbit-like adornment.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "weight": "0.2" + }, + { "id": "10735", + "name": "Scythe", + "examine": "It's a Scythe.", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "3,8,3,0,0,0,3,1,0,0,0,10,0,0,0", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "1383", + "run_anim": "824", + "stand_anim": "847", "stand_turn_anim": "823", - "bonuses": "3,8,3,0,0,0,3,1,0,0,0,10,0,0,0" + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "two_handed": "true", + "walk_anim": "819", + "weight": "3" }, { - "examine": "An enchanted ruby amulet with a nice trim.", - "grand_exchange_price": "443800", - "durability": null, - "name": "Strength amulet(t)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10736", + "name": "Strength amulet(t)", + "examine": "An enchanted ruby amulet with a nice trim.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", - "equipment_slot": "2" + "durability": null, + "equipment_slot": "2", + "tradeable": "true" }, { - "examine": "An enchanted sapphire amulet of magic.", - "grand_exchange_price": "67158", - "durability": null, - "name": "Amulet of magic(t)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10738", + "name": "Amulet of magic(t)", + "examine": "An enchanted sapphire amulet of magic.", + "archery_ticket_price": "0", "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "2" + "durability": null, + "equipment_slot": "2", + "tradeable": "true" }, { - "remove_head": "true", - "lendable": "true", - "examine": "A big 'do about nothing.", - "grand_exchange_price": "36879", - "durability": null, - "name": "A powdered wig", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "10740", - "equipment_slot": "0" - }, - { - "lendable": "true", - "examine": "These'll help me stay alive.", - "grand_exchange_price": "559284", - "durability": null, - "name": "Flared trousers", - "tradeable": "true", - "weight": "1", + "name": "A powdered wig", + "examine": "A big 'do about nothing.", "archery_ticket_price": "0", - "id": "10742", - "equipment_slot": "7" - }, - { - "lendable": "true", - "examine": "Alas, someone has slashed my pantaloons.", - "grand_exchange_price": "12022", "durability": null, - "name": "Pantaloons", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10744", - "equipment_slot": "7" - }, - { + "equipment_slot": "0", + "lendable": "true", "remove_head": "true", - "lendable": "true", - "examine": "A cap for wearing whil...zzzzzzzzz", - "grand_exchange_price": "376084", - "durability": null, - "name": "Sleeping cap", "tradeable": "true", - "weight": "2", + "weight": "2" + }, + { + "id": "10742", + "name": "Flared trousers", + "examine": "These'll help me stay alive.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "lendable": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10744", + "name": "Pantaloons", + "examine": "Alas, someone has slashed my pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "lendable": "true", + "tradeable": "true", + "weight": "1" + }, + { "id": "10746", - "equipment_slot": "0" + "name": "Sleeping cap", + "examine": "A cap for wearing whil...zzzzzzzzz", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "2" }, { - "remove_sleeves": "true", - "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", - "durability": null, - "name": "Elegant shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10748", - "equipment_slot": "4" + "name": "Elegant shirt", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_sleeves": "true", - "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", - "durability": null, - "name": "Elegant shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10750", - "equipment_slot": "4" + "name": "Elegant shirt", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_sleeves": "true", - "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", - "durability": null, - "name": "Elegant shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10752", - "equipment_slot": "4" + "name": "Elegant shirt", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_sleeves": "true", - "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", - "durability": null, - "name": "Elegant shirt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "10754", - "equipment_slot": "4" - }, - { - "remove_sleeves": "true", - "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", - "durability": null, "name": "Elegant shirt", - "tradeable": "true", - "weight": "1", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" + }, + { "id": "10756", - "equipment_slot": "4" + "name": "Elegant shirt", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "1" }, { - "examine": "Stylish!", - "grand_exchange_price": "56600", - "durability": null, - "name": "Red boater", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10758", - "equipment_slot": "0" + "name": "Red boater", + "examine": "Stylish!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" }, { - "examine": "Stylish!", - "grand_exchange_price": "20300", - "durability": null, - "name": "Orange boater", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10760", - "equipment_slot": "0" + "name": "Orange boater", + "examine": "Stylish!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" }, { - "examine": "Stylish!", - "grand_exchange_price": "59940", - "durability": null, - "name": "Green boater", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10762", - "equipment_slot": "0" + "name": "Green boater", + "examine": "Stylish!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" }, { - "examine": "Stylish!", - "grand_exchange_price": "54236", - "durability": null, - "name": "Blue boater", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10764", - "equipment_slot": "0" - }, - { + "name": "Blue boater", "examine": "Stylish!", - "grand_exchange_price": "56495", - "durability": null, - "name": "Black boater", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" + }, + { "id": "10766", - "equipment_slot": "0" + "name": "Black boater", + "examine": "Stylish!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" }, { - "lendable": "true", - "examine": "A minimalist's hat.", - "grand_exchange_price": "114319", - "durability": null, - "name": "Red headband", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10768", - "equipment_slot": "0" + "name": "Red headband", + "examine": "A minimalist's hat.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" }, { - "lendable": "true", - "examine": "A minimalist's hat.", - "grand_exchange_price": "41778", - "durability": null, - "name": "Black headband", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10770", - "equipment_slot": "0" - }, - { - "lendable": "true", + "name": "Black headband", "examine": "A minimalist's hat.", - "grand_exchange_price": "21764", - "durability": null, - "name": "Brown headband", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" + }, + { "id": "10772", - "equipment_slot": "0" + "name": "Brown headband", + "examine": "A minimalist's hat.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" }, { - "examine": "Shiver me timbers!", - "grand_exchange_price": "83200", - "durability": null, - "name": "Pirate's hat", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10774", - "equipment_slot": "0" + "name": "Pirate's hat", + "examine": "Shiver me timbers!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "tradeable": "true" }, { - "requirements": "{1,40}", - "examine": "Rune platebody in the colours of Zamorak.", - "durability": null, - "weight": "9", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "647800", - "name": "Zamorak platebody", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10776", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" - }, - { - "requirements": "{1,40}", - "examine": "Rune platebody in the colours of Saradomin.", - "durability": null, - "weight": "9.07", + "name": "Zamorak platebody", + "examine": "Rune platebody in the colours of Zamorak.", "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "1097689", - "name": "Saradomin plate", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "9" + }, + { "id": "10778", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" - }, - { - "requirements": "{1,40}", - "examine": "Rune platebody in the colours of Guthix.", - "durability": null, - "weight": "9.07", + "name": "Saradomin plate", + "examine": "Rune platebody in the colours of Saradomin.", "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0", + "durability": null, "equipment_slot": "4", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "241600", - "name": "Guthix platebody", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "9.07" + }, + { "id": "10780", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" - }, - { - "requirements": "{1,40}", - "examine": "Rune platebody with complete gold trim & plating.", - "durability": null, - "weight": "10", + "name": "Guthix platebody", + "examine": "Rune platebody in the colours of Guthix.", "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "1653821", - "name": "Gilded platebody", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "9.07" + }, + { "id": "10782", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + "name": "Gilded platebody", + "examine": "Rune platebody with complete gold trim & plating.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "10" }, { - "requirements": "{5,20}", - "remove_sleeves": "true", - "examine": "Blessed vestments of Saradomin.", - "grand_exchange_price": "106389", - "durability": null, - "name": "Saradomin robe top", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10784", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{5,20}", - "remove_sleeves": "true", - "examine": "Zamorak Vestments.", - "grand_exchange_price": "151000", - "durability": null, - "name": "Zamorak robe top", - "tradeable": "true", - "weight": "1", + "name": "Saradomin robe top", + "examine": "Blessed vestments of Saradomin.", "archery_ticket_price": "0", - "id": "10786", "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{5,20}", - "remove_sleeves": "true", - "examine": "Blessed vestments of Guthix.", - "grand_exchange_price": "80181", "durability": null, - "name": "Guthix robe top", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10788", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", - "equipment_slot": "4" - }, - { - "requirements": "{1,40}-{4,70}", - "examine": "Zamorak blessed dragonhide body armour.", - "durability": null, - "weight": "6", - "absorb": "0,6,3", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "84966", - "name": "Zamorak d'hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10790", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0" + "requirements": "{5,20}", + "tradeable": "true" }, { + "id": "10786", + "name": "Zamorak robe top", + "examine": "Zamorak Vestments.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{5,20}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10788", + "name": "Guthix robe top", + "examine": "Blessed vestments of Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{5,20}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "10790", + "name": "Zamorak d'hide", + "examine": "Zamorak blessed dragonhide body armour.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "10792", + "name": "Saradomin d'hide", + "examine": "Saradomin blessed dragonhide body armour.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", "requirements": "{1,40}-{4,70}", "shop_price": "13000", - "examine": "Saradomin blessed dragonhide body armour.", - "durability": null, - "destroy": "true", - "weight": "6", - "absorb": "0,6,3", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "92762", - "name": "Saradomin d'hide", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10792", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0" + "weight": "6" }, { + "id": "10794", + "name": "Guthix dragonhide", + "examine": "Guthix blessed dragonhide body armour.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", "requirements": "{1,40}-{4,70}", "shop_price": "13", - "examine": "Guthix blessed dragonhide body armour.", - "durability": null, - "weight": "6", - "absorb": "0,6,3", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "22384", - "name": "Guthix dragonhide", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10794", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0" + "weight": "6" }, { + "id": "10796", + "name": "Robin hood hat", + "examine": "Endorsed by Robin Hood.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,8,4,6,8,4,4,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", "lendable": "true", "requirements": "{4,40}", - "examine": "Endorsed by Robin Hood.", - "grand_exchange_price": "3070557", - "durability": null, - "name": "Robin hood hat", "tradeable": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10796", - "bonuses": "0,0,0,-10,8,4,6,8,4,4,0,0,0,0,0", - "equipment_slot": "0" + "weight": "0.2" }, { - "requirements": "{1,40}", - "examine": "Rune platebody with gold trim.", - "durability": null, - "weight": "9.07", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "231400", - "name": "Rune platebody (g)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "10798", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" - }, - { - "requirements": "{1,40}", - "examine": "Rune platebody with trim.", - "durability": null, - "weight": "9.07", + "name": "Rune platebody (g)", + "examine": "Rune platebody with gold trim.", "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0", + "durability": null, + "equip_audio": "2239", "equipment_slot": "4", "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "61100", - "name": "Rune platebody (t)", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "9.07" + }, + { "id": "10800", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" - }, - { - "lendable": "true", - "examine": "All for one and one for all!", - "grand_exchange_price": "56677", - "durability": null, - "name": "Tan cavalier", - "tradeable": "true", + "name": "Rune platebody (t)", + "examine": "Rune platebody with trim.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "10802", - "equipment_slot": "0" - }, - { - "lendable": "true", - "examine": "All for one and one for all!", - "grand_exchange_price": "18942", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0", "durability": null, - "name": "Dark cavalier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10804", - "equipment_slot": "0" - }, - { - "lendable": "true", - "examine": "All for one and one for all!", - "grand_exchange_price": "421305", - "durability": null, - "name": "Black cavalier", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10806", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "1000", - "examine": "Arctic Pine logs prepared with sacred oil for a funeral pyre", - "grand_exchange_price": "3453", - "durability": null, - "name": "Arctic pyre logs", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10808" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3453", - "durability": null, - "name": "Arctic pyre logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10809" - }, - { - "ge_buy_limit": "25000", - "examine": "Log cut from an arctic pine.", - "grand_exchange_price": "90", - "durability": null, - "name": "Arctic pine logs", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10810", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "90", - "durability": null, - "name": "Arctic pine logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10811" - }, - { - "ge_buy_limit": "1000", - "examine": "Used to repair bridges.", - "grand_exchange_price": "18", - "durability": null, - "name": "Split log", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "10812" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "18", - "durability": null, - "name": "Split log", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10813" - }, - { - "shop_price": "120", - "ge_buy_limit": "1000", - "examine": "I can spin this into rope.", - "grand_exchange_price": "113", - "durability": null, - "name": "Hair", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10814" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "113", - "durability": null, - "name": "Hair", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10815" - }, - { - "shop_price": "2", - "ge_buy_limit": "1000", - "examine": "I need to cook this.", - "grand_exchange_price": "14", - "durability": null, - "name": "Raw yak meat", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "10816" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "14", - "durability": null, - "name": "Raw yak meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10817" - }, - { - "shop_price": "50", - "ge_buy_limit": "5000", - "examine": "Thakkrad, of Neitiznot, can cure this.", - "grand_exchange_price": "301", - "durability": null, - "name": "Yak-hide", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10818" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "301", - "durability": null, - "name": "Yak-hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10819" - }, - { - "ge_buy_limit": "5000", - "examine": "Ready to be cut and sewn into armour.", - "grand_exchange_price": "396", - "durability": null, - "name": "Cured yak-hide", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10820" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "396", - "durability": null, - "name": "Cured yak-hide", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10821" - }, - { - "requirements": "{1,20}", - "ge_buy_limit": "100", - "examine": "Smelly yak body armour.", - "durability": null, - "weight": "3", + "equip_audio": "2239", "equipment_slot": "4", + "lendable": "true", "remove_sleeves": "true", - "grand_exchange_price": "122", - "name": "Yak-hide armour", + "requirements": "{1,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10822", - "bonuses": "0,0,0,-5,0,25,20,15,-2,25,5,0,0,0,0" + "weight": "9.07" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "122", - "durability": null, - "name": "Yak-hide armour", - "tradeable": "true", + "id": "10802", + "name": "Tan cavalier", + "examine": "All for one and one for all!", "archery_ticket_price": "0", - "id": "10823" + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" }, { - "requirements": "{1,20}", - "ge_buy_limit": "100", - "grand_exchange_price": "83", - "examine": "Leg protection, made from smelly yak-hide.", - "durability": null, - "name": "Yak-hide armour", - "tradeable": "true", + "id": "10804", + "name": "Dark cavalier", + "examine": "All for one and one for all!", "archery_ticket_price": "0", - "weight": "2", - "id": "10824", - "bonuses": "0,0,0,-5,10,25,20,15,-2,10,0,0,0,0,0", - "equipment_slot": "7" + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "83", - "durability": null, - "name": "Yak-hide armour", - "tradeable": "true", + "id": "10806", + "name": "Black cavalier", + "examine": "All for one and one for all!", "archery_ticket_price": "0", - "id": "10825" + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true" }, { - "requirements": "{1,25}", - "ge_buy_limit": "100", - "examine": "A wooden shield with a rope rim.", + "id": "10808", + "name": "Arctic pyre logs", + "examine": "Arctic Pine logs prepared with sacred oil for a funeral pyre", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10809", + "name": "Arctic pyre logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "10810", + "name": "Arctic pine logs", + "examine": "Log cut from an arctic pine.", + "archery_ticket_price": "0", "durability": null, - "destroy": "true", - "weight": "3", "equipment_slot": "5", - "grand_exchange_price": "402", - "name": "Fremennik round shield", + "ge_buy_limit": "25000", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10826", - "bonuses": "0,0,0,-10,-10,17,17,31,-4,33,20,0,0,0,0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "402", + "id": "10811", + "name": "Arctic pine logs", + "archery_ticket_price": "0", "durability": null, - "name": "Fremennik round shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10827" + "ge_buy_limit": "25000", + "tradeable": "true" }, { + "id": "10812", + "name": "Split log", + "examine": "Used to repair bridges.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "10813", + "name": "Split log", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "10814", + "name": "Hair", + "examine": "I can spin this into rope.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "10815", + "name": "Hair", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "10816", + "name": "Raw yak meat", + "examine": "I need to cook this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "2", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10817", + "name": "Raw yak meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "10818", + "name": "Yak-hide", + "examine": "Thakkrad, of Neitiznot, can cure this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "50", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10819", + "name": "Yak-hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10820", + "name": "Cured yak-hide", + "examine": "Ready to be cut and sewn into armour.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.4" + }, + { + "id": "10821", + "name": "Cured yak-hide", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "10822", + "name": "Yak-hide armour", + "examine": "Smelly yak body armour.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,0,25,20,15,-2,25,5,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "requirements": "{1,20}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10823", + "name": "Yak-hide armour", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10824", + "name": "Yak-hide armour", + "examine": "Leg protection, made from smelly yak-hide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,10,25,20,15,-2,10,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "requirements": "{1,20}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "10825", + "name": "Yak-hide armour", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10826", + "name": "Fremennik round shield", + "examine": "A wooden shield with a rope rim.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-10,17,17,31,-4,33,20,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,25}", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10827", + "name": "Fremennik round shield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10828", + "name": "Helm of neitiznot", + "examine": "A gift from Neitiznot's Burgher.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{1,55}", "shop_price": "50000", - "ge_buy_limit": "100", - "examine": "A gift from Neitiznot's Burgher.", - "durability": null, - "weight": "2.2", - "absorb": "2,0,4", - "equipment_slot": "0", - "grand_exchange_price": "44800", - "name": "Helm of neitiznot", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10828", - "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0" + "weight": "2.2" }, { - "destroy_message": "King Sorvott of Jatizso will give you another one, grudgingly.", - "examine": "The document is stamped with King Gjuki Sorvott IV's royal seal.", - "durability": null, + "id": "10830", "name": "Royal decree", - "tradeable": "false", - "destroy": "true", + "examine": "The document is stamped with King Gjuki Sorvott IV's royal seal.", "archery_ticket_price": "0", - "id": "10830" + "destroy": "true", + "destroy_message": "King Sorvott of Jatizso will give you another one, grudgingly.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Are you sure? You can replace it by talking to King Sorvott.", - "examine": "An empty tax bag.", - "durability": null, + "id": "10831", "name": "Empty tax bag", - "tradeable": "false", - "destroy": "true", + "examine": "An empty tax bag.", "archery_ticket_price": "0", - "id": "10831" + "destroy": "true", + "destroy_message": "Are you sure? You can replace it by talking to King Sorvott.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", - "examine": "A silly hat with bells.", - "durability": null, - "name": "Silly jester hat", - "tradeable": "false", - "destroy": "true", - "weight": "2.7", - "archery_ticket_price": "0", "id": "10836", + "name": "Silly jester hat", + "examine": "A silly hat with bells.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", - "equipment_slot": "0" + "destroy": "true", + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "2.7" }, { - "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", - "remove_sleeves": "true", - "examine": "A jester's jangly top.", - "durability": null, - "name": "Silly jester top", - "tradeable": "false", - "destroy": "true", - "weight": "6.8", - "archery_ticket_price": "0", "id": "10837", + "name": "Silly jester top", + "examine": "A jester's jangly top.", + "archery_ticket_price": "0", "bonuses": "0,0,0,0,0,0,0,0,5,-5,5,0,0,0,0", - "equipment_slot": "4" - }, - { + "destroy": "true", "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", - "examine": "Silly jester tights.", "durability": null, - "name": "Silly jester tights", - "tradeable": "false", - "destroy": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "10838", - "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", - "examine": "Silly jester boots.", - "durability": null, - "name": "Silly jester boots", - "tradeable": "false", - "destroy": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "10839", - "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "durability": null, - "name": "A jester stick", - "archery_ticket_price": "0", - "id": "10840", - "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", - "alchemizable": "true", - "equipment_slot": "3" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", - "durability": null, - "name": "Decapitated head", - "weight": "3", - "archery_ticket_price": "0", - "id": "10842" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "44800", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Helm of neitiznot", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10843" - }, - { - "examine": "A slightly sq'irky, I mean quirky, fruit.", - "durability": null, - "name": "Spring sq'irk", - "archery_ticket_price": "0", - "id": "10844" - }, - { - "examine": "A slightly sq'irky, I mean quirky, fruit.", - "durability": null, - "name": "Summer sq'irk", - "archery_ticket_price": "0", - "id": "10845" - }, - { - "examine": "A slightly sq'irky, I mean quirky, fruit.", - "durability": null, - "name": "Autumn sq'irk", - "archery_ticket_price": "0", - "id": "10846" - }, - { - "examine": "A slightly sq'irky, I mean quirky, fruit.", - "durability": null, - "name": "Winter sq'irk", - "archery_ticket_price": "0", - "id": "10847" - }, - { - "examine": "Made from 4 spring sq'irks.", - "durability": null, - "name": "Spring sq'irkjuice", - "weight": "1", - "archery_ticket_price": "0", - "id": "10848" - }, - { - "examine": "Made from 2 summer sq'irks.", - "durability": null, - "name": "Summer sq'irkjuice", - "weight": "1", - "archery_ticket_price": "0", - "id": "10849" - }, - { - "examine": "Made from 3 autumn sq'irks.", - "durability": null, - "name": "Autumn sq'irkjuice", - "weight": "1", - "archery_ticket_price": "0", - "id": "10850" - }, - { - "examine": "Made from 5 winter sq'irks.", - "durability": null, - "name": "Winter sq'irkjuice", - "archery_ticket_price": "0", - "id": "10851" - }, - { - "destroy_message": "You will need to speak to Sin Seer in Seers' Village to get another one.", - "shop_price": "40", - "examine": "Her writing is too scrawled to make out what it says.", - "durability": null, - "name": "Sin seer's note", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10856" - }, - { - "destroy_message": "You will need to speak to General Khazard, near the Fremennik Province, to get another.", - "examine": "A severed human leg.", - "durability": null, - "name": "Severed leg", - "tradeable": "false", - "destroy": "true", - "weight": "12", - "archery_ticket_price": "0", - "id": "10857" - }, - { - "turn90cw_anim": "7044", - "examine": "A shadow sword.", - "walk_anim": "7046", - "durability": null, - "destroy": "true", - "weight": "3.6", - "turn90ccw_anim": "7043", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "7", - "turn180_anim": "7045", - "render_anim": "124", - "equipment_slot": "3", - "destroy_message": "You can get another one by visiting the cave near the Fishing guild. A friendly ghost will replace it for you. You must be wearing a Ring of visibility, or you cannot get it back.", - "stand_anim": "7047", - "name": "Shadow sword", - "tradeable": "false", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "10858", - "stand_turn_anim": "7040", - "bonuses": "-4,27,21,4,0,0,0,0,4,-1,0,26,0,0,0" - }, - { - "examine": "You can put nice, hot tea in it.", - "durability": null, - "name": "Tea flask", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10859" - }, - { - "examine": "You can put nice, hot tea in it.", - "durability": null, - "name": "Tea flask", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10860" - }, - { - "examine": "You can put nice, hot tea in it.", - "durability": null, - "name": "Tea flask", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10861" - }, - { - "destroy_message": "You'll have to find another within the Tower of Life!", - "examine": "Can't get any safer than this.", - "durability": null, - "name": "Hard hat", - "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10862", - "equipment_slot": "0" - }, - { - "destroy_message": "You'll have to find another within the Tower of Life!", - "remove_sleeves": "true", - "examine": "Very fetching.", - "durability": null, - "name": "Builder's shirt", - "tradeable": "false", - "destroy": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "10863", - "equipment_slot": "4" - }, - { - "destroy_message": "You'll have to find another within the Tower of Life!", - "examine": "Slightly tatty in my opinion.", - "durability": null, - "name": "Builder's trousers", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10864", - "equipment_slot": "7" - }, - { - "destroy_message": "You'll have to find another within the Tower of Life!", - "examine": "They'll offer good protection for my toes.", - "durability": null, - "name": "Builder's boots", - "tradeable": "false", - "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10865", - "equipment_slot": "10" - }, - { - "examine": "Used to bolt things together.", - "durability": null, - "name": "Rivets", - "archery_ticket_price": "0", - "id": "10866" - }, - { - "examine": "Some magical fluid to bind surfaces.", - "durability": null, - "name": "Binding fluid", - "archery_ticket_price": "0", - "id": "10870" - }, - { - "examine": "A pipe that belongs in a cannon stand.", - "durability": null, - "name": "Pipe", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "10871" - }, - { - "examine": "A ring used to join two pipes together.", - "durability": null, - "name": "Pipe ring", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10872" - }, - { - "examine": "A sheet of metal.", - "durability": null, - "name": "Metal sheet", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10873" - }, - { - "examine": "Bound to have some use.", - "durability": null, - "name": "Coloured ball", - "archery_ticket_price": "0", - "id": "10874" - }, - { - "examine": "A wheel used to control valves.", - "durability": null, - "name": "Valve wheel", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10875" - }, - { - "examine": "Some unknown metal substance.", - "durability": null, - "name": "Metal bar", - "archery_ticket_price": "0", - "id": "10876" - }, - { - "shop_price": "128", - "examine": "I can keep my grub in here.", - "durability": null, - "name": "Plain satchel", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10877", - "equipment_slot": "5" - }, - { - "examine": "I can keep my grub in here.", - "durability": null, - "name": "Green satchel", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10878", - "equipment_slot": "5" - }, - { - "shop_price": "128", - "examine": "I can keep my grub in here.", - "durability": null, - "name": "Red satchel", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10879", - "equipment_slot": "5" - }, - { - "examine": "I can keep my grub in here.", - "durability": null, - "name": "Black satchel", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10880", - "equipment_slot": "5" - }, - { - "examine": "I can keep my grub in here.", - "durability": null, - "name": "Gold satchel", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10881", - "equipment_slot": "5" - }, - { - "examine": "I can keep my grub in here.", - "durability": null, - "name": "Rune satchel", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "10882", - "equipment_slot": "5" - }, - { - "destroy_message": "You'll have to find another within the Tower of Life!", - "examine": "Can't get any safer than this.", - "durability": null, - "name": "Hard hat", - "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "10883", - "equipment_slot": "0" - }, - { - "examine": "A fuse.", - "durability": null, - "name": "Fuse", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10884" - }, - { - "examine": "A small keg of gunpowder.", - "durability": null, - "name": "Keg", - "weight": "12", - "archery_ticket_price": "0", - "id": "10885" - }, - { - "examine": "Used to cure poison through prayer.", - "durability": null, - "name": "Prayer book", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10886" - }, - { - "turn90cw_anim": "5867", - "examine": "This is likely to put my back out... (when fixed) OR It's broken. I should see if a pirate smith can fix it. (when broken)", - "walk_anim": "5867", - "has_special": "true", - "durability": null, - "weight": "30", - "turn90ccw_anim": "5867", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "8", - "turn180_anim": "5867", - "defence_anim": "5866", - "render_anim": "985", - "equipment_slot": "3", - "attack_anims": "5865,5865,5865,5865", - "destroy_message": "If you drop the Anchor it will be destroyed, and you will need to get a new one from Brother Tranquillity, then pay Smith to re", - "stand_anim": "5869", - "name": "Barrelchest anchor", - "run_anim": "5868", - "archery_ticket_price": "0", - "id": "10887", - "stand_turn_anim": "823", - "bonuses": "-2,10,92,0,0,0,0,0,0,0,0,100,0,0,0" - }, - { - "examine": "This is likely to put my back out... (when fixed) OR It's broken. I should see if a pirate smith can fix it. (when broken)", - "durability": null, - "name": "Barrelchest anchor", - "weight": "30", - "archery_ticket_price": "0", - "attack_speed": "6", - "id": "10888", - "bonuses": "-2,10,92,0,0,0,0,0,0,0,0,100,0,0,0" - }, - { - "destroy_message": "If you drop this lamp it will be destroyed, and you will need to see Brother Tranquility for another.", - "examine": "This will answer my prayers.", - "durability": null, - "name": "Blessed lamp", - "archery_ticket_price": "0", - "id": "10889" - }, - { - "destroy_message": "This book is old and delicate. You can reclaim this item from the place you found it.ping it here will destroy it and you will have to search the Edgeville Monastery bookcase for another.", - "examine": "Used to cure poison through prayer.", - "durability": null, - "name": "Prayer book", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10890" - }, - { - "ge_buy_limit": "100", - "examine": "A wooden cat toy.", - "grand_exchange_price": "922", - "durability": null, - "name": "Wooden cat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10891" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "922", - "durability": null, - "name": "Wooden cat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10892" - }, - { - "examine": "A cranial clamp.", - "durability": null, - "name": "Cranial clamp", - "archery_ticket_price": "0", - "id": "10893" - }, - { - "examine": "Some tongs for use with brains.", - "durability": null, - "name": "Brain tongs", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10894" - }, - { - "examine": "A bell jar for covering things.", - "durability": null, - "name": "Bell jar", - "weight": "1", - "archery_ticket_price": "0", - "id": "10895" - }, - { - "examine": "A silver whistle.", - "durability": null, - "name": "Wolf whistle", - "archery_ticket_price": "0", - "id": "10896" - }, - { - "examine": "A shipping order list.", - "durability": null, - "name": "Shipping order", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10897" - }, - { - "examine": "A small keg of gunpowder.", - "durability": null, - "name": "Keg", - "weight": "12", - "archery_ticket_price": "0", - "id": "10898" - }, - { - "examine": "Part of a crate.", - "durability": null, - "name": "Crate part", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10899" - }, - { - "examine": "One skull staple.", - "durability": null, - "name": "Skull staple", - "archery_ticket_price": "0", - "id": "10904" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore and unicorn dust potion needs more ingredients.", - "grand_exchange_price": "8420", - "durability": null, - "name": "Mixture - step 1(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10909" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8420", - "durability": null, - "name": "Mixture - step 1(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10910" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore and unicorn dust potion needs more ingredients.", - "grand_exchange_price": "6543", - "durability": null, - "name": "Mixture - step 1(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10911" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6543", - "durability": null, - "name": "Mixture - step 1(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10912" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore and unicorn dust potion needs more ingredients.", - "grand_exchange_price": "4335", - "durability": null, - "name": "Mixture - step 1(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10913" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4335", - "durability": null, - "name": "Mixture - step 1(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10914" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore and unicorn dust potion needs more ingredients.", - "grand_exchange_price": "2168", - "durability": null, - "name": "Mixture - step 1(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10915" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2168", - "durability": null, - "name": "Mixture - step 1(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10916" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", - "grand_exchange_price": "8665", - "durability": null, - "name": "Mixture - step 2(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10917" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8665", - "durability": null, - "name": "Mixture - step 2(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10918" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", - "grand_exchange_price": "6695", - "durability": null, - "name": "Mixture - step 2(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10919" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6695", - "durability": null, - "name": "Mixture - step 2(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10920" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", - "grand_exchange_price": "4335", - "durability": null, - "name": "Mixture - step 2(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10921" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4335", - "durability": null, - "name": "Mixture - step 2(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10922" - }, - { - "ge_buy_limit": "100", - "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", - "grand_exchange_price": "2168", - "durability": null, - "name": "Mixture - step 2(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10923" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2168", - "durability": null, - "name": "Mixture - step 2(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10924" - }, - { - "ge_buy_limit": "100", - "examine": "A \"X\" dose Sanfew Serum.", - "grand_exchange_price": "15900", - "durability": null, - "name": "Sanfew serum(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10925" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "15900", - "durability": null, - "name": "Sanfew serum(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10926" - }, - { - "ge_buy_limit": "100", - "examine": "A \"X\" dose Sanfew Serum.", - "grand_exchange_price": "12000", - "durability": null, - "name": "Sanfew serum(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10927" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12000", - "durability": null, - "name": "Sanfew serum(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10928" - }, - { - "ge_buy_limit": "100", - "examine": "A \"X\" dose Sanfew Serum.", - "grand_exchange_price": "10200", - "durability": null, - "name": "Sanfew serum(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10929" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "10200", - "durability": null, - "name": "Sanfew serum(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10930" - }, - { - "ge_buy_limit": "100", - "examine": "A \"X\" dose Sanfew Serum.", - "grand_exchange_price": "6114", - "durability": null, - "name": "Sanfew serum(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10931" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "6114", - "durability": null, - "name": "Sanfew serum(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10932" - }, - { - "examine": "You certainly will be alright wearing these.", - "durability": null, - "name": "Lumberjack boots", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "10933", - "equipment_slot": "10" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10934" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10935" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10936" - }, - { - "ge_buy_limit": "100", - "examine": "The claws from a nail beast", - "grand_exchange_price": "203", - "durability": null, - "name": "Nail beast nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10937" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "203", - "durability": null, - "name": "Nail beast nails", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10938" - }, - { - "remove_sleeves": "true", - "examine": "You certainly will be alright wearing this.", - "durability": null, - "name": "Lumberjack top", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "10939", - "equipment_slot": "4" - }, - { - "examine": "You certainly will be alright wearing these.", - "durability": null, - "name": "Lumberjack legs", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "10940", - "equipment_slot": "7" - }, - { - "remove_head": "true", - "examine": "You certainly will be alright wearing this.", - "durability": null, - "name": "Lumberjack hat", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "10941", - "equipment_slot": "0" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10942" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10943" - }, - { - "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", - "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", - "durability": null, - "name": "Reward token", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10944" - }, - { - "remove_sleeves": "true", - "examine": "You certainly will be alright wearing this.", - "durability": null, - "name": "Lumberjack top", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "10945", - "equipment_slot": "4" - }, - { - "examine": "One skull staple.", - "durability": null, - "name": "Skull staples", - "archery_ticket_price": "0", - "id": "10950" - }, - { - "examine": "One skull staple.", - "durability": null, - "name": "Skull staples", - "archery_ticket_price": "0", - "id": "10951" - }, - { - "requirements": "{18,39}", - "shop_price": "150", - "ge_buy_limit": "100", - "examine": "Don't make anyone jump when you ring this!", - "grand_exchange_price": "57", - "durability": null, - "name": "Slayer bell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10952" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "57", - "durability": null, - "name": "Slayer bell", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10953" - }, - { - "requirements": "{1,25}-{4,25}", - "shop_price": "1000", - "ge_buy_limit": "100", - "examine": "Armour made out of Frog hide.", - "durability": null, - "weight": "3", - "absorb": "0,3,1", "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "1797", - "name": "Frog-leather body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10954", - "bonuses": "0,0,0,-5,10,23,26,30,15,32,20,0,0,0,0" + "tradeable": "false", + "weight": "6.8" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1797", + "id": "10838", + "name": "Silly jester tights", + "examine": "Silly jester tights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", "durability": null, - "name": "Frog-leather body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10955" + "equipment_slot": "7", + "tradeable": "false", + "weight": "0.9" }, { + "id": "10839", + "name": "Silly jester boots", + "examine": "Silly jester boots.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", + "durability": null, + "equipment_slot": "10", + "tradeable": "false", + "weight": "1.3" + }, + { + "id": "10840", + "name": "A jester stick", + "alchemizable": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "10842", + "name": "Decapitated head", + "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "weight": "3" + }, + { + "id": "10843", + "name": "Helm of neitiznot", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10844", + "name": "Spring sq'irk", + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10845", + "name": "Summer sq'irk", + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10846", + "name": "Autumn sq'irk", + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10847", + "name": "Winter sq'irk", + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10848", + "name": "Spring sq'irkjuice", + "examine": "Made from 4 spring sq'irks.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "10849", + "name": "Summer sq'irkjuice", + "examine": "Made from 2 summer sq'irks.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "10850", + "name": "Autumn sq'irkjuice", + "examine": "Made from 3 autumn sq'irks.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "10851", + "name": "Winter sq'irkjuice", + "examine": "Made from 5 winter sq'irks.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10856", + "name": "Sin seer's note", + "examine": "Her writing is too scrawled to make out what it says.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Sin Seer in Seers' Village to get another one.", + "durability": null, + "shop_price": "40", + "tradeable": "false" + }, + { + "id": "10857", + "name": "Severed leg", + "examine": "A severed human leg.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to General Khazard, near the Fremennik Province, to get another.", + "durability": null, + "tradeable": "false", + "weight": "12" + }, + { + "id": "10858", + "name": "Shadow sword", + "examine": "A shadow sword.", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "-4,27,21,4,0,0,0,0,4,-1,0,26,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one by visiting the cave near the Fishing guild. A friendly ghost will replace it for you. You must be wearing a Ring of visibility, or you cannot get it back.", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "124", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "false", + "turn180_anim": "7045", + "turn90ccw_anim": "7043", + "turn90cw_anim": "7044", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3.6" + }, + { + "id": "10859", + "name": "Tea flask", + "examine": "You can put nice, hot tea in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "10860", + "name": "Tea flask", + "examine": "You can put nice, hot tea in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "10861", + "name": "Tea flask", + "examine": "You can put nice, hot tea in it.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "10862", + "name": "Hard hat", + "examine": "Can't get any safer than this.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to find another within the Tower of Life!", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "2" + }, + { + "id": "10863", + "name": "Builder's shirt", + "examine": "Very fetching.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to find another within the Tower of Life!", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "0.9" + }, + { + "id": "10864", + "name": "Builder's trousers", + "examine": "Slightly tatty in my opinion.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to find another within the Tower of Life!", + "durability": null, + "equipment_slot": "7", + "tradeable": "false", + "weight": "1" + }, + { + "id": "10865", + "name": "Builder's boots", + "examine": "They'll offer good protection for my toes.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to find another within the Tower of Life!", + "durability": null, + "equipment_slot": "10", + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "10866", + "name": "Rivets", + "examine": "Used to bolt things together.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10870", + "name": "Binding fluid", + "examine": "Some magical fluid to bind surfaces.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10871", + "name": "Pipe", + "examine": "A pipe that belongs in a cannon stand.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "10872", + "name": "Pipe ring", + "examine": "A ring used to join two pipes together.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10873", + "name": "Metal sheet", + "examine": "A sheet of metal.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10874", + "name": "Coloured ball", + "examine": "Bound to have some use.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10875", + "name": "Valve wheel", + "examine": "A wheel used to control valves.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10876", + "name": "Metal bar", + "examine": "Some unknown metal substance.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10877", + "name": "Plain satchel", + "examine": "I can keep my grub in here.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "shop_price": "128", + "weight": "0.1" + }, + { + "id": "10878", + "name": "Green satchel", + "examine": "I can keep my grub in here.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "weight": "0.1" + }, + { + "id": "10879", + "name": "Red satchel", + "examine": "I can keep my grub in here.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "shop_price": "128", + "weight": "0.1" + }, + { + "id": "10880", + "name": "Black satchel", + "examine": "I can keep my grub in here.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "weight": "0.1" + }, + { + "id": "10881", + "name": "Gold satchel", + "examine": "I can keep my grub in here.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "weight": "0.1" + }, + { + "id": "10882", + "name": "Rune satchel", + "examine": "I can keep my grub in here.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "5", + "weight": "0.1" + }, + { + "id": "10883", + "name": "Hard hat", + "examine": "Can't get any safer than this.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll have to find another within the Tower of Life!", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "2" + }, + { + "id": "10884", + "name": "Fuse", + "examine": "A fuse.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10885", + "name": "Keg", + "examine": "A small keg of gunpowder.", + "archery_ticket_price": "0", + "durability": null, + "weight": "12" + }, + { + "id": "10886", + "name": "Prayer book", + "examine": "Used to cure poison through prayer.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "10887", + "name": "Barrelchest anchor", + "examine": "This is likely to put my back out... (when fixed) OR It's broken. I should see if a pirate smith can fix it. (when broken)", + "archery_ticket_price": "0", + "attack_anims": "5865,5865,5865,5865", + "attack_speed": "6", + "bonuses": "-2,10,92,0,0,0,0,0,0,0,0,100,0,0,0", + "defence_anim": "5866", + "destroy_message": "If you drop the Anchor it will be destroyed, and you will need to get a new one from Brother Tranquillity, then pay Smith to re", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "985", + "run_anim": "5868", + "stand_anim": "5869", + "stand_turn_anim": "823", + "turn180_anim": "5867", + "turn90ccw_anim": "5867", + "turn90cw_anim": "5867", + "two_handed": "true", + "walk_anim": "5867", + "weapon_interface": "8", + "weight": "30" + }, + { + "id": "10888", + "name": "Barrelchest anchor", + "examine": "This is likely to put my back out... (when fixed) OR It's broken. I should see if a pirate smith can fix it. (when broken)", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "-2,10,92,0,0,0,0,0,0,0,0,100,0,0,0", + "durability": null, + "weight": "30" + }, + { + "id": "10889", + "name": "Blessed lamp", + "examine": "This will answer my prayers.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this lamp it will be destroyed, and you will need to see Brother Tranquility for another.", + "durability": null + }, + { + "id": "10890", + "name": "Prayer book", + "examine": "Used to cure poison through prayer.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "This book is old and delicate. You can reclaim this item from the place you found it.ping it here will destroy it and you will have to search the Edgeville Monastery bookcase for another.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "10891", + "name": "Wooden cat", + "examine": "A wooden cat toy.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10892", + "name": "Wooden cat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10893", + "name": "Cranial clamp", + "examine": "A cranial clamp.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10894", + "name": "Brain tongs", + "examine": "Some tongs for use with brains.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10895", + "name": "Bell jar", + "examine": "A bell jar for covering things.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "10896", + "name": "Wolf whistle", + "examine": "A silver whistle.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10897", + "name": "Shipping order", + "examine": "A shipping order list.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10898", + "name": "Keg", + "examine": "A small keg of gunpowder.", + "archery_ticket_price": "0", + "durability": null, + "weight": "12" + }, + { + "id": "10899", + "name": "Crate part", + "examine": "Part of a crate.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "10904", + "name": "Skull staple", + "examine": "One skull staple.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10909", + "name": "Mixture - step 1(4)", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10910", + "name": "Mixture - step 1(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10911", + "name": "Mixture - step 1(3)", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10912", + "name": "Mixture - step 1(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10913", + "name": "Mixture - step 1(2)", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10914", + "name": "Mixture - step 1(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10915", + "name": "Mixture - step 1(1)", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10916", + "name": "Mixture - step 1(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10917", + "name": "Mixture - step 2(4)", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10918", + "name": "Mixture - step 2(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10919", + "name": "Mixture - step 2(3)", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10920", + "name": "Mixture - step 2(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10921", + "name": "Mixture - step 2(2)", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10922", + "name": "Mixture - step 2(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10923", + "name": "Mixture - step 2(1)", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10924", + "name": "Mixture - step 2(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10925", + "name": "Sanfew serum(4)", + "examine": "A \"X\" dose Sanfew Serum.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10926", + "name": "Sanfew serum(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10927", + "name": "Sanfew serum(3)", + "examine": "A \"X\" dose Sanfew Serum.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10928", + "name": "Sanfew serum(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10929", + "name": "Sanfew serum(2)", + "examine": "A \"X\" dose Sanfew Serum.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10930", + "name": "Sanfew serum(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10931", + "name": "Sanfew serum(1)", + "examine": "A \"X\" dose Sanfew Serum.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10932", + "name": "Sanfew serum(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10933", + "name": "Lumberjack boots", + "examine": "You certainly will be alright wearing these.", + "archery_ticket_price": "0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "weight": "0.9" + }, + { + "id": "10934", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10935", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10936", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10937", + "name": "Nail beast nails", + "examine": "The claws from a nail beast", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10938", + "name": "Nail beast nails", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10939", + "name": "Lumberjack top", + "examine": "You certainly will be alright wearing this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "1.3" + }, + { + "id": "10940", + "name": "Lumberjack legs", + "examine": "You certainly will be alright wearing these.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "weight": "0.9" + }, + { + "id": "10941", + "name": "Lumberjack hat", + "examine": "You certainly will be alright wearing this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "0.4" + }, + { + "id": "10942", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10943", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10944", + "name": "Reward token", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "10945", + "name": "Lumberjack top", + "examine": "You certainly will be alright wearing this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "weight": "1.3" + }, + { + "id": "10950", + "name": "Skull staples", + "examine": "One skull staple.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10951", + "name": "Skull staples", + "examine": "One skull staple.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "10952", + "name": "Slayer bell", + "examine": "Don't make anyone jump when you ring this!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{18,39}", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "10953", + "name": "Slayer bell", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10954", + "name": "Frog-leather body", + "examine": "Armour made out of Frog hide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,10,23,26,30,15,32,20,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "requirements": "{1,25}-{4,25}", + "shop_price": "1000", + "tradeable": "true", + "weight": "3" + }, + { + "id": "10955", + "name": "Frog-leather body", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "10956", + "name": "Frog-leather chaps", + "examine": "Chaps made out of Frog hide.", + "absorb": "0,2,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,2,7,7,9,4,9,5,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", "requirements": "{1,25}-{4,25}", "shop_price": "900", - "ge_buy_limit": "100", - "examine": "Chaps made out of Frog hide.", - "durability": null, - "weight": "3", - "absorb": "0,2,1", - "equipment_slot": "7", - "grand_exchange_price": "361", - "name": "Frog-leather chaps", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10956", - "bonuses": "0,0,0,-5,2,7,7,9,4,9,5,0,0,0,0" + "weight": "3" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "361", - "durability": null, + "id": "10957", "name": "Frog-leather chaps", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10957" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { + "id": "10958", + "name": "Frog-leather boots", + "examine": "Boots made out of Frog hide.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,2,1,1,1,0,1,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "ge_buy_limit": "100", "requirements": "{1,25}-{4,25}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "Boots made out of Frog hide.", - "durability": null, - "weight": "1", - "equipment_slot": "10", - "grand_exchange_price": "1156", - "name": "Frog-leather boots", "tradeable": "true", - "archery_ticket_price": "0", - "id": "10958", - "bonuses": "0,0,0,-8,2,1,1,1,0,1,0,0,0,0,0" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1156", - "durability": null, + "id": "10959", "name": "Frog-leather boots", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10959" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "10", - "examine": "Thick and tasty soup.", - "durability": null, + "id": "10960", "name": "Green gloop soup", + "examine": "Thick and tasty soup.", "archery_ticket_price": "0", - "id": "10960" + "durability": null, + "shop_price": "10" }, { - "shop_price": "10", - "examine": "A big bowl of frogspawn gumbo.", - "durability": null, + "id": "10961", "name": "Frogspawn gumbo", + "examine": "A big bowl of frogspawn gumbo.", "archery_ticket_price": "0", - "id": "10961" + "durability": null, + "shop_price": "10" }, { - "shop_price": "10", - "examine": "A juicy frogburger.", - "durability": null, + "id": "10962", "name": "Frogburger", - "weight": "1", + "examine": "A juicy frogburger.", "archery_ticket_price": "0", - "id": "10962" + "durability": null, + "shop_price": "10", + "weight": "1" }, { - "examine": "Nice and crunchy.", - "durability": null, + "id": "10963", "name": "Coated frogs' legs", + "examine": "Nice and crunchy.", "archery_ticket_price": "0", - "id": "10963" + "durability": null }, { - "shop_price": "10", - "examine": "Bat shish kebab.", - "durability": null, + "id": "10964", "name": "Bat shish", + "examine": "Bat shish kebab.", "archery_ticket_price": "0", - "id": "10964" + "durability": null, + "shop_price": "10" }, { - "shop_price": "10", - "examine": "Wall beast fingers in a white fern sauce.", - "durability": null, + "id": "10965", "name": "Fingers", + "examine": "Wall beast fingers in a white fern sauce.", "archery_ticket_price": "0", - "id": "10965" + "durability": null, + "shop_price": "10" }, { - "examine": "A whole roasted frog.", - "durability": null, + "id": "10967", "name": "Roast frog", - "weight": "1", + "examine": "A whole roasted frog.", "archery_ticket_price": "0", - "id": "10967" + "durability": null, + "weight": "1" }, { - "examine": "Tasty saut??ed mushrooms.", - "durability": null, + "id": "10968", "name": "Mushrooms", + "examine": "Tasty saut??ed mushrooms.", "archery_ticket_price": "0", - "id": "10968" + "durability": null }, { - "examine": "Chunky cave-crawler fillets.", - "durability": null, + "id": "10969", "name": "Fillets", + "examine": "Chunky cave-crawler fillets.", "archery_ticket_price": "0", - "id": "10969" + "durability": null }, { - "examine": "Steamed cave pond loach.", - "durability": null, + "id": "10970", "name": "Loach", - "weight": "1", + "examine": "Steamed cave pond loach.", "archery_ticket_price": "0", - "id": "10970" + "durability": null, + "weight": "1" }, { - "examine": "Cave-eel sushi.", - "durability": null, + "id": "10971", "name": "Eel sushi", + "examine": "Cave-eel sushi.", "archery_ticket_price": "0", - "id": "10971" + "durability": null }, { - "shop_price": "2", - "examine": "Oldak's Marvellous Moving-Over-Distance Sphere.", - "durability": null, + "id": "10972", "name": "Dorgesh-kaan sphere", - "weight": "0.5", + "examine": "Oldak's Marvellous Moving-Over-Distance Sphere.", "archery_ticket_price": "0", - "id": "10972" + "durability": null, + "shop_price": "2", + "weight": "0.5" }, { - "requirements": "{11,52}", - "ge_buy_limit": "1000", + "id": "10973", + "name": "Light orb", "examine": "A component of cave goblin Magic.", - "grand_exchange_price": "90", - "durability": null, - "name": "Light orb", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10973" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "90", - "durability": null, - "name": "Light orb", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "10974" + "requirements": "{11,52}", + "tradeable": "true" }, { - "examine": "A goblin wrench.", + "id": "10974", + "name": "Light orb", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "10975", "name": "Spanner", - "weight": "1", + "examine": "A goblin wrench.", "archery_ticket_price": "0", - "id": "10975" + "durability": null, + "weight": "1" }, { - "shop_price": "1000", - "examine": "A Construction bone.", - "durability": null, + "id": "10976", "name": "Long bone", - "weight": "1", + "examine": "A Construction bone.", "archery_ticket_price": "0", - "id": "10976" + "durability": null, + "shop_price": "1000", + "weight": "1" }, { - "shop_price": "2000", - "examine": "A curved Construction bone.", - "durability": null, + "id": "10977", "name": "Curved bone", - "weight": "1", + "examine": "A curved Construction bone.", "archery_ticket_price": "0", - "id": "10977" + "durability": null, + "shop_price": "2000", + "weight": "1" }, { - "ge_buy_limit": "500", + "id": "10978", + "name": "Swamp weed", "examine": "Swamp weed found in the caves near Dorgesh-Kaan.", - "grand_exchange_price": "292", - "durability": null, - "name": "Swamp weed", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", - "id": "10978" - }, - { + "durability": null, "ge_buy_limit": "500", - "grand_exchange_price": "292", - "durability": null, + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "10979", "name": "Swamp weed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10979" + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" }, { - "examine": "Add a wire to complete it.", - "durability": null, + "id": "10980", "name": "Empty light orb", + "examine": "Add a wire to complete it.", "archery_ticket_price": "0", - "id": "10980" + "durability": null }, { - "ge_buy_limit": "1000", + "id": "10981", + "name": "Cave goblin wire", "examine": "Wire found in Dorgesh-Kaan.", - "grand_exchange_price": "988", - "durability": null, - "name": "Cave goblin wire", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "10981" - }, - { + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "988", - "durability": null, + "tradeable": "true", + "weight": "1" + }, + { + "id": "10982", "name": "Cave goblin wire", - "tradeable": "true", "archery_ticket_price": "0", - "id": "10982" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "destroy_message": "You can get another cog from the old power station.", - "shop_price": "160", - "examine": "A cog. Broken: A broken cog.", - "durability": null, + "id": "10983", "name": "Cog", - "tradeable": "false", - "destroy": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "10983" - }, - { - "destroy_message": "You can get another cog from the old power station.", - "shop_price": "160", "examine": "A cog. Broken: A broken cog.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another cog from the old power station.", "durability": null, + "shop_price": "160", + "tradeable": "false", + "weight": "3" + }, + { + "id": "10984", "name": "Cog", - "tradeable": "false", - "destroy": "true", - "weight": "3", + "examine": "A cog. Broken: A broken cog.", "archery_ticket_price": "0", - "id": "10984" + "destroy": "true", + "destroy_message": "You can get another cog from the old power station.", + "durability": null, + "shop_price": "160", + "tradeable": "false", + "weight": "3" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A fuse.", - "durability": null, + "id": "10985", "name": "Fuse", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10985" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", "examine": "A fuse.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "tradeable": "false" + }, + { + "id": "10986", "name": "Fuse", - "tradeable": "false", - "destroy": "true", + "examine": "A fuse.", "archery_ticket_price": "0", - "id": "10986" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A meter.", - "durability": null, + "id": "10987", "name": "Meter", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "10987" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", "examine": "A meter.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, + "tradeable": "false" + }, + { + "id": "10988", "name": "Meter", - "tradeable": "false", - "destroy": "true", + "examine": "A meter.", "archery_ticket_price": "0", - "id": "10988" - }, - { + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A capacitor.", "durability": null, - "name": "Capacitor", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "10989" + "tradeable": "false" }, { + "id": "10989", + "name": "Capacitor", + "examine": "A capacitor.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A capacitor.", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "10990", "name": "Capacitor", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A capacitor.", "archery_ticket_price": "0", - "id": "10990" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "You can get another power box from the old power station.", - "examine": "A powerbox. Broken: A broken powerbox.", - "durability": null, + "id": "10993", "name": "Powerbox", - "tradeable": "false", - "destroy": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "10993" - }, - { - "destroy_message": "You can get another power box from the old power station.", "examine": "A powerbox. Broken: A broken powerbox.", - "durability": null, - "name": "Powerbox", - "tradeable": "false", - "destroy": "true", - "weight": "3", "archery_ticket_price": "0", - "id": "10994" + "destroy": "true", + "destroy_message": "You can get another power box from the old power station.", + "durability": null, + "tradeable": "false", + "weight": "3" }, { - "examine": "A perfect example of a tortoise shell.", + "id": "10994", + "name": "Powerbox", + "examine": "A powerbox. Broken: A broken powerbox.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another power box from the old power station.", "durability": null, + "tradeable": "false", + "weight": "3" + }, + { + "id": "10995", "name": "Perfect shell", - "weight": "6.8", + "examine": "A perfect example of a tortoise shell.", "archery_ticket_price": "0", - "id": "10995" + "durability": null, + "weight": "6.8" }, { - "examine": "A perfect example of a snail shell.", - "durability": null, + "id": "10996", "name": "Perfect snail shell", - "weight": "7", + "examine": "A perfect example of a snail shell.", "archery_ticket_price": "0", - "id": "10996" + "durability": null, + "weight": "7" }, { - "examine": "On wall: That white dot looks like an eye! Off wall: A strange mole-like being.", - "durability": null, + "id": "10997", "name": "Molanisk", + "examine": "On wall: That white dot looks like an eye! Off wall: A strange mole-like being.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "10997" + "durability": null }, { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "durability": null, + "id": "10998", "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", "archery_ticket_price": "0", - "id": "10998" + "durability": null }, { - "examine": "A tattered goblin holy book.", - "durability": null, + "id": "10999", "name": "Goblin book", - "weight": "0.1", + "examine": "A tattered goblin holy book.", "archery_ticket_price": "0", - "id": "10999" + "durability": null, + "weight": "0.1" }, { - "destroy_message": "You will need to get another copy from the Varrock Palace Library if you destroy this one.", - "examine": "The History of Dagon'hai.", - "durability": null, + "id": "11001", "name": "Dagon'hai history", - "tradeable": "false", - "destroy": "true", + "examine": "The History of Dagon'hai.", "archery_ticket_price": "0", - "id": "11001" - }, - { + "destroy": "true", "destroy_message": "You will need to get another copy from the Varrock Palace Library if you destroy this one.", - "examine": "The diary of Sin'keth Magis.", "durability": null, + "tradeable": "false" + }, + { + "id": "11002", "name": "Sin'keth's diary", - "tradeable": "false", - "destroy": "true", + "examine": "The diary of Sin'keth Magis.", "archery_ticket_price": "0", - "id": "11002" + "destroy": "true", + "destroy_message": "You will need to get another copy from the Varrock Palace Library if you destroy this one.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You will need to ask Rat for another empty folder if you destroy this one.", - "examine": "A folder for Rat's papers.", - "durability": null, + "id": "11003", "name": "An empty folder", - "tradeable": "false", - "destroy": "true", + "examine": "A folder for Rat's papers.", "archery_ticket_price": "0", - "id": "11003" + "destroy": "true", + "destroy_message": "You will need to ask Rat for another empty folder if you destroy this one.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A folder for rat's papers. It needs more pages.", - "durability": null, + "id": "11006", "name": "Used folder", - "tradeable": "false", - "destroy": "true", + "examine": "A folder for rat's papers. It needs more pages.", "archery_ticket_price": "0", - "id": "11006" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A full folder. You should take this back to Rat.", - "durability": null, + "id": "11007", "name": "Full folder", - "tradeable": "false", - "destroy": "true", + "examine": "A full folder. You should take this back to Rat.", "archery_ticket_price": "0", - "id": "11007" + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You will need to find more papers about the outlaws if you destroy this.", - "examine": "A page of Rat's document.", - "durability": null, + "id": "11008", "name": "Rat's paper", - "tradeable": "false", - "destroy": "true", + "examine": "A page of Rat's document.", "archery_ticket_price": "0", - "id": "11008" + "destroy": "true", + "destroy_message": "You will need to find more papers about the outlaws if you destroy this.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You will need to get another copy of the letter from Rat if you destroy this.", - "shop_price": "160", - "examine": "A letter in a strange language.", - "durability": null, + "id": "11009", "name": "Rat's letter", - "tradeable": "false", - "destroy": "true", + "examine": "A letter in a strange language.", "archery_ticket_price": "0", - "id": "11009" + "destroy": "true", + "destroy_message": "You will need to get another copy of the letter from Rat if you destroy this.", + "durability": null, + "shop_price": "160", + "tradeable": "false" }, { - "destroy_message": "You will need to ask Surok for another letter to Rat if you destroy this.", - "shop_price": "27", - "examine": "A letter.", - "durability": null, + "id": "11010", "name": "Surok's letter", - "tradeable": "false", - "destroy": "true", + "examine": "A letter.", "archery_ticket_price": "0", - "id": "11010" + "destroy": "true", + "destroy_message": "You will need to ask Surok for another letter to Rat if you destroy this.", + "durability": null, + "shop_price": "27", + "tradeable": "false" }, { - "examine": "Instructions for the beacon ring.", - "durability": null, + "id": "11011", "name": "Zaff's instructions", + "examine": "Instructions for the beacon ring.", "archery_ticket_price": "0", - "id": "11011" + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A wand.", - "durability": null, - "name": "Wand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "11012", - "equipment_slot": "3" - }, - { + "name": "Wand", + "examine": "A wand.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "This wand is glowing with chaos magic.", "durability": null, - "name": "Infused wand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11013", - "equipment_slot": "3" - }, - { - "destroy_message": "You will need to get another ring from Zaff if you destroy this one.", - "examine": "A magical ring.", - "durability": null, - "name": "Beacon ring", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11014", - "bonuses": "0,0,0,2,0,0,0,0,1,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "remove_head": "true", - "examine": "Cock-a-doodle-do!", - "durability": null, - "name": "Chicken head", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11015", - "equipment_slot": "0" - }, - { - "examine": "Perfect for crossing the road.", - "durability": null, - "name": "Chicken feet", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11016", - "equipment_slot": "10" - }, - { - "remove_sleeves": "true", - "examine": "I look fowl in this.", - "durability": null, - "name": "Chicken wings", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11017", - "equipment_slot": "4" - }, - { - "examine": "What's the matter, are you chicken?", - "durability": null, - "name": "Chicken legs", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11018", - "equipment_slot": "7" - }, - { - "destroy_message": "You will need to speak to Diango to get another pair of chicken feet.", - "examine": "Perfect for crossing the road.", - "durability": null, - "name": "Chicken feet", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11019", - "equipment_slot": "10" - }, - { - "destroy_message": "You will need to speak to Diango to get another set of chicken wings.", - "remove_sleeves": "true", - "examine": "I look fowl in this.", - "durability": null, - "name": "Chicken wings", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11020", - "equipment_slot": "4" - }, - { - "remove_head": "true", - "destroy_message": "You will need to speak to Diango to get another chicken head.", - "examine": "Cock-a-doodle-do!", - "durability": null, - "name": "Chicken head", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11021", - "equipment_slot": "0" - }, - { - "destroy_message": "You will need to speak to Diango to get another set of chicken legs.", - "examine": "What's the matter, are you chicken?", - "durability": null, - "name": "Chicken legs", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "11022", - "equipment_slot": "7" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Let's see how far the rabbit hole goes.", - "durability": null, - "name": "Magic egg", - "archery_ticket_price": "0", - "id": "11023" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Used for making chocolate rabbits.", - "durability": null, - "name": "Rabbit mould", - "archery_ticket_price": "0", - "id": "11024" - }, - { - "examine": "Some chocolate chunks.", - "durability": null, - "name": "Chocolate chunks", - "archery_ticket_price": "0", - "id": "11025" - }, - { - "examine": "Chocolatey kebbit goodness.", - "durability": null, - "name": "Chocolate kebbit", - "archery_ticket_price": "0", - "id": "11026" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11027", - "equipment_slot": "3" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11028", - "equipment_slot": "3" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11029", - "equipment_slot": "3" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11030", - "equipment_slot": "3" - }, - { - "destroy_message": "These logs will be destroyed if you drop them and you will need to see Olaf Hradson to get some more.", - "examine": "A number of dripping, waterlogged planks.", - "durability": null, - "name": "Damp planks", - "archery_ticket_price": "0", - "id": "11031" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A log with some squiggles carved into it.", - "durability": null, - "name": "Crude carving", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11032" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Another log with some sort of bird hacked into it.", - "durability": null, - "name": "Cruder carving", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11033" - }, - { - "destroy_message": "This map will be destroyed if you drop it and you will need to see Olaf Hradson to get another.", - "examine": "A faded map marking a cross next to a section of the landscape.", - "durability": null, - "name": "Sven's last map", - "archery_ticket_price": "0", - "id": "11034" - }, - { - "destroy_message": "These logs will be destroyed if you drop them and you will need to chop more from the windswept tree.", - "examine": "Logs taken from the exotic-looking windswept tree.", - "durability": null, - "name": "Windswept logs", - "archery_ticket_price": "0", - "id": "11035" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "examine": "A salty sword.", - "has_special": "true", - "durability": null, - "weight": "1.8", - "attack_speed": "4", - "weapon_interface": "6", "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "120200", - "name": "Brine sabre", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11037", - "bonuses": "7,47,-2,0,0,0,0,0,0,0,0,46,0,0,0" + "tradeable": "false" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "120200", - "durability": null, - "name": "Brine sabre", - "tradeable": "true", + "id": "11013", + "name": "Infused wand", + "examine": "This wand is glowing with chaos magic.", "archery_ticket_price": "0", - "id": "11038" - }, - { - "examine": "Looks like it might still float.", - "durability": null, - "name": "Rotten barrel", - "tradeable": "false", "destroy": "true", - "archery_ticket_price": "0", - "id": "11044" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Looks like it might still float.", "durability": null, - "name": "Rotten barrel", - "tradeable": "false", + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "11014", + "name": "Beacon ring", + "examine": "A magical ring.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,1,0,0,0,0,0,0", "destroy": "true", - "archery_ticket_price": "0", - "id": "11045" + "destroy_message": "You will need to get another ring from Zaff if you destroy this one.", + "durability": null, + "equipment_slot": "12", + "tradeable": "false" }, { - "shop_price": "18", - "examine": "A coil of rope.", - "grand_exchange_price": "101", + "id": "11015", + "name": "Chicken head", + "examine": "Cock-a-doodle-do!", + "archery_ticket_price": "0", + "destroy": "true", "durability": null, - "name": "Rope", + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11016", + "name": "Chicken feet", + "examine": "Perfect for crossing the road.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "10", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11017", + "name": "Chicken wings", + "examine": "I look fowl in this.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11018", + "name": "Chicken legs", + "examine": "What's the matter, are you chicken?", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "7", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11019", + "name": "Chicken feet", + "examine": "Perfect for crossing the road.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Diango to get another pair of chicken feet.", + "durability": null, + "equipment_slot": "10", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11020", + "name": "Chicken wings", + "examine": "I look fowl in this.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Diango to get another set of chicken wings.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11021", + "name": "Chicken head", + "examine": "Cock-a-doodle-do!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Diango to get another chicken head.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11022", + "name": "Chicken legs", + "examine": "What's the matter, are you chicken?", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to speak to Diango to get another set of chicken legs.", + "durability": null, + "equipment_slot": "7", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "11023", + "name": "Magic egg", + "examine": "Let's see how far the rabbit hole goes.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "11024", + "name": "Rabbit mould", + "examine": "Used for making chocolate rabbits.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "11025", + "name": "Chocolate chunks", + "examine": "Some chocolate chunks.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11026", + "name": "Chocolate kebbit", + "examine": "Chocolatey kebbit goodness.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11027", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "tradeable": "true" + }, + { + "id": "11028", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "tradeable": "true" + }, + { + "id": "11029", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "tradeable": "true" + }, + { + "id": "11030", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "tradeable": "true" + }, + { + "id": "11031", + "name": "Damp planks", + "examine": "A number of dripping, waterlogged planks.", + "archery_ticket_price": "0", + "destroy_message": "These logs will be destroyed if you drop them and you will need to see Olaf Hradson to get some more.", + "durability": null + }, + { + "id": "11032", + "name": "Crude carving", + "examine": "A log with some squiggles carved into it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11033", + "name": "Cruder carving", + "examine": "Another log with some sort of bird hacked into it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11034", + "name": "Sven's last map", + "examine": "A faded map marking a cross next to a section of the landscape.", + "archery_ticket_price": "0", + "destroy_message": "This map will be destroyed if you drop it and you will need to see Olaf Hradson to get another.", + "durability": null + }, + { + "id": "11035", + "name": "Windswept logs", + "examine": "Logs taken from the exotic-looking windswept tree.", + "archery_ticket_price": "0", + "destroy_message": "These logs will be destroyed if you drop them and you will need to chop more from the windswept tree.", + "durability": null + }, + { + "id": "11037", + "name": "Brine sabre", + "examine": "A salty sword.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "4", + "bonuses": "7,47,-2,0,0,0,0,0,0,0,0,46,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", + "requirements": "{0,40}", "tradeable": "true", - "weight": "1.3", - "archery_ticket_price": "0", - "id": "11046" + "weapon_interface": "6", + "weight": "1.8" }, { - "examine": "Eww, a bald rat!", + "id": "11038", + "name": "Brine sabre", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11044", + "name": "Rotten barrel", + "examine": "Looks like it might still float.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "11045", + "name": "Rotten barrel", + "examine": "Looks like it might still float.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11046", + "name": "Rope", + "examine": "A coil of rope.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "18", + "tradeable": "true", + "weight": "1.3" + }, + { + "id": "11047", "name": "Brine rat", + "examine": "Eww, a bald rat!", "archery_ticket_price": "0", "attack_speed": "4", - "id": "11047" + "durability": null }, { - "examine": "A piece of ancient goblin armour.", - "durability": null, + "id": "11048", "name": "Armour shard", + "examine": "A piece of ancient goblin armour.", "archery_ticket_price": "0", - "id": "11048" + "durability": null }, { - "examine": "An ancient goblin object encrusted in dirt.", - "durability": null, + "id": "11049", "name": "Artefact", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient goblin object encrusted in dirt.", "archery_ticket_price": "0", - "id": "11049" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "shop_price": "1", - "examine": "It's missing a handle.", - "durability": null, + "id": "11050", "name": "Axe head", - "tradeable": "true", + "examine": "It's missing a handle.", "archery_ticket_price": "0", - "id": "11050" + "durability": null, + "shop_price": "1", + "tradeable": "true" }, { - "examine": "An ancient goblin object encrusted in dirt.", - "durability": null, + "id": "11051", "name": "Artefact", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient goblin object encrusted in dirt.", "archery_ticket_price": "0", - "id": "11051" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A piece of ancient goblin helmet.", - "durability": null, + "id": "11052", "name": "Helmet fragment", - "tradeable": "false", - "destroy": "true", + "examine": "A piece of ancient goblin helmet.", "archery_ticket_price": "0", - "id": "11052" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "An ancient goblin object encrusted in dirt.", - "durability": null, + "id": "11053", "name": "Artefact", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient goblin object encrusted in dirt.", "archery_ticket_price": "0", - "id": "11053" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A piece of an ancient goblin shield.", - "durability": null, + "id": "11054", "name": "Shield fragment", - "tradeable": "false", - "destroy": "true", + "examine": "A piece of an ancient goblin shield.", "archery_ticket_price": "0", - "id": "11054" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "An ancient goblin object encrusted in dirt.", - "durability": null, + "id": "11055", "name": "Artefact", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient goblin object encrusted in dirt.", "archery_ticket_price": "0", - "id": "11055" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A piece of an ancient goblin sword.", - "durability": null, + "id": "11056", "name": "Sword fragment", + "examine": "A piece of an ancient goblin sword.", "archery_ticket_price": "0", - "id": "11056" + "durability": null }, { - "examine": "An ancient goblin object encrusted in dirt.", - "durability": null, + "id": "11057", "name": "Artefact", - "tradeable": "false", - "destroy": "true", + "examine": "An ancient goblin object encrusted in dirt.", "archery_ticket_price": "0", - "id": "11057" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "durability": null, + "id": "11058", "name": "Mace", "archery_ticket_price": "0", + "attack_audios": "2508,2508,25092508", "attack_speed": "5", - "id": "11058" + "durability": null }, { - "examine": "An ancient goblin object encrusted in dirt.", - "durability": null, + "id": "11059", "name": "Artefact", - "tradeable": "false", + "examine": "An ancient goblin object encrusted in dirt.", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "11059" - }, - { - "shop_price": "2", - "examine": "Oldak's marvellous Moving-over-distance Sphere", "durability": null, - "name": "Goblin village sphere", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "11060" + "tradeable": "false" }, { + "id": "11060", + "name": "Goblin village sphere", + "examine": "Oldak's marvellous Moving-over-distance Sphere", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "weight": "0.05" + }, + { + "id": "11061", + "name": "Ancient mace", + "examine": "It has ancient goblin symbols on it.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "10,-2,16,0,0,0,0,0,0,0,0,14,3,0,0", + "defence_anim": "397", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "ge_buy_limit": "100", + "has_special": "true", "requirements": "{0,25}-{5,15}", "shop_price": "1000", - "ge_buy_limit": "100", - "examine": "It has ancient goblin symbols on it.", - "has_special": "true", - "durability": null, - "weight": "1.8", - "attack_speed": "5", + "tradeable": "true", "weapon_interface": "8", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "grand_exchange_price": "4093", - "name": "Ancient mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11061", - "bonuses": "10,-2,16,0,0,0,0,0,0,0,0,14,3,0,0" + "weight": "1.8" }, { + "id": "11064", + "name": "Ancient mace", + "archery_ticket_price": "0", "durability": null, - "name": "Ancient mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11064" + "tradeable": "true" }, { - "shop_price": "5", - "ge_buy_limit": "100", + "id": "11065", + "name": "Bracelet mould", "examine": "Used to make gold bracelets.", - "grand_exchange_price": "456", - "durability": null, - "name": "Bracelet mould", - "tradeable": "true", - "weight": "0.4", "archery_ticket_price": "0", - "id": "11065" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "456", - "durability": null, - "name": "Bracelet mould", + "shop_price": "5", "tradeable": "true", - "archery_ticket_price": "0", - "id": "11066" + "weight": "0.4" }, { - "shop_price": "165", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "223", - "durability": null, - "name": "Gold bracelet", - "tradeable": "true", - "weight": "0.2", + "id": "11066", + "name": "Bracelet mould", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11069", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "223", - "durability": null, "name": "Gold bracelet", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "11070" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "165", + "tradeable": "true", + "weight": "0.2" }, { - "shop_price": "1035", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "578", - "durability": null, - "name": "Sapphire bracelet", - "tradeable": "true", - "weight": "0.25", + "id": "11070", + "name": "Gold bracelet", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11072", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "578", - "durability": null, "name": "Sapphire bracelet", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "11073" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "1035", + "tradeable": "true", + "weight": "0.25" }, { - "shop_price": "506", - "ge_buy_limit": "5000", - "examine": "Now I can become a potter.", - "grand_exchange_price": "644", - "durability": null, - "name": "Bracelet of clay", - "tradeable": "true", + "id": "11073", + "name": "Sapphire bracelet", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11074", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "644", - "durability": null, "name": "Bracelet of clay", - "tradeable": "true", + "examine": "Now I can become a potter.", "archery_ticket_price": "0", - "id": "11075" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "506", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "786", - "durability": null, - "name": "Emerald bracelet", - "tradeable": "true", - "weight": "0.2", + "id": "11075", + "name": "Bracelet of clay", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11076", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "786", - "durability": null, "name": "Emerald bracelet", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "11077" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "34464", - "examine": "Must be worn as you enter the game to receive the bonus for that game.", - "grand_exchange_price": "926", - "durability": null, - "name": "Castlewar brace(3)", - "tradeable": "true", - "weight": "0.25", + "id": "11077", + "name": "Emerald bracelet", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11079", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "926", - "durability": null, "name": "Castlewar brace(3)", - "tradeable": "true", + "examine": "Must be worn as you enter the game to receive the bonus for that game.", "archery_ticket_price": "0", - "id": "11080" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "34464", + "tradeable": "true", + "weight": "0.25" }, { - "examine": "Must be worn as you enter the game to receive the bonus for that game.", - "grand_exchange_price": "3", - "durability": null, - "name": "Castlewar brace(2)", - "tradeable": "true", - "weight": "0.25", + "id": "11080", + "name": "Castlewar brace(3)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11081", - "equipment_slot": "9" - }, - { - "durability": null, "name": "Castlewar brace(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11082" - }, - { - "ge_buy_limit": "5000", "examine": "Must be worn as you enter the game to receive the bonus for that game.", - "grand_exchange_price": "3484", - "durability": null, - "name": "Castlewar brace(1)", - "tradeable": "true", - "weight": "0.25", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.25" + }, + { + "id": "11082", + "name": "Castlewar brace(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11083", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3484", - "durability": null, "name": "Castlewar brace(1)", - "tradeable": "true", + "examine": "Must be worn as you enter the game to receive the bonus for that game.", "archery_ticket_price": "0", - "id": "11084" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.25" }, { - "shop_price": "2325", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "1271", - "durability": null, - "name": "Ruby bracelet", - "tradeable": "true", + "id": "11084", + "name": "Castlewar brace(1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11085", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1271", - "durability": null, "name": "Ruby bracelet", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "11086" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "2325", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "It eases diseases!", - "grand_exchange_price": "1376", - "durability": null, - "name": "Inoculation brace", - "tradeable": "true", - "weight": "0.25", + "id": "11086", + "name": "Ruby bracelet", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11088", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1376", - "durability": null, "name": "Inoculation brace", - "tradeable": "true", + "examine": "It eases diseases!", "archery_ticket_price": "0", - "id": "11089" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.25" }, { - "ge_buy_limit": "5000", - "examine": "In case of emergency, wear necklace.", - "grand_exchange_price": "15400", - "durability": null, - "name": "Phoenix necklace", - "tradeable": "true", + "id": "11089", + "name": "Inoculation brace", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11090", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "15400", - "durability": null, "name": "Phoenix necklace", - "tradeable": "true", + "examine": "In case of emergency, wear necklace.", "archery_ticket_price": "0", - "id": "11091" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "3422", - "ge_buy_limit": "5000", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "12100", - "durability": null, - "name": "Diamond bracelet", - "tradeable": "true", + "id": "11091", + "name": "Phoenix necklace", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11092", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "12100", - "durability": null, "name": "Diamond bracelet", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "11093" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "shop_price": "3422", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "examine": "It repels revenants and helps you enter the Abyss.", - "grand_exchange_price": "15200", - "durability": null, - "name": "Forinthry brace(5)", - "tradeable": "true", - "weight": "0.2", + "id": "11093", + "name": "Diamond bracelet", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11095", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "15200", - "durability": null, "name": "Forinthry brace(5)", - "tradeable": "true", + "examine": "It repels revenants and helps you enter the Abyss.", "archery_ticket_price": "0", - "id": "11096" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.2" }, { - "examine": "It repels revenants and helps you enter the Abyss.", - "grand_exchange_price": "5", - "durability": null, - "name": "Forinthry brace(4)", - "tradeable": "true", - "weight": "0.2", + "id": "11096", + "name": "Forinthry brace(5)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11097", - "equipment_slot": "9" - }, - { - "durability": null, "name": "Forinthry brace(4)", - "tradeable": "true", + "examine": "It repels revenants and helps you enter the Abyss.", "archery_ticket_price": "0", - "id": "11098" + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.2" }, { - "examine": "It repels revenants and helps you enter the Abyss.", - "grand_exchange_price": "5", - "durability": null, - "name": "Forinthry brace(3)", - "tradeable": "true", - "weight": "0.2", + "id": "11098", + "name": "Forinthry brace(4)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11099", - "equipment_slot": "9" - }, - { - "durability": null, "name": "Forinthry brace(3)", - "tradeable": "true", + "examine": "It repels revenants and helps you enter the Abyss.", "archery_ticket_price": "0", - "id": "11100" + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.2" }, { - "examine": "It repels revenants and helps you enter the Abyss.", - "grand_exchange_price": "5", - "durability": null, - "name": "Forinthry brace(2)", - "tradeable": "true", - "weight": "0.2", + "id": "11100", + "name": "Forinthry brace(3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11101", - "equipment_slot": "9" - }, - { - "durability": null, "name": "Forinthry brace(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11102" - }, - { - "ge_buy_limit": "5000", "examine": "It repels revenants and helps you enter the Abyss.", - "grand_exchange_price": "2537", - "durability": null, - "name": "Forinthry brace(1)", - "tradeable": "true", - "weight": "0.2", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "11102", + "name": "Forinthry brace(2)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11103", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2537", - "durability": null, "name": "Forinthry brace(1)", - "tradeable": "true", + "examine": "It repels revenants and helps you enter the Abyss.", "archery_ticket_price": "0", - "id": "11104" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.2" }, { - "ge_buy_limit": "100", - "examine": "This will help me travel.", - "grand_exchange_price": "30400", - "durability": null, - "name": "Skills necklace(4)", - "tradeable": "true", + "id": "11104", + "name": "Forinthry brace(1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { "id": "11105", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "30400", - "durability": null, "name": "Skills necklace(4)", - "tradeable": "true", + "examine": "This will help me travel.", "archery_ticket_price": "0", - "id": "11106" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "This will help me travel.", - "grand_exchange_price": "1", - "durability": null, - "name": "Skills necklace(3)", - "tradeable": "true", + "id": "11106", + "name": "Skills necklace(4)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11107", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Skills necklace(3)", - "tradeable": "true", + "examine": "This will help me travel.", "archery_ticket_price": "0", - "id": "11108" + "durability": null, + "equipment_slot": "2", + "tradeable": "true" }, { - "examine": "This will help me travel.", - "grand_exchange_price": "1", - "durability": null, - "name": "Skills necklace(2)", - "tradeable": "true", + "id": "11108", + "name": "Skills necklace(3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11109", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Skills necklace(2)", - "tradeable": "true", + "examine": "This will help me travel.", "archery_ticket_price": "0", - "id": "11110" + "durability": null, + "equipment_slot": "2", + "tradeable": "true" }, { - "examine": "This will help me travel.", - "grand_exchange_price": "1", - "durability": null, - "name": "Skills necklace(1)", - "tradeable": "true", + "id": "11110", + "name": "Skills necklace(2)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11111", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Skills necklace(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11112" - }, - { - "ge_buy_limit": "100", "examine": "This will help me travel.", - "grand_exchange_price": "28400", - "durability": null, - "name": "Skills necklace", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "tradeable": "true" + }, + { + "id": "11112", + "name": "Skills necklace(1)", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "11113", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "28400", - "durability": null, "name": "Skills necklace", - "tradeable": "true", + "examine": "This will help me travel.", "archery_ticket_price": "0", - "id": "11114" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "I wonder if this is valuable.", - "grand_exchange_price": "26000", - "durability": null, - "name": "Dragon bracelet", - "tradeable": "true", - "weight": "0.3", + "id": "11114", + "name": "Skills necklace", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11115", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "26000", - "durability": null, "name": "Dragon bracelet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11116" - }, - { - "ge_buy_limit": "100", - "examine": "A handy way to get around.", - "grand_exchange_price": "29700", - "durability": null, - "name": "Combat bracelet(4)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "11118", - "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "29700", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Combat bracelet(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11119" - }, - { - "examine": "A handy way to get around.", - "grand_exchange_price": "1", - "durability": null, - "name": "Combat bracelet(3)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "11120", - "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", - "equipment_slot": "9" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Combat bracelet(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11121" - }, - { - "examine": "A handy way to get around.", - "grand_exchange_price": "1", - "durability": null, - "name": "Combat bracelet(2)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "11122", - "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", - "equipment_slot": "9" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Combat bracelet(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11123" - }, - { - "examine": "A handy way to get around.", - "grand_exchange_price": "1", - "durability": null, - "name": "Combat bracelet(1)", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "11124", - "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", - "equipment_slot": "9" - }, - { - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Combat bracelet(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11125" - }, - { - "ge_buy_limit": "100", - "examine": "You will need to recharge the bracelet at the Legends Guild.", - "grand_exchange_price": "29000", - "durability": null, - "name": "Combat bracelet", - "tradeable": "true", - "weight": "0.3", - "archery_ticket_price": "0", - "id": "11126", - "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "29000", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Combat bracelet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11127" - }, - { - "ge_buy_limit": "100", - "examine": "Makes obsidian weapons even stronger!", - "grand_exchange_price": "2400000", - "durability": null, - "name": "Berserker necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11128", - "bonuses": "-10,-10,-10,0,0,-20,-20,-20,-20,-20,-20,7,3,0,0", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "2400000", - "durability": null, - "name": "Berserker necklace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11129" - }, - { - "shop_price": "80400", - "ge_buy_limit": "100", "examine": "I wonder if this is valuable.", - "grand_exchange_price": "941200", - "durability": null, - "name": "Onyx bracelet", - "tradeable": "true", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "11116", + "name": "Dragon bracelet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11118", + "name": "Combat bracelet(4)", + "examine": "A handy way to get around.", + "archery_ticket_price": "0", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "11119", + "name": "Combat bracelet(4)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11120", + "name": "Combat bracelet(3)", + "examine": "A handy way to get around.", + "archery_ticket_price": "0", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "11121", + "name": "Combat bracelet(3)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11122", + "name": "Combat bracelet(2)", + "examine": "A handy way to get around.", + "archery_ticket_price": "0", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "11123", + "name": "Combat bracelet(2)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11124", + "name": "Combat bracelet(1)", + "examine": "A handy way to get around.", + "archery_ticket_price": "0", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "durability": null, + "equipment_slot": "9", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "11125", + "name": "Combat bracelet(1)", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11126", + "name": "Combat bracelet", + "examine": "You will need to recharge the bracelet at the Legends Guild.", + "archery_ticket_price": "0", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "0.3" + }, + { + "id": "11127", + "name": "Combat bracelet", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11128", + "name": "Berserker necklace", + "examine": "Makes obsidian weapons even stronger!", + "archery_ticket_price": "0", + "bonuses": "-10,-10,-10,0,0,-20,-20,-20,-20,-20,-20,7,3,0,0", + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11129", + "name": "Berserker necklace", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11130", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "941200", - "durability": null, "name": "Onyx bracelet", - "tradeable": "true", + "examine": "I wonder if this is valuable.", "archery_ticket_price": "0", - "id": "11131" + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "shop_price": "80400", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "Helps to restore your life points.", - "grand_exchange_price": "124200", - "durability": null, - "name": "Regen bracelet", - "tradeable": "true", - "weight": "0.2", + "id": "11131", + "name": "Onyx bracelet", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11133", - "bonuses": "8,8,8,3,7,6,6,6,3,6,5,7,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "124200", - "durability": null, "name": "Regen bracelet", - "tradeable": "true", + "examine": "Helps to restore your life points.", "archery_ticket_price": "0", - "id": "11134" - }, - { - "remove_sleeves": "true", - "examine": "For all your flying needs.", + "bonuses": "8,8,8,3,7,6,6,6,3,6,5,7,0,0,0", "durability": null, - "name": "Bomber jacket", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11135", - "equipment_slot": "4" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pair of pale green Karamja gloves.", - "durability": null, - "name": "Karamja gloves 1", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11136", - "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11137" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pair of green Karamja gloves.", - "durability": null, - "name": "Karamja gloves 2", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11138", - "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11139" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A pair of dark green Karamja gloves.", - "durability": null, - "name": "Karamja gloves 3", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11140", - "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11141" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", - "durability": null, - "name": "Dream vial (empty)", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11151" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", - "durability": null, - "name": "Dream vial (water)", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11152" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", - "durability": null, - "name": "Dream vial (herb)", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11153" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Potion of Shared Dreaming. One dream for two!", - "durability": null, - "name": "Dream potion", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11154" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A ground astral rune.", - "durability": null, - "name": "Ground astral rune", - "archery_ticket_price": "0", - "id": "11155" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "An astral rune that has been broken into shards.", - "durability": null, - "name": "Astral rune shards", - "archery_ticket_price": "0", - "id": "11156" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A lunar-styled lamp. I wonder what's inside?", - "durability": null, - "name": "Dreamy lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11157" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Perfect for storing heavy things.", - "durability": null, - "name": "Cyrisus's chest", - "tradeable": "false", - "destroy": "true", - "weight": "6", - "archery_ticket_price": "0", - "id": "11158" - }, - { - "destroy_message": "You will have to create another using the Lunar Spellbook.", + "equipment_slot": "9", "ge_buy_limit": "100", - "examine": "A box of Hunter goodies.", - "grand_exchange_price": "3", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "11134", + "name": "Regen bracelet", + "archery_ticket_price": "0", "durability": null, - "name": "Hunter kit", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11135", + "name": "Bomber jacket", + "examine": "For all your flying needs.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", "tradeable": "false", + "weight": "1" + }, + { + "id": "11136", + "name": "Karamja gloves 1", + "examine": "A pair of pale green Karamja gloves.", + "archery_ticket_price": "0", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "11159" - }, - { - "destroy_message": "You'll need to get it back from Captain Rovin.", - "examine": "Complete Shield of Arrav.", - "durability": null, - "name": "Restored shield", - "destroy": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "11164" - }, - { - "turn90cw_anim": "821", - "examine": "Second-rate crossbow, former property of the Phoenix Gang.", - "walk_anim": "4226", - "durability": null, - "weight": "3", - "turn90ccw_anim": "822", - "attack_speed": "6", - "weapon_interface": "17", - "turn180_anim": "4227", - "render_anim": "175", - "equipment_slot": "3", - "stand_anim": "4591", - "attack_audios": "2700,0,0,0", - "name": "Phoenix crossbow", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "11165", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Phoenix crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11166" - }, - { - "turn90cw_anim": "821", - "examine": "Second-rate crossbow, former property of the Phoenix Gang.", - "walk_anim": "4226", - "durability": null, - "weight": "3", - "turn90ccw_anim": "822", - "attack_speed": "6", - "weapon_interface": "17", - "turn180_anim": "4227", - "render_anim": "175", - "equipment_slot": "3", - "stand_anim": "4591", - "attack_audios": "2700,0,0,0", - "name": "Phoenix crossbow", - "tradeable": "true", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "11167", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Phoenix crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11168" - }, - { - "shop_price": "50", - "examine": "A collection of written news on paper!", - "durability": null, - "name": "Newspaper", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11169" - }, - { - "durability": null, - "name": "Newspaper", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11170" - }, - { - "shop_price": "50", - "examine": "A collection of written news on paper!", - "durability": null, - "name": "Newspaper", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11171" - }, - { - "durability": null, - "name": "Newspaper", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11172" - }, - { - "destroy_message": "Instead of destroying this I should get a friend to help me retrieve the other half.", - "examine": "I can use this to claim a reward from the King, if I get the other half.", - "durability": null, - "name": "Half certificate", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11173" - }, - { - "destroy_message": "Instead of destroying this I should get a friend to help me retrieve the other half.", - "examine": "I can use this to claim a reward from the King, if I get the other half.", - "durability": null, - "name": "Half certificate", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11174" - }, - { - "destroy_message": "You can get another find from the pile in the cleaning area of Varrock Museum.", - "examine": "A roughly-prepared archaeological find ready for cleaning.", - "durability": null, - "name": "Uncleaned find", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11175" - }, - { - "examine": "An old looking coin.", - "durability": null, - "name": "Old coin", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11179" - }, - { - "examine": "A cracked and rusty looking coin.", - "durability": null, - "name": "Ancient coin", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11180" - }, - { - "examine": "A very old symbol of Saradomin.", - "durability": null, - "name": "Ancient symbol", - "archery_ticket_price": "0", - "id": "11181" - }, - { - "examine": "An old symbol of Saradomin.", - "durability": null, - "name": "Old symbol", - "archery_ticket_price": "0", - "id": "11182" - }, - { - "examine": "An old vase with Saradominist markings - it has been chipped.", - "durability": null, - "name": "Old chipped vase", - "archery_ticket_price": "0", - "id": "11183" - }, - { - "examine": "A map of Varrock Museum.", - "durability": null, - "name": "Museum map", - "archery_ticket_price": "0", - "id": "11184" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11185" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11186" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11187" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11188" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11189" - }, - { - "examine": "An enchanted necklace.", - "durability": null, - "name": "Digsite pendant (1)", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "11190", - "equipment_slot": "2" - }, - { - "examine": "An enchanted necklace.", - "durability": null, - "name": "Digsite pendant (2)", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "11191", - "equipment_slot": "2" - }, - { - "examine": "An enchanted necklace.", - "durability": null, - "name": "Digsite pendant (3)", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "11192", - "equipment_slot": "2" - }, - { - "examine": "An enchanted necklace.", - "durability": null, - "name": "Digsite pendant (4)", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "11193", - "equipment_slot": "2" - }, - { - "examine": "An enchanted necklace.", - "durability": null, - "name": "Digsite pendant (5)", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "11194", - "equipment_slot": "2" - }, - { - "examine": "A recently-cleaned necklace.", - "durability": null, - "name": "Clean necklace", - "archery_ticket_price": "0", - "id": "11195", - "equipment_slot": "2" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "One of Grimgnash's feathers.", "durability": null, + "equipment_slot": "9", + "tradeable": "false" + }, + { + "id": "11137", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11138", + "name": "Karamja gloves 2", + "examine": "A pair of green Karamja gloves.", + "archery_ticket_price": "0", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", + "tradeable": "false" + }, + { + "id": "11139", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11140", + "name": "Karamja gloves 3", + "examine": "A pair of dark green Karamja gloves.", + "archery_ticket_price": "0", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", + "tradeable": "false" + }, + { + "id": "11141", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11151", + "name": "Dream vial (empty)", + "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11152", + "name": "Dream vial (water)", + "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11153", + "name": "Dream vial (herb)", + "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11154", + "name": "Dream potion", + "examine": "Potion of Shared Dreaming. One dream for two!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11155", + "name": "Ground astral rune", + "examine": "A ground astral rune.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "11156", + "name": "Astral rune shards", + "examine": "An astral rune that has been broken into shards.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "11157", + "name": "Dreamy lamp", + "examine": "A lunar-styled lamp. I wonder what's inside?", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11158", + "name": "Cyrisus's chest", + "examine": "Perfect for storing heavy things.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "6" + }, + { + "id": "11159", + "name": "Hunter kit", + "examine": "A box of Hunter goodies.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will have to create another using the Lunar Spellbook.", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "11164", + "name": "Restored shield", + "examine": "Complete Shield of Arrav.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll need to get it back from Captain Rovin.", + "durability": null, + "weight": "5" + }, + { + "id": "11165", + "name": "Phoenix crossbow", + "examine": "Second-rate crossbow, former property of the Phoenix Gang.", + "archery_ticket_price": "0", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "175", + "run_anim": "4228", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "3" + }, + { + "id": "11166", + "name": "Phoenix crossbow", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11167", + "name": "Phoenix crossbow", + "examine": "Second-rate crossbow, former property of the Phoenix Gang.", + "archery_ticket_price": "0", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "175", + "run_anim": "4228", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "3" + }, + { + "id": "11168", + "name": "Phoenix crossbow", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11169", + "name": "Newspaper", + "examine": "A collection of written news on paper!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "50", + "tradeable": "true" + }, + { + "id": "11170", + "name": "Newspaper", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11171", + "name": "Newspaper", + "examine": "A collection of written news on paper!", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "50", + "tradeable": "true" + }, + { + "id": "11172", + "name": "Newspaper", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11173", + "name": "Half certificate", + "examine": "I can use this to claim a reward from the King, if I get the other half.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Instead of destroying this I should get a friend to help me retrieve the other half.", + "durability": null, + "tradeable": "true" + }, + { + "id": "11174", + "name": "Half certificate", + "examine": "I can use this to claim a reward from the King, if I get the other half.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Instead of destroying this I should get a friend to help me retrieve the other half.", + "durability": null, + "tradeable": "true" + }, + { + "id": "11175", + "name": "Uncleaned find", + "examine": "A roughly-prepared archaeological find ready for cleaning.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another find from the pile in the cleaning area of Varrock Museum.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11179", + "name": "Old coin", + "examine": "An old looking coin.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "11180", + "name": "Ancient coin", + "examine": "A cracked and rusty looking coin.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "11181", + "name": "Ancient symbol", + "examine": "A very old symbol of Saradomin.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11182", + "name": "Old symbol", + "examine": "An old symbol of Saradomin.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11183", + "name": "Old chipped vase", + "examine": "An old vase with Saradominist markings - it has been chipped.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11184", + "name": "Museum map", + "examine": "A map of Varrock Museum.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11185", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11186", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11187", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11188", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11189", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11190", + "name": "Digsite pendant (1)", + "examine": "An enchanted necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "0.5" + }, + { + "id": "11191", + "name": "Digsite pendant (2)", + "examine": "An enchanted necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "0.5" + }, + { + "id": "11192", + "name": "Digsite pendant (3)", + "examine": "An enchanted necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "0.5" + }, + { + "id": "11193", + "name": "Digsite pendant (4)", + "examine": "An enchanted necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "0.5" + }, + { + "id": "11194", + "name": "Digsite pendant (5)", + "examine": "An enchanted necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2", + "weight": "0.5" + }, + { + "id": "11195", + "name": "Clean necklace", + "examine": "A recently-cleaned necklace.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "2" + }, + { + "id": "11196", "name": "Griffin feather", + "examine": "One of Grimgnash's feathers.", "archery_ticket_price": "0", - "id": "11196" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "You will need to try and find another pendant in the mouse hole if you destroy this.", - "examine": "The pendant belonging to Miazrqa.", - "durability": null, + "id": "11197", "name": "Miazrqa's pendant", - "tradeable": "false", - "destroy": "true", + "examine": "The pendant belonging to Miazrqa.", "archery_ticket_price": "0", - "id": "11197" + "destroy": "true", + "destroy_message": "You will need to try and find another pendant in the mouse hole if you destroy this.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You will need to find another sheet of music in the witch's basement if you destroy this.", - "examine": "A sheet of music.", - "durability": null, + "id": "11198", "name": "Music sheet", - "tradeable": "false", - "destroy": "true", + "examine": "A sheet of music.", "archery_ticket_price": "0", - "id": "11198" - }, - { - "destroy_message": "You will need to obtain another helmet from Rupert the Beard if you destroy this", - "shop_price": "60000", - "examine": "A sturdy helmet that belonged to Rupert the beard.", + "destroy": "true", + "destroy_message": "You will need to find another sheet of music in the witch's basement if you destroy this.", "durability": null, - "name": "Rupert's helmet", - "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11199" + "tradeable": "false" }, { + "id": "11199", + "name": "Rupert's helmet", + "examine": "A sturdy helmet that belonged to Rupert the beard.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to obtain another helmet from Rupert the Beard if you destroy this", + "durability": null, + "shop_price": "60000", + "tradeable": "false", + "weight": "2" + }, + { + "id": "11200", + "name": "Dwarven helmet", + "examine": "A sturdy helmet that belonged to Rupert the beard.", + "archery_ticket_price": "0", + "bonuses": "0,0,6,-2,-2,27,28,31,5,24,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{1,50}", "shop_price": "60000", - "ge_buy_limit": "100", - "examine": "A sturdy helmet that belonged to Rupert the beard.", - "durability": null, - "weight": "1.9", - "equipment_slot": "0", - "grand_exchange_price": "35800", - "name": "Dwarven helmet", "tradeable": "true", - "archery_ticket_price": "0", - "id": "11200", - "bonuses": "0,0,6,-2,-2,27,28,31,5,24,8,0,0,0,0" + "weight": "1.9" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "35800", - "durability": null, + "id": "11201", "name": "Dwarven helmet", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11201" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "destroy_message": "You will need to find another copy in the witch's basement if you destroy this.", - "examine": "A recipe for a shrinking potion.", - "durability": null, + "id": "11202", "name": "Shrinking recipe", - "tradeable": "false", - "destroy": "true", + "examine": "A recipe for a shrinking potion.", "archery_ticket_price": "0", - "id": "11202" - }, - { + "destroy": "true", "destroy_message": "You will need to find another copy in the witch's basement if you destroy this.", - "examine": "A list of tasks for the day.", "durability": null, + "tradeable": "false" + }, + { + "id": "11203", "name": "To-do list", - "tradeable": "false", - "destroy": "true", + "examine": "A list of tasks for the day.", "archery_ticket_price": "0", - "id": "11203" + "destroy": "true", + "destroy_message": "You will need to find another copy in the witch's basement if you destroy this.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You will need to make another shrinking potion if you destroy this.", - "examine": "Apparently it shrinks you. Very fast.", - "durability": null, - "name": "Shrink-me-quick", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "11204", - "equipment_slot": "3" + "name": "Shrink-me-quick", + "examine": "Apparently it shrinks you. Very fast.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to make another shrinking potion if you destroy this.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" }, { - "shop_price": "4", - "ge_buy_limit": "100", - "examine": "A shrunk ogleroot! How odd...", - "grand_exchange_price": "35", - "durability": null, + "id": "11205", "name": "Shrunk ogleroot", - "tradeable": "false", + "examine": "A shrunk ogleroot! How odd...", + "archery_ticket_price": "0", "destroy": "true", - "archery_ticket_price": "0", - "id": "11205" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A shiny golden goblin. Strange!", "durability": null, - "name": "Golden goblin", - "tradeable": "false", - "destroy": "true", - "weight": "30", - "archery_ticket_price": "0", - "id": "11210" - }, - { - "destroy_message": "You will need to get another bag of beans from Sylas if you destroy this one.", - "examine": "A bag of magic beans.", - "durability": null, - "name": "Magic beans", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11211" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "An arrow made using a dragon's talon.", - "grand_exchange_price": "2674", - "durability": null, - "name": "Dragon arrow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11212", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with dragon heads and oil-soaked cloth.lit: Dragon-headed fire arrow.", - "grand_exchange_price": "3988", - "durability": null, - "name": "Dragon fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11217", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "unlit: Arrows with dragon heads and oil-soaked cloth.lit: Dragon-headed fire arrow.", - "grand_exchange_price": "3834", - "durability": null, - "name": "Dragon fire arrows", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11222", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "An arrow made using a dragon's talon.", - "grand_exchange_price": "3141", - "durability": null, - "name": "Dragon arrow(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11227", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "An arrow made using a dragon's talon.", - "grand_exchange_price": "2866", - "durability": null, - "name": "Dragon arrow(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11228", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "An arrow made using a dragon's talon.", - "grand_exchange_price": "3766", - "durability": null, - "name": "Dragon arrow(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11229", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", - "equipment_slot": "13" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "A deadly throwing dart with a dragon tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "equipment_slot": "3", - "grand_exchange_price": "315", - "attack_audios": "2547,0,0,0", - "name": "Dragon dart", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11230", - "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "A deadly throwing dart with a dragon tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "equipment_slot": "3", - "grand_exchange_price": "445", - "attack_audios": "2547,0,0,0", - "name": "Dragon dart(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11231", - "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" - }, - { - "ge_buy_limit": "5000", - "examine": "A deadly looking dragon dart tip - needs feathers for flight.", - "grand_exchange_price": "746", - "attack_audios": "2547,0,0,0", - "durability": null, - "name": "Dragon dart tip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11232" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "A deadly throwing dart with a dragon tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "equipment_slot": "3", - "grand_exchange_price": "516", - "attack_audios": "2547,0,0,0", - "name": "Dragon dart(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11233", - "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" - }, - { - "requirements": "{4,60}", - "ge_buy_limit": "10000", - "examine": "A deadly throwing dart with a dragon tip.", - "durability": null, - "attack_speed": "3", - "weapon_interface": "18", - "equipment_slot": "3", - "grand_exchange_price": "1248", - "attack_audios": "2547,0,0,0", - "name": "Dragon dart(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11234", - "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "821", - "examine": "A bow from a darker dimension.", - "walk_anim": "819", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "822", - "attack_speed": "9", - "two_handed": "true", - "turn180_anim": "820", - "defence_anim": "424", - "equipment_slot": "3", - "attack_anims": "426,426,426,426", - "grand_exchange_price": "143400", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "11235", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,95,0,0,0,0,0,0,0,0,0,0", - "requirements": "{4,60}", - "durability": null, - "weight": "1.9", - "weapon_interface": "16", - "equip_audio": "3738", - "render_anim": "1", - "lendable": "true", - "attack_audios": "3731,0,0,0", - "name": "Dark bow" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "143400", - "durability": null, - "name": "Dark bow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11236" - }, - { - "ge_buy_limit": "10000", - "examine": "Dragon talons, usable as arrowheads.", - "grand_exchange_price": "3391", - "durability": null, - "name": "Dragon arrowtips", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11237" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "A baby impling in a jar. That's a bit cruel.", - "grand_exchange_price": "529", - "durability": null, - "name": "Baby impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11238" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "529", - "durability": null, - "name": "Baby impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11239" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "A young impling in a jar. Don't trap me, man.", - "grand_exchange_price": "514", - "durability": null, - "name": "Young impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11240" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "514", - "durability": null, - "name": "Young impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11241" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "A gourmet impling in a jar.", - "grand_exchange_price": "677", - "durability": null, - "name": "Gourm' impling jar", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11242" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "677", - "durability": null, - "name": "Gourm' impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11243" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "Earth impling in a jar.", - "grand_exchange_price": "1343", - "durability": null, - "name": "Earth impling jar", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11244" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1343", - "durability": null, - "name": "Earth impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11245" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "Essence impling in a jar.", - "grand_exchange_price": "1266", - "durability": null, - "name": "Ess' impling jar", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11246" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1266", - "durability": null, - "name": "Ess' impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11247" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "Eclectic impling in a jar.", - "grand_exchange_price": "2943", - "durability": null, - "name": "Eclectic impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11248" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2943", - "durability": null, - "name": "Eclectic impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11249" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "Nature impling in a jar.", - "grand_exchange_price": "8593", - "durability": null, - "name": "Nature impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11250" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "8593", - "durability": null, - "name": "Nature impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11251" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "Magpie impling in a jar.", - "grand_exchange_price": "22900", - "durability": null, - "name": "Magpie impling jar", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11252" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "22900", - "durability": null, - "name": "Magpie impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11253" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "1000", - "examine": "Ninja impling in a jar.", - "grand_exchange_price": "21800", - "durability": null, - "name": "Ninja impling jar", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11254" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "21800", - "durability": null, - "name": "Ninja impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11255" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "ge_buy_limit": "500", - "examine": "Dragon impling in a jar.", - "grand_exchange_price": "423600", - "durability": null, - "name": "Dragon impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11256" - }, - { - "ge_buy_limit": "500", - "grand_exchange_price": "423600", - "durability": null, - "name": "Dragon impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11257" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Creates butterfly and impling jars.", - "durability": null, - "name": "Jar generator", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11258" - }, - { - "requirements": "{21,17}", - "shop_price": "3", - "turn90cw_anim": "6610", - "examine": "For catching butterflies.", - "walk_anim": "6607", - "durability": null, - "destroy": "true", - "weight": "0.2", - "turn90ccw_anim": "6609", - "attack_speed": "4", - "two_handed": "", - "weapon_interface": "14", - "turn180_anim": "6608", - "render_anim": "1426", - "equipment_slot": "3", - "destroy_message": "You will have to trade with Elnock to get a new magic butterfly net.", - "stand_anim": "6604", - "name": "Magic butterfly net", - "tradeable": "false", - "run_anim": "6603", - "archery_ticket_price": "0", - "id": "11259", - "stand_turn_anim": "6611" - }, - { - "shop_price": "1", - "ge_buy_limit": "1000", - "examine": "It's got little holes in the top.", - "grand_exchange_price": "248", - "durability": null, - "name": "Impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11260" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "248", - "durability": null, - "name": "Impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11261" - }, - { - "shop_price": "3", "ge_buy_limit": "100", - "examine": "Imps seem to hate this stuff. Can't say I blame them.", - "grand_exchange_price": "1016", - "durability": null, - "name": "Imp repellent", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11262" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1016", - "durability": null, - "name": "Imp repellent", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11263" - }, - { - "ge_buy_limit": "100", - "examine": "Omega 3 oil. Good for the brain, not so for the nose.", - "grand_exchange_price": "601", - "durability": null, - "name": "Anchovy oil", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11264" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "601", - "durability": null, - "name": "Anchovy oil", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11265" - }, - { - "ge_buy_limit": "100", - "examine": "Fish paste. Urk.", - "grand_exchange_price": "57", - "durability": null, - "name": "Anchovy paste", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11266" - }, - { - "examine": "I can train on this", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "11267" - }, - { - "examine": "I can train on this", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "11268" - }, - { - "examine": "I can train on this", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "11269" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11270" - }, - { - "examine": "I can train on this", - "durability": null, - "name": "Picture", - "archery_ticket_price": "0", - "id": "11271" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11272" - }, - { - "destroy_message": "You will have to ask Elnock for another one of these.", - "examine": "Lets you easily identify your prey.", - "durability": null, - "name": "Impling scroll", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11273" - }, - { - "remove_sleeves": "true", - "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", - "grand_exchange_price": "27", - "durability": null, - "name": "Ham shirt", - "tradeable": "true", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "11274", - "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "durability": null, - "name": "Mith grapple", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11275" - }, - { - "durability": null, - "name": "Mith grapple", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11276" - }, - { - "lendable": "true", - "examine": "I hope I don't meet any roundheads...", - "durability": null, - "name": "Cavalier mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11277", - "equipment_slot": "8" - }, - { - "examine": "Essential mime wear.", - "durability": null, - "name": "Beret mask", - "weight": "1", - "archery_ticket_price": "0", - "id": "11278", - "equipment_slot": "0" - }, - { - "destroy_message": "You can complete the quest by speaking to Oziach even if you do not have the head.", - "examine": "The severed head of the great dragon Elvarg!", - "durability": null, - "name": "Elvarg's head", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11279", - "equipment_slot": "3" - }, - { - "remove_head": "true", - "lendable": "true", - "examine": "I hope I don't meet any roundheads...", - "durability": null, - "name": "Cavalier and mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11280", - "equipment_slot": "0" - }, - { - "durability": null, - "name": "Cavalier and mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11281" - }, - { - "remove_head": "true", - "examine": "Essential mime wear.", - "durability": null, - "name": "Beret and mask", - "weight": "1", - "archery_ticket_price": "0", - "id": "11282", - "equipment_slot": "0" - }, - { - "requirements": "{1,75}", - "examine": "A heavy shield with a snarling, draconic visage.", - "grand_exchange_price": "5653008", - "rare_item": "true", - "durability": null, - "name": "Dragonfire shield", - "weight": "7.2", - "archery_ticket_price": "0", - "id": "11283", - "bonuses": "0,0,0,-10,-5,20,25,22,10,22,17,7,0,0,0", - "equipment_slot": "5" - }, - { - "requirements": "{1,75}", - "ge_buy_limit": "10", - "examine": "A heavy shield with a snarling, draconic visage.", - "rare_item": "true", - "durability": null, - "weight": "7.2", - "equipment_slot": "5", - "grand_exchange_price": "7700000", - "name": "Dragonfire shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11284", - "bonuses": "0,0,0,-10,-5,20,25,22,10,22,17,7,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "7700000", - "durability": null, - "name": "Dragonfire shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11285" - }, - { - "ge_buy_limit": "10", - "examine": "It looks like this could be attached to a shield somehow.", - "grand_exchange_price": "8000000", - "rare_item": "true", - "durability": null, - "name": "Draconic visage", - "tradeable": "true", - "weight": "1.8", - "archery_ticket_price": "0", - "id": "11286" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "8000000", - "durability": null, - "name": "Draconic visage", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11287" - }, - { - "examine": "A heavy barbarian Fishing rod.", - "durability": null, - "name": "Barbarian rod", - "weight": "1", - "archery_ticket_price": "0", - "id": "11323" - }, - { - "shop_price": "6", - "ge_buy_limit": "5000", - "examine": "Roe, or cheap fishy eggs.", - "grand_exchange_price": "17", - "durability": null, - "name": "Roe", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "11324" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "17", - "durability": null, - "name": "Roe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11325" - }, - { - "ge_buy_limit": "5000", - "examine": "Caviar, or expensive fishy eggs.", - "grand_exchange_price": "370", - "durability": null, - "name": "Caviar", - "tradeable": "true", - "weight": "0.05", - "archery_ticket_price": "0", - "id": "11326" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "370", - "durability": null, - "name": "Caviar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11327" - }, - { - "shop_price": "11", - "ge_buy_limit": "5000", - "examine": "A sad-looking trout.", - "grand_exchange_price": "9", - "durability": null, - "name": "Leaping trout", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11328" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "9", - "durability": null, - "name": "Leaping trout", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11329" - }, - { - "ge_buy_limit": "5000", - "examine": "Some non-tasty salmon.", - "grand_exchange_price": "19", - "durability": null, - "name": "Leaping salmon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11330" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "19", - "durability": null, - "name": "Leaping salmon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11331" - }, - { - "ge_buy_limit": "5000", - "examine": "A bloated sturgeon.", - "grand_exchange_price": "151", - "durability": null, - "name": "Leaping sturgeon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11332" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "151", - "durability": null, - "name": "Leaping sturgeon", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11333" - }, - { - "ge_buy_limit": "100", - "examine": "Slices of inedible fish.", - "grand_exchange_price": "2", - "durability": null, - "name": "Fish offcuts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11334" - }, - { - "remove_head": "true", - "requirements": "{1,60}", - "ge_buy_limit": "10", - "examine": "Protects your head and looks impressive too.", - "rare_item": "true", - "durability": null, - "weight": "2", - "absorb": "2,0,4", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "51600000", - "name": "Dragon full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11335", - "bonuses": "0,0,0,-6,-2,45,48,41,-1,46,12,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "51600000", - "durability": null, - "name": "Dragon full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11336" - }, - { - "destroy_message": "I can gather more from the caverns below the Baxtorian Lake.", - "examine": "The bones of a barbarian warrior, slain by his fellow adventurers.", - "durability": null, - "name": "Mangled bones", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11337" - }, - { - "destroy_message": "I can gather more from the caverns below the Baxtorian Lake.", - "examine": "The bones of a barbarian warrior, slain by vile dragons.", - "durability": null, - "name": "Chewed bones", - "destroy": "true", - "weight": "9.6", - "archery_ticket_price": "0", - "id": "11338" - }, - { - "destroy_message": "I can obtain another from Otto.", - "examine": "Records from my discoveries beneath the lake.", - "durability": null, - "name": "My notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11339" - }, - { - "destroy_message": "I can obtain another from Otto.", - "examine": "A record of Otto's instructions to me.", - "durability": null, - "name": "Barbarian skills", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11340" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11341" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11342" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11343" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11344" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11345" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11346" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11347" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11348" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11349" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11350" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11351" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11352" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11353" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11354" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11355" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11356" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11357" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11358" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11359" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11360" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11361" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11362" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11363" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11364" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11365" - }, - { - "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", - "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", - "durability": null, - "name": "Ancient page", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11366" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "204", - "stand_anim": "813", - "name": "Bronze hasta", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11367", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "204", - "durability": null, - "name": "Bronze hasta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11368" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "25", - "stand_anim": "813", - "name": "Iron hasta", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11369", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "25", - "durability": null, - "name": "Iron hasta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11370" - }, - { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "93", - "stand_anim": "813", - "name": "Steel hasta", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11371", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "93", - "durability": null, - "name": "Steel hasta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11372" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "357", - "stand_anim": "813", - "name": "Mithril hasta", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11373", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "357", - "durability": null, - "name": "Mithril hasta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11374" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "1095", - "stand_anim": "813", - "name": "Adamant hasta", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11375", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1095", - "durability": null, - "name": "Adamant hasta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11376" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "12300", - "stand_anim": "813", - "name": "Rune hasta", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11377", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12300", - "durability": null, - "name": "Rune hasta", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11378" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "290", - "stand_anim": "813", - "name": "Bronze hasta(p)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11379", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "290", - "durability": null, - "name": "Bronze hasta(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11380" - }, - { - "turn90cw_anim": "1207", - "examine": "A karambwan poison-tipped, one-handed bronze hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "stand_anim": "813", - "name": "Bronze hasta(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11381", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "775", - "stand_anim": "813", - "name": "Bronze hasta(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11382", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "775", - "durability": null, - "name": "Bronze hasta(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11383" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A bronze-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "8974", - "stand_anim": "813", - "name": "Bronze hasta(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11384", - "stand_turn_anim": "1209", - "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8974", - "durability": null, - "name": "Bronze hasta(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11385" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "99", - "stand_anim": "813", - "name": "Iron hasta(p)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11386", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "99", - "durability": null, - "name": "Iron hasta(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11387" - }, - { - "turn90cw_anim": "1207", - "examine": "A karambwan poison-tipped, one-handed iron hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "stand_anim": "813", - "name": "Iron hasta(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11388", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "584", - "stand_anim": "813", - "name": "Iron hasta(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11389", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "584", - "durability": null, - "name": "Iron hasta(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11390" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An iron-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "8783", - "stand_anim": "813", - "name": "Iron hasta(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11391", - "stand_turn_anim": "1209", - "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8783", - "durability": null, - "name": "Iron hasta(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11392" - }, - { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "151", - "stand_anim": "813", - "name": "Steel hasta(p)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11393", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "151", - "durability": null, - "name": "Steel hasta(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11394" - }, - { - "requirements": "{0,5}", - "turn90cw_anim": "1207", - "examine": "A karambwan poison-tipped, one-handed steel hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "stand_anim": "813", - "name": "Steel hasta(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11395", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" - }, - { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "636", - "stand_anim": "813", - "name": "Steel hasta(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11396", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "636", - "durability": null, - "name": "Steel hasta(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11397" - }, - { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A steel-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "8835", - "stand_anim": "813", - "name": "Steel hasta(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11398", - "stand_turn_anim": "1209", - "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8835", - "durability": null, - "name": "Steel hasta(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11399" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "440", - "stand_anim": "813", - "name": "Mithril hasta(p)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11400", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "440", - "durability": null, - "name": "Mithril hasta(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11401" - }, - { - "requirements": "{0,20}", - "turn90cw_anim": "1207", - "examine": "A karambwan poison-tipped, one-handed mithril hasta", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "353", - "stand_anim": "813", - "name": "Mithril hasta(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11402", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "925", - "stand_anim": "813", - "name": "Mithril hasta(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11403", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "925", - "durability": null, - "name": "Mithril hasta(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11404" - }, - { - "requirements": "{0,20}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A mithril-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "1.8", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "8711", - "stand_anim": "813", - "name": "Mithril hasta(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11405", - "stand_turn_anim": "1209", - "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8711", - "durability": null, - "name": "Mithril hasta(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11406" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "1154", - "stand_anim": "813", - "name": "Adamant hasta(p)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11407", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1154", - "durability": null, - "name": "Adamant hasta(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11408" - }, - { - "requirements": "{0,30}", - "turn90cw_anim": "1207", - "examine": "\tA karambwan poison-tipped, one-handed adamantite hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "stand_anim": "813", - "name": "Adamant hasta(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11409", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "1639", - "stand_anim": "813", - "name": "Adamant hasta(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11410", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1639", - "durability": null, - "name": "Adamant hasta(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11411" - }, - { - "requirements": "{0,30}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "An adamant-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "9388", - "stand_anim": "813", - "name": "Adamant hasta(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11412", - "stand_turn_anim": "1209", - "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "9388", - "durability": null, - "name": "Adamant hasta(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11413" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "12300", - "stand_anim": "813", - "name": "Rune hasta(p)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11414", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12300", - "durability": null, - "name": "Rune hasta(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11415" - }, - { - "requirements": "{0,40}", - "turn90cw_anim": "1207", - "examine": "A karambwan poison-tipped, one-handed rune hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "stand_anim": "813", - "name": "Rune hasta(kp)", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11416", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "12200", - "stand_anim": "813", - "name": "Rune hasta(p+)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11417", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12200", - "durability": null, - "name": "Rune hasta(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11418" - }, - { - "requirements": "{0,40}", - "ge_buy_limit": "100", - "turn90cw_anim": "1207", - "examine": "A rune-tipped, one-handed hasta.", - "walk_anim": "1205", - "durability": null, - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "14", - "turn180_anim": "1206", - "render_anim": "28", - "equipment_slot": "3", - "grand_exchange_price": "15500", - "stand_anim": "813", - "name": "Rune hasta(p++)", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11419", - "stand_turn_anim": "1209", - "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "15500", - "durability": null, - "name": "Rune hasta(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11420" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two dose(s) of fishy attack potion", - "grand_exchange_price": "20", - "durability": null, - "name": "Attack mix(2)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "11429" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "20", - "durability": null, - "name": "Attack mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11430" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two dose(s) of fishy attack potion", - "grand_exchange_price": "19", - "durability": null, - "name": "Attack mix(1)", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "11431" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "19", - "durability": null, - "name": "Attack mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11432" - }, - { - "ge_buy_limit": "1000", - "examine": "Two doses of fishy antipoison potion.", - "grand_exchange_price": "455", - "durability": null, - "name": "Antipoison mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11433" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "455", - "durability": null, - "name": "Antipoison mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11434" - }, - { - "ge_buy_limit": "1000", - "examine": "Two doses of fishy antipoison potion.", - "grand_exchange_price": "608", - "durability": null, - "name": "Antipoison mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11435" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "608", - "durability": null, - "name": "Antipoison mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11436" - }, - { - "ge_buy_limit": "1000", - "examine": "2 dose: Two doses of fishy Relicym's balm.", - "grand_exchange_price": "264", - "durability": null, - "name": "Relicym's mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11437" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "264", - "durability": null, - "name": "Relicym's mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11438" - }, - { - "ge_buy_limit": "1000", - "examine": "2 dose: Two doses of fishy Relicym's balm.", - "grand_exchange_price": "131", - "durability": null, - "name": "Relicym's mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11439" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "131", - "durability": null, - "name": "Relicym's mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11440" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of fishy strength potion.", - "grand_exchange_price": "159", - "durability": null, - "name": "Strength mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11441" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "159", - "durability": null, - "name": "Strength mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11442" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of fishy strength potion.", - "grand_exchange_price": "164", - "durability": null, - "name": "Strength mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11443" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "164", - "durability": null, - "name": "Strength mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11444" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of a fishy Combat potion", - "grand_exchange_price": "366", - "durability": null, - "name": "Combat mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11445" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "366", - "durability": null, - "name": "Combat mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11446" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of a fishy Combat potion", - "grand_exchange_price": "328", - "durability": null, - "name": "Combat mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11447" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "328", - "durability": null, - "name": "Combat mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11448" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two dose(s) of fishy restore potion.", - "grand_exchange_price": "17", - "durability": null, - "name": "Restore mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11449" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "17", - "durability": null, - "name": "Restore mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11450" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two dose(s) of fishy restore potion.", - "grand_exchange_price": "24", - "durability": null, - "name": "Restore mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11451" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "24", - "durability": null, - "name": "Restore mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11452" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of fishy energy potion.", - "grand_exchange_price": "248", - "durability": null, - "name": "Energy mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11453" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "248", - "durability": null, - "name": "Energy mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11454" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of fishy energy potion.", - "grand_exchange_price": "212", - "durability": null, - "name": "Energy mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11455" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "212", - "durability": null, - "name": "Energy mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11456" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of a fishy defence potion", - "grand_exchange_price": "887", - "durability": null, - "name": "Defence mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11457" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "887", - "durability": null, - "name": "Defence mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11458" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of a fishy defence potion", - "grand_exchange_price": "780", - "durability": null, - "name": "Defence mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11459" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "780", - "durability": null, - "name": "Defence mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11460" - }, - { - "ge_buy_limit": "1000", - "examine": "2 doses of a fishy agility potion", - "grand_exchange_price": "388", - "durability": null, - "name": "Agility mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11461" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "388", - "durability": null, - "name": "Agility mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11462" - }, - { - "ge_buy_limit": "1000", - "examine": "1 dose of a fishy agility potion", - "grand_exchange_price": "459", - "durability": null, - "name": "Agility mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11463" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "459", - "durability": null, - "name": "Agility mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11464" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two dose(s) of a fishy Prayer potion.", - "grand_exchange_price": "2761", - "durability": null, - "name": "Prayer mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11465" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2761", - "durability": null, - "name": "Prayer mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11466" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two dose(s) of a fishy Prayer potion.", - "grand_exchange_price": "1857", - "durability": null, - "name": "Prayer mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11467" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1857", - "durability": null, - "name": "Prayer mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11468" - }, - { - "ge_buy_limit": "1000", - "examine": "one/two doses of fishy super attack potion", - "grand_exchange_price": "375", - "durability": null, - "name": "Superattack mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11469" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "375", - "durability": null, - "name": "Superattack mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11470" - }, - { - "ge_buy_limit": "1000", - "examine": "one/two doses of fishy super attack potion", - "grand_exchange_price": "516", - "durability": null, - "name": "Superattack mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11471" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "516", - "durability": null, - "name": "Superattack mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11472" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two dose(s) of fishy super antipoison potion.", - "grand_exchange_price": "613", - "durability": null, - "name": "Anti-p supermix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11473" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "613", - "durability": null, - "name": "Anti-p supermix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11474" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two dose(s) of fishy super antipoison potion.", - "grand_exchange_price": "1119", - "durability": null, - "name": "Anti-p supermix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11475" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1119", - "durability": null, - "name": "Anti-p supermix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11476" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two Doses of fishy fishing potion.", - "grand_exchange_price": "123", - "durability": null, - "name": "Fishing mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11477" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "123", - "durability": null, - "name": "Fishing mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11478" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two Doses of fishy fishing potion.", - "grand_exchange_price": "87", - "durability": null, - "name": "Fishing mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11479" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "87", - "durability": null, - "name": "Fishing mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11480" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy super energy potion.", - "grand_exchange_price": "1062", - "durability": null, - "name": "Super energy mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11481" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1062", - "durability": null, - "name": "Super energy mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11482" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy super energy potion.", - "grand_exchange_price": "562", - "durability": null, - "name": "Super energy mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11483" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "562", - "durability": null, - "name": "Super energy mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11484" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy Super strength potion.", - "grand_exchange_price": "955", - "durability": null, - "name": "Super strength mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11485" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "955", - "durability": null, - "name": "Super strength mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11486" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy Super strength potion.", - "grand_exchange_price": "1040", - "durability": null, - "name": "Super strength mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11487" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1040", - "durability": null, - "name": "Super strength mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11488" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy Magic essence potion.", - "grand_exchange_price": "808", - "durability": null, - "name": "Magic ess. mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11489" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "808", - "durability": null, - "name": "Magic ess. mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11490" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy Magic essence potion.", - "grand_exchange_price": "447", - "durability": null, - "name": "Magic ess. mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11491" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "447", - "durability": null, - "name": "Magic ess. mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11492" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy super restore potion.", - "grand_exchange_price": "3670", - "durability": null, - "name": "Super restore mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11493" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3670", - "durability": null, - "name": "Super restore mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11494" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy super restore potion.", - "grand_exchange_price": "3104", - "durability": null, - "name": "Super restore mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11495" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "3104", - "durability": null, - "name": "Super restore mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11496" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of fishy super defence potion", - "grand_exchange_price": "38", - "durability": null, - "name": "Super defence mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11497" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "38", - "durability": null, - "name": "Super defence mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11498" - }, - { - "ge_buy_limit": "1000", - "examine": "One/two doses of fishy super defence potion", - "grand_exchange_price": "66", - "durability": null, - "name": "Super defence mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11499" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "66", - "durability": null, - "name": "Super defence mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11500" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy extra strength antidote potion.", - "grand_exchange_price": "1909", - "durability": null, - "name": "Antidote+ mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11501" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1909", - "durability": null, - "name": "Antidote+ mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11502" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy extra strength antidote potion.", - "grand_exchange_price": "1330", - "durability": null, - "name": "Antidote+ mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11503" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1330", - "durability": null, - "name": "Antidote+ mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11504" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two dose(s) of fishy anti-fire breath potion.", - "grand_exchange_price": "2048", - "durability": null, - "name": "Antifire mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11505" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2048", - "durability": null, - "name": "Antifire mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11506" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two dose(s) of fishy anti-fire breath potion.", - "grand_exchange_price": "1444", - "durability": null, - "name": "Antifire mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11507" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1444", - "durability": null, - "name": "Antifire mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11508" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy ranging potion.", - "grand_exchange_price": "2879", - "durability": null, - "name": "Ranging mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11509" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "2879", - "durability": null, - "name": "Ranging mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11510" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy ranging potion.", - "grand_exchange_price": "1880", - "durability": null, - "name": "Ranging mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11511" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1880", - "durability": null, - "name": "Ranging mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11512" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy magic potion.", - "grand_exchange_price": "1022", - "durability": null, - "name": "Magic mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11513" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1022", - "durability": null, - "name": "Magic mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11514" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy magic potion.", - "grand_exchange_price": "1323", - "durability": null, - "name": "Magic mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11515" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "1323", - "durability": null, - "name": "Magic mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11516" - }, - { - "ge_buy_limit": "1000", - "examine": "Doses of fishy hunting potion", - "grand_exchange_price": "146", - "durability": null, - "name": "Hunting mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11517" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "146", - "durability": null, - "name": "Hunting mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11518" - }, - { - "ge_buy_limit": "1000", - "examine": "Doses of fishy hunting potion", - "grand_exchange_price": "87", - "durability": null, - "name": "Hunting mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11519" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "87", - "durability": null, - "name": "Hunting mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11520" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy Zamorak potion.", - "grand_exchange_price": "665", - "durability": null, - "name": "Zamorak mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11521" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "665", - "durability": null, - "name": "Zamorak mix(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11522" - }, - { - "ge_buy_limit": "1000", - "examine": "One/Two doses of fishy Zamorak potion.", - "grand_exchange_price": "339", - "durability": null, - "name": "Zamorak mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "weight": "0.1", - "id": "11523" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "339", - "durability": null, - "name": "Zamorak mix(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11524" - }, - { - "ge_buy_limit": "5000", - "examine": "More fluff than feather.", - "grand_exchange_price": "325", - "durability": null, - "name": "Wimpy feather", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11525" - }, - { - "destroy_message": "If you drop this book it will be destroyed. You cannot replace it.", - "examine": "Educate yourself.", - "durability": null, - "name": "Book of knowledge", - "weight": "1", - "archery_ticket_price": "0", - "id": "11640" - }, - { - "durability": null, - "name": "Astronomy book", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11655" - }, - { - "ge_buy_limit": "100", - "examine": "A book that explains the art of crafting items from glass.", - "grand_exchange_price": "278", - "durability": null, - "name": "Glassblowing book", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11656" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "278", - "durability": null, - "name": "Glassblowing book", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11657" - }, - { - "remove_head": "true", - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "200", - "examine": "A mage helm from the order of the Void Knights.", - "durability": null, - "name": "Void mage helm", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11663", - "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "200", - "examine": "A ranger helm from the order of the Void Knights", - "durability": null, - "name": "Void ranger helm", - "tradeable": "false", - "weight": "3.6", - "archery_ticket_price": "0", - "id": "11664", - "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "200", - "examine": "A melee helm from the order of the Void Knights.", - "durability": null, - "name": "Void melee helm", - "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "11665", - "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", - "equipment_slot": "0" - }, - { - "durability": null, - "name": "Void seal(8)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11666", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(7)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11667", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(6)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11668", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(5)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11669", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(4)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11670", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(3)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11671", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(2)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11672", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "durability": null, - "name": "Void seal(1)", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "11673", - "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", - "equipment_slot": "2" - }, - { - "remove_head": "true", - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "200", - "examine": "A mage helm from the order of the Void Knights.", - "durability": null, - "name": "Void mage helm", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11674", - "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "200", - "examine": "A ranger helm from the order of the Void Knights", - "durability": null, - "name": "Void ranger helm", - "tradeable": "false", - "weight": "3.6", - "archery_ticket_price": "0", - "id": "11675", - "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", - "shop_price": "200", - "examine": "A melee helm from the order of the Void Knights.", - "durability": null, - "name": "Void melee helm", - "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "11676", - "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "I can find another book in the Keldagrim library.", - "examine": "\"Beyond Trollheim\" by Nestor Peregrine.", - "durability": null, - "name": "Explorer's notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11677" - }, - { - "destroy_message": "You'll need to visit the Sinclair Mansion to get another one.", - "examine": "A black helm, too small for your head", - "durability": null, - "name": "Black knight helm", - "tradeable": "false", - "destroy": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "11678" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11679" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A change of address form.", - "durability": null, - "name": "Address form", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11680" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "It has something written on it.", - "durability": null, - "name": "Scrap paper", - "archery_ticket_price": "0", - "id": "11681" - }, - { - "examine": "I could use this to pick the lock.", - "durability": null, - "name": "Hair clip", - "archery_ticket_price": "0", - "id": "11682" - }, - { - "ge_buy_limit": "10", - "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", - "grand_exchange_price": "331300", - "durability": null, - "name": "Godsword shards", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11686" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "331300", - "durability": null, - "name": "Godsword shards", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11687" - }, - { - "ge_buy_limit": "10", - "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", - "grand_exchange_price": "342100", - "durability": null, - "name": "Godsword shards", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11688" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "342100", - "durability": null, - "name": "Godsword shards", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11689" - }, - { - "ge_buy_limit": "10", - "examine": "The blade for the ultimate weapon.", - "grand_exchange_price": "466800", - "durability": null, - "name": "Godsword blade", - "tradeable": "true", - "weight": "7.5", - "archery_ticket_price": "0", - "id": "11690" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "466800", - "durability": null, - "name": "Godsword blade", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11691" - }, - { - "ge_buy_limit": "10", - "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", - "grand_exchange_price": "348500", - "durability": null, - "name": "Godsword shards", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11692" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "348500", - "durability": null, - "name": "Godsword shards", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11693" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "7043", - "examine": "A beautiful, heavy sword.", - "walk_anim": "7046", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "7044", - "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "28000000", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "11694", - "stand_turn_anim": "7040", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", - "requirements": "{0,75}", - "durability": null, - "weight": "10", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", - "attack_audios": "3846,0,0,0", - "name": "Armadyl godsword" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "28000000", - "durability": null, - "name": "Armadyl godsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11695" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "7043", - "examine": "A brutally heavy sword.", - "walk_anim": "7046", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "7044", - "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "3700000", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "11696", - "stand_turn_anim": "7040", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", - "requirements": "{0,75}", - "durability": null, - "weight": "10", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", - "attack_audios": "3846,0,0,0", - "name": "Bandos godsword" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "3700000", - "durability": null, - "name": "Bandos godsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11697" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "7043", - "examine": "A gracious, heavy sword.", - "walk_anim": "7046", - "has_special": "true", - "turn90ccw_anim": "7044", - "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "22000000", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "11698", - "stand_turn_anim": "7040", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", - "requirements": "{0,75}", - "durability": null, - "weight": "10", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", - "attack_audios": "3846,0,0,0", - "name": "Saradomin godsword" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "22000000", - "durability": null, - "name": "Saradomin godsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11699" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "7043", - "examine": "A terrifying, heavy sword.", - "walk_anim": "7046", - "has_special": "true", - "turn90ccw_anim": "7044", - "attack_speed": "6", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "6100000", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "11700", - "stand_turn_anim": "7040", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", - "requirements": "{0,75}", - "durability": null, - "weight": "10", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", - "attack_audios": "3846,0,0,0", - "name": "Zamorak godsword" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "6100000", - "durability": null, - "name": "Zamorak godsword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11701" - }, - { - "ge_buy_limit": "10", - "examine": "Brimming with potential.", - "grand_exchange_price": "30600000", - "rare_item": "true", - "durability": null, - "name": "Armadyl hilt", - "tradeable": "true", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "11702" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "30600000", - "durability": null, - "name": "Armadyl hilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11703" - }, - { - "ge_buy_limit": "10", - "examine": "Brimming with potential.", - "grand_exchange_price": "3300000", - "rare_item": "true", - "durability": null, - "name": "Bandos hilt", - "tradeable": "true", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "11704" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "3300000", - "durability": null, - "name": "Bandos hilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11705" - }, - { - "ge_buy_limit": "10", - "examine": "Brimming with potential.", - "grand_exchange_price": "24900000", - "rare_item": "true", - "durability": null, - "name": "Saradomin hilt", - "tradeable": "true", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "11706" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "24900000", - "durability": null, - "name": "Saradomin hilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11707" - }, - { - "ge_buy_limit": "10", - "examine": "Brimming with potential.", - "grand_exchange_price": "6100000", - "rare_item": "true", - "durability": null, - "name": "Zamorak hilt", - "tradeable": "true", - "weight": "2.5", - "archery_ticket_price": "0", - "id": "11708" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "6100000", - "durability": null, - "name": "Zamorak hilt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11709" - }, - { - "ge_buy_limit": "10", - "examine": "Part of the Godsword blade.", - "grand_exchange_price": "150200", - "durability": null, - "rare_item": "true", - "name": "Godsword shard 1", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11710" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "150200", - "durability": null, - "name": "Godsword shard 1", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11711" - }, - { - "ge_buy_limit": "10", - "examine": "Part of the Godsword blade.", - "grand_exchange_price": "149100", - "durability": null, - "rare_item": "true", - "name": "Godsword shard 2", - "tradeable": "true", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11712" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "149100", - "durability": null, - "name": "Godsword shard 2", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11713" - }, - { - "ge_buy_limit": "10", - "examine": "Part of the Godsword blade.", - "grand_exchange_price": "149800", - "durability": null, - "rare_item": "true", - "name": "Godsword shard 3", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11714" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "149800", - "durability": null, - "name": "Godsword shard 3", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11715" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "An evil spear.", - "walk_anim": "1205", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "two_handed": "true", - "turn180_anim": "1206", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "grand_exchange_price": "5400000", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11716", - "stand_turn_anim": "1209", - "bonuses": "85,65,65,0,0,13,13,12,0,13,0,75,2,0,0", - "requirements": "{0,70}", - "durability": null, - "weight": "3", - "weapon_interface": "14", - "render_anim": "28", - "lendable": "true", - "name": "Zamorakian spear" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "5400000", - "durability": null, - "name": "Zamorakian spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11717" - }, - { - "remove_head": "true", - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "1", - "examine": "A helmet of great craftmanship.", - "rare_item": "true", - "durability": null, - "weight": "0.5", - "absorb": "0,5,2", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "4100000", - "name": "Armadyl helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11718", - "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "4100000", - "durability": null, - "name": "Armadyl helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11719" - }, - { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "1", - "examine": "A chestplate of great craftsmanship", - "rare_item": "true", - "durability": null, - "weight": "4", - "absorb": "0,10,5", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "14800000", - "name": "Armadyl chestplate", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11720", - "bonuses": "-7,-7,-7,-15,33,56,48,61,70,57,52,0,1,0,0" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "14800000", - "durability": null, - "name": "Armadyl chestplate", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11721" - }, - { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "2", - "examine": "A plateskirt of great craftsmanship.", - "rare_item": "true", - "durability": null, - "weight": "8", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "14800000", - "name": "Armadyl plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11722", - "bonuses": "-6,-6,-6,-10,20,32,26,34,40,33,25,0,1,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "14800000", - "durability": null, - "name": "Armadyl plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11723" - }, - { - "requirements": "{1,65}", - "ge_buy_limit": "1", - "examine": "A sturdy chestplate.", - "rare_item": "true", - "durability": null, - "weight": "12", - "absorb": "4,0,9", - "equipment_slot": "4", - "lendable": "true", - "remove_sleeves": "true", - "grand_exchange_price": "14700000", - "name": "Bandos chestplate", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11724", - "bonuses": "0,0,0,-15,-10,98,93,105,-6,133,52,4,1,0,0" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "14700000", - "durability": null, - "name": "Bandos chestplate", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11725" - }, - { - "requirements": "{1,65}", - "ge_buy_limit": "1", - "examine": "A sturdy pair of tassets.", - "rare_item": "true", - "durability": null, - "weight": "8", - "absorb": "3,0,6", - "equipment_slot": "7", - "lendable": "true", - "grand_exchange_price": "15200000", - "name": "Bandos tassets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11726", - "bonuses": "0,0,0,-21,-7,71,63,66,-4,93,25,2,1,0,0" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "15200000", - "durability": null, - "name": "Bandos tassets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11727" - }, - { - "requirements": "{1,65}", - "ge_buy_limit": "1", - "examine": "Some sturdy boots", - "rare_item": "true", - "durability": null, - "weight": "6", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "111700", - "name": "Bandos boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11728", - "bonuses": "0,0,0,-5,-3,17,18,19,0,0,15,0,1,0,0" - }, - { - "ge_buy_limit": "1", - "grand_exchange_price": "111700", - "durability": null, - "name": "Bandos boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11729" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "7043", - "examine": "The incredible blade of an Icyene.", - "walk_anim": "7046", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "7044", - "attack_speed": "4", - "two_handed": "true", - "turn180_anim": "7045", - "defence_anim": "7050", - "equipment_slot": "3", - "attack_anims": "7041,7041,7048,7049", - "grand_exchange_price": "5300000", - "stand_anim": "7047", - "tradeable": "true", - "run_anim": "7039", - "archery_ticket_price": "0", - "id": "11730", - "stand_turn_anim": "7040", - "bonuses": "0,82,60,0,0,0,0,0,0,0,0,82,2,0,0", - "requirements": "{0,70}", - "durability": null, - "weight": "3", - "weapon_interface": "7", - "render_anim": "124", - "lendable": "true", - "attack_audios": "3846,0,0,0", - "name": "Saradomin sword" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "5300000", - "durability": null, - "name": "Saradomin sword", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11731" - }, - { - "requirements": "{1,60}", - "ge_buy_limit": "10", - "examine": "These will protect my feet.", - "durability": null, - "rare_item": "true", - "weight": "1", - "equipment_slot": "10", - "lendable": "true", - "grand_exchange_price": "95400", - "name": "Dragon boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11732", - "bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "95400", - "durability": null, - "name": "Dragon boots", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11733" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A scroll for Sir Tiffy. It is sealed with a wax insignia.", - "durability": null, - "name": "Knight's notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11734" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A scroll for Sir Tiffy. The wax seal is broken.", - "durability": null, - "name": "Knight's notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11735" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "231300", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11736", - "stand_turn_anim": "1209", - "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", - "requirements": "{0,30}-{6,30}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "equip_audio": "2230", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Steam battlestaff" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "231300", - "durability": null, - "name": "Steam battlestaff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11737" - }, - { - "ge_buy_limit": "10", - "turn90cw_anim": "1207", - "examine": "It's a slightly magical stick.", - "walk_anim": "1205", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "grand_exchange_price": "267600", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "11738", - "stand_turn_anim": "1209", - "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", - "requirements": "{0,40}-{6,40}", - "durability": null, - "weight": "2", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Mystic steam staff" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "267600", - "durability": null, - "name": "Mystic steam staff", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11739" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11741" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11743" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11745" - }, - { - "destroy_message": "There may be another in the chest where you found this.", - "examine": "This probably opens a chest in Golrie's caves. (Path of Glophrie)", - "durability": null, - "name": "A key to a chest", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11747" - }, - { - "destroy_message": "There may be another in the chest where you found this.", - "examine": "This opens the door into Golrie's strongroom. (Path of Glophrie)", - "durability": null, - "name": "Strongroom key", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11748" - }, - { - "destroy_message": "Maybe Brimstail will have another crystal seed you could grow into a chime.", - "examine": "It makes a sound.", - "durability": null, - "name": "Crystal chime", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11749", - "equipment_slot": "3" - }, - { - "destroy_message": "There may be another in the chest where you found this.", - "examine": "Notes written by Yewnock while copying Oaknock's machine.", - "durability": null, - "name": "Yewnock's notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11750" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11753" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11754" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11755" - }, - { - "destroy_message": "You will need to get a new set of armour from Rat Burgiss if you destroy this one.", - "remove_sleeves": "true", - "examine": "Varrock Smithing armour.", - "durability": null, - "name": "Varrock armour 1", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11756", - "bonuses": "0,0,0,-30,-10,15,14,9,-6,14,5,0,0,0,0", - "equipment_slot": "4" - }, - { - "destroy_message": "You will need to get a new set of armour from Reldo if you destroy this one.", - "remove_sleeves": "true", - "examine": "Varrock smithing armour.", - "durability": null, - "name": "Varrock armour 2", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11757", - "bonuses": "0,0,0,-30,-10,21,20,12,-6,20,5,0,0,0,0", - "equipment_slot": "4" - }, - { - "destroy_message": "You will need to get a new set of armour from Vannaka if you destroy this one.", - "remove_sleeves": "true", - "examine": "Varrock smithing armour.", - "durability": null, - "name": "Varrock armour 3", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11758", - "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", - "equipment_slot": "4" - }, - { "shop_price": "4", - "examine": "A number of wooden logs.", - "grand_exchange_price": "124", + "tradeable": "false" + }, + { + "id": "11210", + "name": "Golden goblin", + "examine": "A shiny golden goblin. Strange!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", "durability": null, - "name": "Logs", + "tradeable": "false", + "weight": "30" + }, + { + "id": "11211", + "name": "Magic beans", + "examine": "A bag of magic beans.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to get another bag of beans from Sylas if you destroy this one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11212", + "name": "Dragon arrow", + "examine": "An arrow made using a dragon's talon.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true" + }, + { + "id": "11217", + "name": "Dragon fire arrows", + "examine": "unlit: Arrows with dragon heads and oil-soaked cloth.lit: Dragon-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true" + }, + { + "id": "11222", + "name": "Dragon fire arrows", + "examine": "unlit: Arrows with dragon heads and oil-soaked cloth.lit: Dragon-headed fire arrow.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true" + }, + { + "id": "11227", + "name": "Dragon arrow(p)", + "examine": "An arrow made using a dragon's talon.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true" + }, + { + "id": "11228", + "name": "Dragon arrow(p+)", + "examine": "An arrow made using a dragon's talon.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true" + }, + { + "id": "11229", + "name": "Dragon arrow(p++)", + "examine": "An arrow made using a dragon's talon.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true" + }, + { + "id": "11230", + "name": "Dragon dart", + "examine": "A deadly throwing dart with a dragon tip.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,60}", "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11760" + "weapon_interface": "18" }, { - "destroy_message": "You can get the diary again from Sandy's desk.", - "examine": "A locked/unlocked diary.", + "id": "11231", + "name": "Dragon dart(p)", + "examine": "A deadly throwing dart with a dragon tip.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20", "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "11232", + "name": "Dragon dart tip", + "examine": "A deadly looking dragon dart tip - needs feathers for flight.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11233", + "name": "Dragon dart(p+)", + "examine": "A deadly throwing dart with a dragon tip.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "11234", + "name": "Dragon dart(p++)", + "examine": "A deadly throwing dart with a dragon tip.", + "archery_ticket_price": "0", + "attack_audios": "2547,0,0,0", + "attack_speed": "3", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "10000", + "requirements": "{4,60}", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "11235", + "name": "Dark bow", + "examine": "A bow from a darker dimension.", + "archery_ticket_price": "0", + "attack_anims": "426,426,426,426", + "attack_audios": "3731,0,0,0", + "attack_speed": "9", + "bonuses": "0,0,0,0,95,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "424", + "durability": null, + "equip_audio": "3738", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "1", + "requirements": "{4,60}", + "run_anim": "824", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "two_handed": "true", + "walk_anim": "819", + "weapon_interface": "16", + "weight": "1.9" + }, + { + "id": "11236", + "name": "Dark bow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11237", + "name": "Dragon arrowtips", + "examine": "Dragon talons, usable as arrowheads.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "11238", + "name": "Baby impling jar", + "examine": "A baby impling in a jar. That's a bit cruel.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11239", + "name": "Baby impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11240", + "name": "Young impling jar", + "examine": "A young impling in a jar. Don't trap me, man.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11241", + "name": "Young impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11242", + "name": "Gourm' impling jar", + "examine": "A gourmet impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11243", + "name": "Gourm' impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11244", + "name": "Earth impling jar", + "examine": "Earth impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11245", + "name": "Earth impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11246", + "name": "Ess' impling jar", + "examine": "Essence impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11247", + "name": "Ess' impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11248", + "name": "Eclectic impling jar", + "examine": "Eclectic impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11249", + "name": "Eclectic impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11250", + "name": "Nature impling jar", + "examine": "Nature impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11251", + "name": "Nature impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11252", + "name": "Magpie impling jar", + "examine": "Magpie impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "11253", + "name": "Magpie impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11254", + "name": "Ninja impling jar", + "examine": "Ninja impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "1" + }, + { + "id": "11255", + "name": "Ninja impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11256", + "name": "Dragon impling jar", + "examine": "Dragon impling in a jar.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "11257", + "name": "Dragon impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "500", + "tradeable": "true" + }, + { + "id": "11258", + "name": "Jar generator", + "examine": "Creates butterfly and impling jars.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11259", + "name": "Magic butterfly net", + "examine": "For catching butterflies.", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "You will have to trade with Elnock to get a new magic butterfly net.", + "durability": null, + "equipment_slot": "3", + "render_anim": "1426", + "requirements": "{21,17}", + "run_anim": "6603", + "shop_price": "3", + "stand_anim": "6604", + "stand_turn_anim": "6611", + "tradeable": "false", + "turn180_anim": "6608", + "turn90ccw_anim": "6609", + "turn90cw_anim": "6610", + "two_handed": "", + "walk_anim": "6607", + "weapon_interface": "14", + "weight": "0.2" + }, + { + "id": "11260", + "name": "Impling jar", + "examine": "It's got little holes in the top.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "11261", + "name": "Impling jar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11262", + "name": "Imp repellent", + "examine": "Imps seem to hate this stuff. Can't say I blame them.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "3", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11263", + "name": "Imp repellent", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11264", + "name": "Anchovy oil", + "examine": "Omega 3 oil. Good for the brain, not so for the nose.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11265", + "name": "Anchovy oil", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11266", + "name": "Anchovy paste", + "examine": "Fish paste. Urk.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11267", + "name": "Picture", + "examine": "I can train on this", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11268", + "name": "Picture", + "examine": "I can train on this", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11269", + "name": "Picture", + "examine": "I can train on this", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11270", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11271", + "name": "Picture", + "examine": "I can train on this", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11272", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11273", + "name": "Impling scroll", + "examine": "Lets you easily identify your prey.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will have to ask Elnock for another one of these.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11274", + "name": "Ham shirt", + "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "true", + "weight": "0.9" + }, + { + "id": "11275", + "name": "Mith grapple", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11276", + "name": "Mith grapple", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11277", + "name": "Cavalier mask", + "examine": "I hope I don't meet any roundheads...", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "8", + "lendable": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "11278", + "name": "Beret mask", + "examine": "Essential mime wear.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "weight": "1" + }, + { + "id": "11279", + "name": "Elvarg's head", + "examine": "The severed head of the great dragon Elvarg!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can complete the quest by speaking to Oziach even if you do not have the head.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "11280", + "name": "Cavalier and mask", + "examine": "I hope I don't meet any roundheads...", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "11281", + "name": "Cavalier and mask", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11282", + "name": "Beret and mask", + "examine": "Essential mime wear.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "weight": "1" + }, + { + "id": "11283", + "name": "Dragonfire shield", + "examine": "A heavy shield with a snarling, draconic visage.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-5,20,25,22,10,22,17,7,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "rare_item": "true", + "requirements": "{1,75}", + "weight": "7.2" + }, + { + "id": "11284", + "name": "Dragonfire shield", + "examine": "A heavy shield with a snarling, draconic visage.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-10,-5,20,25,22,10,22,17,7,0,0,0", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "ge_buy_limit": "10", + "rare_item": "true", + "requirements": "{1,75}", + "tradeable": "true", + "weight": "7.2" + }, + { + "id": "11285", + "name": "Dragonfire shield", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11286", + "name": "Draconic visage", + "examine": "It looks like this could be attached to a shield somehow.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "11287", + "name": "Draconic visage", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11323", + "name": "Barbarian rod", + "examine": "A heavy barbarian Fishing rod.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "11324", + "name": "Roe", + "examine": "Roe, or cheap fishy eggs.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "6", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "11325", + "name": "Roe", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11326", + "name": "Caviar", + "examine": "Caviar, or expensive fishy eggs.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true", + "weight": "0.05" + }, + { + "id": "11327", + "name": "Caviar", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11328", + "name": "Leaping trout", + "examine": "A sad-looking trout.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "shop_price": "11", + "tradeable": "true" + }, + { + "id": "11329", + "name": "Leaping trout", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11330", + "name": "Leaping salmon", + "examine": "Some non-tasty salmon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11331", + "name": "Leaping salmon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11332", + "name": "Leaping sturgeon", + "examine": "A bloated sturgeon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11333", + "name": "Leaping sturgeon", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11334", + "name": "Fish offcuts", + "examine": "Slices of inedible fish.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11335", + "name": "Dragon full helm", + "examine": "Protects your head and looks impressive too.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,45,48,41,-1,46,12,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11336", + "name": "Dragon full helm", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11337", + "name": "Mangled bones", + "examine": "The bones of a barbarian warrior, slain by his fellow adventurers.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can gather more from the caverns below the Baxtorian Lake.", + "durability": null, + "weight": "1" + }, + { + "id": "11338", + "name": "Chewed bones", + "examine": "The bones of a barbarian warrior, slain by vile dragons.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can gather more from the caverns below the Baxtorian Lake.", + "durability": null, + "weight": "9.6" + }, + { + "id": "11339", + "name": "My notes", + "examine": "Records from my discoveries beneath the lake.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can obtain another from Otto.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11340", + "name": "Barbarian skills", + "examine": "A record of Otto's instructions to me.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can obtain another from Otto.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11341", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11342", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11343", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11344", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11345", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11346", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11347", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11348", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11349", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11350", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11351", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11352", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11353", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11354", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11355", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11356", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11357", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11358", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11359", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11360", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11361", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11362", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11363", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11364", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11365", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11366", + "name": "Ancient page", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11367", + "name": "Bronze hasta", + "examine": "A bronze-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11368", + "name": "Bronze hasta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11369", + "name": "Iron hasta", + "examine": "An iron-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11370", + "name": "Iron hasta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11371", + "name": "Steel hasta", + "examine": "A steel-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11372", + "name": "Steel hasta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11373", + "name": "Mithril hasta", + "examine": "A mithril-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "11374", + "name": "Mithril hasta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11375", + "name": "Adamant hasta", + "examine": "An adamant-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11376", + "name": "Adamant hasta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11377", + "name": "Rune hasta", + "examine": "A rune-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11378", + "name": "Rune hasta", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11379", + "name": "Bronze hasta(p)", + "examine": "A bronze-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11380", + "name": "Bronze hasta(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11381", + "name": "Bronze hasta(kp)", + "examine": "A karambwan poison-tipped, one-handed bronze hasta.", + "archery_ticket_price": "0", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11382", + "name": "Bronze hasta(p+)", + "examine": "A bronze-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11383", + "name": "Bronze hasta(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11384", + "name": "Bronze hasta(p++)", + "examine": "A bronze-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11385", + "name": "Bronze hasta(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11386", + "name": "Iron hasta(p)", + "examine": "An iron-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11387", + "name": "Iron hasta(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11388", + "name": "Iron hasta(kp)", + "examine": "A karambwan poison-tipped, one-handed iron hasta.", + "archery_ticket_price": "0", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11389", + "name": "Iron hasta(p+)", + "examine": "An iron-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11390", + "name": "Iron hasta(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11391", + "name": "Iron hasta(p++)", + "examine": "An iron-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11392", + "name": "Iron hasta(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11393", + "name": "Steel hasta(p)", + "examine": "A steel-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11394", + "name": "Steel hasta(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11395", + "name": "Steel hasta(kp)", + "examine": "A karambwan poison-tipped, one-handed steel hasta.", + "archery_ticket_price": "0", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11396", + "name": "Steel hasta(p+)", + "examine": "A steel-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11397", + "name": "Steel hasta(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11398", + "name": "Steel hasta(p++)", + "examine": "A steel-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,5}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11399", + "name": "Steel hasta(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11400", + "name": "Mithril hasta(p)", + "examine": "A mithril-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "11401", + "name": "Mithril hasta(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11402", + "name": "Mithril hasta(kp)", + "examine": "A karambwan poison-tipped, one-handed mithril hasta", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "11403", + "name": "Mithril hasta(p+)", + "examine": "A mithril-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "11404", + "name": "Mithril hasta(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11405", + "name": "Mithril hasta(p++)", + "examine": "A mithril-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,20}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "1.8" + }, + { + "id": "11406", + "name": "Mithril hasta(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11407", + "name": "Adamant hasta(p)", + "examine": "An adamant-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11408", + "name": "Adamant hasta(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11409", + "name": "Adamant hasta(kp)", + "examine": "\tA karambwan poison-tipped, one-handed adamantite hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11410", + "name": "Adamant hasta(p+)", + "examine": "An adamant-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11411", + "name": "Adamant hasta(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11412", + "name": "Adamant hasta(p++)", + "examine": "An adamant-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11413", + "name": "Adamant hasta(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11414", + "name": "Rune hasta(p)", + "examine": "A rune-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11415", + "name": "Rune hasta(p)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11416", + "name": "Rune hasta(kp)", + "examine": "A karambwan poison-tipped, one-handed rune hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11417", + "name": "Rune hasta(p+)", + "examine": "A rune-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11418", + "name": "Rune hasta(p+)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11419", + "name": "Rune hasta(p++)", + "examine": "A rune-tipped, one-handed hasta.", + "archery_ticket_price": "0", + "attack_audios": "2562,2556,2555,2562", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "28", + "requirements": "{0,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "2.2" + }, + { + "id": "11420", + "name": "Rune hasta(p++)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11429", + "name": "Attack mix(2)", + "examine": "One/Two dose(s) of fishy attack potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11430", + "name": "Attack mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11431", + "name": "Attack mix(1)", + "examine": "One/Two dose(s) of fishy attack potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11432", + "name": "Attack mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11433", + "name": "Antipoison mix(2)", + "examine": "Two doses of fishy antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11434", + "name": "Antipoison mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11435", + "name": "Antipoison mix(1)", + "examine": "Two doses of fishy antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11436", + "name": "Antipoison mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11437", + "name": "Relicym's mix(2)", + "examine": "2 dose: Two doses of fishy Relicym's balm.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11438", + "name": "Relicym's mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11439", + "name": "Relicym's mix(1)", + "examine": "2 dose: Two doses of fishy Relicym's balm.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11440", + "name": "Relicym's mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11441", + "name": "Strength mix(1)", + "examine": "One/two doses of fishy strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11442", + "name": "Strength mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11443", + "name": "Strength mix(2)", + "examine": "One/two doses of fishy strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11444", + "name": "Strength mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11445", + "name": "Combat mix(2)", + "examine": "One/two doses of a fishy Combat potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11446", + "name": "Combat mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11447", + "name": "Combat mix(1)", + "examine": "One/two doses of a fishy Combat potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11448", + "name": "Combat mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11449", + "name": "Restore mix(2)", + "examine": "One/two dose(s) of fishy restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11450", + "name": "Restore mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11451", + "name": "Restore mix(1)", + "examine": "One/two dose(s) of fishy restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11452", + "name": "Restore mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11453", + "name": "Energy mix(2)", + "examine": "One/two doses of fishy energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11454", + "name": "Energy mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11455", + "name": "Energy mix(1)", + "examine": "One/two doses of fishy energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11456", + "name": "Energy mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11457", + "name": "Defence mix(2)", + "examine": "One/two doses of a fishy defence potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11458", + "name": "Defence mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11459", + "name": "Defence mix(1)", + "examine": "One/two doses of a fishy defence potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11460", + "name": "Defence mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11461", + "name": "Agility mix(2)", + "examine": "2 doses of a fishy agility potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11462", + "name": "Agility mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11463", + "name": "Agility mix(1)", + "examine": "1 dose of a fishy agility potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11464", + "name": "Agility mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11465", + "name": "Prayer mix(2)", + "examine": "One/two dose(s) of a fishy Prayer potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11466", + "name": "Prayer mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11467", + "name": "Prayer mix(1)", + "examine": "One/two dose(s) of a fishy Prayer potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11468", + "name": "Prayer mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11469", + "name": "Superattack mix(2)", + "examine": "one/two doses of fishy super attack potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11470", + "name": "Superattack mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11471", + "name": "Superattack mix(1)", + "examine": "one/two doses of fishy super attack potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11472", + "name": "Superattack mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11473", + "name": "Anti-p supermix(2)", + "examine": "One/Two dose(s) of fishy super antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11474", + "name": "Anti-p supermix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11475", + "name": "Anti-p supermix(1)", + "examine": "One/Two dose(s) of fishy super antipoison potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11476", + "name": "Anti-p supermix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11477", + "name": "Fishing mix(2)", + "examine": "One/Two Doses of fishy fishing potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11478", + "name": "Fishing mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11479", + "name": "Fishing mix(1)", + "examine": "One/Two Doses of fishy fishing potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11480", + "name": "Fishing mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11481", + "name": "Super energy mix(2)", + "examine": "One/Two doses of fishy super energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11482", + "name": "Super energy mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11483", + "name": "Super energy mix(1)", + "examine": "One/Two doses of fishy super energy potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11484", + "name": "Super energy mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11485", + "name": "Super strength mix(2)", + "examine": "One/Two doses of fishy Super strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11486", + "name": "Super strength mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11487", + "name": "Super strength mix(1)", + "examine": "One/Two doses of fishy Super strength potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11488", + "name": "Super strength mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11489", + "name": "Magic ess. mix(2)", + "examine": "One/Two doses of fishy Magic essence potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11490", + "name": "Magic ess. mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11491", + "name": "Magic ess. mix(1)", + "examine": "One/Two doses of fishy Magic essence potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11492", + "name": "Magic ess. mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11493", + "name": "Super restore mix(2)", + "examine": "One/Two doses of fishy super restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11494", + "name": "Super restore mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11495", + "name": "Super restore mix(1)", + "examine": "One/Two doses of fishy super restore potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11496", + "name": "Super restore mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11497", + "name": "Super defence mix(2)", + "examine": "One/two doses of fishy super defence potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11498", + "name": "Super defence mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11499", + "name": "Super defence mix(1)", + "examine": "One/two doses of fishy super defence potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11500", + "name": "Super defence mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11501", + "name": "Antidote+ mix(2)", + "examine": "One/Two doses of fishy extra strength antidote potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11502", + "name": "Antidote+ mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11503", + "name": "Antidote+ mix(1)", + "examine": "One/Two doses of fishy extra strength antidote potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11504", + "name": "Antidote+ mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11505", + "name": "Antifire mix(2)", + "examine": "One/Two dose(s) of fishy anti-fire breath potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11506", + "name": "Antifire mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11507", + "name": "Antifire mix(1)", + "examine": "One/Two dose(s) of fishy anti-fire breath potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11508", + "name": "Antifire mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11509", + "name": "Ranging mix(2)", + "examine": "One/Two doses of fishy ranging potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11510", + "name": "Ranging mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11511", + "name": "Ranging mix(1)", + "examine": "One/Two doses of fishy ranging potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11512", + "name": "Ranging mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11513", + "name": "Magic mix(2)", + "examine": "One/Two doses of fishy magic potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11514", + "name": "Magic mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11515", + "name": "Magic mix(1)", + "examine": "One/Two doses of fishy magic potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11516", + "name": "Magic mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11517", + "name": "Hunting mix(2)", + "examine": "Doses of fishy hunting potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11518", + "name": "Hunting mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11519", + "name": "Hunting mix(1)", + "examine": "Doses of fishy hunting potion", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11520", + "name": "Hunting mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11521", + "name": "Zamorak mix(2)", + "examine": "One/Two doses of fishy Zamorak potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11522", + "name": "Zamorak mix(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11523", + "name": "Zamorak mix(1)", + "examine": "One/Two doses of fishy Zamorak potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "11524", + "name": "Zamorak mix(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "11525", + "name": "Wimpy feather", + "examine": "More fluff than feather.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "11640", + "name": "Book of knowledge", + "examine": "Educate yourself.", + "archery_ticket_price": "0", + "destroy_message": "If you drop this book it will be destroyed. You cannot replace it.", + "durability": null, + "weight": "1" + }, + { + "id": "11655", + "name": "Astronomy book", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11656", + "name": "Glassblowing book", + "examine": "A book that explains the art of crafting items from glass.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11657", + "name": "Glassblowing book", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11663", + "name": "Void mage helm", + "examine": "A mage helm from the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "tradeable": "false" + }, + { + "id": "11664", + "name": "Void ranger helm", + "examine": "A ranger helm from the order of the Void Knights", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "tradeable": "false", + "weight": "3.6" + }, + { + "id": "11665", + "name": "Void melee helm", + "examine": "A melee helm from the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "tradeable": "false", + "weight": "1" + }, + { + "id": "11666", + "name": "Void seal(8)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11667", + "name": "Void seal(7)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11668", + "name": "Void seal(6)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11669", + "name": "Void seal(5)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11670", + "name": "Void seal(4)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11671", + "name": "Void seal(3)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11672", + "name": "Void seal(2)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11673", + "name": "Void seal(1)", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "2", + "tradeable": "false" + }, + { + "id": "11674", + "name": "Void mage helm", + "examine": "A mage helm from the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "tradeable": "false" + }, + { + "id": "11675", + "name": "Void ranger helm", + "examine": "A ranger helm from the order of the Void Knights", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "tradeable": "false", + "weight": "3.6" + }, + { + "id": "11676", + "name": "Void melee helm", + "examine": "A melee helm from the order of the Void Knights.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "tradeable": "false", + "weight": "1" + }, + { + "id": "11677", + "name": "Explorer's notes", + "examine": "\"Beyond Trollheim\" by Nestor Peregrine.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can find another book in the Keldagrim library.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11678", + "name": "Black knight helm", + "examine": "A black helm, too small for your head", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You'll need to visit the Sinclair Mansion to get another one.", + "durability": null, + "tradeable": "false", + "weight": "3" + }, + { + "id": "11679", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11680", + "name": "Address form", + "examine": "A change of address form.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11681", + "name": "Scrap paper", + "examine": "It has something written on it.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "11682", + "name": "Hair clip", + "examine": "I could use this to pick the lock.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11686", + "name": "Godsword shards", + "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11687", + "name": "Godsword shards", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11688", + "name": "Godsword shards", + "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11689", + "name": "Godsword shards", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11690", + "name": "Godsword blade", + "examine": "The blade for the ultimate weapon.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true", + "weight": "7.5" + }, + { + "id": "11691", + "name": "Godsword blade", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11692", + "name": "Godsword shards", + "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11693", + "name": "Godsword shards", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11694", + "name": "Armadyl godsword", + "examine": "A beautiful, heavy sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "3846,0,0,0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "124", + "requirements": "{0,75}", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7044", + "turn90cw_anim": "7043", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "10" + }, + { + "id": "11695", + "name": "Armadyl godsword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11696", + "name": "Bandos godsword", + "examine": "A brutally heavy sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "3846,0,0,0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "124", + "requirements": "{0,75}", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7044", + "turn90cw_anim": "7043", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "10" + }, + { + "id": "11697", + "name": "Bandos godsword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11698", + "name": "Saradomin godsword", + "examine": "A gracious, heavy sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "3846,0,0,0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "124", + "requirements": "{0,75}", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7044", + "turn90cw_anim": "7043", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "10" + }, + { + "id": "11699", + "name": "Saradomin godsword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11700", + "name": "Zamorak godsword", + "examine": "A terrifying, heavy sword.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "3846,0,0,0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "render_anim": "124", + "requirements": "{0,75}", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7044", + "turn90cw_anim": "7043", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "10" + }, + { + "id": "11701", + "name": "Zamorak godsword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11702", + "name": "Armadyl hilt", + "examine": "Brimming with potential.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2.5" + }, + { + "id": "11703", + "name": "Armadyl hilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11704", + "name": "Bandos hilt", + "examine": "Brimming with potential.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2.5" + }, + { + "id": "11705", + "name": "Bandos hilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11706", + "name": "Saradomin hilt", + "examine": "Brimming with potential.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2.5" + }, + { + "id": "11707", + "name": "Saradomin hilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11708", + "name": "Zamorak hilt", + "examine": "Brimming with potential.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2.5" + }, + { + "id": "11709", + "name": "Zamorak hilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11710", + "name": "Godsword shard 1", + "examine": "Part of the Godsword blade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11711", + "name": "Godsword shard 1", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11712", + "name": "Godsword shard 2", + "examine": "Part of the Godsword blade.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11713", + "name": "Godsword shard 2", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11714", + "name": "Godsword shard 3", + "examine": "Part of the Godsword blade.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "rare_item": "true", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11715", + "name": "Godsword shard 3", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11716", + "name": "Zamorakian spear", + "examine": "An evil spear.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "4", + "bonuses": "85,65,65,0,0,13,13,12,0,13,0,75,2,0,0", + "defence_anim": "2079", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,70}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "3" + }, + { + "id": "11717", + "name": "Zamorakian spear", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11718", + "name": "Armadyl helmet", + "examine": "A helmet of great craftmanship.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "ge_buy_limit": "1", + "lendable": "true", + "rare_item": "true", + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "11719", + "name": "Armadyl helmet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "11720", + "name": "Armadyl chestplate", + "examine": "A chestplate of great craftsmanship", + "absorb": "0,10,5", + "archery_ticket_price": "0", + "bonuses": "-7,-7,-7,-15,33,56,48,61,70,57,52,0,1,0,0", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "ge_buy_limit": "1", + "lendable": "true", + "rare_item": "true", + "remove_sleeves": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "4" + }, + { + "id": "11721", + "name": "Armadyl chestplate", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "11722", + "name": "Armadyl plateskirt", + "examine": "A plateskirt of great craftsmanship.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "-6,-6,-6,-10,20,32,26,34,40,33,25,0,1,0,0", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "ge_buy_limit": "2", + "lendable": "true", + "rare_item": "true", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "8" + }, + { + "id": "11723", + "name": "Armadyl plateskirt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11724", + "name": "Bandos chestplate", + "examine": "A sturdy chestplate.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-15,-10,98,93,105,-6,133,52,4,1,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "1", + "lendable": "true", + "rare_item": "true", + "remove_sleeves": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "12" + }, + { + "id": "11725", + "name": "Bandos chestplate", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "11726", + "name": "Bandos tassets", + "examine": "A sturdy pair of tassets.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-21,-7,71,63,66,-4,93,25,2,1,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "1", + "lendable": "true", + "rare_item": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "8" + }, + { + "id": "11727", + "name": "Bandos tassets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "11728", + "name": "Bandos boots", + "examine": "Some sturdy boots", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,-3,17,18,19,0,0,15,0,1,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "1", + "lendable": "true", + "rare_item": "true", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "6" + }, + { + "id": "11729", + "name": "Bandos boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1", + "tradeable": "true" + }, + { + "id": "11730", + "name": "Saradomin sword", + "examine": "The incredible blade of an Icyene.", + "archery_ticket_price": "0", + "attack_anims": "7041,7041,7048,7049", + "attack_audios": "3846,0,0,0", + "attack_speed": "4", + "bonuses": "0,82,60,0,0,0,0,0,0,0,0,82,2,0,0", + "defence_anim": "7050", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "124", + "requirements": "{0,70}", + "run_anim": "7039", + "stand_anim": "7047", + "stand_turn_anim": "7040", + "tradeable": "true", + "turn180_anim": "7045", + "turn90ccw_anim": "7044", + "turn90cw_anim": "7043", + "two_handed": "true", + "walk_anim": "7046", + "weapon_interface": "7", + "weight": "3" + }, + { + "id": "11731", + "name": "Saradomin sword", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11732", + "name": "Dragon boots", + "examine": "These will protect my feet.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "10", + "lendable": "true", + "rare_item": "true", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "1" + }, + { + "id": "11733", + "name": "Dragon boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11734", + "name": "Knight's notes", + "examine": "A scroll for Sir Tiffy. It is sealed with a wax insignia.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11735", + "name": "Knight's notes", + "examine": "A scroll for Sir Tiffy. The wax seal is broken.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11736", + "name": "Steam battlestaff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2230", + "equipment_slot": "3", + "ge_buy_limit": "10", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,30}-{6,30}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "11737", + "name": "Steam battlestaff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11738", + "name": "Mystic steam staff", + "examine": "It's a slightly magical stick.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "defence_anim": "420", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "28", + "requirements": "{0,40}-{6,40}", + "run_anim": "1210", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2" + }, + { + "id": "11739", + "name": "Mystic steam staff", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11741", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11743", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11745", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11747", + "name": "A key to a chest", + "examine": "This probably opens a chest in Golrie's caves. (Path of Glophrie)", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "There may be another in the chest where you found this.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11748", + "name": "Strongroom key", + "examine": "This opens the door into Golrie's strongroom. (Path of Glophrie)", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "There may be another in the chest where you found this.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11749", + "name": "Crystal chime", + "examine": "It makes a sound.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Maybe Brimstail will have another crystal seed you could grow into a chime.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false", + "weight": "1" + }, + { + "id": "11750", + "name": "Yewnock's notes", + "examine": "Notes written by Yewnock while copying Oaknock's machine.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "There may be another in the chest where you found this.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11753", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11754", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11755", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11756", + "name": "Varrock armour 1", + "examine": "Varrock Smithing armour.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,15,14,9,-6,14,5,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to get a new set of armour from Rat Burgiss if you destroy this one.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "1" + }, + { + "id": "11757", + "name": "Varrock armour 2", + "examine": "Varrock smithing armour.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,21,20,12,-6,20,5,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to get a new set of armour from Reldo if you destroy this one.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "1" + }, + { + "id": "11758", + "name": "Varrock armour 3", + "examine": "Varrock smithing armour.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to get a new set of armour from Vannaka if you destroy this one.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false", + "weight": "1" + }, + { + "id": "11760", + "name": "Logs", + "examine": "A number of wooden logs.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "4", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11761", "name": "Locked diary", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11761" - }, - { - "destroy_message": "You can get the diary again from Sandy's desk.", "examine": "A locked/unlocked diary.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get the diary again from Sandy's desk.", "durability": null, + "tradeable": "false" + }, + { + "id": "11762", "name": "Unlocked diary", - "tradeable": "false", - "destroy": "true", + "examine": "A locked/unlocked diary.", "archery_ticket_price": "0", - "id": "11762" + "destroy": "true", + "destroy_message": "You can get the diary again from Sandy's desk.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get the foot again from the creatures in the Jade Vine.", - "examine": "A wizard's severed foot. You can tell by the robes.", - "durability": null, + "id": "11764", "name": "Foot", - "tradeable": "false", - "destroy": "true", + "examine": "A wizard's severed foot. You can tell by the robes.", "archery_ticket_price": "0", - "id": "11764" + "destroy": "true", + "destroy_message": "You can get the foot again from the creatures in the Jade Vine.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get the arm again from the creatures in the Jade Vine.", - "examine": "\"A wizard's severed arm. You can tell by the robes.", - "durability": null, + "id": "11766", "name": "Left arm", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "\"A wizard's severed arm. You can tell by the robes.", "archery_ticket_price": "0", - "id": "11766" - }, - { + "destroy": "true", "destroy_message": "You can get the arm again from the creatures in the Jade Vine.", - "examine": "A wizard's severed arm. You can tell by the robes.", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11767", "name": "Right arm", - "tradeable": "false", - "destroy": "true", + "examine": "A wizard's severed arm. You can tell by the robes.", "archery_ticket_price": "0", - "id": "11767" + "destroy": "true", + "destroy_message": "You can get the arm again from the creatures in the Jade Vine.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get the leg again from the creatures in the Jade Vine.", - "examine": "A wizard's severed leg. You can tell by the robes.", - "durability": null, + "id": "11768", "name": "Left leg", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11768" - }, - { - "destroy_message": "You can get the leg again from the creatures in the Jade Vine.", "examine": "A wizard's severed leg. You can tell by the robes.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get the leg again from the creatures in the Jade Vine.", "durability": null, + "tradeable": "false" + }, + { + "id": "11769", "name": "Right leg", - "tradeable": "false", - "destroy": "true", + "examine": "A wizard's severed leg. You can tell by the robes.", "archery_ticket_price": "0", - "id": "11769" + "destroy": "true", + "destroy_message": "You can get the leg again from the creatures in the Jade Vine.", + "durability": null, + "tradeable": "false" }, { - "examine": "A root cutting.", - "durability": null, + "id": "11770", "name": "Root cutting", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11770" - }, - { "examine": "A root cutting.", - "durability": null, - "name": "Root cutting", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "11771" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { + "id": "11771", + "name": "Root cutting", "examine": "A root cutting.", - "durability": null, - "name": "Root cutting", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "11772" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { + "id": "11772", + "name": "Root cutting", "examine": "A root cutting.", - "durability": null, - "name": "Root cutting", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "11773" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { + "id": "11773", + "name": "Root cutting", "examine": "A root cutting.", - "durability": null, - "name": "Root cutting", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "11774" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "A floppy root cutting. Quite dead.", + "id": "11774", + "name": "Root cutting", + "examine": "A root cutting.", + "archery_ticket_price": "0", + "destroy": "true", "durability": null, + "tradeable": "false" + }, + { + "id": "11775", "name": "Wilted cutting", + "examine": "A floppy root cutting. Quite dead.", "archery_ticket_price": "0", - "id": "11775" + "durability": null }, { - "examine": "A potted root.", - "durability": null, + "id": "11776", "name": "Potted root", - "tradeable": "false", - "destroy": "true", + "examine": "A potted root.", "archery_ticket_price": "0", - "id": "11776" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get the sealed pot back by visiting Garth, the farmer on Karamja.", - "examine": "This sealed pot contains your vine cutting - hopefully still alive.", - "durability": null, + "id": "11777", "name": "Sealed pot", - "tradeable": "false", - "destroy": "true", - "weight": "2.2", + "examine": "This sealed pot contains your vine cutting - hopefully still alive.", "archery_ticket_price": "0", - "id": "11777" + "destroy": "true", + "destroy_message": "You can get the sealed pot back by visiting Garth, the farmer on Karamja.", + "durability": null, + "tradeable": "false", + "weight": "2.2" }, { - "examine": "A large seed.", - "durability": null, + "id": "11778", "name": "Jade vine seed", + "examine": "A large seed.", "archery_ticket_price": "0", - "id": "11778" + "durability": null }, { - "destroy_message": "You'll have to find another from the Grim Reaper's house.", - "examine": "Surely this holds many a dark tale...", - "durability": null, + "id": "11780", "name": "The grim reaper's diary", - "tradeable": "false", - "destroy": "true", + "examine": "Surely this holds many a dark tale...", "archery_ticket_price": "0", - "id": "11780" + "destroy": "true", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "durability": null, + "tradeable": "false" }, { - "bankable": "false", - "destroy_message": "Another can be found in the Grim Reaper's house.", - "examine": "Some of the Grim Reaper's garb.", - "durability": null, + "id": "11781", "name": "Grim's robe", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "Some of the Grim Reaper's garb.", "archery_ticket_price": "0", - "id": "11781" - }, - { "bankable": "false", - "destroy_message": "You'll have to find another from the Grim Reaper's house.", - "examine": "Someone's Last Will and Testament.", - "durability": null, - "name": "Last will and testament", - "tradeable": "false", "destroy": "true", - "archery_ticket_price": "0", - "id": "11782" - }, - { - "bankable": "false", - "destroy_message": "You'll have to find another from the Grim Reaper's house.", - "examine": "A tasty treat for Muncher.", - "durability": null, - "name": "Human bones", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11783" - }, - { - "bankable": "false", - "destroy_message": "You'll have to find another from the Grim Reaper's house.", - "examine": "Ooooh spooky!", - "durability": null, - "name": "Servant's skull", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "11784" - }, - { - "bankable": "false", - "destroy_message": "You can get a replacement from Diango in Draynor Village.", - "examine": "There's not much sand left in the top half...", - "durability": null, - "name": "Hourglass", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11785" - }, - { - "bankable": "false", "destroy_message": "Another can be found in the Grim Reaper's house.", - "examine": "Used to sharpen the blade of a scythe.", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11782", + "name": "Last will and testament", + "examine": "Someone's Last Will and Testament.", + "archery_ticket_price": "0", + "bankable": "false", + "destroy": "true", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11783", + "name": "Human bones", + "examine": "A tasty treat for Muncher.", + "archery_ticket_price": "0", + "bankable": "false", + "destroy": "true", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11784", + "name": "Servant's skull", + "examine": "Ooooh spooky!", + "archery_ticket_price": "0", + "bankable": "false", + "destroy": "true", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "11785", + "name": "Hourglass", + "examine": "There's not much sand left in the top half...", + "archery_ticket_price": "0", + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get a replacement from Diango in Draynor Village.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11786", "name": "Scythe sharpener", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "Used to sharpen the blade of a scythe.", "archery_ticket_price": "0", - "id": "11786" + "attack_audios": "2524,2524,2522,2524", + "bankable": "false", + "destroy": "true", + "destroy_message": "Another can be found in the Grim Reaper's house.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "bankable": "false", - "destroy_message": "You'll have to find another from the Grim Reaper's house.", - "examine": "That's gross. Why am I carrying it around?", - "durability": null, + "id": "11787", "name": "Human eye", - "tradeable": "false", - "destroy": "true", + "examine": "That's gross. Why am I carrying it around?", "archery_ticket_price": "0", - "id": "11787" - }, - { "bankable": "false", + "destroy": "true", "destroy_message": "You'll have to find another from the Grim Reaper's house.", - "examine": "A 'Voice of Doom' potion, used to deepen your voice.", "durability": null, + "tradeable": "false" + }, + { + "id": "11788", "name": "'voice of doom' potion", - "tradeable": "false", - "destroy": "true", + "examine": "A 'Voice of Doom' potion, used to deepen your voice.", "archery_ticket_price": "0", - "id": "11788" + "bankable": "false", + "destroy": "true", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "durability": null, + "tradeable": "false" }, { - "remove_head": "true", - "destroy_message": "You should be able to get another from Diango in Draynor Village.", - "examine": "Allows me to imitate the harbinger of doom, the stealer of souls, the eternal end...", - "durability": null, - "name": "Grim reaper hood", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "11789", - "remove_beard": "true", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "destroy_message": "You should be able to get another from Diango in Draynor Village.", - "examine": "Allows me to imitate the harbinger of doom, the stealer of souls, the eternal end...", - "durability": null, "name": "Grim reaper hood", - "tradeable": "false", - "destroy": "true", + "examine": "Allows me to imitate the harbinger of doom, the stealer of souls, the eternal end...", "archery_ticket_price": "0", - "id": "11790", + "destroy": "true", + "destroy_message": "You should be able to get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "0", "remove_beard": "true", - "equipment_slot": "0" + "remove_head": "true", + "tradeable": "false" }, { - "examine": "Armour designed to fit goblins.", - "durability": null, - "name": "White goblin mail", - "weight": "3", + "id": "11790", + "name": "Grim reaper hood", + "examine": "Allows me to imitate the harbinger of doom, the stealer of souls, the eternal end...", "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You should be able to get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "tradeable": "false" + }, + { "id": "11791", - "equipment_slot": "4" + "name": "White goblin mail", + "examine": "Armour designed to fit goblins.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "weight": "3" }, { - "examine": "Smaller than the average goblin. After The Chosen Commander: Oldak's new assistant.", - "durability": null, + "id": "11792", "name": "Grubfoot", + "examine": "Smaller than the average goblin. After The Chosen Commander: Oldak's new assistant.", "archery_ticket_price": "0", - "id": "11792" + "durability": null }, { - "examine": "See article", - "durability": null, + "id": "11793", "name": "Zanik", + "examine": "See article", "archery_ticket_price": "0", - "id": "11793" + "durability": null }, { - "shop_price": "32", - "examine": "Oldak's Marvellous Moving-Over-Distance Sphere", - "durability": null, + "id": "11794", "name": "Plain of mud sphere", + "examine": "Oldak's Marvellous Moving-Over-Distance Sphere", "archery_ticket_price": "0", - "id": "11794" + "durability": null, + "shop_price": "32" }, { - "destroy_message": "The Ekeleshuun priest probably has a spare.", - "examine": "The key you stole from the Ekeleshuun priest.", - "durability": null, + "id": "11795", "name": "Ekeleshuun key", - "tradeable": "false", - "destroy": "true", + "examine": "The key you stole from the Ekeleshuun priest.", "archery_ticket_price": "0", - "id": "11795" + "destroy": "true", + "destroy_message": "The Ekeleshuun priest probably has a spare.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "The Narogoshuun priest probably has a spare.", - "examine": "The key you stole from the Narogoshuun priest.", - "durability": null, + "id": "11796", "name": "Narogoshuun key", - "tradeable": "false", - "destroy": "true", + "examine": "The key you stole from the Narogoshuun priest.", "archery_ticket_price": "0", - "id": "11796" + "destroy": "true", + "destroy_message": "The Narogoshuun priest probably has a spare.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "The Huzamogaarb priest probably has a spare.", - "examine": "The key you stole from the Huzamogaarb priest.", - "durability": null, + "id": "11797", "name": "Huzamogaarb key", - "tradeable": "false", - "destroy": "true", + "examine": "The key you stole from the Huzamogaarb priest.", "archery_ticket_price": "0", - "id": "11797" + "destroy": "true", + "destroy_message": "The Huzamogaarb priest probably has a spare.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "The Saragorgak priest probably has a spare.", - "examine": "The key you stole from the Saragorgak priest.", - "durability": null, + "id": "11798", "name": "Saragorgak key", - "tradeable": "false", - "destroy": "true", + "examine": "The key you stole from the Saragorgak priest.", "archery_ticket_price": "0", - "id": "11798" + "destroy": "true", + "destroy_message": "The Saragorgak priest probably has a spare.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "The Horogothgar priest probably has a spare.", - "examine": "The key you stole from the Horogothgar priest.", - "durability": null, + "id": "11799", "name": "Horogothgar key", - "tradeable": "false", - "destroy": "true", + "examine": "The key you stole from the Horogothgar priest.", "archery_ticket_price": "0", - "id": "11799" + "destroy": "true", + "destroy_message": "The Horogothgar priest probably has a spare.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "The Yurkolgokh priest probably has a spare.", - "examine": "The key you stole from the Yurkolgokh priest.", - "durability": null, + "id": "11800", "name": "Yurkolgokh key", - "tradeable": "false", - "destroy": "true", + "examine": "The key you stole from the Yurkolgokh priest.", "archery_ticket_price": "0", - "id": "11800" + "destroy": "true", + "destroy_message": "The Yurkolgokh priest probably has a spare.", + "durability": null, + "tradeable": "false" }, { - "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", - "durability": null, + "id": "11802", "name": "Snothead's bone", - "tradeable": "false", - "destroy": "true", + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", "archery_ticket_price": "0", - "id": "11802" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", - "durability": null, + "id": "11803", "name": "Snailfeet's bone", - "tradeable": "false", - "destroy": "true", + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", "archery_ticket_price": "0", - "id": "11803" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", - "durability": null, + "id": "11804", "name": "Mosschin's bone", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11804" - }, - { "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", - "durability": null, - "name": "Redeyes's bone", "archery_ticket_price": "0", - "id": "11805" - }, - { - "examine": "An ancient goblin bone wrapped in fragments of priestly robes.", - "durability": null, - "name": "Strongbones's bone", - "tradeable": "false", "destroy": "true", - "archery_ticket_price": "0", - "id": "11806" + "durability": null, + "tradeable": "false" }, { - "examine": "You can combine these with a toadflax to make a goblin transformation potion.", + "id": "11805", + "name": "Redeyes's bone", + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11806", + "name": "Strongbones's bone", + "examine": "An ancient goblin bone wrapped in fragments of priestly robes.", + "archery_ticket_price": "0", + "destroy": "true", "durability": null, + "tradeable": "false" + }, + { + "id": "11807", "name": "Pharmakos berries", + "examine": "You can combine these with a toadflax to make a goblin transformation potion.", "archery_ticket_price": "0", - "id": "11807" + "durability": null }, { - "examine": "An ugly albino fish.", - "durability": null, + "id": "11808", "name": "Whitefish", - "weight": "0.25", + "examine": "An ugly albino fish.", "archery_ticket_price": "0", - "id": "11808" + "durability": null, + "weight": "0.25" }, { - "examine": "4 doses of goblin transmogrification potion.", - "durability": null, - "name": "Goblin potion (4)", - "archery_ticket_price": "0", "id": "11809", + "name": "Goblin potion (4)", + "examine": "4 doses of goblin transmogrification potion.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "5" }, { - "examine": "3 doses of goblin transmogrification potion.", - "durability": null, + "id": "11810", "name": "Goblin potion (3)", + "examine": "3 doses of goblin transmogrification potion.", "archery_ticket_price": "0", - "id": "11810" + "durability": null }, { - "examine": "2 doses of goblin transmogrification potion.", - "durability": null, + "id": "11811", "name": "Goblin potion (2)", + "examine": "2 doses of goblin transmogrification potion.", "archery_ticket_price": "0", - "id": "11811" + "durability": null }, { - "examine": "1 dose of goblin transmogrification potion.", - "durability": null, + "id": "11812", "name": "Goblin potion (1)", + "examine": "1 dose of goblin transmogrification potion.", "archery_ticket_price": "0", - "id": "11812" + "durability": null }, { - "shop_price": "177", - "ge_buy_limit": "100", + "id": "11814", + "name": "Bronze armour set (l)", "examine": "Grand Exchange set containing bronze full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "614", - "durability": null, - "name": "Bronze armour set (l)", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11814" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "614", - "durability": null, - "name": "Bronze armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11815" - }, - { "shop_price": "177", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing bronze full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "938", - "durability": null, - "name": "Bronze armour set (sk)", "tradeable": "true", - "weight": "2.2", + "weight": "2.2" + }, + { + "id": "11815", + "name": "Bronze armour set (l)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11816", - "bonuses": "0,0,0,-59,-19,27,26,18,-11,25,5,0,0,1,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "938", - "durability": null, "name": "Bronze armour set (sk)", - "tradeable": "true", + "examine": "Grand Exchange set containing bronze full helm, platebody, skirt and kiteshield.", "archery_ticket_price": "0", - "id": "11817" + "bonuses": "0,0,0,-59,-19,27,26,18,-11,25,5,0,0,1,0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "177", + "tradeable": "true", + "weight": "2.2" }, { - "shop_price": "1022", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing iron full helm, platebody, legs, and kiteshield.", - "grand_exchange_price": "1830", - "durability": null, - "name": "Iron armour set (l)", - "tradeable": "true", - "weight": "2.2", + "id": "11817", + "name": "Bronze armour set (sk)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11818", - "bonuses": "0,0,0,-65,-21,46,44,33,-12,45,7,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1830", - "durability": null, "name": "Iron armour set (l)", - "tradeable": "true", + "examine": "Grand Exchange set containing iron full helm, platebody, legs, and kiteshield.", "archery_ticket_price": "0", - "id": "11819" - }, - { + "bonuses": "0,0,0,-65,-21,46,44,33,-12,45,7,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", "shop_price": "1022", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing iron full helm, platebody, skirt, and kiteshield.", - "grand_exchange_price": "1711", - "durability": null, - "name": "Iron armour set (sk)", "tradeable": "true", - "weight": "2.2", + "weight": "2.2" + }, + { + "id": "11819", + "name": "Iron armour set (l)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11820", - "bonuses": "0,0,0,-65,-21,46,44,33,-12,45,7,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1711", - "durability": null, "name": "Iron armour set (sk)", - "tradeable": "true", + "examine": "Grand Exchange set containing iron full helm, platebody, skirt, and kiteshield.", "archery_ticket_price": "0", - "id": "11821" + "bonuses": "0,0,0,-65,-21,46,44,33,-12,45,7,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "1022", + "tradeable": "true", + "weight": "2.2" }, { - "requirements": "{5,1}", - "shop_price": "2365", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing steel full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "3646", - "durability": null, - "name": "Steel armour set (l)", - "tradeable": "true", - "weight": "2.2", + "id": "11821", + "name": "Iron armour set (sk)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11822", - "bonuses": "0,0,0,-65,-21,71,72,60,-12,70,15,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3646", - "durability": null, "name": "Steel armour set (l)", - "tradeable": "true", + "examine": "Grand Exchange set containing steel full helm, platebody, legs and kiteshield.", "archery_ticket_price": "0", - "id": "11823" - }, - { + "bonuses": "0,0,0,-65,-21,71,72,60,-12,70,15,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{5,1}", "shop_price": "2365", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing steel full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "3796", - "durability": null, - "name": "Steel armour set (sk)", "tradeable": "true", - "weight": "2.2", + "weight": "2.2" + }, + { + "id": "11823", + "name": "Steel armour set (l)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11824", - "bonuses": "0,0,0,-65,-21,71,72,60,-12,70,15,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3796", - "durability": null, "name": "Steel armour set (sk)", - "tradeable": "true", + "examine": "Grand Exchange set containing steel full helm, platebody, skirt and kiteshield.", "archery_ticket_price": "0", - "id": "11825" + "bonuses": "0,0,0,-65,-21,71,72,60,-12,70,15,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{5,1}", + "shop_price": "2365", + "tradeable": "true", + "weight": "2.2" }, { - "requirements": "{10,1}", - "shop_price": "11286", + "id": "11825", + "name": "Steel armour set (sk)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11826", + "name": "Black armour set (l)", "examine": "Grand Exchange set containing Black full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "18900", - "durability": null, - "name": "Black armour set (l)", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11826" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "18900", - "durability": null, - "name": "Black armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11827" - }, - { "requirements": "{10,1}", "shop_price": "11286", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing a black full helm, platebody, skirt and kiteshield.", - "durability": null, - "weight": "2.2", - "absorb": "2,0,4", - "grand_exchange_price": "14600", - "name": "Black armour set (sk)", "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11827", + "name": "Black armour set (l)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11828", - "bonuses": "0,0,0,-65,-21,91,92,78,-12,90,27,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "14600", - "durability": null, "name": "Black armour set (sk)", - "tradeable": "true", + "examine": "Grand Exchange set containing a black full helm, platebody, skirt and kiteshield.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "11829" + "bonuses": "0,0,0,-65,-21,91,92,78,-12,90,27,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{10,1}", + "shop_price": "11286", + "tradeable": "true", + "weight": "2.2" }, { - "requirements": "{20,1}", - "shop_price": "15232", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing a mithril full helm, platebody, legs and kiteshield.", - "durability": null, - "weight": "2.2", - "absorb": "2,0,6", - "grand_exchange_price": "8764", - "name": "Mithril armour set (l)", - "tradeable": "true", + "id": "11829", + "name": "Black armour set (sk)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11830", - "bonuses": "0,0,0,-65,-21,101,102,89,-12,97,52,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "8764", - "durability": null, "name": "Mithril armour set (l)", - "tradeable": "true", + "examine": "Grand Exchange set containing a mithril full helm, platebody, legs and kiteshield.", + "absorb": "2,0,6", "archery_ticket_price": "0", - "id": "11831" - }, - { + "bonuses": "0,0,0,-65,-21,101,102,89,-12,97,52,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{20,1}", "shop_price": "15232", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing a mithril full helm, platebody, skirt and kiteshield.", - "durability": null, - "weight": "2.2", - "absorb": "2,0,5", - "grand_exchange_price": "7829", - "name": "Mithril armour set (sk)", "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11831", + "name": "Mithril armour set (l)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11832", - "bonuses": "0,0,0,-65,-21,101,102,89,-12,99,50,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "7829", - "durability": null, "name": "Mithril armour set (sk)", - "tradeable": "true", + "examine": "Grand Exchange set containing a mithril full helm, platebody, skirt and kiteshield.", + "absorb": "2,0,5", "archery_ticket_price": "0", - "id": "11833" + "bonuses": "0,0,0,-65,-21,101,102,89,-12,99,50,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{20,1}", + "shop_price": "15232", + "tradeable": "true", + "weight": "2.2" }, { - "requirements": "{1,30}", - "shop_price": "28276", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing an adamant full helm, platebody, legs and kiteshield.", - "durability": null, - "weight": "2.2", - "absorb": "7,0,15", - "grand_exchange_price": "20600", - "name": "Adamant armour set (l)", - "tradeable": "true", + "id": "11833", + "name": "Mithril armour set (sk)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11834", - "bonuses": "0,0,0,-65,-21,144,146,129,-12,142,76,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "20600", - "durability": null, "name": "Adamant armour set (l)", - "tradeable": "true", + "examine": "Grand Exchange set containing an adamant full helm, platebody, legs and kiteshield.", + "absorb": "7,0,15", "archery_ticket_price": "0", - "id": "11835" - }, - { + "bonuses": "0,0,0,-65,-21,144,146,129,-12,142,76,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{1,30}", "shop_price": "28276", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing an adamant full helm, platebody, skirt and kiteshield.", - "durability": null, - "weight": "2.2", - "absorb": "7,0,15", - "grand_exchange_price": "21500", - "name": "Adamant armour set (sk)", "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11835", + "name": "Adamant armour set (l)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11836", - "bonuses": "0,0,0,-65,-21,144,146,129,-12,142,76,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "21500", - "durability": null, "name": "Adamant armour set (sk)", - "tradeable": "true", + "examine": "Grand Exchange set containing an adamant full helm, platebody, skirt and kiteshield.", + "absorb": "7,0,15", "archery_ticket_price": "0", - "id": "11837" + "bonuses": "0,0,0,-65,-21,144,146,129,-12,142,76,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{1,30}", + "shop_price": "28276", + "tradeable": "true", + "weight": "2.2" }, { - "requirements": "{1,40}", - "shop_price": "136112", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing a rune full helm, platebody, legs and kiteshield.", - "durability": null, - "weight": "2.2", - "absorb": "9,0,20", - "grand_exchange_price": "136300", - "name": "Rune armour set (l)", - "tradeable": "true", + "id": "11837", + "name": "Adamant armour set (sk)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11838", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "136300", - "durability": null, "name": "Rune armour set (l)", - "tradeable": "true", + "examine": "Grand Exchange set containing a rune full helm, platebody, legs and kiteshield.", + "absorb": "9,0,20", "archery_ticket_price": "0", - "id": "11839" - }, - { + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{1,40}", "shop_price": "136112", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11839", + "name": "Rune armour set (l)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11840", + "name": "Rune armour set (sk)", "examine": "Grand Exchange set containing a rune full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "140300", - "durability": null, - "name": "Rune armour set (sk)", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11840" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "140300", - "durability": null, + "requirements": "{1,40}", + "shop_price": "136112", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11841", "name": "Rune armour set (sk)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11841" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,60}", - "ge_buy_limit": "10", - "grand_exchange_price": "4800000", + "id": "11842", + "name": "Dragon chain armour set (l)", "examine": "Grand Exchange set containing a dragon helm, chainbody, legs.", - "durability": null, - "name": "Dragon chain armour set (l)", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "2.2", - "id": "11842" - }, - { + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "4800000", - "durability": null, - "name": "Dragon chain armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11843" - }, - { "requirements": "{1,60}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11843", + "name": "Dragon chain armour set (l)", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "4600000", + "tradeable": "true" + }, + { + "id": "11844", + "name": "Dragon chain armour set (sk)", "examine": "Grand Exchange set containing a dragon helm, chainbody, skirt.", - "durability": null, - "name": "Dragon chain armour set (sk)", - "tradeable": "true", "archery_ticket_price": "0", - "weight": "2.2", - "id": "11844" + "durability": null, + "ge_buy_limit": "10", + "requirements": "{1,60}", + "tradeable": "true", + "weight": "2.2" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "4600000", - "durability": null, + "id": "11845", "name": "Dragon chain armour set (sk)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11845" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "requirements": "{0,70}-{1,70}-{6,70}", - "ge_buy_limit": "10", + "id": "11846", + "name": "Barrows - ahrim's set", "examine": "Grand Exchange set containing Ahrim's robetop, robeskirt, hood, and staff.", - "grand_exchange_price": "3100000", - "durability": null, - "name": "Barrows - ahrim's set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11846" + "durability": null, + "ge_buy_limit": "10", + "requirements": "{0,70}-{1,70}-{6,70}", + "tradeable": "true", + "weight": "2.2" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "3100000", - "durability": null, + "id": "11847", "name": "Barrows - ahrim's set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11847" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "requirements": "{0,70}-{1,70}-{2,70}", - "ge_buy_limit": "10", + "id": "11848", + "name": "Barrows - dharok's set", "examine": "Grand Exchange set containing Dharok's helm, body, legs and greataxe.", - "grand_exchange_price": "3100000", - "durability": null, - "name": "Barrows - dharok's set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11848" - }, - { + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "3100000", - "durability": null, - "name": "Barrows - dharok's set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11849" - }, - { - "requirements": "{0,70}-{1,70}", - "ge_buy_limit": "10", - "examine": "Grand Exchange set containing Guthan's helm, platebody, chainskirt and warspear.", - "grand_exchange_price": "1600000", - "durability": null, - "name": "Barrows - guthan's set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11850" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "1600000", - "durability": null, - "name": "Barrows - guthan's set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11851" - }, - { - "requirements": "{1,70}-{4,70}", - "ge_buy_limit": "10", - "examine": "A Grand Exchange set containing Karil's coif, crossbow, leather body, and leather skirt.", - "grand_exchange_price": "2200000", - "durability": null, - "name": "Barrows - karil's set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11852" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "2200000", - "durability": null, - "name": "Barrows - karil's set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11853" - }, - { "requirements": "{0,70}-{1,70}-{2,70}", - "ge_buy_limit": "10", - "examine": "Grand Exchange set containing Torag's helm, body, legs and hammers.", - "grand_exchange_price": "1100000", - "durability": null, - "name": "Barrows - torag's set", "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11854" + "weight": "2.2" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "1100000", - "durability": null, - "name": "Barrows - torag's set", - "tradeable": "true", + "id": "11849", + "name": "Barrows - dharok's set", "archery_ticket_price": "0", - "id": "11855" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { + "id": "11850", + "name": "Barrows - guthan's set", + "examine": "Grand Exchange set containing Guthan's helm, platebody, chainskirt and warspear.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", "requirements": "{0,70}-{1,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11851", + "name": "Barrows - guthan's set", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11852", + "name": "Barrows - karil's set", + "examine": "A Grand Exchange set containing Karil's coif, crossbow, leather body, and leather skirt.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "requirements": "{1,70}-{4,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11853", + "name": "Barrows - karil's set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11854", + "name": "Barrows - torag's set", + "examine": "Grand Exchange set containing Torag's helm, body, legs and hammers.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "requirements": "{0,70}-{1,70}-{2,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11855", + "name": "Barrows - torag's set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "11856", + "name": "Barrows - verac's set", "examine": "Grand Exchange set containing Verac's helm, brassard, plateskirt and flail.", - "grand_exchange_price": "1500000", - "durability": null, - "name": "Barrows - verac's set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11856" - }, - { + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "1500000", - "durability": null, + "requirements": "{0,70}-{1,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11857", "name": "Barrows - verac's set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11857" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "requirements": "{1,65}", - "ge_buy_limit": "2", + "id": "11858", + "name": "Third age melee set", "examine": "Grand Exchange set containing a helm, body, legs and shield", - "grand_exchange_price": "388700000", - "durability": null, - "name": "Third age melee set", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "11858" + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,65}", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "388700000", - "durability": null, + "id": "11859", "name": "Third age melee set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11859" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,45}-{4,65}", - "ge_buy_limit": "2", + "id": "11860", + "name": "Third age ranger set", "examine": "Grand Exchange set containing coif, body, chaps and vambraces.", - "grand_exchange_price": "87500000", - "durability": null, - "name": "Third age ranger set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11860" + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,45}-{4,65}", + "tradeable": "true", + "weight": "2.2" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "87500000", - "durability": null, + "id": "11861", "name": "Third age ranger set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11861" + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" }, { - "requirements": "{1,30}-{6,65}", - "ge_buy_limit": "2", + "id": "11862", + "name": "Third age mage set", "examine": "Grand Exchange set containing a body, legs, amulet and hat", - "grand_exchange_price": "163100000", - "durability": null, - "name": "Third age mage set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11862" - }, - { + "durability": null, "ge_buy_limit": "2", - "grand_exchange_price": "163100000", - "durability": null, - "name": "Third age mage set", + "requirements": "{1,30}-{6,65}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "11863" + "weight": "2.2" }, { + "id": "11863", + "name": "Third age mage set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11864", + "name": "Green dragonhide set", + "examine": "Grand Exchange set containing body, chaps and vambraces.", + "absorb": "0,10,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{1,40}-{4,40}", "shop_price": "9000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11865", + "name": "Green dragonhide set", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11866", + "name": "Blue dragonhide set", "examine": "Grand Exchange set containing body, chaps and vambraces.", - "durability": null, - "weight": "2.2", - "absorb": "0,10,5", - "grand_exchange_price": "8932", - "name": "Green dragonhide set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11864", - "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "8932", - "durability": null, - "name": "Green dragonhide set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11865" - }, - { "requirements": "{1,40}-{4,50}", "shop_price": "12000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11867", + "name": "Blue dragonhide set", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11868", + "name": "Red dragonhide set", "examine": "Grand Exchange set containing body, chaps and vambraces.", - "grand_exchange_price": "9062", - "durability": null, - "name": "Blue dragonhide set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11866" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "9062", - "durability": null, - "name": "Blue dragonhide set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11867" - }, - { "requirements": "{1,40}-{4,60}", "shop_price": "15000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11869", + "name": "Red dragonhide set", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11870", + "name": "Black dragonhide set", "examine": "Grand Exchange set containing body, chaps and vambraces.", - "grand_exchange_price": "12800", - "durability": null, - "name": "Red dragonhide set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11868" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "12800", - "durability": null, - "name": "Red dragonhide set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11869" - }, - { "requirements": "{1,40}-{4,70}", "shop_price": "40000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11871", + "name": "Black dragonhide set", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "11872", + "name": "Mystic robes set", + "examine": "Grand Exchange set containing mystic hat, top, bottoms, gloves, and boots.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", - "examine": "Grand Exchange set containing body, chaps and vambraces.", - "grand_exchange_price": "17600", - "durability": null, - "name": "Black dragonhide set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11870" - }, - { - "durability": null, - "name": "Black dragonhide set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11871" - }, - { "requirements": "{20,1}-{6,40}", "shop_price": "169143", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing mystic hat, top, bottoms, gloves, and boots.", - "grand_exchange_price": "163300", - "durability": null, - "name": "Mystic robes set", "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11872" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "163300", - "durability": null, + "id": "11873", "name": "Mystic robes set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11873" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "requirements": "{1,25}-{6,50}", - "ge_buy_limit": "10", + "id": "11874", + "name": "Infinity robes set", "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", - "grand_exchange_price": "11000000", - "durability": null, - "name": "Infinity robes set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11874" - }, - { + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "11000000", - "durability": null, + "requirements": "{1,25}-{6,50}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11875", "name": "Infinity robes set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11875" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "requirements": "{1,40}-{6,40}", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing a helm, body, boots, gauntlets and legs.", - "grand_exchange_price": "107400", - "durability": null, - "name": "Splitbark armour set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", "id": "11876", - "absorb": "13,6,0", - "bonuses": "0,0,0,24,-21,74,59,86,32,0,74,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "107400", - "durability": null, "name": "Splitbark armour set", - "tradeable": "true", + "examine": "Grand Exchange set containing a helm, body, boots, gauntlets and legs.", + "absorb": "13,6,0", "archery_ticket_price": "0", - "id": "11877" - }, - { - "requirements": "{10,1}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "341200", + "bonuses": "0,0,0,24,-21,74,59,86,32,0,74,0,0,0,0", "durability": null, - "name": "Black trimmed armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11878", - "absorb": "2,0,4", - "bonuses": "0,0,0,-65,-21,91,92,77,-12,90,23,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "341200", - "durability": null, - "name": "Black trimmed armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11879" - }, - { - "requirements": "{10,1}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "331600", - "durability": null, - "name": "Black trimmed armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11880", - "absorb": "2,0,4", - "bonuses": "0,0,0,-65,-21,91,92,77,-12,90,23,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "331600", - "durability": null, - "name": "Black trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11881" - }, - { - "requirements": "{10,1}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "1700000", - "durability": null, - "name": "Black gold-trimmed armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11882" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1700000", - "durability": null, - "name": "Black gold-trimmed armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11883" - }, - { - "requirements": "{10,1}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "1300000", - "durability": null, - "name": "Black gold-trimmed armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11884" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1300000", - "durability": null, - "name": "Black gold-trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11885" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "318100", - "durability": null, - "name": "Adamant trimmed armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11886" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "318100", - "durability": null, - "name": "Adamant trimmed armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11887" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "293700", - "durability": null, - "name": "Adamant trimmed armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11888" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "293700", - "durability": null, - "name": "Adamant trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11889" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "949400", - "durability": null, - "name": "Adamant gold-trimmed armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11890" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "949400", - "durability": null, - "name": "Adamant gold-trimmed armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11891" - }, - { - "requirements": "{1,30}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "880500", - "durability": null, - "name": "Adamant gold-trimmed armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11892" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "880500", - "durability": null, - "name": "Adamant gold-trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11893" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "702500", - "durability": null, - "name": "Rune trimmed armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11894", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "702500", - "durability": null, - "name": "Rune trimmed armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11895" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "675400", - "durability": null, - "name": "Rune trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11896", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "675400", - "durability": null, - "name": "Rune trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11897" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "1700000", - "durability": null, - "name": "Rune gold-trimmed armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11898", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1700000", - "durability": null, - "name": "Rune gold-trimmed armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11899" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "1400000", - "durability": null, - "name": "Rune gold-trimmed armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11900", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1400000", - "durability": null, - "name": "Rune gold-trimmed armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11901" - }, - { - "requirements": "{20,1}-{6,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing hat, robetops and bottoms", - "grand_exchange_price": "207200", - "durability": null, - "name": "Enchanted set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11902" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "207200", - "durability": null, - "name": "Enchanted set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11903" - }, - { - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing hat, robetops and bottoms", - "grand_exchange_price": "877900", - "durability": null, - "name": "Trimmed blue wizard set", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "11904" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "877900", - "durability": null, - "name": "Trimmed blue wizard set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11905" - }, - { - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing hat, robe top and bottom", - "grand_exchange_price": "3100000", - "durability": null, - "name": "Gold-trimmed blue wizard set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11906" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "3100000", - "durability": null, - "name": "Gold-trimmed blue wizard set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11907" - }, - { - "requirements": "{20,4}", - "ge_buy_limit": "10000", - "examine": "Grand Exchange set containing body and chaps", - "grand_exchange_price": "85100", - "durability": null, - "name": "Trimmed leather armour set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11908" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "85100", - "durability": null, - "name": "Trimmed leather armour set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11909" - }, - { - "requirements": "{20,4}", - "ge_buy_limit": "10000", - "examine": "Grand Exchange set containing body and chaps", - "grand_exchange_price": "217200", - "durability": null, - "name": "Gold-trimmed leather armour set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11910" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "217200", - "durability": null, - "name": "Gold-trimmed leather armour set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11911" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body and chaps", - "grand_exchange_price": "371600", - "durability": null, - "name": "Green d'hide trimmed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11912", - "absorb": "0,10,5", - "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "371600", - "durability": null, - "name": "Green d'hide trimmed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11913" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body and chaps", - "grand_exchange_price": "1600000", - "durability": null, - "name": "Green d'hide gold-trimmed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11914", - "absorb": "0,10,5", - "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1600000", - "durability": null, - "name": "Green d'hide gold-trimmed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11915" - }, - { - "requirements": "{1,40}-{4,50}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body and chaps", - "grand_exchange_price": "38300", - "durability": null, - "name": "Blue d'hide trimmed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11916" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "38300", - "durability": null, - "name": "Blue d'hide trimmed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11917" - }, - { - "requirements": "{1,40}-{4,50}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body and chaps.", - "grand_exchange_price": "50000", - "durability": null, - "name": "Blue d'hide gold-trimmed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11918" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "50000", - "durability": null, - "name": "Blue d'hide gold-trimmed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11919" - }, - { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body, chaps, bracers and coif.", - "grand_exchange_price": "179500", - "durability": null, - "name": "Green d'hide blessed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11920" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "179500", - "durability": null, - "name": "Green d'hide blessed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11921" - }, - { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body, chaps, bracers and coif.", - "grand_exchange_price": "477500", - "durability": null, - "name": "Blue d'hide blessed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11922" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "477500", - "durability": null, - "name": "Blue d'hide blessed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11923" - }, - { - "requirements": "{1,40}-{4,70}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing body, chaps, bracers and coif.", - "grand_exchange_price": "585300", - "durability": null, - "name": "Red d'hide blessed set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11924" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "585300", - "durability": null, - "name": "Red d'hide blessed set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11925" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, legs and shield.", - "grand_exchange_price": "1100000", - "durability": null, - "name": "Guthix armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11926", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1100000", - "durability": null, - "name": "Guthix armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11927" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield", - "grand_exchange_price": "4000000", - "durability": null, - "name": "Saradomin armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11928", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "4000000", - "durability": null, - "name": "Saradomin armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11929" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield", - "grand_exchange_price": "2300000", - "durability": null, - "name": "Zamorak armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11930", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2300000", - "durability": null, - "name": "Zamorak armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11931" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "1000000", - "durability": null, - "name": "Guthix armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11932", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1000000", - "durability": null, - "name": "Guthix armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11933" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield", - "grand_exchange_price": "3600000", - "durability": null, - "name": "Saradomin armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11934", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "3600000", - "durability": null, - "name": "Saradomin armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11935" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield", - "grand_exchange_price": "2000000", - "durability": null, - "name": "Zamorak armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11936", - "absorb": "9,0,20", - "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "2000000", - "durability": null, - "name": "Zamorak armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11937" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", - "grand_exchange_price": "5900000", - "durability": null, - "name": "Gilded armour set (l)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11938" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "5900000", - "durability": null, - "name": "Gilded armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11939" - }, - { - "requirements": "{1,40}", - "ge_buy_limit": "2", - "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", - "grand_exchange_price": "4300000", - "durability": null, - "name": "Gilded armour set (sk)", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11940" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "4300000", - "durability": null, - "name": "Gilded armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11941" - }, - { - "requirements": "{1,40}", "ge_buy_limit": "100", - "examine": "Grand Exchange set containing helm, platebody, legs, boots and gloves", - "grand_exchange_price": "145000", - "durability": null, - "name": "Rockshell armour set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11942" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "145000", - "durability": null, - "name": "Rockshell armour set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11943" - }, - { - "requirements": "{1,40}-{4,40}", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing helm, body, chaps, boots and gloves", - "grand_exchange_price": "94500", - "durability": null, - "name": "Spined armour set", - "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11944", - "absorb": "0,13,6", - "bonuses": "-6,-6,-6,-31,29,68,56,78,34,62,47,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "94500", - "durability": null, - "name": "Spined armour set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11945" - }, - { "requirements": "{1,40}-{6,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11877", + "name": "Splitbark armour set", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11878", + "name": "Black trimmed armour set (l)", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,91,92,77,-12,90,23,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{10,1}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11879", + "name": "Black trimmed armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11880", + "name": "Black trimmed armour set (sk)", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,91,92,77,-12,90,23,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{10,1}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11881", + "name": "Black trimmed armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11882", + "name": "Black gold-trimmed armour set (l)", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{10,1}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11883", + "name": "Black gold-trimmed armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11884", + "name": "Black gold-trimmed armour set (sk)", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{10,1}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11885", + "name": "Black gold-trimmed armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11886", + "name": "Adamant trimmed armour set (l)", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11887", + "name": "Adamant trimmed armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11888", + "name": "Adamant trimmed armour set (sk)", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11889", + "name": "Adamant trimmed armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11890", + "name": "Adamant gold-trimmed armour set (l)", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11891", + "name": "Adamant gold-trimmed armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11892", + "name": "Adamant gold-trimmed armour set (sk)", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,30}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11893", + "name": "Adamant gold-trimmed armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11894", + "name": "Rune trimmed armour set (l)", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11895", + "name": "Rune trimmed armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11896", + "name": "Rune trimmed armour set (sk)", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true" + }, + { + "id": "11897", + "name": "Rune trimmed armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11898", + "name": "Rune gold-trimmed armour set (l)", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11899", + "name": "Rune gold-trimmed armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11900", + "name": "Rune gold-trimmed armour set (sk)", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11901", + "name": "Rune gold-trimmed armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11902", + "name": "Enchanted set", + "examine": "Grand Exchange set containing hat, robetops and bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{20,1}-{6,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11903", + "name": "Enchanted set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11904", + "name": "Trimmed blue wizard set", + "examine": "Grand Exchange set containing hat, robetops and bottoms", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "2" + }, + { + "id": "11905", + "name": "Trimmed blue wizard set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11906", + "name": "Gold-trimmed blue wizard set", + "examine": "Grand Exchange set containing hat, robe top and bottom", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11907", + "name": "Gold-trimmed blue wizard set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11908", + "name": "Trimmed leather armour set", + "examine": "Grand Exchange set containing body and chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{20,4}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11909", + "name": "Trimmed leather armour set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "11910", + "name": "Gold-trimmed leather armour set", + "examine": "Grand Exchange set containing body and chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "requirements": "{20,4}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11911", + "name": "Gold-trimmed leather armour set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "11912", + "name": "Green d'hide trimmed set", + "examine": "Grand Exchange set containing body and chaps", + "absorb": "0,10,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11913", + "name": "Green d'hide trimmed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11914", + "name": "Green d'hide gold-trimmed set", + "examine": "Grand Exchange set containing body and chaps", + "absorb": "0,10,5", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11915", + "name": "Green d'hide gold-trimmed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11916", + "name": "Blue d'hide trimmed set", + "examine": "Grand Exchange set containing body and chaps", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,50}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11917", + "name": "Blue d'hide trimmed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11918", + "name": "Blue d'hide gold-trimmed set", + "examine": "Grand Exchange set containing body and chaps.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,50}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11919", + "name": "Blue d'hide gold-trimmed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11920", + "name": "Green d'hide blessed set", + "examine": "Grand Exchange set containing body, chaps, bracers and coif.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11921", + "name": "Green d'hide blessed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11922", + "name": "Blue d'hide blessed set", + "examine": "Grand Exchange set containing body, chaps, bracers and coif.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11923", + "name": "Blue d'hide blessed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11924", + "name": "Red d'hide blessed set", + "examine": "Grand Exchange set containing body, chaps, bracers and coif.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}-{4,70}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11925", + "name": "Red d'hide blessed set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11926", + "name": "Guthix armour set (l)", + "examine": "Grand Exchange set containing full helm, platebody, legs and shield.", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11927", + "name": "Guthix armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11928", + "name": "Saradomin armour set (l)", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11929", + "name": "Saradomin armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11930", + "name": "Zamorak armour set (l)", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11931", + "name": "Zamorak armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11932", + "name": "Guthix armour set (sk)", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11933", + "name": "Guthix armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11934", + "name": "Saradomin armour set (sk)", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11935", + "name": "Saradomin armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11936", + "name": "Zamorak armour set (sk)", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield", + "absorb": "9,0,20", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11937", + "name": "Zamorak armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11938", + "name": "Gilded armour set (l)", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11939", + "name": "Gilded armour set (l)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11940", + "name": "Gilded armour set (sk)", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11941", + "name": "Gilded armour set (sk)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "11942", + "name": "Rockshell armour set", + "examine": "Grand Exchange set containing helm, platebody, legs, boots and gloves", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{1,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11943", + "name": "Rockshell armour set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11944", + "name": "Spined armour set", + "examine": "Grand Exchange set containing helm, body, chaps, boots and gloves", + "absorb": "0,13,6", + "archery_ticket_price": "0", + "bonuses": "-6,-6,-6,-31,29,68,56,78,34,62,47,0,0,0,0", + "durability": null, + "ge_buy_limit": "100", + "requirements": "{1,40}-{4,40}", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11945", + "name": "Spined armour set", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11946", + "name": "Skeletal armour set", "examine": "Grand Exchange set containing helm, top, bottoms, boots and gloves", - "grand_exchange_price": "145200", - "durability": null, - "name": "Skeletal armour set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11946" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "145200", - "durability": null, - "name": "Skeletal armour set", + "requirements": "{1,40}-{6,40}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "11947" + "weight": "2.2" }, { - "destroy_message": "You can get another from Diango in Draynor Village.", - "examine": "A tiny model of Lumbridge Castle inside a glass dome.", - "durability": null, - "name": "Snow globe", - "tradeable": "false", - "destroy": "true", + "id": "11947", + "name": "Skeletal armour set", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "11949", - "equipment_slot": "3" - }, - { - "destroy_message": "You can get another from Diango in Draynor Village.", - "examine": "A tiny model of Lumbridge Castle inside a glass dome.", - "durability": null, "name": "Snow globe", - "tradeable": "false", - "destroy": "true", + "examine": "A tiny model of Lumbridge Castle inside a glass dome.", "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { "id": "11950", - "equipment_slot": "3" + "name": "Snow globe", + "examine": "A tiny model of Lumbridge Castle inside a glass dome.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" }, { - "attack_anims": "5063", - "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", - "durability": null, - "name": "Snowball", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "11951", - "weapon_interface": "18", - "equipment_slot": "3" + "name": "Snowball", + "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", + "archery_ticket_price": "0", + "attack_anims": "5063", + "attack_speed": "4", + "durability": null, + "equipment_slot": "3", + "weapon_interface": "18" }, { - "bankable": "false", - "destroy_message": "You can get another from a snow imp.", - "examine": "Add this to a snowman to make a snow warrior.", - "durability": null, + "id": "11952", "name": "Ice sword", - "tradeable": "false", - "destroy": "true", + "examine": "Add this to a snowman to make a snow warrior.", "archery_ticket_price": "0", - "id": "11952" + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get another from a snow imp.", + "durability": null, + "tradeable": "false" }, { - "bankable": "false", - "destroy_message": "You can get another from a snow imp.", - "examine": "Add this to a snowman to make a snow mage.", - "attack_audios": "2555,0,0,0", - "durability": null, + "id": "11953", "name": "Winter staff", - "tradeable": "false", - "destroy": "true", + "examine": "Add this to a snowman to make a snow mage.", "archery_ticket_price": "0", - "id": "11953" + "attack_audios": "2555,0,0,0", + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get another from a snow imp.", + "durability": null, + "tradeable": "false" }, { - "bankable": "false", - "destroy_message": "You can get another from a snow imp.", - "examine": "Add this to a snowman to make a snow ranger.", - "durability": null, + "id": "11954", "name": "Holly bow", - "tradeable": "false", - "destroy": "true", + "examine": "Add this to a snowman to make a snow ranger.", "archery_ticket_price": "0", - "id": "11954" + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get another from a snow imp.", + "durability": null, + "tradeable": "false" }, { - "bankable": "false", - "destroy_message": "You can get another from a snow imp.", - "examine": "Add this to a snowman to make a barbarian snowman.", - "durability": null, + "id": "11955", "name": "Barbarian snowman hat", - "tradeable": "false", - "destroy": "true", + "examine": "Add this to a snowman to make a barbarian snowman.", "archery_ticket_price": "0", - "id": "11955" + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get another from a snow imp.", + "durability": null, + "tradeable": "false" }, { - "bankable": "false", - "destroy_message": "You can get another from a snow imp.", - "examine": "It's actually made of cardboard, but it looks like a dragon full helm.", - "durability": null, + "id": "11956", "name": "Dragon snowman hat", - "tradeable": "false", - "destroy": "true", + "examine": "It's actually made of cardboard, but it looks like a dragon full helm.", "archery_ticket_price": "0", - "id": "11956" + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get another from a snow imp.", + "durability": null, + "tradeable": "false" }, { - "bankable": "false", - "destroy_message": "You can get another from a snow imp.", - "examine": "Use this to make your snowman look like a dwarf.", - "durability": null, + "id": "11957", "name": "Dwarf snowman hat", - "tradeable": "false", - "destroy": "true", + "examine": "Use this to make your snowman look like a dwarf.", "archery_ticket_price": "0", - "id": "11957" - }, - { "bankable": "false", - "destroy_message": "Talk to a snow imp to get another.", - "examine": "Arr! Shiver me snowman!", - "durability": null, - "name": "Pirate snowman hat", - "tradeable": "false", "destroy": "true", - "archery_ticket_price": "0", - "id": "11958" - }, - { - "bankable": "false", "destroy_message": "You can get another from a snow imp.", - "examine": "The most traditional snowman hat.", "durability": null, - "name": "Snowman top hat", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11959" + "tradeable": "false" }, { + "id": "11958", + "name": "Pirate snowman hat", + "examine": "Arr! Shiver me snowman!", + "archery_ticket_price": "0", + "bankable": "false", + "destroy": "true", + "destroy_message": "Talk to a snow imp to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11959", + "name": "Snowman top hat", + "examine": "The most traditional snowman hat.", + "archery_ticket_price": "0", + "bankable": "false", + "destroy": "true", + "destroy_message": "You can get another from a snow imp.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11960", + "name": "Light mystic robes set", + "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", "requirements": "{20,1}-{6,40}", "shop_price": "215431", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11961", + "name": "Light mystic robes set", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "11962", + "name": "Dark mystic robes set", "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", - "grand_exchange_price": "487300", - "durability": null, - "name": "Light mystic robes set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11960" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "487300", - "durability": null, - "name": "Light mystic robes set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "11961" - }, - { "requirements": "{20,1}-{6,40}", "shop_price": "228541", - "ge_buy_limit": "100", - "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", - "grand_exchange_price": "294000", - "durability": null, - "name": "Dark mystic robes set", "tradeable": "true", - "weight": "2.2", - "archery_ticket_price": "0", - "id": "11962" + "weight": "2.2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "294000", - "durability": null, + "id": "11963", "name": "Dark mystic robes set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11963" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "I can hatch this in an incubator.", - "durability": null, + "id": "11964", "name": "Raven egg", - "archery_ticket_price": "0", - "id": "11964" - }, - { "examine": "I can hatch this in an incubator.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "11965", "name": "Vulture egg", + "examine": "I can hatch this in an incubator.", "archery_ticket_price": "0", - "id": "11965" + "durability": null }, { - "examine": "Full: ", - "durability": null, + "id": "11966", "name": "Bird's nest", + "examine": "Full: ", "archery_ticket_price": "0", - "id": "11966" + "durability": null }, { - "shop_price": "750000", - "ge_buy_limit": "10", + "id": "11967", + "name": "Dwarf cannon set", "examine": "Grand Exchange set containing cannon base, stand, barrels and furnace.", - "grand_exchange_price": "718900", - "durability": null, - "name": "Dwarf cannon set", - "tradeable": "true", - "weight": "2.2", "archery_ticket_price": "0", - "id": "11967" - }, - { + "durability": null, "ge_buy_limit": "10", - "grand_exchange_price": "718900", - "durability": null, + "shop_price": "750000", + "tradeable": "true", + "weight": "2.2" + }, + { + "id": "11968", "name": "Dwarf cannon set", - "tradeable": "true", "archery_ticket_price": "0", - "id": "11968" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "destroy_message": "If I destroy this it will disintegrate into its component parts and drop to the floor.", - "examine": "A water tiara infused with water runes. Protects from the hot desert sun.", - "durability": null, - "name": "Enchanted water tiara", - "weight": "1", - "archery_ticket_price": "0", "id": "11969", + "name": "Enchanted water tiara", + "examine": "A water tiara infused with water runes. Protects from the hot desert sun.", + "archery_ticket_price": "0", "bonuses": "0,0,0,2,0,5,5,5,3,3,0,0,2,0,0", - "equipment_slot": "0" + "destroy_message": "If I destroy this it will disintegrate into its component parts and drop to the floor.", + "durability": null, + "equipment_slot": "0", + "weight": "1" }, { - "destroy_message": "I can obtain and fill another one from the archaeologist near Sophanem.", - "examine": "A crate full of distressed gear.", - "durability": null, + "id": "11970", "name": "Smelly crate", - "tradeable": "false", - "destroy": "true", - "weight": "30", + "examine": "A crate full of distressed gear.", "archery_ticket_price": "0", - "id": "11970" + "destroy": "true", + "destroy_message": "I can obtain and fill another one from the archaeologist near Sophanem.", + "durability": null, + "tradeable": "false", + "weight": "30" }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "An empty crate, ready for bronze gear.", - "durability": null, + "id": "11972", "name": "Empty crate", + "examine": "An empty crate, ready for bronze gear.", "archery_ticket_price": "0", - "id": "11972" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "destroy_message": "I can obtain another one from the archaeologist near Sophanem.", - "examine": "A book of research on Scabarite history.", - "durability": null, + "id": "11973", "name": "Scabaras research", - "tradeable": "false", - "destroy": "true", - "weight": "1", + "examine": "A book of research on Scabarite history.", "archery_ticket_price": "0", - "id": "11973" + "destroy": "true", + "destroy_message": "I can obtain another one from the archaeologist near Sophanem.", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "I can obtain another one from Simon Templeton.", - "examine": "Issued by Simon Templeton.", - "durability": null, + "id": "11974", "name": "Artefact receipt", - "tradeable": "false", - "destroy": "true", + "examine": "Issued by Simon Templeton.", "archery_ticket_price": "0", - "id": "11974" + "destroy": "true", + "destroy_message": "I can obtain another one from Simon Templeton.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", - "durability": null, + "id": "11975", "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11975" - }, - { - "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", "examine": "See article", - "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", - "id": "11976" - }, - { + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11977" + "tradeable": "false" }, { + "id": "11976", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11978" + "tradeable": "false" }, { + "id": "11977", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11979" + "tradeable": "false" }, { + "id": "11978", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11980" + "tradeable": "false" }, { + "id": "11979", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11981" + "tradeable": "false" }, { + "id": "11980", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11982" + "tradeable": "false" }, { + "id": "11981", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11983" + "tradeable": "false" }, { + "id": "11982", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11984" + "tradeable": "false" }, { + "id": "11983", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11985" + "tradeable": "false" }, { + "id": "11984", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11986" + "tradeable": "false" }, { + "id": "11985", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11987" + "tradeable": "false" }, { + "id": "11986", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11988" + "tradeable": "false" }, { + "id": "11987", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11989" + "tradeable": "false" }, { + "id": "11988", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11990" + "tradeable": "false" }, { + "id": "11989", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11991" + "tradeable": "false" }, { + "id": "11990", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11992" + "tradeable": "false" }, { + "id": "11991", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", - "examine": "See article", "durability": null, - "name": "Scabarite notes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "11993" + "tradeable": "false" }, { - "destroy_message": "I can obtain another one from the archaeologists near Sophanem.", - "examine": "Newly made, but to an ancient pattern. (Dealing with Scabaras)", + "id": "11992", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", "durability": null, + "tradeable": "false" + }, + { + "id": "11993", + "name": "Scabarite notes", + "examine": "See article", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "durability": null, + "tradeable": "false" + }, + { + "id": "11994", "name": "Scabarite key", - "tradeable": "false", - "destroy": "true", + "examine": "Newly made, but to an ancient pattern. (Dealing with Scabaras)", "archery_ticket_price": "0", - "id": "11994" + "destroy": "true", + "destroy_message": "I can obtain another one from the archaeologists near Sophanem.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze dagger.", - "examine": "It has been oxidised.", - "attack_audios": "2517,2517,2500,2517", - "durability": null, + "id": "11995", "name": "Oxidised dagger", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "11995" + "attack_audios": "2517,2517,2500,2517", + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze dagger.", + "durability": null, + "tradeable": "false" }, { - "examine": "It has been oxidised.", - "durability": null, + "id": "11996", "name": "Oxidised medium helm", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "11996" + "destroy": "true", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze sword.", - "examine": "It has been oxidised.", - "durability": null, + "id": "11997", "name": "Oxidised sword", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "11997" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze sword.", + "durability": null, + "tradeable": "false" }, { - "turn90cw_anim": "821", - "examine": "It has been oxidised.", - "walk_anim": "819", - "durability": null, - "destroy": "true", - "turn90ccw_anim": "822", - "turn180_anim": "820", - "render_anim": "1", - "destroy_message": "I can make another one by using camel dung on a bronze scimitar.", - "stand_anim": "808", - "attack_audios": "2500,0,2517,0", - "name": "Oxidised scimitar", - "tradeable": "false", - "run_anim": "824", - "archery_ticket_price": "0", "id": "11998", - "stand_turn_anim": "823" + "name": "Oxidised scimitar", + "examine": "It has been oxidised.", + "archery_ticket_price": "0", + "attack_audios": "2500,0,2517,0", + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze scimitar.", + "durability": null, + "render_anim": "1", + "run_anim": "824", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "false", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819" }, { - "destroy_message": "I can make another one by using camel dung on a bronze longsword.", - "examine": "It has been oxidised.", - "durability": null, + "id": "11999", "name": "Oxidised longsword", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "11999" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze longsword.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze full helmet.", - "examine": "It has been oxidised.", - "durability": null, + "id": "12000", "name": "Oxidised full helm", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "12000" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze full helmet.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze square shield.", - "examine": "It has been oxidised.", - "durability": null, + "id": "12001", "name": "Oxidised square shield", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "12001" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze square shield.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze chainbody.", - "examine": "It has been oxidised.", - "durability": null, + "id": "12002", "name": "Oxidised chainbody", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "12002" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze chainbody.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze kiteshield.", - "examine": "It has been oxidised.", - "durability": null, + "id": "12003", "name": "Oxidised kiteshield", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "12003" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze kiteshield.", + "durability": null, + "equip_audio": "2245", + "tradeable": "false" }, { - "destroy_message": "I can make another one by using camel dung on a bronze two", - "examine": "It has been oxidised.", - "durability": null, + "id": "12004", "name": "Oxidised two-handed sword", - "tradeable": "false", - "destroy": "true", - "weight": "4", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "12004" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze two", + "durability": null, + "tradeable": "false", + "weight": "4" }, { - "destroy_message": "I can make another one by using camel dung on some bronze platelegs.", - "examine": "It has been oxidised.", - "durability": null, + "id": "12005", "name": "Oxidised platelegs", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12005" - }, - { - "destroy_message": "I can make another one by using camel dung on a bronze plateskirt.", "examine": "It has been oxidised.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on some bronze platelegs.", "durability": null, + "tradeable": "false" + }, + { + "id": "12006", "name": "Oxidised plateskirt", - "tradeable": "false", - "destroy": "true", + "examine": "It has been oxidised.", "archery_ticket_price": "0", - "id": "12006" + "destroy": "true", + "destroy_message": "I can make another one by using camel dung on a bronze plateskirt.", + "durability": null, + "tradeable": "false" }, { - "requirements": "{23,52}", - "ge_buy_limit": "5000", - "grand_exchange_price": "330", + "id": "12007", + "name": "Spirit terrorbird pouch", "examine": "I can summon a spirit terrorbird familiar with this.", - "durability": null, - "name": "Spirit terrorbird pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12007" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,52}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "330", + "id": "12008", + "name": "Spirit terrorbird pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit terrorbird pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12008" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{16,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "239", + "id": "12009", + "name": "Granite crab pouch", "examine": "I can summon a granite crab familiar with this.", - "durability": null, - "name": "Granite crab pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12009" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{16,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "239", + "id": "12010", + "name": "Granite crab pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Granite crab pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12010" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,75}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2918", + "id": "12011", + "name": "Praying mantis pouch", "examine": "I can summon a praying mantis familiar with this.", - "durability": null, - "name": "Praying mantis pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12011" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,75}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2918", + "id": "12012", + "name": "Praying mantis pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Praying mantis pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12012" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,78}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2167", + "id": "12013", + "name": "Giant ent pouch", "examine": "I can summon a giant ent familiar with this.", - "durability": null, - "name": "Giant ent pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12013" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,78}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2167", + "id": "12014", + "name": "Giant ent pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Giant ent pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12014" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,63}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2018", + "id": "12015", + "name": "Spirit cobra pouch", "examine": "I can summon a spirit cobra familiar with this.", - "durability": null, - "name": "Spirit cobra pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12015" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,63}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2018", + "id": "12016", + "name": "Spirit cobra pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit cobra pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12016" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,83}", - "ge_buy_limit": "5000", - "grand_exchange_price": "121", + "id": "12017", + "name": "Spirit dagannoth pouch", "examine": "I can summon a spirit dagannoth familiar with this.", - "durability": null, - "name": "Spirit dagannoth pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12017" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,83}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "121", + "id": "12018", + "name": "Spirit dagannoth pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit dagannoth pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12018" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{13,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "248", + "id": "12019", + "name": "Thorny snail pouch", "examine": "I can summon a thorny snail familiar with this.", - "durability": null, - "name": "Thorny snail pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12019" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{13,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "248", + "id": "12020", + "name": "Thorny snail pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Thorny snail pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12020" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,33}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1268", + "id": "12021", + "name": "Beaver pouch", "examine": "I can summon a beaver familiar with this.", - "durability": null, - "name": "Beaver pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12021" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,33}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1268", + "id": "12022", + "name": "Beaver pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Beaver pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12022" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,58}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2520", + "id": "12023", + "name": "Karam. overlord pouch", "examine": "I can summon a karamthulhu overlord familiar with this.", - "durability": null, - "name": "Karam. overlord pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12023" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,58}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2520", + "id": "12024", + "name": "Karam. overlord pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Karam. overlord pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12024" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,80}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2235", + "id": "12025", + "name": "Hydra pouch", "examine": "I can summon a hydra familiar with this.", - "durability": null, - "name": "Hydra pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12025" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,80}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2235", + "id": "12026", + "name": "Hydra pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Hydra pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12026" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,55}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2641", + "id": "12027", + "name": "Spirit jelly pouch", "examine": "I can summon a spirit jelly familiar with this.", - "durability": null, - "name": "Spirit jelly pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12027" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,55}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2641", + "id": "12028", + "name": "Spirit jelly pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit jelly pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12028" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,68}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3506", + "id": "12029", + "name": "Bunyip pouch", "examine": "I can summon a bunyip familiar with this.", - "durability": null, - "name": "Bunyip pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12029" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,68}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "3506", + "id": "12030", + "name": "Bunyip pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Bunyip pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12030" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,67}", - "ge_buy_limit": "5000", - "grand_exchange_price": "13200", + "id": "12031", + "name": "War tortoise pouch", "examine": "I can summon a war tortoise familiar with this.", - "durability": null, - "name": "War tortoise pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12031" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,67}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "13200", + "id": "12032", + "name": "War tortoise pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "War tortoise pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12032" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,69}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2269", + "id": "12033", + "name": "Fruit bat pouch", "examine": "I can summon a fruit bat familiar with this.", - "durability": null, - "name": "Fruit bat pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12033" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,69}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2269", + "id": "12034", + "name": "Fruit bat pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Fruit bat pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12034" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,54}", - "ge_buy_limit": "5000", - "grand_exchange_price": "4004", + "id": "12035", + "name": "Abyssal parasite pouch", "examine": "I can summon an abyssal parasite familiar with this.", - "durability": null, - "name": "Abyssal parasite pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12035" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,54}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "4004", + "id": "12036", + "name": "Abyssal parasite pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Abyssal parasite pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12036" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,62}", - "ge_buy_limit": "5000", - "grand_exchange_price": "5660", + "id": "12037", + "name": "Abyssal lurker pouch", "examine": "I can summon an abyssal lurker familiar with this.", - "durability": null, - "name": "Abyssal lurker pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12037" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,62}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "5660", + "id": "12038", + "name": "Abyssal lurker pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Abyssal lurker pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12038" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,88}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2439", + "id": "12039", + "name": "Unicorn stallion pouch", "examine": "I can summon a unicorn stallion familiar with this.", - "durability": null, - "name": "Unicorn stallion pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12039" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,88}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2439", + "id": "12040", + "name": "Unicorn stallion pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Unicorn stallion pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12040" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,47}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1559", + "id": "12041", + "name": "Magpie pouch", "examine": "I can summon a magpie familiar with this.", - "durability": null, - "name": "Magpie pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12041" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,47}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1559", + "id": "12042", + "name": "Magpie pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Magpie pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12042" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{4,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "258", + "id": "12043", + "name": "Dreadfowl pouch", "examine": "I can summon a dreadfowl familiar with this.", - "durability": null, - "name": "Dreadfowl pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12043" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{4,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "258", + "id": "12044", + "name": "Dreadfowl pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Dreadfowl pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12044" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,64}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2216", + "id": "12045", + "name": "Stranger plant pouch", "examine": "I can summon a stranger plant familiar with this.", - "durability": null, - "name": "Stranger plant pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12045" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,64}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2216", + "id": "12046", + "name": "Stranger plant pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Stranger plant pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12046" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "301", + "id": "12047", + "name": "Spirit wolf pouch", "examine": "I can summon a spirit wolf familiar with this.", - "durability": null, - "name": "Spirit wolf pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12047" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "301", + "id": "12048", + "name": "Spirit wolf pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit wolf pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12048" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{18,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "808", + "id": "12049", + "name": "Desert wyrm pouch", "examine": "I can summon a desert wyrm familiar with this.", - "durability": null, - "name": "Desert wyrm pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12049" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{18,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "808", + "id": "12050", + "name": "Desert wyrm pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Desert wyrm pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12050" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,42}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1812", + "id": "12051", + "name": "Evil turnip pouch", "examine": "I can summon an evil turnip familiar with this.", - "durability": null, - "name": "Evil turnip pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12051" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "1812", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Evil turnip pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12052" + "requirements": "{23,42}", + "tradeable": "true" }, { - "requirements": "{23,31}", - "ge_buy_limit": "10000", - "grand_exchange_price": "1416", + "id": "12052", + "name": "Evil turnip pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12053", + "name": "Vampire bat pouch", "examine": "I can summon a vampire bat familiar with this.", - "durability": null, - "name": "Vampire bat pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12053" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "1416", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Vampire bat pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12054" + "requirements": "{23,31}", + "tradeable": "true" }, { - "requirements": "{19,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "992", + "id": "12054", + "name": "Vampire bat pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "12055", + "name": "Spirit scorpion pouch", "examine": "I can summon a spirit scorpion familiar with this.", - "durability": null, - "name": "Spirit scorpion pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12055" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{19,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "992", + "id": "12056", + "name": "Spirit scorpion pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit scorpion pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12056" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,71}", - "ge_buy_limit": "5000", - "grand_exchange_price": "332", + "id": "12057", + "name": "Arctic bear pouch", "examine": "I can summon an arctic bear familiar with this.", - "durability": null, - "name": "Arctic bear pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12057" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,71}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "332", + "id": "12058", + "name": "Arctic bear pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Arctic bear pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12058" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{10,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2225", + "id": "12059", + "name": "Spirit spider pouch", "examine": "I can summon a spirit spider familiar with this.", - "durability": null, - "name": "Spirit spider pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12059" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{10,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2225", + "id": "12060", + "name": "Spirit spider pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit spider pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12060" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,49}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2045", + "id": "12061", + "name": "Bloated leech pouch", "examine": "I can summon a bloated leech familiar with this.", - "durability": null, - "name": "Bloated leech pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12061" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,49}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2045", + "id": "12062", + "name": "Bloated leech pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Bloated leech pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12062" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,25}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3746", + "id": "12063", + "name": "Spirit kalphite pouch", "examine": "I can summon a spirit kalphite familiar with this.", - "durability": null, - "name": "Spirit kalphite pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12063" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,25}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "3746", + "id": "12064", + "name": "Spirit kalphite pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit kalphite pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12064" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,32}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1470", + "id": "12065", + "name": "Honey badger pouch", "examine": "I can summon a honey badger familiar with this.", - "durability": null, - "name": "Honey badger pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12065" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,32}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1470", + "id": "12066", + "name": "Honey badger pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Honey badger pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12066" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1578", + "id": "12067", + "name": "Albino rat pouch", "examine": "I can summon an albino rat familiar with this.", - "durability": null, - "name": "Albino rat pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12067" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,23}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1578", + "id": "12068", + "name": "Albino rat pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Albino rat pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12068" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,74}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2924", + "id": "12069", + "name": "Granite lobster pouch", "examine": "I can summon a granite lobster familiar with this.", - "durability": null, - "name": "Granite lobster pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12069" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,74}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2924", + "id": "12070", + "name": "Granite lobster pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Granite lobster pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12070" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,41}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1375", + "id": "12071", + "name": "Macaw pouch", "examine": "I can summon a macaw familiar with this.", - "durability": null, - "name": "Macaw pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12071" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,41}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1375", + "id": "12072", + "name": "Macaw pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Macaw pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12072" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,36}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1804", + "id": "12073", + "name": "Bronze minotaur pouch", "examine": "I can summon a bronze minotaur familiar with this.", - "durability": null, - "name": "Bronze minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12073" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,36}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1804", + "id": "12074", + "name": "Bronze minotaur pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Bronze minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12074" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,46}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2216", + "id": "12075", + "name": "Iron minotaur pouch", "examine": "I can summon an iron minotaur familiar with this.", - "durability": null, - "name": "Iron minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12075" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,46}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2216", + "id": "12076", + "name": "Iron minotaur pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Iron minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12076" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,56}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2529", + "id": "12077", + "name": "Steel minotaur pouch", "examine": "I can summon a steel minotaur familiar with this", - "durability": null, - "name": "Steel minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12077" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,56}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "2529", + "id": "12078", + "name": "Steel minotaur pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Steel minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12078" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,66}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2666", + "id": "12079", + "name": "Mithril minotaur pouch", "examine": "I can summon a mithril minotaur with this.", - "durability": null, - "name": "Mithril minotaur pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12079" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "2666", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Mithril minotaur pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12080" - }, - { - "requirements": "{23,76}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2520", - "examine": "I can summon an adamant minotaur familiar with this.", - "durability": null, - "name": "Adamant minotaur pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12081" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2520", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Adamant minotaur pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12082" - }, - { - "requirements": "{23,86}", - "ge_buy_limit": "5000", - "grand_exchange_price": "373", - "examine": "I can summon a rune minotaur with this.", - "durability": null, - "name": "Rune minotaur pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12083" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "373", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Rune minotaur pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12084" - }, - { - "requirements": "{23,61}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2468", - "examine": "I can summon a smoke devil familiar with this.", - "durability": null, - "name": "Smoke devil pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12085" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2468", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Smoke devil pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12086" - }, - { - "requirements": "{23,40}", - "ge_buy_limit": "5000", - "grand_exchange_price": "319", - "examine": "I can summon a bull ant familiar with this.", - "durability": null, - "name": "Bull ant pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12087" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "319", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Bull ant pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12088" - }, - { - "requirements": "{23,92}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3625", - "examine": "I can summon a wolpertinger familiar with this.", - "durability": null, - "name": "Wolpertinger pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12089" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3625", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Wolpertinger pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12090" - }, - { - "requirements": "{23,28}", - "ge_buy_limit": "5000", - "grand_exchange_price": "906", - "examine": "I can summon a compost mound familiar with this.", - "durability": null, - "name": "Compost mound pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12091" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "906", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Compost mound pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12092" - }, - { - "requirements": "{23,96}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3696", - "examine": "I can summon a pack yak familiar with this.", - "durability": null, - "name": "Pack yak pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12093" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3696", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Pack yak pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12094" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1514", - "examine": "I can summon a spirit cockatrice familiar with this.", - "durability": null, - "name": "Sp. cockatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12095" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1514", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. cockatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12096" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1523", - "examine": "I can summon a spirit guthatrice familiar with this.", - "durability": null, - "name": "Sp. guthatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12097" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1523", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. guthatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12098" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1492", - "examine": "I can summon a spirit saratrice familiar with this.", - "durability": null, - "name": "Sp. saratrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12099" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1492", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. saratrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12100" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1515", - "examine": "I can summon a spirit zamatrice familiar with this.", - "durability": null, - "name": "Sp. zamatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12101" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1515", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. zamatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12102" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1531", - "examine": "I can summon a spirit pengatrice familiar with this.", - "durability": null, - "name": "Sp. pengatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12103" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1531", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. pengatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12104" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3085", - "examine": "I can summon a spirit coraxatrice familiar with this.", - "durability": null, - "name": "Sp. coraxatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12105" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3085", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. coraxatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12106" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3881", - "examine": "I can summon a spirit vulatrice familiar with this.", - "durability": null, - "name": "Sp. vulatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12107" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3881", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Sp. vulatrice pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12108" - }, - { - "ge_buy_limit": "10000", - "examine": "A stripy brown egg.", - "grand_exchange_price": "1053", - "durability": null, - "name": "Cockatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12109" - }, - { - "ge_buy_limit": "10000", - "grand_exchange_price": "1053", - "durability": null, - "name": "Cockatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12110" - }, - { - "ge_buy_limit": "5000", - "examine": "A stripy green egg.", - "grand_exchange_price": "1171", - "durability": null, - "name": "Guthatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12111" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1171", - "durability": null, - "name": "Guthatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12112" - }, - { - "ge_buy_limit": "5000", - "examine": "A stripy blue egg.", - "grand_exchange_price": "1080", - "durability": null, - "name": "Saratrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12113" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1080", - "durability": null, - "name": "Saratrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12114" - }, - { - "ge_buy_limit": "5000", - "examine": "A stripy red egg.", - "grand_exchange_price": "1154", - "durability": null, - "name": "Zamatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12115" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1154", - "durability": null, - "name": "Zamatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12116" - }, - { - "ge_buy_limit": "5000", - "examine": "A stripy grey egg.", - "grand_exchange_price": "2676", - "durability": null, - "name": "Pengatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12117" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2676", - "durability": null, - "name": "Pengatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12118" - }, - { - "ge_buy_limit": "5000", - "examine": "A stripy black egg.", - "grand_exchange_price": "2865", - "durability": null, - "name": "Coraxatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12119" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2865", - "durability": null, - "name": "Coraxatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12120" - }, - { - "ge_buy_limit": "5000", - "examine": "A stripy pink egg.", - "grand_exchange_price": "18900", - "durability": null, - "name": "Vulatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12121" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "18900", - "durability": null, - "name": "Vulatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12122" - }, - { "requirements": "{23,66}", - "ge_buy_limit": "5000", - "grand_exchange_price": "293", - "examine": "I can summon a barker toad familiar with this.", - "durability": null, - "name": "Barker toad pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12123" + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "293", + "id": "12080", + "name": "Mithril minotaur pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Barker toad pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12124" - }, - { - "shop_price": "10", - "ge_buy_limit": "100", - "examine": "A swarm of little flies.", - "grand_exchange_price": "97", "durability": null, - "name": "Flies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12125" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "97", - "durability": null, - "name": "Flies", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12126" - }, - { - "shop_price": "10", - "ge_buy_limit": "100", - "examine": "Some beetle bits.", - "grand_exchange_price": "176", - "durability": null, - "name": "Beetle bits", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12127" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "176", - "durability": null, - "name": "Beetle bits", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12128" - }, - { - "ge_buy_limit": "100", - "examine": "Good for feeding birds.", - "grand_exchange_price": "1", - "durability": null, - "name": "Ground fishing bait", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12129" - }, - { - "shop_price": "10", - "ge_buy_limit": "100", - "examine": "Mmmm...nuts.", - "grand_exchange_price": "673", - "durability": null, - "name": "Nuts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12130" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "673", - "durability": null, - "name": "Nuts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12131" - }, - { - "examine": "Makes me want to do a truffle shuffle.", - "durability": null, - "name": "Truffle", - "tradeable": "false", - "destroy": "true", - "weight": "28.928", - "archery_ticket_price": "0", - "id": "12132" - }, - { - "durability": null, - "name": "Truffle", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12133", - "equipment_slot": "3" - }, - { "ge_buy_limit": "5000", - "examine": "An evil turnip.", - "grand_exchange_price": "6750", - "durability": null, - "name": "Evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12134" + "tradeable": "true" }, { + "id": "12081", + "name": "Adamant minotaur pouch", + "examine": "I can summon an adamant minotaur familiar with this.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "6750", - "durability": null, - "name": "Evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12135" + "requirements": "{23,76}", + "tradeable": "true" }, { + "id": "12082", + "name": "Adamant minotaur pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "examine": "An evil turnip.", - "grand_exchange_price": "133", - "durability": null, - "name": "2/3 evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12136" + "tradeable": "true" }, { + "id": "12083", + "name": "Rune minotaur pouch", + "examine": "I can summon a rune minotaur with this.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "133", - "durability": null, - "name": "2/3 evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12137" + "requirements": "{23,86}", + "tradeable": "true" }, { + "id": "12084", + "name": "Rune minotaur pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "examine": "An evil turnip.", - "grand_exchange_price": "20", - "durability": null, - "name": "1/3 evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12138" + "tradeable": "true" }, { + "id": "12085", + "name": "Smoke devil pouch", + "examine": "I can summon a smoke devil familiar with this.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "20", - "durability": null, - "name": "1/3 evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12139" + "requirements": "{23,61}", + "tradeable": "true" }, { - "ge_buy_limit": "100", - "examine": "4 doses of Summoning potion.", - "grand_exchange_price": "4489", - "durability": null, - "name": "Summoning potion(4)", - "tradeable": "true", - "weight": "1", + "id": "12086", + "name": "Smoke devil pouch", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "id": "12140" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "4489", "durability": null, - "name": "Summoning potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12141" - }, - { - "ge_buy_limit": "100", - "examine": "3 doses of Summoning potion.", - "grand_exchange_price": "3320", - "durability": null, - "name": "Summoning potion(3)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12142" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3320", - "durability": null, - "name": "Summoning potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12143" - }, - { - "ge_buy_limit": "100", - "examine": "2 doses of Summoning potion.", - "grand_exchange_price": "1671", - "durability": null, - "name": "Summoning potion(2)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12144" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1671", - "durability": null, - "name": "Summoning potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12145" - }, - { - "ge_buy_limit": "100", - "examine": "1 dose of Summoning potion.", - "grand_exchange_price": "1576", - "durability": null, - "name": "Summoning potion(1)", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12146" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "1576", - "durability": null, - "name": "Summoning potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12147" - }, - { - "ge_buy_limit": "100", - "examine": "Grows into the root-vegetable of all evil.", - "grand_exchange_price": "68", - "durability": null, - "name": "Evil turnip seed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12148" - }, - { "ge_buy_limit": "5000", - "examine": "Utterly terrifying!", - "grand_exchange_price": "7101", - "durability": null, - "name": "Carved evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12153" + "tradeable": "true" }, { + "id": "12087", + "name": "Bull ant pouch", + "examine": "I can summon a bull ant familiar with this.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "7101", - "durability": null, - "name": "Carved evil turnip", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12154" + "requirements": "{23,40}", + "tradeable": "true" }, { + "id": "12088", + "name": "Bull ant pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12089", + "name": "Wolpertinger pouch", + "examine": "I can summon a wolpertinger familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,92}", + "tradeable": "true" + }, + { + "id": "12090", + "name": "Wolpertinger pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12091", + "name": "Compost mound pouch", + "examine": "I can summon a compost mound familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,28}", + "tradeable": "true" + }, + { + "id": "12092", + "name": "Compost mound pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12093", + "name": "Pack yak pouch", + "examine": "I can summon a pack yak familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,96}", + "tradeable": "true" + }, + { + "id": "12094", + "name": "Pack yak pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12095", + "name": "Sp. cockatrice pouch", + "examine": "I can summon a spirit cockatrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12096", + "name": "Sp. cockatrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12097", + "name": "Sp. guthatrice pouch", + "examine": "I can summon a spirit guthatrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12098", + "name": "Sp. guthatrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12099", + "name": "Sp. saratrice pouch", + "examine": "I can summon a spirit saratrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12100", + "name": "Sp. saratrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12101", + "name": "Sp. zamatrice pouch", + "examine": "I can summon a spirit zamatrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12102", + "name": "Sp. zamatrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12103", + "name": "Sp. pengatrice pouch", + "examine": "I can summon a spirit pengatrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12104", + "name": "Sp. pengatrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12105", + "name": "Sp. coraxatrice pouch", + "examine": "I can summon a spirit coraxatrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12106", + "name": "Sp. coraxatrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12107", + "name": "Sp. vulatrice pouch", + "examine": "I can summon a spirit vulatrice familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12108", + "name": "Sp. vulatrice pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12109", + "name": "Cockatrice egg", + "examine": "A stripy brown egg.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "3", - "examine": "Can be used to create Summoning pouches.", + "tradeable": "true" + }, + { + "id": "12110", + "name": "Cockatrice egg", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "12111", + "name": "Guthatrice egg", + "examine": "A stripy green egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12112", + "name": "Guthatrice egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12113", + "name": "Saratrice egg", + "examine": "A stripy blue egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12114", + "name": "Saratrice egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12115", + "name": "Zamatrice egg", + "examine": "A stripy red egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12116", + "name": "Zamatrice egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12117", + "name": "Pengatrice egg", + "examine": "A stripy grey egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12118", + "name": "Pengatrice egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12119", + "name": "Coraxatrice egg", + "examine": "A stripy black egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12120", + "name": "Coraxatrice egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12121", + "name": "Vulatrice egg", + "examine": "A stripy pink egg.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12122", + "name": "Vulatrice egg", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12123", + "name": "Barker toad pouch", + "examine": "I can summon a barker toad familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,66}", + "tradeable": "true" + }, + { + "id": "12124", + "name": "Barker toad pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12125", + "name": "Flies", + "examine": "A swarm of little flies.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "12126", + "name": "Flies", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12127", + "name": "Beetle bits", + "examine": "Some beetle bits.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "12128", + "name": "Beetle bits", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12129", + "name": "Ground fishing bait", + "examine": "Good for feeding birds.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12130", + "name": "Nuts", + "examine": "Mmmm...nuts.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "12131", + "name": "Nuts", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12132", + "name": "Truffle", + "examine": "Makes me want to do a truffle shuffle.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "tradeable": "false", + "weight": "28.928" + }, + { + "id": "12133", + "name": "Truffle", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "12134", + "name": "Evil turnip", + "examine": "An evil turnip.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12135", + "name": "Evil turnip", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12136", + "name": "2/3 evil turnip", + "examine": "An evil turnip.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12137", + "name": "2/3 evil turnip", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12138", + "name": "1/3 evil turnip", + "examine": "An evil turnip.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12139", + "name": "1/3 evil turnip", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12140", + "name": "Summoning potion(4)", + "examine": "4 doses of Summoning potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "12141", + "name": "Summoning potion(4)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12142", + "name": "Summoning potion(3)", + "examine": "3 doses of Summoning potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "12143", + "name": "Summoning potion(3)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12144", + "name": "Summoning potion(2)", + "examine": "2 doses of Summoning potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "12145", + "name": "Summoning potion(2)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12146", + "name": "Summoning potion(1)", + "examine": "1 dose of Summoning potion.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "12147", + "name": "Summoning potion(1)", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12148", + "name": "Evil turnip seed", + "examine": "Grows into the root-vegetable of all evil.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12153", + "name": "Carved evil turnip", + "examine": "Utterly terrifying!", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12154", + "name": "Carved evil turnip", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12155", "name": "Pouch", - "tradeable": "true", + "examine": "Can be used to create Summoning pouches.", "archery_ticket_price": "0", - "id": "12155" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "ge_buy_limit": "5000", + "id": "12156", + "name": "Honeycomb", "examine": "This is what bees craft.", - "grand_exchange_price": "393", - "durability": null, - "name": "Honeycomb", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12156" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "393", - "durability": null, + "tradeable": "true" + }, + { + "id": "12157", "name": "Honeycomb", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12157" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "shop_price": "1", - "examine": "A charm used to summon familiars.", - "durability": null, + "id": "12158", "name": "Gold charm", - "tradeable": "false", + "examine": "A charm used to summon familiars.", "archery_ticket_price": "0", - "id": "12158" + "durability": null, + "shop_price": "1", + "tradeable": "false" }, { - "examine": "A charm used to summon familiars.", - "durability": null, + "id": "12159", "name": "Green charm", - "tradeable": "false", + "examine": "A charm used to summon familiars.", "archery_ticket_price": "0", - "id": "12159" + "durability": null, + "tradeable": "false" }, { - "examine": "A charm used to summon familiars.", - "durability": null, + "id": "12160", "name": "Crimson charm", - "tradeable": "false", + "examine": "A charm used to summon familiars.", "archery_ticket_price": "0", - "id": "12160" + "durability": null, + "tradeable": "false" }, { - "examine": "A charm used to summon familiars", - "durability": null, + "id": "12161", "name": "Abyssal charm", - "tradeable": "false", + "examine": "A charm used to summon familiars", "archery_ticket_price": "0", - "id": "12161" + "durability": null, + "tradeable": "false" }, { - "examine": "A charm used to summon talon beasts.", - "durability": null, + "id": "12162", "name": "Talon beast charm", + "examine": "A charm used to summon talon beasts.", "archery_ticket_price": "0", - "id": "12162" + "durability": null }, { - "examine": "A charm used to summon familiars.", - "durability": null, + "id": "12163", "name": "Blue charm", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12163" - }, - { - "shop_price": "2", - "examine": "A charm needed to summon a Void ravager.", - "durability": null, - "name": "Ravager charm", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12164" - }, - { - "shop_price": "2", - "examine": "A charm needed to summon a Void shifter.", - "durability": null, - "name": "Shifter charm", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12165" - }, - { - "shop_price": "2", - "examine": "A charm needed to summon a Void Spinner.", - "durability": null, - "name": "Spinner charm", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12166" - }, - { - "shop_price": "2", - "examine": "A charm needed to summon a Void torcher.", - "durability": null, - "name": "Torcher charm", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12167" - }, - { "examine": "A charm used to summon familiars.", - "durability": null, - "name": "Obsidian charm", "archery_ticket_price": "0", - "id": "12168" + "durability": null, + "tradeable": "false" }, { + "id": "12164", + "name": "Ravager charm", + "examine": "A charm needed to summon a Void ravager.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "false" + }, + { + "id": "12165", + "name": "Shifter charm", + "examine": "A charm needed to summon a Void shifter.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "false" + }, + { + "id": "12166", + "name": "Spinner charm", + "examine": "A charm needed to summon a Void Spinner.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "false" + }, + { + "id": "12167", + "name": "Torcher charm", + "examine": "A charm needed to summon a Void torcher.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "false" + }, + { + "id": "12168", + "name": "Obsidian charm", + "examine": "A charm used to summon familiars.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12169", + "name": "Summoning cape", + "examine": "The cape worn by master summoners.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{23,99}", "shop_price": "99000", - "examine": "The cape worn by master summoners.", - "durability": null, - "name": "Summoning cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "12169", - "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { - "requirements": "{23,99}", - "durability": null, + "id": "12170", "name": "Summoning cape(t)", "archery_ticket_price": "0", - "id": "12170", "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", - "equipment_slot": "1" + "durability": null, + "equipment_slot": "1", + "requirements": "{23,99}" }, { + "id": "12171", + "name": "Summoning hood", + "examine": "Summoning skillcape hood.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{23,99}", "shop_price": "99000", - "examine": "Summoning skillcape hood.", - "durability": null, - "name": "Summoning hood", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "12171", - "equipment_slot": "0" + "weight": "0.4" }, { - "ge_buy_limit": "10000", + "id": "12172", + "name": "Clean spirit weed", "examine": "A fresh herb.", - "grand_exchange_price": "3597", - "durability": null, - "name": "Clean spirit weed", - "tradeable": "true", - "weight": "1", "archery_ticket_price": "0", - "id": "12172" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true", + "weight": "1" }, { - "ge_buy_limit": "10000", - "grand_exchange_price": "3597", - "durability": null, + "id": "12173", "name": "Clean spirit weed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12173" + "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" }, { - "requirements": "{15,35}", - "ge_buy_limit": "10000", + "id": "12174", + "name": "Grimy spirit weed", "examine": "I need to clean this herb before I can use it.", - "grand_exchange_price": "3634", - "durability": null, - "name": "Grimy spirit weed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12174" - }, - { + "durability": null, "ge_buy_limit": "10000", - "grand_exchange_price": "3634", - "durability": null, - "name": "Grimy spirit weed", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12175" + "requirements": "{15,35}", + "tradeable": "true" }, { - "requirements": "{19,36}", - "ge_buy_limit": "100", - "examine": "A seed for spirit weed.", - "grand_exchange_price": "698", + "id": "12175", + "name": "Grimy spirit weed", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10000", + "tradeable": "true" + }, + { + "id": "12176", "name": "Spirit weed seed", - "tradeable": "true", + "examine": "A seed for spirit weed.", "archery_ticket_price": "0", - "id": "12176" + "durability": null, + "ge_buy_limit": "100", + "requirements": "{19,36}", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "12181", + "name": "Spirit weed potion(unf)", "examine": "I need another ingredient to finish this spirit weed potion.", - "grand_exchange_price": "2963", - "durability": null, - "name": "Spirit weed potion(unf)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12181" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "2963", - "durability": null, + "tradeable": "true" + }, + { + "id": "12182", "name": "Spirit weed potion(unf)", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12182" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "25", - "ge_buy_limit": "10000", - "examine": "Shards of an obelisk.", - "grand_exchange_price": "24", - "durability": null, + "id": "12183", "name": "Spirit shards", - "tradeable": "true", + "examine": "Shards of an obelisk.", "archery_ticket_price": "0", - "id": "12183" + "durability": null, + "ge_buy_limit": "10000", + "shop_price": "25", + "tradeable": "true" }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12184", "name": "Gecko", + "examine": "How cute!", "archery_ticket_price": "0", - "id": "12184" + "durability": null }, { - "examine": "A fantastic saradomin owl.", - "durability": null, + "id": "12185", "name": "Saradomin owl", + "examine": "A fantastic saradomin owl.", "archery_ticket_price": "0", - "id": "12185" + "durability": null }, { - "examine": "A stately zamorak hawk.", - "durability": null, + "id": "12186", "name": "Zamorak hawk", + "examine": "A stately zamorak hawk.", "archery_ticket_price": "0", - "id": "12186" + "durability": null }, { - "examine": "An impressive Guthix raptor.", - "durability": null, + "id": "12187", "name": "Guthix raptor", + "examine": "An impressive Guthix raptor.", "archery_ticket_price": "0", - "id": "12187" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12190", "name": "Vulture", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12190" + "durability": null }, { - "examine": "It's lively and energetic.", - "durability": null, + "id": "12191", "name": "Terrier puppy", + "examine": "It's lively and energetic.", "archery_ticket_price": "0", - "id": "12191" + "durability": null }, { - "examine": "This is one fast little pooch.", - "durability": null, + "id": "12192", "name": "Greyhound puppy", + "examine": "This is one fast little pooch.", "archery_ticket_price": "0", - "id": "12192" + "durability": null }, { - "examine": "Soft but strong... and cute.", - "durability": null, + "id": "12193", "name": "Labrador puppy", + "examine": "Soft but strong... and cute.", "archery_ticket_price": "0", - "id": "12193" + "durability": null }, { - "examine": "Now, if only I could find another hundred...", - "durability": null, + "id": "12194", "name": "Dalmatian puppy", + "examine": "Now, if only I could find another hundred...", "archery_ticket_price": "0", - "id": "12194" + "durability": null }, { - "examine": "This little puppy is very quiet. (Puppy)Come by! Come by! (Adult)", - "durability": null, + "id": "12195", "name": "Sheepdog puppy", + "examine": "This little puppy is very quiet. (Puppy)Come by! Come by! (Adult)", "archery_ticket_price": "0", - "id": "12195" + "durability": null }, { - "examine": "One proud little puppy. (Puppy)Looks like it's chewing a wasp. (Adult)", - "durability": null, + "id": "12196", "name": "Bulldog puppy", + "examine": "One proud little puppy. (Puppy)Looks like it's chewing a wasp. (Adult)", "archery_ticket_price": "0", - "id": "12196" + "durability": null }, { - "examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.", - "durability": null, + "id": "12197", "name": "Dragon hatchling", + "examine": "A hatchling green dragon.", "archery_ticket_price": "0", - "id": "12197" + "durability": null }, { - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12198", "name": "Baby giant crab", + "examine": "Little Nipper.", "archery_ticket_price": "0", - "id": "12198" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12199", "name": "Baby raccoon", + "examine": "A stripy little baby raccoon.", "archery_ticket_price": "0", - "id": "12199" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12200", "name": "Squirrel", + "examine": "An experienced nut-thief.", "archery_ticket_price": "0", - "id": "12200" + "durability": null }, { - "examine": "It's a colour-coordinated lizard!", - "durability": null, + "id": "12203", "name": "Chameleon", + "examine": "It's a colour-coordinated lizard!", "archery_ticket_price": "0", - "id": "12203" + "durability": null }, { + "id": "12204", + "name": "Antlers", + "examine": "Doors could be a problem, wearing these...", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "requirements": "{23,10}", "shop_price": "100", + "tradeable": "true", + "weight": "1" + }, + { + "id": "12205", + "name": "Antlers", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12206", + "name": "Antlers (charged)", "examine": "Doors could be a problem, wearing these...", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,8,0,0,0,0", "durability": null, - "weight": "1", "equipment_slot": "0", - "grand_exchange_price": "40", - "name": "Antlers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12204", - "bonuses": "0,0,0,0,0,0,0,0,0,0,8,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "40", - "durability": null, - "name": "Antlers", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12205" - }, - { "remove_head": "true", "shop_price": "100", - "examine": "Doors could be a problem, wearing these...", - "grand_exchange_price": "50", - "durability": null, - "name": "Antlers (charged)", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12206", - "bonuses": "0,0,0,0,0,0,0,0,0,0,8,0,0,0,0", - "equipment_slot": "0" + "weight": "1" }, { + "id": "12207", + "name": "Lizard skull", + "examine": "It's a little smelly in there.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,1,2,3,4,2,3,12,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_beard": "true", "remove_head": "true", "requirements": "{23,30}", "shop_price": "200", + "tradeable": "true", + "weight": "3" + }, + { + "id": "12208", + "name": "Lizard skull", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12209", + "name": "Lizard skull (charged)", "examine": "It's a little smelly in there.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,1,2,3,4,2,3,12,0,0,0,0", "durability": null, - "weight": "3", - "remove_beard": "true", "equipment_slot": "0", - "grand_exchange_price": "254", - "name": "Lizard skull", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12207", - "bonuses": "0,0,0,0,1,2,3,4,2,3,12,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "254", - "durability": null, - "name": "Lizard skull", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12208" - }, - { + "remove_beard": "true", "remove_head": "true", "shop_price": "200", - "examine": "It's a little smelly in there.", - "durability": null, - "weight": "3", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "211", - "name": "Lizard skull (charged)", "tradeable": "true", - "archery_ticket_price": "0", - "id": "12209", - "bonuses": "0,0,0,0,1,2,3,4,2,3,12,0,0,0,0" + "weight": "3" }, { - "requirements": "{4,50}-{23,20}", - "ge_buy_limit": "100", - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "234", - "durability": null, - "name": "Feather headdress", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "12210", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "234", - "durability": null, "name": "Feather headdress", - "tradeable": "true", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", "archery_ticket_price": "0", - "id": "12211" + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "requirements": "{4,50}-{23,20}", + "tradeable": "true", + "weight": "2" }, { - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "107", - "durability": null, - "name": "Feather headdress (charged)", - "tradeable": "true", - "weight": "2", + "id": "12211", + "name": "Feather headdress", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12212", + "name": "Feather headdress (charged)", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "archery_ticket_price": "0", "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "2" }, { - "requirements": "{4,50}-{23,20}", - "ge_buy_limit": "100", - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "662", - "durability": null, - "name": "Feather headdress", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "12213", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "662", - "durability": null, "name": "Feather headdress", - "tradeable": "true", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", "archery_ticket_price": "0", - "id": "12214" + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "requirements": "{4,50}-{23,20}", + "tradeable": "true", + "weight": "2" }, { - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "107", - "durability": null, - "name": "Feather headdress (charged)", - "tradeable": "true", - "weight": "2", + "id": "12214", + "name": "Feather headdress", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12215", + "name": "Feather headdress (charged)", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "archery_ticket_price": "0", "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "2" }, { - "requirements": "{4,50}-{23,20}", - "ge_buy_limit": "100", - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "90", - "durability": null, - "name": "Feather headdress", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "12216", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "90", - "durability": null, "name": "Feather headdress", - "tradeable": "true", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", "archery_ticket_price": "0", - "id": "12217" + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "requirements": "{4,50}-{23,20}", + "tradeable": "true", + "weight": "2" }, { - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "107", - "durability": null, - "name": "Feather headdress (charged)", - "tradeable": "true", - "weight": "2", + "id": "12217", + "name": "Feather headdress", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12218", + "name": "Feather headdress (charged)", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "archery_ticket_price": "0", "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "tradeable": "true", + "weight": "2" }, { - "requirements": "{4,50}-{23,20}", - "ge_buy_limit": "100", - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "107", - "durability": null, - "name": "Feather headdress", - "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", "id": "12219", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "107", - "durability": null, "name": "Feather headdress", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12220" - }, - { "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "107", - "durability": null, - "name": "Feather headdress (charged)", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "12221", "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" - }, - { + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "requirements": "{4,50}-{23,20}", - "ge_buy_limit": "100", - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "211", - "durability": null, - "name": "Feather headdress", "tradeable": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12222", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "211", - "durability": null, + "id": "12220", "name": "Feather headdress", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12223" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "examine": "It's fun to go to the O-B-E-L-I-S-K!", - "grand_exchange_price": "107", - "durability": null, + "id": "12221", "name": "Feather headdress (charged)", - "tradeable": "true", - "weight": "2", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", "archery_ticket_price": "0", - "id": "12224", "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", - "equipment_slot": "0" - }, - { "durability": null, - "name": "Pouch", + "equipment_slot": "0", "tradeable": "true", - "archery_ticket_price": "0", - "id": "12294" + "weight": "2" }, { + "id": "12222", + "name": "Feather headdress", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", "durability": null, - "name": "Pouch", + "equipment_slot": "0", + "ge_buy_limit": "100", + "requirements": "{4,50}-{23,20}", "tradeable": "true", - "archery_ticket_price": "0", - "id": "12296" + "weight": "2" }, { + "id": "12223", + "name": "Feather headdress", + "archery_ticket_price": "0", "durability": null, - "name": "Pouch", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12224", + "name": "Feather headdress (charged)", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "durability": null, + "equipment_slot": "0", "tradeable": "true", - "archery_ticket_price": "0", - "id": "12298" + "weight": "2" }, { - "durability": null, + "id": "12294", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12300" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12296", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12302" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12298", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12304" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12300", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12306" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12302", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12308" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12304", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12310" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12306", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12312" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12308", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12314" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12310", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12316" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12312", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12318" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12314", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12320" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12316", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12322" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12318", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12324" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12320", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12326" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12322", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12328" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12324", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12330" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12326", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12332" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12328", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12334" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12330", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12336" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12332", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12338" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12334", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12340" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12336", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12342" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12338", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12344" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12340", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12346" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12342", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12348" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12344", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12350" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12346", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12352" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12348", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12354" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12350", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12356" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12352", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12358" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12354", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12360" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12356", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12362" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12358", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12364" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12360", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12366" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12362", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12368" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12364", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12370" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12366", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12372" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12368", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12374" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12370", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12376" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12372", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12378" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12374", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12380" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12376", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12382" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12378", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12384" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12380", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12386" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12382", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12388" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12384", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12390" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12386", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12392" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12388", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12394" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12390", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12396" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12392", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12398" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12394", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12400" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12396", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12402" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12398", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12404" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12400", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12406" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12402", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12408" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12404", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12410" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12406", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12412" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12408", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12414" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12410", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12416" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12412", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12418" + "durability": null, + "tradeable": "true" }, { - "durability": null, + "id": "12414", "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12420" + "durability": null, + "tradeable": "true" }, { - "requirements": "{23,41}", - "ge_buy_limit": "5000", - "grand_exchange_price": "96", - "examine": "A scroll for a macaw familiar.", + "id": "12416", + "name": "Pouch", + "archery_ticket_price": "0", "durability": null, + "tradeable": "true" + }, + { + "id": "12418", + "name": "Pouch", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "12420", + "name": "Pouch", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "12422", "name": "Herbcall scroll", - "tradeable": "true", + "examine": "A scroll for a macaw familiar.", "archery_ticket_price": "0", - "id": "12422" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,41}", + "tradeable": "true" }, { - "requirements": "{23,69}", - "ge_buy_limit": "5000", - "grand_exchange_price": "258", - "examine": "A scroll for a fruit bat familiar.", - "durability": null, + "id": "12423", "name": "Fruitfall scroll", - "tradeable": "true", + "examine": "A scroll for a fruit bat familiar.", "archery_ticket_price": "0", - "id": "12423" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,69}", + "tradeable": "true" }, { - "requirements": "{23,56}", - "ge_buy_limit": "5000", - "grand_exchange_price": "146", - "examine": "A scroll for an ibis familiar.", - "durability": null, + "id": "12424", "name": "Fish rain scroll", - "tradeable": "true", + "examine": "A scroll for an ibis familiar.", "archery_ticket_price": "0", - "id": "12424" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "7", - "examine": "A scroll for a spirit wolf familiar.", - "durability": null, - "name": "Howl scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12425" - }, - { - "requirements": "{23,47}", - "ge_buy_limit": "5000", - "grand_exchange_price": "97", - "examine": "A scroll for a magpie familiar.", - "durability": null, - "name": "Thieving fingers scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12426" - }, - { - "requirements": "{23,62}", - "ge_buy_limit": "5000", - "grand_exchange_price": "533", - "examine": "A scroll for an abyssal lurker familiar.", - "durability": null, - "name": "Abyssal stealth scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12427" - }, - { - "requirements": "{23,10}", - "ge_buy_limit": "5000", - "grand_exchange_price": "237", - "examine": "A scroll for a spirit spider familiar.", - "durability": null, - "name": "Egg spawn scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12428" - }, - { - "requirements": "{23,33}", - "ge_buy_limit": "5000", - "grand_exchange_price": "97", - "examine": "A scroll for a beaver familiar.", - "durability": null, - "name": "Multichop scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12429" - }, - { - "requirements": "{23,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "121", - "examine": "A scroll for an albino rat familiar.", - "durability": null, - "name": "Cheese feast scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12430" - }, - { - "requirements": "{23,40}", - "ge_buy_limit": "5000", - "grand_exchange_price": "39", - "examine": "A scroll for a bull ant familiar.", - "durability": null, - "name": "Unburden scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12431" - }, - { - "requirements": "{23,19}", - "ge_buy_limit": "5000", - "grand_exchange_price": "72", - "examine": "A scroll for a spirit scorpion familiar.", - "durability": null, - "name": "Venom shot scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12432" - }, - { - "requirements": "{23,32}", - "ge_buy_limit": "5000", - "grand_exchange_price": "99", - "examine": "A scroll for a honey badger familiar.", - "durability": null, - "name": "Insane ferocity scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12433" - }, - { - "requirements": "{23,88}", - "ge_buy_limit": "5000", - "grand_exchange_price": "299", - "examine": "A scroll for a unicorn stallion familiar.", - "durability": null, - "name": "Healing aura scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12434" - }, - { - "requirements": "{23,96}", - "ge_buy_limit": "5000", - "grand_exchange_price": "428", - "examine": "A scroll for a pack yak familiar.", - "durability": null, - "name": "Winter storage scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12435" - }, - { - "requirements": "{23,63}", - "ge_buy_limit": "5000", - "grand_exchange_price": "223", - "examine": "A scroll for a spirit cobra familiar.", - "durability": null, - "name": "Oph. incubation scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12436" - }, - { - "requirements": "{23,92}", - "ge_buy_limit": "5000", - "grand_exchange_price": "419", - "examine": "A scroll for a wolpertinger familiar.", - "durability": null, - "name": "Magic focus scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12437" - }, - { - "requirements": "{23,68}", - "ge_buy_limit": "5000", - "grand_exchange_price": "220", - "examine": "A scroll for a bunyip familiar.", - "durability": null, - "name": "Swallow whole scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12438" - }, - { - "requirements": "{23,67}", - "ge_buy_limit": "5000", - "grand_exchange_price": "269", - "examine": "A scroll for a war tortoise familiar.", - "durability": null, - "name": "Testudo scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12439" - }, - { - "requirements": "{23,28}", - "ge_buy_limit": "5000", - "grand_exchange_price": "47", - "examine": "A scroll for a compost mound familiar.", - "durability": null, - "name": "Generate compost scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12440" - }, - { - "requirements": "{23,52}", - "ge_buy_limit": "5000", - "grand_exchange_price": "35", - "examine": "A scroll for a spirit terrorbird familiar.", - "durability": null, - "name": "Tireless run scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12441" - }, - { - "requirements": "{23,80}", - "ge_buy_limit": "5000", - "grand_exchange_price": "174", - "examine": "A scroll for a hydra familiar.", - "durability": null, - "name": "Regrowth scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12442" - }, - { - "requirements": "{23,34}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1118", - "examine": "A scroll for a Pest Control familiar.", - "durability": null, - "name": "Call to arms scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12443" - }, - { - "requirements": "{23,49}", - "ge_buy_limit": "5000", - "grand_exchange_price": "148", - "examine": "A scroll for a bloated leech familiar.", - "durability": null, - "name": "Blood drain scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12444" - }, - { - "requirements": "{23,4}", - "ge_buy_limit": "5000", - "grand_exchange_price": "7", - "examine": "A scroll for a dreadfowl familiar.", - "durability": null, - "name": "Dreadfowl strike scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12445" - }, - { - "requirements": "{23,25}", - "ge_buy_limit": "5000", - "grand_exchange_price": "122", - "examine": "A scroll for a spirit kalphite familiar.", - "durability": null, - "name": "Sandstorm scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12446" - }, - { - "requirements": "{23,31}", - "ge_buy_limit": "1000", - "grand_exchange_price": "98", - "examine": "A scroll for a vampire bat familiar.", - "durability": null, - "name": "Vampire touch scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12447" - }, - { - "requirements": "{23,42}", - "ge_buy_limit": "5000", - "grand_exchange_price": "123", - "examine": "A scroll for an evil turnip familiar.", - "durability": null, - "name": "Evil flames scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12448" - }, - { - "requirements": "{23,74}", - "ge_buy_limit": "5000", - "grand_exchange_price": "219", - "examine": "A scroll for a granite lobster familiar.", - "durability": null, - "name": "Crushing claw scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12449" - }, - { - "requirements": "{23,75}", - "ge_buy_limit": "5000", - "grand_exchange_price": "221", - "examine": "A scroll for a praying mantis familiar.", - "durability": null, - "name": "Mantis strike scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12450" - }, - { - "requirements": "{23,71}", - "ge_buy_limit": "5000", - "grand_exchange_price": "12", - "examine": "A scroll for an arctic bear familiar.", - "durability": null, - "name": "Arctic blast scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12451" - }, - { - "requirements": "{23,66}", - "ge_buy_limit": "5000", - "grand_exchange_price": "10", - "examine": "A scroll for a barker toad familiar.", - "durability": null, - "name": "Toad bark scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12452" - }, - { - "requirements": "{23,55}", - "ge_buy_limit": "5000", - "grand_exchange_price": "202", - "examine": "A scroll for a spirit jelly familiar.", - "durability": null, - "name": "Dissolve scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12453" - }, - { - "requirements": "{23,54}", - "ge_buy_limit": "5000", - "grand_exchange_price": "163", - "examine": "A scroll for an abyssal parasite familiar.", - "durability": null, - "name": "Abyssal drain scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12454" - }, - { - "requirements": "{23,58}", - "ge_buy_limit": "5000", - "grand_exchange_price": "198", - "examine": "A scroll for a karamthulhu overlord familiar.", - "durability": null, - "name": "Doomsphere scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12455" - }, - { - "requirements": "{23,83}", - "ge_buy_limit": "5000", - "grand_exchange_price": "9", - "examine": "A scroll for a spirit dagannoth familiar.", - "durability": null, - "name": "Spike shot scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12456" - }, - { - "requirements": "{23,78}", - "ge_buy_limit": "5000", - "grand_exchange_price": "146", - "examine": "A scroll for a giant ent familiar.", - "durability": null, - "name": "Acorn missile scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12457" - }, - { - "requirements": "{23,43}", - "ge_buy_limit": "5000", - "grand_exchange_price": "97", - "examine": "A scroll for a cockatrice variant familiar.", - "durability": null, - "name": "Petrifying gaze scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12458" - }, - { - "requirements": "{23,13}", - "ge_buy_limit": "5000", - "grand_exchange_price": "10", - "examine": "A scroll for a thorny snail familiar.", - "durability": null, - "name": "Slime spray scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12459" - }, - { - "requirements": "{23,18}", - "ge_buy_limit": "5000", - "grand_exchange_price": "47", - "examine": "A scroll for a desert wyrm familiar.", - "durability": null, - "name": "Electric lash scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12460" - }, - { - "requirements": "{23,36}", - "ge_buy_limit": "5000", - "grand_exchange_price": "135", - "examine": "A scroll for a bronze minotaur familiar.", - "durability": null, - "name": "Bronze bull rush scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12461" - }, - { - "requirements": "{23,46}", - "ge_buy_limit": "5000", - "grand_exchange_price": "180", - "examine": "A scroll for an iron minotaur familiar.", - "durability": null, - "name": "Iron bull rush scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12462" - }, - { "requirements": "{23,56}", - "ge_buy_limit": "5000", - "grand_exchange_price": "182", - "examine": "A scroll for a steel minotaur familiar.", - "durability": null, - "name": "Steel bull rush scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12463" + "tradeable": "true" }, { + "id": "12425", + "name": "Howl scroll", + "examine": "A scroll for a spirit wolf familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12426", + "name": "Thieving fingers scroll", + "examine": "A scroll for a magpie familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,47}", + "tradeable": "true" + }, + { + "id": "12427", + "name": "Abyssal stealth scroll", + "examine": "A scroll for an abyssal lurker familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,62}", + "tradeable": "true" + }, + { + "id": "12428", + "name": "Egg spawn scroll", + "examine": "A scroll for a spirit spider familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,10}", + "tradeable": "true" + }, + { + "id": "12429", + "name": "Multichop scroll", + "examine": "A scroll for a beaver familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,33}", + "tradeable": "true" + }, + { + "id": "12430", + "name": "Cheese feast scroll", + "examine": "A scroll for an albino rat familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,23}", + "tradeable": "true" + }, + { + "id": "12431", + "name": "Unburden scroll", + "examine": "A scroll for a bull ant familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,40}", + "tradeable": "true" + }, + { + "id": "12432", + "name": "Venom shot scroll", + "examine": "A scroll for a spirit scorpion familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,19}", + "tradeable": "true" + }, + { + "id": "12433", + "name": "Insane ferocity scroll", + "examine": "A scroll for a honey badger familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,32}", + "tradeable": "true" + }, + { + "id": "12434", + "name": "Healing aura scroll", + "examine": "A scroll for a unicorn stallion familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,88}", + "tradeable": "true" + }, + { + "id": "12435", + "name": "Winter storage scroll", + "examine": "A scroll for a pack yak familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,96}", + "tradeable": "true" + }, + { + "id": "12436", + "name": "Oph. incubation scroll", + "examine": "A scroll for a spirit cobra familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,63}", + "tradeable": "true" + }, + { + "id": "12437", + "name": "Magic focus scroll", + "examine": "A scroll for a wolpertinger familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,92}", + "tradeable": "true" + }, + { + "id": "12438", + "name": "Swallow whole scroll", + "examine": "A scroll for a bunyip familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,68}", + "tradeable": "true" + }, + { + "id": "12439", + "name": "Testudo scroll", + "examine": "A scroll for a war tortoise familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,67}", + "tradeable": "true" + }, + { + "id": "12440", + "name": "Generate compost scroll", + "examine": "A scroll for a compost mound familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,28}", + "tradeable": "true" + }, + { + "id": "12441", + "name": "Tireless run scroll", + "examine": "A scroll for a spirit terrorbird familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,52}", + "tradeable": "true" + }, + { + "id": "12442", + "name": "Regrowth scroll", + "examine": "A scroll for a hydra familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,80}", + "tradeable": "true" + }, + { + "id": "12443", + "name": "Call to arms scroll", + "examine": "A scroll for a Pest Control familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,34}", + "tradeable": "true" + }, + { + "id": "12444", + "name": "Blood drain scroll", + "examine": "A scroll for a bloated leech familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,49}", + "tradeable": "true" + }, + { + "id": "12445", + "name": "Dreadfowl strike scroll", + "examine": "A scroll for a dreadfowl familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,4}", + "tradeable": "true" + }, + { + "id": "12446", + "name": "Sandstorm scroll", + "examine": "A scroll for a spirit kalphite familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,25}", + "tradeable": "true" + }, + { + "id": "12447", + "name": "Vampire touch scroll", + "examine": "A scroll for a vampire bat familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "requirements": "{23,31}", + "tradeable": "true" + }, + { + "id": "12448", + "name": "Evil flames scroll", + "examine": "A scroll for an evil turnip familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,42}", + "tradeable": "true" + }, + { + "id": "12449", + "name": "Crushing claw scroll", + "examine": "A scroll for a granite lobster familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,74}", + "tradeable": "true" + }, + { + "id": "12450", + "name": "Mantis strike scroll", + "examine": "A scroll for a praying mantis familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,75}", + "tradeable": "true" + }, + { + "id": "12451", + "name": "Arctic blast scroll", + "examine": "A scroll for an arctic bear familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,71}", + "tradeable": "true" + }, + { + "id": "12452", + "name": "Toad bark scroll", + "examine": "A scroll for a barker toad familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", "requirements": "{23,66}", - "ge_buy_limit": "5000", - "grand_exchange_price": "198", - "examine": "A scroll for a mithril minotaur familiar.", + "tradeable": "true" + }, + { + "id": "12453", + "name": "Dissolve scroll", + "examine": "A scroll for a spirit jelly familiar.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,55}", + "tradeable": "true" + }, + { + "id": "12454", + "name": "Abyssal drain scroll", + "examine": "A scroll for an abyssal parasite familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,54}", + "tradeable": "true" + }, + { + "id": "12455", + "name": "Doomsphere scroll", + "examine": "A scroll for a karamthulhu overlord familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,58}", + "tradeable": "true" + }, + { + "id": "12456", + "name": "Spike shot scroll", + "examine": "A scroll for a spirit dagannoth familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,83}", + "tradeable": "true" + }, + { + "id": "12457", + "name": "Acorn missile scroll", + "examine": "A scroll for a giant ent familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,78}", + "tradeable": "true" + }, + { + "id": "12458", + "name": "Petrifying gaze scroll", + "examine": "A scroll for a cockatrice variant familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,43}", + "tradeable": "true" + }, + { + "id": "12459", + "name": "Slime spray scroll", + "examine": "A scroll for a thorny snail familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,13}", + "tradeable": "true" + }, + { + "id": "12460", + "name": "Electric lash scroll", + "examine": "A scroll for a desert wyrm familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,18}", + "tradeable": "true" + }, + { + "id": "12461", + "name": "Bronze bull rush scroll", + "examine": "A scroll for a bronze minotaur familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,36}", + "tradeable": "true" + }, + { + "id": "12462", + "name": "Iron bull rush scroll", + "examine": "A scroll for an iron minotaur familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,46}", + "tradeable": "true" + }, + { + "id": "12463", + "name": "Steel bull rush scroll", + "examine": "A scroll for a steel minotaur familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,56}", + "tradeable": "true" + }, + { + "id": "12464", "name": "Mith bull rush scroll", - "tradeable": "true", + "examine": "A scroll for a mithril minotaur familiar.", "archery_ticket_price": "0", - "id": "12464" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,66}", + "tradeable": "true" }, { - "requirements": "{23,76}", - "ge_buy_limit": "5000", - "grand_exchange_price": "203", - "examine": "A scroll for an adamant minotaur familiar.", - "durability": null, + "id": "12465", "name": "Addy bull rush scroll", - "tradeable": "true", + "examine": "A scroll for an adamant minotaur familiar.", "archery_ticket_price": "0", - "id": "12465" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,76}", + "tradeable": "true" }, { - "requirements": "{23,86}", - "ge_buy_limit": "5000", - "grand_exchange_price": "67", - "examine": "A scroll for a rune minotaur familiar.", - "durability": null, + "id": "12466", "name": "Rune bull rush scroll", - "tradeable": "true", + "examine": "A scroll for a rune minotaur familiar.", "archery_ticket_price": "0", - "id": "12466" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,86}", + "tradeable": "true" }, { - "requirements": "{23,64}", - "ge_buy_limit": "5000", - "grand_exchange_price": "171", - "examine": "A scroll for a stranger plant familiar.", - "durability": null, + "id": "12467", "name": "Poisonous blast scroll", - "tradeable": "true", + "examine": "A scroll for a stranger plant familiar.", "archery_ticket_price": "0", - "id": "12467" - }, - { - "requirements": "{23,61}", + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "170", - "examine": "A scroll for a smoke devil familiar.", - "durability": null, + "requirements": "{23,64}", + "tradeable": "true" + }, + { + "id": "12468", "name": "Dust cloud scroll", - "tradeable": "true", + "examine": "A scroll for a smoke devil familiar.", "archery_ticket_price": "0", - "id": "12468" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,61}", + "tradeable": "true" }, { - "examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.", - "durability": null, + "id": "12469", + "name": "Dragon hatchling", + "examine": "A hatchling red dragon.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12471", "name": "Hatchling dragon", + "examine": "A hatchling blue dragon.", "archery_ticket_price": "0", - "id": "12469" + "durability": null }, { - "examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.", - "durability": null, + "id": "12473", "name": "Hatchling dragon", + "examine": "A hatchling green dragon.", "archery_ticket_price": "0", - "id": "12471" + "durability": null }, { - "examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.", - "durability": null, + "id": "12475", "name": "Hatchling dragon", + "examine": "A hatchling black dragon.", "archery_ticket_price": "0", - "id": "12473" + "durability": null }, { - "examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.", - "durability": null, - "name": "Hatchling dragon", - "archery_ticket_price": "0", - "id": "12475" - }, - { - "examine": "This will hatch into a mighty dragon.", - "durability": null, + "id": "12477", "name": "Red dragon egg", - "tradeable": "false", - "destroy": "false", - "weight": "1", + "examine": "This will hatch into a mighty dragon.", "archery_ticket_price": "0", - "id": "12477" + "destroy": "false", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "This will hatch into a mighty dragon.", - "durability": null, + "id": "12478", "name": "Blue dragon egg", - "tradeable": "false", - "destroy": "false", - "weight": "1", + "examine": "This will hatch into a mighty dragon.", "archery_ticket_price": "0", - "id": "12478" + "destroy": "false", + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "This will hatch into a mighty dragon.", - "durability": null, + "id": "12479", "name": "Green dragon egg", - "tradeable": "false", - "destroy": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "12479" - }, - { "examine": "This will hatch into a mighty dragon.", - "durability": null, - "name": "Black dragon egg", - "tradeable": "false", + "archery_ticket_price": "0", "destroy": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "12480" + "durability": null, + "tradeable": "false", + "weight": "1" }, { - "examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.", + "id": "12480", + "name": "Black dragon egg", + "examine": "This will hatch into a mighty dragon.", + "archery_ticket_price": "0", + "destroy": "false", "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "12481", "name": "Baby penguin", + "examine": "Can't fly and can barely walk, but adorable nonetheless.", "archery_ticket_price": "0", - "id": "12481" + "durability": null }, { - "examine": "I can hatch this in an Incubator.", - "durability": null, + "id": "12482", + "name": "Penguin", + "examine": "Emperor of all he surveys." + }, + { + "id": "12483", "name": "Penguin egg", + "examine": "I can hatch this in an incubator.", "archery_ticket_price": "0", - "id": "12483" + "durability": null, + "tradeable": "false" }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12484", "name": "Raven chick", - "archery_ticket_price": "0", - "id": "12484" - }, - { "examine": "Chick: A raven chick.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12485", "name": "Raven", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12485" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12486", "name": "Baby raccoon", + "examine": "A stripy little baby raccoon.", "archery_ticket_price": "0", - "id": "12486" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12487", "name": "Raccoon", + "examine": "He can run with us.", "archery_ticket_price": "0", - "id": "12487" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12488", "name": "Baby gecko", + "examine": "It's so adorably tiny!", "archery_ticket_price": "0", - "id": "12488" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12489", "name": "Gecko", + "examine": "How cute!", "archery_ticket_price": "0", - "id": "12489" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12490", "name": "Baby squirrel", + "examine": "A tiny nut-thief.", "archery_ticket_price": "0", - "id": "12490" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12491", "name": "Squirrel", + "examine": "An experienced nut-thief.", "archery_ticket_price": "0", - "id": "12491" + "durability": null }, { - "examine": "It's a colour-coordinated lizard!", - "durability": null, + "id": "12492", "name": "Baby chameleon", - "archery_ticket_price": "0", - "id": "12492" - }, - { "examine": "It's a colour-coordinated lizard!", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12493", "name": "Chameleon", + "examine": "It's a colour-coordinated lizard!", "archery_ticket_price": "0", - "id": "12493" + "durability": null }, { - "examine": "A lizard's egg.", - "durability": null, + "id": "12494", "name": "Chameleon egg", - "weight": "1", - "archery_ticket_price": "0", - "id": "12494" - }, - { "examine": "A lizard's egg.", - "durability": null, - "name": "Chameleon egg", - "weight": "1", "archery_ticket_price": "0", - "id": "12495" + "durability": null, + "weight": "1" }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "id": "12495", + "name": "Chameleon egg", + "examine": "A lizard's egg.", + "archery_ticket_price": "0", "durability": null, + "weight": "1" + }, + { + "id": "12496", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12496" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12497", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12498", "name": "Vulture chick", - "archery_ticket_price": "0", - "id": "12498" - }, - { "examine": "If you see them circling: run.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12499", "name": "Vulture", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12499" + "durability": null }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12500", "name": "Baby giant crab", - "archery_ticket_price": "0", - "id": "12500" - }, - { - "requirements": "{23,40}", "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{23,40}" + }, + { + "id": "12501", "name": "Giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12501" + "durability": null, + "requirements": "{23,40}" }, { - "examine": "Apparently, this token is worth one baby giant crab to someone called Nung.", - "durability": null, + "id": "12502", "name": "Crunchy claw token", + "examine": "Apparently, this token is worth one baby giant crab to someone called Nung.", "archery_ticket_price": "0", - "id": "12502" + "durability": null }, { - "examine": "A fluffy chick.", - "durability": null, + "id": "12503", "name": "Saradomin chick", + "examine": "A fluffy chick.", "archery_ticket_price": "0", - "id": "12503" + "durability": null }, { - "examine": "Lovely blue plumage.", - "durability": null, + "id": "12504", "name": "Saradomin bird", + "examine": "Lovely blue plumage.", "archery_ticket_price": "0", - "id": "12504" + "durability": null }, { - "examine": "A fantastic saradomin owl.", - "durability": null, + "id": "12505", "name": "Saradomin owl", + "examine": "A fantastic saradomin owl.", "archery_ticket_price": "0", - "id": "12505" + "durability": null }, { - "examine": "A fluffy chick.", - "durability": null, + "id": "12506", "name": "Zamorak chick", - "archery_ticket_price": "0", - "id": "12506" - }, - { - "examine": "Lovely red plumage.", - "durability": null, - "name": "Zamorak bird", - "archery_ticket_price": "0", - "id": "12507" - }, - { - "examine": "A stately zamorak hawk.", - "durability": null, - "name": "Zamorak hawk", - "archery_ticket_price": "0", - "id": "12508" - }, - { "examine": "A fluffy chick.", - "durability": null, + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12507", + "name": "Zamorak bird", + "examine": "Lovely red plumage.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12508", + "name": "Zamorak hawk", + "examine": "A stately zamorak hawk.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12509", "name": "Guthix chick", + "examine": "A fluffy chick.", "archery_ticket_price": "0", - "id": "12509" + "durability": null }, { - "examine": "Lovely green plumage.", - "durability": null, + "id": "12510", "name": "Guthix bird", + "examine": "Lovely green plumage.", "archery_ticket_price": "0", - "id": "12510" + "durability": null }, { - "examine": "An impressive Guthix raptor.", - "durability": null, + "id": "12511", "name": "Guthix raptor", + "examine": "An impressive Guthix raptor.", "archery_ticket_price": "0", - "id": "12511" + "durability": null }, { - "requirements": "{4,23}", - "examine": "It's lively and energetic.", - "durability": null, + "id": "12512", "name": "Terrier puppy", - "archery_ticket_price": "0", - "id": "12512" - }, - { - "requirements": "{4,23}", "examine": "It's lively and energetic.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12513", "name": "Terrier", + "examine": "It's lively and energetic.", "archery_ticket_price": "0", - "id": "12513" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "This is one fast little pooch.", - "durability": null, + "id": "12514", "name": "Greyhound puppy", + "examine": "This is one fast little pooch.", "archery_ticket_price": "0", - "id": "12514" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "An aerodynamic doggy.", - "durability": null, + "id": "12515", "name": "Greyhound", + "examine": "An aerodynamic doggy.", "archery_ticket_price": "0", - "id": "12515" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Soft but strong... and cute.", - "durability": null, + "id": "12516", "name": "Labrador puppy", + "examine": "Soft but strong... and cute.", "archery_ticket_price": "0", - "id": "12516" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "My most faithful friend.", - "durability": null, + "id": "12517", "name": "Labrador", + "examine": "My most faithful friend.", "archery_ticket_price": "0", - "id": "12517" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Now, if only I could find another hundred...", - "durability": null, + "id": "12518", "name": "Dalmatian puppy", + "examine": "Now, if only I could find another hundred...", "archery_ticket_price": "0", - "id": "12518" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "A purebred doggy.", - "durability": null, + "id": "12519", "name": "Dalmatian", + "examine": "A purebred doggy.", "archery_ticket_price": "0", - "id": "12519" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "This little puppy is very quiet.", - "durability": null, + "id": "12520", "name": "Sheepdog puppy", + "examine": "This little puppy is very quiet.", "archery_ticket_price": "0", - "id": "12520" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Come by! Come by!", - "durability": null, + "id": "12521", "name": "Sheepdog", + "examine": "Come by! Come by!", "archery_ticket_price": "0", - "id": "12521" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "One proud little puppy.", - "durability": null, + "id": "12522", "name": "Bulldog puppy", + "examine": "One proud little puppy.", "archery_ticket_price": "0", - "id": "12522" - }, - { - "requirements": "{4,23}", - "examine": "Looks like it's chewing a wasp.", "durability": null, - "name": "Bulldog", - "archery_ticket_price": "0", - "id": "12523" + "requirements": "{4,23}" }, { + "id": "12523", + "name": "Bulldog", + "examine": "Looks like it's chewing a wasp.", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12524", + "name": "Summoning cape", + "examine": "The cape worn by master summoners.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "durability": null, + "equipment_slot": "1", "requirements": "{23,99}", "shop_price": "99000", - "examine": "The cape worn by master summoners.", - "durability": null, - "name": "Summoning cape", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "12524", - "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", - "equipment_slot": "1" + "weight": "0.4" }, { - "shop_price": "1", - "examine": "A charm used to summon familiars.", - "durability": null, + "id": "12527", "name": "Gold charm", - "tradeable": "false", + "examine": "A charm used to summon familiars.", "archery_ticket_price": "0", - "id": "12527" + "durability": null, + "shop_price": "1", + "tradeable": "false" }, { - "examine": "A key to Pikkupstix's trapdoor.", - "durability": null, + "id": "12528", "name": "Trapdoor key", + "examine": "A key to Pikkupstix's trapdoor.", "archery_ticket_price": "0", - "id": "12528" + "durability": null }, { - "shop_price": "25", - "examine": "Shards of an obelisk.", - "grand_exchange_price": "24", - "durability": null, + "id": "12530", "name": "Spirit shards", - "tradeable": "true", + "examine": "Shards of an obelisk.", "archery_ticket_price": "0", - "id": "12530" + "durability": null, + "shop_price": "25", + "tradeable": "true" }, { - "requirements": "{23,56}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1914", + "id": "12531", + "name": "Ibis pouch", "examine": "I can summon an ibis familiar with this.", - "durability": null, - "name": "Ibis pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12531" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,56}", + "tradeable": "true" }, { - "ge_buy_limit": "5000", - "grand_exchange_price": "1914", + "id": "12532", + "name": "Ibis pouch", "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ibis pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12532" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,16}", - "ge_buy_limit": "5000", - "grand_exchange_price": "7", - "examine": "A scroll for a granite crab familiar.", - "durability": null, + "id": "12533", "name": "Stony shell scroll", - "tradeable": "true", + "examine": "A scroll for a granite crab familiar.", "archery_ticket_price": "0", - "id": "12533" - }, - { - "ge_buy_limit": "1000", - "examine": "Meat from a creature that can be hunted in Isafdar.", - "grand_exchange_price": "7968", "durability": null, - "name": "Raw pawya meat", - "tradeable": "true", - "weight": "0.33", - "archery_ticket_price": "0", - "id": "12535" - }, - { - "ge_buy_limit": "1000", - "grand_exchange_price": "7968", - "durability": null, - "name": "Raw pawya meat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12536" - }, - { - "durability": null, - "name": "Picture", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12538" - }, - { "ge_buy_limit": "5000", - "examine": "Spikes from a grenwall.", - "grand_exchange_price": "1704", - "durability": null, - "name": "Grenwall spikes", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12539" + "requirements": "{23,16}", + "tradeable": "true" }, { + "id": "12535", + "name": "Raw pawya meat", + "examine": "Meat from a creature that can be hunted in Isafdar.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true", + "weight": "0.33" + }, + { + "id": "12536", + "name": "Raw pawya meat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" + }, + { + "id": "12538", "name": "Picture", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12545" + "durability": null, + "tradeable": "true" }, { - "examine": "A most unlikely creature.", + "id": "12539", + "name": "Grenwall spikes", + "examine": "Spikes from a grenwall.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12545", + "name": "Picture", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "12547", "name": "Platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12547" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12548", "name": "Platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12548" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12549", "name": "Platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12549" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12550", "name": "Platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12550" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12551", "name": "Baby platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12551" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12552", "name": "Baby platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12552" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12553", "name": "Baby platypus", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12553" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12554", "name": "Patrick", + "examine": "A most unlikely creature.", "archery_ticket_price": "0", - "id": "12554" + "durability": null }, { - "examine": "A most unlikely creature.", - "durability": null, + "id": "12555", "name": "Penelope", - "archery_ticket_price": "0", - "id": "12555" - }, - { - "examine": "I bet he can't wait until it's cooked.", - "durability": null, - "name": "Peter", - "archery_ticket_price": "0", - "id": "12556" - }, - { "examine": "A most unlikely creature.", - "durability": null, - "name": "Peanut", "archery_ticket_price": "0", - "id": "12557" + "durability": null }, { - "examine": "Marginally better than egg on your face.", - "durability": null, - "name": "Mud", + "id": "12556", + "name": "Peter", + "examine": "I bet he can't wait until it's cooked.", "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12557", + "name": "Peanut", + "examine": "A most unlikely creature.", + "archery_ticket_price": "0", + "durability": null + }, + { "id": "12558", + "name": "Mud", + "examine": "Marginally better than egg on your face.", + "archery_ticket_price": "0", + "durability": null, "equipment_slot": "0" }, { + "id": "12559", + "name": "Ogre wig", + "examine": "The height of style?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", "remove_head": "true", "shop_price": "50", - "ge_buy_limit": "100", - "examine": "The height of style?", - "grand_exchange_price": "1004", - "durability": null, - "name": "Ogre wig", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12559", - "equipment_slot": "0" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "1004", - "durability": null, + "id": "12560", "name": "Ogre wig", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12560" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "60", - "ge_buy_limit": "100", - "examine": "It's a little big on me.", - "grand_exchange_price": "197", - "durability": null, - "name": "Ogre kilt", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "12561", - "equipment_slot": "7" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "197", - "durability": null, "name": "Ogre kilt", - "tradeable": "true", + "examine": "It's a little big on me.", "archery_ticket_price": "0", - "id": "12562" + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "60", + "tradeable": "true", + "weight": "1" }, { + "id": "12562", + "name": "Ogre kilt", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12563", + "name": "Ogre top", + "examine": "It's a little big on me.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", "remove_sleeves": "true", "shop_price": "60", - "ge_buy_limit": "100", - "examine": "It's a little big on me.", - "grand_exchange_price": "536", - "durability": null, - "name": "Ogre top", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12563", - "equipment_slot": "4" + "weight": "1" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "536", - "durability": null, + "id": "12564", "name": "Ogre top", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12564" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "shop_price": "60", - "ge_buy_limit": "100", - "examine": "Good for stomping.", - "grand_exchange_price": "420", - "durability": null, - "name": "Ogre boots", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", "id": "12565", - "equipment_slot": "10" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "420", - "durability": null, "name": "Ogre boots", - "tradeable": "true", + "examine": "Good for stomping.", "archery_ticket_price": "0", - "id": "12566" + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10", + "ge_buy_limit": "100", + "shop_price": "60", + "tradeable": "true", + "weight": "3" }, { + "id": "12566", + "name": "Ogre boots", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12567", + "name": "Diseased kebbit fur", "examine": "It's a slightly sickly-looking fur.", - "grand_exchange_price": "1468", - "durability": null, - "name": "Diseased kebbit fur", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "12567" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "remove_head": "true", - "ge_buy_limit": "100", - "examine": "A furry hat with an unnerving tail.", - "grand_exchange_price": "3656", - "durability": null, - "name": "Davy kebbit hat", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "12568", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3656", - "durability": null, "name": "Davy kebbit hat", - "tradeable": "true", + "examine": "A furry hat with an unnerving tail.", "archery_ticket_price": "0", - "id": "12569" + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "tradeable": "true", + "weight": "1" }, { - "requirements": "{0,5}", - "ge_buy_limit": "100", - "turn90cw_anim": "8684", - "examine": "A big piece of tree.", - "walk_anim": "8684", - "durability": null, - "weight": "10", - "turn90ccw_anim": "8684", - "attack_speed": "7", - "weapon_interface": "10", - "turn180_anim": "8684", - "render_anim": "1157", - "defence_anim": "403", - "equipment_slot": "3", - "attack_anims": "401,401,401,401", - "grand_exchange_price": "77", - "stand_anim": "8683", - "name": "Ogre club", - "tradeable": "true", - "run_anim": "8685", + "id": "12569", + "name": "Davy kebbit hat", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12570", - "stand_turn_anim": "823", - "bonuses": "-6,-2,15,0,0,0,0,0,0,0,0,12,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "77", - "durability": null, "name": "Ogre club", - "tradeable": "true", + "examine": "A big piece of tree.", "archery_ticket_price": "0", - "id": "12571" - }, - { - "ge_buy_limit": "100", - "examine": "A delicate, sweet-smelling flower.", - "grand_exchange_price": "20", + "attack_anims": "401,401,401,401", + "attack_speed": "7", + "bonuses": "-6,-2,15,0,0,0,0,0,0,0,0,12,0,0,0", + "defence_anim": "403", "durability": null, - "name": "Lavender", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12572" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, - "name": "Lavender", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12573" - }, - { - "ge_buy_limit": "100", - "examine": "A stiff, pungent grass.", - "grand_exchange_price": "31", - "durability": null, - "name": "Fever grass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12574" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "31", - "durability": null, - "name": "Fever grass", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12575" - }, - { - "ge_buy_limit": "100", - "examine": "A cheerful, aromatic flower.", - "grand_exchange_price": "12", - "durability": null, - "name": "Tansymum", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12576" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "12", - "durability": null, - "name": "Tansymum", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12577" - }, - { - "turn90cw_anim": "8681", - "examine": "A stiff, pungent grass.", - "walk_anim": "8681", - "durability": null, - "turn90ccw_anim": "8681", - "turn180_anim": "8681", - "render_anim": "294", "equipment_slot": "3", - "grand_exchange_price": "41", - "stand_anim": "8682", - "name": "Smouldering fever grass", + "ge_buy_limit": "100", + "render_anim": "1157", + "requirements": "{0,5}", + "run_anim": "8685", + "stand_anim": "8683", + "stand_turn_anim": "823", "tradeable": "true", - "run_anim": "8690", + "turn180_anim": "8684", + "turn90ccw_anim": "8684", + "turn90cw_anim": "8684", + "walk_anim": "8684", + "weapon_interface": "10", + "weight": "10" + }, + { + "id": "12571", + "name": "Ogre club", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12572", + "name": "Lavender", + "examine": "A delicate, sweet-smelling flower.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12573", + "name": "Lavender", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12574", + "name": "Fever grass", + "examine": "A stiff, pungent grass.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12575", + "name": "Fever grass", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12576", + "name": "Tansymum", + "examine": "A cheerful, aromatic flower.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12577", + "name": "Tansymum", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12578", - "stand_turn_anim": "8682" + "name": "Smouldering fever grass", + "examine": "A stiff, pungent grass.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "294", + "run_anim": "8690", + "stand_anim": "8682", + "stand_turn_anim": "8682", + "tradeable": "true", + "turn180_anim": "8681", + "turn90ccw_anim": "8681", + "turn90cw_anim": "8681", + "walk_anim": "8681" }, { - "turn90cw_anim": "8681", - "examine": "A delicate, sweet-smelling flower.", - "walk_anim": "8681", - "durability": null, - "turn90ccw_anim": "8681", - "turn180_anim": "8681", - "render_anim": "294", - "equipment_slot": "3", - "grand_exchange_price": "29", - "stand_anim": "8682", - "name": "Smouldering lavender", - "tradeable": "true", - "run_anim": "8690", - "archery_ticket_price": "0", "id": "12579", - "stand_turn_anim": "8682" - }, - { - "turn90cw_anim": "8681", - "examine": "A cheerful, aromatic flower.", - "walk_anim": "8681", + "name": "Smouldering lavender", + "examine": "A delicate, sweet-smelling flower.", + "archery_ticket_price": "0", "durability": null, - "turn90ccw_anim": "8681", - "turn180_anim": "8681", - "render_anim": "294", "equipment_slot": "3", - "grand_exchange_price": "18", - "stand_anim": "8682", - "name": "Smouldering tansymum", - "tradeable": "true", + "render_anim": "294", "run_anim": "8690", - "archery_ticket_price": "0", + "stand_anim": "8682", + "stand_turn_anim": "8682", + "tradeable": "true", + "turn180_anim": "8681", + "turn90ccw_anim": "8681", + "turn90cw_anim": "8681", + "walk_anim": "8681" + }, + { "id": "12580", - "stand_turn_anim": "8682" + "name": "Smouldering tansymum", + "examine": "A cheerful, aromatic flower.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "render_anim": "294", + "run_anim": "8690", + "stand_anim": "8682", + "stand_turn_anim": "8682", + "tradeable": "true", + "turn180_anim": "8681", + "turn90ccw_anim": "8681", + "turn90cw_anim": "8681", + "walk_anim": "8681" }, { - "ge_buy_limit": "25000", - "examine": "Logs cut from a eucalyptus tree.", - "grand_exchange_price": "507", - "durability": null, - "name": "Eucalyptus logs", - "tradeable": "true", - "archery_ticket_price": "0", "id": "12581", - "equipment_slot": "5" - }, - { - "ge_buy_limit": "25000", - "grand_exchange_price": "507", - "durability": null, "name": "Eucalyptus logs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12582" - }, - { - "ge_buy_limit": "1000", "examine": "Logs cut from a eucalyptus tree.", - "grand_exchange_price": "3609", - "durability": null, - "name": "Eucalyptus pyre logs", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "12583" + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "25000", + "tradeable": "true" }, { + "id": "12582", + "name": "Eucalyptus logs", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "25000", + "tradeable": "true" + }, + { + "id": "12583", + "name": "Eucalyptus pyre logs", + "examine": "Logs cut from a eucalyptus tree.", + "archery_ticket_price": "0", + "durability": null, "ge_buy_limit": "1000", - "grand_exchange_price": "3609", - "durability": null, + "tradeable": "true", + "weight": "2" + }, + { + "id": "12584", "name": "Eucalyptus pyre logs", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12584" + "durability": null, + "ge_buy_limit": "1000", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "12588", + "name": "Primweed", "examine": "A modest and mild plant.", - "grand_exchange_price": "20", - "durability": null, - "name": "Primweed", - "tradeable": "true", - "weight": "2", "archery_ticket_price": "0", - "id": "12588" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true", + "weight": "2" }, { - "ge_buy_limit": "100", - "grand_exchange_price": "20", - "durability": null, + "id": "12589", "name": "Primweed", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12589" + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" }, { - "ge_buy_limit": "100", + "id": "12590", + "name": "Stinkbloom", "examine": "A pretty but putrid flower.", - "grand_exchange_price": "16", - "durability": null, - "name": "Stinkbloom", - "tradeable": "true", - "weight": "0.01", "archery_ticket_price": "0", - "id": "12590" - }, - { + "durability": null, "ge_buy_limit": "100", - "grand_exchange_price": "16", - "durability": null, - "name": "Stinkbloom", "tradeable": "true", - "archery_ticket_price": "0", - "id": "12591" + "weight": "0.01" }, { + "id": "12591", + "name": "Stinkbloom", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12592", "name": "Diseased kebbit fur", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12592" + "durability": null, + "tradeable": "true" }, { - "destroy_message": "If you need to, you can get another from the Tyras Camp catapult engineer.", - "examine": "The plans for repairing the Tyras Camp catapult.", - "durability": null, + "id": "12593", "name": "Catapult schematics", - "tradeable": "false", - "destroy": "true", + "examine": "The plans for repairing the Tyras Camp catapult.", "archery_ticket_price": "0", - "id": "12593" + "destroy": "true", + "destroy_message": "If you need to, you can get another from the Tyras Camp catapult engineer.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "If you need to, you can get another from General Hining in the Tyras Camp.", - "examine": "General Hining wants me to deliver this to the Catapult Engineer.", - "durability": null, + "id": "12594", "name": "Engineer's letter", - "tradeable": "false", - "destroy": "true", + "examine": "General Hining wants me to deliver this to the Catapult Engineer.", "archery_ticket_price": "0", - "id": "12594" + "destroy": "true", + "destroy_message": "If you need to, you can get another from General Hining in the Tyras Camp.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can always get another from the drunken sailor in Port Sarim.", - "examine": "Taken from a drunken sailor in Port Sarim.", - "durability": null, - "name": "Sailor's hat", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", "id": "12595", - "equipment_slot": "0" + "name": "Sailor's hat", + "examine": "Taken from a drunken sailor in Port Sarim.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can always get another from the drunken sailor in Port Sarim.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false", + "weight": "0.2" }, { - "destroy_message": "You can get another set from Thaki the delivery dwarf in Port Sarim.", - "examine": "Dwarf-made parts for repairing the Tyras Camp catapult.", - "durability": null, + "id": "12596", "name": "Metal catapult parts", - "tradeable": "false", - "destroy": "true", - "weight": "2", + "examine": "Dwarf-made parts for repairing the Tyras Camp catapult.", "archery_ticket_price": "0", - "id": "12596" + "destroy": "true", + "destroy_message": "You can get another set from Thaki the delivery dwarf in Port Sarim.", + "durability": null, + "tradeable": "false", + "weight": "2" }, { - "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", - "durability": null, + "id": "12597", "name": "Mahogany catapult part", - "tradeable": "false", - "destroy": "true", - "weight": "2", + "examine": "Used to repair the Tyras Camp catapult.", "archery_ticket_price": "0", - "id": "12597" - }, - { + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12598" + "weight": "2" }, { + "id": "12598", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12599" + "weight": "2" }, { + "id": "12599", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12600" + "weight": "2" }, { + "id": "12600", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12601" + "weight": "2" }, { + "id": "12601", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12602" + "weight": "2" }, { + "id": "12602", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12603" + "weight": "2" }, { + "id": "12603", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12604" + "weight": "2" }, { + "id": "12604", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12605" + "weight": "2" }, { + "id": "12605", + "name": "Mahogany catapult part", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", - "examine": "Used to repair the Tyras Camp catapult.", "durability": null, - "name": "Mahogany catapult part", "tradeable": "false", - "destroy": "true", - "weight": "2", - "archery_ticket_price": "0", - "id": "12606" + "weight": "2" }, { + "id": "12606", + "name": "Mahogany catapult part", "examine": "Used to repair the Tyras Camp catapult.", - "durability": null, - "name": "Picture", - "tradeable": "false", - "destroy": "true", - "weight": "2", "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "durability": null, + "tradeable": "false", + "weight": "2" + }, + { "id": "12607", - "equipment_slot": "5" + "name": "Picture", + "examine": "Used to repair the Tyras Camp catapult.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "5", + "tradeable": "false", + "weight": "2" }, { - "shop_price": "200", - "ge_buy_limit": "100", - "examine": "An amulet of Farming with 1 charge.", - "grand_exchange_price": "271", - "durability": null, - "name": "Amulet of farming(1)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "12608", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "271", - "durability": null, "name": "Amulet of farming(1)", - "tradeable": "true", + "examine": "An amulet of Farming with 1 charge.", "archery_ticket_price": "0", - "id": "12609" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An amulet of Farming with 2 charges.", - "grand_exchange_price": "8", - "durability": null, - "name": "Amulet of farming(2)", - "tradeable": "true", + "id": "12609", + "name": "Amulet of farming(1)", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12610", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Amulet of farming(2)", - "tradeable": "true", + "examine": "An amulet of Farming with 2 charges.", "archery_ticket_price": "0", - "id": "12611" + "durability": null, + "equipment_slot": "2", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An amulet of Farming with 3 charges.", - "grand_exchange_price": "8", - "durability": null, - "name": "Amulet of farming(3)", - "tradeable": "true", + "id": "12611", + "name": "Amulet of farming(2)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "12612", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Amulet of farming(3)", - "tradeable": "true", + "examine": "An amulet of Farming with 3 charges.", "archery_ticket_price": "0", - "id": "12613" + "durability": null, + "equipment_slot": "2", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An amulet of Farming with 4 charges.", - "grand_exchange_price": "8", - "durability": null, - "name": "Amulet of farming(4)", - "tradeable": "true", + "id": "12613", + "name": "Amulet of farming(3)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "12614", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Amulet of farming(4)", - "tradeable": "true", + "examine": "An amulet of Farming with 4 charges.", "archery_ticket_price": "0", - "id": "12615" + "durability": null, + "equipment_slot": "2", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An amulet of Farming with 5 charges.", - "grand_exchange_price": "8", - "durability": null, - "name": "Amulet of farming(5)", - "tradeable": "true", + "id": "12615", + "name": "Amulet of farming(4)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "12616", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Amulet of farming(5)", - "tradeable": "true", + "examine": "An amulet of Farming with 5 charges.", "archery_ticket_price": "0", - "id": "12617" + "durability": null, + "equipment_slot": "2", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An amulet of Farming with 6 charges.", - "grand_exchange_price": "8", - "durability": null, - "name": "Amulet of farming(6)", - "tradeable": "true", + "id": "12617", + "name": "Amulet of farming(5)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "12618", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Amulet of farming(6)", - "tradeable": "true", + "examine": "An amulet of Farming with 6 charges.", "archery_ticket_price": "0", - "id": "12619" + "durability": null, + "equipment_slot": "2", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "200", - "examine": "An amulet of Farming with 7 charges.", - "grand_exchange_price": "8", - "durability": null, - "name": "Amulet of farming(7)", - "tradeable": "true", + "id": "12619", + "name": "Amulet of farming(6)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "12620", - "equipment_slot": "2" - }, - { - "durability": null, "name": "Amulet of farming(7)", - "tradeable": "true", + "examine": "An amulet of Farming with 7 charges.", "archery_ticket_price": "0", - "id": "12621" - }, - { + "durability": null, + "equipment_slot": "2", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "An amulet of Farming with 8 charges.", - "grand_exchange_price": "210", - "durability": null, - "name": "Amulet of farming(8)", - "tradeable": "true", + "tradeable": "true" + }, + { + "id": "12621", + "name": "Amulet of farming(7)", "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { "id": "12622", - "equipment_slot": "2" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "210", - "durability": null, "name": "Amulet of farming(8)", - "tradeable": "true", + "examine": "An amulet of Farming with 8 charges.", "archery_ticket_price": "0", - "id": "12623" + "durability": null, + "equipment_slot": "2", + "ge_buy_limit": "100", + "shop_price": "200", + "tradeable": "true" }, { - "shop_price": "10", - "examine": "An ogleroot. How odd.", + "id": "12623", + "name": "Amulet of farming(8)", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12624", "name": "Ogleroot", - "tradeable": "true", + "examine": "An ogleroot. How odd.", "archery_ticket_price": "0", - "weight": "0", - "id": "12624" - }, - { - "destroy_message": "You will need to obtain more flags from Mrs. Winkin or Farmer Blinkin if you have lost all of the flags you have.", - "shop_price": "500", - "examine": "A flag to put in the ground.", "durability": null, - "name": "Flag", - "tradeable": "false", - "destroy": "true", - "weight": "0", - "archery_ticket_price": "0", - "id": "12625" - }, - { - "destroy_message": "You will need to get another exam paper from Professor Henry", - "examine": "Player Safety test", - "durability": null, - "name": "Test paper", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12626" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12627" - }, - { - "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12628" - }, - { - "destroy_message": "You can get another pair of gloves from the chest in the Stronghold of Player Safety.", - "examine": "Gloves from the Stronghold of Player Safety.", - "durability": null, - "name": "Safety gloves", - "tradeable": "false", - "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "12629", - "bonuses": "0,0,0,0,0,1,2,2,1,2,1,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Rubium is very unstable", "shop_price": "10", - "examine": "Be careful with this near water.", + "tradeable": "true", + "weight": "0" + }, + { + "id": "12625", + "name": "Flag", + "examine": "A flag to put in the ground.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to obtain more flags from Mrs. Winkin or Farmer Blinkin if you have lost all of the flags you have.", "durability": null, + "shop_price": "500", + "tradeable": "false", + "weight": "0" + }, + { + "id": "12626", + "name": "Test paper", + "examine": "Player Safety test", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You will need to get another exam paper from Professor Henry", + "durability": null, + "tradeable": "false" + }, + { + "id": "12627", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "12628", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "durability": null, + "tradeable": "false" + }, + { + "id": "12629", + "name": "Safety gloves", + "examine": "Gloves from the Stronghold of Player Safety.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,1,2,2,1,2,1,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another pair of gloves from the chest in the Stronghold of Player Safety.", + "durability": null, + "equipment_slot": "9", + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "12630", "name": "Rubium", - "weight": "1", + "examine": "Be careful with this near water.", "archery_ticket_price": "0", - "id": "12630" + "destroy_message": "Rubium is very unstable", + "durability": null, + "shop_price": "10", + "weight": "1" }, { - "destroy_message": "The train is tiny", - "examine": "(While on the ground) Kennith's lost toy. (While in your inventory) A wooden toy train.", - "durability": null, + "id": "12631", "name": "Toy train", + "examine": "(While on the ground) Kennith's lost toy. (While in your inventory) A wooden toy train.", "archery_ticket_price": "0", - "id": "12631" + "destroy_message": "The train is tiny", + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "160", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, + "id": "12632", "name": "Note", - "tradeable": "true", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "id": "12632" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "160", + "tradeable": "true" }, { - "examine": "The jar is shaking violently!", - "durability": null, + "id": "12633", "name": "Super fishing explosive", + "examine": "The jar is shaking violently!", "archery_ticket_price": "0", - "id": "12633" + "durability": null }, { - "destroy_message": "You can get another chocatrice cape from Diango in Draynor Village.", - "examine": "A thick, orange cape.", - "durability": null, - "name": "Chocatrice cape", - "tradeable": "false", - "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", "id": "12634", - "equipment_slot": "1" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12635" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12636" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12637" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12638" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12639" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12640" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12641" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12642" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12643" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Happy Easter.", - "grand_exchange_price": "64747137", - "durability": null, - "name": "Easter egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12644" - }, - { - "destroy_message": "You can get another chocatrice cape from Diango in Draynor Village.", - "examine": "A thick, orange cape.", - "durability": null, "name": "Chocatrice cape", - "tradeable": "false", + "examine": "A thick, orange cape.", + "archery_ticket_price": "0", "destroy": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "12645", - "equipment_slot": "1" - }, - { - "examine": "A chocolate egg wrapped in coloured foil.", + "destroy_message": "You can get another chocatrice cape from Diango in Draynor Village.", "durability": null, - "name": "Chocolate egg", - "archery_ticket_price": "0", - "id": "12646" - }, - { - "examine": "A chocolate egg wrapped in coloured foil.", - "durability": null, - "name": "Chocolate egg", - "archery_ticket_price": "0", - "id": "12647" - }, - { - "examine": "A chocolate egg wrapped in coloured foil.", - "durability": null, - "name": "Chocolate egg", - "archery_ticket_price": "0", - "id": "12648" - }, - { - "shop_price": "2", - "examine": "It's an empty bucket.", - "grand_exchange_price": "50", - "durability": null, - "name": "Bucket", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "12649" - }, - { - "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", - "grand_exchange_price": "74", - "durability": null, - "name": "Bucket of water", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "12650" - }, - { - "examine": "It's a bucket of water.", - "grand_exchange_price": "74", - "durability": null, - "name": "Bucket of water", - "tradeable": "true", - "weight": "3", - "archery_ticket_price": "0", - "id": "12651" - }, - { - "examine": "It's a bucket of coal from the Easter Bunny's warren.", - "durability": null, - "name": "Bucket of coal", - "weight": "3", - "archery_ticket_price": "0", - "id": "12652" - }, - { - "examine": "It's a bucket of coal from the Easter Bunny's warren.", - "durability": null, - "name": "Bucket of coal", - "weight": "3", - "archery_ticket_price": "0", - "id": "12653" - }, - { - "destroy_message": "Are you sure you want to destroy this object?
You can get another in the Easter Bunny's warren.", - "examine": "A stripy brown egg.", - "grand_exchange_price": "1255", - "durability": null, - "name": "Cockatrice egg", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12654" - }, - { - "destroy_message": "Are you sure you want to destroy this object?
You can make another at the Easter Bunny's warren.", - "examine": "A cockatrice egg that has been dipped in molten chocolate.", - "durability": null, - "name": "Chocatrice egg", + "equip_audio": "2238", + "equipment_slot": "1", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12655", - "equipment_slot": "3" + "weight": "0.4" }, { + "id": "12635", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Some chocolate chunks.", "durability": null, + "tradeable": "true" + }, + { + "id": "12636", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12637", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12638", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12639", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12640", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12641", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12642", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12643", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12644", + "name": "Easter egg", + "examine": "Happy Easter.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12645", + "name": "Chocatrice cape", + "examine": "A thick, orange cape.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another chocatrice cape from Diango in Draynor Village.", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "1", + "tradeable": "false", + "weight": "0.4" + }, + { + "id": "12646", + "name": "Chocolate egg", + "examine": "A chocolate egg wrapped in coloured foil.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12647", + "name": "Chocolate egg", + "examine": "A chocolate egg wrapped in coloured foil.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12648", + "name": "Chocolate egg", + "examine": "A chocolate egg wrapped in coloured foil.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12649", + "name": "Bucket", + "examine": "It's an empty bucket.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "2", + "tradeable": "true", + "weight": "1" + }, + { + "id": "12650", + "name": "Bucket of water", + "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "3" + }, + { + "id": "12651", + "name": "Bucket of water", + "examine": "It's a bucket of water.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "3" + }, + { + "id": "12652", + "name": "Bucket of coal", + "examine": "It's a bucket of coal from the Easter Bunny's warren.", + "archery_ticket_price": "0", + "durability": null, + "weight": "3" + }, + { + "id": "12653", + "name": "Bucket of coal", + "examine": "It's a bucket of coal from the Easter Bunny's warren.", + "archery_ticket_price": "0", + "durability": null, + "weight": "3" + }, + { + "id": "12654", + "name": "Cockatrice egg", + "examine": "A stripy brown egg.", + "archery_ticket_price": "0", + "destroy_message": "Are you sure you want to destroy this object?
You can get another in the Easter Bunny's warren.", + "durability": null, + "tradeable": "true" + }, + { + "id": "12655", + "name": "Chocatrice egg", + "examine": "A cockatrice egg that has been dipped in molten chocolate.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "Are you sure you want to destroy this object?
You can make another at the Easter Bunny's warren.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "12657", "name": "Chocolate chunks", + "examine": "Some chocolate chunks.", "archery_ticket_price": "0", - "id": "12657" + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null }, { - "remove_head": "true", - "shop_price": "3520", - "examine": "A full face helmet.", - "durability": null, - "weight": "2.7", - "absorb": "1,0,2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "1913", - "name": "Adamant full helm (e)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "12658", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" - }, - { + "name": "Adamant full helm (e)", + "examine": "A full face helmet.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "shop_price": "3520", - "examine": "A full face helmet.", - "durability": null, - "weight": "2.7", - "absorb": "1,0,2", - "remove_beard": "true", - "equipment_slot": "0", - "grand_exchange_price": "1913", - "name": "Adamant full helm (charged)", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12659", - "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + "name": "Adamant full helm (charged)", + "examine": "A full face helmet.", + "absorb": "1,0,2", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "3520", + "tradeable": "true", + "weight": "2.7" }, { - "remove_head": "true", - "examine": "Lightweight head protection.", - "grand_exchange_price": "1040", - "durability": null, - "name": "Snakeskin bandana (e)", - "tradeable": "false", - "weight": "0.9", - "archery_ticket_price": "0", "id": "12660", - "absorb": "0,2,1", - "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", + "name": "Snakeskin bandana (e)", "examine": "Lightweight head protection.", - "grand_exchange_price": "1040", - "durability": null, - "name": "Snakeskin bandana (charged)", - "tradeable": "false", - "weight": "0.9", - "archery_ticket_price": "0", - "id": "12661", "absorb": "0,2,1", + "archery_ticket_price": "0", "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false", + "weight": "0.9" }, { - "remove_head": "true", - "examine": "A wooden helmet.", - "durability": null, - "weight": "0.9", - "absorb": "3,1,0", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "5623", - "name": "Splitbark helm (e)", - "tradeable": "true", + "id": "12661", + "name": "Snakeskin bandana (charged)", + "examine": "Lightweight head protection.", + "absorb": "0,2,1", "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false", + "weight": "0.9" + }, + { "id": "12662", - "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" - }, - { - "remove_head": "true", + "name": "Splitbark helm (e)", "examine": "A wooden helmet.", - "durability": null, - "weight": "0.9", "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "5623", - "name": "Splitbark helm (charged)", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "12663", - "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" - }, - { - "remove_head": "true", - "examine": "A full face helmet.", + "name": "Splitbark helm (charged)", + "examine": "A wooden helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0", "durability": null, - "weight": "2.7", - "absorb": "1,0,3", - "remove_beard": "true", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "21200", - "name": "Rune full helm (e)", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "12664", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "remove_head": "true", + "name": "Rune full helm (e)", "examine": "A full face helmet.", - "durability": null, - "weight": "2.7", "absorb": "1,0,3", - "remove_beard": "true", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "21200", - "name": "Rune full helm (charged)", + "remove_beard": "true", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12665", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "remove_head": "true", - "examine": "Makes the wearer pretty intimidating.", + "name": "Rune full helm (charged)", + "examine": "A full face helmet.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", "durability": null, - "weight": "1.3", - "absorb": "2,0,4", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "61200", - "name": "Dragon med helm (e)", + "remove_beard": "true", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12666", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" - }, - { - "remove_head": "true", + "name": "Dragon med helm (e)", "examine": "Makes the wearer pretty intimidating.", - "durability": null, - "weight": "1.3", "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "61200", - "name": "Dragon med helm (charged)", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "1.3" + }, + { "id": "12667", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + "name": "Dragon med helm (charged)", + "examine": "Makes the wearer pretty intimidating.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1.3" }, { - "remove_head": "true", - "shop_price": "15000", - "examine": "A mystical helmet.", - "durability": null, - "destroy": "true", - "weight": "0.9", - "absorb": "3,1,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar helm (e)", - "tradeable": "false", - "archery_ticket_price": "0", "id": "12668", - "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0" - }, - { + "name": "Lunar helm (e)", + "examine": "A mystical helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "shop_price": "15000", - "examine": "A mystical helmet.", - "durability": null, - "destroy": "true", - "weight": "0.9", - "absorb": "3,1,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "The Oneiromancer might be able to help you get another.", - "name": "Lunar helm (charged)", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "12669", - "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0" + "name": "Lunar helm (charged)", + "examine": "A mystical helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0", + "destroy": "true", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "15000", + "tradeable": "false", + "weight": "0.9" }, { - "remove_head": "true", - "examine": "A helmet of great craftmanship.", - "durability": null, - "weight": "0.5", - "absorb": "0,5,2", - "equipment_slot": "0", - "lendable": "true", - "grand_exchange_price": "3932989", - "name": "Armadyl helmet (e)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "12670", - "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0" - }, - { - "remove_head": "true", + "name": "Armadyl helmet (e)", "examine": "A helmet of great craftmanship.", - "durability": null, - "weight": "0.5", "absorb": "0,5,2", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0", + "durability": null, + "equip_audio": "2240", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "3932989", - "name": "Armadyl helmet (charged)", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "0.5" + }, + { "id": "12671", - "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", - "examine": "This helmet is worn by archers.", + "name": "Armadyl helmet (charged)", + "examine": "A helmet of great craftmanship.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0", "durability": null, - "weight": "2", - "absorb": "0,3,1", + "equip_audio": "2240", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "41000", - "name": "Archer helm (e)", + "remove_head": "true", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "0.5" + }, + { "id": "12672", - "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", + "name": "Archer helm (e)", "examine": "This helmet is worn by archers.", - "durability": null, - "weight": "2", "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "41000", - "name": "Archer helm (charged)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "12673", - "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", - "examine": "This helmet is worn by berserkers.", + "name": "Archer helm (charged)", + "examine": "This helmet is worn by archers.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0", "durability": null, - "weight": "2.7", - "absorb": "1,0,3", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "48800", - "name": "Berserker helm (e)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2" + }, + { "id": "12674", - "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", + "name": "Berserker helm (e)", "examine": "This helmet is worn by berserkers.", - "durability": null, - "weight": "2.7", "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "48800", - "name": "Berserker helm (charged)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12675", - "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", - "examine": "This helm is worn by warriors.", - "durability": null, - "weight": "2.7", + "name": "Berserker helm (charged)", + "examine": "This helmet is worn by berserkers.", "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "48200", - "name": "Warrior helm (e)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12676", - "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", + "name": "Warrior helm (e)", "examine": "This helm is worn by warriors.", - "durability": null, - "weight": "2.7", "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "48200", - "name": "Warrior helm (charged)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12677", - "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", - "examine": "This helm is worn by farseers.", + "name": "Warrior helm (charged)", + "examine": "This helm is worn by warriors.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0", "durability": null, - "weight": "2.7", - "absorb": "3,1,0", "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "46400", - "name": "Farseer helm (e)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12678", - "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "78000", + "name": "Farseer helm (e)", "examine": "This helm is worn by farseers.", - "durability": null, - "weight": "2.7", "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0", + "durability": null, "equipment_slot": "0", "lendable": "true", - "grand_exchange_price": "46400", - "name": "Farseer helm (charged)", + "remove_head": "true", + "shop_price": "78000", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.7" + }, + { "id": "12679", - "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" + "name": "Farseer helm (charged)", + "examine": "This helm is worn by farseers.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "shop_price": "78000", + "tradeable": "true", + "weight": "2.7" }, { - "remove_head": "true", - "shop_price": "50000", - "examine": "A gift from Neitiznot's Burgher.", - "durability": null, - "weight": "2.2", - "absorb": "2,0,4", - "equipment_slot": "0", - "grand_exchange_price": "44831", - "name": "Helm of neitiznot (e)", - "tradeable": "true", - "archery_ticket_price": "0", "id": "12680", - "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0" - }, - { + "name": "Helm of neitiznot (e)", + "examine": "A gift from Neitiznot's Burgher.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", "remove_head": "true", "shop_price": "50000", - "examine": "A gift from Neitiznot's Burgher.", - "durability": null, - "weight": "2.2", - "absorb": "2,0,4", - "equipment_slot": "0", - "grand_exchange_price": "44831", - "name": "Helm of neitiznot (charged)", "tradeable": "true", - "archery_ticket_price": "0", + "weight": "2.2" + }, + { "id": "12681", - "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0" - }, - { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, - "name": "Baby monkey", + "name": "Helm of neitiznot (charged)", + "examine": "A gift from Neitiznot's Burgher.", + "absorb": "2,0,4", "archery_ticket_price": "0", - "id": "12682" + "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50000", + "tradeable": "true", + "weight": "2.2" }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12682", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12684" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12683", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12684", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12686" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12685", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12686", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12688" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12687", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12688", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12690" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12689", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12690", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12692" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12691", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12692", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12694" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12693", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12694", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12696" + "durability": null }, { - "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", - "durability": null, + "id": "12695", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12696", "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", "archery_ticket_price": "0", - "id": "12698" + "durability": null }, { - "requirements": "{4,23}", - "examine": "A hyperactive little pup.", - "durability": null, + "id": "12697", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12698", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12699", + "name": "Monkey", + "examine": "Hide the bananas!" + }, + { + "id": "12700", "name": "Terrier puppy", - "archery_ticket_price": "0", - "id": "12700" - }, - { - "requirements": "{4,23}", "examine": "A hyperactive little pup.", - "durability": null, - "name": "Terrier", "archery_ticket_price": "0", - "id": "12701" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Such a brave doggy.", + "id": "12701", + "name": "Terrier", + "examine": "A hyperactive little pup.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12702", "name": "Terrier puppy", - "archery_ticket_price": "0", - "id": "12702" - }, - { - "requirements": "{4,23}", "examine": "Such a brave doggy.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12703", "name": "Terrier", + "examine": "Such a brave doggy.", "archery_ticket_price": "0", - "id": "12703" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "This is one fast little pooch.", - "durability": null, + "id": "12704", "name": "Greyhound puppy", - "archery_ticket_price": "0", - "id": "12704" - }, - { - "requirements": "{4,23}", - "examine": "An aerodynamic doggy.", - "durability": null, - "name": "Greyhound", - "archery_ticket_price": "0", - "id": "12705" - }, - { - "requirements": "{4,23}", "examine": "This is one fast little pooch.", - "durability": null, - "name": "Greyhound puppy", "archery_ticket_price": "0", - "id": "12706" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "An aerodynamic doggy.", - "durability": null, + "id": "12705", "name": "Greyhound", + "examine": "An aerodynamic doggy.", "archery_ticket_price": "0", - "id": "12707" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Soft but strong... and cute.", + "id": "12706", + "name": "Greyhound puppy", + "examine": "This is one fast little pooch.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12707", + "name": "Greyhound", + "examine": "An aerodynamic doggy.", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12708", "name": "Labrador puppy", - "archery_ticket_price": "0", - "id": "12708" - }, - { - "requirements": "{4,23}", - "examine": "My most faithful friend.", - "durability": null, - "name": "Labrador", - "archery_ticket_price": "0", - "id": "12709" - }, - { - "requirements": "{4,23}", "examine": "Soft but strong... and cute.", - "durability": null, - "name": "Labrador puppy", "archery_ticket_price": "0", - "id": "12710" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "My most faithful friend.", - "durability": null, + "id": "12709", "name": "Labrador", + "examine": "My most faithful friend.", "archery_ticket_price": "0", - "id": "12711" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Now, if only I could find another hundred...", + "id": "12710", + "name": "Labrador puppy", + "examine": "Soft but strong... and cute.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12711", + "name": "Labrador", + "examine": "My most faithful friend.", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12712", "name": "Dalmatian puppy", - "archery_ticket_price": "0", - "id": "12712" - }, - { - "requirements": "{4,23}", - "examine": "A purebred doggy.", - "durability": null, - "name": "Dalmatian", - "archery_ticket_price": "0", - "id": "12713" - }, - { - "requirements": "{4,23}", "examine": "Now, if only I could find another hundred...", - "durability": null, - "name": "Dalmatian puppy", "archery_ticket_price": "0", - "id": "12714" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "A purebred doggy.", - "durability": null, + "id": "12713", "name": "Dalmatian", + "examine": "A purebred doggy.", "archery_ticket_price": "0", - "id": "12715" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "This little puppy is very quiet.", + "id": "12714", + "name": "Dalmatian puppy", + "examine": "Now, if only I could find another hundred...", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12715", + "name": "Dalmatian", + "examine": "A purebred doggy.", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12716", "name": "Sheepdog puppy", - "archery_ticket_price": "0", - "id": "12716" - }, - { - "requirements": "{4,23}", - "examine": "Come by! Come by!", - "durability": null, - "name": "Sheepdog", - "archery_ticket_price": "0", - "id": "12717" - }, - { - "requirements": "{4,23}", "examine": "This little puppy is very quiet.", - "durability": null, - "name": "Sheepdog puppy", "archery_ticket_price": "0", - "id": "12718" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Come by! Come by!", - "durability": null, + "id": "12717", "name": "Sheepdog", + "examine": "Come by! Come by!", "archery_ticket_price": "0", - "id": "12719" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "One proud little puppy.", + "id": "12718", + "name": "Sheepdog puppy", + "examine": "This little puppy is very quiet.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12719", + "name": "Sheepdog", + "examine": "Come by! Come by!", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12720", "name": "Bulldog puppy", - "archery_ticket_price": "0", - "id": "12720" - }, - { - "requirements": "{4,23}", - "examine": "Looks like it's chewing a wasp.", - "durability": null, - "name": "Bulldog", - "archery_ticket_price": "0", - "id": "12721" - }, - { - "requirements": "{4,23}", "examine": "One proud little puppy.", - "durability": null, - "name": "Bulldog puppy", "archery_ticket_price": "0", - "id": "12722" + "durability": null, + "requirements": "{4,23}" }, { - "requirements": "{4,23}", - "examine": "Looks like it's chewing a wasp.", - "durability": null, + "id": "12721", "name": "Bulldog", + "examine": "Looks like it's chewing a wasp.", "archery_ticket_price": "0", - "id": "12723" + "durability": null, + "requirements": "{4,23}" }, { - "examine": "Chick: A raven chick.", + "id": "12722", + "name": "Bulldog puppy", + "examine": "One proud little puppy.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12723", + "name": "Bulldog", + "examine": "Looks like it's chewing a wasp.", + "archery_ticket_price": "0", + "durability": null, + "requirements": "{4,23}" + }, + { + "id": "12724", "name": "Raven chick", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12724" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12725", "name": "Raven", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12725" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12726", "name": "Raven chick", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12726" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12727", "name": "Raven", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12727" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12728", "name": "Raven chick", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12728" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12729", "name": "Raven", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12729" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12730", "name": "Raven chick", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12730" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12731", "name": "Raven", + "examine": "Chick: A raven chick.", "archery_ticket_price": "0", - "id": "12731" + "durability": null }, { - "examine": "Chick: A raven chick.", - "durability": null, + "id": "12732", "name": "Raven chick", - "archery_ticket_price": "0", - "id": "12732" - }, - { "examine": "Chick: A raven chick.", - "durability": null, - "name": "Raven", "archery_ticket_price": "0", - "id": "12733" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12733", + "name": "Raven", + "examine": "Chick: A raven chick.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12734", "name": "Baby raccoon", + "examine": "A stripy little baby raccoon.", "archery_ticket_price": "0", - "id": "12734" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12735", "name": "Raccoon", + "examine": "He can run with us.", "archery_ticket_price": "0", - "id": "12735" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12736", "name": "Baby raccoon", + "examine": "A stripy little baby raccoon.", "archery_ticket_price": "0", - "id": "12736" + "durability": null }, { - "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", - "durability": null, + "id": "12737", "name": "Raccoon", + "examine": "He can run with us.", "archery_ticket_price": "0", - "id": "12737" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12738", "name": "Baby gecko", + "examine": "It's so adorably tiny!", "archery_ticket_price": "0", - "id": "12738" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12739", "name": "Baby gecko", + "examine": "It's so adorably tiny!", "archery_ticket_price": "0", - "id": "12739" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12740", "name": "Baby gecko", + "examine": "It's so adorably tiny!", "archery_ticket_price": "0", - "id": "12740" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12741", "name": "Baby gecko", + "examine": "It's so adorably tiny!", "archery_ticket_price": "0", - "id": "12741" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12742", "name": "Gecko", + "examine": "How cute!", "archery_ticket_price": "0", - "id": "12742" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12743", "name": "Gecko", + "examine": "How cute!", "archery_ticket_price": "0", - "id": "12743" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12744", "name": "Gecko", + "examine": "How cute!", "archery_ticket_price": "0", - "id": "12744" + "durability": null }, { - "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", - "durability": null, + "id": "12745", "name": "Gecko", + "examine": "How cute!", "archery_ticket_price": "0", - "id": "12745" + "durability": null }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12746", "name": "Baby giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12746" + "durability": null, + "requirements": "{23,40}" }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12747", "name": "Giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12747" + "durability": null, + "requirements": "{23,40}" }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12748", "name": "Baby giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12748" + "durability": null, + "requirements": "{23,40}" }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12749", "name": "Giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12749" + "durability": null, + "requirements": "{23,40}" }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12750", "name": "Baby giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12750" + "durability": null, + "requirements": "{23,40}" }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12751", "name": "Giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12751" + "durability": null, + "requirements": "{23,40}" }, { - "requirements": "{23,40}", - "examine": "Baby: Little NipperAdult: Bigger Nipper.", - "durability": null, + "id": "12752", "name": "Baby giant crab", - "archery_ticket_price": "0", - "id": "12752" - }, - { - "requirements": "{23,40}", "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "archery_ticket_price": "0", "durability": null, + "requirements": "{23,40}" + }, + { + "id": "12753", "name": "Giant crab", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", "archery_ticket_price": "0", - "id": "12753" + "durability": null, + "requirements": "{23,40}" }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12754", "name": "Baby squirrel", + "examine": "A tiny nut-thief.", "archery_ticket_price": "0", - "id": "12754" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12755", "name": "Squirrel", + "examine": "An experienced nut-thief.", "archery_ticket_price": "0", - "id": "12755" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12756", "name": "Baby squirrel", + "examine": "A tiny nut-thief.", "archery_ticket_price": "0", - "id": "12756" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12757", "name": "Squirrel", + "examine": "An experienced nut-thief.", "archery_ticket_price": "0", - "id": "12757" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12758", "name": "Baby squirrel", + "examine": "A tiny nut-thief.", "archery_ticket_price": "0", - "id": "12758" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12759", "name": "Squirrel", + "examine": "An experienced nut-thief.", "archery_ticket_price": "0", - "id": "12759" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12760", "name": "Baby squirrel", + "examine": "A tiny nut-thief.", "archery_ticket_price": "0", - "id": "12760" + "durability": null }, { - "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", - "durability": null, + "id": "12761", "name": "Squirrel", + "examine": "An experienced nut-thief.", "archery_ticket_price": "0", - "id": "12761" + "durability": null }, { - "examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.", - "durability": null, + "id": "12762", + "name": "Penguin", + "examine": "Emperor of all he surveys." + }, + { + "id": "12763", "name": "Baby penguin", + "examine": "Can't fly and can barely walk, but adorable nonetheless.", "archery_ticket_price": "0", - "id": "12763" + "durability": null }, { - "examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.", - "durability": null, + "id": "12764", + "name": "Penguin", + "examine": "Emperor of all he surveys." + }, + { + "id": "12765", "name": "Baby penguin", + "examine": "Can't fly and can barely walk, but adorable nonetheless.", "archery_ticket_price": "0", - "id": "12765" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12766", "name": "Vulture chick", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12766" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12767", "name": "Vulture", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12767" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12768", "name": "Vulture chick", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12768" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12769", "name": "Vulture", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12769" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12770", "name": "Vulture chick", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12770" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12771", "name": "Vulture", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12771" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12772", "name": "Vulture chick", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12772" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12773", "name": "Vulture", + "examine": "If you see them circling: run.", "archery_ticket_price": "0", - "id": "12773" + "durability": null }, { - "examine": "If you see them circling: run.", - "durability": null, + "id": "12774", "name": "Vulture chick", - "archery_ticket_price": "0", - "id": "12774" - }, - { "examine": "If you see them circling: run.", - "durability": null, - "name": "Vulture", "archery_ticket_price": "0", - "id": "12775" + "durability": null }, { - "requirements": "{23,85}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2613", + "id": "12775", + "name": "Vulture", + "examine": "If you see them circling: run.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "12776", + "name": "Swamp titan pouch", "examine": "I can summon a swamp titan familiar with this.", - "durability": null, - "name": "Swamp titan pouch", - "tradeable": "true", "archery_ticket_price": "0", - "id": "12776" - }, - { + "durability": null, "ge_buy_limit": "5000", - "grand_exchange_price": "2613", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Swamp titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12777" - }, - { - "requirements": "{17,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "130", - "examine": "I can summon a spirit mosquito familiar with this.", - "durability": null, - "name": "Spirit mosquito pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12778" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "130", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit mosquito pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12779" - }, - { - "requirements": "{23,34}", - "ge_buy_limit": "5000", - "grand_exchange_price": "16100", - "examine": "I can summon a void spinner familiar with this.", - "durability": null, - "name": "Void spinner pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12780" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "16100", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Void spinner pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12781" - }, - { - "requirements": "{23,76}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2458", - "examine": "I can summon a forge regent familiar with this.", - "durability": null, - "name": "Forge regent pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12782" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2458", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Forge regent pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12783" - }, - { - "requirements": "{23,57}", - "ge_buy_limit": "5000", - "grand_exchange_price": "4097", - "examine": "I can summon a spirit larupia familiar with this.", - "durability": null, - "name": "Spirit larupia pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12784" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "4097", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit larupia pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12785" - }, - { - "requirements": "{23,89}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3856", - "examine": "I can summon a geyser titan familiar with this.", - "durability": null, - "name": "Geyser titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12786" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3856", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Geyser titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12787" - }, - { - "requirements": "{23,83}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3840", - "examine": "I can summon a lava titan familiar with this.", - "durability": null, - "name": "Lava titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12788" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3840", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Lava titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12789" - }, - { - "requirements": "{23,99}", - "ge_buy_limit": "5000", - "grand_exchange_price": "5800", - "examine": "I can summon a steel titan familiar with this.", - "durability": null, - "name": "Steel titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12790" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "5800", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Steel titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12791" - }, - { - "requirements": "{23,73}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3436", - "examine": "I can summon an obsidian golem familiar with this.", - "durability": null, - "name": "Obsidian golem pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12792" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3436", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Obsidian golem pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12793" - }, - { - "requirements": "{23,77}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3017", - "examine": "I can summon a talon beast familiar with this.", - "durability": null, - "name": "Talon beast pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12794" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3017", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Talon beast pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12795" - }, - { - "requirements": "{23,93}", - "ge_buy_limit": "5000", - "grand_exchange_price": "2991", - "examine": "I can summon an abyssal titan familiar with this.", - "durability": null, - "name": "Abyssal titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12796" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "2991", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Abyssal titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12797" - }, - { - "requirements": "{23,34}", - "ge_buy_limit": "5000", - "grand_exchange_price": "18300", - "examine": "I can summon a void torcher familiar with this.", - "durability": null, - "name": "Void torcher pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12798" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "18300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Void torcher pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12799" - }, - { - "requirements": "{23,29}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1513", - "examine": "I can summon a giant chinchompa familiar with this.", - "durability": null, - "name": "Giant chinchompa pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12800" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1513", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Giant chinchompa pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12801" - }, - { - "requirements": "{23,79}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3567", - "examine": "I can summon a fire titan familiar with this.", - "durability": null, - "name": "Fire titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12802" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3567", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Fire titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12803" - }, - { - "requirements": "{23,79}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3548", - "examine": "I can summon a moss titan familiar with this.", - "durability": null, - "name": "Moss titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12804" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3548", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Moss titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12805" - }, - { - "requirements": "{23,79}", - "ge_buy_limit": "5000", - "grand_exchange_price": "7184", - "examine": "I can summon an ice titan familiar with this.", - "durability": null, - "name": "Ice titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12806" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "7184", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ice titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12807" - }, - { - "requirements": "{22,23}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1116", - "examine": "I can summon a spirit Tz-Kih familiar with this.", - "durability": null, - "name": "Spirit tz-kih pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12808" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1116", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit tz-kih pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12809" - }, - { - "requirements": "{23,57}", - "ge_buy_limit": "5000", - "grand_exchange_price": "7919", - "examine": "I can summon a spirit graahk familiar with this.", - "durability": null, - "name": "Spirit graahk pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12810" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "7919", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit graahk pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12811" - }, - { - "requirements": "{23,57}", - "ge_buy_limit": "5000", - "grand_exchange_price": "13300", - "examine": "I can summon a spirit kyatt familiar with this.", - "durability": null, - "name": "Spirit kyatt pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12812" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "13300", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Spirit kyatt pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12813" - }, - { - "requirements": "{23,34}", - "ge_buy_limit": "5000", - "grand_exchange_price": "18600", - "examine": "I can summon a void shifter familiar with this.", - "durability": null, - "name": "Void shifter pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12814" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "18600", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Void shifter pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12815" - }, - { - "requirements": "{23,46}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1951", - "examine": "I can summon a pyrelord familiar with this.", - "durability": null, - "name": "Pyrelord pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12816" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1951", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Pyrelord pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12817" - }, - { - "requirements": "{23,34}", - "ge_buy_limit": "5000", - "grand_exchange_price": "10700", - "examine": "I can summon a void ravager familiar with this.", - "durability": null, - "name": "Void ravager pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12818" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "10700", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Void ravager pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12819" - }, - { - "requirements": "{23,70}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1382", - "examine": "I can summon a ravenous locust familiar with this.", - "durability": null, - "name": "Ravenous locust pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12820" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "1382", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Ravenous locust pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12821" - }, - { - "requirements": "{23,95}", - "ge_buy_limit": "5000", - "grand_exchange_price": "3470", - "examine": "I can summon an iron titan familiar with this.", - "durability": null, - "name": "Iron titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12822" - }, - { - "ge_buy_limit": "5000", - "grand_exchange_price": "3470", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Iron titan pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12823" - }, - { - "requirements": "{23,79}", - "ge_buy_limit": "5000", - "grand_exchange_price": "380", - "examine": "A scroll for an elemental titan familiar.", - "durability": null, - "name": "Titan's con. scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12824" - }, - { - "requirements": "{23,99}", - "ge_buy_limit": "5000", - "grand_exchange_price": "646", - "examine": "A scroll for a steel titan familiar.", - "durability": null, - "name": "Steel of legends scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12825" - }, - { - "requirements": "{23,73}", - "ge_buy_limit": "5000", - "grand_exchange_price": "271", - "examine": "A scroll for an obsidian golem familiar.", - "durability": null, - "name": "Volcanic str. scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12826" - }, - { - "requirements": "{23,93}", - "ge_buy_limit": "5000", - "grand_exchange_price": "310", - "examine": "A scroll for an abyssal titan familiar.", - "durability": null, - "name": "Essence shipment scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12827" - }, - { - "requirements": "{23,95}", - "ge_buy_limit": "5000", - "grand_exchange_price": "389", - "examine": "A scroll for an iron titan familiar.", - "durability": null, - "name": "Iron within scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12828" - }, - { - "requirements": "{23,46}", - "ge_buy_limit": "5000", - "grand_exchange_price": "146", - "examine": "A scroll for a pyrelord familiar.", - "durability": null, - "name": "Immense heat scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12829" - }, - { - "requirements": "{23,70}", - "ge_buy_limit": "5000", - "grand_exchange_price": "149", - "examine": "A scroll for a ravenous locust familiar.", - "durability": null, - "name": "Famine scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12830" - }, - { - "requirements": "{23,77}", - "ge_buy_limit": "5000", - "grand_exchange_price": "245", - "examine": "A scroll for a talon beast familiar.", - "durability": null, - "name": "Deadly claw scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12831" - }, - { "requirements": "{23,85}", - "ge_buy_limit": "5000", - "grand_exchange_price": "192", - "examine": "A scroll for a swamp titan familiar.", - "durability": null, - "name": "Swamp plague scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12832" + "tradeable": "true" }, { - "requirements": "{23,89}", - "ge_buy_limit": "5000", - "grand_exchange_price": "294", - "examine": "A scroll for a geyser titan familiar.", - "durability": null, - "name": "Boil scroll", - "tradeable": "true", + "id": "12777", + "name": "Swamp titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "id": "12833" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,29}", - "ge_buy_limit": "5000", - "grand_exchange_price": "103", - "examine": "A scroll for a giant chinchompa familiar.", - "durability": null, - "name": "Explode scroll", - "tradeable": "true", + "id": "12778", + "name": "Spirit mosquito pouch", + "examine": "I can summon a spirit mosquito familiar with this.", "archery_ticket_price": "0", - "id": "12834" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{17,23}", + "tradeable": "true" }, { - "requirements": "{23,57}", - "ge_buy_limit": "5000", - "grand_exchange_price": "250", - "examine": "A scroll for a spirit graahk familiar.", - "durability": null, - "name": "Goad scroll", - "tradeable": "true", + "id": "12779", + "name": "Spirit mosquito pouch", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "id": "12835" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,57}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1428", - "examine": "A scroll for a spirit kyatt familiar.", - "durability": null, - "name": "Ambush scroll", - "tradeable": "true", + "id": "12780", + "name": "Void spinner pouch", + "examine": "I can summon a void spinner familiar with this.", "archery_ticket_price": "0", - "id": "12836" + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,34}", + "tradeable": "true" }, { - "requirements": "{23,83}", - "ge_buy_limit": "5000", - "grand_exchange_price": "300", - "examine": "A scroll for a lava titan familiar.", - "durability": null, - "name": "Ebon thunder scroll", - "tradeable": "true", + "id": "12781", + "name": "Void spinner pouch", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "id": "12837" + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" }, { - "requirements": "{23,17}", - "ge_buy_limit": "5000", - "grand_exchange_price": "1", - "examine": "A scroll for a spirit mosquito familiar.", - "durability": null, - "name": "Pester scroll", - "tradeable": "true", + "id": "12782", + "name": "Forge regent pouch", + "examine": "I can summon a forge regent familiar with this.", "archery_ticket_price": "0", - "id": "12838" - }, - { - "requirements": "{23,22}", - "ge_buy_limit": "5000", - "grand_exchange_price": "78", - "examine": "A scroll for a spirit Tz-Kih familiar.", "durability": null, - "name": "Fireball assault scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12839" - }, - { - "requirements": "{23,57}", "ge_buy_limit": "5000", - "grand_exchange_price": "196", - "examine": "A scroll for a spirit larupia familiar.", - "durability": null, - "name": "Rending scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12840" - }, - { "requirements": "{23,76}", - "ge_buy_limit": "5000", - "grand_exchange_price": "173", - "examine": "A scroll for a forge regent familiar.", - "durability": null, - "name": "Inferno scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12841" + "tradeable": "true" }, { - "turn90cw_anim": "8963", - "stand_anim": "8964", - "walk_anim": "8961", - "durability": null, - "name": "Gnomecopter", - "run_anim": "8963", + "id": "12783", + "name": "Forge regent pouch", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", - "turn90ccw_anim": "8963", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12784", + "name": "Spirit larupia pouch", + "examine": "I can summon a spirit larupia familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,57}", + "tradeable": "true" + }, + { + "id": "12785", + "name": "Spirit larupia pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12786", + "name": "Geyser titan pouch", + "examine": "I can summon a geyser titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,89}", + "tradeable": "true" + }, + { + "id": "12787", + "name": "Geyser titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12788", + "name": "Lava titan pouch", + "examine": "I can summon a lava titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,83}", + "tradeable": "true" + }, + { + "id": "12789", + "name": "Lava titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12790", + "name": "Steel titan pouch", + "examine": "I can summon a steel titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,99}", + "tradeable": "true" + }, + { + "id": "12791", + "name": "Steel titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12792", + "name": "Obsidian golem pouch", + "examine": "I can summon an obsidian golem familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,73}", + "tradeable": "true" + }, + { + "id": "12793", + "name": "Obsidian golem pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12794", + "name": "Talon beast pouch", + "examine": "I can summon a talon beast familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,77}", + "tradeable": "true" + }, + { + "id": "12795", + "name": "Talon beast pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12796", + "name": "Abyssal titan pouch", + "examine": "I can summon an abyssal titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,93}", + "tradeable": "true" + }, + { + "id": "12797", + "name": "Abyssal titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12798", + "name": "Void torcher pouch", + "examine": "I can summon a void torcher familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,34}", + "tradeable": "true" + }, + { + "id": "12799", + "name": "Void torcher pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12800", + "name": "Giant chinchompa pouch", + "examine": "I can summon a giant chinchompa familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,29}", + "tradeable": "true" + }, + { + "id": "12801", + "name": "Giant chinchompa pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12802", + "name": "Fire titan pouch", + "examine": "I can summon a fire titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,79}", + "tradeable": "true" + }, + { + "id": "12803", + "name": "Fire titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12804", + "name": "Moss titan pouch", + "examine": "I can summon a moss titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,79}", + "tradeable": "true" + }, + { + "id": "12805", + "name": "Moss titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12806", + "name": "Ice titan pouch", + "examine": "I can summon an ice titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,79}", + "tradeable": "true" + }, + { + "id": "12807", + "name": "Ice titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12808", + "name": "Spirit tz-kih pouch", + "examine": "I can summon a spirit Tz-Kih familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{22,23}", + "tradeable": "true" + }, + { + "id": "12809", + "name": "Spirit tz-kih pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12810", + "name": "Spirit graahk pouch", + "examine": "I can summon a spirit graahk familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,57}", + "tradeable": "true" + }, + { + "id": "12811", + "name": "Spirit graahk pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12812", + "name": "Spirit kyatt pouch", + "examine": "I can summon a spirit kyatt familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,57}", + "tradeable": "true" + }, + { + "id": "12813", + "name": "Spirit kyatt pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12814", + "name": "Void shifter pouch", + "examine": "I can summon a void shifter familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,34}", + "tradeable": "true" + }, + { + "id": "12815", + "name": "Void shifter pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12816", + "name": "Pyrelord pouch", + "examine": "I can summon a pyrelord familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,46}", + "tradeable": "true" + }, + { + "id": "12817", + "name": "Pyrelord pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12818", + "name": "Void ravager pouch", + "examine": "I can summon a void ravager familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,34}", + "tradeable": "true" + }, + { + "id": "12819", + "name": "Void ravager pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12820", + "name": "Ravenous locust pouch", + "examine": "I can summon a ravenous locust familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,70}", + "tradeable": "true" + }, + { + "id": "12821", + "name": "Ravenous locust pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12822", + "name": "Iron titan pouch", + "examine": "I can summon an iron titan familiar with this.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,95}", + "tradeable": "true" + }, + { + "id": "12823", + "name": "Iron titan pouch", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "tradeable": "true" + }, + { + "id": "12824", + "name": "Titan's con. scroll", + "examine": "A scroll for an elemental titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,79}", + "tradeable": "true" + }, + { + "id": "12825", + "name": "Steel of legends scroll", + "examine": "A scroll for a steel titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,99}", + "tradeable": "true" + }, + { + "id": "12826", + "name": "Volcanic str. scroll", + "examine": "A scroll for an obsidian golem familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,73}", + "tradeable": "true" + }, + { + "id": "12827", + "name": "Essence shipment scroll", + "examine": "A scroll for an abyssal titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,93}", + "tradeable": "true" + }, + { + "id": "12828", + "name": "Iron within scroll", + "examine": "A scroll for an iron titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,95}", + "tradeable": "true" + }, + { + "id": "12829", + "name": "Immense heat scroll", + "examine": "A scroll for a pyrelord familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,46}", + "tradeable": "true" + }, + { + "id": "12830", + "name": "Famine scroll", + "examine": "A scroll for a ravenous locust familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,70}", + "tradeable": "true" + }, + { + "id": "12831", + "name": "Deadly claw scroll", + "examine": "A scroll for a talon beast familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,77}", + "tradeable": "true" + }, + { + "id": "12832", + "name": "Swamp plague scroll", + "examine": "A scroll for a swamp titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,85}", + "tradeable": "true" + }, + { + "id": "12833", + "name": "Boil scroll", + "examine": "A scroll for a geyser titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,89}", + "tradeable": "true" + }, + { + "id": "12834", + "name": "Explode scroll", + "examine": "A scroll for a giant chinchompa familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,29}", + "tradeable": "true" + }, + { + "id": "12835", + "name": "Goad scroll", + "examine": "A scroll for a spirit graahk familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,57}", + "tradeable": "true" + }, + { + "id": "12836", + "name": "Ambush scroll", + "examine": "A scroll for a spirit kyatt familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,57}", + "tradeable": "true" + }, + { + "id": "12837", + "name": "Ebon thunder scroll", + "examine": "A scroll for a lava titan familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,83}", + "tradeable": "true" + }, + { + "id": "12838", + "name": "Pester scroll", + "examine": "A scroll for a spirit mosquito familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,17}", + "tradeable": "true" + }, + { + "id": "12839", + "name": "Fireball assault scroll", + "examine": "A scroll for a spirit Tz-Kih familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,22}", + "tradeable": "true" + }, + { + "id": "12840", + "name": "Rending scroll", + "examine": "A scroll for a spirit larupia familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,57}", + "tradeable": "true" + }, + { + "id": "12841", + "name": "Inferno scroll", + "examine": "A scroll for a forge regent familiar.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "5000", + "requirements": "{23,76}", + "tradeable": "true" + }, + { "id": "12842", + "name": "Gnomecopter", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "1", + "run_anim": "8963", + "stand_anim": "8964", "stand_turn_anim": "8963", "turn180_anim": "8963", - "equipment_slot": "1" + "turn90ccw_anim": "8963", + "turn90cw_anim": "8963", + "walk_anim": "8961" }, { - "destroy_message": "This is for use with the gnomecopters, north of Lumbridge. Sasquine Huburns will give you another one.", - "examine": "It tells gnomecopters where you wish to go.", - "durability": null, + "id": "12843", "name": "Gnomecopter ticket", - "tradeable": "false", - "destroy": "true", + "examine": "It tells gnomecopters where you wish to go.", "archery_ticket_price": "0", - "id": "12843" + "destroy": "true", + "destroy_message": "This is for use with the gnomecopters, north of Lumbridge. Sasquine Huburns will give you another one.", + "durability": null, + "tradeable": "false" }, { - "shop_price": "100", - "turn90cw_anim": "8983", - "examine": "A kite with a dragon on it.", - "walk_anim": "8982", - "durability": null, - "turn90ccw_anim": "8984", - "attack_speed": "4", - "turn180_anim": "8985", - "render_anim": "593", - "equipment_slot": "3", - "stand_anim": "8981", - "name": "Toy kite", - "run_anim": "8986", - "archery_ticket_price": "0", "id": "12844", - "stand_turn_anim": "8987" + "name": "Toy kite", + "examine": "A kite with a dragon on it.", + "archery_ticket_price": "0", + "attack_speed": "4", + "durability": null, + "equipment_slot": "3", + "render_anim": "593", + "run_anim": "8986", + "shop_price": "100", + "stand_anim": "8981", + "stand_turn_anim": "8987", + "turn180_anim": "8985", + "turn90ccw_anim": "8984", + "turn90cw_anim": "8983", + "walk_anim": "8982" }, { - "turn90cw_anim": "9002", - "examine": "A stone used to gather energy.", - "walk_anim": "8997", - "durability": null, - "destroy": "true", - "weight": "30", - "turn90ccw_anim": "9003", - "turn180_anim": "9001", - "render_anim": "370", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "8998", - "name": "Stone of power", - "tradeable": "false", - "run_anim": "9004", - "archery_ticket_price": "0", "id": "12845", - "stand_turn_anim": "9000" + "name": "Stone of power", + "examine": "A stone used to gather energy.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "render_anim": "370", + "run_anim": "9004", + "stand_anim": "8998", + "stand_turn_anim": "9000", + "tradeable": "false", + "turn180_anim": "9001", + "turn90ccw_anim": "9003", + "turn90cw_anim": "9002", + "walk_anim": "8997", + "weight": "30" }, { - "turn90cw_anim": "9002", - "examine": "A stone used to gather energy.", - "walk_anim": "8997", - "durability": null, - "destroy": "true", - "weight": "30", - "turn90ccw_anim": "9003", - "turn180_anim": "9001", - "render_anim": "370", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "8998", - "name": "Stone of power", - "tradeable": "false", - "run_anim": "9004", - "archery_ticket_price": "0", "id": "12846", - "stand_turn_anim": "9000" + "name": "Stone of power", + "examine": "A stone used to gather energy.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "render_anim": "370", + "run_anim": "9004", + "stand_anim": "8998", + "stand_turn_anim": "9000", + "tradeable": "false", + "turn180_anim": "9001", + "turn90ccw_anim": "9003", + "turn90cw_anim": "9002", + "walk_anim": "8997", + "weight": "30" }, { - "turn90cw_anim": "9002", - "examine": "A stone used to gather energy.", - "walk_anim": "8997", - "durability": null, - "destroy": "true", - "weight": "30", - "turn90ccw_anim": "9003", - "turn180_anim": "9001", - "render_anim": "370", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "8998", - "name": "Stone of power", - "tradeable": "false", - "run_anim": "9004", - "archery_ticket_price": "0", "id": "12847", - "stand_turn_anim": "9000" + "name": "Stone of power", + "examine": "A stone used to gather energy.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "render_anim": "370", + "run_anim": "9004", + "stand_anim": "8998", + "stand_turn_anim": "9000", + "tradeable": "false", + "turn180_anim": "9001", + "turn90ccw_anim": "9003", + "turn90cw_anim": "9002", + "walk_anim": "8997", + "weight": "30" }, { - "turn90cw_anim": "9002", - "examine": "A stone used to gather energy.", - "walk_anim": "8997", - "durability": null, - "destroy": "true", - "weight": "30", - "turn90ccw_anim": "9003", - "turn180_anim": "9001", - "render_anim": "370", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "8998", - "name": "Stone of power", - "tradeable": "false", - "run_anim": "9004", - "archery_ticket_price": "0", "id": "12848", - "stand_turn_anim": "9000" - }, - { - "turn90cw_anim": "9002", - "examine": "A stone used to gather energy.", - "walk_anim": "8997", - "durability": null, - "destroy": "true", - "weight": "30", - "turn90ccw_anim": "9003", - "turn180_anim": "9001", - "render_anim": "370", - "equipment_slot": "3", - "destroy_message": "You can reclaim this item from the place you found it.", - "stand_anim": "8998", "name": "Stone of power", - "tradeable": "false", + "examine": "A stone used to gather energy.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "render_anim": "370", "run_anim": "9004", - "archery_ticket_price": "0", + "stand_anim": "8998", + "stand_turn_anim": "9000", + "tradeable": "false", + "turn180_anim": "9001", + "turn90ccw_anim": "9003", + "turn90cw_anim": "9002", + "walk_anim": "8997", + "weight": "30" + }, + { "id": "12849", - "stand_turn_anim": "9000" + "name": "Stone of power", + "examine": "A stone used to gather energy.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "3", + "render_anim": "370", + "run_anim": "9004", + "stand_anim": "8998", + "stand_turn_anim": "9000", + "tradeable": "false", + "turn180_anim": "9001", + "turn90ccw_anim": "9003", + "turn90cw_anim": "9002", + "walk_anim": "8997", + "weight": "30" }, { - "examine": "A generic elemental rune", - "durability": null, + "id": "12850", "name": "Elemental rune", + "examine": "A generic elemental rune", "archery_ticket_price": "0", - "id": "12850" + "durability": null }, { - "examine": "A generic non-elemental rune", - "durability": null, + "id": "12851", "name": "Catalytic rune", + "examine": "A generic non-elemental rune", "archery_ticket_price": "0", - "id": "12851" + "durability": null }, { - "examine": "A token awarded for taking part in the Fist of Guthix minigame.", - "durability": null, + "id": "12852", "name": "Fist of guthix token", + "examine": "A token awarded for taking part in the Fist of Guthix minigame.", "archery_ticket_price": "0", - "id": "12852" + "durability": null }, { - "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "A box of bandages for healing.", - "durability": null, + "id": "12853", "name": "Bandages", - "tradeable": "true", + "examine": "A box of bandages for healing.", "archery_ticket_price": "0", - "id": "12853" - }, - { "destroy_message": "You can reclaim this item from the place you found it.", - "examine": "Teleports you to the centre of the arena.", "durability": null, - "name": "Tele-orb", - "archery_ticket_price": "0", - "id": "12855" + "tradeable": "true" }, { + "id": "12855", + "name": "Tele-orb", + "examine": "Teleports you to the centre of the arena.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null + }, + { + "id": "12856", + "name": "Irit gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{15,50}", "shop_price": "75", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Irit gloves", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12856", - "equipment_slot": "9" + "tradeable": "false" }, { + "id": "12857", + "name": "Avantoe gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{15,60}", "shop_price": "100", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Avantoe gloves", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12857", - "equipment_slot": "9" + "tradeable": "false" }, { + "id": "12858", + "name": "Kwuarm gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{15,70}", "shop_price": "200", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Kwuarm gloves", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12858", - "equipment_slot": "9" + "tradeable": "false" }, { + "id": "12859", + "name": "Cadantine gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{15,80}", "shop_price": "200", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Cadantine gloves", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12859", - "equipment_slot": "9" + "tradeable": "false" }, { + "id": "12860", + "name": "Swordfish gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{10,65}", "shop_price": "200", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Swordfish gloves", "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "12860", - "equipment_slot": "9" + "weight": "1" }, { + "id": "12861", + "name": "Shark gloves", + "examine": "A pair of mystical gloves", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{10,90}", "shop_price": "200", - "examine": "A pair of mystical gloves", - "durability": null, - "name": "Shark gloves", "tradeable": "false", - "weight": "1", - "archery_ticket_price": "0", - "id": "12861", - "equipment_slot": "9" + "weight": "1" }, { + "id": "12862", + "name": "Dragon slayer gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "equipment_slot": "9", "requirements": "{18,70}", "shop_price": "200", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Dragon slayer gloves", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12862", - "equipment_slot": "9" + "tradeable": "false" }, { + "id": "12863", + "name": "Air runecrafting gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can buy a new pair from the druids at the Fist of Guthix activity.", + "durability": null, + "equipment_slot": "9", "requirements": "{20,10}", "shop_price": "75", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Air runecrafting gloves", "tradeable": "false", - "weight": "1", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12863", - "equipment_slot": "9" + "weight": "1" }, { + "id": "12864", + "name": "Water runecrafting gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can buy a new pair from the druids at the Fist of Guthix activity.", + "durability": null, + "equipment_slot": "9", "requirements": "{20,20}", "shop_price": "75", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Water runecrafting gloves", "tradeable": "false", - "weight": "1", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12864", - "equipment_slot": "9" + "weight": "1" }, { + "id": "12865", + "name": "Earth runecrafting gloves", + "examine": "A pair of mystical gloves.", + "archery_ticket_price": "0", + "destroy": "true", "destroy_message": "You can buy a new pair from the druids at the Fist of Guthix minigame.", + "durability": null, + "equipment_slot": "9", "requirements": "{20,30}", "shop_price": "75", - "examine": "A pair of mystical gloves.", - "durability": null, - "name": "Earth runecrafting gloves", "tradeable": "false", - "weight": "1", - "destroy": "true", - "archery_ticket_price": "0", - "id": "12865", - "equipment_slot": "9" + "weight": "1" }, { - "remove_head": "true", - "requirements": "{1,50}-{6,60}", - "shop_price": "250", - "examine": "Its arcane power is waning.", - "durability": null, - "absorb": "4,3,0", - "equipment_slot": "0", - "grand_exchange_price": "70529", - "name": "Battle hood 100", - "tradeable": "false", - "archery_ticket_price": "0", "id": "12866", - "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" - }, - { + "name": "Battle hood 100", + "examine": "Its arcane power is waning.", + "absorb": "4,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,50}-{6,60}", "shop_price": "250", - "examine": "Its arcane power is waning.", - "durability": null, - "absorb": "4,3,0", - "equipment_slot": "0", - "grand_exchange_price": "70529", - "name": "Battle hood 80", - "tradeable": "false", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "12867", - "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" - }, - { + "name": "Battle hood 80", + "examine": "Its arcane power is waning.", + "absorb": "4,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,50}-{6,60}", "shop_price": "250", - "examine": "Its arcane power is waning.", - "durability": null, - "absorb": "4,3,0", - "equipment_slot": "0", - "grand_exchange_price": "70529", - "name": "Battle hood 60", - "tradeable": "false", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "12868", - "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" - }, - { + "name": "Battle hood 60", + "examine": "Its arcane power is waning.", + "absorb": "4,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,50}-{6,60}", "shop_price": "250", - "examine": "Its arcane power is waning.", - "durability": null, - "absorb": "4,3,0", - "equipment_slot": "0", - "grand_exchange_price": "70529", - "name": "Battle hood 40", - "tradeable": "false", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "12869", - "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" - }, - { + "name": "Battle hood 40", + "examine": "Its arcane power is waning.", + "absorb": "4,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,50}-{6,60}", "shop_price": "250", - "examine": "Its arcane power is waning.", - "durability": null, - "absorb": "4,3,0", - "equipment_slot": "0", - "grand_exchange_price": "70529", - "name": "Battle hood 20", - "tradeable": "false", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "12870", - "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" - }, - { + "name": "Battle hood 20", + "examine": "Its arcane power is waning.", + "absorb": "4,3,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,50}-{6,60}", "shop_price": "250", - "ge_buy_limit": "10", - "examine": "Its arcane power is waning.", - "durability": null, - "absorb": "4,3,0", - "equipment_slot": "0", - "grand_exchange_price": "78900", - "name": "Battle hood 0", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "12871", - "bonuses": "0,0,0,2,0,3,2,3,2,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "78900", - "durability": null, "name": "Battle hood 0", - "tradeable": "true", + "examine": "Its arcane power is waning.", + "absorb": "4,3,0", "archery_ticket_price": "0", - "id": "12872" + "bonuses": "0,0,0,2,0,3,2,3,2,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "tradeable": "true" }, { - "requirements": "{1,50}-{6,60}", - "shop_price": "1500", - "examine": "A robe top infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "4", - "absorb": "8,4,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "537714", - "name": "Battle robe top 100", - "tradeable": "false", + "id": "12872", + "name": "Battle hood 0", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12873", - "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1500", + "name": "Battle robe top 100", "examine": "A robe top infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "4", "absorb": "8,4,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "537714", - "name": "Battle robe top 80", + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12874", - "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1500", + "name": "Battle robe top 80", "examine": "A robe top infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "4", "absorb": "8,4,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "537714", - "name": "Battle robe top 60", + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12875", - "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1500", + "name": "Battle robe top 60", "examine": "A robe top infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "4", "absorb": "8,4,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "537714", - "name": "Battle robe top 40", + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12876", - "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1500", + "name": "Battle robe top 40", "examine": "A robe top infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "4", "absorb": "8,4,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "537714", - "name": "Battle robe top 20", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12877", - "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" - }, - { "requirements": "{1,50}-{6,60}", "shop_price": "1500", - "ge_buy_limit": "10", - "examine": "Its arcane power is waning.", - "durability": null, - "weight": "4", + "tradeable": "false", + "weight": "4" + }, + { + "id": "12877", + "name": "Battle robe top 20", + "examine": "A robe top infused with arcane power, especially created for combat spells.", "absorb": "8,4,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "431400", - "name": "Battle robe top 0", - "tradeable": "true", - "archery_ticket_price": "0", + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "tradeable": "false", + "weight": "4" + }, + { "id": "12878", - "bonuses": "0,0,0,7,0,4,4,5,7,0,8,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "431400", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, "name": "Battle robe top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12879" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1000", - "examine": "A robe bottom infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "5,2,0", - "equipment_slot": "7", - "grand_exchange_price": "364878", - "name": "Battle robe bottom 100", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12880", - "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1000", - "examine": "A robe bottom infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "5,2,0", - "equipment_slot": "7", - "grand_exchange_price": "364878", - "name": "Battle robe bottom 80", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12881", - "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1000", - "examine": "A robe bottom infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "5,2,0", - "equipment_slot": "7", - "grand_exchange_price": "364878", - "name": "Battle robe bottom 60", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12882", - "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1000", - "examine": "A robe bottom infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "5,2,0", - "equipment_slot": "7", - "grand_exchange_price": "364878", - "name": "Battle robe bottom 40", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12883", - "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1000", - "examine": "A robe bottom infused with arcane power, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "5,2,0", - "equipment_slot": "7", - "grand_exchange_price": "364878", - "name": "Battle robe bottom 20", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12884", - "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" - }, - { - "requirements": "{1,50}-{6,60}", - "shop_price": "1000", - "ge_buy_limit": "10", "examine": "Its arcane power is waning.", - "durability": null, - "weight": "3", - "absorb": "5,2,0", - "equipment_slot": "7", - "grand_exchange_price": "538000", - "name": "Battle robe bottom 0", - "tradeable": "true", + "absorb": "8,4,0", "archery_ticket_price": "0", - "id": "12885", - "bonuses": "0,0,0,6,0,4,3,4,6,0,7,0,0,0,0" + "bonuses": "0,0,0,7,0,4,4,5,7,0,8,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "tradeable": "true", + "weight": "4" }, { - "ge_buy_limit": "10", - "grand_exchange_price": "538000", + "id": "12879", + "name": "Battle robe top 0", "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "12880", + "name": "Battle robe bottom 100", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12881", + "name": "Battle robe bottom 80", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12882", + "name": "Battle robe bottom 60", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12883", + "name": "Battle robe bottom 40", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12884", + "name": "Battle robe bottom 20", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "absorb": "5,2,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12885", "name": "Battle robe bottom 0", - "tradeable": "true", + "examine": "Its arcane power is waning.", + "absorb": "5,2,0", "archery_ticket_price": "0", - "id": "12886" + "bonuses": "0,0,0,6,0,4,3,4,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "tradeable": "true", + "weight": "3" }, { - "remove_head": "true", - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "examine": "A worn-out hood, formerly worn by the followers of Guthix.", - "durability": null, - "weight": "7", - "equipment_slot": "0", - "grand_exchange_price": "6915", - "name": "Druidic mage hood 100", - "tradeable": "false", + "id": "12886", + "name": "Battle robe bottom 0", + "examine": "Swap this note at any bank for the equivalent item.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12887", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { + "name": "Druidic mage hood 100", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "100", - "examine": "A worn-out hood, formerly worn by the followers of Guthix.", - "durability": null, - "weight": "7", - "equipment_slot": "0", - "grand_exchange_price": "6915", - "name": "Druidic mage hood 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12888", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { + "name": "Druidic mage hood 80", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "100", - "examine": "A worn-out hood, formerly worn by the followers of Guthix.", - "durability": null, - "weight": "7", - "equipment_slot": "0", - "grand_exchange_price": "6915", - "name": "Druidic mage hood 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12889", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { + "name": "Druidic mage hood 60", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "100", - "examine": "A worn-out hood, formerly worn by the followers of Guthix.", - "durability": null, - "weight": "7", - "equipment_slot": "0", - "grand_exchange_price": "6915", - "name": "Druidic mage hood 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12890", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { + "name": "Druidic mage hood 40", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "100", - "examine": "A worn-out hood, formerly worn by the followers of Guthix.", - "durability": null, - "weight": "7", - "equipment_slot": "0", - "grand_exchange_price": "6915", - "name": "Druidic mage hood 20", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12891", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "ge_buy_limit": "10", + "name": "Druidic mage hood 20", "examine": "A worn-out hood, formerly worn by the followers of Guthix.", - "durability": null, - "weight": "7", - "equipment_slot": "0", - "grand_exchange_price": "8504", - "name": "Druidic mage hood 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "false", + "weight": "7" + }, + { "id": "12892", - "bonuses": "0,0,0,1,0,0,0,0,1,0,1,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "8504", - "durability": null, "name": "Druidic mage hood 0", - "tradeable": "true", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", "archery_ticket_price": "0", - "id": "12893" + "bonuses": "0,0,0,1,0,0,0,0,1,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "10", + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "true", + "weight": "7" }, { - "requirements": "{1,10}-{6,20}", - "shop_price": "300", - "examine": "A magical robe top worn by followers of Guthix.", - "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "80273", - "name": "Druidic mage top 100", - "tradeable": "false", + "id": "12893", + "name": "Druidic mage hood 0", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12894", - "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "300", + "name": "Druidic mage top 100", "examine": "A magical robe top worn by followers of Guthix.", - "durability": null, - "weight": "4", "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "80273", - "name": "Druidic mage top 80", + "requirements": "{1,10}-{6,20}", + "shop_price": "300", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12895", - "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "300", + "name": "Druidic mage top 80", "examine": "A magical robe top worn by followers of Guthix.", - "durability": null, - "weight": "4", "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "80273", - "name": "Druidic mage top 60", + "requirements": "{1,10}-{6,20}", + "shop_price": "300", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12896", - "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "300", + "name": "Druidic mage top 60", "examine": "A magical robe top worn by followers of Guthix.", - "durability": null, - "weight": "4", "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "80273", - "name": "Druidic mage top 40", + "requirements": "{1,10}-{6,20}", + "shop_price": "300", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12897", - "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "300", + "name": "Druidic mage top 40", "examine": "A magical robe top worn by followers of Guthix.", - "durability": null, - "weight": "4", "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "80273", - "name": "Druidic mage top 20", + "requirements": "{1,10}-{6,20}", + "shop_price": "300", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12898", - "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "300", - "ge_buy_limit": "10", + "name": "Druidic mage top 20", "examine": "A magical robe top worn by followers of Guthix.", - "durability": null, - "weight": "4", "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0", + "durability": null, "equipment_slot": "4", "remove_sleeves": "true", - "grand_exchange_price": "76300", - "name": "Druidic mage top 0", - "tradeable": "true", - "archery_ticket_price": "0", + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "tradeable": "false", + "weight": "4" + }, + { "id": "12899", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "76300", - "durability": null, "name": "Druidic mage top 0", - "tradeable": "true", + "examine": "A magical robe top worn by followers of Guthix.", + "absorb": "2,1,0", "archery_ticket_price": "0", - "id": "12900" + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,10}-{6,20}", - "shop_price": "200", - "examine": "A magical robe bottom worn by a person who follows Guthix.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "54532", - "name": "Druidic mage bottom 100", - "tradeable": "false", + "id": "12900", + "name": "Druidic mage top 0", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12901", - "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" - }, - { + "name": "Druidic mage bottom 100", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0", + "durability": null, + "equipment_slot": "7", "requirements": "{1,10}-{6,20}", "shop_price": "200", - "examine": "A magical robe bottom worn by a person who follows Guthix.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "54532", - "name": "Druidic mage bottom 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "3" + }, + { "id": "12902", - "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" - }, - { + "name": "Druidic mage bottom 80", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0", + "durability": null, + "equipment_slot": "7", "requirements": "{1,10}-{6,20}", "shop_price": "200", - "examine": "A magical robe bottom worn by a person who follows Guthix.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "54532", - "name": "Druidic mage bottom 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "3" + }, + { "id": "12903", - "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" - }, - { + "name": "Druidic mage bottom 60", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0", + "durability": null, + "equipment_slot": "7", "requirements": "{1,10}-{6,20}", "shop_price": "200", - "examine": "A magical robe bottom worn by a person who follows Guthix.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "54532", - "name": "Druidic mage bottom 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "3" + }, + { "id": "12904", - "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" - }, - { + "name": "Druidic mage bottom 40", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0", + "durability": null, + "equipment_slot": "7", "requirements": "{1,10}-{6,20}", "shop_price": "200", - "examine": "A magical robe bottom worn by a person who follows Guthix.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "54532", - "name": "Druidic mage bottom 20", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "3" + }, + { "id": "12905", - "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "200", - "ge_buy_limit": "10", + "name": "Druidic mage bottom 20", "examine": "A magical robe bottom worn by a person who follows Guthix.", - "durability": null, - "weight": "3", "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "60800", - "name": "Druidic mage bottom 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "tradeable": "false", + "weight": "3" + }, + { "id": "12906", - "bonuses": "0,0,0,2,0,0,0,0,2,0,2,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "60800", - "durability": null, "name": "Druidic mage bottom 0", - "tradeable": "true", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "absorb": "1,0,0", "archery_ticket_price": "0", - "id": "12907" + "bonuses": "0,0,0,2,0,0,0,0,2,0,2,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "tradeable": "true", + "weight": "3" }, { - "requirements": "{1,35}", - "shop_price": "50", - "examine": "A spiked square shield.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2271", - "name": "Adamant spikeshield 100", - "tradeable": "false", + "id": "12907", + "name": "Druidic mage bottom 0", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12908", - "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" - }, - { + "name": "Adamant spikeshield 100", + "examine": "A spiked square shield.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "50", - "examine": "A spiked square shield.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2271", - "name": "Adamant spikeshield 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "5" + }, + { "id": "12909", - "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" - }, - { + "name": "Adamant spikeshield 80", + "examine": "A spiked square shield.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "50", - "examine": "A spiked square shield.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2271", - "name": "Adamant spikeshield 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "5" + }, + { "id": "12910", - "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" - }, - { + "name": "Adamant spikeshield 60", + "examine": "A spiked square shield.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "50", - "examine": "A spiked square shield.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2271", - "name": "Adamant spikeshield 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "5" + }, + { "id": "12911", - "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" - }, - { - "requirements": "{1,35}", - "shop_price": "50", + "name": "Adamant spikeshield 40", "examine": "A spiked square shield.", - "durability": null, - "weight": "5", "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2271", - "name": "Adamant spikeshield 20", - "tradeable": "false", "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,35}", + "shop_price": "50", + "tradeable": "false", + "weight": "5" + }, + { "id": "12912", - "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" - }, - { + "name": "Adamant spikeshield 20", + "examine": "A spiked square shield.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "50", - "ge_buy_limit": "100", - "examine": "Not so spiky anymore.", - "durability": null, - "weight": "5", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "2718", - "name": "Adamant spikeshield 0", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "false", + "weight": "5" + }, + { "id": "12913", - "bonuses": "0,0,0,-6,-2,11,12,10,0,11,4,1,0,0,0" - }, - { - "ge_buy_limit": "100", - "examine": "Not so spiky anymore!", - "grand_exchange_price": "2718", - "durability": null, "name": "Adamant spikeshield 0", - "tradeable": "true", + "examine": "Not so spiky anymore.", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "12914" + "bonuses": "0,0,0,-6,-2,11,12,10,0,11,4,1,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "100", + "requirements": "{1,35}", + "shop_price": "50", + "tradeable": "true", + "weight": "5" }, { - "requirements": "{1,35}", - "shop_price": "100", - "examine": "A large, spiked metal shield", - "durability": null, - "weight": "7", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "19190", - "name": "Adamant berserker shield 100", - "tradeable": "false", + "id": "12914", + "name": "Adamant spikeshield 0", + "examine": "Not so spiky anymore!", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12915", - "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" - }, - { + "name": "Adamant berserker shield 100", + "examine": "A large, spiked metal shield", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "100", - "examine": "A large, spiked metal shield", - "durability": null, - "weight": "7", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "19190", - "name": "Adamant berserker shield 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12916", - "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" - }, - { + "name": "Adamant berserker shield 80", + "examine": "A large, spiked metal shield", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "100", - "examine": "A large, spiked metal shield", - "durability": null, - "weight": "7", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "19190", - "name": "Adamant berserker shield 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12917", - "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" - }, - { + "name": "Adamant berserker shield 60", + "examine": "A large, spiked metal shield", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "100", - "examine": "A large, spiked metal shield", - "durability": null, - "weight": "7", - "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "19190", - "name": "Adamant berserker shield 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "7" + }, + { "id": "12918", - "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" - }, - { - "requirements": "{1,35}", - "shop_price": "100", + "name": "Adamant berserker shield 40", "examine": "A large, spiked metal shield", - "durability": null, - "weight": "7", "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "19190", - "name": "Adamant berserker shield 20", - "tradeable": "false", "archery_ticket_price": "0", - "id": "12919", - "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" - }, - { + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,35}", "shop_price": "100", - "ge_buy_limit": "10", - "examine": "Not so spiky anymore!", - "durability": null, - "weight": "7", + "tradeable": "false", + "weight": "7" + }, + { + "id": "12919", + "name": "Adamant berserker shield 20", + "examine": "A large, spiked metal shield", "absorb": "3,0,6", - "equipment_slot": "5", - "grand_exchange_price": "23700", - "name": "Adamant berserker shield 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,35}", + "shop_price": "100", + "tradeable": "false", + "weight": "7" + }, + { "id": "12920", - "bonuses": "0,0,0,-8,-2,12,14,13,-1,8,4,1,0,0,0" - }, - { - "ge_buy_limit": "10", - "examine": "Not so spiky anymore!", - "grand_exchange_price": "23700", - "durability": null, "name": "Adamant berserker shield 0", - "tradeable": "true", + "examine": "Not so spiky anymore!", + "absorb": "3,0,6", "archery_ticket_price": "0", - "id": "12921" + "bonuses": "0,0,0,-8,-2,12,14,13,-1,8,4,1,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", + "requirements": "{1,35}", + "shop_price": "100", + "tradeable": "true", + "weight": "7" }, { - "requirements": "{1,45}", - "shop_price": "200", - "examine": "A spiked, medium square shield.", - "durability": null, - "weight": "4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "57548", - "name": "Rune spikeshield 100", - "tradeable": "false", + "id": "12921", + "name": "Adamant berserker shield 0", + "examine": "Not so spiky anymore!", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12922", + "name": "Rune spikeshield 100", + "examine": "A spiked, medium square shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0", - "point_price": "35" - }, - { + "durability": null, + "equipment_slot": "5", + "point_price": "35", "requirements": "{1,45}", "shop_price": "200", - "examine": "A spiked, medium square shield.", - "durability": null, - "weight": "4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "57548", - "name": "Rune spikeshield 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12923", - "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" - }, - { + "name": "Rune spikeshield 80", + "examine": "A spiked, medium square shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,45}", "shop_price": "200", - "examine": "A spiked, medium square shield.", - "durability": null, - "weight": "4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "57548", - "name": "Rune spikeshield 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12924", - "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" - }, - { + "name": "Rune spikeshield 60", + "examine": "A spiked, medium square shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,45}", "shop_price": "200", - "examine": "A spiked, medium square shield.", - "durability": null, - "weight": "4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "57548", - "name": "Rune spikeshield 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "4" + }, + { "id": "12925", - "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" - }, - { - "requirements": "{1,45}", - "shop_price": "200", + "name": "Rune spikeshield 40", "examine": "A spiked, medium square shield.", - "durability": null, - "weight": "4", "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "57548", - "name": "Rune spikeshield 20", - "tradeable": "false", "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0", + "durability": null, + "equipment_slot": "5", + "requirements": "{1,45}", + "shop_price": "200", + "tradeable": "false", + "weight": "4" + }, + { "id": "12926", - "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" - }, - { + "name": "Rune spikeshield 20", + "examine": "A spiked, medium square shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,45}", "shop_price": "200", - "ge_buy_limit": "10", - "examine": "Not so spiky anymore.", - "durability": null, - "weight": "4", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "50500", - "name": "Rune spikeshield 0", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "false", + "weight": "4" + }, + { "id": "12927", - "bonuses": "0,0,0,-6,-2,14,15,13,0,14,8,2,0,0,0" - }, - { - "ge_buy_limit": "10", - "examine": "Not so spiky anymore.", - "grand_exchange_price": "50500", - "durability": null, "name": "Rune spikeshield 0", - "tradeable": "true", + "examine": "Not so spiky anymore.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "12928" + "bonuses": "0,0,0,-6,-2,14,15,13,0,14,8,2,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", + "requirements": "{1,45}", + "shop_price": "200", + "tradeable": "true", + "weight": "4" }, { - "requirements": "{1,45}", - "shop_price": "300", - "examine": "A Large, spiked metal shield.", - "durability": null, - "weight": "6", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "82000", - "name": "Rune berserker shield 100", - "tradeable": "false", + "id": "12928", + "name": "Rune spikeshield 0", + "examine": "Not so spiky anymore.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12929", + "name": "Rune berserker shield 100", + "examine": "A Large, spiked metal shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0", - "point_price": "35" - }, - { + "durability": null, + "equipment_slot": "5", + "point_price": "35", "requirements": "{1,45}", "shop_price": "300", - "examine": "A Large, spiked metal shield.", - "durability": null, - "weight": "6", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "82000", - "name": "Rune berserker shield 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "6" + }, + { "id": "12930", - "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" - }, - { + "name": "Rune berserker shield 80", + "examine": "A Large, spiked metal shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,45}", "shop_price": "300", - "examine": "A Large, spiked metal shield.", - "durability": null, - "weight": "6", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "82000", - "name": "Rune berserker shield 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "6" + }, + { "id": "12931", - "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" - }, - { + "name": "Rune berserker shield 60", + "examine": "A Large, spiked metal shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,45}", "shop_price": "300", - "examine": "A Large, spiked metal shield.", - "durability": null, - "weight": "6", - "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "82000", - "name": "Rune berserker shield 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "6" + }, + { "id": "12932", - "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" - }, - { - "requirements": "{1,45}", - "shop_price": "300", + "name": "Rune berserker shield 40", "examine": "A Large, spiked metal shield.", - "durability": null, - "weight": "6", "absorb": "3,0,7", - "equipment_slot": "5", - "grand_exchange_price": "82000", - "name": "Rune berserker shield 20", - "tradeable": "false", "archery_ticket_price": "0", - "id": "12933", - "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" - }, - { + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0", + "durability": null, + "equipment_slot": "5", "requirements": "{1,45}", "shop_price": "300", - "ge_buy_limit": "10", - "examine": "Not so spiky anymore.", - "durability": null, - "weight": "6", + "tradeable": "false", + "weight": "6" + }, + { + "id": "12933", + "name": "Rune berserker shield 20", + "examine": "A Large, spiked metal shield.", "absorb": "3,0,7", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0", + "durability": null, "equipment_slot": "5", - "grand_exchange_price": "135300", - "name": "Rune berserker shield 0", - "tradeable": "true", - "archery_ticket_price": "0", + "requirements": "{1,45}", + "shop_price": "300", + "tradeable": "false", + "weight": "6" + }, + { "id": "12934", - "bonuses": "0,0,0,-8,-2,16,18,17,-1,17,9,2,0,0,0" - }, - { - "ge_buy_limit": "10", - "examine": "Not so spiky anymore.", - "grand_exchange_price": "135300", - "durability": null, "name": "Rune berserker shield 0", - "tradeable": "true", + "examine": "Not so spiky anymore.", + "absorb": "3,0,7", "archery_ticket_price": "0", - "id": "12935" + "bonuses": "0,0,0,-8,-2,16,18,17,-1,17,9,2,0,0,0", + "durability": null, + "equipment_slot": "5", + "ge_buy_limit": "10", + "requirements": "{1,45}", + "shop_price": "300", + "tradeable": "true", + "weight": "6" }, { - "remove_head": "true", - "requirements": "{1,40}-{4,40}", - "shop_price": "150", - "examine": "A coif made of green dragonhide.", - "durability": null, - "weight": "0.9", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "88084", - "name": "Green d'hide coif 100", - "tradeable": "false", + "id": "12935", + "name": "Rune berserker shield 0", + "examine": "Not so spiky anymore.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { "id": "12936", - "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" - }, - { + "name": "Green d'hide coif 100", + "examine": "A coif made of green dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,40}", "shop_price": "150", - "examine": "A coif made of green dragonhide.", - "durability": null, - "weight": "0.9", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "88084", - "name": "Green d'hide coif 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "12937", - "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" - }, - { + "name": "Green d'hide coif 80", + "examine": "A coif made of green dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,40}", "shop_price": "150", - "examine": "A coif made of green dragonhide.", - "durability": null, - "weight": "0.9", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "88084", - "name": "Green d'hide coif 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "12938", - "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" - }, - { + "name": "Green d'hide coif 60", + "examine": "A coif made of green dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,40}", "shop_price": "150", - "examine": "A coif made of green dragonhide.", - "durability": null, - "weight": "0.9", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "88084", - "name": "Green d'hide coif 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.9" + }, + { "id": "12939", - "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}-{4,40}", - "shop_price": "150", + "name": "Green d'hide coif 40", "examine": "A coif made of green dragonhide.", - "durability": null, - "weight": "0.9", "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "88084", - "name": "Green d'hide coif 20", - "tradeable": "false", "archery_ticket_price": "0", - "id": "12940", - "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" - }, - { + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,40}", "shop_price": "150", - "ge_buy_limit": "100", - "examine": "A worn out coif made of green dragonhide.", - "durability": null, - "weight": "0.9", + "tradeable": "false", + "weight": "0.9" + }, + { + "id": "12940", + "name": "Green d'hide coif 20", + "examine": "A coif made of green dragonhide.", "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "92700", - "name": "Green d'hide coif 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "tradeable": "false", + "weight": "0.9" + }, + { "id": "12941", - "bonuses": "0,0,0,-1,1,1,2,2,1,2,1,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "examine": "A worn out coif made of green dragonhide.", - "grand_exchange_price": "92700", - "durability": null, "name": "Green d'hide coif 0", - "tradeable": "true", + "examine": "A worn out coif made of green dragonhide.", + "absorb": "0,3,1", "archery_ticket_price": "0", - "id": "12942" + "bonuses": "0,0,0,-1,1,1,2,2,1,2,1,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "tradeable": "true", + "weight": "0.9" }, { - "remove_head": "true", - "requirements": "{1,40}-{4,50}", - "shop_price": "200", - "examine": "A coif made of blue dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "186985", - "name": "Blue d'hide coif 100", - "tradeable": "false", + "id": "12942", + "name": "Green d'hide coif 0", + "examine": "A worn out coif made of green dragonhide.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12943", - "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" - }, - { + "name": "Blue d'hide coif 100", + "examine": "A coif made of blue dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,50}", "shop_price": "200", - "examine": "A coif made of blue dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "186985", - "name": "Blue d'hide coif 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12944", - "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" - }, - { + "name": "Blue d'hide coif 80", + "examine": "A coif made of blue dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,50}", "shop_price": "200", - "examine": "Fully charged: A coif made of blue dragonhide. Fully degraded: A worn out coif made of blue dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "186985", - "name": "Blue d'hide coif 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12945", - "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" - }, - { + "name": "Blue d'hide coif 60", + "examine": "Fully charged: A coif made of blue dragonhide. Fully degraded: A worn out coif made of blue dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,50}", "shop_price": "200", - "examine": "A coif made of blue dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "186985", - "name": "Blue d'hide coif 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12946", - "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}-{4,50}", - "shop_price": "200", + "name": "Blue d'hide coif 40", "examine": "A coif made of blue dragonhide.", - "durability": null, - "weight": "1", "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "186985", - "name": "Blue d'hide coif 20", - "tradeable": "false", "archery_ticket_price": "0", - "id": "12947", - "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" - }, - { + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,50}", "shop_price": "200", - "ge_buy_limit": "100", - "examine": "A worn out coif made of blue dragonhide.", - "durability": null, - "weight": "1", + "tradeable": "false", + "weight": "1" + }, + { + "id": "12947", + "name": "Blue d'hide coif 20", + "examine": "A coif made of blue dragonhide.", "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "131900", - "name": "Blue d'hide coif 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "tradeable": "false", + "weight": "1" + }, + { "id": "12948", - "bonuses": "0,0,0,-1,1,1,2,2,1,2,2,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "examine": "A worn out coif made of blue dragonhide.", - "grand_exchange_price": "131900", - "durability": null, "name": "Blue d'hide coif 0", - "tradeable": "true", + "examine": "A worn out coif made of blue dragonhide.", + "absorb": "0,3,1", "archery_ticket_price": "0", - "id": "12949" + "bonuses": "0,0,0,-1,1,1,2,2,1,2,2,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "requirements": "{1,40}-{4,60}", - "shop_price": "300", - "examine": "A coif made of red dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "230059", - "name": "Red d'hide coif 100", - "tradeable": "false", + "id": "12949", + "name": "Blue d'hide coif 0", + "examine": "A worn out coif made of blue dragonhide.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12950", - "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" - }, - { + "name": "Red d'hide coif 100", + "examine": "A coif made of red dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,60}", "shop_price": "300", - "examine": "A coif made of red dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "230059", - "name": "Red d'hide coif 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12951", - "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" - }, - { + "name": "Red d'hide coif 80", + "examine": "A coif made of red dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,60}", "shop_price": "300", - "examine": "Fully charged: A coif made of red dragonhide.Fully degraded: A worn out coif made of red dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "230059", - "name": "Red d'hide coif 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12952", - "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" - }, - { + "name": "Red d'hide coif 60", + "examine": "Fully charged: A coif made of red dragonhide.Fully degraded: A worn out coif made of red dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,60}", "shop_price": "300", - "examine": "A coif made of red dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "230059", - "name": "Red d'hide coif 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12953", - "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,40}-{4,60}", - "shop_price": "300", + "name": "Red d'hide coif 40", "examine": "A coif made of red dragonhide.", - "durability": null, - "weight": "1", "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "230059", - "name": "Red d'hide coif 20", - "tradeable": "false", "archery_ticket_price": "0", - "id": "12954", - "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" - }, - { + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,60}", "shop_price": "300", - "ge_buy_limit": "100", - "examine": "A worn out coif made of red dragonhide.", - "durability": null, - "weight": "1", + "tradeable": "false", + "weight": "1" + }, + { + "id": "12954", + "name": "Red d'hide coif 20", + "examine": "A coif made of red dragonhide.", "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "156600", - "name": "Red d'hide coif 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "tradeable": "false", + "weight": "1" + }, + { "id": "12955", - "bonuses": "0,0,0,-1,2,1,2,3,1,2,2,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "examine": "A worn out coif made of red dragonhide.", - "grand_exchange_price": "156600", - "durability": null, "name": "Red d'hide coif 0", - "tradeable": "true", + "examine": "A worn out coif made of red dragonhide.", + "absorb": "0,3,1", "archery_ticket_price": "0", - "id": "12956" + "bonuses": "0,0,0,-1,2,1,2,3,1,2,2,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "requirements": "{1,40}-{4,70}", - "shop_price": "500", - "examine": "A coif made of black dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "379555", - "name": "Black d'hide coif 100", - "tradeable": "false", + "id": "12956", + "name": "Red d'hide coif 0", + "examine": "A worn out coif made of red dragonhide.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12957", - "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" - }, - { + "name": "Black d'hide coif 100", + "examine": "A coif made of black dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,70}", "shop_price": "500", - "examine": "A coif made of black dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "379555", - "name": "Black d'hide coif 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12958", - "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" - }, - { + "name": "Black d'hide coif 80", + "examine": "A coif made of black dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,70}", "shop_price": "500", - "examine": "A coif made of black dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "379555", - "name": "Black d'hide coif 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12959", - "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" - }, - { + "name": "Black d'hide coif 60", + "examine": "A coif made of black dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,70}", "shop_price": "500", - "examine": "A coif made of black dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "379555", - "name": "Black d'hide coif 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12960", - "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" - }, - { + "name": "Black d'hide coif 40", + "examine": "A coif made of black dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,70}", "shop_price": "500", - "examine": "Fully charged: A coif made of black dragonhide. Fully degraded: A worn out coif made of black dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "379555", - "name": "Black d'hide coif 20", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "1" + }, + { "id": "12961", - "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" - }, - { + "name": "Black d'hide coif 20", + "examine": "Fully charged: A coif made of black dragonhide. Fully degraded: A worn out coif made of black dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,40}-{4,70}", "shop_price": "500", - "ge_buy_limit": "100", - "examine": "A coif made of black dragonhide.", - "durability": null, - "weight": "1", - "absorb": "0,3,1", - "equipment_slot": "0", - "grand_exchange_price": "229000", - "name": "Black d'hide coif 0", - "tradeable": "true", - "archery_ticket_price": "0", + "tradeable": "false", + "weight": "1" + }, + { "id": "12962", - "bonuses": "0,0,0,-1,3,1,3,3,1,2,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "examine": "A coif made of black dragonhide.", - "grand_exchange_price": "229000", - "durability": null, "name": "Black d'hide coif 0", - "tradeable": "true", + "examine": "A coif made of black dragonhide.", + "absorb": "0,3,1", "archery_ticket_price": "0", - "id": "12963" + "bonuses": "0,0,0,-1,3,1,3,3,1,2,3,0,0,0,0", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "ge_buy_limit": "100", + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "requirements": "{1,10}-{6,20}", - "shop_price": "50", - "examine": "A magical hood, especially created for combat spells.", - "durability": null, - "weight": "0.8", - "equipment_slot": "0", - "grand_exchange_price": "5661", - "name": "Combat hood 100", - "tradeable": "false", + "id": "12963", + "name": "Black d'hide coif 0", + "examine": "A coif made of black dragonhide.", "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { "id": "12964", - "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" - }, - { + "name": "Combat hood 100", + "examine": "A magical hood, especially created for combat spells.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "50", - "examine": "A magical hood, especially created for combat spells.", - "durability": null, - "weight": "0.8", - "equipment_slot": "0", - "grand_exchange_price": "5661", - "name": "Combat hood 80", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.8" + }, + { "id": "12965", - "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" - }, - { + "name": "Combat hood 80", + "examine": "A magical hood, especially created for combat spells.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "50", - "examine": "A magical hood, especially created for combat spells.", - "durability": null, - "weight": "0.8", - "equipment_slot": "0", - "grand_exchange_price": "5661", - "name": "Combat hood 60", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.8" + }, + { "id": "12966", - "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" - }, - { + "name": "Combat hood 60", + "examine": "A magical hood, especially created for combat spells.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "50", - "examine": "A magical hood, especially created for combat spells.", - "durability": null, - "weight": "0.8", - "equipment_slot": "0", - "grand_exchange_price": "5661", - "name": "Combat hood 40", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.8" + }, + { "id": "12967", - "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" - }, - { + "name": "Combat hood 40", + "examine": "A magical hood, especially created for combat spells.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", "remove_head": "true", "requirements": "{1,10}-{6,20}", "shop_price": "50", - "examine": "A magical hood, especially created for combat spells.", - "durability": null, - "weight": "0.8", - "equipment_slot": "0", - "grand_exchange_price": "5661", - "name": "Combat hood 20", "tradeable": "false", - "archery_ticket_price": "0", + "weight": "0.8" + }, + { "id": "12968", - "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,10}-{6,20}", - "shop_price": "50", - "ge_buy_limit": "10", + "name": "Combat hood 20", "examine": "A magical hood, especially created for combat spells.", - "durability": null, - "weight": "0.8", - "equipment_slot": "0", - "grand_exchange_price": "6511", - "name": "Combat hood 0", - "tradeable": "true", "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "tradeable": "false", + "weight": "0.8" + }, + { "id": "12969", - "bonuses": "0,0,0,1,0,0,0,0,1,0,2,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "6511", - "durability": null, "name": "Combat hood 0", - "tradeable": "true", + "examine": "A magical hood, especially created for combat spells.", "archery_ticket_price": "0", - "id": "12970" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "150", - "examine": "A magical robe top, especially made for combat spells.", + "bonuses": "0,0,0,1,0,0,0,0,1,0,2,0,0,0,0", "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "37700", - "name": "Combat robe top 100", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12971", - "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "150", - "examine": "A magical robe top, especially made for combat spells.", - "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "37700", - "name": "Combat robe top 80", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12972", - "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "150", - "examine": "A magical robe top, especially made for combat spells.", - "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "37700", - "name": "Combat robe top 60", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12973", - "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "150", - "examine": "A magical robe top, especially made for combat spells.", - "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "37700", - "name": "Combat robe top 40", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12974", - "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "150", - "examine": "A magical robe top, especially made for combat spells.", - "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "37700", - "name": "Combat robe top 20", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12975", - "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "150", - "ge_buy_limit": "10", - "examine": "A magical robe top, especially made for combat spells.", - "durability": null, - "weight": "4", - "absorb": "2,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "61500", - "name": "Combat robe top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12976", - "bonuses": "0,0,0,3,0,0,0,0,3,0,4,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "61500", - "durability": null, - "name": "Combat robe top 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12977" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "examine": "A magical robe bottom, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "50200", - "name": "Combat robe bottom 100", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12978", - "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "examine": "A magical robe bottom, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "50200", - "name": "Combat robe bottom 80", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12979", - "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "examine": "A magical robe bottom, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "50200", - "name": "Combat robe bottom 60", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12980", - "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "examine": "A magical robe bottom, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "50200", - "name": "Combat robe bottom 40", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12981", - "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "examine": "A magical robe bottom, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "50200", - "name": "Combat robe bottom 20", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12982", - "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" - }, - { - "requirements": "{1,10}-{6,20}", - "shop_price": "100", - "ge_buy_limit": "10", - "examine": "A magical robe bottom, especially created for combat spells.", - "durability": null, - "weight": "3", - "absorb": "1,0,0", - "equipment_slot": "7", - "grand_exchange_price": "47800", - "name": "Combat robe bottom 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12983", - "bonuses": "0,0,0,2,0,0,0,0,2,0,3,0,0,0,0" - }, - { - "ge_buy_limit": "10", - "grand_exchange_price": "47800", - "durability": null, - "name": "Combat robe bottom 0", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12984" - }, - { - "shop_price": "15", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "3694", - "durability": null, - "name": "Bronze gauntlets", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12985", - "bonuses": "0,0,0,-1,-1,2,3,3,-1,2,2,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "15", - "ge_buy_limit": "100", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "3275", - "durability": null, - "name": "Worn-out bronze gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12986", - "bonuses": "0,0,0,-1,-1,0,1,1,-1,0,1,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "3275", - "durability": null, - "name": "Worn-out bronze gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12987" - }, - { - "shop_price": "30", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "17339", - "durability": null, - "name": "Iron gauntlets", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12988", - "bonuses": "0,0,0,-1,-1,3,4,4,-1,3,3,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "30", - "ge_buy_limit": "100", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "16000", - "durability": null, - "name": "Worn-out iron gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12989", - "bonuses": "0,0,0,-1,-1,0,1,1,-1,0,1,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "16000", - "durability": null, - "name": "Worn-out iron gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12990" - }, - { - "requirements": "{1,5}", - "shop_price": "50", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "29844", - "durability": null, - "name": "Steel gauntlets", - "tradeable": "false", - "weight": "10", - "archery_ticket_price": "0", - "id": "12991", - "bonuses": "0,0,0,-1,-1,4,5,5,-1,4,4,0,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,5}", - "shop_price": "50", - "ge_buy_limit": "100", - "examine": "I have to keep my hands safe!", - "durability": null, - "weight": "10", - "equipment_slot": "9", - "grand_exchange_price": "27000", - "name": "Worn-out steel gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12992", - "bonuses": "0,0,0,-1,-1,1,1,1,-1,1,1,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "27000", - "durability": null, - "name": "Worn-out steel gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12993" - }, - { - "requirements": "{1,10}", - "shop_price": "75", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "50808", - "durability": null, - "name": "Black gauntlets", - "tradeable": "false", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "12994", - "bonuses": "0,0,0,-1,-1,5,6,6,-1,5,5,0,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,10}", - "shop_price": "75", - "ge_buy_limit": "100", - "examine": "I have to keep my hands safe!", - "durability": null, - "weight": "0.2", - "equipment_slot": "9", - "grand_exchange_price": "40100", - "name": "Worn-out black gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12995", - "bonuses": "0,0,0,-1,-1,1,2,2,-1,1,1,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "40100", - "durability": null, - "name": "Worn-out black gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12996" - }, - { - "requirements": "{1,20}", - "shop_price": "100", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "60064", - "durability": null, - "name": "Mithril gauntlets", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "12997", - "bonuses": "0,0,0,-1,-1,6,7,7,-1,6,6,0,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,20}", - "shop_price": "100", - "ge_buy_limit": "100", - "examine": "I have to keep my hands safe!", - "grand_exchange_price": "54200", - "durability": null, - "name": "Worn-out mithril gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12998", - "bonuses": "0,0,0,-1,-1,2,2,2,-1,2,2,0,0,0,0", - "equipment_slot": "9" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "54200", - "durability": null, - "name": "Worn-out mithril gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "12999" - }, - { - "requirements": "{1,30}", - "shop_price": "150", - "examine": "I have to keep my hands safe! Uncharged: A bit worse for wear.", - "grand_exchange_price": "74526", - "durability": null, - "name": "Adamant gauntlets", - "tradeable": "false", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "13000", - "bonuses": "0,0,0,-1,-1,8,9,9,-1,8,8,1,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,30}", - "shop_price": "150", - "ge_buy_limit": "100", - "examine": "I have to keep my hands safe! Uncharged: A bit worse for wear.", - "durability": null, - "weight": "0.2", - "equipment_slot": "9", - "grand_exchange_price": "71500", - "name": "Worn-out adamant gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13001", - "bonuses": "0,0,0,-1,-1,2,3,3,-1,2,2,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "71500", - "durability": null, - "name": "Worn-out adamant gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13002" - }, - { - "requirements": "{1,40}", - "shop_price": "200", - "examine": "Fully charged: I have to keep my hands safe! Worn-Out: A bit worse for wear.", - "grand_exchange_price": "95700", - "durability": null, - "name": "Rune gauntlets", - "tradeable": "false", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "13003", - "bonuses": "0,0,0,-1,-1,10,11,11,-1,10,10,2,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,40}", - "shop_price": "200", - "ge_buy_limit": "100", - "examine": "Fully charged: I have to keep my hands safe! Worn-Out: A bit worse for wear.", - "durability": null, - "weight": "0.2", - "equipment_slot": "9", - "grand_exchange_price": "99900", - "name": "Worn-out rune gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13004", - "bonuses": "0,0,0,-1,-1,3,4,4,-1,3,3,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "99900", - "durability": null, - "name": "Worn-out rune gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13005" - }, - { - "requirements": "{1,60}", - "shop_price": "300", - "examine": "Uncharged: A bit worse for wear. Charged: I have to keep my hands safe!", - "grand_exchange_price": "214700", - "durability": null, - "name": "Dragon gauntlets", - "tradeable": "false", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "13006", - "bonuses": "0,0,0,-1,-1,14,15,15,-1,14,14,3,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,60}", - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "Uncharged: A bit worse for wear. Charged: I have to keep my hands safe!", - "durability": null, - "weight": "0.2", - "equipment_slot": "9", - "grand_exchange_price": "166200", - "name": "Worn-out dragon gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13007", - "bonuses": "0,0,0,-1,-1,4,5,5,-1,4,4,1,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "166200", - "durability": null, - "name": "Worn-out dragon gauntlets", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13008" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13010" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13011" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13012" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13013" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13014" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13015" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13016" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13017" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13018" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13019" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13020" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13021" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13022" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13023" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13024" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13025" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13026" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13027" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13028" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13029" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13030" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13031" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13032" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13033" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13034" - }, - { - "destroy_message": "You can reclaim this item from the place you found it.", - "shop_price": "5", - "examine": "I need to solve this.", - "durability": null, - "name": "Puzzle box", - "archery_ticket_price": "0", - "id": "13035" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13036" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13037" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13038" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13039" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13040" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13041" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13042" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13043" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13044" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13045" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13046" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13047" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13048" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13049" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13050" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13051" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13052" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13053" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13054" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13055" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13056" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13057" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13058" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13059" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13060" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13061" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13062" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13063" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13064" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13065" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13066" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13067" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13068" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13069" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13070" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13071" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13072" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13074" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13075" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13076" - }, - { - "examine": "I hope there's treasure in it.", - "grand_exchange_price": "3726", - "durability": null, - "name": "Casket", - "tradeable": "true", - "weight": "5", - "archery_ticket_price": "0", - "id": "13077" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13078" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13079" - }, - { - "shop_price": "5000", - "examine": "A set of instructions to be followed.", - "durability": null, - "name": "Clue scroll", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13080" - }, - { - "requirements": "{4,33}", - "ge_buy_limit": "100", - "turn90cw_anim": "821", - "examine": "A black crossbow.", - "walk_anim": "4226", - "durability": null, - "weight": "5", - "turn90ccw_anim": "822", - "attack_speed": "6", - "weapon_interface": "17", - "turn180_anim": "4227", - "render_anim": "175", - "equipment_slot": "3", - "grand_exchange_price": "261", - "stand_anim": "4591", - "attack_audios": "2700,0,0,0", - "tradeable": "true", - "name": "Black crossbow", - "run_anim": "4228", - "archery_ticket_price": "0", - "id": "13081", - "stand_turn_anim": "823", - "bonuses": "0,0,0,0,60,0,0,0,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "grand_exchange_price": "261", - "durability": null, - "name": "Black crossbow", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13082" - }, - { - "requirements": "{4,33}", - "ge_buy_limit": "100", - "examine": "Black crossbow bolts.", - "grand_exchange_price": "55", - "durability": null, - "name": "Black bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13083", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", - "equipment_slot": "13" - }, - { - "requirements": "{4,33}", - "ge_buy_limit": "100", - "examine": "Black crossbow bolts.", - "grand_exchange_price": "141", - "durability": null, - "name": "Black bolts(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13084", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", - "equipment_slot": "13" - }, - { - "requirements": "{4,33}", - "ge_buy_limit": "100", - "examine": "Black crossbow bolts.", - "grand_exchange_price": "233", - "durability": null, - "name": "Black bolts(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13085", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", - "equipment_slot": "13" - }, - { - "requirements": "{4,33}", - "ge_buy_limit": "100", - "examine": "Black crossbow bolts.", - "grand_exchange_price": "1690", - "durability": null, - "name": "Black bolts(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13086", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", - "equipment_slot": "13" - }, - { - "requirements": "{0,8}", - "ge_buy_limit": "2", - "examine": "A sapphire-topped cane.", - "durability": null, - "weight": "0.5", - "attack_speed": "5", - "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "77000", - "name": "Black cane", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13095", - "bonuses": "0,-2,16,0,0,0,0,0,0,0,0,13,2,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "77000", - "durability": null, - "name": "Black cane", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13096" - }, - { - "requirements": "{0,28}", - "ge_buy_limit": "2", - "examine": "A ruby-topped cane.", - "durability": null, - "weight": "0.5", - "weapon_interface": "10", - "equipment_slot": "3", - "grand_exchange_price": "19100", - "name": "Adamant cane", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13097", - "bonuses": "0,-2,25,0,0,0,0,0,0,0,0,23,3,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "19100", - "durability": null, - "name": "Adamant cane", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13098" - }, - { - "requirements": "{0,38}", - "ge_buy_limit": "2", - "examine": "A diamond-topped cane.", - "durability": null, - "weight": "0.5", - "attack_speed": "5", - "weapon_interface": "10", - "equipment_slot": "3", - "lendable": "true", - "grand_exchange_price": "14500", - "name": "Rune cane", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13099", - "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "14500", - "durability": null, - "name": "Rune cane", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13100" - }, - { - "lendable": "true", - "ge_buy_limit": "2", - "examine": "Comes with a free rabbit!", - "grand_exchange_price": "160400", - "durability": null, - "name": "Top hat", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13101", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "160400", - "durability": null, - "name": "Top hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13102" - }, - { - "ge_buy_limit": "2", - "examine": "Official explorer headgear!", - "grand_exchange_price": "85400", - "durability": null, - "name": "Pith helmet", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", - "id": "13103", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "85400", - "durability": null, - "name": "Pith helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13104" - }, - { - "remove_head": "true", - "requirements": "{1,5}", - "ge_buy_limit": "2", - "examine": "Spikier than normal.", - "durability": null, - "weight": "10", "equipment_slot": "0", - "grand_exchange_price": "38300", - "name": "Spiked helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13105", - "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "38300", - "durability": null, - "name": "Spiked helmet", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13106" - }, - { + "ge_buy_limit": "10", "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "Shear elegance.", - "grand_exchange_price": "296700", - "durability": null, - "name": "Sheep mask", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13107", - "equipment_slot": "0" + "weight": "0.8" }, { - "ge_buy_limit": "2", - "grand_exchange_price": "296700", - "durability": null, - "name": "Sheep mask", - "tradeable": "true", + "id": "12970", + "name": "Combat hood 0", "archery_ticket_price": "0", - "id": "13108" + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" }, { - "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "I can get the look right, but can I do the waddle too?", - "grand_exchange_price": "633600", - "durability": null, - "name": "Penguin mask", - "tradeable": "true", - "weight": "1", + "id": "12971", + "name": "Combat robe top 100", + "examine": "A magical robe top, especially made for combat spells.", + "absorb": "2,1,0", "archery_ticket_price": "0", - "id": "13109", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "633600", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0", "durability": null, - "name": "Penguin mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13110" - }, - { - "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "The bats have left the belltower.", - "grand_exchange_price": "399000", - "durability": null, - "name": "Bat mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13111", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "399000", - "durability": null, - "name": "Bat mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13112" - }, - { - "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "It's the year of the cat!", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Cat mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13113", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1200000", - "durability": null, - "name": "Cat mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13114" - }, - { - "remove_head": "true", - "lendable": "true", - "ge_buy_limit": "2", - "examine": "I'm hungry like the wolf.", - "grand_exchange_price": "1500000", - "durability": null, - "name": "Wolf mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13115", - "equipment_slot": "0" - }, - { - "ge_buy_limit": "2", - "grand_exchange_price": "1500000", - "durability": null, - "name": "Wolf mask", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13116" - }, - { - "turn90cw_anim": "9053", - "examine": "A fully charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "defence_anim": "9048", - "equipment_slot": "3", - "attack_anims": "9097,9097,9097,9097", - "stand_anim": "9049", - "name": "Ivandis flail (30)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13117", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (29)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13118", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "turn90ccw_anim": "9054", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail(28)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13119", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (27)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13120", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (26)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13121", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (25)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13122", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (24)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13123", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (23)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13124", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (22)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13125", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (21)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13126", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (20)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13127", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (19)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13128", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (18)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13129", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (17)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13130", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (16)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13131", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (15)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13132", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (14)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13133", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (13)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13134", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (12)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13135", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (11)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13136", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (10)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13137", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (9)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13138", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (8)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13139", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (7)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13140", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (6)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13141", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail - it's nearly out of charges.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (5)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13142", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail - it's nearly out of charges.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (4)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13143", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail - it's nearly out of charges.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (3)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13144", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail - it's nearly out of charges.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (2)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13145", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "turn90cw_anim": "9053", - "examine": "A partially charged flail - one last charge left.", - "walk_anim": "9051", - "has_special": "true", - "durability": null, - "weight": "5", - "turn90ccw_anim": "9054", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "23", - "turn180_anim": "9052", - "render_anim": "712", - "equipment_slot": "3", - "stand_anim": "9049", - "name": "Ivandis flail (1)", - "run_anim": "9050", - "archery_ticket_price": "0", - "id": "13146", - "stand_turn_anim": "823", - "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" - }, - { - "examine": "Flail of Ivandis dust.", - "durability": null, - "name": "Flail dust", - "archery_ticket_price": "0", - "id": "13147" - }, - { - "destroy_message": "You found this page in the top floor of Paterdomus temple on an old table.", - "examine": "A page ripped from a book; it looks like a map of some kind.", - "durability": null, - "name": "Book page", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "150", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "13149" + "weight": "4" }, { - "destroy_message": "You got this book from a bunk bed in Sanguinesti Myreque base.", - "examine": "A big book of combat techniques.", + "id": "12972", + "name": "Combat robe top 80", + "examine": "A magical robe top, especially made for combat spells.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0", "durability": null, - "name": "Combat book", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "150", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "13151" + "weight": "4" }, { - "examine": "Used to make a metal chain.", - "durability": null, - "name": "Chain link mould", - "weight": "1", + "id": "12973", + "name": "Combat robe top 60", + "examine": "A magical robe top, especially made for combat spells.", + "absorb": "2,1,0", "archery_ticket_price": "0", - "id": "13153" - }, - { - "examine": "A chain made from mithril and silver.", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0", "durability": null, - "name": "Silvthril chain", - "weight": "3", - "archery_ticket_price": "0", - "id": "13154" - }, - { - "examine": "A blessed sickle with an emerald recessed into it.", - "durability": null, - "name": "Silver sickle emerald(b)", - "weight": "1", - "archery_ticket_price": "0", - "id": "13155", - "equipment_slot": "3" - }, - { - "examine": "A blessed and enchanted silver sickle with an emerald recessed into it.", - "durability": null, - "name": "Enchanted sickle emerald(b)", - "weight": "1", - "archery_ticket_price": "0", - "id": "13156", - "equipment_slot": "3" - }, - { - "examine": "A Vyrewatch corpse. Just a husk, really.", - "durability": null, - "name": "Vyre corpse", - "weight": "5", - "archery_ticket_price": "0", - "id": "13157" - }, - { - "examine": "An ornate key: precise workmanship and an ethereal glow. (Legacy of Seergaze)", - "durability": null, - "name": "Columbarium key", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13158" - }, - { - "destroy_message": "You got this key by cremating a Vyrewatch in the Paterdomus Columbarium.", - "examine": "An ornate key: precise workmanship and an ethereal glow. (Legacy of Seergaze)", - "durability": null, - "name": "Ornate tomb key", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "150", "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "id": "13159" + "weight": "4" }, { - "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", - "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "id": "12974", + "name": "Combat robe top 40", + "examine": "A magical robe top, especially made for combat spells.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0", "durability": null, - "name": "Tome of xp 2nd ed (3)", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "150", "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13160" + "weight": "4" }, { - "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", - "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "id": "12975", + "name": "Combat robe top 20", + "examine": "A magical robe top, especially made for combat spells.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0", "durability": null, - "name": "Tome of xp 2nd ed (2)", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "150", "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13161" + "weight": "4" }, { - "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", - "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "id": "12976", + "name": "Combat robe top 0", + "examine": "A magical robe top, especially made for combat spells.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,4,0,0,0,0", "durability": null, - "name": "Tome of xp 2nd ed (1)", + "equipment_slot": "4", + "ge_buy_limit": "10", + "remove_sleeves": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "tradeable": "true", + "weight": "4" + }, + { + "id": "12977", + "name": "Combat robe top 0", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "12978", + "name": "Combat robe bottom 100", + "examine": "A magical robe bottom, especially created for combat spells.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", - "id": "13162" + "weight": "3" }, { - "examine": "A sapphire-topped cane.", - "grand_exchange_price": "115390", + "id": "12979", + "name": "Combat robe bottom 80", + "examine": "A magical robe bottom, especially created for combat spells.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0", "durability": null, + "equipment_slot": "7", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12980", + "name": "Combat robe bottom 60", + "examine": "A magical robe bottom, especially created for combat spells.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12981", + "name": "Combat robe bottom 40", + "examine": "A magical robe bottom, especially created for combat spells.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12982", + "name": "Combat robe bottom 20", + "examine": "A magical robe bottom, especially created for combat spells.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "false", + "weight": "3" + }, + { + "id": "12983", + "name": "Combat robe bottom 0", + "examine": "A magical robe bottom, especially created for combat spells.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,3,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "10", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "tradeable": "true", + "weight": "3" + }, + { + "id": "12984", + "name": "Combat robe bottom 0", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "10", + "tradeable": "true" + }, + { + "id": "12985", + "name": "Bronze gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,2,3,3,-1,2,2,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "shop_price": "15", + "tradeable": "false" + }, + { + "id": "12986", + "name": "Worn-out bronze gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,0,1,1,-1,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "12987", + "name": "Worn-out bronze gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12988", + "name": "Iron gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,3,4,4,-1,3,3,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "shop_price": "30", + "tradeable": "false" + }, + { + "id": "12989", + "name": "Worn-out iron gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,0,1,1,-1,0,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "12990", + "name": "Worn-out iron gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12991", + "name": "Steel gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,4,5,5,-1,4,4,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,5}", + "shop_price": "50", + "tradeable": "false", + "weight": "10" + }, + { + "id": "12992", + "name": "Worn-out steel gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,1,1,1,-1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{1,5}", + "shop_price": "50", + "tradeable": "true", + "weight": "10" + }, + { + "id": "12993", + "name": "Worn-out steel gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12994", + "name": "Black gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,5,6,6,-1,5,5,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,10}", + "shop_price": "75", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "12995", + "name": "Worn-out black gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,1,2,2,-1,1,1,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{1,10}", + "shop_price": "75", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "12996", + "name": "Worn-out black gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "12997", + "name": "Mithril gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,6,7,7,-1,6,6,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,20}", + "shop_price": "100", + "tradeable": "false" + }, + { + "id": "12998", + "name": "Worn-out mithril gauntlets", + "examine": "I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,2,2,2,-1,2,2,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{1,20}", + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "12999", + "name": "Worn-out mithril gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "13000", + "name": "Adamant gauntlets", + "examine": "I have to keep my hands safe! Uncharged: A bit worse for wear.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,8,9,9,-1,8,8,1,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,30}", + "shop_price": "150", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "13001", + "name": "Worn-out adamant gauntlets", + "examine": "I have to keep my hands safe! Uncharged: A bit worse for wear.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,2,3,3,-1,2,2,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{1,30}", + "shop_price": "150", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "13002", + "name": "Worn-out adamant gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "13003", + "name": "Rune gauntlets", + "examine": "Fully charged: I have to keep my hands safe! Worn-Out: A bit worse for wear.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,10,11,11,-1,10,10,2,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,40}", + "shop_price": "200", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "13004", + "name": "Worn-out rune gauntlets", + "examine": "Fully charged: I have to keep my hands safe! Worn-Out: A bit worse for wear.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,3,4,4,-1,3,3,0,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{1,40}", + "shop_price": "200", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "13005", + "name": "Worn-out rune gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "13006", + "name": "Dragon gauntlets", + "examine": "Uncharged: A bit worse for wear. Charged: I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,14,15,15,-1,14,14,3,0,0,0", + "durability": null, + "equipment_slot": "9", + "requirements": "{1,60}", + "shop_price": "300", + "tradeable": "false", + "weight": "0.2" + }, + { + "id": "13007", + "name": "Worn-out dragon gauntlets", + "examine": "Uncharged: A bit worse for wear. Charged: I have to keep my hands safe!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-1,-1,4,5,5,-1,4,4,1,0,0,0", + "durability": null, + "equipment_slot": "9", + "ge_buy_limit": "100", + "requirements": "{1,60}", + "shop_price": "300", + "tradeable": "true", + "weight": "0.2" + }, + { + "id": "13008", + "name": "Worn-out dragon gauntlets", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "13010", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13011", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13012", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13013", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13014", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13015", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13016", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13017", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13018", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13019", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13020", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13021", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13022", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13023", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13024", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13025", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13026", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13027", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13028", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13029", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13030", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13031", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13032", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13033", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13034", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13035", + "name": "Puzzle box", + "examine": "I need to solve this.", + "archery_ticket_price": "0", + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "shop_price": "5" + }, + { + "id": "13036", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13037", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13038", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13039", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13040", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13041", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13042", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13043", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13044", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13045", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13046", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13047", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13048", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13049", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13050", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13051", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13052", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13053", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13054", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13055", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13056", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13057", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13058", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13059", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13060", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13061", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13062", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13063", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13064", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13065", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13066", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13067", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13068", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13069", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13070", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13071", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13072", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13074", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13075", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13076", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13077", + "name": "Casket", + "examine": "I hope there's treasure in it.", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true", + "weight": "5" + }, + { + "id": "13078", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13079", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13080", + "name": "Clue scroll", + "examine": "A set of instructions to be followed.", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "13081", + "name": "Black crossbow", + "examine": "A black crossbow.", + "archery_ticket_price": "0", + "attack_audios": "2700,0,0,0", + "attack_speed": "6", + "bonuses": "0,0,0,0,60,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "ge_buy_limit": "100", + "render_anim": "175", + "requirements": "{4,33}", + "run_anim": "4228", + "stand_anim": "4591", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "4227", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "4226", + "weapon_interface": "17", + "weight": "5" + }, + { + "id": "13082", + "name": "Black crossbow", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "13083", + "name": "Black bolts", + "examine": "Black crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "100", + "requirements": "{4,33}", + "tradeable": "true" + }, + { + "id": "13084", + "name": "Black bolts(p)", + "examine": "Black crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "100", + "requirements": "{4,33}", + "tradeable": "true" + }, + { + "id": "13085", + "name": "Black bolts(p+)", + "examine": "Black crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "100", + "requirements": "{4,33}", + "tradeable": "true" + }, + { + "id": "13086", + "name": "Black bolts(p++)", + "examine": "Black crossbow bolts.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "durability": null, + "equipment_slot": "13", + "ge_buy_limit": "100", + "requirements": "{4,33}", + "tradeable": "true" + }, + { + "id": "13095", "name": "Black cane", - "tradeable": "true", - "weight": "0.5", + "examine": "A sapphire-topped cane.", "archery_ticket_price": "0", "attack_speed": "5", - "weapon_interface": "10", - "id": "13163", "bonuses": "0,-2,16,0,0,0,0,0,0,0,0,13,2,0,0", - "equipment_slot": "3" - }, - { - "examine": "A ruby-topped cane.", - "grand_exchange_price": "18514", "durability": null, - "name": "Adamant cane", + "equipment_slot": "3", + "ge_buy_limit": "2", + "requirements": "{0,8}", "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", "weapon_interface": "10", - "id": "13164", - "bonuses": "0,-2,25,0,0,0,0,0,0,0,0,23,3,0,0", - "equipment_slot": "3" + "weight": "0.5" }, { - "examine": "A diamond-topped cane.", + "id": "13096", + "name": "Black cane", + "archery_ticket_price": "0", "durability": null, - "weight": "0.5", - "attack_speed": "5", + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13097", + "name": "Adamant cane", + "examine": "A ruby-topped cane.", + "archery_ticket_price": "0", + "bonuses": "0,-2,25,0,0,0,0,0,0,0,0,23,3,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "requirements": "{0,28}", + "tradeable": "true", "weapon_interface": "10", + "weight": "0.5" + }, + { + "id": "13098", + "name": "Adamant cane", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13099", + "name": "Rune cane", + "examine": "A diamond-topped cane.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,4,0,0", + "durability": null, + "equipment_slot": "3", + "ge_buy_limit": "2", + "lendable": "true", + "requirements": "{0,38}", + "tradeable": "true", + "weapon_interface": "10", + "weight": "0.5" + }, + { + "id": "13100", + "name": "Rune cane", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13101", + "name": "Top hat", + "examine": "Comes with a free rabbit!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13102", + "name": "Top hat", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13103", + "name": "Pith helmet", + "examine": "Official explorer headgear!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "tradeable": "true", + "weight": "0.5" + }, + { + "id": "13104", + "name": "Pith helmet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13105", + "name": "Spiked helmet", + "examine": "Spikier than normal.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "remove_head": "true", + "requirements": "{1,5}", + "tradeable": "true", + "weight": "10" + }, + { + "id": "13106", + "name": "Spiked helmet", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13107", + "name": "Sheep mask", + "examine": "Shear elegance.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13108", + "name": "Sheep mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13109", + "name": "Penguin mask", + "examine": "I can get the look right, but can I do the waddle too?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13110", + "name": "Penguin mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13111", + "name": "Bat mask", + "examine": "The bats have left the belltower.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13112", + "name": "Bat mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13113", + "name": "Cat mask", + "examine": "It's the year of the cat!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "tradeable": "true" + }, + { + "id": "13114", + "name": "Cat mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13115", + "name": "Wolf mask", + "examine": "I'm hungry like the wolf.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "2", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13116", + "name": "Wolf mask", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "2", + "tradeable": "true" + }, + { + "id": "13117", + "name": "Ivandis flail (30)", + "examine": "A fully charged flail.", + "archery_ticket_price": "0", + "attack_anims": "9097,9097,9097,9097", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "defence_anim": "9048", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13118", + "name": "Ivandis flail (29)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13119", + "name": "Ivandis flail(28)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23" + }, + { + "id": "13120", + "name": "Ivandis flail (27)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13121", + "name": "Ivandis flail (26)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13122", + "name": "Ivandis flail (25)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13123", + "name": "Ivandis flail (24)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13124", + "name": "Ivandis flail (23)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13125", + "name": "Ivandis flail (22)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13126", + "name": "Ivandis flail (21)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13127", + "name": "Ivandis flail (20)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13128", + "name": "Ivandis flail (19)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13129", + "name": "Ivandis flail (18)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13130", + "name": "Ivandis flail (17)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13131", + "name": "Ivandis flail (16)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13132", + "name": "Ivandis flail (15)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13133", + "name": "Ivandis flail (14)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13134", + "name": "Ivandis flail (13)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13135", + "name": "Ivandis flail (12)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13136", + "name": "Ivandis flail (11)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13137", + "name": "Ivandis flail (10)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13138", + "name": "Ivandis flail (9)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13139", + "name": "Ivandis flail (8)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13140", + "name": "Ivandis flail (7)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13141", + "name": "Ivandis flail (6)", + "examine": "A partially charged flail.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13142", + "name": "Ivandis flail (5)", + "examine": "A partially charged flail - it's nearly out of charges.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13143", + "name": "Ivandis flail (4)", + "examine": "A partially charged flail - it's nearly out of charges.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13144", + "name": "Ivandis flail (3)", + "examine": "A partially charged flail - it's nearly out of charges.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13145", + "name": "Ivandis flail (2)", + "examine": "A partially charged flail - it's nearly out of charges.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13146", + "name": "Ivandis flail (1)", + "examine": "A partially charged flail - one last charge left.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "712", + "run_anim": "9050", + "stand_anim": "9049", + "stand_turn_anim": "823", + "turn180_anim": "9052", + "turn90ccw_anim": "9054", + "turn90cw_anim": "9053", + "two_handed": "true", + "walk_anim": "9051", + "weapon_interface": "23", + "weight": "5" + }, + { + "id": "13147", + "name": "Flail dust", + "examine": "Flail of Ivandis dust.", + "archery_ticket_price": "0", + "durability": null + }, + { + "id": "13149", + "name": "Book page", + "examine": "A page ripped from a book; it looks like a map of some kind.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You found this page in the top floor of Paterdomus temple on an old table.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13151", + "name": "Combat book", + "examine": "A big book of combat techniques.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You got this book from a bunk bed in Sanguinesti Myreque base.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13153", + "name": "Chain link mould", + "examine": "Used to make a metal chain.", + "archery_ticket_price": "0", + "durability": null, + "weight": "1" + }, + { + "id": "13154", + "name": "Silvthril chain", + "examine": "A chain made from mithril and silver.", + "archery_ticket_price": "0", + "durability": null, + "weight": "3" + }, + { + "id": "13155", + "name": "Silver sickle emerald(b)", + "examine": "A blessed sickle with an emerald recessed into it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1" + }, + { + "id": "13156", + "name": "Enchanted sickle emerald(b)", + "examine": "A blessed and enchanted silver sickle with an emerald recessed into it.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "3", + "weight": "1" + }, + { + "id": "13157", + "name": "Vyre corpse", + "examine": "A Vyrewatch corpse. Just a husk, really.", + "archery_ticket_price": "0", + "durability": null, + "weight": "5" + }, + { + "id": "13158", + "name": "Columbarium key", + "examine": "An ornate key: precise workmanship and an ethereal glow. (Legacy of Seergaze)", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.1" + }, + { + "id": "13159", + "name": "Ornate tomb key", + "examine": "An ornate key: precise workmanship and an ethereal glow. (Legacy of Seergaze)", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You got this key by cremating a Vyrewatch in the Paterdomus Columbarium.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13160", + "name": "Tome of xp 2nd ed (3)", + "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "13161", + "name": "Tome of xp 2nd ed (2)", + "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "13162", + "name": "Tome of xp 2nd ed (1)", + "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "durability": null, + "tradeable": "false", + "weight": "1" + }, + { + "id": "13163", + "name": "Black cane", + "examine": "A sapphire-topped cane.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-2,16,0,0,0,0,0,0,0,0,13,2,0,0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weapon_interface": "10", + "weight": "0.5" + }, + { + "id": "13164", + "name": "Adamant cane", + "examine": "A ruby-topped cane.", + "archery_ticket_price": "0", + "bonuses": "0,-2,25,0,0,0,0,0,0,0,0,23,3,0,0", + "durability": null, + "equipment_slot": "3", + "tradeable": "true", + "weapon_interface": "10", + "weight": "0.5" + }, + { + "id": "13165", + "name": "Rune cane", + "examine": "A diamond-topped cane.", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,4,0,0", + "durability": null, "equipment_slot": "3", "lendable": "true", - "grand_exchange_price": "15023", - "name": "Rune cane", "tradeable": "true", - "archery_ticket_price": "0", - "id": "13165", - "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + "weapon_interface": "10", + "weight": "0.5" }, { - "lendable": "true", - "examine": "Comes with a free rabbit!", - "grand_exchange_price": "425919", - "durability": null, - "name": "Top hat", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "13166", - "equipment_slot": "0" + "name": "Top hat", + "examine": "Comes with a free rabbit!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "examine": "Official explorer headgear!", - "grand_exchange_price": "99682", - "durability": null, - "name": "Pith helmet", - "tradeable": "true", - "weight": "0.5", - "archery_ticket_price": "0", "id": "13167", - "equipment_slot": "0" + "name": "Pith helmet", + "examine": "Official explorer headgear!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "true", + "weight": "0.5" }, { - "remove_head": "true", - "examine": "Spikier than normal.", - "grand_exchange_price": "39643", - "durability": null, - "name": "Spiked helmet", - "tradeable": "true", - "weight": "10", - "archery_ticket_price": "0", "id": "13168", + "name": "Spiked helmet", + "examine": "Spikier than normal.", + "archery_ticket_price": "0", "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", - "equipment_slot": "0" + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "true", + "weight": "10" }, { - "remove_head": "true", - "lendable": "true", - "examine": "Shear elegance.", - "grand_exchange_price": "313558", - "durability": null, - "name": "Sheep mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "13169", - "equipment_slot": "0" + "name": "Sheep mask", + "examine": "Shear elegance.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "lendable": "true", - "examine": "I can get the look right, but can I do the waddle too?", - "grand_exchange_price": "609515", - "durability": null, - "name": "Penguin mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "13170", - "equipment_slot": "0" + "name": "Penguin mask", + "examine": "I can get the look right, but can I do the waddle too?", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "lendable": "true", - "examine": "The bats have left the belltower.", - "grand_exchange_price": "371616", - "durability": null, - "name": "Bat mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "13171", - "equipment_slot": "0" + "name": "Bat mask", + "examine": "The bats have left the belltower.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" }, { - "remove_head": "true", - "lendable": "true", - "examine": "It's the year of the cat!", - "grand_exchange_price": "1066648", - "durability": null, - "name": "Cat mask", - "tradeable": "true", - "archery_ticket_price": "0", "id": "13172", - "equipment_slot": "0" - }, - { - "remove_head": "true", + "name": "Cat mask", + "examine": "It's the year of the cat!", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", "lendable": "true", - "examine": "I'm hungry like the wolf.", - "grand_exchange_price": "1303443", - "durability": null, - "name": "Wolf mask", - "tradeable": "true", - "weight": "1", - "archery_ticket_price": "0", + "remove_head": "true", + "tradeable": "true" + }, + { "id": "13173", - "equipment_slot": "0" + "name": "Wolf mask", + "examine": "I'm hungry like the wolf.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_head": "true", + "tradeable": "true", + "weight": "1" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Blue navy slacks", - "archery_ticket_price": "0", "id": "13174", - "equipment_slot": "7" + "name": "Blue navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Green navy slacks", - "archery_ticket_price": "0", "id": "13175", - "equipment_slot": "7" + "name": "Green navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Red navy slacks", - "archery_ticket_price": "0", "id": "13176", - "equipment_slot": "7" + "name": "Red navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Brown navy slacks", - "archery_ticket_price": "0", "id": "13177", - "equipment_slot": "7" + "name": "Brown navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Black navy slacks", - "archery_ticket_price": "0", "id": "13178", - "equipment_slot": "7" + "name": "Black navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "shop_price": "100", - "examine": "Not for slackers", - "durability": null, - "name": "Purple navy slacks", - "archery_ticket_price": "0", "id": "13179", - "equipment_slot": "7" - }, - { - "shop_price": "100", + "name": "Purple navy slacks", "examine": "Not for slackers", - "durability": null, - "name": "Grey navy slacks", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" + }, + { "id": "13180", - "equipment_slot": "7" + "name": "Grey navy slacks", + "examine": "Not for slackers", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "7", + "shop_price": "100" }, { - "remove_sleeves": "true", - "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Blue naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", "id": "13181", - "equipment_slot": "4" - }, - { + "name": "Blue naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Green naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "13182", - "equipment_slot": "4" - }, - { + "name": "Green naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Red naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "13183", - "equipment_slot": "4" - }, - { + "name": "Red naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Brown naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "13184", - "equipment_slot": "4" - }, - { + "name": "Brown naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Black naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "13185", - "equipment_slot": "4" - }, - { + "name": "Black naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Purple naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "13186", - "equipment_slot": "4" - }, - { + "name": "Purple naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", "remove_sleeves": "true", "shop_price": "100", - "examine": "...You can sail the seven seas...", - "durability": null, - "name": "Grey naval shirt", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", + "tradeable": "false" + }, + { "id": "13187", - "equipment_slot": "4" + "name": "Grey naval shirt", + "examine": "...You can sail the seven seas...", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "100", + "tradeable": "false" }, { - "remove_head": "true", - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Blue tricorn hat", - "archery_ticket_price": "0", "id": "13188", - "equipment_slot": "0" + "name": "Blue tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" }, { - "remove_head": "true", - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Green tricorn hat", - "archery_ticket_price": "0", "id": "13189", - "equipment_slot": "0" + "name": "Green tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" }, { - "remove_head": "true", - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Red tricorn hat", - "archery_ticket_price": "0", "id": "13190", - "equipment_slot": "0" + "name": "Red tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" }, { - "remove_head": "true", - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Brown tricorn hat", - "archery_ticket_price": "0", "id": "13191", - "equipment_slot": "0" + "name": "Brown tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" }, { - "remove_head": "true", - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Black tricorn hat", - "archery_ticket_price": "0", "id": "13192", - "equipment_slot": "0" + "name": "Black tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" }, { - "remove_head": "true", - "shop_price": "50", - "examine": "I could never look square in this.", - "durability": null, - "name": "Purple tricorn hat", - "archery_ticket_price": "0", "id": "13193", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "50", + "name": "Purple tricorn hat", "examine": "I could never look square in this.", - "durability": null, - "name": "Grey tricorn hat", "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" + }, + { "id": "13194", - "equipment_slot": "0" + "name": "Grey tricorn hat", + "examine": "I could never look square in this.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "50" }, { - "destroy_message": "If you drop this lamp, it will be destroyed. You can obtain another from Dunstan.", - "examine": "I wonder what happens if I rub it.", - "durability": null, + "id": "13227", "name": "Mysterious lamp", - "tradeable": "false", + "examine": "I wonder what happens if I rub it.", "archery_ticket_price": "0", - "id": "13227" + "destroy_message": "If you drop this lamp, it will be destroyed. You can obtain another from Dunstan.", + "durability": null, + "tradeable": "false" }, { - "destroy_message": "You can get another net from Professor Arblenap on Ice Mountain.", - "examine": "Professor Arblenap gave you this net to catch the baby icefiends on Ice Mountain.", - "durability": null, - "name": "Icefiend net", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "13230", - "equipment_slot": "3" + "name": "Icefiend net", + "examine": "Professor Arblenap gave you this net to catch the baby icefiends on Ice Mountain.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "You can get another net from Professor Arblenap on Ice Mountain.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false", + "weight": "1" }, { - "examine": "You should give this to Professor Arblenap.", - "durability": null, - "name": "Baby icefiend", - "tradeable": "false", - "destroy": "true", - "weight": "1", - "archery_ticket_price": "0", "id": "13231", - "equipment_slot": "3" + "name": "Baby icefiend", + "examine": "You should give this to Professor Arblenap.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "3", + "tradeable": "false", + "weight": "1" }, { - "destroy_message": "It will reappear near the bottom of Ice Mountain.", - "examine": "The remains of the Oracle's tent on Ice Mountain.", - "durability": null, + "id": "13232", "name": "Tent", - "tradeable": "false", - "destroy": "true", - "weight": "30", + "examine": "The remains of the Oracle's tent on Ice Mountain.", "archery_ticket_price": "0", - "id": "13232" + "destroy": "true", + "destroy_message": "It will reappear near the bottom of Ice Mountain.", + "durability": null, + "tradeable": "false", + "weight": "30" }, { - "destroy_message": "You can get it back by pickpocketing Drorkar again.", - "examine": "You took this key from Drorkar's pocket in the power station. (Perils of Ice Mountain)", - "durability": null, + "id": "13234", "name": "Dwarven key", - "tradeable": "false", - "destroy": "true", + "examine": "You took this key from Drorkar's pocket in the power station. (Perils of Ice Mountain)", "archery_ticket_price": "0", - "id": "13234" + "destroy": "true", + "destroy_message": "You can get it back by pickpocketing Drorkar again.", + "durability": null, + "tradeable": "false" }, { - "examine": "A plank of oak that has been treated to resist fire.", - "durability": null, + "id": "13238", "name": "Treated oak plank", - "weight": "0.8", - "archery_ticket_price": "0", - "id": "13238" - }, - { - "shop_price": "14", - "examine": "Good for detailed crafting.", - "grand_exchange_price": "33", - "durability": null, - "name": "Chisel", - "tradeable": "true", - "weight": "0.4", - "archery_ticket_price": "0", - "id": "13239" - }, - { - "durability": null, - "name": ".", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13240", - "equipment_slot": "5" - }, - { "examine": "A plank of oak that has been treated to resist fire.", - "durability": null, - "name": "Treated plank", - "weight": "0.8", "archery_ticket_price": "0", - "id": "13241" + "durability": null, + "weight": "0.8" }, { + "id": "13239", + "name": "Chisel", + "examine": "Good for detailed crafting.", + "archery_ticket_price": "0", "durability": null, - "name": ".", + "shop_price": "14", "tradeable": "true", - "archery_ticket_price": "0", - "id": "13242" + "weight": "0.4" }, { - "examine": "An old stone slab with writing on it.", + "id": "13240", + "name": ".", + "archery_ticket_price": "0", "durability": null, + "equipment_slot": "5", + "tradeable": "true" + }, + { + "id": "13241", + "name": "Treated plank", + "examine": "A plank of oak that has been treated to resist fire.", + "archery_ticket_price": "0", + "durability": null, + "weight": "0.8" + }, + { + "id": "13242", + "name": ".", + "archery_ticket_price": "0", + "durability": null, + "tradeable": "true" + }, + { + "id": "13243", "name": "Stone tablet", + "examine": "An old stone slab with writing on it.", "archery_ticket_price": "0", - "id": "13243" + "durability": null }, { - "examine": "A book for those who want to visit the TzHaar city.", - "durability": null, + "id": "13244", "name": "Tzhaar tourist guide", + "examine": "A book for those who want to visit the TzHaar city.", "archery_ticket_price": "0", - "id": "13244" + "durability": null }, { - "destroy_message": "You can mine more stone slabs in the TzHaar mine.", - "examine": "A flawed block of obsidian from the Karamja volcano.", - "durability": null, + "id": "13245", "name": "Stone slab", - "tradeable": "false", - "destroy": "true", - "weight": "32", + "examine": "A flawed block of obsidian from the Karamja volcano.", "archery_ticket_price": "0", - "id": "13245" + "destroy": "true", + "destroy_message": "You can mine more stone slabs in the TzHaar mine.", + "durability": null, + "tradeable": "false", + "weight": "32" }, { - "destroy_message": "You can get more pillars by crafting stone slabs from the TzHaar mine.", - "examine": "A support pillar.", - "durability": null, + "id": "13246", "name": "Pillar", - "tradeable": "false", - "destroy": "true", - "weight": "25", + "examine": "A support pillar.", "archery_ticket_price": "0", - "id": "13246" + "destroy": "true", + "destroy_message": "You can get more pillars by crafting stone slabs from the TzHaar mine.", + "durability": null, + "tradeable": "false", + "weight": "25" }, { - "durability": null, - "name": "Splat", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13247", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, "name": "Splat", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { "id": "13248", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, "name": "Splat", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { "id": "13249", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, "name": "Splat", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { "id": "13250", + "name": "Splat", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can obtain another from the mummy guardian in the undead slayer's tomb.", - "examine": "A key obtained in Catolax's tomb.", - "durability": null, - "name": "Ranged path key", - "tradeable": "false", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { "id": "13259", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can obtain another from the mummy guardian in the undead slayer's tomb.", + "name": "Ranged path key", "examine": "A key obtained in Catolax's tomb.", - "durability": null, - "name": "Magic path key", - "tradeable": "false", - "destroy": "true", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13260", - "absorb": "0,0,0", - "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": "true", + "destroy_message": "You can obtain another from the mummy guardian in the undead slayer's tomb.", + "durability": null, + "tradeable": "false" }, { + "id": "13260", + "name": "Magic path key", + "examine": "A key obtained in Catolax's tomb.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can obtain another from the mummy guardian in the undead slayer's tomb.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13263", + "name": "Slayer helmet", + "examine": "You don't want to wear it inside-out.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", "remove_head": "true", "requirements": "{1,10}", "shop_price": "650", - "examine": "You don't want to wear it inside-out.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Slayer helmet", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13263", - "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0" + "tradeable": "false" }, { - "destroy_message": "Drop", - "examine": "The remains of a banshee's scream.", - "durability": null, - "name": "Banshee voice", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13276", + "name": "Banshee voice", + "examine": "The remains of a banshee's scream.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "tradeable": "false" }, { - "shop_price": "400", - "examine": "More of that crazy Slayer headgear.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Masked earmuffs", - "tradeable": "false", - "archery_ticket_price": "0", "id": "13277", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "50", - "examine": "For use against turoth and kurasks.", - "durability": null, - "destroy": "true", - "attack_speed": "4", + "name": "Masked earmuffs", + "examine": "More of that crazy Slayer headgear.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", "destroy_message": "Drop", - "grand_exchange_price": "89", - "name": "Broad arrow heads", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13278", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "50", - "examine": "For use against turoth and kurasks.", "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "17", - "name": "Unfinished broad bolts", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13279", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "50", - "examine": "For use against turoth and kurasks.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "13", - "destroy_message": "Drop", - "grand_exchange_price": "34", - "name": "Broad-tipped bolts", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13280", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(8)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13281", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(7)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13282", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(6)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13283", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(5)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13284", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(4)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13285", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(3)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13286", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(2)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13287", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "150", - "examine": "An enchanted ring.", - "durability": null, - "name": "Ring of slaying(1)", - "tradeable": "false", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13288", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "turn90cw_anim": "1207", - "examine": "A razor-sharp sword.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "381,381,390,381", - "grand_exchange_price": "43082", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "13290", - "stand_turn_anim": "823", - "bonuses": "67,62,0,0,0,0,0,0,0,0,0,50,0,0,0", - "requirements": "{0,50}-{18,55}", - "shop_price": "68000", - "durability": null, - "destroy": "false", - "weapon_interface": "5", - "attack_audios": "2517,2517,2500,2517", - "name": "Leaf-bladed sword" - }, - { - "shop_price": "68000", - "examine": "A razor-sharp sword.", - "grand_exchange_price": "43082", - "durability": null, - "name": "Leaf-bladed sword", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13291" - }, - { - "durability": null, - "name": "Letter", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13292", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Plans", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13293", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop these plans, they will be lost and you will need to see Captain Donnie for a replacement.", - "examine": "A charcoal rubbing taken from 50% Luke.", - "durability": null, - "name": "Charcoal rubbing", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13294", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop Frank's mark, you will need to see him to get another.", - "examine": "Signature from Frank.", - "durability": null, - "name": "Frank's mark", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13295", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop these lockpicks, you will need to look under the mattress to get another set.", - "examine": "A device for opening locked doors.", - "durability": null, - "name": "Crude lockpick", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13296", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "The top of a Custom Officer's uniform.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "If you drop this shirt you will need to kill another Customs officer for a replacement.", - "remove_sleeves": "true", - "name": "Customs shirt", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13297", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop these trousers you will need to kill another Customs officer for a replacement.", - "examine": "The trousers of a Custom Officer's uniform.", - "durability": null, - "name": "Customs trousers", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13298", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "If you drop this hat you will need to kill another Customs officer for a replacement.", - "examine": "The hat of a Custom Officer's uniform.", - "durability": null, - "name": "Customs hat", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13299", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", - "examine": "A folder containing all the marks I have gathered.", - "durability": null, - "name": "File", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13300", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", - "examine": "A folder containing all the marks I have gathered.", - "durability": null, - "name": "File", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13301", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Brooch", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13302", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop Izzy's No-Beard's mark, you will need to see him to get another.", - "examine": "Signature from Izzy No-Beard.", - "durability": null, - "name": "Izzy's mark", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13303", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Key", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13304", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this crowbar, you will need to get another from the chest on the sunken ship.", - "examine": "This could be useful.", - "durability": null, - "name": "Crowbar", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13305", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop the idol, you will need to go diving to get another replacement.", - "examine": "An idol. It has many heads.", - "durability": null, - "name": "Idol of many heads", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13307", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop Bill Teach's mark, you will need to see him to get another.", - "examine": "Signature from Bill Teach.", - "durability": null, - "name": "Bill teach's mark", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13308", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this paper, you will need to call to the guards for a replacement. ", - "examine": "This is generally used for writing on.", - "durability": null, - "name": "Paper", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13309", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this note, you'll need to call the guards for replacement paper.", - "examine": "A written confession.", - "durability": null, - "name": "Confession", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13310", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Note", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13311", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this ink, you will need to call to the guards for a replacement.", - "examine": "An empty ink bottle./This is full of ink.", - "durability": null, - "name": "Ink bottle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13312", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this paper you will need to call to the guards to replace it and the ink.", - "examine": "It's got ink all over it.", - "durability": null, - "name": "Inky paper", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13313", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this ink, you will need to call to the guards for a replacement.", - "examine": "An empty ink bottle./This is full of ink.", - "durability": null, - "name": "Ink bottle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13314", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this bottle, you will need to call to the guards for a replacement.", - "examine": "It's smashed. I should mind my fingers.", - "durability": null, - "name": "Smashed bottle", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13315", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "The top part of a prisoner's uniform.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "If you drop this top, then you will need to speak to the guards to get it replaced.", - "remove_sleeves": "true", - "name": "Prison uniform top", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13316", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop these trousers, then you will need to speak to the guards to get it replaced.", - "examine": "The bottom part of a prisoner's uniform.", - "durability": null, - "name": "Prison uniform trousers", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13317", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "examine": "It's covered in fish slop.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "If you drop this top, you will need to speak to the guards to get it replaced, then find a way to get stew on it again.", - "remove_sleeves": "true", - "name": "Fishy prison uniform top", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13318", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this cup it will be destroyed and you will have to pick up another.", - "examine": "A standard prison-issue tin cup.", - "durability": null, - "name": "Tin cup", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13319", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "If you drop this cup it will be destroyed and you will have to pick up another.", - "examine": "A standard prison-issue tin cup.", - "durability": null, - "name": "Tin cup", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13320", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "Destroy", - "examine": "A pipe that belongs in a cannon stand.", - "durability": null, - "name": "Pipe", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13321", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", - "durability": null, - "name": "Accordion", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13322", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", - "durability": null, - "name": "Accordion", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13323", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", - "durability": null, - "name": "Accordion", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13324", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this accordion, pipe and inky paper, it will all be destroyed and you will need to get all the items back again.", - "examine": "A very crude vacuum pump.", - "durability": null, - "name": "Vacuum pump", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13325", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this, you will lose all the items you put in it, as well as the seagull.", - "examine": "It sounds like a law firm.", - "durability": null, - "name": "Vacuum pump and gull", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13326", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "If you drop this quill, you will need to talk to the guard for a replacement.", - "examine": "From a bird - can be used for writing.", - "durability": null, - "name": "Quill", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13327", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "From a bird - can be used for writing. It has some ink on the tip.", - "durability": null, - "name": "Inky quill", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13328", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", - "examine": "A folder containing all the marks I have gathered.", - "durability": null, - "name": "File", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13329", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", - "examine": "A folder containing all the marks I have gathered.", - "durability": null, - "name": "File", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13330", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this dead parrot, there is a chance that bad, bad things will happen to you - unless you see 50 Ships Mufassah for a replacement.", - "examine": "A very dead rotten parrot.", - "durability": null, - "name": "Ex-parrot", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13331", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this cage, you will need to see Bill Teach for a replacement.", - "examine": "It feels very cold to the touch.", - "durability": null, - "name": "Magical cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13332", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this dead parrot in a cage (and who wouldn't) then you will need to see ", - "examine": "A very dead rotten parrot in a magical cage.", - "durability": null, - "name": "Ex-parrot in a magic cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13333", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop the cage, the ex-ex-parrot will escape.", - "examine": "A very alive rotten parrot in a magic cage.", - "durability": null, - "name": "Ex-ex-parrot in a magic cage", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13334", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Ex-ex-parrot", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13335", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Ex-ex-parrot", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13336", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "50", - "examine": "A pirate impling in a jar.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "grand_exchange_price": "7346", - "name": "Pirate impling jar", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13337", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", - "shop_price": "50", - "grand_exchange_price": "7346", - "durability": null, - "name": "Pirate impling jar", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13338" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A white bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13339", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A white bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13340", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A red bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13341", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A red bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13342", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A blue bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13343", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A blue bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13344", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A brown bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13345", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A brown bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13346", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A grey bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13347", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A grey bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13348", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A purple bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13349", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A purple bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13350", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A orange bandana and a patch for the left eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13351", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A orange bandana and a patch for both eyes.", - "durability": null, - "name": "Bandana and eyepatches", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13352", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "shop_price": "100", - "examine": "It's dark, and I'm wearing two patches. Hit it!", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Double eyepatches", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13353", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "Two patches and a hat.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Pirate hat and eyepatches", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13354", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "100", - "examine": "A patch for the left eye.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "23485", - "name": "Left eyepatch", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13355", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A patch for the left eye.", - "grand_exchange_price": "23485", - "durability": null, - "name": "Left eyepatch", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13356" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A hat and a patch.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Pirate hat and eyepatch", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13357", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "A seaworthy grey shirt.", - "durability": null, - "weight": "1", - "absorb": "0,0,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13358", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "300", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13359" - }, - { - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "A seaworthy purple shirt.", - "durability": null, - "weight": "1", - "absorb": "0,0,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13360", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "300", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13361" - }, - { - "shop_price": "300", - "ge_buy_limit": "100", - "examine": "A seaworthy orange shirt.", - "durability": null, - "weight": "1", - "absorb": "0,0,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13362", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "300", - "durability": null, - "name": "Stripy pirate shirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13363" - }, - { - "shop_price": "350", - "ge_buy_limit": "100", - "examine": "A seaworthy pair of grey trousers.", - "durability": null, - "weight": "1", - "absorb": "0,0,0", - "equipment_slot": "7", - "grand_exchange_price": "1", - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13364", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "350", - "grand_exchange_price": "1", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13365" - }, - { - "shop_price": "350", - "ge_buy_limit": "100", - "examine": "A seaworthy pair of purple trousers.", - "durability": null, - "weight": "1", - "absorb": "0,0,0", - "equipment_slot": "7", - "grand_exchange_price": "1", - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13366", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "350", - "grand_exchange_price": "1", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13367" - }, - { - "shop_price": "350", - "ge_buy_limit": "100", - "examine": "A seaworthy pair of orange trousers.", - "durability": null, - "weight": "1", - "absorb": "0,0,0", - "equipment_slot": "7", - "grand_exchange_price": "1", - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13368", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "350", - "grand_exchange_price": "1", - "durability": null, - "name": "Pirate leggings", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13369" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A grey bandana.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Bandana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13370", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "durability": null, - "name": "Bandana", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13371" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A purple bandana.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Bandana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13372", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "durability": null, - "name": "Bandana", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13373" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "An orange bandana.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Bandana", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13374", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "durability": null, - "name": "Bandana", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13375" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A purple bandana and a patch for the right eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13376", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A orange bandana and a patch for the right eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13377", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "shop_price": "100", - "examine": "A grey bandana and a patch for the right eye.", - "durability": null, - "name": "Bandana and eyepatch", - "tradeable": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "13378", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Destroy", - "examine": "Some rock fragments.", - "durability": null, - "name": "Rock fragments", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13379", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop the letter, it will be destroyed and you'll need to see Bill Teach for another.", - "examine": "Note from Teach to Brass Hand Harry.", - "durability": null, - "name": "Introduction letter", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13380", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", - "examine": "One of many broken hands.", - "durability": null, - "name": "Broken hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13381", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", - "examine": "One of many broken hands.", - "durability": null, - "name": "Broken hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13382", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", - "examine": "One of many broken hands.", - "durability": null, - "name": "Broken hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13383", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", - "examine": "One of many broken hands.", - "durability": null, - "name": "Broken hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13384", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", - "examine": "One of many broken hands.", - "durability": null, - "name": "Broken hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13385", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Wall beast fingers in a white fern sauce.", - "durability": null, - "name": "Fingers", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13386", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", - "examine": "A brass thumb.", - "durability": null, - "name": "Thumb", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13387", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Hand", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13388", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", - "examine": "A brass wrist.", - "durability": null, - "name": "Wrist", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13389", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", - "examine": "A brass brace.", - "durability": null, - "name": "Brace", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13390", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this hand, you will destroy it and you will have to remake it from parts that Brass Hand Harry has.", - "examine": "A completed brass hand.", - "durability": null, - "name": "Brass hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13391", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this ink pad, you will lose it and will need to see Brass Hand Harry for a replacement.", - "examine": "It's soaked with ink.", - "durability": null, - "name": "Ink pad", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13392", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this hand, you will destroy it and you will have to remake it from parts that Brass Hand Harry has.", - "examine": "An inky brass hand.", - "durability": null, - "name": "Inky hand", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13393", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this paper, you will need to call to the guards for a replacement. ", - "examine": "This is generally used for writing on.", - "durability": null, - "name": "Paper", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13394", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop Brass Hand Harry's mark, it will be destroyed and you need to see him to get another.", - "examine": "Handprint from Brass Hand Harry.", - "durability": null, - "name": "Brass hand harry's mark", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13395", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Makes me itch.", - "durability": null, - "name": "Fake beard", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13396", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", - "examine": "It looks like someone has sneezed in it.", - "durability": null, - "name": "Fake moustache and nose", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13397", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", - "examine": "Why is the monocle nailed to it?", - "durability": null, - "name": "Fake monocle, moustache and nose", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13398", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "remove_head": "true", - "examine": "You can barely see where it connected to the mop handle.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", - "name": "Curly wig", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13399", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "examine": "It looks like it is part-dog, part-mould.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", - "name": "Straight wig", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "13400", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop this order for 'rum' you will need to speak to the Rusty Anchor barman to get another.", - "examine": "An order simply for 'rum'.", - "durability": null, - "name": "Order", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13401", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop Captain Braindeath's mark, you will need to speak to him to get another.", - "examine": "Signature of Captain Braindeath.", - "durability": null, - "name": "Braindeath's mark", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13402", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "300", - "examine": "A replica tinderbox made of solid gold.", - "durability": null, - "name": "Golden tinderbox", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13403", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A bow from a darker dimension.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "9", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "equip_audio": "3738", - "render_anim": "303", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "86850", - "attack_audios": "3731,0,0,0", - "name": "Dark bow", - "archery_ticket_price": "0", - "id": "13405", - "bonuses": "0,0,0,0,95,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "59171", - "name": "Ancient staff", - "archery_ticket_price": "0", - "id": "13406", - "bonuses": "10,-1,40,15,0,2,3,1,15,0,5,50,0,-1,10" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "This helmet is worn by archers.", - "grand_exchange_price": "46334", - "durability": null, - "name": "Archer helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13407", - "absorb": "0,3,1", - "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "This helmet is worn by berserkers.", - "grand_exchange_price": "45978", - "durability": null, - "name": "Berserker helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13408", - "absorb": "1,0,3", - "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "This helm is worn by warriors.", - "grand_exchange_price": "45664", - "durability": null, - "name": "Warrior helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13409", - "absorb": "1,0,3", - "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "This helm is worn by farseers.", - "grand_exchange_price": "45989", - "durability": null, - "name": "Farseer helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13410", - "absorb": "3,1,0", - "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Protective headwear made from crabs. Better than it sounds.", - "grand_exchange_price": "20378", - "durability": null, - "name": "Rock-shell helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13411", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,6,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A sturdy body armour made from rock crab pieces.", - "grand_exchange_price": "41788", - "durability": null, - "name": "Rock-shell plate", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13412", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Some tough leggings made from rock crab parts.", - "grand_exchange_price": "37139", - "durability": null, - "name": "Rock-shell legs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13413", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,10,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A helm fit for any Fremennik ranger.", - "grand_exchange_price": "37724", - "durability": null, - "name": "Spined helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13414", - "absorb": "0,3,1", - "bonuses": "0,-6,-6,-6,6,6,6,6,6,0,6,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A constant reminder that I'm above a Dagannoth in the food chain.", - "grand_exchange_price": "5773", - "durability": null, - "name": "Spined body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13415", - "absorb": "0,6,3", - "bonuses": "0,0,0,-15,15,40,32,45,20,40,30,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Stylish leg armour for rangers with a lingering smell of raw fish...", - "grand_exchange_price": "2696", - "durability": null, - "name": "Spined chaps", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13416", - "absorb": "0,4,2", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,10,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Make your foes cower by wearing a skull as a helmet!", - "grand_exchange_price": "39060", - "durability": null, - "name": "Skeletal helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13417", - "absorb": "3,1,0", - "bonuses": "0,0,0,2,-2,10,9,11,3,0,6,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The bones in this armour seems to vibrate with a magic quality...", - "grand_exchange_price": "26289", - "durability": null, - "name": "Skeletal top", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13418", - "absorb": "6,3,0", - "bonuses": "0,0,0,8,-10,35,25,42,15,0,30,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A superior set of strengthened slacks for any self respecting seer.", - "grand_exchange_price": "24591", - "durability": null, - "name": "Skeletal bottoms", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13419", - "absorb": "4,2,0", - "bonuses": "0,0,0,6,-7,22,20,24,10,0,10,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Some finely crafted Fremennik boots, made from spined dagannoth hide.", - "grand_exchange_price": "158181", - "durability": null, - "name": "Spined boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13420", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,1,1,0,0,0,1,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Some Fremennik boots, made from the shards of a rock crab's shell.", - "grand_exchange_price": "1358", - "durability": null, - "name": "Rock-shell boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13421", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Some finely crafted Fremennik boots, made from the bones of a Wallasalki.", - "grand_exchange_price": "7788", - "durability": null, - "name": "Skeletal boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13422", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Fremennik gloves stitched together from spined dagannoth hide.", - "grand_exchange_price": "3027", - "durability": null, - "name": "Spined gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13423", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,1,2,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Fremennik gloves stitched together from rock crab shell shards.", - "grand_exchange_price": "12839", - "durability": null, - "name": "Rock-shell gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13424", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Fremennik gloves stitched together from wallasalki bones fragments.", - "grand_exchange_price": "25838", - "durability": null, - "name": "Skeletal gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13425", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A mysterious ring that can fill the wearer with magical power...", - "grand_exchange_price": "799703", - "durability": null, - "name": "Seers ring", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13426", - "absorb": "0,0,0", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A fabled ring that improves the wearer's skill with a bow...", - "grand_exchange_price": "483521", - "durability": null, - "name": "Archers ring", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13427", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,4,0,0,0,0,4,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A legendary ring once worn by Fremennik warriors.", - "grand_exchange_price": "361302", - "durability": null, - "name": "Warrior ring", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13428", - "absorb": "0,0,0", - "bonuses": "0,4,0,0,0,0,4,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A ring reputed to bring out a berserk fury in its wearer.", - "grand_exchange_price": "963418", - "durability": null, - "name": "Berserker ring", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13429", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0" - }, - { - "examine": "A two-handed dragon sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "124", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "1024000", - "name": "Dragon 2h sword", - "archery_ticket_price": "0", - "id": "13430", - "bonuses": "-4,92,80,-4,0,0,0,0,0,-1,0,93,0,0,0" - }, - { - "shop_price": "20", - "examine": "Useful for catching crayfish.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "25", - "name": "Crayfish cage", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13431", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "20", - "examine": "Swap this note at any bank for the equivalent item.", - "grand_exchange_price": "25", - "durability": null, - "name": "Crayfish cage", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13432" - }, - { - "shop_price": "5", - "examine": "Some cooked crayfish. Eat it to heal.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "32", - "name": "Crayfish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13433", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "5", - "examine": "Swap this note at any bank for the equivalent item.", - "grand_exchange_price": "32", - "durability": null, - "name": "Crayfish", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13434" - }, - { - "shop_price": "5", - "examine": "I should try cooking this. Used in Cooking (1).", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "41", - "name": "Raw crayfish", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13435", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "5", - "examine": "Swap this note at any bank for the equivalent item.", - "grand_exchange_price": "41", - "durability": null, - "name": "Raw crayfish", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13436" - }, - { - "shop_price": "1", - "durability": null, - "name": "Burnt crayfish", - "tradeable": "true", - "archery_ticket_price": "0", - "destroy": "false", - "attack_speed": "4", - "id": "13437", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "examine": "Swap this note at any bank for the equivalent item.", - "durability": null, - "name": "Burnt crayfish", - "tradeable": "true", - "archery_ticket_price": "0", - "destroy": "false", - "attack_speed": "4", - "id": "13438" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13439", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "This is a bag of runes for Sir Vant.", - "durability": null, - "name": "Bag of runes", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13440", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A very powerful onyx amulet.", - "grand_exchange_price": "2285210", - "durability": null, - "name": "Amulet of fury", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13442", - "absorb": "0,0,0", - "bonuses": "10,10,10,10,10,15,15,15,15,15,15,8,0,5,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A cape woven of obsidian plates.", - "grand_exchange_price": "56575", - "durability": null, - "name": "Obsidian cape", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13443", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0" - }, - { - "examine": "A weapon from the Abyss.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "11", - "absorb": "0,0,0", - "render_anim": "1578", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "114775", - "name": "Abyssal whip", - "archery_ticket_price": "0", - "id": "13444", - "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0" - }, - { - "examine": "Simplicity is the best weapon.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "10", - "absorb": "0,0,0", - "render_anim": "27", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "29584", - "name": "Granite maul", - "archery_ticket_price": "0", - "id": "13445", - "bonuses": "0,0,81,0,0,0,0,0,0,0,0,79,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13446", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13447", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13448", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Protects your head and looks impressive too.", - "grand_exchange_price": "5756658", - "durability": null, - "name": "Dragon full helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13449", - "absorb": "2,0,4", - "bonuses": "0,0,0,-6,-2,45,48,41,-1,46,12,0,0,0,0" - }, - { - "examine": "A beautiful, heavy sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "1579", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "7767458", - "name": "Armadyl godsword", - "archery_ticket_price": "0", - "id": "13450", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" - }, - { - "examine": "A brutally heavy sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "1579", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "1504919", - "name": "Bandos godsword", - "archery_ticket_price": "0", - "id": "13451", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" - }, - { - "examine": "A gracious, heavy sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "1579", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "34966317", - "name": "Saradomin godsword", - "archery_ticket_price": "0", - "id": "13452", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" - }, - { - "examine": "A terrifying, heavy sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "1579", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "2132037", - "name": "Zamorak godsword", - "archery_ticket_price": "0", - "id": "13453", - "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" - }, - { - "examine": "An evil spear.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "1581", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "2070507", - "name": "Zamorakian spear", - "archery_ticket_price": "0", - "id": "13454", - "bonuses": "85,65,65,0,0,13,13,12,0,13,0,75,0,2,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A helmet of great craftmanship.", - "grand_exchange_price": "3732060", - "durability": null, - "name": "Armadyl helmet", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13455", - "absorb": "0,5,2", - "bonuses": "-5,-5,-5,-5,10,6,6,10,10,8,12,0,0,1,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A chestplate of great craftsmanship", - "grand_exchange_price": "9628666", - "durability": null, - "name": "Armadyl chestplate", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13456", - "absorb": "0,10,5", - "bonuses": "-7,-7,-7,-15,33,56,48,61,70,57,52,0,0,1,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A chainskirt of great craftsmanship.", - "grand_exchange_price": "9754868", - "durability": null, - "name": "Armadyl plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13457", - "absorb": "0,7,3", - "bonuses": "-6,-6,-6,-10,20,32,26,34,40,33,25,0,0,1,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A sturdy chestplate.", - "grand_exchange_price": "6460055", - "durability": null, - "name": "Bandos chestplate", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13458", - "absorb": "4,0,9", - "bonuses": "0,0,0,-15,-10,98,93,105,-6,133,52,4,0,1,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A sturdy pair of tassets.", - "grand_exchange_price": "4228256", - "durability": null, - "name": "Bandos tassets", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13459", - "absorb": "3,0,6", - "bonuses": "0,0,0,-21,-7,71,63,66,-4,93,25,2,0,1,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Some sturdy boots.", - "grand_exchange_price": "1259091", - "durability": null, - "name": "Bandos boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13460", - "absorb": "0,0,0", - "bonuses": "0,0,0,-5,-3,17,18,19,0,0,15,0,0,1,0" - }, - { - "examine": "The incredible blade of an Icyene.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "1579", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "850151", - "name": "Saradomin sword", - "archery_ticket_price": "0", - "id": "13461", - "bonuses": "0,82,60,0,0,0,0,0,0,0,0,82,0,2,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These will protect my feet.", - "grand_exchange_price": "17336", - "durability": null, - "name": "Dragon boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13462", - "absorb": "0,0,0", - "bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13463", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another by talking about jobs with citizens and tutors around Lumbridge.", - "examine": "This reminds me of my current job and who set me to the task.", - "durability": null, - "name": "Task list", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13464", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A powerful dagger.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "defence_anim": "397", - "attack_anims": "396,396,395,396", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "16744", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger", - "archery_ticket_price": "0", - "id": "13465", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "defence_anim": "397", - "attack_anims": "396,396,395,396", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger(p)", - "archery_ticket_price": "0", - "id": "13466", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "defence_anim": "397", - "attack_anims": "396,396,395,396", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger(p+)", - "archery_ticket_price": "0", - "id": "13467", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "defence_anim": "397", - "attack_anims": "396,396,395,396", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dragon dagger(p++)", - "archery_ticket_price": "0", - "id": "13468", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "examine": "A powerful axe.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "2", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "7263", - "name": "Rune axe", - "archery_ticket_price": "0", - "id": "13469", - "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0" - }, - { - "examine": "A very powerful axe.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "2", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "3794577", - "name": "Dragon axe", - "archery_ticket_price": "0", - "id": "13470", - "bonuses": "-2,38,32,0,0,0,1,0,0,0,0,42,0,0,0" - }, - { - "examine": "A vicious looking axe.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "2", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "23993", - "name": "Rune battleaxe", - "archery_ticket_price": "0", - "id": "13471", - "bonuses": "-2,48,43,0,0,0,0,0,0,-1,0,64,0,0,0" - }, - { - "requirements": "{0,60}", - "examine": "A vicious looking axe.", - "has_special": "true", - "durability": null, - "destroy": "true", - "weight": "2.7", - "attack_speed": "6", - "weapon_interface": "2", - "absorb": "0,0,0", - "render_anim": "2586", - "defence_anim": "397", - "attack_anims": "395,395,401,395", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "123019", - "attack_audios": "2498,2498,2497,2498", - "name": "Dragon battleaxe", - "archery_ticket_price": "0", - "id": "13472", - "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0" - }, - { - "examine": "I don't think it's intended for joinery.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "10", - "absorb": "0,0,0", - "render_anim": "1430", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "24357", - "name": "Rune warhammer", - "archery_ticket_price": "0", - "id": "13473", - "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0" - }, - { - "examine": "A razor-sharp longsword", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "1582", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "18420", - "name": "Rune longsword", - "archery_ticket_price": "0", - "id": "13474", - "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0" - }, - { - "examine": "A very powerful sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "1582", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "58355", - "name": "Dragon longsword", - "archery_ticket_price": "0", - "id": "13475", - "bonuses": "58,69,-2,0,0,0,3,2,0,0,0,71,0,0,0" - }, - { - "examine": "A vicious, curved sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1582", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "14690", - "name": "Rune scimitar", - "archery_ticket_price": "0", - "id": "13476", - "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0" - }, - { - "examine": "A vicious, curved sword.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1928", - "attack_anims": "390,390,381,390", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "60405", - "name": "Dragon scimitar", - "archery_ticket_price": "0", - "id": "13477", - "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0" - }, - { - "examine": "A dragon halberd.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "15", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "200189", - "name": "Dragon halberd", - "archery_ticket_price": "0", - "id": "13478", - "bonuses": "70,95,0,-4,0,-1,4,5,0,0,0,89,0,0,0" - }, - { - "requirements": "{0,60}", - "examine": "A spiky mace.", - "has_special": "true", - "durability": null, - "destroy": "true", - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "8", - "absorb": "0,0,0", - "defence_anim": "397", - "attack_anims": "390,390,381,390", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "28817", - "name": "Dragon mace", - "archery_ticket_price": "0", - "id": "13479", - "bonuses": "40,-2,60,0,0,0,0,0,0,0,0,55,0,5,0" - }, - { - "examine": "Used for mining.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "4", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "18546", - "name": "Rune pickaxe", - "archery_ticket_price": "0", - "id": "13480", - "bonuses": "26,-2,24,0,0,0,1,0,0,0,0,29,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A series of connected metal rings.", - "grand_exchange_price": "2280904", - "durability": null, - "name": "Dragon chainbody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13481", - "absorb": "4,0,9", - "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Provides excellent protection.", - "grand_exchange_price": "38062", - "durability": null, - "name": "Rune platebody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13482", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "4373", - "durability": null, - "name": "Green d'hide body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13483", - "absorb": "0,6,3", - "bonuses": "0,0,0,-20,15,40,32,45,20,40,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "5266", - "durability": null, - "name": "Blue d'hide body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13484", - "absorb": "0,6,3", - "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "6276", - "durability": null, - "name": "Red d'hide body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13485", - "absorb": "0,6,3", - "bonuses": "0,0,0,-15,25,50,42,55,40,50,50,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "7619", - "durability": null, - "name": "Black d'hide body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13486", - "absorb": "0,6,3", - "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These look pretty heavy.", - "grand_exchange_price": "37355", - "durability": null, - "name": "Rune platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13487", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Looks pretty heavy.", - "grand_exchange_price": "160755", - "durability": null, - "name": "Dragon platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13488", - "absorb": "3,0,6", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Designer leg protection.", - "grand_exchange_price": "37248", - "durability": null, - "name": "Rune plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13489", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "This looks pretty heavy.", - "grand_exchange_price": "161006", - "durability": null, - "name": "Dragon plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13490", - "absorb": "3,0,6", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "100% real dragonhide.", - "grand_exchange_price": "2037", - "durability": null, - "name": "Green d'hide chaps", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13491", - "absorb": "0,4,2", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "2352", - "durability": null, - "name": "Blue d'hide chaps", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13492", - "absorb": "0,5,2", - "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "2761", - "durability": null, - "name": "Red d'hide chaps", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13493", - "absorb": "0,6,3", - "bonuses": "0,0,0,-10,14,28,22,30,20,28,25,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "3377", - "durability": null, - "name": "Black d'hide chaps", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13494", - "absorb": "0,7,3", - "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Makes the wearer pretty intimidating.", - "grand_exchange_price": "59676", - "durability": null, - "name": "Dragon med helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13495", - "absorb": "2,0,4", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A full face helmet.", - "grand_exchange_price": "20388", - "durability": null, - "name": "Rune full helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13496", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "1208", - "durability": null, - "name": "Green d'hide vamb", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13497", - "absorb": "0,0,0", - "bonuses": "0,0,0,-10,8,3,2,4,2,0,3,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Made from 100% real dragonhide.", - "grand_exchange_price": "1488", - "durability": null, - "name": "Blue d'hide vamb", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13498", - "absorb": "0,0,0", - "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Vambraces made from 100% real dragonhide.", - "grand_exchange_price": "1714", - "durability": null, - "name": "Red d'hide vamb", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13499", - "absorb": "0,0,0", - "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Vambraces made from 100% real dragonhide.", - "grand_exchange_price": "2208", - "durability": null, - "name": "Black d'hide vamb", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13500", - "absorb": "0,0,0", - "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A wooden helmet.", - "grand_exchange_price": "5210", - "durability": null, - "name": "Splitbark helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13501", - "absorb": "3,1,0", - "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Provides good protection.", - "grand_exchange_price": "27106", - "durability": null, - "name": "Splitbark body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13502", - "absorb": "6,3,0", - "bonuses": "0,0,0,10,-10,36,26,42,15,0,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These should protect my legs.", - "grand_exchange_price": "56050", - "durability": null, - "name": "Splitbark legs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13503", - "absorb": "4,2,0", - "bonuses": "0,0,0,7,-7,22,20,25,10,0,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These should keep my hands safe.", - "grand_exchange_price": "2442", - "durability": null, - "name": "Splitbark gauntlets", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13504", - "absorb": "0,0,0", - "bonuses": "0,0,0,2,-1,3,2,4,2,0,3,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Wooden foot protection.", - "grand_exchange_price": "6845", - "durability": null, - "name": "Splitbark boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13505", - "absorb": "0,0,0", - "bonuses": "0,0,0,2,-1,3,2,4,2,0,9,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "An ancient and powerful looking Dragon Square shield.", - "grand_exchange_price": "328356", - "durability": null, - "name": "Dragon sq shield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13506", - "absorb": "5,0,11", - "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A large metal shield.", - "grand_exchange_price": "31885", - "durability": null, - "name": "Rune kiteshield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13507", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Blue: A magical hat. ", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13508", - "absorb": "3,1,0", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The upper half of a magical robe.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic robe top", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13509", - "absorb": "3,1,0", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The lower half of a magical robe.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic robe bottom", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13510", - "absorb": "4,2,0", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Bright/Dark magical gloves.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13511", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Magical boots.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13512", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Blue: A magical hat. ", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13513", - "absorb": "3,1,0", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The upper half of a magical robe.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic robe top", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13514", - "absorb": "3,1,0", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The lower half of a magical robe.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic robe bottom", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13515", - "absorb": "4,2,0", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Bright/Dark magical gloves.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13516", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Magical boots.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13517", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Blue: A magical hat. ", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13518", - "absorb": "3,1,0", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The upper half of a magical robe.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic robe top", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13519", - "absorb": "3,1,0", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The lower half of a magical robe.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic robe bottom", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13520", - "absorb": "4,2,0", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Bright/Dark magical gloves.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13521", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Magical boots.", - "grand_exchange_price": "1", - "durability": null, - "name": "Mystic boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13522", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" - }, - { - "examine": "A nice sturdy bow made out of maple.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "193", - "name": "Maple longbow", - "archery_ticket_price": "0", - "id": "13523", - "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A shortbow made out of maple, still effective.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "111", - "name": "Maple shortbow", - "archery_ticket_price": "0", - "id": "13524", - "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A nice sturdy bow made out of yew.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "486", - "name": "Yew longbow", - "archery_ticket_price": "0", - "id": "13525", - "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A shortbow made out of yew, still effective.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "253", - "name": "Yew shortbow", - "archery_ticket_price": "0", - "id": "13526", - "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A nice sturdy magical bow.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "1211", - "name": "Magic longbow", - "archery_ticket_price": "0", - "id": "13527", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "Short and magical, but still effective.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "655", - "name": "Magic shortbow", - "archery_ticket_price": "0", - "id": "13528", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "An ancient Fremennik bow that was once used to battle the Moon Clan.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "21698", - "name": "Seercull", - "archery_ticket_price": "0", - "id": "13529", - "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A runite crossbow.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "17", - "absorb": "0,0,0", - "render_anim": "175", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "8890", - "name": "Rune crossbow", - "archery_ticket_price": "0", - "id": "13530", - "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "1696744720", - "durability": null, - "name": "Red partyhat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13531", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "1314730495", - "durability": null, - "name": "Yellow partyhat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13532", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "2147483647", - "durability": null, - "name": "Blue partyhat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13533", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "1481913809", - "durability": null, - "name": "Green partyhat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13534", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "1248900588", - "durability": null, - "name": "Purple partyhat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13535", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A nice hat from a cracker.", - "grand_exchange_price": "2147473360", - "durability": null, - "name": "White partyhat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13536", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "It's a Santa hat.", - "grand_exchange_price": "130433327", - "durability": null, - "name": "Santa hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13537", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Aaaarrrghhh ... I'm a monster.", - "grand_exchange_price": "104671288", - "durability": null, - "name": "Green h'ween mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13538", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Aaaarrrghhh ... I'm a monster.", - "grand_exchange_price": "127720943", - "durability": null, - "name": "Blue h'ween mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13539", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Aaaarrrghhh ... I'm a monster.", - "grand_exchange_price": "171640098", - "durability": null, - "name": "Red h'ween mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13540", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A powerful bow made from willow.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "2606", - "name": "Willow comp bow", - "archery_ticket_price": "0", - "id": "13541", - "bonuses": "0,0,0,0,22,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A powerful bow made from yew wood.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "588", - "name": "Yew comp bow", - "archery_ticket_price": "0", - "id": "13542", - "bonuses": "0,0,0,0,49,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A powerful bow made from magic wood.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "1345", - "name": "Magic comp bow", - "archery_ticket_price": "0", - "id": "13543", - "bonuses": "0,0,0,0,71,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient range protection crafted from white dragonhide.", - "grand_exchange_price": "74503559", - "durability": null, - "name": "3rd age range top", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13544", - "absorb": "0,6,3", - "bonuses": "0,0,0,-15,30,55,47,60,60,55,52,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Fabulously ancient range protection crafted from white dragonhide.", - "grand_exchange_price": "47837515", - "durability": null, - "name": "3rd age range legs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13545", - "absorb": "0,4,2", - "bonuses": "0,0,0,-10,17,31,25,33,30,31,25,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient range protection crafted from white dragonhide.", - "grand_exchange_price": "9746895", - "durability": null, - "name": "3rd age range coif", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13546", - "absorb": "0,3,1", - "bonuses": "0,0,0,-2,9,4,7,10,5,8,12,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Fabulously ancient range protection crafted from white dragonhide.", - "grand_exchange_price": "6826420", - "durability": null, - "name": "3rd age vambraces", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13547", - "absorb": "0,0,0", - "bonuses": "0,0,0,-11,11,6,5,7,9,0,5,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "grand_exchange_price": "138719269", - "durability": null, - "name": "3rd age robe top", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13548", - "absorb": "4,2,0", - "bonuses": "0,0,0,24,0,0,0,0,24,0,24,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "grand_exchange_price": "89961678", - "durability": null, - "name": "3rd age robe", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13549", - "absorb": "4,2,0", - "bonuses": "0,0,0,19,0,0,0,0,19,0,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "grand_exchange_price": "14976830", - "durability": null, - "name": "3rd age mage hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13550", - "absorb": "2,1,0", - "bonuses": "0,0,0,8,0,0,0,0,8,0,12,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient mage protection enchanted in the Third-Age.", - "grand_exchange_price": "35019596", - "durability": null, - "name": "3rd age amulet", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13551", - "absorb": "0,0,0", - "bonuses": "0,0,0,15,0,0,0,0,10,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient armour beaten from magical silver.", - "grand_exchange_price": "244180930", - "durability": null, - "name": "3rd age platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13552", - "absorb": "3,0,6", - "bonuses": "0,0,0,-25,-2,78,76,83,-5,75,25,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient armour beaten from magical silver.", - "grand_exchange_price": "266509014", - "durability": null, - "name": "3rd age platebody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13553", - "absorb": "4,0,9", - "bonuses": "0,0,0,-20,0,96,108,113,-4,97,52,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient armour beaten from magical silver.", - "grand_exchange_price": "50697678", - "durability": null, - "name": "3rd age full helmet", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13554", - "absorb": "2,0,4", - "bonuses": "0,0,0,-5,-2,47,49,43,-3,48,12,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Ancient armour beaten from magical silver.", - "grand_exchange_price": "91262203", - "durability": null, - "name": "3rd age kiteshield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13555", - "absorb": "5,0,11", - "bonuses": "0,0,0,-10,-4,63,65,61,-3,63,60,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Lightweight boots ideal for rangers.", - "grand_exchange_price": "6253527", - "durability": null, - "name": "Ranger boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13556", - "absorb": "0,0,0", - "bonuses": "0,0,0,-10,8,2,3,4,2,0,10,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Slightly magical boots.", - "grand_exchange_price": "388955", - "durability": null, - "name": "Wizard boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13557", - "absorb": "0,0,0", - "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Endorsed by Robin Hood.", - "grand_exchange_price": "1962571", - "durability": null, - "name": "Robin hood hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13558", - "absorb": "0,0,0", - "bonuses": "0,0,0,-10,8,4,6,8,4,4,7,0,0,0,0" - }, - { - "destroy_message": "You will have talk to Explorer Jack in Lumbridge if you destroy this one.", - "shop_price": "350", - "examine": "A Lumbridge explorer's ring.", - "durability": null, - "name": "Explorer's ring 1", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13560", - "absorb": "0,0,0", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", - "equipment_slot": "12" - }, - { - "destroy_message": "You will have talk to ", - "shop_price": "350", - "examine": "A Lumbridge explorer's ring.", - "durability": null, - "name": "Explorer's ring 2", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13561", - "absorb": "0,0,0", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", - "equipment_slot": "12" - }, - { - "destroy_message": "You will need to obtain a new ring from Ned in Draynor if you destroy this one.", - "shop_price": "350", - "examine": "A Lumbridge explorer's ring.", - "durability": null, - "name": "Explorer's ring 3", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13562", - "absorb": "0,0,0", - "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", - "equipment_slot": "12" - }, - { - "shop_price": "38", - "examine": "An occasionally edible mushroom.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "100", - "name": "Button mushroom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13563", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "38", - "examine": "An occasionally edible mushroom.", - "grand_exchange_price": "100", - "durability": null, - "name": "Button mushroom", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13564" - }, - { - "durability": null, - "name": "Doll", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13565", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You may be able to find a new ring near where Summer stood outside the wilderness wall.", - "examine": "This magical ring once belonged to Summer's mother.", - "durability": null, - "name": "Jennica's ring", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13566", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "destroy_message": "Drop", - "examine": "Logs cut from a cursed magic tree.", - "durability": null, - "name": "Cursed magic logs", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13567", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Logs cut from a cursed magic tree.", - "durability": null, - "name": "Cursed magic logs", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13568" - }, - { - "destroy_message": "Hopefully, Jorral will be able to return them.", - "examine": "Notes on how to use the enchanted key.", - "durability": null, - "name": "Enchanted key notes", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13569", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Useful for mixing things.", - "grand_exchange_price": "106", - "durability": null, - "name": "Bowl", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13570", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "It's a bucket of milk.", - "grand_exchange_price": "177", - "durability": null, - "name": "Bucket of milk", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13571", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A fresh herb.", - "grand_exchange_price": "595", - "durability": null, - "name": "Clean guam", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13572", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You'll have to start again from stratch.", - "examine": "A bowlful of bees' precious product.", - "durability": null, - "name": "Bowl of honey", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13573", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You'll have to start again from stratch.", - "examine": "A bowlful of milk and honey.", - "durability": null, - "name": "Bowl of milk and honey", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13574", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You'll have to start again from stratch.", - "examine": "A bowl full of milk, honey and guam.", - "durability": null, - "name": "Bowl of milk, honey and guam", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13575", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Hopefully, the family has more papyrus and charcoal.", - "examine": "Your best impression of a map of 2009Scape.", - "durability": null, - "name": "Map of 2009Scape", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13576", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "Used for making notes.", - "grand_exchange_price": "290", - "durability": null, - "name": "Papyrus", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13577", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A lump of charcoal.", - "grand_exchange_price": "296", - "durability": null, - "name": "Charcoal", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13578", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A slightly muddy spade. ", - "grand_exchange_price": "130", - "durability": null, - "name": "Spade", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13579", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A plant pot filled with soil.", - "durability": null, - "name": "Plant pot", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13580", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A seedling has been sown in this plant pot.", - "durability": null, - "name": "Pear tree seedling", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13581", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A seedling has been sown in this plant pot.", - "durability": null, - "name": "Mango tree seedling", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13582", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A seedling has been sown in this plant pot.", - "durability": null, - "name": "Quince tree seedling", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13583", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A seedling has been sown in this plant pot.", - "durability": null, - "name": "Lemon tree seedling", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13584", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A seedling has been sown in this plant pot.", - "durability": null, - "name": "Avocado tree seedling", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13585", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A seedling has been sown in this plant pot.", - "durability": null, - "name": "Plum tree seedling", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13586", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "4", - "examine": "I can grind things for potions in this.", - "grand_exchange_price": "169", - "durability": null, - "name": "Pestle and mortar", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13587", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "One of the ingredients for making fish food.", - "grand_exchange_price": "5", - "durability": null, - "name": "Ground guam", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13588", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "2", - "examine": "It's an empty bucket. ", - "grand_exchange_price": "39", - "durability": null, - "name": "Bucket", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13589", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "It seems to change temperature as I walk. (Making History)", - "durability": null, - "name": "Enchanted key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13591", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Hopefully, you can find another.", - "examine": "Some ladies jewellery.", - "durability": null, - "name": "A brooch", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13592", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will not get another chance to read the book!", - "examine": "It's falling apart, but full of knowledge.", - "durability": null, - "name": "Old tome", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13593", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Runecrafting guild teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13598", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Air altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13599", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Mind altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13600", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Water altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13601", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Earth altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13602", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Fire altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13603", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Body altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13604", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Cosmic altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13605", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Chaos altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13606", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Nature altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13607", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Law altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13608", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Death altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13609", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Blood altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13610", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A tablet containing a magic spell.", - "durability": null, - "name": "Astral altar teleport", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13611", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "20", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13612", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "20", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13613", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "shop_price": "75", - "examine": "Heavy duty wizard robes.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Runecrafter robe", - "archery_ticket_price": "0", - "id": "13614", - "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13615", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13616", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "A heavy-duty wizard robe.", - "durability": null, - "name": "Runecrafter skirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13617", - "absorb": "0,0,0", - "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Essence can be rough on the hands", - "durability": null, - "name": "Runecrafter gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13618", - "absorb": "0,0,0", - "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "75", - "examine": "Heavy duty wizard robes.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Runecrafter robe", - "archery_ticket_price": "0", - "id": "13619", - "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13620", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13621", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "A heavy-duty wizard robe.", - "durability": null, - "name": "Runecrafter skirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13622", - "absorb": "0,0,0", - "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Essence can be rough on the hands", - "durability": null, - "name": "Runecrafter gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13623", - "absorb": "0,0,0", - "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "75", - "examine": "Heavy duty wizard robes.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Runecrafter robe", - "archery_ticket_price": "0", - "id": "13624", - "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13625", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13626", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "A heavy-duty wizard robe.", - "durability": null, - "name": "Runecrafter skirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13627", - "absorb": "0,0,0", - "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Essence can be rough on the hands", - "durability": null, - "name": "Runecrafter gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13628", - "absorb": "0,0,0", - "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Drop", - "shop_price": "15", - "examine": "Staff with a holder for a talisman on top.", - "durability": null, - "name": "Runecrafting staff", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "5", - "id": "13629", - "absorb": "0,0,0", - "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0", - "render_anim": "28" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Air talisman staff", - "archery_ticket_price": "0", - "id": "13630", - "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Mind talisman staff", - "archery_ticket_price": "0", - "id": "13631", - "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Water talisman staff", - "archery_ticket_price": "0", - "id": "13632", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Earth talisman staff", - "archery_ticket_price": "0", - "id": "13633", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Fire talisman staff", - "archery_ticket_price": "0", - "id": "13634", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Body talisman staff", - "archery_ticket_price": "0", - "id": "13635", - "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Cosmic talisman staff", - "archery_ticket_price": "0", - "id": "13636", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Chaos talisman staff", - "archery_ticket_price": "0", - "id": "13637", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "No", - "name": "Nature talisman staff", - "archery_ticket_price": "0", - "id": "13638", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Law talisman staff", - "archery_ticket_price": "0", - "id": "13639", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Death talisman staff", - "archery_ticket_price": "0", - "id": "13640", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Blood talisman staff", - "archery_ticket_price": "0", - "id": "13641", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "1500", - "examine": "A staff with a talisman on top.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "You will have to speak to Wizard Elriss to get another omni-talisman.", - "name": "Omni-talisman staff", - "archery_ticket_price": "0", - "id": "13642", - "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" - }, - { - "shop_price": "20", - "examine": "Attracts Runecrafting energy orbs in the rune altars.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "If you destroy this, you will leave the game.", - "name": "Yellow attractor", - "archery_ticket_price": "0", - "id": "13643", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "Repels Runecrafting energy orbs in the rune altars.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "If you destroy this, you will leave the game.", - "name": "Yellow repeller", - "archery_ticket_price": "0", - "id": "13644", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "Attracts Runecrafting energy orbs in the rune altars.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "If you destroy this, you will leave the game.", - "name": "Green attractor", - "archery_ticket_price": "0", - "id": "13645", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "Repels Runecrafting energy orbs in the rune altars.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "If you destroy this, you will leave the game.", - "name": "Green repeller", - "archery_ticket_price": "0", - "id": "13646", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "It creates barriers.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "If you destroy this, you will leave the game.", - "name": "Green barrier generator", - "archery_ticket_price": "0", - "id": "13647", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "It creates barriers.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "If you destroy this, you will leave the game.", - "name": "Yellow barrier generator", - "archery_ticket_price": "0", - "id": "13648", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will have to speak to ", - "shop_price": "4", - "examine": "Many mysterious powers emanate from the talisman.", - "durability": null, - "name": "Omni-talisman", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13649", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "Wizard Elriss will exchange these for rewards.", - "durability": null, - "name": "Runecrafting guild token", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13650", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "Wizard Elriss will exchange these for rewards.", - "durability": null, - "name": "Runecrafting guild token", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13651", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "Wizard Elriss will exchange these for rewards.", - "durability": null, - "name": "Runecrafting guild token", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13652", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "Wizard Elriss will exchange these for rewards.", - "durability": null, - "name": "Runecrafting guild token", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13653", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "Wizard Elriss will exchange these for rewards.", - "durability": null, - "name": "Runecrafting guild token", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13654", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will have to speak to Wizard Elriss to get another omni-talisman.", - "shop_price": "100", - "examine": "A tiara infused with the properties of all talismans.", - "durability": null, - "name": "Omni-tiara", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13655", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13656", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13657", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Comes with goggles, for extra safety while Runecrafting.", - "durability": null, - "name": "Runecrafter hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13658", - "absorb": "0,0,0", - "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "shop_price": "100", - "examine": "It burns, burns, burns...", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "12", - "destroy_message": "To get another Ring of Fire, you need to keep six beacons alight simultaneously and then talk to King Roald.", - "name": "Ring of fire", - "archery_ticket_price": "0", - "id": "13659", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "point_price": "50" - }, - { - "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", - "examine": "The hottest gloves in town.", - "durability": null, - "name": "Flame gloves", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13660", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "shop_price": "300", - "examine": "Danger: risk of fire.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "2", - "absorb": "0,0,0", - "render_anim": "1096", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "destroy_message": "To get another Inferno Adze, you need to keep all fourteen beacons alight simultaneously and then talk to King Roald.", - "name": "Inferno adze", - "archery_ticket_price": "0", - "id": "13661", - "bonuses": "10,9,7,0,0,0,1,0,0,0,0,11,0,0,0", - "point_price": "75" - }, - { - "durability": null, - "name": "Fire beacon", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13662", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "The ticket says: Tearing this ticket will make you leave the circus. Choose wisely.", - "shop_price": "10", - "examine": "Tear ticket to exit the circus.", - "durability": null, - "name": "Circus ticket", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13663", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "shop_price": "10", - "examine": "Let's give them a big hand!", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "326", - "equipment_slot": "3", - "destroy_message": "You will need to speak to the ringmaster to get another one.", - "name": "Giant's hand", - "archery_ticket_price": "0", - "id": "13666", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "10", - "examine": "A clown hat!", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "Clown hat", - "archery_ticket_price": "0", - "id": "13667", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "10", - "examine": "Buttoning this up is tricky.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "remove_sleeves": "true", - "name": "Clown shirt", - "archery_ticket_price": "0", - "id": "13668", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "These are my funny pants.", - "durability": null, - "name": "Clown leggings", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13669", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "For helping clowns stay upright.", - "durability": null, - "name": "Clown shoes", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13670", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "shop_price": "10", - "examine": "For making a happy noise.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "8", - "absorb": "0,0,0", - "render_anim": "327", - "equipment_slot": "3", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "Tambourine", - "archery_ticket_price": "0", - "id": "13671", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another one.", - "shop_price": "10", - "examine": "Very stylish.", - "durability": null, - "name": "Ringmaster hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13672", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "shop_price": "10", - "examine": "Fits nicely.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You will need to speak to the ringmaster to get another one.", - "remove_sleeves": "true", - "name": "Ringmaster shirt", - "archery_ticket_price": "0", - "id": "13673", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another one.", - "shop_price": "10", - "examine": "Very stylish.", - "durability": null, - "name": "Ringmaster pants", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13674", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another one.", - "shop_price": "10", - "examine": "Shiny.", - "durability": null, - "name": "Ringmaster boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13675", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "shop_price": "10", - "examine": "For shouting at people.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "8", - "absorb": "0,0,0", - "render_anim": "328", - "equipment_slot": "3", - "destroy_message": "You will need to speak to the ringmaster to get another one.", - "name": "Mega-phonus", - "archery_ticket_price": "0", - "id": "13676", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "10", - "examine": "Stretchy.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "remove_sleeves": "true", - "name": "Acrobat shirt", - "archery_ticket_price": "0", - "id": "13677", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "Very tight fitting.", - "durability": null, - "name": "Acrobat pants", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13678", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "These keep your feet off the floor.", - "durability": null, - "name": "Acrobat shoes", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13679", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "remove_head": "true", - "shop_price": "10", - "examine": "Oh no, I'm bald! Just kidding.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "Acrobat hood", - "archery_ticket_price": "0", - "id": "13680", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "shop_price": "400", + "tradeable": "false" }, { - "shop_price": "10", - "examine": "Stretchy.", - "durability": null, + "id": "13278", + "name": "Broad arrow heads", + "examine": "For use against turoth and kurasks.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "remove_sleeves": "true", - "name": "Acrobat shirt", - "archery_ticket_price": "0", - "id": "13681", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "destroy_message": "Drop", + "durability": null, + "shop_price": "50", + "tradeable": "false" }, { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "Very tight fitting.", - "durability": null, - "name": "Acrobat pants", + "id": "13279", + "name": "Unfinished broad bolts", + "examine": "For use against turoth and kurasks.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13682", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" + "destroy_message": "Drop", + "durability": null, + "shop_price": "50", + "tradeable": "false" }, { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "These keep your feet off the floor.", - "durability": null, - "name": "Acrobat shoes", + "id": "13280", + "name": "Broad-tipped bolts", + "examine": "For use against turoth and kurasks.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "13", + "shop_price": "50", + "tradeable": "true" + }, + { + "id": "13281", + "name": "Ring of slaying(8)", + "examine": "An enchanted ring.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13683", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "remove_head": "true", - "shop_price": "10", - "examine": "Oh no, I'm bald! Just kidding.", - "durability": null, - "destroy": "true", - "attack_speed": "4", + "id": "13282", + "name": "Ring of slaying(7)", + "examine": "An enchanted ring.", "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "Acrobat hood", - "archery_ticket_price": "0", - "id": "13684", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "Very dapper!", - "durability": null, - "name": "A stylish hat", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13685", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "Very dapper!", - "durability": null, - "name": "A stylish hat", - "destroy": "true", + "id": "13283", + "name": "Ring of slaying(6)", + "examine": "An enchanted ring.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13686", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "destroy_message": "You will need to speak to the ringmaster to get another.", - "shop_price": "10", - "examine": "Very dapper!", - "durability": null, - "name": "A stylish hat", - "destroy": "true", + "id": "13284", + "name": "Ring of slaying(5)", + "examine": "An enchanted ring.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13687", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "0" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "remove_head": "true", - "shop_price": "10", - "examine": "Very dapper!", - "durability": null, - "destroy": "true", - "attack_speed": "4", + "id": "13285", + "name": "Ring of slaying(4)", + "examine": "An enchanted ring.", "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "A stylish hat", - "archery_ticket_price": "0", - "id": "13688", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "10", - "examine": "Very dapper!", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "A stylish hat", - "archery_ticket_price": "0", - "id": "13689", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "10", - "examine": "Very dapper!", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "You will need to speak to the ringmaster to get another.", - "name": "A stylish hat", - "archery_ticket_price": "0", - "id": "13690", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_sleeves": "true", - "shop_price": "10", - "durability": null, - "name": "Shirt", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13691", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "remove_sleeves": "true", - "shop_price": "10", - "durability": null, - "name": "Shirt", + "id": "13286", + "name": "Ring of slaying(3)", + "examine": "An enchanted ring.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13692", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "remove_sleeves": "true", - "shop_price": "10", - "durability": null, - "name": "Shirt", + "id": "13287", + "name": "Ring of slaying(2)", + "examine": "An enchanted ring.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13693", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "remove_sleeves": "true", - "shop_price": "10", - "durability": null, - "name": "Shirt", + "id": "13288", + "name": "Ring of slaying(1)", + "examine": "An enchanted ring.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13694", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" + "destroy": "false", + "durability": null, + "equipment_slot": "12", + "shop_price": "150", + "tradeable": "false" }, { - "remove_sleeves": "true", - "shop_price": "10", - "durability": null, - "name": "Shirt", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13695", + "id": "13290", + "name": "Leaf-bladed sword", + "examine": "A razor-sharp sword.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "remove_sleeves": "true", - "shop_price": "10", - "durability": null, - "name": "Shirt", "archery_ticket_price": "0", + "attack_anims": "381,381,390,381", + "attack_audios": "2517,2517,2500,2517", "attack_speed": "4", - "id": "13696", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "shop_price": "10", + "bonuses": "67,62,0,0,0,0,0,0,0,0,0,50,0,0,0", + "defence_anim": "397", + "destroy": "false", "durability": null, - "name": "Leggings", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13697", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "10", - "durability": null, - "name": "Leggings", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13698", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "10", - "durability": null, - "name": "Leggings", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13699", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "10", - "durability": null, - "name": "Skirt", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13700", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "10", - "durability": null, - "name": "Skirt", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13701", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "10", - "durability": null, - "name": "Skirt", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13702", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "10", - "durability": null, - "name": "Shoes", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13703", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "shop_price": "10", - "durability": null, - "name": "Shoes", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13704", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "shop_price": "10", - "durability": null, - "name": "Shoes", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13705", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "shop_price": "10", - "durability": null, - "name": "Shoes", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13706", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "destroy_message": "You can get another Tightrope 101 by speaking to the Agility assistant.", - "examine": "Shows you the moves you need to succeed!", - "durability": null, - "name": "Tightrope 101", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13707", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another Tightrope 101 by speaking to the Agility assistant.", - "examine": "Shows you the moves you need to succeed!", - "durability": null, - "name": "Tightrope 101", + "equip_audio": "2248", + "equipment_slot": "3", + "rare_item": "true", + "requirements": "{0,50}-{18,55}", + "run_anim": "824", + "shop_price": "68000", + "stand_anim": "813", + "stand_turn_anim": "823", "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13708" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 10 is advised when juggling these.", - "durability": null, - "name": "Balls (level 10 approx.)", - "destroy": "true", + "id": "13291", + "name": "Leaf-bladed sword", + "examine": "A razor-sharp sword.", "archery_ticket_price": "0", "attack_speed": "4", + "destroy": "false", + "durability": null, + "shop_price": "68000", + "tradeable": "true" + }, + { + "id": "13292", + "name": "Letter", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13293", + "name": "Plans", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13294", + "name": "Charcoal rubbing", + "examine": "A charcoal rubbing taken from 50% Luke.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop these plans, they will be lost and you will need to see Captain Donnie for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13295", + "name": "Frank's mark", + "examine": "Signature from Frank.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop Frank's mark, you will need to see him to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13296", + "name": "Crude lockpick", + "examine": "A device for opening locked doors.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop these lockpicks, you will need to look under the mattress to get another set.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13297", + "name": "Customs shirt", + "examine": "The top of a Custom Officer's uniform.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this shirt you will need to kill another Customs officer for a replacement.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false" + }, + { + "id": "13298", + "name": "Customs trousers", + "examine": "The trousers of a Custom Officer's uniform.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop these trousers you will need to kill another Customs officer for a replacement.", + "durability": null, + "equipment_slot": "7", + "tradeable": "false" + }, + { + "id": "13299", + "name": "Customs hat", + "examine": "The hat of a Custom Officer's uniform.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this hat you will need to kill another Customs officer for a replacement.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false" + }, + { + "id": "13300", + "name": "File", + "examine": "A folder containing all the marks I have gathered.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13301", + "name": "File", + "examine": "A folder containing all the marks I have gathered.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13302", + "name": "Brooch", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13303", + "name": "Izzy's mark", + "examine": "Signature from Izzy No-Beard.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop Izzy's No-Beard's mark, you will need to see him to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13304", + "name": "Key", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13305", + "name": "Crowbar", + "examine": "This could be useful.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this crowbar, you will need to get another from the chest on the sunken ship.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13307", + "name": "Idol of many heads", + "examine": "An idol. It has many heads.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop the idol, you will need to go diving to get another replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13308", + "name": "Bill teach's mark", + "examine": "Signature from Bill Teach.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop Bill Teach's mark, you will need to see him to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13309", + "name": "Paper", + "examine": "This is generally used for writing on.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this paper, you will need to call to the guards for a replacement. ", + "durability": null, + "tradeable": "false" + }, + { + "id": "13310", + "name": "Confession", + "examine": "A written confession.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this note, you'll need to call the guards for replacement paper.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13311", + "name": "Note", + "examine": "Swap this note at any bank for the equivalent item.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "tradeable": "false" + }, + { + "id": "13312", + "name": "Ink bottle", + "examine": "An empty ink bottle./This is full of ink.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this ink, you will need to call to the guards for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13313", + "name": "Inky paper", + "examine": "It's got ink all over it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this paper you will need to call to the guards to replace it and the ink.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13314", + "name": "Ink bottle", + "examine": "An empty ink bottle./This is full of ink.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this ink, you will need to call to the guards for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13315", + "name": "Smashed bottle", + "examine": "It's smashed. I should mind my fingers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this bottle, you will need to call to the guards for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13316", + "name": "Prison uniform top", + "examine": "The top part of a prisoner's uniform.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this top, then you will need to speak to the guards to get it replaced.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false" + }, + { + "id": "13317", + "name": "Prison uniform trousers", + "examine": "The bottom part of a prisoner's uniform.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop these trousers, then you will need to speak to the guards to get it replaced.", + "durability": null, + "equipment_slot": "7", + "tradeable": "false" + }, + { + "id": "13318", + "name": "Fishy prison uniform top", + "examine": "It's covered in fish slop.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this top, you will need to speak to the guards to get it replaced, then find a way to get stew on it again.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "tradeable": "false" + }, + { + "id": "13319", + "name": "Tin cup", + "examine": "A standard prison-issue tin cup.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this cup it will be destroyed and you will have to pick up another.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "13320", + "name": "Tin cup", + "examine": "A standard prison-issue tin cup.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this cup it will be destroyed and you will have to pick up another.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "13321", + "name": "Pipe", + "examine": "A pipe that belongs in a cannon stand.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Destroy", + "durability": null, + "tradeable": "false" + }, + { + "id": "13322", + "name": "Accordion", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13323", + "name": "Accordion", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13324", + "name": "Accordion", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13325", + "name": "Vacuum pump", + "examine": "A very crude vacuum pump.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this accordion, pipe and inky paper, it will all be destroyed and you will need to get all the items back again.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13326", + "name": "Vacuum pump and gull", + "examine": "It sounds like a law firm.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this, you will lose all the items you put in it, as well as the seagull.", + "durability": null, + "equipment_slot": "3", + "tradeable": "false" + }, + { + "id": "13327", + "name": "Quill", + "examine": "From a bird - can be used for writing.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this quill, you will need to talk to the guard for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13328", + "name": "Inky quill", + "examine": "From a bird - can be used for writing. It has some ink on the tip.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null, + "tradeable": "false" + }, + { + "id": "13329", + "name": "File", + "examine": "A folder containing all the marks I have gathered.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13330", + "name": "File", + "examine": "A folder containing all the marks I have gathered.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13331", + "name": "Ex-parrot", + "examine": "A very dead rotten parrot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this dead parrot, there is a chance that bad, bad things will happen to you - unless you see 50 Ships Mufassah for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13332", + "name": "Magical cage", + "examine": "It feels very cold to the touch.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this cage, you will need to see Bill Teach for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13333", + "name": "Ex-parrot in a magic cage", + "examine": "A very dead rotten parrot in a magical cage.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this dead parrot in a cage (and who wouldn't) then you will need to see ", + "durability": null, + "tradeable": "false" + }, + { + "id": "13334", + "name": "Ex-ex-parrot in a magic cage", + "examine": "A very alive rotten parrot in a magic cage.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop the cage, the ex-ex-parrot will escape.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13335", + "name": "Ex-ex-parrot", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13336", + "name": "Ex-ex-parrot", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13337", + "name": "Pirate impling jar", + "examine": "A pirate impling in a jar.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "shop_price": "50", + "tradeable": "true" + }, + { + "id": "13338", + "name": "Pirate impling jar", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "durability": null, + "shop_price": "50", + "tradeable": "true" + }, + { + "id": "13339", + "name": "Bandana and eyepatch", + "examine": "A white bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13340", + "name": "Bandana and eyepatches", + "examine": "A white bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13341", + "name": "Bandana and eyepatch", + "examine": "A red bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13342", + "name": "Bandana and eyepatches", + "examine": "A red bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13343", + "name": "Bandana and eyepatch", + "examine": "A blue bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13344", + "name": "Bandana and eyepatches", + "examine": "A blue bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13345", + "name": "Bandana and eyepatch", + "examine": "A brown bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13346", + "name": "Bandana and eyepatches", + "examine": "A brown bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13347", + "name": "Bandana and eyepatch", + "examine": "A grey bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13348", + "name": "Bandana and eyepatches", + "examine": "A grey bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13349", + "name": "Bandana and eyepatch", + "examine": "A purple bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13350", + "name": "Bandana and eyepatches", + "examine": "A purple bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13351", + "name": "Bandana and eyepatch", + "examine": "A orange bandana and a patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13352", + "name": "Bandana and eyepatches", + "examine": "A orange bandana and a patch for both eyes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13353", + "name": "Double eyepatches", + "examine": "It's dark, and I'm wearing two patches. Hit it!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13354", + "name": "Pirate hat and eyepatches", + "examine": "Two patches and a hat.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "false" + }, + { + "id": "13355", + "name": "Left eyepatch", + "examine": "A patch for the left eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "100", + "tradeable": "false" + }, + { + "id": "13356", + "name": "Left eyepatch", + "examine": "A patch for the left eye.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100", + "tradeable": "false" + }, + { + "id": "13357", + "name": "Pirate hat and eyepatch", + "examine": "A hat and a patch.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "false" + }, + { + "id": "13358", + "name": "Stripy pirate shirt", + "examine": "A seaworthy grey shirt.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13359", + "name": "Stripy pirate shirt", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "13360", + "name": "Stripy pirate shirt", + "examine": "A seaworthy purple shirt.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13361", + "name": "Stripy pirate shirt", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "13362", + "name": "Stripy pirate shirt", + "examine": "A seaworthy orange shirt.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "ge_buy_limit": "100", + "remove_sleeves": "true", + "shop_price": "300", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13363", + "name": "Stripy pirate shirt", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "300", + "tradeable": "true" + }, + { + "id": "13364", + "name": "Pirate leggings", + "examine": "A seaworthy pair of grey trousers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13365", + "name": "Pirate leggings", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "350", + "tradeable": "true" + }, + { + "id": "13366", + "name": "Pirate leggings", + "examine": "A seaworthy pair of purple trousers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13367", + "name": "Pirate leggings", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "350", + "tradeable": "true" + }, + { + "id": "13368", + "name": "Pirate leggings", + "examine": "A seaworthy pair of orange trousers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "ge_buy_limit": "100", + "shop_price": "350", + "tradeable": "true", + "weight": "1" + }, + { + "id": "13369", + "name": "Pirate leggings", + "archery_ticket_price": "0", + "durability": null, + "shop_price": "350", + "tradeable": "true" + }, + { + "id": "13370", + "name": "Bandana", + "examine": "A grey bandana.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13371", + "name": "Bandana", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13372", + "name": "Bandana", + "examine": "A purple bandana.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13373", + "name": "Bandana", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13374", + "name": "Bandana", + "examine": "An orange bandana.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13375", + "name": "Bandana", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "13376", + "name": "Bandana and eyepatch", + "examine": "A purple bandana and a patch for the right eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13377", + "name": "Bandana and eyepatch", + "examine": "A orange bandana and a patch for the right eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13378", + "name": "Bandana and eyepatch", + "examine": "A grey bandana and a patch for the right eye.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "100", + "tradeable": "true", + "weight": "0.1" + }, + { + "id": "13379", + "name": "Rock fragments", + "examine": "Some rock fragments.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Destroy", + "durability": null, + "tradeable": "false" + }, + { + "id": "13380", + "name": "Introduction letter", + "examine": "Note from Teach to Brass Hand Harry.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop the letter, it will be destroyed and you'll need to see Bill Teach for another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13381", + "name": "Broken hand", + "examine": "One of many broken hands.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13382", + "name": "Broken hand", + "examine": "One of many broken hands.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13383", + "name": "Broken hand", + "examine": "One of many broken hands.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13384", + "name": "Broken hand", + "examine": "One of many broken hands.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13385", + "name": "Broken hand", + "examine": "One of many broken hands.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13386", + "name": "Fingers", + "examine": "Wall beast fingers in a white fern sauce.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "tradeable": "false" + }, + { + "id": "13387", + "name": "Thumb", + "examine": "A brass thumb.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13388", + "name": "Hand", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13389", + "name": "Wrist", + "examine": "A brass wrist.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13390", + "name": "Brace", + "examine": "A brass brace.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13391", + "name": "Brass hand", + "examine": "A completed brass hand.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this hand, you will destroy it and you will have to remake it from parts that Brass Hand Harry has.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13392", + "name": "Ink pad", + "examine": "It's soaked with ink.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this ink pad, you will lose it and will need to see Brass Hand Harry for a replacement.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13393", + "name": "Inky hand", + "examine": "An inky brass hand.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this hand, you will destroy it and you will have to remake it from parts that Brass Hand Harry has.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13394", + "name": "Paper", + "examine": "This is generally used for writing on.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this paper, you will need to call to the guards for a replacement. ", + "durability": null, + "tradeable": "false" + }, + { + "id": "13395", + "name": "Brass hand harry's mark", + "examine": "Handprint from Brass Hand Harry.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop Brass Hand Harry's mark, it will be destroyed and you need to see him to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13396", + "name": "Fake beard", + "examine": "Makes me itch.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "tradeable": "false" + }, + { + "id": "13397", + "name": "Fake moustache and nose", + "examine": "It looks like someone has sneezed in it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false" + }, + { + "id": "13398", + "name": "Fake monocle, moustache and nose", + "examine": "Why is the monocle nailed to it?", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "durability": null, + "equipment_slot": "0", + "tradeable": "false" + }, + { + "id": "13399", + "name": "Curly wig", + "examine": "You can barely see where it connected to the mop handle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false" + }, + { + "id": "13400", + "name": "Straight wig", + "examine": "It looks like it is part-dog, part-mould.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "tradeable": "false" + }, + { + "id": "13401", + "name": "Order", + "examine": "An order simply for 'rum'.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop this order for 'rum' you will need to speak to the Rusty Anchor barman to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13402", + "name": "Braindeath's mark", + "examine": "Signature of Captain Braindeath.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop Captain Braindeath's mark, you will need to speak to him to get another.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13403", + "name": "Golden tinderbox", + "examine": "A replica tinderbox made of solid gold.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "300", + "tradeable": "false" + }, + { + "id": "13405", + "name": "Dark bow", + "examine": "A bow from a darker dimension.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_audios": "3731,0,0,0", + "attack_speed": "9", + "bonuses": "0,0,0,0,95,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "3738", + "has_special": "true", + "lendable": "true", + "render_anim": "303", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13406", + "name": "Ancient staff", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "10,-1,40,15,0,2,3,1,15,0,5,50,0,-1,10", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "28", + "weapon_interface": "1" + }, + { + "id": "13407", + "name": "Archer helm", + "examine": "This helmet is worn by archers.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13408", + "name": "Berserker helm", + "examine": "This helmet is worn by berserkers.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13409", + "name": "Warrior helm", + "examine": "This helm is worn by warriors.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13410", + "name": "Farseer helm", + "examine": "This helm is worn by farseers.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13411", + "name": "Rock-shell helm", + "examine": "Protective headwear made from crabs. Better than it sounds.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,6,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13412", + "name": "Rock-shell plate", + "examine": "A sturdy body armour made from rock crab pieces.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13413", + "name": "Rock-shell legs", + "examine": "Some tough leggings made from rock crab parts.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13414", + "name": "Spined helm", + "examine": "A helm fit for any Fremennik ranger.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,-6,-6,-6,6,6,6,6,6,0,6,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13415", + "name": "Spined body", + "examine": "A constant reminder that I'm above a Dagannoth in the food chain.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13416", + "name": "Spined chaps", + "examine": "Stylish leg armour for rangers with a lingering smell of raw fish...", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13417", + "name": "Skeletal helm", + "examine": "Make your foes cower by wearing a skull as a helmet!", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,2,-2,10,9,11,3,0,6,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13418", + "name": "Skeletal top", + "examine": "The bones in this armour seems to vibrate with a magic quality...", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,8,-10,35,25,42,15,0,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13419", + "name": "Skeletal bottoms", + "examine": "A superior set of strengthened slacks for any self respecting seer.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,6,-7,22,20,24,10,0,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13420", + "name": "Spined boots", + "examine": "Some finely crafted Fremennik boots, made from spined dagannoth hide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,1,1,0,0,0,1,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13421", + "name": "Rock-shell boots", + "examine": "Some Fremennik boots, made from the shards of a rock crab's shell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13422", + "name": "Skeletal boots", + "examine": "Some finely crafted Fremennik boots, made from the bones of a Wallasalki.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13423", + "name": "Spined gloves", + "examine": "Fremennik gloves stitched together from spined dagannoth hide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,1,2,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13424", + "name": "Rock-shell gloves", + "examine": "Fremennik gloves stitched together from rock crab shell shards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13425", + "name": "Skeletal gloves", + "examine": "Fremennik gloves stitched together from wallasalki bones fragments.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13426", + "name": "Seers ring", + "examine": "A mysterious ring that can fill the wearer with magical power...", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13427", + "name": "Archers ring", + "examine": "A fabled ring that improves the wearer's skill with a bow...", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,4,0,0,0,0,4,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13428", + "name": "Warrior ring", + "examine": "A legendary ring once worn by Fremennik warriors.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,4,0,0,0,0,4,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13429", + "name": "Berserker ring", + "examine": "A ring reputed to bring out a berserk fury in its wearer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13430", + "name": "Dragon 2h sword", + "examine": "A two-handed dragon sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "-4,92,80,-4,0,0,0,0,0,-1,0,93,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "124", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13431", + "name": "Crayfish cage", + "examine": "Useful for catching crayfish.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "13432", + "name": "Crayfish cage", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "13433", + "name": "Crayfish", + "examine": "Some cooked crayfish. Eat it to heal.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "13434", + "name": "Crayfish", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "13435", + "name": "Raw crayfish", + "examine": "I should try cooking this. Used in Cooking (1).", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "13436", + "name": "Raw crayfish", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "shop_price": "5", + "tradeable": "true" + }, + { + "id": "13437", + "name": "Burnt crayfish", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "false", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "13438", + "name": "Burnt crayfish", + "examine": "Swap this note at any bank for the equivalent item.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "durability": null, + "shop_price": "1", + "tradeable": "true" + }, + { + "id": "13439", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "13440", + "name": "Bag of runes", + "examine": "This is a bag of runes for Sir Vant.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "13442", + "name": "Amulet of fury", + "examine": "A very powerful onyx amulet.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "10,10,10,10,10,15,15,15,15,15,15,8,0,5,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13443", + "name": "Obsidian cape", + "examine": "A cape woven of obsidian plates.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13444", + "name": "Abyssal whip", + "examine": "A weapon from the Abyss.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2249", + "has_special": "true", + "lendable": "true", + "render_anim": "1578", + "weapon_interface": "11" + }, + { + "id": "13445", + "name": "Granite maul", + "examine": "Simplicity is the best weapon.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "0,0,81,0,0,0,0,0,0,0,0,79,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "render_anim": "27", + "two_handed": "true", + "weapon_interface": "10" + }, + { + "id": "13446", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "13447", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "13448", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "13449", + "name": "Dragon full helm", + "examine": "Protects your head and looks impressive too.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,45,48,41,-1,46,12,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13450", + "name": "Armadyl godsword", + "examine": "A beautiful, heavy sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "1579", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13451", + "name": "Bandos godsword", + "examine": "A brutally heavy sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "1579", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13452", + "name": "Saradomin godsword", + "examine": "A gracious, heavy sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "1579", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13453", + "name": "Zamorak godsword", + "examine": "A terrifying, heavy sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "1579", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13454", + "name": "Zamorakian spear", + "examine": "An evil spear.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "85,65,65,0,0,13,13,12,0,13,0,75,0,2,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "render_anim": "1581", + "two_handed": "true", + "weapon_interface": "14" + }, + { + "id": "13455", + "name": "Armadyl helmet", + "examine": "A helmet of great craftmanship.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-5,-5,-5,-5,10,6,6,10,10,8,12,0,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "lendable": "true" + }, + { + "id": "13456", + "name": "Armadyl chestplate", + "examine": "A chestplate of great craftsmanship", + "absorb": "0,10,5", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-7,-7,-7,-15,33,56,48,61,70,57,52,0,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "lendable": "true" + }, + { + "id": "13457", + "name": "Armadyl plateskirt", + "examine": "A chainskirt of great craftsmanship.", + "absorb": "0,7,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-6,-6,-6,-10,20,32,26,34,40,33,25,0,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "lendable": "true" + }, + { + "id": "13458", + "name": "Bandos chestplate", + "examine": "A sturdy chestplate.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,-10,98,93,105,-6,133,52,4,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13459", + "name": "Bandos tassets", + "examine": "A sturdy pair of tassets.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,71,63,66,-4,93,25,2,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13460", + "name": "Bandos boots", + "examine": "Some sturdy boots.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-5,-3,17,18,19,0,0,15,0,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2237", + "lendable": "true" + }, + { + "id": "13461", + "name": "Saradomin sword", + "examine": "The incredible blade of an Icyene.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,82,60,0,0,0,0,0,0,0,0,82,0,2,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "1579", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13462", + "name": "Dragon boots", + "examine": "These will protect my feet.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2237", + "lendable": "true" + }, + { + "id": "13463", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "13464", + "name": "Task list", + "examine": "This reminds me of my current job and who set me to the task.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another by talking about jobs with citizens and tutors around Lumbridge.", + "durability": null, + "tradeable": "false" + }, + { + "id": "13465", + "name": "Dragon dagger", + "examine": "A powerful dagger.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "weapon_interface": "5" + }, + { + "id": "13466", + "name": "Dragon dagger(p)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "shop_price": "1" + }, + { + "id": "13467", + "name": "Dragon dagger(p+)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "shop_price": "1" + }, + { + "id": "13468", + "name": "Dragon dagger(p++)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "shop_price": "1" + }, + { + "id": "13469", + "name": "Rune axe", + "examine": "A powerful axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2229", + "lendable": "true", + "weapon_interface": "2" + }, + { + "id": "13470", + "name": "Dragon axe", + "examine": "A very powerful axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "-2,38,32,0,0,0,1,0,0,0,0,42,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2229", + "has_special": "true", + "lendable": "true", + "weapon_interface": "2" + }, + { + "id": "13471", + "name": "Rune battleaxe", + "examine": "A vicious looking axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "-2,48,43,0,0,0,0,0,0,-1,0,64,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "weapon_interface": "2" + }, + { + "id": "13472", + "name": "Dragon battleaxe", + "examine": "A vicious looking axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "render_anim": "2586", + "requirements": "{0,60}", + "weapon_interface": "2", + "weight": "2.7" + }, + { + "id": "13473", + "name": "Rune warhammer", + "examine": "I don't think it's intended for joinery.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2233", + "lendable": "true", + "render_anim": "1430", + "weapon_interface": "10" + }, + { + "id": "13474", + "name": "Rune longsword", + "examine": "A razor-sharp longsword", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "1582", + "weapon_interface": "5" + }, + { + "id": "13475", + "name": "Dragon longsword", + "examine": "A very powerful sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "58,69,-2,0,0,0,3,2,0,0,0,71,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "render_anim": "1582", + "weapon_interface": "5" + }, + { + "id": "13476", + "name": "Rune scimitar", + "examine": "A vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "1582", + "weapon_interface": "6" + }, + { + "id": "13477", + "name": "Dragon scimitar", + "examine": "A vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_speed": "4", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "has_special": "true", + "lendable": "true", + "render_anim": "1928", + "weapon_interface": "6" + }, + { + "id": "13478", + "name": "Dragon halberd", + "examine": "A dragon halberd.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "70,95,0,-4,0,-1,4,5,0,0,0,89,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "15" + }, + { + "id": "13479", + "name": "Dragon mace", + "examine": "A spiky mace.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "40,-2,60,0,0,0,0,0,0,0,0,55,0,5,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2246", + "has_special": "true", + "lendable": "true", + "requirements": "{0,60}", + "weapon_interface": "8", + "weight": "1.8" + }, + { + "id": "13480", + "name": "Rune pickaxe", + "examine": "Used for mining.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "26,-2,24,0,0,0,1,0,0,0,0,29,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2232", + "lendable": "true", + "weapon_interface": "4" + }, + { + "id": "13481", + "name": "Dragon chainbody", + "examine": "A series of connected metal rings.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13482", + "name": "Rune platebody", + "examine": "Provides excellent protection.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13483", + "name": "Green d'hide body", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-20,15,40,32,45,20,40,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13484", + "name": "Blue d'hide body", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13485", + "name": "Red d'hide body", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,25,50,42,55,40,50,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13486", + "name": "Black d'hide body", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13487", + "name": "Rune platelegs", + "examine": "These look pretty heavy.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13488", + "name": "Dragon platelegs", + "examine": "Looks pretty heavy.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13489", + "name": "Rune plateskirt", + "examine": "Designer leg protection.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13490", + "name": "Dragon plateskirt", + "examine": "This looks pretty heavy.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13491", + "name": "Green d'hide chaps", + "examine": "100% real dragonhide.", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13492", + "name": "Blue d'hide chaps", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,5,2", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13493", + "name": "Red d'hide chaps", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,14,28,22,30,20,28,25,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13494", + "name": "Black d'hide chaps", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,7,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13495", + "name": "Dragon med helm", + "examine": "Makes the wearer pretty intimidating.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "lendable": "true" + }, + { + "id": "13496", + "name": "Rune full helm", + "examine": "A full face helmet.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13497", + "name": "Green d'hide vamb", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,8,3,2,4,2,0,3,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13498", + "name": "Blue d'hide vamb", + "examine": "Made from 100% real dragonhide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13499", + "name": "Red d'hide vamb", + "examine": "Vambraces made from 100% real dragonhide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13500", + "name": "Black d'hide vamb", + "examine": "Vambraces made from 100% real dragonhide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13501", + "name": "Splitbark helm", + "examine": "A wooden helmet.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13502", + "name": "Splitbark body", + "examine": "Provides good protection.", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,10,-10,36,26,42,15,0,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13503", + "name": "Splitbark legs", + "examine": "These should protect my legs.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,7,-7,22,20,25,10,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13504", + "name": "Splitbark gauntlets", + "examine": "These should keep my hands safe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,3,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13505", + "name": "Splitbark boots", + "examine": "Wooden foot protection.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,9,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2237", + "lendable": "true" + }, + { + "id": "13506", + "name": "Dragon sq shield", + "examine": "An ancient and powerful looking Dragon Square shield.", + "absorb": "5,0,11", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13507", + "name": "Rune kiteshield", + "examine": "A large metal shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13508", + "name": "Mystic hat", + "examine": "Blue: A magical hat. ", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13509", + "name": "Mystic robe top", + "examine": "The upper half of a magical robe.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13510", + "name": "Mystic robe bottom", + "examine": "The lower half of a magical robe.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13511", + "name": "Mystic gloves", + "examine": "Bright/Dark magical gloves.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13512", + "name": "Mystic boots", + "examine": "Magical boots.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13513", + "name": "Mystic hat", + "examine": "Blue: A magical hat. ", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13514", + "name": "Mystic robe top", + "examine": "The upper half of a magical robe.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13515", + "name": "Mystic robe bottom", + "examine": "The lower half of a magical robe.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13516", + "name": "Mystic gloves", + "examine": "Bright/Dark magical gloves.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13517", + "name": "Mystic boots", + "examine": "Magical boots.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13518", + "name": "Mystic hat", + "examine": "Blue: A magical hat. ", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13519", + "name": "Mystic robe top", + "examine": "The upper half of a magical robe.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13520", + "name": "Mystic robe bottom", + "examine": "The lower half of a magical robe.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13521", + "name": "Mystic gloves", + "examine": "Bright/Dark magical gloves.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13522", + "name": "Mystic boots", + "examine": "Magical boots.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13523", + "name": "Maple longbow", + "examine": "A nice sturdy bow made out of maple.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13524", + "name": "Maple shortbow", + "examine": "A shortbow made out of maple, still effective.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13525", + "name": "Yew longbow", + "examine": "A nice sturdy bow made out of yew.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13526", + "name": "Yew shortbow", + "examine": "A shortbow made out of yew, still effective.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13527", + "name": "Magic longbow", + "examine": "A nice sturdy magical bow.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "has_special": "true", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13528", + "name": "Magic shortbow", + "examine": "Short and magical, but still effective.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "has_special": "true", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13529", + "name": "Seercull", + "examine": "An ancient Fremennik bow that was once used to battle the Moon Clan.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13530", + "name": "Rune crossbow", + "examine": "A runite crossbow.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "lendable": "true", + "render_anim": "175", + "weapon_interface": "17" + }, + { + "id": "13531", + "name": "Red partyhat", + "examine": "A nice hat from a cracker.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13532", + "name": "Yellow partyhat", + "examine": "A nice hat from a cracker.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13533", + "name": "Blue partyhat", + "examine": "A nice hat from a cracker.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13534", + "name": "Green partyhat", + "examine": "A nice hat from a cracker.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13535", + "name": "Purple partyhat", + "examine": "A nice hat from a cracker.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13536", + "name": "White partyhat", + "examine": "A nice hat from a cracker.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13537", + "name": "Santa hat", + "examine": "It's a Santa hat.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13538", + "name": "Green h'ween mask", + "examine": "Aaaarrrghhh ... I'm a monster.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13539", + "name": "Blue h'ween mask", + "examine": "Aaaarrrghhh ... I'm a monster.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13540", + "name": "Red h'ween mask", + "examine": "Aaaarrrghhh ... I'm a monster.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13541", + "name": "Willow comp bow", + "examine": "A powerful bow made from willow.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,0,22,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13542", + "name": "Yew comp bow", + "examine": "A powerful bow made from yew wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,0,49,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13543", + "name": "Magic comp bow", + "examine": "A powerful bow made from magic wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,0,71,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "13544", + "name": "3rd age range top", + "examine": "Ancient range protection crafted from white dragonhide.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,30,55,47,60,60,55,52,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13545", + "name": "3rd age range legs", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,17,31,25,33,30,31,25,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13546", + "name": "3rd age range coif", + "examine": "Ancient range protection crafted from white dragonhide.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-2,9,4,7,10,5,8,12,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13547", + "name": "3rd age vambraces", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-11,11,6,5,7,9,0,5,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2241", + "lendable": "true" + }, + { + "id": "13548", + "name": "3rd age robe top", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,24,0,0,0,0,24,0,24,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13549", + "name": "3rd age robe", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,19,0,0,0,0,19,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13550", + "name": "3rd age mage hat", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,8,0,0,0,0,8,0,12,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13551", + "name": "3rd age amulet", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,15,0,0,0,0,10,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13552", + "name": "3rd age platelegs", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-25,-2,78,76,83,-5,75,25,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13553", + "name": "3rd age platebody", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-20,0,96,108,113,-4,97,52,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13554", + "name": "3rd age full helmet", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-5,-2,47,49,43,-3,48,12,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13555", + "name": "3rd age kiteshield", + "examine": "Ancient armour beaten from magical silver.", + "absorb": "5,0,11", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,-4,63,65,61,-3,63,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13556", + "name": "Ranger boots", + "examine": "Lightweight boots ideal for rangers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,8,2,3,4,2,0,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13557", + "name": "Wizard boots", + "examine": "Slightly magical boots.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13558", + "name": "Robin hood hat", + "examine": "Endorsed by Robin Hood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,8,4,6,8,4,4,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13560", + "name": "Explorer's ring 1", + "examine": "A Lumbridge explorer's ring.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", + "destroy": "true", + "destroy_message": "You will have talk to Explorer Jack in Lumbridge if you destroy this one.", + "durability": null, + "equipment_slot": "12", + "shop_price": "350" + }, + { + "id": "13561", + "name": "Explorer's ring 2", + "examine": "A Lumbridge explorer's ring.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", + "destroy": "true", + "destroy_message": "You will have talk to ", + "durability": null, + "equipment_slot": "12", + "shop_price": "350" + }, + { + "id": "13562", + "name": "Explorer's ring 3", + "examine": "A Lumbridge explorer's ring.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", + "destroy": "true", + "destroy_message": "You will need to obtain a new ring from Ned in Draynor if you destroy this one.", + "durability": null, + "equipment_slot": "12", + "shop_price": "350" + }, + { + "id": "13563", + "name": "Button mushroom", + "examine": "An occasionally edible mushroom.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "38", + "tradeable": "true" + }, + { + "id": "13564", + "name": "Button mushroom", + "examine": "An occasionally edible mushroom.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "38", + "tradeable": "true" + }, + { + "id": "13565", + "name": "Doll", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13566", + "name": "Jennica's ring", + "examine": "This magical ring once belonged to Summer's mother.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You may be able to find a new ring near where Summer stood outside the wilderness wall.", + "durability": null, + "equipment_slot": "12" + }, + { + "id": "13567", + "name": "Cursed magic logs", + "examine": "Logs cut from a cursed magic tree.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "tradeable": "true" + }, + { + "id": "13568", + "name": "Cursed magic logs", + "examine": "Logs cut from a cursed magic tree.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "tradeable": "true" + }, + { + "id": "13569", + "name": "Enchanted key notes", + "examine": "Notes on how to use the enchanted key.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Hopefully, Jorral will be able to return them.", + "durability": null + }, + { + "id": "13570", + "name": "Bowl", + "examine": "Useful for mixing things.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13571", + "name": "Bucket of milk", + "examine": "It's a bucket of milk.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13572", + "name": "Clean guam", + "examine": "A fresh herb.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13573", + "name": "Bowl of honey", + "examine": "A bowlful of bees' precious product.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You'll have to start again from stratch.", + "durability": null + }, + { + "id": "13574", + "name": "Bowl of milk and honey", + "examine": "A bowlful of milk and honey.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You'll have to start again from stratch.", + "durability": null + }, + { + "id": "13575", + "name": "Bowl of milk, honey and guam", + "examine": "A bowl full of milk, honey and guam.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You'll have to start again from stratch.", + "durability": null + }, + { + "id": "13576", + "name": "Map of 2009Scape", + "examine": "Your best impression of a map of 2009Scape.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Hopefully, the family has more papyrus and charcoal.", + "durability": null + }, + { + "id": "13577", + "name": "Papyrus", + "examine": "Used for making notes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13578", + "name": "Charcoal", + "examine": "A lump of charcoal.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13579", + "name": "Spade", + "examine": "A slightly muddy spade. ", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13580", + "name": "Plant pot", + "examine": "A plant pot filled with soil.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13581", + "name": "Pear tree seedling", + "examine": "A seedling has been sown in this plant pot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13582", + "name": "Mango tree seedling", + "examine": "A seedling has been sown in this plant pot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13583", + "name": "Quince tree seedling", + "examine": "A seedling has been sown in this plant pot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13584", + "name": "Lemon tree seedling", + "examine": "A seedling has been sown in this plant pot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13585", + "name": "Avocado tree seedling", + "examine": "A seedling has been sown in this plant pot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13586", + "name": "Plum tree seedling", + "examine": "A seedling has been sown in this plant pot.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13587", + "name": "Pestle and mortar", + "examine": "I can grind things for potions in this.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "4" + }, + { + "id": "13588", + "name": "Ground guam", + "examine": "One of the ingredients for making fish food.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "13589", + "name": "Bucket", + "examine": "It's an empty bucket. ", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "2" + }, + { + "id": "13591", + "name": "Enchanted key", + "examine": "It seems to change temperature as I walk. (Making History)", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null + }, + { + "id": "13592", + "name": "A brooch", + "examine": "Some ladies jewellery.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Hopefully, you can find another.", + "durability": null + }, + { + "id": "13593", + "name": "Old tome", + "examine": "It's falling apart, but full of knowledge.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will not get another chance to read the book!", + "durability": null + }, + { + "id": "13598", + "name": "Runecrafting guild teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13599", + "name": "Air altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13600", + "name": "Mind altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13601", + "name": "Water altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13602", + "name": "Earth altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13603", + "name": "Fire altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13604", + "name": "Body altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13605", + "name": "Cosmic altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13606", + "name": "Chaos altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13607", + "name": "Nature altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13608", + "name": "Law altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13609", + "name": "Death altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13610", + "name": "Blood altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13611", + "name": "Astral altar teleport", + "examine": "A tablet containing a magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100" + }, + { + "id": "13612", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "20" + }, + { + "id": "13613", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "20" + }, + { + "id": "13614", + "name": "Runecrafter robe", + "examine": "Heavy duty wizard robes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "75" + }, + { + "id": "13615", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13616", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13617", + "name": "Runecrafter skirt", + "examine": "A heavy-duty wizard robe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "75" + }, + { + "id": "13618", + "name": "Runecrafter gloves", + "examine": "Essence can be rough on the hands", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "9", + "shop_price": "75" + }, + { + "id": "13619", + "name": "Runecrafter robe", + "examine": "Heavy duty wizard robes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "75" + }, + { + "id": "13620", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13621", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13622", + "name": "Runecrafter skirt", + "examine": "A heavy-duty wizard robe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "75" + }, + { + "id": "13623", + "name": "Runecrafter gloves", + "examine": "Essence can be rough on the hands", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "9", + "shop_price": "75" + }, + { + "id": "13624", + "name": "Runecrafter robe", + "examine": "Heavy duty wizard robes.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "75" + }, + { + "id": "13625", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13626", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13627", + "name": "Runecrafter skirt", + "examine": "A heavy-duty wizard robe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "75" + }, + { + "id": "13628", + "name": "Runecrafter gloves", + "examine": "Essence can be rough on the hands", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "9", + "shop_price": "75" + }, + { + "id": "13629", + "name": "Runecrafting staff", + "examine": "Staff with a holder for a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "render_anim": "28", + "shop_price": "15" + }, + { + "id": "13630", + "name": "Air talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13631", + "name": "Mind talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13632", + "name": "Water talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13633", + "name": "Earth talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13634", + "name": "Fire talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13635", + "name": "Body talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13636", + "name": "Cosmic talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13637", + "name": "Chaos talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13638", + "name": "Nature talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "No", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13639", + "name": "Law talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13640", + "name": "Death talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13641", + "name": "Blood talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13642", + "name": "Omni-talisman staff", + "examine": "A staff with a talisman on top.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0", + "destroy": "true", + "destroy_message": "You will have to speak to Wizard Elriss to get another omni-talisman.", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "1500", + "weapon_interface": "1" + }, + { + "id": "13643", + "name": "Yellow attractor", + "examine": "Attracts Runecrafting energy orbs in the rune altars.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this, you will leave the game.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "20", + "weapon_interface": "1" + }, + { + "id": "13644", + "name": "Yellow repeller", + "examine": "Repels Runecrafting energy orbs in the rune altars.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this, you will leave the game.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "20", + "weapon_interface": "1" + }, + { + "id": "13645", + "name": "Green attractor", + "examine": "Attracts Runecrafting energy orbs in the rune altars.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this, you will leave the game.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "20", + "weapon_interface": "1" + }, + { + "id": "13646", + "name": "Green repeller", + "examine": "Repels Runecrafting energy orbs in the rune altars.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this, you will leave the game.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "20", + "weapon_interface": "1" + }, + { + "id": "13647", + "name": "Green barrier generator", + "examine": "It creates barriers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this, you will leave the game.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "20", + "weapon_interface": "1" + }, + { + "id": "13648", + "name": "Yellow barrier generator", + "examine": "It creates barriers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this, you will leave the game.", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "20", + "weapon_interface": "1" + }, + { + "id": "13649", + "name": "Omni-talisman", + "examine": "Many mysterious powers emanate from the talisman.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will have to speak to ", + "durability": null, + "shop_price": "4" + }, + { + "id": "13650", + "name": "Runecrafting guild token", + "examine": "Wizard Elriss will exchange these for rewards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "13651", + "name": "Runecrafting guild token", + "examine": "Wizard Elriss will exchange these for rewards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "13652", + "name": "Runecrafting guild token", + "examine": "Wizard Elriss will exchange these for rewards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "13653", + "name": "Runecrafting guild token", + "examine": "Wizard Elriss will exchange these for rewards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "13654", + "name": "Runecrafting guild token", + "examine": "Wizard Elriss will exchange these for rewards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "13655", + "name": "Omni-tiara", + "examine": "A tiara infused with the properties of all talismans.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will have to speak to Wizard Elriss to get another omni-talisman.", + "durability": null, + "equipment_slot": "0", + "shop_price": "100" + }, + { + "id": "13656", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13657", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13658", + "name": "Runecrafter hat", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "75" + }, + { + "id": "13659", + "name": "Ring of fire", + "examine": "It burns, burns, burns...", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "To get another Ring of Fire, you need to keep six beacons alight simultaneously and then talk to King Roald.", + "durability": null, + "equipment_slot": "12", + "point_price": "50", + "requirements": "{11,62}", + "shop_price": "100" + }, + { + "id": "13660", + "name": "Flame gloves", + "examine": "The hottest gloves in town.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "To get another pair of Flame Gloves, you need to keep ten beacons alight simultaneously and then talk to King Roald.", + "durability": null, + "equipment_slot": "9", + "requirements": "{11,79}", + "shop_price": "200" + }, + { + "id": "13661", + "name": "Inferno adze", + "examine": "Danger: risk of fire.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_speed": "5", + "bonuses": "10,9,7,0,0,0,1,0,0,0,0,11,0,0,0", + "destroy": "true", + "destroy_message": "To get another Inferno Adze, you need to keep all fourteen beacons alight simultaneously and then talk to King Roald.", + "durability": null, + "equipment_slot": "3", + "point_price": "75", + "render_anim": "1096", + "requirements": "{11,92}", + "shop_price": "300", + "weapon_interface": "2" + }, + { + "id": "13662", + "name": "Fire beacon", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "13663", + "name": "Circus ticket", + "examine": "Tear ticket to exit the circus.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "The ticket says: Tearing this ticket will make you leave the circus. Choose wisely.", + "durability": null, + "equipment_slot": "3", + "shop_price": "10" + }, + { + "id": "13666", + "name": "Giant's hand", + "examine": "Let's give them a big hand!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "durability": null, + "equipment_slot": "3", + "render_anim": "326", + "shop_price": "10", + "weapon_interface": "7" + }, + { + "id": "13667", + "name": "Clown hat", + "examine": "A clown hat!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "10" + }, + { + "id": "13668", + "name": "Clown shirt", + "examine": "Buttoning this up is tricky.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13669", + "name": "Clown leggings", + "examine": "These are my funny pants.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13670", + "name": "Clown shoes", + "examine": "For helping clowns stay upright.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13671", + "name": "Tambourine", + "examine": "For making a happy noise.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "3", + "render_anim": "327", + "shop_price": "10", + "weapon_interface": "8" + }, + { + "id": "13672", + "name": "Ringmaster hat", + "examine": "Very stylish.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "durability": null, + "equipment_slot": "0", + "shop_price": "10" + }, + { + "id": "13673", + "name": "Ringmaster shirt", + "examine": "Fits nicely.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13674", + "name": "Ringmaster pants", + "examine": "Very stylish.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13675", + "name": "Ringmaster boots", + "examine": "Shiny.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13676", + "name": "Mega-phonus", + "examine": "For shouting at people.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "durability": null, + "equipment_slot": "3", + "render_anim": "328", + "shop_price": "10", + "weapon_interface": "8" + }, + { + "id": "13677", + "name": "Acrobat shirt", + "examine": "Stretchy.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13678", + "name": "Acrobat pants", + "examine": "Very tight fitting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13679", + "name": "Acrobat shoes", + "examine": "These keep your feet off the floor.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13680", + "name": "Acrobat hood", + "examine": "Oh no, I'm bald! Just kidding.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "10" + }, + { + "id": "13681", + "name": "Acrobat shirt", + "examine": "Stretchy.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13682", + "name": "Acrobat pants", + "examine": "Very tight fitting.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13683", + "name": "Acrobat shoes", + "examine": "These keep your feet off the floor.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13684", + "name": "Acrobat hood", + "examine": "Oh no, I'm bald! Just kidding.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "10" + }, + { + "id": "13685", + "name": "A stylish hat", + "examine": "Very dapper!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "shop_price": "10" + }, + { + "id": "13686", + "name": "A stylish hat", + "examine": "Very dapper!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "shop_price": "10" + }, + { + "id": "13687", + "name": "A stylish hat", + "examine": "Very dapper!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "shop_price": "10" + }, + { + "id": "13688", + "name": "A stylish hat", + "examine": "Very dapper!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "10" + }, + { + "id": "13689", + "name": "A stylish hat", + "examine": "Very dapper!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "10" + }, + { + "id": "13690", + "name": "A stylish hat", + "examine": "Very dapper!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "10" + }, + { + "id": "13691", + "name": "Shirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13692", + "name": "Shirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13693", + "name": "Shirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13694", + "name": "Shirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13695", + "name": "Shirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13696", + "name": "Shirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "10" + }, + { + "id": "13697", + "name": "Leggings", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13698", + "name": "Leggings", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13699", + "name": "Leggings", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13700", + "name": "Skirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13701", + "name": "Skirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13702", + "name": "Skirt", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "7", + "shop_price": "10" + }, + { + "id": "13703", + "name": "Shoes", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13704", + "name": "Shoes", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13705", + "name": "Shoes", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13706", + "name": "Shoes", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "10", + "shop_price": "10" + }, + { + "id": "13707", + "name": "Tightrope 101", + "examine": "Shows you the moves you need to succeed!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another Tightrope 101 by speaking to the Agility assistant.", + "durability": null + }, + { + "id": "13708", + "name": "Tightrope 101", + "examine": "Shows you the moves you need to succeed!", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "You can get another Tightrope 101 by speaking to the Agility assistant.", + "durability": null, + "tradeable": "true" + }, + { "id": "13709", + "name": "Balls (level 10 approx.)", + "examine": "An Agility level of 10 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 20 is advised when juggling these.", - "durability": null, - "name": "Plates (level 20 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13710", + "name": "Plates (level 20 approx.)", + "examine": "An Agility level of 20 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 30 is advised when juggling these.", - "durability": null, - "name": "Eggs (level 30 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13711", + "name": "Eggs (level 30 approx.)", + "examine": "An Agility level of 30 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 40 is advised when juggling these.", - "durability": null, - "name": "Knives (level 40 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13712", + "name": "Knives (level 40 approx.)", + "examine": "An Agility level of 40 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 50 is advised when juggling these.", - "durability": null, - "name": "Spades (level 50 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13713", + "name": "Spades (level 50 approx.)", + "examine": "An Agility level of 50 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 60 is advised when juggling these.", - "durability": null, - "name": "Tuna (level 60 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13714", + "name": "Tuna (level 60 approx.)", + "examine": "An Agility level of 60 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 70 is advised when juggling these.", - "durability": null, - "name": "Soap (level 70 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13715", + "name": "Soap (level 70 approx.)", + "examine": "An Agility level of 70 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 80 is advised when juggling these.", - "durability": null, - "name": "Cannon balls (level 80 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13716", + "name": "Cannon balls (level 80 approx.)", + "examine": "An Agility level of 80 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 90 is advised when juggling these.", - "durability": null, - "name": "Torches (level 90 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13717", + "name": "Torches (level 90 approx.)", + "examine": "An Agility level of 90 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "destroy_message": "You can get another one from the equipment box for this performance.", - "examine": "An Agility level of 99 is advised when juggling these.", - "durability": null, - "name": "Chinchompas (level 99 approx.)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "13718", + "name": "Chinchompas (level 99 approx.)", + "examine": "An Agility level of 99 is advised when juggling these.", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, "equipment_slot": "3" }, { - "shop_price": "50", - "examine": "Short, but effective.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "16", - "absorb": "0,0,0", - "render_anim": "176", - "equipment_slot": "3", - "destroy_message": "You can get another one from the equipment box for this performance.", - "name": "Performance shortbow", - "archery_ticket_price": "0", "id": "13719", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "14", - "examine": "A finely balanced throwing knife.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "18", + "name": "Performance shortbow", + "examine": "Short, but effective.", "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "You can get another one from the equipment box for this performance.", - "name": "Performance knife", - "archery_ticket_price": "0", - "id": "13720", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "4", - "examine": "A finely balanced throwing axe.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "18", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "You can get another one from the equipment box for this performance.", - "name": "Performance throwing axe", - "archery_ticket_price": "0", - "id": "13721", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another one from the equipment box for this performance.", - "shop_price": "7", - "examine": "Arrows with bronze heads.", - "durability": null, - "name": "Performance arrow", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13722", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "13" - }, - { - "destroy_message": "You can get another one from the equipment box for this performance.", - "shop_price": "100", - "examine": "A tablet containing a Magic spell.", - "durability": null, - "name": "Teleport spell", "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13723", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { "destroy_message": "You can get another one from the equipment box for this performance.", - "shop_price": "100", - "examine": "A tablet containing a Magic spell.", "durability": null, - "name": "Levitation spell", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13724", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another one from the equipment box for this performance.", - "shop_price": "100", - "examine": "A tablet containing a Magic spell.", - "durability": null, - "name": "Alchemy spell", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13725", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another one from the equipment box for this performance.", - "shop_price": "100", - "examine": "A tablet containing a Magic spell.", - "durability": null, - "name": "Elemental spell", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13726", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can mine more if you find another crashed star.", + "equipment_slot": "3", + "render_anim": "176", "shop_price": "50", - "examine": "Small, shiny bits of rock.", - "durability": null, - "name": "Stardust", - "destroy": "true", + "weapon_interface": "16" + }, + { + "id": "13720", + "name": "Performance knife", + "examine": "A finely balanced throwing knife.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "equip_audio": "", + "equipment_slot": "3", + "shop_price": "14", + "weapon_interface": "18" + }, + { + "id": "13721", + "name": "Performance throwing axe", + "examine": "A finely balanced throwing axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "equipment_slot": "3", + "shop_price": "4", + "weapon_interface": "18" + }, + { + "id": "13722", + "name": "Performance arrow", + "examine": "Arrows with bronze heads.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "equipment_slot": "13", + "shop_price": "7" + }, + { + "id": "13723", + "name": "Teleport spell", + "examine": "A tablet containing a Magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "shop_price": "100" + }, + { + "id": "13724", + "name": "Levitation spell", + "examine": "A tablet containing a Magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "shop_price": "100" + }, + { + "id": "13725", + "name": "Alchemy spell", + "examine": "A tablet containing a Magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "shop_price": "100" + }, + { + "id": "13726", + "name": "Elemental spell", + "examine": "A tablet containing a Magic spell.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another one from the equipment box for this performance.", + "durability": null, + "shop_price": "100" + }, + { "id": "13727", + "name": "Stardust", + "examine": "Small, shiny bits of rock.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will need to speak with Larry/Chuck at Ardougne Zoo to get another.", - "examine": "Notes on the locations of penguin spies.", - "durability": null, - "name": "Spy notebook", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13732", - "absorb": "0,0,0", - "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": "true", + "destroy_message": "You can mine more if you find another crashed star.", + "durability": null, + "shop_price": "50" }, { + "id": "13732", + "name": "Spy notebook", + "examine": "Notes on the locations of penguin spies.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will need to speak with Larry/Chuck at Ardougne Zoo to get another.", + "durability": null + }, + { + "id": "13734", + "name": "Spirit shield", + "examine": "An ethereal shield.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,39,41,50,1,45,40,0,1,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "rare_item": "true", "requirements": "{1,40}-{5,55}", "shop_price": "70000", - "examine": "An ethereal shield.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "39982", - "name": "Spirit shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13734", - "bonuses": "0,0,0,0,0,39,41,50,1,45,40,0,1,0,0" + "tradeable": "true" }, { + "id": "13735", + "name": "Spirit shield", + "examine": "An ethereal shield.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", "destroy_message": "Drop", + "durability": null, "shop_price": "70000", - "examine": "An ethereal shield.", - "grand_exchange_price": "39982", - "durability": null, - "name": "Spirit shield", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13735" + "tradeable": "true" }, { + "id": "13736", + "name": "Blessed spirit shield", + "examine": "An ethereal shield that has been blessed with holy powers.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,53,55,73,2,52,65,0,3,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "rare_item": "true", "requirements": "{1,70}-{5,60}", "shop_price": "1400000", - "examine": "An ethereal shield that has been blessed with holy powers.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "936814", - "name": "Blessed spirit shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13736", - "bonuses": "0,0,0,0,0,53,55,73,2,52,65,0,3,0,0" + "tradeable": "true" }, { + "id": "13737", + "name": "Blessed spirit shield", + "examine": "An ethereal shield that has been blessed with holy powers.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", "destroy_message": "Drop", + "durability": null, "shop_price": "1400000", - "examine": "An ethereal shield that has been blessed with holy powers.", - "grand_exchange_price": "936814", - "durability": null, - "name": "Blessed spirit shield", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13737" + "tradeable": "true" }, { + "id": "13738", + "name": "Arcane spirit shield", + "examine": "An ethereal shield with an arcane sigil attached to it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,20,0,53,55,73,2,52,65,0,3,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,75}-{6,65}-{5,70}", "shop_price": "2000000", - "examine": "An ethereal shield with an arcane sigil attached to it.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "15076199", - "name": "Arcane spirit shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13738", - "bonuses": "0,0,0,20,0,53,55,73,2,52,65,0,3,0,0" + "tradeable": "true" }, { - "destroy_message": "Drop", - "shop_price": "2000000", - "examine": "An ethereal shield with an arcane sigil attached to it.", - "grand_exchange_price": "15076199", - "durability": null, + "id": "13739", "name": "Arcane spirit shield", - "tradeable": "true", - "destroy": "true", + "examine": "An ethereal shield with an arcane sigil attached to it.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13739" + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "2000000", + "tradeable": "true" }, { - "requirements": "{1,75}-{5,75}", - "shop_price": "2000000", - "examine": "An ethereal shield with a divine sigil attached to it.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "40003587", - "name": "Divine spirit shield", - "tradeable": "true", - "archery_ticket_price": "0", "id": "13740", - "bonuses": "0,0,0,0,0,63,65,75,2,57,65,0,3,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "2000000", - "examine": "An ethereal shield with a divine sigil attached to it.", - "grand_exchange_price": "40003587", - "durability": null, "name": "Divine spirit shield", - "tradeable": "true", - "destroy": "true", + "examine": "An ethereal shield with a divine sigil attached to it.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13741" - }, - { + "bonuses": "0,0,0,0,0,63,65,75,2,57,65,0,3,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,75}-{5,75}", "shop_price": "2000000", - "examine": "An ethereal shield with an elysian sigil attached to it.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "28420591", - "name": "Elysian spirit shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13742", - "bonuses": "0,0,0,0,0,63,65,75,2,57,65,0,3,0,0" + "tradeable": "true" }, { + "id": "13741", + "name": "Divine spirit shield", + "examine": "An ethereal shield with a divine sigil attached to it.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", "destroy_message": "Drop", + "durability": null, "shop_price": "2000000", - "examine": "An ethereal shield with an elysian sigil attached to it.", - "grand_exchange_price": "28420591", - "durability": null, - "name": "Elysian spirit shield", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13743" + "tradeable": "true" }, { + "id": "13742", + "name": "Elysian spirit shield", + "examine": "An ethereal shield with an elysian sigil attached to it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,63,65,75,2,57,65,0,3,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "requirements": "{1,75}-{5,75}", + "shop_price": "2000000", + "tradeable": "true" + }, + { + "id": "13743", + "name": "Elysian spirit shield", + "examine": "An ethereal shield with an elysian sigil attached to it.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "2000000", + "tradeable": "true" + }, + { + "id": "13744", + "name": "Spectral spirit shield", + "examine": "An ethereal shield with a spectral sigil attached to it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,53,55,73,30,52,65,0,3,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", "requirements": "{1,75}-{5,70}-{6,65}", "shop_price": "2000000", - "examine": "An ethereal shield with a spectral sigil attached to it.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "3616112", - "name": "Spectral spirit shield", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13744", - "bonuses": "0,0,0,0,0,53,55,73,30,52,65,0,3,0,0" + "tradeable": "true" }, { + "id": "13745", + "name": "Spectral spirit shield", + "examine": "An ethereal shield with a spectral sigil attached to it.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", "destroy_message": "Drop", + "durability": null, "shop_price": "2000000", - "examine": "An ethereal shield with a spectral sigil attached to it.", - "grand_exchange_price": "3616112", - "durability": null, - "name": "Spectral spirit shield", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13745" + "tradeable": "true" }, { - "shop_price": "750000", - "examine": "A sigil in the shape of an arcane rune.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "19508553", - "name": "Arcane sigil", - "tradeable": "true", - "archery_ticket_price": "0", "id": "13746", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "750000", - "examine": "A sigil in the shape of an arcane rune.", - "grand_exchange_price": "19508553", - "durability": null, "name": "Arcane sigil", - "tradeable": "true", - "destroy": "true", + "examine": "A sigil in the shape of an arcane rune.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13747" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "750000", + "tradeable": "true" }, { - "shop_price": "750000", - "examine": "A sigil in the shape of a divine symbol.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "53026134", - "name": "Divine sigil", - "tradeable": "true", + "id": "13747", + "name": "Arcane sigil", + "examine": "A sigil in the shape of an arcane rune.", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "750000", + "tradeable": "true" + }, + { "id": "13748", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "750000", - "examine": "A sigil in the shape of a divine symbol.", - "grand_exchange_price": "53026134", - "durability": null, "name": "Divine sigil", - "tradeable": "true", - "destroy": "true", + "examine": "A sigil in the shape of a divine symbol.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13749" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "750000", + "tradeable": "true" }, { - "shop_price": "750000", - "examine": "A sigil marked with elysian signs.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "36159098", - "name": "Elysian sigil", - "tradeable": "true", + "id": "13749", + "name": "Divine sigil", + "examine": "A sigil in the shape of a divine symbol.", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "750000", + "tradeable": "true" + }, + { "id": "13750", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "750000", - "examine": "A sigil marked with elysian signs.", - "grand_exchange_price": "36159098", - "durability": null, "name": "Elysian sigil", - "tradeable": "true", - "destroy": "true", + "examine": "A sigil marked with elysian signs.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13751" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "750000", + "tradeable": "true" }, { - "shop_price": "750000", - "examine": "A sigil tempered with spectral powers.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "3116720", - "name": "Spectral sigil", - "tradeable": "true", + "id": "13751", + "name": "Elysian sigil", + "examine": "A sigil marked with elysian signs.", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "750000", + "tradeable": "true" + }, + { "id": "13752", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "750000", - "examine": "A sigil tempered with spectral powers.", - "grand_exchange_price": "3116720", - "durability": null, "name": "Spectral sigil", - "tradeable": "true", - "destroy": "true", + "examine": "A sigil tempered with spectral powers.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13753" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "750000", + "tradeable": "true" }, { - "shop_price": "750000", - "examine": "A bottle of holy elixir.", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "950904", - "name": "Holy elixir", - "tradeable": "true", + "id": "13753", + "name": "Spectral sigil", + "examine": "A sigil tempered with spectral powers.", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "750000", + "tradeable": "true" + }, + { "id": "13754", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "750000", - "examine": "A bottle of holy elixir.", - "grand_exchange_price": "950904", - "durability": null, "name": "Holy elixir", - "tradeable": "true", - "destroy": "true", + "examine": "A bottle of holy elixir.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13755" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "750000", + "tradeable": "true" }, { - "destroy_message": "Drop", - "shop_price": "40", - "examine": "Logs cut from cursed willow roots.", - "durability": null, - "name": "Cursed willow logs", - "destroy": "true", + "id": "13755", + "name": "Holy elixir", + "examine": "A bottle of holy elixir.", "archery_ticket_price": "0", "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "750000", + "tradeable": "true" + }, + { "id": "13756", + "name": "Cursed willow logs", + "examine": "Logs cut from cursed willow roots.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "examine": "A loyal scout of Varrock.", - "durability": null, - "name": "Hartwin", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "40" + }, + { "id": "13757", + "name": "Hartwin", + "examine": "A loyal scout of Varrock.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You'll have to keep searching trees near the zombie trails until you find another.", - "examine": "A key that was found while tracking zombies. (Defender of Varrock)", - "durability": null, - "name": "Grubby key", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { "id": "13758", + "name": "Grubby key", + "examine": "A key that was found while tracking zombies. (Defender of Varrock)", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You'll have to speak to Thurgo to find another.", - "shop_price": "1", - "examine": "The location of ", - "durability": null, - "name": "Scrap of paper", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You'll have to keep searching trees near the zombie trails until you find another.", + "durability": null + }, + { "id": "13759", + "name": "Scrap of paper", + "examine": "The location of ", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Bottle", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You'll have to speak to Thurgo to find another.", + "durability": null, + "shop_price": "1" + }, + { "id": "13760", + "name": "Bottle", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A bottle of red mist.", - "durability": null, - "name": "Bottle of mist", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { "id": "13761", + "name": "Bottle of mist", + "examine": "A bottle of red mist.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another from ", - "examine": "This lists each of the founding members of the ", - "durability": null, - "name": "List of elders", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { "id": "13762", + "name": "List of elders", + "examine": "This lists each of the founding members of the ", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "I hope I don't meet any roundheads...", - "durability": null, - "name": "Cavalier and mask", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another from ", + "durability": null + }, + { "id": "13763", + "name": "Cavalier and mask", + "examine": "I hope I don't meet any roundheads...", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" }, { - "examine": "A right hand fighting claw.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "absorb": "0,0,0", - "equip_audio": "1003", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "6535", - "name": "Rune claws", - "archery_ticket_price": "0", "id": "13764", - "bonuses": "26,38,-4,0,0,10,19,5,0,0,0,39,0,0,0" + "name": "Rune claws", + "examine": "A right hand fighting claw.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "26,38,-4,0,0,10,19,5,0,0,0,39,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "1003", + "has_special": "true", + "lendable": "true", + "two_handed": "true", + "weapon_interface": "9" }, { - "examine": "A powerful dagger.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "4381", - "name": "Rune dagger", - "archery_ticket_price": "0", "id": "13765", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "durability": null, - "name": "Rune dagger(p)", - "destroy": "true", + "name": "Rune dagger", + "examine": "A powerful dagger.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "weapon_interface": "5" + }, + { "id": "13766", - "absorb": "0,0,0", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1", + "name": "Rune dagger(p)", "examine": "A picture of a lady called Elena.", - "durability": null, - "name": "Rune dagger(p+)", - "destroy": "true", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" + }, + { "id": "13767", - "absorb": "0,0,0", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1", + "name": "Rune dagger(p+)", "examine": "A picture of a lady called Elena.", - "durability": null, - "name": "Rune dagger(p++)", - "destroy": "true", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" + }, + { "id": "13768", + "name": "Rune dagger(p++)", + "examine": "A picture of a lady called Elena.", "absorb": "0,0,0", - "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" }, { - "examine": "A rune tipped spear.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "11317", - "name": "Rune spear", - "archery_ticket_price": "0", "id": "13769", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + "name": "Rune spear", + "examine": "A rune tipped spear.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "14" }, { - "examine": "A dragon tipped spear.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "28", - "defence_anim": "2079", - "attack_anims": "2080,2081,2082,2080", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "36774", - "name": "Dragon spear", - "archery_ticket_price": "0", "id": "13770", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + "name": "Dragon spear", + "examine": "A dragon tipped spear.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "14" }, { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "absorb": "0,0,0", - "render_anim": "28", - "destroy_message": "Drop", - "name": "Rune spear(p)", - "archery_ticket_price": "0", "id": "13771", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + "name": "Rune spear(p)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "render_anim": "28", + "shop_price": "1", + "two_handed": "true" }, { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "absorb": "0,0,0", - "render_anim": "28", - "defence_anim": "2079", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "name": "Dragon spear(p)", - "archery_ticket_price": "0", "id": "13772", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + "name": "Dragon spear(p)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "render_anim": "28", + "shop_price": "1", + "two_handed": "true" }, { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "absorb": "0,0,0", - "render_anim": "28", - "destroy_message": "Drop", - "name": "Rune spear(p+)", - "archery_ticket_price": "0", "id": "13773", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + "name": "Rune spear(p+)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "render_anim": "28", + "shop_price": "1", + "two_handed": "true" }, { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "absorb": "0,0,0", - "render_anim": "28", - "defence_anim": "2079", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "name": "Dragon spear(p+)", - "archery_ticket_price": "0", "id": "13774", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + "name": "Dragon spear(p+)", + "examine": "A picture of a lady called Elena.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "has_special": "true", + "render_anim": "28", + "shop_price": "1", + "two_handed": "true" }, { - "shop_price": "1", - "examine": "A picture of a lady called Elena.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "absorb": "0,0,0", - "render_anim": "28", - "destroy_message": "Drop", - "name": "Rune spear(p++)", - "archery_ticket_price": "0", "id": "13775", - "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" - }, - { - "shop_price": "1", + "name": "Rune spear(p++)", "examine": "A picture of a lady called Elena.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", "absorb": "0,0,0", - "render_anim": "28", - "defence_anim": "2079", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "name": "Dragon spear(p++)", "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "render_anim": "28", + "shop_price": "1", + "two_handed": "true" + }, + { "id": "13776", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" - }, - { - "examine": "A razor-sharp sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", + "name": "Dragon spear(p++)", + "examine": "A picture of a lady called Elena.", "absorb": "0,0,0", - "render_anim": "1381", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "11849", - "name": "Rune sword", "archery_ticket_price": "0", - "id": "13777", - "bonuses": "38,26,-2,0,0,0,2,1,0,0,0,39,0,0,0" - }, - { - "examine": "A two handed sword.", - "durability": null, - "destroy": "true", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "7", - "absorb": "0,0,0", - "render_anim": "124", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "37511", - "name": "Rune 2h sword", - "archery_ticket_price": "0", - "id": "13778", - "bonuses": "-4,69,50,-4,0,0,0,0,0,-1,0,70,0,0,0" - }, - { - "examine": "A rune halberd.", - "durability": null, - "destroy": "true", - "attack_speed": "7", - "two_handed": "true", - "weapon_interface": "15", - "absorb": "0,0,0", - "render_anim": "28", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "74298", - "name": "Rune halberd", - "archery_ticket_price": "0", - "id": "13779", - "bonuses": "48,67,0,-4,0,-1,4,5,0,0,0,68,0,0,0" - }, - { - "examine": "A spiky mace.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "8", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "7917", - "name": "Rune mace", - "archery_ticket_price": "0", - "id": "13780", - "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,0,4,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A series of connected metal rings.", - "grand_exchange_price": "29145", - "durability": null, - "name": "Rune chainbody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13781", - "absorb": "3,0,6", - "bonuses": "0,0,0,-15,0,63,72,78,-3,65,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These will protect my feet.", - "grand_exchange_price": "7036", - "durability": null, - "name": "Rune boots", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13782", - "absorb": "0,0,0", - "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A medium sized helmet.", - "grand_exchange_price": "10678", - "durability": null, - "name": "Rune med helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13783", - "absorb": "1,0,3", - "bonuses": "0,0,0,-3,-1,22,23,21,-1,22,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A stone helmet.", - "grand_exchange_price": "26576", - "durability": null, - "name": "Granite helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13784", - "absorb": "2,0,4", - "bonuses": "0,0,0,-9,-7,31,33,29,-1,39,9,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Provides excellent protection.", - "grand_exchange_price": "136414", - "durability": null, - "name": "Granite body", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13785", - "absorb": "4,0,8", - "bonuses": "0,0,0,-22,-5,87,84,79,-6,97,45,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These look pretty heavy.", - "grand_exchange_price": "72213", - "durability": null, - "name": "Granite legs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13786", - "absorb": "2,0,5", - "bonuses": "0,0,0,-31,-18,43,45,41,-4,68,20,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A medium square shield.", - "grand_exchange_price": "22225", - "durability": null, - "name": "Rune sq shield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13787", - "absorb": "3,0,7", - "bonuses": "0,0,0,-6,-2,38,40,36,0,38,35,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A solid stone shield.", - "grand_exchange_price": "32512", - "durability": null, - "name": "Granite shield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13788", - "absorb": "5,0,10", - "bonuses": "0,0,0,-12,-8,40,42,38,0,65,50,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A big 'do about nothing.", - "grand_exchange_price": "42991", - "durability": null, - "name": "A powdered wig", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13789", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These'll help me stay alive.", - "grand_exchange_price": "811293", - "durability": null, - "name": "Flared trousers", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13790", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Alas, someone has slashed my pantaloons.", - "grand_exchange_price": "19286", - "durability": null, - "name": "Pantaloons", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13791", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A cap for wearing whil...zzzzzzzzz", - "grand_exchange_price": "75357", - "durability": null, - "name": "Sleeping cap", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13792", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A diamond-topped cane.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "8", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "76692", - "name": "Rune cane", - "archery_ticket_price": "0", - "id": "13793", - "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,0,4,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Comes with a free rabbit!", - "grand_exchange_price": "333537", - "durability": null, - "name": "Top hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13794", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Shear elegance.", - "grand_exchange_price": "582969", - "durability": null, - "name": "Sheep mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13795", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "I can get the look right, but can I do the waddle too?", - "grand_exchange_price": "1159807", - "durability": null, - "name": "Penguin mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13796", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "The bats have left the belltower.", - "grand_exchange_price": "681595", - "durability": null, - "name": "Bat mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13797", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "It's the year of the cat!", - "grand_exchange_price": "2512014", - "durability": null, - "name": "Cat mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13798", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "I'm hungry like the wolf.", - "grand_exchange_price": "3240770", - "durability": null, - "name": "Wolf mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13799", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platebody with gold trim.", - "grand_exchange_price": "343688", - "durability": null, - "name": "Rune platebody (g)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13800", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "drop", - "examine": "Rune platelegs with gold trim.", - "grand_exchange_price": "238139", - "durability": null, - "name": "Rune platelegs (g)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13801", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune plateskirt with gold trim.", - "grand_exchange_price": "37616", - "durability": null, - "name": "Rune plateskirt (g)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13802", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune full helmet with gold trim.", - "grand_exchange_price": "247877", - "durability": null, - "name": "Rune full helm(g)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13803", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune kiteshield with gold trim", - "grand_exchange_price": "118205", - "durability": null, - "name": "Rune kiteshield (g)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13804", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platebody with trim.", - "grand_exchange_price": "100586", - "durability": null, - "name": "Rune platebody (t)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13805", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platelegs with trim!", - "grand_exchange_price": "81577", - "durability": null, - "name": "Rune platelegs (t)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13806", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune plateskirt with trim.", - "grand_exchange_price": "37701", - "durability": null, - "name": "Rune plateskirt (t)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13807", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune full helmet with trim.", - "grand_exchange_price": "95809", - "durability": null, - "name": "Rune full helm (t)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13808", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A large, metal shield with a nice trim.", - "grand_exchange_price": "46469", - "durability": null, - "name": "Rune kiteshield (t)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13809", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Your money or your life!", - "grand_exchange_price": "252995", - "durability": null, - "name": "Highwayman mask", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13810", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "Parlez-vous francais?", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "135411", - "name": "Blue beret", - "archery_ticket_price": "0", - "hat": true, - "id": "13811", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "Parlez-vous francais?", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "451371", - "name": "Black beret", - "archery_ticket_price": "0", - "hat": true, - "id": "13812", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "Parlez-vous Francais?", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "704147", - "name": "White beret", - "archery_ticket_price": "0", - "hat": true, - "id": "13813", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "All for one and one for all!", - "grand_exchange_price": "42014", - "durability": null, - "name": "Tan cavalier", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13814", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "All for one and one for all!", - "grand_exchange_price": "61518", - "durability": null, - "name": "Dark cavalier", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13815", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "All for one and one for all!", - "grand_exchange_price": "338530", - "durability": null, - "name": "Black cavalier", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13816", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A minimalist's hat.", - "grand_exchange_price": "159694", - "durability": null, - "name": "Red headband", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13817", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A minimalist's hat.", - "grand_exchange_price": "83543", - "durability": null, - "name": "Black headband", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13818", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A minimalist's hat.", - "grand_exchange_price": "26474", - "durability": null, - "name": "Brown headband", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13819", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platebody in the colours of Zamorak.", - "grand_exchange_price": "868398", - "durability": null, - "name": "Zamorak platebody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13820", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platelegs in the colours of Zamorak.", - "grand_exchange_price": "316989", - "durability": null, - "name": "Zamorak platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13821", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune plateskirt in the colours of Zamorak.", - "grand_exchange_price": "38597", - "durability": null, - "name": "Zamorak plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13822", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A full helmet in the colours of Zamorak.", - "grand_exchange_price": "618480", - "durability": null, - "name": "Zamorak full helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13823", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A Rune kiteshield in the colours of Zamorak.", - "grand_exchange_price": "225574", - "durability": null, - "name": "Zamorak kiteshield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13824", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platebody in the colours of Saradomin.", - "grand_exchange_price": "1555099", - "durability": null, - "name": "Saradomin platebody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13825", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platelegs in the colours of Saradomin.", - "grand_exchange_price": "376849", - "durability": null, - "name": "Saradomin platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13826", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune plateskirt in the colours of Saradomin.", - "grand_exchange_price": "53048", - "durability": null, - "name": "Saradomin plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13827", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune full helmet in the colours of Saradomin.", - "grand_exchange_price": "1025974", - "durability": null, - "name": "Saradomin full helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13828", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune kiteshield in the colours of Saradomin.", - "grand_exchange_price": "353916", - "durability": null, - "name": "Saradomin kiteshield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13829", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platebody in the colours of Guthix.", - "grand_exchange_price": "406762", - "durability": null, - "name": "Guthix platebody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13830", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platelegs in the colours of Guthix.", - "grand_exchange_price": "181471", - "durability": null, - "name": "Guthix platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13831", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune plateskirt in the colours of Guthix.", - "grand_exchange_price": "38388", - "durability": null, - "name": "Guthix plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13832", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "A rune full helmet in the colours of Guthix.", - "grand_exchange_price": "399963", - "durability": null, - "name": "Guthix full helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13833", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune kiteshield in the colours of Guthix.", - "grand_exchange_price": "185266", - "durability": null, - "name": "Guthix kiteshield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13834", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platebody with complete gold trim & plating.", - "grand_exchange_price": "2034838", - "durability": null, - "name": "Gilded platebody", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13835", - "absorb": "3,0,6", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune platelegs with gold plate.", - "grand_exchange_price": "1299758", - "durability": null, - "name": "Gilded platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13836", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune plateskirt with gold plate.", - "grand_exchange_price": "84191", - "durability": null, - "name": "Gilded plateskirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13837", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune full helmet with gold plate.", - "grand_exchange_price": "1057068", - "durability": null, - "name": "Gilded full helm", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13838", - "absorb": "1,0,3", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Rune kiteshield with gold plate.", - "grand_exchange_price": "506093", - "durability": null, - "name": "Gilded kiteshield", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13839", - "absorb": "3,0,7", - "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,45,0,0,0,0" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Atk, Def, Str and LP xp.", - "durability": null, - "name": "Brawling gloves (melee)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13845", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Ranged xp.", - "durability": null, - "name": "Brawling gloves (ranged)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13846", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Magic xp.", - "durability": null, - "name": "Brawling gloves (magic)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13847", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Prayer xp.", - "durability": null, - "name": "Brawling gloves (prayer)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13848", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Agility xp.", - "durability": null, - "name": "Brawling gloves (agility)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13849", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Woodcutting xp.", - "durability": null, - "name": "Brawling gloves (wc)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13850", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Firemaking xp.", - "durability": null, - "name": "Brawling gloves (fm)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13851", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Mining xp.", - "durability": null, - "name": "Brawling gloves (mining)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13852", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Hunting xp.", - "durability": null, - "name": "Brawling gloves (hunter)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13853", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Thieving xp.", - "durability": null, - "name": "Brawling gloves (thieving)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13854", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Smithing xp.", - "durability": null, - "name": "Brawling gloves (smithing)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13855", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Fishing xp.", - "durability": null, - "name": "Brawling gloves (fishing)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13856", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", - "shop_price": "50000", - "examine": "A pair of gloves that gives you bonus Cooking xp.", - "durability": null, - "name": "Brawling gloves (cooking)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13857", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "9" - }, - { - "requirements": "{1,78}-{6,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "12,6,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "1412812", - "name": "Zuriel's robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13858", - "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{6,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "1412812", - "durability": null, - "name": "Zuriel's robe top", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13859" - }, - { - "requirements": "{1,78}-{6,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "12,6,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "1412812", - "name": "Zuriel's robe top (deg)", - "archery_ticket_price": "0", - "id": "13860", - "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" - }, - { - "requirements": "{1,78}-{6,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "8,4,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "986668", - "name": "Zuriel's robe bottom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13861", - "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{6,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "986668", - "durability": null, - "name": "Zuriel's robe bottom", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13862" - }, - { - "requirements": "{1,78}-{6,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "8,4,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "986668", - "name": "Zuriel's robe bottom (deg)", - "archery_ticket_price": "0", - "id": "13863", - "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,78}-{6,78}", - "shop_price": "250000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "6,3,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "361542", - "name": "Zuriel's hood", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13864", - "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{6,78}", - "shop_price": "250000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "361542", - "durability": null, - "name": "Zuriel's hood", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13865" - }, - { - "remove_head": "true", - "requirements": "{1,78}-{6,78}", - "shop_price": "150000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,3,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "361542", - "name": "Zuriel's hood (deg)", - "archery_ticket_price": "0", - "id": "13866", - "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "turn180_anim": "1206", - "absorb": "0,0,0", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "destroy_message": "Drop", - "grand_exchange_price": "2116989", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "13867", - "stand_turn_anim": "1209", - "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", - "requirements": "{0,78}-{6,78}", - "shop_price": "300000", - "durability": null, - "destroy": "false", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Zuriel's staff" - }, - { - "destroy_message": "Drop", - "requirements": "{0,78}-{6,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "2116989", - "durability": null, - "name": "Zuriel's staff", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13868" - }, - { - "turn90cw_anim": "1207", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "1205", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "6", - "turn180_anim": "1206", - "absorb": "0,0,0", - "defence_anim": "420", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "destroy_message": "Drop", - "grand_exchange_price": "2116989", - "stand_anim": "813", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "13869", - "stand_turn_anim": "1209", - "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", - "requirements": "{0,78}-{6,78}", - "shop_price": "300000", - "durability": null, - "destroy": "true", - "weapon_interface": "1", - "render_anim": "28", - "attack_audios": "2555,0,0,0", - "name": "Zuriel's staff (deg)" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "0,12,6", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "926341", - "name": "Morrigan's leather body", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13870", - "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{4,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "926341", - "durability": null, - "name": "Morrigan's leather body", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13871" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,12,6", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "926341", - "name": "Morrigan's leather body (deg)", - "archery_ticket_price": "0", - "id": "13872", - "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "0,8,4", - "equipment_slot": "7", - "destroy_message": "Drop, Destroy after degrading.", - "grand_exchange_price": "510395", - "name": "Morrigan's leather chaps", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13873", - "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" - }, - { - "destroy_message": "Drop, Destroy after degrading.", - "requirements": "{1,78}-{4,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "510395", - "durability": null, - "name": "Morrigan's leather chaps", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13874" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,8,4", - "equipment_slot": "7", - "destroy_message": "Drop, Destroy after degrading.", - "grand_exchange_price": "510395", - "name": "Morrigan's leather chaps (deg)", - "archery_ticket_price": "0", - "id": "13875", - "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,78}-{4,78}", - "shop_price": "250000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "0,6,3", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "236411", - "name": "Morrigan's coif", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13876", - "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{4,78}", - "shop_price": "250000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "236411", - "durability": null, - "name": "Morrigan's coif", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13877" - }, - { - "remove_head": "true", - "requirements": "{1,78}-{4,78}", - "shop_price": "150000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,6,3", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "236411", - "name": "Morrigan's coif (deg)", - "archery_ticket_price": "0", - "id": "13878", - "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" - }, - { - "requirements": "{4,78}", - "shop_price": "4000", - "examine": "A vicious javelin.", - "has_special": "true", - "durability": null, - "destroy": "false", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "19944", - "name": "Morrigan's javelin", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13879", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "10000", - "examine": "A vicious javelin.", - "has_special": "true", - "durability": null, - "destroy": "false", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "19944", - "name": "Morrigan's javelin(p)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13880", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "10000", - "examine": "A vicious javelin.", - "has_special": "true", - "durability": null, - "destroy": "false", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "19944", - "name": "Morrigan's javelin(p+)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13881", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "10000", - "examine": "A vicious javelin.", - "has_special": "true", - "durability": null, - "destroy": "false", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "19944", - "name": "Morrigan's javelin(p++)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13882", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "4000", - "examine": "A vicious throwing axe.", - "has_special": "true", - "durability": null, - "destroy": "false", - "attack_speed": "5", - "weapon_interface": "18", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "9994", - "name": "Morrigan's throwing axe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13883", - "bonuses": "0,0,0,0,93,0,0,0,0,0,0,0,0,0,117" - }, - { - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "1619096", - "name": "Statius's platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13884", - "bonuses": "5,5,7,-30,-10,154,145,121,-6,157,60,5,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "1619096", - "durability": null, - "name": "Statius's platebody", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13885" - }, - { - "requirements": "{1,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "1619096", - "name": "Statius's platebody (deg)", - "archery_ticket_price": "0", - "id": "13886", - "bonuses": "5,5,7,-30,-10,154,145,121,-6,157,60,5,0,0,0" - }, - { - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop, Destroy once it has been degraded.", - "remove_sleeves": "true", - "grand_exchange_price": "2154168", - "name": "Vesta's chainbody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13887", - "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" - }, - { - "destroy_message": "Drop, Destroy once it has been degraded.", - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "2154168", - "durability": null, - "name": "Vesta's chainbody", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13888" - }, - { - "requirements": "{1,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop, Destroy once it has been degraded.", - "remove_sleeves": "true", - "grand_exchange_price": "2154168", - "name": "Vesta's chainbody (deg)", - "archery_ticket_price": "0", - "id": "13889", - "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" - }, - { - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1735029", - "name": "Statius's platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13890", - "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "1735029", - "durability": null, - "name": "Statius's platelegs", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13891" - }, - { - "requirements": "{1,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1735029", - "name": "Statius's platelegs (deg)", - "archery_ticket_price": "0", - "id": "13892", - "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" - }, - { - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1860767", - "name": "Vesta's plateskirt", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13893", - "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "500000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "1860767", - "durability": null, - "name": "Vesta's plateskirt", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13894" - }, - { - "requirements": "{1,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1860767", - "name": "Vesta's plateskirt (deg)", - "archery_ticket_price": "0", - "id": "13895", - "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,78}", - "shop_price": "250000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "1301986", - "name": "Statius's full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13896", - "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "250000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "1301986", - "durability": null, - "name": "Statius's full helm", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13897" - }, - { - "remove_head": "true", - "requirements": "{1,78}", - "shop_price": "150000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "1301986", - "name": "Statius' full helm (deg)", - "archery_ticket_price": "0", - "id": "13898", - "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" - }, - { - "turn90cw_anim": "1207", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "1205", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "10464249", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "13899", - "stand_turn_anim": "823", - "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", - "requirements": "{0,78}", - "shop_price": "300000", - "durability": null, - "destroy": "false", - "weapon_interface": "6", - "render_anim": "1426", - "attack_audios": "2500,2500,2517,2500", - "name": "Vesta's longsword" - }, - { - "destroy_message": "Drop", - "requirements": "{0,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "10464249", - "durability": null, - "name": "Vesta's longsword", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13900" - }, - { - "turn90cw_anim": "1207", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "1205", - "has_special": "true", - "rare_item": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "turn180_anim": "1206", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "10464249", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "13901", - "stand_turn_anim": "823", - "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", - "requirements": "{0,78}", - "shop_price": "300000", - "durability": null, - "destroy": "true", - "weapon_interface": "6", - "render_anim": "1426", - "attack_audios": "2500,2500,2517,2500", - "name": "Vesta's longsword (deg)" - }, - { - "turn90cw_anim": "821", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "819", - "has_special": "true", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "destroy_message": "Drop, Destroy once it has been degraded.", - "grand_exchange_price": "7424450", - "stand_anim": "808", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "13902", - "stand_turn_anim": "823", - "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", - "requirements": "{0,78}", - "shop_price": "300000", - "durability": null, - "destroy": "false", - "weapon_interface": "10", - "attack_audios": "2504,0,0,0", - "name": "Statius's warhammer" - }, - { - "destroy_message": "Drop, Destroy once it has been degraded.", - "requirements": "{0,78}", - "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "grand_exchange_price": "7424450", - "durability": null, - "name": "Statius's warhammer", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13903" - }, - { - "turn90cw_anim": "821", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "819", - "has_special": "true", - "turn90ccw_anim": "822", - "attack_speed": "6", - "turn180_anim": "820", - "absorb": "0,0,0", - "equipment_slot": "3", - "attack_anims": "395,395,395,395", - "destroy_message": "Drop, Destroy once it has been degraded.", - "grand_exchange_price": "7424450", - "stand_anim": "808", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "13904", - "stand_turn_anim": "823", - "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", - "shop_price": "300000", - "durability": null, - "destroy": "true", - "weapon_interface": "10", - "render_anim": "1426", - "attack_audios": "2504,0,0,0", - "name": "Statius' warhammer (deg)" - }, - { - "turn90cw_anim": "1207", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "1205", - "has_special": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "two_handed": "true", - "turn180_anim": "1206", - "absorb": "0,0,0", - "defence_anim": "2079", - "equipment_slot": "3", "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "destroy": "true", "destroy_message": "Drop", - "grand_exchange_price": "5264612", - "stand_anim": "813", - "tradeable": "true", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "13905", - "stand_turn_anim": "1209", - "bonuses": "133,113,120,0,0,18,21,21,0,0,0,122,0,0,0", - "requirements": "{0,78}", - "shop_price": "300000", "durability": null, - "destroy": "false", - "weight": "4.2", - "weapon_interface": "14", + "has_special": "true", "render_anim": "28", - "name": "Vesta's spear" + "shop_price": "1", + "two_handed": "true" }, { + "id": "13777", + "name": "Rune sword", + "examine": "A razor-sharp sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "38,26,-2,0,0,0,2,1,0,0,0,39,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "render_anim": "1381", + "weapon_interface": "5" + }, + { + "id": "13778", + "name": "Rune 2h sword", + "examine": "A two handed sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "-4,69,50,-4,0,0,0,0,0,-1,0,70,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "lendable": "true", + "render_anim": "124", + "two_handed": "true", + "weapon_interface": "7" + }, + { + "id": "13779", + "name": "Rune halberd", + "examine": "A rune halberd.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "7", + "bonuses": "48,67,0,-4,0,-1,4,5,0,0,0,68,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "lendable": "true", + "render_anim": "28", + "two_handed": "true", + "weapon_interface": "15" + }, + { + "id": "13780", + "name": "Rune mace", + "examine": "A spiky mace.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,0,4,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "weapon_interface": "8" + }, + { + "id": "13781", + "name": "Rune chainbody", + "examine": "A series of connected metal rings.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,0,63,72,78,-3,65,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13782", + "name": "Rune boots", + "examine": "These will protect my feet.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2237", + "lendable": "true" + }, + { + "id": "13783", + "name": "Rune med helm", + "examine": "A medium sized helmet.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,22,23,21,-1,22,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13784", + "name": "Granite helm", + "examine": "A stone helmet.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-9,-7,31,33,29,-1,39,9,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13785", + "name": "Granite body", + "examine": "Provides excellent protection.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-22,-5,87,84,79,-6,97,45,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13786", + "name": "Granite legs", + "examine": "These look pretty heavy.", + "absorb": "2,0,5", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-31,-18,43,45,41,-4,68,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13787", + "name": "Rune sq shield", + "examine": "A medium square shield.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,38,40,36,0,38,35,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13788", + "name": "Granite shield", + "examine": "A solid stone shield.", + "absorb": "5,0,10", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-12,-8,40,42,38,0,65,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13789", + "name": "A powdered wig", + "examine": "A big 'do about nothing.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13790", + "name": "Flared trousers", + "examine": "These'll help me stay alive.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13791", + "name": "Pantaloons", + "examine": "Alas, someone has slashed my pantaloons.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13792", + "name": "Sleeping cap", + "examine": "A cap for wearing whil...zzzzzzzzz", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13793", + "name": "Rune cane", + "examine": "A diamond-topped cane.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,0,4,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true", + "weapon_interface": "8" + }, + { + "id": "13794", + "name": "Top hat", + "examine": "Comes with a free rabbit!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13795", + "name": "Sheep mask", + "examine": "Shear elegance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13796", + "name": "Penguin mask", + "examine": "I can get the look right, but can I do the waddle too?", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13797", + "name": "Bat mask", + "examine": "The bats have left the belltower.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13798", + "name": "Cat mask", + "examine": "It's the year of the cat!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13799", + "name": "Wolf mask", + "examine": "I'm hungry like the wolf.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13800", + "name": "Rune platebody (g)", + "examine": "Rune platebody with gold trim.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13801", + "name": "Rune platelegs (g)", + "examine": "Rune platelegs with gold trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13802", + "name": "Rune plateskirt (g)", + "examine": "Rune plateskirt with gold trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13803", + "name": "Rune full helm(g)", + "examine": "Rune full helmet with gold trim.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13804", + "name": "Rune kiteshield (g)", + "examine": "Rune kiteshield with gold trim", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13805", + "name": "Rune platebody (t)", + "examine": "Rune platebody with trim.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13806", + "name": "Rune platelegs (t)", + "examine": "Rune platelegs with trim!", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13807", + "name": "Rune plateskirt (t)", + "examine": "Rune plateskirt with trim.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13808", + "name": "Rune full helm (t)", + "examine": "Rune full helmet with trim.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13809", + "name": "Rune kiteshield (t)", + "examine": "A large, metal shield with a nice trim.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13810", + "name": "Highwayman mask", + "examine": "Your money or your life!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13811", + "name": "Blue beret", + "examine": "Parlez-vous francais?", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "hat": true, + "lendable": "true" + }, + { + "id": "13812", + "name": "Black beret", + "examine": "Parlez-vous francais?", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "hat": true, + "lendable": "true" + }, + { + "id": "13813", + "name": "White beret", + "examine": "Parlez-vous Francais?", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "hat": true, + "lendable": "true" + }, + { + "id": "13814", + "name": "Tan cavalier", + "examine": "All for one and one for all!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13815", + "name": "Dark cavalier", + "examine": "All for one and one for all!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13816", + "name": "Black cavalier", + "examine": "All for one and one for all!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13817", + "name": "Red headband", + "examine": "A minimalist's hat.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13818", + "name": "Black headband", + "examine": "A minimalist's hat.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13819", + "name": "Brown headband", + "examine": "A minimalist's hat.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13820", + "name": "Zamorak platebody", + "examine": "Rune platebody in the colours of Zamorak.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13821", + "name": "Zamorak platelegs", + "examine": "Rune platelegs in the colours of Zamorak.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13822", + "name": "Zamorak plateskirt", + "examine": "Rune plateskirt in the colours of Zamorak.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13823", + "name": "Zamorak full helm", + "examine": "A full helmet in the colours of Zamorak.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13824", + "name": "Zamorak kiteshield", + "examine": "A Rune kiteshield in the colours of Zamorak.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13825", + "name": "Saradomin platebody", + "examine": "Rune platebody in the colours of Saradomin.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13826", + "name": "Saradomin platelegs", + "examine": "Rune platelegs in the colours of Saradomin.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13827", + "name": "Saradomin plateskirt", + "examine": "Rune plateskirt in the colours of Saradomin.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13828", + "name": "Saradomin full helm", + "examine": "Rune full helmet in the colours of Saradomin.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13829", + "name": "Saradomin kiteshield", + "examine": "Rune kiteshield in the colours of Saradomin.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13830", + "name": "Guthix platebody", + "examine": "Rune platebody in the colours of Guthix.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13831", + "name": "Guthix platelegs", + "examine": "Rune platelegs in the colours of Guthix.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13832", + "name": "Guthix plateskirt", + "examine": "Rune plateskirt in the colours of Guthix.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13833", + "name": "Guthix full helm", + "examine": "A rune full helmet in the colours of Guthix.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13834", + "name": "Guthix kiteshield", + "examine": "Rune kiteshield in the colours of Guthix.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13835", + "name": "Gilded platebody", + "examine": "Rune platebody with complete gold trim & plating.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13836", + "name": "Gilded platelegs", + "examine": "Rune platelegs with gold plate.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13837", + "name": "Gilded plateskirt", + "examine": "Rune plateskirt with gold plate.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13838", + "name": "Gilded full helm", + "examine": "Rune full helmet with gold plate.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "13839", + "name": "Gilded kiteshield", + "examine": "Rune kiteshield with gold plate.", + "absorb": "3,0,7", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,45,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "lendable": "true" + }, + { + "id": "13845", + "name": "Brawling gloves (melee)", + "examine": "A pair of gloves that gives you bonus Atk, Def, Str and LP xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13846", + "name": "Brawling gloves (ranged)", + "examine": "A pair of gloves that gives you bonus Ranged xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13847", + "name": "Brawling gloves (magic)", + "examine": "A pair of gloves that gives you bonus Magic xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13848", + "name": "Brawling gloves (prayer)", + "examine": "A pair of gloves that gives you bonus Prayer xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13849", + "name": "Brawling gloves (agility)", + "examine": "A pair of gloves that gives you bonus Agility xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13850", + "name": "Brawling gloves (wc)", + "examine": "A pair of gloves that gives you bonus Woodcutting xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13851", + "name": "Brawling gloves (fm)", + "examine": "A pair of gloves that gives you bonus Firemaking xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13852", + "name": "Brawling gloves (mining)", + "examine": "A pair of gloves that gives you bonus Mining xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13853", + "name": "Brawling gloves (hunter)", + "examine": "A pair of gloves that gives you bonus Hunting xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13854", + "name": "Brawling gloves (thieving)", + "examine": "A pair of gloves that gives you bonus Thieving xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13855", + "name": "Brawling gloves (smithing)", + "examine": "A pair of gloves that gives you bonus Smithing xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13856", + "name": "Brawling gloves (fishing)", + "examine": "A pair of gloves that gives you bonus Fishing xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13857", + "name": "Brawling gloves (cooking)", + "examine": "A pair of gloves that gives you bonus Cooking xp.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "durability": null, + "equipment_slot": "9", + "shop_price": "50000" + }, + { + "id": "13858", + "name": "Zuriel's robe top", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "12,6,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13859", + "name": "Zuriel's robe top", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13860", + "name": "Zuriel's robe top (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "12,6,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}-{6,78}", + "shop_price": "300000" + }, + { + "id": "13861", + "name": "Zuriel's robe bottom", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "8,4,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13862", + "name": "Zuriel's robe bottom", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13863", + "name": "Zuriel's robe bottom (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "8,4,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,78}-{6,78}", + "shop_price": "300000" + }, + { + "id": "13864", + "name": "Zuriel's hood", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,78}-{6,78}", + "shop_price": "250000", + "tradeable": "true" + }, + { + "id": "13865", + "name": "Zuriel's hood", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}-{6,78}", + "shop_price": "250000", + "tradeable": "true" + }, + { + "id": "13866", + "name": "Zuriel's hood (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,78}-{6,78}", + "shop_price": "150000" + }, + { + "id": "13867", + "name": "Zuriel's staff", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", + "defence_anim": "420", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,78}-{6,78}", + "run_anim": "1210", + "shop_price": "300000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "13868", + "name": "Zuriel's staff", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{0,78}-{6,78}", + "shop_price": "300000", + "tradeable": "true" + }, + { + "id": "13869", + "name": "Zuriel's staff (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", + "defence_anim": "420", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "rare_item": "true", + "render_anim": "28", + "requirements": "{0,78}-{6,78}", + "run_anim": "1210", + "shop_price": "300000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1" + }, + { + "id": "13870", + "name": "Morrigan's leather body", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,12,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13871", + "name": "Morrigan's leather body", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13872", + "name": "Morrigan's leather body (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,12,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}-{4,78}", + "shop_price": "300000" + }, + { + "id": "13873", + "name": "Morrigan's leather chaps", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,8,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop, Destroy after degrading.", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13874", + "name": "Morrigan's leather chaps", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop, Destroy after degrading.", + "durability": null, + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13875", + "name": "Morrigan's leather chaps (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,8,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop, Destroy after degrading.", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,78}-{4,78}", + "shop_price": "300000" + }, + { + "id": "13876", + "name": "Morrigan's coif", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,78}-{4,78}", + "shop_price": "250000", + "tradeable": "true" + }, + { + "id": "13877", + "name": "Morrigan's coif", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}-{4,78}", + "shop_price": "250000", + "tradeable": "true" + }, + { + "id": "13878", + "name": "Morrigan's coif (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,78}-{4,78}", + "shop_price": "150000" + }, + { + "id": "13879", + "name": "Morrigan's javelin", + "examine": "A vicious javelin.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "1381", + "requirements": "{4,78}", + "shop_price": "4000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "13880", + "name": "Morrigan's javelin(p)", + "examine": "A vicious javelin.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "1381", + "requirements": "{4,78}", + "shop_price": "10000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "13881", + "name": "Morrigan's javelin(p+)", + "examine": "A vicious javelin.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "1381", + "requirements": "{4,78}", + "shop_price": "10000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "13882", + "name": "Morrigan's javelin(p++)", + "examine": "A vicious javelin.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "1381", + "requirements": "{4,78}", + "shop_price": "10000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "13883", + "name": "Morrigan's throwing axe", + "examine": "A vicious throwing axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,0,93,0,0,0,0,0,0,0,0,0,117", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "requirements": "{4,78}", + "shop_price": "4000", + "tradeable": "true", + "weapon_interface": "18" + }, + { + "id": "13884", + "name": "Statius's platebody", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,5,7,-30,-10,154,145,121,-6,157,60,5,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13885", + "name": "Statius's platebody", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13886", + "name": "Statius's platebody (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,5,7,-30,-10,154,145,121,-6,157,60,5,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}", + "shop_price": "300000" + }, + { + "id": "13887", + "name": "Vesta's chainbody", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0", + "destroy": "false", + "destroy_message": "Drop, Destroy once it has been degraded.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13888", + "name": "Vesta's chainbody", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop, Destroy once it has been degraded.", + "durability": null, + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13889", + "name": "Vesta's chainbody (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0", + "destroy": "true", + "destroy_message": "Drop, Destroy once it has been degraded.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,78}", + "shop_price": "300000" + }, + { + "id": "13890", + "name": "Statius's platelegs", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13891", + "name": "Statius's platelegs", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13892", + "name": "Statius's platelegs (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,78}", + "shop_price": "300000" + }, + { + "id": "13893", + "name": "Vesta's plateskirt", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13894", + "name": "Vesta's plateskirt", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,78}", + "shop_price": "500000", + "tradeable": "true" + }, + { + "id": "13895", + "name": "Vesta's plateskirt (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,78}", + "shop_price": "300000" + }, + { + "id": "13896", + "name": "Statius's full helm", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,78}", + "shop_price": "250000", + "tradeable": "true" + }, + { + "id": "13897", + "name": "Statius's full helm", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "requirements": "{1,78}", + "shop_price": "250000", + "tradeable": "true" + }, + { + "id": "13898", + "name": "Statius' full helm (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,78}", + "shop_price": "150000" + }, + { + "id": "13899", + "name": "Vesta's longsword", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", + "defence_anim": "397", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "has_special": "true", + "rare_item": "true", + "render_anim": "1426", + "requirements": "{0,78}", + "run_anim": "824", + "shop_price": "300000", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "6" + }, + { + "id": "13900", + "name": "Vesta's longsword", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, "requirements": "{0,78}", "shop_price": "300000", - "examine": "This item degrades in combat, and will turn to dust.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "two_handed": "true", - "destroy_message": "Drop", - "grand_exchange_price": "5264612", - "name": "Vesta's spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13906" + "tradeable": "true" }, { + "id": "13901", + "name": "Vesta's longsword (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "has_special": "true", + "rare_item": "true", + "render_anim": "1426", + "requirements": "{0,78}", + "run_anim": "824", + "shop_price": "300000", + "stand_turn_anim": "823", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "6" + }, + { + "id": "13902", + "name": "Statius's warhammer", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", + "defence_anim": "397", + "destroy": "false", + "destroy_message": "Drop, Destroy once it has been degraded.", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "has_special": "true", + "requirements": "{0,78}", + "run_anim": "1210", + "shop_price": "300000", + "stand_anim": "808", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10" + }, + { + "id": "13903", + "name": "Statius's warhammer", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop, Destroy once it has been degraded.", + "durability": null, + "requirements": "{0,78}", + "shop_price": "300000", + "tradeable": "true" + }, + { + "id": "13904", + "name": "Statius' warhammer (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "395,395,395,395", + "attack_audios": "2504,0,0,0", + "attack_speed": "6", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", + "destroy": "true", + "destroy_message": "Drop, Destroy once it has been degraded.", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "1426", + "run_anim": "1210", + "shop_price": "300000", + "stand_anim": "808", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "10" + }, + { + "id": "13905", + "name": "Vesta's spear", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,122,0,0,0", + "defence_anim": "2079", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", + "requirements": "{0,78}", + "run_anim": "1210", + "shop_price": "300000", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14", + "weight": "4.2" + }, + { + "id": "13906", + "name": "Vesta's spear", + "examine": "This item degrades in combat, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "destroy_message": "Drop", + "durability": null, + "requirements": "{0,78}", + "shop_price": "300000", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "13907", + "name": "Vesta's spear (deg)", + "examine": "This item degrades in combat, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,122,0,0,0", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "has_special": "true", + "render_anim": "28", "requirements": "{0,78}", "shop_price": "180000", - "examine": "This item degrades in combat, and will turn to dust.", - "walk_anim": "1205", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", "turn90ccw_anim": "1208", - "weapon_interface": "14", - "absorb": "0,0,0", - "defence_anim": "2079", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "grand_exchange_price": "5264612", - "name": "Vesta's spear (deg)", - "archery_ticket_price": "0", - "id": "13907", - "bonuses": "133,113,120,0,0,18,21,21,0,0,0,122,0,0,0" + "two_handed": "true", + "walk_anim": "1205", + "weapon_interface": "14" }, { - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "1897306", - "name": "Corrupt statius's platebody", - "archery_ticket_price": "0", "id": "13908", - "bonuses": "5,5,7,-10,-30,154,145,121,-6,157,60,5,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "1897306", - "durability": null, "name": "Corrupt statius's platebody", - "tradeable": "true", - "destroy": "true", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "6,0,12", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13909" + "bonuses": "5,5,7,-10,-30,154,145,121,-6,157,60,5,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}", + "shop_price": "125000" }, { - "requirements": "{1,78}", - "shop_price": "75000", + "id": "13909", + "name": "Corrupt statius's platebody", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "1897306", - "name": "Corrupt statius's platebody (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13910", - "bonuses": "5,5,7,-10,-30,154,145,121,-6,157,60,5,0,0,0" + "name": "Corrupt statius's platebody (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,5,7,-10,-30,154,145,121,-6,157,60,5,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}}", + "shop_price": "75000" }, { - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "2546175", - "name": "Corrupt vesta's chainbody", - "archery_ticket_price": "0", "id": "13911", - "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "2546175", - "durability": null, "name": "Corrupt vesta's chainbody", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13912" - }, - { - "requirements": "{1,78}", - "shop_price": "75000", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", "absorb": "6,0,12", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "2546175", - "name": "Corrupt vesta's chainbody (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}", + "shop_price": "125000" + }, + { + "id": "13912", + "name": "Corrupt vesta's chainbody", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13913", - "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" + "name": "Corrupt vesta's chainbody (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "6,0,12", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}", + "shop_price": "75000" }, { - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1734527", - "name": "Corrupt statius's platelegs", - "archery_ticket_price": "0", "id": "13914", - "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "1734527", - "durability": null, "name": "Corrupt statius's platelegs", - "tradeable": "true", - "destroy": "true", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "4,0,8", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13915" + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,20}", + "shop_price": "125000" }, { - "requirements": "{1,78}", - "shop_price": "75000", + "id": "13915", + "name": "Corrupt statius's platelegs", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1734527", - "name": "Corrupt statius's platelegs (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13916", - "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" + "name": "Corrupt statius's platelegs (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "requirements": "{1,20}", + "shop_price": "75000" }, { - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1942627", - "name": "Corrupt vesta's plateskirt", - "archery_ticket_price": "0", "id": "13917", - "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "1942627", - "durability": null, "name": "Corrupt vesta's plateskirt", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13918" - }, - { - "requirements": "{1,78}", - "shop_price": "75000", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", "absorb": "4,0,8", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "1942627", - "name": "Corrupt vesta's plateskirt (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}", + "shop_price": "125000" + }, + { + "id": "13918", + "name": "Corrupt vesta's plateskirt", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13919", - "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" + "name": "Corrupt vesta's plateskirt (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "4,0,8", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}", + "shop_price": "75000" }, { - "remove_head": "true", - "requirements": "{1,78}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "1062835", - "name": "Corrupt statius's full helm", - "archery_ticket_price": "0", "id": "13920", - "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "1062835", - "durability": null, "name": "Corrupt statius's full helm", - "tradeable": "true", - "destroy": "true", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "3,0,6", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13921" + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "50000" }, { - "remove_head": "true", - "requirements": "{1,78}", - "shop_price": "30000", + "id": "13921", + "name": "Corrupt statius's full helm", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "1062835", - "name": "Corrupt statius' full helm (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}", + "shop_price": "50000", + "tradeable": "true" + }, + { "id": "13922", - "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" + "name": "Corrupt statius' full helm (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "30000" }, { - "requirements": "{0,78}", - "shop_price": "125000", - "turn90cw_anim": "1207", - "examine": "This item degrades while worn, and will turn to dust.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "5", - "turn180_anim": "1206", - "absorb": "0,0,0", - "render_anim": "1426", - "equipment_slot": "3", - "attack_anims": "381,390,390,390", - "destroy_message": "Drop", - "grand_exchange_price": "3739998", - "name": "Corrupt vesta's longsword", - "run_anim": "824", - "archery_ticket_price": "0", "id": "13923", - "stand_turn_anim": "823", - "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0" - }, - { - "requirements": "{0,78}", - "shop_price": "125000", - "turn90cw_anim": "1207", - "examine": "This item degrades while worn, and will turn to dust.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "turn90ccw_anim": "1208", - "attack_speed": "4", - "turn180_anim": "1206", - "render_anim": "1426", - "attack_anims": "381,390,390,390", - "destroy_message": "Drop", - "grand_exchange_price": "3739998", "name": "Corrupt vesta's longsword", - "tradeable": "true", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "13924", - "stand_turn_anim": "823" - }, - { - "requirements": "{0,78}", - "shop_price": "75000", - "turn90cw_anim": "1207", "examine": "This item degrades while worn, and will turn to dust.", - "walk_anim": "1205", - "durability": null, - "destroy": "true", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "5", - "turn180_anim": "1206", "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "381,390,390,390", + "attack_speed": "5", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", "render_anim": "1426", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "3739998", - "name": "C. vesta's longsword (deg)", + "requirements": "{0,20}", "run_anim": "824", - "archery_ticket_price": "0", - "id": "13925", + "shop_price": "125000", "stand_turn_anim": "823", - "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0" + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5" }, { - "requirements": "{0,78}", - "shop_price": "125000", + "id": "13924", + "name": "Corrupt vesta's longsword", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "8", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "3033516", - "attack_audios": "395,395,395,395", - "name": "Corrupt statius's warhammer", "archery_ticket_price": "0", + "attack_anims": "381,390,390,390", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "render_anim": "1426", + "requirements": "{0,20}", + "run_anim": "824", + "shop_price": "125000", + "stand_turn_anim": "823", + "tradeable": "true", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205" + }, + { + "id": "13925", + "name": "C. vesta's longsword (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1426", + "requirements": "{0,20}", + "run_anim": "824", + "shop_price": "75000", + "stand_turn_anim": "823", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "5" + }, + { "id": "13926", - "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{0,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "3033516", - "durability": null, "name": "Corrupt statius's warhammer", - "tradeable": "true", - "destroy": "true", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13927" + "attack_audios": "395,395,395,395", + "attack_speed": "6", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "requirements": "{0,20}", + "shop_price": "125000", + "weapon_interface": "8" }, { - "requirements": "{0,78}", - "shop_price": "75000", + "id": "13927", + "name": "Corrupt statius's warhammer", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "8", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "3033516", - "name": "C. statius's warhammer (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{0,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13928", - "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,0,0,0,0" + "name": "C. statius's warhammer (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2233", + "equipment_slot": "3", + "requirements": "{0,20}", + "shop_price": "75000", + "weapon_interface": "8" }, { - "requirements": "{0,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "grand_exchange_price": "343474", - "name": "Corrupt vesta's spear", - "archery_ticket_price": "0", "id": "13929", - "bonuses": "133,113,120,0,0,18,21,21,0,0,0,0,0,0,0" - }, - { - "requirements": "{0,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "destroy_message": "Drop", - "grand_exchange_price": "343474", "name": "Corrupt vesta's spear", - "tradeable": "true", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", "archery_ticket_price": "0", - "id": "13930" + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,20}", + "shop_price": "125000", + "two_handed": "true", + "weapon_interface": "14" }, { - "requirements": "{0,78}", - "shop_price": "75000", + "id": "13930", + "name": "Corrupt vesta's spear", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "343474", - "name": "Corrupt vesta's spear (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{0,20}", + "shop_price": "125000", + "tradeable": "true", + "two_handed": "true" + }, + { "id": "13931", - "bonuses": "133,113,120,0,0,18,21,21,0,0,0,0,0,0,0" + "name": "Corrupt vesta's spear (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{0,20}", + "shop_price": "75000", + "two_handed": "true", + "weapon_interface": "14" }, { - "requirements": "{1,78}-{6,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "12,6,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "253230", - "name": "Corrupt zuriel's robe top", - "archery_ticket_price": "0", "id": "13932", - "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{6,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "253230", - "durability": null, "name": "Corrupt zuriel's robe top", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13933" - }, - { - "requirements": "{1,78}-{6,78}", - "shop_price": "75000", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", "absorb": "12,6,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "253230", - "name": "Corrupt zuriel's robe top (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,20}", + "shop_price": "125000" + }, + { + "id": "13933", + "name": "Corrupt zuriel's robe top", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}-{6,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13934", - "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" + "name": "Corrupt zuriel's robe top (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "12,6,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,20}", + "shop_price": "75000" }, { - "requirements": "{1,78}-{6,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "8,4,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "121290", - "name": "Corrupt zuriel's robe bottom", - "archery_ticket_price": "0", "id": "13935", - "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{6,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "121290", - "durability": null, "name": "Corrupt zuriel's robe bottom", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13936" - }, - { - "requirements": "{1,78}-{6,78}", - "shop_price": "75000", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", "absorb": "8,4,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "121290", - "name": "Corrupt zuriel's robe bottom (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}-{6,20}", + "shop_price": "125000" + }, + { + "id": "13936", + "name": "Corrupt zuriel's robe bottom", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}-{6,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { "id": "13937", - "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" + "name": "Corrupt zuriel's robe bottom (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "8,4,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}-{6,20}", + "shop_price": "75000" }, { - "remove_head": "true", - "requirements": "{1,78}-{6,78}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,3,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "43778", - "name": "Corrupt zuriel's hood", - "archery_ticket_price": "0", "id": "13938", - "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{6,78}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "43778", - "durability": null, "name": "Corrupt zuriel's hood", - "tradeable": "true", - "destroy": "true", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "6,3,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "13939" + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,20}-{6,20}", + "shop_price": "50000" }, { - "remove_head": "true", - "requirements": "{1,78}-{6,78}", - "shop_price": "30000", + "id": "13939", + "name": "Corrupt zuriel's hood", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,3,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "43778", - "name": "Corrupt zuriel's hood (deg)", "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}-{6,20}", + "shop_price": "50000", + "tradeable": "true" + }, + { "id": "13940", - "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" - }, - { - "requirements": "{6,78}", - "shop_price": "125000", + "name": "Corrupt zuriel's hood (deg)", "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "2555,0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "219418", - "attack_audios": "2555,0,0,0", - "name": "Corrupt zuriel's staff", - "archery_ticket_price": "0", - "id": "13941", - "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10" - }, - { - "destroy_message": "Drop", - "requirements": "{6,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "219418", - "durability": null, - "name": "Corrupt zuriel's staff", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13942" - }, - { - "requirements": "{6,78}", - "shop_price": "70000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "219418", - "name": "Corrupt zuriel's staff (deg)", - "archery_ticket_price": "0", - "id": "13943", - "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,12,6", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "387212", - "name": "Corrupt morrigan's leather body", - "archery_ticket_price": "0", - "id": "13944", - "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{4,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "387212", - "durability": null, - "name": "Corrupt morrigan's leather body", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13945" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "75000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,12,6", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "387212", - "name": "Corrupt morrigan's leather body (deg)", - "archery_ticket_price": "0", - "id": "13946", - "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,8,4", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "84592", - "name": "Corrupt morrigan's leather chaps", - "archery_ticket_price": "0", - "id": "13947", - "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{4,78}", - "shop_price": "125000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "84592", - "durability": null, - "name": "Corrupt morrigan's leather chaps", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13948" - }, - { - "requirements": "{1,78}-{4,78}", - "shop_price": "75000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,8,4", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "84592", - "name": "Corrupt morrigan's leather chaps (deg)", - "archery_ticket_price": "0", - "id": "13949", - "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" - }, - { - "remove_head": "true", - "requirements": "{1,78}-{4,78}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,6,3", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "63502", - "name": "Corrupt morrigan's coif", - "archery_ticket_price": "0", - "id": "13950", - "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "requirements": "{1,78}-{4,78}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "63502", - "durability": null, - "name": "Corrupt morrigan's coif", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13951" - }, - { - "remove_head": "true", - "requirements": "{1,78}-{4,78}", - "shop_price": "30000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,6,3", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "63502", - "name": "Corrupt morrigan's coif (deg)", - "archery_ticket_price": "0", - "id": "13952", - "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" - }, - { - "requirements": "{4,78}", - "shop_price": "1000", - "examine": "A vicious javelin.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "6752", - "name": "Corrupt morrigan's javelin", - "archery_ticket_price": "0", - "id": "13953", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "10000", - "examine": "A vicious javelin.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "6752", - "name": "C. morrigan's javelin (p)", - "archery_ticket_price": "0", - "id": "13954", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "10000", - "examine": "A vicious javelin.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "6752", - "name": "C. morrigan's javelin (p+)", - "archery_ticket_price": "0", - "id": "13955", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "10000", - "examine": "A vicious javelin.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "18", - "absorb": "0,0,0", - "render_anim": "1381", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "6752", - "name": "C. morrigan's javelin (p++)", - "archery_ticket_price": "0", - "id": "13956", - "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" - }, - { - "requirements": "{4,78}", - "shop_price": "1000", - "examine": "A vicious throwing axe.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "18", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "5388", - "name": "C. morrigan's throwing axe", - "archery_ticket_price": "0", - "id": "13957", - "bonuses": "0,0,0,0,93,0,0,0,0,0,0,0,0,0,117" - }, - { - "requirements": "{0,78}-{4,78}", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,9", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "168278", - "name": "Corrupt dragon chainbody", - "archery_ticket_price": "0", - "id": "13958", - "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "168278", - "durability": null, - "name": "Corrupt dragon chainbody", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13959" - }, - { - "shop_price": "72000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,9", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "168278", - "name": "Corrupt dragon chainbody (deg)", - "archery_ticket_price": "0", - "id": "13960", - "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "60000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "2,0,4", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "121835", - "name": "Corrupt dragon med helm", - "archery_ticket_price": "0", - "id": "13961", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "121835", - "durability": null, - "name": "Corrupt dragon med helm", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13962" - }, - { - "remove_head": "true", - "shop_price": "36000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "2,0,4", - "equipment_slot": "0", - "destroy_message": "Drop", - "grand_exchange_price": "121835", - "name": "Corrupt dragon med helm (deg)", - "archery_ticket_price": "0", - "id": "13963", - "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" - }, - { - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "5,0,11", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "79703", - "name": "Corrupt dragon sq shield", - "archery_ticket_price": "0", - "id": "13964", - "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "79703", - "durability": null, - "name": "Corrupt dragon sq shield", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13965" - }, - { - "shop_price": "72000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "5,0,11", - "equipment_slot": "5", - "destroy_message": "Drop", - "grand_exchange_price": "79703", - "name": "Corrupt dragon sq shield (deg)", - "archery_ticket_price": "0", - "id": "13966", - "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" - }, - { - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "7", - "destroy_message": "Destroy", - "grand_exchange_price": "71066", - "name": "Corrupt dragon plateskirt", - "archery_ticket_price": "0", - "id": "13967", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "destroy_message": "Destroy", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "71066", - "durability": null, - "name": "Corrupt dragon plateskirt", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13968" - }, - { - "shop_price": "72000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "7", - "destroy_message": "Destroy", - "grand_exchange_price": "71066", - "name": "Corrupt dragon plateskirt (deg)", - "archery_ticket_price": "0", - "id": "13969", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "87957", - "name": "Corrupt dragon platelegs", - "archery_ticket_price": "0", - "id": "13970", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "87957", - "durability": null, - "name": "Corrupt dragon platelegs", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13971" - }, - { - "shop_price": "72000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "7", - "destroy_message": "Drop", - "grand_exchange_price": "87957", - "name": "Corrupt dragon platelegs (deg)", - "archery_ticket_price": "0", - "id": "13972", - "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "2.7", - "attack_speed": "6", - "weapon_interface": "2", - "absorb": "0,0,0", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "destroy_message": "Drop", - "grand_exchange_price": "332229", - "attack_audios": "2498,2498,2497,2498", - "name": "Corrupt dragon battleaxe", - "archery_ticket_price": "0", - "id": "13973", - "bonuses": "-2,70,65,0,0,0,0,0,-1,-1,0,85,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "120000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "2.7", - "attack_speed": "4", - "render_anim": "2586", - "defence_anim": "397", - "attack_anims": "395,395,401,395", - "destroy_message": "Drop", - "grand_exchange_price": "332229", - "attack_audios": "2498,2498,2497,2498", - "name": "Corrupt dragon battleaxe", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13974", - "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "72000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "2.7", - "attack_speed": "6", - "weapon_interface": "2", - "absorb": "0,0,0", - "render_anim": "2586", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "395,395,401,395", - "destroy_message": "Drop", - "grand_exchange_price": "332229", - "attack_audios": "2498,2498,2497,2498", - "name": "C. dragon battleaxe (deg)", - "archery_ticket_price": "0", - "id": "13975", - "bonuses": "-2,70,65,0,0,0,0,0,-1,-1,0,85,0,0,0" - }, - { - "shop_price": "30000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "396,396,395,396", - "destroy_message": "Drop", - "grand_exchange_price": "33358", - "attack_audios": "2517,2517,2500,2517", - "name": "Corrupt dragon dagger", - "archery_ticket_price": "0", - "id": "13976", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "shop_price": "30000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "defence_anim": "397", - "attack_anims": "396,396,395,396", - "destroy_message": "Drop", - "grand_exchange_price": "33358", - "attack_audios": "2517,2517,2500,2517", - "name": "Corrupt dragon dagger", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13977" - }, - { - "shop_price": "18000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "396,396,395,396", - "destroy_message": "Drop", - "grand_exchange_price": "33358", - "attack_audios": "2517,2517,2500,2517", - "name": "C. dragon dagger (deg)", - "archery_ticket_price": "0", - "id": "13978", - "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "100000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "1.8", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1928", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "338644", - "attack_audios": "2500,0,2517,0", - "name": "Corrupt dragon scimitar", - "archery_ticket_price": "0", - "id": "13979", - "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "338644", - "durability": null, - "name": "Corrupt dragon scimitar", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13980" - }, - { - "shop_price": "60000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1928", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "338644", - "name": "C. dragon scimitar (deg)", - "archery_ticket_price": "0", - "id": "13981", - "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "100000", - "ge_buy_limit": "10", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "1582", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "207053", - "attack_audios": "2500,2500,2517,2500", - "name": "Corrupt dragon longsword", - "archery_ticket_price": "0", - "id": "13982", - "bonuses": "58,69,-2,0,0,0,3,2,1,0,0,71,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100000", - "examine": "This item degrades while worn, and will turn to dust.", - "grand_exchange_price": "207053", - "durability": null, - "name": "Corrupt dragon longsword", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "13983" - }, - { - "shop_price": "60000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "1582", - "equipment_slot": "3", - "destroy_message": "Drop", - "grand_exchange_price": "207053", - "name": "C. dragon longsword (deg)", - "archery_ticket_price": "0", - "id": "13984", - "bonuses": "58,69,-2,0,0,0,3,2,1,0,0,71,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "8", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "50096", - "name": "Corrupt dragon mace", - "archery_ticket_price": "0", - "id": "13985", - "bonuses": "40,-2,60,1,0,0,0,0,0,0,0,55,0,5,0" - }, - { - "requirements": "{0,60}", - "shop_price": "50000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "1.8", - "attack_speed": "4", - "defence_anim": "397", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "50096", - "name": "Corrupt dragon mace", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13986" - }, - { - "requirements": "{0,60}", - "shop_price": "30000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "weight": "1.8", - "attack_speed": "5", - "weapon_interface": "8", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "grand_exchange_price": "50096", - "name": "Corrupt dragon mace (deg)", - "archery_ticket_price": "0", - "id": "13987", - "bonuses": "40,-2,60,1,0,0,0,0,0,0,0,55,0,5,0" - }, - { - "shop_price": "40000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "28", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "grand_exchange_price": "920922", - "name": "Corrupt dragon spear", - "archery_ticket_price": "0", - "id": "13988", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" - }, - { - "shop_price": "40000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "defence_anim": "2079", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "grand_exchange_price": "920922", - "name": "Corrupt dragon spear", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "13989" - }, - { - "shop_price": "24000", - "examine": "This item degrades while worn, and will turn to dust.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "two_handed": "true", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "28", - "defence_anim": "2079", - "equipment_slot": "3", - "attack_anims": "2080,2081,2082,2080", - "destroy_message": "Drop", - "grand_exchange_price": "920922", - "name": "Corrupt dragon spear (deg)", - "archery_ticket_price": "0", - "id": "13990", - "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" - }, - { - "destroy_message": "You can get another copy by searching bookshelves around 2009Scape.", - "shop_price": "5", - "examine": "A book about the Wilderness.", - "durability": null, - "name": "Pvp worlds manual", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14056", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "25", - "examine": "A threat to dusty corners everywhere.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "8", - "absorb": "0,0,0", - "render_anim": "1072", - "equipment_slot": "3", - "destroy_message": "You can obtain another by talking to Maggie the witch.", - "name": "Broomstick", - "archery_ticket_price": "0", - "id": "14057", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you drop the goulash, it will be destroyed. You can get some more by dipping a bowl into Maggie's cauldron.", - "shop_price": "2", - "examine": "What a curious and ghoulish smell!", - "durability": null, - "name": "Goulash", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14058", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "You can get another flask of magic unguent from the chest in Betty's basement.", - "shop_price": "2", - "examine": "Purple and pungent.", - "durability": null, - "name": "Magic unguent", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14061", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another flask of broom ointment from Hetty in Rimmington.", - "shop_price": "2", - "examine": "To be used on brooms.", - "durability": null, - "name": "Broom ointment", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14062", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you release this newt, you can get another from the crate in Hetty's basement in Rimmington.", - "shop_price": "5", - "examine": "A newt from Hetty's basement.", - "durability": null, - "name": "Newt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14064", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "You can get another newt label from Gus in Hetty's basement in Rimmington.", - "shop_price": "1", - "examine": "A label for a shipping crate.", - "durability": null, - "name": "Newt label", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14065", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another toad label from Gus in Hetty's basement in Rimmington.", - "shop_price": "1", - "examine": "A label for a shipping crate.", - "durability": null, - "name": "Toad label", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14066", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another newt-and-toad label from Gus in Hetty's basement in Rimmington.", - "shop_price": "1", - "examine": "A label for a shipping crate.", - "durability": null, - "name": "Newts and toads label", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14067", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can obtain another wand from the chest in Betty's basement.", - "shop_price": "15", - "examine": "Warm to the touch.", - "durability": null, - "name": "Betty's wand", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14068", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you destroy this item, you can get another from Lottie in Betty's basement.", - "shop_price": "2", - "examine": "What a view!", - "durability": null, - "name": "Magic slate", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14069", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you release this creature, you will have to restart the puzzle in Betty's basement.", - "shop_price": "1", - "examine": "Desert dweller.", - "durability": null, - "name": "Reptile", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14070", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "If you release this creature, you will have to restart the puzzle in Betty's basement.", - "shop_price": "1", - "examine": "Bleak and beaky.", - "durability": null, - "name": "Blackbird", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14071", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "examine": "An annoying flappy thing.", - "durability": null, - "name": "Bat", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14072", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "examine": "It's an extremely small brown spider, probably very poisonous.", - "durability": null, - "name": "Spider", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14073", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "examine": "A popular dwarven delicacy.", - "durability": null, - "name": "Rat", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14074", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "durability": null, - "name": "Snail", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14075", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "15", - "examine": "The height of warlock fashion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You can get another warlock top from Diango in Draynor Village.", - "remove_sleeves": "true", - "name": "Warlock top", - "archery_ticket_price": "0", - "id": "14076", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another set of warlock legs from Diango in Draynor Village.", - "shop_price": "15", - "examine": "Tattered but trendy.", - "durability": null, - "name": "Warlock legs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14077", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "shop_price": "15", - "examine": "The height of witchly fashion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You can get another witch top from Diango in Draynor.", - "remove_sleeves": "true", - "name": "Witch top", - "archery_ticket_price": "0", - "id": "14078", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another witch top from Diango in Draynor.", - "shop_price": "15", - "examine": "Tattered but trendy.", - "durability": null, - "name": "Witch skirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14079", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "You can get another witch cloak from Diango in Draynor.", - "shop_price": "15", - "examine": "Ragged but rugged.", - "durability": null, - "name": "Witch cloak", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14080", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "destroy_message": "You can get another warlock cloak from Diango in Draynor Village.", - "shop_price": "15", - "examine": "Ragged but rugged.", - "durability": null, - "name": "Warlock cloak", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14081", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "destroy_message": "Drop", - "shop_price": "1", - "examine": "A sticky orb of popped corn.", - "durability": null, - "name": "Popcorn ball", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14082", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1", - "examine": "Chocolatey goodness.", - "durability": null, - "name": "Chocolate drop", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14083", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1", - "examine": "Sugary bliss.", - "durability": null, - "name": "Wrapped candy", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14084", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1", - "examine": "An urgent communiqu?? revealing important information.", - "durability": null, - "name": "Armadyl communiqu?", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14085", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "15", - "examine": "The height of witchly fashion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "You can get another witch top from Diango in Draynor.", - "remove_sleeves": "true", - "name": "Witch top", - "archery_ticket_price": "0", - "id": "14086", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can get another witch top from Diango in Draynor.", - "shop_price": "15", - "examine": "Tattered but trendy.", - "durability": null, - "name": "Witch skirt", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14087", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "You can get another witch cloak from Diango in Draynor.", - "shop_price": "15", - "examine": "Ragged but rugged.", - "durability": null, - "name": "Witch cloak", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14088", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "durability": null, - "name": "Pet kitten", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14089", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Pet cat", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14090", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Lazy cat", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14091", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Overgrown cat", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14092", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Wily cat", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14093", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "43333", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Sacred clay platebody", - "archery_ticket_price": "0", - "id": "14094", - "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "42667", - "examine": "The sacred clay bottom has transformed into spiked, platemail legs.", - "durability": null, - "name": "Sacred clay platelegs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14095", - "absorb": "2,0,4", - "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", - "equipment_slot": "7" - }, - { - "remove_head": "true", - "shop_price": "23467", - "examine": "The sacred clay hat has transformed into a spined helm.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "1,0,3", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Sacred clay helm", - "archery_ticket_price": "0", - "id": "14096", - "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" - }, - { - "shop_price": "17066", - "examine": "The sacred clay weapon has transformed into a sharp scimitar.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "1629", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Sacred clay scimitar", - "archery_ticket_price": "0", - "id": "14097", - "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "This can turn into a variety of tools.", - "durability": null, - "name": "Volatile clay tool", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14098", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "21333", - "examine": "Your volatile tool wants to mine some rocks.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Volatile clay pickaxe", - "archery_ticket_price": "0", - "id": "14099", - "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" - }, - { - "shop_price": "21333", - "examine": "Your volatile tool wants to cut some wood.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Volatile clay hatchet", - "archery_ticket_price": "0", - "id": "14100", - "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "Your volatile tool wants to spear some big fish.", - "durability": null, - "name": "Volatile clay harpoon", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14101", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "shop_price": "21333", - "examine": "Your volatile tool wants to catch some butterflies.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Volatile clay butterfly net", - "archery_ticket_price": "0", - "id": "14102", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "Your volatile tool wants to make some bows or arrows.", - "durability": null, - "name": "Volatile clay fletching knife", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14103", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "Your volatile tool wants to work metal or build furniture.", - "durability": null, - "name": "Volatile clay hammer", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14104", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "Your volatile tool wants to make some leather armour.", - "durability": null, - "name": "Volatile clay needle", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14105", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "This can turn into a variety of tools.", - "durability": null, - "name": "Proto-tool", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14106", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "21333", - "examine": "Your sacred clay tool has transformed into a pickaxe.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Sacred clay pickaxe", - "archery_ticket_price": "0", - "id": "14107", - "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" - }, - { - "shop_price": "21333", - "examine": "Your sacred clay tool has transformed into a hatchet.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Sacred clay hatchet", - "archery_ticket_price": "0", - "id": "14108", - "bonuses": "-2,4,2,0,0,0,1,0,0,0,0,5,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "Your sacred clay tool has transformed into a harpoon.", - "durability": null, - "name": "Sacred clay harpoon", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14109", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "shop_price": "1", - "examine": "Your sacred clay tool has transformed into a butterfly net.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "5", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Sacred clay butterfly net", - "archery_ticket_price": "0", - "id": "14110", - "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "The sacred clay has transformed into a knife.", - "durability": null, - "name": "Sacred clay fletching knife", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14111", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "Your sacred clay tool has transformed into a hammer.", - "durability": null, - "name": "Sacred clay hammer", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14112", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "21333", - "examine": "The sacred clay has transformed into a needle.", - "durability": null, - "name": "Sacred clay needle", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14113", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "43333", - "examine": "The sacred clay top has transformed into a heavy, magical robe.", - "durability": null, - "destroy": "true", - "attack_speed": "4", "absorb": "6,3,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Sacred clay robe top", - "archery_ticket_price": "0", - "id": "14114", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "42667", - "examine": "The sacred clay bottom has transformed into a heavy, magical robe.", - "durability": null, - "name": "Sacred clay robe bottom", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14115", - "absorb": "4,2,0", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", - "equipment_slot": "7" - }, - { + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0", + "destroy": "true", "destroy_message": "Drop", - "shop_price": "23467", - "examine": "The sacred clay hat has transformed into a wizard hat.", "durability": null, - "name": "Sacred clay hat", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14116", - "absorb": "3,1,0", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", - "equipment_slot": "0" + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,20}-{6,20}", + "shop_price": "30000" }, { - "shop_price": "17066", - "examine": "The sacred clay weapon has transformed into a magical staff.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", + "id": "13941", + "name": "Corrupt zuriel's staff", + "examine": "This item degrades while worn, and will turn to dust.", "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Sacred clay staff", "archery_ticket_price": "0", - "id": "14117", - "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0" + "attack_anims": "2555,0,0,0", + "attack_audios": "2555,0,0,0", + "attack_speed": "6", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{6,20}", + "shop_price": "125000", + "weapon_interface": "1" }, { - "shop_price": "43333", - "examine": "The sacred clay top has transformed into a leather body.", - "durability": null, - "destroy": "true", + "id": "13942", + "name": "Corrupt zuriel's staff", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{6,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { + "id": "13943", + "name": "Corrupt zuriel's staff (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "requirements": "{6,20}", + "shop_price": "70000", + "weapon_interface": "1" + }, + { + "id": "13944", + "name": "Corrupt morrigan's leather body", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,12,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}-{4,20}", + "shop_price": "125000" + }, + { + "id": "13945", + "name": "Corrupt morrigan's leather body", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}-{4,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { + "id": "13946", + "name": "Corrupt morrigan's leather body (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,12,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}-{4,20}", + "shop_price": "75000" + }, + { + "id": "13947", + "name": "Corrupt morrigan's leather chaps", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,8,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}-{4,20}", + "shop_price": "125000" + }, + { + "id": "13948", + "name": "Corrupt morrigan's leather chaps", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}-{4,20}", + "shop_price": "125000", + "tradeable": "true" + }, + { + "id": "13949", + "name": "Corrupt morrigan's leather chaps (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,8,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}-{4,20}", + "shop_price": "75000" + }, + { + "id": "13950", + "name": "Corrupt morrigan's coif", + "examine": "This item degrades while worn, and will turn to dust.", "absorb": "0,6,3", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Sacred clay body", - "archery_ticket_price": "0", - "id": "14118", - "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "42667", - "examine": "The sacred clay bottom has been transformed into a set of chaps.", - "durability": null, - "name": "Sacred clay chaps", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14119", - "absorb": "0,4,2", - "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", - "equipment_slot": "7" - }, - { - "remove_head": "true", - "shop_price": "23467", - "examine": "The sacred clay hat has transformed into a coif.", - "durability": null, + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0", "destroy": "true", - "attack_speed": "4", - "absorb": "0,3,1", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2238", "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Sacred clay coif", - "archery_ticket_price": "0", - "id": "14120", - "bonuses": "0,0,0,-1,2,4,6,8,4,4,5,0,0,0,0" + "remove_head": "true", + "requirements": "{1,20}-{4,20}", + "shop_price": "50000" }, { - "shop_price": "17066", - "examine": "The sacred clay weapon has transformed into a bow.", - "durability": null, - "destroy": "true", + "id": "13951", + "name": "Corrupt morrigan's coif", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "16", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{1,20}-{4,20}", + "shop_price": "50000", + "tradeable": "true" + }, + { + "id": "13952", + "name": "Corrupt morrigan's coif (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2238", + "equipment_slot": "0", + "remove_head": "true", + "requirements": "{1,20}-{4,20}", + "shop_price": "30000" + }, + { + "id": "13953", + "name": "Corrupt morrigan's javelin", + "examine": "A vicious javelin.", "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Sacred clay bow", "archery_ticket_price": "0", - "id": "14121", - "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "30", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Pickaxe (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14122", - "bonuses": "10,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "name": "Pickaxe (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14123" - }, - { - "shop_price": "60", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Pickaxe (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14124", - "bonuses": "15,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "name": "Pickaxe (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14125" - }, - { - "shop_price": "90", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Pickaxe (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14126", - "bonuses": "20,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "name": "Pickaxe (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14127" - }, - { - "shop_price": "120", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Pickaxe (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14128", - "bonuses": "25,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "name": "Pickaxe (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14129" - }, - { - "shop_price": "150", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "4", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Pickaxe (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14130", - "bonuses": "30,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has become hard enough to chip stone.", - "durability": null, - "name": "Pickaxe (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14131" - }, - { - "shop_price": "30", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Hatchet (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14132", - "bonuses": "0,10,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "name": "Hatchet (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14133" - }, - { - "shop_price": "60", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Hatchet (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14134", - "bonuses": "0,15,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "name": "Hatchet (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14135" - }, - { - "shop_price": "90", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Hatchet (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14136", - "bonuses": "0,20,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "name": "Hatchet (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14137" - }, - { - "shop_price": "120", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Hatchet (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14138", - "bonuses": "0,25,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "name": "Hatchet (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14139" - }, - { - "shop_price": "150", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "2", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Hatchet (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14140", - "bonuses": "0,30,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has become sharp enough to cut wood.", - "durability": null, - "name": "Hatchet (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14141" - }, - { - "shop_price": "30", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Harpoon (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14142", - "bonuses": "10,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "name": "Harpoon (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14143" - }, - { - "shop_price": "60", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Harpoon (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14144", - "bonuses": "15,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "name": "Harpoon (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14145" - }, - { - "shop_price": "90", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Harpoon (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14146", - "bonuses": "20,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "name": "Harpoon (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14147" - }, - { - "shop_price": "120", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Harpoon (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14148", - "bonuses": "25,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "name": "Harpoon (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14149" - }, - { - "shop_price": "150", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Harpoon (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14150", - "bonuses": "30,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has become long enough to reach the depths of pools.", - "durability": null, - "name": "Harpoon (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14151" - }, - { - "shop_price": "30", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Butterfly net (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14152", - "bonuses": "0,0,10,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "name": "Butterfly net (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14153" - }, - { - "shop_price": "60", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Butterfly net (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14154", - "bonuses": "0,0,15,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "name": "Butterfly net (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14155" - }, - { - "shop_price": "90", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Butterfly net (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14156", - "bonuses": "0,0,20,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "name": "Butterfly net (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14157" - }, - { - "shop_price": "120", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Butterfly net (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14158", - "bonuses": "0,0,25,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "name": "Butterfly net (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14159" - }, - { - "shop_price": "150", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "14", - "absorb": "0,0,0", - "render_anim": "158", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Butterfly net (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14160", - "bonuses": "0,0,30,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has become light enough to swing at floating shards.", - "durability": null, - "name": "Butterfly net (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14161" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14162", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14163" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14164", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14165" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14166", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14167" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14168", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14169" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14170", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into something bland, but edible.", - "durability": null, - "name": "Food (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14171" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14172", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14173" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14174", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14175" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14176", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14177" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14178", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14179" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14180", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The clay has transformed into an expandable wall.", - "durability": null, - "name": "Barrier (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14181" - }, - { - "destroy_message": "Drop", - "shop_price": "15", - "examine": "Very low quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14182", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "15", - "examine": "Very low quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14183" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "Low quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14184", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "Low quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14185" - }, - { - "destroy_message": "Drop", - "shop_price": "45", - "examine": "Medium quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14186", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "45", - "examine": "Medium quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14187" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "High quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14188", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "High quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14189" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Very high quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14190", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "75", - "examine": "Very high quality sacred clay.", - "durability": null, - "name": "Sacred clay (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14191" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Bow (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14192", - "bonuses": "0,0,0,0,55,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "name": "Bow (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "two_handed": "true", - "id": "14193" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Bow (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14194", - "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "name": "Bow (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "two_handed": "true", - "id": "14195" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Bow (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14196", - "bonuses": "0,0,0,0,135,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "name": "Bow (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "two_handed": "true", - "id": "14197" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Bow (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14198", - "bonuses": "0,0,0,0,180,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "name": "Bow (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "two_handed": "true", - "id": "14199" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "two_handed": "true", - "weapon_interface": "16", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Bow (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14200", - "bonuses": "0,0,0,0,225,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a wood-like substance.", - "durability": null, - "name": "Bow (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "two_handed": "true", - "id": "14201" - }, - { - "shop_price": "2", - "examine": "The Sacred Clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "13", - "destroy_message": "Drop", - "name": "Arrows (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14202", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,15" - }, - { - "shop_price": "4", - "examine": "The Sacred Clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "13", - "destroy_message": "Drop", - "name": "Arrows (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14203", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30" - }, - { - "shop_price": "6", - "examine": "The Sacred Clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "13", - "destroy_message": "Drop", - "name": "Arrows (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14204", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,45" - }, - { - "shop_price": "8", - "examine": "The Sacred Clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "13", - "destroy_message": "Drop", - "name": "Arrows (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14205", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60" - }, - { - "shop_price": "10", - "examine": "The Sacred Clay has transformed into a wood-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "13", - "destroy_message": "Drop", - "name": "Arrows (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14206", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75" - }, - { - "shop_price": "150", - "examine": "3 doses of Prayer restore potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Prayer potion(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14207", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "3 doses of Prayer restore potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Prayer potion(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14208" - }, - { - "shop_price": "120", - "examine": "4 doses of Prayer restore potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Prayer potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14209", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of Prayer restore potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Prayer potion(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14210" - }, - { - "shop_price": "90", - "examine": "3 doses of Prayer restore potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Prayer potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14211", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of Prayer restore potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Prayer potion(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14212" - }, - { - "shop_price": "60", - "examine": "2 doses of Prayer restore potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Prayer potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14213", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of Prayer restore potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Prayer potion(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14214" - }, - { - "shop_price": "30", - "examine": "1 dose of Prayer restore potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Prayer potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14215", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of Prayer restore potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Prayer potion(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14216" - }, - { - "shop_price": "150", - "examine": "4 doses of energy potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Energy potion (5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14217", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "4 doses of energy potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Energy potion (5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14218" - }, - { - "shop_price": "120", - "examine": "4 doses of energy potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Energy potion (4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14219", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of energy potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Energy potion (4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14220" - }, - { - "shop_price": "90", - "examine": "3 doses of energy potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Energy potion (3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14221", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of energy potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Energy potion (3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14222" - }, - { - "shop_price": "60", - "examine": "2 doses of energy potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Energy potion (2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14223", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of energy potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Energy potion (2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14224" - }, - { - "shop_price": "30", - "examine": "1 dose of energy potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Energy potion (1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14225", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of energy potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Energy potion (1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14226" - }, - { - "shop_price": "150", - "examine": "5 doses of super Attack potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super attack(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14227", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "5 doses of super Attack potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super attack(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14228" - }, - { - "shop_price": "120", - "examine": "4 doses of super Attack potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super attack(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14229", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of super Attack potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super attack(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14230" - }, - { - "shop_price": "90", - "examine": "3 doses of super Attack potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super attack(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14231", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of super Attack potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super attack(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14232" - }, - { - "shop_price": "60", - "examine": "2 doses of super Attack potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super attack(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14233", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of super Attack potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super attack(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14234" - }, - { - "shop_price": "30", - "examine": "1 dose of super Attack potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super attack(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14235", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of super Attack potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super attack(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14236" - }, - { - "shop_price": "150", - "examine": "5 doses of super Strength potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super strength(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14237", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "5 doses of super Strength potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super strength(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14238" - }, - { - "shop_price": "120", - "examine": "4 doses of super Strength potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super strength(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14239", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of super Strength potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super strength(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14240" - }, - { - "shop_price": "90", - "examine": "3 doses of super Strength potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super strength(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14241", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of super Strength potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super strength(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14242" - }, - { - "shop_price": "60", - "examine": "2 doses of super Strength potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super strength(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14243", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of super Strength potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super strength(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14244" - }, - { - "shop_price": "30", - "examine": "1 dose of super Strength potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Super strength(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14245", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of super Strength potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Super strength(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14246" - }, - { - "shop_price": "150", - "examine": "4 doses of ranging potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Ranging potion(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14247", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "5 doses of ranging potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Ranging potion(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14248" - }, - { - "shop_price": "120", - "examine": "4 doses of ranging potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Ranging potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14249", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of ranging potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Ranging potion(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14250" - }, - { - "shop_price": "90", - "examine": "3 doses of ranging potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Ranging potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14251", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of ranging potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Ranging potion(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14252" - }, - { - "shop_price": "60", - "examine": "2 doses of ranging potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Ranging potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14253", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of ranging potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Ranging potion(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14254" - }, - { - "shop_price": "30", - "examine": "1 dose of ranging potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Ranging potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14255", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of ranging potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Ranging potion(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14256" - }, - { - "shop_price": "150", - "examine": "3 doses of Defence Potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Defence potion(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14257", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "3 doses of Defence Potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Defence potion(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14258" - }, - { - "shop_price": "120", - "examine": "4 doses of Defence Potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Defence potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14259", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of Defence Potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Defence potion(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14260" - }, - { - "shop_price": "90", - "examine": "3 doses of Defence Potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Defence potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14261", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of Defence Potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Defence potion(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14262" - }, - { - "shop_price": "60", - "examine": "2 doses of Defence Potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Defence potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14263", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of Defence Potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Defence potion(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14264" - }, - { - "shop_price": "30", - "examine": "1 dose of Defence Potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Defence potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14265", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of Defence Potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Defence potion(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14266" - }, - { - "shop_price": "150", - "examine": "4 doses of Magic potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Magic potion(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14267", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "5 doses of Magic potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Magic potion(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14268" - }, - { - "shop_price": "120", - "examine": "4 doses of Magic potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Magic potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14269", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of Magic potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Magic potion(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14270" - }, - { - "shop_price": "90", - "examine": "3 doses of Magic potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Magic potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14271", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of Magic potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Magic potion(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14272" - }, - { - "shop_price": "60", - "examine": "2 doses of Magic potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Magic potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14273", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of Magic potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Magic potion(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14274" - }, - { - "shop_price": "30", - "examine": "1 dose of Magic potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Magic potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14275", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of Magic potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Magic potion(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14276" - }, - { - "shop_price": "150", - "examine": "3 doses of Summoning potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Summoning potion(5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14277", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "3 doses of Summoning potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Summoning potion(5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14278" - }, - { - "shop_price": "120", - "examine": "4 doses of Summoning potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Summoning potion(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14279", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "4 doses of Summoning potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Summoning potion(4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14280" - }, - { - "shop_price": "90", - "examine": "3 doses of Summoning potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Summoning potion(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14281", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "3 doses of Summoning potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Summoning potion(3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14282" - }, - { - "shop_price": "60", - "examine": "2 doses of Summoning potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Summoning potion(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14283", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "2 doses of Summoning potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Summoning potion(2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14284" - }, - { - "shop_price": "30", - "examine": "1 dose of Summoning potion.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "4", - "name": "Summoning potion(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14285", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "1 dose of Summoning potion.", - "grand_exchange_price": "4", - "durability": null, - "name": "Summoning potion(1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14286" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1629", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "attack_audios": "2500,0,2517,0", - "name": "Scimitar (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14287", - "bonuses": "0,55,0,0,0,0,0,0,0,0,0,15,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "name": "Scimitar (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14288" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1629", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "attack_audios": "2500,0,2517,0", - "name": "Scimitar (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14289", - "bonuses": "0,90,0,0,0,0,0,0,0,0,0,30,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "name": "Scimitar (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14290" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1629", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "attack_audios": "2500,0,2517,0", - "name": "Scimitar (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14291", - "bonuses": "0,145,0,0,0,0,0,0,0,0,0,45,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "name": "Scimitar (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14292" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1629", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "attack_audios": "2500,0,2517,0", - "name": "Scimitar (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14293", - "bonuses": "0,180,0,0,0,0,0,0,0,0,0,60,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "name": "Scimitar (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14294" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "weapon_interface": "6", - "absorb": "0,0,0", - "render_anim": "1629", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "Drop", - "attack_audios": "2500,0,2517,0", - "name": "Scimitar (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14295", - "bonuses": "0,225,0,0,0,0,0,0,0,0,0,75,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a vicious, curved sword.", - "durability": null, - "name": "Scimitar (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14296" - }, - { - "shop_price": "30", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "destroy": "true", - "attack_speed": "3", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dagger (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14297", - "bonuses": "41,0,0,0,0,0,0,0,0,0,0,15,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "name": "Dagger (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14298" - }, - { - "shop_price": "60", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "destroy": "true", - "attack_speed": "3", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dagger (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14299", - "bonuses": "68,0,0,0,0,0,0,0,0,0,0,30,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "name": "Dagger (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14300" - }, - { - "shop_price": "90", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "destroy": "true", - "attack_speed": "3", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dagger (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14301", - "bonuses": "101,0,0,0,0,0,0,0,0,0,0,45,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "name": "Dagger (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14302" - }, - { - "shop_price": "120", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "destroy": "true", - "attack_speed": "3", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dagger (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14303", - "bonuses": "135,0,0,0,0,0,0,0,0,0,0,60,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "name": "Dagger (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14304" - }, - { - "shop_price": "150", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "destroy": "true", - "attack_speed": "3", - "weapon_interface": "5", - "absorb": "0,0,0", - "equipment_slot": "3", - "attack_anims": "400,400,401,400", - "destroy_message": "Drop", - "attack_audios": "2517,2517,2500,2517", - "name": "Dagger (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14305", - "bonuses": "168,0,0,0,0,0,0,0,0,0,0,75,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay transformed into a sharp dagger.", - "durability": null, - "name": "Dagger (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14306" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "10", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Warhammer (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14307", - "bonuses": "0,0,83,0,0,0,0,0,0,0,0,15,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "name": "Warhammer (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14308" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "10", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Warhammer (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14309", - "bonuses": "0,0,135,0,0,0,0,0,0,0,0,30,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "name": "Warhammer (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14310" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "10", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Warhammer (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14311", - "bonuses": "0,0,202,0,0,0,0,0,0,0,0,45,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "name": "Warhammer (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14312" - }, - { - "shop_price": "120", - "examine": "The Sacred Clay has transformed into a heavy warhammer.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "10", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Warhammer (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14313", - "bonuses": "0,0,270,0,0,0,0,0,0,0,0,60,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The Sacred Clay has transformed into a heavy warhammer.", - "durability": null, - "name": "Warhammer (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14314" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "destroy": "true", - "attack_speed": "6", - "weapon_interface": "10", - "absorb": "0,0,0", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Warhammer (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14315", - "bonuses": "0,0,338,0,0,0,0,0,0,0,0,75,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a heavy warhammer.", - "durability": null, - "name": "Warhammer (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14316" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Robe top (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14317", - "bonuses": "0,0,0,0,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Robe top (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14318" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Robe top (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14319", - "bonuses": "0,0,0,0,0,0,0,0,40,0,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "name": "Robe top (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14320" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Robe top (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14321", - "bonuses": "0,0,0,0,0,0,0,0,60,0,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "name": "Robe top (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14322" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Robe top (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14323", - "bonuses": "0,0,0,0,0,0,0,0,80,0,80,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "name": "Robe top (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14324" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Robe top (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14325", - "bonuses": "0,0,0,0,0,0,0,0,100,0,100,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a light, cloth-like substance.", - "durability": null, - "name": "Robe top (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14326" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Robe bottom (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14327", - "bonuses": "0,0,0,0,0,0,0,0,15,0,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Robe bottom (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14328" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Robe bottom (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14329", - "bonuses": "0,0,0,0,0,0,0,0,30,0,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Robe bottom (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14330" - }, - { - "shop_price": "90", - "examine": "The sacred clay transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Robe bottom (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14331", - "bonuses": "0,0,0,0,0,0,0,0,45,0,45,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay transformed into a light, cloth-like material.", - "durability": null, - "name": "Robe bottom (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14332" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Robe bottom (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14333", - "bonuses": "0,0,0,0,0,0,0,0,60,0,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Robe bottom (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14334" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Robe bottom (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14335", - "bonuses": "0,0,0,0,0,0,0,0,75,0,75,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Robe bottom (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14336" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Hat (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14337", - "bonuses": "0,0,0,0,0,0,0,0,10,0,10,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Hat (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14338" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Hat (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14339", - "bonuses": "0,0,0,0,0,0,0,0,20,0,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Hat (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14340" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Hat (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14341", - "bonuses": "0,0,0,0,0,0,0,0,30,0,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Hat (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14342" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Hat (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14343", - "bonuses": "0,0,0,0,0,0,0,0,40,0,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Hat (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14344" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Hat (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14345", - "bonuses": "0,0,0,0,0,0,0,0,50,0,50,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a light, cloth-like material.", - "durability": null, - "name": "Hat (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14346" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Platebody (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14347", - "bonuses": "0,0,0,-30,-10,20,20,20,-10,10,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Platebody (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14348" - }, - { - "shop_price": "60", - "examine": "The sacred clay transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Platebody (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14349", - "bonuses": "0,0,0,-30,-10,40,40,40,-10,20,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay transformed into a hard, metallic substance.", - "durability": null, - "name": "Platebody (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14350" - }, - { - "shop_price": "90", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Platebody (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14351", - "bonuses": "0,0,0,-30,-10,60,60,60,-10,30,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "name": "Platebody (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14352" - }, - { - "shop_price": "120", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Platebody (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14353", - "bonuses": "0,0,0,-30,-10,80,80,80,-10,40,80,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "name": "Platebody (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14354" - }, - { - "shop_price": "150", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Platebody (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14355", - "bonuses": "0,0,0,-30,-10,100,100,100,-10,50,100,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay top has transformed into a spiked, platemail body.", - "durability": null, - "name": "Platebody (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14356" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Platelegs (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14357", - "bonuses": "0,0,0,-30,-10,15,15,15,-10,7,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Platelegs (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14358" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Platelegs (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14359", - "bonuses": "0,0,0,-30,-10,30,30,30,-10,15,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Platelegs (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14360" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Platelegs (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14361", - "bonuses": "0,0,0,-30,-10,45,45,45,-10,23,45,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Platelegs (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14362" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Platelegs (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14363", - "bonuses": "0,0,0,-30,-10,60,60,60,-10,30,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Platelegs (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14364" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Platelegs (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14365", - "bonuses": "0,0,0,-30,-10,75,75,75,-10,37,75,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Platelegs (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14366" - }, - { - "remove_head": "true", - "shop_price": "30", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Helm (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14367", - "bonuses": "0,0,0,-30,-10,10,10,10,-10,5,10,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Helm (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14368" - }, - { - "remove_head": "true", - "shop_price": "60", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Helm (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14369", - "bonuses": "0,0,0,-30,-10,20,20,20,-10,10,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Helm (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14370" - }, - { - "remove_head": "true", - "shop_price": "90", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Helm (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14371", - "bonuses": "0,0,0,-30,-10,30,30,30,-10,15,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Helm (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14372" - }, - { - "remove_head": "true", - "shop_price": "120", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Helm (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14373", - "bonuses": "0,0,0,-30,-10,40,40,40,-10,20,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Helm (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14374" - }, - { - "remove_head": "true", - "shop_price": "150", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Helm (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14375", - "bonuses": "0,0,0,-30,-10,50,50,50,-10,25,50,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a hard, metallic substance.", - "durability": null, - "name": "Helm (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14376" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a light weight, magical stick.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Staff (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14377", - "bonuses": "0,0,0,55,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a light weight, magical stick.", - "durability": null, - "name": "Staff (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14378" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a light weight, magical stick.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Staff (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14379", - "bonuses": "0,0,0,90,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a light weight, magical stick.", - "durability": null, - "name": "Staff (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14380" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a lightweight, magical stick.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Staff (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14381", - "bonuses": "0,0,0,135,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a lightweight, magical stick.", - "durability": null, - "name": "Staff (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14382" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a lightweight, magical stick.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Staff (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14383", - "bonuses": "0,0,0,180,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a lightweight, magical stick.", - "durability": null, - "name": "Staff (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14384" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a lightweight, magical stick.", - "durability": null, - "destroy": "true", - "attack_speed": "5", - "weapon_interface": "1", - "absorb": "0,0,0", - "render_anim": "28", - "equipment_slot": "3", - "destroy_message": "Drop", - "name": "Staff (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14385", - "bonuses": "0,0,0,225,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a lightweight, magical stick.", - "durability": null, - "name": "Staff (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14386" - }, - { - "durability": null, - "name": "Cape", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14387", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "durability": null, - "name": "Cape", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14389", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", - "equipment_slot": "1" - }, - { - "shop_price": "30", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Leather body (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14391", - "bonuses": "0,0,0,0,0,10,10,10,10,20,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "name": "Leather body (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14392" - }, - { - "shop_price": "60", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Leather body (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14393", - "bonuses": "0,0,0,0,0,20,20,20,20,40,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "name": "Leather body (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14394" - }, - { - "shop_price": "90", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Leather body (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14395", - "bonuses": "0,0,0,0,0,30,30,30,30,60,60,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "name": "Leather body (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14396" - }, - { - "shop_price": "120", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Leather body (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14397", - "bonuses": "0,0,0,0,0,40,40,40,40,80,80,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "name": "Leather body (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14398" - }, - { - "shop_price": "150", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "4", - "destroy_message": "Drop", - "remove_sleeves": "true", - "name": "Leather body (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14399", - "bonuses": "0,0,0,0,0,50,50,50,50,100,100,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a flexible mesh.", - "durability": null, - "name": "Leather body (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14400" - }, - { - "shop_price": "30", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Chaps (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14401", - "bonuses": "0,0,0,0,0,7,7,7,0,15,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "name": "Chaps (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14402" - }, - { - "shop_price": "60", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Chaps (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14403", - "bonuses": "0,0,0,0,0,15,15,15,0,30,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "name": "Chaps (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14404" - }, - { - "shop_price": "90", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Chaps (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14405", - "bonuses": "0,0,0,0,0,23,23,23,0,45,45,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "name": "Chaps (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14406" - }, - { - "shop_price": "120", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Chaps (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14407", - "bonuses": "0,0,0,0,0,30,30,30,0,60,60,0,0,1,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "name": "Chaps (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14408" - }, - { - "shop_price": "150", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "7", - "destroy_message": "Drop", - "name": "Chaps (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14409", - "bonuses": "0,0,0,0,0,37,37,37,0,75,75,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay transformed into a flexible mesh.", - "durability": null, - "name": "Chaps (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14410" - }, - { - "remove_head": "true", - "shop_price": "30", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Coif (class 1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14411", - "bonuses": "0,0,0,0,0,5,5,5,0,10,10,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "name": "Coif (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14412" - }, - { - "remove_head": "true", - "shop_price": "60", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Coif (class 2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14413", - "bonuses": "0,0,0,0,0,10,10,10,0,20,20,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "name": "Coif (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14414" - }, - { - "remove_head": "true", - "shop_price": "90", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Coif (class 3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14415", - "bonuses": "0,0,0,0,0,15,15,15,0,30,30,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "name": "Coif (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14416" - }, - { - "remove_head": "true", - "shop_price": "120", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Coif (class 4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14417", - "bonuses": "0,0,0,0,0,20,20,20,0,40,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "name": "Coif (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14418" - }, - { - "remove_head": "true", - "shop_price": "150", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Coif (class 5)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14419", - "bonuses": "0,0,0,0,0,25,25,25,0,50,50,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "The sacred clay has transformed into a flexible, protective mesh.", - "durability": null, - "name": "Coif (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14420" - }, - { - "shop_price": "30", - "durability": null, - "name": "Clay deposit scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14421", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14422", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 1)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14423" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14424", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "60", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 2)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14425" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14426", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "90", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 3)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14427" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14428", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "120", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 4)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14429" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14430", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "150", - "examine": "This scroll will make your familiar deposit its items at your base.", - "durability": null, - "name": "Sacred clay pouch (class 5)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14431" - }, - { - "durability": null, - "name": "Null sacred clay", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14432", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "5", - "examine": "A vine flower grown through magical means.", - "durability": null, - "name": "Vine flower", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14458", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You caught this broav west of the Hunting Expert's home. You can catch another one with a trap baited with mort Myre Fungus.", - "examine": "Its unconscious, poor thing.", - "durability": null, - "name": "Unconscious broav", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14459", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got these clothes from a washerman who lives near the Khazard battle arena.", - "shop_price": "10", - "examine": "Some dirty clothes that apparently belong to Movario.", - "durability": null, - "name": "Dirty laundry", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14460", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "destroy_message": "You found this basket in Movario's base.", - "examine": "A receptacle for rubbish.", - "durability": null, - "name": "Waste-paper basket", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14461", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this key attached to the bottom of the bin in Movario's base.", - "examine": "A superbly made key with a fine ruby inserted into it. (While Guthix Sleeps)", - "durability": null, - "name": "Ruby key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14462", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found these notes in Movario's basement.", - "examine": "A collection of notes made by an absent-minded fellow.", - "durability": null, - "name": "Notes on pressure", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14463", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found these notes loosely piled up on ", - "examine": "A loose-leaf collection of research notes, found on Movario's study desk.", - "durability": null, - "name": "Movario's notes (volume 1)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14464", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found these notes in Movario's bedchest, in his base of operations near the Khazard Battlefield.", - "examine": "A loose-leaf collection of research notes, found in Movario's bed chest.", - "durability": null, - "name": "Movario's notes (volume 2)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14465", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A 1kg weight.", - "durability": null, - "name": "Weight (1kg)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14466", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A 2kg weight.", - "durability": null, - "name": "Weight (2kg)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14467", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "examine": "A 5kg weight.", - "durability": null, - "name": "Weight (5kg)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14468", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can find another under the bed on the top level of Movario's base", - "examine": "The loop half of a strange key.", - "durability": null, - "name": "Strange key loop", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14469", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You can find another under the bed on the top level of Movario's base", - "examine": "The teeth half of a strange key.", - "durability": null, - "name": "Strange key teeth", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14470", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You fused together two parts of a Dragonkin key which you obtained from Movario's base.", - "examine": "The completed dragonkin key.", - "durability": null, - "name": "Dragonkin key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14471", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "30000", - "examine": "A badly damaged lump of dragon metal.", - "durability": null, - "rare_item": "true", - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "955683", - "name": "Ruined dragon armour lump", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14472", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30000", - "examine": "A badly damaged lump of dragon metal.", - "grand_exchange_price": "955683", - "durability": null, - "name": "Ruined dragon armour lump", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14473" - }, - { - "shop_price": "30000", - "examine": "A badly damaged slice of dragon metal.", - "durability": null, - "rare_item": "true", - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "1761141", - "name": "Ruined dragon armour slice", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14474", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30000", - "examine": "A badly damaged slice of dragon metal.", - "grand_exchange_price": "1761141", - "durability": null, - "name": "Ruined dragon armour slice", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14475" - }, - { - "shop_price": "30000", - "examine": "A badly damaged shard of dragon metal.", - "durability": null, - "rare_item": "true", - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "1090493", - "name": "Ruined dragon armour shard", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14476", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "30000", - "examine": "A badly damaged shard of dragon metal.", - "grand_exchange_price": "1090493", - "durability": null, - "name": "Ruined dragon armour shard", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14477" - }, - { - "destroy_message": "Drop", - "examine": "A very powerful Smithing hammer.", - "durability": null, - "name": "Blast fusion hammer", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14478", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" - }, - { - "requirements": "{1,60}", - "shop_price": "1760000", - "examine": "Provides excellent protection.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,9", - "equipment_slot": "4", - "lendable": "true", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "4453643", - "name": "Dragon platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14479", - "bonuses": "0,0,0,-30,0,109,107,97,-6,106,50,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "1760000", - "examine": "Provides excellent protection.", - "grand_exchange_price": "4453643", - "durability": null, - "name": "Dragon platebody", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14480" - }, - { - "requirements": "{1,60}", - "examine": "Provides excellent protection.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "4,0,9", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "4453643", - "name": "Dragon platebody", - "archery_ticket_price": "0", - "id": "14481", - "bonuses": "0,0,0,-30,0,109,107,97,-6,106,50,0,0,0,0" - }, - { - "requirements": "{0,60}", - "shop_price": "67500", - "examine": "A set of fighting claws.", - "has_special": "true", - "rare_item": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "absorb": "0,0,0", - "equip_audio": "1003", - "defence_anim": "397", - "render_anim": "2583", - "equipment_slot": "3", - "attack_anims": "393,393,1067,393", - "destroy_message": "Drop", - "lendable": "true", - "grand_exchange_price": "1472441", - "tradeable": "true", - "name": "Dragon claws", - "archery_ticket_price": "0", - "id": "14484", - "bonuses": "41,57,-4,0,0,13,26,7,0,0,0,56,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "67500", - "examine": "A set of fighting claws.", - "grand_exchange_price": "1472441", - "durability": null, - "name": "Dragon claws", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "two_handed": "true", - "id": "14485" - }, - { - "requirements": "{0,60}", - "examine": "A set of fighting claws.", - "has_special": "true", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "two_handed": "true", - "weapon_interface": "9", - "absorb": "0,0,0", - "equip_audio": "1003", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "1472441", - "name": "Dragon claws", - "archery_ticket_price": "0", - "id": "14486", - "bonuses": "41,57,-4,0,0,13,26,7,0,0,0,56,0,0,0" - }, - { - "destroy_message": "You grew this herb by planting an enriched snapdragon seed in the special herb patch on top of Falador castle.", - "examine": "An enriched snapdragon herb.", - "durability": null, - "name": "Enriched snapdragon", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14487", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You made this serum by mixing an enriched snapdragon into one of Betty's truth serums.", - "examine": "Fluid sloshes innocently in this vial.", - "durability": null, - "name": "Super truth serum", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14488", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You gained this item by having papyrus and charcoal in your inventory while interrogating a spy in Falador castle.", - "examine": "A sketch of the suspect known as Dark Squall.", - "durability": null, - "name": "Suspect sketch", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14489", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "requirements": "{1,40}", - "shop_price": "65000", - "examine": "These look pretty heavy, but very elite.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "2,0,4", - "equipment_slot": "7", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "41559", - "name": "Elite black platelegs", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14490", - "bonuses": "0,0,0,-14,-6,52,50,25,-1,49,15,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "65000", - "examine": "These look pretty heavy, but very elite.", - "grand_exchange_price": "41559", - "durability": null, - "name": "Elite black platelegs", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14491" - }, - { - "requirements": "{1,40}", - "shop_price": "64000", - "examine": "Provides excellent protection, and is elite.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "3,0,6", - "equipment_slot": "4", - "lendable": "true", - "destroy_message": "Drop", - "remove_sleeves": "true", - "grand_exchange_price": "38275", - "name": "Elite black platebody", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14492", - "bonuses": "0,0,0,-20,-8,80,85,40,-2,80,40,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "64000", - "examine": "Provides excellent protection, and is elite.", - "grand_exchange_price": "38275", - "durability": null, - "name": "Elite black platebody", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14493" - }, - { - "remove_head": "true", - "requirements": "{1,40}", - "shop_price": "35200", - "examine": "A full face helmet, and elite.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "1,0,3", - "remove_beard": "true", - "equipment_slot": "0", - "lendable": "true", - "destroy_message": "Drop", - "grand_exchange_price": "30542", - "name": "Elite black full helm", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14494", - "bonuses": "0,0,0,-4,-2,31,33,15,0,30,7,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "35200", - "examine": "A full face helmet, and elite.", - "grand_exchange_price": "30542", - "durability": null, - "name": "Elite black full helm", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14495" - }, - { - "destroy_message": "You got this key from the key rack in Dark Squall's base.", - "examine": "Opens the cells beneath the Black Knights' Fortress. (While Guthix Sleeps)", - "durability": null, - "name": "Cell key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14496", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "120000", - "examine": "A robe worn by members of the Dagon'hai.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "3,1,0", - "equipment_slot": "4", - "remove_sleeves": "true", - "grand_exchange_price": "71098", - "name": "Dagon'hai robe top", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14497", - "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,2,0" - }, - { - "shop_price": "120000", - "examine": "A robe worn by members of the Dagon'hai.", - "grand_exchange_price": "71098", - "durability": null, - "name": "Dagon'hai robe top", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14498" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "15000", - "examine": "A hat worn by members of the Dagon'hai.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "1,0,0", - "equipment_slot": "0", - "grand_exchange_price": "9580", - "name": "Dagon'hai hat", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14499", - "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" - }, - { - "shop_price": "15000", - "examine": "A hat worn by members of the Dagon'hai.", - "grand_exchange_price": "9580", - "durability": null, - "name": "Dagon'hai hat", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14500" - }, - { - "requirements": "{1,20}-{6,40}", - "shop_price": "80000", - "examine": "A robe worn by members of the Dagon'hai.", - "durability": null, - "destroy": "false", - "attack_speed": "4", - "absorb": "2,1,0", - "equipment_slot": "7", - "grand_exchange_price": "45691", - "name": "Dagon'hai robe bottom", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14501", - "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,2,0" - }, - { - "shop_price": "80000", - "examine": "A robe worn by members of the Dagon'hai.", - "grand_exchange_price": "45691", - "durability": null, - "name": "Dagon'hai robe bottom", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14502" - }, - { - "shop_price": "1", - "examine": "Elite Black Knight armour adds to his stealthiness.", - "durability": null, - "name": "Silif", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14503", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "examine": "Elite Black Knight armour adds to his stealthiness.", - "durability": null, - "name": "Silif", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14504", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Teleorb", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14505", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "5" - }, - { - "destroy_message": "You created this by focusing the light onto a snapdragon seed from a rose tinted lens while in Betty's shop.", - "examine": "An enriched snapdragon seed. The herb that grows from this seed will be extra potent!", - "durability": null, - "name": "Enriched snapdragon seed", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14506", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14507", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14508", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14509", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14510", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14511", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14512", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14513", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", - "examine": "Part of a stone circle.", - "durability": null, - "name": "Dolmen", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14514", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an air-orb on an etched wall section.", - "examine": "An elemental key of air.", - "durability": null, - "name": "Air key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14515", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an earth-orb on an etched wall section.", - "examine": "An elemental key of earth.", - "durability": null, - "name": "Earth key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14516", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an", - "examine": "An elemental key of fire.", - "durability": null, - "name": "Fire key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14517", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an", - "examine": "An elemental key of water.", - "durability": null, - "name": "Water key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14518", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an air-orb on an etched wall section.", - "examine": "An elemental key of air.", - "durability": null, - "name": "Air key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14519", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an earth-orb on an etched wall section.", - "examine": "An elemental key of earth.", - "durability": null, - "name": "Earth key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14520", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an", - "examine": "An elemental key of fire.", - "durability": null, - "name": "Fire key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14521", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You found this in the Chasm of Tears by using an", - "examine": "An elemental key of water.", - "durability": null, - "name": "Water key", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14522", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "Grand Exchange set containing a hat, top and bottoms.", - "grand_exchange_price": "193541", - "durability": null, - "name": "Dagon'hai robes set", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14525", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "20", - "examine": "Grand Exchange set containing a hat, top and bottoms.", - "grand_exchange_price": "193541", - "durability": null, - "name": "Dagon'hai robes set", - "tradeable": "true", - "destroy": "false", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14526" - }, - { - "shop_price": "20", - "examine": "Grand Exchange set containing an elite black full helm, platebody and legs.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "6,0,13", - "destroy_message": "Drop", - "grand_exchange_price": "140536", - "name": "Elite black armour set", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14527", - "bonuses": "0,0,0,-38,-16,163,168,80,-3,159,62,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "20", - "examine": "Grand Exchange set containing an elite black full helm, platebody and legs.", - "grand_exchange_price": "140536", - "durability": null, - "name": "Elite black armour set", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14528" - }, - { - "shop_price": "20", - "examine": "Grand Exchange set containing a dragon full helm, platebody, legs.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "9,0,19", - "destroy_message": "Drop", - "grand_exchange_price": "10629814", - "name": "Dragon plate armour set (l)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14529", - "bonuses": "0,0,0,-57,-9,222,221,201,-11,217,82,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "20", - "examine": "Grand Exchange set containing a dragon full helm, platebody, legs.", - "grand_exchange_price": "10629814", - "durability": null, - "name": "Dragon plate armour set (l)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14530" - }, - { - "shop_price": "20", - "examine": "Grand Exchange set containing a dragon full helm, platebody, skirt.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "9,0,19", - "destroy_message": "Drop", - "grand_exchange_price": "12243786", - "name": "Dragon plate armour set (sk)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14531", - "bonuses": "0,0,0,-57,-9,222,221,201,-11,217,82,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "20", - "examine": "Grand Exchange set containing a dragon full helm, platebody, skirt.", - "grand_exchange_price": "12243786", - "durability": null, - "name": "Dragon plate armour set (sk)", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14532" - }, - { - "durability": null, - "name": "Broav", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14533", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "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.", - "durability": null, - "name": "Strange teleorb", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14534", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will not be able to get the book back if you destroy it.", - "examine": "Notes on the locations of turkeys.", - "durability": null, - "name": "Turkey book", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14536", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", - "durability": null, - "name": "Cornucopia", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14537", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", - "durability": null, - "name": "Cornucopia", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14538", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "9", - "durability": null, - "name": "Raw turkey", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14539", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "4", - "examine": "Mmm, this looks tasty.", - "durability": null, - "name": "Cooked turkey", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14540", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "durability": null, - "name": "Burnt turkey", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14541", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "9", - "examine": "I need to cook this first.", - "durability": null, - "name": "Raw turkey drumstick", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14542", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "4", - "examine": "Mmm, this looks tasty.", - "durability": null, - "name": "Cooked turkey drumstick", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14543", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1", - "durability": null, - "name": "Burnt turkey drumstick", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14544", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", - "durability": null, - "name": "Cornucopia", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14570", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "Not-so-sturdy boots for northern winters.", - "durability": null, - "name": "Fremennik sea boots 1", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14571", - "absorb": "0,0,0", - "bonuses": "0,0,0,-3,-1,2,3,4,0,0,0,0,0,0,0", - "equipment_slot": "10" - }, - { - "destroy_message": "You can claim replacement Fremennik sea boots from Yrsa in Rellekka.", - "examine": "Sturdy boots for northern winters.", - "durability": null, - "name": "Fremennik sea boots 2", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14572", - "absorb": "0,0,0", - "bonuses": "0,0,0,-3,-1,8,9,10,0,0,8,0,0,0,0", - "equipment_slot": "10" - }, - { - "examine": "Very sturdy boots for northern winters.", - "durability": null, - "name": "Fremennik sea boots 3", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14573", - "absorb": "0,0,0", - "bonuses": "0,0,0,-3,-1,10,11,12,0,0,9,1,0,0,0", - "equipment_slot": "10" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14574", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14575", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14576", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will be able to get a replacement shield from Redbeard the Pirate in Port Sarim.", - "shop_price": "100", - "examine": "A buckler shield from Falador.", - "durability": null, - "name": "Falador shield 1", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14577", - "absorb": "0,0,0", - "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,3,0,0", - "equipment_slot": "5" - }, - { - "destroy_message": "You will be able to get a replacement shield from the chemist in Rimmington.", - "shop_price": "200", - "examine": "A kiteshield from Falador.", - "durability": null, - "name": "Falador shield 2", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14578", - "absorb": "0,0,0", - "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,5,0,0", - "equipment_slot": "5" - }, - { - "destroy_message": "You will be able to get a replacement shield from Sir Vyvin's squire in the White Knights' Castle.", - "shop_price": "300", - "examine": "A tower shield from Falador.", - "durability": null, - "name": "Falador shield 3", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14579", - "absorb": "0,0,0", - "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,7,0,0", - "equipment_slot": "5" - }, - { + "render_anim": "1381", + "requirements": "{4,20}", "shop_price": "1000", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14580", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "weapon_interface": "18" }, { - "shop_price": "5000", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14581", + "id": "13954", + "name": "C. morrigan's javelin (p)", + "examine": "A vicious javelin.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "1381", + "requirements": "{4,20}", "shop_price": "10000", - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", + "weapon_interface": "18" + }, + { + "id": "13955", + "name": "C. morrigan's javelin (p+)", + "examine": "A vicious javelin.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14582", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Harvest (turns to ", - "examine": "A white lily seed - plant in a flower patch.", - "durability": null, - "name": "White lily", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14583", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will not be able to replace this voucher - it is a one-time offer only!", - "shop_price": "500000", - "examine": "I can take this to the Herald to get my money crest back for free.", - "durability": null, - "name": "Money crest voucher", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14584", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "1250", - "examine": "A white lily seed - plant in a flower patch.", - "durability": null, - "name": "White lily seed", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14589", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "1381", + "requirements": "{4,20}", + "shop_price": "10000", + "weapon_interface": "18" + }, + { + "id": "13956", + "name": "C. morrigan's javelin (p++)", + "examine": "A vicious javelin.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2244", + "equipment_slot": "3", + "render_anim": "1381", + "requirements": "{4,20}", + "shop_price": "10000", + "weapon_interface": "18" + }, + { + "id": "13957", + "name": "C. morrigan's throwing axe", + "examine": "A vicious throwing axe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,93,0,0,0,0,0,0,0,0,0,117", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "requirements": "{4,20}", "shop_price": "1000", - "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre(5)", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14590", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" + "weapon_interface": "18" }, { - "destroy_message": "Drop", - "shop_price": "1000", - "examine": "This will teleport me to Rellekka when I play it.", - "durability": null, - "name": "Enchanted lyre(6)", - "destroy": "true", + "id": "13958", + "name": "Corrupt dragon chainbody", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "4,0,9", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14591", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "3" + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{0,20}-{4,20}", + "shop_price": "120000" }, { - "lendable": "true", - "destroy_message": "Drop", - "examine": "These look pretty heavy, but very elite.", - "grand_exchange_price": "41559", - "durability": null, - "name": "Elite black platelegs", - "destroy": "true", + "id": "13959", + "name": "Corrupt dragon chainbody", + "examine": "This item degrades while worn, and will turn to dust.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14592", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120000", + "tradeable": "true" + }, + { + "id": "13960", + "name": "Corrupt dragon chainbody (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "72000" + }, + { + "id": "13961", + "name": "Corrupt dragon med helm", + "examine": "This item degrades while worn, and will turn to dust.", "absorb": "2,0,4", - "bonuses": "0,0,0,-14,-6,52,50,25,-1,49,15,0,0,0,0" - }, - { - "lendable": "true", - "destroy_message": "Drop", - "examine": "Provides excellent protection, and is elite.", - "grand_exchange_price": "38275", - "durability": null, - "name": "Elite black platebody", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14593", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "60000" + }, + { + "id": "13962", + "name": "Corrupt dragon med helm", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60000", + "tradeable": "true" + }, + { + "id": "13963", + "name": "Corrupt dragon med helm (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2240", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "36000" + }, + { + "id": "13964", + "name": "Corrupt dragon sq shield", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "5,0,11", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "shop_price": "120000" + }, + { + "id": "13965", + "name": "Corrupt dragon sq shield", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120000", + "tradeable": "true" + }, + { + "id": "13966", + "name": "Corrupt dragon sq shield (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "5,0,11", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "shop_price": "72000" + }, + { + "id": "13967", + "name": "Corrupt dragon plateskirt", + "examine": "This item degrades while worn, and will turn to dust.", "absorb": "3,0,6", - "bonuses": "0,0,0,-20,-8,80,85,40,-2,80,40,0,0,0,0" + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Destroy", + "durability": null, + "equipment_slot": "7", + "shop_price": "120000" }, { - "lendable": "true", + "id": "13968", + "name": "Corrupt dragon plateskirt", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Destroy", + "durability": null, + "shop_price": "120000", + "tradeable": "true" + }, + { + "id": "13969", + "name": "Corrupt dragon plateskirt (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Destroy", + "durability": null, + "equipment_slot": "7", + "shop_price": "72000" + }, + { + "id": "13970", + "name": "Corrupt dragon platelegs", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "destroy": "true", "destroy_message": "Drop", - "examine": "A full face helmet, and elite.", - "grand_exchange_price": "30542", "durability": null, - "name": "Elite black full helm", - "destroy": "true", + "equip_audio": "2242", + "equipment_slot": "7", + "shop_price": "120000" + }, + { + "id": "13971", + "name": "Corrupt dragon platelegs", + "examine": "This item degrades while worn, and will turn to dust.", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14594", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120000", + "tradeable": "true" + }, + { + "id": "13972", + "name": "Corrupt dragon platelegs (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "shop_price": "72000" + }, + { + "id": "13973", + "name": "Corrupt dragon battleaxe", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,70,65,0,0,0,0,0,-1,-1,0,85,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "render_anim": "2586", + "requirements": "{0,60}", + "shop_price": "120000", + "weapon_interface": "2", + "weight": "2.7" + }, + { + "id": "13974", + "name": "Corrupt dragon battleaxe", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "4", + "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "render_anim": "2586", + "requirements": "{0,60}", + "shop_price": "120000", + "tradeable": "true", + "weight": "2.7" + }, + { + "id": "13975", + "name": "C. dragon battleaxe (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "395,395,401,395", + "attack_audios": "2498,2498,2497,2498", + "attack_speed": "6", + "bonuses": "-2,70,65,0,0,0,0,0,-1,-1,0,85,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2232", + "equipment_slot": "3", + "render_anim": "2586", + "requirements": "{0,60}", + "shop_price": "72000", + "weapon_interface": "2", + "weight": "2.7" + }, + { + "id": "13976", + "name": "Corrupt dragon dagger", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "shop_price": "30000", + "weapon_interface": "5" + }, + { + "id": "13977", + "name": "Corrupt dragon dagger", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "13978", + "name": "C. dragon dagger (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "396,396,395,396", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "4", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "shop_price": "18000", + "weapon_interface": "5" + }, + { + "id": "13979", + "name": "Corrupt dragon scimitar", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1928", + "requirements": "{0,60}", + "shop_price": "100000", + "weapon_interface": "6", + "weight": "1.8" + }, + { + "id": "13980", + "name": "Corrupt dragon scimitar", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "shop_price": "100000", + "tradeable": "true" + }, + { + "id": "13981", + "name": "C. dragon scimitar (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1928", + "shop_price": "60000", + "weapon_interface": "6" + }, + { + "id": "13982", + "name": "Corrupt dragon longsword", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "58,69,-2,0,0,0,3,2,1,0,0,71,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "ge_buy_limit": "10", + "render_anim": "1582", + "requirements": "{0,60}", + "shop_price": "100000", + "weapon_interface": "5", + "weight": "1.8" + }, + { + "id": "13983", + "name": "Corrupt dragon longsword", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100000", + "tradeable": "true" + }, + { + "id": "13984", + "name": "C. dragon longsword (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "58,69,-2,0,0,0,3,2,1,0,0,71,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1582", + "shop_price": "60000", + "weapon_interface": "5" + }, + { + "id": "13985", + "name": "Corrupt dragon mace", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "40,-2,60,1,0,0,0,0,0,0,0,55,0,5,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "requirements": "{0,60}", + "shop_price": "50000", + "weapon_interface": "8", + "weight": "1.8" + }, + { + "id": "13986", + "name": "Corrupt dragon mace", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2508,2508,25092508", + "attack_speed": "4", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "requirements": "{0,60}", + "shop_price": "50000", + "tradeable": "true", + "weight": "1.8" + }, + { + "id": "13987", + "name": "Corrupt dragon mace (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2508,2508,25092508", + "attack_speed": "5", + "bonuses": "40,-2,60,1,0,0,0,0,0,0,0,55,0,5,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2246", + "equipment_slot": "3", + "requirements": "{0,60}", + "shop_price": "30000", + "weapon_interface": "8", + "weight": "1.8" + }, + { + "id": "13988", + "name": "Corrupt dragon spear", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "40000", + "two_handed": "true", + "weapon_interface": "14" + }, + { + "id": "13989", + "name": "Corrupt dragon spear", + "examine": "This item degrades while worn, and will turn to dust.", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "4", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "40000", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "13990", + "name": "Corrupt dragon spear (deg)", + "examine": "This item degrades while worn, and will turn to dust.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "2080,2081,2082,2080", + "attack_speed": "5", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "defence_anim": "2079", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "24000", + "two_handed": "true", + "weapon_interface": "14" + }, + { + "id": "14056", + "name": "Pvp worlds manual", + "examine": "A book about the Wilderness.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another copy by searching bookshelves around 2009Scape.", + "durability": null, + "shop_price": "5" + }, + { + "id": "14057", + "name": "Broomstick", + "examine": "A threat to dusty corners everywhere.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can obtain another by talking to Maggie the witch.", + "durability": null, + "equipment_slot": "3", + "render_anim": "1072", + "shop_price": "25", + "weapon_interface": "8" + }, + { + "id": "14058", + "name": "Goulash", + "examine": "What a curious and ghoulish smell!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you drop the goulash, it will be destroyed. You can get some more by dipping a bowl into Maggie's cauldron.", + "durability": null, + "equipment_slot": "3", + "shop_price": "2" + }, + { + "id": "14061", + "name": "Magic unguent", + "examine": "Purple and pungent.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another flask of magic unguent from the chest in Betty's basement.", + "durability": null, + "shop_price": "2" + }, + { + "id": "14062", + "name": "Broom ointment", + "examine": "To be used on brooms.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another flask of broom ointment from Hetty in Rimmington.", + "durability": null, + "shop_price": "2" + }, + { + "id": "14064", + "name": "Newt", + "examine": "A newt from Hetty's basement.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you release this newt, you can get another from the crate in Hetty's basement in Rimmington.", + "durability": null, + "equipment_slot": "3", + "shop_price": "5" + }, + { + "id": "14065", + "name": "Newt label", + "examine": "A label for a shipping crate.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another newt label from Gus in Hetty's basement in Rimmington.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14066", + "name": "Toad label", + "examine": "A label for a shipping crate.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another toad label from Gus in Hetty's basement in Rimmington.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14067", + "name": "Newts and toads label", + "examine": "A label for a shipping crate.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another newt-and-toad label from Gus in Hetty's basement in Rimmington.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14068", + "name": "Betty's wand", + "examine": "Warm to the touch.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can obtain another wand from the chest in Betty's basement.", + "durability": null, + "shop_price": "15" + }, + { + "id": "14069", + "name": "Magic slate", + "examine": "What a view!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you destroy this item, you can get another from Lottie in Betty's basement.", + "durability": null, + "shop_price": "2" + }, + { + "id": "14070", + "name": "Reptile", + "examine": "Desert dweller.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you release this creature, you will have to restart the puzzle in Betty's basement.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14071", + "name": "Blackbird", + "examine": "Bleak and beaky.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "If you release this creature, you will have to restart the puzzle in Betty's basement.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14072", + "name": "Bat", + "examine": "An annoying flappy thing.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14073", + "name": "Spider", + "examine": "It's an extremely small brown spider, probably very poisonous.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14074", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14075", + "name": "Snail", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14076", + "name": "Warlock top", + "examine": "The height of warlock fashion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another warlock top from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "15" + }, + { + "id": "14077", + "name": "Warlock legs", + "examine": "Tattered but trendy.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another set of warlock legs from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "7", + "shop_price": "15" + }, + { + "id": "14078", + "name": "Witch top", + "examine": "The height of witchly fashion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another witch top from Diango in Draynor.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "15" + }, + { + "id": "14079", + "name": "Witch skirt", + "examine": "Tattered but trendy.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another witch top from Diango in Draynor.", + "durability": null, + "equipment_slot": "7", + "shop_price": "15" + }, + { + "id": "14080", + "name": "Witch cloak", + "examine": "Ragged but rugged.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another witch cloak from Diango in Draynor.", + "durability": null, + "equipment_slot": "1", + "shop_price": "15" + }, + { + "id": "14081", + "name": "Warlock cloak", + "examine": "Ragged but rugged.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another warlock cloak from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "1", + "shop_price": "15" + }, + { + "id": "14082", + "name": "Popcorn ball", + "examine": "A sticky orb of popped corn.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" + }, + { + "id": "14083", + "name": "Chocolate drop", + "examine": "Chocolatey goodness.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" + }, + { + "id": "14084", + "name": "Wrapped candy", + "examine": "Sugary bliss.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" + }, + { + "id": "14085", + "name": "Armadyl communiqu?", + "examine": "An urgent communiqu?? revealing important information.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1" + }, + { + "id": "14086", + "name": "Witch top", + "examine": "The height of witchly fashion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another witch top from Diango in Draynor.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "15" + }, + { + "id": "14087", + "name": "Witch skirt", + "examine": "Tattered but trendy.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another witch top from Diango in Draynor.", + "durability": null, + "equipment_slot": "7", + "shop_price": "15" + }, + { + "id": "14088", + "name": "Witch cloak", + "examine": "Ragged but rugged.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another witch cloak from Diango in Draynor.", + "durability": null, + "equipment_slot": "1", + "shop_price": "15" + }, + { + "id": "14089", + "name": "Pet kitten", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14090", + "name": "Pet cat", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14091", + "name": "Lazy cat", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14092", + "name": "Overgrown cat", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14093", + "name": "Wily cat", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14094", + "name": "Sacred clay platebody", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "43333" + }, + { + "id": "14095", + "name": "Sacred clay platelegs", + "examine": "The sacred clay bottom has transformed into spiked, platemail legs.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "42667" + }, + { + "id": "14096", + "name": "Sacred clay helm", + "examine": "The sacred clay hat has transformed into a spined helm.", "absorb": "1,0,3", - "bonuses": "0,0,0,-4,-2,31,33,15,0,30,7,0,0,0,0" - }, - { - "destroy_message": "You can get another from Diango in Draynor Village.", - "remove_sleeves": "true", - "examine": "A red and jolly top.", - "durability": null, - "name": "Santa costume top", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "23467" + }, + { + "id": "14097", + "name": "Sacred clay scimitar", + "examine": "The sacred clay weapon has transformed into a sharp scimitar.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2248", + "equipment_slot": "3", + "render_anim": "1629", + "shop_price": "17066", + "weapon_interface": "5" + }, + { + "id": "14098", + "name": "Volatile clay tool", + "examine": "This can turn into a variety of tools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "21333" + }, + { + "id": "14099", + "name": "Volatile clay pickaxe", + "examine": "Your volatile tool wants to mine some rocks.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333", + "weapon_interface": "4" + }, + { + "id": "14100", + "name": "Volatile clay hatchet", + "examine": "Your volatile tool wants to cut some wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333", + "weapon_interface": "2" + }, + { + "id": "14101", + "name": "Volatile clay harpoon", + "examine": "Your volatile tool wants to spear some big fish.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333" + }, + { + "id": "14102", + "name": "Volatile clay butterfly net", + "examine": "Your volatile tool wants to catch some butterflies.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "21333", + "weapon_interface": "5" + }, + { + "id": "14103", + "name": "Volatile clay fletching knife", + "examine": "Your volatile tool wants to make some bows or arrows.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "3", + "shop_price": "21333" + }, + { + "id": "14104", + "name": "Volatile clay hammer", + "examine": "Your volatile tool wants to work metal or build furniture.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333" + }, + { + "id": "14105", + "name": "Volatile clay needle", + "examine": "Your volatile tool wants to make some leather armour.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "21333" + }, + { + "id": "14106", + "name": "Proto-tool", + "examine": "This can turn into a variety of tools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "21333" + }, + { + "id": "14107", + "name": "Sacred clay pickaxe", + "examine": "Your sacred clay tool has transformed into a pickaxe.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333", + "weapon_interface": "4" + }, + { + "id": "14108", + "name": "Sacred clay hatchet", + "examine": "Your sacred clay tool has transformed into a hatchet.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "-2,4,2,0,0,0,1,0,0,0,0,5,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333", + "weapon_interface": "2" + }, + { + "id": "14109", + "name": "Sacred clay harpoon", + "examine": "Your sacred clay tool has transformed into a harpoon.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "21333" + }, + { + "id": "14110", + "name": "Sacred clay butterfly net", + "examine": "Your sacred clay tool has transformed into a butterfly net.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "5", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "1", + "weapon_interface": "5" + }, + { + "id": "14111", + "name": "Sacred clay fletching knife", + "examine": "The sacred clay has transformed into a knife.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "21333" + }, + { + "id": "14112", + "name": "Sacred clay hammer", + "examine": "Your sacred clay tool has transformed into a hammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "21333" + }, + { + "id": "14113", + "name": "Sacred clay needle", + "examine": "The sacred clay has transformed into a needle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "21333" + }, + { + "id": "14114", + "name": "Sacred clay robe top", + "examine": "The sacred clay top has transformed into a heavy, magical robe.", + "absorb": "6,3,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "43333" + }, + { + "id": "14115", + "name": "Sacred clay robe bottom", + "examine": "The sacred clay bottom has transformed into a heavy, magical robe.", + "absorb": "4,2,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "42667" + }, + { + "id": "14116", + "name": "Sacred clay hat", + "examine": "The sacred clay hat has transformed into a wizard hat.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "23467" + }, + { + "id": "14117", + "name": "Sacred clay staff", + "examine": "The sacred clay weapon has transformed into a magical staff.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "17066", + "weapon_interface": "1" + }, + { + "id": "14118", + "name": "Sacred clay body", + "examine": "The sacred clay top has transformed into a leather body.", + "absorb": "0,6,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "43333" + }, + { + "id": "14119", + "name": "Sacred clay chaps", + "examine": "The sacred clay bottom has been transformed into a set of chaps.", + "absorb": "0,4,2", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "42667" + }, + { + "id": "14120", + "name": "Sacred clay coif", + "examine": "The sacred clay hat has transformed into a coif.", + "absorb": "0,3,1", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,5,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "23467" + }, + { + "id": "14121", + "name": "Sacred clay bow", + "examine": "The sacred clay weapon has transformed into a bow.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "17066", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "14122", + "name": "Pickaxe (class 1)", + "examine": "The sacred clay has become hard enough to chip stone.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "10,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "4" + }, + { + "id": "14123", + "name": "Pickaxe (class 1)", + "examine": "The sacred clay has become hard enough to chip stone.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14124", + "name": "Pickaxe (class 2)", + "examine": "The sacred clay has become hard enough to chip stone.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "15,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "4" + }, + { + "id": "14125", + "name": "Pickaxe (class 2)", + "examine": "The sacred clay has become hard enough to chip stone.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14126", + "name": "Pickaxe (class 3)", + "examine": "The sacred clay has become hard enough to chip stone.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "20,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "4" + }, + { + "id": "14127", + "name": "Pickaxe (class 3)", + "examine": "The sacred clay has become hard enough to chip stone.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14128", + "name": "Pickaxe (class 4)", + "examine": "The sacred clay has become hard enough to chip stone.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "25,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "4" + }, + { + "id": "14129", + "name": "Pickaxe (class 4)", + "examine": "The sacred clay has become hard enough to chip stone.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14130", + "name": "Pickaxe (class 5)", + "examine": "The sacred clay has become hard enough to chip stone.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "30,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "4" + }, + { + "id": "14131", + "name": "Pickaxe (class 5)", + "examine": "The sacred clay has become hard enough to chip stone.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14132", + "name": "Hatchet (class 1)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,10,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "2" + }, + { + "id": "14133", + "name": "Hatchet (class 1)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14134", + "name": "Hatchet (class 2)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,15,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "2" + }, + { + "id": "14135", + "name": "Hatchet (class 2)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14136", + "name": "Hatchet (class 3)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,20,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "2" + }, + { + "id": "14137", + "name": "Hatchet (class 3)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14138", + "name": "Hatchet (class 4)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,25,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "2" + }, + { + "id": "14139", + "name": "Hatchet (class 4)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14140", + "name": "Hatchet (class 5)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,30,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "2" + }, + { + "id": "14141", + "name": "Hatchet (class 5)", + "examine": "The sacred clay has become sharp enough to cut wood.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14142", + "name": "Harpoon (class 1)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "10,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14143", + "name": "Harpoon (class 1)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14144", + "name": "Harpoon (class 2)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "15,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14145", + "name": "Harpoon (class 2)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14146", + "name": "Harpoon (class 3)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "20,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14147", + "name": "Harpoon (class 3)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14148", + "name": "Harpoon (class 4)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "25,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14149", + "name": "Harpoon (class 4)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14150", + "name": "Harpoon (class 5)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "30,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14151", + "name": "Harpoon (class 5)", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14152", + "name": "Butterfly net (class 1)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "bonuses": "0,0,10,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "14" + }, + { + "id": "14153", + "name": "Butterfly net (class 1)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14154", + "name": "Butterfly net (class 2)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "bonuses": "0,0,15,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "14" + }, + { + "id": "14155", + "name": "Butterfly net (class 2)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14156", + "name": "Butterfly net (class 3)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "bonuses": "0,0,20,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "14" + }, + { + "id": "14157", + "name": "Butterfly net (class 3)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14158", + "name": "Butterfly net (class 4)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "bonuses": "0,0,25,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "14" + }, + { + "id": "14159", + "name": "Butterfly net (class 4)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14160", + "name": "Butterfly net (class 5)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "401,401,400,401", + "attack_speed": "4", + "bonuses": "0,0,30,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "403", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "158", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "14" + }, + { + "id": "14161", + "name": "Butterfly net (class 5)", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14162", + "name": "Food (class 1)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14163", + "name": "Food (class 1)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14164", + "name": "Food (class 2)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14165", + "name": "Food (class 2)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14166", + "name": "Food (class 3)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14167", + "name": "Food (class 3)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14168", + "name": "Food (class 4)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14169", + "name": "Food (class 4)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14170", + "name": "Food (class 5)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14171", + "name": "Food (class 5)", + "examine": "The sacred clay has transformed into something bland, but edible.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14172", + "name": "Barrier (class 1)", + "examine": "The clay has transformed into an expandable wall.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14173", + "name": "Barrier (class 1)", + "examine": "The clay has transformed into an expandable wall.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14174", + "name": "Barrier (class 2)", + "examine": "The clay has transformed into an expandable wall.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14175", + "name": "Barrier (class 2)", + "examine": "The clay has transformed into an expandable wall.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14176", + "name": "Barrier (class 3)", + "examine": "The clay has transformed into an expandable wall.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14177", + "name": "Barrier (class 3)", + "examine": "The clay has transformed into an expandable wall.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14178", + "name": "Barrier (class 4)", + "examine": "The clay has transformed into an expandable wall.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14179", + "name": "Barrier (class 4)", + "examine": "The clay has transformed into an expandable wall.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14180", + "name": "Barrier (class 5)", + "examine": "The clay has transformed into an expandable wall.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14181", + "name": "Barrier (class 5)", + "examine": "The clay has transformed into an expandable wall.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14182", + "name": "Sacred clay (class 1)", + "examine": "Very low quality sacred clay.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "14183", + "name": "Sacred clay (class 1)", + "examine": "Very low quality sacred clay.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "15", + "tradeable": "true" + }, + { + "id": "14184", + "name": "Sacred clay (class 2)", + "examine": "Low quality sacred clay.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14185", + "name": "Sacred clay (class 2)", + "examine": "Low quality sacred clay.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14186", + "name": "Sacred clay (class 3)", + "examine": "Medium quality sacred clay.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "45", + "tradeable": "true" + }, + { + "id": "14187", + "name": "Sacred clay (class 3)", + "examine": "Medium quality sacred clay.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "45", + "tradeable": "true" + }, + { + "id": "14188", + "name": "Sacred clay (class 4)", + "examine": "High quality sacred clay.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14189", + "name": "Sacred clay (class 4)", + "examine": "High quality sacred clay.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14190", + "name": "Sacred clay (class 5)", + "examine": "Very high quality sacred clay.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "75", + "tradeable": "true" + }, + { + "id": "14191", + "name": "Sacred clay (class 5)", + "examine": "Very high quality sacred clay.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "75", + "tradeable": "true" + }, + { + "id": "14192", + "name": "Bow (class 1)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,55,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "30", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "14193", + "name": "Bow (class 1)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "14194", + "name": "Bow (class 2)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "60", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "14195", + "name": "Bow (class 2)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "14196", + "name": "Bow (class 3)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,135,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "90", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "14197", + "name": "Bow (class 3)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "14198", + "name": "Bow (class 4)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,180,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "120", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "14199", + "name": "Bow (class 4)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "14200", + "name": "Bow (class 5)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,0,0,225,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "150", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "16" + }, + { + "id": "14201", + "name": "Bow (class 5)", + "examine": "The sacred clay has transformed into a wood-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "14202", + "name": "Arrows (class 1)", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,15", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "13", + "shop_price": "2", + "tradeable": "true" + }, + { + "id": "14203", + "name": "Arrows (class 2)", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "13", + "shop_price": "4", + "tradeable": "true" + }, + { + "id": "14204", + "name": "Arrows (class 3)", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,45", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "13", + "shop_price": "6", + "tradeable": "true" + }, + { + "id": "14205", + "name": "Arrows (class 4)", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "13", + "shop_price": "8", + "tradeable": "true" + }, + { + "id": "14206", + "name": "Arrows (class 5)", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "13", + "shop_price": "10", + "tradeable": "true" + }, + { + "id": "14207", + "name": "Prayer potion(5)", + "examine": "3 doses of Prayer restore potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14208", + "name": "Prayer potion(5)", + "examine": "3 doses of Prayer restore potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14209", + "name": "Prayer potion(4)", + "examine": "4 doses of Prayer restore potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14210", + "name": "Prayer potion(4)", + "examine": "4 doses of Prayer restore potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14211", + "name": "Prayer potion(3)", + "examine": "3 doses of Prayer restore potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14212", + "name": "Prayer potion(3)", + "examine": "3 doses of Prayer restore potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14213", + "name": "Prayer potion(2)", + "examine": "2 doses of Prayer restore potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14214", + "name": "Prayer potion(2)", + "examine": "2 doses of Prayer restore potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14215", + "name": "Prayer potion(1)", + "examine": "1 dose of Prayer restore potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14216", + "name": "Prayer potion(1)", + "examine": "1 dose of Prayer restore potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14217", + "name": "Energy potion (5)", + "examine": "4 doses of energy potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14218", + "name": "Energy potion (5)", + "examine": "4 doses of energy potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14219", + "name": "Energy potion (4)", + "examine": "4 doses of energy potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14220", + "name": "Energy potion (4)", + "examine": "4 doses of energy potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14221", + "name": "Energy potion (3)", + "examine": "3 doses of energy potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14222", + "name": "Energy potion (3)", + "examine": "3 doses of energy potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14223", + "name": "Energy potion (2)", + "examine": "2 doses of energy potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14224", + "name": "Energy potion (2)", + "examine": "2 doses of energy potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14225", + "name": "Energy potion (1)", + "examine": "1 dose of energy potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14226", + "name": "Energy potion (1)", + "examine": "1 dose of energy potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14227", + "name": "Super attack(5)", + "examine": "5 doses of super Attack potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14228", + "name": "Super attack(5)", + "examine": "5 doses of super Attack potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14229", + "name": "Super attack(4)", + "examine": "4 doses of super Attack potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14230", + "name": "Super attack(4)", + "examine": "4 doses of super Attack potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14231", + "name": "Super attack(3)", + "examine": "3 doses of super Attack potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14232", + "name": "Super attack(3)", + "examine": "3 doses of super Attack potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14233", + "name": "Super attack(2)", + "examine": "2 doses of super Attack potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14234", + "name": "Super attack(2)", + "examine": "2 doses of super Attack potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14235", + "name": "Super attack(1)", + "examine": "1 dose of super Attack potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14236", + "name": "Super attack(1)", + "examine": "1 dose of super Attack potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14237", + "name": "Super strength(5)", + "examine": "5 doses of super Strength potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14238", + "name": "Super strength(5)", + "examine": "5 doses of super Strength potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14239", + "name": "Super strength(4)", + "examine": "4 doses of super Strength potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14240", + "name": "Super strength(4)", + "examine": "4 doses of super Strength potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14241", + "name": "Super strength(3)", + "examine": "3 doses of super Strength potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14242", + "name": "Super strength(3)", + "examine": "3 doses of super Strength potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14243", + "name": "Super strength(2)", + "examine": "2 doses of super Strength potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14244", + "name": "Super strength(2)", + "examine": "2 doses of super Strength potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14245", + "name": "Super strength(1)", + "examine": "1 dose of super Strength potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14246", + "name": "Super strength(1)", + "examine": "1 dose of super Strength potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14247", + "name": "Ranging potion(5)", + "examine": "4 doses of ranging potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14248", + "name": "Ranging potion(5)", + "examine": "5 doses of ranging potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14249", + "name": "Ranging potion(4)", + "examine": "4 doses of ranging potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14250", + "name": "Ranging potion(4)", + "examine": "4 doses of ranging potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14251", + "name": "Ranging potion(3)", + "examine": "3 doses of ranging potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14252", + "name": "Ranging potion(3)", + "examine": "3 doses of ranging potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14253", + "name": "Ranging potion(2)", + "examine": "2 doses of ranging potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14254", + "name": "Ranging potion(2)", + "examine": "2 doses of ranging potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14255", + "name": "Ranging potion(1)", + "examine": "1 dose of ranging potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14256", + "name": "Ranging potion(1)", + "examine": "1 dose of ranging potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14257", + "name": "Defence potion(5)", + "examine": "3 doses of Defence Potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14258", + "name": "Defence potion(5)", + "examine": "3 doses of Defence Potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14259", + "name": "Defence potion(4)", + "examine": "4 doses of Defence Potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14260", + "name": "Defence potion(4)", + "examine": "4 doses of Defence Potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14261", + "name": "Defence potion(3)", + "examine": "3 doses of Defence Potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14262", + "name": "Defence potion(3)", + "examine": "3 doses of Defence Potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14263", + "name": "Defence potion(2)", + "examine": "2 doses of Defence Potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14264", + "name": "Defence potion(2)", + "examine": "2 doses of Defence Potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14265", + "name": "Defence potion(1)", + "examine": "1 dose of Defence Potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14266", + "name": "Defence potion(1)", + "examine": "1 dose of Defence Potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14267", + "name": "Magic potion(5)", + "examine": "4 doses of Magic potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14268", + "name": "Magic potion(5)", + "examine": "5 doses of Magic potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14269", + "name": "Magic potion(4)", + "examine": "4 doses of Magic potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14270", + "name": "Magic potion(4)", + "examine": "4 doses of Magic potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14271", + "name": "Magic potion(3)", + "examine": "3 doses of Magic potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14272", + "name": "Magic potion(3)", + "examine": "3 doses of Magic potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14273", + "name": "Magic potion(2)", + "examine": "2 doses of Magic potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14274", + "name": "Magic potion(2)", + "examine": "2 doses of Magic potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14275", + "name": "Magic potion(1)", + "examine": "1 dose of Magic potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14276", + "name": "Magic potion(1)", + "examine": "1 dose of Magic potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14277", + "name": "Summoning potion(5)", + "examine": "3 doses of Summoning potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14278", + "name": "Summoning potion(5)", + "examine": "3 doses of Summoning potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14279", + "name": "Summoning potion(4)", + "examine": "4 doses of Summoning potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14280", + "name": "Summoning potion(4)", + "examine": "4 doses of Summoning potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14281", + "name": "Summoning potion(3)", + "examine": "3 doses of Summoning potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14282", + "name": "Summoning potion(3)", + "examine": "3 doses of Summoning potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14283", + "name": "Summoning potion(2)", + "examine": "2 doses of Summoning potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14284", + "name": "Summoning potion(2)", + "examine": "2 doses of Summoning potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14285", + "name": "Summoning potion(1)", + "examine": "1 dose of Summoning potion.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14286", + "name": "Summoning potion(1)", + "examine": "1 dose of Summoning potion.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14287", + "name": "Scimitar (class 1)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "0,55,0,0,0,0,0,0,0,0,0,15,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "1629", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "6" + }, + { + "id": "14288", + "name": "Scimitar (class 1)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14289", + "name": "Scimitar (class 2)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "0,90,0,0,0,0,0,0,0,0,0,30,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "1629", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "6" + }, + { + "id": "14290", + "name": "Scimitar (class 2)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14291", + "name": "Scimitar (class 3)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "0,145,0,0,0,0,0,0,0,0,0,45,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "1629", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "6" + }, + { + "id": "14292", + "name": "Scimitar (class 3)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14293", + "name": "Scimitar (class 4)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "0,180,0,0,0,0,0,0,0,0,0,60,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "1629", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "6" + }, + { + "id": "14294", + "name": "Scimitar (class 4)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14295", + "name": "Scimitar (class 5)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", + "attack_speed": "4", + "bonuses": "0,225,0,0,0,0,0,0,0,0,0,75,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "1629", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "6" + }, + { + "id": "14296", + "name": "Scimitar (class 5)", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14297", + "name": "Dagger (class 1)", + "examine": "The sacred clay transformed into a sharp dagger.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "3", + "bonuses": "41,0,0,0,0,0,0,0,0,0,0,15,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14298", + "name": "Dagger (class 1)", + "examine": "The sacred clay transformed into a sharp dagger.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14299", + "name": "Dagger (class 2)", + "examine": "The sacred clay transformed into a sharp dagger.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "3", + "bonuses": "68,0,0,0,0,0,0,0,0,0,0,30,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14300", + "name": "Dagger (class 2)", + "examine": "The sacred clay transformed into a sharp dagger.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14301", + "name": "Dagger (class 3)", + "examine": "The sacred clay transformed into a sharp dagger.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "3", + "bonuses": "101,0,0,0,0,0,0,0,0,0,0,45,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14302", + "name": "Dagger (class 3)", + "examine": "The sacred clay transformed into a sharp dagger.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14303", + "name": "Dagger (class 4)", + "examine": "The sacred clay transformed into a sharp dagger.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "3", + "bonuses": "135,0,0,0,0,0,0,0,0,0,0,60,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14304", + "name": "Dagger (class 4)", + "examine": "The sacred clay transformed into a sharp dagger.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14305", + "name": "Dagger (class 5)", + "examine": "The sacred clay transformed into a sharp dagger.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "attack_speed": "3", + "bonuses": "168,0,0,0,0,0,0,0,0,0,0,75,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "5" + }, + { + "id": "14306", + "name": "Dagger (class 5)", + "examine": "The sacred clay transformed into a sharp dagger.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14307", + "name": "Warhammer (class 1)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,83,0,0,0,0,0,0,0,0,15,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "3", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "10" + }, + { + "id": "14308", + "name": "Warhammer (class 1)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14309", + "name": "Warhammer (class 2)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,135,0,0,0,0,0,0,0,0,30,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "10" + }, + { + "id": "14310", + "name": "Warhammer (class 2)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14311", + "name": "Warhammer (class 3)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,202,0,0,0,0,0,0,0,0,45,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "10" + }, + { + "id": "14312", + "name": "Warhammer (class 3)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14313", + "name": "Warhammer (class 4)", + "examine": "The Sacred Clay has transformed into a heavy warhammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,270,0,0,0,0,0,0,0,0,60,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "10" + }, + { + "id": "14314", + "name": "Warhammer (class 4)", + "examine": "The Sacred Clay has transformed into a heavy warhammer.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14315", + "name": "Warhammer (class 5)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "6", + "bonuses": "0,0,338,0,0,0,0,0,0,0,0,75,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "10" + }, + { + "id": "14316", + "name": "Warhammer (class 5)", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14317", + "name": "Robe top (class 1)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,20,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14318", + "name": "Robe top (class 1)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14319", + "name": "Robe top (class 2)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,40,0,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14320", + "name": "Robe top (class 2)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14321", + "name": "Robe top (class 3)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14322", + "name": "Robe top (class 3)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14323", + "name": "Robe top (class 4)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,80,0,80,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14324", + "name": "Robe top (class 4)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14325", + "name": "Robe top (class 5)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,100,0,100,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14326", + "name": "Robe top (class 5)", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14327", + "name": "Robe bottom (class 1)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,15,0,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14328", + "name": "Robe bottom (class 1)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14329", + "name": "Robe bottom (class 2)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,30,0,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14330", + "name": "Robe bottom (class 2)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14331", + "name": "Robe bottom (class 3)", + "examine": "The sacred clay transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,45,0,45,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14332", + "name": "Robe bottom (class 3)", + "examine": "The sacred clay transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14333", + "name": "Robe bottom (class 4)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14334", + "name": "Robe bottom (class 4)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14335", + "name": "Robe bottom (class 5)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,75,0,75,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14336", + "name": "Robe bottom (class 5)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14337", + "name": "Hat (class 1)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,10,0,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14338", + "name": "Hat (class 1)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14339", + "name": "Hat (class 2)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,20,0,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14340", + "name": "Hat (class 2)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14341", + "name": "Hat (class 3)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,30,0,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14342", + "name": "Hat (class 3)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14343", + "name": "Hat (class 4)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,40,0,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14344", + "name": "Hat (class 4)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14345", + "name": "Hat (class 5)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,50,0,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14346", + "name": "Hat (class 5)", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14347", + "name": "Platebody (class 1)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,20,20,20,-10,10,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14348", + "name": "Platebody (class 1)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14349", + "name": "Platebody (class 2)", + "examine": "The sacred clay transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,40,40,40,-10,20,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14350", + "name": "Platebody (class 2)", + "examine": "The sacred clay transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14351", + "name": "Platebody (class 3)", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,60,60,60,-10,30,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14352", + "name": "Platebody (class 3)", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14353", + "name": "Platebody (class 4)", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,80,80,80,-10,40,80,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14354", + "name": "Platebody (class 4)", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14355", + "name": "Platebody (class 5)", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,100,100,100,-10,50,100,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14356", + "name": "Platebody (class 5)", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14357", + "name": "Platelegs (class 1)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,15,15,15,-10,7,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14358", + "name": "Platelegs (class 1)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14359", + "name": "Platelegs (class 2)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,30,30,30,-10,15,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14360", + "name": "Platelegs (class 2)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14361", + "name": "Platelegs (class 3)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,45,45,45,-10,23,45,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14362", + "name": "Platelegs (class 3)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14363", + "name": "Platelegs (class 4)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,60,60,60,-10,30,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14364", + "name": "Platelegs (class 4)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14365", + "name": "Platelegs (class 5)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,75,75,75,-10,37,75,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14366", + "name": "Platelegs (class 5)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14367", + "name": "Helm (class 1)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,10,10,10,-10,5,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14368", + "name": "Helm (class 1)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14369", + "name": "Helm (class 2)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,20,20,20,-10,10,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14370", + "name": "Helm (class 2)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14371", + "name": "Helm (class 3)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,30,30,30,-10,15,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14372", + "name": "Helm (class 3)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14373", + "name": "Helm (class 4)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,40,40,40,-10,20,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14374", + "name": "Helm (class 4)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14375", + "name": "Helm (class 5)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,-10,50,50,50,-10,25,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14376", + "name": "Helm (class 5)", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14377", + "name": "Staff (class 1)", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,55,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "30", + "tradeable": "true", + "weapon_interface": "1" + }, + { + "id": "14378", + "name": "Staff (class 1)", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14379", + "name": "Staff (class 2)", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,90,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "60", + "tradeable": "true", + "weapon_interface": "1" + }, + { + "id": "14380", + "name": "Staff (class 2)", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14381", + "name": "Staff (class 3)", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,135,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "90", + "tradeable": "true", + "weapon_interface": "1" + }, + { + "id": "14382", + "name": "Staff (class 3)", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14383", + "name": "Staff (class 4)", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,180,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "120", + "tradeable": "true", + "weapon_interface": "1" + }, + { + "id": "14384", + "name": "Staff (class 4)", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14385", + "name": "Staff (class 5)", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "5", + "bonuses": "0,0,0,225,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "render_anim": "28", + "shop_price": "150", + "tradeable": "true", + "weapon_interface": "1" + }, + { + "id": "14386", + "name": "Staff (class 5)", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14387", + "name": "Cape", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1" + }, + { + "id": "14389", + "name": "Cape", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "durability": null, + "equipment_slot": "1" + }, + { + "id": "14391", + "name": "Leather body (class 1)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,10,10,20,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14392", + "name": "Leather body (class 1)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14393", + "name": "Leather body (class 2)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,20,40,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14394", + "name": "Leather body (class 2)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14395", + "name": "Leather body (class 3)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,30,30,30,60,60,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14396", + "name": "Leather body (class 3)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14397", + "name": "Leather body (class 4)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,40,40,40,40,80,80,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14398", + "name": "Leather body (class 4)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14399", + "name": "Leather body (class 5)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,50,50,50,100,100,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14400", + "name": "Leather body (class 5)", + "examine": "The sacred clay has transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14401", + "name": "Chaps (class 1)", + "examine": "The sacred clay transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,7,7,7,0,15,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14402", + "name": "Chaps (class 1)", + "examine": "The sacred clay transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14403", + "name": "Chaps (class 2)", + "examine": "The sacred clay transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,15,15,15,0,30,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14404", + "name": "Chaps (class 2)", + "examine": "The sacred clay transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14405", + "name": "Chaps (class 3)", + "examine": "The sacred clay transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,23,23,23,0,45,45,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14406", + "name": "Chaps (class 3)", + "examine": "The sacred clay transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14407", + "name": "Chaps (class 4)", + "examine": "The sacred clay transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,30,30,0,60,60,0,0,1,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14408", + "name": "Chaps (class 4)", + "examine": "The sacred clay transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14409", + "name": "Chaps (class 5)", + "examine": "The sacred clay transformed into a flexible mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,37,37,37,0,75,75,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "7", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14410", + "name": "Chaps (class 5)", + "examine": "The sacred clay transformed into a flexible mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14411", + "name": "Coif (class 1)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,5,0,10,10,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14412", + "name": "Coif (class 1)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14413", + "name": "Coif (class 2)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,10,0,20,20,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14414", + "name": "Coif (class 2)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14415", + "name": "Coif (class 3)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,15,15,15,0,30,30,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14416", + "name": "Coif (class 3)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14417", + "name": "Coif (class 4)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,40,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14418", + "name": "Coif (class 4)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14419", + "name": "Coif (class 5)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,25,25,25,0,50,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_head": "true", + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14420", + "name": "Coif (class 5)", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14421", + "name": "Clay deposit scroll", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14422", + "name": "Sacred clay pouch (class 1)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14422", + "name": "USDT Slot", + "examine": "You should not have this." + }, + { + "id": "14423", + "name": "Sacred clay pouch (class 1)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30", + "tradeable": "true" + }, + { + "id": "14424", + "name": "Sacred clay pouch (class 2)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14424", + "name": "HDT Slot", + "examine": "You should not have this." + }, + { + "id": "14425", + "name": "Sacred clay pouch (class 2)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "60", + "tradeable": "true" + }, + { + "id": "14426", + "name": "Sacred clay pouch (class 3)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14426", + "name": "GDT Slot", + "examine": "You should not have this." + }, + { + "id": "14427", + "name": "Sacred clay pouch (class 3)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "90", + "tradeable": "true" + }, + { + "id": "14428", + "name": "Sacred clay pouch (class 4)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14428", + "name": "RSDT Slot", + "examine": "You should not have this." + }, + { + "id": "14429", + "name": "Sacred clay pouch (class 4)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "120", + "tradeable": "true" + }, + { + "id": "14430", + "name": "Sacred clay pouch (class 5)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14430", + "name": "ASDT Slot", + "examine": "You should not have this." + }, + { + "id": "14431", + "name": "Sacred clay pouch (class 5)", + "examine": "This scroll will make your familiar deposit its items at your base.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "150", + "tradeable": "true" + }, + { + "id": "14432", + "name": "Null sacred clay", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14458", + "name": "Vine flower", + "examine": "A vine flower grown through magical means.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "5" + }, + { + "id": "14459", + "name": "Unconscious broav", + "examine": "Its unconscious, poor thing.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You caught this broav west of the Hunting Expert's home. You can catch another one with a trap baited with mort Myre Fungus.", + "durability": null + }, + { + "id": "14460", + "name": "Dirty laundry", + "examine": "Some dirty clothes that apparently belong to Movario.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got these clothes from a washerman who lives near the Khazard battle arena.", + "durability": null, + "equipment_slot": "3", + "shop_price": "10" + }, + { + "id": "14461", + "name": "Waste-paper basket", + "examine": "A receptacle for rubbish.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this basket in Movario's base.", + "durability": null + }, + { + "id": "14462", + "name": "Ruby key", + "examine": "A superbly made key with a fine ruby inserted into it. (While Guthix Sleeps)", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this key attached to the bottom of the bin in Movario's base.", + "durability": null + }, + { + "id": "14463", + "name": "Notes on pressure", + "examine": "A collection of notes made by an absent-minded fellow.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found these notes in Movario's basement.", + "durability": null + }, + { + "id": "14464", + "name": "Movario's notes (volume 1)", + "examine": "A loose-leaf collection of research notes, found on Movario's study desk.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found these notes loosely piled up on ", + "durability": null + }, + { + "id": "14465", + "name": "Movario's notes (volume 2)", + "examine": "A loose-leaf collection of research notes, found in Movario's bed chest.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found these notes in Movario's bedchest, in his base of operations near the Khazard Battlefield.", + "durability": null + }, + { + "id": "14466", + "name": "Weight (1kg)", + "examine": "A 1kg weight.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "14467", + "name": "Weight (2kg)", + "examine": "A 2kg weight.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "14468", + "name": "Weight (5kg)", + "examine": "A 5kg weight.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null + }, + { + "id": "14469", + "name": "Strange key loop", + "examine": "The loop half of a strange key.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can find another under the bed on the top level of Movario's base", + "durability": null + }, + { + "id": "14470", + "name": "Strange key teeth", + "examine": "The teeth half of a strange key.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can find another under the bed on the top level of Movario's base", + "durability": null + }, + { + "id": "14471", + "name": "Dragonkin key", + "examine": "The completed dragonkin key.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You fused together two parts of a Dragonkin key which you obtained from Movario's base.", + "durability": null + }, + { + "id": "14472", + "name": "Ruined dragon armour lump", + "examine": "A badly damaged lump of dragon metal.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "14473", + "name": "Ruined dragon armour lump", + "examine": "A badly damaged lump of dragon metal.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "14474", + "name": "Ruined dragon armour slice", + "examine": "A badly damaged slice of dragon metal.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "14475", + "name": "Ruined dragon armour slice", + "examine": "A badly damaged slice of dragon metal.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "14476", + "name": "Ruined dragon armour shard", + "examine": "A badly damaged shard of dragon metal.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "rare_item": "true", + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "14477", + "name": "Ruined dragon armour shard", + "examine": "A badly damaged shard of dragon metal.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "30000", + "tradeable": "true" + }, + { + "id": "14478", + "name": "Blast fusion hammer", + "examine": "A very powerful Smithing hammer.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3" + }, + { + "id": "14479", + "name": "Dragon platebody", + "examine": "Provides excellent protection.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,0,109,107,97,-6,106,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,60}", + "shop_price": "1760000", + "tradeable": "true" + }, + { + "id": "14480", + "name": "Dragon platebody", + "examine": "Provides excellent protection.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "1760000", + "tradeable": "true" + }, + { + "id": "14481", + "name": "Dragon platebody", + "examine": "Provides excellent protection.", + "absorb": "4,0,9", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-30,0,109,107,97,-6,106,50,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "", + "lendable": "true", + "requirements": "{1,60}" + }, + { + "id": "14484", + "name": "Dragon claws", + "examine": "A set of fighting claws.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "393,393,1067,393", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "41,57,-4,0,0,13,26,7,0,0,0,56,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "1003", + "equipment_slot": "3", + "has_special": "true", + "lendable": "true", + "rare_item": "true", + "render_anim": "2583", + "requirements": "{0,60}", + "shop_price": "67500", + "tradeable": "true", + "two_handed": "true", + "weapon_interface": "9" + }, + { + "id": "14485", + "name": "Dragon claws", + "examine": "A set of fighting claws.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "67500", + "tradeable": "true", + "two_handed": "true" + }, + { + "id": "14486", + "name": "Dragon claws", + "examine": "A set of fighting claws.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_audios": "2548,2548,2548,2548", + "attack_speed": "4", + "bonuses": "41,57,-4,0,0,13,26,7,0,0,0,56,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "1003", + "has_special": "true", + "lendable": "true", + "requirements": "{0,60}", + "two_handed": "true", + "weapon_interface": "9" + }, + { + "id": "14487", + "name": "Enriched snapdragon", + "examine": "An enriched snapdragon herb.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You grew this herb by planting an enriched snapdragon seed in the special herb patch on top of Falador castle.", + "durability": null + }, + { + "id": "14488", + "name": "Super truth serum", + "examine": "Fluid sloshes innocently in this vial.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You made this serum by mixing an enriched snapdragon into one of Betty's truth serums.", + "durability": null + }, + { + "id": "14489", + "name": "Suspect sketch", + "examine": "A sketch of the suspect known as Dark Squall.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You gained this item by having papyrus and charcoal in your inventory while interrogating a spy in Falador castle.", + "durability": null + }, + { + "id": "14490", + "name": "Elite black platelegs", + "examine": "These look pretty heavy, but very elite.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-14,-6,52,50,25,-1,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "requirements": "{1,40}", + "shop_price": "65000", + "tradeable": "true" + }, + { + "id": "14491", + "name": "Elite black platelegs", + "examine": "These look pretty heavy, but very elite.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "65000", + "tradeable": "true" + }, + { + "id": "14492", + "name": "Elite black platebody", + "examine": "Provides excellent protection, and is elite.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-20,-8,80,85,40,-2,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "requirements": "{1,40}", + "shop_price": "64000", + "tradeable": "true" + }, + { + "id": "14493", + "name": "Elite black platebody", + "examine": "Provides excellent protection, and is elite.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "64000", + "tradeable": "true" + }, + { + "id": "14494", + "name": "Elite black full helm", + "examine": "A full face helmet, and elite.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-4,-2,31,33,15,0,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "lendable": "true", + "remove_beard": "true", + "remove_head": "true", + "requirements": "{1,40}", + "shop_price": "35200", + "tradeable": "true" + }, + { + "id": "14495", + "name": "Elite black full helm", + "examine": "A full face helmet, and elite.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "35200", + "tradeable": "true" + }, + { + "id": "14496", + "name": "Cell key", + "examine": "Opens the cells beneath the Black Knights' Fortress. (While Guthix Sleeps)", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this key from the key rack in Dark Squall's base.", + "durability": null + }, + { + "id": "14497", + "name": "Dagon'hai robe top", + "examine": "A robe worn by members of the Dagon'hai.", + "absorb": "3,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,2,0,0", + "destroy": "false", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true", + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "tradeable": "true" + }, + { + "id": "14498", + "name": "Dagon'hai robe top", + "examine": "A robe worn by members of the Dagon'hai.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "durability": null, + "shop_price": "120000", + "tradeable": "true" + }, + { + "id": "14499", + "name": "Dagon'hai hat", + "examine": "A hat worn by members of the Dagon'hai.", + "absorb": "1,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "destroy": "false", + "durability": null, + "equipment_slot": "0", + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "tradeable": "true" + }, + { + "id": "14500", + "name": "Dagon'hai hat", + "examine": "A hat worn by members of the Dagon'hai.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "durability": null, + "shop_price": "15000", + "tradeable": "true" + }, + { + "id": "14501", + "name": "Dagon'hai robe bottom", + "examine": "A robe worn by members of the Dagon'hai.", + "absorb": "2,1,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,2,0,0", + "destroy": "false", + "durability": null, + "equipment_slot": "7", + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "tradeable": "true" + }, + { + "id": "14502", + "name": "Dagon'hai robe bottom", + "examine": "A robe worn by members of the Dagon'hai.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "durability": null, + "shop_price": "80000", + "tradeable": "true" + }, + { + "id": "14503", + "name": "Silif", + "examine": "Elite Black Knight armour adds to his stealthiness.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14504", + "name": "Silif", + "examine": "Elite Black Knight armour adds to his stealthiness.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14505", + "name": "Teleorb", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "equipment_slot": "5" + }, + { + "id": "14506", + "name": "Enriched snapdragon seed", + "examine": "An enriched snapdragon seed. The herb that grows from this seed will be extra potent!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You created this by focusing the light onto a snapdragon seed from a rose tinted lens while in Betty's shop.", + "durability": null + }, + { + "id": "14507", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14508", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14509", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14510", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14511", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14512", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14513", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14514", + "name": "Dolmen", + "examine": "Part of a stone circle.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "durability": null + }, + { + "id": "14515", + "name": "Air key", + "examine": "An elemental key of air.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an air-orb on an etched wall section.", + "durability": null + }, + { + "id": "14516", + "name": "Earth key", + "examine": "An elemental key of earth.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an earth-orb on an etched wall section.", + "durability": null + }, + { + "id": "14517", + "name": "Fire key", + "examine": "An elemental key of fire.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an", + "durability": null + }, + { + "id": "14518", + "name": "Water key", + "examine": "An elemental key of water.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an", + "durability": null + }, + { + "id": "14519", + "name": "Air key", + "examine": "An elemental key of air.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an air-orb on an etched wall section.", + "durability": null + }, + { + "id": "14520", + "name": "Earth key", + "examine": "An elemental key of earth.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an earth-orb on an etched wall section.", + "durability": null + }, + { + "id": "14521", + "name": "Fire key", + "examine": "An elemental key of fire.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an", + "durability": null + }, + { + "id": "14522", + "name": "Water key", + "examine": "An elemental key of water.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You found this in the Chasm of Tears by using an", + "durability": null + }, + { + "id": "14525", + "name": "Dagon'hai robes set", + "examine": "Grand Exchange set containing a hat, top and bottoms.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "false", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14526", + "name": "Dagon'hai robes set", + "examine": "Grand Exchange set containing a hat, top and bottoms.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "false", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14527", + "name": "Elite black armour set", + "examine": "Grand Exchange set containing an elite black full helm, platebody and legs.", + "absorb": "6,0,13", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-38,-16,163,168,80,-3,159,62,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14528", + "name": "Elite black armour set", + "examine": "Grand Exchange set containing an elite black full helm, platebody and legs.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14529", + "name": "Dragon plate armour set (l)", + "examine": "Grand Exchange set containing a dragon full helm, platebody, legs.", + "absorb": "9,0,19", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-57,-9,222,221,201,-11,217,82,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14530", + "name": "Dragon plate armour set (l)", + "examine": "Grand Exchange set containing a dragon full helm, platebody, legs.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14531", + "name": "Dragon plate armour set (sk)", + "examine": "Grand Exchange set containing a dragon full helm, platebody, skirt.", + "absorb": "9,0,19", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-57,-9,222,221,201,-11,217,82,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14532", + "name": "Dragon plate armour set (sk)", + "examine": "Grand Exchange set containing a dragon full helm, platebody, skirt.", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "20", + "tradeable": "true" + }, + { + "id": "14533", + "name": "Broav", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14534", + "name": "Strange teleorb", + "examine": "This orb can used to teleport people...somehow.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You gained this orb from Dark Squall's base. You can probably get another one from visiting the same place.", + "durability": null + }, + { + "id": "14536", + "name": "Turkey book", + "examine": "Notes on the locations of turkeys.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will not be able to get the book back if you destroy it.", + "durability": null + }, + { + "id": "14537", + "name": "Cornucopia", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", + "durability": null + }, + { + "id": "14538", + "name": "Cornucopia", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", + "durability": null + }, + { + "id": "14539", + "name": "Raw turkey", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "9" + }, + { + "id": "14540", + "name": "Cooked turkey", + "examine": "Mmm, this looks tasty.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "4" + }, + { + "id": "14541", + "name": "Burnt turkey", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14542", + "name": "Raw turkey drumstick", + "examine": "I need to cook this first.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "9" + }, + { + "id": "14543", + "name": "Cooked turkey drumstick", + "examine": "Mmm, this looks tasty.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "4" + }, + { + "id": "14544", + "name": "Burnt turkey drumstick", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1" + }, + { + "id": "14570", + "name": "Cornucopia", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", + "durability": null + }, + { + "id": "14571", + "name": "Fremennik sea boots 1", + "examine": "Not-so-sturdy boots for northern winters.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,2,3,4,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "id": "14572", + "name": "Fremennik sea boots 2", + "examine": "Sturdy boots for northern winters.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,8,9,10,0,0,8,0,0,0,0", + "destroy": "true", + "destroy_message": "You can claim replacement Fremennik sea boots from Yrsa in Rellekka.", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "id": "14573", + "name": "Fremennik sea boots 3", + "examine": "Very sturdy boots for northern winters.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-3,-1,10,11,12,0,0,9,1,0,0,0", + "destroy": "true", + "durability": null, + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "id": "14574", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "14575", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "14576", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "14577", + "name": "Falador shield 1", + "examine": "A buckler shield from Falador.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,3,0,0", + "destroy": "true", + "destroy_message": "You will be able to get a replacement shield from Redbeard the Pirate in Port Sarim.", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "shop_price": "100" + }, + { + "id": "14578", + "name": "Falador shield 2", + "examine": "A kiteshield from Falador.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,5,0,0", + "destroy": "true", + "destroy_message": "You will be able to get a replacement shield from the chemist in Rimmington.", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "shop_price": "200" + }, + { + "id": "14579", + "name": "Falador shield 3", + "examine": "A tower shield from Falador.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,7,0,0", + "destroy": "true", + "destroy_message": "You will be able to get a replacement shield from Sir Vyvin's squire in the White Knights' Castle.", + "durability": null, + "equip_audio": "2245", + "equipment_slot": "5", + "shop_price": "300" + }, + { + "id": "14580", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "shop_price": "1000", + "tradeable": "false" + }, + { + "id": "14581", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "shop_price": "5000", + "tradeable": "false" + }, + { + "id": "14582", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "shop_price": "10000", + "tradeable": "false" + }, + { + "id": "14583", + "name": "White lily", + "examine": "A white lily seed - plant in a flower patch.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Harvest (turns to ", + "durability": null + }, + { + "id": "14584", + "name": "Money crest voucher", + "examine": "I can take this to the Herald to get my money crest back for free.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will not be able to replace this voucher - it is a one-time offer only!", + "durability": null, + "shop_price": "500000" + }, + { + "id": "14589", + "name": "White lily seed", + "examine": "A white lily seed - plant in a flower patch.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "shop_price": "1250" + }, + { + "id": "14590", + "name": "Enchanted lyre(5)", + "examine": "This will teleport me to Rellekka when I play it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "1000" + }, + { + "id": "14591", + "name": "Enchanted lyre(6)", + "examine": "This will teleport me to Rellekka when I play it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "3", + "shop_price": "1000" + }, + { + "id": "14592", + "name": "Elite black platelegs", + "examine": "These look pretty heavy, but very elite.", + "absorb": "2,0,4", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-14,-6,52,50,25,-1,49,15,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "14593", + "name": "Elite black platebody", + "examine": "Provides excellent protection, and is elite.", + "absorb": "3,0,6", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-20,-8,80,85,40,-2,80,40,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { + "id": "14594", + "name": "Elite black full helm", + "examine": "A full face helmet, and elite.", + "absorb": "1,0,3", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,-4,-2,31,33,15,0,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "lendable": "true" + }, + { "id": "14595", + "name": "Santa costume top", + "examine": "A red and jolly top.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "examine": "A spikey amulet made of ice crystals. It has been enchanted so it will not melt.", - "durability": null, - "name": "Ice amulet", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" + }, + { "id": "14596", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "2" - }, - { - "destroy_message": "You can probably get more in the last room of the yeti cave, in the Land of Snow.", - "shop_price": "1", - "durability": null, - "name": "Stones", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14597", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You will have to fetch more in the last room of the yeti cave, then get them enchanted by snow imps.", - "shop_price": "1", - "examine": "According to the snow imps, this is enchanted, frozen yeti dung.", - "durability": null, - "name": "Enchanted stones", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14598", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A spikey amulet made of ice crystals. It has been enchanted so it will not melt.", - "durability": null, "name": "Ice amulet", - "destroy": "true", + "examine": "A spikey amulet made of ice crystals. It has been enchanted so it will not melt.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14599", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, "equipment_slot": "2" }, { - "destroy_message": "You can get another from Diango in Draynor Village.", - "remove_sleeves": "true", - "examine": "A red and jolly top.", - "durability": null, - "name": "Santa costume top", - "destroy": "true", + "id": "14597", + "name": "Stones", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can probably get more in the last room of the yeti cave, in the Land of Snow.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14598", + "name": "Enchanted stones", + "examine": "According to the snow imps, this is enchanted, frozen yeti dung.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You will have to fetch more in the last room of the yeti cave, then get them enchanted by snow imps.", + "durability": null, + "shop_price": "1" + }, + { + "id": "14599", + "name": "Ice amulet", + "examine": "A spikey amulet made of ice crystals. It has been enchanted so it will not melt.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "2" + }, + { "id": "14600", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" - }, - { - "destroy_message": "You can get another from Diango in Draynor Village.", - "remove_sleeves": "true", - "examine": "A red and jolly top.", - "durability": null, "name": "Santa costume top", - "destroy": "true", + "examine": "A red and jolly top.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14601", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "4" + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" }, { - "destroy_message": "You can get another pair from Diango in Draynor Village.", - "examine": "Some black and jolly gloves.", - "durability": null, - "name": "Santa costume gloves", - "destroy": "true", + "id": "14601", + "name": "Santa costume top", + "examine": "A red and jolly top.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14602", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "4", + "remove_sleeves": "true" + }, + { + "id": "14602", + "name": "Santa costume gloves", + "examine": "Some black and jolly gloves.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another pair from Diango in Draynor Village.", + "durability": null, "equipment_slot": "9" }, { - "destroy_message": "You can get another from Diango in Draynor Village.", - "examine": "Some red and jolly legs.", - "durability": null, - "name": "Santa costume legs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "14603", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "7" - }, - { - "destroy_message": "You can get another from Diango in Draynor Village.", - "examine": "Some red and jolly legs.", - "durability": null, "name": "Santa costume legs", - "destroy": "true", + "examine": "Some red and jolly legs.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14604", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, "equipment_slot": "7" }, { - "destroy_message": "You can get another pair from Diango in Draynor Village.", - "examine": "Some black and jolly boots.", - "durability": null, - "name": "Santa costume boots", - "destroy": "true", + "id": "14604", + "name": "Santa costume legs", + "examine": "Some red and jolly legs.", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14605", - "absorb": "0,0,0", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another from Diango in Draynor Village.", + "durability": null, + "equipment_slot": "7" + }, + { + "id": "14605", + "name": "Santa costume boots", + "examine": "Some black and jolly boots.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another pair from Diango in Draynor Village.", + "durability": null, "equipment_slot": "10" }, { - "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Aromatic twigs from a cinnamon tree.", - "durability": null, - "name": "Cinnamon twigs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "14606", + "name": "Cinnamon twigs", + "examine": "Aromatic twigs from a cinnamon tree.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Aromatic twigs from a sassafras tree.", - "durability": null, - "name": "Sassafras twigs", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14607", + "name": "Sassafras twigs", + "examine": "Aromatic twigs from a sassafras tree.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Aromatic twigs from a ailanthus tree.", - "durability": null, - "name": "Ailanthus twigs", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14608", + "name": "Ailanthus twigs", + "examine": "Aromatic twigs from a ailanthus tree.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Aromatic twigs from a cedar tree.", - "durability": null, - "name": "Cedar twigs", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14609", + "name": "Cedar twigs", + "examine": "Aromatic twigs from a cedar tree.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Aromatic twigs from a mastic tree.", - "durability": null, - "name": "Mastic twigs", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", + "durability": null + }, + { "id": "14610", + "name": "Mastic twigs", + "examine": "Aromatic twigs from a mastic tree.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Cinnamon twigs, fletched into ribbons of wood and ready to be woven.", - "durability": null, - "name": "Cinnamon weaving ribbon", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14611", + "name": "Cinnamon weaving ribbon", + "examine": "Cinnamon twigs, fletched into ribbons of wood and ready to be woven.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Sassafras twigs, fletched into ribbons of wood and ready to be woven.", - "durability": null, - "name": "Sassafras weaving ribbon", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14612", + "name": "Sassafras weaving ribbon", + "examine": "Sassafras twigs, fletched into ribbons of wood and ready to be woven.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Ailanthus twigs, fletched into ribbons of wood and ready to be woven.", - "durability": null, - "name": "Ailanthus weaving ribbon", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14613", + "name": "Ailanthus weaving ribbon", + "examine": "Ailanthus twigs, fletched into ribbons of wood and ready to be woven.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Cedar twigs, fletched into ribbons of wood and ready to be woven.", - "durability": null, - "name": "Cedar weaving ribbon", - "destroy": "true", "archery_ticket_price": "0", "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "durability": null + }, + { "id": "14614", + "name": "Cedar weaving ribbon", + "examine": "Cedar twigs, fletched into ribbons of wood and ready to be woven.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", - "examine": "Mastic twigs, fletched into ribbons of wood and ready to be woven.", - "durability": null, - "name": "Mastic weaving ribbon", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", + "durability": null + }, + { "id": "14615", + "name": "Mastic weaving ribbon", + "examine": "Mastic twigs, fletched into ribbons of wood and ready to be woven.", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "durability": null }, { - "shop_price": "100", - "examine": "A feather from a phoenix. Used in Summoning (72).", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "destroy_message": "Drop", - "grand_exchange_price": "3431", - "name": "Phoenix quill", - "tradeable": "true", - "archery_ticket_price": "0", "id": "14616", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Drop", - "shop_price": "100", - "examine": "A feather from a phoenix. Used in Summoning (72).", - "grand_exchange_price": "3431", - "durability": null, "name": "Phoenix quill", - "tradeable": "true", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14617" - }, - { - "durability": null, - "name": "Pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14620", + "examine": "A feather from a phoenix. Used in Summoning (72).", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "durability": null, - "name": "Pouch", - "tradeable": "true", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14621" + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100", + "tradeable": "true" }, { + "id": "14617", + "name": "Phoenix quill", + "examine": "A feather from a phoenix. Used in Summoning (72).", + "archery_ticket_price": "0", + "attack_speed": "4", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "shop_price": "100", + "tradeable": "true" + }, + { + "id": "14620", + "name": "Pouch", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, + "tradeable": "true" + }, + { + "id": "14621", + "name": "Pouch", + "archery_ticket_price": "0", + "attack_speed": "4", + "durability": null, + "tradeable": "true" + }, + { + "id": "14622", + "name": "Rise from the ashes scroll", + "examine": "A scroll for a phoenix familiar.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null, "requirements": "{23,72}", "shop_price": "498", - "examine": "A scroll for a phoenix familiar.", - "durability": null, - "name": "Rise from the ashes scroll", - "tradeable": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14622", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "tradeable": "true" }, { - "shop_price": "4986", - "durability": null, - "name": "Phoenix pouch", - "tradeable": "true", - "archery_ticket_price": "0", - "attack_speed": "4", "id": "14623", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "shop_price": "4986", - "durability": null, "name": "Phoenix pouch", - "tradeable": "true", + "absorb": "0,0,0", "archery_ticket_price": "0", "attack_speed": "4", - "id": "14624" - }, - { - "durability": null, - "name": "Pouch", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14625", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A baby phoenix and it's bad to the bone!", - "durability": null, - "name": "Phoenix eggling", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14626", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "A baby phoenix and it's bad to the bone!", - "durability": null, - "name": "Phoenix eggling", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14627", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "I found this egg in the Phoenix's Lair, and clapped at it!", - "durability": null, - "name": "Phoenix egg", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14629", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "Unknown ", - "examine": "I found this egg in the Phoenix's Lair, and kicked it!", - "durability": null, - "name": "Cracked phoenix egg", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14630", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "destroy_message": "A player can get a new one by talking to any seer around Seer's village.", - "examine": "A headband with an eye embroidered on it.", - "durability": null, - "name": "Seer's headband", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14631", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,3,0,0,0,0,0,0", - "equipment_slot": "0" - }, - { - "turn90cw_anim": "821", - "examine": "This used to belong to King Arthur and has since been improved.", - "walk_anim": "819", - "has_special": "true", - "turn90ccw_anim": "822", - "attack_speed": "5", - "turn180_anim": "820", - "absorb": "0,0,0", - "defence_anim": "397", - "equipment_slot": "3", - "attack_anims": "390,390,381,390", - "destroy_message": "You can retrieve the Enhanced Excalibur from the Lady of the Lake for 500 coins.", - "stand_anim": "808", - "run_anim": "824", - "archery_ticket_price": "0", - "id": "14632", - "stand_turn_anim": "823", - "bonuses": "38,47,-2,0,0,0,3,2,1,0,0,45,0,0,0", - "requirements": "{0,30}", - "shop_price": "200", - "durability": null, - "destroy": "true", - "weapon_interface": "6", - "render_anim": "1", - "attack_audios": "2500,2500,2517,2500", - "name": "Enhanced excalibur" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14633", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14634", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "I wonder what happens if I rub it.", - "durability": null, - "name": "Antique lamp", - "tradeable": "false", - "destroy": "true", - "archery_ticket_price": "0", - "attack_speed": "4", - "id": "14635", - "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "650", - "examine": "You don't want to wear it inside-out.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Slayer helmet (e)", - "archery_ticket_price": "0", - "id": "14636", - "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0" - }, - { - "remove_head": "true", - "shop_price": "650", - "examine": "You don't want to wear it inside-out.", - "durability": null, - "destroy": "true", - "attack_speed": "4", - "absorb": "0,0,0", - "remove_beard": "true", - "equipment_slot": "0", - "destroy_message": "Drop", - "name": "Slayer helmet (charged)", - "archery_ticket_price": "0", - "id": "14637", - "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0" - }, - { - "ge_buy_limit": "100", - "examine": "It can be charged at the Fountain of Rune.", - "grand_exchange_price": "26000", - "durability": null, - "name": "Ring of wealth", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14638", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "examine": "It can be charged at the Fountain of Rune.", - "grand_exchange_price": "29800", - "durability": null, - "name": "Ring of wealth", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14639" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with one teleport charge.", - "grand_exchange_price": "27000", - "durability": null, - "name": "Ring of wealth(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14640", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with one teleport charge.", - "grand_exchange_price": "29800", - "durability": null, - "name": "Ring of wealth(1)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14641" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with two teleport charges.", - "grand_exchange_price": "28000", - "durability": null, - "name": "Ring of wealth(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14642", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with two teleport charges.", - "grand_exchange_price": "29800", - "durability": null, - "name": "Ring of wealth(2)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14643" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with three teleport charges.", - "grand_exchange_price": "30000", - "durability": null, - "name": "Ring of wealth(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14644", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with three teleport charges.", - "grand_exchange_price": "29800", - "durability": null, - "name": "Ring of wealth(3)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14645" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with four teleport charges.", - "grand_exchange_price": "35000", - "durability": null, - "name": "Ring of wealth(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14646", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "100", - "examine": "An enchanted ring with four teleport charges.", - "grand_exchange_price": "29800", - "durability": null, - "name": "Ring of wealth(4)", - "tradeable": "true", - "archery_ticket_price": "0", - "id": "14647" - }, - { - "shop_price": "0", - "ge_buy_limit": "0", - "examine": "A totally alive monkey friend for your back!", - "durability": null, - "destroy": "true", - "weight": "0.0", - "equipment_slot": "1", - "grand_exchange_price": "0", - "name": "Jangles the Monkey Backpack", - "tradeable": "false", - "archery_ticket_price": "0", - "id": "14648", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "ge_buy_limit": "0", - "examine": "A ring for only the truest of cave goblins. And Logg too.", - "grand_exchange_price": "0", - "durability": null, - "name": "Zanik ring", - "tradeable": "false", - "archery_ticket_price": "0", - "destroy": "true", - "id": "14649", - "equipment_slot": "12" - }, - { - "ge_buy_limit": "0", - "examine": "A standard issue wizard hat.", - "durability": null, - "weight": "0.1", - "destroy": "true", - "equipment_slot": "0", - "grand_exchange_price": "0", - "name": "Wizard hat", - "tradeable": "false", - "archery_ticket_price": "0", - "hat": "true", - "id": "14650", - "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0" - }, - { - "destroy_message": " WARNING: You will have to reobtain this item the hard way.", - "examine": "Mysterious blueprints written in an alien language.", - "durability": null, - "name": "Ancient Blueprints", - "destroy": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "14651" - }, - { - "destroy_message": "You can get another by bringing the materials along with the blueprint to a Star Sprite.", - "examine": "A stardust-infused dragonstone ring.", - "durability": null, - "name": "Ring of the Star Sprite", - "destroy": "true", - "weight": "0.1", - "archery_ticket_price": "0", - "id": "14652", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "equipment_slot": "12" - }, - { - "examine": "A chunk of rock.", - "name": "Rock", - "id": "1480" - }, - { - "shop_price": "200", - "turn90cw_anim": "1207", - "examine": "A staff with a spooky raven head attached.", - "walk_anim": "1205", "durability": null, - "destroy": "true", - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "tradeable": "false", - "name": "Staff of the raven", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "14654", - "stand_turn_anim": "1209", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "shop_price": "4986", + "tradeable": "true" }, { - "shop_price": "200", - "turn90cw_anim": "1207", - "examine": "A staff with a spooky raven head attached.", - "walk_anim": "1205", + "id": "14624", + "name": "Phoenix pouch", + "archery_ticket_price": "0", + "attack_speed": "4", "durability": null, - "destroy": "true", - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "tradeable": "false", - "name": "Staff of the raven", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "14655", - "stand_turn_anim": "1209", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + "shop_price": "4986", + "tradeable": "true" }, { - "shop_price": "200", - "turn90cw_anim": "1207", - "examine": "A staff with a spooky raven head attached.", - "walk_anim": "1205", + "id": "14625", + "name": "Pouch", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14626", + "name": "Phoenix eggling", + "examine": "A baby phoenix and it's bad to the bone!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14627", + "name": "Phoenix eggling", + "examine": "A baby phoenix and it's bad to the bone!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "durability": null + }, + { + "id": "14629", + "name": "Phoenix egg", + "examine": "I found this egg in the Phoenix's Lair, and clapped at it!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "14630", + "name": "Cracked phoenix egg", + "examine": "I found this egg in the Phoenix's Lair, and kicked it!", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "Unknown ", + "durability": null + }, + { + "id": "14631", + "name": "Seer's headband", + "examine": "A headband with an eye embroidered on it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,3,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "A player can get a new one by talking to any seer around Seer's village.", "durability": null, - "destroy": "true", - "weight": "2.2", - "turn90ccw_anim": "1208", - "attack_speed": "5", - "weapon_interface": "1", - "turn180_anim": "1206", - "defence_anim": "420", - "render_anim": "28", - "equipment_slot": "3", - "attack_anims": "419,419,419,419", - "stand_anim": "813", - "attack_audios": "2555,0,0,0", - "tradeable": "false", - "name": "Staff of the raven", - "run_anim": "1210", - "archery_ticket_price": "0", - "id": "14656", - "stand_turn_anim": "1209", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - }, - { - "examine": "Item container for C. Ele Minor Drop Table. You should not be able to obtain this item.", - "name": "C. Ele Minor Drop Table", - "id": "799" - }, - { - "examine": "This will unlock something. (Waterfall Quest)", - "name": "A key", - "tradeable": "false", - "weight": "0.01", - "archery_ticket_price": "0", - "id": "293" - }, - { - "examine": "This will unlock something. (Waterfall dungeon)", - "name": "A key", - "tradeable": "false", - "archery_ticket_price": "0", - "weight": "0.01", - "id": "298" - }, - { - "examine": "You should not have this.", - "name": "USDT Slot", - "id": "14422" - }, - { - "examine": "You should not have this.", - "name": "HDT Slot", - "id": "14424" - }, - { - "examine": "You should not have this.", - "name": "GDT Slot", - "id": "14426" - }, - { - "examine": "You should not have this.", - "name": "RSDT Slot", - "id": "14428" - }, - { - "examine": "You should not have this.", - "name": "ASDT Slot", - "id": "14430" - }, - { - "destroy_message": "This item can not be reclaimed.", - "shop_price": "1", - "examine": "A rabbit-like adornment, back in black!", - "name": "Bunny ears", - "tradeable": "false", - "destroy": "true", - "weight": "0.2", - "archery_ticket_price": "0", - "id": "14658", "equipment_slot": "0" + }, + { + "id": "14632", + "name": "Enhanced excalibur", + "examine": "This used to belong to King Arthur and has since been improved.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "attack_speed": "5", + "bonuses": "38,47,-2,0,0,0,3,2,1,0,0,45,0,0,0", + "defence_anim": "397", + "destroy": "true", + "destroy_message": "You can retrieve the Enhanced Excalibur from the Lady of the Lake for 500 coins.", + "durability": null, + "equipment_slot": "3", + "has_special": "true", + "render_anim": "1", + "requirements": "{0,30}", + "run_anim": "824", + "shop_price": "200", + "stand_anim": "808", + "stand_turn_anim": "823", + "turn180_anim": "820", + "turn90ccw_anim": "822", + "turn90cw_anim": "821", + "walk_anim": "819", + "weapon_interface": "6" + }, + { + "id": "14633", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "14634", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "14635", + "name": "Antique lamp", + "examine": "I wonder what happens if I rub it.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "tradeable": "false" + }, + { + "id": "14636", + "name": "Slayer helmet (e)", + "examine": "You don't want to wear it inside-out.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "650" + }, + { + "id": "14637", + "name": "Slayer helmet (charged)", + "examine": "You don't want to wear it inside-out.", + "absorb": "0,0,0", + "archery_ticket_price": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0", + "destroy": "true", + "destroy_message": "Drop", + "durability": null, + "equipment_slot": "0", + "remove_beard": "true", + "remove_head": "true", + "shop_price": "650" + }, + { + "id": "14638", + "name": "Ring of wealth", + "examine": "It can be charged at the Fountain of Rune.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14639", + "name": "Ring of wealth", + "examine": "It can be charged at the Fountain of Rune.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14640", + "name": "Ring of wealth(1)", + "examine": "An enchanted ring with one teleport charge.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14641", + "name": "Ring of wealth(1)", + "examine": "An enchanted ring with one teleport charge.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14642", + "name": "Ring of wealth(2)", + "examine": "An enchanted ring with two teleport charges.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14643", + "name": "Ring of wealth(2)", + "examine": "An enchanted ring with two teleport charges.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14644", + "name": "Ring of wealth(3)", + "examine": "An enchanted ring with three teleport charges.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14645", + "name": "Ring of wealth(3)", + "examine": "An enchanted ring with three teleport charges.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14646", + "name": "Ring of wealth(4)", + "examine": "An enchanted ring with four teleport charges.", + "archery_ticket_price": "0", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14647", + "name": "Ring of wealth(4)", + "examine": "An enchanted ring with four teleport charges.", + "archery_ticket_price": "0", + "durability": null, + "ge_buy_limit": "100", + "tradeable": "true" + }, + { + "id": "14648", + "name": "Jangles the Monkey Backpack", + "examine": "A totally alive monkey friend for your back!", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "1", + "ge_buy_limit": "0", + "shop_price": "0", + "tradeable": "false", + "weight": "0.0" + }, + { + "id": "14649", + "name": "Zanik ring", + "examine": "A ring for only the truest of cave goblins. And Logg too.", + "archery_ticket_price": "0", + "destroy": "true", + "durability": null, + "equipment_slot": "12", + "ge_buy_limit": "0", + "tradeable": "false" + }, + { + "id": "14650", + "name": "Wizard hat", + "examine": "A standard issue wizard hat.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "destroy": "true", + "durability": null, + "equipment_slot": "0", + "ge_buy_limit": "0", + "hat": "true", + "tradeable": "false", + "weight": "0.1" + }, + { + "id": "14651", + "name": "Ancient Blueprints", + "examine": "Mysterious blueprints written in an alien language.", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": " WARNING: You will have to reobtain this item the hard way.", + "durability": null, + "weight": "0.1" + }, + { + "id": "14652", + "name": "Ring of the Star Sprite", + "examine": "A stardust-infused dragonstone ring.", + "archery_ticket_price": "0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "destroy": "true", + "destroy_message": "You can get another by bringing the materials along with the blueprint to a Star Sprite.", + "durability": null, + "equipment_slot": "12", + "weight": "0.1" + }, + { + "id": "14654", + "name": "Staff of the raven", + "examine": "A staff with a spooky raven head attached.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "420", + "destroy": "true", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "200", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "14655", + "name": "Staff of the raven", + "examine": "A staff with a spooky raven head attached.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "420", + "destroy": "true", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "200", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "14656", + "name": "Staff of the raven", + "examine": "A staff with a spooky raven head attached.", + "archery_ticket_price": "0", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_anim": "420", + "destroy": "true", + "durability": null, + "equip_audio": "2247", + "equipment_slot": "3", + "render_anim": "28", + "run_anim": "1210", + "shop_price": "200", + "stand_anim": "813", + "stand_turn_anim": "1209", + "tradeable": "false", + "turn180_anim": "1206", + "turn90ccw_anim": "1208", + "turn90cw_anim": "1207", + "walk_anim": "1205", + "weapon_interface": "1", + "weight": "2.2" + }, + { + "id": "14658", + "name": "Bunny ears", + "examine": "A rabbit-like adornment, back in black!", + "archery_ticket_price": "0", + "destroy": "true", + "destroy_message": "This item can not be reclaimed.", + "equipment_slot": "0", + "shop_price": "1", + "tradeable": "false", + "weight": "0.2" } ] \ No newline at end of file diff --git a/Server/data/configs/music_configs.json b/Server/data/configs/music_configs.json deleted file mode 100644 index ba4a924e6..000000000 --- a/Server/data/configs/music_configs.json +++ /dev/null @@ -1,1640 +0,0 @@ -[ - { - "id": "1", - "borders": "{2112,4544,2175,4607}" - }, - { - "id": "2", - "borders": "{3200,3264,3263,3327}" - }, - { - "id": "3", - "borders": "{3072,3200,3135,3263}" - }, - { - "id": "4", - "borders": "{2752,3712,2815,3775}" - }, - { - "id": "5", - "borders": "{2496,3264,2559,3327}-{2752,4672,2815,4735}" - }, - { - "id": "6", - "borders": "{2752,3200,2815,3263}" - }, - { - "id": "7", - "borders": "{2688,3456,2751,3519}" - }, - { - "id": "8", - "borders": "{3072,3584,3135,3647}" - }, - { - "id": "9", - "borders": "{2816,3520,2879,3583}" - }, - { - "id": "10", - "borders": "{3136,3584,3199,3647}-{2368,3264,2431,3327}" - }, - { - "id": "11", - "borders": "{3392,9600,3455,9663}" - }, - { - "id": "12", - "borders": "{2944,3200,3007,3263}" - }, - { - "id": "13", - "borders": "{3072,3904,3135,3967}-{2496,4672,2559,4735}" - }, - { - "id": "14", - "borders": "{3264,3648,3327,3711}" - }, - { - "id": "15", - "borders": "{3008,3328,3071,3391}" - }, - { - "id": "17", - "borders": "{2688,9664,2751,9727}" - }, - { - "id": "18", - "borders": "{2880,3392,2943,3455}" - }, - { - "id": "19", - "borders": "{2816,9792,2879,9855}" - }, - { - "id": "20", - "borders": "{3328,3392,3391,3455}-{2624,3520,2687,3583}" - }, - { - "id": "21", - "borders": "{2688,3520,2751,3583}" - }, - { - "id": "22", - "borders": "{2432,3456,2495,3519}" - }, - { - "id": "24", - "borders": "{2496,3200,2559,3263}" - }, - { - "id": "25", - "borders": "{2816,9600,2879,9663}" - }, - { - "id": "26", - "borders": "{3008,10240,3071,10303}" - }, - { - "id": "27", - "borders": "{2560,3136,2623,3199}-{2560,9536,2623,9599}" - }, - { - "id": "28", - "borders": "{2240,4672,2303,4735}" - }, - { - "id": "29", - "borders": "{2560,9408,2623,9471}" - }, - { - "id": "30", - "borders": "{2368,4672,2431,4735}-{2880,9280,2943,9343}" - }, - { - "id": "32", - "borders": "{2496,3456,2559,3519}" - }, - { - "id": "33", - "borders": "{2432,3392,2495,3455}" - }, - { - "id": "34", - "borders": "{2944,3520,3007,3583}" - }, - { - "id": "35", - "borders": "{3008,3200,3071,3263}" - }, - { - "id": "36", - "borders": "{3264,3200,3327,3263}-{3392,3136,3455,3199}" - }, - { - "id": "37", - "borders": "{2944,3776,3007,3839}" - }, - { - "id": "38", - "borders": "{1856,4800,1919,4863}" - }, - { - "id": "41", - "borders": "{2432,3200,2495,3263}-{2432,9600,2495,9663}" - }, - { - "id": "42", - "borders": "{3008,3776,3071,3839}" - }, - { - "id": "43", - "borders": "{2944,3712,3007,3775}" - }, - { - "id": "45", - "borders": "{3328,9728,3391,9855}" - }, - { - "id": "46", - "borders": "{3200,9600,3263,9663}" - }, - { - "id": "47", - "borders": "{3328,3200,3391,3263}" - }, - { - "id": "48", - "borders": "{3392,3456,3455,3519}" - }, - { - "id": "49", - "borders": "{3008,3264,3071,3327}" - }, - { - "id": "50", - "borders": "{3264,3136,3327,3199}-{3328,3136,3391,3199}" - }, - { - "id": "51", - "borders": "{1920,4800,1983,4863}" - }, - { - "id": "52", - "borders": "{2944,3904,3007,3967}-{2944,10240,3007,10303}-{2816,4800,2879,4863}" - }, - { - "id": "53", - "borders": "{2880,9664,2943,9727}" - }, - { - "id": "54", - "borders": "{2944,3392,3007,3455}" - }, - { - "id": "55", - "borders": "{2752,3136,2815,3199}" - }, - { - "id": "56", - "borders": "{3136,3520,3199,3583}" - }, - { - "id": "57", - "borders": "{2880,4800,2943,4863}" - }, - { - "id": "58", - "borders": "{2752,3072,2815,3135}" - }, - { - "id": "59", - "borders": "{2368,9664,2431,9727}" - }, - { - "id": "60", - "borders": "{2624,3392,2687,3455}" - }, - { - "id": "61", - "borders": "{3456,3456,3519,3519}" - }, - { - "id": "62", - "borders": "{3052,3055,3155,3135}" - }, - { - "id": "63", - "borders": "{2624,9728,2687,9914}-{2688,9792,2751,9855}" - }, - { - "id": "64", - "borders": "{3136,3136,3199,3199}" - }, - { - "id": "65", - "borders": "{2752,4800,2815,4863}" - }, - { - "id": "66", - "borders": "{3008,3648,3071,3711}-{2496,3520,2559,3583}" - }, - { - "id": "67", - "borders": "{3136,3712,3199,3775}-{1536,5760,1599,5823}" - }, - { - "id": "68", - "borders": "{3008,10304,3071,10367}-{2560,9472,2623,9535}" - }, - { - "id": "69", - "borders": "{3264,3072,3327,3135}" - }, - { - "id": "70", - "borders": "{2624,3200,2687,3263}" - }, - { - "id": "71", - "borders": "{2624,2944,2687,3007}-{2624,9344,2687,9407}" - }, - { - "id": "72", - "borders": "{2944,3328,3007,3391}" - }, - { - "id": "73", - "borders": "" - }, - { - "id": "74", - "borders": "{2752,3392,2815,3455}" - }, - { - "id": "75", - "borders": "{3328,3328,3391,3391}" - }, - { - "id": "76", - "borders": "{3200,3200,3263,3263}" - }, - { - "id": "77", - "borders": "{2880,3456,2943,3519}" - }, - { - "id": "78", - "borders": "{2880,2880,2943,2943}" - }, - { - "id": "79", - "borders": "{3136,3008,3199,3071}" - }, - { - "id": "80", - "borders": "{2432,2944,2495,3007}" - }, - { - "id": "81", - "borders": "{2624,3328,2687,3391}" - }, - { - "id": "82", - "borders": "{2496,3392,2559,3455}-{2496,9792,2559,9855}" - }, - { - "id": "83", - "borders": "{2496,3072,2559,3135}" - }, - { - "id": "84", - "borders": "{3392,3392,3455,3455}-{2304,4992,2367,5055}" - }, - { - "id": "85", - "borders": "{3072,3136,3135,3199}-{3072,9472,3135,9535}" - }, - { - "id": "87", - "borders": "{2816,3456,2879,3519}" - }, - { - "id": "88", - "borders": "{2688,9856,2751,9919}" - }, - { - "id": "89", - "borders": "{2880,3008,2943,3071}" - }, - { - "id": "90", - "borders": "{2816,2944,2879,3007}" - }, - { - "id": "91", - "borders": "{2688,3264,2751,3327}-{2112,3072,2175,3135}" - }, - { - "id": "92", - "borders": "{2880,3136,2943,3199}" - }, - { - "id": "93", - "borders": "{3264,3456,3327,3519}" - }, - { - "id": "94", - "borders": "{2880,2944,2943,3007}" - }, - { - "id": "95", - "borders": "{2304,9792,2367,9855}" - }, - { - "id": "96", - "borders": "{3008,3520,3071,3583}" - }, - { - "id": "97", - "borders": "{2240,4736,2303,4799}" - }, - { - "id": "98", - "borders": "{3072,3456,3135,3519}-{3072,9856,3135,9919}" - }, - { - "id": "99", - "borders": "{2624,3264,2687,3327}" - }, - { - "id": "100", - "borders": "{2816,9856,2879,9919}-{2816,9920,2879,9983}" - }, - { - "id": "101", - "borders": "{2304,3392,2367,3455}" - }, - { - "id": "102", - "borders": "{3008,3456,3071,3519}-{2496,9600,2559,9663}" - }, - { - "id": "103", - "borders": "{2880,9344,2943,9407}" - }, - { - "id": "104", - "borders": "{2752,3456,2815,3519}" - }, - { - "id": "105", - "borders": "{3008,3136,3071,3199}" - }, - { - "id": "106", - "borders": "{3136,3904,3199,3967}-{3200,3328,3263,3391}-{3200,9728,3263,9791}" - }, - { - "id": "107", - "borders": "{2880,3264,2943,3327}-{2624,4672,2687,4735}" - }, - { - "id": "108", - "borders": "{2944,9536,3007,9599}-{3200,9536,3263,9599}" - }, - { - "id": "109", - "borders": "{2560,3456,2623,3519}-{2496,9856,2559,9919}" - }, - { - "id": "110", - "borders": "{2368,3136,2431,3199}" - }, - { - "id": "111", - "borders": "{3264,3328,3327,3391}" - }, - { - "id": "112", - "borders": "{2304,3456,2367,3519}" - }, - { - "id": "113", - "borders": "{3072,3520,3135,3583}" - }, - { - "id": "114", - "borders": "{2752,2944,2815,3007}-{2752,9344,2815,9407}" - }, - { - "id": "115", - "borders": "{2688,3200,2751,3263}" - }, - { - "id": "116", - "borders": "{3136,3328,3199,3391}" - }, - { - "id": "117", - "borders": "{2752,3008,2815,3071}" - }, - { - "id": "118", - "borders": "{2370,2397,2431,4479}" - }, - { - "id": "119", - "borders": "{2816,3392,2879,3455}" - }, - { - "id": "120", - "borders": "{3200,3712,3263,3775}" - }, - { - "id": "121", - "borders": "{3264,3520,3327,3583}" - }, - { - "id": "122", - "borders": "{3328,3264,3391,3327}" - }, - { - "id": "123", - "borders": "{3264,3264,3327,3327}" - }, - { - "id": "124", - "borders": "{3200,3072,3263,3135}" - }, - { - "id": "125", - "borders": "{3200,3392,3263,3455}" - }, - { - "id": "127", - "borders": "{3200,3904,3263,3967}-{2944,3264,3007,3327}" - }, - { - "id": "128", - "borders": "{2560,2944,2623,3007}" - }, - { - "id": "129", - "borders": "{2752,2880,2815,2943}-{2880,9472,2943,9535}" - }, - { - "id": "130", - "borders": "{2304,3328,2367,3391}" - }, - { - "id": "131", - "borders": "{2368,4800,2431,4863}" - }, - { - "id": "132", - "borders": "{2240,3200,2303,3263}" - }, - { - "id": "133", - "borders": "{2560,3328,2623,3391}-{2496,9728,2559,9791}" - }, - { - "id": "134", - "borders": "{2176,4800,2239,4863}" - }, - { - "id": "138", - "borders": "{2880,3200,2943,3263}-{2880,9600,2943,9663}" - }, - { - "id": "140", - "borders": "{2624,3456,2687,3519}" - }, - { - "id": "141", - "borders": "{3072,3392,3135,3455}-{3072,9792,3135,9855}" - }, - { - "id": "142", - "borders": "{2240,4800,2303,4863}" - }, - { - "id": "143", - "borders": "{2624,4800,2687,4863}" - }, - { - "id": "144", - "borders": "{3136,9856,3199,9919}-{3072,9536,3135,9599}" - }, - { - "id": "145", - "borders": "{3200,3136,3263,3199}" - }, - { - "id": "146", - "borders": "{3459,4808,5919,4863}" - }, - { - "id": "148", - "borders": "{2496,3136,2559,3199}-{2560,4416,2623,4479}-{2496,9536,2559,9599}" - }, - { - "id": "149", - "borders": "{2880,3520,2943,3583}" - }, - { - "id": "151", - "borders": "{3072,3264,3135,3327}" - }, - { - "id": "152", - "borders": "{2560,3200,2623,3263}" - }, - { - "id": "153", - "borders": "{2880,9984,2943,10047}" - }, - { - "id": "154", - "borders": "{3392,3264,3455,3327}" - }, - { - "id": "155", - "borders": "{2432,3328,2495,3391}" - }, - { - "id": "156", - "borders": "{3392,9856,3455,9919}" - }, - { - "id": "157", - "borders": "{3264,3392,3327,3455}" - }, - { - "id": "158", - "borders": "{2560,4800,2623,4863}" - }, - { - "id": "159", - "borders": "{3008,3712,3071,3775}-{2496,3008,2559,3071}-{2496,9408,2559,9471}" - }, - { - "id": "160", - "borders": "{3008,3584,3071,3647}" - }, - { - "id": "161", - "borders": "{2624,3072,2687,3135}" - }, - { - "id": "162", - "borders": "{2816,3072,2879,3135}-{2816,9472,2879,9535}" - }, - { - "id": "163", - "borders": "{3136,3264,3199,3327}" - }, - { - "id": "164", - "borders": "{2688,3136,2751,3199}" - }, - { - "id": "165", - "borders": "{2816,3008,2879,3071}" - }, - { - "id": "166", - "borders": "{2944,3008,3007,3071}" - }, - { - "id": "167", - "borders": "{2624,3136,2687,3199}" - }, - { - "id": "168", - "borders": "{3264,9408,3327,9471}" - }, - { - "id": "169", - "borders": "{3200,3520,3263,3583}-{2624,9664,2687,9727}" - }, - { - "id": "170", - "borders": "{2816,3200,2879,3263}" - }, - { - "id": "172", - "borders": "{2816,3136,2879,3199}-{2816,2880,2879,2943}" - }, - { - "id": "173", - "borders": "{2880,9728,2943,9791}" - }, - { - "id": "174", - "borders": "{3264,2944,3327,3007}-{3328,3008,3391,3071}" - }, - { - "id": "175", - "borders": "{3136,3392,3199,3455}" - }, - { - "id": "176", - "borders": "{3072,3648,3135,3711}" - }, - { - "id": "177", - "borders": "{3200,3456,3263,3519}" - }, - { - "id": "178", - "borders": "{2880,9792,2943,9855}" - }, - { - "id": "179", - "borders": "{3328,3584,3391,3647}-{2816,9728,2879,9791}" - }, - { - "id": "180", - "borders": "{2944,3136,3007,3199}" - }, - { - "id": "181", - "borders": "{2432,2397,2495,4479}" - }, - { - "id": "182", - "borders": "{3264,3776,3327,3839}-{3264,3712,3327,3775}" - }, - { - "id": "183", - "borders": "{2944,3648,3007,3711}" - }, - { - "id": "184", - "borders": "{2688,3392,2751,3455}" - }, - { - "id": "185", - "borders": "{2560,3072,2623,3135}" - }, - { - "id": "186", - "borders": "{2880,3328,2943,3391}" - }, - { - "id": "187", - "borders": "{2816,3584,2879,3647}" - }, - { - "id": "188", - "borders": "{2560,3008,2623,3071}" - }, - { - "id": "190", - "borders": "{2496,4800,2559,4863}" - }, - { - "id": "191", - "borders": "{2560,3264,2623,3327}" - }, - { - "id": "192", - "borders": "{2688,3328,2751,3391}-{2688,9728,2751,9791}" - }, - { - "id": "193", - "borders": "{2560,3392,2623,3455}" - }, - { - "id": "198", - "borders": "{1792,4352,1855,4415}-{1920,4352,1983,4415}" - }, - { - "id": "220", - "borders": "{2304,3842,2428,3901}" - }, - { - "id": "241", - "borders": "{3456,3328,3519,3391}-{2176,4992,2239,5055}" - }, - { - "id": "242", - "borders": "{2880,4544,2943,4607}" - }, - { - "id": "243", - "borders": "{2112,4800,2175,4863}" - }, - { - "id": "244", - "borders": "{3456,3392,3519,3455}-{1984,4992,2047,5055}" - }, - { - "id": "245", - "borders": "{3392,3328,3455,3391}-{2240,4992,2303,5055}" - }, - { - "id": "246", - "borders": "{3392,9728,3455,9791}" - }, - { - "id": "247", - "borders": "{1984,4736,2047,4799}" - }, - { - "id": "248", - "borders": "{2752,9536,2815,9599}" - }, - { - "id": "251", - "borders": "{2240,3136,2303,3199}" - }, - { - "id": "252", - "borders": "{2304,3200,2367,3263}" - }, - { - "id": "253", - "borders": "{2240,3072,2303,3135}" - }, - { - "id": "254", - "borders": "{2112,3136,2175,3199}" - }, - { - "id": "255", - "borders": "{2112,3200,2175,3263}" - }, - { - "id": "256", - "borders": "{2304,3264,2367,3327}" - }, - { - "id": "257", - "borders": "{2816,3648,2879,3711}" - }, - { - "id": "258", - "borders": "{2880,3584,2943,3647}" - }, - { - "id": "259", - "borders": "{2240,3264,2303,3327}" - }, - { - "id": "260", - "borders": "{3456,9472,3519,9535}" - }, - { - "id": "261", - "borders": "{2752,10112,2815,10175}-{2816,10048,2879,10111}" - }, - { - "id": "262", - "borders": "{2432,4800,2495,4863}" - }, - { - "id": "263", - "borders": "{3136,2944,3199,3007}" - }, - { - "id": "264", - "borders": "{2880,10048,2943,10111}" - }, - { - "id": "265", - "borders": "{2752,9280,2815,9343}" - }, - { - "id": "266", - "borders": "{3200,9344,3263,9407}" - }, - { - "id": "267", - "borders": "{3200,2944,3263,3007}-{3328,2880,3391,2943}" - }, - { - "id": "268", - "borders": "{2112,3264,2175,3327}" - }, - { - "id": "269", - "borders": "{2176,4928,2239,4991}" - }, - { - "id": "270", - "borders": "{2176,3072,2239,3135}" - }, - { - "id": "271", - "borders": "{2304,9600,2367,9663}" - }, - { - "id": "272", - "borders": "{3145,5189,3187,5240}" - }, - { - "id": "273", - "borders": "" - }, - { - "id": "277", - "borders": "{2752,4416,2815,4479}" - }, - { - "id": "278", - "borders": "{2688,4544,2751,4607}-{2688,4480,2751,4543}" - }, - { - "id": "282", - "borders": "{2688,4416,2751,4479}-{2752,4480,2815,4543}" - }, - { - "id": "284", - "borders": "{2496,3840,2559,3903}" - }, - { - "id": "285", - "borders": "{2560,3840,2623,3903}" - }, - { - "id": "286", - "borders": "{3392,3200,3455,3263}-{3456,3264,3519,3327}-{2112,4992,2175,5055}" - }, - { - "id": "287", - "borders": "{3456,9664,3519,9727}" - }, - { - "id": "288", - "borders": "{3520,3456,3583,3519}" - }, - { - "id": "289", - "borders": "{2563,3647,2687,3776}" - }, - { - "id": "290", - "borders": "{2560,3584,2689,3647}" - }, - { - "id": "291", - "borders": "{2688,3648,2751,3776}" - }, - { - "id": "292", - "borders": "{2816,3712,2879,3775}-{2880,3712,2943,3775}" - }, - { - "id": "293", - "borders": "{2688,3584,2751,3647}" - }, - { - "id": "294", - "borders": "{2816,3776,2879,3839}" - }, - { - "id": "295", - "borders": "{2624,10048,2687,10111}" - }, - { - "id": "296", - "borders": "{2560,4480,2623,4543}" - }, - { - "id": "303", - "borders": "{2752,2752,2815,2815}" - }, - { - "id": "304", - "borders": "{2880,2688,2943,2751}-{3008,5440,3071,5503}" - }, - { - "id": "305", - "borders": "{2688,2752,2751,2815}" - }, - { - "id": "306", - "borders": "{2688,2688,2751,2751}" - }, - { - "id": "307", - "borders": "{2752,9152,2815,9215}" - }, - { - "id": "311", - "borders": "{2688,9152,2751,9215}" - }, - { - "id": "312", - "borders": "{2688,9088,2751,9151}" - }, - { - "id": "314", - "borders": "{2368,3072,2431,3135}" - }, - { - "id": "316", - "borders": "{2624,9984,2687,10047}" - }, - { - "id": "317", - "borders": "{2432,3072,2495,3135}" - }, - { - "id": "318", - "borders": "{2368,9472,2431,9535}" - }, - { - "id": "319", - "borders": "{3456,9792,3519,9855}" - }, - { - "id": "320", - "borders": "{2496,3584,2559,3647}" - }, - { - "id": "322", - "borders": "{2496,9984,2559,10047}" - }, - { - "id": "323", - "borders": "{2368,9536,2431,9599}" - }, - { - "id": "324", - "borders": "{2752,3328,2815,3391}-{1920,4992,1983,5055}" - }, - { - "id": "325", - "borders": "{3008,9728,3071,9791}-{2944,9792,3007,9855}" - }, - { - "id": "326", - "borders": "{3328,3648,3391,3711}" - }, - { - "id": "327", - "borders": "{3136,3200,3199,3263}" - }, - { - "id": "328", - "borders": "{2496,3328,2559,3391}" - }, - { - "id": "329", - "borders": "{3264,3904,3327,3967}" - }, - { - "id": "330", - "borders": "{3136,9792,3199,9855}" - }, - { - "id": "331", - "borders": "{3264,3840,3327,3903}" - }, - { - "id": "332", - "borders": "{3200,3648,3263,3711}-{3136,3840,3199,3903}" - }, - { - "id": "333", - "borders": "{3072,3328,3135,3391}" - }, - { - "id": "334", - "borders": "{3008,3904,3071,3967}" - }, - { - "id": "335", - "borders": "{2752,3840,2815,3903}" - }, - { - "id": "336", - "borders": "{2816,9536,2879,9599}" - }, - { - "id": "337", - "borders": "{3200,3584,3263,3647}" - }, - { - "id": "338", - "borders": "{3072,9728,3135,9791}" - }, - { - "id": "339", - "borders": "{3392,3520,3455,3583}" - }, - { - "id": "340", - "borders": "{2688,9984,2751,10047}" - }, - { - "id": "341", - "borders": "{2752,9984,2815,10047}" - }, - { - "id": "342", - "borders": "{3456,9920,3519,9983}" - }, - { - "id": "343", - "borders": "{3136,9600,3199,9663}" - }, - { - "id": "344", - "borders": "{3456,3520,3519,3583}" - }, - { - "id": "345", - "borders": "{3520,9856,3583,9919}" - }, - { - "id": "346", - "borders": "{2560,9792,2623,9855}" - }, - { - "id": "347", - "borders": "{2752,3264,2815,3327}" - }, - { - "id": "348", - "borders": "{2432,9856,2495,9919}" - }, - { - "id": "351", - "borders": "{3328,2944,3391,3007}" - }, - { - "id": "352", - "borders": "{3136,2880,3199,2943}" - }, - { - "id": "353", - "borders": "{3584,3520,3647,3583}" - }, - { - "id": "354", - "borders": "{3648,9856,3711,9919}" - }, - { - "id": "355", - "borders": "{3648,3456,3711,3519}" - }, - { - "id": "356", - "borders": "{2752,3648,2815,3711}" - }, - { - "id": "357", - "borders": "{2752,10048,2815,10111}" - }, - { - "id": "358", - "borders": "{3776,3520,3839,3583}" - }, - { - "id": "359", - "borders": "{3200,9280,3263,9343}" - }, - { - "id": "361", - "borders": "{3072,9600,3135,9663}" - }, - { - "id": "362", - "borders": "{2688,9472,2751,9535}-{2688,9408,2751,9471}" - }, - { - "id": "363", - "name": "7th Realm", - "indexId": "285", - "borders": "{2624,9536,2687,9599}-{2624,9472,2687,9535}" - }, - { - "id": "364", - "borders": "{2688,9536,2751,9599}" - }, - { - "id": "369", - "borders": "{2816,10112,2879,10175}" - }, - { - "id": "370", - "borders": "{2496,4928,2559,4991}" - }, - { - "id": "372", - "borders": "{2304,3136,2367,3199}" - }, - { - "id": "373", - "borders": "{2304,4928,2367,4991}" - }, - { - "id": "375", - "borders": "{1920,4608,1983,4671}" - }, - { - "id": "376", - "borders": "{1856,4608,1919,4671}" - }, - { - "id": "377", - "borders": "{3392,3072,3455,3135}-{3456,3072,3519,3135}" - }, - { - "id": "380", - "borders": "{3520,3264,3583,3327}" - }, - { - "id": "381", - "borders": "{3520,9664,3583,9727}" - }, - { - "id": "383", - "borders": "{3200,2752,3263,2815}-{3264,2752,3327,2815}" - }, - { - "id": "386", - "borders": "{2820,5312,2849,5369}-{2849,5349,2880,5374}" - }, - { - "id": "387", - "borders": "{3264,2816,3327,2879}" - }, - { - "id": "388", - "borders": "{3264,9152,3327,9215}" - }, - { - "id": "389", - "borders": "{3136,9536,3199,9599}" - }, - { - "id": "390", - "borders": "{2304,3008,2367,3071}" - }, - { - "id": "391", - "borders": "{2879,5340,2944,5366}-{2909,5316,2944,5340}" - }, - { - "id": "392", - "borders": "{2432,3008,2495,3071}" - }, - { - "id": "393", - "borders": "{2624,5056,2687,5119}" - }, - { - "id": "394", - "borders": "{2432,9408,2495,9471}" - }, - { - "id": "395", - "borders": "{2880,10112,2943,10175}" - }, - { - "id": "396", - "borders": "{2816,10176,2879,10239}" - }, - { - "id": "397", - "borders": "{3200,9472,3263,9535}" - }, - { - "id": "399", - "borders": "{2816,5248,2943,5375,[2823,5250,2844,5310]~,[2844,5250,2878,5280]~,[2879,5340,2944,5366]~,[2909,5316,2944,5340]~,[2820,5312,2849,5369]~,[2849,5349,2880,5374]~,[2885,5253,2934,5278]~,[2913,5278,2937,5306]}" - }, - { - "id": "401", - "borders": "" - }, - { - "id": "402", - "borders": "{2944,4928,3071,4991}" - }, - { - "id": "403", - "borders": "{3008,5056,3071,5119}" - }, - { - "id": "404", - "borders": "{2823,5250,2844,5310}-{2844,5250,2878,5276}" - }, - { - "id": "407", - "borders": "{3264,9600,3327,9663}" - }, - { - "id": "408", - "borders": "{2885,5253,2934,5278}-{2913,5278,2937,5306}" - }, - { - "id": "409", - "borders": "{2432,4736,2495,4799}" - }, - { - "id": "411", - "borders": "{3403,4761,3442,4792}" - }, - { - "id": "412", - "borders": "{3008,4800,3071,4863}--{3011,4866,3066,4925}" - }, - { - "id": "413", - "borders": "{1920,4736,1983,4799}" - }, - { - "id": "418", - "borders": "{3136,4800,3199,4863}" - }, - { - "id": "419", - "borders": "{2560,4736,2623,4799}" - }, - { - "id": "425", - "borders": "{2432,4928,2495,4991}" - }, - { - "id": "428", - "borders": "{3264,4800,3327,4863}" - }, - { - "id": "432", - "borders": "{1600,4800,1663,4863}-{1664,4800,1727,4863}" - }, - { - "id": "434", - "borders": "{1920,4928,1983,4991}" - }, - { - "id": "435", - "borders": "{2944,3584,3007,3647}-{3072,3712,3135,3775}" - }, - { - "id": "442", - "borders": "" - }, - { - "id": "443", - "borders": "{2944,5632,3135,5823}" - }, - { - "id": "444", - "borders": "{2688,5632,2879,5823}" - }, - { - "id": "445", - "borders": "{3200,5632,3391,5823}" - }, - { - "id": "447", - "borders": "{3392,2880,3455,2943}" - }, - { - "id": "448", - "borders": "{2432,10112,2495,10175}" - }, - { - "id": "454", - "borders": "" - }, - { - "id": "456", - "borders": "{2202,5339,2212,5351}-{2328,10006,2338,10017}-{3436,9743,3446,9752}" - }, - { - "id": "461", - "borders": "{2496,3712,2559,3775}" - }, - { - "id": "462", - "borders": "{3328,9536,3391,9599}" - }, - { - "id": "463", - "borders": "{2368,5120,2431,5183}" - }, - { - "id": "464", - "borders": "{3328,9280,3391,9343}" - }, - { - "id": "465", - "borders": "{3392,2944,3455,3007}" - }, - { - "id": "469", - "borders": "{2432,5120,2495,5183}" - }, - { - "id": "471", - "borders": "{3648,9920,3711,9983}" - }, - { - "id": "473", - "borders": "{2368,5056,2431,5119}" - }, - { - "id": "475", - "borders": "{3008,3840,3071,3903}" - }, - { - "id": "476", - "borders": "{3136,3648,3199,3711}" - }, - { - "id": "478", - "borders": "{2496,9664,2559,9727}" - }, - { - "id": "479", - "borders": "{2880,3072,2943,3135}" - }, - { - "id": "481", - "borders": "{2624,9600,2687,9663}" - }, - { - "id": "482", - "borders": "{2880,5056,2943,5119}" - }, - { - "id": "489", - "borders": "{1920,4672,1983,4735}" - }, - { - "id": "490", - "borders": "{2944,9600,3007,9663}" - }, - { - "id": "491", - "borders": "{2816,5056,2879,5119}" - }, - { - "id": "496", - "borders": "{3136,3456,3199,3519}" - }, - { - "id": "497", - "borders": "{2112,5056,2175,5119}" - }, - { - "id": "498", - "borders": "{2112,5120,2175,5183}" - }, - { - "id": "500", - "borders": "" - }, - { - "id": "501", - "borders": "{3456,3136,3519,3199}" - }, - { - "id": "505", - "borders": "{3328,2816,3391,2879}-{3008,4672,3071,4735}" - }, - { - "id": "511", - "borders": "{2048,4416,2111,4479}" - }, - { - "id": "515", - "borders": "{2944,3072,3007,3135}" - }, - { - "id": "517", - "borders": "{2496,10112,2559,10175}" - }, - { - "id": "526", - "borders": "" - }, - { - "id": "524", - "borders": "{1856,4352,1919,4415}-{2880,4416,2943,4479}" - }, - { - "id": "528", - "borders": "{3136,9728,3199,9791}" - }, - { - "id": "529", - "borders": "{3008,9536,3071,9599}" - }, - { - "id": "530", - "borders": "{3648,2944,3711,3007}" - }, - { - "id": "532", - "borders": "{1984,4416,2047,4479}" - }, - { - "id": "537", - "borders": "{1856,5185,1917,5246}" - }, - { - "id": "542", - "borders": "{3072,9280,3135,9343}" - }, - { - "id": "544", - "borders": "{2304,3648,2367,3711}-{2304,3584,2367,3647}" - }, - { - "id": "555", - "borders": "" - }, - { - "id": "558", - "borders": "{1985,5185,2047,5247}" - }, - { - "id": "559", - "borders": "{2116,5247,2172,5308}" - }, - { - "id": "560", - "borders": "{2305,5186,2366,5247}" - }, - { - "id": "569", - "borders": "{3200,9984,3263,10047}" - }, - { - "id": "571", - "borders": "" - }, - { - "id": "573", - "borders": "{1728,5120,1791,5247}" - }, - { - "id": "575", - "borders": "{2432,4352,2495,4415}" - }, - { - "id": "576", - "borders": "{2944,9472,3007,9535}" - }, - { - "id": "583", - "borders": "{1856,5312,1919,5375}" - }, - { - "id": "586", - "borders": "{3328,3904,3391,3967}" - }, - { - "id": "587", - "borders": "{2624,2624,2687,2687}" - }, - { - "id": "588", - "borders": "{2624,2560,2687,2623}" - }, - { - "id": "594", - "borders": "{3264,9792,3297,9824}" - }, - { - "id": "603", - "borders": "{2432,5248,2495,5311}" - }, - { - "id": "604", - "borders": "" - }, - { - "id": "612", - "borders": "{1856,5120,1919,5183}" - }, - { - "id": "616", - "borders": "" - }, - { - "id": "634", - "borders": "" - }, - { - "id": "964", - "borders": "{2944,9856,3007,9919}" - }, - { - "id": "222", - "borders": "{2403,10186,2409,10192}" - }, - { - "id": "223", - "borders": "{2404,3797,2421,3820}" - }, - { - "id": "225", - "borders": "{2304,3785,2635,3818}" - }, - { - "id": "584", - "borders": "{2580,5763,2620,5700}" - }, - { - "id": "589", - "borders": "{2500,5766,2620,5810}" - }, - { - "id": "487", - "borders": "{1600,4672,1663,4735}" - }, - { - "id": "578", - "borders": "" - }, - { - "id": "378", - "borders": "{2688,4864,2752,4928}" - }, - { - "id": "379", - "borders": "{3520,4928,3584,4992}" - }, - { - "id": "512", - "borders": "{2436,4876,2485,4918}" - }, - { - "id": "564", - "borders": "{2879,4371,3001,4397}" - }, - { - "id": "488", - "borders": "{3263,5441,3327,5564}--{141,22,171,43}" - }, - { - "id": "467", - "borders": "{3199,5441,3262,5564}--{3193,5482,3198,5497}" - }, - { - "id": "459", - "borders": "{3137,5442,3192,5564}--{3193,5442,3198,5472}--{3193,5507,3198,5564}" - }, - { - "id": "565", - "borders": "{3266,9825,3297,9854}" - }, - { - "id": "602", - "borders": "{3298,9826,3325,9853}" - }, - { - "id": "600", - "borders": "{3298,9793,3325,9825}" - }, - { - "id": "232", - "borders": "{2903,5463,2920,5480}" - }, - { - "id": "230", - "borders": "{2904,5481,2927,5497}" - }, - { - "id": "229", - "borders": "{2921,5456,2937,5479}" - }, - { - "id": "231", - "borders": "{2886,5464,2901,5487}" - }, - { - "id": "228", - "borders": "{2896,5446,2919,5462}" - }, - { - "id": "632", - "borders": "{3716,9349,3837,9469}" - }, - { - "id": "349", - "borders": "{2562,4290,2621,4349}" - }, - { - "id": "625", - "borders": "{2056,3844,2110,3960}" - }, - { - "id": "627", - "borders": "{2111,3844,2171,3960}" - }, - { - "id": "274", - "borders": "{2688,10117,2751,10175}" - } -] diff --git a/Server/data/configs/music_regions.json b/Server/data/configs/music_regions.json new file mode 100644 index 000000000..ef23c3ecf --- /dev/null +++ b/Server/data/configs/music_regions.json @@ -0,0 +1,2574 @@ +[ + { + "region": "6234", + "id": "67" + }, + { + "region": "6473", + "id": "487" + }, + { + "region": "6475", + "id": "432" + }, + { + "region": "6486", + "id": "588" + }, + { + "region": "6487", + "id": "503" + }, + { + "region": "6488", + "id": "507" + }, + { + "region": "6489", + "id": "507" + }, + { + "region": "6722", + "id": "74" + }, + { + "region": "6726", + "id": "205" + }, + { + "region": "6741", + "id": "561" + }, + { + "region": "6744", + "id": "507" + }, + { + "region": "6745", + "id": "507" + }, + { + "region": "6989", + "id": "309" + }, + { + "region": "6992", + "id": "573" + }, + { + "region": "6993", + "id": "573" + }, + { + "region": "6994", + "id": "367" + }, + { + "region": "7236", + "id": "198" + }, + { + "region": "7490", + "id": "374" + }, + { + "region": "7492", + "id": "524" + }, + { + "region": "7494", + "id": "470" + }, + { + "region": "7496", + "id": "376" + }, + { + "region": "7499", + "id": "38" + }, + { + "region": "7500", + "id": "203" + }, + { + "region": "7502", + "id": "371" + }, + { + "region": "7504", + "id": "612" + }, + { + "region": "7505", + "id": "537" + }, + { + "region": "7507", + "id": "583" + }, + { + "region": "7508", + "id": "211" + }, + { + "region": "7509", + "id": "604" + }, + { + "region": "7748", + "id": "198" + }, + { + "region": "7749", + "id": "591" + }, + { + "region": "7752", + "id": "375" + }, + { + "region": "7753", + "id": "489" + }, + { + "region": "7754", + "id": "413" + }, + { + "region": "7755", + "id": "51" + }, + { + "region": "7756", + "id": "620" + }, + { + "region": "7757", + "id": "434" + }, + { + "region": "7758", + "id": "324" + }, + { + "region": "7760", + "id": "202" + }, + { + "region": "7769", + "id": "578" + }, + { + "region": "8001", + "id": "426" + }, + { + "region": "8002", + "id": "426" + }, + { + "region": "8004", + "id": "579" + }, + { + "region": "8005", + "id": "532" + }, + { + "region": "8009", + "id": "271" + }, + { + "region": "8010", + "id": "247" + }, + { + "region": "8013", + "id": "620" + }, + { + "region": "8014", + "id": "244" + }, + { + "region": "8015", + "id": "640" + }, + { + "region": "8017", + "id": "558" + }, + { + "region": "8022", + "id": "421" + }, + { + "region": "8025", + "id": "595" + }, + { + "region": "8252", + "id": "625" + }, + { + "region": "8253", + "id": "625" + }, + { + "region": "8261", + "id": "511" + }, + { + "region": "8267", + "id": "126" + }, + { + "region": "8276", + "id": "303" + }, + { + "region": "8280", + "id": "527" + }, + { + "region": "8282", + "id": "592" + }, + { + "region": "8496", + "id": "91" + }, + { + "region": "8497", + "id": "254" + }, + { + "region": "8498", + "id": "255" + }, + { + "region": "8499", + "id": "268" + }, + { + "region": "8508", + "id": "627" + }, + { + "region": "8509", + "id": "627" + }, + { + "region": "8519", + "id": "1" + }, + { + "region": "8523", + "id": "243" + }, + { + "region": "8526", + "id": "286" + }, + { + "region": "8527", + "id": "497" + }, + { + "region": "8528", + "id": "498" + }, + { + "region": "8529", + "id": "559" + }, + { + "region": "8530", + "id": "559" + }, + { + "region": "8534", + "id": "23" + }, + { + "region": "8752", + "id": "270" + }, + { + "region": "8763", + "id": "630" + }, + { + "region": "8770", + "id": "433" + }, + { + "region": "8779", + "id": "134" + }, + { + "region": "8781", + "id": "269" + }, + { + "region": "8782", + "id": "241" + }, + { + "region": "8787", + "id": "456" + }, + { + "region": "9008", + "id": "253" + }, + { + "region": "9009", + "id": "251" + }, + { + "region": "9010", + "id": "132" + }, + { + "region": "9011", + "id": "259" + }, + { + "region": "9014", + "id": "366" + }, + { + "region": "9015", + "id": "460" + }, + { + "region": "9033", + "id": "28" + }, + { + "region": "9034", + "id": "97" + }, + { + "region": "9035", + "id": "142" + }, + { + "region": "9038", + "id": "245" + }, + { + "region": "9046", + "id": "150" + }, + { + "region": "9263", + "id": "390" + }, + { + "region": "9265", + "id": "372" + }, + { + "region": "9266", + "id": "252" + }, + { + "region": "9267", + "id": "256" + }, + { + "region": "9268", + "id": "130" + }, + { + "region": "9269", + "id": "101" + }, + { + "region": "9270", + "id": "112" + }, + { + "region": "9272", + "id": "544" + }, + { + "region": "9273", + "id": "544" + }, + { + "region": "9275", + "id": "225" + }, + { + "region": "9276", + "id": "220" + }, + { + "region": "9285", + "id": "73" + }, + { + "region": "9293", + "id": "373" + }, + { + "region": "9294", + "id": "84" + }, + { + "region": "9295", + "id": "201" + }, + { + "region": "9297", + "id": "560" + }, + { + "region": "9362", + "id": "153" + }, + { + "region": "9365", + "id": "271" + }, + { + "region": "9366", + "id": "271" + }, + { + "region": "9369", + "id": "95" + }, + { + "region": "9372", + "id": "456" + }, + { + "region": "9520", + "id": "314" + }, + { + "region": "9521", + "id": "110" + }, + { + "region": "9522", + "id": "41" + }, + { + "region": "9523", + "id": "10" + }, + { + "region": "9526", + "id": "112" + }, + { + "region": "9531", + "id": "223" + }, + { + "region": "9532", + "id": "220" + }, + { + "region": "9540", + "id": "118" + }, + { + "region": "9541", + "id": "118" + }, + { + "region": "9544", + "id": "197" + }, + { + "region": "9545", + "id": "30" + }, + { + "region": "9547", + "id": "131" + }, + { + "region": "9550", + "id": "84" + }, + { + "region": "9551", + "id": "473" + }, + { + "region": "9552", + "id": "463" + }, + { + "region": "9553", + "id": "531" + }, + { + "region": "9558", + "id": "276" + }, + { + "region": "9620", + "id": "318" + }, + { + "region": "9621", + "id": "323" + }, + { + "region": "9623", + "id": "59" + }, + { + "region": "9625", + "id": "194" + }, + { + "region": "9626", + "id": "296" + }, + { + "region": "9631", + "id": "222" + }, + { + "region": "9632", + "id": "224" + }, + { + "region": "9774", + "id": "80" + }, + { + "region": "9775", + "id": "392" + }, + { + "region": "9776", + "id": "317" + }, + { + "region": "9778", + "id": "41" + }, + { + "region": "9780", + "id": "155" + }, + { + "region": "9781", + "id": "33" + }, + { + "region": "9782", + "id": "22" + }, + { + "region": "9787", + "id": "225" + }, + { + "region": "9794", + "id": "439" + }, + { + "region": "9796", + "id": "575" + }, + { + "region": "9797", + "id": "181" + }, + { + "region": "9802", + "id": "409" + }, + { + "region": "9803", + "id": "262" + }, + { + "region": "9804", + "id": "512" + }, + { + "region": "9805", + "id": "425" + }, + { + "region": "9808", + "id": "469" + }, + { + "region": "9810", + "id": "603" + }, + { + "region": "9812", + "id": "279" + }, + { + "region": "9814", + "id": "275" + }, + { + "region": "9874", + "id": "394" + }, + { + "region": "9875", + "id": "394" + }, + { + "region": "9878", + "id": "41" + }, + { + "region": "9879", + "id": "59" + }, + { + "region": "9882", + "id": "348" + }, + { + "region": "9886", + "id": "448" + }, + { + "region": "10031", + "id": "159" + }, + { + "region": "10032", + "id": "83" + }, + { + "region": "10033", + "id": "148" + }, + { + "region": "10034", + "id": "24" + }, + { + "region": "10035", + "id": "5" + }, + { + "region": "10036", + "id": "328" + }, + { + "region": "10037", + "id": "82" + }, + { + "region": "10038", + "id": "32" + }, + { + "region": "10039", + "id": "66" + }, + { + "region": "10040", + "id": "320" + }, + { + "region": "10042", + "id": "461" + }, + { + "region": "10043", + "id": "225" + }, + { + "region": "10044", + "id": "284" + }, + { + "region": "10055", + "id": "129" + }, + { + "region": "10056", + "id": "322" + }, + { + "region": "10057", + "id": "13" + }, + { + "region": "10058", + "id": "411" + }, + { + "region": "10059", + "id": "190" + }, + { + "region": "10061", + "id": "370" + }, + { + "region": "10074", + "id": "589" + }, + { + "region": "10075", + "id": "589" + }, + { + "region": "10129", + "id": "453" + }, + { + "region": "10131", + "id": "159" + }, + { + "region": "10133", + "id": "148" + }, + { + "region": "10134", + "id": "102" + }, + { + "region": "10135", + "id": "478" + }, + { + "region": "10136", + "id": "133" + }, + { + "region": "10137", + "id": "82" + }, + { + "region": "10138", + "id": "109" + }, + { + "region": "10139", + "id": "66" + }, + { + "region": "10140", + "id": "322" + }, + { + "region": "10142", + "id": "517" + }, + { + "region": "10144", + "id": "506" + }, + { + "region": "10284", + "id": "474" + }, + { + "region": "10286", + "id": "128" + }, + { + "region": "10287", + "id": "188" + }, + { + "region": "10288", + "id": "185" + }, + { + "region": "10289", + "id": "27" + }, + { + "region": "10290", + "id": "152" + }, + { + "region": "10291", + "id": "191" + }, + { + "region": "10292", + "id": "133" + }, + { + "region": "10293", + "id": "193" + }, + { + "region": "10294", + "id": "109" + }, + { + "region": "10296", + "id": "290" + }, + { + "region": "10297", + "id": "289" + }, + { + "region": "10298", + "id": "289" + }, + { + "region": "10299", + "id": "225" + }, + { + "region": "10300", + "id": "285" + }, + { + "region": "10307", + "id": "349" + }, + { + "region": "10309", + "id": "148" + }, + { + "region": "10310", + "id": "296" + }, + { + "region": "10311", + "id": "308" + }, + { + "region": "10314", + "id": "419" + }, + { + "region": "10315", + "id": "158" + }, + { + "region": "10321", + "id": "638" + }, + { + "region": "10322", + "id": "66" + }, + { + "region": "10330", + "id": "589" + }, + { + "region": "10387", + "id": "29" + }, + { + "region": "10388", + "id": "68" + }, + { + "region": "10389", + "id": "27" + }, + { + "region": "10390", + "id": "102" + }, + { + "region": "10391", + "id": "478" + }, + { + "region": "10393", + "id": "346" + }, + { + "region": "10394", + "id": "109" + }, + { + "region": "10536", + "id": "588" + }, + { + "region": "10537", + "id": "587" + }, + { + "region": "10542", + "id": "71" + }, + { + "region": "10544", + "id": "161" + }, + { + "region": "10545", + "id": "167" + }, + { + "region": "10546", + "id": "70" + }, + { + "region": "10547", + "id": "99" + }, + { + "region": "10548", + "id": "81" + }, + { + "region": "10549", + "id": "60" + }, + { + "region": "10550", + "id": "140" + }, + { + "region": "10551", + "id": "20" + }, + { + "region": "10552", + "id": "290" + }, + { + "region": "10553", + "id": "289" + }, + { + "region": "10554", + "id": "289" + }, + { + "region": "10555", + "id": "225" + }, + { + "region": "10558", + "id": "217" + }, + { + "region": "10569", + "id": "107" + }, + { + "region": "10571", + "id": "143" + }, + { + "region": "10575", + "id": "393" + }, + { + "region": "10577", + "id": "568" + }, + { + "region": "10642", + "id": "71" + }, + { + "region": "10644", + "id": "363" + }, + { + "region": "10645", + "id": "363" + }, + { + "region": "10646", + "id": "481" + }, + { + "region": "10647", + "id": "169" + }, + { + "region": "10648", + "id": "63" + }, + { + "region": "10649", + "id": "63" + }, + { + "region": "10650", + "id": "63" + }, + { + "region": "10652", + "id": "316" + }, + { + "region": "10653", + "id": "295" + }, + { + "region": "10794", + "id": "306" + }, + { + "region": "10795", + "id": "305" + }, + { + "region": "10801", + "id": "164" + }, + { + "region": "10802", + "id": "115" + }, + { + "region": "10803", + "id": "91" + }, + { + "region": "10804", + "id": "192" + }, + { + "region": "10805", + "id": "184" + }, + { + "region": "10806", + "id": "7" + }, + { + "region": "10807", + "id": "21" + }, + { + "region": "10808", + "id": "293" + }, + { + "region": "10809", + "id": "291" + }, + { + "region": "10810", + "id": "291" + }, + { + "region": "10811", + "id": "291" + }, + { + "region": "10820", + "id": "563" + }, + { + "region": "10821", + "id": "282" + }, + { + "region": "10822", + "id": "278" + }, + { + "region": "10823", + "id": "278" + }, + { + "region": "10827", + "id": "146" + }, + { + "region": "10828", + "id": "378" + }, + { + "region": "10829", + "id": "378" + }, + { + "region": "10831", + "id": "393" + }, + { + "region": "10833", + "id": "249" + }, + { + "region": "10834", + "id": "240" + }, + { + "region": "10838", + "id": "442" + }, + { + "region": "10839", + "id": "442" + }, + { + "region": "10840", + "id": "444" + }, + { + "region": "10841", + "id": "444" + }, + { + "region": "10842", + "id": "444" + }, + { + "region": "10894", + "id": "312" + }, + { + "region": "10895", + "id": "311" + }, + { + "region": "10899", + "id": "362" + }, + { + "region": "10900", + "id": "362" + }, + { + "region": "10901", + "id": "364" + }, + { + "region": "10903", + "id": "17" + }, + { + "region": "10904", + "id": "192" + }, + { + "region": "10905", + "id": "63" + }, + { + "region": "10906", + "id": "88" + }, + { + "region": "10907", + "id": "340" + }, + { + "region": "10908", + "id": "340" + }, + { + "region": "10910", + "id": "274" + }, + { + "region": "10911", + "id": "548" + }, + { + "region": "11051", + "id": "303" + }, + { + "region": "11053", + "id": "129" + }, + { + "region": "11054", + "id": "114" + }, + { + "region": "11055", + "id": "117" + }, + { + "region": "11056", + "id": "58" + }, + { + "region": "11057", + "id": "55" + }, + { + "region": "11058", + "id": "6" + }, + { + "region": "11059", + "id": "347" + }, + { + "region": "11060", + "id": "324" + }, + { + "region": "11061", + "id": "74" + }, + { + "region": "11062", + "id": "104" + }, + { + "region": "11065", + "id": "356" + }, + { + "region": "11066", + "id": "4" + }, + { + "region": "11068", + "id": "335" + }, + { + "region": "11077", + "id": "277" + }, + { + "region": "11078", + "id": "282" + }, + { + "region": "11081", + "id": "5" + }, + { + "region": "11083", + "id": "65" + }, + { + "region": "11084", + "id": "378" + }, + { + "region": "11085", + "id": "378" + }, + { + "region": "11096", + "id": "444" + }, + { + "region": "11097", + "id": "444" + }, + { + "region": "11098", + "id": "444" + }, + { + "region": "11151", + "id": "307" + }, + { + "region": "11153", + "id": "265" + }, + { + "region": "11154", + "id": "114" + }, + { + "region": "11157", + "id": "248" + }, + { + "region": "11161", + "id": "19" + }, + { + "region": "11164", + "id": "341" + }, + { + "region": "11165", + "id": "357" + }, + { + "region": "11166", + "id": "261" + }, + { + "region": "11309", + "id": "172" + }, + { + "region": "11310", + "id": "90" + }, + { + "region": "11311", + "id": "165" + }, + { + "region": "11312", + "id": "162" + }, + { + "region": "11313", + "id": "172" + }, + { + "region": "11314", + "id": "170" + }, + { + "region": "11317", + "id": "119" + }, + { + "region": "11318", + "id": "87" + }, + { + "region": "11319", + "id": "9" + }, + { + "region": "11320", + "id": "187" + }, + { + "region": "11321", + "id": "257" + }, + { + "region": "11322", + "id": "292" + }, + { + "region": "11323", + "id": "294" + }, + { + "region": "11324", + "id": "569" + }, + { + "region": "11331", + "id": "553" + }, + { + "region": "11332", + "id": "564" + }, + { + "region": "11335", + "id": "504" + }, + { + "region": "11339", + "id": "52" + }, + { + "region": "11343", + "id": "491" + }, + { + "region": "11352", + "id": "444" + }, + { + "region": "11353", + "id": "444" + }, + { + "region": "11354", + "id": "444" + }, + { + "region": "11356", + "id": "442" + }, + { + "region": "11408", + "id": "365" + }, + { + "region": "11410", + "id": "90" + }, + { + "region": "11412", + "id": "162" + }, + { + "region": "11413", + "id": "336" + }, + { + "region": "11414", + "id": "25" + }, + { + "region": "11416", + "id": "179" + }, + { + "region": "11417", + "id": "19" + }, + { + "region": "11418", + "id": "100" + }, + { + "region": "11419", + "id": "100" + }, + { + "region": "11421", + "id": "261" + }, + { + "region": "11422", + "id": "369" + }, + { + "region": "11423", + "id": "396" + }, + { + "region": "11562", + "id": "304" + }, + { + "region": "11565", + "id": "78" + }, + { + "region": "11566", + "id": "94" + }, + { + "region": "11567", + "id": "89" + }, + { + "region": "11568", + "id": "479" + }, + { + "region": "11569", + "id": "92" + }, + { + "region": "11570", + "id": "138" + }, + { + "region": "11571", + "id": "107" + }, + { + "region": "11572", + "id": "186" + }, + { + "region": "11573", + "id": "18" + }, + { + "region": "11574", + "id": "77" + }, + { + "region": "11575", + "id": "149" + }, + { + "region": "11576", + "id": "258" + }, + { + "region": "11578", + "id": "292" + }, + { + "region": "11587", + "id": "564" + }, + { + "region": "11588", + "id": "564" + }, + { + "region": "11589", + "id": "524" + }, + { + "region": "11591", + "id": "242" + }, + { + "region": "11595", + "id": "57" + }, + { + "region": "11599", + "id": "482" + }, + { + "region": "11605", + "id": "232" + }, + { + "region": "11606", + "id": "442" + }, + { + "region": "11608", + "id": "442" + }, + { + "region": "11612", + "id": "442" + }, + { + "region": "11665", + "id": "30" + }, + { + "region": "11666", + "id": "103" + }, + { + "region": "11668", + "id": "129" + }, + { + "region": "11670", + "id": "138" + }, + { + "region": "11671", + "id": "53" + }, + { + "region": "11672", + "id": "173" + }, + { + "region": "11673", + "id": "178" + }, + { + "region": "11676", + "id": "153" + }, + { + "region": "11677", + "id": "264" + }, + { + "region": "11678", + "id": "395" + }, + { + "region": "11821", + "id": "162" + }, + { + "region": "11823", + "id": "166" + }, + { + "region": "11824", + "id": "515" + }, + { + "region": "11825", + "id": "180" + }, + { + "region": "11826", + "id": "12" + }, + { + "region": "11827", + "id": "127" + }, + { + "region": "11828", + "id": "72" + }, + { + "region": "11829", + "id": "54" + }, + { + "region": "11831", + "id": "34" + }, + { + "region": "11832", + "id": "435" + }, + { + "region": "11833", + "id": "183" + }, + { + "region": "11834", + "id": "43" + }, + { + "region": "11835", + "id": "37" + }, + { + "region": "11837", + "id": "52" + }, + { + "region": "11853", + "id": "402" + }, + { + "region": "11864", + "id": "443" + }, + { + "region": "11865", + "id": "443" + }, + { + "region": "11866", + "id": "443" + }, + { + "region": "11924", + "id": "576" + }, + { + "region": "11925", + "id": "108" + }, + { + "region": "11926", + "id": "490" + }, + { + "region": "11929", + "id": "325" + }, + { + "region": "11930", + "id": "582" + }, + { + "region": "11936", + "id": "52" + }, + { + "region": "11937", + "id": "52" + }, + { + "region": "12078", + "id": "549" + }, + { + "region": "12079", + "id": "62" + }, + { + "region": "12080", + "id": "62" + }, + { + "region": "12081", + "id": "105" + }, + { + "region": "12082", + "id": "35" + }, + { + "region": "12083", + "id": "49" + }, + { + "region": "12084", + "id": "15" + }, + { + "region": "12085", + "id": "310" + }, + { + "region": "12086", + "id": "102" + }, + { + "region": "12087", + "id": "96" + }, + { + "region": "12088", + "id": "160" + }, + { + "region": "12089", + "id": "66" + }, + { + "region": "12090", + "id": "159" + }, + { + "region": "12091", + "id": "42" + }, + { + "region": "12092", + "id": "475" + }, + { + "region": "12093", + "id": "334" + }, + { + "region": "12100", + "id": "236" + }, + { + "region": "12102", + "id": "633" + }, + { + "region": "12105", + "id": "505" + }, + { + "region": "12107", + "id": "412" + }, + { + "region": "12108", + "id": "412" + }, + { + "region": "12109", + "id": "402" + }, + { + "region": "12111", + "id": "403" + }, + { + "region": "12115", + "id": "86" + }, + { + "region": "12117", + "id": "304" + }, + { + "region": "12120", + "id": "443" + }, + { + "region": "12121", + "id": "443" + }, + { + "region": "12122", + "id": "443" + }, + { + "region": "12181", + "id": "529" + }, + { + "region": "12184", + "id": "325" + }, + { + "region": "12186", + "id": "570" + }, + { + "region": "12187", + "id": "585" + }, + { + "region": "12192", + "id": "26" + }, + { + "region": "12193", + "id": "68" + }, + { + "region": "12335", + "id": "62" + }, + { + "region": "12336", + "id": "62" + }, + { + "region": "12337", + "id": "85" + }, + { + "region": "12338", + "id": "3" + }, + { + "region": "12339", + "id": "151" + }, + { + "region": "12340", + "id": "333" + }, + { + "region": "12341", + "id": "141" + }, + { + "region": "12342", + "id": "98" + }, + { + "region": "12343", + "id": "113" + }, + { + "region": "12344", + "id": "8" + }, + { + "region": "12345", + "id": "176" + }, + { + "region": "12346", + "id": "435" + }, + { + "region": "12349", + "id": "13" + }, + { + "region": "12354", + "id": "494" + }, + { + "region": "12367", + "id": "441" + }, + { + "region": "12376", + "id": "443" + }, + { + "region": "12377", + "id": "443" + }, + { + "region": "12378", + "id": "443" + }, + { + "region": "12436", + "id": "85" + }, + { + "region": "12437", + "id": "144" + }, + { + "region": "12438", + "id": "361" + }, + { + "region": "12440", + "id": "338" + }, + { + "region": "12441", + "id": "141" + }, + { + "region": "12442", + "id": "98" + }, + { + "region": "12589", + "id": "352" + }, + { + "region": "12590", + "id": "263" + }, + { + "region": "12591", + "id": "79" + }, + { + "region": "12593", + "id": "64" + }, + { + "region": "12594", + "id": "327" + }, + { + "region": "12595", + "id": "163" + }, + { + "region": "12596", + "id": "116" + }, + { + "region": "12597", + "id": "175" + }, + { + "region": "12598", + "id": "496" + }, + { + "region": "12599", + "id": "56" + }, + { + "region": "12600", + "id": "10" + }, + { + "region": "12601", + "id": "476" + }, + { + "region": "12602", + "id": "67" + }, + { + "region": "12603", + "id": "449" + }, + { + "region": "12604", + "id": "332" + }, + { + "region": "12605", + "id": "106" + }, + { + "region": "12610", + "id": "493" + }, + { + "region": "12610", + "id": "493" + }, + { + "region": "12614", + "id": "572" + }, + { + "region": "12615", + "id": "214" + }, + { + "region": "12619", + "id": "418" + }, + { + "region": "12623", + "id": "441" + }, + { + "region": "12625", + "id": "272" + }, + { + "region": "12693", + "id": "389" + }, + { + "region": "12694", + "id": "343" + }, + { + "region": "12696", + "id": "528" + }, + { + "region": "12697", + "id": "330" + }, + { + "region": "12698", + "id": "144" + }, + { + "region": "12843", + "id": "383" + }, + { + "region": "12846", + "id": "267" + }, + { + "region": "12848", + "id": "124" + }, + { + "region": "12849", + "id": "145" + }, + { + "region": "12850", + "id": "76" + }, + { + "region": "12851", + "id": "2" + }, + { + "region": "12852", + "id": "106" + }, + { + "region": "12853", + "id": "125" + }, + { + "region": "12854", + "id": "177" + }, + { + "region": "12855", + "id": "169" + }, + { + "region": "12856", + "id": "337" + }, + { + "region": "12857", + "id": "332" + }, + { + "region": "12858", + "id": "120" + }, + { + "region": "12861", + "id": "127" + }, + { + "region": "12880", + "id": "441" + }, + { + "region": "12888", + "id": "445" + }, + { + "region": "12889", + "id": "445" + }, + { + "region": "12890", + "id": "445" + }, + { + "region": "12944", + "id": "606" + }, + { + "region": "12945", + "id": "359" + }, + { + "region": "12946", + "id": "266" + }, + { + "region": "12948", + "id": "397" + }, + { + "region": "12949", + "id": "108" + }, + { + "region": "12950", + "id": "46" + }, + { + "region": "12952", + "id": "106" + }, + { + "region": "12953", + "id": "125" + }, + { + "region": "12956", + "id": "569" + }, + { + "region": "13099", + "id": "383" + }, + { + "region": "13100", + "id": "387" + }, + { + "region": "13102", + "id": "174" + }, + { + "region": "13104", + "id": "69" + }, + { + "region": "13105", + "id": "50" + }, + { + "region": "13106", + "id": "36" + }, + { + "region": "13107", + "id": "123" + }, + { + "region": "13108", + "id": "111" + }, + { + "region": "13109", + "id": "157" + }, + { + "region": "13110", + "id": "93" + }, + { + "region": "13111", + "id": "121" + }, + { + "region": "13113", + "id": "14" + }, + { + "region": "13114", + "id": "182" + }, + { + "region": "13115", + "id": "182" + }, + { + "region": "13116", + "id": "331" + }, + { + "region": "13117", + "id": "329" + }, + { + "region": "13131", + "id": "428" + }, + { + "region": "13133", + "id": "552" + }, + { + "region": "13135", + "id": "441" + }, + { + "region": "13141", + "id": "272" + }, + { + "region": "13142", + "id": "459" + }, + { + "region": "13144", + "id": "445" + }, + { + "region": "13145", + "id": "445" + }, + { + "region": "13146", + "id": "445" + }, + { + "region": "13199", + "id": "388" + }, + { + "region": "13200", + "id": "213" + }, + { + "region": "13203", + "id": "168" + }, + { + "region": "13206", + "id": "407" + }, + { + "region": "13209", + "id": "594" + }, + { + "region": "13356", + "id": "505" + }, + { + "region": "13357", + "id": "267" + }, + { + "region": "13358", + "id": "351" + }, + { + "region": "13359", + "id": "174" + }, + { + "region": "13361", + "id": "50" + }, + { + "region": "13362", + "id": "47" + }, + { + "region": "13363", + "id": "122" + }, + { + "region": "13364", + "id": "75" + }, + { + "region": "13365", + "id": "20" + }, + { + "region": "13366", + "id": "93" + }, + { + "region": "13368", + "id": "179" + }, + { + "region": "13369", + "id": "326" + }, + { + "region": "13373", + "id": "586" + }, + { + "region": "13400", + "id": "445" + }, + { + "region": "13401", + "id": "445" + }, + { + "region": "13402", + "id": "445" + }, + { + "region": "13456", + "id": "452" + }, + { + "region": "13457", + "id": "464" + }, + { + "region": "13458", + "id": "540" + }, + { + "region": "13459", + "id": "540" + }, + { + "region": "13461", + "id": "462" + }, + { + "region": "13463", + "id": "534" + }, + { + "region": "13464", + "id": "45" + }, + { + "region": "13465", + "id": "45" + }, + { + "region": "13611", + "id": "451" + }, + { + "region": "13613", + "id": "447" + }, + { + "region": "13614", + "id": "465" + }, + { + "region": "13616", + "id": "377" + }, + { + "region": "13617", + "id": "36" + }, + { + "region": "13618", + "id": "286" + }, + { + "region": "13619", + "id": "154" + }, + { + "region": "13620", + "id": "245" + }, + { + "region": "13621", + "id": "84" + }, + { + "region": "13622", + "id": "48" + }, + { + "region": "13623", + "id": "339" + }, + { + "region": "13642", + "id": "411" + }, + { + "region": "13712", + "id": "452" + }, + { + "region": "13718", + "id": "11" + }, + { + "region": "13720", + "id": "246" + }, + { + "region": "13722", + "id": "156" + }, + { + "region": "13723", + "id": "514" + }, + { + "region": "13872", + "id": "377" + }, + { + "region": "13873", + "id": "501" + }, + { + "region": "13875", + "id": "286" + }, + { + "region": "13876", + "id": "241" + }, + { + "region": "13877", + "id": "244" + }, + { + "region": "13878", + "id": "61" + }, + { + "region": "13879", + "id": "344" + }, + { + "region": "13899", + "id": "146" + }, + { + "region": "13968", + "id": "539" + }, + { + "region": "13972", + "id": "260" + }, + { + "region": "13975", + "id": "287" + }, + { + "region": "13977", + "id": "319" + }, + { + "region": "13979", + "id": "342" + }, + { + "region": "14131", + "id": "380" + }, + { + "region": "14134", + "id": "288" + }, + { + "region": "14155", + "id": "146" + }, + { + "region": "14157", + "id": "379" + }, + { + "region": "14158", + "id": "379" + }, + { + "region": "14167", + "id": "562" + }, + { + "region": "14231", + "id": "381" + }, + { + "region": "14234", + "id": "345" + }, + { + "region": "14391", + "id": "353" + }, + { + "region": "14413", + "id": "379" + }, + { + "region": "14414", + "id": "379" + }, + { + "region": "14486", + "id": "197" + }, + { + "region": "14488", + "id": "521" + }, + { + "region": "14638", + "id": "530" + }, + { + "region": "14646", + "id": "355" + }, + { + "region": "14746", + "id": "354" + }, + { + "region": "14747", + "id": "471" + }, + { + "region": "14894", + "id": "631" + }, + { + "region": "14994", + "id": "632" + }, + { + "region": "14995", + "id": "632" + }, + { + "region": "15148", + "id": "238" + }, + { + "region": "15150", + "id": "611" + }, + { + "region": "15151", + "id": "610" + }, + { + "region": "15159", + "id": "358" + }, + { + "region": "15248", + "id": "238" + }, + { + "region": "15251", + "id": "632" + } +] \ No newline at end of file diff --git a/Server/data/configs/music_tiles.json b/Server/data/configs/music_tiles.json new file mode 100644 index 000000000..7b901f974 --- /dev/null +++ b/Server/data/configs/music_tiles.json @@ -0,0 +1,62 @@ +[ + { + "id": "98", + "borders": "{3072,3456,3135,3519,[3076,3456,3085,3458]~,[3082,3459,3085,3460]}" + }, + { + "id": "141", + "borders": "{3072,3392,3135,3455,[3076,3452,3085,3455]}" + }, + { + "id": "228", + "borders": "{2896,5446,2919,5462}" + }, + { + "id": "229", + "borders": "{2921,5456,2937,5479}" + }, + { + "id": "230", + "borders": "{2904,5481,2927,5497}" + }, + { + "id": "231", + "borders": "{2886,5464,2902,5487}" + }, + { + "id": "386", + "borders": "{2820,5312,2849,5369}-{2849,5349,2880,5374}" + }, + { + "id": "391", + "borders": "{2879,5340,2944,5366}-{2909,5316,2944,5340}" + }, + { + "id": "399", + "borders": "{2816,5248,2943,5375,[2823,5250,2844,5310]~,[2844,5250,2878,5280]~,[2879,5340,2944,5366]~,[2909,5316,2944,5340]~,[2820,5312,2849,5369]~,[2849,5349,2880,5374]~,[2885,5253,2934,5278]~,[2913,5278,2937,5306]}" + }, + { + "id": "404", + "borders": "{2823,5250,2844,5310}-{2844,5250,2878,5276}" + }, + { + "id": "408", + "borders": "{2885,5253,2934,5278}-{2913,5278,2937,5306}" + }, + { + "id": "459", + "borders": "{3137,5442,3192,5564}-{3193,5442,3198,5472}-{3193,5507,3198,5564}" + }, + { + "id": "467", + "borders": "{3199,5441,3262,5564}-{3193,5482,3198,5497}" + }, + { + "id": "488", + "borders": "{3263,5441,3327,5566}" + }, + { + "id": "492", + "borders": "{3076,3452,3085,3460,[3076,3459,3081,3460]}" + } +] \ No newline at end of file diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json index dce10e733..44c10bdcb 100644 --- a/Server/data/configs/npc_configs.json +++ b/Server/data/configs/npc_configs.json @@ -1,72628 +1,88129 @@ [ { - "examine": "Servant of the Duke of Lumbridge.", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "4", - "magic_level": "22", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Hans", - "defence_level": "14", - "safespot": "0", - "lifepoints": "12", - "strength_level": "17", "id": "0", - "range_level": "1", - "attack_level": "17" - }, - { - "examine": "One of Gielinor's many citizens.", + "name": "Hans", + "examine": "Servant of the Duke of Lumbridge.", + "attack_level": "17", + "attack_speed": "4", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "14", + "lifepoints": "12", + "magic_animation": "422", + "magic_level": "22", "melee_animation": "422", "range_animation": "422", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "6", - "respawn_delay": "18", - "defence_animation": "404", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "422", - "death_animation": "9055", - "name": "Man", - "defence_level": "5", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", + "range_level": "1", + "safespot": "0", + "strength_level": "17" + }, + { "id": "1", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "9055", "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", + "attack_level": "5", + "attack_speed": "4", + "clue_level": "0", "combat_audio": "511,513,512", - "attack_speed": "4", - "defence_animation": "404", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "422", "death_animation": "9055", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "4", "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "9055", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "4", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "9055", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "1", - "id": "6", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "He grows the crops in this area.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Farmer", "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "7", + "lifepoints": "10", + "magic_animation": "422", + "magic_level": "6", + "melee_animation": "422", + "range_animation": "422", "range_level": "1", - "attack_level": "5" + "respawn_delay": "18", + "safespot": null, + "slayer_exp": "0", + "strength_level": "2", + "weakness": "9" }, { - "examine": "Known for his light-fingered qualities.", + "id": "2", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "4", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "3", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "3", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "4", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "3", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1", + "weakness": "9" + }, + { + "id": "4", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "4", + "clue_level": "0", + "combat_audio": "511,506,505", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "3", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "4", + "clue_level": "0", + "combat_audio": "511,506,505", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "3", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "6", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", "melee_animation": "422", "range_animation": "0", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "8", "range_level": "1", - "attack_level": "10" + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" }, { + "id": "7", + "name": "Farmer", + "examine": "He grows the crops in this area.", + "attack_level": "5", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "9" + }, + { + "id": "8", + "name": "Thief", + "examine": "Known for his light-fingered qualities.", + "attack_level": "10", + "attack_speed": "4", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "10", + "weakness": "9" + }, + { + "id": "9", + "name": "Guard", "examine": "He tries to keep order around here.", + "attack_level": "13", + "attack_speed": "4", + "clue_level": "1", + "combat_audio": "2549,1979,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", "melee_animation": "400", "range_animation": "0", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "9", - "clue_level": "1", "range_level": "1", - "attack_level": "13" + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "9" }, { + "id": "10", + "name": "Schoolgirl", "examine": "She looks happy.", + "attack_level": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "1142", - "defence_animation": "285", - "magic_animation": "0", - "death_animation": "287", - "name": "Schoolgirl", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "10", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "11", + "name": "Tramp", "examine": "A man down on his luck.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tramp", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "11", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { - "examine": "Not very civilised looking.", - "name": "Barbarian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "12", + "name": "Barbarian", + "examine": "Not very civilised looking.", + "attack_level": "1", "clue_level": "0", + "defence_level": "1", + "lifepoints": "10", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { - "examine": "Slightly magical.", - "start_gfx": "2728", - "combat_style": "2", - "melee_animation": "2791", - "range_animation": "711", - "combat_audio": "511,513,512", - "magic_level": "21", - "respawn_delay": "12", - "end_gfx": "2737", - "defence_animation": "404", - "weakness": "3", - "slayer_exp": "0", - "magic_animation": "711", - "death_animation": "9055", - "name": "Wizard", - "defence_level": "12", - "safespot": null, - "lifepoints": "14", - "strength_level": "1", "id": "13", + "name": "Wizard", + "examine": "Slightly magical.", + "attack_level": "1", "bonuses": "23,7,8,2,1,8,12,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "2729", - "attack_level": "1" - }, - { - "examine": "Loves nature.", "combat_audio": "511,513,512", - "range_animation": "0", - "melee_animation": "422", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", + "combat_style": "2", + "death_animation": "9055", "defence_animation": "404", + "defence_level": "12", + "end_gfx": "2737", + "lifepoints": "14", "magic_animation": "711", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "14", + "magic_level": "21", + "melee_animation": "2791", + "projectile": "2729", + "range_animation": "711", "range_level": "1", - "attack_level": "28" + "respawn_delay": "12", + "safespot": null, + "slayer_exp": "0", + "start_gfx": "2728", + "strength_level": "1", + "weakness": "3" }, { + "id": "14", + "name": "Druid", + "examine": "Loves nature.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "defence_animation": "404", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28" + }, + { + "id": "15", + "name": "Warrior woman", "examine": "Not very fashion conscious.", + "attack_level": "22", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "20", + "magic_animation": "0", "melee_animation": "386", "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Warrior woman", - "defence_level": "22", - "safespot": null, - "lifepoints": "20", - "strength_level": "22", - "id": "15", "range_level": "1", - "attack_level": "22" + "safespot": null, + "strength_level": "22", + "weakness": "7" }, { + "id": "16", + "name": "Man", "examine": "One of the citizens of Al Kharid.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", "melee_animation": "422", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "16", - "clue_level": "0", "range_level": "1", - "attack_level": "3" + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "7" }, { + "id": "17", + "name": "Schoolgirl" + }, + { + "id": "18", + "name": "Al-Kharid warrior", "examine": "Part of Al-Kharid's elite fighting force.", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "10,10,10,0,0,12,15,10,-1,12,0,9,0,0,0", + "clue_level": "0", + "combat_audio": "2500,1976,512", + "death_animation": "836", + "defence_animation": "387", + "defence_level": "4", + "lifepoints": "19", + "magic_animation": "390", "melee_animation": "390", "range_animation": "390", - "combat_audio": "2500,1976,512", - "attack_speed": "4", - "respawn_delay": "25", - "defence_animation": "387", - "weakness": "7", - "magic_animation": "390", - "death_animation": "836", - "name": "Al-Kharid warrior", - "defence_level": "4", - "safespot": null, - "lifepoints": "19", - "strength_level": "5", - "id": "18", - "clue_level": "0", - "bonuses": "10,10,10,0,0,12,15,10,-1,12,0,9,0,0,0", "range_level": "1", - "attack_level": "7" + "respawn_delay": "25", + "safespot": null, + "strength_level": "5", + "weakness": "7" }, { + "id": "19", + "name": "White Knight", "examine": "Shiny armour!", + "attack_level": "25", + "attack_speed": "8", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", "melee_animation": "7042", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "8", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "White Knight", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "19", "range_level": "1", - "attack_level": "25" + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "7" }, { - "examine": "A holy warrior.", - "melee_animation": "390", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Paladin", - "defence_level": "54", - "safespot": null, - "lifepoints": "66", - "strength_level": "54", "id": "20", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "Heroic!", - "melee_animation": "390", - "range_animation": "0", + "name": "Paladin", + "examine": "A holy warrior.", + "attack_level": "54", "attack_speed": "5", - "respawn_delay": "60", + "combat_audio": "511,513,512", + "death_animation": "836", "defence_animation": "425", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Hero", "defence_level": "54", + "lifepoints": "66", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", "safespot": null, - "lifepoints": "82", - "strength_level": "55", + "strength_level": "54" + }, + { "id": "21", + "name": "Hero", + "examine": "Heroic!", + "attack_level": "54", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "54", + "lifepoints": "82", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", "range_level": "1", - "attack_level": "54" + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "7" }, { - "examine": "They love the forests.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "respawn_delay": "18", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Forester", - "defence_level": "8", - "safespot": null, - "lifepoints": "17", - "strength_level": "13", "id": "22", - "range_level": "1", - "attack_level": "14" - }, - { - "examine": "A member of Ardougne's militia.", - "melee_animation": "390", - "range_animation": "0", + "name": "Forester", + "examine": "They love the forests.", + "attack_level": "14", + "attack_speed": "4", "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Knight of Ardougne", - "defence_level": "31", - "safespot": null, - "lifepoints": "52", - "strength_level": "40", - "id": "23", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "24", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "25", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "To protect and serve the populace of Ardougne.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Knight of Ardougne", - "defence_level": "31", - "safespot": null, - "lifepoints": "52", - "strength_level": "40", - "id": "26", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "Good with arrows.", - "start_gfx": "19", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "12", - "defence_animation": "404", - "magic_animation": "426", "death_animation": "9055", - "name": "Archer", - "defence_level": "20", - "safespot": null, - "lifepoints": "50", - "strength_level": "20", - "id": "27", - "range_level": "40", - "projectile": "10", - "attack_level": "20" - }, - { - "examine": "Enjoys locking up animals in small pens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", + "defence_animation": "404", + "defence_level": "8", + "lifepoints": "17", "magic_animation": "0", - "death_animation": "0", - "name": "Zoo keeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "28", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's a lumberjack, and he's ok.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chuck", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "29", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Doesn't water down the beer too much.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "30", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Priest", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "31", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Keeps the peace... kind of.", - "melee_animation": "401", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "22", - "strength_level": "18", - "id": "32", - "clue_level": "1", - "range_level": "1", - "attack_level": "17" - }, - { - "examine": "What a boring job he has.", - "name": "Door man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "33", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Watches stuff. But who watches him?", "melee_animation": "422", "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Watchman", - "defence_level": "31", - "safespot": null, - "lifepoints": "22", - "strength_level": "31", - "id": "34", "range_level": "1", - "attack_level": "31" + "respawn_delay": "18", + "safespot": null, + "strength_level": "13" }, { - "examine": "A soldier of the town of Yanille.", + "id": "23", + "name": "Knight of Ardougne", + "examine": "A member of Ardougne's militia.", + "attack_level": "38", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "52", + "magic_animation": "0", "melee_animation": "390", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "24", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,513,512", "death_animation": "836", - "name": "Soldier", - "defence_level": "26", - "safespot": null, - "lifepoints": "22", - "strength_level": "25", - "id": "35", - "range_level": "1", - "attack_level": "26" - }, - { - "examine": "The head gardener.", - "melee_animation": "0", - "range_animation": "0", "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", "magic_animation": "0", - "death_animation": "0", - "name": "Wyson the gardener", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "36", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bold knight famed for his travels.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sigbert the Adventurer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "37", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Builds ships for a living.", "melee_animation": "422", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Shipyard worker", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "10", - "id": "38", "range_level": "1", - "attack_level": "10" + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" }, { - "examine": "Builds ships for a living.", - "melee_animation": "401", + "id": "25", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "422", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Shipyard worker", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "10", - "id": "39", "range_level": "1", - "attack_level": "10" + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" }, { - "examine": "Let's not go skinny dipping eh?", + "id": "26", + "name": "Knight of Ardougne", + "examine": "To protect and serve the populace of Ardougne.", + "attack_level": "38", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "52", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "27", + "name": "Archer", + "examine": "Good with arrows.", + "attack_level": "20", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "20", + "lifepoints": "50", + "magic_animation": "426", + "melee_animation": "426", + "projectile": "10", + "range_animation": "426", + "range_level": "40", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "19", + "strength_level": "20" + }, + { + "id": "28", + "name": "Zoo keeper", + "examine": "Enjoys locking up animals in small pens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shark", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "40", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "29", + "name": "Chuck", + "examine": "He's a lumberjack, and he's ok.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "30", + "name": "Barman", + "examine": "Doesn't water down the beer too much.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "31", + "name": "Priest", + "examine": "A holy man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "32", + "name": "Guard", + "examine": "Keeps the peace... kind of.", + "attack_level": "17", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "22", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "18", + "weakness": "9" + }, + { + "id": "33", + "name": "Door man", + "examine": "What a boring job he has.", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "34", + "name": "Watchman", + "examine": "Watches stuff. But who watches him?", + "attack_level": "31", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "22", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "31", + "weakness": "7" + }, + { + "id": "35", + "name": "Soldier", + "examine": "A soldier of the town of Yanille.", + "attack_level": "26", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "22", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "8" + }, + { + "id": "36", + "name": "Wyson the gardener", + "examine": "The head gardener.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "37", + "name": "Sigbert the Adventurer", + "examine": "A bold knight famed for his travels.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "38", + "name": "Shipyard worker", + "examine": "Builds ships for a living.", + "attack_level": "10", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "10", + "weakness": "6" + }, + { + "id": "39", + "name": "Shipyard worker", + "examine": "Builds ships for a living.", + "attack_level": "10", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "10", + "weakness": "6" + }, + { + "id": "40", + "name": "Shark", + "examine": "Let's not go skinny dipping eh?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "41", + "name": "Chicken", "examine": "Yep. Definitely a chicken.", - "slayer_task": "7", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", "melee_animation": "5387", "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", + "range_level": "1", "respawn_delay": "18", - "defence_animation": "5388", - "weakness": "9", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", "safespot": null, - "lifepoints": "3", "strength_level": "1", - "id": "41", - "range_level": "1", - "attack_level": "1" + "weakness": "9" }, { - "examine": "Freshly sheared.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "42", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", "name": "Sheep", + "examine": "Freshly sheared.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", "defence_level": "1", - "safespot": null, "lifepoints": "10", - "strength_level": "1", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { "id": "43", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can look after my money.", + "name": "Sheep", + "examine": "White and fluffy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "44", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "45", + "examine": "He can look after my money.", "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Quackers.", - "slayer_task": "7", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "3468", - "name": "Duck", - "defence_level": "1", - "water_npc": "true", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "46", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "45", + "name": "Banker", + "examine": "She can look after my money.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "46", + "name": "Duck", + "examine": "Quackers.", + "attack_level": "1", + "death_animation": "3468", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "water_npc": "true", + "weakness": "8" + }, + { + "id": "47", + "name": "Rat", "examine": "A popular dwarven delicacy.", - "slayer_task": "67", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,-42,-53,0,0,0", + "combat_audio": "3102,3104,3103", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "2705", + "magic_level": "1", "melee_animation": "2705", "range_animation": "2705", - "combat_audio": "3102,3104,3103", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "3", - "defence_animation": "2706", - "slayer_exp": "2", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "47", - "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,-42,-53,0,0,0", "range_level": "1", - "attack_level": "1" + "respawn_delay": "3", + "safespot": null, + "slayer_exp": "2", + "strength_level": "1" }, { + "id": "48", + "name": "Oomlie bird", "examine": "A jungle version of the chicken, but more vicious.", - "slayer_task": "7", + "attack_level": "40", + "attack_speed": "4", + "death_animation": "5389", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "40", + "magic_animation": "0", "melee_animation": "5387", "range_animation": "0", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5389", - "name": "Oomlie bird", - "defence_level": "40", - "safespot": null, - "lifepoints": "40", - "strength_level": "40", - "id": "48", "range_level": "1", - "attack_level": "40" + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "9" }, { + "id": "49", + "name": "Hellhound", "examine": "Hello, nice doggy...", - "slayer_task": "43", + "aggressive": "true", + "attack_level": "105", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "3717,3719,3718", + "death_animation": "6564", + "defence_animation": "6563", + "defence_level": "102", + "lifepoints": "116", + "magic_animation": "6562", "melee_animation": "6562", "range_animation": "6562", - "combat_audio": "3717,3719,3718", - "attack_speed": "4", - "respawn_delay": "50", - "defence_animation": "6563", - "weakness": "1", - "slayer_exp": "116", - "magic_animation": "6562", - "death_animation": "6564", - "name": "Hellhound", - "defence_level": "102", - "safespot": null, - "lifepoints": "116", - "strength_level": "104", - "id": "49", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "range_level": "1", - "attack_level": "105" + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "116", + "strength_level": "104", + "weakness": "1" }, { - "agg_radius": "64", - "examine": "The biggest, meanest dragon around.", - "slayer_task": "9", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "magic_level": "240", - "respawn_delay": "50", - "defence_animation": "89", - "weakness": "4", - "slayer_exp": "258", - "magic_animation": "80", - "death_animation": "92", - "name": "King Black Dragon", - "defence_level": "240", - "safespot": null, - "lifepoints": "240", - "strength_level": "240", "id": "50", + "name": "King Black Dragon", + "examine": "The biggest, meanest dragon around.", + "agg_radius": "64", "aggressive": "true", + "attack_level": "240", "bonuses": "0,0,0,0,0,70,90,90,80,70,0,0,0,0,0", "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "240", + "lifepoints": "240", + "magic_animation": "80", + "magic_level": "240", + "melee_animation": "80", + "range_animation": "80", "range_level": "1", - "attack_level": "240" + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "258", + "strength_level": "240", + "weakness": "4" }, { - "examine": "Young but still dangerous.", - "combat_audio": "407,405,406", - "magic_level": "116", - "respawn_delay": "25", - "weakness": "0", - "name": "Baby dragon", - "defence_level": "112", - "safespot": null, - "lifepoints": "160", - "strength_level": "103", "id": "51", - "aggressive": "true", - "bonuses": "124,130,137,184,176,128,168,145,104,54,0,0,0,0,0", - "range_level": "80", - "attack_level": "102" - }, - { + "name": "Baby dragon", "examine": "Young but still dangerous.", - "slayer_task": "11", - "combat_audio": "405,407,406", - "melee_animation": "25", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "26", - "weakness": "3", - "slayer_exp": "50", - "magic_animation": "25", - "death_animation": "28", - "name": "Baby blue dragon", - "defence_level": "40", + "aggressive": "true", + "attack_level": "102", + "bonuses": "124,130,137,184,176,128,168,145,104,54,0,0,0,0,0", + "combat_audio": "407,405,406", + "defence_level": "112", + "lifepoints": "160", + "magic_level": "116", + "range_level": "80", + "respawn_delay": "25", "safespot": null, - "lifepoints": "50", - "strength_level": "40", + "strength_level": "103", + "weakness": "0" + }, + { "id": "52", + "name": "Baby blue dragon", + "examine": "Young but still dangerous.", "aggressive": "true", + "attack_level": "40", + "attack_speed": "4", "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", + "combat_audio": "405,407,406", + "death_animation": "28", + "defence_animation": "26", + "defence_level": "40", + "lifepoints": "50", + "magic_animation": "25", + "magic_level": "1", + "melee_animation": "25", "range_level": "1", - "attack_level": "40" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "50", + "strength_level": "40", + "weakness": "3" }, { - "examine": "A big powerful dragon.", - "slayer_task": "68", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "143", - "magic_animation": "80", - "death_animation": "92", - "name": "Red dragon", - "defence_level": "130", - "safespot": null, - "lifepoints": "140", - "strength_level": "130", "id": "53", + "name": "Red dragon", + "examine": "A big powerful dragon.", "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", "clue_level": "2", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "A fierce dragon with black scales!", - "slayer_task": "9", - "melee_animation": "80", - "range_animation": "80", "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "200", - "magic_animation": "80", "death_animation": "92", - "name": "Black dragon", - "defence_level": "200", - "safespot": null, - "lifepoints": "190", - "strength_level": "200", - "id": "54", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "200" - }, - { - "examine": "A mother dragon.", - "slayer_task": "11", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", + "defence_animation": "89", + "defence_level": "130", + "lifepoints": "140", + "magic_animation": "80", "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "108", - "magic_animation": "80", - "death_animation": "92", - "name": "Blue dragon", - "defence_level": "95", "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "55", + "slayer_exp": "143", + "strength_level": "130", + "weakness": "3" + }, + { + "id": "54", + "name": "Black dragon", + "examine": "A fierce dragon with black scales!", "aggressive": "true", + "attack_level": "200", + "attack_speed": "4", "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "200", + "lifepoints": "190", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", "range_level": "1", - "attack_level": "95" + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "200", + "strength_level": "200", + "weakness": "3" }, { - "examine": "A wood nymph.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dryad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "56", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A delicate creature from this strange realm.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "57", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is it a spider or is it a shadow?", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "0", - "combat_audio": "537,539,538", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "55", - "magic_animation": "0", - "death_animation": "5329", - "name": "Shadow spider", - "defence_level": "44", - "safespot": null, - "lifepoints": "55", - "strength_level": "42", - "id": "58", + "id": "55", + "name": "Blue dragon", + "examine": "A mother dragon.", "aggressive": "true", + "attack_level": "95", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "95", + "lifepoints": "105", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", "range_level": "1", - "attack_level": "44" + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "108", + "strength_level": "95", + "weakness": "3" }, { - "examine": "I think this spider has been genetically modified.", - "slayer_task": "76", + "id": "56", + "name": "Dryad", + "examine": "A wood nymph.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "57", + "name": "Fairy", + "examine": "A delicate creature from this strange realm.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "58", + "name": "Shadow spider", + "examine": "Is it a spider or is it a shadow?", + "aggressive": "true", + "attack_level": "44", + "attack_speed": "4", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "55", + "magic_animation": "0", "melee_animation": "5327", "range_animation": "0", - "combat_audio": "537,539,538", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "5", - "magic_animation": "0", - "death_animation": "5329", - "name": "Giant spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "59", - "aggressive": "false", "range_level": "1", - "attack_level": "1" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "55", + "strength_level": "42", + "weakness": "2" }, { + "id": "59", + "name": "Giant spider", "examine": "I think this spider has been genetically modified.", - "slayer_task": "76", + "aggressive": "false", + "attack_level": "1", + "attack_speed": "4", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "5327", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "5", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "60", + "name": "Giant spider", + "examine": "I think this spider has been genetically modified.", + "aggressive": "true", + "attack_level": "20", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "21", + "lifepoints": "32", + "magic_animation": "5327", "melee_animation": "5327", "range_animation": "5327", - "combat_audio": "537,539,538", - "defence_animation": "5328", - "weakness": "2", - "slayer_exp": "33", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Giant spider", - "defence_level": "21", - "safespot": null, - "lifepoints": "32", - "strength_level": "24", - "id": "60", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "range_level": "1", - "attack_level": "20" + "safespot": null, + "slayer_exp": "33", + "strength_level": "24", + "weakness": "2" }, { + "id": "61", + "name": "Spider", "examine": "Incey wincey.", - "slayer_task": "76", + "aggressive": "true", + "attack_level": "1", + "death_animation": "6251", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "0", "melee_animation": "6249", "range_animation": "0", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", + "safespot": null, "slayer_exp": "2", - "magic_animation": "0", - "death_animation": "6251", - "name": "Spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", "strength_level": "1", - "id": "61", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" + "weakness": "2" }, { - "examine": "A barely visible deadly jungle spider.", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "5327", - "combat_audio": "537,539,538", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "5328", - "weakness": "2", - "slayer_exp": "50", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Jungle spider", - "defence_level": "35", - "poison_immune": "false", - "safespot": null, - "lifepoints": "50", - "strength_level": "37", "id": "62", + "name": "Jungle spider", + "examine": "A barely visible deadly spider.", "aggressive": "true", + "attack_level": "35", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "5327", + "magic_level": "1", + "melee_animation": "5327", + "poison_immune": "false", + "range_animation": "5327", "range_level": "1", - "attack_level": "35" + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "50", + "strength_level": "37", + "weakness": "2" }, { + "id": "63", + "name": "Deadly red spider", "examine": "I think this spider has been genetically modified.", - "slayer_task": "76", + "attack_level": "30", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,15,16,7,12,16,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "30", + "lifepoints": "35", + "magic_animation": "5327", + "magic_level": "1", "melee_animation": "5327", "range_animation": "5327", - "combat_audio": "537,539,538", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "5328", - "weakness": "2", - "slayer_exp": "35", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Deadly red spider", - "defence_level": "30", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "63", - "bonuses": "0,0,0,0,0,0,15,16,7,12,16,0,0,0,0", "range_level": "1", - "attack_level": "30" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "35", + "strength_level": "25", + "weakness": "2" }, { + "id": "64", + "name": "Ice spider", "examine": "I think this spider has been genetically modified.", - "slayer_task": "76", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,17,12,13,13,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "65", + "magic_animation": "0", "melee_animation": "5327", "range_animation": "0", - "combat_audio": "537,539,538", - "attack_speed": "4", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", + "safespot": null, "slayer_exp": "65", - "magic_animation": "0", - "death_animation": "5329", - "name": "Ice spider", - "defence_level": "43", - "safespot": null, - "lifepoints": "65", "strength_level": "55", - "id": "64", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,20,17,12,13,13,0,0,0,0", - "range_level": "1", - "attack_level": "50" + "weakness": "2" }, { - "examine": "A funny little man normally associated with rainbows.", - "melee_animation": "422", - "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Leprechaun", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "65", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Like a mini man!", + "name": "Leprechaun", + "examine": "A funny little man normally associated with rainbows.", + "attack_level": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "magic_level": "1", "melee_animation": "422", "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Gnome", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "3", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "66", + "name": "Gnome", + "examine": "Like a mini man!", + "attack_level": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "422", + "magic_level": "1", + "melee_animation": "190", + "range_animation": "190", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { - "examine": "Like a mini man!", - "melee_animation": "422", - "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Gnome", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", "id": "67", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Like a mini man!", - "melee_animation": "422", - "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", "name": "Gnome", + "examine": "Like a mini man!", + "attack_level": "1", + "death_animation": "196", + "defence_animation": "193", "defence_level": "1", - "safespot": null, "lifepoints": "3", - "strength_level": "1", + "magic_animation": "422", + "magic_level": "1", + "melee_animation": "190", + "range_animation": "190", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { "id": "68", + "name": "Gnome", + "examine": "Like a mini man!", + "attack_level": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "422", + "magic_level": "1", + "melee_animation": "190", + "range_animation": "190", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { - "examine": "A scaly reptilian creature.", - "slayer_task": "", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Lizard man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "69", + "name": "Lizard man", + "examine": "A scaly reptilian creature.", "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hideous malformed elf.", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "magic_level": "1", "melee_animation": "422", "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Orc", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "70", + "name": "Orc" + }, + { "id": "71", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hideously deformed creature.", + "name": "Orc", + "examine": "A hideous malformed elf.", + "attack_level": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "magic_level": "1", "melee_animation": "422", "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Troll", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "72", + "name": "Troll", + "examine": "A hideously deformed creature.", + "attack_level": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "422", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { - "examine": "Dead man walking.", - "slayer_task": "93", - "melee_animation": "5567", - "combat_audio": "931,923,922", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "5568", - "slayer_exp": "22", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "10", - "safespot": null, - "lifepoints": "22", - "strength_level": "9", "id": "73", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "Dead woman walking.", - "slayer_task": "93", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "4", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "24", - "magic_animation": "5578", - "death_animation": "5580", "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5568", "defence_level": "10", - "safespot": null, - "lifepoints": "24", - "strength_level": "13", - "id": "74", - "aggressive": "true", + "lifepoints": "22", + "melee_animation": "5567", "range_level": "1", - "attack_level": "13" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "22", + "strength_level": "9" }, { - "examine": "The walking dead.", - "slayer_task": "93", + "id": "74", + "name": "Zombie", + "examine": "Dead woman walking.", + "aggressive": "true", + "attack_level": "13", + "attack_speed": "4", + "combat_audio": "931,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "10", + "lifepoints": "24", + "magic_animation": "5578", "melee_animation": "5578", "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "4", + "range_level": "1", "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "16", "safespot": null, - "lifepoints": "30", - "strength_level": "21", + "slayer_exp": "24", + "strength_level": "13" + }, + { "id": "75", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "The walking dead.", - "slayer_task": "93", - "melee_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "5574", - "slayer_exp": "30", - "death_animation": "5575", "name": "Zombie", - "defence_level": "16", - "safespot": null, - "lifepoints": "30", - "strength_level": "21", - "id": "76", + "examine": "The walking dead.", "aggressive": "true", + "attack_level": "19", + "attack_speed": "4", + "combat_audio": "931,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "16", + "lifepoints": "30", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", "range_level": "1", - "attack_level": "19" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "21" }, { + "id": "76", + "name": "Zombie", + "examine": "The walking dead.", + "aggressive": "true", + "attack_level": "19", + "attack_speed": "4", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "16", + "lifepoints": "30", + "melee_animation": "5571", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "21" + }, + { + "id": "77", + "name": "Summoned Zombie", "examine": "The living dead.", - "slayer_task": "93", + "attack_level": "8", + "attack_speed": "4", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "22", + "magic_animation": "0", "melee_animation": "5568", "range_animation": "0", - "attack_speed": "4", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "22", - "magic_animation": "0", - "death_animation": "5569", - "name": "Summoned Zombie", - "defence_level": "10", - "safespot": null, - "lifepoints": "22", - "strength_level": "9", - "id": "77", "range_level": "1", - "attack_level": "8" + "safespot": null, + "slayer_exp": "22", + "strength_level": "9", + "weakness": "9" }, { + "id": "78", + "name": "Giant bat", "examine": "An annoying flappy thing.", - "slayer_task": "5", + "aggressive": "true", + "attack_level": "22", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "combat_audio": "292,294,293", + "death_animation": "4917", + "defence_animation": "4916", + "defence_level": "22", + "lifepoints": "32", + "magic_animation": "4915", + "magic_level": "1", "melee_animation": "4915", "range_animation": "4915", - "combat_audio": "292,294,293", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "4916", - "weakness": "4", - "slayer_exp": "32", - "magic_animation": "4915", - "death_animation": "4917", - "name": "Giant bat", - "defence_level": "22", - "safespot": null, - "lifepoints": "32", - "strength_level": "22", - "id": "78", - "aggressive": "true", - "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", "range_level": "1", - "attack_level": "22" + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "32", + "strength_level": "22", + "weakness": "4" }, { + "id": "79", + "name": "Death wing", "examine": "A shadowy, barely visible flying entity from some evil place.", - "slayer_task": "5", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "death_animation": "4917", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "80", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "4915", "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "slayer_exp": "80", - "magic_animation": "0", - "death_animation": "4917", - "name": "Death wing", - "defence_level": "70", - "safespot": null, - "lifepoints": "80", - "strength_level": "70", - "id": "79", - "aggressive": "true", "range_level": "1", - "attack_level": "70" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "80", + "strength_level": "70", + "weakness": "3" }, { + "id": "80", + "name": "Camel", "examine": "Oh, it's a camel.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "80", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "81", + "name": "Cow", "examine": "Converts grass to beef.", - "slayer_task": "20", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "369,371,370", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "5849", "melee_animation": "5849", "range_animation": "5849", - "combat_audio": "369,371,370", - "attack_speed": "5", - "defence_animation": "5850", - "weakness": "8", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "81", "range_level": "1", - "attack_level": "1" + "safespot": null, + "slayer_exp": "8", + "strength_level": "1", + "weakness": "8" }, { + "id": "82", + "name": "Lesser demon", "examine": "Lesser, but still pretty big.", - "slayer_task": "56", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "400,404,403", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "71", + "lifepoints": "79", + "magic_animation": "4630", + "magic_level": "1", "melee_animation": "4630", "range_animation": "4630", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "79", - "magic_animation": "4630", - "death_animation": "67", - "name": "Lesser demon", - "defence_level": "71", - "safespot": null, - "lifepoints": "79", - "strength_level": "70", - "id": "82", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", "range_level": "1", - "attack_level": "68" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "79", + "strength_level": "70", + "weakness": "4" }, { - "examine": "Big, red, and incredibly evil.", - "slayer_task": "40", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "32", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "87", - "magic_animation": "64", - "death_animation": "68", - "name": "Greater demon", - "defence_level": "81", - "safespot": null, - "lifepoints": "89", - "strength_level": "78", "id": "83", + "name": "Greater demon", + "examine": "Big, red, and incredibly evil.", "aggressive": "true", + "attack_level": "76", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", "clue_level": "2", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "A big, scary, jet-black demon.", - "slayer_task": "8", + "combat_audio": "400,404,403", + "death_animation": "68", + "defence_animation": "65", + "defence_level": "81", + "lifepoints": "89", + "magic_animation": "64", + "magic_level": "1", "melee_animation": "64", "range_animation": "64", - "combat_audio": "397,399,398", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "157", - "facing_booth": "", - "magic_animation": "64", - "death_animation": "67", - "name": "Black demon", - "defence_level": "152", - "safespot": null, - "lifepoints": "157", - "strength_level": "148", - "id": "84", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", "range_level": "1", - "attack_level": "145" + "respawn_delay": "32", + "safespot": null, + "slayer_exp": "87", + "strength_level": "78", + "weakness": "4" }, { + "id": "84", + "name": "Black demon", + "examine": "A big, scary, jet-black demon.", + "aggressive": "true", + "attack_level": "145", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "397,399,398", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "152", + "facing_booth": "", + "lifepoints": "157", + "magic_animation": "64", + "magic_level": "1", + "melee_animation": "64", + "range_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "157", + "strength_level": "148", + "weakness": "4" + }, + { + "id": "85", + "name": "Golem", "examine": "A creature made from clay.", + "attack_level": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "magic_level": "1", "melee_animation": "422", "range_animation": "422", - "magic_level": "1", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Golem", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "85", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "86", + "name": "Giant rat", "examine": "Overgrown vermin.", - "slayer_task": "67", + "aggressive": "true", + "attack_level": "2", + "attack_speed": "4", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "2", + "lifepoints": "5", + "magic_animation": "4933", "melee_animation": "4933", "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "4", - "defence_animation": "4934", - "weakness": "8", - "slayer_exp": "5", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "2", - "safespot": null, - "lifepoints": "5", - "strength_level": "3", - "id": "86", - "aggressive": "true", "range_level": "1", - "attack_level": "2" + "safespot": null, + "slayer_exp": "5", + "strength_level": "3", + "weakness": "8" }, { + "id": "87", + "name": "Giant rat", "examine": "Overgrown vermin.", - "slayer_task": "67", + "aggressive": "true", + "attack_level": "6", + "attack_speed": "4", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "2", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "4933", "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "4", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", + "safespot": null, "slayer_exp": "10", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "2", - "safespot": null, - "lifepoints": "10", "strength_level": "5", - "id": "87", - "aggressive": "true", - "range_level": "1", - "attack_level": "6" + "weakness": "8" }, { - "examine": "A dirty rat.", - "slayer_task": "67", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "slayer_exp": "12", - "magic_animation": "0", - "death_animation": "4935", - "name": "Dungeon rat", - "defence_level": "10", - "safespot": null, - "lifepoints": "12", - "strength_level": "10", "id": "88", + "name": "Dungeon rat", + "examine": "A dirty rat.", "aggressive": "true", + "attack_level": "10", + "attack_speed": "4", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "12", + "magic_animation": "0", + "range_animation": "0", "range_level": "1", - "attack_level": "10" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "12", + "strength_level": "10", + "weakness": "8" }, { + "id": "89", + "name": "Unicorn", "examine": "Horse with a horn.", + "attack_level": "11", + "attack_speed": "4", + "combat_audio": "369,371,370", + "death_animation": "6377", + "defence_animation": "6375", + "defence_level": "13", + "lifepoints": "19", + "magic_animation": "6376", + "magic_level": "1", "melee_animation": "6376", "range_animation": "6376", - "combat_audio": "369,371,370", - "attack_speed": "4", - "magic_level": "1", + "range_level": "1", "respawn_delay": "90", - "defence_animation": "6375", - "weakness": "3", - "magic_animation": "6376", - "death_animation": "6377", - "name": "Unicorn", - "defence_level": "13", "safespot": null, - "lifepoints": "19", "strength_level": "13", - "id": "89", - "range_level": "1", - "attack_level": "11" + "weakness": "3" }, { - "examine": "Not man's best friend.", - "slayer_task": "92", - "melee_animation": "6559", - "combat_audio": "481,491,490", + "id": "90", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "15", "attack_speed": "4", - "defence_animation": "6557", - "slayer_exp": "69", - "death_animation": "6558", - "name": "Wolf", - "defence_level": "52", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "17", + "lifepoints": "29", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "respawn_delay": "70", "safespot": null, - "lifepoints": "69", - "strength_level": "55", + "slayer_exp": "29", + "strength_level": "18", + "weakness": "8" + }, + { + "id": "91", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "17", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "17", + "lifepoints": "24", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "slayer_exp": "24", + "strength_level": "17", + "weakness": "8" + }, + { + "id": "92", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "24", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "24", + "lifepoints": "17", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "slayer_exp": "17", + "strength_level": "24", + "weakness": "8" + }, + { + "id": "93", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "32", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "36", + "lifepoints": "59", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "slayer_exp": "59", + "strength_level": "35", + "weakness": "8" + }, + { + "id": "94", + "name": "Skeleton Mage" + }, + { "id": "95", + "name": "Wolf", + "examine": "Not man's best friend.", + "attack_level": "50", + "attack_speed": "4", + "combat_audio": "481,491,490", + "death_animation": "6558", + "defence_animation": "6557", + "defence_level": "52", + "lifepoints": "69", + "melee_animation": "6559", "range_level": "1", - "attack_level": "50" + "safespot": null, + "slayer_exp": "69", + "strength_level": "55" }, { - "examine": "A vicious mountain wolf.", - "slayer_task": "92", - "melee_animation": "6579", - "range_animation": "6579", - "combat_audio": "909,912,911", - "attack_speed": "4", - "defence_animation": "6578", - "weakness": "9", - "slayer_exp": "34", - "magic_animation": "6579", - "death_animation": "6576", - "name": "White wolf", - "defence_level": "22", - "safespot": null, - "lifepoints": "34", - "strength_level": "16", "id": "96", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { + "name": "White wolf", "examine": "A vicious mountain wolf.", - "slayer_task": "92", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "4", + "combat_audio": "909,912,911", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "22", + "lifepoints": "34", + "magic_animation": "6579", "melee_animation": "6579", "range_animation": "6579", - "combat_audio": "909,912,911", - "attack_speed": "4", - "defence_animation": "6578", - "weakness": "7", - "slayer_exp": "44", - "magic_animation": "6579", - "death_animation": "6576", - "name": "White wolf", - "defence_level": "32", - "safespot": null, - "lifepoints": "44", - "strength_level": "31", - "id": "97", - "aggressive": "true", "range_level": "1", - "attack_level": "30" + "safespot": null, + "slayer_exp": "34", + "strength_level": "16", + "weakness": "9" }, { + "id": "97", + "name": "White wolf", + "examine": "A vicious mountain wolf.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "4", + "combat_audio": "909,912,911", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "32", + "lifepoints": "44", + "magic_animation": "6579", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "safespot": null, + "slayer_exp": "44", + "strength_level": "31", + "weakness": "7" + }, + { + "id": "98", + "name": "Dog", "examine": "Bow wow.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "98", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "99", + "name": "Guard dog", "examine": "He doesn't seem pleased to see me.", - "slayer_task": "27", + "aggressive": "true", + "attack_level": "35", + "attack_speed": "4", + "death_animation": "6564", + "defence_animation": "6563", + "defence_level": "37", + "lifepoints": "49", + "magic_animation": "6562", "melee_animation": "6562", "range_animation": "6562", - "attack_speed": "4", + "range_level": "1", "respawn_delay": "15", - "defence_animation": "6563", - "weakness": "7", + "safespot": null, "slayer_exp": "49", - "magic_animation": "6562", - "death_animation": "6564", - "name": "Guard dog", - "defence_level": "37", - "safespot": null, - "lifepoints": "49", "strength_level": "36", - "id": "99", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" + "weakness": "7" }, { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "4", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", "id": "100", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", "name": "Goblin", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "101", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", + "attack_level": "1", + "attack_speed": "4", + "clue_level": "0", "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "16", - "magic_animation": "6185", "death_animation": "6182", - "name": "Goblin", + "defence_animation": "6183", "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "102", - "clue_level": "0", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", "range_level": "1", - "attack_level": "1" + "safespot": null, + "slayer_exp": "5", + "strength_level": "1" }, { - "agg_radius": "", + "id": "101", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "3", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "102", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "2" + }, + { + "id": "103", + "name": "Ghost", "examine": "Eeek! A ghost!", - "slayer_task": "36", + "agg_radius": "", + "aggressive": "true", + "attack_level": "13", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,5,-5,5,0,0,0,0,0", + "combat_audio": "436,439,438", + "death_animation": "5542", + "defence_animation": "5541", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "5540", + "magic_level": "1", "melee_animation": "5540", "range_animation": "5540", - "combat_audio": "436,439,438", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "40", - "defence_animation": "5541", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "5540", - "death_animation": "5542", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "13", - "id": "103", - "aggressive": "true", - "bonuses": "0,0,0,0,0,5,5,5,-5,5,0,0,0,0,0", "range_level": "1", - "attack_level": "13" + "respawn_delay": "40", + "safespot": null, + "slayer_exp": "25", + "strength_level": "13", + "weakness": "5" }, { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5540", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "40", - "defence_animation": "5541", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5542", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "13", "id": "104", + "name": "Ghost", + "examine": "Eeek! A ghost!", "aggressive": "true", + "attack_level": "13", + "attack_speed": "4", "bonuses": "0,0,0,0,0,5,5,5,-5,5,0,0,0,0,0", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "Eek! A bear!", - "slayer_task": "6", - "melee_animation": "4925", - "range_animation": "0", - "combat_audio": "300,302,301", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "27", - "magic_animation": "0", - "death_animation": "4929", - "name": "Grizzly bear", - "defence_level": "15", - "safespot": null, - "lifepoints": "27", - "strength_level": "18", - "id": "105", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "17" - }, - { - "examine": "Eek! A bear!", - "slayer_task": "6", - "melee_animation": "4925", - "range_animation": "0", - "combat_audio": "300,302,301", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "4929", - "name": "Black bear", - "defence_level": "13", - "safespot": null, + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "18", "lifepoints": "25", - "strength_level": "16", - "id": "106", - "aggressive": "false", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "An extremely vicious scorpion.", - "melee_animation": "6254", - "combat_audio": "3611,3612,3610", - "respawn_delay": "60", - "defence_animation": "6255", - "slayer_exp": "17", - "death_animation": "6256", - "name": "Scorpion", - "defence_level": "1", - "safespot": null, - "lifepoints": "17", - "strength_level": "1", - "id": "107", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It has a very vicious looking tail.", - "slayer_task": "71", - "melee_animation": "6254", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5532", "range_animation": "0", - "combat_audio": "3611,3612,3610", + "range_level": "1", + "respawn_delay": "40", + "safespot": null, + "slayer_exp": "25", + "strength_level": "13", + "weakness": "5" + }, + { + "id": "105", + "name": "Grizzly bear", + "examine": "Eek! A bear!", + "aggressive": "true", + "attack_level": "17", "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "25", - "defence_animation": "6255", - "weakness": "0", - "slayer_exp": "23", - "poison_amount": "3", - "magic_animation": "0", - "death_animation": "6256", - "name": "Poison Scorpion", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "300,302,301", + "death_animation": "4929", + "defence_animation": "0", "defence_level": "15", - "safespot": null, - "lifepoints": "23", - "strength_level": "17", - "id": "108", - "aggressive": "true", - "bonuses": "0,0,0,0,0,5,15,15,0,5,0,0,0,0,0", + "lifepoints": "27", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4925", + "range_animation": "0", "range_level": "1", - "attack_level": "16" + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "27", + "strength_level": "18", + "weakness": "7" }, { + "id": "106", + "name": "Black bear", + "examine": "Eek! A bear!", + "aggressive": "false", + "attack_level": "15", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "300,302,301", + "death_animation": "4929", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4925", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "25", + "strength_level": "16", + "weakness": "7" + }, + { + "id": "107", + "name": "Scorpion", + "examine": "An extremely vicious scorpion.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "6255", + "defence_level": "1", + "lifepoints": "17", + "melee_animation": "6254", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "17", + "strength_level": "1" + }, + { + "id": "108", + "name": "Poison Scorpion", + "examine": "It has a very vicious looking tail.", + "aggressive": "true", + "attack_level": "16", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,15,15,0,5,0,0,0,0,0", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "6255", + "defence_level": "15", + "lifepoints": "23", + "magic_animation": "0", + "melee_animation": "6254", + "poison_amount": "15", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "23", + "strength_level": "17", + "weakness": "0" + }, + { + "id": "109", + "name": "Pit Scorpion", "examine": "Tiny", - "slayer_task": "71", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "6255", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", "melee_animation": "6254", "range_animation": "0", - "combat_audio": "3611,3612,3610", - "respawn_delay": "60", - "defence_animation": "6255", - "weakness": "0", - "magic_animation": "0", - "death_animation": "6256", - "name": "Pit Scorpion", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "1", - "id": "109", - "aggressive": "true", "range_level": "40", - "attack_level": "1" + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" }, { + "id": "110", + "name": "Fire giant", "examine": "A very large elemental adversary.", - "slayer_task": "33", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", "melee_animation": "4666", "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "110", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", "range_level": "1", - "attack_level": "65" + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" }, { + "id": "111", + "name": "Ice giant", "examine": "He's got icicles in his beard.", - "slayer_task": "47", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4673", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "4672", "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "70", - "magic_animation": "0", - "death_animation": "4673", - "name": "Ice giant", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "40", - "id": "111", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", "range_level": "1", - "attack_level": "40" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "70", + "strength_level": "40", + "weakness": "9" }, { + "id": "112", + "name": "Moss giant", "examine": "His beard seems to have a life of its own.", - "slayer_task": "62", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "6", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "30", + "lifepoints": "60", + "magic_animation": "4666", + "magic_level": "1", "melee_animation": "4666", "range_animation": "4666", - "combat_audio": "449,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4665", - "weakness": "1", - "slayer_exp": "60", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "30", - "safespot": null, - "lifepoints": "60", - "strength_level": "30", - "id": "112", - "aggressive": "true", - "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", "range_level": "1", - "attack_level": "30" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "60", + "strength_level": "30", + "weakness": "1" }, { + "id": "113", + "name": "Jogre", "examine": "An aggressive humanoid.", - "slayer_task": "64", + "aggressive": "true", + "attack_level": "41", + "attack_speed": "5", + "clue_level": "1", + "death_animation": "131", + "defence_animation": "129", + "defence_level": "41", + "lifepoints": "50", + "magic_animation": "128", "melee_animation": "128", "range_animation": "128", - "attack_speed": "5", - "defence_animation": "129", - "weakness": "7", - "magic_animation": "128", - "death_animation": "131", - "name": "Jogre", - "defence_level": "41", + "range_level": "1", "safespot": null, - "lifepoints": "50", "strength_level": "36", - "id": "113", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "41" + "weakness": "7" }, { - "examine": "Big, ugly, and smelly.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "27", - "respawn_delay": "25", - "defence_animation": "360", - "slayer_exp": "", - "magic_animation": "359", - "death_animation": "361", - "name": "Mogre", - "defence_level": "27", - "safespot": null, - "lifepoints": "60", - "strength_level": "27", "id": "114", - "aggressive": "true", - "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", - "range_level": "27", - "attack_level": "27" - }, - { - "examine": "A large dim looking humanoid.", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "360", - "magic_animation": "359", - "death_animation": "361", - "name": "Ogre", - "defence_level": "43", - "safespot": null, - "lifepoints": "60", - "strength_level": "43", - "id": "115", - "aggressive": "true", - "bonuses": "22,22,22,0,0,0,0,0,0,0,0,20,0,0,0", - "range_level": "1", - "attack_level": "43" - }, - { + "name": "Mogre", "examine": "Big, ugly, and smelly.", - "slayer_task": "44", + "aggressive": "true", + "attack_level": "27", + "attack_speed": "6", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "27", + "lifepoints": "60", + "magic_animation": "359", + "magic_level": "27", "melee_animation": "359", "range_animation": "359", - "attack_speed": "4", - "magic_level": "1", + "range_level": "27", "respawn_delay": "25", - "defence_animation": "360", - "weakness": "8", - "slayer_exp": "75", - "magic_animation": "359", - "death_animation": "361", - "name": "Cyclops", - "defence_level": "35", "safespot": null, - "lifepoints": "75", - "strength_level": "65", - "id": "116", + "slayer_exp": "", + "strength_level": "27" + }, + { + "id": "115", + "name": "Ogre", + "examine": "A large dim looking humanoid.", "aggressive": "true", + "attack_level": "43", + "attack_speed": "6", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,20,0,0,0", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "43", + "lifepoints": "60", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "43" + }, + { + "id": "116", + "name": "Cyclops", + "examine": "Big, ugly, and smelly.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "35", + "lifepoints": "75", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", "range_level": "1", - "attack_level": "65" + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "75", + "strength_level": "65", + "weakness": "8" }, { + "id": "117", + "name": "Hill Giant", "examine": "A very large foe.", - "slayer_task": "44", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "6", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "35", + "magic_animation": "4652", + "magic_level": "1", "melee_animation": "4652", "range_animation": "4652", - "combat_audio": "448,451,450", - "attack_speed": "6", - "magic_level": "1", + "range_level": "1", "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "6", + "safespot": null, "slayer_exp": "35", - "magic_animation": "4652", - "death_animation": "4653", - "name": "Hill Giant", - "defence_level": "26", - "safespot": null, - "lifepoints": "35", "strength_level": "22", - "id": "117", - "aggressive": "true", - "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", - "range_level": "1", - "attack_level": "18" + "weakness": "6" }, { - "examine": "A short angry guy.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "attack_speed": "7", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "7", - "safespot": null, - "lifepoints": "10", - "strength_level": "7", "id": "118", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "A dwarf gone bad.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "combat_audio": "2567,419,418", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "150", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "61", - "magic_animation": "0", - "death_animation": "102", - "name": "Chaos dwarf", - "defence_level": "28", - "safespot": null, - "lifepoints": "61", - "strength_level": "42", - "id": "119", - "aggressive": "true", - "bonuses": "13,13,13,0,0,40,34,25,10,35,0,9,0,0,0", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "A mountain dwelling short angry guy.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "attack_speed": "6", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", "name": "Dwarf", - "defence_level": "16", - "safespot": null, - "lifepoints": "26", - "strength_level": "16", - "id": "120", - "range_level": "1", - "attack_level": "15" - }, - { - "slayer_exp": "16", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, + "examine": "A short angry guy.", + "attack_level": "7", + "attack_speed": "7", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "7", "lifepoints": "10", - "strength_level": "1", - "id": "121", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly smelly creature.", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "469,472,471", - "attack_speed": "6", - "defence_animation": "165", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "3", + "respawn_delay": "60", "safespot": null, - "lifepoints": "29", - "strength_level": "10", - "id": "122", - "aggressive": "true", - "range_level": "20", - "attack_level": "20" + "slayer_exp": "16", + "strength_level": "7", + "weakness": "6" }, { - "examine": "An ugly smelly creature.", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "3520,472,471", + "id": "119", + "name": "Chaos dwarf", + "examine": "A dwarf gone bad.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "4", + "bonuses": "13,13,13,0,0,40,34,25,10,35,0,9,0,0,0", + "combat_audio": "2567,419,418", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "61", + "strength_level": "42", + "weakness": "6" + }, + { + "id": "120", + "name": "Dwarf", + "examine": "A mountain dwelling short angry guy.", + "attack_level": "15", "attack_speed": "6", - "defence_animation": "165", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "16", + "lifepoints": "26", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "16", + "weakness": "6" + }, + { + "id": "121", + "name": "Dwarf", + "attack_level": "1", "defence_level": "1", + "lifepoints": "10", + "range_level": "1", "safespot": null, - "lifepoints": "29", - "strength_level": "10", - "id": "123", - "aggressive": "true", - "range_level": "20", - "attack_level": "20" + "slayer_exp": "16", + "strength_level": "1" }, { + "id": "122", + "name": "Hobgoblin", + "examine": "An ugly smelly creature.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "469,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "3", + "lifepoints": "29", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "20", + "safespot": null, + "strength_level": "10" + }, + { + "id": "123", + "name": "Hobgoblin", + "examine": "An ugly smelly creature.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "3520,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "1", + "lifepoints": "29", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "20", + "safespot": null, + "strength_level": "10" + }, + { + "id": "124", + "name": "Earth warrior", "examine": "A strange, inhuman, elemental warrior.", - "slayer_task": "30", + "aggressive": "true", + "attack_level": "42", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "54", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "393", "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "54", - "magic_animation": "0", - "death_animation": "836", - "name": "Earth warrior", - "defence_level": "42", - "safespot": null, - "lifepoints": "54", - "strength_level": "42", - "id": "124", - "aggressive": "true", - "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", "range_level": "1", - "attack_level": "42" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "54", + "strength_level": "42", + "weakness": "7" }, { - "examine": "A cold-hearted elemental warrior.", - "slayer_task": "48", - "melee_animation": "451", - "range_animation": "451", - "combat_audio": "2500,530,529", - "attack_speed": "4", - "respawn_delay": "30", - "defence_animation": "404", - "weakness": "9", - "slayer_exp": "59", - "magic_animation": "451", - "death_animation": "843", - "name": "Ice warrior", - "defence_level": "47", - "safespot": null, - "lifepoints": "59", - "strength_level": "47", "id": "125", + "name": "Ice warrior", + "examine": "A cold-hearted elemental warrior.", "aggressive": "true", + "attack_level": "47", + "attack_speed": "4", "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", "clue_level": "1", + "combat_audio": "2500,530,529", + "death_animation": "843", + "defence_animation": "404", + "defence_level": "47", + "lifepoints": "59", + "magic_animation": "451", + "melee_animation": "451", + "range_animation": "451", "range_level": "1", - "attack_level": "47" - }, - { - "examine": "Looks pretty otherworldly to me!", - "slayer_task": "65", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "45", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "name": "Otherworldly being", - "defence_level": "45", + "respawn_delay": "30", "safespot": null, - "lifepoints": "64", - "strength_level": "1", - "id": "126", - "range_level": "1", - "attack_level": "1" + "slayer_exp": "59", + "strength_level": "47", + "weakness": "9" }, { + "id": "126", + "name": "Otherworldly being", + "examine": "Looks pretty otherworldly to me!", + "attack_level": "1", + "attack_speed": "5", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "magic_level": "45", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "127", + "name": "Magic axe", "examine": "A magic axe with a mind of its own.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,5,15,5,10,0,0,0,0,0", + "combat_audio": "2498,12,1976", + "death_animation": "188", + "defence_animation": "0", + "defence_level": "29", + "lifepoints": "44", + "magic_animation": "0", "melee_animation": "185", "range_animation": "0", - "combat_audio": "2498,12,1976", - "attack_speed": "4", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "188", - "name": "Magic axe", - "defence_level": "29", - "safespot": null, - "lifepoints": "44", - "strength_level": "38", - "id": "127", - "aggressive": "true", - "bonuses": "0,0,0,0,0,10,5,15,5,10,0,0,0,0,0", "range_level": "1", - "attack_level": "38" + "respawn_delay": "30", + "safespot": null, + "strength_level": "38", + "weakness": "6" }, { + "id": "128", + "name": "Snake", "examine": "A slithering serpent.", + "aggressive": "true", + "attack_level": "4", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "278", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "6", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "275", "range_animation": "0", - "combat_audio": "3609,3608,3610", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "278", - "name": "Snake", - "defence_level": "3", - "safespot": null, - "lifepoints": "6", - "strength_level": "5", - "id": "128", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "range_level": "1", - "attack_level": "4" + "respawn_delay": "30", + "safespot": null, + "strength_level": "5", + "weakness": "8" }, { + "id": "129", + "name": "Skavid" + }, + { + "id": "130", + "name": "Yeti", + "examine": "Stinky! Poor guy." + }, + { + "id": "131", + "name": "Penguin", "examine": "An inhabitant of icy regions.", - "slayer_task": "7", + "attack_level": "6", + "death_animation": "5671", + "defence_animation": "0", + "defence_level": "6", + "lifepoints": "8", + "magic_animation": "0", "melee_animation": "5669", "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5671", - "name": "Penguin", - "defence_level": "6", - "safespot": null, - "lifepoints": "8", - "strength_level": "6", - "id": "131", "range_level": "1", - "attack_level": "6" + "safespot": null, + "strength_level": "6", + "weakness": "9" }, { + "id": "132", + "name": "Monkey", "examine": "Perhaps our oldest relatives?", - "slayer_task": "61", + "aggressive": "false", + "attack_level": "2", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "629,631,630", + "death_animation": "223", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "6", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "220", "range_animation": "0", - "combat_audio": "629,631,630", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "37", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "223", - "name": "Monkey", - "defence_level": "2", - "safespot": null, - "lifepoints": "6", - "strength_level": "3", - "id": "132", - "aggressive": "false", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "range_level": "1", - "attack_level": "2" + "respawn_delay": "37", + "safespot": null, + "strength_level": "3", + "weakness": "8" }, { + "id": "133", + "name": "Black unicorn", "examine": "A unicorn with a blackened heart.", + "aggressive": "false", + "attack_level": "21", + "attack_speed": "4", + "combat_audio": "369,371,370", + "death_animation": "6377", + "defence_animation": "6375", + "defence_level": "23", + "lifepoints": "29", + "magic_animation": "6376", + "magic_level": "1", "melee_animation": "6376", "range_animation": "6376", - "combat_audio": "369,371,370", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "90", - "defence_animation": "6375", - "weakness": "3", - "magic_animation": "6376", - "death_animation": "6377", - "name": "Black unicorn", - "defence_level": "23", - "safespot": null, - "lifepoints": "29", - "strength_level": "23", - "id": "133", - "aggressive": "false", "range_level": "1", - "attack_level": "21" + "respawn_delay": "90", + "safespot": null, + "strength_level": "23", + "weakness": "3" }, { - "examine": "A nasty, poisonous arachnid.", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "0", - "combat_audio": "537,539,538", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "30", - "defence_animation": "5328", - "weakness": "2", - "poison_amount": "6", - "magic_animation": "0", - "death_animation": "5329", + "id": "134", "name": "Poison spider", - "safespot": null, + "examine": "A nasty, poisonous arachnid.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "4", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", "defence_level": "52", "lifepoints": "64", - "strength_level": "65", - "id": "134", - "aggressive": "true", + "magic_animation": "0", + "melee_animation": "5327", + "poison_amount": "30", + "poisonous": "true", + "range_animation": "0", "range_level": "1", - "attack_level": "50" + "respawn_delay": "30", + "safespot": null, + "strength_level": "65", + "weakness": "2" }, { + "id": "135", + "name": "Mammoth" + }, + { + "id": "136", + "name": "Mounted terrorchick gnome" + }, + { + "id": "137", + "name": "Terrorchick gnome", "examine": "Aaw", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Terrorchick gnome", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "137", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "138", + "name": "Terrorbird", "examine": "A giant raptor.", - "slayer_task": "7", + "aggressive": "false", + "attack_level": "23", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "832,834,833", + "death_animation": "1013", + "defence_animation": "1012", + "defence_level": "19", + "lifepoints": "34", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "1010", "range_animation": "0", - "combat_audio": "832,834,833", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "1012", - "weakness": "6", - "magic_animation": "0", - "death_animation": "1013", - "name": "Terrorbird", - "defence_level": "19", - "safespot": null, - "lifepoints": "34", - "strength_level": "23", - "id": "138", - "aggressive": "false", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "range_level": "1", - "attack_level": "23" + "respawn_delay": "30", + "safespot": null, + "strength_level": "23", + "weakness": "6" }, { - "examine": "A giant raptor.", - "melee_animation": "1010", - "combat_audio": "832,834,833", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "1012", - "magic_animation": "0", - "death_animation": "1013", - "name": "Terrorbird", - "defence_level": "19", - "safespot": null, - "lifepoints": "34", - "strength_level": "23", "id": "139", + "name": "Terrorbird", + "examine": "A giant raptor.", "aggressive": "false", + "attack_level": "23", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "832,834,833", + "death_animation": "1013", + "defence_animation": "1012", + "defence_level": "19", + "lifepoints": "34", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1010", "range_level": "1", - "attack_level": "23" + "respawn_delay": "30", + "safespot": null, + "strength_level": "23" }, { + "id": "140", + "name": "Souless", "examine": "A servant to Iban.", + "aggressive": "true", + "attack_level": "33", + "death_animation": "340", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", "melee_animation": "338", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "340", - "name": "Souless", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "140", - "aggressive": "true", "range_level": "1", - "attack_level": "33" + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "7" }, { + "id": "141", + "name": "Big Wolf", "examine": "Must be the pack leader.", - "slayer_task": "92", + "aggressive": "true", + "attack_level": "31", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "44", + "magic_animation": "0", "melee_animation": "6559", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "74", - "magic_animation": "0", - "death_animation": "6558", - "name": "Big Wolf", - "defence_level": "31", - "safespot": null, - "lifepoints": "44", - "strength_level": "31", - "id": "141", - "aggressive": "true", "range_level": "1", - "attack_level": "31" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "74", + "strength_level": "31", + "weakness": "7" }, { - "slayer_exp": "34", - "death_animation": "6558", + "id": "142", "name": "Wolf", + "attack_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6558", "defence_level": "1", - "safespot": null, "lifepoints": "69", "melee_animation": "6559", - "combat_audio": "481,491,490", - "strength_level": "1", - "id": "142", "range_level": "1", - "attack_level": "1" + "safespot": null, + "slayer_exp": "34", + "strength_level": "1" }, { + "id": "143", + "name": "Jungle Wolf", "examine": "A rare jungle wolf - specific to the Kharazi jungle.", - "slayer_task": "92", + "aggressive": "true", + "attack_level": "63", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", "melee_animation": "6559", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "69", - "magic_animation": "0", - "death_animation": "6558", - "name": "Jungle Wolf", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "63", - "id": "143", - "aggressive": "true", "range_level": "1", - "attack_level": "63" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "69", + "strength_level": "63", + "weakness": "7" }, { + "id": "144", + "name": "King Scorpion", "examine": "Wow! Scorpions shouldn't grow that big.", - "slayer_task": "71", + "aggressive": "true", + "attack_level": "21", + "attack_speed": "5", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", "melee_animation": "6254", "range_animation": "0", - "combat_audio": "3611,3612,3610", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "17", - "magic_animation": "0", - "death_animation": "6256", - "name": "King Scorpion", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "21", - "id": "144", - "aggressive": "true", "range_level": "28", - "attack_level": "21" + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "17", + "strength_level": "21", + "weakness": "2" }, { - "examine": "A cold-hearted elemental warrior.", - "slayer_task": "48", - "melee_animation": "451", - "range_animation": "451", - "combat_audio": "2500,530,529", - "attack_speed": "4", - "respawn_delay": "30", - "defence_animation": "404", - "weakness": "9", - "slayer_exp": "59", - "magic_animation": "451", - "death_animation": "843", - "name": "Ice warrior", - "defence_level": "47", - "safespot": null, - "lifepoints": "59", - "strength_level": "47", "id": "145", + "name": "Ice warrior", + "examine": "A cold-hearted elemental warrior.", "aggressive": "true", + "attack_level": "47", + "attack_speed": "4", "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", "clue_level": "1", + "combat_audio": "2500,530,529", + "death_animation": "843", + "defence_animation": "404", + "defence_level": "47", + "lifepoints": "59", + "magic_animation": "451", + "melee_animation": "451", + "range_animation": "451", "range_level": "1", - "attack_level": "47" + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "59", + "strength_level": "47", + "weakness": "9" }, { - "examine": "A sea bird.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gull", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "146", - "range_level": "1", - "attack_level": "1" - }, - { + "name": "Gull", "examine": "A sea bird.", - "slayer_task": "7", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cormorant", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "147", - "range_level": "1", - "attack_level": "1" - }, - { + "name": "Cormorant", "examine": "A sea bird.", - "slayer_task": "7", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pelican", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "148", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "These look much better in the wild.", + "name": "Pelican", + "examine": "A sea bird.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Butterfly", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "149", + "name": "Gull" + }, + { + "id": "150", + "name": "Gull" + }, + { + "id": "151", + "name": "Fly trap" + }, + { + "id": "152", + "name": "Butterfly" + }, + { "id": "153", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I love butterflies.", + "name": "Butterfly", + "examine": "These look much better in the wild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Butterfly", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "154", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "154", + "name": "Butterfly", + "examine": "I love butterflies.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "155", + "name": "Butterfly" + }, + { + "id": "156", + "name": "Butterfly" + }, + { + "id": "157", + "name": "Butterfly" + }, + { + "id": "158", + "name": "Shadow warrior", "examine": "A fighter from the supernatural world. He's a shadow of his former self.", - "slayer_task": "74", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "5", + "death_animation": "843", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", "melee_animation": "394", "range_animation": "0", - "attack_speed": "5", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "843", - "name": "Shadow warrior", - "defence_level": "47", "safespot": null, - "lifepoints": "67", "strength_level": "47", - "id": "158", - "aggressive": "true", - "range_level": "1", - "attack_level": "47" + "weakness": "6" }, { - "examine": "Small", - "melee_animation": "191", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome child", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", "id": "159", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Seems to crawl the caves.", - "melee_animation": "266", - "range_animation": "266", - "attack_speed": "5", - "defence_animation": "267", - "weakness": "9", - "magic_animation": "266", - "death_animation": "265", "name": "Gnome child", - "defence_level": "23", - "safespot": null, - "lifepoints": "21", - "strength_level": "23", - "id": "160", - "bonuses": "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "Small", + "examine": "Small, even by gnome standards.", + "attack_level": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "0", "melee_animation": "191", "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome child", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "161", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1", + "weakness": "9" }, { + "id": "160", + "name": "Gnome child", + "examine": "Small, even by gnome standards.", + "attack_level": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "191", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "161", + "name": "Gnome child", + "examine": "Small, even by gnome standards.", + "attack_level": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "191", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "162", + "name": "Gnome trainer", "examine": "He can advise on training.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome trainer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "162", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "163", + "name": "Gnome guard", "examine": "A tree gnome guard.", + "attack_level": "38", + "death_animation": "1224", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", "melee_animation": "1218", "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "1224", - "name": "Gnome guard", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "38", - "id": "163", "range_level": "1", - "attack_level": "38" + "safespot": null, + "strength_level": "38", + "weakness": "9" }, { + "id": "164", + "name": "Gnome guard", "examine": "A tree gnome guard.", + "attack_level": "38", + "death_animation": "196", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", "melee_animation": "192", "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome guard", - "defence_level": "38", + "range_level": "1", "safespot": null, - "lifepoints": "54", "strength_level": "38", - "id": "164", - "range_level": "1", - "attack_level": "38" + "weakness": "9" + }, + { + "id": "165", + "name": "Gnome shop keeper" + }, + { + "id": "166", + "name": "Gnome banker", + "examine": "Banks gnomish things." + }, + { + "id": "167", + "name": "Gnome baller" }, { - "examine": "A female gnome.", - "combat_style": "1", - "melee_animation": "191", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome woman", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", "id": "168", - "range_level": "1", - "attack_level": "30" - }, - { + "name": "Gnome woman", "examine": "A female gnome.", + "attack_level": "30", "combat_style": "1", + "death_animation": "196", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", "melee_animation": "191", "range_animation": "0", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome woman", - "defence_level": "30", "safespot": null, - "lifepoints": "42", "strength_level": "30", + "weakness": "7" + }, + { "id": "169", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "One of Gielinor's many citizens", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", + "name": "Gnome woman", + "examine": "A female gnome.", + "attack_level": "30", + "combat_style": "1", + "death_animation": "196", "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "170", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "He works evil magic.", - "combat_style": "2", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "27", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "27", - "safespot": null, - "lifepoints": "24", - "strength_level": "1", - "id": "172", - "aggressive": "true", - "range_level": "1", - "attack_level": "1", - "prj_height": "3" - }, - { - "examine": "An evil user of Magic powers", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "836", - "name": "Invrigar the Necromancer", "defence_level": "30", - "safespot": null, "lifepoints": "42", - "strength_level": "1", - "id": "173", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He works evil magic.", - "combat_style": "2", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "24", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "24", - "safespot": null, - "lifepoints": "12", - "strength_level": "1", - "id": "174", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "2", - "examine": "He jumps out and attacks people.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", "magic_animation": "0", - "death_animation": "836", - "name": "Mugger", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "175", - "aggressive": "true", + "melee_animation": "191", + "range_animation": "0", "range_level": "1", - "attack_level": "11" + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "7" }, { + "id": "170", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" + }, + { + "id": "171", + "name": "Brimstail" + }, + { + "id": "172", + "name": "Dark wizard", + "examine": "He works evil magic.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "27", + "lifepoints": "24", + "magic_animation": "711", + "magic_level": "27", + "melee_animation": "422", + "prj_height": "3", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "173", + "name": "Invrigar the Necromancer", + "examine": "An evil user of Magic powers", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "magic_level": "30", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "174", + "name": "Dark wizard", + "examine": "He works evil magic.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "24", + "lifepoints": "12", + "magic_animation": "711", + "magic_level": "24", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "175", + "name": "Mugger", + "examine": "He jumps out and attacks people.", + "agg_radius": "2", + "aggressive": "true", + "attack_level": "11", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "176", + "name": "Witch", "examine": "The hat's a dead give away.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "magic_level": "22", "melee_animation": "423", "range_animation": "0", - "magic_level": "22", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "836", - "name": "Witch", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "1", - "id": "176", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1", + "weakness": "4" }, { + "id": "177", + "name": "Witch" + }, + { + "id": "178", + "name": "Black Knight", "examine": "A dark-hearted knight.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "5", + "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", + "combat_audio": "2503,15,512", + "death_animation": "836", + "defence_animation": "388", + "defence_level": "25", + "lifepoints": "42", + "magic_animation": "0", "melee_animation": "390", "range_animation": "0", - "combat_audio": "2503,15,512", - "attack_speed": "5", - "respawn_delay": "25", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Black Knight", - "defence_level": "25", - "safespot": null, - "lifepoints": "42", - "strength_level": "25", - "id": "178", - "aggressive": "true", - "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", "range_level": "1", - "attack_level": "25" + "respawn_delay": "25", + "safespot": null, + "strength_level": "25", + "weakness": "7" }, { - "examine": "A dark-hearted knight.", - "melee_animation": "390", - "combat_audio": "2503,15,512", - "attack_speed": "5", - "respawn_delay": "25", - "defence_animation": "388", - "death_animation": "836", - "name": "Black Knight", - "defence_level": "25", - "safespot": null, - "lifepoints": "42", - "strength_level": "25", "id": "179", + "name": "Black Knight", + "examine": "A dark-hearted knight.", "aggressive": "true", + "attack_level": "25", + "attack_speed": "5", "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", + "combat_audio": "2503,15,512", + "death_animation": "836", + "defence_animation": "388", + "defence_level": "25", + "lifepoints": "42", + "melee_animation": "390", "range_level": "1", - "attack_level": "25" + "respawn_delay": "25", + "safespot": null, + "strength_level": "25" }, { + "id": "180", + "name": "Highwayman", "examine": "He holds up passers by.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "8", + "lifepoints": "13", + "magic_animation": "799", "melee_animation": "799", "range_animation": "799", - "combat_audio": "511,513,512", - "attack_speed": "5", - "defence_animation": "404", - "weakness": "7", - "magic_animation": "799", - "death_animation": "9055", - "name": "Highwayman", - "defence_level": "8", - "safespot": null, - "lifepoints": "13", - "strength_level": "8", - "id": "180", - "aggressive": "true", "range_level": "1", - "attack_level": "8" + "safespot": null, + "strength_level": "8", + "weakness": "7" }, { - "examine": "A crazy, evil druid.", - "start_gfx": "105", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "4", - "magic_level": "10", - "end_gfx": "107", - "respawn_delay": "25", - "defence_animation": "404", - "weakness": "3", - "slayer_exp": "0", - "magic_animation": "422", - "death_animation": "9055", - "name": "Chaos druid", - "defence_level": "12", - "safespot": null, - "lifepoints": "20", - "strength_level": "8", "id": "181", + "name": "Chaos druid", + "examine": "A crazy, evil druid.", "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "106", - "attack_level": "8" - }, - { - "melee_animation": "422", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "182", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "422", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "183", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "422", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "184", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "185", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "186", - "aggressive": "true", - "clue_level": "0", - "bonuses": "5,5,5,0,0,2,3,3,0,0,0,5,0,0,0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "An evil human cleric.", - "start_gfx": "99", - "combat_style": "2", - "combat_audio": "511,513,512", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "25", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "5", - "magic_animation": "711", - "death_animation": "836", - "name": "Monk of Zamorak", - "defence_level": "22", - "safespot": null, - "lifepoints": "20", - "strength_level": "18", - "id": "188", - "aggressive": "true", - "range_level": "1", - "projectile": "100", - "attack_level": "18" - }, - { - "examine": "An evil human cleric.", - "start_gfx": "99", - "combat_style": "2", - "combat_audio": "511,513,512", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "25", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "5", - "magic_animation": "711", - "death_animation": "836", - "name": "Monk of Zamorak", - "defence_level": "12", - "safespot": null, - "lifepoints": "10", - "strength_level": "8", - "id": "189", - "aggressive": "true", - "range_level": "1", - "projectile": "100", - "attack_level": "8" - }, - { - "examine": "An evil human cleric.", - "start_gfx": "99", - "combat_style": "2", - "combat_audio": "511,513,512", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "40", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "5", - "magic_animation": "711", - "death_animation": "836", - "name": "Monk of Zamorak", - "defence_level": "42", - "safespot": null, - "lifepoints": "40", - "strength_level": "38", - "id": "190", - "aggressive": "true", - "range_level": "1", - "projectile": "100", - "attack_level": "38" - }, - { - "examine": "A primitive warrior.", - "melee_animation": "428", - "range_animation": "0", - "attack_speed": "4", - "poisonous": "true", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "8", - "poison_amount": "11", - "magic_animation": "0", - "death_animation": "836", - "name": "Tribesman", - "defence_level": "26", - "safespot": null, - "lifepoints": "39", - "strength_level": "27", - "id": "191", - "aggressive": "true", - "clue_level": "1", - "bonuses": "8,8,8,0,0,4,6,6,0,0,0,5,0,0,0", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A warrior of Darkness.", - "melee_animation": "451", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "8", "death_animation": "9055", - "name": "Dark warrior", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "10", - "id": "192", - "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A crazy evil druid.", - "start_gfx": "105", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "4", - "magic_level": "10", - "respawn_delay": "25", - "end_gfx": "107", "defence_animation": "404", - "weakness": "3", - "magic_animation": "422", - "death_animation": "836", - "name": "Chaos druid warrior", "defence_level": "12", - "safespot": null, + "end_gfx": "107", "lifepoints": "20", - "strength_level": "8", - "id": "193", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "106", - "attack_level": "8" - }, - { - "examine": "A crazy evil necromancer.", + "magic_animation": "422", + "magic_level": "10", "melee_animation": "422", - "range_animation": "0", - "magic_level": "28", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "836", - "name": "Necromancer", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "194", + "projectile": "106", + "range_animation": "422", "range_level": "1", - "attack_level": "1" + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "0", + "start_gfx": "105", + "strength_level": "8", + "weakness": "3" }, { - "examine": "Bandit Camp guard.", + "id": "182", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "183", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "184", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "185", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "186", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,2,3,3,0,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "386", "range_animation": "0", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard Bandit", - "defence_level": "20", + "range_level": "1", + "respawn_delay": "50", "safespot": null, - "lifepoints": "28", - "strength_level": "1", - "id": "196", - "range_level": "20", - "attack_level": "1" + "strength_level": "5", + "weakness": "9" }, { + "id": "187", + "name": "Rogue", + "examine": "Rogueish.", + "aggressive": "false", + "attack_level": "7", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "7", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "7", + "weakness": "9" + }, + { + "id": "188", + "name": "Monk of Zamorak", + "examine": "An evil human cleric.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "22", + "end_gfx": "101", + "lifepoints": "20", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "422", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "strength_level": "18", + "weakness": "5" + }, + { + "id": "189", + "name": "Monk of Zamorak", + "examine": "An evil human cleric.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "12", + "end_gfx": "101", + "lifepoints": "10", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "422", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "strength_level": "8", + "weakness": "5" + }, + { + "id": "190", + "name": "Monk of Zamorak", + "examine": "An evil human cleric.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "42", + "end_gfx": "101", + "lifepoints": "40", + "magic_animation": "711", + "magic_level": "40", + "melee_animation": "422", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "strength_level": "38", + "weakness": "5" + }, + { + "id": "191", + "name": "Tribesman", + "examine": "A primitive warrior.", + "aggressive": "true", + "attack_level": "23", + "attack_speed": "4", + "bonuses": "8,8,8,0,0,4,6,6,0,0,0,5,0,0,0", + "clue_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "39", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "428", + "poison_amount": "55", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "27", + "weakness": "8" + }, + { + "id": "192", + "name": "Dark warrior", + "examine": "A warrior of Darkness.", + "attack_level": "10", + "attack_speed": "5", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "10", + "lifepoints": "10", + "melee_animation": "451", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "10", + "weakness": "8" + }, + { + "id": "193", + "name": "Chaos druid warrior", + "examine": "A crazy evil druid.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "12", + "end_gfx": "107", + "lifepoints": "20", + "magic_animation": "422", + "magic_level": "10", + "melee_animation": "422", + "projectile": "106", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "start_gfx": "105", + "strength_level": "8", + "weakness": "3" + }, + { + "id": "194", + "name": "Necromancer", + "examine": "A crazy evil necromancer.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "magic_level": "28", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "195", + "name": "Bandit" + }, + { + "id": "196", + "name": "Guard Bandit", + "examine": "Bandit Camp guard.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "386", + "range_animation": "0", + "range_level": "20", + "safespot": null, + "strength_level": "1", + "weakness": "1" + }, + { + "id": "197", + "name": "Barbarian guard" + }, + { + "id": "198", + "name": "Guildmaster", "examine": "Master of the Champions' Guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guildmaster", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "198", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "199", + "name": "Gunthor the Brave", "examine": "A mighty warrior!", + "attack_level": "29", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "29", + "lifepoints": "41", + "magic_animation": "0", "melee_animation": "395", "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Gunthor the Brave", - "defence_level": "29", + "range_level": "1", "safespot": null, - "lifepoints": "41", "strength_level": "29", - "id": "199", - "range_level": "1", - "attack_level": "29" + "weakness": "8" + }, + { + "id": "200", + "name": "Lord Daquarius" }, { - "examine": "Guards prisoners for the black knights.", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Jailer", - "defence_level": "40", - "safespot": null, - "lifepoints": "47", - "strength_level": "40", "id": "201", + "name": "Jailer", + "examine": "Guards prisoners for the black knights.", "aggressive": "false", + "attack_level": "40", + "attack_speed": "4", "bonuses": "0,0,0,0,0,79,63,47,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Has a fearsome scowl.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", "death_animation": "836", - "name": "Black Heather", - "defence_level": "28", - "lifepoints": "40", - "strength_level": "28", - "id": "202", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A rocky slug.", - "slayer_task": "69", - "melee_animation": "1595", - "range_animation": "1595", - "combat_audio": "729,731,730", - "attack_speed": "5", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "47", + "magic_animation": "0", "magic_level": "1", - "defence_animation": "1596", - "weakness": "7", - "magic_animation": "1595", - "death_animation": "1597", - "name": "Rockslug", - "defence_level": "30", - "safespot": null, - "lifepoints": "30", - "strength_level": "30", - "id": "1631", - "clue_level": "2", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "A rocky slug.", - "slayer_task": "69", - "melee_animation": "1595", - "range_animation": "1595", - "combat_audio": "729,731,730", - "attack_speed": "5", - "magic_level": "1", - "defence_animation": "1596", - "weakness": "7", - "magic_animation": "1595", - "death_animation": "1597", - "name": "Rockslug", - "defence_level": "30", - "safespot": null, - "lifepoints": "30", - "strength_level": "30", - "id": "1632", - "clue_level": "2", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "Has a fearsome posture.", - "melee_animation": "390", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Donny the Lad", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "203", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Nice hair.", - "melee_animation": "390", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Speedy Keith", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "204", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A crazy evil druid.", "melee_animation": "422", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Salarin the Twisted", - "defence_level": "62", - "safespot": null, - "lifepoints": "70", - "strength_level": "58", - "id": "205", - "aggressive": "true", - "bonuses": "45,50,43,55,39,31,19,28,33,22,22,15,13,9,8", "range_level": "1", - "attack_level": "58" + "respawn_delay": "50", + "safespot": null, + "strength_level": "40", + "weakness": "8" }, { + "id": "202", + "name": "Black Heather", + "examine": "Has a fearsome scowl.", + "attack_level": "28", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "strength_level": "28", + "weakness": "8" + }, + { + "id": "203", + "name": "Donny the Lad", + "examine": "Has a fearsome posture.", + "attack_level": "28", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "28", + "weakness": "9" + }, + { + "id": "204", + "name": "Speedy Keith", + "examine": "Nice hair.", + "attack_level": "28", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "28", + "weakness": "7" + }, + { + "id": "205", + "name": "Salarin the Twisted", + "examine": "A crazy evil druid.", + "aggressive": "true", + "attack_level": "58", + "bonuses": "45,50,43,55,39,31,19,28,33,22,22,15,13,9,8", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "62", + "lifepoints": "70", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "58" + }, + { + "id": "206", + "name": "Guard", "examine": "A dwarven guard.", - "slayer_task": "29", + "aggressive": "false", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "17", + "magic_animation": "0", "melee_animation": "99", "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "102", - "name": "Guard", - "defence_level": "12", + "range_level": "1", "safespot": null, - "lifepoints": "17", "strength_level": "12", - "id": "206", - "aggressive": "false", - "clue_level": "1", - "range_level": "1", - "attack_level": "12" + "weakness": "6" + }, + { + "id": "207", + "name": "Lollk" }, { - "examine": "The head honcho around here.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Lawgof", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "208", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks serene.", + "name": "Captain Lawgof", + "examine": "The head honcho around here.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Grail Maiden", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "209", + "name": "Nulodion" + }, + { "id": "210", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A former Knight of the Round Table.", + "name": "Grail Maiden", + "examine": "She looks serene.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Percival", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "211", + "name": "Sir Percival" + }, + { "id": "212", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks unhappy...", + "name": "King Percival", + "examine": "A former Knight of the Round Table.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Peasant", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "213", + "name": "Merlin" + }, + { "id": "214", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "High Priest of Entrana.", + "name": "Peasant", + "examine": "He looks unhappy...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "High Priest", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "215", + "name": "Peasant" + }, + { "id": "216", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a fisherman.", + "name": "High Priest", + "examine": "High Priest of Entrana.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fisherman", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "217", + "name": "Crone" + }, + { + "id": "218", + "name": "Galahad" + }, + { "id": "219", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He doesn't look very well...", + "name": "Fisherman", + "examine": "It's a fisherman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "The Fisher King", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "220", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "220", + "name": "The Fisher King", + "examine": "He doesn't look very well...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "221", + "name": "Black Knight Titan", "examine": "He looks mean and powerful.", + "aggressive": "true", + "attack_level": "91", + "attack_speed": "7", + "bonuses": "27,27,27,0,0,18,27,18,1000,1000,0,0,0,0,0", + "death_animation": "131", + "defence_animation": "0", + "defence_level": "91", + "lifepoints": "142", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "128", "range_animation": "0", - "attack_speed": "7", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "131", - "name": "Black Knight Titan", - "defence_level": "91", - "safespot": null, - "lifepoints": "142", - "strength_level": "100", - "id": "221", - "aggressive": "true", - "bonuses": "27,27,27,0,0,18,27,18,1000,1000,0,0,0,0,0", "range_level": "1", - "attack_level": "91" + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "10" }, { + "id": "222", + "name": "Monk", "examine": "A holy man.", + "attack_level": "7", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "magic_level": "10", "melee_animation": "422", "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "10", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "836", - "name": "Monk", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "7", - "id": "222", "range_level": "1", - "attack_level": "7" + "safespot": null, + "strength_level": "7", + "weakness": "5" }, { + "id": "223", + "name": "Brother Kojo", "examine": "A peaceful monk.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Kojo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "223", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "224", + "name": "Dungeon rat", "examine": "A dirty rat.", - "slayer_task": "67", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", "melee_animation": "4933", "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4935", - "name": "Dungeon rat", - "defence_level": "8", "safespot": null, - "lifepoints": "11", "strength_level": "8", - "id": "224", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" + "weakness": "9" + }, + { + "id": "225", + "name": "Bonzo" + }, + { + "id": "226", + "name": "Morris" + }, + { + "id": "228", + "name": "Big Dave" + }, + { + "id": "229", + "name": "Joshua" }, { - "examine": "He looks elderly.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Grandpa Jack", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "230", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He likes to cut down trees.", + "name": "Grandpa Jack", + "examine": "He looks elderly.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Forester", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "231", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I can fish here.", + "name": "Forester", + "examine": "He likes to cut down trees.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishing spot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "233", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "232", + "name": "Austri" + }, + { + "id": "233", + "name": "Fishing spot", + "examine": "I can fish here.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "234", + "name": "Fishing spot" + }, + { + "id": "235", + "name": "Fishing spot" + }, + { + "id": "236", + "name": "Fishing spot" + }, + { + "id": "237", + "name": "Renegade Knight", "examine": "He isn't very friendly.", + "aggressive": "true", + "attack_level": "15", + "death_animation": "6490", + "defence_animation": "0", + "defence_level": "15", + "lifepoints": "42", + "magic_animation": "0", "melee_animation": "6489", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6490", - "name": "Renegade Knight", - "defence_level": "15", - "safespot": null, - "lifepoints": "42", - "strength_level": "15", - "id": "237", - "aggressive": "true", "range_level": "1", - "attack_level": "15" + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "7" }, { + "id": "238", + "name": "Thrantax the Mighty", "examine": "A terrifying spirit.", + "attack_level": "50", + "death_animation": "5542", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "142", + "magic_animation": "0", "melee_animation": "5540", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5542", - "name": "Thrantax the Mighty", - "defence_level": "50", - "safespot": null, - "lifepoints": "142", - "strength_level": "50", - "id": "238", "range_level": "1", - "attack_level": "50" + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "7" }, { + "id": "239", + "name": "Sir Lancelot" + }, + { + "id": "240", + "name": "Sir Gawain" + }, + { + "id": "241", + "name": "Sir Kay" + }, + { + "id": "242", + "name": "Sir Bedivere" + }, + { + "id": "243", + "name": "Sir Tristram" + }, + { + "id": "244", + "name": "Sir Pelleas" + }, + { + "id": "245", + "name": "Sir Lucan" + }, + { + "id": "246", + "name": "Teapotspout", "examine": "Specialist meat transporter.", + "attack_level": "1", + "death_animation": "2301", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "2301", - "name": "Teapotspout", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "246", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { - "death_animation": "6490", + "id": "247", "name": "Sir Mordred", + "attack_level": "1", + "death_animation": "6490", + "defence_animation": "6488", "defence_level": "1", - "safespot": null, "lifepoints": "50", "melee_animation": "6489", - "strength_level": "1", - "id": "247", "range_level": "1", "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "6488" + "safespot": null, + "strength_level": "1" }, { + "id": "248", + "name": "Morgan Le Faye" + }, + { + "id": "249", + "name": "Merlin" + }, + { + "id": "250", + "name": "The Lady of the Lake" + }, + { + "id": "251", + "name": "King Arthur", "examine": "Legendary King of the Britons.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Arthur", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "251", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" + }, + { + "id": "252", + "name": "Beggar" }, { - "examine": "It's one of General Khazard's guards.", - "melee_animation": "395", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "397", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard Guard", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", "id": "253", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "He's been guarding the tavern for a bit too long.", + "name": "Khazard Guard", + "examine": "It's one of General Khazard's guards.", + "attack_level": "22", + "attack_speed": "6", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "397", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", "melee_animation": "395", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "6", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "397", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard Guard", - "defence_level": "22", "safespot": null, - "lifepoints": "31", "strength_level": "22", + "weakness": "6" + }, + { "id": "254", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "His armour indicates he's a Khazard Guard.", + "name": "Khazard Guard", + "examine": "He's been guarding the tavern for a bit too long.", + "attack_level": "22", + "attack_speed": "6", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "397", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", "melee_animation": "395", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "6", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "397", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard Guard", - "defence_level": "22", "safespot": null, - "lifepoints": "31", "strength_level": "22", + "weakness": "6" + }, + { "id": "255", - "range_level": "1", - "attack_level": "22" - }, - { + "name": "Khazard Guard", "examine": "His armour indicates he's a Khazard Guard.", + "attack_level": "22", + "attack_speed": "6", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "397", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", "melee_animation": "395", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "6", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "397", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard Guard", - "defence_level": "22", "safespot": null, - "lifepoints": "31", "strength_level": "22", + "weakness": "6" + }, + { "id": "256", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "He takes the slaves to the arena. He rarely takes them back..", + "name": "Khazard Guard", + "examine": "His armour indicates he's a Khazard Guard.", + "attack_level": "22", + "attack_speed": "6", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "397", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", "melee_animation": "395", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "397", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard Guard", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "257", "range_level": "1", - "attack_level": "22" + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" }, { + "id": "257", + "name": "Khazard Guard", + "examine": "He takes the slaves to the arena. He rarely takes them back..", + "attack_level": "22", + "attack_speed": "6", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "397", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "395", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" + }, + { + "id": "258", + "name": "General Khazard", "examine": "He looks really nasty. Smells bad too.", + "attack_level": "75", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "7050", + "defence_level": "80", + "lifepoints": "170", + "magic_animation": "0", "melee_animation": "7049", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "7050", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "General Khazard", - "defence_level": "80", "safespot": null, - "lifepoints": "170", "strength_level": "78", - "id": "258", - "range_level": "1", - "attack_level": "75" + "weakness": "6" }, { - "examine": "A tough looking barman.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "397", - "weakness": "6", - "magic_animation": "0", - "death_animation": "0", - "name": "Khazard barman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "259", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A slave fighter. He looks mistreated and weak.", + "name": "Khazard barman", + "examine": "A tough looking barman.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "397", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fightslave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "262", "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks wealthy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lady Servil", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "264", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A young squire. He looks worse for wear.", - "magic_animation": "0", - "death_animation": "0", - "name": "Jeremy Servil", - "defence_level": "0", - "safespot": null, - "lifepoints": "10", - "strength_level": "0", - "id": "265", - "clue_level": "0", - "range_level": "0", - "attack_level": "0" - }, - { - "examine": "A young squire. He looks worse for wear.", - "magic_animation": "0", - "death_animation": "0", - "name": "Jeremy Servil", - "defence_level": "0", - "safespot": null, - "lifepoints": "10", - "strength_level": "0", - "id": "266", - "clue_level": "0", - "range_level": "0", - "attack_level": "0" - }, - { - "examine": "Jeremy father, Sir Servil.", - "magic_animation": "0", - "death_animation": "0", - "name": "Justin Servil", - "defence_level": "0", - "safespot": null, - "lifepoints": "10", - "strength_level": "0", - "id": "267", - "clue_level": "0", - "range_level": "0", - "attack_level": "0" - }, - { - "examine": "A scruffy looking chap.", - "magic_animation": "0", - "death_animation": "0", - "name": "Local", - "defence_level": "0", - "safespot": null, - "lifepoints": "10", - "strength_level": "0", - "id": "268", - "clue_level": "0", - "range_level": "0", - "attack_level": "0" - }, - { - "melee_animation": "6581", "respawn_delay": "60", - "defence_animation": "6578", - "death_animation": "6576", - "name": "Bouncer", - "defence_level": "120", "safespot": null, - "lifepoints": "116", - "strength_level": "120", - "id": "269", - "aggressive": "true", - "range_level": "1", - "attack_level": "120" + "strength_level": "1", + "weakness": "6" }, { + "id": "260", + "name": "Kelvin" + }, + { + "id": "261", + "name": "Joe" + }, + { + "id": "262", + "name": "Fightslave", + "examine": "A slave fighter. He looks mistreated and weak.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "263", + "name": "Hengrad" + }, + { + "id": "264", + "name": "Lady Servil", + "examine": "She looks wealthy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "265", + "name": "Jeremy Servil", + "examine": "A young squire. He looks worse for wear.", + "attack_level": "0", + "clue_level": "0", + "death_animation": "0", + "defence_level": "0", + "lifepoints": "10", + "magic_animation": "0", + "range_level": "0", + "safespot": null, + "strength_level": "0" + }, + { + "id": "266", + "name": "Jeremy Servil", + "examine": "A young squire. He looks worse for wear.", + "attack_level": "0", + "clue_level": "0", + "death_animation": "0", + "defence_level": "0", + "lifepoints": "10", + "magic_animation": "0", + "range_level": "0", + "safespot": null, + "strength_level": "0" + }, + { + "id": "267", + "name": "Justin Servil", + "examine": "Jeremy father, Sir Servil.", + "attack_level": "0", + "clue_level": "0", + "death_animation": "0", + "defence_level": "0", + "lifepoints": "10", + "magic_animation": "0", + "range_level": "0", + "safespot": null, + "strength_level": "0" + }, + { + "id": "268", + "name": "Local", + "examine": "A scruffy looking chap.", + "attack_level": "0", + "clue_level": "0", + "death_animation": "0", + "defence_level": "0", + "lifepoints": "10", + "magic_animation": "0", + "range_level": "0", + "safespot": null, + "strength_level": "0" + }, + { + "id": "269", + "name": "Bouncer", + "aggressive": "true", + "attack_level": "120", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "120", + "lifepoints": "116", + "melee_animation": "6581", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "120" + }, + { + "id": "270", + "name": "Khazard Ogre", "examine": "Khazard's strongest ogre warrior.", + "aggressive": "true", + "attack_level": "46", + "attack_speed": "6", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,20,0,0,0", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "359", + "magic_level": "1", "melee_animation": "359", "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "360", - "magic_animation": "359", - "death_animation": "361", - "name": "Khazard Ogre", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "46", - "id": "270", - "aggressive": "true", - "bonuses": "22,22,22,0,0,0,0,0,0,0,0,20,0,0,0", "range_level": "1", - "attack_level": "46" + "respawn_delay": "25", + "safespot": null, + "strength_level": "46" }, { + "id": "271", + "name": "Khazard Scorpion", "examine": "A large angry scorpion", + "aggressive": "true", + "attack_level": "27", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", "melee_animation": "6254", "range_animation": "0", - "combat_audio": "3611,3612,3610", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "6256", - "name": "Khazard Scorpion", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "27", - "id": "271", - "aggressive": "true", "range_level": "36", - "attack_level": "27" + "safespot": null, + "strength_level": "27", + "weakness": "2" }, { + "id": "272", + "name": "Lucien", "examine": "He walks with a slight limp.", + "aggressive": "", + "attack_level": "12", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "10", + "lifepoints": "17", + "magic_animation": "0", + "magic_level": "1", "melee_animation": "401", "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "404", - "weakness": "", - "magic_animation": "0", - "death_animation": "836", - "name": "Lucien", - "defence_level": "10", - "safespot": null, - "lifepoints": "17", - "strength_level": "11", - "id": "272", - "aggressive": "", "range_level": "1", - "attack_level": "12" + "respawn_delay": "30", + "safespot": null, + "strength_level": "11", + "weakness": "" }, { + "id": "273", + "name": "Lucien", "examine": "He walks with a slight limp.", + "aggressive": "", + "attack_level": "12", + "combat_audio": "", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", "melee_animation": "", "range_animation": "", - "combat_audio": "", - "defence_animation": "404", - "weakness": "", - "magic_animation": "", - "death_animation": "836", - "name": "Lucien", - "defence_level": "", - "safespot": null, - "lifepoints": "", - "strength_level": "", - "id": "273", - "aggressive": "", "range_level": "", - "attack_level": "12" + "safespot": null, + "strength_level": "", + "weakness": "" }, { - "examine": "A guard who has devoted their life to Armadyl.", - "range_animation": "0", - "melee_animation": "401", - "combat_audio": "511,513,512", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Guardian of Armadyl", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", "id": "274", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A guard who has devoted their life to Armadyl.", - "range_animation": "0", - "melee_animation": "401", - "combat_audio": "511,513,512", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", "name": "Guardian of Armadyl", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "275", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Intimidating!", - "start_gfx": "99", - "combat_style": "2", - "start_height": "96", - "melee_animation": "0", - "range_animation": "0", + "examine": "A guard who has devoted their life to Armadyl.", + "attack_level": "30", "combat_audio": "511,513,512", - "attack_speed": "8", - "magic_level": "62", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "425", - "weakness": "3", - "magic_animation": "711", "death_animation": "836", - "name": "Fire Warrior of Lesarkus", - "defence_level": "78", + "defence_animation": "404", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", "safespot": null, - "lifepoints": "59", - "strength_level": "78", + "strength_level": "30", + "weakness": "8" + }, + { + "id": "275", + "name": "Guardian of Armadyl", + "examine": "A guard who has devoted their life to Armadyl.", + "attack_level": "30", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "8" + }, + { + "id": "276", + "name": "Winelda" + }, + { "id": "277", - "range_level": "1", + "name": "Fire Warrior of Lesarkus", + "examine": "Intimidating!", + "attack_level": "55", + "attack_speed": "8", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "78", + "end_gfx": "101", + "lifepoints": "59", + "magic_animation": "711", + "magic_level": "62", + "melee_animation": "0", "projectile": "127", - "attack_level": "55" + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "start_height": "96", + "strength_level": "78", + "weakness": "3" }, { - "examine": "Lumbridge Castle's head cook.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "278", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old monk.", + "name": "Cook", + "examine": "Lumbridge Castle's head cook.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Omad", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "279", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old drunk monk.", + "name": "Brother Omad", + "examine": "An old monk.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Cedric", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "280", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "280", + "name": "Brother Cedric", + "examine": "An old drunk monk.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "281", + "name": "Monk", "examine": "An Ardougne Monk.", + "attack_level": "4", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "4", + "lifepoints": "5", + "magic_animation": "0", "melee_animation": "422", "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Monk", - "defence_level": "4", - "safespot": null, - "lifepoints": "5", - "strength_level": "4", - "id": "281", "range_level": "1", - "attack_level": "4" + "safespot": null, + "strength_level": "4", + "weakness": "9" }, { + "id": "282", + "name": "Thief", "examine": "A dastardly blanket thief.", + "attack_level": "15", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "15", + "lifepoints": "21", + "magic_animation": "0", "melee_animation": "386", "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "15", - "safespot": null, - "lifepoints": "21", - "strength_level": "15", - "id": "282", "range_level": "1", - "attack_level": "15" + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "9" }, { + "id": "283", + "name": "Head Thief", "examine": "The head of the treacherous blanket stealing gang.", + "attack_level": "18", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", "melee_animation": "390", "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Head Thief", - "defence_level": "18", + "range_level": "1", "safespot": null, - "lifepoints": "25", "strength_level": "18", - "id": "283", - "range_level": "1", - "attack_level": "18" + "weakness": "9" }, { - "examine": "A dwarf smith. Quite handy with a hammer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Doric", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "284", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She doesn't look too happy.", + "name": "Doric", + "examine": "A dwarf smith. Quite handy with a hammer.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Veronica", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "285", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "285", + "name": "Veronica", + "examine": "She doesn't look too happy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "286", + "name": "Professor Oddenstein", + "examine": "A mad scientist if I ever saw one!" + }, + { + "id": "287", + "name": "Ernest" + }, + { + "id": "288", + "name": "Chicken", "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", "melee_animation": "5387", "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", + "range_level": "1", "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "288", - "range_level": "1", - "attack_level": "1" + "strength_level": "1" }, { - "examine": "An official of Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Councillor Halgrive", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "289", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A serious-looking doctor.", + "name": "Councillor Halgrive", + "examine": "An official of Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Doctor Orbon", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "290", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A farmer who's seen happier times.", + "name": "Doctor Orbon", + "examine": "A serious-looking doctor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer Brumty", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "291", + "name": "Farmer Brumty", + "examine": "A farmer who's seen happier times.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" + }, + { + "id": "292", + "name": "Guard" }, { - "examine": "He tries to keep order around here.", - "melee_animation": "7218", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "7219", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", "id": "296", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "7218", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "7220", "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "297", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { "examine": "He tries to keep order around here.", - "melee_animation": "7218", - "range_animation": "0", - "combat_audio": "511,513,512", + "attack_level": "25", "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", + "clue_level": "1", + "combat_audio": "511,513,512", "death_animation": "7219", - "name": "Guard", + "defence_animation": "0", "defence_level": "25", - "safespot": null, "lifepoints": "35", - "strength_level": "25", - "id": "298", - "clue_level": "1", + "magic_animation": "0", + "melee_animation": "7218", + "range_animation": "0", "range_level": "1", - "attack_level": "25" + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "7" }, { + "id": "297", + "name": "Guard", "examine": "He tries to keep order around here.", + "attack_level": "25", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "7220", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "7218", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "7" + }, + { + "id": "298", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "25", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "7219", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "7218", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "7" + }, + { + "id": "299", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "25", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "7213", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", "melee_animation": "583", "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", + "range_level": "1", "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "7213", - "name": "Guard", - "defence_level": "25", "safespot": null, - "lifepoints": "35", "strength_level": "25", - "id": "299", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" + "weakness": "7" + }, + { + "id": "300", + "name": "Sedridor", + "examine": "Chief of research at Wizards Tower." + }, + { + "id": "301", + "name": "Twig" + }, + { + "id": "302", + "name": "Hadley" + }, + { + "id": "303", + "name": "Gerald" + }, + { + "id": "304", + "name": "Almera" + }, + { + "id": "305", + "name": "Hudon" + }, + { + "id": "306", + "name": "Golrie" }, { - "examine": "An old motherly witch with a curious smile and a hooked nose.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hetty", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "307", + "name": "Hetty", + "examine": "An old motherly witch with a curious smile and a hooked nose.", "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The man in charge of the fishing guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master fisher", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "308", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He has a colourful personality.", + "name": "Master fisher", + "examine": "The man in charge of the fishing guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Da Vinci", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "309", + "name": "Fishing spot" + }, + { + "id": "310", + "name": "Fishing spot" + }, + { + "id": "311", + "name": "Fishing spot" + }, + { + "id": "312", + "name": "Fishing spot" + }, + { + "id": "313", + "name": "Fishing spot" + }, + { + "id": "314", + "name": "Fishing spot" + }, + { + "id": "315", + "name": "Fishing spot" + }, + { + "id": "316", + "name": "Fishing spot" + }, + { + "id": "317", + "name": "Fishing spot" + }, + { + "id": "318", + "name": "Fishing spot" + }, + { + "id": "319", + "name": "Fishing spot" + }, + { + "id": "320", + "name": "Fishing spot" + }, + { + "id": "321", + "name": "Fishing spot" + }, + { + "id": "322", + "name": "Fishing spot" + }, + { + "id": "323", + "name": "Fishing spot", + "examine": "I can see fish swimming in the water." + }, + { + "id": "324", + "name": "Fishing spot" + }, + { + "id": "325", + "name": "Fishing spot" + }, + { + "id": "326", + "name": "Fishing spot" + }, + { + "id": "327", + "name": "Fishing spot" + }, + { + "id": "328", + "name": "Fishing spot" + }, + { + "id": "329", + "name": "Fishing spot" + }, + { + "id": "330", + "name": "Fishing spot" + }, + { + "id": "331", + "name": "Fishing spot" + }, + { + "id": "332", + "name": "Fishing spot" + }, + { + "id": "333", + "name": "Fishing spot" + }, + { + "id": "334", + "name": "Fishing spot" + }, + { + "id": "335", + "name": "Elena", + "examine": "She doesn't look too happy." + }, + { "id": "336", + "name": "Da Vinci", + "examine": "He has a colourful personality.", "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's ready for a bet.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chancy", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "337", + "name": "Da Vinci" + }, + { "id": "338", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's ready for a bet.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", "name": "Chancy", + "examine": "He's ready for a bet.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", "defence_level": "1", - "safespot": null, "lifepoints": "10", - "strength_level": "1", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { "id": "339", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's drunk.", + "name": "Chancy", + "examine": "He's ready for a bet.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hops", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "340", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's drunk.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", "name": "Hops", + "examine": "He's drunk.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", "defence_level": "1", - "safespot": null, "lifepoints": "10", - "strength_level": "1", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { "id": "341", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks rather concerned.", + "name": "Hops", + "examine": "He's drunk.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guidor's wife", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "342", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He tries to keep order around here.", + "name": "Guidor's wife", + "examine": "She looks rather concerned.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "343", + "name": "Guidor" + }, + { "id": "344", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { + "name": "Guard", "examine": "He tries to keep order around here.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "345", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "346", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mourner, or plague healer.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mourner", - "defence_level": "24", - "safespot": null, - "lifepoints": "34", - "strength_level": "24", - "id": "347", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "A mourner, or plague healer.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mourner", - "defence_level": "24", - "safespot": null, - "lifepoints": "34", - "strength_level": "24", - "id": "348", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "2", - "safespot": null, - "lifepoints": "7", - "strength_level": "2", - "id": "351", - "clue_level": "0", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,506,505", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Woman", - "defence_level": "2", - "safespot": null, - "lifepoints": "7", - "strength_level": "2", - "id": "352", - "clue_level": "0", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,506,505", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Woman", - "defence_level": "2", - "safespot": null, - "lifepoints": "7", - "strength_level": "2", - "id": "353", - "clue_level": "0", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,506,505", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Woman", - "defence_level": "2", - "safespot": null, - "lifepoints": "7", - "strength_level": "2", - "id": "354", - "clue_level": "0", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "355", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Priest", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "358", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "6", - "respawn_delay": "18", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "9055", - "name": "Man", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "2", - "id": "359", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "4", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "7", - "strength_level": "1", - "id": "360", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "4", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "7", - "strength_level": "1", - "id": "361", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "4", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "7", - "strength_level": "1", - "id": "362", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "4", - "defence_animation": "404", - "weakness": "9", - "magic_animation": "422", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "7", - "strength_level": "1", - "id": "363", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "King Lathas of East Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Lathas", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "364", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy warrior.", - "name": "Paladin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "365", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Smells very chemically...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chemist", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "367", - "range_level": "1", - "attack_level": "1" - }, - { "examine": "He tries to keep order around here.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "368", + "attack_level": "1", "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mourner, or plague healer.", - "melee_animation": "422", - "range_animation": "0", + "combat_audio": "511,513,512", + "death_animation": "0", "defence_animation": "0", - "weakness": "9", + "defence_level": "1", + "lifepoints": "10", "magic_animation": "0", - "death_animation": "836", - "name": "Mourner", - "defence_level": "24", - "safespot": null, - "lifepoints": "34", - "strength_level": "24", - "id": "369", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "She's quite a looker!", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Nurse Sarah", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "373", "range_level": "1", - "attack_level": "1" + "safespot": null, + "strength_level": "1" }, { + "id": "346", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "347", + "name": "Mourner", + "examine": "A mourner, or plague healer.", + "attack_level": "8", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_level": "8", + "lifepoints": "18", + "melee_animation": "428", + "strength_level": "8" + }, + { + "id": "348", + "name": "Mourner", + "examine": "A mourner, or plague healer.", + "attack_level": "19", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_level": "19", + "lifepoints": "30", + "melee_animation": "422", + "strength_level": "19" + }, + { + "id": "349", + "name": "Kilron" + }, + { + "id": "350", + "name": "Omart" + }, + { + "id": "351", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "2", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "clue_level": "", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "13", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "" + }, + { + "id": "352", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "2", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "clue_level": "", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1", + "weakness": "" + }, + { + "id": "353", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "2", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "clue_level": "", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "13", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1", + "weakness": "" + }, + { + "id": "354", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "2", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "clue_level": "", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "13", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1", + "weakness": "" + }, + { + "id": "355", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "magic_level": "", + "melee_animation": "", + "movement_radius": "", + "poison_amount": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "356", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "magic_level": "", + "melee_animation": "", + "movement_radius": "", + "poison_amount": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "357", + "name": "Mourner", + "examine": "A mourner, or plague healer.", + "attack_level": "14", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_level": "14", + "lifepoints": "24", + "melee_animation": "428", + "strength_level": "14" + }, + { + "id": "358", + "name": "Priest", + "examine": "A holy man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "359", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "5", + "attack_speed": "4", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "422", + "magic_level": "6", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "2", + "weakness": "9" + }, + { + "id": "360", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "2", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "13", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1", + "weakness": "" + }, + { + "id": "361", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "10", + "lifepoints": "13", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "10", + "weakness": "" + }, + { + "id": "362", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "2", + "lifepoints": "10", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1", + "weakness": "" + }, + { + "id": "363", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "10", + "lifepoints": "23", + "magic_animation": "", + "melee_animation": "422", + "range_animation": "", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "10", + "weakness": "" + }, + { + "id": "364", + "name": "King Lathas", + "examine": "King Lathas of East Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "365", + "name": "Paladin", + "examine": "A holy warrior.", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "366", + "name": "Jerico" + }, + { + "id": "367", + "name": "Chemist", + "examine": "Smells very chemically...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "368", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "369", + "name": "Mourner", + "examine": "A mourner, or plague healer.", + "attack_level": "19", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_level": "19", + "lifepoints": "30", + "melee_animation": "422", + "strength_level": "19" + }, + { + "id": "370", + "name": "Mourner (boss)", + "examine": "A mourner, or plague healer.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,3,2,4,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_level": "10", + "lifepoints": "19", + "melee_animation": "428", + "strength_level": "10" + }, + { + "id": "371", + "name": "Mourner", + "examine": "A mourner, or plague healer.", + "attack_level": "8", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "836", + "defence_level": "8", + "lifepoints": "20", + "melee_animation": "422", + "strength_level": "8" + }, + { + "id": "372", + "name": "Mourner", + "examine": "A mourner, or plague healer." + }, + { + "id": "373", + "name": "Nurse Sarah", + "examine": "She's quite a looker!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "374", + "name": "Ogre", "examine": "Big, ugly, and smelly.", - "slayer_task": "64", + "aggressive": "true", + "attack_level": "27", + "attack_speed": "6", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "27", + "lifepoints": "60", + "magic_animation": "359", + "magic_level": "27", "melee_animation": "359", "range_animation": "359", - "attack_speed": "6", - "magic_level": "27", - "respawn_delay": "25", - "defence_animation": "360", - "weakness": "8", - "magic_animation": "359", - "death_animation": "361", - "name": "Ogre", - "defence_level": "27", - "safespot": null, - "lifepoints": "60", - "strength_level": "27", - "id": "374", - "aggressive": "true", - "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", "range_level": "27", - "attack_level": "27" + "respawn_delay": "25", + "safespot": null, + "strength_level": "27", + "weakness": "8" }, { - "examine": "A pirate. Smells of brine and brimstone. Also vomit.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "498,500,499", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Redbeard Frank", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", "id": "375", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Inspects people's packages.", + "name": "Redbeard Frank", + "examine": "A pirate. Smells of brine and brimstone. Also vomit.", + "attack_level": "1", + "combat_audio": "498,500,499", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Customs officer", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "376", + "name": "Captain Tobias", + "examine": "An old sea dog." + }, + { + "id": "377", + "name": "Seaman Lorris", + "examine": "A young sailor." + }, + { + "id": "378", + "name": "Seaman Thresnor", + "examine": "A young sailor." + }, + { + "id": "379", + "name": "Luthas", + "examine": "Owner of the banana plantation." + }, + { "id": "380", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf who looks after the mining guild.", + "name": "Customs officer", + "examine": "Inspects people's packages.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { + "id": "381", + "name": "Dwarf" + }, + { "id": "382", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not very civilised looking.", + "name": "Dwarf", + "examine": "A dwarf who looks after the mining guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barbarian guard", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "383", + "name": "Stankers" + }, + { "id": "384", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks vicious!", + "name": "Barbarian guard", + "examine": "Not very civilised looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "combat_audio": "3611,3612,3610", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Kharid Scorpion", - "defence_level": "1", + "range_level": "1", "safespot": null, - "lifepoints": "10", - "strength_level": "1", + "strength_level": "1" + }, + { "id": "385", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks vicious!", "name": "Kharid Scorpion", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3611,3612,3610", - "strength_level": "1", - "id": "386", - "range_level": "1", - "attack_level": "1" - }, - { "examine": "Looks vicious!", - "name": "Kharid Scorpion", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", + "attack_level": "1", "combat_audio": "3611,3612,3610", - "strength_level": "1", - "id": "387", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with a shave...", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", "melee_animation": "0", "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "0", - "name": "Seer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "388", "range_level": "1", - "attack_level": "1" + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" }, { + "id": "386", + "name": "Kharid Scorpion", + "examine": "Looks vicious!", + "attack_level": "1", + "combat_audio": "3611,3612,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "387", + "name": "Kharid Scorpion", + "examine": "Looks vicious!", + "attack_level": "1", + "combat_audio": "3611,3612,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "388", + "name": "Seer", + "examine": "Could do with a shave...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "389", + "name": "Thormac", + "examine": "Nice hat." + }, + { + "id": "390", + "name": "Big fish", "examine": "A brightly coloured game bird.", + "attack_level": "3", + "death_animation": "2373", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "1", + "magic_animation": "0", "melee_animation": "2371", "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "2373", - "name": "Big fish", - "defence_level": "3", - "safespot": null, - "lifepoints": "1", - "strength_level": "3", - "id": "390", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "Likes fish... hates people.", - "melee_animation": "284", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "285", - "magic_animation": "0", - "death_animation": "287", - "name": "River troll", - "defence_level": "32", - "safespot": null, - "lifepoints": "35", - "strength_level": "32", - "id": "392", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "Beefy.", - "slayer_task": "20", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "369,371,370", - "attack_speed": "5", - "defence_animation": "5850", - "weakness": "8", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "397", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Legends Guild guard; he protects the entrance to the Legends Guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Legends guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "398", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He deals in exotic types of wood.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jungle forester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "401", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She deals in exotic types of wood.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jungle forester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "402", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Insects buzzing around.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "819,821,820", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Swarm", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "411", - "aggressive": "false", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An annoying flappy thing.", - "slayer_task": "5", - "melee_animation": "4915", - "range_animation": "4915", - "attack_speed": "5", - "magic_level": "10", - "respawn_delay": "30", - "defence_animation": "4916", - "weakness": "4", - "slayer_exp": "8", - "death_animation": "4918", - "name": "Bat", - "defence_level": "2", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "412", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "5", - "magic_level": "5", - "defence_animation": "5574", - "magic_animation": "5578", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "20", - "safespot": null, - "lifepoints": "14", - "strength_level": "5", - "id": "419", - "range_level": "5", - "attack_level": "5" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "5", - "magic_level": "10", - "defence_animation": "5574", - "magic_animation": "5578", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "40", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "420", - "range_level": "10", - "attack_level": "10" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "5", - "magic_level": "15", - "defence_animation": "5574", - "magic_animation": "5578", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "50", - "safespot": null, - "lifepoints": "30", - "strength_level": "15", - "id": "421", - "range_level": "15", - "attack_level": "15" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "5", - "magic_level": "45", - "defence_animation": "5574", - "magic_animation": "5578", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "60", - "safespot": null, - "lifepoints": "79", - "strength_level": "45", - "id": "422", - "range_level": "45", - "attack_level": "45" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "5", - "magic_level": "35", - "defence_animation": "5574", - "magic_animation": "5578", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "45", - "id": "423", - "range_level": "45", - "attack_level": "45" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "931,923,922", - "attack_speed": "5", - "magic_level": "45", - "defence_animation": "5574", - "magic_animation": "5578", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "90", - "safespot": null, - "lifepoints": "159", - "strength_level": "45", - "id": "424", - "range_level": "45", - "attack_level": "45" - }, - { - "examine": "Dead but not gone.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,439,438", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Shade", - "defence_level": "7", - "safespot": null, - "lifepoints": "8", - "strength_level": "6", - "id": "425", - "range_level": "1", - "attack_level": "6" - }, - { - "examine": "Dead but not gone.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,439,438", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Shade", - "defence_level": "30", - "safespot": null, - "lifepoints": "17", - "strength_level": "20", - "id": "426", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Dead but not gone.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,439,438", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Shade", - "defence_level": "45", - "safespot": null, - "lifepoints": "28", - "strength_level": "43", - "id": "427", - "range_level": "1", - "attack_level": "43" - }, - { - "examine": "Dead but not gone.", - "slayer_task": "73", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,439,438", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "4.2", - "magic_animation": "0", - "death_animation": "836", - "name": "Shade", - "defence_level": "80", - "safespot": null, - "lifepoints": "42", - "strength_level": "74", - "id": "428", - "range_level": "1", - "attack_level": "74" - }, - { - "examine": "Dead but not gone.", - "slayer_task": "73", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,439,438", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "4.2", - "magic_animation": "0", - "death_animation": "836", - "name": "Shade", - "defence_level": "130", - "safespot": null, - "lifepoints": "170", - "strength_level": "90", - "id": "429", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "Dead but not gone.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Shade", - "defence_level": "105", - "safespot": null, - "lifepoints": "100", - "strength_level": "150", - "id": "430", - "range_level": "1", - "attack_level": "150" - }, - { - "examine": "I hope he's not dead!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fallen Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "435", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Entrance clerk for the Brimhaven Agility Arena.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "498,500,499", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cap'n Izzy No-Beard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "437", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "combat_audio": "498,500,499", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "95", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "8", - "safespot": null, - "lifepoints": "25", - "strength_level": "8", - "id": "438", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "combat_audio": "498,500,499", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "95", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "17", - "safespot": null, - "lifepoints": "40", - "strength_level": "17", - "id": "439", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "17" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "combat_audio": "498,500,499", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "95", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "38", - "safespot": null, - "lifepoints": "60", - "strength_level": "38", - "id": "440", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "combat_audio": "498,500,499", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "95", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "64", - "safespot": null, - "lifepoints": "86", - "strength_level": "64", - "id": "441", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "combat_audio": "498,500,499", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "95", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "100", - "safespot": null, - "lifepoints": "120", - "strength_level": "100", - "id": "442", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "combat_audio": "498,500,499", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "95", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "130", - "safespot": null, - "lifepoints": "170", - "strength_level": "130", - "id": "443", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "444", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "445", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "2", - "safespot": null, - "lifepoints": "5", - "strength_level": "5", - "id": "446", - "aggressive": "true", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "I wonder who he's guarding?", - "melee_animation": "401", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Jail guard", - "defence_level": "21", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "447", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "I wonder who he's guarding?", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Jail guard", - "defence_level": "21", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "448", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "I wonder who he's guarding?", - "melee_animation": "401", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Jail guard", - "defence_level": "21", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "449", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "A large well built farmer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Seth Groats", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "452", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aargh! It's alive!", - "melee_animation": "390", - "range_animation": "0", - "attack_speed": "5", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Suit of armour", - "defence_level": "9", - "safespot": null, - "lifepoints": "29", - "strength_level": "14", - "id": "453", - "bonuses": "8,8,8,0,0,46,50,46,-12,45,0,10,0,0,0", - "range_level": "1", - "attack_level": "16" - }, - { - "examine": "He seems to be very devout.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Father Aereck", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "456", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eek! A ghost!", - "name": "Restless ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "457", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very holy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Father Urhney", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "458", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Wizard of the Magic Guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard Frumscone", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "460", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Supplier of Magical items.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Magic Store owner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "461", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Head of the Magic Guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard Distentor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "462", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a gnome. He looks important.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Bolren", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "469", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tree gnome.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Commander Montai", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "470", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's one of General Khazard's warriors.", - "melee_animation": "401", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard trooper", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "475", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "An open eye of World-gorger.", - "magic_level": "5", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "name": "Khazard trooper", - "defence_level": "5", - "safespot": null, - "lifepoints": "11", - "strength_level": "1", - "id": "476", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks real nasty", - "melee_animation": "401", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard warlord", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "38", - "id": "477", - "aggressive": "true", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "It's one of General Khazard's commanders.", - "melee_animation": "428", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard commander", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "478", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "It's a tree gnome trooper.", - "melee_animation": "190", - "range_animation": "0", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome troop", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "24", - "id": "479", - "range_level": "32", - "attack_level": "24" - }, - { - "examine": "It's a gnome who specialises in covert operations.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tracker gnome 1", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "481", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a gnome who specialises in covert operations.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tracker gnome 2", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "482", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a gnome who specialises in covert operations.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tracker gnome 3", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "483", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a young tree gnome.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Local Gnome", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "485", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I guess he wants to be more than just the muscle.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Giant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "487", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He doesn't look like he'd trust his own mother.", - "slayer_task": "38", - "melee_animation": "6199", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6190", - "name": "Goblin guard", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "489", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "If the mummy is at school", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mummy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "490", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5540", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5541", - "slayer_exp": "25", - "death_animation": "5542", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "491", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The essence of evil.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spirit of Scorpius", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "492", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A vicious", - "slayer_task": "71", - "melee_animation": "6261", - "range_animation": "0", - "combat_audio": "3611,3612,3610", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "6260", - "name": "Grave scorpion", - "defence_level": "7", - "safespot": null, - "lifepoints": "10", - "strength_level": "5", - "id": "493", - "aggressive": "true", - "range_level": "7", - "attack_level": "5" - }, - { - "examine": "He can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "494", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Good with money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "495", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Manages money momentarily.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "498", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "499", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A minion of Rashiliyia.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Undead one", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "502", - "aggressive": "true", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "A minion of Rashiliyia.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Undead one", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "503", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "The animated dead; one of Rashiliyia's minions.", - "slayer_task": "93", - "melee_animation": "5568", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5569", - "name": "Undead one", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "504", - "aggressive": "true", "range_level": "1", - "attack_level": "32" - }, - { - "examine": "The animated dead; one of Rashiliyia's minions.", - "slayer_task": "93", - "melee_animation": "5571", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5575", - "name": "Undead one", - "defence_level": "33", "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "505", - "aggressive": "true", - "range_level": "1", - "attack_level": "33" - }, - { - "melee_animation": "5571", - "respawn_delay": "60", - "defence_animation": "5574", - "death_animation": "5575", - "name": "Nazastarool", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "507", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5507", - "respawn_delay": "60", - "defence_animation": "5508", - "death_animation": "5509", - "name": "Nazastarool", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "508", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5532", - "respawn_delay": "60", - "defence_animation": "5533", - "death_animation": "5534", - "name": "Nazastarool", - "defence_level": "1", - "safespot": null, - "lifepoints": "110", - "strength_level": "1", - "id": "509", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's the Captain of the 'Lady of the Waves'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Shanks", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "518", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An expert on axes.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bob", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "519", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sells stuff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "520", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Helps sell stuff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "521", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Likes people spending money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "522", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Likes helping sell stuff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "523", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A product of a consumerist society.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "524", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Likes you more, the more you spend.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "525", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A product of a consumerist society.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "526", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Likes you more, the more you spend.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "527", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Has an interesting assortment of items for sale.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "530", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Works on commission.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "531", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He clearly takes pride in his appearance.", - "range_animation": "0", - "magic_level": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Shopkeeper Kofi", - "defence_level": "60", - "safespot": null, - "lifepoints": "285", - "strength_level": "60", - "id": "532", - "aggressive": "true", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Needs a haircut.", - "range_animation": "0", - "magic_level": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Shop assistant", - "defence_level": "60", - "safespot": null, - "lifepoints": "285", - "strength_level": "60", - "id": "533", - "aggressive": "true", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Sells stuff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "534", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sells stuff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "535", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very snappily dressed.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Silk trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "539", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Makes his money selling rocks.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gem trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "540", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "For the finest in armoured legware.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Louie Legs", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "542", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Ironically, makes a living from swords.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "551", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Helps the shopkeeper sell swords.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shop assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "552", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "For the interesting clothing items you just can't find elsewhere.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fancy-dress shop owner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "554", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Has a fine moustache.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "555", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could stand to lose a few pounds.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "561", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Has an odd smell about him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Candle-maker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "562", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A being from a mysterious realm.", - "name": "Jukat", - "id": "564" - }, - { - "examine": "Is he invisible, or just floating clothing?", - "name": "Irksol", - "id": "566" - }, - { - "examine": "Looks strange and mysterious.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "567", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks fairly well fed.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Silver merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "569", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Seems very well-off.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gem merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "570", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "So where are the butcher and the candlestick-maker?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "571", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Has a very exotic aroma about him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spice seller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "572", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Knows how to keep warm in the winter.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fur trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "573", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Seems very well-off.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Silk merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "574", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He runs a Mining store.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Drogo dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "579", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wonder if he wants to buy my junk?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "582", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to sell tea.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tea seller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "595", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A pizza expert; in both making and eating.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fat Tony", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "596", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Anyone fancy a trim?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hairdresser", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "598", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Master of the mystical make-over.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Make-over Mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "599", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Indentured servant of a Knight.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "606", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A generic evil henchman.", - "melee_animation": "428", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Fortress Guard", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "609", - "range_level": "1", - "attack_level": "26" - }, - { - "examine": "One of the Black Knights.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Black Knight Captain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "610", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Black Knights' resident witch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Witch", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "611", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This person is working on the site.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Digsite workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "613", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This person is working on the site.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Doug Deeping", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "614", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A student busy studying the digsite.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Student", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "615", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A student busy studying the digsite.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Student", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "616", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A student busy studying the digsite.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Student", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "617", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Upon examining the examiner you examine it is indeed an examiner!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Examiner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "618", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An expert on archaeology.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Archaeological expert", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "619", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A specialist in panning for gold.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Panning guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "620", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A professional gnome baller.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome baller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "621", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A professional gnome baller.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome winger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "633", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Keeps the game fair.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome ball referee", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "635", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dealer in potions.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Apothecary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "638", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A religious man... And occasional drunk.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Father Lawrence", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "640", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks down on his luck.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Charlie the Tramp", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "641", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks kind of obsessive...", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Weaponsmaster", - "defence_level": "15", - "safespot": null, - "lifepoints": "42", - "strength_level": "15", - "id": "643", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Looks kind of shifty...", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "498,500,499", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Jonny the beard", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "645", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Curator of the museum.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Curator Haig Halen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "646", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Varrock's resident monarch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Roald", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "648", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks quite experienced.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Archer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "649", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks big and dumb.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "650", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks holy.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "651", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks kind of puny...", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "652", - "range_level": "1", - "attack_level": "1", - "prj_height": "3" - }, - { - "examine": "Guardian of the dramen tree.", - "melee_animation": "5532", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5534", - "name": "Tree spirit", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "655", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Unsurprisingly monk like.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "656", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holy looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk of Entrana", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "657", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holy looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk of Entrana", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "658", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He likes to paaaarty!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Party Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "659", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "660", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "663", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A short and angry dwarf.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "665", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Chronozon the blood demon.", - "melee_animation": "64", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "death_animation": "67", - "name": "Chronozon", - "defence_level": "173", - "safespot": null, - "lifepoints": "60", - "strength_level": "172", - "id": "667", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "173" - }, - { - "examine": "An important looking gnome.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Narnode Shareen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "670", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The boss!", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Foreman", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "674", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A big, scary, jet-black demon.", - "slayer_task": "8", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "397,399,398", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "157", - "magic_animation": "64", - "death_animation": "67", - "name": "Black demon", - "defence_level": "152", - "safespot": null, - "lifepoints": "157", - "strength_level": "148", - "id": "677", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "145" - }, - { - "examine": "Keeps order in the ranging guild.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "678", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The keeper of the gates to the ranging guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ranging Guild Doorman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "679", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An expert leatherworker.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Leatherworker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "680", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Mysterious swamp lights...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Held vampyre juvinate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "681", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Supplier of Rangers armour.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Armour salesman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "682", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Supplier of Archery equipment.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bow and Arrow salesman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "683", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Tower keeper and competition judge.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tower Advisor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "684", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Defender of the north tower.", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Tower Archer", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "7", - "id": "688", - "aggressive": "true", - "range_level": "10", - "attack_level": "7" - }, - { - "examine": "Defender of the east tower.", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Tower Archer", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "15", - "id": "689", - "aggressive": "true", - "range_level": "20", - "attack_level": "15" - }, - { - "examine": "Defender of the south tower.", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Tower Archer", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "22", - "id": "690", - "aggressive": "true", - "range_level": "30", - "attack_level": "22" - }, - { - "examine": "Defender of the west tower.", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Tower Archer", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "30", - "id": "691", - "aggressive": "true", - "range_level": "40", - "attack_level": "30" - }, - { - "examine": "Supplier of authentic throwing weapons.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tribal Weapon Salesman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "692", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sells equipment in exchange for archery tickets.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ticket Merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "694", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Harlan, ready to teach swordplay.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Melee tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "705", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old wizard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard Mizgog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "706", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A cheeky little imp.", - "melee_animation": "169", - "range_animation": "169", - "combat_audio": "534,536,535", - "attack_speed": "5", - "defence_animation": "170", - "weakness": "7", - "magic_animation": "169", - "death_animation": "172", - "name": "Imp", - "defence_level": "2", - "safespot": null, - "movement_radius": "25", - "lifepoints": "8", - "strength_level": "2", - "id": "708", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "A cheeky little imp.", - "melee_animation": "169", - "range_animation": "169", - "combat_audio": "534,536,535", - "attack_speed": "5", - "defence_animation": "170", - "magic_animation": "169", - "death_animation": "172", - "name": "Imp", - "defence_level": "1", - "safespot": null, - "movement_radius": "25", - "lifepoints": "8", - "strength_level": "1", - "id": "709", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bureaucratic administrator.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Clerk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "713", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "0", - "examine": "A local civilian.", - "name": "Edmond", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "714", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "In charge of people with silly outfits.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Head mourner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "716", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the Ardougne Royal Army.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Recruiter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "720", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "726", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "727", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "728", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "729", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "730", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I could get a beer from him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "731", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I could get a beer from him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "732", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I could get a beer from him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "735", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I could get a beer from him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "737", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I could get a beer from him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "738", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I could get a beer from him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "739", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Duke Horacio of Lumbridge.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Duke Horacio", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "741", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "Roar! A dragon!", - "melee_animation": "80", - "attack_speed": "4", - "magic_level": "70", - "respawn_delay": "35", - "defence_animation": "89", - "death_animation": "4642", - "name": "Elvarg", - "defence_level": "70", - "safespot": null, - "lifepoints": "80", - "strength_level": "70", - "id": "742", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A badly-behaved goblin.", - "slayer_task": "38", - "melee_animation": "6184", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6204", - "name": "Wormbrain", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "745", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a tad upset.", - "melee_animation": "6726", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6727", - "name": "Angry barbarian spirit", - "defence_level": "76", - "safespot": null, - "lifepoints": "108", - "strength_level": "76", - "id": "749", - "aggressive": "true", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "He looks a tad upset.", - "melee_animation": "6726", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6727", - "name": "Enraged barbarian spirit", - "defence_level": "76", - "safespot": null, - "lifepoints": "108", - "strength_level": "76", - "id": "750", - "aggressive": "true", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "He looks a tad upset.", - "melee_animation": "6726", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6727", - "name": "Berserk barbarian spirit", - "defence_level": "76", - "safespot": null, - "lifepoints": "108", - "strength_level": "76", - "id": "751", - "aggressive": "true", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "He looks a tad upset.", - "melee_animation": "6726", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6727", - "name": "Ferocious barbarian spirit", - "defence_level": "76", - "safespot": null, - "lifepoints": "190", - "strength_level": "76", - "id": "752", - "aggressive": "true", - "bonuses": "80,100,60,70,85,70,70,90,60,100,50,90,90,0,0", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "He looks totally insane!", - "melee_animation": "423", - "range_animation": "0", - "magic_level": "28", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Melzar the Mad", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "753", - "aggressive": "true", - "range_level": "28", - "attack_level": "28" - }, - { - "examine": "Stop looking and run!", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Count Draynor", - "defence_level": "20", - "safespot": null, - "lifepoints": "4", - "strength_level": "1", - "id": "757", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A well-fed farmer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fred the Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "758", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "2", - "melee_animation": "192", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "194", - "death_animation": "196", - "name": "Crate", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "767", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Overgrown cat", - "defence_level": "1", - "safespot": null, - "lifepoints": "66", - "strength_level": "1", - "id": "778", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A citizen of Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Civilian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "785", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A citizen of Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Civilian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "786", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A citizen of Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Civilian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "787", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome who's supposed to be cleaning up a mess.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Letham", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "790", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Smartly dressed", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Alfonse the waiter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "793", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Distinctly cook-like.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Charlie the cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "794", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A cold hearted lady.", - "melee_animation": "422", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Ice Queen", - "defence_level": "55", - "safespot": null, - "lifepoints": "157", - "strength_level": "55", - "id": "795", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "He looks cold and hungry.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Velrak the explorer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "798", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A morally ambiguous guard.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Pirate Guard", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "799", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "It looks like there might be eels swimming in the lava.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishing spot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "800", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Abbot Langley", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "801", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Jered", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "802", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Monk", - "defence_level": "12", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "803", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "Manufacturer of fine leathers.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tanner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "804", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's in charge of the Crafting Guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master Crafter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "805", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks very tired...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Donovan the Family Handyman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "806", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An officer of the Law.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "812", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of those people who love to gossip!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gossip", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "813", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He sure likes to sell stuff!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Poison Salesman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "820", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Big", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sinclair Guard dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "821", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It looks like he's been here a long time.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Male slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "825", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Rowdy slave", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "827", - "aggressive": "true", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mercenary Captain", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "1", - "id": "830", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's in control of the whole mining camp.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Siad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "831", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Bedabin nomad", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bedabin Nomad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "833", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Bedabin nomad guard - it looks like he's protecting an area.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bedabin Nomad Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "834", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He patrols the Shantay Pass.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Shantay Guard", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "837", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "He patrols the Shantay Pass.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shantay Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "838", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A vicious desert wolf.", - "slayer_task": "92", - "melee_animation": "6559", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6558", - "name": "Desert Wolf", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "839", - "range_level": "1", - "attack_level": "11" - }, - { - "death_animation": "9674", - "name": "Ugthanki", - "defence_level": "1", - "safespot": null, - "lifepoints": "46", - "strength_level": "1", - "attack_speed": "5", - "id": "840", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "He looks busy attending to his cart.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mine cart driver", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "841", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This pickaxe has been possessed by a dwarf ancestor spirit.", - "melee_animation": "185", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "188", - "name": "Rowdy Guard", - "defence_level": "40", - "safespot": null, - "lifepoints": "400", - "strength_level": "40", - "id": "842", - "aggressive": "true", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Inefficient looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "RPDT employee", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "843", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Despite his name", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Head chef", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "847", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The famous tree gnome chef.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Aluft Gianne snr.", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "850", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can serve you gnome food.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome Waiter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "851", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Tough-looking.", - "slayer_task": "64", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "300", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Ogre chieftain", - "defence_level": "75", - "safespot": null, - "lifepoints": "60", - "strength_level": "71", - "id": "852", - "bonuses": "5,5,5,0,0,0,0,0,0,0,0,7,0,0,0", - "range_level": "1", - "attack_level": "75" - }, - { - "name": "Gorad", - "defence_level": "1", - "safespot": null, - "lifepoints": "81", - "strength_level": "1", - "id": "856", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "These ogres protect the city.", - "slayer_task": "64", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Ogre guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "858", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ogre that guards.", - "slayer_task": "64", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Ogre guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "859", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Tries to keep the peace.", - "slayer_task": "64", - "melee_animation": "2100", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "8576", - "name": "City guard", - "defence_level": "58", - "safespot": null, - "lifepoints": "331", - "strength_level": "58", - "id": "862", - "range_level": "1", - "attack_level": "58" - }, - { - "examine": "Frightened-looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Scared skavid", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "863", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks mad.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mad skavid", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "864", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Big and ugly looking.", - "slayer_task": "64", - "melee_animation": "2100", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "8576", - "name": "Enclave guard", - "defence_level": "58", - "safespot": null, - "lifepoints": "331", - "strength_level": "58", - "id": "870", - "range_level": "1", - "attack_level": "58" - }, - { - "examine": "The hat is a dead giveaway.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Watchtower Wizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "872", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Funnily enough", - "slayer_task": "64", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ogre trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "873", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Funnily enough", - "slayer_task": "64", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ogre merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "874", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Funnily enough", - "slayer_task": "64", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ogre trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "875", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Tries to keep the peace.", - "melee_animation": "386", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Tower guard", - "defence_level": "17", - "safespot": null, - "lifepoints": "97", - "strength_level": "17", - "id": "877", - "range_level": "1", - "attack_level": "17" - }, - { - "melee_animation": "395", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Colonel Radick", - "defence_level": "1", - "safespot": null, - "lifepoints": "71", - "strength_level": "1", - "id": "878", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "67", - "name": "Delrith", - "defence_level": "1", - "safespot": null, - "lifepoints": "7", - "melee_animation": "64", - "strength_level": "1", - "id": "879", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "65" - }, - { - "examine": "The head of the palace guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Rovin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "884", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Head of the Carnillean household.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ceril Carnillean", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "885", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "887", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Clivet", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "melee_animation": "811", - "strength_level": "1", - "id": "893", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "A member of the Hazeel cult.", - "melee_animation": "422", - "range_animation": "0", - "magic_level": "20", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "836", - "name": "Hazeel Cultist", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "15", - "id": "894", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Children are just like real people...just smaller.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "895", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks unnatural.", - "melee_animation": "255", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "258", - "name": "Witch's experiment", - "defence_level": "19", - "safespot": null, - "lifepoints": "21", - "strength_level": "10", - "id": "897", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "Looks unnatural.", - "melee_animation": "5327", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5329", - "name": "Witch's experiment (second form)", - "defence_level": "29", - "safespot": null, - "lifepoints": "31", - "strength_level": "20", - "id": "898", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Looks unnatural.", - "melee_animation": "4925", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "4929", - "name": "Witch's experiment (third form)", - "defence_level": "39", - "safespot": null, - "lifepoints": "41", - "strength_level": "30", - "id": "899", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "Looks unnatural.", - "melee_animation": "6559", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6558", - "name": "Witch's experiment (fourth form)", - "defence_level": "49", - "safespot": null, - "lifepoints": "51", - "strength_level": "40", - "id": "900", - "range_level": "1", - "attack_level": "48" - }, - { - "examine": "He hasn't seen much sun lately.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chamber guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "904", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "0", - "examine": "Runs the Mage Arena.", - "name": "Kolodion", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "905", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's a shape-shifter", - "combat_style": "2", - "melee_animation": "811", - "attack_speed": "7", - "magic_level": "75", - "defence_animation": "404", - "slayer_exp": "0", - "death_animation": "1816", - "name": "Kolodion", - "defence_level": "20", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "907", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "He's a shape-shifter", - "combat_style": "2", - "melee_animation": "132", - "attack_speed": "7", - "magic_level": "89", - "defence_animation": "404", - "slayer_exp": "0", - "death_animation": "133", - "name": "Kolodion", - "defence_level": "25", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "908", - "range_level": "1", - "attack_level": "74" - }, - { - "examine": "He's a shape-shifter", - "combat_style": "2", - "melee_animation": "5322", - "attack_speed": "7", - "magic_level": "89", - "defence_animation": "5320", - "slayer_exp": "0", - "death_animation": "5323", - "name": "Kolodion", - "defence_level": "28", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "909", - "range_level": "1", - "attack_level": "74" - }, - { - "examine": "He's a shape-shifter", - "combat_style": "2", - "melee_animation": "811", - "attack_speed": "7", - "magic_level": "89", - "defence_animation": "404", - "slayer_exp": "0", - "death_animation": "714", - "name": "Kolodion", - "defence_level": "30", - "safespot": null, - "lifepoints": "78", - "strength_level": "1", - "id": "910", - "range_level": "1", - "attack_level": "74" - }, - { - "examine": "He's a shape-shifter", - "melee_animation": "69", - "attack_speed": "7", - "magic_level": "80", - "defence_animation": "65", - "slayer_exp": "0", - "death_animation": "68", - "name": "Kolodion", - "defence_level": "105", - "safespot": null, - "lifepoints": "107", - "strength_level": "98", - "id": "911", - "range_level": "1", - "attack_level": "85" - }, - { - "examine": "He kills in the name of Zamorak.", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "50", - "respawn_delay": "150", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "836", - "name": "Battle mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "912", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He kills in the name of Saradomin.", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "50", - "respawn_delay": "150", - "defence_animation": "0", - "weakness": "3", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Battle mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "913", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He kills in the name of Guthix.", - "combat_style": "2", - "melee_animation": "197", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "50", - "respawn_delay": "150", - "defence_animation": "0", - "weakness": "3", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "196", - "name": "Battle mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "914", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A crafter at the pinnacle of his art.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Joe", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "916", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wonder who he's guarding?", - "melee_animation": "401", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Jail guard", - "defence_level": "21", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "917", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "The emir's chief advisor and physician.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hassan", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "923", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Guards the border between Al Kharid and the Kingdom of Misthalin.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Border Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "925", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An aggressive native of the Kharazi Jungle.", - "melee_animation": "428", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Jungle savage", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "44", - "id": "931", - "aggressive": "true", - "range_level": "1", - "attack_level": "44" - }, - { - "melee_animation": "64", - "respawn_delay": "60", - "defence_animation": "65", - "death_animation": "67", - "name": "Nezikchened", - "defence_level": "1", - "safespot": null, - "lifepoints": "150", - "strength_level": "1", - "id": "934", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5485", - "respawn_delay": "60", - "defence_animation": "5489", - "death_animation": "5491", - "name": "Ranalph Devere", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "938", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wonder what this is doing here.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boulder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "939", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Must be related to Elvarg.", - "slayer_task": "41", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "68", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "75", - "magic_animation": "80", - "death_animation": "92", - "name": "Green dragon", - "defence_level": "68", - "safespot": null, - "lifepoints": "75", - "strength_level": "68", - "id": "941", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "An expert on all things culinary.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master chef", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "942", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very much an outdoors type.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Survival expert", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "943", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An expert on all forms of combat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Combat instructor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "944", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Your introduction to the world of Gielinor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "RuneScape guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "945", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A master of Magic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Magic instructor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "946", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An official representative from the First National Bank of Gielinor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Financial advisor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "947", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An expert on Mining-related skills.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mining instructor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "948", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Your introduction to the world of Gielinor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Quest guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "949", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "950", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "951", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Brace", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "954", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Converts grass to beef.", - "slayer_task": "20", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "369,371,370", - "attack_speed": "5", - "defence_animation": "5850", - "weakness": "8", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "955", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's had a fair bit to drink...", - "start_gfx": "", - "combat_style": "1", - "melee_animation": "99", - "range_animation": "99", - "combat_audio": "2707,419,418", - "attack_speed": "5", - "magic_level": "20", - "defence_animation": "101", - "slayer_exp": "0", - "magic_animation": "99", - "death_animation": "102", - "name": "Drunken Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "5", - "id": "956", - "range_level": "6", - "projectile": "33", - "attack_level": "5", - "prj_height": "45" - }, - { - "examine": "This doctor really knows her stuff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Surgeon General Tafani", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "961", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's one of Iban's pets.", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "0", - "combat_audio": "537,539,538", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "5329", - "name": "Blessed spider", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "22", - "id": "977", - "range_level": "30", - "attack_level": "22" - }, - { - "examine": "It's one of Iban's pet vermin.", - "slayer_task": "67", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "name": "Blessed giant rat", - "defence_level": "12", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "978", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "979", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "980", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "981", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "982", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "983", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "984", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wretched slave of Iban.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "985", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Precariously balanced...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boulder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "986", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Unicorn", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "369,371,370", - "strength_level": "1", - "id": "987", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Sir Jerro", - "defence_level": "1", - "safespot": null, - "lifepoints": "57", - "melee_animation": "400", - "strength_level": "1", - "id": "988", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Sir Carl", - "defence_level": "1", - "safespot": null, - "lifepoints": "57", - "melee_animation": "400", - "strength_level": "1", - "id": "989", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Sir Harry", - "defence_level": "1", - "safespot": null, - "lifepoints": "57", - "melee_animation": "400", - "strength_level": "1", - "id": "990", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "A creature empty of emotion.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Half-soulless", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "991", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Curiosity is yet to kill this one...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Witch's cat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "993", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A giant spider.", - "melee_animation": "5319", - "respawn_delay": "60", - "defence_animation": "5320", - "death_animation": "5321", - "name": "Kalrag", - "defence_level": "1", - "safespot": null, - "lifepoints": "91", - "strength_level": "1", - "id": "997", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the guardians of Iban.", - "melee_animation": "64", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "65", - "death_animation": "67", - "name": "Othainian", - "defence_level": "1", - "safespot": null, - "lifepoints": "90", - "strength_level": "1", - "id": "998", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the guardians of Iban.", - "melee_animation": "64", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "65", - "death_animation": "67", - "name": "Doomion", - "defence_level": "1", - "safespot": null, - "lifepoints": "90", - "strength_level": "1", - "id": "999", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the guardians of Iban.", - "melee_animation": "64", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "65", - "death_animation": "67", - "name": "Holthion", - "defence_level": "1", - "safespot": null, - "lifepoints": "90", - "strength_level": "1", - "id": "1000", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A user of dark magic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "0", - "name": "Dark mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1001", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dark magic user.", - "melee_animation": "422", - "range_animation": "0", - "magic_level": "32", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "836", - "name": "Disciple of Iban", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "24", - "id": "1002", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "Incey wincey.", - "melee_animation": "6249", - "respawn_delay": "60", - "defence_animation": "6250", - "death_animation": "6251", - "name": "Spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "1004", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An annoying flappy thing.", - "combat_audio": "292,294,293", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "slayer_exp": "8", - "name": "Giant bat", - "defence_level": "22", - "safespot": null, - "lifepoints": "32", - "strength_level": "22", - "id": "1005", - "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "A servant of Zamorak.", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "60", - "spell_id": "43", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Zamorak wizard", - "defence_level": "50", - "safespot": null, - "lifepoints": "73", - "strength_level": "50", - "id": "1007", - "aggressive": "true", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "A nasty, poisonous arachnid.", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "0", - "combat_audio": "537,539,538", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "30", - "defence_animation": "5328", - "weakness": "2", - "poison_amount": "6", - "magic_animation": "0", - "death_animation": "5329", - "name": "Poison spider", - "safespot": null, - "defence_level": "52", - "lifepoints": "64", - "strength_level": "65", - "id": "1009", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A green skinned croaker", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "34", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Swamp toad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1013", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Useful for hitting rocks.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Iron pickaxe", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1015", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "slayer_task": "7", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "weakness": "9", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "1017", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He rules the", - "slayer_task": "7", - "melee_animation": "5387", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5389", - "name": "Rooster", - "defence_level": "2", - "safespot": null, - "lifepoints": "2", - "strength_level": "2", - "id": "1018", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "A fire elemental.", - "melee_animation": "1029", - "range_animation": "0", - "combat_audio": "1534,1536,1535", - "magic_level": "32", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1031", - "name": "Fire elemental", - "defence_level": "32", - "safespot": null, - "movement_radius": "4", - "lifepoints": "45", - "strength_level": "24", - "id": "1019", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "An earth elemental.", - "melee_animation": "4868", - "range_animation": "0", - "combat_audio": "1531,1533,1532", - "attack_speed": "6", - "magic_level": "10", - "respawn_delay": "50", - "defence_animation": "4869", - "weakness": "7", - "magic_animation": "0", - "death_animation": "4870", - "name": "Earth elemental", - "defence_level": "35", - "safespot": null, - "movement_radius": "4", - "lifepoints": "35", - "strength_level": "32", - "id": "1020", - "aggressive": "false", - "range_level": "30", - "attack_level": "20" - }, - { - "examine": "An air elemental.", - "melee_animation": "1040", - "range_animation": "0", - "combat_audio": "1527,1529,1528", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "1041", - "name": "Air elemental", - "defence_level": "32", - "safespot": null, - "movement_radius": "4", - "lifepoints": "45", - "strength_level": "24", - "id": "1021", - "range_level": "32", - "attack_level": "24" - }, - { - "examine": "A water elemental.", - "melee_animation": "1044", - "range_animation": "0", - "combat_audio": "1546,1543,1545", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "1048", - "name": "Water elemental", - "defence_level": "32", - "safespot": null, - "movement_radius": "4", - "lifepoints": "45", - "strength_level": "24", - "id": "1022", - "range_level": "32", - "attack_level": "24" - }, - { - "examine": "It looks very hungry!", - "melee_animation": "7183", - "slayer_exp": "50", - "death_animation": "7185", - "name": "Vampire", - "defence_level": "52", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1023", - "clue_level": "1", - "range_level": "1", - "attack_level": "52" - }, - { - "examine": "An evil human cleric.", - "start_gfx": "99", - "combat_style": "2", - "combat_audio": "511,513,512", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "25", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "3", - "magic_animation": "711", - "death_animation": "836", - "name": "Monk of Zamorak", - "defence_level": "22", - "safespot": null, - "lifepoints": "20", - "strength_level": "18", - "id": "1044", - "aggressive": "true", - "range_level": "1", - "projectile": "100", - "attack_level": "18" - }, - { - "examine": "An evil human cleric.", - "start_gfx": "99", - "combat_style": "2", - "combat_audio": "511,513,512", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "25", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "3", - "magic_animation": "711", - "death_animation": "836", - "name": "Monk of Zamorak", - "defence_level": "17", - "safespot": null, - "lifepoints": "10", - "strength_level": "8", - "id": "1045", - "aggressive": "true", - "range_level": "1", - "projectile": "100", - "attack_level": "8" - }, - { - "examine": "An evil human cleric.", - "start_gfx": "99", - "combat_style": "2", - "combat_audio": "511,513,512", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "40", - "end_gfx": "101", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "3", - "magic_animation": "711", - "death_animation": "836", - "name": "Monk of Zamorak", - "defence_level": "25", - "safespot": null, - "lifepoints": "25", - "strength_level": "25", - "id": "1046", - "aggressive": "true", - "range_level": "1", - "projectile": "100", - "attack_level": "25" - }, - { - "examine": "Arrghhh... a Ghast.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "433,435,434", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghast", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1052", - "aggressive": "false", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Arrghhh... A Ghast.", - "death_gfx": "265", - "range_animation": "0", - "melee_animation": "1087", - "combat_audio": "433,435,434", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "1088", - "weakness": "9", - "magic_animation": "0", - "death_animation": "1089", - "name": "Ghast", - "defence_level": "18", - "safespot": null, - "lifepoints": "45", - "strength_level": "22", - "id": "1053", - "aggressive": "true", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Ticket trader for the Brimhaven Agility Arena.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pirate Jackie the Fruit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1055", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the audience.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Strange watcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1057", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the audience.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Strange watcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1058", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the audience.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Strange watcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1059", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Commander of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Denulth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1060", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A sergeant of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sergeant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1061", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A sergeant of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sergeant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1062", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A soldier of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1063", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A soldier of the Imperial Guard.", - "name": "Soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1064", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A soldier of the Imperial Guard.", - "name": "Soldier", - "defence_level": "44", - "safespot": null, - "lifepoints": "55", - "combat_audio": "511,513,512", - "strength_level": "44", - "id": "1065", - "magic_level": "1", - "range_level": "1", - "attack_level": "44" - }, - { - "examine": "A soldier of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1066", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A soldier of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1067", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A soldier of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1068", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A soldier of the Imperial Guard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1069", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Burthorpe Castle cook.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Eadburg", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "1072", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "A Burthorpe Castle Archer.", - "start_gfx": "19", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "magic_level": "1", - "respawn_delay": "12", - "defence_animation": "404", - "magic_animation": "426", - "death_animation": "9055", - "name": "Archer", - "defence_level": "44", - "safespot": null, - "lifepoints": "55", - "strength_level": "1", - "id": "1073", - "bonuses": "54,68,75,72,67,81,54,35,35,0,0,0,0,0,0", - "range_level": "44", - "projectile": "10", - "attack_level": "1" - }, - { - "examine": "A Burthorpe Castle Archer.", - "start_gfx": "19", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "magic_level": "1", - "respawn_delay": "12", - "defence_animation": "404", - "magic_animation": "426", - "death_animation": "9055", - "name": "Archer", - "defence_level": "44", - "safespot": null, - "lifepoints": "55", - "strength_level": "1", - "id": "1074", - "bonuses": "54,68,75,72,67,81,54,35,35,0,0,0,0,0,0", - "range_level": "44", - "projectile": "10", - "attack_level": "1" - }, - { - "examine": "A Burthorpe Castle guard.", - "melee_animation": "401", - "combat_audio": "511,513,512", - "magic_level": "1", - "defence_animation": "404", - "death_animation": "836", - "name": "Guard", - "defence_level": "33", - "safespot": null, - "lifepoints": "44", - "strength_level": "33", - "id": "1076", - "clue_level": "1", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "A Burthorpe Castle guard.", - "melee_animation": "401", - "combat_audio": "511,513,512", - "magic_level": "1", - "defence_animation": "404", - "death_animation": "836", - "name": "Guard", - "defence_level": "33", - "safespot": null, - "lifepoints": "44", - "strength_level": "33", - "id": "1077", - "clue_level": "1", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "An off-duty Burthorpe Castle guard.", - "name": "Harold", - "id": "1078" - }, - { - "examine": "Barman of the Toad and Chicken.", - "name": "Tostig", - "id": "1079" - }, - { - "examine": "Head servant for Prince Anlaf.", - "name": "Eohric", - "id": "1080" - }, - { - "examine": "A servant for Prince Anlaf.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Servant", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "3", - "id": "1081", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "Smithy for Burthorpe.", - "name": "Dunstan", - "id": "1082" - }, - { - "examine": "Shopkeeper for Burthorpe.", - "name": "Wistan", - "id": "1083" - }, - { - "examine": "A citizen of Burthorpe.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Breoca", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "3", - "id": "1084", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "A citizen of Burthorpe.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Ocga", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "3", - "id": "1085", - "range_level": "1", - "attack_level": "3" - }, - { - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1086", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A citizen of Burthorpe.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Penda", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "3", - "id": "1087", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "A citizen of Burthorpe.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Hygd", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "1088", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "A citizen of Burthorpe.", - "melee_animation": "422", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Ceolburg", - "defence_level": "3", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "1089", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "A pretty young woman with an air of mystery around her.", - "name": "Hild", - "id": "1090" - }, - { - "examine": "The knight seems to be watching something.", - "melee_animation": "7042", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "8", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "White Knight", - "defence_level": "27", - "safespot": null, - "lifepoints": "38", - "strength_level": "27", - "id": "1092", - "range_level": "1", - "attack_level": "27" - }, - { - "examine": "The biggest and baddest troll.", - "melee_animation": "6523", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Rock", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "110", - "id": "1095", - "aggressive": "true", - "bonuses": "60,60,60,0,0,35,60,35,200,200,0,100,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "Careful, he is a big.", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Stick", - "defence_level": "60", - "safespot": null, - "lifepoints": "135", - "strength_level": "110", - "id": "1096", - "aggressive": "true", - "bonuses": "50,50,50,0,0,30,30,50,200,200,0,80,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A nasty looking troll.", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Pee Hat", - "defence_level": "50", - "safespot": null, - "lifepoints": "120", - "strength_level": "100", - "id": "1097", - "aggressive": "true", - "bonuses": "40,40,40,0,0,25,25,40,200,200,0,70,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A nasty looking troll.", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Kraka", - "defence_level": "50", - "safespot": null, - "lifepoints": "120", - "strength_level": "100", - "id": "1098", - "aggressive": "true", - "bonuses": "40,40,40,0,0,25,25,40,200,400,0,70,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "Human is his speciality.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dung", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1099", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Human is his speciality.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ash", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1100", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but mean, ugly and throws rocks.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower Troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1101", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but mean, ugly and throws rocks.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower Troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1102", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but mean, ugly and throws rocks.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower Troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1103", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but mean, ugly and throws rocks.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower Troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1104", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but mean, ugly and throws rocks.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower Troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1105", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1106", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1107", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1108", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1109", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1110", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1111", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1112", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "One of the troll generals.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll general", - "defence_level": "65", - "safespot": null, - "lifepoints": "92", - "strength_level": "65", - "id": "1115", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "One of the troll generals.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll general", - "defence_level": "65", - "safespot": null, - "lifepoints": "92", - "strength_level": "65", - "id": "1116", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "One of the troll generals.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll general", - "defence_level": "65", - "safespot": null, - "lifepoints": "92", - "strength_level": "65", - "id": "1117", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1118", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1119", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1120", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1121", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1122", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1123", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "He's watching the arena.", - "slayer_task": "83", - "melee_animation": "1259", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Troll spectator", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "1124", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "An unusually large troll.", - "slayer_task": "83", - "melee_animation": "1158", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Dad", - "defence_level": "50", - "safespot": null, - "lifepoints": "120", - "strength_level": "120", - "id": "1125", - "bonuses": "40,40,40,0,0,25,25,40,200,200,0,70,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "He's guarding the cells.", - "slayer_task": "83", - "range_animation": "0", - "melee_animation": "1158", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Twig", - "defence_level": "25", - "safespot": null, - "lifepoints": "90", - "strength_level": "90", - "id": "1126", - "aggressive": "true", - "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "He's guarding the cells.", - "slayer_task": "83", - "range_animation": "0", - "melee_animation": "1158", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "287", - "name": "Berry", - "defence_level": "40", - "safespot": null, - "lifepoints": "90", - "strength_level": "90", - "id": "1127", - "aggressive": "true", - "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "He's guarding the cells.", - "slayer_task": "83", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Twig", - "defence_level": "25", - "safespot": null, - "lifepoints": "90", - "strength_level": "90", - "id": "1128", - "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "He's guarding the cells.", - "slayer_task": "83", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Berry", - "defence_level": "40", - "safespot": null, - "lifepoints": "90", - "strength_level": "90", - "id": "1129", - "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Small for a troll, but it's mean, ugly and throws rocks.", - "slayer_task": "83", - "start_gfx": "33", - "combat_style": "1", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1130", - "aggressive": "true", - "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but it's mean, ugly and throws rocks.", - "slayer_task": "83", - "start_gfx": "33", - "combat_style": "1", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1131", - "aggressive": "true", - "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but it's mean, ugly and throws rocks.", - "slayer_task": "83", - "start_gfx": "33", - "combat_style": "1", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1132", - "aggressive": "true", - "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but it's mean, ugly and throws rocks.", - "slayer_task": "83", - "start_gfx": "33", - "combat_style": "1", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1133", - "aggressive": "true", - "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "agg_radius": "6", - "examine": "Small for a troll, but it's mean, ugly and throws rocks.", - "slayer_task": "83", - "start_gfx": "33", - "combat_style": "1", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "7", - "respawn_delay": "35", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "284", - "death_animation": "287", - "name": "Thrower troll", - "defence_level": "30", - "safespot": null, - "lifepoints": "95", - "strength_level": "41", - "id": "1134", - "aggressive": "true", - "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "276", - "attack_level": "41" - }, - { - "examine": "Human is his speciality.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1135", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Human is his speciality.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1136", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Human is his speciality.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1137", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Small for a troll, but mean and ugly.", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "284", - "attack_speed": "5", - "defence_animation": "285", - "weakness": "7", - "magic_animation": "284", - "death_animation": "287", - "name": "Mountain troll", - "defence_level": "53", - "safespot": null, - "lifepoints": "90", - "strength_level": "20", - "id": "1138", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "He's fast asleep.", - "slayer_task": "83", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Mushroom", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1139", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This beast doesn't need climbing boots.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1140", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This beast doesn't need climbing boots.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1141", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's guarding the storeroom.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1142", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's guarding the storeroom.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1143", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1144", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1145", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1146", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1147", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1148", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1149", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's guarding the goutweed.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1150", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Human is his speciality.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Burntmeat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1151", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What's he mumbling about?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Weird Old Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1152", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6223", - "range_animation": "6223", - "combat_audio": "571,573,572", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "38", - "defence_animation": "6232", - "weakness": "7", - "slayer_exp": "40", - "magic_animation": "6223", - "death_animation": "6230", - "name": "Kalphite Worker", - "defence_level": "20", - "safespot": null, - "lifepoints": "40", - "strength_level": "20", - "id": "1153", - "bonuses": "0,0,0,0,0,5,5,1,10,10,0,0,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6224", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "60", - "weakness": "7", - "slayer_exp": "90", - "poison_amount": "4", - "magic_animation": "0", - "death_animation": "6228", - "lifepoints": "90", - "id": "1154", - "aggressive": "true", - "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", - "range_animation": "0", - "combat_audio": "567,569,568", - "magic_level": "1", - "defence_animation": "6227", - "name": "Kalphite Soldier", - "defence_level": "70", - "safespot": null, - "strength_level": "70", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6223", - "range_animation": "6223", - "attack_speed": "4", - "poisonous": "true", - "magic_level": "1", - "respawn_delay": "65", - "defence_animation": "6232", - "weakness": "7", - "poison_amount": "6", - "magic_animation": "6223", - "death_animation": "6230", - "name": "Kalphite Guardian", - "defence_level": "110", - "safespot": null, - "lifepoints": "170", - "strength_level": "110", - "id": "1155", - "aggressive": "true", - "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "110" - }, - { - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6223", - "range_animation": "6223", - "combat_audio": "571,573,572", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "38", - "defence_animation": "6232", - "weakness": "7", - "slayer_exp": "40", - "magic_animation": "6223", - "death_animation": "6230", - "name": "Kalphite Worker", - "defence_level": "20", - "safespot": null, - "lifepoints": "40", - "strength_level": "20", - "id": "1156", - "bonuses": "0,0,0,0,0,5,5,1,10,10,0,0,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6223", - "range_animation": "6223", - "attack_speed": "4", - "poisonous": "true", - "magic_level": "1", - "respawn_delay": "65", - "defence_animation": "6232", - "weakness": "7", - "poison_amount": "6", - "magic_animation": "6223", - "death_animation": "6230", - "name": "Kalphite Guardian", - "defence_level": "110", - "safespot": null, - "lifepoints": "170", - "strength_level": "110", - "id": "1157", - "aggressive": "true", - "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "110" - }, - { - "agg_radius": "64", - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6241", - "range_animation": "6241", - "attack_speed": "4", - "poisonous": "true", - "magic_level": "150", - "respawn_delay": "45", - "defence_animation": "6232", - "weakness": "10", - "magic_animation": "6241", - "death_animation": "6242", - "name": "Kalphite Queen", - "defence_level": "300", - "safespot": null, - "lifepoints": "255", - "strength_level": "300", - "id": "1158", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,50,10,100,100,0,0,0,0,0", - "range_level": "1000", - "attack_level": "300" - }, - { - "agg_radius": "64", - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "6235", - "range_animation": "6235", - "attack_speed": "4", - "magic_level": "150", - "respawn_delay": "0", - "defence_animation": "6234", - "weakness": "10", - "magic_animation": "6235", - "death_animation": "6233", - "name": "Kalphite Queen", - "defence_level": "300", - "safespot": null, - "lifepoints": "255", - "strength_level": "300", - "id": "1160", - "aggressive": "true", - "bonuses": "0,0,0,0,0,100,100,100,10,10,0,0,0,0,0", - "range_level": "1000", - "attack_level": "300" - }, - { - "examine": "I don't think insect repellent will work...", - "slayer_task": "53", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Kalphite Larva", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1161", - "aggressive": "false", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A huge beast, resembling in some ways a lion, but mostly a twisted nightmare.", - "melee_animation": "1199", - "range_animation": "1197", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "1200", - "weakness": "9", - "magic_animation": "1197", - "death_animation": "1201", - "name": "The Shaikahan", - "defence_level": "50", - "safespot": null, - "lifepoints": "100", - "strength_level": "50", - "id": "1172", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "He looks pretty handy with that bow.", - "slayer_task": "31", - "start_gfx": "250", - "combat_style": "1", - "melee_animation": "428", - "range_animation": "426", - "combat_audio": "425,427,426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "1", - "id": "1183", - "clue_level": "2", - "range_level": "72", - "projectile": "249", - "attack_level": "1" - }, - { - "examine": "I don't wanna be at the wrong end of that pike.", - "slayer_task": "31", - "melee_animation": "428", - "range_animation": "0", - "combat_audio": "425,427,426", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "68", - "safespot": null, - "lifepoints": "85", - "strength_level": "68", - "id": "1184", - "clue_level": "2", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "An elven city guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Elven city guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1185", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A cute bunny rabbit.", - "melee_animation": "6090", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6092", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "1192", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "6092", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "melee_animation": "6090", - "strength_level": "1", - "id": "1193", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "6091" - }, - { - "death_animation": "6092", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "melee_animation": "6090", - "strength_level": "1", - "id": "1194", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "6091" - }, - { - "examine": "It's an NPC.", - "melee_animation": "4921", - "combat_audio": "300,302,301", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "4927", - "slayer_exp": "0", - "death_animation": "4929", - "name": "Grizzly bear", - "defence_level": "35", - "safespot": null, - "lifepoints": "35", - "strength_level": "36", - "id": "1195", - "aggressive": "true", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Eek! A bear cub!", - "slayer_task": "6", - "range_animation": "0", - "combat_audio": "498,500,499", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Grizzly bear cub", - "defence_level": "21", - "safespot": null, - "lifepoints": "30", - "strength_level": "21", - "id": "1196", - "range_level": "1", - "attack_level": "21" - }, - { - "name": "Grizzly bear cub", - "defence_level": "1", - "safespot": null, - "lifepoints": "35", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "1197", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "What big teeth you have.", - "slayer_task": "92", - "melee_animation": "6559", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6558", - "name": "Dire Wolf", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "1198", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "An elf tracker.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Elf Tracker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1199", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of King Tyras's men.", - "melee_animation": "414", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Tyras guard", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "1200", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "I don't want to get on the wrong side of him.", - "start_gfx": "250", - "combat_style": "1", - "melee_animation": "426", - "combat_audio": "425,427,426", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "id": "1201", - "clue_level": "2", - "range_level": "1", - "projectile": "249", - "attack_level": "1" - }, - { - "examine": "One of King Tyras's men.", - "melee_animation": "395", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Tyras guard", - "defence_level": "110", - "safespot": null, - "lifepoints": "110", - "strength_level": "105", - "id": "1203", - "range_level": "50", - "attack_level": "95" - }, - { - "examine": "One of King Tyras's men.", - "melee_animation": "395", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Tyras guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "112", - "strength_level": "1", - "id": "1204", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Responsible for the food and equipment of the troops.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Quartermaster", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1208", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Mysterious swamp lights...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Will o' the wisp", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1211", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems strangely familiar...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Parroty Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1216", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old gardener.", - "melee_animation": "433", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Gardener", - "defence_level": "4", - "safespot": null, - "lifepoints": "5", - "strength_level": "4", - "id": "1217", - "range_level": "1", - "attack_level": "4" - }, - { - "examine": "A scary, man eating ghoul.", - "slayer_task": "37", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "442,444,443", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "404", - "weakness": "9", - "slayer_exp": "50", - "magic_animation": "422", - "death_animation": "9055", - "name": "Ghoul", - "defence_level": "30", - "safespot": null, - "lifepoints": "50", - "strength_level": "40", - "id": "1218", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Yuck! It's all slimy!", - "melee_animation": "1273", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "1272", - "name": "Leech", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "1219", - "aggressive": "true", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "It looks very hungry!", - "melee_animation": "7183", - "slayer_exp": "50", - "death_animation": "7185", - "name": "Vampire", - "defence_level": "52", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1220", - "clue_level": "1", - "range_level": "1", - "attack_level": "52" - }, - { - "slayer_exp": "40", - "name": "Vampire", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1223", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Vampire", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1225", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A marsh coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Myre Blamish Snail", - "defence_level": "22", - "safespot": null, - "lifepoints": "8", - "strength_level": "0", - "id": "1227", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "5", - "attack_level": "0" - }, - { - "examine": "A blood coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Blood Blamish Snail", - "defence_level": "45", - "safespot": null, - "lifepoints": "13", - "strength_level": "0", - "id": "1228", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "12", - "attack_level": "0" - }, - { - "examine": "A muddy coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Ochre Blamish Snail", - "defence_level": "18", - "safespot": null, - "lifepoints": "10", - "strength_level": "0", - "id": "1229", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "7", - "attack_level": "0" - }, - { - "examine": "A bruise blue coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Bruise Blamish Snail", - "defence_level": "40", - "safespot": null, - "lifepoints": "12", - "strength_level": "0", - "id": "1230", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "15", - "attack_level": "0" - }, - { - "agg_radius": "", - "examine": "A branch bark coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Bark Blamish Snail", - "defence_level": "20", - "safespot": null, - "lifepoints": "22", - "strength_level": "0", - "id": "1231", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "10", - "attack_level": "0" - }, - { - "examine": "A marsh coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Myre Blamish Snail", - "defence_level": "22", - "safespot": null, - "lifepoints": "8", - "strength_level": "0", - "id": "1232", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "5", - "attack_level": "0" - }, - { - "examine": "A blood coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Blood Blamish Snail", - "defence_level": "45", - "safespot": null, - "lifepoints": "13", - "strength_level": "0", - "id": "1233", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "12", - "attack_level": "0" - }, - { - "examine": "A muddy coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Ochre Blamish Snail", - "defence_level": "18", - "safespot": null, - "lifepoints": "10", - "strength_level": "0", - "id": "1234", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "7", - "attack_level": "0" - }, - { - "examine": "A bruise blue coloured blamish snail, these types are said to spit acid.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "8144", - "name": "Bruise Blamish Snail", - "defence_level": "40", - "safespot": null, - "lifepoints": "12", - "strength_level": "0", - "id": "1235", - "aggressive": "true", - "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", - "range_level": "15", - "attack_level": "0" - }, - { - "examine": "A Bedabin nomad fighter - a sandy swordsman.", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Bedabin Nomad Fighter", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "1239", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A shadowy sort of entity", - "slayer_task": "73", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "0", - "name": "Loar Shadow", - "defence_level": "26", - "safespot": null, - "lifepoints": "38", - "strength_level": "30", - "id": "1240", - "aggressive": "true", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "The shadowy remains of a long departed soul.", - "slayer_task": "73", - "melee_animation": "1283", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "1284", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1308", - "name": "Loar Shade", - "defence_level": "26", - "safespot": null, - "lifepoints": "38", - "strength_level": "30", - "id": "1241", - "aggressive": "true", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "A shadowy sort of entity", - "slayer_task": "73", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "0", - "name": "Phrin Shadow", - "defence_level": "42", - "safespot": null, - "lifepoints": "56", - "strength_level": "47", - "id": "1243", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "The shadowy remains of a long departed soul.", - "slayer_task": "73", - "melee_animation": "1283", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1287", - "name": "Phrin Shade", - "defence_level": "42", - "safespot": null, - "lifepoints": "56", - "strength_level": "47", - "id": "1244", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "A shadowy sort of entity", - "slayer_task": "73", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "0", - "name": "Riyl Shadow", - "defence_level": "60", - "safespot": null, - "lifepoints": "76", - "strength_level": "55", - "id": "1245", - "aggressive": "true", - "range_level": "1", - "attack_level": "88" - }, - { - "examine": "The shadowy remains of a long departed soul.", - "slayer_task": "73", - "melee_animation": "1283", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1287", - "name": "Riyl Shade", - "defence_level": "60", - "safespot": null, - "lifepoints": "76", - "strength_level": "55", - "id": "1246", - "aggressive": "true", - "range_level": "1", - "attack_level": "88" - }, - { - "examine": "A shadowy sort of entity", - "slayer_task": "73", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "0", - "name": "Asyn Shadow", - "defence_level": "70", - "safespot": null, - "lifepoints": "90", - "strength_level": "84", - "id": "1247", - "aggressive": "true", - "range_level": "1", - "attack_level": "102" - }, - { - "examine": "The shadowy remains of a long departed soul.", - "slayer_task": "73", - "melee_animation": "1283", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1287", - "name": "Asyn Shade", - "defence_level": "70", - "safespot": null, - "lifepoints": "90", - "strength_level": "84", - "id": "1248", - "aggressive": "true", - "range_level": "1", - "attack_level": "102" - }, - { - "examine": "A shadowy sort of entity", - "slayer_task": "73", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "0", - "name": "Fiyr Shadow", - "defence_level": "85", - "safespot": null, - "lifepoints": "110", - "strength_level": "100", - "id": "1249", - "aggressive": "true", - "range_level": "1", - "attack_level": "120" - }, - { - "examine": "The shadowy remains of a long departed soul.", - "slayer_task": "73", - "melee_animation": "1283", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1287", - "name": "Fiyr Shade", - "defence_level": "85", - "safespot": null, - "lifepoints": "110", - "strength_level": "100", - "id": "1250", - "aggressive": "true", - "range_level": "1", - "attack_level": "120" - }, - { - "examine": "A local villager of Mort'ton.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Afflicted", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "1257", - "range_level": "1", - "attack_level": "43" - }, - { - "examine": "A local villager of Mort'ton.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Afflicted", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "44", - "id": "1258", - "range_level": "1", - "attack_level": "44" - }, - { - "examine": "A local villager of Mort'ton.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Afflicted", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "1261", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "A local villager of Mort'ton.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Afflicted", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "46", - "id": "1262", - "aggressive": "true", - "range_level": "1", - "attack_level": "46" - }, - { - "examine": "Slightly more magical.", - "name": "Wizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1263", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A follower of Saradomin.", - "melee_animation": "376", - "range_animation": "0", - "poisonous": "true", - "magic_level": "90", - "spell_id": "41", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Saradomin wizard", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "90", - "id": "1264", - "aggressive": "true", - "range_level": "70", - "attack_level": "90" - }, - { - "examine": "No one likes crabs...", - "melee_animation": "1312", - "range_animation": "1312", - "combat_audio": "717,723,722", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "1313", - "weakness": "7", - "magic_animation": "1312", - "death_animation": "1314", - "name": "Rock Crab", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1265", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rocky outcrop.", - "melee_animation": "1312", - "range_animation": "1312", - "attack_speed": "5", - "defence_animation": "1313", - "weakness": "7", - "magic_animation": "1312", - "death_animation": "1314", - "name": "Rocks", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1266", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "No one likes crabs...", - "melee_animation": "1312", - "range_animation": "1312", - "combat_audio": "717,723,722", - "attack_speed": "4", - "respawn_delay": "50", - "defence_animation": "1313", - "magic_animation": "1312", - "death_animation": "1314", - "name": "Rock Crab", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1267", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rocky outcrop.", - "melee_animation": "1312", - "range_animation": "1312", - "attack_speed": "5", - "defence_animation": "1313", - "magic_animation": "1312", - "death_animation": "1314", - "name": "Rocks", - "defence_level": "4", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1268", - "aggressive": "true", - "range_level": "1", - "attack_level": "4" - }, - { - "examine": "A Fremennik bard.", - "melee_animation": "1312", - "range_animation": "1312", - "attack_speed": "5", - "defence_animation": "1313", - "magic_animation": "1312", - "death_animation": "1314", - "name": "Olaf the Bard", - "defence_level": "8", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1269", - "aggressive": "true", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "Distinctly troll-shaped.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lalli", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1270", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Freshly shorn.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Golden sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1271", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Lovely thick wool.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Golden sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1272", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A powerful spirit that lives in this lake.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fossegrimen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1273", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like he's had a few drinks already.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ospak", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1274", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Doesn't look like the musical type.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Styrmir", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1275", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Waiting for the show.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Torbrund", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1276", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He sits impatiently with his friends.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fridgeir", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1277", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's fat, he's round, he bounces on the ground. That's how he got the job.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Longhall Bouncer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1278", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fearful spirit of the drowned.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "The Draugen", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "1279", - "aggressive": "true", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A Fremennik hunter.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sigli the Huntsman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1281", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Fremennik merchant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sigmund The Merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1282", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Fremennik navigator.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Swensen the Navigator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1283", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Every innkeeper's best friend!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Manni the Reveller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1286", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Supposedly fixes things around Gielinor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Council workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1287", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Fremennik riddler.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Peer the Seer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1288", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Fremennik hero.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Thorvald the Warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1289", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Your challenge awaits! ", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Koschei the deathless", - "defence_level": "13", - "safespot": null, - "lifepoints": "14", - "strength_level": "13", - "id": "1290", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "He lives again!", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Koschei the deathless", - "defence_level": "13", - "safespot": null, - "lifepoints": "14", - "strength_level": "13", - "id": "1291", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "He keeps on living!", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Koschei the deathless", - "defence_level": "13", - "safespot": null, - "lifepoints": "14", - "strength_level": "13", - "id": "1292", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "He just keeps on going.", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Koschei the deathless", - "defence_level": "13", - "safespot": null, - "lifepoints": "14", - "strength_level": "13", - "id": "1293", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "The Fremennik tribe's chieftain.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brundt the Chieftain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1294", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Stands around and looks at stuff all day.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1296", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1297", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What a rubbish job he has.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Town Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1298", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Longhall barkeep", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A bartender.", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1300", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Pretty shabbily dressed for a clothes shop owner.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Yrsa", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1301", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "There's something fishy about this guy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fisherman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1302", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sells and makes weapons and armour.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Skulgrimen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1303", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's strong to the finish", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sailor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1304", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Agnar", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1305", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Freidir", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1306", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "395", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Borrokar", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1307", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Lanzig", - "defence_level": "1", - "safespot": null, - "lifepoints": "51", - "strength_level": "1", - "id": "1308", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pontak", - "defence_level": "1", - "safespot": null, - "lifepoints": "51", - "strength_level": "1", - "id": "1309", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sassilik", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1313", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Rellekka's many citizens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Inga", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1314", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Fish-tastic!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish monger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1315", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wonder what he does with all that fur?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fur trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1316", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Keeps the stalls secure.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Market Guard", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "1317", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A hardened Fremennik warrior.", - "melee_animation": "401", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Warrior", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "1318", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A cunning animal.", - "melee_animation": "6562", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6570", - "name": "Fox", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "1319", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "Hoppity", - "melee_animation": "1245", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "1246", - "name": "Bunny", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "1320", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "1246", - "name": "Bunny", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "melee_animation": "1245", - "strength_level": "1", - "id": "1321", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "1244" - }, - { - "examine": "Cute. But deadly.", - "slayer_task": "6", - "range_animation": "0", - "combat_audio": "498,500,499", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Bear Cub", - "defence_level": "8", - "safespot": null, - "lifepoints": "11", - "strength_level": "8", - "id": "1326", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "Cute. But deadly.", - "name": "Bear Cub", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "1327", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Horned horsey.", - "melee_animation": "6376", - "range_animation": "6376", - "combat_audio": "369,371,370", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "90", - "defence_animation": "6375", - "weakness": "7", - "magic_animation": "6376", - "death_animation": "6377", - "name": "Unicorn Foal", - "defence_level": "10", - "safespot": null, - "lifepoints": "15", - "strength_level": "6", - "id": "1328", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "Cute but evil.", - "melee_animation": "6376", - "range_animation": "0", - "combat_audio": "369,371,370", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6377", - "name": "Black unicorn Foal", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "18", - "id": "1329", - "aggressive": "false", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "Fearsome predator found only in the Fremennik Province", - "slayer_task": "92", - "melee_animation": "6559", - "range_animation": "0", - "combat_audio": "481,491,490", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "69", - "magic_animation": "0", - "death_animation": "6558", - "name": "Wolf", - "defence_level": "35", - "safespot": null, - "lifepoints": "69", - "strength_level": "35", - "id": "1330", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "A horror from the ocean depths...", - "combat_style": "1", - "melee_animation": "1340", - "range_animation": "1340", - "attack_speed": "5", - "defence_animation": "1341", - "magic_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "70", - "safespot": null, - "lifepoints": "70", - "strength_level": "80", - "id": "1338", - "clue_level": "1", - "range_level": "85", - "projectile": "288", - "attack_level": "80" - }, - { - "examine": "A horror from the ocean depths...", - "combat_style": "1", - "melee_animation": "1343", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1339", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "projectile": "288", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "combat_style": "1", - "melee_animation": "1343", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1340", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "projectile": "288", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "1341", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "1342", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "1343", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1344", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1345", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1346", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths...", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1347", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths.", - "slayer_task": "24", - "melee_animation": "1341", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "1342", - "name": "Dagannoth mother", - "defence_level": "60", - "safespot": null, - "lifepoints": "128", - "strength_level": "60", - "id": "1351", - "aggressive": "true", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "A horror from the ocean depths.", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1352", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths.", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1353", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths.", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1354", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths.", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1355", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A horror from the ocean depths.", - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1356", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Pretty barmaid.", - "name": "Sam", - "id": "1357" - }, - { - "examine": "Pretty barmaid.", - "name": "Rachael", - "id": "1358" - }, - { - "examine": "He seems happy to see you.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1360", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Skraeling", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "401", - "strength_level": "1", - "id": "1367", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Skraeling", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "395", - "strength_level": "1", - "id": "1368", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "Hmm", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishmonger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1369", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "At least he eats his greens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Greengrocer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1370", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's guarding the throne room.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1374", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's cutting the wheat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1377", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "No-one would mistake her for a duchess.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Flower Girl", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1378", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Alrik", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "422", - "strength_level": "1", - "id": "1381", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "He's strong to the finish, because he eats cabbage.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sailor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1385", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Rannveig", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "422", - "strength_level": "1", - "id": "1386", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Valgerd", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "422", - "strength_level": "1", - "id": "1388", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Skraeling", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "395", - "strength_level": "1", - "id": "1389", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Broddi", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "422", - "strength_level": "1", - "id": "1390", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Skraeling", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "395", - "strength_level": "1", - "id": "1391", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Ragnvald", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "810", - "strength_level": "1", - "id": "1392", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "Hmm", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishmonger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1393", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "At least he eats his greens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Greengrocer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1394", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's a lumberjack", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lumberjack Leif", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1395", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's just mining his own business.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Miner Magnus", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1396", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "There's something fishy about him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fisherman Frodi", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1397", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She's looking a bit weedy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gardener Gunnhild", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1398", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "1401", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "1402", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "5389", - "name": "Rooster", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "melee_animation": "5387", - "strength_level": "1", - "id": "1403", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "5388" - }, - { - "death_animation": "6092", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "melee_animation": "6090", - "strength_level": "1", - "id": "1404", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "6091" - }, - { - "examine": "There to help me make my bids.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lumdo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1419", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An official looking Gnome with small beady eyes.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "G.L.O. Caranock", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1427", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1383", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Duke", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "1442", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1383", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Oipuis", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "1443", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1383", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Uyoro", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "1444", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1383", - "respawn_delay": "60", - "defence_animation": "1387", - "death_animation": "1384", - "name": "Ouhai", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "1445", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1383", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Uodai", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "1446", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1383", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Padulah", - "defence_level": "1", - "safespot": null, - "lifepoints": "133", - "strength_level": "1", - "id": "1447", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rather sleepy looking guard", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sleeping Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1451", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An adorable little monkey child.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monkey Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1452", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks like the Monkey's Uncle.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "The Monkey's Uncle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1453", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks like the Monkey's Aunt.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "The Monkey's Aunt", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1454", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A scimitar wielding ninja monkey.", - "slayer_task": "61", - "melee_animation": "1392", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "1384", - "name": "Monkey Guard", - "defence_level": "66", - "safespot": null, - "lifepoints": "94", - "strength_level": "66", - "id": "1455", - "range_level": "1", - "attack_level": "66" - }, - { - "examine": "A bow wielding ninja monkey.", - "slayer_task": "61", - "combat_style": "1", - "melee_animation": "0", - "range_animation": "1394", - "combat_audio": "629,631,630", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "0", - "name": "Monkey Archer", - "defence_level": "58", - "safespot": null, - "lifepoints": "82", - "strength_level": "43", - "id": "1456", - "aggressive": "true", - "range_level": "58", - "attack_level": "43" - }, - { - "combat_style": "1", - "melee_animation": "1394", - "combat_audio": "629,631,630", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Monkey Archer", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1457", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "1394", - "combat_audio": "629,631,630", - "respawn_delay": "60", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Monkey Archer", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1458", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A huge brutish gorilla armoured with dangerous looking vambraces.", - "slayer_task": "61", - "melee_animation": "1402", - "range_animation": "1402", - "combat_audio": "629,631,630", - "attack_speed": "6", - "defence_animation": "1403", - "weakness": "8", - "magic_animation": "1402", - "death_animation": "1404", - "name": "Monkey Guard", - "defence_level": "90", - "safespot": null, - "lifepoints": "130", - "strength_level": "130", - "id": "1459", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A huge brutish gorilla armoured with dangerous looking vambraces.", - "slayer_task": "61", - "melee_animation": "1402", - "range_animation": "0", - "combat_audio": "629,631,630", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "1404", - "name": "Monkey Guard", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "63", - "id": "1460", - "aggressive": "true", - "range_level": "1", - "attack_level": "63" - }, - { - "examine": "A huge brutish gorilla stands here", - "slayer_task": "61", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Elder Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1461", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1463", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1464", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A large and lumbering undead monkey.", - "slayer_task": "61", - "melee_animation": "1383", - "range_animation": "0", - "combat_audio": "629,631,630", - "attack_speed": "4", - "magic_level": "60", - "respawn_delay": "50", - "defence_animation": "1393", - "weakness": "6", - "magic_animation": "0", - "death_animation": "1384", - "name": "Monkey Zombie", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "60", - "id": "1465", - "aggressive": "true", - "bonuses": "35,35,35,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "150" - }, - { - "examine": "A large and lumbering undead monkey stands here, blocking the way.", - "melee_animation": "1392", - "combat_audio": "629,631,630", - "attack_speed": "4", - "magic_level": "90", - "respawn_delay": "13", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Monkey Zombie", - "defence_level": "90", - "safespot": null, - "lifepoints": "90", - "strength_level": "110", - "id": "1466", - "aggressive": "true", - "bonuses": "35,35,35,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "150" - }, - { - "examine": "A recently deceased monkey. Its flesh seems to be worse for the wear.", - "melee_animation": "1392", - "combat_audio": "629,631,630", - "attack_speed": "4", - "magic_level": "60", - "respawn_delay": "50", - "defence_animation": "1393", - "death_animation": "1384", - "name": "Monkey Zombie", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "60", - "id": "1467", - "aggressive": "true", - "bonuses": "15,15,15,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "He looks like the type of guy who would mind monkeys.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monkey minder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1469", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Greater Jungle demon. A magical aura emanates from its hide.", - "range_animation": "0", - "combat_audio": "400,404,403", - "attack_speed": "2", - "magic_level": "50", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Jungle demon", - "defence_level": "50", - "safespot": null, - "lifepoints": "428", - "strength_level": "50", - "id": "1472", - "aggressive": "true", - "range_level": "50", - "attack_level": "50" - }, - { - "melee_animation": "6249", - "respawn_delay": "60", - "defence_animation": "6250", - "death_animation": "6251", - "name": "Spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "1473", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a brightly coloured bird of the jungle.", - "slayer_task": "7", - "melee_animation": "6775", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "6779", - "name": "Bird", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "1475", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "It's a brightly coloured bird of the jungle. It flies very quickly.", - "slayer_task": "7", - "melee_animation": "6775", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "6777", - "name": "Bird", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "1476", - "range_level": "1", - "attack_level": "5" - }, - { - "slayer_exp": "17", - "name": "Scorpion", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3611,3612,3610", - "strength_level": "1", - "id": "1477", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very dangerous looking spider", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "0", - "combat_audio": "537,539,538", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "5329", - "name": "Jungle spider", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "47", - "id": "1478", - "aggressive": "true", - "range_level": "63", - "attack_level": "47" - }, - { - "name": "Snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3609,3608,3610", - "strength_level": "1", - "id": "1479", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Small ninja monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1480", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Medium ninja monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1481", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Bearded gorilla", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "1483", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ancient monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1484", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Small zombie monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1485", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Large zombie monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1486", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "1487", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A huge nail beast. Its nails appear very sharp.", - "melee_animation": "5989", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5990", - "name": "Nail beast", - "defence_level": "20", - "safespot": null, - "lifepoints": "550", - "strength_level": "150", - "id": "1521", - "range_level": "1", - "attack_level": "150" - }, - { - "examine": "He is one", - "melee_animation": "5970", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5972", - "name": "Undead Lumberjack", - "defence_level": "10", - "safespot": null, - "lifepoints": "100", - "strength_level": "73", - "id": "1524", - "range_level": "1", - "attack_level": "73" - }, - { - "examine": "His robes prominently display the star of Saradomin.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zealot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1528", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Imp", - "defence_level": "1", - "safespot": null, - "movement_radius": "25", - "lifepoints": "8", - "strength_level": "1", - "id": "1531", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Handy for hindering the enemy team's movement.", - "combat_style": "1", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "9658", - "name": "Barricade", - "defence_level": "1", - "poison_immune": "true", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1532", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Handy for hindering the enemy team's movement.", - "combat_style": "1", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "9658", - "name": "Barricade", - "defence_level": "1", - "poison_immune": "true", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1533", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Handy for hindering the enemy team's movement.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "9658", - "name": "Barricade", - "defence_level": "1", - "poison_immune": "true", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1534", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Handy for hindering the enemy team's movement.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "9658", - "name": "Barricade", - "defence_level": "1", - "poison_immune": "true", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1535", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "185", - "respawn_delay": "60", - "defence_animation": "186", - "death_animation": "188", - "name": "Possessed pickaxe", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "1536", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A strange disturbance in the air.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Haze", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1537", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Well", - "slayer_task": "75", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Corpse", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1538", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I don't think the pickaxe is for hitting rocks.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeletal miner", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "1539", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5540", - "respawn_delay": "60", - "defence_animation": "5541", - "death_animation": "5542", - "name": "Treus Dayth", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1540", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "25", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1541", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5540", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5541", - "slayer_exp": "25", - "death_animation": "5542", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "1549", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A large boisterous bird, a delicacy for ogres.", - "slayer_task": "7", - "melee_animation": "6761", - "range_animation": "0", - "combat_audio": "1449,1451,1450", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "6762", - "name": "Chompy bird", - "defence_level": "3", - "safespot": null, - "poison_immune": "true", - "lifepoints": "10", - "strength_level": "5", - "id": "1550", - "aggressive": "false", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "5" - }, - { - "name": "Mischievous ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1551", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ug", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1553", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Arrg", - "defence_level": "1", - "safespot": null, - "lifepoints": "150", - "strength_level": "1", - "attack_speed": "5", - "id": "1556", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Ug", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "1557", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not man's best friend.", - "slayer_task": "92", - "melee_animation": "6559", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6558", - "name": "Ice wolf", - "defence_level": "51", - "safespot": null, - "lifepoints": "72", - "strength_level": "51", - "id": "1558", - "aggressive": "true", - "range_level": "1", - "attack_level": "51" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1560", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1561", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1562", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1563", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1564", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1565", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice Troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1566", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A tall and imposing man who's more than familiar with boating.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cyreg Paddlehorn", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1567", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "1582", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "1583", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "1584", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "1585", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "1586", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "His beard seems to have a life of its own.", - "slayer_task": "62", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "449,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4665", - "weakness": "1", - "slayer_exp": "60", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "30", - "safespot": null, - "lifepoints": "60", - "strength_level": "30", - "id": "1587", - "aggressive": "true", - "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "His beard seems to have a life of its own.", - "slayer_task": "62", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "449,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4665", - "weakness": "1", - "slayer_exp": "60", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "30", - "safespot": null, - "lifepoints": "60", - "strength_level": "30", - "id": "1588", - "aggressive": "true", - "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Young but still dangerous.", - "slayer_task": "68", - "melee_animation": "25", - "range_animation": "25", - "combat_audio": "405,407,406", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "32", - "defence_animation": "26", - "weakness": "3", - "magic_animation": "25", - "death_animation": "28", - "name": "Baby red dragon", - "defence_level": "42", - "safespot": null, - "lifepoints": "50", - "strength_level": "40", - "id": "1589", - "aggressive": "true", - "bonuses": "50,40,64,60,30,45,40,40,20,40,40,20,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Its scales seem to be made of bronze.", - "slayer_task": "13", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "40", - "defence_animation": "89", - "weakness": "7", - "slayer_exp": "125", - "magic_animation": "80", - "death_animation": "92", - "name": "Bronze dragon", - "defence_level": "112", - "safespot": null, - "lifepoints": "122", - "strength_level": "112", - "id": "1590", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "112" - }, - { - "examine": "Its scales seem to be made of iron.", - "slayer_task": "50", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "45", - "defence_animation": "89", - "weakness": "7", - "slayer_exp": "173", - "magic_animation": "80", - "death_animation": "92", - "name": "Iron dragon", - "defence_level": "165", - "safespot": null, - "lifepoints": "165", - "strength_level": "165", - "id": "1591", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "165" - }, - { - "examine": "Its scales seem to be made of steel.", - "slayer_task": "80", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "45", - "defence_animation": "89", - "weakness": "7", - "slayer_exp": "221", - "magic_animation": "80", - "death_animation": "92", - "name": "Steel dragon", - "defence_level": "215", - "safespot": null, - "lifepoints": "210", - "strength_level": "215", - "id": "1592", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "215" - }, - { - "examine": "An unsuitable pet.", - "slayer_task": "27", - "melee_animation": "6562", - "range_animation": "6562", - "magic_level": "20", - "respawn_delay": "20", - "defence_animation": "6563", - "weakness": "7", - "magic_animation": "6562", - "death_animation": "6564", - "name": "Wild dog", - "defence_level": "25", - "safespot": null, - "lifepoints": "62", - "strength_level": "25", - "id": "1593", - "aggressive": "true", - "bonuses": "10,15,5,10,30,5,30,30,30,10,30,5,40,5,5", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "Looks like it's got Rabies!", - "melee_animation": "6562", - "range_animation": "6562", - "magic_level": "20", - "respawn_delay": "20", - "defence_animation": "6563", - "magic_animation": "6562", - "death_animation": "6564", - "name": "Wild dog", - "defence_level": "25", - "safespot": null, - "lifepoints": "62", - "strength_level": "25", - "id": "1594", - "aggressive": "true", - "bonuses": "10,15,5,10,30,5,30,30,30,10,30,5,40,5,5", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "She looks dangerous!", - "name": "Chaeldar", - "id": "1598" - }, - { - "examine": "A spiky crawling critter. ", - "slayer_task": "16", - "melee_animation": "266", - "range_animation": "266", - "combat_audio": "341,343,342", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "25", - "defence_animation": "267", - "weakness": "1", - "slayer_exp": "22", - "magic_animation": "266", - "death_animation": "265", - "name": "Cave crawler", - "defence_level": "30", - "safespot": null, - "lifepoints": "23", - "strength_level": "30", - "id": "1600", - "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", - "range_level": "38", - "attack_level": "28" - }, - { - "examine": "A spiky crawling critter. ", - "melee_animation": "266", - "range_animation": "266", - "combat_audio": "341,343,342", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "25", - "defence_animation": "267", - "slayer_exp": "22", - "magic_animation": "266", - "death_animation": "265", - "name": "Cave crawler", - "defence_level": "30", - "safespot": null, - "lifepoints": "23", - "strength_level": "30", - "id": "1601", - "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A spiky crawling critter. ", - "melee_animation": "266", - "range_animation": "266", - "combat_audio": "341,343,342", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "25", - "defence_animation": "267", - "slayer_exp": "22", - "magic_animation": "266", - "death_animation": "265", - "name": "Cave crawler", - "defence_level": "30", - "safespot": null, - "lifepoints": "23", - "strength_level": "30", - "id": "1602", - "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A spiky crawling critter. ", - "melee_animation": "266", - "range_animation": "266", - "combat_audio": "341,343,342", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "25", - "defence_animation": "267", - "slayer_exp": "22", - "magic_animation": "266", - "death_animation": "265", - "name": "Cave crawler", - "defence_level": "30", - "safespot": null, - "lifepoints": "23", - "strength_level": "30", - "id": "1603", - "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A very smelly ghost.", - "slayer_task": "0", - "start_gfx": "334", - "combat_style": "2", - "melee_animation": "9466", - "attack_speed": "4", - "weakness": "5", - "slayer_exp": "90", - "magic_animation": "9466", - "death_animation": "9467", - "lifepoints": "90", - "id": "1604", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", - "range_animation": "1507", - "combat_audio": "272,275,274", - "magic_level": "105", - "end_gfx": "336", - "defence_animation": "9468", - "name": "Aberrant spectre", - "defence_level": "90", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "335", - "attack_level": "1" - }, - { - "examine": "A very smelly ghost.", - "slayer_task": "0", - "start_gfx": "334", - "combat_style": "2", - "melee_animation": "9466", - "attack_speed": "4", - "weakness": "5", - "slayer_exp": "90", - "magic_animation": "9466", - "death_animation": "9467", - "lifepoints": "90", - "id": "1605", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", - "range_animation": "1507", - "combat_audio": "272,275,274", - "magic_level": "105", - "end_gfx": "336", - "defence_animation": "9468", - "name": "Aberrant spectre", - "defence_level": "90", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "335", - "attack_level": "1" - }, - { - "examine": "A very smelly ghost.", - "slayer_task": "0", - "start_gfx": "334", - "combat_style": "2", - "melee_animation": "9466", - "attack_speed": "4", - "weakness": "5", - "slayer_exp": "90", - "magic_animation": "9466", - "death_animation": "9467", - "lifepoints": "90", - "id": "1606", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", - "range_animation": "1507", - "combat_audio": "272,275,274", - "magic_level": "105", - "end_gfx": "336", - "defence_animation": "9468", - "name": "Aberrant spectre", - "defence_level": "90", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "335", - "attack_level": "1" - }, - { - "examine": "A very smelly ghost.", - "slayer_task": "0", - "start_gfx": "334", - "combat_style": "2", - "melee_animation": "9466", - "attack_speed": "4", - "weakness": "5", - "slayer_exp": "90", - "magic_animation": "9466", - "death_animation": "9467", - "lifepoints": "90", - "id": "1607", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", - "range_animation": "1507", - "combat_audio": "272,275,274", - "magic_level": "105", - "end_gfx": "336", - "defence_animation": "9468", - "name": "Aberrant spectre", - "defence_level": "90", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "335", - "attack_level": "1" - }, - { - "examine": "Large, heavy, with sharp things attached to its head.", - "melee_animation": "9439", - "range_animation": "9439", - "combat_audio": "588,590,589", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9441", - "slayer_exp": "97", - "magic_animation": "9439", - "death_animation": "9440", - "name": "Kurask", - "defence_level": "105", - "safespot": null, - "lifepoints": "97", - "strength_level": "105", - "id": "1608", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "67" - }, - { - "examine": "Large, heavy, with sharp things attached to its head.", - "melee_animation": "9439", - "range_animation": "9439", - "combat_audio": "588,590,589", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9441", - "slayer_exp": "97", - "magic_animation": "9439", - "death_animation": "9440", - "name": "Kurask", - "defence_level": "105", - "safespot": null, - "lifepoints": "97", - "strength_level": "105", - "id": "1609", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "67" - }, - { - "examine": "Flies like a rock.", - "melee_animation": "9454", - "range_animation": "1516", - "combat_audio": "428,430,429", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "9455", - "slayer_exp": "105", - "magic_animation": "1516", - "death_animation": "1518", - "name": "Gargoyle", - "defence_level": "107", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "1610", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "Flies like a rock.", - "slayer_task": "84", - "melee_animation": "1516", - "range_animation": "1516", - "attack_speed": "5", - "defence_animation": "0", - "weakness": "0", - "slayer_exp": "105", - "magic_animation": "1516", - "death_animation": "1518", - "name": "Swarming turoth", - "defence_level": "42", - "safespot": null, - "lifepoints": "105", - "strength_level": "104", - "id": "1611", - "clue_level": "2", - "range_level": "49", - "attack_level": "45" - }, - { - "examine": "A tortured screaming soul.", - "melee_animation": "9449", - "range_animation": "1523", - "combat_audio": "284,286,285", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9451", - "slayer_exp": "22", - "magic_animation": "1523", - "death_animation": "9450", - "name": "Banshee", - "defence_level": "22", - "safespot": null, - "lifepoints": "22", - "strength_level": "15", - "id": "1612", - "aggressive": "true", - "clue_level": "0", - "bonuses": "0,0,0,0,0,5,5,5,0,5,0,0,0,0,0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "An evil death demon.", - "melee_animation": "9487", - "range_animation": "1528", - "combat_audio": "645,647,646", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "9489", - "magic_animation": "1528", - "death_animation": "9488", - "name": "Nechryael", - "defence_level": "105", - "safespot": null, - "lifepoints": "105", - "strength_level": "97", - "id": "1613", - "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "97" - }, - { - "examine": "An evil death spawn.", - "melee_animation": "1540", - "range_animation": "1540", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "1540", - "death_animation": "9460", - "name": "Death spawn", - "defence_level": "30", - "poison_immune": "true", - "safespot": null, - "lifepoints": "60", - "strength_level": "7", - "id": "1614", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", - "range_level": "1", - "attack_level": "67" - }, - { - "examine": "A denizen of the Abyss!", - "slayer_task": "1", - "melee_animation": "1537", - "range_animation": "1537", - "combat_audio": "276,278,277", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "1", - "slayer_exp": "150", - "magic_animation": "1537", - "death_animation": "1538", - "name": "Abyssal demon", - "defence_level": "135", - "safespot": null, - "lifepoints": "150", - "strength_level": "67", - "id": "1615", - "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "97" - }, - { - "examine": "The eyes of evil.", - "melee_animation": "260", - "range_animation": "260", - "combat_audio": "288,290,289", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "261", - "slayer_exp": "75", - "magic_animation": "260", - "death_animation": "264", - "name": "Basilisk", - "defence_level": "75", - "safespot": null, - "lifepoints": "75", - "strength_level": "45", - "id": "1616", - "aggressive": "false", - "bonuses": "0,0,0,0,0,20,20,0,20,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "The eyes of evil.", - "melee_animation": "260", - "range_animation": "260", - "combat_audio": "288,290,289", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "261", - "slayer_exp": "75", - "magic_animation": "260", - "death_animation": "264", - "name": "Basilisk", - "defence_level": "75", - "safespot": null, - "lifepoints": "75", - "strength_level": "45", - "id": "1617", - "aggressive": "false", - "bonuses": "0,0,0,0,0,20,20,0,20,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "The tongue of evil.", - "melee_animation": "9130", - "range_animation": "1552", - "combat_audio": "312,314,313", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "9132", - "slayer_exp": "120", - "magic_animation": "1552", - "death_animation": "9131", - "name": "Bloodveld", - "defence_level": "30", - "safespot": null, - "lifepoints": "120", - "strength_level": "45", - "id": "1618", - "aggressive": "true", - "clue_level": "2", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "The tongue of evil.", - "melee_animation": "9130", - "range_animation": "1552", - "combat_audio": "312,314,313", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "9132", - "slayer_exp": "120", - "magic_animation": "1552", - "death_animation": "9131", - "name": "Bloodveld", - "defence_level": "30", - "safespot": null, - "lifepoints": "120", - "strength_level": "45", - "id": "1619", - "aggressive": "true", - "clue_level": "2", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "The winged reptile.", - "slayer_task": "19", - "melee_animation": "7762", - "range_animation": "7762", - "combat_audio": "363,365,364", - "attack_speed": "5", - "defence_animation": "7761", - "weakness": "2", - "slayer_exp": "37", - "magic_animation": "7762", - "death_animation": "7763", - "name": "Cockatrice", - "defence_level": "35", - "safespot": null, - "lifepoints": "37", - "strength_level": "32", - "id": "1620", - "bonuses": "30,30,30,30,30,35,0,0,0,0,0,0,0,0,0", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "examine": "The winged reptile.", - "melee_animation": "7762", - "range_animation": "7762", - "combat_audio": "363,365,364", - "attack_speed": "5", - "defence_animation": "7761", - "slayer_exp": "37", - "magic_animation": "7762", - "death_animation": "7763", - "name": "Cockatrice", - "defence_level": "35", - "safespot": null, - "lifepoints": "37", - "strength_level": "32", - "id": "1621", - "bonuses": "30,30,30,30,30,35,0,0,0,0,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "He's one big leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "85", - "safespot": null, - "lifepoints": "78", - "strength_level": "85", - "id": "1622", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "He's one big leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "88", - "safespot": null, - "lifepoints": "81", - "strength_level": "88", - "id": "1623", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "58" - }, - { - "examine": "The vacuumed face of evil.", - "slayer_task": "28", - "melee_animation": "1557", - "range_animation": "1557", - "combat_audio": "414,416,415", - "attack_speed": "4", - "defence_animation": "1555", - "weakness": "2", - "slayer_exp": "105", - "magic_animation": "1557", - "death_animation": "1558", - "name": "Dust devil", - "defence_level": "40", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "1624", - "range_level": "1", - "attack_level": "105" - }, - { - "examine": "The cave-dwelling cousin of the dust devils.", - "slayer_task": "28", - "melee_animation": "1557", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "1558", - "name": "Smokedevil", - "defence_level": "61", - "safespot": null, - "lifepoints": "87", - "strength_level": "105", - "id": "1625", - "range_level": "61", - "attack_level": "105" - }, - { - "examine": "She's one leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "86", - "safespot": null, - "lifepoints": "79", - "strength_level": "86", - "id": "1626", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "56" - }, - { - "examine": "It's one leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "84", - "safespot": null, - "lifepoints": "77", - "strength_level": "84", - "id": "1627", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "It's one small leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "83", - "safespot": null, - "lifepoints": "76", - "strength_level": "83", - "id": "1628", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "He's one big leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "87", - "safespot": null, - "lifepoints": "80", - "strength_level": "87", - "id": "1629", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "57" - }, - { - "examine": "He's one big leg short!", - "melee_animation": "9471", - "range_animation": "9471", - "combat_audio": "873,875,874", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9473", - "magic_animation": "9471", - "death_animation": "9472", - "name": "Turoth", - "defence_level": "87", - "safespot": null, - "lifepoints": "80", - "strength_level": "87", - "id": "1630", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "57" - }, - { - "spawn_animation": "8081", - "examine": "A small fire demon.", - "slayer_task": "66", - "melee_animation": "8080", - "combat_audio": "696,698,697", - "attack_speed": "5", - "magic_level": "10", - "respawn_delay": "60", - "defence_animation": "8084", - "weakness": "4", - "slayer_exp": "45", - "death_animation": "8078", - "name": "Pyrefiend", - "defence_level": "19", - "safespot": null, - "lifepoints": "45", - "strength_level": "29", - "id": "1633", - "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", - "clue_level": "1", - "range_level": "19", - "attack_level": "22" - }, - { - "spawn_animation": "8081", - "examine": "A small fire demon.", - "slayer_task": "66", - "melee_animation": "8080", - "combat_audio": "696,698,697", - "attack_speed": "5", - "magic_level": "10", - "respawn_delay": "60", - "defence_animation": "8084", - "weakness": "4", - "slayer_exp": "45", - "death_animation": "8078", - "name": "Pyrefiend", - "defence_level": "19", - "safespot": null, - "lifepoints": "45", - "strength_level": "29", - "id": "1634", - "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", - "clue_level": "1", - "range_level": "19", - "attack_level": "22" - }, - { - "spawn_animation": "8081", - "examine": "A small fire demon.", - "slayer_task": "66", - "melee_animation": "8080", - "combat_audio": "696,698,697", - "attack_speed": "5", - "magic_level": "10", - "respawn_delay": "60", - "defence_animation": "8084", - "weakness": "4", - "slayer_exp": "45", - "death_animation": "8078", - "name": "Pyrefiend", - "defence_level": "19", - "safespot": null, - "lifepoints": "45", - "strength_level": "29", - "id": "1635", - "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", - "clue_level": "1", - "range_level": "19", - "attack_level": "22" - }, - { - "spawn_animation": "8081", - "examine": "A small fire demon.", - "slayer_task": "66", - "melee_animation": "8080", - "combat_audio": "696,698,697", - "attack_speed": "5", - "magic_level": "10", - "respawn_delay": "60", - "defence_animation": "8084", - "weakness": "4", - "slayer_exp": "45", - "death_animation": "8078", - "name": "Pyrefiend", - "defence_level": "19", - "safespot": null, - "lifepoints": "45", - "strength_level": "29", - "id": "1636", - "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", - "clue_level": "1", - "range_level": "19", - "attack_level": "22" - }, - { - "examine": "It's a Jelly.", - "slayer_task": "51", - "melee_animation": "8569", - "range_animation": "8569", - "combat_audio": "547,550,549", - "attack_speed": "5", - "magic_level": "40", - "defence_animation": "8571", - "weakness": "2", - "slayer_exp": "75", - "magic_animation": "8569", - "death_animation": "8570", - "name": "Jelly", - "defence_level": "40", - "safespot": null, - "lifepoints": "75", - "strength_level": "45", - "id": "1637", - "clue_level": "2", - "range_level": "40", - "attack_level": "40" - }, - { - "examine": "Doesn't look so tough...", - "slayer_task": "51", - "melee_animation": "8569", - "range_animation": "0", - "combat_audio": "547,550,549", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "75", - "magic_animation": "0", - "death_animation": "8570", - "name": "Jelly", - "defence_level": "49", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1638", - "clue_level": "2", - "range_level": "49", - "attack_level": "1" - }, - { - "examine": "Wibbly.", - "slayer_task": "51", - "melee_animation": "8569", - "range_animation": "0", - "combat_audio": "547,550,549", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "75", - "magic_animation": "0", - "death_animation": "8570", - "name": "Jelly", - "defence_level": "49", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1639", - "clue_level": "2", - "range_level": "49", - "attack_level": "1" - }, - { - "examine": "There's always room for jelly.", - "slayer_task": "51", - "melee_animation": "8569", - "range_animation": "0", - "combat_audio": "547,550,549", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "75", - "magic_animation": "0", - "death_animation": "8570", - "name": "Jelly", - "defence_level": "49", - "safespot": null, - "lifepoints": "140", - "strength_level": "1", - "id": "1640", - "clue_level": "2", - "range_level": "49", - "attack_level": "1" - }, - { - "melee_animation": "8569", - "combat_audio": "547,550,549", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "8571", - "slayer_exp": "75", - "name": "Jelly", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "1641", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "8569", - "combat_audio": "547,550,549", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "8571", - "slayer_exp": "75", - "name": "Jelly", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "1642", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil magic user.", - "slayer_task": "49", - "start_gfx": "99", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "magic_level": "75", - "respawn_delay": "12", - "end_gfx": "101", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Infernal Mage", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "1643", - "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", - "range_level": "1", - "projectile": "100", - "attack_level": "1" - }, - { - "slayer_task": "49", - "start_gfx": "99", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "magic_level": "75", - "respawn_delay": "12", - "end_gfx": "101", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Infernal Mage", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "1644", - "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", - "range_level": "1", - "projectile": "100", - "attack_level": "1" - }, - { - "examine": "An evil magic user.", - "slayer_task": "49", - "start_gfx": "99", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "magic_level": "75", - "respawn_delay": "12", - "end_gfx": "101", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Infernal Mage", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "1645", - "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", - "range_level": "1", - "projectile": "100", - "attack_level": "1" - }, - { - "examine": "An evil magic user.", - "slayer_task": "49", - "start_gfx": "99", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "magic_level": "75", - "respawn_delay": "12", - "end_gfx": "101", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Infernal Mage", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "1646", - "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", - "range_level": "1", - "projectile": "100", - "attack_level": "1" - }, - { - "examine": "An evil magic user.", - "slayer_task": "49", - "start_gfx": "99", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "magic_level": "75", - "respawn_delay": "12", - "end_gfx": "101", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "811", - "death_animation": "836", - "name": "Infernal Mage", - "defence_level": "60", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "1647", - "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", - "range_level": "1", - "projectile": "100", - "attack_level": "1" - }, - { - "examine": "Now THAT'S handy.", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "9125", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "9127", - "weakness": "9", - "slayer_exp": "19", - "magic_animation": "9125", - "death_animation": "9126", - "name": "Crawling Hand", - "defence_level": "5", - "safespot": null, - "lifepoints": "16", - "strength_level": "5", - "id": "1648", - "bonuses": "5,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "Gimmie five. Actually", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "19", - "magic_animation": "0", - "death_animation": "9126", - "name": "Crawling Hand", - "defence_level": "8", - "safespot": null, - "lifepoints": "5", - "strength_level": "8", - "id": "1649", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "Gimmie five. Actually", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "9126", - "name": "Crawling Hand", - "defence_level": "8", - "safespot": null, - "lifepoints": "5", - "strength_level": "8", - "id": "1650", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "Gimmie five. Actually", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "19", - "magic_animation": "0", - "death_animation": "9126", - "name": "Crawling Hand", - "defence_level": "8", - "safespot": null, - "lifepoints": "5", - "strength_level": "8", - "id": "1651", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "Gimmie five. Actually", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "19", - "magic_animation": "0", - "death_animation": "9126", - "name": "Crawling Hand", - "defence_level": "8", - "safespot": null, - "lifepoints": "5", - "strength_level": "8", - "id": "1652", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "Now THAT's handy.", - "slayer_task": "21", - "melee_animation": "9444", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "9445", - "name": "Crawling Hand", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "1653", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "I'm glad it's just the hand I can see...", - "slayer_task": "21", - "melee_animation": "9444", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "9445", - "name": "Crawling Hand", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "1654", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A big severed hand.", - "slayer_task": "21", - "melee_animation": "9444", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "9445", - "name": "Crawling Hand", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "1655", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "Give the guy a big hand.....", - "slayer_task": "21", - "melee_animation": "9444", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "9445", - "name": "Crawling Hand", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "1656", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A big severed hand.", - "slayer_task": "21", - "melee_animation": "9444", - "range_animation": "0", - "combat_audio": "377,379,378", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "9445", - "name": "Crawling Hand", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "1657", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A Supplier of Magical robes.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Robe Store owner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1658", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's in charge of the Skullball Course.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Skullball Boss", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1660", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's in charge of the Agility Course.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Agility Boss", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1661", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A skullball guide.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Skullball Trainer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1662", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A werewolf agility trainer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Agility Trainer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1663", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like he's guarding a trapdoor...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Werewolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "1665", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Gardener Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1675", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His beard seems to have a life of its own.", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "449,451,450", - "magic_level": "1", - "defence_animation": "4665", - "weakness": "3", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "60", - "safespot": null, - "lifepoints": "120", - "strength_level": "60", - "id": "1681", - "aggressive": "true", - "bonuses": "66,62,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A ghost disciple.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost disciple", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1686", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader from across the eastern sea.", - "start_gfx": "0", - "start_height": "0", - "melee_animation": "386", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Ak-Haranu", - "defence_level": "1", - "movement_radius": "2", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1688", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's an undead cow.", - "slayer_task": "20", - "melee_animation": "5849", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "5", - "defence_animation": "5850", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5851", - "name": "Undead cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "3", - "id": "1691", - "aggressive": "false", - "bonuses": "-15,-15,-15,0,0,-21,-21,-21,-21,-21,0,-15,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yup, definitely a chicken... an undead chicken.", - "slayer_task": "7", - "melee_animation": "5387", - "range_animation": "0", - "combat_audio": "355,357,356", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5389", - "name": "Undead chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "1692", - "aggressive": "false", - "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,0,-42,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An extremely vicious lobster.", - "slayer_task": "71", - "melee_animation": "6265", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6267", - "name": "Giant lobster", - "defence_level": "30", - "safespot": null, - "lifepoints": "128", - "strength_level": "30", - "id": "1693", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "An old", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Old crone", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1695", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A creaky old man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Old man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1696", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A spooky ghost villager.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost villager", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1697", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This poor soul cannot understand why it has not passed to the next world.", - "slayer_task": "36", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "slayer_exp": "51", - "magic_animation": "0", - "death_animation": "836", - "name": "Tortured soul", - "defence_level": "38", - "safespot": null, - "lifepoints": "51", - "strength_level": "62", - "id": "1698", - "aggressive": "true", - "range_level": "1", - "attack_level": "52" - }, - { - "examine": "Beware the ghostly shopkeeper's wares!", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1699", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Doesn't look like the bar's open anymore.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost innkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1700", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ghost farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1701", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A ghost banker.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1702", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A ghost sailor.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost sailor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1703", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A ghostship captain.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost captain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1704", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ghost captain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1705", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This ghost guards the gates of Port Phasmatys.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1706", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ghost (?)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1707", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ghost (?)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "1708", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard for the humans against monster group.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "H.A.M. Guard", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "1710", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "A guard for the humans against monster group.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "H.A.M. Guard", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "1711", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "A guard for the humans against monster group.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "H.A.M. Guard", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "1712", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "A deacon in the Humans Against Monsters group. A rather enthusiastic chap.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "H.A.M. Deacon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1713", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the 'Humans Against Monsters' group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "H.A.M. Member", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1714", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the 'Humans Against Monsters' group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "H.A.M. Member", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1715", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the 'Humans Against Monsters' group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "H.A.M. Member", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1716", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the 'Humans Against Monsters' group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "H.A.M. Member", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1717", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A young man with a dark and mysterious past.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jimmy the Chisel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1718", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Manages the mill.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Oak", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1739", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Sigmund's elite guards.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Yew", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1740", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Sigmund's elite guards.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Evergreen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1741", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Evergreen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1742", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Evergreen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1743", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tree", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1744", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dead tree", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1745", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Achey Tree", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1746", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tree", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1747", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of Sigmund's H.A.M. splinter group.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tree", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1748", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A giant raptor.", - "melee_animation": "1010", - "combat_audio": "832,834,833", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "1012", - "magic_animation": "0", - "death_animation": "1013", - "name": "Terrorbird", - "defence_level": "19", - "safespot": null, - "lifepoints": "34", - "strength_level": "23", - "id": "1751", - "aggressive": "false", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "These gnomes know how to get around!", - "slayer_task": "7", - "melee_animation": "6790", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6791", - "name": "Mounted terrorbird gnome", - "defence_level": "33", - "safespot": null, - "lifepoints": "37", - "strength_level": "33", - "id": "1752", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "A farmer's enemy.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Crow", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1754", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He grows the crops in this area.", - "melee_animation": "7181", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Farmer", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "1757", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "He grows the crops in this area.", - "melee_animation": "7181", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Farmer", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "1758", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "Farming.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1759", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He grows the crops in this area.", - "melee_animation": "7181", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7185", - "name": "Farmer", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "1760", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "Farming the wheat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1761", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1763", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Young, but still beefy.", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "366,368,367", - "attack_speed": "5", - "defence_animation": "5850", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow calf", - "defence_level": "1", - "safespot": null, - "lifepoints": "6", - "strength_level": "1", - "id": "1766", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Where beef comes from.", - "slayer_task": "20", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "369,371,370", - "attack_speed": "5", - "defence_animation": "5850", - "weakness": "8", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "1767", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Young, but still beefy.", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "366,368,367", - "attack_speed": "5", - "defence_animation": "5850", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow calf", - "defence_level": "1", - "safespot": null, - "lifepoints": "6", - "strength_level": "1", - "id": "1768", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1769", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1770", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1771", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1772", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1773", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1774", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1775", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "weakness": "7", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "1776", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks quite independent in an aggressive and business like way.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "498,500,499", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hammerspike Stoutbeard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1794", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A short stout menacing fellow.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf gang member", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "1795", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "A short stout menacing fellow.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf gang member", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "1796", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "A short stout menacing fellow.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf gang member", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "1797", - "range_level": "1", - "attack_level": "25" - }, - { - "melee_animation": "1750", - "respawn_delay": "60", - "defence_animation": "1751", - "death_animation": "1752", - "name": "Slagilith", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "1802", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A pile of boulders.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rock pile", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1803", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to be guarding a pile of rocks. Interesting job.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1805", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to be guarding a single rock. Interesting job.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1806", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Chieftain of the mountain camp.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hamal the Chieftain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1807", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is that a bear... or a man?", - "melee_animation": "1760", - "range_animation": "0", - "magic_level": "23", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "1759", - "name": "The Kendal", - "defence_level": "23", - "safespot": null, - "lifepoints": "85", - "strength_level": "23", - "id": "1812", - "aggressive": "true", - "range_level": "23", - "attack_level": "23" - }, - { - "melee_animation": "1760", - "respawn_delay": "60", - "defence_animation": "1758", - "death_animation": "1759", - "name": "The Kendal", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "1813", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the inhabitants of the camp.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Camp dweller", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "1814", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "One of the inhabitants of the camp.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Camp dweller", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "1815", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "One of the inhabitants of the camp.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Camp dweller", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "1816", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "One of the inhabitants of the camp.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Camp dweller", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "1817", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "One of the inhabitants of the camp.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Camp dweller", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "1818", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "Looks a little underfed.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1819", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This goat belongs to the mountain camp people.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1820", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin with big bulging eyes.", - "slayer_task": "38", - "melee_animation": "6001", - "range_animation": "0", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "1822", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin with big bulging eyes.", - "slayer_task": "38", - "melee_animation": "6001", - "range_animation": "0", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "1823", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin with big bulging eyes.", - "slayer_task": "38", - "melee_animation": "6001", - "range_animation": "0", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "1824", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin with big bulging eyes.", - "slayer_task": "38", - "melee_animation": "6001", - "range_animation": "0", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "1825", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Flies like a rock.", - "melee_animation": "9454", - "range_animation": "1516", - "combat_audio": "428,430,429", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "9455", - "slayer_exp": "105", - "magic_animation": "1516", - "death_animation": "1518", - "name": "Gargoyle", - "defence_level": "107", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "1827", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "It didn't get that big eating flies!", - "melee_animation": "1793", - "range_animation": "1793", - "attack_speed": "6", - "defence_animation": "1794", - "weakness": "1", - "magic_animation": "1793", - "death_animation": "1795", - "name": "Giant frog", - "defence_level": "60", - "safespot": null, - "lifepoints": "100", - "strength_level": "45", - "id": "1828", - "bonuses": "10,10,10,10,10,10,1,10,10,10,10,37,0,0,0", - "range_level": "32", - "attack_level": "45" - }, - { - "examine": "It didn't get that big eating flies.", - "melee_animation": "1793", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "1795", - "name": "Big frog", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "1", - "id": "1829", - "range_level": "26", - "attack_level": "1" - }, - { - "examine": "A foul-smelling blob of protoplasm.", - "slayer_task": "18", - "melee_animation": "1789", - "attack_speed": "4", - "poisonous": "true", - "respawn_delay": "15", - "weakness": "1", - "slayer_exp": "25", - "poison_amount": "3", - "magic_animation": "0", - "death_animation": "1792", - "lifepoints": "25", - "id": "1831", - "aggressive": "false", - "range_animation": "0", - "combat_audio": "784,786,785", - "magic_level": "13", - "defence_animation": "0", - "name": "Cave slime", - "defence_level": "35", - "safespot": null, - "strength_level": "13", - "clue_level": "0", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A nasty crawling critter.", - "slayer_task": "15", - "melee_animation": "6079", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "5", - "magic_animation": "0", - "death_animation": "6082", - "name": "Cave bug", - "defence_level": "6", - "safespot": null, - "lifepoints": "5", - "strength_level": "5", - "id": "1832", - "bonuses": "0,0,0,0,0,10,10,5,5,10,0,0,0,0,0", - "range_level": "1", - "attack_level": "6" - }, - { - "examine": "A little", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave bug larva", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1833", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Has an odd smell about him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Candle seller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1834", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A short angry guy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Engineer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1840", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The little guy is having trouble standing up right.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Khorvak, a dwarven engineer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1842", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's probably you who will be paying the ferryman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Ferryman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1843", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's probably you who will be paying the ferryman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Ferryman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1844", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to be in charge of the ship on the river.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Boatman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1846", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It is the avatar of the Arzinian Being of Bordanzan", - "melee_animation": "1840", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "1841", - "name": "Arzinian Avatar of Strength", - "defence_level": "40", - "safespot": null, - "lifepoints": "114", - "strength_level": "40", - "id": "1850", - "range_level": "1", - "attack_level": "40" - }, - { - "melee_animation": "1840", - "respawn_delay": "60", - "defence_animation": "1842", - "death_animation": "1843", - "name": "Arzinian Avatar of Strength", - "defence_level": "1", - "safespot": null, - "lifepoints": "110", - "strength_level": "1", - "id": "1851", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1840", - "respawn_delay": "60", - "defence_animation": "1842", - "death_animation": "1843", - "name": "Arzinian Avatar of Strength", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1852", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It is the avatar of the Arzinian Being of Bordanzan", - "melee_animation": "1843", - "range_animation": "1843", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "1841", - "name": "Arzinian Avatar of Ranging", - "defence_level": "40", - "safespot": null, - "lifepoints": "114", - "strength_level": "30", - "id": "1853", - "aggressive": "true", - "range_level": "40", - "attack_level": "30" - }, - { - "melee_animation": "1840", - "respawn_delay": "60", - "defence_animation": "1842", - "death_animation": "1843", - "name": "Arzinian Avatar of Ranging", - "defence_level": "1", - "safespot": null, - "lifepoints": "110", - "strength_level": "1", - "id": "1854", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1840", - "respawn_delay": "60", - "defence_animation": "1842", - "death_animation": "1843", - "name": "Arzinian Avatar of Ranging", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1855", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It is the avatar of the Arzinian Being of Bordanzan", - "melee_animation": "1844", - "range_animation": "0", - "magic_level": "40", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "1841", - "name": "Arzinian Avatar of Magic", - "defence_level": "40", - "safespot": null, - "lifepoints": "114", - "strength_level": "30", - "id": "1856", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "melee_animation": "1840", - "respawn_delay": "60", - "defence_animation": "1842", - "death_animation": "1843", - "name": "Arzinian Avatar of Magic", - "defence_level": "1", - "safespot": null, - "lifepoints": "110", - "strength_level": "1", - "id": "1857", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1840", - "respawn_delay": "60", - "defence_animation": "1842", - "death_animation": "1843", - "name": "Arzinian Avatar of Magic", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "1858", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's the Arzinian Being", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Arzinian Being of Bordanzan", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1859", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He sells ranging equipment.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1866", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Nemarti looks ready to teach you about ranged combat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ranged Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1861", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Drunk man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Drunken Ali", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1863", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hassled looking barman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali The barman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1864", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A kebab seller.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Kebab seller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1865", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Ali the discount animal seller.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Camel Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1867", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mischievous looking child.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Street urchin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1868", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old Hag named Alice.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Hag", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1871", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A snake charmer.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Snake Charmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1872", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A foul tempered ugly lumpy yellow horse prone to spitting.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1873", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A slithering serpent.", - "melee_animation": "275", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "278", - "name": "Desert snake", - "defence_level": "6", - "safespot": null, - "lifepoints": "8", - "strength_level": "4", - "id": "1874", - "range_level": "6", - "attack_level": "4" - }, - { - "examine": "A toothless old Snake.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1875", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very tough-looking bandit.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Bandit champion", - "defence_level": "39", - "safespot": null, - "lifepoints": "55", - "strength_level": "39", - "id": "1885", - "aggressive": "true", - "range_level": "1", - "attack_level": "39" - }, - { - "examine": "Probably the weakest bandit in the world ....ever.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cowardly Bandit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1886", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Smooth operator.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "4", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Operator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1902", - "bonuses": "0,0,0,0,0,10,10,5,5,10,0,0,0,0,0", - "range_level": "1", - "attack_level": "6" - }, - { - "examine": "Menaphite thug.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "0", - "respawn_delay": "5", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Menaphite Thug", - "defence_level": "20", - "safespot": null, - "lifepoints": "60", - "strength_level": "50", - "id": "1904", - "aggressive": "false", - "bonuses": "4,4,4,0,0,9,8,10,0,0,0,9,0,0,0", - "range_level": "0", - "attack_level": "60" - }, - { - "examine": "Menaphite thug.", - "melee_animation": "395", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "0", - "respawn_delay": "5", - "defence_animation": "425", - "magic_animation": "0", - "death_animation": "836", - "name": "Menaphite Thug", - "defence_level": "20", - "safespot": null, - "lifepoints": "60", - "strength_level": "50", - "id": "1905", - "aggressive": "false", - "bonuses": "4,4,4,0,0,9,8,10,0,0,0,9,0,0,0", - "range_level": "0", - "attack_level": "60" - }, - { - "examine": "Tough looking Menaphite.", - "melee_animation": "395", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Tough Guy", - "defence_level": "39", - "safespot": null, - "lifepoints": "114", - "strength_level": "39", - "id": "1906", - "aggressive": "true", - "range_level": "1", - "attack_level": "39" - }, - { - "examine": "Definitely not a chicken.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Desert Phoenix", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1911", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A tough-looking criminal.", - "melee_animation": "412", - "range_animation": "412", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "412", - "death_animation": "9055", - "name": "Kamil", - "defence_level": "20", - "safespot": null, - "lifepoints": "50", - "strength_level": "55", - "id": "1913", - "range_level": "1", - "attack_level": "20" - }, - { - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Dessous", - "defence_level": "1", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "1914", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Dessous", - "defence_level": "1", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "1915", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I guess he sells what he steals...?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bandit shopkeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1917", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Hardened by the cutthroat world of archaeology.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Archaeologist", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1918", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very mysterious looking...", - "melee_animation": "377", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Stranger", - "defence_level": "58", - "safespot": null, - "lifepoints": "82", - "strength_level": "58", - "id": "1919", - "aggressive": "true", - "range_level": "1", - "attack_level": "58" - }, - { - "examine": "Looks like a rough-and-ready type.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bartender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1921", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A tough-looking criminal.", - "melee_animation": "412", - "range_animation": "412", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "412", - "death_animation": "9055", - "name": "Bandit", - "defence_level": "30", - "safespot": null, - "lifepoints": "65", - "strength_level": "70", - "id": "1926", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "This is an NPC.", - "melee_animation": "412", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "100", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Bandit", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "1931", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ice troll.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ice troll", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1935", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1936", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1937", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1938", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1939", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1940", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1941", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Brrrrr...he must be cold!", - "slayer_task": "83", - "melee_animation": "284", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "1942", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Not a man's best friend.", - "melee_animation": "6579", - "range_animation": "6579", - "magic_level": "30", - "respawn_delay": "28", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Ice wolf", - "defence_level": "60", - "safespot": null, - "lifepoints": "72", - "strength_level": "60", - "id": "1951", - "aggressive": "true", - "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Not a man's best friend.", - "melee_animation": "6579", - "range_animation": "6579", - "magic_level": "30", - "respawn_delay": "28", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Ice wolf", - "defence_level": "60", - "safespot": null, - "lifepoints": "72", - "strength_level": "60", - "id": "1952", - "aggressive": "true", - "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Not a man's best friend.", - "melee_animation": "6579", - "range_animation": "6579", - "magic_level": "30", - "respawn_delay": "28", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Ice wolf", - "defence_level": "60", - "safespot": null, - "lifepoints": "72", - "strength_level": "60", - "id": "1953", - "aggressive": "true", - "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Not a man's best friend.", - "melee_animation": "6579", - "range_animation": "6579", - "magic_level": "30", - "respawn_delay": "28", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Ice wolf", - "defence_level": "60", - "safespot": null, - "lifepoints": "72", - "strength_level": "60", - "id": "1954", - "aggressive": "true", - "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Not a man's best friend.", - "melee_animation": "6579", - "range_animation": "6579", - "magic_level": "30", - "respawn_delay": "28", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Ice wolf", - "defence_level": "60", - "safespot": null, - "lifepoints": "72", - "strength_level": "60", - "id": "1955", - "aggressive": "true", - "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Not a man's best friend.", - "melee_animation": "6579", - "range_animation": "6579", - "magic_level": "30", - "respawn_delay": "28", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Ice wolf", - "defence_level": "60", - "safespot": null, - "lifepoints": "72", - "strength_level": "60", - "id": "1956", - "aggressive": "true", - "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Highly flammable!", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1958", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "A tightly-wrapped monster.", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1961", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "Spooky", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "poison_immune": "true", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1962", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "A victim of poor first aid.", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "poison_immune": "true", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1963", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "But who's the daddy?", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1964", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "A tightly-wrapped monster.", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1965", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "A victim of poor first aid.", - "melee_animation": "5549", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "1967", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "I think they're some kind of beetle...", - "slayer_task": "70", - "melee_animation": "1948", - "range_animation": "0", - "poisonous": "true", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "1946", - "name": "Scarabs", - "defence_level": "62", - "safespot": null, - "lifepoints": "88", - "strength_level": "62", - "id": "1969", - "range_level": "1", - "attack_level": "62" - }, - { - "examine": "A wandering merchant.", - "name": "Rasolo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1972", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A giant skeleton.", - "slayer_task": "75", - "melee_animation": "5499", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5503", - "name": "Giant skeleton", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "1973", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Looks hungry!", - "slayer_task": "27", - "melee_animation": "6565", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6564", - "name": "Shadow Hound", - "defence_level": "48", - "safespot": null, - "lifepoints": "68", - "strength_level": "48", - "id": "1976", - "range_level": "1", - "attack_level": "48" - }, - { - "melee_animation": "799", - "respawn_delay": "60", - "defence_animation": "434", - "death_animation": "836", - "name": "Fareed", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "1977", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A malnourished worker.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1978", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A malnourished worker.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1979", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A strange-smelling merchant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Embalmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1980", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A block of a man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Carpenter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1981", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Preach my brother!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Priest", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1988", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He has a dangerous glint in his eye.", - "combat_style": "2", - "melee_animation": "429", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "836", - "name": "Possessed Priest", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "30", - "id": "1991", - "aggressive": "true", - "range_level": "40", - "attack_level": "30" - }, - { - "melee_animation": "7588", - "combat_audio": "386,388,387", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "7590", - "slayer_exp": "62", - "death_animation": "7591", - "name": "Crocodile", - "defence_level": "1", - "safespot": null, - "lifepoints": "63", - "strength_level": "1", - "id": "1993", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He has had his day.", - "slayer_task": "27", - "melee_animation": "6568", - "range_animation": "0", - "combat_audio": "544,546,545", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6567", - "name": "Jackal", - "defence_level": "15", - "safespot": null, - "lifepoints": "27", - "strength_level": "18", - "id": "1994", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "17" - }, - { - "examine": "Obnoxious", - "melee_animation": "2015", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "2013", - "name": "Locust", - "defence_level": "12", - "safespot": null, - "lifepoints": "34", - "strength_level": "12", - "id": "1995", - "aggressive": "true", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "A very smelly frog.", - "melee_animation": "1021", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "1022", - "name": "Plague frog", - "defence_level": "15", - "safespot": null, - "lifepoints": "42", - "strength_level": "15", - "id": "1997", - "aggressive": "true", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "I might give the burgers a miss in this town.", - "slayer_task": "20", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "0", - "name": "Plague cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1998", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I don't fancy eating any part of this.", - "slayer_task": "20", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "0", - "name": "Plague cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "1999", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I think they're some kind of beetle.", - "slayer_task": "70", - "melee_animation": "1948", - "range_animation": "0", - "attack_speed": "2", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "1946", - "name": "Scarab swarm", - "defence_level": "9", - "safespot": null, - "lifepoints": "900", - "strength_level": "9", - "id": "2001", - "aggressive": "true", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "This mummy looks like it means business!", - "melee_animation": "5554", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "2015", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "An irate warrior-mummy.", - "melee_animation": "5554", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "2016", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "This mummy looks like it means business!", - "melee_animation": "5554", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "2017", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "An irate mummy.", - "melee_animation": "5554", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "2018", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A wizened old warrior.", - "melee_animation": "5554", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5555", - "name": "Mummy", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "2019", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A shimmering creature of blue light.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Light creature", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2021", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Wonder how long he's been here...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Strange Old Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2024", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A vengeful spirit corrupted by dark magic.", - "start_gfx": "155", - "combat_style": "2", - "start_height": "96", - "melee_animation": "1162", - "range_animation": "1162", - "attack_speed": "5", - "magic_level": "100", - "end_gfx": "157", - "defence_animation": "420", - "weakness": "3", - "magic_animation": "1162", - "death_animation": "7197", - "name": "Ahrim the Blighted", - "defence_level": "100", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "2025", - "aggressive": "true", - "bonuses": "68,68,68,73,-19,103,85,117,73,0,0,68,0,49,0", - "range_level": "1", - "projectile": "156", - "attack_level": "1" - }, - { - "examine": "A vengeful spirit corrupted by dark magic.", - "melee_animation": "2066", - "range_animation": "2066", - "attack_speed": "7", - "magic_level": "1", - "respawn_delay": "0", - "defence_animation": "2063", - "weakness": "9", - "magic_animation": "2066", - "death_animation": "7197", - "name": "Dharok the Wretched", - "defence_level": "100", - "safespot": null, - "lifepoints": "100", - "strength_level": "100", - "id": "2026", - "aggressive": "true", - "bonuses": "105,105,105,-58,-18,252,250,244,-11,249,0,105,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A vengeful spirit corrupted by dark magic.", - "melee_animation": "2080", - "range_animation": "2080", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "0", - "defence_animation": "2079", - "weakness": "6", - "magic_animation": "2080", - "death_animation": "7197", - "name": "Guthan the Infested", - "defence_level": "100", - "safespot": null, - "lifepoints": "100", - "strength_level": "100", - "id": "2027", - "aggressive": "true", - "bonuses": "75,75,75,-50,-19,259,247,241,-11,-250,0,75,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A vengeful spirit corrupted by dark magic.", - "combat_style": "1", - "melee_animation": "2075", - "range_animation": "2075", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "16", - "defence_animation": "424", - "weakness": "0", - "magic_animation": "2075", - "death_animation": "7197", - "name": "Karil the Tainted", - "defence_level": "100", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "2028", - "aggressive": "true", - "bonuses": "0,0,0,-26,134,79,71,90,106,100,0,0,0,0,61", - "range_level": "100", - "projectile": "27", - "attack_level": "1" - }, - { - "examine": "A vengeful spirit corrupted by dark magic.", - "melee_animation": "2068", - "range_animation": "2068", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "0", - "defence_animation": "404", - "weakness": "7", - "magic_animation": "2068", - "death_animation": "7197", - "name": "Torag the Corrupted", - "defence_level": "100", - "safespot": null, - "lifepoints": "100", - "strength_level": "100", - "id": "2029", - "aggressive": "true", - "bonuses": "72,72,72,-33,-11,221,235,222,0,221,0,72,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A vengeful spirit corrupted by dark magic.", - "melee_animation": "2062", - "range_animation": "2062", - "combat_audio": "", - "attack_speed": "5", - "magic_level": "1", - "defence_animation": "2063", - "weakness": "8", - "magic_animation": "2062", - "death_animation": "7197", - "name": "Verac the Defiled", - "defence_level": "100", - "safespot": null, - "lifepoints": "100", - "strength_level": "100", - "id": "2030", - "aggressive": "true", - "bonuses": "72,72,72,-42,-14,227,230,221,0,225,72,78,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "I think I should keep my distance...", - "melee_animation": "2070", - "range_animation": "2070", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "26", - "defence_animation": "2072", - "weakness": "6", - "magic_animation": "2070", - "death_animation": "2073", - "name": "Bloodworm", - "defence_level": "35", - "safespot": null, - "lifepoints": "45", - "strength_level": "20", - "id": "2031", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "A nasty little rodent.", - "slayer_task": "67", - "melee_animation": "240", - "range_animation": "240", - "combat_audio": "703,705,704", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "241", - "weakness": "9", - "magic_animation": "240", - "death_animation": "243", - "name": "Crypt rat", - "defence_level": "20", - "safespot": null, - "lifepoints": "35", - "strength_level": "20", - "id": "2032", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A nasty overgrown rodent.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4934", - "weakness": "9", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Giant crypt rat", - "defence_level": "65", - "safespot": null, - "lifepoints": "70", - "strength_level": "50", - "id": "2033", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "Incey wincey.", - "slayer_task": "76", - "melee_animation": "6249", - "range_animation": "6249", - "combat_audio": "537,539,538", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "6250", - "weakness": "7", - "magic_animation": "6249", - "death_animation": "6251", - "name": "Crypt spider", - "defence_level": "45", - "safespot": null, - "lifepoints": "45", - "strength_level": "47", - "id": "2034", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,10,17,20,0,0,0,0,0", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Not very incey wincey.", - "slayer_task": "76", - "melee_animation": "5327", - "range_animation": "5327", - "combat_audio": "537,539,538", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "5328", - "weakness": "7", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Giant crypt spider", - "defence_level": "65", - "safespot": null, - "lifepoints": "80", - "strength_level": "67", - "id": "2035", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "combat_audio": "", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2044", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2045", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2046", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2047", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2048", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2049", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "It's falling apart!", - "slayer_task": "64", - "combat_audio": "", - "range_animation": "359", - "melee_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "weakness": "7", - "slayer_exp": "", - "magic_animation": "359", - "death_animation": "361", - "name": "Skogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2050", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2051", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2052", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2053", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2054", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A partially decomposing zombie ogre.", - "slayer_task": "64", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Zogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2055", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "It's falling apart!", - "slayer_task": "64", - "combat_audio": "", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Skogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2056", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "It's falling apart!", - "slayer_task": "64", - "combat_audio": "", - "range_animation": "359", - "melee_animation": "359", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "360", - "slayer_exp": "", - "weakness": "7", - "magic_animation": "359", - "death_animation": "361", - "name": "Skogre", - "defence_level": "35", - "safespot": null, - "lifepoints": "71", - "strength_level": "36", - "id": "2057", - "aggressive": "true", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "What could be hiding in that crack in the wall?", - "slayer_task": "87", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "30", - "magic_animation": "0", - "death_animation": "0", - "name": "Hole in the wall", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "2058", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Slash Bash", - "defence_level": "1", - "safespot": null, - "lifepoints": "103", - "strength_level": "1", - "id": "2060", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "I can see fish swimming in the water.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishing spot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2067", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This one is slacking off.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "2069", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "This one is slacking off.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "2070", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "This one is slacking off.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "2071", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "This one is slacking off.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "2072", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "He protects the miners.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "6008", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin guard", - "defence_level": "15", - "safespot": null, - "lifepoints": "21", - "strength_level": "15", - "id": "2073", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "He protects the miners.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "6008", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Cave goblin guard", - "defence_level": "15", - "safespot": null, - "lifepoints": "21", - "strength_level": "15", - "id": "2074", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "He's working hard!", - "melee_animation": "6007", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2075", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's working hard!", - "melee_animation": "6007", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2076", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's working hard!", - "melee_animation": "6007", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2077", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's working hard!", - "melee_animation": "6007", - "combat_audio": "469,472,471", - "defence_animation": "6008", - "death_animation": "6003", - "name": "Cave goblin miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2078", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Advisor to the Duke of Lumbridge.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sigmund", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2082", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5327", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5328", - "death_animation": "5329", - "name": "Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2091", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the Purple Pewter mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Purple Pewter Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2092", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the Yellow Fortune mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Yellow Fortune Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2093", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the Blue Opal mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Blue Opal Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2094", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the Green Gemstone mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Green Gemstone Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2095", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the White Chisel mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "White Chisel Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2096", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the Silver Cog mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Silver Cog Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2097", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head secretary of the Brown Engine mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brown Engine Secretary", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2098", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Purple Pewter Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2100", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Blue Opal Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2101", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Yellow Fortune Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2102", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Green Gemstone Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2103", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "White Chisel Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2104", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Silver Cog Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2105", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the leaders of the business Consortium", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brown Engine Director", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2106", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Purple Pewter mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2109", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Purple Pewter mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2110", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Blue Opal mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2111", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Blue Opal mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2112", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Yellow Fortune mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2113", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Yellow Fortune mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2114", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Green Gemstone mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2115", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Green Gemstone mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2116", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the White Chisel mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2117", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the White Chisel mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2118", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Silver Cog mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2119", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Silver Cog mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2120", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Brown Engine mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2121", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A trader for the Brown Engine mining company.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2122", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He is regulating the flow of goods on the trade floor and maintaining order.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trade Referee", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2127", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2130", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2131", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2132", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2133", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "An elite member of the Black Guard.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard Berserker", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "38", - "id": "2134", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "An elite member of the Black Guard.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard Berserker", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "38", - "id": "2135", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "An elite member of the Black Guard.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard Berserker", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "38", - "id": "2136", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "A gnome traveller, visiting Keldagrim.", - "name": "Gnome traveller", - "defence_level": "1", - "force_talk": "", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2138", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome traveller, visiting Keldagrim.", - "name": "Gnome traveller", - "defence_level": "1", - "force_talk": "", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2139", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very protective of his master... and his property.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dromund's cat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2140", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Makes sculptures.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Blasidar the sculptor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2141", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Proprietor of Gunslik's Assorted Items.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gunslik", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2154", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old mining dwarf, now he sells pickaxes and generally acts grumpy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tati", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2160", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rather personable banker lady.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2163", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rather serious old fella.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2164", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He takes care of the library and its many books.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Librarian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2165", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A customer looking for books.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Customer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2167", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like a human traveler visiting the library.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Customer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2168", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He tends to the plants in the palace garden.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rind the gardener", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2170", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after the factory.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Factory Manager", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2171", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Works hard at whatever it is he does.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Factory Worker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2172", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Works hard at whatever it is he does.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Factory Worker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2173", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Works hard at whatever it is he does.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Factory Worker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2174", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Works hard at whatever it is he does.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Factory Worker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2175", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "These Dwarf ladies are so attractive!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barmaid", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2178", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He makes sure the carts don't run anyone over.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2180", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He makes sure the carts don't run anyone over.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2181", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He makes sure the carts don't run anyone over.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2182", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He makes sure the carts don't run anyone over.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2183", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He makes sure the carts don't run anyone over.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2184", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Remember: don't drink and ride in mine carts.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2185", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Keeps the line clear of traffic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cart conductor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2186", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A loud, drunk and generally obnoxious dwarf.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rowdy dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2187", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A sad old dwarf living in a sad old home.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Runvastr", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2190", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to always be busy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sune", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2191", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This dwarf doesn't seem to be very well off.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bentamir", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2192", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf minding his own business.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ulifed", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2193", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A short, merry guy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Karl", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2195", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His kebabs certainly smell delicious.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Kjut", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2198", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to be very well off.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Audmann", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2201", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's had a fair bit to drink...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Drunken Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2202", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's had a fair bit to drink...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Drunken Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2203", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "You cannot see his ship, but presumably he has one.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Boatman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2205", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "You cannot see his ship, but presumably he has one.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Boatman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2206", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He carries a heavy load.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarven Miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2207", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An elite member of the Black Guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Black Guard Berserker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2232", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A master at farming.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2234", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A master at farming.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2235", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He guards the Draynor Market stalls from thieves.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "2547,1979,512", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Market Guard", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "2236", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A local farmer. He may be able to provide some useful information.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gee", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2237", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "There to help me make my bids.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pig", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2240", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "There to help me make my bids.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Piglet", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2241", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Porcine.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Piglet", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2242", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He provides new players with useful information.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lumbridge Guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2244", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's one of General Khazard's warriors.", - "melee_animation": "401", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Khazard trooper", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "2245", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's one of General Khazard's warriors.", - "melee_animation": "429", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Khazard trooper", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "2246", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "It's a tree gnome trooper.", - "combat_style": "1", - "melee_animation": "190", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "193", - "death_animation": "196", - "name": "Gnome troop", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "2247", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tree gnome trooper.", - "combat_style": "1", - "melee_animation": "190", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "193", - "death_animation": "196", - "name": "Gnome troop", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "2248", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Paladin", - "defence_level": "1", - "safespot": null, - "lifepoints": "66", - "strength_level": "1", - "id": "2256", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An initiate of Zamorak.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dark mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2262", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A blood-drinking denizen of the abyss.", - "melee_animation": "2181", - "range_animation": "0", - "combat_audio": "232,231,230", - "attack_speed": "3", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "0", - "magic_animation": "0", - "death_animation": "2183", - "name": "Abyssal leech", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "2263", - "aggressive": "true", - "range_level": "52", - "attack_level": "1" - }, - { - "examine": "It seems to have eyes in the back of its head...", - "melee_animation": "2186", - "range_animation": "2186", - "attack_speed": "6", - "magic_level": "57", - "defence_animation": "2188", - "weakness": "3", - "slayer_exp": "0", - "magic_animation": "2186", - "death_animation": "2189", - "name": "Abyssal guardian", - "defence_level": "65", - "safespot": null, - "lifepoints": "50", - "strength_level": "96", - "id": "2264", - "aggressive": "true", - "range_level": "135", - "attack_level": "65" - }, - { - "examine": "Apparently walks the abyss.", - "melee_animation": "2192", - "range_animation": "2192", - "combat_audio": "233,235,234", - "attack_speed": "5", - "defence_animation": "2193", - "weakness": "8", - "slayer_exp": "0", - "magic_animation": "2192", - "death_animation": "2194", - "name": "Abyssal walker", - "defence_level": "55", - "safespot": null, - "lifepoints": "95", - "strength_level": "116", - "id": "2265", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Sparkles the Tinsel Snake", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rogue Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2267", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A snowman armed with a holly bow.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rogue Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2269", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A snowman armed with an ice sword.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Emerald Benedict", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2271", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A snowman armed with a winter staff.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spin Blades", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2272", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2274", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2275", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2276", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2277", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2278", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2279", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2280", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2281", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A warrior blessed by Saradomin.", - "melee_animation": "400", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Sir Leye", - "defence_level": "1", - "safespot": null, - "lifepoints": "21", - "strength_level": "1", - "id": "2285", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An observer for the Temple Knights.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Miss Cheevers", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2288", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An observer for the Temple Knights.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ms. Hynn Terprett", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2289", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A carpet merchant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rug Merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2291", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A carpet merchant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rug Merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2292", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A man who deals in rugs.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rug Merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2293", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A man who deals in rugs.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rug Merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2294", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Perhaps our oldest relatives.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2301", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Young, but still beefy.", - "slayer_task": "20", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "366,368,367", - "attack_speed": "5", - "defence_animation": "5850", - "weakness": "8", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow calf", - "defence_level": "2", - "safespot": null, - "lifepoints": "6", - "strength_level": "2", - "id": "2310", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "Farmer/sheep liaison officer. Go on - give the dog a bone!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sheepdog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2311", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He rules the", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rooster", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2312", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "2313", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "2314", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yep. Definitely a chicken.", - "melee_animation": "5387", - "range_animation": "5387", - "combat_audio": "355,357,356", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "5388", - "magic_animation": "5387", - "death_animation": "5389", - "name": "Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "2315", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Swine.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pig", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2316", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Porker.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pig", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2317", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Hog.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Piglet", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2318", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Porcine.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Piglet", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2319", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He has a certain bovine aroma.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Piglet", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2320", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An expert on the brewing of ales and cider.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Blandebir", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2321", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Only the Grim Reaper would have a pet like this.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Muncher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2329", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Perhaps this farmer might look after your crops for you.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Vasquen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2333", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Taria", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2336", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fayeth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2342", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2354", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She can look after my money.", - "combat_style": "2", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "476", - "strength_level": "1", - "id": "2355", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I don't wanna be at the wrong end of that pike.", - "slayer_task": "31", - "melee_animation": "428", - "range_animation": "0", - "combat_audio": "425,427,426", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "2359", - "clue_level": "2", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "I don't wanna be at the wrong end of that pike.", - "slayer_task": "31", - "melee_animation": "428", - "range_animation": "0", - "combat_audio": "425,427,426", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "2360", - "clue_level": "2", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "He looks pretty handy with that bow.", - "slayer_task": "31", - "start_gfx": "250", - "combat_style": "1", - "melee_animation": "428", - "range_animation": "426", - "combat_audio": "425,427,426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "1", - "id": "2361", - "clue_level": "2", - "range_level": "64", - "projectile": "249", - "attack_level": "1" - }, - { - "examine": "He looks pretty handy with that bow.", - "slayer_task": "31", - "start_gfx": "250", - "combat_style": "1", - "melee_animation": "428", - "range_animation": "426", - "combat_audio": "425,427,426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "836", - "name": "Elf warrior", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "1", - "id": "2362", - "clue_level": "2", - "range_level": "64", - "projectile": "249", - "attack_level": "1" - }, - { - "examine": "A Mourner showing his true identity.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Head mourner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2372", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mourner, or plague healer.", - "slayer_task": "31", - "melee_animation": "428", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mourner", - "defence_level": "61", - "safespot": null, - "lifepoints": "87", - "strength_level": "61", - "id": "2373", - "aggressive": "true", - "range_level": "1", - "attack_level": "61" - }, - { - "name": "Mysterious ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2397", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Mysterious ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2398", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Mysterious ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2399", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Mysterious ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2400", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Mysterious ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2401", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Mysterious ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2402", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_task": "29", - "examine": "A dwarf gone bad.", - "respawn_delay": "150", - "slayer_exp": "61", - "weakness": "6", - "name": "Chaos dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2423", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "9230", - "name": "Jarvald", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "melee_animation": "9232", - "strength_level": "10", - "id": "2436", - "range_level": "1", - "attack_level": "10", - "defence_animation": "9231" - }, - { - "examine": "Looks like a wanna be Fremennik.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Askeladden", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2439", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This support is propping the door closed.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Door-support", - "defence_level": "1", - "safespot": null, - "lifepoints": "0", - "strength_level": "1", - "id": "2443", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "No one likes crabs... especially really big ones!", - "melee_animation": "2368", - "range_animation": "0", - "combat_audio": "717,723,722", - "attack_speed": "4", - "respawn_delay": "50", - "defence_animation": "1313", - "weakness": "9", - "magic_animation": "0", - "death_animation": "1314", - "name": "Giant Rock Crab", - "defence_level": "200", - "safespot": null, - "lifepoints": "180", - "strength_level": "80", - "id": "2452", - "aggressive": "true", - "bonuses": "0,0,0,0,0,225,200,175,-10,250,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "Heavy rock!", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boulder", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "2453", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A teeny-tiny horror from the ocean depths...", - "slayer_task": "24", - "melee_animation": "1341", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "1342", - "name": "Dagannoth spawn", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "2454", - "aggressive": "true", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "A horror from the ocean depths...", - "melee_animation": "1343", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "1340", - "slayer_exp": "120", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "71", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2455", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "projectile": "294", - "attack_level": "68" - }, - { - "examine": "A horror from the ocean depths...", - "combat_style": "1", - "melee_animation": "1343", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "1340", - "slayer_exp": "0", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "50", - "safespot": null, - "lifepoints": "70", - "strength_level": "70", - "id": "2456", - "aggressive": "true", - "clue_level": "1", - "range_level": "70", - "projectile": "294", - "attack_level": "68" - }, - { - "examine": "A fearsome magical creature from the deep.", - "combat_style": "2", - "melee_animation": "2365", - "combat_audio": "1077,1079,1078", - "attack_speed": "6", - "spell_id": "48", - "magic_level": "100", - "respawn_delay": "60", - "defence_animation": "2366", - "magic_animation": "2365", - "death_animation": "2367", - "name": "Wallasalki", - "defence_level": "80", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "2457", - "aggressive": "true", - "bonuses": "0,0,0,0,0,100,150,175,250,-10,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A brightly coloured game bird.", - "melee_animation": "2372", - "range_animation": "2372", - "combat_audio": "690,692,691", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "2371", - "magic_animation": "2372", - "death_animation": "2373", - "name": "Pheasant", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "2459", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A brightly coloured game bird.", - "melee_animation": "2372", - "range_animation": "2372", - "combat_audio": "690,692,691", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "2371", - "magic_animation": "2372", - "death_animation": "2373", - "name": "Pheasant", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "2460", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A brightly coloured game bird.", - "melee_animation": "2372", - "range_animation": "2372", - "combat_audio": "690,692,691", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "2371", - "magic_animation": "2372", - "death_animation": "2373", - "name": "Pheasant", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "2461", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A brightly coloured game bird.", - "melee_animation": "2372", - "range_animation": "2372", - "combat_audio": "690,692,691", - "attack_speed": "6", - "respawn_delay": "18", - "defence_animation": "2371", - "magic_animation": "2372", - "death_animation": "2373", - "name": "Pheasant", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "2462", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fowl beast.", - "combat_style": "2", - "melee_animation": "2302", - "range_animation": "2302", - "combat_audio": "2288,357,356", - "magic_level": "5", - "respawn_delay": "25", - "defence_animation": "2300", - "magic_animation": "2302", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "20", - "safespot": null, - "lifepoints": "19", - "strength_level": "5", - "id": "2463", - "aggressive": "true", - "bonuses": "25,85,105,75,103,85,65,0,0,0,0,0,0,0,0", - "range_level": "5", - "projectile": "337", - "attack_level": "5" - }, - { - "examine": "A fowl beast.", - "combat_style": "2", - "melee_animation": "2302", - "range_animation": "2302", - "combat_audio": "2288,357,356", - "magic_level": "10", - "respawn_delay": "25", - "defence_animation": "2300", - "magic_animation": "2302", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "40", - "safespot": null, - "lifepoints": "40", - "strength_level": "10", - "id": "2464", - "aggressive": "true", - "bonuses": "35,105,125,95,128,105,85,0,0,0,0,0,0,0,0", - "range_level": "10", - "projectile": "337", - "attack_level": "10" - }, - { - "examine": "A fowl beast.", - "combat_style": "2", - "melee_animation": "2302", - "range_animation": "2302", - "combat_audio": "2288,357,356", - "magic_level": "15", - "respawn_delay": "25", - "defence_animation": "2300", - "magic_animation": "2302", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "50", - "safespot": null, - "lifepoints": "60", - "strength_level": "15", - "id": "2465", - "aggressive": "true", - "bonuses": "35,185,185,155,188,125,165,0,0,0,0,0,0,0,0", - "range_level": "15", - "projectile": "337", - "attack_level": "15" - }, - { - "examine": "A fowl beast.", - "combat_style": "2", - "melee_animation": "2302", - "range_animation": "2302", - "combat_audio": "2288,357,356", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "2300", - "magic_animation": "2302", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "60", - "safespot": null, - "lifepoints": "80", - "strength_level": "45", - "id": "2466", - "aggressive": "true", - "bonuses": "45,235,235,205,238,145,165,0,0,0,0,0,0,0,0", - "range_level": "45", - "projectile": "337", - "attack_level": "45" - }, - { - "examine": "A fowl beast.", - "combat_style": "2", - "melee_animation": "2302", - "range_animation": "2302", - "combat_audio": "2288,357,356", - "magic_level": "35", - "respawn_delay": "25", - "defence_animation": "2300", - "magic_animation": "2302", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "45", - "id": "2467", - "aggressive": "true", - "bonuses": "45,285,285,255,288,145,165,0,0,0,0,0,0,0,0", - "range_level": "45", - "projectile": "337", - "attack_level": "45" - }, - { - "examine": "A fowl beast.", - "combat_style": "2", - "melee_animation": "2302", - "range_animation": "2302", - "combat_audio": "2288,357,356", - "magic_level": "45", - "respawn_delay": "25", - "defence_animation": "2300", - "weakness": "9", - "magic_animation": "2302", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "90", - "safespot": null, - "lifepoints": "120", - "strength_level": "45", - "id": "2468", - "aggressive": "true", - "bonuses": "45,285,285,255,288,145,165,0,0,0,0,0,0,0,0", - "range_level": "45", - "projectile": "337", - "attack_level": "45" - }, - { - "examine": "A Retired Highwayman", - "combat_style": "1", - "melee_animation": "4230", - "range_animation": "4230", - "combat_audio": "2695,513,512", - "attack_speed": "5", - "magic_level": "30", - "defence_animation": "404", - "magic_animation": "4230", - "death_animation": "9055", - "name": "Rick Turpentine", - "defence_level": "8", - "safespot": null, - "lifepoints": "10", - "strength_level": "8", - "id": "2476", - "bonuses": "30,20,10,20,20,30,30,10,20,10,30,30,20,30,20", - "range_level": "20", - "projectile": "27", - "attack_level": "8", - "prj_height": "" - }, - { - "examine": "Apparently a master of quizzes!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Quiz Master", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2477", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Hey, it's Bob the cat! Or... is it?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Evil Bob", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2479", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Servant of Evil Bob.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Servant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2481", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Annoying flappy thing.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "292,294,293", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "0", - "slayer_exp": "8", - "magic_animation": "0", - "death_animation": "0", - "name": "Giant bat", - "defence_level": "22", - "safespot": null, - "lifepoints": "32", - "strength_level": "22", - "id": "2482", - "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "A slithering serpent that likes to hide in the bush.", - "melee_animation": "275", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "poison_amount": "11", - "magic_animation": "0", - "death_animation": "278", - "name": "Bush snake", - "defence_level": "61", - "safespot": null, - "lifepoints": "87", - "strength_level": "1", - "id": "2489", - "aggressive": "true", - "range_level": "61", - "attack_level": "1" - }, - { - "melee_animation": "275", - "combat_audio": "3609,3608,3610", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "276", - "poison_amount": "11", - "death_animation": "278", - "name": "Bush snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "2490", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5327", - "combat_audio": "537,539,538", - "respawn_delay": "60", - "defence_animation": "5328", - "death_animation": "5329", - "name": "Jungle spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "2491", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5327", - "combat_audio": "537,539,538", - "respawn_delay": "60", - "defence_animation": "5328", - "death_animation": "5329", - "name": "Jungle spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "2492", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A flying bloodsucker.", - "melee_animation": "2397", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "2398", - "name": "Large mosquito", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "1", - "id": "2493", - "range_level": "63", - "attack_level": "1" - }, - { - "examine": "A swarm of three highly agile mosquitoes.", - "melee_animation": "2397", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "2398", - "name": "Mosquito swarm", - "defence_level": "66", - "safespot": null, - "lifepoints": "94", - "strength_level": "1", - "id": "2494", - "range_level": "66", - "attack_level": "1" - }, - { - "examine": "A swarm of five highly agile mosquitoes.", - "melee_animation": "2397", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "2398", - "name": "Mosquito swarm", - "defence_level": "68", - "safespot": null, - "lifepoints": "97", - "strength_level": "1", - "id": "2495", - "range_level": "68", - "attack_level": "1" - }, - { - "name": "Tribesman", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "2496", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A vicious warrior.", - "melee_animation": "428", - "range_animation": "0", - "attack_speed": "4", - "poisonous": "true", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "9", - "poison_amount": "11", - "magic_animation": "0", - "death_animation": "836", - "name": "Tribesman", - "defence_level": "26", - "safespot": null, - "lifepoints": "39", - "strength_level": "27", - "id": "2497", - "aggressive": "true", - "clue_level": "1", - "bonuses": "8,8,8,0,0,4,6,6,0,0,0,5,0,0,0", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "An undead victim of some ancient murderous ritual; his skin appears deep green.", - "combat_style": "2", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Broodoo victim", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "2499", - "aggressive": "true", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "An undead victim of some ancient murderous ritual; his skin appears pale yellow.", - "combat_style": "2", - "melee_animation": "428", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Broodoo victim", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "2501", - "aggressive": "true", - "range_level": "1", - "attack_level": "43" - }, - { - "combat_style": "2", - "melee_animation": "810", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Broodoo victim", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "2503", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He used to swashbuckle his away across the seven seas.", - "combat_style": "1", - "melee_animation": "4230", - "range_animation": "4230", - "attack_speed": "5", - "magic_level": "20", - "defence_animation": "404", - "magic_animation": "4230", - "death_animation": "9055", - "name": "Cap'n Hand", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "10", - "id": "2539", - "bonuses": "10,30,20,30,10,20,15,30,10,30,15,20,20,0,0", - "range_level": "30", - "attack_level": "30" - }, - { - "examine": "A crazy, evil druid.", - "start_gfx": "105", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "4", - "magic_level": "10", - "end_gfx": "107", - "respawn_delay": "25", - "defence_animation": "404", - "weakness": "3", - "magic_animation": "422", - "death_animation": "9055", - "name": "Chaos druid", - "defence_level": "12", - "safespot": null, - "lifepoints": "20", - "strength_level": "8", - "id": "2547", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "106", - "attack_level": "8" - }, - { - "examine": "A colourful character.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the dyer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2549", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after the blast furnace.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Blast Furnace Foreman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2553", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He smells of rock dust.", - "name": "Ordan", - "id": "2564" - }, - { - "examine": "He buys stuff.", - "name": "Jorzik", - "id": "2565" - }, - { - "death_animation": "836", - "name": "Market Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "melee_animation": "400", - "strength_level": "1", - "id": "2571", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "He's guarding the bank.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bank guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2574", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Althric", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2588", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2591", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2592", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2593", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2594", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2595", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2596", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like some kind of mystic.", - "start_gfx": "1618", - "combat_style": "2", - "melee_animation": "9260", - "range_animation": "9260", - "attack_speed": "5", - "magic_level": "70", - "end_gfx": "1621", - "defence_animation": "9287", - "magic_animation": "9260", - "death_animation": "9291", - "name": "TzHaar-Mej", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "2597", - "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", - "range_level": "70", - "projectile": "1617", - "attack_level": "70" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "2598", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "2599", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "2600", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "2601", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "2602", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "2603", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "50" - }, - { - "examine": "Doesn't look very social.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9291", - "name": "TzHaar-Xil", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2604", - "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Doesn't look very social.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9291", - "name": "TzHaar-Xil", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2605", - "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Doesn't look very social.", - "combat_style": "1", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9291", - "name": "TzHaar-Xil", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2606", - "bonuses": "50,30,80,56,80,80,100,60,50,45,45,0,0,0,0", - "range_level": "70", - "projectile": "442", - "attack_level": "70" - }, - { - "examine": "Doesn't look very social.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9291", - "name": "TzHaar-Xil", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2607", - "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Doesn't look very social.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9291", - "name": "TzHaar-Xil", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2608", - "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Doesn't look very social.", - "combat_style": "1", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "slayer_exp": "0", - "magic_animation": "9345", - "death_animation": "9291", - "name": "TzHaar-Xil", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "70", - "id": "2609", - "bonuses": "50,30,80,56,80,80,100,60,50,45,45,0,0,0,0", - "range_level": "70", - "projectile": "442", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2610", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2611", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2612", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2613", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2614", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2615", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Must be a guard or something.", - "melee_animation": "9345", - "range_animation": "9345", - "magic_level": "70", - "defence_animation": "9287", - "magic_animation": "9345", - "death_animation": "9288", - "name": "TzHaar-Ket", - "defence_level": "70", - "safespot": null, - "lifepoints": "140", - "strength_level": "70", - "id": "2616", - "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", - "range_level": "70", - "attack_level": "70" - }, - { - "name": "Tz-Kih", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "attack_speed": "7", - "id": "2627", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Tz-Kih", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "attack_speed": "7", - "id": "2628", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Tz-Kek", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "attack_speed": "5", - "id": "2629", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Tz-Kek", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "attack_speed": "5", - "id": "2630", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "The Tok-Xil fires deadly spines out of its arm", - "range_animation": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Tok-Xil", - "defence_level": "80", - "safespot": null, - "lifepoints": "114", - "strength_level": "1", - "id": "2631", - "aggressive": "true", - "range_level": "80", - "attack_level": "1" - }, - { - "examine": "A busy-body who loves a bit of gossip.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Miss Schism", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2634", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Dragonkin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "2641", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Nice but dim.", - "name": "Unferth", - "id": "2655" - }, - { - "examine": "Known for his light-fingered qualities.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "2674", - "range_level": "1", - "attack_level": "10" - }, - { - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2675", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He holds up passers by.", - "melee_animation": "799", - "range_animation": "799", - "combat_audio": "511,513,512", - "attack_speed": "5", - "defence_animation": "404", - "weakness": "7", - "magic_animation": "799", - "death_animation": "9055", - "name": "Highwayman", - "defence_level": "8", - "safespot": null, - "lifepoints": "13", - "strength_level": "8", - "id": "2677", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2678", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2679", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2680", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "2", - "id": "2681", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "3102,3104,3103", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "2682", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A citizen of Rimmington.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hengel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2683", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A citizen of Rimmington.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Anja", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2684", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly smelly creature.", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "469,472,471", - "attack_speed": "6", - "defence_animation": "165", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "29", - "strength_level": "10", - "id": "2685", - "aggressive": "true", - "range_level": "20", - "attack_level": "20" - }, - { - "examine": "An ugly smelly creature.", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "469,472,471", - "attack_speed": "6", - "defence_animation": "165", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "29", - "strength_level": "10", - "id": "2686", - "aggressive": "true", - "range_level": "20", - "attack_level": "20" - }, - { - "examine": "An ugly smelly creature.", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "469,472,471", - "attack_speed": "6", - "defence_animation": "165", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "29", - "strength_level": "10", - "id": "2687", - "aggressive": "true", - "range_level": "20", - "attack_level": "20" - }, - { - "examine": "An ugly smelly creature, with a spear.", - "melee_animation": "163", - "range_animation": "163", - "combat_audio": "3520,472,471", - "attack_speed": "6", - "defence_animation": "165", - "magic_animation": "163", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "29", - "strength_level": "10", - "id": "2688", - "aggressive": "true", - "range_level": "20", - "attack_level": "20" - }, - { - "examine": "Didn't the mage say this procedure was totally safe?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Frog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2689", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A salty seafarer. Needs a wash.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jack Seagull", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2690", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A strange man with a strange name. Probably a strange past, too.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Longbow Ben", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2691", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She quackers.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "3468", - "name": "Duck", - "defence_level": "1", - "water_npc": "true", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "2693", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Mini quackers.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "3468", - "name": "Duckling", - "defence_level": "1", - "water_npc": "true", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "2694", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This one's had too much to drink!", - "melee_animation": "422", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "2695", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Known for his light-fingered qualities.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "2696", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "He doesn't look so happy now he's in jail.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Mugger", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "2697", - "aggressive": "true", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "A dark-hearted knight.", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Black knight", - "defence_level": "25", - "safespot": null, - "lifepoints": "42", - "strength_level": "24", - "id": "2698", - "aggressive": "true", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He's guarding the prison.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "2699", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A prison guard.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "2700", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A prison guard.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "2701", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A prison guard.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "2702", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "A prison guard.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "2703", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "He's asleep.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2704", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Keeping an eye out for suspicious activity.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2705", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "No one likes crabs...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Crab", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2706", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A sea bird.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "309,311,310", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Seagull", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2707", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Caution: HOT!", - "start_gfx": "99", - "combat_style": "2", - "start_height": "80", - "melee_animation": "414", - "range_animation": "0", - "magic_level": "18", - "respawn_delay": "60", - "end_gfx": "101", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "2553", - "name": "Fire wizard", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "2709", - "range_level": "1", - "projectile": "100", - "attack_level": "1" - }, - { - "examine": "Hydro-power!", - "combat_style": "2", - "melee_animation": "414", - "range_animation": "0", - "magic_level": "14", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "2553", - "name": "Water wizard", - "defence_level": "14", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "2710", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His hands are covered in mud, at least.", - "start_gfx": "96", - "combat_style": "2", - "start_height": "80", - "melee_animation": "414", - "range_animation": "0", - "magic_level": "16", - "respawn_delay": "60", - "end_gfx": "98", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "2553", - "name": "Earth wizard", - "defence_level": "16", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "2711", - "range_level": "1", - "projectile": "97", - "attack_level": "1" - }, - { - "examine": "At least he looks solid enough to fight.", - "start_gfx": "90", - "combat_style": "2", - "start_height": "80", - "melee_animation": "414", - "range_animation": "0", - "magic_level": "12", - "respawn_delay": "60", - "end_gfx": "92", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "2553", - "name": "Air wizard", - "defence_level": "12", - "safespot": null, - "lifepoints": "17", - "strength_level": "1", - "id": "2712", - "range_level": "1", - "projectile": "91", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "2714", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "25", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2716", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She'll store my items for me.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Betty", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2718", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wise barbarian, apparently. He still looks like a thug.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Otto Godblessed", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2725", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holy looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk of Entrana", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2728", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holy looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk of Entrana", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2729", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holy looking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk of Entrana", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2731", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He works in the Crafting Guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master Crafter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2732", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He wanders around the Crafting Guild pretending to be working.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Master Crafter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2733", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Hangs out in caves.", - "melee_animation": "9232", - "range_animation": "9232", - "attack_speed": "5", - "respawn_delay": "0", - "defence_animation": "9231", - "magic_animation": "9232", - "death_animation": "9230", - "name": "Tz-Kih", - "defence_level": "11", - "safespot": null, - "lifepoints": "10", - "strength_level": "27", - "id": "2734", - "aggressive": "true", - "bonuses": "150,22,22,22,22,11,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Hangs out in caves.", - "melee_animation": "9232", - "range_animation": "9232", - "attack_speed": "5", - "respawn_delay": "0", - "defence_animation": "9231", - "magic_animation": "9232", - "death_animation": "9230", - "name": "Tz-Kih", - "defence_level": "11", - "safespot": null, - "lifepoints": "10", - "strength_level": "27", - "id": "2735", - "aggressive": "true", - "bonuses": "150,22,22,22,22,11,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Looks like living lava...", - "melee_animation": "9233", - "range_animation": "9233", - "attack_speed": "5", - "magic_level": "20", - "defence_animation": "9235", - "magic_animation": "9233", - "death_animation": "9234", - "name": "Tz-Kek", - "defence_level": "22", - "safespot": null, - "lifepoints": "20", - "strength_level": "60", - "id": "2736", - "aggressive": "true", - "bonuses": "80,45,45,45,45,22,0,0,0,0,0,0,0,0,0", - "range_level": "20", - "attack_level": "60" - }, - { - "examine": "Looks like living lava...", - "melee_animation": "9233", - "range_animation": "9233", - "attack_speed": "5", - "magic_level": "20", - "defence_animation": "9235", - "magic_animation": "9233", - "death_animation": "9234", - "name": "Tz-Kek", - "defence_level": "22", - "safespot": null, - "lifepoints": "20", - "strength_level": "60", - "id": "2737", - "aggressive": "true", - "bonuses": "80,45,45,45,45,22,0,0,0,0,0,0,0,0,0", - "range_level": "20", - "attack_level": "60" - }, - { - "examine": "Looks like living lava...", - "melee_animation": "9233", - "range_animation": "9233", - "attack_speed": "5", - "defence_animation": "9235", - "magic_animation": "9233", - "death_animation": "9234", - "name": "Tz-Kek", - "defence_level": "11", - "safespot": null, - "lifepoints": "10", - "strength_level": "30", - "id": "2738", - "bonuses": "60,22,22,22,22,11,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "I don't like the look of those spines...", - "melee_animation": "9245", - "range_animation": "9245", - "attack_speed": "5", - "defence_animation": "9242", - "weakness": "4", - "magic_animation": "9245", - "death_animation": "9239", - "name": "Tok-Xil", - "defence_level": "45", - "safespot": null, - "lifepoints": "40", - "strength_level": "80", - "id": "2739", - "bonuses": "80,90,86,90,90,90,45,55,26,55,0,0,0,0,0", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "I don't like the look of those spines...", - "melee_animation": "9245", - "range_animation": "9245", - "attack_speed": "5", - "defence_animation": "9242", - "weakness": "4", - "magic_animation": "9245", - "death_animation": "9239", - "name": "Tok-Xil", - "defence_level": "45", - "safespot": null, - "lifepoints": "40", - "strength_level": "80", - "id": "2740", - "bonuses": "80,90,86,90,90,90,45,55,26,55,0,0,0,0,0", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "Holy reptile...", - "melee_animation": "9252", - "range_animation": "9252", - "attack_speed": "5", - "defence_animation": "9249", - "magic_animation": "9252", - "death_animation": "9257", - "name": "Yt-MejKot", - "defence_level": "90", - "safespot": null, - "lifepoints": "80", - "strength_level": "100", - "id": "2741", - "aggressive": "true", - "bonuses": "100,180,180,180,180,90,97,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "Holy reptile...", - "melee_animation": "9252", - "range_animation": "9252", - "attack_speed": "5", - "defence_animation": "9249", - "magic_animation": "9252", - "death_animation": "9257", - "name": "Yt-MejKot", - "defence_level": "90", - "safespot": null, - "lifepoints": "80", - "strength_level": "100", - "id": "2742", - "aggressive": "true", - "bonuses": "100,180,180,180,180,90,97,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "That's one hot dog!", - "melee_animation": "9265", - "range_animation": "9265", - "attack_speed": "5", - "magic_level": "150", - "defence_animation": "9268", - "magic_animation": "9265", - "death_animation": "9269", - "name": "Ket-Zek", - "defence_level": "180", - "safespot": null, - "lifepoints": "160", - "strength_level": "150", - "id": "2743", - "bonuses": "180,180,280,280,280,250,140,152,131,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "150" - }, - { - "examine": "That's one hot dog!", - "melee_animation": "9265", - "range_animation": "9265", - "attack_speed": "5", - "magic_level": "150", - "defence_animation": "9268", - "magic_animation": "9265", - "death_animation": "9269", - "name": "Ket-Zek", - "defence_level": "180", - "safespot": null, - "lifepoints": "160", - "strength_level": "150", - "id": "2744", - "bonuses": "180,180,280,280,280,250,140,152,131,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "150" - }, - { - "agg_radius": "64", - "examine": "This is going to hurt...", - "melee_animation": "9277", - "range_animation": "9277", - "attack_speed": "8", - "magic_level": "480", - "defence_animation": "9278", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "9277", - "death_animation": "9279", - "name": "TzTok-Jad", - "defence_level": "480", - "safespot": null, - "lifepoints": "250", - "strength_level": "960", - "id": "2745", - "aggressive": "true", - "bonuses": "0,0,0,60,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "960", - "attack_level": "640" - }, - { - "examine": "Mini Menace.", - "melee_animation": "9252", - "range_animation": "9252", - "attack_speed": "5", - "defence_animation": "9253", - "magic_animation": "9252", - "death_animation": "9257", - "name": "Yt-HurKot", - "defence_level": "75", - "safespot": null, - "lifepoints": "40", - "strength_level": "75", - "id": "2746", - "aggressive": "true", - "bonuses": "100,110,110,110,110,60,110,30,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "She can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2759", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Woman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,506,505", - "strength_level": "1", - "id": "2776", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Ranger of the Temple Knights.", - "melee_animation": "426", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Ranger", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "2779", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shadow.", - "melee_animation": "2738", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "2739", - "name": "Shadow", - "defence_level": "68", - "safespot": null, - "lifepoints": "100", - "strength_level": "68", - "id": "2782", - "aggressive": "true", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "From a darker dimension.", - "slayer_task": "25", - "melee_animation": "2731", - "range_animation": "2731", - "combat_audio": "389,391,390", - "attack_speed": "4", - "magic_level": "160", - "defence_animation": "2732", - "weakness": "4", - "slayer_exp": "225", - "magic_animation": "2731", - "death_animation": "2733", - "name": "Dark beast", - "defence_level": "120", - "safespot": null, - "lifepoints": "220", - "can_tolerate": "false", - "strength_level": "160", - "id": "2783", - "aggressive": "true", - "bonuses": "0,0,0,0,0,30,40,100,90,100,0,0,0,0,0", - "range_level": "1", - "attack_level": "140" - }, - { - "examine": "Digging.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2785", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Digging.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2786", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Confused.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2787", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Drill Sergeant from heck!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sergeant Damien", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2790", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A man down on his luck.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tramp", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2792", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An angry Ogre in a funny hat.", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "defence_animation": "360", - "magic_animation": "359", - "death_animation": "361", - "name": "Ogre", - "defence_level": "30", - "safespot": null, - "lifepoints": "48", - "strength_level": "30", - "id": "2801", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "They just call him 'Coach'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome Coach", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2802", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A cold-blooded creature, partial to warmth.", - "slayer_task": "26", - "melee_animation": "2776", - "range_animation": "2776", - "attack_speed": "5", - "defence_animation": "2777", - "weakness": "0", - "slayer_exp": "40", - "magic_animation": "2776", - "death_animation": "2778", - "name": "Lizard", - "defence_level": "55", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "2803", - "aggressive": "true", - "range_level": "55", - "attack_level": "1" - }, - { - "examine": "A cold-blooded creature, partial to warmth.", - "slayer_task": "26", - "melee_animation": "2776", - "range_animation": "2776", - "attack_speed": "5", - "defence_animation": "2777", - "weakness": "0", - "slayer_exp": "25", - "magic_animation": "2776", - "death_animation": "2778", - "name": "Desert Lizard", - "defence_level": "45", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "2804", - "aggressive": "true", - "range_level": "45", - "attack_level": "1" - }, - { - "examine": "A cold-blooded creature, partial to warmth.", - "slayer_task": "26", - "melee_animation": "2776", - "range_animation": "2776", - "attack_speed": "5", - "defence_animation": "2777", - "weakness": "0", - "slayer_exp": "25", - "magic_animation": "2776", - "death_animation": "2778", - "name": "Desert Lizard", - "defence_level": "45", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "2805", - "aggressive": "true", - "range_level": "45", - "attack_level": "1" - }, - { - "examine": "A cold-blooded creature, partial to warmth.", - "melee_animation": "2776", - "range_animation": "2776", - "attack_speed": "5", - "defence_animation": "2777", - "slayer_exp": "25", - "magic_animation": "2776", - "death_animation": "2778", - "name": "Desert Lizard", - "defence_level": "45", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "2806", - "aggressive": "true", - "range_level": "45", - "attack_level": "1" - }, - { - "examine": "A cold-blooded creature, partial to warmth.", - "slayer_task": "26", - "melee_animation": "2776", - "range_animation": "2776", - "attack_speed": "5", - "defence_animation": "2777", - "weakness": "0", - "slayer_exp": "15", - "magic_animation": "2776", - "death_animation": "2778", - "name": "Small Lizard", - "defence_level": "15", - "safespot": null, - "lifepoints": "15", - "strength_level": "1", - "id": "2807", - "range_level": "15", - "attack_level": "1" - }, - { - "examine": "A cold-blooded creature, partial to warmth.", - "slayer_task": "26", - "melee_animation": "2776", - "range_animation": "2776", - "attack_speed": "5", - "defence_animation": "2777", - "weakness": "0", - "magic_animation": "2776", - "death_animation": "2778", - "name": "Small Lizard", - "defence_level": "15", - "safespot": null, - "lifepoints": "15", - "strength_level": "1", - "id": "2808", - "aggressive": "true", - "range_level": "15", - "attack_level": "1" - }, - { - "examine": "A camel who has the soul of a poet.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Al the Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2809", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A camel whose love is unrequited.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Elly the Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2810", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A camel who wants to fly some day.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ollie the Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2811", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A camel who likes to rest.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cam the Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2812", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A camel who wants to see the world.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Neferti the Camel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2815", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shifty-looking character.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pirate Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2825", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "2826", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shabby-looking leader.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Braindeath", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2827", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Most of an angry", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "50% Luke", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2828", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wonder if it was all the 'rum' that pickled him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Donnie", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2830", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sticking it to 'The Man'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zombie protester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2831", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sticking it to 'The Man'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zombie protester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2832", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sticking it to 'The Man'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zombie protester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2833", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sticking it to 'The Man'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zombie protester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2834", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sticking it to 'The Man'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zombie protester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2835", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sticking it to 'The Man'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Zombie protester", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2836", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An undead sea scoundrel.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "2837", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "An undead sea scoundrel.", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "2838", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "An undead sea scoundrel.", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "2839", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "An undead sea scoundrel.", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "2840", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "An undead sea scoundrel.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "2841", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "An undead sea scoundrel.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "2842", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "He talks a good fight.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie swab", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2843", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "He talks a good fight.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie swab", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2844", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "He talks a good fight.", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie swab", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2845", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "He talks a good fight.", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie swab", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2846", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "He talks a good fight.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie swab", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2847", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "He talks a good fight.", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie swab", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "2848", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "The pun was intended.", - "melee_animation": "2804", - "range_animation": "0", - "magic_level": "40", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "2805", - "name": "Evil spirit", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "2849", - "aggressive": "true", - "range_level": "40", - "attack_level": "40" - }, - { - "examine": "A bunch of legs, eyes and teeth.", - "slayer_task": "76", - "melee_animation": "5319", - "range_animation": "0", - "combat_audio": "537,539,538", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "40", - "magic_animation": "0", - "death_animation": "5321", - "name": "Fever spider", - "defence_level": "40", - "safespot": null, - "lifepoints": "40", - "strength_level": "30", - "id": "2850", - "bonuses": "0,0,0,0,0,20,15,10,15,15,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2851", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2852", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2853", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2854", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2855", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2856", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2857", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker in the brewery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brewer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2858", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "2863", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "2866", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "2869", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "2878", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A knee-high horror from the ocean depths...", - "slayer_task": "24", - "melee_animation": "1579", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "1581", - "name": "Dagannoth fledgeling", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "52", - "id": "2880", - "aggressive": "true", - "range_level": "1", - "attack_level": "52" - }, - { - "agg_radius": "8", - "examine": "The Dagannoth King responsible for the death of Bukalla.", - "combat_style": "1", - "melee_animation": "2855", - "attack_speed": "4", - "magic_level": "255", - "respawn_delay": "60", - "defence_animation": "2852", - "death_animation": "2856", - "name": "Dagannoth Supreme", - "defence_level": "128", - "movement_radius": "8", - "safespot": null, - "lifepoints": "255", - "strength_level": "255", - "id": "2881", - "aggressive": "true", - "bonuses": "0,0,0,0,0,10,10,10,255,550,0,0,0,0,0", - "clue_level": "2", - "range_level": "255", - "projectile": "475", - "attack_level": "255" - }, - { - "agg_radius": "8", - "examine": "A legendary Dagannoth King, rumoured to fly on the North winds.", - "combat_style": "2", - "melee_animation": "2854", - "attack_speed": "4", - "magic_level": "255", - "spell_id": "48", - "respawn_delay": "60", - "defence_animation": "2852", - "death_animation": "2856", - "name": "Dagannoth Prime", - "defence_level": "255", - "movement_radius": "8", - "safespot": null, - "lifepoints": "255", - "strength_level": "255", - "id": "2882", - "aggressive": "true", - "bonuses": "0,0,0,0,0,255,255,255,255,10,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "255" - }, - { - "agg_radius": "8", - "examine": "Firstborn of the legendary Dagannoth Kings.", - "melee_animation": "2853", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "2852", - "death_animation": "2856", - "name": "Dagannoth Rex", - "defence_level": "255", - "movement_radius": "8", - "safespot": null, - "lifepoints": "255", - "strength_level": "255", - "id": "2883", - "aggressive": "true", - "bonuses": "0,0,0,0,0,255,255,255,10,255,0,0,0,0,0", - "clue_level": "2", - "range_level": "255", - "attack_level": "255" - }, - { - "melee_animation": "1312", - "combat_audio": "717,723,722", - "attack_speed": "4", - "respawn_delay": "50", - "defence_animation": "1313", - "death_animation": "1314", - "name": "Giant Rock Crab", - "defence_level": "200", - "safespot": null, - "lifepoints": "180", - "strength_level": "80", - "id": "2885", - "aggressive": "true", - "bonuses": "0,0,0,0,0,225,200,175,-10,250,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "name": "Boulder", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "attack_speed": "5", - "id": "2886", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "1343", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "strength_level": "1", - "id": "2887", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "projectile": "288", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "1343", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "2888", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "projectile": "288", - "attack_level": "1" - }, - { - "examine": "It wasn't a rock... It was a rock lobster!", - "melee_animation": "2860", - "range_animation": "2860", - "combat_audio": "726,728,727", - "attack_speed": "2", - "defence_animation": "2861", - "weakness": "7", - "magic_animation": "2860", - "death_animation": "2862", - "name": "Rock lobster", - "defence_level": "100", - "safespot": null, - "movement_radius": "30", - "lifepoints": "150", - "strength_level": "100", - "id": "2889", - "bonuses": "0,0,0,0,0,100,100,50,50,150,0,0,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A Rock.", - "melee_animation": "2860", - "range_animation": "2860", - "attack_speed": "2", - "defence_animation": "2861", - "weakness": "7", - "magic_animation": "2860", - "death_animation": "2861", - "name": "Large rock", - "defence_level": "100", - "safespot": null, - "lifepoints": "150", - "strength_level": "100", - "id": "2890", - "aggressive": "true", - "range_level": "1", - "attack_level": "100" - }, - { - "agg_radius": "12", - "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", - "combat_style": "2", - "melee_animation": "2868", - "range_animation": "2866", - "attack_speed": "6", - "magic_level": "65", - "spell_id": "14", - "respawn_delay": "55", - "defence_animation": "2869", - "slayer_exp": "0", - "magic_animation": "2866", - "death_animation": "2866", - "name": "Spinolyp", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "10", - "id": "2892", - "aggressive": "true", - "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", - "range_level": "20", - "projectile": "294", - "attack_level": "1" - }, - { - "agg_radius": "12", - "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", - "combat_style": "2", - "melee_animation": "2868", - "range_animation": "2866", - "attack_speed": "6", - "magic_level": "65", - "spell_id": "14", - "respawn_delay": "55", - "defence_animation": "2869", - "magic_animation": "2866", - "death_animation": "2866", - "name": "Spinolyp", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "10", - "id": "2894", - "aggressive": "true", - "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", - "range_level": "20", - "projectile": "294", - "attack_level": "1" - }, - { - "agg_radius": "12", - "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", - "combat_style": "2", - "melee_animation": "2868", - "range_animation": "2866", - "attack_speed": "6", - "magic_level": "65", - "spell_id": "14", - "respawn_delay": "55", - "defence_animation": "2869", - "slayer_exp": "0", - "magic_animation": "2866", - "death_animation": "2866", - "name": "Spinolyp", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "60", - "id": "2896", - "aggressive": "true", - "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", - "range_level": "70", - "projectile": "294", - "attack_level": "1" - }, - { - "melee_animation": "64", - "respawn_delay": "60", - "defence_animation": "65", - "death_animation": "67", - "name": "Agrith Naar", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "id": "2919", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "25", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "2931", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Who ate all the rats?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "The Beast", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2941", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Lovely, cute, and possibly what dreams are made of.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bones", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2945", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Obviously punches above his weight.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hooknosed Jack", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2948", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks rich like an actor of sorts.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jimmy Dazzler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2949", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Once beautiful, now repugnant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "The Face", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2950", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What is he?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Smokin' Joe", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2952", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks fairly well fed.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Silver merchant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2958", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2962", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2963", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2964", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2965", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2966", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2967", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2968", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2969", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2970", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2971", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2972", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "2973", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "2980", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "2981", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The master of all rats.", - "name": "King rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "2982", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not a soft touch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pusskins", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2984", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A not-so friendly, not-so little cat.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Tom", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2986", - "aggressive": "true", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A fully grown feline.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mittens", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2988", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Cute and fluffy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Topsy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2990", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A friendly feline?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gertrude's cat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2997", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very well to do. I wonder what he's doing here.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2998", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Rich.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3001", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Poor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3002", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Poor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3003", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Poor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3004", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Poor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3005", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Poor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gambler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3006", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3007", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3008", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3009", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3010", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3011", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3012", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3013", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3014", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3015", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3016", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3017", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "3018", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tool leprechaun", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3021", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Phenomenal cosmic powers", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Genie", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3022", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An animated clay statue.", - "melee_animation": "2917", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "2919", - "name": "Black golem", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "3026", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "An animated clay statue.", - "melee_animation": "2917", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "2919", - "name": "White golem", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "3027", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "An animated clay statue.", - "melee_animation": "2917", - "range_animation": "0", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "2919", - "name": "Grey golem", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "3028", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "The oldest man in Nardah.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghaslor the Elder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3029", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A water salesman from Pollnivneach.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Carter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3030", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Mayor of Nardah.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Awusah the Mayor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3040", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Poltenip", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "melee_animation": "395", - "strength_level": "1", - "id": "3042", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Radat", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "melee_animation": "395", - "strength_level": "1", - "id": "3043", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "Custodian of the shrine to Elidinis.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shiratti the Custodian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3044", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A banker of Nardah.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Nardah Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3046", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mysterious watcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mystery figure", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3051", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mysterious watcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mystery figure", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3052", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mysterious watcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mystery figure", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3053", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mysterious watcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mystery figure", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3054", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mysterious watcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mystery figure", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3055", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mysterious watcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mystery figure", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3056", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Champion of the earth warriors.", - "melee_animation": "2951", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "2946", - "name": "Earth Warrior Champion", - "defence_level": "84", - "safespot": null, - "lifepoints": "108", - "strength_level": "84", - "id": "3057", - "aggressive": "true", - "range_level": "1", - "attack_level": "84" - }, - { - "examine": "Champion of the giants.", - "melee_animation": "6368", - "range_animation": "0", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "slayer_exp": "35", - "magic_animation": "0", - "death_animation": "6369", - "name": "Giant Champion", - "defence_level": "52", - "safespot": null, - "lifepoints": "70", - "strength_level": "44", - "id": "3058", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "Champion of the ghouls.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "441,444,443", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "50", - "magic_animation": "0", - "death_animation": "836", - "name": "Ghoul Champion", - "defence_level": "60", - "safespot": null, - "lifepoints": "100", - "strength_level": "80", - "id": "3059", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Champion of the goblins.", - "melee_animation": "6188", - "range_animation": "0", - "combat_audio": "469,472,471", - "attack_speed": "4", - "magic_level": "26", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6190", - "name": "Goblin Champion", - "defence_level": "14", - "safespot": null, - "lifepoints": "32", - "strength_level": "1", - "id": "3060", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Champion of the hobgoblins.", - "combat_style": "1", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "469,472,471", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "165", - "weakness": "0", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin Champion", - "defence_level": "48", - "safespot": null, - "lifepoints": "58", - "strength_level": "48", - "id": "3061", - "aggressive": "true", - "range_level": "44", - "attack_level": "44" - }, - { - "examine": "Champion of the imps.", - "melee_animation": "5285", - "range_animation": "0", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "172", - "name": "Imp Champion", - "defence_level": "5", - "safespot": null, - "lifepoints": "40", - "strength_level": "5", - "id": "3062", - "aggressive": "true", - "range_level": "5", - "attack_level": "5" - }, - { - "examine": "Champion of the jogres.", - "melee_animation": "2936", - "range_animation": "2936", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "2937", - "weakness": "9", - "magic_animation": "2936", - "death_animation": "2938", - "name": "Jogre Champion", - "defence_level": "86", - "safespot": null, - "lifepoints": "120", - "strength_level": "86", - "id": "3063", - "aggressive": "true", - "range_level": "1", - "attack_level": "86" - }, - { - "examine": "Champion of the lesser demons.", - "melee_animation": "64", - "range_animation": "0", - "combat_audio": "396,402,401", - "magic_level": "136", - "respawn_delay": "60", - "defence_animation": "65", - "weakness": "5", - "slayer_exp": "79", - "magic_animation": "0", - "death_animation": "67", - "name": "Lesser Demon Champion", - "defence_level": "142", - "safespot": null, - "lifepoints": "148", - "strength_level": "140", - "id": "3064", - "aggressive": "true", - "range_level": "1", - "attack_level": "136" - }, - { - "examine": "Champion of the jogres.", - "melee_animation": "5485", - "range_animation": "5493", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "5493", - "weakness": "9", - "magic_animation": "0", - "death_animation": "1444", - "name": "Skeleton Champion", - "defence_level": "54", - "safespot": null, - "lifepoints": "58", - "strength_level": "1", - "id": "3065", - "aggressive": "true", - "range_level": "36", - "attack_level": "1" - }, - { - "examine": "Champion of the zombies.", - "melee_animation": "5581", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5575", - "name": "Zombies Champion", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "3066", - "aggressive": "true", - "range_level": "1", - "attack_level": "26" - }, - { - "melee_animation": "7049", - "respawn_delay": "60", - "defence_animation": "7050", - "death_animation": "836", - "name": "Leon d'Cour", - "defence_level": "1", - "safespot": null, - "lifepoints": "123", - "strength_level": "1", - "id": "3067", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very dangerous pile of animated Wyvern bones.", - "slayer_task": "95", - "start_gfx": "499", - "melee_animation": "2985", - "attack_speed": "6", - "weakness": "9", - "slayer_exp": "210", - "magic_animation": "2985", - "death_animation": "2987", - "lifepoints": "200", - "id": "3068", - "aggressive": "true", - "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", - "agg_radius": "6", - "range_animation": "2989", - "combat_audio": "0,771,770", - "magic_level": "125", - "end_gfx": "501", - "defence_animation": "2983", - "name": "Skeletal Wyvern", - "defence_level": "120", - "safespot": null, - "strength_level": "116", - "clue_level": "2", - "range_level": "120", - "projectile": "500", - "attack_level": "125" - }, - { - "examine": "A very dangerous pile of animated Wyvern bones.", - "slayer_task": "95", - "start_gfx": "499", - "melee_animation": "2985", - "attack_speed": "6", - "weakness": "9", - "slayer_exp": "210", - "magic_animation": "2985", - "death_animation": "2987", - "lifepoints": "200", - "id": "3069", - "aggressive": "true", - "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", - "agg_radius": "6", - "range_animation": "2989", - "combat_audio": "0,771,770", - "magic_level": "125", - "end_gfx": "501", - "defence_animation": "2983", - "name": "Skeletal Wyvern", - "defence_level": "120", - "safespot": null, - "strength_level": "116", - "clue_level": "2", - "range_level": "120", - "projectile": "500", - "attack_level": "125" - }, - { - "examine": "A very dangerous pile of animated Wyvern bones.", - "slayer_task": "95", - "start_gfx": "499", - "melee_animation": "2985", - "attack_speed": "6", - "weakness": "9", - "slayer_exp": "210", - "magic_animation": "2985", - "death_animation": "2987", - "lifepoints": "200", - "id": "3070", - "aggressive": "true", - "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", - "agg_radius": "6", - "range_animation": "2989", - "combat_audio": "0,771,770", - "magic_level": "125", - "end_gfx": "501", - "defence_animation": "2983", - "name": "Skeletal Wyvern", - "defence_level": "120", - "safespot": null, - "strength_level": "116", - "clue_level": "2", - "range_level": "120", - "projectile": "500", - "attack_level": "125" - }, - { - "examine": "A very dangerous pile of animated Wyvern bones.", - "slayer_task": "95", - "start_gfx": "499", - "melee_animation": "2985", - "attack_speed": "6", - "weakness": "9", - "slayer_exp": "210", - "magic_animation": "2985", - "death_animation": "2987", - "lifepoints": "200", - "id": "3071", - "aggressive": "true", - "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", - "agg_radius": "6", - "range_animation": "2989", - "combat_audio": "0,771,770", - "magic_level": "125", - "end_gfx": "501", - "defence_animation": "2983", - "name": "Skeletal Wyvern", - "defence_level": "120", - "safespot": null, - "strength_level": "116", - "clue_level": "2", - "range_level": "120", - "projectile": "500", - "attack_level": "125" - }, - { - "examine": "He's got icicles in his beard.", - "slayer_task": "47", - "melee_animation": "4672", - "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "70", - "magic_animation": "0", - "death_animation": "4673", - "name": "Ice giant", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "40", - "id": "3072", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A cold-hearted elemental warrior.", - "slayer_task": "48", - "melee_animation": "451", - "range_animation": "451", - "combat_audio": "2500,530,529", - "attack_speed": "4", - "respawn_delay": "30", - "defence_animation": "404", - "weakness": "9", - "slayer_exp": "59", - "magic_animation": "451", - "death_animation": "843", - "name": "Ice warrior", - "defence_level": "47", - "safespot": null, - "lifepoints": "59", - "strength_level": "47", - "id": "3073", - "aggressive": "true", - "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "47" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3074", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3075", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3079", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3080", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3089", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mighty warrior", - "melee_animation": "7048", - "range_animation": "0", - "combat_audio": "511,513,512", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "", - "defence_level": "17", - "safespot": null, - "lifepoints": "24", - "strength_level": "17", - "id": "3090", - "aggressive": "true", - "range_level": "1", - "attack_level": "17" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3091", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The book moves by itself!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Flying Book", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3094", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Entrance Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3097", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Telekinetic Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3098", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Alchemy Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3099", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Enchantment Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3100", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Graveyard Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3101", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Maze Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3102", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guardian of the arena.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rewards Guardian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3103", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Equipment that moves by itself!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Charmed Warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3104", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Equipment that moves by itself!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Charmed Warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3105", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Equipment that moves by itself!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Charmed Warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3106", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This guard looks rather drunk and has beer stains down his armour.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard Captain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3109", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Balloon Animal", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3121", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I saw the witchdoctor", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Balloon Animal", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3122", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like he's seen the inside of a few tombs.", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Simon Templeton", - "defence_level": "1", - "safespot": "0", - "lifepoints": "12", - "strength_level": "1", - "id": "3123", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It seems to be blocked.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Furnace grate", - "defence_level": "1", - "safespot": null, - "lifepoints": "0", - "strength_level": "1", - "id": "3135", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3150", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A swarm of bugs.", - "slayer_task": "42", - "melee_animation": "1584", - "range_animation": "0", - "combat_audio": "2743,2745,2744", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "1585", - "name": "Harpie Bug Swarm", - "defence_level": "32", - "safespot": null, - "lifepoints": "25", - "strength_level": "46", - "id": "3153", - "aggressive": "true", - "bonuses": "0,0,0,0,0,10,5,10,5,10,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "Bill Teach the pirate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bill Teach", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3155", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3167", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3168", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3169", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3170", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3171", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3172", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3173", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3174", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3175", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3176", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3177", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3178", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3179", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3180", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3181", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3182", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3183", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3184", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3185", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "3186", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "422", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "3187", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3188", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3189", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3190", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3191", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3192", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3193", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3194", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Arghh matey!", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "388", - "death_animation": "9055", - "name": "Pirate", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "40", - "id": "3195", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "range_level": "1", - "attack_level": "40" - }, - { - "melee_animation": "400", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "3196", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3198", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3199", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "pUre A cHaOs of crEatuRe!", - "start_gfx": "556", - "melee_animation": "3146", - "attack_speed": "5", - "respawn_delay": "100", - "weakness": "4", - "magic_animation": "5443", - "death_animation": "3147", - "lifepoints": "250", - "id": "3200", - "aggressive": "true", - "bonuses": "0,0,0,0,0,70,70,70,70,70,0,0,0,0,0", - "agg_radius": "16", - "range_animation": "5443", - "combat_audio": "345,351,347", - "magic_level": "270", - "end_gfx": "558", - "defence_animation": "3149", - "name": "Chaos Elemental", - "defence_level": "270", - "movement_radius": "30", - "safespot": "true", - "strength_level": "270", - "range_level": "270", - "projectile": "557", - "attack_level": "270" - }, - { - "slayer_exp": "51", - "name": "Killerwatt", - "defence_level": "1", - "safespot": null, - "lifepoints": "51", - "strength_level": "1", - "attack_speed": "3", - "id": "3201", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "slayer_exp": "51", - "name": "Killerwatt", - "defence_level": "1", - "safespot": null, - "lifepoints": "51", - "strength_level": "1", - "attack_speed": "3", - "id": "3202", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A very small storm!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Storm Cloud", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3203", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very small storm!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Storm Cloud", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3204", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mourner, or plague healer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mourner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3216", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Loves mining.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "3219", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Loves mining.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "3220", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "Loves mining.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "3221", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "3223", - "range_level": "1", - "attack_level": "3" - }, - { - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3224", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens. He looks worried about something.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "3225", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "melee_animation": "422", - "combat_audio": "511,506,505", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Woman", - "defence_level": "1", - "safespot": null, - "lifepoints": "9", - "strength_level": "1", - "id": "3226", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Woman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,506,505", - "strength_level": "1", - "id": "3227", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "386", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "3228", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "4230", - "range_animation": "2075", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "3229", - "clue_level": "1", - "range_level": "13", - "attack_level": "1" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "395", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "404", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "3230", - "clue_level": "1", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "422", - "range_animation": "426", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "3231", - "clue_level": "1", - "range_level": "13", - "attack_level": "1" - }, - { - "examine": "Keeping an eye out for threats to the city.", - "melee_animation": "422", - "range_animation": "426", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "3232", - "clue_level": "1", - "range_level": "13", - "attack_level": "1" - }, - { - "examine": "Keeping an eye out for threats to the city.", - "melee_animation": "422", - "range_animation": "426", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "3233", - "clue_level": "1", - "range_level": "13", - "attack_level": "1" - }, - { - "examine": "An old gardener.", - "melee_animation": "433", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Gardener", - "defence_level": "4", - "safespot": null, - "lifepoints": "5", - "strength_level": "4", - "id": "3234", - "range_level": "1", - "attack_level": "4" - }, - { - "examine": "He's learning a trade.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Apprentice workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3235", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A busy workman", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3236", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Cuffs", - "defence_level": "1", - "safespot": null, - "lifepoints": "7", - "melee_animation": "422", - "strength_level": "1", - "id": "3237", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Rusty", - "defence_level": "1", - "safespot": null, - "lifepoints": "7", - "melee_animation": "422", - "strength_level": "1", - "id": "3239", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Jeff", - "defence_level": "1", - "safespot": null, - "lifepoints": "7", - "melee_animation": "422", - "strength_level": "1", - "id": "3240", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "404", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "3241", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A practicer of dark arts.", - "combat_style": "2", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "25", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "25", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "3242", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A practicer of dark arts.", - "combat_style": "2", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "27", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "27", - "safespot": null, - "lifepoints": "38", - "strength_level": "1", - "id": "3243", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A practicer of dark arts.", - "combat_style": "2", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "16", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "16", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "3244", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A practicer of dark arts.", - "combat_style": "2", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "16", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "16", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "3245", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Alberich, a fierce barbarian warrior.", - "melee_animation": "2067", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3246", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Fafner, a tough barbarian warrior.", - "melee_animation": "7048", - "range_animation": "7048", - "attack_speed": "6", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "7048", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "18", - "strength_level": "22", - "id": "3247", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Fasolt, a strong barbarian warrior.", - "melee_animation": "2067", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3248", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Siegmund, a guard in the Barbarian Village.", - "melee_animation": "401", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3249", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Siegfried, a young guard in the Barbarian Village.", - "melee_animation": "2067", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3250", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Lydspor, a well-traveld barbarian warrior.", - "melee_animation": "7048", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3251", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Hagen, a guard in the Barbarian Village.", - "melee_animation": "2067", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3252", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Minarch, a barbarian who likes his beer.", - "melee_animation": "401", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3253", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Wotan, a sturdy barbarian warrior.", - "melee_animation": "401", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3255", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Acelin, a guard in the Barbarian Village.", - "melee_animation": "390", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3256", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Adelino, a barbarian warrior with a big axe.", - "melee_animation": "2067", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3257", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Adolpho, a barbarian warrior with a warhammer.", - "melee_animation": "401", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3258", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Aitan, a barbarian archer.", - "melee_animation": "426", - "range_animation": "426", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3259", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Brunnhilde, a fierce barbarian warrior.", - "melee_animation": "428", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "3260", - "clue_level": "0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Gutrune, a mighty barbarian warrior.", - "melee_animation": "428", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "3261", - "clue_level": "0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Edelschwarz, a barbarian warrior with a spear.", - "melee_animation": "428", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "3262", - "clue_level": "0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Sieglinde, a muscular barbarian warrior.", - "melee_animation": "428", - "range_animation": "428", - "attack_speed": "6", - "defence_animation": "404", - "weakness": "8", - "magic_animation": "428", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "22", - "safespot": null, - "lifepoints": "20", - "strength_level": "20", - "id": "3263", - "clue_level": "0", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "3264", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "3265", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "3266", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "470,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "3267", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3268", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3269", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3270", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3271", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3272", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3273", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3274", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A dwarven worker.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Dwarf", - "defence_level": "10", - "safespot": null, - "lifepoints": "14", - "strength_level": "10", - "id": "3275", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "3276", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "3277", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "3278", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A member of the Black Guard", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "102", - "name": "Black Guard", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "3279", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "He looks busy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Engineering assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3280", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's building a cannon.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Engineer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3282", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Bushy tail!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squirrel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3283", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A raccoon.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Raccoon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3286", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A raccoon.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Raccoon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3288", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She'll store my items for me.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3293", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf who looks after the mining guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3294", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf who looks after the mining guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3295", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A graceful bird.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Swan", - "defence_level": "1", - "safespot": null, - "water_npc": true, - "lifepoints": "10", - "strength_level": "1", - "id": "3296", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Keeps this magic area tidy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sweeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3298", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A master at gardening.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Martin the Master Gardener", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3299", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Manages the fairies.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Co-ordinator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3302", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I'm gonna make him an offer he can't refuse.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy Godfather", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3304", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Guardian of the market gate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gatekeeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3307", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Converts grass to beef.", - "slayer_task": "20", - "melee_animation": "5849", - "range_animation": "5849", - "combat_audio": "369,371,370", - "attack_speed": "5", - "defence_animation": "5850", - "weakness": "8", - "slayer_exp": "8", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "3309", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy", - "name": "Sheep", - "id": "3310" - }, - { - "name": "Tanglefoot", - "defence_level": "1", - "safespot": null, - "lifepoints": "102", - "strength_level": "1", - "id": "3313", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "An animated shrub.", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "name": "Baby tanglefoot", - "defence_level": "41", - "safespot": null, - "lifepoints": "58", - "strength_level": "1", - "id": "3319", - "range_level": "41", - "attack_level": "1" - }, - { - "examine": "An aggressive bush.", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "name": "Baby tanglefoot", - "defence_level": "41", - "safespot": null, - "lifepoints": "58", - "strength_level": "1", - "id": "3320", - "range_level": "41", - "attack_level": "1" - }, - { - "examine": "Rather more tired than most.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jeremy Clerksin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3327", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks a little green around the gills.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barfy Bill", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3331", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's made of pure fire.", - "attack_speed": "6", - "magic_level": "300", - "respawn_delay": "25", - "name": "Cavemouth", - "defence_level": "500", - "safespot": null, - "lifepoints": "1000", - "strength_level": "1500", - "id": "3334", - "aggressive": "true", - "bonuses": "126,98,86,297,311,304,319,13,284,30,0,0,0,0,0", - "range_level": "300", - "attack_level": "200" - }, - { - "examine": "Holy Mole-y!", - "melee_animation": "3312", - "range_animation": "3312", - "combat_audio": "1642,1646,1645", - "attack_speed": "4", - "magic_level": "200", - "respawn_delay": "56", - "defence_animation": "3311", - "weakness": "7", - "magic_animation": "3312", - "death_animation": "3310", - "name": "Giant Mole", - "defence_level": "200", - "safespot": null, - "lifepoints": "200", - "strength_level": "200", - "id": "3340", - "bonuses": "0,0,0,0,0,60,80,100,80,60,0,0,0,0,0", - "range_level": "1", - "attack_level": "200" - }, - { - "examine": "I will call him, Mini Mole.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby Mole", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3341", - "aggressive": "false", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fungi", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "3344", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense.", - "melee_animation": "2776", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "2775", - "death_animation": "2777", - "name": "Fungi", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "3345", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bouncy fungus.", - "slayer_task": "94", - "melee_animation": "2776", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "2777", - "name": "Zygomite", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "3346", - "range_level": "42", - "attack_level": "1" - }, - { - "examine": "Have a fungus.", - "melee_animation": "2776", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "2775", - "death_animation": "2777", - "name": "Zygomite", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "3347", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "7049", - "combat_audio": "511,513,512", - "attack_speed": "8", - "respawn_delay": "60", - "defence_animation": "7050", - "death_animation": "836", - "name": "White Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "53", - "strength_level": "1", - "id": "3348", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "7049", - "combat_audio": "511,513,512", - "attack_speed": "8", - "respawn_delay": "60", - "defence_animation": "7050", - "death_animation": "836", - "name": "White Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "53", - "strength_level": "1", - "id": "3349", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "7049", - "combat_audio": "511,513,512", - "attack_speed": "8", - "respawn_delay": "60", - "defence_animation": "7050", - "death_animation": "836", - "name": "White Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "53", - "strength_level": "1", - "id": "3350", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Evil Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "355,357,356", - "strength_level": "1", - "id": "3366", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Evil Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "355,357,356", - "strength_level": "1", - "id": "3367", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Evil Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "355,357,356", - "strength_level": "1", - "id": "3368", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Evil Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "355,357,356", - "strength_level": "1", - "id": "3369", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Evil Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "355,357,356", - "strength_level": "1", - "id": "3370", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Evil Chicken", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "355,357,356", - "strength_level": "1", - "id": "3371", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fowl beast.", - "slayer_task": "7", - "melee_animation": "2299", - "range_animation": "0", - "combat_audio": "355,357,356", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "2301", - "name": "Evil Chicken", - "defence_level": "55", - "safespot": null, - "lifepoints": "117", - "strength_level": "55", - "id": "3375", - "aggressive": "true", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "Young but still dangerous.", - "slayer_task": "68", - "melee_animation": "25", - "range_animation": "25", - "combat_audio": "405,407,406", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "32", - "defence_animation": "26", - "weakness": "3", - "slayer_exp": "0", - "magic_animation": "25", - "death_animation": "28", - "name": "Baby black dragon", - "defence_level": "42", - "safespot": null, - "lifepoints": "50", - "strength_level": "80", - "id": "3376", - "aggressive": "true", - "bonuses": "50,40,64,60,30,45,40,40,20,40,40,20,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "He seems to like wearing black.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Evil Dave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3378", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Vermin from the underworld.", - "slayer_task": "67", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hell-Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3382", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shifty-looking character.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pirate Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3389", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks short and grumpy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3390", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "General Wartface", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3391", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "General Bentnoze", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3392", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He provides new players with useful information.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lumbridge Guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3393", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems to like wearing black.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Evil Dave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3394", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Rutmir's assistant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3404", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A small ice demon.", - "slayer_task": "46", - "range_animation": "0", - "combat_audio": "531,533,532", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "name": "Icefiend", - "defence_level": "60", - "safespot": null, - "lifepoints": "171", - "strength_level": "60", - "id": "3406", - "aggressive": "true", - "clue_level": "0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "7218", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "7219", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "3407", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He tries to keep order around here.", - "melee_animation": "583", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "7213", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "3408", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "A sentient plant - ready", - "melee_animation": "7246", - "range_animation": "0", - "poisonous": "true", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7249", - "name": "Wild jade vine", - "defence_level": "65", - "safespot": null, - "lifepoints": "185", - "strength_level": "65", - "id": "3409", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "A sentient plant - ready", - "melee_animation": "7246", - "range_animation": "0", - "poisonous": "true", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7249", - "name": "Wild jade vine", - "defence_level": "65", - "safespot": null, - "lifepoints": "185", - "strength_level": "65", - "id": "3410", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "A sentient plant - ready", - "melee_animation": "7246", - "range_animation": "0", - "poisonous": "true", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7249", - "name": "Wild jade vine", - "defence_level": "65", - "safespot": null, - "lifepoints": "185", - "strength_level": "65", - "id": "3411", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "A sentient plant - ready", - "melee_animation": "7246", - "range_animation": "0", - "poisonous": "true", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7249", - "name": "Wild jade vine", - "defence_level": "65", - "safespot": null, - "lifepoints": "185", - "strength_level": "65", - "id": "3412", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "He's got funky socks, but he's still an ugly green creature.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Goblin Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3413", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "More like a goblin cooked.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Goblin Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3414", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Half way up the wall is maybe not a naturally tenable position for a goblin.", - "name": "Goblin Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "3415", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He'll store my items for me.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pirate Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3416", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He'll store my items for me.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pirate Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3418", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ogre", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "attack_speed": "7", - "id": "3419", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "An angry Ogre in a highly amusing hat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mogre Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3420", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Nice claw!", - "melee_animation": "3428", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "3430", - "name": "Crab", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3421", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Not the most beautiful fish in the sea.", - "melee_animation": "3433", - "range_animation": "0", - "combat_audio": "241,243,242", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "10", - "defence_animation": "3434", - "weakness": "9", - "magic_animation": "0", - "death_animation": "3435", - "name": "Mudskipper", - "defence_level": "26", - "safespot": null, - "lifepoints": "20", - "strength_level": "29", - "id": "3422", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "29" - }, - { - "examine": "Not the most beautiful fish in the sea.", - "melee_animation": "3433", - "combat_audio": "241,243,242", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "5", - "defence_animation": "3434", - "death_animation": "3435", - "name": "Mudskipper", - "defence_level": "29", - "safespot": null, - "lifepoints": "20", - "strength_level": "30", - "id": "3423", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "death_animation": "3430", - "name": "Crab", - "defence_level": "1", - "safespot": null, - "lifepoints": "18", - "melee_animation": "3428", - "strength_level": "1", - "id": "3424", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "3429" - }, - { - "examine": "A Red Fantail.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3425", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Red Fantail.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3426", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Red Fantail.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3427", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An Angel Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3431", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An Angel Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3432", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An Angel Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3433", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Harlequin Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3434", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Harlequin Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3435", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Harlequin Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3436", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Discus Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3437", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Discus Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3438", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Discus Fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3439", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shoal of Neon Tetra.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3443", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shoal of Neon Tetra.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3444", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shoal of Neon Tetra.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3445", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Lumbridge Guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "attack_speed": "7", - "id": "3449", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "attack_speed": "7", - "id": "3450", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Lumbridge Guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "attack_speed": "7", - "id": "3451", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "What restful music!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Skrach Uglogwee", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3463", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A large boisterous bird", - "slayer_task": "7", - "melee_animation": "6800", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "6801", - "name": "Jubbly bird", - "defence_level": "8", - "safespot": null, - "lifepoints": "11", - "strength_level": "6", - "id": "3476", - "aggressive": "true", - "range_level": "8", - "attack_level": "6" - }, - { - "name": "King Awowogei", - "defence_level": "1", - "safespot": null, - "lifepoints": "328", - "strength_level": "1", - "id": "3478", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A big snake.", - "melee_animation": "3538", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "3540", - "name": "Big Snake", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "46", - "id": "3484", - "aggressive": "true", - "range_level": "1", - "attack_level": "46" - }, - { - "name": "Culinaromancer", - "defence_level": "1", - "safespot": null, - "lifepoints": "140", - "strength_level": "1", - "id": "3491", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "melee_animation": "3501", - "respawn_delay": "60", - "defence_animation": "3500", - "death_animation": "3503", - "name": "Agrith-Na-Na", - "defence_level": "1", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "3493", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1750", - "respawn_delay": "60", - "defence_animation": "1751", - "death_animation": "1752", - "name": "Flambeed", - "defence_level": "1", - "safespot": null, - "lifepoints": "210", - "strength_level": "1", - "id": "3494", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Karamel", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "3495", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "3507", - "respawn_delay": "60", - "defence_animation": "3505", - "death_animation": "3510", - "name": "Dessourt", - "defence_level": "1", - "safespot": null, - "lifepoints": "140", - "strength_level": "1", - "id": "3496", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Deadly AND fruity!", - "melee_animation": "1341", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "1342", - "name": "Gelatinnoth Mother", - "defence_level": "65", - "safespot": null, - "lifepoints": "139", - "strength_level": "48", - "id": "3497", - "aggressive": "true", - "range_level": "1", - "attack_level": "48" - }, - { - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Gelatinnoth Mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "3498", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Gelatinnoth Mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "3499", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Gelatinnoth Mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "3500", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Gelatinnoth Mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "3501", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "1341", - "respawn_delay": "60", - "defence_animation": "1340", - "death_animation": "1342", - "name": "Gelatinnoth Mother", - "defence_level": "1", - "safespot": null, - "lifepoints": "240", - "strength_level": "1", - "id": "3502", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Chronicler and regaler of your piratical exploits.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sorin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3509", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An initiate juvenile vampyre.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Vampyre Juvinate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3514", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An initiate juvenile vampyre.", - "melee_animation": "5783", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "5798", - "name": "Vampyre Juvinate", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "1", - "id": "3521", - "aggressive": "true", - "range_level": "45", - "attack_level": "1" - }, - { - "death_animation": "5798", - "name": "Vampyre Juvinate", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "melee_animation": "5783", - "strength_level": "1", - "id": "3522", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "death_animation": "5798", - "name": "Vampyre Juvinate", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "melee_animation": "5783", - "strength_level": "1", - "id": "3523", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "death_animation": "5798", - "name": "Vampyre Juvinate", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "melee_animation": "5783", - "strength_level": "1", - "id": "3524", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "death_animation": "5798", - "name": "Vampyre Juvinate", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "melee_animation": "5783", - "strength_level": "1", - "id": "3525", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "An initiate juvenile vampyre", - "slayer_task": "86", - "melee_animation": "6016", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "6031", - "name": "Vampyre Juvinate", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "3526", - "range_level": "46", - "attack_level": "1" - }, - { - "examine": "A Juvinate vampyre", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "5798", - "name": "Held Vampyre Juvinate", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "1", - "id": "3527", - "range_level": "45", - "attack_level": "1" - }, - { - "examine": "He looks really hungry!", - "slayer_task": "86", - "melee_animation": "6276", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Vampyre Juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "3531", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "She looks really hungry!", - "slayer_task": "86", - "melee_animation": "6276", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Vampyre Juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "3532", - "range_level": "1", - "attack_level": "40" - }, - { - "death_animation": "6781", - "name": "Vampyre Juvenile", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "6276", - "strength_level": "1", - "id": "3533", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "He looks really hungry!", - "slayer_task": "86", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Held Vampyre Juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "3534", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "An initiate juvenile vampyre", - "slayer_task": "86", - "melee_animation": "6016", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "6031", - "name": "Juvinate", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "3577", - "range_level": "46", - "attack_level": "1" - }, - { - "examine": "Is it a sheep?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3579", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "49", - "name": "Guard dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3582", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "164", - "combat_audio": "469,472,471", - "respawn_delay": "60", - "defence_animation": "163", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "29", - "strength_level": "1", - "id": "3583", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "No spider could grow that big! It's unrealistic!", - "melee_animation": "5319", - "range_animation": "0", - "combat_audio": "537,539,538", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "5321", - "name": "Huge spider", - "defence_level": "72", - "safespot": null, - "lifepoints": "122", - "strength_level": "1", - "id": "3585", - "aggressive": "true", - "range_level": "72", - "attack_level": "1" - }, - { - "examine": "Good doggy...", - "slayer_task": "43", - "melee_animation": "6562", - "range_animation": "0", - "combat_audio": "3717,3719,3718", - "attack_speed": "4", - "respawn_delay": "50", - "defence_animation": "0", - "weakness": "7", - "slayer_exp": "116", - "magic_animation": "0", - "death_animation": "6576", - "name": "Hellhound", - "defence_level": "102", - "safespot": null, - "lifepoints": "116", - "strength_level": "104", - "id": "3586", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "105" - }, - { - "examine": "Big, ugly, and smelly.", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "27", - "respawn_delay": "25", - "defence_animation": "360", - "magic_animation": "359", - "death_animation": "361", - "name": "Rantz", - "defence_level": "27", - "safespot": null, - "lifepoints": "60", - "strength_level": "27", - "id": "3587", - "aggressive": "true", - "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", - "range_level": "27", - "attack_level": "27" - }, - { - "examine": "Young but still dangerous.", - "melee_animation": "25", - "range_animation": "25", - "combat_audio": "405,407,406", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "32", - "defence_animation": "26", - "weakness": "8", - "magic_animation": "25", - "death_animation": "28", - "name": "Baby red dragon", - "defence_level": "42", - "safespot": null, - "lifepoints": "50", - "strength_level": "40", - "id": "3588", - "aggressive": "true", - "bonuses": "20,10,10,20,40,40,20,40,40,20,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "I don't think insect repellent will work...", - "melee_animation": "6223", - "range_animation": "0", - "combat_audio": "567,569,568", - "attack_speed": "4", - "poisonous": "true", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "6227", - "weakness": "6", - "poison_amount": "4", - "magic_animation": "0", - "death_animation": "6228", - "name": "Kalphite Soldier", - "defence_level": "70", - "safespot": null, - "lifepoints": "90", - "strength_level": "70", - "id": "3589", - "aggressive": "true", - "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "Its scales seem to be made of steel.", - "combat_audio": "408,410,409", - "magic_level": "72", - "respawn_delay": "35", - "weakness": "8", - "slayer_exp": "221", - "name": "Steel dragon", - "defence_level": "238", - "safespot": null, - "lifepoints": "210", - "strength_level": "229", - "id": "3590", - "aggressive": "true", - "bonuses": "56,42,104,51,212,115,232,302,331,21,264,100,100,40,0", - "clue_level": "2", - "range_level": "185", - "attack_level": "234" - }, - { - "examine": "A darkened horror from the ocean depths.", - "name": "Dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3591", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Arrgh! Look at its pointy teeth!", - "range_animation": "0", - "combat_audio": "400,404,403", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Demon", - "defence_level": "75", - "safespot": null, - "lifepoints": "107", - "strength_level": "75", - "id": "3593", - "aggressive": "true", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "A large snake that thrives in swamps.", - "melee_animation": "3538", - "range_animation": "3538", - "combat_audio": "3609,3608,3610", - "attack_speed": "5", - "defence_animation": "3539", - "weakness": "0", - "magic_animation": "3538", - "death_animation": "3540", - "name": "Swamp snake", - "defence_level": "40", - "safespot": null, - "lifepoints": "121", - "strength_level": "33", - "id": "3599", - "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", - "range_level": "45", - "attack_level": "35" - }, - { - "examine": "A large snake that thrives in swamps.", - "melee_animation": "3538", - "range_animation": "3538", - "combat_audio": "3609,3608,3610", - "attack_speed": "5", - "defence_animation": "3539", - "magic_animation": "3538", - "death_animation": "3540", - "name": "Swamp snake", - "defence_level": "60", - "safespot": null, - "lifepoints": "121", - "strength_level": "50", - "id": "3600", - "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A large snake that thrives in swamps.", - "slayer_task": "86", - "melee_animation": "3538", - "range_animation": "3538", - "combat_audio": "3609,3608,3610", - "attack_speed": "5", - "defence_animation": "3539", - "weakness": "7", - "magic_animation": "3538", - "death_animation": "3540", - "name": "Swamp snake", - "defence_level": "40", - "safespot": null, - "lifepoints": "121", - "strength_level": "33", - "id": "3601", - "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "A large snake that thrives in swamps.", - "melee_animation": "3538", - "range_animation": "3538", - "combat_audio": "3609,3608,3610", - "attack_speed": "5", - "defence_animation": "3539", - "magic_animation": "3538", - "death_animation": "3540", - "name": "Swamp snake", - "defence_level": "40", - "safespot": null, - "lifepoints": "121", - "strength_level": "33", - "id": "3602", - "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", - "range_level": "1", - "attack_level": "35" - }, - { - "name": "Dead swamp snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3609,3608,3610", - "strength_level": "1", - "id": "3603", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Dead swamp snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3609,3608,3610", - "strength_level": "1", - "id": "3604", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Dead swamp snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3609,3608,3610", - "strength_level": "1", - "id": "3605", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I'm glad I can't see the rest of it!", - "melee_animation": "3618", - "range_animation": "3618", - "magic_level": "80", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "3620", - "name": "Tentacle", - "defence_level": "60", - "safespot": null, - "lifepoints": "171", - "strength_level": "80", - "id": "3618", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "I'm glad I can't see the rest of it!", - "melee_animation": "3731", - "range_animation": "0", - "attack_speed": "10", - "magic_level": "80", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "3733", - "name": "Head", - "defence_level": "60", - "safespot": null, - "lifepoints": "171", - "strength_level": "85", - "id": "3619", - "aggressive": "true", - "range_level": "80", - "attack_level": "85" - }, - { - "melee_animation": "3731", - "attack_speed": "10", - "respawn_delay": "60", - "defence_animation": "3732", - "death_animation": "3733", - "name": "Head", - "defence_level": "1", - "safespot": null, - "lifepoints": "150", - "strength_level": "1", - "id": "3620", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "3622", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A high-ranking Vyrewatch", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fyiona Fray", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3634", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a little on the cross side!", - "range_animation": "0", - "combat_audio": "297,299,298", - "melee_animation": "4927", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "4927", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4929", - "name": "Angry bear", - "defence_level": "38", - "safespot": null, - "lifepoints": "35", - "strength_level": "41", - "id": "3645", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "He looks a little on the cross side!", - "melee_animation": "6376", - "range_animation": "0", - "combat_audio": "876,878,877", - "attack_speed": "4", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6377", - "name": "Angry unicorn", - "defence_level": "38", - "safespot": null, - "lifepoints": "50", - "strength_level": "41", - "id": "3646", - "aggressive": "false", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "He looks a little on the cross side!", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "4934", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4935", - "name": "Angry giant rat", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "3647", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a little on the cross side!", - "melee_animation": "6185", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "6183", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6182", - "name": "Angry goblin", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "3648", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "AHHHHH!", - "melee_animation": "3812", - "range_animation": "0", - "combat_audio": "297,299,298", - "attack_speed": "4", - "defence_animation": "3811", - "weakness": "", - "magic_animation": "0", - "death_animation": "3813", - "name": "Fear reaper", - "defence_level": "40", - "safespot": null, - "lifepoints": "25", - "strength_level": "41", - "id": "3649", - "range_level": "1", - "attack_level": "41" - }, - { - "examine": "What on Gielinor is that?!?", - "melee_animation": "3818", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "3821", - "name": "Confusion beast", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "3650", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A hopeless poor creature.", - "melee_animation": "3823", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "3827", - "name": "Hopeless creature", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "3655", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a little on the cross side!", - "melee_animation": "6376", - "range_animation": "0", - "combat_audio": "876,878,877", - "attack_speed": "4", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6377", - "name": "Angry unicorn", - "defence_level": "38", - "safespot": null, - "lifepoints": "50", - "strength_level": "41", - "id": "3661", - "aggressive": "false", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "He looks a little on the cross side!", - "combat_audio": "703,705,704", - "melee_animation": "4933", - "defence_animation": "4934", - "death_animation": "4935", - "name": "Angry giant rat", - "defence_level": "38", - "safespot": null, - "lifepoints": "50", - "strength_level": "41", - "id": "3662", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "He looks a little on the cross side!", - "slayer_task": "38", - "melee_animation": "6185", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "6183", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6182", - "name": "Angry goblin", - "defence_level": "38", - "safespot": null, - "lifepoints": "50", - "strength_level": "41", - "id": "3663", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "He looks a little on the cross side!", - "combat_audio": "297,299,298", - "melee_animation": "4927", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "4927", - "death_animation": "4929", - "name": "Angry bear", - "defence_level": "38", - "safespot": null, - "lifepoints": "10", - "strength_level": "41", - "id": "3664", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "AHHHHH!", - "melee_animation": "3812", - "combat_audio": "297,299,298", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "3811", - "death_animation": "3813", - "name": "Fear reaper", - "defence_level": "45", - "safespot": null, - "lifepoints": "57", - "strength_level": "48", - "id": "3665", - "bonuses": "", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "What on Gielinor is that?!?", - "melee_animation": "3818", - "combat_audio": "297,299,298", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "3820", - "death_animation": "3821", - "name": "Confusion beast", - "defence_level": "52", - "safespot": null, - "lifepoints": "64", - "strength_level": "55", - "id": "3666", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "52" - }, - { - "examine": "He looks a little on the cross side!", - "melee_animation": "3823", - "combat_audio": "297,299,298", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "death_animation": "3827", - "name": "Hopeless creature", - "defence_level": "59", - "safespot": null, - "lifepoints": "71", - "strength_level": "62", - "id": "3667", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "59" - }, - { - "examine": "That's a lot of bones on his back...", - "name": "Odd Old Man", - "id": "3670" - }, - { - "examine": "Freshly sheared.", - "melee_animation": "5341", - "range_animation": "0", - "combat_audio": "757,759,758", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5337", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5343", - "name": "Ram", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "3672", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "5338", - "range_animation": "0", - "combat_audio": "757,759,758", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5337", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5336", - "name": "Ram", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "3673", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Sack", - "id": "3674" - }, - { - "examine": "If you see them circling, run.", - "melee_animation": "2019", - "range_animation": "0", - "combat_audio": "890,892,891", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "2024", - "weakness": "9", - "magic_animation": "0", - "death_animation": "2021", - "name": "Vulture", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "40", - "id": "3675", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "If you see them circling, run.", - "melee_animation": "2025", - "combat_audio": "890,892,891", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "2024", - "death_animation": "2026", - "name": "Vulture", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "40", - "id": "3676", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A young boy handing out flyers.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ali the Leaflet Dropper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3680", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Ulfric", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "6118", - "strength_level": "1", - "id": "3706", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Eww", - "slayer_task": "67", - "melee_animation": "6117", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "50", - "magic_animation": "0", - "death_animation": "6115", - "name": "Brine rat", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "3707", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "A Wilderness fighter of massive repute.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boulder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3709", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An annoying flappy thing.", - "slayer_task": "5", - "melee_animation": "4915", - "range_animation": "4915", - "combat_audio": "292,294,293", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "4916", - "weakness": "4", - "slayer_exp": "8", - "magic_animation": "4915", - "death_animation": "4917", - "name": "Giant bat", - "defence_level": "22", - "safespot": null, - "lifepoints": "32", - "strength_level": "22", - "id": "3711", - "aggressive": "true", - "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", - "range_level": "1", - "attack_level": "12" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "3715", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "3726", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Don't burst its bubble!", - "melee_animation": "3891", - "range_animation": "3891", - "combat_audio": "809,811,810", - "magic_level": "5", - "respawn_delay": "120", - "defence_animation": "3890", - "weakness": "8", - "magic_animation": "3891", - "death_animation": "3888", - "name": "Splatter", - "defence_level": "20", - "safespot": null, - "lifepoints": "13", - "strength_level": "20", - "id": "3727", - "bonuses": "5,10,10,10,10,2,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Don't burst its bubble!", - "melee_animation": "3891", - "range_animation": "3891", - "combat_audio": "809,811,810", - "magic_level": "10", - "respawn_delay": "120", - "defence_animation": "3890", - "magic_animation": "3891", - "death_animation": "3888", - "name": "Splatter", - "defence_level": "25", - "safespot": null, - "lifepoints": "23", - "strength_level": "25", - "id": "3728", - "bonuses": "10,15,15,15,15,5,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "Don't burst its bubble!", - "melee_animation": "3891", - "range_animation": "3891", - "combat_audio": "809,811,810", - "magic_level": "10", - "respawn_delay": "120", - "defence_animation": "3890", - "magic_animation": "3891", - "death_animation": "3888", - "name": "Splatter", - "defence_level": "30", - "safespot": null, - "lifepoints": "23", - "strength_level": "30", - "id": "3729", - "bonuses": "15,20,20,20,20,8,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Don't burst its bubble!", - "melee_animation": "3891", - "range_animation": "3891", - "combat_audio": "809,811,810", - "magic_level": "15", - "respawn_delay": "120", - "defence_animation": "3890", - "magic_animation": "3891", - "death_animation": "3888", - "name": "Splatter", - "defence_level": "35", - "safespot": null, - "lifepoints": "23", - "strength_level": "35", - "id": "3730", - "bonuses": "20,25,25,25,25,10,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Don't burst its bubble!", - "melee_animation": "3891", - "range_animation": "3891", - "combat_audio": "809,811,810", - "magic_level": "20", - "respawn_delay": "120", - "defence_animation": "3890", - "magic_animation": "3891", - "death_animation": "3888", - "name": "Splatter", - "defence_level": "40", - "safespot": null, - "lifepoints": "23", - "strength_level": "40", - "id": "3731", - "bonuses": "25,30,30,30,30,15,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "14", - "respawn_delay": "127", - "defence_animation": "3902", - "weakness": "9", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "28", - "poison_immune": "true", - "safespot": null, - "lifepoints": "23", - "strength_level": "28", - "id": "3732", - "aggressive": "true", - "bonuses": "20,25,20,40,40,40,40,5,18,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "14", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "28", - "poison_immune": "true", - "safespot": null, - "lifepoints": "23", - "strength_level": "28", - "id": "3733", - "aggressive": "true", - "bonuses": "20,25,20,40,40,40,40,5,18,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "20", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "42", - "poison_immune": "true", - "safespot": null, - "lifepoints": "38", - "strength_level": "42", - "id": "3734", - "aggressive": "true", - "bonuses": "30,35,30,50,50,50,50,10,15,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "20", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "42", - "poison_immune": "true", - "safespot": null, - "lifepoints": "38", - "strength_level": "42", - "id": "3735", - "aggressive": "true", - "bonuses": "30,35,30,50,50,50,50,10,15,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "25", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "54", - "poison_immune": "true", - "safespot": null, - "lifepoints": "53", - "strength_level": "54", - "id": "3736", - "aggressive": "true", - "bonuses": "35,40,35,60,60,60,60,20,15,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "25", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "54", - "poison_immune": "true", - "safespot": null, - "lifepoints": "53", - "strength_level": "54", - "id": "3737", - "aggressive": "true", - "bonuses": "35,40,35,60,60,60,60,20,15,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "30", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "60", - "poison_immune": "true", - "safespot": null, - "lifepoints": "68", - "strength_level": "60", - "id": "3738", - "aggressive": "true", - "bonuses": "40,50,40,70,70,70,70,30,15,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "30", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "60", - "poison_immune": "true", - "safespot": null, - "lifepoints": "68", - "strength_level": "60", - "id": "3739", - "aggressive": "true", - "bonuses": "40,50,40,70,70,70,70,30,15,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "35", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "83", - "strength_level": "70", - "id": "3740", - "aggressive": "true", - "bonuses": "50,60,50,80,70,90,80,35,14,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "Nippy little thing!", - "melee_animation": "3901", - "range_animation": "3901", - "combat_audio": "766,768,767", - "magic_level": "35", - "respawn_delay": "127", - "defence_animation": "3902", - "magic_animation": "3901", - "death_animation": "3903", - "name": "Shifter", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "83", - "strength_level": "70", - "id": "3741", - "aggressive": "true", - "bonuses": "50,60,50,80,70,90,80,35,14,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "Worse than termites!", - "melee_animation": "3915", - "range_animation": "3915", - "combat_audio": "714,716,715", - "attack_speed": "5", - "magic_level": "10", - "respawn_delay": "120", - "defence_animation": "3916", - "weakness": "7", - "magic_animation": "3915", - "death_animation": "3917", - "name": "Ravager", - "defence_level": "15", - "safespot": null, - "lifepoints": "23", - "strength_level": "30", - "id": "3742", - "bonuses": "45,45,45,45,50,5,45,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Worse than termites!", - "melee_animation": "3915", - "range_animation": "3915", - "combat_audio": "714,716,715", - "attack_speed": "5", - "magic_level": "15", - "respawn_delay": "120", - "defence_animation": "3916", - "magic_animation": "3915", - "death_animation": "3917", - "name": "Ravager", - "defence_level": "20", - "safespot": null, - "lifepoints": "38", - "strength_level": "40", - "id": "3743", - "bonuses": "45,45,45,45,50,5,55,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Worse than termites!", - "melee_animation": "3915", - "range_animation": "3915", - "combat_audio": "714,716,715", - "attack_speed": "5", - "magic_level": "20", - "respawn_delay": "120", - "defence_animation": "3916", - "magic_animation": "3915", - "death_animation": "3917", - "name": "Ravager", - "defence_level": "30", - "safespot": null, - "lifepoints": "53", - "strength_level": "60", - "id": "3744", - "bonuses": "45,55,55,55,50,10,45,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Worse than termites!", - "melee_animation": "3915", - "range_animation": "3915", - "combat_audio": "714,716,715", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "120", - "defence_animation": "3916", - "magic_animation": "3915", - "death_animation": "3917", - "name": "Ravager", - "defence_level": "45", - "safespot": null, - "lifepoints": "53", - "strength_level": "75", - "id": "3745", - "bonuses": "60,60,60,60,80,10,45,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Worse than termites!", - "melee_animation": "3915", - "range_animation": "3915", - "combat_audio": "714,716,715", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "120", - "defence_animation": "3916", - "magic_animation": "3915", - "death_animation": "3917", - "name": "Ravager", - "defence_level": "60", - "safespot": null, - "lifepoints": "53", - "strength_level": "80", - "id": "3746", - "bonuses": "65,70,70,70,90,20,56,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Eeewww!", - "melee_animation": "3908", - "range_animation": "3908", - "combat_audio": "805,807,806", - "magic_level": "10", - "respawn_delay": "125", - "defence_animation": "3909", - "weakness": "6", - "magic_animation": "3908", - "death_animation": "3910", - "name": "Spinner", - "defence_level": "20", - "safespot": null, - "lifepoints": "33", - "strength_level": "20", - "id": "3747", - "bonuses": "20,40,40,40,40,10,38,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Eeewww!", - "melee_animation": "3908", - "range_animation": "3908", - "combat_audio": "805,807,806", - "magic_level": "15", - "respawn_delay": "125", - "defence_animation": "3909", - "magic_animation": "3908", - "death_animation": "3910", - "name": "Spinner", - "defence_level": "30", - "safespot": null, - "lifepoints": "50", - "strength_level": "30", - "id": "3748", - "bonuses": "30,60,60,60,60,15,38,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Eeewww!", - "melee_animation": "3908", - "range_animation": "3908", - "combat_audio": "805,807,806", - "magic_level": "20", - "respawn_delay": "125", - "defence_animation": "3909", - "magic_animation": "3908", - "death_animation": "3910", - "name": "Spinner", - "defence_level": "40", - "safespot": null, - "lifepoints": "67", - "strength_level": "40", - "id": "3749", - "bonuses": "50,70,70,70,70,20,38,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Eeewww!", - "melee_animation": "3908", - "range_animation": "3908", - "combat_audio": "805,807,806", - "magic_level": "30", - "respawn_delay": "125", - "defence_animation": "3909", - "magic_animation": "3908", - "death_animation": "3910", - "name": "Spinner", - "defence_level": "60", - "safespot": null, - "lifepoints": "101", - "strength_level": "60", - "id": "3750", - "bonuses": "60,100,100,100,100,30,25,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Eeewww!", - "melee_animation": "3908", - "range_animation": "3908", - "combat_audio": "805,807,806", - "magic_level": "25", - "respawn_delay": "125", - "defence_animation": "3909", - "magic_animation": "3908", - "death_animation": "3910", - "name": "Spinner", - "defence_level": "50", - "safespot": null, - "lifepoints": "84", - "strength_level": "50", - "id": "3751", - "bonuses": "55,80,80,80,85,25,30,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "25", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "weakness": "5", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "25", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "3752", - "aggressive": "true", - "bonuses": "30,30,30,30,15,30,40,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "25", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "25", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "3753", - "aggressive": "true", - "bonuses": "30,30,30,30,15,30,40,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "40", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "40", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "3754", - "aggressive": "true", - "bonuses": "45,40,40,40,25,35,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "40", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "40", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "3755", - "aggressive": "true", - "bonuses": "45,40,40,40,25,35,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "50", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "50", - "safespot": null, - "lifepoints": "42", - "strength_level": "1", - "id": "3756", - "aggressive": "true", - "bonuses": "35,40,40,40,30,35,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "50", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "50", - "safespot": null, - "lifepoints": "42", - "strength_level": "1", - "id": "3757", - "aggressive": "true", - "bonuses": "35,40,40,40,30,35,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "60", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "60", - "safespot": null, - "lifepoints": "51", - "strength_level": "1", - "id": "3758", - "aggressive": "true", - "bonuses": "60,80,80,80,50,50,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "60", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "60", - "safespot": null, - "lifepoints": "51", - "strength_level": "1", - "id": "3759", - "aggressive": "true", - "bonuses": "60,80,80,80,50,50,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "70", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "70", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "3760", - "aggressive": "true", - "bonuses": "40,100,100,100,50,50,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Burn, baby, burn!", - "start_gfx": "646", - "combat_style": "2", - "melee_animation": "3882", - "range_animation": "3882", - "combat_audio": "845,848,846", - "magic_level": "70", - "respawn_delay": "120", - "end_gfx": "648", - "defence_animation": "3880", - "magic_animation": "3882", - "death_animation": "3881", - "name": "Torcher", - "defence_level": "70", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "3761", - "aggressive": "true", - "bonuses": "40,100,100,100,50,50,35,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "647", - "attack_level": "1" - }, - { - "examine": "Duck!", - "start_gfx": "657", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "30", - "respawn_delay": "120", - "defence_animation": "3921", - "weakness": "0", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "25", - "safespot": null, - "lifepoints": "27", - "strength_level": "1", - "id": "3762", - "aggressive": "true", - "bonuses": "20,40,40,40,40,40,40,40,0,0,0,0,0,0,0", - "range_level": "25", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "30", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "25", - "safespot": null, - "lifepoints": "27", - "strength_level": "1", - "id": "3763", - "aggressive": "true", - "bonuses": "20,40,40,40,40,40,40,40,0,0,0,0,0,0,0", - "range_level": "25", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "start_gfx": "657", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "40", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "1", - "id": "3764", - "aggressive": "true", - "bonuses": "30,50,60,60,60,60,40,40,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "40", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "40", - "safespot": null, - "lifepoints": "45", - "strength_level": "1", - "id": "3765", - "aggressive": "true", - "bonuses": "30,40,60,60,60,60,40,40,0,0,0,0,0,0,0", - "range_level": "40", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "start_gfx": "657", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "50", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "50", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "3766", - "aggressive": "true", - "bonuses": "35,65,70,70,70,70,40,40,0,0,0,0,0,0,0", - "range_level": "50", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "50", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "50", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "3767", - "aggressive": "true", - "bonuses": "35,65,70,70,70,70,40,40,0,0,0,0,0,0,0", - "range_level": "50", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "start_gfx": "657", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "60", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "60", - "safespot": null, - "lifepoints": "78", - "strength_level": "1", - "id": "3768", - "aggressive": "true", - "bonuses": "40,90,80,80,80,80,40,40,0,0,0,0,0,0,0", - "range_level": "60", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "60", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "60", - "safespot": null, - "lifepoints": "78", - "strength_level": "1", - "id": "3769", - "aggressive": "true", - "bonuses": "40,90,80,80,80,80,40,40,0,0,0,0,0,0,0", - "range_level": "60", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "start_gfx": "657", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "70", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "70", - "safespot": null, - "lifepoints": "97", - "strength_level": "1", - "id": "3770", - "aggressive": "true", - "bonuses": "50,100,100,100,120,100,40,40,80,0,0,0,0,0,0", - "range_level": "70", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Duck!", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "combat_audio": "392,394,393", - "magic_level": "70", - "respawn_delay": "120", - "defence_animation": "3921", - "magic_animation": "3920", - "death_animation": "3922", - "name": "Defiler", - "defence_level": "70", - "safespot": null, - "lifepoints": "97", - "strength_level": "1", - "id": "3771", - "aggressive": "true", - "bonuses": "50,100,100,100,120,100,40,40,80,0,0,0,0,0,0", - "range_level": "70", - "projectile": "657", - "attack_level": "1" - }, - { - "examine": "Mind your toes!", - "melee_animation": "3896", - "range_animation": "3896", - "combat_audio": "323,326,325", - "magic_level": "14", - "respawn_delay": "120", - "defence_animation": "3895", - "weakness": "9", - "magic_animation": "3896", - "death_animation": "3894", - "name": "Brawler", - "defence_level": "28", - "safespot": null, - "lifepoints": "53", - "strength_level": "28", - "id": "3772", - "aggressive": "true", - "bonuses": "45,45,50,50,50,50,50,15,50,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Mind your toes!", - "melee_animation": "3896", - "range_animation": "3896", - "combat_audio": "323,326,325", - "magic_level": "21", - "respawn_delay": "120", - "defence_animation": "3895", - "magic_animation": "3896", - "death_animation": "3894", - "name": "Brawler", - "defence_level": "42", - "safespot": null, - "lifepoints": "83", - "strength_level": "42", - "id": "3773", - "aggressive": "true", - "bonuses": "45,45,60,50,50,50,50,15,50,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "Mind your toes!", - "melee_animation": "3896", - "range_animation": "3896", - "combat_audio": "323,326,325", - "magic_level": "32", - "respawn_delay": "120", - "defence_animation": "3895", - "magic_animation": "3896", - "death_animation": "3894", - "name": "Brawler", - "defence_level": "56", - "safespot": null, - "lifepoints": "113", - "strength_level": "56", - "id": "3774", - "aggressive": "true", - "bonuses": "45,45,60,80,80,80,80,25,50,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "56" - }, - { - "examine": "Mind your toes!", - "melee_animation": "3896", - "range_animation": "3896", - "combat_audio": "323,326,325", - "magic_level": "38", - "respawn_delay": "120", - "defence_animation": "3895", - "magic_animation": "3896", - "death_animation": "3894", - "name": "Brawler", - "defence_level": "74", - "safespot": null, - "lifepoints": "143", - "strength_level": "74", - "id": "3775", - "aggressive": "true", - "bonuses": "45,45,60,60,60,60,60,20,50,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "74" - }, - { - "examine": "Mind your toes!", - "melee_animation": "3896", - "range_animation": "3896", - "combat_audio": "323,326,325", - "magic_level": "45", - "respawn_delay": "120", - "defence_animation": "3895", - "magic_animation": "3896", - "death_animation": "3894", - "name": "Brawler", - "defence_level": "88", - "safespot": null, - "lifepoints": "173", - "strength_level": "88", - "id": "3776", - "aggressive": "true", - "bonuses": "45,45,80,100,100,100,100,30,46,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "88" - }, - { - "examine": "Cheerful, helpful and optimistic, I'll bet.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Doomsayer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3777", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "attack_speed": "5", - "magic_level": "80", - "respawn_delay": "120", - "name": "Void Knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "3782", - "bonuses": "180,180,180,180,80,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Long legged licker.", - "melee_animation": "7260", - "range_animation": "0", - "poisonous": "true", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7256", - "name": "Frog", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "3783", - "range_level": "1", - "attack_level": "55" - }, - { - "name": "Void Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "attack_speed": "0", - "id": "3784", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "attack_speed": "5", - "magic_level": "80", - "respawn_delay": "120", - "name": "Void Knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "3785", - "bonuses": "180,180,180,180,80,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A powerful knight of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Void Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3786", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A powerful knight of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Void Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3788", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3790", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3791", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3792", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3793", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3794", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3795", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3796", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3797", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3798", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3799", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3800", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3801", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire (Novice)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3802", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Posts things.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Postie Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3805", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Miss Millicent Miller the Miller of Mill Lane Mill.", - "name": "Millie Miller", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3806", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Gillie the Milkmaid milks cows. She's udderly fantastic at it.", - "name": "Gillie Groats", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3807", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Massive beast of War with extra Gnome.", - "melee_animation": "3960", - "range_animation": "3954", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "3962", - "name": "Tortoise", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "3808", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "Tally Ho!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Dalbur", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3809", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Huzzah!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Bleemadge", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3810", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Up up and away!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Errdo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3811", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Up up and away!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Klemfoodle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3812", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Gnome Arrow-chucker", - "combat_style": "1", - "melee_animation": "190", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome Archer", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "1", - "id": "3814", - "aggressive": "true", - "range_level": "30", - "attack_level": "1" - }, - { - "examine": "Yee haa!", - "melee_animation": "3969", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome Driver", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "3815", - "aggressive": "true", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "A battle mage of the gnomish variety.", - "combat_style": "2", - "melee_animation": "3968", - "range_animation": "0", - "magic_level": "34", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "196", - "name": "Gnome Mage", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "1", - "id": "3816", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The cruel tortoise trainer. Boo!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trainer Nacklepen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3818", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A large tortoise.", - "melee_animation": "3960", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "3962", - "name": "Tortoise", - "defence_level": "36", - "safespot": null, - "lifepoints": "51", - "strength_level": "36", - "id": "3819", - "range_level": "1", - "attack_level": "36" - }, - { - "agg_radius": "64", - "melee_animation": "6241", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6240", - "death_animation": "6242", - "name": "Kalphite Queen", - "defence_level": "1", - "safespot": null, - "lifepoints": "255", - "strength_level": "1", - "id": "3835", - "aggressive": "true", - "range_level": "1000", - "attack_level": "1" - }, - { - "agg_radius": "64", - "melee_animation": "6234", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6237", - "death_animation": "6233", - "name": "Kalphite Queen", - "defence_level": "1", - "safespot": null, - "lifepoints": "255", - "strength_level": "1", - "id": "3836", - "aggressive": "true", - "range_level": "1000", - "attack_level": "1" - }, - { - "examine": "An aquatic troll.", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Sea troll", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "3840", - "aggressive": "true", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "An aquatic troll.", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Sea troll", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "3843", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "The mother of all sea trolls!", - "melee_animation": "3991", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "3993", - "name": "Sea Troll Queen", - "defence_level": "65", - "safespot": null, - "lifepoints": "428", - "strength_level": "65", - "id": "3847", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "What have they done to him?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishing spot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3849", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "7", - "strength_level": "1", - "id": "3915", - "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His bark's worse than his blight.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Carpenter Kjallak", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3916", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a bit seedy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer Fromund", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3917", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Snake", - "slayer_task": "72", - "melee_animation": "3538", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "3540", - "name": "Sea Snake Young", - "defence_level": "45", - "safespot": null, - "lifepoints": "128", - "strength_level": "33", - "id": "3939", - "aggressive": "true", - "range_level": "45", - "attack_level": "33" - }, - { - "examine": "A baby sea snake. Snaaaaaaake!", - "slayer_task": "72", - "melee_animation": "3538", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "3540", - "name": "Sea Snake Hatchling", - "defence_level": "45", - "safespot": null, - "lifepoints": "100", - "strength_level": "33", - "id": "3940", - "aggressive": "true", - "range_level": "45", - "attack_level": "33" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "3941", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's guarding the entrance to the dungeons.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "3942", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A big snake that lives in the sea. How did it get in here?", - "melee_animation": "4040", - "range_animation": "0", - "combat_audio": "3609,3608,3610", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "4039", - "name": "Giant Sea Snake", - "defence_level": "45", - "safespot": null, - "lifepoints": "385", - "strength_level": "33", - "id": "3943", - "aggressive": "true", - "range_level": "45", - "attack_level": "33" - }, - { - "slayer_exp": "37", - "name": "Cockatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4227", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "75", - "name": "Basilisk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "288,290,289", - "strength_level": "1", - "id": "4228", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Large, heavy, with sharp things attached to its head.", - "melee_animation": "9439", - "range_animation": "9439", - "combat_audio": "588,590,589", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "9441", - "slayer_exp": "97", - "magic_animation": "9439", - "death_animation": "9440", - "name": "Kurask", - "defence_level": "105", - "safespot": null, - "lifepoints": "97", - "strength_level": "105", - "id": "4229", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "67" - }, - { - "examine": "A denizen of the Abyss!", - "slayer_task": "1", - "melee_animation": "1537", - "range_animation": "1537", - "combat_audio": "276,278,277", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "0", - "weakness": "1", - "slayer_exp": "150", - "magic_animation": "1537", - "death_animation": "1538", - "name": "Abyssal demon", - "defence_level": "135", - "safespot": null, - "lifepoints": "150", - "strength_level": "67", - "id": "4230", - "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "97" - }, - { - "name": "Demon butler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "400,404,403", - "strength_level": "1", - "id": "4243", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Head of the servants' guild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chief servant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4245", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She smells unpleasantly of chemicals.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Taxidermist", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4246", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fancy businessman with a mighty fine hat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Estate agent", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4247", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Someone has to get rid of all the stone they dug Keldagrim out of.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Stonemason", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4248", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He changes the shape of wood.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "facing_booth": "true", - "magic_animation": "0", - "death_animation": "0", - "name": "Sawmill operator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4250", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She has green fingers. (Not literally.)", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Garden supplier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4251", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Beak areful with this one", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Macaroni Penguin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4252", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4257", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarven guard.", - "slayer_task": "29", - "melee_animation": "99", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "102", - "name": "Guard", - "defence_level": "12", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "4258", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "12" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4259", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4260", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4261", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4262", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4263", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4264", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4265", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4266", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4267", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4268", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4269", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4270", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4271", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4272", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4273", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4274", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4275", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4276", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Animated bronze armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Bronze Armour", - "defence_level": "10", - "safespot": null, - "poison_immune": "true", - "lifepoints": "10", - "strength_level": "10", - "id": "4278", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "10" - }, - { - "examine": "Animated iron armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Iron Armour", - "defence_level": "20", - "safespot": null, - "poison_immune": "true", - "lifepoints": "20", - "strength_level": "20", - "id": "4279", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Animated steel armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Steel Armour", - "defence_level": "40", - "safespot": null, - "poison_immune": "true", - "lifepoints": "40", - "strength_level": "40", - "id": "4280", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Animated black armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Black Armour", - "defence_level": "60", - "safespot": null, - "poison_immune": "true", - "lifepoints": "60", - "strength_level": "60", - "id": "4281", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Animated mithril armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Mithril Armour", - "defence_level": "80", - "safespot": null, - "poison_immune": "true", - "lifepoints": "80", - "strength_level": "80", - "id": "4282", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "Animated adamant armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Adamant Armour", - "defence_level": "99", - "safespot": null, - "poison_immune": "true", - "lifepoints": "99", - "strength_level": "99", - "id": "4283", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "99" - }, - { - "examine": "Animated rune armour.", - "melee_animation": "386", - "range_animation": "386", - "combat_audio": "2549,1979,512", - "attack_speed": "4", - "respawn_delay": "20", - "defence_animation": "388", - "weakness": "7", - "magic_animation": "386", - "death_animation": "4167", - "name": "Animated Rune Armour", - "defence_level": "120", - "safespot": null, - "poison_immune": "true", - "lifepoints": "120", - "strength_level": "120", - "id": "4284", - "aggressive": "true", - "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", - "range_level": "1", - "attack_level": "120" - }, - { - "examine": "The big door man.", - "name": "Ghommal", - "id": "4285" - }, - { - "examine": "Guild Master.", - "name": "Harrallak Menarous", - "id": "4286" - }, - { - "examine": "The guild engineer.", - "name": "Gamfred", - "id": "4287" - }, - { - "examine": "Used to be a black knight.", - "name": "Ajjat", - "id": "4288" - }, - { - "examine": "Blademistress, skillful female warrior.", - "name": "Kamfreena", - "id": "4289" - }, - { - "examine": "A warrior mage from the east.", - "name": "Shanomi", - "id": "4290" - }, - { - "examine": "A one-eyed man eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "8", - "slayer_exp": "75", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "26", - "safespot": null, - "lifepoints": "75", - "strength_level": "50", - "id": "4291", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "A one-eyed woman eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "1", - "slayer_exp": "100", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "35", - "safespot": null, - "lifepoints": "100", - "strength_level": "65", - "id": "4292", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "Food shopkeeper.", - "name": "Lidio", - "id": "4293" - }, - { - "examine": "Potion shopkeeper.", - "name": "Lilly", - "id": "4294" - }, - { - "examine": "Armour shopkeeper.", - "name": "Anton", - "id": "4295" - }, - { - "examine": "Bank staff.", - "name": "Jade", - "id": "4296" - }, - { - "examine": "He looks like a strong warrior.", - "name": "Sloane", - "id": "4297" - }, - { - "examine": "He looks a bit drunk.", - "name": "Jimmy", - "id": "4298" - }, - { - "examine": "He looks fair and reliable.", - "name": "Ref", - "id": "4299" - }, - { - "examine": "He looks fair and reliable.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ref", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4300", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4301", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4302", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4303", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4304", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4305", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4306", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard for the humans against monster group.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "4307", - "clue_level": "1", - "range_level": "1", - "attack_level": "26" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "4308", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "4309", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "4310", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "4311", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "16", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4316", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "H.A.M. Member", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4318", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "H.A.M. Member", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4320", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "H.A.M. Deacon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4329", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "395", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "4336", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Snake", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "3609,3608,3610", - "strength_level": "1", - "id": "4343", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "220", - "combat_audio": "629,631,630", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "221", - "death_animation": "223", - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "12", - "strength_level": "1", - "id": "4344", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's all white by me.", - "slayer_task": "5", - "melee_animation": "4915", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4917", - "name": "Albino bat", - "defence_level": "31", - "safespot": null, - "lifepoints": "44", - "strength_level": "31", - "id": "4345", - "range_level": "1", - "attack_level": "31" - }, - { - "examine": "A flying blood sucker.", - "melee_animation": "2397", - "range_animation": "0", - "attack_speed": "10", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "2398", - "name": "Giant mosquito", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "63", - "id": "4347", - "range_level": "1", - "attack_level": "63" - }, - { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "slayer_task": "52", - "melee_animation": "4235", - "range_animation": "0", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "7", - "slayer_exp": "45", - "magic_animation": "0", - "death_animation": "4233", - "name": "Jungle horror", - "defence_level": "55", - "safespot": null, - "lifepoints": "45", - "strength_level": "70", - "id": "4348", - "aggressive": "true", - "clue_level": "1", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A horrible, emaciated ape like creature with beady yellow eyes.", - "melee_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "4232", - "slayer_exp": "45", - "death_animation": "4233", - "name": "Jungle horror", - "defence_level": "55", - "safespot": null, - "lifepoints": "45", - "strength_level": "70", - "id": "4349", - "aggressive": "true", - "clue_level": "1", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A horrible, emaciated ape like creature with beady green eyes.", - "slayer_task": "52", - "melee_animation": "4235", - "range_animation": "0", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "7", - "slayer_exp": "45", - "magic_animation": "0", - "death_animation": "4233", - "name": "Jungle horror", - "defence_level": "55", - "safespot": null, - "lifepoints": "45", - "strength_level": "70", - "id": "4350", - "aggressive": "true", - "clue_level": "1", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A horrible, emaciated ape like creature with beady blue eyes.", - "melee_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "4232", - "slayer_exp": "45", - "death_animation": "4233", - "name": "Jungle horror", - "defence_level": "55", - "safespot": null, - "lifepoints": "45", - "strength_level": "70", - "id": "4351", - "aggressive": "true", - "clue_level": "1", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A horrible, emaciated ape like creature with beady pink eyes.", - "melee_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "4232", - "slayer_exp": "45", - "death_animation": "4233", - "name": "Jungle horror", - "defence_level": "55", - "safespot": null, - "lifepoints": "45", - "strength_level": "70", - "id": "4352", - "aggressive": "true", - "clue_level": "1", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "slayer_task": "17", - "melee_animation": "4234", - "range_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "80", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "6", - "slayer_exp": "55", - "magic_animation": "4234", - "death_animation": "4233", - "name": "Cave horror", - "defence_level": "62", - "safespot": null, - "lifepoints": "55", - "strength_level": "77", - "id": "4353", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "slayer_task": "17", - "melee_animation": "4234", - "range_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "80", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "6", - "slayer_exp": "55", - "magic_animation": "4234", - "death_animation": "4233", - "name": "Cave horror", - "defence_level": "62", - "safespot": null, - "lifepoints": "55", - "strength_level": "77", - "id": "4354", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "slayer_task": "17", - "melee_animation": "4234", - "range_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "80", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "6", - "slayer_exp": "55", - "magic_animation": "4234", - "death_animation": "4233", - "name": "Cave horror", - "defence_level": "62", - "safespot": null, - "lifepoints": "55", - "strength_level": "77", - "id": "4355", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "slayer_task": "17", - "melee_animation": "4234", - "range_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "80", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "6", - "slayer_exp": "55", - "magic_animation": "4234", - "death_animation": "4233", - "name": "Cave horror", - "defence_level": "62", - "safespot": null, - "lifepoints": "55", - "strength_level": "77", - "id": "4356", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "A horrible, emaciated ape like creature with beady red eyes.", - "slayer_task": "17", - "melee_animation": "4234", - "range_animation": "4234", - "combat_audio": "496,500,499", - "attack_speed": "4", - "magic_level": "80", - "respawn_delay": "50", - "defence_animation": "4232", - "weakness": "6", - "slayer_exp": "55", - "magic_animation": "4234", - "death_animation": "4233", - "name": "Cave horror", - "defence_level": "62", - "safespot": null, - "lifepoints": "55", - "strength_level": "77", - "id": "4357", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "Patchy the pirate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Patchy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4359", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very flamboyant pirate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fancy Dan", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4361", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I can't wait to buy from a guy with Honest in his name...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Honest Jimmy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4362", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "4363", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Blue Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "4371", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Red Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "4372", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A colourful bird.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Parrot", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4373", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A retired Gielinor security guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Security Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4375", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A boney ghost.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "924,926,925", - "attack_speed": "4", - "defence_animation": "404", - "slayer_exp": "60", - "magic_animation": "422", - "death_animation": "9055", - "name": "Ankou", - "defence_level": "50", - "safespot": null, - "lifepoints": "60", - "strength_level": "69", - "id": "4381", - "aggressive": "true", - "clue_level": "2", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A boney ghost.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "924,926,925", - "attack_speed": "4", - "defence_animation": "404", - "slayer_exp": "60", - "magic_animation": "422", - "death_animation": "9055", - "name": "Ankou", - "defence_level": "50", - "safespot": null, - "lifepoints": "66", - "strength_level": "69", - "id": "4382", - "aggressive": "true", - "clue_level": "2", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A boney ghost.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "924,926,925", - "attack_speed": "4", - "defence_animation": "404", - "slayer_exp": "60", - "magic_animation": "422", - "death_animation": "9055", - "name": "Ankou", - "defence_level": "55", - "safespot": null, - "lifepoints": "66", - "strength_level": "74", - "id": "4383", - "aggressive": "true", - "clue_level": "2", - "range_level": "1", - "attack_level": "60" - }, - { - "melee_animation": "5540", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5541", - "slayer_exp": "25", - "death_animation": "5542", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "36", - "strength_level": "1", - "id": "4387", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "1", - "id": "4388", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I don't think insect repellent will work.", - "slayer_task": "34", - "melee_animation": "1184", - "range_animation": "1184", - "combat_audio": "571,573,572", - "attack_speed": "3", - "respawn_delay": "30", - "defence_animation": "1186", - "weakness": "0", - "slayer_exp": "25", - "magic_animation": "1184", - "death_animation": "1190", - "name": "Flesh Crawler", - "defence_level": "10", - "safespot": null, - "lifepoints": "25", - "strength_level": "2", - "id": "4389", - "aggressive": "true", - "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "I don't think insect repellent will work.", - "melee_animation": "1184", - "range_animation": "1184", - "combat_audio": "571,573,572", - "attack_speed": "3", - "respawn_delay": "30", - "defence_animation": "1186", - "slayer_exp": "25", - "magic_animation": "1184", - "death_animation": "1190", - "name": "Flesh Crawler", - "defence_level": "10", - "safespot": null, - "lifepoints": "25", - "strength_level": "2", - "id": "4390", - "aggressive": "true", - "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "I don't think insect repellent will work.", - "melee_animation": "1184", - "range_animation": "1184", - "combat_audio": "571,573,572", - "attack_speed": "3", - "respawn_delay": "30", - "defence_animation": "1186", - "slayer_exp": "25", - "magic_animation": "1184", - "death_animation": "1190", - "name": "Flesh Crawler", - "defence_level": "10", - "safespot": null, - "lifepoints": "25", - "strength_level": "2", - "id": "4391", - "aggressive": "true", - "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5568", - "range_animation": "5568", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5567", - "slayer_exp": "30", - "magic_animation": "5568", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "25", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "4392", - "aggressive": "true", - "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "28", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "4393", - "aggressive": "true", - "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "48", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "4394", - "aggressive": "true", - "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "combat_audio": "703,705,704", - "melee_animation": "4933", - "attack_speed": "5", - "defence_animation": "4934", - "weakness": "9", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "23", - "safespot": null, - "lifepoints": "26", - "strength_level": "20", - "id": "4395", - "aggressive": "true", - "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", - "range_level": "1", - "attack_level": "21" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "710,713,711", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "4396", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Big Cow-like... But cows don't have serpent tails!", - "melee_animation": "4271", - "combat_audio": "511,330,329", - "attack_speed": "5", - "magic_level": "38", - "spell_id": "7", - "respawn_delay": "74", - "defence_animation": "4273", - "slayer_exp": "50", - "magic_animation": "4272", - "death_animation": "4270", - "name": "Catablepon", - "defence_level": "38", - "safespot": null, - "lifepoints": "50", - "strength_level": "38", - "id": "4397", - "aggressive": "true", - "bonuses": "5,20,15,3,10,20,10,10,20,15,23,25,15,25,10", - "clue_level": "1", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "Big Cow-like... But cows don't have serpent tails!", - "melee_animation": "4271", - "combat_audio": "511,330,329", - "attack_speed": "5", - "magic_level": "38", - "spell_id": "7", - "respawn_delay": "74", - "defence_animation": "4273", - "slayer_exp": "50", - "magic_animation": "4272", - "death_animation": "4270", - "name": "Catablepon", - "defence_level": "38", - "safespot": null, - "lifepoints": "70", - "strength_level": "38", - "id": "4398", - "aggressive": "true", - "bonuses": "20,25,10,20,25,10,10,11,0,0,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "Big Cow-like... But cows don't have serpent tails!", - "melee_animation": "4271", - "combat_audio": "511,330,329", - "attack_speed": "5", - "magic_level": "45", - "spell_id": "7", - "respawn_delay": "74", - "defence_animation": "4273", - "slayer_exp": "50", - "magic_animation": "4272", - "death_animation": "4270", - "name": "Catablepon", - "defence_level": "38", - "safespot": null, - "lifepoints": "50", - "strength_level": "58", - "id": "4399", - "aggressive": "true", - "bonuses": "50,45,50,40,45,20,30,25,33,25,25,20,20,40,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "I think this spider has been genetically modified.", - "melee_animation": "5327", - "range_animation": "5327", - "combat_audio": "537,539,538", - "defence_animation": "5328", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Giant spider", - "defence_level": "51", - "safespot": null, - "lifepoints": "50", - "strength_level": "45", - "id": "4400", - "aggressive": "true", - "bonuses": "19,21,19,62,45,51,54,63,60,18,0,0,0,0,0", - "range_level": "1", - "attack_level": "48" - }, - { - "melee_animation": "6249", - "combat_audio": "3604,3609,3608", - "respawn_delay": "60", - "defence_animation": "6250", - "death_animation": "6251", - "name": "Spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "4401", - "aggressive": "false", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An extremely vicious scorpion.", - "melee_animation": "6254", - "range_animation": "6254", - "combat_audio": "3611,3612,3610", - "attack_speed": "5", - "defence_animation": "6255", - "slayer_exp": "17", - "magic_animation": "6254", - "death_animation": "6256", - "name": "Scorpion", - "defence_level": "49", - "safespot": null, - "lifepoints": "55", - "strength_level": "51", - "id": "4402", - "aggressive": "true", - "bonuses": "12,23,10,51,32,62,29,54,48,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "An extremely vicious scorpion.", - "melee_animation": "6254", - "range_animation": "6254", - "combat_audio": "3611,3612,3610", - "attack_speed": "5", - "defence_animation": "6255", - "slayer_exp": "17", - "magic_animation": "6254", - "death_animation": "6256", - "name": "Scorpion", - "defence_level": "35", - "safespot": null, - "lifepoints": "37", - "strength_level": "31", - "id": "4403", - "aggressive": "true", - "bonuses": "15,16,12,32,19,38,18,34,32,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "He doesn't look very pleased to see you.", - "slayer_task": "58", - "melee_animation": "4266", - "range_animation": "4266", - "combat_audio": "626,628,627", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "4267", - "weakness": "7", - "slayer_exp": "10", - "magic_animation": "4266", - "death_animation": "4265", - "name": "Minotaur", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "10", - "id": "4404", - "aggressive": "false", - "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "He doesn't look very pleased to see you.", - "melee_animation": "4266", - "range_animation": "4266", - "combat_audio": "626,628,627", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "4267", - "magic_animation": "4266", - "death_animation": "4265", - "name": "Minotaur", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "10", - "id": "4405", - "aggressive": "false", - "bonuses": "11,11,13,11,11,13,11,11,11,13,11,11,11,11,11", - "clue_level": "0", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "He doesn't look very pleased to see you.", - "melee_animation": "4266", - "range_animation": "4266", - "combat_audio": "626,628,627", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "15", - "defence_animation": "4267", - "slayer_exp": "22", - "magic_animation": "4266", - "death_animation": "4265", - "name": "Minotaur", - "defence_level": "25", - "safespot": null, - "lifepoints": "22", - "strength_level": "25", - "id": "4406", - "aggressive": "false", - "bonuses": "0,0,0,0,0,-10,-10,-10,21,-10,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "3520,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "5", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4407", - "bonuses": "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "3520,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "16", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "11", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4408", - "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "3520,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "7", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "9", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4409", - "bonuses": "6,6,6,6,6,6,6,6,6,6,6,6,6,6,6", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "3520,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4410", - "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "3520,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "17", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4411", - "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "3520,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "10", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4412", - "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "They say inside you there are two wolves...", - "melee_animation": "6559", - "range_animation": "6559", - "combat_audio": "481,491,490", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "6557", - "slayer_exp": "15", - "magic_animation": "6559", - "death_animation": "6558", - "name": "Wolf", - "defence_level": "9", - "safespot": null, - "lifepoints": "15", - "strength_level": "1", - "id": "4413", - "bonuses": "7,7,7,7,7,7,7,7,7,7,7,7,7,7,7", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "They say inside you there are two wolves...", - "melee_animation": "6559", - "range_animation": "6559", - "combat_audio": "481,491,490", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "6557", - "slayer_exp": "10", - "magic_animation": "6559", - "death_animation": "6558", - "name": "Wolf", - "defence_level": "7", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4414", - "bonuses": "5,5,5,5,5,5,5,5,5,5,5,5,5,5,5", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "slayer_task": "67", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "710,713,711", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "3", - "defence_animation": "2706", - "slayer_exp": "2", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "4415", - "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,-42,-53,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "4300", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4301", - "slayer_exp": "112", - "death_animation": "4302", - "name": "Gorak", - "defence_level": "1", - "safespot": null, - "lifepoints": "112", - "strength_level": "1", - "id": "4418", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A highly enlightened being.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cosmic Being", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4419", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A healing fairy.", - "name": "Fairy Nuff", - "id": "4434" - }, - { - "examine": "Horseplay.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Centaur", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4438", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Horseplay.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Centaur", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4439", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A noble creature!", - "melee_animation": "6376", - "range_animation": "0", - "combat_audio": "812,814,813", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "90", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6377", - "name": "Stag", - "defence_level": "13", - "safespot": null, - "lifepoints": "19", - "strength_level": "13", - "id": "4440", - "aggressive": "false", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "Twiggy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wood Dryad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4441", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Fairy ring maintenance division.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy Fixit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4455", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He works in the bank.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ork", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4457", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She works in the bank.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ork", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4458", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She works in the bank.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ork", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4459", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very angry nymph.", - "melee_animation": "94", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "97", - "name": "Tree spirit", - "defence_level": "9", - "safespot": null, - "lifepoints": "12", - "strength_level": "9", - "id": "4470", - "aggressive": "true", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "A magic training dummy", - "melee_animation": "94", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "97", - "name": "Magic dummy", - "defence_level": "1", - "safespot": null, - "lifepoints": "15", - "strength_level": "1", - "id": "4474", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Who's your mummy?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guardian mummy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4476", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4479", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4480", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4481", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4482", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4483", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4484", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4485", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4486", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4487", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4488", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4489", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4490", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4491", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4492", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "General Wartface", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4494", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ugly green creature.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "attack_speed": "5", - "defence_animation": "6183", - "slayer_exp": "5", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "4499", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is he real or is it just my imagination?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Man", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4501", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Does she really exist?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Lady", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4502", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He reminds me of my old mathematics teacher.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Numerator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4503", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The master of accomplishment.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Expert", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4504", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He knows what is possible.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Perceptive", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4505", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He knows the past, present and future. But what of my shoe size?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Guide", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4506", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Luck is probably on his side.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ethereal Fluke", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4507", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's like looking in the mirror.", - "melee_animation": "414", - "range_animation": "0", - "magic_level": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Me", - "defence_level": "60", - "safespot": null, - "lifepoints": "171", - "strength_level": "60", - "id": "4509", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "It's like looking in the mirror.", - "melee_animation": "414", - "range_animation": "0", - "magic_level": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Me", - "defence_level": "60", - "safespot": null, - "lifepoints": "171", - "strength_level": "60", - "id": "4510", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Spiritual leader of the Moonclan.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Oneiromancer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4511", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The craziest house I ever did see!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "House", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4512", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "How does it see where to sweep?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Enchanted Broom", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4521", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I'm not sure if it's actually doing anything of use.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Enchanted Bucket", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4524", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4384", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4529", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4385", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4530", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4385", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4531", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,70,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4384", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4533", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "His beard seems to have a life of its own.", - "slayer_task": "62", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "449,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4665", - "weakness": "1", - "slayer_exp": "85", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "30", - "safespot": null, - "lifepoints": "85", - "strength_level": "30", - "id": "4534", - "aggressive": "true", - "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Either a very fremennikey pirate, or a very piratey fremnnik.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lokar Searunner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4537", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I always wondered what that job description actually meant...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cabin boy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4539", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The High Priest has been transformed into an avatar of Bandos.", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Bentley", - "defence_level": "55", - "safespot": null, - "lifepoints": "214", - "strength_level": "55", - "id": "4540", - "aggressive": "true", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "A stickler for hygiene in the kitchen.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Beefy' Burns", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4541", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A keen-eyed lookout with a telescope.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Eagle-eye' Shultz", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4542", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "First mate to Captain Bentley.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "First mate 'Davey-boy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4543", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A pirate through and through.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Picarron' Pete", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4545", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Jake", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "melee_animation": "422", - "strength_level": "1", - "id": "4546", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "He got his name from his favourite hobby. Reading about beds.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bedread the bold", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4547", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Wilson", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "melee_animation": "395", - "strength_level": "1", - "id": "4548", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "examine": "Nobody really knows why he's called Tommy 2-times...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tommy 2-times", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4549", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Don't look him straight in the eyes. He'll eat you alive!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Murky Pat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4550", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Nice beard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jack Sails", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4551", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is he looking at me?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Beedy-eye' Jones", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4554", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yes", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jenny Blade", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4555", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A low-down", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Lecherous' Lee", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4556", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Apparently his nickname comes from his fondness for jam.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Sticky' Sanders", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4557", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This person is working on the site.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Digsite workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4564", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This person is working on the site.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Digsite workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4565", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Upon examining the examiner you examine it is indeed an examiner!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Examiner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4566", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Upon examining the examiner you examine it is indeed an examiner!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Examiner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4567", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Must be hard at work.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Researcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4568", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He makes pots.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Generic Diplomat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4579", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's very diplomatic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ambassador Gimblewap", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4580", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Peaceful man!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ambassador Spanfipple", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4581", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Peaceful man!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ambassador Ferrnook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4582", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Your common man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sorrn", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4589", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Your common woman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mimm", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4590", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Your common man.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Portobello", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4593", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome pilot off duty", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Ninto", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4594", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome pilot off duty", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Daerkin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4595", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks alert and ready for action.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard Vemmeldo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4600", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A generic evil henchman.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Fortress Guard", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "4603", - "range_level": "1", - "attack_level": "26" - }, - { - "examine": "A generic evil henchman.", - "melee_animation": "428", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Fortress Guard", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "4604", - "range_level": "1", - "attack_level": "26" - }, - { - "examine": "A generic evil henchman.", - "melee_animation": "428", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Fortress Guard", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "4605", - "range_level": "1", - "attack_level": "26" - }, - { - "examine": "A generic evil henchman.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Fortress Guard", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "26", - "id": "4606", - "range_level": "1", - "attack_level": "26" - }, - { - "examine": "A witch's black cat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Black Cat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4607", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4608", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Swine.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Saboteur", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4611", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What is that thing!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "0", - "name": "Evil creature", - "defence_level": "1", - "safespot": null, - "lifepoints": "0", - "strength_level": "1", - "id": "4615", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "4633", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "4634", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "4635", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "4636", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "4637", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A little warrior.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4638", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A little warrior.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4639", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A little warrior.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4640", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A little warrior.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4641", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A little warrior.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gnome soldier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4642", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "King Healthorg riding his War Tortoise.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Healthorg and tortoise", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4643", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A weasly, shifty-looking Gnome Mage.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Glouphrie the Untrusted", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4645", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "With the prices he charges, no wonder he can afford to look so sharp.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Stan", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4650", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks very stylish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Crewmember", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4651", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "That suit looks a little briny around the edges.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Crewmember", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4652", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "First storm he is in that hat will blow away.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Crewmember", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4653", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She'll never be able to climb rigging in that.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Crewmember", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4654", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "High heels on a ship? What is she thinking?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Crewmember", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4655", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The effect is sort of spoiled by all those tattoos.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Crewmember", - "defence_level": "1", - "movement_radius": "710", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4656", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He works evil magic.", - "start_gfx": "93", - "combat_style": "2", - "melee_animation": "810", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "6", - "end_gfx": "95", - "respawn_delay": "60", - "defence_animation": "425", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "5", - "safespot": null, - "lifepoints": "12", - "strength_level": "2", - "id": "4659", - "aggressive": "true", - "range_level": "1", - "projectile": "94", - "attack_level": "5" - }, - { - "examine": "He works evil magic.", - "start_gfx": "96", - "combat_style": "2", - "melee_animation": "810", - "range_animation": "0", - "combat_audio": "511,513,512", - "magic_level": "22", - "end_gfx": "98", - "respawn_delay": "60", - "defence_animation": "425", - "magic_animation": "711", - "death_animation": "836", - "name": "Dark wizard", - "defence_level": "14", - "safespot": null, - "lifepoints": "24", - "strength_level": "17", - "id": "4660", - "aggressive": "true", - "range_level": "1", - "projectile": "97", - "attack_level": "17" - }, - { - "examine": "He works evil magic.", - "combat_style": "2", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "15", - "respawn_delay": "20", - "defence_animation": "404", - "magic_animation": "711", - "death_animation": "9055", - "name": "Dark wizard", - "defence_level": "15", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "4661", - "aggressive": "true", - "range_level": "1", - "projectile": "98", - "attack_level": "1" - }, - { - "examine": "Young but still dangerous.", - "slayer_task": "11", - "melee_animation": "25", - "range_animation": "25", - "combat_audio": "405,407,406", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "26", - "weakness": "3", - "slayer_exp": "50", - "magic_animation": "25", - "death_animation": "28", - "name": "Baby blue dragon", - "defence_level": "40", - "safespot": null, - "lifepoints": "50", - "strength_level": "40", - "id": "4665", - "aggressive": "true", - "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Young but still dangerous.", - "slayer_task": "11", - "combat_audio": "405,407,406", - "melee_animation": "25", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "26", - "slayer_exp": "50", - "weakness": "3", - "magic_animation": "25", - "death_animation": "28", - "name": "Baby blue dragon", - "defence_level": "40", - "safespot": null, - "lifepoints": "50", - "strength_level": "40", - "id": "4666", - "aggressive": "true", - "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Young but still dangerous.", - "name": "Baby red dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "combat_audio": "405,407,406", - "strength_level": "1", - "id": "4667", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Young but still dangerous.", - "name": "Baby red dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "combat_audio": "405,407,406", - "strength_level": "1", - "id": "4668", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A big powerful dragon.", - "slayer_task": "68", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "143", - "magic_animation": "80", - "death_animation": "92", - "name": "Red dragon", - "defence_level": "130", - "safespot": null, - "lifepoints": "140", - "strength_level": "130", - "id": "4669", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "A big powerful dragon.", - "slayer_task": "68", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "143", - "magic_animation": "80", - "death_animation": "92", - "name": "Red dragon", - "defence_level": "130", - "safespot": null, - "lifepoints": "140", - "strength_level": "130", - "id": "4670", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "A big powerful dragon.", - "slayer_task": "68", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "143", - "magic_animation": "80", - "death_animation": "92", - "name": "Red dragon", - "defence_level": "130", - "safespot": null, - "lifepoints": "140", - "strength_level": "130", - "id": "4671", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "A big powerful dragon.", - "slayer_task": "68", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "143", - "magic_animation": "80", - "death_animation": "92", - "name": "Red dragon", - "defence_level": "130", - "safespot": null, - "lifepoints": "140", - "strength_level": "130", - "id": "4672", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "A fierce dragon with black scales!", - "slayer_task": "9", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "200", - "magic_animation": "80", - "death_animation": "92", - "name": "Black dragon", - "defence_level": "200", - "safespot": null, - "lifepoints": "190", - "strength_level": "200", - "id": "4673", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "200" - }, - { - "examine": "A fierce dragon with black scales!", - "slayer_task": "9", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "200", - "magic_animation": "80", - "death_animation": "92", - "name": "Black dragon", - "defence_level": "200", - "safespot": null, - "lifepoints": "190", - "strength_level": "200", - "id": "4674", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "200" - }, - { - "examine": "A fierce dragon with black scales!", - "slayer_task": "9", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "200", - "magic_animation": "80", - "death_animation": "92", - "name": "Black dragon", - "defence_level": "200", - "safespot": null, - "lifepoints": "190", - "strength_level": "200", - "id": "4675", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "200" - }, - { - "examine": "A fierce dragon with black scales!", - "slayer_task": "9", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "100", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "200", - "magic_animation": "80", - "death_animation": "92", - "name": "Black dragon", - "defence_level": "200", - "safespot": null, - "lifepoints": "190", - "strength_level": "200", - "id": "4676", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "200" - }, - { - "examine": "Must be related to Elvarg.", - "slayer_task": "41", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "68", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "75", - "magic_animation": "80", - "death_animation": "92", - "name": "Green dragon", - "defence_level": "68", - "safespot": null, - "lifepoints": "75", - "strength_level": "68", - "id": "4677", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Must be related to Elvarg.", - "slayer_task": "41", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "68", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "75", - "magic_animation": "80", - "death_animation": "92", - "name": "Green dragon", - "defence_level": "68", - "safespot": null, - "lifepoints": "75", - "strength_level": "68", - "id": "4678", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Must be related to Elvarg.", - "slayer_task": "41", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "68", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "75", - "magic_animation": "80", - "death_animation": "92", - "name": "Green dragon", - "defence_level": "68", - "safespot": null, - "lifepoints": "75", - "strength_level": "68", - "id": "4679", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Must be related to Elvarg.", - "slayer_task": "41", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "68", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "75", - "magic_animation": "80", - "death_animation": "92", - "name": "Green dragon", - "defence_level": "68", - "safespot": null, - "lifepoints": "75", - "strength_level": "68", - "id": "4680", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "A mother dragon.", - "slayer_task": "11", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "108", - "magic_animation": "80", - "death_animation": "92", - "name": "Blue dragon", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4681", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "A mother dragon.", - "slayer_task": "11", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "108", - "magic_animation": "80", - "death_animation": "92", - "name": "Blue dragon", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4682", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "A mother dragon.", - "slayer_task": "11", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "108", - "magic_animation": "80", - "death_animation": "92", - "name": "Blue dragon", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4683", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "A mother dragon.", - "slayer_task": "11", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "108", - "magic_animation": "80", - "death_animation": "92", - "name": "Blue dragon", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4684", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "He's got icicles in his beard.", - "slayer_task": "47", - "melee_animation": "4672", - "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "70", - "magic_animation": "0", - "death_animation": "4673", - "name": "Ice giant", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "40", - "id": "4685", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "He's got icicles in his beard.", - "slayer_task": "47", - "melee_animation": "4672", - "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "70", - "magic_animation": "0", - "death_animation": "4673", - "name": "Ice giant", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "40", - "id": "4686", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "He's got icicles in his beard.", - "slayer_task": "47", - "melee_animation": "4672", - "range_animation": "0", - "combat_audio": "448,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "70", - "magic_animation": "0", - "death_animation": "4673", - "name": "Ice giant", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "40", - "id": "4687", - "aggressive": "true", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "His beard seems to have a life of its own.", - "slayer_task": "62", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "449,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4665", - "weakness": "1", - "slayer_exp": "60", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "30", - "safespot": null, - "lifepoints": "60", - "strength_level": "30", - "id": "4688", - "aggressive": "true", - "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A very large foe.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "4652", - "combat_audio": "448,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "6", - "slayer_exp": "35", - "magic_animation": "4652", - "death_animation": "4653", - "name": "Hill Giant", - "defence_level": "26", - "safespot": null, - "lifepoints": "35", - "strength_level": "22", - "id": "4689", - "aggressive": "true", - "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "A very large foe.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "4652", - "combat_audio": "448,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "6", - "slayer_exp": "35", - "magic_animation": "4652", - "death_animation": "4653", - "name": "Hill Giant", - "defence_level": "26", - "safespot": null, - "lifepoints": "35", - "strength_level": "22", - "id": "4690", - "aggressive": "true", - "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "A very large foe.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "4652", - "combat_audio": "448,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "6", - "slayer_exp": "35", - "magic_animation": "4652", - "death_animation": "4653", - "name": "Hill Giant", - "defence_level": "26", - "safespot": null, - "lifepoints": "35", - "strength_level": "22", - "id": "4691", - "aggressive": "true", - "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "A very large foe.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "4652", - "combat_audio": "448,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "6", - "slayer_exp": "35", - "magic_animation": "4652", - "death_animation": "4653", - "name": "Hill Giant", - "defence_level": "26", - "safespot": null, - "lifepoints": "35", - "strength_level": "22", - "id": "4692", - "aggressive": "true", - "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "A very large foe.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "4652", - "combat_audio": "448,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4651", - "weakness": "6", - "slayer_exp": "35", - "magic_animation": "4652", - "death_animation": "4653", - "name": "Hill Giant", - "defence_level": "26", - "safespot": null, - "lifepoints": "35", - "strength_level": "22", - "id": "4693", - "aggressive": "true", - "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "Lesser, but still pretty big.", - "slayer_task": "56", - "melee_animation": "4630", - "range_animation": "4630", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "79", - "magic_animation": "4630", - "death_animation": "67", - "name": "Lesser demon", - "defence_level": "71", - "safespot": null, - "lifepoints": "79", - "strength_level": "70", - "id": "4694", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Lesser, but still pretty big.", - "slayer_task": "56", - "melee_animation": "4630", - "range_animation": "4630", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "79", - "magic_animation": "4630", - "death_animation": "67", - "name": "Lesser demon", - "defence_level": "71", - "safespot": null, - "lifepoints": "79", - "strength_level": "70", - "id": "4695", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Lesser, but still pretty big.", - "slayer_task": "56", - "melee_animation": "4630", - "range_animation": "4630", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "79", - "magic_animation": "4630", - "death_animation": "67", - "name": "Lesser demon", - "defence_level": "71", - "safespot": null, - "lifepoints": "79", - "strength_level": "70", - "id": "4696", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Lesser, but still pretty big.", - "slayer_task": "56", - "melee_animation": "4630", - "range_animation": "4630", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "79", - "magic_animation": "4630", - "death_animation": "67", - "name": "Lesser demon", - "defence_level": "71", - "safespot": null, - "lifepoints": "79", - "strength_level": "70", - "id": "4697", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Big, red, and incredibly evil.", - "slayer_task": "40", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "400,404,403", - "attack_speed": "5", - "magic_level": "59", - "respawn_delay": "32", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "87", - "magic_animation": "64", - "death_animation": "68", - "name": "Greater demon", - "defence_level": "59", - "safespot": null, - "lifepoints": "87", - "strength_level": "59", - "id": "4698", - "aggressive": "true", - "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", - "clue_level": "2", - "range_level": "59", - "attack_level": "59" - }, - { - "examine": "Big, red, and incredibly evil.", - "slayer_task": "40", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "400,404,403", - "attack_speed": "5", - "magic_level": "59", - "respawn_delay": "32", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "87", - "magic_animation": "64", - "death_animation": "68", - "name": "Greater demon", - "defence_level": "59", - "safespot": null, - "lifepoints": "87", - "strength_level": "59", - "id": "4699", - "aggressive": "true", - "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", - "clue_level": "2", - "range_level": "59", - "attack_level": "59" - }, - { - "examine": "Big, red, and incredibly evil.", - "slayer_task": "40", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "400,404,403", - "attack_speed": "5", - "magic_level": "59", - "respawn_delay": "32", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "87", - "magic_animation": "64", - "death_animation": "68", - "name": "Greater demon", - "defence_level": "59", - "safespot": null, - "lifepoints": "87", - "strength_level": "59", - "id": "4700", - "aggressive": "true", - "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", - "clue_level": "2", - "range_level": "59", - "attack_level": "59" - }, - { - "examine": "Big, red, and incredibly evil.", - "slayer_task": "40", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "400,404,403", - "attack_speed": "5", - "magic_level": "59", - "respawn_delay": "32", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "87", - "magic_animation": "64", - "death_animation": "68", - "name": "Greater demon", - "defence_level": "59", - "safespot": null, - "lifepoints": "87", - "strength_level": "59", - "id": "4701", - "aggressive": "true", - "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", - "clue_level": "2", - "range_level": "59", - "attack_level": "59" - }, - { - "examine": "A big, scary, jet-black demon.", - "slayer_task": "8", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "397,399,398", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "157", - "magic_animation": "64", - "death_animation": "67", - "name": "Black demon", - "defence_level": "152", - "safespot": null, - "lifepoints": "157", - "strength_level": "148", - "id": "4702", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "145" - }, - { - "examine": "A big, scary, jet-black demon.", - "slayer_task": "8", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "397,399,398", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "157", - "magic_animation": "64", - "death_animation": "67", - "name": "Black demon", - "defence_level": "152", - "safespot": null, - "lifepoints": "157", - "strength_level": "148", - "id": "4703", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "145" - }, - { - "examine": "A big, scary, jet-black demon.", - "slayer_task": "8", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "397,399,398", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "157", - "magic_animation": "64", - "death_animation": "67", - "name": "Black demon", - "defence_level": "152", - "safespot": null, - "lifepoints": "157", - "strength_level": "148", - "id": "4704", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "145" - }, - { - "examine": "A big, scary, jet-black demon.", - "slayer_task": "8", - "melee_animation": "64", - "range_animation": "64", - "combat_audio": "397,399,398", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "157", - "magic_animation": "64", - "death_animation": "67", - "name": "Black demon", - "defence_level": "152", - "safespot": null, - "lifepoints": "157", - "strength_level": "148", - "id": "4705", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "145" - }, - { - "examine": "His beard seems to have a life of its own.", - "slayer_task": "62", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "449,451,450", - "attack_speed": "6", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4665", - "weakness": "1", - "slayer_exp": "85", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Moss giant", - "defence_level": "30", - "safespot": null, - "lifepoints": "85", - "strength_level": "30", - "id": "4706", - "aggressive": "true", - "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Mikasi looks ready to teach you about magic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Magic Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4707", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A flea-infested", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Old Man Ral", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4708", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A flea-infested black market trader.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trader Sven", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4716", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A flea-infested", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4717", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A flea-infested", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4718", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4719", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4720", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4721", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4722", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4723", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4724", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4725", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4726", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Cowardly mage.", - "magic_level": "90", - "defence_animation": "0", - "magic_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "60", - "safespot": null, - "lifepoints": "28", - "strength_level": "1", - "id": "4733", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4734", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4735", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4736", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4737", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4738", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4739", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4740", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks pale", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch citizen", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4741", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4746", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4747", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4748", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4749", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4750", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4751", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4752", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4753", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4754", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A poor street urchin!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "A Meiyerditch child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4755", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks dirty and tired!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4756", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks dirty and tired!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4757", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This citizen looks dirty and tired!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Meiyerditch miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4759", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Some rubbish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4765", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like it's got fleas!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Stray dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4766", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A smelly cat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4768", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An initiate juvenile vampyre; a guard for the mining area.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Juvinate guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4772", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An initiate juvenile vampyre; a guard for the mining area.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Juvinate guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4773", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A juvenile vampyre.", - "melee_animation": "6276", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Vampyre juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "4774", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A juvenile vampyre.", - "melee_animation": "6276", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Vampyre juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "4775", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "An initiate juvenile vampyre; seems to be a servant.", - "melee_animation": "5783", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "5798", - "name": "Vampyre juvinate", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "4776", - "range_level": "44", - "attack_level": "1" - }, - { - "examine": "An initiate juvenile vampyre.", - "melee_animation": "5783", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "5798", - "name": "Vampyre juvinate", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "4777", - "range_level": "44", - "attack_level": "1" - }, - { - "examine": "A juvenile vampyre.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Held vampyre juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "4778", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A juvenile vampyre.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6781", - "name": "Held vampyre juvenile", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "4779", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "An initiate juvenile vampyre; seems to be a servant.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "5798", - "name": "Held vampyre juvinate", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "4780", - "range_level": "44", - "attack_level": "1" - }, - { - "examine": "An enraged vampyre!", - "slayer_task": "86", - "melee_animation": "6016", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6031", - "name": "Angry vampyre", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "4789", - "range_level": "1", - "attack_level": "42" - }, - { - "name": "Vanstrom Klause", - "defence_level": "1", - "safespot": null, - "lifepoints": "155", - "strength_level": "1", - "id": "4793", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Not as strong as Thok.", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "name": "Vanstrom Klause", - "defence_level": "60", - "safespot": null, - "lifepoints": "28", - "strength_level": "90", - "id": "4796", - "aggressive": "true", - "range_level": "1", - "attack_level": "90" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "50", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "1", - "id": "4805", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "52", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "4806", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "54", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "1", - "id": "4807", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "56", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "56", - "safespot": null, - "lifepoints": "80", - "strength_level": "1", - "id": "4808", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Flying female vampire", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4810", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Flying female vampire", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4811", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Flying female vampire", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4812", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "50", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "1", - "id": "4813", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "52", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "4814", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "54", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "1", - "id": "4815", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "56", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "56", - "safespot": null, - "lifepoints": "80", - "strength_level": "1", - "id": "4816", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "50", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "1", - "id": "4817", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "52", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "4818", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "54", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "1", - "id": "4819", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An evil", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "56", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "0", - "name": "Vyrewatch", - "defence_level": "56", - "safespot": null, - "lifepoints": "80", - "strength_level": "1", - "id": "4820", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Vyrewatch", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4821", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Vyrewatch", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4822", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Vyrewatch", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4823", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Vyrewatch", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4824", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "50", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "1", - "id": "4825", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "52", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "4826", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "54", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "1", - "id": "4827", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A thirsty-looking", - "melee_animation": "6783", - "range_animation": "0", - "attack_speed": "6", - "magic_level": "56", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "6861", - "name": "Vyrewatch", - "defence_level": "56", - "safespot": null, - "lifepoints": "80", - "strength_level": "1", - "id": "4828", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4829", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "4830", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "4831", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "4832", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4833", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "4834", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "4835", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "4836", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4837", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "4838", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "4839", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "4840", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4841", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "4842", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "4843", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "4844", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A very high-ranking vampyre.", - "melee_animation": "7435", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "7524", - "name": "Flying female vampire", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "4845", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Flying female vampire", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4847", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Flying female vampire", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4848", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "4849", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4850", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "4851", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "4852", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Her knives tickle Thok.", - "magic_animation": "0", - "name": "Holgart", - "defence_level": "60", - "safespot": null, - "lifepoints": "28", - "strength_level": "1", - "id": "4868", - "aggressive": "true", - "range_level": "90", - "attack_level": "1", - "defence_animation": "0" - }, - { - "examine": "Not Thok's pretty lass.", - "magic_level": "90", - "defence_animation": "0", - "magic_animation": "0", - "name": "Fisherman", - "defence_level": "60", - "safespot": null, - "lifepoints": "28", - "strength_level": "1", - "id": "4870", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A child of aquatic evil.", - "melee_animation": "4829", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4830", - "name": "Slug Prince", - "defence_level": "37", - "safespot": null, - "lifepoints": "105", - "strength_level": "37", - "id": "4890", - "aggressive": "true", - "range_level": "1", - "attack_level": "37" - }, - { - "examine": "An extremely vicious lobster.", - "slayer_task": "71", - "melee_animation": "6265", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6267", - "name": "Giant Lobster", - "defence_level": "29", - "safespot": null, - "lifepoints": "82", - "strength_level": "29", - "id": "4893", - "aggressive": "true", - "range_level": "1", - "attack_level": "29" - }, - { - "examine": "A rather nasty looking crustacean.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sea slug", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4894", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "164", - "combat_audio": "3520,472,471", - "respawn_delay": "60", - "defence_animation": "163", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "29", - "strength_level": "1", - "id": "4898", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Cordero looks ready to teach you how to cook.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cooking Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4899", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Cadmus, looking a little bit crafty.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Crafting Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4900", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Finlay, mending a crayfish cage.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fishing Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4901", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Monlum, surveying the rocks.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mining Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4902", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Yauchomi, follower of Saradomin.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Prayer Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4903", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Feoras looks a bit fiery.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Smelting Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4904", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Wilfred, a chip off the old block.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Woodcutting Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4906", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Barb, ready to teach you about banking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bank Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4907", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His motives are see-through.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fritz the Glassblower", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4909", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An earth elemental.", - "melee_animation": "4868", - "combat_audio": "1531,1533,1532", - "attack_speed": "6", - "magic_level": "10", - "respawn_delay": "5", - "defence_animation": "4869", - "death_animation": "4870", - "name": "Earth elemental", - "defence_level": "35", - "safespot": null, - "lifepoints": "35", - "strength_level": "35", - "id": "4910", - "aggressive": "false", - "range_level": "30", - "attack_level": "20" - }, - { - "examine": "An elemental rock.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "0", - "name": "Elemental rock", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4911", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A nasty overgrown rodent.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4934", - "weakness": "9", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Giant crypt rat", - "defence_level": "65", - "safespot": null, - "lifepoints": "70", - "strength_level": "50", - "id": "4920", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "A nasty overgrown rodent.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "4934", - "weakness": "9", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Giant crypt rat", - "defence_level": "65", - "safespot": null, - "lifepoints": "70", - "strength_level": "50", - "id": "4921", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "4922", - "aggressive": "true", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "4923", - "aggressive": "true", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "4924", - "aggressive": "true", - "range_level": "1", - "attack_level": "5" - }, - { - "melee_animation": "4933", - "combat_audio": "703,705,704", - "defence_animation": "4934", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4925", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "7", - "safespot": null, - "lifepoints": "10", - "strength_level": "7", - "id": "4926", - "aggressive": "true", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "7", - "safespot": null, - "lifepoints": "10", - "strength_level": "7", - "id": "4927", - "aggressive": "true", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Dungeon rat", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "4928", - "aggressive": "true", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "weakness": "8", - "magic_animation": "0", - "death_animation": "4935", - "name": "Dungeon rat", - "defence_level": "13", - "safespot": null, - "lifepoints": "18", - "strength_level": "13", - "id": "4929", - "aggressive": "true", - "range_level": "1", - "attack_level": "13" - }, - { - "examine": "They'll eat anything!", - "melee_animation": "5341", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5343", - "name": "Goat", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "4930", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "They'll eat anything!", - "melee_animation": "5341", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5343", - "name": "Goat", - "defence_level": "5", - "safespot": null, - "lifepoints": "7", - "strength_level": "5", - "id": "4931", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "They'll eat anything!", - "melee_animation": "5341", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5343", - "name": "Billy Goat", - "defence_level": "11", - "safespot": null, - "lifepoints": "15", - "strength_level": "11", - "id": "4932", - "range_level": "1", - "attack_level": "11" - }, - { - "death_animation": "5343", - "name": "Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "21", - "melee_animation": "5341", - "strength_level": "1", - "id": "4933", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "5342" - }, - { - "death_animation": "5343", - "name": "Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "21", - "melee_animation": "5341", - "strength_level": "1", - "id": "4934", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "5342" - }, - { - "death_animation": "5343", - "name": "Billy Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "28", - "melee_animation": "5341", - "strength_level": "1", - "id": "4935", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "5342" - }, - { - "examine": "A dirty rat.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4935", - "name": "Dungeon rat", - "defence_level": "8", - "safespot": null, - "lifepoints": "11", - "strength_level": "8", - "id": "4936", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "A dirty rat.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4935", - "name": "Dungeon rat", - "defence_level": "8", - "safespot": null, - "lifepoints": "11", - "strength_level": "8", - "id": "4937", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "name": "Angry giant rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "4938", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Angry giant rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "4939", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a little on the cross side!", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "4935", - "name": "Angry giant rat", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4940", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "It's one of Iban's pet vermin.", - "slayer_task": "67", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "name": "Blessed giant rat", - "defence_level": "12", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "4941", - "range_level": "1", - "attack_level": "12" - }, - { - "melee_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "4942", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4934", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "4943", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Overgrown vermin.", - "combat_audio": "703,705,704", - "melee_animation": "4933", - "attack_speed": "5", - "defence_animation": "4934", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "23", - "safespot": null, - "lifepoints": "26", - "strength_level": "20", - "id": "4944", - "aggressive": "true", - "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", - "range_level": "1", - "attack_level": "21" - }, - { - "examine": "Overgrown vermin.", - "slayer_task": "67", - "combat_audio": "703,705,704", - "melee_animation": "4933", - "attack_speed": "5", - "defence_animation": "4934", - "weakness": "9", - "death_animation": "4935", - "name": "Giant rat", - "defence_level": "23", - "safespot": null, - "lifepoints": "26", - "strength_level": "20", - "id": "4945", - "aggressive": "true", - "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", - "range_level": "1", - "attack_level": "21" - }, - { - "examine": "Trollish.", - "slayer_task": "83", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "My Arm", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4947", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old sailor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Barnaby", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4962", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a leprechaun sunbathing on a mountain.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tool Leprechaun", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4965", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mountain-dwelling bird. Cute", - "slayer_task": "7", - "melee_animation": "5031", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5033", - "name": "Baby Roc", - "defence_level": "40", - "safespot": null, - "lifepoints": "100", - "strength_level": "40", - "id": "4971", - "aggressive": "true", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A very", - "slayer_task": "7", - "melee_animation": "5024", - "range_animation": "5025", - "magic_level": "55", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5027", - "name": "Giant Roc", - "defence_level": "55", - "safespot": null, - "lifepoints": "285", - "strength_level": "55", - "id": "4972", - "aggressive": "true", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "It looks like he's been here a long time.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Male slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4975", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks like she's been down here a long time.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Female slave", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4977", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mercenary", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4989", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mercenary", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4990", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mercenary", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4991", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Mercenary", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4992", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4993", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4994", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4995", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4996", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4997", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He looks a bit aggressive.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Guard", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "4998", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "4999", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5000", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5001", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5002", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An apprentice.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Egg launcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5026", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A tired old wizard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Egg launcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5027", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An egg launcher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Egg launcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5028", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A slightly more approachable barbarian.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Commander Connad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5029", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks pretty mean.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Cain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5030", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A stressed out barbarian private.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Private Paldo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5031", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian private.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Private Pendron", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5032", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian private.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Private Pierreb", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5033", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian private.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Private Paldon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5034", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian army teacher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Major Attack", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5035", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian army teacher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Major Collect", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5036", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian army teacher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Major Defend", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5037", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A barbarian army teacher.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Major Heal", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5038", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's keeping a close eye on that nearby door.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sergeant Sambur", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5039", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What on Gielinor is that?", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "670,672,671", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Penance Fighter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5040", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Shooty-shooty.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Penance Ranger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5041", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's making a run for it!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Penance Runner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5042", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A nasty piece of work.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Penance Healer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5043", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not as strong as Thok.", - "melee_animation": "401", - "range_animation": "0", - "magic_level": "80", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Jeff", - "defence_level": "40", - "safespot": null, - "lifepoints": "22", - "strength_level": "80", - "id": "5048", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "Time to run away...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shark", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5067", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It blends in very well with its surroundings.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tropical wagtail", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5072", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This bird obviously doesn't believe in subtlety.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Crimson swift", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5073", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Best served ice cold.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cerulean twitch", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5074", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Actually", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Golden warbler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5075", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Nothing much to get in a flap about.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Copper longtail", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5076", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Chinchompa", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "5079", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It looks fluffy and cute; it's probably deadly.", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "2", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5183", - "name": "Carnivorous chinchompa", - "defence_level": "2", - "safespot": null, - "lifepoints": "10", - "strength_level": "2", - "id": "5080", - "range_level": "2", - "attack_level": "2" - }, - { - "examine": "Wild.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ferret", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5081", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A black warlock. The air seems to distort wherever it passes.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Black warlock", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5082", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a snowy knight butterfly.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Snowy knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5083", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A sapphire glacialis. It doesn't look as pretentious as its name sounds.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sapphire glacialis", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5084", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a ruby harvest butterfly.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ruby harvest", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5085", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Curls up into a ball to protect itself from attack.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Prickly kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5086", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Now that's a big overbite.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sabre-toothed kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5087", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It uses its tail to hunt and skewer fish.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barb-tailed kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5088", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "That's a mean looking set of claws.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wild kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5089", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Ha! Thok much stronger.", - "melee_animation": "395", - "range_animation": "0", - "magic_level": "80", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Gyr Falcon", - "defence_level": "40", - "safespot": null, - "lifepoints": "22", - "strength_level": "80", - "id": "5097", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "It seems to be on a permanent sugar rush.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spotted kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5098", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Quieter than a ninja mouse with slippers on.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dark kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5099", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Now you see it; now you don't.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dashing kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5100", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's just like a big, white, furry, deadly can opener.", - "melee_animation": "5228", - "range_animation": "5228", - "attack_speed": "5", - "respawn_delay": "10", - "defence_animation": "404", - "magic_animation": "5228", - "death_animation": "5234", - "name": "Sabre-toothed kyatt", - "defence_level": "99", - "safespot": null, - "lifepoints": "10", - "strength_level": "25", - "id": "5103", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "If you tried to ride that, you'd just impale yourself!", - "melee_animation": "5228", - "range_animation": "5228", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "5228", - "death_animation": "5234", - "name": "Spined larupia", - "defence_level": "99", - "safespot": null, - "lifepoints": "10", - "strength_level": "15", - "id": "5104", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Get in a graahk's way and you're going to know about it... however briefly.", - "melee_animation": "5228", - "range_animation": "5228", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "5228", - "death_animation": "5234", - "name": "Horned graahk", - "defence_level": "99", - "safespot": null, - "lifepoints": "10", - "strength_level": "25", - "id": "5105", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "It's just like a big, white, furry, deadly can opener.", - "melee_animation": "5228", - "range_animation": "5228", - "attack_speed": "5", - "defence_animation": "404", - "magic_animation": "5228", - "death_animation": "9055", - "name": "null", - "defence_level": "40", - "safespot": null, - "lifepoints": "10", - "strength_level": "20", - "id": "5106", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "He must be good at hunting; even his hair blends in with the surroundings.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hunting expert", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5112", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "With all the furs", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hunting expert", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5113", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Slightly slimy but kind of cute.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Orange salamander", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5114", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Slightly slimy but certainly striking.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Red salamander", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5115", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Slightly slimy and somewhat menacing.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Black salamander", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5116", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Very slimy and generally disgusting.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Swamp lizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5117", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very large", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Eagle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5120", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very large", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Desert eagle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5130", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very large", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jungle eagle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5131", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very large", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Polar eagle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5132", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It seems to be protecting the nest.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Eagle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5133", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "melee_animation": "5304", - "strength_level": "1", - "id": "5137", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "5305" - }, - { - "examine": "Now", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Boulder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5140", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's playing both sides!", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "75", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Double agent", - "defence_level": "75", - "safespot": null, - "lifepoints": "85", - "strength_level": "75", - "id": "5144", - "aggressive": "true", - "range_level": "1", - "attack_level": "75" - }, - { - "melee_animation": "422", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Double agent", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "5145", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "How cute!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Li'l lamb", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5146", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The black sheep of the family.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lamb", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5147", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5162", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5163", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy", - "name": "Sheep", - "id": "5164" - }, - { - "examine": "This goat belongs to the mountain camp people.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5166", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This goat belongs to the mountain camp people.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain Goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5167", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "5338", - "combat_audio": "757,759,758", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5337", - "weakness": "9", - "death_animation": "5336", - "name": "Ram", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "5168", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "5338", - "combat_audio": "757,759,758", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5337", - "weakness": "9", - "death_animation": "5336", - "name": "Ram", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "5169", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "White and fluffy.", - "melee_animation": "5338", - "range_animation": "0", - "combat_audio": "757,759,758", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5337", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5336", - "name": "Ram", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "5170", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This beast doesn't need climbing boots.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mountain goat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5171", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Freshly shorn.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Golden sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5172", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Lovely thick wool.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Golden sheep", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5173", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Seems intelligent... for an ogre.", - "slayer_task": "64", - "combat_style": "2", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Ogre shaman", - "defence_level": "65", - "safespot": null, - "lifepoints": "371", - "strength_level": "65", - "id": "5176", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A mother dragon.", - "slayer_task": "11", - "melee_animation": "80", - "range_animation": "80", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "35", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "108", - "magic_animation": "80", - "death_animation": "92", - "name": "Blue dragon", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "5178", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "Seems intelligent... for an ogre.", - "slayer_task": "64", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Ogre shaman", - "defence_level": "65", - "safespot": null, - "lifepoints": "371", - "strength_level": "65", - "id": "5181", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "Seems intelligent... for an ogre.", - "slayer_task": "64", - "combat_style": "2", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Ogre shaman", - "defence_level": "65", - "safespot": null, - "lifepoints": "371", - "strength_level": "65", - "id": "5184", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "Seems intelligent... for an ogre.", - "slayer_task": "64", - "combat_style": "2", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Ogre shaman", - "defence_level": "65", - "safespot": null, - "lifepoints": "371", - "strength_level": "65", - "id": "5187", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "It's Nial", - "melee_animation": "8946", - "range_animation": "0", - "magic_level": "58", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8948", - "name": "Saff Waldon", - "defence_level": "58", - "safespot": null, - "lifepoints": "165", - "strength_level": "58", - "id": "5188", - "aggressive": "true", - "range_level": "58", - "attack_level": "58" - }, - { - "examine": "Seems intelligent. For an ogre.", - "combat_style": "2", - "name": "Ogre shaman", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "5190", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Seems intelligent. For an ogre.", - "combat_style": "2", - "name": "Ogre shaman", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "5193", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A wizard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5195", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wizard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5196", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A wizard.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5197", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She needs to work out before facing Thok.", - "melee_animation": "7041", - "range_animation": "0", - "magic_level": "80", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Alice's husband", - "defence_level": "40", - "safespot": null, - "lifepoints": "22", - "strength_level": "80", - "id": "5204", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "It's an undead cow.", - "melee_animation": "5849", - "range_animation": "5849", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "5", - "defence_animation": "5850", - "magic_animation": "5849", - "death_animation": "5851", - "name": "Undead cow", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "5211", - "aggressive": "false", - "bonuses": "-15,-15,-15,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Shooty-shooty.", - "combat_style": "1", - "melee_animation": "5395", - "respawn_delay": "60", - "defence_animation": "5396", - "death_animation": "5937", - "name": "Penance Ranger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5229", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Shooty-shooty.", - "combat_style": "1", - "melee_animation": "5395", - "respawn_delay": "60", - "defence_animation": "5396", - "death_animation": "5937", - "name": "Penance Ranger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5237", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Run away! Run away!", - "melee_animation": "5411", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5412", - "name": "Penance Queen", - "defence_level": "132", - "safespot": null, - "lifepoints": "71", - "strength_level": "260", - "id": "5247", - "aggressive": "true", - "range_level": "116", - "attack_level": "260" - }, - { - "examine": "What's it looking at?", - "melee_animation": "5092", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5093", - "name": "Queen spawn", - "defence_level": "50", - "safespot": null, - "lifepoints": "450", - "strength_level": "60", - "id": "5248", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "He looks embarrassed", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain Errdo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5249", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Part scarab, part man.", - "slayer_task": "70", - "combat_style": "2", - "melee_animation": "7615", - "range_animation": "0", - "magic_level": "54", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "7616", - "name": "Scarab mage", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "40", - "id": "5250", - "aggressive": "true", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "A mounted lancer.", - "slayer_task": "70", - "melee_animation": "7584", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "7581", - "name": "Locust rider", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "54", - "id": "5251", - "aggressive": "true", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "A mounted archer.", - "slayer_task": "70", - "melee_animation": "5451", - "range_animation": "5451", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "7581", - "name": "Locust rider", - "defence_level": "54", - "safespot": null, - "lifepoints": "77", - "strength_level": "40", - "id": "5252", - "aggressive": "true", - "range_level": "54", - "attack_level": "40" - }, - { - "examine": "A huge scarab beast.", - "slayer_task": "70", - "melee_animation": "5457", - "range_animation": "0", - "magic_level": "62", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5456", - "name": "Giant scarab", - "defence_level": "62", - "safespot": null, - "lifepoints": "571", - "strength_level": "62", - "id": "5253", - "aggressive": "true", - "range_level": "62", - "attack_level": "62" - }, - { - "examine": "Part scarab, part man.", - "combat_style": "2", - "melee_animation": "7615", - "respawn_delay": "60", - "defence_animation": "7617", - "death_animation": "7616", - "name": "Scarab mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "5254", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5258", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She can look after my money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5260", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard of Sophanem.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sophanem guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5270", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard of Sophanem.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sophanem guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5274", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard of Menaphos.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Menaphite guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5277", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Flings annoying splinters at Thok.", - "melee_animation": "426", - "range_animation": "426", - "magic_level": "80", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "836", - "name": "Osman", - "defence_level": "40", - "safespot": null, - "lifepoints": "22", - "strength_level": "80", - "id": "5285", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5293", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5294", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5295", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5296", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5297", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5298", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5299", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5300", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5301", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5302", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5303", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5304", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "range_animation": "5568", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5567", - "slayer_exp": "30", - "magic_animation": "5568", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "10", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "5305", - "bonuses": "6,15,15,15,15,15,15,6,6,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "5306", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "range_animation": "5568", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5567", - "slayer_exp": "30", - "magic_animation": "5568", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "10", - "safespot": null, - "lifepoints": "18", - "strength_level": "1", - "id": "5307", - "bonuses": "6,15,15,15,15,15,15,6,6,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "Brains!", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "1", - "id": "5308", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Brains!", - "melee_animation": "5571", - "range_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5574", - "slayer_exp": "30", - "magic_animation": "5571", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "16", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "5309", - "bonuses": "10,15,16,16,15,16,16,10,10,16,15,15,15,15,15", - "range_level": "1", - "attack_level": "15" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "1", - "id": "5310", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "1", - "id": "5311", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "1", - "id": "5312", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "1", - "id": "5313", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5314", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5315", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5316", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5317", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5318", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Examine not added", - "melee_animation": "5571", - "range_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5574", - "slayer_exp": "30", - "magic_animation": "5571", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "20", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "5319", - "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Examine not added", - "melee_animation": "5571", - "range_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5574", - "slayer_exp": "30", - "magic_animation": "5571", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "20", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "5320", - "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "Examine not added", - "melee_animation": "5571", - "range_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5574", - "slayer_exp": "30", - "magic_animation": "5571", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "20", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "5321", - "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5571", - "range_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "5", - "defence_animation": "5574", - "slayer_exp": "30", - "magic_animation": "5571", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "23", - "safespot": null, - "lifepoints": "30", - "strength_level": "19", - "id": "5322", - "aggressive": "true", - "bonuses": "21,19,20,42,44,34,41,38,40,21,0,0,0,0,0", - "range_level": "1", - "attack_level": "20" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5323", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5324", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5325", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5326", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5327", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5328", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5329", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "", - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5330", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5331", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5342", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5343", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5344", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5345", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5346", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5347", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "slayer_task": "36", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5348", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5349", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5350", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5351", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "5352", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A minion of Rashiliyia.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Undead one", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "5353", - "aggressive": "true", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "A minion of Rashiliyia.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Undead one", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "5354", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "The animated dead; one of Rashiliyia's minions.", - "slayer_task": "93", - "melee_animation": "5568", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5569", - "name": "Undead one", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "5355", - "aggressive": "true", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "The animated dead; one of Rashiliyia's minions.", - "slayer_task": "93", - "melee_animation": "5568", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5569", - "name": "Undead one", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "5356", - "aggressive": "true", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "The animated dead; one of Rashiliyia's minions.", - "slayer_task": "93", - "melee_animation": "5571", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5575", - "name": "Undead one", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "5357", - "aggressive": "true", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "The animated dead; one of Rashiliyia's minions.", - "slayer_task": "93", - "melee_animation": "5571", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5575", - "name": "Undead one", - "defence_level": "33", - "safespot": null, - "lifepoints": "47", - "strength_level": "33", - "id": "5358", - "aggressive": "true", - "range_level": "1", - "attack_level": "33" - }, - { - "examine": "A giant skeleton.", - "slayer_task": "75", - "melee_animation": "5499", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5503", - "name": "Giant skeleton", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "5359", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A fiendish embodiment of water.", - "slayer_task": "90", - "combat_style": "1", - "melee_animation": "1582", - "range_animation": "1582", - "combat_audio": "3774,3773,3772", - "attack_speed": "4", - "magic_level": "105", - "defence_animation": "1581", - "weakness": "4", - "magic_animation": "1582", - "death_animation": "1580", - "name": "Waterfiend", - "defence_level": "128", - "poison_immune": "true", - "safespot": null, - "lifepoints": "128", - "strength_level": "0", - "id": "5361", - "aggressive": "true", - "bonuses": "0,0,0,0,0,100,100,10,100,100,0,0,0,0,0", - "range_level": "105", - "projectile": "16", - "attack_level": "0" - }, - { - "examine": "It appears to be intelligent and savage.", - "slayer_task": "41", - "melee_animation": "91", - "range_animation": "91", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "168", - "defence_animation": "89", - "weakness": "3", - "slayer_exp": "183", - "magic_animation": "91", - "death_animation": "92", - "name": "Brutal green dragon", - "defence_level": "168", - "poison_immune": "true", - "safespot": null, - "lifepoints": "175", - "strength_level": "168", - "id": "5362", - "aggressive": "true", - "clue_level": "2", - "range_level": "0", - "attack_level": "268" - }, - { - "examine": "Experimenting with mithril gone bad!", - "slayer_task": "57", - "melee_animation": "91", - "range_animation": "91", - "combat_audio": "408,410,409", - "attack_speed": "4", - "magic_level": "168", - "respawn_delay": "30", - "defence_animation": "89", - "weakness": "8", - "slayer_exp": "273", - "magic_animation": "91", - "death_animation": "92", - "name": "Mithril dragon", - "defence_level": "268", - "safespot": null, - "lifepoints": "254", - "strength_level": "268", - "id": "5363", - "aggressive": "true", - "bonuses": "0,0,0,0,0,50,100,70,30,90,0,0,0,0,0", - "clue_level": "2", - "range_level": "168", - "attack_level": "268" - }, - { - "weakness": "7", - "examine": "It appears to be intelligent and savage.", - "name": "Confused barbarian", - "defence_level": "50", - "safespot": null, - "lifepoints": "175", - "strength_level": "167", - "attack_speed": "6", - "id": "5364", - "range_level": "167", - "attack_level": "70" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "36", - "strength_level": "1", - "id": "5369", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "36", - "strength_level": "1", - "id": "5370", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eeek! A ghost!", - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "36", - "strength_level": "1", - "id": "5371", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Why does it attack with twigs? Swords and axes much better.", - "melee_animation": "5532", - "range_animation": "426", - "combat_audio": "436,439,438", - "magic_level": "80", - "defence_animation": "5533", - "weakness": "10", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "40", - "safespot": null, - "lifepoints": "36", - "strength_level": "80", - "id": "5372", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "Are these twigs meant to hurt Thok?", - "melee_animation": "5532", - "range_animation": "426", - "combat_audio": "436,439,438", - "magic_level": "80", - "defence_animation": "5533", - "weakness": "10", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "40", - "safespot": null, - "lifepoints": "36", - "strength_level": "80", - "id": "5373", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "It thinks it scary. Thok show it scary.", - "melee_animation": "5532", - "range_animation": "0", - "combat_audio": "436,439,438", - "magic_level": "80", - "defence_animation": "5533", - "weakness": "10", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "70", - "safespot": null, - "lifepoints": "36", - "strength_level": "80", - "id": "5374", - "aggressive": "true", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5568", - "range_animation": "5568", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5567", - "slayer_exp": "30", - "magic_animation": "5568", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "25", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "5375", - "aggressive": "true", - "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5568", - "range_animation": "5568", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5567", - "slayer_exp": "30", - "magic_animation": "5568", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "25", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "5376", - "aggressive": "true", - "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "28", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5377", - "aggressive": "true", - "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "Dead man walking.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "28", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "5378", - "aggressive": "true", - "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "The walking dead.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "48", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "5379", - "aggressive": "true", - "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "The walking dead.", - "melee_animation": "5578", - "range_animation": "5578", - "combat_audio": "918,923,922", - "attack_speed": "5", - "respawn_delay": "30", - "defence_animation": "5579", - "slayer_exp": "30", - "magic_animation": "5578", - "death_animation": "5580", - "name": "Zombie", - "defence_level": "48", - "safespot": null, - "lifepoints": "40", - "strength_level": "1", - "id": "5380", - "aggressive": "true", - "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "Animated steel armour.", - "melee_animation": "386", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "4167", - "name": "Animated steel armour", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "5382", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "Big and bony, just how I like them.", - "start_gfx": "2713", - "melee_animation": "5499", - "range_animation": "5499", - "attack_speed": "2", - "defence_animation": "5489", - "magic_animation": "5499", - "death_animation": "5503", - "name": "Giant skeleton", - "defence_level": "85", - "poison_immune": "true", - "safespot": null, - "lifepoints": "100", - "strength_level": "95", - "id": "5384", - "aggressive": "true", - "bonuses": "25,25,25,25,25,25,25,25,25,25,25,25,25,25,25", - "range_level": "1", - "projectile": "2718", - "attack_level": "95" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "56", - "strength_level": "1", - "id": "5393", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5394", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5395", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5396", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5397", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5398", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5399", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5400", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5401", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5402", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5403", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5568", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5567", - "slayer_exp": "30", - "death_animation": "5569", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "92", - "strength_level": "1", - "id": "5404", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5405", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5406", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5407", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5408", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5409", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "5410", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "How does it move of its own accord?", - "melee_animation": "5591", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5592", - "name": "Possessed pickaxe", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "5413", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "How does it move of its own accord?", - "melee_animation": "5597", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5596", - "name": "Animated spade", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "52", - "id": "5414", - "range_level": "1", - "attack_level": "52" - }, - { - "examine": "A terrifying dog beast.", - "slayer_task": "82", - "melee_animation": "5625", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "5628", - "name": "Terror dog", - "defence_level": "47", - "safespot": null, - "lifepoints": "134", - "strength_level": "47", - "id": "5417", - "aggressive": "true", - "range_level": "1", - "attack_level": "47" - }, - { - "melee_animation": "5625", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5626", - "death_animation": "5627", - "name": "Terror dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "82", - "strength_level": "1", - "id": "5418", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5617", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "5618", - "death_animation": "5619", - "name": "Tarn", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "5420", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I preferred him when he was human.", - "melee_animation": "5617", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5619", - "name": "Mutant tarn", - "defence_level": "57", - "safespot": null, - "lifepoints": "325", - "strength_level": "57", - "id": "5421", - "aggressive": "true", - "range_level": "1", - "attack_level": "57" - }, - { - "examine": "What restful music!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5439", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What restful music!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "KGP Agent", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5442", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Instructs agility.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Agility Instructor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5447", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An army commander.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Army Commander", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5448", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sturdy cold being.", - "slayer_task": "48", - "melee_animation": "5724", - "range_animation": "5725", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "5726", - "name": "Icelord", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "22", - "id": "5452", - "aggressive": "true", - "range_level": "30", - "attack_level": "22" - }, - { - "examine": "Sturdy cold being.", - "slayer_task": "48", - "melee_animation": "5724", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5726", - "name": "Icelord", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "5453", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Sturdy cold being.", - "slayer_task": "48", - "melee_animation": "5724", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5726", - "name": "Icelord", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "5454", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Sturdy cold being.", - "slayer_task": "48", - "melee_animation": "5724", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "5726", - "name": "Icelord", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "5455", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "An impressive-looking troll.", - "slayer_task": "83", - "melee_animation": "5374", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5209", - "name": "Ice Troll King", - "defence_level": "65", - "safespot": null, - "lifepoints": "185", - "strength_level": "65", - "id": "5472", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "An ice troll youngling.", - "range_animation": "0", - "melee_animation": "284", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll runt", - "defence_level": "70", - "safespot": null, - "lifepoints": "60", - "strength_level": "70", - "id": "5473", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A male troll wielding a large club.", - "range_animation": "0", - "melee_animation": "284", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll male", - "defence_level": "40", - "safespot": null, - "lifepoints": "80", - "strength_level": "80", - "id": "5474", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "An ice troll with a bag of rocks.", - "combat_style": "1", - "range_animation": "1142", - "melee_animation": "1142", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll female", - "defence_level": "40", - "safespot": null, - "lifepoints": "80", - "strength_level": "80", - "id": "5475", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "projectile": "276", - "attack_level": "80" - }, - { - "examine": "A large ice troll.", - "melee_animation": "4332", - "range_animation": "0", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "name": "Ice troll grunt", - "defence_level": "60", - "safespot": null, - "lifepoints": "80", - "strength_level": "100", - "id": "5476", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "An ill-tempered king.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "King Gjuki Sorvott IV", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5478", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Thorkel Silkbeard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "5480", - "range_level": "1", - "attack_level": "1" - }, - { - "facing_booth": "true", - "name": "Magnus Gram", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "5488", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard on insult duty.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5489", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5490", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5491", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of King Sorvott's militia.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5492", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A miner at work.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Miner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5497", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Burgher's protectors.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Honour guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5514", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Burgher's protectors.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Honour guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5516", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of your militia.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "0", - "name": "Honour guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5517", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ice troll youngling.", - "range_animation": "0", - "melee_animation": "284", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll runt", - "defence_level": "70", - "safespot": null, - "lifepoints": "60", - "strength_level": "70", - "id": "5521", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A male troll wielding a large club.", - "range_animation": "0", - "melee_animation": "284", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll male", - "defence_level": "40", - "safespot": null, - "lifepoints": "80", - "strength_level": "80", - "id": "5522", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "An ice troll with a bag of rocks.", - "combat_style": "1", - "range_animation": "1142", - "melee_animation": "1142", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll female", - "defence_level": "40", - "safespot": null, - "lifepoints": "80", - "strength_level": "80", - "id": "5523", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "projectile": "276", - "attack_level": "80" - }, - { - "examine": "An ice troll youngling.", - "range_animation": "0", - "melee_animation": "284", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll runt", - "defence_level": "70", - "safespot": null, - "lifepoints": "60", - "strength_level": "70", - "id": "5525", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A male troll wielding a large club.", - "range_animation": "0", - "melee_animation": "284", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "9", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll male", - "defence_level": "40", - "safespot": null, - "lifepoints": "80", - "strength_level": "80", - "id": "5526", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "80" - }, - { - "examine": "An ice troll with a bag of rocks.", - "combat_style": "1", - "range_animation": "1142", - "melee_animation": "1142", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "285", - "weakness": "0", - "magic_animation": "0", - "death_animation": "287", - "name": "Ice troll female", - "defence_level": "40", - "safespot": null, - "lifepoints": "80", - "strength_level": "80", - "id": "5527", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "projectile": "276", - "attack_level": "80" - }, - { - "examine": "A hairy, smelly, grazing animal.", - "melee_animation": "5782", - "range_animation": "5782", - "combat_audio": "3378,3380,3379", - "attack_speed": "4", - "defence_animation": "5783", - "weakness": "7", - "magic_animation": "5782", - "death_animation": "5784", - "name": "Yak", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "10", - "id": "5529", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Antisocial.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sorceress", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5531", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Come", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Apprentice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5532", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An autumn elemental.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Autumn Elemental", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5533", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A spring elemental.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spring Elemental", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5539", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A summer elemental.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Summer Elemental", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5547", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A winter elemental.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Winter Elemental", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5553", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It dare attack Pretty Lass? Thok crush its puny skull!", - "range_animation": "0", - "magic_level": "95", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Osman", - "defence_level": "50", - "safespot": null, - "lifepoints": "157", - "strength_level": "95", - "id": "5561", - "aggressive": "true", - "range_level": "95", - "attack_level": "95" - }, - { - "examine": "She's honest about the things you aren't.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sin Seer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5571", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Shadow Realm guardian.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "436,439,438", - "defence_animation": "0", - "slayer_exp": "25", - "magic_animation": "0", - "death_animation": "0", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5572", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is it male or female?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Homunculus", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5581", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Strong", - "range_animation": "0", - "magic_level": "95", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Cage", - "defence_level": "70", - "safespot": null, - "lifepoints": "85", - "strength_level": "95", - "id": "5584", - "aggressive": "true", - "range_level": "95", - "attack_level": "95" - }, - { - "examine": "Famous for his fights.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Black-eye", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5589", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Count them pinkies!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'No fingers", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5590", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He wishes he had teeth.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "'Gummy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5591", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is it a frog", - "melee_animation": "5842", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "5841", - "name": "Frogeel", - "defence_level": "49", - "safespot": null, - "lifepoints": "70", - "strength_level": "36", - "id": "5593", - "aggressive": "true", - "range_level": "49", - "attack_level": "36" - }, - { - "death_animation": "146", - "name": "Spidine", - "defence_level": "1", - "safespot": null, - "lifepoints": "35", - "melee_animation": "143", - "strength_level": "1", - "id": "5594", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "144" - }, - { - "examine": "Definitely not a chicken or a swordfish.", - "melee_animation": "5387", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5389", - "name": "Swordchick", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "5595", - "range_level": "1", - "attack_level": "45" - }, - { - "melee_animation": "6800", - "respawn_delay": "60", - "defence_animation": "6802", - "death_animation": "6801", - "name": "Jubster", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "5596", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Since when did newts have beaks?", - "melee_animation": "2299", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "2301", - "name": "Newtroost", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "5597", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "Half unicorn", - "melee_animation": "5849", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "41", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "5851", - "name": "Unicow", - "defence_level": "41", - "safespot": null, - "lifepoints": "58", - "strength_level": "30", - "id": "5603", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Holier than thou.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5608", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holier than thou.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5609", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holier than thou.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5610", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Holier than thou.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5611", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I'd prefer it if it were a muffin...", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Puffin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5614", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5619", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5620", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5621", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "5622", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Bedside manner is a little lacking", - "slayer_task": "93", - "melee_animation": "5643", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5658", - "name": "Sorebones", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5627", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "I hope his hands don't shake.", - "slayer_task": "93", - "melee_animation": "5643", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5658", - "name": "Sorebones", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5628", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5629", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5630", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5631", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5632", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5633", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5634", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5647", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5635", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5636", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5637", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5638", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5639", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5640", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5651", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5641", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5880", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5642", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5880", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5643", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5880", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5644", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5880", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5645", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5880", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5654", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5646", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5884", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5886", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5647", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5884", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5886", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5648", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5649", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5884", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5886", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5650", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5651", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5884", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5886", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5652", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5653", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5884", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5886", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5654", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5655", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5889", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5891", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5656", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5657", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5889", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5891", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5658", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5889", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5891", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5659", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5660", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5889", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5891", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5661", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5662", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5889", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5891", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5663", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "melee_animation": "5647", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "5648", - "death_animation": "5649", - "name": "Zombie pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "52", - "strength_level": "1", - "id": "5664", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aaaarg", - "slayer_task": "93", - "melee_animation": "5889", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5891", - "name": "Zombie pirate", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "5665", - "aggressive": "true", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "It's trying to mash you flat! Less examine", - "melee_animation": "5895", - "range_animation": "0", - "magic_level": "52", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5898", - "name": "Barrelchest", - "defence_level": "52", - "safespot": null, - "lifepoints": "285", - "strength_level": "52", - "id": "5666", - "aggressive": "true", - "range_level": "52", - "attack_level": "52" - }, - { - "examine": "He is one", - "melee_animation": "5970", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5972", - "name": "Undead Lumberjack", - "defence_level": "10", - "safespot": null, - "lifepoints": "100", - "strength_level": "73", - "id": "5680", - "range_level": "1", - "attack_level": "73" - }, - { - "examine": "A big", - "slayer_task": "15", - "melee_animation": "6079", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "slayer_exp": "93", - "magic_animation": "0", - "death_animation": "6081", - "name": "Cave bug", - "defence_level": "84", - "safespot": null, - "lifepoints": "93", - "strength_level": "80", - "id": "5750", - "bonuses": "0,0,0,0,0,72,59,35,25,95,0,0,0,0,0", - "range_level": "1", - "attack_level": "82" - }, - { - "examine": "A strange mole-like being.", - "melee_animation": "6012", - "combat_audio": "3492,3494,3493", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "6013", - "slayer_exp": "52", - "death_animation": "6014", - "name": "Molanisk", - "defence_level": "50", - "safespot": null, - "lifepoints": "52", - "strength_level": "40", - "id": "5751", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5752", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5753", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5754", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5755", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5756", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5757", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5758", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5759", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5760", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5761", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5762", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5763", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5764", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5765", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5766", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5767", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5768", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5769", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after cave goblin money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5776", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after cave goblin money.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5777", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5783", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Taking a terribly important box from one place to another.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Crate goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5784", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the many citizens of Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5785", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Good at shorthand.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Goblin scribe", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5786", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He keeps order in the city.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Guard", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "5800", - "clue_level": "1", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "He keeps order in the city.", - "slayer_task": "38", - "melee_animation": "6007", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6003", - "name": "Guard", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "5801", - "clue_level": "1", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "A goblin baby.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Young 'un", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5803", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin baby.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Nipper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5805", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5807", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5808", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5809", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5810", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5811", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5812", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5813", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5814", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5815", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5816", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5817", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5818", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5819", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5820", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5821", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5822", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Don't spit", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spit goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5823", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bug-eyed little goblin fish. How cute.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Goblin fish", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5824", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Annoying little flappy things.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Moths", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5827", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "6092", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "melee_animation": "6090", - "strength_level": "1", - "id": "5829", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "6091" - }, - { - "name": "Rat Burgiss", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "703,705,704", - "strength_level": "1", - "id": "5833", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5842", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5843", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5844", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5845", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5846", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5847", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5848", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5849", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5850", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "A mean looking outlaw. Don't get too close!", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Outlaw", - "defence_level": "23", - "safespot": null, - "lifepoints": "32", - "strength_level": "23", - "id": "5851", - "range_level": "1", - "attack_level": "23" - }, - { - "examine": "Weird eyeball thing. Reminds Thok of breakfast.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "magic_level": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Monkey", - "defence_level": "40", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "5852", - "aggressive": "true", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "For sitting on.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bench", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5854", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5855", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5856", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks pretty skilled with that bow.", - "melee_animation": "426", - "range_animation": "0", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "H.A.M. Archer", - "defence_level": "20", - "safespot": null, - "lifepoints": "57", - "strength_level": "15", - "id": "5859", - "aggressive": "true", - "clue_level": "0", - "range_level": "20", - "attack_level": "15" - }, - { - "examine": "He bristles with arcane power.", - "combat_style": "2", - "melee_animation": "429", - "range_animation": "0", - "magic_level": "20", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "death_animation": "836", - "name": "H.A.M. Mage", - "defence_level": "20", - "safespot": null, - "lifepoints": "57", - "strength_level": "15", - "id": "5860", - "aggressive": "true", - "clue_level": "0", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "No match for Thok. Silly demon.", - "magic_level": "85", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Zanik", - "defence_level": "85", - "safespot": null, - "lifepoints": "71", - "strength_level": "85", - "id": "5861", - "aggressive": "true", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "A worker on the train link.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Builder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5864", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker on the train link.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Builder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5865", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker on the train link.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Builder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5866", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A worker on the train link.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Builder", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5867", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5873", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin with big", - "slayer_task": "38", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5874", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin with big", - "slayer_task": "38", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5875", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5876", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5877", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Cave goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "5878", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He sells tickets to Keldagrim.", - "slayer_task": "38", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ticket goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5879", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf from Keldagrim.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5880", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf from Keldagrim.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5881", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarf from Keldagrim.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "slayer_exp": "16", - "magic_animation": "0", - "death_animation": "0", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5882", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "16", - "examine": "A dwarf from Keldagrim.", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5883", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "16", - "examine": "A dwarf from Keldagrim.", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5884", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "16", - "examine": "A dwarf from Keldagrim.", - "name": "Dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5885", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He sells tickets to Dorgesh-Kaan.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ticket dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5886", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Are you good enough to fight?", - "melee_animation": "6318", - "range_animation": "0", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6322", - "name": "The Inadequacy", - "defence_level": "70", - "safespot": null, - "lifepoints": "100", - "strength_level": "70", - "id": "5902", - "aggressive": "true", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Can you endure long enough?", - "melee_animation": "6345", - "range_animation": "0", - "magic_level": "67", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6347", - "name": "The Everlasting", - "defence_level": "67", - "safespot": null, - "lifepoints": "191", - "strength_level": "67", - "id": "5903", - "aggressive": "true", - "range_level": "67", - "attack_level": "67" - }, - { - "examine": "Can you bring yourself to hurt another?", - "melee_animation": "6329", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6331", - "name": "The Untouchable", - "defence_level": "75", - "safespot": null, - "lifepoints": "100", - "strength_level": "65", - "id": "5904", - "aggressive": "true", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "What if you don't know how to win?", - "melee_animation": "6342", - "range_animation": "0", - "magic_level": "63", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "0", - "name": "The Illusive", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "63", - "id": "5905", - "aggressive": "true", - "range_level": "63", - "attack_level": "63" - }, - { - "examine": "You can't escape your inadequacy!", - "melee_animation": "6310", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "6315", - "name": "A Doubt", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "5906", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "Dead stone defending a dead throne room.", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Dying tree", - "defence_level": "50", - "safespot": null, - "lifepoints": "142", - "strength_level": "50", - "id": "5908", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "Don't let her arm-wrestle you for money.", - "melee_animation": "422", - "range_animation": "0", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Barbarian", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "5909", - "clue_level": "0", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A greasy, grimy gourmet.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5910", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's suspiciously talented with a meat-cleaver.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cook", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5911", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This grizzled soldier is here to distribute Rated Clan Wars badges.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Iffie", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5914", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Does what too many people aren't interested in doing.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cleaner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5916", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mangy mutt.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Stray dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5917", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He tries to keep order around here. His bizarre uniform isn't helping.", - "melee_animation": "6489", - "range_animation": "0", - "combat_audio": "2548,1979,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6490", - "name": "Guard", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "18", - "id": "5919", - "clue_level": "1", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "He tries to keep order around here. His bizarre uniform isn't helping.", - "melee_animation": "6489", - "range_animation": "0", - "combat_audio": "2548,1979,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "6490", - "name": "Guard", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "18", - "id": "5920", - "clue_level": "1", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "He's studying to be a guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trainee Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5921", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Trains the guards of the future.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Captain", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5922", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Man", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "5923", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "One of Gielinor's many citizens.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Woman", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "5924", - "clue_level": "0", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "Known for his light-fingered qualities.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "9", - "safespot": null, - "lifepoints": "25", - "strength_level": "9", - "id": "5926", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "Known for his light-fingered qualities.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "9", - "safespot": null, - "lifepoints": "25", - "strength_level": "9", - "id": "5927", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "Known for her light-fingered qualities.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "8", - "safespot": null, - "lifepoints": "24", - "strength_level": "9", - "id": "5928", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "Known for her light-fingered qualities.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Thief", - "defence_level": "8", - "safespot": null, - "lifepoints": "24", - "strength_level": "9", - "id": "5929", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "Jacques Netis - a slightly pompous art expert.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Art Critic Jacques", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5930", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Seth Minas - an aged expert in Gielinor history.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Historian Minas", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5931", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A lady with lots of information about the Museum.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Information clerk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5938", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A teacher and one of his pupils.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Teacher and pupil", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5944", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks kind of familiar.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Schoolboy", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5945", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A teacher and one of her pupils.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Teacher and pupil", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5947", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks hard at work.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5952", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could there be something exciting in his wheelbarrow?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5954", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A powerful knight of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Void Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5956", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Wheelbarrow loader.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Digsite workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5958", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Working hard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barge workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5959", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Working hard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barge workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5960", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Working hard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barge workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5961", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Working hard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barge workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5962", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Working hard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Barge foreman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5963", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An aged expert in natural history.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Natural historian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5966", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Bloodsuckers!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Leech display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5971", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Slugs of the sea variety.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sea slugs display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5972", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A house on its back.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Snail display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5973", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A cheeky little monkey.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Monkey display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5974", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A scaly little fellow.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lizard display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5975", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Nice suit.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Penguin display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5976", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's got the hump.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Camel display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5977", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Terrifying!", - "melee_animation": "1010", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Terrorbird display", - "defence_level": "1", - "safespot": null, - "lifepoints": "34", - "strength_level": "23", - "id": "5978", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like a fire-breather.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "408,410,409", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dragon display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5979", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Needs a good square meal.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wyvern display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5980", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A huge beast.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Battle tortoise display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5981", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Loves making molehills.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mole display", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5982", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It hides in stone", - "range_animation": "0", - "magic_level": "95", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Workman", - "defence_level": "1", - "safespot": null, - "lifepoints": "34", - "strength_level": "95", - "id": "5986", - "aggressive": "true", - "range_level": "95", - "attack_level": "95" - }, - { - "name": "Rupert the Beard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "5990", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Rupert the Beard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "5992", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very odd looking creature.", - "melee_animation": "6513", - "range_animation": "0", - "magic_level": "46", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6512", - "name": "Experiment No.2", - "defence_level": "46", - "safespot": null, - "lifepoints": "131", - "strength_level": "46", - "id": "5993", - "range_level": "46", - "attack_level": "46" - }, - { - "examine": "A huge mouse. It looks hungry...", - "melee_animation": "6519", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6521", - "name": "Mouse", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "44", - "id": "5994", - "aggressive": "true", - "range_level": "1", - "attack_level": "44" - }, - { - "melee_animation": "6501", - "respawn_delay": "60", - "defence_animation": "6503", - "death_animation": "6502", - "name": "Glod", - "defence_level": "1", - "safespot": null, - "lifepoints": "160", - "strength_level": "1", - "id": "5996", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Rupert the Beard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "5999", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Rupert the Beard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "498,500,499", - "strength_level": "1", - "id": "6001", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6006", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6007", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6008", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6009", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6010", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6011", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6012", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6013", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "I wish the moon wasn't out!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "76", - "safespot": null, - "lifepoints": "87", - "strength_level": "76", - "id": "6014", - "aggressive": "true", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,20,20,20", - "clue_level": "1", - "range_level": "1", - "attack_level": "76" - }, - { - "examine": "Eek! A werewolf!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6015", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Eek! A werewolf!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6016", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Eek! A werewolf!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6017", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Eek! A werewolf!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6018", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "45" - }, - { - "melee_animation": "6536", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6538", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "6019", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Eek! A werewolf!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6020", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Eek! A werewolf!", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6021", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "45" - }, - { - "melee_animation": "6536", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6538", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "6022", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "6536", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6538", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "6023", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "6536", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6538", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "6024", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "6536", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "6538", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "100", - "strength_level": "1", - "id": "6025", - "aggressive": "true", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Boris", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6026", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Imre", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6027", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Yuri", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6028", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Joseph", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6029", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Nikolai", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6030", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Eduard", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6031", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Lev", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6032", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "melee_animation": "422", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Georgy", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "6033", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "836", - "name": "Svetlana", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6034", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Irina", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6035", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Alexis", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6036", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Milla", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6037", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Galina", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6038", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Sofiya", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6039", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Ksenia", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6040", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Yadviga", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6041", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Nikita", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6042", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Vera", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6043", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Zoja", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6044", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "death_animation": "836", - "name": "Liliya", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "melee_animation": "422", - "strength_level": "1", - "id": "6045", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "melee_animation": "6559", - "combat_audio": "909,912,911", - "respawn_delay": "60", - "defence_animation": "6557", - "slayer_exp": "74", - "death_animation": "6558", - "name": "Big Wolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "6046", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A vicious mountain wolf.", - "melee_animation": "6579", - "range_animation": "6579", - "combat_audio": "909,912,911", - "attack_speed": "6", - "defence_animation": "6578", - "slayer_exp": "34", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Wolf", - "defence_level": "22", - "safespot": null, - "lifepoints": "69", - "strength_level": "1", - "id": "6047", - "aggressive": "true", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Now it has no armour", - "range_animation": "0", - "combat_audio": "481,491,490", - "magic_level": "95", - "defence_animation": "0", - "weakness": "10", - "slayer_exp": "34", - "magic_animation": "0", - "name": "Wolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "157", - "strength_level": "95", - "id": "6048", - "aggressive": "true", - "range_level": "95", - "attack_level": "95" - }, - { - "examine": "A big coward. Thok mocks scaredy man.", - "combat_audio": "481,491,490", - "magic_level": "75", - "defence_animation": "0", - "weakness": "10", - "slayer_exp": "34", - "magic_animation": "0", - "name": "Wolf", - "defence_level": "75", - "safespot": null, - "lifepoints": "100", - "strength_level": "75", - "id": "6049", - "aggressive": "true", - "range_level": "75", - "attack_level": "75" - }, - { - "examine": "A vicious desert wolf.", - "slayer_task": "92", - "melee_animation": "6579", - "range_animation": "6579", - "attack_speed": "5", - "defence_animation": "6578", - "weakness": "9", - "magic_animation": "6579", - "death_animation": "6558", - "name": "Desert Wolf", - "defence_level": "5", - "safespot": null, - "lifepoints": "55", - "strength_level": "20", - "id": "6050", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "A vicious desert wolf.", - "melee_animation": "6579", - "range_animation": "6579", - "attack_speed": "5", - "defence_animation": "6578", - "magic_animation": "6579", - "death_animation": "6558", - "name": "Desert Wolf", - "defence_level": "5", - "safespot": null, - "lifepoints": "55", - "strength_level": "20", - "id": "6051", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "Not man's best friend.", - "melee_animation": "6559", - "respawn_delay": "60", - "defence_animation": "6557", - "death_animation": "6558", - "name": "Ice wolf", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "6052", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An impling who likes the word \"dragon\".", - "name": "Dragon impling", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "6054", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An impling who likes the word \"dragon.\"", - "name": "Dragon impling", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "6064", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She tends the wheat.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy Aeryka", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6072", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a little lost.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wandering impling", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6073", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An angry little imp. Grrr.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Imp defender", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6074", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A one-eyed man eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "4651", - "weakness": "8", - "slayer_exp": "75", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "35", - "safespot": null, - "lifepoints": "75", - "strength_level": "65", - "id": "6078", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A one-eyed woman eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "4651", - "weakness": "1", - "slayer_exp": "100", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "65", - "safespot": null, - "lifepoints": "100", - "strength_level": "65", - "id": "6079", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A one-eyed man eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "4651", - "weakness": "8", - "slayer_exp": "75", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "35", - "safespot": null, - "lifepoints": "75", - "strength_level": "65", - "id": "6080", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A one-eyed woman eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "4651", - "weakness": "1", - "slayer_exp": "100", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "65", - "safespot": null, - "lifepoints": "100", - "strength_level": "65", - "id": "6081", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "Overgrown undead vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "4935", - "name": "Zombie rat", - "defence_level": "2", - "safespot": null, - "lifepoints": "2", - "strength_level": "2", - "id": "6088", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "Overgrown undead vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "4935", - "name": "Zombie rat", - "defence_level": "2", - "safespot": null, - "lifepoints": "2", - "strength_level": "2", - "id": "6089", - "range_level": "1", - "attack_level": "2" - }, - { - "examine": "Overgrown undead vermin.", - "slayer_task": "67", - "melee_animation": "4933", - "range_animation": "0", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "4935", - "name": "Zombie rat", - "defence_level": "2", - "safespot": null, - "lifepoints": "2", - "strength_level": "2", - "id": "6090", - "range_level": "1", - "attack_level": "2" - }, - { - "melee_animation": "5540", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5541", - "slayer_exp": "25", - "death_animation": "5542", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6094", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6095", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6096", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6097", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5532", - "combat_audio": "436,439,438", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5533", - "slayer_exp": "25", - "death_animation": "5534", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6098", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5571", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5574", - "slayer_exp": "30", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "6099", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5571", - "combat_audio": "931,923,922", - "respawn_delay": "60", - "defence_animation": "5574", - "slayer_exp": "30", - "death_animation": "5575", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "6100", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Lesser, but still pretty big.", - "slayer_task": "56", - "melee_animation": "4630", - "range_animation": "4630", - "combat_audio": "400,404,403", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "30", - "defence_animation": "65", - "weakness": "4", - "slayer_exp": "79", - "magic_animation": "4630", - "death_animation": "67", - "name": "Lesser demon", - "defence_level": "71", - "safespot": null, - "lifepoints": "79", - "strength_level": "70", - "id": "6101", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "His face is expressionless.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Lost barbarian", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "6102", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Probably not a chicken.", - "slayer_task": "7", - "melee_animation": "6811", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "6812", - "name": "Entrana firebird", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "strength_level": "1", - "id": "6108", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "These gnomes know how to get around!", - "slayer_task": "7", - "melee_animation": "6790", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "6791", - "name": "Mounted terrorbird gnome", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "38", - "id": "6109", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "These gnomes know how to get around!", - "melee_animation": "6790", - "respawn_delay": "60", - "defence_animation": "6792", - "death_animation": "6791", - "name": "Mounted terrorbird gnome", - "defence_level": "1", - "safespot": null, - "lifepoints": "55", - "strength_level": "1", - "id": "6110", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "These gnomes know how to get around!", - "melee_animation": "6790", - "respawn_delay": "60", - "defence_animation": "6792", - "death_animation": "6791", - "name": "Mounted terrorbird gnome", - "defence_level": "1", - "safespot": null, - "lifepoints": "55", - "strength_level": "1", - "id": "6111", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aww, cute.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ducklings", - "defence_level": "1", - "water_npc": "true", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6112", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Quackers.", - "melee_animation": "747", - "respawn_delay": "60", - "defence_animation": "3268", - "death_animation": "750", - "name": "Duck", - "defence_level": "1", - "safespot": null, - "lifepoints": "3", - "strength_level": "1", - "id": "6113", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A messy bird.", - "slayer_task": "7", - "melee_animation": "3467", - "range_animation": "3467", - "combat_audio": "309,311,310", - "attack_speed": "5", - "defence_animation": "1014", - "weakness": "6", - "magic_animation": "3467", - "death_animation": "3468", - "name": "Seagull", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "6115", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A messy bird.", - "melee_animation": "3467", - "range_animation": "3467", - "combat_audio": "309,311,310", - "attack_speed": "5", - "defence_animation": "1014", - "magic_animation": "3467", - "death_animation": "3468", - "name": "Seagull", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "6116", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Do not upset this teacher. You have been warned!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mr. Mordaut", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6117", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He helps the professor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Observatory assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6118", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sleeping like an ugly baby.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Sleeping guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6122", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An old goblin hag.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Naghead", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6123", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A young goblin 'beauty'.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wagchin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6124", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6125", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6126", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Big appetite for a small creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Greasycheeks", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6127", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Likes drink a little too much.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Smellytoes", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6128", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Lean and green.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Creakyknees", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6129", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "30", - "name": "Zombie", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "combat_audio": "931,923,922", - "strength_level": "1", - "id": "6131", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6132", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6133", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This imp is clearly the class clown.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dunce", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6134", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Get useful information from this guy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Town crier", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6135", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire (Intermediate)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6140", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A squire of balance.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire (Veteran)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6141", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "50", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6142", - "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "25", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "50", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6143", - "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "50", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6144", - "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "50", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6145", - "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6146", - "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "15", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6147", - "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6148", - "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "200", - "strength_level": "1", - "id": "6149", - "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "70", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6150", - "bonuses": "150,150,150,75,75,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "70", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6151", - "bonuses": "150,150,150,150,37,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "70", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6152", - "bonuses": "150,150,75,150,75,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "70", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "70", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6153", - "bonuses": "75,75,150,150,75,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6154", - "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "15", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6155", - "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6156", - "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "6157", - "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It is cold and solid. Thok will strap it to Marmaros's leg.", - "range_animation": "0", - "magic_level": "50", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Workman", - "defence_level": "65", - "safespot": null, - "lifepoints": "114", - "strength_level": "50", - "id": "6159", - "aggressive": "true", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "Squire to the Knights of the Round Table.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Squire", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6169", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "400", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "422", - "death_animation": "836", - "name": "Sir Lancelot", - "defence_level": "1", - "safespot": null, - "lifepoints": "118", - "strength_level": "1", - "id": "6170", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An officer of the law.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6183", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An officer of the law.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6184", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He isn't very friendly.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "0", - "name": "Renegade knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6188", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dark-hearted knight.", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "2503,15,512", - "attack_speed": "5", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Black Knight", - "defence_level": "25", - "safespot": null, - "lifepoints": "42", - "strength_level": "25", - "id": "6189", - "aggressive": "true", - "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "Primping with combs and hair clips.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6190", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The name isn't just for show.", - "range_animation": "0", - "magic_level": "55", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Sinclair", - "defence_level": "55", - "safespot": null, - "lifepoints": "85", - "strength_level": "55", - "id": "6198", - "aggressive": "true", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "He can look after my money.", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6200", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Knight", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6201", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A servant of the god Zamorak. ", - "slayer_task": "40", - "melee_animation": "6945", - "attack_speed": "6", - "poisonous": "true", - "respawn_delay": "150", - "weakness": "9", - "slayer_exp": "350", - "poison_amount": "16", - "magic_animation": "6945", - "death_animation": "6946", - "lifepoints": "255", - "id": "6203", - "aggressive": "true", - "bonuses": "160,160,160,0,0,80,80,80,130,80,0,31,0,0,0", - "agg_radius": "64", - "range_animation": "6945", - "magic_level": "200", - "defence_animation": "6944", - "name": "K'ril Tsutsaroth", - "defence_level": "270", - "poison_immune": "true", - "safespot": null, - "strength_level": "300", - "clue_level": "2", - "range_level": "1", - "attack_level": "340" - }, - { - "agg_radius": "64", - "examine": "Destroyer of 1000 planes!", - "slayer_task": "40", - "melee_animation": "6945", - "range_animation": "6945", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "50", - "defence_animation": "6944", - "weakness": "9", - "slayer_exp": "142", - "magic_animation": "6945", - "death_animation": "6946", - "name": "Tstanon Karlak", - "defence_level": "125", - "safespot": null, - "lifepoints": "142", - "strength_level": "118", - "id": "6204", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,-5,0,0,14,0,0,0", - "range_level": "50", - "attack_level": "124" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6205", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Scourge of light.", - "slayer_task": "56", - "start_gfx": "1208", - "combat_style": "1", - "melee_animation": "7033", - "attack_speed": "5", - "respawn_delay": "50", - "weakness": "0", - "slayer_exp": "150", - "magic_animation": "7033", - "death_animation": "6946", - "lifepoints": "150", - "id": "6206", - "aggressive": "true", - "bonuses": "0,0,0,0,20,0,0,0,-5,0,0,0,0,0,20", - "agg_radius": "64", - "range_animation": "7033", - "magic_level": "50", - "defence_animation": "6945", - "name": "Zakl'n Gritch", - "defence_level": "127", - "safespot": null, - "strength_level": "76", - "range_level": "150", - "projectile": "1209", - "attack_level": "83" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6207", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "Despoiler of Ullek.", - "start_gfx": "1212", - "combat_style": "2", - "melee_animation": "7033", - "range_animation": "7033", - "attack_speed": "5", - "magic_level": "150", - "respawn_delay": "50", - "defence_animation": "6944", - "slayer_exp": "161", - "magic_animation": "7033", - "death_animation": "6946", - "name": "Balfrug Kreeyath", - "defence_level": "153", - "safespot": null, - "lifepoints": "161", - "strength_level": "60", - "id": "6208", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,10,0,0,0,0,0,0", - "range_level": "1", - "projectile": "1213", - "attack_level": "115" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6209", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "From the maws of hell.", - "slayer_task": "43", - "melee_animation": "6579", - "range_animation": "6579", - "combat_audio": "3717,3719,3718", - "attack_speed": "4", - "respawn_delay": "50", - "defence_animation": "6578", - "weakness": "7", - "slayer_exp": "116", - "magic_animation": "6579", - "death_animation": "6576", - "name": "Hellhound", - "defence_level": "102", - "safespot": null, - "lifepoints": "116", - "strength_level": "104", - "id": "6210", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "105" - }, - { - "examine": "Have you checked your pockets lately?", - "melee_animation": "169", - "range_animation": "169", - "combat_audio": "534,536,535", - "defence_animation": "170", - "weakness": "7", - "magic_animation": "169", - "death_animation": "172", - "name": "Imp", - "defence_level": "4", - "safespot": null, - "movement_radius": "25", - "lifepoints": "10", - "strength_level": "4", - "id": "6211", - "aggressive": "true", - "bonuses": "10,5,5,10,10,10,10,10,10,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "4" - }, - { - "examine": "He doesn't look pleased to see me.", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "respawn_delay": "25", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "64", - "safespot": null, - "lifepoints": "100", - "strength_level": "64", - "id": "6212", - "aggressive": "true", - "bonuses": "50,40,45,60,70,70,70,40,40,50,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "He doesn't look pleased to see me.", - "slayer_task": "91", - "melee_animation": "6536", - "range_animation": "6536", - "respawn_delay": "25", - "defence_animation": "6538", - "weakness": "7", - "magic_animation": "6536", - "death_animation": "6537", - "name": "Werewolf", - "defence_level": "64", - "safespot": null, - "lifepoints": "100", - "strength_level": "64", - "id": "6213", - "aggressive": "true", - "bonuses": "50,40,45,60,70,70,70,40,40,50,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "It looks really hungry!", - "melee_animation": "810", - "range_animation": "810", - "respawn_delay": "25", - "defence_animation": "404", - "magic_animation": "810", - "death_animation": "9055", - "name": "Vampire", - "defence_level": "44", - "safespot": null, - "lifepoints": "60", - "strength_level": "44", - "id": "6214", - "aggressive": "true", - "bonuses": "30,35,30,40,50,50,50,25,30,30,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "44" - }, - { - "examine": "The tongue of evil.", - "melee_animation": "9130", - "range_animation": "1552", - "combat_audio": "312,314,313", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "9132", - "slayer_exp": "120", - "magic_animation": "1552", - "death_animation": "9131", - "name": "Bloodveld", - "defence_level": "30", - "safespot": null, - "lifepoints": "120", - "strength_level": "45", - "id": "6215", - "aggressive": "true", - "clue_level": "2", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "A small fire demon.", - "slayer_task": "66", - "melee_animation": "1582", - "range_animation": "1582", - "combat_audio": "696,698,697", - "respawn_delay": "25", - "defence_animation": "1581", - "weakness": "7", - "magic_animation": "1582", - "death_animation": "1580", - "name": "Pyrefiend", - "defence_level": "25", - "safespot": null, - "lifepoints": "48", - "strength_level": "25", - "id": "6216", - "aggressive": "true", - "bonuses": "25,25,20,40,40,40,15,30,20,60,20,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "A small ice demon.", - "melee_animation": "8080", - "range_animation": "8080", - "combat_audio": "531,533,532", - "respawn_delay": "25", - "defence_animation": "8079", - "magic_animation": "8080", - "death_animation": "8078", - "name": "Icefiend", - "defence_level": "5", - "safespot": null, - "lifepoints": "15", - "strength_level": "5", - "id": "6217", - "bonuses": "5,5,5,5,10,10,10,10,10,10,5,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "Those horns look pretty sharp...", - "slayer_task": "39", - "melee_animation": "4300", - "range_animation": "4300", - "respawn_delay": "25", - "defence_animation": "4301", - "weakness": "9", - "slayer_exp": "112", - "magic_animation": "4300", - "death_animation": "4302", - "name": "Gorak", - "defence_level": "70", - "safespot": null, - "lifepoints": "112", - "strength_level": "70", - "id": "6218", - "aggressive": "true", - "bonuses": "30,30,50,70,40,70,70,50,60,55,0,0,0,0,0", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "Warrior of Zamorak.", - "slayer_task": "79", - "melee_animation": "390", - "range_animation": "390", - "attack_speed": "5", - "respawn_delay": "25", - "defence_animation": "1156", - "weakness": "6", - "magic_animation": "390", - "death_animation": "9055", - "name": "Spiritual warrior", - "defence_level": "66", - "safespot": null, - "lifepoints": "102", - "strength_level": "66", - "id": "6219", - "aggressive": "true", - "bonuses": "40,60,60,60,60,20,50,55,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "66" - }, - { - "examine": "A ranger spirit dedicated to Zamorak.", - "slayer_task": "78", - "start_gfx": "18", - "combat_style": "1", - "start_height": "96", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "25", - "defence_animation": "404", - "weakness": "1", - "magic_animation": "426", - "death_animation": "9055", - "name": "Spiritual ranger", - "defence_level": "70", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "6220", - "aggressive": "true", - "bonuses": "50,70,50,50,50,70,50,85,85,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "70", - "projectile": "9", - "attack_level": "1" - }, - { - "examine": "A deadly servant of Zamorak.", - "slayer_task": "77", - "combat_style": "2", - "melee_animation": "811", - "attack_speed": "5", - "respawn_delay": "25", - "weakness": "3", - "magic_animation": "811", - "death_animation": "9055", - "lifepoints": "75", - "id": "6221", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_animation": "811", - "magic_level": "180", - "end_gfx": "78", - "defence_animation": "404", - "end_height": "0", - "name": "Spiritual mage", - "defence_level": "61", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "78", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "Graceful avatar of Armadyl.", - "melee_animation": "6977", - "range_animation": "6977", - "attack_speed": "3", - "magic_level": "200", - "respawn_delay": "150", - "defence_animation": "6974", - "weakness": "10", - "slayer_exp": "357", - "magic_animation": "6977", - "death_animation": "6975", - "name": "Kree'arra", - "defence_level": "260", - "poison_immune": "true", - "safespot": null, - "lifepoints": "255", - "strength_level": "200", - "id": "6222", - "aggressive": "true", - "bonuses": "136,136,136,0,120,180,180,180,200,200,0,12,0,0,0", - "clue_level": "2", - "range_level": "380", - "attack_level": "300" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "2", - "melee_animation": "6952", - "attack_speed": "5", - "respawn_delay": "50", - "weakness": "3", - "slayer_exp": "124", - "magic_animation": "6952", - "death_animation": "6956", - "lifepoints": "121", - "id": "6223", - "aggressive": "true", - "bonuses": "45,45,45,0,0,0,0,0,0,0,0,25,0,0,0", - "prj_height": "92", - "agg_radius": "64", - "range_animation": "6952", - "magic_level": "150", - "defence_animation": "6955", - "name": "Wingman Skree", - "defence_level": "160", - "poison_immune": "false", - "safespot": null, - "strength_level": "50", - "range_level": "100", - "projectile": "1199", - "attack_level": "80" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6224", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "attack_speed": "5", - "respawn_delay": "50", - "weakness": "4", - "slayer_exp": "133", - "magic_animation": "6953", - "death_animation": "6956", - "lifepoints": "132", - "id": "6225", - "aggressive": "true", - "bonuses": "0,0,0,0,60,0,0,0,0,0,0,0,0,0,0", - "prj_height": "92", - "agg_radius": "64", - "range_animation": "6953", - "magic_level": "50", - "defence_animation": "6955", - "name": "Flockleader Geerin", - "defence_level": "175", - "poison_immune": "false", - "safespot": null, - "strength_level": "80", - "range_level": "150", - "projectile": "1190", - "attack_level": "80" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6226", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "Graceful, bird-like creature.", - "melee_animation": "6954", - "range_animation": "6954", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "50", - "defence_animation": "6955", - "weakness": "6", - "slayer_exp": "133", - "magic_animation": "6954", - "death_animation": "6956", - "name": "Flight Kilisa", - "defence_level": "175", - "safespot": null, - "lifepoints": "133", - "strength_level": "118", - "id": "6227", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,14,0,0,0", - "range_level": "169", - "attack_level": "124" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6228", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A servant of Armadyl.", - "slayer_task": "79", - "combat_style": "1", - "melee_animation": "6954", - "range_animation": "6954", - "respawn_delay": "25", - "defence_animation": "6955", - "weakness": "6", - "magic_animation": "6954", - "death_animation": "6956", - "name": "Spiritual warrior", - "defence_level": "70", - "safespot": null, - "lifepoints": "98", - "strength_level": "70", - "id": "6229", - "aggressive": "true", - "bonuses": "40,40,50,50,20,50,50,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "68", - "attack_level": "70" - }, - { - "examine": "Armadyl's favourite servant.", - "slayer_task": "78", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "weakness": "4", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Spiritual ranger", - "defence_level": "70", - "safespot": null, - "lifepoints": "89", - "strength_level": "1", - "id": "6230", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "70", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "A mage who serves Armadyl above all else - even death.", - "slayer_task": "77", - "combat_style": "2", - "melee_animation": "6952", - "attack_speed": "5", - "respawn_delay": "25", - "weakness": "4", - "magic_animation": "6952", - "death_animation": "6956", - "lifepoints": "75", - "id": "6231", - "aggressive": "true", - "bonuses": "0,0,0,0,0,9,12,5,45,28,0,0,0,0,0", - "prj_height": "92", - "range_animation": "6952", - "magic_level": "150", - "defence_animation": "6955", - "name": "Spiritual mage", - "defence_level": "111", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "1199", - "attack_level": "1" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "6232", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "40", - "projectile": "1191", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "45", - "safespot": null, - "lifepoints": "83", - "strength_level": "1", - "id": "6233", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "45", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "50", - "safespot": null, - "lifepoints": "86", - "strength_level": "1", - "id": "6234", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "50", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "50", - "safespot": null, - "lifepoints": "86", - "strength_level": "1", - "id": "6235", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "50", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "55", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "id": "6236", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "55", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "55", - "safespot": null, - "lifepoints": "98", - "strength_level": "1", - "id": "6237", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "55", - "projectile": "1191", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "65", - "safespot": null, - "lifepoints": "124", - "strength_level": "1", - "id": "6238", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "65", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "65", - "safespot": null, - "lifepoints": "139", - "strength_level": "1", - "id": "6239", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "65", - "projectile": "1191", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "40", - "safespot": null, - "lifepoints": "63", - "strength_level": "1", - "id": "6240", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "40", - "projectile": "1191", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "40", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "6241", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "40", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "40", - "safespot": null, - "lifepoints": "83", - "strength_level": "1", - "id": "6242", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "40", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "50", - "safespot": null, - "lifepoints": "69", - "strength_level": "1", - "id": "6243", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "50", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "55", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "6244", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "55", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "55", - "safespot": null, - "lifepoints": "98", - "strength_level": "1", - "id": "6245", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "55", - "projectile": "1190", - "attack_level": "1", - "prj_height": "92" - }, - { - "examine": "Graceful, bird-like creature.", - "combat_style": "1", - "melee_animation": "6953", - "range_animation": "6953", - "respawn_delay": "25", - "defence_animation": "6955", - "magic_animation": "6953", - "death_animation": "6956", - "name": "Aviansie", - "defence_level": "65", - "safespot": null, - "lifepoints": "73", - "strength_level": "1", - "id": "6246", - "aggressive": "true", - "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "65", - "projectile": "1191", - "attack_level": "1", - "prj_height": "92" - }, - { - "agg_radius": "64", - "examine": "Commander of Saradomin's forces. ", - "melee_animation": "6964", - "range_animation": "6964", - "attack_speed": "2", - "magic_level": "300", - "respawn_delay": "150", - "defence_animation": "6966", - "weakness": "7", - "slayer_exp": "360", - "magic_animation": "6964", - "death_animation": "6965", - "name": "Commander Zilyana", - "defence_level": "300", - "poison_immune": "true", - "safespot": null, - "lifepoints": "255", - "strength_level": "196", - "id": "6247", - "aggressive": "true", - "bonuses": "195,195,195,200,0,100,100,100,100,100,0,20,0,0,0", - "clue_level": "2", - "range_level": "250", - "attack_level": "280" - }, - { - "agg_radius": "64", - "examine": "The bane of darkness.", - "melee_animation": "6376", - "range_animation": "6376", - "combat_audio": "3829,3866,3849", - "attack_speed": "5", - "magic_level": "125", - "respawn_delay": "50", - "defence_animation": "6375", - "weakness": "7", - "slayer_exp": "0", - "magic_animation": "6376", - "death_animation": "6377", - "name": "Starlight", - "defence_level": "120", - "poison_immune": "false", - "safespot": null, - "lifepoints": "160", - "strength_level": "125", - "id": "6248", - "aggressive": "true", - "bonuses": "60,60,60,0,0,12,14,13,5,13,0,10,0,0,0", - "range_level": "1", - "attack_level": "120" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6249", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Defender of the faithful.", - "start_gfx": "1184", - "combat_style": "2", - "melee_animation": "7019", - "attack_speed": "5", - "respawn_delay": "50", - "slayer_exp": "0", - "magic_animation": "7019", - "death_animation": "7016", - "lifepoints": "146", - "id": "6250", - "aggressive": "true", - "bonuses": "10,10,10,0,0,12,14,14,18,5,0,7,0,0,0", - "prj_height": "0", - "agg_radius": "64", - "range_animation": "7019", - "combat_audio": "3830,3869,3867", - "magic_level": "150", - "end_gfx": "1186", - "defence_animation": "7017", - "name": "Growler", - "defence_level": "120", - "safespot": null, - "strength_level": "101", - "range_level": "1", - "projectile": "1185", - "attack_level": "100" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6251", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Champion of Truth.", - "combat_style": "1", - "melee_animation": "7009", - "attack_speed": "5", - "respawn_delay": "50", - "weakness": "0", - "slayer_exp": "0", - "magic_animation": "7009", - "death_animation": "7011", - "lifepoints": "162", - "id": "6252", - "aggressive": "true", - "bonuses": "10,10,10,0,0,12,14,14,18,5,0,7,0,0,0", - "prj_height": "50", - "agg_radius": "64", - "range_animation": "7009", - "magic_level": "80", - "end_gfx": "24", - "defence_animation": "7010", - "name": "Bree", - "defence_level": "130", - "safespot": null, - "strength_level": "80", - "range_level": "150", - "projectile": "1188", - "attack_level": "110" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6253", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man wearing ancient clothing.", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "poisonous": "true", - "magic_level": "60", - "respawn_delay": "25", - "end_gfx": "76", - "defence_animation": "404", - "weakness": "3", - "magic_animation": "811", - "death_animation": "9055", - "name": "Saradomin priest", - "defence_level": "60", - "safespot": null, - "lifepoints": "89", - "strength_level": "1", - "id": "6254", - "aggressive": "true", - "bonuses": "40,40,40,40,20,50,40,55,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Warrior of Saradomin.", - "slayer_task": "79", - "melee_animation": "390", - "range_animation": "390", - "attack_speed": "5", - "respawn_delay": "25", - "defence_animation": "1156", - "weakness": "8", - "magic_animation": "390", - "death_animation": "9055", - "name": "Spiritual warrior", - "defence_level": "66", - "safespot": null, - "lifepoints": "100", - "strength_level": "66", - "id": "6255", - "aggressive": "true", - "bonuses": "40,60,60,60,60,20,50,45,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "66" - }, - { - "examine": "A ranger spirit dedicated to Saradomin.", - "slayer_task": "78", - "start_gfx": "18", - "combat_style": "1", - "start_height": "96", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "25", - "defence_animation": "404", - "weakness": "0", - "magic_animation": "426", - "death_animation": "9055", - "name": "Spiritual ranger", - "defence_level": "70", - "safespot": null, - "lifepoints": "106", - "strength_level": "1", - "id": "6256", - "aggressive": "true", - "bonuses": "50,70,50,50,50,70,50,65,65,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "70", - "projectile": "9", - "attack_level": "1" - }, - { - "examine": "Saradomin's holy mage.", - "slayer_task": "77", - "combat_style": "2", - "melee_animation": "811", - "attack_speed": "5", - "respawn_delay": "25", - "weakness": "4", - "magic_animation": "811", - "death_animation": "9055", - "lifepoints": "85", - "id": "6257", - "aggressive": "true", - "bonuses": "0,0,0,0,0,8,7,3,16,2,0,0,0,0,0", - "range_animation": "811", - "magic_level": "160", - "end_gfx": "76", - "defence_animation": "404", - "end_height": "0", - "name": "Spiritual mage", - "defence_level": "86", - "safespot": null, - "strength_level": "1", - "clue_level": "2", - "range_level": "1", - "projectile": "76", - "attack_level": "1" - }, - { - "examine": "A valiant knight.", - "melee_animation": "407", - "range_animation": "407", - "respawn_delay": "25", - "defence_animation": "410", - "weakness": "7", - "magic_animation": "407", - "death_animation": "9055", - "name": "Knight of Saradomin", - "defence_level": "50", - "safespot": null, - "lifepoints": "135", - "strength_level": "50", - "id": "6258", - "aggressive": "true", - "bonuses": "40,40,40,40,50,20,40,50,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A valiant knight.", - "melee_animation": "401", - "range_animation": "401", - "respawn_delay": "25", - "defence_animation": "424", - "weakness": "7", - "magic_animation": "401", - "death_animation": "9055", - "name": "Knight of Saradomin", - "defence_level": "50", - "safespot": null, - "lifepoints": "108", - "strength_level": "50", - "id": "6259", - "aggressive": "true", - "bonuses": "40,40,40,40,50,20,40,65,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "agg_radius": "64", - "examine": "A huge war chief.", - "melee_animation": "7060", - "range_animation": "7060", - "attack_speed": "6", - "magic_level": "280", - "respawn_delay": "150", - "defence_animation": "7061", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7060", - "death_animation": "7062", - "name": "General Graardor", - "defence_level": "250", - "poison_immune": "true", - "safespot": null, - "lifepoints": "255", - "strength_level": "350", - "id": "6260", - "aggressive": "true", - "bonuses": "120,120,120,0,100,90,90,90,65,90,0,43,0,0,0", - "clue_level": "2", - "range_level": "350", - "attack_level": "280" - }, - { - "agg_radius": "64", - "examine": "A battle-honed goblin. ", - "slayer_task": "38", - "melee_animation": "6154", - "range_animation": "6154", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "50", - "defence_animation": "6155", - "weakness": "8", - "magic_animation": "6154", - "death_animation": "6156", - "name": "Sergeant Strongstack", - "defence_level": "126", - "safespot": null, - "lifepoints": "128", - "strength_level": "118", - "id": "6261", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,14,0,0,0", - "range_level": "50", - "attack_level": "124" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6262", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A battle-honed goblin. ", - "slayer_task": "38", - "start_gfx": "1202", - "combat_style": "2", - "melee_animation": "6154", - "attack_speed": "5", - "respawn_delay": "50", - "weakness": "3", - "magic_animation": "6154", - "death_animation": "6156", - "lifepoints": "127", - "id": "6263", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,6,0,0,0", - "agg_radius": "64", - "range_animation": "6154", - "magic_level": "150", - "defence_animation": "6155", - "name": "Sergeant Steelwill", - "defence_level": "150", - "safespot": null, - "strength_level": "50", - "range_level": "1", - "projectile": "1203", - "attack_level": "80" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6264", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "A battle-honed goblin. ", - "slayer_task": "38", - "combat_style": "1", - "melee_animation": "6154", - "range_animation": "6154", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "50", - "defence_animation": "6155", - "weakness": "2", - "magic_animation": "6154", - "death_animation": "6156", - "name": "Sergeant Grimspike", - "defence_level": "132", - "safespot": null, - "lifepoints": "146", - "strength_level": "80", - "id": "6265", - "aggressive": "true", - "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,20", - "range_level": "150", - "projectile": "1206", - "attack_level": "80" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6266", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Big, ugly, and smelly.", - "melee_animation": "359", - "range_animation": "359", - "attack_speed": "6", - "magic_level": "27", - "respawn_delay": "25", - "defence_animation": "360", - "magic_animation": "359", - "death_animation": "361", - "name": "Fishing spot", - "defence_level": "27", - "safespot": null, - "lifepoints": "60", - "strength_level": "27", - "id": "6267", - "aggressive": "true", - "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", - "range_level": "27", - "attack_level": "27" - }, - { - "examine": "Green and aggressive.", - "melee_animation": "2936", - "range_animation": "2936", - "attack_speed": "6", - "respawn_delay": "25", - "defence_animation": "2937", - "weakness": "8", - "magic_animation": "2936", - "death_animation": "2938", - "name": "Jogre", - "defence_level": "62", - "safespot": null, - "lifepoints": "70", - "strength_level": "62", - "id": "6268", - "aggressive": "true", - "bonuses": "10,20,20,20,20,20,10,20,0,0,0,0,0,0,0", - "clue_level": "1", - "range_level": "1", - "attack_level": "62" - }, - { - "examine": "A one-eyed man-eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "4651", - "weakness": "8", - "slayer_exp": "110", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "48", - "safespot": null, - "lifepoints": "110", - "strength_level": "70", - "id": "6269", - "aggressive": "true", - "bonuses": "22,22,22,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "A one-eyed man-eater.", - "slayer_task": "44", - "melee_animation": "4652", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "25", - "defence_animation": "4651", - "weakness": "8", - "slayer_exp": "110", - "magic_animation": "0", - "death_animation": "4653", - "name": "Cyclops", - "defence_level": "48", - "safespot": null, - "lifepoints": "110", - "strength_level": "70", - "id": "6270", - "aggressive": "true", - "bonuses": "22,22,22,0,0,0,0,0,0,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Ugly, fierce and with a bad attitude.", - "melee_animation": "4320", - "range_animation": "4320", - "respawn_delay": "25", - "defence_animation": "4322", - "weakness": "8", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Ork", - "defence_level": "68", - "safespot": null, - "lifepoints": "110", - "strength_level": "68", - "id": "6271", - "aggressive": "true", - "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Ugly, fierce and with a bad attitude.", - "melee_animation": "4320", - "range_animation": "4320", - "respawn_delay": "25", - "defence_animation": "4322", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Ork", - "defence_level": "68", - "safespot": null, - "lifepoints": "110", - "strength_level": "68", - "id": "6272", - "aggressive": "true", - "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Ugly, fierce and with a bad attitude.", - "melee_animation": "4320", - "range_animation": "4320", - "respawn_delay": "25", - "defence_animation": "4322", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Ork", - "defence_level": "68", - "safespot": null, - "lifepoints": "110", - "strength_level": "68", - "id": "6273", - "aggressive": "true", - "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "Ugly, fierce and with a bad attitude.", - "melee_animation": "4320", - "range_animation": "4320", - "respawn_delay": "25", - "defence_animation": "4322", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Ork", - "defence_level": "68", - "safespot": null, - "lifepoints": "110", - "strength_level": "68", - "id": "6274", - "aggressive": "true", - "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", - "range_level": "1", - "attack_level": "68" - }, - { - "examine": "An ugly, smelly creature.", - "slayer_task": "45", - "melee_animation": "164", - "range_animation": "164", - "combat_audio": "469,472,471", - "respawn_delay": "25", - "defence_animation": "165", - "weakness": "8", - "magic_animation": "164", - "death_animation": "167", - "name": "Hobgoblin", - "defence_level": "40", - "safespot": null, - "lifepoints": "52", - "strength_level": "40", - "id": "6275", - "aggressive": "true", - "bonuses": "20,30,30,30,30,30,10,30,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "The spirit of a ranger, serving bandos beyond death.", - "slayer_task": "78", - "start_gfx": "95", - "combat_style": "1", - "melee_animation": "4320", - "range_animation": "4320", - "respawn_delay": "25", - "defence_animation": "4322", - "weakness": "0", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Spiritual ranger", - "defence_level": "70", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "id": "6276", - "aggressive": "true", - "bonuses": "30,50,30,30,50,60,50,40,40,0,0,0,0,0,0", - "clue_level": "2", - "range_level": "70", - "projectile": "1195", - "attack_level": "1" - }, - { - "examine": "A true servant of Bandos.", - "slayer_task": "79", - "melee_animation": "4320", - "range_animation": "4320", - "respawn_delay": "25", - "defence_animation": "4322", - "weakness": "8", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Spiritual warrior", - "defence_level": "70", - "safespot": null, - "lifepoints": "131", - "strength_level": "70", - "id": "6277", - "aggressive": "true", - "bonuses": "50,40,45,60,60,60,60,20,50,60,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "70" - }, - { - "examine": "One of Bandos' chosen.", - "slayer_task": "77", - "combat_style": "2", - "melee_animation": "4320", - "range_animation": "4320", - "attack_speed": "5", - "magic_level": "142", - "respawn_delay": "25", - "defence_animation": "4322", - "weakness": "4", - "magic_animation": "4320", - "death_animation": "4321", - "name": "Spiritual mage", - "defence_level": "103", - "safespot": null, - "lifepoints": "106", - "strength_level": "1", - "id": "6278", - "aggressive": "true", - "bonuses": "0,0,0,0,0,12,14,13,35,13,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ancient goblin.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "respawn_delay": "25", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "5", - "safespot": null, - "lifepoints": "20", - "strength_level": "5", - "id": "6279", - "aggressive": "true", - "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "A warrior for Bandos.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "respawn_delay": "25", - "defence_animation": "6183", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "5", - "safespot": null, - "lifepoints": "15", - "strength_level": "5", - "id": "6280", - "aggressive": "true", - "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "A soldier to the death.", - "melee_animation": "6188", - "range_animation": "6188", - "combat_audio": "469,472,471", - "respawn_delay": "25", - "defence_animation": "6189", - "magic_animation": "6188", - "death_animation": "6190", - "name": "Goblin", - "defence_level": "5", - "safespot": null, - "lifepoints": "15", - "strength_level": "5", - "id": "6281", - "aggressive": "true", - "bonuses": "5,10,10,10,10,10,5,10,5,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "A soldier to the death.", - "melee_animation": "6188", - "range_animation": "6188", - "combat_audio": "469,472,471", - "respawn_delay": "25", - "defence_animation": "6189", - "magic_animation": "6188", - "death_animation": "6190", - "name": "Goblin", - "defence_level": "5", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "6282", - "aggressive": "true", - "bonuses": "5,10,10,10,10,10,5,10,5,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "A warrior for Bandos.", - "melee_animation": "6185", - "range_animation": "6185", - "combat_audio": "469,472,471", - "respawn_delay": "25", - "defence_animation": "6183", - "slayer_exp": "16", - "magic_animation": "6185", - "death_animation": "6182", - "name": "Goblin", - "defence_level": "5", - "safespot": null, - "lifepoints": "16", - "strength_level": "5", - "id": "6283", - "aggressive": "true", - "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "5" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6285", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6286", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6287", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6288", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6289", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6290", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6291", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "168", - "strength_level": "59", - "id": "6292", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6293", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "308", - "strength_level": "59", - "id": "6294", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this terrorbird.", - "slayer_task": "88", - "combat_style": "1", - "melee_animation": "7108", - "range_animation": "0", - "magic_level": "59", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "59", - "safespot": null, - "lifepoints": "308", - "strength_level": "59", - "id": "6295", - "aggressive": "true", - "range_level": "59", - "projectile": "1468", - "attack_level": "59" - }, - { - "examine": "You don't think you can harm this creature.", - "slayer_task": "89", - "melee_animation": "7093", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "52", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "7091", - "name": "Warped tortoise", - "defence_level": "52", - "safespot": null, - "lifepoints": "148", - "strength_level": "39", - "id": "6296", - "range_level": "1", - "attack_level": "39" - }, - { - "melee_animation": "7093", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "7092", - "death_animation": "7091", - "name": "Warped tortoise", - "defence_level": "1", - "safespot": null, - "lifepoints": "87", - "strength_level": "1", - "id": "6297", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Annoyingly easy to squish.", - "slayer_task": "73", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "2", - "defence_animation": "0", - "magic_animation": "0", - "name": "Bolrie", - "defence_level": "2", - "safespot": null, - "lifepoints": "0", - "strength_level": "1", - "id": "6306", - "aggressive": "true", - "range_level": "2", - "attack_level": "1" - }, - { - "examine": "She looks bored.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard no. 21", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6314", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks even more bored.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard no. 72", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6315", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6322", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6323", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6324", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6325", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6326", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6327", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6328", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6329", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6330", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6331", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7108", - "respawn_delay": "60", - "defence_animation": "7110", - "death_animation": "7109", - "name": "Warped terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "154", - "strength_level": "1", - "id": "6332", - "aggressive": "true", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6334", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6335", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6336", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6337", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6338", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A child of West Ardougne.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Child", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6339", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Duck!", - "combat_style": "1", - "melee_animation": "3920", - "range_animation": "3920", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "3922", - "name": "Child", - "defence_level": "65", - "safespot": null, - "lifepoints": "92", - "strength_level": "48", - "id": "6344", - "aggressive": "true", - "range_level": "65", - "attack_level": "48" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6346", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6347", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6348", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6349", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6350", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "6351", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "6352", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "6353", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "6354", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "6355", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "390", - "combat_audio": "703,705,704", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Pirate", - "defence_level": "1", - "safespot": null, - "lifepoints": "23", - "strength_level": "1", - "id": "6356", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The mother of all pests!", - "attack_speed": "6", - "magic_level": "70", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "0", - "name": "Street urchin", - "defence_level": "70", - "safespot": null, - "lifepoints": "1428", - "strength_level": "70", - "id": "6358", - "aggressive": "true", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "A warrior of Zamorak.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak warrior", - "defence_level": "44", - "safespot": null, - "lifepoints": "62", - "strength_level": "44", - "id": "6363", - "aggressive": "true", - "range_level": "1", - "attack_level": "44" - }, - { - "examine": "A warrior of Zamorak.", - "melee_animation": "390", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak warrior", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "47", - "id": "6364", - "aggressive": "true", - "range_level": "1", - "attack_level": "47" - }, - { - "examine": "A ranger of Zamorak.", - "combat_style": "1", - "melee_animation": "426", - "range_animation": "426", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak ranger", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "6365", - "aggressive": "true", - "range_level": "46", - "attack_level": "1" - }, - { - "examine": "A ranger of Zamorak.", - "melee_animation": "426", - "range_animation": "426", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak ranger", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "6366", - "aggressive": "true", - "range_level": "46", - "attack_level": "1" - }, - { - "examine": "A mage of Zamorak.", - "combat_style": "2", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "49", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak mage", - "defence_level": "49", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "6367", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A mage of Zamorak.", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "49", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak mage", - "defence_level": "49", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "6368", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A cave dweller.", - "melee_animation": "7207", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "7205", - "name": "Cave lizard", - "defence_level": "47", - "safespot": null, - "lifepoints": "67", - "strength_level": "1", - "id": "6369", - "aggressive": "true", - "range_level": "47", - "attack_level": "1" - }, - { - "examine": "A representative of the Z.M.I.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mage of Zamorak", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6370", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A Z.M.I. runecrafter.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Zamorak crafter", - "defence_level": "19", - "safespot": null, - "lifepoints": "27", - "strength_level": "19", - "id": "6371", - "range_level": "1", - "attack_level": "19" - }, - { - "death_animation": "836", - "name": "Zamorak crafter", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "melee_animation": "422", - "strength_level": "1", - "id": "6372", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1", - "defence_animation": "425" - }, - { - "slayer_exp": "49", - "name": "Guard dog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6374", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5327", - "combat_audio": "537,539,538", - "respawn_delay": "60", - "defence_animation": "5328", - "death_animation": "5329", - "name": "Jungle spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6376", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "5327", - "combat_audio": "537,539,538", - "respawn_delay": "60", - "defence_animation": "5328", - "death_animation": "5329", - "name": "Jungle spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "6377", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I wouldn't want to be footing that bill.", - "slayer_task": "7", - "melee_animation": "6775", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6779", - "name": "Tenacious toucan", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "6378", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "I wonder how much he can lift.", - "melee_animation": "7237", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7238", - "name": "Giant ant worker", - "defence_level": "35", - "safespot": null, - "lifepoints": "50", - "strength_level": "35", - "id": "6379", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "Gi-ant-ant-ant-ant...", - "melee_animation": "7237", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7238", - "name": "Giant ant soldier", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "6380", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "That stinger has to hurt...", - "melee_animation": "7242", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7244", - "name": "Giant wasp", - "defence_level": "60", - "safespot": null, - "lifepoints": "85", - "strength_level": "60", - "id": "6381", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "Polynomial - a parrot that goes without breakfast", - "slayer_task": "7", - "melee_animation": "6775", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6777", - "name": "Pernicious parrot", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "6382", - "range_level": "1", - "attack_level": "45" - }, - { - "melee_animation": "7242", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "7243", - "death_animation": "7244", - "name": "Giant wasp", - "defence_level": "1", - "safespot": null, - "lifepoints": "37", - "strength_level": "1", - "id": "6383", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very large", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Karamjan Jungle eagle", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6385", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Flies like a rock.", - "melee_animation": "9454", - "range_animation": "1516", - "combat_audio": "428,430,429", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "9455", - "slayer_exp": "105", - "magic_animation": "1516", - "death_animation": "1518", - "name": "Gargoyle", - "defence_level": "107", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "6389", - "aggressive": "true", - "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", - "clue_level": "2", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "I wish I could tell where he was looking. What could be beneath that hood?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Grim Reaper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6390", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6402", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6403", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6404", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6405", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6406", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6407", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6408", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6409", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6410", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6411", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6412", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6413", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6414", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6415", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6416", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6417", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6418", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6419", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6420", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6421", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6422", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6423", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6424", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6425", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6426", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6427", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6428", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6429", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6430", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6431", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6432", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6433", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6434", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6435", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6436", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6437", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6438", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6439", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6440", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6441", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6442", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6443", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6444", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6445", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6446", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6447", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6448", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6449", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6450", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6451", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6452", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6453", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6454", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6455", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6456", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6457", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6458", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6459", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6460", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6461", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6462", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6463", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6464", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6465", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6466", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6467", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A goblin high priest", - "slayer_task": "75", - "melee_animation": "7317", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "6182", - "name": "Snothead", - "defence_level": "14", - "safespot": null, - "lifepoints": "20", - "strength_level": "14", - "id": "6469", - "aggressive": "true", - "range_level": "1", - "attack_level": "14" - }, - { - "examine": "A goblin high priest", - "slayer_task": "75", - "melee_animation": "7317", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "6182", - "name": "Snailfeet", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "13", - "id": "6470", - "aggressive": "true", - "range_level": "18", - "attack_level": "13" - }, - { - "examine": "A goblin high priest", - "slayer_task": "75", - "melee_animation": "7317", - "range_animation": "0", - "magic_level": "22", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "6182", - "name": "Mosschin", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "16", - "id": "6471", - "aggressive": "true", - "range_level": "1", - "attack_level": "16" - }, - { - "examine": "A goblin high priest", - "slayer_task": "75", - "melee_animation": "7317", - "range_animation": "0", - "magic_level": "26", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "6182", - "name": "Redeyes", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "19", - "id": "6472", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "A goblin high priest", - "slayer_task": "75", - "melee_animation": "7317", - "range_animation": "0", - "magic_level": "26", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "6182", - "name": "Strongbones", - "defence_level": "26", - "safespot": null, - "lifepoints": "37", - "strength_level": "19", - "id": "6473", - "aggressive": "true", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "Priest of the Ekeleshuun tribe.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Priest", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6482", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He is expounding the word of the Big High War God.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Preacher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6488", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6490", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6491", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6492", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6493", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6494", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Goblin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "469,472,471", - "strength_level": "1", - "id": "6495", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He doesn't look very welcoming.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Goblin guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6496", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He doesn't look very welcoming.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "469,472,471", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Goblin guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6497", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard wearing blue armour.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6498", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard wearing orange armour.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6499", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard wearing black armour.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6500", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard wearing white armour.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6501", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard wearing purple armour.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6502", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guard wearing yellow armour.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6503", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "25", - "name": "Ghost", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "436,439,438", - "strength_level": "1", - "id": "6504", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very noble spider and attendant to the Queen.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Registrar 2", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6507", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The highest ranking of the Spider Queen's servants.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Registrar 3", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6508", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The head of the Spider Queen's army.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Registrar 4", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6509", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Trying hard to hide his identity.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jury", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6510", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Sir Amik's loyal squire.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spectator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6512", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A being of ore and minerals.", - "magic_animation": "0", - "name": "Spectator", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "range_animation": "0", - "strength_level": "1", - "id": "6514", - "range_level": "1", - "attack_level": "1", - "defence_animation": "0" - }, - { - "examine": "A monkey on a mission.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spectator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6516", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He works for Doric & Son.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spectator", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6518", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Gives an introduction to the Grand Exchange.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Grand Exchange Tutor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6521", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The son of Ali M!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farid Morrisane (ores)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6523", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's probably seen better days.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bob Barter (herbs)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6524", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "You can never miss a pirate in disguise.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Murky Matt (runes)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6525", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A tribal man", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Relobo Blinyo (logs)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6526", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's travelled a long way.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hofuthand (armour and weapons)", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6527", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Chief architect of the Spider Realm.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Registrar 5", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6536", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6543", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "511,513,512", - "strength_level": "1", - "id": "6544", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Tapping his feet and looking very bored.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "null", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6558", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A huge war chief. ", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "7061", - "magic_animation": "422", - "death_animation": "7062", - "name": "null", - "defence_level": "250", - "safespot": null, - "lifepoints": "254", - "strength_level": "251", - "id": "6560", - "aggressive": "true", - "bonuses": "300,300,300,300,300,300,150,300,300,250,43,96,43,30,0", - "range_level": "200", - "attack_level": "250" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6604", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6605", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6606", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6607", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6608", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6609", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6610", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6611", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6612", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6613", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6614", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6615", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6616", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6617", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6618", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6619", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6620", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6621", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6622", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6623", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6624", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6625", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6626", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6627", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6628", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6629", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6630", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6631", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6632", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6633", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6634", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6635", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6636", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6637", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6638", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6639", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6640", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6641", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6642", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6643", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6644", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "spawn_animation": "7457", - "examine": "The ghost of a cyclops slain during the god wars.", - "melee_animation": "7453", - "range_animation": "7510", - "magic_level": "43", - "defence_animation": "7455", - "weakness": "0", - "slayer_exp": "110", - "magic_animation": "7497", - "death_animation": "7454", - "name": "Revenant cyclops", - "defence_level": "43", - "safespot": null, - "lifepoints": "110", - "strength_level": "43", - "id": "6645", - "clue_level": "2", - "range_level": "43", - "attack_level": "43" - }, - { - "spawn_animation": "7464", - "examine": "The essence of a hellhound slain during the god wars.", - "melee_animation": "7460", - "range_animation": "7501", - "combat_audio": "3717,3719,3718", - "magic_level": "50", - "defence_animation": "7462", - "slayer_exp": "80", - "magic_animation": "7515", - "death_animation": "7461", - "name": "Revenant hellhound", - "defence_level": "1", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "6646", - "clue_level": "2", - "range_level": "50", - "attack_level": "50" - }, - { - "spawn_animation": "7478", - "examine": "The essence of a demon slain during the god wars.", - "melee_animation": "7474", - "range_animation": "7512", - "combat_audio": "400,404,403", - "magic_level": "60", - "defence_animation": "7476", - "slayer_exp": "80", - "magic_animation": "7498", - "death_animation": "7475", - "name": "Revenant demon", - "defence_level": "60", - "safespot": null, - "lifepoints": "80", - "strength_level": "60", - "id": "6647", - "clue_level": "2", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6648", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7471", - "examine": "The ghost of a dark beast slain during the god wars.", - "melee_animation": "7467", - "range_animation": "7514", - "defence_animation": "7469", - "slayer_exp": "140", - "magic_animation": "7515", - "death_animation": "7468", - "name": "Revenant dark beast", - "defence_level": "80", - "safespot": null, - "lifepoints": "140", - "strength_level": "80", - "id": "6649", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6650", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6651", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6652", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6653", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6654", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6655", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6656", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "22", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "22", - "safespot": null, - "lifepoints": "34", - "strength_level": "22", - "id": "6657", - "clue_level": "1", - "range_level": "22", - "attack_level": "22" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6658", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6659", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6660", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6661", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6662", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6663", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6664", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6665", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6666", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6667", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6668", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6669", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6670", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6671", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6672", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6673", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6674", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6675", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6676", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6677", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6678", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6679", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6680", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6681", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6682", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6683", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6684", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6685", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6686", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "spawn_animation": "7457", - "examine": "The ghost of a cyclops slain during the god wars.", - "melee_animation": "7453", - "range_animation": "7510", - "magic_level": "43", - "defence_animation": "7455", - "weakness": "0", - "slayer_exp": "110", - "magic_animation": "7497", - "death_animation": "7454", - "name": "Revenant cyclops", - "defence_level": "43", - "safespot": null, - "lifepoints": "110", - "strength_level": "43", - "id": "6687", - "clue_level": "2", - "range_level": "43", - "attack_level": "43" - }, - { - "spawn_animation": "7464", - "examine": "The essence of a hellhound slain during the god wars.", - "melee_animation": "7460", - "range_animation": "7501", - "combat_audio": "3717,3719,3718", - "magic_level": "50", - "defence_animation": "7462", - "slayer_exp": "80", - "magic_animation": "7515", - "death_animation": "7461", - "name": "Revenant hellhound", - "defence_level": "1", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "6688", - "clue_level": "2", - "range_level": "50", - "attack_level": "50" - }, - { - "spawn_animation": "7478", - "examine": "The essence of a demon slain during the god wars.", - "melee_animation": "7474", - "range_animation": "7512", - "combat_audio": "400,404,403", - "magic_level": "60", - "defence_animation": "7476", - "slayer_exp": "80", - "magic_animation": "7498", - "death_animation": "7475", - "name": "Revenant demon", - "defence_level": "60", - "safespot": null, - "lifepoints": "80", - "strength_level": "60", - "id": "6689", - "clue_level": "2", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6690", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7471", - "examine": "The ghost of a dark beast slain during the god wars.", - "melee_animation": "7467", - "range_animation": "7514", - "defence_animation": "7469", - "slayer_exp": "140", - "magic_animation": "7515", - "death_animation": "7468", - "name": "Revenant dark beast", - "defence_level": "80", - "safespot": null, - "lifepoints": "140", - "strength_level": "80", - "id": "6691", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6692", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6693", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6694", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6695", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6696", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6697", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6698", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6699", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6700", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6701", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6702", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6703", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6704", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6705", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6706", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6707", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6708", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6709", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6710", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6711", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6712", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6713", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6714", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "spawn_animation": "7410", - "examine": "The essence of an imp slain during the god wars.", - "melee_animation": "7407", - "range_animation": "7501", - "combat_audio": "0,0,0", - "magic_level": "10", - "defence_animation": "7404", - "slayer_exp": "10", - "magic_animation": "7500", - "death_animation": "7408", - "name": "Revenant imp", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "10", - "id": "6715", - "range_level": "10", - "attack_level": "10" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6716", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6717", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6718", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7447", - "examine": "The ghost of a goblin slain during the god wars.", - "melee_animation": "7449", - "range_animation": "7513", - "combat_audio": "469,472,471", - "magic_level": "12", - "defence_animation": "7450", - "magic_animation": "7499", - "death_animation": "7448", - "name": "Revenant goblin", - "defence_level": "12", - "safespot": null, - "lifepoints": "24", - "strength_level": "12", - "id": "6719", - "clue_level": "1", - "range_level": "12", - "attack_level": "12" - }, - { - "spawn_animation": "7485", - "examine": "The ghost of an icefiend slain during the God Wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "27", - "defence_animation": "7483", - "slayer_exp": "40", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant icefiend", - "defence_level": "27", - "safespot": null, - "lifepoints": "40", - "strength_level": "27", - "id": "6720", - "clue_level": "1", - "range_level": "27", - "attack_level": "27" - }, - { - "spawn_animation": "7485", - "examine": "The essence of a pyrefiend slain during the god wars.", - "melee_animation": "7481", - "range_animation": "7519", - "attack_speed": "3", - "magic_level": "29", - "defence_animation": "7483", - "slayer_exp": "48", - "magic_animation": "7506", - "death_animation": "7482", - "name": "Revenant pyrefiend", - "defence_level": "29", - "safespot": null, - "lifepoints": "48", - "strength_level": "29", - "id": "6721", - "clue_level": "1", - "range_level": "29", - "attack_level": "29" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6722", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7426", - "examine": "The ghost of a vampire slain in the god wars.", - "melee_animation": "7427", - "range_animation": "7520", - "magic_level": "34", - "defence_animation": "7429", - "slayer_exp": "60", - "magic_animation": "7507", - "death_animation": "7428", - "name": "Revenant vampire", - "defence_level": "34", - "safespot": null, - "lifepoints": "60", - "strength_level": "34", - "id": "6723", - "clue_level": "1", - "range_level": "34", - "attack_level": "34" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6724", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6725", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6726", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "The ghost of a hobgoblin slain during the God Wars.", - "melee_animation": "7418", - "range_animation": "7516", - "combat_audio": "469,472,471", - "magic_level": "32", - "defence_animation": "7420", - "slayer_exp": "72", - "magic_animation": "7503", - "death_animation": "7419", - "name": "Revenant hobgoblin", - "defence_level": "32", - "safespot": null, - "lifepoints": "72", - "strength_level": "32", - "id": "6727", - "clue_level": "1", - "range_level": "32", - "attack_level": "32" - }, - { - "spawn_animation": "7403", - "examine": "The ghost of a werewolf slain during the god wars.", - "melee_animation": "7397", - "range_animation": "7521", - "magic_level": "38", - "defence_animation": "7399", - "magic_animation": "7496", - "death_animation": "7398", - "name": "Revenant werewolf", - "defence_level": "38", - "safespot": null, - "lifepoints": "65", - "strength_level": "38", - "id": "6728", - "clue_level": "2", - "range_level": "38", - "attack_level": "38" - }, - { - "examine": "A ghost of an ork slain during the god wars.", - "melee_animation": "7411", - "range_animation": "7518", - "magic_level": "70", - "defence_animation": "7413", - "magic_animation": "7505", - "death_animation": "7412", - "name": "Revenant ork", - "defence_level": "70", - "safespot": null, - "lifepoints": "105", - "strength_level": "70", - "id": "6729", - "clue_level": "2", - "range_level": "70", - "attack_level": "70" - }, - { - "spawn_animation": "7440", - "examine": "A ghost of a knight slain during the god wars.", - "melee_animation": "7441", - "range_animation": "7522", - "poisonous": "true", - "magic_level": "80", - "defence_animation": "7443", - "slayer_exp": "143", - "poison_amount": "8", - "magic_animation": "7508", - "death_animation": "7442", - "name": "Revenant knight", - "defence_level": "80", - "safespot": null, - "lifepoints": "143", - "strength_level": "80", - "id": "6730", - "clue_level": "2", - "range_level": "80", - "attack_level": "80" - }, - { - "examine": "Her lack of body heat is unsettling.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Queen of Snow", - "defence_level": "1", - "movement_radius": "5", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6731", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It looks right at home here.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Snow imp", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6739", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Snowflakes swirling in the wind.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Snow", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6740", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A snowman in fake dragon armour.", - "combat_audio": "29,3295,3287", - "melee_animation": "7558", - "defence_animation": "7559", - "death_animation": "7560", - "name": "Dragon snowman", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6743", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Arr!", - "combat_audio": "29,3295,3287", - "melee_animation": "7558", - "defence_animation": "7559", - "death_animation": "7560", - "name": "Pirate snowman", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6745", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A snowman armed with a holly bow.", - "name": "Snow ranger", - "defence_level": "10", - "safespot": null, - "lifepoints": "30", - "strength_level": "1", - "id": "6747", - "range_level": "30", - "attack_level": "30" - }, - { - "examine": "A snowman armed with an ice sword.", - "name": "Snow ranger", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6748", - "magic_level": "30", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A snowman armed with a winter staff.", - "name": "Snow mage", - "defence_level": "10", - "safespot": null, - "lifepoints": "20", - "strength_level": "1", - "id": "6749", - "range_level": "30", - "attack_level": "30" - }, - { - "examine": "Cut-down and dried.", - "slayer_task": "93", - "melee_animation": "5568", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5569", - "name": "Dried zombie", - "defence_level": "48", - "safespot": null, - "lifepoints": "68", - "strength_level": "48", - "id": "6761", - "range_level": "1", - "attack_level": "48" - }, - { - "examine": "Needs moisturising.", - "slayer_task": "93", - "melee_animation": "5568", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5569", - "name": "Dried zombie", - "defence_level": "48", - "safespot": null, - "lifepoints": "68", - "strength_level": "48", - "id": "6762", - "range_level": "1", - "attack_level": "48" - }, - { - "examine": "I bet it's parched.", - "slayer_task": "93", - "melee_animation": "5568", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5569", - "name": "Dried zombie", - "defence_level": "48", - "safespot": null, - "lifepoints": "68", - "strength_level": "48", - "id": "6763", - "range_level": "1", - "attack_level": "48" - }, - { - "examine": "A guard.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Doorman", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6769", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A huge beast of a beetle.", - "slayer_task": "70", - "melee_animation": "7596", - "range_animation": "0", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "7595", - "name": "Giant scarab", - "defence_level": "66", - "safespot": null, - "lifepoints": "285", - "strength_level": "49", - "id": "6770", - "aggressive": "true", - "range_level": "66", - "attack_level": "49" - }, - { - "examine": "It's not quite small enough to stamp upon.", - "melee_animation": "7657", - "range_animation": "0", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7656", - "name": "Scarab larva", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "18", - "id": "6772", - "range_level": "1", - "attack_level": "18" - }, - { - "examine": "Bred to shoot you down.", - "slayer_task": "70", - "start_gfx": "18", - "combat_style": "1", - "melee_animation": "7607", - "range_animation": "7607", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "7609", - "name": "Scabaras ranger", - "defence_level": "55", - "safespot": null, - "lifepoints": "157", - "strength_level": "41", - "id": "6773", - "aggressive": "true", - "range_level": "55", - "projectile": "11", - "attack_level": "41" - }, - { - "examine": "It might be angry...it's hard to tell.", - "slayer_task": "70", - "melee_animation": "7612", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7614", - "name": "Scabaras lancer", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "6774", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "A giant, mountable locust.", - "melee_animation": "7586", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "7581", - "name": "Scabaras locust", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "41", - "id": "6776", - "aggressive": "true", - "range_level": "55", - "attack_level": "41" - }, - { - "examine": "Bouncy", - "slayer_task": "70", - "melee_animation": "7584", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "7581", - "name": "Locust lancer", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "6777", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "He'll have someone's eye out with that.", - "slayer_task": "70", - "start_gfx": "18", - "combat_style": "1", - "melee_animation": "5451", - "range_animation": "5451", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "2", - "magic_animation": "0", - "death_animation": "7581", - "name": "Locust ranger", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "41", - "id": "6778", - "aggressive": "true", - "range_level": "55", - "projectile": "11", - "attack_level": "41" - }, - { - "melee_animation": "7588", - "combat_audio": "386,388,387", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "7590", - "slayer_exp": "62", - "death_animation": "7591", - "name": "Crocodile", - "defence_level": "1", - "safespot": null, - "lifepoints": "72", - "strength_level": "1", - "id": "6779", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Part scarab, part man.", - "slayer_task": "70", - "combat_style": "2", - "melee_animation": "7615", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "4", - "magic_animation": "0", - "death_animation": "7616", - "name": "Scabaras mage", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "41", - "id": "6780", - "aggressive": "true", - "range_level": "1", - "attack_level": "41" - }, - { - "examine": "Part scarab, part man.", - "combat_style": "2", - "melee_animation": "7620", - "respawn_delay": "60", - "defence_animation": "7617", - "death_animation": "7616", - "name": "Scabaras mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "6781", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An animated clay statue.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Clay golem", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6785", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She looks a bit dirty from digging.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lead archaeologist Abigail", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6786", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks a bit dusty from troweling.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Assistant archaeologist Kerner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6787", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He exudes something like holiness.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "High Priest of Scabaras", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6788", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He exudes something like holiness.", - "slayer_task": "70", - "melee_animation": "7612", - "range_animation": "0", - "magic_level": "66", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7614", - "name": "High Priest of Scabaras", - "defence_level": "66", - "safespot": null, - "lifepoints": "94", - "strength_level": "66", - "id": "6789", - "range_level": "66", - "attack_level": "66" - }, - { - "examine": "He exudes something like holiness.", - "slayer_task": "70", - "melee_animation": "7607", - "range_animation": "7607", - "magic_level": "66", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7609", - "name": "High Priest of Scabaras", - "defence_level": "66", - "safespot": null, - "lifepoints": "94", - "strength_level": "66", - "id": "6790", - "range_level": "66", - "attack_level": "66" - }, - { - "examine": "A bird. Literally terrifying.", - "melee_animation": "1010", - "respawn_delay": "0", - "defence_animation": "1011", - "death_animation": "1012", - "name": "Spirit terrorbird", - "defence_level": "1", - "safespot": null, - "lifepoints": "74", - "strength_level": "1", - "id": "6794", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bird. Literally terrifying.", - "melee_animation": "1010", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "1013", - "name": "Spirit terrorbird", - "defence_level": "50", - "safespot": null, - "lifepoints": "74", - "strength_level": "50", - "id": "6795", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "Is it a stone? Is it a crab? No! It's Granite Crab!", - "melee_animation": "8104", - "range_animation": "8104", - "attack_speed": "3", - "magic_level": "13", - "respawn_delay": "50", - "defence_animation": "8105", - "magic_animation": "8104", - "death_animation": "8106", - "name": "Granite crab", - "defence_level": "22", - "safespot": null, - "lifepoints": "39", - "strength_level": "17", - "id": "6796", - "bonuses": "16,9,5,12,4,11,57,53,61,12,45,22,0,0,0", - "range_level": "16", - "attack_level": "18" - }, - { - "examine": "Is it a stone? Is it a crab? No! It's Granite Crab!", - "melee_animation": "8104", - "range_animation": "8104", - "attack_speed": "3", - "magic_level": "13", - "respawn_delay": "50", - "defence_animation": "8105", - "weakness": "10", - "magic_animation": "8104", - "death_animation": "8106", - "name": "Granite crab", - "defence_level": "22", - "safespot": null, - "lifepoints": "39", - "strength_level": "17", - "id": "6797", - "bonuses": "16,9,5,12,4,11,57,53,61,12,45,22,0,0,0", - "range_level": "16", - "attack_level": "18" - }, - { - "death_animation": "8065", - "name": "Praying mantis", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "8064", - "strength_level": "1", - "id": "6798", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "8066" - }, - { - "examine": "Wax on", - "melee_animation": "8069", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8065", - "name": "Praying mantis", - "defence_level": "60", - "safespot": null, - "lifepoints": "107", - "strength_level": "60", - "id": "6799", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "7854", - "name": "Giant ent", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7853", - "strength_level": "1", - "id": "6800", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7852" - }, - { - "examine": "He ent such a bad guy.", - "melee_animation": "7853", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7854", - "name": "Giant ent", - "defence_level": "60", - "safespot": null, - "lifepoints": "111", - "strength_level": "60", - "id": "6801", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "8153", - "name": "Spirit cobra", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "8152", - "strength_level": "1", - "id": "6802", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "8154" - }, - { - "examine": "Serpentine.", - "melee_animation": "8152", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8153", - "name": "Spirit cobra", - "defence_level": "55", - "safespot": null, - "lifepoints": "90", - "strength_level": "55", - "id": "6803", - "range_level": "55", - "attack_level": "55" - }, - { - "death_animation": "7780", - "name": "Spirit dagannoth", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7786", - "strength_level": "1", - "id": "6804", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7785" - }, - { - "examine": "Face the thing that should not be!", - "melee_animation": "7786", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7780", - "name": "Spirit dagannoth", - "defence_level": "65", - "safespot": null, - "lifepoints": "115", - "strength_level": "65", - "id": "6805", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "A hermit slug.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "8143", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "55", - "end_gfx": "1387", - "defence_animation": "8145", - "magic_animation": "8143", - "death_animation": "8143", - "name": "Thorny snail", - "defence_level": "22", - "poison_immune": "true", - "safespot": null, - "lifepoints": "28", - "strength_level": "18", - "id": "6806", - "bonuses": "47,50,52,52,54,49,13,3,13,4,0,0,0,0,0", - "range_level": "21", - "projectile": "1386", - "attack_level": "19" - }, - { - "examine": "A hermit slug.", - "combat_style": "1", - "melee_animation": "8143", - "range_animation": "8143", - "attack_speed": "5", - "magic_level": "18", - "respawn_delay": "55", - "end_gfx": "1387", - "defence_animation": "8145", - "weakness": "10", - "magic_animation": "8143", - "death_animation": "8143", - "name": "Thorny snail", - "defence_level": "22", - "poison_immune": "true", - "safespot": null, - "lifepoints": "28", - "strength_level": "18", - "id": "6807", - "bonuses": "47,50,52,52,54,49,13,3,13,4,0,0,0,0,0", - "range_level": "21", - "projectile": "1386", - "attack_level": "19" - }, - { - "combat_style": "2", - "melee_animation": "7970", - "respawn_delay": "0", - "defence_animation": "7967", - "death_animation": "7979", - "name": "Karamthulhu overlord", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6809", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Kneel before squid!", - "combat_style": "2", - "melee_animation": "7963", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7964", - "name": "Karamthulhu overlord", - "defence_level": "50", - "safespot": null, - "lifepoints": "82", - "strength_level": "50", - "id": "6810", - "range_level": "50", - "attack_level": "50" - }, - { - "combat_style": "1", - "melee_animation": "7935", - "respawn_delay": "0", - "defence_animation": "7936", - "death_animation": "7937", - "name": "Hydra", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6811", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "7935", - "respawn_delay": "0", - "defence_animation": "7936", - "death_animation": "7937", - "name": "Hydra", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6812", - "range_level": "1", - "attack_level": "1" - }, - { - "death_animation": "7740", - "name": "Bunyip", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "melee_animation": "7741", - "strength_level": "1", - "id": "6813", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7742" - }, - { - "death_animation": "7740", - "name": "Bunyip", - "defence_level": "1", - "safespot": null, - "lifepoints": "40", - "melee_animation": "7741", - "strength_level": "1", - "id": "6814", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7742" - }, - { - "combat_style": "1", - "melee_animation": "8286", - "respawn_delay": "0", - "defence_animation": "8287", - "death_animation": "8285", - "name": "War tortoise", - "defence_level": "1", - "safespot": null, - "lifepoints": "348", - "strength_level": "1", - "id": "6815", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Definitely not teenaged", - "combat_style": "1", - "melee_animation": "8286", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8285", - "name": "War tortoise", - "defence_level": "55", - "safespot": null, - "lifepoints": "95", - "strength_level": "55", - "id": "6816", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "Fruity and bat-shaped. A winning combination!.", - "name": "Fruit bat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6817", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "2", - "melee_animation": "7675", - "respawn_delay": "0", - "defence_animation": "7670", - "death_animation": "7671", - "name": "Abyssal parasite", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6818", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's an extra-planar little blood hoover.", - "combat_style": "2", - "melee_animation": "8910", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7671", - "name": "Abyssal parasite", - "defence_level": "50", - "safespot": null, - "lifepoints": "77", - "strength_level": "50", - "id": "6819", - "range_level": "50", - "attack_level": "50" - }, - { - "death_animation": "7684", - "name": "Abyssal lurker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7680", - "strength_level": "1", - "id": "6820", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7681" - }, - { - "examine": "Lurking like only a lurker can.", - "melee_animation": "7680", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7684", - "name": "Abyssal lurker", - "defence_level": "55", - "safespot": null, - "lifepoints": "88", - "strength_level": "55", - "id": "6821", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "The pointiest horse on the planet.", - "melee_animation": "6376", - "range_animation": "6376", - "combat_audio": "4135,4196,4195", - "magic_level": "69", - "defence_animation": "6375", - "magic_animation": "6376", - "death_animation": "6377", - "name": "Unicorn stallion", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "100", - "strength_level": "62", - "id": "6822", - "bonuses": "48,59,43,52,104,52,116,123,134,46,127,4,0,0,0", - "range_level": "72", - "attack_level": "64" - }, - { - "examine": "The pointiest horse on the planet.", - "melee_animation": "6376", - "range_animation": "6376", - "combat_audio": "4135,4196,4195", - "magic_level": "69", - "defence_animation": "6375", - "weakness": "10", - "magic_animation": "6376", - "death_animation": "6377", - "name": "Unicorn stallion", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "100", - "strength_level": "62", - "id": "6823", - "bonuses": "48,59,43,52,104,52,116,123,134,46,127,4,0,0,0", - "range_level": "72", - "attack_level": "64" - }, - { - "combat_style": "2", - "melee_animation": "7810", - "attack_speed": "5", - "respawn_delay": "0", - "defence_animation": "5388", - "death_animation": "8012", - "name": "Magpie", - "defence_level": "1", - "safespot": null, - "lifepoints": "16", - "strength_level": "1", - "id": "6824", - "range_level": "1", - "projectile": "1318", - "attack_level": "1" - }, - { - "examine": "Southern fried please!", - "combat_style": "2", - "melee_animation": "7810", - "range_animation": "7810", - "attack_speed": "5", - "magic_level": "23", - "respawn_delay": "50", - "defence_animation": "5388", - "magic_animation": "7810", - "death_animation": "5389", - "name": "Dreadfowl", - "defence_level": "22", - "poison_immune": "true", - "safespot": null, - "lifepoints": "16", - "strength_level": "15", - "id": "6825", - "bonuses": "16,15,29,12,39,13,41,35,29,39,47,2,2,2,7", - "range_level": "16", - "projectile": "1318", - "attack_level": "17" - }, - { - "examine": "Southern fried please!", - "combat_style": "2", - "melee_animation": "7810", - "range_animation": "7810", - "attack_speed": "5", - "magic_level": "23", - "respawn_delay": "50", - "defence_animation": "5388", - "weakness": "10", - "magic_animation": "7810", - "death_animation": "5389", - "name": "Dreadfowl", - "defence_level": "22", - "poison_immune": "true", - "safespot": null, - "lifepoints": "16", - "strength_level": "15", - "id": "6826", - "bonuses": "16,15,29,12,39,13,41,35,29,39,47,2,2,2,7", - "range_level": "16", - "projectile": "1318", - "attack_level": "17" - }, - { - "examine": "It's mean and green.", - "melee_animation": "8208", - "respawn_delay": "0", - "defence_animation": "8205", - "death_animation": "8209", - "name": "Stranger plant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6827", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's mean and green!", - "melee_animation": "8208", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8209", - "name": "Stranger plant", - "defence_level": "55", - "safespot": null, - "lifepoints": "91", - "strength_level": "55", - "id": "6828", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "Man's significantly less-domesticated friend.", - "melee_animation": "8292", - "range_animation": "8292", - "attack_speed": "5", - "magic_level": "7", - "defence_animation": "8294", - "magic_animation": "8292", - "death_animation": "8295", - "name": "Spirit wolf", - "defence_level": "21", - "safespot": null, - "lifepoints": "15", - "strength_level": "18", - "id": "6829", - "bonuses": "12,7,4,10,23,5,29,27,16,12,13,17,0,0,0", - "range_level": "9", - "attack_level": "16" - }, - { - "examine": "Man's significantly less-domesticated friend.", - "melee_animation": "8292", - "range_animation": "8292", - "attack_speed": "5", - "magic_level": "7", - "defence_animation": "8294", - "weakness": "10", - "magic_animation": "8292", - "death_animation": "8295", - "name": "Spirit wolf", - "defence_level": "21", - "safespot": null, - "lifepoints": "15", - "strength_level": "18", - "id": "6830", - "bonuses": "12,7,4,10,23,5,29,27,16,12,13,17,0,0,0", - "range_level": "9", - "attack_level": "16" - }, - { - "death_animation": "7797", - "name": "Desert wyrm", - "defence_level": "1", - "safespot": null, - "lifepoints": "47", - "melee_animation": "7795", - "strength_level": "1", - "id": "6831", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7796" - }, - { - "examine": "Surprisingly slime-free.", - "combat_style": "1", - "melee_animation": "7795", - "range_animation": "0", - "magic_level": "18", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7797", - "name": "Desert wyrm", - "defence_level": "18", - "safespot": null, - "lifepoints": "25", - "strength_level": "18", - "id": "6832", - "range_level": "18", - "attack_level": "18" - }, - { - "examine": "If you think he's evil", - "melee_animation": "8248", - "range_animation": "0", - "magic_level": "42", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8250", - "name": "Evil turnip", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "6834", - "range_level": "42", - "attack_level": "42" - }, - { - "death_animation": "8276", - "name": "Vampire bat", - "defence_level": "1", - "safespot": null, - "lifepoints": "20", - "melee_animation": "8275", - "strength_level": "1", - "id": "6835", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "8274" - }, - { - "examine": "It vants to suck my blood!", - "melee_animation": "8275", - "range_animation": "0", - "magic_level": "31", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8276", - "name": "Vampire bat", - "defence_level": "31", - "safespot": null, - "lifepoints": "44", - "strength_level": "31", - "id": "6836", - "range_level": "31", - "attack_level": "31" - }, - { - "melee_animation": "6254", - "combat_audio": "3611,3612,3610", - "respawn_delay": "0", - "defence_animation": "6255", - "death_animation": "6256", - "name": "Spirit scorpion", - "defence_level": "1", - "safespot": null, - "lifepoints": "67", - "strength_level": "1", - "id": "6837", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Salt and vinegaroon.", - "melee_animation": "6254", - "range_animation": "0", - "combat_audio": "3611,3612,3610", - "magic_level": "19", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6256", - "name": "Spirit scorpion", - "defence_level": "19", - "safespot": null, - "lifepoints": "27", - "strength_level": "19", - "id": "6838", - "range_level": "19", - "attack_level": "19" - }, - { - "examine": "Crikey! Look at the size of those teeth!", - "melee_animation": "4925", - "combat_audio": "498,500,499", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "4928", - "death_animation": "4929", - "name": "Arctic bear", - "defence_level": "60", - "safespot": null, - "lifepoints": "10", - "strength_level": "60", - "id": "6839", - "bonuses": "90,50,50,60,90,80,50,30,40,100,0,0,0,0,0", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Crikey! Look at the size of those teeth!", - "melee_animation": "4925", - "range_animation": "0", - "combat_audio": "498,500,499", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "4929", - "name": "Arctic bear", - "defence_level": "60", - "safespot": null, - "lifepoints": "101", - "strength_level": "60", - "id": "6840", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Would scare anyone off their tuffet.", - "melee_animation": "5327", - "range_animation": "5327", - "combat_audio": "537,539,538", - "magic_level": "15", - "respawn_delay": "50", - "defence_animation": "5328", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Spirit spider", - "defence_level": "17", - "safespot": null, - "lifepoints": "18", - "strength_level": "16", - "id": "6841", - "bonuses": "15,16,11,14,34,12,24,36,46,16,37,0,0,0,0", - "range_level": "12", - "attack_level": "17" - }, - { - "examine": "Would scare anyone off their tuffet.", - "melee_animation": "5327", - "range_animation": "5327", - "combat_audio": "537,539,538", - "magic_level": "15", - "respawn_delay": "50", - "defence_animation": "5328", - "weakness": "10", - "magic_animation": "5327", - "death_animation": "5329", - "name": "Spirit spider", - "defence_level": "17", - "safespot": null, - "lifepoints": "18", - "strength_level": "16", - "id": "6842", - "bonuses": "15,16,11,14,34,12,24,36,46,16,37,0,0,0,0", - "range_level": "12", - "attack_level": "17" - }, - { - "death_animation": "7656", - "name": "Bloated leech", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7657", - "strength_level": "1", - "id": "6843", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7655" - }, - { - "examine": "It's like a little suction pump with eyes.", - "melee_animation": "7657", - "range_animation": "0", - "magic_level": "49", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7656", - "name": "Bloated leech", - "defence_level": "49", - "safespot": null, - "lifepoints": "70", - "strength_level": "49", - "id": "6844", - "range_level": "49", - "attack_level": "49" - }, - { - "death_animation": "7925", - "name": "Honey badger", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7928", - "strength_level": "1", - "id": "6845", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7927" - }, - { - "examine": "Violent little so-and-so.", - "melee_animation": "7928", - "range_animation": "0", - "magic_level": "32", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7925", - "name": "Honey badger", - "defence_level": "32", - "safespot": null, - "lifepoints": "45", - "strength_level": "32", - "id": "6846", - "range_level": "32", - "attack_level": "32" - }, - { - "examine": "The big cheese.", - "combat_audio": "703,705,704", - "magic_level": "27", - "respawn_delay": "50", - "name": "Albino rat", - "defence_level": "32", - "poison_immune": "true", - "safespot": null, - "lifepoints": "68", - "strength_level": "28", - "id": "6847", - "bonuses": "64,42,40,57,64,50,76,82,72,24,75,5,15,5,5", - "range_level": "31", - "attack_level": "31" - }, - { - "examine": "The big cheese.", - "combat_audio": "703,705,704", - "magic_level": "27", - "respawn_delay": "50", - "weakness": "10", - "name": "Albino rat", - "defence_level": "32", - "poison_immune": "true", - "safespot": null, - "lifepoints": "68", - "strength_level": "28", - "id": "6848", - "bonuses": "64,42,40,57,64,50,76,82,72,24,75,5,15,5,5", - "range_level": "31", - "attack_level": "31" - }, - { - "examine": "Puts the 'crust' in 'crustacean'.", - "melee_animation": "8112", - "respawn_delay": "0", - "defence_animation": "8114", - "death_animation": "8113", - "name": "Granite lobster", - "defence_level": "60", - "safespot": null, - "lifepoints": "10", - "strength_level": "60", - "id": "6849", - "bonuses": "93,90,65,90,30,40,50,50,60,40,0,0,0,0,0", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Puts the 'crust' in 'crustacean'.", - "melee_animation": "8112", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8113", - "name": "Granite lobster", - "defence_level": "60", - "safespot": null, - "lifepoints": "105", - "strength_level": "60", - "id": "6850", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "8012", - "name": "Macaw", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6851", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1" - }, - { - "death_animation": "8012", - "name": "Macaw", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6852", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "magic_level": "1", - "respawn_delay": "0", - "defence_animation": "8023", - "death_animation": "8025", - "name": "Bronze minotaur", - "defence_level": "19", - "safespot": null, - "lifepoints": "133", - "strength_level": "19", - "id": "6853", - "bonuses": "-2,6,3,0,0,15,14,9,-6,14,5,90,0,0,0", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "range_animation": "0", - "magic_level": "1", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8025", - "name": "Bronze minotaur", - "defence_level": "19", - "safespot": null, - "lifepoints": "133", - "strength_level": "19", - "id": "6854", - "bonuses": "15,20,10,15,10,15,15,15,0,0,0,90,0,0,0", - "range_level": "1", - "attack_level": "19" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "magic_level": "25", - "respawn_delay": "0", - "defence_animation": "8023", - "magic_animation": "", - "death_animation": "8025", - "name": "Iron minotaur", - "defence_level": "25", - "safespot": null, - "lifepoints": "193", - "strength_level": "25", - "id": "6855", - "bonuses": "-2,8,5,0,0,21,17,9,-6,20,5,100,0,100,0", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "range_animation": "0", - "magic_level": "25", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8025", - "name": "Iron minotaur", - "defence_level": "25", - "safespot": null, - "lifepoints": "193", - "strength_level": "25", - "id": "6856", - "bonuses": "25,25,25,25,0,25,25,25,25,0,0,100,0,100,0", - "clue_level": "", - "range_level": "1", - "attack_level": "25" - }, - { - "examine": "He's just a big bully!", - "combat_style": "1", - "melee_animation": "8024", - "magic_level": "28", - "respawn_delay": "0", - "defence_animation": "8023", - "death_animation": "8025", - "name": "Steel minotaur", - "defence_level": "28", - "safespot": null, - "lifepoints": "260", - "strength_level": "28", - "id": "6857", - "bonuses": "-2,16,11,0,0,32,31,24,-6,31,5,122,0,122,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "range_animation": "0", - "magic_level": "28", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8025", - "name": "Steel minotaur", - "defence_level": "28", - "safespot": null, - "lifepoints": "260", - "strength_level": "28", - "id": "6858", - "bonuses": "40,30,30,30,30,30,30,30,30,30,0,127,0,0,0", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "He's just a big bully", - "combat_style": "1", - "melee_animation": "8024", - "magic_level": "30", - "respawn_delay": "0", - "defence_animation": "8023", - "death_animation": "8025", - "name": "Mithril minotaur", - "defence_level": "30", - "safespot": null, - "lifepoints": "340", - "can_tolerate": "", - "strength_level": "30", - "id": "6859", - "bonuses": "-2,22,17,0,0,46,44,38,-6,44,20,146,0,147,0", - "range_level": "0", - "attack_level": "30" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "range_animation": "0", - "magic_level": "30", - "respawn_delay": "0", - "defence_animation": "8023", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8025", - "name": "Mithril minotaur", - "defence_level": "30", - "safespot": null, - "lifepoints": "340", - "strength_level": "30", - "id": "6860", - "bonuses": "30,30,30,30,0,30,30,30,30,0,30,146,0,147,0", - "range_level": "0", - "attack_level": "30" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "attack_speed": "", - "magic_level": "35", - "respawn_delay": "0", - "defence_animation": "8023", - "death_animation": "8025", - "name": "Adamant minotaur", - "defence_level": "35", - "safespot": null, - "poison_immune": "", - "lifepoints": "441", - "strength_level": "35", - "id": "6861", - "bonuses": "-2,31,26,-3,-17,65,63,55,-6,63,30,146,0,181,0", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "He's just a big bully.", - "combat_style": "1", - "melee_animation": "8024", - "range_animation": "0", - "magic_level": "35", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8025", - "name": "Adamant minotaur", - "defence_level": "35", - "safespot": null, - "lifepoints": "441", - "strength_level": "35", - "id": "6862", - "bonuses": "40,50,40,45,35,20,50,36,30,40,15,180,30,10,0", - "range_level": "1", - "attack_level": "35" - }, - { - "examine": "He's just a big bully.", - "melee_animation": "8024", - "magic_level": "40", - "respawn_delay": "0", - "defence_animation": "8023", - "death_animation": "8025", - "name": "Rune minotaur", - "defence_level": "40", - "safespot": null, - "lifepoints": "570", - "strength_level": "40", - "id": "6863", - "bonuses": "-2,48,43,0,-1,207,209,192,-12,205,102,157,0,195,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "He's just a big bully.", - "melee_animation": "8024", - "magic_level": "40", - "respawn_delay": "0", - "defence_animation": "8023", - "slayer_exp": "0", - "death_animation": "8025", - "name": "Rune minotaur", - "defence_level": "40", - "safespot": null, - "lifepoints": "570", - "strength_level": "40", - "id": "6864", - "bonuses": "50,40,40,56,40,30,50,30,60,30,40,219,50,40,40", - "range_level": "1", - "attack_level": "40" - }, - { - "death_animation": "7818", - "name": "Smoke devil", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7816", - "strength_level": "1", - "id": "6865", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7817" - }, - { - "examine": "Well", - "melee_animation": "7816", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7818", - "name": "Smoke devil", - "defence_level": "55", - "safespot": null, - "lifepoints": "87", - "strength_level": "55", - "id": "6866", - "range_level": "55", - "attack_level": "55" - }, - { - "death_animation": "7897", - "name": "Bull ant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7896", - "strength_level": "1", - "id": "6867", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7900" - }, - { - "examine": "Putting all three of its best feet forward.", - "melee_animation": "7896", - "range_animation": "0", - "magic_level": "40", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7897", - "name": "Bull ant", - "defence_level": "40", - "safespot": null, - "lifepoints": "57", - "strength_level": "40", - "id": "6868", - "range_level": "40", - "attack_level": "40" - }, - { - "examine": "It's just a harmless wee rabbit. ", - "combat_style": "2", - "melee_animation": "8304", - "range_animation": "8304", - "attack_speed": "5", - "magic_level": "95", - "defence_animation": "8306", - "magic_animation": "8304", - "death_animation": "8305", - "name": "Wolpertinger", - "defence_level": "95", - "poison_immune": "true", - "safespot": null, - "lifepoints": "619", - "strength_level": "1", - "id": "6869", - "bonuses": "59,50,50,50,50,50,50,50,50,50,50,50,50,68,0", - "range_level": "95", - "attack_level": "1" - }, - { - "examine": "It's just a harmless wee rabbit. ", - "combat_style": "2", - "melee_animation": "8304", - "range_animation": "8304", - "attack_speed": "5", - "magic_level": "95", - "defence_animation": "8306", - "magic_animation": "8304", - "death_animation": "8305", - "name": "Wolpertinger", - "defence_level": "95", - "poison_immune": "true", - "safespot": null, - "lifepoints": "619", - "strength_level": "1", - "id": "6870", - "bonuses": "59,50,50,50,50,50,50,50,50,50,50,50,50,68,0", - "range_level": "95", - "attack_level": "1" - }, - { - "melee_animation": "853", - "attack_speed": "5", - "respawn_delay": "0", - "defence_animation": "851", - "death_animation": "852", - "name": "Compost mound", - "defence_level": "1", - "safespot": null, - "lifepoints": "96", - "strength_level": "1", - "id": "6871", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "I suppose it could smell worse", - "melee_animation": "7769", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "28", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7770", - "name": "Compost mound", - "defence_level": "28", - "safespot": null, - "lifepoints": "40", - "strength_level": "28", - "id": "6872", - "range_level": "28", - "attack_level": "28" - }, - { - "examine": "Bulk haulage never smelled so bad.", - "melee_animation": "5782", - "range_animation": "5782", - "attack_speed": "5", - "magic_level": "91", - "defence_animation": "5783", - "magic_animation": "5782", - "death_animation": "5784", - "name": "Pack yak", - "defence_level": "121", - "poison_immune": "true", - "safespot": null, - "lifepoints": "710", - "strength_level": "104", - "id": "6873", - "bonuses": "64,67,5,72,128,49,264,234,164,49,132,40,35,40,40", - "range_level": "86", - "attack_level": "112" - }, - { - "examine": "Bulk haulage never smelled so bad.", - "melee_animation": "5782", - "range_animation": "5782", - "attack_speed": "5", - "magic_level": "91", - "defence_animation": "5783", - "weakness": "10", - "magic_animation": "5782", - "death_animation": "5784", - "name": "Pack yak", - "defence_level": "121", - "poison_immune": "true", - "safespot": null, - "lifepoints": "710", - "strength_level": "104", - "id": "6874", - "bonuses": "64,67,5,72,128,49,264,234,164,49,132,40,35,40,40", - "range_level": "86", - "attack_level": "112" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit cockatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6875", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit cockatrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6876", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit guthatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6877", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit guthatrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6878", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "combat_audio": "703,705,704", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit saratrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6879", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "combat_audio": "703,705,704", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit saratrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6880", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit zamatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6881", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit zamatrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6882", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit pengatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6883", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit pengatrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6884", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit coraxatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6885", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit coraxatrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6886", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "respawn_delay": "0", - "defence_animation": "7761", - "death_animation": "7763", - "name": "Spirit vulatrice", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6887", - "range_level": "1", - "projectile": "1468", - "attack_level": "1" - }, - { - "examine": "If looks could kill... Wait", - "start_gfx": "1467", - "combat_style": "2", - "melee_animation": "7762", - "range_animation": "0", - "magic_level": "43", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7763", - "name": "Spirit vulatrice", - "defence_level": "43", - "safespot": null, - "lifepoints": "61", - "strength_level": "43", - "id": "6888", - "range_level": "43", - "projectile": "1468", - "attack_level": "43" - }, - { - "examine": "The only creature with a mouth big enough to hold a cannonball.", - "melee_animation": "7260", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "7257", - "death_animation": "7256", - "name": "Barker toad", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "55", - "id": "6889", - "range_level": "55", - "attack_level": "1" - }, - { - "examine": "The only creature with a mouth big enough to fit a cannon ball into.", - "melee_animation": "7260", - "range_animation": "0", - "magic_level": "55", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7256", - "name": "Barker toad", - "defence_level": "55", - "safespot": null, - "lifepoints": "94", - "strength_level": "55", - "id": "6890", - "range_level": "55", - "attack_level": "55" - }, - { - "examine": "He looks like the type of guy who would keep penguins.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Penguin keeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6891", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The lady of the pet shop.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pet shop owner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6892", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The man of the pet shop.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pet shop owner", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6893", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dalmatian puppy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Dalmatian", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6896", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bulldog puppy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bulldog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6897", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Hatchling dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "6900", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "407,405,406", - "strength_level": "1", - "id": "6901", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Hatchling dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "6902", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "407,405,406", - "strength_level": "1", - "id": "6903", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Hatchling dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "6904", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "407,405,406", - "strength_level": "1", - "id": "6905", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Hatchling dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "6906", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby dragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "407,405,406", - "strength_level": "1", - "id": "6907", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's so adorably tiny!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby gecko", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6917", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A tiny nut-thief.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby squirrel", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6921", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "6942", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "6943", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6944", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "2", - "melee_animation": "8304", - "attack_speed": "5", - "respawn_delay": "0", - "defence_animation": "8306", - "death_animation": "8305", - "name": "Bulldog puppy", - "defence_level": "1", - "safespot": null, - "lifepoints": "651", - "strength_level": "1", - "id": "6969", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A nature lover.", - "melee_animation": "7181", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "7186", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6972", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "range_animation": "0", - "combat_audio": "511,513,512", - "melee_animation": "7182", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6973", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "range_animation": "0", - "combat_audio": "511,513,512", - "melee_animation": "7182", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6974", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7181", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "7186", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6975", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6976", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6977", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6978", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7181", - "combat_audio": "511,513,512", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "7186", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6979", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,513,512", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druid", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6980", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6981", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7181", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "7186", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6982", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6983", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7181", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "7186", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6984", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6985", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6986", - "range_level": "1", - "attack_level": "28" - }, - { - "examine": "A nature lover.", - "melee_animation": "7182", - "range_animation": "0", - "combat_audio": "511,506,505", - "attack_speed": "4", - "magic_level": "25", - "respawn_delay": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "711", - "death_animation": "7185", - "name": "Druidess", - "defence_level": "32", - "safespot": null, - "lifepoints": "30", - "strength_level": "28", - "id": "6987", - "range_level": "1", - "attack_level": "28" - }, - { - "death_animation": "8570", - "name": "Spirit jelly", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "8569", - "strength_level": "1", - "id": "6992", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "8571" - }, - { - "examine": "On Gielinor", - "melee_animation": "8569", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8570", - "name": "Spirit jelly", - "defence_level": "50", - "safespot": null, - "lifepoints": "78", - "strength_level": "50", - "id": "6993", - "range_level": "50", - "attack_level": "50" - }, - { - "combat_style": "1", - "melee_animation": "8519", - "respawn_delay": "0", - "defence_animation": "8518", - "death_animation": "8517", - "name": "Spirit kalphite", - "defence_level": "1", - "safespot": null, - "lifepoints": "77", - "strength_level": "1", - "id": "6994", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Hail to the Queen", - "combat_style": "1", - "melee_animation": "6223", - "range_animation": "0", - "magic_level": "25", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "6228", - "name": "Spirit kalphite", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "25", - "id": "6995", - "range_level": "25", - "attack_level": "25" - }, - { - "examine": "A stripy little baby raccoon.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby raccoon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "6997", - "range_level": "1", - "attack_level": "1" - }, - { - "spawn_animation": "8595", - "examine": "A ghost of a dragon slain during the god wars.", - "melee_animation": "8591", - "range_animation": "8594", - "combat_audio": "408,410,409", - "poisonous": "true", - "defence_animation": "8592", - "poison_amount": "8", - "magic_animation": "8594", - "death_animation": "8593", - "name": "Revenant dragon", - "defence_level": "85", - "safespot": null, - "lifepoints": "155", - "strength_level": "85", - "id": "6998", - "clue_level": "2", - "range_level": "85", - "attack_level": "85" - }, - { - "spawn_animation": "8595", - "examine": "A ghost of a dragon slain during the god wars.", - "melee_animation": "8591", - "range_animation": "8594", - "combat_audio": "408,410,409", - "poisonous": "true", - "defence_animation": "8592", - "poison_amount": "8", - "magic_animation": "8594", - "death_animation": "8593", - "name": "Revenant dragon", - "defence_level": "85", - "safespot": null, - "lifepoints": "155", - "strength_level": "85", - "id": "6999", - "clue_level": "2", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "7003", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "A very large elemental adversary.", - "slayer_task": "33", - "melee_animation": "4666", - "range_animation": "4666", - "combat_audio": "447,451,450", - "attack_speed": "5", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "4664", - "weakness": "1", - "slayer_exp": "111", - "magic_animation": "4666", - "death_animation": "4668", - "name": "Fire giant", - "defence_level": "65", - "safespot": null, - "lifepoints": "111", - "strength_level": "65", - "id": "7004", - "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "Must be the pack leader.", - "slayer_task": "92", - "melee_animation": "6559", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "slayer_exp": "74", - "magic_animation": "0", - "death_animation": "6558", - "name": "Big wolf", - "defence_level": "62", - "safespot": null, - "lifepoints": "21", - "strength_level": "60", - "id": "7005", - "aggressive": "true", - "range_level": "1", - "attack_level": "60" - }, - { - "examine": "An active spiny creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Grenwall", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7010", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hiding spiny creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Grenwall", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7011", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What a strange little creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pawya", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7012", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Dug by a Pawya (Not actual exam).", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Earth Mound", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7013", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "What a strange little creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Pawya", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7014", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A most unlikely creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Platypus", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7021", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A most unlikely creature.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby platypus", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7024", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An ogre snack with wings.", - "slayer_task": "7", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wimpy bird", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7031", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A shy creature with a toxic bite.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Diseased kebbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7039", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Fit to wear the uniform?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ogress banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7049", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "She walks as if she owns the place.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chief Tess", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7051", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fearsome adversary with no sense of humour.", - "slayer_task": "64", - "melee_animation": "8636", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "8640", - "name": "Ogress champion", - "defence_level": "48", - "safespot": null, - "lifepoints": "68", - "strength_level": "48", - "id": "7078", - "aggressive": "true", - "range_level": "1", - "attack_level": "48" - }, - { - "examine": "Irascible, belligerent and stupefyingly impolite.", - "slayer_task": "64", - "melee_animation": "8636", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "8640", - "name": "Ogress warrior", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "7079", - "aggressive": "true", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "Irascible, beliggerent and stupefyingly impolite.", - "slayer_task": "64", - "melee_animation": "8637", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "8641", - "name": "Ogress warrior", - "defence_level": "45", - "safespot": null, - "lifepoints": "64", - "strength_level": "45", - "id": "7080", - "aggressive": "true", - "range_level": "1", - "attack_level": "45" - }, - { - "examine": "A large and contentious lady ogre.", - "slayer_task": "64", - "melee_animation": "8636", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "8640", - "name": "Ogress", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "7081", - "aggressive": "true", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "A large and contentious lady ogre.", - "slayer_task": "64", - "melee_animation": "8637", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "8641", - "name": "Ogress", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "7082", - "aggressive": "true", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "Dead stone defending a dead throne room.", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Eucalyptus ent", - "defence_level": "51", - "safespot": null, - "lifepoints": "145", - "strength_level": "51", - "id": "7084", - "aggressive": "true", - "range_level": "1", - "attack_level": "51" - }, - { - "examine": "Dead stone defending a dead throne room.", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Eucalyptus ent", - "defence_level": "54", - "safespot": null, - "lifepoints": "142", - "strength_level": "54", - "id": "7085", - "aggressive": "true", - "range_level": "1", - "attack_level": "54" - }, - { - "examine": "Dead stone defending a dead throne room.", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "name": "Eucalyptus ent", - "defence_level": "57", - "safespot": null, - "lifepoints": "162", - "strength_level": "57", - "id": "7086", - "aggressive": "true", - "range_level": "1", - "attack_level": "57" - }, - { - "examine": "A crazy, evil druid.", - "start_gfx": "105", - "melee_animation": "422", - "range_animation": "422", - "attack_speed": "4", - "magic_level": "10", - "end_gfx": "107", - "respawn_delay": "25", - "defence_animation": "404", - "weakness": "3", - "magic_animation": "422", - "death_animation": "9055", - "name": "Chaos druid", - "defence_level": "12", - "safespot": null, - "lifepoints": "20", - "strength_level": "8", - "id": "7105", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "projectile": "106", - "attack_level": "8" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7106", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7107", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7108", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7109", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7110", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7111", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7112", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7113", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "Low on brains, high on aggression.", - "melee_animation": "386", - "range_animation": "0", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "50", - "defence_animation": "404", - "magic_animation": "0", - "death_animation": "9055", - "name": "Thug", - "defence_level": "9", - "safespot": null, - "lifepoints": "18", - "strength_level": "5", - "id": "7114", - "aggressive": "true", - "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", - "clue_level": "0", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "He seems to be enjoying his time in the bar.", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "1", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Thaki the delivery dwarf", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7115", - "bonuses": "5,5,0,0,0,0,2,3,3,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of King Tyras's men.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Tyras guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7120", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hungry-looking rabbit.", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "50", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7125", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome farmer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7128", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome farmer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7130", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Owner of this homestead.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mrs. Winkin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7132", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "That's one big Ork... ", - "melee_animation": "8754", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "8755", - "death_animation": "8756", - "name": "Bork", - "defence_level": "80", - "lifepoints": "300", - "strength_level": "90", - "id": "7133", - "bonuses": "200,120,100,300,300,120,400,500,300,200,300,400,200,90,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Sharimika", - "id": "2505" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Sharimika", - "id": "2506" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Mamma Bufetta", - "id": "2508" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Mamma Bufetta", - "id": "2509" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Layleen", - "id": "2511" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Layleen", - "id": "2512" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Karaday", - "id": "2514" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Karaday", - "id": "2515" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Safta Doc", - "id": "2517" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Safta Doc", - "id": "2518" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Gabooty", - "id": "2520" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Gabooty", - "id": "2521" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Fanellaman", - "id": "2523" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Fanellaman", - "id": "2524" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Jagbakoba", - "id": "2526" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Jagbakoba", - "id": "2527" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Murcaily", - "id": "2529" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Murcaily", - "id": "2530" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Rionasta", - "id": "2532" - }, - { - "examine": "A native of Tai Bwo Wannai.", - "name": "Rionasta", - "id": "2533" - }, - { - "agg_radius": "64", - "melee_animation": "8754", - "attack_speed": "8", - "respawn_delay": "60", - "defence_animation": "8755", - "death_animation": "8756", - "name": "Bork", - "defence_level": "1", - "safespot": null, - "lifepoints": "300", - "strength_level": "1", - "id": "7134", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Aww, aren't they the cutest li - Argh!", - "melee_animation": "8760", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "8761", - "name": "Ork legion", - "defence_level": "57", - "poison_immune": "true", - "safespot": null, - "lifepoints": "100", - "strength_level": "68", - "id": "7135", - "aggressive": "true", - "bonuses": "5,10,3,5,3,5,5,5,10,0,0,0,0,0,0", - "range_level": "68", - "attack_level": "68" - }, - { - "examine": "A powerful wizard.", - "combat_style": "2", - "attack_speed": "25", - "magic_level": "90", - "spell_id": "11", - "name": "Dagon'hai Elite", - "defence_level": "40", - "safespot": null, - "lifepoints": "70", - "strength_level": "90", - "id": "7137", - "aggressive": "true", - "bonuses": "220,190,140,120,120,130,90,120,120,200,100,154,150,93,190", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A monk of the Dagon'hai.", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "98", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Dagon'hai Monk", - "defence_level": "80", - "safespot": null, - "lifepoints": "88", - "strength_level": "84", - "id": "7138", - "aggressive": "true", - "range_level": "1", - "attack_level": "84" - }, - { - "examine": "A monk of the Dagon'hai.", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "98", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Dagon'hai Monk", - "defence_level": "80", - "safespot": null, - "lifepoints": "88", - "strength_level": "84", - "id": "7139", - "aggressive": "true", - "range_level": "1", - "attack_level": "84" - }, - { - "examine": "A monk of the Dagon'hai.", - "melee_animation": "422", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "98", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "836", - "name": "Dagon'hai Monk", - "defence_level": "80", - "safespot": null, - "lifepoints": "88", - "strength_level": "84", - "id": "7140", - "aggressive": "true", - "range_level": "1", - "attack_level": "84" - }, - { - "examine": "He seems to have gone mad.", - "melee_animation": "426", - "range_animation": "426", - "magic_level": "25", - "defence_animation": "0", - "weakness": "1", - "magic_animation": "0", - "death_animation": "836", - "name": "null", - "defence_level": "25", - "safespot": null, - "lifepoints": "4", - "strength_level": "25", - "id": "7141", - "aggressive": "true", - "range_level": "25", - "attack_level": "25" - }, - { - "examine": "He thumps people who cheat.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Guard", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7142", - "clue_level": "1", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinch jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7144", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinchette jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7145", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinchette jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7146", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinch jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7147", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinch jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7148", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinch jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7149", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An imprisoned gublinch.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Gublinch jailmate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7150", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A person sitting an exam.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Student", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7152", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A person sitting an exam.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Student", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7156", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A person sitting an exam.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Student", - "defence_level": "1", - "lifepoints": "10", - "strength_level": "1", - "id": "7157", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A household pest.", - "melee_animation": "8785", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "8788", - "name": "Cockroach drone", - "defence_level": "3", - "safespot": null, - "lifepoints": "4", - "strength_level": "3", - "id": "7158", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "Eurgh! A big bug.", - "melee_animation": "8787", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "8790", - "name": "Cockroach worker", - "defence_level": "70", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "7159", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "Euww! A giant bug.", - "melee_animation": "8786", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "8789", - "name": "Cockroach soldier", - "defence_level": "70", - "safespot": null, - "lifepoints": "97", - "strength_level": "26", - "id": "7160", - "bonuses": "10,10,10,5,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "38" - }, - { - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Mugger", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "7161", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "422", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Mugger", - "defence_level": "1", - "safespot": null, - "lifepoints": "8", - "strength_level": "1", - "id": "7162", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "4933", - "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "4934", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "7202", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "4933", - "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "4934", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "7204", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It seems to have eaten a lot of chocolate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Cockroach", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7206", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's searching for crumbs of chocolate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Spider", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7207", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It seems to have eaten a lot of chocolate.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Snail", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7209", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7210", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7211", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7212", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7213", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7214", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7215", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7216", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7217", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7218", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7219", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7220", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7221", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7222", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7223", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7224", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7225", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7226", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7227", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7228", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7229", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7230", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7231", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7232", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's a tiny", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "629,631,630", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7233", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7234", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7235", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Baby monkey", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "629,631,630", - "strength_level": "1", - "id": "7236", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A stripy little baby raccoon.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby Raccoon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7275", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's so adorably tiny!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Baby gecko", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7285", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "1", - "melee_animation": "8222", - "magic_level": "70", - "respawn_delay": "0", - "defence_animation": "8224", - "death_animation": "8226", - "name": "Swamp titan", - "defence_level": "78", - "safespot": null, - "lifepoints": "556", - "strength_level": "1", - "id": "7329", - "bonuses": "60,60,60,60,50,50,100,200,200,28,100,100,70,70,70", - "range_level": "70", - "attack_level": "1" - }, - { - "examine": "Do you hear duelling banjos?", - "combat_style": "1", - "melee_animation": "8222", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8226", - "name": "Swamp titan", - "defence_level": "65", - "safespot": null, - "lifepoints": "117", - "strength_level": "60", - "id": "7330", - "bonuses": "60,60,60,60,50,50,100,200,200,28,100,100,70,70,70", - "range_level": "65", - "attack_level": "60" - }, - { - "examine": "It buzzes and bites. Nasty.", - "melee_animation": "8032", - "range_animation": "8032", - "magic_level": "21", - "respawn_delay": "50", - "defence_animation": "8034", - "magic_animation": "8032", - "death_animation": "8033", - "name": "Spirit mosquito", - "defence_level": "25", - "poison_immune": "true", - "safespot": null, - "lifepoints": "43", - "strength_level": "24", - "id": "7331", - "bonuses": "45,49,42,39,47,46,29,43,51,16,53,10,0,0,0", - "range_level": "25", - "attack_level": "28" - }, - { - "examine": "It buzzes and bites. Nasty.", - "melee_animation": "8032", - "range_animation": "8032", - "magic_level": "21", - "respawn_delay": "50", - "defence_animation": "8034", - "weakness": "10", - "magic_animation": "8032", - "death_animation": "8033", - "name": "Spirit mosquito", - "defence_level": "25", - "poison_immune": "true", - "safespot": null, - "lifepoints": "43", - "strength_level": "24", - "id": "7332", - "bonuses": "45,49,42,39,47,46,29,43,51,16,53,10,0,0,0", - "range_level": "25", - "attack_level": "28" - }, - { - "examine": "It spins.", - "melee_animation": "8172", - "range_animation": "0", - "magic_level": "34", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8176", - "name": "Void spinner", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "7334", - "range_level": "34", - "attack_level": "34" - }, - { - "death_animation": "7864", - "name": "Forge regent", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7863", - "strength_level": "1", - "id": "7335", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7865" - }, - { - "examine": "This one will burn right through the net!", - "melee_animation": "7863", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7864", - "name": "Forge regent", - "defence_level": "60", - "safespot": null, - "lifepoints": "108", - "strength_level": "60", - "id": "7336", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "5230", - "name": "Spirit larupia", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "5228", - "strength_level": "1", - "id": "7337", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "5227" - }, - { - "examine": "Fast cat is fast.", - "melee_animation": "5228", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5230", - "name": "Spirit larupia", - "defence_level": "50", - "safespot": null, - "lifepoints": "81", - "strength_level": "50", - "id": "7338", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "It'll kill your enemies, and makes a great cup of tea.", - "melee_animation": "7879", - "range_animation": "422", - "magic_level": "70", - "respawn_delay": "50", - "defence_animation": "7878", - "weakness": "0", - "magic_animation": "422", - "death_animation": "7880", - "name": "Geyser titan", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "620", - "strength_level": "70", - "id": "7339", - "bonuses": "115,115,115,110,110,102,95,110,110,105,78,120,115,120,120", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "It'll kill your enemies, and makes a great cup of tea.", - "melee_animation": "7879", - "range_animation": "422", - "magic_level": "70", - "respawn_delay": "50", - "defence_animation": "7878", - "weakness": "0", - "slayer_exp": "0", - "magic_animation": "422", - "death_animation": "7880", - "name": "Geyser titan", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "620", - "strength_level": "70", - "id": "7340", - "bonuses": "115,115,115,110,110,102,95,110,110,105,78,120,115,120,120", - "range_level": "70", - "attack_level": "70" - }, - { - "combat_style": "1", - "melee_animation": "7980", - "respawn_delay": "0", - "defence_animation": "7981", - "death_animation": "7692", - "name": "Lava titan", - "defence_level": "1", - "safespot": null, - "lifepoints": "528", - "strength_level": "1", - "id": "7341", - "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Made of lava.", - "combat_style": "1", - "melee_animation": "7980", - "range_animation": "0", - "magic_level": "65", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7979", - "name": "Lava titan", - "defence_level": "65", - "safespot": null, - "lifepoints": "115", - "strength_level": "65", - "id": "7342", - "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "The King of the Titans!", - "melee_animation": "8183", - "range_animation": "8183", - "magic_level": "70", - "respawn_delay": "15", - "defence_animation": "8185", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "8183", - "death_animation": "8184", - "name": "Steel titan", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "750", - "strength_level": "70", - "id": "7343", - "bonuses": "105,105,105,100,110,102,95,110,110,105,78,120,115,120,120", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "The King of the Titans!", - "melee_animation": "8183", - "range_animation": "8183", - "magic_level": "70", - "respawn_delay": "15", - "defence_animation": "8185", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "8183", - "death_animation": "8184", - "name": "Steel titan", - "defence_level": "70", - "poison_immune": "true", - "safespot": null, - "lifepoints": "750", - "strength_level": "70", - "id": "7344", - "bonuses": "105,105,105,100,110,102,95,110,110,105,78,120,115,120,120", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "Four fists can make quite an impression IN someone...", - "melee_animation": "8050", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "8051", - "death_animation": "8052", - "name": "Obsidian golem", - "defence_level": "60", - "safespot": null, - "lifepoints": "10", - "strength_level": "60", - "id": "7345", - "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", - "range_level": "60", - "attack_level": "60" - }, - { - "examine": "Four fists can make quite an impression IN someone...", - "melee_animation": "8050", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8052", - "name": "Obsidian golem", - "defence_level": "60", - "safespot": null, - "lifepoints": "104", - "strength_level": "60", - "id": "7346", - "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "5990", - "name": "Talon beast", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "5989", - "strength_level": "1", - "id": "7347", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "5988" - }, - { - "examine": "If a normal black cat is bad luck", - "melee_animation": "5989", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5990", - "name": "Talon beast", - "defence_level": "60", - "safespot": null, - "lifepoints": "110", - "strength_level": "60", - "id": "7348", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "7979", - "name": "Abyssal titan", - "defence_level": "1", - "safespot": null, - "lifepoints": "667", - "melee_animation": "7693", - "strength_level": "1", - "id": "7349", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7691" - }, - { - "examine": "Big", - "melee_animation": "7693", - "range_animation": "0", - "magic_level": "70", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7692", - "name": "Abyssal titan", - "defence_level": "70", - "safespot": null, - "lifepoints": "125", - "strength_level": "70", - "id": "7350", - "range_level": "70", - "attack_level": "70" - }, - { - "examine": "It torches.", - "melee_animation": "8235", - "range_animation": "0", - "magic_level": "34", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8236", - "name": "Void torcher", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "7352", - "range_level": "34", - "attack_level": "34" - }, - { - "death_animation": "7758", - "name": "Giant chinchompa", - "defence_level": "1", - "safespot": null, - "lifepoints": "1", - "melee_animation": "7755", - "strength_level": "1", - "id": "7353", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7753" - }, - { - "examine": "Looks a little...volatile.", - "melee_animation": "7755", - "range_animation": "0", - "magic_level": "29", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7758", - "name": "Giant chinchompa", - "defence_level": "29", - "safespot": null, - "lifepoints": "41", - "strength_level": "29", - "id": "7354", - "range_level": "29", - "attack_level": "29" - }, - { - "examine": "Scorching!", - "melee_animation": "7834", - "range_animation": "7834", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "50", - "defence_animation": "7832", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7834", - "death_animation": "7833", - "name": "Fire titan", - "defence_level": "40", - "poison_immune": "true", - "safespot": null, - "lifepoints": "476", - "strength_level": "30", - "id": "7355", - "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", - "range_level": "30", - "attack_level": "40" - }, - { - "examine": "Scorching!", - "melee_animation": "7834", - "range_animation": "7834", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "50", - "defence_animation": "7832", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7834", - "death_animation": "7833", - "name": "Fire titan", - "defence_level": "40", - "poison_immune": "true", - "safespot": null, - "lifepoints": "476", - "strength_level": "30", - "id": "7356", - "bonuses": "64,45,76,82,208,84,221,231,179,89,113,23,0,0,0", - "range_level": "30", - "attack_level": "40" - }, - { - "examine": "Gathers rolling stones to bash people with.", - "melee_animation": "7844", - "range_animation": "7834", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "50", - "defence_animation": "7832", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7834", - "death_animation": "7843", - "name": "Moss titan", - "defence_level": "40", - "poison_immune": "true", - "safespot": null, - "lifepoints": "476", - "strength_level": "30", - "id": "7357", - "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", - "range_level": "30", - "attack_level": "40" - }, - { - "examine": "Gathers rolling stones to bash people with.", - "melee_animation": "7844", - "range_animation": "7834", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "50", - "defence_animation": "7832", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7834", - "death_animation": "7843", - "name": "Moss titan", - "defence_level": "40", - "poison_immune": "true", - "safespot": null, - "lifepoints": "476", - "strength_level": "30", - "id": "7358", - "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", - "range_level": "30", - "attack_level": "40" - }, - { - "examine": "Frosty the highly violent snowman.", - "melee_animation": "7845", - "range_animation": "7834", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "50", - "defence_animation": "7832", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7834", - "death_animation": "7846", - "name": "Ice titan", - "defence_level": "40", - "poison_immune": "true", - "safespot": null, - "lifepoints": "476", - "strength_level": "30", - "id": "7359", - "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", - "range_level": "30", - "attack_level": "40" - }, - { - "examine": "Frosty the highly violent snowman.", - "melee_animation": "7845", - "range_animation": "7834", - "attack_speed": "5", - "magic_level": "40", - "respawn_delay": "50", - "defence_animation": "7832", - "weakness": "10", - "slayer_exp": "0", - "magic_animation": "7834", - "death_animation": "7846", - "name": "Ice titan", - "defence_level": "40", - "poison_immune": "true", - "safespot": null, - "lifepoints": "476", - "strength_level": "30", - "id": "7360", - "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", - "range_level": "30", - "attack_level": "40" - }, - { - "combat_style": "1", - "melee_animation": "8257", - "attack_speed": "3", - "respawn_delay": "0", - "defence_animation": "8256", - "death_animation": "8258", - "name": "Spirit Tz-Kih", - "defence_level": "1", - "safespot": null, - "lifepoints": "62", - "strength_level": "1", - "id": "7361", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This bat burned down the belfry.", - "combat_style": "1", - "melee_animation": "8257", - "range_animation": "0", - "attack_speed": "3", - "magic_level": "22", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8258", - "name": "Spirit Tz-Kih", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "7362", - "range_level": "22", - "attack_level": "22" - }, - { - "start_gfx": "1367", - "melee_animation": "5228", - "respawn_delay": "0", - "defence_animation": "5227", - "death_animation": "5230", - "name": "Spirit graahk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7363", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Those spikes are pretty big!", - "start_gfx": "1367", - "melee_animation": "5229", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5230", - "name": "Spirit graahk", - "defence_level": "50", - "safespot": null, - "lifepoints": "81", - "strength_level": "50", - "id": "7364", - "range_level": "50", - "attack_level": "50" - }, - { - "start_gfx": "1365", - "melee_animation": "5228", - "respawn_delay": "0", - "defence_animation": "5227", - "death_animation": "5230", - "name": "Spirit kyatt", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7365", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Those teeth are pretty big!", - "start_gfx": "1365", - "melee_animation": "5228", - "range_animation": "0", - "magic_level": "50", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "5230", - "name": "Spirit kyatt", - "defence_level": "50", - "safespot": null, - "lifepoints": "81", - "strength_level": "50", - "id": "7366", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "It shifts.", - "melee_animation": "8131", - "range_animation": "0", - "magic_level": "34", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8133", - "name": "Void shifter", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "7368", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "It ravages.", - "melee_animation": "8086", - "range_animation": "0", - "magic_level": "34", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8087", - "name": "Void ravager", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "7371", - "range_level": "34", - "attack_level": "34" - }, - { - "examine": "It's like a little stomach on wings.", - "melee_animation": "7994", - "range_animation": "0", - "magic_level": "60", - "respawn_delay": "0", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "7996", - "name": "Ravenous locust", - "defence_level": "60", - "safespot": null, - "lifepoints": "100", - "strength_level": "60", - "id": "7373", - "range_level": "60", - "attack_level": "60" - }, - { - "death_animation": "7996", - "name": "Ravenous locust", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "melee_animation": "7994", - "strength_level": "1", - "id": "7374", - "range_level": "1", - "respawn_delay": "0", - "attack_level": "1", - "defence_animation": "7995" - }, - { - "examine": "He is an iron man!", - "combat_style": "1", - "melee_animation": "7946", - "magic_level": "65", - "respawn_delay": "0", - "defence_animation": "7948", - "weakness": "10", - "death_animation": "7947", - "name": "Iron titan", - "defence_level": "65", - "safespot": null, - "lifepoints": "694", - "strength_level": "65", - "id": "7375", - "bonuses": "120,130,100,109,80,120,102,90,103,80,100,108,105,66,90", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "He is an iron man!", - "combat_style": "1", - "melee_animation": "7946", - "combat_audio": "0,0,0", - "magic_level": "65", - "respawn_delay": "0", - "defence_animation": "7948", - "weakness": "10", - "slayer_exp": "0", - "death_animation": "7947", - "name": "Iron titan", - "defence_level": "65", - "safespot": null, - "lifepoints": "694", - "strength_level": "65", - "id": "7376", - "bonuses": "120,130,100,109,80,120,102,90,103,80,100,108,105,66,90", - "range_level": "65", - "attack_level": "65" - }, - { - "examine": "Where did I put the marshmallows?", - "melee_animation": "8080", - "range_animation": "0", - "magic_level": "46", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "death_animation": "8078", - "name": "Pyrelord", - "defence_level": "46", - "safespot": null, - "lifepoints": "65", - "strength_level": "46", - "id": "7378", - "range_level": "46", - "attack_level": "46" - }, - { - "melee_animation": "8965", - "respawn_delay": "60", - "defence_animation": "8966", - "death_animation": "8967", - "name": "Elfinlocks", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "7379", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "8965", - "respawn_delay": "60", - "defence_animation": "8966", - "death_animation": "8967", - "name": "Missi Sissi", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "7380", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "2", - "melee_animation": "8955", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "8957", - "death_animation": "8956", - "name": "Missi Sissi", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "7381", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_style": "2", - "melee_animation": "8955", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "8957", - "death_animation": "8956", - "name": "Uberlass", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "id": "7382", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The vengeful spirit of one who died within Daemonheim.", - "melee_animation": "0", - "range_animation": "0", - "magic_level": "25", - "defence_animation": "0", - "weakness": "3", - "magic_animation": "0", - "name": "Elisabeta", - "defence_level": "25", - "safespot": null, - "lifepoints": "7", - "strength_level": "25", - "id": "7398", - "aggressive": "true", - "range_level": "25", - "attack_level": "25" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "2705", - "range_animation": "2705", - "combat_audio": "3102,3104,3103", - "attack_speed": "5", - "defence_animation": "2706", - "magic_animation": "2705", - "death_animation": "2707", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "2", - "strength_level": "1", - "id": "7417", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "An impling manager: what a terrifying thought!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wigglewoo", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7425", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "This worker looks after the incubator.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Orangeowns", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7426", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Elf warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "425,427,426", - "strength_level": "1", - "id": "7438", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Elf warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "425,427,426", - "strength_level": "1", - "id": "7439", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Elf warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "425,427,426", - "strength_level": "1", - "id": "7440", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Elf warrior", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "425,427,426", - "strength_level": "1", - "id": "7441", - "clue_level": "2", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He holds up passers by.", - "melee_animation": "386", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "836", - "name": "Eudav", - "defence_level": "8", - "safespot": null, - "lifepoints": "11", - "strength_level": "8", - "id": "7443", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "name": "Fairtrade", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "attack_speed": "5", - "id": "7459", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Teapotspout", - "defence_level": "1", - "safespot": null, - "lifepoints": "75", - "strength_level": "1", - "attack_speed": "5", - "id": "7460", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "A popular dwarven delicacy.", - "melee_animation": "4933", - "range_animation": "4933", - "combat_audio": "703,705,704", - "attack_speed": "5", - "defence_animation": "4934", - "magic_animation": "4933", - "death_animation": "4935", - "name": "Rat", - "defence_level": "1", - "safespot": null, - "lifepoints": "5", - "strength_level": "1", - "id": "7461", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "It's bubbling, gross.", - "melee_animation": "9130", - "range_animation": "9130", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "9132", - "magic_animation": "9130", - "death_animation": "9131", - "name": "Hotwater", - "defence_level": "99", - "safespot": null, - "lifepoints": "120", - "strength_level": "99", - "id": "7462", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,45,20,0", - "range_level": "1", - "attack_level": "99" - }, - { - "examine": "It's bubbling, gross.", - "melee_animation": "9130", - "range_animation": "9130", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "9132", - "magic_animation": "9130", - "death_animation": "9131", - "name": "Hotwater", - "defence_level": "99", - "safespot": null, - "lifepoints": "120", - "strength_level": "99", - "id": "7463", - "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,45,20,0", - "range_level": "1", - "attack_level": "99" - }, - { - "examine": "His usual sunny disposition is not in evidence.", - "range_animation": "0", - "magic_level": "30", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "10", - "magic_animation": "0", - "name": "Lady Seenit", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7475", - "range_level": "30", - "attack_level": "30" - }, - { - "name": "Berrybree", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "7476", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Stuffstuffer", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "7477", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Learking", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "7479", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Rachael", - "defence_level": "1", - "safespot": null, - "lifepoints": "70", - "strength_level": "1", - "id": "7480", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "You clearly can't live on treasure alone.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "Cool Mom227", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7481", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A testament to the effect of greed.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "Purepker895", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7482", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "He wanted loot", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "Pkmaster0036", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7483", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Eternally looking for that big payday.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "Cow1337killr", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7484", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "No more tea-breaks for this one.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "Mathdude", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7485", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Even in death you can smell his feet.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "Mathdude", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7486", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "An anatomist's dream.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "1337sp34kr", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7487", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A hand seems to be gripping his spine through his chest. Ouch.", - "slayer_task": "75", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "5491", - "name": "1337sp34kr", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7488", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A desert dweller taken to banditry.", - "melee_animation": "9705", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Sarah Domin", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7492", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Calls himself an archaeologist.", - "melee_animation": "9715", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Sarah Domin", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7493", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "He hasn't found much of use", - "melee_animation": "9705", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Sue Spammers", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7494", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "An amateur historian with added greed.", - "melee_animation": "9715", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Killerwail", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7495", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "It all started with her love of genealogy.", - "melee_animation": "9705", - "range_animation": "0", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Wise Old Man", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7496", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "A rocky horror.", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Sabre-toothed kyatt", - "defence_level": "27", - "safespot": null, - "lifepoints": "38", - "strength_level": "27", - "id": "7497", - "range_level": "1", - "attack_level": "27" - }, - { - "examine": "This dung beetle has mistaken you for its staple diet.", - "slayer_task": "70", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Cerulean twitch", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7500", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "It's looking unwell - probably something it ate.", - "slayer_task": "70", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Abone", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7501", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "Once a valuable contributor to the ecosystem.", - "slayer_task": "70", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Mythmaster", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7502", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "This is what happens if you play with your food.", - "slayer_task": "70", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "name": "Donkey Wrong", - "defence_level": "30", - "safespot": null, - "lifepoints": "42", - "strength_level": "30", - "id": "7503", - "aggressive": "true", - "range_level": "1", - "attack_level": "30" - }, - { - "examine": "He likes a good fight", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Creapantic", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7504", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He likes a good fight", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Frondlike", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7505", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His favourite must be winning.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Happy Spud", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7506", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Blood-thirsty and enthusiastic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Nobodyhere", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7507", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bluehairlass", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7508", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His favourite must be winning.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ilikekebabs", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7510", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "His favourite must be winning.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Trunka Lex", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7511", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Val Razz", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7512", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Abstractclas", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7513", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Bloodthirsty and enthusiastic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Bigbluebox", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7514", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Bloodthirsty and enthusiastic.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Funorbrox", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7515", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's asleep.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Morrisnorris", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7518", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's propping the bar up. Or is it the other way round?", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Matt Blitzer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7519", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He demands to have some booze.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ketchuppl0x", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7520", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "395", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Redheadmonky", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "7528", - "range_level": "1", - "attack_level": "1" - }, - { - "slayer_exp": "0", - "examine": "It's an NPC.", - "name": "3sacrowd", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7532", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "90", - "magic_level": "70", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "90", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7551", - "bonuses": "200,200,200,100,100,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "50", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "90", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7552", - "bonuses": "200,200,200,200,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "attack_speed": "5", - "magic_level": "90", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "90", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7553", - "bonuses": "200,200,100,200,100,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Not somewhere I want to go...", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "90", - "respawn_delay": "125", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Portal", - "defence_level": "90", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7554", - "bonuses": "100,100,200,200,100,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7555", - "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "attack_speed": "5", - "magic_level": "15", - "respawn_delay": "125", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7556", - "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7557", - "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Void Knight will soon weaken the shield.", - "melee_animation": "0", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "30", - "respawn_delay": "125", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Portal", - "defence_level": "30", - "safespot": null, - "lifepoints": "250", - "strength_level": "1", - "id": "7558", - "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "323,326,325", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brawler", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7559", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Lostme", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7560", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Chiercat", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7561", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Skydischarge", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7562", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Agplus", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7563", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Distantthin", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7564", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Allmarshes", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7565", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Explosive67", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7566", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks after your Farming tools.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Alpha1beta", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7569", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Enjoys locking up animals in small pens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Solltalk", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7570", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Enjoys locking up animals in small pens.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Hm Val", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7571", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks like the type of guy who would mind monkeys.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Wizzydumped", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7572", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks like the type of guy who would mind monkeys.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Oddskater", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7573", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Poledragon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "408,410,409", - "strength_level": "1", - "id": "7580", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He likes inflicting pain.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Al Truism", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7582", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The Don of penguins.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ohhhhdude", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7583", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A penguin pushing paper", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "845,848,846", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Torcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7585", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A penguin pushing paper", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "845,848,846", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Torcher", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7586", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He's a little rough around the edges.", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "766,768,767", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Shifter", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7593", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He has unbelievable strength!", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Banker", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7605", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7606", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7607", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7608", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "7609", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7614", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7615", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7616", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "7617", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7618", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7619", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7620", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "7621", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7626", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7627", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7628", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "7629", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7631", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7632", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7634", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7635", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Ew it's still alive.", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "9125", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "9127", - "weakness": "9", - "magic_animation": "9125", - "death_animation": "9126", - "name": "Skeletal hand", - "defence_level": "85", - "safespot": null, - "lifepoints": "90", - "strength_level": "85", - "id": "7640", - "aggressive": "true", - "bonuses": "15,15,15,15,15,15,15,15,15,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "85" - }, - { - "examine": "Ew it's still alive.", - "slayer_task": "21", - "melee_animation": "9125", - "range_animation": "9125", - "attack_speed": "5", - "respawn_delay": "20", - "defence_animation": "9127", - "weakness": "9", - "magic_animation": "9125", - "death_animation": "9126", - "name": "Zombie hand", - "defence_level": "75", - "safespot": null, - "lifepoints": "90", - "strength_level": "75", - "id": "7641", - "aggressive": "true", - "bonuses": "15,15,15,15,15,15,15,15,15,15,15,15,15,15,15", - "range_level": "1", - "attack_level": "75" - }, - { - "examine": "A bloodveld with a very mixed heritage.", - "slayer_task": "10", - "melee_animation": "9102", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "206", - "magic_animation": "0", - "death_animation": "9131", - "name": "Mutated bloodveld", - "defence_level": "56", - "safespot": null, - "lifepoints": "112", - "strength_level": "56", - "id": "7642", - "aggressive": "true", - "range_level": "1", - "attack_level": "56" - }, - { - "examine": "A bloodveld with a very mixed heritage.", - "slayer_task": "10", - "melee_animation": "9102", - "range_animation": "0", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "slayer_exp": "206", - "magic_animation": "0", - "death_animation": "9131", - "name": "Mutated bloodveld", - "defence_level": "58", - "safespot": null, - "lifepoints": "116", - "strength_level": "58", - "id": "7643", - "aggressive": "true", - "range_level": "1", - "attack_level": "58" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7644", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7645", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7646", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7647", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7648", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7649", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7650", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Zaromark Sliver", - "defence_level": "1", - "safespot": null, - "lifepoints": "88", - "strength_level": "1", - "id": "7651", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7654", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7655", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7656", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7657", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7658", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7659", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7660", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Fistandantilus", - "defence_level": "1", - "safespot": null, - "lifepoints": "65", - "strength_level": "1", - "id": "7661", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7682", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7683", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7691", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7692", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7693", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7694", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7695", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7696", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7697", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7698", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7699", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7700", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7701", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "7702", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "95", - "strength_level": "1", - "attack_speed": "6", - "id": "7703", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "1", - "attack_speed": "6", - "id": "7704", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "attack_speed": "6", - "id": "7705", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "name": "Vyrewatch", - "defence_level": "1", - "safespot": null, - "lifepoints": "130", - "strength_level": "1", - "attack_speed": "6", - "id": "7706", - "aggressive": "true", - "range_level": "1", - "respawn_delay": "60", - "attack_level": "1" - }, - { - "examine": "Looks like a big ugly dog.", - "slayer_task": "27", - "melee_animation": "6565", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "6564", - "name": "Temple guardian", - "defence_level": "24", - "safespot": null, - "lifepoints": "34", - "strength_level": "24", - "id": "7711", - "range_level": "1", - "attack_level": "24" - }, - { - "melee_animation": "8080", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "8084", - "death_animation": "8078", - "name": "Baby icefiend", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "7713", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A small ice demon.", - "slayer_task": "46", - "melee_animation": "8080", - "range_animation": "0", - "combat_audio": "531,533,532", - "attack_speed": "5", - "magic_level": "25", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "8078", - "name": "Icefiend", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "1", - "id": "7714", - "aggressive": "true", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The icefiend seems to be melting.", - "slayer_task": "46", - "melee_animation": "8080", - "range_animation": "0", - "combat_audio": "531,533,532", - "attack_speed": "5", - "magic_level": "25", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "8078", - "name": "Icefiend", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "1", - "id": "7715", - "aggressive": "true", - "clue_level": "0", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "The icefiend seems to be melting.", - "slayer_task": "46", - "melee_animation": "8080", - "range_animation": "0", - "attack_speed": "5", - "magic_level": "25", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "8078", - "name": "null", - "defence_level": "25", - "safespot": null, - "lifepoints": "35", - "strength_level": "1", - "id": "7716", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A holy man.", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "511,513,512", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Monk", - "defence_level": "12", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "7727", - "range_level": "1", - "attack_level": "12" - }, - { - "melee_animation": "8080", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "8084", - "death_animation": "8078", - "name": "Baby icefiend", - "defence_level": "1", - "safespot": null, - "lifepoints": "50", - "strength_level": "1", - "id": "7736", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Is it full of rats?", - "melee_animation": "0", - "range_animation": "0", - "combat_audio": "703,705,704", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jiggling crate", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7740", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A warrior who has been long forgotten.", - "range_animation": "0", - "magic_level": "25", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Three little kittens", - "defence_level": "25", - "safespot": null, - "lifepoints": "5", - "strength_level": "30", - "id": "7741", - "aggressive": "true", - "range_level": "25", - "attack_level": "30" - }, - { - "examine": "It looks upset.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "TzHaar-Xil-Tog", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7747", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A TzHaar librarian.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "TzHaar-Mej-Lor", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7752", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A TzHaar-Hur stamping stone tablets.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Library assistant", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7756", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "7767", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "7768", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "Looks like a craftsman of some kind.", - "melee_animation": "9286", - "range_animation": "9286", - "attack_speed": "5", - "magic_level": "50", - "defence_animation": "9287", - "magic_animation": "9286", - "death_animation": "9288", - "name": "TzHaar-Hur", - "defence_level": "50", - "safespot": null, - "lifepoints": "80", - "strength_level": "50", - "id": "7769", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "A monster made of magma.", - "combat_style": "1", - "melee_animation": "9337", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "9340", - "name": "Lava monster", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "28", - "id": "7772", - "aggressive": "true", - "range_level": "38", - "attack_level": "28" - }, - { - "examine": "A monster like many others", - "combat_style": "2", - "melee_animation": "9341", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "0", - "magic_animation": "0", - "death_animation": "9344", - "name": "Fire monster", - "defence_level": "38", - "safespot": null, - "lifepoints": "54", - "strength_level": "28", - "id": "7773", - "aggressive": "true", - "range_level": "38", - "attack_level": "28" - }, - { - "examine": "A big, scary hand! ", - "melee_animation": "1802", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "1803", - "slayer_exp": "105", - "death_animation": "1804", - "name": "Wall Beast", - "defence_level": "38", - "movement_radius": "1", - "safespot": null, - "lifepoints": "105", - "strength_level": "38", - "id": "7823", - "aggressive": "true", - "range_level": "1", - "attack_level": "38" - }, - { - "examine": "A melee training dummy", - "melee_animation": "94", - "range_animation": "0", - "attack_speed": "6", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "97", - "name": "Melee dummy", - "defence_level": "1", - "safespot": null, - "lifepoints": "15", - "strength_level": "1", - "id": "7891", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A man of his craft.", - "name": "Smelting Tutor", - "defence_level": "1", - "movement_radius": "5", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7958", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A master of his craft.", - "name": "Smelting Tutor", - "defence_level": "1", - "movement_radius": "5", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7959", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He looks like a professional explorer.", - "name": "Explorer Jack", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7969", - "range_level": "1", - "attack_level": "1" - }, - { - "agg_radius": "64", - "examine": "A vision of supernatural horror.", - "melee_animation": "10058", - "attack_speed": "6", - "magic_level": "350", - "respawn_delay": "80", - "defence_animation": "10386", - "magic_animation": "10053", - "death_animation": "10385", - "name": "Corporeal Beast", - "defence_level": "310", - "poison_immune": "true", - "movement_radius": "64", - "safespot": null, - "lifepoints": "2000", - "strength_level": "320", - "id": "8133", - "aggressive": "true", - "bonuses": "50,50,50,0,0,25,200,100,150,230,0,0,0,0,0", - "range_level": "150", - "attack_level": "320" - }, - { - "examine": "He sure looks grave.", - "melee_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "6", - "respawn_delay": "35", - "defence_animation": "5574", - "slayer_exp": "30", - "death_animation": "5575", - "name": "Armoured zombie", - "defence_level": "50", - "safespot": null, - "lifepoints": "62", - "strength_level": "50", - "id": "8149", - "aggressive": "true", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "This is a rotten one.", - "melee_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "6", - "respawn_delay": "35", - "defence_animation": "5574", - "slayer_exp": "30", - "death_animation": "5575", - "name": "Armoured zombie", - "defence_level": "50", - "safespot": null, - "lifepoints": "62", - "strength_level": "50", - "id": "8150", - "aggressive": "true", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "It hasn't quite gotten around to dying.", - "melee_animation": "5571", - "combat_audio": "931,923,922", - "attack_speed": "6", - "respawn_delay": "35", - "defence_animation": "5574", - "slayer_exp": "30", - "death_animation": "5575", - "name": "Armoured zombie", - "defence_level": "50", - "safespot": null, - "lifepoints": "62", - "strength_level": "50", - "id": "8151", - "aggressive": "true", - "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", - "range_level": "50", - "attack_level": "50" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "2", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "0", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8349", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "2", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "2", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8350", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "2", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "1", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8351", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "1", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "0", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8352", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "1", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "2", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8353", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "1", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "1", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8354", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "0", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "0", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8355", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "0", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "2", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8356", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "0", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "1", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8357", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "2", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "0", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8358", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "2", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "2", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8359", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "2", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "1", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8360", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "1", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "0", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8361", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "1", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "2", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8362", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "1", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "1", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8363", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "0", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "0", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8364", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "0", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "2", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8365", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", - "combat_style": "0", - "melee_animation": "10922", - "range_animation": "10919", - "attack_speed": "6", - "magic_level": "85", - "protect_style": "1", - "respawn_delay": "100", - "defence_animation": "10923", - "slayer_exp": "136", - "magic_animation": "10918", - "death_animation": "10924", - "name": "Tormented demon", - "defence_level": "85", - "poison_immune": "true", - "safespot": "true", - "movement_radius": "40", - "lifepoints": "326", - "strength_level": "85", - "id": "8366", - "aggressive": "true", - "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", - "range_level": "85", - "attack_level": "85" - }, - { - "examine": "Flappy bird.", - "name": "Gull", - "water_npc": "true", - "id": "1179" - }, - { - "examine": "Flappy bird.", - "name": "Gull", - "water_npc": "true", - "id": "450" - }, - { - "examine": "Flappy bird.", - "name": "Gull", - "water_npc": "true", - "id": "451" - }, - { - "examine": "Tough-looking combat type.", - "name": "Mubariz", - "id": "957" - }, - { - "examine": "Looks kinda bored.", - "name": "Fadli", - "id": "958" - }, - { - "examine": "Trained to deal with all sorts of injuries.", - "name": "A'abla", - "id": "959" - }, - { - "examine": "Wow! She's made a statement with that hair!", - "name": "Sabreen", - "id": "960" - }, - { - "examine": "Has the messy job of putting players back together again.", - "name": "Jaraah", - "id": "962" - }, - { - "examine": "Battle-scarred.", - "name": "Zahwa", - "id": "963" - }, - { - "examine": "A citizen of Al Kharid", - "name": "Ima", - "id": "964" - }, - { - "examine": "A citizen of Al Kharid", - "name": "Sabeil", - "id": "965" - }, - { - "examine": "A citizen of Al Kharid", - "name": "Jadid", - "id": "966" - }, - { - "examine": "A citizen of Al Kharid", - "name": "Dalal", - "id": "967" - }, - { - "examine": "A citizen of Al Kharid", - "name": "Afrah", - "id": "968" - }, - { - "examine": "A citizen of Al Kharid", - "name": "Jeed", - "id": "969" - }, - { - "examine": "He smells funny.", - "name": "Diango", - "id": "970" - }, - { - "examine": "Shopkeeper.", - "name": "Chadwell", - "id": "971" - }, - { - "examine": "The cave guide.", - "name": "Koftik", - "id": "972" - }, - { - "examine": "The cave guide.", - "name": "Koftik", - "id": "973" - }, - { - "examine": "The cave guide.", - "name": "Koftik", - "id": "974" - }, - { - "examine": "The cave guide.", - "name": "Koftik", - "id": "975" - }, - { - "examine": "The cave guide.", - "name": "Koftik", - "id": "976" - }, - { - "examine": "This dwarf looks intoxicated.", - "name": "Kamen", - "id": "996" - }, - { - "examine": "A dwarven maker of gauntlets.", - "name": "Klank", - "id": "995" - }, - { - "examine": "One of King Tyras's men.", - "name": "Tyras guard", - "id": "1206" - }, - { - "examine": "The cave guide.", - "name": "Koftik", - "id": "1209" - }, - { - "examine": "One of King Lathas' messengers.", - "name": "Kings messenger", - "id": "1210" - }, - { - "examine": "Mysterious swamp lights...", - "name": "Will o' the wisp", - "id": "1212" - }, - { - "examine": "He's washing his clothes in the lake.", - "name": "Tegid", - "id": "1213" - }, - { - "examine": "A plant.", - "name": "Thistle", - "id": "1214" - }, - { - "examine": "What a colourful bunch of parrots!", - "name": "Parrots", - "id": "1215" - }, - { - "examine": "Rather dense and soppy looking.", - "name": "Romeo", - "id": "639" - }, - { - "examine": "Newspaper seller.", - "name": "Benny", - "id": "5925" - }, - { - "examine": "One of Gertrude's Sons.", - "name": "Wilough", - "id": "783" - }, - { - "examine": "An old gypsy lady.", - "name": "Gypsy Aris", - "id": "882" - }, - { - "examine": "Interesting assortment of clothes on offer...", - "name": "Thessalia", - "id": "548" - }, - { - "examine": "Sells superior staffs.", - "name": "Zaff", - "id": "546" - }, - { - "examine": "A retired vampyre hunter.", - "name": "Dr Harlow", - "id": "756" - }, - { - "examine": "I could get a beer from him.", - "name": "Bartender", - "id": "733" - }, - { - "examine": "Director of the Grand Exchange.", - "id": "6522" - }, - { - "examine": "He can look after my money. Good with money.", - "id": "6535" - }, - { - "examine": "She can look after my money. Good with money.", - "id": "6532" - }, - { - "examine": "There to help me make my bids.", - "id": "6530" - }, - { - "examine": "There to help me make my bids.", - "id": "6528" - }, - { - "examine": "He can look after my money. Good with money.", - "id": "6534" - }, - { - "examine": "She can look after my money. Good with money.", - "id": "6533" - }, - { - "examine": "There to help me make my bids.", - "id": "6531" - }, - { - "examine": "There to help me make my bids.", - "id": "6529" - }, - { - "examine": "She looks very worried about something.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Caroline", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "696", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A very good sailor.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Holgart", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "698", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Smells a bit fishy.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Ezekial Lovecraft", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4856", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A (semi) retired member of the Temple Knights.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Col. O'Niall", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4872", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "There's something fishy about him.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Mayor Hobb", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4874", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A fresh-faced and innocent priest.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Brother Maledict", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4878", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A down on his luck fisherman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Witchaven villager", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4883", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A down on her luck fisherman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Witchaven villager", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4885", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A down on his luck fisherman.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Witchaven villager", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4887", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A villager named Jeb.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Jeb", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "4895", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A little girl. She looks terrified.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Kimberly", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7168", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Stinky! Poor guy.", - "name": "Yeti", - "id": "130" - }, - { - "examine": "A regal cat with an evil glint in its eye.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "HRH Hrafn", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5479", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Harder than the rocks he sells.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Hring Hring", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5483", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Jatizso's fishmonger.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Flossi Dalksson", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5484", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A guy that will sell you armour.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Raum Urda-Stein", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5485", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Jatizso's armour merchant.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Skuli Myrka", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5486", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rough-looking chef.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Keepa Kettilon", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5487", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Jatizso's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Freygerd", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5493", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Jatizso's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Lensa", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5494", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A happy, friendly landlady.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Vanligga Gastfrihet", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5495", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Jatizso's many citizens.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Sassilik", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5496", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A bedraggled-looking tramp.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Eric", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5499", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Mina guards the mine entrance.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Gruva Patrull", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5500", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A dwarven trader from Keldagrim.", - "melee_animation": "422", - "range_animation": "422", - "combat_audio": "511,513,512", - "defence_animation": "404", - "magic_animation": "422", - "death_animation": "9055", - "name": "Brendt", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "5501", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hungry-looking rabbit.", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "50", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7126", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A gnome farmer.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Farmer", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7129", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of the Burgher's Protectors", - "death_animation": "836", - "name": "Honour Guard", - "melee_animation": "395", - "id": "5515", - "defence_animation": "404" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "4", - "respawn_delay": "70", - "defence_animation": "5489", - "weakness": "8", - "slayer_exp": "29", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "17", - "safespot": null, - "lifepoints": "29", - "strength_level": "18", - "id": "90", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "4", - "defence_animation": "5489", - "weakness": "8", - "slayer_exp": "24", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "17", - "safespot": null, - "lifepoints": "24", - "strength_level": "17", - "id": "91", - "range_level": "1", - "attack_level": "17" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "4", - "defence_animation": "5489", - "weakness": "8", - "slayer_exp": "17", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "24", - "safespot": null, - "lifepoints": "17", - "strength_level": "24", - "id": "92", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "4", - "defence_animation": "5489", - "weakness": "8", - "slayer_exp": "59", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "36", - "safespot": null, - "lifepoints": "59", - "strength_level": "35", - "id": "93", - "range_level": "1", - "attack_level": "32" - }, - { - "examine": "Rogueish.", - "melee_animation": "386", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Rogue", - "defence_level": "7", - "safespot": null, - "lifepoints": "10", - "strength_level": "7", - "aggressive": "false", - "id": "187", - "range_level": "1", - "attack_level": "7" - }, - { - "examine": "It rattles when it moves.", - "slayer_task": "75", - "combat_style": "2", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "magic_level": "5", - "respawn_delay": "60", - "defence_animation": "5489", - "weakness": "3", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "5", - "safespot": null, - "lifepoints": "14", - "strength_level": "3", - "id": "459", - "aggressive": "true", - "range_level": "1", - "attack_level": "3" - }, - { - "examine": "It looks just a bit... underfed.", - "slayer_task": "75", - "melee_animation": "5519", - "range_animation": "5519", - "combat_audio": "774,775,777", - "attack_speed": "4", - "magic_level": "110", - "respawn_delay": "100", - "defence_animation": "5520", - "weakness": "8", - "slayer_exp": "110", - "magic_animation": "5519", - "death_animation": "5521", - "name": "Skeleton", - "defence_level": "110", - "safespot": null, - "lifepoints": "77", - "strength_level": "90", - "id": "1471", - "aggressive": "true", - "bonuses": "50,50,50,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "180" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "5487", - "combat_audio": "774,775,777", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "5513", - "weakness": "8", - "magic_animation": "5487", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "72", - "safespot": null, - "lifepoints": "51", - "strength_level": "72", - "id": "2036", - "aggressive": "true", - "bonuses": "0,0,0,0,0,5,5,-5,0,5,0,0,0,0,0", - "range_level": "1", - "attack_level": "72" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "5487", - "combat_audio": "774,775,777", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "20", - "defence_animation": "5513", - "weakness": "8", - "magic_animation": "5487", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "72", - "safespot": null, - "lifepoints": "51", - "strength_level": "72", - "id": "2037", - "aggressive": "true", - "bonuses": "0,0,0,0,0,5,5,-5,0,5,0,0,0,0,0", - "range_level": "1", - "attack_level": "72" - }, - { - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "774,775,777", - "strength_level": "1", - "id": "2715", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Skeleton mage", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "774,775,777", - "strength_level": "1", - "id": "2717", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "774,775,777", - "strength_level": "1", - "id": "3151", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "One of Gielinor's many citizens, currently incapacitated by alcohol.", - "melee_animation": "422", - "range_animation": "0", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "death_animation": "836", - "name": "Drunken man", - "defence_level": "4", - "safespot": null, - "lifepoints": "5", - "strength_level": "4", - "id": "3222", - "range_level": "1", - "attack_level": "4" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "8", - "safespot": null, - "lifepoints": "11", - "strength_level": "8", - "id": "3291", - "aggressive": "true", - "range_level": "1", - "attack_level": "8" - }, - { - "examine": "He guards the dungeon with the faithfulness of the undead.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "70", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "17", - "safespot": null, - "lifepoints": "29", - "strength_level": "18", - "id": "3581", - "aggressive": "true", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Could use a good meal.", - "slayer_task": "75", - "melee_animation": "6128", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "17", - "safespot": null, - "lifepoints": "24", - "strength_level": "17", - "id": "3697", - "range_level": "1", - "attack_level": "17" - }, - { - "melee_animation": "400", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "3698", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "400", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "1", - "safespot": null, - "lifepoints": "25", - "strength_level": "1", - "id": "3699", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems a little underweight.", - "slayer_task": "75", - "melee_animation": "6128", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "3700", - "range_level": "1", - "attack_level": "20" - }, - { - "examine": "He seems a little underweight.", - "slayer_task": "75", - "melee_animation": "6128", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "20", - "safespot": null, - "lifepoints": "28", - "strength_level": "20", - "id": "3701", - "range_level": "1", - "attack_level": "20" - }, - { - "melee_animation": "395", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "425", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "1", - "safespot": null, - "lifepoints": "35", - "strength_level": "1", - "id": "3702", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "He seems a little underweight.", - "slayer_task": "75", - "melee_animation": "6128", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3703", - "range_level": "1", - "attack_level": "22" - }, - { - "examine": "He seems a little underweight.", - "slayer_task": "75", - "melee_animation": "6128", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "6", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton fremennik", - "defence_level": "22", - "safespot": null, - "lifepoints": "31", - "strength_level": "22", - "id": "3704", - "range_level": "1", - "attack_level": "22" - }, - { - "name": "Skeleton fremennik", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "combat_audio": "774,775,777", - "melee_animation": "5485", - "strength_level": "1", - "id": "3705", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "68", - "strength_level": "1", - "id": "4384", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "4385", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "strength_level": "1", - "id": "4386", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4384", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4532", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "70", - "defence_animation": "5513", - "weakness": "8", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "17", - "safespot": null, - "lifepoints": "29", - "strength_level": "18", - "id": "5332", - "aggressive": "true", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "range_animation": "0", - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "70", - "defence_animation": "5513", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "17", - "safespot": null, - "lifepoints": "29", - "strength_level": "18", - "id": "5333", - "aggressive": "true", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "range_animation": "0", - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "70", - "defence_animation": "5513", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "17", - "safespot": null, - "lifepoints": "29", - "strength_level": "18", - "id": "5334", - "aggressive": "true", - "range_level": "1", - "attack_level": "15" - }, - { - "examine": "Could do with gaining a few pounds.", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "6", - "defence_animation": "5489", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "11", - "id": "5335", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "Could do with gaining a few pounds.", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "6", - "defence_animation": "5489", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "24", - "strength_level": "11", - "id": "5336", - "range_level": "1", - "attack_level": "11" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "60", - "defence_animation": "5489", - "weakness": "8", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "24", - "safespot": null, - "lifepoints": "17", - "strength_level": "24", - "id": "5337", - "aggressive": "true", - "range_level": "1", - "attack_level": "24" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "6", - "defence_animation": "5489", - "weakness": "8", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "23", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "5338", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "6", - "defence_animation": "5489", - "weakness": "8", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "23", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "5339", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "5485", - "combat_audio": "774,775,777", - "attack_speed": "6", - "defence_animation": "5489", - "weakness": "8", - "magic_animation": "5485", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "23", - "safespot": null, - "lifepoints": "17", - "strength_level": "12", - "id": "5340", - "range_level": "1", - "attack_level": "12" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5499", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5503", - "name": "Skeleton", - "defence_level": "42", - "safespot": null, - "lifepoints": "60", - "strength_level": "42", - "id": "5341", - "aggressive": "true", - "range_level": "1", - "attack_level": "42" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "7", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "34", - "safespot": null, - "lifepoints": "48", - "strength_level": "34", - "id": "5365", - "aggressive": "true", - "range_level": "1", - "attack_level": "34" - }, - { - "examine": "Could do with gaining a few pounds.", - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "60", - "strength_level": "1", - "id": "5366", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with gaining a few pounds.", - "combat_audio": "774,775,777", - "melee_animation": "5485", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "strength_level": "1", - "id": "5367", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with gaining a few pounds.", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "85", - "strength_level": "1", - "id": "5368", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "62", - "safespot": null, - "lifepoints": "88", - "strength_level": "62", - "id": "5381", - "aggressive": "true", - "range_level": "1", - "attack_level": "62" - }, - { - "examine": "A skeleton in a dress!", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "magic_level": "57", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "5", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "57", - "safespot": null, - "lifepoints": "81", - "strength_level": "1", - "id": "5385", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Achingly thin.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "5386", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "Look: another skeleton.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "5387", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "That skeleton's grinning at me.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "50", - "safespot": null, - "lifepoints": "71", - "strength_level": "50", - "id": "5388", - "aggressive": "true", - "range_level": "1", - "attack_level": "50" - }, - { - "examine": "He needs a tan.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "51", - "safespot": null, - "lifepoints": "72", - "strength_level": "51", - "id": "5389", - "aggressive": "true", - "range_level": "1", - "attack_level": "51" - }, - { - "examine": "How do you know if a skeleton's male or female?", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "30", - "safespot": null, - "lifepoints": "420", - "strength_level": "36", - "id": "5390", - "aggressive": "true", - "range_level": "1", - "attack_level": "36" - }, - { - "examine": "He obviously hasn't realised he's dead.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "5391", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "Put some meat on those bones!", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "52", - "safespot": null, - "lifepoints": "74", - "strength_level": "52", - "id": "5392", - "aggressive": "true", - "range_level": "1", - "attack_level": "52" - }, - { - "examine": "An angry skeleton.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "55", - "safespot": null, - "lifepoints": "78", - "strength_level": "55", - "id": "5411", - "aggressive": "true", - "range_level": "1", - "attack_level": "55" - }, - { - "examine": "Cross bones.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "57", - "safespot": null, - "lifepoints": "81", - "strength_level": "57", - "id": "5412", - "aggressive": "true", - "range_level": "1", - "attack_level": "57" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5485", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "63", - "id": "5422", - "aggressive": "true", - "range_level": "1", - "attack_level": "63" - }, - { - "examine": "Ey.", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "6091", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with gaining a few pounds.", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "22", - "strength_level": "1", - "id": "6092", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Could do with gaining a few pounds.", - "slayer_task": "75", - "melee_animation": "5487", - "range_animation": "0", - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "9", - "safespot": null, - "lifepoints": "12", - "strength_level": "9", - "id": "6093", - "aggressive": "true", - "range_level": "1", - "attack_level": "9" - }, - { - "examine": "An opponent from the grave. He seems unimpressed by your bone rummaging.", - "slayer_task": "75", - "melee_animation": "2067", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton hero", - "defence_level": "53", - "safespot": null, - "lifepoints": "75", - "strength_level": "53", - "id": "6103", - "aggressive": "true", - "range_level": "1", - "attack_level": "53" - }, - { - "examine": "An ex-barbarian, willing to make you ex too.", - "slayer_task": "75", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton brute", - "defence_level": "63", - "safespot": null, - "lifepoints": "90", - "strength_level": "63", - "id": "6104", - "aggressive": "true", - "range_level": "1", - "attack_level": "63" - }, - { - "examine": "He's heartless.", - "slayer_task": "75", - "melee_animation": "2067", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton warlord", - "defence_level": "65", - "safespot": null, - "lifepoints": "92", - "strength_level": "65", - "id": "6105", - "aggressive": "true", - "range_level": "1", - "attack_level": "65" - }, - { - "examine": "He's less heavy now.", - "slayer_task": "75", - "melee_animation": "390", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton heavy", - "defence_level": "64", - "safespot": null, - "lifepoints": "91", - "strength_level": "64", - "id": "6106", - "aggressive": "true", - "range_level": "1", - "attack_level": "64" - }, - { - "examine": "Floats like an anvil, hits like a hammer.", - "slayer_task": "75", - "melee_animation": "422", - "range_animation": "0", - "combat_audio": "774,775,777", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "8", - "magic_animation": "0", - "death_animation": "836", - "name": "Skeleton thug", - "defence_level": "61", - "safespot": null, - "lifepoints": "87", - "strength_level": "61", - "id": "6107", - "aggressive": "true", - "range_level": "1", - "attack_level": "61" - }, - { - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "97", - "strength_level": "1", - "id": "6764", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "108", - "strength_level": "1", - "id": "6765", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "120", - "strength_level": "1", - "id": "6766", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "115", - "strength_level": "1", - "id": "6767", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "combat_audio": "774,775,777", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "5513", - "death_animation": "5491", - "name": "Skeleton", - "defence_level": "1", - "safespot": null, - "lifepoints": "140", - "strength_level": "1", - "id": "6768", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A hungry-looking rabbit.", - "melee_animation": "0", - "range_animation": "0", - "respawn_delay": "50", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Rabbit", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "7127", - "aggressive": "true", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "A rich landlord, fat and jolly.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Inn Keeper", - "defence_level": "1", - "safespot": null, - "lifepoints": "10", - "strength_level": "1", - "id": "2177", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Likes to cook with mushrooms.", - "melee_animation": "0", - "range_animation": "0", - "defence_animation": "0", - "magic_animation": "0", - "death_animation": "0", - "name": "Fairy chef", - "defence_level": "1", - "safespot": null, - "movement_radius": "2", - "lifepoints": "10", - "strength_level": "1", - "id": "3322", - "range_level": "1", - "attack_level": "1" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4384", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4527", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "melee_animation": "4388", - "attack_speed": "5", - "respawn_delay": "60", - "defence_animation": "4384", - "death_animation": "4389", - "name": "Suqah", - "defence_level": "95", - "safespot": null, - "lifepoints": "105", - "strength_level": "95", - "id": "4528", - "aggressive": "true", - "clue_level": "2", - "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", - "range_level": "1", - "attack_level": "95" - }, - { - "examine": "A large ice troll.", - "melee_animation": "4332", - "range_animation": "0", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "0", - "weakness": "9", - "magic_animation": "0", - "name": "Ice troll grunt", - "defence_level": "60", - "safespot": null, - "lifepoints": "80", - "strength_level": "100", - "id": "5524", - "aggressive": "true", - "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", - "range_level": "1", - "attack_level": "100" - }, - { - "examine": "Soft but strong... and cute.", - "name": "Labrador puppy", - "id": "7247" - }, - { - "examine": "Soft but strong... and cute.", - "name": "Labrador puppy", - "id": "6962" - }, - { - "examine": "Soft but strong... and cute.", - "name": "Labrador puppy", - "id": "7245" - }, - { - "examine": "My most faithful friend.", - "name": "Labrador", - "id": "7248" - }, - { - "examine": "My most faithful friend.", - "name": "Labrador", - "id": "6963" - }, - { - "examine": "My most faithful friend.", - "name": "Labrador", - "id": "7246" - }, - { - "examine": "One proud little puppy.", - "name": "Bulldog puppy", - "id": "7260" - }, - { - "examine": "One proud little puppy.", - "name": "Bulldog puppy", - "id": "7259" - }, - { - "examine": "Looks like it's chewing a wasp.", - "name": "Bulldog", - "id": "6968" - }, - { - "examine": "Looks like it's chewing a wasp.", - "name": "Bulldog", - "id": "7258" - }, - { - "examine": "Looks like it's chewing a wasp.", - "name": "Bulldog", - "id": "7257" - }, - { - "examine": "Now, if only I could find another hundred...", - "name": "Dalmatian puppy", - "id": "6964" - }, - { - "examine": "Now, if only I could find another hundred...", - "name": "Dalmatian puppy", - "id": "7249" - }, - { - "examine": "Now, if only I could find another hundred...", - "name": "Dalmatian puppy", - "id": "7251" - }, - { - "examine": "A purebred doggy.", - "name": "Dalmatian", - "id": "7252" - }, - { - "examine": "A purebred doggy.", - "name": "Dalmatian", - "id": "7250" - }, - { - "examine": "A purebred doggy.", - "name": "Dalmatian", - "id": "6965" - }, - { - "examine": "This is one fast little pooch.", - "name": "Greyhound puppy", - "id": "6960" - }, - { - "examine": "This is one fast little pooch.", - "name": "Greyhound puppy", - "id": "7241" - }, - { - "examine": "This is one fast little pooch.", - "name": "Greyhound puppy", - "id": "7243" - }, - { - "examine": "An aerodynamic doggy.", - "name": "Greyhound", - "id": "6961" - }, - { - "examine": "An aerodynamic doggy.", - "name": "Greyhound", - "id": "7242" - }, - { - "examine": "An aerodynamic doggy.", - "name": "Greyhound", - "id": "7244" - }, - { - "examine": "It's lively and energetic.", - "name": "Terrier puppy", - "id": "6958" - }, - { - "examine": "A hyperactive little pup.", - "name": "Terrier puppy", - "id": "7237" - }, - { - "examine": "Such a brave doggy.", - "name": "Terrier puppy", - "id": "7239" - }, - { - "examine": "It's lively and energetic.", - "name": "Terrier", - "id": "6959" - }, - { - "examine": "A hyperactive little pup.", - "name": "Terrier", - "id": "7238" - }, - { - "examine": "Such a brave doggy.", - "name": "Terrier", - "id": "7240" - }, - { - "examine": "This little puppy is very quiet.", - "name": "Sheepdog puppy", - "id": "7253" - }, - { - "examine": "This little puppy is very quiet.", - "name": "Sheepdog puppy", - "id": "6966" - }, - { - "examine": "This little puppy is very quiet.", - "name": "Sheepdog puppy", - "id": "7255" - }, - { - "examine": "Come by! Come by!", - "name": "Sheepdog", - "id": "6967" - }, - { - "examine": "Come by! Come by!", - "name": "Sheepdog", - "id": "7254" - }, - { - "examine": "Come by! Come by!", - "name": "Sheepdog", - "id": "7256" - }, - { - "examine": "The sandwich lady.", - "name": "Sandwich lady", - "id": "3117" - }, - { - "examine": "A holy man.", - "name": "Drezel", - "id": "1049" - }, - { - "examine": "A holy man.", - "name": "Drezel", - "id": "7690" - }, - { - "examine": "A holy man.", - "name": "Drezel", - "id": "7707" - }, - { - "examine": "A slightly nervous guard.", - "name": "Ulizius", - "id": "1054" - }, - { - "examine": "A local holy man who supports the people trying to get though Mort Myre.", - "name": "Hiylik Myna", - "id": "1514" - }, - { - "examine": "The animated spirit of a soul not at rest.", - "name": "Filiman Tarlock", - "id": "1050" - }, - { - "examine": "The animated spirit of a soul not at rest.", - "name": "Nature Spirit", - "id": "1051" - }, - { - "examine": "I can see fish swimming in the water.", - "name": "Fishing spot", - "id": "323" - }, - { - "examine": "I can see fish swimming in the water.", - "name": "Fishing spot", - "id": "1176" - }, - { - "examine": "Nice hat.", - "name": "Thormac", - "id": "389" - }, - { - "examine": "An evil priest.", - "name": "Necrovarus", - "id": "1684" - }, - { - "examine": "He looks dangerous.", - "name": "Vannaka", - "id": "1597" - }, - { - "examine": "A soggy, smelly Fremennik.", - "name": "Olaf Hardson", - "id": "2621" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Elstan", - "id": "2323" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Dantaera", - "id": "2324" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Kragen", - "id": "2325" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Lyra", - "id": "2326" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Francis", - "id": "2327" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Rhonen", - "id": "2334" - }, - { - "examine": "Banks gnomish things.", - "name": "Gnome banker", - "id": "166" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Ellena", - "id": "2331" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Alain", - "id": "2339" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Dreven", - "id": "2335" - }, - { - "examine": "Founder and Director of the Piscatoris Fishing Colony.", - "name": "Herman Caranos", - "id": "3822" - }, - { - "examine": "Engineer for the Piscatoris Fishing Colony.", - "name": "Franklin Caranos", - "id": "3823" - }, - { - "examine": "Secretary and Storemaster for the Piscatoris Fishing Colony.", - "name": "Arnold Lydspor", - "id": "3824" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Frizzy Skernip", - "id": "4560" - }, - { - "examine": "She sells farming equipment.", - "name": "Sarah", - "id": "2304" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Garth", - "id": "2330" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Selena", - "id": "2332" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Rhazien", - "id": "2337" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Torrell", - "id": "2338" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Heskel", - "id": "2340" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Treznor", - "id": "2341" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Bolongo", - "id": "2343" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Gileth", - "id": "2344" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Amaethwyr", - "id": "2860" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Praistan Ebola", - "id": "4562" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Imiago", - "id": "8041" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Prissy Scilla", - "id": "1037" - }, - { - "examine": "Looks after your Farming tools.", - "name": "Teclyn", - "id": "2861" - }, - { - "examine": "Perhaps this gardener might look after your crops for you.", - "name": "Yulf Squecks", - "id": "4561" - }, - { - "examine": "The head farmer, apparently.", - "name": "Farmer Blinkin", - "id": "7131" - }, - { - "examine": "The lady of the pet shop.", - "name": "Pet shop owner", - "id": "6750" - }, - { - "examine": "Looks after the Burthorpe vinery.", - "name": "Bernald", - "id": "2580" - }, - { - "examine": "An old druid.", - "name": "Sanfew", - "id": "454" - }, - { - "examine": "He runs the Herblore Shop.", - "name": "Jatix", - "id": "587" - }, - { - "examine": "A wise druid.", - "name": "Kaqemeex", - "id": "455" - }, - { - "examine": "He's a very important druid.", - "name": "Pikkupstix", - "id": "6971" - }, - { - "examine": "Ironically, makes a living from swords.", - "name": "Gaius", - "id": "586" - }, - { - "examine": "A gnarly old man.", - "name": "Sylas", - "id": "5987" - }, - { - "examine": "A terrier puppy.", - "name": "Terrier", - "id": "6894" - }, - { - "examine": "A labrador puppy.", - "name": "Labrador", - "id": "6895" - }, - { - "examine": "Dwarvish.", - "name": "Thurgo", - "id": "604" - }, - { - "examine": "Get useful information from this guy.", - "name": "Town crier", - "id": "6137" - }, - { - "examine": "The mace salesman.", - "name": "Flynn", - "id": "580" - }, - { - "examine": "Works in the Rising Sun.", - "name": "Kaylee", - "id": "3217" - }, - { - "examine": "Works in the Rising Sun.", - "name": "Emily", - "id": "736" - }, - { - "examine": "Nice eyes.", - "name": "Cassie", - "id": "577" - }, - { - "examine": "Chief Herald of Falador.", - "name": "Sir Renitee", - "id": "4249" - }, - { - "examine": "An elderly White Knight.", - "name": "Sir Vyvin", - "id": "605" - }, - { - "examine": "Head of recruitment for the Temple Knights.", - "name": "Sir Tiffy Cashien", - "id": "2290" - }, - { - "examine": "An armourer.", - "name": "Wayne", - "id": "581" - }, - { - "examine": "A master of necromancy!", - "name": "Malignius Mortifer", - "id": "2713" - }, - { - "examine": "She seems like a nice sort of person.", - "name": "Betty", - "id": "583" - }, - { - "examine": "Loves his gold!", - "name": "Grum", - "id": "556" - }, - { - "examine": "Unkempt and a bit smelly.", - "name": "Bellemorde", - "id": "2942" - }, - { - "examine": "A Fishing expert.", - "name": "Gerrant", - "id": "558" - }, - { - "examine": "Likes his food to be kept fresh.", - "name": "Wydin", - "id": "557" - }, - { - "examine": "A sea bird.", - "name": "Gull", - "id": "2726" - }, - { - "examine": "An old sea dog.", - "name": "Captain Tobias", - "id": "376" - }, - { - "examine": "A young sailor.", - "name": "Klarense", - "id": "744" - }, - { - "examine": "An expert on axes.", - "name": "Brian", - "id": "559" - }, - { - "examine": "I could get a beer from him.", - "name": "Bartender", - "id": "734" - }, - { - "examine": "She is a seed merchant.", - "name": "Olivia", - "id": "2572" - }, - { - "examine": "Get useful information from this guy.", - "name": "Town crier", - "id": "6136" - }, - { - "examine": "Looks like he could do with a sip of Amontillado.", - "name": "Fortunato", - "id": "3671" - }, - { - "examine": "A young sailor.", - "name": "Seaman Thresnor", - "id": "378" - }, - { - "examine": "A young sailor.", - "name": "Seaman Lorris", - "id": "377" - }, - { - "examine": "A venerable and rich sage.", - "name": "Wise Old Man", - "id": "2253" - }, - { - "examine": "She comes from Al-Kharid.", - "name": "Leela", - "id": "915" - }, - { - "examine": "An old sailor.", - "name": "Ned", - "id": "743" - }, - { - "examine": "He looks scared.", - "name": "Morgan", - "id": "755" - }, - { - "examine": "A witch.", - "name": "Aggie", - "id": "922" - }, - { - "examine": "Bacon-in-training.", - "name": "Piglet", - "id": "2243" - }, - { - "examine": "An infamous bandit.", - "name": "Lady Keli", - "id": "919" - }, - { - "examine": "A young prince.", - "name": "Prince Ali", - "id": "920" - }, - { - "examine": "A gnome mage on sabbatical.", - "name": "Professor Onglewip", - "id": "4585" - }, - { - "examine": "Chief of research at Wizards Tower.", - "name": "Sedridor", - "id": "300" - }, - { - "examine": "An old wizard.", - "name": "Traiborn", - "id": "881" - }, - { - "examine": "Master of imps.", - "name": "Wizard Grayzag", - "id": "707" - }, - { - "examine": "A very brave merchant.", - "name": "Edmond", - "id": "1785" - }, - { - "examine": "She's an expert on armoured skirts.", - "name": "Ranael", - "id": "544" - }, - { - "examine": "Spymaster of Al Kharid.", - "name": "Osman", - "id": "924" - }, - { - "examine": "Kebabs are full of meaty goodness!", - "name": "Karim", - "id": "543" - }, - { - "examine": "He can look after my money.", - "name": "Banker", - "id": "496" - }, - { - "examine": "She can look after my money.", - "name": "Banker", - "id": "497" - }, - { - "examine": "Manufacturer of fine leathers.", - "name": "Ellis", - "id": "2824" - }, - { - "examine": "Sells superior scimitars.", - "name": "Zeke", - "id": "541" - }, - { - "examine": "If Crafting's your thing, he's your man.", - "name": "Dommik", - "id": "545" - }, - { - "examine": "He's in control of the Shantay Pass.", - "name": "Shantay", - "id": "836" - }, - { - "examine": "A resident of Al Kharid.", - "name": "Irena", - "id": "835" - }, - { - "examine": "A farmer's enemy.", - "name": "Crow", - "id": "1755" - }, - { - "examine": "The hat's a dead giveaway.", - "name": "Witch", - "id": "5200" - }, - { - "examine": "A mad scientist if I ever saw one!", - "name": "Professor Oddenstein", - "id": "286" - }, - { - "examine": "She's watching you.", - "name": "Ava", - "id": "5198" - }, - { - "examine": "Litara, a barbarian explorer.", - "name": "Litara", - "id": "4376" - }, - { - "examine": "Always up-to-date with the latest helmet fashions.", - "name": "Peksa", - "id": "538" - }, - { - "examine": "A strange little man.", - "name": "Oziach", - "id": "747" - }, - { - "examine": "A very brave merchant.", - "name": "Richard", - "id": "1783" - }, - { - "examine": "Loves you more, the more you spend.", - "name": "Shop assistant", - "id": "529" - }, - { - "examine": "Sells stuff.", - "name": "Shopkeeper", - "id": "528" - }, - { - "examine": "One of the king's knights.", - "name": "Sir Prysin", - "id": "883" - }, - { - "examine": "Reldo the librarian.", - "name": "Reldo", - "id": "2660" - }, - { - "examine": "A powerful wizard.", - "name": "Surok Magis", - "id": "5834" - }, - { - "examine": "Animal skins are a specialty.", - "name": "Baraek", - "id": "547" - }, - { - "examine": "One of Gertrude's Sons.", - "name": "Shilop", - "id": "781" - }, - { - "examine": "The man with the armour.", - "name": "Horvik", - "id": "549" - }, - { - "examine": "Sells arrows.", - "name": "Lowe", - "id": "550" - }, - { - "examine": "This looks like an angry, aggressive man.", - "name": "Draul Leptoc", - "id": "3324" - }, - { - "examine": "A quiet, more reserved sort of lady.", - "name": "Phillipa", - "id": "3325" - }, - { - "examine": "A tearful damsel, maybe I can help her?", - "name": "Juliet", - "id": "637" - }, - { - "agg_radius": "", - "examine": "Like a mini man!", - "combat_style": "1", - "melee_animation": "190", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "193", - "weakness": "", - "end_height": "", - "death_animation": "196", - "name": "Gnome", - "defence_level": "1", - "lifepoints": "2", - "strength_level": "1", - "id": "2250", - "aggressive": "", - "range_level": "1", - "attack_level": "1" - }, - { - "examine": "Like a mini man!", - "combat_style": "1", - "melee_animation": "190", - "attack_speed": "4", - "respawn_delay": "60", - "defence_animation": "193", - "death_animation": "196", - "name": "Gnome", - "defence_level": "1", - "lifepoints": "3", - "strength_level": "1", - "id": "2249", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "null", - "defence_level": "1", - "safespot": "null", - "combat_audio": "511,513,512", - "id": "2309", - "range_level": "1", - "attack_level": "1", - "defence_animation": "" - }, - { - "examine": "Yanni Salika; he buys and sells antiques.", - "name": "Yanni Salika", - "id": "515" - }, - { - "examine": "This is Kaleb Paramaya, a warm and friendly inn owner.", - "name": "Kaleb Paramaya", - "id": "512" - }, - { - "examine": "This is Fernahei; he owns the local fishing tackle shop.", - "name": "Fernahei", - "id": "517" - }, - { - "examine": "A warrior from Shilo Village.", - "name": "Mosol Rei", - "id": "500" - }, - { - "examine": "An unquiet soul.", - "name": "Spirit of Zadimus", - "id": "501" - }, - { - "examine": "The animated spirit of Rashiliyia the Zombie Queen.", - "name": "Rashiliyia ", - "id": "506" - }, - { - "examine": "A dwarf miner. He's shoring up the walls.", - "name": "Ferd", - "id": "3937" - }, - { - "examine": "A crafty dwarf.", - "name": "Nolar", - "id": "2158" - }, - { - "examine": "She sells general items at the Legends Guild.", - "name": "Fionella", - "id": "932" - }, - { - "examine": "A dwarf who's currently living in Miscellania.", - "name": "Alviss", - "id": "3933" - }, - { - "examine": "Smithy for Sogthorpe.", - "name": "Derrik", - "id": "1376" - }, - { - "examine": "A rather scared-looking dwarf. He doesn't seem all that drunk.", - "name": "Donal", - "id": "3938" - }, - { - "examine": "Runs the general store.", - "name": "Finn", - "id": "3922" - }, - { - "examine": "A dwarf who's currently living in Miscellania.", - "name": "Fullangr", - "id": "3934" - }, - { - "examine": "A subject of Miscellania.", - "name": "Halla", - "id": "3921" - }, - { - "examine": "A dwarf who's currently living in Miscellania.", - "name": "Jari", - "id": "3935" - }, - { - "examine": "A subject of Miscellania.", - "name": "Einar", - "id": "1380" - }, - { - "examine": "A subject of Miscellania.", - "name": "Ragnar", - "id": "1379" - }, - { - "examine": "A subject of Miscellania.", - "name": "Thora", - "id": "3927" - }, - { - "examine": "A subject of Miscellania.", - "name": "Thorhild", - "id": "1382" - }, - { - "examine": "A subject of Miscellania.", - "name": "Tjorvi", - "id": "3925" + "strength_level": "3" }, { - "examine": "Likes fish... hates people.", - "melee_animation": "284", - "attack_speed": "4", - "magic_level": "1", - "respawn_delay": "", - "defence_animation": "285", - "death_animation": "287", - "name": "River troll", - "defence_level": "17", - "lifepoints": "20", - "strength_level": "17", "id": "391", + "name": "River troll", + "examine": "Likes fish... hates people.", "aggressive": "true", - "clue_level": "", + "attack_level": "17", + "attack_speed": "4", "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "17", + "lifepoints": "20", + "magic_level": "1", + "melee_animation": "284", "range_level": "1", - "attack_level": "17" + "respawn_delay": "", + "strength_level": "17" }, { - "examine": "Likes fish... hates people.", - "melee_animation": "284", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "285", - "death_animation": "287", + "id": "392", "name": "River troll", + "examine": "Likes fish... hates people.", + "aggressive": "true", + "attack_level": "32", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "32", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "32" + }, + { + "id": "393", + "name": "River troll", + "examine": "Likes fish... hates people.", + "aggressive": "true", + "attack_level": "48", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "287", + "defence_animation": "285", "defence_level": "48", "lifepoints": "48", - "strength_level": "48", - "id": "393", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "magic_level": "1", + "melee_animation": "284", "range_level": "1", - "attack_level": "48" + "strength_level": "48" }, { - "examine": "Likes fish... hates people.", - "melee_animation": "284", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "285", - "death_animation": "287", + "id": "394", "name": "River troll", + "examine": "Likes fish... hates people.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "287", + "defence_animation": "285", "defence_level": "65", "lifepoints": "85", - "strength_level": "65", - "id": "394", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "magic_level": "1", + "melee_animation": "284", "range_level": "1", - "attack_level": "65" + "strength_level": "65" }, { - "examine": "Likes fish... hates people.", - "melee_animation": "284", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "285", - "death_animation": "287", + "id": "395", "name": "River troll", + "examine": "Likes fish... hates people.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "287", + "defence_animation": "285", "defence_level": "100", "lifepoints": "120", - "strength_level": "100", - "id": "395", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "magic_level": "1", + "melee_animation": "284", "range_level": "1", - "attack_level": "100" + "strength_level": "100" }, { - "examine": "Likes fish... hates people.", - "melee_animation": "284", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "285", - "death_animation": "287", + "id": "396", "name": "River troll", + "examine": "Likes fish... hates people.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "287", + "defence_animation": "285", "defence_level": "130", "lifepoints": "170", - "strength_level": "130", - "id": "396", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "130" - }, - { - "examine": "Rock with attitude.", - "combat_style": "1", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "8", - "name": "Rock Golem", - "lifepoints": "25", - "strength_level": "8", - "id": "413", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "15", - "attack_level": "8" - }, - { - "examine": "Rock with attitude.", - "combat_style": "1", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "17", - "name": "Rock Golem", - "lifepoints": "40", - "strength_level": "17", - "id": "414", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "30", - "attack_level": "17" - }, - { - "examine": "Rock with attitude.", - "combat_style": "1", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "36", - "name": "Rock Golem", - "lifepoints": "60", - "strength_level": "36", - "id": "415", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "40", - "attack_level": "38" - }, - { - "examine": "Rock with attitude.", - "combat_style": "1", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "64", - "name": "Rock Golem", - "lifepoints": "86", - "strength_level": "64", - "id": "416", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "60", - "attack_level": "64" - }, - { - "examine": "Rock with attitude.", - "combat_style": "1", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "100", - "name": "Rock Golem", - "lifepoints": "120", - "strength_level": "100", - "id": "417", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "75", - "attack_level": "100" - }, - { - "examine": "Rock with attitude.", - "combat_style": "1", - "range_animation": "0", - "attack_speed": "4", - "defence_animation": "130", - "name": "Rock Golem", - "lifepoints": "166", - "strength_level": "130", - "id": "418", - "aggressive": "true", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "80", - "attack_level": "130" - }, - { - "examine": "Mooooooooooooole.", - "name": "Baby Mole", - "id": "3342" - }, - { - "examine": "Moley, moley, moley!", - "name": "Baby Mole", - "id": "3343" - }, - { - "examine": "He hungry.", - "combat_style": "1", - "start_gfx": "243", - "name": "Rantz", - "start_height": "100", - "range_animation": "3460", - "id": "1010", - "projectile": "242", - "prj_height": "50" - }, - { - "examine": "One of Fenkenstrain's failed experiments.", - "combat_style": "", - "melee_animation": "1616", - "attack_speed": "4", "magic_level": "1", - "defence_animation": "1617", - "death_animation": "1618", - "name": "Experiment", - "defence_level": "30", - "lifepoints": "100", + "melee_animation": "284", + "range_level": "1", + "strength_level": "130" + }, + { + "id": "397", + "name": "Cow", + "examine": "Beefy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "369,371,370", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", "strength_level": "1", - "id": "1677", - "aggressive": "", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" + "weakness": "8" }, { - "examine": "It has a key hanging from its collar.", - "melee_animation": "1626", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "1627", - "death_animation": "1628", - "name": "Experiment", - "defence_level": "50", - "lifepoints": "40", - "strength_level": "50", - "id": "1676", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "40" - }, - { - "examine": "One of Fenkenstrain's failed experiments.", - "melee_animation": "1612", - "attack_speed": "4", - "magic_level": "1", - "defence_animation": "1613", - "death_animation": "1611", - "name": "Experiment", - "defence_level": "30", - "lifepoints": "100", - "strength_level": "1", - "id": "1678", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "range_level": "1", - "attack_level": "1" - }, - { - "name": "Puro Spawn (Low)", - "id": "6065", - "respawn_delay": "1" - }, - { - "name": "Puro Spawn (Mid)", - "id": "6066", - "respawn_delay": "1" - }, - { - "name": "Puro Spawn (High)", - "id": "6067", - "respawn_delay": "1" - }, - { - "name": "Baby Impling Puro", - "id": "6055", - "respawn_delay": "7" - }, - { - "name": "Young Impling Puro", - "id": "6056", - "respawn_delay": "7" - }, - { - "name": "Gourmet Impling Puro", - "id": "6057", - "respawn_delay": "7" - }, - { - "name": "Earth Impling Puro", - "id": "6058", - "respawn_delay": "50" - }, - { - "name": "Essence Impling Puro", - "id": "6059", - "respawn_delay": "50" - }, - { - "name": "Eclectic Impling Puro", - "id": "6060", - "respawn_delay": "7" - }, - { - "name": "Ninja Impling Puro", - "id": "6063", - "respawn_delay": "9999" - }, - { - "name": "Nature Impling Puro", - "id": "6061", - "respawn_delay": "9999" - }, - { - "name": "Magpie Impling Puro", - "id": "6062", - "respawn_delay": "9999" - }, - { - "examine": "He looks dangerous!", - "name": "Turael", - "id": "8273" - }, - { - "examine": "Doesn't seem to want to go away.", - "combat_style": "2", - "melee_animation": "811", - "range_animation": "811", - "attack_speed": "4", - "magic_level": "100", + "id": "398", + "name": "Legends guard", + "examine": "A Legends Guild guard; he protects the entrance to the Legends Guild.", + "attack_level": "1", + "death_animation": "0", "defence_animation": "0", - "magic_animation": "811", - "death_animation": "836", - "name": "Skeleton Mage", - "defence_level": "60", - "lifepoints": "80", - "strength_level": "10", - "id": "3851", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", "range_level": "1", - "attack_level": "10" + "safespot": null, + "strength_level": "1" }, { - "examine": "Blaec seems to be covered in sand.", - "name": "Blaec", - "id": "3115" + "id": "399", + "name": "Legends guard" }, { - "examine": "Looks otherworldy...", - "name": "Fairy Queen", - "id": "4437" + "id": "400", + "name": "Radimus Erkle" }, { - "examine": "A delicate creature from this strange realm.", - "name": "Fairy", - "id": "4443" + "id": "401", + "name": "Jungle forester", + "examine": "He deals in exotic types of wood.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" }, { + "id": "402", + "name": "Jungle forester", + "examine": "She deals in exotic types of wood.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "403", + "name": "Fishing spot" + }, + { + "id": "404", + "name": "Fishing spot" + }, + { + "id": "405", + "name": "Fishing spot" + }, + { + "id": "406", + "name": "Fishing spot" + }, + { + "id": "407", + "name": "Strange Plant", + "examine": "A very strange plant." + }, + { + "id": "408", + "name": "Strange Plant", "examine": "A very strange plant.", "death_animation": "355", - "name": "Strange Plant", + "defence_animation": "354", "defence_level": "300", - "melee_animation": "353", "lifepoints": "100", - "id": "408", "magic_level": "200", - "defence_animation": "354" + "melee_animation": "353" }, { - "examine": "A very strange plant.", - "name": "Strange Plant", - "id": "407" + "id": "409", + "name": "Genie" }, { - "agg_radius": "", - "examine": "A helmetted, barbarian snowman.", - "death_animation": "7560", - "name": "Barbarian Snowman", + "id": "410", + "name": "Mysterious Old Man" + }, + { + "id": "411", + "name": "Swarm", + "examine": "Insects buzzing around.", + "aggressive": "false", + "attack_level": "1", + "combat_audio": "819,821,820", + "death_animation": "0", + "defence_animation": "0", "defence_level": "1", - "melee_animation": "7565", - "lifepoints": "20", - "combat_audio": "12,3295,3287", - "id": "6742", - "defence_animation": "7559" + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" }, { - "examine": "A snow dwarf.", - "death_animation": "7560", - "name": "Dwarf Snowman", + "id": "412", + "name": "Bat", + "examine": "An annoying flappy thing.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "4918", + "defence_animation": "4916", + "defence_level": "2", + "lifepoints": "8", + "magic_level": "10", + "melee_animation": "4915", + "range_animation": "4915", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "8", + "strength_level": "1", + "weakness": "4" + }, + { + "id": "413", + "name": "Rock Golem", + "examine": "Rock with attitude.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "156", + "defence_animation": "154", + "lifepoints": "25", + "projectile": "968", + "range_animation": "5347", + "range_level": "15", + "strength_level": "8" + }, + { + "id": "414", + "name": "Rock Golem", + "examine": "Rock with attitude.", + "aggressive": "true", + "attack_level": "17", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "156", + "defence_animation": "154", + "lifepoints": "40", + "projectile": "968", + "range_animation": "5347", + "range_level": "30", + "strength_level": "17" + }, + { + "id": "415", + "name": "Rock Golem", + "examine": "Rock with attitude.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "156", + "defence_animation": "154", + "lifepoints": "60", + "projectile": "968", + "range_animation": "5347", + "range_level": "40", + "strength_level": "36" + }, + { + "id": "416", + "name": "Rock Golem", + "examine": "Rock with attitude.", + "aggressive": "true", + "attack_level": "64", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "156", + "defence_animation": "154", + "lifepoints": "86", + "projectile": "968", + "range_animation": "5347", + "range_level": "60", + "strength_level": "64" + }, + { + "id": "417", + "name": "Rock Golem", + "examine": "Rock with attitude.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "156", + "defence_animation": "154", + "lifepoints": "120", + "projectile": "968", + "range_animation": "5347", + "range_level": "75", + "strength_level": "100" + }, + { + "id": "418", + "name": "Rock Golem", + "examine": "Rock with attitude.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "156", + "defence_animation": "154", + "lifepoints": "166", + "projectile": "968", + "range_animation": "5347", + "range_level": "80", + "strength_level": "130" + }, + { + "id": "419", + "name": "Zombie", + "examine": "Dead man walking.", + "attack_level": "5", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "20", + "lifepoints": "14", + "magic_animation": "5578", + "magic_level": "5", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "5", + "safespot": null, + "strength_level": "5" + }, + { + "id": "420", + "name": "Zombie", + "examine": "Dead man walking.", + "attack_level": "10", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "40", + "lifepoints": "14", + "magic_animation": "5578", + "magic_level": "10", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "10", + "safespot": null, + "strength_level": "10" + }, + { + "id": "421", + "name": "Zombie", + "examine": "Dead man walking.", + "attack_level": "15", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "50", + "lifepoints": "30", + "magic_animation": "5578", + "magic_level": "15", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "15", + "safespot": null, + "strength_level": "15" + }, + { + "id": "422", + "name": "Zombie", + "examine": "Dead man walking.", + "attack_level": "45", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "60", + "lifepoints": "79", + "magic_animation": "5578", + "magic_level": "45", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "45", + "safespot": null, + "strength_level": "45" + }, + { + "id": "423", + "name": "Zombie", + "examine": "Dead man walking.", + "attack_level": "45", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "5578", + "magic_level": "35", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "45", + "safespot": null, + "strength_level": "45" + }, + { + "id": "424", + "name": "Zombie", + "examine": "Dead man walking.", + "attack_level": "45", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "90", + "lifepoints": "159", + "magic_animation": "5578", + "magic_level": "45", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "45", + "safespot": null, + "strength_level": "45" + }, + { + "id": "425", + "name": "Shade", + "examine": "Dead but not gone.", + "attack_level": "6", + "combat_audio": "511,439,438", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "7", + "lifepoints": "8", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "6", + "weakness": "9" + }, + { + "id": "426", + "name": "Shade", + "examine": "Dead but not gone.", + "attack_level": "20", + "combat_audio": "511,439,438", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "17", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "20", + "weakness": "9" + }, + { + "id": "427", + "name": "Shade", + "examine": "Dead but not gone.", + "attack_level": "43", + "combat_audio": "511,439,438", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "43", + "weakness": "9" + }, + { + "id": "428", + "name": "Shade", + "examine": "Dead but not gone.", + "attack_level": "74", + "combat_audio": "511,439,438", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "80", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "4.2", + "strength_level": "74", + "weakness": "9" + }, + { + "id": "429", + "name": "Shade", + "examine": "Dead but not gone.", + "attack_level": "130", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "511,439,438", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "130", + "lifepoints": "170", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "4.2", + "strength_level": "90", + "weakness": "9" + }, + { + "id": "430", + "name": "Shade", + "examine": "Dead but not gone.", + "attack_level": "150", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "105", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "150", + "weakness": "9" + }, + { + "id": "431", + "name": "Cyrisus" + }, + { + "id": "433", + "name": "Cyrisus" + }, + { + "id": "434", + "name": "Cyrisus" + }, + { + "id": "435", + "name": "Fallen Man", + "examine": "I hope he's not dead!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "436", + "name": "Fallen Man" + }, + { + "id": "437", + "name": "Cap'n Izzy No-Beard", + "examine": "Entrance clerk for the Brimhaven Agility Arena.", + "attack_level": "1", + "combat_audio": "498,500,499", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "438", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "97", + "defence_animation": "95", + "defence_level": "8", + "lifepoints": "25", + "magic_level": "1", + "melee_animation": "94", + "range_level": "1", + "safespot": null, + "strength_level": "8" + }, + { + "id": "439", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "17", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "97", + "defence_animation": "95", + "defence_level": "17", + "lifepoints": "40", + "magic_level": "1", + "melee_animation": "94", + "range_level": "1", + "safespot": null, + "strength_level": "17" + }, + { + "id": "440", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "97", + "defence_animation": "95", + "defence_level": "38", + "lifepoints": "60", + "magic_level": "1", + "melee_animation": "94", + "range_level": "1", + "safespot": null, + "strength_level": "38" + }, + { + "id": "441", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "64", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "97", + "defence_animation": "95", + "defence_level": "64", + "lifepoints": "86", + "magic_level": "1", + "melee_animation": "94", + "range_level": "1", + "safespot": null, + "strength_level": "64" + }, + { + "id": "442", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "97", + "defence_animation": "95", + "defence_level": "100", + "lifepoints": "120", + "magic_level": "1", + "melee_animation": "94", + "range_level": "1", + "safespot": null, + "strength_level": "100" + }, + { + "id": "443", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "97", + "defence_animation": "95", + "defence_level": "130", + "lifepoints": "170", + "magic_level": "1", + "melee_animation": "94", + "range_level": "1", + "safespot": null, + "strength_level": "130" + }, + { + "id": "444", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "445", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "446", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "5", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "2", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "8" + }, + { + "id": "447", + "name": "Jail guard", + "examine": "I wonder who he's guarding?", + "aggressive": "true", + "attack_level": "19", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "21", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23" + }, + { + "id": "448", + "name": "Jail guard", + "examine": "I wonder who he's guarding?", + "aggressive": "true", + "attack_level": "19", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "21", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23" + }, + { + "id": "449", + "name": "Jail guard", + "examine": "I wonder who he's guarding?", + "aggressive": "true", + "attack_level": "19", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "21", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23" + }, + { + "id": "450", + "name": "Gull", + "examine": "Flappy bird.", + "water_npc": "true" + }, + { + "id": "451", + "name": "Gull", + "examine": "Flappy bird.", + "water_npc": "true" + }, + { + "id": "452", + "name": "Seth Groats", + "examine": "A large well built farmer.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "453", + "name": "Suit of armour", + "examine": "Aargh! It's alive!", + "attack_level": "16", + "attack_speed": "5", + "bonuses": "8,8,8,0,0,46,50,46,-12,45,0,10,0,0,0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "29", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "14", + "weakness": "6" + }, + { + "id": "454", + "name": "Sanfew", + "examine": "An old druid." + }, + { + "id": "455", + "name": "Kaqemeex", + "examine": "A wise druid." + }, + { + "id": "456", + "name": "Father Aereck", + "examine": "He seems to be very devout.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "457", + "name": "Restless ghost", + "examine": "Eek! A ghost!", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "458", + "name": "Father Urhney", + "examine": "Very holy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "459", + "name": "Skeleton", + "examine": "It rattles when it moves.", + "aggressive": "true", + "attack_level": "3", + "combat_audio": "774,775,777", + "combat_style": "2", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "5", + "lifepoints": "14", + "magic_animation": "5485", + "magic_level": "5", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "3" + }, + { + "id": "460", + "name": "Wizard Frumscone", + "examine": "A Wizard of the Magic Guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "461", + "name": "Magic Store owner", + "examine": "A Supplier of Magical items.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "462", + "name": "Wizard Distentor", + "examine": "Head of the Magic Guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "463", + "name": "Murphy" + }, + { + "id": "464", + "name": "Murphy" + }, + { + "id": "465", + "name": "Murphy" + }, + { + "id": "466", + "name": "Murphy" + }, + { + "id": "467", + "name": "Shark" + }, + { + "id": "468", + "name": "Shark" + }, + { + "id": "469", + "name": "King Bolren", + "examine": "It's a gnome. He looks important.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "470", + "name": "Commander Montai", + "examine": "It's a tree gnome.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "471", + "name": "Bolkoy" + }, + { + "id": "472", + "name": "Remsai" + }, + { + "id": "473", + "name": "Khazard trooper" + }, + { + "id": "475", + "name": "Khazard trooper", + "examine": "It's one of General Khazard's warriors.", + "attack_level": "32", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "6" + }, + { + "id": "476", + "name": "Khazard trooper", + "examine": "An open eye of World-gorger.", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "11", + "magic_animation": "0", + "magic_level": "5", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "3" + }, + { + "id": "477", + "name": "Khazard warlord", + "examine": "He looks real nasty", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "38", + "weakness": "6" + }, + { + "id": "478", + "name": "Khazard commander", + "examine": "It's one of General Khazard's commanders.", + "attack_level": "35", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "479", + "name": "Gnome troop", + "examine": "It's a tree gnome trooper.", + "attack_level": "24", + "death_animation": "196", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "190", + "range_animation": "0", + "range_level": "32", + "safespot": null, + "strength_level": "24", + "weakness": "1" + }, + { + "id": "480", + "name": "Gnome troop" + }, + { + "id": "481", + "name": "Tracker gnome 1", + "examine": "It's a gnome who specialises in covert operations.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "482", + "name": "Tracker gnome 2", + "examine": "It's a gnome who specialises in covert operations.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "483", + "name": "Tracker gnome 3", + "examine": "It's a gnome who specialises in covert operations.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "484", + "name": "Local Gnome" + }, + { + "id": "485", + "name": "Local Gnome", + "examine": "It's a young tree gnome.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "486", + "name": "Kalron" + }, + { + "id": "487", + "name": "Giant", + "examine": "I guess he wants to be more than just the muscle.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "488", + "name": "Observatory professor", + "examine": "A man, learned in the ways of the stars.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "489", + "name": "Goblin guard", + "examine": "He doesn't look like he'd trust his own mother.", + "attack_level": "32", + "combat_audio": "469,472,471", + "death_animation": "6190", + "defence_animation": "0", + "defence_level": "37", + "lifepoints": "43", + "magic_animation": "0", + "melee_animation": "6199", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "37", + "weakness": "7" + }, + { + "id": "490", + "name": "Mummy", + "examine": "If the mummy is at school", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "491", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5542", + "defence_animation": "5541", "defence_level": "1", - "melee_animation": "7565", "lifepoints": "20", - "combat_audio": "12,3295,3287", - "id": "6744", - "defence_animation": "7559" + "melee_animation": "5540", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" }, { - "examine": "Distinctly heroic.", - "name": "Achietties", - "id": "796" + "id": "492", + "name": "Spirit of Scorpius", + "examine": "The essence of evil.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" }, { - "examine": "The hat is a dead give away.", - "name": "Wizard Cromperty", - "id": "2328" + "id": "493", + "name": "Grave scorpion", + "examine": "A vicious", + "aggressive": "true", + "attack_level": "5", + "combat_audio": "3611,3612,3610", + "death_animation": "6260", + "defence_animation": "0", + "defence_level": "7", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "6261", + "range_animation": "0", + "range_level": "7", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "2" }, { - "examine": "An intelligent-looking shop owner.", + "id": "494", + "name": "Banker", + "examine": "He can look after my money.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "495", + "name": "Banker", + "examine": "Good with money.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "496", + "name": "Banker", + "examine": "He can look after my money." + }, + { + "id": "497", + "name": "Banker", + "examine": "She can look after my money." + }, + { + "id": "498", + "name": "Banker", + "examine": "Manages money momentarily.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "499", + "name": "Banker", + "examine": "He can look after my money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "500", + "name": "Mosol Rei", + "examine": "A warrior from Shilo Village." + }, + { + "id": "501", + "name": "Spirit of Zadimus", + "examine": "An unquiet soul." + }, + { + "id": "502", + "name": "Undead one", + "examine": "A minion of Rashiliyia.", + "aggressive": "true", + "attack_level": "32", + "attack_speed": "5", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "8" + }, + { + "id": "503", + "name": "Undead one", + "examine": "A minion of Rashiliyia.", + "attack_level": "33", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "33", + "weakness": "8" + }, + { + "id": "504", + "name": "Undead one", + "examine": "The animated dead; one of Rashiliyia's minions.", + "aggressive": "true", + "attack_level": "32", + "attack_speed": "5", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "5568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "8" + }, + { + "id": "505", + "name": "Undead one", + "examine": "The animated dead; one of Rashiliyia's minions.", + "aggressive": "true", + "attack_level": "33", + "attack_speed": "5", + "death_animation": "5575", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", + "melee_animation": "5571", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "8" + }, + { + "id": "506", + "name": "Rashiliyia ", + "examine": "The animated spirit of Rashiliyia the Zombie Queen." + }, + { + "id": "507", + "name": "Nazastarool", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "5571", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "508", + "name": "Nazastarool", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5509", + "defence_animation": "5508", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "5507", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "509", + "name": "Nazastarool", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "110", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "510", + "name": "Hajedy", + "examine": "A cart driver; it looks like he's quite experienced." + }, + { + "id": "511", + "name": "Vigroy", + "examine": "A cart driver; it looks like he's quite experienced." + }, + { + "id": "512", + "name": "Kaleb Paramaya", + "examine": "This is Kaleb Paramaya, a warm and friendly inn owner." + }, + { + "id": "513", + "name": "Yohnus", + "examine": "This is Yohnus - he runs the local blacksmiths." + }, + { + "id": "514", + "name": "Seravel", + "examine": "This is Seravel. He sells tickets for the 'Lady of the Waves.'" + }, + { + "id": "515", + "name": "Yanni Salika", + "examine": "Yanni Salika; he buys and sells antiques." + }, + { + "id": "516", "name": "Obli", - "id": "516" + "examine": "An intelligent-looking shop owner." + }, + { + "id": "517", + "name": "Fernahei", + "examine": "This is Fernahei; he owns the local fishing tackle shop." + }, + { + "id": "518", + "name": "Captain Shanks", + "examine": "He's the Captain of the 'Lady of the Waves'.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "519", + "name": "Bob", + "examine": "An expert on axes.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "520", + "name": "Shopkeeper", + "examine": "Sells stuff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "521", + "name": "Shop assistant", + "examine": "Helps sell stuff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "522", + "name": "Shopkeeper", + "examine": "Likes people spending money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "523", + "name": "Shop assistant", + "examine": "Likes helping sell stuff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "524", + "name": "Shopkeeper", + "examine": "A product of a consumerist society.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "525", + "name": "Shop assistant", + "examine": "Likes you more, the more you spend.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "526", + "name": "Shopkeeper", + "examine": "A product of a consumerist society.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "527", + "name": "Shop assistant", + "examine": "Likes you more, the more you spend.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "528", + "name": "Shopkeeper", + "examine": "Sells stuff." + }, + { + "id": "529", + "name": "Shop assistant", + "examine": "Loves you more, the more you spend." + }, + { + "id": "530", + "name": "Shopkeeper", + "examine": "Has an interesting assortment of items for sale.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "531", + "name": "Shop assistant", + "examine": "Works on commission.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "532", + "name": "Shopkeeper Kofi", + "examine": "He clearly takes pride in his appearance.", + "aggressive": "true", + "attack_level": "60", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "285", + "magic_animation": "0", + "magic_level": "60", + "range_animation": "0", + "range_level": "60", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "533", + "name": "Shop assistant", + "examine": "Needs a haircut.", + "aggressive": "true", + "attack_level": "60", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "285", + "magic_animation": "0", + "magic_level": "60", + "range_animation": "0", + "range_level": "60", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "534", + "name": "Fairy shopkeeper", + "examine": "Sells stuff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "535", + "name": "Fairy shop assistant", + "examine": "Sells stuff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "536", + "name": "Valaine" + }, + { + "id": "537", + "name": "Scavvo" + }, + { + "id": "538", + "name": "Peksa", + "examine": "Always up-to-date with the latest helmet fashions." + }, + { + "id": "539", + "name": "Silk trader", + "examine": "Very snappily dressed.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "540", + "name": "Gem trader", + "examine": "Makes his money selling rocks.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "541", + "name": "Zeke", + "examine": "Sells superior scimitars." + }, + { + "id": "542", + "name": "Louie Legs", + "examine": "For the finest in armoured legware.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "543", + "name": "Karim", + "examine": "Kebabs are full of meaty goodness!" + }, + { + "id": "544", + "name": "Ranael", + "examine": "She's an expert on armoured skirts." + }, + { + "id": "545", + "name": "Dommik", + "examine": "If Crafting's your thing, he's your man." + }, + { + "id": "546", + "name": "Zaff", + "examine": "Sells superior staffs." + }, + { + "id": "547", + "name": "Baraek", + "examine": "Animal skins are a specialty." + }, + { + "id": "548", + "name": "Thessalia", + "examine": "Interesting assortment of clothes on offer..." + }, + { + "id": "549", + "name": "Horvik", + "examine": "The man with the armour." + }, + { + "id": "550", + "name": "Lowe", + "examine": "Sells arrows." + }, + { + "id": "551", + "name": "Shopkeeper", + "examine": "Ironically, makes a living from swords.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "552", + "name": "Shop assistant", + "examine": "Helps the shopkeeper sell swords.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "553", + "name": "Aubury" + }, + { + "id": "554", + "name": "Fancy-dress shop owner", + "examine": "For the interesting clothing items you just can't find elsewhere.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "555", + "name": "Shopkeeper", + "examine": "Has a fine moustache.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "556", + "name": "Grum", + "examine": "Loves his gold!" + }, + { + "id": "557", + "name": "Wydin", + "examine": "Likes his food to be kept fresh." + }, + { + "id": "558", + "name": "Gerrant", + "examine": "A Fishing expert." + }, + { + "id": "559", + "name": "Brian", + "examine": "An expert on axes." + }, + { + "id": "560", + "name": "Jiminua", + "examine": "Goods for sale and trade." + }, + { + "id": "561", + "name": "Shopkeeper", + "examine": "Could stand to lose a few pounds.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "562", + "name": "Candle-maker", + "examine": "Has an odd smell about him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "563", + "name": "Arhein" + }, + { + "id": "564", + "name": "Jukat", + "examine": "A being from a mysterious realm." + }, + { + "id": "565", + "name": "Lunderwin" + }, + { + "id": "566", + "name": "Irksol", + "examine": "Is he invisible, or just floating clothing?" + }, + { + "id": "567", + "name": "Fairy", + "examine": "Looks strange and mysterious.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "568", + "name": "Zambo", + "examine": "Appears slightly drunk." + }, + { + "id": "569", + "name": "Silver merchant", + "examine": "Looks fairly well fed.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "570", + "name": "Gem merchant", + "examine": "Seems very well-off.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "571", + "name": "Baker", + "examine": "So where are the butcher and the candlestick-maker?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "572", + "name": "Spice seller", + "examine": "Has a very exotic aroma about him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "573", + "name": "Fur trader", + "examine": "Knows how to keep warm in the winter.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "574", + "name": "Silk merchant", + "examine": "Seems very well-off.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "575", + "name": "Hickton" + }, + { + "id": "576", + "name": "Harry" + }, + { + "id": "577", + "name": "Cassie", + "examine": "Nice eyes." + }, + { + "id": "578", + "name": "Frincos" + }, + { + "id": "579", + "name": "Drogo dwarf", + "examine": "He runs a Mining store.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "580", + "name": "Flynn", + "examine": "The mace salesman." + }, + { + "id": "581", + "name": "Wayne", + "examine": "An armourer." + }, + { + "id": "582", + "name": "Dwarf", + "examine": "I wonder if he wants to buy my junk?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "583", + "name": "Betty", + "examine": "She seems like a nice sort of person." + }, + { + "id": "584", + "name": "Herquin" + }, + { + "id": "585", + "name": "Rommik" + }, + { + "id": "586", + "name": "Gaius", + "examine": "Ironically, makes a living from swords." + }, + { + "id": "587", + "name": "Jatix", + "examine": "He runs the Herblore Shop." + }, + { + "id": "588", + "name": "Davon", + "examine": "An amulet trader." + }, + { + "id": "589", + "name": "Zenesha" + }, + { + "id": "590", + "name": "Aemad" + }, + { + "id": "591", + "name": "Kortan" + }, + { + "id": "592", + "name": "Roachey" + }, + { + "id": "593", + "name": "Frenita" + }, + { + "id": "594", + "name": "Nurmof" + }, + { + "id": "595", + "name": "Tea seller", + "examine": "He seems to sell tea.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "596", + "name": "Fat Tony", + "examine": "A pizza expert; in both making and eating.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "597", + "name": "Noterazzo" + }, + { + "id": "598", + "name": "Hairdresser", + "examine": "Anyone fancy a trim?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "599", + "name": "Make-over Mage", + "examine": "Master of the mystical make-over.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "600", + "name": "Hudo" + }, + { + "id": "601", + "name": "Rometti" + }, + { + "id": "602", + "name": "Gulluck" + }, + { + "id": "603", + "name": "Heckel Funch" + }, + { + "id": "604", + "name": "Thurgo", + "examine": "Dwarvish." + }, + { + "id": "605", + "name": "Sir Vyvin", + "examine": "An elderly White Knight." + }, + { + "id": "606", + "name": "Squire", + "examine": "Indentured servant of a Knight.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "607", + "name": "Gunnjorn" + }, + { + "id": "608", + "name": "Sir Amik Varze" + }, + { + "id": "609", + "name": "Fortress Guard", + "examine": "A generic evil henchman.", + "attack_level": "26", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "610", + "name": "Black Knight Captain", + "examine": "One of the Black Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "611", + "name": "Witch", + "examine": "The Black Knights' resident witch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "612", + "name": "Greldo" + }, + { + "id": "613", + "name": "Digsite workman", + "examine": "This person is working on the site.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "614", + "name": "Doug Deeping", + "examine": "This person is working on the site.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "615", + "name": "Student", + "examine": "A student busy studying the digsite.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "616", + "name": "Student", + "examine": "A student busy studying the digsite.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "617", + "name": "Student", + "examine": "A student busy studying the digsite.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "618", + "name": "Examiner", + "examine": "Upon examining the examiner you examine it is indeed an examiner!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "619", + "name": "Archaeological expert", + "examine": "An expert on archaeology.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "620", + "name": "Panning guide", + "examine": "A specialist in panning for gold.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "621", + "name": "Gnome baller", + "examine": "A professional gnome baller.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "622", + "name": "Gnome baller" + }, + { + "id": "623", + "name": "Gnome baller" + }, + { + "id": "624", + "name": "Gnome baller" + }, + { + "id": "625", + "name": "Gnome baller" + }, + { + "id": "626", + "name": "Gnome baller" + }, + { + "id": "627", + "name": "Gnome baller" + }, + { + "id": "628", + "name": "Gnome baller" + }, + { + "id": "629", + "name": "Gnome baller" + }, + { + "id": "630", + "name": "Gnome baller" + }, + { + "id": "631", + "name": "Gnome baller" + }, + { + "id": "632", + "name": "Gnome baller" + }, + { + "id": "633", + "name": "Gnome winger", + "examine": "A professional gnome baller.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "634", + "name": "Gnome winger" + }, + { + "id": "635", + "name": "Gnome ball referee", + "examine": "Keeps the game fair.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "636", + "name": "Cheerleader" + }, + { + "id": "637", + "name": "Juliet", + "examine": "A tearful damsel, maybe I can help her?" + }, + { + "id": "638", + "name": "Apothecary", + "examine": "A dealer in potions.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "639", + "name": "Romeo", + "examine": "Rather dense and soppy looking." + }, + { + "id": "640", + "name": "Father Lawrence", + "examine": "A religious man... And occasional drunk.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "641", + "name": "Charlie the Tramp", + "examine": "Looks down on his luck.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "642", + "name": "Katrine" + }, + { + "id": "643", + "name": "Weaponsmaster", + "examine": "Looks kind of obsessive...", + "attack_level": "15", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "15", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "15", + "weakness": "9" + }, + { + "id": "644", + "name": "Straven" + }, + { + "id": "645", + "name": "Jonny the beard", + "examine": "Looks kind of shifty...", + "attack_level": "1", + "combat_audio": "498,500,499", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "646", + "name": "Curator Haig Halen", + "examine": "Curator of the museum.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "647", + "name": "King Roald" + }, + { + "id": "648", + "name": "King Roald", + "examine": "Varrock's resident monarch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "649", + "name": "Archer", + "examine": "She looks quite experienced.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "650", + "name": "Warrior", + "examine": "He looks big and dumb.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "651", + "name": "Monk", + "examine": "He looks holy.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "652", + "name": "Wizard", + "examine": "He looks kind of puny...", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "prj_height": "3", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "653", + "name": "Fairy Queen" + }, + { + "id": "654", + "name": "Shamus" + }, + { + "id": "655", + "name": "Tree spirit", + "examine": "Guardian of the dramen tree.", + "attack_level": "45", + "attack_speed": "5", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "45", + "weakness": "9" + }, + { + "id": "656", + "name": "Cave monk", + "examine": "Unsurprisingly monk like.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "657", + "name": "Monk of Entrana", + "examine": "Holy looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "658", + "name": "Monk of Entrana", + "examine": "Holy looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "659", + "name": "Party Pete", + "examine": "He likes to paaaarty!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "660", + "name": "Knight", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "661", + "name": "Megan" + }, + { + "id": "662", + "name": "Lucy" + }, + { + "id": "663", + "name": "Man", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "664", + "name": "Boot" + }, + { + "id": "665", + "name": "Boot", + "examine": "A short and angry dwarf.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "666", + "name": "Caleb" + }, + { + "id": "667", + "name": "Chronozon", + "examine": "Chronozon the blood demon.", + "aggressive": "true", + "attack_level": "173", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "173", + "lifepoints": "60", + "magic_level": "1", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "172" + }, + { + "id": "668", + "name": "Johnathon" + }, + { + "id": "669", + "name": "Hazelmere" + }, + { + "id": "670", + "name": "King Narnode Shareen", + "examine": "An important looking gnome.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "671", + "name": "Glough" + }, + { + "id": "672", + "name": "Anita" + }, + { + "id": "673", + "name": "Charlie" + }, + { + "id": "674", + "name": "Foreman", + "examine": "The boss!", + "attack_level": "20", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "9" + }, + { + "id": "675", + "name": "Shipyard worker", + "examine": "Builds ships for a living." + }, + { + "id": "676", + "name": "Femi" + }, + { + "id": "677", + "name": "Black demon", + "examine": "A big, scary, jet-black demon.", + "aggressive": "true", + "attack_level": "145", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "397,399,398", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "152", + "lifepoints": "157", + "magic_animation": "64", + "magic_level": "1", + "melee_animation": "64", + "range_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "157", + "strength_level": "148", + "weakness": "4" + }, + { + "id": "678", + "name": "Guard", + "examine": "Keeps order in the ranging guild.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "679", + "name": "Ranging Guild Doorman", + "examine": "The keeper of the gates to the ranging guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "680", + "name": "Leatherworker", + "examine": "An expert leatherworker.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "681", + "name": "Held vampyre juvinate", + "examine": "Mysterious swamp lights...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "682", + "name": "Armour salesman", + "examine": "Supplier of Rangers armour.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "683", + "name": "Bow and Arrow salesman", + "examine": "Supplier of Archery equipment.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "684", + "name": "Tower Advisor", + "examine": "Tower keeper and competition judge.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "685", + "name": "Tower Advisor" + }, + { + "id": "686", + "name": "Tower Advisor" + }, + { + "id": "687", + "name": "Tower Advisor" + }, + { + "id": "688", + "name": "Tower Archer", + "examine": "Defender of the north tower.", + "aggressive": "true", + "attack_level": "7", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "10", + "respawn_delay": "60", + "safespot": null, + "strength_level": "7", + "weakness": "0" + }, + { + "id": "689", + "name": "Tower Archer", + "examine": "Defender of the east tower.", + "aggressive": "true", + "attack_level": "15", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "20", + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "0" + }, + { + "id": "690", + "name": "Tower Archer", + "examine": "Defender of the south tower.", + "aggressive": "true", + "attack_level": "22", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "30", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "0" + }, + { + "id": "691", + "name": "Tower Archer", + "examine": "Defender of the west tower.", + "aggressive": "true", + "attack_level": "30", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "40", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "0" + }, + { + "id": "692", + "name": "Tribal Weapon Salesman", + "examine": "Supplier of authentic throwing weapons.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "693", + "name": "Competition Judge" + }, + { + "id": "694", + "name": "Ticket Merchant", + "examine": "Sells equipment in exchange for archery tickets.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "695", + "name": "Bailey" + }, + { + "id": "696", + "name": "Caroline", + "examine": "She looks very worried about something.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "697", + "name": "Holgart" + }, + { + "id": "698", + "name": "Holgart", + "examine": "A very good sailor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "699", + "name": "Holgart" + }, + { + "id": "700", + "name": "Holgart" + }, + { + "id": "701", + "name": "Kent" + }, + { + "id": "702", + "name": "Fisherman" + }, + { + "id": "703", + "name": "Fisherman" + }, + { + "id": "704", + "name": "Fisherman" + }, + { + "id": "705", + "name": "Melee tutor", + "examine": "Harlan, ready to teach swordplay.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "706", + "name": "Wizard Mizgog", + "examine": "An old wizard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "707", + "name": "Wizard Grayzag", + "examine": "Master of imps." + }, + { + "id": "708", + "name": "Imp", + "examine": "A cheeky little imp.", + "attack_level": "2", + "attack_speed": "5", + "combat_audio": "534,536,535", + "death_animation": "172", + "defence_animation": "170", + "defence_level": "2", + "lifepoints": "8", + "magic_animation": "169", + "melee_animation": "169", + "movement_radius": "25", + "range_animation": "169", + "range_level": "1", + "safespot": null, + "strength_level": "2", + "weakness": "7" + }, + { + "id": "709", + "name": "Imp", + "examine": "A cheeky little imp.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "534,536,535", + "death_animation": "172", + "defence_animation": "170", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "169", + "melee_animation": "169", + "movement_radius": "25", + "range_animation": "169", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "710", + "name": "Alrena" + }, + { + "id": "711", + "name": "Bravek" + }, + { + "id": "712", + "name": "Carla" + }, + { + "id": "713", + "name": "Clerk", + "examine": "A bureaucratic administrator.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "714", + "name": "Edmond", + "examine": "A local civilian.", + "attack_level": "", + "combat_audio": "", + "defence_level": "", + "lifepoints": "", + "range_level": "", + "safespot": null, + "slayer_exp": "", + "strength_level": "" + }, + { + "id": "715", + "name": "Elena", + "examine": "She looks concerned." + }, + { + "id": "716", + "name": "Head Mourner", + "examine": "In charge of people with silly outfits." + }, + { + "id": "717", + "name": "Mourner", + "examine": "A mourner, or plague healer." + }, + { + "id": "718", + "name": "Mourner", + "examine": "A mourner, or plague healer." + }, + { + "id": "719", + "name": "Mourner", + "examine": "A mourner, or plague healer." + }, + { + "id": "720", + "name": "Recruiter", + "examine": "A member of the Ardougne Royal Army.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "721", + "name": "Ted Rehnison" + }, + { + "id": "722", + "name": "Martha Rehnison" + }, + { + "id": "723", + "name": "Billy Rehnison" + }, + { + "id": "724", + "name": "Milli Rehnison" + }, + { + "id": "725", + "name": "Jethick" + }, + { + "id": "726", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "727", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "728", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "", + "clue_level": "", + "combat_audio": "", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "protect_style": "", + "range_animation": "", + "range_level": "", + "respawn_delay": "", + "safespot": "", + "slayer_exp": "", + "strength_level": "" + }, + { + "id": "729", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "", + "clue_level": "", + "combat_audio": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "730", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "731", + "name": "Bartender", + "examine": "I could get a beer from him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "732", + "name": "Bartender", + "examine": "I could get a beer from him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "733", + "name": "Bartender", + "examine": "I could get a beer from him." + }, + { + "id": "734", + "name": "Bartender", + "examine": "I could get a beer from him." + }, + { + "id": "735", + "name": "Bartender", + "examine": "I could get a beer from him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "736", + "name": "Emily", + "examine": "Works in the Rising Sun." + }, + { + "id": "737", + "name": "Bartender", + "examine": "I could get a beer from him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "738", + "name": "Bartender", + "examine": "I could get a beer from him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "739", + "name": "Bartender", + "examine": "I could get a beer from him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "740", + "name": "Trufitus", + "examine": "A wise old witch doctor." + }, + { + "id": "741", + "name": "Duke Horacio", + "examine": "Duke Horacio of Lumbridge.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "742", + "name": "Elvarg", + "examine": "Roar! A dragon!", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "death_animation": "4642", + "defence_animation": "89", + "defence_level": "70", + "lifepoints": "80", + "magic_level": "70", + "melee_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "strength_level": "70" + }, + { + "id": "743", + "name": "Ned", + "examine": "An old sailor." + }, + { + "id": "744", + "name": "Klarense", + "examine": "A young sailor." + }, + { + "id": "745", + "name": "Wormbrain", + "examine": "A badly-behaved goblin.", + "attack_level": "1", + "death_animation": "6204", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "6184", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "746", + "name": "Oracle" + }, + { + "id": "747", + "name": "Oziach", + "examine": "A strange little man." + }, + { + "id": "748", + "name": "Angry barbarian spirit" + }, + { + "id": "749", + "name": "Angry barbarian spirit", + "examine": "He looks a tad upset.", + "aggressive": "true", + "attack_level": "76", + "death_animation": "6727", + "defence_animation": "0", + "defence_level": "76", + "lifepoints": "108", + "magic_animation": "0", + "melee_animation": "6726", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "76", + "weakness": "6" + }, + { + "id": "750", + "name": "Enraged barbarian spirit", + "examine": "He looks a tad upset.", + "aggressive": "true", + "attack_level": "76", + "death_animation": "6727", + "defence_animation": "0", + "defence_level": "76", + "lifepoints": "108", + "magic_animation": "0", + "melee_animation": "6726", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "76", + "weakness": "6" + }, + { + "id": "751", + "name": "Berserk barbarian spirit", + "examine": "He looks a tad upset.", + "aggressive": "true", + "attack_level": "76", + "death_animation": "6727", + "defence_animation": "0", + "defence_level": "76", + "lifepoints": "108", + "magic_animation": "0", + "melee_animation": "6726", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "76", + "weakness": "6" + }, + { + "id": "752", + "name": "Ferocious barbarian spirit", + "examine": "He looks a tad upset.", + "aggressive": "true", + "attack_level": "76", + "bonuses": "80,100,60,70,85,70,70,90,60,100,50,90,90,0,0", + "death_animation": "6727", + "defence_animation": "0", + "defence_level": "76", + "lifepoints": "190", + "magic_animation": "0", + "melee_animation": "6726", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "76", + "weakness": "6" + }, + { + "id": "753", + "name": "Melzar the Mad", + "examine": "He looks totally insane!", + "aggressive": "true", + "attack_level": "28", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "magic_level": "28", + "melee_animation": "423", + "range_animation": "0", + "range_level": "28", + "respawn_delay": "60", + "safespot": null, + "strength_level": "28", + "weakness": "10" + }, + { + "id": "754", + "name": "Peaceful barbarian spirit" + }, + { + "id": "755", + "name": "Morgan", + "examine": "He looks scared." + }, + { + "id": "756", + "name": "Dr Harlow", + "examine": "A retired vampyre hunter." + }, + { + "id": "757", + "name": "Count Draynor", + "examine": "Stop looking and run!", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "5", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "20", + "lifepoints": "4", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "758", + "name": "Fred the Farmer", + "examine": "A well-fed farmer.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "759", + "name": "Kittens" + }, + { + "id": "761", + "name": "Kitten" + }, + { + "id": "762", + "name": "Kitten" + }, + { + "id": "763", + "name": "Kitten" + }, + { + "id": "764", + "name": "Kitten" + }, + { + "id": "765", + "name": "Kitten" + }, + { + "id": "766", + "name": "Kitten" + }, + { + "id": "767", + "name": "Crate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "combat_style": "2", + "death_animation": "196", + "defence_animation": "194", + "defence_level": "1", + "lifepoints": "88", + "melee_animation": "192", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "768", + "name": "Cat" + }, + { + "id": "769", + "name": "Cat" + }, + { + "id": "770", + "name": "Cat" + }, + { + "id": "771", + "name": "Cat" + }, + { + "id": "772", + "name": "Cat" + }, + { + "id": "773", + "name": "Cat" + }, + { + "id": "774", + "name": "Overgrown cat" + }, + { + "id": "775", + "name": "Overgrown cat" + }, + { + "id": "776", + "name": "Overgrown cat" + }, + { + "id": "777", + "name": "Overgrown cat" + }, + { + "id": "778", + "name": "Overgrown cat", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "66", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "779", + "name": "Overgrown cat" + }, + { + "id": "780", + "name": "Gertrude" + }, + { + "id": "781", + "name": "Shilop", + "examine": "One of Gertrude's Sons." + }, + { + "id": "782", + "name": "Philop" + }, + { + "id": "783", + "name": "Wilough", + "examine": "One of Gertrude's Sons." + }, + { + "id": "784", + "name": "Kanel" + }, + { + "id": "785", + "name": "Civilian", + "examine": "A citizen of Ardougne.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "786", + "name": "Civilian", + "examine": "A citizen of Ardougne.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "787", + "name": "Civilian", + "examine": "A citizen of Ardougne.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "788", + "name": "Garv", + "examine": "A diligent guard." + }, + { + "id": "789", + "name": "Grubor", + "examine": "A rough looking thief." + }, + { + "id": "790", + "name": "Letham", + "examine": "A gnome who's supposed to be cleaning up a mess.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "791", + "name": "Seth" + }, + { + "id": "792", + "name": "Grip", + "examine": "Looks like he's been in the wars." + }, + { + "id": "793", + "name": "Alfonse the waiter", + "examine": "Smartly dressed, and ready to deliver food.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "794", + "name": "Charlie the cook", + "examine": "Distinctly cook-like.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "795", + "name": "Ice Queen", + "examine": "A cold hearted lady.", + "attack_level": "95", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "95", + "lifepoints": "104", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "94", + "weakness": "10" + }, + { + "id": "796", + "name": "Achietties", + "examine": "Distinctly heroic." + }, + { + "id": "797", + "name": "Helemos" + }, + { + "id": "798", + "name": "Velrak the explorer", + "examine": "He looks cold and hungry.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "799", + "name": "Pirate Guard", + "examine": "A morally ambiguous guard.", + "attack_level": "30", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "800", + "name": "Fishing spot", + "examine": "It looks like there might be eels swimming in the lava.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "801", + "name": "Abbot Langley", + "examine": "A holy man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "802", + "name": "Brother Jered", + "examine": "A holy man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "803", + "name": "Monk", + "examine": "A holy man.", + "attack_level": "12", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "17", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "9" + }, + { + "id": "804", + "name": "Tanner", + "examine": "Manufacturer of fine leathers.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "805", + "name": "Master Crafter", + "examine": "He's in charge of the Crafting Guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "806", + "name": "Donovan the Family Handyman", + "examine": "He looks very tired...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "807", + "name": "Pierre", + "examine": "His job doesn't look very fun..." + }, + { + "id": "808", + "name": "Hobbes", + "examine": "He looks kind of stuck up..." + }, + { + "id": "809", + "name": "Louisa", + "examine": "She looks like she enjoys her job." + }, + { + "id": "810", + "name": "Mary", + "examine": "She looks very nervous..." + }, + { + "id": "811", + "name": "Stanford", + "examine": "He looks like he spends a lot of time outdoor." + }, + { + "id": "812", + "name": "Guard", + "examine": "An officer of the Law.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "813", + "name": "Gossip", + "examine": "One of those people who love to gossip!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "814", + "name": "Anna", + "examine": "She's dressed in a red top and green trousers." + }, + { + "id": "815", + "name": "Bob", + "examine": "He's dressed all in red." + }, + { + "id": "816", + "name": "Carol", + "examine": "She's wearing a blue top and red trousers." + }, + { + "id": "817", + "name": "David", + "examine": "He's dressed all in green." + }, + { + "id": "818", + "name": "Elizabeth", + "examine": "She's wearing a green top and blue trousers." + }, + { + "id": "819", + "name": "Frank", + "examine": "He's dressed all in blue." + }, + { + "id": "820", + "name": "Poison Salesman", + "examine": "He sure likes to sell stuff!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "821", + "name": "Sinclair Guard dog", + "examine": "Big, noisy, and scary looking!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "822", + "name": "Ana" + }, + { + "id": "823", + "name": "Ana" + }, + { + "id": "824", + "name": "Female slave" + }, + { + "id": "825", + "name": "Male slave", + "examine": "It looks like he's been here a long time.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "826", + "name": "Escaping slave" + }, + { + "id": "827", + "name": "Rowdy slave", + "examine": "He looks a bit aggressive.", + "aggressive": "true", + "attack_level": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "9" + }, + { + "id": "828", + "name": "Shanty Claws" + }, + { + "id": "829", + "name": "Mercenary Captain" + }, + { + "id": "830", + "name": "Mercenary Captain", + "examine": "He looks a bit aggressive.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "831", + "name": "Captain Siad", + "examine": "He's in control of the whole mining camp.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "832", + "name": "Al Shabim" + }, + { + "id": "833", + "name": "Bedabin Nomad", + "examine": "A Bedabin nomad", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "834", + "name": "Bedabin Nomad Guard", + "examine": "A Bedabin nomad guard - it looks like he's protecting an area.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "835", + "name": "Irena", + "examine": "A resident of Al Kharid." + }, + { + "id": "836", + "name": "Shantay", + "examine": "He's in control of the Shantay Pass." + }, + { + "id": "837", + "name": "Shantay Guard", + "examine": "He patrols the Shantay Pass.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "838", + "name": "Shantay Guard", + "examine": "He patrols the Shantay Pass.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "839", + "name": "Desert Wolf", + "examine": "A vicious desert wolf.", + "attack_level": "11", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "6559", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "840", + "name": "Ugthanki", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "9674", + "defence_level": "1", + "lifepoints": "46", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "841", + "name": "Mine cart driver", + "examine": "He looks busy attending to his cart.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "842", + "name": "Rowdy Guard", + "examine": "This pickaxe has been possessed by a dwarf ancestor spirit.", + "aggressive": "true", + "attack_level": "40", + "death_animation": "188", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "400", + "magic_animation": "0", + "melee_animation": "185", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40" + }, + { + "id": "843", + "name": "RPDT employee", + "examine": "Inefficient looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "844", + "name": "Horacio" + }, + { + "id": "846", + "name": "Kangai Mau", + "examine": "A happening kind of guy!" + }, + { + "id": "847", + "name": "Head chef", + "examine": "Despite his name", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "848", + "name": "Blurberry" + }, + { + "id": "849", + "name": "Barman" + }, + { + "id": "850", + "name": "Aluft Gianne snr.", + "examine": "The famous tree gnome chef.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "851", + "name": "Gnome Waiter", + "examine": "He can serve you gnome food.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "852", + "name": "Ogre chieftain", + "examine": "Tough-looking.", + "attack_level": "75", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,0,0,0,0,0,7,0,0,0", + "defence_animation": "0", + "defence_level": "75", + "lifepoints": "60", + "magic_animation": "0", + "magic_level": "1", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "300", + "safespot": null, + "strength_level": "71", + "weakness": "7" + }, + { + "id": "853", + "name": "Og" + }, + { + "id": "854", + "name": "Grew" + }, + { + "id": "855", + "name": "Toban" + }, + { + "id": "856", + "name": "Gorad", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "81", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "857", + "name": "Ogre guard" + }, + { + "id": "858", + "name": "Ogre guard", + "examine": "These ogres protect the city.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "859", + "name": "Ogre guard", + "examine": "An ogre that guards.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "860", + "name": "Ogre guard" + }, + { + "id": "861", + "name": "Ogre guard" + }, + { + "id": "862", + "name": "City guard", + "examine": "Tries to keep the peace.", + "attack_level": "58", + "death_animation": "8576", + "defence_animation": "0", + "defence_level": "58", + "lifepoints": "331", + "magic_animation": "0", + "melee_animation": "2100", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "58", + "weakness": "7" + }, + { + "id": "863", + "name": "Scared skavid", + "examine": "Frightened-looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "864", + "name": "Mad skavid", + "examine": "Looks mad.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "865", + "name": "Skavid" + }, + { + "id": "866", + "name": "Skavid" + }, + { + "id": "867", + "name": "Skavid" + }, + { + "id": "868", + "name": "Skavid" + }, + { + "id": "869", + "name": "Skavid" + }, + { + "id": "870", + "name": "Enclave guard", + "examine": "Big and ugly looking.", + "attack_level": "58", + "death_animation": "8576", + "defence_animation": "0", + "defence_level": "58", + "lifepoints": "331", + "magic_animation": "0", + "melee_animation": "2100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "58", + "weakness": "7" + }, + { + "id": "871", + "name": "Watchtower Wizard" + }, + { + "id": "872", + "name": "Watchtower Wizard", + "examine": "The hat is a dead giveaway.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "873", + "name": "Ogre trader", + "examine": "Funnily enough", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "874", + "name": "Ogre merchant", + "examine": "Funnily enough", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "875", + "name": "Ogre trader", + "examine": "Funnily enough", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "876", + "name": "Ogre trader" + }, + { + "id": "877", + "name": "Tower guard", + "examine": "Tries to keep the peace.", + "attack_level": "17", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "17", + "lifepoints": "97", + "magic_animation": "0", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "17", + "weakness": "7" + }, + { + "id": "878", + "name": "Colonel Radick", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "71", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "879", + "name": "Delrith", + "attack_level": "1", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "1", + "lifepoints": "7", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "880", + "name": "Weakened Delrith" + }, + { + "id": "881", + "name": "Traiborn", + "examine": "An old wizard." + }, + { + "id": "882", + "name": "Gypsy Aris", + "examine": "An old gypsy lady." + }, + { + "id": "883", + "name": "Sir Prysin", + "examine": "One of the king's knights." + }, + { + "id": "884", + "name": "Captain Rovin", + "examine": "The head of the palace guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "885", + "name": "Ceril Carnillean", + "examine": "Head of the Carnillean household.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "886", + "name": "Claus the chef", + "examine": "The Carnillean family chef." + }, + { + "id": "887", + "name": "Guard", + "examine": "On special duty to protect the Canilleans.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "888", + "name": "Philipe Carnillean" + }, + { + "id": "889", + "name": "Henryeta Carnillean", + "examine": "Ceril Carnillean's wife." + }, + { + "id": "890", + "name": "Butler Jones", + "examine": "The Carnellian family butler." + }, + { + "id": "891", + "name": "Alomone", + "examine": "Leader of the Hazeel cult." + }, + { + "id": "892", + "name": "Hazeel" + }, + { + "id": "893", + "name": "Clivet", + "examine": "A member of the Hazeel cult.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "811", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "894", + "name": "Hazeel Cultist", + "examine": "A member of the Hazeel cult.", + "attack_level": "15", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "magic_level": "20", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "3" + }, + { + "id": "895", + "name": "Boy", + "examine": "A sad looking child.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "896", + "name": "Nora T. Hagg" + }, + { + "id": "897", + "name": "Witch's experiment", + "examine": "Looks unnatural.", + "attack_level": "18", + "attack_speed": "4", + "death_animation": "258", + "defence_animation": "0", + "defence_level": "19", + "lifepoints": "21", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "255", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "10", + "weakness": "7" + }, + { + "id": "898", + "name": "Witch's experiment (second form)", + "examine": "Looks unnatural.", + "attack_level": "28", + "attack_speed": "4", + "death_animation": "5329", + "defence_animation": "0", + "defence_level": "29", + "lifepoints": "31", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5327", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "899", + "name": "Witch's experiment (third form)", + "examine": "Looks unnatural.", + "attack_level": "38", + "attack_speed": "4", + "death_animation": "4929", + "defence_animation": "0", + "defence_level": "39", + "lifepoints": "41", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4925", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "7" + }, + { + "id": "900", + "name": "Witch's experiment (fourth form)", + "examine": "Looks unnatural.", + "attack_level": "48", + "attack_speed": "4", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "51", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6559", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "901", + "name": "Mouse" + }, + { + "id": "902", + "name": "Gundai" + }, + { + "id": "903", + "name": "Lundail" + }, + { + "id": "904", + "name": "Chamber guardian", + "examine": "He hasn't seen much sun lately.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "905", + "name": "Kolodion", + "examine": "Runs the Mage Arena.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1" + }, + { + "id": "906", + "name": "Kolodion" + }, + { + "id": "907", + "name": "Kolodion", + "examine": "He's a shape-shifter", + "attack_level": "42", + "attack_speed": "7", + "combat_style": "2", + "death_animation": "1816", + "defence_animation": "404", + "defence_level": "20", + "lifepoints": "3", + "magic_level": "75", + "melee_animation": "811", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1" + }, + { + "id": "908", + "name": "Kolodion", + "examine": "He's a shape-shifter", + "attack_level": "74", + "attack_speed": "7", + "combat_style": "2", + "death_animation": "133", + "defence_animation": "404", + "defence_level": "25", + "lifepoints": "65", + "magic_level": "89", + "melee_animation": "132", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1" + }, + { + "id": "909", + "name": "Kolodion", + "examine": "He's a shape-shifter", + "attack_level": "74", + "attack_speed": "7", + "combat_style": "2", + "death_animation": "5323", + "defence_animation": "5320", + "defence_level": "28", + "lifepoints": "65", + "magic_level": "89", + "melee_animation": "5322", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1" + }, + { + "id": "910", + "name": "Kolodion", + "examine": "He's a shape-shifter", + "attack_level": "74", + "attack_speed": "7", + "combat_style": "2", + "death_animation": "714", + "defence_animation": "404", + "defence_level": "30", + "lifepoints": "78", + "magic_level": "89", + "melee_animation": "811", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1" + }, + { + "id": "911", + "name": "Kolodion", + "examine": "He's a shape-shifter", + "attack_level": "85", + "attack_speed": "7", + "death_animation": "68", + "defence_animation": "65", + "defence_level": "105", + "lifepoints": "107", + "magic_level": "80", + "melee_animation": "69", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "98" + }, + { + "id": "912", + "name": "Battle mage", + "examine": "He kills in the name of Zamorak.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "120", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "811", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "150", + "safespot": null, + "strength_level": "1", + "weakness": "3" + }, + { + "id": "913", + "name": "Battle mage", + "examine": "He kills in the name of Saradomin.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "120", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "811", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "914", + "name": "Battle mage", + "examine": "He kills in the name of Guthix.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "196", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "120", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "197", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "915", + "name": "Leela", + "examine": "She comes from Al-Kharid." + }, + { + "id": "916", + "name": "Joe", + "examine": "A crafter at the pinnacle of his art.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "917", + "name": "Jail guard", + "examine": "I wonder who he's guarding?", + "aggressive": "true", + "attack_level": "19", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "21", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23" + }, + { + "id": "918", + "name": "Ned" + }, + { + "id": "919", + "name": "Lady Keli", + "examine": "An infamous bandit." + }, + { + "id": "920", + "name": "Prince Ali", + "examine": "A young prince." + }, + { + "id": "921", + "name": "Prince Ali" + }, + { + "id": "922", + "name": "Aggie", + "examine": "A witch." + }, + { + "id": "923", + "name": "Hassan", + "examine": "The emir's chief advisor and physician.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "924", + "name": "Osman", + "examine": "Spymaster of Al Kharid." + }, + { + "id": "925", + "name": "Border Guard", + "examine": "Guards the border between Al Kharid and the Kingdom of Misthalin.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "926", + "name": "Border Guard" + }, + { + "id": "927", + "name": "Fishing spot" + }, + { + "id": "928", + "name": "Gujuo" + }, + { + "id": "929", + "name": "Ungadulu" + }, + { + "id": "930", + "name": "Ungadulu" + }, + { + "id": "931", + "name": "Jungle savage", + "examine": "An aggressive native of the Kharazi Jungle.", + "aggressive": "true", + "attack_level": "44", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "44", + "weakness": "6" + }, + { + "id": "932", + "name": "Fionella", + "examine": "She sells general items at the Legends Guild." + }, + { + "id": "933", + "name": "Siegfried Erkle" + }, + { + "id": "934", + "name": "Nezikchened", + "aggressive": "true", + "attack_level": "1", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "1", + "lifepoints": "150", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "935", + "name": "Viyeldi" + }, + { + "id": "936", + "name": "San Tojalon" + }, + { + "id": "937", + "name": "Irvig Senay" + }, + { + "id": "938", + "name": "Ranalph Devere", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "1", + "lifepoints": "130", + "melee_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "939", + "name": "Boulder", + "examine": "I wonder what this is doing here.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "940", + "name": "Echned Zekin" + }, + { + "id": "941", + "name": "Green dragon", + "examine": "Must be related to Elvarg.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "68", + "lifepoints": "75", + "magic_animation": "80", + "magic_level": "68", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "75", + "strength_level": "68", + "weakness": "3" + }, + { + "id": "942", + "name": "Master chef", + "examine": "An expert on all things culinary.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "943", + "name": "Survival expert", + "examine": "Very much an outdoors type.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "944", + "name": "Combat instructor", + "examine": "An expert on all forms of combat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "945", + "name": "RuneScape guide", + "examine": "Your introduction to the world of Gielinor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "946", + "name": "Magic instructor", + "examine": "A master of Magic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "947", + "name": "Financial advisor", + "examine": "An official representative from the First National Bank of Gielinor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "948", + "name": "Mining instructor", + "examine": "An expert on Mining-related skills.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "949", + "name": "Quest guide", + "examine": "Your introduction to the world of Gielinor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "950", + "name": "Giant rat", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "4933", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "951", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "952", + "name": "Fishing spot" + }, + { + "id": "953", + "name": "Banker" + }, + { + "id": "954", + "name": "Brother Brace", + "examine": "A holy man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "955", + "name": "Cow", + "examine": "Converts grass to beef.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "369,371,370", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", + "strength_level": "1", + "weakness": "8" + }, + { + "id": "956", + "name": "Drunken Dwarf", + "examine": "He's had a fair bit to drink...", + "attack_level": "5", + "attack_speed": "5", + "combat_audio": "2707,419,418", + "combat_style": "1", + "death_animation": "102", + "defence_animation": "101", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "99", + "magic_level": "20", + "melee_animation": "99", + "prj_height": "45", + "projectile": "33", + "range_animation": "99", + "range_level": "6", + "safespot": null, + "slayer_exp": "0", + "start_gfx": "", + "strength_level": "5" + }, + { + "id": "957", + "name": "Mubariz", + "examine": "Tough-looking combat type." + }, + { + "id": "958", + "name": "Fadli", + "examine": "Looks kinda bored." + }, + { + "id": "959", + "name": "A'abla", + "examine": "Trained to deal with all sorts of injuries." + }, + { + "id": "960", + "name": "Sabreen", + "examine": "Wow! She's made a statement with that hair!" + }, + { + "id": "961", + "name": "Surgeon General Tafani", + "examine": "This doctor really knows her stuff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "962", + "name": "Jaraah", + "examine": "Has the messy job of putting players back together again." + }, + { + "id": "963", + "name": "Zahwa", + "examine": "Battle-scarred." + }, + { + "id": "964", + "name": "Ima", + "examine": "A citizen of Al Kharid" + }, + { + "id": "965", + "name": "Sabeil", + "examine": "A citizen of Al Kharid" + }, + { + "id": "966", + "name": "Jadid", + "examine": "A citizen of Al Kharid" + }, + { + "id": "967", + "name": "Dalal", + "examine": "A citizen of Al Kharid" + }, + { + "id": "968", + "name": "Afrah", + "examine": "A citizen of Al Kharid" + }, + { + "id": "969", + "name": "Jeed", + "examine": "A citizen of Al Kharid" + }, + { + "id": "970", + "name": "Diango", + "examine": "He smells funny." + }, + { + "id": "971", + "name": "Chadwell", + "examine": "Shopkeeper." + }, + { + "id": "972", + "name": "Koftik", + "examine": "The cave guide." + }, + { + "id": "973", + "name": "Koftik", + "examine": "The cave guide." + }, + { + "id": "974", + "name": "Koftik", + "examine": "The cave guide." + }, + { + "id": "975", + "name": "Koftik", + "examine": "The cave guide." + }, + { + "id": "976", + "name": "Koftik", + "examine": "The cave guide." + }, + { + "id": "977", + "name": "Blessed spider", + "examine": "It's one of Iban's pets.", + "attack_level": "22", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "5327", + "range_animation": "0", + "range_level": "30", + "safespot": null, + "strength_level": "22", + "weakness": "2" + }, + { + "id": "978", + "name": "Blessed giant rat", + "examine": "It's one of Iban's pet vermin.", + "attack_level": "12", + "combat_audio": "703,705,704", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "17", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "9" + }, + { + "id": "979", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "980", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "981", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "982", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "983", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "984", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "985", + "name": "Slave", + "examine": "A wretched slave of Iban.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "986", + "name": "Boulder", + "examine": "Precariously balanced...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "987", + "name": "Unicorn", + "attack_level": "1", + "combat_audio": "369,371,370", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "988", + "name": "Sir Jerro", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "57", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "989", + "name": "Sir Carl", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "57", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "990", + "name": "Sir Harry", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "57", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "991", + "name": "Half-soulless", + "examine": "A creature empty of emotion.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "992", + "name": "Kardia" + }, + { + "id": "993", + "name": "Witch's cat", + "examine": "Curiosity is yet to kill this one...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "994", + "name": "Niloof" + }, + { + "id": "995", + "name": "Klank", + "examine": "A dwarven maker of gauntlets." + }, + { + "id": "996", + "name": "Kamen", + "examine": "This dwarf looks intoxicated." + }, + { + "id": "997", + "name": "Kalrag", + "examine": "A giant spider.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5321", + "defence_animation": "5320", + "defence_level": "1", + "lifepoints": "91", + "melee_animation": "5319", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "998", + "name": "Othainian", + "examine": "One of the guardians of Iban.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "1", + "lifepoints": "90", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "999", + "name": "Doomion", + "examine": "One of the guardians of Iban.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "1", + "lifepoints": "90", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1000", + "name": "Holthion", + "examine": "One of the guardians of Iban.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "1", + "lifepoints": "90", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1001", + "name": "Dark mage", + "examine": "A user of dark magic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "3" + }, + { + "id": "1002", + "name": "Disciple of Iban", + "examine": "A dark magic user.", + "attack_level": "24", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "32", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "24", + "weakness": "3" + }, + { + "id": "1003", + "name": "Lord Iban" + }, + { + "id": "1004", + "name": "Spider", + "examine": "Incey wincey.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "6251", + "defence_animation": "6250", + "defence_level": "1", + "lifepoints": "2", + "melee_animation": "6249", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1005", + "name": "Giant bat", + "examine": "An annoying flappy thing.", + "attack_level": "22", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "combat_audio": "292,294,293", + "defence_level": "22", + "lifepoints": "32", + "magic_level": "1", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "8", + "strength_level": "22" + }, + { + "id": "1006", + "name": "Sea slug", + "examine": "A rather nasty looking crustacean." + }, + { + "id": "1007", + "name": "Zamorak wizard", + "examine": "A servant of Zamorak.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "73", + "magic_animation": "811", + "magic_level": "60", + "melee_animation": "811", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "60", + "safespot": null, + "spell_id": "43", + "strength_level": "50", + "weakness": "3" + }, + { + "id": "1008", + "name": "Hamid" + }, + { + "id": "1009", + "name": "Poison spider", + "examine": "A nasty, poisonous arachnid.", + "aggressive": "true", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "28", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "5327", + "poison_amount": "30", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "28", + "weakness": "2" + }, + { + "id": "1010", + "name": "Rantz", + "examine": "He hungry.", + "combat_style": "1", + "prj_height": "50", + "projectile": "242", + "range_animation": "3460", + "start_gfx": "243", + "start_height": "100" + }, + { + "id": "1011", + "name": "Fycie" + }, + { + "id": "1012", + "name": "Bugs" + }, + { + "id": "1013", + "name": "Swamp toad", + "examine": "A green skinned croaker", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "34", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1014", + "name": "Bloated Toad" + }, + { + "id": "1015", + "name": "Iron pickaxe", + "examine": "Useful for hitting rocks.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1016", + "name": "Chompy bird" + }, + { + "id": "1017", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1018", + "name": "Rooster", + "examine": "He rules the", + "attack_level": "2", + "death_animation": "5389", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "5387", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2", + "weakness": "9" + }, + { + "id": "1019", + "name": "Fire elemental", + "examine": "A fire elemental.", + "attack_level": "24", + "combat_audio": "1534,1536,1535", + "death_animation": "1031", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "32", + "melee_animation": "1029", + "movement_radius": "4", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "24", + "weakness": "3" + }, + { + "id": "1020", + "name": "Earth elemental", + "examine": "An earth elemental.", + "aggressive": "false", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "1531,1533,1532", + "death_animation": "4870", + "defence_animation": "4869", + "defence_level": "35", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "10", + "melee_animation": "4868", + "movement_radius": "4", + "range_animation": "0", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "strength_level": "32", + "weakness": "7" + }, + { + "id": "1021", + "name": "Air elemental", + "examine": "An air elemental.", + "attack_level": "24", + "combat_audio": "1527,1529,1528", + "death_animation": "1041", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "1040", + "movement_radius": "4", + "range_animation": "0", + "range_level": "32", + "respawn_delay": "60", + "safespot": null, + "strength_level": "24", + "weakness": "1" + }, + { + "id": "1022", + "name": "Water elemental", + "examine": "A water elemental.", + "attack_level": "24", + "combat_audio": "1546,1543,1545", + "death_animation": "1048", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "1044", + "movement_radius": "4", + "range_animation": "0", + "range_level": "32", + "respawn_delay": "60", + "safespot": null, + "strength_level": "24", + "weakness": "1" + }, + { + "id": "1023", + "name": "Vampire", + "examine": "It looks very hungry!", + "attack_level": "52", + "clue_level": "1", + "death_animation": "7185", + "defence_level": "52", + "lifepoints": "50", + "melee_animation": "7183", + "range_level": "1", + "safespot": null, + "slayer_exp": "50", + "strength_level": "1" + }, + { + "id": "1024", + "name": "Baby impling" + }, + { + "id": "1028", + "name": "Baby Impling", + "examine": "A baby impling. Ahhh." + }, + { + "id": "1029", + "name": "Young Impling", + "examine": "A young impling. It's not fair!" + }, + { + "id": "1030", + "name": "Gourmet Impling", + "examine": "An impling gourmet. Mmmm, tasty." + }, + { + "id": "1031", + "name": "Earth Impling", + "examine": "An earth impling. Rock on." + }, + { + "id": "1032", + "name": "Essence Impling", + "examine": "An impling who likes magic. Magic!" + }, + { + "id": "1033", + "name": "Eclectic Impling", + "examine": "An impling with varied tastes." + }, + { + "id": "1034", + "name": "Nature Impling", + "examine": "A nature impling. Right on, maaan." + }, + { + "id": "1035", + "name": "Magpie Impling", + "examine": "Ooh, shiny things!" + }, + { + "id": "1036", + "name": "Banker" + }, + { + "id": "1037", + "name": "Prissy Scilla", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "1038", + "name": "Rufus" + }, + { + "id": "1039", + "name": "Barker" + }, + { + "id": "1040", + "name": "Fidelio" + }, + { + "id": "1041", + "name": "Sbott" + }, + { + "id": "1042", + "name": "Roavar" + }, + { + "id": "1043", + "name": "Will o' the wisp" + }, + { + "id": "1044", + "name": "Monk of Zamorak", + "examine": "An evil human cleric.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "22", + "end_gfx": "101", + "lifepoints": "20", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "422", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "strength_level": "18", + "weakness": "3" + }, + { + "id": "1045", + "name": "Monk of Zamorak", + "examine": "An evil human cleric.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "17", + "end_gfx": "101", + "lifepoints": "10", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "422", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "strength_level": "8", + "weakness": "3" + }, + { + "id": "1046", + "name": "Monk of Zamorak", + "examine": "An evil human cleric.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "25", + "end_gfx": "101", + "lifepoints": "25", + "magic_animation": "711", + "magic_level": "40", + "melee_animation": "422", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "strength_level": "25", + "weakness": "3" + }, + { + "id": "1047", + "name": "Drezel" + }, + { + "id": "1049", + "name": "Drezel", + "examine": "A holy man." + }, + { + "id": "1050", + "name": "Filiman Tarlock", + "examine": "The animated spirit of a soul not at rest." + }, + { + "id": "1051", + "name": "Nature Spirit", + "examine": "The animated spirit of a soul not at rest." + }, + { + "id": "1052", + "name": "Ghast", + "examine": "Arrghhh... a Ghast.", + "aggressive": "false", + "attack_level": "1", + "combat_audio": "433,435,434", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1053", + "name": "Ghast", + "examine": "Arrghhh... A Ghast.", + "aggressive": "true", + "attack_level": "22", + "attack_speed": "4", + "combat_audio": "433,435,434", + "death_animation": "1089", + "death_gfx": "265", + "defence_animation": "1088", + "defence_level": "18", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1087", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "9" + }, + { + "id": "1054", + "name": "Ulizius", + "examine": "A slightly nervous guard." + }, + { + "id": "1055", + "name": "Pirate Jackie the Fruit", + "examine": "Ticket trader for the Brimhaven Agility Arena.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1056", + "name": "Mime" + }, + { + "id": "1057", + "name": "Strange watcher", + "examine": "A member of the audience.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1058", + "name": "Strange watcher", + "examine": "A member of the audience.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1059", + "name": "Strange watcher", + "examine": "A member of the audience.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1060", + "name": "Denulth", + "examine": "Commander of the Imperial Guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1061", + "name": "Sergeant", + "examine": "A sergeant of the Imperial Guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1062", + "name": "Sergeant", + "examine": "A sergeant of the Imperial Guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1063", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1064", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1065", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "44", + "combat_audio": "511,513,512", + "defence_level": "44", + "lifepoints": "55", + "magic_level": "1", + "range_level": "1", + "safespot": null, + "strength_level": "44" + }, + { + "id": "1066", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1067", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1068", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1069", + "name": "Soldier", + "examine": "A soldier of the Imperial Guard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1070", + "name": "Saba" + }, + { + "id": "1071", + "name": "Tenzing" + }, + { + "id": "1072", + "name": "Eadburg", + "examine": "The Burthorpe Castle cook.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2" + }, + { + "id": "1073", + "name": "Archer", + "examine": "A Burthorpe Castle Archer.", + "attack_level": "1", + "bonuses": "54,68,75,72,67,81,54,35,35,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "44", + "lifepoints": "55", + "magic_animation": "426", + "magic_level": "1", + "melee_animation": "426", + "projectile": "10", + "range_animation": "426", + "range_level": "44", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "19", + "strength_level": "1" + }, + { + "id": "1074", + "name": "Archer", + "examine": "A Burthorpe Castle Archer.", + "attack_level": "1", + "bonuses": "54,68,75,72,67,81,54,35,35,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "44", + "lifepoints": "55", + "magic_animation": "426", + "magic_level": "1", + "melee_animation": "426", + "projectile": "10", + "range_animation": "426", + "range_level": "44", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "19", + "strength_level": "1" + }, + { + "id": "1075", + "name": "Archer" + }, + { + "id": "1076", + "name": "Guard", + "examine": "A Burthorpe Castle guard.", + "attack_level": "33", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "33", + "lifepoints": "44", + "magic_level": "1", + "melee_animation": "401", + "range_level": "1", + "safespot": null, + "strength_level": "33" + }, + { + "id": "1077", + "name": "Guard", + "examine": "A Burthorpe Castle guard.", + "attack_level": "33", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "33", + "lifepoints": "44", + "magic_level": "1", + "melee_animation": "401", + "range_level": "1", + "safespot": null, + "strength_level": "33" + }, + { + "id": "1078", + "name": "Harold", + "examine": "An off-duty Burthorpe Castle guard." + }, + { + "id": "1079", + "name": "Tostig", + "examine": "Barman of the Toad and Chicken." + }, + { + "id": "1080", + "name": "Eohric", + "examine": "Head servant for Prince Anlaf." + }, + { + "id": "1081", + "name": "Servant", + "examine": "A servant for Prince Anlaf.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3" + }, + { + "id": "1082", + "name": "Dunstan", + "examine": "Smithy for Burthorpe." + }, + { + "id": "1083", + "name": "Wistan", + "examine": "Shopkeeper for Burthorpe." + }, + { + "id": "1084", + "name": "Breoca", + "examine": "A citizen of Burthorpe.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3" + }, + { + "id": "1085", + "name": "Ocga", + "examine": "A citizen of Burthorpe.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3" + }, + { + "id": "1086", + "name": "Man", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1087", + "name": "Penda", + "examine": "A citizen of Burthorpe.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3" + }, + { + "id": "1088", + "name": "Hygd", + "examine": "A citizen of Burthorpe.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2" + }, + { + "id": "1089", + "name": "Ceolburg", + "examine": "A citizen of Burthorpe.", + "attack_level": "3", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "3", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2" + }, + { + "id": "1090", + "name": "Hild", + "examine": "A pretty young woman with an air of mystery around her." + }, + { + "id": "1091", + "name": "Bob" + }, + { + "id": "1092", + "name": "White Knight", + "examine": "The knight seems to be watching something.", + "attack_level": "27", + "attack_speed": "8", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "27", + "lifepoints": "38", + "magic_animation": "0", + "melee_animation": "7042", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "27", + "weakness": "9" + }, + { + "id": "1093", + "name": "Billy" + }, + { + "id": "1094", + "name": "Mountain goat" + }, + { + "id": "1095", + "name": "Rock", + "examine": "The biggest and baddest troll.", + "aggressive": "true", + "attack_level": "70", + "bonuses": "60,60,60,0,0,35,60,35,200,200,0,100,0,0,0", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "0", + "melee_animation": "6523", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "110", + "weakness": "7" + }, + { + "id": "1096", + "name": "Stick", + "examine": "Careful, he is a big.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "7", + "bonuses": "50,50,50,0,0,30,30,50,200,200,0,80,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "135", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "110", + "weakness": "7" + }, + { + "id": "1097", + "name": "Pee Hat", + "examine": "A nasty looking troll.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "6", + "bonuses": "40,40,40,0,0,25,25,40,200,200,0,70,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "50", + "lifepoints": "120", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "7" + }, + { + "id": "1098", + "name": "Kraka", + "examine": "A nasty looking troll.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "6", + "bonuses": "40,40,40,0,0,25,25,40,200,400,0,70,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "50", + "lifepoints": "120", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "7" + }, + { + "id": "1099", + "name": "Dung", + "examine": "Human is his speciality.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "1100", + "name": "Ash", + "examine": "Human is his speciality.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "1101", + "name": "Thrower Troll", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "agg_radius": "6", + "attack_level": "41", + "attack_speed": "7", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1102", + "name": "Thrower Troll", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "agg_radius": "6", + "attack_level": "41", + "attack_speed": "7", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1103", + "name": "Thrower Troll", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "agg_radius": "6", + "attack_level": "41", + "attack_speed": "7", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1104", + "name": "Thrower Troll", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "agg_radius": "6", + "attack_level": "41", + "attack_speed": "7", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1105", + "name": "Thrower Troll", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "agg_radius": "6", + "attack_level": "41", + "attack_speed": "7", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1106", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1107", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1108", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1109", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1110", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1111", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1112", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1113", + "name": "Eadgar" + }, + { + "id": "1114", + "name": "Godric" + }, + { + "id": "1115", + "name": "Troll general", + "examine": "One of the troll generals.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "92", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "1116", + "name": "Troll general", + "examine": "One of the troll generals.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "92", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "1117", + "name": "Troll general", + "examine": "One of the troll generals.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "92", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "1118", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1119", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1120", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1121", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1122", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1123", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1124", + "name": "Troll spectator", + "examine": "He's watching the arena.", + "attack_level": "47", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1259", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "1125", + "name": "Dad", + "examine": "An unusually large troll.", + "attack_level": "60", + "bonuses": "40,40,40,0,0,25,25,40,200,200,0,70,0,0,0", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "120", + "magic_animation": "0", + "melee_animation": "1158", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "120", + "weakness": "7" + }, + { + "id": "1126", + "name": "Twig", + "examine": "He's guarding the cells.", + "aggressive": "true", + "attack_level": "40", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "1158", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "90", + "weakness": "7" + }, + { + "id": "1127", + "name": "Berry", + "examine": "He's guarding the cells.", + "aggressive": "true", + "attack_level": "40", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "death_animation": "287", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "1158", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "90", + "weakness": "7" + }, + { + "id": "1128", + "name": "Twig", + "examine": "He's guarding the cells.", + "attack_level": "40", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "90", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "90", + "weakness": "7" + }, + { + "id": "1129", + "name": "Berry", + "examine": "He's guarding the cells.", + "attack_level": "40", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "90", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "90", + "weakness": "7" + }, + { + "id": "1130", + "name": "Thrower troll", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "aggressive": "true", + "attack_level": "41", + "attack_speed": "7", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "start_gfx": "33", + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1131", + "name": "Thrower troll", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "41", + "attack_speed": "7", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "start_gfx": "33", + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1132", + "name": "Thrower troll", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "41", + "attack_speed": "7", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "start_gfx": "33", + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1133", + "name": "Thrower troll", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "41", + "attack_speed": "7", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "start_gfx": "33", + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1134", + "name": "Thrower troll", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "41", + "attack_speed": "7", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "30", + "lifepoints": "95", + "magic_animation": "284", + "melee_animation": "284", + "projectile": "276", + "range_animation": "284", + "range_level": "40", + "respawn_delay": "35", + "safespot": null, + "start_gfx": "33", + "strength_level": "41", + "weakness": "0" + }, + { + "id": "1135", + "name": "Cook", + "examine": "Human is his speciality.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1136", + "name": "Cook", + "examine": "Human is his speciality.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1137", + "name": "Cook", + "examine": "Human is his speciality.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1138", + "name": "Mountain troll", + "examine": "Small for a troll, but mean and ugly.", + "attack_level": "53", + "attack_speed": "5", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "53", + "lifepoints": "90", + "magic_animation": "284", + "melee_animation": "284", + "range_animation": "284", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1139", + "name": "Mushroom", + "examine": "He's fast asleep.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1140", + "name": "Mountain goat", + "examine": "This beast doesn't need climbing boots.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1141", + "name": "Mountain goat", + "examine": "This beast doesn't need climbing boots.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1142", + "name": "Guard", + "examine": "He's guarding the storeroom.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1143", + "name": "Guard", + "examine": "He's guarding the storeroom.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1144", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1145", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1146", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1147", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1148", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1149", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1150", + "name": "Guard", + "examine": "He's guarding the goutweed.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1151", + "name": "Burntmeat", + "examine": "Human is his speciality.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1152", + "name": "Weird Old Man", + "examine": "What's he mumbling about?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1153", + "name": "Kalphite Worker", + "examine": "I don't think insect repellent will work...", + "attack_level": "20", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,1,10,10,0,0,0,0,0", + "combat_audio": "571,573,572", + "death_animation": "6230", + "defence_animation": "6232", + "defence_level": "20", + "lifepoints": "40", + "magic_animation": "6223", + "magic_level": "1", + "melee_animation": "6223", + "range_animation": "6223", + "range_level": "1", + "respawn_delay": "38", + "safespot": null, + "slayer_exp": "40", + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1154", + "name": "Kalphite Soldier", + "examine": "I don't think insect repellent will work...", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "combat_audio": "567,569,568", + "death_animation": "6228", + "defence_animation": "6227", + "defence_level": "70", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6224", + "poison_amount": "20", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "90", + "strength_level": "70", + "weakness": "7" + }, + { + "id": "1155", + "name": "Kalphite Guardian", + "examine": "I don't think insect repellent will work...", + "aggressive": "true", + "attack_level": "110", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "death_animation": "6230", + "defence_animation": "6232", + "defence_level": "110", + "lifepoints": "170", + "magic_animation": "6223", + "magic_level": "1", + "melee_animation": "6223", + "poison_amount": "30", + "poisonous": "true", + "range_animation": "6223", + "range_level": "1", + "respawn_delay": "65", + "safespot": null, + "strength_level": "110", + "weakness": "7" + }, + { + "id": "1156", + "name": "Kalphite Worker", + "examine": "I don't think insect repellent will work...", + "attack_level": "20", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,1,10,10,0,0,0,0,0", + "combat_audio": "571,573,572", + "death_animation": "6230", + "defence_animation": "6232", + "defence_level": "20", + "lifepoints": "40", + "magic_animation": "6223", + "magic_level": "1", + "melee_animation": "6223", + "range_animation": "6223", + "range_level": "1", + "respawn_delay": "38", + "safespot": null, + "slayer_exp": "40", + "strength_level": "20", + "weakness": "7" + }, + { + "id": "1157", + "name": "Kalphite Guardian", + "examine": "I don't think insect repellent will work...", + "aggressive": "true", + "attack_level": "110", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "death_animation": "6230", + "defence_animation": "6232", + "defence_level": "110", + "lifepoints": "170", + "magic_animation": "6223", + "magic_level": "1", + "melee_animation": "6223", + "poison_amount": "30", + "poisonous": "true", + "range_animation": "6223", + "range_level": "1", + "respawn_delay": "65", + "safespot": null, + "strength_level": "110", + "weakness": "7" + }, + { + "id": "1158", + "name": "Kalphite Queen", + "examine": "I don't think insect repellent will work...", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "300", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,50,10,100,100,0,0,0,0,0", + "death_animation": "6242", + "defence_animation": "6232", + "defence_level": "300", + "lifepoints": "255", + "magic_animation": "6241", + "magic_level": "150", + "melee_animation": "6241", + "poisonous": "", + "range_animation": "6241", + "range_level": "1000", + "respawn_delay": "0", + "safespot": null, + "strength_level": "300", + "weakness": "10" + }, + { + "id": "1159", + "name": "Kalphite Queen" + }, + { + "id": "1160", + "name": "Kalphite Queen", + "examine": "I don't think insect repellent will work...", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "300", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,100,100,100,10,10,0,0,0,0,0", + "death_animation": "6233", + "defence_animation": "6234", + "defence_level": "300", + "lifepoints": "255", + "magic_animation": "6235", + "magic_level": "150", + "melee_animation": "6235", + "range_animation": "6235", + "range_level": "1000", + "respawn_delay": "45", + "safespot": null, + "strength_level": "300", + "weakness": "10" + }, + { + "id": "1161", + "name": "Kalphite Larva", + "examine": "I don't think insect repellent will work...", + "aggressive": "false", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1162", + "name": "Timfraku", + "examine": "The imposing Chief of Tai Bwo Wannai." + }, + { + "id": "1163", + "name": "Tiadeche", + "examine": "A rather depressed looking fisherman." + }, + { + "id": "1164", + "name": "Tiadeche", + "examine": "A rather depressed looking fisherman." + }, + { + "id": "1165", + "name": "Tinsay" + }, + { + "id": "1166", + "name": "Tinsay" + }, + { + "id": "1167", + "name": "Tamayu", + "examine": "A hunter who long ago succumbed to blood lust." + }, + { + "id": "1168", + "name": "Tamayu" + }, + { + "id": "1169", + "name": "Tamayu" + }, + { + "id": "1170", + "name": "Tamayu" + }, + { + "id": "1171", + "name": "Lubufu", + "examine": "A crotchety old fisherman who doesn't like young whippersnappers." + }, + { + "id": "1172", + "name": "The Shaikahan", + "examine": "A huge beast, resembling in some ways a lion, but mostly a twisted nightmare.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "death_animation": "1201", + "defence_animation": "1200", + "defence_level": "50", + "lifepoints": "100", + "magic_animation": "1197", + "melee_animation": "1199", + "range_animation": "1197", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "1173", + "name": "The Shaikahan" + }, + { + "id": "1174", + "name": "Fishing spot" + }, + { + "id": "1175", + "name": "Fishing spot" + }, + { + "id": "1176", + "name": "Fishing spot", + "examine": "I can see fish swimming in the water." + }, + { + "id": "1177", + "name": "Fishing spot" + }, + { + "id": "1178", + "name": "Fishing spot" + }, + { + "id": "1179", + "name": "Gull", + "examine": "Flappy bird.", + "water_npc": "true" + }, + { + "id": "1180", + "name": "Cormorant", + "examine": "A sea bird." + }, + { + "id": "1181", + "name": "Pelican", + "examine": "A sea bird." + }, + { + "id": "1182", + "name": "Lord Iorwerth" + }, + { + "id": "1183", + "name": "Elf warrior", + "examine": "He looks pretty handy with that bow.", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "428", + "projectile": "249", + "range_animation": "426", + "range_level": "72", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "250", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "1184", + "name": "Elf warrior", + "examine": "I don't wanna be at the wrong end of that pike.", + "attack_level": "68", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "425,427,426", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "68", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "68", + "weakness": "9" + }, + { + "id": "1185", + "name": "Elven city guard", + "examine": "An elven city guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1186", + "name": "Idris" + }, + { + "id": "1187", + "name": "Essyllt" + }, + { + "id": "1188", + "name": "Morvran" + }, + { + "id": "1189", + "name": "Fishing spot" + }, + { + "id": "1190", + "name": "Fishing spot" + }, + { + "id": "1191", + "name": "Fishing spot" + }, + { + "id": "1192", + "name": "Rabbit", + "examine": "A cute bunny rabbit.", + "attack_level": "1", + "death_animation": "6092", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "6090", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1193", + "name": "Rabbit", + "attack_level": "1", + "death_animation": "6092", + "defence_animation": "6091", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "6090", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1194", + "name": "Rabbit", + "attack_level": "1", + "death_animation": "6092", + "defence_animation": "6091", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "6090", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1195", + "name": "Grizzly bear", + "examine": "It's an NPC.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "4", + "combat_audio": "300,302,301", + "death_animation": "4929", + "defence_animation": "4927", + "defence_level": "35", + "lifepoints": "35", + "magic_level": "1", + "melee_animation": "4921", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "36" + }, + { + "id": "1196", + "name": "Grizzly bear cub", + "examine": "Eek! A bear cub!", + "attack_level": "21", + "combat_audio": "498,500,499", + "defence_animation": "0", + "defence_level": "21", + "lifepoints": "30", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "21", + "weakness": "6" + }, + { + "id": "1197", + "name": "Grizzly bear cub", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "35", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1198", + "name": "Dire Wolf", + "examine": "What big teeth you have.", + "attack_level": "33", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", + "melee_animation": "6559", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "33", + "weakness": "9" + }, + { + "id": "1199", + "name": "Elf Tracker", + "examine": "An elf tracker.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1200", + "name": "Tyras guard", + "examine": "One of King Tyras's men.", + "attack_level": "42", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "414", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "42", + "weakness": "8" + }, + { + "id": "1201", + "name": "Elf warrior", + "examine": "I don't want to get on the wrong side of him.", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "105", + "melee_animation": "426", + "projectile": "249", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "250", + "strength_level": "1" + }, + { + "id": "1202", + "name": "Arianwyn" + }, + { + "id": "1203", + "name": "Tyras guard", + "examine": "One of King Tyras's men.", + "attack_level": "95", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "110", + "lifepoints": "110", + "melee_animation": "395", + "range_level": "50", + "respawn_delay": "60", + "safespot": null, + "strength_level": "105" + }, + { + "id": "1204", + "name": "Tyras guard", + "examine": "One of King Tyras's men.", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "112", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1205", + "name": "Tyras guard" + }, + { + "id": "1206", + "name": "Tyras guard", + "examine": "One of King Tyras's men." + }, + { + "id": "1207", + "name": "Quartermaster" + }, + { + "id": "1208", + "name": "Quartermaster", + "examine": "Responsible for the food and equipment of the troops.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1209", + "name": "Koftik", + "examine": "The cave guide." + }, + { + "id": "1210", + "name": "Kings messenger", + "examine": "One of King Lathas' messengers." + }, + { + "id": "1211", + "name": "Will o' the wisp", + "examine": "Mysterious swamp lights...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1212", + "name": "Will o' the wisp", + "examine": "Mysterious swamp lights..." + }, + { + "id": "1213", + "name": "Tegid", + "examine": "He's washing his clothes in the lake." + }, + { + "id": "1214", + "name": "Thistle", + "examine": "A plant." + }, + { + "id": "1215", + "name": "Parrots", + "examine": "What a colourful bunch of parrots!" + }, + { + "id": "1216", + "name": "Parroty Pete", + "examine": "He seems strangely familiar...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1217", + "name": "Gardener", + "examine": "An old gardener.", + "attack_level": "4", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "4", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "433", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "4", + "weakness": "8" + }, + { + "id": "1218", + "name": "Ghoul", + "examine": "A scary, man eating ghoul.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "442,444,443", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "30", + "lifepoints": "50", + "magic_animation": "422", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "50", + "strength_level": "40", + "weakness": "9" + }, + { + "id": "1219", + "name": "Leech", + "examine": "Yuck! It's all slimy!", + "aggressive": "true", + "attack_level": "42", + "death_animation": "1272", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "1273", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "42", + "weakness": "9" + }, + { + "id": "1220", + "name": "Vampire", + "examine": "It looks very hungry!", + "attack_level": "52", + "clue_level": "1", + "death_animation": "7185", + "defence_level": "52", + "lifepoints": "50", + "melee_animation": "1264", + "range_level": "1", + "safespot": null, + "slayer_exp": "50", + "strength_level": "1" + }, + { + "id": "1221", + "name": "Spider" + }, + { + "id": "1222", + "name": "Mist" + }, + { + "id": "1223", + "name": "Vampire", + "examine": "It looks very hungry!", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "1264", + "range_level": "1", + "safespot": null, + "slayer_exp": "40", + "strength_level": "1" + }, + { + "id": "1224", + "name": "Vampyric hound" + }, + { + "id": "1225", + "name": "Vampire", + "examine": "It looks very hungry!", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "50", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1226", + "name": "Tree" + }, + { + "id": "1227", + "name": "Myre Blamish Snail", + "examine": "A marsh coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "4", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "8", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "5", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1228", + "name": "Blood Blamish Snail", + "examine": "A blood coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "13", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "12", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1229", + "name": "Ochre Blamish Snail", + "examine": "A muddy coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "10", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "7", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1230", + "name": "Bruise Blamish Snail", + "examine": "A bruise blue coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "12", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "15", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1231", + "name": "Bark Blamish Snail", + "examine": "A branch bark coloured blamish snail, these types are said to spit acid.", + "agg_radius": "", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "22", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "10", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1232", + "name": "Myre Blamish Snail", + "examine": "A marsh coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "4", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "8", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "5", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1233", + "name": "Blood Blamish Snail", + "examine": "A blood coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "13", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "12", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1234", + "name": "Ochre Blamish Snail", + "examine": "A muddy coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "10", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "7", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1235", + "name": "Bruise Blamish Snail", + "examine": "A bruise blue coloured blamish snail, these types are said to spit acid.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "6", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "combat_style": "1", + "death_animation": "8144", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "12", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8143", + "range_animation": "0", + "range_level": "15", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "0", + "weakness": "9" + }, + { + "id": "1236", + "name": "Fishing spot" + }, + { + "id": "1237", + "name": "Fishing spot" + }, + { + "id": "1238", + "name": "Fishing spot" + }, + { + "id": "1239", + "name": "Bedabin Nomad Fighter", + "examine": "A Bedabin nomad fighter - a sandy swordsman.", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "9" + }, + { + "id": "1240", + "name": "Loar Shadow", + "examine": "A shadowy sort of entity", + "aggressive": "true", + "attack_level": "45", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "38", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "3" + }, + { + "id": "1241", + "name": "Loar Shade", + "examine": "The shadowy remains of a long departed soul.", + "aggressive": "true", + "attack_level": "45", + "death_animation": "1308", + "defence_animation": "1284", + "defence_level": "26", + "lifepoints": "38", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1283", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "3" + }, + { + "id": "1242", + "name": "Shade Spirit" + }, + { + "id": "1243", + "name": "Phrin Shadow", + "examine": "A shadowy sort of entity", + "aggressive": "true", + "attack_level": "64", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "56", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "3" + }, + { + "id": "1244", + "name": "Phrin Shade", + "examine": "The shadowy remains of a long departed soul.", + "aggressive": "true", + "attack_level": "64", + "death_animation": "1287", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "56", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1283", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "3" + }, + { + "id": "1245", + "name": "Riyl Shadow", + "examine": "A shadowy sort of entity", + "aggressive": "true", + "attack_level": "88", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "76", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "3" + }, + { + "id": "1246", + "name": "Riyl Shade", + "examine": "The shadowy remains of a long departed soul.", + "aggressive": "true", + "attack_level": "88", + "death_animation": "1287", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "76", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1283", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "3" + }, + { + "id": "1247", + "name": "Asyn Shadow", + "examine": "A shadowy sort of entity", + "aggressive": "true", + "attack_level": "102", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "84", + "weakness": "3" + }, + { + "id": "1248", + "name": "Asyn Shade", + "examine": "The shadowy remains of a long departed soul.", + "aggressive": "true", + "attack_level": "102", + "death_animation": "1287", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1283", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "84", + "weakness": "3" + }, + { + "id": "1249", + "name": "Fiyr Shadow", + "examine": "A shadowy sort of entity", + "aggressive": "true", + "attack_level": "120", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "85", + "lifepoints": "110", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "3" + }, + { + "id": "1250", + "name": "Fiyr Shade", + "examine": "The shadowy remains of a long departed soul.", + "aggressive": "true", + "attack_level": "120", + "death_animation": "1287", + "defence_animation": "0", + "defence_level": "85", + "lifepoints": "110", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1283", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "3" + }, + { + "id": "1251", + "name": "Afflicted(Ulsquire)" + }, + { + "id": "1252", + "name": "Ulsquire Shauncy" + }, + { + "id": "1253", + "name": "Afflicted(Razmire)" + }, + { + "id": "1254", + "name": "Razmire Keelgan" + }, + { + "id": "1255", + "name": "Mort'ton Local" + }, + { + "id": "1256", + "name": "Mort'ton Local" + }, + { + "id": "1257", + "name": "Afflicted", + "examine": "A local villager of Mort'ton.", + "attack_level": "43", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "43", + "weakness": "6" + }, + { + "id": "1258", + "name": "Afflicted", + "examine": "A local villager of Mort'ton.", + "attack_level": "44", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "44", + "weakness": "6" + }, + { + "id": "1259", + "name": "Mort'ton local" + }, + { + "id": "1260", + "name": "Mort'ton local" + }, + { + "id": "1261", + "name": "Afflicted", + "examine": "A local villager of Mort'ton.", + "attack_level": "45", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "45", + "weakness": "6" + }, + { + "id": "1262", + "name": "Afflicted", + "examine": "A local villager of Mort'ton.", + "aggressive": "true", + "attack_level": "46", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "46", + "weakness": "6" + }, + { + "id": "1263", + "name": "Wizard", + "examine": "Slightly more magical.", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1264", + "name": "Saradomin wizard", + "examine": "A follower of Saradomin.", + "aggressive": "true", + "attack_level": "90", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "811", + "magic_level": "90", + "melee_animation": "376", + "poison_amount": "30", + "poisonous": "true", + "range_animation": "0", + "range_level": "70", + "respawn_delay": "60", + "safespot": null, + "spell_id": "41", + "strength_level": "90", + "weakness": "3" + }, + { + "id": "1265", + "name": "Rock Crab", + "examine": "No one likes crabs...", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "717,723,722", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "1312", + "magic_level": "1", + "melee_animation": "1312", + "range_animation": "1312", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1266", + "name": "Rocks", + "examine": "A rocky outcrop.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "1312", + "melee_animation": "1312", + "range_animation": "1312", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1267", + "name": "Rock Crab", + "examine": "No one likes crabs...", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "717,723,722", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "1312", + "melee_animation": "1312", + "range_animation": "1312", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1268", + "name": "Rocks", + "examine": "A rocky outcrop.", + "aggressive": "true", + "attack_level": "4", + "attack_speed": "5", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "4", + "lifepoints": "50", + "magic_animation": "1312", + "melee_animation": "1312", + "range_animation": "1312", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1269", + "name": "Olaf the Bard", + "examine": "A Fremennik bard.", + "aggressive": "true", + "attack_level": "10", + "attack_speed": "5", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "8", + "lifepoints": "50", + "magic_animation": "1312", + "melee_animation": "1312", + "range_animation": "1312", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1270", + "name": "Lalli", + "examine": "Distinctly troll-shaped.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1271", + "name": "Golden sheep", + "examine": "Freshly shorn.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1272", + "name": "Golden sheep", + "examine": "Lovely thick wool.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1273", + "name": "Fossegrimen", + "examine": "A powerful spirit that lives in this lake.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1274", + "name": "Ospak", + "examine": "Looks like he's had a few drinks already.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1275", + "name": "Styrmir", + "examine": "Doesn't look like the musical type.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1276", + "name": "Torbrund", + "examine": "Waiting for the show.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1277", + "name": "Fridgeir", + "examine": "He sits impatiently with his friends.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1278", + "name": "Longhall Bouncer", + "examine": "He's fat, he's round, he bounces on the ground. That's how he got the job.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1279", + "name": "The Draugen", + "examine": "A fearful spirit of the drowned.", + "aggressive": "true", + "attack_level": "40", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "9" + }, + { + "id": "1280", + "name": "Butterfly" + }, + { + "id": "1281", + "name": "Sigli the Huntsman", + "examine": "A Fremennik hunter.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1282", + "name": "Sigmund The Merchant", + "examine": "A Fremennik merchant.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1283", + "name": "Swensen the Navigator", + "examine": "A Fremennik navigator.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1284", + "name": "Bjorn" + }, + { + "id": "1285", + "name": "Eldgrim" + }, + { + "id": "1286", + "name": "Manni the Reveller", + "examine": "Every innkeeper's best friend!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1287", + "name": "Council workman", + "examine": "Supposedly fixes things around Gielinor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1288", + "name": "Peer the Seer", + "examine": "A Fremennik riddler.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1289", + "name": "Thorvald the Warrior", + "examine": "A Fremennik hero.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1290", + "name": "Koschei the deathless", + "examine": "Your challenge awaits! ", + "attack_level": "13", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "13", + "weakness": "10" + }, + { + "id": "1291", + "name": "Koschei the deathless", + "examine": "He lives again!", + "attack_level": "13", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "13", + "weakness": "10" + }, + { + "id": "1292", + "name": "Koschei the deathless", + "examine": "He keeps on living!", + "attack_level": "13", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "13", + "weakness": "10" + }, + { + "id": "1293", + "name": "Koschei the deathless", + "examine": "He just keeps on going.", + "attack_level": "13", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "13", + "weakness": "10" + }, + { + "id": "1294", + "name": "Brundt the Chieftain", + "examine": "The Fremennik tribe's chieftain.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1295", + "name": "Askeladden" + }, + { + "id": "1296", + "name": "Guard", + "examine": "Stands around and looks at stuff all day.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1297", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1298", + "name": "Town Guard", + "examine": "What a rubbish job he has.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1299", + "name": "Town Guard" + }, + { + "id": "1300", + "name": "A bartender.", + "examine": "The Longhall barkeep", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1301", + "name": "Yrsa", + "examine": "Pretty shabbily dressed for a clothes shop owner.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1302", + "name": "Fisherman", + "examine": "There's something fishy about this guy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1303", + "name": "Skulgrimen", + "examine": "Sells and makes weapons and armour.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1304", + "name": "Sailor", + "examine": "He's strong to the finish", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1305", + "name": "Agnar", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1306", + "name": "Freidir", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1307", + "name": "Borrokar", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1308", + "name": "Lanzig", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "51", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1309", + "name": "Pontak", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "51", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1310", + "name": "Freygerd" + }, + { + "id": "1311", + "name": "Lensa" + }, + { + "id": "1312", + "name": "Jennella" + }, + { + "id": "1313", + "name": "Sassilik", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1314", + "name": "Inga", + "examine": "One of Rellekka's many citizens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1315", + "name": "Fish monger", + "examine": "Fish-tastic!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1316", + "name": "Fur trader", + "examine": "I wonder what he does with all that fur?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1317", + "name": "Market Guard", + "examine": "Keeps the stalls secure.", + "attack_level": "28", + "combat_audio": "", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "28", + "weakness": "9" + }, + { + "id": "1318", + "name": "Warrior", + "examine": "A hardened Fremennik warrior.", + "attack_level": "28", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "28", + "weakness": "9" + }, + { + "id": "1319", + "name": "Fox", + "examine": "A cunning animal.", + "attack_level": "32", + "death_animation": "6570", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "6562", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "7" + }, + { + "id": "1320", + "name": "Bunny", + "examine": "Hoppity", + "attack_level": "1", + "death_animation": "1246", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "1245", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1321", + "name": "Bunny", + "attack_level": "1", + "death_animation": "1246", + "defence_animation": "1244", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "1245", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1322", + "name": "Gull" + }, + { + "id": "1323", + "name": "Gull" + }, + { + "id": "1324", + "name": "Gull" + }, + { + "id": "1325", + "name": "Gull" + }, + { + "id": "1326", + "name": "Bear Cub", + "examine": "Cute. But deadly.", + "aggressive": "true", + "attack_level": "8", + "combat_audio": "498,500,499", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "8", + "weakness": "7" + }, + { + "id": "1327", + "name": "Bear Cub", + "examine": "Cute. But deadly.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "20", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1328", + "name": "Unicorn Foal", + "examine": "Horned horsey.", + "attack_level": "10", + "attack_speed": "4", + "combat_audio": "369,371,370", + "death_animation": "6377", + "defence_animation": "6375", + "defence_level": "10", + "lifepoints": "15", + "magic_animation": "6376", + "magic_level": "1", + "melee_animation": "6376", + "range_animation": "6376", + "range_level": "1", + "respawn_delay": "90", + "safespot": null, + "strength_level": "6", + "weakness": "7" + }, + { + "id": "1329", + "name": "Black unicorn Foal", + "examine": "Cute but evil.", + "aggressive": "false", + "attack_level": "18", + "attack_speed": "4", + "combat_audio": "369,371,370", + "death_animation": "6377", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "6376", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "18", + "weakness": "7" + }, + { + "id": "1330", + "name": "Wolf", + "examine": "Fearsome predator found only in the Fremennik Province", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "481,491,490", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "69", + "magic_animation": "0", + "melee_animation": "6559", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "69", + "strength_level": "35", + "weakness": "7" + }, + { + "id": "1331", + "name": "Fishing spot" + }, + { + "id": "1332", + "name": "Fishing spot" + }, + { + "id": "1333", + "name": "Fishing spot" + }, + { + "id": "1334", + "name": "Jossik" + }, + { + "id": "1335", + "name": "Jossik" + }, + { + "id": "1336", + "name": "Larrissa" + }, + { + "id": "1337", + "name": "Larrissa" + }, + { + "id": "1338", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "attack_level": "80", + "attack_speed": "5", + "clue_level": "1", + "combat_style": "1", + "death_animation": "1342", + "defence_animation": "1341", + "defence_level": "70", + "lifepoints": "70", + "magic_animation": "1340", + "melee_animation": "1340", + "projectile": "288", + "range_animation": "1340", + "range_level": "85", + "safespot": null, + "strength_level": "80" + }, + { + "id": "1339", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "combat_style": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "1343", + "projectile": "288", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1340", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "combat_style": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "1343", + "projectile": "288", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1341", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "120", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1342", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "120", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1343", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "120", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1344", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1345", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1346", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1347", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1348", + "name": "Dagannoth mother" + }, + { + "id": "1349", + "name": "Dagannoth mother" + }, + { + "id": "1350", + "name": "Dagannoth mother" + }, + { + "id": "1351", + "name": "Dagannoth mother", + "examine": "A horror from the ocean depths.", + "aggressive": "true", + "attack_level": "60", + "death_animation": "1342", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "128", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "1341", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "1352", + "name": "Dagannoth mother", + "examine": "A horror from the ocean depths.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1353", + "name": "Dagannoth mother", + "examine": "A horror from the ocean depths.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1354", + "name": "Dagannoth mother", + "examine": "A horror from the ocean depths.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1355", + "name": "Dagannoth mother", + "examine": "A horror from the ocean depths.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1356", + "name": "Dagannoth mother", + "examine": "A horror from the ocean depths.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1357", + "name": "Sam", + "examine": "Pretty barmaid." + }, + { + "id": "1358", + "name": "Rachael", + "examine": "Pretty barmaid." + }, + { + "id": "1359", + "name": "Queen Sigrid" + }, + { + "id": "1360", + "name": "Banker", + "examine": "He seems happy to see you.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1361", + "name": "Arnor" + }, + { + "id": "1362", + "name": "Haming" + }, + { + "id": "1363", + "name": "Moldof" + }, + { + "id": "1364", + "name": "Helga" + }, + { + "id": "1365", + "name": "Matilda" + }, + { + "id": "1366", + "name": "Ashild" + }, + { + "id": "1367", + "name": "Skraeling", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "401", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1368", + "name": "Skraeling", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1369", + "name": "Fishmonger", + "examine": "Hmm", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1370", + "name": "Greengrocer", + "examine": "At least he eats his greens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1371", + "name": "Prince Brand" + }, + { + "id": "1372", + "name": "Princess Astrid" + }, + { + "id": "1373", + "name": "King Vargas" + }, + { + "id": "1374", + "name": "Guard", + "examine": "He's guarding the throne room.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1375", + "name": "Advisor Ghrim" + }, + { + "id": "1376", + "name": "Derrik", + "examine": "Smithy for Sogthorpe." + }, + { + "id": "1377", + "name": "Farmer", + "examine": "He's cutting the wheat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1378", + "name": "Flower Girl", + "examine": "No-one would mistake her for a duchess.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1379", + "name": "Ragnar", + "examine": "A subject of Miscellania." + }, + { + "id": "1380", + "name": "Einar", + "examine": "A subject of Miscellania." + }, + { + "id": "1381", + "name": "Alrik", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1382", + "name": "Thorhild", + "examine": "A subject of Miscellania." + }, + { + "id": "1383", + "name": "Halla" + }, + { + "id": "1384", + "name": "Yrsa" + }, + { + "id": "1385", + "name": "Sailor", + "examine": "He's strong to the finish, because he eats cabbage.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1386", + "name": "Rannveig", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1387", + "name": "Thora" + }, + { + "id": "1388", + "name": "Valgerd", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1389", + "name": "Skraeling", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1390", + "name": "Broddi", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1391", + "name": "Skraeling", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1392", + "name": "Ragnvald", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "1", + "melee_animation": "810", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1393", + "name": "Fishmonger", + "examine": "Hmm", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1394", + "name": "Greengrocer", + "examine": "At least he eats his greens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1395", + "name": "Lumberjack Leif", + "examine": "He's a lumberjack", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1396", + "name": "Miner Magnus", + "examine": "He's just mining his own business.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1397", + "name": "Fisherman Frodi", + "examine": "There's something fishy about him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1398", + "name": "Gardener Gunnhild", + "examine": "She's looking a bit weedy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1399", + "name": "Fishing spot" + }, + { + "id": "1400", + "name": "Gull" + }, + { + "id": "1401", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1402", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1403", + "name": "Rooster", + "attack_level": "1", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "5387", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1404", + "name": "Rabbit", + "attack_level": "1", + "death_animation": "6092", + "defence_animation": "6091", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "6090", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1405", + "name": "Fishing spot" + }, + { + "id": "1406", + "name": "Fishing spot" + }, + { + "id": "1407", + "name": "Daero" + }, + { + "id": "1408", + "name": "Waydar" + }, + { + "id": "1409", + "name": "Waydar" + }, + { + "id": "1410", + "name": "Waydar" + }, + { + "id": "1411", + "name": "Garkor" + }, + { + "id": "1412", + "name": "Garkor" + }, + { + "id": "1413", + "name": "Lumo" + }, + { + "id": "1414", + "name": "Lumo" + }, + { + "id": "1415", + "name": "Bunkdo" + }, + { + "id": "1416", + "name": "Bunkdo" + }, + { + "id": "1417", + "name": "Carado" + }, + { + "id": "1418", + "name": "Carado" + }, + { + "id": "1419", + "name": "Lumdo", + "examine": "There to help me make my bids.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1420", + "name": "Karam" + }, + { + "id": "1421", + "name": "Karam" + }, + { + "id": "1422", + "name": "Karam" + }, + { + "id": "1423", + "name": "Bunkwicket" + }, + { + "id": "1424", + "name": "Waymottin" + }, + { + "id": "1425", + "name": "Zooknock" + }, + { + "id": "1426", + "name": "Zooknock" + }, + { + "id": "1427", + "name": "G.L.O. Caranock", + "examine": "An official looking Gnome with small beady eyes.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1428", + "name": "G.L.O. Caranock" + }, + { + "id": "1429", + "name": "Dugopul" + }, + { + "id": "1430", + "name": "Salenab" + }, + { + "id": "1431", + "name": "Trefaji" + }, + { + "id": "1432", + "name": "Aberab" + }, + { + "id": "1433", + "name": "Solihib", + "movement_radius": "1" + }, + { + "id": "1434", + "name": "Daga" + }, + { + "id": "1435", + "name": "Tutab" + }, + { + "id": "1436", + "name": "Ifaba" + }, + { + "id": "1437", + "name": "Hamab" + }, + { + "id": "1438", + "name": "Hafuba" + }, + { + "id": "1439", + "name": "Denadu" + }, + { + "id": "1440", + "name": "Lofu" + }, + { + "id": "1441", + "name": "Kruk" + }, + { + "id": "1442", + "name": "Duke", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "130", + "melee_animation": "1383", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1443", + "name": "Oipuis", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "130", + "melee_animation": "1383", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1444", + "name": "Uyoro", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "130", + "melee_animation": "1383", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1445", + "name": "Ouhai", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1384", + "defence_animation": "1387", + "defence_level": "1", + "lifepoints": "130", + "melee_animation": "1383", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1446", + "name": "Uodai", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "130", + "melee_animation": "1383", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1447", + "name": "Padulah", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "133", + "melee_animation": "1383", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1448", + "name": "Awowogei" + }, + { + "id": "1449", + "name": "Uwogo" + }, + { + "id": "1450", + "name": "Muruwoi" + }, + { + "id": "1451", + "name": "Sleeping Monkey", + "examine": "A rather sleepy looking guard", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1452", + "name": "Monkey Child", + "examine": "An adorable little monkey child.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1453", + "name": "The Monkey's Uncle", + "examine": "He looks like the Monkey's Uncle.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1454", + "name": "The Monkey's Aunt", + "examine": "She looks like the Monkey's Aunt.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1455", + "name": "Monkey Guard", + "examine": "A scimitar wielding ninja monkey.", + "attack_level": "66", + "combat_audio": "629,631,630", + "death_animation": "1384", + "defence_animation": "0", + "defence_level": "66", + "lifepoints": "94", + "magic_animation": "0", + "melee_animation": "1392", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "66", + "weakness": "8" + }, + { + "id": "1456", + "name": "Monkey Archer", + "examine": "A bow wielding ninja monkey.", + "aggressive": "true", + "attack_level": "43", + "combat_audio": "629,631,630", + "combat_style": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "58", + "lifepoints": "82", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "1394", + "range_level": "58", + "respawn_delay": "60", + "safespot": null, + "strength_level": "43", + "weakness": "1" + }, + { + "id": "1457", + "name": "Monkey Archer", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "629,631,630", + "combat_style": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "1394", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1458", + "name": "Monkey Archer", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "629,631,630", + "combat_style": "1", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "1394", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1459", + "name": "Monkey Guard", + "examine": "A huge brutish gorilla armoured with dangerous looking vambraces.", + "attack_level": "100", + "attack_speed": "6", + "combat_audio": "629,631,630", + "death_animation": "1404", + "defence_animation": "1403", + "defence_level": "90", + "lifepoints": "130", + "magic_animation": "1402", + "melee_animation": "1402", + "range_animation": "1402", + "range_level": "1", + "safespot": null, + "strength_level": "130", + "weakness": "8" + }, + { + "id": "1460", + "name": "Monkey Guard", + "examine": "A huge brutish gorilla armoured with dangerous looking vambraces.", + "aggressive": "true", + "attack_level": "63", + "attack_speed": "5", + "combat_audio": "629,631,630", + "death_animation": "1404", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "1402", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "63", + "weakness": "8" + }, + { + "id": "1461", + "name": "Elder Guard", + "examine": "A huge brutish gorilla stands here", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1462", + "name": "Elder Guard" + }, + { + "id": "1463", + "name": "Monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1464", + "name": "Monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1465", + "name": "Monkey Zombie", + "examine": "A large and lumbering undead monkey.", + "aggressive": "true", + "attack_level": "150", + "attack_speed": "4", + "bonuses": "35,35,35,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "629,631,630", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "60", + "lifepoints": "60", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "1383", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "60", + "weakness": "6" + }, + { + "id": "1466", + "name": "Monkey Zombie", + "examine": "A large and lumbering undead monkey stands here, blocking the way.", + "aggressive": "true", + "attack_level": "150", + "attack_speed": "4", + "bonuses": "35,35,35,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "629,631,630", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "90", + "lifepoints": "90", + "magic_level": "90", + "melee_animation": "1392", + "range_level": "1", + "respawn_delay": "13", + "safespot": null, + "strength_level": "110" + }, + { + "id": "1467", + "name": "Monkey Zombie", + "examine": "A recently deceased monkey. Its flesh seems to be worse for the wear.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "4", + "bonuses": "15,15,15,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "629,631,630", + "death_animation": "1384", + "defence_animation": "1393", + "defence_level": "60", + "lifepoints": "60", + "magic_level": "60", + "melee_animation": "1392", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1468", + "name": "Bonzara" + }, + { + "id": "1469", + "name": "Monkey minder", + "examine": "He looks like the type of guy who would mind monkeys.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1470", + "name": "Foreman" + }, + { + "id": "1471", + "name": "Skeleton", + "examine": "It looks just a bit... underfed.", + "aggressive": "true", + "attack_level": "180", + "attack_speed": "4", + "bonuses": "50,50,50,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "774,775,777", + "death_animation": "5521", + "defence_animation": "5520", + "defence_level": "110", + "lifepoints": "77", + "magic_animation": "5519", + "magic_level": "110", + "melee_animation": "5519", + "range_animation": "5519", + "range_level": "1", + "respawn_delay": "100", + "safespot": null, + "slayer_exp": "110", + "strength_level": "90", + "weakness": "8" + }, + { + "id": "1472", + "name": "Jungle demon", + "examine": "A Greater Jungle demon. A magical aura emanates from its hide.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "2", + "combat_audio": "400,404,403", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "428", + "magic_animation": "0", + "magic_level": "50", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "1473", + "name": "Spider", + "aggressive": "true", + "attack_level": "1", + "death_animation": "6251", + "defence_animation": "6250", + "defence_level": "1", + "lifepoints": "2", + "melee_animation": "6249", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1474", + "name": "Spider" + }, + { + "id": "1475", + "name": "Bird", + "examine": "It's a brightly coloured bird of the jungle.", + "attack_level": "5", + "death_animation": "6779", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "6775", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "8" + }, + { + "id": "1476", + "name": "Bird", + "examine": "It's a brightly coloured bird of the jungle. It flies very quickly.", + "attack_level": "5", + "death_animation": "6777", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "6775", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "8" + }, + { + "id": "1477", + "name": "Scorpion", + "attack_level": "1", + "combat_audio": "3611,3612,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "17", + "strength_level": "1" + }, + { + "id": "1478", + "name": "Jungle spider", + "examine": "A very dangerous looking spider", + "aggressive": "true", + "attack_level": "47", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "5327", + "range_animation": "0", + "range_level": "63", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "2" + }, + { + "id": "1479", + "name": "Snake", + "attack_level": "1", + "combat_audio": "3609,3608,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1480", + "name": "Small ninja monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1481", + "name": "Medium ninja monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1482", + "name": "Gorilla" + }, + { + "id": "1483", + "name": "Bearded gorilla", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1484", + "name": "Ancient monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1485", + "name": "Small zombie monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1486", + "name": "Large zombie monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1487", + "name": "Monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1488", + "name": "Dummy" + }, + { + "id": "1489", + "name": "Dummy" + }, + { + "id": "1490", + "name": "Dummy" + }, + { + "id": "1491", + "name": "Dummy" + }, + { + "id": "1492", + "name": "Dummy" + }, + { + "id": "1493", + "name": "Dummy" + }, + { + "id": "1494", + "name": "Dummy" + }, + { + "id": "1495", + "name": "Dummy" + }, + { + "id": "1496", + "name": "Dummy" + }, + { + "id": "1497", + "name": "Dummy" + }, + { + "id": "1498", + "name": "Dummy" + }, + { + "id": "1499", + "name": "Dummy" + }, + { + "id": "1500", + "name": "Dummy" + }, + { + "id": "1501", + "name": "Dummy" + }, + { + "id": "1502", + "name": "Dummy" + }, + { + "id": "1503", + "name": "Dummy" + }, + { + "id": "1504", + "name": "Dummy" + }, + { + "id": "1505", + "name": "Dummy" + }, + { + "id": "1506", + "name": "Dummy" + }, + { + "id": "1507", + "name": "Dummy" + }, + { + "id": "1508", + "name": "Forester" + }, + { + "id": "1509", + "name": "Woman-at-arms" + }, + { + "id": "1510", + "name": "Apprentice" + }, + { + "id": "1511", + "name": "Ranger" + }, + { + "id": "1512", + "name": "Adventurer" + }, + { + "id": "1513", + "name": "Mage" + }, + { + "id": "1514", + "name": "Hiylik Myna", + "examine": "A local holy man who supports the people trying to get though Mort Myre." + }, + { + "id": "1515", + "name": "Nail beast" + }, + { + "id": "1521", + "name": "Nail beast", + "examine": "A huge nail beast. Its nails appear very sharp.", + "attack_level": "150", + "death_animation": "5990", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "550", + "magic_animation": "0", + "melee_animation": "5989", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "150" + }, + { + "id": "1522", + "name": "Nail beast" + }, + { + "id": "1523", + "name": "Nail beast" + }, + { + "id": "1524", + "name": "Undead Lumberjack", + "examine": "He is one", + "attack_level": "73", + "death_animation": "5972", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "5970", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "73" + }, + { + "id": "1525", + "name": "Undead Lumberjack" + }, + { + "id": "1526", + "name": "Lanthus" + }, + { + "id": "1527", + "name": "Mine cart" + }, + { + "id": "1528", + "name": "Zealot", + "examine": "His robes prominently display the star of Saradomin.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1529", + "name": "Sheep" + }, + { + "id": "1530", + "name": "Rabbit" + }, + { + "id": "1531", + "name": "Imp", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "8", + "movement_radius": "25", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1532", + "name": "Barricade", + "examine": "Handy for hindering the enemy team's movement.", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "1", + "death_animation": "9658", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "0", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1533", + "name": "Barricade", + "examine": "Handy for hindering the enemy team's movement.", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "1", + "death_animation": "9658", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "0", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1534", + "name": "Barricade", + "examine": "Handy for hindering the enemy team's movement.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "9658", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "0", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1535", + "name": "Barricade", + "examine": "Handy for hindering the enemy team's movement.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "9658", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "0", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1536", + "name": "Possessed pickaxe", + "aggressive": "true", + "attack_level": "1", + "death_animation": "188", + "defence_animation": "186", + "defence_level": "1", + "lifepoints": "40", + "melee_animation": "185", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1537", + "name": "Haze", + "examine": "A strange disturbance in the air.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1538", + "name": "Corpse", + "examine": "Well", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1539", + "name": "Skeletal miner", + "examine": "I don't think the pickaxe is for hitting rocks.", + "aggressive": "true", + "attack_level": "35", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "0", + "strength_level": "35", + "weakness": "8" + }, + { + "id": "1540", + "name": "Treus Dayth", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5542", + "defence_animation": "5541", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "5540", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1541", + "name": "Ghost", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "1542", + "name": "Loading crane" + }, + { + "id": "1543", + "name": "Innocent-looking key" + }, + { + "id": "1544", + "name": "Mine cart" + }, + { + "id": "1545", + "name": "Mine cart" + }, + { + "id": "1546", + "name": "Mine cart" + }, + { + "id": "1547", + "name": "Mine cart" + }, + { + "id": "1548", + "name": "Mine cart" + }, + { + "id": "1549", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5542", + "defence_animation": "5541", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5540", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "1550", + "name": "Chompy bird", + "examine": "A large boisterous bird, a delicacy for ogres.", + "aggressive": "false", + "attack_level": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "1449,1451,1450", + "death_animation": "6762", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "6761", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "3" + }, + { + "id": "1551", + "name": "Mischievous ghost", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1552", + "name": "Santa" + }, + { + "id": "1553", + "name": "Ug", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1554", + "name": "Aga" + }, + { + "id": "1555", + "name": "Arrg" + }, + { + "id": "1556", + "name": "Arrg", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "defence_level": "1", + "lifepoints": "150", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1557", + "name": "Ug", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1558", + "name": "Ice wolf", + "examine": "Not man's best friend.", + "aggressive": "true", + "attack_level": "51", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "51", + "lifepoints": "72", + "magic_animation": "0", + "melee_animation": "6559", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "51", + "weakness": "7" + }, + { + "id": "1559", + "name": "Ice wolf" + }, + { + "id": "1560", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1561", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1562", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1563", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1564", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1565", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1566", + "name": "Ice Troll", + "examine": "Brrrrr...he must be cold!", + "attack_level": "60", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "1567", + "name": "Cyreg Paddlehorn", + "examine": "A tall and imposing man who's more than familiar with boating.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1568", + "name": "Curpile Fyod" + }, + { + "id": "1569", + "name": "Veliaf Hurtz" + }, + { + "id": "1570", + "name": "Sani Piliu" + }, + { + "id": "1571", + "name": "Harold Evans" + }, + { + "id": "1572", + "name": "Radigad Ponfit" + }, + { + "id": "1573", + "name": "Polmafi Ferdygris" + }, + { + "id": "1574", + "name": "Ivan Strom" + }, + { + "id": "1575", + "name": "Skeleton Hellhound" + }, + { + "id": "1576", + "name": "Stranger" + }, + { + "id": "1577", + "name": "Vanstrom Klause" + }, + { + "id": "1578", + "name": "Mist" + }, + { + "id": "1579", + "name": "Vanstrom Klause" + }, + { + "id": "1580", + "name": "Vanstrom Klause" + }, + { + "id": "1581", + "name": "Vanstrom Klause" + }, + { + "id": "1582", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "1583", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "1584", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "1585", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "1586", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "1587", + "name": "Moss giant", + "examine": "His beard seems to have a life of its own.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "6", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "30", + "lifepoints": "60", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "60", + "strength_level": "30", + "weakness": "1" + }, + { + "id": "1588", + "name": "Moss giant", + "examine": "His beard seems to have a life of its own.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "6", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "30", + "lifepoints": "60", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "60", + "strength_level": "30", + "weakness": "1" + }, + { + "id": "1589", + "name": "Baby red dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "50,40,64,60,30,45,40,40,20,40,40,20,0,0,0", + "combat_audio": "405,407,406", + "death_animation": "28", + "defence_animation": "26", + "defence_level": "42", + "lifepoints": "50", + "magic_animation": "25", + "magic_level": "40", + "melee_animation": "25", + "range_animation": "25", + "range_level": "1", + "respawn_delay": "32", + "safespot": null, + "strength_level": "40", + "weakness": "3" + }, + { + "id": "1590", + "name": "Bronze dragon", + "examine": "Its scales seem to be made of bronze.", + "aggressive": "true", + "attack_level": "112", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "112", + "lifepoints": "122", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "40", + "safespot": null, + "slayer_exp": "125", + "strength_level": "112", + "weakness": "7" + }, + { + "id": "1591", + "name": "Iron dragon", + "examine": "Its scales seem to be made of iron.", + "aggressive": "true", + "attack_level": "165", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "165", + "lifepoints": "165", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "45", + "safespot": null, + "slayer_exp": "173", + "strength_level": "165", + "weakness": "7" + }, + { + "id": "1592", + "name": "Steel dragon", + "examine": "Its scales seem to be made of steel.", + "aggressive": "true", + "attack_level": "215", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "215", + "lifepoints": "210", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "45", + "safespot": null, + "slayer_exp": "221", + "strength_level": "215", + "weakness": "7" + }, + { + "id": "1593", + "name": "Wild dog", + "examine": "An unsuitable pet.", + "aggressive": "true", + "attack_level": "25", + "bonuses": "10,15,5,10,30,5,30,30,30,10,30,5,40,5,5", + "death_animation": "6564", + "defence_animation": "6563", + "defence_level": "25", + "lifepoints": "62", + "magic_animation": "6562", + "magic_level": "20", + "melee_animation": "6562", + "range_animation": "6562", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "25", + "weakness": "7" + }, + { + "id": "1594", + "name": "Wild dog", + "examine": "Looks like it's got Rabies!", + "aggressive": "true", + "attack_level": "25", + "bonuses": "10,15,5,10,30,5,30,30,30,10,30,5,40,5,5", + "death_animation": "6564", + "defence_animation": "6563", + "defence_level": "25", + "lifepoints": "62", + "magic_animation": "6562", + "magic_level": "20", + "melee_animation": "6562", + "range_animation": "6562", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "25" + }, + { + "id": "1595", + "name": "Saniboch", + "examine": "Looks like he wants money." + }, + { + "id": "1596", + "name": "Vannaka" + }, + { + "id": "1597", + "name": "Vannaka", + "examine": "He looks dangerous." + }, + { + "id": "1598", + "name": "Chaeldar", + "examine": "She looks dangerous!" + }, + { + "id": "1599", + "name": "Cave crawler" + }, + { + "id": "1600", + "name": "Cave crawler", + "examine": "A spiky crawling critter. ", + "attack_level": "28", + "attack_speed": "4", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "combat_audio": "341,343,342", + "death_animation": "265", + "defence_animation": "267", + "defence_level": "30", + "lifepoints": "23", + "magic_animation": "266", + "melee_animation": "266", + "poison_amount": "40", + "poisonous": "true", + "range_animation": "266", + "range_level": "38", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "22", + "strength_level": "30", + "weakness": "1" + }, + { + "id": "1601", + "name": "Cave crawler", + "examine": "A spiky crawling critter. ", + "attack_level": "28", + "attack_speed": "4", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "combat_audio": "341,343,342", + "death_animation": "265", + "defence_animation": "267", + "defence_level": "30", + "lifepoints": "23", + "magic_animation": "266", + "melee_animation": "266", + "poison_amount": "40", + "poisonous": "true", + "range_animation": "266", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "22", + "strength_level": "30" + }, + { + "id": "1602", + "name": "Cave crawler", + "examine": "A spiky crawling critter. ", + "attack_level": "28", + "attack_speed": "4", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "combat_audio": "341,343,342", + "death_animation": "265", + "defence_animation": "267", + "defence_level": "30", + "lifepoints": "23", + "magic_animation": "266", + "melee_animation": "266", + "poison_amount": "40", + "poisonous": "true", + "range_animation": "266", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "22", + "strength_level": "30" + }, + { + "id": "1603", + "name": "Cave crawler", + "examine": "A spiky crawling critter. ", + "attack_level": "28", + "attack_speed": "4", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "combat_audio": "341,343,342", + "death_animation": "265", + "defence_animation": "267", + "defence_level": "30", + "lifepoints": "23", + "magic_animation": "266", + "melee_animation": "266", + "poison_amount": "40", + "poisonous": "true", + "range_animation": "266", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "22", + "strength_level": "30" + }, + { + "id": "1604", + "name": "Aberrant spectre", + "examine": "A very smelly ghost.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "272,275,274", + "combat_style": "2", + "death_animation": "9467", + "defence_animation": "9468", + "defence_level": "90", + "end_gfx": "336", + "lifepoints": "90", + "magic_animation": "9466", + "magic_level": "105", + "melee_animation": "9466", + "projectile": "335", + "range_animation": "1507", + "range_level": "1", + "safespot": null, + "slayer_exp": "90", + "start_gfx": "334", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "1605", + "name": "Aberrant spectre", + "examine": "A very smelly ghost.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "272,275,274", + "combat_style": "2", + "death_animation": "9467", + "defence_animation": "9468", + "defence_level": "90", + "end_gfx": "336", + "lifepoints": "90", + "magic_animation": "9466", + "magic_level": "105", + "melee_animation": "9466", + "projectile": "335", + "range_animation": "1507", + "range_level": "1", + "safespot": null, + "slayer_exp": "90", + "start_gfx": "334", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "1606", + "name": "Aberrant spectre", + "examine": "A very smelly ghost.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "272,275,274", + "combat_style": "2", + "death_animation": "9467", + "defence_animation": "9468", + "defence_level": "90", + "end_gfx": "336", + "lifepoints": "90", + "magic_animation": "9466", + "magic_level": "105", + "melee_animation": "9466", + "projectile": "335", + "range_animation": "1507", + "range_level": "1", + "safespot": null, + "slayer_exp": "90", + "start_gfx": "334", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "1607", + "name": "Aberrant spectre", + "examine": "A very smelly ghost.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "272,275,274", + "combat_style": "2", + "death_animation": "9467", + "defence_animation": "9468", + "defence_level": "90", + "end_gfx": "336", + "lifepoints": "90", + "magic_animation": "9466", + "magic_level": "105", + "melee_animation": "9466", + "projectile": "335", + "range_animation": "1507", + "range_level": "1", + "safespot": null, + "slayer_exp": "90", + "start_gfx": "334", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "1608", + "name": "Kurask", + "examine": "Large, heavy, with sharp things attached to its head.", + "aggressive": "true", + "attack_level": "67", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "combat_audio": "588,590,589", + "death_animation": "9440", + "defence_animation": "9441", + "defence_level": "105", + "lifepoints": "97", + "magic_animation": "9439", + "magic_level": "1", + "melee_animation": "9439", + "range_animation": "9439", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "97", + "strength_level": "105" + }, + { + "id": "1609", + "name": "Kurask", + "examine": "Large, heavy, with sharp things attached to its head.", + "aggressive": "true", + "attack_level": "67", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "combat_audio": "588,590,589", + "death_animation": "9440", + "defence_animation": "9441", + "defence_level": "105", + "lifepoints": "97", + "magic_animation": "9439", + "magic_level": "1", + "melee_animation": "9439", + "range_animation": "9439", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "97", + "strength_level": "105" + }, + { + "id": "1610", + "name": "Gargoyle", + "examine": "Flies like a rock.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "428,430,429", + "death_animation": "1518", + "defence_animation": "9455", + "defence_level": "107", + "lifepoints": "105", + "magic_animation": "1516", + "magic_level": "1", + "melee_animation": "9454", + "range_animation": "1516", + "range_level": "1", + "safespot": null, + "slayer_exp": "105", + "strength_level": "95" + }, + { + "id": "1611", + "name": "Swarming turoth", + "examine": "Flies like a rock.", + "attack_level": "45", + "attack_speed": "5", + "clue_level": "2", + "death_animation": "1518", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "105", + "magic_animation": "1516", + "melee_animation": "1516", + "range_animation": "1516", + "range_level": "49", + "safespot": null, + "slayer_exp": "105", + "strength_level": "104", + "weakness": "0" + }, + { + "id": "1612", + "name": "Banshee", + "examine": "A tortured screaming soul.", + "aggressive": "true", + "attack_level": "22", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,5,0,5,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "284,286,285", + "death_animation": "9450", + "defence_animation": "9451", + "defence_level": "22", + "lifepoints": "22", + "magic_animation": "1523", + "magic_level": "1", + "melee_animation": "9449", + "range_animation": "1523", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "22", + "strength_level": "15" + }, + { + "id": "1613", + "name": "Nechryael", + "examine": "An evil death demon.", + "attack_level": "97", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "645,647,646", + "death_animation": "9488", + "defence_animation": "9489", + "defence_level": "105", + "lifepoints": "105", + "magic_animation": "1528", + "magic_level": "1", + "melee_animation": "9487", + "range_animation": "1528", + "range_level": "1", + "safespot": null, + "strength_level": "97" + }, + { + "id": "1614", + "name": "Death spawn", + "examine": "An evil death spawn.", + "aggressive": "true", + "attack_level": "67", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "death_animation": "9460", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "60", + "magic_animation": "1540", + "magic_level": "1", + "melee_animation": "1540", + "poison_immune": "true", + "range_animation": "1540", + "range_level": "1", + "safespot": null, + "strength_level": "7", + "weakness": "2" + }, + { + "id": "1615", + "name": "Abyssal demon", + "examine": "A denizen of the Abyss!", + "attack_level": "97", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "276,278,277", + "death_animation": "1538", + "defence_animation": "0", + "defence_level": "135", + "lifepoints": "150", + "magic_animation": "1537", + "magic_level": "1", + "melee_animation": "1537", + "range_animation": "1537", + "range_level": "1", + "safespot": null, + "slayer_exp": "150", + "strength_level": "67", + "weakness": "1" + }, + { + "id": "1616", + "name": "Basilisk", + "examine": "The eyes of evil.", + "aggressive": "false", + "attack_level": "30", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,0,20,0,0,0,0,0,0", + "combat_audio": "288,290,289", + "death_animation": "264", + "defence_animation": "261", + "defence_level": "75", + "lifepoints": "75", + "magic_animation": "260", + "magic_level": "1", + "melee_animation": "260", + "range_animation": "260", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "75", + "strength_level": "45" + }, + { + "id": "1617", + "name": "Basilisk", + "examine": "The eyes of evil.", + "aggressive": "false", + "attack_level": "30", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,0,20,0,0,0,0,0,0", + "combat_audio": "288,290,289", + "death_animation": "264", + "defence_animation": "261", + "defence_level": "75", + "lifepoints": "75", + "magic_animation": "260", + "magic_level": "1", + "melee_animation": "260", + "range_animation": "260", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "75", + "strength_level": "45" + }, + { + "id": "1618", + "name": "Bloodveld", + "examine": "The tongue of evil.", + "aggressive": "false", + "attack_level": "75", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "312,314,313", + "death_animation": "9131", + "defence_animation": "9132", + "defence_level": "30", + "lifepoints": "120", + "magic_animation": "1552", + "melee_animation": "9130", + "range_animation": "1552", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "120", + "strength_level": "45" + }, + { + "id": "1619", + "name": "Bloodveld", + "examine": "The tongue of evil.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "312,314,313", + "death_animation": "9131", + "defence_animation": "9132", + "defence_level": "30", + "lifepoints": "120", + "magic_animation": "1552", + "melee_animation": "9130", + "range_animation": "1552", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "120", + "strength_level": "45" + }, + { + "id": "1620", + "name": "Cockatrice", + "examine": "The winged reptile.", + "attack_level": "32", + "attack_speed": "5", + "bonuses": "30,30,30,30,30,35,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "363,365,364", + "death_animation": "7763", + "defence_animation": "7761", + "defence_level": "35", + "lifepoints": "37", + "magic_animation": "7762", + "melee_animation": "7762", + "range_animation": "7762", + "range_level": "32", + "safespot": null, + "slayer_exp": "37", + "strength_level": "32", + "weakness": "2" + }, + { + "id": "1621", + "name": "Cockatrice", + "examine": "The winged reptile.", + "attack_level": "32", + "attack_speed": "5", + "bonuses": "30,30,30,30,30,35,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "363,365,364", + "death_animation": "7763", + "defence_animation": "7761", + "defence_level": "35", + "lifepoints": "37", + "magic_animation": "7762", + "melee_animation": "7762", + "range_animation": "7762", + "range_level": "1", + "safespot": null, + "slayer_exp": "37", + "strength_level": "32" + }, + { + "id": "1622", + "name": "Turoth", + "examine": "He's one big leg short!", + "attack_level": "55", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "85", + "lifepoints": "78", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "85" + }, + { + "id": "1623", + "name": "Turoth", + "examine": "He's one big leg short!", + "attack_level": "58", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "88", + "lifepoints": "81", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "88" + }, + { + "id": "1624", + "name": "Dust devil", + "examine": "The vacuumed face of evil.", + "attack_level": "105", + "attack_speed": "4", + "combat_audio": "414,416,415", + "death_animation": "1558", + "defence_animation": "1555", + "defence_level": "40", + "lifepoints": "105", + "magic_animation": "1557", + "melee_animation": "1557", + "range_animation": "1557", + "range_level": "1", + "safespot": null, + "slayer_exp": "105", + "strength_level": "70", + "weakness": "2" + }, + { + "id": "1625", + "name": "Smokedevil", + "examine": "The cave-dwelling cousin of the dust devils.", + "attack_level": "105", + "death_animation": "1558", + "defence_animation": "0", + "defence_level": "61", + "lifepoints": "87", + "magic_animation": "0", + "melee_animation": "1557", + "range_animation": "0", + "range_level": "61", + "safespot": null, + "strength_level": "105", + "weakness": "2" + }, + { + "id": "1626", + "name": "Turoth", + "examine": "She's one leg short!", + "attack_level": "56", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "86", + "lifepoints": "79", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "86" + }, + { + "id": "1627", + "name": "Turoth", + "examine": "It's one leg short!", + "attack_level": "54", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "84", + "lifepoints": "77", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "84" + }, + { + "id": "1628", + "name": "Turoth", + "examine": "It's one small leg short!", + "attack_level": "53", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "83", + "lifepoints": "76", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "83" + }, + { + "id": "1629", + "name": "Turoth", + "examine": "He's one big leg short!", + "attack_level": "57", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "87", + "lifepoints": "80", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "87" + }, + { + "id": "1630", + "name": "Turoth", + "examine": "He's one big leg short!", + "attack_level": "57", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "873,875,874", + "death_animation": "9472", + "defence_animation": "9473", + "defence_level": "87", + "lifepoints": "80", + "magic_animation": "9471", + "magic_level": "1", + "melee_animation": "9471", + "range_animation": "9471", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "87" + }, + { + "id": "1631", + "name": "Rockslug", + "examine": "A rocky slug.", + "attack_level": "24", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "729,731,730", + "death_animation": "1597", + "defence_animation": "1596", + "defence_level": "30", + "lifepoints": "30", + "magic_animation": "1595", + "magic_level": "1", + "melee_animation": "1595", + "range_animation": "1595", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "7" + }, + { + "id": "1632", + "name": "Rockslug", + "examine": "A rocky slug.", + "attack_level": "24", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "729,731,730", + "death_animation": "1597", + "defence_animation": "1596", + "defence_level": "30", + "lifepoints": "30", + "magic_animation": "1595", + "magic_level": "1", + "melee_animation": "1595", + "range_animation": "1595", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "7" + }, + { + "id": "1633", + "name": "Pyrefiend", + "examine": "A small fire demon.", + "attack_level": "22", + "attack_speed": "5", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "combat_audio": "696,698,697", + "death_animation": "8078", + "defence_animation": "8084", + "defence_level": "19", + "lifepoints": "45", + "magic_level": "10", + "melee_animation": "8080", + "range_level": "19", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "45", + "spawn_animation": "8081", + "strength_level": "29", + "weakness": "4" + }, + { + "id": "1634", + "name": "Pyrefiend", + "examine": "A small fire demon.", + "attack_level": "22", + "attack_speed": "5", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "combat_audio": "696,698,697", + "death_animation": "8078", + "defence_animation": "8084", + "defence_level": "19", + "lifepoints": "45", + "magic_level": "10", + "melee_animation": "8080", + "range_level": "19", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "45", + "spawn_animation": "8081", + "strength_level": "29", + "weakness": "4" + }, + { + "id": "1635", + "name": "Pyrefiend", + "examine": "A small fire demon.", + "attack_level": "22", + "attack_speed": "5", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "combat_audio": "696,698,697", + "death_animation": "8078", + "defence_animation": "8084", + "defence_level": "19", + "lifepoints": "45", + "magic_level": "10", + "melee_animation": "8080", + "range_level": "19", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "45", + "spawn_animation": "8081", + "strength_level": "29", + "weakness": "4" + }, + { + "id": "1636", + "name": "Pyrefiend", + "examine": "A small fire demon.", + "attack_level": "22", + "attack_speed": "5", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "combat_audio": "696,698,697", + "death_animation": "8078", + "defence_animation": "8084", + "defence_level": "19", + "lifepoints": "45", + "magic_level": "10", + "melee_animation": "8080", + "range_level": "19", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "45", + "spawn_animation": "8081", + "strength_level": "29", + "weakness": "4" + }, + { + "id": "1637", + "name": "Jelly", + "examine": "It's a Jelly.", + "attack_level": "40", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "547,550,549", + "death_animation": "8570", + "defence_animation": "8571", + "defence_level": "40", + "lifepoints": "75", + "magic_animation": "8569", + "magic_level": "40", + "melee_animation": "8569", + "range_animation": "8569", + "range_level": "40", + "safespot": null, + "slayer_exp": "75", + "strength_level": "45", + "weakness": "2" + }, + { + "id": "1638", + "name": "Jelly", + "examine": "Doesn't look so tough...", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "547,550,549", + "death_animation": "8570", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "melee_animation": "8569", + "range_animation": "0", + "range_level": "49", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "75", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "1639", + "name": "Jelly", + "examine": "Wibbly.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "547,550,549", + "death_animation": "8570", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "melee_animation": "8569", + "range_animation": "0", + "range_level": "49", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "75", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "1640", + "name": "Jelly", + "examine": "There's always room for jelly.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "547,550,549", + "death_animation": "8570", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "140", + "magic_animation": "0", + "melee_animation": "8569", + "range_animation": "0", + "range_level": "49", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "75", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "1641", + "name": "Jelly", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "547,550,549", + "defence_animation": "8571", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "8569", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "75", + "strength_level": "1" + }, + { + "id": "1642", + "name": "Jelly", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "547,550,549", + "defence_animation": "8571", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "8569", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "75", + "strength_level": "1" + }, + { + "id": "1643", + "name": "Infernal Mage", + "examine": "An evil magic user.", + "attack_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "end_gfx": "101", + "lifepoints": "60", + "magic_animation": "811", + "magic_level": "75", + "melee_animation": "811", + "projectile": "100", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "99", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "1644", + "name": "Infernal Mage", + "attack_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "end_gfx": "101", + "lifepoints": "60", + "magic_animation": "811", + "magic_level": "75", + "melee_animation": "811", + "projectile": "100", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "99", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "1645", + "name": "Infernal Mage", + "examine": "An evil magic user.", + "attack_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "end_gfx": "101", + "lifepoints": "60", + "magic_animation": "811", + "magic_level": "75", + "melee_animation": "811", + "projectile": "100", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "99", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "1646", + "name": "Infernal Mage", + "examine": "An evil magic user.", + "attack_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "end_gfx": "101", + "lifepoints": "60", + "magic_animation": "811", + "magic_level": "75", + "melee_animation": "811", + "projectile": "100", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "99", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "1647", + "name": "Infernal Mage", + "examine": "An evil magic user.", + "attack_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "end_gfx": "101", + "lifepoints": "60", + "magic_animation": "811", + "magic_level": "75", + "melee_animation": "811", + "projectile": "100", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "12", + "safespot": null, + "start_gfx": "99", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "1648", + "name": "Crawling Hand", + "examine": "Now THAT'S handy.", + "attack_level": "5", + "attack_speed": "5", + "bonuses": "5,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "377,379,378", + "death_animation": "9126", + "defence_animation": "9127", + "defence_level": "5", + "lifepoints": "16", + "magic_animation": "9125", + "melee_animation": "9125", + "range_animation": "9125", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "19", + "strength_level": "5", + "weakness": "9" + }, + { + "id": "1649", + "name": "Crawling Hand", + "examine": "Gimmie five. Actually", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9126", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "9125", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "19", + "strength_level": "8", + "weakness": "9" + }, + { + "id": "1650", + "name": "Crawling Hand", + "examine": "Gimmie five. Actually", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9126", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "9125", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "8", + "weakness": "9" + }, + { + "id": "1651", + "name": "Crawling Hand", + "examine": "Gimmie five. Actually", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9126", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "9125", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "19", + "strength_level": "8", + "weakness": "9" + }, + { + "id": "1652", + "name": "Crawling Hand", + "examine": "Gimmie five. Actually", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9126", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "9125", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "19", + "strength_level": "8", + "weakness": "9" + }, + { + "id": "1653", + "name": "Crawling Hand", + "examine": "Now THAT's handy.", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9445", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "9444", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "16", + "strength_level": "13", + "weakness": "9" + }, + { + "id": "1654", + "name": "Crawling Hand", + "examine": "I'm glad it's just the hand I can see...", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9445", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "9444", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "16", + "strength_level": "13", + "weakness": "9" + }, + { + "id": "1655", + "name": "Crawling Hand", + "examine": "A big severed hand.", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9445", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "9444", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "9" + }, + { + "id": "1656", + "name": "Crawling Hand", + "examine": "Give the guy a big hand.....", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9445", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "9444", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "16", + "strength_level": "13", + "weakness": "9" + }, + { + "id": "1657", + "name": "Crawling Hand", + "examine": "A big severed hand.", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "377,379,378", + "death_animation": "9445", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "9444", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "16", + "strength_level": "13", + "weakness": "9" + }, + { + "id": "1658", + "name": "Robe Store owner", + "examine": "A Supplier of Magical robes.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1659", + "name": "Skullball" + }, + { + "id": "1660", + "name": "Skullball Boss", + "examine": "He's in charge of the Skullball Course.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1661", + "name": "Agility Boss", + "examine": "He's in charge of the Agility Course.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1662", + "name": "Skullball Trainer", + "examine": "A skullball guide.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1663", + "name": "Agility Trainer", + "examine": "A werewolf agility trainer.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1664", + "name": "Agility Trainer" + }, + { + "id": "1665", + "name": "Werewolf", + "examine": "Looks like he's guarding a trapdoor...", + "attack_level": "1", + "clue_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1666", + "name": "Dr Fenkenstrain" + }, + { + "id": "1671", + "name": "Fenkenstrain's Monster" + }, + { + "id": "1674", + "name": "Lord Rologarth" + }, + { + "id": "1675", + "name": "Gardener Ghost", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1676", + "name": "Experiment", + "examine": "It has a key hanging from its collar.", + "attack_level": "40", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "1628", + "defence_animation": "1627", + "defence_level": "50", + "lifepoints": "40", + "magic_level": "1", + "melee_animation": "1626", + "range_level": "1", + "strength_level": "50" + }, + { + "id": "1677", + "name": "Experiment", + "examine": "One of Fenkenstrain's failed experiments.", + "aggressive": "", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "", + "death_animation": "1618", + "defence_animation": "1617", + "defence_level": "30", + "lifepoints": "100", + "magic_level": "1", + "melee_animation": "1616", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "1678", + "name": "Experiment", + "examine": "One of Fenkenstrain's failed experiments.", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "1611", + "defence_animation": "1613", + "defence_level": "30", + "lifepoints": "100", + "magic_level": "1", + "melee_animation": "1612", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "1679", + "name": "Eluned" + }, + { + "id": "1680", + "name": "Islwyn" + }, + { + "id": "1681", + "name": "Moss giant", + "examine": "His beard seems to have a life of its own.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "66,62,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "60", + "lifepoints": "120", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "safespot": null, + "strength_level": "60", + "weakness": "3" + }, + { + "id": "1682", + "name": "Golrie" + }, + { + "id": "1683", + "name": "Velorina" + }, + { + "id": "1684", + "name": "Necrovarus", + "examine": "An evil priest." + }, + { + "id": "1685", + "name": "Gravingas" + }, + { + "id": "1686", + "name": "Ghost disciple", + "examine": "A ghost disciple.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1687", + "name": "Ak-Haranu" + }, + { + "id": "1688", + "name": "Ak-Haranu", + "examine": "A trader from across the eastern sea.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "movement_radius": "2", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "0", + "start_height": "0", + "strength_level": "1" + }, + { + "id": "1689", + "name": "Undead cow" + }, + { + "id": "1691", + "name": "Undead cow", + "examine": "It's an undead cow.", + "aggressive": "false", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "-15,-15,-15,0,0,-21,-21,-21,-21,-21,0,-15,0,0,0", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5849", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "5", + "safespot": null, + "strength_level": "3", + "weakness": "8" + }, + { + "id": "1692", + "name": "Undead chicken", + "examine": "Yup, definitely a chicken... an undead chicken.", + "aggressive": "false", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,0,-42,0,0,0", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5387", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1693", + "name": "Giant lobster", + "examine": "An extremely vicious lobster.", + "attack_level": "30", + "death_animation": "6267", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "128", + "magic_animation": "0", + "melee_animation": "6265", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "1694", + "name": "Robin" + }, + { + "id": "1695", + "name": "Old crone", + "examine": "An old", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1696", + "name": "Old man", + "examine": "A creaky old man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1697", + "name": "Ghost villager", + "examine": "A spooky ghost villager.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1698", + "name": "Tortured soul", + "examine": "This poor soul cannot understand why it has not passed to the next world.", + "aggressive": "true", + "attack_level": "52", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "51", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "51", + "strength_level": "62", + "weakness": "3" + }, + { + "id": "1699", + "name": "Ghost shopkeeper", + "examine": "Beware the ghostly shopkeeper's wares!", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1700", + "name": "Ghost innkeeper", + "examine": "Doesn't look like the bar's open anymore.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1701", + "name": "Ghost farmer", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1702", + "name": "Ghost banker", + "examine": "A ghost banker.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1703", + "name": "Ghost sailor", + "examine": "A ghost sailor.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1704", + "name": "Ghost captain", + "examine": "A ghostship captain.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1705", + "name": "Ghost captain", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1706", + "name": "Ghost guard", + "examine": "This ghost guards the gates of Port Phasmatys.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1707", + "name": "Ghost (?)", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1708", + "name": "Ghost (?)", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1709", + "name": "Johanhus Ulsbrecht" + }, + { + "id": "1710", + "name": "H.A.M. Guard", + "examine": "A guard for the humans against monster group.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" + }, + { + "id": "1711", + "name": "H.A.M. Guard", + "examine": "A guard for the humans against monster group.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" + }, + { + "id": "1712", + "name": "H.A.M. Guard", + "examine": "A guard for the humans against monster group.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" + }, + { + "id": "1713", + "name": "H.A.M. Deacon", + "examine": "A deacon in the Humans Against Monsters group. A rather enthusiastic chap.", + "attack_level": "1", + "clue_level": "0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1714", + "name": "H.A.M. Member", + "examine": "A member of the 'Humans Against Monsters' group.", + "attack_level": "1", + "clue_level": "0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1715", + "name": "H.A.M. Member", + "examine": "A member of the 'Humans Against Monsters' group.", + "attack_level": "1", + "clue_level": "0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1716", + "name": "H.A.M. Member", + "examine": "A member of the 'Humans Against Monsters' group.", + "attack_level": "1", + "clue_level": "0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1717", + "name": "H.A.M. Member", + "examine": "A member of the 'Humans Against Monsters' group.", + "attack_level": "1", + "clue_level": "0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1718", + "name": "Jimmy the Chisel", + "examine": "A young man with a dark and mysterious past.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1719", + "name": "Tree" + }, + { + "id": "1720", + "name": "Tree" + }, + { + "id": "1721", + "name": "Tree" + }, + { + "id": "1722", + "name": "Dead tree" + }, + { + "id": "1723", + "name": "Dead tree" + }, + { + "id": "1724", + "name": "Dead tree" + }, + { + "id": "1725", + "name": "Dead tree" + }, + { + "id": "1726", + "name": "Dead tree" + }, + { + "id": "1727", + "name": "Dead tree" + }, + { + "id": "1728", + "name": "Dead tree" + }, + { + "id": "1729", + "name": "Dead tree" + }, + { + "id": "1730", + "name": "Dead tree" + }, + { + "id": "1731", + "name": "Dead tree" + }, + { + "id": "1732", + "name": "Dramen tree" + }, + { + "id": "1734", + "name": "Magic tree" + }, + { + "id": "1735", + "name": "Maple tree" + }, + { + "id": "1736", + "name": "Willow" + }, + { + "id": "1737", + "name": "Willow" + }, + { + "id": "1738", + "name": "Willow" + }, + { + "id": "1739", + "name": "Oak", + "examine": "Manages the mill.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1740", + "name": "Yew", + "examine": "One of Sigmund's elite guards.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1741", + "name": "Evergreen", + "examine": "One of Sigmund's elite guards.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1742", + "name": "Evergreen", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1743", + "name": "Evergreen", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1744", + "name": "Tree", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1745", + "name": "Dead tree", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1746", + "name": "Achey Tree", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1747", + "name": "Tree", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1748", + "name": "Tree", + "examine": "A member of Sigmund's H.A.M. splinter group.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1749", + "name": "Hollow tree" + }, + { + "id": "1750", + "name": "Hollow tree" + }, + { + "id": "1751", + "name": "Terrorbird", + "examine": "A giant raptor.", + "aggressive": "false", + "attack_level": "23", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "832,834,833", + "death_animation": "1013", + "defence_animation": "1012", + "defence_level": "19", + "lifepoints": "34", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1010", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "23" + }, + { + "id": "1752", + "name": "Mounted terrorbird gnome", + "examine": "These gnomes know how to get around!", + "attack_level": "33", + "death_animation": "6791", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "6790", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "6" + }, + { + "id": "1753", + "name": "Mounted terrorbird gnome" + }, + { + "id": "1754", + "name": "Crow", + "examine": "A farmer's enemy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1755", + "name": "Crow", + "examine": "A farmer's enemy." + }, + { + "id": "1756", + "name": "Crow" + }, + { + "id": "1757", + "name": "Farmer", + "examine": "He grows the crops in this area.", + "attack_level": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "9" + }, + { + "id": "1758", + "name": "Farmer", + "examine": "He grows the crops in this area.", + "attack_level": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "9" + }, + { + "id": "1759", + "name": "Farmer", + "examine": "Farming.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1760", + "name": "Farmer", + "examine": "He grows the crops in this area.", + "attack_level": "5", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "9" + }, + { + "id": "1761", + "name": "Farmer", + "examine": "Farming the wheat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1762", + "name": "Sheep" + }, + { + "id": "1763", + "name": "Sheep", + "examine": "White and fluffy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1764", + "name": "Sheep" + }, + { + "id": "1765", + "name": "Sheep" + }, + { + "id": "1766", + "name": "Cow calf", + "examine": "Young, but still beefy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "366,368,367", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "6", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", + "strength_level": "1" + }, + { + "id": "1767", + "name": "Cow", + "examine": "Where beef comes from.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "369,371,370", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", + "strength_level": "1", + "weakness": "8" + }, + { + "id": "1768", + "name": "Cow calf", + "examine": "Young, but still beefy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "366,368,367", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "6", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", + "strength_level": "1" + }, + { + "id": "1769", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1770", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1771", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1772", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1773", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1774", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1775", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1776", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1777", + "name": "Ilfeen" + }, + { + "id": "1778", + "name": "William" + }, + { + "id": "1779", + "name": "Ian" + }, + { + "id": "1780", + "name": "Larry" + }, + { + "id": "1781", + "name": "Darren" + }, + { + "id": "1782", + "name": "Edward" + }, + { + "id": "1783", + "name": "Richard", + "examine": "A very brave merchant." + }, + { + "id": "1784", + "name": "Neil" + }, + { + "id": "1785", + "name": "Edmond", + "examine": "A very brave merchant." + }, + { + "id": "1786", + "name": "Simon" + }, + { + "id": "1787", + "name": "Sam" + }, + { + "id": "1788", + "name": "Lumdo" + }, + { + "id": "1789", + "name": "Bunkwicket" + }, + { + "id": "1790", + "name": "Waymottin" + }, + { + "id": "1791", + "name": "Jungle Tree" + }, + { + "id": "1792", + "name": "Jungle Tree" + }, + { + "id": "1793", + "name": "Tassie Slipcast" + }, + { + "id": "1794", + "name": "Hammerspike Stoutbeard", + "examine": "He looks quite independent in an aggressive and business like way.", + "attack_level": "1", + "combat_audio": "498,500,499", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1795", + "name": "Dwarf gang member", + "examine": "A short stout menacing fellow.", + "attack_level": "25", + "attack_speed": "6", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "1796", + "name": "Dwarf gang member", + "examine": "A short stout menacing fellow.", + "attack_level": "25", + "attack_speed": "6", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "1797", + "name": "Dwarf gang member", + "examine": "A short stout menacing fellow.", + "attack_level": "25", + "attack_speed": "6", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "1798", + "name": "Phantuwti Fanstuwi Farsight" + }, + { + "id": "1799", + "name": "Tindel Marchant" + }, + { + "id": "1800", + "name": "Gnormadium Avlafrim" + }, + { + "id": "1801", + "name": "Petra Fiyed" + }, + { + "id": "1802", + "name": "Slagilith", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1752", + "defence_animation": "1751", + "defence_level": "1", + "lifepoints": "60", + "melee_animation": "1750", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1803", + "name": "Rock pile", + "examine": "A pile of boulders.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1804", + "name": "Slagilith" + }, + { + "id": "1805", + "name": "Guard", + "examine": "He seems to be guarding a pile of rocks. Interesting job.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1806", + "name": "Guard", + "examine": "He seems to be guarding a single rock. Interesting job.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1807", + "name": "Hamal the Chieftain", + "examine": "The Chieftain of the mountain camp.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1808", + "name": "Ragnar" + }, + { + "id": "1809", + "name": "Svidi" + }, + { + "id": "1810", + "name": "Jokul" + }, + { + "id": "1811", + "name": "The Kendal" + }, + { + "id": "1812", + "name": "The Kendal", + "examine": "Is that a bear... or a man?", + "aggressive": "true", + "attack_level": "23", + "death_animation": "1759", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "85", + "magic_animation": "0", + "magic_level": "23", + "melee_animation": "1760", + "range_animation": "0", + "range_level": "23", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "10" + }, + { + "id": "1813", + "name": "The Kendal", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1759", + "defence_animation": "1758", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "1760", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1814", + "name": "Camp dweller", + "examine": "One of the inhabitants of the camp.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "1815", + "name": "Camp dweller", + "examine": "One of the inhabitants of the camp.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "1816", + "name": "Camp dweller", + "examine": "One of the inhabitants of the camp.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "1817", + "name": "Camp dweller", + "examine": "One of the inhabitants of the camp.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "1818", + "name": "Camp dweller", + "examine": "One of the inhabitants of the camp.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "11", + "weakness": "9" + }, + { + "id": "1819", + "name": "Mountain Goat", + "examine": "Looks a little underfed.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1820", + "name": "Mountain Goat", + "examine": "This goat belongs to the mountain camp people.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1821", + "name": "Bald Headed Eagle" + }, + { + "id": "1822", + "name": "Cave goblin", + "examine": "A goblin with big bulging eyes.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "6001", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1823", + "name": "Cave goblin", + "examine": "A goblin with big bulging eyes.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "6001", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1824", + "name": "Cave goblin", + "examine": "A goblin with big bulging eyes.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "6001", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1825", + "name": "Cave goblin", + "examine": "A goblin with big bulging eyes.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "6001", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "1826", + "name": "Zombie", + "examine": "A human zombie.", + "attack_level": "30", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "30", + "lifepoints": "50", + "melee_animation": "5568", + "range_level": "1", + "safespot": null, + "strength_level": "30" + }, + { + "id": "1827", + "name": "Gargoyle", + "examine": "Flies like a rock.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "428,430,429", + "death_animation": "1518", + "defence_animation": "9455", + "defence_level": "107", + "lifepoints": "105", + "magic_animation": "1516", + "magic_level": "1", + "melee_animation": "9454", + "range_animation": "1516", + "range_level": "1", + "safespot": null, + "slayer_exp": "105", + "strength_level": "95" + }, + { + "id": "1828", + "name": "Giant frog", + "examine": "It didn't get that big eating flies!", + "attack_level": "45", + "attack_speed": "6", + "bonuses": "10,10,10,10,10,10,1,10,10,10,10,37,0,0,0", + "death_animation": "1795", + "defence_animation": "1794", + "defence_level": "60", + "lifepoints": "100", + "magic_animation": "1793", + "melee_animation": "1793", + "range_animation": "1793", + "range_level": "32", + "safespot": null, + "strength_level": "45", + "weakness": "1" + }, + { + "id": "1829", + "name": "Big frog", + "examine": "It didn't get that big eating flies.", + "attack_level": "1", + "death_animation": "1795", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "1793", + "range_animation": "0", + "range_level": "26", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "1" + }, + { + "id": "1830", + "name": "Frog" + }, + { + "id": "1831", + "name": "Cave slime", + "examine": "A foul-smelling blob of protoplasm.", + "aggressive": "false", + "attack_level": "13", + "attack_speed": "4", + "clue_level": "0", + "combat_audio": "784,786,785", + "death_animation": "1792", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "13", + "melee_animation": "1789", + "poison_amount": "15", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "25", + "strength_level": "13", + "weakness": "1" + }, + { + "id": "1832", + "name": "Cave bug", + "examine": "A nasty crawling critter.", + "attack_level": "6", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,5,5,10,0,0,0,0,0", + "death_animation": "6082", + "defence_animation": "0", + "defence_level": "6", + "lifepoints": "5", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6079", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "5", + "strength_level": "5", + "weakness": "2" + }, + { + "id": "1833", + "name": "Cave bug larva", + "examine": "A little", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1834", + "name": "Candle seller", + "examine": "Has an odd smell about him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1835", + "name": "Easter Bunny" + }, + { + "id": "1836", + "name": "Dondakan the Dwarf" + }, + { + "id": "1838", + "name": "Dondakan the Dwarf" + }, + { + "id": "1839", + "name": "Dondakan the Dwarf" + }, + { + "id": "1840", + "name": "Dwarven Engineer", + "examine": "A short angry guy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1841", + "name": "Rolad" + }, + { + "id": "1842", + "name": "Khorvak, a dwarven engineer", + "examine": "The little guy is having trouble standing up right.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1843", + "name": "Dwarven Ferryman", + "examine": "It's probably you who will be paying the ferryman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1844", + "name": "Dwarven Ferryman", + "examine": "It's probably you who will be paying the ferryman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1845", + "name": "Dwarven Boatman" + }, + { + "id": "1846", + "name": "Dwarven Boatman", + "examine": "He seems to be in charge of the ship on the river.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1847", + "name": "Miodvetnir" + }, + { + "id": "1848", + "name": "Dernu" + }, + { + "id": "1849", + "name": "Derni" + }, + { + "id": "1850", + "name": "Arzinian Avatar of Strength", + "examine": "It is the avatar of the Arzinian Being of Bordanzan", + "attack_level": "40", + "death_animation": "1841", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "114", + "magic_animation": "0", + "melee_animation": "1840", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "1851", + "name": "Arzinian Avatar of Strength", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1843", + "defence_animation": "1842", + "defence_level": "1", + "lifepoints": "110", + "melee_animation": "1840", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1852", + "name": "Arzinian Avatar of Strength", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1843", + "defence_animation": "1842", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "1840", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1853", + "name": "Arzinian Avatar of Ranging", + "examine": "It is the avatar of the Arzinian Being of Bordanzan", + "aggressive": "true", + "attack_level": "30", + "death_animation": "1841", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "114", + "magic_animation": "0", + "melee_animation": "1843", + "range_animation": "1843", + "range_level": "40", + "safespot": null, + "strength_level": "30", + "weakness": "0" + }, + { + "id": "1854", + "name": "Arzinian Avatar of Ranging", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1843", + "defence_animation": "1842", + "defence_level": "1", + "lifepoints": "110", + "melee_animation": "1840", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1855", + "name": "Arzinian Avatar of Ranging", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1843", + "defence_animation": "1842", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "1840", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1856", + "name": "Arzinian Avatar of Magic", + "examine": "It is the avatar of the Arzinian Being of Bordanzan", + "aggressive": "true", + "attack_level": "30", + "death_animation": "1841", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "114", + "magic_animation": "0", + "magic_level": "40", + "melee_animation": "1844", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "3" + }, + { + "id": "1857", + "name": "Arzinian Avatar of Magic", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1843", + "defence_animation": "1842", + "defence_level": "1", + "lifepoints": "110", + "melee_animation": "1840", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1858", + "name": "Arzinian Avatar of Magic", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1843", + "defence_animation": "1842", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "1840", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1859", + "name": "Arzinian Being of Bordanzan", + "examine": "It's the Arzinian Being", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1860", + "name": "Brian" + }, + { + "id": "1861", + "name": "Ranged Tutor", + "examine": "Nemarti looks ready to teach you about ranged combat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1862", + "name": "Ali Morrisane" + }, + { + "id": "1863", + "name": "Drunken Ali", + "examine": "Drunk man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1864", + "name": "Ali The barman", + "examine": "A hassled looking barman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1865", + "name": "Ali the Kebab seller", + "examine": "A kebab seller.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1866", + "name": "Brian", + "examine": "He sells ranging equipment.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1867", + "name": "Ali the Camel Man", + "examine": "Ali the discount animal seller.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1868", + "name": "Street urchin", + "examine": "A mischievous looking child.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1869", + "name": "Ali the Mayor" + }, + { + "id": "1871", + "name": "Ali the Hag", + "examine": "An old Hag named Alice.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1872", + "name": "Ali the Snake Charmer", + "examine": "A snake charmer.", + "attack_level": "1", + "combat_audio": "3609,3608,3610", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1873", + "name": "Ali the Camel", + "examine": "A foul tempered ugly lumpy yellow horse prone to spitting.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1874", + "name": "Desert snake", + "examine": "A slithering serpent.", + "attack_level": "4", + "combat_audio": "3609,3608,3610", + "death_animation": "278", + "defence_animation": "0", + "defence_level": "6", + "lifepoints": "8", + "magic_animation": "0", + "melee_animation": "275", + "range_animation": "0", + "range_level": "6", + "respawn_delay": "60", + "safespot": null, + "strength_level": "4", + "weakness": "1" + }, + { + "id": "1875", + "name": "Snake", + "examine": "A toothless old Snake.", + "attack_level": "1", + "combat_audio": "3609,3608,3610", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1876", + "name": "Bandit Leader" + }, + { + "id": "1879", + "name": "Bandit" + }, + { + "id": "1881", + "name": "Bandit" + }, + { + "id": "1882", + "name": "Sir Palomedes" + }, + { + "id": "1883", + "name": "Sir Palomedes" + }, + { + "id": "1884", + "name": "Trobert", + "examine": "A well dressed thief." + }, + { + "id": "1885", + "name": "Bandit champion", + "examine": "A very tough-looking bandit.", + "aggressive": "true", + "attack_level": "39", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "39", + "lifepoints": "55", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "39", + "weakness": "9" + }, + { + "id": "1886", + "name": "Cowardly Bandit", + "examine": "Probably the weakest bandit in the world ....ever.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1887", + "name": "Villager" + }, + { + "id": "1889", + "name": "Villager" + }, + { + "id": "1890", + "name": "Villager" + }, + { + "id": "1891", + "name": "Villager" + }, + { + "id": "1893", + "name": "Villager" + }, + { + "id": "1894", + "name": "Villager" + }, + { + "id": "1895", + "name": "Villager" + }, + { + "id": "1897", + "name": "Villager" + }, + { + "id": "1898", + "name": "Villager" + }, + { + "id": "1899", + "name": "Menaphite Leader" + }, + { + "id": "1902", + "name": "Ali the Operator", + "examine": "Smooth operator.", + "attack_level": "6", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,5,5,10,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1903", + "name": "Menaphite Thug" + }, + { + "id": "1904", + "name": "Menaphite Thug", + "examine": "Menaphite thug.", + "aggressive": "false", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,9,8,10,0,0,0,9,0,0,0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "60", + "magic_animation": "0", + "magic_level": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "0", + "respawn_delay": "5", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "1905", + "name": "Menaphite Thug", + "examine": "Menaphite thug.", + "aggressive": "false", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,9,8,10,0,0,0,9,0,0,0", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "20", + "lifepoints": "60", + "magic_animation": "0", + "magic_level": "0", + "melee_animation": "395", + "range_animation": "0", + "range_level": "0", + "respawn_delay": "5", + "safespot": null, + "strength_level": "50" + }, + { + "id": "1906", + "name": "Tough Guy", + "examine": "Tough looking Menaphite.", + "aggressive": "true", + "attack_level": "39", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "39", + "lifepoints": "114", + "magic_animation": "0", + "melee_animation": "395", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "39", + "weakness": "9" + }, + { + "id": "1907", + "name": "Broken clay golem" + }, + { + "id": "1909", + "name": "Damaged clay golem" + }, + { + "id": "1910", + "name": "Clay golem" + }, + { + "id": "1911", + "name": "Desert Phoenix", + "examine": "Definitely not a chicken.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1912", + "name": "Elissa" + }, + { + "id": "1913", + "name": "Kamil", + "examine": "Ice warrior.", + "attack_level": "190", + "attack_speed": "5", + "bonuses": "0,60,0,0,0,35,60,35,0,0,0,100,0,0,0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "135", + "lifepoints": "130", + "magic_animation": "412", + "melee_animation": "440", + "range_animation": "440", + "range_level": "1", + "safespot": null, + "strength_level": "80" + }, + { + "id": "1914", + "name": "Dessous", + "examine": "A vampyre warrior of Zamorak.", + "aggressive": "true", + "attack_level": "99", + "bonuses": "0,0,50,0,0,10,150,150,0,0,0,50,0,0,0", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "99", + "lifepoints": "200", + "melee_animation": "1264", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "99" + }, + { + "id": "1915", + "name": "Dessous", + "examine": "A vampyre warrior of Zamorak.", + "aggressive": "true", + "attack_level": "99", + "bonuses": "0,0,50,0,0,10,150,150,0,0,0,50,0,0,0", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "99", + "lifepoints": "200", + "melee_animation": "1264", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "99" + }, + { + "id": "1916", + "name": "Ruantun", + "examine": "Luckily, I can't see much of his face.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1917", + "name": "Bandit shopkeeper", + "examine": "I guess he sells what he steals...?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1918", + "name": "Archaeologist", + "examine": "Hardened by the cutthroat world of archaeology.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1919", + "name": "Stranger", + "examine": "Very mysterious looking...", + "aggressive": "true", + "attack_level": "58", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "58", + "lifepoints": "82", + "magic_animation": "0", + "melee_animation": "377", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "58", + "weakness": "7" + }, + { + "id": "1920", + "name": "Malak", + "examine": "One of Morytania's vampyric nobility.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1921", + "name": "Bartender", + "examine": "Looks like a rough-and-ready type.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1922", + "name": "Eblis" + }, + { + "id": "1924", + "name": "Eblis" + }, + { + "id": "1926", + "name": "Bandit", + "examine": "A tough-looking criminal.", + "attack_level": "30", + "attack_speed": "5", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "30", + "lifepoints": "65", + "magic_animation": "412", + "melee_animation": "412", + "range_animation": "412", + "range_level": "1", + "safespot": null, + "strength_level": "70" + }, + { + "id": "1927", + "name": "Bandit" + }, + { + "id": "1928", + "name": "Bandit" + }, + { + "id": "1929", + "name": "Bandit" + }, + { + "id": "1930", + "name": "Bandit" + }, + { + "id": "1931", + "name": "Bandit", + "examine": "This is an NPC.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "412", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "100", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1932", + "name": "Troll child" + }, + { + "id": "1934", + "name": "Troll child" + }, + { + "id": "1935", + "name": "Ice troll", + "examine": "An ice troll.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1936", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1937", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1938", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1939", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1940", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1941", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "aggressive": "true", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1942", + "name": "Ice troll", + "examine": "Brrrrr...he must be cold!", + "attack_level": "64", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "9" + }, + { + "id": "1943", + "name": "Ice block", + "examine": "A troll frozen in a block of ice.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1944", + "name": "Ice block", + "examine": "A troll frozen in a block of ice.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1945", + "name": "Ice block", + "examine": "A troll frozen in a block of ice.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1946", + "name": "Ice block", + "examine": "A troll frozen in a block of ice.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "1947", + "name": "Troll father", + "examine": "An ice troll." + }, + { + "id": "1948", + "name": "Troll father", + "examine": "An ice troll." + }, + { + "id": "1949", + "name": "Troll mother", + "examine": "An ice troll." + }, + { + "id": "1950", + "name": "Troll mother", + "examine": "An ice troll." + }, + { + "id": "1951", + "name": "Ice wolf", + "examine": "Not a man's best friend.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "60", + "lifepoints": "72", + "magic_animation": "6579", + "magic_level": "30", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "28", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1952", + "name": "Ice wolf", + "examine": "Not a man's best friend.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "60", + "lifepoints": "72", + "magic_animation": "6579", + "magic_level": "30", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "28", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1953", + "name": "Ice wolf", + "examine": "Not a man's best friend.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "60", + "lifepoints": "72", + "magic_animation": "6579", + "magic_level": "30", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "28", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1954", + "name": "Ice wolf", + "examine": "Not a man's best friend.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "60", + "lifepoints": "72", + "magic_animation": "6579", + "magic_level": "30", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "28", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1955", + "name": "Ice wolf", + "examine": "Not a man's best friend.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "60", + "lifepoints": "72", + "magic_animation": "6579", + "magic_level": "30", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "28", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1956", + "name": "Ice wolf", + "examine": "Not a man's best friend.", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "60", + "lifepoints": "72", + "magic_animation": "6579", + "magic_level": "30", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "28", + "safespot": null, + "strength_level": "60" + }, + { + "id": "1957", + "name": "Mummy" + }, + { + "id": "1958", + "name": "Mummy", + "examine": "Highly flammable!", + "attack_level": "55", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5549", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "1959", + "name": "Mummy" + }, + { + "id": "1960", + "name": "Mummy ashes" + }, + { + "id": "1961", + "name": "Mummy", + "examine": "A tightly-wrapped monster.", + "aggressive": "true", + "attack_level": "90", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "90", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "5549", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "90", + "weakness": "9" + }, + { + "id": "1962", + "name": "Mummy", + "examine": "Spooky, bandaged dead dude.", + "aggressive": "true", + "attack_level": "90", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "90", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "5549", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "90", + "weakness": "9" + }, + { + "id": "1963", + "name": "Mummy", + "examine": "A victim of poor first aid.", + "aggressive": "true", + "attack_level": "90", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "90", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "5549", + "poison_immune": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "90", + "weakness": "9" + }, + { + "id": "1964", + "name": "Mummy", + "examine": "But who's the daddy?", + "aggressive": "true", + "attack_level": "90", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "90", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "5549", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "90", + "weakness": "9" + }, + { + "id": "1965", + "name": "Mummy", + "examine": "A tightly-wrapped monster.", + "attack_level": "55", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5549", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "1966", + "name": "Mummy" + }, + { + "id": "1967", + "name": "Mummy", + "examine": "A victim of poor first aid.", + "attack_level": "55", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5549", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "1968", + "name": "Mummy" + }, + { + "id": "1969", + "name": "Scarabs", + "examine": "I think they're some kind of beetle...", + "attack_level": "255", + "attack_speed": "3", + "death_animation": "5464", + "defence_animation": "1946", + "defence_level": "10", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "1948", + "poison_amount": "15", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "2", + "weakness": "7" + }, + { + "id": "1970", + "name": "Azzanadra" + }, + { + "id": "1972", + "name": "Rasolo", + "examine": "A wandering merchant.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1973", + "name": "Giant skeleton", + "examine": "A giant skeleton.", + "attack_level": "60", + "death_animation": "5503", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "5499", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "60", + "weakness": "8" + }, + { + "id": "1974", + "name": "Damis", + "examine": "The warrior of darkness.", + "attack_level": "90", + "bonuses": "0,0,0,0,0,60,60,60,60,60,0,80,0,0,0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "90", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "440", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "90", + "weakness": "0" + }, + { + "id": "1975", + "name": "Damis", + "examine": "The warrior of darkness.", + "attack_level": "160", + "attack_speed": "3", + "bonuses": "0,0,0,0,0,100,100,100,80,120,0,100,0,0,0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "160", + "lifepoints": "200", + "magic_animation": "0", + "melee_animation": "440", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "0" + }, + { + "id": "1976", + "name": "Shadow Hound", + "examine": "Looks hungry!", + "attack_level": "48", + "death_animation": "6564", + "defence_animation": "0", + "defence_level": "48", + "lifepoints": "68", + "magic_animation": "0", + "melee_animation": "6565", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "7" + }, + { + "id": "1977", + "name": "Fareed", + "examine": "Zamorak's warrior of fire.", + "aggressive": "true", + "attack_level": "190", + "bonuses": "0,0,0,0,0,100,100,100,0,0,0,120,0,0,0", + "death_animation": "836", + "defence_animation": "434", + "defence_level": "135", + "lifepoints": "130", + "magic_level": "100", + "melee_animation": "799", + "range_level": "100", + "respawn_delay": "60", + "safespot": null, + "strength_level": "120" + }, + { + "id": "1978", + "name": "Slave", + "examine": "A malnourished worker.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1979", + "name": "Slave", + "examine": "A malnourished worker.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1980", + "name": "Embalmer", + "examine": "A strange-smelling merchant.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1981", + "name": "Carpenter", + "examine": "A block of a man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1982", + "name": "Raetul" + }, + { + "id": "1983", + "name": "Siamun" + }, + { + "id": "1984", + "name": "High Priest" + }, + { + "id": "1987", + "name": "Priest" + }, + { + "id": "1988", + "name": "Priest", + "examine": "Preach my brother!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "1989", + "name": "Priest" + }, + { + "id": "1990", + "name": "Sphinx" + }, + { + "id": "1991", + "name": "Possessed Priest", + "examine": "He has a dangerous glint in his eye.", + "aggressive": "true", + "attack_level": "30", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "429", + "range_animation": "0", + "range_level": "40", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "1" + }, + { + "id": "1992", + "name": "Neite" + }, + { + "id": "1993", + "name": "Crocodile", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "386,388,387", + "death_animation": "7591", + "defence_animation": "7590", + "defence_level": "1", + "lifepoints": "63", + "melee_animation": "7588", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "62", + "strength_level": "1" + }, + { + "id": "1994", + "name": "Jackal", + "examine": "He has had his day.", + "aggressive": "true", + "attack_level": "17", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "544,546,545", + "death_animation": "6567", + "defence_animation": "0", + "defence_level": "15", + "lifepoints": "27", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "18", + "weakness": "6" + }, + { + "id": "1995", + "name": "Locust", + "examine": "Obnoxious", + "aggressive": "true", + "attack_level": "12", + "attack_speed": "5", + "death_animation": "2013", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "34", + "magic_animation": "0", + "melee_animation": "2015", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "12", + "weakness": "6" + }, + { + "id": "1996", + "name": "Vulture" + }, + { + "id": "1997", + "name": "Plague frog", + "examine": "A very smelly frog.", + "aggressive": "true", + "attack_level": "15", + "death_animation": "1022", + "defence_animation": "0", + "defence_level": "15", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "1021", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "6" + }, + { + "id": "1998", + "name": "Plague cow", + "examine": "I might give the burgers a miss in this town.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "6" + }, + { + "id": "1999", + "name": "Plague cow", + "examine": "I don't fancy eating any part of this.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "6" + }, + { + "id": "2000", + "name": "Plague cow" + }, + { + "id": "2001", + "name": "Scarab swarm", + "examine": "I think they're some kind of beetle.", + "aggressive": "true", + "attack_level": "9", + "attack_speed": "2", + "death_animation": "1946", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "900", + "magic_animation": "0", + "melee_animation": "1948", + "poison_amount": "15", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "6" + }, + { + "id": "2002", + "name": "Wanderer" + }, + { + "id": "2006", + "name": "Wanderer" + }, + { + "id": "2007", + "name": "Het" + }, + { + "id": "2008", + "name": "Apmeken" + }, + { + "id": "2009", + "name": "Scabaras" + }, + { + "id": "2010", + "name": "Crondis" + }, + { + "id": "2011", + "name": "Icthlarin" + }, + { + "id": "2013", + "name": "Klenter" + }, + { + "id": "2015", + "name": "Mummy", + "examine": "This mummy looks like it means business!", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5554", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "2016", + "name": "Mummy", + "examine": "An irate warrior-mummy.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5554", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "2017", + "name": "Mummy", + "examine": "This mummy looks like it means business!", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5554", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "2018", + "name": "Mummy", + "examine": "An irate mummy.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5554", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "2019", + "name": "Mummy", + "examine": "A wizened old warrior.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "death_animation": "5555", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5554", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "2020", + "name": "Light creature" + }, + { + "id": "2021", + "name": "Light creature", + "examine": "A shimmering creature of blue light.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2022", + "name": "Light creature" + }, + { + "id": "2023", + "name": "Juna" + }, + { + "id": "2024", + "name": "Strange Old Man", + "examine": "Wonder how long he's been here...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2025", + "name": "Ahrim the Blighted", + "examine": "A vengeful spirit corrupted by dark magic.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "68,68,68,73,-19,103,85,117,73,0,0,68,0,49,0", + "combat_style": "2", + "death_animation": "7197", + "defence_animation": "420", + "defence_level": "100", + "end_gfx": "157", + "lifepoints": "100", + "magic_animation": "1162", + "magic_level": "100", + "melee_animation": "1162", + "projectile": "156", + "range_animation": "1162", + "range_level": "1", + "safespot": null, + "start_gfx": "155", + "start_height": "96", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "2026", + "name": "Dharok the Wretched", + "examine": "A vengeful spirit corrupted by dark magic.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "7", + "bonuses": "105,105,105,-58,-18,252,250,244,-11,249,0,105,0,0,0", + "death_animation": "7197", + "defence_animation": "2063", + "defence_level": "100", + "lifepoints": "100", + "magic_animation": "2066", + "magic_level": "1", + "melee_animation": "2066", + "range_animation": "2066", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "100", + "weakness": "9" + }, + { + "id": "2027", + "name": "Guthan the Infested", + "examine": "A vengeful spirit corrupted by dark magic.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "5", + "bonuses": "75,75,75,-50,-19,259,247,241,-11,-250,0,75,0,0,0", + "death_animation": "7197", + "defence_animation": "2079", + "defence_level": "100", + "lifepoints": "100", + "magic_animation": "2080", + "magic_level": "1", + "melee_animation": "2080", + "range_animation": "2080", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "100", + "weakness": "6" + }, + { + "id": "2028", + "name": "Karil the Tainted", + "examine": "A vengeful spirit corrupted by dark magic.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,-26,134,79,71,90,106,100,0,0,0,0,61", + "combat_style": "1", + "death_animation": "7197", + "defence_animation": "424", + "defence_level": "100", + "lifepoints": "100", + "magic_animation": "2075", + "magic_level": "1", + "melee_animation": "2075", + "projectile": "27", + "range_animation": "2075", + "range_level": "100", + "respawn_delay": "16", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "2029", + "name": "Torag the Corrupted", + "examine": "A vengeful spirit corrupted by dark magic.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "5", + "bonuses": "72,72,72,-33,-11,221,235,222,0,221,0,72,0,0,0", + "death_animation": "7197", + "defence_animation": "404", + "defence_level": "100", + "lifepoints": "100", + "magic_animation": "2068", + "magic_level": "1", + "melee_animation": "2068", + "range_animation": "2068", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "100", + "weakness": "7" + }, + { + "id": "2030", + "name": "Verac the Defiled", + "examine": "A vengeful spirit corrupted by dark magic.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "5", + "bonuses": "72,72,72,-42,-14,227,230,221,0,225,72,78,0,0,0", + "combat_audio": "", + "death_animation": "7197", + "defence_animation": "2063", + "defence_level": "100", + "lifepoints": "100", + "magic_animation": "2062", + "magic_level": "1", + "melee_animation": "2062", + "range_animation": "2062", + "range_level": "1", + "safespot": null, + "strength_level": "100", + "weakness": "8" + }, + { + "id": "2031", + "name": "Bloodworm", + "examine": "I think I should keep my distance...", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "2073", + "defence_animation": "2072", + "defence_level": "35", + "lifepoints": "45", + "magic_animation": "2070", + "magic_level": "1", + "melee_animation": "2070", + "range_animation": "2070", + "range_level": "1", + "respawn_delay": "26", + "safespot": null, + "strength_level": "20", + "weakness": "6" + }, + { + "id": "2032", + "name": "Crypt rat", + "examine": "A nasty little rodent.", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "243", + "defence_animation": "241", + "defence_level": "20", + "lifepoints": "35", + "magic_animation": "240", + "magic_level": "1", + "melee_animation": "240", + "range_animation": "240", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "20", + "weakness": "9" + }, + { + "id": "2033", + "name": "Giant crypt rat", + "examine": "A nasty overgrown rodent.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "65", + "lifepoints": "70", + "magic_animation": "4933", + "magic_level": "1", + "melee_animation": "4933", + "range_animation": "4933", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "2034", + "name": "Crypt spider", + "examine": "Incey wincey.", + "aggressive": "true", + "attack_level": "45", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,10,17,20,0,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "6251", + "defence_animation": "6250", + "defence_level": "45", + "lifepoints": "45", + "magic_animation": "6249", + "magic_level": "1", + "melee_animation": "6249", + "range_animation": "6249", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "2035", + "name": "Giant crypt spider", + "examine": "Not very incey wincey.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "65", + "lifepoints": "80", + "magic_animation": "5327", + "magic_level": "1", + "melee_animation": "5327", + "range_animation": "5327", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "strength_level": "67", + "weakness": "7" + }, + { + "id": "2036", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "72", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,-5,0,5,0,0,0,0,0", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "72", + "lifepoints": "51", + "magic_animation": "5487", + "magic_level": "1", + "melee_animation": "5487", + "range_animation": "5487", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "72", + "weakness": "8" + }, + { + "id": "2037", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "72", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,5,5,-5,0,5,0,0,0,0,0", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "72", + "lifepoints": "51", + "magic_animation": "5487", + "magic_level": "1", + "melee_animation": "5487", + "range_animation": "5487", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "72", + "weakness": "8" + }, + { + "id": "2038", + "name": "Grish" + }, + { + "id": "2039", + "name": "Uglug Nar" + }, + { + "id": "2040", + "name": "Pilg" + }, + { + "id": "2041", + "name": "Grug" + }, + { + "id": "2042", + "name": "Ogre guard" + }, + { + "id": "2043", + "name": "Ogre guard" + }, + { + "id": "2044", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2045", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2046", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2047", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2048", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2049", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2050", + "name": "Skogre", + "examine": "It's falling apart!", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2051", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2052", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2053", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2054", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2055", + "name": "Zogre", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2056", + "name": "Skogre", + "examine": "It's falling apart!", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2057", + "name": "Skogre", + "examine": "It's falling apart!", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "35", + "lifepoints": "71", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "strength_level": "36", + "weakness": "7" + }, + { + "id": "2058", + "name": "Hole in the wall", + "examine": "What could be hiding in that crack in the wall?", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "931,923,922", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1", + "weakness": "7" + }, + { + "id": "2059", + "name": "Zavistic Rarve" + }, + { + "id": "2060", + "name": "Slash Bash", + "examine": "A partially decomposing zombie ogre.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "6", + "combat_audio": "", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "60", + "lifepoints": "100", + "magic_animation": "359", + "magic_level": "1", + "melee_animation": "359", + "range_animation": "359", + "range_level": "100", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "", + "slayer_task": "64", + "strength_level": "120", + "weakness": "7" + }, + { + "id": "2061", + "name": "Sithik Ints" + }, + { + "id": "2062", + "name": "Sithik Ints" + }, + { + "id": "2063", + "name": "Gargh" + }, + { + "id": "2064", + "name": "Scarg" + }, + { + "id": "2065", + "name": "Gruh" + }, + { + "id": "2066", + "name": "Irwin Feaselbaum" + }, + { + "id": "2067", + "name": "Fishing spot", + "examine": "I can see fish swimming in the water.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2068", + "name": "Fishing spot" + }, + { + "id": "2069", + "name": "Cave goblin miner", + "examine": "This one is slacking off.", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "6" + }, + { + "id": "2070", + "name": "Cave goblin miner", + "examine": "This one is slacking off.", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "6" + }, + { + "id": "2071", + "name": "Cave goblin miner", + "examine": "This one is slacking off.", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "6" + }, + { + "id": "2072", + "name": "Cave goblin miner", + "examine": "This one is slacking off.", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "5", + "weakness": "6" + }, + { + "id": "2073", + "name": "Cave goblin guard", + "examine": "He protects the miners.", + "attack_level": "15", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "15", + "lifepoints": "21", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "6" + }, + { + "id": "2074", + "name": "Cave goblin guard", + "examine": "He protects the miners.", + "attack_level": "15", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "15", + "lifepoints": "21", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "6" + }, + { + "id": "2075", + "name": "Cave goblin miner", + "examine": "He's working hard!", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "melee_animation": "6007", + "range_level": "1", + "safespot": null, + "strength_level": "5" + }, + { + "id": "2076", + "name": "Cave goblin miner", + "examine": "He's working hard!", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "melee_animation": "6007", + "range_level": "1", + "safespot": null, + "strength_level": "5" + }, + { + "id": "2077", + "name": "Cave goblin miner", + "examine": "He's working hard!", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "melee_animation": "6007", + "range_level": "1", + "safespot": null, + "strength_level": "5" + }, + { + "id": "2078", + "name": "Cave goblin miner", + "examine": "He's working hard!", + "attack_level": "5", + "combat_audio": "469,472,471", + "death_animation": "6003", + "defence_animation": "6008", + "defence_level": "5", + "lifepoints": "10", + "melee_animation": "6007", + "range_level": "1", + "safespot": null, + "strength_level": "5" + }, + { + "id": "2079", + "name": "Sigmund" + }, + { + "id": "2082", + "name": "Sigmund", + "examine": "Advisor to the Duke of Lumbridge.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2083", + "name": "Sigmund" + }, + { + "id": "2084", + "name": "Mistag" + }, + { + "id": "2085", + "name": "Kazgar" + }, + { + "id": "2087", + "name": "Ur-tag" + }, + { + "id": "2088", + "name": "Duke Horacio" + }, + { + "id": "2089", + "name": "Mistag" + }, + { + "id": "2090", + "name": "Sigmund" + }, + { + "id": "2091", + "name": "Secretary", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "5327", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2092", + "name": "Purple Pewter Secretary", + "examine": "The head secretary of the Purple Pewter mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2093", + "name": "Yellow Fortune Secretary", + "examine": "The head secretary of the Yellow Fortune mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2094", + "name": "Blue Opal Secretary", + "examine": "The head secretary of the Blue Opal mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2095", + "name": "Green Gemstone Secretary", + "examine": "The head secretary of the Green Gemstone mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2096", + "name": "White Chisel Secretary", + "examine": "The head secretary of the White Chisel mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2097", + "name": "Silver Cog Secretary", + "examine": "The head secretary of the Silver Cog mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2098", + "name": "Brown Engine Secretary", + "examine": "The head secretary of the Brown Engine mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2099", + "name": "Red Axe Secretary" + }, + { + "id": "2100", + "name": "Purple Pewter Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2101", + "name": "Blue Opal Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2102", + "name": "Yellow Fortune Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2103", + "name": "Green Gemstone Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2104", + "name": "White Chisel Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2105", + "name": "Silver Cog Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2106", + "name": "Brown Engine Director", + "examine": "One of the leaders of the business Consortium", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2107", + "name": "Red Axe Director" + }, + { + "id": "2108", + "name": "Red Axe Cat" + }, + { + "id": "2109", + "name": "Trader", + "examine": "A trader for the Purple Pewter mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2110", + "name": "Trader", + "examine": "A trader for the Purple Pewter mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2111", + "name": "Trader", + "examine": "A trader for the Blue Opal mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2112", + "name": "Trader", + "examine": "A trader for the Blue Opal mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2113", + "name": "Trader", + "examine": "A trader for the Yellow Fortune mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2114", + "name": "Trader", + "examine": "A trader for the Yellow Fortune mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2115", + "name": "Trader", + "examine": "A trader for the Green Gemstone mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2116", + "name": "Trader", + "examine": "A trader for the Green Gemstone mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2117", + "name": "Trader", + "examine": "A trader for the White Chisel mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2118", + "name": "Trader", + "examine": "A trader for the White Chisel mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2119", + "name": "Trader", + "examine": "A trader for the Silver Cog mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2120", + "name": "Trader", + "examine": "A trader for the Silver Cog mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2121", + "name": "Trader", + "examine": "A trader for the Brown Engine mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2122", + "name": "Trader", + "examine": "A trader for the Brown Engine mining company.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2123", + "name": "Trader" + }, + { + "id": "2125", + "name": "Trader" + }, + { + "id": "2127", + "name": "Trade Referee", + "examine": "He is regulating the flow of goods on the trade floor and maintaining order.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2128", + "name": "Supreme Commander" + }, + { + "id": "2129", + "name": "Commander Veldaban" + }, + { + "id": "2130", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "34", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2131", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "34", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2132", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "34", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2133", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "34", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2134", + "name": "Black Guard Berserker", + "examine": "An elite member of the Black Guard.", + "attack_level": "38", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "38", + "weakness": "6" + }, + { + "id": "2135", + "name": "Black Guard Berserker", + "examine": "An elite member of the Black Guard.", + "attack_level": "38", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "38", + "weakness": "6" + }, + { + "id": "2136", + "name": "Black Guard Berserker", + "examine": "An elite member of the Black Guard.", + "attack_level": "38", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "38", + "weakness": "6" + }, + { + "id": "2137", + "name": "Gnome emissary" + }, + { + "id": "2138", + "name": "Gnome traveller", + "examine": "A gnome traveller, visiting Keldagrim.", + "attack_level": "1", + "defence_level": "1", + "force_talk": "", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2139", + "name": "Gnome traveller", + "examine": "A gnome traveller, visiting Keldagrim.", + "attack_level": "1", + "defence_level": "1", + "force_talk": "", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2140", + "name": "Dromund's cat", + "examine": "Very protective of his master... and his property.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2141", + "name": "Blasidar the sculptor", + "examine": "Makes sculptures.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2142", + "name": "Riki the sculptor's model" + }, + { + "id": "2144", + "name": "Riki the sculptor's model" + }, + { + "id": "2145", + "name": "Riki the sculptor's model" + }, + { + "id": "2146", + "name": "Riki the sculptor's model" + }, + { + "id": "2147", + "name": "Riki the sculptor's model" + }, + { + "id": "2148", + "name": "Riki the sculptor's model" + }, + { + "id": "2149", + "name": "Riki the sculptor's model" + }, + { + "id": "2150", + "name": "Riki the sculptor's model" + }, + { + "id": "2151", + "name": "Vigr" + }, + { + "id": "2152", + "name": "Santiri" + }, + { + "id": "2153", + "name": "Saro" + }, + { + "id": "2154", + "name": "Gunslik", + "examine": "Proprietor of Gunslik's Assorted Items.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2155", + "name": "Wemund" + }, + { + "id": "2156", + "name": "Randivor" + }, + { + "id": "2157", + "name": "Hervi" + }, + { + "id": "2158", + "name": "Nolar", + "examine": "A crafty dwarf." + }, + { + "id": "2159", + "name": "Gulldamar" + }, + { + "id": "2160", + "name": "Tati", + "examine": "An old mining dwarf, now he sells pickaxes and generally acts grumpy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2161", + "name": "Agmundi" + }, + { + "id": "2162", + "name": "Vermundi" + }, + { + "id": "2163", + "name": "Banker", + "examine": "A rather personable banker lady.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2164", + "name": "Banker", + "examine": "A rather serious old fella.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2165", + "name": "Librarian", + "examine": "He takes care of the library and its many books.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2166", + "name": "Assistant" + }, + { + "id": "2167", + "name": "Customer", + "examine": "A customer looking for books.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2168", + "name": "Customer", + "examine": "Looks like a human traveler visiting the library.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2169", + "name": "Dromund" + }, + { + "id": "2170", + "name": "Rind the gardener", + "examine": "He tends to the plants in the palace garden.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2171", + "name": "Factory Manager", + "examine": "Looks after the factory.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2172", + "name": "Factory Worker", + "examine": "Works hard at whatever it is he does.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2173", + "name": "Factory Worker", + "examine": "Works hard at whatever it is he does.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2174", + "name": "Factory Worker", + "examine": "Works hard at whatever it is he does.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2175", + "name": "Factory Worker", + "examine": "Works hard at whatever it is he does.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2176", + "name": "Inn Keeper" + }, + { + "id": "2177", + "name": "Inn Keeper", + "examine": "A rich landlord, fat and jolly.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2178", + "name": "Barmaid", + "examine": "These Dwarf ladies are so attractive!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2179", + "name": "Barman" + }, + { + "id": "2180", + "name": "Cart conductor", + "examine": "He makes sure the carts don't run anyone over.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2181", + "name": "Cart conductor", + "examine": "He makes sure the carts don't run anyone over.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2182", + "name": "Cart conductor", + "examine": "He makes sure the carts don't run anyone over.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2183", + "name": "Cart conductor", + "examine": "He makes sure the carts don't run anyone over.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2184", + "name": "Cart conductor", + "examine": "He makes sure the carts don't run anyone over.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2185", + "name": "Cart conductor", + "examine": "Remember: don't drink and ride in mine carts.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2186", + "name": "Cart conductor", + "examine": "Keeps the line clear of traffic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2187", + "name": "Rowdy dwarf", + "examine": "A loud, drunk and generally obnoxious dwarf.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2188", + "name": "Hegir" + }, + { + "id": "2189", + "name": "Haera" + }, + { + "id": "2190", + "name": "Runvastr", + "examine": "A sad old dwarf living in a sad old home.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2191", + "name": "Sune", + "examine": "He seems to always be busy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2192", + "name": "Bentamir", + "examine": "This dwarf doesn't seem to be very well off.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2193", + "name": "Ulifed", + "examine": "A dwarf minding his own business.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2194", + "name": "Reinald" + }, + { + "id": "2195", + "name": "Karl", + "examine": "A short, merry guy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2196", + "name": "Gauss" + }, + { + "id": "2197", + "name": "Myndill" + }, + { + "id": "2198", + "name": "Kjut", + "examine": "His kebabs certainly smell delicious.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2199", + "name": "Tombar" + }, + { + "id": "2200", + "name": "Odmar" + }, + { + "id": "2201", + "name": "Audmann", + "examine": "He seems to be very well off.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2202", + "name": "Drunken Dwarf", + "examine": "He's had a fair bit to drink...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2203", + "name": "Drunken Dwarf", + "examine": "He's had a fair bit to drink...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2204", + "name": "Drunken Dwarf" + }, + { + "id": "2205", + "name": "Dwarven Boatman", + "examine": "You cannot see his ship, but presumably he has one.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2206", + "name": "Dwarven Boatman", + "examine": "You cannot see his ship, but presumably he has one.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2207", + "name": "Dwarven Miner", + "examine": "He carries a heavy load.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2208", + "name": "Dwarven Miner" + }, + { + "id": "2209", + "name": "Dwarven Miner" + }, + { + "id": "2210", + "name": "Dwarven Miner" + }, + { + "id": "2211", + "name": "Dwarven Miner" + }, + { + "id": "2212", + "name": "Dwarven Miner" + }, + { + "id": "2213", + "name": "Dwarven Miner" + }, + { + "id": "2214", + "name": "Dwarven Miner" + }, + { + "id": "2215", + "name": "Dwarven Miner" + }, + { + "id": "2216", + "name": "Dwarven Miner" + }, + { + "id": "2217", + "name": "Dwarven Miner" + }, + { + "id": "2218", + "name": "Dwarven Miner" + }, + { + "id": "2219", + "name": "Purple Pewter Director" + }, + { + "id": "2220", + "name": "Purple Pewter Director" + }, + { + "id": "2221", + "name": "Blue Opal Director" + }, + { + "id": "2222", + "name": "Yellow Fortune Director" + }, + { + "id": "2223", + "name": "Green Gemstone Director" + }, + { + "id": "2224", + "name": "White Chisel Director" + }, + { + "id": "2225", + "name": "Silver Cog Director" + }, + { + "id": "2226", + "name": "Brown Engine Director" + }, + { + "id": "2227", + "name": "Red Axe Director" + }, + { + "id": "2228", + "name": "Commander Veldaban" + }, + { + "id": "2229", + "name": "Red Axe Cat" + }, + { + "id": "2230", + "name": "Red Axe Cat" + }, + { + "id": "2231", + "name": "Black Guard Berserker" + }, + { + "id": "2232", + "name": "Black Guard Berserker", + "examine": "An elite member of the Black Guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2233", + "name": "Olivia" + }, + { + "id": "2234", + "name": "Master Farmer", + "examine": "A master at farming.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2235", + "name": "Master Farmer", + "examine": "A master at farming.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2236", + "name": "Market Guard", + "examine": "He guards the Draynor Market stalls from thieves.", + "attack_level": "30", + "combat_audio": "2547,1979,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "2237", + "name": "Gee", + "examine": "A local farmer. He may be able to provide some useful information.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2238", + "name": "Donie" + }, + { + "id": "2239", + "name": "Pig" + }, + { + "id": "2240", + "name": "Pig", + "examine": "There to help me make my bids.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2241", + "name": "Piglet", + "examine": "There to help me make my bids.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2242", + "name": "Piglet", + "examine": "Porcine.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2243", + "name": "Piglet", + "examine": "Bacon-in-training." + }, + { + "id": "2244", + "name": "Lumbridge Guide", + "examine": "He provides new players with useful information.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2245", + "name": "Khazard trooper", + "examine": "It's one of General Khazard's warriors.", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "401", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2246", + "name": "Khazard trooper", + "examine": "It's one of General Khazard's warriors.", + "attack_level": "32", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "429", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "8" + }, + { + "id": "2247", + "name": "Gnome troop", + "examine": "It's a tree gnome trooper.", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "3", + "melee_animation": "190", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2248", + "name": "Gnome troop", + "examine": "It's a tree gnome trooper.", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "3", + "melee_animation": "190", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2249", + "name": "Gnome", + "examine": "Like a mini man!", + "attack_level": "1", + "attack_speed": "4", + "combat_style": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "3", + "melee_animation": "190", + "range_level": "1", + "respawn_delay": "60", + "strength_level": "1" + }, + { + "id": "2250", + "name": "Gnome", + "examine": "Like a mini man!", + "agg_radius": "", + "aggressive": "", + "attack_level": "1", + "attack_speed": "4", + "combat_style": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "end_height": "", + "lifepoints": "2", + "melee_animation": "190", + "range_level": "1", + "respawn_delay": "60", + "strength_level": "1", + "weakness": "" + }, + { + "id": "2251", + "name": "Gnome", + "examine": "Like a mini man!", + "attack_level": "1", + "attack_speed": "4", + "combat_style": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "force_talk": "", + "lifepoints": "3", + "melee_animation": "190", + "range_level": "1", + "respawn_delay": "60", + "strength_level": "1" + }, + { + "id": "2252", + "name": "Crow" + }, + { + "id": "2253", + "name": "Wise Old Man", + "examine": "A venerable and rich sage." + }, + { + "id": "2254", + "name": "Bed" + }, + { + "id": "2255", + "name": "Thing under the bed" + }, + { + "id": "2256", + "name": "Paladin", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "66", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2257", + "name": "Mage of Zamorak" + }, + { + "id": "2259", + "name": "Mage of Zamorak" + }, + { + "id": "2260", + "name": "Mage of Zamorak" + }, + { + "id": "2262", + "name": "Dark mage", + "examine": "An initiate of Zamorak.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2263", + "name": "Abyssal leech", + "examine": "A blood-drinking denizen of the abyss.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "3", + "combat_audio": "232,231,230", + "death_animation": "2183", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "2181", + "range_animation": "0", + "range_level": "52", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "2264", + "name": "Abyssal guardian", + "examine": "It seems to have eyes in the back of its head...", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "6", + "death_animation": "2189", + "defence_animation": "2188", + "defence_level": "65", + "lifepoints": "50", + "magic_animation": "2186", + "magic_level": "57", + "melee_animation": "2186", + "range_animation": "2186", + "range_level": "135", + "safespot": null, + "slayer_exp": "0", + "strength_level": "96", + "weakness": "3" + }, + { + "id": "2265", + "name": "Abyssal walker", + "examine": "Apparently walks the abyss.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "5", + "combat_audio": "233,235,234", + "death_animation": "2194", + "defence_animation": "2193", + "defence_level": "55", + "lifepoints": "95", + "magic_animation": "2192", + "melee_animation": "2192", + "range_animation": "2192", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "116", + "weakness": "8" + }, + { + "id": "2266", + "name": "Brian O'Richard" + }, + { + "id": "2267", + "name": "Rogue Guard", + "examine": "Sparkles the Tinsel Snake", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2268", + "name": "Rogue Guard" + }, + { + "id": "2269", + "name": "Rogue Guard", + "examine": "A snowman armed with a holly bow.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2270", + "name": "Martin Thwait" + }, + { + "id": "2271", + "name": "Emerald Benedict", + "examine": "A snowman armed with an ice sword.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2272", + "name": "Spin Blades", + "examine": "A snowman armed with a winter staff.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2273", + "name": "Spin Blades" + }, + { + "id": "2274", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2275", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2276", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2277", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2278", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2279", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2280", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2281", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2282", + "name": "Sir Spishyus", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2283", + "name": "Lady Table", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2284", + "name": "Sir Kuam Ferentse", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2285", + "name": "Sir Leye", + "examine": "A warrior blessed by Saradomin.", + "aggressive": "true", + "attack_level": "18", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "15", + "lifepoints": "21", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "18" + }, + { + "id": "2286", + "name": "Sir Tinley", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2287", + "name": "Sir Ren Itchood", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2288", + "name": "Miss Cheevers", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2289", + "name": "Ms. Hynn Terprett", + "examine": "An observer for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2290", + "name": "Sir Tiffy Cashien", + "examine": "Head of recruitment for the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2291", + "name": "Rug Merchant", + "examine": "A carpet merchant.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2292", + "name": "Rug Merchant", + "examine": "A carpet merchant.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2293", + "name": "Rug Merchant", + "examine": "A man who deals in rugs.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2294", + "name": "Rug Merchant", + "examine": "A man who deals in rugs.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2295", + "name": "Rug Merchant" + }, + { + "id": "2297", + "name": "Rug Merchant" + }, + { + "id": "2299", + "name": "Rug Station Attendant" + }, + { + "id": "2301", + "name": "Monkey", + "examine": "Perhaps our oldest relatives.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2302", + "name": "Sarah" + }, + { + "id": "2304", + "name": "Sarah", + "examine": "She sells farming equipment." + }, + { + "id": "2305", + "name": "Vanessa" + }, + { + "id": "2306", + "name": "Richard" + }, + { + "id": "2307", + "name": "Alice" + }, + { + "id": "2308", + "name": "Capt' Arnav" + }, + { + "id": "2309", + "name": "null", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_animation": "", + "defence_level": "1", + "range_level": "1", + "safespot": "null" + }, + { + "id": "2310", + "name": "Cow calf", + "examine": "Young, but still beefy.", + "attack_level": "2", + "attack_speed": "5", + "combat_audio": "366,368,367", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "2", + "lifepoints": "6", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", + "strength_level": "2", + "weakness": "8" + }, + { + "id": "2311", + "name": "Sheepdog", + "examine": "Farmer/sheep liaison officer. Go on - give the dog a bone!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2312", + "name": "Rooster", + "examine": "He rules the", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2313", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2314", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2315", + "name": "Chicken", + "examine": "Yep. Definitely a chicken.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "355,357,356", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "3", + "magic_animation": "5387", + "melee_animation": "5387", + "range_animation": "5387", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2316", + "name": "Pig", + "examine": "Swine.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2317", + "name": "Pig", + "examine": "Porker.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2318", + "name": "Piglet", + "examine": "Hog.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2319", + "name": "Piglet", + "examine": "Porcine.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2320", + "name": "Piglet", + "examine": "He has a certain bovine aroma.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2321", + "name": "Blandebir", + "examine": "An expert on the brewing of ales and cider.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2322", + "name": "Metarialus", + "examine": "In his former life an expert brewer." + }, + { + "id": "2323", + "name": "Elstan", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2324", + "name": "Dantaera", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2325", + "name": "Kragen", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2326", + "name": "Lyra", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2327", + "name": "Francis", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2328", + "name": "Wizard Cromperty", + "examine": "The hat is a dead give away." + }, + { + "id": "2329", + "name": "Muncher", + "examine": "Only the Grim Reaper would have a pet like this.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2330", + "name": "Garth", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2331", + "name": "Ellena", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2332", + "name": "Selena", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2333", + "name": "Vasquen", + "examine": "Perhaps this farmer might look after your crops for you.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2334", + "name": "Rhonen", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2335", + "name": "Dreven", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2336", + "name": "Taria", + "examine": "Perhaps this gardener might look after your crops for you.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2337", + "name": "Rhazien", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2338", + "name": "Torrell", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2339", + "name": "Alain", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2340", + "name": "Heskel", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2341", + "name": "Treznor", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2342", + "name": "Fayeth", + "examine": "Perhaps this gardener might look after your crops for you.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2343", + "name": "Bolongo", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2344", + "name": "Gileth", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2345", + "name": "Sick-looking sheep (1)" + }, + { + "id": "2346", + "name": "Sick-looking sheep (2)" + }, + { + "id": "2347", + "name": "Sick-looking sheep (3)" + }, + { + "id": "2348", + "name": "Sick-looking sheep (4)" + }, + { + "id": "2349", + "name": "Mourner" + }, + { + "id": "2350", + "name": "Mourner" + }, + { + "id": "2351", + "name": "Mourner" + }, + { + "id": "2352", + "name": "Eudav" + }, + { + "id": "2353", + "name": "Oronwen" + }, + { + "id": "2354", + "name": "Banker", + "examine": "He can look after my money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2355", + "name": "Banker", + "examine": "She can look after my money.", + "attack_level": "1", + "combat_style": "2", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "476", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2356", + "name": "Dalldav" + }, + { + "id": "2357", + "name": "Gethin" + }, + { + "id": "2358", + "name": "Arianwyn" + }, + { + "id": "2359", + "name": "Elf warrior", + "examine": "I don't wanna be at the wrong end of that pike.", + "attack_level": "60", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "425,427,426", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "2360", + "name": "Elf warrior", + "examine": "I don't wanna be at the wrong end of that pike.", + "attack_level": "60", + "attack_speed": "5", + "clue_level": "2", + "combat_audio": "425,427,426", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "2361", + "name": "Elf warrior", + "examine": "He looks pretty handy with that bow.", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "428", + "projectile": "249", + "range_animation": "426", + "range_level": "64", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "250", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "2362", + "name": "Elf warrior", + "examine": "He looks pretty handy with that bow.", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "428", + "projectile": "249", + "range_animation": "426", + "range_level": "64", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "250", + "strength_level": "1", + "weakness": "2" + }, + { + "id": "2363", + "name": "Goreu" + }, + { + "id": "2364", + "name": "Ysgawyn" + }, + { + "id": "2365", + "name": "Arvel" + }, + { + "id": "2366", + "name": "Mawrth" + }, + { + "id": "2367", + "name": "Kelyn" + }, + { + "id": "2368", + "name": "Eoin" + }, + { + "id": "2369", + "name": "Iona" + }, + { + "id": "2370", + "name": "Gnome" + }, + { + "id": "2372", + "name": "Head mourner", + "examine": "A Mourner showing his true identity.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "2373", + "name": "Mourner", + "examine": "A mourner, or plague healer.", + "aggressive": "true", + "attack_level": "61", + "attack_speed": "4", + "death_animation": "836", + "defence_animation": "", + "defence_level": "80", + "lifepoints": "87", + "magic_animation": "", + "melee_animation": "428", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "61", + "weakness": "" + }, + { + "id": "2374", + "name": "Mourner", + "examine": "A Mourner, or plague healer." + }, + { + "id": "2375", + "name": "Eluned" + }, + { + "id": "2377", + "name": "Sick-looking sheep (1)" + }, + { + "id": "2378", + "name": "Sick-looking sheep (2)" + }, + { + "id": "2379", + "name": "Sick-looking sheep (3)" + }, + { + "id": "2380", + "name": "Sick-looking sheep (4)" + }, + { + "id": "2381", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2382", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2383", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2384", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2385", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2386", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2387", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2388", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2389", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2390", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2391", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2392", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2393", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2394", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2395", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2396", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2397", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2398", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2399", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2400", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2401", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2402", + "name": "Mysterious ghost", + "examine": "Seems to flitter in and out of existence...", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2403", + "name": "Cart conductor" + }, + { + "id": "2410", + "name": "Red Axe Director" + }, + { + "id": "2411", + "name": "Red Axe Director" + }, + { + "id": "2412", + "name": "Red Axe Henchman" + }, + { + "id": "2413", + "name": "Red Axe Henchman" + }, + { + "id": "2414", + "name": "Red Axe Henchman" + }, + { + "id": "2415", + "name": "Colonel Grimsson" + }, + { + "id": "2416", + "name": "Colonel Grimsson" + }, + { + "id": "2417", + "name": "Ogre shaman" + }, + { + "id": "2418", + "name": "Ogre shaman" + }, + { + "id": "2419", + "name": "Grunsh" + }, + { + "id": "2420", + "name": "Gnome emissary" + }, + { + "id": "2421", + "name": "Gnome companion" + }, + { + "id": "2422", + "name": "Gnome companion" + }, + { + "id": "2423", + "name": "Chaos dwarf", + "examine": "A dwarf gone bad.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "61", + "strength_level": "1", + "weakness": "6" + }, + { + "id": "2424", + "name": "Gunslik" + }, + { + "id": "2425", + "name": "Nolar" + }, + { + "id": "2426", + "name": "Factory Worker" + }, + { + "id": "2427", + "name": "Cart conductor" + }, + { + "id": "2428", + "name": "Gauss" + }, + { + "id": "2429", + "name": "Drunken Dwarf" + }, + { + "id": "2430", + "name": "Rowdy dwarf" + }, + { + "id": "2431", + "name": "Ulifed" + }, + { + "id": "2432", + "name": "Red Axe Henchman" + }, + { + "id": "2433", + "name": "Red Axe Henchman" + }, + { + "id": "2434", + "name": "Ogre shaman" + }, + { + "id": "2435", + "name": "Jarvald" + }, + { + "id": "2436", + "name": "Jarvald", + "attack_level": "10", + "death_animation": "9230", + "defence_animation": "9231", + "defence_level": "10", + "lifepoints": "10", + "melee_animation": "9232", + "range_level": "1", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2437", + "name": "Jarvald" + }, + { + "id": "2438", + "name": "Jarvald" + }, + { + "id": "2439", + "name": "Askeladden", + "examine": "Looks like a wanna be Fremennik.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2440", + "name": "Door-support" + }, + { + "id": "2441", + "name": "Door" + }, + { + "id": "2442", + "name": "Door" + }, + { + "id": "2443", + "name": "Door-support", + "examine": "This support is propping the door closed.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "0", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2444", + "name": "Door" + }, + { + "id": "2445", + "name": "Door" + }, + { + "id": "2446", + "name": "Door-support" + }, + { + "id": "2447", + "name": "Door" + }, + { + "id": "2448", + "name": "Door" + }, + { + "id": "2449", + "name": "Egg" + }, + { + "id": "2450", + "name": "Egg" + }, + { + "id": "2451", + "name": "Egg" + }, + { + "id": "2452", + "name": "Giant Rock Crab", + "examine": "No one likes crabs... especially really big ones!", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,225,200,175,-10,250,0,0,0,0,0", + "combat_audio": "717,723,722", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "200", + "lifepoints": "180", + "magic_animation": "0", + "melee_animation": "2368", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "80", + "weakness": "9" + }, + { + "id": "2453", + "name": "Boulder", + "examine": "Heavy rock!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "240", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2454", + "name": "Dagannoth spawn", + "examine": "A teeny-tiny horror from the ocean depths...", + "aggressive": "true", + "attack_level": "47", + "death_animation": "1342", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "1341", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "9" + }, + { + "id": "2455", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "clue_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "71", + "lifepoints": "120", + "melee_animation": "1343", + "projectile": "294", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "120", + "strength_level": "70" + }, + { + "id": "2456", + "name": "Dagannoth", + "examine": "A horror from the ocean depths...", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "clue_level": "1", + "combat_style": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "50", + "lifepoints": "70", + "melee_animation": "1343", + "projectile": "294", + "range_level": "70", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "0", + "strength_level": "70" + }, + { + "id": "2457", + "name": "Wallasalki", + "examine": "A fearsome magical creature from the deep.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,100,150,175,250,-10,0,0,0,0,0", + "combat_audio": "1077,1079,1078", + "combat_style": "2", + "death_animation": "2367", + "defence_animation": "2366", + "defence_level": "80", + "lifepoints": "120", + "magic_animation": "2365", + "magic_level": "100", + "melee_animation": "2365", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "spell_id": "48", + "strength_level": "1" + }, + { + "id": "2458", + "name": "Freaky Forester" + }, + { + "id": "2459", + "name": "Pheasant", + "examine": "A brightly coloured game bird.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "690,692,691", + "death_animation": "2373", + "defence_animation": "2371", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2372", + "melee_animation": "2372", + "range_animation": "2372", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2460", + "name": "Pheasant", + "examine": "A brightly coloured game bird.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "690,692,691", + "death_animation": "2373", + "defence_animation": "2371", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2372", + "melee_animation": "2372", + "range_animation": "2372", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2461", + "name": "Pheasant", + "examine": "A brightly coloured game bird.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "690,692,691", + "death_animation": "2373", + "defence_animation": "2371", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2372", + "melee_animation": "2372", + "range_animation": "2372", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2462", + "name": "Pheasant", + "examine": "A brightly coloured game bird.", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "690,692,691", + "death_animation": "2373", + "defence_animation": "2371", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2372", + "melee_animation": "2372", + "range_animation": "2372", + "range_level": "1", + "respawn_delay": "18", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2463", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "5", + "bonuses": "25,85,105,75,103,85,65,0,0,0,0,0,0,0,0", + "combat_audio": "2288,357,356", + "combat_style": "2", + "death_animation": "2301", + "defence_animation": "2300", + "defence_level": "20", + "lifepoints": "19", + "magic_animation": "2302", + "magic_level": "5", + "melee_animation": "2302", + "projectile": "337", + "range_animation": "2302", + "range_level": "5", + "respawn_delay": "25", + "safespot": null, + "strength_level": "5" + }, + { + "id": "2464", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "10", + "bonuses": "35,105,125,95,128,105,85,0,0,0,0,0,0,0,0", + "combat_audio": "2288,357,356", + "combat_style": "2", + "death_animation": "2301", + "defence_animation": "2300", + "defence_level": "40", + "lifepoints": "40", + "magic_animation": "2302", + "magic_level": "10", + "melee_animation": "2302", + "projectile": "337", + "range_animation": "2302", + "range_level": "10", + "respawn_delay": "25", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2465", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "15", + "bonuses": "35,185,185,155,188,125,165,0,0,0,0,0,0,0,0", + "combat_audio": "2288,357,356", + "combat_style": "2", + "death_animation": "2301", + "defence_animation": "2300", + "defence_level": "50", + "lifepoints": "60", + "magic_animation": "2302", + "magic_level": "15", + "melee_animation": "2302", + "projectile": "337", + "range_animation": "2302", + "range_level": "15", + "respawn_delay": "25", + "safespot": null, + "strength_level": "15" + }, + { + "id": "2466", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "45", + "bonuses": "45,235,235,205,238,145,165,0,0,0,0,0,0,0,0", + "combat_audio": "2288,357,356", + "combat_style": "2", + "death_animation": "2301", + "defence_animation": "2300", + "defence_level": "60", + "lifepoints": "80", + "magic_animation": "2302", + "magic_level": "25", + "melee_animation": "2302", + "projectile": "337", + "range_animation": "2302", + "range_level": "45", + "respawn_delay": "25", + "safespot": null, + "strength_level": "45" + }, + { + "id": "2467", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "45", + "bonuses": "45,285,285,255,288,145,165,0,0,0,0,0,0,0,0", + "combat_audio": "2288,357,356", + "combat_style": "2", + "death_animation": "2301", + "defence_animation": "2300", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "2302", + "magic_level": "35", + "melee_animation": "2302", + "projectile": "337", + "range_animation": "2302", + "range_level": "45", + "respawn_delay": "25", + "safespot": null, + "strength_level": "45" + }, + { + "id": "2468", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "45", + "bonuses": "45,285,285,255,288,145,165,0,0,0,0,0,0,0,0", + "combat_audio": "2288,357,356", + "combat_style": "2", + "death_animation": "2301", + "defence_animation": "2300", + "defence_level": "90", + "lifepoints": "120", + "magic_animation": "2302", + "magic_level": "45", + "melee_animation": "2302", + "projectile": "337", + "range_animation": "2302", + "range_level": "45", + "respawn_delay": "25", + "safespot": null, + "strength_level": "45", + "weakness": "9" + }, + { + "id": "2469", + "name": "Frog" + }, + { + "id": "2470", + "name": "Frog" + }, + { + "id": "2471", + "name": "Frog" + }, + { + "id": "2472", + "name": "Frog" + }, + { + "id": "2473", + "name": "Frog" + }, + { + "id": "2474", + "name": "Frog prince" + }, + { + "id": "2475", + "name": "Frog princess" + }, + { + "id": "2476", + "name": "Rick Turpentine", + "examine": "A Retired Highwayman", + "attack_level": "8", + "attack_speed": "5", + "bonuses": "30,20,10,20,20,30,30,10,20,10,30,30,20,30,20", + "combat_audio": "2695,513,512", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "8", + "lifepoints": "10", + "magic_animation": "4230", + "magic_level": "30", + "melee_animation": "4230", + "prj_height": "", + "projectile": "27", + "range_animation": "4230", + "range_level": "20", + "safespot": null, + "strength_level": "8" + }, + { + "id": "2477", + "name": "Quiz Master", + "examine": "Apparently a master of quizzes!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2478", + "name": "Evil Bob" + }, + { + "id": "2479", + "name": "Evil Bob", + "examine": "Hey, it's Bob the cat! Or... is it?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2480", + "name": "Servant" + }, + { + "id": "2481", + "name": "Servant", + "examine": "Servant of Evil Bob.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2482", + "name": "Giant bat", + "examine": "Annoying flappy thing.", + "attack_level": "22", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "combat_audio": "292,294,293", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "32", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "8", + "strength_level": "22" + }, + { + "id": "2483", + "name": "Bush snake" + }, + { + "id": "2489", + "name": "Bush snake", + "examine": "A slithering serpent that likes to hide in the bush.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "7", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "278", + "defence_animation": "276", + "defence_level": "50", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "275", + "poison_amount": "55", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "1" + }, + { + "id": "2490", + "name": "Bush snake", + "examine": "A slithering serpent that likes to hide in the bush.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "7", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "278", + "defence_animation": "276", + "defence_level": "50", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "275", + "poison_amount": "55", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25" + }, + { + "id": "2491", + "name": "Jungle spider", + "examine": "", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "5327", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2492", + "name": "Jungle spider", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "5327", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2493", + "name": "Large mosquito", + "examine": "A flying bloodsucker.", + "attack_level": "1", + "death_animation": "2398", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "2397", + "range_animation": "0", + "range_level": "63", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "2494", + "name": "Mosquito swarm", + "examine": "A swarm of three highly agile mosquitoes.", + "attack_level": "1", + "death_animation": "2398", + "defence_animation": "0", + "defence_level": "66", + "lifepoints": "94", + "magic_animation": "0", + "melee_animation": "2397", + "range_animation": "0", + "range_level": "66", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "2495", + "name": "Mosquito swarm", + "examine": "A swarm of five highly agile mosquitoes.", + "attack_level": "1", + "death_animation": "2398", + "defence_animation": "0", + "defence_level": "68", + "lifepoints": "97", + "magic_animation": "0", + "melee_animation": "2397", + "range_animation": "0", + "range_level": "68", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "2496", + "name": "Tribesman", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2497", + "name": "Tribesman", + "examine": "A vicious warrior.", + "aggressive": "true", + "attack_level": "23", + "attack_speed": "4", + "bonuses": "8,8,8,0,0,4,6,6,0,0,0,5,0,0,0", + "clue_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "39", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "428", + "poison_amount": "55", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "27", + "weakness": "9" + }, + { + "id": "2498", + "name": "Broodoo victim" + }, + { + "id": "2499", + "name": "Broodoo victim", + "examine": "An undead victim of some ancient murderous ritual; his skin appears deep green.", + "aggressive": "true", + "attack_level": "45", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "45", + "weakness": "9" + }, + { + "id": "2500", + "name": "Broodoo victim" + }, + { + "id": "2501", + "name": "Broodoo victim", + "examine": "An undead victim of some ancient murderous ritual; his skin appears pale yellow.", + "aggressive": "true", + "attack_level": "43", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "43", + "weakness": "9" + }, + { + "id": "2502", + "name": "Broodoo victim" + }, + { + "id": "2503", + "name": "Broodoo victim", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "100", + "melee_animation": "810", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2504", + "name": "Sharimika" + }, + { + "id": "2505", + "name": "Sharimika", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2506", + "name": "Sharimika", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2507", + "name": "Mamma Bufetta" + }, + { + "id": "2508", + "name": "Mamma Bufetta", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2509", + "name": "Mamma Bufetta", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2510", + "name": "Layleen" + }, + { + "id": "2511", + "name": "Layleen", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2512", + "name": "Layleen", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2513", + "name": "Karaday" + }, + { + "id": "2514", + "name": "Karaday", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2515", + "name": "Karaday", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2516", + "name": "Safta Doc" + }, + { + "id": "2517", + "name": "Safta Doc", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2518", + "name": "Safta Doc", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2519", + "name": "Gabooty" + }, + { + "id": "2520", + "name": "Gabooty", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2521", + "name": "Gabooty", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2522", + "name": "Fanellaman" + }, + { + "id": "2523", + "name": "Fanellaman", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2524", + "name": "Fanellaman", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2525", + "name": "Jagbakoba" + }, + { + "id": "2526", + "name": "Jagbakoba", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2527", + "name": "Jagbakoba", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2528", + "name": "Murcaily" + }, + { + "id": "2529", + "name": "Murcaily", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2530", + "name": "Murcaily", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2531", + "name": "Rionasta" + }, + { + "id": "2532", + "name": "Rionasta", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2533", + "name": "Rionasta", + "examine": "A native of Tai Bwo Wannai." + }, + { + "id": "2534", + "name": "Mahogany" + }, + { + "id": "2535", + "name": "Teak" + }, + { + "id": "2536", + "name": "Niles" + }, + { + "id": "2537", + "name": "Miles" + }, + { + "id": "2538", + "name": "Giles" + }, + { + "id": "2539", + "name": "Cap'n Hand", + "examine": "He used to swashbuckle his away across the seven seas.", + "attack_level": "30", + "attack_speed": "5", + "bonuses": "10,30,20,30,10,20,15,30,10,30,15,20,20,0,0", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "4230", + "magic_level": "20", + "melee_animation": "4230", + "range_animation": "4230", + "range_level": "30", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2540", + "name": "Dr Jekyll" + }, + { + "id": "2541", + "name": "Mr Hyde" + }, + { + "id": "2542", + "name": "Mr Hyde" + }, + { + "id": "2543", + "name": "Mr Hyde" + }, + { + "id": "2544", + "name": "Mr Hyde" + }, + { + "id": "2545", + "name": "Mr Hyde" + }, + { + "id": "2546", + "name": "Mr Hyde" + }, + { + "id": "2547", + "name": "Chaos druid", + "examine": "A crazy, evil druid.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "12", + "end_gfx": "107", + "lifepoints": "20", + "magic_animation": "422", + "magic_level": "10", + "melee_animation": "422", + "projectile": "106", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "start_gfx": "105", + "strength_level": "8", + "weakness": "3" + }, + { + "id": "2548", + "name": "Blackjack seller" + }, + { + "id": "2549", + "name": "Ali the dyer", + "examine": "A colourful character.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2550", + "name": "Dwarven Miner" + }, + { + "id": "2551", + "name": "Dwarven Miner" + }, + { + "id": "2552", + "name": "Dwarven Miner" + }, + { + "id": "2553", + "name": "Blast Furnace Foreman", + "examine": "Looks after the blast furnace.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2554", + "name": "Tin ore" + }, + { + "id": "2555", + "name": "Copper ore" + }, + { + "id": "2556", + "name": "Iron ore" + }, + { + "id": "2557", + "name": "Mithril ore" + }, + { + "id": "2558", + "name": "Adamantite ore" + }, + { + "id": "2559", + "name": "Runite ore" + }, + { + "id": "2560", + "name": "Silver ore" + }, + { + "id": "2561", + "name": "Gold ore" + }, + { + "id": "2562", + "name": "Coal" + }, + { + "id": "2563", + "name": "Perfect gold ore" + }, + { + "id": "2564", + "name": "Ordan", + "examine": "He smells of rock dust." + }, + { + "id": "2565", + "name": "Jorzik", + "examine": "He buys stuff." + }, + { + "id": "2566", + "name": "Wise Old Man" + }, + { + "id": "2567", + "name": "Wise Old Man" + }, + { + "id": "2568", + "name": "Banker" + }, + { + "id": "2569", + "name": "Banker" + }, + { + "id": "2570", + "name": "Banker" + }, + { + "id": "2571", + "name": "Market Guard", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2572", + "name": "Olivia", + "examine": "She is a seed merchant." + }, + { + "id": "2573", + "name": "Pillory Guard" + }, + { + "id": "2574", + "name": "Bank guard", + "examine": "He's guarding the bank.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2575", + "name": "Purepker895" + }, + { + "id": "2576", + "name": "Qutiedoll" + }, + { + "id": "2577", + "name": "1337sp34kr" + }, + { + "id": "2578", + "name": "Elfinlocks" + }, + { + "id": "2579", + "name": "Cool Mom227" + }, + { + "id": "2580", + "name": "Bernald", + "examine": "Looks after the Burthorpe vinery." + }, + { + "id": "2581", + "name": "Ellamaria" + }, + { + "id": "2582", + "name": "Trolley" + }, + { + "id": "2583", + "name": "Trolley" + }, + { + "id": "2584", + "name": "Trolley" + }, + { + "id": "2585", + "name": "Billy, a guard of Falador" + }, + { + "id": "2587", + "name": "Bob, another guard of Falador" + }, + { + "id": "2588", + "name": "Brother Althric", + "examine": "A holy man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2589", + "name": "PKMaster0036" + }, + { + "id": "2590", + "name": "King Roald" + }, + { + "id": "2591", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2592", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2593", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2594", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2595", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2596", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2597", + "name": "TzHaar-Mej", + "examine": "Looks like some kind of mystic.", + "attack_level": "70", + "attack_speed": "5", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "end_gfx": "1621", + "lifepoints": "100", + "magic_animation": "9260", + "magic_level": "70", + "melee_animation": "9260", + "projectile": "1617", + "range_animation": "9260", + "range_level": "70", + "safespot": null, + "start_gfx": "1618", + "strength_level": "70" + }, + { + "id": "2598", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "70", + "safespot": null, + "strength_level": "50" + }, + { + "id": "2599", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "70", + "safespot": null, + "strength_level": "50" + }, + { + "id": "2600", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "70", + "safespot": null, + "strength_level": "50" + }, + { + "id": "2601", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "70", + "safespot": null, + "strength_level": "50" + }, + { + "id": "2602", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "70", + "safespot": null, + "strength_level": "50" + }, + { + "id": "2603", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "70", + "safespot": null, + "strength_level": "50" + }, + { + "id": "2604", + "name": "TzHaar-Xil", + "examine": "Doesn't look very social.", + "attack_level": "70", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2605", + "name": "TzHaar-Xil", + "examine": "Doesn't look very social.", + "attack_level": "70", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2606", + "name": "TzHaar-Xil", + "examine": "Doesn't look very social.", + "attack_level": "70", + "bonuses": "50,30,80,56,80,80,100,60,50,45,45,0,0,0,0", + "combat_style": "1", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "projectile": "442", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2607", + "name": "TzHaar-Xil", + "examine": "Doesn't look very social.", + "attack_level": "70", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2608", + "name": "TzHaar-Xil", + "examine": "Doesn't look very social.", + "attack_level": "70", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2609", + "name": "TzHaar-Xil", + "examine": "Doesn't look very social.", + "attack_level": "70", + "bonuses": "50,30,80,56,80,80,100,60,50,45,45,0,0,0,0", + "combat_style": "1", + "death_animation": "9291", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "projectile": "442", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "slayer_exp": "0", + "strength_level": "70" + }, + { + "id": "2610", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2611", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2612", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2613", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2614", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2615", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2616", + "name": "TzHaar-Ket", + "examine": "Must be a guard or something.", + "attack_level": "70", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "70", + "lifepoints": "140", + "magic_animation": "9345", + "magic_level": "70", + "melee_animation": "9345", + "range_animation": "9345", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "2617", + "name": "TzHaar-Mej-Jal", + "examine": "Another one of those mystic-types." + }, + { + "id": "2618", + "name": "TzHaar-Mej-Kah", + "examine": "Another one of those mystic-types." + }, + { + "id": "2619", + "name": "TzHaar-Ket-Zuh", + "examine": "Maybe it'll guard my possessions." + }, + { + "id": "2620", + "name": "TzHaar-Hur-Tel", + "examine": "Wonder what it's making." + }, + { + "id": "2621", + "name": "Olaf Hardson", + "examine": "A soggy, smelly Fremennik." + }, + { + "id": "2622", + "name": "TzHaar-Hur-Lek", + "examine": "Wonder what it's making." + }, + { + "id": "2623", + "name": "TzHaar-Mej-Roh", + "examine": "Another one of those mystic-types." + }, + { + "id": "2624", + "name": "TzHaar-Ket" + }, + { + "id": "2625", + "name": "TzHaar-Ket" + }, + { + "id": "2626", + "name": "Rocks" + }, + { + "id": "2627", + "name": "Tz-Kih", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "7", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2628", + "name": "Tz-Kih", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "7", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2629", + "name": "Tz-Kek", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "defence_level": "1", + "lifepoints": "20", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2630", + "name": "Tz-Kek", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "defence_level": "1", + "lifepoints": "20", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2631", + "name": "Tok-Xil", + "examine": "The Tok-Xil fires deadly spines out of its arm", + "aggressive": "true", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "80", + "lifepoints": "114", + "magic_animation": "0", + "range_animation": "0", + "range_level": "80", + "safespot": null, + "strength_level": "1", + "weakness": "10" + }, + { + "id": "2632", + "name": "Tok-Xil" + }, + { + "id": "2633", + "name": "Wise Old Man" + }, + { + "id": "2634", + "name": "Miss Schism", + "examine": "A busy-body who loves a bit of gossip.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2635", + "name": "Bob" + }, + { + "id": "2636", + "name": "Bob" + }, + { + "id": "2637", + "name": "Sphinx" + }, + { + "id": "2638", + "name": "Neite" + }, + { + "id": "2639", + "name": "Robert the Strong" + }, + { + "id": "2640", + "name": "Odysseus" + }, + { + "id": "2641", + "name": "Dragonkin", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2642", + "name": "King Black Dragon" + }, + { + "id": "2643", + "name": "R4ng3rNo0b889" + }, + { + "id": "2644", + "name": "Love Cats" + }, + { + "id": "2645", + "name": "Love Cats" + }, + { + "id": "2646", + "name": "Neite" + }, + { + "id": "2647", + "name": "Bob" + }, + { + "id": "2648", + "name": "Beite" + }, + { + "id": "2649", + "name": "Gnome" + }, + { + "id": "2650", + "name": "Gnome" + }, + { + "id": "2651", + "name": "Odysseus" + }, + { + "id": "2652", + "name": "Neite" + }, + { + "id": "2654", + "name": "Unferth" + }, + { + "id": "2655", + "name": "Unferth", + "examine": "Nice but dim." + }, + { + "id": "2656", + "name": "Unferth" + }, + { + "id": "2657", + "name": "Unferth" + }, + { + "id": "2658", + "name": "Unferth" + }, + { + "id": "2659", + "name": "Unferth" + }, + { + "id": "2660", + "name": "Reldo", + "examine": "Reldo the librarian." + }, + { + "id": "2661", + "name": "Reldo" + }, + { + "id": "2662", + "name": "Lazy cat" + }, + { + "id": "2663", + "name": "Lazy cat" + }, + { + "id": "2664", + "name": "Lazy cat" + }, + { + "id": "2665", + "name": "Lazy cat" + }, + { + "id": "2666", + "name": "Lazy cat" + }, + { + "id": "2667", + "name": "Lazy cat" + }, + { + "id": "2668", + "name": "Wily cat" + }, + { + "id": "2669", + "name": "Wily cat" + }, + { + "id": "2670", + "name": "Wily cat" + }, + { + "id": "2671", + "name": "Wily cat" + }, + { + "id": "2672", + "name": "Wily cat" + }, + { + "id": "2673", + "name": "Wily cat" + }, + { + "id": "2674", + "name": "Thief", + "examine": "Known for his light-fingered qualities.", + "attack_level": "10", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "10", + "weakness": "9" + }, + { + "id": "2675", + "name": "Man", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2676", + "name": "Make-over Mage" + }, + { + "id": "2677", + "name": "Highwayman", + "examine": "He holds up passers by.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "8", + "lifepoints": "13", + "magic_animation": "799", + "melee_animation": "799", + "range_animation": "799", + "range_level": "1", + "safespot": null, + "strength_level": "8", + "weakness": "7" + }, + { + "id": "2678", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2679", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2680", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2681", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "2682", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "3102,3104,3103", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2683", + "name": "Hengel", + "examine": "A citizen of Rimmington.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2684", + "name": "Anja", + "examine": "A citizen of Rimmington.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2685", + "name": "Hobgoblin", + "examine": "An ugly smelly creature.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "469,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "1", + "lifepoints": "29", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "20", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2686", + "name": "Hobgoblin", + "examine": "An ugly smelly creature.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "469,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "1", + "lifepoints": "29", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "20", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2687", + "name": "Hobgoblin", + "examine": "An ugly smelly creature.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "469,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "1", + "lifepoints": "29", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "20", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2688", + "name": "Hobgoblin", + "examine": "An ugly smelly creature, with a spear.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "3520,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "1", + "lifepoints": "29", + "magic_animation": "163", + "melee_animation": "163", + "range_animation": "163", + "range_level": "20", + "safespot": null, + "strength_level": "10" + }, + { + "id": "2689", + "name": "Frog", + "examine": "Didn't the mage say this procedure was totally safe?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2690", + "name": "Jack Seagull", + "examine": "A salty seafarer. Needs a wash.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2691", + "name": "Longbow Ben", + "examine": "A strange man with a strange name. Probably a strange past, too.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2692", + "name": "Ahab", + "examine": "So what can one do with a drunken sailor?" + }, + { + "id": "2693", + "name": "Duck", + "examine": "She quackers.", + "attack_level": "1", + "death_animation": "3468", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "water_npc": "true", + "weakness": "8" + }, + { + "id": "2694", + "name": "Duckling", + "examine": "Mini quackers.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "3468", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "water_npc": "true", + "weakness": "8" + }, + { + "id": "2695", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2696", + "name": "Thief", + "examine": "Known for his light-fingered qualities.", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "8" + }, + { + "id": "2697", + "name": "Mugger", + "examine": "He doesn't look so happy now he's in jail.", + "aggressive": "true", + "attack_level": "11", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "8" + }, + { + "id": "2698", + "name": "Black knight", + "examine": "A dark-hearted knight.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "42", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "24", + "weakness": "7" + }, + { + "id": "2699", + "name": "Guard", + "examine": "He's guarding the prison.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "2700", + "name": "Guard", + "examine": "A prison guard.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "2701", + "name": "Guard", + "examine": "A prison guard.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "2702", + "name": "Guard", + "examine": "A prison guard.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "2703", + "name": "Guard", + "examine": "A prison guard.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "2704", + "name": "Guard", + "examine": "He's asleep.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2705", + "name": "Guard", + "examine": "Keeping an eye out for suspicious activity.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2706", + "name": "Crab", + "examine": "No one likes crabs...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2707", + "name": "Seagull", + "examine": "A sea bird.", + "attack_level": "1", + "combat_audio": "309,311,310", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2708", + "name": "Seagull" + }, + { + "id": "2709", + "name": "Fire wizard", + "examine": "Caution: HOT!", + "attack_level": "1", + "combat_style": "2", + "death_animation": "2553", + "defence_animation": "0", + "defence_level": "18", + "end_gfx": "101", + "lifepoints": "25", + "magic_animation": "711", + "magic_level": "18", + "melee_animation": "414", + "projectile": "100", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "99", + "start_height": "80", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "2710", + "name": "Water wizard", + "examine": "Hydro-power!", + "attack_level": "1", + "combat_style": "2", + "death_animation": "2553", + "defence_animation": "0", + "defence_level": "14", + "lifepoints": "20", + "magic_animation": "711", + "magic_level": "14", + "melee_animation": "414", + "projectile": "94", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "93", + "start_height": "80", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "2711", + "name": "Earth wizard", + "examine": "His hands are covered in mud, at least.", + "attack_level": "1", + "combat_style": "2", + "death_animation": "2553", + "defence_animation": "0", + "defence_level": "16", + "end_gfx": "98", + "lifepoints": "22", + "magic_animation": "711", + "magic_level": "16", + "melee_animation": "414", + "projectile": "97", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "96", + "start_height": "80", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "2712", + "name": "Air wizard", + "examine": "At least he looks solid enough to fight.", + "attack_level": "1", + "combat_style": "2", + "death_animation": "2553", + "defence_animation": "0", + "defence_level": "12", + "end_gfx": "92", + "lifepoints": "17", + "magic_animation": "711", + "magic_level": "12", + "melee_animation": "414", + "projectile": "91", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "90", + "start_height": "80", + "strength_level": "1", + "weakness": "3" + }, + { + "id": "2713", + "name": "Malignius Mortifer", + "examine": "A master of necromancy!" + }, + { + "id": "2714", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "2715", + "name": "Skeleton", + "attack_level": "1", + "combat_audio": "774,775,777", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2716", + "name": "Ghost", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "2717", + "name": "Skeleton mage", + "attack_level": "1", + "combat_audio": "774,775,777", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2718", + "name": "Betty", + "examine": "She'll store my items for me.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2719", + "name": "Grum" + }, + { + "id": "2720", + "name": "Gerrant" + }, + { + "id": "2721", + "name": "Wydin" + }, + { + "id": "2722", + "name": "Fishing spot" + }, + { + "id": "2723", + "name": "Fishing spot" + }, + { + "id": "2724", + "name": "Fishing spot" + }, + { + "id": "2725", + "name": "Otto Godblessed", + "examine": "A wise barbarian, apparently. He still looks like a thug.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2726", + "name": "Gull", + "examine": "A sea bird.", + "water_npc": "true" + }, + { + "id": "2727", + "name": "Gull" + }, + { + "id": "2728", + "name": "Monk of Entrana", + "examine": "Holy looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2729", + "name": "Monk of Entrana", + "examine": "Holy looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2730", + "name": "Monk of Entrana" + }, + { + "id": "2731", + "name": "Monk of Entrana", + "examine": "Holy looking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2732", + "name": "Master Crafter", + "examine": "He works in the Crafting Guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2733", + "name": "Master Crafter", + "examine": "He wanders around the Crafting Guild pretending to be working.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2734", + "name": "Tz-Kih", + "examine": "Hangs out in caves.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "5", + "bonuses": "150,22,22,22,22,11,0,0,0,0,0,0,0,0,0", + "death_animation": "9230", + "defence_animation": "9231", + "defence_level": "11", + "lifepoints": "10", + "magic_animation": "9232", + "melee_animation": "9232", + "range_animation": "9232", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "27" + }, + { + "id": "2735", + "name": "Tz-Kih", + "examine": "Hangs out in caves.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "5", + "bonuses": "150,22,22,22,22,11,0,0,0,0,0,0,0,0,0", + "death_animation": "9230", + "defence_animation": "9231", + "defence_level": "11", + "lifepoints": "10", + "magic_animation": "9232", + "melee_animation": "9232", + "range_animation": "9232", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "27" + }, + { + "id": "2736", + "name": "Tz-Kek", + "examine": "Looks like living lava...", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "5", + "bonuses": "80,45,45,45,45,22,0,0,0,0,0,0,0,0,0", + "death_animation": "9234", + "defence_animation": "9235", + "defence_level": "22", + "lifepoints": "20", + "magic_animation": "9233", + "magic_level": "20", + "melee_animation": "9233", + "range_animation": "9233", + "range_level": "20", + "safespot": null, + "strength_level": "60" + }, + { + "id": "2737", + "name": "Tz-Kek", + "examine": "Looks like living lava...", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "5", + "bonuses": "80,45,45,45,45,22,0,0,0,0,0,0,0,0,0", + "death_animation": "9234", + "defence_animation": "9235", + "defence_level": "22", + "lifepoints": "20", + "magic_animation": "9233", + "magic_level": "20", + "melee_animation": "9233", + "range_animation": "9233", + "range_level": "20", + "safespot": null, + "strength_level": "60" + }, + { + "id": "2738", + "name": "Tz-Kek", + "examine": "Looks like living lava...", + "attack_level": "30", + "attack_speed": "5", + "bonuses": "60,22,22,22,22,11,0,0,0,0,0,0,0,0,0", + "death_animation": "9234", + "defence_animation": "9235", + "defence_level": "11", + "lifepoints": "10", + "magic_animation": "9233", + "melee_animation": "9233", + "range_animation": "9233", + "range_level": "1", + "safespot": null, + "strength_level": "30" + }, + { + "id": "2739", + "name": "Tok-Xil", + "examine": "I don't like the look of those spines...", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "80,90,86,90,90,90,45,55,26,55,0,0,0,0,0", + "death_animation": "9239", + "defence_animation": "9242", + "defence_level": "45", + "lifepoints": "40", + "magic_animation": "9245", + "melee_animation": "9245", + "range_animation": "9245", + "range_level": "80", + "safespot": null, + "strength_level": "80", + "weakness": "4" + }, + { + "id": "2740", + "name": "Tok-Xil", + "examine": "I don't like the look of those spines...", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "80,90,86,90,90,90,45,55,26,55,0,0,0,0,0", + "death_animation": "9239", + "defence_animation": "9242", + "defence_level": "45", + "lifepoints": "40", + "magic_animation": "9245", + "melee_animation": "9245", + "range_animation": "9245", + "range_level": "80", + "safespot": null, + "strength_level": "80", + "weakness": "4" + }, + { + "id": "2741", + "name": "Yt-MejKot", + "examine": "Holy reptile...", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "5", + "bonuses": "100,180,180,180,180,90,97,0,0,0,0,0,0,0,0", + "death_animation": "9257", + "defence_animation": "9249", + "defence_level": "90", + "lifepoints": "80", + "magic_animation": "9252", + "melee_animation": "9252", + "range_animation": "9252", + "range_level": "1", + "safespot": null, + "strength_level": "100" + }, + { + "id": "2742", + "name": "Yt-MejKot", + "examine": "Holy reptile...", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "5", + "bonuses": "100,180,180,180,180,90,97,0,0,0,0,0,0,0,0", + "death_animation": "9257", + "defence_animation": "9249", + "defence_level": "90", + "lifepoints": "80", + "magic_animation": "9252", + "melee_animation": "9252", + "range_animation": "9252", + "range_level": "1", + "safespot": null, + "strength_level": "100" + }, + { + "id": "2743", + "name": "Ket-Zek", + "examine": "That's one hot dog!", + "attack_level": "150", + "attack_speed": "5", + "bonuses": "180,180,280,280,280,250,140,152,131,0,0,0,0,0,0", + "death_animation": "9269", + "defence_animation": "9268", + "defence_level": "180", + "lifepoints": "160", + "magic_animation": "9265", + "magic_level": "150", + "melee_animation": "9265", + "range_animation": "9265", + "range_level": "1", + "safespot": null, + "strength_level": "150" + }, + { + "id": "2744", + "name": "Ket-Zek", + "examine": "That's one hot dog!", + "attack_level": "150", + "attack_speed": "5", + "bonuses": "180,180,280,280,280,250,140,152,131,0,0,0,0,0,0", + "death_animation": "9269", + "defence_animation": "9268", + "defence_level": "180", + "lifepoints": "160", + "magic_animation": "9265", + "magic_level": "150", + "melee_animation": "9265", + "range_animation": "9265", + "range_level": "1", + "safespot": null, + "strength_level": "150" + }, + { + "id": "2745", + "name": "TzTok-Jad", + "examine": "This is going to hurt...", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "640", + "attack_speed": "8", + "bonuses": "0,0,0,60,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "9279", + "defence_animation": "9278", + "defence_level": "480", + "lifepoints": "250", + "magic_animation": "9277", + "magic_level": "480", + "melee_animation": "9277", + "range_animation": "9277", + "range_level": "960", + "safespot": null, + "slayer_exp": "0", + "strength_level": "960", + "weakness": "10" + }, + { + "id": "2746", + "name": "Yt-HurKot", + "examine": "Mini Menace.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "5", + "bonuses": "100,110,110,110,110,60,110,30,0,0,0,0,0,0,0", + "death_animation": "9257", + "defence_animation": "9253", + "defence_level": "75", + "lifepoints": "40", + "magic_animation": "9252", + "melee_animation": "9252", + "range_animation": "9252", + "range_level": "1", + "safespot": null, + "strength_level": "75" + }, + { + "id": "2747", + "name": "Solus Dellagar" + }, + { + "id": "2748", + "name": "Savant" + }, + { + "id": "2749", + "name": "Lord Daquarius" + }, + { + "id": "2750", + "name": "Solus Dellagar" + }, + { + "id": "2751", + "name": "Black Knight" + }, + { + "id": "2752", + "name": "Lord Daquarius" + }, + { + "id": "2753", + "name": "Mage of Zamorak" + }, + { + "id": "2754", + "name": "Mage of Zamorak" + }, + { + "id": "2755", + "name": "Mage of Zamorak" + }, + { + "id": "2756", + "name": "Woman" + }, + { + "id": "2759", + "name": "null", + "examine": "She can look after my money.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2776", + "name": "Woman", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,506,505", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2777", + "name": "Black Knight" + }, + { + "id": "2778", + "name": "Black Knight" + }, + { + "id": "2779", + "name": "Ranger", + "examine": "A Ranger of the Temple Knights.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "20", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2780", + "name": "Solus Dellagar" + }, + { + "id": "2781", + "name": "Gnome guard" + }, + { + "id": "2782", + "name": "Shadow", + "examine": "A shadow.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "5", + "death_animation": "2739", + "defence_animation": "0", + "defence_level": "68", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "2738", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "68", + "weakness": "6" + }, + { + "id": "2783", + "name": "Dark beast", + "examine": "From a darker dimension.", + "aggressive": "true", + "attack_level": "140", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,40,100,90,100,0,0,0,0,0", + "can_tolerate": "false", + "combat_audio": "389,391,390", + "death_animation": "2733", + "defence_animation": "2732", + "defence_level": "120", + "lifepoints": "220", + "magic_animation": "2731", + "magic_level": "160", + "melee_animation": "2731", + "range_animation": "2731", + "range_level": "1", + "safespot": null, + "slayer_exp": "225", + "strength_level": "160", + "weakness": "4" + }, + { + "id": "2784", + "name": "Mourner", + "examine": "A mourner, or plague healer." + }, + { + "id": "2785", + "name": "Slave", + "examine": "Digging.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "2786", + "name": "Slave", + "examine": "Digging.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "2787", + "name": "Slave", + "examine": "Confused.", + "attack_level": "", + "death_animation": "", + "defence_animation": "", + "defence_level": "", + "lifepoints": "", + "magic_animation": "", + "melee_animation": "", + "range_animation": "", + "range_level": "", + "safespot": null, + "strength_level": "" + }, + { + "id": "2788", + "name": "Thorgel" + }, + { + "id": "2790", + "name": "Sergeant Damien", + "examine": "Drill Sergeant from heck!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2791", + "name": "Pillory Guard" + }, + { + "id": "2792", + "name": "Tramp", + "examine": "A man down on his luck.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2793", + "name": "Tramp" + }, + { + "id": "2794", + "name": "Tramp" + }, + { + "id": "2795", + "name": "Skippy" + }, + { + "id": "2796", + "name": "Skippy", + "examine": "He looks angry and smells drunk." + }, + { + "id": "2797", + "name": "Skippy" + }, + { + "id": "2798", + "name": "Skippy" + }, + { + "id": "2799", + "name": "Skippy" + }, + { + "id": "2800", + "name": "A pile of broken glass" + }, + { + "id": "2801", + "name": "Ogre", + "examine": "Big, ugly, and smelly.", + "aggressive": "true", + "attack_level": "54", + "attack_speed": "6", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "54", + "lifepoints": "60", + "magic_animation": "359", + "melee_animation": "359", + "range_animation": "359", + "range_level": "1", + "safespot": null, + "strength_level": "54" + }, + { + "id": "2802", + "name": "Gnome Coach", + "examine": "They just call him 'Coach'.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2803", + "name": "Lizard", + "examine": "A cold-blooded creature, partial to warmth.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2778", + "defence_animation": "2777", + "defence_level": "55", + "lifepoints": "40", + "magic_animation": "2776", + "melee_animation": "2776", + "range_animation": "2776", + "range_level": "55", + "safespot": null, + "slayer_exp": "40", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "2804", + "name": "Desert Lizard", + "examine": "A cold-blooded creature, partial to warmth.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2778", + "defence_animation": "2777", + "defence_level": "45", + "lifepoints": "25", + "magic_animation": "2776", + "melee_animation": "2776", + "range_animation": "2776", + "range_level": "45", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "2805", + "name": "Desert Lizard", + "examine": "A cold-blooded creature, partial to warmth.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2778", + "defence_animation": "2777", + "defence_level": "45", + "lifepoints": "25", + "magic_animation": "2776", + "melee_animation": "2776", + "range_animation": "2776", + "range_level": "45", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "2806", + "name": "Desert Lizard", + "examine": "A cold-blooded creature, partial to warmth.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2778", + "defence_animation": "2777", + "defence_level": "45", + "lifepoints": "25", + "magic_animation": "2776", + "melee_animation": "2776", + "range_animation": "2776", + "range_level": "45", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "2807", + "name": "Small Lizard", + "examine": "A cold-blooded creature, partial to warmth.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2778", + "defence_animation": "2777", + "defence_level": "15", + "lifepoints": "15", + "magic_animation": "2776", + "melee_animation": "2776", + "range_animation": "2776", + "range_level": "15", + "safespot": null, + "slayer_exp": "15", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "2808", + "name": "Small Lizard", + "examine": "A cold-blooded creature, partial to warmth.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2778", + "defence_animation": "2777", + "defence_level": "15", + "lifepoints": "15", + "magic_animation": "2776", + "melee_animation": "2776", + "range_animation": "2776", + "range_level": "15", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "2809", + "name": "Al the Camel", + "examine": "A camel who has the soul of a poet.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2810", + "name": "Elly the Camel", + "examine": "A camel whose love is unrequited.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2811", + "name": "Ollie the Camel", + "examine": "A camel who wants to fly some day.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2812", + "name": "Cam the Camel", + "examine": "A camel who likes to rest.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2813", + "name": "Alice the Camel" + }, + { + "id": "2815", + "name": "Neferti the Camel", + "examine": "A camel who wants to see the world.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2816", + "name": "Ali the Smith" + }, + { + "id": "2821", + "name": "Ali the Farmer" + }, + { + "id": "2822", + "name": "Ali the Tailor" + }, + { + "id": "2823", + "name": "Ali the Guard" + }, + { + "id": "2824", + "name": "Ellis", + "examine": "Manufacturer of fine leathers." + }, + { + "id": "2825", + "name": "Pirate Pete", + "examine": "A shifty-looking character.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2826", + "name": "Pirate Pete", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2827", + "name": "Captain Braindeath", + "examine": "A shabby-looking leader.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2828", + "name": "50% Luke", + "examine": "Most of an angry", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2829", + "name": "Davey" + }, + { + "id": "2830", + "name": "Captain Donnie", + "examine": "I wonder if it was all the 'rum' that pickled him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2831", + "name": "Zombie protester", + "examine": "Sticking it to 'The Man'.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2832", + "name": "Zombie protester", + "examine": "Sticking it to 'The Man'.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2833", + "name": "Zombie protester", + "examine": "Sticking it to 'The Man'.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2834", + "name": "Zombie protester", + "examine": "Sticking it to 'The Man'.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2835", + "name": "Zombie protester", + "examine": "Sticking it to 'The Man'.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2836", + "name": "Zombie protester", + "examine": "Sticking it to 'The Man'.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2837", + "name": "Zombie pirate", + "examine": "An undead sea scoundrel.", + "aggressive": "true", + "attack_level": "36", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "2838", + "name": "Zombie pirate", + "examine": "An undead sea scoundrel.", + "aggressive": "true", + "attack_level": "36", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "2839", + "name": "Zombie pirate", + "examine": "An undead sea scoundrel.", + "aggressive": "true", + "attack_level": "36", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "2840", + "name": "Zombie pirate", + "examine": "An undead sea scoundrel.", + "aggressive": "true", + "attack_level": "36", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "2841", + "name": "Zombie pirate", + "examine": "An undead sea scoundrel.", + "aggressive": "true", + "attack_level": "36", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "2842", + "name": "Zombie pirate", + "examine": "An undead sea scoundrel.", + "aggressive": "true", + "attack_level": "36", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "51", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "2843", + "name": "Zombie swab", + "examine": "He talks a good fight.", + "aggressive": "true", + "attack_level": "34", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2844", + "name": "Zombie swab", + "examine": "He talks a good fight.", + "aggressive": "true", + "attack_level": "34", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2845", + "name": "Zombie swab", + "examine": "He talks a good fight.", + "aggressive": "true", + "attack_level": "34", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2846", + "name": "Zombie swab", + "examine": "He talks a good fight.", + "aggressive": "true", + "attack_level": "34", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2847", + "name": "Zombie swab", + "examine": "He talks a good fight.", + "aggressive": "true", + "attack_level": "34", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2848", + "name": "Zombie swab", + "examine": "He talks a good fight.", + "aggressive": "true", + "attack_level": "34", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "34", + "weakness": "6" + }, + { + "id": "2849", + "name": "Evil spirit", + "examine": "The pun was intended.", + "aggressive": "true", + "attack_level": "40", + "death_animation": "2805", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "magic_level": "40", + "melee_animation": "2804", + "range_animation": "0", + "range_level": "40", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "10" + }, + { + "id": "2850", + "name": "Fever spider", + "examine": "A bunch of legs, eyes and teeth.", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,15,10,15,15,0,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5321", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "5319", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "40", + "strength_level": "30", + "weakness": "2" + }, + { + "id": "2851", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2852", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2853", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2854", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2855", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2856", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2857", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2858", + "name": "Brewer", + "examine": "A worker in the brewery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2859", + "name": "Fishing spot" + }, + { + "id": "2860", + "name": "Amaethwyr", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "2861", + "name": "Teclyn", + "examine": "Looks after your Farming tools." + }, + { + "id": "2862", + "name": "Death" + }, + { + "id": "2863", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "2864", + "name": "Most of a Zombie" + }, + { + "id": "2865", + "name": "Most of a Zombie" + }, + { + "id": "2866", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "2867", + "name": "Most of a Zombie" + }, + { + "id": "2868", + "name": "Zombie Head" + }, + { + "id": "2869", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "2870", + "name": "Half-Zombie" + }, + { + "id": "2871", + "name": "Other Half-Zombie" + }, + { + "id": "2872", + "name": "Child" + }, + { + "id": "2873", + "name": "Child" + }, + { + "id": "2874", + "name": "Child" + }, + { + "id": "2875", + "name": "Child" + }, + { + "id": "2876", + "name": "Child" + }, + { + "id": "2877", + "name": "Child" + }, + { + "id": "2878", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "2879", + "name": "Bardur" + }, + { + "id": "2880", + "name": "Dagannoth fledgeling", + "examine": "A knee-high horror from the ocean depths...", + "aggressive": "true", + "attack_level": "52", + "death_animation": "1581", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "melee_animation": "1579", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "52", + "weakness": "6" + }, + { + "id": "2881", + "name": "Dagannoth Supreme", + "examine": "The Dagannoth King responsible for the death of Bukalla.", + "agg_radius": "8", + "aggressive": "true", + "attack_level": "255", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,10,255,550,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "2856", + "defence_animation": "2852", + "defence_level": "128", + "lifepoints": "255", + "magic_level": "255", + "melee_animation": "2855", + "movement_radius": "8", + "projectile": "475", + "range_level": "255", + "respawn_delay": "60", + "safespot": null, + "strength_level": "255" + }, + { + "id": "2882", + "name": "Dagannoth Prime", + "examine": "A legendary Dagannoth King, rumoured to fly on the North winds.", + "agg_radius": "8", + "aggressive": "true", + "attack_level": "255", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,255,255,255,255,10,0,0,0,0,0", + "clue_level": "2", + "combat_style": "2", + "death_animation": "2856", + "defence_animation": "2852", + "defence_level": "255", + "lifepoints": "255", + "magic_level": "255", + "melee_animation": "2854", + "movement_radius": "8", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "spell_id": "48", + "strength_level": "255" + }, + { + "id": "2883", + "name": "Dagannoth Rex", + "examine": "Firstborn of the legendary Dagannoth Kings.", + "agg_radius": "8", + "aggressive": "true", + "attack_level": "255", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,255,255,255,10,255,0,0,0,0,0", + "clue_level": "2", + "death_animation": "2856", + "defence_animation": "2852", + "defence_level": "255", + "lifepoints": "255", + "magic_level": "1", + "melee_animation": "2853", + "movement_radius": "8", + "range_level": "255", + "respawn_delay": "60", + "safespot": null, + "strength_level": "255" + }, + { + "id": "2884", + "name": "Wallasalki" + }, + { + "id": "2885", + "name": "Giant Rock Crab", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,225,200,175,-10,250,0,0,0,0,0", + "combat_audio": "717,723,722", + "death_animation": "1314", + "defence_animation": "1313", + "defence_level": "200", + "lifepoints": "180", + "melee_animation": "1312", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "80" + }, + { + "id": "2886", + "name": "Boulder", + "attack_level": "1", + "attack_speed": "5", + "defence_level": "1", + "lifepoints": "240", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2887", + "name": "Dagannoth", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "combat_style": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "1343", + "projectile": "288", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2888", + "name": "Dagannoth", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "combat_style": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "1343", + "projectile": "288", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2889", + "name": "Rock lobster", + "examine": "It wasn't a rock... It was a rock lobster!", + "attack_level": "100", + "attack_speed": "2", + "bonuses": "0,0,0,0,0,100,100,50,50,150,0,0,0,0,0", + "combat_audio": "726,728,727", + "death_animation": "2862", + "defence_animation": "2861", + "defence_level": "100", + "lifepoints": "150", + "magic_animation": "2860", + "melee_animation": "2860", + "movement_radius": "30", + "range_animation": "2860", + "range_level": "1", + "safespot": null, + "strength_level": "100", + "weakness": "7" + }, + { + "id": "2890", + "name": "Large rock", + "examine": "A Rock.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "2", + "death_animation": "2861", + "defence_animation": "2861", + "defence_level": "100", + "lifepoints": "150", + "magic_animation": "2860", + "melee_animation": "2860", + "range_animation": "2860", + "range_level": "1", + "safespot": null, + "strength_level": "100", + "weakness": "7" + }, + { + "id": "2891", + "name": "Suspicious water" + }, + { + "id": "2892", + "name": "Spinolyp", + "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", + "agg_radius": "12", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", + "combat_style": "2", + "death_animation": "2866", + "defence_animation": "2869", + "defence_level": "1", + "lifepoints": "75", + "magic_animation": "2866", + "magic_level": "65", + "melee_animation": "2868", + "projectile": "294", + "range_animation": "2866", + "range_level": "20", + "respawn_delay": "55", + "safespot": null, + "slayer_exp": "0", + "spell_id": "14", + "strength_level": "10" + }, + { + "id": "2893", + "name": "Suspicious water" + }, + { + "id": "2894", + "name": "Spinolyp", + "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", + "agg_radius": "12", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", + "combat_style": "2", + "death_animation": "2866", + "defence_animation": "2869", + "defence_level": "1", + "lifepoints": "75", + "magic_animation": "2866", + "magic_level": "65", + "melee_animation": "2868", + "projectile": "294", + "range_animation": "2866", + "range_level": "20", + "respawn_delay": "55", + "safespot": null, + "spell_id": "14", + "strength_level": "10" + }, + { + "id": "2895", + "name": "Suspicious water" + }, + { + "id": "2896", + "name": "Spinolyp", + "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", + "agg_radius": "12", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", + "combat_style": "2", + "death_animation": "2866", + "defence_animation": "2869", + "defence_level": "1", + "lifepoints": "75", + "magic_animation": "2866", + "magic_level": "65", + "melee_animation": "2868", + "projectile": "294", + "range_animation": "2866", + "range_level": "70", + "respawn_delay": "55", + "safespot": null, + "slayer_exp": "0", + "spell_id": "14", + "strength_level": "60" + }, + { + "id": "2897", + "name": "Father Reen" + }, + { + "id": "2900", + "name": "Father Reen" + }, + { + "id": "2901", + "name": "Father Badden" + }, + { + "id": "2903", + "name": "Father Badden" + }, + { + "id": "2904", + "name": "Denath" + }, + { + "id": "2905", + "name": "Denath" + }, + { + "id": "2906", + "name": "Eric" + }, + { + "id": "2907", + "name": "Eric" + }, + { + "id": "2908", + "name": "Evil Dave" + }, + { + "id": "2910", + "name": "Evil Dave" + }, + { + "id": "2911", + "name": "Matthew" + }, + { + "id": "2912", + "name": "Matthew" + }, + { + "id": "2913", + "name": "Jennifer" + }, + { + "id": "2914", + "name": "Jennifer" + }, + { + "id": "2915", + "name": "Tanya" + }, + { + "id": "2916", + "name": "Tanya" + }, + { + "id": "2917", + "name": "Patrick" + }, + { + "id": "2918", + "name": "Patrick" + }, + { + "id": "2919", + "name": "Agrith Naar", + "aggressive": "true", + "attack_level": "1", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "1", + "lifepoints": "95", + "melee_animation": "64", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2920", + "name": "Sand storm" + }, + { + "id": "2922", + "name": "Clay golem" + }, + { + "id": "2928", + "name": "Clay golem" + }, + { + "id": "2929", + "name": "Ghost" + }, + { + "id": "2931", + "name": "Ghost", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "2932", + "name": "Jorral" + }, + { + "id": "2933", + "name": "Melina" + }, + { + "id": "2935", + "name": "Melina" + }, + { + "id": "2936", + "name": "Droalak" + }, + { + "id": "2938", + "name": "Droalak" + }, + { + "id": "2939", + "name": "Dron" + }, + { + "id": "2940", + "name": "Blanin" + }, + { + "id": "2941", + "name": "The Beast", + "examine": "Who ate all the rats?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2942", + "name": "Bellemorde", + "examine": "Unkempt and a bit smelly." + }, + { + "id": "2943", + "name": "Pox" + }, + { + "id": "2944", + "name": "Pox" + }, + { + "id": "2945", + "name": "Bones", + "examine": "Lovely, cute, and possibly what dreams are made of.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2946", + "name": "Grimesquit", + "examine": "Cracking personality." + }, + { + "id": "2947", + "name": "Phingspet", + "examine": "Lovely girl, shame about the smell." + }, + { + "id": "2948", + "name": "Hooknosed Jack", + "examine": "Obviously punches above his weight.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2949", + "name": "Jimmy Dazzler", + "examine": "Looks rich like an actor of sorts.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2950", + "name": "The Face", + "examine": "Once beautiful, now repugnant.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2951", + "name": "Felkrash" + }, + { + "id": "2952", + "name": "Smokin' Joe", + "examine": "What is he?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2953", + "name": "Ceril Carnillean" + }, + { + "id": "2954", + "name": "Councillor Halgrive" + }, + { + "id": "2955", + "name": "Spice seller" + }, + { + "id": "2956", + "name": "Fur trader" + }, + { + "id": "2957", + "name": "Gem merchant" + }, + { + "id": "2958", + "name": "Silver merchant", + "examine": "Looks fairly well fed.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2959", + "name": "Silk merchant" + }, + { + "id": "2960", + "name": "Zenesha" + }, + { + "id": "2961", + "name": "Ali Morrisane" + }, + { + "id": "2962", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2963", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2964", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2965", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2966", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2967", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2968", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2969", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2970", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2971", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2972", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2973", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2974", + "name": "Rat" + }, + { + "id": "2980", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2981", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2982", + "name": "King rat", + "examine": "The master of all rats.", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2983", + "name": "Turbogroomer" + }, + { + "id": "2984", + "name": "Pusskins", + "examine": "Not a soft touch.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2985", + "name": "Loki" + }, + { + "id": "2986", + "name": "Captain Tom", + "examine": "A not-so friendly, not-so little cat.", + "aggressive": "true", + "attack_level": "10", + "attack_speed": "4", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2987", + "name": "Treacle" + }, + { + "id": "2988", + "name": "Mittens", + "examine": "A fully grown feline.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2989", + "name": "Claude" + }, + { + "id": "2990", + "name": "Topsy", + "examine": "Cute and fluffy.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2991", + "name": "Rauborn" + }, + { + "id": "2992", + "name": "Vaeringk" + }, + { + "id": "2993", + "name": "Oxi" + }, + { + "id": "2994", + "name": "Fior" + }, + { + "id": "2995", + "name": "Sagira" + }, + { + "id": "2996", + "name": "Anleif" + }, + { + "id": "2997", + "name": "Gertrude's cat", + "examine": "A friendly feline?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2998", + "name": "Gambler", + "examine": "Very well to do. I wonder what he's doing here.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "2999", + "name": "Gambler" + }, + { + "id": "3000", + "name": "Barman" + }, + { + "id": "3001", + "name": "Gambler", + "examine": "Rich.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3002", + "name": "Gambler", + "examine": "Poor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3003", + "name": "Gambler", + "examine": "Poor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3004", + "name": "Gambler", + "examine": "Poor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3005", + "name": "Gambler", + "examine": "Poor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3006", + "name": "Gambler", + "examine": "Poor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3007", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3008", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3009", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3010", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3011", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3012", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3013", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3014", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3015", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3016", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3017", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3018", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3019", + "name": "Fishing spot" + }, + { + "id": "3020", + "name": "Rug Merchant" + }, + { + "id": "3021", + "name": "Tool leprechaun", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3022", + "name": "Genie", + "examine": "Phenomenal cosmic powers", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3023", + "name": "Nirrie" + }, + { + "id": "3024", + "name": "Tirrie" + }, + { + "id": "3025", + "name": "Hallak" + }, + { + "id": "3026", + "name": "Black golem", + "examine": "An animated clay statue.", + "aggressive": "true", + "attack_level": "55", + "death_animation": "2919", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "2917", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "2" + }, + { + "id": "3027", + "name": "White golem", + "examine": "An animated clay statue.", + "aggressive": "true", + "attack_level": "55", + "death_animation": "2919", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "2917", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "55", + "weakness": "0" + }, + { + "id": "3028", + "name": "Grey golem", + "examine": "An animated clay statue.", + "aggressive": "true", + "attack_level": "55", + "death_animation": "2919", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "2917", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "55", + "weakness": "1" + }, + { + "id": "3029", + "name": "Ghaslor the Elder", + "examine": "The oldest man in Nardah.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3030", + "name": "Ali the Carter", + "examine": "A water salesman from Pollnivneach.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3031", + "name": "Usi" + }, + { + "id": "3032", + "name": "Nkuku" + }, + { + "id": "3033", + "name": "Garai" + }, + { + "id": "3034", + "name": "Habibah" + }, + { + "id": "3035", + "name": "Meskhenet" + }, + { + "id": "3036", + "name": "Zahra" + }, + { + "id": "3037", + "name": "Zahur" + }, + { + "id": "3038", + "name": "Seddu" + }, + { + "id": "3039", + "name": "Kazemde" + }, + { + "id": "3040", + "name": "Awusah the Mayor", + "examine": "The Mayor of Nardah.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3041", + "name": "Tarik" + }, + { + "id": "3042", + "name": "Poltenip", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3043", + "name": "Radat", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3044", + "name": "Shiratti the Custodian", + "examine": "Custodian of the shrine to Elidinis.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3045", + "name": "Rokuh" + }, + { + "id": "3046", + "name": "Nardah Banker", + "examine": "A banker of Nardah.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3047", + "name": "Target" + }, + { + "id": "3048", + "name": "Target" + }, + { + "id": "3049", + "name": "Larxus" + }, + { + "id": "3051", + "name": "Mystery figure", + "examine": "A mysterious watcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3052", + "name": "Mystery figure", + "examine": "A mysterious watcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3053", + "name": "Mystery figure", + "examine": "A mysterious watcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3054", + "name": "Mystery figure", + "examine": "A mysterious watcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3055", + "name": "Mystery figure", + "examine": "A mysterious watcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3056", + "name": "Mystery figure", + "examine": "A mysterious watcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3057", + "name": "Earth Warrior Champion", + "examine": "Champion of the earth warriors.", + "aggressive": "true", + "attack_level": "84", + "death_animation": "2946", + "defence_animation": "0", + "defence_level": "84", + "lifepoints": "108", + "magic_animation": "0", + "melee_animation": "2951", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "84", + "weakness": "7" + }, + { + "id": "3058", + "name": "Giant Champion", + "examine": "Champion of the giants.", + "aggressive": "true", + "attack_level": "36", + "attack_speed": "4", + "death_animation": "6369", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "70", + "magic_animation": "0", + "melee_animation": "6368", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "35", + "strength_level": "44", + "weakness": "8" + }, + { + "id": "3059", + "name": "Ghoul Champion", + "examine": "Champion of the ghouls.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "441,444,443", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "50", + "strength_level": "80", + "weakness": "9" + }, + { + "id": "3060", + "name": "Goblin Champion", + "examine": "Champion of the goblins.", + "attack_level": "1", + "attack_speed": "4", + "combat_audio": "469,472,471", + "death_animation": "6190", + "defence_animation": "0", + "defence_level": "14", + "lifepoints": "32", + "magic_animation": "0", + "magic_level": "26", + "melee_animation": "6188", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "10" + }, + { + "id": "3061", + "name": "Hobgoblin Champion", + "examine": "Champion of the hobgoblins.", + "aggressive": "true", + "attack_level": "44", + "attack_speed": "4", + "combat_audio": "469,472,471", + "combat_style": "1", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "48", + "lifepoints": "58", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "44", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "0" + }, + { + "id": "3062", + "name": "Imp Champion", + "examine": "Champion of the imps.", + "aggressive": "true", + "attack_level": "5", + "attack_speed": "4", + "death_animation": "172", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "5285", + "range_animation": "0", + "range_level": "5", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "7" + }, + { + "id": "3063", + "name": "Jogre Champion", + "examine": "Champion of the jogres.", + "aggressive": "true", + "attack_level": "86", + "death_animation": "2938", + "defence_animation": "2937", + "defence_level": "86", + "lifepoints": "120", + "magic_animation": "2936", + "melee_animation": "2936", + "poison_amount": "40", + "poisonous": "true", + "range_animation": "2936", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "86", + "weakness": "9" + }, + { + "id": "3064", + "name": "Lesser Demon Champion", + "examine": "Champion of the lesser demons.", + "aggressive": "true", + "attack_level": "136", + "combat_audio": "396,402,401", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "142", + "lifepoints": "148", + "magic_animation": "0", + "magic_level": "136", + "melee_animation": "64", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "79", + "strength_level": "140", + "weakness": "5" + }, + { + "id": "3065", + "name": "Skeleton Champion", + "examine": "Champion of the jogres.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1444", + "defence_animation": "5493", + "defence_level": "54", + "lifepoints": "58", + "magic_animation": "0", + "melee_animation": "5485", + "poisonous": "", + "range_animation": "5493", + "range_level": "36", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "3066", + "name": "Zombies Champion", + "examine": "Champion of the zombies.", + "aggressive": "true", + "attack_level": "26", + "attack_speed": "5", + "death_animation": "5575", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "5581", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "3067", + "name": "Leon d'Cour", + "aggressive": "true", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "7050", + "defence_level": "1", + "lifepoints": "123", + "melee_animation": "7049", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3068", + "name": "Skeletal Wyvern", + "examine": "A very dangerous pile of animated Wyvern bones.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "125", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "0,771,770", + "death_animation": "2987", + "defence_animation": "2983", + "defence_level": "120", + "end_gfx": "501", + "lifepoints": "200", + "magic_animation": "2985", + "magic_level": "125", + "melee_animation": "2985", + "projectile": "500", + "range_animation": "2989", + "range_level": "120", + "safespot": null, + "slayer_exp": "210", + "start_gfx": "499", + "strength_level": "116", + "weakness": "9" + }, + { + "id": "3069", + "name": "Skeletal Wyvern", + "examine": "A very dangerous pile of animated Wyvern bones.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "125", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "0,771,770", + "death_animation": "2987", + "defence_animation": "2983", + "defence_level": "120", + "end_gfx": "501", + "lifepoints": "200", + "magic_animation": "2985", + "magic_level": "125", + "melee_animation": "2985", + "projectile": "500", + "range_animation": "2989", + "range_level": "120", + "safespot": null, + "slayer_exp": "210", + "start_gfx": "499", + "strength_level": "116", + "weakness": "9" + }, + { + "id": "3070", + "name": "Skeletal Wyvern", + "examine": "A very dangerous pile of animated Wyvern bones.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "125", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "0,771,770", + "death_animation": "2987", + "defence_animation": "2983", + "defence_level": "120", + "end_gfx": "501", + "lifepoints": "200", + "magic_animation": "2985", + "magic_level": "125", + "melee_animation": "2985", + "projectile": "500", + "range_animation": "2989", + "range_level": "120", + "safespot": null, + "slayer_exp": "210", + "start_gfx": "499", + "strength_level": "116", + "weakness": "9" + }, + { + "id": "3071", + "name": "Skeletal Wyvern", + "examine": "A very dangerous pile of animated Wyvern bones.", + "agg_radius": "6", + "aggressive": "true", + "attack_level": "125", + "attack_speed": "6", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "0,771,770", + "death_animation": "2987", + "defence_animation": "2983", + "defence_level": "120", + "end_gfx": "501", + "lifepoints": "200", + "magic_animation": "2985", + "magic_level": "125", + "melee_animation": "2985", + "projectile": "500", + "range_animation": "2989", + "range_level": "120", + "safespot": null, + "slayer_exp": "210", + "start_gfx": "499", + "strength_level": "116", + "weakness": "9" + }, + { + "id": "3072", + "name": "Ice giant", + "examine": "He's got icicles in his beard.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4673", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4672", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "70", + "strength_level": "40", + "weakness": "9" + }, + { + "id": "3073", + "name": "Ice warrior", + "examine": "A cold-hearted elemental warrior.", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "2500,530,529", + "death_animation": "843", + "defence_animation": "404", + "defence_level": "47", + "lifepoints": "59", + "magic_animation": "451", + "melee_animation": "451", + "range_animation": "451", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "59", + "strength_level": "47", + "weakness": "9" + }, + { + "id": "3074", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3075", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3076", + "name": "Dead Monk" + }, + { + "id": "3078", + "name": "High Priest" + }, + { + "id": "3079", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3080", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3081", + "name": "Assassin" + }, + { + "id": "3082", + "name": "Rosie" + }, + { + "id": "3083", + "name": "Sorcha" + }, + { + "id": "3084", + "name": "Cait" + }, + { + "id": "3085", + "name": "Cormac" + }, + { + "id": "3086", + "name": "Fionn" + }, + { + "id": "3087", + "name": "Donnacha" + }, + { + "id": "3088", + "name": "Ronan" + }, + { + "id": "3089", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3090", + "name": "", + "examine": "A mighty warrior", + "aggressive": "true", + "attack_level": "17", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "17", + "lifepoints": "24", + "magic_animation": "0", + "melee_animation": "7048", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "17", + "weakness": "8" + }, + { + "id": "3091", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3093", + "name": "Flying Book" + }, + { + "id": "3094", + "name": "Flying Book", + "examine": "The book moves by itself!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3095", + "name": "Flying Book" + }, + { + "id": "3096", + "name": "Pizzaz Hat" + }, + { + "id": "3097", + "name": "Entrance Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3098", + "name": "Telekinetic Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3099", + "name": "Alchemy Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3100", + "name": "Enchantment Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3101", + "name": "Graveyard Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3102", + "name": "Maze Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3103", + "name": "Rewards Guardian", + "examine": "A guardian of the arena.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3104", + "name": "Charmed Warrior", + "examine": "Equipment that moves by itself!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3105", + "name": "Charmed Warrior", + "examine": "Equipment that moves by itself!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3106", + "name": "Charmed Warrior", + "examine": "Equipment that moves by itself!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3107", + "name": "Charmed Warrior" + }, + { + "id": "3108", + "name": "Bert" + }, + { + "id": "3109", + "name": "Guard Captain", + "examine": "This guard looks rather drunk and has beer stains down his armour.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3110", + "name": "Sandy" + }, + { + "id": "3112", + "name": "Sandy", + "examine": "Angry and stressed, he doesn't seem to have time for anything other than sand." + }, + { + "id": "3113", + "name": "Sandy" + }, + { + "id": "3114", + "name": "Mazion" + }, + { + "id": "3115", + "name": "Blaec", + "examine": "Blaec seems to be covered in sand." + }, + { + "id": "3116", + "name": "Reeso" + }, + { + "id": "3117", + "name": "Sandwich lady", + "examine": "The sandwich lady." + }, + { + "id": "3118", + "name": "Prison Pete" + }, + { + "id": "3119", + "name": "Balloon Animal" + }, + { + "id": "3120", + "name": "Balloon Animal" + }, + { + "id": "3121", + "name": "Balloon Animal", + "examine": "Looks after farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3122", + "name": "Balloon Animal", + "examine": "I saw the witchdoctor", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3123", + "name": "Simon Templeton", + "examine": "Looks like he's seen the inside of a few tombs.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "12", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": "0", + "strength_level": "1" + }, + { + "id": "3124", + "name": "Pyramid block" + }, + { + "id": "3125", + "name": "Pyramid block" + }, + { + "id": "3126", + "name": "Pentyn" + }, + { + "id": "3127", + "name": "Aristarchus" + }, + { + "id": "3128", + "name": "Boneguard" + }, + { + "id": "3130", + "name": "Pile of bones" + }, + { + "id": "3131", + "name": "Desert Spirit" + }, + { + "id": "3132", + "name": "Crust of ice" + }, + { + "id": "3134", + "name": "Furnace grate" + }, + { + "id": "3135", + "name": "Furnace grate", + "examine": "It seems to be blocked.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "0", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3136", + "name": "Enakhra" + }, + { + "id": "3138", + "name": "Enakhra" + }, + { + "id": "3139", + "name": "Boneguard" + }, + { + "id": "3141", + "name": "Akthanakos" + }, + { + "id": "3142", + "name": "Akthanakos" + }, + { + "id": "3143", + "name": "Lazim" + }, + { + "id": "3148", + "name": "Enakhra" + }, + { + "id": "3149", + "name": "Akthanakos" + }, + { + "id": "3150", + "name": "Knight", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3151", + "name": "Skeleton", + "attack_level": "1", + "combat_audio": "774,775,777", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3152", + "name": "Harpie Bug Swarm" + }, + { + "id": "3153", + "name": "Harpie Bug Swarm", + "examine": "A swarm of bugs.", + "aggressive": "true", + "attack_level": "54", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,5,10,5,10,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "2743,2745,2744", + "death_animation": "1585", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1584", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "25", + "strength_level": "46", + "weakness": "2" + }, + { + "id": "3154", + "name": "Count Draynor" + }, + { + "id": "3155", + "name": "Bill Teach", + "examine": "Bill Teach the pirate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3156", + "name": "Bill Teach" + }, + { + "id": "3157", + "name": "Bill Teach" + }, + { + "id": "3158", + "name": "Bill Teach" + }, + { + "id": "3159", + "name": "Bill Teach" + }, + { + "id": "3160", + "name": "Bill Teach" + }, + { + "id": "3161", + "name": "Charley" + }, + { + "id": "3162", + "name": "Smith" + }, + { + "id": "3163", + "name": "Joe" + }, + { + "id": "3164", + "name": "Mama" + }, + { + "id": "3165", + "name": "Mama" + }, + { + "id": "3166", + "name": "Mike", + "examine": "Dodgy Mike." + }, + { + "id": "3167", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3168", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3169", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3170", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3171", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3172", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3173", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3174", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3175", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3176", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3177", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3178", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3179", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3180", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3181", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3182", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3183", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3184", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3185", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3186", + "name": "Pirate", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3187", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3188", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3189", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3190", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3191", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3192", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3193", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3194", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3195", + "name": "Pirate", + "examine": "Arghh matey!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "combat_audio": "703,705,704", + "death_animation": "9055", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "45", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3196", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3197", + "name": "Gull" + }, + { + "id": "3198", + "name": "Banker", + "examine": "He can look after my money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3199", + "name": "Banker", + "examine": "He can look after my money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3200", + "name": "Chaos Elemental", + "examine": "pUre A cHaOs of crEatuRe!", + "agg_radius": "16", + "aggressive": "true", + "attack_level": "270", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,70,70,70,70,70,0,0,0,0,0", + "combat_audio": "345,351,347", + "death_animation": "3147", + "defence_animation": "3149", + "defence_level": "270", + "end_gfx": "558", + "lifepoints": "250", + "magic_animation": "5443", + "magic_level": "270", + "melee_animation": "3146", + "movement_radius": "30", + "projectile": "557", + "range_animation": "5443", + "range_level": "270", + "respawn_delay": "100", + "safespot": "true", + "start_gfx": "556", + "strength_level": "270", + "weakness": "4" + }, + { + "id": "3201", + "name": "Killerwatt", + "attack_level": "1", + "attack_speed": "3", + "defence_level": "1", + "lifepoints": "51", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "51", + "strength_level": "1" + }, + { + "id": "3202", + "name": "Killerwatt", + "attack_level": "1", + "attack_speed": "3", + "defence_level": "1", + "lifepoints": "51", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "51", + "strength_level": "1" + }, + { + "id": "3203", + "name": "Storm Cloud", + "examine": "A very small storm!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3204", + "name": "Storm Cloud", + "examine": "A very small storm!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3205", + "name": "Romily Weaklax" + }, + { + "id": "3206", + "name": "Priest" + }, + { + "id": "3207", + "name": "Pious Pete" + }, + { + "id": "3208", + "name": "Taper" + }, + { + "id": "3209", + "name": "Elena", + "examine": "She doesn't look too happy." + }, + { + "id": "3210", + "name": "Alrena" + }, + { + "id": "3211", + "name": "Alrena" + }, + { + "id": "3212", + "name": "Bravek" + }, + { + "id": "3213", + "name": "Edmond", + "examine": "A local civilian.", + "attack_level": "", + "combat_audio": "", + "defence_level": "", + "lifepoints": "", + "range_level": "", + "safespot": null, + "slayer_exp": "", + "strength_level": "" + }, + { + "id": "3214", + "name": "Edmond", + "examine": "A local civilian.", + "attack_level": "", + "combat_audio": "", + "defence_level": "", + "lifepoints": "", + "range_level": "", + "safespot": null, + "slayer_exp": "", + "strength_level": "" + }, + { + "id": "3215", + "name": "Elena", + "examine": "She looks concerned." + }, + { + "id": "3216", + "name": "Mourner", + "examine": "A mourner, or plague healer." + }, + { + "id": "3217", + "name": "Kaylee", + "examine": "Works in the Rising Sun." + }, + { + "id": "3218", + "name": "Tina" + }, + { + "id": "3219", + "name": "Dwarf", + "examine": "Loves mining.", + "attack_level": "28", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "28", + "weakness": "6" + }, + { + "id": "3220", + "name": "Dwarf", + "examine": "Loves mining.", + "attack_level": "32", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "32", + "weakness": "6" + }, + { + "id": "3221", + "name": "Dwarf", + "examine": "Loves mining.", + "attack_level": "28", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "28", + "weakness": "6" + }, + { + "id": "3222", + "name": "Drunken man", + "examine": "One of Gielinor's many citizens, currently incapacitated by alcohol.", + "attack_level": "4", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "4", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "4", + "weakness": "9" + }, + { + "id": "3223", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" + }, + { + "id": "3224", + "name": "Man", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3225", + "name": "Man", + "examine": "One of Gielinor's many citizens. He looks worried about something.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" + }, + { + "id": "3226", + "name": "Woman", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "9", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3227", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "511,506,505", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3228", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "3229", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "4230", + "range_animation": "2075", + "range_level": "13", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3230", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "13", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "395", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "3231", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "426", + "range_level": "13", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3232", + "name": "Guard", + "examine": "Keeping an eye out for threats to the city.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "426", + "range_level": "13", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3233", + "name": "Guard", + "examine": "Keeping an eye out for threats to the city.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "426", + "range_level": "13", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3234", + "name": "Gardener", + "examine": "An old gardener.", + "attack_level": "4", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "4", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "433", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "4", + "weakness": "8" + }, + { + "id": "3235", + "name": "Apprentice workman", + "examine": "He's learning a trade.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3236", + "name": "Workman", + "examine": "A busy workman", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3237", + "name": "Cuffs", + "examine": "He looks a bit dodgy.", + "agg_radius": "", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "7", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3238", + "name": "Narf", + "examine": "Looks unpleasant.", + "agg_radius": "", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "7", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3239", + "name": "Rusty", + "examine": "Seems to be loitering.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "7", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3240", + "name": "Jeff", + "examine": "Untrustworthy.", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "7", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3241", + "name": "Guard", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3242", + "name": "Dark wizard", + "examine": "A practicer of dark arts.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "3243", + "name": "Dark wizard", + "examine": "A practicer of dark arts.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "27", + "lifepoints": "38", + "magic_animation": "711", + "magic_level": "27", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "3244", + "name": "Dark wizard", + "examine": "A practicer of dark arts.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "16", + "lifepoints": "22", + "magic_animation": "711", + "magic_level": "16", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "3245", + "name": "Dark wizard", + "examine": "A practicer of dark arts.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "16", + "lifepoints": "22", + "magic_animation": "711", + "magic_level": "16", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "3246", + "name": "Barbarian", + "examine": "Alberich, a fierce barbarian warrior.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3247", + "name": "Barbarian", + "examine": "Fafner, a tough barbarian warrior.", + "attack_level": "22", + "attack_speed": "6", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "18", + "magic_animation": "7048", + "melee_animation": "7048", + "range_animation": "7048", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3248", + "name": "Barbarian", + "examine": "Fasolt, a strong barbarian warrior.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3249", + "name": "Barbarian", + "examine": "Siegmund, a guard in the Barbarian Village.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3250", + "name": "Barbarian", + "examine": "Siegfried, a young guard in the Barbarian Village.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3251", + "name": "Barbarian", + "examine": "Lydspor, a well-traveld barbarian warrior.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "7048", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3252", + "name": "Barbarian", + "examine": "Hagen, a guard in the Barbarian Village.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3253", + "name": "Barbarian", + "examine": "Minarch, a barbarian who likes his beer.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3254", + "name": "Hunding" + }, + { + "id": "3255", + "name": "Barbarian", + "examine": "Wotan, a sturdy barbarian warrior.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3256", + "name": "Barbarian", + "examine": "Acelin, a guard in the Barbarian Village.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3257", + "name": "Barbarian", + "examine": "Adelino, a barbarian warrior with a big axe.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3258", + "name": "Barbarian", + "examine": "Adolpho, a barbarian warrior with a warhammer.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "401", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3259", + "name": "Barbarian", + "examine": "Aitan, a barbarian archer.", + "attack_level": "22", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "1", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "3260", + "name": "Barbarian", + "examine": "Brunnhilde, a fierce barbarian warrior.", + "attack_level": "20", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "8" + }, + { + "id": "3261", + "name": "Barbarian", + "examine": "Gutrune, a mighty barbarian warrior.", + "attack_level": "20", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "8" + }, + { + "id": "3262", + "name": "Barbarian", + "examine": "Edelschwarz, a barbarian warrior with a spear.", + "attack_level": "20", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "8" + }, + { + "id": "3263", + "name": "Barbarian", + "examine": "Sieglinde, a muscular barbarian warrior.", + "attack_level": "22", + "attack_speed": "6", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "404", + "defence_level": "22", + "lifepoints": "20", + "magic_animation": "428", + "melee_animation": "428", + "range_animation": "428", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "8" + }, + { + "id": "3264", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "3265", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "3266", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "3267", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "470,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "3268", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3269", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3270", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3271", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3272", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3273", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3274", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3275", + "name": "Dwarf", + "examine": "A dwarven worker.", + "attack_level": "10", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "14", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "10", + "weakness": "6" + }, + { + "id": "3276", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "30", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "30", + "weakness": "6" + }, + { + "id": "3277", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "30", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "30", + "weakness": "6" + }, + { + "id": "3278", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "30", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "30", + "weakness": "6" + }, + { + "id": "3279", + "name": "Black Guard", + "examine": "A member of the Black Guard", + "attack_level": "30", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "30", + "weakness": "6" + }, + { + "id": "3280", + "name": "Engineering assistant", + "examine": "He looks busy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3281", + "name": "Engineering assistant" + }, + { + "id": "3282", + "name": "Engineer", + "examine": "He's building a cannon.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3283", + "name": "Squirrel", + "examine": "Bushy tail!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3284", + "name": "Squirrel", + "examine": "Bushy tail!" + }, + { + "id": "3285", + "name": "Squirrel", + "examine": "Bushy tail!" + }, + { + "id": "3286", + "name": "Raccoon", + "examine": "A raccoon.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3287", + "name": "Raccoon", + "examine": "A raccoon." + }, + { + "id": "3288", + "name": "Raccoon", + "examine": "A raccoon.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3289", + "name": "Skeleton" + }, + { + "id": "3291", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "8", + "weakness": "8" + }, + { + "id": "3292", + "name": "Witch" + }, + { + "id": "3293", + "name": "null", + "examine": "She'll store my items for me.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3294", + "name": "Dwarf", + "examine": "A dwarf who looks after the mining guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "3295", + "name": "Dwarf", + "examine": "A dwarf who looks after the mining guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "3296", + "name": "Swan", + "examine": "A graceful bird.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "water_npc": true + }, + { + "id": "3297", + "name": "Black Swan", + "examine": "A rare bird.", + "water_npc": "true" + }, + { + "id": "3298", + "name": "Sweeper", + "examine": "Keeps this magic area tidy.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3299", + "name": "Martin the Master Gardener", + "examine": "A master at gardening.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3300", + "name": "Frog" + }, + { + "id": "3301", + "name": "Storm cloud" + }, + { + "id": "3302", + "name": "Co-ordinator", + "examine": "Manages the fairies.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3303", + "name": "Fairy Nuff" + }, + { + "id": "3304", + "name": "Fairy Godfather", + "examine": "I'm gonna make him an offer he can't refuse.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3305", + "name": "Slim Louie" + }, + { + "id": "3306", + "name": "Fat Rocco" + }, + { + "id": "3307", + "name": "Gatekeeper", + "examine": "Guardian of the market gate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3308", + "name": "Zandar Horfyre" + }, + { + "id": "3309", + "name": "Cow", + "examine": "Converts grass to beef.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "369,371,370", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "5849", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "safespot": null, + "slayer_exp": "8", + "strength_level": "1", + "weakness": "8" + }, + { + "id": "3310", + "name": "Sheep", + "examine": "White and fluffy" + }, + { + "id": "3311", + "name": "Sheep" + }, + { + "id": "3312", + "name": "Zanaris choir", + "examine": "They're going to sing to you!" + }, + { + "id": "3313", + "name": "Tanglefoot", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "102", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3314", + "name": "Baby tanglefoot" + }, + { + "id": "3319", + "name": "Baby tanglefoot", + "examine": "An animated shrub.", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "41", + "lifepoints": "58", + "magic_animation": "0", + "range_animation": "0", + "range_level": "41", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "3320", + "name": "Baby tanglefoot", + "examine": "An aggressive bush.", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "41", + "lifepoints": "58", + "magic_animation": "0", + "range_animation": "0", + "range_level": "41", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "3321", + "name": "Gatekeeper" + }, + { + "id": "3322", + "name": "Fairy chef", + "examine": "Likes to cook with mushrooms.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "movement_radius": "2", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3323", + "name": "Draul Leptoc" + }, + { + "id": "3324", + "name": "Draul Leptoc", + "examine": "This looks like an angry, aggressive man." + }, + { + "id": "3325", + "name": "Phillipa", + "examine": "A quiet, more reserved sort of lady." + }, + { + "id": "3326", + "name": "Martina Scorsby" + }, + { + "id": "3327", + "name": "Jeremy Clerksin", + "examine": "Rather more tired than most.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3328", + "name": "Tarquin" + }, + { + "id": "3329", + "name": "Sigurd" + }, + { + "id": "3330", + "name": "Hari" + }, + { + "id": "3331", + "name": "Barfy Bill", + "examine": "Looks a little green around the gills.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3332", + "name": "Trees" + }, + { + "id": "3333", + "name": "Trees" + }, + { + "id": "3334", + "name": "Cavemouth", + "examine": "It's made of pure fire.", + "aggressive": "true", + "attack_level": "200", + "attack_speed": "6", + "bonuses": "126,98,86,297,311,304,319,13,284,30,0,0,0,0,0", + "defence_level": "500", + "lifepoints": "1000", + "magic_level": "300", + "range_level": "300", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1500" + }, + { + "id": "3335", + "name": "Bullrush" + }, + { + "id": "3336", + "name": "Bullrush" + }, + { + "id": "3337", + "name": "Cave scenery" + }, + { + "id": "3338", + "name": "Cave scenery" + }, + { + "id": "3339", + "name": "Cave scenery" + }, + { + "id": "3340", + "name": "Giant Mole", + "examine": "Holy Mole-y!", + "attack_level": "200", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,60,80,100,80,60,0,0,0,0,0", + "combat_audio": "1642,1646,1645", + "death_animation": "3310", + "defence_animation": "3311", + "defence_level": "200", + "lifepoints": "200", + "magic_animation": "3312", + "magic_level": "200", + "melee_animation": "3312", + "range_animation": "3312", + "range_level": "1", + "respawn_delay": "56", + "safespot": null, + "strength_level": "200", + "weakness": "7" + }, + { + "id": "3341", + "name": "Baby Mole", + "examine": "I will call him, Mini Mole.", + "aggressive": "false", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3342", + "name": "Baby Mole", + "examine": "Mooooooooooooole." + }, + { + "id": "3343", + "name": "Baby Mole", + "examine": "Moley, moley, moley!" + }, + { + "id": "3344", + "name": "Fungi", + "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3345", + "name": "Fungi", + "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2777", + "defence_animation": "2775", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "2776", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3346", + "name": "Zygomite", + "examine": "A bouncy fungus.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2777", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "2776", + "range_animation": "0", + "range_level": "42", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "1" + }, + { + "id": "3347", + "name": "Zygomite", + "examine": "Have a fungus.", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "2777", + "defence_animation": "2775", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "2776", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3348", + "name": "White Knight", + "attack_level": "1", + "attack_speed": "8", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "7050", + "defence_level": "1", + "lifepoints": "53", + "melee_animation": "7049", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3349", + "name": "White Knight", + "attack_level": "1", + "attack_speed": "8", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "7050", + "defence_level": "1", + "lifepoints": "53", + "melee_animation": "7049", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3350", + "name": "White Knight", + "attack_level": "1", + "attack_speed": "8", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "7050", + "defence_level": "1", + "lifepoints": "53", + "melee_animation": "7049", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3351", + "name": "Genie" + }, + { + "id": "3352", + "name": "Mysterious Old Man" + }, + { + "id": "3353", + "name": "Swarm" + }, + { + "id": "3354", + "name": "Cap'n Hand" + }, + { + "id": "3355", + "name": "Rick Turpentine" + }, + { + "id": "3356", + "name": "Niles" + }, + { + "id": "3357", + "name": "Miles" + }, + { + "id": "3358", + "name": "Giles" + }, + { + "id": "3359", + "name": "Dr Jekyll" + }, + { + "id": "3360", + "name": "Mr Hyde" + }, + { + "id": "3361", + "name": "Mr Hyde" + }, + { + "id": "3362", + "name": "Mr Hyde" + }, + { + "id": "3363", + "name": "Mr Hyde" + }, + { + "id": "3364", + "name": "Mr Hyde" + }, + { + "id": "3365", + "name": "Mr Hyde" + }, + { + "id": "3366", + "name": "Evil Chicken", + "attack_level": "1", + "combat_audio": "355,357,356", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3367", + "name": "Evil Chicken", + "attack_level": "1", + "combat_audio": "355,357,356", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3368", + "name": "Evil Chicken", + "attack_level": "1", + "combat_audio": "355,357,356", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3369", + "name": "Evil Chicken", + "attack_level": "1", + "combat_audio": "355,357,356", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3370", + "name": "Evil Chicken", + "attack_level": "1", + "combat_audio": "355,357,356", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3371", + "name": "Evil Chicken", + "attack_level": "1", + "combat_audio": "355,357,356", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3372", + "name": "Sir Amik Varze" + }, + { + "id": "3373", + "name": "Sir Amik Varze" + }, + { + "id": "3375", + "name": "Evil Chicken", + "examine": "A fowl beast.", + "aggressive": "true", + "attack_level": "55", + "combat_audio": "355,357,356", + "death_animation": "2301", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "117", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "2299", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "3376", + "name": "Baby black dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "50,40,64,60,30,45,40,40,20,40,40,20,0,0,0", + "combat_audio": "405,407,406", + "death_animation": "28", + "defence_animation": "26", + "defence_level": "42", + "lifepoints": "50", + "magic_animation": "25", + "magic_level": "40", + "melee_animation": "25", + "range_animation": "25", + "range_level": "1", + "respawn_delay": "32", + "safespot": null, + "slayer_exp": "0", + "strength_level": "80", + "weakness": "3" + }, + { + "id": "3377", + "name": "K'klik" + }, + { + "id": "3378", + "name": "Evil Dave", + "examine": "He seems to like wearing black.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3379", + "name": "Evil Dave" + }, + { + "id": "3381", + "name": "Doris" + }, + { + "id": "3382", + "name": "Hell-Rat", + "examine": "Vermin from the underworld.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3383", + "name": "Gypsy" + }, + { + "id": "3386", + "name": "Gypsy" + }, + { + "id": "3387", + "name": "Culinaromancer" + }, + { + "id": "3388", + "name": "Osman" + }, + { + "id": "3389", + "name": "Pirate Pete", + "examine": "A shifty-looking character.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3390", + "name": "Mountain Dwarf", + "examine": "He looks short and grumpy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "3391", + "name": "General Wartface", + "examine": "An ugly green creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3392", + "name": "General Bentnoze", + "examine": "An ugly green creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3393", + "name": "Lumbridge Guide", + "examine": "He provides new players with useful information.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3394", + "name": "Evil Dave", + "examine": "He seems to like wearing black.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3395", + "name": "Sir Amik Varze" + }, + { + "id": "3396", + "name": "Awowogei" + }, + { + "id": "3397", + "name": "Awowogei" + }, + { + "id": "3398", + "name": "Skrach Uglogwee" + }, + { + "id": "3399", + "name": "Culinaromancer" + }, + { + "id": "3401", + "name": "An old Dwarf" + }, + { + "id": "3403", + "name": "Rohak" + }, + { + "id": "3404", + "name": "null", + "examine": "Rutmir's assistant.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3406", + "name": "Icefiend", + "examine": "A small ice demon.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "531,533,532", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "171", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "3407", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "25", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "7219", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "7218", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "7" + }, + { + "id": "3408", + "name": "Guard", + "examine": "He tries to keep order around here.", + "attack_level": "25", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "7213", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "583", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "7" + }, + { + "id": "3409", + "name": "Wild jade vine", + "examine": "A sentient plant - ready", + "aggressive": "true", + "attack_level": "65", + "death_animation": "7249", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "185", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7246", + "poison_amount": "35", + "poisonous": "true", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "3410", + "name": "Wild jade vine", + "examine": "A sentient plant - ready", + "aggressive": "true", + "attack_level": "65", + "death_animation": "7249", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "185", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7246", + "poison_amount": "35", + "poisonous": "true", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "3411", + "name": "Wild jade vine", + "examine": "A sentient plant - ready", + "aggressive": "true", + "attack_level": "65", + "death_animation": "7249", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "185", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7246", + "poison_amount": "35", + "poisonous": "true", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "3412", + "name": "Wild jade vine", + "examine": "A sentient plant - ready", + "aggressive": "true", + "attack_level": "65", + "death_animation": "7249", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "185", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7246", + "poison_amount": "35", + "poisonous": "true", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "3413", + "name": "Goblin Cook", + "examine": "He's got funky socks, but he's still an ugly green creature.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3414", + "name": "Goblin Cook", + "examine": "More like a goblin cooked.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3415", + "name": "Goblin Cook", + "examine": "Half way up the wall is maybe not a naturally tenable position for a goblin.", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3416", + "name": "Pirate Pete", + "examine": "He'll store my items for me.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3417", + "name": "Pirate Pete" + }, + { + "id": "3418", + "name": "Pirate Pete", + "examine": "He'll store my items for me.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3419", + "name": "Ogre", + "examine": "Big, ugly, and smelly.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "7", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "27", + "lifepoints": "60", + "melee_animation": "359", + "respawn_delay": "60", + "safespot": null, + "slayer_task": "64", + "strength_level": "27", + "weakness": "8" + }, + { + "id": "3420", + "name": "Mogre Guard", + "examine": "An angry Ogre in a highly amusing hat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3421", + "name": "Crab", + "examine": "Nice claw!", + "attack_level": "22", + "death_animation": "3430", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "3428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "9" + }, + { + "id": "3422", + "name": "Mudskipper", + "examine": "Not the most beautiful fish in the sea.", + "aggressive": "true", + "attack_level": "29", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "241,243,242", + "death_animation": "3435", + "defence_animation": "3434", + "defence_level": "26", + "lifepoints": "20", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "3433", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "10", + "safespot": null, + "strength_level": "29", + "weakness": "9" + }, + { + "id": "3423", + "name": "Mudskipper", + "examine": "Not the most beautiful fish in the sea.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "241,243,242", + "death_animation": "3435", + "defence_animation": "3434", + "defence_level": "29", + "lifepoints": "20", + "magic_level": "1", + "melee_animation": "3433", + "range_level": "1", + "respawn_delay": "5", + "safespot": null, + "strength_level": "30" + }, + { + "id": "3424", + "name": "Crab", + "attack_level": "1", + "death_animation": "3430", + "defence_animation": "3429", + "defence_level": "1", + "lifepoints": "18", + "melee_animation": "3428", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3425", + "name": "Fish", + "examine": "A Red Fantail.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3426", + "name": "Fish", + "examine": "A Red Fantail.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3427", + "name": "Fish", + "examine": "A Red Fantail.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3428", + "name": "Fish" + }, + { + "id": "3429", + "name": "Fish" + }, + { + "id": "3430", + "name": "Fish" + }, + { + "id": "3431", + "name": "Fish", + "examine": "An Angel Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3432", + "name": "Fish", + "examine": "An Angel Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3433", + "name": "Fish", + "examine": "An Angel Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3434", + "name": "Fish", + "examine": "A Harlequin Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3435", + "name": "Fish", + "examine": "A Harlequin Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3436", + "name": "Fish", + "examine": "A Harlequin Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3437", + "name": "Fish", + "examine": "A Discus Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3438", + "name": "Fish", + "examine": "A Discus Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3439", + "name": "Fish", + "examine": "A Discus Fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3440", + "name": "Fish" + }, + { + "id": "3441", + "name": "Fish" + }, + { + "id": "3442", + "name": "Fish" + }, + { + "id": "3443", + "name": "Fish", + "examine": "A shoal of Neon Tetra.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3444", + "name": "Fish", + "examine": "A shoal of Neon Tetra.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3445", + "name": "Fish", + "examine": "A shoal of Neon Tetra.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3446", + "name": "Fish" + }, + { + "id": "3447", + "name": "Fish" + }, + { + "id": "3448", + "name": "Fish" + }, + { + "id": "3449", + "name": "Lumbridge Guide", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "7", + "defence_level": "1", + "lifepoints": "60", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3450", + "name": "null", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "7", + "defence_level": "1", + "lifepoints": "60", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3451", + "name": "Lumbridge Guide", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "7", + "defence_level": "1", + "lifepoints": "60", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3452", + "name": "? ? ? ?" + }, + { + "id": "3453", + "name": "? ? ? ?" + }, + { + "id": "3454", + "name": "? ? ? ?" + }, + { + "id": "3455", + "name": "? ? ? ?" + }, + { + "id": "3456", + "name": "? ? ? ?" + }, + { + "id": "3457", + "name": "? ? ? ?" + }, + { + "id": "3458", + "name": "? ? ? ?" + }, + { + "id": "3459", + "name": "? ? ? ?" + }, + { + "id": "3460", + "name": "? ? ? ?" + }, + { + "id": "3461", + "name": "? ? ? ?" + }, + { + "id": "3462", + "name": "Skrach Uglogwee" + }, + { + "id": "3463", + "name": "Skrach Uglogwee", + "examine": "What restful music!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3464", + "name": "Skrach Uglogwee" + }, + { + "id": "3465", + "name": "Nung" + }, + { + "id": "3466", + "name": "Ogre" + }, + { + "id": "3467", + "name": "Rantz" + }, + { + "id": "3468", + "name": "Rantz" + }, + { + "id": "3469", + "name": "Ogre boat" + }, + { + "id": "3472", + "name": "Ogre boat" + }, + { + "id": "3473", + "name": "Balloon Toad" + }, + { + "id": "3474", + "name": "Balloon Toad" + }, + { + "id": "3475", + "name": "Balloon Toad" + }, + { + "id": "3476", + "name": "Jubbly bird", + "examine": "A large boisterous bird", + "aggressive": "true", + "attack_level": "6", + "death_animation": "6801", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", + "melee_animation": "6800", + "range_animation": "0", + "range_level": "8", + "safespot": null, + "strength_level": "6", + "weakness": "0" + }, + { + "id": "3477", + "name": "Jubbly bird" + }, + { + "id": "3478", + "name": "King Awowogei", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "328", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3479", + "name": "King Awowogei" + }, + { + "id": "3481", + "name": "Mizaru" + }, + { + "id": "3482", + "name": "Kikazaru" + }, + { + "id": "3483", + "name": "Iwazaru" + }, + { + "id": "3484", + "name": "Big Snake", + "examine": "A big snake.", + "aggressive": "true", + "attack_level": "46", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "3538", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "46", + "weakness": "8" + }, + { + "id": "3485", + "name": "Culinaromancer" + }, + { + "id": "3486", + "name": "Culinaromancer" + }, + { + "id": "3487", + "name": "Culinaromancer" + }, + { + "id": "3488", + "name": "Culinaromancer" + }, + { + "id": "3489", + "name": "Culinaromancer" + }, + { + "id": "3490", + "name": "Culinaromancer" + }, + { + "id": "3491", + "name": "Culinaromancer", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "140", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3492", + "name": "Culinaromancer" + }, + { + "id": "3493", + "name": "Agrith-Na-Na", + "aggressive": "true", + "attack_level": "1", + "death_animation": "3503", + "defence_animation": "3500", + "defence_level": "1", + "lifepoints": "200", + "melee_animation": "3501", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3494", + "name": "Flambeed", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1752", + "defence_animation": "1751", + "defence_level": "1", + "lifepoints": "210", + "melee_animation": "1750", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3495", + "name": "Karamel", + "aggressive": "true", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "240", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3496", + "name": "Dessourt", + "aggressive": "true", + "attack_level": "1", + "death_animation": "3510", + "defence_animation": "3505", + "defence_level": "1", + "lifepoints": "140", + "melee_animation": "3507", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3497", + "name": "Gelatinnoth Mother", + "examine": "Deadly AND fruity!", + "aggressive": "true", + "attack_level": "48", + "death_animation": "1342", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "139", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "1341", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "5" + }, + { + "id": "3498", + "name": "Gelatinnoth Mother", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "240", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3499", + "name": "Gelatinnoth Mother", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "240", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3500", + "name": "Gelatinnoth Mother", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "240", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3501", + "name": "Gelatinnoth Mother", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "240", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3502", + "name": "Gelatinnoth Mother", + "aggressive": "true", + "attack_level": "1", + "death_animation": "1342", + "defence_animation": "1340", + "defence_level": "1", + "lifepoints": "240", + "melee_animation": "1341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3503", + "name": "Overgrown hellcat" + }, + { + "id": "3504", + "name": "Hellcat" + }, + { + "id": "3505", + "name": "Hell-kitten" + }, + { + "id": "3506", + "name": "Lazy hellcat" + }, + { + "id": "3507", + "name": "Wily hellcat" + }, + { + "id": "3508", + "name": "Leo" + }, + { + "id": "3509", + "name": "Sorin", + "examine": "Chronicler and regaler of your piratical exploits.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3510", + "name": "Wiskit" + }, + { + "id": "3512", + "name": "Vampyre Juvinate" + }, + { + "id": "3514", + "name": "Vampyre Juvinate", + "examine": "An initiate juvenile vampyre.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3515", + "name": "Vampyre Juvinate" + }, + { + "id": "3516", + "name": "Gadderanks" + }, + { + "id": "3518", + "name": "Gadderanks" + }, + { + "id": "3519", + "name": "Gadderanks" + }, + { + "id": "3520", + "name": "Vampyre Juvinate" + }, + { + "id": "3521", + "name": "Vampyre Juvinate", + "examine": "An initiate juvenile vampyre.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5798", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "5783", + "range_animation": "0", + "range_level": "45", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3522", + "name": "Vampyre Juvinate", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5798", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "5783", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3523", + "name": "Vampyre Juvinate", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5798", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "5783", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3524", + "name": "Vampyre Juvinate", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5798", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "5783", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3525", + "name": "Vampyre Juvinate", + "aggressive": "true", + "attack_level": "1", + "death_animation": "5798", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "5783", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3526", + "name": "Vampyre Juvinate", + "examine": "An initiate juvenile vampyre", + "attack_level": "1", + "death_animation": "6031", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "6016", + "range_animation": "0", + "range_level": "46", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3527", + "name": "Held Vampyre Juvinate", + "examine": "A Juvinate vampyre", + "attack_level": "1", + "death_animation": "5798", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "45", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3528", + "name": "Vampyre Juvinate" + }, + { + "id": "3529", + "name": "Vampyre Juvinate" + }, + { + "id": "3530", + "name": "Mist" + }, + { + "id": "3531", + "name": "Vampyre Juvenile", + "examine": "He looks really hungry!", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "6276", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "3532", + "name": "Vampyre Juvenile", + "examine": "She looks really hungry!", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "6276", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "3533", + "name": "Vampyre Juvenile", + "attack_level": "1", + "death_animation": "6781", + "defence_level": "1", + "lifepoints": "60", + "melee_animation": "6276", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3534", + "name": "Held Vampyre Juvenile", + "examine": "He looks really hungry!", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "3535", + "name": "Ivan Strom" + }, + { + "id": "3536", + "name": "Ivan Strom" + }, + { + "id": "3537", + "name": "Vampyre Juvinate" + }, + { + "id": "3538", + "name": "Vampyre Juvinate" + }, + { + "id": "3539", + "name": "Veliaf Hurtz" + }, + { + "id": "3540", + "name": "Elisabeta" + }, + { + "id": "3541", + "name": "Aurel" + }, + { + "id": "3542", + "name": "Sorin" + }, + { + "id": "3543", + "name": "Luscion" + }, + { + "id": "3544", + "name": "Sergiu" + }, + { + "id": "3545", + "name": "Radu" + }, + { + "id": "3546", + "name": "Grigore" + }, + { + "id": "3547", + "name": "Ileana" + }, + { + "id": "3548", + "name": "Valeria" + }, + { + "id": "3549", + "name": "Emilia" + }, + { + "id": "3550", + "name": "Florin" + }, + { + "id": "3551", + "name": "Catalina" + }, + { + "id": "3552", + "name": "Ivan" + }, + { + "id": "3553", + "name": "Victor" + }, + { + "id": "3554", + "name": "Helena" + }, + { + "id": "3555", + "name": "Teodor" + }, + { + "id": "3556", + "name": "Marius" + }, + { + "id": "3557", + "name": "Gabriela" + }, + { + "id": "3558", + "name": "Vladimir" + }, + { + "id": "3559", + "name": "Calin" + }, + { + "id": "3560", + "name": "Mihail" + }, + { + "id": "3561", + "name": "Nicoleta" + }, + { + "id": "3562", + "name": "Simona" + }, + { + "id": "3563", + "name": "Vasile" + }, + { + "id": "3564", + "name": "Razvan" + }, + { + "id": "3565", + "name": "Luminata" + }, + { + "id": "3566", + "name": "Cornelius" + }, + { + "id": "3569", + "name": "Cornelius" + }, + { + "id": "3570", + "name": "Benjamin" + }, + { + "id": "3571", + "name": "Liam" + }, + { + "id": "3572", + "name": "Miala" + }, + { + "id": "3573", + "name": "Verak" + }, + { + "id": "3574", + "name": "Fishing spot" + }, + { + "id": "3575", + "name": "Fishing spot" + }, + { + "id": "3576", + "name": "Juvinate" + }, + { + "id": "3577", + "name": "Juvinate", + "examine": "An initiate juvenile vampyre", + "attack_level": "1", + "death_animation": "6031", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "6016", + "range_animation": "0", + "range_level": "46", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3578", + "name": "Juvinate" + }, + { + "id": "3579", + "name": "Sheep", + "examine": "Is it a sheep?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3580", + "name": "Tentacle" + }, + { + "id": "3581", + "name": "Skeleton", + "examine": "He guards the dungeon with the faithfulness of the undead.", + "aggressive": "true", + "attack_level": "15", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "17", + "lifepoints": "29", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "70", + "safespot": null, + "strength_level": "18", + "weakness": "8" + }, + { + "id": "3582", + "name": "Guard dog", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "49", + "strength_level": "1" + }, + { + "id": "3583", + "name": "Hobgoblin", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "167", + "defence_animation": "163", + "defence_level": "1", + "lifepoints": "29", + "melee_animation": "164", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3584", + "name": "Troll" + }, + { + "id": "3585", + "name": "Huge spider", + "examine": "No spider could grow that big! It's unrealistic!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "537,539,538", + "death_animation": "5321", + "defence_animation": "0", + "defence_level": "72", + "lifepoints": "122", + "magic_animation": "0", + "melee_animation": "5319", + "range_animation": "0", + "range_level": "72", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "3586", + "name": "Hellhound", + "examine": "Good doggy...", + "aggressive": "true", + "attack_level": "105", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "3717,3719,3718", + "death_animation": "6576", + "defence_animation": "0", + "defence_level": "102", + "lifepoints": "116", + "magic_animation": "0", + "melee_animation": "6562", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "116", + "strength_level": "104", + "weakness": "7" + }, + { + "id": "3587", + "name": "Rantz", + "examine": "Big, ugly, and smelly.", + "aggressive": "true", + "attack_level": "27", + "attack_speed": "6", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "27", + "lifepoints": "60", + "magic_animation": "359", + "magic_level": "27", + "melee_animation": "359", + "range_animation": "359", + "range_level": "27", + "respawn_delay": "25", + "safespot": null, + "strength_level": "27" + }, + { + "id": "3588", + "name": "Baby red dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "20,10,10,20,40,40,20,40,40,20,0,0,0,0,0", + "combat_audio": "405,407,406", + "death_animation": "28", + "defence_animation": "26", + "defence_level": "42", + "lifepoints": "50", + "magic_animation": "25", + "magic_level": "40", + "melee_animation": "25", + "range_animation": "25", + "range_level": "1", + "respawn_delay": "32", + "safespot": null, + "strength_level": "40", + "weakness": "8" + }, + { + "id": "3589", + "name": "Kalphite Soldier", + "examine": "I don't think insect repellent will work...", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "combat_audio": "567,569,568", + "death_animation": "6228", + "defence_animation": "6227", + "defence_level": "70", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6223", + "poison_amount": "20", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "70", + "weakness": "6" + }, + { + "id": "3590", + "name": "Steel dragon", + "examine": "Its scales seem to be made of steel.", + "aggressive": "true", + "attack_level": "234", + "bonuses": "56,42,104,51,212,115,232,302,331,21,264,100,100,40,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "defence_level": "238", + "lifepoints": "210", + "magic_level": "72", + "range_level": "185", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "221", + "strength_level": "229", + "weakness": "8" + }, + { + "id": "3591", + "name": "Dagannoth", + "examine": "A darkened horror from the ocean depths.", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3592", + "name": "Tok-Xil" + }, + { + "id": "3593", + "name": "Demon", + "examine": "Arrgh! Look at its pointy teeth!", + "aggressive": "true", + "attack_level": "75", + "combat_audio": "400,404,403", + "defence_animation": "0", + "defence_level": "75", + "lifepoints": "107", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "75", + "weakness": "7" + }, + { + "id": "3594", + "name": "Rocnar" + }, + { + "id": "3595", + "name": "Toy Soldier" + }, + { + "id": "3596", + "name": "Toy Doll" + }, + { + "id": "3597", + "name": "Toy Mouse" + }, + { + "id": "3598", + "name": "Clockwork cat" + }, + { + "id": "3599", + "name": "Swamp snake", + "examine": "A large snake that thrives in swamps.", + "attack_level": "35", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "3539", + "defence_level": "40", + "lifepoints": "121", + "magic_animation": "3538", + "melee_animation": "3538", + "range_animation": "3538", + "range_level": "45", + "safespot": null, + "strength_level": "33", + "weakness": "0" + }, + { + "id": "3600", + "name": "Swamp snake", + "examine": "A large snake that thrives in swamps.", + "attack_level": "60", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "3539", + "defence_level": "60", + "lifepoints": "121", + "magic_animation": "3538", + "melee_animation": "3538", + "range_animation": "3538", + "range_level": "1", + "safespot": null, + "strength_level": "50" + }, + { + "id": "3601", + "name": "Swamp snake", + "examine": "A large snake that thrives in swamps.", + "attack_level": "35", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "3539", + "defence_level": "40", + "lifepoints": "121", + "magic_animation": "3538", + "melee_animation": "3538", + "range_animation": "3538", + "range_level": "1", + "safespot": null, + "strength_level": "33", + "weakness": "7" + }, + { + "id": "3602", + "name": "Swamp snake", + "examine": "A large snake that thrives in swamps.", + "attack_level": "35", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "3539", + "defence_level": "40", + "lifepoints": "121", + "magic_animation": "3538", + "melee_animation": "3538", + "range_animation": "3538", + "range_level": "1", + "safespot": null, + "strength_level": "33" + }, + { + "id": "3603", + "name": "Dead swamp snake", + "attack_level": "1", + "combat_audio": "3609,3608,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3604", + "name": "Dead swamp snake", + "attack_level": "1", + "combat_audio": "3609,3608,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3605", + "name": "Dead swamp snake", + "attack_level": "1", + "combat_audio": "3609,3608,3610", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3606", + "name": "Ghast" + }, + { + "id": "3607", + "name": "Ghast" + }, + { + "id": "3608", + "name": "Ghast" + }, + { + "id": "3609", + "name": "Ghast" + }, + { + "id": "3610", + "name": "Ghast" + }, + { + "id": "3611", + "name": "Ghast" + }, + { + "id": "3612", + "name": "Giant snail" + }, + { + "id": "3613", + "name": "Giant snail" + }, + { + "id": "3614", + "name": "Giant snail" + }, + { + "id": "3615", + "name": "Riyl shadow" + }, + { + "id": "3616", + "name": "Asyn shadow" + }, + { + "id": "3617", + "name": "Shade" + }, + { + "id": "3618", + "name": "Tentacle", + "examine": "I'm glad I can't see the rest of it!", + "aggressive": "true", + "attack_level": "80", + "death_animation": "3620", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "171", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "3618", + "range_animation": "3618", + "range_level": "80", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "9" + }, + { + "id": "3619", + "name": "Head", + "examine": "I'm glad I can't see the rest of it!", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "10", + "death_animation": "3733", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "171", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "3731", + "range_animation": "0", + "range_level": "80", + "respawn_delay": "60", + "safespot": null, + "strength_level": "85", + "weakness": "9" + }, + { + "id": "3620", + "name": "Head", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "10", + "death_animation": "3733", + "defence_animation": "3732", + "defence_level": "1", + "lifepoints": "150", + "melee_animation": "3731", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3621", + "name": "Tentacle" + }, + { + "id": "3622", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "3623", + "name": "Smiddi Ryak" + }, + { + "id": "3625", + "name": "Rolayne Twickit" + }, + { + "id": "3627", + "name": "Jayene Kliyn" + }, + { + "id": "3629", + "name": "Valantay Eppel" + }, + { + "id": "3631", + "name": "Dalcian Fang" + }, + { + "id": "3633", + "name": "Fyiona Fray" + }, + { + "id": "3634", + "name": "Fyiona Fray", + "examine": "A high-ranking Vyrewatch", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3635", + "name": "Abidor Crank" + }, + { + "id": "3636", + "name": "Spirit tree" + }, + { + "id": "3637", + "name": "Spirit tree" + }, + { + "id": "3638", + "name": "Launa" + }, + { + "id": "3640", + "name": "Launa" + }, + { + "id": "3641", + "name": "Brana" + }, + { + "id": "3642", + "name": "Mawnis Burowgar" + }, + { + "id": "3643", + "name": "Tolna" + }, + { + "id": "3644", + "name": "Tolna" + }, + { + "id": "3645", + "name": "Angry bear", + "examine": "He looks a little on the cross side!", + "attack_level": "38", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "297,299,298", + "death_animation": "4929", + "defence_animation": "4927", + "defence_level": "38", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4927", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "41", + "weakness": "9" + }, + { + "id": "3646", + "name": "Angry unicorn", + "examine": "He looks a little on the cross side!", + "aggressive": "false", + "attack_level": "38", + "attack_speed": "4", + "combat_audio": "876,878,877", + "death_animation": "6377", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "6376", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "41", + "weakness": "9" + }, + { + "id": "3647", + "name": "Angry giant rat", + "examine": "He looks a little on the cross side!", + "attack_level": "25", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "3648", + "name": "Angry goblin", + "examine": "He looks a little on the cross side!", + "attack_level": "25", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "6185", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "3649", + "name": "Fear reaper", + "examine": "AHHHHH!", + "attack_level": "41", + "attack_speed": "4", + "combat_audio": "297,299,298", + "death_animation": "3813", + "defence_animation": "3811", + "defence_level": "40", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "3812", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "41", + "weakness": "" + }, + { + "id": "3650", + "name": "Confusion beast", + "examine": "What on Gielinor is that?!?", + "attack_level": "28", + "death_animation": "3821", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "3818", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "28", + "weakness": "9" + }, + { + "id": "3651", + "name": "Confusion beast" + }, + { + "id": "3652", + "name": "Confusion beast" + }, + { + "id": "3653", + "name": "Confusion beast" + }, + { + "id": "3654", + "name": "Confusion beast" + }, + { + "id": "3655", + "name": "Hopeless creature", + "examine": "A hopeless poor creature.", + "attack_level": "25", + "death_animation": "3827", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "3823", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "3656", + "name": "Hopeless creature" + }, + { + "id": "3657", + "name": "Hopeless creature" + }, + { + "id": "3658", + "name": "Tolna" + }, + { + "id": "3659", + "name": "Tolna" + }, + { + "id": "3660", + "name": "Tolna" + }, + { + "id": "3661", + "name": "Angry unicorn", + "examine": "He looks a little on the cross side!", + "aggressive": "false", + "attack_level": "38", + "attack_speed": "4", + "combat_audio": "876,878,877", + "death_animation": "6377", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "6376", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "41", + "weakness": "9" + }, + { + "id": "3662", + "name": "Angry giant rat", + "examine": "He looks a little on the cross side!", + "attack_level": "38", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "38", + "lifepoints": "50", + "melee_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "41" + }, + { + "id": "3663", + "name": "Angry goblin", + "examine": "He looks a little on the cross side!", + "attack_level": "38", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "38", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "6185", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "41", + "weakness": "9" + }, + { + "id": "3664", + "name": "Angry bear", + "examine": "He looks a little on the cross side!", + "attack_level": "38", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "297,299,298", + "death_animation": "4929", + "defence_animation": "4927", + "defence_level": "38", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "4927", + "range_level": "1", + "safespot": null, + "strength_level": "41" + }, + { + "id": "3665", + "name": "Fear reaper", + "examine": "AHHHHH!", + "attack_level": "45", + "attack_speed": "4", + "bonuses": "", + "combat_audio": "297,299,298", + "death_animation": "3813", + "defence_animation": "3811", + "defence_level": "45", + "lifepoints": "57", + "magic_level": "1", + "melee_animation": "3812", + "range_level": "1", + "safespot": null, + "strength_level": "48" + }, + { + "id": "3666", + "name": "Confusion beast", + "examine": "What on Gielinor is that?!?", + "attack_level": "52", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "297,299,298", + "death_animation": "3821", + "defence_animation": "3820", + "defence_level": "52", + "lifepoints": "64", + "magic_level": "1", + "melee_animation": "3818", + "range_level": "1", + "safespot": null, + "strength_level": "55" + }, + { + "id": "3667", + "name": "Hopeless creature", + "examine": "He looks a little on the cross side!", + "attack_level": "59", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "297,299,298", + "death_animation": "3827", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "71", + "magic_level": "1", + "melee_animation": "3823", + "range_level": "1", + "safespot": null, + "strength_level": "62" + }, + { + "id": "3668", + "name": "Hopeless beast" + }, + { + "id": "3669", + "name": "Hopeless beast" + }, + { + "id": "3670", + "name": "Odd Old Man", + "examine": "That's a lot of bones on his back..." + }, + { + "id": "3671", + "name": "Fortunato", + "examine": "Looks like he could do with a sip of Amontillado." + }, + { + "id": "3672", + "name": "Ram", + "examine": "Freshly sheared.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "757,759,758", + "death_animation": "5343", + "defence_animation": "5337", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "0", + "melee_animation": "5341", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "3673", + "name": "Ram", + "examine": "White and fluffy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "757,759,758", + "death_animation": "5336", + "defence_animation": "5337", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "0", + "melee_animation": "5338", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "3674", + "name": "Sack" + }, + { + "id": "3675", + "name": "Vulture", + "examine": "If you see them circling, run.", + "attack_level": "40", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "890,892,891", + "death_animation": "2021", + "defence_animation": "2024", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "2019", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "40", + "weakness": "9" + }, + { + "id": "3676", + "name": "Vulture", + "examine": "If you see them circling, run.", + "attack_level": "40", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "890,892,891", + "death_animation": "2026", + "defence_animation": "2024", + "defence_level": "10", + "lifepoints": "10", + "magic_level": "1", + "melee_animation": "2025", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3677", + "name": "Sinister Stranger" + }, + { + "id": "3678", + "name": "Sinister Stranger" + }, + { + "id": "3679", + "name": "Vestri" + }, + { + "id": "3680", + "name": "Ali the Leaflet Dropper", + "examine": "A young boy handing out flyers.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3681", + "name": "Nigel" + }, + { + "id": "3682", + "name": "Egg" + }, + { + "id": "3683", + "name": "Egg" + }, + { + "id": "3684", + "name": "Egg" + }, + { + "id": "3685", + "name": "Egg" + }, + { + "id": "3686", + "name": "Chocolate kebbit" + }, + { + "id": "3687", + "name": "Chocolate kebbit" + }, + { + "id": "3688", + "name": "Easter Bunny" + }, + { + "id": "3689", + "name": "Egg" + }, + { + "id": "3690", + "name": "Egg" + }, + { + "id": "3691", + "name": "Egg" + }, + { + "id": "3692", + "name": "Egg" + }, + { + "id": "3693", + "name": "Egg" + }, + { + "id": "3694", + "name": "Egg" + }, + { + "id": "3695", + "name": "Volf Olafson" + }, + { + "id": "3696", + "name": "Ingrid Hradson" + }, + { + "id": "3697", + "name": "Skeleton fremennik", + "examine": "Could use a good meal.", + "attack_level": "17", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "17", + "lifepoints": "24", + "magic_animation": "0", + "melee_animation": "6128", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "17", + "weakness": "6" + }, + { + "id": "3698", + "name": "Skeleton fremennik", + "attack_level": "1", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3699", + "name": "Skeleton fremennik", + "attack_level": "1", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3700", + "name": "Skeleton fremennik", + "examine": "He seems a little underweight.", + "attack_level": "20", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "6128", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "20", + "weakness": "6" + }, + { + "id": "3701", + "name": "Skeleton fremennik", + "examine": "He seems a little underweight.", + "attack_level": "20", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "6128", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "20", + "weakness": "6" + }, + { + "id": "3702", + "name": "Skeleton fremennik", + "attack_level": "1", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "35", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3703", + "name": "Skeleton fremennik", + "examine": "He seems a little underweight.", + "attack_level": "22", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "6128", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" + }, + { + "id": "3704", + "name": "Skeleton fremennik", + "examine": "He seems a little underweight.", + "attack_level": "22", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "6128", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "6" + }, + { + "id": "3705", + "name": "Skeleton fremennik", + "attack_level": "1", + "combat_audio": "774,775,777", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "5485", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3706", + "name": "Ulfric", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "60", + "melee_animation": "6118", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3707", + "name": "Brine rat", + "examine": "Eww", + "attack_level": "35", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "6115", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "6117", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "50", + "strength_level": "35", + "weakness": "9" + }, + { + "id": "3708", + "name": "Boulder" + }, + { + "id": "3709", + "name": "Boulder", + "examine": "A Wilderness fighter of massive repute.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3710", + "name": "Ulfric" + }, + { + "id": "3711", + "name": "Giant bat", + "examine": "An annoying flappy thing.", + "aggressive": "true", + "attack_level": "12", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "combat_audio": "292,294,293", + "death_animation": "4917", + "defence_animation": "4916", + "defence_level": "22", + "lifepoints": "32", + "magic_animation": "4915", + "magic_level": "1", + "melee_animation": "4915", + "range_animation": "4915", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "8", + "strength_level": "22", + "weakness": "4" + }, + { + "id": "3712", + "name": "Zanik" + }, + { + "id": "3713", + "name": "Sigmund" + }, + { + "id": "3714", + "name": "Zanik" + }, + { + "id": "3715", + "name": "Guard", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3716", + "name": "Sigmund" + }, + { + "id": "3717", + "name": "Sigmund" + }, + { + "id": "3718", + "name": "Sigmund" + }, + { + "id": "3719", + "name": "Sigmund" + }, + { + "id": "3720", + "name": "Sigmund" + }, + { + "id": "3721", + "name": "Zanik" + }, + { + "id": "3722", + "name": "Zanik" + }, + { + "id": "3723", + "name": "General Bentnoze" + }, + { + "id": "3724", + "name": "General Wartface" + }, + { + "id": "3725", + "name": "Grubfoot" + }, + { + "id": "3726", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "3727", + "name": "Splatter", + "examine": "Don't burst its bubble!", + "attack_level": "20", + "bonuses": "5,10,10,10,10,2,0,0,0,0,0,0,0,0,0", + "combat_audio": "809,811,810", + "death_animation": "3888", + "defence_animation": "3890", + "defence_level": "20", + "lifepoints": "13", + "magic_animation": "3891", + "magic_level": "5", + "melee_animation": "3891", + "range_animation": "3891", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "20", + "weakness": "8" + }, + { + "id": "3728", + "name": "Splatter", + "examine": "Don't burst its bubble!", + "attack_level": "25", + "bonuses": "10,15,15,15,15,5,0,0,0,0,0,0,0,0,0", + "combat_audio": "809,811,810", + "death_animation": "3888", + "defence_animation": "3890", + "defence_level": "25", + "lifepoints": "23", + "magic_animation": "3891", + "magic_level": "10", + "melee_animation": "3891", + "range_animation": "3891", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "25" + }, + { + "id": "3729", + "name": "Splatter", + "examine": "Don't burst its bubble!", + "attack_level": "30", + "bonuses": "15,20,20,20,20,8,0,0,0,0,0,0,0,0,0", + "combat_audio": "809,811,810", + "death_animation": "3888", + "defence_animation": "3890", + "defence_level": "30", + "lifepoints": "23", + "magic_animation": "3891", + "magic_level": "10", + "melee_animation": "3891", + "range_animation": "3891", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "30" + }, + { + "id": "3730", + "name": "Splatter", + "examine": "Don't burst its bubble!", + "attack_level": "35", + "bonuses": "20,25,25,25,25,10,0,0,0,0,0,0,0,0,0", + "combat_audio": "809,811,810", + "death_animation": "3888", + "defence_animation": "3890", + "defence_level": "35", + "lifepoints": "23", + "magic_animation": "3891", + "magic_level": "15", + "melee_animation": "3891", + "range_animation": "3891", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "35" + }, + { + "id": "3731", + "name": "Splatter", + "examine": "Don't burst its bubble!", + "attack_level": "40", + "bonuses": "25,30,30,30,30,15,0,0,0,0,0,0,0,0,0", + "combat_audio": "809,811,810", + "death_animation": "3888", + "defence_animation": "3890", + "defence_level": "40", + "lifepoints": "23", + "magic_animation": "3891", + "magic_level": "20", + "melee_animation": "3891", + "range_animation": "3891", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3732", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "28", + "bonuses": "20,25,20,40,40,40,40,5,18,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "28", + "lifepoints": "23", + "magic_animation": "3901", + "magic_level": "14", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "28", + "weakness": "9" + }, + { + "id": "3733", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "28", + "bonuses": "20,25,20,40,40,40,40,5,18,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "28", + "lifepoints": "23", + "magic_animation": "3901", + "magic_level": "14", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "28" + }, + { + "id": "3734", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "42", + "bonuses": "30,35,30,50,50,50,50,10,15,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "42", + "lifepoints": "38", + "magic_animation": "3901", + "magic_level": "20", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "42" + }, + { + "id": "3735", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "42", + "bonuses": "30,35,30,50,50,50,50,10,15,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "42", + "lifepoints": "38", + "magic_animation": "3901", + "magic_level": "20", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "42" + }, + { + "id": "3736", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "54", + "bonuses": "35,40,35,60,60,60,60,20,15,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "54", + "lifepoints": "53", + "magic_animation": "3901", + "magic_level": "25", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "54" + }, + { + "id": "3737", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "54", + "bonuses": "35,40,35,60,60,60,60,20,15,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "54", + "lifepoints": "53", + "magic_animation": "3901", + "magic_level": "25", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "54" + }, + { + "id": "3738", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,50,40,70,70,70,70,30,15,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "60", + "lifepoints": "68", + "magic_animation": "3901", + "magic_level": "30", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "60" + }, + { + "id": "3739", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "60", + "bonuses": "40,50,40,70,70,70,70,30,15,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "60", + "lifepoints": "68", + "magic_animation": "3901", + "magic_level": "30", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "60" + }, + { + "id": "3740", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "70", + "bonuses": "50,60,50,80,70,90,80,35,14,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "70", + "lifepoints": "83", + "magic_animation": "3901", + "magic_level": "35", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "70" + }, + { + "id": "3741", + "name": "Shifter", + "examine": "Nippy little thing!", + "aggressive": "true", + "attack_level": "70", + "bonuses": "50,60,50,80,70,90,80,35,14,0,0,0,0,0,0", + "combat_audio": "766,768,767", + "death_animation": "3903", + "defence_animation": "3902", + "defence_level": "70", + "lifepoints": "83", + "magic_animation": "3901", + "magic_level": "35", + "melee_animation": "3901", + "poison_immune": "true", + "range_animation": "3901", + "range_level": "1", + "respawn_delay": "127", + "safespot": null, + "strength_level": "70" + }, + { + "id": "3742", + "name": "Ravager", + "examine": "Worse than termites!", + "attack_level": "15", + "attack_speed": "5", + "bonuses": "45,45,45,45,50,5,45,0,0,0,0,0,0,0,0", + "combat_audio": "714,716,715", + "death_animation": "3917", + "defence_animation": "3916", + "defence_level": "15", + "lifepoints": "23", + "magic_animation": "3915", + "magic_level": "10", + "melee_animation": "3915", + "range_animation": "3915", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "30", + "weakness": "7" + }, + { + "id": "3743", + "name": "Ravager", + "examine": "Worse than termites!", + "attack_level": "20", + "attack_speed": "5", + "bonuses": "45,45,45,45,50,5,55,0,0,0,0,0,0,0,0", + "combat_audio": "714,716,715", + "death_animation": "3917", + "defence_animation": "3916", + "defence_level": "20", + "lifepoints": "38", + "magic_animation": "3915", + "magic_level": "15", + "melee_animation": "3915", + "range_animation": "3915", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3744", + "name": "Ravager", + "examine": "Worse than termites!", + "attack_level": "30", + "attack_speed": "5", + "bonuses": "45,55,55,55,50,10,45,0,0,0,0,0,0,0,0", + "combat_audio": "714,716,715", + "death_animation": "3917", + "defence_animation": "3916", + "defence_level": "30", + "lifepoints": "53", + "magic_animation": "3915", + "magic_level": "20", + "melee_animation": "3915", + "range_animation": "3915", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "60" + }, + { + "id": "3745", + "name": "Ravager", + "examine": "Worse than termites!", + "attack_level": "45", + "attack_speed": "5", + "bonuses": "60,60,60,60,80,10,45,0,0,0,0,0,0,0,0", + "combat_audio": "714,716,715", + "death_animation": "3917", + "defence_animation": "3916", + "defence_level": "45", + "lifepoints": "53", + "magic_animation": "3915", + "magic_level": "30", + "melee_animation": "3915", + "range_animation": "3915", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "75" + }, + { + "id": "3746", + "name": "Ravager", + "examine": "Worse than termites!", + "attack_level": "60", + "attack_speed": "5", + "bonuses": "65,70,70,70,90,20,56,0,0,0,0,0,0,0,0", + "combat_audio": "714,716,715", + "death_animation": "3917", + "defence_animation": "3916", + "defence_level": "60", + "lifepoints": "53", + "magic_animation": "3915", + "magic_level": "40", + "melee_animation": "3915", + "range_animation": "3915", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "80" + }, + { + "id": "3747", + "name": "Spinner", + "examine": "Eeewww!", + "attack_level": "20", + "bonuses": "20,40,40,40,40,10,38,0,0,0,0,0,0,0,0", + "combat_audio": "805,807,806", + "death_animation": "3910", + "defence_animation": "3909", + "defence_level": "20", + "lifepoints": "33", + "magic_animation": "3908", + "magic_level": "10", + "melee_animation": "3908", + "range_animation": "3908", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "20", + "weakness": "6" + }, + { + "id": "3748", + "name": "Spinner", + "examine": "Eeewww!", + "attack_level": "30", + "bonuses": "30,60,60,60,60,15,38,0,0,0,0,0,0,0,0", + "combat_audio": "805,807,806", + "death_animation": "3910", + "defence_animation": "3909", + "defence_level": "30", + "lifepoints": "50", + "magic_animation": "3908", + "magic_level": "15", + "melee_animation": "3908", + "range_animation": "3908", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "30" + }, + { + "id": "3749", + "name": "Spinner", + "examine": "Eeewww!", + "attack_level": "40", + "bonuses": "50,70,70,70,70,20,38,0,0,0,0,0,0,0,0", + "combat_audio": "805,807,806", + "death_animation": "3910", + "defence_animation": "3909", + "defence_level": "40", + "lifepoints": "67", + "magic_animation": "3908", + "magic_level": "20", + "melee_animation": "3908", + "range_animation": "3908", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "40" + }, + { + "id": "3750", + "name": "Spinner", + "examine": "Eeewww!", + "attack_level": "60", + "bonuses": "60,100,100,100,100,30,25,0,0,0,0,0,0,0,0", + "combat_audio": "805,807,806", + "death_animation": "3910", + "defence_animation": "3909", + "defence_level": "60", + "lifepoints": "101", + "magic_animation": "3908", + "magic_level": "30", + "melee_animation": "3908", + "range_animation": "3908", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "60" + }, + { + "id": "3751", + "name": "Spinner", + "examine": "Eeewww!", + "attack_level": "50", + "bonuses": "55,80,80,80,85,25,30,0,0,0,0,0,0,0,0", + "combat_audio": "805,807,806", + "death_animation": "3910", + "defence_animation": "3909", + "defence_level": "50", + "lifepoints": "84", + "magic_animation": "3908", + "magic_level": "25", + "melee_animation": "3908", + "range_animation": "3908", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "50" + }, + { + "id": "3752", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "30,30,30,30,15,30,40,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "25", + "end_gfx": "648", + "lifepoints": "18", + "magic_animation": "3882", + "magic_level": "25", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "3753", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "30,30,30,30,15,30,40,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "25", + "end_gfx": "648", + "lifepoints": "18", + "magic_animation": "3882", + "magic_level": "25", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3754", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "45,40,40,40,25,35,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "40", + "end_gfx": "648", + "lifepoints": "30", + "magic_animation": "3882", + "magic_level": "40", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3755", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "45,40,40,40,25,35,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "40", + "end_gfx": "648", + "lifepoints": "30", + "magic_animation": "3882", + "magic_level": "40", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3756", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "35,40,40,40,30,35,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "50", + "end_gfx": "648", + "lifepoints": "42", + "magic_animation": "3882", + "magic_level": "50", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3757", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "35,40,40,40,30,35,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "50", + "end_gfx": "648", + "lifepoints": "42", + "magic_animation": "3882", + "magic_level": "50", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3758", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,80,80,80,50,50,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "60", + "end_gfx": "648", + "lifepoints": "51", + "magic_animation": "3882", + "magic_level": "60", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3759", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,80,80,80,50,50,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "60", + "end_gfx": "648", + "lifepoints": "51", + "magic_animation": "3882", + "magic_level": "60", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3760", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "40,100,100,100,50,50,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "70", + "end_gfx": "648", + "lifepoints": "62", + "magic_animation": "3882", + "magic_level": "70", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3761", + "name": "Torcher", + "examine": "Burn, baby, burn!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "40,100,100,100,50,50,35,0,0,0,0,0,0,0,0", + "combat_audio": "845,848,846", + "combat_style": "2", + "death_animation": "3881", + "defence_animation": "3880", + "defence_level": "70", + "end_gfx": "648", + "lifepoints": "62", + "magic_animation": "3882", + "magic_level": "70", + "melee_animation": "3882", + "projectile": "647", + "range_animation": "3882", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "646", + "strength_level": "1" + }, + { + "id": "3762", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "20,40,40,40,40,40,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "25", + "lifepoints": "27", + "magic_animation": "3920", + "magic_level": "30", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "25", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "657", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "3763", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "20,40,40,40,40,40,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "25", + "lifepoints": "27", + "magic_animation": "3920", + "magic_level": "30", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "25", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3764", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "30,50,60,60,60,60,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "40", + "lifepoints": "45", + "magic_animation": "3920", + "magic_level": "40", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "40", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "657", + "strength_level": "1" + }, + { + "id": "3765", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "30,40,60,60,60,60,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "40", + "lifepoints": "45", + "magic_animation": "3920", + "magic_level": "40", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "40", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3766", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "35,65,70,70,70,70,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "50", + "lifepoints": "62", + "magic_animation": "3920", + "magic_level": "50", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "50", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "657", + "strength_level": "1" + }, + { + "id": "3767", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "35,65,70,70,70,70,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "50", + "lifepoints": "62", + "magic_animation": "3920", + "magic_level": "50", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "50", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3768", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "40,90,80,80,80,80,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "60", + "lifepoints": "78", + "magic_animation": "3920", + "magic_level": "60", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "60", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "657", + "strength_level": "1" + }, + { + "id": "3769", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "40,90,80,80,80,80,40,40,0,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "60", + "lifepoints": "78", + "magic_animation": "3920", + "magic_level": "60", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "60", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3770", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "50,100,100,100,120,100,40,40,80,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "70", + "lifepoints": "97", + "magic_animation": "3920", + "magic_level": "70", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "70", + "respawn_delay": "120", + "safespot": null, + "start_gfx": "657", + "strength_level": "1" + }, + { + "id": "3771", + "name": "Defiler", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "1", + "bonuses": "50,100,100,100,120,100,40,40,80,0,0,0,0,0,0", + "combat_audio": "392,394,393", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "3921", + "defence_level": "70", + "lifepoints": "97", + "magic_animation": "3920", + "magic_level": "70", + "melee_animation": "3920", + "projectile": "657", + "range_animation": "3920", + "range_level": "70", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3772", + "name": "Brawler", + "examine": "Mind your toes!", + "aggressive": "true", + "attack_level": "28", + "bonuses": "45,45,50,50,50,50,50,15,50,0,0,0,0,0,0", + "combat_audio": "323,326,325", + "death_animation": "3894", + "defence_animation": "3895", + "defence_level": "28", + "lifepoints": "53", + "magic_animation": "3896", + "magic_level": "14", + "melee_animation": "3896", + "range_animation": "3896", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "28", + "weakness": "9" + }, + { + "id": "3773", + "name": "Brawler", + "examine": "Mind your toes!", + "aggressive": "true", + "attack_level": "42", + "bonuses": "45,45,60,50,50,50,50,15,50,0,0,0,0,0,0", + "combat_audio": "323,326,325", + "death_animation": "3894", + "defence_animation": "3895", + "defence_level": "42", + "lifepoints": "83", + "magic_animation": "3896", + "magic_level": "21", + "melee_animation": "3896", + "range_animation": "3896", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "42" + }, + { + "id": "3774", + "name": "Brawler", + "examine": "Mind your toes!", + "aggressive": "true", + "attack_level": "56", + "bonuses": "45,45,60,80,80,80,80,25,50,0,0,0,0,0,0", + "combat_audio": "323,326,325", + "death_animation": "3894", + "defence_animation": "3895", + "defence_level": "56", + "lifepoints": "113", + "magic_animation": "3896", + "magic_level": "32", + "melee_animation": "3896", + "range_animation": "3896", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "56" + }, + { + "id": "3775", + "name": "Brawler", + "examine": "Mind your toes!", + "aggressive": "true", + "attack_level": "74", + "bonuses": "45,45,60,60,60,60,60,20,50,0,0,0,0,0,0", + "combat_audio": "323,326,325", + "death_animation": "3894", + "defence_animation": "3895", + "defence_level": "74", + "lifepoints": "143", + "magic_animation": "3896", + "magic_level": "38", + "melee_animation": "3896", + "range_animation": "3896", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "74" + }, + { + "id": "3776", + "name": "Brawler", + "examine": "Mind your toes!", + "aggressive": "true", + "attack_level": "88", + "bonuses": "45,45,80,100,100,100,100,30,46,0,0,0,0,0,0", + "combat_audio": "323,326,325", + "death_animation": "3894", + "defence_animation": "3895", + "defence_level": "88", + "lifepoints": "173", + "magic_animation": "3896", + "magic_level": "45", + "melee_animation": "3896", + "range_animation": "3896", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "88" + }, + { + "id": "3777", + "name": "Doomsayer", + "examine": "Cheerful, helpful and optimistic, I'll bet.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3778", + "name": "Arthur" + }, + { + "id": "3780", + "name": "Squire" + }, + { + "id": "3782", + "name": "Void Knight", + "examine": "A squire of balance.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "180,180,180,180,80,0,0,0,0,0,0,0,0,0,0", + "defence_level": "80", + "lifepoints": "200", + "magic_level": "80", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3783", + "name": "Frog", + "examine": "Long legged licker.", + "attack_level": "55", + "death_animation": "7256", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "7260", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "3784", + "name": "Void Knight", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "0", + "defence_level": "1", + "lifepoints": "200", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3785", + "name": "Void Knight", + "examine": "A squire of balance.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "180,180,180,180,80,0,0,0,0,0,0,0,0,0,0", + "defence_level": "80", + "lifepoints": "200", + "magic_level": "80", + "range_level": "1", + "respawn_delay": "120", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3786", + "name": "Void Knight", + "examine": "A powerful knight of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3787", + "name": "Sir Palomedes" + }, + { + "id": "3788", + "name": "Void Knight", + "examine": "A powerful knight of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3789", + "name": "Void Knight" + }, + { + "id": "3790", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3791", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3792", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3793", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3794", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3795", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3796", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3797", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3798", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3799", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3800", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3801", + "name": "Squire", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3802", + "name": "Squire (Novice)", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3803", + "name": "Fishing spot" + }, + { + "id": "3805", + "name": "Postie Pete", + "examine": "Posts things.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3806", + "name": "Millie Miller", + "examine": "Miss Millicent Miller the Miller of Mill Lane Mill.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3807", + "name": "Gillie Groats", + "examine": "Gillie the Milkmaid milks cows. She's udderly fantastic at it.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3808", + "name": "Tortoise", + "examine": "Massive beast of War with extra Gnome.", + "attack_level": "36", + "death_animation": "3962", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "121", + "magic_animation": "0", + "melee_animation": "3960", + "range_animation": "3954", + "range_level": "1", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "3809", + "name": "Captain Dalbur", + "examine": "Tally Ho!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3810", + "name": "Captain Bleemadge", + "examine": "Huzzah!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3811", + "name": "Captain Errdo", + "examine": "Up up and away!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3812", + "name": "Captain Klemfoodle", + "examine": "Up up and away!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3814", + "name": "Gnome Archer", + "examine": "A Gnome Arrow-chucker", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "190", + "prj_height": "30", + "projectile": "10", + "range_animation": "190", + "range_level": "5", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "2" + }, + { + "id": "3815", + "name": "Gnome Driver", + "examine": "Yee haa!", + "aggressive": "true", + "attack_level": "5", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "3969", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "3816", + "name": "Gnome Mage", + "examine": "A battle mage of the gnomish variety.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "death_animation": "196", + "defence_animation": "193", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "200", + "magic_level": "5", + "melee_animation": "3968", + "prj_height": "30", + "projectile": "94", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "spell_id": "", + "start_gfx": "93", + "start_height": "80", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "3817", + "name": "Lieutenant Schepbur" + }, + { + "id": "3818", + "name": "Trainer Nacklepen", + "examine": "The cruel tortoise trainer. Boo!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3819", + "name": "Tortoise", + "examine": "A large tortoise.", + "attack_level": "36", + "death_animation": "3962", + "defence_animation": "0", + "defence_level": "36", + "lifepoints": "101", + "magic_animation": "0", + "melee_animation": "3960", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "36", + "weakness": "6" + }, + { + "id": "3820", + "name": "Wise Old Man" + }, + { + "id": "3822", + "name": "Herman Caranos", + "examine": "Founder and Director of the Piscatoris Fishing Colony." + }, + { + "id": "3823", + "name": "Franklin Caranos", + "examine": "Engineer for the Piscatoris Fishing Colony." + }, + { + "id": "3824", + "name": "Arnold Lydspor", + "examine": "Secretary and Storemaster for the Piscatoris Fishing Colony." + }, + { + "id": "3825", + "name": "Devin Mendelberg" + }, + { + "id": "3826", + "name": "George Laxmeister" + }, + { + "id": "3827", + "name": "Ramara du Croissant" + }, + { + "id": "3828", + "name": "Kathy Corkat" + }, + { + "id": "3831", + "name": "Kathy Corkat" + }, + { + "id": "3832", + "name": "Kalphite Queen" + }, + { + "id": "3835", + "name": "Kalphite Queen", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "6242", + "defence_animation": "6240", + "defence_level": "1", + "lifepoints": "255", + "melee_animation": "6241", + "range_level": "1000", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3836", + "name": "Kalphite Queen", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "6233", + "defence_animation": "6237", + "defence_level": "1", + "lifepoints": "255", + "melee_animation": "6234", + "range_level": "1000", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3837", + "name": "Drunken Dwarf" + }, + { + "id": "3838", + "name": "Wise Old Man" + }, + { + "id": "3839", + "name": "Wise Old Man" + }, + { + "id": "3840", + "name": "Sea troll", + "examine": "An aquatic troll.", + "aggressive": "true", + "attack_level": "45", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "45", + "weakness": "6" + }, + { + "id": "3841", + "name": "Sea troll" + }, + { + "id": "3842", + "name": "Sea troll" + }, + { + "id": "3843", + "name": "Sea troll", + "examine": "An aquatic troll.", + "aggressive": "true", + "attack_level": "60", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "60", + "weakness": "6" + }, + { + "id": "3844", + "name": "Skeleton Mage" + }, + { + "id": "3845", + "name": "Sea troll" + }, + { + "id": "3846", + "name": "Sea Troll General" + }, + { + "id": "3847", + "name": "Sea Troll Queen", + "examine": "The mother of all sea trolls!", + "aggressive": "true", + "attack_level": "65", + "death_animation": "3993", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "428", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "3991", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "3848", + "name": "Fishing spot" + }, + { + "id": "3849", + "name": "Fishing spot", + "examine": "What have they done to him?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3850", + "name": "Skeleton Mage" + }, + { + "id": "3851", + "name": "Skeleton Mage", + "examine": "Doesn't seem to want to go away.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "80", + "magic_animation": "811", + "magic_level": "100", + "melee_animation": "811", + "range_animation": "811", + "range_level": "1", + "strength_level": "10" + }, + { + "id": "3852", + "name": "Suspect" + }, + { + "id": "3853", + "name": "Suspect" + }, + { + "id": "3854", + "name": "Suspect" + }, + { + "id": "3855", + "name": "Suspect" + }, + { + "id": "3856", + "name": "Suspect" + }, + { + "id": "3857", + "name": "Suspect" + }, + { + "id": "3858", + "name": "Suspect" + }, + { + "id": "3859", + "name": "Suspect" + }, + { + "id": "3860", + "name": "Suspect" + }, + { + "id": "3861", + "name": "Suspect" + }, + { + "id": "3862", + "name": "Suspect" + }, + { + "id": "3863", + "name": "Suspect" + }, + { + "id": "3864", + "name": "Suspect" + }, + { + "id": "3865", + "name": "Suspect" + }, + { + "id": "3866", + "name": "Suspect" + }, + { + "id": "3867", + "name": "Suspect" + }, + { + "id": "3868", + "name": "Suspect" + }, + { + "id": "3869", + "name": "Suspect" + }, + { + "id": "3870", + "name": "Suspect" + }, + { + "id": "3871", + "name": "Suspect" + }, + { + "id": "3872", + "name": "Suspect" + }, + { + "id": "3873", + "name": "Suspect" + }, + { + "id": "3874", + "name": "Suspect" + }, + { + "id": "3875", + "name": "Suspect" + }, + { + "id": "3876", + "name": "Suspect" + }, + { + "id": "3877", + "name": "Suspect" + }, + { + "id": "3878", + "name": "Suspect" + }, + { + "id": "3879", + "name": "Suspect" + }, + { + "id": "3880", + "name": "Suspect" + }, + { + "id": "3881", + "name": "Suspect" + }, + { + "id": "3882", + "name": "Suspect" + }, + { + "id": "3883", + "name": "Suspect" + }, + { + "id": "3884", + "name": "Suspect" + }, + { + "id": "3885", + "name": "Suspect" + }, + { + "id": "3886", + "name": "Suspect" + }, + { + "id": "3887", + "name": "Suspect" + }, + { + "id": "3888", + "name": "Suspect" + }, + { + "id": "3889", + "name": "Suspect" + }, + { + "id": "3890", + "name": "Suspect" + }, + { + "id": "3891", + "name": "Suspect" + }, + { + "id": "3892", + "name": "Molly" + }, + { + "id": "3893", + "name": "Molly" + }, + { + "id": "3894", + "name": "Molly" + }, + { + "id": "3895", + "name": "Molly" + }, + { + "id": "3896", + "name": "Molly" + }, + { + "id": "3897", + "name": "Molly" + }, + { + "id": "3898", + "name": "Molly" + }, + { + "id": "3899", + "name": "Molly" + }, + { + "id": "3900", + "name": "Molly" + }, + { + "id": "3901", + "name": "Molly" + }, + { + "id": "3902", + "name": "Molly" + }, + { + "id": "3903", + "name": "Molly" + }, + { + "id": "3904", + "name": "Molly" + }, + { + "id": "3905", + "name": "Molly" + }, + { + "id": "3906", + "name": "Molly" + }, + { + "id": "3907", + "name": "Molly" + }, + { + "id": "3908", + "name": "Molly" + }, + { + "id": "3909", + "name": "Molly" + }, + { + "id": "3910", + "name": "Molly" + }, + { + "id": "3911", + "name": "Molly" + }, + { + "id": "3912", + "name": "Flippa" + }, + { + "id": "3913", + "name": "Tilt" + }, + { + "id": "3914", + "name": "Gardener" + }, + { + "id": "3915", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "7", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "3916", + "name": "Carpenter Kjallak", + "examine": "His bark's worse than his blight.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3917", + "name": "Farmer Fromund", + "examine": "He looks a bit seedy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3918", + "name": "Prince Brand" + }, + { + "id": "3919", + "name": "Princess Astrid" + }, + { + "id": "3920", + "name": "Runa" + }, + { + "id": "3921", + "name": "Halla", + "examine": "A subject of Miscellania." + }, + { + "id": "3922", + "name": "Finn", + "examine": "Runs the general store." + }, + { + "id": "3923", + "name": "Osvald" + }, + { + "id": "3924", + "name": "Runolf" + }, + { + "id": "3925", + "name": "Tjorvi", + "examine": "A subject of Miscellania." + }, + { + "id": "3926", + "name": "Ingrid" + }, + { + "id": "3927", + "name": "Thora", + "examine": "A subject of Miscellania." + }, + { + "id": "3928", + "name": "Signy" + }, + { + "id": "3929", + "name": "Hild" + }, + { + "id": "3930", + "name": "Armod" + }, + { + "id": "3931", + "name": "Beigarth" + }, + { + "id": "3932", + "name": "Reinn" + }, + { + "id": "3933", + "name": "Alviss", + "examine": "A dwarf who's currently living in Miscellania." + }, + { + "id": "3934", + "name": "Fullangr", + "examine": "A dwarf who's currently living in Miscellania." + }, + { + "id": "3935", + "name": "Jari", + "examine": "A dwarf who's currently living in Miscellania." + }, + { + "id": "3936", + "name": "Thorodin" + }, + { + "id": "3937", + "name": "Ferd", + "examine": "A dwarf miner. He's shoring up the walls." + }, + { + "id": "3938", + "name": "Donal", + "examine": "A rather scared-looking dwarf. He doesn't seem all that drunk." + }, + { + "id": "3939", + "name": "Sea Snake Young", + "examine": "Snake", + "aggressive": "true", + "attack_level": "33", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "128", + "magic_animation": "0", + "melee_animation": "3538", + "range_animation": "0", + "range_level": "45", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "1" + }, + { + "id": "3940", + "name": "Sea Snake Hatchling", + "examine": "A baby sea snake. Snaaaaaaake!", + "aggressive": "true", + "attack_level": "33", + "combat_audio": "3609,3608,3610", + "death_animation": "3540", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "3538", + "range_animation": "0", + "range_level": "45", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "1" + }, + { + "id": "3941", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3942", + "name": "Guard", + "examine": "He's guarding the entrance to the dungeons.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "3943", + "name": "Giant Sea Snake", + "examine": "A big snake that lives in the sea. How did it get in here?", + "aggressive": "true", + "attack_level": "33", + "combat_audio": "3609,3608,3610", + "death_animation": "4039", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "385", + "magic_animation": "0", + "melee_animation": "4040", + "range_animation": "0", + "range_level": "45", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "1" + }, + { + "id": "3944", + "name": "Hangman game" + }, + { + "id": "3945", + "name": "Hangman game" + }, + { + "id": "3946", + "name": "Hangman game" + }, + { + "id": "3947", + "name": "Hangman game" + }, + { + "id": "3948", + "name": "Hangman game" + }, + { + "id": "3949", + "name": "Hangman game" + }, + { + "id": "3950", + "name": "Hangman game" + }, + { + "id": "3951", + "name": "Hangman game" + }, + { + "id": "3952", + "name": "Hangman game" + }, + { + "id": "3953", + "name": "Hangman game" + }, + { + "id": "3954", + "name": "Treasure fairy" + }, + { + "id": "3955", + "name": "Jacky Jester" + }, + { + "id": "3956", + "name": "Combat stone" + }, + { + "id": "3957", + "name": "Combat stone" + }, + { + "id": "3958", + "name": "Combat stone" + }, + { + "id": "3959", + "name": "Combat stone" + }, + { + "id": "3960", + "name": "Combat stone" + }, + { + "id": "3961", + "name": "Combat stone" + }, + { + "id": "3962", + "name": "Combat stone" + }, + { + "id": "3963", + "name": "Combat stone" + }, + { + "id": "3964", + "name": "Combat stone" + }, + { + "id": "3965", + "name": "Combat stone" + }, + { + "id": "3966", + "name": "Combat stone" + }, + { + "id": "3967", + "name": "Combat stone" + }, + { + "id": "3968", + "name": "Combat stone" + }, + { + "id": "3969", + "name": "Combat stone" + }, + { + "id": "3970", + "name": "Combat stone" + }, + { + "id": "3971", + "name": "Combat stone" + }, + { + "id": "3972", + "name": "Combat stone" + }, + { + "id": "3973", + "name": "Combat stone" + }, + { + "id": "3974", + "name": "Combat stone" + }, + { + "id": "3975", + "name": "Combat stone" + }, + { + "id": "3976", + "name": "Combat stone" + }, + { + "id": "3977", + "name": "Combat stone" + }, + { + "id": "3978", + "name": "Combat stone" + }, + { + "id": "3979", + "name": "Combat stone" + }, + { + "id": "3980", + "name": "Combat stone" + }, + { + "id": "3981", + "name": "Combat stone" + }, + { + "id": "3982", + "name": "Combat stone" + }, + { + "id": "3983", + "name": "Combat stone" + }, + { + "id": "3984", + "name": "Combat stone" + }, + { + "id": "3985", + "name": "Combat stone" + }, + { + "id": "3986", + "name": "Combat stone" + }, + { + "id": "3987", + "name": "Combat stone" + }, + { + "id": "3988", + "name": "Combat stone" + }, + { + "id": "3989", + "name": "Combat stone" + }, + { + "id": "3990", + "name": "Combat stone" + }, + { + "id": "3991", + "name": "Combat stone" + }, + { + "id": "3992", + "name": "Combat stone" + }, + { + "id": "3993", + "name": "Combat stone" + }, + { + "id": "3994", + "name": "Combat stone" + }, + { + "id": "3995", + "name": "Combat stone" + }, + { + "id": "3996", + "name": "Combat stone" + }, + { + "id": "3997", + "name": "Combat stone" + }, + { + "id": "3998", + "name": "Combat stone" + }, + { + "id": "3999", + "name": "Combat stone" + }, + { + "id": "4000", + "name": "Combat stone" + }, + { + "id": "4001", + "name": "Combat stone" + }, + { + "id": "4002", + "name": "Combat stone" + }, + { + "id": "4003", + "name": "Combat stone" + }, + { + "id": "4004", + "name": "Combat stone" + }, + { + "id": "4005", + "name": "Combat stone" + }, + { + "id": "4006", + "name": "Combat stone" + }, + { + "id": "4007", + "name": "Combat stone" + }, + { + "id": "4008", + "name": "Combat stone" + }, + { + "id": "4009", + "name": "Combat stone" + }, + { + "id": "4010", + "name": "Combat stone" + }, + { + "id": "4011", + "name": "Combat stone" + }, + { + "id": "4012", + "name": "Combat stone" + }, + { + "id": "4013", + "name": "Combat stone" + }, + { + "id": "4014", + "name": "Combat stone" + }, + { + "id": "4015", + "name": "Combat stone" + }, + { + "id": "4016", + "name": "Combat stone" + }, + { + "id": "4017", + "name": "Combat stone" + }, + { + "id": "4018", + "name": "Combat stone" + }, + { + "id": "4019", + "name": "Combat stone" + }, + { + "id": "4020", + "name": "Combat stone" + }, + { + "id": "4021", + "name": "Elemental balance" + }, + { + "id": "4022", + "name": "Elemental balance" + }, + { + "id": "4023", + "name": "Elemental balance" + }, + { + "id": "4024", + "name": "Elemental balance" + }, + { + "id": "4025", + "name": "Elemental balance" + }, + { + "id": "4026", + "name": "Elemental balance" + }, + { + "id": "4027", + "name": "Elemental balance" + }, + { + "id": "4028", + "name": "Elemental balance" + }, + { + "id": "4029", + "name": "Elemental balance" + }, + { + "id": "4030", + "name": "Elemental balance" + }, + { + "id": "4031", + "name": "Elemental balance" + }, + { + "id": "4032", + "name": "Elemental balance" + }, + { + "id": "4033", + "name": "Elemental balance" + }, + { + "id": "4034", + "name": "Elemental balance" + }, + { + "id": "4035", + "name": "Elemental balance" + }, + { + "id": "4036", + "name": "Elemental balance" + }, + { + "id": "4037", + "name": "Elemental balance" + }, + { + "id": "4038", + "name": "Elemental balance" + }, + { + "id": "4039", + "name": "Elemental balance" + }, + { + "id": "4040", + "name": "Elemental balance" + }, + { + "id": "4041", + "name": "Elemental balance" + }, + { + "id": "4042", + "name": "Elemental balance" + }, + { + "id": "4043", + "name": "Elemental balance" + }, + { + "id": "4044", + "name": "Elemental balance" + }, + { + "id": "4045", + "name": "Elemental balance" + }, + { + "id": "4046", + "name": "Elemental balance" + }, + { + "id": "4047", + "name": "Elemental balance" + }, + { + "id": "4048", + "name": "Elemental balance" + }, + { + "id": "4049", + "name": "Elemental balance" + }, + { + "id": "4050", + "name": "Elemental balance" + }, + { + "id": "4051", + "name": "Elemental balance" + }, + { + "id": "4052", + "name": "Elemental balance" + }, + { + "id": "4053", + "name": "Elemental balance" + }, + { + "id": "4054", + "name": "Elemental balance" + }, + { + "id": "4055", + "name": "Elemental balance" + }, + { + "id": "4056", + "name": "Elemental balance" + }, + { + "id": "4057", + "name": "Elemental balance" + }, + { + "id": "4058", + "name": "Elemental balance" + }, + { + "id": "4059", + "name": "Elemental balance" + }, + { + "id": "4060", + "name": "Elemental balance" + }, + { + "id": "4061", + "name": "Elemental balance" + }, + { + "id": "4062", + "name": "Elemental balance" + }, + { + "id": "4063", + "name": "Elemental balance" + }, + { + "id": "4064", + "name": "Elemental balance" + }, + { + "id": "4065", + "name": "Elemental balance" + }, + { + "id": "4066", + "name": "Elemental balance" + }, + { + "id": "4067", + "name": "Elemental balance" + }, + { + "id": "4068", + "name": "Elemental balance" + }, + { + "id": "4069", + "name": "Elemental balance" + }, + { + "id": "4070", + "name": "Elemental balance" + }, + { + "id": "4071", + "name": "Elemental balance" + }, + { + "id": "4072", + "name": "Elemental balance" + }, + { + "id": "4073", + "name": "Elemental balance" + }, + { + "id": "4074", + "name": "Elemental balance" + }, + { + "id": "4075", + "name": "Elemental balance" + }, + { + "id": "4076", + "name": "Elemental balance" + }, + { + "id": "4077", + "name": "Elemental balance" + }, + { + "id": "4078", + "name": "Elemental balance" + }, + { + "id": "4079", + "name": "Elemental balance" + }, + { + "id": "4080", + "name": "Elemental balance" + }, + { + "id": "4081", + "name": "Elemental balance" + }, + { + "id": "4082", + "name": "Elemental balance" + }, + { + "id": "4083", + "name": "Elemental balance" + }, + { + "id": "4084", + "name": "Elemental balance" + }, + { + "id": "4085", + "name": "Elemental balance" + }, + { + "id": "4086", + "name": "Elemental balance" + }, + { + "id": "4087", + "name": "Elemental balance" + }, + { + "id": "4088", + "name": "Elemental balance" + }, + { + "id": "4089", + "name": "Elemental balance" + }, + { + "id": "4090", + "name": "Elemental balance" + }, + { + "id": "4091", + "name": "Elemental balance" + }, + { + "id": "4092", + "name": "Elemental balance" + }, + { + "id": "4093", + "name": "Elemental balance" + }, + { + "id": "4094", + "name": "Elemental balance" + }, + { + "id": "4095", + "name": "Elemental balance" + }, + { + "id": "4096", + "name": "Combat stone" + }, + { + "id": "4097", + "name": "Combat stone" + }, + { + "id": "4098", + "name": "Combat stone" + }, + { + "id": "4099", + "name": "Combat stone" + }, + { + "id": "4100", + "name": "Combat stone" + }, + { + "id": "4101", + "name": "Combat stone" + }, + { + "id": "4102", + "name": "Combat stone" + }, + { + "id": "4103", + "name": "Combat stone" + }, + { + "id": "4104", + "name": "Combat stone" + }, + { + "id": "4105", + "name": "Combat stone" + }, + { + "id": "4106", + "name": "Combat stone" + }, + { + "id": "4107", + "name": "Combat stone" + }, + { + "id": "4108", + "name": "Combat stone" + }, + { + "id": "4109", + "name": "Combat stone" + }, + { + "id": "4110", + "name": "Combat stone" + }, + { + "id": "4111", + "name": "Combat stone" + }, + { + "id": "4112", + "name": "Combat stone" + }, + { + "id": "4113", + "name": "Combat stone" + }, + { + "id": "4114", + "name": "Combat stone" + }, + { + "id": "4115", + "name": "Combat stone" + }, + { + "id": "4116", + "name": "Combat stone" + }, + { + "id": "4117", + "name": "Combat stone" + }, + { + "id": "4118", + "name": "Combat stone" + }, + { + "id": "4119", + "name": "Combat stone" + }, + { + "id": "4120", + "name": "Combat stone" + }, + { + "id": "4121", + "name": "Combat stone" + }, + { + "id": "4122", + "name": "Combat stone" + }, + { + "id": "4123", + "name": "Combat stone" + }, + { + "id": "4124", + "name": "Combat stone" + }, + { + "id": "4125", + "name": "Combat stone" + }, + { + "id": "4126", + "name": "Combat stone" + }, + { + "id": "4127", + "name": "Combat stone" + }, + { + "id": "4128", + "name": "Combat stone" + }, + { + "id": "4129", + "name": "Combat stone" + }, + { + "id": "4130", + "name": "Combat stone" + }, + { + "id": "4131", + "name": "Combat stone" + }, + { + "id": "4132", + "name": "Combat stone" + }, + { + "id": "4133", + "name": "Combat stone" + }, + { + "id": "4134", + "name": "Combat stone" + }, + { + "id": "4135", + "name": "Combat stone" + }, + { + "id": "4136", + "name": "Combat stone" + }, + { + "id": "4137", + "name": "Combat stone" + }, + { + "id": "4138", + "name": "Combat stone" + }, + { + "id": "4139", + "name": "Combat stone" + }, + { + "id": "4140", + "name": "Combat stone" + }, + { + "id": "4141", + "name": "Combat stone" + }, + { + "id": "4142", + "name": "Combat stone" + }, + { + "id": "4143", + "name": "Combat stone" + }, + { + "id": "4144", + "name": "Combat stone" + }, + { + "id": "4145", + "name": "Combat stone" + }, + { + "id": "4146", + "name": "Combat stone" + }, + { + "id": "4147", + "name": "Combat stone" + }, + { + "id": "4148", + "name": "Combat stone" + }, + { + "id": "4149", + "name": "Combat stone" + }, + { + "id": "4150", + "name": "Combat stone" + }, + { + "id": "4151", + "name": "Combat stone" + }, + { + "id": "4152", + "name": "Combat stone" + }, + { + "id": "4153", + "name": "Combat stone" + }, + { + "id": "4154", + "name": "Combat stone" + }, + { + "id": "4155", + "name": "Combat stone" + }, + { + "id": "4156", + "name": "Combat stone" + }, + { + "id": "4157", + "name": "Combat stone" + }, + { + "id": "4158", + "name": "Combat stone" + }, + { + "id": "4159", + "name": "Combat stone" + }, + { + "id": "4160", + "name": "Combat stone" + }, + { + "id": "4161", + "name": "Combat stone" + }, + { + "id": "4162", + "name": "Combat stone" + }, + { + "id": "4163", + "name": "Combat stone" + }, + { + "id": "4164", + "name": "Combat stone" + }, + { + "id": "4165", + "name": "Combat stone" + }, + { + "id": "4166", + "name": "Combat stone" + }, + { + "id": "4167", + "name": "Combat stone" + }, + { + "id": "4168", + "name": "Combat stone" + }, + { + "id": "4169", + "name": "Combat stone" + }, + { + "id": "4170", + "name": "Combat stone" + }, + { + "id": "4171", + "name": "Combat stone" + }, + { + "id": "4172", + "name": "Combat stone" + }, + { + "id": "4173", + "name": "Combat stone" + }, + { + "id": "4174", + "name": "Combat stone" + }, + { + "id": "4175", + "name": "Combat stone" + }, + { + "id": "4176", + "name": "Combat stone" + }, + { + "id": "4177", + "name": "Combat stone" + }, + { + "id": "4178", + "name": "Combat stone" + }, + { + "id": "4179", + "name": "Combat stone" + }, + { + "id": "4180", + "name": "Combat stone" + }, + { + "id": "4181", + "name": "Combat stone" + }, + { + "id": "4182", + "name": "Combat stone" + }, + { + "id": "4183", + "name": "Combat stone" + }, + { + "id": "4184", + "name": "Combat stone" + }, + { + "id": "4185", + "name": "Combat stone" + }, + { + "id": "4186", + "name": "Combat stone" + }, + { + "id": "4187", + "name": "Combat stone" + }, + { + "id": "4188", + "name": "Combat stone" + }, + { + "id": "4189", + "name": "Combat stone" + }, + { + "id": "4190", + "name": "Combat stone" + }, + { + "id": "4191", + "name": "Combat stone" + }, + { + "id": "4192", + "name": "Combat stone" + }, + { + "id": "4193", + "name": "Combat stone" + }, + { + "id": "4194", + "name": "Combat stone" + }, + { + "id": "4195", + "name": "Combat stone" + }, + { + "id": "4196", + "name": "Combat stone" + }, + { + "id": "4197", + "name": "Combat stone" + }, + { + "id": "4198", + "name": "Combat stone" + }, + { + "id": "4199", + "name": "Combat stone" + }, + { + "id": "4200", + "name": "Combat stone" + }, + { + "id": "4201", + "name": "Combat stone" + }, + { + "id": "4202", + "name": "Combat stone" + }, + { + "id": "4203", + "name": "Combat stone" + }, + { + "id": "4204", + "name": "Combat stone" + }, + { + "id": "4205", + "name": "Combat stone" + }, + { + "id": "4206", + "name": "Combat stone" + }, + { + "id": "4207", + "name": "Combat stone" + }, + { + "id": "4208", + "name": "Combat stone" + }, + { + "id": "4209", + "name": "Combat stone" + }, + { + "id": "4210", + "name": "Combat stone" + }, + { + "id": "4211", + "name": "Combat stone" + }, + { + "id": "4212", + "name": "Combat stone" + }, + { + "id": "4213", + "name": "Combat stone" + }, + { + "id": "4214", + "name": "Combat stone" + }, + { + "id": "4215", + "name": "Combat stone" + }, + { + "id": "4216", + "name": "Combat stone" + }, + { + "id": "4217", + "name": "Combat stone" + }, + { + "id": "4218", + "name": "Combat stone" + }, + { + "id": "4219", + "name": "Combat stone" + }, + { + "id": "4220", + "name": "Combat stone" + }, + { + "id": "4221", + "name": "Combat stone" + }, + { + "id": "4222", + "name": "Combat stone" + }, + { + "id": "4223", + "name": "Combat stone" + }, + { + "id": "4224", + "name": "Combat stone" + }, + { + "id": "4225", + "name": "Combat stone" + }, + { + "id": "4226", + "name": "Crawling hand" + }, + { + "id": "4227", + "name": "Cockatrice", + "attack_level": "1", + "clue_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "37", + "strength_level": "1" + }, + { + "id": "4228", + "name": "Basilisk", + "attack_level": "1", + "combat_audio": "288,290,289", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "75", + "strength_level": "1" + }, + { + "id": "4229", + "name": "Kurask", + "examine": "Large, heavy, with sharp things attached to its head.", + "aggressive": "true", + "attack_level": "67", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "combat_audio": "588,590,589", + "death_animation": "9440", + "defence_animation": "9441", + "defence_level": "105", + "lifepoints": "97", + "magic_animation": "9439", + "magic_level": "1", + "melee_animation": "9439", + "range_animation": "9439", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "97", + "strength_level": "105" + }, + { + "id": "4230", + "name": "Abyssal demon", + "examine": "A denizen of the Abyss!", + "attack_level": "97", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "276,278,277", + "death_animation": "1538", + "defence_animation": "0", + "defence_level": "135", + "lifepoints": "150", + "magic_animation": "1537", + "magic_level": "1", + "melee_animation": "1537", + "range_animation": "1537", + "range_level": "1", + "safespot": null, + "slayer_exp": "150", + "strength_level": "67", + "weakness": "1" + }, + { + "id": "4231", + "name": "Left head" + }, + { + "id": "4232", + "name": "Middle head" + }, + { + "id": "4233", + "name": "Right head" + }, + { + "id": "4234", + "name": "Kalphite Queen" + }, + { + "id": "4235", + "name": "Rick" + }, + { + "id": "4236", + "name": "Maid" + }, + { + "id": "4238", + "name": "Cook" + }, + { + "id": "4239", + "name": "Cook", + "examine": "I hope she can find all the ingredients!" + }, + { + "id": "4240", + "name": "Butler" + }, + { + "id": "4242", + "name": "Demon butler" + }, + { + "id": "4243", + "name": "Demon butler", + "attack_level": "1", + "combat_audio": "400,404,403", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4244", + "name": "Chief servant" + }, + { + "id": "4245", + "name": "Chief servant", + "examine": "Head of the servants' guild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4246", + "name": "Taxidermist", + "examine": "She smells unpleasantly of chemicals.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4247", + "name": "Estate agent", + "examine": "A fancy businessman with a mighty fine hat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4248", + "name": "Stonemason", + "examine": "Someone has to get rid of all the stone they dug Keldagrim out of.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4249", + "name": "Sir Renitee", + "examine": "Chief Herald of Falador." + }, + { + "id": "4250", + "name": "Sawmill operator", + "examine": "He changes the shape of wood.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "facing_booth": "true", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4251", + "name": "Garden supplier", + "examine": "She has green fingers. (Not literally.)", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4252", + "name": "Macaroni Penguin", + "examine": "Beak areful with this one", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4253", + "name": "Guard" + }, + { + "id": "4257", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4258", + "name": "Guard", + "examine": "A dwarven guard.", + "aggressive": "true", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "102", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "17", + "magic_animation": "0", + "melee_animation": "99", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "6" + }, + { + "id": "4259", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4260", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4261", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4262", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4263", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4264", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4265", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4266", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4267", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4268", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4269", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4270", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4271", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4272", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4273", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4274", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4275", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4276", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4277", + "name": "Buinn" + }, + { + "id": "4278", + "name": "Animated Bronze Armour", + "examine": "Animated bronze armour.", + "aggressive": "true", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "10", + "weakness": "7" + }, + { + "id": "4279", + "name": "Animated Iron Armour", + "examine": "Animated iron armour.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "20", + "lifepoints": "20", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "4280", + "name": "Animated Steel Armour", + "examine": "Animated steel armour.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "40", + "lifepoints": "40", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "4281", + "name": "Animated Black Armour", + "examine": "Animated black armour.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "60", + "lifepoints": "60", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "60", + "weakness": "7" + }, + { + "id": "4282", + "name": "Animated Mithril Armour", + "examine": "Animated mithril armour.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "80", + "lifepoints": "80", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "80", + "weakness": "7" + }, + { + "id": "4283", + "name": "Animated Adamant Armour", + "examine": "Animated adamant armour.", + "aggressive": "true", + "attack_level": "99", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "99", + "lifepoints": "99", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "99", + "weakness": "7" + }, + { + "id": "4284", + "name": "Animated Rune Armour", + "examine": "Animated rune armour.", + "aggressive": "true", + "attack_level": "120", + "attack_speed": "4", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "combat_audio": "2549,1979,512", + "death_animation": "4167", + "defence_animation": "388", + "defence_level": "120", + "lifepoints": "120", + "magic_animation": "386", + "melee_animation": "386", + "poison_immune": "true", + "range_animation": "386", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "120", + "weakness": "7" + }, + { + "id": "4285", + "name": "Ghommal", + "examine": "The big door man." + }, + { + "id": "4286", + "name": "Harrallak Menarous", + "examine": "Guild Master." + }, + { + "id": "4287", + "name": "Gamfred", + "examine": "The guild engineer." + }, + { + "id": "4288", + "name": "Ajjat", + "examine": "Used to be a black knight." + }, + { + "id": "4289", + "name": "Kamfreena", + "examine": "Blademistress, skillful female warrior." + }, + { + "id": "4290", + "name": "Shanomi", + "examine": "A warrior mage from the east." + }, + { + "id": "4291", + "name": "Cyclops", + "examine": "A one-eyed man eater.", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "75", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "75", + "strength_level": "50", + "weakness": "8" + }, + { + "id": "4292", + "name": "Cyclops", + "examine": "A one-eyed woman eater.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "35", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "100", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "4293", + "name": "Lidio", + "examine": "Food shopkeeper." + }, + { + "id": "4294", + "name": "Lilly", + "examine": "Potion shopkeeper." + }, + { + "id": "4295", + "name": "Anton", + "examine": "Armour shopkeeper." + }, + { + "id": "4296", + "name": "Jade", + "examine": "Bank staff." + }, + { + "id": "4297", + "name": "Sloane", + "examine": "He looks like a strong warrior." + }, + { + "id": "4298", + "name": "Jimmy", + "examine": "He looks a bit drunk." + }, + { + "id": "4299", + "name": "Ref", + "examine": "He looks fair and reliable." + }, + { + "id": "4300", + "name": "Ref", + "examine": "He looks fair and reliable.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4301", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4302", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4303", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4304", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4305", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4306", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4307", + "name": "Guard", + "examine": "A guard for the humans against monster group.", + "attack_level": "26", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "4308", + "name": "Guard", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4309", + "name": "Guard", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4310", + "name": "Guard", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4311", + "name": "Guard", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4312", + "name": "Nardok" + }, + { + "id": "4313", + "name": "Dartog" + }, + { + "id": "4315", + "name": "Dwarf" + }, + { + "id": "4316", + "name": "Dwarf", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "4317", + "name": "H.A.M. Member" + }, + { + "id": "4318", + "name": "H.A.M. Member", + "attack_level": "1", + "clue_level": "0", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4319", + "name": "H.A.M. Member" + }, + { + "id": "4320", + "name": "H.A.M. Member", + "attack_level": "1", + "clue_level": "0", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4321", + "name": "Zanik" + }, + { + "id": "4323", + "name": "Zanik" + }, + { + "id": "4324", + "name": "Zanik" + }, + { + "id": "4325", + "name": "Light creature" + }, + { + "id": "4326", + "name": "Zanik" + }, + { + "id": "4327", + "name": "HAM member" + }, + { + "id": "4328", + "name": "Sigmund" + }, + { + "id": "4329", + "name": "H.A.M. Deacon", + "attack_level": "1", + "clue_level": "0", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4330", + "name": "Johanhus Ulsbrecht" + }, + { + "id": "4331", + "name": "Sigmund" + }, + { + "id": "4332", + "name": "Sigmund" + }, + { + "id": "4333", + "name": "Sigmund" + }, + { + "id": "4334", + "name": "Sigmund" + }, + { + "id": "4335", + "name": "Sigmund" + }, + { + "id": "4336", + "name": "Guard", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4337", + "name": "Zanik" + }, + { + "id": "4338", + "name": "Zanik" + }, + { + "id": "4340", + "name": "Zanik" + }, + { + "id": "4341", + "name": "Zanik" + }, + { + "id": "4342", + "name": "Zanik" + }, + { + "id": "4343", + "name": "Snake", + "examine": "Snake! Snaaaaake! ", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "3", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "3609,3608,3610", + "death_animation": "278", + "defence_animation": "276", + "defence_level": "50", + "end_gfx": "", + "end_height": "", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "275", + "poison_amount": "15", + "poisonous": "true", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "25" + }, + { + "id": "4344", + "name": "Monkey", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "629,631,630", + "death_animation": "223", + "defence_animation": "221", + "defence_level": "1", + "lifepoints": "12", + "melee_animation": "220", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4345", + "name": "Albino bat", + "examine": "It's all white by me.", + "attack_level": "31", + "death_animation": "4917", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "44", + "magic_animation": "0", + "melee_animation": "4915", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "31", + "weakness": "8" + }, + { + "id": "4346", + "name": "Crab" + }, + { + "id": "4347", + "name": "Giant mosquito", + "examine": "A flying blood sucker.", + "attack_level": "63", + "attack_speed": "10", + "death_animation": "2398", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "2397", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "63", + "weakness": "8" + }, + { + "id": "4348", + "name": "Jungle horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "55", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4235", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "45", + "strength_level": "70", + "weakness": "7" + }, + { + "id": "4349", + "name": "Jungle horror", + "examine": "A horrible, emaciated ape like creature with beady yellow eyes.", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "55", + "lifepoints": "45", + "magic_level": "1", + "melee_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "45", + "strength_level": "70" + }, + { + "id": "4350", + "name": "Jungle horror", + "examine": "A horrible, emaciated ape like creature with beady green eyes.", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "55", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4235", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "45", + "strength_level": "70", + "weakness": "7" + }, + { + "id": "4351", + "name": "Jungle horror", + "examine": "A horrible, emaciated ape like creature with beady blue eyes.", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "55", + "lifepoints": "45", + "magic_level": "1", + "melee_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "45", + "strength_level": "70" + }, + { + "id": "4352", + "name": "Jungle horror", + "examine": "A horrible, emaciated ape like creature with beady pink eyes.", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "55", + "lifepoints": "45", + "magic_level": "1", + "melee_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "45", + "strength_level": "70" + }, + { + "id": "4353", + "name": "Cave horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "62", + "lifepoints": "55", + "magic_animation": "4234", + "magic_level": "80", + "melee_animation": "4234", + "range_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "55", + "strength_level": "77", + "weakness": "6" + }, + { + "id": "4354", + "name": "Cave horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "62", + "lifepoints": "55", + "magic_animation": "4234", + "magic_level": "80", + "melee_animation": "4234", + "range_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "55", + "strength_level": "77", + "weakness": "6" + }, + { + "id": "4355", + "name": "Cave horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "62", + "lifepoints": "55", + "magic_animation": "4234", + "magic_level": "80", + "melee_animation": "4234", + "range_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "55", + "strength_level": "77", + "weakness": "6" + }, + { + "id": "4356", + "name": "Cave horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "62", + "lifepoints": "55", + "magic_animation": "4234", + "magic_level": "80", + "melee_animation": "4234", + "range_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "55", + "strength_level": "77", + "weakness": "6" + }, + { + "id": "4357", + "name": "Cave horror", + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "496,500,499", + "death_animation": "4233", + "defence_animation": "4232", + "defence_level": "62", + "lifepoints": "55", + "magic_animation": "4234", + "magic_level": "80", + "melee_animation": "4234", + "range_animation": "4234", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "55", + "strength_level": "77", + "weakness": "6" + }, + { + "id": "4358", + "name": "Cavey Davey" + }, + { + "id": "4359", + "name": "Patchy", + "examine": "Patchy the pirate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4360", + "name": "San Fan" + }, + { + "id": "4361", + "name": "Fancy Dan", + "examine": "A very flamboyant pirate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4362", + "name": "Honest Jimmy", + "examine": "I can't wait to buy from a guy with Honest in his name...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4363", + "name": "Monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4364", + "name": "Swarm" + }, + { + "id": "4365", + "name": "Blue Monkey" + }, + { + "id": "4371", + "name": "Blue Monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4372", + "name": "Red Monkey", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4373", + "name": "Parrot", + "examine": "A colourful bird.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4374", + "name": "Parrot" + }, + { + "id": "4375", + "name": "Security Guard", + "examine": "A retired Gielinor security guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4376", + "name": "Litara", + "examine": "Litara, a barbarian explorer." + }, + { + "id": "4377", + "name": "Gate of War" + }, + { + "id": "4378", + "name": "Ricketty door" + }, + { + "id": "4379", + "name": "Oozing barrier" + }, + { + "id": "4380", + "name": "Portal of Death" + }, + { + "id": "4381", + "name": "Ankou", + "examine": "A boney ghost.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "924,926,925", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "50", + "lifepoints": "60", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "slayer_exp": "60", + "strength_level": "69" + }, + { + "id": "4382", + "name": "Ankou", + "examine": "A boney ghost.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "924,926,925", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "50", + "lifepoints": "66", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "slayer_exp": "60", + "strength_level": "69" + }, + { + "id": "4383", + "name": "Ankou", + "examine": "A boney ghost.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "924,926,925", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "55", + "lifepoints": "66", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "slayer_exp": "60", + "strength_level": "74" + }, + { + "id": "4384", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "68", + "melee_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4385", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "34", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "34", + "weakness": "7" + }, + { + "id": "4386", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4387", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5542", + "defence_animation": "5541", + "defence_level": "1", + "lifepoints": "36", + "melee_animation": "5540", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "4388", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "magic_level": "30", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4389", + "name": "Flesh Crawler", + "examine": "I don't think insect repellent will work.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "3", + "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", + "combat_audio": "571,573,572", + "death_animation": "1190", + "defence_animation": "1186", + "defence_level": "10", + "lifepoints": "25", + "magic_animation": "1184", + "melee_animation": "1184", + "range_animation": "1184", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "25", + "strength_level": "2", + "weakness": "0" + }, + { + "id": "4390", + "name": "Flesh Crawler", + "examine": "I don't think insect repellent will work.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "3", + "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", + "combat_audio": "571,573,572", + "death_animation": "1190", + "defence_animation": "1186", + "defence_level": "10", + "lifepoints": "25", + "magic_animation": "1184", + "melee_animation": "1184", + "range_animation": "1184", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "25", + "strength_level": "2" + }, + { + "id": "4391", + "name": "Flesh Crawler", + "examine": "I don't think insect repellent will work.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "3", + "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", + "combat_audio": "571,573,572", + "death_animation": "1190", + "defence_animation": "1186", + "defence_level": "10", + "lifepoints": "25", + "magic_animation": "1184", + "melee_animation": "1184", + "range_animation": "1184", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "25", + "strength_level": "2" + }, + { + "id": "4392", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "24", + "attack_speed": "5", + "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", + "combat_audio": "918,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "25", + "lifepoints": "23", + "magic_animation": "5568", + "melee_animation": "5568", + "range_animation": "5568", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "4393", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "35", + "attack_speed": "5", + "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", + "combat_audio": "918,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "28", + "lifepoints": "18", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "4394", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "5", + "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", + "combat_audio": "918,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "48", + "lifepoints": "40", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "4395", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "21", + "attack_speed": "5", + "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "23", + "lifepoints": "26", + "melee_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "9" + }, + { + "id": "4396", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "710,713,711", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4397", + "name": "Catablepon", + "examine": "Big Cow-like... But cows don't have serpent tails!", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "5", + "bonuses": "5,20,15,3,10,20,10,10,20,15,23,25,15,25,10", + "clue_level": "1", + "combat_audio": "511,330,329", + "death_animation": "4270", + "defence_animation": "4273", + "defence_level": "38", + "lifepoints": "50", + "magic_animation": "4272", + "magic_level": "38", + "melee_animation": "4271", + "range_level": "1", + "respawn_delay": "74", + "safespot": null, + "slayer_exp": "50", + "spell_id": "7", + "strength_level": "38" + }, + { + "id": "4398", + "name": "Catablepon", + "examine": "Big Cow-like... But cows don't have serpent tails!", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "5", + "bonuses": "20,25,10,20,25,10,10,11,0,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "511,330,329", + "death_animation": "4270", + "defence_animation": "4273", + "defence_level": "38", + "lifepoints": "70", + "magic_animation": "4272", + "magic_level": "38", + "melee_animation": "4271", + "range_level": "1", + "respawn_delay": "74", + "safespot": null, + "slayer_exp": "50", + "spell_id": "7", + "strength_level": "38" + }, + { + "id": "4399", + "name": "Catablepon", + "examine": "Big Cow-like... But cows don't have serpent tails!", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "50,45,50,40,45,20,30,25,33,25,25,20,20,40,0", + "clue_level": "1", + "combat_audio": "511,330,329", + "death_animation": "4270", + "defence_animation": "4273", + "defence_level": "38", + "lifepoints": "50", + "magic_animation": "4272", + "magic_level": "45", + "melee_animation": "4271", + "range_level": "1", + "respawn_delay": "74", + "safespot": null, + "slayer_exp": "50", + "spell_id": "7", + "strength_level": "58" + }, + { + "id": "4400", + "name": "Giant spider", + "examine": "I think this spider has been genetically modified.", + "aggressive": "true", + "attack_level": "48", + "bonuses": "19,21,19,62,45,51,54,63,60,18,0,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "51", + "lifepoints": "50", + "magic_animation": "5327", + "melee_animation": "5327", + "range_animation": "5327", + "range_level": "1", + "safespot": null, + "strength_level": "45" + }, + { + "id": "4401", + "name": "Spider", + "aggressive": "false", + "attack_level": "1", + "combat_audio": "3604,3609,3608", + "death_animation": "6251", + "defence_animation": "6250", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "6249", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4402", + "name": "Scorpion", + "examine": "An extremely vicious scorpion.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "12,23,10,51,32,62,29,54,48,0,0,0,0,0,0", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "6255", + "defence_level": "49", + "lifepoints": "55", + "magic_animation": "6254", + "melee_animation": "6254", + "range_animation": "6254", + "range_level": "1", + "safespot": null, + "slayer_exp": "17", + "strength_level": "51" + }, + { + "id": "4403", + "name": "Scorpion", + "examine": "An extremely vicious scorpion.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "5", + "bonuses": "15,16,12,32,19,38,18,34,32,0,0,0,0,0,0", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "6255", + "defence_level": "35", + "lifepoints": "37", + "magic_animation": "6254", + "melee_animation": "6254", + "range_animation": "6254", + "range_level": "1", + "safespot": null, + "slayer_exp": "17", + "strength_level": "31" + }, + { + "id": "4404", + "name": "Minotaur", + "examine": "He doesn't look very pleased to see you.", + "aggressive": "false", + "attack_level": "12", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "626,628,627", + "death_animation": "4265", + "defence_animation": "4267", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "4266", + "magic_level": "1", + "melee_animation": "4266", + "range_animation": "4266", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "10", + "strength_level": "10", + "weakness": "7" + }, + { + "id": "4405", + "name": "Minotaur", + "examine": "He doesn't look very pleased to see you.", + "aggressive": "false", + "attack_level": "12", + "attack_speed": "4", + "bonuses": "11,11,13,11,11,13,11,11,11,13,11,11,11,11,11", + "clue_level": "0", + "combat_audio": "626,628,627", + "death_animation": "4265", + "defence_animation": "4267", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "4266", + "magic_level": "1", + "melee_animation": "4266", + "range_animation": "4266", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "4406", + "name": "Minotaur", + "examine": "He doesn't look very pleased to see you.", + "aggressive": "false", + "attack_level": "23", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-10,-10,-10,21,-10,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "626,628,627", + "death_animation": "4265", + "defence_animation": "4267", + "defence_level": "25", + "lifepoints": "22", + "magic_animation": "4266", + "magic_level": "1", + "melee_animation": "4266", + "range_animation": "4266", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "22", + "strength_level": "25" + }, + { + "id": "4407", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3", + "clue_level": "0", + "combat_audio": "3520,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "5", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4408", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", + "clue_level": "0", + "combat_audio": "3520,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "11", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "2" + }, + { + "id": "4409", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "6,6,6,6,6,6,6,6,6,6,6,6,6,6,6", + "clue_level": "0", + "combat_audio": "3520,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "9", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "7", + "strength_level": "2" + }, + { + "id": "4410", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", + "clue_level": "0", + "combat_audio": "3520,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4411", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "clue_level": "0", + "combat_audio": "3520,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "17", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4412", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", + "clue_level": "0", + "combat_audio": "3520,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "10", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4413", + "name": "Wolf", + "examine": "They say inside you there are two wolves...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "7,7,7,7,7,7,7,7,7,7,7,7,7,7,7", + "combat_audio": "481,491,490", + "death_animation": "6558", + "defence_animation": "6557", + "defence_level": "9", + "lifepoints": "15", + "magic_animation": "6559", + "melee_animation": "6559", + "range_animation": "6559", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "15", + "strength_level": "1" + }, + { + "id": "4414", + "name": "Wolf", + "examine": "They say inside you there are two wolves...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "5,5,5,5,5,5,5,5,5,5,5,5,5,5,5", + "combat_audio": "481,491,490", + "death_animation": "6558", + "defence_animation": "6557", + "defence_level": "7", + "lifepoints": "10", + "magic_animation": "6559", + "melee_animation": "6559", + "range_animation": "6559", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "10", + "strength_level": "1" + }, + { + "id": "4415", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,-42,-53,0,0,0", + "combat_audio": "710,713,711", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "2705", + "magic_level": "1", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "respawn_delay": "3", + "safespot": null, + "slayer_exp": "2", + "strength_level": "1" + }, + { + "id": "4416", + "name": "Bee keeper" + }, + { + "id": "4417", + "name": "Bees!" + }, + { + "id": "4418", + "name": "Gorak", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "4302", + "defence_animation": "4301", + "defence_level": "1", + "lifepoints": "112", + "melee_animation": "4300", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "112", + "strength_level": "1" + }, + { + "id": "4419", + "name": "Cosmic Being", + "examine": "A highly enlightened being.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4420", + "name": "Fairy Godfather" + }, + { + "id": "4434", + "name": "Fairy Nuff", + "examine": "A healing fairy." + }, + { + "id": "4435", + "name": "Fairy Queen" + }, + { + "id": "4437", + "name": "Fairy Queen", + "examine": "Looks otherworldy..." + }, + { + "id": "4438", + "name": "Centaur", + "examine": "Horseplay.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4439", + "name": "Centaur", + "examine": "Horseplay.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4440", + "name": "Stag", + "examine": "A noble creature!", + "aggressive": "false", + "attack_level": "11", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "812,814,813", + "death_animation": "6377", + "defence_animation": "0", + "defence_level": "13", + "lifepoints": "19", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6376", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "90", + "safespot": null, + "strength_level": "13", + "weakness": "7" + }, + { + "id": "4441", + "name": "Wood Dryad", + "examine": "Twiggy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4442", + "name": "Fairy Very Wise" + }, + { + "id": "4443", + "name": "Fairy", + "examine": "A delicate creature from this strange realm." + }, + { + "id": "4444", + "name": "Fairy" + }, + { + "id": "4445", + "name": "Fairy" + }, + { + "id": "4446", + "name": "Fairy" + }, + { + "id": "4447", + "name": "Rabbit" + }, + { + "id": "4448", + "name": "Rabbit" + }, + { + "id": "4449", + "name": "Butterfly" + }, + { + "id": "4450", + "name": "Butterfly" + }, + { + "id": "4451", + "name": "Starflower" + }, + { + "id": "4452", + "name": "Starflower" + }, + { + "id": "4453", + "name": "Fairy Fixit" + }, + { + "id": "4455", + "name": "Fairy Fixit", + "examine": "Fairy ring maintenance division.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4456", + "name": "Ork" + }, + { + "id": "4457", + "name": "Ork", + "examine": "He works in the bank.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4458", + "name": "Ork", + "examine": "She works in the bank.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4459", + "name": "Ork", + "examine": "She works in the bank.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4460", + "name": "Fake Man" + }, + { + "id": "4461", + "name": "Held vampyre juvinate" + }, + { + "id": "4462", + "name": "Held vampyre juvinate" + }, + { + "id": "4463", + "name": "Angry juvinate" + }, + { + "id": "4464", + "name": "Angry juvinate" + }, + { + "id": "4465", + "name": "Angry juvinate" + }, + { + "id": "4466", + "name": "Benjamin" + }, + { + "id": "4467", + "name": "Liam" + }, + { + "id": "4468", + "name": "Miala" + }, + { + "id": "4469", + "name": "Verak" + }, + { + "id": "4470", + "name": "Tree spirit", + "examine": "A very angry nymph.", + "aggressive": "true", + "attack_level": "9", + "attack_speed": "6", + "death_animation": "97", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "12", + "magic_animation": "0", + "melee_animation": "94", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "6" + }, + { + "id": "4471", + "name": "Bogrog" + }, + { + "id": "4473", + "name": "Woman" + }, + { + "id": "4474", + "name": "Magic dummy", + "examine": "A magic training dummy", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "97", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "94", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "6" + }, + { + "id": "4475", + "name": "Ned" + }, + { + "id": "4476", + "name": "Guardian mummy", + "examine": "Who's your mummy?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4477", + "name": "Annoyed guardian mummy" + }, + { + "id": "4478", + "name": "Tarik" + }, + { + "id": "4479", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4480", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4481", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4482", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4483", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4484", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4485", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4486", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4487", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4488", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4489", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4490", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4491", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4492", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "strength_level": "2" + }, + { + "id": "4493", + "name": "General Bentnoze" + }, + { + "id": "4494", + "name": "General Wartface", + "examine": "An ugly green creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4495", + "name": "Grubfoot" + }, + { + "id": "4497", + "name": "Grubfoot" + }, + { + "id": "4498", + "name": "Grubfoot" + }, + { + "id": "4499", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "safespot": null, + "slayer_exp": "5", + "strength_level": "2" + }, + { + "id": "4500", + "name": "Scarab swarm" + }, + { + "id": "4501", + "name": "Ethereal Man", + "examine": "Is he real or is it just my imagination?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4502", + "name": "Ethereal Lady", + "examine": "Does she really exist?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4503", + "name": "Ethereal Numerator", + "examine": "He reminds me of my old mathematics teacher.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4504", + "name": "Ethereal Expert", + "examine": "The master of accomplishment.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4505", + "name": "Ethereal Perceptive", + "examine": "He knows what is possible.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4506", + "name": "Ethereal Guide", + "examine": "He knows the past, present and future. But what of my shoe size?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4507", + "name": "Ethereal Fluke", + "examine": "Luck is probably on his side.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4508", + "name": "Ethereal Mimic" + }, + { + "id": "4509", + "name": "Me", + "examine": "It's like looking in the mirror.", + "attack_level": "60", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "171", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "414", + "range_animation": "0", + "range_level": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "4510", + "name": "Me", + "examine": "It's like looking in the mirror.", + "attack_level": "60", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "171", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "414", + "range_animation": "0", + "range_level": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "4511", + "name": "Oneiromancer", + "examine": "Spiritual leader of the Moonclan.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4512", + "name": "House", + "examine": "The craziest house I ever did see!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4513", + "name": "Baba Yaga" + }, + { + "id": "4514", + "name": "Pauline Polaris" + }, + { + "id": "4515", + "name": "Meteora" + }, + { + "id": "4516", + "name": "Melana Moonlander" + }, + { + "id": "4517", + "name": "Selene" + }, + { + "id": "4518", + "name": "Rimae Sirsalis" + }, + { + "id": "4519", + "name": "Sirsal Banker" + }, + { + "id": "4520", + "name": "Clan Guard" + }, + { + "id": "4521", + "name": "Enchanted Broom", + "examine": "How does it see where to sweep?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4522", + "name": "Enchanted Broom" + }, + { + "id": "4523", + "name": "Enchanted Broom" + }, + { + "id": "4524", + "name": "Enchanted Bucket", + "examine": "I'm not sure if it's actually doing anything of use.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4525", + "name": "Enchanted Bucket" + }, + { + "id": "4526", + "name": "Bouquet Mac Hyacinth" + }, + { + "id": "4527", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4384", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4528", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4384", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4529", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4384", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4530", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4385", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4531", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,70,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4385", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4532", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4384", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4533", + "name": "Suqah", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4389", + "defence_animation": "4384", + "defence_level": "95", + "lifepoints": "105", + "melee_animation": "4388", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "95" + }, + { + "id": "4534", + "name": "Moss giant", + "examine": "His beard seems to have a life of its own.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "6", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "30", + "lifepoints": "85", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "85", + "strength_level": "30", + "weakness": "1" + }, + { + "id": "4535", + "name": "Parrot" + }, + { + "id": "4536", + "name": "Lokar Searunner" + }, + { + "id": "4537", + "name": "Lokar Searunner", + "examine": "Either a very fremennikey pirate, or a very piratey fremnnik.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4538", + "name": "Cabin boy" + }, + { + "id": "4539", + "name": "Cabin boy", + "examine": "I always wondered what that job description actually meant...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4540", + "name": "Captain Bentley", + "examine": "The High Priest has been transformed into an avatar of Bandos.", + "aggressive": "true", + "attack_level": "55", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "214", + "magic_animation": "0", + "magic_level": "55", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "4541", + "name": "'Beefy' Burns", + "examine": "A stickler for hygiene in the kitchen.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4542", + "name": "'Eagle-eye' Shultz", + "examine": "A keen-eyed lookout with a telescope.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4543", + "name": "First mate 'Davey-boy", + "examine": "First mate to Captain Bentley.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4544", + "name": "'Bird's-Eye' Jack" + }, + { + "id": "4545", + "name": "'Picarron' Pete", + "examine": "A pirate through and through.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4546", + "name": "Jake", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4547", + "name": "Bedread the bold", + "examine": "He got his name from his favourite hobby. Reading about beds.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4548", + "name": "Wilson", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4549", + "name": "Tommy 2-times", + "examine": "Nobody really knows why he's called Tommy 2-times...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4550", + "name": "Murky Pat", + "examine": "Don't look him straight in the eyes. He'll eat you alive!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4551", + "name": "Jack Sails", + "examine": "Nice beard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4552", + "name": "Palmer" + }, + { + "id": "4553", + "name": "'Betty' B.Boppin" + }, + { + "id": "4554", + "name": "'Beedy-eye' Jones", + "examine": "Is he looking at me?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4555", + "name": "Jenny Blade", + "examine": "Yes", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4556", + "name": "'Lecherous' Lee", + "examine": "A low-down", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4557", + "name": "'Sticky' Sanders", + "examine": "Apparently his nickname comes from his fondness for jam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4558", + "name": "Hirko" + }, + { + "id": "4559", + "name": "Holoy" + }, + { + "id": "4560", + "name": "Frizzy Skernip", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "4561", + "name": "Yulf Squecks", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "4562", + "name": "Praistan Ebola", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "4563", + "name": "Hura" + }, + { + "id": "4564", + "name": "Digsite workman", + "examine": "This person is working on the site.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4565", + "name": "Digsite workman", + "examine": "This person is working on the site.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4566", + "name": "Examiner", + "examine": "Upon examining the examiner you examine it is indeed an examiner!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4567", + "name": "Examiner", + "examine": "Upon examining the examiner you examine it is indeed an examiner!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4568", + "name": "Researcher", + "examine": "Must be hard at work.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4569", + "name": "Nick" + }, + { + "id": "4570", + "name": "Crow" + }, + { + "id": "4571", + "name": "Crow" + }, + { + "id": "4572", + "name": "Gianne jnr." + }, + { + "id": "4573", + "name": "Timble" + }, + { + "id": "4574", + "name": "Tamble" + }, + { + "id": "4575", + "name": "Spang" + }, + { + "id": "4576", + "name": "Brambickle" + }, + { + "id": "4577", + "name": "Wingstone" + }, + { + "id": "4578", + "name": "Penwie", + "examine": "He looks like he's a long way from home." + }, + { + "id": "4579", + "name": "Generic Diplomat", + "examine": "He makes pots.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4580", + "name": "Ambassador Gimblewap", + "examine": "He's very diplomatic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4581", + "name": "Ambassador Spanfipple", + "examine": "Peaceful man!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4582", + "name": "Ambassador Ferrnook", + "examine": "Peaceful man!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4583", + "name": "Professor Manglethorp" + }, + { + "id": "4584", + "name": "Damwin" + }, + { + "id": "4585", + "name": "Professor Onglewip", + "examine": "A gnome mage on sabbatical." + }, + { + "id": "4586", + "name": "Professor Imblewyn" + }, + { + "id": "4587", + "name": "Perrdur" + }, + { + "id": "4588", + "name": "Dalila" + }, + { + "id": "4589", + "name": "Sorrn", + "examine": "Your common man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4590", + "name": "Mimm", + "examine": "Your common woman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4591", + "name": "Eebel" + }, + { + "id": "4592", + "name": "Ermin" + }, + { + "id": "4593", + "name": "Portobello", + "examine": "Your common man.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4594", + "name": "Captain Ninto", + "examine": "A gnome pilot off duty", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4595", + "name": "Captain Daerkin", + "examine": "A gnome pilot off duty", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4596", + "name": "Captain Lamdoo" + }, + { + "id": "4597", + "name": "Meegle" + }, + { + "id": "4598", + "name": "Wurbel" + }, + { + "id": "4599", + "name": "Sarble" + }, + { + "id": "4600", + "name": "Guard Vemmeldo", + "examine": "He looks alert and ready for action.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4601", + "name": "Burkor" + }, + { + "id": "4602", + "name": "Froono" + }, + { + "id": "4603", + "name": "Fortress Guard", + "examine": "A generic evil henchman.", + "attack_level": "26", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "4604", + "name": "Fortress Guard", + "examine": "A generic evil henchman.", + "attack_level": "26", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "4605", + "name": "Fortress Guard", + "examine": "A generic evil henchman.", + "attack_level": "26", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "428", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "4606", + "name": "Fortress Guard", + "examine": "A generic evil henchman.", + "attack_level": "26", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "9" + }, + { + "id": "4607", + "name": "Black Cat", + "examine": "A witch's black cat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "4608", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4609", + "name": "Brimstail" + }, + { + "id": "4611", + "name": "Saboteur", + "examine": "Swine.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4612", + "name": "Gnome shop keeper" + }, + { + "id": "4613", + "name": "Cute creature" + }, + { + "id": "4615", + "name": "Evil creature", + "examine": "What is that thing!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "0", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "6" + }, + { + "id": "4616", + "name": "Cute creature" + }, + { + "id": "4618", + "name": "Evil creature" + }, + { + "id": "4619", + "name": "Cute creature" + }, + { + "id": "4621", + "name": "Evil creature" + }, + { + "id": "4622", + "name": "Cute creature" + }, + { + "id": "4624", + "name": "Evil creature" + }, + { + "id": "4625", + "name": "Cute creature" + }, + { + "id": "4627", + "name": "Evil creature" + }, + { + "id": "4628", + "name": "Cute creature" + }, + { + "id": "4630", + "name": "Evil creature" + }, + { + "id": "4631", + "name": "fluffie" + }, + { + "id": "4632", + "name": "fluffie" + }, + { + "id": "4633", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4634", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4635", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4636", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4637", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4638", + "name": "Gnome soldier", + "examine": "A little warrior.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4639", + "name": "Gnome soldier", + "examine": "A little warrior.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4640", + "name": "Gnome soldier", + "examine": "A little warrior.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4641", + "name": "Gnome soldier", + "examine": "A little warrior.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4642", + "name": "Gnome soldier", + "examine": "A little warrior.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4643", + "name": "Healthorg and tortoise", + "examine": "King Healthorg riding his War Tortoise.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4644", + "name": "Oaknock the Engineer" + }, + { + "id": "4645", + "name": "Glouphrie the Untrusted", + "examine": "A weasly, shifty-looking Gnome Mage.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4646", + "name": "King Healthorg" + }, + { + "id": "4647", + "name": "Hazelmere" + }, + { + "id": "4648", + "name": "Nisha" + }, + { + "id": "4649", + "name": "Tyras guard" + }, + { + "id": "4650", + "name": "Trader Stan", + "examine": "With the prices he charges, no wonder he can afford to look so sharp.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4651", + "name": "Trader Crewmember", + "examine": "Looks very stylish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4652", + "name": "Trader Crewmember", + "examine": "That suit looks a little briny around the edges.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4653", + "name": "Trader Crewmember", + "examine": "First storm he is in that hat will blow away.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4654", + "name": "Trader Crewmember", + "examine": "She'll never be able to climb rigging in that.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4655", + "name": "Trader Crewmember", + "examine": "High heels on a ship? What is she thinking?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4656", + "name": "Trader Crewmember", + "examine": "The effect is sort of spoiled by all those tattoos.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "movement_radius": "710", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4657", + "name": "Sir Prysin" + }, + { + "id": "4658", + "name": "Dark wizard" + }, + { + "id": "4659", + "name": "Dark wizard", + "examine": "He works evil magic.", + "aggressive": "true", + "attack_level": "5", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "5", + "end_gfx": "95", + "lifepoints": "12", + "magic_animation": "711", + "magic_level": "6", + "melee_animation": "810", + "projectile": "94", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "93", + "start_height": "80", + "strength_level": "2" + }, + { + "id": "4660", + "name": "Dark wizard", + "examine": "He works evil magic.", + "aggressive": "true", + "attack_level": "17", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "14", + "end_gfx": "98", + "lifepoints": "24", + "magic_animation": "711", + "magic_level": "22", + "melee_animation": "810", + "projectile": "97", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "96", + "start_height": "80", + "strength_level": "17" + }, + { + "id": "4661", + "name": "Dark wizard", + "examine": "He works evil magic.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "4", + "combat_audio": "511,513,512", + "combat_style": "2", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "15", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "15", + "projectile": "98", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4662", + "name": "Denath" + }, + { + "id": "4663", + "name": "Denath" + }, + { + "id": "4664", + "name": "Wally" + }, + { + "id": "4665", + "name": "Baby blue dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", + "combat_audio": "405,407,406", + "death_animation": "28", + "defence_animation": "26", + "defence_level": "40", + "lifepoints": "50", + "magic_animation": "25", + "magic_level": "1", + "melee_animation": "25", + "range_animation": "25", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "50", + "strength_level": "40", + "weakness": "3" + }, + { + "id": "4666", + "name": "Baby blue dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "45", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", + "combat_audio": "405,407,406", + "death_animation": "28", + "defence_animation": "26", + "defence_level": "40", + "lifepoints": "50", + "magic_animation": "25", + "magic_level": "1", + "melee_animation": "25", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "50", + "strength_level": "40", + "weakness": "3" + }, + { + "id": "4667", + "name": "Baby red dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "405,407,406", + "defence_level": "1", + "lifepoints": "50", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4668", + "name": "Baby red dragon", + "examine": "Young but still dangerous.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "405,407,406", + "defence_level": "1", + "lifepoints": "50", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4669", + "name": "Red dragon", + "examine": "A big powerful dragon.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "130", + "lifepoints": "140", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "143", + "strength_level": "130", + "weakness": "3" + }, + { + "id": "4670", + "name": "Red dragon", + "examine": "A big powerful dragon.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "130", + "lifepoints": "140", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "143", + "strength_level": "130", + "weakness": "3" + }, + { + "id": "4671", + "name": "Red dragon", + "examine": "A big powerful dragon.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "130", + "lifepoints": "140", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "143", + "strength_level": "130", + "weakness": "3" + }, + { + "id": "4672", + "name": "Red dragon", + "examine": "A big powerful dragon.", + "aggressive": "true", + "attack_level": "130", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "130", + "lifepoints": "140", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "143", + "strength_level": "130", + "weakness": "3" + }, + { + "id": "4673", + "name": "Black dragon", + "examine": "A fierce dragon with black scales!", + "aggressive": "true", + "attack_level": "200", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "200", + "lifepoints": "190", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "200", + "strength_level": "200", + "weakness": "3" + }, + { + "id": "4674", + "name": "Black dragon", + "examine": "A fierce dragon with black scales!", + "aggressive": "true", + "attack_level": "200", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "200", + "lifepoints": "190", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "200", + "strength_level": "200", + "weakness": "3" + }, + { + "id": "4675", + "name": "Black dragon", + "examine": "A fierce dragon with black scales!", + "aggressive": "true", + "attack_level": "200", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "200", + "lifepoints": "190", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "200", + "strength_level": "200", + "weakness": "3" + }, + { + "id": "4676", + "name": "Black dragon", + "examine": "A fierce dragon with black scales!", + "aggressive": "true", + "attack_level": "200", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "200", + "lifepoints": "190", + "magic_animation": "80", + "magic_level": "100", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "200", + "strength_level": "200", + "weakness": "3" + }, + { + "id": "4677", + "name": "Green dragon", + "examine": "Must be related to Elvarg.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "68", + "lifepoints": "75", + "magic_animation": "80", + "magic_level": "68", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "75", + "strength_level": "68", + "weakness": "3" + }, + { + "id": "4678", + "name": "Green dragon", + "examine": "Must be related to Elvarg.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "68", + "lifepoints": "75", + "magic_animation": "80", + "magic_level": "68", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "75", + "strength_level": "68", + "weakness": "3" + }, + { + "id": "4679", + "name": "Green dragon", + "examine": "Must be related to Elvarg.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "68", + "lifepoints": "75", + "magic_animation": "80", + "magic_level": "68", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "75", + "strength_level": "68", + "weakness": "3" + }, + { + "id": "4680", + "name": "Green dragon", + "examine": "Must be related to Elvarg.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "68", + "lifepoints": "75", + "magic_animation": "80", + "magic_level": "68", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "75", + "strength_level": "68", + "weakness": "3" + }, + { + "id": "4681", + "name": "Blue dragon", + "examine": "A mother dragon.", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "95", + "lifepoints": "105", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "108", + "strength_level": "95", + "weakness": "3" + }, + { + "id": "4682", + "name": "Blue dragon", + "examine": "A mother dragon.", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "95", + "lifepoints": "105", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "108", + "strength_level": "95", + "weakness": "3" + }, + { + "id": "4683", + "name": "Blue dragon", + "examine": "A mother dragon.", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "95", + "lifepoints": "105", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "108", + "strength_level": "95", + "weakness": "3" + }, + { + "id": "4684", + "name": "Blue dragon", + "examine": "A mother dragon.", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "95", + "lifepoints": "105", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "108", + "strength_level": "95", + "weakness": "3" + }, + { + "id": "4685", + "name": "Ice giant", + "examine": "He's got icicles in his beard.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4673", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4672", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "70", + "strength_level": "40", + "weakness": "9" + }, + { + "id": "4686", + "name": "Ice giant", + "examine": "He's got icicles in his beard.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4673", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4672", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "70", + "strength_level": "40", + "weakness": "9" + }, + { + "id": "4687", + "name": "Ice giant", + "examine": "He's got icicles in his beard.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4673", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4672", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "70", + "strength_level": "40", + "weakness": "9" + }, + { + "id": "4688", + "name": "Moss giant", + "examine": "His beard seems to have a life of its own.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "6", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "30", + "lifepoints": "60", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "60", + "strength_level": "30", + "weakness": "1" + }, + { + "id": "4689", + "name": "Hill Giant", + "examine": "A very large foe.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "6", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "35", + "magic_animation": "4652", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "4652", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "35", + "strength_level": "22", + "weakness": "6" + }, + { + "id": "4690", + "name": "Hill Giant", + "examine": "A very large foe.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "6", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "35", + "magic_animation": "4652", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "4652", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "35", + "strength_level": "22", + "weakness": "6" + }, + { + "id": "4691", + "name": "Hill Giant", + "examine": "A very large foe.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "6", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "35", + "magic_animation": "4652", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "4652", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "35", + "strength_level": "22", + "weakness": "6" + }, + { + "id": "4692", + "name": "Hill Giant", + "examine": "A very large foe.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "6", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "35", + "magic_animation": "4652", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "4652", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "35", + "strength_level": "22", + "weakness": "6" + }, + { + "id": "4693", + "name": "Hill Giant", + "examine": "A very large foe.", + "aggressive": "true", + "attack_level": "18", + "attack_speed": "6", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "combat_audio": "448,451,450", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "26", + "lifepoints": "35", + "magic_animation": "4652", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "4652", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "35", + "strength_level": "22", + "weakness": "6" + }, + { + "id": "4694", + "name": "Lesser demon", + "examine": "Lesser, but still pretty big.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "400,404,403", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "71", + "lifepoints": "79", + "magic_animation": "4630", + "magic_level": "1", + "melee_animation": "4630", + "range_animation": "4630", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "79", + "strength_level": "70", + "weakness": "4" + }, + { + "id": "4695", + "name": "Lesser demon", + "examine": "Lesser, but still pretty big.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "400,404,403", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "71", + "lifepoints": "79", + "magic_animation": "4630", + "magic_level": "1", + "melee_animation": "4630", + "range_animation": "4630", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "79", + "strength_level": "70", + "weakness": "4" + }, + { + "id": "4696", + "name": "Lesser demon", + "examine": "Lesser, but still pretty big.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "400,404,403", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "71", + "lifepoints": "79", + "magic_animation": "4630", + "magic_level": "1", + "melee_animation": "4630", + "range_animation": "4630", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "79", + "strength_level": "70", + "weakness": "4" + }, + { + "id": "4697", + "name": "Lesser demon", + "examine": "Lesser, but still pretty big.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "400,404,403", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "71", + "lifepoints": "79", + "magic_animation": "4630", + "magic_level": "1", + "melee_animation": "4630", + "range_animation": "4630", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "79", + "strength_level": "70", + "weakness": "4" + }, + { + "id": "4698", + "name": "Greater demon", + "examine": "Big, red, and incredibly evil.", + "aggressive": "true", + "attack_level": "59", + "attack_speed": "5", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "combat_audio": "400,404,403", + "death_animation": "68", + "defence_animation": "65", + "defence_level": "59", + "lifepoints": "87", + "magic_animation": "64", + "magic_level": "59", + "melee_animation": "64", + "range_animation": "64", + "range_level": "59", + "respawn_delay": "32", + "safespot": null, + "slayer_exp": "87", + "strength_level": "59", + "weakness": "4" + }, + { + "id": "4699", + "name": "Greater demon", + "examine": "Big, red, and incredibly evil.", + "aggressive": "true", + "attack_level": "59", + "attack_speed": "5", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "combat_audio": "400,404,403", + "death_animation": "68", + "defence_animation": "65", + "defence_level": "59", + "lifepoints": "87", + "magic_animation": "64", + "magic_level": "59", + "melee_animation": "64", + "range_animation": "64", + "range_level": "59", + "respawn_delay": "32", + "safespot": null, + "slayer_exp": "87", + "strength_level": "59", + "weakness": "4" + }, + { + "id": "4700", + "name": "Greater demon", + "examine": "Big, red, and incredibly evil.", + "aggressive": "true", + "attack_level": "59", + "attack_speed": "5", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "combat_audio": "400,404,403", + "death_animation": "68", + "defence_animation": "65", + "defence_level": "59", + "lifepoints": "87", + "magic_animation": "64", + "magic_level": "59", + "melee_animation": "64", + "range_animation": "64", + "range_level": "59", + "respawn_delay": "32", + "safespot": null, + "slayer_exp": "87", + "strength_level": "59", + "weakness": "4" + }, + { + "id": "4701", + "name": "Greater demon", + "examine": "Big, red, and incredibly evil.", + "aggressive": "true", + "attack_level": "59", + "attack_speed": "5", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "combat_audio": "400,404,403", + "death_animation": "68", + "defence_animation": "65", + "defence_level": "59", + "lifepoints": "87", + "magic_animation": "64", + "magic_level": "59", + "melee_animation": "64", + "range_animation": "64", + "range_level": "59", + "respawn_delay": "32", + "safespot": null, + "slayer_exp": "87", + "strength_level": "59", + "weakness": "4" + }, + { + "id": "4702", + "name": "Black demon", + "examine": "A big, scary, jet-black demon.", + "aggressive": "true", + "attack_level": "145", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "397,399,398", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "152", + "lifepoints": "157", + "magic_animation": "64", + "magic_level": "1", + "melee_animation": "64", + "range_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "157", + "strength_level": "148", + "weakness": "4" + }, + { + "id": "4703", + "name": "Black demon", + "examine": "A big, scary, jet-black demon.", + "aggressive": "true", + "attack_level": "145", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "397,399,398", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "152", + "lifepoints": "157", + "magic_animation": "64", + "magic_level": "1", + "melee_animation": "64", + "range_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "157", + "strength_level": "148", + "weakness": "4" + }, + { + "id": "4704", + "name": "Black demon", + "examine": "A big, scary, jet-black demon.", + "aggressive": "true", + "attack_level": "145", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "397,399,398", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "152", + "lifepoints": "157", + "magic_animation": "64", + "magic_level": "1", + "melee_animation": "64", + "range_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "157", + "strength_level": "148", + "weakness": "4" + }, + { + "id": "4705", + "name": "Black demon", + "examine": "A big, scary, jet-black demon.", + "aggressive": "true", + "attack_level": "145", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "397,399,398", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "152", + "lifepoints": "157", + "magic_animation": "64", + "magic_level": "1", + "melee_animation": "64", + "range_animation": "64", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "157", + "strength_level": "148", + "weakness": "4" + }, + { + "id": "4706", + "name": "Moss giant", + "examine": "His beard seems to have a life of its own.", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "6", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "combat_audio": "449,451,450", + "death_animation": "4668", + "defence_animation": "4665", + "defence_level": "30", + "lifepoints": "85", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "85", + "strength_level": "30", + "weakness": "1" + }, + { + "id": "4707", + "name": "Magic Tutor", + "examine": "Mikasi looks ready to teach you about magic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4708", + "name": "Old Man Ral", + "examine": "A flea-infested", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4709", + "name": "Vertida Sefalatis" + }, + { + "id": "4710", + "name": "Aeonisig Raispher" + }, + { + "id": "4711", + "name": "Safalaan" + }, + { + "id": "4714", + "name": "Sarius Guile" + }, + { + "id": "4716", + "name": "Trader Sven", + "examine": "A flea-infested black market trader.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4717", + "name": "Meiyerditch citizen", + "examine": "A flea-infested", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4718", + "name": "Meiyerditch citizen", + "examine": "A flea-infested", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4719", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4720", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4721", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4722", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4723", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4724", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4725", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4726", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4727", + "name": "Meiyerditch citizen" + }, + { + "id": "4728", + "name": "Meiyerditch citizen" + }, + { + "id": "4729", + "name": "Meiyerditch citizen" + }, + { + "id": "4730", + "name": "Meiyerditch citizen" + }, + { + "id": "4731", + "name": "Meiyerditch citizen" + }, + { + "id": "4732", + "name": "Meiyerditch citizen" + }, + { + "id": "4733", + "name": "Meiyerditch citizen", + "examine": "Cowardly mage.", + "aggressive": "true", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "28", + "magic_animation": "0", + "magic_level": "90", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4734", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4735", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4736", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4737", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4738", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4739", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4740", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4741", + "name": "Meiyerditch citizen", + "examine": "This citizen looks pale", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4742", + "name": "Meiyerditch citizen" + }, + { + "id": "4743", + "name": "Meiyerditch citizen" + }, + { + "id": "4744", + "name": "Meiyerditch citizen" + }, + { + "id": "4745", + "name": "Meiyerditch citizen" + }, + { + "id": "4746", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4747", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4748", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4749", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4750", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4751", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4752", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4753", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4754", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4755", + "name": "A Meiyerditch child", + "examine": "A poor street urchin!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4756", + "name": "Meiyerditch miner", + "examine": "This citizen looks dirty and tired!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4757", + "name": "Meiyerditch miner", + "examine": "This citizen looks dirty and tired!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4758", + "name": "Meiyerditch miner" + }, + { + "id": "4759", + "name": "Meiyerditch miner", + "examine": "This citizen looks dirty and tired!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4760", + "name": "Meiyerditch miner" + }, + { + "id": "4761", + "name": "Meiyerditch miner" + }, + { + "id": "4762", + "name": "Shadowy figure" + }, + { + "id": "4763", + "name": "Shadowy figure" + }, + { + "id": "4764", + "name": "Shadowy figure" + }, + { + "id": "4765", + "name": "null", + "examine": "Some rubbish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4766", + "name": "Stray dog", + "examine": "Looks like it's got fleas!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4767", + "name": "Stray dog" + }, + { + "id": "4768", + "name": "Cat", + "examine": "A smelly cat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4769", + "name": "Cat" + }, + { + "id": "4770", + "name": "Boat" + }, + { + "id": "4771", + "name": "Boat" + }, + { + "id": "4772", + "name": "Juvinate guard", + "examine": "An initiate juvenile vampyre; a guard for the mining area.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "4773", + "name": "Juvinate guard", + "examine": "An initiate juvenile vampyre; a guard for the mining area.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "4774", + "name": "Vampyre juvenile", + "examine": "A juvenile vampyre.", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "6276", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "4775", + "name": "Vampyre juvenile", + "examine": "A juvenile vampyre.", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "6276", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "4776", + "name": "Vampyre juvinate", + "examine": "An initiate juvenile vampyre; seems to be a servant.", + "attack_level": "1", + "death_animation": "5798", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "5783", + "range_animation": "0", + "range_level": "44", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "4777", + "name": "Vampyre juvinate", + "examine": "An initiate juvenile vampyre.", + "attack_level": "1", + "death_animation": "5798", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "5783", + "range_animation": "0", + "range_level": "44", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "4778", + "name": "Held vampyre juvenile", + "examine": "A juvenile vampyre.", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "4779", + "name": "Held vampyre juvenile", + "examine": "A juvenile vampyre.", + "attack_level": "40", + "death_animation": "6781", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "4780", + "name": "Held vampyre juvinate", + "examine": "An initiate juvenile vampyre; seems to be a servant.", + "attack_level": "1", + "death_animation": "5798", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "44", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "4781", + "name": "Held vampyre juvinate" + }, + { + "id": "4782", + "name": "Vampyre juvinate" + }, + { + "id": "4783", + "name": "Former vampyre" + }, + { + "id": "4784", + "name": "Former vampyre" + }, + { + "id": "4785", + "name": "Former vampyre" + }, + { + "id": "4786", + "name": "Former vampyre" + }, + { + "id": "4787", + "name": "Former vampyre" + }, + { + "id": "4788", + "name": "Former vampyre" + }, + { + "id": "4789", + "name": "Angry vampyre", + "examine": "An enraged vampyre!", + "attack_level": "42", + "death_animation": "6031", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "6016", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "42", + "weakness": "7" + }, + { + "id": "4790", + "name": "Angry vampyre" + }, + { + "id": "4791", + "name": "Vanstrom Klause" + }, + { + "id": "4792", + "name": "Vanstrom Klause" + }, + { + "id": "4793", + "name": "Vanstrom Klause", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "155", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4794", + "name": "Vanstrom Klause" + }, + { + "id": "4795", + "name": "Vanstrom Klause" + }, + { + "id": "4796", + "name": "Vanstrom Klause", + "examine": "Not as strong as Thok.", + "aggressive": "true", + "attack_level": "90", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "28", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "90" + }, + { + "id": "4797", + "name": "Vanescula Drakan" + }, + { + "id": "4798", + "name": "Vanescula Drakan" + }, + { + "id": "4799", + "name": "Vanescula Drakan" + }, + { + "id": "4800", + "name": "Vanescula Drakan" + }, + { + "id": "4801", + "name": "Ranis Drakan" + }, + { + "id": "4802", + "name": "Ranis Drakan" + }, + { + "id": "4803", + "name": "Ranis Drakan" + }, + { + "id": "4804", + "name": "Ranis Drakan" + }, + { + "id": "4805", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4806", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "magic_level": "52", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4807", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "54", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4808", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "56", + "lifepoints": "80", + "magic_animation": "0", + "magic_level": "56", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4809", + "name": "Flying female vampire" + }, + { + "id": "4810", + "name": "Flying female vampire", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4811", + "name": "Flying female vampire", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4812", + "name": "Flying female vampire", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4813", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4814", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "magic_level": "52", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4815", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "54", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4816", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "56", + "lifepoints": "80", + "magic_animation": "0", + "magic_level": "56", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4817", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4818", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "magic_level": "52", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4819", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "54", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4820", + "name": "Vyrewatch", + "examine": "An evil", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "56", + "lifepoints": "80", + "magic_animation": "0", + "magic_level": "56", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4821", + "name": "Vyrewatch", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4822", + "name": "Vyrewatch", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4823", + "name": "Vyrewatch", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4824", + "name": "Vyrewatch", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4825", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4826", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "magic_level": "52", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4827", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "54", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4828", + "name": "Vyrewatch", + "examine": "A thirsty-looking", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "6861", + "defence_animation": "0", + "defence_level": "56", + "lifepoints": "80", + "magic_animation": "0", + "magic_level": "56", + "melee_animation": "6783", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "4829", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4830", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4831", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4832", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4833", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4834", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4835", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4836", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4837", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4838", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4839", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4840", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4841", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4842", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4843", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4844", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4845", + "name": "Flying female vampire", + "examine": "A very high-ranking vampyre.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7524", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7435", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "4846", + "name": "Flying female vampire" + }, + { + "id": "4847", + "name": "Flying female vampire", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4848", + "name": "Flying female vampire", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4849", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4850", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4851", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4852", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4853", + "name": "Ezekial Lovecraft" + }, + { + "id": "4856", + "name": "Ezekial Lovecraft", + "examine": "Smells a bit fishy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4857", + "name": "Sarius Guile" + }, + { + "id": "4862", + "name": "Vanstrom Klause" + }, + { + "id": "4863", + "name": "Kennith" + }, + { + "id": "4864", + "name": "Kennith" + }, + { + "id": "4865", + "name": "Holgart" + }, + { + "id": "4867", + "name": "Holgart" + }, + { + "id": "4868", + "name": "Holgart", + "examine": "Her knives tickle Thok.", + "aggressive": "true", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "28", + "magic_animation": "0", + "range_level": "90", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4869", + "name": "Fisherman" + }, + { + "id": "4870", + "name": "Fisherman", + "examine": "Not Thok's pretty lass.", + "aggressive": "true", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "28", + "magic_animation": "0", + "magic_level": "90", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4871", + "name": "Col. O'Niall" + }, + { + "id": "4872", + "name": "Col. O'Niall", + "examine": "A (semi) retired member of the Temple Knights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4873", + "name": "Col. O'Niall" + }, + { + "id": "4874", + "name": "Mayor Hobb", + "examine": "There's something fishy about him.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4875", + "name": "Mayor Hobb" + }, + { + "id": "4876", + "name": "Brother Maledict" + }, + { + "id": "4878", + "name": "Brother Maledict", + "examine": "A fresh-faced and innocent priest.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4879", + "name": "Brother Maledict" + }, + { + "id": "4880", + "name": "Witchaven villager" + }, + { + "id": "4883", + "name": "Witchaven villager", + "examine": "A down on his luck fisherman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4884", + "name": "Witchaven villager" + }, + { + "id": "4885", + "name": "Witchaven villager", + "examine": "A down on her luck fisherman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4886", + "name": "Witchaven villager" + }, + { + "id": "4887", + "name": "Witchaven villager", + "examine": "A down on his luck fisherman.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4888", + "name": "Witchaven villager" + }, + { + "id": "4889", + "name": "Mother Mallum" + }, + { + "id": "4890", + "name": "Slug Prince", + "examine": "A child of aquatic evil.", + "aggressive": "true", + "attack_level": "37", + "death_animation": "4830", + "defence_animation": "0", + "defence_level": "37", + "lifepoints": "105", + "magic_animation": "0", + "melee_animation": "4829", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "37", + "weakness": "9" + }, + { + "id": "4891", + "name": "Giant lobster" + }, + { + "id": "4893", + "name": "Giant Lobster", + "examine": "An extremely vicious lobster.", + "aggressive": "true", + "attack_level": "29", + "death_animation": "6267", + "defence_animation": "0", + "defence_level": "29", + "lifepoints": "82", + "magic_animation": "0", + "melee_animation": "6265", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "29", + "weakness": "9" + }, + { + "id": "4894", + "name": "Sea slug", + "examine": "A rather nasty looking crustacean.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4895", + "name": "Jeb", + "examine": "A villager named Jeb.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4896", + "name": "Jeb" + }, + { + "id": "4897", + "name": "Sir Tinley" + }, + { + "id": "4898", + "name": "Hobgoblin", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "3520,472,471", + "death_animation": "167", + "defence_animation": "163", + "defence_level": "1", + "lifepoints": "29", + "melee_animation": "164", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4899", + "name": "Cooking Tutor", + "examine": "Cordero looks ready to teach you how to cook.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4900", + "name": "Crafting Tutor", + "examine": "Cadmus, looking a little bit crafty.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4901", + "name": "Fishing Tutor", + "examine": "Finlay, mending a crayfish cage.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4902", + "name": "Mining Tutor", + "examine": "Monlum, surveying the rocks.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4903", + "name": "Prayer Tutor", + "examine": "Yauchomi, follower of Saradomin.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4904", + "name": "Smelting Tutor", + "examine": "Feoras looks a bit fiery.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4905", + "name": "Smithing Tutor" + }, + { + "id": "4906", + "name": "Woodcutting Tutor", + "examine": "Wilfred, a chip off the old block.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4907", + "name": "Bank Tutor", + "examine": "Barb, ready to teach you about banking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4908", + "name": "Fishing spot" + }, + { + "id": "4909", + "name": "Fritz the Glassblower", + "examine": "His motives are see-through.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4910", + "name": "Earth elemental", + "examine": "An earth elemental.", + "aggressive": "false", + "attack_level": "20", + "attack_speed": "6", + "combat_audio": "1531,1533,1532", + "death_animation": "4870", + "defence_animation": "4869", + "defence_level": "35", + "lifepoints": "35", + "magic_level": "10", + "melee_animation": "4868", + "range_level": "30", + "respawn_delay": "5", + "safespot": null, + "strength_level": "35" + }, + { + "id": "4911", + "name": "Elemental rock", + "examine": "An elemental rock.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "7" + }, + { + "id": "4912", + "name": "Jig cart" + }, + { + "id": "4914", + "name": "Jig cart" + }, + { + "id": "4915", + "name": "Jig cart" + }, + { + "id": "4916", + "name": "Jig cart" + }, + { + "id": "4917", + "name": "Jig cart" + }, + { + "id": "4918", + "name": "Jig cart" + }, + { + "id": "4919", + "name": "Abidor Crank" + }, + { + "id": "4920", + "name": "Giant crypt rat", + "examine": "A nasty overgrown rodent.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "65", + "lifepoints": "70", + "magic_animation": "4933", + "magic_level": "1", + "melee_animation": "4933", + "range_animation": "4933", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "4921", + "name": "Giant crypt rat", + "examine": "A nasty overgrown rodent.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "65", + "lifepoints": "70", + "magic_animation": "4933", + "magic_level": "1", + "melee_animation": "4933", + "range_animation": "4933", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "4922", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "5", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "8" + }, + { + "id": "4923", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "5", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "8" + }, + { + "id": "4924", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "5", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "8" + }, + { + "id": "4925", + "name": "Giant rat", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4926", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "7", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "7", + "weakness": "8" + }, + { + "id": "4927", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "7", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "7", + "weakness": "8" + }, + { + "id": "4928", + "name": "Dungeon rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "8" + }, + { + "id": "4929", + "name": "Dungeon rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "13", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "13", + "lifepoints": "18", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "8" + }, + { + "id": "4930", + "name": "Goat", + "examine": "They'll eat anything!", + "attack_level": "5", + "death_animation": "5343", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "5341", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "6" + }, + { + "id": "4931", + "name": "Goat", + "examine": "They'll eat anything!", + "attack_level": "5", + "death_animation": "5343", + "defence_animation": "0", + "defence_level": "5", + "lifepoints": "7", + "magic_animation": "0", + "melee_animation": "5341", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "5", + "weakness": "6" + }, + { + "id": "4932", + "name": "Billy Goat", + "examine": "They'll eat anything!", + "attack_level": "11", + "death_animation": "5343", + "defence_animation": "0", + "defence_level": "11", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "5341", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "11", + "weakness": "6" + }, + { + "id": "4933", + "name": "Goat", + "attack_level": "1", + "death_animation": "5343", + "defence_animation": "5342", + "defence_level": "1", + "lifepoints": "21", + "melee_animation": "5341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4934", + "name": "Goat", + "attack_level": "1", + "death_animation": "5343", + "defence_animation": "5342", + "defence_level": "1", + "lifepoints": "21", + "melee_animation": "5341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4935", + "name": "Billy Goat", + "attack_level": "1", + "death_animation": "5343", + "defence_animation": "5342", + "defence_level": "1", + "lifepoints": "28", + "melee_animation": "5341", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4936", + "name": "Dungeon rat", + "examine": "A dirty rat.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "8", + "weakness": "9" + }, + { + "id": "4937", + "name": "Dungeon rat", + "examine": "A dirty rat.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "8", + "weakness": "9" + }, + { + "id": "4938", + "name": "Angry giant rat", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4939", + "name": "Angry giant rat", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4940", + "name": "Angry giant rat", + "examine": "He looks a little on the cross side!", + "attack_level": "25", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4941", + "name": "Blessed giant rat", + "examine": "It's one of Iban's pet vermin.", + "attack_level": "12", + "combat_audio": "703,705,704", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "17", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "9" + }, + { + "id": "4942", + "name": "Giant rat", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "4933", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4943", + "name": "Giant rat", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "4933", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4944", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "21", + "attack_speed": "5", + "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "23", + "lifepoints": "26", + "melee_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "20" + }, + { + "id": "4945", + "name": "Giant rat", + "examine": "Overgrown vermin.", + "aggressive": "true", + "attack_level": "21", + "attack_speed": "5", + "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "23", + "lifepoints": "26", + "melee_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "9" + }, + { + "id": "4946", + "name": "Ignatius Vulcan" + }, + { + "id": "4947", + "name": "My Arm", + "examine": "Trollish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4948", + "name": "My Arm" + }, + { + "id": "4949", + "name": "My Arm" + }, + { + "id": "4950", + "name": "My Arm" + }, + { + "id": "4958", + "name": "My Arm" + }, + { + "id": "4959", + "name": "My Arm" + }, + { + "id": "4960", + "name": "Adventurer" + }, + { + "id": "4961", + "name": "Captain Barnaby" + }, + { + "id": "4962", + "name": "Captain Barnaby", + "examine": "An old sailor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4963", + "name": "Murcaily" + }, + { + "id": "4964", + "name": "Jagbakoba" + }, + { + "id": "4965", + "name": "Tool Leprechaun", + "examine": "It's a leprechaun sunbathing on a mountain.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4966", + "name": "Flies" + }, + { + "id": "4968", + "name": "Unnamed troll child" + }, + { + "id": "4969", + "name": "Drunken dwarf's leg" + }, + { + "id": "4970", + "name": "Baby Roc" + }, + { + "id": "4971", + "name": "Baby Roc", + "examine": "A mountain-dwelling bird. Cute", + "aggressive": "true", + "attack_level": "40", + "death_animation": "5033", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "5031", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "4972", + "name": "Giant Roc", + "examine": "A very", + "aggressive": "true", + "attack_level": "55", + "death_animation": "5027", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "285", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "5024", + "range_animation": "5025", + "range_level": "55", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "4973", + "name": "Shadow" + }, + { + "id": "4974", + "name": "Captain Barnaby" + }, + { + "id": "4975", + "name": "Male slave", + "examine": "It looks like he's been here a long time.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4976", + "name": "Male slave" + }, + { + "id": "4977", + "name": "Female slave", + "examine": "She looks like she's been down here a long time.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "4978", + "name": "Female slave" + }, + { + "id": "4979", + "name": "Cart Camel" + }, + { + "id": "4980", + "name": "Mine Cart" + }, + { + "id": "4981", + "name": "Mine Cart" + }, + { + "id": "4982", + "name": "Ana" + }, + { + "id": "4983", + "name": "Mercenary" + }, + { + "id": "4984", + "name": "Irena" + }, + { + "id": "4989", + "name": "Mercenary", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4990", + "name": "Mercenary", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4991", + "name": "Mercenary", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4992", + "name": "Mercenary", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4993", + "name": "Guard", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4994", + "name": "Guard", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4995", + "name": "Guard", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4996", + "name": "Guard", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4997", + "name": "Guard", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4998", + "name": "Guard", + "examine": "He looks a bit aggressive.", + "attack_level": "25", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "25", + "weakness": "9" + }, + { + "id": "4999", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5000", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5001", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5002", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5003", + "name": "Gublinch" + }, + { + "id": "5018", + "name": "Gublinch" + }, + { + "id": "5019", + "name": "Gublinch" + }, + { + "id": "5020", + "name": "Jack" + }, + { + "id": "5024", + "name": "Jill" + }, + { + "id": "5025", + "name": "Jeff" + }, + { + "id": "5026", + "name": "Egg launcher", + "examine": "An apprentice.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5027", + "name": "Egg launcher", + "examine": "A tired old wizard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5028", + "name": "Egg launcher", + "examine": "An egg launcher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5029", + "name": "Commander Connad", + "examine": "A slightly more approachable barbarian.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5030", + "name": "Captain Cain", + "examine": "He looks pretty mean.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5031", + "name": "Private Paldo", + "examine": "A stressed out barbarian private.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5032", + "name": "Private Pendron", + "examine": "A barbarian private.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5033", + "name": "Private Pierreb", + "examine": "A barbarian private.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5034", + "name": "Private Paldon", + "examine": "A barbarian private.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5035", + "name": "Major Attack", + "examine": "A barbarian army teacher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5036", + "name": "Major Collect", + "examine": "A barbarian army teacher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5037", + "name": "Major Defend", + "examine": "A barbarian army teacher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5038", + "name": "Major Heal", + "examine": "A barbarian army teacher.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5039", + "name": "Sergeant Sambur", + "examine": "He's keeping a close eye on that nearby door.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5040", + "name": "Penance Fighter", + "examine": "What on Gielinor is that?", + "attack_level": "1", + "combat_audio": "670,672,671", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5041", + "name": "Penance Ranger", + "examine": "Shooty-shooty.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5042", + "name": "Penance Runner", + "examine": "He's making a run for it!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5043", + "name": "Penance Healer", + "examine": "A nasty piece of work.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5044", + "name": "Penance Fighter" + }, + { + "id": "5045", + "name": "Penance Fighter" + }, + { + "id": "5046", + "name": "Jack" + }, + { + "id": "5047", + "name": "Jill" + }, + { + "id": "5048", + "name": "Jeff", + "examine": "Not as strong as Thok.", + "aggressive": "true", + "attack_level": "80", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "22", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "401", + "range_animation": "0", + "range_level": "80", + "safespot": null, + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5049", + "name": "Auguste" + }, + { + "id": "5050", + "name": "Auguste" + }, + { + "id": "5051", + "name": "Auguste" + }, + { + "id": "5052", + "name": "Auguste" + }, + { + "id": "5053", + "name": "Assistant Serf" + }, + { + "id": "5054", + "name": "Assistant Brock" + }, + { + "id": "5055", + "name": "Assistant Marrow" + }, + { + "id": "5056", + "name": "Assistant Le Smith" + }, + { + "id": "5057", + "name": "Assistant Stan" + }, + { + "id": "5058", + "name": "Bob" + }, + { + "id": "5059", + "name": "Curly" + }, + { + "id": "5060", + "name": "Moe" + }, + { + "id": "5061", + "name": "Larry" + }, + { + "id": "5062", + "name": "Shark" + }, + { + "id": "5067", + "name": "Shark", + "examine": "Time to run away...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5068", + "name": "Shark" + }, + { + "id": "5069", + "name": "Shark" + }, + { + "id": "5070", + "name": "Tropical wagtail" + }, + { + "id": "5072", + "name": "Tropical wagtail", + "examine": "It blends in very well with its surroundings.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5073", + "name": "Crimson swift", + "examine": "This bird obviously doesn't believe in subtlety.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5074", + "name": "Cerulean twitch", + "examine": "Best served ice cold.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5075", + "name": "Golden warbler", + "examine": "Actually", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5076", + "name": "Copper longtail", + "examine": "Nothing much to get in a flap about.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5077", + "name": "Chinchompa" + }, + { + "id": "5079", + "name": "Chinchompa", + "examine": "Handle with care.", + "attack_level": "1", + "death_animation": "5183", + "defence_level": "1", + "lifepoints": "1", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5080", + "name": "Carnivorous chinchompa", + "examine": "It looks fluffy and cute; it's probably deadly.", + "attack_level": "2", + "death_animation": "5183", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "10", + "magic_animation": "0", + "magic_level": "2", + "melee_animation": "0", + "range_animation": "0", + "range_level": "2", + "safespot": null, + "strength_level": "2" + }, + { + "id": "5081", + "name": "Ferret", + "examine": "Wild.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5082", + "name": "Black warlock", + "examine": "A black warlock. The air seems to distort wherever it passes.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5083", + "name": "Snowy knight", + "examine": "It's a snowy knight butterfly.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5084", + "name": "Sapphire glacialis", + "examine": "A sapphire glacialis. It doesn't look as pretentious as its name sounds.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5085", + "name": "Ruby harvest", + "examine": "It's a ruby harvest butterfly.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5086", + "name": "Prickly kebbit", + "examine": "Curls up into a ball to protect itself from attack.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5087", + "name": "Sabre-toothed kebbit", + "examine": "Now that's a big overbite.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5088", + "name": "Barb-tailed kebbit", + "examine": "It uses its tail to hunt and skewer fish.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5089", + "name": "Wild kebbit", + "examine": "That's a mean looking set of claws.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5090", + "name": "Matthias" + }, + { + "id": "5093", + "name": "Matthias" + }, + { + "id": "5094", + "name": "Gyr Falcon" + }, + { + "id": "5095", + "name": "Gyr Falcon" + }, + { + "id": "5096", + "name": "Gyr Falcon" + }, + { + "id": "5097", + "name": "Gyr Falcon", + "examine": "Ha! Thok much stronger.", + "aggressive": "true", + "attack_level": "80", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "22", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "395", + "range_animation": "0", + "range_level": "80", + "safespot": null, + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5098", + "name": "Spotted kebbit", + "examine": "It seems to be on a permanent sugar rush.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5099", + "name": "Dark kebbit", + "examine": "Quieter than a ninja mouse with slippers on.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5100", + "name": "Dashing kebbit", + "examine": "Now you see it; now you don't.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5101", + "name": "Sabre-toothed kyatt" + }, + { + "id": "5103", + "name": "Sabre-toothed kyatt", + "examine": "It's just like a big, white, furry, deadly can opener.", + "attack_level": "25", + "attack_speed": "5", + "death_animation": "5234", + "defence_animation": "404", + "defence_level": "99", + "lifepoints": "10", + "magic_animation": "5228", + "melee_animation": "5228", + "range_animation": "5228", + "range_level": "1", + "respawn_delay": "10", + "safespot": null, + "strength_level": "25" + }, + { + "id": "5104", + "name": "Spined larupia", + "examine": "If you tried to ride that, you'd just impale yourself!", + "attack_level": "15", + "attack_speed": "5", + "death_animation": "5234", + "defence_animation": "404", + "defence_level": "99", + "lifepoints": "10", + "magic_animation": "5228", + "melee_animation": "5228", + "range_animation": "5228", + "range_level": "1", + "safespot": null, + "strength_level": "15" + }, + { + "id": "5105", + "name": "Horned graahk", + "examine": "Get in a graahk's way and you're going to know about it... however briefly.", + "attack_level": "25", + "attack_speed": "5", + "death_animation": "5234", + "defence_animation": "404", + "defence_level": "99", + "lifepoints": "10", + "magic_animation": "5228", + "melee_animation": "5228", + "range_animation": "5228", + "range_level": "1", + "safespot": null, + "strength_level": "25" + }, + { + "id": "5106", + "name": "null", + "examine": "It's just like a big, white, furry, deadly can opener.", + "attack_level": "20", + "attack_speed": "5", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "40", + "lifepoints": "10", + "magic_animation": "5228", + "melee_animation": "5228", + "range_animation": "5228", + "range_level": "1", + "safespot": null, + "strength_level": "20" + }, + { + "id": "5110", + "name": "Aleck" + }, + { + "id": "5111", + "name": "Leon", + "examine": "He seems to be making odd sucking noises with his teeth." + }, + { + "id": "5112", + "name": "Hunting expert", + "examine": "He must be good at hunting; even his hair blends in with the surroundings.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5113", + "name": "Hunting expert", + "examine": "With all the furs", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5114", + "name": "Orange salamander", + "examine": "Slightly slimy but kind of cute.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5115", + "name": "Red salamander", + "examine": "Slightly slimy but certainly striking.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5116", + "name": "Black salamander", + "examine": "Slightly slimy and somewhat menacing.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5117", + "name": "Swamp lizard", + "examine": "Very slimy and generally disgusting.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5118", + "name": "Eagle" + }, + { + "id": "5120", + "name": "Eagle", + "examine": "A very large", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5121", + "name": "Eagle" + }, + { + "id": "5122", + "name": "Eagle" + }, + { + "id": "5123", + "name": "Eagle" + }, + { + "id": "5124", + "name": "Nickolaus" + }, + { + "id": "5127", + "name": "Nickolaus" + }, + { + "id": "5128", + "name": "Nickolaus" + }, + { + "id": "5129", + "name": "Nickolaus" + }, + { + "id": "5130", + "name": "Desert eagle", + "examine": "A very large", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5131", + "name": "Jungle eagle", + "examine": "A very large", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5132", + "name": "Polar eagle", + "examine": "A very large", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5133", + "name": "Eagle", + "examine": "It seems to be protecting the nest.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5134", + "name": "Kebbit" + }, + { + "id": "5137", + "name": "Kebbit", + "aggressive": "true", + "attack_level": "1", + "defence_animation": "5305", + "defence_level": "1", + "lifepoints": "40", + "melee_animation": "5304", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5138", + "name": "Charlie" + }, + { + "id": "5139", + "name": "Boulder" + }, + { + "id": "5140", + "name": "Boulder", + "examine": "Now", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5141", + "name": "Uri" + }, + { + "id": "5142", + "name": "Uri" + }, + { + "id": "5143", + "name": "Uri" + }, + { + "id": "5144", + "name": "Double agent", + "examine": "He's playing both sides!", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "75", + "lifepoints": "85", + "magic_animation": "0", + "magic_level": "75", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "75", + "weakness": "6" + }, + { + "id": "5145", + "name": "Double agent", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "120", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5146", + "name": "Li'l lamb", + "examine": "How cute!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5147", + "name": "Lamb", + "examine": "The black sheep of the family.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5148", + "name": "Sheep" + }, + { + "id": "5149", + "name": "Sheep" + }, + { + "id": "5150", + "name": "Sheep" + }, + { + "id": "5151", + "name": "Sheep" + }, + { + "id": "5152", + "name": "Sheep" + }, + { + "id": "5153", + "name": "Sheep" + }, + { + "id": "5154", + "name": "Sheep" + }, + { + "id": "5155", + "name": "Sheep" + }, + { + "id": "5156", + "name": "Sheep" + }, + { + "id": "5157", + "name": "Sheep" + }, + { + "id": "5158", + "name": "Sheep" + }, + { + "id": "5159", + "name": "Sheep" + }, + { + "id": "5160", + "name": "Sheep" + }, + { + "id": "5161", + "name": "Sheep" + }, + { + "id": "5162", + "name": "Sheep", + "examine": "White and fluffy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5163", + "name": "Sheep", + "examine": "White and fluffy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5164", + "name": "Sheep", + "examine": "White and fluffy" + }, + { + "id": "5165", + "name": "Sheep" + }, + { + "id": "5166", + "name": "Mountain Goat", + "examine": "This goat belongs to the mountain camp people.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5167", + "name": "Mountain Goat", + "examine": "This goat belongs to the mountain camp people.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5168", + "name": "Ram", + "examine": "White and fluffy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "757,759,758", + "death_animation": "5336", + "defence_animation": "5337", + "defence_level": "1", + "lifepoints": "8", + "melee_animation": "5338", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5169", + "name": "Ram", + "examine": "White and fluffy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "757,759,758", + "death_animation": "5336", + "defence_animation": "5337", + "defence_level": "1", + "lifepoints": "8", + "melee_animation": "5338", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5170", + "name": "Ram", + "examine": "White and fluffy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "757,759,758", + "death_animation": "5336", + "defence_animation": "5337", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "0", + "melee_animation": "5338", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5171", + "name": "Mountain goat", + "examine": "This beast doesn't need climbing boots.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5172", + "name": "Golden sheep", + "examine": "Freshly shorn.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5173", + "name": "Golden sheep", + "examine": "Lovely thick wool.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5174", + "name": "Ogre chieftain" + }, + { + "id": "5175", + "name": "Ogre shaman" + }, + { + "id": "5176", + "name": "Ogre shaman", + "examine": "Seems intelligent... for an ogre.", + "aggressive": "true", + "attack_level": "65", + "combat_style": "2", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "371", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "5177", + "name": "Ogre shaman" + }, + { + "id": "5178", + "name": "Blue dragon", + "examine": "A mother dragon.", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "95", + "lifepoints": "105", + "magic_animation": "80", + "magic_level": "1", + "melee_animation": "80", + "range_animation": "80", + "range_level": "1", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "108", + "strength_level": "95", + "weakness": "3" + }, + { + "id": "5179", + "name": "Elkoy" + }, + { + "id": "5180", + "name": "Ogre shaman" + }, + { + "id": "5181", + "name": "Ogre shaman", + "examine": "Seems intelligent... for an ogre.", + "attack_level": "65", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "371", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "5182", + "name": "Elkoy" + }, + { + "id": "5183", + "name": "Ogre shaman" + }, + { + "id": "5184", + "name": "Ogre shaman", + "examine": "Seems intelligent... for an ogre.", + "aggressive": "true", + "attack_level": "65", + "combat_style": "2", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "371", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "5185", + "name": "Biggleswade" + }, + { + "id": "5186", + "name": "Ogre shaman" + }, + { + "id": "5187", + "name": "Ogre shaman", + "examine": "Seems intelligent... for an ogre.", + "aggressive": "true", + "attack_level": "65", + "combat_style": "2", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "371", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "7" + }, + { + "id": "5188", + "name": "Saff Waldon", + "examine": "It's Nial", + "aggressive": "true", + "attack_level": "58", + "death_animation": "8948", + "defence_animation": "0", + "defence_level": "58", + "lifepoints": "165", + "magic_animation": "0", + "magic_level": "58", + "melee_animation": "8946", + "range_animation": "0", + "range_level": "58", + "respawn_delay": "60", + "safespot": null, + "strength_level": "58", + "weakness": "10" + }, + { + "id": "5189", + "name": "Ogre shaman" + }, + { + "id": "5190", + "name": "Ogre shaman", + "examine": "Seems intelligent. For an ogre.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "defence_level": "1", + "lifepoints": "1", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5191", + "name": "Blaze Sharpeye" + }, + { + "id": "5192", + "name": "Ogre shaman" + }, + { + "id": "5193", + "name": "Ogre shaman", + "examine": "Seems intelligent. For an ogre.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "defence_level": "1", + "lifepoints": "1", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5194", + "name": "Blaze Sharpeye" + }, + { + "id": "5195", + "name": "Wizard", + "examine": "A wizard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5196", + "name": "Wizard", + "examine": "A wizard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5197", + "name": "Wizard", + "examine": "A wizard.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5198", + "name": "Ava", + "examine": "She's watching you." + }, + { + "id": "5199", + "name": "Witch" + }, + { + "id": "5200", + "name": "Witch", + "examine": "The hat's a dead giveaway." + }, + { + "id": "5201", + "name": "Alice's husband" + }, + { + "id": "5203", + "name": "Alice's husband" + }, + { + "id": "5204", + "name": "Alice's husband", + "examine": "She needs to work out before facing Thok.", + "aggressive": "true", + "attack_level": "80", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "22", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "7041", + "range_animation": "0", + "range_level": "80", + "safespot": null, + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5205", + "name": "Alice's husband" + }, + { + "id": "5206", + "name": "Tree" + }, + { + "id": "5208", + "name": "Undead tree" + }, + { + "id": "5209", + "name": " Sneaky undead fowl" + }, + { + "id": "5210", + "name": "Cow1337killr" + }, + { + "id": "5211", + "name": "Undead cow", + "examine": "It's an undead cow.", + "aggressive": "false", + "attack_level": "1", + "attack_speed": "4", + "bonuses": "-15,-15,-15,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "death_animation": "5851", + "defence_animation": "5850", + "defence_level": "1", + "lifepoints": "8", + "magic_animation": "5849", + "magic_level": "1", + "melee_animation": "5849", + "range_animation": "5849", + "range_level": "1", + "respawn_delay": "5", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5212", + "name": "Alice" + }, + { + "id": "5213", + "name": "Penance Fighter" + }, + { + "id": "5214", + "name": "Penance Fighter" + }, + { + "id": "5215", + "name": "Penance Fighter" + }, + { + "id": "5216", + "name": "Penance Fighter" + }, + { + "id": "5217", + "name": "Penance Fighter" + }, + { + "id": "5218", + "name": "Penance Fighter" + }, + { + "id": "5219", + "name": "Penance Fighter" + }, + { + "id": "5220", + "name": "Penance Runner" + }, + { + "id": "5221", + "name": "Penance Runner" + }, + { + "id": "5222", + "name": "Penance Runner" + }, + { + "id": "5223", + "name": "Penance Runner" + }, + { + "id": "5224", + "name": "Penance Runner" + }, + { + "id": "5225", + "name": "Penance Runner" + }, + { + "id": "5226", + "name": "Penance Runner" + }, + { + "id": "5227", + "name": "Penance Runner" + }, + { + "id": "5228", + "name": "Penance Runner" + }, + { + "id": "5229", + "name": "Penance Ranger", + "examine": "Shooty-shooty.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "5937", + "defence_animation": "5396", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "5395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5230", + "name": "Penance Ranger" + }, + { + "id": "5231", + "name": "Penance Ranger" + }, + { + "id": "5232", + "name": "Penance Ranger" + }, + { + "id": "5233", + "name": "Penance Ranger" + }, + { + "id": "5234", + "name": "Penance Ranger" + }, + { + "id": "5235", + "name": "Penance Ranger" + }, + { + "id": "5236", + "name": "Penance Ranger" + }, + { + "id": "5237", + "name": "Penance Ranger", + "examine": "Shooty-shooty.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "5937", + "defence_animation": "5396", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "5395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5238", + "name": "Penance Healer" + }, + { + "id": "5239", + "name": "Penance Healer" + }, + { + "id": "5240", + "name": "Penance Healer" + }, + { + "id": "5241", + "name": "Penance Healer" + }, + { + "id": "5242", + "name": "Penance Healer" + }, + { + "id": "5243", + "name": "Penance Healer" + }, + { + "id": "5244", + "name": "Penance Healer" + }, + { + "id": "5245", + "name": "Penance Healer" + }, + { + "id": "5246", + "name": "Penance Healer" + }, + { + "id": "5247", + "name": "Penance Queen", + "examine": "Run away! Run away!", + "aggressive": "true", + "attack_level": "260", + "death_animation": "5412", + "defence_animation": "0", + "defence_level": "132", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5411", + "range_animation": "0", + "range_level": "116", + "respawn_delay": "60", + "safespot": null, + "strength_level": "260" + }, + { + "id": "5248", + "name": "Queen spawn", + "examine": "What's it looking at?", + "aggressive": "true", + "attack_level": "60", + "death_animation": "5093", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "450", + "magic_animation": "0", + "melee_animation": "5092", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60" + }, + { + "id": "5249", + "name": "Captain Errdo", + "examine": "He looks embarrassed", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5250", + "name": "Scarab mage", + "examine": "Part scarab, part man.", + "aggressive": "true", + "attack_level": "40", + "combat_style": "2", + "death_animation": "7616", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "54", + "melee_animation": "7615", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "3" + }, + { + "id": "5251", + "name": "Locust rider", + "examine": "A mounted lancer.", + "aggressive": "true", + "attack_level": "54", + "death_animation": "7581", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "melee_animation": "7584", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "54", + "weakness": "7" + }, + { + "id": "5252", + "name": "Locust rider", + "examine": "A mounted archer.", + "aggressive": "true", + "attack_level": "40", + "death_animation": "7581", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "77", + "magic_animation": "0", + "melee_animation": "5451", + "range_animation": "5451", + "range_level": "54", + "safespot": null, + "strength_level": "40", + "weakness": "2" + }, + { + "id": "5253", + "name": "Giant scarab", + "examine": "A huge scarab beast.", + "aggressive": "true", + "attack_level": "62", + "death_animation": "5456", + "defence_animation": "0", + "defence_level": "62", + "lifepoints": "571", + "magic_animation": "0", + "magic_level": "62", + "melee_animation": "5457", + "range_animation": "0", + "range_level": "62", + "safespot": null, + "strength_level": "62", + "weakness": "10" + }, + { + "id": "5254", + "name": "Scarab mage", + "examine": "Part scarab, part man.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "death_animation": "7616", + "defence_animation": "7617", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "7615", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5255", + "name": "Locust rider" + }, + { + "id": "5256", + "name": "Locust rider" + }, + { + "id": "5257", + "name": "Banker" + }, + { + "id": "5258", + "name": "Banker", + "examine": "He can look after my money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5259", + "name": "Banker" + }, + { + "id": "5260", + "name": "Banker", + "examine": "She can look after my money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5261", + "name": "Stonemason" + }, + { + "id": "5263", + "name": "Nathifa" + }, + { + "id": "5265", + "name": "Urbi" + }, + { + "id": "5267", + "name": "Jamila" + }, + { + "id": "5269", + "name": "Sophanem guard" + }, + { + "id": "5270", + "name": "Sophanem guard", + "examine": "A guard of Sophanem.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5271", + "name": "Sophanem guard" + }, + { + "id": "5273", + "name": "Sophanem guard" + }, + { + "id": "5274", + "name": "Sophanem guard", + "examine": "A guard of Sophanem.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5275", + "name": "Sophanem guard" + }, + { + "id": "5277", + "name": "Menaphite guard", + "examine": "A guard of Menaphos.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5278", + "name": "Coenus" + }, + { + "id": "5279", + "name": "Jex" + }, + { + "id": "5280", + "name": "Maisa" + }, + { + "id": "5282", + "name": "Osman" + }, + { + "id": "5285", + "name": "Osman", + "examine": "Flings annoying splinters at Thok.", + "aggressive": "true", + "attack_level": "80", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "22", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "426", + "range_animation": "426", + "range_level": "80", + "safespot": null, + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5286", + "name": "Osman" + }, + { + "id": "5287", + "name": "Osman" + }, + { + "id": "5288", + "name": "Embalmer" + }, + { + "id": "5289", + "name": "Carpenter" + }, + { + "id": "5290", + "name": "Linen worker" + }, + { + "id": "5291", + "name": "Priest" + }, + { + "id": "5292", + "name": "Giant scarab" + }, + { + "id": "5293", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5294", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5295", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5296", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5297", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5298", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5299", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5300", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5301", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5302", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5303", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5304", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5305", + "name": "Zombie", + "examine": "Brains!", + "attack_level": "11", + "attack_speed": "5", + "bonuses": "6,15,15,15,15,15,15,6,6,15,15,15,15,15,15", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "10", + "lifepoints": "18", + "magic_animation": "5568", + "melee_animation": "5568", + "range_animation": "5568", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5306", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5307", + "name": "Zombie", + "examine": "Brains!", + "attack_level": "11", + "attack_speed": "5", + "bonuses": "6,15,15,15,15,15,15,6,6,15,15,15,15,15,15", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "10", + "lifepoints": "18", + "magic_animation": "5568", + "melee_animation": "5568", + "range_animation": "5568", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5308", + "name": "Zombie", + "examine": "Brains!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "24", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5309", + "name": "Zombie", + "examine": "Brains!", + "attack_level": "15", + "attack_speed": "5", + "bonuses": "10,15,16,16,15,16,16,10,10,16,15,15,15,15,15", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "16", + "lifepoints": "40", + "magic_animation": "5571", + "melee_animation": "5571", + "range_animation": "5571", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5310", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "24", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5311", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "24", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5312", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "24", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5313", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "24", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5314", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5315", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5316", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5317", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5318", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5319", + "name": "Zombie", + "examine": "Examine not added", + "attack_level": "15", + "attack_speed": "5", + "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "20", + "lifepoints": "40", + "magic_animation": "5571", + "melee_animation": "5571", + "range_animation": "5571", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5320", + "name": "Zombie", + "examine": "Examine not added", + "attack_level": "18", + "attack_speed": "5", + "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "20", + "lifepoints": "40", + "magic_animation": "5571", + "melee_animation": "5571", + "range_animation": "5571", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5321", + "name": "Zombie", + "examine": "Examine not added", + "attack_level": "18", + "attack_speed": "5", + "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "20", + "lifepoints": "40", + "magic_animation": "5571", + "melee_animation": "5571", + "range_animation": "5571", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5322", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "20", + "attack_speed": "5", + "bonuses": "21,19,20,42,44,34,41,38,40,21,0,0,0,0,0", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "23", + "lifepoints": "30", + "magic_animation": "5571", + "melee_animation": "5571", + "range_animation": "5571", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "19" + }, + { + "id": "5323", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5324", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5325", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5326", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5327", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5328", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5329", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5330", + "name": "Zombie", + "examine": "", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5331", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5332", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "15", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "17", + "lifepoints": "29", + "magic_level": "1", + "melee_animation": "5485", + "range_level": "1", + "respawn_delay": "70", + "safespot": null, + "strength_level": "18", + "weakness": "8" + }, + { + "id": "5333", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "15", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "17", + "lifepoints": "29", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "70", + "safespot": null, + "strength_level": "18", + "weakness": "8" + }, + { + "id": "5334", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "15", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "17", + "lifepoints": "29", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "70", + "safespot": null, + "strength_level": "18", + "weakness": "8" + }, + { + "id": "5335", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "11", + "attack_speed": "6", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "1", + "lifepoints": "24", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "strength_level": "11" + }, + { + "id": "5336", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "11", + "attack_speed": "6", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "1", + "lifepoints": "24", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "strength_level": "11" + }, + { + "id": "5337", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "24", + "attack_speed": "4", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "24", + "lifepoints": "17", + "magic_animation": "5485", + "magic_level": "1", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "24", + "weakness": "8" + }, + { + "id": "5338", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "12", + "attack_speed": "6", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "23", + "lifepoints": "17", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "8" + }, + { + "id": "5339", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "12", + "attack_speed": "6", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "23", + "lifepoints": "17", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "8" + }, + { + "id": "5340", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "attack_level": "12", + "attack_speed": "6", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5489", + "defence_level": "23", + "lifepoints": "17", + "magic_animation": "5485", + "melee_animation": "5485", + "range_animation": "5485", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "8" + }, + { + "id": "5341", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "42", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5503", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "5499", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "42", + "weakness": "8" + }, + { + "id": "5342", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "5343", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5344", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "5345", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "5346", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5347", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "5348", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1", + "weakness": "5" + }, + { + "id": "5349", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5350", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5351", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5352", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5353", + "name": "Undead one", + "examine": "A minion of Rashiliyia.", + "aggressive": "true", + "attack_level": "32", + "attack_speed": "5", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "8" + }, + { + "id": "5354", + "name": "Undead one", + "examine": "A minion of Rashiliyia.", + "attack_level": "33", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "33", + "weakness": "8" + }, + { + "id": "5355", + "name": "Undead one", + "examine": "The animated dead; one of Rashiliyia's minions.", + "aggressive": "true", + "attack_level": "32", + "attack_speed": "5", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "5568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "8" + }, + { + "id": "5356", + "name": "Undead one", + "examine": "The animated dead; one of Rashiliyia's minions.", + "aggressive": "true", + "attack_level": "32", + "attack_speed": "5", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "melee_animation": "5568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "32", + "weakness": "8" + }, + { + "id": "5357", + "name": "Undead one", + "examine": "The animated dead; one of Rashiliyia's minions.", + "aggressive": "true", + "attack_level": "33", + "attack_speed": "5", + "death_animation": "5575", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", + "melee_animation": "5571", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "8" + }, + { + "id": "5358", + "name": "Undead one", + "examine": "The animated dead; one of Rashiliyia's minions.", + "aggressive": "true", + "attack_level": "33", + "attack_speed": "5", + "death_animation": "5575", + "defence_animation": "0", + "defence_level": "33", + "lifepoints": "47", + "magic_animation": "0", + "melee_animation": "5571", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "33", + "weakness": "8" + }, + { + "id": "5359", + "name": "Giant skeleton", + "examine": "A giant skeleton.", + "attack_level": "60", + "death_animation": "5503", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "5499", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "60", + "weakness": "8" + }, + { + "id": "5360", + "name": "Mummy ashes" + }, + { + "id": "5361", + "name": "Waterfiend", + "examine": "A fiendish embodiment of water.", + "aggressive": "true", + "attack_level": "0", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,100,100,10,100,100,0,0,0,0,0", + "combat_audio": "3774,3773,3772", + "combat_style": "1", + "death_animation": "300", + "defence_animation": "301", + "defence_level": "128", + "lifepoints": "128", + "magic_animation": "299", + "magic_level": "105", + "melee_animation": "299", + "poison_immune": "true", + "projectile": "16", + "range_animation": "299", + "range_level": "105", + "safespot": null, + "strength_level": "0", + "weakness": "4" + }, + { + "id": "5362", + "name": "Brutal green dragon", + "examine": "It appears to be intelligent and savage.", + "aggressive": "true", + "attack_level": "268", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "168", + "lifepoints": "175", + "magic_animation": "91", + "magic_level": "168", + "melee_animation": "91", + "poison_immune": "true", + "range_animation": "91", + "range_level": "0", + "safespot": null, + "slayer_exp": "183", + "strength_level": "168", + "weakness": "3" + }, + { + "id": "5363", + "name": "Mithril dragon", + "examine": "Experimenting with mithril gone bad!", + "aggressive": "true", + "attack_level": "268", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,50,100,70,30,90,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "92", + "defence_animation": "89", + "defence_level": "268", + "lifepoints": "254", + "magic_animation": "91", + "magic_level": "168", + "melee_animation": "91", + "range_animation": "91", + "range_level": "168", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "273", + "strength_level": "268", + "weakness": "8" + }, + { + "id": "5364", + "name": "Confused barbarian", + "examine": "It appears to be intelligent and savage.", + "attack_level": "70", + "attack_speed": "6", + "defence_level": "50", + "lifepoints": "175", + "range_level": "167", + "safespot": null, + "strength_level": "167", + "weakness": "7" + }, + { + "id": "5365", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "34", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "34", + "weakness": "7" + }, + { + "id": "5366", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "60", + "melee_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5367", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "85", + "melee_animation": "5485", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5368", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "85", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5369", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "36", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5370", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "36", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5371", + "name": "Ghost", + "examine": "Eeek! A ghost!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "36", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5372", + "name": "Ghost", + "examine": "Why does it attack with twigs? Swords and axes much better.", + "aggressive": "true", + "attack_level": "80", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "40", + "lifepoints": "36", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "5532", + "range_animation": "426", + "range_level": "80", + "safespot": null, + "slayer_exp": "25", + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5373", + "name": "Ghost", + "examine": "Are these twigs meant to hurt Thok?", + "aggressive": "true", + "attack_level": "80", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "40", + "lifepoints": "36", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "5532", + "range_animation": "426", + "range_level": "80", + "safespot": null, + "slayer_exp": "25", + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5374", + "name": "Ghost", + "examine": "It thinks it scary. Thok show it scary.", + "aggressive": "true", + "attack_level": "80", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "70", + "lifepoints": "36", + "magic_animation": "0", + "magic_level": "80", + "melee_animation": "5532", + "range_animation": "0", + "range_level": "80", + "safespot": null, + "slayer_exp": "25", + "strength_level": "80", + "weakness": "10" + }, + { + "id": "5375", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "5", + "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", + "combat_audio": "918,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "25", + "lifepoints": "23", + "magic_animation": "5568", + "melee_animation": "5568", + "range_animation": "5568", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5376", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "5", + "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", + "combat_audio": "918,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "25", + "lifepoints": "23", + "magic_animation": "5568", + "melee_animation": "5568", + "range_animation": "5568", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5377", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "5", + "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", + "combat_audio": "918,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "28", + "lifepoints": "30", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5378", + "name": "Zombie", + "examine": "Dead man walking.", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "5", + "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", + "combat_audio": "918,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "28", + "lifepoints": "30", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5379", + "name": "Zombie", + "examine": "The walking dead.", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "5", + "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", + "combat_audio": "918,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "48", + "lifepoints": "40", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5380", + "name": "Zombie", + "examine": "The walking dead.", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "5", + "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", + "combat_audio": "918,923,922", + "death_animation": "5580", + "defence_animation": "5579", + "defence_level": "48", + "lifepoints": "40", + "magic_animation": "5578", + "melee_animation": "5578", + "range_animation": "5578", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5381", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "62", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "62", + "lifepoints": "88", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "62", + "weakness": "8" + }, + { + "id": "5382", + "name": "Animated steel armour", + "examine": "Animated steel armour.", + "attack_level": "28", + "death_animation": "4167", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "28", + "weakness": "7" + }, + { + "id": "5383", + "name": "Odovacar" + }, + { + "id": "5384", + "name": "Giant skeleton", + "examine": "Big and bony, just how I like them.", + "aggressive": "true", + "attack_level": "95", + "attack_speed": "2", + "bonuses": "25,25,25,25,25,25,25,25,25,25,25,25,25,25,25", + "death_animation": "5503", + "defence_animation": "5489", + "defence_level": "85", + "lifepoints": "100", + "magic_animation": "5499", + "melee_animation": "5499", + "poison_immune": "true", + "projectile": "2718", + "range_animation": "5499", + "range_level": "1", + "safespot": null, + "start_gfx": "2713", + "strength_level": "95" + }, + { + "id": "5385", + "name": "Skeleton", + "examine": "A skeleton in a dress!", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "57", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "57", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "5386", + "name": "Skeleton", + "examine": "Achingly thin.", + "aggressive": "true", + "attack_level": "55", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "8" + }, + { + "id": "5387", + "name": "Skeleton", + "examine": "Look: another skeleton.", + "aggressive": "true", + "attack_level": "55", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "8" + }, + { + "id": "5388", + "name": "Skeleton", + "examine": "That skeleton's grinning at me.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "8" + }, + { + "id": "5389", + "name": "Skeleton", + "examine": "He needs a tan.", + "aggressive": "true", + "attack_level": "51", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "51", + "lifepoints": "72", + "magic_animation": "0", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "51", + "weakness": "8" + }, + { + "id": "5390", + "name": "Skeleton", + "examine": "How do you know if a skeleton's male or female?", + "aggressive": "true", + "attack_level": "36", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "420", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36" + }, + { + "id": "5391", + "name": "Skeleton", + "examine": "He obviously hasn't realised he's dead.", + "aggressive": "true", + "attack_level": "55", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "8" + }, + { + "id": "5392", + "name": "Skeleton", + "examine": "Put some meat on those bones!", + "aggressive": "true", + "attack_level": "52", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "52", + "weakness": "8" + }, + { + "id": "5393", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "56", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5394", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "40", + "melee_animation": "5578", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5395", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5396", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5397", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5398", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5399", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5400", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5401", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5402", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5403", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5404", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5569", + "defence_animation": "5567", + "defence_level": "1", + "lifepoints": "92", + "melee_animation": "5568", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5405", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5406", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5407", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5408", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5409", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5410", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "5411", + "name": "Skeleton", + "examine": "An angry skeleton.", + "aggressive": "true", + "attack_level": "55", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "8" + }, + { + "id": "5412", + "name": "Skeleton", + "examine": "Cross bones.", + "aggressive": "true", + "attack_level": "57", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "57", + "lifepoints": "81", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "57", + "weakness": "8" + }, + { + "id": "5413", + "name": "Possessed pickaxe", + "examine": "How does it move of its own accord?", + "aggressive": "true", + "attack_level": "55", + "death_animation": "5592", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5591", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "6" + }, + { + "id": "5414", + "name": "Animated spade", + "examine": "How does it move of its own accord?", + "attack_level": "52", + "death_animation": "5596", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "74", + "magic_animation": "0", + "melee_animation": "5597", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "52", + "weakness": "6" + }, + { + "id": "5415", + "name": "Terror dog statue" + }, + { + "id": "5416", + "name": "Terror dog statue" + }, + { + "id": "5417", + "name": "Terror dog", + "examine": "A terrifying dog beast.", + "aggressive": "true", + "attack_level": "47", + "attack_speed": "5", + "death_animation": "5628", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "134", + "magic_animation": "0", + "melee_animation": "5625", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "1" + }, + { + "id": "5418", + "name": "Terror dog", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "5627", + "defence_animation": "5626", + "defence_level": "1", + "lifepoints": "82", + "melee_animation": "5625", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5419", + "name": "Tarn" + }, + { + "id": "5420", + "name": "Tarn", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "5619", + "defence_animation": "5618", + "defence_level": "1", + "lifepoints": "65", + "melee_animation": "5617", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5421", + "name": "Mutant tarn", + "examine": "I preferred him when he was human.", + "aggressive": "true", + "attack_level": "57", + "attack_speed": "6", + "death_animation": "5619", + "defence_animation": "0", + "defence_level": "57", + "lifepoints": "325", + "magic_animation": "0", + "melee_animation": "5617", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "57", + "weakness": "6" + }, + { + "id": "5422", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "63", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "5485", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "63", + "weakness": "8" + }, + { + "id": "5423", + "name": "Larry" + }, + { + "id": "5425", + "name": "Larry" + }, + { + "id": "5426", + "name": "Larry" + }, + { + "id": "5427", + "name": "Penguin" + }, + { + "id": "5429", + "name": "Penguin" + }, + { + "id": "5430", + "name": "Penguin" + }, + { + "id": "5431", + "name": "KGP Guard" + }, + { + "id": "5432", + "name": "Pescaling Pax" + }, + { + "id": "5433", + "name": "Ping" + }, + { + "id": "5434", + "name": "Ping" + }, + { + "id": "5435", + "name": "Pong" + }, + { + "id": "5436", + "name": "Pong" + }, + { + "id": "5437", + "name": "Ping" + }, + { + "id": "5438", + "name": "Pong" + }, + { + "id": "5439", + "name": "null", + "examine": "What restful music!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5442", + "name": "KGP Agent", + "examine": "What restful music!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5443", + "name": "Noodle" + }, + { + "id": "5445", + "name": "Penguin" + }, + { + "id": "5446", + "name": "Penguin suit" + }, + { + "id": "5447", + "name": "Agility Instructor", + "examine": "Instructs agility.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5448", + "name": "Army Commander", + "examine": "An army commander.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5449", + "name": "Penguin" + }, + { + "id": "5450", + "name": "Penguin" + }, + { + "id": "5451", + "name": "Penguin" + }, + { + "id": "5452", + "name": "Icelord", + "examine": "Sturdy cold being.", + "aggressive": "true", + "attack_level": "22", + "death_animation": "5726", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "5724", + "range_animation": "5725", + "range_level": "30", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "0" + }, + { + "id": "5453", + "name": "Icelord", + "examine": "Sturdy cold being.", + "aggressive": "true", + "attack_level": "30", + "death_animation": "5726", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "5724", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "9" + }, + { + "id": "5454", + "name": "Icelord", + "examine": "Sturdy cold being.", + "aggressive": "true", + "attack_level": "30", + "death_animation": "5726", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "5724", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "9" + }, + { + "id": "5455", + "name": "Icelord", + "examine": "Sturdy cold being.", + "aggressive": "true", + "attack_level": "30", + "death_animation": "5726", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "5724", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "9" + }, + { + "id": "5456", + "name": "Crusher" + }, + { + "id": "5457", + "name": "Crusher" + }, + { + "id": "5458", + "name": "Crusher" + }, + { + "id": "5459", + "name": "Crusher" + }, + { + "id": "5460", + "name": "Tree" + }, + { + "id": "5461", + "name": "Jungle Tree" + }, + { + "id": "5462", + "name": "Tolna" + }, + { + "id": "5463", + "name": "Honour guard" + }, + { + "id": "5464", + "name": "Honour guard" + }, + { + "id": "5465", + "name": "Fridleif Shieldson" + }, + { + "id": "5466", + "name": "Thakkrad Sigmundson" + }, + { + "id": "5467", + "name": "Iceberg" + }, + { + "id": "5468", + "name": "Iceberg" + }, + { + "id": "5469", + "name": "Arctic Pine" + }, + { + "id": "5470", + "name": "Fishing spot" + }, + { + "id": "5471", + "name": "Fishing spot" + }, + { + "id": "5472", + "name": "Ice Troll King", + "examine": "An impressive-looking troll.", + "aggressive": "true", + "attack_level": "65", + "death_animation": "5209", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "185", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "5374", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "5473", + "name": "Ice troll runt", + "examine": "An ice troll youngling.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "70", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "70", + "weakness": "9" + }, + { + "id": "5474", + "name": "Ice troll male", + "examine": "A male troll wielding a large club.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "40", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "9" + }, + { + "id": "5475", + "name": "Ice troll female", + "examine": "An ice troll with a bag of rocks.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "40", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "1142", + "projectile": "276", + "range_animation": "1142", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "0" + }, + { + "id": "5476", + "name": "Ice troll grunt", + "examine": "A large ice troll.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "4332", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "9" + }, + { + "id": "5477", + "name": "Bork Sigmundson" + }, + { + "id": "5478", + "name": "King Gjuki Sorvott IV", + "examine": "An ill-tempered king.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5479", + "name": "HRH Hrafn", + "examine": "A regal cat with an evil glint in its eye.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5480", + "name": "Thorkel Silkbeard", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5481", + "name": "Mord Gunnars" + }, + { + "id": "5482", + "name": "Mord Gunnars" + }, + { + "id": "5483", + "name": "Hring Hring", + "examine": "Harder than the rocks he sells.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5484", + "name": "Flossi Dalksson", + "examine": "Jatizso's fishmonger.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5485", + "name": "Raum Urda-Stein", + "examine": "A guy that will sell you armour.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5486", + "name": "Skuli Myrka", + "examine": "Jatizso's armour merchant.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5487", + "name": "Keepa Kettilon", + "examine": "A rough-looking chef.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5488", + "name": "Magnus Gram", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "facing_booth": "true", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5489", + "name": "Guard", + "examine": "A guard on insult duty.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5490", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5491", + "name": "Guard", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5492", + "name": "Guard", + "examine": "One of King Sorvott's militia.", + "aggressive": "true", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5493", + "name": "Freygerd", + "examine": "One of Jatizso's many citizens.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5494", + "name": "Lensa", + "examine": "One of Jatizso's many citizens.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5495", + "name": "Vanligga Gastfrihet", + "examine": "A happy, friendly landlady.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5496", + "name": "Sassilik", + "examine": "One of Jatizso's many citizens.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5497", + "name": "Miner", + "examine": "A miner at work.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5498", + "name": "Miner" + }, + { + "id": "5499", + "name": "Eric", + "examine": "A bedraggled-looking tramp.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5500", + "name": "Gruva Patrull", + "examine": "Mina guards the mine entrance.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5501", + "name": "Brendt", + "examine": "A dwarven trader from Keldagrim.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5502", + "name": "Grundt" + }, + { + "id": "5503", + "name": "Mawnis Burowgar" + }, + { + "id": "5504", + "name": "Mawnis Burowgar" + }, + { + "id": "5505", + "name": "Fridleif Shieldson" + }, + { + "id": "5506", + "name": "Thakkrad Sigmundson" + }, + { + "id": "5507", + "name": "Maria Gunnars" + }, + { + "id": "5508", + "name": "Maria Gunnars" + }, + { + "id": "5509", + "name": "Jofridr Mordstatter" + }, + { + "id": "5510", + "name": "Morten Holdstrom" + }, + { + "id": "5511", + "name": "Gunnar Holdstrom" + }, + { + "id": "5512", + "name": "Anne Isaakson" + }, + { + "id": "5513", + "name": "Lisse Isaakson" + }, + { + "id": "5514", + "name": "Honour guard", + "examine": "The Burgher's protectors.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5515", + "name": "Honour Guard", + "examine": "One of the Burgher's Protectors", + "death_animation": "836", + "defence_animation": "404", + "melee_animation": "395" + }, + { + "id": "5516", + "name": "Honour guard", + "examine": "The Burgher's protectors.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5517", + "name": "Honour guard", + "examine": "One of your militia.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "9" + }, + { + "id": "5518", + "name": "Kjedelig Uppsen" + }, + { + "id": "5519", + "name": "Trogen Konungarde" + }, + { + "id": "5520", + "name": "Slug Hemligssen" + }, + { + "id": "5521", + "name": "Ice troll runt", + "examine": "An ice troll youngling.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "70", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "70", + "weakness": "9" + }, + { + "id": "5522", + "name": "Ice troll male", + "examine": "A male troll wielding a large club.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "40", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "9" + }, + { + "id": "5523", + "name": "Ice troll female", + "examine": "An ice troll with a bag of rocks.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "40", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "1142", + "projectile": "276", + "range_animation": "1142", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "0" + }, + { + "id": "5524", + "name": "Ice troll grunt", + "examine": "A large ice troll.", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "4332", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "100", + "weakness": "9" + }, + { + "id": "5525", + "name": "Ice troll runt", + "examine": "An ice troll youngling.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "70", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "70", + "weakness": "9" + }, + { + "id": "5526", + "name": "Ice troll male", + "examine": "A male troll wielding a large club.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "40", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "284", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "9" + }, + { + "id": "5527", + "name": "Ice troll female", + "examine": "An ice troll with a bag of rocks.", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "4", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "combat_style": "1", + "death_animation": "287", + "defence_animation": "285", + "defence_level": "40", + "lifepoints": "80", + "magic_animation": "0", + "melee_animation": "1142", + "projectile": "276", + "range_animation": "1142", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "80", + "weakness": "0" + }, + { + "id": "5528", + "name": "Ice troll grunt" + }, + { + "id": "5529", + "name": "Yak", + "examine": "A hairy, smelly, grazing animal.", + "attack_level": "20", + "attack_speed": "4", + "combat_audio": "3378,3380,3379", + "death_animation": "5784", + "defence_animation": "5783", + "defence_level": "1", + "lifepoints": "50", + "magic_animation": "5782", + "melee_animation": "5782", + "range_animation": "5782", + "range_level": "1", + "safespot": null, + "strength_level": "10", + "weakness": "7" + }, + { + "id": "5530", + "name": "Sorceress" + }, + { + "id": "5531", + "name": "Sorceress", + "examine": "Antisocial.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5532", + "name": "Apprentice", + "examine": "Come", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5533", + "name": "Autumn Elemental", + "examine": "An autumn elemental.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5539", + "name": "Spring Elemental", + "examine": "A spring elemental.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5547", + "name": "Summer Elemental", + "examine": "A summer elemental.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5553", + "name": "Winter Elemental", + "examine": "A winter elemental.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5560", + "name": "Osman" + }, + { + "id": "5561", + "name": "Osman", + "examine": "It dare attack Pretty Lass? Thok crush its puny skull!", + "aggressive": "true", + "attack_level": "95", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "157", + "magic_animation": "0", + "magic_level": "95", + "range_animation": "0", + "range_level": "95", + "safespot": null, + "strength_level": "95", + "weakness": "10" + }, + { + "id": "5562", + "name": "Del-Monty" + }, + { + "id": "5564", + "name": "Bouncer" + }, + { + "id": "5565", + "name": "Bouncer" + }, + { + "id": "5566", + "name": "General Khazard" + }, + { + "id": "5567", + "name": "Scout" + }, + { + "id": "5568", + "name": "Scout" + }, + { + "id": "5569", + "name": "Scout" + }, + { + "id": "5570", + "name": "Scout" + }, + { + "id": "5571", + "name": "Sin Seer", + "examine": "She's honest about the things you aren't.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5572", + "name": "Ghost", + "examine": "A Shadow Realm guardian.", + "attack_level": "1", + "combat_audio": "436,439,438", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "5573", + "name": "Effigy" + }, + { + "id": "5579", + "name": "Effigy" + }, + { + "id": "5580", + "name": "Bonafido" + }, + { + "id": "5581", + "name": "Homunculus", + "examine": "Is it male or female?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5582", + "name": "Homunculus" + }, + { + "id": "5583", + "name": "Homunculus" + }, + { + "id": "5584", + "name": "Cage", + "examine": "Strong", + "aggressive": "true", + "attack_level": "95", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "85", + "magic_animation": "0", + "magic_level": "95", + "range_animation": "0", + "range_level": "95", + "safespot": null, + "strength_level": "95", + "weakness": "10" + }, + { + "id": "5585", + "name": "'Transmute' The Alchemist" + }, + { + "id": "5586", + "name": "'Transmute' The Alchemist" + }, + { + "id": "5587", + "name": "'Currency' The Alchemist" + }, + { + "id": "5588", + "name": "'Currency' The Alchemist" + }, + { + "id": "5589", + "name": "'Black-eye", + "examine": "Famous for his fights.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5590", + "name": "'No fingers", + "examine": "Count them pinkies!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5591", + "name": "'Gummy", + "examine": "He wishes he had teeth.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5592", + "name": "'The Guns'" + }, + { + "id": "5593", + "name": "Frogeel", + "examine": "Is it a frog", + "aggressive": "true", + "attack_level": "36", + "attack_speed": "5", + "death_animation": "5841", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "melee_animation": "5842", + "range_animation": "0", + "range_level": "49", + "respawn_delay": "60", + "safespot": null, + "strength_level": "36", + "weakness": "2" + }, + { + "id": "5594", + "name": "Spidine", + "attack_level": "1", + "death_animation": "146", + "defence_animation": "144", + "defence_level": "1", + "lifepoints": "35", + "melee_animation": "143", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5595", + "name": "Swordchick", + "examine": "Definitely not a chicken or a swordfish.", + "attack_level": "45", + "attack_speed": "5", + "death_animation": "5389", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "5387", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "45", + "weakness": "7" + }, + { + "id": "5596", + "name": "Jubster", + "aggressive": "true", + "attack_level": "1", + "death_animation": "6801", + "defence_animation": "6802", + "defence_level": "1", + "lifepoints": "60", + "melee_animation": "6800", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5597", + "name": "Newtroost", + "examine": "Since when did newts have beaks?", + "attack_level": "40", + "death_animation": "2301", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "2299", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "40", + "weakness": "7" + }, + { + "id": "5598", + "name": "Unicow" + }, + { + "id": "5603", + "name": "Unicow", + "examine": "Half unicorn", + "aggressive": "true", + "attack_level": "30", + "attack_speed": "5", + "death_animation": "5851", + "defence_animation": "0", + "defence_level": "41", + "lifepoints": "58", + "magic_animation": "0", + "magic_level": "41", + "melee_animation": "5849", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "4" + }, + { + "id": "5604", + "name": "Elfinlocks" + }, + { + "id": "5605", + "name": "Clockwork cat" + }, + { + "id": "5606", + "name": "Clockwork cat" + }, + { + "id": "5608", + "name": "Monk", + "examine": "Holier than thou.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5609", + "name": "Monk", + "examine": "Holier than thou.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5610", + "name": "Monk", + "examine": "Holier than thou.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5611", + "name": "Monk", + "examine": "Holier than thou.", + "attack_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5612", + "name": "Rufus" + }, + { + "id": "5613", + "name": "Mi-Gor" + }, + { + "id": "5614", + "name": "Puffin", + "examine": "I'd prefer it if it were a muffin...", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5615", + "name": "Puffin" + }, + { + "id": "5616", + "name": "Brother Tranquility" + }, + { + "id": "5617", + "name": "Brother Tranquility" + }, + { + "id": "5618", + "name": "Brother Tranquility" + }, + { + "id": "5619", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5620", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5621", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5622", + "name": "Monk", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5623", + "name": "Zombie monk" + }, + { + "id": "5624", + "name": "Zombie monk" + }, + { + "id": "5625", + "name": "Zombie monk" + }, + { + "id": "5626", + "name": "Zombie monk" + }, + { + "id": "5627", + "name": "Sorebones", + "examine": "Bedside manner is a little lacking", + "attack_level": "35", + "death_animation": "5658", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5643", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5628", + "name": "Sorebones", + "examine": "I hope his hands don't shake.", + "attack_level": "35", + "death_animation": "5658", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5643", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5629", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5630", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5631", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5632", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5633", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5634", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5635", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5647", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5636", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5637", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5638", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5639", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5640", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5641", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5651", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5642", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5880", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5643", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5880", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5644", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5880", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5645", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5880", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5646", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5654", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5880", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5647", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5886", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5884", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5648", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5886", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5884", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5649", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5650", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5886", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5884", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5651", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5652", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5886", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5884", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5653", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5654", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5886", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5884", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5655", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5656", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5891", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5889", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5657", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5658", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5891", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5889", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5659", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5891", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5889", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5660", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5661", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5891", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5889", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5662", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5663", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5891", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5889", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5664", + "name": "Zombie pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "5649", + "defence_animation": "5648", + "defence_level": "1", + "lifepoints": "52", + "melee_animation": "5647", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5665", + "name": "Zombie pirate", + "examine": "Aaaarg", + "aggressive": "true", + "attack_level": "35", + "combat_audio": "703,705,704", + "death_animation": "5891", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "5889", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "6" + }, + { + "id": "5666", + "name": "Barrelchest", + "examine": "It's trying to mash you flat! Less examine", + "aggressive": "true", + "attack_level": "52", + "death_animation": "5898", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "285", + "magic_animation": "0", + "magic_level": "52", + "melee_animation": "5895", + "range_animation": "0", + "range_level": "52", + "respawn_delay": "60", + "safespot": null, + "strength_level": "52", + "weakness": "10" + }, + { + "id": "5667", + "name": "Undead Lumberjack" + }, + { + "id": "5679", + "name": "Undead Lumberjack" + }, + { + "id": "5680", + "name": "Undead Lumberjack", + "examine": "He is one", + "attack_level": "73", + "death_animation": "5972", + "defence_animation": "0", + "defence_level": "10", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "5970", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "73" + }, + { + "id": "5681", + "name": "Undead Lumberjack" + }, + { + "id": "5682", + "name": "Undead Lumberjack" + }, + { + "id": "5683", + "name": "Undead Lumberjack" + }, + { + "id": "5684", + "name": "Undead Lumberjack" + }, + { + "id": "5685", + "name": "Undead Lumberjack" + }, + { + "id": "5686", + "name": "Undead Lumberjack" + }, + { + "id": "5687", + "name": "Undead Lumberjack" + }, + { + "id": "5688", + "name": "Undead Lumberjack" + }, + { + "id": "5689", + "name": "Undead Lumberjack" + }, + { + "id": "5690", + "name": "Undead Lumberjack" + }, + { + "id": "5691", + "name": "Undead Lumberjack" + }, + { + "id": "5692", + "name": "Undead Lumberjack" + }, + { + "id": "5693", + "name": "Undead Lumberjack" + }, + { + "id": "5694", + "name": "Undead Lumberjack" + }, + { + "id": "5695", + "name": "Undead Lumberjack" + }, + { + "id": "5696", + "name": "Undead Lumberjack" + }, + { + "id": "5697", + "name": "Undead Lumberjack" + }, + { + "id": "5698", + "name": "Undead Lumberjack" + }, + { + "id": "5699", + "name": "Undead Lumberjack" + }, + { + "id": "5700", + "name": "Undead Lumberjack" + }, + { + "id": "5701", + "name": "Undead Lumberjack" + }, + { + "id": "5702", + "name": "Undead Lumberjack" + }, + { + "id": "5703", + "name": "Undead Lumberjack" + }, + { + "id": "5704", + "name": "Undead Lumberjack" + }, + { + "id": "5705", + "name": "Undead Lumberjack" + }, + { + "id": "5706", + "name": "Undead Lumberjack" + }, + { + "id": "5707", + "name": "Undead Lumberjack" + }, + { + "id": "5708", + "name": "Undead Lumberjack" + }, + { + "id": "5709", + "name": "Undead Lumberjack" + }, + { + "id": "5710", + "name": "Undead Lumberjack" + }, + { + "id": "5711", + "name": "Undead Lumberjack" + }, + { + "id": "5712", + "name": "Undead Lumberjack" + }, + { + "id": "5713", + "name": "Undead Lumberjack" + }, + { + "id": "5714", + "name": "Undead Lumberjack" + }, + { + "id": "5715", + "name": "Undead Lumberjack" + }, + { + "id": "5716", + "name": "Undead Lumberjack" + }, + { + "id": "5717", + "name": "Undead Lumberjack" + }, + { + "id": "5718", + "name": "Undead Lumberjack" + }, + { + "id": "5719", + "name": "Undead Lumberjack" + }, + { + "id": "5720", + "name": "Undead Lumberjack" + }, + { + "id": "5721", + "name": "Undead Lumberjack" + }, + { + "id": "5722", + "name": "Undead Lumberjack" + }, + { + "id": "5723", + "name": "Undead Lumberjack" + }, + { + "id": "5724", + "name": "Undead Lumberjack" + }, + { + "id": "5725", + "name": "Undead Lumberjack" + }, + { + "id": "5726", + "name": "Undead Lumberjack" + }, + { + "id": "5727", + "name": "Undead Lumberjack" + }, + { + "id": "5728", + "name": "Undead Lumberjack" + }, + { + "id": "5729", + "name": "Undead Lumberjack" + }, + { + "id": "5730", + "name": "Undead Lumberjack" + }, + { + "id": "5731", + "name": "Undead Lumberjack" + }, + { + "id": "5732", + "name": "Undead Lumberjack" + }, + { + "id": "5733", + "name": "Undead Lumberjack" + }, + { + "id": "5734", + "name": "Undead Lumberjack" + }, + { + "id": "5735", + "name": "Undead Lumberjack" + }, + { + "id": "5736", + "name": "Undead Lumberjack" + }, + { + "id": "5737", + "name": "Undead Lumberjack" + }, + { + "id": "5738", + "name": "Undead Lumberjack" + }, + { + "id": "5739", + "name": "Undead Lumberjack" + }, + { + "id": "5740", + "name": "Undead Lumberjack" + }, + { + "id": "5741", + "name": "Undead Lumberjack" + }, + { + "id": "5742", + "name": "Undead Lumberjack" + }, + { + "id": "5743", + "name": "Undead Lumberjack" + }, + { + "id": "5744", + "name": "Undead Lumberjack" + }, + { + "id": "5745", + "name": "Undead Lumberjack" + }, + { + "id": "5746", + "name": "Undead Lumberjack" + }, + { + "id": "5747", + "name": "Undead Lumberjack" + }, + { + "id": "5748", + "name": "Fishing spot" + }, + { + "id": "5749", + "name": "Fishing spot" + }, + { + "id": "5750", + "name": "Cave bug", + "examine": "A big", + "attack_level": "82", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,72,59,35,25,95,0,0,0,0,0", + "death_animation": "6081", + "defence_animation": "0", + "defence_level": "84", + "lifepoints": "93", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "6079", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "93", + "strength_level": "80", + "weakness": "2" + }, + { + "id": "5751", + "name": "Molanisk", + "examine": "A strange mole-like being.", + "aggressive": "true", + "attack_level": "40", + "attack_speed": "4", + "clue_level": "1", + "combat_audio": "3492,3494,3493", + "death_animation": "6014", + "defence_animation": "6013", + "defence_level": "50", + "lifepoints": "52", + "magic_level": "1", + "melee_animation": "6012", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "52", + "strength_level": "40" + }, + { + "id": "5752", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5753", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5754", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5755", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5756", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5757", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5758", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5759", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5760", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5761", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5762", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5763", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5764", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5765", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5766", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5767", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5768", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5769", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5770", + "name": "Ur-zek" + }, + { + "id": "5771", + "name": "Ur-vass" + }, + { + "id": "5772", + "name": "Ur-taal" + }, + { + "id": "5773", + "name": "Ur-meg" + }, + { + "id": "5774", + "name": "Ur-lun" + }, + { + "id": "5775", + "name": "Ur-pel" + }, + { + "id": "5776", + "name": "Banker", + "examine": "Looks after cave goblin money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5777", + "name": "Banker", + "examine": "Looks after cave goblin money.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5778", + "name": "Bartak" + }, + { + "id": "5779", + "name": "Turgall" + }, + { + "id": "5780", + "name": "Reldak" + }, + { + "id": "5781", + "name": "Miltog" + }, + { + "id": "5782", + "name": "Mernik" + }, + { + "id": "5783", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5784", + "name": "Crate goblin", + "examine": "Taking a terribly important box from one place to another.", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5785", + "name": "Cave goblin", + "examine": "One of the many citizens of Dorgesh-Kaan.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5786", + "name": "Goblin scribe", + "examine": "Good at shorthand.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5787", + "name": "Gourmet" + }, + { + "id": "5789", + "name": "Gourmet" + }, + { + "id": "5790", + "name": "Gourmet" + }, + { + "id": "5791", + "name": "Gourmet" + }, + { + "id": "5792", + "name": "Turgok" + }, + { + "id": "5793", + "name": "Markog" + }, + { + "id": "5794", + "name": "Durgok" + }, + { + "id": "5795", + "name": "Tindar" + }, + { + "id": "5796", + "name": "Gundik" + }, + { + "id": "5797", + "name": "Zenkog" + }, + { + "id": "5798", + "name": "Lurgon" + }, + { + "id": "5799", + "name": "Ur-tag" + }, + { + "id": "5800", + "name": "Guard", + "examine": "He keeps order in the city.", + "attack_level": "42", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "6003", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "42", + "weakness": "6" + }, + { + "id": "5801", + "name": "Guard", + "examine": "He keeps order in the city.", + "attack_level": "42", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "6003", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "6007", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "42", + "weakness": "6" + }, + { + "id": "5802", + "name": "Young 'un" + }, + { + "id": "5803", + "name": "Young 'un", + "examine": "A goblin baby.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5804", + "name": "Tyke" + }, + { + "id": "5805", + "name": "Nipper", + "examine": "A goblin baby.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5806", + "name": "Nipper" + }, + { + "id": "5807", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5808", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5809", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5810", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5811", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5812", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5813", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5814", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5815", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5816", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5817", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5818", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5819", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5820", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5821", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5822", + "name": "Cave goblin child", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5823", + "name": "Spit goblin", + "examine": "Don't spit", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5824", + "name": "Goblin fish", + "examine": "A bug-eyed little goblin fish. How cute.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5825", + "name": "Movario" + }, + { + "id": "5826", + "name": "Darve" + }, + { + "id": "5827", + "name": "Moths", + "examine": "Annoying little flappy things.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5828", + "name": "Barlak" + }, + { + "id": "5829", + "name": "Rabbit", + "attack_level": "1", + "death_animation": "6092", + "defence_animation": "6091", + "defence_level": "1", + "lifepoints": "5", + "melee_animation": "6090", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5830", + "name": "Rat Burgiss" + }, + { + "id": "5833", + "name": "Rat Burgiss", + "attack_level": "1", + "combat_audio": "703,705,704", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5834", + "name": "Surok Magis", + "examine": "A powerful wizard." + }, + { + "id": "5835", + "name": "Surok Magis" + }, + { + "id": "5836", + "name": "Zaff" + }, + { + "id": "5837", + "name": "Anna Jones" + }, + { + "id": "5838", + "name": "King Roald" + }, + { + "id": "5839", + "name": "Mishkal'un Dorn" + }, + { + "id": "5840", + "name": "Dakh'thoulan Aegis" + }, + { + "id": "5841", + "name": "Sil'as Dahcsnu" + }, + { + "id": "5842", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5843", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5844", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5845", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5846", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5847", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5848", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5849", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5850", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5851", + "name": "Outlaw", + "examine": "A mean looking outlaw. Don't get too close!", + "attack_level": "23", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "23", + "lifepoints": "32", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "23", + "weakness": "9" + }, + { + "id": "5852", + "name": "Monkey", + "examine": "Weird eyeball thing. Reminds Thok of breakfast.", + "aggressive": "true", + "attack_level": "60", + "combat_audio": "629,631,630", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "85", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "0", + "range_animation": "0", + "range_level": "60", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "5853", + "name": "Bench" + }, + { + "id": "5854", + "name": "Bench", + "examine": "For sitting on.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5855", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5856", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5857", + "name": "Zanik" + }, + { + "id": "5858", + "name": "Ur-tag" + }, + { + "id": "5859", + "name": "H.A.M. Archer", + "examine": "He looks pretty skilled with that bow.", + "aggressive": "true", + "attack_level": "15", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "57", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "0", + "range_level": "20", + "safespot": null, + "strength_level": "15", + "weakness": "0" + }, + { + "id": "5860", + "name": "H.A.M. Mage", + "examine": "He bristles with arcane power.", + "aggressive": "true", + "attack_level": "15", + "clue_level": "0", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "57", + "magic_animation": "0", + "magic_level": "20", + "melee_animation": "429", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "15", + "weakness": "3" + }, + { + "id": "5861", + "name": "Zanik", + "examine": "No match for Thok. Silly demon.", + "aggressive": "true", + "attack_level": "85", + "defence_animation": "0", + "defence_level": "85", + "lifepoints": "71", + "magic_animation": "0", + "magic_level": "85", + "range_level": "85", + "safespot": null, + "strength_level": "85", + "weakness": "10" + }, + { + "id": "5862", + "name": "Sigmund and Zanik" + }, + { + "id": "5863", + "name": "Ambassador Alvijar" + }, + { + "id": "5864", + "name": "Builder", + "examine": "A worker on the train link.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5865", + "name": "Builder", + "examine": "A worker on the train link.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5866", + "name": "Builder", + "examine": "A worker on the train link.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5867", + "name": "Builder", + "examine": "A worker on the train link.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5868", + "name": "Tegdak" + }, + { + "id": "5869", + "name": "Zanik" + }, + { + "id": "5871", + "name": "Sergeant Mossfists" + }, + { + "id": "5872", + "name": "Sergeant Slimetoes" + }, + { + "id": "5873", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5874", + "name": "Cave goblin", + "examine": "A goblin with big", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5875", + "name": "Cave goblin", + "examine": "A goblin with big", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5876", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5877", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5878", + "name": "Cave goblin", + "attack_level": "1", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5879", + "name": "Ticket goblin", + "examine": "He sells tickets to Keldagrim.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5880", + "name": "Dwarf", + "examine": "A dwarf from Keldagrim.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "5881", + "name": "Dwarf", + "examine": "A dwarf from Keldagrim.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "5882", + "name": "Dwarf", + "examine": "A dwarf from Keldagrim.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "5883", + "name": "Dwarf", + "examine": "A dwarf from Keldagrim.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "5884", + "name": "Dwarf", + "examine": "A dwarf from Keldagrim.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "5885", + "name": "Dwarf", + "examine": "A dwarf from Keldagrim.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "16", + "strength_level": "1" + }, + { + "id": "5886", + "name": "Ticket dwarf", + "examine": "He sells tickets to Dorgesh-Kaan.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5887", + "name": "Cyrisus" + }, + { + "id": "5894", + "name": "Cyrisus" + }, + { + "id": "5895", + "name": "Cyrisus" + }, + { + "id": "5896", + "name": "Cyrisus" + }, + { + "id": "5897", + "name": "Cyrisus" + }, + { + "id": "5898", + "name": "'Bird's-Eye' Jack" + }, + { + "id": "5899", + "name": "The Inadequacy" + }, + { + "id": "5902", + "name": "The Inadequacy", + "examine": "Are you good enough to fight?", + "aggressive": "true", + "attack_level": "70", + "death_animation": "6322", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "6318", + "range_animation": "0", + "range_level": "70", + "respawn_delay": "60", + "safespot": null, + "strength_level": "70", + "weakness": "10" + }, + { + "id": "5903", + "name": "The Everlasting", + "examine": "Can you endure long enough?", + "aggressive": "true", + "attack_level": "67", + "death_animation": "6347", + "defence_animation": "0", + "defence_level": "67", + "lifepoints": "191", + "magic_animation": "0", + "magic_level": "67", + "melee_animation": "6345", + "range_animation": "0", + "range_level": "67", + "respawn_delay": "60", + "safespot": null, + "strength_level": "67", + "weakness": "10" + }, + { + "id": "5904", + "name": "The Untouchable", + "examine": "Can you bring yourself to hurt another?", + "aggressive": "true", + "attack_level": "65", + "death_animation": "6331", + "defence_animation": "0", + "defence_level": "75", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "6329", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "5905", + "name": "The Illusive", + "examine": "What if you don't know how to win?", + "aggressive": "true", + "attack_level": "63", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "63", + "melee_animation": "6342", + "range_animation": "0", + "range_level": "63", + "respawn_delay": "60", + "safespot": null, + "strength_level": "63", + "weakness": "10" + }, + { + "id": "5906", + "name": "A Doubt", + "examine": "You can't escape your inadequacy!", + "aggressive": "true", + "attack_level": "55", + "death_animation": "6315", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "6310", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "8" + }, + { + "id": "5907", + "name": "The Illusive" + }, + { + "id": "5908", + "name": "Dying tree", + "examine": "Dead stone defending a dead throne room.", + "aggressive": "true", + "attack_level": "50", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "142", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "7" + }, + { + "id": "5909", + "name": "Barbarian", + "examine": "Don't let her arm-wrestle you for money.", + "attack_level": "20", + "clue_level": "0", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "20", + "lifepoints": "28", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "7" + }, + { + "id": "5910", + "name": "Cook", + "examine": "A greasy, grimy gourmet.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5911", + "name": "Cook", + "examine": "He's suspiciously talented with a meat-cleaver.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5912", + "name": "Banker" + }, + { + "id": "5913", + "name": "Banker" + }, + { + "id": "5914", + "name": "Iffie", + "examine": "This grizzled soldier is here to distribute Rated Clan Wars badges.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5915", + "name": "Elsie" + }, + { + "id": "5916", + "name": "Cleaner", + "examine": "Does what too many people aren't interested in doing.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5917", + "name": "Stray dog", + "examine": "A mangy mutt.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5918", + "name": "Stray dog" + }, + { + "id": "5919", + "name": "Guard", + "examine": "He tries to keep order around here. His bizarre uniform isn't helping.", + "attack_level": "18", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "2548,1979,512", + "death_animation": "6490", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "6489", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "18", + "weakness": "6" + }, + { + "id": "5920", + "name": "Guard", + "examine": "He tries to keep order around here. His bizarre uniform isn't helping.", + "attack_level": "18", + "attack_speed": "5", + "clue_level": "1", + "combat_audio": "2548,1979,512", + "death_animation": "6490", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "6489", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "18", + "weakness": "6" + }, + { + "id": "5921", + "name": "Trainee Guard", + "examine": "He's studying to be a guard.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5922", + "name": "Captain", + "examine": "Trains the guards of the future.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5923", + "name": "Man", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" + }, + { + "id": "5924", + "name": "Woman", + "examine": "One of Gielinor's many citizens.", + "attack_level": "3", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "511,506,505", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "9" + }, + { + "id": "5925", + "name": "Benny", + "examine": "Newspaper seller." + }, + { + "id": "5926", + "name": "Thief", + "examine": "Known for his light-fingered qualities.", + "attack_level": "9", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "9" + }, + { + "id": "5927", + "name": "Thief", + "examine": "Known for his light-fingered qualities.", + "attack_level": "9", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "9" + }, + { + "id": "5928", + "name": "Thief", + "examine": "Known for her light-fingered qualities.", + "attack_level": "9", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "24", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "9" + }, + { + "id": "5929", + "name": "Thief", + "examine": "Known for her light-fingered qualities.", + "attack_level": "9", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "24", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "9" + }, + { + "id": "5930", + "name": "Art Critic Jacques", + "examine": "Jacques Netis - a slightly pompous art expert.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5931", + "name": "Historian Minas", + "examine": "Seth Minas - an aged expert in Gielinor history.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5932", + "name": "Barnabus Hurma" + }, + { + "id": "5933", + "name": "Marius Giste" + }, + { + "id": "5934", + "name": "Caden Azro" + }, + { + "id": "5935", + "name": "Thias Leacke" + }, + { + "id": "5936", + "name": "Sinco Doar" + }, + { + "id": "5937", + "name": "Tinse Torpe" + }, + { + "id": "5938", + "name": "Information clerk", + "examine": "A lady with lots of information about the Museum.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5939", + "name": "Torrcs" + }, + { + "id": "5940", + "name": "Marfet" + }, + { + "id": "5941", + "name": "Museum guard" + }, + { + "id": "5942", + "name": "Museum guard" + }, + { + "id": "5943", + "name": "Museum guard" + }, + { + "id": "5944", + "name": "Teacher and pupil", + "examine": "A teacher and one of his pupils.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5945", + "name": "Schoolboy", + "examine": "Looks kind of familiar.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5946", + "name": "Schoolboy" + }, + { + "id": "5947", + "name": "Teacher and pupil", + "examine": "A teacher and one of her pupils.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5948", + "name": "Teacher and pupil" + }, + { + "id": "5949", + "name": "Schoolboy" + }, + { + "id": "5950", + "name": "Teacher" + }, + { + "id": "5951", + "name": "Schoolgirl" + }, + { + "id": "5952", + "name": "Workman", + "examine": "Looks hard at work.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5953", + "name": "Workman" + }, + { + "id": "5954", + "name": "Workman", + "examine": "Could there be something exciting in his wheelbarrow?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5955", + "name": "Workman" + }, + { + "id": "5956", + "name": "Void Knight", + "examine": "A powerful knight of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5957", + "name": "Schoolgirl" + }, + { + "id": "5958", + "name": "Digsite workman", + "examine": "Wheelbarrow loader.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5959", + "name": "Barge workman", + "examine": "Working hard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5960", + "name": "Barge workman", + "examine": "Working hard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5961", + "name": "Barge workman", + "examine": "Working hard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5962", + "name": "Barge workman", + "examine": "Working hard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5963", + "name": "Barge foreman", + "examine": "Working hard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5964", + "name": "Ed Wood" + }, + { + "id": "5965", + "name": "Orlando Smith" + }, + { + "id": "5966", + "name": "Natural historian", + "examine": "An aged expert in natural history.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5967", + "name": "Natural historian" + }, + { + "id": "5968", + "name": "Natural historian" + }, + { + "id": "5969", + "name": "Natural historian" + }, + { + "id": "5970", + "name": "Natural historian" + }, + { + "id": "5971", + "name": "Leech display", + "examine": "Bloodsuckers!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5972", + "name": "Sea slugs display", + "examine": "Slugs of the sea variety.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5973", + "name": "Snail display", + "examine": "A house on its back.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5974", + "name": "Monkey display", + "examine": "A cheeky little monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5975", + "name": "Lizard display", + "examine": "A scaly little fellow.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5976", + "name": "Penguin display", + "examine": "Nice suit.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5977", + "name": "Camel display", + "examine": "He's got the hump.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5978", + "name": "Terrorbird display", + "examine": "Terrifying!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "34", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "1010", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "strength_level": "23" + }, + { + "id": "5979", + "name": "Dragon display", + "examine": "Looks like a fire-breather.", + "attack_level": "1", + "combat_audio": "408,410,409", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5980", + "name": "Wyvern display", + "examine": "Needs a good square meal.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5981", + "name": "Battle tortoise display", + "examine": "A huge beast.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5982", + "name": "Mole display", + "examine": "Loves making molehills.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5983", + "name": "Schoolgirl" + }, + { + "id": "5984", + "name": "Schoolgirl" + }, + { + "id": "5985", + "name": "Schoolgirl" + }, + { + "id": "5986", + "name": "Workman", + "examine": "It hides in stone", + "aggressive": "true", + "attack_level": "95", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "34", + "magic_animation": "0", + "magic_level": "95", + "range_animation": "0", + "range_level": "95", + "safespot": null, + "strength_level": "95", + "weakness": "10" + }, + { + "id": "5987", + "name": "Sylas", + "examine": "A gnarly old man." + }, + { + "id": "5988", + "name": "Miazrqa" + }, + { + "id": "5989", + "name": "Grimgnash" + }, + { + "id": "5990", + "name": "Rupert the Beard", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5991", + "name": "Drain pipe" + }, + { + "id": "5992", + "name": "Rupert the Beard", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5993", + "name": "Experiment No.2", + "examine": "A very odd looking creature.", + "attack_level": "46", + "death_animation": "6512", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "131", + "magic_animation": "0", + "magic_level": "46", + "melee_animation": "6513", + "range_animation": "0", + "range_level": "46", + "respawn_delay": "60", + "safespot": null, + "strength_level": "46", + "weakness": "10" + }, + { + "id": "5994", + "name": "Mouse", + "examine": "A huge mouse. It looks hungry...", + "aggressive": "true", + "attack_level": "44", + "death_animation": "6521", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "6519", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "44", + "weakness": "9" + }, + { + "id": "5995", + "name": "Mouse" + }, + { + "id": "5996", + "name": "Glod", + "aggressive": "true", + "attack_level": "1", + "death_animation": "6502", + "defence_animation": "6503", + "defence_level": "1", + "lifepoints": "160", + "melee_animation": "6501", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "5997", + "name": "Rupert the Beard" + }, + { + "id": "5999", + "name": "Rupert the Beard", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6000", + "name": "Rupert the Beard" + }, + { + "id": "6001", + "name": "Rupert the Beard", + "attack_level": "1", + "combat_audio": "498,500,499", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6002", + "name": "Gnome" + }, + { + "id": "6003", + "name": "Winkin" + }, + { + "id": "6004", + "name": "Gnome" + }, + { + "id": "6005", + "name": "Cage" + }, + { + "id": "6006", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6007", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6008", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6009", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6010", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6011", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6012", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6013", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6014", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6015", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6016", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6017", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6018", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6019", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6020", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6021", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6022", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6023", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6024", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6025", + "name": "Werewolf", + "examine": "Eek! A werewolf!", + "aggressive": "false", + "attack_level": "70", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "combat_audio": "481,491,490", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "", + "magic_level": "1", + "melee_animation": "6536", + "range_animation": "", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "70", + "weakness": "" + }, + { + "id": "6026", + "name": "Boris", + "examine": "A traveling man. Are those fleas?", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6027", + "name": "Imre", + "examine": "A well organised shop keeper.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6028", + "name": "Yuri", + "examine": "He's staring at the moon.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6029", + "name": "Joseph", + "examine": "He keeps calling me comrade.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6030", + "name": "Nikolai", + "examine": "There's a set of brows that mean business.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6031", + "name": "Eduard", + "examine": "This is one feral looking innkeeper.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6032", + "name": "Lev", + "examine": "A tough looking villager.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6033", + "name": "Georgy", + "examine": "A simple villager.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6034", + "name": "Svetlana", + "examine": "Seems a bit of a drama queen.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6035", + "name": "Irina", + "examine": "I bet she works out.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6036", + "name": "Alexis", + "examine": "She doesn't say much.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6037", + "name": "Milla", + "examine": "She looks like she can handle herself.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6038", + "name": "Galina", + "examine": "She seems light on her feet.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6039", + "name": "Sofiya", + "examine": "A wise villager.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6040", + "name": "Ksenia", + "examine": "Not exactly a warrior princess.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6041", + "name": "Yadviga", + "examine": "A well off villager.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6042", + "name": "Nikita", + "examine": "The woman.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6043", + "name": "Vera", + "examine": "She seems sure of herself.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6044", + "name": "Zoja", + "examine": "A healthy villager.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6045", + "name": "Liliya", + "examine": "She's looking for flowers.", + "attack_level": "10", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "10", + "lifepoints": "60", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "15", + "safespot": null, + "strength_level": "10" + }, + { + "id": "6046", + "name": "Big Wolf", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "909,912,911", + "death_animation": "6558", + "defence_animation": "6557", + "defence_level": "1", + "lifepoints": "74", + "melee_animation": "6559", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "74", + "strength_level": "1" + }, + { + "id": "6047", + "name": "Wolf", + "examine": "A vicious mountain wolf.", + "aggressive": "true", + "attack_level": "22", + "attack_speed": "6", + "combat_audio": "909,912,911", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "22", + "lifepoints": "69", + "magic_animation": "6579", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "safespot": null, + "slayer_exp": "34", + "strength_level": "1" + }, + { + "id": "6048", + "name": "Wolf", + "examine": "Now it has no armour", + "aggressive": "true", + "attack_level": "95", + "combat_audio": "481,491,490", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "157", + "magic_animation": "0", + "magic_level": "95", + "range_animation": "0", + "range_level": "95", + "safespot": null, + "slayer_exp": "34", + "strength_level": "95", + "weakness": "10" + }, + { + "id": "6049", + "name": "Wolf", + "examine": "A big coward. Thok mocks scaredy man.", + "aggressive": "true", + "attack_level": "75", + "combat_audio": "481,491,490", + "defence_animation": "0", + "defence_level": "75", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "75", + "range_level": "75", + "safespot": null, + "slayer_exp": "34", + "strength_level": "75", + "weakness": "10" + }, + { + "id": "6050", + "name": "Desert Wolf", + "examine": "A vicious desert wolf.", + "attack_level": "20", + "attack_speed": "5", + "death_animation": "6558", + "defence_animation": "6578", + "defence_level": "5", + "lifepoints": "55", + "magic_animation": "6579", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "safespot": null, + "strength_level": "20", + "weakness": "9" + }, + { + "id": "6051", + "name": "Desert Wolf", + "examine": "A vicious desert wolf.", + "attack_level": "20", + "attack_speed": "5", + "death_animation": "6558", + "defence_animation": "6578", + "defence_level": "5", + "lifepoints": "55", + "magic_animation": "6579", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "safespot": null, + "strength_level": "20" + }, + { + "id": "6052", + "name": "Ice wolf", + "examine": "Not man's best friend.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "6558", + "defence_animation": "6557", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "6559", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6053", + "name": "Ninja Impling", + "examine": "A very stealthy impling." + }, + { + "id": "6054", + "name": "Dragon impling", + "examine": "An impling who likes the word \"dragon\".", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6055", + "name": "Baby Impling Puro", + "examine": "A baby impling. Ahhh.", + "respawn_delay": "7" + }, + { + "id": "6056", + "name": "Young Impling Puro", + "examine": "A young impling. It's not fair!", + "respawn_delay": "7" + }, + { + "id": "6057", + "name": "Gourmet Impling Puro", + "examine": "An impling gourmet. Mmmm, tasty.", + "respawn_delay": "7" + }, + { + "id": "6058", + "name": "Earth Impling Puro", + "examine": "An earth impling. Rock on.", + "respawn_delay": "50" + }, + { + "id": "6059", + "name": "Essence Impling Puro", + "examine": "An impling who likes magic. Magic!", + "respawn_delay": "50" + }, + { + "id": "6060", + "name": "Eclectic Impling Puro", + "examine": "An impling with varied tastes.", + "respawn_delay": "7" + }, + { + "id": "6061", + "name": "Nature Impling Puro", + "examine": "A nature impling. Right on, maaan.", + "respawn_delay": "9999" + }, + { + "id": "6062", + "name": "Magpie Impling Puro", + "examine": "Ooh, shiny things!", + "respawn_delay": "9999" + }, + { + "id": "6063", + "name": "Ninja Impling Puro", + "examine": "A very stealthy impling.", + "respawn_delay": "9999" + }, + { + "id": "6064", + "name": "Dragon impling", + "examine": "An impling who likes the word \"dragon.\"", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6065", + "name": "Puro Spawn (Low)", + "respawn_delay": "1" + }, + { + "id": "6066", + "name": "Puro Spawn (Mid)", + "respawn_delay": "1" + }, + { + "id": "6067", + "name": "Puro Spawn (High)", + "respawn_delay": "1" + }, + { + "id": "6071", + "name": "Immenizz" + }, + { + "id": "6072", + "name": "Fairy Aeryka", + "examine": "She tends the wheat.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6073", + "name": "Wandering impling", + "examine": "He looks a little lost.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6074", + "name": "Imp defender", + "examine": "An angry little imp. Grrr.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6075", + "name": "Cyclops" + }, + { + "id": "6078", + "name": "Cyclops", + "examine": "A one-eyed man eater.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "35", + "lifepoints": "75", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "75", + "strength_level": "65", + "weakness": "8" + }, + { + "id": "6079", + "name": "Cyclops", + "examine": "A one-eyed woman eater.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "65", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "100", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "6080", + "name": "Cyclops", + "examine": "A one-eyed man eater.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "35", + "lifepoints": "75", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "75", + "strength_level": "65", + "weakness": "8" + }, + { + "id": "6081", + "name": "Cyclops", + "examine": "A one-eyed woman eater.", + "aggressive": "true", + "attack_level": "65", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "65", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "100", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "6082", + "name": "Captain Ned" + }, + { + "id": "6085", + "name": "Cabin boy Jenkins" + }, + { + "id": "6086", + "name": "Cabin boy Jenkins" + }, + { + "id": "6087", + "name": "Elvarg" + }, + { + "id": "6088", + "name": "Zombie rat", + "examine": "Overgrown undead vermin.", + "attack_level": "2", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2", + "weakness": "7" + }, + { + "id": "6089", + "name": "Zombie rat", + "examine": "Overgrown undead vermin.", + "attack_level": "2", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2", + "weakness": "7" + }, + { + "id": "6090", + "name": "Zombie rat", + "examine": "Overgrown undead vermin.", + "attack_level": "2", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "2", + "magic_animation": "0", + "melee_animation": "4933", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "2", + "weakness": "7" + }, + { + "id": "6091", + "name": "Skeleton", + "examine": "Ey.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "22", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6092", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "22", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6093", + "name": "Skeleton", + "examine": "Could do with gaining a few pounds.", + "aggressive": "true", + "attack_level": "9", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "9", + "lifepoints": "12", + "magic_animation": "0", + "melee_animation": "5487", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "9", + "weakness": "8" + }, + { + "id": "6094", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5542", + "defence_animation": "5541", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5540", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "6095", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "6096", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "6097", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "6098", + "name": "Ghost", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "436,439,438", + "death_animation": "5534", + "defence_animation": "5533", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5532", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "6099", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5571", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "6100", + "name": "Zombie", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "1", + "lifepoints": "30", + "melee_animation": "5571", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "6101", + "name": "Lesser demon", + "examine": "Lesser, but still pretty big.", + "aggressive": "true", + "attack_level": "68", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "combat_audio": "400,404,403", + "death_animation": "67", + "defence_animation": "65", + "defence_level": "71", + "lifepoints": "79", + "magic_animation": "4630", + "magic_level": "1", + "melee_animation": "4630", + "range_animation": "4630", + "range_level": "1", + "respawn_delay": "30", + "safespot": null, + "slayer_exp": "79", + "strength_level": "70", + "weakness": "4" + }, + { + "id": "6102", + "name": "Lost barbarian", + "examine": "His face is expressionless.", + "attack_level": "60", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "7" + }, + { + "id": "6103", + "name": "Skeleton hero", + "examine": "An opponent from the grave. He seems unimpressed by your bone rummaging.", + "aggressive": "true", + "attack_level": "53", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "53", + "lifepoints": "75", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "53", + "weakness": "8" + }, + { + "id": "6104", + "name": "Skeleton brute", + "examine": "An ex-barbarian, willing to make you ex too.", + "aggressive": "true", + "attack_level": "63", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "63", + "lifepoints": "90", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "63", + "weakness": "8" + }, + { + "id": "6105", + "name": "Skeleton warlord", + "examine": "He's heartless.", + "aggressive": "true", + "attack_level": "65", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "92", + "magic_animation": "0", + "melee_animation": "2067", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "8" + }, + { + "id": "6106", + "name": "Skeleton heavy", + "examine": "He's less heavy now.", + "aggressive": "true", + "attack_level": "64", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "64", + "lifepoints": "91", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "64", + "weakness": "8" + }, + { + "id": "6107", + "name": "Skeleton thug", + "examine": "Floats like an anvil, hits like a hammer.", + "aggressive": "true", + "attack_level": "61", + "combat_audio": "774,775,777", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "61", + "lifepoints": "87", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "61", + "weakness": "8" + }, + { + "id": "6108", + "name": "Entrana firebird", + "examine": "Probably not a chicken.", + "attack_level": "1", + "death_animation": "6812", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "0", + "melee_animation": "6811", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "1" + }, + { + "id": "6109", + "name": "Mounted terrorbird gnome", + "examine": "These gnomes know how to get around!", + "attack_level": "38", + "death_animation": "6791", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "6790", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "38", + "weakness": "8" + }, + { + "id": "6110", + "name": "Mounted terrorbird gnome", + "examine": "These gnomes know how to get around!", + "attack_level": "1", + "death_animation": "6791", + "defence_animation": "6792", + "defence_level": "1", + "lifepoints": "55", + "melee_animation": "6790", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6111", + "name": "Mounted terrorbird gnome", + "examine": "These gnomes know how to get around!", + "attack_level": "1", + "death_animation": "6791", + "defence_animation": "6792", + "defence_level": "1", + "lifepoints": "55", + "melee_animation": "6790", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6112", + "name": "Ducklings", + "examine": "Aww, cute.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "water_npc": "true" + }, + { + "id": "6113", + "name": "Duck", + "examine": "Quackers.", + "attack_level": "1", + "death_animation": "750", + "defence_animation": "3268", + "defence_level": "1", + "lifepoints": "3", + "melee_animation": "747", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6114", + "name": "Drake" + }, + { + "id": "6115", + "name": "Seagull", + "examine": "A messy bird.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "309,311,310", + "death_animation": "3468", + "defence_animation": "1014", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "3467", + "melee_animation": "3467", + "range_animation": "3467", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "6" + }, + { + "id": "6116", + "name": "Seagull", + "examine": "A messy bird.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "309,311,310", + "death_animation": "3468", + "defence_animation": "1014", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "3467", + "melee_animation": "3467", + "range_animation": "3467", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6117", + "name": "Mr. Mordaut", + "examine": "Do not upset this teacher. You have been warned!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6118", + "name": "Observatory assistant", + "examine": "He helps the professor.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6119", + "name": "Observatory professor", + "examine": "A man, learned in the ways of the stars." + }, + { + "id": "6122", + "name": "Sleeping guard", + "examine": "Sleeping like an ugly baby.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6123", + "name": "Naghead", + "examine": "An old goblin hag.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6124", + "name": "Wagchin", + "examine": "A young goblin 'beauty'.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6125", + "name": "Goblin", + "examine": "An ugly green creature.", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6126", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6127", + "name": "Greasycheeks", + "examine": "Big appetite for a small creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6128", + "name": "Smellytoes", + "examine": "Likes drink a little too much.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6129", + "name": "Creakyknees", + "examine": "Lean and green.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6130", + "name": "Clothears" + }, + { + "id": "6131", + "name": "Zombie", + "attack_level": "1", + "combat_audio": "931,923,922", + "defence_level": "1", + "lifepoints": "40", + "range_level": "1", + "safespot": null, + "slayer_exp": "30", + "strength_level": "1" + }, + { + "id": "6132", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6133", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6134", + "name": "Dunce", + "examine": "This imp is clearly the class clown.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6135", + "name": "Town crier", + "examine": "Get useful information from this guy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6136", + "name": "Town crier", + "examine": "Get useful information from this guy." + }, + { + "id": "6137", + "name": "Town crier", + "examine": "Get useful information from this guy." + }, + { + "id": "6138", + "name": "Town crier" + }, + { + "id": "6139", + "name": "Town crier" + }, + { + "id": "6140", + "name": "Squire (Intermediate)", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6141", + "name": "Squire (Veteran)", + "examine": "A squire of balance.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6142", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "50", + "lifepoints": "200", + "magic_level": "50", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6143", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "defence_level": "50", + "lifepoints": "200", + "magic_level": "25", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6144", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "50", + "lifepoints": "200", + "magic_level": "50", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6145", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "50", + "lifepoints": "200", + "magic_level": "50", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6146", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "200", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6147", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "200", + "magic_level": "15", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6148", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "200", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6149", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "200", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6150", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "150,150,150,75,75,0,0,0,0,0,0,0,0,0,0", + "defence_level": "70", + "lifepoints": "250", + "magic_level": "70", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6151", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "150,150,150,150,37,0,0,0,0,0,0,0,0,0,0", + "defence_level": "70", + "lifepoints": "250", + "magic_level": "40", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6152", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "150,150,75,150,75,0,0,0,0,0,0,0,0,0,0", + "defence_level": "70", + "lifepoints": "250", + "magic_level": "70", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6153", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "75,75,150,150,75,0,0,0,0,0,0,0,0,0,0", + "defence_level": "70", + "lifepoints": "250", + "magic_level": "70", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6154", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "250", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6155", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "250", + "magic_level": "15", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6156", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "250", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6157", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "250", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6158", + "name": "Sir Lucan" + }, + { + "id": "6159", + "name": "Workman", + "examine": "It is cold and solid. Thok will strap it to Marmaros's leg.", + "aggressive": "true", + "attack_level": "50", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "114", + "magic_animation": "0", + "magic_level": "50", + "range_animation": "0", + "range_level": "50", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6160", + "name": "Sir Lancelot" + }, + { + "id": "6161", + "name": "Sir Bedivere" + }, + { + "id": "6162", + "name": "Sir Tristram" + }, + { + "id": "6163", + "name": "Sir Pelleas" + }, + { + "id": "6164", + "name": "Sir Gawain" + }, + { + "id": "6165", + "name": "Sir Kay" + }, + { + "id": "6166", + "name": "Sir Pelleas" + }, + { + "id": "6167", + "name": "Sir Gawain" + }, + { + "id": "6168", + "name": "Sir Kay" + }, + { + "id": "6169", + "name": "Squire", + "examine": "Squire to the Knights of the Round Table.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6170", + "name": "Sir Lancelot", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "422", + "defence_level": "1", + "lifepoints": "118", + "melee_animation": "400", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6171", + "name": "Sir Kay" + }, + { + "id": "6172", + "name": "Sir Gawain" + }, + { + "id": "6173", + "name": "Sir Lucan" + }, + { + "id": "6174", + "name": "Bandit" + }, + { + "id": "6175", + "name": "Sir Tristram" + }, + { + "id": "6176", + "name": "Sir Pelleas" + }, + { + "id": "6177", + "name": "Sir Bedivere" + }, + { + "id": "6178", + "name": "Anna" + }, + { + "id": "6179", + "name": "David" + }, + { + "id": "6180", + "name": "Anna" + }, + { + "id": "6181", + "name": "Court judge" + }, + { + "id": "6182", + "name": "Jury" + }, + { + "id": "6183", + "name": "Guard", + "examine": "An officer of the law.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6184", + "name": "Guard", + "examine": "An officer of the law.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6185", + "name": "Prosecutor" + }, + { + "id": "6186", + "name": "Morgan Le Faye" + }, + { + "id": "6188", + "name": "Renegade knight", + "examine": "He isn't very friendly.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "8" + }, + { + "id": "6189", + "name": "Black Knight", + "examine": "A dark-hearted knight.", + "aggressive": "true", + "attack_level": "25", + "attack_speed": "5", + "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", + "combat_audio": "2503,15,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "25", + "weakness": "8" + }, + { + "id": "6190", + "name": "Guard", + "examine": "Primping with combs and hair clips.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6191", + "name": "Sinclair" + }, + { + "id": "6198", + "name": "Sinclair", + "examine": "The name isn't just for show.", + "aggressive": "true", + "attack_level": "55", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "85", + "magic_animation": "0", + "magic_level": "55", + "range_animation": "0", + "range_level": "55", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6199", + "name": "Banker" + }, + { + "id": "6200", + "name": "Banker", + "examine": "He can look after my money.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6201", + "name": "Knight", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6202", + "name": "K'ril Tsutsaroth" + }, + { + "id": "6203", + "name": "K'ril Tsutsaroth", + "examine": "A servant of the god Zamorak. ", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "340", + "attack_speed": "6", + "bonuses": "160,160,160,0,0,80,80,80,130,80,0,31,0,0,0", + "clue_level": "2", + "death_animation": "6946", + "defence_animation": "6944", + "defence_level": "270", + "lifepoints": "255", + "magic_animation": "6945", + "magic_level": "200", + "melee_animation": "6945", + "poison_amount": "", + "poison_immune": "true", + "poisonous": "", + "range_animation": "6945", + "range_level": "1", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "350", + "strength_level": "300", + "weakness": "9" + }, + { + "id": "6204", + "name": "Tstanon Karlak", + "examine": "Destroyer of 1000 planes!", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "124", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,-5,0,0,14,0,0,0", + "death_animation": "6946", + "defence_animation": "6944", + "defence_level": "125", + "lifepoints": "142", + "magic_animation": "6945", + "magic_level": "50", + "melee_animation": "6945", + "range_animation": "6945", + "range_level": "50", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "142", + "strength_level": "118", + "weakness": "9" + }, + { + "id": "6205", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6206", + "name": "Zakl'n Gritch", + "examine": "Scourge of light.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "83", + "attack_speed": "5", + "bonuses": "0,0,0,0,20,0,0,0,-5,0,0,0,0,0,20", + "combat_style": "1", + "death_animation": "6946", + "defence_animation": "6945", + "defence_level": "127", + "lifepoints": "150", + "magic_animation": "7033", + "magic_level": "50", + "melee_animation": "7033", + "projectile": "1209", + "range_animation": "7033", + "range_level": "150", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "150", + "start_gfx": "1208", + "strength_level": "76", + "weakness": "0" + }, + { + "id": "6207", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6208", + "name": "Balfrug Kreeyath", + "examine": "Despoiler of Ullek.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "115", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,10,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "6946", + "defence_animation": "6944", + "defence_level": "153", + "lifepoints": "161", + "magic_animation": "7033", + "magic_level": "150", + "melee_animation": "7033", + "projectile": "1213", + "range_animation": "7033", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "161", + "start_gfx": "1212", + "strength_level": "60" + }, + { + "id": "6209", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6210", + "name": "Hellhound", + "examine": "From the maws of hell.", + "aggressive": "true", + "attack_level": "105", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "3717,3719,3718", + "death_animation": "6576", + "defence_animation": "6578", + "defence_level": "102", + "lifepoints": "116", + "magic_animation": "6579", + "melee_animation": "6579", + "range_animation": "6579", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "116", + "strength_level": "104", + "weakness": "7" + }, + { + "id": "6211", + "name": "Imp", + "examine": "Have you checked your pockets lately?", + "aggressive": "true", + "attack_level": "4", + "bonuses": "10,5,5,10,10,10,10,10,10,0,0,0,0,0,0", + "combat_audio": "534,536,535", + "death_animation": "172", + "defence_animation": "170", + "defence_level": "4", + "lifepoints": "10", + "magic_animation": "169", + "melee_animation": "169", + "movement_radius": "25", + "range_animation": "169", + "range_level": "1", + "safespot": null, + "strength_level": "4", + "weakness": "7" + }, + { + "id": "6212", + "name": "Werewolf", + "examine": "He doesn't look pleased to see me.", + "aggressive": "true", + "attack_level": "64", + "bonuses": "50,40,45,60,70,70,70,40,40,50,0,0,0,0,0", + "clue_level": "1", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "64", + "lifepoints": "100", + "magic_animation": "6536", + "melee_animation": "6536", + "range_animation": "6536", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "64", + "weakness": "7" + }, + { + "id": "6213", + "name": "Werewolf", + "examine": "He doesn't look pleased to see me.", + "aggressive": "true", + "attack_level": "64", + "bonuses": "50,40,45,60,70,70,70,40,40,50,0,0,0,0,0", + "clue_level": "1", + "death_animation": "6537", + "defence_animation": "6538", + "defence_level": "64", + "lifepoints": "100", + "magic_animation": "6536", + "melee_animation": "6536", + "range_animation": "6536", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "64", + "weakness": "7" + }, + { + "id": "6214", + "name": "Vampire", + "examine": "It looks really hungry!", + "aggressive": "true", + "attack_level": "44", + "bonuses": "30,35,30,40,50,50,50,25,30,30,0,0,0,0,0", + "clue_level": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "44", + "lifepoints": "60", + "magic_animation": "810", + "melee_animation": "810", + "range_animation": "810", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "44" + }, + { + "id": "6215", + "name": "Bloodveld", + "examine": "The tongue of evil.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "4", + "clue_level": "2", + "combat_audio": "312,314,313", + "death_animation": "9131", + "defence_animation": "9132", + "defence_level": "30", + "lifepoints": "120", + "magic_animation": "1552", + "melee_animation": "9130", + "range_animation": "1552", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "120", + "strength_level": "45" + }, + { + "id": "6216", + "name": "Pyrefiend", + "examine": "A small fire demon.", + "aggressive": "true", + "attack_level": "25", + "bonuses": "25,25,20,40,40,40,15,30,20,60,20,0,0,0,0", + "clue_level": "1", + "combat_audio": "696,698,697", + "death_animation": "1580", + "defence_animation": "1581", + "defence_level": "25", + "lifepoints": "48", + "magic_animation": "1582", + "melee_animation": "1582", + "range_animation": "1582", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "25", + "weakness": "7" + }, + { + "id": "6217", + "name": "Icefiend", + "examine": "A small ice demon.", + "attack_level": "5", + "bonuses": "5,5,5,5,10,10,10,10,10,10,5,0,0,0,0", + "clue_level": "0", + "combat_audio": "531,533,532", + "death_animation": "8078", + "defence_animation": "8079", + "defence_level": "5", + "lifepoints": "15", + "magic_animation": "8080", + "melee_animation": "8080", + "range_animation": "8080", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "5" + }, + { + "id": "6218", + "name": "Gorak", + "examine": "Those horns look pretty sharp...", + "aggressive": "true", + "attack_level": "70", + "bonuses": "30,30,50,70,40,70,70,50,60,55,0,0,0,0,0", + "death_animation": "4302", + "defence_animation": "4301", + "defence_level": "70", + "lifepoints": "112", + "magic_animation": "4300", + "melee_animation": "4300", + "range_animation": "4300", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "112", + "strength_level": "70", + "weakness": "9" + }, + { + "id": "6219", + "name": "Spiritual warrior", + "examine": "Warrior of Zamorak.", + "aggressive": "true", + "attack_level": "66", + "attack_speed": "5", + "bonuses": "40,60,60,60,60,20,50,55,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "9055", + "defence_animation": "1156", + "defence_level": "66", + "lifepoints": "102", + "magic_animation": "390", + "melee_animation": "390", + "range_animation": "390", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "66", + "weakness": "6" + }, + { + "id": "6220", + "name": "Spiritual ranger", + "examine": "A ranger spirit dedicated to Zamorak.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "50,70,50,50,50,70,50,85,85,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "70", + "lifepoints": "120", + "magic_animation": "426", + "melee_animation": "426", + "projectile": "9", + "range_animation": "426", + "range_level": "70", + "respawn_delay": "25", + "safespot": null, + "start_gfx": "18", + "start_height": "96", + "strength_level": "1", + "weakness": "1" + }, + { + "id": "6221", + "name": "Spiritual mage", + "examine": "A deadly servant of Zamorak.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "2", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "61", + "end_gfx": "78", + "end_height": "0", + "lifepoints": "75", + "magic_animation": "811", + "magic_level": "180", + "melee_animation": "811", + "projectile": "78", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "3" + }, + { + "id": "6222", + "name": "Kree'arra", + "examine": "Graceful avatar of Armadyl.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "300", + "attack_speed": "3", + "bonuses": "136,136,136,0,120,180,180,180,200,200,0,12,0,0,0", + "clue_level": "2", + "death_animation": "6975", + "defence_animation": "6974", + "defence_level": "260", + "lifepoints": "255", + "magic_animation": "6977", + "magic_level": "200", + "melee_animation": "6977", + "poison_immune": "true", + "range_animation": "6977", + "range_level": "380", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "357", + "strength_level": "200", + "weakness": "10" + }, + { + "id": "6223", + "name": "Wingman Skree", + "examine": "Graceful, bird-like creature.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "45,45,45,0,0,0,0,0,0,0,0,25,0,0,0", + "combat_style": "2", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "160", + "lifepoints": "121", + "magic_animation": "6952", + "magic_level": "150", + "melee_animation": "6952", + "poison_immune": "false", + "prj_height": "92", + "projectile": "1199", + "range_animation": "6952", + "range_level": "100", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "124", + "strength_level": "50", + "weakness": "3" + }, + { + "id": "6224", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6225", + "name": "Flockleader Geerin", + "examine": "Graceful, bird-like creature.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "0,0,0,0,60,0,0,0,0,0,0,0,0,0,0", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "175", + "lifepoints": "132", + "magic_animation": "6953", + "magic_level": "50", + "melee_animation": "6953", + "poison_immune": "false", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "150", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "133", + "strength_level": "80", + "weakness": "4" + }, + { + "id": "6226", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6227", + "name": "Flight Kilisa", + "examine": "Graceful, bird-like creature.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "124", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,14,0,0,0", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "175", + "lifepoints": "133", + "magic_animation": "6954", + "magic_level": "50", + "melee_animation": "6954", + "range_animation": "6954", + "range_level": "169", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "133", + "strength_level": "118", + "weakness": "6" + }, + { + "id": "6228", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6229", + "name": "Spiritual warrior", + "examine": "A servant of Armadyl.", + "aggressive": "true", + "attack_level": "70", + "bonuses": "40,40,50,50,20,50,50,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "70", + "lifepoints": "98", + "magic_animation": "6954", + "melee_animation": "6954", + "range_animation": "6954", + "range_level": "68", + "respawn_delay": "25", + "safespot": null, + "strength_level": "70", + "weakness": "6" + }, + { + "id": "6230", + "name": "Spiritual ranger", + "examine": "Armadyl's favourite servant.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "70", + "lifepoints": "89", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "70", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "6231", + "name": "Spiritual mage", + "examine": "A mage who serves Armadyl above all else - even death.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,9,12,5,45,28,0,0,0,0,0", + "clue_level": "2", + "combat_style": "2", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "111", + "lifepoints": "75", + "magic_animation": "6952", + "magic_level": "150", + "melee_animation": "6952", + "prj_height": "92", + "projectile": "1199", + "range_animation": "6952", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "6232", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "40", + "lifepoints": "70", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1191", + "range_animation": "6953", + "range_level": "40", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6233", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "45", + "lifepoints": "83", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "45", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6234", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "50", + "lifepoints": "86", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "50", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6235", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "50", + "lifepoints": "86", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "50", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6236", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "55", + "lifepoints": "95", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "55", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6237", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "55", + "lifepoints": "98", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1191", + "range_animation": "6953", + "range_level": "55", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6238", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "65", + "lifepoints": "124", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "65", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6239", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "65", + "lifepoints": "139", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1191", + "range_animation": "6953", + "range_level": "65", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6240", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "40", + "lifepoints": "63", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1191", + "range_animation": "6953", + "range_level": "40", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6241", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "40", + "lifepoints": "65", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "40", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6242", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "40", + "lifepoints": "83", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "40", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6243", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "50", + "lifepoints": "69", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "50", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6244", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "55", + "lifepoints": "75", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "55", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6245", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "55", + "lifepoints": "98", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1190", + "range_animation": "6953", + "range_level": "55", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6246", + "name": "Aviansie", + "examine": "Graceful, bird-like creature.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "6956", + "defence_animation": "6955", + "defence_level": "65", + "lifepoints": "73", + "magic_animation": "6953", + "melee_animation": "6953", + "prj_height": "92", + "projectile": "1191", + "range_animation": "6953", + "range_level": "65", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6247", + "name": "Commander Zilyana", + "examine": "Commander of Saradomin's forces. ", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "280", + "attack_speed": "2", + "bonuses": "195,195,195,200,0,100,100,100,100,100,0,20,0,0,0", + "clue_level": "2", + "death_animation": "6965", + "defence_animation": "6966", + "defence_level": "300", + "lifepoints": "255", + "magic_animation": "6964", + "magic_level": "300", + "melee_animation": "6964", + "poison_immune": "true", + "range_animation": "6964", + "range_level": "250", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "360", + "strength_level": "196", + "weakness": "7" + }, + { + "id": "6248", + "name": "Starlight", + "examine": "The bane of darkness.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "120", + "attack_speed": "5", + "bonuses": "60,60,60,0,0,12,14,13,5,13,0,10,0,0,0", + "combat_audio": "3829,3866,3849", + "death_animation": "6377", + "defence_animation": "6375", + "defence_level": "120", + "lifepoints": "160", + "magic_animation": "6376", + "magic_level": "125", + "melee_animation": "6376", + "poison_immune": "false", + "range_animation": "6376", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "125", + "weakness": "7" + }, + { + "id": "6249", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6250", + "name": "Growler", + "examine": "Defender of the faithful.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "100", + "attack_speed": "5", + "bonuses": "10,10,10,0,0,12,14,14,18,5,0,7,0,0,0", + "combat_audio": "3830,3869,3867", + "combat_style": "2", + "death_animation": "7016", + "defence_animation": "7017", + "defence_level": "120", + "end_gfx": "1186", + "lifepoints": "146", + "magic_animation": "7019", + "magic_level": "150", + "melee_animation": "7019", + "prj_height": "0", + "projectile": "1185", + "range_animation": "7019", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "start_gfx": "1184", + "strength_level": "101" + }, + { + "id": "6251", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6252", + "name": "Bree", + "examine": "Champion of Truth.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "110", + "attack_speed": "5", + "bonuses": "10,10,10,0,0,12,14,14,18,5,0,7,0,0,0", + "combat_style": "1", + "death_animation": "7011", + "defence_animation": "7010", + "defence_level": "130", + "end_gfx": "24", + "lifepoints": "162", + "magic_animation": "7009", + "magic_level": "80", + "melee_animation": "7009", + "prj_height": "50", + "projectile": "1188", + "range_animation": "7009", + "range_level": "150", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "80", + "weakness": "0" + }, + { + "id": "6253", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6254", + "name": "Saradomin priest", + "examine": "A holy man wearing ancient clothing.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "40,40,40,40,20,50,40,55,0,0,0,0,0,0,0", + "combat_style": "2", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "60", + "end_gfx": "76", + "lifepoints": "89", + "magic_animation": "811", + "magic_level": "60", + "melee_animation": "811", + "poisonous": "", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "3" + }, + { + "id": "6255", + "name": "Spiritual warrior", + "examine": "Warrior of Saradomin.", + "aggressive": "true", + "attack_level": "66", + "attack_speed": "5", + "bonuses": "40,60,60,60,60,20,50,45,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "9055", + "defence_animation": "1156", + "defence_level": "66", + "lifepoints": "100", + "magic_animation": "390", + "melee_animation": "390", + "range_animation": "390", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "66", + "weakness": "8" + }, + { + "id": "6256", + "name": "Spiritual ranger", + "examine": "A ranger spirit dedicated to Saradomin.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "50,70,50,50,50,70,50,65,65,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "70", + "lifepoints": "106", + "magic_animation": "426", + "melee_animation": "426", + "projectile": "9", + "range_animation": "426", + "range_level": "70", + "respawn_delay": "25", + "safespot": null, + "start_gfx": "18", + "start_height": "96", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "6257", + "name": "Spiritual mage", + "examine": "Saradomin's holy mage.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,8,7,3,16,2,0,0,0,0,0", + "clue_level": "2", + "combat_style": "2", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "86", + "end_gfx": "76", + "end_height": "0", + "lifepoints": "85", + "magic_animation": "811", + "magic_level": "160", + "melee_animation": "811", + "projectile": "76", + "range_animation": "811", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "6258", + "name": "Knight of Saradomin", + "examine": "A valiant knight.", + "aggressive": "true", + "attack_level": "50", + "bonuses": "40,40,40,40,50,20,40,50,0,0,0,0,0,0,0", + "death_animation": "9055", + "defence_animation": "410", + "defence_level": "50", + "lifepoints": "135", + "magic_animation": "407", + "melee_animation": "407", + "range_animation": "407", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "50", + "weakness": "7" + }, + { + "id": "6259", + "name": "Knight of Saradomin", + "examine": "A valiant knight.", + "aggressive": "true", + "attack_level": "50", + "bonuses": "40,40,40,40,50,20,40,65,0,0,0,0,0,0,0", + "death_animation": "9055", + "defence_animation": "424", + "defence_level": "50", + "lifepoints": "108", + "magic_animation": "401", + "melee_animation": "401", + "range_animation": "401", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "50", + "weakness": "7" + }, + { + "id": "6260", + "name": "General Graardor", + "examine": "A huge war chief.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "280", + "attack_speed": "6", + "bonuses": "120,120,120,0,100,90,90,90,65,90,0,43,0,0,0", + "clue_level": "2", + "death_animation": "7062", + "defence_animation": "7061", + "defence_level": "250", + "lifepoints": "255", + "magic_animation": "7060", + "magic_level": "280", + "melee_animation": "7060", + "poison_immune": "true", + "range_animation": "7060", + "range_level": "350", + "respawn_delay": "150", + "safespot": null, + "slayer_exp": "0", + "strength_level": "350", + "weakness": "10" + }, + { + "id": "6261", + "name": "Sergeant Strongstack", + "examine": "A battle-honed goblin. ", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "124", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,14,0,0,0", + "death_animation": "6156", + "defence_animation": "6155", + "defence_level": "126", + "lifepoints": "128", + "magic_animation": "6154", + "magic_level": "50", + "melee_animation": "6154", + "range_animation": "6154", + "range_level": "50", + "respawn_delay": "50", + "safespot": null, + "strength_level": "118", + "weakness": "8" + }, + { + "id": "6262", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6263", + "name": "Sergeant Steelwill", + "examine": "A battle-honed goblin. ", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,6,0,0,0", + "combat_style": "2", + "death_animation": "6156", + "defence_animation": "6155", + "defence_level": "150", + "lifepoints": "127", + "magic_animation": "6154", + "magic_level": "150", + "melee_animation": "6154", + "projectile": "1203", + "range_animation": "6154", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "start_gfx": "1202", + "strength_level": "50", + "weakness": "3" + }, + { + "id": "6264", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6265", + "name": "Sergeant Grimspike", + "examine": "A battle-honed goblin. ", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "80", + "attack_speed": "5", + "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,20", + "combat_style": "1", + "death_animation": "6156", + "defence_animation": "6155", + "defence_level": "132", + "lifepoints": "146", + "magic_animation": "6154", + "magic_level": "50", + "melee_animation": "6154", + "projectile": "1206", + "range_animation": "6154", + "range_level": "150", + "respawn_delay": "50", + "safespot": null, + "strength_level": "80", + "weakness": "2" + }, + { + "id": "6266", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6267", + "name": "Fishing spot", + "examine": "Big, ugly, and smelly.", + "aggressive": "true", + "attack_level": "27", + "attack_speed": "6", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "death_animation": "361", + "defence_animation": "360", + "defence_level": "27", + "lifepoints": "60", + "magic_animation": "359", + "magic_level": "27", + "melee_animation": "359", + "range_animation": "359", + "range_level": "27", + "respawn_delay": "25", + "safespot": null, + "strength_level": "27" + }, + { + "id": "6268", + "name": "Jogre", + "examine": "Green and aggressive.", + "aggressive": "true", + "attack_level": "62", + "attack_speed": "6", + "bonuses": "10,20,20,20,20,20,10,20,0,0,0,0,0,0,0", + "clue_level": "1", + "death_animation": "2938", + "defence_animation": "2937", + "defence_level": "62", + "lifepoints": "70", + "magic_animation": "2936", + "melee_animation": "2936", + "range_animation": "2936", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "62", + "weakness": "8" + }, + { + "id": "6269", + "name": "Cyclops", + "examine": "A one-eyed man-eater.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "48", + "lifepoints": "110", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "110", + "strength_level": "70", + "weakness": "8" + }, + { + "id": "6270", + "name": "Cyclops", + "examine": "A one-eyed man-eater.", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "4", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4653", + "defence_animation": "4651", + "defence_level": "48", + "lifepoints": "110", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "4652", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "110", + "strength_level": "70", + "weakness": "8" + }, + { + "id": "6271", + "name": "Ork", + "examine": "Ugly, fierce and with a bad attitude.", + "aggressive": "true", + "attack_level": "68", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "68", + "lifepoints": "110", + "magic_animation": "4320", + "melee_animation": "4320", + "range_animation": "4320", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "68", + "weakness": "8" + }, + { + "id": "6272", + "name": "Ork", + "examine": "Ugly, fierce and with a bad attitude.", + "aggressive": "true", + "attack_level": "68", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "68", + "lifepoints": "110", + "magic_animation": "4320", + "melee_animation": "4320", + "range_animation": "4320", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "68" + }, + { + "id": "6273", + "name": "Ork", + "examine": "Ugly, fierce and with a bad attitude.", + "aggressive": "true", + "attack_level": "68", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "68", + "lifepoints": "110", + "magic_animation": "4320", + "melee_animation": "4320", + "range_animation": "4320", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "68" + }, + { + "id": "6274", + "name": "Ork", + "examine": "Ugly, fierce and with a bad attitude.", + "aggressive": "true", + "attack_level": "68", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "68", + "lifepoints": "110", + "magic_animation": "4320", + "melee_animation": "4320", + "range_animation": "4320", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "68" + }, + { + "id": "6275", + "name": "Hobgoblin", + "examine": "An ugly, smelly creature.", + "aggressive": "true", + "attack_level": "40", + "bonuses": "20,30,30,30,30,30,10,30,0,0,0,0,0,0,0", + "combat_audio": "469,472,471", + "death_animation": "167", + "defence_animation": "165", + "defence_level": "40", + "lifepoints": "52", + "magic_animation": "164", + "melee_animation": "164", + "range_animation": "164", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "40", + "weakness": "8" + }, + { + "id": "6276", + "name": "Spiritual ranger", + "examine": "The spirit of a ranger, serving bandos beyond death.", + "aggressive": "true", + "attack_level": "1", + "bonuses": "30,50,30,30,50,60,50,40,40,0,0,0,0,0,0", + "clue_level": "2", + "combat_style": "1", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "70", + "lifepoints": "130", + "magic_animation": "4320", + "melee_animation": "4320", + "projectile": "1195", + "range_animation": "4320", + "range_level": "70", + "respawn_delay": "25", + "safespot": null, + "start_gfx": "95", + "strength_level": "1", + "weakness": "0" + }, + { + "id": "6277", + "name": "Spiritual warrior", + "examine": "A true servant of Bandos.", + "aggressive": "true", + "attack_level": "70", + "bonuses": "50,40,45,60,60,60,60,20,50,60,0,0,0,0,0", + "clue_level": "2", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "70", + "lifepoints": "131", + "magic_animation": "4320", + "melee_animation": "4320", + "range_animation": "4320", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "70", + "weakness": "8" + }, + { + "id": "6278", + "name": "Spiritual mage", + "examine": "One of Bandos' chosen.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "0,0,0,0,0,12,14,13,35,13,0,0,0,0,0", + "clue_level": "2", + "combat_style": "2", + "death_animation": "4321", + "defence_animation": "4322", + "defence_level": "103", + "lifepoints": "106", + "magic_animation": "4320", + "magic_level": "142", + "melee_animation": "4320", + "range_animation": "4320", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "1", + "weakness": "4" + }, + { + "id": "6279", + "name": "Goblin", + "examine": "An ancient goblin.", + "aggressive": "true", + "attack_level": "5", + "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "5", + "lifepoints": "20", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "5" + }, + { + "id": "6280", + "name": "Goblin", + "examine": "A warrior for Bandos.", + "aggressive": "true", + "attack_level": "5", + "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "5", + "lifepoints": "15", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "5" + }, + { + "id": "6281", + "name": "Goblin", + "examine": "A soldier to the death.", + "aggressive": "true", + "attack_level": "5", + "bonuses": "5,10,10,10,10,10,5,10,5,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6190", + "defence_animation": "6189", + "defence_level": "5", + "lifepoints": "15", + "magic_animation": "6188", + "melee_animation": "6188", + "range_animation": "6188", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "5" + }, + { + "id": "6282", + "name": "Goblin", + "examine": "A soldier to the death.", + "aggressive": "true", + "attack_level": "5", + "bonuses": "5,10,10,10,10,10,5,10,5,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6190", + "defence_animation": "6189", + "defence_level": "5", + "lifepoints": "18", + "magic_animation": "6188", + "melee_animation": "6188", + "range_animation": "6188", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "5" + }, + { + "id": "6283", + "name": "Goblin", + "examine": "A warrior for Bandos.", + "aggressive": "true", + "attack_level": "5", + "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", + "clue_level": "0", + "combat_audio": "469,472,471", + "death_animation": "6182", + "defence_animation": "6183", + "defence_level": "5", + "lifepoints": "16", + "magic_animation": "6185", + "melee_animation": "6185", + "range_animation": "6185", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "slayer_exp": "16", + "strength_level": "5" + }, + { + "id": "6284", + "name": "Warped terrorbird" + }, + { + "id": "6285", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6286", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6287", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6288", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6289", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6290", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6291", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6292", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "168", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6293", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6294", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "308", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6295", + "name": "Warped terrorbird", + "examine": "You don't think you can harm this terrorbird.", + "aggressive": "true", + "attack_level": "59", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "0", + "defence_level": "59", + "lifepoints": "308", + "magic_animation": "0", + "magic_level": "59", + "melee_animation": "7108", + "projectile": "1468", + "range_animation": "0", + "range_level": "59", + "respawn_delay": "60", + "safespot": null, + "strength_level": "59", + "weakness": "1" + }, + { + "id": "6296", + "name": "Warped tortoise", + "examine": "You don't think you can harm this creature.", + "attack_level": "39", + "attack_speed": "5", + "death_animation": "7091", + "defence_animation": "0", + "defence_level": "52", + "lifepoints": "148", + "magic_animation": "0", + "magic_level": "52", + "melee_animation": "7093", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "39", + "weakness": "4" + }, + { + "id": "6297", + "name": "Warped tortoise", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7091", + "defence_animation": "7092", + "defence_level": "1", + "lifepoints": "87", + "melee_animation": "7093", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6298", + "name": "Jeffery" + }, + { + "id": "6299", + "name": "Big monolith" + }, + { + "id": "6300", + "name": "Small monolith" + }, + { + "id": "6301", + "name": "Cute creature" + }, + { + "id": "6302", + "name": "Evil creature" + }, + { + "id": "6303", + "name": "Yewnock the engineer" + }, + { + "id": "6304", + "name": "Bolrie" + }, + { + "id": "6305", + "name": "Hazelmere" + }, + { + "id": "6306", + "name": "Bolrie", + "examine": "Annoyingly easy to squish.", + "aggressive": "true", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "2", + "lifepoints": "0", + "magic_animation": "0", + "magic_level": "2", + "melee_animation": "0", + "range_animation": "0", + "range_level": "2", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6307", + "name": "Advisor" + }, + { + "id": "6308", + "name": "King Argenthorg" + }, + { + "id": "6309", + "name": "Prince Argenthorg" + }, + { + "id": "6310", + "name": "Cute creature" + }, + { + "id": "6312", + "name": "Evil creature" + }, + { + "id": "6313", + "name": "Terrorbird servant" + }, + { + "id": "6314", + "name": "Guard no. 21", + "examine": "She looks bored.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6315", + "name": "Guard no. 72", + "examine": "He looks even more bored.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6316", + "name": "Guard no. 21" + }, + { + "id": "6317", + "name": "Guard no. 72" + }, + { + "id": "6318", + "name": "Longramble" + }, + { + "id": "6319", + "name": "Spirit tree" + }, + { + "id": "6321", + "name": "Spirit tree" + }, + { + "id": "6322", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6323", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6324", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6325", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6326", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6327", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6328", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6329", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6330", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6331", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6332", + "name": "Warped terrorbird", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7109", + "defence_animation": "7110", + "defence_level": "1", + "lifepoints": "154", + "melee_animation": "7108", + "projectile": "1468", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6333", + "name": "Child" + }, + { + "id": "6334", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6335", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6336", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6337", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6338", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6339", + "name": "Child", + "examine": "A child of West Ardougne.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6340", + "name": "Child" + }, + { + "id": "6341", + "name": "Child" + }, + { + "id": "6342", + "name": "Child" + }, + { + "id": "6343", + "name": "Child" + }, + { + "id": "6344", + "name": "Child", + "examine": "Duck!", + "aggressive": "true", + "attack_level": "48", + "attack_speed": "5", + "combat_style": "1", + "death_animation": "3922", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "92", + "magic_animation": "0", + "melee_animation": "3920", + "range_animation": "3920", + "range_level": "65", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "1" + }, + { + "id": "6345", + "name": "Child" + }, + { + "id": "6346", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6347", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6348", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6349", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6350", + "name": "Pirate", + "examine": "This one's had too much to drink!", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6351", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6352", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6353", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6354", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6355", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6356", + "name": "Pirate", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "23", + "melee_animation": "390", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6357", + "name": "Street urchin" + }, + { + "id": "6358", + "name": "Street urchin", + "examine": "The mother of all pests!", + "aggressive": "true", + "attack_level": "70", + "attack_speed": "6", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "1428", + "magic_animation": "0", + "magic_level": "70", + "range_level": "70", + "respawn_delay": "60", + "safespot": null, + "strength_level": "70", + "weakness": "10" + }, + { + "id": "6359", + "name": "Street urchin" + }, + { + "id": "6360", + "name": "Street urchin" + }, + { + "id": "6361", + "name": "Street urchin" + }, + { + "id": "6362", + "name": "Eniola" + }, + { + "id": "6363", + "name": "Zamorak warrior", + "examine": "A warrior of Zamorak.", + "aggressive": "true", + "attack_level": "44", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "44", + "lifepoints": "62", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "44", + "weakness": "7" + }, + { + "id": "6364", + "name": "Zamorak warrior", + "examine": "A warrior of Zamorak.", + "aggressive": "true", + "attack_level": "47", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "390", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "47", + "weakness": "7" + }, + { + "id": "6365", + "name": "Zamorak ranger", + "examine": "A ranger of Zamorak.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "46", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "1" + }, + { + "id": "6366", + "name": "Zamorak ranger", + "examine": "A ranger of Zamorak.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "melee_animation": "426", + "range_animation": "426", + "range_level": "46", + "safespot": null, + "strength_level": "1", + "weakness": "1" + }, + { + "id": "6367", + "name": "Zamorak mage", + "examine": "A mage of Zamorak.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "49", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "6368", + "name": "Zamorak mage", + "examine": "A mage of Zamorak.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "49", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "6369", + "name": "Cave lizard", + "examine": "A cave dweller.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7205", + "defence_animation": "0", + "defence_level": "47", + "lifepoints": "67", + "magic_animation": "0", + "melee_animation": "7207", + "range_animation": "0", + "range_level": "47", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "0" + }, + { + "id": "6370", + "name": "Mage of Zamorak", + "examine": "A representative of the Z.M.I.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6371", + "name": "Zamorak crafter", + "examine": "A Z.M.I. runecrafter.", + "attack_level": "19", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "19", + "lifepoints": "27", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "19", + "weakness": "7" + }, + { + "id": "6372", + "name": "Zamorak crafter", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6373", + "name": "Kennith" + }, + { + "id": "6374", + "name": "Guard dog", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "49", + "strength_level": "1" + }, + { + "id": "6375", + "name": "Wizard Cromperty" + }, + { + "id": "6376", + "name": "Jungle spider", + "examine": "A barely visible deadly spider.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5327", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6377", + "name": "Jungle spider", + "examine": "A barely visible deadly spider.", + "aggressive": "true", + "attack_level": "1", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "1", + "lifepoints": "25", + "melee_animation": "5327", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6378", + "name": "Tenacious toucan", + "examine": "I wouldn't want to be footing that bill.", + "attack_level": "60", + "attack_speed": "5", + "death_animation": "6779", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "6775", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "6379", + "name": "Giant ant worker", + "examine": "I wonder how much he can lift.", + "attack_level": "35", + "death_animation": "7238", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "50", + "magic_animation": "0", + "melee_animation": "7237", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "35", + "weakness": "9" + }, + { + "id": "6380", + "name": "Giant ant soldier", + "examine": "Gi-ant-ant-ant-ant...", + "aggressive": "true", + "attack_level": "50", + "death_animation": "7238", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "71", + "magic_animation": "0", + "melee_animation": "7237", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "50", + "weakness": "9" + }, + { + "id": "6381", + "name": "Giant wasp", + "examine": "That stinger has to hurt...", + "aggressive": "true", + "attack_level": "60", + "attack_speed": "5", + "death_animation": "7244", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "85", + "magic_animation": "0", + "melee_animation": "7242", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "60", + "weakness": "9" + }, + { + "id": "6382", + "name": "Pernicious parrot", + "examine": "Polynomial - a parrot that goes without breakfast", + "attack_level": "45", + "attack_speed": "5", + "death_animation": "6777", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "6775", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "45", + "weakness": "9" + }, + { + "id": "6383", + "name": "Giant wasp", + "examine": "That stinger has to hurt...", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "7244", + "defence_animation": "7243", + "defence_level": "1", + "lifepoints": "37", + "melee_animation": "7242", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6384", + "name": "Karamjan Jungle Eagle" + }, + { + "id": "6385", + "name": "Karamjan Jungle eagle", + "examine": "A very large", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6386", + "name": "Bandit" + }, + { + "id": "6389", + "name": "Gargoyle", + "examine": "Flies like a rock.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", + "clue_level": "2", + "combat_audio": "428,430,429", + "death_animation": "1518", + "defence_animation": "9455", + "defence_level": "107", + "lifepoints": "105", + "magic_animation": "1516", + "magic_level": "1", + "melee_animation": "9454", + "range_animation": "1516", + "range_level": "1", + "safespot": null, + "slayer_exp": "105", + "strength_level": "95" + }, + { + "id": "6390", + "name": "Grim Reaper", + "examine": "I wish I could tell where he was looking. What could be beneath that hood?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6391", + "name": "Glough" + }, + { + "id": "6392", + "name": "Oldak" + }, + { + "id": "6393", + "name": "Zanik" + }, + { + "id": "6394", + "name": "Zanik" + }, + { + "id": "6396", + "name": "Zanik" + }, + { + "id": "6398", + "name": "Zanik" + }, + { + "id": "6400", + "name": "Oldak" + }, + { + "id": "6402", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6403", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6404", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6405", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6406", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6407", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6408", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6409", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6410", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6411", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6412", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6413", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6414", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6415", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6416", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6417", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6418", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6419", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6420", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6421", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6422", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6423", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6424", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6425", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6426", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6427", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6428", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6429", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6430", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6431", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6432", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6433", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6434", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6435", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6436", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6437", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6438", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6439", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6440", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6441", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6442", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6443", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6444", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6445", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6446", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6447", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6448", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6449", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6450", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6451", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6452", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6453", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6454", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6455", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6456", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6457", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6458", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6459", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6460", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6461", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6462", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6463", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6464", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6465", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6466", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6467", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6468", + "name": "Skoblin" + }, + { + "id": "6469", + "name": "Snothead", + "examine": "A goblin high priest", + "aggressive": "true", + "attack_level": "14", + "death_animation": "6182", + "defence_animation": "0", + "defence_level": "14", + "lifepoints": "20", + "magic_animation": "0", + "melee_animation": "7317", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "14", + "weakness": "8" + }, + { + "id": "6470", + "name": "Snailfeet", + "examine": "A goblin high priest", + "aggressive": "true", + "attack_level": "13", + "death_animation": "6182", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "7317", + "range_animation": "0", + "range_level": "18", + "respawn_delay": "60", + "safespot": null, + "strength_level": "13", + "weakness": "2" + }, + { + "id": "6471", + "name": "Mosschin", + "examine": "A goblin high priest", + "aggressive": "true", + "attack_level": "16", + "death_animation": "6182", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "magic_level": "22", + "melee_animation": "7317", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "16", + "weakness": "5" + }, + { + "id": "6472", + "name": "Redeyes", + "examine": "A goblin high priest", + "aggressive": "true", + "attack_level": "19", + "death_animation": "6182", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "magic_level": "26", + "melee_animation": "7317", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "19", + "weakness": "5" + }, + { + "id": "6473", + "name": "Strongbones", + "examine": "A goblin high priest", + "aggressive": "true", + "attack_level": "19", + "death_animation": "6182", + "defence_animation": "0", + "defence_level": "26", + "lifepoints": "37", + "magic_animation": "0", + "magic_level": "26", + "melee_animation": "7317", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "19", + "weakness": "5" + }, + { + "id": "6474", + "name": "Snothead" + }, + { + "id": "6475", + "name": "Snailfeet" + }, + { + "id": "6476", + "name": "Mosschin" + }, + { + "id": "6477", + "name": "Redeyes" + }, + { + "id": "6478", + "name": "Strongbones" + }, + { + "id": "6479", + "name": "Grubfoot" + }, + { + "id": "6480", + "name": "Grubfoot" + }, + { + "id": "6482", + "name": "Priest", + "examine": "Priest of the Ekeleshuun tribe.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6483", + "name": "Priest" + }, + { + "id": "6484", + "name": "Priest" + }, + { + "id": "6485", + "name": "Priest" + }, + { + "id": "6486", + "name": "Priest" + }, + { + "id": "6487", + "name": "Priest" + }, + { + "id": "6488", + "name": "Preacher", + "examine": "He is expounding the word of the Big High War God.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6489", + "name": "High priest" + }, + { + "id": "6490", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6491", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6492", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6493", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6494", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6495", + "name": "Goblin", + "attack_level": "1", + "clue_level": "0", + "combat_audio": "469,472,471", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6496", + "name": "Goblin guard", + "examine": "He doesn't look very welcoming.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6497", + "name": "Goblin guard", + "examine": "He doesn't look very welcoming.", + "attack_level": "1", + "combat_audio": "469,472,471", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6498", + "name": "Guard", + "examine": "A guard wearing blue armour.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6499", + "name": "Guard", + "examine": "A guard wearing orange armour.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6500", + "name": "Guard", + "examine": "A guard wearing black armour.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6501", + "name": "Guard", + "examine": "A guard wearing white armour.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6502", + "name": "Guard", + "examine": "A guard wearing purple armour.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6503", + "name": "Guard", + "examine": "A guard wearing yellow armour.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6504", + "name": "Ghost", + "attack_level": "1", + "combat_audio": "436,439,438", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "25", + "strength_level": "1" + }, + { + "id": "6505", + "name": "Registrar 1" + }, + { + "id": "6507", + "name": "Registrar 2", + "examine": "A very noble spider and attendant to the Queen.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6508", + "name": "Registrar 3", + "examine": "The highest ranking of the Spider Queen's servants.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6509", + "name": "Registrar 4", + "examine": "The head of the Spider Queen's army.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6510", + "name": "Jury", + "examine": "Trying hard to hide his identity.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6511", + "name": "Jury" + }, + { + "id": "6512", + "name": "Spectator", + "examine": "Sir Amik's loyal squire.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6513", + "name": "Spectator" + }, + { + "id": "6514", + "name": "Spectator", + "examine": "A being of ore and minerals.", + "attack_level": "1", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "1", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6515", + "name": "Spectator" + }, + { + "id": "6516", + "name": "Spectator", + "examine": "A monkey on a mission.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6517", + "name": "Spectator" + }, + { + "id": "6518", + "name": "Spectator", + "examine": "He works for Doric & Son.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6519", + "name": "Spectator" + }, + { + "id": "6520", + "name": "Head Registrar" + }, + { + "id": "6521", + "name": "Grand Exchange Tutor", + "examine": "Gives an introduction to the Grand Exchange.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6522", + "examine": "Director of the Grand Exchange." + }, + { + "id": "6523", + "name": "Farid Morrisane (ores)", + "examine": "The son of Ali M!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6524", + "name": "Bob Barter (herbs)", + "examine": "He's probably seen better days.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6525", + "name": "Murky Matt (runes)", + "examine": "You can never miss a pirate in disguise.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6526", + "name": "Relobo Blinyo (logs)", + "examine": "A tribal man", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6527", + "name": "Hofuthand (armour and weapons)", + "examine": "He's travelled a long way.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6528", + "examine": "There to help me make my bids." + }, + { + "id": "6529", + "examine": "There to help me make my bids." + }, + { + "id": "6530", + "examine": "There to help me make my bids." + }, + { + "id": "6531", + "examine": "There to help me make my bids." + }, + { + "id": "6532", + "examine": "She can look after my money. Good with money." + }, + { + "id": "6533", + "examine": "She can look after my money. Good with money." + }, + { + "id": "6534", + "examine": "He can look after my money. Good with money." + }, + { + "id": "6535", + "examine": "He can look after my money. Good with money." + }, + { + "id": "6536", + "name": "Registrar 5", + "examine": "Chief architect of the Spider Realm.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6537", + "name": "Mandrith" + }, + { + "id": "6538", + "name": "Banker" + }, + { + "id": "6539", + "name": "Charley the Cleaner" + }, + { + "id": "6540", + "name": "Scotty the Cleaner" + }, + { + "id": "6541", + "name": "Sanchez the Cleaner" + }, + { + "id": "6542", + "name": "Summer Bonde" + }, + { + "id": "6543", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6544", + "name": "", + "attack_level": "1", + "combat_audio": "511,513,512", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6558", + "name": "null", + "examine": "Tapping his feet and looking very bored.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6560", + "name": "null", + "examine": "A huge war chief. ", + "aggressive": "true", + "attack_level": "250", + "attack_speed": "5", + "bonuses": "300,300,300,300,300,300,150,300,300,250,43,96,43,30,0", + "death_animation": "7062", + "defence_animation": "7061", + "defence_level": "250", + "lifepoints": "254", + "magic_animation": "422", + "melee_animation": "422", + "range_animation": "422", + "range_level": "200", + "respawn_delay": "20", + "safespot": null, + "strength_level": "251" + }, + { + "id": "6566", + "name": "Broken grave marker" + }, + { + "id": "6567", + "name": "Collapsing grave marker" + }, + { + "id": "6568", + "name": "Grave marker" + }, + { + "id": "6569", + "name": "Broken grave marker" + }, + { + "id": "6570", + "name": "Collapsing grave marker" + }, + { + "id": "6571", + "name": "Gravestone" + }, + { + "id": "6572", + "name": "Broken gravestone" + }, + { + "id": "6573", + "name": "Collapsing gravestone" + }, + { + "id": "6574", + "name": "Gravestone" + }, + { + "id": "6575", + "name": "Broken gravestone" + }, + { + "id": "6576", + "name": "Collapsing gravestone" + }, + { + "id": "6577", + "name": "Gravestone" + }, + { + "id": "6578", + "name": "Broken gravestone" + }, + { + "id": "6579", + "name": "Collapsing gravestone" + }, + { + "id": "6580", + "name": "Stele" + }, + { + "id": "6581", + "name": "Broken stele" + }, + { + "id": "6582", + "name": "Collapsing stele" + }, + { + "id": "6583", + "name": "Saradomin symbol" + }, + { + "id": "6584", + "name": "Broken Saradomin symbol" + }, + { + "id": "6585", + "name": "Collapsing Saradomin symbol" + }, + { + "id": "6586", + "name": "Zamorak symbol" + }, + { + "id": "6587", + "name": "Broken Zamorak symbol" + }, + { + "id": "6588", + "name": "Collapsing Zamorak symbol" + }, + { + "id": "6589", + "name": "Guthix symbol" + }, + { + "id": "6590", + "name": "Broken Guthix symbol" + }, + { + "id": "6591", + "name": "Collapsing Guthix symbol" + }, + { + "id": "6592", + "name": "Bandos symbol" + }, + { + "id": "6593", + "name": "Broken Bandos symbol" + }, + { + "id": "6594", + "name": "Collapsing Bandos symbol" + }, + { + "id": "6595", + "name": "Armadyl symbol" + }, + { + "id": "6596", + "name": "Broken Armadyl symbol" + }, + { + "id": "6597", + "name": "Collapsing Armadyl symbol" + }, + { + "id": "6598", + "name": "Memorial stone" + }, + { + "id": "6599", + "name": "Broken memorial stone" + }, + { + "id": "6600", + "name": "Collapsing memorial stone" + }, + { + "id": "6601", + "name": "Memorial stone" + }, + { + "id": "6602", + "name": "Broken memorial stone" + }, + { + "id": "6603", + "name": "Collapsing memorial stone" + }, + { + "id": "6604", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6605", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6606", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6607", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6608", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6609", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6610", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6611", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6612", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6613", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6614", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6615", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6616", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6617", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6618", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6619", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6620", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6621", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6622", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6623", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6624", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6625", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6626", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6627", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6628", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6629", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6630", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6631", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6632", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6633", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6634", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6635", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6636", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6637", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6638", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6639", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6640", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6641", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6642", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6643", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6644", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6645", + "name": "Revenant cyclops", + "examine": "The ghost of a cyclops slain during the god wars.", + "attack_level": "43", + "clue_level": "2", + "death_animation": "7454", + "defence_animation": "7455", + "defence_level": "43", + "lifepoints": "110", + "magic_animation": "7497", + "magic_level": "43", + "melee_animation": "7453", + "range_animation": "7510", + "range_level": "43", + "safespot": null, + "slayer_exp": "110", + "spawn_animation": "7457", + "strength_level": "43", + "weakness": "0" + }, + { + "id": "6646", + "name": "Revenant hellhound", + "examine": "The essence of a hellhound slain during the god wars.", + "attack_level": "50", + "clue_level": "2", + "combat_audio": "3717,3719,3718", + "death_animation": "7461", + "defence_animation": "7462", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "7515", + "magic_level": "50", + "melee_animation": "7460", + "range_animation": "7501", + "range_level": "50", + "safespot": null, + "slayer_exp": "80", + "spawn_animation": "7464", + "strength_level": "50" + }, + { + "id": "6647", + "name": "Revenant demon", + "examine": "The essence of a demon slain during the god wars.", + "attack_level": "60", + "clue_level": "2", + "combat_audio": "400,404,403", + "death_animation": "7475", + "defence_animation": "7476", + "defence_level": "60", + "lifepoints": "80", + "magic_animation": "7498", + "magic_level": "60", + "melee_animation": "7474", + "range_animation": "7512", + "range_level": "60", + "safespot": null, + "slayer_exp": "80", + "spawn_animation": "7478", + "strength_level": "60" + }, + { + "id": "6648", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6649", + "name": "Revenant dark beast", + "examine": "The ghost of a dark beast slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7468", + "defence_animation": "7469", + "defence_level": "80", + "lifepoints": "140", + "magic_animation": "7515", + "melee_animation": "7467", + "range_animation": "7514", + "range_level": "80", + "safespot": null, + "slayer_exp": "140", + "spawn_animation": "7471", + "strength_level": "80" + }, + { + "id": "6650", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6651", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6652", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6653", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6654", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6655", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6656", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6657", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "22", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "22", + "lifepoints": "34", + "magic_animation": "7499", + "magic_level": "22", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "22", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "22" + }, + { + "id": "6658", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6659", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6660", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6661", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6662", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6663", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6664", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "poisonous": "", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6665", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6666", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6667", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6668", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6669", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6670", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6671", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6672", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6673", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "prj_height": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6674", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6675", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6676", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6677", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6678", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6679", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6680", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6681", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6682", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6683", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6684", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6685", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6686", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6687", + "name": "Revenant cyclops", + "examine": "The ghost of a cyclops slain during the god wars.", + "attack_level": "43", + "clue_level": "2", + "death_animation": "7454", + "defence_animation": "7455", + "defence_level": "43", + "lifepoints": "110", + "magic_animation": "7497", + "magic_level": "43", + "melee_animation": "7453", + "range_animation": "7510", + "range_level": "43", + "safespot": null, + "slayer_exp": "110", + "spawn_animation": "7457", + "strength_level": "43", + "weakness": "0" + }, + { + "id": "6688", + "name": "Revenant hellhound", + "examine": "The essence of a hellhound slain during the god wars.", + "attack_level": "50", + "clue_level": "2", + "combat_audio": "3717,3719,3718", + "death_animation": "7461", + "defence_animation": "7462", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "7515", + "magic_level": "50", + "melee_animation": "7460", + "range_animation": "7501", + "range_level": "50", + "safespot": null, + "slayer_exp": "80", + "spawn_animation": "7464", + "strength_level": "50" + }, + { + "id": "6689", + "name": "Revenant demon", + "examine": "The essence of a demon slain during the god wars.", + "attack_level": "60", + "clue_level": "2", + "combat_audio": "400,404,403", + "death_animation": "7475", + "defence_animation": "7476", + "defence_level": "60", + "lifepoints": "80", + "magic_animation": "7498", + "magic_level": "60", + "melee_animation": "7474", + "range_animation": "7512", + "range_level": "60", + "safespot": null, + "slayer_exp": "80", + "spawn_animation": "7478", + "strength_level": "60" + }, + { + "id": "6690", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6691", + "name": "Revenant dark beast", + "examine": "The ghost of a dark beast slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7468", + "defence_animation": "7469", + "defence_level": "80", + "lifepoints": "140", + "magic_animation": "7515", + "melee_animation": "7467", + "range_animation": "7514", + "range_level": "80", + "safespot": null, + "slayer_exp": "140", + "spawn_animation": "7471", + "strength_level": "80" + }, + { + "id": "6692", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6693", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6694", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6695", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6696", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6697", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6698", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6699", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6700", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6701", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6702", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6703", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6704", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6705", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6706", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6707", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6708", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6709", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6710", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6711", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6712", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6713", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6714", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6715", + "name": "Revenant imp", + "examine": "The essence of an imp slain during the god wars.", + "attack_level": "10", + "combat_audio": "0,0,0", + "death_animation": "7408", + "defence_animation": "7404", + "defence_level": "10", + "lifepoints": "20", + "magic_animation": "7500", + "magic_level": "10", + "melee_animation": "7407", + "range_animation": "7501", + "range_level": "10", + "safespot": null, + "slayer_exp": "10", + "spawn_animation": "7410", + "strength_level": "10" + }, + { + "id": "6716", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6717", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6718", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6719", + "name": "Revenant goblin", + "examine": "The ghost of a goblin slain during the god wars.", + "attack_level": "12", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7448", + "defence_animation": "7450", + "defence_level": "12", + "lifepoints": "24", + "magic_animation": "7499", + "magic_level": "12", + "melee_animation": "7449", + "range_animation": "7513", + "range_level": "12", + "safespot": null, + "spawn_animation": "7447", + "strength_level": "12" + }, + { + "id": "6720", + "name": "Revenant icefiend", + "examine": "The ghost of an icefiend slain during the God Wars.", + "attack_level": "27", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "27", + "lifepoints": "40", + "magic_animation": "7506", + "magic_level": "27", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "27", + "safespot": null, + "slayer_exp": "40", + "spawn_animation": "7485", + "strength_level": "27" + }, + { + "id": "6721", + "name": "Revenant pyrefiend", + "examine": "The essence of a pyrefiend slain during the god wars.", + "attack_level": "29", + "attack_speed": "3", + "clue_level": "1", + "death_animation": "7482", + "defence_animation": "7483", + "defence_level": "29", + "lifepoints": "48", + "magic_animation": "7506", + "magic_level": "29", + "melee_animation": "7481", + "range_animation": "7519", + "range_level": "29", + "safespot": null, + "slayer_exp": "48", + "spawn_animation": "7485", + "strength_level": "29" + }, + { + "id": "6722", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6723", + "name": "Revenant vampire", + "examine": "The ghost of a vampire slain in the god wars.", + "attack_level": "34", + "clue_level": "1", + "death_animation": "7428", + "defence_animation": "7429", + "defence_level": "34", + "lifepoints": "60", + "magic_animation": "7507", + "magic_level": "34", + "melee_animation": "7427", + "range_animation": "7520", + "range_level": "34", + "safespot": null, + "slayer_exp": "60", + "spawn_animation": "7426", + "strength_level": "34" + }, + { + "id": "6724", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6725", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6726", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6727", + "name": "Revenant hobgoblin", + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "attack_level": "32", + "clue_level": "1", + "combat_audio": "469,472,471", + "death_animation": "7419", + "defence_animation": "7420", + "defence_level": "32", + "lifepoints": "72", + "magic_animation": "7503", + "magic_level": "32", + "melee_animation": "7418", + "range_animation": "7516", + "range_level": "32", + "safespot": null, + "slayer_exp": "72", + "strength_level": "32" + }, + { + "id": "6728", + "name": "Revenant werewolf", + "examine": "The ghost of a werewolf slain during the god wars.", + "attack_level": "38", + "clue_level": "2", + "death_animation": "7398", + "defence_animation": "7399", + "defence_level": "38", + "lifepoints": "65", + "magic_animation": "7496", + "magic_level": "38", + "melee_animation": "7397", + "range_animation": "7521", + "range_level": "38", + "safespot": null, + "spawn_animation": "7403", + "strength_level": "38" + }, + { + "id": "6729", + "name": "Revenant ork", + "examine": "A ghost of an ork slain during the god wars.", + "attack_level": "70", + "clue_level": "2", + "death_animation": "7412", + "defence_animation": "7413", + "defence_level": "70", + "lifepoints": "105", + "magic_animation": "7505", + "magic_level": "70", + "melee_animation": "7411", + "range_animation": "7518", + "range_level": "70", + "safespot": null, + "strength_level": "70" + }, + { + "id": "6730", + "name": "Revenant knight", + "examine": "A ghost of a knight slain during the god wars.", + "attack_level": "80", + "clue_level": "2", + "death_animation": "7442", + "defence_animation": "7443", + "defence_level": "80", + "lifepoints": "143", + "magic_animation": "7508", + "magic_level": "80", + "melee_animation": "7441", + "poison_amount": "", + "poisonous": "", + "range_animation": "7522", + "range_level": "80", + "safespot": null, + "slayer_exp": "143", + "spawn_animation": "7440", + "strength_level": "80" + }, + { + "id": "6731", + "name": "Queen of Snow", + "examine": "Her lack of body heat is unsettling.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "movement_radius": "5", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6732", + "name": "Snow imp" + }, + { + "id": "6733", + "name": "Snow imp" + }, + { + "id": "6734", + "name": "Snow imp" + }, + { + "id": "6735", + "name": "Snow imp" + }, + { + "id": "6736", + "name": "Snow imp" + }, + { + "id": "6737", + "name": "Snow imp" + }, + { + "id": "6738", + "name": "Snow imp" + }, + { + "id": "6739", + "name": "Snow imp", + "examine": "It looks right at home here.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6740", + "name": "Snow", + "examine": "Snowflakes swirling in the wind.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6741", + "name": "Snow" + }, + { + "id": "6742", + "name": "Barbarian Snowman", + "examine": "A helmetted, barbarian snowman.", + "agg_radius": "", + "combat_audio": "12,3295,3287", + "death_animation": "7560", + "defence_animation": "7559", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "7565" + }, + { + "id": "6743", + "name": "Dragon snowman", + "examine": "A snowman in fake dragon armour.", + "attack_level": "1", + "combat_audio": "29,3295,3287", + "death_animation": "7560", + "defence_animation": "7559", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "7558", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6744", + "name": "Dwarf Snowman", + "examine": "A snow dwarf.", + "combat_audio": "12,3295,3287", + "death_animation": "7560", + "defence_animation": "7559", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "7565" + }, + { + "id": "6745", + "name": "Pirate snowman", + "examine": "Arr!", + "attack_level": "1", + "combat_audio": "29,3295,3287", + "death_animation": "7560", + "defence_animation": "7559", + "defence_level": "1", + "lifepoints": "20", + "melee_animation": "7558", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6746", + "name": "Snowman", + "examine": "A traditional snowman." + }, + { + "id": "6747", + "name": "Snow ranger", + "examine": "A snowman armed with a holly bow.", + "attack_level": "30", + "defence_level": "10", + "lifepoints": "30", + "range_level": "30", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6748", + "name": "Snow ranger", + "examine": "A snowman armed with an ice sword.", + "attack_level": "30", + "defence_level": "10", + "lifepoints": "20", + "magic_level": "30", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6749", + "name": "Snow mage", + "examine": "A snowman armed with a winter staff.", + "attack_level": "30", + "defence_level": "10", + "lifepoints": "20", + "range_level": "30", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6750", + "name": "Pet shop owner", + "examine": "The lady of the pet shop." + }, + { + "id": "6751", + "name": "Bulldog" + }, + { + "id": "6753", + "name": "Mummy" + }, + { + "id": "6754", + "name": "Mummy" + }, + { + "id": "6755", + "name": "Mummy" + }, + { + "id": "6756", + "name": "Mummy" + }, + { + "id": "6757", + "name": "Mummy" + }, + { + "id": "6758", + "name": "Mummy" + }, + { + "id": "6759", + "name": "Mummy" + }, + { + "id": "6760", + "name": "Mummy" + }, + { + "id": "6761", + "name": "Dried zombie", + "examine": "Cut-down and dried.", + "attack_level": "48", + "attack_speed": "5", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "48", + "lifepoints": "68", + "magic_animation": "0", + "melee_animation": "5568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "7" + }, + { + "id": "6762", + "name": "Dried zombie", + "examine": "Needs moisturising.", + "attack_level": "48", + "attack_speed": "5", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "48", + "lifepoints": "68", + "magic_animation": "0", + "melee_animation": "5568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "7" + }, + { + "id": "6763", + "name": "Dried zombie", + "examine": "I bet it's parched.", + "attack_level": "48", + "attack_speed": "5", + "death_animation": "5569", + "defence_animation": "0", + "defence_level": "48", + "lifepoints": "68", + "magic_animation": "0", + "melee_animation": "5568", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "7" + }, + { + "id": "6764", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "97", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6765", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "108", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6766", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6767", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "115", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6768", + "name": "Skeleton", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "774,775,777", + "death_animation": "5491", + "defence_animation": "5513", + "defence_level": "1", + "lifepoints": "140", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6769", + "name": "Doorman", + "examine": "A guard.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6770", + "name": "Giant scarab", + "examine": "A huge beast of a beetle.", + "aggressive": "true", + "attack_level": "49", + "death_animation": "7595", + "defence_animation": "0", + "defence_level": "66", + "lifepoints": "285", + "magic_animation": "0", + "melee_animation": "7596", + "range_animation": "0", + "range_level": "66", + "safespot": null, + "strength_level": "49", + "weakness": "2" + }, + { + "id": "6771", + "name": "Giant scarab" + }, + { + "id": "6772", + "name": "Scarab larva", + "examine": "It's not quite small enough to stamp upon.", + "attack_level": "18", + "death_animation": "7656", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "melee_animation": "7657", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "18", + "weakness": "9" + }, + { + "id": "6773", + "name": "Scabaras ranger", + "examine": "Bred to shoot you down.", + "aggressive": "true", + "attack_level": "41", + "combat_style": "1", + "death_animation": "7609", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "157", + "magic_animation": "0", + "melee_animation": "7607", + "projectile": "11", + "range_animation": "7607", + "range_level": "55", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "18", + "strength_level": "41", + "weakness": "2" + }, + { + "id": "6774", + "name": "Scabaras lancer", + "examine": "It might be angry...it's hard to tell.", + "aggressive": "true", + "attack_level": "55", + "death_animation": "7614", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "7612", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "6775", + "name": "Scabaras priest" + }, + { + "id": "6776", + "name": "Scabaras locust", + "examine": "A giant, mountable locust.", + "aggressive": "true", + "attack_level": "41", + "death_animation": "7581", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "7586", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "60", + "safespot": null, + "strength_level": "41", + "weakness": "2" + }, + { + "id": "6777", + "name": "Locust lancer", + "examine": "Bouncy", + "aggressive": "true", + "attack_level": "55", + "death_animation": "7581", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "7584", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "55", + "weakness": "9" + }, + { + "id": "6778", + "name": "Locust ranger", + "examine": "He'll have someone's eye out with that.", + "aggressive": "true", + "attack_level": "41", + "combat_style": "1", + "death_animation": "7581", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "melee_animation": "5451", + "projectile": "11", + "range_animation": "5451", + "range_level": "55", + "respawn_delay": "60", + "safespot": null, + "start_gfx": "18", + "strength_level": "41", + "weakness": "2" + }, + { + "id": "6779", + "name": "Crocodile", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "combat_audio": "386,388,387", + "death_animation": "7591", + "defence_animation": "7590", + "defence_level": "1", + "lifepoints": "72", + "melee_animation": "7588", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "62", + "strength_level": "1" + }, + { + "id": "6780", + "name": "Scabaras mage", + "examine": "Part scarab, part man.", + "aggressive": "true", + "attack_level": "41", + "combat_style": "2", + "death_animation": "7616", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "78", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7615", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "41", + "weakness": "4" + }, + { + "id": "6781", + "name": "Scabaras mage", + "examine": "Part scarab, part man.", + "aggressive": "true", + "attack_level": "1", + "combat_style": "2", + "death_animation": "7616", + "defence_animation": "7617", + "defence_level": "1", + "lifepoints": "70", + "melee_animation": "7620", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6782", + "name": "Maisa" + }, + { + "id": "6783", + "name": "Maisa" + }, + { + "id": "6784", + "name": "Priest" + }, + { + "id": "6785", + "name": "Clay golem", + "examine": "An animated clay statue.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6786", + "name": "Lead archaeologist Abigail", + "examine": "She looks a bit dirty from digging.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6787", + "name": "Assistant archaeologist Kerner", + "examine": "He looks a bit dusty from troweling.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6788", + "name": "High Priest of Scabaras", + "examine": "He exudes something like holiness.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6789", + "name": "High Priest of Scabaras", + "examine": "He exudes something like holiness.", + "attack_level": "66", + "death_animation": "7614", + "defence_animation": "0", + "defence_level": "66", + "lifepoints": "94", + "magic_animation": "0", + "magic_level": "66", + "melee_animation": "7612", + "range_animation": "0", + "range_level": "66", + "safespot": null, + "strength_level": "66", + "weakness": "10" + }, + { + "id": "6790", + "name": "High Priest of Scabaras", + "examine": "He exudes something like holiness.", + "attack_level": "66", + "death_animation": "7609", + "defence_animation": "0", + "defence_level": "66", + "lifepoints": "94", + "magic_animation": "0", + "magic_level": "66", + "melee_animation": "7607", + "range_animation": "7607", + "range_level": "66", + "safespot": null, + "strength_level": "66", + "weakness": "10" + }, + { + "id": "6791", + "name": "High Priest of Scabaras" + }, + { + "id": "6792", + "name": "Vulture" + }, + { + "id": "6793", + "name": "Spirit terrorbird" + }, + { + "id": "6794", + "name": "Spirit terrorbird", + "examine": "A bird. Literally terrifying.", + "attack_level": "50", + "death_animation": "1013", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "74", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "1010", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6795", + "name": "Spirit terrorbird", + "examine": "A bird. Literally terrifying.", + "attack_level": "50", + "death_animation": "1013", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "74", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "1010", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6796", + "name": "Granite crab", + "examine": "Is it a stone? Is it a crab? No! It's Granite Crab!", + "attack_level": "18", + "attack_speed": "3", + "bonuses": "16,9,5,12,4,11,57,53,61,12,45,22,0,0,0", + "death_animation": "8106", + "defence_animation": "8105", + "defence_level": "22", + "lifepoints": "39", + "magic_animation": "8104", + "magic_level": "13", + "melee_animation": "8104", + "range_animation": "8104", + "range_level": "16", + "respawn_delay": "50", + "safespot": null, + "strength_level": "17" + }, + { + "id": "6797", + "name": "Granite crab", + "examine": "Is it a stone? Is it a crab? No! It's Granite Crab!", + "attack_level": "18", + "attack_speed": "3", + "bonuses": "16,9,5,12,4,11,57,53,61,12,45,22,0,0,0", + "death_animation": "8106", + "defence_animation": "8105", + "defence_level": "22", + "lifepoints": "39", + "magic_animation": "8104", + "magic_level": "13", + "melee_animation": "8104", + "range_animation": "8104", + "range_level": "16", + "respawn_delay": "50", + "safespot": null, + "strength_level": "17", + "weakness": "10" + }, + { + "id": "6798", + "name": "Praying mantis", + "examine": "Wax on", + "attack_level": "60", + "death_animation": "8065", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "107", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "8069", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "6799", + "name": "Praying mantis", + "examine": "Wax on", + "attack_level": "60", + "death_animation": "8065", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "107", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "8069", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "6800", + "name": "Giant ent", + "examine": "He ent such a bad guy.", + "attack_level": "60", + "death_animation": "7854", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "111", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "7853", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "6801", + "name": "Giant ent", + "examine": "He ent such a bad guy.", + "attack_level": "60", + "death_animation": "7854", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "111", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "7853", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "6802", + "name": "Spirit cobra", + "examine": "Serpentine.", + "attack_level": "55", + "death_animation": "8153", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "8152", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6803", + "name": "Spirit cobra", + "examine": "Serpentine.", + "attack_level": "55", + "death_animation": "8153", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "90", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "8152", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6804", + "name": "Spirit dagannoth", + "examine": "Face the thing that should not be!", + "attack_level": "65", + "death_animation": "7780", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "115", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7786", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "6805", + "name": "Spirit dagannoth", + "examine": "Face the thing that should not be!", + "attack_level": "65", + "death_animation": "7780", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "115", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7786", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "6806", + "name": "Thorny snail", + "examine": "A hermit slug.", + "attack_level": "19", + "attack_speed": "5", + "bonuses": "47,50,52,52,54,49,13,3,13,4,0,0,0,0,0", + "combat_style": "1", + "death_animation": "8143", + "defence_animation": "8145", + "defence_level": "22", + "end_gfx": "1387", + "lifepoints": "28", + "magic_animation": "8143", + "magic_level": "18", + "melee_animation": "8143", + "poison_immune": "true", + "projectile": "1386", + "range_animation": "8143", + "range_level": "21", + "respawn_delay": "55", + "safespot": null, + "strength_level": "18" + }, + { + "id": "6807", + "name": "Thorny snail", + "examine": "A hermit slug.", + "attack_level": "19", + "attack_speed": "5", + "bonuses": "47,50,52,52,54,49,13,3,13,4,0,0,0,0,0", + "combat_style": "1", + "death_animation": "8143", + "defence_animation": "8145", + "defence_level": "22", + "end_gfx": "1387", + "lifepoints": "28", + "magic_animation": "8143", + "magic_level": "18", + "melee_animation": "8143", + "poison_immune": "true", + "projectile": "1386", + "range_animation": "8143", + "range_level": "21", + "respawn_delay": "55", + "safespot": null, + "strength_level": "18", + "weakness": "10" + }, + { + "id": "6808", + "name": "Beaver" + }, + { + "id": "6809", + "name": "Karamthulhu overlord", + "examine": "Kneel before squid!", + "attack_level": "50", + "combat_style": "2", + "death_animation": "7964", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "82", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "7963", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6810", + "name": "Karamthulhu overlord", + "examine": "Kneel before squid!", + "attack_level": "50", + "combat_style": "2", + "death_animation": "7964", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "82", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "7963", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6811", + "name": "Hydra", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7937", + "defence_animation": "7936", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "7935", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6812", + "name": "Hydra", + "attack_level": "1", + "combat_style": "1", + "death_animation": "7937", + "defence_animation": "7936", + "defence_level": "1", + "lifepoints": "10", + "melee_animation": "7935", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6813", + "name": "Bunyip", + "attack_level": "1", + "death_animation": "7740", + "defence_animation": "7742", + "defence_level": "1", + "lifepoints": "40", + "melee_animation": "7741", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6814", + "name": "Bunyip", + "attack_level": "1", + "death_animation": "7740", + "defence_animation": "7742", + "defence_level": "1", + "lifepoints": "40", + "melee_animation": "7741", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6815", + "name": "War tortoise", + "examine": "Definitely not teenaged", + "attack_level": "55", + "combat_style": "0", + "death_animation": "8285", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "95", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "8286", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6816", + "name": "War tortoise", + "examine": "Definitely not teenaged", + "attack_level": "55", + "combat_style": "0", + "death_animation": "8285", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "95", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "8286", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6817", + "name": "Fruit bat", + "examine": "Fruity and bat-shaped. A winning combination!.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6818", + "name": "Abyssal parasite", + "examine": "It's an extra-planar little blood hoover.", + "attack_level": "50", + "combat_style": "2", + "death_animation": "7671", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "8910", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6819", + "name": "Abyssal parasite", + "examine": "It's an extra-planar little blood hoover.", + "attack_level": "50", + "combat_style": "2", + "death_animation": "7671", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "77", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "8910", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6820", + "name": "Abyssal lurker", + "examine": "Lurking like only a lurker can.", + "attack_level": "55", + "death_animation": "7684", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "88", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7680", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6821", + "name": "Abyssal lurker", + "examine": "Lurking like only a lurker can.", + "attack_level": "55", + "death_animation": "7684", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "88", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7680", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6822", + "name": "Unicorn stallion", + "examine": "The pointiest horse on the planet.", + "attack_level": "64", + "bonuses": "48,59,43,52,104,52,116,123,134,46,127,4,0,0,0", + "combat_audio": "4135,4196,4195", + "death_animation": "6377", + "defence_animation": "6375", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "6376", + "magic_level": "69", + "melee_animation": "6376", + "poison_immune": "true", + "range_animation": "6376", + "range_level": "72", + "safespot": null, + "strength_level": "62" + }, + { + "id": "6823", + "name": "Unicorn stallion", + "examine": "The pointiest horse on the planet.", + "attack_level": "64", + "bonuses": "48,59,43,52,104,52,116,123,134,46,127,4,0,0,0", + "combat_audio": "4135,4196,4195", + "death_animation": "6377", + "defence_animation": "6375", + "defence_level": "70", + "lifepoints": "100", + "magic_animation": "6376", + "magic_level": "69", + "melee_animation": "6376", + "poison_immune": "true", + "range_animation": "6376", + "range_level": "72", + "safespot": null, + "strength_level": "62", + "weakness": "10" + }, + { + "id": "6824", + "name": "Magpie", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "2", + "death_animation": "8012", + "defence_animation": "5388", + "defence_level": "1", + "lifepoints": "16", + "melee_animation": "7810", + "projectile": "1318", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6825", + "name": "Dreadfowl", + "examine": "Southern fried please!", + "attack_level": "17", + "attack_speed": "5", + "bonuses": "16,15,29,12,39,13,41,35,29,39,47,2,2,2,7", + "combat_style": "2", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "22", + "lifepoints": "16", + "magic_animation": "7810", + "magic_level": "23", + "melee_animation": "7810", + "poison_immune": "true", + "projectile": "1318", + "range_animation": "7810", + "range_level": "16", + "respawn_delay": "50", + "safespot": null, + "strength_level": "15" + }, + { + "id": "6826", + "name": "Dreadfowl", + "examine": "Southern fried please!", + "attack_level": "17", + "attack_speed": "5", + "bonuses": "16,15,29,12,39,13,41,35,29,39,47,2,2,2,7", + "combat_style": "2", + "death_animation": "5389", + "defence_animation": "5388", + "defence_level": "22", + "lifepoints": "16", + "magic_animation": "7810", + "magic_level": "23", + "melee_animation": "7810", + "poison_immune": "true", + "projectile": "1318", + "range_animation": "7810", + "range_level": "16", + "respawn_delay": "50", + "safespot": null, + "strength_level": "15", + "weakness": "10" + }, + { + "id": "6827", + "name": "Stranger plant", + "examine": "It's mean and green!", + "attack_level": "55", + "attack_speed": "5", + "death_animation": "8209", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "91", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "8208", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6828", + "name": "Stranger plant", + "examine": "It's mean and green!", + "attack_level": "55", + "attack_speed": "5", + "death_animation": "8209", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "91", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "8208", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6829", + "name": "Spirit wolf", + "examine": "Man's significantly less-domesticated friend.", + "attack_level": "16", + "attack_speed": "5", + "bonuses": "12,7,4,10,23,5,29,27,16,12,13,17,0,0,0", + "death_animation": "8295", + "defence_animation": "8294", + "defence_level": "21", + "lifepoints": "15", + "magic_animation": "8292", + "magic_level": "7", + "melee_animation": "8292", + "range_animation": "8292", + "range_level": "9", + "safespot": null, + "strength_level": "18" + }, + { + "id": "6830", + "name": "Spirit wolf", + "examine": "Man's significantly less-domesticated friend.", + "attack_level": "16", + "attack_speed": "5", + "bonuses": "12,7,4,10,23,5,29,27,16,12,13,17,0,0,0", + "death_animation": "8295", + "defence_animation": "8294", + "defence_level": "21", + "lifepoints": "15", + "magic_animation": "8292", + "magic_level": "7", + "melee_animation": "8292", + "range_animation": "8292", + "range_level": "9", + "safespot": null, + "strength_level": "18", + "weakness": "10" + }, + { + "id": "6831", + "name": "Desert wyrm", + "examine": "Surprisingly slime-free.", + "attack_level": "18", + "combat_style": "1", + "death_animation": "7797", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "7795", + "range_animation": "0", + "range_level": "18", + "respawn_delay": "0", + "safespot": null, + "strength_level": "18", + "weakness": "10" + }, + { + "id": "6832", + "name": "Desert wyrm", + "examine": "Surprisingly slime-free.", + "attack_level": "18", + "combat_style": "1", + "death_animation": "7797", + "defence_animation": "0", + "defence_level": "18", + "lifepoints": "25", + "magic_animation": "0", + "magic_level": "18", + "melee_animation": "7795", + "range_animation": "0", + "range_level": "18", + "respawn_delay": "0", + "safespot": null, + "strength_level": "18", + "weakness": "10" + }, + { + "id": "6833", + "name": "Evil turnip", + "examine": "If you think he's evil", + "attack_level": "42", + "combat_style": "1", + "death_animation": "8250", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "magic_level": "42", + "melee_animation": "8248", + "range_animation": "0", + "range_level": "42", + "safespot": null, + "strength_level": "42", + "weakness": "10" + }, + { + "id": "6834", + "name": "Evil turnip", + "examine": "If you think he's evil", + "attack_level": "42", + "combat_style": "1", + "death_animation": "8250", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "magic_level": "42", + "melee_animation": "8248", + "range_animation": "0", + "range_level": "42", + "safespot": null, + "strength_level": "42", + "weakness": "10" + }, + { + "id": "6835", + "name": "Vampire bat", + "examine": "It vants to suck my blood!", + "attack_level": "31", + "death_animation": "8276", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "44", + "magic_animation": "0", + "magic_level": "31", + "melee_animation": "8275", + "range_animation": "0", + "range_level": "31", + "respawn_delay": "0", + "safespot": null, + "strength_level": "31", + "weakness": "10" + }, + { + "id": "6836", + "name": "Vampire bat", + "examine": "It vants to suck my blood!", + "attack_level": "31", + "death_animation": "8276", + "defence_animation": "0", + "defence_level": "31", + "lifepoints": "44", + "magic_animation": "0", + "magic_level": "31", + "melee_animation": "8275", + "range_animation": "0", + "range_level": "31", + "respawn_delay": "0", + "safespot": null, + "strength_level": "31", + "weakness": "10" + }, + { + "id": "6837", + "name": "Spirit scorpion", + "examine": "Salt and vinegaroon.", + "attack_level": "19", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "0", + "defence_level": "19", + "lifepoints": "27", + "magic_animation": "0", + "magic_level": "19", + "melee_animation": "6254", + "range_animation": "0", + "range_level": "19", + "respawn_delay": "0", + "safespot": null, + "strength_level": "19", + "weakness": "10" + }, + { + "id": "6838", + "name": "Spirit scorpion", + "examine": "Salt and vinegaroon.", + "attack_level": "19", + "combat_audio": "3611,3612,3610", + "death_animation": "6256", + "defence_animation": "0", + "defence_level": "19", + "lifepoints": "27", + "magic_animation": "0", + "magic_level": "19", + "melee_animation": "6254", + "range_animation": "0", + "range_level": "19", + "respawn_delay": "0", + "safespot": null, + "strength_level": "19", + "weakness": "10" + }, + { + "id": "6839", + "name": "Arctic bear", + "examine": "Crikey! Look at the size of those teeth!", + "attack_level": "60", + "bonuses": "90,50,50,60,90,80,50,30,40,100,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "4929", + "defence_animation": "4928", + "defence_level": "60", + "lifepoints": "10", + "magic_level": "60", + "melee_animation": "4925", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60" + }, + { + "id": "6840", + "name": "Arctic bear", + "examine": "Crikey! Look at the size of those teeth!", + "attack_level": "60", + "bonuses": "90,50,50,60,90,80,50,30,40,100,0,0,0,0,0", + "combat_audio": "498,500,499", + "death_animation": "4929", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "101", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "4925", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "6841", + "name": "Spirit spider", + "examine": "Would scare anyone off their tuffet.", + "attack_level": "17", + "bonuses": "15,16,11,14,34,12,24,36,46,16,37,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "17", + "lifepoints": "18", + "magic_animation": "5327", + "magic_level": "15", + "melee_animation": "5327", + "range_animation": "5327", + "range_level": "12", + "respawn_delay": "50", + "safespot": null, + "strength_level": "16" + }, + { + "id": "6842", + "name": "Spirit spider", + "examine": "Would scare anyone off their tuffet.", + "attack_level": "17", + "bonuses": "15,16,11,14,34,12,24,36,46,16,37,0,0,0,0", + "combat_audio": "537,539,538", + "death_animation": "5329", + "defence_animation": "5328", + "defence_level": "17", + "lifepoints": "18", + "magic_animation": "5327", + "magic_level": "15", + "melee_animation": "5327", + "range_animation": "5327", + "range_level": "12", + "respawn_delay": "50", + "safespot": null, + "strength_level": "16", + "weakness": "10" + }, + { + "id": "6843", + "name": "Bloated leech", + "examine": "It's like a little suction pump with eyes.", + "attack_level": "49", + "death_animation": "7656", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "49", + "melee_animation": "7657", + "range_animation": "0", + "range_level": "49", + "respawn_delay": "0", + "safespot": null, + "strength_level": "49", + "weakness": "10" + }, + { + "id": "6844", + "name": "Bloated leech", + "examine": "It's like a little suction pump with eyes.", + "attack_level": "49", + "death_animation": "7656", + "defence_animation": "0", + "defence_level": "49", + "lifepoints": "70", + "magic_animation": "0", + "magic_level": "49", + "melee_animation": "7657", + "range_animation": "0", + "range_level": "49", + "respawn_delay": "0", + "safespot": null, + "strength_level": "49", + "weakness": "10" + }, + { + "id": "6845", + "name": "Honey badger", + "examine": "Violent little so-and-so.", + "attack_level": "32", + "death_animation": "7925", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "32", + "melee_animation": "7928", + "range_animation": "0", + "range_level": "32", + "respawn_delay": "0", + "safespot": null, + "strength_level": "32", + "weakness": "10" + }, + { + "id": "6846", + "name": "Honey badger", + "examine": "Violent little so-and-so.", + "attack_level": "32", + "death_animation": "7925", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "45", + "magic_animation": "0", + "magic_level": "32", + "melee_animation": "7928", + "range_animation": "0", + "range_level": "32", + "respawn_delay": "0", + "safespot": null, + "strength_level": "32", + "weakness": "10" + }, + { + "id": "6847", + "name": "Albino rat", + "examine": "The big cheese.", + "attack_level": "31", + "bonuses": "64,42,40,57,64,50,76,82,72,24,75,5,15,5,5", + "combat_audio": "703,705,704", + "defence_level": "32", + "lifepoints": "68", + "magic_level": "27", + "poison_immune": "true", + "range_level": "31", + "respawn_delay": "50", + "safespot": null, + "strength_level": "28" + }, + { + "id": "6848", + "name": "Albino rat", + "examine": "The big cheese.", + "attack_level": "31", + "bonuses": "64,42,40,57,64,50,76,82,72,24,75,5,15,5,5", + "combat_audio": "703,705,704", + "defence_level": "32", + "lifepoints": "68", + "magic_level": "27", + "poison_immune": "true", + "range_level": "31", + "respawn_delay": "50", + "safespot": null, + "strength_level": "28", + "weakness": "10" + }, + { + "id": "6849", + "name": "Granite lobster", + "examine": "Puts the 'crust' in 'crustacean'.", + "attack_level": "60", + "bonuses": "93,90,65,90,30,40,50,50,60,40,0,0,0,0,0", + "death_animation": "8113", + "defence_animation": "8114", + "defence_level": "60", + "lifepoints": "10", + "melee_animation": "8112", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60" + }, + { + "id": "6850", + "name": "Granite lobster", + "examine": "Puts the 'crust' in 'crustacean'.", + "attack_level": "60", + "bonuses": "93,90,65,90,30,40,50,50,60,40,0,0,0,0,0", + "death_animation": "8113", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "105", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "8112", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "6851", + "name": "Macaw", + "attack_level": "1", + "death_animation": "8012", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6852", + "name": "Macaw", + "attack_level": "1", + "death_animation": "8012", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6853", + "name": "Bronze minotaur", + "examine": "He's just a big bully.", + "attack_level": "19", + "bonuses": "-2,6,3,0,0,15,14,9,-6,14,5,90,0,0,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "19", + "lifepoints": "133", + "magic_level": "1", + "melee_animation": "8024", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "19" + }, + { + "id": "6854", + "name": "Bronze minotaur", + "examine": "He's just a big bully.", + "attack_level": "19", + "bonuses": "15,20,10,15,10,15,15,15,0,0,0,90,0,0,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "0", + "defence_level": "19", + "lifepoints": "133", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "8024", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "19", + "weakness": "10" + }, + { + "id": "6855", + "name": "Iron minotaur", + "examine": "He's just a big bully.", + "attack_level": "25", + "bonuses": "-2,8,5,0,0,21,17,9,-6,20,5,100,0,100,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "25", + "lifepoints": "193", + "magic_animation": "", + "magic_level": "25", + "melee_animation": "8024", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "25" + }, + { + "id": "6856", + "name": "Iron minotaur", + "examine": "He's just a big bully.", + "attack_level": "25", + "bonuses": "25,25,25,25,0,25,25,25,25,0,0,100,0,100,0", + "clue_level": "", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "193", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "8024", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "25", + "weakness": "10" + }, + { + "id": "6857", + "name": "Steel minotaur", + "examine": "He's just a big bully!", + "attack_level": "28", + "bonuses": "-2,16,11,0,0,32,31,24,-6,31,5,122,0,122,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "28", + "lifepoints": "260", + "magic_level": "28", + "melee_animation": "8024", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "28" + }, + { + "id": "6858", + "name": "Steel minotaur", + "examine": "He's just a big bully.", + "attack_level": "28", + "bonuses": "40,30,30,30,30,30,30,30,30,30,0,127,0,0,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "260", + "magic_animation": "0", + "magic_level": "28", + "melee_animation": "8024", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "28", + "weakness": "10" + }, + { + "id": "6859", + "name": "Mithril minotaur", + "examine": "He's just a big bully", + "attack_level": "30", + "bonuses": "-2,22,17,0,0,46,44,38,-6,44,20,146,0,147,0", + "can_tolerate": "", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "30", + "lifepoints": "340", + "magic_level": "30", + "melee_animation": "8024", + "range_level": "0", + "respawn_delay": "0", + "safespot": null, + "strength_level": "30" + }, + { + "id": "6860", + "name": "Mithril minotaur", + "examine": "He's just a big bully.", + "attack_level": "30", + "bonuses": "30,30,30,30,0,30,30,30,30,0,30,146,0,147,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "30", + "lifepoints": "340", + "magic_animation": "0", + "magic_level": "30", + "melee_animation": "8024", + "range_animation": "0", + "range_level": "0", + "respawn_delay": "0", + "safespot": null, + "strength_level": "30", + "weakness": "10" + }, + { + "id": "6861", + "name": "Adamant minotaur", + "examine": "He's just a big bully.", + "attack_level": "35", + "attack_speed": "", + "bonuses": "-2,31,26,-3,-17,65,63,55,-6,63,30,146,0,181,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "35", + "lifepoints": "441", + "magic_level": "35", + "melee_animation": "8024", + "poison_immune": "", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "35" + }, + { + "id": "6862", + "name": "Adamant minotaur", + "examine": "He's just a big bully.", + "attack_level": "35", + "bonuses": "40,50,40,45,35,20,50,36,30,40,15,180,30,10,0", + "combat_style": "0", + "death_animation": "8025", + "defence_animation": "0", + "defence_level": "35", + "lifepoints": "441", + "magic_animation": "0", + "magic_level": "35", + "melee_animation": "8024", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "35", + "weakness": "10" + }, + { + "id": "6863", + "name": "Rune minotaur", + "examine": "He's just a big bully.", + "attack_level": "40", + "bonuses": "-2,48,43,0,-1,207,209,192,-12,205,102,157,0,195,0", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "40", + "lifepoints": "570", + "magic_level": "40", + "melee_animation": "8024", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "40" + }, + { + "id": "6864", + "name": "Rune minotaur", + "examine": "He's just a big bully.", + "attack_level": "40", + "bonuses": "50,40,40,56,40,30,50,30,60,30,40,219,50,40,40", + "death_animation": "8025", + "defence_animation": "8023", + "defence_level": "40", + "lifepoints": "570", + "magic_level": "40", + "melee_animation": "8024", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "slayer_exp": "0", + "strength_level": "40" + }, + { + "id": "6865", + "name": "Smoke devil", + "examine": "Well", + "attack_level": "55", + "death_animation": "7818", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "87", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7816", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6866", + "name": "Smoke devil", + "examine": "Well", + "attack_level": "55", + "death_animation": "7818", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "87", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7816", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6867", + "name": "Bull ant", + "examine": "Putting all three of its best feet forward.", + "attack_level": "40", + "death_animation": "7897", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "magic_level": "40", + "melee_animation": "7896", + "range_animation": "0", + "range_level": "40", + "respawn_delay": "0", + "safespot": null, + "strength_level": "40", + "weakness": "10" + }, + { + "id": "6868", + "name": "Bull ant", + "examine": "Putting all three of its best feet forward.", + "attack_level": "40", + "death_animation": "7897", + "defence_animation": "0", + "defence_level": "40", + "lifepoints": "57", + "magic_animation": "0", + "magic_level": "40", + "melee_animation": "7896", + "range_animation": "0", + "range_level": "40", + "respawn_delay": "0", + "safespot": null, + "strength_level": "40", + "weakness": "10" + }, + { + "id": "6869", + "name": "Wolpertinger", + "examine": "It's just a harmless wee rabbit. ", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "59,50,50,50,50,50,50,50,50,50,50,50,50,68,0", + "combat_style": "2", + "death_animation": "8305", + "defence_animation": "8306", + "defence_level": "95", + "lifepoints": "619", + "magic_animation": "8304", + "magic_level": "95", + "melee_animation": "8304", + "poison_immune": "true", + "range_animation": "8304", + "range_level": "95", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6870", + "name": "Wolpertinger", + "examine": "It's just a harmless wee rabbit. ", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "59,50,50,50,50,50,50,50,50,50,50,50,50,68,0", + "combat_style": "2", + "death_animation": "8305", + "defence_animation": "8306", + "defence_level": "95", + "lifepoints": "619", + "magic_animation": "8304", + "magic_level": "95", + "melee_animation": "8304", + "poison_immune": "true", + "range_animation": "8304", + "range_level": "95", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6871", + "name": "Compost mound", + "examine": "I suppose it could smell worse", + "attack_level": "28", + "attack_speed": "5", + "death_animation": "7770", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "magic_level": "28", + "melee_animation": "7769", + "range_animation": "0", + "range_level": "28", + "respawn_delay": "0", + "safespot": null, + "strength_level": "28", + "weakness": "10" + }, + { + "id": "6872", + "name": "Compost mound", + "examine": "I suppose it could smell worse", + "attack_level": "28", + "attack_speed": "5", + "death_animation": "7770", + "defence_animation": "0", + "defence_level": "28", + "lifepoints": "40", + "magic_animation": "0", + "magic_level": "28", + "melee_animation": "7769", + "range_animation": "0", + "range_level": "28", + "respawn_delay": "0", + "safespot": null, + "strength_level": "28", + "weakness": "10" + }, + { + "id": "6873", + "name": "Pack yak", + "examine": "Bulk haulage never smelled so bad.", + "attack_level": "112", + "attack_speed": "5", + "bonuses": "64,67,5,72,128,49,264,234,164,49,132,40,35,40,40", + "death_animation": "5784", + "defence_animation": "5783", + "defence_level": "121", + "lifepoints": "710", + "magic_animation": "5782", + "magic_level": "91", + "melee_animation": "5782", + "poison_immune": "true", + "range_animation": "5782", + "range_level": "86", + "safespot": null, + "strength_level": "104" + }, + { + "id": "6874", + "name": "Pack yak", + "examine": "Bulk haulage never smelled so bad.", + "attack_level": "112", + "attack_speed": "5", + "bonuses": "64,67,5,72,128,49,264,234,164,49,132,40,35,40,40", + "death_animation": "5784", + "defence_animation": "5783", + "defence_level": "121", + "lifepoints": "710", + "magic_animation": "5782", + "magic_level": "91", + "melee_animation": "5782", + "poison_immune": "true", + "range_animation": "5782", + "range_level": "86", + "safespot": null, + "strength_level": "104", + "weakness": "10" + }, + { + "id": "6875", + "name": "Spirit cockatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6876", + "name": "Spirit cockatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6877", + "name": "Spirit guthatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6878", + "name": "Spirit guthatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6879", + "name": "Spirit saratrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_audio": "703,705,704", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6880", + "name": "Spirit saratrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_audio": "703,705,704", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6881", + "name": "Spirit zamatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6882", + "name": "Spirit zamatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6883", + "name": "Spirit pengatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6884", + "name": "Spirit pengatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6885", + "name": "Spirit coraxatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6886", + "name": "Spirit coraxatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6887", + "name": "Spirit vulatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6888", + "name": "Spirit vulatrice", + "examine": "If looks could kill... Wait", + "attack_level": "43", + "combat_style": "2", + "death_animation": "7763", + "defence_animation": "0", + "defence_level": "43", + "lifepoints": "61", + "magic_animation": "0", + "magic_level": "43", + "melee_animation": "7762", + "projectile": "1468", + "range_animation": "0", + "range_level": "43", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1467", + "strength_level": "43", + "weakness": "10" + }, + { + "id": "6889", + "name": "Barker toad", + "examine": "The only creature with a mouth big enough to fit a cannon ball into.", + "attack_level": "55", + "death_animation": "7256", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "94", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7260", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6890", + "name": "Barker toad", + "examine": "The only creature with a mouth big enough to fit a cannon ball into.", + "attack_level": "55", + "death_animation": "7256", + "defence_animation": "0", + "defence_level": "55", + "lifepoints": "94", + "magic_animation": "0", + "magic_level": "55", + "melee_animation": "7260", + "range_animation": "0", + "range_level": "55", + "respawn_delay": "0", + "safespot": null, + "strength_level": "55", + "weakness": "10" + }, + { + "id": "6891", + "name": "Penguin keeper", + "examine": "He looks like the type of guy who would keep penguins.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6892", + "name": "Pet shop owner", + "examine": "The lady of the pet shop.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6893", + "name": "Pet shop owner", + "examine": "The man of the pet shop.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6894", + "name": "Terrier", + "examine": "A terrier puppy." + }, + { + "id": "6895", + "name": "Labrador", + "examine": "A labrador puppy." + }, + { + "id": "6896", + "name": "Dalmatian", + "examine": "A dalmatian puppy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6897", + "name": "Bulldog", + "examine": "A bulldog puppy.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6898", + "name": "Pet shop owner" + }, + { + "id": "6899", + "name": "Bulldog" + }, + { + "id": "6900", + "name": "Hatchling dragon", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6901", + "name": "Baby dragon", + "attack_level": "1", + "combat_audio": "407,405,406", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6902", + "name": "Hatchling dragon", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6903", + "name": "Baby dragon", + "attack_level": "1", + "combat_audio": "407,405,406", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6904", + "name": "Hatchling dragon", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6905", + "name": "Baby dragon", + "attack_level": "1", + "combat_audio": "407,405,406", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6906", + "name": "Hatchling dragon", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6907", + "name": "Baby dragon", + "attack_level": "1", + "combat_audio": "407,405,406", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6908", + "name": "Baby penguin" + }, + { + "id": "6909", + "name": "Penguin" + }, + { + "id": "6910", + "name": "Penguin" + }, + { + "id": "6911", + "name": "Raven chick" + }, + { + "id": "6912", + "name": "Raven" + }, + { + "id": "6913", + "name": "Baby raccoon", + "examine": "A stripy little baby raccoon." + }, + { + "id": "6914", + "name": "Raccoon", + "examine": "He can run with us." + }, + { + "id": "6915", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "6916", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "6917", + "name": "Baby gecko", + "examine": "It's so adorably tiny!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6918", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "6919", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "6920", + "name": "Squirrel", + "examine": "An experienced nut-thief." + }, + { + "id": "6921", + "name": "Baby squirrel", + "examine": "A tiny nut-thief.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6922", + "name": "Baby chameleon" + }, + { + "id": "6923", + "name": "Chameleon" + }, + { + "id": "6924", + "name": "Baby chameleon" + }, + { + "id": "6925", + "name": "Chameleon" + }, + { + "id": "6926", + "name": "Baby chameleon" + }, + { + "id": "6927", + "name": "Chameleon" + }, + { + "id": "6928", + "name": "Baby chameleon" + }, + { + "id": "6929", + "name": "Chameleon" + }, + { + "id": "6930", + "name": "Baby chameleon" + }, + { + "id": "6931", + "name": "Chameleon" + }, + { + "id": "6932", + "name": "Baby chameleon" + }, + { + "id": "6933", + "name": "Chameleon" + }, + { + "id": "6934", + "name": "Baby chameleon" + }, + { + "id": "6935", + "name": "Chameleon" + }, + { + "id": "6936", + "name": "Baby chameleon" + }, + { + "id": "6937", + "name": "Chameleon" + }, + { + "id": "6938", + "name": "Baby chameleon" + }, + { + "id": "6939", + "name": "Chameleon" + }, + { + "id": "6940", + "name": "Baby chameleon" + }, + { + "id": "6941", + "name": "Chameleon" + }, + { + "id": "6942", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6943", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6944", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6945", + "name": "Vulture chick" + }, + { + "id": "6946", + "name": "Vulture" + }, + { + "id": "6947", + "name": "Baby giant crab" + }, + { + "id": "6948", + "name": "Giant crab" + }, + { + "id": "6949", + "name": "Saradomin chick" + }, + { + "id": "6950", + "name": "Saradomin bird" + }, + { + "id": "6951", + "name": "Saradomin owl" + }, + { + "id": "6952", + "name": "Zamorak chick" + }, + { + "id": "6953", + "name": "Zamorak bird" + }, + { + "id": "6954", + "name": "Zamorak hawk" + }, + { + "id": "6955", + "name": "Guthix chick" + }, + { + "id": "6956", + "name": "Guthix bird" + }, + { + "id": "6957", + "name": "Guthix raptor" + }, + { + "id": "6958", + "name": "Terrier puppy", + "examine": "It's lively and energetic." + }, + { + "id": "6959", + "name": "Terrier", + "examine": "It's lively and energetic." + }, + { + "id": "6960", + "name": "Greyhound puppy", + "examine": "This is one fast little pooch." + }, + { + "id": "6961", + "name": "Greyhound", + "examine": "An aerodynamic doggy." + }, + { + "id": "6962", + "name": "Labrador puppy", + "examine": "Soft but strong... and cute." + }, + { + "id": "6963", + "name": "Labrador", + "examine": "My most faithful friend." + }, + { + "id": "6964", + "name": "Dalmatian puppy", + "examine": "Now, if only I could find another hundred..." + }, + { + "id": "6965", + "name": "Dalmatian", + "examine": "A purebred doggy." + }, + { + "id": "6966", + "name": "Sheepdog puppy", + "examine": "This little puppy is very quiet." + }, + { + "id": "6967", + "name": "Sheepdog", + "examine": "Come by! Come by!" + }, + { + "id": "6968", + "name": "Bulldog", + "examine": "Looks like it's chewing a wasp." + }, + { + "id": "6969", + "name": "Bulldog puppy", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "2", + "death_animation": "8305", + "defence_animation": "8306", + "defence_level": "1", + "lifepoints": "651", + "magic_level": "28", + "melee_animation": "8304", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6970", + "name": "Pikkupstix", + "examine": "He's a very important druid." + }, + { + "id": "6971", + "name": "Pikkupstix", + "examine": "He's a very important druid." + }, + { + "id": "6972", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "7186", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6973", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6974", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6975", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "7186", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6976", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6977", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6978", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6979", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "7186", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28" + }, + { + "id": "6980", + "name": "Druid", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,513,512", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6981", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6982", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "7186", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6983", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6984", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "7186", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7181", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6985", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6986", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6987", + "name": "Druidess", + "examine": "A nature lover.", + "attack_level": "28", + "attack_speed": "4", + "combat_audio": "511,506,505", + "death_animation": "7185", + "defence_animation": "0", + "defence_level": "32", + "lifepoints": "30", + "magic_animation": "711", + "magic_level": "25", + "melee_animation": "7182", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "strength_level": "28", + "weakness": "3" + }, + { + "id": "6988", + "name": "Pikkupstix", + "examine": "He's a very important druid." + }, + { + "id": "6989", + "name": "Pikkupstix", + "examine": "He's a very important druid." + }, + { + "id": "6990", + "name": "Giant wolpertinger" + }, + { + "id": "6991", + "name": "Ibis" + }, + { + "id": "6992", + "name": "Spirit jelly", + "examine": "On Gielinor", + "attack_level": "50", + "death_animation": "8570", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "78", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "8569", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6993", + "name": "Spirit jelly", + "examine": "On Gielinor", + "attack_level": "50", + "death_animation": "8570", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "78", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "8569", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "6994", + "name": "Spirit kalphite", + "examine": "Hail to the Queen", + "attack_level": "25", + "combat_style": "1", + "death_animation": "6228", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "6223", + "range_animation": "0", + "range_level": "25", + "respawn_delay": "0", + "safespot": null, + "strength_level": "25", + "weakness": "10" + }, + { + "id": "6995", + "name": "Spirit kalphite", + "examine": "Hail to the Queen", + "attack_level": "25", + "combat_style": "1", + "death_animation": "6228", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "6223", + "range_animation": "0", + "range_level": "25", + "respawn_delay": "0", + "safespot": null, + "strength_level": "25", + "weakness": "10" + }, + { + "id": "6996", + "name": "Fishing spot" + }, + { + "id": "6997", + "name": "Baby raccoon", + "examine": "A stripy little baby raccoon.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "6998", + "name": "Revenant dragon", + "examine": "A ghost of a dragon slain during the god wars.", + "attack_level": "85", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "8593", + "defence_animation": "8592", + "defence_level": "85", + "lifepoints": "155", + "magic_animation": "8594", + "melee_animation": "8591", + "poison_amount": "", + "poisonous": "", + "range_animation": "8594", + "range_level": "85", + "safespot": null, + "spawn_animation": "8595", + "strength_level": "85" + }, + { + "id": "6999", + "name": "Revenant dragon", + "examine": "A ghost of a dragon slain during the god wars.", + "attack_level": "85", + "clue_level": "2", + "combat_audio": "408,410,409", + "death_animation": "8593", + "defence_animation": "8592", + "defence_level": "85", + "lifepoints": "155", + "magic_animation": "8594", + "melee_animation": "8591", + "poison_amount": "", + "poisonous": "", + "range_animation": "8594", + "range_level": "85", + "safespot": null, + "spawn_animation": "8595", + "strength_level": "85" + }, + { + "id": "7000", + "name": "Dark Squall" + }, + { + "id": "7002", + "name": "Surok Magis" + }, + { + "id": "7003", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "7004", + "name": "Fire giant", + "examine": "A very large elemental adversary.", + "attack_level": "65", + "attack_speed": "5", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "combat_audio": "447,451,450", + "death_animation": "4668", + "defence_animation": "4664", + "defence_level": "65", + "lifepoints": "111", + "magic_animation": "4666", + "magic_level": "1", + "melee_animation": "4666", + "range_animation": "4666", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "slayer_exp": "111", + "strength_level": "65", + "weakness": "1" + }, + { + "id": "7005", + "name": "Big wolf", + "examine": "Must be the pack leader.", + "aggressive": "true", + "attack_level": "60", + "death_animation": "6558", + "defence_animation": "0", + "defence_level": "62", + "lifepoints": "21", + "magic_animation": "0", + "melee_animation": "6559", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "74", + "strength_level": "60" + }, + { + "id": "7006", + "name": "Grenwall" + }, + { + "id": "7010", + "name": "Grenwall", + "examine": "An active spiny creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7011", + "name": "Grenwall", + "examine": "A hiding spiny creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7012", + "name": "Pawya", + "examine": "What a strange little creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7013", + "name": "Earth Mound", + "examine": "Dug by a Pawya (Not actual exam).", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7014", + "name": "Pawya", + "examine": "What a strange little creature.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7015", + "name": "Platypus" + }, + { + "id": "7016", + "name": "Platypus" + }, + { + "id": "7017", + "name": "Platypus" + }, + { + "id": "7018", + "name": "Baby platypus" + }, + { + "id": "7019", + "name": "Baby platypus" + }, + { + "id": "7020", + "name": "Baby platypus" + }, + { + "id": "7021", + "name": "Platypus", + "examine": "A most unlikely creature.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7022", + "name": "Platypus" + }, + { + "id": "7023", + "name": "Platypus" + }, + { + "id": "7024", + "name": "Baby platypus", + "examine": "A most unlikely creature.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7025", + "name": "Baby platypus" + }, + { + "id": "7026", + "name": "Baby platypus" + }, + { + "id": "7027", + "name": "Patrick" + }, + { + "id": "7028", + "name": "Penelope" + }, + { + "id": "7029", + "name": "Peter" + }, + { + "id": "7030", + "name": "Peanut" + }, + { + "id": "7031", + "name": "Wimpy bird", + "examine": "An ogre snack with wings.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7032", + "name": "Diseased kebbit" + }, + { + "id": "7039", + "name": "Diseased kebbit", + "examine": "A shy creature with a toxic bite.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7040", + "name": "Fishing spot" + }, + { + "id": "7045", + "name": "Fishing spot" + }, + { + "id": "7046", + "name": "Fishing spot" + }, + { + "id": "7047", + "name": "Balnea", + "examine": "She looks like she means business." + }, + { + "id": "7048", + "name": "Frawd" + }, + { + "id": "7049", + "name": "Ogress banker", + "examine": "Fit to wear the uniform?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7050", + "name": "Ogress banker" + }, + { + "id": "7051", + "name": "Chief Tess", + "examine": "She walks as if she owns the place.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7052", + "name": "Seegud" + }, + { + "id": "7053", + "name": "Chargurr" + }, + { + "id": "7054", + "name": "Chargurr" + }, + { + "id": "7055", + "name": "Snurgh" + }, + { + "id": "7058", + "name": "Kringk" + }, + { + "id": "7059", + "name": "Thump" + }, + { + "id": "7060", + "name": "Massage table" + }, + { + "id": "7061", + "name": "Thump" + }, + { + "id": "7062", + "name": "Muggh" + }, + { + "id": "7063", + "name": "Kringk" + }, + { + "id": "7064", + "name": "Hairdryer" + }, + { + "id": "7065", + "name": "Snert" + }, + { + "id": "7068", + "name": "Tyke" + }, + { + "id": "7069", + "name": "Snarrl" + }, + { + "id": "7070", + "name": "Snarrk" + }, + { + "id": "7071", + "name": "I'rk" + }, + { + "id": "7072", + "name": "Thuddley" + }, + { + "id": "7073", + "name": "Grr'bah" + }, + { + "id": "7074", + "name": "Chomp" + }, + { + "id": "7075", + "name": "Grubb" + }, + { + "id": "7076", + "name": "Grunther" + }, + { + "id": "7077", + "name": "Glum" + }, + { + "id": "7078", + "name": "Ogress champion", + "examine": "A fearsome adversary with no sense of humour.", + "aggressive": "true", + "attack_level": "48", + "death_animation": "8640", + "defence_animation": "0", + "defence_level": "48", + "lifepoints": "68", + "magic_animation": "0", + "melee_animation": "8636", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "48", + "weakness": "6" + }, + { + "id": "7079", + "name": "Ogress warrior", + "examine": "Irascible, belligerent and stupefyingly impolite.", + "aggressive": "true", + "attack_level": "45", + "death_animation": "8640", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "8636", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "45", + "weakness": "6" + }, + { + "id": "7080", + "name": "Ogress warrior", + "examine": "Irascible, beliggerent and stupefyingly impolite.", + "aggressive": "true", + "attack_level": "45", + "death_animation": "8641", + "defence_animation": "0", + "defence_level": "45", + "lifepoints": "64", + "magic_animation": "0", + "melee_animation": "8637", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "45", + "weakness": "6" + }, + { + "id": "7081", + "name": "Ogress", + "examine": "A large and contentious lady ogre.", + "aggressive": "true", + "attack_level": "42", + "attack_speed": "5", + "death_animation": "8640", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "8636", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "42", + "weakness": "6" + }, + { + "id": "7082", + "name": "Ogress", + "examine": "A large and contentious lady ogre.", + "aggressive": "true", + "attack_level": "42", + "attack_speed": "5", + "death_animation": "8641", + "defence_animation": "0", + "defence_level": "42", + "lifepoints": "60", + "magic_animation": "0", + "melee_animation": "8637", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "42", + "weakness": "6" + }, + { + "id": "7083", + "name": "Flying bugs" + }, + { + "id": "7084", + "name": "Eucalyptus ent", + "examine": "Dead stone defending a dead throne room.", + "aggressive": "true", + "attack_level": "51", + "attack_speed": "5", + "defence_animation": "0", + "defence_level": "51", + "lifepoints": "145", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "51", + "weakness": "7" + }, + { + "id": "7085", + "name": "Eucalyptus ent", + "examine": "Dead stone defending a dead throne room.", + "aggressive": "true", + "attack_level": "54", + "attack_speed": "5", + "defence_animation": "0", + "defence_level": "54", + "lifepoints": "142", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "54", + "weakness": "7" + }, + { + "id": "7086", + "name": "Eucalyptus ent", + "examine": "Dead stone defending a dead throne room.", + "aggressive": "true", + "attack_level": "57", + "defence_animation": "0", + "defence_level": "57", + "lifepoints": "162", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "57", + "weakness": "7" + }, + { + "id": "7087", + "name": "Balnea" + }, + { + "id": "7088", + "name": "Chief Tess" + }, + { + "id": "7089", + "name": "Chargurr" + }, + { + "id": "7090", + "name": "Wise Old Man" + }, + { + "id": "7091", + "name": "Dawg" + }, + { + "id": "7105", + "name": "Chaos druid", + "examine": "A crazy, evil druid.", + "aggressive": "true", + "attack_level": "8", + "attack_speed": "4", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "12", + "end_gfx": "107", + "lifepoints": "20", + "magic_animation": "422", + "magic_level": "10", + "melee_animation": "422", + "projectile": "106", + "range_animation": "422", + "range_level": "1", + "respawn_delay": "25", + "safespot": null, + "start_gfx": "105", + "strength_level": "8", + "weakness": "3" + }, + { + "id": "7106", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7107", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7108", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7109", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7110", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7111", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7112", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7113", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7114", + "name": "Thug", + "examine": "Low on brains, high on aggression.", + "aggressive": "true", + "attack_level": "7", + "attack_speed": "4", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "death_animation": "9055", + "defence_animation": "404", + "defence_level": "9", + "lifepoints": "18", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "5" + }, + { + "id": "7115", + "name": "Thaki the delivery dwarf", + "examine": "He seems to be enjoying his time in the bar.", + "attack_level": "1", + "bonuses": "5,5,0,0,0,0,2,3,3,0,0,0,0,0,0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "magic_level": "1", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7116", + "name": "Drunken sailor" + }, + { + "id": "7117", + "name": "Drunken sailor" + }, + { + "id": "7118", + "name": "Catapult engineer" + }, + { + "id": "7119", + "name": "Tyras guard" + }, + { + "id": "7120", + "name": "Tyras guard", + "examine": "One of King Tyras's men.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7121", + "name": "General Hining" + }, + { + "id": "7122", + "name": "Githan" + }, + { + "id": "7123", + "name": "Amulet of Nature" + }, + { + "id": "7124", + "name": "Mud" + }, + { + "id": "7125", + "name": "Rabbit", + "examine": "A hungry-looking rabbit.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7126", + "name": "Rabbit", + "examine": "A hungry-looking rabbit.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7127", + "name": "Rabbit", + "examine": "A hungry-looking rabbit.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "50", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7128", + "name": "Farmer", + "examine": "A gnome farmer.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7129", + "name": "Farmer", + "examine": "A gnome farmer.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7130", + "name": "Farmer", + "examine": "A gnome farmer.", + "aggressive": "true", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7131", + "name": "Farmer Blinkin", + "examine": "The head farmer, apparently." + }, + { + "id": "7132", + "name": "Mrs. Winkin", + "examine": "Owner of this homestead.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7133", + "name": "Bork", + "examine": "That's one big Ork... ", + "agg_radius": "64", + "attack_level": "100", + "attack_speed": "6", + "bonuses": "200,120,100,300,300,120,400,500,300,200,300,400,200,90,0", + "death_animation": "8756", + "defence_animation": "8755", + "defence_level": "80", + "lifepoints": "300", + "melee_animation": "8754", + "poison_immune": "true", + "range_level": "1", + "respawn_delay": "60", + "strength_level": "90" + }, + { + "id": "7134", + "name": "Bork", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "8", + "death_animation": "8756", + "defence_animation": "8755", + "defence_level": "1", + "lifepoints": "300", + "melee_animation": "8754", + "poison_immune": "true", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7135", + "name": "Ork legion", + "examine": "Aww, aren't they the cutest li - Argh!", + "aggressive": "true", + "attack_level": "68", + "bonuses": "5,10,3,5,3,5,5,5,10,0,0,0,0,0,0", + "death_animation": "8761", + "defence_animation": "0", + "defence_level": "57", + "lifepoints": "100", + "magic_animation": "0", + "melee_animation": "8760", + "poison_immune": "true", + "range_animation": "0", + "range_level": "68", + "respawn_delay": "60", + "safespot": null, + "strength_level": "68" + }, + { + "id": "7136", + "name": "Surok Magis" + }, + { + "id": "7137", + "name": "Dagon'hai Elite", + "examine": "A powerful wizard.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "25", + "bonuses": "220,190,140,120,120,130,90,120,120,200,100,154,150,93,190", + "combat_style": "2", + "defence_level": "40", + "lifepoints": "70", + "magic_level": "90", + "range_level": "1", + "safespot": null, + "spell_id": "11", + "strength_level": "90" + }, + { + "id": "7138", + "name": "Dagon'hai Monk", + "examine": "A monk of the Dagon'hai.", + "aggressive": "true", + "attack_level": "84", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "80", + "lifepoints": "88", + "magic_animation": "0", + "magic_level": "98", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "84" + }, + { + "id": "7139", + "name": "Dagon'hai Monk", + "examine": "A monk of the Dagon'hai.", + "aggressive": "true", + "attack_level": "84", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "80", + "lifepoints": "88", + "magic_animation": "0", + "magic_level": "98", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "84" + }, + { + "id": "7140", + "name": "Dagon'hai Monk", + "examine": "A monk of the Dagon'hai.", + "aggressive": "true", + "attack_level": "84", + "attack_speed": "5", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "80", + "lifepoints": "88", + "magic_animation": "0", + "magic_level": "98", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "84" + }, + { + "id": "7141", + "name": "null", + "examine": "He seems to have gone mad.", + "aggressive": "true", + "attack_level": "25", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "4", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "426", + "range_animation": "426", + "range_level": "25", + "safespot": null, + "strength_level": "25", + "weakness": "1" + }, + { + "id": "7142", + "name": "Guard", + "examine": "He thumps people who cheat.", + "attack_level": "1", + "clue_level": "1", + "combat_audio": "511,513,512", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7143", + "name": "Professor Henry" + }, + { + "id": "7144", + "name": "Gublinch jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7145", + "name": "Gublinchette jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7146", + "name": "Gublinchette jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7147", + "name": "Gublinch jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7148", + "name": "Gublinch jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7149", + "name": "Gublinch jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7150", + "name": "Gublinch jailmate", + "examine": "An imprisoned gublinch.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7151", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "7152", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7153", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "7154", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "7155", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "7156", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7157", + "name": "Student", + "examine": "A person sitting an exam.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "strength_level": "1" + }, + { + "id": "7158", + "name": "Cockroach drone", + "examine": "A household pest.", + "attack_level": "3", + "attack_speed": "5", + "death_animation": "8788", + "defence_animation": "0", + "defence_level": "3", + "lifepoints": "4", + "magic_animation": "0", + "melee_animation": "8785", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "3", + "weakness": "8" + }, + { + "id": "7159", + "name": "Cockroach worker", + "examine": "Eurgh! A big bug.", + "attack_level": "22", + "attack_speed": "5", + "death_animation": "8790", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "31", + "magic_animation": "0", + "melee_animation": "8787", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "22", + "weakness": "8" + }, + { + "id": "7160", + "name": "Cockroach soldier", + "examine": "Euww! A giant bug.", + "attack_level": "38", + "attack_speed": "5", + "bonuses": "10,10,10,5,0,0,0,0,0,0,0,0,0,0,0", + "death_animation": "8789", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "97", + "magic_animation": "0", + "melee_animation": "8786", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "26", + "weakness": "8" + }, + { + "id": "7161", + "name": "Mugger", + "aggressive": "true", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "8", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7162", + "name": "Mugger", + "aggressive": "true", + "attack_level": "1", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "8", + "melee_animation": "422", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7163", + "name": "Villager" + }, + { + "id": "7165", + "name": "Villager" + }, + { + "id": "7166", + "name": "Villager" + }, + { + "id": "7167", + "name": "Villager" + }, + { + "id": "7168", + "name": "Kimberly", + "examine": "A little girl. She looks terrified.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7169", + "name": "Kimberly" + }, + { + "id": "7170", + "name": "Kimberly" + }, + { + "id": "7171", + "name": "Kennith" + }, + { + "id": "7172", + "name": "Kennith" + }, + { + "id": "7173", + "name": "Kennith" + }, + { + "id": "7174", + "name": "Kennith" + }, + { + "id": "7175", + "name": "Kennith" + }, + { + "id": "7176", + "name": "Villager" + }, + { + "id": "7184", + "name": "Ezekial Lovecraft" + }, + { + "id": "7185", + "name": "Clive" + }, + { + "id": "7186", + "name": "Katherine" + }, + { + "id": "7187", + "name": "Katherine" + }, + { + "id": "7188", + "name": "Clive" + }, + { + "id": "7189", + "name": "Kent" + }, + { + "id": "7190", + "name": "Rabbit hole" + }, + { + "id": "7197", + "name": "Easter Bunny" + }, + { + "id": "7198", + "name": "Bunny" + }, + { + "id": "7199", + "name": "Bunny" + }, + { + "id": "7200", + "name": "Guard bunny" + }, + { + "id": "7201", + "name": "Chocatrice" + }, + { + "id": "7202", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "4933", + "melee_animation": "4933", + "range_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7203", + "name": "Void Knight" + }, + { + "id": "7204", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "4933", + "melee_animation": "4933", + "range_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7205", + "name": "Mouse" + }, + { + "id": "7206", + "name": "Cockroach", + "examine": "It seems to have eaten a lot of chocolate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7207", + "name": "Spider", + "examine": "It's searching for crumbs of chocolate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7208", + "name": "Rabbit" + }, + { + "id": "7209", + "name": "Snail", + "examine": "It seems to have eaten a lot of chocolate.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7210", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7211", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7212", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7213", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7214", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7215", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7216", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7217", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7218", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7219", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7220", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7221", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7222", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7223", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7224", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7225", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7226", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7227", + "name": "Monkey", + "examine": "Hide the bananas!", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7228", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7229", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7230", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7231", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7232", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7233", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7234", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7235", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7236", + "name": "Baby monkey", + "examine": "It's a tiny, cheeky monkey.", + "attack_level": "1", + "combat_audio": "629,631,630", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7237", + "name": "Terrier puppy", + "examine": "A hyperactive little pup." + }, + { + "id": "7238", + "name": "Terrier", + "examine": "A hyperactive little pup." + }, + { + "id": "7239", + "name": "Terrier puppy", + "examine": "Such a brave doggy." + }, + { + "id": "7240", + "name": "Terrier", + "examine": "Such a brave doggy." + }, + { + "id": "7241", + "name": "Greyhound puppy", + "examine": "This is one fast little pooch." + }, + { + "id": "7242", + "name": "Greyhound", + "examine": "An aerodynamic doggy." + }, + { + "id": "7243", + "name": "Greyhound puppy", + "examine": "This is one fast little pooch." + }, + { + "id": "7244", + "name": "Greyhound", + "examine": "An aerodynamic doggy." + }, + { + "id": "7245", + "name": "Labrador puppy", + "examine": "Soft but strong... and cute." + }, + { + "id": "7246", + "name": "Labrador", + "examine": "My most faithful friend." + }, + { + "id": "7247", + "name": "Labrador puppy", + "examine": "Soft but strong... and cute." + }, + { + "id": "7248", + "name": "Labrador", + "examine": "My most faithful friend." + }, + { + "id": "7249", + "name": "Dalmatian puppy", + "examine": "Now, if only I could find another hundred..." + }, + { + "id": "7250", + "name": "Dalmatian", + "examine": "A purebred doggy." + }, + { + "id": "7251", + "name": "Dalmatian puppy", + "examine": "Now, if only I could find another hundred..." + }, + { + "id": "7252", + "name": "Dalmatian", + "examine": "A purebred doggy." + }, + { + "id": "7253", + "name": "Sheepdog puppy", + "examine": "This little puppy is very quiet." + }, + { + "id": "7254", + "name": "Sheepdog", + "examine": "Come by! Come by!" + }, + { + "id": "7255", + "name": "Sheepdog puppy", + "examine": "This little puppy is very quiet." + }, + { + "id": "7256", + "name": "Sheepdog", + "examine": "Come by! Come by!" + }, + { + "id": "7257", + "name": "Bulldog", + "examine": "Looks like it's chewing a wasp." + }, + { + "id": "7258", + "name": "Bulldog", + "examine": "Looks like it's chewing a wasp." + }, + { + "id": "7259", + "name": "Bulldog puppy", + "examine": "One proud little puppy." + }, + { + "id": "7260", + "name": "Bulldog puppy", + "examine": "One proud little puppy." + }, + { + "id": "7261", + "name": "Raven chick" + }, + { + "id": "7262", + "name": "Raven" + }, + { + "id": "7263", + "name": "Raven chick" + }, + { + "id": "7264", + "name": "Raven" + }, + { + "id": "7265", + "name": "Raven chick" + }, + { + "id": "7266", + "name": "Raven" + }, + { + "id": "7267", + "name": "Raven chick" + }, + { + "id": "7268", + "name": "Raven" + }, + { + "id": "7269", + "name": "Raven chick" + }, + { + "id": "7270", + "name": "Raven" + }, + { + "id": "7271", + "name": "Baby raccoon", + "examine": "A stripy little baby raccoon." + }, + { + "id": "7272", + "name": "Raccoon", + "examine": "He can run with us." + }, + { + "id": "7273", + "name": "Baby raccoon", + "examine": "A stripy little baby raccoon." + }, + { + "id": "7274", + "name": "Raccoon", + "examine": "He can run with us." + }, + { + "id": "7275", + "name": "Baby Raccoon", + "examine": "A stripy little baby raccoon.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7276", + "name": "Baby raccoon", + "examine": "A stripy little baby raccoon." + }, + { + "id": "7277", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7278", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7279", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7280", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7281", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7282", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7283", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7284", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7285", + "name": "Baby gecko", + "examine": "It's so adorably tiny!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7286", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7287", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7288", + "name": "Baby gecko", + "examine": "It's so adorably tiny!" + }, + { + "id": "7289", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7290", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7291", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7292", + "name": "Gecko", + "examine": "How cute!" + }, + { + "id": "7293", + "name": "Baby giant crab" + }, + { + "id": "7294", + "name": "Giant crab" + }, + { + "id": "7295", + "name": "Baby giant crab" + }, + { + "id": "7296", + "name": "Giant crab" + }, + { + "id": "7297", + "name": "Baby giant crab" + }, + { + "id": "7298", + "name": "Giant crab" + }, + { + "id": "7299", + "name": "Baby giant crab" + }, + { + "id": "7300", + "name": "Giant crab" + }, + { + "id": "7301", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7302", + "name": "Squirrel", + "examine": "An experienced nut-thief." + }, + { + "id": "7303", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7304", + "name": "Squirrel", + "examine": "An experienced nut-thief." + }, + { + "id": "7305", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7306", + "name": "Squirrel", + "examine": "An experienced nut-thief." + }, + { + "id": "7307", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7308", + "name": "Squirrel", + "examine": "An experienced nut-thief." + }, + { + "id": "7309", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7310", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7311", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7312", + "name": "Baby squirrel", + "examine": "A tiny nut-thief." + }, + { + "id": "7313", + "name": "Baby penguin" + }, + { + "id": "7314", + "name": "Penguin" + }, + { + "id": "7315", + "name": "Penguin" + }, + { + "id": "7316", + "name": "Baby penguin" + }, + { + "id": "7317", + "name": "Penguin" + }, + { + "id": "7318", + "name": "Penguin" + }, + { + "id": "7319", + "name": "Vulture chick" + }, + { + "id": "7320", + "name": "Vulture" + }, + { + "id": "7321", + "name": "Vulture chick" + }, + { + "id": "7322", + "name": "Vulture" + }, + { + "id": "7323", + "name": "Vulture chick" + }, + { + "id": "7324", + "name": "Vulture" + }, + { + "id": "7325", + "name": "Vulture chick" + }, + { + "id": "7326", + "name": "Vulture" + }, + { + "id": "7327", + "name": "Vulture chick" + }, + { + "id": "7328", + "name": "Vulture" + }, + { + "id": "7329", + "name": "Swamp titan", + "attack_level": "1", + "bonuses": "60,60,60,60,50,50,100,200,200,28,100,100,70,70,70", + "combat_style": "0", + "death_animation": "8226", + "defence_animation": "8224", + "defence_level": "78", + "lifepoints": "556", + "magic_level": "70", + "melee_animation": "8222", + "range_level": "70", + "respawn_delay": "0", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7330", + "name": "Swamp titan", + "examine": "Do you hear duelling banjos?", + "attack_level": "60", + "bonuses": "60,60,60,60,50,50,100,200,200,28,100,100,70,70,70", + "combat_style": "0", + "death_animation": "8226", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "117", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "8222", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7331", + "name": "Spirit mosquito", + "examine": "It buzzes and bites. Nasty.", + "attack_level": "28", + "bonuses": "45,49,42,39,47,46,29,43,51,16,53,10,0,0,0", + "death_animation": "8033", + "defence_animation": "8034", + "defence_level": "25", + "lifepoints": "43", + "magic_animation": "8032", + "magic_level": "21", + "melee_animation": "8032", + "poison_immune": "true", + "range_animation": "8032", + "range_level": "25", + "respawn_delay": "50", + "safespot": null, + "strength_level": "24" + }, + { + "id": "7332", + "name": "Spirit mosquito", + "examine": "It buzzes and bites. Nasty.", + "attack_level": "28", + "bonuses": "45,49,42,39,47,46,29,43,51,16,53,10,0,0,0", + "death_animation": "8033", + "defence_animation": "8034", + "defence_level": "25", + "lifepoints": "43", + "magic_animation": "8032", + "magic_level": "21", + "melee_animation": "8032", + "poison_immune": "true", + "range_animation": "8032", + "range_level": "25", + "respawn_delay": "50", + "safespot": null, + "strength_level": "24", + "weakness": "10" + }, + { + "id": "7333", + "name": "Void spinner", + "examine": "It spins.", + "attack_level": "34", + "death_animation": "8176", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8172", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7334", + "name": "Void spinner", + "examine": "It spins.", + "attack_level": "34", + "death_animation": "8176", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8172", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7335", + "name": "Forge regent", + "examine": "This one will burn right through the net!", + "attack_level": "60", + "combat_style": "1", + "death_animation": "7864", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "108", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "7863", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7336", + "name": "Forge regent", + "examine": "This one will burn right through the net!", + "attack_level": "60", + "combat_style": "1", + "death_animation": "7864", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "108", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "7863", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7337", + "name": "Spirit larupia", + "examine": "Fast cat is fast.", + "attack_level": "50", + "death_animation": "5230", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "5228", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "7338", + "name": "Spirit larupia", + "examine": "Fast cat is fast.", + "attack_level": "50", + "death_animation": "5230", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "5228", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "strength_level": "50", + "weakness": "10" + }, + { + "id": "7339", + "name": "Geyser titan", + "examine": "It'll kill your enemies, and makes a great cup of tea.", + "attack_level": "70", + "bonuses": "115,115,115,110,110,102,95,110,110,105,78,120,115,120,120", + "combat_style": "1", + "death_animation": "7880", + "defence_animation": "7878", + "defence_level": "70", + "lifepoints": "620", + "magic_animation": "422", + "magic_level": "70", + "melee_animation": "7879", + "poison_immune": "true", + "range_animation": "422", + "range_level": "70", + "respawn_delay": "50", + "safespot": null, + "strength_level": "70", + "weakness": "0" + }, + { + "id": "7340", + "name": "Geyser titan", + "examine": "It'll kill your enemies, and makes a great cup of tea.", + "attack_level": "70", + "bonuses": "115,115,115,110,110,102,95,110,110,105,78,120,115,120,120", + "combat_style": "1", + "death_animation": "7880", + "defence_animation": "7878", + "defence_level": "70", + "lifepoints": "620", + "magic_animation": "422", + "magic_level": "70", + "melee_animation": "7879", + "poison_immune": "true", + "range_animation": "422", + "range_level": "70", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "70", + "weakness": "0" + }, + { + "id": "7341", + "name": "Lava titan", + "examine": "Made of lava.", + "attack_level": "65", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "combat_style": "0", + "death_animation": "7979", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "115", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7980", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "7342", + "name": "Lava titan", + "examine": "Made of lava.", + "attack_level": "65", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "combat_style": "0", + "death_animation": "7979", + "defence_animation": "0", + "defence_level": "65", + "lifepoints": "115", + "magic_animation": "0", + "magic_level": "65", + "melee_animation": "7980", + "range_animation": "0", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "7343", + "name": "Steel titan", + "examine": "The King of the Titans!", + "attack_level": "70", + "bonuses": "105,105,105,100,110,102,95,110,110,105,78,120,115,120,120", + "combat_style": "1", + "death_animation": "8184", + "defence_animation": "8185", + "defence_level": "70", + "lifepoints": "750", + "magic_animation": "8183", + "magic_level": "70", + "melee_animation": "8183", + "poison_immune": "true", + "range_animation": "8183", + "range_level": "70", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "0", + "strength_level": "70", + "weakness": "10" + }, + { + "id": "7344", + "name": "Steel titan", + "examine": "The King of the Titans!", + "attack_level": "70", + "bonuses": "105,105,105,100,110,102,95,110,110,105,78,120,115,120,120", + "combat_style": "1", + "death_animation": "8184", + "defence_animation": "8185", + "defence_level": "70", + "lifepoints": "750", + "magic_animation": "8183", + "magic_level": "70", + "melee_animation": "8183", + "poison_immune": "true", + "range_animation": "8183", + "range_level": "70", + "respawn_delay": "15", + "safespot": null, + "slayer_exp": "0", + "strength_level": "70", + "weakness": "10" + }, + { + "id": "7345", + "name": "Obsidian golem", + "examine": "Four fists can make quite an impression IN someone...", + "attack_level": "60", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "death_animation": "8052", + "defence_animation": "8051", + "defence_level": "60", + "lifepoints": "10", + "magic_level": "60", + "melee_animation": "8050", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60" + }, + { + "id": "7346", + "name": "Obsidian golem", + "examine": "Four fists can make quite an impression IN someone...", + "attack_level": "60", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "death_animation": "8052", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "104", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "8050", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7347", + "name": "Talon beast", + "examine": "If a normal black cat is bad luck", + "attack_level": "60", + "death_animation": "5990", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "110", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "5989", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7348", + "name": "Talon beast", + "examine": "If a normal black cat is bad luck", + "attack_level": "60", + "death_animation": "5990", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "110", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "5989", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7349", + "name": "Abyssal titan", + "examine": "Big", + "attack_level": "70", + "death_animation": "7692", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "125", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7693", + "range_animation": "0", + "range_level": "70", + "respawn_delay": "0", + "safespot": null, + "strength_level": "70", + "weakness": "10" + }, + { + "id": "7350", + "name": "Abyssal titan", + "examine": "Big", + "attack_level": "70", + "death_animation": "7692", + "defence_animation": "0", + "defence_level": "70", + "lifepoints": "125", + "magic_animation": "0", + "magic_level": "70", + "melee_animation": "7693", + "range_animation": "0", + "range_level": "70", + "respawn_delay": "0", + "safespot": null, + "strength_level": "70", + "weakness": "10" + }, + { + "id": "7351", + "name": "Void torcher", + "examine": "It torches.", + "attack_level": "34", + "combat_style": "2", + "death_animation": "8236", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8235", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7352", + "name": "Void torcher", + "examine": "It torches.", + "attack_level": "34", + "combat_style": "2", + "death_animation": "8236", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8235", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7353", + "name": "Giant chinchompa", + "examine": "Looks a little...volatile.", + "attack_level": "29", + "combat_style": "1", + "death_animation": "7758", + "defence_animation": "0", + "defence_level": "29", + "lifepoints": "41", + "magic_animation": "0", + "magic_level": "29", + "melee_animation": "7755", + "range_animation": "0", + "range_level": "29", + "respawn_delay": "0", + "safespot": null, + "strength_level": "29", + "weakness": "10" + }, + { + "id": "7354", + "name": "Giant chinchompa", + "examine": "Looks a little...volatile.", + "attack_level": "29", + "combat_style": "1", + "death_animation": "7758", + "defence_animation": "0", + "defence_level": "29", + "lifepoints": "41", + "magic_animation": "0", + "magic_level": "29", + "melee_animation": "7755", + "range_animation": "0", + "range_level": "29", + "respawn_delay": "0", + "safespot": null, + "strength_level": "29", + "weakness": "10" + }, + { + "id": "7355", + "name": "Fire titan", + "examine": "Scorching!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "combat_style": "2", + "death_animation": "7833", + "defence_animation": "7832", + "defence_level": "40", + "lifepoints": "476", + "magic_animation": "7834", + "magic_level": "40", + "melee_animation": "7834", + "poison_immune": "true", + "range_animation": "7834", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7356", + "name": "Fire titan", + "examine": "Scorching!", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "64,45,76,82,208,84,221,231,179,89,113,23,0,0,0", + "combat_style": "2", + "death_animation": "7833", + "defence_animation": "7832", + "defence_level": "40", + "lifepoints": "476", + "magic_animation": "7834", + "magic_level": "40", + "melee_animation": "7834", + "poison_immune": "true", + "range_animation": "7834", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7357", + "name": "Moss titan", + "examine": "Gathers rolling stones to bash people with.", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "death_animation": "7843", + "defence_animation": "7832", + "defence_level": "40", + "lifepoints": "476", + "magic_animation": "7834", + "magic_level": "40", + "melee_animation": "7844", + "poison_immune": "true", + "range_animation": "7834", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7358", + "name": "Moss titan", + "examine": "Gathers rolling stones to bash people with.", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "death_animation": "7843", + "defence_animation": "7832", + "defence_level": "40", + "lifepoints": "476", + "magic_animation": "7834", + "magic_level": "40", + "melee_animation": "7844", + "poison_immune": "true", + "range_animation": "7834", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7359", + "name": "Ice titan", + "examine": "Frosty the highly violent snowman.", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "death_animation": "7846", + "defence_animation": "7832", + "defence_level": "40", + "lifepoints": "476", + "magic_animation": "7834", + "magic_level": "40", + "melee_animation": "7845", + "poison_immune": "true", + "range_animation": "7834", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7360", + "name": "Ice titan", + "examine": "Frosty the highly violent snowman.", + "attack_level": "40", + "attack_speed": "5", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "death_animation": "7846", + "defence_animation": "7832", + "defence_level": "40", + "lifepoints": "476", + "magic_animation": "7834", + "magic_level": "40", + "melee_animation": "7845", + "poison_immune": "true", + "range_animation": "7834", + "range_level": "30", + "respawn_delay": "50", + "safespot": null, + "slayer_exp": "0", + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7361", + "name": "Spirit Tz-Kih", + "examine": "This bat burned down the belfry.", + "attack_level": "22", + "attack_speed": "3", + "combat_style": "2", + "death_animation": "8258", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "magic_level": "22", + "melee_animation": "8257", + "range_animation": "0", + "range_level": "22", + "respawn_delay": "0", + "safespot": null, + "strength_level": "22", + "weakness": "10" + }, + { + "id": "7362", + "name": "Spirit Tz-Kih", + "examine": "This bat burned down the belfry.", + "attack_level": "22", + "attack_speed": "3", + "combat_style": "2", + "death_animation": "8258", + "defence_animation": "0", + "defence_level": "22", + "lifepoints": "31", + "magic_animation": "0", + "magic_level": "22", + "melee_animation": "8257", + "range_animation": "0", + "range_level": "22", + "respawn_delay": "0", + "safespot": null, + "strength_level": "22", + "weakness": "10" + }, + { + "id": "7363", + "name": "Spirit graahk", + "examine": "Those spikes are pretty big!", + "attack_level": "50", + "death_animation": "5230", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "5229", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1367", + "strength_level": "50", + "weakness": "10" + }, + { + "id": "7364", + "name": "Spirit graahk", + "examine": "Those spikes are pretty big!", + "attack_level": "50", + "death_animation": "5230", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "5229", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1367", + "strength_level": "50", + "weakness": "10" + }, + { + "id": "7365", + "name": "Spirit kyatt", + "examine": "Those teeth are pretty big!", + "attack_level": "50", + "death_animation": "5230", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "5228", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1365", + "strength_level": "50", + "weakness": "10" + }, + { + "id": "7366", + "name": "Spirit kyatt", + "examine": "Those teeth are pretty big!", + "attack_level": "50", + "death_animation": "5230", + "defence_animation": "0", + "defence_level": "50", + "lifepoints": "81", + "magic_animation": "0", + "magic_level": "50", + "melee_animation": "5228", + "range_animation": "0", + "range_level": "50", + "respawn_delay": "0", + "safespot": null, + "start_gfx": "1365", + "strength_level": "50", + "weakness": "10" + }, + { + "id": "7367", + "name": "Void shifter", + "examine": "It shifts.", + "attack_level": "34", + "death_animation": "8133", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8131", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7368", + "name": "Void shifter", + "examine": "It shifts.", + "attack_level": "34", + "death_animation": "8133", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8131", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7369", + "name": "Void shifter" + }, + { + "id": "7370", + "name": "Void ravager", + "examine": "It ravages.", + "attack_level": "34", + "death_animation": "8087", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8086", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7371", + "name": "Void ravager", + "examine": "It ravages.", + "attack_level": "34", + "death_animation": "8087", + "defence_animation": "0", + "defence_level": "34", + "lifepoints": "48", + "magic_animation": "0", + "magic_level": "34", + "melee_animation": "8086", + "range_animation": "0", + "range_level": "34", + "safespot": null, + "strength_level": "34", + "weakness": "10" + }, + { + "id": "7372", + "name": "Ravenous locust" + }, + { + "id": "7373", + "name": "Ravenous locust", + "examine": "It's like a little stomach on wings.", + "attack_level": "60", + "death_animation": "7996", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "7994", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7374", + "name": "Ravenous locust", + "examine": "It's like a little stomach on wings.", + "attack_level": "60", + "death_animation": "7996", + "defence_animation": "0", + "defence_level": "60", + "lifepoints": "100", + "magic_animation": "0", + "magic_level": "60", + "melee_animation": "7994", + "range_animation": "0", + "range_level": "60", + "respawn_delay": "0", + "safespot": null, + "strength_level": "60", + "weakness": "10" + }, + { + "id": "7375", + "name": "Iron titan", + "examine": "He is an iron man!", + "attack_level": "65", + "bonuses": "120,130,100,109,80,120,102,90,103,80,100,108,105,66,90", + "combat_style": "0", + "death_animation": "7947", + "defence_animation": "7948", + "defence_level": "65", + "lifepoints": "694", + "magic_level": "65", + "melee_animation": "7946", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "strength_level": "65", + "weakness": "10" + }, + { + "id": "7376", + "name": "Iron titan", + "examine": "He is an iron man!", + "attack_level": "65", + "bonuses": "120,130,100,109,80,120,102,90,103,80,100,108,105,66,90", + "combat_audio": "0,0,0", + "combat_style": "0", + "death_animation": "7947", + "defence_animation": "7948", + "defence_level": "65", + "lifepoints": "694", + "magic_level": "65", + "melee_animation": "7946", + "range_level": "65", + "respawn_delay": "0", + "safespot": null, + "slayer_exp": "0", + "strength_level": "65", + "weakness": "10" + }, + { + "id": "7377", + "name": "Pyrelord", + "examine": "Where did I put the marshmallows?", + "attack_level": "46", + "death_animation": "8078", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "magic_level": "46", + "melee_animation": "8080", + "range_animation": "0", + "range_level": "46", + "safespot": null, + "strength_level": "46", + "weakness": "10" + }, + { + "id": "7378", + "name": "Pyrelord", + "examine": "Where did I put the marshmallows?", + "attack_level": "46", + "death_animation": "8078", + "defence_animation": "0", + "defence_level": "46", + "lifepoints": "65", + "magic_animation": "0", + "magic_level": "46", + "melee_animation": "8080", + "range_animation": "0", + "range_level": "46", + "safespot": null, + "strength_level": "46", + "weakness": "10" + }, + { + "id": "7379", + "name": "Elfinlocks", + "aggressive": "true", + "attack_level": "1", + "death_animation": "8967", + "defence_animation": "8966", + "defence_level": "1", + "lifepoints": "120", + "melee_animation": "8965", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7380", + "name": "Missi Sissi", + "aggressive": "true", + "attack_level": "1", + "death_animation": "8967", + "defence_animation": "8966", + "defence_level": "1", + "lifepoints": "120", + "melee_animation": "8965", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7381", + "name": "Missi Sissi", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "2", + "death_animation": "8956", + "defence_animation": "8957", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "8955", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7382", + "name": "Uberlass", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "combat_style": "2", + "death_animation": "8956", + "defence_animation": "8957", + "defence_level": "1", + "lifepoints": "75", + "melee_animation": "8955", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7383", + "name": "Uberlass" + }, + { + "id": "7384", + "name": "Uberlass" + }, + { + "id": "7385", + "name": "Uberlass" + }, + { + "id": "7386", + "name": "Uberlass" + }, + { + "id": "7387", + "name": "Sannytea" + }, + { + "id": "7388", + "name": "Sannytea" + }, + { + "id": "7389", + "name": "Irollsixes" + }, + { + "id": "7390", + "name": "Irollsixes" + }, + { + "id": "7391", + "name": "Foxyhunter" + }, + { + "id": "7392", + "name": "Foxyhunter" + }, + { + "id": "7393", + "name": "Foxyhunter" + }, + { + "id": "7394", + "name": "Gabriela" + }, + { + "id": "7395", + "name": "Teodor" + }, + { + "id": "7396", + "name": "Aurel" + }, + { + "id": "7397", + "name": "Cornelius" + }, + { + "id": "7398", + "name": "Elisabeta", + "examine": "The vengeful spirit of one who died within Daemonheim.", + "aggressive": "true", + "attack_level": "25", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "7", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "0", + "range_animation": "0", + "range_level": "25", + "safespot": null, + "strength_level": "25", + "weakness": "3" + }, + { + "id": "7399", + "name": "Sorin" + }, + { + "id": "7400", + "name": "Luscion" + }, + { + "id": "7401", + "name": "Sergiu" + }, + { + "id": "7402", + "name": "Radu" + }, + { + "id": "7403", + "name": "Grigore" + }, + { + "id": "7404", + "name": "Ileana" + }, + { + "id": "7405", + "name": "Valeria" + }, + { + "id": "7406", + "name": "Emilia" + }, + { + "id": "7407", + "name": "Florin" + }, + { + "id": "7408", + "name": "Catalina" + }, + { + "id": "7409", + "name": "Ivan" + }, + { + "id": "7410", + "name": "Victor" + }, + { + "id": "7411", + "name": "Helena" + }, + { + "id": "7412", + "name": "Mihail" + }, + { + "id": "7413", + "name": "Nicoleta" + }, + { + "id": "7414", + "name": "Vasile" + }, + { + "id": "7415", + "name": "Razvan" + }, + { + "id": "7416", + "name": "Luminata" + }, + { + "id": "7417", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "3102,3104,3103", + "death_animation": "2707", + "defence_animation": "2706", + "defence_level": "1", + "lifepoints": "2", + "magic_animation": "2705", + "melee_animation": "2705", + "range_animation": "2705", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7418", + "name": "Juvinate" + }, + { + "id": "7419", + "name": "Held vampyre juvinate" + }, + { + "id": "7420", + "name": "Hieronymus Avlafrim" + }, + { + "id": "7421", + "name": "Sasquine Huburns" + }, + { + "id": "7422", + "name": "Sasquine Huburns" + }, + { + "id": "7423", + "name": "Lollery" + }, + { + "id": "7424", + "name": "Wigglewoo" + }, + { + "id": "7425", + "name": "Wigglewoo", + "examine": "An impling manager: what a terrifying thought!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7426", + "name": "Orangeowns", + "examine": "This worker looks after the incubator.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7427", + "name": "Orangeowns" + }, + { + "id": "7428", + "name": "I like m0m" + }, + { + "id": "7429", + "name": "I like m0m" + }, + { + "id": "7430", + "name": "Qutiedoll" + }, + { + "id": "7431", + "name": "Goreu" + }, + { + "id": "7432", + "name": "Ysgawyn" + }, + { + "id": "7433", + "name": "Arvel" + }, + { + "id": "7434", + "name": "Mawrth" + }, + { + "id": "7435", + "name": "Kelyn" + }, + { + "id": "7436", + "name": "Eoin" + }, + { + "id": "7437", + "name": "Iona" + }, + { + "id": "7438", + "name": "Elf warrior", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7439", + "name": "Elf warrior", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7440", + "name": "Elf warrior", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7441", + "name": "Elf warrior", + "attack_level": "1", + "clue_level": "2", + "combat_audio": "425,427,426", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7442", + "name": "Arianwyn" + }, + { + "id": "7443", + "name": "Eudav", + "examine": "He holds up passers by.", + "aggressive": "true", + "attack_level": "8", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "8", + "lifepoints": "11", + "magic_animation": "0", + "melee_animation": "386", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "8", + "weakness": "7" + }, + { + "id": "7444", + "name": "Oronwen" + }, + { + "id": "7445", + "name": "Banker" + }, + { + "id": "7446", + "name": "Banker" + }, + { + "id": "7447", + "name": "Dalldav" + }, + { + "id": "7448", + "name": "Gethin" + }, + { + "id": "7449", + "name": "Amaethwr" + }, + { + "id": "7450", + "name": "Teclyn" + }, + { + "id": "7451", + "name": "Butterfly" + }, + { + "id": "7452", + "name": "Lapsang" + }, + { + "id": "7453", + "name": "Lapsang" + }, + { + "id": "7454", + "name": "Souchong" + }, + { + "id": "7455", + "name": "Souchong" + }, + { + "id": "7456", + "name": "Earlgrey" + }, + { + "id": "7457", + "name": "Earlgrey" + }, + { + "id": "7458", + "name": "Fairtrade" + }, + { + "id": "7459", + "name": "Fairtrade", + "attack_level": "1", + "attack_speed": "5", + "defence_level": "1", + "lifepoints": "75", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7460", + "name": "Teapotspout", + "attack_level": "1", + "attack_speed": "5", + "defence_level": "1", + "lifepoints": "75", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7461", + "name": "Rat", + "examine": "A popular dwarven delicacy.", + "attack_level": "1", + "attack_speed": "5", + "combat_audio": "703,705,704", + "death_animation": "4935", + "defence_animation": "4934", + "defence_level": "1", + "lifepoints": "5", + "magic_animation": "4933", + "melee_animation": "4933", + "range_animation": "4933", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7462", + "name": "Hotwater", + "examine": "It's bubbling, gross.", + "attack_level": "99", + "attack_speed": "5", + "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,45,20,0", + "death_animation": "9131", + "defence_animation": "9132", + "defence_level": "99", + "lifepoints": "120", + "magic_animation": "9130", + "melee_animation": "9130", + "range_animation": "9130", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "99" + }, + { + "id": "7463", + "name": "Hotwater", + "examine": "It's bubbling, gross.", + "attack_level": "99", + "attack_speed": "5", + "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,45,20,0", + "death_animation": "9131", + "defence_animation": "9132", + "defence_level": "99", + "lifepoints": "120", + "magic_animation": "9130", + "melee_animation": "9130", + "range_animation": "9130", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "99" + }, + { + "id": "7464", + "name": "Sliceoflemon" + }, + { + "id": "7465", + "name": "Sliceoflemon" + }, + { + "id": "7466", + "name": "Milknosugar" + }, + { + "id": "7467", + "name": "Milknosugar" + }, + { + "id": "7468", + "name": "Randomdood" + }, + { + "id": "7469", + "name": "Employedman" + }, + { + "id": "7470", + "name": "Heidiggle" + }, + { + "id": "7471", + "name": "Dodgy Penny" + }, + { + "id": "7472", + "name": "Shadydude98" + }, + { + "id": "7473", + "name": "Madam C" + }, + { + "id": "7474", + "name": "M0m Online" + }, + { + "id": "7475", + "name": "Lady Seenit", + "examine": "His usual sunny disposition is not in evidence.", + "attack_level": "30", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "magic_level": "30", + "range_animation": "0", + "range_level": "30", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "10" + }, + { + "id": "7476", + "name": "Berrybree", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "50", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7477", + "name": "Stuffstuffer", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "50", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7478", + "name": "Learking" + }, + { + "id": "7479", + "name": "Learking", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "60", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7480", + "name": "Rachael", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "70", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7481", + "name": "Cool Mom227", + "examine": "You clearly can't live on treasure alone.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7482", + "name": "Purepker895", + "examine": "A testament to the effect of greed.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7483", + "name": "Pkmaster0036", + "examine": "He wanted loot", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7484", + "name": "Cow1337killr", + "examine": "Eternally looking for that big payday.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7485", + "name": "Mathdude", + "examine": "No more tea-breaks for this one.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7486", + "name": "Mathdude", + "examine": "Even in death you can smell his feet.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7487", + "name": "1337sp34kr", + "examine": "An anatomist's dream.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7488", + "name": "1337sp34kr", + "examine": "A hand seems to be gripping his spine through his chest. Ouch.", + "attack_level": "30", + "death_animation": "5491", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7489", + "name": "Moglewee" + }, + { + "id": "7490", + "name": "Moglewee" + }, + { + "id": "7491", + "name": "Sarah Domin" + }, + { + "id": "7492", + "name": "Sarah Domin", + "examine": "A desert dweller taken to banditry.", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "9705", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7493", + "name": "Sarah Domin", + "examine": "Calls himself an archaeologist.", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "9715", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7494", + "name": "Sue Spammers", + "examine": "He hasn't found much of use", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "9705", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7495", + "name": "Killerwail", + "examine": "An amateur historian with added greed.", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "9715", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7496", + "name": "Wise Old Man", + "examine": "It all started with her love of genealogy.", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "melee_animation": "9705", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7497", + "name": "Sabre-toothed kyatt", + "examine": "A rocky horror.", + "attack_level": "27", + "defence_animation": "0", + "defence_level": "27", + "lifepoints": "38", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "27", + "weakness": "6" + }, + { + "id": "7498", + "name": "Snowy knight" + }, + { + "id": "7499", + "name": "Sapphire glacialis" + }, + { + "id": "7500", + "name": "Cerulean twitch", + "examine": "This dung beetle has mistaken you for its staple diet.", + "aggressive": "true", + "attack_level": "30", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7501", + "name": "Abone", + "examine": "It's looking unwell - probably something it ate.", + "aggressive": "true", + "attack_level": "30", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7502", + "name": "Mythmaster", + "examine": "Once a valuable contributor to the ecosystem.", + "aggressive": "true", + "attack_level": "30", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7503", + "name": "Donkey Wrong", + "examine": "This is what happens if you play with your food.", + "aggressive": "true", + "attack_level": "30", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "42", + "magic_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7504", + "name": "Creapantic", + "examine": "He likes a good fight", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7505", + "name": "Frondlike", + "examine": "He likes a good fight", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7506", + "name": "Happy Spud", + "examine": "His favourite must be winning.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7507", + "name": "Nobodyhere", + "examine": "Blood-thirsty and enthusiastic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7508", + "name": "Bluehairlass", + "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7509", + "name": "Evil Wibbler" + }, + { + "id": "7510", + "name": "Ilikekebabs", + "examine": "His favourite must be winning.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7511", + "name": "Trunka Lex", + "examine": "His favourite must be winning.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7512", + "name": "Val Razz", + "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7513", + "name": "Abstractclas", + "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7514", + "name": "Bigbluebox", + "examine": "Bloodthirsty and enthusiastic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7515", + "name": "Funorbrox", + "examine": "Bloodthirsty and enthusiastic.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7516", + "name": "Heresjohnny" + }, + { + "id": "7517", + "name": "Mogglewump" + }, + { + "id": "7518", + "name": "Morrisnorris", + "examine": "He's asleep.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7519", + "name": "Matt Blitzer", + "examine": "He's propping the bar up. Or is it the other way round?", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7520", + "name": "Ketchuppl0x", + "examine": "He demands to have some booze.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7521", + "name": "Renderorder" + }, + { + "id": "7522", + "name": "Boolean" + }, + { + "id": "7523", + "name": "Stress Diva" + }, + { + "id": "7524", + "name": "Treadsoftly" + }, + { + "id": "7525", + "name": "Helphelphelp" + }, + { + "id": "7526", + "name": "Doorbellpl0x" + }, + { + "id": "7527", + "name": "Fixmydoorup" + }, + { + "id": "7528", + "name": "Redheadmonky", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "836", + "defence_animation": "425", + "defence_level": "1", + "lifepoints": "22", + "melee_animation": "395", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7529", + "name": "Wallscaler" + }, + { + "id": "7530", + "name": "2scompany" + }, + { + "id": "7531", + "name": "2scompany" + }, + { + "id": "7532", + "name": "3sacrowd", + "examine": "It's an NPC.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "slayer_exp": "0", + "strength_level": "1" + }, + { + "id": "7533", + "name": "4sjustsilly" + }, + { + "id": "7534", + "name": "Roadblocked" + }, + { + "id": "7535", + "name": "Barricade" + }, + { + "id": "7536", + "name": "Barricade" + }, + { + "id": "7537", + "name": "Yoinker" + }, + { + "id": "7538", + "name": "Yoinker" + }, + { + "id": "7539", + "name": "Stopthief" + }, + { + "id": "7540", + "name": "Stopthief" + }, + { + "id": "7541", + "name": "Knickknack" + }, + { + "id": "7542", + "name": "Paddywhack" + }, + { + "id": "7543", + "name": "Giveadog" + }, + { + "id": "7544", + "name": "Spacebadgers" + }, + { + "id": "7545", + "name": "Freakypeaky" + }, + { + "id": "7546", + "name": "Rollinghome" + }, + { + "id": "7547", + "name": "Nullpointer" + }, + { + "id": "7548", + "name": "Badgerfreak" + }, + { + "id": "7549", + "name": "Windstrike32" + }, + { + "id": "7550", + "name": "Void Knight" + }, + { + "id": "7551", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "90", + "bonuses": "200,200,200,100,100,0,0,0,0,0,0,0,0,0,0", + "defence_level": "90", + "lifepoints": "250", + "magic_level": "70", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7552", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "200,200,200,200,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "90", + "lifepoints": "250", + "magic_level": "50", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7553", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "200,200,100,200,100,0,0,0,0,0,0,0,0,0,0", + "defence_level": "90", + "lifepoints": "250", + "magic_level": "90", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7554", + "name": "Portal", + "examine": "Not somewhere I want to go...", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,200,200,100,0,0,0,0,0,0,0,0,0,0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "90", + "lifepoints": "250", + "magic_animation": "0", + "magic_level": "90", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7555", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "250", + "magic_level": "30", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7556", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "defence_level": "30", + "lifepoints": "250", + "magic_level": "15", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7557", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "250", + "magic_animation": "0", + "magic_level": "30", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7558", + "name": "Portal", + "examine": "The Void Knight will soon weaken the shield.", + "attack_level": "1", + "attack_speed": "5", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "30", + "lifepoints": "250", + "magic_animation": "0", + "magic_level": "30", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "125", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7559", + "name": "Brawler", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "combat_audio": "323,326,325", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7560", + "name": "Lostme", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7561", + "name": "Chiercat", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7562", + "name": "Skydischarge", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7563", + "name": "Agplus", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7564", + "name": "Distantthin", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7565", + "name": "Allmarshes", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7566", + "name": "Explosive67", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7567", + "name": "Wraithboss" + }, + { + "id": "7568", + "name": "What Goudron" + }, + { + "id": "7569", + "name": "Alpha1beta", + "examine": "Looks after your Farming tools.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7570", + "name": "Solltalk", + "examine": "Enjoys locking up animals in small pens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7571", + "name": "Hm Val", + "examine": "Enjoys locking up animals in small pens.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7572", + "name": "Wizzydumped", + "examine": "He looks like the type of guy who would mind monkeys.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7573", + "name": "Oddskater", + "examine": "He looks like the type of guy who would mind monkeys.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7574", + "name": "Lvzyoda" + }, + { + "id": "7575", + "name": "Airstriker" + }, + { + "id": "7576", + "name": "Droepedoff" + }, + { + "id": "7577", + "name": "Plzpudding" + }, + { + "id": "7578", + "name": "Assassin10" + }, + { + "id": "7579", + "name": "Steallake" + }, + { + "id": "7580", + "name": "Poledragon", + "attack_level": "1", + "combat_audio": "408,410,409", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7581", + "name": "Deepkiwi" + }, + { + "id": "7582", + "name": "Al Truism", + "examine": "He likes inflicting pain.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7583", + "name": "Ohhhhdude", + "examine": "The Don of penguins.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7584", + "name": "Bigface Oz" + }, + { + "id": "7585", + "name": "Torcher", + "examine": "A penguin pushing paper", + "attack_level": "1", + "combat_audio": "845,848,846", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7586", + "name": "Torcher", + "examine": "A penguin pushing paper", + "attack_level": "1", + "combat_audio": "845,848,846", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7587", + "name": "Torcher" + }, + { + "id": "7588", + "name": "Torcher" + }, + { + "id": "7589", + "name": "Defiler" + }, + { + "id": "7590", + "name": "Defiler" + }, + { + "id": "7591", + "name": "Shifter" + }, + { + "id": "7592", + "name": "Shifter" + }, + { + "id": "7593", + "name": "Shifter", + "examine": "He's a little rough around the edges.", + "attack_level": "1", + "combat_audio": "766,768,767", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7594", + "name": "Shifter" + }, + { + "id": "7595", + "name": "Splatter" + }, + { + "id": "7596", + "name": "Splatter" + }, + { + "id": "7597", + "name": "Splatter" + }, + { + "id": "7598", + "name": "Spinner" + }, + { + "id": "7599", + "name": "Ravager" + }, + { + "id": "7600", + "name": "Fiara" + }, + { + "id": "7601", + "name": "Reggie" + }, + { + "id": "7602", + "name": "Getorix" + }, + { + "id": "7603", + "name": "Pontimer" + }, + { + "id": "7604", + "name": "Alran" + }, + { + "id": "7605", + "name": "Banker", + "examine": "He has unbelievable strength!", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7606", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7607", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7608", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7609", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7610", + "name": "Flying female vampire" + }, + { + "id": "7611", + "name": "Flying female vampire" + }, + { + "id": "7612", + "name": "Flying female vampire" + }, + { + "id": "7613", + "name": "Flying female vampire" + }, + { + "id": "7614", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7615", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7616", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7617", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7618", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7619", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7620", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7621", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7622", + "name": "Vyrewatch" + }, + { + "id": "7623", + "name": "Vyrewatch" + }, + { + "id": "7624", + "name": "Vyrewatch" + }, + { + "id": "7625", + "name": "Vyrewatch" + }, + { + "id": "7626", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7627", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7628", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7629", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7630", + "name": "Vyrewatch" + }, + { + "id": "7631", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7632", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7633", + "name": "Vyrewatch" + }, + { + "id": "7634", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7635", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7636", + "name": "Fishing spot" + }, + { + "id": "7637", + "name": "Skeletal hand" + }, + { + "id": "7640", + "name": "Skeletal hand", + "examine": "Ew it's still alive.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "5", + "bonuses": "15,15,15,15,15,15,15,15,15,15,15,15,15,15,15", + "death_animation": "9126", + "defence_animation": "9127", + "defence_level": "85", + "lifepoints": "90", + "magic_animation": "9125", + "melee_animation": "9125", + "range_animation": "9125", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "85", + "weakness": "9" + }, + { + "id": "7641", + "name": "Zombie hand", + "examine": "Ew it's still alive.", + "aggressive": "true", + "attack_level": "75", + "attack_speed": "5", + "bonuses": "15,15,15,15,15,15,15,15,15,15,15,15,15,15,15", + "death_animation": "9126", + "defence_animation": "9127", + "defence_level": "75", + "lifepoints": "90", + "magic_animation": "9125", + "melee_animation": "9125", + "range_animation": "9125", + "range_level": "1", + "respawn_delay": "20", + "safespot": null, + "strength_level": "75", + "weakness": "9" + }, + { + "id": "7642", + "name": "Mutated bloodveld", + "examine": "A bloodveld with a very mixed heritage.", + "aggressive": "true", + "attack_level": "56", + "attack_speed": "5", + "death_animation": "9131", + "defence_animation": "0", + "defence_level": "56", + "lifepoints": "112", + "magic_animation": "0", + "melee_animation": "9102", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "206", + "strength_level": "56", + "weakness": "9" + }, + { + "id": "7643", + "name": "Mutated bloodveld", + "examine": "A bloodveld with a very mixed heritage.", + "aggressive": "true", + "attack_level": "58", + "attack_speed": "5", + "death_animation": "9131", + "defence_animation": "0", + "defence_level": "58", + "lifepoints": "116", + "magic_animation": "0", + "melee_animation": "9102", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "slayer_exp": "206", + "strength_level": "58", + "weakness": "9" + }, + { + "id": "7644", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7645", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7646", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7647", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7648", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7649", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7650", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7651", + "name": "Zaromark Sliver", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "88", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7652", + "name": "Zaromark Sliver" + }, + { + "id": "7653", + "name": "Zaromark Sliver" + }, + { + "id": "7654", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7655", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7656", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7657", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7658", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7659", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7660", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7661", + "name": "Fistandantilus", + "aggressive": "true", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "65", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7662", + "name": "Fistandantilus" + }, + { + "id": "7663", + "name": "Fistandantilus" + }, + { + "id": "7664", + "name": "Mercenary Adventurer" + }, + { + "id": "7665", + "name": "Ivan Strom" + }, + { + "id": "7666", + "name": "Mysterious person" + }, + { + "id": "7667", + "name": "Mysterious person" + }, + { + "id": "7668", + "name": "Mysterious person" + }, + { + "id": "7669", + "name": "Mysterious person" + }, + { + "id": "7670", + "name": "Mysterious person" + }, + { + "id": "7671", + "name": "Mysterious person" + }, + { + "id": "7672", + "name": "Flaygian Screwte" + }, + { + "id": "7673", + "name": "Mekritus A'hara" + }, + { + "id": "7674", + "name": "Andiess Juip" + }, + { + "id": "7675", + "name": "Kael Forshaw" + }, + { + "id": "7676", + "name": "Andiess Juip" + }, + { + "id": "7677", + "name": "Kael Forshaw" + }, + { + "id": "7678", + "name": "Safalaan" + }, + { + "id": "7679", + "name": "Andiess Juip" + }, + { + "id": "7680", + "name": "Kael Forshaw" + }, + { + "id": "7681", + "name": "Safalaan" + }, + { + "id": "7682", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7683", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7684", + "name": "Vyrewatch" + }, + { + "id": "7685", + "name": "Vyrewatch" + }, + { + "id": "7686", + "name": "Safalaan" + }, + { + "id": "7687", + "name": "Spectral Vyrewatch" + }, + { + "id": "7688", + "name": "Drezel" + }, + { + "id": "7690", + "name": "Drezel", + "examine": "A holy man." + }, + { + "id": "7691", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7692", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7693", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7694", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7695", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7696", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7697", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7698", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7699", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7700", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7701", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7702", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7703", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "95", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7704", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "105", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7705", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "120", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7706", + "name": "Vyrewatch", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "defence_level": "1", + "lifepoints": "130", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7707", + "name": "Drezel", + "examine": "A holy man." + }, + { + "id": "7708", + "name": "Temple guardian" + }, + { + "id": "7711", + "name": "Temple guardian", + "examine": "Looks like a big ugly dog.", + "attack_level": "24", + "death_animation": "6564", + "defence_animation": "0", + "defence_level": "24", + "lifepoints": "34", + "magic_animation": "0", + "melee_animation": "6565", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "24", + "weakness": "9" + }, + { + "id": "7712", + "name": "Baby icefiend" + }, + { + "id": "7713", + "name": "Baby icefiend", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "8078", + "defence_animation": "8084", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "8080", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7714", + "name": "Icefiend", + "examine": "A small ice demon.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "531,533,532", + "death_animation": "8078", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "8080", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "7715", + "name": "Icefiend", + "examine": "The icefiend seems to be melting.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "clue_level": "0", + "combat_audio": "531,533,532", + "death_animation": "8078", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "8080", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "7716", + "name": "null", + "examine": "The icefiend seems to be melting.", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "8078", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "35", + "magic_animation": "0", + "magic_level": "25", + "melee_animation": "8080", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "5" + }, + { + "id": "7718", + "name": "Brother Bordiss" + }, + { + "id": "7719", + "name": "Brother Althric" + }, + { + "id": "7720", + "name": "Drorkar" + }, + { + "id": "7721", + "name": "Nurmof" + }, + { + "id": "7722", + "name": "Lakki the delivery dwarf" + }, + { + "id": "7723", + "name": "Drorkar" + }, + { + "id": "7724", + "name": "Brother Bordiss" + }, + { + "id": "7725", + "name": "Professor Arblenap" + }, + { + "id": "7726", + "name": "Assistant" + }, + { + "id": "7727", + "name": "Monk", + "examine": "A holy man.", + "attack_level": "12", + "combat_audio": "511,513,512", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "12", + "lifepoints": "17", + "magic_animation": "0", + "melee_animation": "422", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "12", + "weakness": "9" + }, + { + "id": "7728", + "name": "Baby icefiend" + }, + { + "id": "7736", + "name": "Baby icefiend", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "5", + "death_animation": "8078", + "defence_animation": "8084", + "defence_level": "1", + "lifepoints": "50", + "melee_animation": "8080", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7737", + "name": "Will" + }, + { + "id": "7738", + "name": "Will" + }, + { + "id": "7739", + "name": "Phil" + }, + { + "id": "7740", + "name": "Jiggling crate", + "examine": "Is it full of rats?", + "attack_level": "1", + "combat_audio": "703,705,704", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7741", + "name": "Three little kittens", + "examine": "A warrior who has been long forgotten.", + "aggressive": "true", + "attack_level": "30", + "death_animation": "836", + "defence_animation": "0", + "defence_level": "25", + "lifepoints": "5", + "magic_animation": "0", + "magic_level": "25", + "range_animation": "0", + "range_level": "25", + "safespot": null, + "strength_level": "30", + "weakness": "6" + }, + { + "id": "7742", + "name": "Fluffs" + }, + { + "id": "7743", + "name": "Fluffs" + }, + { + "id": "7744", + "name": "Kittens" + }, + { + "id": "7746", + "name": "TzHaar-Mej-Malk" + }, + { + "id": "7747", + "name": "TzHaar-Xil-Tog", + "examine": "It looks upset.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7748", + "name": "TzHaar-Hur-Frok" + }, + { + "id": "7749", + "name": "TzHaar-Ket-Grol" + }, + { + "id": "7750", + "name": "TzHaar-Ket-Rok" + }, + { + "id": "7751", + "name": "TzHaar-Ket-Lurk" + }, + { + "id": "7752", + "name": "TzHaar-Mej-Lor", + "examine": "A TzHaar librarian.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7753", + "name": "TzHaar-Mej" + }, + { + "id": "7754", + "name": "TzHaar-Hur" + }, + { + "id": "7755", + "name": "TzHaar-Xil" + }, + { + "id": "7756", + "name": "Library assistant", + "examine": "A TzHaar-Hur stamping stone tablets.", + "attack_level": "1", + "death_animation": "0", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "10", + "magic_animation": "0", + "melee_animation": "0", + "range_animation": "0", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7757", + "name": "TzHaar-Hur-Brekt" + }, + { + "id": "7758", + "name": "TzHaar-Hur-Brekt" + }, + { + "id": "7759", + "name": "TzHaar-Ket-Jok" + }, + { + "id": "7760", + "name": "TzHaar-Ket-Jok" + }, + { + "id": "7761", + "name": "TzHaar-Xil-Mor" + }, + { + "id": "7762", + "name": "TzHaar-Xil-Mor" + }, + { + "id": "7763", + "name": "TzHaar-Mej-Kol" + }, + { + "id": "7764", + "name": "TzHaar-Mej-Kol" + }, + { + "id": "7765", + "name": "TzHaar-Hur-Klag" + }, + { + "id": "7766", + "name": "TzHaar-Hur-Klag" + }, + { + "id": "7767", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "1", + "safespot": null, + "strength_level": "50" + }, + { + "id": "7768", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "1", + "safespot": null, + "strength_level": "50" + }, + { + "id": "7769", + "name": "TzHaar-Hur", + "examine": "Looks like a craftsman of some kind.", + "attack_level": "50", + "attack_speed": "5", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "death_animation": "9288", + "defence_animation": "9287", + "defence_level": "50", + "lifepoints": "80", + "magic_animation": "9286", + "magic_level": "50", + "melee_animation": "9286", + "range_animation": "9286", + "range_level": "1", + "safespot": null, + "strength_level": "50" + }, + { + "id": "7770", + "name": "TokTz-Ket-Dill" + }, + { + "id": "7771", + "name": "TokTz-Ket-Dill" + }, + { + "id": "7772", + "name": "Lava monster", + "examine": "A monster made of magma.", + "aggressive": "true", + "attack_level": "28", + "combat_style": "1", + "death_animation": "9340", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "9337", + "range_animation": "0", + "range_level": "38", + "respawn_delay": "60", + "safespot": null, + "strength_level": "28", + "weakness": "0" + }, + { + "id": "7773", + "name": "Fire monster", + "examine": "A monster like many others", + "aggressive": "true", + "attack_level": "28", + "combat_style": "2", + "death_animation": "9344", + "defence_animation": "0", + "defence_level": "38", + "lifepoints": "54", + "magic_animation": "0", + "melee_animation": "9341", + "range_animation": "0", + "range_level": "38", + "respawn_delay": "60", + "safespot": null, + "strength_level": "28", + "weakness": "0" + }, + { + "id": "7774", + "name": "Skeleton" + }, + { + "id": "7775", + "name": "Skeleton" + }, + { + "id": "7776", + "name": "Skeleton" + }, + { + "id": "7777", + "name": "Skeleton" + }, + { + "id": "7778", + "name": "Skeleton" + }, + { + "id": "7779", + "name": "Sumona" + }, + { + "id": "7781", + "name": "Jesmona" + }, + { + "id": "7782", + "name": "Catolax" + }, + { + "id": "7783", + "name": "Ali Cat" + }, + { + "id": "7786", + "name": "Mighty banshee", + "examine": "Not the best of vocalists.", + "aggressive": "true", + "attack_level": "65", + "combat_audio": "284,286,285", + "combat_style": "1", + "death_animation": "9450", + "defence_animation": "9451", + "defence_level": "65", + "lifepoints": "85", + "magic_animation": "9382", + "magic_level": "65", + "melee_animation": "9449", + "range_animation": "9382", + "range_level": "0", + "respawn_delay": "60", + "safespot": null, + "strength_level": "65", + "weakness": "0" + }, + { + "id": "7787", + "name": "Cave crawler" + }, + { + "id": "7788", + "name": "Skeleton" + }, + { + "id": "7789", + "name": "Zombie" + }, + { + "id": "7790", + "name": "Zombie" + }, + { + "id": "7791", + "name": "Zombie" + }, + { + "id": "7792", + "name": "Zombie" + }, + { + "id": "7793", + "name": "Banshee mistress" + }, + { + "id": "7794", + "name": "Banshee mistress" + }, + { + "id": "7795", + "name": "Insectoid assassin" + }, + { + "id": "7796", + "name": "Insectoid assassin" + }, + { + "id": "7797", + "name": "Kurask overlord" + }, + { + "id": "7798", + "name": "Monstrous cave crawler" + }, + { + "id": "7799", + "name": "Basilisk boss" + }, + { + "id": "7800", + "name": "Mightiest turoth" + }, + { + "id": "7801", + "name": "Aberrant spectre" + }, + { + "id": "7802", + "name": "Aberrant spectre" + }, + { + "id": "7803", + "name": "Aberrant spectre" + }, + { + "id": "7804", + "name": "Aberrant spectre" + }, + { + "id": "7805", + "name": "Kurask minion" + }, + { + "id": "7806", + "name": "Mummy warrior" + }, + { + "id": "7807", + "name": "Mummy warrior" + }, + { + "id": "7808", + "name": "Mummy warrior" + }, + { + "id": "7809", + "name": "Cat" + }, + { + "id": "7810", + "name": "Banshee" + }, + { + "id": "7811", + "name": "Kurask" + }, + { + "id": "7812", + "name": "Cave crawler" + }, + { + "id": "7813", + "name": "Basilisk" + }, + { + "id": "7814", + "name": "Turoth" + }, + { + "id": "7815", + "name": "Skeleton" + }, + { + "id": "7816", + "name": "Master" + }, + { + "id": "7817", + "name": "Zombie" + }, + { + "id": "7818", + "name": "Zombie" + }, + { + "id": "7819", + "name": "Zombie" + }, + { + "id": "7820", + "name": "Zombie" + }, + { + "id": "7821", + "name": "A wanderer." + }, + { + "id": "7822", + "name": "A wanderer." + }, + { + "id": "7823", + "name": "Wall Beast", + "examine": "A big, scary hand! ", + "aggressive": "true", + "attack_level": "38", + "attack_speed": "6", + "death_animation": "1804", + "defence_animation": "1803", + "defence_level": "38", + "lifepoints": "105", + "melee_animation": "1802", + "movement_radius": "0", + "range_level": "1", + "respawn_delay": "0", + "safespot": null, + "slayer_exp": "105", + "strength_level": "38" + }, + { + "id": "7824", + "name": "Osman" + }, + { + "id": "7825", + "name": "50 Ships Mufassah" + }, + { + "id": "7826", + "name": "Karamthulhu" + }, + { + "id": "7827", + "name": "Karamthulhu" + }, + { + "id": "7828", + "name": "Giant lobster" + }, + { + "id": "7829", + "name": "Giant crab" + }, + { + "id": "7830", + "name": "Customs Sergeant" + }, + { + "id": "7831", + "name": "Customs Sergeant" + }, + { + "id": "7832", + "name": "Young Ralph" + }, + { + "id": "7833", + "name": "Young Ralph" + }, + { + "id": "7834", + "name": "Young Ralph" + }, + { + "id": "7835", + "name": "Young Ralph" + }, + { + "id": "7836", + "name": "Young Ralph" + }, + { + "id": "7837", + "name": "Customs Officer" + }, + { + "id": "7838", + "name": "Customs Officer" + }, + { + "id": "7839", + "name": "Customs Officer" + }, + { + "id": "7840", + "name": "Heavy-Handed Harry" + }, + { + "id": "7841", + "name": "Player" + }, + { + "id": "7842", + "name": "Locker Officer" + }, + { + "id": "7843", + "name": "Locker Officer" + }, + { + "id": "7844", + "name": "Ex-ex-parrot" + }, + { + "id": "7845", + "name": "Pirate impling" + }, + { + "id": "7846", + "name": "Pirate impling" + }, + { + "id": "7847", + "name": "Captain Rabid Jack" + }, + { + "id": "7848", + "name": "Jack" + }, + { + "id": "7849", + "name": "Bosun Giles" + }, + { + "id": "7850", + "name": "Pirate" + }, + { + "id": "7851", + "name": "Lizzie" + }, + { + "id": "7852", + "name": "Cap'n Izzy No-Beard" + }, + { + "id": "7853", + "name": "Ralph" + }, + { + "id": "7854", + "name": "Brass Hand Harry" + }, + { + "id": "7855", + "name": "Bill Teach" + }, + { + "id": "7856", + "name": "Pirate" + }, + { + "id": "7857", + "name": "Brass Hand Harry" + }, + { + "id": "7858", + "name": "Gull" + }, + { + "id": "7861", + "name": "Jack" + }, + { + "id": "7862", + "name": "Fishing spot" + }, + { + "id": "7863", + "name": "Fishing spot" + }, + { + "id": "7864", + "name": "Fishing spot" + }, + { + "id": "7865", + "name": "Guardsman Dante" + }, + { + "id": "7866", + "name": "Guardsman DeShawn" + }, + { + "id": "7867", + "name": "Guardsman Brawn" + }, + { + "id": "7868", + "name": "Iain" + }, + { + "id": "7869", + "name": "Julian" + }, + { + "id": "7870", + "name": "Lachtopher" + }, + { + "id": "7871", + "name": "Samuel" + }, + { + "id": "7872", + "name": "Victoria" + }, + { + "id": "7873", + "name": "Man" + }, + { + "id": "7874", + "name": "Man" + }, + { + "id": "7875", + "name": "Man" + }, + { + "id": "7876", + "name": "Man" + }, + { + "id": "7877", + "name": "Man" + }, + { + "id": "7878", + "name": "Man" + }, + { + "id": "7879", + "name": "Man" + }, + { + "id": "7880", + "name": "Woman" + }, + { + "id": "7881", + "name": "Woman" + }, + { + "id": "7882", + "name": "Woman" + }, + { + "id": "7883", + "name": "Woman" + }, + { + "id": "7884", + "name": "Woman" + }, + { + "id": "7885", + "name": "Guardsman Dante" + }, + { + "id": "7886", + "name": "Guardsman DeShawn" + }, + { + "id": "7887", + "name": "Guardsman Brawn" + }, + { + "id": "7888", + "name": "Sergeant Abram" + }, + { + "id": "7889", + "name": "Guardsman Pazel" + }, + { + "id": "7890", + "name": "Guardsman Peale" + }, + { + "id": "7891", + "name": "Melee dummy", + "examine": "A melee training dummy", + "aggressive": "true", + "attack_level": "1", + "attack_speed": "6", + "death_animation": "97", + "defence_animation": "0", + "defence_level": "1", + "lifepoints": "15", + "magic_animation": "0", + "melee_animation": "94", + "range_animation": "0", + "range_level": "1", + "respawn_delay": "60", + "safespot": null, + "strength_level": "1", + "weakness": "6" + }, + { + "id": "7892", + "name": "General Wartface" + }, + { + "id": "7893", + "name": "General Bentnoze" + }, + { + "id": "7894", + "name": "General Wartface" + }, + { + "id": "7896", + "name": "General Bentnoze" + }, + { + "id": "7898", + "name": "Loar Shadow" + }, + { + "id": "7901", + "name": "Loar Shadow" + }, + { + "id": "7902", + "name": "Sergeant Abram" + }, + { + "id": "7903", + "name": "Guardsman Pazel" + }, + { + "id": "7904", + "name": "Guardsman Peale" + }, + { + "id": "7905", + "name": "Barricade guard" + }, + { + "id": "7906", + "name": "Barricade guard" + }, + { + "id": "7907", + "name": "Barricade guard" + }, + { + "id": "7908", + "name": "Barricade guard" + }, + { + "id": "7909", + "name": "Barricade guard" + }, + { + "id": "7910", + "name": "Barricade guard" + }, + { + "id": "7911", + "name": "Barricade guard" + }, + { + "id": "7912", + "name": "Border guard" + }, + { + "id": "7913", + "name": "Iain" + }, + { + "id": "7914", + "name": "Julian" + }, + { + "id": "7915", + "name": "Lachtopher" + }, + { + "id": "7916", + "name": "Samuel" + }, + { + "id": "7917", + "name": "Victoria" + }, + { + "id": "7918", + "name": "Man" + }, + { + "id": "7919", + "name": "Man" + }, + { + "id": "7920", + "name": "Man" + }, + { + "id": "7921", + "name": "Man" + }, + { + "id": "7922", + "name": "Man" + }, + { + "id": "7923", + "name": "Man" + }, + { + "id": "7924", + "name": "Man" + }, + { + "id": "7925", + "name": "Woman" + }, + { + "id": "7926", + "name": "Woman" + }, + { + "id": "7927", + "name": "Woman" + }, + { + "id": "7928", + "name": "Woman" + }, + { + "id": "7929", + "name": "Lumbridge Guide" + }, + { + "id": "7930", + "name": "Doomsayer" + }, + { + "id": "7931", + "name": "Donie" + }, + { + "id": "7932", + "name": "Gee" + }, + { + "id": "7933", + "name": "Duke Horacio" + }, + { + "id": "7934", + "name": "Sigmund" + }, + { + "id": "7935", + "name": "Hans" + }, + { + "id": "7936", + "name": "Cook" + }, + { + "id": "7937", + "name": "Father Aereck" + }, + { + "id": "7938", + "name": "Sir Vant" + }, + { + "id": "7939", + "name": "Sir Vant" + }, + { + "id": "7940", + "name": "Sir Vant" + }, + { + "id": "7941", + "name": "Sir Vant" + }, + { + "id": "7942", + "name": "Sir Vant" + }, + { + "id": "7943", + "name": "Dragon" + }, + { + "id": "7944", + "name": "Dragon" + }, + { + "id": "7945", + "name": "Dragon" + }, + { + "id": "7946", + "name": "Dragon" + }, + { + "id": "7947", + "name": "Dragon" + }, + { + "id": "7948", + "name": "Dragon" + }, + { + "id": "7949", + "name": "Lumbridge Guide" + }, + { + "id": "7950", + "name": "Melee Tutor" + }, + { + "id": "7951", + "name": "Ranged Tutor" + }, + { + "id": "7952", + "name": "Magic Tutor" + }, + { + "id": "7953", + "name": "Cooking Tutor" + }, + { + "id": "7954", + "name": "Crafting Tutor" + }, + { + "id": "7955", + "name": "Fishing Tutor" + }, + { + "id": "7956", + "name": "Mining Tutor" + }, + { + "id": "7957", + "name": "Prayer Tutor" + }, + { + "id": "7958", + "name": "Smelting Tutor", + "examine": "A man of his craft.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "movement_radius": "5", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7959", + "name": "Smelting Tutor", + "examine": "A master of his craft.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "movement_radius": "5", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7960", + "name": "Woodcutting Tutor" + }, + { + "id": "7961", + "name": "Bank Tutor" + }, + { + "id": "7962", + "name": "Gee" + }, + { + "id": "7963", + "name": "Spirit" + }, + { + "id": "7964", + "name": "Goblin" + }, + { + "id": "7965", + "name": "Goblin" + }, + { + "id": "7966", + "name": "Chaos druid" + }, + { + "id": "7967", + "name": "Shopkeeper" + }, + { + "id": "7968", + "name": "Explorer Jack" + }, + { + "id": "7969", + "name": "Explorer Jack", + "examine": "He looks like a professional explorer.", + "attack_level": "1", + "defence_level": "1", + "lifepoints": "10", + "range_level": "1", + "safespot": null, + "strength_level": "1" + }, + { + "id": "7970", + "name": "Smithing Tutor" + }, + { + "id": "7971", + "name": "Mining Tutor" + }, + { + "id": "7972", + "name": "Spirit" + }, + { + "id": "7977", + "name": "Spirit" + }, + { + "id": "7978", + "name": "Spirit" + }, + { + "id": "7979", + "name": "Spirit" + }, + { + "id": "7980", + "name": "Spirit" + }, + { + "id": "7981", + "name": "Spirit" + }, + { + "id": "7982", + "name": "Spirit" + }, + { + "id": "7983", + "name": "Spirit" + }, + { + "id": "7984", + "name": "Spirit" + }, + { + "id": "7985", + "name": "Summer Bonde" + }, + { + "id": "7987", + "name": "Spirit" + }, + { + "id": "7988", + "name": "Spirit" + }, + { + "id": "7989", + "name": "Erik Bonde" + }, + { + "id": "7990", + "name": "Spirit" + }, + { + "id": "7991", + "name": "Jallek Lenkin" + }, + { + "id": "7992", + "name": "Spirit" + }, + { + "id": "7993", + "name": "Meranek Thanatos" + }, + { + "id": "7994", + "name": "Ghostly warrior" + }, + { + "id": "7995", + "name": "Spirit Beast" + }, + { + "id": "7996", + "name": "Spirit Beast" + }, + { + "id": "7997", + "name": "Spirit Beast" + }, + { + "id": "7998", + "name": "Ghost" + }, + { + "id": "7999", + "name": "Ghost" + }, + { + "id": "8000", + "name": "Goth leprechaun" + }, + { + "id": "8001", + "name": "Jack" + }, + { + "id": "8003", + "name": "Sarah" + }, + { + "id": "8004", + "name": "Laura" + }, + { + "id": "8005", + "name": "Laura" + }, + { + "id": "8006", + "name": "Roger" + }, + { + "id": "8007", + "name": "Jorral" + }, + { + "id": "8008", + "name": "Guthix" + }, + { + "id": "8009", + "name": "Max the traveller" + }, + { + "id": "8010", + "name": "Man" + }, + { + "id": "8011", + "name": "Man" + }, + { + "id": "8012", + "name": "Woman" + }, + { + "id": "8013", + "name": "Woman" + }, + { + "id": "8014", + "name": "Haluned" + }, + { + "id": "8015", + "name": "Jack" + }, + { + "id": "8016", + "name": "Baby Sarah" + }, + { + "id": "8017", + "name": "Snowy" + }, + { + "id": "8018", + "name": "Roger" + }, + { + "id": "8019", + "name": "Portal" + }, + { + "id": "8020", + "name": "Portal" + }, + { + "id": "8021", + "name": "Yellow orb" + }, + { + "id": "8023", + "name": "Yellow orb" + }, + { + "id": "8024", + "name": "Yellow orb" + }, + { + "id": "8025", + "name": "Green orb" + }, + { + "id": "8027", + "name": "Green orb" + }, + { + "id": "8028", + "name": "Green orb" + }, + { + "id": "8029", + "name": "Wizard Korvak" + }, + { + "id": "8030", + "name": "Wizard Vief" + }, + { + "id": "8031", + "name": "Wizard Acantha" + }, + { + "id": "8032", + "name": "Wizard Elriss" + }, + { + "id": "8033", + "name": "Wizard" + }, + { + "id": "8034", + "name": "Wizard" + }, + { + "id": "8035", + "name": "Wizard" + }, + { + "id": "8036", + "name": "Wizard" + }, + { + "id": "8037", + "name": "Wizard" + }, + { + "id": "8038", + "name": "Wizard" + }, + { + "id": "8039", + "name": "Wizard" + }, + { + "id": "8040", + "name": "Wizard" + }, + { + "id": "8041", + "name": "Imiago", + "examine": "Perhaps this gardener might look after your crops for you." + }, + { + "id": "8042", + "name": "Squire Fyre" + }, + { + "id": "8043", + "name": "Squire Fyre" + }, + { + "id": "8044", + "name": "Orry" + }, + { + "id": "8045", + "name": "Orry" + }, + { + "id": "8046", + "name": "Ube" + }, + { + "id": "8047", + "name": "Ube" + }, + { + "id": "8048", + "name": "Waldo" + }, + { + "id": "8049", + "name": "Waldo" + }, + { + "id": "8050", + "name": "Gjalp" + }, + { + "id": "8051", + "name": "Gjalp" + }, + { + "id": "8052", + "name": "Brother Fintan" + }, + { + "id": "8053", + "name": "Brother Fintan" + }, + { + "id": "8054", + "name": "Stubthumb" + }, + { + "id": "8055", + "name": "Stubthumb" + }, + { + "id": "8056", + "name": "Stubthumb" + }, + { + "id": "8057", + "name": "Doronbol" + }, + { + "id": "8058", + "name": "Doronbol" + }, + { + "id": "8059", + "name": "Crate" + }, + { + "id": "8060", + "name": "Crate" + }, + { + "id": "8061", + "name": "Egg" + }, + { + "id": "8062", + "name": "Egg" + }, + { + "id": "8063", + "name": "Nanuq" + }, + { + "id": "8064", + "name": "Nanuq" + }, + { + "id": "8065", + "name": "Pumpkin" + }, + { + "id": "8077", + "name": "Pumpkin", + "examine": "What's black and white and smells of pumpkin?", + "end_height": "" + }, + { + "id": "8078", + "name": "Maggie" + }, + { + "id": "8079", + "name": "Circus barker" + }, + { + "id": "8080", + "name": "Circus barker" + }, + { + "id": "8081", + "name": "Circus barker" + }, + { + "id": "8082", + "name": "Agility assistant" + }, + { + "id": "8083", + "name": "Magic assistant" + }, + { + "id": "8084", + "name": "Ranged assistant" + }, + { + "id": "8085", + "name": "Ringmaster" + }, + { + "id": "8086", + "name": "Audience" + }, + { + "id": "8087", + "name": "Audience" + }, + { + "id": "8088", + "name": "Ticket vendor" + }, + { + "id": "8089", + "name": "Rock" + }, + { + "id": "8091", + "name": "Star sprite" + }, + { + "id": "8092", + "name": "Shooting star shadow" + }, + { + "id": "8093", + "name": "Penguin" + }, + { + "id": "8094", + "name": "Penguin" + }, + { + "id": "8095", + "name": "Penguin" + }, + { + "id": "8096", + "name": "Penguin" + }, + { + "id": "8097", + "name": "Penguin" + }, + { + "id": "8098", + "name": "Penguin" + }, + { + "id": "8099", + "name": "Penguin" + }, + { + "id": "8100", + "name": "Penguin" + }, + { + "id": "8101", + "name": "Penguin" + }, + { + "id": "8102", + "name": "Penguin" + }, + { + "id": "8103", + "name": "Penguin" + }, + { + "id": "8104", + "name": "Barrel", + "examine": "What's black and white and smells like beer?" + }, + { + "id": "8105", + "name": "Bush", + "examine": "What's black and white and down to earth?" + }, + { + "id": "8106", + "name": "Bush" + }, + { + "id": "8107", + "name": "Cactus", + "examine": "What's black and white and covered in spines?" + }, + { + "id": "8108", + "name": "Crate", + "examine": "What's black and white and on a sneaking mission?" + }, + { + "id": "8109", + "name": "Rock", + "examine": "What's black and white and looks like a rock hopper?" + }, + { + "id": "8110", + "name": "Toadstool", + "examine": "What's black and white and covered in mushroom?" + }, + { + "id": "8111", + "name": "Calladin" + }, + { + "id": "8112", + "name": "Summer Bonde" + }, + { + "id": "8114", + "name": "Summer Bonde" + }, + { + "id": "8115", + "name": "Erik Bonde" + }, + { + "id": "8116", + "name": "Erik Bonde" + }, + { + "id": "8117", + "name": "Jallek Lenkin" + }, + { + "id": "8118", + "name": "Jallek Lenkin" + }, + { + "id": "8119", + "name": "Meranek Thanatos" + }, + { + "id": "8120", + "name": "Meranek Thanatos" + }, + { + "id": "8121", + "name": "Spirit" + }, + { + "id": "8122", + "name": "Rogue" + }, + { + "id": "8123", + "name": "Tormented wraith" + }, + { + "id": "8126", + "name": "Dark energy core" + }, + { + "id": "8127", + "name": "Dark energy core" + }, + { + "id": "8128", + "name": "Spirit Beast" + }, + { + "id": "8129", + "name": "Spirit Beast" + }, + { + "id": "8130", + "name": "Spirit Beast" + }, + { + "id": "8131", + "name": "Spirit Beast" + }, + { + "id": "8132", + "name": "Spirit Beast" + }, + { + "id": "8133", + "name": "Corporeal Beast", + "examine": "A vision of supernatural horror.", + "agg_radius": "64", + "aggressive": "true", + "attack_level": "320", + "attack_speed": "6", + "bonuses": "50,50,50,0,0,25,200,100,150,230,0,0,0,0,0", + "death_animation": "10385", + "defence_animation": "10386", + "defence_level": "310", + "lifepoints": "2000", + "magic_animation": "10053", + "magic_level": "350", + "melee_animation": "10058", + "movement_radius": "64", + "poison_immune": "true", + "range_level": "150", + "respawn_delay": "80", + "safespot": null, + "strength_level": "320" + }, + { + "id": "8134", + "name": "Spirit" + }, + { + "id": "8135", + "name": "Summer Bonde" + }, + { + "id": "8136", + "name": "Erik Bonde" + }, + { + "id": "8137", + "name": "Jallek Lenkin" + }, + { + "id": "8138", + "name": "Meranek Thanatos" + }, + { + "id": "8139", + "name": "Hartwin" + }, + { + "id": "8140", + "name": "Hartwin" + }, + { + "id": "8141", + "name": "Zombie" + }, + { + "id": "8143", + "name": "Zombie" + }, + { + "id": "8144", + "name": "Zombie" + }, + { + "id": "8145", + "name": "Zombie" + }, + { + "id": "8146", + "name": "Zemouregal" + }, + { + "id": "8147", + "name": "Zemouregal" + }, + { + "id": "8149", + "name": "Armoured zombie", + "examine": "He sure looks grave.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "6", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "50", + "lifepoints": "62", + "melee_animation": "5571", + "range_level": "50", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "30", + "strength_level": "50" + }, + { + "id": "8150", + "name": "Armoured zombie", + "examine": "This is a rotten one.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "6", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "50", + "lifepoints": "62", + "melee_animation": "5571", + "range_level": "50", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "30", + "strength_level": "50" + }, + { + "id": "8151", + "name": "Armoured zombie", + "examine": "It hasn't quite gotten around to dying.", + "aggressive": "true", + "attack_level": "50", + "attack_speed": "6", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "combat_audio": "931,923,922", + "death_animation": "5575", + "defence_animation": "5574", + "defence_level": "50", + "lifepoints": "62", + "melee_animation": "5571", + "range_level": "50", + "respawn_delay": "35", + "safespot": null, + "slayer_exp": "30", + "strength_level": "50" + }, + { + "id": "8152", + "name": "Armoured zombie" + }, + { + "id": "8153", + "name": "Armoured zombie" + }, + { + "id": "8154", + "name": "Armoured zombie" + }, + { + "id": "8155", + "name": "Armoured zombie" + }, + { + "id": "8156", + "name": "Armoured zombie" + }, + { + "id": "8157", + "name": "Armoured zombie" + }, + { + "id": "8158", + "name": "Armoured zombie" + }, + { + "id": "8159", + "name": "Armoured zombie" + }, + { + "id": "8160", + "name": "Armoured zombie" + }, + { + "id": "8161", + "name": "Armoured zombie" + }, + { + "id": "8162", + "name": "Armoured zombie" + }, + { + "id": "8163", + "name": "Armoured zombie" + }, + { + "id": "8164", + "name": "Armoured zombie" + }, + { + "id": "8165", + "name": "Sharathteerk" + }, + { + "id": "8166", + "name": "Sharathteerk" + }, + { + "id": "8168", + "name": "Arrav" + }, + { + "id": "8169", + "name": "Arrav" + }, + { + "id": "8170", + "name": "Ramarno" + }, + { + "id": "8171", + "name": "Dimintheis" + }, + { + "id": "8172", + "name": "Dimintheis" + }, + { + "id": "8173", + "name": "Guard" + }, + { + "id": "8174", + "name": "Clive" + }, + { + "id": "8175", + "name": "Ellamaria" + }, + { + "id": "8176", + "name": "Fish" + }, + { + "id": "8177", + "name": "Fish" + }, + { + "id": "8178", + "name": "Monk of Zamorak" + }, + { + "id": "8179", + "name": "Ellamaria" + }, + { + "id": "8180", + "name": "Traiborn" + }, + { + "id": "8181", + "name": "Fenkenstrain's Monster" + }, + { + "id": "8182", + "name": "Wise Old Man" + }, + { + "id": "8183", + "name": "Acrobat" + }, + { + "id": "8186", + "name": "Acrobat" + }, + { + "id": "8187", + "name": "Acrobat" + }, + { + "id": "8188", + "name": "Acrobat" + }, + { + "id": "8189", + "name": "Acrobat" + }, + { + "id": "8190", + "name": "Acrobat" + }, + { + "id": "8191", + "name": "Acrobat" + }, + { + "id": "8192", + "name": "Acrobat" + }, + { + "id": "8193", + "name": "Acrobat" + }, + { + "id": "8194", + "name": "Acrobat" + }, + { + "id": "8195", + "name": "Acrobat" + }, + { + "id": "8196", + "name": "Acrobat" + }, + { + "id": "8197", + "name": "Acrobat" + }, + { + "id": "8198", + "name": "Acrobat" + }, + { + "id": "8199", + "name": "Acrobat" + }, + { + "id": "8200", + "name": "Acrobat" + }, + { + "id": "8201", + "name": "Wendy" + }, + { + "id": "8202", + "name": "Trogs" + }, + { + "id": "8203", + "name": "Norman" + }, + { + "id": "8204", + "name": "Babe" + }, + { + "id": "8205", + "name": "Gus" + }, + { + "id": "8206", + "name": "Lottie" + }, + { + "id": "8207", + "name": "Aggie" + }, + { + "id": "8208", + "name": "Bat" + }, + { + "id": "8209", + "name": "Rat" + }, + { + "id": "8210", + "name": "Lizard" + }, + { + "id": "8211", + "name": "Blackbird" + }, + { + "id": "8212", + "name": "Spider" + }, + { + "id": "8213", + "name": "Snail" + }, + { + "id": "8214", + "name": "Cat" + }, + { + "id": "8215", + "name": "Lazy cat" + }, + { + "id": "8216", + "name": "Overgrown cat" + }, + { + "id": "8217", + "name": "Kitten" + }, + { + "id": "8218", + "name": "Wily cat" + }, + { + "id": "8219", + "name": "Guardian of Armadyl" + }, + { + "id": "8227", + "name": "Head mystic" + }, + { + "id": "8228", + "name": "Rewards mystic" + }, + { + "id": "8229", + "name": "Mystic" + }, + { + "id": "8230", + "name": "Mystic" + }, + { + "id": "8231", + "name": "Mystic" + }, + { + "id": "8232", + "name": "Mystic" + }, + { + "id": "8233", + "name": "Mystic" + }, + { + "id": "8234", + "name": "Mystic" + }, + { + "id": "8235", + "name": "Mystic" + }, + { + "id": "8236", + "name": "Mystic" + }, + { + "id": "8237", + "name": "Mystic" + }, + { + "id": "8238", + "name": "Mystic" + }, + { + "id": "8239", + "name": "Head mystic" + }, + { + "id": "8240", + "name": "Clay familiar (class 1)" + }, + { + "id": "8241", + "name": "Clay familiar (class 1)" + }, + { + "id": "8242", + "name": "Clay familiar (class 2)" + }, + { + "id": "8243", + "name": "Clay familiar (class 2)" + }, + { + "id": "8244", + "name": "Clay familiar (class 3)" + }, + { + "id": "8245", + "name": "Clay familiar (class 3)" + }, + { + "id": "8246", + "name": "Clay familiar (class 4)" + }, + { + "id": "8247", + "name": "Clay familiar (class 4)" + }, + { + "id": "8248", + "name": "Clay familiar (class 5)" + }, + { + "id": "8249", + "name": "Clay familiar (class 5)" + }, + { + "id": "8250", + "name": "Grindxplox" + }, + { + "id": "8251", + "name": "Grindxplox" + }, + { + "id": "8252", + "name": "Stealing Creation team" + }, + { + "id": "8253", + "name": "Resource NPC" + }, + { + "id": "8254", + "name": "Game NPC" + }, + { + "id": "8255", + "name": "Resource NPC" + }, + { + "id": "8257", + "name": "Harrallak Menarous" + }, + { + "id": "8269", + "name": "Yadech Strongarm" + }, + { + "id": "8271", + "name": "Turael" + }, + { + "id": "8273", + "name": "Turael", + "examine": "He looks dangerous!" + }, + { + "id": "8274", + "name": "Mazchna" + }, + { + "id": "8275", + "name": "Duradel", + "examine": "He looks dangerous!" + }, + { + "id": "8276", + "name": "Cyrisus" + }, + { + "id": "8280", + "name": "Sloane" + }, + { + "id": "8281", + "name": "Balance Elemental" + }, + { + "id": "8282", + "name": "Balance Elemental" + }, + { + "id": "8283", + "name": "Balance Elemental" + }, + { + "id": "8284", + "name": "Balance Elemental" + }, + { + "id": "8285", + "name": "Balance Elemental" + }, + { + "id": "8286", + "name": "Undead hero" + }, + { + "id": "8287", + "name": "Undead hero" + }, + { + "id": "8288", + "name": "Undead hero" + }, + { + "id": "8289", + "name": "Undead hero" + }, + { + "id": "8290", + "name": "Undead hero" + }, + { + "id": "8291", + "name": "Undead hero" + }, + { + "id": "8292", + "name": "Undead hero" + }, + { + "id": "8293", + "name": "Undead hero" + }, + { + "id": "8294", + "name": "Undead hero" + }, + { + "id": "8295", + "name": "Undead hero" + }, + { + "id": "8296", + "name": "Undead hero" + }, + { + "id": "8297", + "name": "Undead hero" + }, + { + "id": "8298", + "name": "Stone block" + }, + { + "id": "8299", + "name": "Harrallak Menarous" + }, + { + "id": "8300", + "name": "Harrallak Menarous" + }, + { + "id": "8301", + "name": "Harrallak Menarous" + }, + { + "id": "8302", + "name": "Turael" + }, + { + "id": "8303", + "name": "Turael" + }, + { + "id": "8304", + "name": "Cyrisus" + }, + { + "id": "8305", + "name": "Cyrisus" + }, + { + "id": "8306", + "name": "Ghommal" + }, + { + "id": "8307", + "name": "Mazchna" + }, + { + "id": "8308", + "name": "Mazchna" + }, + { + "id": "8309", + "name": "Mazchna" + }, + { + "id": "8310", + "name": "Duradel" + }, + { + "id": "8311", + "name": "Sloane" + }, + { + "id": "8317", + "name": "Elite Dark Ranger" + }, + { + "id": "8318", + "name": "Elite Dark Ranger" + }, + { + "id": "8319", + "name": "Elite Dark Ranger" + }, + { + "id": "8320", + "name": "Elite Dark Mage" + }, + { + "id": "8321", + "name": "Elite Dark Mage" + }, + { + "id": "8322", + "name": "Elite Dark Mage" + }, + { + "id": "8323", + "name": "Elite Dark Mage" + }, + { + "id": "8324", + "name": "Elite Black Knight" + }, + { + "id": "8325", + "name": "Elite Black Knight" + }, + { + "id": "8326", + "name": "Elite Black Knight" + }, + { + "id": "8327", + "name": "Elite Black Knight" + }, + { + "id": "8328", + "name": "Elite Black Knight" + }, + { + "id": "8329", + "name": "Elite Black Knight" + }, + { + "id": "8330", + "name": "Elite Black Knight" + }, + { + "id": "8331", + "name": "Guardian of Armadyl" + }, + { + "id": "8332", + "name": "Guardian of Armadyl" + }, + { + "id": "8333", + "name": "Guardian of Armadyl" + }, + { + "id": "8334", + "name": "Mercenary axeman" + }, + { + "id": "8335", + "name": "Mercenary mage" + }, + { + "id": "8336", + "name": "Idria" + }, + { + "id": "8337", + "name": "Idria" + }, + { + "id": "8338", + "name": "Akrisae" + }, + { + "id": "8339", + "name": "Shady stranger" + }, + { + "id": "8340", + "name": "Shady stranger" + }, + { + "id": "8341", + "name": "Shady stranger" + }, + { + "id": "8342", + "name": "Guardian of Armadyl" + }, + { + "id": "8344", + "name": "Guardian of Armadyl" + }, + { + "id": "8345", + "name": "Local thug" + }, + { + "id": "8347", + "name": "Local mage" + }, + { + "id": "8349", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "2", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "0", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8350", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "2", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "2", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8351", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "2", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "1", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8352", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "1", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "0", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8353", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "1", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "2", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8354", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "1", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "1", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8355", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "0", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "0", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8356", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "0", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "2", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8357", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "0", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "1", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8358", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "2", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "0", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8359", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "2", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "2", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8360", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "2", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "1", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8361", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "1", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "0", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8362", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "1", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "2", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8363", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "1", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "1", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8364", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "0", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "0", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8365", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "0", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "2", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8366", + "name": "Tormented demon", + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "aggressive": "true", + "attack_level": "85", + "attack_speed": "6", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "combat_style": "0", + "death_animation": "10924", + "defence_animation": "10923", + "defence_level": "85", + "lifepoints": "326", + "magic_animation": "10918", + "magic_level": "85", + "melee_animation": "10922", + "movement_radius": "40", + "poison_immune": "true", + "protect_style": "1", + "range_animation": "10919", + "range_level": "85", + "respawn_delay": "100", + "safespot": "true", + "slayer_exp": "136", + "strength_level": "85" + }, + { + "id": "8367", + "name": "Undead troll" + }, + { + "id": "8378", + "name": "Undead troll" + }, + { + "id": "8379", + "name": "Undead troll" + }, + { + "id": "8380", + "name": "Undead troll" + }, + { + "id": "8381", + "name": "Undead troll" + }, + { + "id": "8382", + "name": "Undead troll" + }, + { + "id": "8383", + "name": "Undead troll" + }, + { + "id": "8384", + "name": "Undead troll" + }, + { + "id": "8385", + "name": "Undead troll" + }, + { + "id": "8386", + "name": "Undead troll" + }, + { + "id": "8387", + "name": "Undead troll" + }, + { + "id": "8388", + "name": "Undead troll" + }, + { + "id": "8389", + "name": "Undead troll" + }, + { + "id": "8390", + "name": "Undead troll" + }, + { + "id": "8391", + "name": "Undead troll" + }, + { + "id": "8392", + "name": "Undead troll" + }, + { + "id": "8393", + "name": "Vasador" + }, + { + "id": "8394", + "name": "Valator" + }, + { + "id": "8395", + "name": "Vaasdor" + }, + { + "id": "8396", + "name": "Varosad" + }, + { + "id": "8397", + "name": "Verisad" + }, + { + "id": "8398", + "name": "Vudisor" + }, + { + "id": "8399", + "name": "Vlatoad" + }, + { + "id": "8400", + "name": "Vedolas" + }, + { + "id": "8401", + "name": "Vundiar" + }, + { + "id": "8402", + "name": "Versita" + }, + { + "id": "8403", + "name": "Vislota" + }, + { + "id": "8404", + "name": "Vanjuta" + }, + { + "id": "8405", + "name": "Vasador" + }, + { + "id": "8406", + "name": "Valator" + }, + { + "id": "8407", + "name": "Vaasdor" + }, + { + "id": "8408", + "name": "Varosad" + }, + { + "id": "8409", + "name": "Verisad" + }, + { + "id": "8410", + "name": "Vudisor" + }, + { + "id": "8411", + "name": "Vlatoad" + }, + { + "id": "8412", + "name": "Vedolas" + }, + { + "id": "8413", + "name": "Vundiar" + }, + { + "id": "8414", + "name": "Versita" + }, + { + "id": "8415", + "name": "Vislota" + }, + { + "id": "8416", + "name": "Vanjuta" + }, + { + "id": "8417", + "name": "Ivy Sophista" + }, + { + "id": "8418", + "name": "Thaerisk Cemphier" + }, + { + "id": "8419", + "name": "Thaerisk Cemphier" + }, + { + "id": "8420", + "name": "Assassin" + }, + { + "id": "8423", + "name": "Assassin" + }, + { + "id": "8424", + "name": "Mithril dragon" + }, + { + "id": "8425", + "name": "Dragon head" + }, + { + "id": "8426", + "name": "Dragon head" + }, + { + "id": "8427", + "name": "Dragon head" + }, + { + "id": "8428", + "name": "Khazard launderer" + }, + { + "id": "8429", + "name": "Khazard cook" + }, + { + "id": "8430", + "name": "Silif" + }, + { + "id": "8431", + "name": "Silif" + }, + { + "id": "8432", + "name": "Silif" + }, + { + "id": "8433", + "name": "Silif" + }, + { + "id": "8434", + "name": "Silif" + }, + { + "id": "8435", + "name": "Shady stranger" + }, + { + "id": "8436", + "name": "Suspicious outsider" + }, + { + "id": "8437", + "name": "Elite Khazard guard" + }, + { + "id": "8438", + "name": "Elite Khazard guard" + }, + { + "id": "8439", + "name": "Elite Khazard guard" + }, + { + "id": "8440", + "name": "Elite Khazard guard" + }, + { + "id": "8441", + "name": "Dark Squall" + }, + { + "id": "8442", + "name": "Surok Magis" + }, + { + "id": "8443", + "name": "Lucien" + }, + { + "id": "8444", + "name": "Druid" + }, + { + "id": "8445", + "name": "Druid" + }, + { + "id": "8446", + "name": "Druid" + }, + { + "id": "8447", + "name": "Druid bodyguard" + }, + { + "id": "8448", + "name": "Druid bodyguard" + }, + { + "id": "8449", + "name": "Movario" + }, + { + "id": "8450", + "name": "Darve" + }, + { + "id": "8451", + "name": "Cave goblin" + }, + { + "id": "8452", + "name": "Movario" + }, + { + "id": "8453", + "name": "Darve" + }, + { + "id": "8454", + "name": "Light creature" + }, + { + "id": "8455", + "name": "Light creature" + }, + { + "id": "8456", + "name": "Druid spirit" + }, + { + "id": "8457", + "name": "Druid spirit" + }, + { + "id": "8458", + "name": "Druid spirit" + }, + { + "id": "8459", + "name": "Druid spirit" + }, + { + "id": "8460", + "name": "Turael" + }, + { + "id": "8462", + "name": "Spria" + }, + { + "id": "8463", + "name": "Mazchna" + }, + { + "id": "8464", + "name": "Mazchna" + }, + { + "id": "8465", + "name": "Achtryn" + }, + { + "id": "8466", + "name": "Duradel" + }, + { + "id": "8467", + "name": "Lapalok" + }, + { + "id": "8468", + "name": "Laidee Gnonock" + }, + { + "id": "8485", + "name": "Hazelmere" + }, + { + "id": "8486", + "name": "Undead mage" + }, + { + "id": "8487", + "name": "Wild broav" + }, + { + "id": "8488", + "name": "Hazelmere" + }, + { + "id": "8490", + "name": "Hazelmere" + }, + { + "id": "8491", + "name": "Broav" + }, + { + "id": "8492", + "name": "Sithaph" + }, + { + "id": "8494", + "name": "Strisath" + }, + { + "id": "8495", + "name": "Sakirth" + }, + { + "id": "8496", + "name": "Hazelmere's hat" + }, + { + "id": "8497", + "name": "Lucien" + }, + { + "id": "8498", + "name": "A lazy Khazard guard" + }, + { + "id": "8499", + "name": "Thanksgiving Turkey" + }, + { + "id": "8500", + "name": "Cook's brother" + }, + { + "id": "8501", + "name": "Turkey" + }, + { + "id": "8502", + "name": "Cactus", + "examine": "Are those spines or feathers? Either way, it looks delicious." + }, + { + "id": "8503", + "name": "Cactus", + "examine": "Prickly, but strangely tasty-looking..." + }, + { + "id": "8504", + "name": "Bush", + "examine": "It rustles deliciously." + }, + { + "id": "8505", + "name": "Toadstool", + "examine": "A horrible fungus, but there is something strangely tasty about it." + }, + { + "id": "8506", + "name": "Barrel", + "examine": "The most delicious barrel you have ever seen." + }, + { + "id": "8507", + "name": "Bush", + "examine": "Who would have thought that leaves could smell so edible?" + }, + { + "id": "8508", + "name": "Crate", + "examine": "A crate. But delicious." + }, + { + "id": "8509", + "name": "Bush", + "examine": "You feel a strange urge to pour gravy on that bush." + }, + { + "id": "8510", + "name": "Rock", + "examine": "Now that's a rock I'd try to make into soup!" + }, + { + "id": "8511", + "name": "Bush", + "examine": "Did that bush just pour sauce on itself?" + }, + { + "id": "8512", + "name": "Marvin" + }, + { + "id": "8513", + "name": "Marius" + }, + { + "id": "8514", + "name": "Benny" + }, + { + "id": "8515", + "name": "Yeti" + }, + { + "id": "8516", + "name": "Yeti" + }, + { + "id": "8517", + "name": "Jack Frost", + "examine": "The rebellious teenage son of the Queen of Snow. Interesting outfit!" + }, + { + "id": "8518", + "name": "Jack Frost" + }, + { + "id": "8519", + "name": "Jack Frost" + }, + { + "id": "8520", + "name": "Jack Frost" + }, + { + "id": "8521", + "name": "Snow imp" + }, + { + "id": "8537", + "name": "Snow imp" + }, + { + "id": "8538", + "name": "Snow imp" + }, + { + "id": "8539", + "name": "Queen of Snow" + }, + { + "id": "8540", + "name": "Santa Claus", + "examine": "A jolly-looking present-distributor." + }, + { + "id": "8541", + "name": "Head snow imp" + }, + { + "id": "8542", + "name": "Head snow imp" + }, + { + "id": "8543", + "name": "Head snow imp" + }, + { + "id": "8544", + "name": "Isidor" + }, + { + "id": "8545", + "name": "Mystic" + }, + { + "id": "8546", + "name": "Balance Elemental" + }, + { + "id": "8547", + "name": "Wounded phoenix" + }, + { + "id": "8548", + "name": "Phoenix" + }, + { + "id": "8549", + "name": "Phoenix" + }, + { + "id": "8550", + "name": "Phoenix eggling" + }, + { + "id": "8551", + "name": "Phoenix eggling" + }, + { + "id": "8552", + "name": "Large egg" + }, + { + "id": "8553", + "name": "Priest of Guthix" + }, + { + "id": "8556", + "name": "Brian Twitcher" + }, + { + "id": "8557", + "name": "Lesser reborn warrior" + }, + { + "id": "8558", + "name": "Lesser reborn warrior" + }, + { + "id": "8559", + "name": "Greater reborn warrior" + }, + { + "id": "8560", + "name": "Greater reborn warrior" + }, + { + "id": "8561", + "name": "Lesser reborn ranger" + }, + { + "id": "8562", + "name": "Lesser reborn ranger" + }, + { + "id": "8563", + "name": "Greater reborn ranger" + }, + { + "id": "8564", + "name": "Greater reborn ranger" + }, + { + "id": "8565", + "name": "Lesser reborn mage" + }, + { + "id": "8566", + "name": "Lesser reborn mage" + }, + { + "id": "8567", + "name": "Greater reborn mage" + }, + { + "id": "8568", + "name": "Greater reborn mage" + }, + { + "id": "8569", + "name": "Lesser reborn warrior" + }, + { + "id": "8570", + "name": "Greater reborn warrior" + }, + { + "id": "8571", + "name": "Lesser reborn ranger" + }, + { + "id": "8572", + "name": "Greater reborn ranger" + }, + { + "id": "8573", + "name": "Lesser reborn mage" + }, + { + "id": "8574", + "name": "Greater reborn mage" + }, + { + "id": "8575", + "name": "Phoenix" + }, + { + "id": "8576", + "name": "Phoenix" + }, + { + "id": "8577", + "name": "Phoenix eggling" + }, + { + "id": "8578", + "name": "Phoenix eggling" + }, + { + "id": "8579", + "name": "Karma the chameleon" + }, + { + "id": "8581", + "name": "Karma the chameleon" + }, + { + "id": "8582", + "name": "Karma the chameleon" + }, + { + "id": "8583", + "name": "Karma the chameleon" + }, + { + "id": "8584", + "name": "Karma the chameleon" + }, + { + "id": "8585", + "name": "Karma the chameleon" + }, + { + "id": "8586", + "name": "Karma the chameleon" + }, + { + "id": "8587", + "name": "Karma the chameleon" + }, + { + "id": "8588", + "name": "Karma the chameleon" + }, + { + "id": "8589", + "name": "Karma the chameleon" + }, + { + "id": "8590", + "name": "Geoffrey" } ] \ No newline at end of file diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json index 57a3f2c37..77ef33f02 100644 --- a/Server/data/configs/npc_spawns.json +++ b/Server/data/configs/npc_spawns.json @@ -1,7 +1,7 @@ [ { "npc_id": "0", - "loc_data": "{3221,3218,0,1,0}-{2522,5000,0,0,4}-" + "loc_data": "{3221,3218,0,1,0}-" }, { "npc_id": "1", @@ -133,7 +133,7 @@ }, { "npc_id": "41", - "loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-" + "loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{3197,3353,0,1,0}-{3196,3358,0,1,0}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-" }, { "npc_id": "42", @@ -157,7 +157,7 @@ }, { "npc_id": "47", - "loc_data": "{2821,3170,0,1,1}-{3341,3267,0,1,5}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{2801,3158,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-" + "loc_data": "{2821,3170,0,1,1}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3341,3267,0,1,5}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2339,9356,0,1,0}-{2354,9390,0,1,0}-{2361,9403,0,1,0}-{2362,9347,0,1,0}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-" }, { "npc_id": "48", @@ -193,7 +193,7 @@ }, { "npc_id": "59", - "loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-" + "loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2369,3374,0,1,0}-{2372,3379,0,1,0}-{2378,3366,0,1,0}-{2379,3378,0,1,0}-{2387,3370,0,1,0}-{2394,3365,0,1,0}-{2402,3386,0,1,0}-{2405,3381,0,1,0}-{2407,3387,0,1,0}-{2412,3384,0,1,0}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-" }, { "npc_id": "60", @@ -213,19 +213,19 @@ }, { "npc_id": "64", - "loc_data": "{2684,9798,0,1,2}-{2959,3917,0,1,0}-{2960,3925,0,1,0}-{2961,3920,0,1,0}-{2962,3915,0,1,0}-{2962,3933,0,1,0}-{2963,3923,0,1,0}-{2963,3929,0,1,0}-{2965,3927,0,1,0}-{2965,3931,0,1,0}-{2691,9814,0,1,5}-{2694,9819,0,1,6}-{2696,9831,0,1,3}-{2702,9837,0,1,6}-{2709,9844,0,1,3}-{2720,9847,0,1,4}-{2724,9843,0,1,6}-{2733,9846,0,1,4}-{2740,9841,0,1,3}-{2745,9836,0,1,4}-{2745,9828,0,1,5}-{2747,9826,0,1,1}-" + "loc_data": "{2869,9912,0,1,0}-{2819,9950,0,1,0}-{2824,9934,0,1,0}-{2827,9925,0,1,0}-{2828,9956,0,1,0}-{2857,9969,0,1,0}-{2872,9972,0,1,0}-{2684,9798,0,1,2}-{2885,9962,0,1,0}-{2887,9936,0,1,0}-{2959,3917,0,1,0}-{2960,3925,0,1,0}-{2961,3920,0,1,0}-{2962,3915,0,1,0}-{2962,3933,0,1,0}-{2963,3923,0,1,0}-{2963,3929,0,1,0}-{2965,3927,0,1,0}-{2965,3931,0,1,0}-{2691,9814,0,1,5}-{2694,9819,0,1,6}-{2696,9831,0,1,3}-{2702,9837,0,1,6}-{2709,9844,0,1,3}-{2720,9847,0,1,4}-{2724,9843,0,1,6}-{2733,9846,0,1,4}-{2740,9841,0,1,3}-{2745,9836,0,1,4}-{2745,9828,0,1,5}-{2747,9826,0,1,1}-" }, { "npc_id": "66", - "loc_data": "{2526,3169,0,1,6}-{2528,3164,0,1,6}-{2529,3169,0,1,1}-{2537,3170,0,1,1}-{2507,3204,0,1,5}-{2506,3205,0,1,6}-{2540,3226,0,1,6}-" + "loc_data": "{2399,3356,0,1,0}-{2383,3452,0,1,0}-{2401,3417,0,1,0}-{2402,3422,0,1,0}-{2402,3441,0,1,0}-{2403,3430,0,1,0}-{2408,3441,0,1,0}-{2409,3430,0,1,0}-{2423,3426,0,1,0}-{2427,3428,0,1,0}-{2427,3440,0,1,0}-{2417,3493,1,1,0}-{2418,3495,1,1,0}-{2435,3460,0,1,0}-{2440,3470,0,1,0}-{2447,3502,0,1,0}-{2457,3462,0,1,0}-{2478,3502,0,1,0}-{2449,3492,1,1,0}-{2450,3490,1,1,0}-{2474,3490,1,1,0}-{2482,3492,1,1,0}-{2482,3498,1,1,0}-{2526,3168,0,1,0}-{2529,3163,0,1,0}-{2530,3172,0,1,0}-{2536,3169,0,1,0}-" }, { "npc_id": "67", - "loc_data": "{2507,3200,0,1,6}-{2516,3212,0,1,1}-" + "loc_data": "{2400,3356,0,1,0}-{2377,3442,0,1,0}-{2380,3425,0,1,0}-{2383,3433,0,1,0}-{2405,3447,0,1,0}-{2406,3440,0,1,0}-{2393,3451,1,1,0}-{2408,3437,1,1,0}-{2394,3500,1,1,0}-{2417,3483,1,1,0}-{2456,3425,0,1,0}-{2459,3421,0,1,0}-{2462,3431,0,1,0}-{2437,3478,0,1,0}-{2442,3465,0,1,0}-{2456,3467,0,1,0}-{2471,3496,0,1,0}-{2474,3508,0,1,0}-{2475,3471,0,1,0}-{2479,3468,0,1,0}-{2486,3470,0,1,0}-{2492,3474,0,1,0}-{2443,3464,1,1,0}-{2443,3502,1,1,0}-{2448,3496,1,1,0}-{2449,3506,1,1,0}-{2457,3498,1,1,0}-{2474,3498,1,1,0}-{2480,3502,1,1,0}-{2481,3482,1,1,0}-{2490,3503,1,1,0}-{2521,3169,0,1,0}-{2521,3171,0,1,0}-{2556,3226,0,1,0}-{2033,5530,1,1,0}-" }, { "npc_id": "68", - "loc_data": "{2518,3209,0,1,3}-{2533,3209,0,1,5}-{2530,3212,0,1,1}-" + "loc_data": "{2401,3357,0,1,0}-{2378,3423,0,1,0}-{2393,3435,0,1,0}-{2394,3425,0,1,0}-{2395,3449,0,1,0}-{2403,3433,0,1,0}-{2420,3429,0,1,0}-{2420,3438,0,1,0}-{2400,3514,1,1,0}-{2418,3485,1,1,0}-{2433,3474,0,1,0}-{2433,3492,0,1,0}-{2458,3497,0,1,0}-{2464,3505,0,1,0}-{2476,3458,0,1,0}-{2445,3502,1,1,0}-{2453,3488,1,1,0}-{2475,3502,1,1,0}-{2465,3490,2,1,0}-{2522,3172,0,1,0}-" }, { "npc_id": "73", @@ -325,11 +325,11 @@ }, { "npc_id": "100", - "loc_data": "{2567,3440,0,1,3}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-" + "loc_data": "{2567,3440,0,1,3}-{2316,9392,0,1,0}-{2319,9367,0,1,0}-{2321,9402,0,1,0}-{2322,9387,0,1,0}-{2325,9360,0,1,0}-{2333,9346,0,1,0}-{2335,9382,0,1,0}-{2337,9387,0,1,0}-{2343,9360,0,1,0}-{2344,9369,0,1,0}-{2348,9390,0,1,0}-{2349,9380,0,1,0}-{2349,9402,0,1,0}-{2359,9345,0,1,0}-{2359,9359,0,1,0}-{2359,9374,0,1,0}-{2359,9382,0,1,0}-{2363,9403,0,1,0}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-" }, { "npc_id": "101", - "loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-" + "loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2305,9385,0,1,0}-{2307,9359,0,1,0}-{2307,9403,0,1,0}-{2310,9396,0,1,0}-{2317,9371,0,1,0}-{2317,9383,0,1,0}-{2324,9404,0,1,0}-{2333,9366,0,1,0}-{2335,9393,0,1,0}-{2339,9403,0,1,0}-{2342,9347,0,1,0}-{2351,9359,0,1,0}-{2359,9392,0,1,0}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-" }, { "npc_id": "102", @@ -345,7 +345,7 @@ }, { "npc_id": "105", - "loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-" + "loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2387,3376,0,1,0}-{2398,3366,0,1,0}-{2412,3378,0,1,0}-{2419,3372,0,1,0}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-" }, { "npc_id": "106", @@ -365,11 +365,11 @@ }, { "npc_id": "110", - "loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3305,9400,0,1,1}-{3296,9378,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-" + "loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3244,9356,0,1,1}-{3252,9370,0,1,1}-{3305,9400,0,1,1}-{3294,9375,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-" }, { "npc_id": "111", - "loc_data": "{2920,3800,0,1,3}-{2952,3902,0,1,6}-{2953,3889,0,1,6}-{2947,3921,0,1,6}-{3043,9581,0,1,1}-{3055,9577,0,1,6}-{3061,9576,0,1,4}-{3055,9571,0,1,7}-{3052,9566,0,1,6}-" + "loc_data": "{2920,3800,0,1,3}-{2883,9932,0,1,0}-{2883,9965,0,1,0}-{2952,3902,0,1,6}-{2953,3889,0,1,6}-{2947,3921,0,1,6}-{2811,3506,0,1,0}-{3043,9581,0,1,1}-{3055,9577,0,1,6}-{3061,9576,0,1,4}-{3055,9571,0,1,7}-{3052,9566,0,1,6}-" }, { "npc_id": "112", @@ -389,7 +389,7 @@ }, { "npc_id": "117", - "loc_data": "{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2904,9734,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-" + "loc_data": "{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2369,3404,0,1,0}-{2904,9734,0,1,0}-{2439,3214,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-" }, { "npc_id": "118", @@ -417,7 +417,7 @@ }, { "npc_id": "125", - "loc_data": "{2845,3517,0,1,4}-{2848,3515,0,1,4}-{2958,3867,0,1,3}-{2956,3857,0,1,6}-{2952,3862,0,1,3}-{2949,3858,0,1,4}-{2955,3875,0,1,7}-{2954,3874,0,1,5}-{2962,3876,0,1,1}-{2961,3877,0,1,3}-{2947,3878,0,1,6}-{2959,3884,0,1,4}-{2956,3885,0,1,3}-{2956,3886,0,1,3}-{2948,3886,0,1,1}-{2947,3934,0,1,0}-{2948,3917,0,1,0}-{2949,3926,0,1,0}-{2952,3913,0,1,0}-{2952,3936,0,1,0}-{2954,3921,0,1,0}-{2956,3930,0,1,0}-{2964,3944,0,1,0}-{2970,3947,0,1,0}-{2971,3938,0,1,0}-{2977,3953,0,1,0}-{2978,3942,0,1,0}-{2984,3933,0,1,0}-{3227,5443,0,1,5}-{3220,5448,0,1,5}-{3208,5443,0,1,6}-{3207,5448,0,1,4}-{3050,9570,0,1,3}-{3043,9579,0,1,2}-{3056,9585,0,1,0}-{3058,9575,0,1,1}-{3052,9582,0,1,0}-{3049,9577,0,1,4}-{3042,9586,0,1,6}-{3052,9588,0,1,1}-{3049,9590,0,1,5}-{3060,9578,0,1,3}-{3054,9566,0,1,7}-" + "loc_data": "{2845,3517,0,1,4}-{2848,3515,0,1,4}-{2822,9901,0,1,0}-{2836,9905,0,1,0}-{2838,9917,0,1,0}-{2847,9919,0,1,0}-{2848,9912,0,1,0}-{2834,9940,0,1,0}-{2836,9953,0,1,0}-{2844,9944,0,1,0}-{2958,3867,0,1,3}-{2956,3857,0,1,6}-{2952,3862,0,1,3}-{2949,3858,0,1,4}-{2955,3875,0,1,7}-{2954,3874,0,1,5}-{2962,3876,0,1,1}-{2961,3877,0,1,3}-{2947,3878,0,1,6}-{2959,3884,0,1,4}-{2956,3885,0,1,3}-{2956,3886,0,1,3}-{2948,3886,0,1,1}-{2947,3934,0,1,0}-{2948,3917,0,1,0}-{2949,3926,0,1,0}-{2952,3913,0,1,0}-{2952,3936,0,1,0}-{2954,3921,0,1,0}-{2956,3930,0,1,0}-{2964,3944,0,1,0}-{2970,3947,0,1,0}-{2971,3938,0,1,0}-{2977,3953,0,1,0}-{2978,3942,0,1,0}-{2984,3933,0,1,0}-{3227,5443,0,1,5}-{3220,5448,0,1,5}-{3208,5443,0,1,6}-{3207,5448,0,1,4}-{3050,9570,0,1,3}-{3043,9579,0,1,2}-{3056,9585,0,1,0}-{3058,9575,0,1,1}-{3052,9582,0,1,0}-{3049,9577,0,1,4}-{3042,9586,0,1,6}-{3052,9588,0,1,1}-{3049,9590,0,1,5}-{3060,9578,0,1,3}-{3054,9566,0,1,7}-" }, { "npc_id": "126", @@ -471,6 +471,10 @@ "npc_id": "144", "loc_data": "{2842,3298,0,1,6}-{2844,3291,0,1,6}-{2851,3298,0,1,4}-{2855,3303,0,1,4}-{2859,3283,0,1,1}-{2861,3295,0,1,5}-{3075,3848,0,1,0}-{3090,3841,0,1,0}-{3070,3829,0,1,0}-{3070,3836,0,1,0}-{3040,9775,0,1,4}-{3048,9770,0,1,1}-" }, + { + "npc_id": "145", + "loc_data": "{2864,9950,0,1,0}-{2865,9951,0,1,0}-{2866,9948,0,1,0}-{2867,9948,0,1,0}-{2867,9951,0,1,0}-{2868,9950,0,1,0}-" + }, { "npc_id": "146", "loc_data": "{2827,3139,0,1,0}-{2896,2992,0,1,7}-{2976,3053,0,1,0}-{2985,3038,0,1,0}-{2994,3048,0,1,5}-{2992,3030,0,1,0}-" @@ -485,19 +489,39 @@ }, { "npc_id": "153", - "loc_data": "{2415,4466,0,0,0}-{2419,4427,0,0,0}-{2421,4468,0,0,0}-{2426,4431,0,0,0}-{2245,3147,0,1,4}-{2246,3143,0,1,0}-{2242,3140,0,1,3}-{2247,3149,0,1,1}-{2500,3492,0,1,4}-" + "loc_data": "{3082,3077,0,1,0}-{3092,3082,0,1,0}-{3109,3090,0,1,0}-{3112,3093,0,1,0}-{2324,4599,0,1,0}-{2325,4597,0,1,0}-{2326,4589,0,1,0}-{2326,4595,0,1,0}-{2327,4591,0,1,0}-{2327,4595,0,1,0}-{2328,4593,0,1,0}-{2329,4593,0,1,0}-{2332,4588,0,1,0}-{2828,5091,0,1,0}-{2832,5108,0,1,0}-{2835,5079,0,1,0}-{2846,5067,0,1,0}-{2850,5111,0,1,0}-{2853,5086,0,1,0}-{2864,5071,0,1,0}-{3175,3226,0,1,0}-{3178,3228,0,1,0}-{3179,3226,0,1,0}-{3182,3251,0,1,0}-{3183,3254,0,1,0}-{2416,3404,0,1,0}-{2424,3410,0,1,0}-{2430,3405,0,1,0}-{2415,4466,0,1,0}-{2419,4427,0,1,0}-{2421,4468,0,1,0}-{2426,4431,0,1,0}-{1906,5223,0,1,0}-{1907,5221,0,1,0}-{2196,3191,0,1,0}-{2197,3189,0,1,0}-{2198,3181,0,1,0}-{2198,3187,0,1,0}-{2199,3183,0,1,0}-{2199,3187,0,1,0}-{2200,3185,0,1,0}-{2201,3185,0,1,0}-{2204,3180,0,1,0}-{2176,3202,0,1,0}-{2178,3206,0,1,0}-{2180,3203,0,1,0}-{2180,3207,0,1,0}-{2207,3215,0,1,0}-{2212,3222,0,1,0}-{2213,3216,0,1,0}-{2216,3240,0,1,0}-{2216,3242,0,1,0}-{2218,3238,0,1,0}-{2218,3241,0,1,0}-{2220,3242,0,1,0}-{2222,3237,0,1,0}-{2478,3373,0,1,0}-{2479,3381,0,1,0}-{2481,3384,0,1,0}-{2490,3371,0,1,0}-{2437,3425,0,1,0}-{2438,3422,0,1,0}-{2450,3419,0,1,0}-{2464,4421,0,1,0}-{2466,4423,0,1,0}-{2486,4464,0,1,0}-{3200,5954,0,1,0}-{3202,5958,0,1,0}-{3204,5955,0,1,0}-{3204,5959,0,1,0}-{3231,5967,0,1,0}-{3236,5974,0,1,0}-{3237,5968,0,1,0}-{3240,5992,0,1,0}-{3240,5994,0,1,0}-{3242,5990,0,1,0}-{3242,5993,0,1,0}-{3244,5994,0,1,0}-{3246,5989,0,1,0}-{2689,6083,0,1,0}-{2689,6088,0,1,0}-{2690,6094,0,1,0}-{2691,6084,0,1,0}-{2692,6081,0,1,0}-{2692,6090,0,1,0}-{2693,6083,0,1,0}-{2693,6085,0,1,0}-{2693,6090,0,1,0}-{2694,6083,0,1,0}-{2694,6086,0,1,0}-{2695,6082,0,1,0}-{2695,6085,0,1,0}-{2695,6088,0,1,0}-{2695,6091,0,1,0}-{2695,6121,0,1,0}-{2698,6121,0,1,0}-{2699,6082,0,1,0}-{2699,6085,0,1,0}-{2700,6084,0,1,0}-{2701,6085,0,1,0}-{2702,6081,0,1,0}-{2702,6083,0,1,0}-{2703,6119,0,1,0}-{2704,6117,0,1,0}-{2705,6121,0,1,0}-{2730,6091,0,1,0}-{2732,6095,0,1,0}-{2734,6090,0,1,0}-{2735,6094,0,1,0}-{2735,6097,0,1,0}-{2738,6098,0,1,0}-{2697,6204,0,1,0}-{2698,6201,0,1,0}-{2698,6203,0,1,0}-{2700,6205,0,1,0}-{2701,6200,0,1,0}-{2710,6170,0,1,0}-{2712,6169,0,1,0}-{2714,6173,0,1,0}-{2716,6171,0,1,0}-{2717,6166,0,1,0}-{2717,6168,0,1,0}-{2718,6167,0,1,0}-{2718,6170,0,1,0}-{2549,3139,0,1,0}-{2241,3139,0,1,0}-{2241,3144,0,1,0}-{2242,3150,0,1,0}-{2243,3140,0,1,0}-{2244,3137,0,1,0}-{2244,3146,0,1,0}-{2245,3139,0,1,0}-{2245,3141,0,1,0}-{2245,3146,0,1,0}-{2246,3139,0,1,0}-{2246,3142,0,1,0}-{2247,3138,0,1,0}-{2247,3141,0,1,0}-{2247,3144,0,1,0}-{2247,3147,0,1,0}-{2247,3177,0,1,0}-{2250,3177,0,1,0}-{2251,3138,0,1,0}-{2251,3141,0,1,0}-{2252,3140,0,1,0}-{2253,3141,0,1,0}-{2254,3137,0,1,0}-{2254,3139,0,1,0}-{2255,3175,0,1,0}-{2256,3173,0,1,0}-{2257,3177,0,1,0}-{2282,3147,0,1,0}-{2284,3151,0,1,0}-{2286,3146,0,1,0}-{2287,3150,0,1,0}-{2287,3153,0,1,0}-{2290,3154,0,1,0}-{2249,3260,0,1,0}-{2250,3257,0,1,0}-{2250,3259,0,1,0}-{2252,3261,0,1,0}-{2253,3256,0,1,0}-{2262,3226,0,1,0}-{2264,3225,0,1,0}-{2266,3229,0,1,0}-{2268,3227,0,1,0}-{2269,3222,0,1,0}-{2269,3224,0,1,0}-{2270,3223,0,1,0}-{2270,3226,0,1,0}-{2556,3444,0,1,0}-{3273,6012,0,1,0}-{3274,6009,0,1,0}-{3274,6011,0,1,0}-{3276,6013,0,1,0}-{3277,6008,0,1,0}-{3286,5978,0,1,0}-{3288,5977,0,1,0}-{3290,5981,0,1,0}-{3292,5979,0,1,0}-{3293,5974,0,1,0}-{3293,5976,0,1,0}-{3294,5975,0,1,0}-{3294,5978,0,1,0}-{2540,9820,0,1,0}-{2543,9813,0,1,0}-{2546,9817,0,1,0}-" }, { "npc_id": "154", - "loc_data": "{2568,3470,0,1,5}-{2394,4453,0,0,0}-{2394,4457,0,0,0}-{2406,4447,0,0,0}-{2523,3164,0,1,4}-{2534,3173,0,1,3}-{2538,3160,0,1,3}-{2246,3144,0,1,4}-{2245,3147,0,1,4}-{2240,3147,0,1,3}-{2247,3142,0,1,5}-" + "loc_data": "{3125,3084,0,1,0}-{2308,4581,0,1,0}-{2321,4595,0,1,0}-{2324,4592,0,1,0}-{2328,4589,0,1,0}-{2328,4596,0,1,0}-{2331,4597,0,1,0}-{2831,5070,0,1,0}-{2843,5106,0,1,0}-{2844,5080,0,1,0}-{2860,5079,0,1,0}-{2866,5104,0,1,0}-{2868,5096,0,1,0}-{2378,3418,0,1,0}-{2380,3422,0,1,0}-{2393,3442,0,1,0}-{2397,3440,0,1,0}-{2423,3399,0,1,0}-{2425,3406,0,1,0}-{2427,3402,0,1,0}-{2422,3489,0,1,0}-{2394,4453,0,1,0}-{2394,4457,0,1,0}-{2406,4447,0,1,0}-{1908,5222,0,1,0}-{2180,3173,0,1,0}-{2193,3187,0,1,0}-{2196,3184,0,1,0}-{2200,3181,0,1,0}-{2200,3188,0,1,0}-{2203,3189,0,1,0}-{2178,3203,0,1,0}-{2182,3201,0,1,0}-{2207,3224,0,1,0}-{2209,3222,0,1,0}-{2211,3218,0,1,0}-{2217,3244,0,1,0}-{2218,3236,0,1,0}-{2220,3240,0,1,0}-{2446,3396,0,1,0}-{2470,3397,0,1,0}-{2475,4459,0,1,0}-{2480,4458,0,1,0}-{2481,4454,0,1,0}-{2488,4465,0,1,0}-{3202,5955,0,1,0}-{3206,5953,0,1,0}-{3231,5976,0,1,0}-{3233,5974,0,1,0}-{3235,5970,0,1,0}-{3241,5996,0,1,0}-{3242,5988,0,1,0}-{3244,5992,0,1,0}-{2688,6092,0,1,0}-{2690,6087,0,1,0}-{2690,6095,0,1,0}-{2692,6082,0,1,0}-{2692,6088,0,1,0}-{2692,6123,0,1,0}-{2693,6081,0,1,0}-{2694,6125,0,1,0}-{2695,6087,0,1,0}-{2697,6086,0,1,0}-{2697,6087,0,1,0}-{2698,6081,0,1,0}-{2698,6124,0,1,0}-{2700,6083,0,1,0}-{2702,6084,0,1,0}-{2726,6085,0,1,0}-{2727,6081,0,1,0}-{2729,6083,0,1,0}-{2732,6084,0,1,0}-{2716,6172,0,1,0}-{2240,3148,0,1,0}-{2242,3143,0,1,0}-{2242,3151,0,1,0}-{2244,3138,0,1,0}-{2244,3144,0,1,0}-{2244,3179,0,1,0}-{2245,3137,0,1,0}-{2246,3181,0,1,0}-{2247,3143,0,1,0}-{2249,3142,0,1,0}-{2249,3143,0,1,0}-{2250,3137,0,1,0}-{2250,3180,0,1,0}-{2252,3139,0,1,0}-{2254,3140,0,1,0}-{2278,3141,0,1,0}-{2279,3137,0,1,0}-{2281,3139,0,1,0}-{2284,3140,0,1,0}-{2268,3228,0,1,0}-{3292,5980,0,1,0}-" }, { "npc_id": "155", - "loc_data": "{2561,3471,0,1,0}-{3235,3222,0,0,0}-{3255,3226,0,0,0}-" + "loc_data": "{3093,3086,0,1,0}-{3097,3085,0,1,0}-{3129,3091,0,1,0}-{3135,3084,0,1,0}-{2318,4588,0,1,0}-{2374,3469,0,1,0}-{2376,3466,0,1,0}-{2190,3180,0,1,0}-{3254,3230,0,1,0}-{2434,3516,0,1,0}-{2479,3501,0,1,0}-{1986,5564,0,1,0}-" + }, + { + "npc_id": "156", + "loc_data": "{2371,3460,0,1,0}-{2372,3456,0,1,0}-{2422,3467,0,1,0}-{2444,3491,0,1,0}-{2725,6127,0,1,0}-{2277,3183,0,1,0}-" }, { "npc_id": "157", - "loc_data": "{2502,3521,0,1,5}-" + "loc_data": "{2104,2873,0,1,0}-{2102,2942,0,1,0}-{2108,2919,0,1,0}-{2326,2894,0,1,0}-{2333,2920,0,1,0}-{2314,2960,0,1,0}-{2110,2955,0,1,0}-{2322,4566,0,1,0}-{2344,4596,0,1,0}-{2345,4598,0,1,0}-{2348,4566,0,1,0}-{2350,4549,0,1,0}-{2357,4546,0,1,0}-{2359,4589,0,1,0}-{2364,4563,0,1,0}-{2050,5860,0,1,0}-{2056,5930,0,1,0}-{2064,5900,0,1,0}-{2092,5946,0,1,0}-{2086,6028,0,1,0}-{2153,2810,0,1,0}-{2172,2806,0,1,0}-{2113,2859,0,1,0}-{2139,2836,0,1,0}-{2147,2877,0,1,0}-{2165,2816,0,1,0}-{2167,2846,0,1,0}-{2123,2966,0,1,0}-{2175,2965,0,1,0}-{3143,3210,0,1,0}-{3155,3253,0,1,0}-{3163,3261,0,1,0}-{3168,3258,0,1,0}-{1912,5945,0,1,0}-{2134,5966,0,1,0}-{2141,5992,0,1,0}-{1910,6014,0,1,0}-{1916,5991,0,1,0}-{2122,6032,0,1,0}-{1918,6027,0,1,0}-{2180,2798,0,1,0}-{2209,2812,0,1,0}-{2217,2780,0,1,0}-{2182,2979,0,1,0}-{2211,2963,0,1,0}-{2194,3158,0,1,0}-{2216,3188,0,1,0}-{2217,3190,0,1,0}-{2220,3158,0,1,0}-{2222,3141,0,1,0}-{2229,3138,0,1,0}-{2231,3181,0,1,0}-{2236,3155,0,1,0}-{2177,3234,0,1,0}-{2230,3220,0,1,0}-{2231,3234,0,1,0}-{2232,3256,0,1,0}-{2233,3221,0,1,0}-{2233,3223,0,1,0}-{2236,3222,0,1,0}-{2237,3225,0,1,0}-{2238,3205,0,1,0}-{2479,3396,0,1,0}-{2447,3467,0,1,0}-{2448,3469,0,1,0}-{1961,5882,0,1,0}-{1980,5878,0,1,0}-{1921,5931,0,1,0}-{1947,5908,0,1,0}-{1955,5949,0,1,0}-{1973,5888,0,1,0}-{1975,5918,0,1,0}-{3201,5986,0,1,0}-{3254,5972,0,1,0}-{3255,5986,0,1,0}-{3256,6008,0,1,0}-{3257,5973,0,1,0}-{3257,5975,0,1,0}-{3260,5974,0,1,0}-{3261,5977,0,1,0}-{3262,5957,0,1,0}-{1931,6038,0,1,0}-{1983,6037,0,1,0}-{2723,6105,0,1,0}-{2739,6123,0,1,0}-{2744,6108,0,1,0}-{2703,6160,0,1,0}-{2710,6154,0,1,0}-{2719,6148,0,1,0}-{2742,6163,0,1,0}-{2744,6150,0,1,0}-{2746,6145,0,1,0}-{2242,2788,0,1,0}-{2248,2858,0,1,0}-{2256,2828,0,1,0}-{2284,2874,0,1,0}-{2278,2956,0,1,0}-{2540,3167,0,1,0}-{2275,3161,0,1,0}-{2291,3179,0,1,0}-{2296,3164,0,1,0}-{2255,3216,0,1,0}-{2262,3210,0,1,0}-{2271,3204,0,1,0}-{2294,3219,0,1,0}-{2296,3206,0,1,0}-{2298,3201,0,1,0}-{1988,5870,0,1,0}-{2017,5884,0,1,0}-{2025,5852,0,1,0}-{3279,5968,0,1,0}-{3286,5962,0,1,0}-{3295,5956,0,1,0}-{3318,5971,0,1,0}-{3320,5958,0,1,0}-{3322,5953,0,1,0}-{1990,6051,0,1,0}-{2019,6035,0,1,0}-" + }, + { + "npc_id": "158", + "loc_data": "{2693,9776,0,1,0}-{2697,9773,0,1,0}-{2697,9779,0,1,0}-{2700,9770,0,1,0}-{2700,9774,0,1,0}-{2700,9777,0,1,0}-{2701,9781,0,1,0}-{2703,9770,0,1,0}-{2703,9774,0,1,0}-{2703,9779,0,1,0}-{2705,9757,0,1,0}-{2705,9760,0,1,0}-{2705,9766,0,1,0}-{2706,9753,0,1,0}-{2706,9763,0,1,0}-{2706,9772,0,1,0}-{2707,9756,0,1,0}-{2707,9761,0,1,0}-{2708,9758,0,1,0}-" + }, + { + "npc_id": "159", + "loc_data": "{2413,3445,1,1,0}-{2415,3435,1,1,0}-{2416,3416,1,1,0}-{2424,3434,1,1,0}-{2392,3475,0,1,0}-{2394,3506,0,1,0}-{2396,3471,0,1,0}-{2405,3499,0,1,0}-{2416,3487,0,1,0}-{2483,3500,1,1,0}-" + }, + { + "npc_id": "160", + "loc_data": "{2424,3430,1,1,0}-{2474,3500,1,1,0}-" + }, + { + "npc_id": "161", + "loc_data": "{2409,3436,1,1,0}-{2484,3501,1,1,0}-" }, { "npc_id": "162", @@ -505,16 +529,32 @@ }, { "npc_id": "163", - "loc_data": "{2465,9899,0,1,6}-{2477,9896,0,1,6}-{2469,9887,0,1,6}-{2463,9893,0,1,6}-" + "loc_data": "{2392,3454,0,1,0}-{2394,3436,0,1,0}-{2408,3452,0,1,0}-{2421,3413,0,1,0}-{2409,3470,1,1,0}-{2416,3466,1,1,0}-{2420,3466,1,1,0}-{2459,3385,0,1,0}-{2463,3385,0,1,0}-{2451,3414,0,1,0}-{2459,3395,0,1,0}-{2459,3438,0,1,0}-{2462,3395,0,1,0}-{2445,3429,1,1,0}-{2442,3489,0,1,0}-{2450,3485,0,1,0}-{2451,3507,0,1,0}-{2453,3490,0,1,0}-{2459,3503,0,1,0}-{2461,3509,0,1,0}-{2464,3465,0,1,0}-{2464,3468,0,1,0}-{2468,3465,0,1,0}-{2468,3468,0,1,0}-{2468,3506,0,1,0}-{2472,3484,0,1,0}-{2475,3490,0,1,0}-{2475,3502,0,1,0}-{2477,3512,0,1,0}-{2481,3485,0,1,0}-{2482,3501,0,1,0}-{2467,3495,1,1,0}-{2473,3495,1,1,0}-{2448,3497,2,1,0}-{2463,3480,2,1,0}-{2465,3497,2,1,0}-{2465,3510,2,1,0}-{2466,3480,2,1,0}-{2461,9895,0,1,0}-{2465,9894,0,1,0}-{2465,9899,0,1,0}-" + }, + { + "npc_id": "164", + "loc_data": "{2410,3416,0,1,0}-{2420,3435,0,1,0}-{2420,3447,0,1,0}-{2427,3410,0,1,0}-{2460,3382,0,1,0}-{2462,3382,0,1,0}-{2459,3392,0,1,0}-{2461,3422,0,1,0}-{2462,3392,0,1,0}-{2441,3497,0,1,0}-{2447,3510,0,1,0}-{2461,3487,0,1,0}-{2464,3472,0,1,0}-{2464,3489,0,1,0}-{2467,3489,0,1,0}-{2468,3472,0,1,0}-{2473,3503,0,1,0}-{2478,3497,0,1,0}-{2464,3496,1,1,0}-{2448,3495,2,1,0}-{2460,3487,2,1,0}-{2467,3494,2,1,0}-{2467,3510,2,1,0}-{2471,3496,2,1,0}-{2483,3495,2,1,0}-{2483,3497,2,1,0}-{2012,5535,2,1,0}-{2023,5544,2,1,0}-" }, { "npc_id": "166", "loc_data": "{2448,3427,1,0,6}-{2448,3424,1,0,6}-{2443,3424,1,0,3}-{2443,3425,1,0,3}-{2450,3480,1,0,1}-{2449,3480,1,0,1}-{2448,3480,1,0,1}-{2440,3488,1,0,4}-{2440,3487,1,0,4}-" }, + { + "npc_id": "168", + "loc_data": "{2398,3451,1,1,0}-{2414,3447,1,1,0}-{2379,3482,0,1,0}-{2381,3496,0,1,0}-{2384,3497,0,1,0}-{2391,3476,0,1,0}-{2410,3496,0,1,0}-{2421,3481,0,1,0}-{2397,3514,1,1,0}-{2434,3436,0,1,0}-{2437,3451,0,1,0}-{2438,3427,0,1,0}-{2441,3411,0,1,0}-{2466,3449,0,1,0}-{2470,3399,0,1,0}-{2472,3400,0,1,0}-{2473,3412,0,1,0}-{2476,3454,0,1,0}-{2482,3397,0,1,0}-{2489,3401,0,1,0}-{2479,3407,1,1,0}-{2438,3465,0,1,0}-{2442,3505,0,1,0}-{2448,3486,0,1,0}-{2449,3487,0,1,0}-{2450,3489,0,1,0}-{2450,3505,0,1,0}-{2454,3465,0,1,0}-{2449,3486,1,1,0}-{2457,3488,1,1,0}-{2476,3488,1,1,0}-{2450,3496,2,1,0}-{2467,3488,2,1,0}-{2470,3503,2,1,0}-{2481,3498,2,1,0}-" + }, + { + "npc_id": "169", + "loc_data": "{2392,3450,1,1,0}-{2415,3415,1,1,0}-{2416,3434,1,1,0}-{2423,3425,1,1,0}-{2424,3442,1,1,0}-{2378,3482,0,1,0}-{2383,3496,0,1,0}-{2402,3507,0,1,0}-{2406,3476,0,1,0}-{2422,3485,0,1,0}-{2382,3506,1,1,0}-{2418,3472,1,1,0}-{2439,3433,0,1,0}-{2441,3449,0,1,0}-{2442,3428,0,1,0}-{2446,3403,0,1,0}-{2450,3416,0,1,0}-{2468,3441,0,1,0}-{2480,3408,0,1,0}-{2480,3406,1,1,0}-{2486,3400,1,1,0}-{2448,3489,0,1,0}-{2450,3488,0,1,0}-{2463,3508,0,1,0}-{2473,3489,0,1,0}-{2474,3457,0,1,0}-{2479,3503,0,1,0}-{2486,3467,0,1,0}-{2437,3463,1,1,0}-{2448,3489,1,1,0}-{2482,3508,1,1,0}-" + }, { "npc_id": "170", "loc_data": "{2890,3175,0,1,4}-" }, + { + "npc_id": "171", + "loc_data": "{2409,9817,0,1,0}-" + }, { "npc_id": "175", "loc_data": "{3084,3495,0,1,4}-{3179,3215,0,1,0}-{3182,3365,0,1,6}-{2994,9549,0,1,6}-{2993,9551,0,1,6}-{2995,9555,0,1,6}-{2999,9548,0,1,0}-" @@ -809,7 +849,7 @@ }, { "npc_id": "278", - "loc_data": "{3209,3215,0,0,0}-" + "loc_data": "{3209,3215,0,1,0}-" }, { "npc_id": "279", @@ -921,7 +961,7 @@ }, { "npc_id": "316", - "loc_data": "{3086,3227,0,0,1}-{3085,3230,0,0,0}-{2986,3176,0,0,4}-{2996,3157,0,0,1}-" + "loc_data": "{3086,3227,0,0,1}-{3085,3230,0,0,0}-{2986,3176,0,0,4}-{2996,3157,0,0,1}-{2790,3273,0,0,1}-{2790,3276,0,0,6}-{2794,3283,0,0,6}-{2795,3279,0,0,3}-" }, { "npc_id": "322", @@ -951,6 +991,10 @@ "npc_id": "334", "loc_data": "{2612,3411,0,0,0}-{2165,3268,0,0,4}-{2162,3274,0,0,4}-{2627,3415,0,0,0}-{2639,3698,0,0,4}-{2642,3698,0,0,4}-{2699,2702,0,0,4}-{2694,2706,0,0,4}-{2700,2702,0,0,4}-{2707,2698,0,0,4}-{2700,2702,0,0,0}-{2700,2702,0,0,0}-{2700,2702,0,0,0}-{2707,2698,0,0,0}-{2707,2698,0,0,0}-{2707,2698,0,0,0}-" }, + { + "npc_id": "335", + "loc_data": "{2592,3336,0,1,0}-" + }, { "npc_id": "336", "loc_data": "{2928,3218,0,1,4}-" @@ -973,19 +1017,23 @@ }, { "npc_id": "344", - "loc_data": "{3016,3187,1,1,0}-{3015,3183,1,1,0}-{3014,3181,1,1,0}-{3011,3185,1,1,0}-" + "loc_data": "{2510,3378,0,1,0}-{2511,3383,0,1,0}-{2515,3356,0,1,0}-{2519,3356,0,1,0}-{2521,3383,0,1,0}-{2524,3362,0,1,0}-{2525,3383,0,1,0}-" }, { "npc_id": "345", - "loc_data": "{3018,3185,2,1,0}-" + "loc_data": "{2519,3366,0,1,0}-{2525,3369,0,1,0}-{2531,3368,0,1,0}-" + }, + { + "npc_id": "346", + "loc_data": "{2508,3370,0,1,0}-{2512,3374,0,1,0}-{2518,3371,0,1,0}-{2525,3380,0,1,0}-" }, { "npc_id": "347", - "loc_data": "{2523,3292,0,1,0}-{2536,3294,0,1,0}-{2538,3321,0,1,0}-" + "loc_data": "{2524,3292,0,1,3}-{2536,3294,0,1,3}-{2538,3321,0,1,3}-" }, { "npc_id": "348", - "loc_data": "{2501,3315,0,1,0}-{2513,3325,0,1,0}-{2526,3279,0,1,0}-{2528,3297,0,1,0}-{2535,3288,0,1,0}-{2548,3287,0,1,0}-" + "loc_data": "{2501,3315,0,1,3}-{2513,3325,0,1,3}-{2526,3279,0,1,3}-{2528,3297,0,1,3}-{2535,3288,0,1,3}-{2548,3287,0,1,3}-" }, { "npc_id": "349", @@ -997,31 +1045,31 @@ }, { "npc_id": "351", - "loc_data": "{2507,3325,0,1,4}-" + "loc_data": "{2465,3307,0,1,0}-{2482,3293,0,1,0}-{2509,3325,0,1,0}-" }, { "npc_id": "352", - "loc_data": "{2511,3322,0,1,2}-{2540,3279,0,1,6}-" + "loc_data": "{2453,3307,0,1,0}-{2480,3300,0,1,0}-{2511,3322,0,1,0}-{2540,3279,0,1,0}-" }, { "npc_id": "353", - "loc_data": "{2504,3326,0,1,1}-{2509,3314,0,1,3}-{2545,3278,0,1,3}-" + "loc_data": "{2473,3288,0,1,0}-{2504,3326,0,1,0}-{2509,3314,0,1,0}-{2546,3277,0,1,0}-" }, { "npc_id": "354", - "loc_data": "{2510,3318,0,1,6}-{2524,3271,0,1,3}-" + "loc_data": "{2470,3290,0,1,0}-{2472,3296,0,1,0}-{2483,3318,0,1,0}-{2483,3323,0,1,0}-{2490,3293,0,1,0}-{2510,3318,0,1,0}-{2524,3271,0,1,0}-" }, { "npc_id": "355", - "loc_data": "{2504,3318,0,1,0}-" + "loc_data": "{2464,3302,0,1,0}-{2466,3300,0,1,0}-{2466,3307,0,1,0}-{2467,3306,0,1,0}-{2468,3315,0,1,0}-{2469,3319,0,1,0}-{2471,3323,0,1,0}-{2473,3305,0,1,0}-{2474,3296,0,1,0}-{2476,3307,0,1,0}-{2478,3323,0,1,0}-{2480,3296,0,1,0}-{2481,3313,0,1,0}-{2485,3312,0,1,0}-{2504,3318,0,1,0}-{2547,3277,0,1,0}-" }, { "npc_id": "356", - "loc_data": "{2523,3307,0,1,0}-" + "loc_data": "{2462,3306,0,1,0}-{2465,3305,0,1,0}-{2469,3295,0,1,0}-{2477,3320,0,1,0}-{2482,3311,0,1,0}-{2518,3275,0,1,0}-{2523,3307,0,1,0}-" }, { "npc_id": "357", - "loc_data": "{2518,3309,0,1,0}-{2526,3303,0,1,0}-{2543,3309,0,1,0}-{2550,3319,0,1,0}-{2552,3319,0,1,0}-" + "loc_data": "{2518,3309,0,1,3}-{2526,3303,0,1,3}-{2543,3309,0,1,3}-{2552,3320,0,1,3}-" }, { "npc_id": "358", @@ -1029,19 +1077,19 @@ }, { "npc_id": "360", - "loc_data": "{2550,3272,0,1,4}-" + "loc_data": "{2472,3307,0,1,0}-{2492,3314,0,1,0}-{2553,3275,0,1,0}-" }, { "npc_id": "361", - "loc_data": "{2519,3277,0,1,6}-" + "loc_data": "{2463,3317,0,1,0}-{2482,3296,0,1,0}-{2485,3315,0,1,0}-{2519,3277,0,1,0}-" }, { "npc_id": "362", - "loc_data": "{2537,3324,0,1,6}-" + "loc_data": "{2482,3286,0,1,0}-{2489,3295,0,1,0}-{2537,3324,0,1,0}-" }, { "npc_id": "363", - "loc_data": "{2513,3315,0,1,4}-" + "loc_data": "{2468,3290,0,1,0}-{2475,3325,0,1,0}-{2479,3312,0,1,0}-{2513,3315,0,1,0}-" }, { "npc_id": "364", @@ -1061,19 +1109,19 @@ }, { "npc_id": "369", - "loc_data": "{2542,3326,0,1,0}-{2545,3324,0,1,0}-{2545,3327,0,1,0}-{2552,3326,0,1,0}-{2553,3322,0,1,0}-{2553,3324,0,1,0}-" + "loc_data": "{2548,3324,0,1,3}-{2550,3326,0,1,3}-{2553,3325,0,1,3}-" }, { "npc_id": "370", - "loc_data": "{2551,3324,1,1,0}-{2551,3327,1,1,0}-" + "loc_data": "{2549,3325,1,1,0}-{2550,3327,1,1,0}-" }, { "npc_id": "371", - "loc_data": "{2547,3326,0,1,0}-{2549,3322,0,1,0}-{2550,3326,0,1,0}-{2552,3323,0,1,0}-" + "loc_data": "{2545,3326,0,1,3}-{2551,3322,0,1,3}-{2555,3324,0,1,3}-" }, { "npc_id": "372", - "loc_data": "{2561,3303,0,1,6}-{2561,3305,0,1,4}-{2559,3303,0,1,6}-{2559,3305,0,1,1}-" + "loc_data": "{2561,3305,0,1,2}-{2561,3303,0,1,7}-{2559,3304,0,1,3}-" }, { "npc_id": "373", @@ -1121,7 +1169,7 @@ }, { "npc_id": "385", - "loc_data": "{2549,3568,0,1,6}-" + "loc_data": "{2552,3570,0,1,6}-" }, { "npc_id": "386", @@ -1307,6 +1355,14 @@ "npc_id": "478", "loc_data": "{2509,3255,0,1,3}-{2503,3254,1,1,3}-" }, + { + "npc_id": "479", + "loc_data": "{2415,3433,3,1,0}-{2384,3481,0,1,0}-{2388,3473,0,1,0}-{2418,3474,3,1,0}-{2466,3500,2,1,0}-{1970,5522,3,1,0}-" + }, + { + "npc_id": "480", + "loc_data": "{2409,3507,0,1,0}-{2412,3474,3,1,0}-{2458,3417,1,1,0}-{2460,3417,1,1,0}-{2463,3504,2,1,0}-{1964,5522,3,1,0}-" + }, { "npc_id": "481", "loc_data": "{2499,3266,0,0,4}-" @@ -1331,6 +1387,10 @@ "npc_id": "490", "loc_data": "{1887,5026,0,0,6}-" }, + { + "npc_id": "492", + "loc_data": "{2464,3227,0,1,0}-" + }, { "npc_id": "494", "loc_data": "{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{2584,3418,0,0,4}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2807,3443,0,0,6}-{2810,3443,0,0,6}-" @@ -1567,6 +1627,10 @@ "npc_id": "560", "loc_data": "{2767,3122,0,1,6}-" }, + { + "npc_id": "561", + "loc_data": "{2514,3385,0,1,0}-" + }, { "npc_id": "562", "loc_data": "{2799,3438,0,1,1}-" @@ -1711,10 +1775,6 @@ "npc_id": "598", "loc_data": "{2943,3384,0,1,3}-" }, - { - "npc_id": "599", - "loc_data": "{2522,5001,0,0,4}-" - }, { "npc_id": "600", "loc_data": "{2449,3511,1,1,6}-" @@ -1987,14 +2047,42 @@ "npc_id": "694", "loc_data": "{2659,3431,0,0,3}-" }, + { + "npc_id": "695", + "loc_data": "{2765,3276,0,1,3}-" + }, { "npc_id": "696", "loc_data": "{2716,3303,0,1,1}-" }, + { + "npc_id": "697", + "loc_data": "{2766,3288,1,0,6}-" + }, { "npc_id": "698", + "loc_data": "{2799,3320,0,1,1}-" + }, + { + "npc_id": "700", "loc_data": "{2716,3303,0,1,1}-" }, + { + "npc_id": "701", + "loc_data": "{2793,3321,0,1,1}-" + }, + { + "npc_id": "702", + "loc_data": "{2774,3273,0,1,0}-{2775,3284,0,1,0}-{2781,3290,1,1,0}-{2785,3284,1,1,0}-" + }, + { + "npc_id": "703", + "loc_data": "{2770,3284,0,1,0}-{2794,3279,0,1,0}-{2768,3285,1,1,0}-{2784,3277,1,1,0}-" + }, + { + "npc_id": "704", + "loc_data": "{2778,3291,0,1,0}-{2773,3282,1,1,0}-{2787,3280,1,1,0}-" + }, { "npc_id": "705", "loc_data": "{3208,3252,0,0,6}-" @@ -2024,20 +2112,24 @@ "loc_data": "{2526,3319,0,0,6}-" }, { - "npc_id": "714", - "loc_data": "{2569,3333,0,1,0}-{2517,9755,0,1,0}-" + "npc_id": "715", + "loc_data": "{2541,9672,0,1,0}-" }, { "npc_id": "716", - "loc_data": "{2540,3286,0,0,1}-" + "loc_data": "{2542,3286,0,1,3}-" }, { "npc_id": "717", - "loc_data": "{2513,3294,0,1,0}-{2518,3320,0,1,0}-{2539,3273,0,0,1}-{2535,3296,0,1,0}-" + "loc_data": "{2513,3294,0,1,0}-{2518,3320,0,1,0}-{2530,3274,0,1,0}-{2535,3296,0,1,0}-" + }, + { + "npc_id": "718", + "loc_data": "{2582,3329,0,1,2}-" }, { "npc_id": "719", - "loc_data": "{2560,3288,0,0,0}-{2026,4619,0,1,6}-{2026,4615,0,0,6}-{2020,4614,0,1,1}-{2021,4614,0,1,6}-{2008,4612,0,1,3}-{2002,4613,0,1,4}-" + "loc_data": "{2560,3288,0,1,2}-" }, { "npc_id": "720", @@ -2065,11 +2157,11 @@ }, { "npc_id": "728", - "loc_data": "{2540,3308,0,1,6}-" + "loc_data": "{2540,3308,0,1,0}-" }, { "npc_id": "729", - "loc_data": "{2536,3308,0,1,4}-" + "loc_data": "{2536,3308,0,1,0}-" }, { "npc_id": "731", @@ -2193,15 +2285,15 @@ }, { "npc_id": "785", - "loc_data": "{2470,3312,0,1,0}-{2479,3315,0,1,0}-" + "loc_data": "{2468,3304,0,1,0}-{2476,3317,0,1,0}-{2478,3291,0,1,0}-{2492,3312,0,1,0}-" }, { "npc_id": "786", - "loc_data": "{2482,3313,0,1,0}-{2477,3311,0,1,0}-" + "loc_data": "{2469,3309,0,1,0}-{2475,3298,0,1,0}-{2487,3308,0,1,0}-{2490,3289,0,1,0}-" }, { "npc_id": "787", - "loc_data": "{2486,3315,0,1,0}-{2479,3313,0,1,0}-" + "loc_data": "{2476,3313,0,1,0}-{2481,3289,0,1,0}-{2490,3313,0,1,0}-{2491,3300,0,1,0}-" }, { "npc_id": "788", @@ -2209,11 +2301,11 @@ }, { "npc_id": "789", - "loc_data": "{2811,3167,0,0,0}-" + "loc_data": "{2811,3167,0,1,0}-" }, { "npc_id": "792", - "loc_data": "{2774,3197,0,0,0}-" + "loc_data": "{2774,3197,0,1,0}-" }, { "npc_id": "793", @@ -2223,6 +2315,10 @@ "npc_id": "794", "loc_data": "{2793,3191,0,1,3}-" }, + { + "npc_id": "795", + "loc_data": "{2866,9956,0,1,6}-" + }, { "npc_id": "796", "loc_data": "{2903,3511,0,1,3}-" @@ -2259,14 +2355,46 @@ "npc_id": "805", "loc_data": "{2936,3288,0,1,4}-" }, + { + "npc_id": "806", + "loc_data": "{2745,3576,1,0,4}-" + }, + { + "npc_id": "807", + "loc_data": "{2750,3576,0,0,4}-" + }, + { + "npc_id": "808", + "loc_data": "{2736,3575,0,1,1}-" + }, + { + "npc_id": "809", + "loc_data": "{2734,3581,0,1,1}-" + }, + { + "npc_id": "810", + "loc_data": "{2736,3576,1,1,1}-" + }, + { + "npc_id": "811", + "loc_data": "{2731,3579,0,1,4}-" + }, { "npc_id": "812", - "loc_data": "{2738,3473,0,0,1}-{2733,3473,0,0,1}-" + "loc_data": "{2741,3562,0,1,0}-" + }, + { + "npc_id": "813", + "loc_data": "{2741,3552,0,1,1}-" }, { "npc_id": "820", "loc_data": "{2697,3496,0,0,0}-" }, + { + "npc_id": "821", + "loc_data": "{2750,3580,0,1,0}-" + }, { "npc_id": "822", "loc_data": "{3302,9466,0,1,6}-" @@ -2309,7 +2437,11 @@ }, { "npc_id": "839", - "loc_data": "{3153,3035,0,1,3}-" + "loc_data": "{3150,3044,0,1,0}-{3172,3009,0,1,0}-{3197,3012,0,1,0}-{3198,3040,0,1,0}-{3237,2968,0,1,0}-{3224,3013,0,1,0}-{3225,3034,0,1,0}-{3226,3060,0,1,0}-{3250,3057,0,1,0}-{3217,3092,0,1,0}-{3235,3074,0,1,0}-{3252,3125,0,1,0}-{3258,3078,0,1,0}-{3265,3066,0,1,0}-{3267,3066,0,1,0}-{3310,3068,0,1,0}-{3322,3011,0,1,0}-{3322,3052,0,1,0}-{3324,3030,0,1,0}-{3283,3108,0,1,0}-{3323,3094,0,1,0}-" + }, + { + "npc_id": "840", + "loc_data": "{3190,3054,0,1,0}-{3192,3016,0,1,0}-{3237,3000,0,1,0}-{3245,2960,0,1,0}-{3208,3032,0,1,0}-{3217,3064,0,1,0}-{3238,3015,0,1,0}-{3258,3063,0,1,0}-{3217,3111,0,1,0}-{3222,3086,0,1,0}-{3238,3101,0,1,0}-{3244,3080,0,1,0}-{3253,3116,0,1,0}-{3255,3095,0,1,0}-{3268,3052,0,1,0}-{3281,3056,0,1,0}-{3307,3055,0,1,0}-{3318,3020,0,1,0}-{3318,3040,0,1,0}-{3267,3077,0,1,0}-{3269,3110,0,1,0}-{3275,3094,0,1,0}-{3291,3078,0,1,0}-{3291,3100,0,1,0}-{3305,3089,0,1,0}-{3318,3078,0,1,0}-{3321,3104,0,1,0}-" }, { "npc_id": "841", @@ -2441,7 +2573,11 @@ }, { "npc_id": "885", - "loc_data": "{2565,3271,0,0,0}-{2573,3268,1,0,0}-" + "loc_data": "{2565,3271,0,1,0}-{2573,3268,1,1,0}-" + }, + { + "npc_id": "886", + "loc_data": "{2567,9669,0,1,0}-" }, { "npc_id": "887", @@ -2449,15 +2585,27 @@ }, { "npc_id": "888", - "loc_data": "{2565,3273,0,0,0}-" + "loc_data": "{2565,3273,0,1,0}-" }, { "npc_id": "889", - "loc_data": "{2571,3270,0,0,0}-" + "loc_data": "{2571,3270,0,1,0}-" }, { "npc_id": "890", - "loc_data": "{2569,3272,0,0,0}-{2573,3269,1,0,0}-" + "loc_data": "{2569,3272,0,1,0}-{2573,3269,1,1,0}-" + }, + { + "npc_id": "891", + "loc_data": "{2609,9670,0,1,0}-" + }, + { + "npc_id": "893", + "loc_data": "{2567,9683,0,1,0}-" + }, + { + "npc_id": "894", + "loc_data": "{2609,9686,0,1,0}-{2607,9681,0,1,0}-{2609,9674,0,1,0}-{2608,9672,0,1,0}-{2604,9674,0,1,0}-{2605,9671,0,1,0}-" }, { "npc_id": "895", @@ -2619,10 +2767,18 @@ "npc_id": "970", "loc_data": "{3081,3247,0,0,1}-" }, + { + "npc_id": "971", + "loc_data": "{2464,3287,0,1,0}-" + }, { "npc_id": "1005", "loc_data": "{3057,3905,0,1,3}-" }, + { + "npc_id": "1006", + "loc_data": "{2763,3284,0,1,0}-{2768,3274,0,1,0}-{2768,3288,0,1,0}-{2770,3277,0,1,0}-{2770,3290,0,1,0}-{2771,3279,0,1,0}-{2774,3291,0,1,0}-{2778,3285,0,1,0}-{2781,3278,0,1,0}-{2781,3285,0,1,0}-{2783,3275,0,1,0}-{2784,3279,0,1,0}-{2785,3276,0,1,0}-{2785,3287,0,1,0}-{2788,3274,0,1,0}-{2793,3275,0,1,0}-{2793,3280,0,1,0}-{2768,3282,1,1,0}-{2770,3282,1,1,0}-{2773,3291,1,1,0}-{2780,3283,1,1,0}-{2780,3290,1,1,0}-{2783,3286,1,1,0}-{2784,3279,1,1,0}-{2785,3282,1,1,0}-" + }, { "npc_id": "1010", "loc_data": "{2629,2979,0,1,0}-" @@ -2641,7 +2797,7 @@ }, { "npc_id": "1017", - "loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-" + "loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{3198,3355,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-" }, { "npc_id": "1019", @@ -2673,11 +2829,11 @@ }, { "npc_id": "1038", - "loc_data": "{3507,3496,1,1,1}-{3508,3494,0,1,1}-" + "loc_data": "{3508,3494,0,1,1}-" }, { "npc_id": "1039", - "loc_data": "{3499,3506,1,1,5}-{3500,3505,0,1,5}-" + "loc_data": "{3500,3505,0,1,5}-" }, { "npc_id": "1040", @@ -2685,7 +2841,7 @@ }, { "npc_id": "1041", - "loc_data": "{3490,3503,1,0,0}-{3490,3500,0,1,4}-" + "loc_data": "{3490,3500,0,1,4}-" }, { "npc_id": "1042", @@ -2693,7 +2849,7 @@ }, { "npc_id": "1043", - "loc_data": "{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-" + "loc_data": "{2852,4561,0,0,0}-{2853,4566,0,0,0}-{2856,4568,0,0,0}-{2864,4561,0,0,0}-{2864,4563,0,0,0}-{3409,3369,0,0,0}-{3420,3349,0,0,0}-{3430,3340,0,0,0}-{3435,3330,0,0,0}-{3435,3359,0,0,0}-{3437,3374,0,0,0}-{3446,3385,0,0,0}-{3447,3388,0,0,0}-{3450,3370,0,0,0}-{3450,3387,0,0,0}-{3451,3336,0,0,0}-{3452,3355,0,0,0}-{3418,3420,0,0,0}-{3424,3452,0,0,0}-{3428,3409,0,0,0}-{3433,3416,0,0,0}-{3434,3394,0,0,0}-{3436,3407,0,0,0}-{3438,3414,0,0,0}-{3439,3449,0,0,0}-{3446,3439,0,0,0}-{3454,3410,0,0,0}-{3454,3423,0,0,0}-{3726,3289,0,0,0}-{3732,3291,0,0,0}-{3737,3280,0,0,0}-{3745,3285,0,0,0}-{3726,3381,0,0,0}-{3745,3359,0,0,0}-{3749,3365,0,0,0}-{3750,3354,0,0,0}-{3757,3363,0,0,0}-{3763,3337,0,0,0}-{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-" }, { "npc_id": "1044", @@ -3073,11 +3229,11 @@ }, { "npc_id": "1154", - "loc_data": "{3472,9501,2,1,3}-{3495,9494,2,1,4}-{3479,9484,2,1,1}-{3500,9477,2,1,6}-" + "loc_data": "{3472,9501,2,1,3}-{3495,9494,2,1,4}-{3479,9484,2,1,1}-{3500,9477,2,1,6}-{3470,9482,2,1,6}-{3465,9481,2,1,3}-{3465,9491,2,1,6}-{3468,9488,2,1,0}-" }, { "npc_id": "1155", - "loc_data": "{3468,9486,2,1,0}-{3467,9480,2,1,1}-{3505,9496,2,1,6}-{3513,9496,2,1,7}-" + "loc_data": "{3505,9496,2,1,6}-{3513,9496,2,1,7}-" }, { "npc_id": "1157", @@ -3204,9 +3360,17 @@ "loc_data": "{2194,3140,0,1,5}-" }, { - "npc_id": "1213", + "npc_id": "1211", "loc_data": "{2914,3418,0,0,6}-" }, + { + "npc_id": "1212", + "loc_data": "{2194,3189,0,0,0}-{2196,3187,0,0,0}-{2196,3189,0,0,0}-{2206,3164,0,0,0}-{2209,3164,0,0,0}-{2216,3142,0,0,0}-{2218,3139,0,0,0}-{2178,3238,0,0,0}-{2208,3225,0,0,0}-{2210,3217,0,0,0}-{2213,3243,0,0,0}-{2218,3245,0,0,0}-{2220,3243,0,0,0}-{2221,3243,0,0,0}-{3202,5990,0,0,0}-{3232,5977,0,0,0}-{3234,5969,0,0,0}-{3237,5995,0,0,0}-{3242,5997,0,0,0}-{3244,5995,0,0,0}-{3245,5995,0,0,0}-{2729,6086,0,0,0}-{2731,6080,0,0,0}-{2731,6089,0,0,0}-{2744,6139,0,0,0}-{2695,6170,0,0,0}-{2697,6171,0,0,0}-{2697,6202,0,0,0}-{2699,6204,0,0,0}-{2707,6155,0,0,0}-{2715,6167,0,0,0}-{2715,6169,0,0,0}-{2746,6206,0,0,0}-{2281,3142,0,0,0}-{2283,3136,0,0,0}-{2283,3145,0,0,0}-{2296,3195,0,0,0}-{2247,3226,0,0,0}-{2249,3227,0,0,0}-{2249,3258,0,0,0}-{2251,3260,0,0,0}-{2259,3211,0,0,0}-{2267,3223,0,0,0}-{2267,3225,0,0,0}-{2298,3262,0,0,0}-{3271,5978,0,0,0}-{3273,5979,0,0,0}-{3273,6010,0,0,0}-{3275,6012,0,0,0}-{3283,5963,0,0,0}-{3291,5975,0,0,0}-{3291,5977,0,0,0}-{3322,6014,0,0,0}-" + }, + { + "npc_id": "1213", + "loc_data": "{2192,3188,0,0,0}-{2192,3191,0,0,0}-{2194,3190,0,0,0}-{2208,3163,0,0,0}-{2209,3163,0,0,0}-{2216,3136,0,0,0}-{2216,3140,0,0,0}-{2180,3236,0,0,0}-{2208,3227,0,0,0}-{2210,3215,0,0,0}-{2210,3224,0,0,0}-{2214,3244,0,0,0}-{2215,3245,0,0,0}-{2219,3244,0,0,0}-{3204,5988,0,0,0}-{3232,5979,0,0,0}-{3234,5967,0,0,0}-{3234,5976,0,0,0}-{3238,5996,0,0,0}-{3239,5997,0,0,0}-{3243,5996,0,0,0}-{2730,6084,0,0,0}-{2696,6169,0,0,0}-{2696,6171,0,0,0}-{2699,6201,0,0,0}-{2701,6203,0,0,0}-{2716,6168,0,0,0}-{2739,6206,0,0,0}-{2282,3140,0,0,0}-{2248,3225,0,0,0}-{2248,3227,0,0,0}-{2251,3257,0,0,0}-{2253,3259,0,0,0}-{2268,3224,0,0,0}-{2291,3262,0,0,0}-{3272,5977,0,0,0}-{3272,5979,0,0,0}-{3275,6009,0,0,0}-{3277,6011,0,0,0}-{3292,5976,0,0,0}-{3315,6014,0,0,0}-" + }, { "npc_id": "1214", "loc_data": "{2891,3676,0,0,1}-" @@ -3241,7 +3405,7 @@ }, { "npc_id": "1227", - "loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3494,3388,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-" + "loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3426,3381,0,1,0}-{3418,3375,0,1,0}-{3414,3363,0,1,0}-{3411,3358,0,1,0}-{3441,3356,0,1,0}-{3424,3426,0,1,0}-{3414,3413,0,1,0}-{3421,3408,0,1,0}-{3422,3408,0,1,0}-{3440,3406,0,1,0}-{3412,3392,0,1,0}-{3494,3388,0,1,0}-{3467,3346,0,1,0}-{3465,3347,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3481,3446,0,1,0}-{3480,3445,0,1,0}-{3479,3443,0,1,0}-{3471,3433,0,1,0}-{3459,3432,0,1,0}-{3459,3426,0,1,0}-{3459,3418,0,1,0}-{3456,3415,0,1,0}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-{3563,3441,0,1,0}-{3544,3430,0,1,0}-{3540,3413,0,1,0}-{3529,3441,0,1,0}-" }, { "npc_id": "1228", @@ -3249,11 +3413,11 @@ }, { "npc_id": "1229", - "loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3492,3457,0,1,1}-" + "loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3427,3376,0,1,0}-{3420,3407,0,1,0}-{3425,3403,0,1,0}-{3438,3399,0,1,0}-{3446,3406,0,1,0}-{3420,3426,0,1,0}-{3477,3368,0,1,0}-{3479,3367,0,1,0}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3484,3443,0,1,0}-{3483,3442,0,1,0}-{3457,3416,0,1,0}-{3469,3402,0,1,0}-{3471,3401,0,1,0}-{3492,3457,0,1,1}-" }, { "npc_id": "1230", - "loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3496,3447,0,1,7}-{3520,3437,0,1,4}-" + "loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3476,3350,0,1,0}-{3496,3447,0,1,7}-{3481,3442,0,1,0}-{3520,3437,0,1,4}-" }, { "npc_id": "1231", @@ -3261,7 +3425,7 @@ }, { "npc_id": "1232", - "loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3525,3417,0,1,3}-" + "loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3411,3362,0,1,0}-{3415,3365,0,1,0}-{3415,3371,0,1,0}-{3413,3373,0,1,0}-{3431,3383,0,1,0}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3470,3400,0,1,0}-{3464,3405,0,1,0}-{3474,3417,0,1,0}-{3474,3419,0,1,0}-{3477,3419,0,1,0}-{3480,3441,0,1,0}-{3525,3417,0,1,3}-" }, { "npc_id": "1233", @@ -3269,7 +3433,7 @@ }, { "npc_id": "1234", - "loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3520,3412,0,1,0}-" + "loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3409,3387,0,1,0}-{3424,3377,0,1,0}-{3438,3351,0,1,0}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3461,3355,0,1,0}-{3473,3348,0,1,0}-{3477,3367,0,1,0}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3483,3444,0,1,0}-{3479,3423,0,1,0}-{3466,3408,0,1,0}-{3466,3407,0,1,0}-{3520,3412,0,1,0}-" }, { "npc_id": "1235", @@ -3627,6 +3791,10 @@ "npc_id": "1427", "loc_data": "{2957,3025,0,0,0}-" }, + { + "npc_id": "1433", + "loc_data": "{2770,2789,0,1,6}-" + }, { "npc_id": "1434", "loc_data": "{2753,2770,0,1,6}-" @@ -3704,7 +3872,7 @@ "loc_data": "{2443,3089,0,0,0}-" }, { - "npc_id": "1546", + "npc_id": "1544", "loc_data": "{2911,10175,0,0,4}-{2912,10175,0,0,4}-{2913,10175,0,0,4}-{2914,10175,0,0,4}-{2909,10173,0,0,4}-{2910,10173,0,0,4}-{2911,10173,0,0,4}-{2912,10173,0,0,4}-{2913,10173,0,0,4}-{2909,10171,0,0,4}-{2910,10171,0,0,4}-{2911,10169,0,0,4}-{2912,10169,0,0,4}-{2913,10169,0,0,4}-" }, { @@ -3765,7 +3933,7 @@ }, { "npc_id": "1585", - "loc_data": "{2575,9892,0,1,6}-{2666,9482,0,0,5}-{2641,9563,2,0,5}-{3257,5523,0,1,1}-{3204,5516,0,1,3}-" + "loc_data": "{2575,9892,0,1,6}-{2666,9482,0,0,5}-{2641,9563,2,0,5}-{3257,5523,0,1,1}-{3204,5516,0,1,3}-{3244,9369,0,1,3}-{3252,9359,0,1,3}-{3306,9400,0,1,3}-" }, { "npc_id": "1586", @@ -3913,7 +4081,7 @@ }, { "npc_id": "1633", - "loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-" + "loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3248,9374,0,1,3}-{3253,9363,0,1,3}-{3249,9355,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-" }, { "npc_id": "1634", @@ -4113,7 +4281,7 @@ }, { "npc_id": "1752", - "loc_data": "{2510,3228,0,1,3}-" + "loc_data": "{2381,3428,0,1,0}-{2392,3405,0,1,0}-{2413,3397,0,1,0}-{2415,3408,0,1,0}-{2432,3387,0,1,0}-{2442,3388,0,1,0}-{2453,3363,0,1,0}-{2463,3375,0,1,0}-{2437,3442,0,1,0}-{2449,3421,0,1,0}-{2457,3394,0,1,0}-{2464,3394,0,1,0}-{2480,3406,0,1,0}-{2463,3456,0,1,0}-{2468,3456,0,1,0}-" }, { "npc_id": "1754", @@ -4395,13 +4563,17 @@ "npc_id": "1873", "loc_data": "{3343,2962,0,1,0}-{3343,2964,0,1,1}-" }, + { + "npc_id": "1874", + "loc_data": "{3328,2952,0,1,0}-{3328,2957,0,1,0}-{3331,2955,0,1,0}-{3331,2961,0,1,0}-{3371,9301,0,1,0}-{3371,9303,0,1,0}-{3371,9305,0,1,0}-{3371,9307,0,1,0}-{3371,9309,0,1,0}-{3373,9301,0,1,0}-{3373,9303,0,1,0}-{3373,9306,0,1,0}-{3373,9308,0,1,0}-{3375,9301,0,1,0}-{3375,9303,0,1,0}-{3375,9305,0,1,0}-{3375,9307,0,1,0}-{3375,9309,0,1,0}-{3403,2963,0,1,0}-{3429,2976,0,1,0}-{3396,3029,0,1,0}-{3397,3044,0,1,0}-{3398,3038,0,1,0}-{3266,2955,0,1,0}-{3271,2967,0,1,0}-{3279,2957,0,1,0}-{3280,2975,0,1,0}-{3284,2959,0,1,0}-{3294,2964,0,1,0}-{3295,2978,0,1,0}-{3305,2966,0,1,0}-{3307,2959,0,1,0}-{3309,2973,0,1,0}-" + }, { "npc_id": "1875", "loc_data": "{3354,2952,0,0,1}-" }, { "npc_id": "1884", - "loc_data": "{2811,3174,0,0,0}-" + "loc_data": "{2811,3174,0,1,0}-" }, { "npc_id": "1902", @@ -4423,6 +4595,10 @@ "npc_id": "1912", "loc_data": "{3376,3429,0,1,6}-" }, + { + "npc_id": "1916", + "loc_data": "{3112,9690,0,0,7}-" + }, { "npc_id": "1917", "loc_data": "{3177,2987,0,1,6}-" @@ -4441,7 +4617,11 @@ }, { "npc_id": "1923", - "loc_data": "{3183,2974,0,0,7}-" + "loc_data": "{3185,2983,0,1,4}-" + }, + { + "npc_id": "1924", + "loc_data": "{3213,2956,0,1,1}-" }, { "npc_id": "1926", @@ -4463,6 +4643,10 @@ "npc_id": "1930", "loc_data": "{3161,2985,0,0,6}-{3161,2983,0,0,6}-{3161,2982,0,0,6}-{3161,2981,0,0,6}-{3161,2984,0,0,6}-" }, + { + "npc_id": "1932", + "loc_data": "{2836,3740,0,0,6}-" + }, { "npc_id": "1935", "loc_data": "{2841,3738,0,0,3}-" @@ -4495,6 +4679,22 @@ "npc_id": "1942", "loc_data": "{2855,3735,0,1,0}-{2858,3730,0,1,0}-{2865,3726,0,1,0}-" }, + { + "npc_id": "1943", + "loc_data": "{2825,3807,2,0,1}-" + }, + { + "npc_id": "1945", + "loc_data": "{2825,3811,2,0,6}-" + }, + { + "npc_id": "1947", + "loc_data": "{2835,3740,0,0,6}-" + }, + { + "npc_id": "1949", + "loc_data": "{2837,3740,0,0,6}-" + }, { "npc_id": "1951", "loc_data": "{2886,3723,0,1,3}-{2887,3720,0,1,4}-{2890,3721,0,1,7}-{2890,3724,0,1,1}-{2909,3736,0,1,5}-{2910,3736,0,1,2}-{2891,3724,0,1,7}-" @@ -4525,23 +4725,35 @@ }, { "npc_id": "1961", - "loc_data": "{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{3250,9326,0,1,4}-{3258,9327,0,1,6}-{3256,9333,0,1,1}-{3220,9309,0,1,4}-{3252,9333,0,1,3}-{3208,9318,0,1,3}-{3241,9331,0,1,6}-{3204,9328,0,1,3}-{3209,9328,0,1,3}-{3228,9323,0,1,4}-{3210,9282,0,1,7}-{3225,9329,0,1,6}-{3207,9299,0,1,4}-{3215,9295,0,1,3}-{3213,9322,0,1,3}-{3214,9315,0,1,0}-{3221,9291,0,1,0}-{3213,9303,0,1,4}-{3227,9304,0,1,6}-{3247,9301,0,1,1}-{3228,9284,0,1,3}-{3254,9286,0,1,4}-{3262,9291,0,1,6}-{3224,9302,0,1,3}-{3250,9298,0,1,3}-{3252,9293,0,1,6}-{3262,9299,0,1,1}-{3256,9297,0,1,7}-{3262,9285,0,1,1}-{3254,9322,0,1,0}-{3261,9318,0,1,4}-{3242,9316,0,1,6}-{3250,9306,0,1,3}-{3250,9327,0,1,3}-" + "loc_data": "{2832,4959,2,1,0}-{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{3201,9293,0,1,0}-{3205,9303,0,1,0}-{3206,9328,0,1,0}-{3207,9310,0,1,0}-{3211,9284,0,1,0}-{3220,9289,0,1,0}-{3224,9334,0,1,0}-{3249,9286,0,1,0}-{3251,9303,0,1,0}-{3252,9327,0,1,0}-{3252,9332,0,1,0}-{3255,9315,0,1,0}-{3261,9296,0,1,0}-{3261,9306,0,1,0}-{2764,4944,1,1,0}-{2796,4976,1,1,0}-{2798,4950,1,1,0}-{2806,4939,1,1,0}-" }, { "npc_id": "1962", - "loc_data": "{3168,5458,0,1,2}-{3242,9331,0,1,3}-{3238,9333,0,1,6}-{3261,9330,0,1,1}-{3232,9333,0,1,0}-{3222,9324,0,1,4}-{3205,9303,0,1,3}-" + "loc_data": "{2838,4948,2,1,0}-{2900,4948,3,1,0}-{3168,5458,0,1,2}-{3205,9329,0,1,0}-{3210,9292,0,1,0}-{3221,9310,0,1,0}-{3225,9323,0,1,0}-{3243,9310,0,1,0}-{3246,9290,0,1,0}-{3255,9301,0,1,0}-{3255,9321,0,1,0}-{3261,9331,0,1,0}-{2762,4962,1,1,0}-{2763,4973,1,1,0}-{2780,4977,1,1,0}-{2787,4967,1,1,0}-{2796,4959,1,1,0}-" }, { "npc_id": "1963", - "loc_data": "{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-" + "loc_data": "{2858,4964,2,1,0}-{2926,4965,3,1,0}-{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-{3204,9309,0,1,0}-{3214,9333,0,1,0}-{3219,9297,0,1,0}-{3239,9300,0,1,0}-{3240,9286,0,1,0}-{3240,9330,0,1,0}-{3245,9306,0,1,0}-{3250,9316,0,1,0}-{3250,9317,0,1,0}-{3257,9290,0,1,0}-{2771,4947,1,1,0}-{2775,4963,1,1,0}-{2781,4948,1,1,0}-{2792,4942,1,1,0}-{2798,4954,1,1,0}-" + }, + { + "npc_id": "1964", + "loc_data": "{2864,4946,2,1,0}-{3202,9283,0,1,0}-{3206,9333,0,1,0}-{3209,9299,0,1,0}-{3219,9301,0,1,0}-{3226,9285,0,1,0}-{3227,9303,0,1,0}-{3228,9293,0,1,0}-{3229,9333,0,1,0}-{3237,9293,0,1,0}-{3246,9321,0,1,0}-{3256,9296,0,1,0}-{3260,9285,0,1,0}-{3262,9317,0,1,0}-{2761,4950,1,1,0}-{2765,4938,1,1,0}-{2770,4955,1,1,0}-{2772,4940,1,1,0}-{2777,4943,1,1,0}-{2782,4967,1,1,0}-{2797,4965,1,1,0}-{2799,4937,1,1,0}-{2799,4941,1,1,0}-{2807,4968,1,1,0}-{2808,4975,1,1,0}-{2809,4953,1,1,0}-" + }, + { + "npc_id": "1970", + "loc_data": "{3233,9317,0,1,1}-" }, { "npc_id": "1972", "loc_data": "{2536,3426,0,1,0}-" }, + { + "npc_id": "1973", + "loc_data": "{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-" + }, { "npc_id": "1976", - "loc_data": "{3315,5508,0,1,5}-{3308,5510,0,1,3}-{3304,5507,0,1,4}-{3299,5509,0,1,3}-{3317,5514,0,1,3}-{3319,5518,0,1,4}-{3320,5507,0,1,4}-{3324,5513,0,1,1}-{3283,5510,0,1,5}-{3320,5550,0,1,0}-{3313,5523,0,1,4}-{3310,5541,0,1,4}-{3308,5535,0,1,5}-{3301,5531,0,1,4}-{3315,5530,0,1,1}-{3322,5536,0,1,4}-{3320,5539,0,1,7}-{3311,5519,0,1,3}-{3289,5525,0,1,2}-{3300,5519,0,1,6}-{3289,5515,0,1,7}-{3287,5523,0,1,3}-" + "loc_data": "{2694,5067,0,1,0}-{2717,5081,0,1,0}-{2718,5108,0,1,0}-{2721,5104,0,1,0}-{2726,5091,0,1,0}-{2731,5060,0,1,0}-{2732,5073,0,1,0}-{2740,5083,0,1,0}-{2742,5103,0,1,0}-{2747,5094,0,1,0}-{3315,5508,0,1,5}-{3308,5510,0,1,3}-{3304,5507,0,1,4}-{3299,5509,0,1,3}-{3317,5514,0,1,3}-{3319,5518,0,1,4}-{3320,5507,0,1,4}-{3324,5513,0,1,1}-{3283,5510,0,1,5}-{3320,5550,0,1,0}-{3313,5523,0,1,4}-{3310,5541,0,1,4}-{3308,5535,0,1,5}-{3301,5531,0,1,4}-{3315,5530,0,1,1}-{3322,5536,0,1,4}-{3320,5539,0,1,7}-{3311,5519,0,1,3}-{3289,5525,0,1,2}-{3300,5519,0,1,6}-{3289,5515,0,1,7}-{3287,5523,0,1,3}-" }, { "npc_id": "1990", @@ -4549,11 +4761,43 @@ }, { "npc_id": "1993", - "loc_data": "{3360,2935,0,1,4}-{3359,2924,0,1,6}-{3352,2936,0,1,0}-{3349,2931,0,1,6}-{3341,2924,0,1,4}-" + "loc_data": "{3337,2922,0,1,0}-{3343,2931,0,1,0}-{3349,2922,0,1,0}-{3351,2927,0,1,0}-{3357,2922,0,1,0}-{3359,2927,0,1,0}-{3364,2937,0,1,0}-{3258,2868,0,1,0}-{3259,2823,0,1,0}-{3259,2845,0,1,0}-{3260,2830,0,1,0}-{3260,2859,0,1,0}-{3261,2819,0,1,0}-{3261,2851,0,1,0}-{3268,2854,0,1,0}-{3269,2827,0,1,0}-{3269,2866,0,1,0}-{3269,2875,0,1,0}-{3270,2818,0,1,0}-{3272,2841,0,1,0}-{3276,2842,0,1,0}-{3282,2839,0,1,0}-{3290,2847,0,1,0}-{3264,2886,0,1,0}-{3267,2891,0,1,0}-{3268,2881,0,1,0}-{3269,2885,0,1,0}-{3296,2912,0,1,0}-{3297,2919,0,1,0}-{3301,2920,0,1,0}-{3308,2916,0,1,0}-" }, { "npc_id": "1994", - "loc_data": "{3344,2933,0,1,3}-{3350,2936,0,1,4}-" + "loc_data": "{3329,2933,0,1,0}-{3330,2931,0,1,0}-{3331,2933,0,1,0}-{3343,2895,0,1,0}-{3345,2896,0,1,0}-{3346,2894,0,1,0}-{3348,2894,0,1,0}-{3376,2934,0,1,0}-{3378,2933,0,1,0}-{3378,2935,0,1,0}-{3381,2907,0,1,0}-{3383,2905,0,1,0}-{3383,2908,0,1,0}-{3384,2907,0,1,0}-{3400,2997,0,1,0}-{3402,2999,0,1,0}-{3403,2997,0,1,0}-{3445,2993,0,1,0}-{3446,2992,0,1,0}-{3448,2991,0,1,0}-{3448,2994,0,1,0}-{3406,3014,0,1,0}-{3408,3013,0,1,0}-{3408,3016,0,1,0}-{3410,3015,0,1,0}-{3212,2863,0,1,0}-{3213,2866,0,1,0}-{3215,2863,0,1,0}-{3216,2865,0,1,0}-{3216,2868,0,1,0}-{3218,2831,0,1,0}-{3220,2830,0,1,0}-{3220,2833,0,1,0}-{3221,2831,0,1,0}-{3238,2845,0,1,0}-{3240,2845,0,1,0}-{3241,2843,0,1,0}-{3241,2847,0,1,0}-{3306,2817,0,1,0}-{3308,2818,0,1,0}-{3309,2816,0,1,0}-{3312,2817,0,1,0}-{3314,2861,0,1,0}-{3319,2873,0,1,0}-{3321,2871,0,1,0}-{3324,2870,0,1,0}-{3327,2858,0,1,0}-{3265,2931,0,1,0}-{3265,2935,0,1,0}-{3268,2932,0,1,0}-{3268,2935,0,1,0}-{3316,2900,0,1,0}-{3319,2897,0,1,0}-{3320,2901,0,1,0}-{3321,2899,0,1,0}-" + }, + { + "npc_id": "1995", + "loc_data": "{3309,2806,0,1,0}-{3312,2806,0,1,0}-{3314,2752,0,1,0}-{3314,2806,0,1,0}-{3315,2805,0,1,0}-{3316,2780,0,1,0}-{3316,2795,0,1,0}-{3317,2752,0,1,0}-{3317,2762,0,1,0}-{3317,2763,0,1,0}-{3317,2779,0,1,0}-{3317,2794,0,1,0}-{3318,2761,0,1,0}-{3318,2778,0,1,0}-{3318,2781,0,1,0}-{3318,2794,0,1,0}-{3318,2795,0,1,0}-{3319,2760,0,1,0}-{3319,2763,0,1,0}-" + }, + { + "npc_id": "1997", + "loc_data": "{3272,2802,0,1,0}-{3273,2802,0,1,0}-{3273,2805,0,1,0}-{3274,2798,0,1,0}-{3274,2799,0,1,0}-{3274,2802,0,1,0}-{3274,2804,0,1,0}-{3275,2795,0,1,0}-{3275,2796,0,1,0}-{3275,2798,0,1,0}-{3277,2752,0,1,0}-{3277,2753,0,1,0}-{3277,2756,0,1,0}-{3277,2757,0,1,0}-{3278,2752,0,1,0}-{3278,2753,0,1,0}-{3278,2754,0,1,0}-{3278,2755,0,1,0}-" + }, + { + "npc_id": "1998", + "loc_data": "{3275,2803,0,1,0}-" + }, + { + "npc_id": "1999", + "loc_data": "{3278,2804,0,1,0}-" + }, + { + "npc_id": "2000", + "loc_data": "{3277,2802,0,1,0}-" + }, + { + "npc_id": "2002", + "loc_data": "{3315,2849,0,1,0}-" + }, + { + "npc_id": "2003", + "loc_data": "{3304,9196,0,1,0}-" + }, + { + "npc_id": "2004", + "loc_data": "{3304,9195,0,1,0}-" }, { "npc_id": "2014", @@ -4565,7 +4809,7 @@ }, { "npc_id": "2021", - "loc_data": "{3222,9525,2,1,3}-{3216,9522,2,1,3}-{3219,9518,2,1,3}-{3224,9521,2,1,3}-{3218,9523,2,1,3}-{3215,9521,2,1,3}-{3213,9522,2,1,3}-{3227,9517,2,1,3}-" + "loc_data": "{3224,9516,2,1,0}-{3224,9517,2,1,0}-{3224,9518,2,1,0}-{3225,9516,2,1,0}-{3225,9517,2,1,0}-{3225,9518,2,1,0}-{3226,9516,2,1,0}-{3226,9517,2,1,0}-{3226,9518,2,1,0}-" }, { "npc_id": "2031", @@ -4621,15 +4865,27 @@ }, { "npc_id": "2044", - "loc_data": "{2486,3048,0,1,3}-" + "loc_data": "{2486,3048,0,1,3}-{2484,9392,2,1,0}-{2465,9454,2,1,0}-{2471,9422,2,1,0}-{2448,9442,2,1,0}-" }, { "npc_id": "2045", - "loc_data": "{2482,3046,0,1,3}-" + "loc_data": "{2482,3046,0,1,3}-{2459,9394,2,1,0}-{2473,9430,2,1,0}-{2478,9442,2,1,0}-{2487,9455,2,1,0}-" + }, + { + "npc_id": "2046", + "loc_data": "{2466,9389,2,1,0}-{2449,9429,0,1,0}-{2436,9452,2,1,0}-{2436,9465,2,1,0}-{2450,9460,2,1,0}-{2455,9440,2,1,0}-{2473,9439,2,1,0}-{2483,9408,2,1,0}-" }, { "npc_id": "2047", - "loc_data": "{2480,3046,0,1,3}-" + "loc_data": "{2480,3046,0,1,3}-{2477,9384,2,1,0}-{2449,9434,0,1,0}-{2437,9429,2,1,0}-{2440,9438,2,1,0}-{2458,9408,2,1,0}-" + }, + { + "npc_id": "2048", + "loc_data": "{2485,9398,2,1,0}-{2455,9435,0,1,0}-{2457,9420,2,1,0}-{2462,9431,2,1,0}-{2482,9422,2,1,0}-" + }, + { + "npc_id": "2049", + "loc_data": "{2452,9440,0,1,0}-" }, { "npc_id": "2050", @@ -4659,6 +4915,14 @@ "npc_id": "2056", "loc_data": "{2470,3040,0,0,0}-" }, + { + "npc_id": "2057", + "loc_data": "{2480,3046,0,1,0}-{2453,9393,2,1,0}-{2461,9403,2,1,0}-{2464,9380,2,1,0}-{2442,9436,2,1,0}-{2458,9413,2,1,0}-{2470,9435,2,1,0}-{2472,9460,2,1,0}-{2483,9413,2,1,0}-{2485,9447,2,1,0}-" + }, + { + "npc_id": "2058", + "loc_data": "{3161,9547,0,0,7}-{3164,9556,0,0,7}-{3162,9574,0,0,7}-{3198,9554,0,0,7}-{3198,9572,0,0,7}-{3215,9560,0,0,7}-{3216,9588,0,0,7}-" + }, { "npc_id": "2059", "loc_data": "{2588,3088,0,1,3}-" @@ -5043,6 +5307,10 @@ "npc_id": "2237", "loc_data": "{3249,3266,0,1,5}-" }, + { + "npc_id": "2238", + "loc_data": "{3219,3247,0,1,6}-" + }, { "npc_id": "2240", "loc_data": "{3077,3259,0,1,4}-" @@ -5121,7 +5389,7 @@ }, { "npc_id": "2265", - "loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3016,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-" + "loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3017,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-" }, { "npc_id": "2266", @@ -5167,6 +5435,34 @@ "npc_id": "2281", "loc_data": "{3187,3241,0,1,0}-{3177,3243,0,1,0}-{3246,3245,0,1,4}-" }, + { + "npc_id": "2282", + "loc_data": "{2488,4973,0,0,6}-" + }, + { + "npc_id": "2283", + "loc_data": "{2458,4980,0,0,6}-" + }, + { + "npc_id": "2284", + "loc_data": "{2457,4966,0,0,6}-" + }, + { + "npc_id": "2286", + "loc_data": "{2476,4958,0,0,3}-" + }, + { + "npc_id": "2287", + "loc_data": "{2443,4956,0,0,4}-" + }, + { + "npc_id": "2288", + "loc_data": "{2469,4941,0,0,6}-" + }, + { + "npc_id": "2289", + "loc_data": "{2451,4939,0,0,6}-" + }, { "npc_id": "2290", "loc_data": "{2997,3373,0,0,0}-" @@ -5189,16 +5485,24 @@ }, { "npc_id": "2296", - "loc_data": "{3399,2916,0,0,6}-" + "loc_data": "{3401,2918,0,0,6}-" }, { "npc_id": "2298", "loc_data": "{3287,2813,0,1,1}-" }, + { + "npc_id": "2300", + "loc_data": "{3243,2813,0,0,1}-" + }, { "npc_id": "2301", "loc_data": "{3181,3043,0,1,3}-{3310,3107,0,1,4}-" }, + { + "npc_id": "2302", + "loc_data": "{3243,2812,0,1,1}-" + }, { "npc_id": "2304", "loc_data": "{3039,3292,0,1,6}-" @@ -5259,6 +5563,10 @@ "npc_id": "2321", "loc_data": "{2915,10194,1,1,0}-" }, + { + "npc_id": "2322", + "loc_data": "{3679,9957,0,1,1}-" + }, { "npc_id": "2323", "loc_data": "{3056,3306,0,1,1}-" @@ -5301,7 +5609,7 @@ }, { "npc_id": "2335", - "loc_data": "{3181,3359,0,0,0}-" + "loc_data": "{3181,3359,0,1,0}-" }, { "npc_id": "2336", @@ -5377,27 +5685,79 @@ }, { "npc_id": "2372", - "loc_data": "{2044,4632,0,1,3}-" + "loc_data": "{2044,4628,0,1,0}-" + }, + { + "npc_id": "2373", + "loc_data": "{2037,4636,0,1,0}-{2038,4644,0,1,0}-{2041,4638,0,1,0}-{2044,4642,0,1,0}-" }, { "npc_id": "2374", - "loc_data": "{2041,4632,0,1,3}-{2037,4630,0,1,3}-{2041,4644,0,1,4}-" + "loc_data": "{2036,4633,0,0,6}-" + }, + { + "npc_id": "2381", + "loc_data": "{2555,3444,0,1,0}-" + }, + { + "npc_id": "2382", + "loc_data": "{3022,3946,0,1,0}-" + }, + { + "npc_id": "2383", + "loc_data": "{3034,3701,0,1,0}-" + }, + { + "npc_id": "2384", + "loc_data": "{3162,2982,0,1,0}-" }, { "npc_id": "2385", - "loc_data": "{3112,3159,0,0,0}-" + "loc_data": "{3112,3158,0,1,0}-" }, { "npc_id": "2386", - "loc_data": "{3051,3496,1,0,0}-" + "loc_data": "{3052,3496,1,1,0}-" + }, + { + "npc_id": "2387", + "loc_data": "{3053,3378,1,1,0}-" + }, + { + "npc_id": "2388", + "loc_data": "{2950,3820,0,1,0}-" }, { "npc_id": "2389", - "loc_data": "{3219,3677,0,0,0}-" + "loc_data": "{3218,3677,0,1,0}-" + }, + { + "npc_id": "2390", + "loc_data": "{3068,3858,0,1,0}-" + }, + { + "npc_id": "2391", + "loc_data": "{2850,3348,0,1,0}-" }, { "npc_id": "2392", - "loc_data": "{3043,3204,0,0,0}-" + "loc_data": "{3044,3204,0,1,0}-" + }, + { + "npc_id": "2393", + "loc_data": "{2396,3481,0,1,0}-" + }, + { + "npc_id": "2394", + "loc_data": "{3294,3934,1,1,0}-" + }, + { + "npc_id": "2395", + "loc_data": "{3448,3550,1,1,0}-" + }, + { + "npc_id": "2396", + "loc_data": "{3119,9996,0,1,0}-" }, { "npc_id": "2414", @@ -5471,6 +5831,10 @@ "npc_id": "2462", "loc_data": "{2596,4773,0,1,2}-{2602,4771,0,1,6}-{2596,4780,0,1,4}-" }, + { + "npc_id": "2477", + "loc_data": "{1952,4768,1,0,6}-" + }, { "npc_id": "2479", "loc_data": "{3420,4777,0,0,0}-" @@ -5499,14 +5863,6 @@ "npc_id": "2488", "loc_data": "{2799,3058,0,0,0}-" }, - { - "npc_id": "2489", - "loc_data": "{3703,3040,0,1,3}-{3706,3051,0,1,1}-{3664,3013,0,1,7}-{3749,3000,0,1,6}-{3723,2998,0,1,2}-{3731,2991,0,1,1}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-" - }, - { - "npc_id": "2490", - "loc_data": "{3782,3016,0,1,7}-" - }, { "npc_id": "2491", "loc_data": "{2679,3080,0,1,6}-{2684,3084,0,1,4}-{2682,3093,0,1,4}-{2678,3095,0,1,3}-{2679,3102,0,1,1}-{2681,3110,0,1,4}-{2683,3115,0,1,6}-{2675,3108,0,1,3}-{2671,3109,0,1,3}-{2671,3113,0,1,4}-{2676,3090,0,1,4}-{2670,3088,0,1,6}-{2671,3086,0,1,6}-{2664,3088,0,1,7}-{2660,3086,0,1,6}-{2662,3088,0,1,6}-{2670,3082,0,1,7}-{2674,3081,0,1,3}-{2663,3086,0,1,6}-{2679,3082,0,1,1}-{2682,3093,0,1,3}-" @@ -5829,19 +6185,31 @@ }, { "npc_id": "2699", - "loc_data": "{3037,2982,0,0,6}-{3036,2979,0,0,6}-" + "loc_data": "{3016,3184,1,1,0}-" }, { "npc_id": "2700", - "loc_data": "{3037,2982,0,0,6}-" + "loc_data": "{3016,3182,1,1,0}-" + }, + { + "npc_id": "2701", + "loc_data": "{3011,3181,1,1,0}-" + }, + { + "npc_id": "2702", + "loc_data": "{3019,3180,1,1,0}-" + }, + { + "npc_id": "2703", + "loc_data": "{3012,3185,1,1,0}-" }, { "npc_id": "2704", - "loc_data": "{3034,2979,0,0,1}-{3033,2980,1,0,4}-{3032,2979,0,0,1}-{3034,2985,0,0,1}-{3035,2982,0,0,1}-{3019,3185,0,0,0}-" + "loc_data": "{3019,3185,0,0,0}-" }, { "npc_id": "2705", - "loc_data": "{3034,2985,1,0,1}-" + "loc_data": "{3018,3185,2,1,0}-" }, { "npc_id": "2706", @@ -5913,7 +6281,23 @@ }, { "npc_id": "2783", - "loc_data": "{1995,4660,0,1,7}-{1989,4660,0,1,0}-{1989,4664,0,1,7}-{1995,4660,0,1,2}-{1997,4664,0,1,3}-{1989,4658,0,1,0}-{2001,4646,0,1,4}-{2000,4645,0,1,3}-{1997,4644,0,1,1}-{2006,4639,0,1,6}-{1999,4636,0,1,3}-" + "loc_data": "{1995,4660,0,1,7}-{1989,4660,0,1,0}-{1989,4664,0,1,7}-{1997,4664,0,1,3}-{1989,4658,0,1,0}-{2001,4646,0,1,4}-{2000,4645,0,1,3}-{1997,4644,0,1,1}-{1999,4636,0,1,3}-{2022,4665,0,1,0}-{2024,4662,0,1,0}-{2020,4660,0,1,0}-{2023,4656,0,1,0}-{2029,4660,0,1,0}-{2031,4665,0,1,0}-{2034,4661,0,1,0}-{2032,4658,0,1,0}-{1991,4653,0,1,0}-{1995,4651,0,1,0}-" + }, + { + "npc_id": "2784", + "loc_data": "{2022,4616,0,1,5}-{2024,4620,0,1,5}-" + }, + { + "npc_id": "2785", + "loc_data": "{2000,4613,0,0,0}-{2000,4611,0,0,5}-" + }, + { + "npc_id": "2786", + "loc_data": "{2008,4613,0,1,0}-" + }, + { + "npc_id": "2787", + "loc_data": "{2023,4612,0,1,0}-" }, { "npc_id": "2790", @@ -5927,6 +6311,10 @@ "npc_id": "2794", "loc_data": "{2606,3100,0,0,0}-" }, + { + "npc_id": "2795", + "loc_data": "{2979,3197,0,1,0}-" + }, { "npc_id": "2796", "loc_data": "{3096,3108,0,0,6}-" @@ -5935,9 +6323,17 @@ "npc_id": "2800", "loc_data": "{2981,3190,0,0,0}-" }, + { + "npc_id": "2801", + "loc_data": "{2523,3373,0,1,0}-{2523,3376,0,1,0}-{2526,3373,0,1,0}-{2526,3376,0,1,0}-{2529,3373,0,1,0}-{2529,3376,0,1,0}-{2531,3376,0,1,0}-{2532,3373,0,1,0}-" + }, + { + "npc_id": "2802", + "loc_data": "{2406,3498,0,1,0}-" + }, { "npc_id": "2803", - "loc_data": "{3391,3066,0,1,6}-{3397,3054,0,1,6}-{3398,3060,0,1,0}-{3412,3059,0,1,3}-" + "loc_data": "{3338,2804,0,1,0}-{3339,2815,0,1,0}-{3342,2809,0,1,0}-{3344,2800,0,1,0}-{3348,2809,0,1,0}-{3349,2814,0,1,0}-{3357,2813,0,1,0}-{3357,2806,0,1,0}-{3365,2815,0,1,0}-{3387,3068,0,1,0}-{3387,3017,0,1,0}-{3404,3062,0,1,0}-{3441,3061,0,1,0}-{3445,3034,0,1,0}-" }, { "npc_id": "2804", @@ -5953,11 +6349,11 @@ }, { "npc_id": "2807", - "loc_data": "{3414,3045,0,1,1}-{3403,3050,0,1,4}-{3407,3058,0,1,3}-{3420,3022,0,0,0}-" + "loc_data": "{3384,3013,0,1,0}-{3387,3014,0,1,0}-{3441,3059,0,1,0}-{3443,3033,0,1,0}-{3443,3059,0,1,0}-" }, { "npc_id": "2808", - "loc_data": "{3384,3072,0,1,2}-{3419,3006,0,1,4}-{3403,3069,0,1,1}-{3402,3061,0,1,1}-{3394,3076,0,1,1}-" + "loc_data": "{3385,3067,0,1,0}-{3389,3065,0,1,0}-{3400,3032,0,1,0}-{3402,3061,0,1,0}-{3404,3060,0,1,0}-{3407,3067,0,1,0}-{3408,3060,0,1,0}-{3411,3065,0,1,0}-{3412,3032,0,1,0}-{3412,3049,0,1,0}-{3414,3029,0,1,0}-{3417,3036,0,1,0}-{3418,3032,0,1,0}-{3419,3034,0,1,0}-{3422,3058,0,1,0}-{3424,3059,0,1,0}-{3435,3057,0,1,0}-{3435,3062,0,1,0}-{3439,3013,0,1,0}-{3439,3065,0,1,0}-{3440,3016,0,1,0}-{3443,3012,0,1,0}-{3443,3017,0,1,0}-{3443,3034,0,1,0}-{3443,3047,0,1,0}-{3446,3014,0,1,0}-" }, { "npc_id": "2809", @@ -6043,6 +6439,10 @@ "npc_id": "2910", "loc_data": "{3082,9885,0,1,4}-" }, + { + "npc_id": "2932", + "loc_data": "{2437,3347,0,1,0}-" + }, { "npc_id": "2935", "loc_data": "{3671,3484,0,1,4}-" @@ -6119,6 +6519,10 @@ "npc_id": "3021", "loc_data": "{2572,3105,0,1,0}-{2614,3226,0,1,4}-{3088,3357,0,1,0}-{2856,3435,0,1,0}-{3603,3529,0,1,6}-{2611,3859,0,1,6}-{2589,3863,0,1,0}-{3189,3234,0,1,0}-{2940,3225,0,1,6}-{2663,3374,0,1,4}-{3182,3354,0,1,0}-{2933,3434,0,1,4}-{3449,3471,0,1,6}-{2666,3521,0,1,4}-{2491,3177,0,1,1}-{3007,3371,0,1,2}-{2474,3446,0,1,4}-{2434,3415,0,1,3}-{3232,3459,0,1,3}-{2796,3104,0,1,0}-{2764,3210,0,1,1}-{3315,3205,0,1,6}-{3060,3263,0,1,0}-{3053,3304,0,1,1}-{2812,3333,0,1,4}-{2815,3466,0,1,3}-" }, + { + "npc_id": "3022", + "loc_data": "{3371,9320,0,0,6}-" + }, { "npc_id": "3029", "loc_data": "{3422,2937,0,1,1}-" @@ -6380,12 +6784,20 @@ "loc_data": "{3139,3448,0,1,3}-" }, { - "npc_id": "3215", - "loc_data": "{2541,9672,0,1,3}-" + "npc_id": "3207", + "loc_data": "{1970,5002,0,1,4}-" + }, + { + "npc_id": "3213", + "loc_data": "{2568,3334,0,1,0}-" + }, + { + "npc_id": "3214", + "loc_data": "{2517,9755,0,1,0}-" }, { "npc_id": "3216", - "loc_data": "{2581,3332,0,1,3}-{2534,3273,0,0,1}-" + "loc_data": "{2534,3273,0,0,1}-{2539,3273,0,0,1}-" }, { "npc_id": "3217", @@ -6635,6 +7047,10 @@ "npc_id": "3288", "loc_data": "{2987,3446,0,1,7}-{3034,3437,0,1,0}-" }, + { + "npc_id": "3293", + "loc_data": "{3113,3369,1,0,0}-{3122,3353,0,0,3}-{3124,3360,0,0,2}-{3115,3362,0,0,1}-" + }, { "npc_id": "3294", "loc_data": "{3014,3339,0,1,2}-" @@ -6837,7 +7253,7 @@ }, { "npc_id": "3675", - "loc_data": "{3331,2791,0,1,1}-{3333,2803,0,1,2}-{3338,2801,0,1,4}-{3338,2776,0,1,3}-{3321,2857,0,1,3}-{3322,2861,0,0,4}-{3319,2855,0,1,1}-{3319,2853,0,1,6}-" + "loc_data": "{3336,2778,0,1,0}-{3343,2793,0,1,0}-{3367,2791,0,1,0}-{3333,2864,0,1,1}-{3335,2860,0,1,2}-{3338,2864,0,1,4}-{3215,2841,0,1,0}-{3217,2845,0,1,0}-{3220,2841,0,1,0}-{3295,2866,0,1,0}-{3297,2863,0,1,0}-{3301,2864,0,1,0}-" }, { "npc_id": "3677", @@ -7065,7 +7481,7 @@ }, { "npc_id": "4246", - "loc_data": "{3480,3484,1,0,0}-{3479,3484,0,1,3}-" + "loc_data": "{3479,3484,0,1,3}-" }, { "npc_id": "4247", @@ -7199,6 +7615,10 @@ "npc_id": "4317", "loc_data": "{3230,3285,0,0,0}-" }, + { + "npc_id": "4343", + "loc_data": "{3706,3051,0,1,6}-{3703,3040,0,1,3}-{3664,3013,0,1,7}-{3731,2991,0,1,1}-{3723,2998,0,1,2}-{3749,3000,0,1,6}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-{3782,3016,0,1,7}-" + }, { "npc_id": "4344", "loc_data": "{3733,2972,0,1,4}-{3747,3013,0,1,4}-{3766,3034,0,1,6}-" @@ -7261,7 +7681,7 @@ }, { "npc_id": "4375", - "loc_data": "{3012,3192,1,0,2}-" + "loc_data": "{3013,3192,1,0,6}-" }, { "npc_id": "4376", @@ -7825,11 +8245,11 @@ }, { "npc_id": "4685", - "loc_data": "{3209,5552,0,1,1}-{3223,5555,0,1,4}-{3220,5548,0,1,6}-{3220,5557,0,1,4}-" + "loc_data": "{2817,3514,0,1,0}-{2884,9959,0,1,0}-{2890,9950,0,1,0}-{3209,5552,0,1,1}-{3223,5555,0,1,4}-{3220,5548,0,1,6}-{3220,5557,0,1,4}-" }, { "npc_id": "4686", - "loc_data": "{2827,3512,0,1,5}-{2954,3894,0,1,4}-{2950,3932,0,1,0}-{2955,3945,0,1,0}-{3213,5548,0,1,4}-" + "loc_data": "{2824,3510,0,1,5}-{2880,9927,0,1,0}-{2887,9955,0,1,0}-{2891,9941,0,1,0}-{2954,3894,0,1,4}-{2950,3932,0,1,0}-{2955,3945,0,1,0}-{3213,5548,0,1,4}-{2804,3507,0,1,0}-" }, { "npc_id": "4687", @@ -7841,23 +8261,23 @@ }, { "npc_id": "4689", - "loc_data": "{2902,9736,0,1,0}-" + "loc_data": "{2369,3401,0,1,0}-{2902,9736,0,1,0}-{2440,3213,0,1,0}-" }, { "npc_id": "4690", - "loc_data": "{3104,3875,0,1,2}-{2912,9731,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-" + "loc_data": "{3104,3875,0,1,2}-{2372,3401,0,1,0}-{2912,9731,0,1,0}-{2439,3211,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-" }, { "npc_id": "4691", - "loc_data": "{3110,3854,0,1,0}-" + "loc_data": "{3110,3854,0,1,0}-{2371,3398,0,1,0}-{2439,3208,0,1,0}-" }, { "npc_id": "4692", - "loc_data": "{3116,3858,0,1,0}-" + "loc_data": "{3116,3858,0,1,0}-{2372,3395,0,1,0}-{2442,3210,0,1,0}-" }, { "npc_id": "4693", - "loc_data": "{3094,3849,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-" + "loc_data": "{3094,3849,0,1,0}-{2369,3394,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-{2444,3208,0,1,0}-" }, { "npc_id": "4694", @@ -7927,6 +8347,10 @@ "npc_id": "4856", "loc_data": "{2732,3292,0,1,1}-" }, + { + "npc_id": "4871", + "loc_data": "{2782,3276,0,1,0}-" + }, { "npc_id": "4872", "loc_data": "{2740,3310,0,0,0}-" @@ -7951,6 +8375,10 @@ "npc_id": "4887", "loc_data": "{2738,3303,0,1,1}-{2723,3274,0,1,1}-" }, + { + "npc_id": "4891", + "loc_data": "{2768,3286,0,1,0}-{2777,3278,0,1,0}-{2783,3289,0,1,0}-{2784,3277,0,1,0}-{2768,3289,1,1,0}-{2780,3288,1,1,0}-" + }, { "npc_id": "4895", "loc_data": "{2718,3302,0,1,1}-" @@ -8443,6 +8871,10 @@ "npc_id": "5260", "loc_data": "{2665,2651,0,0,1}-{2667,2651,0,0,1}-" }, + { + "npc_id": "5277", + "loc_data": "{3264,2784,0,0,4}-{3264,2785,0,0,4}-" + }, { "npc_id": "5291", "loc_data": "{3300,2792,0,0,6}-{3282,2807,0,0,6}-{3285,2811,0,0,1}-{3283,2772,0,1,5}-{3281,2771,0,1,7}-{3283,2776,0,1,6}-{3278,2770,0,1,6}-" @@ -8595,6 +9027,10 @@ "npc_id": "5358", "loc_data": "{2874,2954,0,0,6}-" }, + { + "npc_id": "5359", + "loc_data": "{2627,5093,0,1,0}-{2629,5061,0,1,0}-{2638,5090,0,1,0}-{2651,5105,0,1,0}-{2654,5079,0,1,0}-{2663,5116,0,1,0}-{2683,5059,0,1,0}-{2685,5111,0,1,0}-{2693,5065,0,1,0}-{2693,5089,0,1,0}-{2704,5091,0,1,0}-{2710,5095,0,1,0}-{2712,5076,0,1,0}-{2714,5108,0,1,0}-{2716,5092,0,1,0}-{2719,5071,0,1,0}-{2722,5061,0,1,0}-{2732,5087,0,1,0}-{2739,5078,0,1,0}-{2740,5104,0,1,0}-{2747,5083,0,1,0}-" + }, { "npc_id": "5361", "loc_data": "{3176,5543,0,1,3}-{3191,5542,0,1,4}-{3175,5543,0,1,2}-{3178,5541,0,1,2}-{3187,5542,0,1,3}-{3192,5545,0,1,2}-{3192,5542,0,1,3}-{3179,5549,0,1,6}-{1757,5358,0,1,5}-{1760,5357,0,1,5}-{1755,5352,0,1,5}-{1751,5342,0,1,3}-{1745,5342,0,1,6}-{1739,5342,0,1,3}-{1737,5344,0,1,7}-{1739,5347,0,1,6}-{1740,5350,0,1,5}-{1739,5355,0,1,3}-{1747,5363,0,1,4}-{1749,5363,0,1,4}-{1743,5360,0,1,3}-{1739,5356,0,1,0}-" @@ -9253,7 +9689,7 @@ }, { "npc_id": "5748", - "loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-{3481,3473,0,0,0}-" + "loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-" }, { "npc_id": "5750", @@ -9613,19 +10049,27 @@ }, { "npc_id": "5932", - "loc_data": "{3255,3442,0,0,0}-" + "loc_data": "{3253,3445,0,0,6}-" }, { "npc_id": "5933", - "loc_data": "{3254,3443,0,0,0}-" + "loc_data": "{3254,3444,0,0,1}-" }, { "npc_id": "5934", - "loc_data": "{3259,3443,0,0,0}-" + "loc_data": "{3256,3443,0,0,6}-" }, { "npc_id": "5935", - "loc_data": "{3260,3442,0,0,0}-" + "loc_data": "{3257,3442,0,0,1}-" + }, + { + "npc_id": "5936", + "loc_data": "{3266,3445,0,0,6}-" + }, + { + "npc_id": "5937", + "loc_data": "{3267,3444,0,0,1}-" }, { "npc_id": "5938", @@ -9799,13 +10243,17 @@ "npc_id": "6028", "loc_data": "{3497,3497,0,1,2}-" }, + { + "npc_id": "6029", + "loc_data": "{3474,3475,0,1,0}-" + }, { "npc_id": "6030", "loc_data": "{3496,3476,0,1,2}-" }, { "npc_id": "6031", - "loc_data": "{3511,3482,1,0,0}-" + "loc_data": "{3511,3482,0,1,0}-" }, { "npc_id": "6032", @@ -9825,7 +10273,7 @@ }, { "npc_id": "6036", - "loc_data": "{3499,3474,1,0,0}-" + "loc_data": "{3499,3474,1,1,0}-" }, { "npc_id": "6037", @@ -9833,7 +10281,7 @@ }, { "npc_id": "6038", - "loc_data": "{3490,3472,1,0,0}-" + "loc_data": "{3490,3472,1,1,0}-" }, { "npc_id": "6039", @@ -9841,7 +10289,7 @@ }, { "npc_id": "6040", - "loc_data": "{3498,3472,1,0,0}-" + "loc_data": "{3498,3472,1,1,0}-" }, { "npc_id": "6041", @@ -9849,31 +10297,35 @@ }, { "npc_id": "6042", - "loc_data": "{3479,3498,0,1,4}-" + "loc_data": "{3480,3499,0,1,4}-" + }, + { + "npc_id": "6043", + "loc_data": "{3490,3473,0,1,0}-" }, { "npc_id": "6044", - "loc_data": "{3505,3491,1,0,0}-" + "loc_data": "{3505,3491,0,1,0}-" }, { "npc_id": "6045", - "loc_data": "{3479,3498,1,0,0}-" + "loc_data": "{3479,3498,0,1,0}-" }, { "npc_id": "6046", - "loc_data": "{2835,3509,0,0,1}-{3306,5510,0,1,5}-{3309,5543,0,1,6}-" + "loc_data": "{2835,3509,0,1,1}-{3306,5510,0,1,5}-{3309,5543,0,1,6}-" }, { "npc_id": "6047", - "loc_data": "{2839,3497,0,1,6}-{2840,3504,0,1,4}-" + "loc_data": "{2836,3495,0,1,0}-{2837,3499,0,1,0}-{2839,3502,0,1,0}-{2839,3506,0,1,0}-{2842,3504,0,1,0}-{2844,3507,0,1,0}-" }, { "npc_id": "6050", - "loc_data": "{3252,3069,0,1,1}-{3242,3059,0,1,7}-{3235,3051,0,1,5}-{3248,3051,0,1,4}-{3257,3055,0,1,3}-{3263,3063,0,1,3}-{3253,3040,0,1,6}-{3243,3039,0,1,6}-{3254,3031,0,1,1}-{3243,3035,0,1,5}-{3232,3039,0,1,2}-{3230,3046,0,1,6}-{3219,3033,0,1,3}-{3219,3022,0,1,1}-{3227,3017,0,1,5}-{3235,3012,0,1,4}-{3243,3019,0,1,2}-{3251,3028,0,1,3}-{3259,3080,0,1,2}-{3246,3080,0,1,3}-{3244,3082,0,1,1}-{3235,3072,0,1,4}-{3267,3048,0,1,0}-{3291,3081,0,1,7}-{3298,3075,0,1,1}-{3284,3076,0,1,3}-{3266,3072,0,1,1}-" + "loc_data": "{3174,3010,0,1,0}-{3198,3061,0,1,0}-{3199,3016,0,1,0}-{3223,3011,0,1,0}-{3228,3060,0,1,0}-{3251,3059,0,1,0}-{3219,3125,0,1,0}-{3233,3075,0,1,0}-{3250,3126,0,1,0}-{3264,3008,0,1,0}-{3266,3008,0,1,0}-{3285,3066,0,1,0}-{3322,3032,0,1,0}-{3323,3055,0,1,0}-{3325,3010,0,1,0}-{3310,3076,0,1,0}-" }, { "npc_id": "6051", - "loc_data": "{3292,3069,0,1,1}-{3285,3071,0,1,1}-{3273,3065,0,1,3}-{3288,3066,0,1,6}-{3281,3057,0,1,5}-{3294,3056,0,1,5}-{3305,3064,0,1,3}-{3279,3078,0,1,4}-{3312,3075,0,1,6}-{3306,3086,0,1,4}-{3272,3082,0,1,4}-" + "loc_data": "{3153,3047,0,1,0}-{3196,3063,0,1,0}-{3199,3036,0,1,0}-{3223,3035,0,1,0}-{3225,3011,0,1,0}-{3215,3092,0,1,0}-{3217,3124,0,1,0}-{3260,3077,0,1,0}-{3266,3010,0,1,0}-{3267,3068,0,1,0}-{3287,3065,0,1,0}-{3287,3067,0,1,0}-{3310,3070,0,1,0}-{3312,3068,0,1,0}-{3320,3054,0,1,0}-{3324,3013,0,1,0}-{3325,3033,0,1,0}-{3283,3084,0,1,0}-" }, { "npc_id": "6052", @@ -9999,6 +10451,38 @@ "npc_id": "6117", "loc_data": "{1884,5020,0,0,6}-" }, + { + "npc_id": "6118", + "loc_data": "{2443,3190,0,0,6}-" + }, + { + "npc_id": "6119", + "loc_data": "{2439,3186,0,1,4}-" + }, + { + "npc_id": "6120", + "loc_data": "{2437,3160,1,1,4}-" + }, + { + "npc_id": "6122", + "loc_data": "{2327,9394,0,0,1}-" + }, + { + "npc_id": "6123", + "loc_data": "{2364,9399,0,0,1}-" + }, + { + "npc_id": "6124", + "loc_data": "{2364,9398,0,0,1}-" + }, + { + "npc_id": "6125", + "loc_data": "{2323,9377,0,1,0}-" + }, + { + "npc_id": "6126", + "loc_data": "{2351,9358,0,1,0}-" + }, { "npc_id": "6127", "loc_data": "{2467,3183,0,0,3}-" @@ -10079,6 +10563,38 @@ "npc_id": "6190", "loc_data": "{1906,4270,0,1,0}-" }, + { + "npc_id": "6191", + "loc_data": "{2739,3577,0,1,0}-{2739,3579,1,1,0}-" + }, + { + "npc_id": "6192", + "loc_data": "{2734,3575,0,1,0}-" + }, + { + "npc_id": "6193", + "loc_data": "{2748,3559,0,1,0}-" + }, + { + "npc_id": "6194", + "loc_data": "{2734,3581,1,1,0}-" + }, + { + "npc_id": "6195", + "loc_data": "{2739,3581,0,1,0}-" + }, + { + "npc_id": "6196", + "loc_data": "{2746,3581,1,1,0}-" + }, + { + "npc_id": "6197", + "loc_data": "{2742,3577,0,1,0}-" + }, + { + "npc_id": "6199", + "loc_data": "{2737,3466,0,1,0}-" + }, { "npc_id": "6200", "loc_data": "{2947,3366,0,0,1}-{2949,3366,0,0,1}-{2946,3366,0,0,1}-{2948,3366,0,0,1}-{2945,3366,0,0,1}-{3010,3353,0,0,1}-{3011,3353,0,0,1}-{3012,3353,0,0,1}-{3013,3353,0,0,1}-{3014,3353,0,0,1}-{3015,3353,0,0,1}-" @@ -10327,14 +10843,6 @@ "npc_id": "6283", "loc_data": "{2877,5326,2,1,2}-{2857,5328,2,1,3}-{2861,5315,2,1,7}-" }, - { - "npc_id": "6339", - "loc_data": "{2547,3277,0,0,0}-" - }, - { - "npc_id": "6345", - "loc_data": "{2518,3275,0,1,0}-" - }, { "npc_id": "6346", "loc_data": "{2799,3186,0,1,7}-{2797,3169,0,0,0}-{2793,3161,0,1,3}-" @@ -10805,7 +11313,7 @@ }, { "npc_id": "6779", - "loc_data": "{3392,2759,0,1,2}-{3408,2763,0,1,7}-{3410,2786,0,1,2}-{3420,2778,0,1,6}-{3427,2792,0,1,6}-{3429,2802,0,1,4}-" + "loc_data": "{3337,2762,0,1,0}-{3340,2767,0,1,0}-{3345,2763,0,1,0}-{3350,2766,0,1,0}-{3352,2761,0,1,0}-{3356,2769,0,1,0}-{3358,2758,0,1,0}-{3359,2763,0,1,0}-{3365,2769,0,1,0}-{3368,2764,0,1,0}-{3375,2762,0,1,0}-{3392,2759,0,1,2}-{3408,2763,0,1,7}-{3410,2786,0,1,2}-{3420,2778,0,1,6}-{3427,2792,0,1,6}-{3429,2802,0,1,4}-" }, { "npc_id": "6780", @@ -10833,7 +11341,7 @@ }, { "npc_id": "6891", - "loc_data": "{2598,3272,0,0,0}-" + "loc_data": "{2598,3272,0,1,0}-" }, { "npc_id": "6893", @@ -10955,6 +11463,10 @@ "npc_id": "7004", "loc_data": "{2581,9891,0,1,2}-{3225,5495,0,1,4}-{3256,5540,0,1,4}-{3247,5536,0,1,6}-" }, + { + "npc_id": "7005", + "loc_data": "{2487,2924,0,1,0}-" + }, { "npc_id": "7009", "loc_data": "{3282,3467,0,0,0}-" @@ -11389,11 +11901,11 @@ }, { "npc_id": "7159", - "loc_data": "{3174,4238,2,1,6}-{3175,4243,2,1,6}-{3179,4236,2,1,4}-{3145,4272,1,1,3}-{3145,4276,1,1,3}-{3152,4271,1,1,6}-{3144,4264,1,1,4}-{3153,4266,1,1,1}-{3152,4261,1,1,4}-{3145,4259,1,1,6}-{3161,4259,1,1,0}-{3160,4265,1,1,0}-{3153,4246,1,1,3}-{3157,4248,1,1,6}-{3161,4247,1,1,4}-{3146,4247,1,1,6}-{3153,4233,1,1,4}-{3153,4240,1,1,6}-{3155,4238,1,1,5}-{3169,4267,3,1,3}-{3160,4265,3,1,6}-{3168,4250,3,1,4}-{3168,4244,3,1,6}-{3160,4239,3,1,1}-{3160,4228,3,1,3}-{3147,4225,3,1,3}-{3145,4242,3,1,5}-{3139,4249,3,1,6}-{3144,4253,3,1,3}-{3145,4266,3,1,0}-{3138,4266,3,1,3}-" + "loc_data": "{3174,4238,2,1,6}-{3175,4243,2,1,6}-{3179,4236,2,1,4}-{3145,4272,1,1,3}-{3145,4276,1,1,3}-{3152,4271,1,1,6}-{3144,4264,1,1,4}-{3153,4266,1,1,1}-{3152,4261,1,1,4}-{3145,4259,1,1,6}-{3161,4259,1,1,0}-{3160,4265,1,1,0}-{3153,4246,1,1,3}-{3157,4248,1,1,6}-{3161,4247,1,1,4}-{3146,4247,1,1,6}-{3153,4233,1,1,4}-{3153,4240,1,1,6}-{3155,4238,1,1,5}-{3169,4267,3,1,3}-{3160,4265,3,1,6}-{3168,4250,3,1,4}-{3168,4244,3,1,6}-{3160,4239,3,1,1}-{3160,4228,3,1,3}-{3147,4225,3,1,3}-{3145,4242,3,1,5}-{3139,4249,3,1,6}-{3144,4253,3,1,3}-{3145,4266,3,1,0}-{3138,4266,3,1,3}-{3151,4272,3,1,0}-{3139,4272,3,1,0}-{3146,4231,3,1,0}-{3169,4270,3,1,0}-" }, { "npc_id": "7160", - "loc_data": "{3175,4254,2,1,7}-{3176,4247,2,1,5}-{3174,4269,2,1,1}-{3190,4253,2,1,3}-{3192,4247,2,1,3}-{3189,4235,2,1,0}-{3152,4269,0,1,4}-{3160,4278,0,1,1}-{3160,4262,0,1,3}-{3149,4250,0,1,0}-{3158,4250,0,1,5}-{3161,4236,0,1,6}-{3172,4250,0,1,2}-{3171,4269,3,1,1}-{3157,4277,3,1,3}-{3150,4278,3,1,3}-" + "loc_data": "{3175,4254,2,1,7}-{3176,4247,2,1,5}-{3174,4269,2,1,1}-{3190,4253,2,1,3}-{3192,4247,2,1,3}-{3189,4235,2,1,0}-{3152,4269,0,1,4}-{3160,4278,0,1,1}-{3160,4262,0,1,3}-{3149,4250,0,1,0}-{3158,4250,0,1,5}-{3161,4236,0,1,6}-{3172,4250,0,1,2}-{3171,4269,3,1,1}-{3157,4277,3,1,3}-{3150,4278,3,1,3}-{3160,4271,1,1,0}-{3163,4274,1,1,0}-{3167,4277,1,1,0}-{3173,4277,1,1,0}-{3175,4275,1,1,0}-{3160,4269,0,1,0}-{3173,4264,0,1,0}-{3190,4237,2,1,0}-{3154,4279,3,1,0}-" }, { "npc_id": "7161", @@ -11664,13 +12176,37 @@ "loc_data": "{3358,2993,0,1,0}-" }, { - "npc_id": "7823", - "loc_data": "{3161,9547,0,0,3}-{3164,9556,0,0,4}-{3162,9574,0,0,3}-{3198,9554,0,0,7}-{3198,9572,0,0,1}-{3215,9560,0,0,1}-{3216,9588,0,0,1}-" + "npc_id": "7786", + "loc_data": "{3348,9388,0,1,0}-{3350,9393,0,1,0}-{3350,9400,0,1,0}-{3350,9406,0,1,0}-{3351,9380,0,1,0}-{3352,9374,0,1,0}-{3354,9387,0,1,0}-{3358,9378,0,1,0}-{3358,9396,0,1,0}-{3358,9406,0,1,0}-{3365,9381,0,1,0}-{3365,9387,0,1,0}-{3365,9402,0,1,0}-{3369,9390,0,1,0}-{3350,9412,0,1,0}-{3351,9420,0,1,0}-{3356,9414,0,1,0}-{3358,9421,0,1,0}-{3364,9424,0,1,0}-{3365,9416,0,1,0}-" + }, + { + "npc_id": "7787", + "loc_data": "{3301,4413,0,1,0}-{3302,4394,0,1,0}-{3304,4397,0,1,0}-{3306,4410,0,1,0}-{3307,4383,0,1,0}-{3307,4397,0,1,0}-{3308,4407,0,1,0}-{3310,4383,0,1,0}-{3310,4386,0,1,0}-{3310,4398,0,1,0}-{3311,4407,0,1,0}-{3312,4380,0,1,0}-{3313,4401,0,1,0}-{3314,4411,0,1,0}-{3316,4376,0,1,0}-{3316,4382,0,1,0}-{3316,4387,0,1,0}-{3316,4397,0,1,0}-{3316,4401,0,1,0}-{3316,4405,0,1,0}-{3317,4391,0,1,0}-{3318,4412,0,1,0}-{3319,4373,0,1,0}-{3319,4407,0,1,0}-{3321,4385,0,1,0}-{3321,4398,0,1,0}-{3322,4412,0,1,0}-{3323,4402,0,1,0}-{3324,4394,0,1,0}-{3324,4397,0,1,0}-{3325,4410,0,1,0}-" + }, + { + "npc_id": "7801", + "loc_data": "{3283,4346,0,1,0}-{3308,4349,0,1,0}-{3293,4375,0,1,0}-{3303,4363,0,1,0}-" + }, + { + "npc_id": "7802", + "loc_data": "{3288,4350,0,1,0}-{3296,4340,0,1,0}-{3288,4361,0,1,0}-{3310,4355,0,1,0}-" + }, + { + "npc_id": "7803", + "loc_data": "{3297,4347,0,1,0}-{3315,4346,0,1,0}-{3282,4357,0,1,0}-{3303,4369,0,1,0}-" + }, + { + "npc_id": "7804", + "loc_data": "{3279,4350,0,1,0}-{3294,4353,0,1,0}-{3294,4366,0,1,0}-" }, { "npc_id": "7891", "loc_data": "{3207,3250,0,0,0}-{3208,3250,0,0,0}-{3209,3250,0,0,0}-" }, + { + "npc_id": "7942", + "loc_data": "{3294,4937,0,0,6}-" + }, { "npc_id": "7959", "loc_data": "{3188,3425,0,1,0}-" @@ -11811,6 +12347,26 @@ "npc_id": "8275", "loc_data": "{2869,2982,1,1,5}-" }, + { + "npc_id": "8312", + "loc_data": "{3016,9974,1,1,0}-{3021,9940,1,1,0}-{3023,9940,1,1,0}-{3024,9959,1,1,0}-{3027,9960,1,1,0}-{3043,9967,1,1,0}-{3023,9992,1,1,0}-{3016,10021,2,1,0}-{3028,10013,2,1,0}-{3029,10028,2,1,0}-{3038,10005,2,1,0}-{3044,10001,2,1,0}-{3045,9993,2,1,0}-{3045,9999,2,1,0}-{3047,10000,2,1,0}-{3052,10009,2,1,0}-{3054,10001,2,1,0}-{3056,10006,2,1,0}-{3032,10090,1,1,0}-{3040,10096,1,1,0}-{3048,10095,1,1,0}-" + }, + { + "npc_id": "8316", + "loc_data": "{3017,9972,1,1,0}-{3025,9962,1,1,0}-{3030,9943,1,1,0}-{3033,9941,1,1,0}-{3034,9950,1,1,0}-{3035,9950,1,1,0}-{3036,9940,1,1,0}-{3038,9939,1,1,0}-{3045,9968,1,1,0}-{3058,9952,1,1,0}-{3063,9952,1,1,0}-{3025,9995,1,1,0}-{3027,10029,2,1,0}-{3051,10006,2,1,0}-{3052,10002,2,1,0}-{3054,10005,2,1,0}-{3027,10101,1,1,0}-{3039,10100,1,1,0}-{3054,10097,1,1,0}-" + }, + { + "npc_id": "8320", + "loc_data": "{3014,9971,1,1,0}-{3016,9969,1,1,0}-{3028,9942,1,1,0}-{3029,9943,1,1,0}-{3030,9951,1,1,0}-{3033,9950,1,1,0}-{3045,9965,1,1,0}-{3061,9953,1,1,0}-{3062,9953,1,1,0}-{3030,9995,1,1,0}-{3016,10023,2,1,0}-{3029,10014,2,1,0}-{3029,10030,2,1,0}-{3036,10005,2,1,0}-{3042,9994,2,1,0}-{3047,10005,2,1,0}-{3049,10002,2,1,0}-{3053,9998,2,1,0}-{3031,10100,1,1,0}-{3044,10098,1,1,0}-{3049,10102,1,1,0}-" + }, + { + "npc_id": "8324", + "loc_data": "{2911,3811,0,1,0}-{2911,3812,0,1,0}-{2911,3813,0,1,0}-{2925,3821,0,1,0}-{2925,3822,0,1,0}-{2925,3823,0,1,0}-{2929,3798,0,1,0}-{2936,3790,0,1,0}-{2936,3810,0,1,0}-{2939,3823,0,1,0}-{3427,5102,0,1,0}-{3428,5099,0,1,0}-{3428,5102,0,1,0}-{3430,5099,0,1,0}-{2949,3819,1,1,0}-{2949,3822,1,1,0}-{2955,3822,1,1,0}-{2957,3822,1,1,0}-{3016,9977,1,1,0}-{3021,9939,1,1,0}-{3024,9954,1,1,0}-{3025,9943,1,1,0}-{3025,9954,1,1,0}-{3026,9966,1,1,0}-{3032,9952,1,1,0}-{3039,9954,1,1,0}-{3044,9967,1,1,0}-{3044,9971,1,1,0}-{3057,9936,1,1,0}-{3059,9953,1,1,0}-{3041,9975,2,1,0}-{3043,9975,2,1,0}-{3045,9975,2,1,0}-{3016,10022,2,1,0}-{3017,10039,2,1,0}-{3027,10028,2,1,0}-{3029,10013,2,1,0}-{3036,10038,2,1,0}-{3037,10006,2,1,0}-{3041,10024,2,1,0}-{3043,10032,2,1,0}-{3057,10002,2,1,0}-{3058,10021,2,1,0}-{3065,10006,2,1,0}-{3027,10092,1,1,0}-{3035,10097,1,1,0}-{3051,10099,1,1,0}-" + }, + { + "npc_id": "8328", + "loc_data": "{3055,10103,1,1,0}-" + }, { "npc_id": "8349", "loc_data": "{2589,5735,0,1,0}-{2589,5713,0,1,0}-{2610,5709,0,1,0}-{2613,5732,0,1,0}-" @@ -11819,6 +12375,58 @@ "npc_id": "8358", "loc_data": "{2601,5710,0,1,0}-{2603,5737,0,1,0}-" }, + { + "npc_id": "8380", + "loc_data": "{2907,3806,0,1,0}-" + }, + { + "npc_id": "8381", + "loc_data": "{2910,3805,0,1,0}-" + }, + { + "npc_id": "8382", + "loc_data": "{2912,3812,0,1,0}-{2923,3823,0,1,0}-" + }, + { + "npc_id": "8383", + "loc_data": "{2908,3809,0,1,0}-{2919,3823,0,1,0}-" + }, + { + "npc_id": "8384", + "loc_data": "{2922,3827,0,1,0}-" + }, + { + "npc_id": "8385", + "loc_data": "{2924,3825,0,1,0}-" + }, + { + "npc_id": "8386", + "loc_data": "{2921,3824,0,1,0}-" + }, + { + "npc_id": "8387", + "loc_data": "{2934,3786,0,1,0}-" + }, + { + "npc_id": "8388", + "loc_data": "{2935,3784,0,1,0}-{2940,3827,0,1,0}-" + }, + { + "npc_id": "8389", + "loc_data": "{2937,3785,0,1,0}-" + }, + { + "npc_id": "8390", + "loc_data": "{2935,3781,0,1,0}-{2939,3829,0,1,0}-" + }, + { + "npc_id": "8391", + "loc_data": "{2937,3780,0,1,0}-{2940,3833,0,1,0}-" + }, + { + "npc_id": "8392", + "loc_data": "{2938,3782,0,1,0}-{2938,3831,0,1,0}-" + }, { "npc_id": "8536", "loc_data": "{2654,5600,0,1,3}-{2650,5600,0,0,3}-{2662,5593,0,0,3}-{2653,5590,0,0,3}-{2644,5592,0,0,3}-{2644,5601,0,0,3}-{2654,5604,0,0,3}-{2663,5606,0,0,3}-{2670,5597,0,0,3}-{2657,5589,0,0,3}-" diff --git a/Server/data/configs/object_configs.json b/Server/data/configs/object_configs.json index 6c887b349..e4f2c26a3 100644 --- a/Server/data/configs/object_configs.json +++ b/Server/data/configs/object_configs.json @@ -3,14030 +3,14 @@ "examine": "I wonder what's inside.", "ids": "0,1" }, - { - "examine": "Looks and smells like a place where goblins live.", - "ids": "2" - }, - { - "examine": "The door is closed.", - "ids": "3,4" - }, - { - "examine": "A powerful ranging device, unfortunately not working.", - "ids": "5" - }, - { - "examine": "A powerful ranging device that fires metal balls.", - "ids": "6" - }, - { - "examine": "The cannon is built on here.", - "ids": "7" - }, - { - "examine": "The mounting for the multicannon.", - "ids": "8" - }, - { - "examine": "The barrels of the multicannon.", - "ids": "9" - }, { "examine": "I can climb down this.", "ids": "10" }, - { - "examine": "I can climb up this.", - "ids": "11" - }, - { - "examine": "A pile of rocks is blocking my path.", - "ids": "12" - }, - { - "examine": "Mud caved in from above.", - "ids": "13" - }, - { - "examine": "Intended to keep the goblins away from the mines.", - "ids": "14,15,16,17,18,19,20" - }, - { - "examine": "Its eyes stare off into the distance...", - "ids": "21" - }, - { - "examine": "The door is shut.", - "ids": "22" - }, - { - "examine": "Unusually lumpy looking.", - "ids": "23" - }, - { - "examine": "The door is shut.", - "ids": "24" - }, - { - "examine": "Seems to be some kind of clock part.", - "ids": "25,26,27,28,29,30,31,32" - }, - { - "examine": "Yup, definitely a lever.", - "ids": "33,34,35,36" - }, - { - "examine": "Stops people walking past.", - "ids": "37,38,39" - }, - { - "examine": "Animals have no table manners.", - "ids": "40" - }, - { - "examine": "Looks like an outlet pipe to the lake.", - "ids": "41" - }, - { - "examine": "I can see fish swimming in the water.", - "ids": "42,326" - }, - { - "examine": "It seems to sparkle.", - "ids": "43" - }, - { - "examine": "I can see really big fish swimming in the water.", - "ids": "44" - }, - { - "examine": "Big Dave is fishing here.", - "ids": "45" - }, - { - "examine": "Joshua is fishing here.", - "ids": "46" - }, - { - "examine": "A wooden gate.", - "ids": "47,48,49,50" - }, - { - "examine": "Hmmm... I wonder if it's loose enough to get through.", - "ids": "51" - }, - { - "examine": "It's locked.", - "ids": "52,53" - }, - { - "examine": "It's a flight of stairs.", - "ids": "54,55,56,57" - }, - { - "examine": "Known commonly as Red worm vine.", - "ids": "58" - }, - { - "examine": "A fancy hole in the wall.", - "ids": "59" - }, - { - "examine": "A fancy hole in the ceiling.", - "ids": "60" - }, - { - "examine": "A shrine to evil.", - "ids": "61" - }, - { - "examine": "Is there something in there?", - "ids": "62" - }, - { - "examine": "Used for storage.", - "ids": "63,64,36351,36352" - }, - { - "examine": "Surprisingly sturdy looking.", - "ids": "65,66" - }, - { - "examine": "Used for storage.", - "ids": "67" - }, - { - "examine": "Where bees live.", - "ids": "68" - }, - { - "examine": "Handy for boarding boats.", - "ids": "69,70" - }, - { - "examine": "Sturdy looking door.", - "ids": "71,72" - }, - { - "examine": "Securely fastened shut.", - "ids": "73,74" - }, - { - "examine": "I wonder what's inside?", - "ids": "75" - }, - { - "examine": "It's open.", - "ids": "76" - }, - { - "examine": "Securely fastened shut.", - "ids": "77,78" - }, - { - "examine": "Looks secure.", - "ids": "79,80" - }, - { - "examine": "The door is closed.", - "ids": "81,82" - }, - { - "examine": "Seems very old...", - "ids": "86" - }, - { - "examine": "I guess you pull it...", - "ids": "87" - }, - { - "examine": "A wrought iron gate.", - "ids": "89,90" - }, - { - "examine": "I don't like the look of this!", - "ids": "91" - }, - { - "examine": "The door is closed.", - "ids": "92,93" - }, - { - "examine": "A wrought iron gate.", - "ids": "94,95" - }, - { - "examine": "A dark flight of stairs.", - "ids": "96,98" - }, - { - "examine": "The door is closed.", - "ids": "99" - }, { "examine": "Don't you open that trapdoor!", "ids": "100" }, - { - "examine": "I can climb this.", - "ids": "101" - }, - { - "examine": "A sturdy door.", - "ids": "102" - }, - { - "examine": "I wonder what's inside.", - "ids": "103" - }, - { - "examine": "Perhaps I should search it.", - "ids": "104" - }, - { - "examine": "I wonder what that's there for...", - "ids": "105,106" - }, - { - "examine": "An appliance for cooking with.", - "ids": "114" - }, - { - "examine": "A party balloon.", - "ids": "115,116,117,118,119,120" - }, - { - "examine": "Aren't they pretty?", - "ids": "121" - }, - { - "examine": "Paaaarty!", - "ids": "122" - }, - { - "examine": "A party balloon.", - "ids": "123,124,125,126,127,128,129,130" - }, - { - "examine": "The door is closed.", - "ids": "131" - }, - { - "examine": "An escape route.", - "ids": "132" - }, - { - "examine": "Looks spooky down there.", - "ids": "133" - }, - { - "examine": "A large double door.", - "ids": "134,135,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,4423,4424,4425,4426,4427,4428,4429,4430,4629,4630,4631,4632,4633,4634,4635,4963,4964,12349,12350,12446,12447,12448,12449,13094,13095,13096,13097,13098,13099,31814,31815,31816" - }, - { - "examine": "The door is closed.", - "ids": "136" - }, - { - "examine": "Smelly.", - "ids": "152" - }, - { - "examine": "An ornate fountain.", - "ids": "153,36781" - }, - { - "examine": "A pipe I can squeeze through.", - "ids": "154,2287,2288,2290,2291,2292,2293,3236,3237,4058,5099,5100,5101,5102,5152,5153,5154,5155,9293,9295,10063,10064,10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,29370" - }, - { - "examine": "Lots of books.", - "ids": "155,156,157" - }, - { - "examine": "This wall looks odd...", - "ids": "158,159" - }, - { - "examine": "I wonder what this does...", - "ids": "160" - }, - { - "examine": "I'm not touching that.", - "ids": "162,163,164" - }, - { - "examine": "A special furnace for destroying contaminated items.", - "ids": "165" - }, - { - "examine": "A wooden gate.", - "ids": "166,167" - }, - { - "examine": "I wonder what's inside.", - "ids": "170" - }, - { - "examine": "Perhaps I should search it.", - "ids": "171" - }, - { - "examine": "I wonder what's inside.", - "ids": "172" - }, - { - "examine": "Perhaps I should search it.", - "ids": "173" - }, - { - "examine": "Fly Gnome Air.", - "ids": "187" - }, - { - "examine": "Probably pilot error.", - "ids": "188" - }, - { - "examine": "The Blurberry bar", - "ids": "189" - }, - { - "examine": "A large gate in the gnome style.", - "ids": "190" - }, - { - "examine": "The entrance to the cave.", - "ids": "194" - }, - { - "examine": "I can climb this.", - "ids": "195" - }, - { - "examine": "A quirky gnome lamp.", - "ids": "200" - }, - { - "examine": "These insects love this light.", - "ids": "201" - }, - { - "examine": "It's amazing what bees produce!", - "ids": "202" - }, - { - "examine": "Posh candlesticks.", - "ids": "203,204,32287,40074" - }, - { - "examine": "Scary lighting apparatus.", - "ids": "208" - }, - { - "examine": "An ornamental lighting fixture.", - "ids": "209" - }, - { - "examine": "A mysterious glowing ice crystal.", - "ids": "210" - }, - { - "examine": "It's amazing what bees produce!", - "ids": "211" - }, - { - "examine": "Useful for making ships move.", - "ids": "212,218" - }, - { - "examine": "This figure brings luck to those who sail.", - "ids": "221,222" - }, - { - "examine": "Useful for making ships move.", - "ids": "225,226" - }, - { - "examine": "Barnacle infested rope.", - "ids": "227" - }, - { - "examine": "Allows access to other parts of the ship.", - "ids": "245,246" - }, - { - "examine": "Without this I'm going around in circles.", - "ids": "252,253" - }, - { - "examine": "This figure brings luck to those who sail.", - "ids": "254" - }, - { - "examine": "Used for pulling things up.", - "ids": "255" - }, - { - "examine": "This figure brings luck to those who sail.", - "ids": "260" - }, - { - "examine": "Useful if there is any wind.", - "ids": "265" - }, - { - "examine": "Useful for making ships move.", - "ids": "266,267" - }, - { - "examine": "Useful for making ships move", - "ids": "268" - }, - { - "examine": "How much does this weigh?", - "ids": "271" - }, - { - "examine": "I can climb up here.", - "ids": "272" - }, - { - "examine": "I can go below decks with this ladder.", - "ids": "273" - }, - { - "examine": "A conveniently rolled sail.", - "ids": "274,275,276,277,278,279" - }, - { - "examine": "I'm not allowed to climb this ladder.", - "ids": "287" - }, - { - "examine": "It's like a land rudder.", - "ids": "296" - }, - { - "examine": "Disturbingly man-like.", - "ids": "297" - }, - { - "examine": "I bet there's a needle in it somewhere.", - "ids": "298,299,300" - }, - { - "examine": "Animals have no table manners.", - "ids": "301" - }, - { - "examine": "A home for baby creatures.", - "ids": "302" - }, - { - "examine": "In the city we would call this mouldy rubbish.", - "ids": "303" - }, - { - "examine": "I bet there's a needle in it somewhere.", - "ids": "304" - }, - { - "examine": "Where bees live.", - "ids": "305" - }, - { - "examine": "A used cart seller will probably try and sell it later.", - "ids": "306" - }, - { - "examine": "One horsepower; wooden suspension: a beauty.", - "ids": "307,308" - }, - { - "examine": "Dead tree parts piled together neatly.", - "ids": "309" - }, - { - "examine": "A patch of soft dark brown matter. Probably mud.", - "ids": "310" - }, - { - "examine": "A pile of something I hope is mud.", - "ids": "311" - }, - { - "examine": "Potato-licious!", - "ids": "312" - }, - { - "examine": "Baby bread.", - "ids": "313" - }, - { - "examine": "The remains of a bad driver.", - "ids": "327" - }, - { - "examine": "The perfect place to store things.", - "ids": "346,347" - }, - { - "examine": "These open and close!", - "ids": "348" - }, - { - "examine": "This may be worth searching.", - "ids": "349" - }, - { - "examine": "These open and close!", - "ids": "350" - }, - { - "examine": "This may be worth searching.", - "ids": "351" - }, - { - "examine": "These open and close!", - "ids": "352" - }, - { - "examine": "This may be worth searching.", - "ids": "353" - }, - { - "examine": "A wooden crate for storage.", - "ids": "354,355" - }, - { - "examine": "An old crate for storage.", - "ids": "356,357,358" - }, - { - "examine": "A pile of boxes for storage.", - "ids": "359,360,361" - }, - { - "examine": "A wooden barrel for storage.", - "ids": "362" - }, - { - "examine": "A wooden barrel containing lots of fish.", - "ids": "363" - }, - { - "examine": "It's got ale in it.", - "ids": "364,32063" - }, - { - "examine": "These may have something in them.", - "ids": "365" - }, - { - "examine": "Useful for transportation of delicate items.", - "ids": "366" - }, - { - "examine": "This may be worth opening.", - "ids": "367,368,369" - }, - { - "examine": "This may be worth searching.", - "ids": "370,371,372" - }, - { - "examine": "The perfect accompaniment to a bedroom.", - "ids": "373" - }, - { - "examine": "A stand for hats!", - "ids": "374" - }, - { - "examine": "I wonder what's inside.", - "ids": "375,376,377" - }, - { - "examine": "Perhaps I should search it.", - "ids": "378,379" - }, - { - "examine": "A good source of books!", - "ids": "380,381" - }, - { - "examine": "A woven storage basket.", - "ids": "382,383,384,385" - }, - { - "examine": "A gigantic pottery urn.", - "ids": "386" - }, - { - "examine": "This no doubt contains arcane knowledge.", - "ids": "387" - }, - { - "examine": "I wonder what this spooky item contains.", - "ids": "388" - }, - { - "examine": "It smells funny in there.", - "ids": "389,390" - }, - { - "examine": "A fishing net full of fish.", - "ids": "392" - }, - { - "examine": "A good source of books!", - "ids": "393" - }, - { - "examine": "Bamboo storage!", - "ids": "394,395,396" - }, - { - "examine": "The perfect place to store things.", - "ids": "397" - }, - { - "examine": "I hope no-one's home...", - "ids": "398,26931,26935,26937,26939,32290" - }, - { - "examine": "I see dead people.", - "ids": "399,36737,32291" - }, - { - "examine": "A small simple gravestone.", - "ids": "400" - }, - { - "examine": "A simple marker for a forgotten person.", - "ids": "401" - }, - { - "examine": "The remains of someone lie inside.", - "ids": "402" - }, - { - "examine": "A monument to a special person.", - "ids": "403" - }, - { - "examine": "The inscription is worn away and unreadable.", - "ids": "404" - }, - { - "examine": "'Here lies...' is all I can read.", - "ids": "405" - }, - { - "examine": "Whoever bought this must have really cared for the inhabitant.", - "ids": "406" - }, - { - "examine": "Looks like a stone doorway to me.", - "ids": "407" - }, - { - "examine": "Looks like a stone doorway to my untrained eye.", - "ids": "408" - }, - { - "examine": "Shrine to the glory of Saradomin.", - "ids": "409" - }, - { - "examine": "An ancient altar to the glory of Guthix.", - "ids": "410" - }, - { - "examine": "Shrine to the glory of Zamorak.", - "ids": "411,412" - }, - { - "examine": "Looks suspiciously like a big stone table.", - "ids": "413" - }, - { - "examine": "A really posh upright coffin.", - "ids": "414" - }, - { - "examine": "Whoever's inside must have been rich.", - "ids": "415" - }, - { - "examine": "With skill I can play this.", - "ids": "416" - }, - { - "examine": "Great for sleeping in.", - "ids": "417" - }, - { - "examine": "A stylish-looking bed.", - "ids": "418" - }, - { - "examine": "A drab-looking bed.", - "ids": "419" - }, - { - "examine": "A stylish-looking bed.", - "ids": "420,421" - }, - { - "examine": "Technically a bed.", - "ids": "422" - }, - { - "examine": "I guess I could sleep in it if I were really tired.", - "ids": "423" - }, - { - "examine": "Lovely comfy-looking big bed.", - "ids": "424,425" - }, - { - "examine": "Posh-looking bed.", - "ids": "426" - }, - { - "examine": "A bed fit for a king.", - "ids": "427,428" - }, - { - "examine": "One of the nicest beds I have ever seen.", - "ids": "429" - }, - { - "examine": "Perfect for snoozing in the sun.", - "ids": "430" - }, - { - "examine": "A comfortable seat to recline and recuperate.", - "ids": "431" - }, - { - "examine": "I don't think anyone's slept here for a long time.", - "ids": "432" - }, - { - "examine": "Bamboo's a versatile material.", - "ids": "433,434,435" - }, - { - "examine": "A lump of rock.", - "ids": "436,437,438,439" - }, - { - "examine": "A big slimy lump of rock.", - "ids": "440" - }, - { - "examine": "A slimy lump of rock.", - "ids": "441" - }, - { - "examine": "A slippery looking rock.", - "ids": "442,443" - }, - { - "examine": "A huge lump of rock.", - "ids": "444,445" - }, - { - "examine": "Some small stones.", - "ids": "446,447,448" - }, - { - "examine": "A rocky ledge.", - "ids": "449" - }, - { - "examine": "Stoney!", - "ids": "450,451,452,453" - }, - { - "examine": "Solid rock from the cave floor.", - "ids": "454,455" - }, - { - "examine": "Looks slippery!", - "ids": "462,463" - }, - { - "examine": "Formed over many years of dripping limestone.", - "ids": "464,465,466" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "467" - }, - { - "examine": "Limestone floor growth.", - "ids": "468" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "469,470" - }, - { - "examine": "A deposit of rocks.", - "ids": "471,472,473,474" - }, - { - "examine": "Looks slippery!", - "ids": "477,478" - }, - { - "examine": "A deposit of rocks.", - "ids": "479,480,481,482,483,484,485,486" - }, - { - "examine": "A collection of rocks over what looks like a depression.", - "ids": "492" - }, - { - "examine": "A deposit of rocks.", - "ids": "507,508,509,510" - }, - { - "examine": "A rock with a pickaxe and mining tools.", - "ids": "511" - }, - { - "examine": "A very tall column of ice.", - "ids": "516" - }, - { - "examine": "A deposit of rocks.", - "ids": "517,518,519,520" - }, - { - "examine": "Formed over many years of dripping limestone.", - "ids": "523,524,525,526,527,528" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "529" - }, - { - "examine": "Formed over many years of dripping limestone.", - "ids": "530" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "531" - }, - { - "examine": "Limestone floor growth.", - "ids": "532" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "533" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "534" - }, - { - "examine": "A tooth shaped rock formation protruding from the ceiling.", - "ids": "539,540" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "541,542" - }, - { - "examine": "A tooth shaped rock formation protruding from the ceiling.", - "ids": "543" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "544" - }, - { - "examine": "A huge lump of rock.", - "ids": "545" - }, - { - "examine": "Intimidating!", - "ids": "546,547" - }, - { - "examine": "A deposit of rocks.", - "ids": "548,549,550,551,552,553" - }, - { - "examine": "Frozen water has formed an icicle here.", - "ids": "554,555,556,557" - }, - { - "examine": "It looks cold in there.", - "ids": "558,559,560,561" - }, - { - "examine": "This person was of great importance.", - "ids": "562" - }, - { - "examine": "A monarch chiselled in stone.", - "ids": "563,564" - }, - { - "examine": "A sculpture of a monarch.", - "ids": "565" - }, - { - "examine": "This person was of great importance.", - "ids": "566" - }, - { - "examine": "A huge carving of an ancient race.", - "ids": "567" - }, - { - "examine": "A depiction of a great dwarven miner.", - "ids": "568" - }, - { - "examine": "A depiction of a famous gnome warrior.", - "ids": "569,570" - }, - { - "examine": "The head and shoulders of a famous gnome.", - "ids": "571,572" - }, - { - "examine": "A depiction of a famous gnomeballer.", - "ids": "573" - }, - { - "examine": "A carving of a figure from the history of 2009Scape.", - "ids": "574,575,576,577,578" - }, - { - "examine": "An expertly chiselled statue.", - "ids": "579,580,581" - }, - { - "examine": "An unusual symbol of ancient times.", - "ids": "582" - }, - { - "examine": "An expertly crafted vase.", - "ids": "583" - }, - { - "examine": "An expertly chiselled statue of a bird.", - "ids": "584" - }, - { - "examine": "What a good likeness!", - "ids": "585,586" - }, - { - "examine": "A depiction of the evil god Zamorak.", - "ids": "587" - }, - { - "examine": "A base for the statue to sit on.", - "ids": "588" - }, - { - "examine": "The scrying glass of a seer.", - "ids": "589" - }, - { - "examine": "Banking transactions are processed here.", - "ids": "590" - }, - { - "examine": "Banking transactions are recorded here.", - "ids": "591" - }, - { - "examine": "Contains washing items.", - "ids": "592" - }, - { - "examine": "A nice sturdy looking table.", - "ids": "593,594,595" - }, - { - "examine": "A banquet could be eaten from this.", - "ids": "596,597" - }, - { - "examine": "Useful for putting things on.", - "ids": "598" - }, - { - "examine": "At one time it was for putting things on.", - "ids": "599" - }, - { - "examine": "The napkins are made from real silk.", - "ids": "600" - }, - { - "examine": "Useful for putting things on.", - "ids": "601,602,603,604,605,606" - }, - { - "examine": "Items for making clothes are kept on here.", - "ids": "607" - }, - { - "examine": "The ideal place to study.", - "ids": "608" - }, - { - "examine": "A handy workbench for a handy person.", - "ids": "609,610" - }, - { - "examine": "Sit back and enjoy the view.", - "ids": "611" - }, - { - "examine": "Items are for sale here.", - "ids": "612" - }, - { - "examine": "Useful for putting things on.", - "ids": "613,614,615" - }, - { - "examine": "A creepy looking table.", - "ids": "616" - }, - { - "examine": "Items are for sale here.", - "ids": "617" - }, - { - "examine": "There are some strange chemicals here.", - "ids": "618,619" - }, - { - "examine": "Bamboo's a versatile material.", - "ids": "620" - }, - { - "examine": "It's a banquet table.", - "ids": "621,622" - }, - { - "examine": "A nice sturdy looking table.", - "ids": "623,624,625,626,627" - }, - { - "examine": "Finely wrought wares of silver.", - "ids": "628" - }, - { - "examine": "Garments for the discerning.", - "ids": "629" - }, - { - "examine": "Bread cakes and pastries.", - "ids": "630" - }, - { - "examine": "Finest precious stones.", - "ids": "631" - }, - { - "examine": "These will keep you warm.", - "ids": "632" - }, - { - "examine": "The spice is right.", - "ids": "633" - }, - { - "examine": "Always a source of good bargains.", - "ids": "634" - }, - { - "examine": "Fine brews from exotic regions.", - "ids": "635" - }, - { - "examine": "Keeps mine carts from rolling away.", - "ids": "636" - }, - { - "examine": "You can 'cart' things around on this.", - "ids": "637" - }, - { - "examine": "Makes you taller.", - "ids": "647,29314" - }, - { - "examine": "A bit large for a bracelet!", - "ids": "648" - }, - { - "examine": "A macabre variation on the neck tie.", - "ids": "649,650" - }, - { - "examine": "Dead and half buried.", - "ids": "651,652,653,654,655,656,657" - }, - { - "examine": "Disturbing but tidy.", - "ids": "658" - }, - { - "examine": "I don't even want to think about what did that...", - "ids": "659" - }, - { - "examine": "Now that's what I call slimline!", - "ids": "660,664,3797,3971,5122,7206,29340" - }, - { - "examine": "He looks very relaxed.", - "ids": "661,665,3798,3972,5123,7207,29341" - }, - { - "examine": "Now he's just too thin.", - "ids": "662,666,3799,3973,5124,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,29342" - }, - { - "examine": "He hasn't eaten in a long time.", - "ids": "663,667,3974,5125,29343" - }, - { - "examine": "Disturbing but tidy.", - "ids": "658,668,669,670,3969,29347" - }, - { - "examine": "No cats were harmed in the making of this device.", - "ids": "671" - }, - { - "examine": "Shattered.", - "ids": "672,673,674,675,676,677" - }, - { - "examine": "I see fish.", - "ids": "678" - }, - { - "examine": "I can see fish swimming in the water.", - "ids": "679" - }, - { - "examine": "I was always forced to play this as a child.", - "ids": "680" - }, - { - "examine": "I never learnt to play.", - "ids": "681" - }, - { - "examine": "Time for a recital?", - "ids": "682" - }, - { - "examine": "Tick-tock, it's a clock.", - "ids": "683" - }, - { - "examine": "The noxious liquid bubbles horribly.", - "ids": "684" - }, - { - "examine": "Shows which way the wind blows.", - "ids": "685,686,687,688" - }, - { - "examine": "Looking good!", - "ids": "689" - }, - { - "examine": "A privacy aid!", - "ids": "690" - }, - { - "examine": "Use this to get changed behind and retain modesty.", - "ids": "691" - }, - { - "examine": "I don't even want to think about what's cooking in that.", - "ids": "692" - }, - { - "examine": "Good for sweeping.", - "ids": "693" - }, - { - "examine": "I'm guessing it's for making women's clothes.", - "ids": "694" - }, - { - "examine": "Helps make human clothing.", - "ids": "695" - }, - { - "examine": "A hole.", - "ids": "696" - }, - { - "examine": "Dead animal head. Lovely.", - "ids": "697,736,29344" - }, - { - "examine": "Must have been laid by a huge bird.", - "ids": "698" - }, - { - "examine": "Whatever it was I'm glad it's not alive.", - "ids": "699" - }, - { - "examine": "Spooky!", - "ids": "700,701,2614,4048,4049,4050,29345" - }, - { - "examine": "A dog's idea of heaven.", - "ids": "702,703,704,705,706,29346" - }, - { - "examine": "Ding-Dong!", - "ids": "707" - }, - { - "examine": "Some kind of pulley system.", - "ids": "708" - }, - { - "examine": "Surprisingly rope-shaped.", - "ids": "709" - }, - { - "examine": "Suspiciously hole-shaped.", - "ids": "710" - }, - { - "examine": "A huge chunk of shining natural crystal.", - "ids": "711,712,713" - }, - { - "examine": "A recently extinguished fire.", - "ids": "714,715,716,717" - }, - { - "examine": "A barrel full of swords...", - "ids": "718,719,720,721,722" - }, - { - "examine": "I'm glad this isn't around anymore!", - "ids": "723" - }, - { - "examine": "A crude torch stuck in the ground.", - "ids": "724,725,726,25200" - }, - { - "examine": "A fissure in the cave wall.", - "ids": "727,728,729,730,731,732" - }, - { - "examine": "This huge web blocks your path.", - "ids": "733" - }, - { - "examine": "A huge web, cruelly slashed in half.", - "ids": "734" - }, - { - "examine": "The noxious liquid bubbles horribly.", - "ids": "735" - }, - { - "examine": "Whatever it was I'm glad it's not alive.", - "ids": "737,738,739,740" - }, - { - "examine": "Looks a little too broken to climb.", - "ids": "741,742" - }, - { - "examine": "An old-looking ladder.", - "ids": "743" - }, - { - "examine": "An old-looking bit of scaffolding.", - "ids": "744,745,746,747" - }, - { - "examine": "The entrance to the cave.", - "ids": "748" - }, - { - "examine": "A map icon..", - "ids": "771" - }, - { - "examine": "It's a door made from bamboo.", - "ids": "779" - }, - { - "examine": "A loom.", - "ids": "787" - }, - { - "examine": "You'd need a big siege engine to force that.", - "ids": "788,789" - }, - { - "examine": "I always wonder if someone's hiding inside when I see these.", - "ids": "817" - }, - { - "examine": "Looks kind of like a man made of metal.", - "ids": "818,819,820" - }, - { - "examine": "Not suitable for children. Aim away from face.", - "ids": "821,36780" - }, - { - "examine": "Big heavy metal balls.", - "ids": "822,36790" - }, - { - "examine": "The easiest opponent I'll ever fight.", - "ids": "823" - }, - { - "examine": "A wooden defensive structure.", - "ids": "824,825,826,827,828,36928" - }, - { - "examine": "For private use only!", - "ids": "829,830,831,832,833" - }, - { - "examine": "Break glass in case of emergency.", - "ids": "834,835" - }, - { - "examine": "An attractively laid out collection of ranging weapons.", - "ids": "836" - }, - { - "examine": "Break glass in case of emergency.", - "ids": "837,838" - }, - { - "examine": "An attractively laid out collection of ranging weapons.", - "ids": "839" - }, - { - "examine": "A row of sharp pointy spears.", - "ids": "848" - }, - { - "examine": "Rows of sharp pointy spears.", - "ids": "849,850" - }, - { - "examine": "A tatty old standard.", - "ids": "851,852" - }, - { - "examine": "A standard.", - "ids": "853" - }, - { - "examine": "A blue standard.", - "ids": "854,855,856" - }, - { - "examine": "A standard of the gnome race.", - "ids": "857,858" - }, - { - "examine": "The standard of the ogre race.", - "ids": "859" - }, - { - "examine": "The flag of Asgarnia.", - "ids": "860" - }, - { - "examine": "The flag of Kandarin.", - "ids": "861" - }, - { - "examine": "The flag of Ardougne.", - "ids": "862" - }, - { - "examine": "A standard of Asgarnia.", - "ids": "863" - }, - { - "examine": "A standard of Kandarin.", - "ids": "864" - }, - { - "examine": "A standard of Asgarnia.", - "ids": "865" - }, - { - "examine": "A standard of Kandarin.", - "ids": "866" - }, - { - "examine": "A standard of Misthalin.", - "ids": "867" - }, - { - "examine": "A standard of Varrock.", - "ids": "868" - }, - { - "examine": "A flag flies here.", - "ids": "869" - }, - { - "examine": "A sculpted trunk of wood.", - "ids": "870" - }, - { - "examine": "Takes my dirty bath water away.", - "ids": "871" - }, - { - "examine": "It smells horrible in there.", - "ids": "872" - }, - { - "examine": "Ideal for washing things in.", - "ids": "873,874,4063,36971" - }, - { - "examine": "Wash here.", - "ids": "875,876,877" - }, - { - "examine": "No this is not a mirage!", - "ids": "878" - }, - { - "examine": "Everyone needs a water feature.", - "ids": "879,28682" - }, - { - "examine": "A beautiful water feature.", - "ids": "880" - }, - { - "examine": "There's a cover over this manhole.", - "ids": "881" - }, - { - "examine": "How dangerous, someone has left this manhole open.", - "ids": "882" - }, - { - "examine": "This is supposed to stop people falling down the manhole.", - "ids": "883" - }, - { - "examine": "Best used with a bucket.", - "ids": "884" - }, - { - "examine": "If only I had one of those at home...", - "ids": "885,886" - }, - { - "examine": "A painting of the King looking royal.", - "ids": "887" - }, - { - "examine": "A beautiful landscape.", - "ids": "888" - }, - { - "examine": "A mysterious figure stands alone in this haunting image.", - "ids": "889" - }, - { - "examine": "Hail to the King!", - "ids": "890" - }, - { - "examine": "I don't know much about art, but I like this.", - "ids": "891" - }, - { - "examine": "A painting of some guy standing around somewhere.", - "ids": "892" - }, - { - "examine": "A really bad portrait of the King.", - "ids": "893" - }, - { - "examine": "Fine brushwork adds to the realism of this serene landscape.", - "ids": "894" - }, - { - "examine": "Pretty good painting.", - "ids": "895" - }, - { - "examine": "I can see the stars on this.", - "ids": "896" - }, - { - "examine": "A picture of the stars with funny diagrams and things on.", - "ids": "897" - }, - { - "examine": "Cross shaped.", - "ids": "898" - }, - { - "examine": "Mmmm decorative!", - "ids": "899" - }, - { - "examine": "Brightens up the room a bit.", - "ids": "900" - }, - { - "examine": "I don't know art, but I like it!", - "ids": "901" - }, - { - "examine": "Not bad at all.", - "ids": "902" - }, - { - "examine": "Alas poor unicorn, I knew him well.", - "ids": "903" - }, - { - "examine": "The scary-looking head of a scary-looking dragon.", - "ids": "904" - }, - { - "examine": "Not what I would pick as wall decoration.", - "ids": "905" - }, - { - "examine": "Looks like the bull lost.", - "ids": "906" - }, - { - "examine": "Trinkets and stuff.", - "ids": "907" - }, - { - "examine": "Not everyone's idea of a nice wall decoration.", - "ids": "908" - }, - { - "examine": "Something is written on it. I can't read what.", - "ids": "909" - }, - { - "examine": "Looks like an eye with huge lashes.", - "ids": "910" - }, - { - "examine": "A tablet covered in weird looking little squiggles and pictures.", - "ids": "911" - }, - { - "examine": "A posh water bowl.", - "ids": "915" - }, - { - "examine": "For wiping muddy feet on.", - "ids": "954" - }, - { - "examine": "Disturbingly its eyes look everywhere in the room except at you.", - "ids": "955,956,957,958" - }, - { - "examine": "What has a face and hands but is not a man?", - "ids": "959" - }, - { - "examine": "It's a time machine....sort of!", - "ids": "960" - }, - { - "examine": "'Ask about our low, low interest rates!'", - "ids": "961" - }, - { - "examine": "Some helpful people have placed notes on here, how nice.", - "ids": "962" - }, - { - "examine": "Essentials for a seamstress.", - "ids": "963" - }, - { - "examine": "It really was this big!", - "ids": "964,965" - }, - { - "examine": "He doesn't look too jolly to me!", - "ids": "966" - }, - { - "examine": "Looks like this ship was way off course!", - "ids": "967" - }, - { - "examine": "X marks the spot.", - "ids": "968" - }, - { - "examine": "Complete with authentic seaweed!", - "ids": "969" - }, - { - "examine": "This mentions the monk trapped here...", - "ids": "970" - }, - { - "examine": "A useful ranging device.", - "ids": "971" - }, - { - "examine": "Use these with bows.", - "ids": "972" - }, - { - "examine": "A powerful throwing weapon.", - "ids": "973" - }, - { - "examine": "Improved Leather armour for archers.", - "ids": "974" - }, - { - "examine": "Leather made from the skin of a Dragon.", - "ids": "975" - }, - { - "examine": "I can climb over the fence with this..", - "ids": "993" - }, - { - "examine": "This section of railing has been broken", - "ids": "1004,1005" - }, - { - "examine": "There is a hole in this section of the railing.", - "ids": "1006,1007,1008,1009" - }, - { - "examine": "Someone was thirsty...", - "ids": "1010" - }, - { - "examine": "Full of lovely drinks!", - "ids": "1011,1012" - }, - { - "examine": "Storage for cookery items.", - "ids": "1013,32283,40055" - }, - { - "examine": "Storage for all needs.", - "ids": "1014,1015,1016,1017,1018,10495,10496,10497,10498,11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779,11780,11781,12980,30648,30649,30650,32284,40045,40046,40047" - }, - { - "examine": "What kind of sick person keeps a skull on their wall?", - "ids": "1019" - }, - { - "examine": "Esoteric artefacts.", - "ids": "1020" - }, - { - "examine": "I don't want to know what's in those little urns.", - "ids": "1021,1022,1023" - }, - { - "examine": "Used for storing things on.", - "ids": "1024" - }, - { - "examine": "Tailor made for needlework supplies", - "ids": "1025,1026" - }, - { - "examine": "Prepared hides hang here drying.", - "ids": "1027" - }, - { - "examine": "This contains dye for leather.", - "ids": "1028,1029" - }, - { - "examine": "Used to squeeze moisture from the hide.", - "ids": "1030,1031" - }, - { - "examine": "Danger!", - "ids": "1032,5127" - }, - { - "examine": "This tells you which way is which.", - "ids": "1033,1034,1035" - }, - { - "examine": "Ye olde Shrimp and Parrot.", - "ids": "1057" - }, - { - "examine": "The Blue Moon Inn", - "ids": "1068" - }, - { - "examine": "The Jolly Boar", - "ids": "1069" - }, - { - "examine": "The Rusty Anchor", - "ids": "1070" - }, - { - "examine": "The Shrimp and Parrot", - "ids": "1071" - }, - { - "examine": "The Dead Man's Chest", - "ids": "1072" - }, - { - "examine": "The Rising Sun", - "ids": "1073" - }, - { - "examine": "The Forester's Arms", - "ids": "1074" - }, - { - "examine": "The Flying Horse", - "ids": "1075" - }, - { - "examine": "The Dancing Donkey", - "ids": "1076" - }, - { - "examine": "The Dragon Inn", - "ids": "1077" - }, - { - "examine": "Karamja Spirits bar", - "ids": "1078" - }, - { - "examine": "North to Varrock :: East to Al-Kharid.", - "ids": "1079" - }, - { - "examine": "North road to Draynor Village :: East road to Varrock.", - "ids": "1080" - }, - { - "examine": "North to Draynor Village.", - "ids": "1081" - }, - { - "examine": "North to Draynor Manor :: West to Asgarnia.", - "ids": "1082" - }, - { - "examine": "South to the Wizards' Tower :: East to Lumbridge.", - "ids": "1083" - }, - { - "examine": "South to Lumbridge :: West to Varrock :: East to the Digsite.", - "ids": "1084" - }, - { - "examine": "South to Al-Kharid :: West to Lumbridge :: East to the Digsite.", - "ids": "1085" - }, - { - "examine": "North to Varrock :: East to the Digsite.", - "ids": "1086" - }, - { - "examine": "South to the Wizards' Tower :: North to Draynor Village :: East to Lumbridge.", - "ids": "1087" - }, - { - "examine": "The ideal thing to sit on.", - "ids": "1088,1115,3801,5345,5614,7385,7386,7387,10491,11489,12885,12886,13582,32032,36830,40039" - }, - { - "examine": "Not so good for sitting on.", - "ids": "1089" - }, - { - "examine": "A comfortable seat.", - "ids": "1090,1091,1092,11760,13583,13584,13585,13586,13587,32286" - }, - { - "examine": "Good for sitting on.", - "ids": "1093,1094,1095,1102,5880,10492,12440,12441,12973,32033" - }, - { - "examine": "Good for rocking in!", - "ids": "1096" - }, - { - "examine": "A kingly seat for a royal behind.", - "ids": "1097,1098,1099,1105,1108,1109,32285" - }, - { - "examine": "The perfect way to sit at the bar.", - "ids": "1100,1101" - }, - { - "examine": "Gnomes sit on these.", - "ids": "1103" - }, - { - "examine": "Gnomes are found sitting here.", - "ids": "1104" - }, - { - "examine": "Sit back and relax...", - "ids": "1106,1107" - }, - { - "examine": "Used for sitting on.", - "ids": "1110" - }, - { - "examine": "Do I dare sit on this?", - "ids": "1111" - }, - { - "examine": "Church seating.", - "ids": "1112" - }, - { - "examine": "Park it here...", - "ids": "1113" - }, - { - "examine": "Wouldn't like to sit on that for too long...", - "ids": "1114" - }, - { - "examine": "Keeps the neighbours out!", - "ids": "1116,1117" - }, - { - "examine": "Found in wild areas.", - "ids": "1118" - }, - { - "examine": "These are commonly found.", - "ids": "1119" - }, - { - "examine": "An unusual bush.", - "ids": "1120" - }, - { - "examine": "A wild bush.", - "ids": "1121" - }, - { - "examine": "All the leaves have fallen off.", - "ids": "1122,1123" - }, - { - "examine": "A commonly found bush.", - "ids": "1124,36782" - }, - { - "examine": "Bushy!", - "ids": "1125" - }, - { - "examine": "A rose by any other name would still have prickly bits.", - "ids": "1126" - }, - { - "examine": "A leafy bush.", - "ids": "1144,1145,1146" - }, - { - "examine": "The abode of a fairy.", - "ids": "1147,1148,1149" - }, - { - "examine": "Fairies need money too!", - "ids": "1150" - }, - { - "examine": "A fairy is selling items here.", - "ids": "1151" - }, - { - "examine": "A small potted plant.", - "ids": "1152" - }, - { - "examine": "Someone has planted this.", - "ids": "1153" - }, - { - "examine": "A nicely potted fern.", - "ids": "1154" - }, - { - "examine": "Better than weeding.", - "ids": "1155" - }, - { - "examine": "I bet bees like this.", - "ids": "1156,1157" - }, - { - "examine": "A large potted plant.", - "ids": "1158,1159" - }, - { - "examine": "A plant in a bamboo pot.", - "ids": "1160" - }, - { - "examine": "Cabbage... yuck!", - "ids": "1161" - }, - { - "examine": "Found near the water's edge.", - "ids": "1162" - }, - { - "examine": "Not good for eating.", - "ids": "1163,1164" - }, - { - "examine": "Fungal growth.", - "ids": "1165" - }, - { - "examine": "Poisonous no doubt.", - "ids": "1166" - }, - { - "examine": "Fungal growth.", - "ids": "1167" - }, - { - "examine": "Poisonous no doubt.", - "ids": "1168,1169" - }, - { - "examine": "I doubt that's edible.", - "ids": "1170,1171,1172" - }, - { - "examine": "A commonly found fern.", - "ids": "1173" - }, - { - "examine": "Spiky!", - "ids": "1174" - }, - { - "examine": "A home for frogs.", - "ids": "1175" - }, - { - "examine": "Otherwise known as a lilypad.", - "ids": "1176" - }, - { - "examine": "A home for frogs.", - "ids": "1177" - }, - { - "examine": "Smells lovely!", - "ids": "1178" - }, - { - "examine": "Who is this Heather girl?", - "ids": "1179" - }, - { - "examine": "I wonder why it's purple?", - "ids": "1180" - }, - { - "examine": "I'd better not get stung.", - "ids": "1181,1182,1183" - }, - { - "examine": "The tendrils of a creeping plant.", - "ids": "1184" - }, - { - "examine": "Nicely planted.", - "ids": "1185" - }, - { - "examine": "A large curling plant.", - "ids": "1186" - }, - { - "examine": "That's pretty.", - "ids": "1187" - }, - { - "examine": "Blooming!", - "ids": "1188" - }, - { - "examine": "Commonly found in grassy areas.", - "ids": "1189" - }, - { - "examine": "Is this the biggest flower around?", - "ids": "1190" - }, - { - "examine": "These are huge!", - "ids": "1191" - }, - { - "examine": "A rare flower.", - "ids": "1192" - }, - { - "examine": "Don't flowers make you feel better?", - "ids": "1193" - }, - { - "examine": "Can this talk?", - "ids": "1194" - }, - { - "examine": "You don't see that many of these.", - "ids": "1195" - }, - { - "examine": "I wonder what these are?", - "ids": "1196" - }, - { - "examine": "A rarely found flower.", - "ids": "1197" - }, - { - "examine": "Very rare flowers.", - "ids": "1198" - }, - { - "examine": "These smell nice.", - "ids": "1199" - }, - { - "examine": "A bed of red flowers.", - "ids": "1200" - }, - { - "examine": "These are pretty.", - "ids": "1201" - }, - { - "examine": "Found only in jungle areas.", - "ids": "1202" - }, - { - "examine": "A very rare exotic flower.", - "ids": "1203" - }, - { - "examine": "A small fernlike plant.", - "ids": "1204" - }, - { - "examine": "The leaves of a nasty creeping plant.", - "ids": "1205" - }, - { - "examine": "The flower of a nasty creeping plant.", - "ids": "1206,1207,1208" - }, - { - "examine": "Nasty curling tendrils of a creeping plant.", - "ids": "1231" - }, - { - "examine": "One of the most common trees in 2009Scape.", - "ids": "1276" - }, - { - "examine": "A healthy young tree.", - "ids": "1277" - }, - { - "examine": "A commonly found tree.", - "ids": "1278,1279" - }, - { - "examine": "A healthy young tree.", - "ids": "1280" - }, - { - "examine": "A beautiful old oak.", - "ids": "1281" - }, - { - "examine": "This tree has long been dead.", - "ids": "1282,1283,1284" - }, - { - "examine": "An old weather beaten tree.", - "ids": "1285" - }, - { - "examine": "It's only useful for firewood now.", - "ids": "1286,1287,1288,1289,1290,1291" - }, - { - "examine": "An ancient magical tree.", - "ids": "1292" - }, - { - "examine": "An ancient sentient tree.", - "ids": "1293,1294,1295" - }, - { - "examine": "This tree has fallen to the ground.", - "ids": "1296" - }, - { - "examine": "This tree was either the victim of weather or mankind.", - "ids": "1297" - }, - { - "examine": "A commonly found fern.", - "ids": "1298" - }, - { - "examine": "Is this a weed?", - "ids": "1299" - }, - { - "examine": "A fern is growing here.", - "ids": "1300" - }, - { - "examine": "Home to many unusual creatures.", - "ids": "1301" - }, - { - "examine": "A leafy tree.", - "ids": "1302" - }, - { - "examine": "A tree found in tropical areas.", - "ids": "1303,1304,1305" - }, - { - "examine": "The tree shimmers with a magical force.", - "ids": "1306" - }, - { - "examine": "I bet this makes good syrup!", - "ids": "1307" - }, - { - "examine": "These trees are found near water.", - "ids": "1308" - }, - { - "examine": "A splendid tree.", - "ids": "1309" - }, - { - "examine": "This tree has vines hanging from it.", - "ids": "1310" - }, - { - "examine": "This would be good to sleep under.", - "ids": "1311" - }, - { - "examine": "An essential for tropical islands.", - "ids": "1312" - }, - { - "examine": "An unusual tree grows here.", - "ids": "1313,1314" - }, - { - "examine": "A hardy evergreen tree.", - "ids": "1315,1316" - }, - { - "examine": "A young sentient tree.", - "ids": "1317" - }, - { - "examine": "This would make good firewood.", - "ids": "1318,1319" - }, - { - "examine": "The branch is infested with moss.", - "ids": "1320,1321" - }, - { - "examine": "The trunk of this tree is hollow.", - "ids": "1322" - }, - { - "examine": "A gnarly old tree root.", - "ids": "1323" - }, - { - "examine": "The roots of a tree are exposed.", - "ids": "1324" - }, - { - "examine": "I hope I don't trip over any of these.", - "ids": "1325" - }, - { - "examine": "A terribly tall tropical tree.", - "ids": "1326,1327,1328" - }, - { - "examine": "Leaves of a bamboo tree.", - "ids": "1329" - }, - { - "examine": "It's thick with snow.", - "ids": "1330,1331,1332" - }, - { - "examine": "This old tree has been taken over by parasitic plants.", - "ids": "1333" - }, - { - "examine": "This old tree is rotting away.", - "ids": "1334,1335,1336,1337,1338" - }, - { - "examine": "They're just waiting to trip someone up.", - "ids": "1339,1340" - }, - { - "examine": "This tree has been cut down.", - "ids": "1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359" - }, - { - "examine": "This tree contains dangerous insects no doubt.", - "ids": "1360,1361,1362" - }, - { - "examine": "They're just waiting to trip someone up.", - "ids": "1363,1364" - }, - { - "examine": "It's only useful for firewood now.", - "ids": "1365" - }, - { - "examine": "A gnarly old tree root.", - "ids": "1366" - }, - { - "examine": "The roots of this tree are exposed.", - "ids": "1367" - }, - { - "examine": "I hope I don't trip over any of these.", - "ids": "1368" - }, - { - "examine": "An unusual tree grows here.", - "ids": "1369" - }, - { - "examine": "This old tree is rotting away.", - "ids": "1370" - }, - { - "examine": "This tree contains dangerous insects no doubt.", - "ids": "1371,1372,1373,1374,1375,1376,1377" - }, - { - "examine": "This old tree is rotting away.", - "ids": "1378,1379" - }, - { - "examine": "A gnarly old tree root.", - "ids": "1380" - }, - { - "examine": "The roots of this tree are exposed.", - "ids": "1381" - }, - { - "examine": "I hope I don't trip over any of these.", - "ids": "1382" - }, - { - "examine": "This tree has long been dead.", - "ids": "1383" - }, - { - "examine": "It's only useful for firewood now.", - "ids": "1384" - }, - { - "examine": "A gnarly old tree root.", - "ids": "1385" - }, - { - "examine": "The roots of this tree are exposed.", - "ids": "1386" - }, - { - "examine": "I hope I don't trip over any of these.", - "ids": "1387" - }, - { - "examine": "They're just waiting to trip someone up.", - "ids": "1388,1389" - }, - { - "examine": "Commonly found in these parts.", - "ids": "1390" - }, - { - "examine": "A leafy plant.", - "ids": "1391" - }, - { - "examine": "A leafy fern.", - "ids": "1392" - }, - { - "examine": "A small bushy plant.", - "ids": "1393" - }, - { - "examine": "A leafy shrub.", - "ids": "1394" - }, - { - "examine": "No flies on me.", - "ids": "1395" - }, - { - "examine": "How do these things manage to grow?", - "ids": "1396" - }, - { - "examine": "This cactus has recently had a chunk taken off.", - "ids": "1397" - }, - { - "examine": "A leafy fern.", - "ids": "1398" - }, - { - "examine": "This has broad leaves.", - "ids": "1399" - }, - { - "examine": "A large waxy jungle plant.", - "ids": "1400" - }, - { - "examine": "A type of jungle fern.", - "ids": "1401" - }, - { - "examine": "A large waxy jungle plant.", - "ids": "1402" - }, - { - "examine": "How do these things manage to grow?", - "ids": "1403,1404,1405,1406" - }, - { - "examine": "Leaves a nasty mark.", - "ids": "1407" - }, - { - "examine": "Looks spiky.", - "ids": "1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503" - }, - { - "examine": "The door is open.", - "ids": "1504" - }, - { - "examine": "The door is closed.", - "ids": "1505" - }, - { - "examine": "A sturdy wooden door.", - "ids": "1506,1507,1508,1509,1510,1511,1512,1513,1514,1515" - }, - { - "examine": "The curtain is closed.", - "ids": "1526,1527,1528" - }, - { - "examine": "The curtain is open.", - "ids": "1529" - }, - { - "examine": "The door is closed.", - "ids": "1530" - }, - { - "examine": "The door is open.", - "ids": "1531,1532" - }, - { - "examine": "A nicely fitted door.", - "ids": "1533,1534,1535" - }, - { - "examine": "An ornately-fashioned door.", - "ids": "1536" - }, - { - "examine": "An elf-fashioned door.", - "ids": "1537,1538" - }, - { - "examine": "Solid bars of iron.", - "ids": "1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550" - }, - { - "examine": "A wooden gate.", - "ids": "1551,1552,1553,1554,1555,1556" - }, - { - "examine": "A wrought iron gate.", - "ids": "1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567" - }, - { - "examine": "I wonder what's under it?", - "ids": "1568,1569" - }, - { - "examine": "I wonder what's down there?", - "ids": "1570,1571" - }, - { - "examine": "This door has been boarded up.", - "ids": "1572" - }, - { - "examine": "A door to a grand place.", - "ids": "1573,1574,1575,1576" - }, - { - "examine": "The top of the archway.", - "ids": "1577,1578,1579" - }, - { - "examine": "The base of the archway.", - "ids": "1580,1581,1582" - }, - { - "examine": "There is something strange about this wall...", - "ids": "1583,1584,1585,1586,1587,1588" - }, - { - "examine": "A wrought iron gate.", - "ids": "1589,1590" - }, - { - "examine": "The door is closed.", - "ids": "1591" - }, - { - "examine": "Something is strange about this panel.", - "ids": "1592,1593" - }, - { - "examine": "An entranceway into the dungeon.", - "ids": "1594" - }, - { - "examine": "The way in.", - "ids": "1595" - }, - { - "examine": "A wrought iron gate.", - "ids": "1596,1597" - }, - { - "examine": "A wooden gate.", - "ids": "1598,1599" - }, - { - "examine": "The doors to the Magic Guild.", - "ids": "1600" - }, - { - "examine": "The doors to the Magic guild.", - "ids": "1601,1602,1603,1604,1605,1606,1607,1608" - }, - { - "examine": "A wooden structure used in the process of building.", - "ids": "1609,1610,1611,1612" - }, - { - "examine": "This timber is broken", - "ids": "1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660" - }, - { - "examine": "A pile of bricks.", - "ids": "1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721" - }, - { - "examine": "I can climb these stairs.", - "ids": "1722,36791" - }, - { - "examine": "They go down.", - "ids": "1723" - }, - { - "examine": "I can climb down these stairs.", - "ids": "1724" - }, - { - "examine": "I can climb up this.", - "ids": "1725,36768,36771" - }, - { - "examine": "I can climb down this.", - "ids": "1726,1727,1728" - }, - { - "examine": "I can climb this.", - "ids": "1729,36347,36363,36644" - }, - { - "examine": "Dare I go up?", - "ids": "1730" - }, - { - "examine": "These stairs look spooky!", - "ids": "1731,1732" - }, - { - "examine": "I can use these stairs to climb down.", - "ids": "1733" - }, - { - "examine": "I can climb these stairs.", - "ids": "1734" - }, - { - "examine": "A rickety old staircase.", - "ids": "1735" - }, - { - "examine": "I can climb down these stairs.", - "ids": "1736" - }, - { - "examine": "I can climb up these stairs.", - "ids": "1737,1738" - }, - { - "examine": "I can climb up or go down these stairs.", - "ids": "1739" - }, - { - "examine": "I can climb down these stairs.", - "ids": "1740,1741" - }, - { - "examine": "I can climb up these stairs.", - "ids": "1742" - }, - { - "examine": "I can climb up or go down these stairs.", - "ids": "1743" - }, - { - "examine": "I can climb down these stairs.", - "ids": "1744,1745" - }, - { - "examine": "I can climb down this.", - "ids": "1746" - }, - { - "examine": "I can climb this.", - "ids": "1747,1748" - }, - { - "examine": "I can climb down this.", - "ids": "1749" - }, - { - "examine": "I can climb this.", - "ids": "1750,1751" - }, - { - "examine": "I can't climb this.", - "ids": "1752" - }, - { - "examine": "It's useless.", - "ids": "1753" - }, - { - "examine": "I can climb down this.", - "ids": "1754" - }, - { - "examine": "I can climb this.", - "ids": "1755" - }, - { - "examine": "I can climb down this.", - "ids": "1756" - }, - { - "examine": "I can climb this.", - "ids": "1757" - }, - { - "examine": "Not much use really.", - "ids": "1758" - }, - { - "examine": "This leads downwards.", - "ids": "1759" - }, - { - "examine": "These can be useful.", - "ids": "1760" - }, - { - "examine": "Steps made from natural rock.", - "ids": "1761" - }, - { - "examine": "A rope hangs here.", - "ids": "1762,1763,1764" - }, - { - "examine": "I can climb down this.", - "ids": "1765" - }, - { - "examine": "I can climb this.", - "ids": "1766" - }, - { - "examine": "I can climb down this.", - "ids": "1767" - }, - { - "examine": "I can climb this.", - "ids": "1768,1769,1770,1771,1772,1773,1774,1775,1776,1777" - }, - { - "examine": "These huge stone discs grind grain to make flour.", - "ids": "1778" - }, - { - "examine": "These sails use the wind to drive the windmill.", - "ids": "1779,1780,1781" - }, - { - "examine": "I'll need an empty pot so I can collect my flour.", - "ids": "1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796" - }, - { - "examine": "Some very hard rocks, I wouldn't want to fall on those.", - "ids": "1797,1798,1799,1800,1801,1802,1803" - }, - { - "examine": "This door requires a key.", - "ids": "1804" - }, - { - "examine": "The door to the Champions' Guild.", - "ids": "1805,1806,1807,1808,1809" - }, - { - "examine": "Here be spiders!", - "ids": "1810" - }, - { - "examine": "I can walk through this tattered web.", - "ids": "1811" - }, - { - "examine": "A magical border of teleportation.", - "ids": "1812" - }, - { - "examine": "For putting things on.", - "ids": "1813" - }, - { - "examine": "I wonder what this does...", - "ids": "1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851" - }, - { - "examine": "This lets in more light.", - "ids": "1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863" - }, - { - "examine": "These obviously mean keep out!", - "ids": "1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875" - }, - { - "examine": "I shudder to think what has taken place here.", - "ids": "1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,32289" - }, - { - "examine": "This hasn't seen a duster for a while.", - "ids": "1896" - }, - { - "examine": "Not as nice as some.", - "ids": "1897" - }, - { - "examine": "This needs dusting before I'll sit on it.", - "ids": "1898,1899" - }, - { - "examine": "This could do with a bit of a spit and polish.", - "ids": "1900" - }, - { - "examine": "This clearly isn't used for dining very often.", - "ids": "1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938" - }, - { - "examine": "A tower.", - "ids": "1939,1940,1941,1942,1943,1944,1945,1946" - }, - { - "examine": "It looks like I might be able to climb over this piece of the wall...", - "ids": "1947,1948" - }, - { - "examine": "A pile of bricks.", - "ids": "1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966" - }, - { - "examine": "A grand door for a grand tree.", - "ids": "1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984" - }, - { - "examine": "A large root.", - "ids": "1985,1986" - }, - { - "examine": "A primitive looking boat.", - "ids": "1987" - }, - { - "examine": "Oops!", - "ids": "1988" - }, - { - "examine": "A good source of books!", - "ids": "1989" - }, - { - "examine": "A wooden crate for storage.", - "ids": "1990" - }, - { - "examine": "Solid bars of iron.", - "ids": "1991" - }, - { - "examine": "There is an indent the size of a pebble in the stone's centre.", - "ids": "1992" - }, - { - "examine": "A stone tomb surrounded by flowers.", - "ids": "1993" - }, - { - "examine": "I wonder what's inside.", - "ids": "1994,37016,37015" - }, - { - "examine": "Perhaps I should search it.", - "ids": "1995" - }, - { - "examine": "I should be safe if I can reach this.", - "ids": "1996,1997" - }, - { - "examine": "Wet rope.", - "ids": "1998" - }, - { - "examine": "A wooden crate for storage.", - "ids": "1999" - }, - { - "examine": "An elf-fashioned door.", - "ids": "2000,2001,2002,2003" - }, - { - "examine": "The pillar has a rune shaped dent in it.", - "ids": "2004" - }, - { - "examine": "A statue of Baxtorian chiselled in stone.", - "ids": "2005" - }, - { - "examine": "A statue of Glarial chiselled in stone.", - "ids": "2006,2007,2008,2009" - }, - { - "examine": "A ledge.", - "ids": "2010,2011,2012" - }, - { - "examine": "Known commonly as Red worm vine.", - "ids": "2013" - }, - { - "examine": "A magically elevated chalice full of tears.", - "ids": "2014" - }, - { - "examine": "A magically elevated chalice full of ash.", - "ids": "2015,2016,2017,2018" - }, - { - "examine": "A whirlpool.", - "ids": "2019" - }, - { - "examine": "It's too wet for firewood.", - "ids": "2020,2021" - }, - { - "examine": "A wooden barrel, maybe a way off this rock.", - "ids": "2022" - }, - { - "examine": "An interesting tree with long straight branches.", - "ids": "2023" - }, - { - "examine": "A large bubbling cauldron, smells... Ugh!", - "ids": "2024" - }, - { - "examine": "The door is closed.", - "ids": "2025" - }, - { - "examine": "I can see fish swimming in the water.", - "ids": "2026,2027,2028,2029,2030,2031" - }, - { - "examine": "It's closed.", - "ids": "2032" - }, - { - "examine": "It's open.", - "ids": "2033" - }, - { - "examine": "It's closed.", - "ids": "2034" - }, - { - "examine": "It's open.", - "ids": "2035" - }, - { - "examine": "It's closed.", - "ids": "2036" - }, - { - "examine": "It's open.", - "ids": "2037" - }, - { - "examine": "I've met less intelligent conversationalists.", - "ids": "2038" - }, - { - "examine": "It's closed.", - "ids": "2039,2040,2041,2042" - }, - { - "examine": "Something's bubbling away in it.", - "ids": "2043" - }, - { - "examine": "Like an animal dinner table.", - "ids": "2044,2045,2046,2047" - }, - { - "examine": "It's a door.", - "ids": "2048,2049" - }, - { - "examine": "A wooden gate.", - "ids": "2050,2051,2052,2053" - }, - { - "examine": "It's a door.", - "ids": "2054,2055" - }, - { - "examine": "It's closed.", - "ids": "2056" - }, - { - "examine": "It's open.", - "ids": "2057" - }, - { - "examine": "It's closed.", - "ids": "2058,2059,2060,2061,2062" - }, - { - "examine": "It's open.", - "ids": "2063" - }, - { - "examine": "For storage.", - "ids": "2064" - }, - { - "examine": "Used for climbing.", - "ids": "2065" - }, - { - "examine": "A wall.", - "ids": "2066" - }, - { - "examine": "A watchtower.", - "ids": "2067" - }, - { - "examine": "A fence.", - "ids": "2068" - }, - { - "examine": "A closed door.", - "ids": "2069,2070" - }, - { - "examine": "Used for storage.", - "ids": "2071,2072" - }, - { - "examine": "Grows weird yellow fruit.", - "ids": "2073,2074,2075,2076,2077,2078" - }, - { - "examine": "I wonder what's inside?", - "ids": "2079,2080" - }, - { - "examine": "Handy for boarding boats.", - "ids": "2081,2082,2083,2084,2085,2086,2087,2088" - }, - { - "examine": "Ornamental.", - "ids": "2089" - }, - { - "examine": "A rocky outcrop.", - "ids": "2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111" - }, - { - "examine": "The door is closed.", - "ids": "2112" - }, - { - "examine": "I can climb down this.", - "ids": "2113" - }, - { - "examine": "This transports coal!", - "ids": "2114" - }, - { - "examine": "The left hand side of the gate.", - "ids": "2115" - }, - { - "examine": "The right hand side of the gate.", - "ids": "2116" - }, - { - "examine": "It's an old wall.", - "ids": "2117" - }, - { - "examine": "Lots of water swirling around", - "ids": "2118" - }, - { - "examine": "A rocky outcrop.", - "ids": "2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140" - }, - { - "examine": "An open chest.", - "ids": "2141" - }, - { - "examine": "An eerie glow permeates the cauldron.", - "ids": "2142" - }, - { - "examine": "Looks secure.", - "ids": "2143,2144" - }, - { - "examine": "Ooooh! Spooky!", - "ids": "2145,2146" - }, - { - "examine": "Going down?", - "ids": "2147" - }, - { - "examine": "Going up?", - "ids": "2148" - }, - { - "examine": "An imposing stone structure.", - "ids": "2149" - }, - { - "examine": "A column of elemental power.", - "ids": "2150,2151,2152,2153,29415" - }, - { - "examine": "A wrought iron gate.", - "ids": "2154,2155" - }, - { - "examine": "A magical portal of teleportation.", - "ids": "2156,2157,2158" - }, - { - "examine": "It's a floating barrel.", - "ids": "2159,2160,2161" - }, - { - "examine": "Smells like fish.", - "ids": "2162,2163,2164,2165,2166" - }, - { - "examine": "Water is pouring in through the hole.", - "ids": "2167" - }, - { - "examine": "A patch of swamp tar has bunged up the hole.", - "ids": "2168" - }, - { - "examine": "There's a strong wind whipping up the sea.", - "ids": "2169,2170,2171" - }, - { - "examine": "A huge net to catch little fish.", - "ids": "2172,2173" - }, - { - "examine": "The upper deck can be accessed with this ladder.", - "ids": "2174" - }, - { - "examine": "Back down to the main deck.", - "ids": "2175" - }, - { - "examine": "This old trawler has seen better days.", - "ids": "2176,2177" - }, - { - "examine": "Handy for boarding boats.", - "ids": "2178,2179" - }, - { - "examine": "It's a war machine.", - "ids": "2180,2181" - }, - { - "examine": "It can't hurt to just have a look, can it?", - "ids": "2182" - }, - { - "examine": "I wonder what is inside...", - "ids": "2183" - }, - { - "examine": "The door is closed.", - "ids": "2184" - }, - { - "examine": "This wall has seen better days.", - "ids": "2185" - }, - { - "examine": "Hmmm... I wonder if it's loose enough to get through.", - "ids": "2186" - }, - { - "examine": "I can climb down this ladder.", - "ids": "2187" - }, - { - "examine": "I can climb up this ladder.", - "ids": "2188,2189" - }, - { - "examine": "I can climb down this ladder.", - "ids": "2190" - }, - { - "examine": "I wonder what's inside?", - "ids": "2191,2192,2193" - }, - { - "examine": "Perhaps I should search it.", - "ids": "2194,2195,2196" - }, - { - "examine": "I wonder what's inside?", - "ids": "2197" - }, - { - "examine": "Perhaps I should search it.", - "ids": "2198" - }, - { - "examine": "An old gate for locking up undesirables.", - "ids": "2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209" - }, - { - "examine": "Looking through it makes far off things look closer!", - "ids": "2210" - }, - { - "examine": "A weathered old gravestone.", - "ids": "2211" - }, - { - "examine": "Looks like fun.", - "ids": "2212" - }, - { - "examine": "The bank teller will serve you from here.", - "ids": "2213" - }, - { - "examine": "This booth is for private customers only.", - "ids": "2214,34205" - }, - { - "examine": "This booth is closed.", - "ids": "2215" - }, - { - "examine": "This looks like it's being used to block entrance to the village.", - "ids": "2216" - }, - { - "examine": "Something seems to be buried under this.", - "ids": "2217" - }, - { - "examine": "A narrow fissure in the ground.", - "ids": "2218,2219" - }, - { - "examine": "A pile of rubble.", - "ids": "2220" - }, - { - "examine": "A stone with some carvings on it.", - "ids": "2221" - }, - { - "examine": "A pile of loose rocks.", - "ids": "2222" - }, - { - "examine": "Probably nothing useful in these.", - "ids": "2223" - }, - { - "examine": "A rotten and barely standing set of gallows.", - "ids": "2224" - }, - { - "examine": "Wet rocks, it looks like you might be able to climb them.", - "ids": "2225" - }, - { - "examine": "This table has seen better days.", - "ids": "2226" - }, - { - "examine": "A crudely constructed raft.", - "ids": "2227,2228" - }, - { - "examine": "A statue to mark Tai Bwo Wannai sacred grounds.", - "ids": "2229" - }, - { - "examine": "A sturdy cart for travelling in.", - "ids": "2230" - }, - { - "examine": "A rocky outcrop.", - "ids": "2231,2232,2233" - }, - { - "examine": "Rocks that have been stacked at regular intervals.", - "ids": "2234" - }, - { - "examine": "An ancient construct for supporting the bones of the deceased.", - "ids": "2235" - }, - { - "examine": "I can climb the rocky outcrop.", - "ids": "2236" - }, - { - "examine": "An exotic looking tree.", - "ids": "2237" - }, - { - "examine": "Large doors set into the hillside.", - "ids": "2238,2239" - }, - { - "examine": "These doors must have been hidden here for years.", - "ids": "2240,2241" - }, - { - "examine": "Perhaps you should give them a push.", - "ids": "2242,2243" - }, - { - "examine": "Commonly found in these parts.", - "ids": "2244" - }, - { - "examine": "A leafy fern.", - "ids": "2245" - }, - { - "examine": "Large carved tomb doors, they look terrifying.", - "ids": "2246,2247,2248,2249,2250,2251,2252" - }, - { - "examine": "Perhaps you should give them a push.", - "ids": "2253,2254" - }, - { - "examine": "An ancient metal gate, but still pretty secure.", - "ids": "2255,2256" - }, - { - "examine": "A rocky outcrop.", - "ids": "2257" - }, - { - "examine": "An ancient construct for supporting the bones of the deceased.", - "ids": "2258" - }, - { - "examine": "The gate is closed.", - "ids": "2259,2260,2261,2262,2263,2264" - }, - { - "examine": "A sturdy cart for travelling in.", - "ids": "2265" - }, - { - "examine": "The door is closed.", - "ids": "2266,2267" - }, - { - "examine": "This leads up to the sleeping area.", - "ids": "2268" - }, - { - "examine": "This leads downwards.", - "ids": "2269" - }, - { - "examine": "A jungle plant.", - "ids": "2270" - }, - { - "examine": "I wonder what's inside?", - "ids": "2271" - }, - { - "examine": "It's open.", - "ids": "2272" - }, - { - "examine": "An odd-looking rock with a rope tied to it.", - "ids": "2273,2274" - }, - { - "examine": "An odd-looking rock formation.", - "ids": "2275,2276,2277,2278" - }, - { - "examine": "Holds the rope up. Hopefuly.", - "ids": "2279,2280,2281" - }, - { - "examine": "Use this to swing over crevices.", - "ids": "2282,2283" - }, - { - "examine": "This must be climbed over.", - "ids": "2284,2285,2286" - }, - { - "examine": "It's hollow...", - "ids": "2289" - }, - { - "examine": "A slippery log I can walk across.", - "ids": "2294,2295,2296,2297" - }, - { - "examine": "The irregular surface can be climbed.", - "ids": "2298,2299,2300" - }, - { - "examine": "Tread carefully!", - "ids": "2301,2302" - }, - { - "examine": "I can just about edge across here.", - "ids": "2303" - }, - { - "examine": "Pointy!", - "ids": "2304,2305,2306" - }, - { - "examine": "A wrought iron gate.", - "ids": "2307,2308" - }, - { - "examine": "Solid bars of iron.", - "ids": "2309" - }, - { - "examine": "This tree has been cut down.", - "ids": "2310" - }, - { - "examine": "I can jump from this stepping stone.", - "ids": "2311" - }, - { - "examine": "I can balance on this rope.", - "ids": "2312" - }, - { - "examine": "I can climb up this.", - "ids": "2313" - }, - { - "examine": "I can climb down here.", - "ids": "2314,2315" - }, - { - "examine": "I can climb up these stairs.", - "ids": "2316,36776" - }, - { - "examine": "I can climb up these rocks to another cave.", - "ids": "2317" - }, - { - "examine": "I can climb down these rocks to another cave.", - "ids": "2318" - }, - { - "examine": "I can traverse these.", - "ids": "2319,2320,2321,12573,12574,12575,29375" - }, - { - "examine": "Use this to swing across gaps.", - "ids": "2322,2323,2324" - }, - { - "examine": "I can swing on this tree.", - "ids": "2325" - }, - { - "examine": "A branch protrudes here.", - "ids": "2326" - }, - { - "examine": "This tree has an unusually long branch on it.", - "ids": "2327" - }, - { - "examine": "A rocky outcrop.", - "ids": "2328,2329,2330,2331" - }, - { - "examine": "A nearly rotten wooden log that crosses the river.", - "ids": "2332" - }, - { - "examine": "A rocky outcrop from the running water.", - "ids": "2333,2334,2335" - }, - { - "examine": "You can see a cauldron directly below.", - "ids": "2336" - }, - { - "examine": "This door is very sturdy looking.", - "ids": "2337" - }, - { - "examine": "This door is closed.", - "ids": "2338" - }, - { - "examine": "This door is very sturdy looking.", - "ids": "2339,2340" - }, - { - "examine": "There is something strange about this wall...", - "ids": "2341" - }, - { - "examine": "Looks like a ventilation grill.", - "ids": "2342" - }, - { - "examine": "A large stone block.", - "ids": "2343,2344,2345,2346,2347,2348,2349" - }, - { - "examine": "Used to move earth to, and from, the dig shaft.", - "ids": "2350,2351" - }, - { - "examine": "This leads back up the dig shaft.", - "ids": "2352,2353" - }, - { - "examine": "Yep, they're sacks!", - "ids": "2354,2355,2356" - }, - { - "examine": "A leafy bush.", - "ids": "2357,2358" - }, - { - "examine": "A sealed barrel with a warning sign on it.", - "ids": "2359" - }, - { - "examine": "I wonder what's inside...", - "ids": "2360" - }, - { - "examine": "A sturdy chest to keep things in.", - "ids": "2361" - }, - { - "examine": "A large stone block.", - "ids": "2362" - }, - { - "examine": "A place where you can pan for gold.", - "ids": "2363" - }, - { - "examine": "A wooden container.", - "ids": "2364,2365" - }, - { - "examine": "A signpost!", - "ids": "2366,2367,2368,2369,2370,2371" - }, - { - "examine": "Shelves filled with interesting books.", - "ids": "2372" - }, - { - "examine": "A cupboard.", - "ids": "2373,2374" - }, - { - "examine": "Used to keep specimens on.", - "ids": "2375" - }, - { - "examine": "Soil. Dug up!", - "ids": "2376,2377,2378" - }, - { - "examine": "Technically a bed.", - "ids": "2379" - }, - { - "examine": "I wonder what's inside...", - "ids": "2380" - }, - { - "examine": "Swampy dirt.", - "ids": "2381,2382,2383,2384,2385,2386,2387,2388,2389,2390" - }, - { - "examine": "A very solid looking gate.", - "ids": "2391,2392" - }, - { - "examine": "Aim for the goal!", - "ids": "2393" - }, - { - "examine": "A gate to the Gnomeball pitch.", - "ids": "2394,2395" - }, - { - "examine": "Distinctly feminine.", - "ids": "2396" - }, - { - "examine": "A solid looking door.", - "ids": "2397,2398,2399" - }, - { - "examine": "Might be worth searching.", - "ids": "2400,2401" - }, - { - "examine": "A good source of books!", - "ids": "2402" - }, - { - "examine": "Might be worth searching.", - "ids": "2403,2404" - }, - { - "examine": "I can climb this.", - "ids": "2405" - }, - { - "examine": "The door is closed.", - "ids": "2406,2407" - }, - { - "examine": "I can climb down this.", - "ids": "2408,36693,36694" - }, - { - "examine": "A commonly found tree.", - "ids": "2409" - }, - { - "examine": "I can climb this.", - "ids": "2410" - }, - { - "examine": "The door is closed.", - "ids": "2411" - }, - { - "examine": "Handy for boarding the ship.", - "ids": "2412,2413,2414,2415" - }, - { - "examine": "Pull me!", - "ids": "2416" - }, - { - "examine": "Place party drop items here.", - "ids": "2417,2418,2419,2420" - }, - { - "examine": "This lever is down.", - "ids": "2421" - }, - { - "examine": "This lever is up.", - "ids": "2422" - }, - { - "examine": "This lever is down.", - "ids": "2423" - }, - { - "examine": "This lever is up.", - "ids": "2424" - }, - { - "examine": "This lever is down.", - "ids": "2425" - }, - { - "examine": "This lever is up.", - "ids": "2426" - }, - { - "examine": "This door is closed by an unknown mechanism.", - "ids": "2427,2428,2429,2430,2431" - }, - { - "examine": "This gate is closed shut.", - "ids": "2432,2433" - }, - { - "examine": "This may be worth opening.", - "ids": "2434,2435" - }, - { - "examine": "I wonder what's inside.", - "ids": "2436,2437" - }, - { - "examine": "A wooden gate.", - "ids": "2438,2439" - }, - { - "examine": "Wonder what this pillar is for?", - "ids": "2440,2441,2442,2443" - }, - { - "examine": "I wonder what's under it?", - "ids": "2444,2445" - }, - { - "examine": "This leads to somewhere...but where?", - "ids": "2446" - }, - { - "examine": "I reckon I could climb that!", - "ids": "2447,2448" - }, - { - "examine": "Some magical rocks.", - "ids": "2449,2450" - }, - { - "examine": "There's something behind these roots.", - "ids": "2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464" - }, - { - "examine": "A portal from this mystical place.", - "ids": "2465,2466,2467,2468,2469,2470,2471,2472,2473,2474,2475,2476,2477" - }, - { - "examine": "A mysterious power emanates from this shrine.", - "ids": "2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490" - }, - { - "examine": "The source of all Rune Stones.", - "ids": "2491" - }, - { - "examine": "A portal from this mystical place.", - "ids": "2492" - }, - { - "examine": "A part of an old temple.", - "ids": "2493,2494,2495,2496" - }, - { - "examine": "Unusual energy is gathered here.", - "ids": "2497,2498,2499,2500,2501,2502" - }, - { - "examine": "An old crumbled pillar.", - "ids": "2503,2504,2505,2506,2507" - }, - { - "examine": "Broken parts of an old temple.", - "ids": "2508,2509,2510" - }, - { - "examine": "This leads to the practice tower.", - "ids": "2511" - }, - { - "examine": "This leads back down to the guild.", - "ids": "2512" - }, - { - "examine": "I wonder if I can hit a bullseye?", - "ids": "2513" - }, - { - "examine": "The door to the Ranging Guild.", - "ids": "2514" - }, - { - "examine": "I hope it doesn't sink.", - "ids": "2515" - }, - { - "examine": "It's sinking!", - "ids": "2516" - }, - { - "examine": "Going up?", - "ids": "2517" - }, - { - "examine": "Typical shoddy workmanship.", - "ids": "2518" - }, - { - "examine": "Crates of packed fish.", - "ids": "2519" - }, - { - "examine": "It's used for loading and unloading fishing boats.", - "ids": "2520,2521" - }, - { - "examine": "It's a flight of stairs.", - "ids": "2522,2523" - }, - { - "examine": "I wonder what's inside?", - "ids": "2524" - }, - { - "examine": "It's open.", - "ids": "2525" - }, - { - "examine": "The door of a small prison.", - "ids": "2526,2527" - }, - { - "examine": "The door is closed.", - "ids": "2528" - }, - { - "examine": "A door.", - "ids": "2529" - }, - { - "examine": "Used for storage.", - "ids": "2530" - }, - { - "examine": "Looks like someone's tried digging here.", - "ids": "2531,2532" - }, - { - "examine": "A pile of what is hopefully mud.", - "ids": "2533" - }, - { - "examine": "There's black cross on the door.", - "ids": "2534" - }, - { - "examine": "The door is closed.", - "ids": "2535" - }, - { - "examine": "A door.", - "ids": "2536" - }, - { - "examine": "The door is closed.", - "ids": "2537" - }, - { - "examine": "A door.", - "ids": "2538" - }, - { - "examine": "A flight of stairs.", - "ids": "2539,2540" - }, - { - "examine": "An outlet to the sewer.", - "ids": "2541,2542" - }, - { - "examine": "There's a cover over this manhole.", - "ids": "2543" - }, - { - "examine": "How dangerous, someone has left this manhole open.", - "ids": "2544" - }, - { - "examine": "This is supposed to stop people falling down the manhole.", - "ids": "2545" - }, - { - "examine": "A door.", - "ids": "2546,2547,2548,2549" - }, - { - "examine": "A secure door.", - "ids": "2550,2551" - }, - { - "examine": "A metal gate bars your way.", - "ids": "2552,2553" - }, - { - "examine": "A secure door.", - "ids": "2554,2555,2556,2557,2558,2559" - }, - { - "examine": "Fine silk woven by experts.", - "ids": "2560" - }, - { - "examine": "This stall smells great.", - "ids": "2561" - }, - { - "examine": "Precious stones from around the world.", - "ids": "2562" - }, - { - "examine": "All manner of animal clothing.", - "ids": "2563" - }, - { - "examine": "Spices to tingle your taste buds.", - "ids": "2564" - }, - { - "examine": "Fine silver items are for sale here.", - "ids": "2565" - }, - { - "examine": "I wonder what's inside it.", - "ids": "2566,2567,2568,2569,2570,2571,2572,2573,2574" - }, - { - "examine": "A marshy jungle vine.", - "ids": "2575,2576" - }, - { - "examine": "A tall palm tree with some plants growing at its stem.", - "ids": "2577" - }, - { - "examine": "A tall palm tree.", - "ids": "2578" - }, - { - "examine": "The burnt ground has a plant growing on it.", - "ids": "2579" - }, - { - "examine": "The ground has been burnt here by a fire.", - "ids": "2580" - }, - { - "examine": "A rock with green moss growing on it.", - "ids": "2581" - }, - { - "examine": "A rock, it looks like something was growing here.", - "ids": "2582" - }, - { - "examine": "It looks as if it is covered in some fungus.", - "ids": "2583" - }, - { - "examine": "A collection of rocks over what looks like a depression.", - "ids": "2584" - }, - { - "examine": "Rocky walls, you may be able to climb it.", - "ids": "2585" - }, - { - "examine": "It's closed.", - "ids": "2586" - }, - { - "examine": "I wonder what's inside?", - "ids": "2587" - }, - { - "examine": "It's open.", - "ids": "2588" - }, - { - "examine": "This ship's not getting far with that.", - "ids": "2589" - }, - { - "examine": "Takes me into the ship.", - "ids": "2590,2591" - }, - { - "examine": "Takes me back on deck.", - "ids": "2592" - }, - { - "examine": "Handy for boarding the ship.", - "ids": "2593,2594" - }, - { - "examine": "It's closed.", - "ids": "2595" - }, - { - "examine": "A blood-red door.", - "ids": "2596" - }, - { - "examine": "A lurid orange door.", - "ids": "2597" - }, - { - "examine": "A sickly yellow door.", - "ids": "2598" - }, - { - "examine": "A gloomy blue door.", - "ids": "2599" - }, - { - "examine": "A groovy magenta door.", - "ids": "2600" - }, - { - "examine": "A putrid green door.", - "ids": "2601" - }, - { - "examine": "Probably the nicest door in this ghastly place.", - "ids": "2602" - }, - { - "examine": "It's closed.", - "ids": "2603" - }, - { - "examine": "It's open.", - "ids": "2604" - }, - { - "examine": "It's a ladder.", - "ids": "2605" - }, - { - "examine": "There is something strange about this wall...", - "ids": "2606" - }, - { - "examine": "It's closed.", - "ids": "2607,2608" - }, - { - "examine": "A collection of rocks over what looks like a depression.", - "ids": "2609" - }, - { - "examine": "A rope hangs here that I can climb.", - "ids": "2610" - }, - { - "examine": "It's a ladder.", - "ids": "2611" - }, - { - "examine": "Wonder what's in here...", - "ids": "2612" - }, - { - "examine": "Smells kind of funny...", - "ids": "2613" - }, - { - "examine": "Looks comfortable...", - "ids": "2615" - }, - { - "examine": "Looks spooky...", - "ids": "2616" - }, - { - "examine": "Phew, an exit!", - "ids": "2617" - }, - { - "examine": "The fence is broken at this point.", - "ids": "2618" - }, - { - "examine": "A wooden barrel for storage.", - "ids": "2619" - }, - { - "examine": "An old crate for storage.", - "ids": "2620" - }, - { - "examine": "It's a door.", - "ids": "2621,2622" - }, - { - "examine": "It's a gate.", - "ids": "2623" - }, - { - "examine": "The entrance to the Hero's Guild.", - "ids": "2624,2625" - }, - { - "examine": "It's a door.", - "ids": "2626,2627,2628" - }, - { - "examine": "There is something unusual about this wall...", - "ids": "2629" - }, - { - "examine": "I can see eels swimming in the lava.", - "ids": "2630" - }, - { - "examine": "It's a door.", - "ids": "2631" - }, - { - "examine": "I wonder what's inside?", - "ids": "2632" - }, - { - "examine": "It's open.", - "ids": "2633" - }, - { - "examine": "Rocks that contain nothing interesting, but block the way.", - "ids": "2634" - }, - { - "examine": "I wonder what's inside?", - "ids": "2635" - }, - { - "examine": "It's open.", - "ids": "2636,2637" - }, - { - "examine": "A source of pure water.", - "ids": "2638,2639" - }, - { - "examine": "A shrine for the faithful to worship at.", - "ids": "2640" - }, - { - "examine": "I can climb this.", - "ids": "2641" - }, - { - "examine": "Used for fashioning clay items.", - "ids": "2642" - }, - { - "examine": "Bake your clay items in here.", - "ids": "2643" - }, - { - "examine": "Used for spinning thread.", - "ids": "2644" - }, - { - "examine": "A tray of sand.", - "ids": "2645" - }, - { - "examine": "A plant cultivated for fibres.", - "ids": "2646" - }, - { - "examine": "The door to the Crafting Guild.", - "ids": "2647,2648,2649" - }, - { - "examine": "A pile of smelly rotting waste.", - "ids": "2650" - }, - { - "examine": "A sturdy home for bees.", - "ids": "2651" - }, - { - "examine": "Looks like this is where waste from the kitchen comes out.", - "ids": "2652" - }, - { - "examine": "It looks like a spiders' nest to me.", - "ids": "2653" - }, - { - "examine": "This fountain suits the garden.", - "ids": "2654" - }, - { - "examine": "It's the Sinclair Family coat of arms.", - "ids": "2655" - }, - { - "examine": "Looks like this is where Anna keeps her stuff.", - "ids": "2656" - }, - { - "examine": "Looks like this is where Bob keeps his stuff.", - "ids": "2657" - }, - { - "examine": "Looks like this is where Carol keeps her stuff.", - "ids": "2658" - }, - { - "examine": "Looks like this is where David keeps his stuff.", - "ids": "2659" - }, - { - "examine": "Looks like this is where Elizabeth keeps her stuff.", - "ids": "2660" - }, - { - "examine": "Looks like this is where Frank keeps his stuff.", - "ids": "2661" - }, - { - "examine": "Looks like this is where the cook stores flour.", - "ids": "2662" - }, - { - "examine": "Some sacks of general garden items.", - "ids": "2663" - }, - { - "examine": "Luckily it seems able to keep that vicious dog inside.", - "ids": "2664,2665" - }, - { - "examine": "Looks like the killer smashed this to leave the mansion.", - "ids": "2666" - }, - { - "examine": "Slaves are using this to pull up barrels of rocks from down below.", - "ids": "2667" - }, - { - "examine": "Slaves are placing barrels on this to haul them to the surface.", - "ids": "2668,2669" - }, - { - "examine": "A succulent cactus.", - "ids": "2670" - }, - { - "examine": "A less-than-succulent succulent.", - "ids": "2671" - }, - { - "examine": "I can try to make new items on this.", - "ids": "2672" - }, - { - "examine": "A solid looking gate.", - "ids": "2673,2674" - }, - { - "examine": "Large doors made of solid oak.", - "ids": "2675,2676" - }, - { - "examine": "A solid looking chest, it belongs to Captain Siad.", - "ids": "2677" - }, - { - "examine": "A selection of Captain Siad's Books.", - "ids": "2678" - }, - { - "examine": "A sturdy looking desk on which the Captain works.", - "ids": "2679" - }, - { - "examine": "A barrel containing rocks and mining debris.", - "ids": "2680" - }, - { - "examine": "An empty mining barrel.", - "ids": "2681" - }, - { - "examine": "The cart which takes barrels of rocks from the mining encampment to Al-Kharid.", - "ids": "2682" - }, - { - "examine": "Gives a lovely view of the desert, complete with metalic bars.", - "ids": "2683" - }, - { - "examine": "It seems to be used for moving rocks into and out of this area.", - "ids": "2684" - }, - { - "examine": "A solid looking gate.", - "ids": "2685,2686,2687,2688" - }, - { - "examine": "There's no getting around it, it's a fairly sturdy prison cell door.", - "ids": "2689" - }, - { - "examine": "Large solid, thick set oak doors", - "ids": "2690,2691" - }, - { - "examine": "It looks fairly sturdy.", - "ids": "2692" - }, - { - "examine": "This is used by Shantay and his men to take items to the bank on your behalf.", - "ids": "2693" - }, - { - "examine": "A rocky rock.", - "ids": "2694,2695,2696,2697" - }, - { - "examine": "A cave which has been mined out.", - "ids": "2698,2699" - }, - { - "examine": "The entrance to the tent.", - "ids": "2700,2701" - }, - { - "examine": "Tracks in the sand.", - "ids": "2702,2703" - }, - { - "examine": "Rocky!", - "ids": "2704" - }, - { - "examine": "It's a door.", - "ids": "2705" - }, - { - "examine": "A nicely fitted door.", - "ids": "2706" - }, - { - "examine": "A wooden crate for storage.", - "ids": "2707,2708" - }, - { - "examine": "I wonder what's inside?", - "ids": "2709" - }, - { - "examine": "It's open.", - "ids": "2710" - }, - { - "examine": "It's a flight of stairs.", - "ids": "2711" - }, - { - "examine": "The door is closed.", - "ids": "2712" - }, - { - "examine": "Grain goes in here.", - "ids": "2713,2714,2715,2716,2717" - }, - { - "examine": "These control the flow of grain from the hopper to the millstones.", - "ids": "2718,2719,2720,2721,2722" - }, - { - "examine": "A spicy meat kebab is cooking here.", - "ids": "2723" - }, - { - "examine": "A fire burns brightly here.", - "ids": "2724" - }, - { - "examine": "A grand old fireplace.", - "ids": "2725,2726" - }, - { - "examine": "Something is cooking nicely here.", - "ids": "2727" - }, - { - "examine": "Ideal for cooking on.", - "ids": "2728,2729,2730,2731,3039,9682,12102,36973,40110" - }, - { - "examine": "Hot!", - "ids": "2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780" - }, - { - "examine": "A hot place for forging things in.", - "ids": "2781" - }, - { - "examine": "It says \"Property of Doric the dwarf.\" on the side.", - "ids": "2782" - }, - { - "examine": "Used for fashioning metal items.", - "ids": "2783" - }, - { - "examine": "Various implements for working with metal.", - "ids": "2784" - }, - { - "examine": "A hot place for forging things in.", - "ids": "2785" - }, - { - "examine": "An entrance to Gu'Tanoth.", - "ids": "2786,2787,2788,2789" - }, - { - "examine": "I wonder what's inside it.", - "ids": "2790" - }, - { - "examine": "A counter made from a stone block.", - "ids": "2791,2792,2876,3800,29356" - }, - { - "examine": "An ogre is selling cakes here.", - "ids": "2793" - }, - { - "examine": "A lever for activating something.", - "ids": "2794,2795" - }, - { - "examine": "This leads to the watchtower.", - "ids": "2796" - }, - { - "examine": "This leads downwards.", - "ids": "2797" - }, - { - "examine": "A leafy bush.", - "ids": "2798,2799,2800,2801,2802,2803" - }, - { - "examine": "I think I can squeeze through here...", - "ids": "2804,2805,2806,2807,2808,2809,2810,2811" - }, - { - "examine": "This leads downwards.", - "ids": "2812" - }, - { - "examine": "I think I can squeeze through here...", - "ids": "2813" - }, - { - "examine": "The gate has been locked shut.", - "ids": "2814,2815" - }, - { - "examine": "A strange looking rock...", - "ids": "2816" - }, - { - "examine": "I think I can get out here...", - "ids": "2817,2818,2819,2820,2821,2822" - }, - { - "examine": "A hole.", - "ids": "2823" - }, - { - "examine": "A hole", - "ids": "2824" - }, - { - "examine": "I hope this leads the way out.", - "ids": "2825" - }, - { - "examine": "I wonder what's inside it?", - "ids": "2826,2827,2828,2829" - }, - { - "examine": "You can probably jump over from here.", - "ids": "2830,2831" - }, - { - "examine": "A low wall is blocking your path.", - "ids": "2832" - }, - { - "examine": "This goes up!", - "ids": "2833" - }, - { - "examine": "A low wall is blocking your path.", - "ids": "2834" - }, - { - "examine": "Looks hard.", - "ids": "2835,2836,2837,2838,2839,2840,2841" - }, - { - "examine": "It has a special magical quality.", - "ids": "2842" - }, - { - "examine": "This drain leads from the sink to the sewers below.", - "ids": "2843" - }, - { - "examine": "This looks like it can be turned.", - "ids": "2844,2845,2846,2847,2848" - }, - { - "examine": "A rudimentary type of boat.", - "ids": "2849" - }, - { - "examine": "It's closed.", - "ids": "2850" - }, - { - "examine": "It's open.", - "ids": "2851" - }, - { - "examine": "I can probably squeeze my way inside there.", - "ids": "2852" - }, - { - "examine": "It's a flight of stairs.", - "ids": "2853" - }, - { - "examine": "Made of wood.", - "ids": "2854,2855" - }, - { - "examine": "I wonder what's inside?", - "ids": "2856" - }, - { - "examine": "It's open.", - "ids": "2857" - }, - { - "examine": "Used for storage.", - "ids": "2858" - }, - { - "examine": "A hot range, where some soup is bubbling nicely.", - "ids": "2859" - }, - { - "examine": "Very ominous.", - "ids": "2860" - }, - { - "examine": "It's a door.", - "ids": "2861,2862" - }, - { - "examine": "The door is closed.", - "ids": "2863" - }, - { - "examine": "A water feature.", - "ids": "2864" - }, - { - "examine": "It's a gate.", - "ids": "2865,2866" - }, - { - "examine": "Very decorative!", - "ids": "2867" - }, - { - "examine": "It's a cupboard.", - "ids": "2868,2869" - }, - { - "examine": "The mouse equivalent of a door.", - "ids": "2870" - }, - { - "examine": "I can climb down this.", - "ids": "2871" - }, - { - "examine": "I can climb this.", - "ids": "2872" - }, - { - "examine": "What a good likeness!", - "ids": "2873" - }, - { - "examine": "A depiction that chills one to the bone.", - "ids": "2874" - }, - { - "examine": "I wonder how accurate a representation this is.", - "ids": "2875" - }, - { - "examine": "A barrel full of staffs...", - "ids": "2877" - }, - { - "examine": "Patterns of light dance hypnotically across the pool's surface.", - "ids": "2878,2879" - }, - { - "examine": "There seems to be some sort of magical field here.", - "ids": "2880" - }, - { - "examine": "It's closed.", - "ids": "2881" - }, - { - "examine": "The toll gate from Lumbridge to Al-Kharid.", - "ids": "2882,2883" - }, - { - "examine": "I can climb this.", - "ids": "2884" - }, - { - "examine": "An antique by anyone's standards.", - "ids": "2885" - }, - { - "examine": "An antique by anyone's standards, however, it might have something interesting in it.", - "ids": "2886" - }, - { - "examine": "Looks good for logging.", - "ids": "2887" - }, - { - "examine": "A leafy jungle palm, dense foliage.", - "ids": "2888" - }, - { - "examine": "Home to many unusual creatures.", - "ids": "2889" - }, - { - "examine": "A leafy tree.", - "ids": "2890" - }, - { - "examine": "This tree has been cut down.", - "ids": "2891" - }, - { - "examine": "A jungle bush, quite common to these areas.", - "ids": "2892,2893" - }, - { - "examine": "A jungle bush that has been chopped down.", - "ids": "2894,2895" - }, - { - "examine": "A door to the Legends Guild.", - "ids": "2896,2897,2898,2899" - }, - { - "examine": "Looks slippery!", - "ids": "2900,2901" - }, - { - "examine": "Stoney!", - "ids": "2902" - }, - { - "examine": "A rather shadowy cavern entrance.", - "ids": "2903,2904" - }, - { - "examine": "An old crate for storage.", - "ids": "2905" - }, - { - "examine": "Useful for putting things on.", - "ids": "2906" - }, - { - "examine": "I guess I could sleep in it if I was really tired.", - "ids": "2907" - }, - { - "examine": "A wall of magic fire.", - "ids": "2908,2909" - }, - { - "examine": "Rickety bamboo tables that are lashed together to make a desk.", - "ids": "2910" - }, - { - "examine": "Bamboo storage!", - "ids": "2911" - }, - { - "examine": "This gate has a horribly complex locking mechanism.", - "ids": "2912,2913,2914,2915" - }, - { - "examine": "A dark cave entrance leading to the surface.", - "ids": "2916,2917" - }, - { - "examine": "A large crack in the wall.", - "ids": "2918" - }, - { - "examine": "A huge lump of rock.", - "ids": "2919,2920,2921" - }, - { - "examine": "A heavily constructed, cast-iron, ancient gateway.", - "ids": "2922,2923,2924,2925" - }, - { - "examine": "A high wall made up of rocks with sharp edges.", - "ids": "2926" - }, - { - "examine": "It looks like ancient graffiti.", - "ids": "2927" - }, - { - "examine": "An ornately carved rock with a pointed receptacle.", - "ids": "2928" - }, - { - "examine": "A half buried skeleton, probably dwarven remains.", - "ids": "2929" - }, - { - "examine": "A huge, strangely constructed doorway, not sure how this opens.", - "ids": "2930" - }, - { - "examine": "It looks like a magical portal of some kind, who knows where it leads?", - "ids": "2931" - }, - { - "examine": "Strangely, there's a locked barrel here, I wonder what's inside.", - "ids": "2932,2933" - }, - { - "examine": "A large scaffold platform most likely used for lifting and lowering heavy items.", - "ids": "2934" - }, - { - "examine": "Used to move earth to, and from, the dig shaft. A rope has been thrown over it.", - "ids": "2935" - }, - { - "examine": "A sculpted trunk of wood.", - "ids": "2936,2937,2938,2939" - }, - { - "examine": "A wonderfully dressed table.", - "ids": "2940" - }, - { - "examine": "Sparkling sacred water straight from the source.", - "ids": "2941" - }, - { - "examine": "A sparkling, babbling flow of water from an underground source.", - "ids": "2942" - }, - { - "examine": "Disgusting filthy quagmire that oozes from the ground.", - "ids": "2943" - }, - { - "examine": "Found near the water's edge.", - "ids": "2944" - }, - { - "examine": "A baby Yommi tree, it has a mystical aura.", - "ids": "2945" - }, - { - "examine": "An adolescent-looking Yommi tree, it has a mystical aura.", - "ids": "2946" - }, - { - "examine": "A dead Yommi tree sapling, you'll need a tough axe to remove this.", - "ids": "2947" - }, - { - "examine": "A fully grown Yommi tree, it won't get much taller than this.", - "ids": "2948" - }, - { - "examine": "A dead fully grown Yommi tree, you'll need a tough, sharp axe to remove this.", - "ids": "2949" - }, - { - "examine": "A felled adult Yommi tree, perhaps you should trim those branches?", - "ids": "2950" - }, - { - "examine": "A rotten felled Yommi tree, it was left too long in the damp jungle.", - "ids": "2951" - }, - { - "examine": "A trimmed Yommi tree log, perfect for sculpting into a totem pole.", - "ids": "2952" - }, - { - "examine": "A rotten Yommi tree log, it was left too long in the damp jungle air.", - "ids": "2953" - }, - { - "examine": "A beautifully crafted totem pole carved from the trunk of the sacred Yommi tree.", - "ids": "2954" - }, - { - "examine": "A rotten totem pole, it was left to rot in the jungle.", - "ids": "2955" - }, - { - "examine": "This earth is particularly fertile.", - "ids": "2956" - }, - { - "examine": "This earth is damaged by cultivation, time will restore the fertility.", - "ids": "2957" - }, - { - "examine": "A rope hangs here.", - "ids": "2958" - }, - { - "examine": "A dangerous path onwards.", - "ids": "2959,2960,2961" - }, - { - "examine": "Stoney!", - "ids": "2962,2963,2964" - }, - { - "examine": "Looks slippery!", - "ids": "2965" - }, - { - "examine": "A hot place for forging things in.", - "ids": "2966,2967,2968" - }, - { - "examine": "It looks like a strangely shaped depression in the rock.", - "ids": "2969" - }, - { - "examine": "This recess has a glowing heart shaped crystal in it.", - "ids": "2970" - }, - { - "examine": "This looks like some sort of shimmering surface.", - "ids": "2971" - }, - { - "examine": "A huge lump of rock.", - "ids": "2972,2973,2974" - }, - { - "examine": "This tree is particularly leafy.", - "ids": "2975,2976" - }, - { - "examine": "A large pile of sand", - "ids": "2977" - }, - { - "examine": "A medium pile of sand", - "ids": "2978" - }, - { - "examine": "A small pile of sand", - "ids": "2979" - }, - { - "examine": "Some beautiful flowers.", - "ids": "2980,2981,2982,2983,2984,2985,2986,2987,2988" - }, - { - "examine": "Known commonly as Red worm vine.", - "ids": "2989,2990,2991,2992,2993,2994" - }, - { - "examine": "I wonder what's inside.", - "ids": "2995,2996" - }, - { - "examine": "The door is closed.", - "ids": "2997" - }, - { - "examine": "The door is open.", - "ids": "2998,2999" - }, - { - "examine": "These obviously mean keep out!", - "ids": "3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013" - }, - { - "examine": "A nicely fitted door.", - "ids": "3014" - }, - { - "examine": "A wooden gate.", - "ids": "3015,3016" - }, - { - "examine": "A nicely fitted door.", - "ids": "3017,3018,3019" - }, - { - "examine": "A wrought iron gate.", - "ids": "3020,3021,3022,3023" - }, - { - "examine": "A closed door.", - "ids": "3024,3025,3026,3027" - }, - { - "examine": "I can climb this.", - "ids": "3028" - }, - { - "examine": "I can climb down this.", - "ids": "3029" - }, - { - "examine": "I can climb this.", - "ids": "3030" - }, - { - "examine": "I can climb down this.", - "ids": "3031" - }, - { - "examine": "I can see fish swimming in the water.", - "ids": "3032" - }, - { - "examine": "One of the most common trees in 2009Scape.", - "ids": "3033,3034,3035,3036" - }, - { - "examine": "A beautiful old oak.", - "ids": "3037" - }, - { - "examine": "Hot!", - "ids": "3038" - }, - { - "examine": "It's closed.", - "ids": "3040" - }, - { - "examine": "It's open.", - "ids": "3041" - }, - { - "examine": "A rocky outcrop.", - "ids": "3042,3043" - }, - { - "examine": "A hot place for forging things in.", - "ids": "3044" - }, - { - "examine": "The bank teller will serve you from here.", - "ids": "3045" - }, - { - "examine": "These obviously mean keep out!", - "ids": "3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076" - }, - { - "examine": "Lean against the wall to get a better view!", - "ids": "3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107" - }, - { - "examine": "Flags marking the entrance to the arena.", - "ids": "3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158" - }, - { - "examine": "Beats the operating table.", - "ids": "3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,3174,3175,3176,3177,3178,3179,3180,3181" - }, - { - "examine": "Wait here for a nurse.", - "ids": "3182" - }, - { - "examine": "Storage for drugs and bandages.", - "ids": "3183,3184,3185" - }, - { - "examine": "I don't really want to end up here...", - "ids": "3186,3187,3188,3189" - }, - { - "examine": "These open and close!", - "ids": "3190" - }, - { - "examine": "This may be worth searching.", - "ids": "3191" - }, - { - "examine": "You can see the last 50 fights on here.", - "ids": "3192" - }, - { - "examine": "Used to store players' items whilst they duel.", - "ids": "3193" - }, - { - "examine": "Use for quick access to your bank.", - "ids": "3194" - }, - { - "examine": "Smells pretty bad!", - "ids": "3195" - }, - { - "examine": "Not much use for anything except scrap.", - "ids": "3196" - }, - { - "examine": "Entrance to the Duel Arena.", - "ids": "3197,3198" - }, - { - "examine": "A wooden double bed.", - "ids": "3199,3200,3201,3202" - }, - { - "examine": "Access to the duel arena.", - "ids": "3203,3204" - }, - { - "examine": "I can climb down this.", - "ids": "3205" - }, - { - "examine": "A barrel full of staffs...", - "ids": "3206,3207,3208" - }, - { - "examine": "A strange crack cuts into the wall.", - "ids": "3209,3210,3211,3212,29360,29362" - }, - { - "examine": "It looks like I can squeeze through here.", - "ids": "3213" - }, - { - "examine": "The easy way out...", - "ids": "3214,3215" - }, - { - "examine": "A pile of mud.", - "ids": "3216" - }, - { - "examine": "I can go through here.", - "ids": "3217" - }, - { - "examine": "Dark and intimidating.", - "ids": "3218,3219" - }, - { - "examine": "That skull's looking at me....", - "ids": "3220,3221" - }, - { - "examine": "I can climb down these.", - "ids": "3222" - }, - { - "examine": "I can climb up these.", - "ids": "3223" - }, - { - "examine": "I can go through here.", - "ids": "3224,3225,3226" - }, - { - "examine": "Best not to get caught!", - "ids": "3227" - }, - { - "examine": "Best avoided.", - "ids": "3228,3229" - }, - { - "examine": "Looks suspicious.", - "ids": "3230" - }, - { - "examine": "A plank.", - "ids": "3231" - }, - { - "examine": "Formed over many years.", - "ids": "3232" - }, - { - "examine": "Best avoided.", - "ids": "3233" - }, - { - "examine": "Looks suspicious.", - "ids": "3234" - }, - { - "examine": "I can open the grill from this side.", - "ids": "3235" - }, - { - "examine": "Maybe I can cross that.", - "ids": "3238" - }, - { - "examine": "It looks like only the guide ropes are holding the bridge up.", - "ids": "3239" - }, - { - "examine": "A bridge.", - "ids": "3240" - }, - { - "examine": "This lever can be operated.", - "ids": "3241,3242" - }, - { - "examine": "The base of a platform.", - "ids": "3243,3244,3245,3246" - }, - { - "examine": "A bridge.", - "ids": "3247,3248,3249,3250,3251,3252,3253" - }, - { - "examine": "I can't get past that very easily...", - "ids": "3254,3255,3256" - }, - { - "examine": "A platform.", - "ids": "3257" - }, - { - "examine": "A bridge.", - "ids": "3258,3259,3260,3261,3262" - }, - { - "examine": "This area may not be safe...", - "ids": "3263" - }, - { - "examine": "A well of nastiness.", - "ids": "3264" - }, - { - "examine": "I can climb this pile of rocks...", - "ids": "3265" - }, - { - "examine": "Usually used for storing living things...", - "ids": "3266,3267,3268,3269" - }, - { - "examine": "The door is closed.", - "ids": "3270" - }, - { - "examine": "The door is open.", - "ids": "3271" - }, - { - "examine": "I wonder what's inside.", - "ids": "3272,3273,3274,3275" - }, - { - "examine": "A stone bridge.", - "ids": "3276,3277,3278,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293" - }, - { - "examine": "A hot place for forging things in.", - "ids": "3294" - }, - { - "examine": "It's covered in strange writing.", - "ids": "3295,3296,3297,3298,3299,3300,3301,3302" - }, - { - "examine": "You won't be able to lift that.", - "ids": "3303" - }, - { - "examine": "A portcullis.", - "ids": "3304" - }, - { - "examine": "It doesn't look like water in there...", - "ids": "3305,3306" - }, - { - "examine": "A pile of rocks.", - "ids": "3307" - }, - { - "examine": "The boulder has smashed through the cage.", - "ids": "3308" - }, - { - "examine": "A deposit of rocks.", - "ids": "3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326" - }, - { - "examine": "Intimidating!", - "ids": "3327" - }, - { - "examine": "A depiction of a great dwarf miner.", - "ids": "3328,3329,3330,3331" - }, - { - "examine": "A temple door.", - "ids": "3332" - }, - { - "examine": "A very big door.", - "ids": "3333,3334,3335,3336" - }, - { - "examine": "This lever can be operated.", - "ids": "3337" - }, - { - "examine": "Why would a log be hung up there?", - "ids": "3338" - }, - { - "examine": "Looks suspicious.", - "ids": "3339" - }, - { - "examine": "Looks like the rope is holding the bridge up.", - "ids": "3340" - }, - { - "examine": "Looks like the other rope is holding the bridge up.", - "ids": "3341,3342" - }, - { - "examine": "A pile of rocks.", - "ids": "3343" - }, - { - "examine": "It's got dwarf brew in it.", - "ids": "3344,3345,3346,3347" - }, - { - "examine": "Lord Iban's Throne.", - "ids": "3348,3349,3350" - }, - { - "examine": "I'm glad I'm on this side of those bars.", - "ids": "3351,3352" - }, - { - "examine": "I don't much like the look of that...", - "ids": "3353,3354,3355,3356,3357,3358" - }, - { - "examine": "Well of the damned.", - "ids": "3359" - }, - { - "examine": "A wooden crate for storage.", - "ids": "3360" - }, - { - "examine": "A magical sphere that glimmers within.", - "ids": "3361" - }, - { - "examine": "A window.", - "ids": "3362,3363" - }, - { - "examine": "An odd looking rock formation.", - "ids": "3364" - }, - { - "examine": "Looks like I can climb these.", - "ids": "3365" - }, - { - "examine": "Makes you cry.", - "ids": "3366" - }, - { - "examine": "Steel bars that are locked securely.", - "ids": "3367,3368,3369,3370" - }, - { - "examine": "An Achey tree stump.", - "ids": "3371" - }, - { - "examine": "Useful for ogre dinners.", - "ids": "3372,3373,3374,3375" - }, - { - "examine": "An ogre bench, useful for taking all that weight off their legs.", - "ids": "3376" - }, - { - "examine": "Hmmm, a rock for a lock....", - "ids": "3377" - }, - { - "examine": "Some stealthy thief must have picked the ogre lock!", - "ids": "3378" - }, - { - "examine": "The entrance to Rantz's cave", - "ids": "3379" - }, - { - "examine": "Exit this way for fresh air and daylight.", - "ids": "3380,3381" - }, - { - "examine": "Useful for ogre dinners.", - "ids": "3382,3383,3384,3385,3386,3387,3388" - }, - { - "examine": "A good source of books!", - "ids": "3389" - }, - { - "examine": "A strange crack cuts into the wall.", - "ids": "3390,3391,3392,3393" - }, - { - "examine": "A wooden crate for storage.", - "ids": "3394,3395" - }, - { - "examine": "A pile of boxes for storage.", - "ids": "3396,3397" - }, - { - "examine": "A wooden crate for storage.", - "ids": "3398,3399,3400,3401" - }, - { - "examine": "Used for fashioning metal items.", - "ids": "3402" - }, - { - "examine": "A pile of Elemental rock.", - "ids": "3403" - }, - { - "examine": "A valve to start and stop the flow of water.", - "ids": "3404,3405" - }, - { - "examine": "This lever can be operated.", - "ids": "3406" - }, - { - "examine": "It spins.", - "ids": "3407,3408" - }, - { - "examine": "This lever can be operated.", - "ids": "3409" - }, - { - "examine": "Big bellows.", - "ids": "3410,3411,3412" - }, - { - "examine": "A furnace with an air blast pipe.", - "ids": "3413" - }, - { - "examine": "A small trough full of lava.", - "ids": "3414" - }, - { - "examine": "I can climb down these stairs.", - "ids": "3415" - }, - { - "examine": "I can climb up these stairs.", - "ids": "3416" - }, - { - "examine": "This lever can be operated.", - "ids": "3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428" - }, - { - "examine": "Water powered machinery.", - "ids": "3429,3430" - }, - { - "examine": "Stoney!", - "ids": "3431" - }, - { - "examine": "I wonder what's under it?", - "ids": "3432" - }, - { - "examine": "I can see a holy barrier at the bottom.", - "ids": "3433,3434,3435,3436,3437,3438,3439" - }, - { - "examine": "They let you walk up them!", - "ids": "3440" - }, - { - "examine": "They let you walk down them!", - "ids": "3441,3442" - }, - { - "examine": "A holy barrier blocking evil forces.", - "ids": "3443" - }, - { - "examine": "A sturdy metal gate.", - "ids": "3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,3460,3461,3462" - }, - { - "examine": "A hastily constructed yet sturdy prison door.", - "ids": "3463,3464,3465" - }, - { - "examine": "Dead animal parts dangling!", - "ids": "3466" - }, - { - "examine": "So how long has this been dead, then?", - "ids": "3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478" - }, - { - "examine": "A statue honouring Saradomin.", - "ids": "3479" - }, - { - "examine": "An ornately decorated coffin. Something seems to be alive inside.", - "ids": "3480,3481,3482,3483,3484" - }, - { - "examine": "An ornately carved well that draws water from the river Salve.", - "ids": "3485,3486,3487,3488" - }, - { - "examine": "Sturdy looking door.", - "ids": "3489,3490,3491,3492" - }, - { - "examine": "A monument to a fallen priest.", - "ids": "3493,3494,3495,3496,3497,3498,3499" - }, - { - "examine": "With skill I can play this.", - "ids": "3500,3501,3502,3503,3504,3505" - }, - { - "examine": "A wrought iron gate.", - "ids": "3506,3507" - }, - { - "examine": "Not sure if I should sit on that.", - "ids": "3508,3509" - }, - { - "examine": "Not sure if that's any use.", - "ids": "3510,3511" - }, - { - "examine": "It'll probably die soon.", - "ids": "3512,3513" - }, - { - "examine": "Not sure if I should stand under that.", - "ids": "3514,3515" - }, - { - "examine": "A dark dank entrance to below.", - "ids": "3516" - }, - { - "examine": "A large tree thriving where trees normally die.", - "ids": "3517,3518,3519" - }, - { - "examine": "Special grotto area.", - "ids": "3520" - }, - { - "examine": "A grotto transformed into an altar of nature.", - "ids": "3521" - }, - { - "examine": "It's a bridge.", - "ids": "3522" - }, - { - "examine": "An old bench, probably made from wood in this swamp.", - "ids": "3523,3524" - }, - { - "examine": "The door.", - "ids": "3525" - }, - { - "examine": "The green door.", - "ids": "3526" - }, - { - "examine": "A roughly hewn stone with some sort of symbol on it.", - "ids": "3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545" - }, - { - "examine": "There is a rope leading to the bottom of this well.", - "ids": "3546,3547,3548,3549,3550" - }, - { - "examine": "I can balance on this rope.", - "ids": "3551,3552" - }, - { - "examine": "I can balance on this log.", - "ids": "3553,3554,3555,3556,3557,3558" - }, - { - "examine": "Tread carefully!", - "ids": "3559,3560,3561,3562" - }, - { - "examine": "Now, I'm the king of the swingers, oh, the jungle VIP.", - "ids": "3563,3564" - }, - { - "examine": "It looks like I can clamber over this.", - "ids": "3565" - }, - { - "examine": "Use this to swing over to the next platform.", - "ids": "3566" - }, - { - "examine": "I might want to avoid this nasty blade.", - "ids": "3567,3568,3569" - }, - { - "examine": "Walk the plank! Ya land lubber!", - "ids": "3570,3571,3572,3573,3574,3575,3576,3577" - }, - { - "examine": "It's a small step for a player, a giant leap for player kind.", - "ids": "3578,3579" - }, - { - "examine": "Makes sliced human.", - "ids": "3580" - }, - { - "examine": "Releases a ticket when the flashing arrow is above it.", - "ids": "3581" - }, - { - "examine": "Makes human colanders.", - "ids": "3582" - }, - { - "examine": "I can use these to climb across to the other side.", - "ids": "3583,3584" - }, - { - "examine": "Looks suspiciously like a pressure pad to me.", - "ids": "3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607" - }, - { - "examine": "Releases a ticket when the flashing arrow is above it.", - "ids": "3608,3609" - }, - { - "examine": "I can use this rope to climb back to the top.", - "ids": "3610,3611,3612,3613,3614,3615,3616" - }, - { - "examine": "Leads down into the Agility Arena.", - "ids": "3617" - }, - { - "examine": "Leads back to Brimhaven.", - "ids": "3618,3619,3620,3621,3622,3623,3624,3625" - }, - { - "examine": "It looks very sturdy.", - "ids": "3626,3627,3628,3629,3630,3631,3632,3633" - }, - { - "examine": "A shrine of the gods!", - "ids": "3634" - }, - { - "examine": "I wonder what's inside...", - "ids": "3635" - }, - { - "examine": "It looks empty.", - "ids": "3636,3637,3638,3639,3640,3641,3642,3643" - }, - { - "examine": "That's really bright!", - "ids": "3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661" - }, - { - "examine": "Smells more like \"innocent villager\" stew to me...", - "ids": "3662,3663,3664" - }, - { - "examine": "Troll leftovers...", - "ids": "3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675" - }, - { - "examine": "A stone mechanism that unlocks the equipment room.", - "ids": "3676,3677,3678" - }, - { - "examine": "A standard of Asgarnia.", - "ids": "3679" - }, - { - "examine": "The flag of Asgarnia.", - "ids": "3680" - }, - { - "examine": "Town of Burthorpe", - "ids": "3681,3682,3683,3684" - }, - { - "examine": "A pile of boxes for storage.", - "ids": "3685,3686,3687,3688,3689,3690,3691" - }, - { - "examine": "Some of the Sherpa's climbing rope.", - "ids": "3692,3693" - }, - { - "examine": "Looks like the Imperial Guard's supply of Dual Claws.", - "ids": "3694,3695" - }, - { - "examine": "The Imperial Guard's ceremonial armour.", - "ids": "3696" - }, - { - "examine": "A barrel full of swords...", - "ids": "3697,3698,3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,3714,3715,3716,3717,3718,3719,3720,3721" - }, - { - "examine": "A rocky outcrop.", - "ids": "3722,3723,3724" - }, - { - "examine": "A wooden gate.", - "ids": "3725,3726,3727,3728,3729" - }, - { - "examine": "I can climb over the fence with this.", - "ids": "3730,3731,3732,3733,3734" - }, - { - "examine": "Looks like a small cave.", - "ids": "3735" - }, - { - "examine": "The exit to the outside.", - "ids": "3736,3737,3738,3739,3740" - }, - { - "examine": "No solicitors!", - "ids": "3741" - }, - { - "examine": "Danger", - "ids": "3742" - }, - { - "examine": "A sturdy wooden door.", - "ids": "3743,3744" - }, - { - "examine": "The door is closed.", - "ids": "3745,3746" - }, - { - "examine": "A nicely fitted door.", - "ids": "3747" - }, - { - "examine": "A rocky outcrop.", - "ids": "3748,3749,3750,3751" - }, - { - "examine": "Unusual energy is gathered here.", - "ids": "3752,3753,3754,3755,3756" - }, - { - "examine": "Looks like a small cave.", - "ids": "3757" - }, - { - "examine": "The way out.", - "ids": "3758" - }, - { - "examine": "Looks like a small cave.", - "ids": "3759" - }, - { - "examine": "The way out.", - "ids": "3760" - }, - { - "examine": "The back way out.", - "ids": "3761" - }, - { - "examine": "The back way into the stronghold.", - "ids": "3762" - }, - { - "examine": "The door is closed.", - "ids": "3763" - }, - { - "examine": "The door is open.", - "ids": "3764" - }, - { - "examine": "The door to Mad Eadgar's cell.", - "ids": "3765,3766" - }, - { - "examine": "The door to Godric's cell.", - "ids": "3767,3768" - }, - { - "examine": "Hot!", - "ids": "3769" - }, - { - "examine": "This window looks down onto the Troll Camp.", - "ids": "3770" - }, - { - "examine": "The entrance to the Troll Stronghold.", - "ids": "3771" - }, - { - "examine": "The way out of the Troll Stronghold.", - "ids": "3772,3773,3774" - }, - { - "examine": "Looks like stew of some kind...", - "ids": "3775" - }, - { - "examine": "A door in the Stronghold.", - "ids": "3776,3777,3778,3779" - }, - { - "examine": "The door to the prison.", - "ids": "3780,3781" - }, - { - "examine": "The entrance to the Troll Arena.", - "ids": "3782,3783,3784" - }, - { - "examine": "The exit to the Troll Arena.", - "ids": "3785,3786,3787" - }, - { - "examine": "I can climb these stairs.", - "ids": "3788" - }, - { - "examine": "They go down.", - "ids": "3789" - }, - { - "examine": "A rocky outcrop.", - "ids": "3790,3791,3792,3793" - }, - { - "examine": "Looks tasty! If you're a goat, that is.", - "ids": "3794,3795,3796" - }, - { - "examine": "Not so good for sitting on.", - "ids": "3802" - }, - { - "examine": "A rocky outcrop.", - "ids": "3803,3804" - }, - { - "examine": "They don't seem to roll.", - "ids": "3805" - }, - { - "examine": "They're troll eggs. Or perhaps rocks.", - "ids": "3806" - }, - { - "examine": "These make great pets.", - "ids": "3807" - }, - { - "examine": "It's a troll! Run! No, wait, it's just a rock.", - "ids": "3808,3809" - }, - { - "examine": "The door to the storeroom.", - "ids": "3810,3811,3812" - }, - { - "examine": "It probably hasn't got anything interesting inside.", - "ids": "3813" - }, - { - "examine": "They probably haven't got anything interesting inside.", - "ids": "3814,3815" - }, - { - "examine": "They're closed.", - "ids": "3816" - }, - { - "examine": "They're open.", - "ids": "3817,3818,3819" - }, - { - "examine": "It doesn't contain anything particularly appetising.", - "ids": "3820" - }, - { - "examine": "Makes you taller.", - "ids": "3821" - }, - { - "examine": "It's full of dried goutweed.", - "ids": "3822" - }, - { - "examine": "Welcome to Mad Eadgar's! If I'm not in, I've probably been captured again.", - "ids": "3823" - }, - { - "examine": "I don't want to look too closely at what's cooking in there...", - "ids": "3824" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "3825" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "3826" - }, - { - "examine": "How am I going to get down there?", - "ids": "3827,3828" - }, - { - "examine": "I hope this holds!", - "ids": "3829" - }, - { - "examine": "How am I going to get down there?", - "ids": "3830,3831" - }, - { - "examine": "I hope this holds!", - "ids": "3832" - }, - { - "examine": "It's moving...", - "ids": "3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,3849,3850,3851,3852,3853,3854,3855" - }, - { - "examine": "It's a half buried crate.", - "ids": "3856,3857" - }, - { - "examine": "It's stuck in the sand.", - "ids": "3858,3859" - }, - { - "examine": "It's full of brightly coloured fish.", - "ids": "3860,3861" - }, - { - "examine": "It's a pile of burning bones.", - "ids": "3862" - }, - { - "examine": "The tribal statue of Tai Bwo Wannai Village.", - "ids": "3863,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878" - }, - { - "examine": "A tree.", - "ids": "3879" - }, - { - "examine": "It's a tree stump.", - "ids": "3880" - }, - { - "examine": "A tree.", - "ids": "3881,3882,3883" - }, - { - "examine": "It's a tree stump.", - "ids": "3884" - }, - { - "examine": "A tree.", - "ids": "3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900" - }, - { - "examine": "A rare flower.", - "ids": "3901" - }, - { - "examine": "Don't flowers make you feel better?", - "ids": "3902" - }, - { - "examine": "A rare flower.", - "ids": "3903" - }, - { - "examine": "Don't flowers make you feel better?", - "ids": "3904" - }, - { - "examine": "A rare flower.", - "ids": "3905" - }, - { - "examine": "Don't flowers make you feel better?", - "ids": "3906,3907,3908,3909,3910,3911" - }, - { - "examine": "Fungal growth.", - "ids": "3912" - }, - { - "examine": "Poisonous no doubt.", - "ids": "3913,3914" - }, - { - "examine": "Fungal growth.", - "ids": "3915" - }, - { - "examine": "Poisonous no doubt.", - "ids": "3916,3917" - }, - { - "examine": "The lamp has a glowing crystal at its core.", - "ids": "3918" - }, - { - "examine": "It's a trap!", - "ids": "3919,3920" - }, - { - "examine": "A tripwire.", - "ids": "3921" - }, - { - "examine": "An odd-looking group of tied sticks.", - "ids": "3922" - }, - { - "examine": "A pile of leaves.", - "ids": "3923,3924,3925,3926" - }, - { - "examine": "Looks like I can climb these.", - "ids": "3927" - }, - { - "examine": "It's a tree.", - "ids": "3928" - }, - { - "examine": "I can balance on this log.", - "ids": "3929,3930,3931,3932,3933,3934,3935,3936" - }, - { - "examine": "There are some broken twigs here.", - "ids": "3937" - }, - { - "examine": "It looks as if the grass here has been flattened.", - "ids": "3938" - }, - { - "examine": "You notice the leaf litter here has been disturbed.", - "ids": "3939,3940" - }, - { - "examine": "Tracks in the soil.", - "ids": "3941,3942,3943" - }, - { - "examine": "You'd need a big siege engine to force that.", - "ids": "3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961" - }, - { - "examine": "A yellow crystal structure.", - "ids": "3962,3963,3964,3965,3966" - }, - { - "examine": "A tree", - "ids": "3967,3968" - }, - { - "examine": "Disturbing but tidy.", - "ids": "3969" - }, - { - "examine": "I don't even want to think about what did that...", - "ids": "3970" - }, - { - "examine": "I don't wanna fall in that!", - "ids": "3975" - }, - { - "examine": "Good for smashing city walls.", - "ids": "3976" - }, - { - "examine": "There's a winch on this side.", - "ids": "3977" - }, - { - "examine": "There's a lever on this side.", - "ids": "3978,3979" - }, - { - "examine": "A way to get into the tent.", - "ids": "3980,3981,3982" - }, - { - "examine": "A tent.", - "ids": "3983,3984,3985,3986" - }, - { - "examine": "A small barrel.", - "ids": "3987,3988,3989,3990,3991" - }, - { - "examine": "A standard of Kandarin.", - "ids": "3992,3993" - }, - { - "examine": "A small furnace.", - "ids": "3994" - }, - { - "examine": "A tent wall.", - "ids": "3995" - }, - { - "examine": "A way to get into the tent.", - "ids": "3996" - }, - { - "examine": "A tent wall.", - "ids": "3997" - }, - { - "examine": "It looks as if the grass here has been flattened.", - "ids": "3998" - }, - { - "examine": "There are some broken twigs here.", - "ids": "3999" - }, - { - "examine": "A tent roof.", - "ids": "4000" - }, - { - "examine": "A tent wall.", - "ids": "4001" - }, - { - "examine": "The charred remains of a tent pole.", - "ids": "4002,4003" - }, - { - "examine": "Well of voyage.", - "ids": "4004,4005" - }, - { - "examine": "It looks like I can squeeze through here.", - "ids": "4006" - }, - { - "examine": "The exit to the outside.", - "ids": "4007" - }, - { - "examine": "Shrine to the glory of Saradomin.", - "ids": "4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023" - }, - { - "examine": "A barrel.", - "ids": "4024,4025" - }, - { - "examine": "A still for fractionalizing oils.", - "ids": "4026" - }, - { - "examine": "A pile of lime rock.", - "ids": "4027,4028,4029,4030" - }, - { - "examine": "Looks like a stone doorway to me.", - "ids": "4031,4032,4033,4034" - }, - { - "examine": "These clean Druid's robes are drying off.", - "ids": "4035,4036,4037,4038" - }, - { - "examine": "It's full of dirty robes.", - "ids": "4039,4040,4041,4042" - }, - { - "examine": "Presumably the hatch the zookeeper feeds the parrots through.", - "ids": "4043" - }, - { - "examine": "A red standard.", - "ids": "4044,4045,4046,4047" - }, - { - "examine": "It doesn't look healthy...", - "ids": "4051" - }, - { - "examine": "It's covered in slime.", - "ids": "4052" - }, - { - "examine": "It doesn't look healthy...", - "ids": "4053,4054" - }, - { - "examine": "These fat fungi take up so much room.", - "ids": "4055,4056,4057" - }, - { - "examine": "I can balance on this rope.", - "ids": "4059" - }, - { - "examine": "It's hollow...", - "ids": "4060" - }, - { - "examine": "This tree has been cut down.", - "ids": "4061" - }, - { - "examine": "Strange items are stored here.", - "ids": "4062" - }, - { - "examine": "This table has seen better days.", - "ids": "4064" - }, - { - "examine": "It looks very ornamental in a practical 'solid rock' way.", - "ids": "4065" - }, - { - "examine": "Welcome to Mort'ton", - "ids": "4066" - }, - { - "examine": "Danger! Sickness and affliction... stay away!", - "ids": "4067" - }, - { - "examine": "Looks like a pile of ancient rubble.", - "ids": "4068" - }, - { - "examine": "The starting of a wall.", - "ids": "4069,4070,4071,4072,4073,4074,4075,4076" - }, - { - "examine": "It's nearly a wall.", - "ids": "4077" - }, - { - "examine": "A rebuilt wall.", - "ids": "4078" - }, - { - "examine": "The broken wall of a desecrated temple.", - "ids": "4079" - }, - { - "examine": "The partially repaired wall of a desecrated temple.", - "ids": "4080,4081,4082,4083,4084,4085,4086,4087" - }, - { - "examine": "The nearly repaired wall of a desecrated temple.", - "ids": "4088" - }, - { - "examine": "The repaired wall of a temple.", - "ids": "4089" - }, - { - "examine": "A flaming Fire altar.", - "ids": "4090" - }, - { - "examine": "An ancient Fire altar.", - "ids": "4091" - }, - { - "examine": "An ancient, totally desecrated, broken down fire altar.", - "ids": "4092" - }, - { - "examine": "A place to cremate the dead. Needs some wood.", - "ids": "4093" - }, - { - "examine": "A place to cremate the dead. Needs a body.", - "ids": "4094,4095,4096,4097,4098,4099" - }, - { - "examine": "A place to cremate the dead. Needs a light.", - "ids": "4100,4101,4102,4103,4104,4105" - }, - { - "examine": "Heavy metal!", - "ids": "4106,4107,4108,4109,4110" - }, - { - "examine": "A strangely decorated bronze chest, the lock is painted blood red.", - "ids": "4111" - }, - { - "examine": "A strangely decorated chest, the lock is painted brown.", - "ids": "4112" - }, - { - "examine": "A strangely decorated chest, the lock is painted crimson.", - "ids": "4113" - }, - { - "examine": "A strangely decorated chest, the lock is painted black.", - "ids": "4114" - }, - { - "examine": "A strangely decorated chest, the lock is painted purple.", - "ids": "4115" - }, - { - "examine": "A strangely decorated steel chest, the lock is painted blood red.", - "ids": "4116" - }, - { - "examine": "A strangely decorated steel chest, the lock is painted brown.", - "ids": "4117" - }, - { - "examine": "A strangely decorated steel chest, the lock is painted crimson.", - "ids": "4118" - }, - { - "examine": "A strangely decorated steel chest, the lock is painted black.", - "ids": "4119" - }, - { - "examine": "A strangely decorated steel chest, the lock is painted purple.", - "ids": "4120" - }, - { - "examine": "A strangely decorated black chest, the lock is painted blood red.", - "ids": "4121" - }, - { - "examine": "A strangely decorated black chest, the lock is painted brown.", - "ids": "4122" - }, - { - "examine": "A strangely decorated black chest, the lock is painted crimson.", - "ids": "4123" - }, - { - "examine": "A strangely decorated black chest, the lock is painted black.", - "ids": "4124" - }, - { - "examine": "A strangely decorated black chest, the lock is painted purple.", - "ids": "4125" - }, - { - "examine": "A strangely decorated silver chest, the lock is painted blood red.", - "ids": "4126" - }, - { - "examine": "A strangely decorated silver chest, the lock is painted brown.", - "ids": "4127" - }, - { - "examine": "A strangely decorated silver chest, the lock is painted crimson.", - "ids": "4128" - }, - { - "examine": "A strangely decorated silver chest, the lock is painted black.", - "ids": "4129" - }, - { - "examine": "A strangely decorated silver chest, the lock is painted purple.", - "ids": "4130" - }, - { - "examine": "A strangely decorated bronze chest, the open lock is painted blood red.", - "ids": "4131" - }, - { - "examine": "This tells you which way is which.", - "ids": "4132,4133,4134,4135" - }, - { - "examine": "These doors look very ominous. A sign says 'To the tombs'.", - "ids": "4136,4137" - }, - { - "examine": "Items are for sale here.", - "ids": "4138" - }, - { - "examine": "Entrance to the Duel Arena.", - "ids": "4139,4140" - }, - { - "examine": "This seems to be some kind of shrine.", - "ids": "4141" - }, - { - "examine": "The wind makes a musical sound as it blows through it...", - "ids": "4142" - }, - { - "examine": "Danger", - "ids": "4143" - }, - { - "examine": "Those golden fruit look good enough to eat!", - "ids": "4144,4145,4146" - }, - { - "examine": "This must be Lalli's home.", - "ids": "4147" - }, - { - "examine": "Allows performers backstage at the Longhall.", - "ids": "4148" - }, - { - "examine": "It smells pretty good actually.", - "ids": "4149" - }, - { - "examine": "A portal from this mystical place.", - "ids": "4150,4151,4152,4153,4154,4155,4156,4157" - }, - { - "examine": "Takes me into the maze.", - "ids": "4158" - }, - { - "examine": "Takes me out of the maze.", - "ids": "4159,4160,4161" - }, - { - "examine": "A thin metal pipe, presumably for rainwater to run through.", - "ids": "4162" - }, - { - "examine": "I can climb this.", - "ids": "4163,4164" - }, - { - "examine": "Keeps the wind out.", - "ids": "4165,4166" - }, - { - "examine": "I wonder what's inside?", - "ids": "4167,4168" - }, - { - "examine": "Brrrrrr!", - "ids": "4169" - }, - { - "examine": "There is some kind of balancing mechanism as a lock.", - "ids": "4170" - }, - { - "examine": "A good source of books!", - "ids": "4171" - }, - { - "examine": "An appliance for cooking with.", - "ids": "4172" - }, - { - "examine": "I wonder what's down there?", - "ids": "4173" - }, - { - "examine": "I wonder what's under it?", - "ids": "4174" - }, - { - "examine": "Kind of funny smelling...", - "ids": "4175" - }, - { - "examine": "Water comes out of it.", - "ids": "4176" - }, - { - "examine": "This may be worth opening.", - "ids": "4177" - }, - { - "examine": "This may be worth searching.", - "ids": "4178" - }, - { - "examine": "A very unusual piece of artwork...", - "ids": "4179,4180" - }, - { - "examine": "Alas poor unicorn, I knew him well.", - "ids": "4181" - }, - { - "examine": "Looks like the bull lost.", - "ids": "4182" - }, - { - "examine": "A pile of boxes for storage.", - "ids": "4183,4184" - }, - { - "examine": "A wooden crate for storage.", - "ids": "4185" - }, - { - "examine": "An old crate for storage.", - "ids": "4186" - }, - { - "examine": "I can climb this.", - "ids": "4187" - }, - { - "examine": "This leads upwards.", - "ids": "4188" - }, - { - "examine": "This leads downwards.", - "ids": "4189,4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,4239,4240,4241,4242,4243,4244,4245,4246" - }, - { - "examine": "Keeps the cold winds out.", - "ids": "4247" - }, - { - "examine": "Doesn't keep the wind out if it's open!", - "ids": "4248,4249" - }, - { - "examine": "I'm sure the animal is glad its fur was put to good use.", - "ids": "4250,4251" - }, - { - "examine": "I wonder what's inside?", - "ids": "4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264" - }, - { - "examine": "Toasty.", - "ids": "4265" - }, - { - "examine": "Hot!", - "ids": "4266" - }, - { - "examine": "Finger licking good!", - "ids": "4267,4268" - }, - { - "examine": "It's a long wooden table.", - "ids": "4269" - }, - { - "examine": "It's a table with candles on.", - "ids": "4270" - }, - { - "examine": "Generally used for sitting.", - "ids": "4271" - }, - { - "examine": "Generally used for putting things on.", - "ids": "4272" - }, - { - "examine": "Actually, I could do with a drink...", - "ids": "4273" - }, - { - "examine": "For leaning against...", - "ids": "4274" - }, - { - "examine": "A wooden barrel containing lots of fish.", - "ids": "4275" - }, - { - "examine": "Always a source of good bargains.", - "ids": "4276" - }, - { - "examine": "There's something fishy about this stall.", - "ids": "4277" - }, - { - "examine": "Around here, this is where you buy new doors.", - "ids": "4278,4279,4280,4281,4282" - }, - { - "examine": "Has a peculiar odour.", - "ids": "4283,4284" - }, - { - "examine": "Water comes out of this.", - "ids": "4285" - }, - { - "examine": "It's kind of like a barrel.", - "ids": "4286" - }, - { - "examine": "Looks pretty comfy.", - "ids": "4287" - }, - { - "examine": "I guess I could sleep in it if I was really tired.", - "ids": "4288,4289,4290,4291,4292,4293,4294,4295" - }, - { - "examine": "Yup, looks like this neighbourhood is perfectly safe for travellers...", - "ids": "4296" - }, - { - "examine": "A pile of boxes for storage.", - "ids": "4297,4298,4299" - }, - { - "examine": "A wooden crate for storage.", - "ids": "4300" - }, - { - "examine": "An old crate for storage.", - "ids": "4301,4302,4303" - }, - { - "examine": "A hot place for forging things in.", - "ids": "4304,4305" - }, - { - "examine": "Used for fashioning metal items.", - "ids": "4306" - }, - { - "examine": "Various implements for working with metal.", - "ids": "4307" - }, - { - "examine": "Bake your clay pots in here.", - "ids": "4308" - }, - { - "examine": "Used for spinning thread.", - "ids": "4309" - }, - { - "examine": "Used for fashioning clay items.", - "ids": "4310" - }, - { - "examine": "A wooden gate.", - "ids": "4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327" - }, - { - "examine": "This tree has been cut down.", - "ids": "4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4347" - }, - { - "examine": "Best left on the beach.", - "ids": "4348" - }, - { - "examine": "This once belonged to a sea animal.", - "ids": "4349" - }, - { - "examine": "Best left for the crabs.", - "ids": "4350" - }, - { - "examine": "I can hear the sea with this.", - "ids": "4351" - }, - { - "examine": "A half-buried bowl.", - "ids": "4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365" - }, - { - "examine": "An empty shelf...", - "ids": "4366,4367" - }, - { - "examine": "There are some pots and pans here.", - "ids": "4368" - }, - { - "examine": "There are some tankards here.", - "ids": "4369" - }, - { - "examine": "A shelf with a bucket on it.", - "ids": "4370" - }, - { - "examine": "There are a few books on this shelf.", - "ids": "4371" - }, - { - "examine": "It's a small table.", - "ids": "4372" - }, - { - "examine": "A tray of sand.", - "ids": "4373,4374,4375,4376" - }, - { - "examine": "There should be a standard here!", - "ids": "4377,4378,4379" - }, - { - "examine": "I could climb this if I wanted.", - "ids": "4380" - }, - { - "examine": "It's a war machine.", - "ids": "4381,4382" - }, - { - "examine": "I could climb this if I wanted.", - "ids": "4383,4384" - }, - { - "examine": "The catapult is damaged.", - "ids": "4385,4386" - }, - { - "examine": "A portal to join the Saradomin team.", - "ids": "4387" - }, - { - "examine": "A portal to join the Zamorak team.", - "ids": "4388" - }, - { - "examine": "A portal to leave the Saradomin team.", - "ids": "4389" - }, - { - "examine": "A portal to leave the Zamorak team.", - "ids": "4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405" - }, - { - "examine": "A portal to leave the Saradomin team.", - "ids": "4406" - }, - { - "examine": "A portal to leave the Zamorak team.", - "ids": "4407" - }, - { - "examine": "A portal to join a random team.", - "ids": "4408,4409,4410" - }, - { - "examine": "A very slippery stepping stone", - "ids": "4411" - }, - { - "examine": "I could climb this if I wanted.", - "ids": "4412,4413" - }, - { - "examine": "A rickety old staircase.", - "ids": "4414" - }, - { - "examine": "A solid stone staircase.", - "ids": "4415,4416,4417,4418,4419,4420,36480,36481,36484,36495,36521,36523,36532,36540" - }, - { - "examine": "A spiky barricade.", - "ids": "4421,4422" - }, - { - "examine": "A large broken door.", - "ids": "4431,4432,4433,4434,4435,4436" - }, - { - "examine": "We could use our pickaxes to get past these...", - "ids": "4437" - }, - { - "examine": "We can almost get past these...", - "ids": "4438,4439,4440,4441,4442,4443" - }, - { - "examine": "Should be long enough to scale castle walls.", - "ids": "4444,4445" - }, - { - "examine": "Maybe I could tie a rope to this...", - "ids": "4446,4447" - }, - { - "examine": "It doesn't look very stable...", - "ids": "4448" - }, - { - "examine": "A solid stone staircase.", - "ids": "4449,4450,4451,4452,4453,4454,4455,4456,4457" - }, - { - "examine": "There are some bandages on this table.", - "ids": "4458" - }, - { - "examine": "There are some toolboxes on this table.", - "ids": "4459" - }, - { - "examine": "There's some rock I can use with the catapult here.", - "ids": "4460" - }, - { - "examine": "There are some barricades here.", - "ids": "4461" - }, - { - "examine": "There is some rope here.", - "ids": "4462" - }, - { - "examine": "There are some explosive potions here.", - "ids": "4463" - }, - { - "examine": "There are some pickaxes on this table.", - "ids": "4464" - }, - { - "examine": "An elf-fashioned door.", - "ids": "4465,4466" - }, - { - "examine": "The door is closed.", - "ids": "4467" - }, - { - "examine": "The door is open.", - "ids": "4468" - }, - { - "examine": "Only the Saradomin team may pass.", - "ids": "4469" - }, - { - "examine": "Only the Zamorak team may pass.", - "ids": "4470" - }, - { - "examine": "I wonder what's under it?", - "ids": "4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481" - }, - { - "examine": "Water comes out of this.", - "ids": "4482" - }, - { - "examine": "It's open.", - "ids": "4483" - }, - { - "examine": "Keep track of which team has the most victories.", - "ids": "4484" - }, - { - "examine": "I could climb this if I wanted.", - "ids": "4485,4486" - }, - { - "examine": "A big wooden door.", - "ids": "4487,4488,4489,4490,4491,4492" - }, - { - "examine": "I can climb these stairs.", - "ids": "4493" - }, - { - "examine": "They go down.", - "ids": "4494" - }, - { - "examine": "I can climb these stairs.", - "ids": "4495" - }, - { - "examine": "They go down.", - "ids": "4496" - }, - { - "examine": "I can climb these stairs.", - "ids": "4497" - }, - { - "examine": "They go down.", - "ids": "4498" - }, - { - "examine": "Wow", - "ids": "4499" - }, - { - "examine": "This leads back to the cruel world above.", - "ids": "4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512" - }, - { - "examine": "I doubt that was built to last...", - "ids": "4513,4514,4515,4516,4517" - }, - { - "examine": "How do you make a skeleton laugh?", - "ids": "4518" - }, - { - "examine": "Tickle his funny bone.", - "ids": "4519" - }, - { - "examine": "Clearly has been relaxing too long....", - "ids": "4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540" - }, - { - "examine": "Did that thing just twitch?", - "ids": "4541,4542" - }, - { - "examine": "A strange wall with objects engraved upon it.", - "ids": "4543,4544" - }, - { - "examine": "A strange wall that appears to be hinged.", - "ids": "4545,4546,4547,4548,4549" - }, - { - "examine": "I can jump off this one.", - "ids": "4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567" - }, - { - "examine": "I can climb up these stairs.", - "ids": "4568" - }, - { - "examine": "I can climb up or go down these stairs.", - "ids": "4569,36777" - }, - { - "examine": "I can climb down these stairs.", - "ids": "4570,4571,4572,4573,4574,4575,4576" - }, - { - "examine": "Lets you walk through walls!", - "ids": "4577,4578,4579,4580,4581,4582,4583,4584,4585,4586" - }, - { - "examine": "It turns the light around.", - "ids": "4587" - }, - { - "examine": "It looks broken.", - "ids": "4588" - }, - { - "examine": "Part of the Lighthouse's lighting mechanism.", - "ids": "4589" - }, - { - "examine": "Part of the lighthouse Light mechanism.", - "ids": "4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609" - }, - { - "examine": "Best left on the beach.", - "ids": "4610" - }, - { - "examine": "This once belonged to a sea animal.", - "ids": "4611" - }, - { - "examine": "Best left for the crabs.", - "ids": "4612" - }, - { - "examine": "I can hear the sea with this.", - "ids": "4613" - }, - { - "examine": "It is a buried bowl.", - "ids": "4614" - }, - { - "examine": "I can jump off this one.", - "ids": "4615,4616" - }, - { - "examine": "Shelves filled with interesting books.", - "ids": "4617" - }, - { - "examine": "A nice and cosy fire.", - "ids": "4618,4619" - }, - { - "examine": "They go down.", - "ids": "4620,4621" - }, - { - "examine": "They go up.", - "ids": "4622,4623" - }, - { - "examine": "They go down.", - "ids": "4624,4625" - }, - { - "examine": "They go up.", - "ids": "4626,4627,4628" - }, - { - "examine": "An elf-fashioned door.", - "ids": "4636,4637,4638,4639,4640" - }, - { - "examine": "Mmm...beer!", - "ids": "4641" - }, - { - "examine": "Has some board games news on it.", - "ids": "4642" - }, - { - "examine": "The ladder to the Runelink challenge room for experienced players.", - "ids": "4643" - }, - { - "examine": "The ladder back to the Runelink challenge room.", - "ids": "4644" - }, - { - "examine": "The ladder to the Draughts challenge room for experienced players.", - "ids": "4645" - }, - { - "examine": "The ladder back to the Draughts challenge room.", - "ids": "4646" - }, - { - "examine": "The ladder back up to the Toad and Chicken.", - "ids": "4647" - }, - { - "examine": "Leads down to the Burthorpe Games Rooms.", - "ids": "4648,4649" - }, - { - "examine": "A nice and cosy fire.", - "ids": "4650" - }, - { - "examine": "A table for board games.", - "ids": "4651" - }, - { - "examine": "A game of draughts is being played on this table.", - "ids": "4652" - }, - { - "examine": "A game of Runelink is being played on this table.", - "ids": "4653,4654,4655" - }, - { - "examine": "A comfy stool.", - "ids": "4656,4657" - }, - { - "examine": "Draughts challenge room.", - "ids": "4658" - }, - { - "examine": "Runelink challenge room.", - "ids": "4659" - }, - { - "examine": "Draughts challenge room for experienced players.", - "ids": "4660" - }, - { - "examine": "Runelink challenge room for experienced players.", - "ids": "4661,4662,4663,4664,4665,4666,4667,4668" - }, - { - "examine": "A statue of Arrav (the Fountain of Heroes has moved downstairs.)", - "ids": "4669" - }, - { - "examine": "A statue of Camorra (the Fountain of Heroes has moved downstairs.)", - "ids": "4670" - }, - { - "examine": "A good source of books!", - "ids": "4671" - }, - { - "examine": "The door into the throne room.", - "ids": "4672,4673" - }, - { - "examine": "I bet this makes good syrup!", - "ids": "4674" - }, - { - "examine": "Scented herbs.", - "ids": "4675" - }, - { - "examine": "A rocky outcrop.", - "ids": "4676" - }, - { - "examine": "Scented herbs.", - "ids": "4677,4678,4679,4680,4681,4682" - }, - { - "examine": "A large harp.", - "ids": "4683" - }, - { - "examine": "Good for shooting fish in.", - "ids": "4684" - }, - { - "examine": "This old tree is rotting away", - "ids": "4685" - }, - { - "examine": "This old tree is rotting away.", - "ids": "4686,4687,4688,4689" - }, - { - "examine": "Fancy.", - "ids": "4690,4691" - }, - { - "examine": "Flag, pole...Yep, it's a flagpole.", - "ids": "4692,4693,4694,4695" - }, - { - "examine": "The door is closed.", - "ids": "4696" - }, - { - "examine": "The door is open.", - "ids": "4697,4698,4699,4700" - }, - { - "examine": "Keeps the cold winds out.", - "ids": "4701" - }, - { - "examine": "A nicely carved wooden chair.", - "ids": "4702" - }, - { - "examine": "A wooden double bed. For sleeping in...", - "ids": "4703,4704" - }, - { - "examine": "There's something fishy about this stall.", - "ids": "4705" - }, - { - "examine": "You should eat your greens!", - "ids": "4706" - }, - { - "examine": "There's something fishy about this stall.", - "ids": "4707" - }, - { - "examine": "You should eat your greens!", - "ids": "4708,4709" - }, - { - "examine": "A doorway made from bamboo.", - "ids": "4710,4711" - }, - { - "examine": "It's a trapdoor.", - "ids": "4712" - }, - { - "examine": "It's an open trapdoor.", - "ids": "4713" - }, - { - "examine": "A wooden crate for storage.", - "ids": "4714" - }, - { - "examine": "This crate is making chattering sounds.", - "ids": "4715" - }, - { - "examine": "This crate smells slightly nauseous.", - "ids": "4716" - }, - { - "examine": "This crate says 'Property of Hamab' on its side.", - "ids": "4717,4718" - }, - { - "examine": "This crate says 'Property of Ifaba' on its side.", - "ids": "4719" - }, - { - "examine": "This crate says 'Property of Daga' on its side.", - "ids": "4720,4721" - }, - { - "examine": "This crate smells slightly of banana.", - "ids": "4722,4723" - }, - { - "examine": "This crate says 'Property of Hamab' on its side.", - "ids": "4724" - }, - { - "examine": "This crate says 'Property of Ifaba' on its side.", - "ids": "4725,4726,4727" - }, - { - "examine": "I can climb up this.", - "ids": "4728" - }, - { - "examine": "A dried up bush, void of life.", - "ids": "4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742" - }, - { - "examine": "It's a bamboo ladder.", - "ids": "4743,4744" - }, - { - "examine": "Looks good for jumping off.", - "ids": "4745" - }, - { - "examine": "This crate is marked 'Deliver to Glough'...", - "ids": "4746,4747,4748" - }, - { - "examine": "It's a banana tree, full of bananas.", - "ids": "4749" - }, - { - "examine": "It's a banana tree, with lots of bananas.", - "ids": "4750" - }, - { - "examine": "It's a banana tree, with many bananas.", - "ids": "4751" - }, - { - "examine": "It's a banana tree, with a few bananas.", - "ids": "4752" - }, - { - "examine": "It's a banana tree, with but one banana.", - "ids": "4753" - }, - { - "examine": "It's a banana tree, with no more bananas left.", - "ids": "4754" - }, - { - "examine": "They go down.", - "ids": "4755" - }, - { - "examine": "They go up.", - "ids": "4756,4757,4758,4759,4760,4761,4762,4763" - }, - { - "examine": "It's a bamboo stool.", - "ids": "4764" - }, - { - "examine": "It's a sheer wall of fire, rising as high as you can see.", - "ids": "4765,4766" - }, - { - "examine": "The contents of this pyre are rapidly bubbling and burning.", - "ids": "4767" - }, - { - "examine": "It's a wall of bricks.", - "ids": "4768" - }, - { - "examine": "It's a pile of bricks.", - "ids": "4769,4770" - }, - { - "examine": "A rather dapper little monkey sitting on a throne.", - "ids": "4771" - }, - { - "examine": "It's a bamboo ladder.", - "ids": "4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4785" - }, - { - "examine": "A plant in a bamboo pot.", - "ids": "4786" - }, - { - "examine": "It's an absolutely huge bamboo gate.", - "ids": "4787,4788,4789,4790" - }, - { - "examine": "It's a big comfy bed, made of strips of bamboo.", - "ids": "4791,4792,4793" - }, - { - "examine": "It's a pot made out of bamboo.", - "ids": "4794" - }, - { - "examine": "They are pots made out of bamboo.", - "ids": "4795,4796" - }, - { - "examine": "Bamboo strips have been lashed together to make this rickety desk.", - "ids": "4797" - }, - { - "examine": "It's a bookcase made out of bamboo.", - "ids": "4798" - }, - { - "examine": "It's a bamboo door with a large iron padlock.", - "ids": "4799,4800,4801,4802,4803,4804,4805,4806" - }, - { - "examine": "It's a door made from bamboo.", - "ids": "4807,4808,4809,4810,4811" - }, - { - "examine": "Looks good for hiding in...", - "ids": "4812,4813,4814" - }, - { - "examine": "Looks good for hiding in.", - "ids": "4815" - }, - { - "examine": "This is a fairly tall tree with sparse foliage.", - "ids": "4816" - }, - { - "examine": "A jungle palm with dense foliage.", - "ids": "4817" - }, - { - "examine": "This is a fairly tall tree with sparse foliage.", - "ids": "4818" - }, - { - "examine": "This was a fairly tall tree with sparse foliage.", - "ids": "4819" - }, - { - "examine": "A leafy tree.", - "ids": "4820" - }, - { - "examine": "This was a fairly tall tree with sparse foliage.", - "ids": "4821" - }, - { - "examine": "This tree has been cut down.", - "ids": "4822" - }, - { - "examine": "This flower is found only in jungle areas.", - "ids": "4823" - }, - { - "examine": "A very rare and exotic flower.", - "ids": "4824" - }, - { - "examine": "A small fernlike plant.", - "ids": "4825" - }, - { - "examine": "Leaves a nasty mark.", - "ids": "4826" - }, - { - "examine": "Looks spiky.", - "ids": "4827" - }, - { - "examine": "This has broad leaves.", - "ids": "4828" - }, - { - "examine": "A type of jungle fern.", - "ids": "4829" - }, - { - "examine": "A large waxy jungle plant.", - "ids": "4830" - }, - { - "examine": "Commonly found in these parts.", - "ids": "4831" - }, - { - "examine": "The tendrils of a creeping plant.", - "ids": "4832" - }, - { - "examine": "A jungle bush, quite common to these areas.", - "ids": "4833,4834" - }, - { - "examine": "A jungle bush that has been chopped down.", - "ids": "4835,4836,4837,4838,4839,4840,4841,4842,4843,4844" - }, - { - "examine": "A terribly tall tropical tree.", - "ids": "4845,4846,4847" - }, - { - "examine": "Leaves of a tropical tree.", - "ids": "4848" - }, - { - "examine": "This tree no doubt contains dangerous insects.", - "ids": "4849,4850,4851" - }, - { - "examine": "This old tree is rotting away.", - "ids": "4852" - }, - { - "examine": "A gnarly old tree root.", - "ids": "4853" - }, - { - "examine": "The roots of this tree are exposed.", - "ids": "4854" - }, - { - "examine": "I hope I don't trip over any of these.", - "ids": "4855" - }, - { - "examine": "It's a small patch of glowing fungus.", - "ids": "4856" - }, - { - "examine": "It's a medium patch of glowing fungus.", - "ids": "4857" - }, - { - "examine": "It's an absolutely colossal statue of some kind of gorilla.", - "ids": "4858" - }, - { - "examine": "It's a huge statue of some kind of gorilla.", - "ids": "4859,4860" - }, - { - "examine": "It's a huge statue of some kind of monkey.", - "ids": "4861" - }, - { - "examine": "It's a large patch of glowing fungus.", - "ids": "4862" - }, - { - "examine": "Legs of this watchtower.", - "ids": "4863,4864" - }, - { - "examine": "It's the middle of this watchtower.", - "ids": "4865" - }, - { - "examine": "It's a deactivated military Gnome glider.", - "ids": "4866" - }, - { - "examine": "It's an activated military Gnome glider.", - "ids": "4867" - }, - { - "examine": "It's some kind of Gnome teleportation device.", - "ids": "4868,4869,4870" - }, - { - "examine": "This is the panel controlling the hangar reinitialisation.", - "ids": "4871" - }, - { - "examine": "There must be an exit nearby.", - "ids": "4872" - }, - { - "examine": "It's probably too risky to try pulling this.", - "ids": "4873" - }, - { - "examine": "This table has crafting paraphernalia on it.", - "ids": "4874" - }, - { - "examine": "This table has ripe bananas on show.", - "ids": "4875" - }, - { - "examine": "This table has items of a general nature on it.", - "ids": "4876" - }, - { - "examine": "This table has runes on display.", - "ids": "4877" - }, - { - "examine": "This table has a scimitar on it.", - "ids": "4878" - }, - { - "examine": "It's a trapdoor.", - "ids": "4879" - }, - { - "examine": "It's an open trapdoor.", - "ids": "4880" - }, - { - "examine": "I can climb up this.", - "ids": "4881" - }, - { - "examine": "Looks suspicious.", - "ids": "4882,4883" - }, - { - "examine": "A plank.", - "ids": "4884" - }, - { - "examine": "Formed over many years.", - "ids": "4885" - }, - { - "examine": "Human sieve creation.", - "ids": "4886" - }, - { - "examine": "Looks suspicious.", - "ids": "4887" - }, - { - "examine": "It's a trapdoor.", - "ids": "4888" - }, - { - "examine": "I can climb up this.", - "ids": "4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899" - }, - { - "examine": "The Saradomin Team Standard.", - "ids": "4900" - }, - { - "examine": "The Zamorak Team Standard.", - "ids": "4901" - }, - { - "examine": "The Saradomin Team Standard.", - "ids": "4902" - }, - { - "examine": "The Zamorak Team Standard.", - "ids": "4903" - }, - { - "examine": "It's on fire!", - "ids": "4904,4905,4906,4907,4908,4909" - }, - { - "examine": "A wooden barrel for storage.", - "ids": "4910" - }, - { - "examine": "I can climb down this.", - "ids": "4911,4912,36349,36365" - }, - { - "examine": "It looks cramped and dark.", - "ids": "4913,4914,4915,4916,4917" - }, - { - "examine": "This cart is blocking the way up the ridge.", - "ids": "4918" - }, - { - "examine": "These stairs seem to have been hewn out of the rock itself.", - "ids": "4919" - }, - { - "examine": "It looks cramped and dark.", - "ids": "4920,4921,4922" - }, - { - "examine": "These stairs seem to have been hewn out of the rock itself.", - "ids": "4923" - }, - { - "examine": "A valve to start and stop the flow of water.", - "ids": "4924,4925" - }, - { - "examine": "Shiny!", - "ids": "4926,4927,4928" - }, - { - "examine": "It looks cramped and dark.", - "ids": "4929" - }, - { - "examine": "It's blocking the tunnel, but it looks dark down there anyway.", - "ids": "4930,4931" - }, - { - "examine": "A bizarre fungus. It emits a pale blue light.", - "ids": "4932,4933,4934" - }, - { - "examine": "If that wasn't there I'd probably be a lot flatter now.", - "ids": "4935" - }, - { - "examine": "It prevents the wall unceremoniously squashing people.", - "ids": "4936" - }, - { - "examine": "It looks like it's water powered.", - "ids": "4937,4938,4939,4940,4941" - }, - { - "examine": "It's a little waterlogged. I hope it still works.", - "ids": "4942,4943" - }, - { - "examine": "It doesn't look very watertight. Any contents will be ruined.", - "ids": "4944" - }, - { - "examine": "A sunken mine cart, how useful.", - "ids": "4945,4946,4947,4948" - }, - { - "examine": "This displays information on how the points on this level are set.", - "ids": "4949" - }, - { - "examine": "It has the letter 'B' inscribed on the end.", - "ids": "4950" - }, - { - "examine": "It has the letter 'A' inscribed on the end.", - "ids": "4951" - }, - { - "examine": "It has the letter 'C' inscribed on the end.", - "ids": "4952" - }, - { - "examine": "It has the letter 'D' inscribed on the end.", - "ids": "4953" - }, - { - "examine": "It has the letter 'E' inscribed on the end.", - "ids": "4954" - }, - { - "examine": "It has the letter 'I' inscribed on the end.", - "ids": "4955" - }, - { - "examine": "It has the letter 'J' inscribed on the end.", - "ids": "4956" - }, - { - "examine": "It has the letter 'K' inscribed on the end.", - "ids": "4957" - }, - { - "examine": "I think this changes one of the sets of points.", - "ids": "4958" - }, - { - "examine": "It has the letter 'F' inscribed on the end.", - "ids": "4959" - }, - { - "examine": "It has the letter 'G' inscribed on the end.", - "ids": "4960" - }, - { - "examine": "It has the letter 'H' inscribed on the end.", - "ids": "4961" - }, - { - "examine": "The door is closed.", - "ids": "4962" - }, - { - "examine": "I can climb down this.", - "ids": "4965" - }, - { - "examine": "I can climb this.", - "ids": "4966" - }, - { - "examine": "I can climb down this.", - "ids": "4967" - }, - { - "examine": "I can climb this.", - "ids": "4968" - }, - { - "examine": "I can climb down this.", - "ids": "4969" - }, - { - "examine": "I can climb this.", - "ids": "4970" - }, - { - "examine": "These stairs seem to have been hewn out of the rock itself.", - "ids": "4971,4972,4973" - }, - { - "examine": "Useful for moving items around the mine.", - "ids": "4974" - }, - { - "examine": "An old crate for storage.", - "ids": "4975" - }, - { - "examine": "A distinctive layer in the rock strata.", - "ids": "4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000" - }, - { - "examine": "This cave has been boarded up.", - "ids": "5001" - }, - { - "examine": "Useful for passing over inaccessible areas.", - "ids": "5002" - }, - { - "examine": "It's old and pretty broken.", - "ids": "5003" - }, - { - "examine": "A well used tree.", - "ids": "5004,5005" - }, - { - "examine": "These flowers only grow in one place in the mountains.", - "ids": "5006" - }, - { - "examine": "Looks like small cave.", - "ids": "5007" - }, - { - "examine": "Looks dark...", - "ids": "5008,5009,5010,5011,5012,5013,5014" - }, - { - "examine": "It's too dangerous to go down here by foot...", - "ids": "5015,5016,5017,5018,5019,5020,5021,5022,5023,5024" - }, - { - "examine": "A split in the cave wall...", - "ids": "5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036" - }, - { - "examine": "A large ice covered boulder.", - "ids": "5037" - }, - { - "examine": "An ice covered boulder.", - "ids": "5038" - }, - { - "examine": "A small ice covered boulder.", - "ids": "5039,5040,5041,5042" - }, - { - "examine": "A huge ice gate.", - "ids": "5043,5044" - }, - { - "examine": "An interesting-looking tree.", - "ids": "5045" - }, - { - "examine": "A small cave entrance.", - "ids": "5046" - }, - { - "examine": "Limestone ceiling growth.", - "ids": "5047" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "5048" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "5049" - }, - { - "examine": "Tooth shaped rock formations protruding from the floor.", - "ids": "5050" - }, - { - "examine": "A dirty little swamp boat.", - "ids": "5051" - }, - { - "examine": "If it had paint on it, you'd probably watch it dry.", - "ids": "5052,5053" - }, - { - "examine": "I can climb this.", - "ids": "5054" - }, - { - "examine": "I wonder what that's there for...", - "ids": "5055" - }, - { - "examine": "These doors look very ominous.", - "ids": "5056,5057" - }, - { - "examine": "Large doors set into the hillside.", - "ids": "5058,5059" - }, - { - "examine": "These doors seem to lead into the underground.", - "ids": "5060,5061" - }, - { - "examine": "Large doors set into the hillside.", - "ids": "5062,5063,5064,5065,5066,5067,5068,5069,5070,5071" - }, - { - "examine": "A Large Pillar", - "ids": "5072,5073,5074,5075,5076,5077,5078,5079,5080,5081" - }, - { - "examine": "An overgrown dungeon entrance.", - "ids": "5082" - }, - { - "examine": "A closed overgrown dungeon entrance.", - "ids": "5083" - }, - { - "examine": "The way to go when I get scared.", - "ids": "5084,5085,5086,5087" - }, - { - "examine": "I hope I don't fall off this.", - "ids": "5088,5089,5090,5091,5092,5093" - }, - { - "examine": "These stairs seem to have been hewn out of the rock itself.", - "ids": "5094,5095,5096,5097,5098" - }, - { - "examine": "Thick vines blocking your way.", - "ids": "5103,5104,5105,5106,5107,5108,5109" - }, - { - "examine": "I can jump from this stepping stone.", - "ids": "5110,5111" - }, - { - "examine": "Not good for eating.", - "ids": "5112" - }, - { - "examine": "I doubt that's edible.", - "ids": "5113,5114,5115" - }, - { - "examine": "A statue of a big monster.", - "ids": "5116,5117,5118,5119,5120,5121" - }, - { - "examine": "A tall wooden door.", - "ids": "5126" - }, - { - "examine": "A tall wooden door.", - "ids": "5128,5129" - }, - { - "examine": "Looks like whoever uses this has claws on their hands.", - "ids": "5130" - }, - { - "examine": "I wonder what's under it?", - "ids": "5131" - }, - { - "examine": "I wonder what's down there?", - "ids": "5132" - }, - { - "examine": "A hurdle.", - "ids": "5133,5134,5135" - }, - { - "examine": "A climbing wall made from skulls.", - "ids": "5136,5137" - }, - { - "examine": "A very slippery stepping stone.", - "ids": "5138" - }, - { - "examine": "A scary zip line for teeth??", - "ids": "5139,5140,5141,5142,5143,5144,5145" - }, - { - "examine": "A goal.", - "ids": "5146,5147,5148,5149,5150,5151" - }, - { - "examine": "This may be worth opening.", - "ids": "5156" - }, - { - "examine": "This may be worth searching.", - "ids": "5157" - }, - { - "examine": "A pile of garden canes.", - "ids": "5158" - }, - { - "examine": "There's no way to cross this bridge.", - "ids": "5159,5160" - }, - { - "examine": "An old grandfather clock.", - "ids": "5161" - }, - { - "examine": "A closed chest.", - "ids": "5162" - }, - { - "examine": "An open chest.", - "ids": "5163" - }, - { - "examine": "There is a note pinned to the signpost.", - "ids": "5164" - }, - { - "examine": "It looks like it needs a good sweep out.", - "ids": "5165" - }, - { - "examine": "Bookish.", - "ids": "5166" - }, - { - "examine": "A large, elaborately ornamented memorial stone.", - "ids": "5167" - }, - { - "examine": "A grave, marked by an ostentatious memorial stone.", - "ids": "5168" - }, - { - "examine": "A poor grave marked by a simple, wooden cross.", - "ids": "5169" - }, - { - "examine": "The entrance to an extravagantly decorated mausoleum.", - "ids": "5170,5171" - }, - { - "examine": "The door to the Tower.", - "ids": "5172,5173" - }, - { - "examine": "The door to the garden shed.", - "ids": "5174,5175" - }, - { - "examine": "At some point the lightning conductor has broken, rendering it useless.", - "ids": "5176" - }, - { - "examine": "A shocking piece of kit.", - "ids": "5177" - }, - { - "examine": "Mmm.. scented candles.", - "ids": "5178,5179" - }, - { - "examine": "I wouldn't eat there!", - "ids": "5180,5181,5182" - }, - { - "examine": "Looks wooden. Feels wooden. I wonder is it wooden?", - "ids": "5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201" - }, - { - "examine": "Dangerous, someone could trip on them.", - "ids": "5202,5203,5204,5205" - }, - { - "examine": "I can climb these stairs.", - "ids": "5206" - }, - { - "examine": "They go down.", - "ids": "5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227" - }, - { - "examine": "Formed over many years of dripping limestone.", - "ids": "5228,5229,5230" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243" - }, - { - "examine": "Looks a bit tatty...", - "ids": "5244,5245" - }, - { - "examine": "A well slept in bed.", - "ids": "5246,5247" - }, - { - "examine": "It looks like a tree made of crystal.", - "ids": "5248" - }, - { - "examine": "Looks to me like a quickly built fire.", - "ids": "5249" - }, - { - "examine": "I can climb down this.", - "ids": "5250" - }, - { - "examine": "I can climb this.", - "ids": "5251" - }, - { - "examine": "A recently extinguished fire.", - "ids": "5252" - }, - { - "examine": "I wish I could sting other people.", - "ids": "5253" - }, - { - "examine": "Probably feels like a mild bee sting.", - "ids": "5254" - }, - { - "examine": "I wouldn't like to get stung.", - "ids": "5255" - }, - { - "examine": "Dock leaves at the ready.", - "ids": "5256" - }, - { - "examine": "Nettles sting my leggies.", - "ids": "5257" - }, - { - "examine": "These may hurt.", - "ids": "5258" - }, - { - "examine": "A ghostly barrier.", - "ids": "5259,5260,5261" - }, - { - "examine": "These stairs were carved out of the rock of the cavern.", - "ids": "5262,5263" - }, - { - "examine": "I can climb this.", - "ids": "5264" - }, - { - "examine": "I can climb up here.", - "ids": "5265" - }, - { - "examine": "I can go below decks with this ladder.", - "ids": "5266" - }, - { - "examine": "I wonder what's under it.", - "ids": "5267" - }, - { - "examine": "I wonder what's down there.", - "ids": "5268" - }, - { - "examine": "I can't see a rock!", - "ids": "5269" - }, - { - "examine": "I wonder what's inside.", - "ids": "5270,5271,5272" - }, - { - "examine": "Perhaps I should search it.", - "ids": "5273" - }, - { - "examine": "High above here is a tattered flag, blowing in the wind.", - "ids": "5274" - }, - { - "examine": "An appliance for cooking with.", - "ids": "5275" - }, - { - "examine": "The bank teller will serve you from here.", - "ids": "5276" - }, - { - "examine": "This booth is closed.", - "ids": "5277" - }, - { - "examine": "The resting place of Necrovarus' mortal body.", - "ids": "5278,5279" - }, - { - "examine": "I can climb these stairs.", - "ids": "5280" - }, - { - "examine": "They go down.", - "ids": "5281" - }, - { - "examine": "A ghastly fountain filled with slime and bones, the source of Necrovarus' power.", - "ids": "5282" - }, - { - "examine": "It's a small Ectofuntus.", - "ids": "5283" - }, - { - "examine": "A big grinding thing.", - "ids": "5284" - }, - { - "examine": "The tatty gangplank of a tatty ship.", - "ids": "5285,5286" - }, - { - "examine": "Seen better days.", - "ids": "5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305" - }, - { - "examine": "A wooden rowing boat.", - "ids": "5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329" - }, - { - "examine": "A pile of boxes for storage.", - "ids": "5330" - }, - { - "examine": "A leafy fern.", - "ids": "5331" - }, - { - "examine": "A small bushy plant.", - "ids": "5332" - }, - { - "examine": "A leafy shrub.", - "ids": "5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344" - }, - { - "examine": "This needs dusting before I'll sit on it.", - "ids": "5346,5347" - }, - { - "examine": "Not so good for sitting on.", - "ids": "5348" - }, - { - "examine": "Generally used for putting things on.", - "ids": "5349" - }, - { - "examine": "Actually, I could do with a drink...", - "ids": "5350" - }, - { - "examine": "For leaning against...", - "ids": "5351" - }, - { - "examine": "One horsepower; wooden suspension: a beauty.", - "ids": "5352" - }, - { - "examine": "A wooden wheelbarrow.", - "ids": "5353" - }, - { - "examine": "Animal feeder.", - "ids": "5354" - }, - { - "examine": "It probably hasn't got anything interesting inside.", - "ids": "5355" - }, - { - "examine": "They probably haven't got anything interesting inside.", - "ids": "5356,5357" - }, - { - "examine": "Looks like he's been dead a while now...", - "ids": "5358" - }, - { - "examine": "I don't think he'd mind us checking for his wallet now...", - "ids": "5359" - }, - { - "examine": "I'm sure he died of natural causes. Like a massive dragon or something...", - "ids": "5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396" - }, - { - "examine": "This figure brings luck to those who sail.", - "ids": "5397,5398,5399,5400,5401,5402" - }, - { - "examine": "Without this I'm going around in circles.", - "ids": "5403" - }, - { - "examine": "Holds up the sails.", - "ids": "5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414" - }, - { - "examine": "Allows access to other parts of the ship.", - "ids": "5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428" - }, - { - "examine": "It's a table with candles on.", - "ids": "5429" - }, - { - "examine": "Doesn't look too good...", - "ids": "5430" - }, - { - "examine": "Looks a bit empty.", - "ids": "5431,5432,5433,5434,5435,5436,5437,5438" - }, - { - "examine": "It's been knocked off its hinges.", - "ids": "5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452" - }, - { - "examine": "It's a door.", - "ids": "5453,5454,5455,5456,5457,5458,5459,5460" - }, - { - "examine": "A subterranean pool of ectoplasm.", - "ids": "5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487" - }, - { - "examine": "I can climb this.", - "ids": "5488" - }, - { - "examine": "The finest rings.", - "ids": "5489" - }, - { - "examine": "I wonder what's under it?", - "ids": "5490" - }, - { - "examine": "I wonder what's down there?", - "ids": "5491,5492" - }, - { - "examine": "I can climb this.", - "ids": "5493" - }, - { - "examine": "A crude torch stuck in the ground.", - "ids": "5494" - }, - { - "examine": "I guess I could sleep in it if I was really tired.", - "ids": "5495,5496" - }, - { - "examine": "A well slept in bed.", - "ids": "5497,5498" - }, - { - "examine": "Hot!", - "ids": "5499,5500" - }, - { - "examine": "Stops people getting out.", - "ids": "5501,5502,5503,5504,5505,5506,5507" - }, - { - "examine": "It's a lectern.", - "ids": "5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537" - }, - { - "examine": "Makes you cry.", - "ids": "5538" - }, - { - "examine": "Found near the water's edge.", - "ids": "5539,5540,5541,5542" - }, - { - "examine": "Isn't Heather a girls' name?", - "ids": "5543" - }, - { - "examine": "Smells lovely!", - "ids": "5544" - }, - { - "examine": "Who is this Heather girl?", - "ids": "5545" - }, - { - "examine": "A purple haze of delight.", - "ids": "5546" - }, - { - "examine": "The colour purple on stems.", - "ids": "5547" - }, - { - "examine": "I ponder... Why is it purple?", - "ids": "5548" - }, - { - "examine": "I wonder why it's purple?", - "ids": "5549" - }, - { - "examine": "A cure for nettle stings.", - "ids": "5550" - }, - { - "examine": "A droopy tree.", - "ids": "5551" - }, - { - "examine": "These trees are found near water.", - "ids": "5552,5553" - }, - { - "examine": "This is what is left of a willow tree.", - "ids": "5554" - }, - { - "examine": "I don't know art, but I like it!", - "ids": "5555,5556,5557" - }, - { - "examine": "Aggie's cooking something, probably best not to think what...", - "ids": "5558,9736" - }, - { - "examine": "Trinkets and stuff.", - "ids": "5559" - }, - { - "examine": "Looking good!", - "ids": "5560" - }, - { - "examine": "Aggie's broomstick.", - "ids": "5561" - }, - { - "examine": "Aggie has already dyed this cloth.", - "ids": "5562,5563" - }, - { - "examine": "A thoroughly used bed.", - "ids": "5564" - }, - { - "examine": "A lovely comfy-looking big bed.", - "ids": "5565,5566,5567,5568" - }, - { - "examine": "The remains of a stone wall.", - "ids": "5569,5570" - }, - { - "examine": "An empty home for chickens.", - "ids": "5571" - }, - { - "examine": "A lovely bare chicken coop.", - "ids": "5572,5573" - }, - { - "examine": "Full of animal feed.", - "ids": "5574" - }, - { - "examine": "Animal feeder.", - "ids": "5575,5576,5577" - }, - { - "examine": "A traveller's companion.", - "ids": "5578" - }, - { - "examine": "Loaded with hay and ready to roll.", - "ids": "5579" - }, - { - "examine": "A wooden wheelbarrow.", - "ids": "5580" - }, - { - "examine": "Someone's been chopping logs.", - "ids": "5581,5582" - }, - { - "examine": "Baby bread.", - "ids": "5583,5584,5585,5586,5587,5588" - }, - { - "examine": "The river makes it spin.", - "ids": "5589,5590,5591,5592,5593" - }, - { - "examine": "I'd better not get my hands trapped in that.", - "ids": "5594" - }, - { - "examine": "Diango's Toy Stall.", - "ids": "5595" - }, - { - "examine": "Doesn't look too good...", - "ids": "5596" - }, - { - "examine": "Shows which way the wind blows.", - "ids": "5597" - }, - { - "examine": "A barrel for collecting rain water.", - "ids": "5598,5599,5600,5601,5602,5603" - }, - { - "examine": "A rock.", - "ids": "5604" - }, - { - "examine": "A small rock.", - "ids": "5605" - }, - { - "examine": "Some rock.", - "ids": "5606,5607" - }, - { - "examine": "This fire is already in use, I wouldn't mess with it if I were you...", - "ids": "5608" - }, - { - "examine": "They could do with a wash.", - "ids": "5609,5610,5611,5612" - }, - { - "examine": "It smells like the rats aren't washing often enough.", - "ids": "5613" - }, - { - "examine": "Sit back and relax...", - "ids": "5615" - }, - { - "examine": "This tells you which way is which.", - "ids": "5616,5617" - }, - { - "examine": "These open and close!", - "ids": "5618" - }, - { - "examine": "This may be worth searching.", - "ids": "5619,5620" - }, - { - "examine": "An elegant ceramic pot tarnished with the dirt of a hundred years.", - "ids": "5621" - }, - { - "examine": "I wonder what's inside...", - "ids": "5622" - }, - { - "examine": "It smells a bit stuffy.", - "ids": "5623" - }, - { - "examine": "It smells funny in there.", - "ids": "5624" - }, - { - "examine": "Ned is making some rope here.", - "ids": "5625,5626" - }, - { - "examine": "A blue standard.", - "ids": "5627" - }, - { - "examine": "A standard of Lumbridge Castle.", - "ids": "5628,5629,5630,36925" - }, - { - "examine": "Glowing embers.", - "ids": "5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787" - }, - { - "examine": "The sort of bench you get in churches.", - "ids": "5788" - }, - { - "examine": "An expertly carved statue of a former King of Misthalin.", - "ids": "5789,5790" - }, - { - "examine": "A carving of a figure from the history of 2009Scape.", - "ids": "5791,36749,36751" - }, - { - "examine": "When I've ground some flour, I'll be able to collect it here.", - "ids": "5792" - }, - { - "examine": "It's a large crack in the wall.", - "ids": "5793,5794,5795,5796,5797,5798" - }, - { - "examine": "It's a trapdoor.", - "ids": "5799,5800,5801,5802" - }, - { - "examine": "It's an open trapdoor.", - "ids": "5803,5804,5805,5806,5807" - }, - { - "examine": "An incredibly detailed stone sculpture.", - "ids": "5808" - }, - { - "examine": "Helps the Seers predict the weather when it's working.", - "ids": "5809" - }, - { - "examine": "Helps the Seers predict the weather.", - "ids": "5810,5811" - }, - { - "examine": "I can climb this.", - "ids": "5812" - }, - { - "examine": "I can climb down this.", - "ids": "5813,5814" - }, - { - "examine": "A candle, a lens and some sort of crystal all precariously balanced together.", - "ids": "5815" - }, - { - "examine": "A beacon so gnome gliders can safely land.", - "ids": "5816,5817,5818,5819,5820,5821,5822,5823,5824" - }, - { - "examine": "Fly Gnome Air.", - "ids": "5825" - }, - { - "examine": "This shop deals in antique swords.", - "ids": "5826,5827,5828,5829,5830" - }, - { - "examine": "Shop counter.", - "ids": "5831,5832,5833,5834" - }, - { - "examine": "Don't want to close this, I might not be able to get back down.", - "ids": "5835,5836,5837,5838,5839,5840,5841" - }, - { - "examine": "It overlooks the path below. Let's hope it won't fall on your head.", - "ids": "5842" - }, - { - "examine": "Someone is climbing down there! Looks dangerous.", - "ids": "5843" - }, - { - "examine": "Placed in a perfect position for stumbling over.", - "ids": "5844" - }, - { - "examine": "There is a rope going over it.", - "ids": "5845" - }, - { - "examine": "Someone is climbing down the rope.", - "ids": "5846" - }, - { - "examine": "You will need to climb over it.", - "ids": "5847" - }, - { - "examine": "The tree stands tall at the edge of the pool.", - "ids": "5848" - }, - { - "examine": "You can't stand on them, but maybe something can be wedged into there.", - "ids": "5849" - }, - { - "examine": "Something put on top of this wouldn't fall off, it's quite smooth and flat.", - "ids": "5850,5851" - }, - { - "examine": "Someone put a plank on top of the stone! Clever...", - "ids": "5852,5853,5854" - }, - { - "examine": "The pool looks very peaceful. You can also hear faint singing coming from it.", - "ids": "5855" - }, - { - "examine": "The legendary White Pearl fruit is growing on these thorny bushes!", - "ids": "5856" - }, - { - "examine": "There's a nasty stench coming from the cave.", - "ids": "5857" - }, - { - "examine": "Faint rays of daylight shine through.", - "ids": "5858" - }, - { - "examine": "It's very dark down there.", - "ids": "5859" - }, - { - "examine": "Very pointy, very sharp.", - "ids": "5860,5861" - }, - { - "examine": "This is the place where you buried Asleif.", - "ids": "5862" - }, - { - "examine": "Asleif was given a proper burial on this spot.", - "ids": "5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876,5877" - }, - { - "examine": "It's a long wooden table.", - "ids": "5878" - }, - { - "examine": "Generally used for putting things on.", - "ids": "5879" - }, - { - "examine": "A crude torch stuck in the ground.", - "ids": "5881,5882" - }, - { - "examine": "Sticky, dirty mud.", - "ids": "5883" - }, - { - "examine": "This stinks...", - "ids": "5884" - }, - { - "examine": "The roots go down into the mud.", - "ids": "5885" - }, - { - "examine": "Sticky, dirty roots covered in sticky, dirty mud.", - "ids": "5886" - }, - { - "examine": "It's barely a door, really.", - "ids": "5887,5888,5889,5890" - }, - { - "examine": "The entry to a special tent in the camp.", - "ids": "5891,5892,5893,5894" - }, - { - "examine": "It's just a big stone, really.", - "ids": "5895" - }, - { - "examine": "Uh oh, someone is going to be in trouble!", - "ids": "5896" - }, - { - "examine": "The pool looks very peaceful. You can also hear faint singing coming from it.", - "ids": "5897,5898,5899,5900,5901" - }, - { - "examine": "It's only useful for hiding behind now.", - "ids": "5902,5903,5904" - }, - { - "examine": "This tree has been cut down.", - "ids": "5905,5906,5907,5908" - }, - { - "examine": "A still for making lamp oil.", - "ids": "5909" - }, - { - "examine": "The still has oil in.", - "ids": "5910,5911,5912,5913,5914,5915,5916" - }, - { - "examine": "Noxious fumes bubble up from the bowels of the earth.", - "ids": "5917,5918,5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945" - }, - { - "examine": "You see a circle of light at the top.", - "ids": "5946" - }, - { - "examine": "An entrance to the dark caves.", - "ids": "5947" - }, - { - "examine": "I can jump from this stepping stone.", - "ids": "5948,5949,5950,5951,5952,5953,5954,5955,5956,5957,5958" - }, - { - "examine": "I wonder what this does...", - "ids": "5959,5960,5961,5962,5963" - }, - { - "examine": "Flying in mid-air!", - "ids": "5964,5965" - }, - { - "examine": "A blocked passage.", - "ids": "5966" - }, - { - "examine": "I'd better leave his expensive dwarven balls alone.", - "ids": "5967,5968,5969,5970,5971,5972" - }, - { - "examine": "A small cave entrance.", - "ids": "5973,5974" - }, - { - "examine": "A powerful ranging device that fires metal balls.", - "ids": "5975,5976" - }, - { - "examine": "It's a sheer wall of fire, rising as high as you can see.", - "ids": "5977,5978,5979,5980" - }, - { - "examine": "Lighting for the caves.", - "ids": "5981,5982,5983,5984" - }, - { - "examine": "A rock.", - "ids": "5985" - }, - { - "examine": "A small rock.", - "ids": "5986" - }, - { - "examine": "A rock.", - "ids": "5987,5988" - }, - { - "examine": "A mineral vein that looks distinctly like gold.", - "ids": "5989,5990,5991,5992,5993,5994,5995,5996,5997" - }, - { - "examine": "Functions like an open door...", - "ids": "5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008" - }, - { - "examine": "It's a tiny little blue flame. Is this the essence of the Arzinian Being?", - "ids": "6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031" - }, - { - "examine": "Powers the boat.", - "ids": "6032,6033,6034,6035" - }, - { - "examine": "Allows access to other parts of the ship.", - "ids": "6036,6037" - }, - { - "examine": "Without this I'm going around in circles.", - "ids": "6038,6039,6040,6041,6042" - }, - { - "examine": "Powers the boat.", - "ids": "6043,6044" - }, - { - "examine": "You can 'cart' things around on this.", - "ids": "6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063" - }, - { - "examine": "A stand for hats.", - "ids": "6064" - }, - { - "examine": "Some dwarf clothes that are obviously too small for me!", - "ids": "6065" - }, - { - "examine": "An empty weapon rack.", - "ids": "6066" - }, - { - "examine": "A weapon rack.", - "ids": "6067,6068,6069" - }, - { - "examine": "A method of dwarf storage", - "ids": "6070" - }, - { - "examine": "A method of dwarf storage.", - "ids": "6071,6072,6073,6074" - }, - { - "examine": "Useful for a dwarf.", - "ids": "6075" - }, - { - "examine": "A big desk, for a dwarf!", - "ids": "6076,6077,6078,6079" - }, - { - "examine": "Spins yarn.", - "ids": "6080" - }, - { - "examine": "Banking transactions are processed here.", - "ids": "6081" - }, - { - "examine": "Banking transactions are recorded here.", - "ids": "6082,37159" - }, - { - "examine": "This booth is closed.", - "ids": "6083" - }, - { - "examine": "The bank teller will serve you from here.", - "ids": "6084" - }, - { - "examine": "A way upwards.", - "ids": "6085" - }, - { - "examine": "A way down.", - "ids": "6086" - }, - { - "examine": "A way upwards.", - "ids": "6087" - }, - { - "examine": "A way down.", - "ids": "6088" - }, - { - "examine": "A way upwards.", - "ids": "6089" - }, - { - "examine": "A way down.", - "ids": "6090" - }, - { - "examine": "A treasure trove of knowledge.", - "ids": "6091,6092" - }, - { - "examine": "A lovely place to cook meat.", - "ids": "6093,6094,6095" - }, - { - "examine": "A great place to cook meat.", - "ids": "6096" - }, - { - "examine": "A good source of water.", - "ids": "6097,6098,6099" - }, - { - "examine": "The door is closed.", - "ids": "6100" - }, - { - "examine": "The door is open.", - "ids": "6101" - }, - { - "examine": "The door is closed.", - "ids": "6102" - }, - { - "examine": "The door is open.", - "ids": "6103" - }, - { - "examine": "The door is closed.", - "ids": "6104" - }, - { - "examine": "The door is open.", - "ids": "6105" - }, - { - "examine": "The door is closed.", - "ids": "6106" - }, - { - "examine": "The door is open.", - "ids": "6107" - }, - { - "examine": "The door is closed.", - "ids": "6108" - }, - { - "examine": "The door is open.", - "ids": "6109" - }, - { - "examine": "The door is closed.", - "ids": "6110" - }, - { - "examine": "The door is open.", - "ids": "6111" - }, - { - "examine": "The door is closed.", - "ids": "6112" - }, - { - "examine": "The door is open.", - "ids": "6113" - }, - { - "examine": "The door is closed.", - "ids": "6114" - }, - { - "examine": "The door is open.", - "ids": "6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145" - }, - { - "examine": "Useful for keeping birds.", - "ids": "6146" - }, - { - "examine": "Tower of rock.", - "ids": "6147,6148,6149" - }, - { - "examine": "Useful for making weapons.", - "ids": "6150" - }, - { - "examine": "Used for getting water.", - "ids": "6151" - }, - { - "examine": "Used for getting drunk.", - "ids": "6152,6153" - }, - { - "examine": "Used for storage.", - "ids": "6154,6155,6156,6157" - }, - { - "examine": "Not good for eating.", - "ids": "6158,6159,6160,6161" - }, - { - "examine": "Finest precious stones.", - "ids": "6162" - }, - { - "examine": "Bread and cakes are spread out over it.", - "ids": "6163" - }, - { - "examine": "Finely wrought wares of silver.", - "ids": "6164" - }, - { - "examine": "I can get clothes made up from this stall.", - "ids": "6165" - }, - { - "examine": "A whole lot of tools for crafting.", - "ids": "6166,6167,6168,6169,6170,6171,6172" - }, - { - "examine": "A fine piece of sculpting.", - "ids": "6173,6174,6175" - }, - { - "examine": "Oblong boxes. You hope there isn't anything other than salt inside.", - "ids": "6176" - }, - { - "examine": "Big mysterious crates. You wonder what could be inside.", - "ids": "6177" - }, - { - "examine": "Wooden crates, contents unknown.", - "ids": "6178" - }, - { - "examine": "They could do with a wash.", - "ids": "6179,6180" - }, - { - "examine": "Dead animal parts dangling!", - "ids": "6181" - }, - { - "examine": "Dead meat. Dangling from the wall. Looks delicious.", - "ids": "6182" - }, - { - "examine": "It looks as hard as a rock, not very inviting.", - "ids": "6183" - }, - { - "examine": "A smelly old mattress.", - "ids": "6184" - }, - { - "examine": "Metal plating to protect the dwarf.", - "ids": "6185,6186" - }, - { - "examine": "Useful... for a dwarf!", - "ids": "6187" - }, - { - "examine": "Various implements for working with metal.", - "ids": "6188" - }, - { - "examine": "A hot place for forging things in.", - "ids": "6189,6190" - }, - { - "examine": "Being repaired.", - "ids": "6191,6192" - }, - { - "examine": "I look shorter, but not necessarily sweeter!", - "ids": "6193" - }, - { - "examine": "Used for sitting.", - "ids": "6194,6195" - }, - { - "examine": "Useful for a dwarf.", - "ids": "6196,6197,6198,6199" - }, - { - "examine": "Fit for a dwarven feast!", - "ids": "6200,6201" - }, - { - "examine": "Gives out light, but then you knew that already.", - "ids": "6202,6203" - }, - { - "examine": "A simple place to sleep.", - "ids": "6204" - }, - { - "examine": "A good dwarven bed. Too small for me!", - "ids": "6205" - }, - { - "examine": "Many important meetings are held here...", - "ids": "6206" - }, - { - "examine": "Draped in cloth.", - "ids": "6207" - }, - { - "examine": "A beautiful seat, fit for a King.", - "ids": "6208,6209,6210" - }, - { - "examine": "A dwarf table with chopping board.", - "ids": "6211" - }, - { - "examine": "This tree has been cut down.", - "ids": "6212" - }, - { - "examine": "A barrel full of ranging equipment...", - "ids": "6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229" - }, - { - "examine": "I suppose he wants my money.", - "ids": "6230" - }, - { - "examine": "A lovely table.", - "ids": "6231" - }, - { - "examine": "An expensive water feature.", - "ids": "6232,6233,6234,6235" - }, - { - "examine": "Stop for what, food?", - "ids": "6236" - }, - { - "examine": "Yellow blossom, lovely.", - "ids": "6237" - }, - { - "examine": "Closed.", - "ids": "6238" - }, - { - "examine": "Open.", - "ids": "6239" - }, - { - "examine": "Closed.", - "ids": "6240" - }, - { - "examine": "Open.", - "ids": "6241" - }, - { - "examine": "A stone staircase.", - "ids": "6242,6243,6244,6245" - }, - { - "examine": "Has upon it a beer, which I will not take for moral reasons.", - "ids": "6246,6247,6248" - }, - { - "examine": "No this is not a mirage!", - "ids": "6249" - }, - { - "examine": "It's a goldfish! No, wait, it's just a bed.", - "ids": "6250,6251,6252,6253,6254" - }, - { - "examine": "Animal feeder.", - "ids": "6255,6256" - }, - { - "examine": "Lovely... Fresh.", - "ids": "6257" - }, - { - "examine": "Dry dung.", - "ids": "6258" - }, - { - "examine": "Smelly.", - "ids": "6259" - }, - { - "examine": "I can climb down this.", - "ids": "6260" - }, - { - "examine": "I can climb this.", - "ids": "6261,6262" - }, - { - "examine": "Useful for pets.", - "ids": "6263" - }, - { - "examine": "Useful for keeping birds.", - "ids": "6264" - }, - { - "examine": "Bird cage.", - "ids": "6265,6266" - }, - { - "examine": "An empty cage, maybe the owner let the creature free... I do hope so.", - "ids": "6267" - }, - { - "examine": "Useful for pets.", - "ids": "6268,6269,6270,6271,6272,6273" - }, - { - "examine": "Lovely comfy looking big bed.", - "ids": "6274" - }, - { - "examine": "Laden with heaps of paper.", - "ids": "6275" - }, - { - "examine": "I don't know much about art, but I like this.", - "ids": "6276" - }, - { - "examine": "Look at the size of this cactus.", - "ids": "6277" - }, - { - "examine": "Don't you open that trapdoor!", - "ids": "6278" - }, - { - "examine": "There is a rope leading to the bottom of this smoke filled well.", - "ids": "6279" - }, - { - "examine": "I can climb this.", - "ids": "6280,6281" - }, - { - "examine": "A portal to another land?", - "ids": "6282" - }, - { - "examine": "Weird looking pillar.", - "ids": "6283,6284,6285,6286,6287,6288,6289,6290,6291" - }, - { - "examine": "Shelves filled with interesting books.", - "ids": "6292,6293" - }, - { - "examine": "A locked display case for valuable artefacts.", - "ids": "6294" - }, - { - "examine": "One of the sculptures is missing. Oh yes, that was me!", - "ids": "6295" - }, - { - "examine": "It looks like the demon didn't survive after all.", - "ids": "6296" - }, - { - "examine": "He looks old, older than me anyway.", - "ids": "6297" - }, - { - "examine": "I don't think he's going to make it.", - "ids": "6298" - }, - { - "examine": "I don't understand, why didn't he go back to Lumby?", - "ids": "6299,6300" - }, - { - "examine": "A throne encrusted with sparkling gems.", - "ids": "6301" - }, - { - "examine": "A throne from which you have removed the gems.", - "ids": "6302,6303,6304,6305,6306" - }, - { - "examine": "A statuette of a golem, facing right.", - "ids": "6307" - }, - { - "examine": "A statuette of a golem, facing left.", - "ids": "6308" - }, - { - "examine": "The statuette is missing from this alcove.", - "ids": "6309,6310" - }, - { - "examine": "Not good for eating.", - "ids": "6311" - }, - { - "examine": "I can climb this.", - "ids": "6312" - }, - { - "examine": "I can climb down this.", - "ids": "6313,6314,6315,6316,6317,6318,6319,6320,6321,6322" - }, - { - "examine": "A broken clay arm.", - "ids": "6323" - }, - { - "examine": "A clay foot.", - "ids": "6324" - }, - { - "examine": "Half a golem smashed and broken.", - "ids": "6325" - }, - { - "examine": "Smashed and half buried.", - "ids": "6326" - }, - { - "examine": "A device once used for making pottery.", - "ids": "6327" - }, - { - "examine": "Once upon a time this was used to make pottery.", - "ids": "6328" - }, - { - "examine": "Once upon a time this made clay hard.", - "ids": "6329" - }, - { - "examine": "There was a lot of pottery made here a long time ago.", - "ids": "6330" - }, - { - "examine": "A statue of a guy with a hammer.", - "ids": "6331" - }, - { - "examine": "A weathered old statue.", - "ids": "6332" - }, - { - "examine": "A reclining lady.", - "ids": "6333" - }, - { - "examine": "This statue has been tampered with.", - "ids": "6334" - }, - { - "examine": "Contains a statue of a woman.", - "ids": "6335,6336,6337" - }, - { - "examine": "Empty.", - "ids": "6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362" - }, - { - "examine": "A very heavy stone door.", - "ids": "6363" - }, - { - "examine": "A door to a demon's lair?", - "ids": "6364,6365,6366,6367,6368,6369,6370,6371" - }, - { - "examine": "A stone staircase.", - "ids": "6372,6373,6374,6375,6376,6377,6378,6379,6380" - }, - { - "examine": "A source of water for the river Elid.", - "ids": "6381" - }, - { - "examine": "Maybe I could swing on this somehow...", - "ids": "6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,6399,6400,6401" - }, - { - "examine": "A limestone ceiling growth.", - "ids": "6402" - }, - { - "examine": "A tooth shaped rock formation protruding from the floor.", - "ids": "6403" - }, - { - "examine": "An old mystical torch.", - "ids": "6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417" - }, - { - "examine": "I can climb this.", - "ids": "6418,6419" - }, - { - "examine": "I wonder what's inside?", - "ids": "6420,6421,6422" - }, - { - "examine": "A magical aura seems to shimmer over the glass...", - "ids": "6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433" - }, - { - "examine": "I wonder what that's there for...", - "ids": "6434,6435" - }, - { - "examine": "I can climb this.", - "ids": "6436" - }, - { - "examine": "An ancient looking tomb.", - "ids": "6437,6438" - }, - { - "examine": "Climb this rope to go up.", - "ids": "6439,6440" - }, - { - "examine": "Looks like a small cave.", - "ids": "6441" - }, - { - "examine": "Blocked by an icicle.", - "ids": "6442" - }, - { - "examine": "Blocked by two icicles.", - "ids": "6443" - }, - { - "examine": "Blocked by three icicles.", - "ids": "6444" - }, - { - "examine": "Blocked by four icicles.", - "ids": "6445" - }, - { - "examine": "Blocked by five icicles.", - "ids": "6446" - }, - { - "examine": "Looks like a small cave.", - "ids": "6447" - }, - { - "examine": "It looks very sturdy.", - "ids": "6448,6449" - }, - { - "examine": "I can climb this.", - "ids": "6450" - }, - { - "examine": "A wrought iron gate.", - "ids": "6451,6452,6453" - }, - { - "examine": "Even rocks could freeze in this cold!", - "ids": "6454" - }, - { - "examine": "Looks slippery.", - "ids": "6455,6456,6457,6458,6459,6460" - }, - { - "examine": "An ice gate.", - "ids": "6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471" - }, - { - "examine": "Chunky pieces of ice.", - "ids": "6472,6473,6474,6475,6476,6477,6478,6479,6480" - }, - { - "examine": "A mysterious tunnel-like structure.", - "ids": "6481,6482" - }, - { - "examine": "You can feel a mysterious power emanating from it...", - "ids": "6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493" - }, - { - "examine": "This door is sealed by an ancient mystical power...", - "ids": "6494,6495,6496" - }, - { - "examine": "I can climb down this.", - "ids": "6497,6498,6499,6500" - }, - { - "examine": "I can climb this.", - "ids": "6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511" - }, - { - "examine": "A fancy name for a coffin.", - "ids": "6512" - }, - { - "examine": "A strange thing to leave lying around...", - "ids": "6513" - }, - { - "examine": "I hope this is just ornamental...", - "ids": "6514,6515,6516,6517,6518,6519,6520" - }, - { - "examine": "Uh-oh!", - "ids": "6521,6522" - }, - { - "examine": "This leads downwards.", - "ids": "6523" - }, - { - "examine": "You can see a small fissure in the ground here.", - "ids": "6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537" - }, - { - "examine": "The body of a lion, the head of a man?", - "ids": "6538,6539,6540,6541,6542,6543,6544" - }, - { - "examine": "A smooth, sandstone door that is slightly warm to the touch.", - "ids": "6545,6546,6547,6548" - }, - { - "examine": "A well down into the pyramid.", - "ids": "6549,6550" - }, - { - "examine": "A portal that leads you out of the pyramid.", - "ids": "6551" - }, - { - "examine": "A mysterious ancient altar to some forgotten god...", - "ids": "6552" - }, - { - "examine": "Opens into another area.", - "ids": "6553,6554,6555,6556,6557,6558,6559,6560" - }, - { - "examine": "A ladder that's almost not there at all...", - "ids": "6561,6562,6563,6564,6565" - }, - { - "examine": "Gate like?", - "ids": "6566,6567" - }, - { - "examine": "Garments for the discerning.", - "ids": "6568" - }, - { - "examine": "Gone-off bread, cakes and pastries.", - "ids": "6569" - }, - { - "examine": "Finest precious stones.", - "ids": "6570" - }, - { - "examine": "These will keep you warm.", - "ids": "6571" - }, - { - "examine": "The spice is right.", - "ids": "6572" - }, - { - "examine": "An empty market stall.", - "ids": "6573" - }, - { - "examine": "Fine brews from exotic regions.", - "ids": "6574" - }, - { - "examine": "Best used with a horse.", - "ids": "6575,6576,6577" - }, - { - "examine": "Grows a yellow fruit.", - "ids": "6578,6579,6580" - }, - { - "examine": "A way to get in the tent.", - "ids": "6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604" - }, - { - "examine": "Wet and salty.", - "ids": "6605" - }, - { - "examine": "The focus of the suntrap.", - "ids": "6606" - }, - { - "examine": "A shiny mirror.", - "ids": "6607,6608,6609,6610,6611,6612,6613" - }, - { - "examine": "A large door with a hieroglyph of a cat.", - "ids": "6614" - }, - { - "examine": "Gate like?", - "ids": "6615,6616,6617,6618,6619" - }, - { - "examine": "It looks like a hole in the wall.", - "ids": "6620,6621" - }, - { - "examine": "Rocky.", - "ids": "6622" - }, - { - "examine": "An entrance into a tunnel. I wonder where it leads to.", - "ids": "6623" - }, - { - "examine": "It looks like a door.", - "ids": "6624" - }, - { - "examine": "Hmm. A door.", - "ids": "6625" - }, - { - "examine": "A big wooden door.", - "ids": "6626,6627,6628" - }, - { - "examine": "That could hurt.", - "ids": "6629" - }, - { - "examine": "A strange thing to leave lying around...", - "ids": "6630,6631" - }, - { - "examine": "I can't see the bottom.", - "ids": "6632,6633,6634" - }, - { - "examine": "Has a lid shaped like a man. I think it contains someone's liver. Yuck.", - "ids": "6635,6636" - }, - { - "examine": "Has a lid shaped like a crocodile. Yuck, I think there are lungs inside.", - "ids": "6637,6638" - }, - { - "examine": "Has a lid shaped like a bug. Disgusting! I think there's a stomach inside.", - "ids": "6639,6640" - }, - { - "examine": "Has a lid shaped like an ape. Eeew! I think it contains someone's intestines.", - "ids": "6641" - }, - { - "examine": "Doorway*Opens into another area, come on, I know this.", - "ids": "6642" - }, - { - "examine": "Useful for putting things on.", - "ids": "6644" - }, - { - "examine": "A ladder!! Never seen one of those before.", - "ids": "6645" - }, - { - "examine": "I wonder what's inside.", - "ids": "6646" - }, - { - "examine": "Perhaps I should search it.", - "ids": "6647" - }, - { - "examine": "I wonder where this goes?", - "ids": "6648" - }, - { - "examine": "They go down.", - "ids": "6649" - }, - { - "examine": "Phew!! That's one big bridge.", - "ids": "6650" - }, - { - "examine": "A big bridge over the river.", - "ids": "6651,6652" - }, - { - "examine": "Wow. More bridge. Awesome.", - "ids": "6653,6654" - }, - { - "examine": "Oops.", - "ids": "6655" - }, - { - "examine": "Rolls of colourful cloth.", - "ids": "6656" - }, - { - "examine": "An ancient giant serpent.", - "ids": "6657" - }, - { - "examine": "A tunnel leading upwards.", - "ids": "6658" - }, - { - "examine": "A tunnel leading into the depths of the earth.", - "ids": "6659" - }, - { - "examine": "A rock wall infused with the power of Guthix.", - "ids": "6660" - }, - { - "examine": "The wall is weeping blue tears.", - "ids": "6661" - }, - { - "examine": "The wall is weeping green tears.", - "ids": "6662" - }, - { - "examine": "The wall is not weeping at the moment.", - "ids": "6663,6664" - }, - { - "examine": "The wall is weeping blue tears.", - "ids": "6665" - }, - { - "examine": "The wall is weeping green tears.", - "ids": "6666" - }, - { - "examine": "The wall is not weeping at the moment.", - "ids": "6667,6668" - }, - { - "examine": "Stone with blue veins.", - "ids": "6669,6670,6671" - }, - { - "examine": "They don't look too easy to climb.", - "ids": "6672" - }, - { - "examine": "I could climb these.", - "ids": "6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701" - }, - { - "examine": "I can climb these stairs.", - "ids": "6702,6703,6704,6705,6706,6707" - }, - { - "examine": "I can climb this.", - "ids": "6708,6709,6710,6711,6712" - }, - { - "examine": "I wonder what is awaiting me on the other side?", - "ids": "6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731" - }, - { - "examine": "I wonder what awaits me on the other side?", - "ids": "6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766" - }, - { - "examine": "A crude torch stuck in the ground.", - "ids": "6767,6768,6769,6770" - }, - { - "examine": "A large stone coffin.", - "ids": "6771,6772,6773" - }, - { - "examine": "A large stone chest.", - "ids": "6774,6775" - }, - { - "examine": "Looks like he's been dead a while now...", - "ids": "6776" - }, - { - "examine": "I don't think he'd mind us checking for his wallet now...", - "ids": "6777" - }, - { - "examine": "I'm sure he died of natural causes. Like a massive dragon or something...", - "ids": "6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790" - }, - { - "examine": "The groundskeeper's bed.", - "ids": "6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820" - }, - { - "examine": "A large stone coffin.", - "ids": "6821,6822,6823" - }, - { - "examine": "It's locked.", - "ids": "6824,6825,6826" - }, - { - "examine": "It might still work...", - "ids": "6827,6828,6829,6830,6831,6832,6833,6834" - }, - { - "examine": "Danger... weak surface beyond gate. Digging may lead to cave-ins.", - "ids": "6835" - }, - { - "examine": "Sturdy metal bars.", - "ids": "6836,6837,6838" - }, - { - "examine": "Smells pretty bad!", - "ids": "6839" - }, - { - "examine": "It looks as this is where some wall fungus used to be.", - "ids": "6840" - }, - { - "examine": "Some crude stone steps.", - "ids": "6841,6842,6843" - }, - { - "examine": "An old crude tomb.", - "ids": "6844,6845" - }, - { - "examine": "It's damaged.", - "ids": "6846" - }, - { - "examine": "A note says, 'Please ring for attention.'", - "ids": "6847" - }, - { - "examine": "An old crude tomb.", - "ids": "6848" - }, - { - "examine": "'Leave da dead-uns boxes 'lone or else ya goes down da 'ole'", - "ids": "6849" - }, - { - "examine": "An old crude tomb.", - "ids": "6850" - }, - { - "examine": "This coffin is spilt over the floor.", - "ids": "6851" - }, - { - "examine": "This coffin is open.", - "ids": "6852" - }, - { - "examine": "An old crude tomb.", - "ids": "6853" - }, - { - "examine": "This coffin is spilt over the floor.", - "ids": "6854" - }, - { - "examine": "This coffin is open.", - "ids": "6855" - }, - { - "examine": "A barricade made from skulls and bones.", - "ids": "6856,6857,6858,6859,6860,6861,6862,6863,6864" - }, - { - "examine": "Not very high.", - "ids": "6865" - }, - { - "examine": "Hot stuff.", - "ids": "6866" - }, - { - "examine": "Ogres bang these to make noise.", - "ids": "6867,6868,6869,6870" - }, - { - "examine": "A bulky door made from solid rock.", - "ids": "6871,6872,6873,6874" - }, - { - "examine": "These open and close!", - "ids": "6875" - }, - { - "examine": "This may be worth opening.", - "ids": "6876" - }, - { - "examine": "I wonder what this item contains.", - "ids": "6877,6878,6879" - }, - { - "examine": "A barricade made of skulls and bones.", - "ids": "6880" - }, - { - "examine": "A barricade made of skulls and bones which has been crushed.", - "ids": "6881,6882" - }, - { - "examine": "An old crude tomb.", - "ids": "6883,6884,6885,6886,6887" - }, - { - "examine": "A sick, frail old man.", - "ids": "6888" - }, - { - "examine": "A sick, frail old man", - "ids": "6889" - }, - { - "examine": "An old crude tomb.", - "ids": "6890,6891,6892" - }, - { - "examine": "I don't think he'd mind us checking for his wallet now...", - "ids": "6893" - }, - { - "examine": "A good source of books!", - "ids": "6894,6895" - }, - { - "examine": "A crude torch stuck in the ground.", - "ids": "6896" - }, - { - "examine": "A strange ogre plinth, this must be where the artifacts are stored.", - "ids": "6897,6898,6899,6900,6901,6902" - }, - { - "examine": "It looks like the hole in the wall has been blocked with rubble.", - "ids": "6903" - }, - { - "examine": "How exciting, some shelves.", - "ids": "6904" - }, - { - "examine": "A hole in the wall.", - "ids": "6905,6906,6907,6908" - }, - { - "examine": "A rock wall.", - "ids": "6909" - }, - { - "examine": "It has a letter 'S' on the lock.", - "ids": "6910" - }, - { - "examine": "Used for storage.", - "ids": "6911" - }, - { - "examine": "A narrow hole in the wall.", - "ids": "6912,6913,6914" - }, - { - "examine": "Rubble is blocking the passage.", - "ids": "6915" - }, - { - "examine": "A good source of books!", - "ids": "6916,6917,6918" - }, - { - "examine": "A heavy portal decorated with bone.", - "ids": "6919,6920" - }, - { - "examine": "A symbol is carved into the wall here.", - "ids": "6921,6922,6923,6924,6925,6926" - }, - { - "examine": "I don't think I can get through this way!", - "ids": "6927" - }, - { - "examine": "Looks like its no longer operational.", - "ids": "6928" - }, - { - "examine": "Big bones are being used to prop up the wall.", - "ids": "6929,6930" - }, - { - "examine": "It's a bit like walking through a giant rib cage.", - "ids": "6931,6932,6933,6934,6935,6936,6937,6938" - }, - { - "examine": "This arch is broken. I hope the ceiling doesn't come down!", - "ids": "6939,6940,6941,6942" - }, - { - "examine": "A rocky outcrop.", - "ids": "6943,6944,6945,6946,6947,6948,6949" - }, - { - "examine": "I dont think i can get through this way.", - "ids": "6950" - }, - { - "examine": "An eye-wrenching nexus of utter negation!", - "ids": "6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968" - }, - { - "examine": "A dirty little swamp boat.", - "ids": "6969,6970" - }, - { - "examine": "It looks dark down there.", - "ids": "6971" - }, - { - "examine": "A book sits on top.", - "ids": "6972,6973,6974" - }, - { - "examine": "The door is closed.", - "ids": "6975" - }, - { - "examine": "The door is open.", - "ids": "6976" - }, - { - "examine": "The door is closed.", - "ids": "6977" - }, - { - "examine": "The door is open.", - "ids": "6978,6979,6980,6981,6982,6983" - }, - { - "examine": "Empty market stall.", - "ids": "6984" - }, - { - "examine": "A steam powered crushing machine.", - "ids": "6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001" - }, - { - "examine": "A dwarven statue crumbling away from old age.", - "ids": "7002" - }, - { - "examine": "It's crumbling away from old age, it's hardly recognizable as a dwarf.", - "ids": "7003" - }, - { - "examine": "This stone dwarf must be guarding the way into a dwarven area!", - "ids": "7004,7005" - }, - { - "examine": "Big. For a dwarf!", - "ids": "7006,7007" - }, - { - "examine": "A work in progress.", - "ids": "7008,7009" - }, - { - "examine": "A work that has yet to begin.", - "ids": "7010" - }, - { - "examine": "An underground limpwurt plant.", - "ids": "7011,7012" - }, - { - "examine": "Insect eating plant.", - "ids": "7013,7014,7015" - }, - { - "examine": "A stone carved Pillar.", - "ids": "7016,7017" - }, - { - "examine": "Dwarf storage.", - "ids": "7018" - }, - { - "examine": "Used for keeping beer or glasses.", - "ids": "7019,7020,7021" - }, - { - "examine": "Tracks for the carts to run over.", - "ids": "7022,7023,7024,7025,7026" - }, - { - "examine": "A steam powered cart.", - "ids": "7027,7028,7029,7030,7031" - }, - { - "examine": "A fine piece of sculpting.", - "ids": "7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043" - }, - { - "examine": "Keeps mine carts from rolling away.", - "ids": "7044,7045,7046,7047,7048" - }, - { - "examine": "A wooden gate.", - "ids": "7049,7050,7051,7052" - }, - { - "examine": "Lots of seeds here.", - "ids": "7053,7054,7055" - }, - { - "examine": "I can climb down these stairs.", - "ids": "7056" - }, - { - "examine": "I can climb up these stairs.", - "ids": "7057" - }, - { - "examine": "Filled to the brim with knowledge.", - "ids": "7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089" - }, - { - "examine": "'You are here.'", - "ids": "7090" - }, - { - "examine": "Lots of hard study has been done here.", - "ids": "7091" - }, - { - "examine": "A telescope pointing southwards...", - "ids": "7092,7093,7094,7095" - }, - { - "examine": "A map of some ancient land.", - "ids": "7096" - }, - { - "examine": "There are plenty of shelves", - "ids": "7097" - }, - { - "examine": "Maybe it shows the location of buried treasure?", - "ids": "7098" - }, - { - "examine": "Old songs, old stories...", - "ids": "7099" - }, - { - "examine": "Armour of a Saradominist warrior. Decorative, but still effective.", - "ids": "7100" - }, - { - "examine": "A cape from Saradomin, suitable for a battle-mage.", - "ids": "7101" - }, - { - "examine": "A staff as used by Saradominist magi.", - "ids": "7102" - }, - { - "examine": "There is a powerful presence about these ruins...", - "ids": "7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128" - }, - { - "examine": "A tear in the dimensional weave of the Abyss.", - "ids": "7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153" - }, - { - "examine": "A tunnel through the abyss.", - "ids": "7154,7155" - }, - { - "examine": "This seems to be blocking the exit...", - "ids": "7156,7157" - }, - { - "examine": "I could probably break this up with a pickaxe.", - "ids": "7158" - }, - { - "examine": "I could probably break this up with a pickaxe. Oh wait, I just did.", - "ids": "7159" - }, - { - "examine": "Pickaxe power!", - "ids": "7160" - }, - { - "examine": "They don't look that solid, an axe could help me chop them down.", - "ids": "7161,7162" - }, - { - "examine": "I cannot tell a lie. I chopped them down.", - "ids": "7163" - }, - { - "examine": "If I'm agile enough I might be able to squeeze through...", - "ids": "7164" - }, - { - "examine": "I could probably burn this away with a tinderbox.", - "ids": "7165" - }, - { - "examine": "I could probably burn this with fire.", - "ids": "7166" - }, - { - "examine": "Burnt open.", - "ids": "7167" - }, - { - "examine": "I could probably distract these with thievery.", - "ids": "7168,7169,7170" - }, - { - "examine": "An unstable portal across the dimensions...", - "ids": "7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188" - }, - { - "examine": "Abyssal Tendrils.", - "ids": "7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205" - }, - { - "examine": "An opening into the crumbling wall.", - "ids": "7219,7220" - }, - { - "examine": "This leads downwards.", - "ids": "7221" - }, - { - "examine": "This way to the viewing gallery.", - "ids": "7222,7223" - }, - { - "examine": "I'll never be able to dodge that!", - "ids": "7224" - }, - { - "examine": "It's a wall...", - "ids": "7225,7226" - }, - { - "examine": "It's the floor...", - "ids": "7227" - }, - { - "examine": "It's a wall...", - "ids": "7228,7229" - }, - { - "examine": "It's the floor...", - "ids": "7230" - }, - { - "examine": "Not your average door...", - "ids": "7231,7232,7233,7234,7235" - }, - { - "examine": "I wonder what's inside.", - "ids": "7236,7237,7238" - }, - { - "examine": "It's a long way down...", - "ids": "7239,7240" - }, - { - "examine": "That's going to hurt if it hits me!", - "ids": "7241" - }, - { - "examine": "If only I knew Karate...", - "ids": "7242,7243,7244" - }, - { - "examine": "It's the floor...", - "ids": "7245" - }, - { - "examine": "Locked.", - "ids": "7246,7247" - }, - { - "examine": "It's a wall...", - "ids": "7248,7249" - }, - { - "examine": "It's the floor...", - "ids": "7250" - }, - { - "examine": "Bend your way through.", - "ids": "7251" - }, - { - "examine": "That could really hurt!", - "ids": "7252" - }, - { - "examine": "I must not fear, fear is the little death that brings total oblivion.", - "ids": "7253" - }, - { - "examine": "Blocking my way back.", - "ids": "7254,7255,7256" - }, - { - "examine": "I wonder where it leads.", - "ids": "7257" - }, - { - "examine": "An opening into the crumbling wall.", - "ids": "7258" - }, - { - "examine": "This way to exit.", - "ids": "7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271" - }, - { - "examine": "A mystical teleport.", - "ids": "7272,7273" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7274,7275,7276" - }, - { - "examine": "He looks hungry, but I don't think he'll do anything while I'm here.", - "ids": "7277" - }, - { - "examine": "He's no longer looks hungry, although perhaps a little guilty-looking.", - "ids": "7278,7279,7280" - }, - { - "examine": "He's looking at the grain...", - "ids": "7281,7282,7283" - }, - { - "examine": "A sack full of grain.", - "ids": "7284" - }, - { - "examine": "I think the chicken enjoyed his meal...", - "ids": "7285" - }, - { - "examine": "It looks pretty rickety...", - "ids": "7286,7287" - }, - { - "examine": "A mystical teleport.", - "ids": "7288,7289,7290,7291,7292,7293,7294,7295,7296,7297,7298,7299,7300,7301" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7302" - }, - { - "examine": "A gold statue of a famous White Knight.", - "ids": "7303" - }, - { - "examine": "A silver statue of a famous White Knight.", - "ids": "7304" - }, - { - "examine": "A bronze statue of a famous White Knight.", - "ids": "7305" - }, - { - "examine": "A gold statue of an ancient warrior.", - "ids": "7306" - }, - { - "examine": "A silver statue of an ancient warrior.", - "ids": "7307" - }, - { - "examine": "A bronze statue of an ancient warrior.", - "ids": "7308" - }, - { - "examine": "A gold statue of a famous warrior.", - "ids": "7309" - }, - { - "examine": "A silver statue of a famous warrior.", - "ids": "7310" - }, - { - "examine": "A bronze statue of a famous warrior.", - "ids": "7311" - }, - { - "examine": "A gold statue of an ancient White Knight.", - "ids": "7312" - }, - { - "examine": "A silver statue of an ancient White Knight.", - "ids": "7313" - }, - { - "examine": "A bronze statue of an ancient White Knight.", - "ids": "7314" - }, - { - "examine": "A mystical teleport.", - "ids": "7315,7316" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7317" - }, - { - "examine": "A mystical teleport.", - "ids": "7318,7319" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7320" - }, - { - "examine": "A mystical teleport.", - "ids": "7321,7322" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7323" - }, - { - "examine": "A mystical teleport.", - "ids": "7324,7325" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7326" - }, - { - "examine": "Filled to the brim with knowledge.", - "ids": "7327,7328,7329,7330" - }, - { - "examine": "Generally used for putting things on.", - "ids": "7331" - }, - { - "examine": "A table with a Bunsen burner on it.", - "ids": "7332" - }, - { - "examine": "There are some containers of chemicals here.", - "ids": "7333,7334,7335,7336,7337,7338,7339" - }, - { - "examine": "There's an empty vial here.", - "ids": "7340,7341,7342" - }, - { - "examine": "There's a small hole in the centre.", - "ids": "7343" - }, - { - "examine": "The spade is stuck in the hole.", - "ids": "7344" - }, - { - "examine": "The spade opened the door.", - "ids": "7345" - }, - { - "examine": "It's chained to the wall.", - "ids": "7346" - }, - { - "examine": "For storage.", - "ids": "7347,7348,7349" - }, - { - "examine": "I wonder what's inside.", - "ids": "7350" - }, - { - "examine": "Perhaps I should search it.", - "ids": "7351" - }, - { - "examine": "A mystical teleport.", - "ids": "7352,7353" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7354" - }, - { - "examine": "Bridge will support a person carrying no more than 5 kg.", - "ids": "7355,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372" - }, - { - "examine": "Lets me walk through walls...", - "ids": "7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384" - }, - { - "examine": "Sit back and relax...", - "ids": "7388,7389" - }, - { - "examine": "Designed specifically to ruin your health.", - "ids": "7390" - }, - { - "examine": "A rolled up magic carpet.", - "ids": "7391" - }, - { - "examine": "A pile of rolled up magic carpets.", - "ids": "7392" - }, - { - "examine": "A little shaded area.", - "ids": "7393" - }, - { - "examine": "A magic carpet.", - "ids": "7394,7395" - }, - { - "examine": "The infamous carpet of '76.", - "ids": "7396" - }, - { - "examine": "A leafy tree.", - "ids": "7397,7398" - }, - { - "examine": "This is what is left of a willow tree.", - "ids": "7399" - }, - { - "examine": "This is what is left of a maple tree.", - "ids": "7400" - }, - { - "examine": "This is what is left of a magic tree.", - "ids": "7401" - }, - { - "examine": "This is what is left of a yew tree.", - "ids": "7402" - }, - { - "examine": "An empty barrel.", - "ids": "7403" - }, - { - "examine": "A barrel full of mushed apples.", - "ids": "7404,7405" - }, - { - "examine": "This tap runs from the apple crushing barrel.", - "ids": "7406" - }, - { - "examine": "An empty ale barrel.", - "ids": "7407" - }, - { - "examine": "A barrel of bad ale.", - "ids": "7408" - }, - { - "examine": "A barrel of unfermented liquid.", - "ids": "7409" - }, - { - "examine": "A barrel of bad cider.", - "ids": "7410" - }, - { - "examine": "A barrel of Dwarven Stout.", - "ids": "7411" - }, - { - "examine": "A barrel of mature Dwarven Stout.", - "ids": "7412" - }, - { - "examine": "A barrel of Asgarnian Ale.", - "ids": "7413" - }, - { - "examine": "A barrel of mature Asgarnian Ale.", - "ids": "7414" - }, - { - "examine": "A barrel of Greenmans Ale.", - "ids": "7415" - }, - { - "examine": "A barrel of mature Greenmans Ale.", - "ids": "7416" - }, - { - "examine": "A barrel of Wizards Mind Bomb.", - "ids": "7417" - }, - { - "examine": "A barrel of mature Wizards Mind Bomb.", - "ids": "7418" - }, - { - "examine": "A barrel of Dragon Bitter.", - "ids": "7419" - }, - { - "examine": "A barrel of mature Dragon Bitter.", - "ids": "7420" - }, - { - "examine": "A barrel of Moonlight Mead.", - "ids": "7421" - }, - { - "examine": "A barrel of mature Moonlight Mead.", - "ids": "7422" - }, - { - "examine": "A barrel of Axeman's Folly.", - "ids": "7423" - }, - { - "examine": "A barrel of mature Axeman's Folly.", - "ids": "7424" - }, - { - "examine": "A barrel of Chef's Delight.", - "ids": "7425" - }, - { - "examine": "A barrel of mature Chef's Delight.", - "ids": "7426" - }, - { - "examine": "A barrel of Slayer's Respite.", - "ids": "7427" - }, - { - "examine": "A barrel of mature Slayer's Respite.", - "ids": "7428" - }, - { - "examine": "A barrel of Cider.", - "ids": "7429" - }, - { - "examine": "A barrel of mature Cider.", - "ids": "7430,7431,7432" - }, - { - "examine": "Goes up and down!", - "ids": "7433" - }, - { - "examine": "I wonder what's under it?", - "ids": "7434" - }, - { - "examine": "I wonder what's down there?", - "ids": "7435" - }, - { - "examine": "A wooden barrel.", - "ids": "7436" - }, - { - "examine": "This vat is empty.", - "ids": "7437" - }, - { - "examine": "This vat is filled with water.", - "ids": "7438" - }, - { - "examine": "This vat is filled with bad ale.", - "ids": "7439" - }, - { - "examine": "This vat is filled with bad cider.", - "ids": "7440" - }, - { - "examine": "This vat contains a mixture of water and barley malt.", - "ids": "7441" - }, - { - "examine": "This controls the flow of ale to the barrel.", - "ids": "7442,7443" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Hammerstone hops.", - "ids": "7444" - }, - { - "examine": "Dwarven Stout is fermenting in this vat.", - "ids": "7445,7446" - }, - { - "examine": "This vat is filled with Dwarven Stout.", - "ids": "7447" - }, - { - "examine": "This vat is filled with mature Dwarven Stout.", - "ids": "7448" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Asgarnian hops.", - "ids": "7449" - }, - { - "examine": "Asgarnian Ale is fermenting in this vat.", - "ids": "7450,7451" - }, - { - "examine": "This vat is filled with Asgarnian Ale.", - "ids": "7452" - }, - { - "examine": "This vat is filled with mature Asgarnian Ale.", - "ids": "7453" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Harralander.", - "ids": "7454" - }, - { - "examine": "Greenmans Ale is fermenting in this vat.", - "ids": "7455,7456" - }, - { - "examine": "This vat is filled with Greenmans Ale.", - "ids": "7457" - }, - { - "examine": "This vat is filled with mature Greenmans Ale.", - "ids": "7458" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Yanillian hops.", - "ids": "7459" - }, - { - "examine": "Wizards Mind Bomb is fermenting in this vat.", - "ids": "7460,7461" - }, - { - "examine": "This vat is filled with Wizards Mind Bomb.", - "ids": "7462" - }, - { - "examine": "This vat is filled with mature Wizards Mind Bomb.", - "ids": "7463" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Krandorian hops.", - "ids": "7464" - }, - { - "examine": "Dragon Bitter is fermenting in this vat.", - "ids": "7465,7466" - }, - { - "examine": "This vat is filled with Dragon Bitter.", - "ids": "7467" - }, - { - "examine": "This vat is filled with mature Dragon Bitter.", - "ids": "7468" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Bittercap mushrooms.", - "ids": "7469" - }, - { - "examine": "Moonlight Mead is fermenting in this vat.", - "ids": "7470,7471" - }, - { - "examine": "This vat is filled with Moonlight Mead.", - "ids": "7472" - }, - { - "examine": "This vat is filled with mature Moonlight Mead.", - "ids": "7473" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and oak roots.", - "ids": "7474" - }, - { - "examine": "Axeman's Folly is fermenting in this vat.", - "ids": "7475,7476" - }, - { - "examine": "This vat is filled with Axeman's Folly.", - "ids": "7477" - }, - { - "examine": "This vat is filled with mature Axeman's Folly.", - "ids": "7478" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and chocolate dust.", - "ids": "7479" - }, - { - "examine": "Chef's Delight is fermenting in this vat.", - "ids": "7480,7481" - }, - { - "examine": "This vat is filled with Chef's Delight.", - "ids": "7482" - }, - { - "examine": "This vat is filled with mature Chef's Delight.", - "ids": "7483" - }, - { - "examine": "This vat contains a mixture of water, barley malt, and Wildblood hops.", - "ids": "7484" - }, - { - "examine": "Slayer's Respite is fermenting in this vat.", - "ids": "7485,7486" - }, - { - "examine": "This vat is filled with Slayer's Respite.", - "ids": "7487" - }, - { - "examine": "This vat is filled with mature Slayer's Respite.", - "ids": "7488" - }, - { - "examine": "This vat contains some apple mush.", - "ids": "7489" - }, - { - "examine": "Cider is fermenting in this vat.", - "ids": "7490,7491" - }, - { - "examine": "This vat is filled with cider.", - "ids": "7492" - }, - { - "examine": "This vat is filled with mature cider.", - "ids": "7493,7494,7495" - }, - { - "examine": "Items are for sale here.", - "ids": "7496,7497" - }, - { - "examine": "They're empty.", - "ids": "7498" - }, - { - "examine": "Farming stock is kept here.", - "ids": "7499,7500,7501,7502,7503" - }, - { - "examine": "For sitting.", - "ids": "7504,7505" - }, - { - "examine": "They're empty.", - "ids": "7506" - }, - { - "examine": "Farming stock is kept here.", - "ids": "7507,7508,7509,7510,7511" - }, - { - "examine": "A pair of sacks.", - "ids": "7512" - }, - { - "examine": "For storage.", - "ids": "7513,7514,7515" - }, - { - "examine": "A farmer's spade and rake.", - "ids": "7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526" - }, - { - "examine": "I can climb over the fence with this.", - "ids": "7527" - }, - { - "examine": "For fermenting beer.", - "ids": "7528,7529,7530" - }, - { - "examine": "An ale barrel.", - "ids": "7531" - }, - { - "examine": "This controls the flow of ale to the barrel.", - "ids": "7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556" - }, - { - "examine": "You can grow Deadly Nightshade in this Farming patch.", - "ids": "7557,7558,7559,7560" - }, - { - "examine": "Deadly Nightshade has been sown in this farming patch.", - "ids": "7561" - }, - { - "examine": "Deadly Nightshade is growing in this farming patch.", - "ids": "7562,7563,7564" - }, - { - "examine": "I wouldn't pick this with my bare hands.", - "ids": "7565" - }, - { - "examine": "This Deadly Nightshade has become diseased.", - "ids": "7566,7567,7568" - }, - { - "examine": "This Deadly Nightshade has died.", - "ids": "7569,7570,7571,7572" - }, - { - "examine": "You can grow bushes in this Farming patch.", - "ids": "7573,7574,7575,7576,7577,7578,7579,7580" - }, - { - "examine": "A cadavaberry bush is growing in this Farming patch.", - "ids": "7581,7582,7583,7584,7585,7586" - }, - { - "examine": "A fully grown cadavaberry bush.", - "ids": "7587,7588,7589,7590,7591,7592" - }, - { - "examine": "This diseased cadavaberry bush needs pruning.", - "ids": "7593,7594,7595,7596,7597,7598" - }, - { - "examine": "This cadavaberry bush has died.", - "ids": "7599,7600,7601,7602,7603,7604" - }, - { - "examine": "A dwellberry bush is growing in this Farming patch.", - "ids": "7605,7606,7607,7608,7609,7610,7611" - }, - { - "examine": "A fully grown dwellberry bush.", - "ids": "7612,7613,7614,7615,7616,7617" - }, - { - "examine": "This diseased dwellberry bush needs pruning.", - "ids": "7618,7619,7620,7621,7622,7623,7624" - }, - { - "examine": "This dwellberry bush has died.", - "ids": "7625,7626,7627,7628,7629,7630,7631" - }, - { - "examine": "A jangerberry bush is growing in this Farming patch.", - "ids": "7632,7633,7634,7635,7636,7637,7638,7639" - }, - { - "examine": "A fully grown jangerberry bush.", - "ids": "7640,7641,7642,7643,7644,7645" - }, - { - "examine": "This diseased jangerberry bush needs pruning.", - "ids": "7646,7647,7648,7649,7650,7651,7652,7653" - }, - { - "examine": "This jangerberry bush has died.", - "ids": "7654,7655,7656,7657,7658,7659,7660,7661" - }, - { - "examine": "A Poison Ivy bush is growing in this Farming patch.", - "ids": "7662,7663,7664,7665,7666,7667,7668,7669" - }, - { - "examine": "A fully grown Poison Ivy bush.", - "ids": "7670,7671,7672,7673,7674,7675" - }, - { - "examine": "This diseased Poison Ivy bush needs pruning.", - "ids": "7676,7677,7678,7679,7680,7681,7682,7683" - }, - { - "examine": "This Poison Ivy bush has died.", - "ids": "7684,7685,7686,7687,7688,7689,7690,7691" - }, - { - "examine": "A redberry bush is growing in this Farming patch.", - "ids": "7692,7693,7694,7695,7696" - }, - { - "examine": "A fully grown redberry bush.", - "ids": "7697,7698,7699,7700,7701,7702" - }, - { - "examine": "This diseased redberry bush needs pruning.", - "ids": "7703,7704,7705,7706,7707" - }, - { - "examine": "This redberry bush has died.", - "ids": "7708,7709,7710,7711,7712" - }, - { - "examine": "A whiteberry bush is growing in this Farming patch.", - "ids": "7713,7714,7715,7716,7717,7718,7719,7720" - }, - { - "examine": "A fully grown whiteberry bush.", - "ids": "7721,7722,7723,7724,7725,7726" - }, - { - "examine": "This diseased whiteberry bush needs pruning.", - "ids": "7727,7728,7729,7730,7731,7732,7733,7734" - }, - { - "examine": "This whiteberry bush has died.", - "ids": "7735,7736,7737,7738,7739,7740,7741,7742" - }, - { - "examine": "You can grow a Cactus in this Farming patch.", - "ids": "7743,7744,7745,7746" - }, - { - "examine": "Cactus seeds have been planted in this patch.", - "ids": "7747" - }, - { - "examine": "A cactus is growing in this patch.", - "ids": "7748,7749,7750,7751,7752,7753" - }, - { - "examine": "A fully-grown cactus.", - "ids": "7754,7755,7756,7757,7758" - }, - { - "examine": "This cactus has become diseased.", - "ids": "7759,7760,7761,7762,7763,7764" - }, - { - "examine": "This cactus has died.", - "ids": "7765,7766,7767,7768,7769,7770,7771" - }, - { - "examine": "You can grow a Calquat Tree in this Farming patch.", - "ids": "7772,7773,7774,7775" - }, - { - "examine": "A Calquat tree is growing in this Farming patch.", - "ids": "7776,7777,7778,7779,7780,7781,7782,7783" - }, - { - "examine": "A fully grown Calquat tree stands in this Farming patch.", - "ids": "7784,7785,7786,7787,7788,7789,7790,7791" - }, - { - "examine": "This diseased Calquat tree needs pruning.", - "ids": "7792,7793,7794,7795,7796,7797,7798" - }, - { - "examine": "This Calquat tree has died.", - "ids": "7799,7800,7801,7802,7803,7804,7805" - }, - { - "examine": "A Calquat tree stump.", - "ids": "7806,7807" - }, - { - "examine": "Turns vegetation into compost.", - "ids": "7808" - }, - { - "examine": "This compost bin contains compostable items.", - "ids": "7809" - }, - { - "examine": "This compost bin is full of compostable items.", - "ids": "7810" - }, - { - "examine": "This compost bin contains supercompostable items.", - "ids": "7811" - }, - { - "examine": "This compost bin is full of supercompostable items.", - "ids": "7812" - }, - { - "examine": "Turns vegetation into compost.", - "ids": "7813" - }, - { - "examine": "This compost bin contains compost.", - "ids": "7814" - }, - { - "examine": "This compost bin is full of compost.", - "ids": "7815" - }, - { - "examine": "This compost bin contains super compost.", - "ids": "7816" - }, - { - "examine": "This compost bin is full of super compost.", - "ids": "7817" - }, - { - "examine": "Turns vegetation into compost.", - "ids": "7818" - }, - { - "examine": "This compost bin contains compostable items.", - "ids": "7819" - }, - { - "examine": "This compost bin is full of compostable items.", - "ids": "7820" - }, - { - "examine": "This compost bin contains supercompostable items.", - "ids": "7821" - }, - { - "examine": "This compost bin is full of supercompostable items.", - "ids": "7822" - }, - { - "examine": "Turns vegetation into compost.", - "ids": "7823" - }, - { - "examine": "This compost bin contains compost.", - "ids": "7824" - }, - { - "examine": "This compost bin is full of compost.", - "ids": "7825" - }, - { - "examine": "This compost bin contains super compost.", - "ids": "7826" - }, - { - "examine": "This compost bin is full of super compost.", - "ids": "7827" - }, - { - "examine": "This compost bin contains tomatoes.", - "ids": "7828" - }, - { - "examine": "This compost bin is full of tomatoes.", - "ids": "7829" - }, - { - "examine": "This compost bin contains rotten tomatoes.", - "ids": "7830" - }, - { - "examine": "This compost bin is full of rotten tomatoes.", - "ids": "7831" - }, - { - "examine": "This compost bin contains tomatoes.", - "ids": "7832" - }, - { - "examine": "This compost bin is full of tomatoes.", - "ids": "7833" - }, - { - "examine": "This compost bin contains rotten tomatoes.", - "ids": "7834" - }, - { - "examine": "This compost bin is full of rotten tomatoes.", - "ids": "7835,7836,7837,7838,7839" - }, - { - "examine": "You can grow flowers in this Farming patch.", - "ids": "7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850" - }, - { - "examine": "A limpwurt plant is growing in this patch.", - "ids": "7851,7852,7853,7854" - }, - { - "examine": "A fully grown limpwurt plant.", - "ids": "7855" - }, - { - "examine": "A limpwurt plant is growing in this patch.", - "ids": "7856,7857,7858,7859" - }, - { - "examine": "This limpwurt plant has become diseased.", - "ids": "7860,7861,7862" - }, - { - "examine": "This limpwurt plant has died while growing.", - "ids": "7863,7864,7865" - }, - { - "examine": "This limpwurt plant has died.", - "ids": "7866" - }, - { - "examine": "A marigold is growing in this patch.", - "ids": "7867,7868,7869,7870" - }, - { - "examine": "A fully grown marigold.", - "ids": "7871" - }, - { - "examine": "A marigold is growing in this patch.", - "ids": "7872,7873,7874,7875" - }, - { - "examine": "This marigold has become diseased.", - "ids": "7876,7877,7878" - }, - { - "examine": "This marigold has died while growing.", - "ids": "7879,7880,7881" - }, - { - "examine": "This marigold has died.", - "ids": "7882" - }, - { - "examine": "A nasturtium is growing in this patch.", - "ids": "7883,7884,7885,7886" - }, - { - "examine": "A fully grown nasturtium.", - "ids": "7887" - }, - { - "examine": "A nasturtium is growing in this patch.", - "ids": "7888,7889,7890,7891" - }, - { - "examine": "This nasturtium has become diseased.", - "ids": "7892,7893,7894" - }, - { - "examine": "This nasturtium has died while growing.", - "ids": "7895,7896,7897" - }, - { - "examine": "This nasturtium has died.", - "ids": "7898" - }, - { - "examine": "A rosemary is growing in this patch.", - "ids": "7899,7900,7901,7902" - }, - { - "examine": "A fully grown rosemary.", - "ids": "7903" - }, - { - "examine": "A rosemary is growing in this patch.", - "ids": "7904,7905,7906,7907" - }, - { - "examine": "This rosemary has become diseased.", - "ids": "7908,7909,7910" - }, - { - "examine": "This rosemary has died while growing.", - "ids": "7911,7912,7913" - }, - { - "examine": "This rosemary has died.", - "ids": "7914" - }, - { - "examine": "Should scare off the birds...", - "ids": "7915,7916,7917,7918" - }, - { - "examine": "A woad plant is growing in this patch.", - "ids": "7919,7920,7921,7922" - }, - { - "examine": "A fully grown woad plant.", - "ids": "7923" - }, - { - "examine": "A woad plant is growing in this patch.", - "ids": "7924,7925,7926,7927" - }, - { - "examine": "This woad plant has become diseased.", - "ids": "7928,7929,7930" - }, - { - "examine": "This woad plant has died while growing.", - "ids": "7931,7932,7933" - }, - { - "examine": "This woad plant has died.", - "ids": "7934" - }, - { - "examine": "An apple tree sapling has been planted in this fruit tree patch.", - "ids": "7935" - }, - { - "examine": "An apple tree is growing in this fruit tree patch.", - "ids": "7936,7937,7938,7939,7940" - }, - { - "examine": "A fully grown apple tree.", - "ids": "7941" - }, - { - "examine": "There is a single apple on this apple tree.", - "ids": "7942" - }, - { - "examine": "There are two apples on this apple tree.", - "ids": "7943" - }, - { - "examine": "There are three apples on this apple tree.", - "ids": "7944" - }, - { - "examine": "There are four apples on this apple tree.", - "ids": "7945" - }, - { - "examine": "There are five apples on this apple tree.", - "ids": "7946" - }, - { - "examine": "There are six apples on this apple tree.", - "ids": "7947" - }, - { - "examine": "A fully grown apple tree.", - "ids": "7948" - }, - { - "examine": "This diseased tree looks like it needs pruning with secateurs.", - "ids": "7949,7950,7951,7952,7953,7954" - }, - { - "examine": "This apple tree has become diseased and died.", - "ids": "7955,7956,7957,7958,7959,7960" - }, - { - "examine": "This apple tree has been cut down.", - "ids": "7961,7962,7963,7964,7965" - }, - { - "examine": "A pineapple plant has been planted in this fruit tree patch.", - "ids": "7966" - }, - { - "examine": "A pineapple plant is growing in this fruit tree patch.", - "ids": "7967,7968,7969,7970,7971" - }, - { - "examine": "A fully grown pineapple plant.", - "ids": "7972" - }, - { - "examine": "There is a single pineapple on this pineapple plant.", - "ids": "7973" - }, - { - "examine": "There are two pineapples on this pineapple plant.", - "ids": "7974" - }, - { - "examine": "There are three pineapples on this pineapple plant.", - "ids": "7975" - }, - { - "examine": "There are four pineapples on this pineapple plant.", - "ids": "7976" - }, - { - "examine": "There are five pineapples on this pineapple plant.", - "ids": "7977" - }, - { - "examine": "There are six pineapples on this pineapple plant.", - "ids": "7978" - }, - { - "examine": "A fully grown pineapple plant.", - "ids": "7979" - }, - { - "examine": "This pineapple plant looks like it could do with pruning with secateurs.", - "ids": "7980,7981,7982,7983,7984,7985" - }, - { - "examine": "This pineapple plant has become diseased and died.", - "ids": "7986,7987,7988,7989,7990,7991" - }, - { - "examine": "This pineapple plant has been cut down.", - "ids": "7992" - }, - { - "examine": "A banana tree sapling has been planted in this fruit tree patch.", - "ids": "7993" - }, - { - "examine": "A banana tree is growing in this fruit tree patch.", - "ids": "7994,7995,7996,7997,7998" - }, - { - "examine": "A fully grown banana tree.", - "ids": "7999,8000" - }, - { - "examine": "There is a single banana on this banana tree.", - "ids": "8001" - }, - { - "examine": "There are two bananas on this banana tree.", - "ids": "8002" - }, - { - "examine": "There are three bananas on this banana tree.", - "ids": "8003" - }, - { - "examine": "There are four bananas on this banana tree.", - "ids": "8004" - }, - { - "examine": "There are five bananas on this banana tree.", - "ids": "8005" - }, - { - "examine": "There are six bananas on this banana tree.", - "ids": "8006" - }, - { - "examine": "This banana looks like it could do with pruning with secateurs.", - "ids": "8007,8008,8009,8010,8011,8012" - }, - { - "examine": "This banana tree has become diseased and died.", - "ids": "8013,8014,8015,8016,8017,8018" - }, - { - "examine": "This banana tree has been cut down.", - "ids": "8019" - }, - { - "examine": "A curry tree sapling has been planted in this fruit tree patch.", - "ids": "8020" - }, - { - "examine": "A curry tree is growing in this fruit tree patch.", - "ids": "8021,8022,8023,8024,8025" - }, - { - "examine": "A fully grown curry tree.", - "ids": "8026" - }, - { - "examine": "There is a single curry leaf on this curry tree.", - "ids": "8027" - }, - { - "examine": "There are two curry leaves on this curry tree.", - "ids": "8028" - }, - { - "examine": "There are three curry leaves on this curry tree.", - "ids": "8029" - }, - { - "examine": "There are four curry leaves on this curry tree.", - "ids": "8030" - }, - { - "examine": "There are five curry leaves on this curry tree.", - "ids": "8031" - }, - { - "examine": "There are six curry leaves on this curry tree.", - "ids": "8032" - }, - { - "examine": "A fully grown curry tree.", - "ids": "8033" - }, - { - "examine": "This curry tree looks like it could do with pruning with secateurs.", - "ids": "8034,8035,8036,8037,8038,8039" - }, - { - "examine": "This curry tree has become diseased and died.", - "ids": "8040,8041,8042,8043,8044,8045" - }, - { - "examine": "This curry tree has been cut down.", - "ids": "8046" - }, - { - "examine": "You can grow Fruit Trees in this Farming patch.", - "ids": "8047,8048,8049,8050" - }, - { - "examine": "An orange tree sapling has been planted in this fruit tree patch.", - "ids": "8051" - }, - { - "examine": "An orange tree is growing in this fruit tree patch.", - "ids": "8052,8053,8054,8055,8056" - }, - { - "examine": "A fully grown orange tree.", - "ids": "8057" - }, - { - "examine": "There is a single orange on this orange tree.", - "ids": "8058" - }, - { - "examine": "There are two oranges on this orange tree.", - "ids": "8059" - }, - { - "examine": "There are three oranges on this orange tree.", - "ids": "8060" - }, - { - "examine": "There are four oranges on this orange tree.", - "ids": "8061" - }, - { - "examine": "There are five oranges on this orange tree.", - "ids": "8062" - }, - { - "examine": "There are six oranges on this orange tree.", - "ids": "8063" - }, - { - "examine": "A fully grown orange tree.", - "ids": "8064" - }, - { - "examine": "This orange tree looks like it could do with pruning with secateurs.", - "ids": "8065,8066,8067,8068,8069,8070" - }, - { - "examine": "This orange tree has become diseased and died.", - "ids": "8071,8072,8073,8074,8075,8076" - }, - { - "examine": "This orange tree has been cut down.", - "ids": "8077" - }, - { - "examine": "A palm tree sapling has been planted in this fruit tree patch.", - "ids": "8078" - }, - { - "examine": "A palm tree is growing in this fruit tree patch.", - "ids": "8079,8080,8081,8082,8083" - }, - { - "examine": "A fully grown palm tree.", - "ids": "8084" - }, - { - "examine": "There is a single coconut on this palm tree.", - "ids": "8085" - }, - { - "examine": "There are two coconuts on this palm tree.", - "ids": "8086" - }, - { - "examine": "There are three coconuts on this palm tree.", - "ids": "8087" - }, - { - "examine": "There are four coconuts on this palm tree.", - "ids": "8088" - }, - { - "examine": "There are five coconuts on this palm tree.", - "ids": "8089" - }, - { - "examine": "There are six coconuts on this palm tree.", - "ids": "8090" - }, - { - "examine": "A fully grown palm tree.", - "ids": "8091" - }, - { - "examine": "This palm tree looks like it could do with pruning with secateurs.", - "ids": "8092,8093,8094,8095,8096,8097" - }, - { - "examine": "This palm tree has become diseased and died.", - "ids": "8098,8099,8100,8101,8102,8103" - }, - { - "examine": "This palm tree has been cut down.", - "ids": "8104" - }, - { - "examine": "A papaya tree sapling has been planted in this fruit tree patch.", - "ids": "8105" - }, - { - "examine": "A papaya tree is growing in this fruit tree patch.", - "ids": "8106,8107,8108,8109,8110" - }, - { - "examine": "A fully grown papaya tree", - "ids": "8111" - }, - { - "examine": "There is a single papaya fruit on this tree.", - "ids": "8112" - }, - { - "examine": "There are two papaya fruits on this tree.", - "ids": "8113" - }, - { - "examine": "There are three papaya fruits on this tree.", - "ids": "8114" - }, - { - "examine": "There are four papaya fruits on this tree.", - "ids": "8115" - }, - { - "examine": "There are five papaya fruits on this tree.", - "ids": "8116" - }, - { - "examine": "There are six papaya fruits on this tree.", - "ids": "8117" - }, - { - "examine": "A fully grown papaya tree.", - "ids": "8118" - }, - { - "examine": "This papaya tree looks like it could do with pruning with secateurs.", - "ids": "8119,8120,8121,8122,8123,8124" - }, - { - "examine": "This papaya tree has become diseased and died.", - "ids": "8125,8126,8127,8128,8129,8130" - }, - { - "examine": "This papaya tree has been cut down.", - "ids": "8131" - }, - { - "examine": "You can grow herbs in this Farming patch.", - "ids": "8132,8133,8134,8135,8136,8137,8138" - }, - { - "examine": "Some herb seeds have been sown in this patch.", - "ids": "8139" - }, - { - "examine": "A herb is growing in this patch.", - "ids": "8140,8141,8142" - }, - { - "examine": "A fully grown herb.", - "ids": "8143" - }, - { - "examine": "These herbs have become diseased.", - "ids": "8144,8145,8146" - }, - { - "examine": "These herbs have become diseased and died.", - "ids": "8147,8148,8149,8150,8151,8152,8153" - }, - { - "examine": "Asgarnian hop seeds have been sown in this farming patch.", - "ids": "8154" - }, - { - "examine": "Asgarnian hops are growing in this farming patch.", - "ids": "8155,8156,8157,8158" - }, - { - "examine": "These are fully grown Asgarnian Hops.", - "ids": "8159" - }, - { - "examine": "Asgarnian hop seeds have been sown in this farming patch.", - "ids": "8160" - }, - { - "examine": "Asgarnian hops are growing in this farming patch.", - "ids": "8161,8162,8163,8164" - }, - { - "examine": "These Asgarnian Hop plants are diseased.", - "ids": "8165,8166,8167,8168" - }, - { - "examine": "These Asgarnian Hop plants have died from disease.", - "ids": "8169,8170,8171,8172,8173,8174,8175,8176" - }, - { - "examine": "Hammerstone Hop seeds have been sown in this farming patch.", - "ids": "8177" - }, - { - "examine": "Hammerstone Hops are growing in this farming patch.", - "ids": "8178,8179,8180" - }, - { - "examine": "These are fully grown Hammerstone Hops.", - "ids": "8181" - }, - { - "examine": "Hammerstone Hop seeds have been sown in this farming patch.", - "ids": "8182" - }, - { - "examine": "Hammerstone Hops are growing in this farming patch.", - "ids": "8183,8184,8185" - }, - { - "examine": "These Hammerstone Hops are diseased.", - "ids": "8186,8187,8188" - }, - { - "examine": "These Hammerstone Hops have died from disease.", - "ids": "8189,8190,8191" - }, - { - "examine": "Barley seeds have been sown in this farming patch.", - "ids": "8192" - }, - { - "examine": "Barley is growing in this farming patch.", - "ids": "8193,8194,8195" - }, - { - "examine": "This patch is full of Barley.", - "ids": "8196" - }, - { - "examine": "Barley seeds have been sown in this farming patch.", - "ids": "8197" - }, - { - "examine": "Barley is growing in this farming patch.", - "ids": "8198,8199,8200" - }, - { - "examine": "This Barley is diseased.", - "ids": "8201,8202,8203" - }, - { - "examine": "This Barley has died from disease.", - "ids": "8204,8205,8206" - }, - { - "examine": "You can grow hops in this Farming patch.", - "ids": "8207,8208,8209,8210" - }, - { - "examine": "Krandorian Hop seeds have been planted in this farming patch.", - "ids": "8211" - }, - { - "examine": "Krandorian Hops are growing in this farming patch.", - "ids": "8212,8213,8214,8215,8216,8217" - }, - { - "examine": "These are fully grown Krandorian Hops.", - "ids": "8218" - }, - { - "examine": "Krandorian Hop seeds have been planted in this farming patch.", - "ids": "8219" - }, - { - "examine": "Krandorian Hops are growing in this farming patch.", - "ids": "8220,8221,8222,8223,8224,8225" - }, - { - "examine": "These Krandorian Hops are diseased.", - "ids": "8226,8227,8228,8229,8230,8231" - }, - { - "examine": "These Krandorian Hops have died from disease.", - "ids": "8232,8233,8234,8235,8236,8237" - }, - { - "examine": "Jute seeds have been sown in this farming patch.", - "ids": "8238" - }, - { - "examine": "Jute plants are growing in this farming patch.", - "ids": "8239,8240,8241,8242" - }, - { - "examine": "These are fully grown Jute plants.", - "ids": "8243" - }, - { - "examine": "Jute seeds have been sown in this farming patch.", - "ids": "8244" - }, - { - "examine": "Jute plants are growing in this farming patch.", - "ids": "8245,8246,8247,8248" - }, - { - "examine": "These Jute plants are diseased.", - "ids": "8249,8250,8251,8252" - }, - { - "examine": "These Jute plants have died from disease.", - "ids": "8253,8254,8255,8256" - }, - { - "examine": "Wildblood hop seeds have been planted in this farming patch.", - "ids": "8257" - }, - { - "examine": "Wildblood Hops are growing in this farming patch.", - "ids": "8258,8259,8260,8261,8262,8263,8264" - }, - { - "examine": "These are fully grown Wildblood Hops.", - "ids": "8265" - }, - { - "examine": "Wildblood hop seeds have been planted in this farming patch.", - "ids": "8266" - }, - { - "examine": "Wildblood Hops are growing in this farming patch.", - "ids": "8267,8268,8269,8270,8271,8272,8273" - }, - { - "examine": "These Wildblood hops are diseased.", - "ids": "8274,8275,8276,8277,8278,8279,8280" - }, - { - "examine": "These Wildblood Hops have died from disease.", - "ids": "8281,8282,8283,8284,8285,8286,8287" - }, - { - "examine": "Yanillian Hop seeds have been sown in this farming patch.", - "ids": "8288" - }, - { - "examine": "Yanillian Hops are growing in this farming patch.", - "ids": "8289,8290,8291,8292,8293" - }, - { - "examine": "These are fully grown Yanillian Hops.", - "ids": "8294" - }, - { - "examine": "Yanillian Hop seeds have been sown in this farming patch.", - "ids": "8295" - }, - { - "examine": "Yanillian Hops are growing in this farming patch.", - "ids": "8296,8297,8298,8299,8300" - }, - { - "examine": "These Yanillian Hops are diseased.", - "ids": "8301,8302,8303,8304,8305" - }, - { - "examine": "These Yanillian Hops have died from disease.", - "ids": "8306,8307,8308,8309,8310" - }, - { - "examine": "You can grow Bittercap mushrooms in this Farming patch.", - "ids": "8311,8312,8313,8314" - }, - { - "examine": "Bittercap mushroom spores have been sown in this farming patch.", - "ids": "8315" - }, - { - "examine": "Bittercap mushrooms are growing in this farming patch.", - "ids": "8316,8317,8318,8319,8320" - }, - { - "examine": "A patch of Bittercap Mushrooms.", - "ids": "8321,8322,8323,8324,8325,8326" - }, - { - "examine": "These Bittercap mushrooms have become diseased.", - "ids": "8327,8328,8329,8330,8331" - }, - { - "examine": "These Bittercap mushrooms have become diseased and died.", - "ids": "8332,8333,8334,8335,8336,8337,8338" - }, - { - "examine": "You can grow a Spirit Tree in this Farming patch.", - "ids": "8339,8340,8341,8342" - }, - { - "examine": "A Spirit Tree.", - "ids": "8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356" - }, - { - "examine": "A Spirit Tree stump.", - "ids": "8357" - }, - { - "examine": "Needs pruning before it dies.", - "ids": "8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369" - }, - { - "examine": "Oh dear, your spirit tree has died.", - "ids": "8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,8390,8391" - }, - { - "examine": "You can grow trees in this Farming patch.", - "ids": "8392,8393,8394,8395" - }, - { - "examine": "A Magic Tree sapling has been planted in this tree patch.", - "ids": "8396" - }, - { - "examine": "A Magic Tree is growing in this tree patch.", - "ids": "8397,8398,8399,8400,8401,8402,8403,8404,8405,8406,8407" - }, - { - "examine": "A fully grown Magic Tree.", - "ids": "8408,8409" - }, - { - "examine": "You can uproot this stump with a spade.", - "ids": "8410" - }, - { - "examine": "To remove all signs of disease, prune the tree with secateurs.", - "ids": "8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,8422" - }, - { - "examine": "This Magic Tree has become diseased and died.", - "ids": "8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434" - }, - { - "examine": "A Maple tree sapling has been planted in this tree patch.", - "ids": "8435" - }, - { - "examine": "A Maple tree is growing in this tree patch.", - "ids": "8436,8437,8438,8439,8440,8441,8442" - }, - { - "examine": "A fully grown Maple tree.", - "ids": "8443,8444" - }, - { - "examine": "You can uproot this stump with a spade.", - "ids": "8445" - }, - { - "examine": "To remove all signs of disease, prune the tree with secateurs.", - "ids": "8446,8447,8448,8449,8450,8451,8452,8453" - }, - { - "examine": "This Maple tree has become diseased and died.", - "ids": "8454,8455,8456,8457,8458,8459,8460,8461" - }, - { - "examine": "An Oak sapling has been planted in this tree patch.", - "ids": "8462" - }, - { - "examine": "An Oak tree is growing in this tree patch.", - "ids": "8463,8464,8465" - }, - { - "examine": "A fully grown Oak tree.", - "ids": "8466,8467" - }, - { - "examine": "You can uproot this stump with a spade.", - "ids": "8468,8469,8470,8471,8472" - }, - { - "examine": "To remove all signs of disease, prune the tree with secateurs.", - "ids": "8473,8474,8475,8476" - }, - { - "examine": "This Oak tree has become diseased and died.", - "ids": "8477,8478,8479,8480" - }, - { - "examine": "A Willow sapling has been planted in this tree patch.", - "ids": "8481" - }, - { - "examine": "A Willow tree is growing in this tree patch.", - "ids": "8482,8483,8484,8485,8486" - }, - { - "examine": "A fully grown Willow tree.", - "ids": "8487,8488" - }, - { - "examine": "You can uproot this stump with a spade.", - "ids": "8489" - }, - { - "examine": "To remove all signs of disease, prune the tree with secateurs.", - "ids": "8490,8491,8492,8493,8494,8495" - }, - { - "examine": "This Willow tree has become diseased and died.", - "ids": "8496,8497,8498,8499,8500,8501" - }, - { - "examine": "A Yew sapling has been planted in this tree patch.", - "ids": "8502" - }, - { - "examine": "A Yew tree is growing in this tree patch.", - "ids": "8503,8504,8505,8506,8507,8508,8509,8510,8511" - }, - { - "examine": "A fully grown Yew tree.", - "ids": "8512,8513" - }, - { - "examine": "You can uproot this tree stump with a spade.", - "ids": "8514" - }, - { - "examine": "To remove all signs of disease, prune the tree with secateurs.", - "ids": "8515,8516,8517,8518,8519,8520,8521,8522,8523,8524" - }, - { - "examine": "This Yew tree has become diseased and died.", - "ids": "8525,8526,8527,8528,8529,8530,8531,8532,8533,8534" - }, - { - "examine": "Cabbage seeds have been sown in this allotment.", - "ids": "8535" - }, - { - "examine": "Cabbages are growing in this allotment.", - "ids": "8536,8537,8538" - }, - { - "examine": "These cabbages could do with harvesting.", - "ids": "8539" - }, - { - "examine": "Cabbages are growing in this allotment.", - "ids": "8540,8541,8542,8543" - }, - { - "examine": "These cabbages have become diseased and need tending.", - "ids": "8544,8545,8546" - }, - { - "examine": "These cabbages have become diseased and died.", - "ids": "8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557" - }, - { - "examine": "Potato seeds have been planted in this allotment.", - "ids": "8558" - }, - { - "examine": "Potato plants are growing in this allotment.", - "ids": "8559,8560,8561" - }, - { - "examine": "These potato plants are fully grown.", - "ids": "8562" - }, - { - "examine": "Potato seeds have been planted in this allotment.", - "ids": "8563" - }, - { - "examine": "Potato plants are growing in this allotment.", - "ids": "8564,8565,8566" - }, - { - "examine": "These potato plants are diseased.", - "ids": "8567,8568,8569" - }, - { - "examine": "These potato plants are dead.", - "ids": "8570,8571,8572" - }, - { - "examine": "You can grow fruit and vegetables here.", - "ids": "8573,8574,8575,8576,8577,8578,8579" - }, - { - "examine": "Some onion seeds have sown in this allotment.", - "ids": "8580" - }, - { - "examine": "Some onion plants are growing in this allotment.", - "ids": "8581,8582,8583" - }, - { - "examine": "There are some fully grown onions in this allotment.", - "ids": "8584" - }, - { - "examine": "Some onion seeds have sown in this allotment.", - "ids": "8585" - }, - { - "examine": "Some onion plants are growing in this allotment.", - "ids": "8586,8587,8588" - }, - { - "examine": "These onions have become diseased.", - "ids": "8589,8590,8591" - }, - { - "examine": "These onions have become diseased and died.", - "ids": "8592,8593,8594" - }, - { - "examine": "Strawberry seeds have been sown in this allotment.", - "ids": "8595" - }, - { - "examine": "Strawberry plants are growing in this allotment.", - "ids": "8596,8597,8598,8599,8600" - }, - { - "examine": "These strawberry plants are fully grown.", - "ids": "8601" - }, - { - "examine": "Strawberry seeds have been sown in this allotment.", - "ids": "8602" - }, - { - "examine": "Strawberry plants are growing in this allotment.", - "ids": "8603,8604,8605,8606,8607" - }, - { - "examine": "These strawberry plants have become diseased.", - "ids": "8608,8609,8610,8611,8612" - }, - { - "examine": "These strawberry plants have become diseased and died.", - "ids": "8613,8614,8615,8616,8617" - }, - { - "examine": "Some sweetcorn seeds have been sown in this allotment.", - "ids": "8618" - }, - { - "examine": "Some sweetcorn plants are growing in this allotment.", - "ids": "8619,8620,8621,8622,8623" - }, - { - "examine": "These sweetcorn plants are fully grown.", - "ids": "8624" - }, - { - "examine": "Some sweetcorn seeds have been sown in this allotment.", - "ids": "8625" - }, - { - "examine": "Some sweetcorn plants are growing in this allotment.", - "ids": "8626,8627,8628,8629,8630" - }, - { - "examine": "These sweetcorn plants have been attacked by crows.", - "ids": "8631,8632,8633,8634,8635" - }, - { - "examine": "These sweetcorn plants have become diseased and died.", - "ids": "8636,8637,8638,8639,8640" - }, - { - "examine": "Tomato seeds have been sown in this allotment.", - "ids": "8641" - }, - { - "examine": "Tomato plants are growing in this allotment.", - "ids": "8642,8643,8644" - }, - { - "examine": "These tomato plants are fully grown.", - "ids": "8645" - }, - { - "examine": "Tomato seeds have been sown in this allotment.", - "ids": "8646" - }, - { - "examine": "Tomato plants are growing in this allotment.", - "ids": "8647,8648,8649" - }, - { - "examine": "These tomato plants have become diseased.", - "ids": "8650,8651,8652" - }, - { - "examine": "These tomato plants have become diseased and died.", - "ids": "8653,8654,8655" - }, - { - "examine": "Watermelon seeds have been sown in this allotment.", - "ids": "8656" - }, - { - "examine": "Watermelons are growing in this allotment.", - "ids": "8657,8658,8659,8660,8661,8662,8663" - }, - { - "examine": "These watermelons could do with harvesting.", - "ids": "8664" - }, - { - "examine": "Watermelon seeds have been sown in this allotment.", - "ids": "8665" - }, - { - "examine": "Watermelons are growing in this allotment.", - "ids": "8666,8667,8668,8669,8670,8671,8672" - }, - { - "examine": "These watermelons have become diseased and need tending.", - "ids": "8673,8674,8675,8676,8677,8678,8679" - }, - { - "examine": "These watermelon plants have become diseased and died.", - "ids": "8680" - }, - { - "examine": "These watermelons have become diseased and died.", - "ids": "8681,8682,8683,8684,8685,8686,8687" - }, - { - "examine": "The perfect accompaniment to a bedroom.", - "ids": "8688" - }, - { - "examine": "Fit for milking.", - "ids": "8689" - }, - { - "examine": "Each full of milk no doubt.", - "ids": "8690,8691,8692,8693,8694" - }, - { - "examine": "The door is closed.", - "ids": "8695" - }, - { - "examine": "The door is open.", - "ids": "8696,8697,8698" - }, - { - "examine": "After working with livestock, why not wash your hands?", - "ids": "8699" - }, - { - "examine": "For putting things on.", - "ids": "8700" - }, - { - "examine": "Someone's been preparing meat.", - "ids": "8701" - }, - { - "examine": "A barrel for collecting rain water.", - "ids": "8702,8703,8704,8705,8706,8707,8708,8709,8710,8711" - }, - { - "examine": "A grand old fireplace.", - "ids": "8712" - }, - { - "examine": "I bet there's a needle in it somewhere.", - "ids": "8713,8714,8715,8716" - }, - { - "examine": "A loom.", - "ids": "8717,8718,8719,8720,8721,8722,8723,8724" - }, - { - "examine": "A little rock.", - "ids": "8725" - }, - { - "examine": "A small chunk of rock.", - "ids": "8726" - }, - { - "examine": "They're not floating, even though it may look like they are!", - "ids": "8727" - }, - { - "examine": "A deposit of rocks.", - "ids": "8728,8729,8730,8731,8732,8733,8734,8735,8736" - }, - { - "examine": "This tap runs from the apple crushing barrel.", - "ids": "8737" - }, - { - "examine": "You can walk through these doors.", - "ids": "8738,8739,8740,8741" - }, - { - "examine": "An odd looking tree.", - "ids": "8742,8743" - }, - { - "examine": "I can climb this.", - "ids": "8744,8745" - }, - { - "examine": "I can climb down this.", - "ids": "8746" - }, - { - "examine": "A local water source.", - "ids": "8747" - }, - { - "examine": "Used for spinning thread.", - "ids": "8748" - }, - { - "examine": "A Shrine to the glory of Seren.", - "ids": "8749" - }, - { - "examine": "I can cook here.", - "ids": "8750" - }, - { - "examine": "A nice sturdy looking table.", - "ids": "8751" - }, - { - "examine": "A good source of books!", - "ids": "8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,8765,8766" - }, - { - "examine": "The lamp has a glowing crystal at its core.", - "ids": "8767" - }, - { - "examine": "A table.", - "ids": "8768,8769" - }, - { - "examine": "A chair.", - "ids": "8770" - }, - { - "examine": "A painting of an elf standing in some woodland.", - "ids": "8771" - }, - { - "examine": "Sit back and relax...", - "ids": "8772" - }, - { - "examine": "A useful ranging device.", - "ids": "8773,8774" - }, - { - "examine": "Use these with bows.", - "ids": "8775" - }, - { - "examine": "Tailor-made for needlework supplies.", - "ids": "8776,8777" - }, - { - "examine": "I'm guessing it's for making elven clothes.", - "ids": "8778" - }, - { - "examine": "Helps make elf clothing.", - "ids": "8779,8780,8781,8782" - }, - { - "examine": "I wonder what's under it?", - "ids": "8783,8784" - }, - { - "examine": "I can climb this.", - "ids": "8785" - }, - { - "examine": "The door is closed.", - "ids": "8786,8787,8788,8789" - }, - { - "examine": "The door is open.", - "ids": "8790,8791,8792,8793,8794" - }, - { - "examine": "Makes gnomes taller.", - "ids": "8795" - }, - { - "examine": "Makes creatures taller.", - "ids": "8796" - }, - { - "examine": "I wonder what's inside.", - "ids": "8797" - }, - { - "examine": "Perhaps I should search it.", - "ids": "8798" - }, - { - "examine": "The desk of the head mourner.", - "ids": "8799" - }, - { - "examine": "I wonder what's inside.", - "ids": "8800" - }, - { - "examine": "A sack full of grain.", - "ids": "8801,8802,8803" - }, - { - "examine": "These have grain in them.", - "ids": "8804,8805,8806" - }, - { - "examine": "An empty barrel.", - "ids": "8807" - }, - { - "examine": "A barrel full of mushed apples.", - "ids": "8808" - }, - { - "examine": "A pile of rotten apples!", - "ids": "8809" - }, - { - "examine": "A wooden gate.", - "ids": "8810,8811,8812,8813" - }, - { - "examine": "A well slept in bed.", - "ids": "8814,8815,8816,8817" - }, - { - "examine": "The door is closed.", - "ids": "8818" - }, - { - "examine": "The door is open.", - "ids": "8819" - }, - { - "examine": "Solid iron bars.", - "ids": "8820,8821,8822,8823,8824,8825,8826,8827" - }, - { - "examine": "Heavy.", - "ids": "8828,8829,8830" - }, - { - "examine": "You can 'cart' things around on this.", - "ids": "8831,8832,8833,8834,8835,8836,8837,8838,8839" - }, - { - "examine": "I feel the need to throw a rotten cabbage!", - "ids": "8840,8841" - }, - { - "examine": "Nothing growing on this tree at the moment...", - "ids": "8842" - }, - { - "examine": "Mmmmm, nice juicy apples!", - "ids": "8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,8855,8856,8857,8858,8859,8860" - }, - { - "examine": "This is a special hops patch.", - "ids": "8861,8862,8863,8864" - }, - { - "examine": "Kelda Hop seeds have been sown in this farming patch.", - "ids": "8865" - }, - { - "examine": "Kelda Hops are growing in this farming patch.", - "ids": "8866,8867,8868" - }, - { - "examine": "These are fully grown Kelda Hops.", - "ids": "8869" - }, - { - "examine": "A barrel of Kelda Stout.", - "ids": "8870" - }, - { - "examine": "This vat contains Kelda hops.", - "ids": "8871" - }, - { - "examine": "Kelda Stout is fermenting in this vat.", - "ids": "8872,8873" - }, - { - "examine": "This vat contains Kelda Stout.", - "ids": "8874,8875,8876,8877" - }, - { - "examine": "Some bizarre mixture between rocks and machinery. Definitely dwarven.", - "ids": "8878" - }, - { - "examine": "A strange box of some kind.", - "ids": "8879" - }, - { - "examine": "A strange box of some kind. It's open.", - "ids": "8880" - }, - { - "examine": "A small cave entrance.", - "ids": "8881,8882,8883,8884,8885" - }, - { - "examine": "Keeps mine carts from rolling away.", - "ids": "8886" - }, - { - "examine": "Cart tracks.", - "ids": "8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898" - }, - { - "examine": "A support for the tracks.", - "ids": "8899,8900,8901,8902,8903,8904,8905,8906,8907,8908,8909" - }, - { - "examine": "These books contain all sorts of data on the Red Axe.", - "ids": "8910" - }, - { - "examine": "Big mysterious crates. You wonder what could be inside.", - "ids": "8911" - }, - { - "examine": "Wooden crates with metal edges, contents unknown.", - "ids": "8912" - }, - { - "examine": "Big mysterious crates. There are some papers on top.", - "ids": "8913,8914,8915,8916,8917" - }, - { - "examine": "A symbol of the Red Axe.", - "ids": "8918,8919,8920,8921,8922,8923" - }, - { - "examine": "A steam powered cart.", - "ids": "8924,8925" - }, - { - "examine": "A short long boat!", - "ids": "8926" - }, - { - "examine": "Best used with a bucket.", - "ids": "8927,8928" - }, - { - "examine": "A deep and terrifying cave.", - "ids": "8929" - }, - { - "examine": "It looks cold in there.", - "ids": "8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,8945,8946,8947,8948,8949" - }, - { - "examine": "A big slimy lump of rock.", - "ids": "8950" - }, - { - "examine": "A slimy lump of rock.", - "ids": "8951" - }, - { - "examine": "A slippery looking rock.", - "ids": "8952,8953" - }, - { - "examine": "A tall flag blowing in the wind.", - "ids": "8954,8955" - }, - { - "examine": "I could climb this if I wanted.", - "ids": "8956,8957" - }, - { - "examine": "There must be some trick to opening this...", - "ids": "8958,8959,8960" - }, - { - "examine": "It's opening...", - "ids": "8961" - }, - { - "examine": "Apparently there was some trick to opening it!", - "ids": "8962" - }, - { - "examine": "Not as difficult to walk through as it was a minute ago.", - "ids": "8963,8964,8965" - }, - { - "examine": "Steps*Leads to the surface.", - "ids": "1337" - }, - { - "examine": "A sturdy looking door, propped shut with a support.", - "ids": "8967,8968,8969,8970,8971" - }, - { - "examine": "A portal back to the real world...", - "ids": "8972" - }, - { - "examine": "One of the most common trees in 2009Scape.", - "ids": "8973" - }, - { - "examine": "A commonly found tree.", - "ids": "8974,8975,8976,8977,8978,8979,8980,8981,8982,8983,8984" - }, - { - "examine": "Steam seems to be condensing into the pot. Neat trick!", - "ids": "8985" - }, - { - "examine": "I can see fish swimming in the water. Well, they sort of look like fish...", - "ids": "8986" - }, - { - "examine": "A portal that leads... somewhere?", - "ids": "8987" - }, - { - "examine": "I wonder what's inside...", - "ids": "8988" - }, - { - "examine": "Someone's looking through the chest.", - "ids": "8989,8990,8991,8992,8993,8994,8995,8996,8997" - }, - { - "examine": "An appendage for activating something.", - "ids": "8998,8999,9000,9001,9002,9003,9004,9005" - }, - { - "examine": "A place to cremate the dead. Needs a body.", - "ids": "9006,9007" - }, - { - "examine": "A place to cremate the dead. Needs a light.", - "ids": "9008,9009" - }, - { - "examine": "This has broad leaves.", - "ids": "9010,9011,9012,9013" - }, - { - "examine": "This has been chopped away.", - "ids": "9014" - }, - { - "examine": "This has broad leaves.", - "ids": "9015,9016,9017,9018" - }, - { - "examine": "This has been chopped away.", - "ids": "9019" - }, - { - "examine": "This has broad leaves.", - "ids": "9020,9021,9022,9023" - }, - { - "examine": "This has been chopped away.", - "ids": "9024" - }, - { - "examine": "A damaged wooden fence.", - "ids": "9025,9026,9027,9028" - }, - { - "examine": "A wooden fence.", - "ids": "9029" - }, - { - "examine": "Gems encrusted in stone.", - "ids": "9030,9031,9032" - }, - { - "examine": "Many rare plants such as this usually have exotic tubers.", - "ids": "9033" - }, - { - "examine": "A beautiful old mahogany tree.", - "ids": "9034" - }, - { - "examine": "This once was a beautiful tree.", - "ids": "9035" - }, - { - "examine": "A beautiful old teak tree.", - "ids": "9036" - }, - { - "examine": "This tree has been cut down.", - "ids": "9037" - }, - { - "examine": "A set of large, sturdy wooden doors.", - "ids": "9038,9039,9040,9041,9042,9043" - }, - { - "examine": "Some goutweed is growing in this patch.", - "ids": "9044,9045,9046,9047" - }, - { - "examine": "Some fully grown goutweed.", - "ids": "9048" - }, - { - "examine": "This goutweed has become diseased.", - "ids": "9049,9050,9051" - }, - { - "examine": "This goutweed has become diseased and died.", - "ids": "9052,9053,9054,9055,9056,9057" - }, - { - "examine": "He's not stocking much.", - "ids": "9058" - }, - { - "examine": "He's stocking rune caskets.", - "ids": "9059" - }, - { - "examine": "He's stocking blackjacks.", - "ids": "9060" - }, - { - "examine": "He's stocking fez hats.", - "ids": "9061" - }, - { - "examine": "He's stocking rune caskets.", - "ids": "9062" - }, - { - "examine": "He's stocking colourful clothes.", - "ids": "9063" - }, - { - "examine": "A wooden crate.", - "ids": "9064,9065" - }, - { - "examine": "A wooden crate containing caskets.", - "ids": "9066,9067" - }, - { - "examine": "A wooden crate containing Blackjacks.", - "ids": "9068,9069" - }, - { - "examine": "A wooden crate containing fez hats.", - "ids": "9070" - }, - { - "examine": "A wooden crate containing clothes.", - "ids": "9071" - }, - { - "examine": "Boxy.", - "ids": "9072,9073" - }, - { - "examine": "boxy", - "ids": "9074,9075" - }, - { - "examine": "This cloth has been dyed.", - "ids": "9076" - }, - { - "examine": "Mmmm pretty!", - "ids": "9077,9078" - }, - { - "examine": "These dyed fabrics are drying off.", - "ids": "9079,9080,9081" - }, - { - "examine": "Items for making clothes are kept on here.", - "ids": "9082" - }, - { - "examine": "Pots full of dye.", - "ids": "9083" - }, - { - "examine": "A way down.", - "ids": "9084" - }, - { - "examine": "There's not much coke in the stove.", - "ids": "9085" - }, - { - "examine": "There's a fair amount of coke in the stove.", - "ids": "9086" - }, - { - "examine": "There's lots of coke in the stove.", - "ids": "9087" - }, - { - "examine": "A big pile of refined coal.", - "ids": "9088" - }, - { - "examine": "You can read the furnace temperature here.", - "ids": "9089" - }, - { - "examine": "Used to pump hot air through the furnace.", - "ids": "9090" - }, - { - "examine": "Bars come out of the blast furnace here.", - "ids": "9091,9092" - }, - { - "examine": "Your bars will come out here.", - "ids": "9093,9094" - }, - { - "examine": "The bars are glowing hot!", - "ids": "9095" - }, - { - "examine": "Your bars are ready to take.", - "ids": "9096" - }, - { - "examine": "They power the conveyor belt.", - "ids": "9097" - }, - { - "examine": "The foreman refers to it as 'Bertha'.", - "ids": "9098" - }, - { - "examine": "It shows that the furnace is working.", - "ids": "9099" - }, - { - "examine": "Ore rides this into the blast furnace.", - "ids": "9100,9101" - }, - { - "examine": "It keeps the conveyor belt running.", - "ids": "9102" - }, - { - "examine": "Fix it, quick!", - "ids": "9103" - }, - { - "examine": "They keep the conveyor belt running.", - "ids": "9104" - }, - { - "examine": "Fix them, quick!", - "ids": "9105" - }, - { - "examine": "It keeps the conveyor belt turning.", - "ids": "9106,9107" - }, - { - "examine": "They keep the conveyor belt turning.", - "ids": "9108,9109,9110,9111,9112,9113,9114" - }, - { - "examine": "It shows that the furnace is working.", - "ids": "9115" - }, - { - "examine": "Hot air circulates through these.", - "ids": "9116" - }, - { - "examine": "Quick, fix them!", - "ids": "9117,9118,9119" - }, - { - "examine": "Hot air circulates through these.", - "ids": "9120" - }, - { - "examine": "Quick, fix them!", - "ids": "9121,9122" - }, - { - "examine": "It shows the furnace is working.", - "ids": "9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137" - }, - { - "examine": "A way upwards.", - "ids": "9138,9139" - }, - { - "examine": "The gate is closed.", - "ids": "9140,9141" - }, - { - "examine": "The gate is open.", - "ids": "9142" - }, - { - "examine": "Used for getting water.", - "ids": "9143" - }, - { - "examine": "Some kind of jewellery is dangling from this ornament.", - "ids": "9144" - }, - { - "examine": "Someone's showing off their wealth!", - "ids": "9145" - }, - { - "examine": "Filled to the brim with knowledge.", - "ids": "9146,9147" - }, - { - "examine": "A nicely carved wooden chair.", - "ids": "9148" - }, - { - "examine": "An expensive privacy aid!", - "ids": "9149" - }, - { - "examine": "An old wall.", - "ids": "9150" - }, - { - "examine": "Security breach!", - "ids": "9151" - }, - { - "examine": "A patched up hole.", - "ids": "9152,9153,9154" - }, - { - "examine": "'You are here.'", - "ids": "9155" - }, - { - "examine": "An elegant desk with a curious ornament on it.", - "ids": "9156" - }, - { - "examine": "Someone's gold-trimmed this Saradomin armour!", - "ids": "9157,9158" - }, - { - "examine": "Lit to remember the souls of the departed.", - "ids": "9159,9160,9161,9162,9163,9164,9165" - }, - { - "examine": "You can grow delphiniums in this Farming patch.", - "ids": "9166,9167,9168,9169" - }, - { - "examine": "Delphinium seeds have been sown in this farming patch.", - "ids": "9170" - }, - { - "examine": "Beautiful.", - "ids": "9171,9172" - }, - { - "examine": "These delphiniums are fully grown.", - "ids": "9173,9174,9175,9176" - }, - { - "examine": "You can grow a pink rose bush in this patch.", - "ids": "9177,9178,9179,9180" - }, - { - "examine": "You can grow a white rose bush in this patch.", - "ids": "9181,9182,9183,9184" - }, - { - "examine": "You can grow a red rose bush in this patch.", - "ids": "9185,9186,9187,9188" - }, - { - "examine": "A rose bush.", - "ids": "9189,9190,9191" - }, - { - "examine": "This white rosebush is fully grown.", - "ids": "9192" - }, - { - "examine": "A rose bush.", - "ids": "9193" - }, - { - "examine": "This red rosebush is fully grown.", - "ids": "9194" - }, - { - "examine": "A pink rosebush.", - "ids": "9195" - }, - { - "examine": "This pink rosebush is fully grown.", - "ids": "9196,9197,9198" - }, - { - "examine": "A plantpot of pink orchids.", - "ids": "9199,9200,9201" - }, - { - "examine": "These pink orchids are fully grown.", - "ids": "9202" - }, - { - "examine": "An empty plantpot.", - "ids": "9203" - }, - { - "examine": "A plantpot filled with soil.", - "ids": "9204" - }, - { - "examine": "A plantpot of yellow orchids.", - "ids": "9205,9206,9207" - }, - { - "examine": "These yellow orchids are fully grown.", - "ids": "9208,9209" - }, - { - "examine": "You can grow a White Tree in this patch.", - "ids": "9210,9211,9212,9213" - }, - { - "examine": "A White Tree sapling has been planted in this patch.", - "ids": "9214" - }, - { - "examine": "A White Tree is growing in this patch.", - "ids": "9215,9216,9217" - }, - { - "examine": "This White Tree is fully grown.", - "ids": "9218" - }, - { - "examine": "This White Tree bears a single fruit.", - "ids": "9219" - }, - { - "examine": "This White Tree bears two fruits.", - "ids": "9220" - }, - { - "examine": "This White Tree bears three fruits.", - "ids": "9221" - }, - { - "examine": "This White Tree bears four fruits.", - "ids": "9222,9223" - }, - { - "examine": "You can grow snowdrops in this Farming patch.", - "ids": "9224,9225,9226,9227" - }, - { - "examine": "A patch of snowdrops.", - "ids": "9228,9229,9230" - }, - { - "examine": "These snowdrops are fully grown.", - "ids": "9231,9232" - }, - { - "examine": "You can grow Burthorpe Vine in this patch.", - "ids": "9233" - }, - { - "examine": "You can grow Burthorpe Vines in this patch.", - "ids": "9234,9235,9236" - }, - { - "examine": "Burthorpe vines are growing in this patch.", - "ids": "9237,9238,9239" - }, - { - "examine": "These Burthorpe vines are fully grown.", - "ids": "9240" - }, - { - "examine": "An empty plinth for a statue.", - "ids": "9241,9242" - }, - { - "examine": "What a good likeness!", - "ids": "9243" - }, - { - "examine": "An empty plinth for a statue.", - "ids": "9244" - }, - { - "examine": "An expertly carved statue of a former King of Misthalin.", - "ids": "9245" - }, - { - "examine": "An empty plinth for a statue.", - "ids": "9246" - }, - { - "examine": "What a good likeness!", - "ids": "9247" - }, - { - "examine": "An empty plinth for a statue.", - "ids": "9248" - }, - { - "examine": "An expertly carved statue of a former King of Misthalin.", - "ids": "9249,9250,9251,9252,9253,9254" - }, - { - "examine": "These grapevines look much healthier now.", - "ids": "9255" - }, - { - "examine": "These grapevines are suffering from some strange disease.", - "ids": "9256" - }, - { - "examine": "Some wild-looking grass.", - "ids": "9257,9258,9259" - }, - { - "examine": "Some red roses.", - "ids": "9260" - }, - { - "examine": "Some pink roses.", - "ids": "9261" - }, - { - "examine": "Some white roses.", - "ids": "9262" - }, - { - "examine": "A White Tree.", - "ids": "9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,9290" - }, - { - "examine": "Sit back and enjoy the view.", - "ids": "9291" - }, - { - "examine": "An expertly carved statue of a former Queen of Misthalin.", - "ids": "9292" - }, - { - "examine": "Funny looking holes that don't look too inviting.", - "ids": "9294" - }, - { - "examine": "A rocky outcrop.", - "ids": "9296,9297,9298" - }, - { - "examine": "Ornate railing.", - "ids": "9299" - }, - { - "examine": "Wooden fencing.", - "ids": "9300" - }, - { - "examine": "A well constructed castle wall.", - "ids": "9301" - }, - { - "examine": "A rather strategically placed hole, which appears to be in the ground.", - "ids": "9302" - }, - { - "examine": "A rocky outcrop.", - "ids": "9303,9304,9305,9306" - }, - { - "examine": "A well weathered wall.", - "ids": "9307,9308" - }, - { - "examine": "A tunnel leading under the wall.", - "ids": "9309,9310" - }, - { - "examine": "An underwall tunnel.", - "ids": "9311,9312" - }, - { - "examine": "Looks suspicious.", - "ids": "9313" - }, - { - "examine": "A wall jutting out into the path.", - "ids": "9314" - }, - { - "examine": "I can jump from this stepping stone.", - "ids": "9315" - }, - { - "examine": "A rocky outcrop.", - "ids": "9316,9317,9318" - }, - { - "examine": "A chain rope", - "ids": "9319,9320" - }, - { - "examine": "A few rocks short of a wall", - "ids": "9321" - }, - { - "examine": "The foam from the river makes this log very slippy.", - "ids": "9322,9323,9324" - }, - { - "examine": "Just another crack in the wall.", - "ids": "9325" - }, - { - "examine": "Funny looking holes that don't look too inviting.", - "ids": "9326" - }, - { - "examine": "They seem to fit in the with the rocky surroundings, so as not to stick out.", - "ids": "9327" - }, - { - "examine": "A slippery well worn log.", - "ids": "9328,9329,9330" - }, - { - "examine": "A rocky outcrop.", - "ids": "9331,9332,9333" - }, - { - "examine": "Used to be ornate, now it's a little bit vandalised.", - "ids": "9334" - }, - { - "examine": "A rocky outcrop.", - "ids": "9335,9336" - }, - { - "examine": "Used to be ornate, now it's a little bit vandalised.", - "ids": "9337" - }, - { - "examine": "Should scare off the birds...", - "ids": "9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9352,9353" - }, - { - "examine": "This looks like the way out.", - "ids": "9354" - }, - { - "examine": "A cave deep into the volcano.", - "ids": "9355" - }, - { - "examine": "A cave deeper into the volcano.", - "ids": "9356,9357" - }, - { - "examine": "A cave deep into the volcano.", - "ids": "9358" - }, - { - "examine": "This looks like the way out.", - "ids": "9359,9360,9361,9362,9363,9364,9365" - }, - { - "examine": "The barrier of heat is down.", - "ids": "9366" - }, - { - "examine": "A barrier of heat.", - "ids": "9367,9368,9369,9370,9371,9372,9373" - }, - { - "examine": "Hot enough to cook your breakfast on.", - "ids": "9374,9375,9376" - }, - { - "examine": "An egg incubated in the lava.", - "ids": "9377,9378,9379" - }, - { - "examine": "Who's the man?", - "ids": "9380" - }, - { - "examine": "A wooden crate.", - "ids": "9381" - }, - { - "examine": "Some wooden crates.", - "ids": "9382,9383,9384,9385,9386,9387,9388,9389" - }, - { - "examine": "A natural forge using volcanic heat.", - "ids": "9390" - }, - { - "examine": "I spy with my little eye...", - "ids": "9391,9392,9393,9394,9395,9396,9397" - }, - { - "examine": "Lets you put items into your bank.", - "ids": "9398,9399,26969,36788" - }, - { - "examine": "Sparse weeds.", - "ids": "9400" - }, - { - "examine": "Weeds.", - "ids": "9401" - }, - { - "examine": "Thick weeds.", - "ids": "9402" - }, - { - "examine": "This is Unferth's patch for growing potatos.", - "ids": "9403" - }, - { - "examine": "You say Potato, I say Poh-tar-to.", - "ids": "9404,9405,9406,9407" - }, - { - "examine": "Looks like these potatoes have fully grown.", - "ids": "9408,9409,9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9424,9425,9426,9427,9428,9429" - }, - { - "examine": "A nice sturdy bare table.", - "ids": "9430" - }, - { - "examine": "A nice sturdy table.", - "ids": "9431" - }, - { - "examine": "A table with milk.", - "ids": "9432" - }, - { - "examine": "A table with cake.", - "ids": "9433" - }, - { - "examine": "A hearty meal for Unferth.", - "ids": "9434,9435" - }, - { - "examine": "Great for sleeping in.", - "ids": "9436" - }, - { - "examine": "Not so great for sleeping in, it's not made.", - "ids": "9437,9438" - }, - { - "examine": "A fire burns brightly here.", - "ids": "9439" - }, - { - "examine": "An empty fire place.", - "ids": "9440" - }, - { - "examine": "An unlit fire place.", - "ids": "9441,9442" - }, - { - "examine": "A good source of books!", - "ids": "9443,9444,9445,9446,9447,9448,9449,9450,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469" - }, - { - "examine": "I can climb these stairs.", - "ids": "9470" - }, - { - "examine": "They go down.", - "ids": "9471" - }, - { - "examine": "What could be down here?", - "ids": "9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497" - }, - { - "examine": "A small plant, suitable for sandy soil.", - "ids": "9498" - }, - { - "examine": "A decorative plant.", - "ids": "9499" - }, - { - "examine": "A fairly small plant.", - "ids": "9500" - }, - { - "examine": "Another plant.", - "ids": "9501,9502,9503,9504,9505,9506,9507" - }, - { - "examine": "Perfect for snoozing in the sun.", - "ids": "9508" - }, - { - "examine": "Lovely comfy-looking big bed.", - "ids": "9509" - }, - { - "examine": "East to Draynor Village :: South to Rimmington :: South-east to Port Sarim.", - "ids": "9510,9511,9512,9513" - }, - { - "examine": "Betty's chair.", - "ids": "9514" - }, - { - "examine": "I wonder what she's making?", - "ids": "9515" - }, - { - "examine": "Betty's counter.", - "ids": "9516,9517,9518" - }, - { - "examine": "A wooden barrel for storage.", - "ids": "9519" - }, - { - "examine": "A wooden barrel containing lots of fish.", - "ids": "9520" - }, - { - "examine": "A wooden barrel for storage.", - "ids": "9521" - }, - { - "examine": "How much does this weigh?", - "ids": "9522" - }, - { - "examine": "A case. With books.", - "ids": "9523" - }, - { - "examine": "A mooring chain.", - "ids": "9524" - }, - { - "examine": "One horsepower; wooden suspension: a beauty.", - "ids": "9525" - }, - { - "examine": "Betty keeps some rune objects here.", - "ids": "9526,9527,9528,9529" - }, - { - "examine": "A sinister fungus.", - "ids": "9530" - }, - { - "examine": "Sit back and relax...", - "ids": "9531" - }, - { - "examine": "Sit back and enjoy the view.", - "ids": "9532" - }, - { - "examine": "A wooden crate.", - "ids": "9533,9534" - }, - { - "examine": "Some wooden crates.", - "ids": "9535" - }, - { - "examine": "Some wooden boxes.", - "ids": "9536" - }, - { - "examine": "It's used for loading and unloading fishing boats.", - "ids": "9537" - }, - { - "examine": "I hope it doesn't sink.", - "ids": "9538,9539,9540,9541,9542,9543,9544,9545,9546,9547" - }, - { - "examine": "A bucket full of red hot coals.", - "ids": "9548,9549,9550,9551,9552,9553,9554,9555,9556,9557" - }, - { - "examine": "It leads up.", - "ids": "9558" - }, - { - "examine": "I can climb down this.", - "ids": "9559,9560" - }, - { - "examine": "I guess I could sleep in it if I were really tired.", - "ids": "9561" - }, - { - "examine": "A prison cell door.", - "ids": "9562" - }, - { - "examine": "A locked prison cell door.", - "ids": "9563" - }, - { - "examine": "A prison cell door.", - "ids": "9564" - }, - { - "examine": "Stops people getting out.", - "ids": "9565,9566" - }, - { - "examine": "Ewww!", - "ids": "9567" - }, - { - "examine": "En-suite facilities in every cell!", - "ids": "9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581" - }, - { - "examine": "I can climb up these stairs.", - "ids": "9582,9583" - }, - { - "examine": "I can climb down these stairs.", - "ids": "9584,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603" - }, - { - "examine": "A leafy plant.", - "ids": "9604" - }, - { - "examine": "A leafy fern.", - "ids": "9605" - }, - { - "examine": "A leafy shrub.", - "ids": "9606" - }, - { - "examine": "A case. With books.", - "ids": "9607,9608,9609" - }, - { - "examine": "An artist's easel.", - "ids": "9610" - }, - { - "examine": "A good source of books!", - "ids": "9611" - }, - { - "examine": "The Make-over Mage's bed.", - "ids": "9612" - }, - { - "examine": "A nice sturdy looking table.", - "ids": "9613" - }, - { - "examine": "Generally used for putting things on.", - "ids": "9614" - }, - { - "examine": "A small wooden table.", - "ids": "9615" - }, - { - "examine": "Items are for sale here.", - "ids": "9616" - }, - { - "examine": "All-purpose storage.", - "ids": "9617,9618,9619,9620" - }, - { - "examine": "For sitting.", - "ids": "9621" - }, - { - "examine": "Fancy.", - "ids": "9622,9623" - }, - { - "examine": "It's like a land rudder.", - "ids": "9624" - }, - { - "examine": "A wooden wheelbarrow.", - "ids": "9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660" - }, - { - "examine": "This tree has been cut down.", - "ids": "9661" - }, - { - "examine": "Popular with farmers and treasure hunters.", - "ids": "9662" - }, - { - "examine": "This tree has fallen to the ground.", - "ids": "9663" - }, - { - "examine": "A gnarly old tree root.", - "ids": "9664" - }, - { - "examine": "The roots of a tree are exposed.", - "ids": "9665" - }, - { - "examine": "I hope I don't trip over any of these.", - "ids": "9666" - }, - { - "examine": "Disturbingly man-like.", - "ids": "9667" - }, - { - "examine": "Its eyes stare off into the distance...", - "ids": "9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,9680,9681" - }, - { - "examine": "Expels smoke from the range.", - "ids": "9683" - }, - { - "examine": "Wash your hands!", - "ids": "9684" - }, - { - "examine": "Generally used for putting things on.", - "ids": "9685" - }, - { - "examine": "Some fabric ready for clothing.", - "ids": "9686" - }, - { - "examine": "I'm guessing it's for making women's clothes.", - "ids": "9687,9688" - }, - { - "examine": "Looks like it's for making men's clothes.", - "ids": "9689" - }, - { - "examine": "I think this one's for making men's clothes.", - "ids": "9690,9691,9692,9693" - }, - { - "examine": "Some helpful people have placed notes on here, how nice.", - "ids": "9694" - }, - { - "examine": "This notice board is full of scrolls and charts.", - "ids": "9695" - }, - { - "examine": "I wonder what's inside ?", - "ids": "9696" - }, - { - "examine": "A nice sturdy looking table.", - "ids": "9697,9698,9699,9700,9701" - }, - { - "examine": "This clearly isn't used for dining very often.", - "ids": "9702" - }, - { - "examine": "Not as nice as some.", - "ids": "9703" - }, - { - "examine": "This needs dusting before I'll sit on it.", - "ids": "9704,9705" - }, - { - "examine": "This must let me in to the arena somehow...", - "ids": "9706" - }, - { - "examine": "This must let me out of the arena somehow...", - "ids": "9707" - }, - { - "examine": "A rocky outcrop.", - "ids": "9708,9709,9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9737" - }, - { - "examine": "An old crumbled pillar.", - "ids": "9738,9739,9740" - }, - { - "examine": "Smells like fish.", - "ids": "9741,9742,9743" - }, - { - "examine": "I can climb up here.", - "ids": "9744" - }, - { - "examine": "I can go below decks with this ladder.", - "ids": "9745,9746,9747" - }, - { - "examine": "A collection point.", - "ids": "9748" - }, - { - "examine": "A Lever.", - "ids": "9749,9750" - }, - { - "examine": "A crystal that was broken a long time ago.", - "ids": "9751" - }, - { - "examine": "A repowered crystal.", - "ids": "9752" - }, - { - "examine": "Perhaps I should search it.", - "ids": "9753" - }, - { - "examine": "I wonder what's inside.", - "ids": "9754" - }, - { - "examine": "Perhaps I should search it.", - "ids": "9755" - }, - { - "examine": "I wonder what's inside.", - "ids": "9756" - }, - { - "examine": "Perhaps I should search it.", - "ids": "9757" - }, - { - "examine": "I wonder what's inside.", - "ids": "9758" - }, - { - "examine": "Perhaps I should search it.", - "ids": "9759" - }, - { - "examine": "I wonder what's inside.", - "ids": "9760" - }, - { - "examine": "Perhaps I should search it.", - "ids": "9761" - }, - { - "examine": "I wonder what's inside.", - "ids": "9762" - }, - { - "examine": "A recently killed guard.", - "ids": "9763,9764,9765" - }, - { - "examine": "A recently killed slave.", - "ids": "9766,9767" - }, - { - "examine": "A door of pure light!", - "ids": "9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,9890,9891,9892,9893,9894,9895,9896,9897" - }, - { - "examine": "There are holes passing through this pillar.", - "ids": "9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,9965,9966,9967,9968,9969,9970,9971,9972,9973,9974" - }, - { - "examine": "I can climb down these.", - "ids": "9975" - }, - { - "examine": "A cave wall.", - "ids": "9976" - }, - { - "examine": "I wonder where this goes?", - "ids": "9977" - }, - { - "examine": "A ladder carved into the wall.", - "ids": "9978,9979" - }, - { - "examine": "A good place for light to merge.", - "ids": "9980" - }, - { - "examine": "A good place for a light crystal.", - "ids": "9981,9982,9983,9984,9985,9986,9987" - }, - { - "examine": "A broken pillar.", - "ids": "9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001" - }, { "examine": "An ancient elvish light doorway.", "ids": "10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013" @@ -14071,6 +55,10 @@ "examine": "A way up.", "ids": "10038,10039,10040" }, + { + "examine": "This section of railing has been broken", + "ids": "1004,1005" + }, { "examine": "The legs probably aren't a natural feature of the tree.", "ids": "10041,10042,10043,10044,10045,10046,10047,10048,10049,10050,10051,10052,10053" @@ -14087,6 +75,10 @@ "examine": "Flag, pole... Yep, it's a flagpole.", "ids": "10057,10058,10059,10060,10061" }, + { + "examine": "There is a hole in this section of the railing.", + "ids": "1006,1007,1008,1009" + }, { "examine": "This must be climbed over.", "ids": "10062" @@ -14151,6 +143,14 @@ "examine": "Almost clear.", "ids": "10099" }, + { + "examine": "I can climb this.", + "ids": "101" + }, + { + "examine": "Someone was thirsty...", + "ids": "1010" + }, { "examine": "Free from weeds.", "ids": "10100" @@ -14171,10 +171,18 @@ "examine": "A stagnant lake.", "ids": "10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,10128" }, + { + "examine": "Full of lovely drinks!", + "ids": "1011,1012" + }, { "examine": "A very large pipe.", "ids": "10129,10130,10131,10132,10133,10134,10135" }, + { + "examine": "Storage for cookery items.", + "ids": "1013,32283,40055" + }, { "examine": "Rickety.", "ids": "10136,10137" @@ -14187,6 +195,10 @@ "examine": "It's a palm tree.", "ids": "10139,10140,10141" }, + { + "examine": "Storage for all needs.", + "ids": "1014,1015,1016,1017,1018,10495,10496,10497,10498,11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779,11780,11781,12980,30648,30649,30650,32284,40045,40046,40047" + }, { "examine": "This controls the entire brewery.", "ids": "10142" @@ -14283,10 +295,30 @@ "examine": "A lit torch.", "ids": "10179,10180,10181,10182,10183,10184,10185,10186,10187,10188,10189,10190,10191,10192" }, + { + "examine": "What kind of sick person keeps a skull on their wall?", + "ids": "1019" + }, { "examine": "A sturdy iron frame, for climbing up and down.", "ids": "10193,10194,10195,10196,10197,10198,10199,10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,10236,10237,10238,10239,10240,10241,10242,10243,10244,10245" }, + { + "examine": "A sturdy door.", + "ids": "102" + }, + { + "examine": "Esoteric artefacts.", + "ids": "1020" + }, + { + "examine": "I don't want to know what's in those little urns.", + "ids": "1021,1022,1023" + }, + { + "examine": "Used for storing things on.", + "ids": "1024" + }, { "examine": "Once upon a time this was used to make pottery.", "ids": "10246" @@ -14299,6 +331,10 @@ "examine": "There was a lot of pottery made here a long time ago.", "ids": "10248,10249" }, + { + "examine": "Tailor made for needlework supplies", + "ids": "1025,1026" + }, { "examine": "Eric's been killed by stones falling from the ceiling!", "ids": "10250" @@ -14367,6 +403,10 @@ "examine": "A display of various relics.", "ids": "10269,10270,10271,10272" }, + { + "examine": "Prepared hides hang here drying.", + "ids": "1027" + }, { "examine": "A collection of rare books.", "ids": "10273" @@ -14383,6 +423,10 @@ "examine": "It's some crates.", "ids": "10279,10280" }, + { + "examine": "This contains dye for leather.", + "ids": "1028,1029" + }, { "examine": "It's a crate.", "ids": "10281" @@ -14439,6 +483,14 @@ "examine": "Opens the rat door.", "ids": "10299" }, + { + "examine": "I wonder what's inside.", + "ids": "103" + }, + { + "examine": "Used to squeeze moisture from the hide.", + "ids": "1030,1031" + }, { "examine": "Contains many rats.", "ids": "10300" @@ -14515,6 +567,10 @@ "examine": "Handy piece of garden decor.", "ids": "10319" }, + { + "examine": "Danger!", + "ids": "1032,5127" + }, { "examine": "Big enough for a cat to get in.", "ids": "10320" @@ -14547,6 +603,10 @@ "examine": "A magical device that enables one to walk through walls.", "ids": "10327,10328,10329,10330,10331,10332,10333,10334" }, + { + "examine": "This tells you which way is which.", + "ids": "1033,1034,1035" + }, { "examine": "Observe the rats.", "ids": "10335,10336,10337,10338,10339,10340,10341,10342,10343,10344,10345" @@ -14631,6 +691,10 @@ "examine": "It's empty.", "ids": "10386,10387,10388,10389,10390,10391,10392,10393,10394,10395,10396,10397,10398,10399,10400,10401" }, + { + "examine": "Perhaps I should search it.", + "ids": "104" + }, { "examine": "It looks like water once ran here.", "ids": "10402,10403" @@ -14755,6 +819,10 @@ "examine": "A small potted plant.", "ids": "10499" }, + { + "examine": "I wonder what that's there for...", + "ids": "105,106" + }, { "examine": "Someone has planted this.", "ids": "10500" @@ -14907,6 +975,10 @@ "examine": "A banner proclaiming your victory over the Giant Champion!", "ids": "10568,10569" }, + { + "examine": "Ye olde Shrimp and Parrot.", + "ids": "1057" + }, { "examine": "A banner proclaiming your victory over the Goblin Champion!", "ids": "10570,10571" @@ -15079,6 +1151,10 @@ "examine": "A box containing unpainted decorations.", "ids": "10679,10680,10681,10682,10683,10684,10685" }, + { + "examine": "The Blue Moon Inn", + "ids": "1068" + }, { "examine": "Box containing blue puppet heads.", "ids": "10686" @@ -15095,6 +1171,10 @@ "examine": "Box containing blue puppet legs.", "ids": "10689" }, + { + "examine": "The Jolly Boar", + "ids": "1069" + }, { "examine": "Box containing red puppet heads.", "ids": "10690" @@ -15135,6 +1215,10 @@ "examine": "You can climb up these.", "ids": "10699,10700" }, + { + "examine": "The Rusty Anchor", + "ids": "1070" + }, { "examine": "A blue crate. Probably containing puppets.", "ids": "10701" @@ -15163,10 +1247,18 @@ "examine": "A wooden ladder.", "ids": "10707,10708,10709" }, + { + "examine": "The Shrimp and Parrot", + "ids": "1071" + }, { "examine": "Pots full of paint.", "ids": "10710,10711,10712,10713,10714,10715,10716,10717,10718,10719,10720" }, + { + "examine": "The Dead Man's Chest", + "ids": "1072" + }, { "examine": "A doorway made of light.", "ids": "10721" @@ -15183,6 +1275,10 @@ "examine": "A pile of animal Bones.", "ids": "10725,10726,10727,10728,10729,10730,10731,10732" }, + { + "examine": "The Rising Sun", + "ids": "1073" + }, { "examine": "Hidden away, I wonder where it goes?", "ids": "10733" @@ -15207,10 +1303,26 @@ "examine": "A statue representing air.", "ids": "10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751,10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,10764,10765,10766,10767" }, + { + "examine": "The Forester's Arms", + "ids": "1074" + }, + { + "examine": "The Flying Horse", + "ids": "1075" + }, + { + "examine": "The Dancing Donkey", + "ids": "1076" + }, { "examine": "A place to put your money.", "ids": "10768,10769,10770" }, + { + "examine": "The Dragon Inn", + "ids": "1077" + }, { "examine": "Stairs.", "ids": "10771,10772,10773,10774,10775,10776,10777" @@ -15223,6 +1335,10 @@ "examine": "A teleport to the Enchanting Chamber.", "ids": "10779" }, + { + "examine": "Karamja Spirits bar", + "ids": "1078" + }, { "examine": "A teleport to the Alchemists' Playground.", "ids": "10780" @@ -15239,10 +1355,18 @@ "examine": "This may be worth opening.", "ids": "10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798" }, + { + "examine": "North to Varrock :: East to Al-Kharid.", + "ids": "1079" + }, { "examine": "Some simple cubes.", "ids": "10799" }, + { + "examine": "North road to Draynor Village :: East road to Varrock.", + "ids": "1080" + }, { "examine": "A pile of cylindrical shapes.", "ids": "10800" @@ -15279,6 +1403,10 @@ "examine": "A bin full of paper.", "ids": "10809,10810,10811,10812" }, + { + "examine": "North to Draynor Village.", + "ids": "1081" + }, { "examine": "Betty's counter. There is a vial standing on it.", "ids": "10813" @@ -15295,6 +1423,10 @@ "examine": "Doesn't look like the way out.", "ids": "10818,10819" }, + { + "examine": "North to Draynor Manor :: West to Asgarnia.", + "ids": "1082" + }, { "examine": "A glowing barrier of energy prevents your escape.", "ids": "10820,10821,10822,10823" @@ -15311,10 +1443,22 @@ "examine": "Smells like fish.", "ids": "10828,10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847" }, + { + "examine": "South to the Wizards' Tower :: East to Lumbridge.", + "ids": "1083" + }, + { + "examine": "South to Lumbridge :: West to Varrock :: East to the Digsite.", + "ids": "1084" + }, { "examine": "This leads to a tunnel too steep for me to scale.", "ids": "10848,10849,10850" }, + { + "examine": "South to Al-Kharid :: West to Lumbridge :: East to the Digsite.", + "ids": "1085" + }, { "examine": "I can climb this rocky outcrop.", "ids": "10851" @@ -15339,6 +1483,10 @@ "examine": "A gap.", "ids": "10859" }, + { + "examine": "North to Varrock :: East to the Digsite.", + "ids": "1086" + }, { "examine": "A narrow ledge.", "ids": "10860" @@ -15355,10 +1503,18 @@ "examine": "A wooden plank.", "ids": "10867,10868,10869,10870,10871,10872,10873,10874" }, + { + "examine": "South to the Wizards' Tower :: North to Draynor Village :: East to Lumbridge.", + "ids": "1087" + }, { "examine": "A stone block.", "ids": "10875,10876,10877,10878,10879,10880,10881" }, + { + "examine": "The ideal thing to sit on.", + "ids": "1088,1115,3801,5345,5614,7385,7386,7387,10491,11489,12885,12886,13582,32032,36830,40039" + }, { "examine": "A gap.", "ids": "10882,10883,10884,10885" @@ -15367,6 +1523,18 @@ "examine": "A narrow ledge.", "ids": "10886,10887,10888,10889,10890,10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943" }, + { + "examine": "Not so good for sitting on.", + "ids": "1089" + }, + { + "examine": "A comfortable seat.", + "ids": "1090,1091,1092,11760,13583,13584,13585,13586,13587,32286" + }, + { + "examine": "Good for sitting on.", + "ids": "1093,1094,1095,1102,5880,10492,12440,12441,12973,32033" + }, { "examine": "A rocky outcrop.", "ids": "10944,10945,10946,10947,10948,10949" @@ -15391,10 +1559,18 @@ "examine": "Made of sandstone and granite.", "ids": "10958,10959,10960,10961" }, + { + "examine": "Good for rocking in!", + "ids": "1096" + }, { "examine": "A large statue.", "ids": "10962,10963,10964,10965,10966,10967,10968,10969,10970" }, + { + "examine": "A kingly seat for a royal behind.", + "ids": "1097,1098,1099,1105,1108,1109,32285" + }, { "examine": "It has no limbs.", "ids": "10971" @@ -15507,6 +1683,14 @@ "examine": "The shadow and smoke globes are lit.", "ids": "10999" }, + { + "examine": "I can climb up this.", + "ids": "11" + }, + { + "examine": "The perfect way to sit at the bar.", + "ids": "1100,1101" + }, { "examine": "The ice, shadow and smoke globes are lit.", "ids": "11000" @@ -15555,6 +1739,10 @@ "examine": "A finished wall.", "ids": "11028,11029,11030,11031" }, + { + "examine": "Gnomes sit on these.", + "ids": "1103" + }, { "examine": "A nearly finished wall.", "ids": "11032,11033" @@ -15571,6 +1759,10 @@ "examine": "A ruined wall.", "ids": "11038,11039" }, + { + "examine": "Gnomes are found sitting here.", + "ids": "1104" + }, { "examine": "A pile of bricks dislodged from the wall nearby.", "ids": "11040" @@ -15615,6 +1807,10 @@ "examine": "There's a recess on the top shaped like a head.", "ids": "11059" }, + { + "examine": "Sit back and relax...", + "ids": "1106,1107" + }, { "examine": "There's a sigil on it shaped like a Z.", "ids": "11060" @@ -15675,6 +1871,14 @@ "examine": "A rock.", "ids": "11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111" }, + { + "examine": "Used for sitting on.", + "ids": "1110" + }, + { + "examine": "Do I dare sit on this?", + "ids": "1111" + }, { "examine": "This tree has long been dead.", "ids": "11112" @@ -15683,6 +1887,18 @@ "examine": "A dried up bush, void of life.", "ids": "11113,11114,11115,11116,11117,11118,11119,11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,11136,11137,11138,11139,11140" }, + { + "examine": "Church seating.", + "ids": "1112" + }, + { + "examine": "Park it here...", + "ids": "1113" + }, + { + "examine": "Wouldn't like to sit on that for too long...", + "ids": "1114" + }, { "examine": "He's been trapped in there for a long time.", "ids": "11141,11142,11143,11144,11145,11146,11147,11148,11149,11150" @@ -15699,6 +1915,10 @@ "examine": "A simple stone pedestal.", "ids": "11153,11154,11155,11156,11157,11158,11159,11160,11161" }, + { + "examine": "Keeps the neighbours out!", + "ids": "1116,1117" + }, { "examine": "A big grinding thing.", "ids": "11162,11163,11164" @@ -15707,6 +1927,14 @@ "examine": "A rocky outcrop.", "ids": "11165,11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,11181,11182,11183,11184,11185,11186,11187,11188,11189,11190,11191,11192,11193,11194,11195" }, + { + "examine": "Found in wild areas.", + "ids": "1118" + }, + { + "examine": "These are commonly found.", + "ids": "1119" + }, { "examine": "An elf-fashioned door.", "ids": "11196,11197" @@ -15719,6 +1947,10 @@ "examine": "The ladder back to the Runeversi challenge room.", "ids": "11199" }, + { + "examine": "An unusual bush.", + "ids": "1120" + }, { "examine": "The ladder to the Runesquares challenge room for experienced players.", "ids": "11200" @@ -15759,6 +1991,10 @@ "examine": "Permission to board?", "ids": "11209,11210,11211,11212,11213" }, + { + "examine": "A wild bush.", + "ids": "1121" + }, { "examine": "Ready...aim...fire!", "ids": "11214" @@ -15779,6 +2015,10 @@ "examine": "If I can't destroy this we're sunk.", "ids": "11219" }, + { + "examine": "All the leaves have fallen off.", + "ids": "1122,1123" + }, { "examine": "Let's hope they don't repair it.", "ids": "11220,11221,11222,11223,11224,11225,11226,11227" @@ -15811,6 +2051,10 @@ "examine": "I wouldn't be surprised if bits land over in Lumbridge.", "ids": "11239" }, + { + "examine": "A commonly found bush.", + "ids": "1124,36782" + }, { "examine": "Rigged to blow.", "ids": "11240,11241,11242,11243" @@ -15831,6 +2075,14 @@ "examine": "Cannons. Lots of cannons.", "ids": "11248,11249,11250,11251,11252,11253,11254,11255,11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272,11273,11274,11275" }, + { + "examine": "Bushy!", + "ids": "1125" + }, + { + "examine": "A rose by any other name would still have prickly bits.", + "ids": "1126" + }, { "examine": "Holds up the sails.", "ids": "11276,11277,11278,11279" @@ -16047,6 +2299,10 @@ "examine": "Interface button up.", "ids": "11399" }, + { + "examine": "An appliance for cooking with.", + "ids": "114" + }, { "examine": "Interface button down.", "ids": "11400" @@ -16059,6 +2315,10 @@ "examine": "Interface button right.", "ids": "11402" }, + { + "examine": "The bank teller will serve you from here.", + "ids": "11402" + }, { "examine": "Interface button ignite.", "ids": "11403" @@ -16099,6 +2359,10 @@ "examine": "A rocky outcrop.", "ids": "11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448" }, + { + "examine": "A leafy bush.", + "ids": "1144,1145,1146" + }, { "examine": "This door is locked.", "ids": "11449" @@ -16163,6 +2427,10 @@ "examine": "Disturbingly its eyes look everywhere in the room except at you.", "ids": "11469" }, + { + "examine": "The abode of a fairy.", + "ids": "1147,1148,1149" + }, { "examine": "The door is closed.", "ids": "11470" @@ -16239,6 +2507,14 @@ "examine": "These stairs look spooky!", "ids": "11499" }, + { + "examine": "A party balloon.", + "ids": "115,116,117,118,119,120" + }, + { + "examine": "Fairies need money too!", + "ids": "1150" + }, { "examine": "A filthy but sturdy looking table.", "ids": "11500" @@ -16247,6 +2523,10 @@ "examine": "I'm not eating off that.", "ids": "11501,11502,11503,11504,11505,11506,11507,11508,11509" }, + { + "examine": "A fairy is selling items here.", + "ids": "1151" + }, { "examine": "This tree has long been dead.", "ids": "11510" @@ -16255,10 +2535,26 @@ "examine": "I can climb up these stairs.", "ids": "11511,11512,11513,11514,11515,11516,11517,11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,11530,11531,11532,11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545" }, + { + "examine": "A small potted plant.", + "ids": "1152" + }, + { + "examine": "Someone has planted this.", + "ids": "1153" + }, + { + "examine": "A nicely potted fern.", + "ids": "1154" + }, { "examine": "It's a strange machine.", "ids": "11546,11547,11548,11549,11550" }, + { + "examine": "Better than weeding.", + "ids": "1155" + }, { "examine": "It's a table for putting objects on.", "ids": "11551" @@ -16267,6 +2563,14 @@ "examine": "A rocky outcrop.", "ids": "11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,11588" }, + { + "examine": "I bet bees like this.", + "ids": "1156,1157" + }, + { + "examine": "A large potted plant.", + "ids": "1158,1159" + }, { "examine": "A wooden barrel for storage.", "ids": "11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,29333" @@ -16275,6 +2579,10 @@ "examine": "A wooden crate.", "ids": "11599" }, + { + "examine": "A plant in a bamboo pot.", + "ids": "1160" + }, { "examine": "Convenient for storage.", "ids": "11600" @@ -16291,6 +2599,10 @@ "examine": "A simple torch stuck in the ground.", "ids": "11606,11607,11608,11609,11610,11611,11612,11613" }, + { + "examine": "Cabbage... yuck!", + "ids": "1161" + }, { "examine": "A barbarian flag.", "ids": "11614,11615" @@ -16307,6 +2619,10 @@ "examine": "Generally used for putting things on.", "ids": "11619" }, + { + "examine": "Found near the water's edge.", + "ids": "1162" + }, { "examine": "The entrance to the barbarians' longhall.", "ids": "11620,11621,11622,11623,11624,11625" @@ -16324,7 +2640,11 @@ "ids": "11629" }, { - "examine": "South to Falador :: West to Taverley :: East to Varrock.", + "examine": "Not good for eating.", + "ids": "1163,1164" + }, + { + "examine": "This tells you which way is which.", "ids": "11630,11631,11632,11633" }, { @@ -16335,6 +2655,10 @@ "examine": "Keeps unwelcome folk out of Falador.", "ids": "11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654,11655,11656" }, + { + "examine": "Fungal growth.", + "ids": "1165" + }, { "examine": "A rack for displaying fine maces.", "ids": "11657" @@ -16347,6 +2671,10 @@ "examine": "A barrel of maces.", "ids": "11659" }, + { + "examine": "Poisonous no doubt.", + "ids": "1166" + }, { "examine": "A table bearing a fine selection of maces.", "ids": "11660" @@ -16367,6 +2695,10 @@ "examine": "A hot furnace.", "ids": "11666,11667,11668,11669,11670,11671,11672,11673,36956" }, + { + "examine": "Fungal growth.", + "ids": "1167" + }, { "examine": "Rising Sun Tavern.", "ids": "11674" @@ -16383,6 +2715,10 @@ "examine": "The traditional sign of a barber.", "ids": "11678,11679,11680,11681" }, + { + "examine": "Poisonous no doubt.", + "ids": "1168,1169" + }, { "examine": "A small wooden table.", "ids": "11682,11683,11684,11685,11686,11687,11688,11689,11690,11691,11692" @@ -16399,6 +2735,10 @@ "examine": "The flag of Asgarnia.", "ids": "11699" }, + { + "examine": "I doubt that's edible.", + "ids": "1170,1171,1172" + }, { "examine": "I thought he'd be bigger than that.", "ids": "11700" @@ -16471,6 +2811,10 @@ "examine": "I can climb up these stairs.", "ids": "11729,11730" }, + { + "examine": "A commonly found fern.", + "ids": "1173" + }, { "examine": "I can climb down these stairs.", "ids": "11731" @@ -16507,6 +2851,10 @@ "examine": "Allows access to above level.", "ids": "11739,11740" }, + { + "examine": "Spiky!", + "ids": "1174" + }, { "examine": "Allows access to level below.", "ids": "11741,11742" @@ -16539,6 +2887,10 @@ "examine": "A sturdy-looking round table.", "ids": "11749,11750,11751,11752" }, + { + "examine": "A home for frogs.", + "ids": "1175" + }, { "examine": "Armour of a White Knight. Decorative, but still effective.", "ids": "11753,11754" @@ -16563,6 +2915,10 @@ "examine": "Hope springs eternal.", "ids": "11759" }, + { + "examine": "Otherwise known as a lilypad.", + "ids": "1176" + }, { "examine": "A carving of a figure from the history of 2009Scape.", "ids": "11761" @@ -16591,6 +2947,14 @@ "examine": "Dusty old books.", "ids": "11767" }, + { + "examine": "A home for frogs.", + "ids": "1177" + }, + { + "examine": "Smells lovely!", + "ids": "1178" + }, { "examine": "What ancient rites were performed here?", "ids": "11782,11783,11784,11785,11786,11787,11788" @@ -16599,6 +2963,10 @@ "examine": "Weathered rocks.", "ids": "11789,11790,11791,11792" }, + { + "examine": "Who is this Heather girl?", + "ids": "1179" + }, { "examine": "Best used with a bucket.", "ids": "11793" @@ -16619,6 +2987,14 @@ "examine": "Makes your hair stay curly.", "ids": "11799,11800,11801,11802,11803,11804,11805,11806,11807,11808,11809,11810,11811" }, + { + "examine": "I wonder why it's purple?", + "ids": "1180" + }, + { + "examine": "I'd better not get stung.", + "ids": "1181,1182,1183" + }, { "examine": "Running water", "ids": "11812" @@ -16627,6 +3003,10 @@ "examine": "Might be handy for a workman.", "ids": "11813,11814,11815,11816,11817,11818,11819,11820,11821,11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,11835,11836,11837,11838,11839" }, + { + "examine": "The tendrils of a creeping plant.", + "ids": "1184" + }, { "examine": "A pile of bricks.", "ids": "11840,11841,11842,11843" @@ -16643,6 +3023,14 @@ "examine": "Contains washing items.", "ids": "11849,11850,11851,11852,11853,11854,11855,11856,11857,11858,11859,11860" }, + { + "examine": "Nicely planted.", + "ids": "1185" + }, + { + "examine": "A large curling plant.", + "ids": "1186" + }, { "examine": "A dwarven flag.", "ids": "11861" @@ -16667,6 +3055,10 @@ "examine": "A pile of parts for building a multicannon.", "ids": "11869,11870,11871,11872" }, + { + "examine": "That's pretty.", + "ids": "1187" + }, { "examine": "A crate containing parts for building a multicannon.", "ids": "11873,11874" @@ -16683,6 +3075,10 @@ "examine": "A simple place for a simple dwarf to sleep and dream of gold.", "ids": "11877,11878,11879,11880,11881,11882,11883,11884,11885,11886,11887" }, + { + "examine": "Blooming!", + "ids": "1188" + }, { "examine": "I can climb up these stairs.", "ids": "11888" @@ -16691,6 +3087,10 @@ "examine": "I can climb these stairs.", "ids": "11889" }, + { + "examine": "Commonly found in grassy areas.", + "ids": "1189" + }, { "examine": "I can climb down these stairs.", "ids": "11890" @@ -16719,6 +3119,14 @@ "examine": "Not suitable for sitting on.", "ids": "11897,11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909" }, + { + "examine": "Is this the biggest flower around?", + "ids": "1190" + }, + { + "examine": "These are huge!", + "ids": "1191" + }, { "examine": "I hope I never meet one of those.", "ids": "11910" @@ -16731,6 +3139,38 @@ "examine": "A rocky outcrop.", "ids": "11915,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944,11945,11946,11947,11948,11949,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959,11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,11988,11989,11990,11991,11992" }, + { + "examine": "A rare flower.", + "ids": "1192" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "1193" + }, + { + "examine": "Can this talk?", + "ids": "1194" + }, + { + "examine": "You don't see that many of these.", + "ids": "1195" + }, + { + "examine": "I wonder what these are?", + "ids": "1196" + }, + { + "examine": "A rarely found flower.", + "ids": "1197" + }, + { + "examine": "Very rare flowers.", + "ids": "1198" + }, + { + "examine": "These smell nice.", + "ids": "1199" + }, { "examine": "The door is closed.", "ids": "11993" @@ -16739,9 +3179,17 @@ "examine": "The door is open.", "ids": "11994,11995,11996,11997,11998,11999,12000,12001,12002" }, + { + "examine": "A pile of rocks is blocking my path.", + "ids": "12" + }, + { + "examine": "A bed of red flowers.", + "ids": "1200" + }, { "examine": "Better not eat them!", - "ids": "12003" + "ids": "12003,12128" }, { "examine": "It's going to be a tight squeeze!", @@ -16751,6 +3199,22 @@ "examine": "Illuminating!", "ids": "12005,12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037,12038,12039,12040" }, + { + "examine": "These are pretty.", + "ids": "1201" + }, + { + "examine": "Found only in jungle areas.", + "ids": "1202" + }, + { + "examine": "A very rare exotic flower.", + "ids": "1203" + }, + { + "examine": "A small fernlike plant.", + "ids": "1204" + }, { "examine": "It'll be a tight squeeze.", "ids": "12041" @@ -16763,6 +3227,14 @@ "examine": "A magic door.", "ids": "12045,12046,12047,12048,12049,12050,12051,12052,12053,12054,12055,12056,12057,12058,12059" }, + { + "examine": "The leaves of a nasty creeping plant.", + "ids": "1205" + }, + { + "examine": "The flower of a nasty creeping plant.", + "ids": "1206,1207,1208" + }, { "examine": "Shelves of colourful potion gourds!", "ids": "12060,12061" @@ -16807,6 +3279,10 @@ "examine": "Better not eat them!", "ids": "12094,12095,12096,12097,12098,12099,14121" }, + { + "examine": "Aren't they pretty?", + "ids": "121" + }, { "examine": "A hot furnace.", "ids": "12100,12101" @@ -16881,7 +3357,7 @@ }, { "examine": "A wall jutting out into the path.", - "ids": "12127,12128,12129,12130" + "ids": "12127,12129,12130" }, { "examine": "Spooky.", @@ -16923,6 +3399,10 @@ "examine": "canoe", "ids": "12168,12169,12170,12171,12172,12173,12174,12175,12176,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188,12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200" }, + { + "examine": "Paaaarty!", + "ids": "122" + }, { "examine": "A well, it is not safe to climb down.", "ids": "12201" @@ -17071,6 +3551,10 @@ "examine": "Tick tock.", "ids": "12293,12294,12295,12296,12297,12298,12299,12300" }, + { + "examine": "A party balloon.", + "ids": "123,124,125,126,127,128,129,130" + }, { "examine": "Little candles flickering.", "ids": "12301,12302,12303,12304,12305,12306,12307,12308" @@ -17079,6 +3563,10 @@ "examine": "It's open.", "ids": "12309" }, + { + "examine": "Nasty curling tendrils of a creeping plant.", + "ids": "1231" + }, { "examine": "Someone should be sitting here.", "ids": "12310,12311" @@ -17587,6 +4075,10 @@ "examine": "You seem to make out some writing.", "ids": "12750,12751,12752,12753,12754,12755,12756,12757,12758,12759,12760" }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "1276" + }, { "examine": "A rotten looking door.", "ids": "12761,12762" @@ -17615,6 +4107,10 @@ "examine": "Perhaps I should search it.", "ids": "12769" }, + { + "examine": "A healthy young tree.", + "ids": "1277" + }, { "examine": "A small cave entrance.", "ids": "12770,12771,12772" @@ -17647,6 +4143,10 @@ "examine": "I can climb this.", "ids": "12779" }, + { + "examine": "A commonly found tree.", + "ids": "1278,1279" + }, { "examine": "A wooden ladder.", "ids": "12780,12781" @@ -17699,6 +4199,10 @@ "examine": "This bank booth could probably be repaired.", "ids": "12799" }, + { + "examine": "A healthy young tree.", + "ids": "1280" + }, { "examine": "This bank booth is too damaged to use.", "ids": "12800,12801" @@ -17727,6 +4231,10 @@ "examine": "A repaired furnace, hot and ready for action.", "ids": "12809,12810,12811" }, + { + "examine": "A beautiful old oak.", + "ids": "1281" + }, { "examine": "Hardened earth, with bits of rock in it, not easy to move.", "ids": "12812" @@ -17747,6 +4255,10 @@ "examine": "A wooden gate.", "ids": "12816,12817,12818,12819" }, + { + "examine": "This tree has long been dead.", + "ids": "1282,1283,1284" + }, { "examine": "A path leading out of this swampy dead end.", "ids": "12820,12821,12822,12823,12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835,12836,12837,12838,12839,12840,12841,12842,12843" @@ -17755,6 +4267,10 @@ "examine": "A veritable pile of bricks.", "ids": "12844,12845,12846,12847,12848,12849,12850,12851,12852,12853,12854" }, + { + "examine": "An old weather beaten tree.", + "ids": "1285" + }, { "examine": "It's a bit broken.", "ids": "12855" @@ -17767,6 +4283,10 @@ "examine": "Actually, I could do with a drink...never mind...I wasn't thirsty anyway.", "ids": "12857,12858,12859,12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871" }, + { + "examine": "It's only useful for firewood now.", + "ids": "1286,1287,1288,1289,1290,1291" + }, { "examine": "Where does this go?", "ids": "12872" @@ -17851,6 +4371,14 @@ "examine": "A wooden ladder.", "ids": "12906,12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931,12932" }, + { + "examine": "An ancient magical tree.", + "ids": "1292" + }, + { + "examine": "An ancient sentient tree.", + "ids": "1293,1294,1295" + }, { "examine": "Items are for sale here.", "ids": "12933,12934,12935,12936,12937,12938,12939,12940" @@ -17863,6 +4391,10 @@ "examine": "It's not a schooner, it's a sailboat.", "ids": "12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,12957,12958,12959,12960" }, + { + "examine": "This tree has fallen to the ground.", + "ids": "1296" + }, { "examine": "A wooden crate.", "ids": "12961" @@ -17891,6 +4423,10 @@ "examine": "Something is cooking nicely here.", "ids": "12969" }, + { + "examine": "This tree was either the victim of weather or mankind.", + "ids": "1297" + }, { "examine": "A well slept in bed.", "ids": "12970" @@ -17915,6 +4451,10 @@ "examine": "This chair rocks", "ids": "12979" }, + { + "examine": "A commonly found fern.", + "ids": "1298" + }, { "examine": "A stand for hats!", "ids": "12981" @@ -17927,6 +4467,18 @@ "examine": "A wooden gate.", "ids": "12986,12987,12988,12989,12990,12991,12992,12993,12994,12995,12996,12997,12998,12999,13000" }, + { + "examine": "Is this a weed?", + "ids": "1299" + }, + { + "examine": "Mud caved in from above.", + "ids": "13" + }, + { + "examine": "A fern is growing here.", + "ids": "1300" + }, { "examine": "The door is closed.", "ids": "13001" @@ -17947,10 +4499,46 @@ "examine": "A desert door.", "ids": "13006,13007,13008,13009,13010,13011,13012,13013,13014" }, + { + "examine": "Home to many unusual creatures.", + "ids": "1301" + }, { "examine": "A timber door.", "ids": "13015,13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093" }, + { + "examine": "A leafy tree.", + "ids": "1302" + }, + { + "examine": "A tree found in tropical areas.", + "ids": "1303,1304,1305" + }, + { + "examine": "The tree shimmers with a magical force.", + "ids": "1306" + }, + { + "examine": "I bet this makes good syrup!", + "ids": "1307" + }, + { + "examine": "These trees are found near water.", + "ids": "1308" + }, + { + "examine": "A splendid tree.", + "ids": "1309" + }, + { + "examine": "The door is closed.", + "ids": "131" + }, + { + "examine": "This tree has vines hanging from it.", + "ids": "1310" + }, { "examine": "A way in to the house.", "ids": "13100,13101,13102,13103,13104,13105,13106" @@ -17959,14 +4547,26 @@ "examine": "I'm sure the animal is glad its fur was put to good use.", "ids": "13107,13108,13109,13110,13111,13112,13113,13114,13115,13116,13117" }, + { + "examine": "This would be good to sleep under.", + "ids": "1311" + }, { "examine": "A posh door.", "ids": "13118,13119,13120,13121,13122,13123,13124,13125" }, + { + "examine": "An essential for tropical islands.", + "ids": "1312" + }, { "examine": "A place to train unarmed combat with your friends.", "ids": "13126,13127,13128,13129,13130,13131,13132" }, + { + "examine": "An unusual tree grows here.", + "ids": "1313,1314" + }, { "examine": "A place to train weapon skills with your friends.", "ids": "13133,13134,13135,13136" @@ -17995,6 +4595,10 @@ "examine": "Great for sleeping in.", "ids": "13148,13149,13150,13151,13152,13153,13154" }, + { + "examine": "A hardy evergreen tree.", + "ids": "1315,1316" + }, { "examine": "A place to keep your shoes.", "ids": "13155" @@ -18019,6 +4623,10 @@ "examine": "No little mouse to be seen.", "ids": "13169,13170,13171" }, + { + "examine": "A young sentient tree.", + "ids": "1317" + }, { "examine": "The holy symbol of the god of light.", "ids": "13172" @@ -18051,6 +4659,10 @@ "examine": "An oak altar with a symbol of Saradomin.", "ids": "13179" }, + { + "examine": "This would make good firewood.", + "ids": "1318,1319" + }, { "examine": "An oak altar with a symbol of Zamorak.", "ids": "13180" @@ -18131,6 +4743,14 @@ "examine": "A gilded marble altar with a symbol of Guthix.", "ids": "13199" }, + { + "examine": "An escape route.", + "ids": "132" + }, + { + "examine": "The branch is infested with moss.", + "ids": "1320,1321" + }, { "examine": "The smoke goes up to the gods.", "ids": "13200,13201,13202,13203,13204,13205,13206,13207,13208,13209,13210,13211,13212,13213" @@ -18159,6 +4779,10 @@ "examine": "It fills the room with coloured light.", "ids": "13219" }, + { + "examine": "The trunk of this tree is hollow.", + "ids": "1322" + }, { "examine": "What nice shapes you can make out of glass!", "ids": "13220" @@ -18199,6 +4823,10 @@ "examine": "What nice shapes you can make out of glass!", "ids": "13229" }, + { + "examine": "A gnarly old tree root.", + "ids": "1323" + }, { "examine": "It fills the room with coloured light.", "ids": "13230" @@ -18239,6 +4867,10 @@ "examine": "It fills the room with coloured light.", "ids": "13239" }, + { + "examine": "The roots of a tree are exposed.", + "ids": "1324" + }, { "examine": "What nice shapes you can make out of glass!", "ids": "13240" @@ -18279,6 +4911,10 @@ "examine": "What nice shapes you can make out of glass!", "ids": "13249" }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1325" + }, { "examine": "It fills the room with coloured light.", "ids": "13250" @@ -18319,6 +4955,10 @@ "examine": "It fills the room with coloured light.", "ids": "13259" }, + { + "examine": "A terribly tall tropical tree.", + "ids": "1326,1327,1328" + }, { "examine": "What nice shapes you can make out of glass!", "ids": "13260" @@ -18427,6 +5067,10 @@ "examine": "There must surely be treasure in a chest this expensive!", "ids": "13289,13290" }, + { + "examine": "Leaves of a bamboo tree.", + "ids": "1329" + }, { "examine": "Could the magic be guarding some treasure?", "ids": "13291,13292" @@ -18459,6 +5103,14 @@ "examine": "Marble and mahogany, ooh.", "ids": "13299" }, + { + "examine": "Looks spooky down there.", + "ids": "133" + }, + { + "examine": "It's thick with snow.", + "ids": "1330,1331,1332" + }, { "examine": "A basic wooden dining bench.", "ids": "13300" @@ -18531,6 +5183,10 @@ "examine": "A teak ladder.", "ids": "13329" }, + { + "examine": "This old tree has been taken over by parasitic plants.", + "ids": "1333" + }, { "examine": "A mahogany ladder.", "ids": "13330" @@ -18551,6 +5207,10 @@ "examine": "Invisible?", "ids": "13338,13339,13340" }, + { + "examine": "This old tree is rotting away.", + "ids": "1334,1335,1336,1337,1338" + }, { "examine": "Even a dungeon needs light!", "ids": "13341,13342,13343" @@ -18599,6 +5259,10 @@ "examine": "A pet Troll!", "ids": "13369" }, + { + "examine": "Steps*Leads to the surface.", + "ids": "1337" + }, { "examine": "No spider could get that big! It's unrealistic!", "ids": "13370" @@ -18675,6 +5339,10 @@ "examine": "Is there a prize inside?", "ids": "13389" }, + { + "examine": "They're just waiting to trip someone up.", + "ids": "1339,1340" + }, { "examine": "A private jester.", "ids": "13390,13391" @@ -18695,6 +5363,10 @@ "examine": "Someone hooped it!", "ids": "13399" }, + { + "examine": "A large double door.", + "ids": "134,135,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,4423,4424,4425,4426,4427,4428,4429,4430,4629,4630,4631,4632,4633,4634,4635,4963,4964,12349,12350,12446,12447,12448,12449,13094,13095,13096,13097,13098,13099,31814,31815,31816" + }, { "examine": "More humane than using an actual bull's eye.", "ids": "13400,13401" @@ -18727,6 +5399,10 @@ "examine": "What horrors lurk below?", "ids": "13409,13410" }, + { + "examine": "This tree has been cut down.", + "ids": "1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359" + }, { "examine": "One of the most common trees in 2009Scape.", "ids": "13411,13412" @@ -19127,6 +5803,14 @@ "examine": "A good source of books!", "ids": "13597,13598,13599" }, + { + "examine": "The door is closed.", + "ids": "136" + }, + { + "examine": "This tree contains dangerous insects no doubt.", + "ids": "1360,1361,1362" + }, { "examine": "A good source of scrolls!", "ids": "13600,13601,13602" @@ -19168,87 +5852,91 @@ "ids": "13614" }, { - "examine": "A gateway to Varrock", + "examine": "A gateway to Varrock.", "ids": "13615" }, { - "examine": "A gateway to Lumbridge", + "examine": "A gateway to Lumbridge.", "ids": "13616" }, { - "examine": "A gateway to Falador", + "examine": "A gateway to Falador.", "ids": "13617" }, { - "examine": "A gateway to Camelot", + "examine": "A gateway to Camelot.", "ids": "13618" }, { - "examine": "A gateway to Ardougne", + "examine": "A gateway to Ardougne.", "ids": "13619" }, { - "examine": "A gateway to the Yanille watchtower", + "examine": "A gateway to the Yanille watchtower.", "ids": "13620" }, { - "examine": "A gateway to Trollheim", + "examine": "A gateway to Kharyrll.", "ids": "13621" }, { - "examine": "A gateway to Varrock", + "examine": "A gateway to Varrock.", "ids": "13622" }, { - "examine": "A gateway to Lumbridge", + "examine": "A gateway to Lumbridge.", "ids": "13623" }, { - "examine": "A gateway to Falador", + "examine": "A gateway to Falador.", "ids": "13624" }, { - "examine": "A gateway to Camelot", + "examine": "A gateway to Camelot.", "ids": "13625" }, { - "examine": "A gateway to Ardougne", + "examine": "A gateway to Ardougne.", "ids": "13626" }, { - "examine": "A gateway to the Yanille watchtower", + "examine": "A gateway to the Yanille watchtower.", "ids": "13627" }, { - "examine": "A gateway to Trollheim", + "examine": "A gateway to Kharyrll.", "ids": "13628" }, { - "examine": "A gateway to Varrock", + "examine": "A gateway to Varrock.", "ids": "13629" }, { - "examine": "A gateway to Lumbridge", + "examine": "They're just waiting to trip someone up.", + "ids": "1363,1364" + }, + { + "examine": "A gateway to Lumbridge.", "ids": "13630" }, { - "examine": "A gateway to Falador", + "examine": "A gateway to Falador.", "ids": "13631" }, { - "examine": "A gateway to Camelot", + "examine": "A gateway to Camelot.", "ids": "13632" }, { - "examine": "A gateway to Ardougne", + "examine": "A gateway to Ardougne.", "ids": "13633" }, { - "examine": "A gateway to the Yanille watchtower", + "examine": "A gateway to the Yanille watchtower.", "ids": "13634" }, { - "examine": "A gateway to Trollheim", + "examine": "A gateway to Kharyrll.", "ids": "13635" }, { @@ -19279,6 +5967,10 @@ "examine": "A wooden planet of your very own.", "ids": "13649,13650,13651,13652,13653" }, + { + "examine": "It's only useful for firewood now.", + "ids": "1365" + }, { "examine": "A wooden solar system of your very own.", "ids": "13654,13655" @@ -19291,6 +5983,10 @@ "examine": "Use an elemental staff on it.", "ids": "13659,13660,13661" }, + { + "examine": "A gnarly old tree root.", + "ids": "1366" + }, { "examine": "If there's a recipe for the philosopher's stone there, you can't see it.", "ids": "13662" @@ -19307,6 +6003,10 @@ "examine": "Sit here and rule all you survey.", "ids": "13665,13666,13667,13668,13669,13670,13671" }, + { + "examine": "The roots of this tree are exposed.", + "ids": "1367" + }, { "examine": "Pull this to activate your machinery of doom!", "ids": "13672,13673,13674" @@ -19331,6 +6031,10 @@ "examine": "Go through this teak trapdoor to see the pit below your throne room.", "ids": "13679" }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1368" + }, { "examine": "Go through this mahogany trapdoor to see the pit below your throne room.", "ids": "13680" @@ -19347,6 +6051,10 @@ "examine": "What could happen on this spot?", "ids": "13684,13685,13686,13687,13688,13689" }, + { + "examine": "An unusual tree grows here.", + "ids": "1369" + }, { "examine": "An elengant cloth hanging.", "ids": "13690" @@ -19387,6 +6095,10 @@ "examine": "Hammer, chisel, saw and shears.", "ids": "13699" }, + { + "examine": "This old tree is rotting away.", + "ids": "1370" + }, { "examine": "Bucket, spade, tinderbox and knife.", "ids": "13700" @@ -19411,6 +6123,10 @@ "examine": "You can do delicate crafting here.", "ids": "13709,13710,13711,13712" }, + { + "examine": "This tree contains dangerous insects no doubt.", + "ids": "1371,1372,1373,1374,1375,1376,1377" + }, { "examine": "You can repair broken staffs and arrows here.", "ids": "13713" @@ -19635,6 +6351,10 @@ "examine": "A shield with a picture of a skull.", "ids": "13779" }, + { + "examine": "This old tree is rotting away.", + "ids": "1378,1379" + }, { "examine": "A shield with the symbol of Varrock.", "ids": "13780" @@ -19715,6 +6435,10 @@ "examine": "The symbol of Asgarnia.", "ids": "13799" }, + { + "examine": "A gnarly old tree root.", + "ids": "1380" + }, { "examine": "The symbol of the Dorgeshuun.", "ids": "13800" @@ -19755,6 +6479,10 @@ "examine": "A picture of a money bag.", "ids": "13809" }, + { + "examine": "The roots of this tree are exposed.", + "ids": "1381" + }, { "examine": "The symbol of Saradomin.", "ids": "13810" @@ -19795,6 +6523,10 @@ "examine": "The symbol of Guthix.", "ids": "13819" }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1382" + }, { "examine": "The symbol of the HAM cult.", "ids": "13820" @@ -19835,6 +6567,10 @@ "examine": "The symbol of Zamorak.", "ids": "13829" }, + { + "examine": "This tree has long been dead.", + "ids": "1383" + }, { "examine": "This should have resolved!", "ids": "13830" @@ -19867,6 +6603,10 @@ "examine": "Gloopy, sticky, muddy bog...", "ids": "13838,13839" }, + { + "examine": "It's only useful for firewood now.", + "ids": "1384" + }, { "examine": "A bush made up of long slender branches.", "ids": "13840" @@ -19903,6 +6643,14 @@ "examine": "Small swamp tree.", "ids": "13848,13849,13850,13851,13852,13853,13854,13855,13856,13857,13858,13859,13860,13861,13862,13863" }, + { + "examine": "A gnarly old tree root.", + "ids": "1385" + }, + { + "examine": "The roots of this tree are exposed.", + "ids": "1386" + }, { "examine": "It's our transport across the swamp.", "ids": "13864,13865" @@ -19911,6 +6659,10 @@ "examine": "A path leading out of this swampy dead end.", "ids": "13866,13867,13868,13869,13870" }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1387" + }, { "examine": "A path leading out of this swampy dead end, you'll be running away if you go down here.", "ids": "13871" @@ -19931,6 +6683,10 @@ "examine": "Get me out of here!", "ids": "13879,13880" }, + { + "examine": "They're just waiting to trip someone up.", + "ids": "1388,1389" + }, { "examine": "Very hot!", "ids": "13881" @@ -19947,6 +6703,10 @@ "examine": "There's no way I'm going in there!", "ids": "13899" }, + { + "examine": "Commonly found in these parts.", + "ids": "1390" + }, { "examine": "Doesn't look so scary now.", "ids": "13900" @@ -19959,14 +6719,26 @@ "examine": "The exit to the surface.", "ids": "13904,13905,13906,13907,13908,13909,13910,13911,13912" }, + { + "examine": "A leafy plant.", + "ids": "1391" + }, { "examine": "Where does it lead?", "ids": "13913,13914,13915,13916,13917,13918,13919,13920,13921,13922,13923,13924" }, + { + "examine": "A leafy fern.", + "ids": "1392" + }, { "examine": "What's that?", "ids": "13925,13926,13927,13928,13929,13930,13931" }, + { + "examine": "A small bushy plant.", + "ids": "1393" + }, { "examine": "I think it's the way out.", "ids": "13932" @@ -19979,10 +6751,26 @@ "examine": "Does that really exist?", "ids": "13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966" }, + { + "examine": "A leafy shrub.", + "ids": "1394" + }, + { + "examine": "No flies on me.", + "ids": "1395" + }, + { + "examine": "How do these things manage to grow?", + "ids": "1396" + }, { "examine": "Should I go down there?", "ids": "13967,13968,13969" }, + { + "examine": "This cactus has recently had a chunk taken off.", + "ids": "1397" + }, { "examine": "I can use that rope now.", "ids": "13970" @@ -19991,6 +6779,14 @@ "examine": "Should I go down there?", "ids": "13971,13972,13973,13974,13975,13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,13991,13992,13993" }, + { + "examine": "A leafy fern.", + "ids": "1398" + }, + { + "examine": "This has broad leaves.", + "ids": "1399" + }, { "examine": "Oooo, sharp, pointy things!", "ids": "13994,13995,13996,13997,13998" @@ -19999,6 +6795,14 @@ "examine": "This will take me back to the surface.", "ids": "13999,14000,14001" }, + { + "examine": "Intended to keep the goblins away from the mines.", + "ids": "14,15,16,17,18,19,20" + }, + { + "examine": "A large waxy jungle plant.", + "ids": "1400" + }, { "examine": "A sign warning of danger.", "ids": "14002" @@ -20027,6 +6831,38 @@ "examine": "It seems to have all boiled away.", "ids": "14009" }, + { + "examine": "A type of jungle fern.", + "ids": "1401" + }, + { + "examine": "A large waxy jungle plant.", + "ids": "1402" + }, + { + "examine": "How do these things manage to grow?", + "ids": "1403,1404,1405,1406" + }, + { + "examine": "Leaves a nasty mark.", + "ids": "1407" + }, + { + "examine": "Looks spiky.", + "ids": "1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503" + }, + { + "examine": "The wood burning here must be full of salt.", + "ids": "14169" + }, + { + "examine": "Doesn't look like it'll be sailing again.", + "ids": "14173" + }, + { + "examine": "Looks a bit damp.", + "ids": "14174" + }, { "examine": "Stop examining signs! You're in the Wilderness now!", "ids": "14503" @@ -20047,6 +6883,78 @@ "examine": "Danger, Wilderness up ahead. Almost certain death!", "ids": "14507" }, + { + "examine": "Rough but adequate.", + "ids": "14918" + }, + { + "examine": "A wooden crate.", + "ids": "15030" + }, + { + "examine": "A wooden crate.", + "ids": "15031" + }, + { + "examine": "Some wooden crates.", + "ids": "15032" + }, + { + "examine": "The door is open.", + "ids": "1504" + }, + { + "examine": "The door is closed.", + "ids": "1505" + }, + { + "examine": "A sturdy wooden door.", + "ids": "1506,1507,1508,1509,1510,1511,1512,1513,1514,1515" + }, + { + "examine": "Smelly.", + "ids": "152" + }, + { + "examine": "The curtain is closed.", + "ids": "1526,1527,1528" + }, + { + "examine": "The curtain is open.", + "ids": "1529" + }, + { + "examine": "An ornate fountain.", + "ids": "153,36781" + }, + { + "examine": "The door is closed.", + "ids": "1530" + }, + { + "examine": "The door is open.", + "ids": "1531,1532" + }, + { + "examine": "A nicely fitted door.", + "ids": "1533,1534,1535" + }, + { + "examine": "An ornately-fashioned door.", + "ids": "1536" + }, + { + "examine": "An elf-fashioned door.", + "ids": "1537,1538" + }, + { + "examine": "Solid bars of iron.", + "ids": "1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550" + }, + { + "examine": "A pipe I can squeeze through.", + "ids": "154,2287,2288,2290,2291,2292,2293,3236,3237,4058,5099,5100,5101,5102,5152,5153,5154,5155,9293,9295,10063,10064,10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,29370" + }, { "examine": "Home sweet home?", "ids": "15477" @@ -20055,22 +6963,514 @@ "examine": "Home sweet home?", "ids": "15480" }, + { + "examine": "Lots of books.", + "ids": "155,156,157" + }, + { + "examine": "Baby bread.", + "ids": "15506,15507" + }, + { + "examine": "A wooden gate.", + "ids": "1551,1552,1553,1554,1555,1556" + }, + { + "examine": "Probably looked better mounted on the dragon's neck.", + "ids": "15564" + }, + { + "examine": "A wrought iron gate.", + "ids": "1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567" + }, + { + "examine": "The body of a Dwarf savaged by Goblins.", + "ids": "15596" + }, + { + "examine": "I wonder what's under it?", + "ids": "1568,1569" + }, + { + "examine": "I wonder what's down there?", + "ids": "1570,1571" + }, + { + "examine": "This door has been boarded up.", + "ids": "1572" + }, + { + "examine": "A door to a grand place.", + "ids": "1573,1574,1575,1576" + }, { "examine": "Home sweet home?", "ids": "15748" }, + { + "examine": "Looks like part of the entrance is blocked by rubble.", + "ids": "15767" + }, + { + "examine": "The top of the archway.", + "ids": "1577,1578,1579" + }, + { + "examine": "This wall looks odd...", + "ids": "158,159" + }, + { + "examine": "The base of the archway.", + "ids": "1580,1581,1582" + }, + { + "examine": "Cave exit.", + "ids": "15812" + }, + { + "examine": "There is something strange about this wall...", + "ids": "1583,1584,1585,1586,1587,1588" + }, + { + "examine": "A wrought iron gate.", + "ids": "1589,1590" + }, + { + "examine": "The door is closed.", + "ids": "1591" + }, + { + "examine": "Something is strange about this panel.", + "ids": "1592,1593" + }, + { + "examine": "An entranceway into the dungeon.", + "ids": "1594" + }, + { + "examine": "The way in.", + "ids": "1595" + }, + { + "examine": "A wrought iron gate.", + "ids": "1596,1597" + }, + { + "examine": "A wooden gate.", + "ids": "1598,1599" + }, + { + "examine": "I wonder what this does...", + "ids": "160" + }, + { + "examine": "The doors to the Magic Guild.", + "ids": "1600" + }, + { + "examine": "The doors to the Magic guild.", + "ids": "1601,1602,1603,1604,1605,1606,1607,1608" + }, + { + "examine": "Danger - Possibly deadly creatures below!", + "ids": "16083,16151,16117" + }, + { + "examine": "A wooden structure used in the process of building.", + "ids": "1609,1610,1611,1612" + }, + { + "examine": "This timber is broken", + "ids": "1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660" + }, + { + "examine": "I'm not touching that.", + "ids": "162,163,164" + }, + { + "examine": "A special furnace for destroying contaminated items.", + "ids": "165" + }, + { + "examine": "A wooden gate.", + "ids": "166,167" + }, + { + "examine": "A pile of bricks.", + "ids": "1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721" + }, + { + "examine": "I wonder what's inside.", + "ids": "170" + }, + { + "examine": "Perhaps I should search it.", + "ids": "171" + }, + { + "examine": "I wonder what's inside.", + "ids": "172" + }, + { + "examine": "I can climb these stairs.", + "ids": "1722,36791" + }, + { + "examine": "They go down.", + "ids": "1723" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1724" + }, + { + "examine": "I can climb up this.", + "ids": "1725,36768,36771" + }, + { + "examine": "I can climb down this.", + "ids": "1726,1727,1728" + }, + { + "examine": "I can climb this.", + "ids": "1729,36347,36363,36644" + }, + { + "examine": "A sealed barrel with a warning sign on it.", + "ids": "17296" + }, + { + "examine": "A barrel with a warning sign on it.", + "ids": "17297" + }, + { + "examine": "Perhaps I should search it.", + "ids": "173" + }, + { + "examine": "Dare I go up?", + "ids": "1730" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "17308,31136,36798" + }, + { + "examine": "These stairs look spooky!", + "ids": "1731,1732" + }, + { + "examine": "I can use these stairs to climb down.", + "ids": "1733" + }, + { + "examine": "I can climb these stairs.", + "ids": "1734" + }, + { + "examine": "A rickety old staircase.", + "ids": "1735" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1736" + }, { "examine": "Large urn.", "ids": "17362" }, + { + "examine": "I can climb up these stairs.", + "ids": "1737,1738" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "1739" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1740,1741" + }, + { + "examine": "I can climb up these stairs.", + "ids": "1742" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "1743" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1744,1745" + }, + { + "examine": "I can climb down this.", + "ids": "1746" + }, + { + "examine": "Where people may put themselves.", + "ids": "17462" + }, + { + "examine": "I can climb this.", + "ids": "1747,1748" + }, + { + "examine": "I can climb down this.", + "ids": "1749" + }, + { + "examine": "I can climb this.", + "ids": "1750,1751" + }, + { + "examine": "I can't climb this.", + "ids": "1752" + }, + { + "examine": "It's useless.", + "ids": "1753" + }, + { + "examine": "I can climb down this.", + "ids": "1754" + }, + { + "examine": "I can climb this.", + "ids": "1755" + }, + { + "examine": "I can climb down this.", + "ids": "1756" + }, + { + "examine": "I can climb this.", + "ids": "1757" + }, + { + "examine": "Not much use really.", + "ids": "1758" + }, + { + "examine": "This leads downwards.", + "ids": "1759" + }, + { + "examine": "These can be useful.", + "ids": "1760" + }, + { + "examine": "Steps made from natural rock.", + "ids": "1761" + }, + { + "examine": "A rope hangs here.", + "ids": "1762,1763,1764" + }, + { + "examine": "I can climb down this.", + "ids": "1765" + }, + { + "examine": "I can climb this.", + "ids": "1766" + }, + { + "examine": "I can climb down this.", + "ids": "1767" + }, + { + "examine": "I can climb this.", + "ids": "1768,1769,1770,1771,1772,1773,1774,1775,1776,1777" + }, + { + "examine": "These huge stone discs grind grain to make flour.", + "ids": "1778" + }, + { + "examine": "These sails use the wind to drive the windmill.", + "ids": "1779,1780,1781" + }, + { + "examine": "I'll need an empty pot so I can collect my flour.", + "ids": "1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796" + }, + { + "examine": "Some very hard rocks, I wouldn't want to fall on those.", + "ids": "1797,1798,1799,1800,1801,1802,1803" + }, + { + "examine": "This door requires a key.", + "ids": "1804" + }, + { + "examine": "The door to the Champions' Guild.", + "ids": "1805,1806,1807,1808,1809" + }, + { + "examine": "Here be spiders!", + "ids": "1810" + }, + { + "examine": "I can walk through this tattered web.", + "ids": "1811" + }, + { + "examine": "A magical border of teleportation.", + "ids": "1812" + }, + { + "examine": "For putting things on.", + "ids": "1813" + }, + { + "examine": "I wonder what this does...", + "ids": "1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851" + }, { "examine": "A large fish.", "ids": "18482" }, + { + "examine": "A wooden crate for storage.", + "ids": "18506" + }, + { + "examine": "A pile of crates for storage.", + "ids": "18508" + }, + { + "examine": "This lets in more light.", + "ids": "1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863" + }, + { + "examine": "These obviously mean keep out!", + "ids": "1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875" + }, + { + "examine": "Fly Gnome Air.", + "ids": "187" + }, + { + "examine": "I shudder to think what has taken place here.", + "ids": "1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,32289" + }, + { + "examine": "Probably pilot error.", + "ids": "188" + }, + { + "examine": "Popular on sandy beaches where fruity cocktails may be found.", + "ids": "18856" + }, { "examine": "A sign on a cactus.", "ids": "18876" }, + { + "examine": "The Blurberry bar", + "ids": "189" + }, + { + "examine": "This hasn't seen a duster for a while.", + "ids": "1896" + }, + { + "examine": "Not as nice as some.", + "ids": "1897" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "1898,1899" + }, + { + "examine": "A large gate in the gnome style.", + "ids": "190" + }, + { + "examine": "This could do with a bit of a spit and polish.", + "ids": "1900" + }, + { + "examine": "This clearly isn't used for dining very often.", + "ids": "1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938" + }, + { + "examine": "A tower.", + "ids": "1939,1940,1941,1942,1943,1944,1945,1946" + }, + { + "examine": "The entrance to the cave.", + "ids": "194" + }, + { + "examine": "It looks like I might be able to climb over this piece of the wall...", + "ids": "1947,1948" + }, + { + "examine": "A pile of bricks.", + "ids": "1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966" + }, + { + "examine": "I can climb this.", + "ids": "195" + }, + { + "examine": "A grand door for a grand tree.", + "ids": "1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984" + }, + { + "examine": "A large root.", + "ids": "1985,1986" + }, + { + "examine": "A primitive looking boat.", + "ids": "1987" + }, + { + "examine": "Oops!", + "ids": "1988" + }, + { + "examine": "A good source of books!", + "ids": "1989" + }, + { + "examine": "A wooden crate for storage.", + "ids": "1990" + }, + { + "examine": "Solid bars of iron.", + "ids": "1991" + }, + { + "examine": "There is an indent the size of a pebble in the stone's centre.", + "ids": "1992" + }, + { + "examine": "A stone tomb surrounded by flowers.", + "ids": "1993" + }, + { + "examine": "I wonder what's inside.", + "ids": "1994,37016,37015" + }, + { + "examine": "Perhaps I should search it.", + "ids": "1995" + }, + { + "examine": "I should be safe if I can reach this.", + "ids": "1996,1997" + }, + { + "examine": "Wet rope.", + "ids": "1998" + }, + { + "examine": "A wooden crate for storage.", + "ids": "1999" + }, { "examine": "Dead and half-buried.", "ids": "19996" @@ -20079,18 +7479,274 @@ "examine": "Dead animal head. Lovely.", "ids": "19997" }, + { + "examine": "Looks and smells like a place where goblins live.", + "ids": "2" + }, + { + "examine": "A quirky gnome lamp.", + "ids": "200" + }, + { + "examine": "An elf-fashioned door.", + "ids": "2000,2001,2002,2003" + }, + { + "examine": "The pillar has a rune shaped dent in it.", + "ids": "2004" + }, + { + "examine": "A statue of Baxtorian chiselled in stone.", + "ids": "2005" + }, + { + "examine": "A statue of Glarial chiselled in stone.", + "ids": "2006,2007,2008,2009" + }, + { + "examine": "These insects love this light.", + "ids": "201" + }, + { + "examine": "A ledge.", + "ids": "2010,2011,2012" + }, + { + "examine": "Known commonly as Red worm vine.", + "ids": "2013" + }, + { + "examine": "A magically elevated chalice full of tears.", + "ids": "2014" + }, + { + "examine": "A magically elevated chalice full of ash.", + "ids": "2015,2016,2017,2018" + }, + { + "examine": "A whirlpool.", + "ids": "2019" + }, + { + "examine": "It's amazing what bees produce!", + "ids": "202" + }, + { + "examine": "It's too wet for firewood.", + "ids": "2020,2021" + }, + { + "examine": "A wooden barrel, maybe a way off this rock.", + "ids": "2022" + }, + { + "examine": "An interesting tree with long straight branches.", + "ids": "2023" + }, + { + "examine": "A large bubbling cauldron, smells... Ugh!", + "ids": "2024" + }, + { + "examine": "The door is closed.", + "ids": "2025" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "2026,2027,2028,2029,2030,2031" + }, + { + "examine": "Posh candlesticks.", + "ids": "203,204,32287,40074" + }, + { + "examine": "It's closed.", + "ids": "2032" + }, + { + "examine": "It's open.", + "ids": "2033" + }, + { + "examine": "It's closed.", + "ids": "2034" + }, + { + "examine": "It's open.", + "ids": "2035" + }, + { + "examine": "It's closed.", + "ids": "2036" + }, + { + "examine": "It's open.", + "ids": "2037" + }, + { + "examine": "I've met less intelligent conversationalists.", + "ids": "2038" + }, + { + "examine": "It's closed.", + "ids": "2039,2040,2041,2042" + }, + { + "examine": "Something's bubbling away in it.", + "ids": "2043" + }, + { + "examine": "Like an animal dinner table.", + "ids": "2044,2045,2046,2047" + }, + { + "examine": "It's a door.", + "ids": "2048,2049" + }, + { + "examine": "A wooden gate.", + "ids": "2050,2051,2052,2053" + }, + { + "examine": "It's a door.", + "ids": "2054,2055" + }, + { + "examine": "It's closed.", + "ids": "2056" + }, + { + "examine": "It's open.", + "ids": "2057" + }, + { + "examine": "It's closed.", + "ids": "2058,2059,2060,2061,2062" + }, + { + "examine": "It's open.", + "ids": "2063" + }, + { + "examine": "For storage.", + "ids": "2064" + }, + { + "examine": "Used for climbing.", + "ids": "2065" + }, + { + "examine": "A wall.", + "ids": "2066" + }, + { + "examine": "A watchtower.", + "ids": "2067" + }, + { + "examine": "A fence.", + "ids": "2068" + }, + { + "examine": "A closed door.", + "ids": "2069,2070" + }, + { + "examine": "Used for storage.", + "ids": "2071,2072" + }, + { + "examine": "Grows weird yellow fruit.", + "ids": "2073,2074,2075,2076,2077,2078" + }, + { + "examine": "I wonder what's inside?", + "ids": "2079,2080" + }, + { + "examine": "Scary lighting apparatus.", + "ids": "208" + }, + { + "examine": "Handy for boarding boats.", + "ids": "2081,2082,2083,2084,2085,2086,2087,2088" + }, + { + "examine": "Ornamental.", + "ids": "2089" + }, + { + "examine": "An ornamental lighting fixture.", + "ids": "209" + }, + { + "examine": "A rocky outcrop.", + "ids": "2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111" + }, + { + "examine": "Its eyes stare off into the distance...", + "ids": "21" + }, + { + "examine": "A mysterious glowing ice crystal.", + "ids": "210" + }, + { + "examine": "It's amazing what bees produce!", + "ids": "211" + }, + { + "examine": "The door is closed.", + "ids": "2112" + }, + { + "examine": "I can climb down this.", + "ids": "2113" + }, + { + "examine": "This transports coal!", + "ids": "2114" + }, + { + "examine": "The left hand side of the gate.", + "ids": "2115" + }, + { + "examine": "The right hand side of the gate.", + "ids": "2116" + }, + { + "examine": "It's an old wall.", + "ids": "2117" + }, + { + "examine": "Sturdy looking.", + "ids": "21176" + }, + { + "examine": "Lots of water swirling around", + "ids": "2118" + }, + { + "examine": "A rocky outcrop.", + "ids": "2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140" + }, + { + "examine": "Useful for making ships move.", + "ids": "212,218" + }, { "examine": "Might be worth opening?", "ids": "21299" }, - { - "examine": "A sturdy metal door.", - "ids": "21400,21402,21399" - }, { "examine": "I can climb this.", "ids": "21395,29355" }, + { + "examine": "A sturdy metal door.", + "ids": "21400,21402,21399" + }, { "examine": "A closed, sturdy metal door.", "ids": "21403,21405" @@ -20099,6 +7755,18 @@ "examine": "An open, sturdy metal door.", "ids": "21404" }, + { + "examine": "An open chest.", + "ids": "2141" + }, + { + "examine": "An eerie glow permeates the cauldron.", + "ids": "2142" + }, + { + "examine": "Looks secure.", + "ids": "2143,2144" + }, { "examine": "A display case, full of axes.", "ids": "21437" @@ -20135,6 +7803,10 @@ "examine": "A shelf, displaying armour.", "ids": "21447" }, + { + "examine": "Ooooh! Spooky!", + "ids": "2145,2146" + }, { "examine": "I can climb down these stairs.", "ids": "21455" @@ -20147,6 +7819,34 @@ "examine": "A stone torch.", "ids": "21465" }, + { + "examine": "Going down?", + "ids": "2147" + }, + { + "examine": "Going up?", + "ids": "2148" + }, + { + "examine": "An imposing stone structure.", + "ids": "2149" + }, + { + "examine": "A column of elemental power.", + "ids": "2150,2151,2152,2153,29415" + }, + { + "examine": "A wrought iron gate.", + "ids": "2154,2155" + }, + { + "examine": "A magical portal of teleportation.", + "ids": "2156,2157,2158" + }, + { + "examine": "It's a floating barrel.", + "ids": "2159,2160,2161" + }, { "examine": "A chair made from stone.", "ids": "21607" @@ -20155,6 +7855,10 @@ "examine": "A table with swords on it.", "ids": "21608" }, + { + "examine": "A table with plates and mugs on it.", + "ids": "21609,21610" + }, { "examine": "A bed to sleep in.", "ids": "21611" @@ -20163,221 +7867,1325 @@ "examine": "A stone crate with some stuff in it.", "ids": "21612" }, - { - "examine": "A table with plates and mugs on it.", - "ids": "21609,21610" - }, { "examine": "A shelf with some cups on it.", "ids": "21614,21615" }, + { + "examine": "Smells like fish.", + "ids": "2162,2163,2164,2165,2166" + }, { "examine": "A Fremennik flag.", "ids": "21637" }, + { + "examine": "Water is pouring in through the hole.", + "ids": "2167" + }, + { + "examine": "A patch of swamp tar has bunged up the hole.", + "ids": "2168" + }, + { + "examine": "There's a strong wind whipping up the sea.", + "ids": "2169,2170,2171" + }, + { + "examine": "A huge net to catch little fish.", + "ids": "2172,2173" + }, + { + "examine": "The upper deck can be accessed with this ladder.", + "ids": "2174" + }, + { + "examine": "Back down to the main deck.", + "ids": "2175" + }, + { + "examine": "This old trawler has seen better days.", + "ids": "2176,2177" + }, + { + "examine": "Handy for boarding boats.", + "ids": "2178,2179" + }, + { + "examine": "It's a war machine.", + "ids": "2180,2181" + }, + { + "examine": "It can't hurt to just have a look, can it?", + "ids": "2182" + }, + { + "examine": "I wonder what is inside...", + "ids": "2183" + }, { "examine": "A short longboat!", "ids": "21834" }, { - "examine": "Contains traces of summoning energy.", - "ids": "29939,29943,29944,29945,29947,29951,29952,29953,29954" + "examine": "The door is closed.", + "ids": "2184" }, { - "examine": "An interesting sign.", - "ids": "31297,31298,31299,31300,31301" + "examine": "This wall has seen better days.", + "ids": "2185" }, { - "examine": "I wonder what this spooky contains.", - "ids": "37051" + "examine": "Hmmm... I wonder if it's loose enough to get through.", + "ids": "2186" }, { - "examine": "It really was this big!", - "ids": "40043" + "examine": "I can climb down this ladder.", + "ids": "2187" }, { - "examine": "It really was this big!", - "ids": "40042" + "examine": "I can climb up this ladder.", + "ids": "2188,2189" }, { - "examine": "A wooden barrel for storage.", - "ids": "40018" + "examine": "I can climb down this ladder.", + "ids": "2190" }, { - "examine": "A wooden barrel containing lots of fish.", - "ids": "40019" + "examine": "I wonder what's inside?", + "ids": "2191,2192,2193" }, { - "examine": "A nice sturdy looking table.", - "ids": "40044" + "examine": "Perhaps I should search it.", + "ids": "2194,2195,2196" }, { - "examine": "A wooden crate.", - "ids": "40021" + "examine": "I wonder what's inside?", + "ids": "2197" }, { - "examine": "Some wooden crates.", - "ids": "40022" + "examine": "Perhaps I should search it.", + "ids": "2198" }, { - "examine": "A large potted plant.", - "ids": "40111" + "examine": "An old gate for locking up undesirables.", + "ids": "2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209" }, { - "examine": "Tick-tock, it's a clock.", - "ids": "40029" + "examine": "The door is shut.", + "ids": "22" }, { - "examine": "I wonder what's inside.", - "ids": "29400,32010,40093" + "examine": "This figure brings luck to those who sail.", + "ids": "221,222" }, { - "examine": "Useful for putting things on.", - "ids": "40031" + "examine": "Looking through it makes far off things look closer!", + "ids": "2210" }, { - "examine": "Items are for sale here.", - "ids": "40028" + "examine": "A weathered old gravestone.", + "ids": "2211" }, { - "examine": "I can climb this.", - "ids": "40026" + "examine": "Looks like fun.", + "ids": "2212" }, { - "examine": "Some wooden crates.", - "ids": "15032" + "examine": "The bank teller will serve you from here.", + "ids": "2213" }, { - "examine": "A wooden crate.", - "ids": "15030" + "examine": "This booth is for private customers only.", + "ids": "2214,34205" }, { - "examine": "A wooden crate.", - "ids": "15031" + "examine": "This booth is closed.", + "ids": "2215" + }, + { + "examine": "This looks like it's being used to block entrance to the village.", + "ids": "2216" + }, + { + "examine": "Something seems to be buried under this.", + "ids": "2217" + }, + { + "examine": "A narrow fissure in the ground.", + "ids": "2218,2219" + }, + { + "examine": "A pile of rubble.", + "ids": "2220" + }, + { + "examine": "A stone with some carvings on it.", + "ids": "2221" + }, + { + "examine": "A pile of loose rocks.", + "ids": "2222" + }, + { + "examine": "Probably nothing useful in these.", + "ids": "2223" + }, + { + "examine": "A rotten and barely standing set of gallows.", + "ids": "2224" + }, + { + "examine": "Wet rocks, it looks like you might be able to climb them.", + "ids": "2225" + }, + { + "examine": "This table has seen better days.", + "ids": "2226" + }, + { + "examine": "A crudely constructed raft.", + "ids": "2227,2228" + }, + { + "examine": "A statue to mark Tai Bwo Wannai sacred grounds.", + "ids": "2229" + }, + { + "examine": "A sturdy cart for travelling in.", + "ids": "2230" + }, + { + "examine": "A rocky outcrop.", + "ids": "2231,2232,2233" + }, + { + "examine": "Rocks that have been stacked at regular intervals.", + "ids": "2234" + }, + { + "examine": "An ancient construct for supporting the bones of the deceased.", + "ids": "2235" + }, + { + "examine": "I can climb the rocky outcrop.", + "ids": "2236" + }, + { + "examine": "An exotic looking tree.", + "ids": "2237" + }, + { + "examine": "Large doors set into the hillside.", + "ids": "2238,2239" + }, + { + "examine": "These doors must have been hidden here for years.", + "ids": "2240,2241" + }, + { + "examine": "Perhaps you should give them a push.", + "ids": "2242,2243" + }, + { + "examine": "Commonly found in these parts.", + "ids": "2244" + }, + { + "examine": "A leafy fern.", + "ids": "2245" + }, + { + "examine": "Large carved tomb doors, they look terrifying.", + "ids": "2246,2247,2248,2249,2250,2251,2252" + }, + { + "examine": "Useful for making ships move.", + "ids": "225,226" + }, + { + "examine": "Perhaps you should give them a push.", + "ids": "2253,2254" + }, + { + "examine": "An ancient metal gate, but still pretty secure.", + "ids": "2255,2256" + }, + { + "examine": "A rocky outcrop.", + "ids": "2257" + }, + { + "examine": "An ancient construct for supporting the bones of the deceased.", + "ids": "2258" + }, + { + "examine": "The gate is closed.", + "ids": "2259,2260,2261,2262,2263,2264" + }, + { + "examine": "A sturdy cart for travelling in.", + "ids": "2265" + }, + { + "examine": "The door is closed.", + "ids": "2266,2267" + }, + { + "examine": "This leads up to the sleeping area.", + "ids": "2268" + }, + { + "examine": "This leads downwards.", + "ids": "2269" + }, + { + "examine": "Barnacle infested rope.", + "ids": "227" + }, + { + "examine": "A jungle plant.", + "ids": "2270" + }, + { + "examine": "I wonder what's inside?", + "ids": "2271" + }, + { + "examine": "It's open.", + "ids": "2272" + }, + { + "examine": "An odd-looking rock with a rope tied to it.", + "ids": "2273,2274" + }, + { + "examine": "An odd-looking rock formation.", + "ids": "2275,2276,2277,2278" + }, + { + "examine": "Holds the rope up. Hopefuly.", + "ids": "2279,2280,2281" + }, + { + "examine": "Use this to swing over crevices.", + "ids": "2282,2283" + }, + { + "examine": "This must be climbed over.", + "ids": "2284,2285,2286" + }, + { + "examine": "It's hollow...", + "ids": "2289" + }, + { + "examine": "A slippery log I can walk across.", + "ids": "2294,2295,2296,2297" + }, + { + "examine": "The irregular surface can be climbed.", + "ids": "2298,2299,2300" + }, + { + "examine": "Unusually lumpy looking.", + "ids": "23" + }, + { + "examine": "Tread carefully!", + "ids": "2301,2302" + }, + { + "examine": "I can just about edge across here.", + "ids": "2303" + }, + { + "examine": "Pointy!", + "ids": "2304,2305,2306" + }, + { + "examine": "A wrought iron gate.", + "ids": "2307,2308" + }, + { + "examine": "Solid bars of iron.", + "ids": "2309" + }, + { + "examine": "This tree has been cut down.", + "ids": "2310" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "2311" + }, + { + "examine": "I can balance on this rope.", + "ids": "2312" + }, + { + "examine": "I can climb up this.", + "ids": "2313" + }, + { + "examine": "I can climb down here.", + "ids": "2314,2315" + }, + { + "examine": "I can climb up these stairs.", + "ids": "2316,36776" + }, + { + "examine": "I can climb up these rocks to another cave.", + "ids": "2317" + }, + { + "examine": "I can climb down these rocks to another cave.", + "ids": "2318" + }, + { + "examine": "I can traverse these.", + "ids": "2319,2320,2321,12573,12574,12575,29375" + }, + { + "examine": "Use this to swing across gaps.", + "ids": "2322,2323,2324" + }, + { + "examine": "I can swing on this tree.", + "ids": "2325" + }, + { + "examine": "A branch protrudes here.", + "ids": "2326" + }, + { + "examine": "This tree has an unusually long branch on it.", + "ids": "2327" + }, + { + "examine": "Jump here.", + "ids": "23271" + }, + { + "examine": "A rocky outcrop.", + "ids": "2328,2329,2330,2331" + }, + { + "examine": "A nearly rotten wooden log that crosses the river.", + "ids": "2332" + }, + { + "examine": "A rocky outcrop from the running water.", + "ids": "2333,2334,2335" + }, + { + "examine": "You can see a cauldron directly below.", + "ids": "2336" + }, + { + "examine": "This door is very sturdy looking.", + "ids": "2337" + }, + { + "examine": "This door is closed.", + "ids": "2338" + }, + { + "examine": "This door is very sturdy looking.", + "ids": "2339,2340" + }, + { + "examine": "There is something strange about this wall...", + "ids": "2341" + }, + { + "examine": "Looks like a ventilation grill.", + "ids": "2342" + }, + { + "examine": "A large stone block.", + "ids": "2343,2344,2345,2346,2347,2348,2349" + }, + { + "examine": "Used to move earth to, and from, the dig shaft.", + "ids": "2350,2351" + }, + { + "examine": "This leads back up the dig shaft.", + "ids": "2352,2353" + }, + { + "examine": "Yep, they're sacks!", + "ids": "2354,2355,2356" + }, + { + "examine": "A leafy bush.", + "ids": "2357,2358" }, { "examine": "A sealed barrel with a warning sign on it.", - "ids": "17296" + "ids": "2359" }, { - "examine": "A barrel with a warning sign on it.", - "ids": "17297" + "examine": "I wonder what's inside...", + "ids": "2360" + }, + { + "examine": "A sturdy chest to keep things in.", + "ids": "2361" + }, + { + "examine": "A large stone block.", + "ids": "2362" + }, + { + "examine": "A place where you can pan for gold.", + "ids": "2363" + }, + { + "examine": "A wooden container.", + "ids": "2364,2365" + }, + { + "examine": "A signpost!", + "ids": "2366,2367,2368,2369,2370,2371" + }, + { + "examine": "Shelves filled with interesting books.", + "ids": "2372" + }, + { + "examine": "A cupboard.", + "ids": "2373,2374" + }, + { + "examine": "Used to keep specimens on.", + "ids": "2375" + }, + { + "examine": "Soil. Dug up!", + "ids": "2376,2377,2378" + }, + { + "examine": "Technically a bed.", + "ids": "2379" + }, + { + "examine": "I wonder what's inside...", + "ids": "2380" + }, + { + "examine": "Swampy dirt.", + "ids": "2381,2382,2383,2384,2385,2386,2387,2388,2389,2390" + }, + { + "examine": "A very solid looking gate.", + "ids": "2391,2392" + }, + { + "examine": "'Pay back all your debts by borrowing more money from us!' Clever.", + "ids": "23924" + }, + { + "examine": "Contains quite a lot of someone else's property.", + "ids": "23925" + }, + { + "examine": "This chest looks strong.", + "ids": "23926" + }, + { + "examine": "A handy place for filling in forms and paperwork.", + "ids": "23928" + }, + { + "examine": "They say money can't buy happiness.", + "ids": "23929" + }, + { + "examine": "Aim for the goal!", + "ids": "2393" + }, + { + "examine": "A gilt sculpture of a monarch.", + "ids": "23930" + }, + { + "examine": "A gate to the Gnomeball pitch.", + "ids": "2394,2395" + }, + { + "examine": "Distinctly feminine.", + "ids": "2396" + }, + { + "examine": "A solid looking door.", + "ids": "2397,2398,2399" + }, + { + "examine": "The door is shut.", + "ids": "24" + }, + { + "examine": "Might be worth searching.", + "ids": "2400,2401" + }, + { + "examine": "A good source of books!", + "ids": "2402" + }, + { + "examine": "Might be worth searching.", + "ids": "2403,2404" + }, + { + "examine": "I can climb this.", + "ids": "2405" + }, + { + "examine": "The door is closed.", + "ids": "2406,2407" + }, + { + "examine": "I can climb down this.", + "ids": "2408,36693,36694" + }, + { + "examine": "A commonly found tree.", + "ids": "2409" + }, + { + "examine": "I can climb this.", + "ids": "2410" + }, + { + "examine": "The door is closed.", + "ids": "2411" + }, + { + "examine": "Handy for boarding the ship.", + "ids": "2412,2413,2414,2415" + }, + { + "examine": "Pull me!", + "ids": "2416" + }, + { + "examine": "Place party drop items here.", + "ids": "2417,2418,2419,2420" }, { "examine": "A beautiful landscape.", "ids": "24184" }, { - "examine": "These open and close!", - "ids": "40050" + "examine": "This lever is down.", + "ids": "2421" }, { - "examine": "A case. With books.", - "ids": "40033" + "examine": "This lever is up.", + "ids": "2422" }, { - "examine": "A drab looking bed.", - "ids": "40035" + "examine": "This lever is down.", + "ids": "2423" }, { - "examine": "I can climb down this.", - "ids": "40027,20987,29358" + "examine": "This lever is up.", + "ids": "2424" }, { - "examine": "These open and close!", - "ids": "40052" + "examine": "This lever is down.", + "ids": "2425" }, { - "examine": "The perfect place to store things.", - "ids": "40054" + "examine": "This lever is up.", + "ids": "2426" }, { - "examine": "Break glass in case in case of emergency.", - "ids": "40076" + "examine": "This door is closed by an unknown mechanism.", + "ids": "2427,2428,2429,2430,2431" + }, + { + "examine": "This gate is closed shut.", + "ids": "2432,2433" + }, + { + "examine": "This may be worth opening.", + "ids": "2434,2435" }, { "examine": "I can climb up these stairs.", - "ids": "40057" + "ids": "24349" }, { - "examine": "Trinkets and stuff.", - "ids": "40075" + "examine": "I wonder what's inside.", + "ids": "2436,2437" }, { - "examine": "Looking good!", - "ids": "40065" + "examine": "A wooden gate.", + "ids": "2438,2439" }, { - "examine": "It looks slightly different from the rest.", - "ids": "30532" + "examine": "Wonder what this pillar is for?", + "ids": "2440,2441,2442,2443" }, { - "examine": "'Here lies...' is all I can read.", - "ids": "30671,30672" + "examine": "I wonder what's under it?", + "ids": "2444,2445" }, { - "examine": "The inscription is worn away and unreadable.", - "ids": "30667,30669" + "examine": "This leads to somewhere...but where?", + "ids": "2446" }, { - "examine": "Whoever bought this must have really cared for the inhabitant.", - "ids": "30668" + "examine": "I reckon I could climb that!", + "ids": "2447,2448" }, { - "examine": "Make a wish.", - "ids": "28715" + "examine": "Some magical rocks.", + "ids": "2449,2450" }, { - "examine": "Contains no summoning energy.", - "ids": "28720,28721" + "examine": "Allows access to other parts of the ship.", + "ids": "245,246" }, { - "examine": "Glowing with barely-suppressed energies.", - "ids": "28719" + "examine": "There's something behind these roots.", + "ids": "2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464" }, { - "examine": "Looks kind of like a man made of metal.", - "ids": "32292" + "examine": "A portal from this mystical place.", + "ids": "2465,2466,2467,2468,2469,2470,2471,2472,2473,2474,2475,2476,2477" }, { - "examine": "Technically a bed.", - "ids": "32031" + "examine": "A mysterious power emanates from this shrine.", + "ids": "2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490" }, { - "examine": "Now that's what I call slimline!", - "ids": "32072" + "examine": "The source of all Rune Stones.", + "ids": "2491" }, { - "examine": "A really bad portrait of the King.", - "ids": "32326" + "examine": "A portal from this mystical place.", + "ids": "2492" }, { - "examine": "A tatty old standard.", - "ids": "32295" + "examine": "For keeping things in.", + "ids": "24924" }, { - "examine": "I can climb this.", - "ids": "32015" + "examine": "A part of an old temple.", + "ids": "2493,2494,2495,2496" }, { - "examine": "An old crate for storage.", - "ids": "29351,29352,31137,31140" + "examine": "Unusual energy is gathered here.", + "ids": "2497,2498,2499,2500,2501,2502" + }, + { + "examine": "Seems to be some kind of clock part.", + "ids": "25,26,27,28,29,30,31,32" + }, + { + "examine": "An old crumbled pillar.", + "ids": "2503,2504,2505,2506,2507" + }, + { + "examine": "Broken parts of an old temple.", + "ids": "2508,2509,2510" + }, + { + "examine": "This leads to the practice tower.", + "ids": "2511" + }, + { + "examine": "This leads back down to the guild.", + "ids": "2512" + }, + { + "examine": "I wonder if I can hit a bullseye?", + "ids": "2513" + }, + { + "examine": "The door to the Ranging Guild.", + "ids": "2514" + }, + { + "examine": "I hope it doesn't sink.", + "ids": "2515" + }, + { + "examine": "It's sinking!", + "ids": "2516" + }, + { + "examine": "Going up?", + "ids": "2517" + }, + { + "examine": "Typical shoddy workmanship.", + "ids": "2518" + }, + { + "examine": "Crates of packed fish.", + "ids": "2519" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "252,253" + }, + { + "examine": "It's used for loading and unloading fishing boats.", + "ids": "2520,2521" + }, + { + "examine": "It's a flight of stairs.", + "ids": "2522,2523" + }, + { + "examine": "I wonder what's inside?", + "ids": "2524" + }, + { + "examine": "It's open.", + "ids": "2525" + }, + { + "examine": "The door of a small prison.", + "ids": "2526,2527" + }, + { + "examine": "The door is closed.", + "ids": "2528" + }, + { + "examine": "A door.", + "ids": "2529" + }, + { + "examine": "Used for storage.", + "ids": "2530" + }, + { + "examine": "Looks like someone's tried digging here.", + "ids": "2531,2532" + }, + { + "examine": "A pile of what is hopefully mud.", + "ids": "2533" + }, + { + "examine": "There's black cross on the door.", + "ids": "2534" + }, + { + "examine": "The door is closed.", + "ids": "2535" + }, + { + "examine": "A door.", + "ids": "2536" + }, + { + "examine": "The door is closed.", + "ids": "2537" + }, + { + "examine": "A door.", + "ids": "2538" + }, + { + "examine": "A flight of stairs.", + "ids": "2539,2540" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "254" + }, + { + "examine": "An outlet to the sewer.", + "ids": "2541,2542" + }, + { + "examine": "There's a cover over this manhole.", + "ids": "2543" + }, + { + "examine": "I wonder where they will take me.", + "ids": "25432" + }, + { + "examine": "How dangerous, someone has left this manhole open.", + "ids": "2544" + }, + { + "examine": "This is supposed to stop people falling down the manhole.", + "ids": "2545" + }, + { + "examine": "A door.", + "ids": "2546,2547,2548,2549" + }, + { + "examine": "Potentially hot!", + "ids": "25464" + }, + { + "examine": "A goblin fire. Looks fierce.", + "ids": "25465" + }, + { + "examine": "Used for pulling things up.", + "ids": "255" + }, + { + "examine": "A secure door.", + "ids": "2550,2551" + }, + { + "examine": "A metal gate bars your way.", + "ids": "2552,2553" + }, + { + "examine": "A secure door.", + "ids": "2554,2555,2556,2557,2558,2559" + }, + { + "examine": "Fine silk woven by experts.", + "ids": "2560" + }, + { + "examine": "This stall smells great.", + "ids": "2561" + }, + { + "examine": "Precious stones from around the world.", + "ids": "2562" + }, + { + "examine": "All manner of animal clothing.", + "ids": "2563" + }, + { + "examine": "Spices to tingle your taste buds.", + "ids": "2564" + }, + { + "examine": "Fine silver items are for sale here.", + "ids": "2565" + }, + { + "examine": "I wonder what's inside it.", + "ids": "2566,2567,2568,2569,2570,2571,2572,2573,2574" + }, + { + "examine": "A marshy jungle vine.", + "ids": "2575,2576" + }, + { + "examine": "A tall palm tree with some plants growing at its stem.", + "ids": "2577" + }, + { + "examine": "A tall palm tree.", + "ids": "2578" + }, + { + "examine": "The burnt ground has a plant growing on it.", + "ids": "2579" + }, + { + "examine": "The ground has been burnt here by a fire.", + "ids": "2580" + }, + { + "examine": "A rock with green moss growing on it.", + "ids": "2581" + }, + { + "examine": "A rock, it looks like something was growing here.", + "ids": "2582" + }, + { + "examine": "It looks as if it is covered in some fungus.", + "ids": "2583" + }, + { + "examine": "A collection of rocks over what looks like a depression.", + "ids": "2584" + }, + { + "examine": "Rocky walls, you may be able to climb it.", + "ids": "2585" + }, + { + "examine": "It's closed.", + "ids": "2586" + }, + { + "examine": "I wonder what's inside?", + "ids": "2587" + }, + { + "examine": "It's open.", + "ids": "2588" + }, + { + "examine": "This ship's not getting far with that.", + "ids": "2589" + }, + { + "examine": "Takes me into the ship.", + "ids": "2590,2591" + }, + { + "examine": "Takes me back on deck.", + "ids": "2592" + }, + { + "examine": "Handy for boarding the ship.", + "ids": "2593,2594" + }, + { + "examine": "It's closed.", + "ids": "2595" + }, + { + "examine": "A blood-red door.", + "ids": "2596" + }, + { + "examine": "A lurid orange door.", + "ids": "2597" + }, + { + "examine": "A sickly yellow door.", + "ids": "2598" + }, + { + "examine": "A gloomy blue door.", + "ids": "2599" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "260" + }, + { + "examine": "A groovy magenta door.", + "ids": "2600" + }, + { + "examine": "A putrid green door.", + "ids": "2601" + }, + { + "examine": "Probably the nicest door in this ghastly place.", + "ids": "2602" + }, + { + "examine": "It's closed.", + "ids": "2603" + }, + { + "examine": "It's open.", + "ids": "2604" + }, + { + "examine": "It's a ladder.", + "ids": "2605" + }, + { + "examine": "There is something strange about this wall...", + "ids": "2606" + }, + { + "examine": "It's closed.", + "ids": "2607,2608" + }, + { + "examine": "A collection of rocks over what looks like a depression.", + "ids": "2609" + }, + { + "examine": "A rope hangs here that I can climb.", + "ids": "2610" + }, + { + "examine": "It's a ladder.", + "ids": "2611" + }, + { + "examine": "Wonder what's in here...", + "ids": "2612" + }, + { + "examine": "Smells kind of funny...", + "ids": "2613" + }, + { + "examine": "Looks comfortable...", + "ids": "2615" + }, + { + "examine": "Looks spooky...", + "ids": "2616" + }, + { + "examine": "Phew, an exit!", + "ids": "2617" + }, + { + "examine": "The fence is broken at this point.", + "ids": "2618" }, { "examine": "A wooden barrel for storage.", - "ids": "17308,31136,36798" + "ids": "2619" }, { - "examine": "A home for baby creatures.", - "ids": "32312" + "examine": "An old crate for storage.", + "ids": "2620" }, { - "examine": "Must have been laid by a huge bird.", - "ids": "32313" + "examine": "It's a door.", + "ids": "2621,2622" }, { - "examine": "Stops bits of building falling on me.", - "ids": "37451" + "examine": "It's a gate.", + "ids": "2623" + }, + { + "examine": "The entrance to the Hero's Guild.", + "ids": "2624,2625" + }, + { + "examine": "It's a door.", + "ids": "2626,2627,2628" + }, + { + "examine": "There is something unusual about this wall...", + "ids": "2629" + }, + { + "examine": "I can see eels swimming in the lava.", + "ids": "2630" + }, + { + "examine": "It's a door.", + "ids": "2631" + }, + { + "examine": "I wonder what's inside?", + "ids": "2632" + }, + { + "examine": "It's open.", + "ids": "2633" + }, + { + "examine": "Rocks that contain nothing interesting, but block the way.", + "ids": "2634" + }, + { + "examine": "I wonder what's inside?", + "ids": "2635" + }, + { + "examine": "It's open.", + "ids": "2636,2637" + }, + { + "examine": "A source of pure water.", + "ids": "2638,2639" + }, + { + "examine": "A shrine for the faithful to worship at.", + "ids": "2640" + }, + { + "examine": "I can climb this.", + "ids": "2641" + }, + { + "examine": "Used for fashioning clay items.", + "ids": "2642" + }, + { + "examine": "Bake your clay items in here.", + "ids": "2643" + }, + { + "examine": "Used for spinning thread.", + "ids": "2644" + }, + { + "examine": "A tray of sand.", + "ids": "2645" + }, + { + "examine": "A plant cultivated for fibres.", + "ids": "2646" + }, + { + "examine": "The door to the Crafting Guild.", + "ids": "2647,2648,2649" + }, + { + "examine": "Useful if there is any wind.", + "ids": "265" + }, + { + "examine": "A pile of smelly rotting waste.", + "ids": "2650" + }, + { + "examine": "A sturdy home for bees.", + "ids": "2651" + }, + { + "examine": "Looks like this is where waste from the kitchen comes out.", + "ids": "2652" + }, + { + "examine": "It looks like a spiders' nest to me.", + "ids": "2653" + }, + { + "examine": "This fountain suits the garden.", + "ids": "2654" + }, + { + "examine": "It's the Sinclair Family coat of arms.", + "ids": "2655" + }, + { + "examine": "Looks like this is where Anna keeps her stuff.", + "ids": "2656" + }, + { + "examine": "Looks like this is where Bob keeps his stuff.", + "ids": "2657" + }, + { + "examine": "Looks like this is where Carol keeps her stuff.", + "ids": "2658" + }, + { + "examine": "Looks like this is where David keeps his stuff.", + "ids": "2659" + }, + { + "examine": "Useful for making ships move.", + "ids": "266,267" + }, + { + "examine": "Looks like this is where Elizabeth keeps her stuff.", + "ids": "2660" + }, + { + "examine": "Looks like this is where Frank keeps his stuff.", + "ids": "2661" + }, + { + "examine": "Looks like this is where the cook stores flour.", + "ids": "2662" + }, + { + "examine": "Some sacks of general garden items.", + "ids": "2663" + }, + { + "examine": "Luckily it seems able to keep that vicious dog inside.", + "ids": "2664,2665" + }, + { + "examine": "Looks like the killer smashed this to leave the mansion.", + "ids": "2666" + }, + { + "examine": "Slaves are using this to pull up barrels of rocks from down below.", + "ids": "2667" + }, + { + "examine": "Slaves are placing barrels on this to haul them to the surface.", + "ids": "2668,2669" + }, + { + "examine": "A succulent cactus.", + "ids": "2670" + }, + { + "examine": "A less-than-succulent succulent.", + "ids": "2671" + }, + { + "examine": "I can try to make new items on this.", + "ids": "2672" + }, + { + "examine": "A solid looking gate.", + "ids": "2673,2674" + }, + { + "examine": "Large doors made of solid oak.", + "ids": "2675,2676" + }, + { + "examine": "A solid looking chest, it belongs to Captain Siad.", + "ids": "2677" + }, + { + "examine": "A selection of Captain Siad's Books.", + "ids": "2678" + }, + { + "examine": "A sturdy looking desk on which the Captain works.", + "ids": "2679" + }, + { + "examine": "Useful for making ships move", + "ids": "268" + }, + { + "examine": "A barrel containing rocks and mining debris.", + "ids": "2680" + }, + { + "examine": "An empty mining barrel.", + "ids": "2681" + }, + { + "examine": "The cart which takes barrels of rocks from the mining encampment to Al-Kharid.", + "ids": "2682" + }, + { + "examine": "Gives a lovely view of the desert, complete with metalic bars.", + "ids": "2683" + }, + { + "examine": "It seems to be used for moving rocks into and out of this area.", + "ids": "2684" + }, + { + "examine": "A solid looking gate.", + "ids": "2685,2686,2687,2688" + }, + { + "examine": "There's no getting around it, it's a fairly sturdy prison cell door.", + "ids": "2689" + }, + { + "examine": "Large solid, thick set oak doors", + "ids": "2690,2691" + }, + { + "examine": "It looks fairly sturdy.", + "ids": "2692" + }, + { + "examine": "This is used by Shantay and his men to take items to the bank on your behalf.", + "ids": "2693" }, { "examine": "I wonder what's under it?", @@ -20388,105 +9196,649 @@ "ids": "26934,36687" }, { - "examine": "A strong metal door.", - "ids": "29315,29316,29317,29318,29319,29320,29321,29322" + "examine": "A rocky rock.", + "ids": "2694,2695,2696,2697" }, { - "examine": "The body of a Dwarf savaged by Goblins.", - "ids": "15596" + "examine": "A cave which has been mined out.", + "ids": "2698,2699" }, { - "examine": "I don't know art, but I like it!", - "ids": "36809" + "examine": "The entrance to the tent.", + "ids": "2700,2701" }, { - "examine": "The wood burning here must be full of salt.", - "ids": "14169" + "examine": "Tracks in the sand.", + "ids": "2702,2703" }, { - "examine": "Sturdy looking.", - "ids": "21176" + "examine": "Rocky!", + "ids": "2704" }, { - "examine": "Doesn't look like it'll be sailing again.", - "ids": "14173" + "examine": "It's a door.", + "ids": "2705" }, { - "examine": "Looks a bit damp.", - "ids": "14174" + "examine": "A nicely fitted door.", + "ids": "2706" + }, + { + "examine": "A wooden crate for storage.", + "ids": "2707,2708" + }, + { + "examine": "I wonder what's inside?", + "ids": "2709" + }, + { + "examine": "How much does this weigh?", + "ids": "271" + }, + { + "examine": "It's open.", + "ids": "2710" + }, + { + "examine": "It's a flight of stairs.", + "ids": "2711" + }, + { + "examine": "The door is closed.", + "ids": "2712" + }, + { + "examine": "Grain goes in here.", + "ids": "2713,2714,2715,2716,2717" + }, + { + "examine": "These control the flow of grain from the hopper to the millstones.", + "ids": "2718,2719,2720,2721,2722" + }, + { + "examine": "I can climb up here.", + "ids": "272" + }, + { + "examine": "A spicy meat kebab is cooking here.", + "ids": "2723" + }, + { + "examine": "A fire burns brightly here.", + "ids": "2724" + }, + { + "examine": "A grand old fireplace.", + "ids": "2725,2726" + }, + { + "examine": "Something is cooking nicely here.", + "ids": "2727" + }, + { + "examine": "Ideal for cooking on.", + "ids": "2728,2729,2730,2731,3039,9682,12102,36973,40110" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "273" + }, + { + "examine": "Hot!", + "ids": "2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780" + }, + { + "examine": "A conveniently rolled sail.", + "ids": "274,275,276,277,278,279" + }, + { + "examine": "A hot place for forging things in.", + "ids": "2781" + }, + { + "examine": "It says \"Property of Doric the dwarf.\" on the side.", + "ids": "2782" + }, + { + "examine": "Used for fashioning metal items.", + "ids": "2783" + }, + { + "examine": "Various implements for working with metal.", + "ids": "2784" + }, + { + "examine": "A hot place for forging things in.", + "ids": "2785" + }, + { + "examine": "An entrance to Gu'Tanoth.", + "ids": "2786,2787,2788,2789" + }, + { + "examine": "I wonder what's inside it.", + "ids": "2790" + }, + { + "examine": "A counter made from a stone block.", + "ids": "2791,2792,2876,3800,29356" + }, + { + "examine": "An ogre is selling cakes here.", + "ids": "2793" + }, + { + "examine": "A lever for activating something.", + "ids": "2794,2795" + }, + { + "examine": "This leads to the watchtower.", + "ids": "2796" + }, + { + "examine": "This leads downwards.", + "ids": "2797" + }, + { + "examine": "A leafy bush.", + "ids": "2798,2799,2800,2801,2802,2803" + }, + { + "examine": "I think I can squeeze through here...", + "ids": "2804,2805,2806,2807,2808,2809,2810,2811" + }, + { + "examine": "This leads downwards.", + "ids": "2812" + }, + { + "examine": "I think I can squeeze through here...", + "ids": "2813" + }, + { + "examine": "The gate has been locked shut.", + "ids": "2814,2815" + }, + { + "examine": "A strange looking rock...", + "ids": "2816" + }, + { + "examine": "I think I can get out here...", + "ids": "2817,2818,2819,2820,2821,2822" + }, + { + "examine": "A hole.", + "ids": "2823" + }, + { + "examine": "A hole", + "ids": "2824" + }, + { + "examine": "I hope this leads the way out.", + "ids": "2825" + }, + { + "examine": "I wonder what's inside it?", + "ids": "2826,2827,2828,2829" + }, + { + "examine": "You can probably jump over from here.", + "ids": "2830,2831" + }, + { + "examine": "A low wall is blocking your path.", + "ids": "2832" + }, + { + "examine": "This goes up!", + "ids": "2833" + }, + { + "examine": "Sure it's gilded, but would you want to live in it?", + "ids": "28335" + }, + { + "examine": "It incubates eggs.", + "ids": "28336" + }, + { + "examine": "It's a basket for cats.", + "ids": "28337" + }, + { + "examine": "It's a basket for dogs.", + "ids": "28338" + }, + { + "examine": "Enough baskets for any dog's needs.", + "ids": "28339" + }, + { + "examine": "A low wall is blocking your path.", + "ids": "2834" + }, + { + "examine": "Lots of little fishies.", + "ids": "28340" + }, + { + "examine": "Keeps the puppies out of trouble.", + "ids": "28341" + }, + { + "examine": "It's good for bedding and stuffing.", + "ids": "28343" + }, + { + "examine": "Things are cheaper by the pound.", + "ids": "28344" + }, + { + "examine": "Made by the A. Wilson Company.", + "ids": "28345" + }, + { + "examine": "Looks hard.", + "ids": "2835,2836,2837,2838,2839,2840,2841" + }, + { + "examine": "They know how much that dog in the window is.", + "ids": "28351" + }, + { + "examine": "Lots of things for a growing pup.", + "ids": "28353" + }, + { + "examine": "Lots of things for a growing kitten.", + "ids": "28354" + }, + { + "examine": "Lots of things for a growing fish.", + "ids": "28355" + }, + { + "examine": "It seems to be sat happily on the counter.", + "ids": "28356" + }, + { + "examine": "Lots of things for a growing pup/kitten/fish.", + "ids": "28357" + }, + { + "examine": "There are a lot of pet supplies here.", + "ids": "28357,28358,28363,28364" + }, + { + "examine": "Fetch!", + "ids": "28360" + }, + { + "examine": "It's covered in hairs.", + "ids": "28361" + }, + { + "examine": "It has a special magical quality.", + "ids": "2842" + }, + { + "examine": "This drain leads from the sink to the sewers below.", + "ids": "2843" + }, + { + "examine": "This looks like it can be turned.", + "ids": "2844,2845,2846,2847,2848" + }, + { + "examine": "A rudimentary type of boat.", + "ids": "2849" + }, + { + "examine": "It's closed.", + "ids": "2850" + }, + { + "examine": "It's open.", + "ids": "2851" + }, + { + "examine": "I can probably squeeze my way inside there.", + "ids": "2852" + }, + { + "examine": "It's a flight of stairs.", + "ids": "2853" + }, + { + "examine": "Made of wood.", + "ids": "2854,2855" + }, + { + "examine": "I wonder what's inside?", + "ids": "2856" + }, + { + "examine": "It's open.", + "ids": "2857" + }, + { + "examine": "Used for storage.", + "ids": "2858" }, { "examine": "Those druids certainly make the best of natural resources.", "ids": "28588,28589" }, + { + "examine": "A hot range, where some soup is bubbling nicely.", + "ids": "2859" + }, + { + "examine": "Very ominous.", + "ids": "2860" + }, + { + "examine": "It's a door.", + "ids": "2861,2862" + }, + { + "examine": "A place to sit and watch furniture grow.", + "ids": "28627" + }, + { + "examine": "The door is closed.", + "ids": "2863" + }, + { + "examine": "It's not rolling, but it seems to have gathered some moss.", + "ids": "28635" + }, { "examine": "Sit back and relax...", "ids": "28636,18488" }, { - "examine": "One horsepower; wooden suspension: a beauty.", - "ids": "34376" + "examine": "A water feature.", + "ids": "2864" }, { - "examine": "I don't even want to think about what did that...", - "ids": "32071" + "examine": "It's a gate.", + "ids": "2865,2866" }, { - "examine": "It's a door.", - "ids": "31838" + "examine": "Very decorative!", + "ids": "2867" }, { - "examine": "Wooden crates for storage.", - "ids": "31138,31139" + "examine": "It's a cupboard.", + "ids": "2868,2869" }, { - "examine": "These may have something in them.", - "ids": "32049,36929" + "examine": "A thick metal gate.", + "ids": "28690,28691,28692,28693" }, { - "examine": "Probably looked better mounted on the dragon's neck.", - "ids": "15564" + "examine": "I'm not allowed to climb this ladder.", + "ids": "287" }, { - "examine": "A magical wall decoration.", - "ids": "32324,32325" + "examine": "The mouse equivalent of a door.", + "ids": "2870" }, { - "examine": "Perhaps I should search this.", - "ids": "32009" + "examine": "I can climb down this.", + "ids": "2871" }, { - "examine": "The door is closed.", - "ids": "31808" + "examine": "Make a wish.", + "ids": "28715" }, { - "examine": "The door is open.", - "ids": "31809" + "examine": "Glowing with barely-suppressed energies.", + "ids": "28719" }, { - "examine": "The bank teller will serve you from here.", - "ids": "36786" + "examine": "I can climb this.", + "ids": "2872" }, { - "examine": "Closed for business.", - "ids": "36787" + "examine": "Contains no summoning energy.", + "ids": "28720,28721" }, { - "examine": "Banking transactions are processed here.", - "ids": "36789,37158" + "examine": "What a good likeness!", + "ids": "2873" }, { - "examine": "This will give me a bit more information.", - "ids": "29461,29462,29463,29464" + "examine": "A depiction that chills one to the bone.", + "ids": "2874" + }, + { + "examine": "I wonder how accurate a representation this is.", + "ids": "2875" + }, + { + "examine": "A barrel full of staffs...", + "ids": "2877" + }, + { + "examine": "Patterns of light dance hypnotically across the pool's surface.", + "ids": "2878,2879" + }, + { + "examine": "There seems to be some sort of magical field here.", + "ids": "2880" + }, + { + "examine": "It's closed.", + "ids": "2881" + }, + { + "examine": "The toll gate from Lumbridge to Al-Kharid.", + "ids": "2882,2883" + }, + { + "examine": "I can climb this.", + "ids": "2884" + }, + { + "examine": "An antique by anyone's standards.", + "ids": "2885" + }, + { + "examine": "An antique by anyone's standards, however, it might have something interesting in it.", + "ids": "2886" + }, + { + "examine": "Looks good for logging.", + "ids": "2887" + }, + { + "examine": "A leafy jungle palm, dense foliage.", + "ids": "2888" + }, + { + "examine": "Home to many unusual creatures.", + "ids": "2889" + }, + { + "examine": "A leafy tree.", + "ids": "2890" + }, + { + "examine": "This tree has been cut down.", + "ids": "2891" + }, + { + "examine": "A jungle bush, quite common to these areas.", + "ids": "2892,2893" + }, + { + "examine": "A jungle bush that has been chopped down.", + "ids": "2894,2895" + }, + { + "examine": "A door to the Legends Guild.", + "ids": "2896,2897,2898,2899" + }, + { + "examine": "Looks slippery!", + "ids": "2900,2901" + }, + { + "examine": "Stoney!", + "ids": "2902" + }, + { + "examine": "A rather shadowy cavern entrance.", + "ids": "2903,2904" + }, + { + "examine": "An old crate for storage.", + "ids": "2905" + }, + { + "examine": "Useful for putting things on.", + "ids": "2906" + }, + { + "examine": "I guess I could sleep in it if I was really tired.", + "ids": "2907" + }, + { + "examine": "A wall of magic fire.", + "ids": "2908,2909" + }, + { + "examine": "Rickety bamboo tables that are lashed together to make a desk.", + "ids": "2910" + }, + { + "examine": "Bamboo storage!", + "ids": "2911" + }, + { + "examine": "This gate has a horribly complex locking mechanism.", + "ids": "2912,2913,2914,2915" + }, + { + "examine": "A dark cave entrance leading to the surface.", + "ids": "2916,2917" + }, + { + "examine": "A large crack in the wall.", + "ids": "2918" + }, + { + "examine": "A huge lump of rock.", + "ids": "2919,2920,2921" + }, + { + "examine": "A heavily constructed, cast-iron, ancient gateway.", + "ids": "2922,2923,2924,2925" + }, + { + "examine": "A high wall made up of rocks with sharp edges.", + "ids": "2926" + }, + { + "examine": "It looks like ancient graffiti.", + "ids": "2927" + }, + { + "examine": "An ornately carved rock with a pointed receptacle.", + "ids": "2928" + }, + { + "examine": "A half buried skeleton, probably dwarven remains.", + "ids": "2929" + }, + { + "examine": "A huge, strangely constructed doorway, not sure how this opens.", + "ids": "2930" + }, + { + "examine": "It looks like a magical portal of some kind, who knows where it leads?", + "ids": "2931" + }, + { + "examine": "A strong metal door.", + "ids": "29315,29316,29317,29318,29319,29320,29321,29322" + }, + { + "examine": "Strangely, there's a locked barrel here, I wonder what's inside.", + "ids": "2932,2933" + }, + { + "examine": "A large scaffold platform most likely used for lifting and lowering heavy items.", + "ids": "2934" + }, + { + "examine": "Used to move earth to, and from, the dig shaft. A rope has been thrown over it.", + "ids": "2935" + }, + { + "examine": "An old crate for storage.", + "ids": "29351,29352,31137,31140" + }, + { + "examine": "A sculpted trunk of wood.", + "ids": "2936,2937,2938,2939" + }, + { + "examine": "Warning! Danger of death.", + "ids": "29373" + }, + { + "examine": "A wonderfully dressed table.", + "ids": "2940" + }, + { + "examine": "I wonder what's inside.", + "ids": "29400,32010,40093" + }, + { + "examine": "Sparkling sacred water straight from the source.", + "ids": "2941" + }, + { + "examine": "A sparkling, babbling flow of water from an underground source.", + "ids": "2942" + }, + { + "examine": "Disgusting filthy quagmire that oozes from the ground.", + "ids": "2943" + }, + { + "examine": "Found near the water's edge.", + "ids": "2944" + }, + { + "examine": "A baby Yommi tree, it has a mystical aura.", + "ids": "2945" + }, + { + "examine": "An adolescent-looking Yommi tree, it has a mystical aura.", + "ids": "2946" }, { "examine": "I can climb over the fence using this.", "ids": "29460" }, + { + "examine": "This will give me a bit more information.", + "ids": "29461,29462,29463,29464" + }, { "examine": "It looks slightly rickety.", "ids": "29468" }, + { + "examine": "A dead Yommi tree sapling, you'll need a tough axe to remove this.", + "ids": "2947" + }, { "examine": "These probably contain Farming supplies.", "ids": "29471" @@ -20503,6 +9855,30 @@ "examine": "I wonder what's buried here.", "ids": "29476,29477,29478" }, + { + "examine": "A fully grown Yommi tree, it won't get much taller than this.", + "ids": "2948" + }, + { + "examine": "A dead fully grown Yommi tree, you'll need a tough, sharp axe to remove this.", + "ids": "2949" + }, + { + "examine": "A felled adult Yommi tree, perhaps you should trim those branches?", + "ids": "2950" + }, + { + "examine": "A rotten felled Yommi tree, it was left too long in the damp jungle.", + "ids": "2951" + }, + { + "examine": "A trimmed Yommi tree log, perfect for sculpting into a totem pole.", + "ids": "2952" + }, + { + "examine": "A rotten Yommi tree log, it was left too long in the damp jungle air.", + "ids": "2953" + }, { "examine": "So small only a rabbit could squeeze down.", "ids": "29533" @@ -20512,168 +9888,1044 @@ "ids": "29534" }, { - "examine": "Potentially hot!", - "ids": "25464" + "examine": "A beautifully crafted totem pole carved from the trunk of the sacred Yommi tree.", + "ids": "2954" }, { - "examine": "A goblin fire. Looks fierce.", - "ids": "25465" + "examine": "A rotten totem pole, it was left to rot in the jungle.", + "ids": "2955" }, { - "examine": "A wooden crate for storage.", - "ids": "18506" + "examine": "This earth is particularly fertile.", + "ids": "2956" }, { - "examine": "A pile of crates for storage.", - "ids": "18508" + "examine": "This earth is damaged by cultivation, time will restore the fertility.", + "ids": "2957" }, { - "examine": "I wonder where they will take me.", - "ids": "25432" + "examine": "A rope hangs here.", + "ids": "2958" }, { - "examine": "'Pay back all your debts by borrowing more money from us!' Clever.", - "ids": "23924" + "examine": "A dangerous path onwards.", + "ids": "2959,2960,2961" + }, + { + "examine": "It's like a land rudder.", + "ids": "296" + }, + { + "examine": "Stoney!", + "ids": "2962,2963,2964" + }, + { + "examine": "Looks slippery!", + "ids": "2965" + }, + { + "examine": "A hot place for forging things in.", + "ids": "2966,2967,2968" + }, + { + "examine": "It looks like a strangely shaped depression in the rock.", + "ids": "2969" + }, + { + "examine": "Disturbingly man-like.", + "ids": "297" + }, + { + "examine": "This recess has a glowing heart shaped crystal in it.", + "ids": "2970" + }, + { + "examine": "This looks like some sort of shimmering surface.", + "ids": "2971" + }, + { + "examine": "A huge lump of rock.", + "ids": "2972,2973,2974" + }, + { + "examine": "This tree is particularly leafy.", + "ids": "2975,2976" + }, + { + "examine": "A large pile of sand", + "ids": "2977" + }, + { + "examine": "A medium pile of sand", + "ids": "2978" + }, + { + "examine": "A small pile of sand", + "ids": "2979" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "298,299,300" + }, + { + "examine": "Some beautiful flowers.", + "ids": "2980,2981,2982,2983,2984,2985,2986,2987,2988" + }, + { + "examine": "Known commonly as Red worm vine.", + "ids": "2989,2990,2991,2992,2993,2994" + }, + { + "examine": "Contains traces of summoning energy.", + "ids": "29939,29943,29944,29945,29947,29951,29952,29953,29954" + }, + { + "examine": "I wonder what's inside.", + "ids": "2995,2996" + }, + { + "examine": "The door is closed.", + "ids": "2997" + }, + { + "examine": "The door is open.", + "ids": "2998,2999" + }, + { + "examine": "The door is closed.", + "ids": "3,4" + }, + { + "examine": "These obviously mean keep out!", + "ids": "3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013" + }, + { + "examine": "Animals have no table manners.", + "ids": "301" + }, + { + "examine": "A nicely fitted door.", + "ids": "3014" + }, + { + "examine": "A wooden gate.", + "ids": "3015,3016" + }, + { + "examine": "A nicely fitted door.", + "ids": "3017,3018,3019" + }, + { + "examine": "A home for baby creatures.", + "ids": "302" + }, + { + "examine": "A wrought iron gate.", + "ids": "3020,3021,3022,3023" + }, + { + "examine": "A closed door.", + "ids": "3024,3025,3026,3027" + }, + { + "examine": "I can climb this.", + "ids": "3028" + }, + { + "examine": "I can climb down this.", + "ids": "3029" + }, + { + "examine": "In the city we would call this mouldy rubbish.", + "ids": "303" + }, + { + "examine": "I can climb this.", + "ids": "3030" + }, + { + "examine": "I can climb down this.", + "ids": "3031" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "3032" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "3033,3034,3035,3036" + }, + { + "examine": "A beautiful old oak.", + "ids": "3037" + }, + { + "examine": "Hot!", + "ids": "3038" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "304" + }, + { + "examine": "It's closed.", + "ids": "3040" + }, + { + "examine": "It's open.", + "ids": "3041" + }, + { + "examine": "A rocky outcrop.", + "ids": "3042,3043" + }, + { + "examine": "A hot place for forging things in.", + "ids": "3044" }, { "examine": "The bank teller will serve you from here.", - "ids": "11402" + "ids": "3045" }, { - "examine": "I can climb up these stairs.", - "ids": "24349" + "examine": "These obviously mean keep out!", + "ids": "3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076" }, { - "examine": "A handy place for filling in forms and paperwork.", - "ids": "23928" + "examine": "Where bees live.", + "ids": "305" }, { - "examine": "Where people may put themselves.", - "ids": "17462" + "examine": "It looks slightly different from the rest.", + "ids": "30532" }, { - "examine": "For keeping things in.", - "ids": "24924" + "examine": "A used cart seller will probably try and sell it later.", + "ids": "306" }, { - "examine": "Contains quite a lot of someone else's property.", - "ids": "23925" + "examine": "The inscription is worn away and unreadable.", + "ids": "30667,30669" }, { - "examine": "This chest looks strong.", - "ids": "23926" + "examine": "Whoever bought this must have really cared for the inhabitant.", + "ids": "30668" }, { - "examine": "They say money can't buy happiness.", - "ids": "23929" + "examine": "'Here lies...' is all I can read.", + "ids": "30671,30672" }, { - "examine": "A gilt sculpture of a monarch.", - "ids": "23930" + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "307,308" }, { - "examine": "Cave exit.", - "ids": "15812" + "examine": "Lean against the wall to get a better view!", + "ids": "3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107" }, { - "examine": "A flag on a pole.", - "ids": "37335" + "examine": "Dead tree parts piled together neatly.", + "ids": "309" + }, + { + "examine": "A patch of soft dark brown matter. Probably mud.", + "ids": "310" + }, + { + "examine": "Flags marking the entrance to the arena.", + "ids": "3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158" + }, + { + "examine": "A pile of something I hope is mud.", + "ids": "311" + }, + { + "examine": "Wooden crates for storage.", + "ids": "31138,31139" + }, + { + "examine": "Potato-licious!", + "ids": "312" + }, + { + "examine": "An interesting sign.", + "ids": "31297,31298,31299,31300,31301" + }, + { + "examine": "Baby bread.", + "ids": "313" + }, + { + "examine": "Beats the operating table.", + "ids": "3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,3174,3175,3176,3177,3178,3179,3180,3181" + }, + { + "examine": "The door is closed.", + "ids": "31808" + }, + { + "examine": "The door is open.", + "ids": "31809" + }, + { + "examine": "Wait here for a nurse.", + "ids": "3182" + }, + { + "examine": "Storage for drugs and bandages.", + "ids": "3183,3184,3185" + }, + { + "examine": "It's a door.", + "ids": "31838" + }, + { + "examine": "I don't really want to end up here...", + "ids": "3186,3187,3188,3189" + }, + { + "examine": "These open and close!", + "ids": "3190" + }, + { + "examine": "This may be worth searching.", + "ids": "3191" + }, + { + "examine": "You can see the last 50 fights on here.", + "ids": "3192" + }, + { + "examine": "Used to store players' items whilst they duel.", + "ids": "3193" + }, + { + "examine": "Use for quick access to your bank.", + "ids": "3194" + }, + { + "examine": "Smells pretty bad!", + "ids": "3195" + }, + { + "examine": "Not much use for anything except scrap.", + "ids": "3196" + }, + { + "examine": "Entrance to the Duel Arena.", + "ids": "3197,3198" + }, + { + "examine": "A wooden double bed.", + "ids": "3199,3200,3201,3202" + }, + { + "examine": "Perhaps I should search this.", + "ids": "32009" + }, + { + "examine": "I can climb this.", + "ids": "32015" + }, + { + "examine": "Access to the duel arena.", + "ids": "3203,3204" + }, + { + "examine": "Technically a bed.", + "ids": "32031" + }, + { + "examine": "These may have something in them.", + "ids": "32049,36929" + }, + { + "examine": "I can climb down this.", + "ids": "3205" + }, + { + "examine": "A barrel full of staffs...", + "ids": "3206,3207,3208" + }, + { + "examine": "I don't even want to think about what did that...", + "ids": "32071" + }, + { + "examine": "Now that's what I call slimline!", + "ids": "32072" + }, + { + "examine": "A strange crack cuts into the wall.", + "ids": "3209,3210,3211,3212,29360,29362" + }, + { + "examine": "It looks like I can squeeze through here.", + "ids": "3213" + }, + { + "examine": "The easy way out...", + "ids": "3214,3215" + }, + { + "examine": "A pile of mud.", + "ids": "3216" + }, + { + "examine": "I can go through here.", + "ids": "3217" + }, + { + "examine": "Dark and intimidating.", + "ids": "3218,3219" + }, + { + "examine": "That skull's looking at me....", + "ids": "3220,3221" + }, + { + "examine": "I can climb down these.", + "ids": "3222" + }, + { + "examine": "I can climb up these.", + "ids": "3223" + }, + { + "examine": "I can go through here.", + "ids": "3224,3225,3226" + }, + { + "examine": "Best not to get caught!", + "ids": "3227" + }, + { + "examine": "Best avoided.", + "ids": "3228,3229" + }, + { + "examine": "Looks kind of like a man made of metal.", + "ids": "32292" + }, + { + "examine": "A tatty old standard.", + "ids": "32295" + }, + { + "examine": "Looks suspicious.", + "ids": "3230" + }, + { + "examine": "A plank.", + "ids": "3231" + }, + { + "examine": "A home for baby creatures.", + "ids": "32312" + }, + { + "examine": "Must have been laid by a huge bird.", + "ids": "32313" + }, + { + "examine": "Formed over many years.", + "ids": "3232" + }, + { + "examine": "A magical wall decoration.", + "ids": "32324,32325" + }, + { + "examine": "A really bad portrait of the King.", + "ids": "32326" + }, + { + "examine": "Best avoided.", + "ids": "3233" + }, + { + "examine": "Looks suspicious.", + "ids": "3234" + }, + { + "examine": "I can open the grill from this side.", + "ids": "3235" + }, + { + "examine": "Maybe I can cross that.", + "ids": "3238" + }, + { + "examine": "It looks like only the guide ropes are holding the bridge up.", + "ids": "3239" + }, + { + "examine": "A bridge.", + "ids": "3240" + }, + { + "examine": "This lever can be operated.", + "ids": "3241,3242" + }, + { + "examine": "The base of a platform.", + "ids": "3243,3244,3245,3246" + }, + { + "examine": "A bridge.", + "ids": "3247,3248,3249,3250,3251,3252,3253" + }, + { + "examine": "I can't get past that very easily...", + "ids": "3254,3255,3256" + }, + { + "examine": "A platform.", + "ids": "3257" + }, + { + "examine": "A bridge.", + "ids": "3258,3259,3260,3261,3262" + }, + { + "examine": "This area may not be safe...", + "ids": "3263" + }, + { + "examine": "A well of nastiness.", + "ids": "3264" + }, + { + "examine": "I can climb this pile of rocks...", + "ids": "3265" + }, + { + "examine": "Usually used for storing living things...", + "ids": "3266,3267,3268,3269" + }, + { + "examine": "The remains of a bad driver.", + "ids": "327" + }, + { + "examine": "The door is closed.", + "ids": "3270" + }, + { + "examine": "The door is open.", + "ids": "3271" + }, + { + "examine": "I wonder what's inside.", + "ids": "3272,3273,3274,3275" + }, + { + "examine": "A stone bridge.", + "ids": "3276,3277,3278,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293" + }, + { + "examine": "A hot place for forging things in.", + "ids": "3294" + }, + { + "examine": "It's covered in strange writing.", + "ids": "3295,3296,3297,3298,3299,3300,3301,3302" + }, + { + "examine": "Yup, definitely a lever.", + "ids": "33,34,35,36" + }, + { + "examine": "You won't be able to lift that.", + "ids": "3303" + }, + { + "examine": "A portcullis.", + "ids": "3304" + }, + { + "examine": "It doesn't look like water in there...", + "ids": "3305,3306" + }, + { + "examine": "A pile of rocks.", + "ids": "3307" + }, + { + "examine": "The boulder has smashed through the cage.", + "ids": "3308" + }, + { + "examine": "A deposit of rocks.", + "ids": "3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326" + }, + { + "examine": "Intimidating!", + "ids": "3327" + }, + { + "examine": "A depiction of a great dwarf miner.", + "ids": "3328,3329,3330,3331" + }, + { + "examine": "A temple door.", + "ids": "3332" + }, + { + "examine": "A very big door.", + "ids": "3333,3334,3335,3336" + }, + { + "examine": "This lever can be operated.", + "ids": "3337" + }, + { + "examine": "Why would a log be hung up there?", + "ids": "3338" + }, + { + "examine": "Looks suspicious.", + "ids": "3339" + }, + { + "examine": "Looks like the rope is holding the bridge up.", + "ids": "3340" + }, + { + "examine": "Looks like the other rope is holding the bridge up.", + "ids": "3341,3342" + }, + { + "examine": "A pile of rocks.", + "ids": "3343" + }, + { + "examine": "It's got dwarf brew in it.", + "ids": "3344,3345,3346,3347" + }, + { + "examine": "Lord Iban's Throne.", + "ids": "3348,3349,3350" + }, + { + "examine": "I'm glad I'm on this side of those bars.", + "ids": "3351,3352" + }, + { + "examine": "I don't much like the look of that...", + "ids": "3353,3354,3355,3356,3357,3358" + }, + { + "examine": "Well of the damned.", + "ids": "3359" + }, + { + "examine": "A wooden crate for storage.", + "ids": "3360" + }, + { + "examine": "A magical sphere that glimmers within.", + "ids": "3361" + }, + { + "examine": "A window.", + "ids": "3362,3363" + }, + { + "examine": "An odd looking rock formation.", + "ids": "3364" + }, + { + "examine": "Looks like I can climb these.", + "ids": "3365" + }, + { + "examine": "Makes you cry.", + "ids": "3366" + }, + { + "examine": "Steel bars that are locked securely.", + "ids": "3367,3368,3369,3370" + }, + { + "examine": "An Achey tree stump.", + "ids": "3371" + }, + { + "examine": "Useful for ogre dinners.", + "ids": "3372,3373,3374,3375" + }, + { + "examine": "An ogre bench, useful for taking all that weight off their legs.", + "ids": "3376" + }, + { + "examine": "Hmmm, a rock for a lock....", + "ids": "3377" + }, + { + "examine": "Some stealthy thief must have picked the ogre lock!", + "ids": "3378" + }, + { + "examine": "The entrance to Rantz's cave", + "ids": "3379" + }, + { + "examine": "Exit this way for fresh air and daylight.", + "ids": "3380,3381" + }, + { + "examine": "Useful for ogre dinners.", + "ids": "3382,3383,3384,3385,3386,3387,3388" + }, + { + "examine": "A good source of books!", + "ids": "3389" + }, + { + "examine": "A strange crack cuts into the wall.", + "ids": "3390,3391,3392,3393" + }, + { + "examine": "A wooden crate for storage.", + "ids": "3394,3395" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "3396,3397" + }, + { + "examine": "A wooden crate for storage.", + "ids": "3398,3399,3400,3401" + }, + { + "examine": "Used for fashioning metal items.", + "ids": "3402" + }, + { + "examine": "A pile of Elemental rock.", + "ids": "3403" + }, + { + "examine": "A valve to start and stop the flow of water.", + "ids": "3404,3405" + }, + { + "examine": "This lever can be operated.", + "ids": "3406" + }, + { + "examine": "It spins.", + "ids": "3407,3408" + }, + { + "examine": "This lever can be operated.", + "ids": "3409" + }, + { + "examine": "Big bellows.", + "ids": "3410,3411,3412" + }, + { + "examine": "A furnace with an air blast pipe.", + "ids": "3413" + }, + { + "examine": "A small trough full of lava.", + "ids": "3414" }, { "examine": "I can climb down these stairs.", - "ids": "36775,36778" + "ids": "3415" }, { - "examine": "Jump here.", - "ids": "23271" + "examine": "I can climb up these stairs.", + "ids": "3416" }, { - "examine": "Popular on sandy beaches where fruity cocktails may be found.", - "ids": "18856" + "examine": "This lever can be operated.", + "ids": "3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428" }, { - "examine": "Looks like part of the entrance is blocked by rubble.", - "ids": "15767" + "examine": "Water powered machinery.", + "ids": "3429,3430" }, { - "examine": "They know how much that dog in the window is.", - "ids": "28351" + "examine": "Stoney!", + "ids": "3431" }, { - "examine": "Lots of things for a growing fish.", - "ids": "28355" + "examine": "I wonder what's under it?", + "ids": "3432" }, { - "examine": "It's a basket for dogs.", - "ids": "28338" + "examine": "I can see a holy barrier at the bottom.", + "ids": "3433,3434,3435,3436,3437,3438,3439" }, { - "examine": "Enough baskets for any dog's needs.", - "ids": "28339" + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "34376" }, { - "examine": "Made by the A. Wilson Company.", - "ids": "28345" + "examine": "They let you walk up them!", + "ids": "3440" }, { - "examine": "Sure it's gilded, but would you want to live in it?", - "ids": "28335" + "examine": "They let you walk down them!", + "ids": "3441,3442" }, { - "examine": "It's covered in hairs.", - "ids": "28361" + "examine": "A holy barrier blocking evil forces.", + "ids": "3443" }, { - "examine": "It's good for bedding and stuffing.", - "ids": "28343" + "examine": "A sturdy metal gate.", + "ids": "3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,3460,3461,3462" }, { - "examine": "Lots of little fishies.", - "ids": "28340" + "examine": "The perfect place to store things.", + "ids": "346,347" }, { - "examine": "Fetch!", - "ids": "28360" + "examine": "A hastily constructed yet sturdy prison door.", + "ids": "3463,3464,3465" }, { - "examine": "It's a basket for cats.", - "ids": "28337" + "examine": "Dead animal parts dangling!", + "ids": "3466" }, { - "examine": "It seems to be sat happily on the counter.", - "ids": "28356" + "examine": "So how long has this been dead, then?", + "ids": "3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478" }, { - "examine": "Lots of things for a growing pup.", - "ids": "28353" + "examine": "A statue honouring Saradomin.", + "ids": "3479" }, { - "examine": "Lots of things for a growing kitten.", - "ids": "28354" + "examine": "These open and close!", + "ids": "348" }, { - "examine": "Lots of things for a growing pup/kitten/fish.", - "ids": "28357" + "examine": "An ornately decorated coffin. Something seems to be alive inside.", + "ids": "3480,3481,3482,3483,3484" }, { - "examine": "Things are cheaper by the pound.", - "ids": "28344" + "examine": "An ornately carved well that draws water from the river Salve.", + "ids": "3485,3486,3487,3488" }, { - "examine": "It incubates eggs.", - "ids": "28336" + "examine": "Sturdy looking door.", + "ids": "3489,3490,3491,3492" }, { - "examine": "There are a lot of pet supplies here.", - "ids": "28357,28358,28363,28364" + "examine": "This may be worth searching.", + "ids": "349" }, { - "examine": "Keeps the puppies out of trouble.", - "ids": "28341" + "examine": "A monument to a fallen priest.", + "ids": "3493,3494,3495,3496,3497,3498,3499" }, { - "examine": "Warning! Danger of death.", - "ids": "29373" + "examine": "These open and close!", + "ids": "350" + }, + { + "examine": "With skill I can play this.", + "ids": "3500,3501,3502,3503,3504,3505" + }, + { + "examine": "A wrought iron gate.", + "ids": "3506,3507" + }, + { + "examine": "Not sure if I should sit on that.", + "ids": "3508,3509" + }, + { + "examine": "This may be worth searching.", + "ids": "351" + }, + { + "examine": "Not sure if that's any use.", + "ids": "3510,3511" + }, + { + "examine": "It'll probably die soon.", + "ids": "3512,3513" + }, + { + "examine": "Not sure if I should stand under that.", + "ids": "3514,3515" + }, + { + "examine": "A dark dank entrance to below.", + "ids": "3516" + }, + { + "examine": "A large tree thriving where trees normally die.", + "ids": "3517,3518,3519" + }, + { + "examine": "These open and close!", + "ids": "352" + }, + { + "examine": "Special grotto area.", + "ids": "3520" + }, + { + "examine": "A grotto transformed into an altar of nature.", + "ids": "3521" + }, + { + "examine": "It's a bridge.", + "ids": "3522" + }, + { + "examine": "An old bench, probably made from wood in this swamp.", + "ids": "3523,3524" + }, + { + "examine": "The door.", + "ids": "3525" + }, + { + "examine": "The green door.", + "ids": "3526" + }, + { + "examine": "A roughly hewn stone with some sort of symbol on it.", + "ids": "3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545" + }, + { + "examine": "This may be worth searching.", + "ids": "353" + }, + { + "examine": "A wooden crate for storage.", + "ids": "354,355" + }, + { + "examine": "There is a rope leading to the bottom of this well.", + "ids": "3546,3547,3548,3549,3550" + }, + { + "examine": "I can balance on this rope.", + "ids": "3551,3552" + }, + { + "examine": "I can balance on this log.", + "ids": "3553,3554,3555,3556,3557,3558" + }, + { + "examine": "Tread carefully!", + "ids": "3559,3560,3561,3562" + }, + { + "examine": "An old crate for storage.", + "ids": "356,357,358" + }, + { + "examine": "Now, I'm the king of the swingers, oh, the jungle VIP.", + "ids": "3563,3564" + }, + { + "examine": "It looks like I can clamber over this.", + "ids": "3565" + }, + { + "examine": "Use this to swing over to the next platform.", + "ids": "3566" + }, + { + "examine": "I might want to avoid this nasty blade.", + "ids": "3567,3568,3569" + }, + { + "examine": "Walk the plank! Ya land lubber!", + "ids": "3570,3571,3572,3573,3574,3575,3576,3577" + }, + { + "examine": "It's a small step for a player, a giant leap for player kind.", + "ids": "3578,3579" + }, + { + "examine": "Makes sliced human.", + "ids": "3580" + }, + { + "examine": "Releases a ticket when the flashing arrow is above it.", + "ids": "3581" + }, + { + "examine": "Makes human colanders.", + "ids": "3582" + }, + { + "examine": "I can use these to climb across to the other side.", + "ids": "3583,3584" + }, + { + "examine": "Looks suspiciously like a pressure pad to me.", + "ids": "3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "359,360,361" + }, + { + "examine": "Releases a ticket when the flashing arrow is above it.", + "ids": "3608,3609" + }, + { + "examine": "I can use this rope to climb back to the top.", + "ids": "3610,3611,3612,3613,3614,3615,3616" + }, + { + "examine": "Leads down into the Agility Arena.", + "ids": "3617" + }, + { + "examine": "Leads back to Brimhaven.", + "ids": "3618,3619,3620,3621,3622,3623,3624,3625" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "362" + }, + { + "examine": "It looks very sturdy.", + "ids": "3626,3627,3628,3629,3630,3631,3632,3633" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "363" + }, + { + "examine": "A shrine of the gods!", + "ids": "3634" + }, + { + "examine": "I wonder what's inside...", + "ids": "3635" + }, + { + "examine": "It looks empty.", + "ids": "3636,3637,3638,3639,3640,3641,3642,3643" + }, + { + "examine": "It's got ale in it.", + "ids": "364,32063" + }, + { + "examine": "That's really bright!", + "ids": "3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661" + }, + { + "examine": "These may have something in them.", + "ids": "365" }, { "examine": "There are some toolboxes on this table.", @@ -20704,7 +10956,9779 @@ "ids": "36579,36586" }, { - "examine": "Rough but adequate.", - "ids": "14918" + "examine": "Useful for transportation of delicate items.", + "ids": "366" + }, + { + "examine": "Smells more like \"innocent villager\" stew to me...", + "ids": "3662,3663,3664" + }, + { + "examine": "Troll leftovers...", + "ids": "3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675" + }, + { + "examine": "This may be worth opening.", + "ids": "367,368,369" + }, + { + "examine": "A stone mechanism that unlocks the equipment room.", + "ids": "3676,3677,3678" + }, + { + "examine": "I can climb down these stairs.", + "ids": "36775,36778" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "36786" + }, + { + "examine": "Closed for business.", + "ids": "36787" + }, + { + "examine": "Banking transactions are processed here.", + "ids": "36789,37158" + }, + { + "examine": "A standard of Asgarnia.", + "ids": "3679" + }, + { + "examine": "The flag of Asgarnia.", + "ids": "3680" + }, + { + "examine": "I don't know art, but I like it!", + "ids": "36809" + }, + { + "examine": "Town of Burthorpe", + "ids": "3681,3682,3683,3684" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "3685,3686,3687,3688,3689,3690,3691" + }, + { + "examine": "Some of the Sherpa's climbing rope.", + "ids": "3692,3693" + }, + { + "examine": "Looks like the Imperial Guard's supply of Dual Claws.", + "ids": "3694,3695" + }, + { + "examine": "The Imperial Guard's ceremonial armour.", + "ids": "3696" + }, + { + "examine": "A barrel full of swords...", + "ids": "3697,3698,3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,3714,3715,3716,3717,3718,3719,3720,3721" + }, + { + "examine": "Stops people walking past.", + "ids": "37,38,39" + }, + { + "examine": "This may be worth searching.", + "ids": "370,371,372" + }, + { + "examine": "I wonder what this spooky contains.", + "ids": "37051" + }, + { + "examine": "A rocky outcrop.", + "ids": "3722,3723,3724" + }, + { + "examine": "A wooden gate.", + "ids": "3725,3726,3727,3728,3729" + }, + { + "examine": "The perfect accompaniment to a bedroom.", + "ids": "373" + }, + { + "examine": "I can climb over the fence with this.", + "ids": "3730,3731,3732,3733,3734" + }, + { + "examine": "A flag on a pole.", + "ids": "37335" + }, + { + "examine": "Looks like a small cave.", + "ids": "3735" + }, + { + "examine": "The exit to the outside.", + "ids": "3736,3737,3738,3739,3740" + }, + { + "examine": "A stand for hats!", + "ids": "374" + }, + { + "examine": "No solicitors!", + "ids": "3741" + }, + { + "examine": "Danger", + "ids": "3742" + }, + { + "examine": "A sturdy wooden door.", + "ids": "3743,3744" + }, + { + "examine": "The door is closed.", + "ids": "3745,3746" + }, + { + "examine": "Stops bits of building falling on me.", + "ids": "37451" + }, + { + "examine": "A nicely fitted door.", + "ids": "3747" + }, + { + "examine": "A rocky outcrop.", + "ids": "3748,3749,3750,3751" + }, + { + "examine": "I wonder what's inside.", + "ids": "375,376,377" + }, + { + "examine": "Unusual energy is gathered here.", + "ids": "3752,3753,3754,3755,3756" + }, + { + "examine": "Looks like a small cave.", + "ids": "3757" + }, + { + "examine": "The way out.", + "ids": "3758" + }, + { + "examine": "Looks like a small cave.", + "ids": "3759" + }, + { + "examine": "The way out.", + "ids": "3760" + }, + { + "examine": "The back way out.", + "ids": "3761" + }, + { + "examine": "The back way into the stronghold.", + "ids": "3762" + }, + { + "examine": "The door is closed.", + "ids": "3763" + }, + { + "examine": "The mine has collapsed.", + "ids": "37634" + }, + { + "examine": "The door is open.", + "ids": "3764" + }, + { + "examine": "The door to Mad Eadgar's cell.", + "ids": "3765,3766" + }, + { + "examine": "The door to Godric's cell.", + "ids": "3767,3768" + }, + { + "examine": "Hot!", + "ids": "3769" + }, + { + "examine": "This window looks down onto the Troll Camp.", + "ids": "3770" + }, + { + "examine": "The entrance to the Troll Stronghold.", + "ids": "3771" + }, + { + "examine": "The way out of the Troll Stronghold.", + "ids": "3772,3773,3774" + }, + { + "examine": "Looks like stew of some kind...", + "ids": "3775" + }, + { + "examine": "A door in the Stronghold.", + "ids": "3776,3777,3778,3779" + }, + { + "examine": "Perhaps I should search it.", + "ids": "378,379" + }, + { + "examine": "The door to the prison.", + "ids": "3780,3781" + }, + { + "examine": "The entrance to the Troll Arena.", + "ids": "3782,3783,3784" + }, + { + "examine": "The exit to the Troll Arena.", + "ids": "3785,3786,3787" + }, + { + "examine": "I can climb these stairs.", + "ids": "3788" + }, + { + "examine": "They go down.", + "ids": "3789" + }, + { + "examine": "A rocky outcrop.", + "ids": "3790,3791,3792,3793" + }, + { + "examine": "Looks tasty! If you're a goat, that is.", + "ids": "3794,3795,3796" + }, + { + "examine": "A good source of books!", + "ids": "380,381" + }, + { + "examine": "Not so good for sitting on.", + "ids": "3802" + }, + { + "examine": "A rocky outcrop.", + "ids": "3803,3804" + }, + { + "examine": "They don't seem to roll.", + "ids": "3805" + }, + { + "examine": "They're troll eggs. Or perhaps rocks.", + "ids": "3806" + }, + { + "examine": "These make great pets.", + "ids": "3807" + }, + { + "examine": "It's a troll! Run! No, wait, it's just a rock.", + "ids": "3808,3809" + }, + { + "examine": "The door to the storeroom.", + "ids": "3810,3811,3812" + }, + { + "examine": "It probably hasn't got anything interesting inside.", + "ids": "3813" + }, + { + "examine": "They probably haven't got anything interesting inside.", + "ids": "3814,3815" + }, + { + "examine": "They're closed.", + "ids": "3816" + }, + { + "examine": "They're open.", + "ids": "3817,3818,3819" + }, + { + "examine": "A woven storage basket.", + "ids": "382,383,384,385" + }, + { + "examine": "It doesn't contain anything particularly appetising.", + "ids": "3820" + }, + { + "examine": "Makes you taller.", + "ids": "3821" + }, + { + "examine": "It's full of dried goutweed.", + "ids": "3822" + }, + { + "examine": "Welcome to Mad Eadgar's! If I'm not in, I've probably been captured again.", + "ids": "3823" + }, + { + "examine": "I don't want to look too closely at what's cooking in there...", + "ids": "3824" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "3825" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "3826" + }, + { + "examine": "How am I going to get down there?", + "ids": "3827,3828" + }, + { + "examine": "I hope this holds!", + "ids": "3829" + }, + { + "examine": "How am I going to get down there?", + "ids": "3830,3831" + }, + { + "examine": "I hope this holds!", + "ids": "3832" + }, + { + "examine": "It's moving...", + "ids": "3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,3849,3850,3851,3852,3853,3854,3855" + }, + { + "examine": "It's a half buried crate.", + "ids": "3856,3857" + }, + { + "examine": "It's stuck in the sand.", + "ids": "3858,3859" + }, + { + "examine": "A gigantic pottery urn.", + "ids": "386" + }, + { + "examine": "It's full of brightly coloured fish.", + "ids": "3860,3861" + }, + { + "examine": "It's a pile of burning bones.", + "ids": "3862" + }, + { + "examine": "The tribal statue of Tai Bwo Wannai Village.", + "ids": "3863,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878" + }, + { + "examine": "This no doubt contains arcane knowledge.", + "ids": "387" + }, + { + "examine": "A tree.", + "ids": "3879" + }, + { + "examine": "I wonder what this spooky item contains.", + "ids": "388" + }, + { + "examine": "It's a tree stump.", + "ids": "3880" + }, + { + "examine": "A tree.", + "ids": "3881,3882,3883" + }, + { + "examine": "It's a tree stump.", + "ids": "3884" + }, + { + "examine": "A tree.", + "ids": "3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900" + }, + { + "examine": "It smells funny in there.", + "ids": "389,390" + }, + { + "examine": "A rare flower.", + "ids": "3901" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "3902" + }, + { + "examine": "A rare flower.", + "ids": "3903" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "3904" + }, + { + "examine": "A rare flower.", + "ids": "3905" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "3906,3907,3908,3909,3910,3911" + }, + { + "examine": "Fungal growth.", + "ids": "3912" + }, + { + "examine": "Poisonous no doubt.", + "ids": "3913,3914" + }, + { + "examine": "Fungal growth.", + "ids": "3915" + }, + { + "examine": "Poisonous no doubt.", + "ids": "3916,3917" + }, + { + "examine": "The lamp has a glowing crystal at its core.", + "ids": "3918" + }, + { + "examine": "It's a trap!", + "ids": "3919,3920" + }, + { + "examine": "A fishing net full of fish.", + "ids": "392" + }, + { + "examine": "A tripwire.", + "ids": "3921" + }, + { + "examine": "An odd-looking group of tied sticks.", + "ids": "3922" + }, + { + "examine": "A pile of leaves.", + "ids": "3923,3924,3925,3926" + }, + { + "examine": "Looks like I can climb these.", + "ids": "3927" + }, + { + "examine": "It's a tree.", + "ids": "3928" + }, + { + "examine": "I can balance on this log.", + "ids": "3929,3930,3931,3932,3933,3934,3935,3936" + }, + { + "examine": "A good source of books!", + "ids": "393" + }, + { + "examine": "There are some broken twigs here.", + "ids": "3937" + }, + { + "examine": "It looks as if the grass here has been flattened.", + "ids": "3938" + }, + { + "examine": "You notice the leaf litter here has been disturbed.", + "ids": "3939,3940" + }, + { + "examine": "Bamboo storage!", + "ids": "394,395,396" + }, + { + "examine": "Tracks in the soil.", + "ids": "3941,3942,3943" + }, + { + "examine": "You'd need a big siege engine to force that.", + "ids": "3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961" + }, + { + "examine": "A yellow crystal structure.", + "ids": "3962,3963,3964,3965,3966" + }, + { + "examine": "A tree", + "ids": "3967,3968" + }, + { + "examine": "Disturbing but tidy.", + "ids": "3969" + }, + { + "examine": "The perfect place to store things.", + "ids": "397" + }, + { + "examine": "I don't even want to think about what did that...", + "ids": "3970" + }, + { + "examine": "I don't wanna fall in that!", + "ids": "3975" + }, + { + "examine": "Good for smashing city walls.", + "ids": "3976" + }, + { + "examine": "There's a winch on this side.", + "ids": "3977" + }, + { + "examine": "There's a lever on this side.", + "ids": "3978,3979" + }, + { + "examine": "I hope no-one's home...", + "ids": "398,26931,26935,26937,26939,32290" + }, + { + "examine": "A way to get into the tent.", + "ids": "3980,3981,3982" + }, + { + "examine": "A tent.", + "ids": "3983,3984,3985,3986" + }, + { + "examine": "A small barrel.", + "ids": "3987,3988,3989,3990,3991" + }, + { + "examine": "I see dead people.", + "ids": "399,36737,32291" + }, + { + "examine": "A standard of Kandarin.", + "ids": "3992,3993" + }, + { + "examine": "A small furnace.", + "ids": "3994" + }, + { + "examine": "A tent wall.", + "ids": "3995" + }, + { + "examine": "A way to get into the tent.", + "ids": "3996" + }, + { + "examine": "A tent wall.", + "ids": "3997" + }, + { + "examine": "It looks as if the grass here has been flattened.", + "ids": "3998" + }, + { + "examine": "There are some broken twigs here.", + "ids": "3999" + }, + { + "examine": "Animals have no table manners.", + "ids": "40" + }, + { + "examine": "A small simple gravestone.", + "ids": "400" + }, + { + "examine": "A tent roof.", + "ids": "4000" + }, + { + "examine": "A tent wall.", + "ids": "4001" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "40018" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "40019" + }, + { + "examine": "The charred remains of a tent pole.", + "ids": "4002,4003" + }, + { + "examine": "A wooden crate.", + "ids": "40021" + }, + { + "examine": "Some wooden crates.", + "ids": "40022" + }, + { + "examine": "I can climb this.", + "ids": "40026" + }, + { + "examine": "I can climb down this.", + "ids": "40027,20987,29358" + }, + { + "examine": "Items are for sale here.", + "ids": "40028" + }, + { + "examine": "Tick-tock, it's a clock.", + "ids": "40029" + }, + { + "examine": "Useful for putting things on.", + "ids": "40031" + }, + { + "examine": "A case. With books.", + "ids": "40033" + }, + { + "examine": "A drab looking bed.", + "ids": "40035" + }, + { + "examine": "Well of voyage.", + "ids": "4004,4005" + }, + { + "examine": "It really was this big!", + "ids": "40042" + }, + { + "examine": "It really was this big!", + "ids": "40043" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "40044" + }, + { + "examine": "These open and close!", + "ids": "40050" + }, + { + "examine": "These open and close!", + "ids": "40052" + }, + { + "examine": "The perfect place to store things.", + "ids": "40054" + }, + { + "examine": "I can climb up these stairs.", + "ids": "40057" + }, + { + "examine": "It looks like I can squeeze through here.", + "ids": "4006" + }, + { + "examine": "Looking good!", + "ids": "40065" + }, + { + "examine": "The exit to the outside.", + "ids": "4007" + }, + { + "examine": "Trinkets and stuff.", + "ids": "40075" + }, + { + "examine": "Break glass in case in case of emergency.", + "ids": "40076" + }, + { + "examine": "Shrine to the glory of Saradomin.", + "ids": "4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023" + }, + { + "examine": "A simple marker for a forgotten person.", + "ids": "401" + }, + { + "examine": "A large potted plant.", + "ids": "40111" + }, + { + "examine": "The remains of someone lie inside.", + "ids": "402" + }, + { + "examine": "A barrel.", + "ids": "4024,4025" + }, + { + "examine": "A still for fractionalizing oils.", + "ids": "4026" + }, + { + "examine": "A pile of lime rock.", + "ids": "4027,4028,4029,4030" + }, + { + "examine": "A monument to a special person.", + "ids": "403" + }, + { + "examine": "Looks like a stone doorway to me.", + "ids": "4031,4032,4033,4034" + }, + { + "examine": "These clean Druid's robes are drying off.", + "ids": "4035,4036,4037,4038" + }, + { + "examine": "It's full of dirty robes.", + "ids": "4039,4040,4041,4042" + }, + { + "examine": "The inscription is worn away and unreadable.", + "ids": "404" + }, + { + "examine": "Presumably the hatch the zookeeper feeds the parrots through.", + "ids": "4043" + }, + { + "examine": "A red standard.", + "ids": "4044,4045,4046,4047" + }, + { + "examine": "'Here lies...' is all I can read.", + "ids": "405" + }, + { + "examine": "It doesn't look healthy...", + "ids": "4051" + }, + { + "examine": "It's covered in slime.", + "ids": "4052" + }, + { + "examine": "It doesn't look healthy...", + "ids": "4053,4054" + }, + { + "examine": "These fat fungi take up so much room.", + "ids": "4055,4056,4057" + }, + { + "examine": "I can balance on this rope.", + "ids": "4059" + }, + { + "examine": "Whoever bought this must have really cared for the inhabitant.", + "ids": "406" + }, + { + "examine": "It's hollow...", + "ids": "4060" + }, + { + "examine": "This tree has been cut down.", + "ids": "4061" + }, + { + "examine": "Strange items are stored here.", + "ids": "4062" + }, + { + "examine": "This table has seen better days.", + "ids": "4064" + }, + { + "examine": "It looks very ornamental in a practical 'solid rock' way.", + "ids": "4065" + }, + { + "examine": "Welcome to Mort'ton", + "ids": "4066" + }, + { + "examine": "Danger! Sickness and affliction... stay away!", + "ids": "4067" + }, + { + "examine": "Looks like a pile of ancient rubble.", + "ids": "4068" + }, + { + "examine": "The starting of a wall.", + "ids": "4069,4070,4071,4072,4073,4074,4075,4076" + }, + { + "examine": "Looks like a stone doorway to me.", + "ids": "407" + }, + { + "examine": "It's nearly a wall.", + "ids": "4077" + }, + { + "examine": "A rebuilt wall.", + "ids": "4078" + }, + { + "examine": "The broken wall of a desecrated temple.", + "ids": "4079" + }, + { + "examine": "Looks like a stone doorway to my untrained eye.", + "ids": "408" + }, + { + "examine": "The partially repaired wall of a desecrated temple.", + "ids": "4080,4081,4082,4083,4084,4085,4086,4087" + }, + { + "examine": "The nearly repaired wall of a desecrated temple.", + "ids": "4088" + }, + { + "examine": "The repaired wall of a temple.", + "ids": "4089" + }, + { + "examine": "Shrine to the glory of Saradomin.", + "ids": "409" + }, + { + "examine": "A flaming Fire altar.", + "ids": "4090" + }, + { + "examine": "An ancient Fire altar.", + "ids": "4091" + }, + { + "examine": "An ancient, totally desecrated, broken down fire altar.", + "ids": "4092" + }, + { + "examine": "A place to cremate the dead. Needs some wood.", + "ids": "4093" + }, + { + "examine": "A place to cremate the dead. Needs a body.", + "ids": "4094,4095,4096,4097,4098,4099" + }, + { + "examine": "Looks like an outlet pipe to the lake.", + "ids": "41" + }, + { + "examine": "An ancient altar to the glory of Guthix.", + "ids": "410" + }, + { + "examine": "A place to cremate the dead. Needs a light.", + "ids": "4100,4101,4102,4103,4104,4105" + }, + { + "examine": "Heavy metal!", + "ids": "4106,4107,4108,4109,4110" + }, + { + "examine": "Shrine to the glory of Zamorak.", + "ids": "411,412" + }, + { + "examine": "A strangely decorated bronze chest, the lock is painted blood red.", + "ids": "4111" + }, + { + "examine": "A strangely decorated chest, the lock is painted brown.", + "ids": "4112" + }, + { + "examine": "A strangely decorated chest, the lock is painted crimson.", + "ids": "4113" + }, + { + "examine": "A strangely decorated chest, the lock is painted black.", + "ids": "4114" + }, + { + "examine": "A strangely decorated chest, the lock is painted purple.", + "ids": "4115" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted blood red.", + "ids": "4116" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted brown.", + "ids": "4117" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted crimson.", + "ids": "4118" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted black.", + "ids": "4119" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted purple.", + "ids": "4120" + }, + { + "examine": "A strangely decorated black chest, the lock is painted blood red.", + "ids": "4121" + }, + { + "examine": "A strangely decorated black chest, the lock is painted brown.", + "ids": "4122" + }, + { + "examine": "A strangely decorated black chest, the lock is painted crimson.", + "ids": "4123" + }, + { + "examine": "A strangely decorated black chest, the lock is painted black.", + "ids": "4124" + }, + { + "examine": "A strangely decorated black chest, the lock is painted purple.", + "ids": "4125" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted blood red.", + "ids": "4126" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted brown.", + "ids": "4127" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted crimson.", + "ids": "4128" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted black.", + "ids": "4129" + }, + { + "examine": "Looks suspiciously like a big stone table.", + "ids": "413" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted purple.", + "ids": "4130" + }, + { + "examine": "A strangely decorated bronze chest, the open lock is painted blood red.", + "ids": "4131" + }, + { + "examine": "This tells you which way is which.", + "ids": "4132,4133,4134,4135" + }, + { + "examine": "These doors look very ominous. A sign says 'To the tombs'.", + "ids": "4136,4137" + }, + { + "examine": "Items are for sale here.", + "ids": "4138" + }, + { + "examine": "Entrance to the Duel Arena.", + "ids": "4139,4140" + }, + { + "examine": "A really posh upright coffin.", + "ids": "414" + }, + { + "examine": "This seems to be some kind of shrine.", + "ids": "4141" + }, + { + "examine": "The wind makes a musical sound as it blows through it...", + "ids": "4142" + }, + { + "examine": "Danger", + "ids": "4143" + }, + { + "examine": "Those golden fruit look good enough to eat!", + "ids": "4144,4145,4146" + }, + { + "examine": "This must be Lalli's home.", + "ids": "4147" + }, + { + "examine": "Allows performers backstage at the Longhall.", + "ids": "4148" + }, + { + "examine": "It smells pretty good actually.", + "ids": "4149" + }, + { + "examine": "Whoever's inside must have been rich.", + "ids": "415" + }, + { + "examine": "A portal from this mystical place.", + "ids": "4150,4151,4152,4153,4154,4155,4156,4157" + }, + { + "examine": "Takes me into the maze.", + "ids": "4158" + }, + { + "examine": "Takes me out of the maze.", + "ids": "4159,4160,4161" + }, + { + "examine": "With skill I can play this.", + "ids": "416" + }, + { + "examine": "A thin metal pipe, presumably for rainwater to run through.", + "ids": "4162" + }, + { + "examine": "I can climb this.", + "ids": "4163,4164" + }, + { + "examine": "Keeps the wind out.", + "ids": "4165,4166" + }, + { + "examine": "I wonder what's inside?", + "ids": "4167,4168" + }, + { + "examine": "Brrrrrr!", + "ids": "4169" + }, + { + "examine": "Great for sleeping in.", + "ids": "417" + }, + { + "examine": "There is some kind of balancing mechanism as a lock.", + "ids": "4170" + }, + { + "examine": "A good source of books!", + "ids": "4171" + }, + { + "examine": "An appliance for cooking with.", + "ids": "4172" + }, + { + "examine": "I wonder what's down there?", + "ids": "4173" + }, + { + "examine": "I wonder what's under it?", + "ids": "4174" + }, + { + "examine": "Kind of funny smelling...", + "ids": "4175" + }, + { + "examine": "Water comes out of it.", + "ids": "4176" + }, + { + "examine": "This may be worth opening.", + "ids": "4177" + }, + { + "examine": "This may be worth searching.", + "ids": "4178" + }, + { + "examine": "A very unusual piece of artwork...", + "ids": "4179,4180" + }, + { + "examine": "A stylish-looking bed.", + "ids": "418" + }, + { + "examine": "Alas poor unicorn, I knew him well.", + "ids": "4181" + }, + { + "examine": "Looks like the bull lost.", + "ids": "4182" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "4183,4184" + }, + { + "examine": "A wooden crate for storage.", + "ids": "4185" + }, + { + "examine": "An old crate for storage.", + "ids": "4186" + }, + { + "examine": "I can climb this.", + "ids": "4187" + }, + { + "examine": "This leads upwards.", + "ids": "4188" + }, + { + "examine": "This leads downwards.", + "ids": "4189,4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,4239,4240,4241,4242,4243,4244,4245,4246" + }, + { + "examine": "A drab-looking bed.", + "ids": "419" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "42,326" + }, + { + "examine": "A stylish-looking bed.", + "ids": "420,421" + }, + { + "examine": "Technically a bed.", + "ids": "422" + }, + { + "examine": "I guess I could sleep in it if I were really tired.", + "ids": "423" + }, + { + "examine": "Lovely comfy-looking big bed.", + "ids": "424,425" + }, + { + "examine": "Keeps the cold winds out.", + "ids": "4247" + }, + { + "examine": "Doesn't keep the wind out if it's open!", + "ids": "4248,4249" + }, + { + "examine": "I'm sure the animal is glad its fur was put to good use.", + "ids": "4250,4251" + }, + { + "examine": "I wonder what's inside?", + "ids": "4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264" + }, + { + "examine": "Posh-looking bed.", + "ids": "426" + }, + { + "examine": "Toasty.", + "ids": "4265" + }, + { + "examine": "Hot!", + "ids": "4266" + }, + { + "examine": "Finger licking good!", + "ids": "4267,4268" + }, + { + "examine": "It's a long wooden table.", + "ids": "4269" + }, + { + "examine": "A bed fit for a king.", + "ids": "427,428" + }, + { + "examine": "It's a table with candles on.", + "ids": "4270" + }, + { + "examine": "Generally used for sitting.", + "ids": "4271" + }, + { + "examine": "Generally used for putting things on.", + "ids": "4272" + }, + { + "examine": "Actually, I could do with a drink...", + "ids": "4273" + }, + { + "examine": "For leaning against...", + "ids": "4274" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "4275" + }, + { + "examine": "Always a source of good bargains.", + "ids": "4276" + }, + { + "examine": "There's something fishy about this stall.", + "ids": "4277" + }, + { + "examine": "Around here, this is where you buy new doors.", + "ids": "4278,4279,4280,4281,4282" + }, + { + "examine": "Has a peculiar odour.", + "ids": "4283,4284" + }, + { + "examine": "Water comes out of this.", + "ids": "4285" + }, + { + "examine": "It's kind of like a barrel.", + "ids": "4286" + }, + { + "examine": "Looks pretty comfy.", + "ids": "4287" + }, + { + "examine": "I guess I could sleep in it if I was really tired.", + "ids": "4288,4289,4290,4291,4292,4293,4294,4295" + }, + { + "examine": "One of the nicest beds I have ever seen.", + "ids": "429" + }, + { + "examine": "Yup, looks like this neighbourhood is perfectly safe for travellers...", + "ids": "4296" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "4297,4298,4299" + }, + { + "examine": "It seems to sparkle.", + "ids": "43" + }, + { + "examine": "Perfect for snoozing in the sun.", + "ids": "430" + }, + { + "examine": "A wooden crate for storage.", + "ids": "4300" + }, + { + "examine": "An old crate for storage.", + "ids": "4301,4302,4303" + }, + { + "examine": "A hot place for forging things in.", + "ids": "4304,4305" + }, + { + "examine": "Used for fashioning metal items.", + "ids": "4306" + }, + { + "examine": "Various implements for working with metal.", + "ids": "4307" + }, + { + "examine": "Bake your clay pots in here.", + "ids": "4308" + }, + { + "examine": "Used for spinning thread.", + "ids": "4309" + }, + { + "examine": "A comfortable seat to recline and recuperate.", + "ids": "431" + }, + { + "examine": "Used for fashioning clay items.", + "ids": "4310" + }, + { + "examine": "A wooden gate.", + "ids": "4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327" + }, + { + "examine": "I don't think anyone's slept here for a long time.", + "ids": "432" + }, + { + "examine": "This tree has been cut down.", + "ids": "4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4347" + }, + { + "examine": "Bamboo's a versatile material.", + "ids": "433,434,435" + }, + { + "examine": "Best left on the beach.", + "ids": "4348" + }, + { + "examine": "This once belonged to a sea animal.", + "ids": "4349" + }, + { + "examine": "Best left for the crabs.", + "ids": "4350" + }, + { + "examine": "I can hear the sea with this.", + "ids": "4351" + }, + { + "examine": "A half-buried bowl.", + "ids": "4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365" + }, + { + "examine": "A lump of rock.", + "ids": "436,437,438,439" + }, + { + "examine": "An empty shelf...", + "ids": "4366,4367" + }, + { + "examine": "There are some pots and pans here.", + "ids": "4368" + }, + { + "examine": "There are some tankards here.", + "ids": "4369" + }, + { + "examine": "A shelf with a bucket on it.", + "ids": "4370" + }, + { + "examine": "There are a few books on this shelf.", + "ids": "4371" + }, + { + "examine": "It's a small table.", + "ids": "4372" + }, + { + "examine": "A tray of sand.", + "ids": "4373,4374,4375,4376" + }, + { + "examine": "There should be a standard here!", + "ids": "4377,4378,4379" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4380" + }, + { + "examine": "It's a war machine.", + "ids": "4381,4382" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4383,4384" + }, + { + "examine": "The catapult is damaged.", + "ids": "4385,4386" + }, + { + "examine": "A portal to join the Saradomin team.", + "ids": "4387" + }, + { + "examine": "A portal to join the Zamorak team.", + "ids": "4388" + }, + { + "examine": "A portal to leave the Saradomin team.", + "ids": "4389" + }, + { + "examine": "A portal to leave the Zamorak team.", + "ids": "4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405" + }, + { + "examine": "I can see really big fish swimming in the water.", + "ids": "44" + }, + { + "examine": "A big slimy lump of rock.", + "ids": "440" + }, + { + "examine": "A portal to leave the Saradomin team.", + "ids": "4406" + }, + { + "examine": "A portal to leave the Zamorak team.", + "ids": "4407" + }, + { + "examine": "A portal to join a random team.", + "ids": "4408,4409,4410" + }, + { + "examine": "A slimy lump of rock.", + "ids": "441" + }, + { + "examine": "A very slippery stepping stone", + "ids": "4411" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4412,4413" + }, + { + "examine": "A rickety old staircase.", + "ids": "4414" + }, + { + "examine": "A solid stone staircase.", + "ids": "4415,4416,4417,4418,4419,4420,36480,36481,36484,36495,36521,36523,36532,36540" + }, + { + "examine": "A slippery looking rock.", + "ids": "442,443" + }, + { + "examine": "A spiky barricade.", + "ids": "4421,4422" + }, + { + "examine": "A large broken door.", + "ids": "4431,4432,4433,4434,4435,4436" + }, + { + "examine": "We could use our pickaxes to get past these...", + "ids": "4437" + }, + { + "examine": "We can almost get past these...", + "ids": "4438,4439,4440,4441,4442,4443" + }, + { + "examine": "A huge lump of rock.", + "ids": "444,445" + }, + { + "examine": "Should be long enough to scale castle walls.", + "ids": "4444,4445" + }, + { + "examine": "Maybe I could tie a rope to this...", + "ids": "4446,4447" + }, + { + "examine": "It doesn't look very stable...", + "ids": "4448" + }, + { + "examine": "A solid stone staircase.", + "ids": "4449,4450,4451,4452,4453,4454,4455,4456,4457" + }, + { + "examine": "There are some bandages on this table.", + "ids": "4458" + }, + { + "examine": "There are some toolboxes on this table.", + "ids": "4459" + }, + { + "examine": "Some small stones.", + "ids": "446,447,448" + }, + { + "examine": "There's some rock I can use with the catapult here.", + "ids": "4460" + }, + { + "examine": "There are some barricades here.", + "ids": "4461" + }, + { + "examine": "There is some rope here.", + "ids": "4462" + }, + { + "examine": "There are some explosive potions here.", + "ids": "4463" + }, + { + "examine": "There are some pickaxes on this table.", + "ids": "4464" + }, + { + "examine": "An elf-fashioned door.", + "ids": "4465,4466" + }, + { + "examine": "The door is closed.", + "ids": "4467" + }, + { + "examine": "The door is open.", + "ids": "4468" + }, + { + "examine": "Only the Saradomin team may pass.", + "ids": "4469" + }, + { + "examine": "Only the Zamorak team may pass.", + "ids": "4470" + }, + { + "examine": "I wonder what's under it?", + "ids": "4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481" + }, + { + "examine": "Water comes out of this.", + "ids": "4482" + }, + { + "examine": "It's open.", + "ids": "4483" + }, + { + "examine": "Keep track of which team has the most victories.", + "ids": "4484" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4485,4486" + }, + { + "examine": "A big wooden door.", + "ids": "4487,4488,4489,4490,4491,4492" + }, + { + "examine": "A rocky ledge.", + "ids": "449" + }, + { + "examine": "I can climb these stairs.", + "ids": "4493" + }, + { + "examine": "They go down.", + "ids": "4494" + }, + { + "examine": "I can climb these stairs.", + "ids": "4495" + }, + { + "examine": "They go down.", + "ids": "4496" + }, + { + "examine": "I can climb these stairs.", + "ids": "4497" + }, + { + "examine": "They go down.", + "ids": "4498" + }, + { + "examine": "Wow", + "ids": "4499" + }, + { + "examine": "Big Dave is fishing here.", + "ids": "45" + }, + { + "examine": "Stoney!", + "ids": "450,451,452,453" + }, + { + "examine": "This leads back to the cruel world above.", + "ids": "4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512" + }, + { + "examine": "I doubt that was built to last...", + "ids": "4513,4514,4515,4516,4517" + }, + { + "examine": "How do you make a skeleton laugh?", + "ids": "4518" + }, + { + "examine": "Tickle his funny bone.", + "ids": "4519" + }, + { + "examine": "Clearly has been relaxing too long....", + "ids": "4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540" + }, + { + "examine": "Solid rock from the cave floor.", + "ids": "454,455" + }, + { + "examine": "Did that thing just twitch?", + "ids": "4541,4542" + }, + { + "examine": "A strange wall with objects engraved upon it.", + "ids": "4543,4544" + }, + { + "examine": "A strange wall that appears to be hinged.", + "ids": "4545,4546,4547,4548,4549" + }, + { + "examine": "I can jump off this one.", + "ids": "4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567" + }, + { + "examine": "I can climb up these stairs.", + "ids": "4568" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "4569,36777" + }, + { + "examine": "I can climb down these stairs.", + "ids": "4570,4571,4572,4573,4574,4575,4576" + }, + { + "examine": "Lets you walk through walls!", + "ids": "4577,4578,4579,4580,4581,4582,4583,4584,4585,4586" + }, + { + "examine": "It turns the light around.", + "ids": "4587" + }, + { + "examine": "It looks broken.", + "ids": "4588" + }, + { + "examine": "Part of the Lighthouse's lighting mechanism.", + "ids": "4589" + }, + { + "examine": "Part of the lighthouse Light mechanism.", + "ids": "4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609" + }, + { + "examine": "Joshua is fishing here.", + "ids": "46" + }, + { + "examine": "Best left on the beach.", + "ids": "4610" + }, + { + "examine": "This once belonged to a sea animal.", + "ids": "4611" + }, + { + "examine": "Best left for the crabs.", + "ids": "4612" + }, + { + "examine": "I can hear the sea with this.", + "ids": "4613" + }, + { + "examine": "It is a buried bowl.", + "ids": "4614" + }, + { + "examine": "I can jump off this one.", + "ids": "4615,4616" + }, + { + "examine": "Shelves filled with interesting books.", + "ids": "4617" + }, + { + "examine": "A nice and cosy fire.", + "ids": "4618,4619" + }, + { + "examine": "Looks slippery!", + "ids": "462,463" + }, + { + "examine": "They go down.", + "ids": "4620,4621" + }, + { + "examine": "They go up.", + "ids": "4622,4623" + }, + { + "examine": "They go down.", + "ids": "4624,4625" + }, + { + "examine": "They go up.", + "ids": "4626,4627,4628" + }, + { + "examine": "An elf-fashioned door.", + "ids": "4636,4637,4638,4639,4640" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "464,465,466" + }, + { + "examine": "Mmm...beer!", + "ids": "4641" + }, + { + "examine": "Has some board games news on it.", + "ids": "4642" + }, + { + "examine": "The ladder to the Runelink challenge room for experienced players.", + "ids": "4643" + }, + { + "examine": "The ladder back to the Runelink challenge room.", + "ids": "4644" + }, + { + "examine": "The ladder to the Draughts challenge room for experienced players.", + "ids": "4645" + }, + { + "examine": "The ladder back to the Draughts challenge room.", + "ids": "4646" + }, + { + "examine": "The ladder back up to the Toad and Chicken.", + "ids": "4647" + }, + { + "examine": "Leads down to the Burthorpe Games Rooms.", + "ids": "4648,4649" + }, + { + "examine": "A nice and cosy fire.", + "ids": "4650" + }, + { + "examine": "A table for board games.", + "ids": "4651" + }, + { + "examine": "A game of draughts is being played on this table.", + "ids": "4652" + }, + { + "examine": "A game of Runelink is being played on this table.", + "ids": "4653,4654,4655" + }, + { + "examine": "A comfy stool.", + "ids": "4656,4657" + }, + { + "examine": "Draughts challenge room.", + "ids": "4658" + }, + { + "examine": "Runelink challenge room.", + "ids": "4659" + }, + { + "examine": "Draughts challenge room for experienced players.", + "ids": "4660" + }, + { + "examine": "Runelink challenge room for experienced players.", + "ids": "4661,4662,4663,4664,4665,4666,4667,4668" + }, + { + "examine": "A statue of Arrav (the Fountain of Heroes has moved downstairs.)", + "ids": "4669" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "467" + }, + { + "examine": "A statue of Camorra (the Fountain of Heroes has moved downstairs.)", + "ids": "4670" + }, + { + "examine": "A good source of books!", + "ids": "4671" + }, + { + "examine": "The door into the throne room.", + "ids": "4672,4673" + }, + { + "examine": "I bet this makes good syrup!", + "ids": "4674" + }, + { + "examine": "Scented herbs.", + "ids": "4675" + }, + { + "examine": "A rocky outcrop.", + "ids": "4676" + }, + { + "examine": "Scented herbs.", + "ids": "4677,4678,4679,4680,4681,4682" + }, + { + "examine": "Limestone floor growth.", + "ids": "468" + }, + { + "examine": "A large harp.", + "ids": "4683" + }, + { + "examine": "Good for shooting fish in.", + "ids": "4684" + }, + { + "examine": "This old tree is rotting away", + "ids": "4685" + }, + { + "examine": "This old tree is rotting away.", + "ids": "4686,4687,4688,4689" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "469,470" + }, + { + "examine": "Fancy.", + "ids": "4690,4691" + }, + { + "examine": "Flag, pole...Yep, it's a flagpole.", + "ids": "4692,4693,4694,4695" + }, + { + "examine": "The door is closed.", + "ids": "4696" + }, + { + "examine": "The door is open.", + "ids": "4697,4698,4699,4700" + }, + { + "examine": "A wooden gate.", + "ids": "47,48,49,50" + }, + { + "examine": "Keeps the cold winds out.", + "ids": "4701" + }, + { + "examine": "A nicely carved wooden chair.", + "ids": "4702" + }, + { + "examine": "A wooden double bed. For sleeping in...", + "ids": "4703,4704" + }, + { + "examine": "There's something fishy about this stall.", + "ids": "4705" + }, + { + "examine": "You should eat your greens!", + "ids": "4706" + }, + { + "examine": "There's something fishy about this stall.", + "ids": "4707" + }, + { + "examine": "You should eat your greens!", + "ids": "4708,4709" + }, + { + "examine": "A deposit of rocks.", + "ids": "471,472,473,474" + }, + { + "examine": "A doorway made from bamboo.", + "ids": "4710,4711" + }, + { + "examine": "It's a trapdoor.", + "ids": "4712" + }, + { + "examine": "It's an open trapdoor.", + "ids": "4713" + }, + { + "examine": "A wooden crate for storage.", + "ids": "4714" + }, + { + "examine": "This crate is making chattering sounds.", + "ids": "4715" + }, + { + "examine": "This crate smells slightly nauseous.", + "ids": "4716" + }, + { + "examine": "This crate says 'Property of Hamab' on its side.", + "ids": "4717,4718" + }, + { + "examine": "This crate says 'Property of Ifaba' on its side.", + "ids": "4719" + }, + { + "examine": "This crate says 'Property of Daga' on its side.", + "ids": "4720,4721" + }, + { + "examine": "This crate smells slightly of banana.", + "ids": "4722,4723" + }, + { + "examine": "This crate says 'Property of Hamab' on its side.", + "ids": "4724" + }, + { + "examine": "This crate says 'Property of Ifaba' on its side.", + "ids": "4725,4726,4727" + }, + { + "examine": "I can climb up this.", + "ids": "4728" + }, + { + "examine": "A dried up bush, void of life.", + "ids": "4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742" + }, + { + "examine": "It's a bamboo ladder.", + "ids": "4743,4744" + }, + { + "examine": "Looks good for jumping off.", + "ids": "4745" + }, + { + "examine": "This crate is marked 'Deliver to Glough'...", + "ids": "4746,4747,4748" + }, + { + "examine": "It's a banana tree, full of bananas.", + "ids": "4749" + }, + { + "examine": "It's a banana tree, with lots of bananas.", + "ids": "4750" + }, + { + "examine": "It's a banana tree, with many bananas.", + "ids": "4751" + }, + { + "examine": "It's a banana tree, with a few bananas.", + "ids": "4752" + }, + { + "examine": "It's a banana tree, with but one banana.", + "ids": "4753" + }, + { + "examine": "It's a banana tree, with no more bananas left.", + "ids": "4754" + }, + { + "examine": "They go down.", + "ids": "4755" + }, + { + "examine": "They go up.", + "ids": "4756,4757,4758,4759,4760,4761,4762,4763" + }, + { + "examine": "It's a bamboo stool.", + "ids": "4764" + }, + { + "examine": "It's a sheer wall of fire, rising as high as you can see.", + "ids": "4765,4766" + }, + { + "examine": "The contents of this pyre are rapidly bubbling and burning.", + "ids": "4767" + }, + { + "examine": "It's a wall of bricks.", + "ids": "4768" + }, + { + "examine": "It's a pile of bricks.", + "ids": "4769,4770" + }, + { + "examine": "Looks slippery!", + "ids": "477,478" + }, + { + "examine": "A rather dapper little monkey sitting on a throne.", + "ids": "4771" + }, + { + "examine": "It's a bamboo ladder.", + "ids": "4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4785" + }, + { + "examine": "A plant in a bamboo pot.", + "ids": "4786" + }, + { + "examine": "It's an absolutely huge bamboo gate.", + "ids": "4787,4788,4789,4790" + }, + { + "examine": "A deposit of rocks.", + "ids": "479,480,481,482,483,484,485,486" + }, + { + "examine": "It's a big comfy bed, made of strips of bamboo.", + "ids": "4791,4792,4793" + }, + { + "examine": "It's a pot made out of bamboo.", + "ids": "4794" + }, + { + "examine": "They are pots made out of bamboo.", + "ids": "4795,4796" + }, + { + "examine": "Bamboo strips have been lashed together to make this rickety desk.", + "ids": "4797" + }, + { + "examine": "It's a bookcase made out of bamboo.", + "ids": "4798" + }, + { + "examine": "It's a bamboo door with a large iron padlock.", + "ids": "4799,4800,4801,4802,4803,4804,4805,4806" + }, + { + "examine": "It's a door made from bamboo.", + "ids": "4807,4808,4809,4810,4811" + }, + { + "examine": "Looks good for hiding in...", + "ids": "4812,4813,4814" + }, + { + "examine": "Looks good for hiding in.", + "ids": "4815" + }, + { + "examine": "This is a fairly tall tree with sparse foliage.", + "ids": "4816" + }, + { + "examine": "A jungle palm with dense foliage.", + "ids": "4817" + }, + { + "examine": "This is a fairly tall tree with sparse foliage.", + "ids": "4818" + }, + { + "examine": "This was a fairly tall tree with sparse foliage.", + "ids": "4819" + }, + { + "examine": "A leafy tree.", + "ids": "4820" + }, + { + "examine": "This was a fairly tall tree with sparse foliage.", + "ids": "4821" + }, + { + "examine": "This tree has been cut down.", + "ids": "4822" + }, + { + "examine": "This flower is found only in jungle areas.", + "ids": "4823" + }, + { + "examine": "A very rare and exotic flower.", + "ids": "4824" + }, + { + "examine": "A small fernlike plant.", + "ids": "4825" + }, + { + "examine": "Leaves a nasty mark.", + "ids": "4826" + }, + { + "examine": "Looks spiky.", + "ids": "4827" + }, + { + "examine": "This has broad leaves.", + "ids": "4828" + }, + { + "examine": "A type of jungle fern.", + "ids": "4829" + }, + { + "examine": "A large waxy jungle plant.", + "ids": "4830" + }, + { + "examine": "Commonly found in these parts.", + "ids": "4831" + }, + { + "examine": "The tendrils of a creeping plant.", + "ids": "4832" + }, + { + "examine": "A jungle bush, quite common to these areas.", + "ids": "4833,4834" + }, + { + "examine": "A jungle bush that has been chopped down.", + "ids": "4835,4836,4837,4838,4839,4840,4841,4842,4843,4844" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "4845,4846,4847" + }, + { + "examine": "Leaves of a tropical tree.", + "ids": "4848" + }, + { + "examine": "This tree no doubt contains dangerous insects.", + "ids": "4849,4850,4851" + }, + { + "examine": "This old tree is rotting away.", + "ids": "4852" + }, + { + "examine": "A gnarly old tree root.", + "ids": "4853" + }, + { + "examine": "The roots of this tree are exposed.", + "ids": "4854" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "4855" + }, + { + "examine": "It's a small patch of glowing fungus.", + "ids": "4856" + }, + { + "examine": "It's a medium patch of glowing fungus.", + "ids": "4857" + }, + { + "examine": "It's an absolutely colossal statue of some kind of gorilla.", + "ids": "4858" + }, + { + "examine": "It's a huge statue of some kind of gorilla.", + "ids": "4859,4860" + }, + { + "examine": "It's a huge statue of some kind of monkey.", + "ids": "4861" + }, + { + "examine": "It's a large patch of glowing fungus.", + "ids": "4862" + }, + { + "examine": "Legs of this watchtower.", + "ids": "4863,4864" + }, + { + "examine": "It's the middle of this watchtower.", + "ids": "4865" + }, + { + "examine": "It's a deactivated military Gnome glider.", + "ids": "4866" + }, + { + "examine": "It's an activated military Gnome glider.", + "ids": "4867" + }, + { + "examine": "It's some kind of Gnome teleportation device.", + "ids": "4868,4869,4870" + }, + { + "examine": "This is the panel controlling the hangar reinitialisation.", + "ids": "4871" + }, + { + "examine": "There must be an exit nearby.", + "ids": "4872" + }, + { + "examine": "It's probably too risky to try pulling this.", + "ids": "4873" + }, + { + "examine": "This table has crafting paraphernalia on it.", + "ids": "4874" + }, + { + "examine": "This table has ripe bananas on show.", + "ids": "4875" + }, + { + "examine": "This table has items of a general nature on it.", + "ids": "4876" + }, + { + "examine": "This table has runes on display.", + "ids": "4877" + }, + { + "examine": "This table has a scimitar on it.", + "ids": "4878" + }, + { + "examine": "It's a trapdoor.", + "ids": "4879" + }, + { + "examine": "It's an open trapdoor.", + "ids": "4880" + }, + { + "examine": "I can climb up this.", + "ids": "4881" + }, + { + "examine": "Looks suspicious.", + "ids": "4882,4883" + }, + { + "examine": "A plank.", + "ids": "4884" + }, + { + "examine": "Formed over many years.", + "ids": "4885" + }, + { + "examine": "Human sieve creation.", + "ids": "4886" + }, + { + "examine": "Looks suspicious.", + "ids": "4887" + }, + { + "examine": "It's a trapdoor.", + "ids": "4888" + }, + { + "examine": "I can climb up this.", + "ids": "4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899" + }, + { + "examine": "The Saradomin Team Standard.", + "ids": "4900" + }, + { + "examine": "The Zamorak Team Standard.", + "ids": "4901" + }, + { + "examine": "The Saradomin Team Standard.", + "ids": "4902" + }, + { + "examine": "The Zamorak Team Standard.", + "ids": "4903" + }, + { + "examine": "It's on fire!", + "ids": "4904,4905,4906,4907,4908,4909" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "4910" + }, + { + "examine": "I can climb down this.", + "ids": "4911,4912,36349,36365" + }, + { + "examine": "It looks cramped and dark.", + "ids": "4913,4914,4915,4916,4917" + }, + { + "examine": "This cart is blocking the way up the ridge.", + "ids": "4918" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "4919" + }, + { + "examine": "A collection of rocks over what looks like a depression.", + "ids": "492" + }, + { + "examine": "It looks cramped and dark.", + "ids": "4920,4921,4922" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "4923" + }, + { + "examine": "A valve to start and stop the flow of water.", + "ids": "4924,4925" + }, + { + "examine": "Shiny!", + "ids": "4926,4927,4928" + }, + { + "examine": "It looks cramped and dark.", + "ids": "4929" + }, + { + "examine": "It's blocking the tunnel, but it looks dark down there anyway.", + "ids": "4930,4931" + }, + { + "examine": "A bizarre fungus. It emits a pale blue light.", + "ids": "4932,4933,4934" + }, + { + "examine": "If that wasn't there I'd probably be a lot flatter now.", + "ids": "4935" + }, + { + "examine": "It prevents the wall unceremoniously squashing people.", + "ids": "4936" + }, + { + "examine": "It looks like it's water powered.", + "ids": "4937,4938,4939,4940,4941" + }, + { + "examine": "It's a little waterlogged. I hope it still works.", + "ids": "4942,4943" + }, + { + "examine": "It doesn't look very watertight. Any contents will be ruined.", + "ids": "4944" + }, + { + "examine": "A sunken mine cart, how useful.", + "ids": "4945,4946,4947,4948" + }, + { + "examine": "This displays information on how the points on this level are set.", + "ids": "4949" + }, + { + "examine": "It has the letter 'B' inscribed on the end.", + "ids": "4950" + }, + { + "examine": "It has the letter 'A' inscribed on the end.", + "ids": "4951" + }, + { + "examine": "It has the letter 'C' inscribed on the end.", + "ids": "4952" + }, + { + "examine": "It has the letter 'D' inscribed on the end.", + "ids": "4953" + }, + { + "examine": "It has the letter 'E' inscribed on the end.", + "ids": "4954" + }, + { + "examine": "It has the letter 'I' inscribed on the end.", + "ids": "4955" + }, + { + "examine": "It has the letter 'J' inscribed on the end.", + "ids": "4956" + }, + { + "examine": "It has the letter 'K' inscribed on the end.", + "ids": "4957" + }, + { + "examine": "I think this changes one of the sets of points.", + "ids": "4958" + }, + { + "examine": "It has the letter 'F' inscribed on the end.", + "ids": "4959" + }, + { + "examine": "It has the letter 'G' inscribed on the end.", + "ids": "4960" + }, + { + "examine": "It has the letter 'H' inscribed on the end.", + "ids": "4961" + }, + { + "examine": "The door is closed.", + "ids": "4962" + }, + { + "examine": "I can climb down this.", + "ids": "4965" + }, + { + "examine": "I can climb this.", + "ids": "4966" + }, + { + "examine": "I can climb down this.", + "ids": "4967" + }, + { + "examine": "I can climb this.", + "ids": "4968" + }, + { + "examine": "I can climb down this.", + "ids": "4969" + }, + { + "examine": "I can climb this.", + "ids": "4970" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "4971,4972,4973" + }, + { + "examine": "Useful for moving items around the mine.", + "ids": "4974" + }, + { + "examine": "An old crate for storage.", + "ids": "4975" + }, + { + "examine": "A distinctive layer in the rock strata.", + "ids": "4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000" + }, + { + "examine": "A powerful ranging device, unfortunately not working.", + "ids": "5" + }, + { + "examine": "This cave has been boarded up.", + "ids": "5001" + }, + { + "examine": "Useful for passing over inaccessible areas.", + "ids": "5002" + }, + { + "examine": "It's old and pretty broken.", + "ids": "5003" + }, + { + "examine": "A well used tree.", + "ids": "5004,5005" + }, + { + "examine": "These flowers only grow in one place in the mountains.", + "ids": "5006" + }, + { + "examine": "Looks like small cave.", + "ids": "5007" + }, + { + "examine": "Looks dark...", + "ids": "5008,5009,5010,5011,5012,5013,5014" + }, + { + "examine": "It's too dangerous to go down here by foot...", + "ids": "5015,5016,5017,5018,5019,5020,5021,5022,5023,5024" + }, + { + "examine": "A split in the cave wall...", + "ids": "5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036" + }, + { + "examine": "A large ice covered boulder.", + "ids": "5037" + }, + { + "examine": "An ice covered boulder.", + "ids": "5038" + }, + { + "examine": "A small ice covered boulder.", + "ids": "5039,5040,5041,5042" + }, + { + "examine": "A huge ice gate.", + "ids": "5043,5044" + }, + { + "examine": "An interesting-looking tree.", + "ids": "5045" + }, + { + "examine": "A small cave entrance.", + "ids": "5046" + }, + { + "examine": "Limestone ceiling growth.", + "ids": "5047" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "5048" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "5049" + }, + { + "examine": "Tooth shaped rock formations protruding from the floor.", + "ids": "5050" + }, + { + "examine": "A dirty little swamp boat.", + "ids": "5051" + }, + { + "examine": "If it had paint on it, you'd probably watch it dry.", + "ids": "5052,5053" + }, + { + "examine": "I can climb this.", + "ids": "5054" + }, + { + "examine": "I wonder what that's there for...", + "ids": "5055" + }, + { + "examine": "These doors look very ominous.", + "ids": "5056,5057" + }, + { + "examine": "Large doors set into the hillside.", + "ids": "5058,5059" + }, + { + "examine": "These doors seem to lead into the underground.", + "ids": "5060,5061" + }, + { + "examine": "Large doors set into the hillside.", + "ids": "5062,5063,5064,5065,5066,5067,5068,5069,5070,5071" + }, + { + "examine": "A deposit of rocks.", + "ids": "507,508,509,510" + }, + { + "examine": "A Large Pillar", + "ids": "5072,5073,5074,5075,5076,5077,5078,5079,5080,5081" + }, + { + "examine": "An overgrown dungeon entrance.", + "ids": "5082" + }, + { + "examine": "A closed overgrown dungeon entrance.", + "ids": "5083" + }, + { + "examine": "The way to go when I get scared.", + "ids": "5084,5085,5086,5087" + }, + { + "examine": "I hope I don't fall off this.", + "ids": "5088,5089,5090,5091,5092,5093" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "5094,5095,5096,5097,5098" + }, + { + "examine": "Hmmm... I wonder if it's loose enough to get through.", + "ids": "51" + }, + { + "examine": "Thick vines blocking your way.", + "ids": "5103,5104,5105,5106,5107,5108,5109" + }, + { + "examine": "A rock with a pickaxe and mining tools.", + "ids": "511" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "5110,5111" + }, + { + "examine": "Not good for eating.", + "ids": "5112" + }, + { + "examine": "I doubt that's edible.", + "ids": "5113,5114,5115" + }, + { + "examine": "A statue of a big monster.", + "ids": "5116,5117,5118,5119,5120,5121" + }, + { + "examine": "A tall wooden door.", + "ids": "5126" + }, + { + "examine": "A tall wooden door.", + "ids": "5128,5129" + }, + { + "examine": "Looks like whoever uses this has claws on their hands.", + "ids": "5130" + }, + { + "examine": "I wonder what's under it?", + "ids": "5131" + }, + { + "examine": "I wonder what's down there?", + "ids": "5132" + }, + { + "examine": "A hurdle.", + "ids": "5133,5134,5135" + }, + { + "examine": "A climbing wall made from skulls.", + "ids": "5136,5137" + }, + { + "examine": "A very slippery stepping stone.", + "ids": "5138" + }, + { + "examine": "A scary zip line for teeth??", + "ids": "5139,5140,5141,5142,5143,5144,5145" + }, + { + "examine": "A goal.", + "ids": "5146,5147,5148,5149,5150,5151" + }, + { + "examine": "This may be worth opening.", + "ids": "5156" + }, + { + "examine": "This may be worth searching.", + "ids": "5157" + }, + { + "examine": "A pile of garden canes.", + "ids": "5158" + }, + { + "examine": "There's no way to cross this bridge.", + "ids": "5159,5160" + }, + { + "examine": "A very tall column of ice.", + "ids": "516" + }, + { + "examine": "An old grandfather clock.", + "ids": "5161" + }, + { + "examine": "A closed chest.", + "ids": "5162" + }, + { + "examine": "An open chest.", + "ids": "5163" + }, + { + "examine": "There is a note pinned to the signpost.", + "ids": "5164" + }, + { + "examine": "It looks like it needs a good sweep out.", + "ids": "5165" + }, + { + "examine": "Bookish.", + "ids": "5166" + }, + { + "examine": "A large, elaborately ornamented memorial stone.", + "ids": "5167" + }, + { + "examine": "A grave, marked by an ostentatious memorial stone.", + "ids": "5168" + }, + { + "examine": "A poor grave marked by a simple, wooden cross.", + "ids": "5169" + }, + { + "examine": "A deposit of rocks.", + "ids": "517,518,519,520" + }, + { + "examine": "The entrance to an extravagantly decorated mausoleum.", + "ids": "5170,5171" + }, + { + "examine": "The door to the Tower.", + "ids": "5172,5173" + }, + { + "examine": "The door to the garden shed.", + "ids": "5174,5175" + }, + { + "examine": "At some point the lightning conductor has broken, rendering it useless.", + "ids": "5176" + }, + { + "examine": "A shocking piece of kit.", + "ids": "5177" + }, + { + "examine": "Mmm.. scented candles.", + "ids": "5178,5179" + }, + { + "examine": "I wouldn't eat there!", + "ids": "5180,5181,5182" + }, + { + "examine": "Looks wooden. Feels wooden. I wonder is it wooden?", + "ids": "5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201" + }, + { + "examine": "It's locked.", + "ids": "52,53" + }, + { + "examine": "Dangerous, someone could trip on them.", + "ids": "5202,5203,5204,5205" + }, + { + "examine": "I can climb these stairs.", + "ids": "5206" + }, + { + "examine": "They go down.", + "ids": "5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "5228,5229,5230" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "523,524,525,526,527,528" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243" + }, + { + "examine": "Looks a bit tatty...", + "ids": "5244,5245" + }, + { + "examine": "A well slept in bed.", + "ids": "5246,5247" + }, + { + "examine": "It looks like a tree made of crystal.", + "ids": "5248" + }, + { + "examine": "Looks to me like a quickly built fire.", + "ids": "5249" + }, + { + "examine": "I can climb down this.", + "ids": "5250" + }, + { + "examine": "I can climb this.", + "ids": "5251" + }, + { + "examine": "A recently extinguished fire.", + "ids": "5252" + }, + { + "examine": "I wish I could sting other people.", + "ids": "5253" + }, + { + "examine": "Probably feels like a mild bee sting.", + "ids": "5254" + }, + { + "examine": "I wouldn't like to get stung.", + "ids": "5255" + }, + { + "examine": "Dock leaves at the ready.", + "ids": "5256" + }, + { + "examine": "Nettles sting my leggies.", + "ids": "5257" + }, + { + "examine": "These may hurt.", + "ids": "5258" + }, + { + "examine": "A ghostly barrier.", + "ids": "5259,5260,5261" + }, + { + "examine": "These stairs were carved out of the rock of the cavern.", + "ids": "5262,5263" + }, + { + "examine": "I can climb this.", + "ids": "5264" + }, + { + "examine": "I can climb up here.", + "ids": "5265" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "5266" + }, + { + "examine": "I wonder what's under it.", + "ids": "5267" + }, + { + "examine": "I wonder what's down there.", + "ids": "5268" + }, + { + "examine": "I can't see a rock!", + "ids": "5269" + }, + { + "examine": "I wonder what's inside.", + "ids": "5270,5271,5272" + }, + { + "examine": "Perhaps I should search it.", + "ids": "5273" + }, + { + "examine": "High above here is a tattered flag, blowing in the wind.", + "ids": "5274" + }, + { + "examine": "An appliance for cooking with.", + "ids": "5275" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "5276" + }, + { + "examine": "This booth is closed.", + "ids": "5277" + }, + { + "examine": "The resting place of Necrovarus' mortal body.", + "ids": "5278,5279" + }, + { + "examine": "I can climb these stairs.", + "ids": "5280" + }, + { + "examine": "They go down.", + "ids": "5281" + }, + { + "examine": "A ghastly fountain filled with slime and bones, the source of Necrovarus' power.", + "ids": "5282" + }, + { + "examine": "It's a small Ectofuntus.", + "ids": "5283" + }, + { + "examine": "A big grinding thing.", + "ids": "5284" + }, + { + "examine": "The tatty gangplank of a tatty ship.", + "ids": "5285,5286" + }, + { + "examine": "Seen better days.", + "ids": "5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "529" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "530" + }, + { + "examine": "A wooden rowing boat.", + "ids": "5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "531" + }, + { + "examine": "Limestone floor growth.", + "ids": "532" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "533" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "5330" + }, + { + "examine": "A leafy fern.", + "ids": "5331" + }, + { + "examine": "A small bushy plant.", + "ids": "5332" + }, + { + "examine": "A leafy shrub.", + "ids": "5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "534" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "5346,5347" + }, + { + "examine": "Not so good for sitting on.", + "ids": "5348" + }, + { + "examine": "Generally used for putting things on.", + "ids": "5349" + }, + { + "examine": "Actually, I could do with a drink...", + "ids": "5350" + }, + { + "examine": "For leaning against...", + "ids": "5351" + }, + { + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "5352" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "5353" + }, + { + "examine": "Animal feeder.", + "ids": "5354" + }, + { + "examine": "It probably hasn't got anything interesting inside.", + "ids": "5355" + }, + { + "examine": "They probably haven't got anything interesting inside.", + "ids": "5356,5357" + }, + { + "examine": "Looks like he's been dead a while now...", + "ids": "5358" + }, + { + "examine": "I don't think he'd mind us checking for his wallet now...", + "ids": "5359" + }, + { + "examine": "I'm sure he died of natural causes. Like a massive dragon or something...", + "ids": "5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396" + }, + { + "examine": "A tooth shaped rock formation protruding from the ceiling.", + "ids": "539,540" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "5397,5398,5399,5400,5401,5402" + }, + { + "examine": "It's a flight of stairs.", + "ids": "54,55,56,57" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "5403" + }, + { + "examine": "Holds up the sails.", + "ids": "5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "541,542" + }, + { + "examine": "Allows access to other parts of the ship.", + "ids": "5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428" + }, + { + "examine": "It's a table with candles on.", + "ids": "5429" + }, + { + "examine": "A tooth shaped rock formation protruding from the ceiling.", + "ids": "543" + }, + { + "examine": "Doesn't look too good...", + "ids": "5430" + }, + { + "examine": "Looks a bit empty.", + "ids": "5431,5432,5433,5434,5435,5436,5437,5438" + }, + { + "examine": "It's been knocked off its hinges.", + "ids": "5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "544" + }, + { + "examine": "A huge lump of rock.", + "ids": "545" + }, + { + "examine": "It's a door.", + "ids": "5453,5454,5455,5456,5457,5458,5459,5460" + }, + { + "examine": "Intimidating!", + "ids": "546,547" + }, + { + "examine": "A subterranean pool of ectoplasm.", + "ids": "5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487" + }, + { + "examine": "A deposit of rocks.", + "ids": "548,549,550,551,552,553" + }, + { + "examine": "I can climb this.", + "ids": "5488" + }, + { + "examine": "The finest rings.", + "ids": "5489" + }, + { + "examine": "I wonder what's under it?", + "ids": "5490" + }, + { + "examine": "I wonder what's down there?", + "ids": "5491,5492" + }, + { + "examine": "I can climb this.", + "ids": "5493" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "5494" + }, + { + "examine": "I guess I could sleep in it if I was really tired.", + "ids": "5495,5496" + }, + { + "examine": "A well slept in bed.", + "ids": "5497,5498" + }, + { + "examine": "Hot!", + "ids": "5499,5500" + }, + { + "examine": "Stops people getting out.", + "ids": "5501,5502,5503,5504,5505,5506,5507" + }, + { + "examine": "It's a lectern.", + "ids": "5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537" + }, + { + "examine": "Makes you cry.", + "ids": "5538" + }, + { + "examine": "Found near the water's edge.", + "ids": "5539,5540,5541,5542" + }, + { + "examine": "Frozen water has formed an icicle here.", + "ids": "554,555,556,557" + }, + { + "examine": "Isn't Heather a girls' name?", + "ids": "5543" + }, + { + "examine": "Smells lovely!", + "ids": "5544" + }, + { + "examine": "Who is this Heather girl?", + "ids": "5545" + }, + { + "examine": "A purple haze of delight.", + "ids": "5546" + }, + { + "examine": "The colour purple on stems.", + "ids": "5547" + }, + { + "examine": "I ponder... Why is it purple?", + "ids": "5548" + }, + { + "examine": "I wonder why it's purple?", + "ids": "5549" + }, + { + "examine": "A cure for nettle stings.", + "ids": "5550" + }, + { + "examine": "A droopy tree.", + "ids": "5551" + }, + { + "examine": "These trees are found near water.", + "ids": "5552,5553" + }, + { + "examine": "This is what is left of a willow tree.", + "ids": "5554" + }, + { + "examine": "I don't know art, but I like it!", + "ids": "5555,5556,5557" + }, + { + "examine": "Aggie's cooking something, probably best not to think what...", + "ids": "5558,9736" + }, + { + "examine": "Trinkets and stuff.", + "ids": "5559" + }, + { + "examine": "Looking good!", + "ids": "5560" + }, + { + "examine": "Aggie's broomstick.", + "ids": "5561" + }, + { + "examine": "Aggie has already dyed this cloth.", + "ids": "5562,5563" + }, + { + "examine": "A thoroughly used bed.", + "ids": "5564" + }, + { + "examine": "A lovely comfy-looking big bed.", + "ids": "5565,5566,5567,5568" + }, + { + "examine": "The remains of a stone wall.", + "ids": "5569,5570" + }, + { + "examine": "An empty home for chickens.", + "ids": "5571" + }, + { + "examine": "A lovely bare chicken coop.", + "ids": "5572,5573" + }, + { + "examine": "Full of animal feed.", + "ids": "5574" + }, + { + "examine": "Animal feeder.", + "ids": "5575,5576,5577" + }, + { + "examine": "A traveller's companion.", + "ids": "5578" + }, + { + "examine": "Loaded with hay and ready to roll.", + "ids": "5579" + }, + { + "examine": "It looks cold in there.", + "ids": "558,559,560,561" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "5580" + }, + { + "examine": "Someone's been chopping logs.", + "ids": "5581,5582" + }, + { + "examine": "Baby bread.", + "ids": "5583,5584,5585,5586,5587,5588" + }, + { + "examine": "The river makes it spin.", + "ids": "5589,5590,5591,5592,5593" + }, + { + "examine": "I'd better not get my hands trapped in that.", + "ids": "5594" + }, + { + "examine": "Diango's Toy Stall.", + "ids": "5595" + }, + { + "examine": "Doesn't look too good...", + "ids": "5596" + }, + { + "examine": "Shows which way the wind blows.", + "ids": "5597" + }, + { + "examine": "A barrel for collecting rain water.", + "ids": "5598,5599,5600,5601,5602,5603" + }, + { + "examine": "A rock.", + "ids": "5604" + }, + { + "examine": "A small rock.", + "ids": "5605" + }, + { + "examine": "Some rock.", + "ids": "5606,5607" + }, + { + "examine": "This fire is already in use, I wouldn't mess with it if I were you...", + "ids": "5608" + }, + { + "examine": "They could do with a wash.", + "ids": "5609,5610,5611,5612" + }, + { + "examine": "It smells like the rats aren't washing often enough.", + "ids": "5613" + }, + { + "examine": "Sit back and relax...", + "ids": "5615" + }, + { + "examine": "This tells you which way is which.", + "ids": "5616,5617" + }, + { + "examine": "These open and close!", + "ids": "5618" + }, + { + "examine": "This may be worth searching.", + "ids": "5619,5620" + }, + { + "examine": "This person was of great importance.", + "ids": "562" + }, + { + "examine": "An elegant ceramic pot tarnished with the dirt of a hundred years.", + "ids": "5621" + }, + { + "examine": "I wonder what's inside...", + "ids": "5622" + }, + { + "examine": "It smells a bit stuffy.", + "ids": "5623" + }, + { + "examine": "It smells funny in there.", + "ids": "5624" + }, + { + "examine": "Ned is making some rope here.", + "ids": "5625,5626" + }, + { + "examine": "A blue standard.", + "ids": "5627" + }, + { + "examine": "A standard of Lumbridge Castle.", + "ids": "5628,5629,5630,36925" + }, + { + "examine": "A monarch chiselled in stone.", + "ids": "563,564" + }, + { + "examine": "Glowing embers.", + "ids": "5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787" + }, + { + "examine": "A sculpture of a monarch.", + "ids": "565" + }, + { + "examine": "This person was of great importance.", + "ids": "566" + }, + { + "examine": "A huge carving of an ancient race.", + "ids": "567" + }, + { + "examine": "A depiction of a great dwarven miner.", + "ids": "568" + }, + { + "examine": "A depiction of a famous gnome warrior.", + "ids": "569,570" + }, + { + "examine": "The head and shoulders of a famous gnome.", + "ids": "571,572" + }, + { + "examine": "A depiction of a famous gnomeballer.", + "ids": "573" + }, + { + "examine": "A carving of a figure from the history of 2009Scape.", + "ids": "574,575,576,577,578" + }, + { + "examine": "The sort of bench you get in churches.", + "ids": "5788" + }, + { + "examine": "An expertly carved statue of a former King of Misthalin.", + "ids": "5789,5790" + }, + { + "examine": "An expertly chiselled statue.", + "ids": "579,580,581" + }, + { + "examine": "A carving of a figure from the history of 2009Scape.", + "ids": "5791,36749,36751" + }, + { + "examine": "When I've ground some flour, I'll be able to collect it here.", + "ids": "5792" + }, + { + "examine": "It's a large crack in the wall.", + "ids": "5793,5794,5795,5796,5797,5798" + }, + { + "examine": "It's a trapdoor.", + "ids": "5799,5800,5801,5802" + }, + { + "examine": "Known commonly as Red worm vine.", + "ids": "58" + }, + { + "examine": "It's an open trapdoor.", + "ids": "5803,5804,5805,5806,5807" + }, + { + "examine": "An incredibly detailed stone sculpture.", + "ids": "5808" + }, + { + "examine": "Helps the Seers predict the weather when it's working.", + "ids": "5809" + }, + { + "examine": "Helps the Seers predict the weather.", + "ids": "5810,5811" + }, + { + "examine": "I can climb this.", + "ids": "5812" + }, + { + "examine": "I can climb down this.", + "ids": "5813,5814" + }, + { + "examine": "A candle, a lens and some sort of crystal all precariously balanced together.", + "ids": "5815" + }, + { + "examine": "A beacon so gnome gliders can safely land.", + "ids": "5816,5817,5818,5819,5820,5821,5822,5823,5824" + }, + { + "examine": "An unusual symbol of ancient times.", + "ids": "582" + }, + { + "examine": "Fly Gnome Air.", + "ids": "5825" + }, + { + "examine": "This shop deals in antique swords.", + "ids": "5826,5827,5828,5829,5830" + }, + { + "examine": "An expertly crafted vase.", + "ids": "583" + }, + { + "examine": "Shop counter.", + "ids": "5831,5832,5833,5834" + }, + { + "examine": "Don't want to close this, I might not be able to get back down.", + "ids": "5835,5836,5837,5838,5839,5840,5841" + }, + { + "examine": "An expertly chiselled statue of a bird.", + "ids": "584" + }, + { + "examine": "It overlooks the path below. Let's hope it won't fall on your head.", + "ids": "5842" + }, + { + "examine": "Someone is climbing down there! Looks dangerous.", + "ids": "5843" + }, + { + "examine": "Placed in a perfect position for stumbling over.", + "ids": "5844" + }, + { + "examine": "There is a rope going over it.", + "ids": "5845" + }, + { + "examine": "Someone is climbing down the rope.", + "ids": "5846" + }, + { + "examine": "You will need to climb over it.", + "ids": "5847" + }, + { + "examine": "The tree stands tall at the edge of the pool.", + "ids": "5848" + }, + { + "examine": "You can't stand on them, but maybe something can be wedged into there.", + "ids": "5849" + }, + { + "examine": "What a good likeness!", + "ids": "585,586" + }, + { + "examine": "Something put on top of this wouldn't fall off, it's quite smooth and flat.", + "ids": "5850,5851" + }, + { + "examine": "Someone put a plank on top of the stone! Clever...", + "ids": "5852,5853,5854" + }, + { + "examine": "The pool looks very peaceful. You can also hear faint singing coming from it.", + "ids": "5855" + }, + { + "examine": "The legendary White Pearl fruit is growing on these thorny bushes!", + "ids": "5856" + }, + { + "examine": "There's a nasty stench coming from the cave.", + "ids": "5857" + }, + { + "examine": "Faint rays of daylight shine through.", + "ids": "5858" + }, + { + "examine": "It's very dark down there.", + "ids": "5859" + }, + { + "examine": "Very pointy, very sharp.", + "ids": "5860,5861" + }, + { + "examine": "This is the place where you buried Asleif.", + "ids": "5862" + }, + { + "examine": "Asleif was given a proper burial on this spot.", + "ids": "5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876,5877" + }, + { + "examine": "A depiction of the evil god Zamorak.", + "ids": "587" + }, + { + "examine": "It's a long wooden table.", + "ids": "5878" + }, + { + "examine": "Generally used for putting things on.", + "ids": "5879" + }, + { + "examine": "A base for the statue to sit on.", + "ids": "588" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "5881,5882" + }, + { + "examine": "Sticky, dirty mud.", + "ids": "5883" + }, + { + "examine": "This stinks...", + "ids": "5884" + }, + { + "examine": "The roots go down into the mud.", + "ids": "5885" + }, + { + "examine": "Sticky, dirty roots covered in sticky, dirty mud.", + "ids": "5886" + }, + { + "examine": "It's barely a door, really.", + "ids": "5887,5888,5889,5890" + }, + { + "examine": "The scrying glass of a seer.", + "ids": "589" + }, + { + "examine": "The entry to a special tent in the camp.", + "ids": "5891,5892,5893,5894" + }, + { + "examine": "It's just a big stone, really.", + "ids": "5895" + }, + { + "examine": "Uh oh, someone is going to be in trouble!", + "ids": "5896" + }, + { + "examine": "The pool looks very peaceful. You can also hear faint singing coming from it.", + "ids": "5897,5898,5899,5900,5901" + }, + { + "examine": "A fancy hole in the wall.", + "ids": "59" + }, + { + "examine": "Banking transactions are processed here.", + "ids": "590" + }, + { + "examine": "It's only useful for hiding behind now.", + "ids": "5902,5903,5904" + }, + { + "examine": "This tree has been cut down.", + "ids": "5905,5906,5907,5908" + }, + { + "examine": "A still for making lamp oil.", + "ids": "5909" + }, + { + "examine": "Banking transactions are recorded here.", + "ids": "591" + }, + { + "examine": "The still has oil in.", + "ids": "5910,5911,5912,5913,5914,5915,5916" + }, + { + "examine": "Noxious fumes bubble up from the bowels of the earth.", + "ids": "5917,5918,5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945" + }, + { + "examine": "Contains washing items.", + "ids": "592" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "593,594,595" + }, + { + "examine": "You see a circle of light at the top.", + "ids": "5946" + }, + { + "examine": "An entrance to the dark caves.", + "ids": "5947" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "5948,5949,5950,5951,5952,5953,5954,5955,5956,5957,5958" + }, + { + "examine": "I wonder what this does...", + "ids": "5959,5960,5961,5962,5963" + }, + { + "examine": "A banquet could be eaten from this.", + "ids": "596,597" + }, + { + "examine": "Flying in mid-air!", + "ids": "5964,5965" + }, + { + "examine": "A blocked passage.", + "ids": "5966" + }, + { + "examine": "I'd better leave his expensive dwarven balls alone.", + "ids": "5967,5968,5969,5970,5971,5972" + }, + { + "examine": "A small cave entrance.", + "ids": "5973,5974" + }, + { + "examine": "A powerful ranging device that fires metal balls.", + "ids": "5975,5976" + }, + { + "examine": "It's a sheer wall of fire, rising as high as you can see.", + "ids": "5977,5978,5979,5980" + }, + { + "examine": "Useful for putting things on.", + "ids": "598" + }, + { + "examine": "Lighting for the caves.", + "ids": "5981,5982,5983,5984" + }, + { + "examine": "A rock.", + "ids": "5985" + }, + { + "examine": "A small rock.", + "ids": "5986" + }, + { + "examine": "A rock.", + "ids": "5987,5988" + }, + { + "examine": "A mineral vein that looks distinctly like gold.", + "ids": "5989,5990,5991,5992,5993,5994,5995,5996,5997" + }, + { + "examine": "At one time it was for putting things on.", + "ids": "599" + }, + { + "examine": "Functions like an open door...", + "ids": "5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008" + }, + { + "examine": "A powerful ranging device that fires metal balls.", + "ids": "6" + }, + { + "examine": "A fancy hole in the ceiling.", + "ids": "60" + }, + { + "examine": "The napkins are made from real silk.", + "ids": "600" + }, + { + "examine": "It's a tiny little blue flame. Is this the essence of the Arzinian Being?", + "ids": "6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031" + }, + { + "examine": "Useful for putting things on.", + "ids": "601,602,603,604,605,606" + }, + { + "examine": "Powers the boat.", + "ids": "6032,6033,6034,6035" + }, + { + "examine": "Allows access to other parts of the ship.", + "ids": "6036,6037" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "6038,6039,6040,6041,6042" + }, + { + "examine": "Powers the boat.", + "ids": "6043,6044" + }, + { + "examine": "You can 'cart' things around on this.", + "ids": "6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063" + }, + { + "examine": "A stand for hats.", + "ids": "6064" + }, + { + "examine": "Some dwarf clothes that are obviously too small for me!", + "ids": "6065" + }, + { + "examine": "An empty weapon rack.", + "ids": "6066" + }, + { + "examine": "A weapon rack.", + "ids": "6067,6068,6069" + }, + { + "examine": "Items for making clothes are kept on here.", + "ids": "607" + }, + { + "examine": "A method of dwarf storage", + "ids": "6070" + }, + { + "examine": "A method of dwarf storage.", + "ids": "6071,6072,6073,6074" + }, + { + "examine": "Useful for a dwarf.", + "ids": "6075" + }, + { + "examine": "A big desk, for a dwarf!", + "ids": "6076,6077,6078,6079" + }, + { + "examine": "The ideal place to study.", + "ids": "608" + }, + { + "examine": "Spins yarn.", + "ids": "6080" + }, + { + "examine": "Banking transactions are processed here.", + "ids": "6081" + }, + { + "examine": "Banking transactions are recorded here.", + "ids": "6082,37159" + }, + { + "examine": "This booth is closed.", + "ids": "6083" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "6084" + }, + { + "examine": "A way upwards.", + "ids": "6085" + }, + { + "examine": "A way down.", + "ids": "6086" + }, + { + "examine": "A way upwards.", + "ids": "6087" + }, + { + "examine": "A way down.", + "ids": "6088" + }, + { + "examine": "A way upwards.", + "ids": "6089" + }, + { + "examine": "A handy workbench for a handy person.", + "ids": "609,610" + }, + { + "examine": "A way down.", + "ids": "6090" + }, + { + "examine": "A treasure trove of knowledge.", + "ids": "6091,6092" + }, + { + "examine": "A lovely place to cook meat.", + "ids": "6093,6094,6095" + }, + { + "examine": "A great place to cook meat.", + "ids": "6096" + }, + { + "examine": "A good source of water.", + "ids": "6097,6098,6099" + }, + { + "examine": "A shrine to evil.", + "ids": "61" + }, + { + "examine": "The door is closed.", + "ids": "6100" + }, + { + "examine": "The door is open.", + "ids": "6101" + }, + { + "examine": "The door is closed.", + "ids": "6102" + }, + { + "examine": "The door is open.", + "ids": "6103" + }, + { + "examine": "The door is closed.", + "ids": "6104" + }, + { + "examine": "The door is open.", + "ids": "6105" + }, + { + "examine": "The door is closed.", + "ids": "6106" + }, + { + "examine": "The door is open.", + "ids": "6107" + }, + { + "examine": "The door is closed.", + "ids": "6108" + }, + { + "examine": "The door is open.", + "ids": "6109" + }, + { + "examine": "Sit back and enjoy the view.", + "ids": "611" + }, + { + "examine": "The door is closed.", + "ids": "6110" + }, + { + "examine": "The door is open.", + "ids": "6111" + }, + { + "examine": "The door is closed.", + "ids": "6112" + }, + { + "examine": "The door is open.", + "ids": "6113" + }, + { + "examine": "The door is closed.", + "ids": "6114" + }, + { + "examine": "The door is open.", + "ids": "6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145" + }, + { + "examine": "Items are for sale here.", + "ids": "612" + }, + { + "examine": "Useful for putting things on.", + "ids": "613,614,615" + }, + { + "examine": "Useful for keeping birds.", + "ids": "6146" + }, + { + "examine": "Tower of rock.", + "ids": "6147,6148,6149" + }, + { + "examine": "Useful for making weapons.", + "ids": "6150" + }, + { + "examine": "Used for getting water.", + "ids": "6151" + }, + { + "examine": "Used for getting drunk.", + "ids": "6152,6153" + }, + { + "examine": "Used for storage.", + "ids": "6154,6155,6156,6157" + }, + { + "examine": "Not good for eating.", + "ids": "6158,6159,6160,6161" + }, + { + "examine": "A creepy looking table.", + "ids": "616" + }, + { + "examine": "Finest precious stones.", + "ids": "6162" + }, + { + "examine": "Bread and cakes are spread out over it.", + "ids": "6163" + }, + { + "examine": "Finely wrought wares of silver.", + "ids": "6164" + }, + { + "examine": "I can get clothes made up from this stall.", + "ids": "6165" + }, + { + "examine": "A whole lot of tools for crafting.", + "ids": "6166,6167,6168,6169,6170,6171,6172" + }, + { + "examine": "Items are for sale here.", + "ids": "617" + }, + { + "examine": "A fine piece of sculpting.", + "ids": "6173,6174,6175" + }, + { + "examine": "Oblong boxes. You hope there isn't anything other than salt inside.", + "ids": "6176" + }, + { + "examine": "Big mysterious crates. You wonder what could be inside.", + "ids": "6177" + }, + { + "examine": "Wooden crates, contents unknown.", + "ids": "6178" + }, + { + "examine": "They could do with a wash.", + "ids": "6179,6180" + }, + { + "examine": "There are some strange chemicals here.", + "ids": "618,619" + }, + { + "examine": "Dead animal parts dangling!", + "ids": "6181" + }, + { + "examine": "Dead meat. Dangling from the wall. Looks delicious.", + "ids": "6182" + }, + { + "examine": "It looks as hard as a rock, not very inviting.", + "ids": "6183" + }, + { + "examine": "A smelly old mattress.", + "ids": "6184" + }, + { + "examine": "Metal plating to protect the dwarf.", + "ids": "6185,6186" + }, + { + "examine": "Useful... for a dwarf!", + "ids": "6187" + }, + { + "examine": "Various implements for working with metal.", + "ids": "6188" + }, + { + "examine": "A hot place for forging things in.", + "ids": "6189,6190" + }, + { + "examine": "Being repaired.", + "ids": "6191,6192" + }, + { + "examine": "I look shorter, but not necessarily sweeter!", + "ids": "6193" + }, + { + "examine": "Used for sitting.", + "ids": "6194,6195" + }, + { + "examine": "Useful for a dwarf.", + "ids": "6196,6197,6198,6199" + }, + { + "examine": "Is there something in there?", + "ids": "62" + }, + { + "examine": "Bamboo's a versatile material.", + "ids": "620" + }, + { + "examine": "Fit for a dwarven feast!", + "ids": "6200,6201" + }, + { + "examine": "Gives out light, but then you knew that already.", + "ids": "6202,6203" + }, + { + "examine": "A simple place to sleep.", + "ids": "6204" + }, + { + "examine": "A good dwarven bed. Too small for me!", + "ids": "6205" + }, + { + "examine": "Many important meetings are held here...", + "ids": "6206" + }, + { + "examine": "Draped in cloth.", + "ids": "6207" + }, + { + "examine": "A beautiful seat, fit for a King.", + "ids": "6208,6209,6210" + }, + { + "examine": "It's a banquet table.", + "ids": "621,622" + }, + { + "examine": "A dwarf table with chopping board.", + "ids": "6211" + }, + { + "examine": "This tree has been cut down.", + "ids": "6212" + }, + { + "examine": "A barrel full of ranging equipment...", + "ids": "6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "623,624,625,626,627" + }, + { + "examine": "I suppose he wants my money.", + "ids": "6230" + }, + { + "examine": "A lovely table.", + "ids": "6231" + }, + { + "examine": "An expensive water feature.", + "ids": "6232,6233,6234,6235" + }, + { + "examine": "Stop for what, food?", + "ids": "6236" + }, + { + "examine": "Yellow blossom, lovely.", + "ids": "6237" + }, + { + "examine": "Closed.", + "ids": "6238" + }, + { + "examine": "Open.", + "ids": "6239" + }, + { + "examine": "Closed.", + "ids": "6240" + }, + { + "examine": "Open.", + "ids": "6241" + }, + { + "examine": "A stone staircase.", + "ids": "6242,6243,6244,6245" + }, + { + "examine": "Has upon it a beer, which I will not take for moral reasons.", + "ids": "6246,6247,6248" + }, + { + "examine": "No this is not a mirage!", + "ids": "6249" + }, + { + "examine": "It's a goldfish! No, wait, it's just a bed.", + "ids": "6250,6251,6252,6253,6254" + }, + { + "examine": "Animal feeder.", + "ids": "6255,6256" + }, + { + "examine": "Lovely... Fresh.", + "ids": "6257" + }, + { + "examine": "Dry dung.", + "ids": "6258" + }, + { + "examine": "Smelly.", + "ids": "6259" + }, + { + "examine": "I can climb down this.", + "ids": "6260" + }, + { + "examine": "I can climb this.", + "ids": "6261,6262" + }, + { + "examine": "Useful for pets.", + "ids": "6263" + }, + { + "examine": "Useful for keeping birds.", + "ids": "6264" + }, + { + "examine": "Bird cage.", + "ids": "6265,6266" + }, + { + "examine": "An empty cage, maybe the owner let the creature free... I do hope so.", + "ids": "6267" + }, + { + "examine": "Useful for pets.", + "ids": "6268,6269,6270,6271,6272,6273" + }, + { + "examine": "Lovely comfy looking big bed.", + "ids": "6274" + }, + { + "examine": "Laden with heaps of paper.", + "ids": "6275" + }, + { + "examine": "I don't know much about art, but I like this.", + "ids": "6276" + }, + { + "examine": "Look at the size of this cactus.", + "ids": "6277" + }, + { + "examine": "Don't you open that trapdoor!", + "ids": "6278" + }, + { + "examine": "There is a rope leading to the bottom of this smoke filled well.", + "ids": "6279" + }, + { + "examine": "Finely wrought wares of silver.", + "ids": "628" + }, + { + "examine": "I can climb this.", + "ids": "6280,6281" + }, + { + "examine": "A portal to another land?", + "ids": "6282" + }, + { + "examine": "Weird looking pillar.", + "ids": "6283,6284,6285,6286,6287,6288,6289,6290,6291" + }, + { + "examine": "Garments for the discerning.", + "ids": "629" + }, + { + "examine": "Shelves filled with interesting books.", + "ids": "6292,6293" + }, + { + "examine": "A locked display case for valuable artefacts.", + "ids": "6294" + }, + { + "examine": "One of the sculptures is missing. Oh yes, that was me!", + "ids": "6295" + }, + { + "examine": "It looks like the demon didn't survive after all.", + "ids": "6296" + }, + { + "examine": "He looks old, older than me anyway.", + "ids": "6297" + }, + { + "examine": "I don't think he's going to make it.", + "ids": "6298" + }, + { + "examine": "I don't understand, why didn't he go back to Lumby?", + "ids": "6299,6300" + }, + { + "examine": "Used for storage.", + "ids": "63,64,36351,36352" + }, + { + "examine": "Bread cakes and pastries.", + "ids": "630" + }, + { + "examine": "A throne encrusted with sparkling gems.", + "ids": "6301" + }, + { + "examine": "A throne from which you have removed the gems.", + "ids": "6302,6303,6304,6305,6306" + }, + { + "examine": "A statuette of a golem, facing right.", + "ids": "6307" + }, + { + "examine": "A statuette of a golem, facing left.", + "ids": "6308" + }, + { + "examine": "The statuette is missing from this alcove.", + "ids": "6309,6310" + }, + { + "examine": "Finest precious stones.", + "ids": "631" + }, + { + "examine": "Not good for eating.", + "ids": "6311" + }, + { + "examine": "I can climb this.", + "ids": "6312" + }, + { + "examine": "I can climb down this.", + "ids": "6313,6314,6315,6316,6317,6318,6319,6320,6321,6322" + }, + { + "examine": "These will keep you warm.", + "ids": "632" + }, + { + "examine": "A broken clay arm.", + "ids": "6323" + }, + { + "examine": "A clay foot.", + "ids": "6324" + }, + { + "examine": "Half a golem smashed and broken.", + "ids": "6325" + }, + { + "examine": "Smashed and half buried.", + "ids": "6326" + }, + { + "examine": "A device once used for making pottery.", + "ids": "6327" + }, + { + "examine": "Once upon a time this was used to make pottery.", + "ids": "6328" + }, + { + "examine": "Once upon a time this made clay hard.", + "ids": "6329" + }, + { + "examine": "The spice is right.", + "ids": "633" + }, + { + "examine": "There was a lot of pottery made here a long time ago.", + "ids": "6330" + }, + { + "examine": "A statue of a guy with a hammer.", + "ids": "6331" + }, + { + "examine": "A weathered old statue.", + "ids": "6332" + }, + { + "examine": "A reclining lady.", + "ids": "6333" + }, + { + "examine": "This statue has been tampered with.", + "ids": "6334" + }, + { + "examine": "Contains a statue of a woman.", + "ids": "6335,6336,6337" + }, + { + "examine": "Empty.", + "ids": "6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362" + }, + { + "examine": "Always a source of good bargains.", + "ids": "634" + }, + { + "examine": "Fine brews from exotic regions.", + "ids": "635" + }, + { + "examine": "Keeps mine carts from rolling away.", + "ids": "636" + }, + { + "examine": "A very heavy stone door.", + "ids": "6363" + }, + { + "examine": "A door to a demon's lair?", + "ids": "6364,6365,6366,6367,6368,6369,6370,6371" + }, + { + "examine": "You can 'cart' things around on this.", + "ids": "637" + }, + { + "examine": "A stone staircase.", + "ids": "6372,6373,6374,6375,6376,6377,6378,6379,6380" + }, + { + "examine": "A source of water for the river Elid.", + "ids": "6381" + }, + { + "examine": "Maybe I could swing on this somehow...", + "ids": "6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,6399,6400,6401" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "6402" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "6403" + }, + { + "examine": "An old mystical torch.", + "ids": "6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417" + }, + { + "examine": "I can climb this.", + "ids": "6418,6419" + }, + { + "examine": "I wonder what's inside?", + "ids": "6420,6421,6422" + }, + { + "examine": "A magical aura seems to shimmer over the glass...", + "ids": "6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433" + }, + { + "examine": "I wonder what that's there for...", + "ids": "6434,6435" + }, + { + "examine": "I can climb this.", + "ids": "6436" + }, + { + "examine": "An ancient looking tomb.", + "ids": "6437,6438" + }, + { + "examine": "Climb this rope to go up.", + "ids": "6439,6440" + }, + { + "examine": "Looks like a small cave.", + "ids": "6441" + }, + { + "examine": "Blocked by an icicle.", + "ids": "6442" + }, + { + "examine": "Blocked by two icicles.", + "ids": "6443" + }, + { + "examine": "Blocked by three icicles.", + "ids": "6444" + }, + { + "examine": "Blocked by four icicles.", + "ids": "6445" + }, + { + "examine": "Blocked by five icicles.", + "ids": "6446" + }, + { + "examine": "Looks like a small cave.", + "ids": "6447" + }, + { + "examine": "It looks very sturdy.", + "ids": "6448,6449" + }, + { + "examine": "I can climb this.", + "ids": "6450" + }, + { + "examine": "A wrought iron gate.", + "ids": "6451,6452,6453" + }, + { + "examine": "Even rocks could freeze in this cold!", + "ids": "6454" + }, + { + "examine": "Looks slippery.", + "ids": "6455,6456,6457,6458,6459,6460" + }, + { + "examine": "An ice gate.", + "ids": "6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471" + }, + { + "examine": "Makes you taller.", + "ids": "647,29314" + }, + { + "examine": "Chunky pieces of ice.", + "ids": "6472,6473,6474,6475,6476,6477,6478,6479,6480" + }, + { + "examine": "A bit large for a bracelet!", + "ids": "648" + }, + { + "examine": "A mysterious tunnel-like structure.", + "ids": "6481,6482" + }, + { + "examine": "You can feel a mysterious power emanating from it...", + "ids": "6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493" + }, + { + "examine": "A macabre variation on the neck tie.", + "ids": "649,650" + }, + { + "examine": "This door is sealed by an ancient mystical power...", + "ids": "6494,6495,6496" + }, + { + "examine": "I can climb down this.", + "ids": "6497,6498,6499,6500" + }, + { + "examine": "Surprisingly sturdy looking.", + "ids": "65,66" + }, + { + "examine": "I can climb this.", + "ids": "6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511" + }, + { + "examine": "Dead and half buried.", + "ids": "651,652,653,654,655,656,657" + }, + { + "examine": "A fancy name for a coffin.", + "ids": "6512" + }, + { + "examine": "A strange thing to leave lying around...", + "ids": "6513" + }, + { + "examine": "I hope this is just ornamental...", + "ids": "6514,6515,6516,6517,6518,6519,6520" + }, + { + "examine": "Uh-oh!", + "ids": "6521,6522" + }, + { + "examine": "This leads downwards.", + "ids": "6523" + }, + { + "examine": "You can see a small fissure in the ground here.", + "ids": "6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537" + }, + { + "examine": "The body of a lion, the head of a man?", + "ids": "6538,6539,6540,6541,6542,6543,6544" + }, + { + "examine": "A smooth, sandstone door that is slightly warm to the touch.", + "ids": "6545,6546,6547,6548" + }, + { + "examine": "A well down into the pyramid.", + "ids": "6549,6550" + }, + { + "examine": "A portal that leads you out of the pyramid.", + "ids": "6551" + }, + { + "examine": "A mysterious ancient altar to some forgotten god...", + "ids": "6552" + }, + { + "examine": "Opens into another area.", + "ids": "6553,6554,6555,6556,6557,6558,6559,6560" + }, + { + "examine": "A ladder that's almost not there at all...", + "ids": "6561,6562,6563,6564,6565" + }, + { + "examine": "Gate like?", + "ids": "6566,6567" + }, + { + "examine": "Garments for the discerning.", + "ids": "6568" + }, + { + "examine": "Gone-off bread, cakes and pastries.", + "ids": "6569" + }, + { + "examine": "Finest precious stones.", + "ids": "6570" + }, + { + "examine": "These will keep you warm.", + "ids": "6571" + }, + { + "examine": "The spice is right.", + "ids": "6572" + }, + { + "examine": "An empty market stall.", + "ids": "6573" + }, + { + "examine": "Fine brews from exotic regions.", + "ids": "6574" + }, + { + "examine": "Best used with a horse.", + "ids": "6575,6576,6577" + }, + { + "examine": "Grows a yellow fruit.", + "ids": "6578,6579,6580" + }, + { + "examine": "Disturbing but tidy.", + "ids": "658" + }, + { + "examine": "Disturbing but tidy.", + "ids": "658,668,669,670,3969,29347" + }, + { + "examine": "A way to get in the tent.", + "ids": "6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604" + }, + { + "examine": "I don't even want to think about what did that...", + "ids": "659" + }, + { + "examine": "Now that's what I call slimline!", + "ids": "660,664,3797,3971,5122,7206,29340" + }, + { + "examine": "Wet and salty.", + "ids": "6605" + }, + { + "examine": "The focus of the suntrap.", + "ids": "6606" + }, + { + "examine": "A shiny mirror.", + "ids": "6607,6608,6609,6610,6611,6612,6613" + }, + { + "examine": "He looks very relaxed.", + "ids": "661,665,3798,3972,5123,7207,29341" + }, + { + "examine": "A large door with a hieroglyph of a cat.", + "ids": "6614" + }, + { + "examine": "Gate like?", + "ids": "6615,6616,6617,6618,6619" + }, + { + "examine": "Now he's just too thin.", + "ids": "662,666,3799,3973,5124,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,29342" + }, + { + "examine": "It looks like a hole in the wall.", + "ids": "6620,6621" + }, + { + "examine": "Rocky.", + "ids": "6622" + }, + { + "examine": "An entrance into a tunnel. I wonder where it leads to.", + "ids": "6623" + }, + { + "examine": "It looks like a door.", + "ids": "6624" + }, + { + "examine": "Hmm. A door.", + "ids": "6625" + }, + { + "examine": "A big wooden door.", + "ids": "6626,6627,6628" + }, + { + "examine": "That could hurt.", + "ids": "6629" + }, + { + "examine": "He hasn't eaten in a long time.", + "ids": "663,667,3974,5125,29343" + }, + { + "examine": "A strange thing to leave lying around...", + "ids": "6630,6631" + }, + { + "examine": "I can't see the bottom.", + "ids": "6632,6633,6634" + }, + { + "examine": "Has a lid shaped like a man. I think it contains someone's liver. Yuck.", + "ids": "6635,6636" + }, + { + "examine": "Has a lid shaped like a crocodile. Yuck, I think there are lungs inside.", + "ids": "6637,6638" + }, + { + "examine": "Has a lid shaped like a bug. Disgusting! I think there's a stomach inside.", + "ids": "6639,6640" + }, + { + "examine": "Has a lid shaped like an ape. Eeew! I think it contains someone's intestines.", + "ids": "6641" + }, + { + "examine": "Doorway*Opens into another area, come on, I know this.", + "ids": "6642" + }, + { + "examine": "Useful for putting things on.", + "ids": "6644" + }, + { + "examine": "A ladder!! Never seen one of those before.", + "ids": "6645" + }, + { + "examine": "I wonder what's inside.", + "ids": "6646" + }, + { + "examine": "Perhaps I should search it.", + "ids": "6647" + }, + { + "examine": "I wonder where this goes?", + "ids": "6648" + }, + { + "examine": "They go down.", + "ids": "6649" + }, + { + "examine": "Phew!! That's one big bridge.", + "ids": "6650" + }, + { + "examine": "A big bridge over the river.", + "ids": "6651,6652" + }, + { + "examine": "Wow. More bridge. Awesome.", + "ids": "6653,6654" + }, + { + "examine": "Oops.", + "ids": "6655" + }, + { + "examine": "Rolls of colourful cloth.", + "ids": "6656" + }, + { + "examine": "An ancient giant serpent.", + "ids": "6657" + }, + { + "examine": "A tunnel leading upwards.", + "ids": "6658" + }, + { + "examine": "A tunnel leading into the depths of the earth.", + "ids": "6659" + }, + { + "examine": "A rock wall infused with the power of Guthix.", + "ids": "6660" + }, + { + "examine": "The wall is weeping blue tears.", + "ids": "6661" + }, + { + "examine": "The wall is weeping green tears.", + "ids": "6662" + }, + { + "examine": "The wall is not weeping at the moment.", + "ids": "6663,6664" + }, + { + "examine": "The wall is weeping blue tears.", + "ids": "6665" + }, + { + "examine": "The wall is weeping green tears.", + "ids": "6666" + }, + { + "examine": "The wall is not weeping at the moment.", + "ids": "6667,6668" + }, + { + "examine": "Stone with blue veins.", + "ids": "6669,6670,6671" + }, + { + "examine": "They don't look too easy to climb.", + "ids": "6672" + }, + { + "examine": "I could climb these.", + "ids": "6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701" + }, + { + "examine": "Used for storage.", + "ids": "67" + }, + { + "examine": "I can climb these stairs.", + "ids": "6702,6703,6704,6705,6706,6707" + }, + { + "examine": "I can climb this.", + "ids": "6708,6709,6710,6711,6712" + }, + { + "examine": "No cats were harmed in the making of this device.", + "ids": "671" + }, + { + "examine": "I wonder what is awaiting me on the other side?", + "ids": "6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731" + }, + { + "examine": "Shattered.", + "ids": "672,673,674,675,676,677" + }, + { + "examine": "I wonder what awaits me on the other side?", + "ids": "6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "6767,6768,6769,6770" + }, + { + "examine": "A large stone coffin.", + "ids": "6771,6772,6773" + }, + { + "examine": "A large stone chest.", + "ids": "6774,6775" + }, + { + "examine": "Looks like he's been dead a while now...", + "ids": "6776" + }, + { + "examine": "I don't think he'd mind us checking for his wallet now...", + "ids": "6777" + }, + { + "examine": "I'm sure he died of natural causes. Like a massive dragon or something...", + "ids": "6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790" + }, + { + "examine": "I see fish.", + "ids": "678" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "679" + }, + { + "examine": "The groundskeeper's bed.", + "ids": "6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820" + }, + { + "examine": "Where bees live.", + "ids": "68" + }, + { + "examine": "I was always forced to play this as a child.", + "ids": "680" + }, + { + "examine": "I never learnt to play.", + "ids": "681" + }, + { + "examine": "Time for a recital?", + "ids": "682" + }, + { + "examine": "A large stone coffin.", + "ids": "6821,6822,6823" + }, + { + "examine": "It's locked.", + "ids": "6824,6825,6826" + }, + { + "examine": "It might still work...", + "ids": "6827,6828,6829,6830,6831,6832,6833,6834" + }, + { + "examine": "Tick-tock, it's a clock.", + "ids": "683" + }, + { + "examine": "Danger... weak surface beyond gate. Digging may lead to cave-ins.", + "ids": "6835" + }, + { + "examine": "Sturdy metal bars.", + "ids": "6836,6837,6838" + }, + { + "examine": "Smells pretty bad!", + "ids": "6839" + }, + { + "examine": "The noxious liquid bubbles horribly.", + "ids": "684" + }, + { + "examine": "It looks as this is where some wall fungus used to be.", + "ids": "6840" + }, + { + "examine": "Some crude stone steps.", + "ids": "6841,6842,6843" + }, + { + "examine": "An old crude tomb.", + "ids": "6844,6845" + }, + { + "examine": "It's damaged.", + "ids": "6846" + }, + { + "examine": "A note says, 'Please ring for attention.'", + "ids": "6847" + }, + { + "examine": "An old crude tomb.", + "ids": "6848" + }, + { + "examine": "'Leave da dead-uns boxes 'lone or else ya goes down da 'ole'", + "ids": "6849" + }, + { + "examine": "Shows which way the wind blows.", + "ids": "685,686,687,688" + }, + { + "examine": "An old crude tomb.", + "ids": "6850" + }, + { + "examine": "This coffin is spilt over the floor.", + "ids": "6851" + }, + { + "examine": "This coffin is open.", + "ids": "6852" + }, + { + "examine": "An old crude tomb.", + "ids": "6853" + }, + { + "examine": "This coffin is spilt over the floor.", + "ids": "6854" + }, + { + "examine": "This coffin is open.", + "ids": "6855" + }, + { + "examine": "A barricade made from skulls and bones.", + "ids": "6856,6857,6858,6859,6860,6861,6862,6863,6864" + }, + { + "examine": "Not very high.", + "ids": "6865" + }, + { + "examine": "Hot stuff.", + "ids": "6866" + }, + { + "examine": "Ogres bang these to make noise.", + "ids": "6867,6868,6869,6870" + }, + { + "examine": "A bulky door made from solid rock.", + "ids": "6871,6872,6873,6874" + }, + { + "examine": "These open and close!", + "ids": "6875" + }, + { + "examine": "This may be worth opening.", + "ids": "6876" + }, + { + "examine": "I wonder what this item contains.", + "ids": "6877,6878,6879" + }, + { + "examine": "A barricade made of skulls and bones.", + "ids": "6880" + }, + { + "examine": "A barricade made of skulls and bones which has been crushed.", + "ids": "6881,6882" + }, + { + "examine": "An old crude tomb.", + "ids": "6883,6884,6885,6886,6887" + }, + { + "examine": "A sick, frail old man.", + "ids": "6888" + }, + { + "examine": "A sick, frail old man", + "ids": "6889" + }, + { + "examine": "Looking good!", + "ids": "689" + }, + { + "examine": "An old crude tomb.", + "ids": "6890,6891,6892" + }, + { + "examine": "I don't think he'd mind us checking for his wallet now...", + "ids": "6893" + }, + { + "examine": "A good source of books!", + "ids": "6894,6895" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "6896" + }, + { + "examine": "A strange ogre plinth, this must be where the artifacts are stored.", + "ids": "6897,6898,6899,6900,6901,6902" + }, + { + "examine": "Handy for boarding boats.", + "ids": "69,70" + }, + { + "examine": "A privacy aid!", + "ids": "690" + }, + { + "examine": "It looks like the hole in the wall has been blocked with rubble.", + "ids": "6903" + }, + { + "examine": "How exciting, some shelves.", + "ids": "6904" + }, + { + "examine": "A hole in the wall.", + "ids": "6905,6906,6907,6908" + }, + { + "examine": "A rock wall.", + "ids": "6909" + }, + { + "examine": "Use this to get changed behind and retain modesty.", + "ids": "691" + }, + { + "examine": "It has a letter 'S' on the lock.", + "ids": "6910" + }, + { + "examine": "Used for storage.", + "ids": "6911" + }, + { + "examine": "A narrow hole in the wall.", + "ids": "6912,6913,6914" + }, + { + "examine": "Rubble is blocking the passage.", + "ids": "6915" + }, + { + "examine": "A good source of books!", + "ids": "6916,6917,6918" + }, + { + "examine": "A heavy portal decorated with bone.", + "ids": "6919,6920" + }, + { + "examine": "I don't even want to think about what's cooking in that.", + "ids": "692" + }, + { + "examine": "A symbol is carved into the wall here.", + "ids": "6921,6922,6923,6924,6925,6926" + }, + { + "examine": "I don't think I can get through this way!", + "ids": "6927" + }, + { + "examine": "Looks like its no longer operational.", + "ids": "6928" + }, + { + "examine": "Big bones are being used to prop up the wall.", + "ids": "6929,6930" + }, + { + "examine": "Good for sweeping.", + "ids": "693" + }, + { + "examine": "It's a bit like walking through a giant rib cage.", + "ids": "6931,6932,6933,6934,6935,6936,6937,6938" + }, + { + "examine": "This arch is broken. I hope the ceiling doesn't come down!", + "ids": "6939,6940,6941,6942" + }, + { + "examine": "I'm guessing it's for making women's clothes.", + "ids": "694" + }, + { + "examine": "A rocky outcrop.", + "ids": "6943,6944,6945,6946,6947,6948,6949" + }, + { + "examine": "Helps make human clothing.", + "ids": "695" + }, + { + "examine": "I dont think i can get through this way.", + "ids": "6950" + }, + { + "examine": "An eye-wrenching nexus of utter negation!", + "ids": "6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968" + }, + { + "examine": "A hole.", + "ids": "696" + }, + { + "examine": "A dirty little swamp boat.", + "ids": "6969,6970" + }, + { + "examine": "Dead animal head. Lovely.", + "ids": "697,736,29344" + }, + { + "examine": "It looks dark down there.", + "ids": "6971" + }, + { + "examine": "A book sits on top.", + "ids": "6972,6973,6974" + }, + { + "examine": "The door is closed.", + "ids": "6975" + }, + { + "examine": "The door is open.", + "ids": "6976" + }, + { + "examine": "The door is closed.", + "ids": "6977" + }, + { + "examine": "The door is open.", + "ids": "6978,6979,6980,6981,6982,6983" + }, + { + "examine": "Must have been laid by a huge bird.", + "ids": "698" + }, + { + "examine": "Empty market stall.", + "ids": "6984" + }, + { + "examine": "A steam powered crushing machine.", + "ids": "6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001" + }, + { + "examine": "Whatever it was I'm glad it's not alive.", + "ids": "699" + }, + { + "examine": "The cannon is built on here.", + "ids": "7" + }, + { + "examine": "Spooky!", + "ids": "700,701,2614,4048,4049,4050,29345" + }, + { + "examine": "A dwarven statue crumbling away from old age.", + "ids": "7002" + }, + { + "examine": "It's crumbling away from old age, it's hardly recognizable as a dwarf.", + "ids": "7003" + }, + { + "examine": "This stone dwarf must be guarding the way into a dwarven area!", + "ids": "7004,7005" + }, + { + "examine": "Big. For a dwarf!", + "ids": "7006,7007" + }, + { + "examine": "A work in progress.", + "ids": "7008,7009" + }, + { + "examine": "A work that has yet to begin.", + "ids": "7010" + }, + { + "examine": "An underground limpwurt plant.", + "ids": "7011,7012" + }, + { + "examine": "Insect eating plant.", + "ids": "7013,7014,7015" + }, + { + "examine": "A stone carved Pillar.", + "ids": "7016,7017" + }, + { + "examine": "Dwarf storage.", + "ids": "7018" + }, + { + "examine": "Used for keeping beer or glasses.", + "ids": "7019,7020,7021" + }, + { + "examine": "A dog's idea of heaven.", + "ids": "702,703,704,705,706,29346" + }, + { + "examine": "Tracks for the carts to run over.", + "ids": "7022,7023,7024,7025,7026" + }, + { + "examine": "A steam powered cart.", + "ids": "7027,7028,7029,7030,7031" + }, + { + "examine": "A fine piece of sculpting.", + "ids": "7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043" + }, + { + "examine": "Keeps mine carts from rolling away.", + "ids": "7044,7045,7046,7047,7048" + }, + { + "examine": "A wooden gate.", + "ids": "7049,7050,7051,7052" + }, + { + "examine": "Lots of seeds here.", + "ids": "7053,7054,7055" + }, + { + "examine": "I can climb down these stairs.", + "ids": "7056" + }, + { + "examine": "I can climb up these stairs.", + "ids": "7057" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089" + }, + { + "examine": "Ding-Dong!", + "ids": "707" + }, + { + "examine": "Some kind of pulley system.", + "ids": "708" + }, + { + "examine": "Surprisingly rope-shaped.", + "ids": "709" + }, + { + "examine": "'You are here.'", + "ids": "7090" + }, + { + "examine": "Lots of hard study has been done here.", + "ids": "7091" + }, + { + "examine": "A telescope pointing southwards...", + "ids": "7092,7093,7094,7095" + }, + { + "examine": "A map of some ancient land.", + "ids": "7096" + }, + { + "examine": "There are plenty of shelves", + "ids": "7097" + }, + { + "examine": "Maybe it shows the location of buried treasure?", + "ids": "7098" + }, + { + "examine": "Old songs, old stories...", + "ids": "7099" + }, + { + "examine": "Sturdy looking door.", + "ids": "71,72" + }, + { + "examine": "Suspiciously hole-shaped.", + "ids": "710" + }, + { + "examine": "Armour of a Saradominist warrior. Decorative, but still effective.", + "ids": "7100" + }, + { + "examine": "A cape from Saradomin, suitable for a battle-mage.", + "ids": "7101" + }, + { + "examine": "A staff as used by Saradominist magi.", + "ids": "7102" + }, + { + "examine": "There is a powerful presence about these ruins...", + "ids": "7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128" + }, + { + "examine": "A huge chunk of shining natural crystal.", + "ids": "711,712,713" + }, + { + "examine": "A tear in the dimensional weave of the Abyss.", + "ids": "7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153" + }, + { + "examine": "A recently extinguished fire.", + "ids": "714,715,716,717" + }, + { + "examine": "A tunnel through the abyss.", + "ids": "7154,7155" + }, + { + "examine": "This seems to be blocking the exit...", + "ids": "7156,7157" + }, + { + "examine": "I could probably break this up with a pickaxe.", + "ids": "7158" + }, + { + "examine": "I could probably break this up with a pickaxe. Oh wait, I just did.", + "ids": "7159" + }, + { + "examine": "Pickaxe power!", + "ids": "7160" + }, + { + "examine": "They don't look that solid, an axe could help me chop them down.", + "ids": "7161,7162" + }, + { + "examine": "I cannot tell a lie. I chopped them down.", + "ids": "7163" + }, + { + "examine": "If I'm agile enough I might be able to squeeze through...", + "ids": "7164" + }, + { + "examine": "I could probably burn this away with a tinderbox.", + "ids": "7165" + }, + { + "examine": "I could probably burn this with fire.", + "ids": "7166" + }, + { + "examine": "Burnt open.", + "ids": "7167" + }, + { + "examine": "I could probably distract these with thievery.", + "ids": "7168,7169,7170" + }, + { + "examine": "An unstable portal across the dimensions...", + "ids": "7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188" + }, + { + "examine": "A barrel full of swords...", + "ids": "718,719,720,721,722" + }, + { + "examine": "Abyssal Tendrils.", + "ids": "7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205" + }, + { + "examine": "An opening into the crumbling wall.", + "ids": "7219,7220" + }, + { + "examine": "This leads downwards.", + "ids": "7221" + }, + { + "examine": "This way to the viewing gallery.", + "ids": "7222,7223" + }, + { + "examine": "I'll never be able to dodge that!", + "ids": "7224" + }, + { + "examine": "It's a wall...", + "ids": "7225,7226" + }, + { + "examine": "It's the floor...", + "ids": "7227" + }, + { + "examine": "It's a wall...", + "ids": "7228,7229" + }, + { + "examine": "I'm glad this isn't around anymore!", + "ids": "723" + }, + { + "examine": "It's the floor...", + "ids": "7230" + }, + { + "examine": "Not your average door...", + "ids": "7231,7232,7233,7234,7235" + }, + { + "examine": "I wonder what's inside.", + "ids": "7236,7237,7238" + }, + { + "examine": "It's a long way down...", + "ids": "7239,7240" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "724,725,726,25200" + }, + { + "examine": "That's going to hurt if it hits me!", + "ids": "7241" + }, + { + "examine": "If only I knew Karate...", + "ids": "7242,7243,7244" + }, + { + "examine": "It's the floor...", + "ids": "7245" + }, + { + "examine": "Locked.", + "ids": "7246,7247" + }, + { + "examine": "It's a wall...", + "ids": "7248,7249" + }, + { + "examine": "It's the floor...", + "ids": "7250" + }, + { + "examine": "Bend your way through.", + "ids": "7251" + }, + { + "examine": "That could really hurt!", + "ids": "7252" + }, + { + "examine": "I must not fear, fear is the little death that brings total oblivion.", + "ids": "7253" + }, + { + "examine": "Blocking my way back.", + "ids": "7254,7255,7256" + }, + { + "examine": "I wonder where it leads.", + "ids": "7257" + }, + { + "examine": "An opening into the crumbling wall.", + "ids": "7258" + }, + { + "examine": "This way to exit.", + "ids": "7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271" + }, + { + "examine": "A fissure in the cave wall.", + "ids": "727,728,729,730,731,732" + }, + { + "examine": "A mystical teleport.", + "ids": "7272,7273" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7274,7275,7276" + }, + { + "examine": "He looks hungry, but I don't think he'll do anything while I'm here.", + "ids": "7277" + }, + { + "examine": "He's no longer looks hungry, although perhaps a little guilty-looking.", + "ids": "7278,7279,7280" + }, + { + "examine": "He's looking at the grain...", + "ids": "7281,7282,7283" + }, + { + "examine": "A sack full of grain.", + "ids": "7284" + }, + { + "examine": "I think the chicken enjoyed his meal...", + "ids": "7285" + }, + { + "examine": "It looks pretty rickety...", + "ids": "7286,7287" + }, + { + "examine": "A mystical teleport.", + "ids": "7288,7289,7290,7291,7292,7293,7294,7295,7296,7297,7298,7299,7300,7301" + }, + { + "examine": "Securely fastened shut.", + "ids": "73,74" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7302" + }, + { + "examine": "A gold statue of a famous White Knight.", + "ids": "7303" + }, + { + "examine": "A silver statue of a famous White Knight.", + "ids": "7304" + }, + { + "examine": "A bronze statue of a famous White Knight.", + "ids": "7305" + }, + { + "examine": "A gold statue of an ancient warrior.", + "ids": "7306" + }, + { + "examine": "A silver statue of an ancient warrior.", + "ids": "7307" + }, + { + "examine": "A bronze statue of an ancient warrior.", + "ids": "7308" + }, + { + "examine": "A gold statue of a famous warrior.", + "ids": "7309" + }, + { + "examine": "A silver statue of a famous warrior.", + "ids": "7310" + }, + { + "examine": "A bronze statue of a famous warrior.", + "ids": "7311" + }, + { + "examine": "A gold statue of an ancient White Knight.", + "ids": "7312" + }, + { + "examine": "A silver statue of an ancient White Knight.", + "ids": "7313" + }, + { + "examine": "A bronze statue of an ancient White Knight.", + "ids": "7314" + }, + { + "examine": "A mystical teleport.", + "ids": "7315,7316" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7317" + }, + { + "examine": "A mystical teleport.", + "ids": "7318,7319" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7320" + }, + { + "examine": "A mystical teleport.", + "ids": "7321,7322" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7323" + }, + { + "examine": "A mystical teleport.", + "ids": "7324,7325" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7326" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "7327,7328,7329,7330" + }, + { + "examine": "This huge web blocks your path.", + "ids": "733" + }, + { + "examine": "Generally used for putting things on.", + "ids": "7331" + }, + { + "examine": "A table with a Bunsen burner on it.", + "ids": "7332" + }, + { + "examine": "There are some containers of chemicals here.", + "ids": "7333,7334,7335,7336,7337,7338,7339" + }, + { + "examine": "A huge web, cruelly slashed in half.", + "ids": "734" + }, + { + "examine": "There's an empty vial here.", + "ids": "7340,7341,7342" + }, + { + "examine": "There's a small hole in the centre.", + "ids": "7343" + }, + { + "examine": "The spade is stuck in the hole.", + "ids": "7344" + }, + { + "examine": "The spade opened the door.", + "ids": "7345" + }, + { + "examine": "It's chained to the wall.", + "ids": "7346" + }, + { + "examine": "For storage.", + "ids": "7347,7348,7349" + }, + { + "examine": "The noxious liquid bubbles horribly.", + "ids": "735" + }, + { + "examine": "I wonder what's inside.", + "ids": "7350" + }, + { + "examine": "Perhaps I should search it.", + "ids": "7351" + }, + { + "examine": "A mystical teleport.", + "ids": "7352,7353" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7354" + }, + { + "examine": "Bridge will support a person carrying no more than 5 kg.", + "ids": "7355,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372" + }, + { + "examine": "Whatever it was I'm glad it's not alive.", + "ids": "737,738,739,740" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384" + }, + { + "examine": "Sit back and relax...", + "ids": "7388,7389" + }, + { + "examine": "Designed specifically to ruin your health.", + "ids": "7390" + }, + { + "examine": "A rolled up magic carpet.", + "ids": "7391" + }, + { + "examine": "A pile of rolled up magic carpets.", + "ids": "7392" + }, + { + "examine": "A little shaded area.", + "ids": "7393" + }, + { + "examine": "A magic carpet.", + "ids": "7394,7395" + }, + { + "examine": "The infamous carpet of '76.", + "ids": "7396" + }, + { + "examine": "A leafy tree.", + "ids": "7397,7398" + }, + { + "examine": "This is what is left of a willow tree.", + "ids": "7399" + }, + { + "examine": "This is what is left of a maple tree.", + "ids": "7400" + }, + { + "examine": "This is what is left of a magic tree.", + "ids": "7401" + }, + { + "examine": "This is what is left of a yew tree.", + "ids": "7402" + }, + { + "examine": "An empty barrel.", + "ids": "7403" + }, + { + "examine": "A barrel full of mushed apples.", + "ids": "7404,7405" + }, + { + "examine": "This tap runs from the apple crushing barrel.", + "ids": "7406" + }, + { + "examine": "An empty ale barrel.", + "ids": "7407" + }, + { + "examine": "A barrel of bad ale.", + "ids": "7408" + }, + { + "examine": "A barrel of unfermented liquid.", + "ids": "7409" + }, + { + "examine": "Looks a little too broken to climb.", + "ids": "741,742" + }, + { + "examine": "A barrel of bad cider.", + "ids": "7410" + }, + { + "examine": "A barrel of Dwarven Stout.", + "ids": "7411" + }, + { + "examine": "A barrel of mature Dwarven Stout.", + "ids": "7412" + }, + { + "examine": "A barrel of Asgarnian Ale.", + "ids": "7413" + }, + { + "examine": "A barrel of mature Asgarnian Ale.", + "ids": "7414" + }, + { + "examine": "A barrel of Greenmans Ale.", + "ids": "7415" + }, + { + "examine": "A barrel of mature Greenmans Ale.", + "ids": "7416" + }, + { + "examine": "A barrel of Wizards Mind Bomb.", + "ids": "7417" + }, + { + "examine": "A barrel of mature Wizards Mind Bomb.", + "ids": "7418" + }, + { + "examine": "A barrel of Dragon Bitter.", + "ids": "7419" + }, + { + "examine": "A barrel of mature Dragon Bitter.", + "ids": "7420" + }, + { + "examine": "A barrel of Moonlight Mead.", + "ids": "7421" + }, + { + "examine": "A barrel of mature Moonlight Mead.", + "ids": "7422" + }, + { + "examine": "A barrel of Axeman's Folly.", + "ids": "7423" + }, + { + "examine": "A barrel of mature Axeman's Folly.", + "ids": "7424" + }, + { + "examine": "A barrel of Chef's Delight.", + "ids": "7425" + }, + { + "examine": "A barrel of mature Chef's Delight.", + "ids": "7426" + }, + { + "examine": "A barrel of Slayer's Respite.", + "ids": "7427" + }, + { + "examine": "A barrel of mature Slayer's Respite.", + "ids": "7428" + }, + { + "examine": "A barrel of Cider.", + "ids": "7429" + }, + { + "examine": "An old-looking ladder.", + "ids": "743" + }, + { + "examine": "A barrel of mature Cider.", + "ids": "7430,7431,7432" + }, + { + "examine": "Goes up and down!", + "ids": "7433" + }, + { + "examine": "I wonder what's under it?", + "ids": "7434" + }, + { + "examine": "I wonder what's down there?", + "ids": "7435" + }, + { + "examine": "A wooden barrel.", + "ids": "7436" + }, + { + "examine": "This vat is empty.", + "ids": "7437" + }, + { + "examine": "This vat is filled with water.", + "ids": "7438" + }, + { + "examine": "This vat is filled with bad ale.", + "ids": "7439" + }, + { + "examine": "An old-looking bit of scaffolding.", + "ids": "744,745,746,747" + }, + { + "examine": "This vat is filled with bad cider.", + "ids": "7440" + }, + { + "examine": "This vat contains a mixture of water and barley malt.", + "ids": "7441" + }, + { + "examine": "This controls the flow of ale to the barrel.", + "ids": "7442,7443" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Hammerstone hops.", + "ids": "7444" + }, + { + "examine": "Dwarven Stout is fermenting in this vat.", + "ids": "7445,7446" + }, + { + "examine": "This vat is filled with Dwarven Stout.", + "ids": "7447" + }, + { + "examine": "This vat is filled with mature Dwarven Stout.", + "ids": "7448" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Asgarnian hops.", + "ids": "7449" + }, + { + "examine": "Asgarnian Ale is fermenting in this vat.", + "ids": "7450,7451" + }, + { + "examine": "This vat is filled with Asgarnian Ale.", + "ids": "7452" + }, + { + "examine": "This vat is filled with mature Asgarnian Ale.", + "ids": "7453" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Harralander.", + "ids": "7454" + }, + { + "examine": "Greenmans Ale is fermenting in this vat.", + "ids": "7455,7456" + }, + { + "examine": "This vat is filled with Greenmans Ale.", + "ids": "7457" + }, + { + "examine": "This vat is filled with mature Greenmans Ale.", + "ids": "7458" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Yanillian hops.", + "ids": "7459" + }, + { + "examine": "Wizards Mind Bomb is fermenting in this vat.", + "ids": "7460,7461" + }, + { + "examine": "This vat is filled with Wizards Mind Bomb.", + "ids": "7462" + }, + { + "examine": "This vat is filled with mature Wizards Mind Bomb.", + "ids": "7463" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Krandorian hops.", + "ids": "7464" + }, + { + "examine": "Dragon Bitter is fermenting in this vat.", + "ids": "7465,7466" + }, + { + "examine": "This vat is filled with Dragon Bitter.", + "ids": "7467" + }, + { + "examine": "This vat is filled with mature Dragon Bitter.", + "ids": "7468" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Bittercap mushrooms.", + "ids": "7469" + }, + { + "examine": "Moonlight Mead is fermenting in this vat.", + "ids": "7470,7471" + }, + { + "examine": "This vat is filled with Moonlight Mead.", + "ids": "7472" + }, + { + "examine": "This vat is filled with mature Moonlight Mead.", + "ids": "7473" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and oak roots.", + "ids": "7474" + }, + { + "examine": "Axeman's Folly is fermenting in this vat.", + "ids": "7475,7476" + }, + { + "examine": "This vat is filled with Axeman's Folly.", + "ids": "7477" + }, + { + "examine": "This vat is filled with mature Axeman's Folly.", + "ids": "7478" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and chocolate dust.", + "ids": "7479" + }, + { + "examine": "The entrance to the cave.", + "ids": "748" + }, + { + "examine": "Chef's Delight is fermenting in this vat.", + "ids": "7480,7481" + }, + { + "examine": "This vat is filled with Chef's Delight.", + "ids": "7482" + }, + { + "examine": "This vat is filled with mature Chef's Delight.", + "ids": "7483" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Wildblood hops.", + "ids": "7484" + }, + { + "examine": "Slayer's Respite is fermenting in this vat.", + "ids": "7485,7486" + }, + { + "examine": "This vat is filled with Slayer's Respite.", + "ids": "7487" + }, + { + "examine": "This vat is filled with mature Slayer's Respite.", + "ids": "7488" + }, + { + "examine": "This vat contains some apple mush.", + "ids": "7489" + }, + { + "examine": "Cider is fermenting in this vat.", + "ids": "7490,7491" + }, + { + "examine": "This vat is filled with cider.", + "ids": "7492" + }, + { + "examine": "This vat is filled with mature cider.", + "ids": "7493,7494,7495" + }, + { + "examine": "Items are for sale here.", + "ids": "7496,7497" + }, + { + "examine": "They're empty.", + "ids": "7498" + }, + { + "examine": "Farming stock is kept here.", + "ids": "7499,7500,7501,7502,7503" + }, + { + "examine": "I wonder what's inside?", + "ids": "75" + }, + { + "examine": "For sitting.", + "ids": "7504,7505" + }, + { + "examine": "They're empty.", + "ids": "7506" + }, + { + "examine": "Farming stock is kept here.", + "ids": "7507,7508,7509,7510,7511" + }, + { + "examine": "A pair of sacks.", + "ids": "7512" + }, + { + "examine": "For storage.", + "ids": "7513,7514,7515" + }, + { + "examine": "A farmer's spade and rake.", + "ids": "7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526" + }, + { + "examine": "I can climb over the fence with this.", + "ids": "7527" + }, + { + "examine": "For fermenting beer.", + "ids": "7528,7529,7530" + }, + { + "examine": "An ale barrel.", + "ids": "7531" + }, + { + "examine": "This controls the flow of ale to the barrel.", + "ids": "7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556" + }, + { + "examine": "You can grow Deadly Nightshade in this Farming patch.", + "ids": "7557,7558,7559,7560" + }, + { + "examine": "Deadly Nightshade has been sown in this farming patch.", + "ids": "7561" + }, + { + "examine": "Deadly Nightshade is growing in this farming patch.", + "ids": "7562,7563,7564" + }, + { + "examine": "I wouldn't pick this with my bare hands.", + "ids": "7565" + }, + { + "examine": "This Deadly Nightshade has become diseased.", + "ids": "7566,7567,7568" + }, + { + "examine": "This Deadly Nightshade has died.", + "ids": "7569,7570,7571,7572" + }, + { + "examine": "You can grow bushes in this Farming patch.", + "ids": "7573,7574,7575,7576,7577,7578,7579,7580" + }, + { + "examine": "A cadavaberry bush is growing in this Farming patch.", + "ids": "7581,7582,7583,7584,7585,7586" + }, + { + "examine": "A fully grown cadavaberry bush.", + "ids": "7587,7588,7589,7590,7591,7592" + }, + { + "examine": "This diseased cadavaberry bush needs pruning.", + "ids": "7593,7594,7595,7596,7597,7598" + }, + { + "examine": "This cadavaberry bush has died.", + "ids": "7599,7600,7601,7602,7603,7604" + }, + { + "examine": "It's open.", + "ids": "76" + }, + { + "examine": "A dwellberry bush is growing in this Farming patch.", + "ids": "7605,7606,7607,7608,7609,7610,7611" + }, + { + "examine": "A fully grown dwellberry bush.", + "ids": "7612,7613,7614,7615,7616,7617" + }, + { + "examine": "This diseased dwellberry bush needs pruning.", + "ids": "7618,7619,7620,7621,7622,7623,7624" + }, + { + "examine": "This dwellberry bush has died.", + "ids": "7625,7626,7627,7628,7629,7630,7631" + }, + { + "examine": "A jangerberry bush is growing in this Farming patch.", + "ids": "7632,7633,7634,7635,7636,7637,7638,7639" + }, + { + "examine": "A fully grown jangerberry bush.", + "ids": "7640,7641,7642,7643,7644,7645" + }, + { + "examine": "This diseased jangerberry bush needs pruning.", + "ids": "7646,7647,7648,7649,7650,7651,7652,7653" + }, + { + "examine": "This jangerberry bush has died.", + "ids": "7654,7655,7656,7657,7658,7659,7660,7661" + }, + { + "examine": "A Poison Ivy bush is growing in this Farming patch.", + "ids": "7662,7663,7664,7665,7666,7667,7668,7669" + }, + { + "examine": "A fully grown Poison Ivy bush.", + "ids": "7670,7671,7672,7673,7674,7675" + }, + { + "examine": "This diseased Poison Ivy bush needs pruning.", + "ids": "7676,7677,7678,7679,7680,7681,7682,7683" + }, + { + "examine": "This Poison Ivy bush has died.", + "ids": "7684,7685,7686,7687,7688,7689,7690,7691" + }, + { + "examine": "A redberry bush is growing in this Farming patch.", + "ids": "7692,7693,7694,7695,7696" + }, + { + "examine": "A fully grown redberry bush.", + "ids": "7697,7698,7699,7700,7701,7702" + }, + { + "examine": "Securely fastened shut.", + "ids": "77,78" + }, + { + "examine": "This diseased redberry bush needs pruning.", + "ids": "7703,7704,7705,7706,7707" + }, + { + "examine": "This redberry bush has died.", + "ids": "7708,7709,7710,7711,7712" + }, + { + "examine": "A map icon..", + "ids": "771" + }, + { + "examine": "A whiteberry bush is growing in this Farming patch.", + "ids": "7713,7714,7715,7716,7717,7718,7719,7720" + }, + { + "examine": "A fully grown whiteberry bush.", + "ids": "7721,7722,7723,7724,7725,7726" + }, + { + "examine": "This diseased whiteberry bush needs pruning.", + "ids": "7727,7728,7729,7730,7731,7732,7733,7734" + }, + { + "examine": "This whiteberry bush has died.", + "ids": "7735,7736,7737,7738,7739,7740,7741,7742" + }, + { + "examine": "You can grow a Cactus in this Farming patch.", + "ids": "7743,7744,7745,7746" + }, + { + "examine": "Cactus seeds have been planted in this patch.", + "ids": "7747" + }, + { + "examine": "A cactus is growing in this patch.", + "ids": "7748,7749,7750,7751,7752,7753" + }, + { + "examine": "A fully-grown cactus.", + "ids": "7754,7755,7756,7757,7758" + }, + { + "examine": "This cactus has become diseased.", + "ids": "7759,7760,7761,7762,7763,7764" + }, + { + "examine": "This cactus has died.", + "ids": "7765,7766,7767,7768,7769,7770,7771" + }, + { + "examine": "You can grow a Calquat Tree in this Farming patch.", + "ids": "7772,7773,7774,7775" + }, + { + "examine": "A Calquat tree is growing in this Farming patch.", + "ids": "7776,7777,7778,7779,7780,7781,7782,7783" + }, + { + "examine": "A fully grown Calquat tree stands in this Farming patch.", + "ids": "7784,7785,7786,7787,7788,7789,7790,7791" + }, + { + "examine": "It's a door made from bamboo.", + "ids": "779" + }, + { + "examine": "This diseased Calquat tree needs pruning.", + "ids": "7792,7793,7794,7795,7796,7797,7798" + }, + { + "examine": "This Calquat tree has died.", + "ids": "7799,7800,7801,7802,7803,7804,7805" + }, + { + "examine": "A Calquat tree stump.", + "ids": "7806,7807" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7808" + }, + { + "examine": "This compost bin contains compostable items.", + "ids": "7809" + }, + { + "examine": "This compost bin is full of compostable items.", + "ids": "7810" + }, + { + "examine": "This compost bin contains supercompostable items.", + "ids": "7811" + }, + { + "examine": "This compost bin is full of supercompostable items.", + "ids": "7812" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7813" + }, + { + "examine": "This compost bin contains compost.", + "ids": "7814" + }, + { + "examine": "This compost bin is full of compost.", + "ids": "7815" + }, + { + "examine": "This compost bin contains super compost.", + "ids": "7816" + }, + { + "examine": "This compost bin is full of super compost.", + "ids": "7817" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7818" + }, + { + "examine": "This compost bin contains compostable items.", + "ids": "7819" + }, + { + "examine": "This compost bin is full of compostable items.", + "ids": "7820" + }, + { + "examine": "This compost bin contains supercompostable items.", + "ids": "7821" + }, + { + "examine": "This compost bin is full of supercompostable items.", + "ids": "7822" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7823" + }, + { + "examine": "This compost bin contains compost.", + "ids": "7824" + }, + { + "examine": "This compost bin is full of compost.", + "ids": "7825" + }, + { + "examine": "This compost bin contains super compost.", + "ids": "7826" + }, + { + "examine": "This compost bin is full of super compost.", + "ids": "7827" + }, + { + "examine": "This compost bin contains tomatoes.", + "ids": "7828" + }, + { + "examine": "This compost bin is full of tomatoes.", + "ids": "7829" + }, + { + "examine": "This compost bin contains rotten tomatoes.", + "ids": "7830" + }, + { + "examine": "This compost bin is full of rotten tomatoes.", + "ids": "7831" + }, + { + "examine": "This compost bin contains tomatoes.", + "ids": "7832" + }, + { + "examine": "This compost bin is full of tomatoes.", + "ids": "7833" + }, + { + "examine": "This compost bin contains rotten tomatoes.", + "ids": "7834" + }, + { + "examine": "This compost bin is full of rotten tomatoes.", + "ids": "7835,7836,7837,7838,7839" + }, + { + "examine": "You can grow flowers in this Farming patch.", + "ids": "7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850" + }, + { + "examine": "A limpwurt plant is growing in this patch.", + "ids": "7851,7852,7853,7854" + }, + { + "examine": "A fully grown limpwurt plant.", + "ids": "7855" + }, + { + "examine": "A limpwurt plant is growing in this patch.", + "ids": "7856,7857,7858,7859" + }, + { + "examine": "This limpwurt plant has become diseased.", + "ids": "7860,7861,7862" + }, + { + "examine": "This limpwurt plant has died while growing.", + "ids": "7863,7864,7865" + }, + { + "examine": "This limpwurt plant has died.", + "ids": "7866" + }, + { + "examine": "A marigold is growing in this patch.", + "ids": "7867,7868,7869,7870" + }, + { + "examine": "A loom.", + "ids": "787" + }, + { + "examine": "A fully grown marigold.", + "ids": "7871" + }, + { + "examine": "A marigold is growing in this patch.", + "ids": "7872,7873,7874,7875" + }, + { + "examine": "This marigold has become diseased.", + "ids": "7876,7877,7878" + }, + { + "examine": "This marigold has died while growing.", + "ids": "7879,7880,7881" + }, + { + "examine": "You'd need a big siege engine to force that.", + "ids": "788,789" + }, + { + "examine": "This marigold has died.", + "ids": "7882" + }, + { + "examine": "A nasturtium is growing in this patch.", + "ids": "7883,7884,7885,7886" + }, + { + "examine": "A fully grown nasturtium.", + "ids": "7887" + }, + { + "examine": "A nasturtium is growing in this patch.", + "ids": "7888,7889,7890,7891" + }, + { + "examine": "This nasturtium has become diseased.", + "ids": "7892,7893,7894" + }, + { + "examine": "This nasturtium has died while growing.", + "ids": "7895,7896,7897" + }, + { + "examine": "This nasturtium has died.", + "ids": "7898" + }, + { + "examine": "A rosemary is growing in this patch.", + "ids": "7899,7900,7901,7902" + }, + { + "examine": "Looks secure.", + "ids": "79,80" + }, + { + "examine": "A fully grown rosemary.", + "ids": "7903" + }, + { + "examine": "A rosemary is growing in this patch.", + "ids": "7904,7905,7906,7907" + }, + { + "examine": "This rosemary has become diseased.", + "ids": "7908,7909,7910" + }, + { + "examine": "This rosemary has died while growing.", + "ids": "7911,7912,7913" + }, + { + "examine": "This rosemary has died.", + "ids": "7914" + }, + { + "examine": "Should scare off the birds...", + "ids": "7915,7916,7917,7918" + }, + { + "examine": "A woad plant is growing in this patch.", + "ids": "7919,7920,7921,7922" + }, + { + "examine": "A fully grown woad plant.", + "ids": "7923" + }, + { + "examine": "A woad plant is growing in this patch.", + "ids": "7924,7925,7926,7927" + }, + { + "examine": "This woad plant has become diseased.", + "ids": "7928,7929,7930" + }, + { + "examine": "This woad plant has died while growing.", + "ids": "7931,7932,7933" + }, + { + "examine": "This woad plant has died.", + "ids": "7934" + }, + { + "examine": "An apple tree sapling has been planted in this fruit tree patch.", + "ids": "7935" + }, + { + "examine": "An apple tree is growing in this fruit tree patch.", + "ids": "7936,7937,7938,7939,7940" + }, + { + "examine": "A fully grown apple tree.", + "ids": "7941" + }, + { + "examine": "There is a single apple on this apple tree.", + "ids": "7942" + }, + { + "examine": "There are two apples on this apple tree.", + "ids": "7943" + }, + { + "examine": "There are three apples on this apple tree.", + "ids": "7944" + }, + { + "examine": "There are four apples on this apple tree.", + "ids": "7945" + }, + { + "examine": "There are five apples on this apple tree.", + "ids": "7946" + }, + { + "examine": "There are six apples on this apple tree.", + "ids": "7947" + }, + { + "examine": "A fully grown apple tree.", + "ids": "7948" + }, + { + "examine": "This diseased tree looks like it needs pruning with secateurs.", + "ids": "7949,7950,7951,7952,7953,7954" + }, + { + "examine": "This apple tree has become diseased and died.", + "ids": "7955,7956,7957,7958,7959,7960" + }, + { + "examine": "This apple tree has been cut down.", + "ids": "7961,7962,7963,7964,7965" + }, + { + "examine": "A pineapple plant has been planted in this fruit tree patch.", + "ids": "7966" + }, + { + "examine": "A pineapple plant is growing in this fruit tree patch.", + "ids": "7967,7968,7969,7970,7971" + }, + { + "examine": "A fully grown pineapple plant.", + "ids": "7972" + }, + { + "examine": "There is a single pineapple on this pineapple plant.", + "ids": "7973" + }, + { + "examine": "There are two pineapples on this pineapple plant.", + "ids": "7974" + }, + { + "examine": "There are three pineapples on this pineapple plant.", + "ids": "7975" + }, + { + "examine": "There are four pineapples on this pineapple plant.", + "ids": "7976" + }, + { + "examine": "There are five pineapples on this pineapple plant.", + "ids": "7977" + }, + { + "examine": "There are six pineapples on this pineapple plant.", + "ids": "7978" + }, + { + "examine": "A fully grown pineapple plant.", + "ids": "7979" + }, + { + "examine": "This pineapple plant looks like it could do with pruning with secateurs.", + "ids": "7980,7981,7982,7983,7984,7985" + }, + { + "examine": "This pineapple plant has become diseased and died.", + "ids": "7986,7987,7988,7989,7990,7991" + }, + { + "examine": "This pineapple plant has been cut down.", + "ids": "7992" + }, + { + "examine": "A banana tree sapling has been planted in this fruit tree patch.", + "ids": "7993" + }, + { + "examine": "A banana tree is growing in this fruit tree patch.", + "ids": "7994,7995,7996,7997,7998" + }, + { + "examine": "A fully grown banana tree.", + "ids": "7999,8000" + }, + { + "examine": "The mounting for the multicannon.", + "ids": "8" + }, + { + "examine": "There is a single banana on this banana tree.", + "ids": "8001" + }, + { + "examine": "There are two bananas on this banana tree.", + "ids": "8002" + }, + { + "examine": "There are three bananas on this banana tree.", + "ids": "8003" + }, + { + "examine": "There are four bananas on this banana tree.", + "ids": "8004" + }, + { + "examine": "There are five bananas on this banana tree.", + "ids": "8005" + }, + { + "examine": "There are six bananas on this banana tree.", + "ids": "8006" + }, + { + "examine": "This banana looks like it could do with pruning with secateurs.", + "ids": "8007,8008,8009,8010,8011,8012" + }, + { + "examine": "This banana tree has become diseased and died.", + "ids": "8013,8014,8015,8016,8017,8018" + }, + { + "examine": "This banana tree has been cut down.", + "ids": "8019" + }, + { + "examine": "A curry tree sapling has been planted in this fruit tree patch.", + "ids": "8020" + }, + { + "examine": "A curry tree is growing in this fruit tree patch.", + "ids": "8021,8022,8023,8024,8025" + }, + { + "examine": "A fully grown curry tree.", + "ids": "8026" + }, + { + "examine": "There is a single curry leaf on this curry tree.", + "ids": "8027" + }, + { + "examine": "There are two curry leaves on this curry tree.", + "ids": "8028" + }, + { + "examine": "There are three curry leaves on this curry tree.", + "ids": "8029" + }, + { + "examine": "There are four curry leaves on this curry tree.", + "ids": "8030" + }, + { + "examine": "There are five curry leaves on this curry tree.", + "ids": "8031" + }, + { + "examine": "There are six curry leaves on this curry tree.", + "ids": "8032" + }, + { + "examine": "A fully grown curry tree.", + "ids": "8033" + }, + { + "examine": "This curry tree looks like it could do with pruning with secateurs.", + "ids": "8034,8035,8036,8037,8038,8039" + }, + { + "examine": "This curry tree has become diseased and died.", + "ids": "8040,8041,8042,8043,8044,8045" + }, + { + "examine": "This curry tree has been cut down.", + "ids": "8046" + }, + { + "examine": "You can grow Fruit Trees in this Farming patch.", + "ids": "8047,8048,8049,8050" + }, + { + "examine": "An orange tree sapling has been planted in this fruit tree patch.", + "ids": "8051" + }, + { + "examine": "An orange tree is growing in this fruit tree patch.", + "ids": "8052,8053,8054,8055,8056" + }, + { + "examine": "A fully grown orange tree.", + "ids": "8057" + }, + { + "examine": "There is a single orange on this orange tree.", + "ids": "8058" + }, + { + "examine": "There are two oranges on this orange tree.", + "ids": "8059" + }, + { + "examine": "There are three oranges on this orange tree.", + "ids": "8060" + }, + { + "examine": "There are four oranges on this orange tree.", + "ids": "8061" + }, + { + "examine": "There are five oranges on this orange tree.", + "ids": "8062" + }, + { + "examine": "There are six oranges on this orange tree.", + "ids": "8063" + }, + { + "examine": "A fully grown orange tree.", + "ids": "8064" + }, + { + "examine": "This orange tree looks like it could do with pruning with secateurs.", + "ids": "8065,8066,8067,8068,8069,8070" + }, + { + "examine": "This orange tree has become diseased and died.", + "ids": "8071,8072,8073,8074,8075,8076" + }, + { + "examine": "This orange tree has been cut down.", + "ids": "8077" + }, + { + "examine": "A palm tree sapling has been planted in this fruit tree patch.", + "ids": "8078" + }, + { + "examine": "A palm tree is growing in this fruit tree patch.", + "ids": "8079,8080,8081,8082,8083" + }, + { + "examine": "A fully grown palm tree.", + "ids": "8084" + }, + { + "examine": "There is a single coconut on this palm tree.", + "ids": "8085" + }, + { + "examine": "There are two coconuts on this palm tree.", + "ids": "8086" + }, + { + "examine": "There are three coconuts on this palm tree.", + "ids": "8087" + }, + { + "examine": "There are four coconuts on this palm tree.", + "ids": "8088" + }, + { + "examine": "There are five coconuts on this palm tree.", + "ids": "8089" + }, + { + "examine": "There are six coconuts on this palm tree.", + "ids": "8090" + }, + { + "examine": "A fully grown palm tree.", + "ids": "8091" + }, + { + "examine": "This palm tree looks like it could do with pruning with secateurs.", + "ids": "8092,8093,8094,8095,8096,8097" + }, + { + "examine": "This palm tree has become diseased and died.", + "ids": "8098,8099,8100,8101,8102,8103" + }, + { + "examine": "The door is closed.", + "ids": "81,82" + }, + { + "examine": "This palm tree has been cut down.", + "ids": "8104" + }, + { + "examine": "A papaya tree sapling has been planted in this fruit tree patch.", + "ids": "8105" + }, + { + "examine": "A papaya tree is growing in this fruit tree patch.", + "ids": "8106,8107,8108,8109,8110" + }, + { + "examine": "A fully grown papaya tree", + "ids": "8111" + }, + { + "examine": "There is a single papaya fruit on this tree.", + "ids": "8112" + }, + { + "examine": "There are two papaya fruits on this tree.", + "ids": "8113" + }, + { + "examine": "There are three papaya fruits on this tree.", + "ids": "8114" + }, + { + "examine": "There are four papaya fruits on this tree.", + "ids": "8115" + }, + { + "examine": "There are five papaya fruits on this tree.", + "ids": "8116" + }, + { + "examine": "There are six papaya fruits on this tree.", + "ids": "8117" + }, + { + "examine": "A fully grown papaya tree.", + "ids": "8118" + }, + { + "examine": "This papaya tree looks like it could do with pruning with secateurs.", + "ids": "8119,8120,8121,8122,8123,8124" + }, + { + "examine": "This papaya tree has become diseased and died.", + "ids": "8125,8126,8127,8128,8129,8130" + }, + { + "examine": "This papaya tree has been cut down.", + "ids": "8131" + }, + { + "examine": "You can grow herbs in this Farming patch.", + "ids": "8132,8133,8134,8135,8136,8137,8138" + }, + { + "examine": "Some herb seeds have been sown in this patch.", + "ids": "8139" + }, + { + "examine": "A herb is growing in this patch.", + "ids": "8140,8141,8142" + }, + { + "examine": "A fully grown herb.", + "ids": "8143" + }, + { + "examine": "These herbs have become diseased.", + "ids": "8144,8145,8146" + }, + { + "examine": "These herbs have become diseased and died.", + "ids": "8147,8148,8149,8150,8151,8152,8153" + }, + { + "examine": "Asgarnian hop seeds have been sown in this farming patch.", + "ids": "8154" + }, + { + "examine": "Asgarnian hops are growing in this farming patch.", + "ids": "8155,8156,8157,8158" + }, + { + "examine": "These are fully grown Asgarnian Hops.", + "ids": "8159" + }, + { + "examine": "Asgarnian hop seeds have been sown in this farming patch.", + "ids": "8160" + }, + { + "examine": "Asgarnian hops are growing in this farming patch.", + "ids": "8161,8162,8163,8164" + }, + { + "examine": "These Asgarnian Hop plants are diseased.", + "ids": "8165,8166,8167,8168" + }, + { + "examine": "These Asgarnian Hop plants have died from disease.", + "ids": "8169,8170,8171,8172,8173,8174,8175,8176" + }, + { + "examine": "I always wonder if someone's hiding inside when I see these.", + "ids": "817" + }, + { + "examine": "Hammerstone Hop seeds have been sown in this farming patch.", + "ids": "8177" + }, + { + "examine": "Hammerstone Hops are growing in this farming patch.", + "ids": "8178,8179,8180" + }, + { + "examine": "Looks kind of like a man made of metal.", + "ids": "818,819,820" + }, + { + "examine": "These are fully grown Hammerstone Hops.", + "ids": "8181" + }, + { + "examine": "Hammerstone Hop seeds have been sown in this farming patch.", + "ids": "8182" + }, + { + "examine": "Hammerstone Hops are growing in this farming patch.", + "ids": "8183,8184,8185" + }, + { + "examine": "These Hammerstone Hops are diseased.", + "ids": "8186,8187,8188" + }, + { + "examine": "These Hammerstone Hops have died from disease.", + "ids": "8189,8190,8191" + }, + { + "examine": "Barley seeds have been sown in this farming patch.", + "ids": "8192" + }, + { + "examine": "Barley is growing in this farming patch.", + "ids": "8193,8194,8195" + }, + { + "examine": "This patch is full of Barley.", + "ids": "8196" + }, + { + "examine": "Barley seeds have been sown in this farming patch.", + "ids": "8197" + }, + { + "examine": "Barley is growing in this farming patch.", + "ids": "8198,8199,8200" + }, + { + "examine": "This Barley is diseased.", + "ids": "8201,8202,8203" + }, + { + "examine": "This Barley has died from disease.", + "ids": "8204,8205,8206" + }, + { + "examine": "You can grow hops in this Farming patch.", + "ids": "8207,8208,8209,8210" + }, + { + "examine": "Not suitable for children. Aim away from face.", + "ids": "821,36780" + }, + { + "examine": "Krandorian Hop seeds have been planted in this farming patch.", + "ids": "8211" + }, + { + "examine": "Krandorian Hops are growing in this farming patch.", + "ids": "8212,8213,8214,8215,8216,8217" + }, + { + "examine": "These are fully grown Krandorian Hops.", + "ids": "8218" + }, + { + "examine": "Krandorian Hop seeds have been planted in this farming patch.", + "ids": "8219" + }, + { + "examine": "Big heavy metal balls.", + "ids": "822,36790" + }, + { + "examine": "Krandorian Hops are growing in this farming patch.", + "ids": "8220,8221,8222,8223,8224,8225" + }, + { + "examine": "These Krandorian Hops are diseased.", + "ids": "8226,8227,8228,8229,8230,8231" + }, + { + "examine": "The easiest opponent I'll ever fight.", + "ids": "823" + }, + { + "examine": "These Krandorian Hops have died from disease.", + "ids": "8232,8233,8234,8235,8236,8237" + }, + { + "examine": "Jute seeds have been sown in this farming patch.", + "ids": "8238" + }, + { + "examine": "Jute plants are growing in this farming patch.", + "ids": "8239,8240,8241,8242" + }, + { + "examine": "A wooden defensive structure.", + "ids": "824,825,826,827,828,36928" + }, + { + "examine": "These are fully grown Jute plants.", + "ids": "8243" + }, + { + "examine": "Jute seeds have been sown in this farming patch.", + "ids": "8244" + }, + { + "examine": "Jute plants are growing in this farming patch.", + "ids": "8245,8246,8247,8248" + }, + { + "examine": "These Jute plants are diseased.", + "ids": "8249,8250,8251,8252" + }, + { + "examine": "These Jute plants have died from disease.", + "ids": "8253,8254,8255,8256" + }, + { + "examine": "Wildblood hop seeds have been planted in this farming patch.", + "ids": "8257" + }, + { + "examine": "Wildblood Hops are growing in this farming patch.", + "ids": "8258,8259,8260,8261,8262,8263,8264" + }, + { + "examine": "These are fully grown Wildblood Hops.", + "ids": "8265" + }, + { + "examine": "Wildblood hop seeds have been planted in this farming patch.", + "ids": "8266" + }, + { + "examine": "Wildblood Hops are growing in this farming patch.", + "ids": "8267,8268,8269,8270,8271,8272,8273" + }, + { + "examine": "These Wildblood hops are diseased.", + "ids": "8274,8275,8276,8277,8278,8279,8280" + }, + { + "examine": "These Wildblood Hops have died from disease.", + "ids": "8281,8282,8283,8284,8285,8286,8287" + }, + { + "examine": "Yanillian Hop seeds have been sown in this farming patch.", + "ids": "8288" + }, + { + "examine": "Yanillian Hops are growing in this farming patch.", + "ids": "8289,8290,8291,8292,8293" + }, + { + "examine": "For private use only!", + "ids": "829,830,831,832,833" + }, + { + "examine": "These are fully grown Yanillian Hops.", + "ids": "8294" + }, + { + "examine": "Yanillian Hop seeds have been sown in this farming patch.", + "ids": "8295" + }, + { + "examine": "Yanillian Hops are growing in this farming patch.", + "ids": "8296,8297,8298,8299,8300" + }, + { + "examine": "These Yanillian Hops are diseased.", + "ids": "8301,8302,8303,8304,8305" + }, + { + "examine": "These Yanillian Hops have died from disease.", + "ids": "8306,8307,8308,8309,8310" + }, + { + "examine": "You can grow Bittercap mushrooms in this Farming patch.", + "ids": "8311,8312,8313,8314" + }, + { + "examine": "Bittercap mushroom spores have been sown in this farming patch.", + "ids": "8315" + }, + { + "examine": "Bittercap mushrooms are growing in this farming patch.", + "ids": "8316,8317,8318,8319,8320" + }, + { + "examine": "A patch of Bittercap Mushrooms.", + "ids": "8321,8322,8323,8324,8325,8326" + }, + { + "examine": "These Bittercap mushrooms have become diseased.", + "ids": "8327,8328,8329,8330,8331" + }, + { + "examine": "These Bittercap mushrooms have become diseased and died.", + "ids": "8332,8333,8334,8335,8336,8337,8338" + }, + { + "examine": "You can grow a Spirit Tree in this Farming patch.", + "ids": "8339,8340,8341,8342" + }, + { + "examine": "Break glass in case of emergency.", + "ids": "834,835" + }, + { + "examine": "A Spirit Tree.", + "ids": "8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356" + }, + { + "examine": "A Spirit Tree stump.", + "ids": "8357" + }, + { + "examine": "Needs pruning before it dies.", + "ids": "8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369" + }, + { + "examine": "An attractively laid out collection of ranging weapons.", + "ids": "836" + }, + { + "examine": "Break glass in case of emergency.", + "ids": "837,838" + }, + { + "examine": "Oh dear, your spirit tree has died.", + "ids": "8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,8390,8391" + }, + { + "examine": "An attractively laid out collection of ranging weapons.", + "ids": "839" + }, + { + "examine": "You can grow trees in this Farming patch.", + "ids": "8392,8393,8394,8395" + }, + { + "examine": "A Magic Tree sapling has been planted in this tree patch.", + "ids": "8396" + }, + { + "examine": "A Magic Tree is growing in this tree patch.", + "ids": "8397,8398,8399,8400,8401,8402,8403,8404,8405,8406,8407" + }, + { + "examine": "A fully grown Magic Tree.", + "ids": "8408,8409" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8410" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,8422" + }, + { + "examine": "This Magic Tree has become diseased and died.", + "ids": "8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434" + }, + { + "examine": "A Maple tree sapling has been planted in this tree patch.", + "ids": "8435" + }, + { + "examine": "A Maple tree is growing in this tree patch.", + "ids": "8436,8437,8438,8439,8440,8441,8442" + }, + { + "examine": "A fully grown Maple tree.", + "ids": "8443,8444" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8445" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8446,8447,8448,8449,8450,8451,8452,8453" + }, + { + "examine": "This Maple tree has become diseased and died.", + "ids": "8454,8455,8456,8457,8458,8459,8460,8461" + }, + { + "examine": "An Oak sapling has been planted in this tree patch.", + "ids": "8462" + }, + { + "examine": "An Oak tree is growing in this tree patch.", + "ids": "8463,8464,8465" + }, + { + "examine": "A fully grown Oak tree.", + "ids": "8466,8467" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8468,8469,8470,8471,8472" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8473,8474,8475,8476" + }, + { + "examine": "This Oak tree has become diseased and died.", + "ids": "8477,8478,8479,8480" + }, + { + "examine": "A row of sharp pointy spears.", + "ids": "848" + }, + { + "examine": "A Willow sapling has been planted in this tree patch.", + "ids": "8481" + }, + { + "examine": "A Willow tree is growing in this tree patch.", + "ids": "8482,8483,8484,8485,8486" + }, + { + "examine": "A fully grown Willow tree.", + "ids": "8487,8488" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8489" + }, + { + "examine": "Rows of sharp pointy spears.", + "ids": "849,850" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8490,8491,8492,8493,8494,8495" + }, + { + "examine": "This Willow tree has become diseased and died.", + "ids": "8496,8497,8498,8499,8500,8501" + }, + { + "examine": "A Yew sapling has been planted in this tree patch.", + "ids": "8502" + }, + { + "examine": "A Yew tree is growing in this tree patch.", + "ids": "8503,8504,8505,8506,8507,8508,8509,8510,8511" + }, + { + "examine": "A tatty old standard.", + "ids": "851,852" + }, + { + "examine": "A fully grown Yew tree.", + "ids": "8512,8513" + }, + { + "examine": "You can uproot this tree stump with a spade.", + "ids": "8514" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8515,8516,8517,8518,8519,8520,8521,8522,8523,8524" + }, + { + "examine": "This Yew tree has become diseased and died.", + "ids": "8525,8526,8527,8528,8529,8530,8531,8532,8533,8534" + }, + { + "examine": "A standard.", + "ids": "853" + }, + { + "examine": "Cabbage seeds have been sown in this allotment.", + "ids": "8535" + }, + { + "examine": "Cabbages are growing in this allotment.", + "ids": "8536,8537,8538" + }, + { + "examine": "These cabbages could do with harvesting.", + "ids": "8539" + }, + { + "examine": "A blue standard.", + "ids": "854,855,856" + }, + { + "examine": "Cabbages are growing in this allotment.", + "ids": "8540,8541,8542,8543" + }, + { + "examine": "These cabbages have become diseased and need tending.", + "ids": "8544,8545,8546" + }, + { + "examine": "These cabbages have become diseased and died.", + "ids": "8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557" + }, + { + "examine": "Potato seeds have been planted in this allotment.", + "ids": "8558" + }, + { + "examine": "Potato plants are growing in this allotment.", + "ids": "8559,8560,8561" + }, + { + "examine": "These potato plants are fully grown.", + "ids": "8562" + }, + { + "examine": "Potato seeds have been planted in this allotment.", + "ids": "8563" + }, + { + "examine": "Potato plants are growing in this allotment.", + "ids": "8564,8565,8566" + }, + { + "examine": "These potato plants are diseased.", + "ids": "8567,8568,8569" + }, + { + "examine": "A standard of the gnome race.", + "ids": "857,858" + }, + { + "examine": "These potato plants are dead.", + "ids": "8570,8571,8572" + }, + { + "examine": "You can grow fruit and vegetables here.", + "ids": "8573,8574,8575,8576,8577,8578,8579" + }, + { + "examine": "Some onion seeds have sown in this allotment.", + "ids": "8580" + }, + { + "examine": "Some onion plants are growing in this allotment.", + "ids": "8581,8582,8583" + }, + { + "examine": "There are some fully grown onions in this allotment.", + "ids": "8584" + }, + { + "examine": "Some onion seeds have sown in this allotment.", + "ids": "8585" + }, + { + "examine": "Some onion plants are growing in this allotment.", + "ids": "8586,8587,8588" + }, + { + "examine": "These onions have become diseased.", + "ids": "8589,8590,8591" + }, + { + "examine": "The standard of the ogre race.", + "ids": "859" + }, + { + "examine": "These onions have become diseased and died.", + "ids": "8592,8593,8594" + }, + { + "examine": "Strawberry seeds have been sown in this allotment.", + "ids": "8595" + }, + { + "examine": "Strawberry plants are growing in this allotment.", + "ids": "8596,8597,8598,8599,8600" + }, + { + "examine": "Seems very old...", + "ids": "86" + }, + { + "examine": "The flag of Asgarnia.", + "ids": "860" + }, + { + "examine": "These strawberry plants are fully grown.", + "ids": "8601" + }, + { + "examine": "Strawberry seeds have been sown in this allotment.", + "ids": "8602" + }, + { + "examine": "Strawberry plants are growing in this allotment.", + "ids": "8603,8604,8605,8606,8607" + }, + { + "examine": "These strawberry plants have become diseased.", + "ids": "8608,8609,8610,8611,8612" + }, + { + "examine": "The flag of Kandarin.", + "ids": "861" + }, + { + "examine": "These strawberry plants have become diseased and died.", + "ids": "8613,8614,8615,8616,8617" + }, + { + "examine": "Some sweetcorn seeds have been sown in this allotment.", + "ids": "8618" + }, + { + "examine": "Some sweetcorn plants are growing in this allotment.", + "ids": "8619,8620,8621,8622,8623" + }, + { + "examine": "The flag of Ardougne.", + "ids": "862" + }, + { + "examine": "These sweetcorn plants are fully grown.", + "ids": "8624" + }, + { + "examine": "Some sweetcorn seeds have been sown in this allotment.", + "ids": "8625" + }, + { + "examine": "Some sweetcorn plants are growing in this allotment.", + "ids": "8626,8627,8628,8629,8630" + }, + { + "examine": "A standard of Asgarnia.", + "ids": "863" + }, + { + "examine": "These sweetcorn plants have been attacked by crows.", + "ids": "8631,8632,8633,8634,8635" + }, + { + "examine": "These sweetcorn plants have become diseased and died.", + "ids": "8636,8637,8638,8639,8640" + }, + { + "examine": "A standard of Kandarin.", + "ids": "864" + }, + { + "examine": "Tomato seeds have been sown in this allotment.", + "ids": "8641" + }, + { + "examine": "Tomato plants are growing in this allotment.", + "ids": "8642,8643,8644" + }, + { + "examine": "These tomato plants are fully grown.", + "ids": "8645" + }, + { + "examine": "Tomato seeds have been sown in this allotment.", + "ids": "8646" + }, + { + "examine": "Tomato plants are growing in this allotment.", + "ids": "8647,8648,8649" + }, + { + "examine": "A standard of Asgarnia.", + "ids": "865" + }, + { + "examine": "These tomato plants have become diseased.", + "ids": "8650,8651,8652" + }, + { + "examine": "These tomato plants have become diseased and died.", + "ids": "8653,8654,8655" + }, + { + "examine": "Watermelon seeds have been sown in this allotment.", + "ids": "8656" + }, + { + "examine": "Watermelons are growing in this allotment.", + "ids": "8657,8658,8659,8660,8661,8662,8663" + }, + { + "examine": "A standard of Kandarin.", + "ids": "866" + }, + { + "examine": "These watermelons could do with harvesting.", + "ids": "8664" + }, + { + "examine": "Watermelon seeds have been sown in this allotment.", + "ids": "8665" + }, + { + "examine": "Watermelons are growing in this allotment.", + "ids": "8666,8667,8668,8669,8670,8671,8672" + }, + { + "examine": "A standard of Misthalin.", + "ids": "867" + }, + { + "examine": "These watermelons have become diseased and need tending.", + "ids": "8673,8674,8675,8676,8677,8678,8679" + }, + { + "examine": "A standard of Varrock.", + "ids": "868" + }, + { + "examine": "These watermelon plants have become diseased and died.", + "ids": "8680" + }, + { + "examine": "These watermelons have become diseased and died.", + "ids": "8681,8682,8683,8684,8685,8686,8687" + }, + { + "examine": "The perfect accompaniment to a bedroom.", + "ids": "8688" + }, + { + "examine": "Fit for milking.", + "ids": "8689" + }, + { + "examine": "A flag flies here.", + "ids": "869" + }, + { + "examine": "Each full of milk no doubt.", + "ids": "8690,8691,8692,8693,8694" + }, + { + "examine": "The door is closed.", + "ids": "8695" + }, + { + "examine": "The door is open.", + "ids": "8696,8697,8698" + }, + { + "examine": "After working with livestock, why not wash your hands?", + "ids": "8699" + }, + { + "examine": "I guess you pull it...", + "ids": "87" + }, + { + "examine": "A sculpted trunk of wood.", + "ids": "870" + }, + { + "examine": "For putting things on.", + "ids": "8700" + }, + { + "examine": "Someone's been preparing meat.", + "ids": "8701" + }, + { + "examine": "A barrel for collecting rain water.", + "ids": "8702,8703,8704,8705,8706,8707,8708,8709,8710,8711" + }, + { + "examine": "Takes my dirty bath water away.", + "ids": "871" + }, + { + "examine": "A grand old fireplace.", + "ids": "8712" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "8713,8714,8715,8716" + }, + { + "examine": "A loom.", + "ids": "8717,8718,8719,8720,8721,8722,8723,8724" + }, + { + "examine": "It smells horrible in there.", + "ids": "872" + }, + { + "examine": "A little rock.", + "ids": "8725" + }, + { + "examine": "A small chunk of rock.", + "ids": "8726" + }, + { + "examine": "They're not floating, even though it may look like they are!", + "ids": "8727" + }, + { + "examine": "A deposit of rocks.", + "ids": "8728,8729,8730,8731,8732,8733,8734,8735,8736" + }, + { + "examine": "Ideal for washing things in.", + "ids": "873,874,4063,36971" + }, + { + "examine": "This tap runs from the apple crushing barrel.", + "ids": "8737" + }, + { + "examine": "You can walk through these doors.", + "ids": "8738,8739,8740,8741" + }, + { + "examine": "An odd looking tree.", + "ids": "8742,8743" + }, + { + "examine": "I can climb this.", + "ids": "8744,8745" + }, + { + "examine": "I can climb down this.", + "ids": "8746" + }, + { + "examine": "A local water source.", + "ids": "8747" + }, + { + "examine": "Used for spinning thread.", + "ids": "8748" + }, + { + "examine": "A Shrine to the glory of Seren.", + "ids": "8749" + }, + { + "examine": "Wash here.", + "ids": "875,876,877" + }, + { + "examine": "I can cook here.", + "ids": "8750" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "8751" + }, + { + "examine": "A good source of books!", + "ids": "8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,8765,8766" + }, + { + "examine": "The lamp has a glowing crystal at its core.", + "ids": "8767" + }, + { + "examine": "A table.", + "ids": "8768,8769" + }, + { + "examine": "A chair.", + "ids": "8770" + }, + { + "examine": "A painting of an elf standing in some woodland.", + "ids": "8771" + }, + { + "examine": "Sit back and relax...", + "ids": "8772" + }, + { + "examine": "A useful ranging device.", + "ids": "8773,8774" + }, + { + "examine": "Use these with bows.", + "ids": "8775" + }, + { + "examine": "Tailor-made for needlework supplies.", + "ids": "8776,8777" + }, + { + "examine": "I'm guessing it's for making elven clothes.", + "ids": "8778" + }, + { + "examine": "Helps make elf clothing.", + "ids": "8779,8780,8781,8782" + }, + { + "examine": "No this is not a mirage!", + "ids": "878" + }, + { + "examine": "I wonder what's under it?", + "ids": "8783,8784" + }, + { + "examine": "I can climb this.", + "ids": "8785" + }, + { + "examine": "The door is closed.", + "ids": "8786,8787,8788,8789" + }, + { + "examine": "Everyone needs a water feature.", + "ids": "879,28682" + }, + { + "examine": "The door is open.", + "ids": "8790,8791,8792,8793,8794" + }, + { + "examine": "Makes gnomes taller.", + "ids": "8795" + }, + { + "examine": "Makes creatures taller.", + "ids": "8796" + }, + { + "examine": "I wonder what's inside.", + "ids": "8797" + }, + { + "examine": "Perhaps I should search it.", + "ids": "8798" + }, + { + "examine": "The desk of the head mourner.", + "ids": "8799" + }, + { + "examine": "A beautiful water feature.", + "ids": "880" + }, + { + "examine": "I wonder what's inside.", + "ids": "8800" + }, + { + "examine": "A sack full of grain.", + "ids": "8801,8802,8803" + }, + { + "examine": "These have grain in them.", + "ids": "8804,8805,8806" + }, + { + "examine": "An empty barrel.", + "ids": "8807" + }, + { + "examine": "A barrel full of mushed apples.", + "ids": "8808" + }, + { + "examine": "A pile of rotten apples!", + "ids": "8809" + }, + { + "examine": "There's a cover over this manhole.", + "ids": "881" + }, + { + "examine": "A wooden gate.", + "ids": "8810,8811,8812,8813" + }, + { + "examine": "A well slept in bed.", + "ids": "8814,8815,8816,8817" + }, + { + "examine": "The door is closed.", + "ids": "8818" + }, + { + "examine": "The door is open.", + "ids": "8819" + }, + { + "examine": "How dangerous, someone has left this manhole open.", + "ids": "882" + }, + { + "examine": "Solid iron bars.", + "ids": "8820,8821,8822,8823,8824,8825,8826,8827" + }, + { + "examine": "Heavy.", + "ids": "8828,8829,8830" + }, + { + "examine": "This is supposed to stop people falling down the manhole.", + "ids": "883" + }, + { + "examine": "You can 'cart' things around on this.", + "ids": "8831,8832,8833,8834,8835,8836,8837,8838,8839" + }, + { + "examine": "Best used with a bucket.", + "ids": "884" + }, + { + "examine": "I feel the need to throw a rotten cabbage!", + "ids": "8840,8841" + }, + { + "examine": "Nothing growing on this tree at the moment...", + "ids": "8842" + }, + { + "examine": "Mmmmm, nice juicy apples!", + "ids": "8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,8855,8856,8857,8858,8859,8860" + }, + { + "examine": "If only I had one of those at home...", + "ids": "885,886" + }, + { + "examine": "This is a special hops patch.", + "ids": "8861,8862,8863,8864" + }, + { + "examine": "Kelda Hop seeds have been sown in this farming patch.", + "ids": "8865" + }, + { + "examine": "Kelda Hops are growing in this farming patch.", + "ids": "8866,8867,8868" + }, + { + "examine": "These are fully grown Kelda Hops.", + "ids": "8869" + }, + { + "examine": "A painting of the King looking royal.", + "ids": "887" + }, + { + "examine": "A barrel of Kelda Stout.", + "ids": "8870" + }, + { + "examine": "This vat contains Kelda hops.", + "ids": "8871" + }, + { + "examine": "Kelda Stout is fermenting in this vat.", + "ids": "8872,8873" + }, + { + "examine": "This vat contains Kelda Stout.", + "ids": "8874,8875,8876,8877" + }, + { + "examine": "Some bizarre mixture between rocks and machinery. Definitely dwarven.", + "ids": "8878" + }, + { + "examine": "A strange box of some kind.", + "ids": "8879" + }, + { + "examine": "A beautiful landscape.", + "ids": "888" + }, + { + "examine": "A strange box of some kind. It's open.", + "ids": "8880" + }, + { + "examine": "A small cave entrance.", + "ids": "8881,8882,8883,8884,8885" + }, + { + "examine": "Keeps mine carts from rolling away.", + "ids": "8886" + }, + { + "examine": "Cart tracks.", + "ids": "8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898" + }, + { + "examine": "A mysterious figure stands alone in this haunting image.", + "ids": "889" + }, + { + "examine": "A support for the tracks.", + "ids": "8899,8900,8901,8902,8903,8904,8905,8906,8907,8908,8909" + }, + { + "examine": "A wrought iron gate.", + "ids": "89,90" + }, + { + "examine": "Hail to the King!", + "ids": "890" + }, + { + "examine": "I don't know much about art, but I like this.", + "ids": "891" + }, + { + "examine": "These books contain all sorts of data on the Red Axe.", + "ids": "8910" + }, + { + "examine": "Big mysterious crates. You wonder what could be inside.", + "ids": "8911" + }, + { + "examine": "Wooden crates with metal edges, contents unknown.", + "ids": "8912" + }, + { + "examine": "Big mysterious crates. There are some papers on top.", + "ids": "8913,8914,8915,8916,8917" + }, + { + "examine": "A symbol of the Red Axe.", + "ids": "8918,8919,8920,8921,8922,8923" + }, + { + "examine": "A painting of some guy standing around somewhere.", + "ids": "892" + }, + { + "examine": "A steam powered cart.", + "ids": "8924,8925" + }, + { + "examine": "A short long boat!", + "ids": "8926" + }, + { + "examine": "Best used with a bucket.", + "ids": "8927,8928" + }, + { + "examine": "A deep and terrifying cave.", + "ids": "8929" + }, + { + "examine": "A really bad portrait of the King.", + "ids": "893" + }, + { + "examine": "It looks cold in there.", + "ids": "8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,8945,8946,8947,8948,8949" + }, + { + "examine": "Fine brushwork adds to the realism of this serene landscape.", + "ids": "894" + }, + { + "examine": "Pretty good painting.", + "ids": "895" + }, + { + "examine": "A big slimy lump of rock.", + "ids": "8950" + }, + { + "examine": "A slimy lump of rock.", + "ids": "8951" + }, + { + "examine": "A slippery looking rock.", + "ids": "8952,8953" + }, + { + "examine": "A tall flag blowing in the wind.", + "ids": "8954,8955" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "8956,8957" + }, + { + "examine": "There must be some trick to opening this...", + "ids": "8958,8959,8960" + }, + { + "examine": "I can see the stars on this.", + "ids": "896" + }, + { + "examine": "It's opening...", + "ids": "8961" + }, + { + "examine": "Apparently there was some trick to opening it!", + "ids": "8962" + }, + { + "examine": "Not as difficult to walk through as it was a minute ago.", + "ids": "8963,8964,8965" + }, + { + "examine": "A sturdy looking door, propped shut with a support.", + "ids": "8967,8968,8969,8970,8971" + }, + { + "examine": "A picture of the stars with funny diagrams and things on.", + "ids": "897" + }, + { + "examine": "A portal back to the real world...", + "ids": "8972" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "8973" + }, + { + "examine": "A commonly found tree.", + "ids": "8974,8975,8976,8977,8978,8979,8980,8981,8982,8983,8984" + }, + { + "examine": "Cross shaped.", + "ids": "898" + }, + { + "examine": "Steam seems to be condensing into the pot. Neat trick!", + "ids": "8985" + }, + { + "examine": "I can see fish swimming in the water. Well, they sort of look like fish...", + "ids": "8986" + }, + { + "examine": "A portal that leads... somewhere?", + "ids": "8987" + }, + { + "examine": "I wonder what's inside...", + "ids": "8988" + }, + { + "examine": "Someone's looking through the chest.", + "ids": "8989,8990,8991,8992,8993,8994,8995,8996,8997" + }, + { + "examine": "Mmmm decorative!", + "ids": "899" + }, + { + "examine": "An appendage for activating something.", + "ids": "8998,8999,9000,9001,9002,9003,9004,9005" + }, + { + "examine": "The barrels of the multicannon.", + "ids": "9" + }, + { + "examine": "Brightens up the room a bit.", + "ids": "900" + }, + { + "examine": "A place to cremate the dead. Needs a body.", + "ids": "9006,9007" + }, + { + "examine": "A place to cremate the dead. Needs a light.", + "ids": "9008,9009" + }, + { + "examine": "I don't know art, but I like it!", + "ids": "901" + }, + { + "examine": "This has broad leaves.", + "ids": "9010,9011,9012,9013" + }, + { + "examine": "This has been chopped away.", + "ids": "9014" + }, + { + "examine": "This has broad leaves.", + "ids": "9015,9016,9017,9018" + }, + { + "examine": "This has been chopped away.", + "ids": "9019" + }, + { + "examine": "Not bad at all.", + "ids": "902" + }, + { + "examine": "This has broad leaves.", + "ids": "9020,9021,9022,9023" + }, + { + "examine": "This has been chopped away.", + "ids": "9024" + }, + { + "examine": "A damaged wooden fence.", + "ids": "9025,9026,9027,9028" + }, + { + "examine": "A wooden fence.", + "ids": "9029" + }, + { + "examine": "Alas poor unicorn, I knew him well.", + "ids": "903" + }, + { + "examine": "Gems encrusted in stone.", + "ids": "9030,9031,9032" + }, + { + "examine": "Many rare plants such as this usually have exotic tubers.", + "ids": "9033" + }, + { + "examine": "A beautiful old mahogany tree.", + "ids": "9034" + }, + { + "examine": "This once was a beautiful tree.", + "ids": "9035" + }, + { + "examine": "A beautiful old teak tree.", + "ids": "9036" + }, + { + "examine": "This tree has been cut down.", + "ids": "9037" + }, + { + "examine": "A set of large, sturdy wooden doors.", + "ids": "9038,9039,9040,9041,9042,9043" + }, + { + "examine": "The scary-looking head of a scary-looking dragon.", + "ids": "904" + }, + { + "examine": "Some goutweed is growing in this patch.", + "ids": "9044,9045,9046,9047" + }, + { + "examine": "Some fully grown goutweed.", + "ids": "9048" + }, + { + "examine": "This goutweed has become diseased.", + "ids": "9049,9050,9051" + }, + { + "examine": "Not what I would pick as wall decoration.", + "ids": "905" + }, + { + "examine": "This goutweed has become diseased and died.", + "ids": "9052,9053,9054,9055,9056,9057" + }, + { + "examine": "He's not stocking much.", + "ids": "9058" + }, + { + "examine": "He's stocking rune caskets.", + "ids": "9059" + }, + { + "examine": "Looks like the bull lost.", + "ids": "906" + }, + { + "examine": "He's stocking blackjacks.", + "ids": "9060" + }, + { + "examine": "He's stocking fez hats.", + "ids": "9061" + }, + { + "examine": "He's stocking rune caskets.", + "ids": "9062" + }, + { + "examine": "He's stocking colourful clothes.", + "ids": "9063" + }, + { + "examine": "A wooden crate.", + "ids": "9064,9065" + }, + { + "examine": "A wooden crate containing caskets.", + "ids": "9066,9067" + }, + { + "examine": "A wooden crate containing Blackjacks.", + "ids": "9068,9069" + }, + { + "examine": "Trinkets and stuff.", + "ids": "907" + }, + { + "examine": "A wooden crate containing fez hats.", + "ids": "9070" + }, + { + "examine": "A wooden crate containing clothes.", + "ids": "9071" + }, + { + "examine": "Boxy.", + "ids": "9072,9073" + }, + { + "examine": "boxy", + "ids": "9074,9075" + }, + { + "examine": "This cloth has been dyed.", + "ids": "9076" + }, + { + "examine": "Mmmm pretty!", + "ids": "9077,9078" + }, + { + "examine": "These dyed fabrics are drying off.", + "ids": "9079,9080,9081" + }, + { + "examine": "Not everyone's idea of a nice wall decoration.", + "ids": "908" + }, + { + "examine": "Items for making clothes are kept on here.", + "ids": "9082" + }, + { + "examine": "Pots full of dye.", + "ids": "9083" + }, + { + "examine": "A way down.", + "ids": "9084" + }, + { + "examine": "There's not much coke in the stove.", + "ids": "9085" + }, + { + "examine": "There's a fair amount of coke in the stove.", + "ids": "9086" + }, + { + "examine": "There's lots of coke in the stove.", + "ids": "9087" + }, + { + "examine": "A big pile of refined coal.", + "ids": "9088" + }, + { + "examine": "You can read the furnace temperature here.", + "ids": "9089" + }, + { + "examine": "Something is written on it. I can't read what.", + "ids": "909" + }, + { + "examine": "Used to pump hot air through the furnace.", + "ids": "9090" + }, + { + "examine": "Bars come out of the blast furnace here.", + "ids": "9091,9092" + }, + { + "examine": "Your bars will come out here.", + "ids": "9093,9094" + }, + { + "examine": "The bars are glowing hot!", + "ids": "9095" + }, + { + "examine": "Your bars are ready to take.", + "ids": "9096" + }, + { + "examine": "They power the conveyor belt.", + "ids": "9097" + }, + { + "examine": "The foreman refers to it as 'Bertha'.", + "ids": "9098" + }, + { + "examine": "It shows that the furnace is working.", + "ids": "9099" + }, + { + "examine": "I don't like the look of this!", + "ids": "91" + }, + { + "examine": "Looks like an eye with huge lashes.", + "ids": "910" + }, + { + "examine": "Ore rides this into the blast furnace.", + "ids": "9100,9101" + }, + { + "examine": "It keeps the conveyor belt running.", + "ids": "9102" + }, + { + "examine": "Fix it, quick!", + "ids": "9103" + }, + { + "examine": "They keep the conveyor belt running.", + "ids": "9104" + }, + { + "examine": "Fix them, quick!", + "ids": "9105" + }, + { + "examine": "It keeps the conveyor belt turning.", + "ids": "9106,9107" + }, + { + "examine": "They keep the conveyor belt turning.", + "ids": "9108,9109,9110,9111,9112,9113,9114" + }, + { + "examine": "A tablet covered in weird looking little squiggles and pictures.", + "ids": "911" + }, + { + "examine": "It shows that the furnace is working.", + "ids": "9115" + }, + { + "examine": "Hot air circulates through these.", + "ids": "9116" + }, + { + "examine": "Quick, fix them!", + "ids": "9117,9118,9119" + }, + { + "examine": "Hot air circulates through these.", + "ids": "9120" + }, + { + "examine": "Quick, fix them!", + "ids": "9121,9122" + }, + { + "examine": "It shows the furnace is working.", + "ids": "9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137" + }, + { + "examine": "A way upwards.", + "ids": "9138,9139" + }, + { + "examine": "The gate is closed.", + "ids": "9140,9141" + }, + { + "examine": "The gate is open.", + "ids": "9142" + }, + { + "examine": "Used for getting water.", + "ids": "9143" + }, + { + "examine": "Some kind of jewellery is dangling from this ornament.", + "ids": "9144" + }, + { + "examine": "Someone's showing off their wealth!", + "ids": "9145" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "9146,9147" + }, + { + "examine": "A nicely carved wooden chair.", + "ids": "9148" + }, + { + "examine": "An expensive privacy aid!", + "ids": "9149" + }, + { + "examine": "A posh water bowl.", + "ids": "915" + }, + { + "examine": "An old wall.", + "ids": "9150" + }, + { + "examine": "Security breach!", + "ids": "9151" + }, + { + "examine": "A patched up hole.", + "ids": "9152,9153,9154" + }, + { + "examine": "'You are here.'", + "ids": "9155" + }, + { + "examine": "An elegant desk with a curious ornament on it.", + "ids": "9156" + }, + { + "examine": "Someone's gold-trimmed this Saradomin armour!", + "ids": "9157,9158" + }, + { + "examine": "Lit to remember the souls of the departed.", + "ids": "9159,9160,9161,9162,9163,9164,9165" + }, + { + "examine": "You can grow delphiniums in this Farming patch.", + "ids": "9166,9167,9168,9169" + }, + { + "examine": "Delphinium seeds have been sown in this farming patch.", + "ids": "9170" + }, + { + "examine": "Beautiful.", + "ids": "9171,9172" + }, + { + "examine": "These delphiniums are fully grown.", + "ids": "9173,9174,9175,9176" + }, + { + "examine": "You can grow a pink rose bush in this patch.", + "ids": "9177,9178,9179,9180" + }, + { + "examine": "You can grow a white rose bush in this patch.", + "ids": "9181,9182,9183,9184" + }, + { + "examine": "You can grow a red rose bush in this patch.", + "ids": "9185,9186,9187,9188" + }, + { + "examine": "A rose bush.", + "ids": "9189,9190,9191" + }, + { + "examine": "This white rosebush is fully grown.", + "ids": "9192" + }, + { + "examine": "A rose bush.", + "ids": "9193" + }, + { + "examine": "This red rosebush is fully grown.", + "ids": "9194" + }, + { + "examine": "A pink rosebush.", + "ids": "9195" + }, + { + "examine": "This pink rosebush is fully grown.", + "ids": "9196,9197,9198" + }, + { + "examine": "A plantpot of pink orchids.", + "ids": "9199,9200,9201" + }, + { + "examine": "The door is closed.", + "ids": "92,93" + }, + { + "examine": "These pink orchids are fully grown.", + "ids": "9202" + }, + { + "examine": "An empty plantpot.", + "ids": "9203" + }, + { + "examine": "A plantpot filled with soil.", + "ids": "9204" + }, + { + "examine": "A plantpot of yellow orchids.", + "ids": "9205,9206,9207" + }, + { + "examine": "These yellow orchids are fully grown.", + "ids": "9208,9209" + }, + { + "examine": "You can grow a White Tree in this patch.", + "ids": "9210,9211,9212,9213" + }, + { + "examine": "A White Tree sapling has been planted in this patch.", + "ids": "9214" + }, + { + "examine": "A White Tree is growing in this patch.", + "ids": "9215,9216,9217" + }, + { + "examine": "This White Tree is fully grown.", + "ids": "9218" + }, + { + "examine": "This White Tree bears a single fruit.", + "ids": "9219" + }, + { + "examine": "This White Tree bears two fruits.", + "ids": "9220" + }, + { + "examine": "This White Tree bears three fruits.", + "ids": "9221" + }, + { + "examine": "This White Tree bears four fruits.", + "ids": "9222,9223" + }, + { + "examine": "You can grow snowdrops in this Farming patch.", + "ids": "9224,9225,9226,9227" + }, + { + "examine": "A patch of snowdrops.", + "ids": "9228,9229,9230" + }, + { + "examine": "These snowdrops are fully grown.", + "ids": "9231,9232" + }, + { + "examine": "You can grow Burthorpe Vine in this patch.", + "ids": "9233" + }, + { + "examine": "You can grow Burthorpe Vines in this patch.", + "ids": "9234,9235,9236" + }, + { + "examine": "Burthorpe vines are growing in this patch.", + "ids": "9237,9238,9239" + }, + { + "examine": "These Burthorpe vines are fully grown.", + "ids": "9240" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9241,9242" + }, + { + "examine": "What a good likeness!", + "ids": "9243" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9244" + }, + { + "examine": "An expertly carved statue of a former King of Misthalin.", + "ids": "9245" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9246" + }, + { + "examine": "What a good likeness!", + "ids": "9247" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9248" + }, + { + "examine": "An expertly carved statue of a former King of Misthalin.", + "ids": "9249,9250,9251,9252,9253,9254" + }, + { + "examine": "These grapevines look much healthier now.", + "ids": "9255" + }, + { + "examine": "These grapevines are suffering from some strange disease.", + "ids": "9256" + }, + { + "examine": "Some wild-looking grass.", + "ids": "9257,9258,9259" + }, + { + "examine": "Some red roses.", + "ids": "9260" + }, + { + "examine": "Some pink roses.", + "ids": "9261" + }, + { + "examine": "Some white roses.", + "ids": "9262" + }, + { + "examine": "A White Tree.", + "ids": "9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,9290" + }, + { + "examine": "Sit back and enjoy the view.", + "ids": "9291" + }, + { + "examine": "An expertly carved statue of a former Queen of Misthalin.", + "ids": "9292" + }, + { + "examine": "Funny looking holes that don't look too inviting.", + "ids": "9294" + }, + { + "examine": "A rocky outcrop.", + "ids": "9296,9297,9298" + }, + { + "examine": "Ornate railing.", + "ids": "9299" + }, + { + "examine": "Wooden fencing.", + "ids": "9300" + }, + { + "examine": "A well constructed castle wall.", + "ids": "9301" + }, + { + "examine": "A rather strategically placed hole, which appears to be in the ground.", + "ids": "9302" + }, + { + "examine": "A rocky outcrop.", + "ids": "9303,9304,9305,9306" + }, + { + "examine": "A well weathered wall.", + "ids": "9307,9308" + }, + { + "examine": "A tunnel leading under the wall.", + "ids": "9309,9310" + }, + { + "examine": "An underwall tunnel.", + "ids": "9311,9312" + }, + { + "examine": "Looks suspicious.", + "ids": "9313" + }, + { + "examine": "A wall jutting out into the path.", + "ids": "9314" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "9315" + }, + { + "examine": "A rocky outcrop.", + "ids": "9316,9317,9318" + }, + { + "examine": "A chain rope", + "ids": "9319,9320" + }, + { + "examine": "A few rocks short of a wall", + "ids": "9321" + }, + { + "examine": "The foam from the river makes this log very slippy.", + "ids": "9322,9323,9324" + }, + { + "examine": "Just another crack in the wall.", + "ids": "9325" + }, + { + "examine": "Funny looking holes that don't look too inviting.", + "ids": "9326" + }, + { + "examine": "They seem to fit in the with the rocky surroundings, so as not to stick out.", + "ids": "9327" + }, + { + "examine": "A slippery well worn log.", + "ids": "9328,9329,9330" + }, + { + "examine": "A rocky outcrop.", + "ids": "9331,9332,9333" + }, + { + "examine": "Used to be ornate, now it's a little bit vandalised.", + "ids": "9334" + }, + { + "examine": "A rocky outcrop.", + "ids": "9335,9336" + }, + { + "examine": "Used to be ornate, now it's a little bit vandalised.", + "ids": "9337" + }, + { + "examine": "Should scare off the birds...", + "ids": "9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9352,9353" + }, + { + "examine": "This looks like the way out.", + "ids": "9354" + }, + { + "examine": "A cave deep into the volcano.", + "ids": "9355" + }, + { + "examine": "A cave deeper into the volcano.", + "ids": "9356,9357" + }, + { + "examine": "A cave deep into the volcano.", + "ids": "9358" + }, + { + "examine": "This looks like the way out.", + "ids": "9359,9360,9361,9362,9363,9364,9365" + }, + { + "examine": "The barrier of heat is down.", + "ids": "9366" + }, + { + "examine": "A barrier of heat.", + "ids": "9367,9368,9369,9370,9371,9372,9373" + }, + { + "examine": "Hot enough to cook your breakfast on.", + "ids": "9374,9375,9376" + }, + { + "examine": "An egg incubated in the lava.", + "ids": "9377,9378,9379" + }, + { + "examine": "Who's the man?", + "ids": "9380" + }, + { + "examine": "A wooden crate.", + "ids": "9381" + }, + { + "examine": "Some wooden crates.", + "ids": "9382,9383,9384,9385,9386,9387,9388,9389" + }, + { + "examine": "A natural forge using volcanic heat.", + "ids": "9390" + }, + { + "examine": "I spy with my little eye...", + "ids": "9391,9392,9393,9394,9395,9396,9397" + }, + { + "examine": "Lets you put items into your bank.", + "ids": "9398,9399,26969,36788" + }, + { + "examine": "A wrought iron gate.", + "ids": "94,95" + }, + { + "examine": "Sparse weeds.", + "ids": "9400" + }, + { + "examine": "Weeds.", + "ids": "9401" + }, + { + "examine": "Thick weeds.", + "ids": "9402" + }, + { + "examine": "This is Unferth's patch for growing potatos.", + "ids": "9403" + }, + { + "examine": "You say Potato, I say Poh-tar-to.", + "ids": "9404,9405,9406,9407" + }, + { + "examine": "Looks like these potatoes have fully grown.", + "ids": "9408,9409,9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9424,9425,9426,9427,9428,9429" + }, + { + "examine": "A nice sturdy bare table.", + "ids": "9430" + }, + { + "examine": "A nice sturdy table.", + "ids": "9431" + }, + { + "examine": "A table with milk.", + "ids": "9432" + }, + { + "examine": "A table with cake.", + "ids": "9433" + }, + { + "examine": "A hearty meal for Unferth.", + "ids": "9434,9435" + }, + { + "examine": "Great for sleeping in.", + "ids": "9436" + }, + { + "examine": "Not so great for sleeping in, it's not made.", + "ids": "9437,9438" + }, + { + "examine": "A fire burns brightly here.", + "ids": "9439" + }, + { + "examine": "An empty fire place.", + "ids": "9440" + }, + { + "examine": "An unlit fire place.", + "ids": "9441,9442" + }, + { + "examine": "A good source of books!", + "ids": "9443,9444,9445,9446,9447,9448,9449,9450,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469" + }, + { + "examine": "I can climb these stairs.", + "ids": "9470" + }, + { + "examine": "They go down.", + "ids": "9471" + }, + { + "examine": "What could be down here?", + "ids": "9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497" + }, + { + "examine": "A small plant, suitable for sandy soil.", + "ids": "9498" + }, + { + "examine": "A decorative plant.", + "ids": "9499" + }, + { + "examine": "A fairly small plant.", + "ids": "9500" + }, + { + "examine": "Another plant.", + "ids": "9501,9502,9503,9504,9505,9506,9507" + }, + { + "examine": "Perfect for snoozing in the sun.", + "ids": "9508" + }, + { + "examine": "Lovely comfy-looking big bed.", + "ids": "9509" + }, + { + "examine": "East to Draynor Village :: South to Rimmington :: South-east to Port Sarim.", + "ids": "9510,9511,9512,9513" + }, + { + "examine": "Betty's chair.", + "ids": "9514" + }, + { + "examine": "I wonder what she's making?", + "ids": "9515" + }, + { + "examine": "Betty's counter.", + "ids": "9516,9517,9518" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "9519" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "9520" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "9521" + }, + { + "examine": "How much does this weigh?", + "ids": "9522" + }, + { + "examine": "A case. With books.", + "ids": "9523" + }, + { + "examine": "A mooring chain.", + "ids": "9524" + }, + { + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "9525" + }, + { + "examine": "Betty keeps some rune objects here.", + "ids": "9526,9527,9528,9529" + }, + { + "examine": "A sinister fungus.", + "ids": "9530" + }, + { + "examine": "Sit back and relax...", + "ids": "9531" + }, + { + "examine": "Sit back and enjoy the view.", + "ids": "9532" + }, + { + "examine": "A wooden crate.", + "ids": "9533,9534" + }, + { + "examine": "Some wooden crates.", + "ids": "9535" + }, + { + "examine": "Some wooden boxes.", + "ids": "9536" + }, + { + "examine": "It's used for loading and unloading fishing boats.", + "ids": "9537" + }, + { + "examine": "I hope it doesn't sink.", + "ids": "9538,9539,9540,9541,9542,9543,9544,9545,9546,9547" + }, + { + "examine": "For wiping muddy feet on.", + "ids": "954" + }, + { + "examine": "A bucket full of red hot coals.", + "ids": "9548,9549,9550,9551,9552,9553,9554,9555,9556,9557" + }, + { + "examine": "Disturbingly its eyes look everywhere in the room except at you.", + "ids": "955,956,957,958" + }, + { + "examine": "It leads up.", + "ids": "9558" + }, + { + "examine": "I can climb down this.", + "ids": "9559,9560" + }, + { + "examine": "I guess I could sleep in it if I were really tired.", + "ids": "9561" + }, + { + "examine": "A prison cell door.", + "ids": "9562" + }, + { + "examine": "A locked prison cell door.", + "ids": "9563" + }, + { + "examine": "A prison cell door.", + "ids": "9564" + }, + { + "examine": "Stops people getting out.", + "ids": "9565,9566" + }, + { + "examine": "Ewww!", + "ids": "9567" + }, + { + "examine": "En-suite facilities in every cell!", + "ids": "9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581" + }, + { + "examine": "I can climb up these stairs.", + "ids": "9582,9583" + }, + { + "examine": "I can climb down these stairs.", + "ids": "9584,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603" + }, + { + "examine": "What has a face and hands but is not a man?", + "ids": "959" + }, + { + "examine": "A dark flight of stairs.", + "ids": "96,98" + }, + { + "examine": "It's a time machine....sort of!", + "ids": "960" + }, + { + "examine": "A leafy plant.", + "ids": "9604" + }, + { + "examine": "A leafy fern.", + "ids": "9605" + }, + { + "examine": "A leafy shrub.", + "ids": "9606" + }, + { + "examine": "A case. With books.", + "ids": "9607,9608,9609" + }, + { + "examine": "'Ask about our low, low interest rates!'", + "ids": "961" + }, + { + "examine": "An artist's easel.", + "ids": "9610" + }, + { + "examine": "A good source of books!", + "ids": "9611" + }, + { + "examine": "The Make-over Mage's bed.", + "ids": "9612" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "9613" + }, + { + "examine": "Generally used for putting things on.", + "ids": "9614" + }, + { + "examine": "A small wooden table.", + "ids": "9615" + }, + { + "examine": "Items are for sale here.", + "ids": "9616" + }, + { + "examine": "All-purpose storage.", + "ids": "9617,9618,9619,9620" + }, + { + "examine": "Some helpful people have placed notes on here, how nice.", + "ids": "962" + }, + { + "examine": "For sitting.", + "ids": "9621" + }, + { + "examine": "Fancy.", + "ids": "9622,9623" + }, + { + "examine": "It's like a land rudder.", + "ids": "9624" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660" + }, + { + "examine": "Essentials for a seamstress.", + "ids": "963" + }, + { + "examine": "It really was this big!", + "ids": "964,965" + }, + { + "examine": "He doesn't look too jolly to me!", + "ids": "966" + }, + { + "examine": "This tree has been cut down.", + "ids": "9661" + }, + { + "examine": "Popular with farmers and treasure hunters.", + "ids": "9662" + }, + { + "examine": "This tree has fallen to the ground.", + "ids": "9663" + }, + { + "examine": "A gnarly old tree root.", + "ids": "9664" + }, + { + "examine": "The roots of a tree are exposed.", + "ids": "9665" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "9666" + }, + { + "examine": "Disturbingly man-like.", + "ids": "9667" + }, + { + "examine": "Its eyes stare off into the distance...", + "ids": "9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,9680,9681" + }, + { + "examine": "Looks like this ship was way off course!", + "ids": "967" + }, + { + "examine": "X marks the spot.", + "ids": "968" + }, + { + "examine": "Expels smoke from the range.", + "ids": "9683" + }, + { + "examine": "Wash your hands!", + "ids": "9684" + }, + { + "examine": "Generally used for putting things on.", + "ids": "9685" + }, + { + "examine": "Some fabric ready for clothing.", + "ids": "9686" + }, + { + "examine": "I'm guessing it's for making women's clothes.", + "ids": "9687,9688" + }, + { + "examine": "Looks like it's for making men's clothes.", + "ids": "9689" + }, + { + "examine": "Complete with authentic seaweed!", + "ids": "969" + }, + { + "examine": "I think this one's for making men's clothes.", + "ids": "9690,9691,9692,9693" + }, + { + "examine": "Some helpful people have placed notes on here, how nice.", + "ids": "9694" + }, + { + "examine": "This notice board is full of scrolls and charts.", + "ids": "9695" + }, + { + "examine": "I wonder what's inside ?", + "ids": "9696" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "9697,9698,9699,9700,9701" + }, + { + "examine": "This mentions the monk trapped here...", + "ids": "970" + }, + { + "examine": "This clearly isn't used for dining very often.", + "ids": "9702" + }, + { + "examine": "Not as nice as some.", + "ids": "9703" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "9704,9705" + }, + { + "examine": "This must let me in to the arena somehow...", + "ids": "9706" + }, + { + "examine": "This must let me out of the arena somehow...", + "ids": "9707" + }, + { + "examine": "A rocky outcrop.", + "ids": "9708,9709,9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9737" + }, + { + "examine": "A useful ranging device.", + "ids": "971" + }, + { + "examine": "Use these with bows.", + "ids": "972" + }, + { + "examine": "A powerful throwing weapon.", + "ids": "973" + }, + { + "examine": "An old crumbled pillar.", + "ids": "9738,9739,9740" + }, + { + "examine": "Improved Leather armour for archers.", + "ids": "974" + }, + { + "examine": "Smells like fish.", + "ids": "9741,9742,9743" + }, + { + "examine": "I can climb up here.", + "ids": "9744" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "9745,9746,9747" + }, + { + "examine": "A collection point.", + "ids": "9748" + }, + { + "examine": "A Lever.", + "ids": "9749,9750" + }, + { + "examine": "Leather made from the skin of a Dragon.", + "ids": "975" + }, + { + "examine": "A crystal that was broken a long time ago.", + "ids": "9751" + }, + { + "examine": "A repowered crystal.", + "ids": "9752" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9753" + }, + { + "examine": "I wonder what's inside.", + "ids": "9754" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9755" + }, + { + "examine": "I wonder what's inside.", + "ids": "9756" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9757" + }, + { + "examine": "I wonder what's inside.", + "ids": "9758" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9759" + }, + { + "examine": "I wonder what's inside.", + "ids": "9760" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9761" + }, + { + "examine": "I wonder what's inside.", + "ids": "9762" + }, + { + "examine": "A recently killed guard.", + "ids": "9763,9764,9765" + }, + { + "examine": "A recently killed slave.", + "ids": "9766,9767" + }, + { + "examine": "A door of pure light!", + "ids": "9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,9890,9891,9892,9893,9894,9895,9896,9897" + }, + { + "examine": "There are holes passing through this pillar.", + "ids": "9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,9965,9966,9967,9968,9969,9970,9971,9972,9973,9974" + }, + { + "examine": "The door is closed.", + "ids": "99" + }, + { + "examine": "I can climb over the fence with this..", + "ids": "993" + }, + { + "examine": "I can climb down these.", + "ids": "9975" + }, + { + "examine": "A cave wall.", + "ids": "9976" + }, + { + "examine": "I wonder where this goes?", + "ids": "9977" + }, + { + "examine": "A ladder carved into the wall.", + "ids": "9978,9979" + }, + { + "examine": "A good place for light to merge.", + "ids": "9980" + }, + { + "examine": "A good place for a light crystal.", + "ids": "9981,9982,9983,9984,9985,9986,9987" + }, + { + "examine": "A broken pillar.", + "ids": "9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001" } ] \ No newline at end of file diff --git a/Server/data/configs/ranged_weapon_configs.json b/Server/data/configs/ranged_weapon_configs.json index 03f8d60dd..dc6fbe429 100644 --- a/Server/data/configs/ranged_weapon_configs.json +++ b/Server/data/configs/ranged_weapon_configs.json @@ -15,7 +15,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,13280" + "ammunition": "877,878,6061,6062,879,9236" }, { "itemId": "800", @@ -294,7 +294,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,13280" + "ammunition": "877,878,6061,6062,879,9236" }, { "itemId": "839", @@ -1095,7 +1095,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "8882,877,878,6061,6062,879,9236" + "ammunition": "8882,877,878,6061,6062,879,9236,9139,9286,9293,9300,9140,9287,9294,9237,9145,9301,9292,9299,9306,9335,880,9238" }, { "itemId": "9174", @@ -1104,7 +1104,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,13280" + "ammunition": "877,878,6061,6062,879,9236" }, { "itemId": "9176", @@ -1113,7 +1113,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,9140,879,9139,9236,13280" + "ammunition": "877,878,6061,6062,879,9139,9236,9286,9293,9300,9335,9237" }, { "itemId": "9177", @@ -1122,7 +1122,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,9139,9140,9287,9294,9301,880,9238,9145,13280" + "ammunition": "877,878,6061,6062,879,9236,9139,9140,9287,9294,9301,880,9238,9145,9286,9293,9300,9292,9299,9306,9335,9237" }, { "itemId": "9179", @@ -1131,7 +1131,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9139,9140,9236,9141,9288,9295,9302,9336,9239,9145,13280" + "ammunition": "877,878,6061,6062,879,9139,9140,9236,9141,9288,9295,9302,9336,9239,9145,9286,9293,9300,9287,9294,9301,9292,9299,9306,9335,9237,880,9238" }, { "itemId": "9181", @@ -1140,7 +1140,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9145,9139,9140,9241,13280" + "ammunition": "877,878,6061,6062,879,9236,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9145,9139,9140,9241,9286,9293,9300,9140,9287,9294,9301,9292,9299,9306,9335,9237,880,9238,13083,13084,13085,13086" }, { "itemId": "9183", @@ -1149,7 +1149,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,9139,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9145,9143,9290,9297,9304,9339,9242,9340,9243,13280" + "ammunition": "877,878,6061,6062,879,9236,9139,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9145,9143,9290,9297,9304,9339,9242,9340,9243,9286,9293,9300,9140,9287,9294,9301,9292,9299,9306,9335,9237,880,9238,13083,13084,13085,13086" }, { "itemId": "9185", @@ -1158,7 +1158,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,9139,9141,9288,9295,9302,9336,9239,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9145,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9143,9290,9297,9304,9339,9242,9340,9243,9144,9291,9298,9305,9341,9244,9342,9245,9140,13280" + "ammunition": "877,878,6061,6062,879,9236,9139,9141,9288,9295,9302,9336,9239,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9145,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9143,9290,9297,9304,9339,9242,9340,9243,9144,9291,9298,9305,9341,9244,9342,9245,9140,13280,9139,9286,9293,9300,9287,9294,9301,9292,9299,9306,9335,9237,880,13083,13084,13085,13086" }, { "itemId": "9705", @@ -1293,7 +1293,7 @@ "weapon_type": "1", "animation": "4230", "drop_ammo": "true", - "ammunition": "877,878,6061,6062,879,9236,9141,9288,9295,9302,9140,9336,9239,13083,13084,13085,13086,13280" + "ammunition": "877,878,6061,6062,879,9139,9140,9236,9141,9288,9295,9302,9336,9239,9145,9286,9293,9300,9287,9294,9301,9292,9299,9306,9335,9237,880,9238,13083,13084,13085,13086" }, { "itemId": "13405", @@ -1546,5 +1546,41 @@ "animation": "426", "drop_ammo": "true", "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "10149", + "name": "Swamp lizard", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "5247", + "drop_ammo": "false", + "ammunition": "10142" + }, + { + "itemId": "10146", + "name": "Orange salamander", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "5247", + "drop_ammo": "false", + "ammunition": "10143" + }, + { + "itemId": "10147", + "name": "Red salamander", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "5247", + "drop_ammo": "false", + "ammunition": "10144" + }, + { + "itemId": "10148", + "name": "Black salamander", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "5247", + "drop_ammo": "false", + "ammunition": "10145" } ] diff --git a/Server/data/configs/shops.json b/Server/data/configs/shops.json index 714e32a73..2f285314c 100644 --- a/Server/data/configs/shops.json +++ b/Server/data/configs/shops.json @@ -177,7 +177,7 @@ "general_store": "true", "id": "21", "title": "Gunslik's Assorted Items", - "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + "stock": "{1935,10,100}-{1925,30,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{36,10,100}-{596,10,100}-{973,10,100}-{1059,10,100}-{229,300,100}-{233,10,100}-{954,10,100}" }, { "npcs": "1334", @@ -564,7 +564,7 @@ "general_store": "false", "id": "65", "title": "Dodgy Mikes Second-hand Clothing", - "stock": "{7114,10,100}" + "stock": "{7114,10,100}-{7122,10,100}-{7128,10,100}-{7134,10,100}-{7110,10,100}-{7126,10,100}-{7132,10,100}-{7138,10,100}-{7116,10,100}-{7124,10,100}-{7130,10,100}-{7112,10,100}-{7136,10,100}" }, { "npcs": "2161", @@ -2177,5 +2177,23 @@ "id": "255", "title": "Castle Wars Ticket Exchange", "stock": "{4068,1,100}-{4069,1,100}-{4070,1,100}-{4071,1,100}-{4072,1,100}-{4503,1,100}-{4504,1,100}-{4505,1,100}-{4506,1,100}-{4507,1,100}-{4508,1,100}-{4509,1,100}-{4510,1,100}-{4511,1,100}-{4512,1,100}-{4513,1,100}-{4514,1,100}-{4515,1,100}-{4516,1,100}" + }, + { + "npcs": "5111", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "256", + "title": "Leon's Prototype Crossbow", + "stock": "{10156,2,100}" + }, + { + "npcs": "2039", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "256", + "title": "Uglug's Stuffsies", + "stock": "{4844,100,10}-{10927,0,100}-{2862,100,100}-{1777,10,200}-{2876,0,500}-{2878,10,100}-{4850,0,100}-{946,5,100}-{4773,0,1000}-{4778,0,1000}-{4783,0,1000}-{4788,0,1500}-{4793,0,2000}-{4798,0,3000}-{4803,0,4000}-{4827,0,2000}" } ] \ No newline at end of file diff --git a/Server/data/configs/xteas.json b/Server/data/configs/xteas.json index 69528883f..5b8de21a7 100644 --- a/Server/data/configs/xteas.json +++ b/Server/data/configs/xteas.json @@ -1,17 +1,5 @@ { "xteas": [ - { - "regionId": "6230", - "keys": "0,0,0,0" - }, - { - "regionId": "6231", - "keys": "0,0,0,0" - }, - { - "regionId": "6232", - "keys": "0,0,0,0" - }, { "regionId": "6234", "keys": "-1591922206,-1429764510,-1087339341,1592935185" @@ -28,18 +16,6 @@ "regionId": "6483", "keys": "14881828,-6662814,58238456,146761213" }, - { - "regionId": "6484", - "keys": "0,0,0,0" - }, - { - "regionId": "6485", - "keys": "0,0,0,0" - }, - { - "regionId": "6486", - "keys": "0,0,0,0" - }, { "regionId": "6487", "keys": "-844708758,693908396,-1724237422,-2131620302" @@ -64,50 +40,10 @@ "regionId": "6726", "keys": "-3492110,65044555,1450623668,-483811536" }, - { - "regionId": "6732", - "keys": "0,0,0,0" - }, - { - "regionId": "6733", - "keys": "0,0,0,0" - }, - { - "regionId": "6734", - "keys": "0,0,0,0" - }, - { - "regionId": "6735", - "keys": "0,0,0,0" - }, - { - "regionId": "6736", - "keys": "0,0,0,0" - }, - { - "regionId": "6737", - "keys": "0,0,0,0" - }, - { - "regionId": "6738", - "keys": "0,0,0,0" - }, - { - "regionId": "6739", - "keys": "0,0,0,0" - }, - { - "regionId": "6740", - "keys": "0,0,0,0" - }, { "regionId": "6741", "keys": "-1634995791,710519356,-47126463,-1180416882" }, - { - "regionId": "6742", - "keys": "0,0,0,0" - }, { "regionId": "6743", "keys": "-1239303400,-1604922847,-1532369005,982307785" @@ -120,38 +56,14 @@ "regionId": "6745", "keys": "365190378,-1767339898,2011432030,276148826" }, - { - "regionId": "6746", - "keys": "0,0,0,0" - }, - { - "regionId": "6979", - "keys": "0,0,0,0" - }, - { - "regionId": "6980", - "keys": "0,0,0,0" - }, - { - "regionId": "6981", - "keys": "0,0,0,0" - }, { "regionId": "6985", "keys": "1193572731,-1288765743,-386862979,351599890" }, - { - "regionId": "6988", - "keys": "0,0,0,0" - }, { "regionId": "6989", "keys": "-891749173,-113432144,-1228601828,695082558" }, - { - "regionId": "6990", - "keys": "0,0,0,0" - }, { "regionId": "6991", "keys": "-1448188175,626198836,1985989165,-1062391664" @@ -172,46 +84,14 @@ "regionId": "6995", "keys": "-1227889203,-199624313,2143494494,531356102" }, - { - "regionId": "6996", - "keys": "0,0,0,0" - }, - { - "regionId": "6997", - "keys": "0,0,0,0" - }, - { - "regionId": "6998", - "keys": "0,0,0,0" - }, - { - "regionId": "6999", - "keys": "0,0,0,0" - }, - { - "regionId": "7000", - "keys": "0,0,0,0" - }, { "regionId": "7001", "keys": "170738852,2045755396,-1580637869,-1933392334" }, - { - "regionId": "7002", - "keys": "0,0,0,0" - }, - { - "regionId": "7235", - "keys": "0,0,0,0" - }, { "regionId": "7236", "keys": "570290255,-1513898184,-1269691884,782850050" }, - { - "regionId": "7237", - "keys": "0,0,0,0" - }, { "regionId": "7238", "keys": "-853120516,1697831503,-12188711,770411534" @@ -220,14 +100,6 @@ "regionId": "7244", "keys": "796665731,1335649913,758227393,585095755" }, - { - "regionId": "7245", - "keys": "0,0,0,0" - }, - { - "regionId": "7246", - "keys": "0,0,0,0" - }, { "regionId": "7247", "keys": "-122734679,-1029771956,1633683499,846700218" @@ -244,30 +116,10 @@ "regionId": "7250", "keys": "497663526,-1258315657,-785166329,-999527877" }, - { - "regionId": "7251", - "keys": "0,0,0,0" - }, - { - "regionId": "7252", - "keys": "0,0,0,0" - }, - { - "regionId": "7490", - "keys": "0,0,0,0" - }, - { - "regionId": "7491", - "keys": "0,0,0,0" - }, { "regionId": "7492", "keys": "417150556,1135530200,2139696777,-742314409" }, - { - "regionId": "7493", - "keys": "0,0,0,0" - }, { "regionId": "7494", "keys": "-1653750072,103282771,384178856,1122166637" @@ -276,14 +128,6 @@ "regionId": "7496", "keys": "-1890766195,-149577199,919306397,-954784877" }, - { - "regionId": "7497", - "keys": "0,0,0,0" - }, - { - "regionId": "7498", - "keys": "0,0,0,0" - }, { "regionId": "7499", "keys": "-2007696984,-1215288615,-1572330641,-2125382604" @@ -312,10 +156,6 @@ "regionId": "7505", "keys": "-1177354806,-1864641630,23736540,750869235" }, - { - "regionId": "7506", - "keys": "0,0,0,0" - }, { "regionId": "7507", "keys": "-1476331852,1093075535,-2003580146,734573751" @@ -332,6 +172,10 @@ "regionId": "7510", "keys": "2073894230,-553352720,274325814,-1461052837" }, + { + "regionId": "7511", + "keys": "14881828,-6662814,58238456,146761213" + }, { "regionId": "7513", "keys": "1066375195,548376104,-1771348528,1096433429" @@ -340,10 +184,6 @@ "regionId": "7745", "keys": "1212560091,-662504525,-1213494614,-1245629284" }, - { - "regionId": "7747", - "keys": "0,0,0,0" - }, { "regionId": "7748", "keys": "-850453392,-249468744,1635462867,100471784" @@ -352,10 +192,6 @@ "regionId": "7749", "keys": "369356966,-1038198212,282112206,802717032" }, - { - "regionId": "7750", - "keys": "0,0,0,0" - }, { "regionId": "7752", "keys": "1894158557,20416613,-1434347651,-1209846311" @@ -392,46 +228,14 @@ "regionId": "7760", "keys": "2042192998,743878512,-1804236758,-1160501924" }, - { - "regionId": "7761", - "keys": "0,0,0,0" - }, - { - "regionId": "7762", - "keys": "0,0,0,0" - }, { "regionId": "7763", "keys": "14881828,-6662814,58238456,146761213" }, - { - "regionId": "7764", - "keys": "0,0,0,0" - }, - { - "regionId": "7765", - "keys": "0,0,0,0" - }, { "regionId": "7769", "keys": "560280774,910095015,871073102,263015376" }, - { - "regionId": "7995", - "keys": "0,0,0,0" - }, - { - "regionId": "7996", - "keys": "0,0,0,0" - }, - { - "regionId": "7997", - "keys": "0,0,0,0" - }, - { - "regionId": "7998", - "keys": "0,0,0,0" - }, { "regionId": "8001", "keys": "690512367,1578449236,-1443501555,546253393" @@ -440,10 +244,6 @@ "regionId": "8002", "keys": "1597309277,469931771,1619035792,663887748" }, - { - "regionId": "8003", - "keys": "0,0,0,0" - }, { "regionId": "8004", "keys": "609107948,-755432209,-723012522,1175820911" @@ -488,26 +288,14 @@ "regionId": "8015", "keys": "305015825,-634097708,865786116,-1850059578" }, - { - "regionId": "8016", - "keys": "0,0,0,0" - }, { "regionId": "8017", "keys": "959968310,-363819769,-1402232275,-1678358818" }, - { - "regionId": "8018", - "keys": "0,0,0,0" - }, { "regionId": "8019", "keys": "-1512999074,1064201012,2143076355,-1937376726" }, - { - "regionId": "8020", - "keys": "-955989323,1284433026,690014510,2145912092" - }, { "regionId": "8021", "keys": "-297039986,-1011877372,-1763869337,-900998253" @@ -528,6 +316,14 @@ "regionId": "8241", "keys": "-320813650,-1654452876,-352291520,-290946896" }, + { + "regionId": "8242", + "keys": "347990635,-1017326068,-1600504696,1565374916" + }, + { + "regionId": "8243", + "keys": "-107199068,-843304946,910528064,-626516712" + }, { "regionId": "8251", "keys": "1142567601,1650263019,49659607,-899246535" @@ -580,10 +376,6 @@ "regionId": "8267", "keys": "-474856962,-1295973639,789657650,-1769058462" }, - { - "regionId": "8268", - "keys": "0,0,0,0" - }, { "regionId": "8269", "keys": "-497435078,2028988145,486156819,-1178938803" @@ -604,22 +396,6 @@ "regionId": "8273", "keys": "978831670,664328414,1943273766,-1823800887" }, - { - "regionId": "8274", - "keys": "0,0,0,0" - }, - { - "regionId": "8275", - "keys": "0,0,0,0" - }, - { - "regionId": "8276", - "keys": "0,0,0,0" - }, - { - "regionId": "8277", - "keys": "0,0,0,0" - }, { "regionId": "8280", "keys": "-1615836970,1947387796,2141672540,-333423400" @@ -644,10 +420,6 @@ "regionId": "8499", "keys": "1158999293,2131770333,-861122128,1149793504" }, - { - "regionId": "8500", - "keys": "0,0,0,0" - }, { "regionId": "8506", "keys": "-1227747958,1491928866,1293676120,2065870654" @@ -724,30 +496,14 @@ "regionId": "8530", "keys": "-1466808210,962381183,-1581244207,-457271917" }, - { - "regionId": "8531", - "keys": "0,0,0,0" - }, { "regionId": "8532", "keys": "1553260654,1996107908,-2124357970,1441816370" }, - { - "regionId": "8533", - "keys": "0,0,0,0" - }, { "regionId": "8534", "keys": "1712031920,299813553,484205392,-939092911" }, - { - "regionId": "8545", - "keys": "1322297584,105544016,-1148309508,-574484176" - }, - { - "regionId": "8751", - "keys": "0,0,0,0" - }, { "regionId": "8752", "keys": "238354066,1687454525,1494747147,1911377137" @@ -764,22 +520,6 @@ "regionId": "8755", "keys": "-1165798584,772244190,-402783978,541755309" }, - { - "regionId": "8756", - "keys": "0,0,0,0" - }, - { - "regionId": "8757", - "keys": "0,0,0,0" - }, - { - "regionId": "8759", - "keys": "0,0,0,0" - }, - { - "regionId": "8760", - "keys": "0,0,0,0" - }, { "regionId": "8761", "keys": "1760753095,-1427813077,266675077,-255782653" @@ -804,6 +544,14 @@ "regionId": "8766", "keys": "1244410566,-1397143615,-1848205088,-1435723900" }, + { + "regionId": "8767", + "keys": "-368125809,-1805271492,-400403765,697149536" + }, + { + "regionId": "8768", + "keys": "-517024281,-1363386333,227729042,-1950025355" + }, { "regionId": "8769", "keys": "2044453226,-2064473213,1306128347,784973817" @@ -840,10 +588,6 @@ "regionId": "8779", "keys": "-1680845199,-1149954104,-1177525481,-576614197" }, - { - "regionId": "8780", - "keys": "0,0,0,0" - }, { "regionId": "8781", "keys": "-2133721491,843228961,1706232103,-934369964" @@ -864,34 +608,14 @@ "regionId": "8785", "keys": "1543774040,-487517297,-1630373503,102220753" }, - { - "regionId": "8786", - "keys": "0,0,0,0" - }, { "regionId": "8787", "keys": "1791798624,-1711313280,166719404,-1487207913" }, - { - "regionId": "8788", - "keys": "0,0,0,0" - }, - { - "regionId": "8789", - "keys": "0,0,0,0" - }, { "regionId": "8790", "keys": "230755787,-1139640838,-21592892,49661984" }, - { - "regionId": "9006", - "keys": "0,0,0,0" - }, - { - "regionId": "9007", - "keys": "0,0,0,0" - }, { "regionId": "9008", "keys": "2084752401,-1394447522,2084945842,1474596929" @@ -912,18 +636,6 @@ "regionId": "9012", "keys": "1204696185,-486414605,-1016110497,134649113" }, - { - "regionId": "9013", - "keys": "0,0,0,0" - }, - { - "regionId": "9014", - "keys": "0,0,0,0" - }, - { - "regionId": "9015", - "keys": "0,0,0,0" - }, { "regionId": "9016", "keys": "-1274221467,730617286,-1448054569,427043430" @@ -948,6 +660,14 @@ "regionId": "9021", "keys": "-665917952,-432697139,-602494723,-2097936281" }, + { + "regionId": "9022", + "keys": "1910381678,352194237,836248,347278834" + }, + { + "regionId": "9024", + "keys": "-785865296,-520648067,-1207176889,-441641818" + }, { "regionId": "9025", "keys": "1812159970,1795526437,1172074678,289074337" @@ -976,34 +696,10 @@ "regionId": "9035", "keys": "1525685385,1372975156,-2010144170,-1594192581" }, - { - "regionId": "9036", - "keys": "0,0,0,0" - }, - { - "regionId": "9037", - "keys": "0,0,0,0" - }, { "regionId": "9038", "keys": "-473165893,2110570897,-1726275929,806180444" }, - { - "regionId": "9040", - "keys": "0,0,0,0" - }, - { - "regionId": "9041", - "keys": "0,0,0,0" - }, - { - "regionId": "9042", - "keys": "0,0,0,0" - }, - { - "regionId": "9043", - "keys": "0,0,0,0" - }, { "regionId": "9044", "keys": "1541894861,-2145670115,-138793212,-921922364" @@ -1028,18 +724,6 @@ "regionId": "9050", "keys": "-1725663967,1678055280,1100896300,706957861" }, - { - "regionId": "9109", - "keys": "0,0,0,0" - }, - { - "regionId": "9110", - "keys": "0,0,0,0" - }, - { - "regionId": "9111", - "keys": "0,0,0,0" - }, { "regionId": "9113", "keys": "-570298090,-864625293,-668545435,8389096" @@ -1048,18 +732,6 @@ "regionId": "9114", "keys": "-962790446,-1706163576,82969599,310163719" }, - { - "regionId": "9120", - "keys": "0,0,0,0" - }, - { - "regionId": "9121", - "keys": "0,0,0,0" - }, - { - "regionId": "9122", - "keys": "0,0,0,0" - }, { "regionId": "9262", "keys": "-1327237404,-257519940,-1398355053,-970581711" @@ -1125,21 +797,21 @@ "keys": "272801923,1797149371,-131972865,1265002008" }, { - "regionId": "9283", - "keys": "0,0,0,0" + "regionId": "9278", + "keys": "-1782196006,1021278723,887209787,-1016997291" }, { - "regionId": "9284", - "keys": "0,0,0,0" + "regionId": "9279", + "keys": "-841578670,318269186,-353500843,-932268603" + }, + { + "regionId": "9280", + "keys": "727010382,181752242,1033156911,1262921484" }, { "regionId": "9285", "keys": "1742241898,-1564206342,-460725435,1614032789" }, - { - "regionId": "9286", - "keys": "0,0,0,0" - }, { "regionId": "9287", "keys": "-272431907,639665846,-1633276264,1645937141" @@ -1156,14 +828,6 @@ "regionId": "9290", "keys": "702687456,43635181,-1983533012,-319469910" }, - { - "regionId": "9291", - "keys": "0,0,0,0" - }, - { - "regionId": "9292", - "keys": "0,0,0,0" - }, { "regionId": "9293", "keys": "-810831340,-1857428683,-892017185,249052010" @@ -1176,30 +840,14 @@ "regionId": "9295", "keys": "224580924,-858933614,-432602901,-1433710083" }, - { - "regionId": "9296", - "keys": "0,0,0,0" - }, { "regionId": "9297", "keys": "-1667110403,-655319123,-2124588845,-262291671" }, - { - "regionId": "9298", - "keys": "0,0,0,0" - }, - { - "regionId": "9299", - "keys": "0,0,0,0" - }, { "regionId": "9300", "keys": "644587156,-605721698,681391959,1688865408" }, - { - "regionId": "9301", - "keys": "0,0,0,0" - }, { "regionId": "9304", "keys": "14881828,-6662814,58238456,146761213" @@ -1216,10 +864,6 @@ "regionId": "9362", "keys": "-253025041,376209206,1663580032,1115549308" }, - { - "regionId": "9363", - "keys": "0,0,0,0" - }, { "regionId": "9364", "keys": "1350964684,-1141243546,-158288919,1853454502" @@ -1232,10 +876,6 @@ "regionId": "9366", "keys": "-1691974727,-1591730841,1506117200,822346809" }, - { - "regionId": "9367", - "keys": "0,0,0,0" - }, { "regionId": "9368", "keys": "-911562498,-1433720091,257702084,1652121807" @@ -1256,30 +896,10 @@ "regionId": "9372", "keys": "1005996231,-569567890,-1578994771,-1136932414" }, - { - "regionId": "9376", - "keys": "0,0,0,0" - }, { "regionId": "9377", "keys": "-1671261866,-750153286,1731026368,-1501269926" }, - { - "regionId": "9378", - "keys": "0,0,0,0" - }, - { - "regionId": "9515", - "keys": "0,0,0,0" - }, - { - "regionId": "9516", - "keys": "0,0,0,0" - }, - { - "regionId": "9517", - "keys": "0,0,0,0" - }, { "regionId": "9518", "keys": "-557639005,398566091,-133936467,-850662847" @@ -1344,6 +964,14 @@ "regionId": "9533", "keys": "1393307887,646464303,-1582337843,2048412434" }, + { + "regionId": "9534", + "keys": "-2072244370,1114739695,-1096608867,-1932870993" + }, + { + "regionId": "9535", + "keys": "-1107428972,531677783,-1575581308,1343828898" + }, { "regionId": "9536", "keys": "679931979,-1660801436,-1184954844,-1006016912" @@ -1360,10 +988,6 @@ "regionId": "9541", "keys": "1352006827,1096305726,805420370,-1426885864" }, - { - "regionId": "9542", - "keys": "0,0,0,0" - }, { "regionId": "9543", "keys": "1852273964,-104833248,-2069080639,-188650169" @@ -1384,10 +1008,6 @@ "regionId": "9547", "keys": "-1998382641,30700550,1548517068,-855708219" }, - { - "regionId": "9548", - "keys": "0,0,0,0" - }, { "regionId": "9549", "keys": "-1648136735,1402264941,639592027,348907048" @@ -1408,22 +1028,10 @@ "regionId": "9553", "keys": "-1873675730,-1930195432,759400017,-1395479956" }, - { - "regionId": "9554", - "keys": "0,0,0,0" - }, - { - "regionId": "9555", - "keys": "0,0,0,0" - }, { "regionId": "9556", "keys": "-300312374,-1152515846,-863452271,-1500855067" }, - { - "regionId": "9557", - "keys": "0,0,0,0" - }, { "regionId": "9558", "keys": "1245928204,-1892089406,-1321168410,-1108146443" @@ -1440,10 +1048,6 @@ "regionId": "9562", "keys": "-1047298777,1197811918,663745433,-2098029011" }, - { - "regionId": "9619", - "keys": "0,0,0,0" - }, { "regionId": "9620", "keys": "1941157140,-1630547377,-1114648519,87057467" @@ -1472,18 +1076,6 @@ "regionId": "9626", "keys": "-1411729186,1049744836,-1608961973,-1681145313" }, - { - "regionId": "9627", - "keys": "0,0,0,0" - }, - { - "regionId": "9629", - "keys": "0,0,0,0" - }, - { - "regionId": "9630", - "keys": "0,0,0,0" - }, { "regionId": "9631", "keys": "1266963397,269916041,734658458,725243574" @@ -1492,18 +1084,6 @@ "regionId": "9632", "keys": "1023657558,-2001662423,-46679010,2064543607" }, - { - "regionId": "9633", - "keys": "0,0,0,0" - }, - { - "regionId": "9634", - "keys": "0,0,0,0" - }, - { - "regionId": "9771", - "keys": "0,0,0,0" - }, { "regionId": "9772", "keys": "-1742165439,-1273697376,2055229018,901215817" @@ -1576,6 +1156,10 @@ "regionId": "9789", "keys": "-620749099,528872615,1976629038,667155751" }, + { + "regionId": "9791", + "keys": "-2105683947,1913166182,-1697741730,-25818496" + }, { "regionId": "9792", "keys": "1500471532,1729075639,-304984137,1117230148" @@ -1584,10 +1168,6 @@ "regionId": "9794", "keys": "1788083183,2097372895,1633476682,-589223611" }, - { - "regionId": "9795", - "keys": "0,0,0,0" - }, { "regionId": "9796", "keys": "517509106,-2019799796,1066150754,-676371780" @@ -1596,10 +1176,6 @@ "regionId": "9797", "keys": "672333395,-284721288,262558790,-344798491" }, - { - "regionId": "9798", - "keys": "0,0,0,0" - }, { "regionId": "9799", "keys": "181886191,758691911,810524169,1456599388" @@ -1632,10 +1208,6 @@ "regionId": "9806", "keys": "368995667,940146211,957819918,-761335591" }, - { - "regionId": "9807", - "keys": "0,0,0,0" - }, { "regionId": "9808", "keys": "308766586,-214665927,-1255727041,-1034716346" @@ -1656,10 +1228,6 @@ "regionId": "9812", "keys": "50571970,-1762921782,-1667424270,524742325" }, - { - "regionId": "9813", - "keys": "0,0,0,0" - }, { "regionId": "9814", "keys": "-34428628,1940609264,-1638642159,-295486604" @@ -1704,38 +1272,14 @@ "regionId": "9883", "keys": "472234846,1198089044,500187071,239458328" }, - { - "regionId": "9884", - "keys": "0,0,0,0" - }, - { - "regionId": "9885", - "keys": "0,0,0,0" - }, { "regionId": "9886", "keys": "1515209815,-1457146379,-146402808,-1454274033" }, - { - "regionId": "9887", - "keys": "0,0,0,0" - }, - { - "regionId": "9888", - "keys": "0,0,0,0" - }, - { - "regionId": "9889", - "keys": "0,0,0,0" - }, { "regionId": "10027", "keys": "1491811841,1724263915,-1397066186,1733646819" }, - { - "regionId": "10028", - "keys": "0,0,0,0" - }, { "regionId": "10029", "keys": "203145796,-773666188,-569831878,-1510455793" @@ -1760,10 +1304,6 @@ "regionId": "10034", "keys": "-1435464304,-836439389,-788586899,1579582706" }, - { - "regionId": "10035", - "keys": "0,0,0,0" - }, { "regionId": "10036", "keys": "689954852,-1377739344,-847433475,-1883927289" @@ -1804,26 +1344,18 @@ "regionId": "10045", "keys": "-1429464298,1580360509,-1936477065,-337842786" }, + { + "regionId": "10046", + "keys": "1579643227,-1819574910,1035634488,-1469908551" + }, + { + "regionId": "10047", + "keys": "1248461784,913422340,-928862457,-1858877253" + }, { "regionId": "10048", "keys": "-1457016886,349941309,-400267403,-1711584223" }, - { - "regionId": "10051", - "keys": "0,0,0,0" - }, - { - "regionId": "10052", - "keys": "0,0,0,0" - }, - { - "regionId": "10053", - "keys": "0,0,0,0" - }, - { - "regionId": "10054", - "keys": "0,0,0,0" - }, { "regionId": "10055", "keys": "-813287484,-1417786621,-1794468339,578992617" @@ -1844,10 +1376,6 @@ "regionId": "10059", "keys": "1185163869,-1047826729,-1461057337,139139001" }, - { - "regionId": "10060", - "keys": "0,0,0,0" - }, { "regionId": "10061", "keys": "1683880127,1851133137,-567572662,-1477799312" @@ -1856,10 +1384,6 @@ "regionId": "10062", "keys": "2024717410,-1807032706,1106507805,1426160484" }, - { - "regionId": "10063", - "keys": "0,0,0,0" - }, { "regionId": "10064", "keys": "1978019309,1433546802,-1989346624,-1611361553" @@ -1872,10 +1396,6 @@ "regionId": "10066", "keys": "105954939,-1741244981,-1491777272,207112205" }, - { - "regionId": "10067", - "keys": "0,0,0,0" - }, { "regionId": "10068", "keys": "-452138979,-1929816521,364996963,-1315825295" @@ -1952,26 +1472,14 @@ "regionId": "10140", "keys": "-104825447,-1092637213,-105814713,-2129567531" }, - { - "regionId": "10141", - "keys": "0,0,0,0" - }, { "regionId": "10142", "keys": "1872120942,-765842959,449655176,-1168971827" }, - { - "regionId": "10143", - "keys": "0,0,0,0" - }, { "regionId": "10144", "keys": "265530509,2033515489,-2022406749,-591072091" }, - { - "regionId": "10145", - "keys": "0,0,0,0" - }, { "regionId": "10280", "keys": "-1245893544,-118079793,-1624599660,-626968532" @@ -1988,10 +1496,6 @@ "regionId": "10283", "keys": "-2133080221,1327669620,173304076,-151662318" }, - { - "regionId": "10284", - "keys": "0,0,0,0" - }, { "regionId": "10285", "keys": "-1317120534,1321149083,-1700628824,1028203235" @@ -2016,10 +1520,6 @@ "regionId": "10290", "keys": "-587752684,-318735232,336724431,-1931735346" }, - { - "regionId": "10291", - "keys": "0,0,0,0" - }, { "regionId": "10292", "keys": "933507835,1135929795,-1932059890,1492191263" @@ -2108,10 +1608,6 @@ "regionId": "10315", "keys": "-1034094191,1810212216,618808107,1905492210" }, - { - "regionId": "10316", - "keys": "0,0,0,0" - }, { "regionId": "10317", "keys": "216403117,1910251124,144162918,224240414" @@ -2120,14 +1616,6 @@ "regionId": "10318", "keys": "1053988597,-2121917140,1730755899,1549334321" }, - { - "regionId": "10319", - "keys": "0,0,0,0" - }, - { - "regionId": "10320", - "keys": "0,0,0,0" - }, { "regionId": "10321", "keys": "1996825886,-1552231723,1721080145,-869420516" @@ -2136,18 +1624,10 @@ "regionId": "10322", "keys": "1773602876,-1410394076,-239593243,148286798" }, - { - "regionId": "10323", - "keys": "0,0,0,0" - }, { "regionId": "10324", "keys": "-1670587478,-401532783,1705875521,995683837" }, - { - "regionId": "10325", - "keys": "0,0,0,0" - }, { "regionId": "10326", "keys": "-375687378,472100528,-288941184,523344380" @@ -2208,26 +1688,10 @@ "regionId": "10396", "keys": "-1878072140,1648991920,1054624070,333445417" }, - { - "regionId": "10397", - "keys": "0,0,0,0" - }, - { - "regionId": "10398", - "keys": "0,0,0,0" - }, - { - "regionId": "10399", - "keys": "0,0,0,0" - }, { "regionId": "10400", "keys": "-1656816922,1318311812,-811481661,1625916625" }, - { - "regionId": "10401", - "keys": "0,0,0,0" - }, { "regionId": "10536", "keys": "349537117,1202512092,-698870718,-2083455397" @@ -2272,10 +1736,6 @@ "regionId": "10546", "keys": "192659093,263441429,29086759,670094037" }, - { - "regionId": "10547", - "keys": "0,0,0,0" - }, { "regionId": "10548", "keys": "-1157394711,-1306553144,2105373539,798383108" @@ -2332,10 +1792,6 @@ "regionId": "10564", "keys": "1279522133,380240348,604239496,1759916207" }, - { - "regionId": "10565", - "keys": "0,0,0,0" - }, { "regionId": "10566", "keys": "221004409,1368318650,-1237341956,25411913" @@ -2364,10 +1820,6 @@ "regionId": "10572", "keys": "-1375061166,-1411427241,-294467489,-2106748278" }, - { - "regionId": "10573", - "keys": "0,0,0,0" - }, { "regionId": "10574", "keys": "-1609693854,991245740,148787249,-1011766477" @@ -2376,10 +1828,6 @@ "regionId": "10575", "keys": "434036980,-780702800,-1042242727,-354464628" }, - { - "regionId": "10576", - "keys": "0,0,0,0" - }, { "regionId": "10577", "keys": "824897954,-1807466644,2079017570,1299975025" @@ -2393,12 +1841,8 @@ "keys": "-123618550,684067223,486273630,-1103816964" }, { - "regionId": "10580", - "keys": "0,0,0,0" - }, - { - "regionId": "10637", - "keys": "0,0,0,0" + "regionId": "10583", + "keys": "14881828,-6662814,58238456,146761213" }, { "regionId": "10638", @@ -2448,10 +1892,6 @@ "regionId": "10650", "keys": "-908578223,-911827513,1137573080,-419444146" }, - { - "regionId": "10651", - "keys": "0,0,0,0" - }, { "regionId": "10652", "keys": "1580722385,609745227,1407021351,1098485033" @@ -2460,22 +1900,6 @@ "regionId": "10653", "keys": "570189753,-1700559836,2108215671,-701775893" }, - { - "regionId": "10654", - "keys": "0,0,0,0" - }, - { - "regionId": "10655", - "keys": "0,0,0,0" - }, - { - "regionId": "10656", - "keys": "0,0,0,0" - }, - { - "regionId": "10657", - "keys": "0,0,0,0" - }, { "regionId": "10792", "keys": "-125671574,254943715,1343095705,-1965171670" @@ -2516,10 +1940,6 @@ "regionId": "10801", "keys": "850125851,1199386038,-1494136472,-1487577933" }, - { - "regionId": "10802", - "keys": "0,0,0,0" - }, { "regionId": "10803", "keys": "-1028081880,964144306,174845257,1906118817" @@ -2572,6 +1992,10 @@ "regionId": "10815", "keys": "2102925673,1133406202,-1885710196,165240951" }, + { + "regionId": "10816", + "keys": "-1909517714,218137505,744896894,831968418" + }, { "regionId": "10819", "keys": "-904401587,-2054970579,55120674,-1889562804" @@ -2612,10 +2036,6 @@ "regionId": "10828", "keys": "1665018619,-1607107877,-1997272567,1342325223" }, - { - "regionId": "10829", - "keys": "0,0,0,0" - }, { "regionId": "10830", "keys": "-608096960,58771202,1174291927,-1613596249" @@ -2636,18 +2056,10 @@ "regionId": "10834", "keys": "-1640569486,-512141704,-1179536382,720004469" }, - { - "regionId": "10835", - "keys": "0,0,0,0" - }, { "regionId": "10836", "keys": "1637505449,619992365,-1935536269,-1526242295" }, - { - "regionId": "10837", - "keys": "0,0,0,0" - }, { "regionId": "10838", "keys": "1678881362,-952862831,-1804688659,-1247653912" @@ -2744,10 +2156,6 @@ "regionId": "10911", "keys": "948965123,-545528654,-459191491,-860302360" }, - { - "regionId": "10912", - "keys": "0,0,0,0" - }, { "regionId": "11049", "keys": "-621090199,-1004888612,-749707219,2052444337" @@ -2872,30 +2280,14 @@ "regionId": "11083", "keys": "1255503855,-674022312,-807132804,-1287799121" }, - { - "regionId": "11084", - "keys": "0,0,0,0" - }, { "regionId": "11085", "keys": "327229160,-1433790638,1944433240,234034136" }, - { - "regionId": "11086", - "keys": "0,0,0,0" - }, - { - "regionId": "11087", - "keys": "0,0,0,0" - }, { "regionId": "11088", "keys": "-1943123304,1713176080,-1524844090,-445387865" }, - { - "regionId": "11089", - "keys": "0,0,0,0" - }, { "regionId": "11090", "keys": "2089067081,828176382,-1112393031,-1452165920" @@ -2904,10 +2296,6 @@ "regionId": "11091", "keys": "977844365,-245927723,99303766,-735341354" }, - { - "regionId": "11092", - "keys": "0,0,0,0" - }, { "regionId": "11093", "keys": "-379710910,-2088433559,1180928189,-54938349" @@ -2972,14 +2360,6 @@ "regionId": "11158", "keys": "160361538,733169435,1244326761,1681727551" }, - { - "regionId": "11159", - "keys": "0,0,0,0" - }, - { - "regionId": "11160", - "keys": "0,0,0,0" - }, { "regionId": "11161", "keys": "-1713920755,1291269906,320754968,741637543" @@ -3008,10 +2388,6 @@ "regionId": "11167", "keys": "-1735216162,2141149053,57787230,-1263840909" }, - { - "regionId": "11168", - "keys": "0,0,0,0" - }, { "regionId": "11305", "keys": "-1429346525,-118378130,1002549662,1383588995" @@ -3088,10 +2464,6 @@ "regionId": "11323", "keys": "-1710808226,725482732,1863997544,5983834" }, - { - "regionId": "11324", - "keys": "0,0,0,0" - }, { "regionId": "11326", "keys": "1862093150,1696245244,1320714102,1241887579" @@ -3108,30 +2480,14 @@ "regionId": "11332", "keys": "-936631483,-1093055133,-161202591,-1476364681" }, - { - "regionId": "11333", - "keys": "0,0,0,0" - }, - { - "regionId": "11334", - "keys": "0,0,0,0" - }, { "regionId": "11335", "keys": "-133492081,-915358326,-714649892,-2093709476" }, - { - "regionId": "11338", - "keys": "0,0,0,0" - }, { "regionId": "11339", "keys": "140118336,-1920268877,-1967576060,-1437209189" }, - { - "regionId": "11340", - "keys": "0,0,0,0" - }, { "regionId": "11341", "keys": "-1219163353,-1635920416,-2124217842,-1318908036" @@ -3152,14 +2508,6 @@ "regionId": "11347", "keys": "-122396964,-1996200666,-585000602,-863390951" }, - { - "regionId": "11348", - "keys": "0,0,0,0" - }, - { - "regionId": "11349", - "keys": "0,0,0,0" - }, { "regionId": "11350", "keys": "-1365557009,-1350738529,-1074800707,-446118748" @@ -3184,22 +2532,10 @@ "regionId": "11356", "keys": "2033204014,1416145849,-1721330996,2134394884" }, - { - "regionId": "11405", - "keys": "0,0,0,0" - }, { "regionId": "11406", "keys": "375301159,353365492,-940259891,-223647771" }, - { - "regionId": "11407", - "keys": "0,0,0,0" - }, - { - "regionId": "11408", - "keys": "0,0,0,0" - }, { "regionId": "11409", "keys": "1937092760,-1545935537,29954084,-1081016062" @@ -3208,10 +2544,6 @@ "regionId": "11410", "keys": "1509299526,-892391942,1485831814,1255407038" }, - { - "regionId": "11411", - "keys": "0,0,0,0" - }, { "regionId": "11412", "keys": "-1379772393,621580805,-316850307,1026773740" @@ -3316,10 +2648,6 @@ "regionId": "11572", "keys": "892185929,686162443,1793819023,-992991976" }, - { - "regionId": "11573", - "keys": "0,0,0,0" - }, { "regionId": "11574", "keys": "-1406155502,13961326,1071473330,1528558089" @@ -3336,22 +2664,10 @@ "regionId": "11577", "keys": "1283493672,1550135524,-1621670256,769418438" }, - { - "regionId": "11578", - "keys": "0,0,0,0" - }, { "regionId": "11579", "keys": "-719996638,-1831948234,494156672,1684753309" }, - { - "regionId": "11580", - "keys": "0,0,0,0" - }, - { - "regionId": "11581", - "keys": "0,0,0,0" - }, { "regionId": "11582", "keys": "602331327,-1036793753,1702673112,-1107214996" @@ -3376,18 +2692,10 @@ "regionId": "11589", "keys": "39678032,469576041,-1878694956,-1720799345" }, - { - "regionId": "11590", - "keys": "0,0,0,0" - }, { "regionId": "11591", "keys": "1300749474,-912770362,-1665451776,480747745" }, - { - "regionId": "11592", - "keys": "0,0,0,0" - }, { "regionId": "11593", "keys": "14881828,-6662814,58238456,146761213" @@ -3400,26 +2708,14 @@ "regionId": "11595", "keys": "-1497259084,-1208341848,874209282,-1950133061" }, - { - "regionId": "11596", - "keys": "0,0,0,0" - }, { "regionId": "11597", "keys": "-824244627,-1750674106,-2032396270,-451550546" }, - { - "regionId": "11598", - "keys": "0,0,0,0" - }, { "regionId": "11599", "keys": "-1124938025,110281395,-1121479364,68953473" }, - { - "regionId": "11600", - "keys": "0,0,0,0" - }, { "regionId": "11601", "keys": "722657934,1495340205,-437272583,-1331954618" @@ -3432,10 +2728,6 @@ "regionId": "11603", "keys": "-254635141,-1757221941,-2072225761,-752948578" }, - { - "regionId": "11604", - "keys": "0,0,0,0" - }, { "regionId": "11605", "keys": "57037316,1119657363,2040370510,801474589" @@ -3444,10 +2736,6 @@ "regionId": "11606", "keys": "-1790275662,-1050505330,-1496410655,679769180" }, - { - "regionId": "11607", - "keys": "0,0,0,0" - }, { "regionId": "11608", "keys": "248039728,1861834308,1335200688,317723667" @@ -3456,10 +2744,6 @@ "regionId": "11609", "keys": "-1581925228,-215021003,-1695323698,-1853661356" }, - { - "regionId": "11610", - "keys": "0,0,0,0" - }, { "regionId": "11612", "keys": "-1751954695,954770889,-337304771,986015401" @@ -3564,14 +2848,6 @@ "regionId": "11824", "keys": "-1116727390,-659788658,307002260,354360287" }, - { - "regionId": "11825", - "keys": "0,0,0,0" - }, - { - "regionId": "11826", - "keys": "0,0,0,0" - }, { "regionId": "11827", "keys": "379001889,1835230493,1861106702,338991847" @@ -3632,42 +2908,10 @@ "regionId": "11844", "keys": "46502425,-1301719099,-1597781617,1434487073" }, - { - "regionId": "11845", - "keys": "0,0,0,0" - }, - { - "regionId": "11846", - "keys": "0,0,0,0" - }, - { - "regionId": "11847", - "keys": "0,0,0,0" - }, - { - "regionId": "11848", - "keys": "0,0,0,0" - }, - { - "regionId": "11849", - "keys": "0,0,0,0" - }, - { - "regionId": "11850", - "keys": "0,0,0,0" - }, { "regionId": "11851", "keys": "-516358140,791692293,-1663509747,1243508195" }, - { - "regionId": "11852", - "keys": "0,0,0,0" - }, - { - "regionId": "11853", - "keys": "0,0,0,0" - }, { "regionId": "11854", "keys": "311566497,-486013229,1351929142,744327317" @@ -3676,30 +2920,10 @@ "regionId": "11855", "keys": "770787544,-1305958539,670684335,208100825" }, - { - "regionId": "11856", - "keys": "0,0,0,0" - }, { "regionId": "11857", "keys": "150488681,419659968,-1871963555,1031596369" }, - { - "regionId": "11858", - "keys": "0,0,0,0" - }, - { - "regionId": "11859", - "keys": "0,0,0,0" - }, - { - "regionId": "11860", - "keys": "0,0,0,0" - }, - { - "regionId": "11861", - "keys": "0,0,0,0" - }, { "regionId": "11862", "keys": "2071521092,797384499,364423664,-1286422461" @@ -3744,10 +2968,6 @@ "regionId": "11926", "keys": "-501586879,235710413,-1122707717,-354940885" }, - { - "regionId": "11927", - "keys": "0,0,0,0" - }, { "regionId": "11928", "keys": "-445378710,-788377286,1363332226,627739779" @@ -3760,18 +2980,6 @@ "regionId": "11930", "keys": "1436132147,-902725534,590285278,2018675988" }, - { - "regionId": "11931", - "keys": "0,0,0,0" - }, - { - "regionId": "11932", - "keys": "0,0,0,0" - }, - { - "regionId": "11933", - "keys": "0,0,0,0" - }, { "regionId": "11934", "keys": "-854127330,1609124159,-999989310,-734721734" @@ -3780,22 +2988,10 @@ "regionId": "11935", "keys": "-1453725493,-1575973068,1979334907,1130399929" }, - { - "regionId": "11936", - "keys": "0,0,0,0" - }, { "regionId": "11937", "keys": "-1518927827,1819850502,-992647105,299958470" }, - { - "regionId": "11938", - "keys": "0,0,0,0" - }, - { - "regionId": "12073", - "keys": "-882281631,257910959,1642484329,-1342807140" - }, { "regionId": "12076", "keys": "193939514,-115011236,-1406304015,-1626342231" @@ -3876,26 +3072,10 @@ "regionId": "12097", "keys": "-862465947,2109948185,583246321,-850147469" }, - { - "regionId": "12098", - "keys": "0,0,0,0" - }, - { - "regionId": "12099", - "keys": "0,0,0,0" - }, { "regionId": "12100", "keys": "1852910519,712916664,1670787779,1294835477" }, - { - "regionId": "12101", - "keys": "0,0,0,0" - }, - { - "regionId": "12102", - "keys": "14881828,-6662814,58238456,146761213" - }, { "regionId": "12105", "keys": "1153497516,-449169462,-635419798,-1471828315" @@ -3924,10 +3104,6 @@ "regionId": "12111", "keys": "-746445771,1759120362,1253848335,1433199232" }, - { - "regionId": "12112", - "keys": "0,0,0,0" - }, { "regionId": "12113", "keys": "-1749952613,1569535680,1900425482,-1993748284" @@ -3936,10 +3112,6 @@ "regionId": "12115", "keys": "2146362785,1996258091,-613445101,539756591" }, - { - "regionId": "12116", - "keys": "0,0,0,0" - }, { "regionId": "12117", "keys": "-97063310,1962833557,-849078816,-1560293275" @@ -3976,10 +3148,6 @@ "regionId": "12182", "keys": "-499997333,1910872683,-234510566,-361238419" }, - { - "regionId": "12183", - "keys": "0,0,0,0" - }, { "regionId": "12184", "keys": "-1993918550,1977224805,-1048356116,-1578331413" @@ -3992,10 +3160,6 @@ "regionId": "12186", "keys": "-259674875,-949495016,1835821953,1740556829" }, - { - "regionId": "12187", - "keys": "0,0,0,0" - }, { "regionId": "12188", "keys": "22801476,-1237575758,2139201694,-163382547" @@ -4004,26 +3168,10 @@ "regionId": "12189", "keys": "-626419958,-861781849,-400257621,465575053" }, - { - "regionId": "12191", - "keys": "0,0,0,0" - }, - { - "regionId": "12192", - "keys": "0,0,0,0" - }, { "regionId": "12193", "keys": "1013552068,-364826455,4137749,729786125" }, - { - "regionId": "12194", - "keys": "0,0,0,0" - }, - { - "regionId": "12332", - "keys": "0,0,0,0" - }, { "regionId": "12333", "keys": "372281878,-809369100,-1989039261,-980074402" @@ -4112,54 +3260,18 @@ "regionId": "12356", "keys": "-1201681208,106398334,-2123418385,1010672418" }, - { - "regionId": "12362", - "keys": "0,0,0,0" - }, - { - "regionId": "12363", - "keys": "0,0,0,0" - }, - { - "regionId": "12364", - "keys": "0,0,0,0" - }, - { - "regionId": "12365", - "keys": "0,0,0,0" - }, - { - "regionId": "12366", - "keys": "0,0,0,0" - }, { "regionId": "12367", "keys": "-2006617355,-1390093250,-1950318553,1842364433" }, - { - "regionId": "12368", - "keys": "0,0,0,0" - }, { "regionId": "12369", "keys": "-891954120,1710352781,-1883639556,-1461026236" }, - { - "regionId": "12372", - "keys": "0,0,0,0" - }, - { - "regionId": "12373", - "keys": "0,0,0,0" - }, { "regionId": "12374", "keys": "1620519366,-1309341299,68411383,1308746010" }, - { - "regionId": "12375", - "keys": "0,0,0,0" - }, { "regionId": "12376", "keys": "1918934265,1530066885,-1991367516,1783839145" @@ -4204,38 +3316,10 @@ "regionId": "12442", "keys": "1883167946,191149821,-1270401415,-126025128" }, - { - "regionId": "12443", - "keys": "0,0,0,0" - }, { "regionId": "12444", "keys": "1576354846,-1768236409,821965805,-861456742" }, - { - "regionId": "12447", - "keys": "0,0,0,0" - }, - { - "regionId": "12448", - "keys": "0,0,0,0" - }, - { - "regionId": "12449", - "keys": "0,0,0,0" - }, - { - "regionId": "12450", - "keys": "0,0,0,0" - }, - { - "regionId": "12587", - "keys": "0,0,0,0" - }, - { - "regionId": "12588", - "keys": "0,0,0,0" - }, { "regionId": "12589", "keys": "1981659006,1591583400,1958084245,667979721" @@ -4324,10 +3408,6 @@ "regionId": "12614", "keys": "1621048325,1179863793,357058137,-1896311701" }, - { - "regionId": "12615", - "keys": "0,0,0,0" - }, { "regionId": "12616", "keys": "1951523008,-2131232747,-381301931,2007660709" @@ -4340,26 +3420,14 @@ "regionId": "12619", "keys": "1922733696,773456556,-1923866275,-1305839916" }, - { - "regionId": "12620", - "keys": "0,0,0,0" - }, { "regionId": "12621", "keys": "1619333755,-1869146576,77302288,-937694202" }, - { - "regionId": "12622", - "keys": "0,0,0,0" - }, { "regionId": "12623", "keys": "-369583241,545715110,-134871454,1404138108" }, - { - "regionId": "12624", - "keys": "0,0,0,0" - }, { "regionId": "12625", "keys": "-260562230,1208275247,436993278,30028881" @@ -4380,18 +3448,6 @@ "regionId": "12631", "keys": "693308333,-269450306,-924437218,309489139" }, - { - "regionId": "12632", - "keys": "0,0,0,0" - }, - { - "regionId": "12633", - "keys": "0,0,0,0" - }, - { - "regionId": "12634", - "keys": "0,0,0,0" - }, { "regionId": "12688", "keys": "1861636222,1638403446,-649444098,2131977195" @@ -4408,10 +3464,6 @@ "regionId": "12691", "keys": "-998717750,-178246764,973015517,-1732934591" }, - { - "regionId": "12692", - "keys": "0,0,0,0" - }, { "regionId": "12693", "keys": "1339198001,799729854,-750687990,1703141753" @@ -4420,10 +3472,6 @@ "regionId": "12694", "keys": "631068451,-510806123,2026757696,207332608" }, - { - "regionId": "12695", - "keys": "0,0,0,0" - }, { "regionId": "12696", "keys": "690970369,-466418236,-666391415,1091047140" @@ -4444,10 +3492,6 @@ "regionId": "12700", "keys": "-1802430094,1220107446,-1897971895,-1437873968" }, - { - "regionId": "12842", - "keys": "0,0,0,0" - }, { "regionId": "12843", "keys": "-203885401,22803731,234561826,140244374" @@ -4476,22 +3520,6 @@ "regionId": "12849", "keys": "183396243,-461663209,-212681663,-266126212" }, - { - "regionId": "12850", - "keys": "0,0,0,0" - }, - { - "regionId": "12851", - "keys": "0,0,0,0" - }, - { - "regionId": "12852", - "keys": "0,0,0,0" - }, - { - "regionId": "12853", - "keys": "0,0,0,0" - }, { "regionId": "12854", "keys": "-648789394,672092351,713515997,1153393095" @@ -4541,24 +3569,12 @@ "keys": "1462732309,395803116,803023666,-1139113006" }, { - "regionId": "12874", - "keys": "0,0,0,0" + "regionId": "12869", + "keys": "14881828,-6662814,58238456,146761213" }, { - "regionId": "12875", - "keys": "0,0,0,0" - }, - { - "regionId": "12876", - "keys": "0,0,0,0" - }, - { - "regionId": "12877", - "keys": "0,0,0,0" - }, - { - "regionId": "12878", - "keys": "0,0,0,0" + "regionId": "12870", + "keys": "14881828,-6662814,58238456,146761213" }, { "regionId": "12879", @@ -4636,10 +3652,6 @@ "regionId": "12956", "keys": "-1383918319,-1190517730,-1037058957,534994622" }, - { - "regionId": "13098", - "keys": "0,0,0,0" - }, { "regionId": "13099", "keys": "919393388,-1011543647,454982828,-809340931" @@ -4664,14 +3676,6 @@ "regionId": "13104", "keys": "-421493992,1381068261,1710426242,2142500778" }, - { - "regionId": "13105", - "keys": "0,0,0,0" - }, - { - "regionId": "13106", - "keys": "0,0,0,0" - }, { "regionId": "13107", "keys": "-1161498786,-880845643,1588242926,2124040528" @@ -4732,34 +3736,18 @@ "regionId": "13126", "keys": "1732039952,536833573,-81136437,1031070663" }, - { - "regionId": "13130", - "keys": "0,0,0,0" - }, { "regionId": "13131", "keys": "-1234145533,479347649,1835828804,1685593501" }, - { - "regionId": "13132", - "keys": "0,0,0,0" - }, { "regionId": "13133", "keys": "-1026003062,917176839,-84576515,-1037395862" }, - { - "regionId": "13134", - "keys": "0,0,0,0" - }, { "regionId": "13135", "keys": "425723212,580084357,1788364975,1608414630" }, - { - "regionId": "13136", - "keys": "0,0,0,0" - }, { "regionId": "13138", "keys": "14881828,-6662814,58238456,146761213" @@ -4800,10 +3788,6 @@ "regionId": "13203", "keys": "-1342258113,-2106603709,395365404,-973258459" }, - { - "regionId": "13204", - "keys": "0,0,0,0" - }, { "regionId": "13205", "keys": "1250202258,-2009534633,1981493488,10068968" @@ -4812,14 +3796,6 @@ "regionId": "13206", "keys": "1456157358,1036496685,-1478577110,-1039552689" }, - { - "regionId": "13207", - "keys": "0,0,0,0" - }, - { - "regionId": "13208", - "keys": "0,0,0,0" - }, { "regionId": "13209", "keys": "-441828435,-1834839387,-1652863357,1161715526" @@ -4928,30 +3904,10 @@ "regionId": "13387", "keys": "50769406,1445159687,1657343198,-1977600563" }, - { - "regionId": "13388", - "keys": "0,0,0,0" - }, - { - "regionId": "13389", - "keys": "0,0,0,0" - }, { "regionId": "13393", "keys": "14881828,-6662814,58238456,146761213" }, - { - "regionId": "13397", - "keys": "0,0,0,0" - }, - { - "regionId": "13398", - "keys": "0,0,0,0" - }, - { - "regionId": "13399", - "keys": "0,0,0,0" - }, { "regionId": "13456", "keys": "-476100316,-1682296770,133855524,112315923" @@ -4996,10 +3952,6 @@ "regionId": "13466", "keys": "-460228398,-76181685,2062962515,1167974062" }, - { - "regionId": "13467", - "keys": "0,0,0,0" - }, { "regionId": "13610", "keys": "-1259340500,2094890289,-1255134464,1578867778" @@ -5048,10 +4000,6 @@ "regionId": "13621", "keys": "-1291167236,-1205011126,-1949699235,1530879202" }, - { - "regionId": "13622", - "keys": "0,0,0,0" - }, { "regionId": "13623", "keys": "-1700397822,-1427942931,1638091118,438962861" @@ -5096,10 +4044,6 @@ "regionId": "13643", "keys": "1113875885,-236852397,193142585,-854043613" }, - { - "regionId": "13644", - "keys": "0,0,0,0" - }, { "regionId": "13650", "keys": "-1281992532,-252178835,-207196406,32900092" @@ -5112,10 +4056,6 @@ "regionId": "13713", "keys": "676853493,-1887443315,-998811191,1947183065" }, - { - "regionId": "13715", - "keys": "0,0,0,0" - }, { "regionId": "13716", "keys": "-913580283,340446282,893998558,589419388" @@ -5140,10 +4080,6 @@ "regionId": "13721", "keys": "-1188425330,1307846097,888707126,-1843934128" }, - { - "regionId": "13722", - "keys": "0,0,0,0" - }, { "regionId": "13723", "keys": "-310574621,110640497,1685108265,-1931806505" @@ -5160,18 +4096,6 @@ "regionId": "13868", "keys": "255205616,-1585903009,-1371243067,-264891948" }, - { - "regionId": "13869", - "keys": "0,0,0,0" - }, - { - "regionId": "13870", - "keys": "0,0,0,0" - }, - { - "regionId": "13871", - "keys": "0,0,0,0" - }, { "regionId": "13872", "keys": "-865041276,1374390842,-909885942,30088570" @@ -5196,10 +4120,6 @@ "regionId": "13877", "keys": "1498185652,2064367906,152992439,585271079" }, - { - "regionId": "13878", - "keys": "0,0,0,0" - }, { "regionId": "13879", "keys": "-2101514338,-1139447054,51825149,-512907347" @@ -5220,18 +4140,6 @@ "regionId": "13899", "keys": "-2117805741,-268051413,-733527930,471010998" }, - { - "regionId": "13900", - "keys": "0,0,0,0" - }, - { - "regionId": "13901", - "keys": "0,0,0,0" - }, - { - "regionId": "13902", - "keys": "0,0,0,0" - }, { "regionId": "13905", "keys": "14881828,-6662814,58238456,146761213" @@ -5240,18 +4148,10 @@ "regionId": "13968", "keys": "-620062336,-1110235330,-1095431209,-470716307" }, - { - "regionId": "13971", - "keys": "0,0,0,0" - }, { "regionId": "13972", "keys": "1266294685,1139088638,1514900183,-1389022839" }, - { - "regionId": "13973", - "keys": "0,0,0,0" - }, { "regionId": "13974", "keys": "1384510929,1857691725,-293821029,-1219099456" @@ -5280,10 +4180,6 @@ "regionId": "13980", "keys": "-12957944,-743456598,2041601862,618819565" }, - { - "regionId": "14127", - "keys": "0,0,0,0" - }, { "regionId": "14128", "keys": "1907787432,-241593923,1152767085,-541422403" @@ -5320,26 +4216,10 @@ "regionId": "14136", "keys": "-1104533465,1792124817,-1564247177,79706641" }, - { - "regionId": "14154", - "keys": "0,0,0,0" - }, - { - "regionId": "14155", - "keys": "0,0,0,0" - }, - { - "regionId": "14156", - "keys": "0,0,0,0" - }, { "regionId": "14157", "keys": "-852479713,1901063521,-1097484894,1013793379" }, - { - "regionId": "14158", - "keys": "0,0,0,0" - }, { "regionId": "14161", "keys": "14881828,-6662814,58238456,146761213" @@ -5348,18 +4228,6 @@ "regionId": "14167", "keys": "-1398455,-469478596,190482870,-1233173597" }, - { - "regionId": "14227", - "keys": "0,0,0,0" - }, - { - "regionId": "14228", - "keys": "0,0,0,0" - }, - { - "regionId": "14229", - "keys": "0,0,0,0" - }, { "regionId": "14230", "keys": "-453901412,-2074594443,-809419406,1774073603" @@ -5388,6 +4256,10 @@ "regionId": "14236", "keys": "816141215,-2114312227,1578950035,1471842311" }, + { + "regionId": "14380", + "keys": "1663518625,-107913441,-1625821936,330353351" + }, { "regionId": "14381", "keys": "-534048527,1614741928,-469012711,1064350100" @@ -5420,10 +4292,6 @@ "regionId": "14388", "keys": "2048238173,2003642395,1658667134,411519881" }, - { - "regionId": "14389", - "keys": "0,0,0,0" - }, { "regionId": "14390", "keys": "-1631704360,1281079278,-1549067757,-2034268623" @@ -5436,18 +4304,6 @@ "regionId": "14392", "keys": "993603906,-1477196579,593064486,166369140" }, - { - "regionId": "14412", - "keys": "0,0,0,0" - }, - { - "regionId": "14413", - "keys": "0,0,0,0" - }, - { - "regionId": "14414", - "keys": "0,0,0,0" - }, { "regionId": "14486", "keys": "-131982139,-1189975142,-1667401999,-1794787704" @@ -5456,14 +4312,6 @@ "regionId": "14487", "keys": "-330478679,11506767,395036194,-971774384" }, - { - "regionId": "14488", - "keys": "0,0,0,0" - }, - { - "regionId": "14489", - "keys": "0,0,0,0" - }, { "regionId": "14490", "keys": "1578682567,-1175551739,170259358,-1972709096" @@ -5476,6 +4324,10 @@ "regionId": "14492", "keys": "420310205,1004898846,889537686,13961361" }, + { + "regionId": "14636", + "keys": "-1554034534,-545576842,-416921234,1887723532" + }, { "regionId": "14637", "keys": "112774068,-1867270219,-442076728,-1436438131" @@ -5496,10 +4348,6 @@ "regionId": "14641", "keys": "-310201697,1724559662,90126688,-664432561" }, - { - "regionId": "14645", - "keys": "0,0,0,0" - }, { "regionId": "14646", "keys": "-2069357113,-2117603296,1620573021,-239596308" @@ -5512,10 +4360,6 @@ "regionId": "14648", "keys": "-1757352130,-1996516705,263017190,1647356258" }, - { - "regionId": "14745", - "keys": "0,0,0,0" - }, { "regionId": "14746", "keys": "2081288932,-143900986,-1978370486,-544919360" @@ -5548,10 +4392,6 @@ "regionId": "14896", "keys": "548765086,801664009,-1716752945,-1492954302" }, - { - "regionId": "14901", - "keys": "0,0,0,0" - }, { "regionId": "14902", "keys": "1158948283,-12013143,1242958376,-1265402384" @@ -5572,26 +4412,10 @@ "regionId": "14995", "keys": "958328498,239876404,608758325,933929091" }, - { - "regionId": "15001", - "keys": "0,0,0,0" - }, - { - "regionId": "15002", - "keys": "0,0,0,0" - }, - { - "regionId": "15003", - "keys": "0,0,0,0" - }, { "regionId": "15147", "keys": "-423978185,359589519,280220972,-1608470374" }, - { - "regionId": "15148", - "keys": "0,0,0,0" - }, { "regionId": "15149", "keys": "-1200628316,15132614,-465260385,-1525542932" diff --git a/Server/pom.xml b/Server/pom.xml index f3cc5f0ac..5c93c44d2 100644 --- a/Server/pom.xml +++ b/Server/pom.xml @@ -6,6 +6,7 @@ 1.0.0 core.Server + UTF-8 true 1.8.20 11 @@ -90,6 +91,11 @@ 2.9.0 compile + + org.java-websocket + Java-WebSocket + 1.5.7 + diff --git a/Server/src/main/content/data/BossKillCounter.java b/Server/src/main/content/data/BossKillCounter.java deleted file mode 100644 index e6d865600..000000000 --- a/Server/src/main/content/data/BossKillCounter.java +++ /dev/null @@ -1,172 +0,0 @@ -package content.data; - -import core.game.node.entity.player.Player; - -/** - * The BossKillcounter keeps track of the amount of bosses the player has slain. - * addtoKillcount(player, npcId) should be added in the finalizeDeath() method of the combat handler for the boss. - * @author Splinter - */ -public enum BossKillCounter { - - - /* ORDINAL BOUND */ - KING_BLACK_DRAGON(new int[] { 50 }, "King Black Dragon", 14649), - BORK(new int[] { 7133, 7134 }, "Bork", -1), - DAGANNOTH_SUPREME(new int[] { 2881 }, "Dagannoth Supreme", 14639), - DAGANNOTH_PRIME(new int[] { 2882 }, "Dagannoth Prime", 14640), - DAGANNOTH_REX(new int[] { 2883 }, "Dagannoth Rex", 14641), - CHAOS_ELEMENTAL(new int[] { 3200 }, "Chaos Elemental", 14638), - GIANT_MOLE(new int[] { 3340 }, "Giant Mole", 14642), - SARADOMIN(new int[] { 6247 }, "Commander Zilyana", 14647), - ZAMORAK(new int[] { 6203 }, "K'ril Tsutsaroth", 14648), - BANDOS(new int[] { 6260 }, "General Graardor", 14646), - ARMADYL(new int[] { 6222 }, "Kree'arra", 14645), - JAD(new int[] { 2745 }, "Tz-Tok Jad", 14828), - KALPHITE_QUEEN(new int[] { 1160 }, "Kalphite Queen", 14650), - CORPOREAL_BEAST(new int[] { 8133 }, "Corporeal Beast", 14653), - TORMENTED_DEMONS(new int[] { - 8349, 8350, 8351, 8352, 8353, 8354, - 8355, 8356, 8357, 8358, 8359, 8360, - 8361, 8362, 8363, 8364, 8365, 8366, - }, "Tormented demon", -1), - - - ; - - /** - * The npcs that can increase the killcounter - */ - private final int[] npc; - - /** - * The name of the NPC, to be displayed as a sendMessage - */ - private final String name; - - /** - * The item ID of the pet relating to the boss. - */ - private final int petId; - - /** - * Constructs a new {@code BossKillCounter} {@code Object}. - * @param npc the npc. - * @param name the npc's string name - */ - BossKillCounter(final int[] npc, final String name, final int petId) { - this.npc = npc; - this.name = name; - this.petId = petId; - } - - /** - * Gets the npc. - * @return The npc. - */ - public int[] getNpc() { - return npc; - } - - /** - * Gets the NPC's name - * @return their name - */ - public String getName() { - return name; - } - - /** - * Gets the petId - * @return The petId - */ - public int getPetId() { - return petId; - } - - /** - * Gets the type for the npc. - * @param npc the npc. - * @return the BossKillcounter - */ - public static BossKillCounter forNPC(final int npc) { - for (BossKillCounter kc : BossKillCounter.values()) { - for (int i : kc.getNpc()) { - if (npc == i) { - return kc; - } - } - } - return null; - } - - /** - * Adds to the player's killcount for that particular boss. - * @param killer The player who killed the npc - * @param npcid the ID of the npc that just died - */ - public static void addtoKillcount(Player killer, int npcid) { - if (killer == null) { - return; - } - BossKillCounter boss = BossKillCounter.forNPC(npcid); - if (boss == null) { - return; - } - killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()]++; - killer.getPacketDispatch().sendMessage("Your " + boss.getName() + " killcount is now: " + killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()] + "."); -// addBossPet(killer, npcid, boss); - } - -// /** -// * Gives the player the pet if they killed a certain boss. -// * The chance by default is 1/5000. This rate lowers to 1/2200 if the for Boss Pets is active. -// * Note: Not all bosses have pet versions of themselves. -// */ -// private static void addBossPet(Player killer, int npcid, BossKillCounter boss){ -// if(boss.getPetId() == -1){ //The boss does not have a pet version. -// return; -// } -// int number = 5000; -// if (npcid == 2745) { -// number = 200; -// if (killer.getSlayer().getTask() == Tasks.JAD) { -// number = 100; -// } -// } else if (npcid == 3200) { -// number = 300; -// } -// int rand = number; -// if(rand == 10){ -// for (int i = 0; i < killer.getFamiliarManager().getInsuredPets().size(); i++) { -// if (killer.getFamiliarManager().getInsuredPets().get(i).getBabyItemId() == boss.getPetId()) { -// return; -// } -// } -// if(killer.getFamiliarManager().hasFamiliar() && killer.getInventory().freeSlots() < 1){ -// return; -// } -// if(!killer.getFamiliarManager().hasFamiliar()){ -// killer.getFamiliarManager().summon(new Item(boss.getPetId()), true); -// killer.sendNotificationMessage("You have a funny feeling like you're being followed."); -// } else if (killer.getInventory().freeSlots() > 0){ -// killer.getInventory().add(new Item(boss.getPetId(), 1)); -// killer.sendNotificationMessage("You feel something weird sneaking into your backpack."); -// } -// Repository.sendNews(killer.getUsername()+" now commands a miniature "+(boss.equals(CORPOREAL_BEAST) ? "Dark core" : boss.getName())+"!"); -// } -// } - - /** - * Increments the player's Barrows chest counter. - * @param player the player - */ - public static void addtoBarrowsCount(Player player) { - if (player == null) { - return; - } - player.getSavedData().getGlobalData().setBarrowsLoots(player.getSavedData().getGlobalData().getBarrowsLoots() + 1); - player.getPacketDispatch().sendMessage("Your Barrows chest count is: " + player.getSavedData().getGlobalData().getBarrowsLoots() + "."); - } - -} diff --git a/Server/src/main/content/data/BossKillCounter.kt b/Server/src/main/content/data/BossKillCounter.kt new file mode 100644 index 000000000..cea7c687d --- /dev/null +++ b/Server/src/main/content/data/BossKillCounter.kt @@ -0,0 +1,72 @@ +package content.data + +import core.api.sendMessage +import core.game.node.entity.player.Player +import org.rs09.consts.NPCs + +/** + * Enumerates the bosses that have their kill counts tracked in a player's statistics (::stats). + * addToBossKillCount(player, npcId) should be added in the finalizeDeath() method of the combat handler for the boss. + * ORDINAL BOUND + * @author Bishop + */ + +enum class BossKillCounter(val bossId: IntArray, val bossName: String) { + + KING_BLACK_DRAGON(intArrayOf(NPCs.KING_BLACK_DRAGON_50), "King Black Dragon"), + BORK(intArrayOf(NPCs.BORK_7133, NPCs.BORK_7134), "Bork"), + DAGANNOTH_SUPREME(intArrayOf(NPCs.DAGANNOTH_SUPREME_2881), "Dagannoth Supreme"), + DAGANNOTH_PRIME(intArrayOf(NPCs.DAGANNOTH_PRIME_2882), "Dagannoth Prime"), + DAGANNOTH_REX(intArrayOf(NPCs.DAGANNOTH_REX_2883), "Dagannoth Rex"), + CHAOS_ELEMENTAL(intArrayOf(NPCs.CHAOS_ELEMENTAL_3200), "Chaos Elemental"), + GIANT_MOLE(intArrayOf(NPCs.GIANT_MOLE_3340), "Giant Mole"), + SARADOMIN(intArrayOf(NPCs.COMMANDER_ZILYANA_6247), "Commander Zilyana"), + ZAMORAK(intArrayOf(NPCs.KRIL_TSUTSAROTH_6203), "K'ril Tsutsaroth"), + BANDOS(intArrayOf(NPCs.GENERAL_GRAARDOR_6260), "General Graardor"), + ARMADYL(intArrayOf(NPCs.KREEARRA_6222), "Kree'arra"), + JAD(intArrayOf(NPCs.TZTOK_JAD_2745), "Tz-Tok Jad"), + KALPHITE_QUEEN(intArrayOf(NPCs.KALPHITE_QUEEN_1160), "Kalphite Queen"), + CORPOREAL_BEAST(intArrayOf(NPCs.CORPOREAL_BEAST_8133), "Corporeal Beast"), + TORMENTED_DEMONS( + intArrayOf( + NPCs.TORMENTED_DEMON_8349, NPCs.TORMENTED_DEMON_8350, NPCs.TORMENTED_DEMON_8351, + NPCs.TORMENTED_DEMON_8352, NPCs.TORMENTED_DEMON_8353, NPCs.TORMENTED_DEMON_8354, + NPCs.TORMENTED_DEMON_8355, NPCs.TORMENTED_DEMON_8356, NPCs.TORMENTED_DEMON_8357, + NPCs.TORMENTED_DEMON_8358, NPCs.TORMENTED_DEMON_8359, NPCs.TORMENTED_DEMON_8360, + NPCs.TORMENTED_DEMON_8361, NPCs.TORMENTED_DEMON_8362, NPCs.TORMENTED_DEMON_8363, + NPCs.TORMENTED_DEMON_8364, NPCs.TORMENTED_DEMON_8365, NPCs.TORMENTED_DEMON_8366), + "Tormented demon" + ), + PENANCE_QUEEN(intArrayOf(NPCs.PENANCE_QUEEN_5247), "Penance Queen"); + + companion object { + private fun forBossId(npc: Int): BossKillCounter? { + for (kc in values()) { + for (i in kc.bossId) { + if (npc == i) { + return kc + } + } + } + return null + } + + @JvmStatic + fun addToBossKillCount(killer: Player?, bossId: Int) { + if (killer == null) { + return + } + val boss: BossKillCounter = forBossId(bossId) ?: return + killer.getSavedData().globalData.bossCounters[boss.ordinal]++ + sendMessage(killer, "Your ${boss.bossName} killcount is now: ${killer.getSavedData().globalData.bossCounters[boss.ordinal]}.") + } + + fun addToBarrowsChestCount(player: Player?) { + if (player == null) { + return + } + player.getSavedData().globalData.barrowsLoots++ + sendMessage(player, "Your Barrows chest count is: ${player.getSavedData().globalData.barrowsLoots}.") + } + } +} diff --git a/Server/src/main/content/data/EnchantedJewellery.kt b/Server/src/main/content/data/EnchantedJewellery.kt index b21ab7e01..251bfa6c1 100644 --- a/Server/src/main/content/data/EnchantedJewellery.kt +++ b/Server/src/main/content/data/EnchantedJewellery.kt @@ -2,23 +2,27 @@ package content.data import content.global.skill.magic.TeleportMethod import content.global.skill.slayer.SlayerManager.Companion.getInstance +import content.global.skill.slayer.SlayerUtils +import core.ServerConstants import core.api.* import core.game.event.TeleportEvent +import core.game.interaction.QueueStrength import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.player.link.diary.DiaryType import core.game.node.item.Item -import core.game.system.task.Pulse +import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics +import core.tools.Log import org.rs09.consts.Items -import core.game.world.GameWorld.Pulser import org.rs09.consts.Sounds import java.util.* /** - * Represents an enchanted jewellery. - * @author Vexia & downthecrop + * Represents a piece of enchanted jewellery. + * @author Vexia, downthecrop, Player Name */ enum class EnchantedJewellery( @@ -70,17 +74,17 @@ enum class EnchantedJewellery( ), AMULET_OF_GLORY( arrayOf( - "Edgeville.", - "Karamja.", - "Draynor Village.", - "Al-Kharid.", - "Nowhere." + "Edgeville", + "Karamja", + "Draynor Village", + "Al Kharid", + "Nowhere" ), arrayOf( Location.create(3087, 3495, 0), Location.create(2919, 3175, 0), Location.create(3104, 3249, 0), - Location.create(3304, 3124, 0) + Location.create(3292, 3175, 0) ), Items.AMULET_OF_GLORY4_1712, Items.AMULET_OF_GLORY3_1710, @@ -186,6 +190,13 @@ enum class EnchantedJewellery( Items.RING_OF_WEALTH2_14642, Items.RING_OF_WEALTH1_14640, Items.RING_OF_WEALTH_14638 + ), + RING_OF_LIFE(arrayOf(), + arrayOf( + Location.create(ServerConstants.HOME_LOCATION!!) + ), + true, + Items.RING_OF_LIFE_2570 ); val isCrumble: Boolean = crumble @@ -199,7 +210,7 @@ enum class EnchantedJewellery( constructor(options: Array, locations: Array, vararg ids: Int) : this(options, locations, false, *ids) /** - * Method used to teleport the player to the desired location. + * Method used when the player clicks one of the options in the jewellery piece's options dialog. * @param player the player. * @param item the used jewellery item. * @param buttonID the button id. @@ -212,39 +223,92 @@ enum class EnchantedJewellery( } return } + attemptTeleport(player, item, buttonID, true, isEquipped) + } + + /** + * Method used to actually teleport the player to the desired location. + * @param player the player. + * @param item the used jewellery item. + * @param buttonID the button id. + * @param replace Whether to attempt replacing the item with its lower-charge version. Always true unless you generated a fake item in code. + * @param isEquipped If the player is operating. + */ + fun attemptTeleport(player: Player, item: Item, buttonID: Int, replace: Boolean, isEquipped: Boolean): Boolean { val itemIndex = getItemIndex(item) val nextJewellery = Item(getNext(itemIndex)) - if (canTeleport(player, nextJewellery)) { - Pulser.submit(object : Pulse(0) { - private var count = 0 - private var location = getLocation(buttonID) - override fun pulse(): Boolean { - when (count) { - 0 -> { - lock(player,4) - visualize(player, ANIMATION, GRAPHICS) - playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) - player.impactHandler.disabledTicks = 4 - closeInterface(player) - } - 3 -> { - teleport(player,location) - resetAnimator(player) - if (isLastItemIndex(itemIndex)) { - if (isCrumble) crumbleJewellery(player, item, isEquipped) - } else { - replaceJewellery(player, item, nextJewellery, isEquipped) - } - unlock(player) - player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location)) - return true - } - } - count += 1 - return false - } - }) + if (!canTeleport(player, nextJewellery)) { + return false } + val location = getLocation(buttonID) + player.scripts.delay = GameWorld.ticks + 4 + queueScript(player, 0, QueueStrength.SOFT) { stage -> + when (stage) { + 0 -> { + lock(player, 4) + // This is an intentional teleport animation & graphics difference as these two jewellery + // animations are authentic to 2009 while others are currently unknown. + if (this == RING_OF_DUELING || this == GAMES_NECKLACE) { + visualize(player, JEWELLERY_ANIMATION, JEWELLERY_GRAPHICS) + } else { + visualize(player, ANIMATION, GRAPHICS) + } + playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + player.impactHandler.disabledTicks = 4 + closeInterface(player) + return@queueScript delayScript(player, 3) + } + 1 -> { + teleport(player, location) + resetAnimator(player) + if (this == RING_OF_DUELING || this == GAMES_NECKLACE) { + player.graphics(JEWELLERY_GRAPHICS) + } + unlock(player) + player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location)) + + if (DIGSITE_PENDANT.ids.contains(item.id)) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 10) + } + + if (!replace) { + return@queueScript stopExecuting(player) + } + if (isLastItemIndex(itemIndex)) { + if (isSlayerRing(item)) { + if (isEquipped) { + // Remove it now, but only addItemOrDrop the gem after the teleport has procced + if (removeItem(player, item, Container.EQUIPMENT)) { + return@queueScript delayScript(player, 1) + } + log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (removeItem from equipment)") + } + // Not equipped -> can replace fluently + if (replaceSlot(player, item.slot, Item(Items.ENCHANTED_GEM_4155), item) == item) { + return@queueScript stopExecuting(player) + } + log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (replaceSlot)") + } + // Not slayer ring + if (isCrumble) { + val removeFrom = if (isEquipped) Container.EQUIPMENT else Container.INVENTORY + if (removeItem(player, item, removeFrom)) { + return@queueScript stopExecuting(player) + } + log(this.javaClass, Log.ERR, "Error crumbling jewelry") + } + } else { + replaceJewellery(player, item, nextJewellery, isEquipped) + } + } + 2 -> { + addItemOrDrop(player, Items.ENCHANTED_GEM_4155) + sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.") + } + } + return@queueScript stopExecuting(player) + } + return true } private fun replaceJewellery(player: Player, item: Item, nextJewellery: Item, isEquipped: Boolean) { @@ -255,18 +319,6 @@ enum class EnchantedJewellery( } } - private fun crumbleJewellery(player: Player, item: Item, isEquipped: Boolean) { - if (isEquipped) { - removeItem(player, item, Container.EQUIPMENT) - } else { - removeItem(player, item) - } - if (isSlayerRing(item)) { - addItem(player, Items.ENCHANTED_GEM_4155) - sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.") - } - } - private fun isSlayerRing(item: Item): Boolean { return (item.id in RING_OF_SLAYING.ids) } @@ -279,7 +331,7 @@ enum class EnchantedJewellery( return } sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " + - "assigned to kill ${getSlayerTaskName(player).lowercase(Locale.getDefault())}'s; " + + "assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player))} " + "only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY) // Slayer tracker UI setVarp(player, 2502, slayerManager.flags.taskFlags shr 4) @@ -327,6 +379,8 @@ enum class EnchantedJewellery( companion object { private val ANIMATION = Animation(714) private val GRAPHICS = Graphics(308, 100, 50) + private val JEWELLERY_ANIMATION = Animation(9603) + private val JEWELLERY_GRAPHICS = Graphics(1684) val idMap = HashMap() init { diff --git a/Server/src/main/content/data/GodBook.java b/Server/src/main/content/data/GodBook.java index 314e61773..92029b479 100644 --- a/Server/src/main/content/data/GodBook.java +++ b/Server/src/main/content/data/GodBook.java @@ -100,7 +100,7 @@ public enum GodBook { * @param page the page. */ public void insertPage(Player player, Item book, Item page) { - if (!hasRequirement(player, "Horror from the Deep")) + if (!hasRequirement(player, Quests.HORROR_FROM_THE_DEEP)) return; if (hasPage(player, book, page)) { player.sendMessage("The book already has that page."); diff --git a/Server/src/main/content/data/Quests.kt b/Server/src/main/content/data/Quests.kt new file mode 100644 index 000000000..190cf2093 --- /dev/null +++ b/Server/src/main/content/data/Quests.kt @@ -0,0 +1,158 @@ +package content.data + +enum class Quests(val questName: String) { + MYTHS_OF_THE_WHITE_LANDS("Myths of the White Lands"), + BLACK_KNIGHTS_FORTRESS("Black Knights' Fortress"), + COOKS_ASSISTANT("Cook's Assistant"), + DEMON_SLAYER("Demon Slayer"), + DORICS_QUEST("Doric's Quest"), + DRAGON_SLAYER("Dragon Slayer"), + ERNEST_THE_CHICKEN("Ernest the Chicken"), + GOBLIN_DIPLOMACY("Goblin Diplomacy"), + IMP_CATCHER("Imp Catcher"), + THE_KNIGHTS_SWORD("The Knight's Sword"), + PIRATES_TREASURE("Pirate's Treasure"), + PRINCE_ALI_RESCUE("Prince Ali Rescue"), + THE_RESTLESS_GHOST("The Restless Ghost"), + ROMEO_JULIET("Romeo & Juliet"), + RUNE_MYSTERIES("Rune Mysteries"), + SHEEP_SHEARER("Sheep Shearer"), + SHIELD_OF_ARRAV("Shield of Arrav"), + VAMPIRE_SLAYER("Vampire Slayer"), + WITCHS_POTION("Witch's Potion"), + ANIMAL_MAGNETISM("Animal Magnetism"), + BETWEEN_A_ROCK("Between a Rock..."), + BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting"), + BIOHAZARD("Biohazard"), + CABIN_FEVER("Cabin Fever"), + CLOCK_TOWER("Clock Tower"), + CONTACT("Contact!"), + ZOGRE_FLESH_EATERS("Zogre Flesh Eaters"), + CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain"), + DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale"), + DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun"), + DEATH_PLATEAU("Death Plateau"), + DESERT_TREASURE("Desert Treasure"), + DEVIOUS_MINDS("Devious Minds"), + THE_DIG_SITE("The Dig Site"), + DRUIDIC_RITUAL("Druidic Ritual"), + DWARF_CANNON("Dwarf Cannon"), + EADGARS_RUSE("Eadgar's Ruse"), + EAGLES_PEAK("Eagles' Peak"), + ELEMENTAL_WORKSHOP_I("Elemental Workshop I"), + ELEMENTAL_WORKSHOP_II("Elemental Workshop II"), + ENAKHRAS_LAMENT("Enakhra's Lament"), + ENLIGHTENED_JOURNEY("Enlightened Journey"), + THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie"), + FAIRYTALE_I_GROWING_PAINS("Fairytale I - Growing Pains"), + FAIRYTALE_II_CURE_A_QUEEN("Fairytale II - Cure a Queen"), + FAMILY_CREST("Family Crest"), + THE_FEUD("The Feud"), + FIGHT_ARENA("Fight Arena"), + FISHING_CONTEST("Fishing Contest"), + FORGETTABLE_TALE("Forgettable Tale..."), + THE_FREMENNIK_TRIALS("The Fremennik Trials"), + WATERFALL_QUEST("Waterfall Quest"), + GARDEN_OF_TRANQUILITY("Garden of Tranquility"), + GERTRUDES_CAT("Gertrude's Cat"), + GHOSTS_AHOY("Ghosts Ahoy"), + THE_GIANT_DWARF("The Giant Dwarf"), + THE_GOLEM("The Golem"), + THE_GRAND_TREE("The Grand Tree"), + THE_HAND_IN_THE_SAND("The Hand in the Sand"), + HAUNTED_MINE("Haunted Mine"), + HAZEEL_CULT("Hazeel Cult"), + HEROES_QUEST("Heroes' Quest"), + HOLY_GRAIL("Holy Grail"), + HORROR_FROM_THE_DEEP("Horror from the Deep"), + ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper"), + IN_AID_OF_THE_MYREQUE("In Aid of the Myreque"), + IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque"), + JUNGLE_POTION("Jungle Potion"), + LEGENDS_QUEST("Legend's Quest"), + LOST_CITY("Lost City"), + THE_LOST_TRIBE("The Lost Tribe"), + LUNAR_DIPLOMACY("Lunar Diplomacy"), + MAKING_HISTORY("Making History"), + MERLINS_CRYSTAL("Merlin's Crystal"), + MONKEY_MADNESS("Monkey Madness"), + MONKS_FRIEND("Monk's Friend"), + MOUNTAIN_DAUGHTER("Mountain Daughter"), + MOURNINGS_END_PART_I("Mourning's End Part I"), + MOURNINGS_END_PART_II("Mourning's End Part II"), + MURDER_MYSTERY("Murder Mystery"), + MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure"), + NATURE_SPIRIT("Nature Spirit"), + OBSERVATORY_QUEST("Observatory Quest"), + ONE_SMALL_FAVOUR("One Small Favour"), + PLAGUE_CITY("Plague City"), + PRIEST_IN_PERIL("Priest in Peril"), + RAG_AND_BONE_MAN("Rag and Bone Man"), + RATCATCHERS("Ratcatchers"), + RECIPE_FOR_DISASTER("Recipe for Disaster"), + RECRUITMENT_DRIVE("Recruitment Drive"), + REGICIDE("Regicide"), + ROVING_ELVES("Roving Elves"), + ROYAL_TROUBLE("Royal Trouble"), + RUM_DEAL("Rum Deal"), + SCORPION_CATCHER("Scorpion Catcher"), + SEA_SLUG("Sea Slug"), + THE_SLUG_MENACE("The Slug Menace"), + SHADES_OF_MORTTON("Shades of Mort'ton"), + SHADOW_OF_THE_STORM("Shadow of the Storm"), + SHEEP_HERDER("Sheep Herder"), + SHILO_VILLAGE("Shilo Village"), + A_SOULS_BANE("A Soul's Bane"), + SPIRITS_OF_THE_ELID("Spirits of the Elid"), + SWAN_SONG("Swan Song"), + TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio"), + A_TAIL_OF_TWO_CATS("A Tail of Two Cats"), + TEARS_OF_GUTHIX("Tears of Guthix"), + TEMPLE_OF_IKOV("Temple of Ikov"), + THRONE_OF_MISCELLANIA("Throne of Miscellania"), + THE_TOURIST_TRAP("The Tourist Trap"), + WITCHS_HOUSE("Witch's House"), + TREE_GNOME_VILLAGE("Tree Gnome Village"), + TRIBAL_TOTEM("Tribal Totem"), + TROLL_ROMANCE("Troll Romance"), + TROLL_STRONGHOLD("Troll Stronghold"), + UNDERGROUND_PASS("Underground Pass"), + WANTED("Wanted!"), + WATCHTOWER("Watchtower"), + COLD_WAR("Cold War"), + THE_FREMENNIK_ISLES("The Fremennik Isles"), + TOWER_OF_LIFE("Tower of Life"), + THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery"), + WHAT_LIES_BELOW("What Lies Below"), + OLAFS_QUEST("Olaf's Quest"), + ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M"), + DREAM_MENTOR("Dream Mentor"), + GRIM_TALES("Grim Tales"), + KINGS_RANSOM("King's Ransom"), + THE_PATH_OF_GLOUPHRIE("The Path of Glouphrie"), + BACK_TO_MY_ROOTS("Back to my Roots"), + LAND_OF_THE_GOBLINS("Land of the Goblins"), + DEALING_WITH_SCABARAS("Dealing with Scabaras"), + WOLF_WHISTLE("Wolf Whistle"), + AS_A_FIRST_RESORT("As a First Resort..."), + CATAPULT_CONSTRUCTION("Catapult Construction"), + KENNITHS_CONCERNS("Kennith's Concerns"), + LEGACY_OF_SEERGAZE("Legacy of Seergaze"), + PERILS_OF_ICE_MOUNTAIN("Perils of Ice Mountain"), + TOKTZ_KET_DILL("TokTz-Ket-Dill"), + SMOKING_KILLS("Smoking Kills"), + ROCKING_OUT("Rocking Out"), + SPIRIT_OF_SUMMER("Spirit of Summer"), + MEETING_HISTORY("Meeting History"), + ALL_FIRED_UP("All Fired Up"), + SUMMERS_END("Summer's End"), + DEFENDER_OF_VARROCK("Defender of Varrock"), + SWEPT_AWAY("Swept Away"), + WHILE_GUTHIX_SLEEPS("While Guthix Sleeps"), + IN_PYRE_NEED("In Pyre Need"), + TEST_QUEST("Test Quest"); + + override fun toString(): String { + return questName + } +} diff --git a/Server/src/main/content/data/RepairItem.java b/Server/src/main/content/data/RepairItem.java deleted file mode 100644 index 3ab25a4d5..000000000 --- a/Server/src/main/content/data/RepairItem.java +++ /dev/null @@ -1,87 +0,0 @@ -package content.data; - -import core.game.node.item.Item; - -/** - * Represents the repair item type. - * @author Vexia - */ -public enum RepairItem { - BRONZE_HATCHET(new Item(494, 1), new Item(1351, 1), 0), - BRONZE_PICKAXE(new Item(468, 1), new Item(1265, 1), 0), - IRON_HATCHET(new Item(496, 1), new Item(1349, 1), 0), - IRON_PICKAXE(new Item(470, 1), new Item(1267, 1), 0), - STEEL_HATCHET(new Item(498, 1), new Item(1353, 1), 0), - STEEL_PICKAXE(new Item(472, 1), new Item(1269, 1), 14), - BLACK_HATCHET(new Item(500, 1), new Item(1361, 1), 10), - MITHRIL_HATCHET(new Item(502, 1), new Item(1355, 1), 18), - MITHRIL_PICKAXE(new Item(474, 1), new Item(1273, 1), 43), - ADAMANT_HATCHET(new Item(504, 1), new Item(1357, 1), 43), - ADAMANT_PICKAXE(new Item(476, 1), new Item(1271, 1), 107), - RUNE_HATCHET(new Item(506, 1), new Item(1359, 1), 427), - RUNE_PICKAXE(new Item(478, 1), new Item(1275, 1), 1100), - DRAGON_HATCHET(new Item(6741, 1), new Item(6739, 1), 1800); - - /** - * The item id. - */ - private final Item item; - - /** - * The product item. - */ - private final Item product; - - /** - * The cost of the money to repair. - */ - private final int cost; - - /** - * Constructs a new {@code BobRepairItem} {@code Object}. - * @param item the item. - * @param product the product. - * @param cost the cost. - */ - RepairItem(Item item, Item product, int cost) { - this.item = item; - this.product = product; - this.cost = cost; - } - - /** - * Gets the item. - * @return The item. - */ - public Item getItem() { - return item; - } - - /** - * Gets the product. - * @return The product. - */ - public Item getProduct() { - return product; - } - - /** - * Gets the cost. - * @return The cost. - */ - public int getCost() { - return cost; - } - - /** - * Gets the reapir item by the id. - * @param id the id. - * @return the repair item. - */ - public static RepairItem forId(int id) { - for (RepairItem item : RepairItem.values()) - if (item.item.getId() == id) - return item; - return null; - } -} \ No newline at end of file diff --git a/Server/src/main/content/data/RepairItem.kt b/Server/src/main/content/data/RepairItem.kt new file mode 100644 index 000000000..4d89a7194 --- /dev/null +++ b/Server/src/main/content/data/RepairItem.kt @@ -0,0 +1,43 @@ +package content.data + +import core.game.node.item.Item + +/** + * Represents the repair item type. + * @author Vexia + * @author Damighty - Kotlin conversion + */ +enum class RepairItem( + val item: Item, + val product: Item, + val cost: Int +) { + BRONZE_HATCHET(Item(494, 1), Item(1351, 1), 0), + BRONZE_PICKAXE(Item(468, 1), Item(1265, 1), 0), + IRON_HATCHET(Item(496, 1), Item(1349, 1), 0), + IRON_PICKAXE(Item(470, 1), Item(1267, 1), 0), + STEEL_HATCHET(Item(498, 1), Item(1353, 1), 0), + STEEL_PICKAXE(Item(472, 1), Item(1269, 1), 14), + BLACK_HATCHET(Item(500, 1), Item(1361, 1), 10), + MITHRIL_HATCHET(Item(502, 1), Item(1355, 1), 18), + MITHRIL_PICKAXE(Item(474, 1), Item(1273, 1), 43), + ADAMANT_HATCHET(Item(504, 1), Item(1357, 1), 43), + ADAMANT_PICKAXE(Item(476, 1), Item(1271, 1), 107), + RUNE_HATCHET(Item(506, 1), Item(1359, 1), 427), + RUNE_PICKAXE(Item(478, 1), Item(1275, 1), 1100), + DRAGON_HATCHET(Item(6741, 1), Item(6739, 1), 1800); + + companion object { + /** + * List of all repairable item IDs. + */ + @JvmStatic + val repairableItemIds: List = values().map { it.item.id } + + /** + * Gets the repair item by the broken items ID. + */ + @JvmStatic + fun forId(id: Int): RepairItem? = values().firstOrNull { it.item.id == id } + } +} diff --git a/Server/src/main/content/data/consumables/Consumables.java b/Server/src/main/content/data/consumables/Consumables.java index 12808d965..67791684b 100644 --- a/Server/src/main/content/data/consumables/Consumables.java +++ b/Server/src/main/content/data/consumables/Consumables.java @@ -30,36 +30,36 @@ public enum Consumables { HERRING(new Food(new int[] {347}, new HealingEffect(5))), MACKEREL(new Food(new int[] {355}, new HealingEffect(6))), ROAST_BIRD_MEAT(new Food(new int[] {9980}, new HealingEffect(6))), - THIN_SNAIL(new Food(new int[] {3369}, new HealingEffect(5))), + THIN_SNAIL(new Food(new int[] {3369}, new RandomHealthEffect(5, 7))), TROUT(new Food(new int[] {333}, new HealingEffect(7))), - SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new HealingEffect(7))), + SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new RandomHealthEffect(7, 11))), SPIDER_ON_SHAFT(new Food(new int[] {6299}, new HealingEffect(7))), ROAST_RABBIT(new Food(new int[] {7223}, new HealingEffect(7))), - LEAN_SNAIL(new Food(new int[] {3371}, new HealingEffect(8))), + LEAN_SNAIL(new Food(new int[] {3371}, new RandomHealthEffect(6, 8))), COD(new Food(new int[] {339}, new HealingEffect(7))), PIKE(new Food(new int[] {351}, new HealingEffect(8))), ROAST_BEAST_MEAT(new Food(new int[] {9988}, new HealingEffect(8))), COOKED_CRAB_MEAT(new Food(new int[] {7521, 7523, 7524, 7525, 7526}, new HealingEffect(2))), - FAT_SNAIL(new Food(new int[] {3373}, new HealingEffect(9))), + FAT_SNAIL(new Food(new int[] {3373}, new RandomHealthEffect(7, 9))), SALMON(new Food(new int[] {329}, new HealingEffect(9))), - SLIMY_EEL(new Food(new int[] {3381}, new HealingEffect(6))), + SLIMY_EEL(new Food(new int[] {3381}, new RandomHealthEffect(6, 10))), TUNA(new Food(new int[] {361}, new HealingEffect(10))), COOKED_KARAMBWAN(new Food(new int[] {3144}, new HealingEffect(18)), true), COOKED_CHOMPY(new Food(new int[] {2878}, new HealingEffect(10))), RAINBOW_FISH(new Food(new int[] {10136}, new HealingEffect(11))), - CAVE_EEL(new Food(new int[] {5003}, new HealingEffect(7))), + CAVE_EEL(new Food(new int[] {5003}, new RandomHealthEffect(8, 12))), LOBSTER(new Food(new int[] {379}, new HealingEffect(12))), COOKED_JUBBLY(new Food(new int[] {7568}, new HealingEffect(15))), BASS(new Food(new int[] {365}, new HealingEffect(13))), SWORDFISH(new Food(new int[] {373}, new HealingEffect(14))), - LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(14))), + LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(11))), MONKFISH(new Food(new int[] {7946}, new HealingEffect(16))), SHARK(new Food(new int[] {385}, new HealingEffect(20))), SEA_TURTLE(new Food(new int[] {397}, new HealingEffect(21))), MANTA_RAY(new Food(new int[] {391}, new HealingEffect(22))), KARAMBWANJI(new Food(new int[] {3151}, new HealingEffect(3))), STUFFED_SNAKE(new Food(new int[] {7579}, new HealingEffect(20), "You eat the stuffed snake-it's quite a meal! It tastes like chicken.")), - CRAYFISH(new Food(new int[] {13433}, new HealingEffect(2))), + CRAYFISH(new Food(new int[] {13433}, new HealingEffect(1))), GIANT_FROG_LEGS(new Food(new int [] {4517}, new HealingEffect(6))), /** Breads */ @@ -111,13 +111,15 @@ public enum Consumables { /** Vegetables */ POTATO(new Food(new int[] {1942}, new HealingEffect(1), "You eat the potato. Yuck!")), - BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(2))), + BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(4))), SPICY_SAUCE(new Food(new int[] {7072, 1923}, new HealingEffect(2))), CHILLI_CON_CARNE(new Food(new int[] {7062, 1923}, new HealingEffect(5))), SCRAMBLED_EGG(new Food(new int[] {7078, 1923}, new HealingEffect(5))), EGG_AND_TOMATO(new Food(new int[] {7064, 1923}, new HealingEffect(8))), SWEET_CORN(new Food(new int[] {5988}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))), SWEETCORN_BOWL(new Food(new int[] {7088, 1923}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))), + CHOPPED_TUNA(new Food(new int[] {7086, 1923}, new HealingEffect(10))), + CHOPPED_ONION(new Food(new int[] {1871, 1923}, new HealingEffect(1))), POTATO_WITH_BUTTER(new Food(new int[] {6703}, new HealingEffect(7))), CHILLI_POTATO(new Food(new int[] {7054}, new HealingEffect(14))), FRIED_ONIONS(new Food(new int[] {7084, 1923}, new HealingEffect(5))), @@ -128,8 +130,8 @@ public enum Consumables { MUSHROOM_POTATO(new Food(new int[] {7058}, new HealingEffect(20))), TUNA_AND_CORN(new Food(new int[] {7068, 1923}, new HealingEffect(13))), TUNA_POTATO(new Food(new int[] {7060}, new HealingEffect(22))), - ONION(new Food(new int[] {1957}, new HealingEffect(2), "It's always sad to see a grown man/woman cry.")), - CABBAGE(new Food(new int[] {1965}, new HealingEffect(2), "You eat the cabbage. Yuck!")), + ONION(new Food(new int[] {1957}, new HealingEffect(1), "It's always sad to see a grown man/woman cry.")), + CABBAGE(new Food(new int[] {1965}, new HealingEffect(1), "You eat the cabbage. Yuck!")), DRAYNOR_CABBAGE(new Food(new int[] {1967}, new DraynorCabbageEffect(), "You eat the cabbage.", "It seems to taste nicer than normal.")), EVIL_TURNIP(new Food(new int[] {12134, 12136, 12138}, new HealingEffect(6))), SPINACH_ROLL(new Food(new int[] {1969}, new HealingEffect(2))), @@ -147,7 +149,7 @@ public enum Consumables { ORANGE(new Food(new int[] {2108}, new HealingEffect(2))), ORANGE_CHUNKS(new Food(new int[] {2110}, new HealingEffect(2))), ORANGE_SLICES(new Food(new int[] {2112}, new HealingEffect(2))), - PAPAYA_FRUIT(new Food(new int[] {5972}, new HealingEffect(2))), + PAPAYA_FRUIT(new Food(new int[] {5972}, new MultiEffect(new EnergyEffect(5), new HealingEffect(8)))), TENTI_PINEAPPLE(new FakeConsumable(1851, new String[] {"Try using a knife to slice it into pieces."})), PINEAPPLE(new FakeConsumable(2114, new String[] {"Try using a knife to slice it into pieces."})), PINEAPPLE_CHUNKS(new Food(new int[] {2116}, new HealingEffect(2))), @@ -169,8 +171,8 @@ public enum Consumables { STRANGE_FRUIT(new Food(new int[] {464}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(30)))), /** Gnome Cooking */ - TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(12))), - PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(12))), + TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(8))), + PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(8))), SPICY_CRUNCHIES(new Food(new int[] {2213}, new HealingEffect(7))), PREMADE_SY_CRUNCH(new Food(new int[] {2241}, new HealingEffect(7))), WORM_CRUNCHIES(new Food(new int[] {2205}, new HealingEffect(8))), @@ -201,48 +203,56 @@ public enum Consumables { /** Ales */ ASGOLDIAN_ALE(new FakeConsumable(7508, new String[] {"I don't think I'd like gold in beer thanks. Leave it for the dwarves."})), ASGARNIAN_ALE(new Drink(new int[] {1905, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + ASGARNIAN_ALE_POH(new Drink(new int[] {7744, 7742}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), ASGARNIAN_ALE_KEG(new Drink(new int[] {5785, 5783, 5781, 5779, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), - ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), - ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))), + ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), AXEMANS_FOLLY(new Drink(new int[] {5751, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)))), AXEMANS_FOLLY_KEG(new Drink(new int[] {5825, 5823, 5821, 5819, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)), new Animation(2289))), AXEMANS_FOLLY_M(new Drink(new int[] {5753, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), AXEMANS_FOLLY_M_KEG(new Drink(new int[] {5905, 5903, 5901, 5899, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))), BANDITS_BREW(new Drink(new int[] {4627, 1919}, new MultiEffect(new SkillEffect(Skills.THIEVING, 1, 0), new SkillEffect(Skills.ATTACK, 1, 0), new SkillEffect(Skills.STRENGTH, -1, 0), new SkillEffect(Skills.DEFENCE, -6, 0), new HealingEffect(1)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), BEER(new Drink(new int[] {1917, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + BEER_POH(new Drink(new int[] {7740, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), BEER_TANKARD(new Drink(new int[] {3803, 3805}, new MultiEffect(new SkillEffect(Skills.ATTACK, -9, 0), new SkillEffect(Skills.STRENGTH, 4, 0)), "You quaff the beer. You feel slightly reinvigorated...", "...but very dizzy too.")), KEG_OF_BEER(new Drink(new int[] {3801}, new KegOfBeerEffect(), new Animation(1330), "You chug the keg. You feel reinvigorated...", "...but extremely drunk too.")), CHEFS_DELIGHT(new Drink(new int[] {5755, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), + CHEFS_DELIGHT_POH(new Drink(new int[] {7754, 7742}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), CHEFS_DELIGHT_KEG(new Drink(new int[] {5833, 5831, 5829, 5827, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), CHEFS_DELIGHT_M(new Drink(new int[] {5757, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)))), CHEFS_DELIGHT_M_KEG(new Drink(new int[] {5913, 5911, 5909, 5907, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)), new Animation(2289))), CIDER(new Drink(new int[] {5763, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))), + CIDER_POH(new Drink(new int[] {7752, 7742}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))), CIDER_KEG(new Drink(new int[] {5849, 5847, 5845, 5843, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))), new Animation(2289))), MATURE_CIDER(new Drink(new int[] {5765, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))))), CIDER_M_KEG(new Drink(new int[] {5929, 5927, 5925, 5923, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))), new Animation(2289))), DRAGON_BITTER(new Drink(new int[] {1911, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + DRAGON_BITTER_POH(new Drink(new int[] {7748, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), DRAGON_BITTER_KEG(new Drink(new int[] {5809, 5807, 5805, 5803, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))), DRAGON_BITTER_M(new Drink(new int[] {5745, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), DRAGON_BITTER_M_KEG(new Drink(new int[] {5889, 5887, 5885, 5883, 5769}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))), DWARVEN_STOUT(new Drink(new int[] {1913, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), DWARVEN_STOUT_KEG(new Drink(new int[] {5777, 5775, 5773, 5771, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), - DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)))), - DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289))), + DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), + DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), GREENMANS_ALE(new Drink(new int[] {1909, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))), + GREENMANS_ALE_POH(new Drink(new int[] {7746, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))), GREENMANS_ALE_KEG(new Drink(new int[] {5793, 5791, 5789, 5787, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)), new Animation(2289))), GREENMANS_ALE_M(new Drink(new int[] {5743, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), GREENMANS_ALE_M_KEG(new Drink(new int[] {5873, 5871, 5869, 5867, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), GROG(new Drink(new int[] {1915, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), - MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")), - MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")), - MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(6))), - MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(6), new Animation(2289))), + MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(5), "It tastes like something just died in your mouth.")), + MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(5), new Animation(2289), "It tastes like something just died in your mouth.")), + MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")), + MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")), SLAYERS_RESPITE(new Drink(new int[] {5759, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), SLAYERS_RESPITE_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), SLAYERS_RESPITE_M(new Drink(new int[] {5761, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), SLAYERS_RESPITE_M_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), WIZARDS_MIND_BOMB(new Drink(new int[] {1907, 1919}, new WizardsMindBombEffect(), "You drink the Wizard's Mind Bomb.", "You feel very strange.")), - MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect())), + WIZARDS_MIND_BOMB_KEG(new Drink(new int[] {5801, 5799, 5797, 5795, 5769}, new WizardsMindBombEffect(), new Animation(2289), "You drink the Wizard's Mind Bomb.", "You feel very strange.")), + MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect(), "You drink the mature Wizard's Mind Bomb.", "You feel very strange.")), + MATURE_WMB_KEG(new Drink(new int[] {5881, 5879, 5877, 5875, 5769}, new MatureWmbEffect(), new Animation(2289), "You drink the mature Wizard's Mind Bomb.", "You feel very strange.")), /** Cocktails */ FRUIT_BLAST(new Drink(new int[] {2084, 2026}, new HealingEffect(9))), @@ -272,11 +282,11 @@ public enum Consumables { BRAINDEATH_RUM(new Drink(new int[] {7157}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 0, -0.1), new SkillEffect(Skills.ATTACK, 0, -0.05), new SkillEffect(Skills.PRAYER, 0, -0.05), new SkillEffect(Skills.RANGE, 0, -0.05), new SkillEffect(Skills.MAGIC, 0, -0.05), new SkillEffect(Skills.HERBLORE, 0, -0.05), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.MINING, 1, 0)), "With a sense of impending doom you drink the 'rum'. You try very hard not to die.")), RUM_TROUBLE_BREWING_RED(new Drink(new int[] {8940, 8940}, new TroubleBrewingRumEffect("Oh gods! It tastes like burning!"), new Animation(9605))), RUM_TROUBLE_BREWING_BLUE(new Drink(new int[] {8941, 8941}, new TroubleBrewingRumEffect("My Liver! My Liver is melting!"), new Animation(9604))), - VODKA(new Drink(new int[] {2015}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -3, 0)))), + VODKA(new Drink(new int[] {2015}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.ATTACK, -4, 0), new SkillEffect(Skills.STRENGTH, 4, 0)))), GIN(new Drink(new int[] {2019}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 1, 0), new SkillEffect(Skills.ATTACK, 4, 0), new RandomHealthEffect(3, 4)))), BRANDY(new Drink(new int[] {2021}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.ATTACK, 4, 0)))), WHISKY(new Drink(new int[] {2017}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), - BOTTLE_OF_WINE(new Drink(new int[] {2015, 7921}, new MultiEffect(new HealingEffect(14), new SkillEffect(Skills.ATTACK, -3, 0)))), + BOTTLE_OF_WINE(new Drink(new int[] {7919, 7921}, new MultiEffect(new HealingEffect(14), new SkillEffect(Skills.ATTACK, -3, 0)))), /** Wine */ JUG_OF_WINE(new Drink(new int[] {1993, 1935}, new MultiEffect(new HealingEffect(11), new SkillEffect(Skills.ATTACK, -2, 0)))), @@ -285,16 +295,19 @@ public enum Consumables { /** Tea */ CUP_OF_TEA(new Drink(new int[] {712, 1980}, new MultiEffect(new HealingEffect(3), new SkillEffect(Skills.ATTACK, 3, 0)), "Aaah, nothing like a nice cuppa tea!")), - CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new EnergyEffect(10))), - CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new EnergyEffect(10))), - NETTLE_TEA(new Drink(new int[] {4239, 1923}, new NettleTeaEffect())), - NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1980}, new NettleTeaEffect())), + NETTLE_WATER(new Drink(new int[] {Items.NETTLE_WATER_4237, Items.BOWL_1923}, new HealingEffect((1)))), + CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))), + CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))), + CUP_OF_TEA_NETTLE_PORCELAIN(new Drink(new int[] {4245, 4244}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))), + CUP_OF_TEA_MILKY_NETTLE_PORCELAIN(new Drink(new int[] {4246, 4244}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))), + NETTLE_TEA(new Drink(new int[] {4239, 1923}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))), + NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1923}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))), CUP_OF_TEA_CLAY(new Drink(new int[] {7730, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")), - CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0))), + CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")), CUP_OF_TEA_WHITE(new Drink(new int[] {7733, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")), - CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0))), + CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")), CUP_OF_TEA_GOLD(new Drink(new int[] {7736, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")), - CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0))), + CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")), /** Miscellaneous */ CHOCOLATE_BAR(new Food(new int[] {1973}, new HealingEffect(3))), @@ -306,8 +319,9 @@ public enum Consumables { TCHIKI_MONKEY_PASTE(new Food(new int[] {7575}, new HealingEffect(5), "You eat the Tchiki monkey nut paste. It sticks to the roof of your mouth.")), 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))), + CAVIAR(new Food(new int[]{11326}, new HealingEffect(5))), EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))), - CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(6))), + CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))), EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))), FROG_SPAWN(new Food(new int[] {5004}, new RandomHealthEffect(3, 7), "You eat the frogspawn. Yuck.")), @@ -319,44 +333,44 @@ public enum Consumables { STRENGTH(new Potion(new int[] {113, 115, 117, 119}, new SkillEffect(Skills.STRENGTH, 3, 0.1))), ATTACK(new Potion(new int[] {2428, 121, 123, 125}, new SkillEffect(Skills.ATTACK, 3, 0.1))), DEFENCE(new Potion(new int[] {2432, 133, 135, 137}, new SkillEffect(Skills.DEFENCE, 3, 0.1))), - RANGING(new Potion(new int[] {2444, 169, 171, 173}, new SkillEffect(Skills.RANGE, 3, 0.1))), - MAGIC(new Potion(new int[] {3040, 3042, 3044, 3046}, new SkillEffect(Skills.MAGIC, 3, 0.1))), - SUPER_STRENGTH(new Potion(new int[] {2440, 157, 159, 161}, new SkillEffect(Skills.STRENGTH, 3, 0.2))), - SUPER_ATTACK(new Potion(new int[] {2436, 145, 147, 149}, new SkillEffect(Skills.ATTACK, 3, 0.2))), - SUPER_DEFENCE(new Potion(new int[] {2442, 163, 165, 167}, new SkillEffect(Skills.DEFENCE, 3, 0.2))), + RANGING(new Potion(new int[] {2444, 169, 171, 173}, new SkillEffect(Skills.RANGE, 4, 0.1))), + MAGIC(new Potion(new int[] {3040, 3042, 3044, 3046}, new SkillEffect(Skills.MAGIC, 4, 0))), + SUPER_STRENGTH(new Potion(new int[] {2440, 157, 159, 161}, new SkillEffect(Skills.STRENGTH, 5, 0.15))), + SUPER_ATTACK(new Potion(new int[] {2436, 145, 147, 149}, new SkillEffect(Skills.ATTACK, 5, 0.15))), + SUPER_DEFENCE(new Potion(new int[] {2442, 163, 165, 167}, new SkillEffect(Skills.DEFENCE, 5, 0.15))), ANTIPOISON(new Potion(new int[] {2446, 175, 177, 179}, new AddTimerEffect("poison:immunity", secondsToTicks(90)))), ANTIPOISON_(new Potion(new int[] {5943, 5945, 5947, 5949}, new AddTimerEffect("poison:immunity", minutesToTicks(9)))), ANTIPOISON__(new Potion(new int[] {5952, 5954, 5956, 5958}, new AddTimerEffect("poison:immunity", minutesToTicks(12)))), SUPER_ANTIP(new Potion(new int[] {2448, 181, 183, 185}, new AddTimerEffect("poison:immunity", minutesToTicks(6)))), - RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new MultiEffect(new SetAttributeEffect("disease:immunity", 300), new RemoveTimerEffect("disease")))), + RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new CureDiseaseEffect())), AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))), HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))), RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))), SARA_BREW(new Potion(new int[] {6685, 6687, 6689, 6691}, new MultiEffect(new PercentHeal(2, .15), new SkillEffect(Skills.ATTACK, 0, -0.10), new SkillEffect(Skills.STRENGTH, 0, -0.10), new SkillEffect(Skills.MAGIC, 0, -0.10), new SkillEffect(Skills.RANGE, 0, -0.10), new SkillEffect(Skills.DEFENCE, 2, 0.2)))), SUMMONING(new Potion(new int[] {12140, 12142, 12144, 12146}, new MultiEffect(new RestoreSummoningSpecial(), new SummoningEffect(7, 0.25)))), COMBAT(new Potion(new int[] {9739, 9741, 9743, 9745}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, .1), new SkillEffect(Skills.ATTACK, 3, .1)))), - ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new MultiEffect(new EnergyEffect(10), new HealingEffect(3)))), + ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new EnergyEffect(10))), FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))), PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))), - SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new MultiEffect(new RestoreEffect(8, 0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25)))), - ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(0, 10)))), - ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new SetAttributeEffect("fire:immune", 600, true))), + SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))), + ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true, 2), new SkillEffect(Skills.ATTACK, 2, 0.20), new SkillEffect(Skills.STRENGTH, 2, 0.12), new SkillEffect(Skills.DEFENCE, -2, -0.10), new PrayerEffect(0.0, 0.10, true)))), + ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))), GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))), - MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))), - SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8,0.25), new RemoveTimerEffect("poison"), new RemoveTimerEffect("disease")))), + MAGIC_ESS(new Potion(new int[] {9021, 9022, 9023, 9024}, 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")))), SUPER_ENERGY(new Potion(new int[] {3016, 3018, 3020, 3022}, new EnergyEffect(20))), BLAMISH_OIL(new FakeConsumable(1582, new String[] {"You know... I'd really rather not."})), /** Barbarian Mixes */ PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))), - ZAMMY_MIX(new BarbarianMix(new int[] {11521, 11523}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(0, 10)))), + ZAMMY_MIX(new BarbarianMix(new int[]{11521, 11523}, new MultiEffect(new ZamorakMixEffect(), new SkillEffect(Skills.ATTACK, 2, 0.20), new SkillEffect(Skills.STRENGTH, 2, 0.12), new SkillEffect(Skills.DEFENCE, -2, -0.10)))), ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))), ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))), - RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new RemoveTimerEffect("disease"), new SetAttributeEffect("disease:immunity", 300), new HealingEffect(3)))), + RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))), STR_MIX(new BarbarianMix(new int[] {11443, 11441}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(3)))), RESTO_MIX(new BarbarianMix(new int[] {11449, 11451}, new MultiEffect(new RestoreEffect(10, 0.3), new HealingEffect(3)))), SUPER_RESTO_MIX(new BarbarianMix(new int [] {11493, 11495}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25), new HealingEffect(6)))), - ENERGY_MIX(new BarbarianMix(new int[] {11453, 11455}, new MultiEffect(new EnergyEffect(10), new HealingEffect(6)))), + ENERGY_MIX(new BarbarianMix(new int[] {11453, 11455}, new MultiEffect(new EnergyEffect(10), new HealingEffect(3)))), DEF_MIX(new BarbarianMix(new int[] {11457, 11459}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 3, 0.1), new HealingEffect(6)))), AGIL_MIX(new BarbarianMix(new int[] {11461, 11463}, new MultiEffect(new SkillEffect(Skills.AGILITY, 3, 0), new HealingEffect(6)))), COMBAT_MIX(new BarbarianMix(new int[] {11445, 11447}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(6)))), @@ -365,8 +379,13 @@ public enum Consumables { SUPER_ENERGY_MIX(new BarbarianMix(new int[] {11481, 11483}, new MultiEffect(new EnergyEffect(20), new HealingEffect(6)))), HUNTING_MIX(new BarbarianMix(new int[] {11517, 11519}, new MultiEffect(new SkillEffect(Skills.HUNTER, 3, 0), 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)))), - ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new RandomHealthEffect(3, 7)))), + ANTIDOTE_PLUS_MIX(new BarbarianMix(new int[] {11501, 11503}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(9)), new HealingEffect(6)))), + ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new HealingEffect(6)))), + ANTIFIRE_MIX(new BarbarianMix(new int[] {11505, 11507}, new MultiEffect(new AddTimerEffect("dragonfire:immunity", 600, true), new HealingEffect(6)))), + MAGIC_ESS_MIX(new BarbarianMix(new int[] {11489, 11491}, new MultiEffect(new SkillEffect(Skills.MAGIC, 3, 0), new HealingEffect(6)))), + SUPER_DEF_MIX(new BarbarianMix(new int[] {11497, 11499}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 5, 0.15), new HealingEffect(6)))), + RANGING_MIX(new BarbarianMix(new int[] {11509, 11511}, new MultiEffect(new SkillEffect(Skills.RANGE, 4, 0.1), new HealingEffect(6)))), + MAGIC_MIX(new BarbarianMix(new int[] {11513, 11515}, new MultiEffect(new SkillEffect(Skills.MAGIC, 4, 0), new HealingEffect(6)))), /** Stealing creation potions */ SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))), diff --git a/Server/src/main/content/data/consumables/effects/CureDiseaseEffect.kt b/Server/src/main/content/data/consumables/effects/CureDiseaseEffect.kt new file mode 100644 index 000000000..4c63c6e99 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/CureDiseaseEffect.kt @@ -0,0 +1,21 @@ +package content.data.consumables.effects + +import core.api.* +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player +import core.game.system.timer.impl.Disease + +class CureDiseaseEffect () : ConsumableEffect() { + override fun activate (p: Player) { + val existingTimer = getTimer(p) + if (existingTimer != null) { + existingTimer.hitsLeft -= 9 + if (existingTimer.hitsLeft <= 0) { + sendMessage(p, "The disease has been cured.") + removeTimer(p) + }else{ + sendMessage(p,"You feel slightly better.") + } + } + } +} diff --git a/Server/src/main/content/data/consumables/effects/DamageEffect.java b/Server/src/main/content/data/consumables/effects/DamageEffect.java index c4573306b..1b5e4778c 100644 --- a/Server/src/main/content/data/consumables/effects/DamageEffect.java +++ b/Server/src/main/content/data/consumables/effects/DamageEffect.java @@ -7,15 +7,21 @@ import core.game.node.entity.player.Player; public class DamageEffect extends ConsumableEffect { final double amt; final boolean isPercent; + final int baseAmount; - public DamageEffect(double amt,boolean isPercent){ + public DamageEffect(double amt, boolean isPercent) { + this(amt, isPercent, 0); + } + + public DamageEffect(double amt, boolean isPercent, int baseAmount) { this.amt = amt; this.isPercent = isPercent; + this.baseAmount = baseAmount; } @Override public void activate(Player p) { - p.getImpactHandler().manualHit(p,-getHealthEffectValue(p), ImpactHandler.HitsplatType.NORMAL); + p.getImpactHandler().manualHit(p, -getHealthEffectValue(p), ImpactHandler.HitsplatType.NORMAL); } @Override @@ -23,8 +29,8 @@ public class DamageEffect extends ConsumableEffect { double amount = amt; if (isPercent) { amount /= 100; - return (int) -(amount * player.getSkills().getLifepoints()); + return (int) -(amount * player.getSkills().getLifepoints() + baseAmount); } - return (int) -amt; + return (int) -(amt + baseAmount); } } diff --git a/Server/src/main/content/data/consumables/effects/NettleTeaEffect.java b/Server/src/main/content/data/consumables/effects/NettleTeaEffect.java deleted file mode 100644 index 8f20e8c33..000000000 --- a/Server/src/main/content/data/consumables/effects/NettleTeaEffect.java +++ /dev/null @@ -1,20 +0,0 @@ -package content.data.consumables.effects; - -import core.game.consumable.ConsumableEffect; -import core.game.node.entity.player.Player; - -public class NettleTeaEffect extends ConsumableEffect { - - private final static int healing = 3; - - @Override - public void activate(Player p) { - final ConsumableEffect effect = p.getSkills().getLifepoints() < p.getSkills().getMaximumLifepoints() ? new MultiEffect(new HealingEffect(3), new EnergyEffect(5)) : new HealingEffect(3); - effect.activate(p); - } - - @Override - public int getHealthEffectValue(Player player) { - return healing; - } -} diff --git a/Server/src/main/content/data/consumables/effects/PrayerEffect.kt b/Server/src/main/content/data/consumables/effects/PrayerEffect.kt index 9f636bc27..5edaff7dc 100644 --- a/Server/src/main/content/data/consumables/effects/PrayerEffect.kt +++ b/Server/src/main/content/data/consumables/effects/PrayerEffect.kt @@ -5,16 +5,18 @@ import core.game.consumable.ConsumableEffect import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import org.rs09.consts.Items +import kotlin.math.ceil import kotlin.math.floor -class PrayerEffect(var base: Double, var bonus: Double) : ConsumableEffect() { +class PrayerEffect @JvmOverloads constructor(var base: Double, var bonus: Double, private val roundUp: Boolean = false) : ConsumableEffect() { override fun activate(player: Player?) { if(player == null) return val level = getStatLevel(player, Skills.PRAYER) var b = bonus if(inInventory(player, Items.HOLY_WRENCH_6714)) b += 0.02 // Leaving this in for futureproofing. Current update is for properly rounding down. - val amount = floor(base + (level * b)) + val rawAmount = base + (level * b) + val amount = if (roundUp) ceil(rawAmount) else floor(rawAmount) modPrayerPoints(player, amount) } } \ No newline at end of file diff --git a/Server/src/main/content/data/consumables/effects/RestoreEffect.java b/Server/src/main/content/data/consumables/effects/RestoreEffect.java index 3b57acabf..ba9b3ea8d 100644 --- a/Server/src/main/content/data/consumables/effects/RestoreEffect.java +++ b/Server/src/main/content/data/consumables/effects/RestoreEffect.java @@ -6,21 +6,37 @@ import core.game.node.entity.skill.Skills; public class RestoreEffect extends ConsumableEffect { double base,bonus; + boolean all_skills; // Except for hitpoints public RestoreEffect(double base, double bonus){ this.base = base; this.bonus = bonus; + this.all_skills = false; + } + + public RestoreEffect(double base, double bonus, boolean all_skills){ + this.base = base; + this.bonus = bonus; + this.all_skills = all_skills; } final int[] SKILLS = new int[] { Skills.DEFENCE, Skills.ATTACK, Skills.STRENGTH, Skills.MAGIC, Skills.RANGE }; + final int[] ALL_SKILLS = new int[]{ + Skills.ATTACK,Skills.DEFENCE, Skills.STRENGTH,Skills.RANGE,Skills.PRAYER,Skills.MAGIC, Skills.COOKING, + Skills.WOODCUTTING,Skills.FLETCHING,Skills.FISHING,Skills.FIREMAKING,Skills.CRAFTING,Skills.SMITHING, + Skills.MINING,Skills.HERBLORE,Skills.AGILITY,Skills.THIEVING,Skills.SLAYER,Skills.FARMING, + Skills.RUNECRAFTING,Skills.HUNTER,Skills.CONSTRUCTION,Skills.SUMMONING }; @Override public void activate(Player p) { Skills sk = p.getSkills(); - for(int skill : SKILLS){ + int[] skills = this.all_skills ? ALL_SKILLS : SKILLS; + for(int skill : skills){ int statL = sk.getStaticLevel(skill); + int boost = (int) (base + (statL * bonus)); int curL = sk.getLevel(skill); if(curL < statL){ - int boost = (int) (base + (statL * bonus)); p.getSkills().updateLevel(skill, boost, statL); } + if (skill == Skills.PRAYER) + p.getSkills().incrementPrayerPoints(boost); } } } diff --git a/Server/src/main/content/data/consumables/effects/ZamorakMixEffect.java b/Server/src/main/content/data/consumables/effects/ZamorakMixEffect.java new file mode 100644 index 000000000..688da0961 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/ZamorakMixEffect.java @@ -0,0 +1,25 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; + +/** + * The Zamorak mix shows the regular Zamorak brew hitsplat (10% of pre-drink lifepoints + 2, rounded down) + * but also heals 6 lifepoints. The heal must be applied before the hit so the net change can never kill + * the player, while the hitsplat still reflects the pre-heal lifepoints. + */ +public class ZamorakMixEffect extends ConsumableEffect { + + @Override + public void activate(Player p) { + int damage = (int) (p.getSkills().getLifepoints() * 0.10 + 2); + p.getSkills().heal(6); + p.getImpactHandler().manualHit(p, damage, ImpactHandler.HitsplatType.NORMAL); + } + + @Override + public int getHealthEffectValue(Player player) { + return 6 - (int) (player.getSkills().getLifepoints() * 0.10 + 2); + } +} diff --git a/Server/src/main/content/data/skill/SkillingPets.java b/Server/src/main/content/data/skill/SkillingPets.java deleted file mode 100644 index 4ea03edd9..000000000 --- a/Server/src/main/content/data/skill/SkillingPets.java +++ /dev/null @@ -1,103 +0,0 @@ -package content.data.skill; - -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.repository.Repository; - -/** - * Represents the skilling pets obtained randomly. - * @author Empathy - * - */ -public enum SkillingPets { - - BABY_RED_CHINCHOMPA(new Item(14823), "Baby Chinchompa", Skills.HUNTER), - BABY_GREY_CHINCHOMPA(new Item(14824), "Baby Chinchompa", Skills.HUNTER), - BEAVER(new Item(14821), "Beaver", Skills.WOODCUTTING), - GOLEM(new Item(14822), "Rock Golem", Skills.MINING), - HERON(new Item(14827), "Heron", Skills.FISHING); - - /** - * The pet item drop. - */ - private final Item pet; - - /** - * The name. - */ - private final String name; - - /** - * The skill. - */ - private final int skill; - - /** - * Constructs a new {@code SkillingPets} object. - * @param skill The skill id. - * @param pet The pet item. - */ - SkillingPets(Item pet, String name, int skill) { - this.pet = pet; - this.name = name; - this.skill = skill; - } - - /** - * Checks the pet drop. - * @param player The player. - * @param pet The pet drop to check. - */ - public static void checkPetDrop(Player player, SkillingPets pet) { - if (pet == null) { - return; - } - int defaultChance = 15000; - int newChance = (defaultChance / player.getSkills().getStaticLevel(pet.getSkill()) * 55); - int outOf = (newChance > defaultChance ? defaultChance : newChance); - int getChance = outOf; - if (getChance != 1) { - return; - } - if (player.hasItem(pet.getPet())) { - return; - } - if (player.getFamiliarManager().hasFamiliar() && player.getInventory().isFull()) { - return; - } - if (player.getFamiliarManager().hasFamiliar()) { - if (player.getFamiliarManager().getFamiliar().getName().equalsIgnoreCase(pet.getName())) { - return; - } - player.getInventory().add(pet.getPet()); - player.sendNotificationMessage("You feel something weird sneaking into your backpack."); - } else { - player.getFamiliarManager().summon(pet.getPet(), true); - player.sendNotificationMessage("You have a funny feeling like you're being followed."); - } - Repository.sendNews(player.getUsername() + " has found a " + pet.getPet().getName() + "!"); - } - - - /** - * @return the pet - */ - public Item getPet() { - return pet; - } - - /** - * @return the pet name. - */ - public String getName() { - return name; - } - - /** - * @return the skill. - */ - public int getSkill() { - return skill; - } -} diff --git a/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt b/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt index 8cea6d806..1b9147172 100644 --- a/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt +++ b/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt @@ -45,35 +45,35 @@ class ChampionChallengeListener : InteractionListener, MapArea { private val IMP_SCROLL_TEXT = arrayOf( "How about picking on someone your own size? I'll", - "see you at the Champion's Guild.", + "see you at the Champions' Guild.", "", "Champion of Imps" ) private val GOBLIN_SCROLL_TEXT = arrayOf( "Fight me if you think you can human, I'll wait", - "for you in the Champion's Guild.", + "for you in the Champions' Guild.", "", "Champion of Goblins" ) private val SKELETON_SCROLL_TEXT = arrayOf( - "I'll be waiting at the Champions' Guild to", - "collect your bones.", + "I'll be waiting at the Champions' Guild to collect", + "your bones.", "", "Champion of Skeletons" ) private val ZOMBIE_SCROLL_TEXT = arrayOf( - "You come to Champions' Guild, you fight me,", - "I squish you, I get brains!", + "You come to Champions' Guild, you fight me, I", + "squish you, I get brains!", "", "Champion of Zombies" ) private val GIANT_SCROLL_TEXT = arrayOf( - "Get yourself to the Champions' Guild, if you", - "dare to face me puny human.", + "Get yourself to the Champions' Guild, if you dare", + "to face me puny human.", "", "Champion of Giants" ) @@ -93,28 +93,28 @@ class ChampionChallengeListener : InteractionListener, MapArea { ) private val EARTH_WARRIOR_TEXT = arrayOf( - "I challenge you to a duel, come to the arena beneath", - "the Champion's Guild and fight me if you dare.", + "I challenge you to a duel, come to the arena", + "beneath the Champions' Guild and fight me if you", + "dare.", "", "Champion of Earth Warriors" ) private val JOGRE_SCROLL_TEXT = arrayOf( "You think you can defeat me? Come to the", - "Champion's Guild and prove it!", + "Champions' Guild and prove it!", "", "Champion of Jogres" ) private val LESSER_DEMON_SCROLL_TEXT = arrayOf( - "Come to the Champion's Guild so I can banish", + "Come to the Champions' Guild so I can banish", "you mortal!", "", "Champion of Lesser Demons" ) private val PORTCULLIS = Scenery.PORTCULLIS_10553 - private val LADDER = Scenery.LADDER_10554 private val CHAMPION_STATUE_CLOSED = Scenery.CHAMPION_STATUE_10556 private val CHAMPION_STATUE_OPEN = Scenery.CHAMPION_STATUE_10557 private val TRAPDOOR_CLOSED = Scenery.TRAPDOOR_10558 @@ -124,6 +124,13 @@ class ChampionChallengeListener : InteractionListener, MapArea { private val ARENA_ZONE = 12696 override fun defineListeners() { + // Champion's Guild Basement Ladder to Main Floor + addClimbDest(Location(3190, 9758, 0), Location(3190, 3356, 0)) + // Champion Statue Ladder to Arena + addClimbDest(Location(3184, 9758, 0), Location(3182, 9758, 0)) + // Arena Ladder to Champion's Guild Basement + addClimbDest(Location(3183, 9758, 0), Location(3185, 9758, 0)) + on(LARXUS, IntType.NPC, "talk-to") { player, _ -> openDialogue(player, LarxusDialogue(false)) return@on true @@ -134,18 +141,18 @@ class ChampionChallengeListener : InteractionListener, MapArea { return@on true } - on(TRAPDOOR_CLOSED, IntType.SCENERY, "open") { _, node -> - replaceScenery(node.asScenery(), TRAPDOOR_OPEN, 100, node.location) - return@on true - } - onUseWith(IntType.NPC, ChampionScrollsDropHandler.SCROLLS, NPCs.LARXUS_3050) { player, _, _ -> openDialogue(player, LarxusDialogue(true)) return@onUseWith true } + on(TRAPDOOR_CLOSED, IntType.SCENERY, "open") { _, node -> + replaceScenery(node.asScenery(), TRAPDOOR_OPEN, 100, node.location) + return@on true + } + on(TRAPDOOR_OPEN, IntType.SCENERY, "close") { _, node -> - replaceScenery(node.asScenery(), TRAPDOOR_CLOSED, 100, node.location) + replaceScenery(node.asScenery(), TRAPDOOR_CLOSED, -1, node.location) return@on true } @@ -154,15 +161,6 @@ class ChampionChallengeListener : InteractionListener, MapArea { return@on true } - on(LADDER, IntType.SCENERY, "climb-up") { player, _ -> - teleport(player, Location.create(3185, 9758, 0)) - return@on true - } - on(CHAMPION_STATUE_OPEN, IntType.SCENERY, "climb-down") { player, _ -> - teleport(player, Location.create(3182, 9758, 0)) - return@on true - } - on(PORTCULLIS, IntType.SCENERY, "open") { player, node -> if (player.getAttribute("championsarena:start", false) == false) { sendNPCDialogue(player, NPCs.LARXUS_3050, "You need to arrange a challenge with me before you enter the arena.") @@ -229,4 +227,4 @@ class ChampionChallengeListener : InteractionListener, MapArea { ZoneRestriction.RANDOM_EVENTS ) } -} +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt b/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt index 02b3b2b0e..bfbe78a76 100644 --- a/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt +++ b/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt @@ -70,7 +70,7 @@ class ChampionScrollsDropHandler : ChampionScrollsEventHookBase() { NPCs.CAVE_GOBLIN_GUARD_2073, NPCs.CAVE_GOBLIN_GUARD_2074, - NPCs.GOBLIN_GUARD_489, NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497, + NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497, NPCs.SERGEANT_GRIMSPIKE_6265, NPCs.SERGEANT_STEELWILL_6263, NPCs.SERGEANT_STRONGSTACK_6261 diff --git a/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt b/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt index 6ec919bd7..3157b6b50 100644 --- a/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt +++ b/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt @@ -27,24 +27,24 @@ class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() { 0 -> { face(findNPC(NPCs.LARXUS_3050)!!, player!!, 1) for (i in scrolls)when{ - inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use prayer's. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only weapons. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only melee combat skill. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only magic skill. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use melee combat skills. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use weapons with special attack. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use ranged skill. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only equipment. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only ranged skill. Do you still want to proceed?").also { stage = 1 } - inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use magic skill. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Prayers. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to take Weapons, no other items are allowed. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Melee attacks, no Ranged or Magic. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Magic attacks, no Melee or Ranged. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Melee attacks. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Special Attacks. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Ranged attacks. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed any Weapons or Armour. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Ranged attacks, no Melee or Magic. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Magic attacks. Do you still want to proceed?").also { stage = 1 } else -> { sendMessage(player!!, "Nothing interesting happens.").also { stage = END_DIALOGUE } } } } - 1 -> options("Yes, let me at him!", "No, thanks I'll pass.").also { stage = 2 } + 1 -> options("Yes, let me at him!", "No thanks, I'll pass.").also { stage = 2 } 2 -> when (buttonID) { 1 -> playerl("Yes, let me at him!").also { stage = 3 } - 2 -> playerl("No, thanks I'll pass.").also { stage = END_DIALOGUE } + 2 -> playerl("No thanks, I'll pass.").also { stage = END_DIALOGUE } } 3 -> npcl("Your challenger is ready, please go down through the trapdoor when you're ready.").also { stage = 4 } 4 -> { @@ -65,7 +65,7 @@ class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() { 3 -> playerl("Nothing thanks.").also { stage = END_DIALOGUE } } 3 -> npcl("Well pass it here and we'll get you started.").also { stage = END_DIALOGUE } - 4 -> npcl("This is the champions' arena, the champions of various, races use it to duel those they deem worthy of the, honour.").also { stage = END_DIALOGUE } + 4 -> npcl("This is the champions' arena. The champions of various races use it to duel those they deem worthy of the honour. If you find a challenge scroll in your travels, bring it here to face your challenger.").also { stage = END_DIALOGUE } } } } diff --git a/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt index 4a81fc066..1c131efc9 100644 --- a/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt +++ b/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt @@ -3,8 +3,6 @@ package content.global.activity.cchallange.npc import core.api.* import core.game.node.entity.Entity import core.game.node.entity.combat.BattleState -import core.game.node.entity.combat.CombatStyle -import core.game.node.entity.combat.equipment.WeaponInterface import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills @@ -63,21 +61,11 @@ class ImpChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, super.checkImpact(state) val player = state.attacker if (player is Player) { - val w = player.getExtension(WeaponInterface::class.java) - if (state.style == CombatStyle.MELEE || state.style == CombatStyle.MAGIC || state.style == CombatStyle.RANGE) { + + //somehow the maximumHit is determined to be zero by this point if you're using a melee special attack. + if (state.maximumHit == 0) { state.neutralizeHits() - state.estimatedHit = state.maximumHit - } - if (w.weaponInterface.interfaceId == 10) { - sendMessage(player, "You cannot use special attack in this challenge.") - if (state.estimatedHit > -1) { - state.estimatedHit = 0 - return - } - if (state.secondaryHit > -1) { - state.secondaryHit = 0 - return - } + sendMessage(player, "Larxus said you couldn't use special attacks in this duel.") } } } diff --git a/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt index e62f73bf2..e41fd5d72 100644 --- a/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt +++ b/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt @@ -1,8 +1,6 @@ package content.global.activity.cchallange.npc import core.api.* -import core.game.container.impl.EquipmentContainer -import core.game.global.action.EquipHandler import core.game.node.entity.Entity import core.game.node.entity.combat.BattleState import core.game.node.entity.npc.AbstractNPC @@ -62,12 +60,11 @@ class LesserDemonChampionNPC(id: Int = 0, location: Location? = null) : Abstract super.checkImpact(state) val player = state.attacker if (player is Player) { - if (!player.equipment[3].hasItemPlugin()) { + if (player.equipment.isEmpty) { state.neutralizeHits() state.estimatedHit = state.maximumHit } else { - EquipHandler.unequip(player, EquipmentContainer.SLOT_WEAPON, id) - sendMessage(player, "You cannot use weapons in this challenge.") + sendMessage(player, "You cannot wear any equipment in this challenge.") if (state.estimatedHit > -1) { state.estimatedHit = 0 return diff --git a/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt index 0be9eeb3d..bab84b5b5 100644 --- a/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt +++ b/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt @@ -63,8 +63,8 @@ class ZombieChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(i val player = state.attacker if (player is Player) { if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) { - state.estimatedHit = state.maximumHit state.neutralizeHits() + state.estimatedHit = state.maximumHit } if (state.style == CombatStyle.MAGIC) { sendMessage(player, "You cannot use spells in this challenge.") diff --git a/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt b/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt index c284214a7..48cdc7dec 100644 --- a/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt +++ b/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt @@ -30,7 +30,7 @@ class PenguinManager{ return tagMapping[Penguin.forLocation(location)?.ordinal]?.contains(player.username.toLowerCase()) ?: false } - private fun updateStoreFile(){ + fun updateStoreFile(){ val jsonTags = JSONArray() tagMapping.filter { it.value.isNotEmpty() }.forEach { (ordinal,taggers) -> log(this::class.java, Log.FINE, "$ordinal - ${taggers.first()}") diff --git a/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt b/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt index d19b9a82a..2d6abe7bb 100644 --- a/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt +++ b/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt @@ -44,18 +44,65 @@ enum class Penguin(val id: Int, val hint: String, val location: Location){ BUSH_8(NPCs.BUSH_8105,"located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)), BUSH_9(NPCs.BUSH_8105,"located in the northern desert.",Location.create(3350, 3311, 0)), BUSH_10(NPCs.BUSH_8105,"located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)), - BUSH_11(NPCs.BUSH_8105,"located south of Ardougne.",Location.create(2440, 3206, 0)), - BUSH_12(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)), + BUSH_11(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)), ROCK_1(NPCs.ROCK_8109,"located where the Imperial Guard train.",Location.create(2852, 3578, 0)), ROCK_2(NPCs.ROCK_8109,"located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)), - ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)), + ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)), //potentially incorrect location ROCK_4(NPCs.ROCK_8109,"located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)), ROCK_5(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2532, 3630, 0)), CRATE_1(NPCs.CRATE_8108,"located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)), CRATE_2(NPCs.CRATE_8108,"located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)), - BARREL_1(NPCs.CRATE_8108,"located where no weapons may go.",Location.create(2806, 3383, 0)), + CRATE_3(NPCs.CRATE_8108,"located south of Ardougne.",Location.create(2440, 3206, 0)), + BARREL_1(NPCs.BARREL_8104,"located where no weapons may go.",Location.create(2806, 3383, 0)), TOADSTOOL_1(NPCs.TOADSTOOL_8110,"located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)), - TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0)); + TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0)), //potentially a spawn from 2010 + + BUSH_12(NPCs.BUSH_8105,"located on an island.",Location.create(2534, 3871, 0)), + BARREL_2(NPCs.BARREL_8104,"located near the ghost town.",Location.create(3654, 3491, 0)), + BUSH_13(NPCs.BUSH_8105,"located where bloodsuckers rule.",Location.create(3600, 3487, 0)), + BUSH_14(NPCs.BUSH_8105,"located on islands where brothers quarrel.",Location.create(2355, 3848, 0)), + ROCK_6(NPCs.ROCK_8109,"located on a large crescent island.",Location.create(2118, 3943, 0)), + ROCK_7(NPCs.ROCK_8109,"located on islands where brothers quarrel.",Location.create(2357, 3797, 0)), + ROCK_8(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3169, 3650, 0)), + BARREL_3(NPCs.BARREL_8104,"located where pirates feel mostly harmless.",Location.create(3738, 3001, 0)), + CACTUS_3(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3276, 2797, 0)), + TOADSTOOL_3(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2314, 3174, 0)), + BUSH_15(NPCs.BUSH_8105,"located deep in the jungle.",Location.create(2938, 2978, 0)), + TOADSTOOL_4(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2219, 3227, 0)), + BARREL_4(NPCs.BARREL_8104,"located south of Ardougne.",Location.create(2662, 3152, 0)), + //BARREL_5(NPCs.BARREL_8104,"located where monkeys rule.",Location.create(2751, 2700, 0)), + //currently not well accessible, will need to add when Ape Atoll is sorted. + //BUSH_16(NPCs.BUSH_8105,"located on islands where brothers quarrel.",Location.create(2353, 3834, 0)), + //currently not well accessible, will need to add when Neitiznot bridges are fixed. + ROCK_9(NPCs.ROCK_8109,"located near a mountain of wolves.",Location.create(2852, 3504, 0)), + ROCK_10(NPCs.ROCK_8109,"located on islands where brothers quarrel.",Location.create(2413, 3846, 0)), + + BUSH_17(NPCs.BUSH_8105,"located near some ogres.",Location.create(2578, 2909, 0)), + CRATE_4(NPCs.CRATE_8108,"located where banana smugglers dwell.",Location.create(2869, 3157, 0)), + //CRATE_5(NPCs.CRATE_8108,"located near the island of Dragontooth.",Location.create(3824, 3562, 0)), + //current not accessible, will need to add when Dragontooth island is sorted. + ROCK_11(NPCs.ROCK_8109,"located where bloodsuckers rule.",Location.create(3550, 3439, 0)), + TOADSTOOL_5(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2181, 3172, 0)), + BUSH_18(NPCs.BUSH_8105,"located where bloodsuckers rule.",Location.create(3472, 3392, 0)), + BUSH_19(NPCs.BUSH_8105,"located near Port Sarim.",Location.create(2989, 3121, 0)), + CRATE_6(NPCs.CRATE_8108,"located where fishers colonise.",Location.create(2322, 3658, 0)), + ROCK_12(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2675, 3717, 0)), + ROCK_13(NPCs.ROCK_8109,"located near the pointy-eared ones.",Location.create(2296, 3270, 0)), + CRATE_7(NPCs.CRATE_8108,"located where bloodsuckers rule.",Location.create(3637, 3486, 0)), + TOADSTOOL_6(NPCs.TOADSTOOL_8110,"located where bloodsuckers rule.",Location.create(3416, 3437, 0)), + BUSH_20(NPCs.BUSH_8105,"located where monkeys rule.",Location.create(2802, 2806, 0)), + + ROCK_14(NPCs.ROCK_8109,"located near some ogres.",Location.create(2438, 3050, 0)), + CACTUS_4(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3252, 2963, 0)), + ROCK_15(NPCs.ROCK_8109,"located near some ogres.",Location.create(2340, 3064, 0)), + ROCK_16(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3108, 3837, 0)), + CACTUS_5(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3433, 3000, 0)), + CACTUS_6(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3274, 2813, 0)), + ROCK_17(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3019, 3866, 0)), + ROCK_18(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(2991, 3824, 0)), + BUSH_21(NPCs.BUSH_8105,"located north of Ardougne.",Location.create(2398, 3361, 0)), + ROCK_19(NPCs.ROCK_8109,"located near the coast.",Location.create(2733, 3283, 0)), + ROCK_20(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3236, 3927, 0)); companion object { private val locationMap = values().map { it.location.toString() to it }.toMap() diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt index 9663b16fa..074ab27a6 100644 --- a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt @@ -11,12 +11,13 @@ import core.ServerStore.Companion.getString import content.global.bots.ShootingStarBot import core.game.world.repository.Repository +import core.tools.RandomFunction /** * Represents a shooting star object (Only ever initialized once) (ideally) * @author Ceikry */ -class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()){ +class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()) { val crash_locations = mapOf( "East of Dark Wizards' Tower" to Location.create(2925, 3339, 0), // East of Dark Wizards' Tower "Crafting Guild" to Location.create(2940, 3280, 0), // Crafting Guild Mine @@ -26,12 +27,12 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando "Brimhaven mining site" to Location.create(2743, 3143, 0), // Brimhaven mining site "South Crandor mining site" to Location.create(2822, 3239, 0), // South Crandor mining site (requires Dragon Slayer) "Karamja mining site" to Location.create(2854, 3032, 0), // Karamja mining site - "Shilo Village mining site" to Location.create(2826, 2997, 0), // Shilo Village mining site/Gem rocks + "Shilo Village mining site" to Location.create(2826, 2997, 0), // Shilo Village mining site/Gem rocks (requires Shilo Village prereqs) "Relleka mining site" to Location.create(2682, 3700, 0), // Rellekka mining site - "Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Trials) - //"Lunar Isle mine" to Location.create(2140, 3939, 0), // Lunar Isle mine (requires Lunar Diplomacy?) - //"Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires Fremennik Trials) - //"Neitiznot runite mine" to Location.create(2376, 3835, 0), // Near the Neitiznot runite mine (requires Fremennik Trials) currently inaccessible as bridge does not work + "Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Isles prereqs) + "Lunar Isle mine" to Location.create(2140, 3939, 0), // Lunar Isle mine (requires Lunar Diplomacy prereqs) + "Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires The Fremennik Trials) + //"Neitiznot runite mine" to Location.create(2376, 3835, 0), // Near the Neitiznot runite mine (requires Fremennik Isles prereqs) currently inaccessible as bridge does not work "Ardougne mining site" to Location.create(2600, 3232, 0), // Ardougne mining site (Monastery) "Ardougne eastern mine" to Location.create(2706, 3334, 0), // Ardougne mining site (Legends Guild) "Kandarin Coal trucks" to Location.create(2589, 3485, 0), // Kandarin Coal trucks @@ -48,11 +49,11 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando "South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine "Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop "Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine - //"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires Quest to enter) + "Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter) "Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank - "Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires Quest to enter but is currently accessible for Slayer) + "Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer) "Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank - "Lletya bank" to Location.create(2329, 3163, 0), // Lletya bank (requires Roving Elves?) + "Lletya bank" to Location.create(2329, 3163, 0), // Lletya bank (requires MEP1 prereqs) "Piscatoris mining site" to Location.create(2336, 3636, 0), // Piscatoris mining site "North Edgeville mining site" to Location.create(3101, 3569, 0), // Wilderness Steel mine / Zamorak mage mine "Southern wilderness mine" to Location.create(3025, 3591, 0), // Wilderness skeleton mine @@ -79,22 +80,15 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando * Degrades a ShootingStar (or removes the starObject and spawns a Star Sprite if it's the last star) */ fun degrade() { - if(level.ordinal == 0){ - selfBots.filter { it.isMining() }.forEach { it.sleep() } - SceneryBuilder.remove(starObject) - isSpawned = false - starSprite.location = starObject.location - starSprite.init() - spriteSpawned = true - ShootingStarPlugin.getStoreFile().clear() + if(level.ordinal == 0) { + spawnSprite() return } level = getNextType() maxDust = level.totalStardust dustLeft = level.totalStardust - ShootingStarPlugin.getStoreFile()["level"] = level.ordinal - ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered + ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft val newStar = Scenery(level.objectId, starObject.location) SceneryBuilder.replace(starObject, newStar) @@ -110,7 +104,6 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando */ fun fire() { SceneryBuilder.remove(starObject) - rebuildVars() clearSprite() SceneryBuilder.add(starObject) if(!isSpawned) { @@ -123,37 +116,54 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando } isSpawned = true Repository.sendNews("A shooting star level ${level.ordinal + 1} just crashed near ${location}!") + ShootingStarPlugin.getStoreFile()["level"] = level.ordinal + ShootingStarPlugin.getStoreFile()["location"] = location + ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered + ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft } /** * Rebuilds some of the variables with new information. */ fun rebuildVars(){ - if(firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()){ - level = ShootingStarType.values()[ShootingStarPlugin.getStoreFile().getInt("level")] - location = ShootingStarPlugin.getStoreFile().getString("location") - isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered") - } else { - level = ShootingStarType.values().random() - location = crash_locations.entries.random().key - isDiscovered = false + // Defaults + var levelOrd = RandomFunction.random(9) + level = ShootingStarType.values()[levelOrd] + location = crash_locations.entries.random().key + isDiscovered = false + dustLeft = level.totalStardust + ticks = 0 + spriteSpawned = false + + if (firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()) { + // Replace default with stored values, if any + levelOrd = ShootingStarPlugin.getStoreFile().getInt("level", levelOrd) + level = ShootingStarType.values()[levelOrd] + location = ShootingStarPlugin.getStoreFile().getString("location", location) + isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered", false) + dustLeft = ShootingStarPlugin.getStoreFile().getInt("dustLeft", dustLeft) + ticks = ShootingStarPlugin.getStoreFile().getInt("ticks", ticks) + spriteSpawned = ShootingStarPlugin.getStoreFile().getBoolean("spriteSpawned", false) } maxDust = level.totalStardust - dustLeft = level.totalStardust starObject = Scenery(level.objectId, crash_locations.get(location)) + } - ShootingStarPlugin.getStoreFile()["level"] = level.ordinal - ShootingStarPlugin.getStoreFile()["location"] = location - ShootingStarPlugin.getStoreFile()["isDiscovered"] = false - - ticks = 0 - firstStar = false + fun spawnSprite() { + selfBots.filter { it.isMining() }.forEach { it.sleep() } + SceneryBuilder.remove(starObject) + isSpawned = false + starSprite.location = starObject.location + starSprite.init() + spriteSpawned = true + ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned } fun clearSprite() { starSprite.clear() spriteSpawned = false + ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned } /** @@ -161,6 +171,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando */ fun decDust() { if(--dustLeft <= 0) degrade() + ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft } /** diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt index 74360b3d2..5c5ecf033 100644 --- a/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player import core.game.node.entity.skill.SkillPulse import core.game.node.entity.skill.Skills import content.data.skill.SkillingTool +import core.ServerConstants import core.game.node.item.Item import core.tools.RandomFunction import org.rs09.consts.Items @@ -13,6 +14,9 @@ import core.game.world.GameWorld import core.game.world.repository.Repository import core.tools.colorize +// TODO: Shooting stars should roll for bonus gems while mining +// See: https://youtu.be/6OqZ2TGc6fM?si=U8nB5IDQREhWXApD + /** * The pulse used to handle mining shooting stars. */ @@ -46,14 +50,14 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin //checks if the star has been discovered and if not, awards the bonus xp. Xp can be awarded regardless of mining level as per the wiki. if (!star.isDiscovered && !player.isArtificial) { val bonusXp = 75 * player.skills.getStaticLevel(Skills.MINING) - player.incrementAttribute("/save:shooting-star:bonus-xp", bonusXp) + rewardXP(player, Skills.MINING, bonusXp.toDouble()) Repository.sendNews(player.username + " is the discoverer of the crashed star near " + star.location + "!") - player.sendMessage("You have ${player.skills.experienceMutiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.") ShootingStarPlugin.submitScoreBoard(player) star.isDiscovered = true + ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered return player.skills.getLevel(Skills.MINING) >= star.miningLevel } - + if (player.skills.getLevel(Skills.MINING) < star.miningLevel) { player.dialogueInterpreter.sendDialogue("You need a Mining level of at least " + star.miningLevel + " in order to mine this layer.") return false @@ -87,6 +91,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin val bonusXp = player.getAttribute("shooting-star:bonus-xp", 0).toDouble() var xp = star.level.exp.toDouble() if(bonusXp > 0) { + // legacy: shooting star bonus xp used to be handed out in an inauthentic way; see GL !2092 val delta = Math.min(bonusXp, xp) player.incrementAttribute("/save:shooting-star:bonus-xp", (-delta).toInt()) xp += delta @@ -99,7 +104,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin if (ShootingStarPlugin.getStarDust(player) < 200) { player.inventory.add(Item(ShootingStarPlugin.STAR_DUST, 1)) } - if(!inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !inBank(player, Items.ANCIENT_BLUEPRINT_14651)){ + if (ServerConstants.SHOOTING_STAR_RING && hasAnItem(player, Items.ANCIENT_BLUEPRINT_14651).container == null) { rollBlueprint(player) } @@ -129,7 +134,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin override fun message(type: Int) { when (type) { - 0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock...") + 0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock.") } } diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt index cf141ca56..7368b7689 100644 --- a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt @@ -12,11 +12,11 @@ import core.ServerStore.Companion.getBoolean import core.game.dialogue.DialogueFile import core.game.interaction.InteractionListener import core.game.interaction.IntType -import core.tools.SystemLogger import core.game.system.command.Privilege import core.game.world.GameWorld import core.tools.Log import core.tools.secondsToTicks +import content.data.Quests class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener { override fun login(player: Player) { @@ -27,14 +27,30 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com override fun tick() { ++star.ticks + // Check if the current star sprite should expire val maxDelay = tickDelay + (tickDelay / 3) if(star.ticks > maxDelay && star.spriteSpawned){ star.clearSprite() } - if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!star.isSpawned && !star.spriteSpawned)) { + if (star.firstStar && !star.isSpawned && !star.spriteSpawned) { + // Apparently, the server has only just booted + star.rebuildVars() + if (star.spriteSpawned) { + star.spawnSprite() + } else { + star.fire() + } + star.firstStar = false + } + + // Check if it's time to fire a new one + if (star.ticks >= tickDelay && !star.spriteSpawned) { + star.rebuildVars() star.fire() } + + getStoreFile()["ticks"] = star.ticks } override fun defineListeners() { @@ -66,49 +82,67 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com return@on true } - val condition: (Player) -> Boolean = when(star.location.toLowerCase()){ - "canifis bank" -> { p -> hasRequirement(p, "Priest in Peril") } - //"Burgh de Rott bank" -> { p -> p.questRepository.isComplete("Priest in Peril")} // for now, require this as it is in Morytania. remove when appropriate quests added - Crash - "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40) } - "lletya bank" -> {p -> hasRequirement(p, "Mourning's End Part I") } - "jatizso mine" -> {p -> hasRequirement(player, "Fremennik Trials") } - "south crandor mining site" -> {p -> hasRequirement(p, "Dragon Slayer") } - "shilo village mining site" -> {p -> hasRequirement(p, "Shilo Village") } - "mos le'harmless bank" -> {p -> hasRequirement(p, "Cabin Fever") } - else -> {_ -> true} + class RingDialogue(val star: ShootingStar) : DialogueFile() { + val shouldWarn = when (star.location) { + "North Edgeville mining site", + "Southern wilderness mine", + "Wilderness hobgoblin mine", + "Pirates' Hideout mine", + "Lava Maze mining site", + "Mage Arena bank" -> true + else -> false + } + + override fun handle(componentID: Int, buttonID: Int) { + fun teleportToStar(player: Player) { + val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) { + "canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")} + "burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} + "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)} + "lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)} + "jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} + "south crandor mining site" -> {p -> hasRequirement(p, Quests.DRAGON_SLAYER)} + "shilo village mining site" -> {p -> hasRequirement(p, Quests.SHILO_VILLAGE)} + "mos le'harmless bank" -> {p -> hasRequirement(p, Quests.CABIN_FEVER)} //needs to be updated to check for completion when the quest releases; https://runescape.wiki/w/Mos_Le%27Harmless?oldid=913025 + "lunar isle mine" -> {p -> hasRequirement(p, Quests.LUNAR_DIPLOMACY)} + "miscellania coal mine" -> {p -> requireQuest(p, Quests.THE_FREMENNIK_TRIALS, "to access this.")} + //"neitiznot runite mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} //disabled: currently not reachable + else -> {_ -> true} + } + if (!condition.invoke(player)) { + sendDialogue(player,"Magical forces prevent your teleportation.") + } else if (teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME)) { + getRingStoreFile()[player.username.toLowerCase()] = true + } + } + when (stage) { + 0 -> dialogue(if (star.spriteSpawned) "The star sprite has already been freed." else "The star sprite is still trapped.").also { if (shouldWarn) stage++ else stage += 2 } + 1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ } + 2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ } + 3 -> when (buttonID) { + 1 -> teleportToStar(player) + 2 -> end() + } + } + } } - if(!condition.invoke(player)){ - sendDialogue(player, "Magical forces prevent your teleportation.") - return@on true - } - - val shouldWarn = when(star.location){ - "North Edgeville mining site", - "Southern wilderness mine", - "Wilderness hobgoblin mine", - "Pirates' Hideout mine", - "Lava Maze mining site", - "Mage Arena bank" -> true - else -> false - } - - openDialogue(player, RingDialogue(shouldWarn, star)) - + openDialogue(player, RingDialogue(star)) return@on true } } override fun defineCommands() { - define("tostar", Privilege.ADMIN) { player, _ -> + define("tostar", Privilege.ADMIN, description = "Teleports you adjacent to the currently active star.") { player, _ -> teleport(player, star.starObject.location.transform(1,1,0)) } - define("submit", Privilege.ADMIN) { _, _ -> + define("submit", Privilege.ADMIN, description = "Rebuilds and fires the shooting star event immediately.") { _, _ -> + star.rebuildVars() star.fire() } - define("resetsprite", Privilege.ADMIN) { player, _ -> + define("resetsprite", Privilege.ADMIN, description = "Resets your star sprite reward cooldown.") { player, _ -> player.savedData.globalData.starSpriteDelay = 0L } } @@ -119,26 +153,6 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com private data class ScoreboardEntry(val player: String, val time: Int) - private class RingDialogue(val shouldWarn: Boolean, val star: ShootingStar) : DialogueFile(){ - override fun handle(componentID: Int, buttonID: Int) { - when (stage) { - 0 -> dialogue(if (star.spriteSpawned) "The star sprite has already been freed." else "The star sprite is still trapped.").also { if (shouldWarn) stage++ else stage += 2 } - 1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ } - 2 -> player!!.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ } - 3 -> when (buttonID) { - 1 -> teleport(player!!, star).also { end() } - 2 -> end() - } - } - } - - fun teleport(player: Player, star: ShootingStar){ - if (teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME)) { - getRingStoreFile()[player.username.toLowerCase()] = true - } - } - } - companion object { private val star = ShootingStar() private val tickDelay = if(GameWorld.settings?.isDevMode == true) 200 else 25000 diff --git a/Server/src/main/content/global/ame/KidnapHelper.kt b/Server/src/main/content/global/ame/KidnapHelper.kt new file mode 100644 index 000000000..39406108f --- /dev/null +++ b/Server/src/main/content/global/ame/KidnapHelper.kt @@ -0,0 +1,59 @@ +package content.global.ame + +import core.ServerConstants +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Sounds + +fun kidnapPlayer(npc: NPC, player: Player, dest: Location, playerLine: String? = null, callback: (player: Player, npc: NPC) -> Unit) { + clearScripts(player) + val lockDuration = if (playerLine != null) 4 else 6 + lock(player, lockDuration) + queueScript(player, 1, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + if (playerLine != null) { + sendChat(player, playerLine) + return@queueScript delayScript(player, 2) + } + return@queueScript delayScript(player, 0) + } + 1 -> { + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 2 -> { + setAttribute(player, "kidnapped-by-random", true) + if (getAttribute(player, "/save:original-loc", null) == null) { + setAttribute(player, "/save:original-loc", player.location) + } + teleport(player, dest, TeleportType.INSTANT) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player, 8941) + resetAnimator(player) + callback(player, npc) + return@queueScript delayScript(player, 2) + } + 3 -> { + removeAttribute(player, "kidnapped-by-random") //this is not needed at this point anymore and will reenable the original-loc sanity check tick action + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } +} + +fun returnPlayer(player: Player) { + player.locks.unlockTeleport() + val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION) + teleport(player, destination!!) + unlock(player) + removeAttributes(player, "/save:original-loc", "kidnapped-by-random") +} diff --git a/Server/src/main/content/global/ame/RandomEventNPC.kt b/Server/src/main/content/global/ame/RandomEventNPC.kt index c0aba00af..a4f3072f7 100644 --- a/Server/src/main/content/global/ame/RandomEventNPC.kt +++ b/Server/src/main/content/global/ame/RandomEventNPC.kt @@ -1,11 +1,20 @@ package content.global.ame -import content.global.ame.events.MysteriousOldManNPC +import content.global.ame.events.surpriseexam.MysteriousOldManNPC +import core.api.getAttribute import core.api.playGlobalAudio import core.api.poofClear +import core.api.removeAttribute +import core.api.sendMessage +import core.api.setAttribute +import core.api.utils.WeightBasedTable import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle import core.game.node.entity.impl.PulseType import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.agg.AggressiveBehavior +import core.game.node.entity.npc.agg.AggressiveHandler import core.game.node.entity.player.Player import core.game.node.item.Item import core.game.world.map.Location @@ -13,9 +22,10 @@ import core.game.world.map.RegionManager import core.game.world.map.path.Pathfinder import core.game.world.update.flag.context.Graphics import core.integrations.discord.Discord -import core.api.utils.WeightBasedTable +import core.tools.RandomFunction import core.tools.secondsToTicks import core.tools.ticksToCycles +import org.rs09.consts.NPCs import org.rs09.consts.Sounds import kotlin.random.Random import kotlin.reflect.full.createInstance @@ -27,8 +37,8 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { val SMOKE_GRAPHICS = Graphics(86) var initialized = false var finalized = false - var timerPaused = false var ticksLeft = secondsToTicks(180) + private val combatBracket = intArrayOf(10, 20, 40, 60, 90) open fun create(player: Player, loot: WeightBasedTable? = null, type: String = ""): RandomEventNPC { val event = this::class.createInstance() @@ -36,6 +46,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { event.loot = loot event.player = player event.spawnLocation = RegionManager.getSpawnLocation(player, this) + setAttribute(event, "spawned-by-ame", true) return event } @@ -45,6 +56,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { poofClear(this) playGlobalAudio(this.location, Sounds.SMOKEPUFF_1930, ticksToCycles(1)) } + removeAttribute(player, "random:pause") finalized = true } @@ -66,7 +78,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { if (!player.getAttribute("random:pause", false)) { ticksLeft-- } - if (!pulseManager.hasPulseRunning() && !finalized) { follow() } @@ -82,15 +93,18 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { override fun init() { initialized = true finalized = false - timerPaused = false spawnLocation ?: terminate() location = spawnLocation player.setAttribute("re-npc", this) super.init() + super.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() { + override fun canSelectTarget(entity: Entity, target: Entity): Boolean { + return target == player + } + }) } open fun onTimeUp() { - noteAndTeleport() terminate() } @@ -118,4 +132,39 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { } abstract fun talkTo(npc: NPC) -} \ No newline at end of file + + 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, player: Player): Int { + val index = combatBracket.indexOfFirst { player.properties.currentCombatLevel <= it }.takeIf { it != -1 }?: ids.lastIndex + return ids[index] + } + + fun sayLine(npc: NPC, phrases: Array, hasOpeningPhrase: Boolean, hasOverTimePhrase: Boolean) { + val inInteraction = getAttribute(player, "random:pause", false) //used by Certer + if ((ticksLeft % 20 == 0 || ticksLeft <= 2) && !inInteraction) { //speak every 20 ticks, or in the 2nd-to-last tick before attack/note-&-teleport + var playDwarfWhistle = true + if (ticksLeft == secondsToTicks(180) && hasOpeningPhrase) { + sendChat(phrases[0]) + } else if (ticksLeft <= 2 && hasOverTimePhrase) { + sendChat(phrases[phrases.size - 1]) + playDwarfWhistle = false + } else { + val start = if (hasOpeningPhrase) 0 else 1 + val end = if (hasOverTimePhrase) phrases.size - 2 else phrases.size - 1 + sendChat(phrases[RandomFunction.random(start, end + 1)]) + } + if (npc.id == NPCs.DRUNKEN_DWARF_956 && playDwarfWhistle) { + playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297) + } + } + } +} diff --git a/Server/src/main/content/global/ame/RandomEvents.kt b/Server/src/main/content/global/ame/RandomEvents.kt index 7e07d744a..db5ad9b2e 100644 --- a/Server/src/main/content/global/ame/RandomEvents.kt +++ b/Server/src/main/content/global/ame/RandomEvents.kt @@ -1,23 +1,28 @@ package content.global.ame import org.rs09.consts.Items -import content.global.ame.events.MysteriousOldManNPC +import content.global.ame.events.surpriseexam.MysteriousOldManNPC import content.global.ame.events.certer.CerterNPC -import content.global.ame.events.drilldemon.SeargentDamienNPC +import content.global.ame.events.drilldemon.SergeantDamienNPC import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC import content.global.ame.events.evilbob.EvilBobNPC import content.global.ame.events.evilchicken.EvilChickenNPC import content.global.ame.events.freakyforester.FreakyForesterNPC +import content.global.ame.events.maze.MazeNPC import content.global.ame.events.genie.GenieNPC +import content.global.ame.events.candlelight.PiousPeteNPC +import content.global.ame.events.pillory.PilloryNPC import content.global.ame.events.rickturpentine.RickTurpentineNPC import content.global.ame.events.rivertroll.RiverTrollRENPC import content.global.ame.events.rockgolem.RockGolemRENPC +import content.global.ame.events.quizmaster.QuizMasterNPC import content.global.ame.events.sandwichlady.SandwichLadyRENPC import content.global.ame.events.shade.ShadeRENPC import content.global.ame.events.strangeplant.StrangePlantNPC import content.global.ame.events.swarm.SwarmNPC import content.global.ame.events.treespirit.TreeSpiritRENPC import content.global.ame.events.zombie.ZombieRENPC +import core.ServerConstants import core.api.utils.WeightBasedTable import core.api.utils.WeightedItem @@ -26,6 +31,7 @@ import core.game.node.entity.skill.Skills enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = null, val skillIds: IntArray = intArrayOf(), val type: String = "") { SANDWICH_LADY(npc = SandwichLadyRENPC()), GENIE(npc = GenieNPC()), + CANDLELIGHT(npc = PiousPeteNPC(), skillIds = intArrayOf(Skills.PRAYER)), CERTER(npc = CerterNPC(), loot = WeightBasedTable.create( WeightedItem(Items.UNCUT_SAPPHIRE_1623,1,1,3.4), WeightedItem(Items.KEBAB_1971,1,1,1.7), @@ -43,7 +49,8 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1), WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1) )), - DRILL_DEMON(npc = SeargentDamienNPC()), + MAZE(npc = MazeNPC()), + DRILL_DEMON(npc = SergeantDamienNPC()), EVIL_CHICKEN(npc = EvilChickenNPC()), STRANGE_PLANT(npc = StrangePlantNPC()), SWARM(npc = SwarmNPC()), @@ -52,7 +59,9 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot), SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"), FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)), + PILLORY(npc = PilloryNPC(), skillIds = intArrayOf(Skills.THIEVING)), TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)), + QUIZ_MASTER(npc = QuizMasterNPC()), RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)), ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)), SHADE(ShadeRENPC(), skillIds = intArrayOf(Skills.PRAYER)), @@ -76,6 +85,9 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n private fun populateMappings() { for (event in values()) { + if (!ServerConstants.INAUTHENTIC_CANDLELIGHT_RANDOM && event == CANDLELIGHT) { + continue + } for (id in event.skillIds) { val list = skillMap[id] ?: ArrayList().also { skillMap[id] = it } list.add (event) @@ -85,5 +97,4 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n } } } - } diff --git a/Server/src/main/content/global/ame/events/HostileRandomEventBehavior.kt b/Server/src/main/content/global/ame/events/HostileRandomEventBehavior.kt new file mode 100644 index 000000000..952bd0289 --- /dev/null +++ b/Server/src/main/content/global/ame/events/HostileRandomEventBehavior.kt @@ -0,0 +1,20 @@ +package content.global.ame.events + +import core.api.getAttribute +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +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.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 { + val xprate = super.getXpMultiplier(self, attacker) + return if (getAttribute(self, "spawned-by-ame", false)) xprate / 16.0 else xprate + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/MysteriousOldManDialogue.kt b/Server/src/main/content/global/ame/events/MysteriousOldManDialogue.kt deleted file mode 100644 index 628a3c8f0..000000000 --- a/Server/src/main/content/global/ame/events/MysteriousOldManDialogue.kt +++ /dev/null @@ -1,41 +0,0 @@ -package content.global.ame.events - -import core.game.node.entity.player.Player -import content.global.ame.events.supriseexam.SurpriseExamUtils -import core.game.dialogue.DialogueFile -import core.game.system.timer.impl.AntiMacro - -class MysteriousOldManDialogue(val type: String) : DialogueFile() { - - val CHOICE_STAGE = 50000 - - override fun handle(componentID: Int, buttonID: Int) { - - if(type == "sexam" && stage < CHOICE_STAGE){ - npc("Would you like to come do a surprise exam?") - stage = CHOICE_STAGE - } - - else if(stage >= CHOICE_STAGE){ - when(stage) { - CHOICE_STAGE -> options("Yeah, sure!", "No, thanks.").also { stage++ } - CHOICE_STAGE.substage(1) -> when(buttonID){ - 1 -> { - end() - teleport(player!!,type) - AntiMacro.terminateEventNpc(player!!) - } - 2 -> { - end() - AntiMacro.terminateEventNpc(player!!) - } - } - } - } - } - fun teleport(player: Player,type: String){ - when(type){ - "sexam" -> SurpriseExamUtils.teleport(player) - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/MysteriousOldManNPC.kt b/Server/src/main/content/global/ame/events/MysteriousOldManNPC.kt deleted file mode 100644 index 3ed7289b1..000000000 --- a/Server/src/main/content/global/ame/events/MysteriousOldManNPC.kt +++ /dev/null @@ -1,31 +0,0 @@ -package content.global.ame.events - -import content.global.ame.RandomEventNPC -import core.game.node.entity.npc.NPC -import core.tools.RandomFunction -import org.rs09.consts.NPCs -import core.api.utils.WeightBasedTable - -class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) { - override fun init() { - super.init() - sayLine() - } - - override fun tick() { - super.tick() - if(RandomFunction.random(1,10) == 5) sayLine() - } - - fun sayLine() { - when(type){ - "sexam" -> sendChat("Surprise exam, ${player.username.capitalize()}!") - } - } - - override fun talkTo(npc: NPC) { - when(type){ - "sexam" -> player.dialogueInterpreter.open(MysteriousOldManDialogue("sexam"),this.asNpc()) - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/candlelight/CandlelightInterface.kt b/Server/src/main/content/global/ame/events/candlelight/CandlelightInterface.kt new file mode 100644 index 000000000..249f9f194 --- /dev/null +++ b/Server/src/main/content/global/ame/events/candlelight/CandlelightInterface.kt @@ -0,0 +1,164 @@ +package content.global.ame.events.candlelight + +import core.api.* +import core.api.utils.PlayerCamera +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import org.rs09.consts.Scenery + +/** + * Candlelight Interface CANDLELIGHT_178 + * + */ +class CandlelightInterface : InterfaceListener, InteractionListener, MapArea { + companion object { + const val CANDLELIGHT_INTERFACE = 178 + const val CANDLELIGHT_RETURN_LOC = "/save:original-loc" + const val CANDLELIGHT_CANDLE_ARRAY = "/save:candlelight:candle-array" + const val CANDLELIGHT_CAMERA_AT = "candlelight:camera-at" + + val CANDLE_LOC_ARRAY = arrayOf( + Location(1967, 4997), + Location(1968, 4998), + Location(1967, 4999), + Location(1968, 5000), + Location(1967, 5001), + Location(1968, 5002), + Location(1967, 5003), + Location(1968, 5004), + Location(1967, 5005), + Location(1968, 5006), + Location(1967, 5007), + ) + + fun initCandlelight(player: Player) { + val candleArray = intArrayOf(0,0,0,0,0,0,2,2,2,2,2) + candleArray.shuffle() + setAttribute(player, CANDLELIGHT_CANDLE_ARRAY, candleArray) + for (candleIndex in 0..10) { + setVarbit(player, 1771 + candleIndex, candleArray[candleIndex]) + } + } + + fun areCandlesLit(player: Player): Boolean { + val candleArray = getAttribute(player, CANDLELIGHT_CANDLE_ARRAY, intArrayOf(0,0,0,0,0,0,0,0,0,0,0)) + for (candle in candleArray) { + if (candle == 0) { + return false + } + } + return true + } + + fun lightCandle(player: Player) { + var currentCamLoc = getAttribute(player, CANDLELIGHT_CAMERA_AT, Location(1968, 5002)) + val candleIndex = CANDLE_LOC_ARRAY.indexOf(currentCamLoc) + val varbit = candleIndex + 1771 // Essentially all varbits are 1771 .. 1881 + + if (candleIndex != -1) { + val candleArray = getAttribute(player, CANDLELIGHT_CANDLE_ARRAY, intArrayOf(0,0,0,0,0,0,0,0,0,0,0)) + if (candleArray[candleIndex] == 0) { + candleArray[candleIndex] = 1 + setAttribute(player, CANDLELIGHT_CANDLE_ARRAY, candleArray) + setVarbit(player, varbit, 1) + sendMessage(player, "You light the candle.") + } else if (candleArray[candleIndex] == 1) { + sendMessage(player, "This candle is already lit.") + } else { + sendMessage(player, "This candle is too short to light.") + } + } else { + sendMessage(player, "There is nothing to light here.") + } + } + + fun moveCamera(player: Player, direction: Direction, firstTime: Boolean = false) { + var currentCamLoc = getAttribute(player, CANDLELIGHT_CAMERA_AT, Location(1968, 5002)) + when(direction) { + Direction.NORTH -> currentCamLoc = currentCamLoc.transform(Direction.NORTH) + Direction.SOUTH -> currentCamLoc = currentCamLoc.transform(Direction.SOUTH) + Direction.EAST -> currentCamLoc = currentCamLoc.transform(Direction.EAST) + Direction.WEST -> currentCamLoc = currentCamLoc.transform(Direction.WEST) + else -> {} + } + if (currentCamLoc.x < 1967) { currentCamLoc.x = 1967 } + if (currentCamLoc.x > 1968) { currentCamLoc.x = 1968 } + if (currentCamLoc.y < 4997) { currentCamLoc.y = 4997 } + if (currentCamLoc.y > 5007) { currentCamLoc.y = 5007 } + setAttribute(player, CANDLELIGHT_CAMERA_AT, currentCamLoc) + PlayerCamera(player).rotateTo(currentCamLoc.x - 30, currentCamLoc.y,0,200) // height is kind of a relative value? + PlayerCamera(player).panTo(currentCamLoc.x + 2, currentCamLoc.y,350, if(firstTime) 400 else 10) + } + } + + override fun defineInterfaceListeners() { + on(CANDLELIGHT_INTERFACE){ player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + 1 -> moveCamera(player, Direction.WEST) + 2 -> moveCamera(player, Direction.EAST) + 3 -> lightCandle(player)/* Light */ + 4 -> moveCamera(player, Direction.SOUTH) + 5 -> moveCamera(player, Direction.NORTH) + 9 -> closeInterface(player) + } + return@on true + } + + onOpen(CANDLELIGHT_INTERFACE){ player, component -> + // Move camera + return@onOpen true + } + + onClose(CANDLELIGHT_INTERFACE){ player, component -> + PlayerCamera(player).reset() + // Reset camera + return@onClose true + } + } + + + override fun defineListeners() { + on((11364 .. 11394).toIntArray(), SCENERY, "light") { player, node -> + setAttribute(player, CANDLELIGHT_CAMERA_AT, Location(node.location.x, node.location.y)) + moveCamera(player, Direction.NORTH_WEST, true) + openInterface(player, CANDLELIGHT_INTERFACE) + return@on true + } + } + + override fun defineDestinationOverrides() { + setDest(SCENERY, (11364 .. 11394).toIntArray(),"light"){ player, node -> + return@setDest Location(1970, node.location.y) + } + } + + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders.forRegion(7758)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + initCandlelight(entity) + 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() + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/candlelight/PiousPeteDialogue.kt b/Server/src/main/content/global/ame/events/candlelight/PiousPeteDialogue.kt new file mode 100644 index 000000000..9eb9b7ede --- /dev/null +++ b/Server/src/main/content/global/ame/events/candlelight/PiousPeteDialogue.kt @@ -0,0 +1,94 @@ +package content.global.ame.events.candlelight + +import content.global.ame.RandomEvents +import content.global.ame.events.pillory.PilloryInterface +import content.global.ame.returnPlayer +import core.api.* +import core.game.dialogue.* +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +// iface 178 + +@Initializable +class PiousPeteDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return PiousPeteDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, PiousPeteDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.PIOUS_PETE_3207, NPCs._6564) + } +} + +class PiousPeteDialogueFile : DialogueLabeller() { + + override fun addConversation() { + npc(ChatAnim.THINKING, "Have you lit all the tall candles?") + exec { player, npc -> + if (CandlelightInterface.areCandlesLit(player)) { + loadLabel(player, "yeslit") + } else { + loadLabel(player, "nolit") + } + } + + label("nolit") + player(ChatAnim.HALF_GUILTY, "Sorry, not yet.") + npc(ChatAnim.SAD, "Please help me in lighting the candles. I just need you to light all the tall candles, but not the short ones.") + line("Click on the pillars to open an interface", "to move around and light the candles.") + + label("yeslit") + player(ChatAnim.FRIENDLY, "Yes, the tall ones are all lit.") + npc(ChatAnim.HAPPY, "Thank you my brother! I will now return you where you came from with a parting gift.") + npc(ChatAnim.FRIENDLY, "Take care brother!") + exec { player, npc -> + 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 -> { + returnPlayer(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + closeInterface(player) + return@queueScript delayScript(player, 3) + } + 2 -> { + val loot = RandomEvents.CERTER.loot!!.roll(player)[0] + addItemOrDrop(player, loot.id, loot.amount) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + } +} +class PiousPeteStartingDialogueFile : DialogueLabeller() { + + override fun addConversation() { + npc("I'm sorry to drag you away from your tasks, but I need a little help with something.") + player(ChatAnim.THINKING,"How can I help?") + npc("This is a chapel dedicated to our lord, Saradomin, and I'm tasked with maintaining this chapel.") + npc(ChatAnim.SAD,"My task is to light the chapel candles, but I couldn't reach them myself and I kept getting dazzled by the light whenever I tried.") + npc("So I need your help in lighting the candles. I need you to light all the tall candles, but not the short ones.") + npc(ChatAnim.FRIENDLY, "Once all the tall candles are all lit, come back and see me, and I will reward you for your work.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/candlelight/PiousPeteNPC.kt b/Server/src/main/content/global/ame/events/candlelight/PiousPeteNPC.kt new file mode 100644 index 000000000..5231b6f9c --- /dev/null +++ b/Server/src/main/content/global/ame/events/candlelight/PiousPeteNPC.kt @@ -0,0 +1,26 @@ +package content.global.ame.events.candlelight + +import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class PiousPeteNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PRIEST_3206) { + override fun init() { + super.init() + // Supposed to be "I'm sorry to drag you away from your tasks, but I need a little help with something." but it's too goddamn long. + sendChat("${player.username}! I need a little help with something.") + face(player) + kidnapPlayer(this, player, Location(1972, 5002, 0)) { player, _ -> + CandlelightInterface.initCandlelight(player) + openDialogue(player, PiousPeteStartingDialogueFile(), NPC(NPCs.PIOUS_PETE_3207)) + } + } + + override fun talkTo(npc: NPC) { + player.dialogueInterpreter.open(PiousPeteDialogueFile(),npc) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/certer/CerterNPC.kt b/Server/src/main/content/global/ame/events/certer/CerterNPC.kt index daf3bc822..dee88ed3a 100644 --- a/Server/src/main/content/global/ame/events/certer/CerterNPC.kt +++ b/Server/src/main/content/global/ame/events/certer/CerterNPC.kt @@ -2,29 +2,20 @@ package content.global.ame.events.certer import core.game.node.entity.npc.NPC import core.game.node.entity.player.link.emote.Emotes -import core.tools.RandomFunction import org.rs09.consts.NPCs import content.global.ame.RandomEventNPC import core.api.animate +import core.api.lock +import core.api.setAttribute import core.api.utils.WeightBasedTable class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) { - lateinit var pName: String lateinit var phrases: Array override fun tick() { - // Don't speak if we have the interface opened - if (!timerPaused) { - // Over allotted time phrase - if (ticksLeft <= 2) { - player.lock(2) - sendChat(phrases[4]) - - // Say a phrase every 20 ticks starting at 280 ticks - // as to not interfere with the init chat phrase - } else if (ticksLeft <= 280 && ticksLeft % 20 == 0) { - sendChat(phrases[RandomFunction.random(1, 3)]) - } + sayLine(this, phrases, true, true) + if (ticksLeft == 2) { + lock(player, 2) } super.tick() } @@ -36,15 +27,19 @@ class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NP override fun init() { super.init() - pName = player.username.capitalize() - phrases = arrayOf("Greetings $pName, I need your help.", - "ehem... Hello $pName, please talk to me!", - "Hello, are you there $pName?", - "It's really rude to ignore someone, $pName!", - "No-one ignores me!") - player.setAttribute("random:pause", false) - player.setAttribute("certer:reward", false) - sendChat(phrases[0]) + phrases = arrayOf( + "Greetings ${player.username}, I need your help.", + "ehem... Hello ${player.username}, please talk to me!", + "Hello, are you there ${player.username}?", + "It's really rude to ignore someone, ${player.username}!", + "No-one ignores me!" + ) + setAttribute(player, "certer:reward", false) animate(this, Emotes.BOW.animation, true) } -} \ No newline at end of file + + override fun onTimeUp() { + noteAndTeleport() + terminate() + } +} diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt index cb270f02f..2287de37d 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt @@ -79,7 +79,7 @@ class DrillDemonListeners : InteractionListener, MapArea { } override fun getRestrictions(): Array { - return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) } override fun areaEnter(entity: Entity) { @@ -90,4 +90,4 @@ class DrillDemonListeners : InteractionListener, MapArea { setComponentVisibility(entity.asPlayer(), 746, 12, true) } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt index a85bde6a3..8c90bd77f 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt @@ -1,9 +1,9 @@ package content.global.ame.events.drilldemon +import content.global.ame.returnPlayer import core.api.* import core.game.interaction.QueueStrength import core.game.node.entity.player.Player -import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import core.game.world.update.flag.context.Animation import org.rs09.consts.Items @@ -11,7 +11,6 @@ import org.rs09.consts.NPCs object DrillDemonUtils { val DD_KEY_TASK = "/save:drilldemon:task" - val DD_KEY_RETURN_LOC = "/save:drilldemon:original-loc" val DD_SIGN_VARP = 531 val DD_SIGN_JOG = 0 val DD_SIGN_SITUP = 1 @@ -22,14 +21,6 @@ object DrillDemonUtils { val DD_AREA = ZoneBorders(3158, 4817, 3168, 4823) val DD_NPC = NPCs.SERGEANT_DAMIEN_2790 - fun teleport(player: Player) { - setAttribute(player, DD_KEY_RETURN_LOC, player.location) - teleport(player, Location.create(3163, 4819, 0)) - player.interfaceManager.closeDefaultTabs() - setComponentVisibility(player, 548, 69, true) - setComponentVisibility(player, 746, 12, true) - } - fun changeSignsAndAssignTask(player: Player) { setVarp(player, DD_SIGN_VARP, 0) val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList() @@ -63,13 +54,8 @@ object DrillDemonUtils { } fun cleanup(player: Player) { - player.locks.unlockTeleport() - unlock(player) - teleport(player, getAttribute(player, DD_KEY_RETURN_LOC, Location.create(3222, 3218, 0))) - removeAttribute(player, DD_KEY_RETURN_LOC) - removeAttribute(player, DD_KEY_TASK) - removeAttribute(player, DD_CORRECT_OFFSET) - removeAttribute(player, DD_CORRECT_COUNTER) + returnPlayer(player) + removeAttributes(player, DD_KEY_TASK, DD_CORRECT_OFFSET, DD_CORRECT_COUNTER) player.interfaceManager.openDefaultTabs() setComponentVisibility(player, 548, 69, false) setComponentVisibility(player, 746, 12, false) @@ -98,6 +84,5 @@ object DrillDemonUtils { } return@queueScript stopExecuting(player) } - } } diff --git a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt deleted file mode 100644 index f767b0554..000000000 --- a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt +++ /dev/null @@ -1,38 +0,0 @@ -package content.global.ame.events.drilldemon - -import core.game.node.entity.npc.NPC -import org.rs09.consts.NPCs -import content.global.ame.RandomEventNPC -import core.api.* -import core.api.utils.WeightBasedTable - -import core.game.interaction.QueueStrength -import core.game.system.timer.impl.AntiMacro -import core.tools.secondsToTicks - -class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) { - - override fun init() { - super.init() - sendChat(player.username.capitalize() + "! Drop and give me 20!") - queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> - when (stage) { - 0 -> { - lock(player, secondsToTicks(30)) - DrillDemonUtils.teleport(player) - AntiMacro.terminateEventNpc(player) - return@queueScript delayScript(player, 2) - } - 1 -> { - openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790) - return@queueScript stopExecuting(player) - } - else -> return@queueScript stopExecuting(player) - } - } - } - - override fun talkTo(npc: NPC) { - openDialogue(player, SeargentDamienDialogue(), npc) - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt new file mode 100644 index 000000000..2a3ec7f51 --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt @@ -0,0 +1,28 @@ +package content.global.ame.events.drilldemon + +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs +import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer +import core.api.* +import core.api.utils.WeightBasedTable + +import core.game.world.map.Location + +class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) { + override fun init() { + super.init() + sendChat("${player.username}! Drop and give me 20!") + face(player) + kidnapPlayer(this, player, Location(3163, 4819, 0)) { player, _ -> + player.interfaceManager.closeDefaultTabs() + setComponentVisibility(player, 548, 69, true) + setComponentVisibility(player, 746, 12, true) + openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790) + } + } + + override fun talkTo(npc: NPC) { + openDialogue(player, SeargentDamienDialogue(), npc) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt index 1485dd8c4..f4a6842ff 100644 --- a/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt +++ b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt @@ -9,35 +9,27 @@ import org.rs09.consts.NPCs import org.rs09.consts.Sounds class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.DRUNKEN_DWARF_956) { - private val phrases = arrayOf("Oi, are you der @name!","Dunt ignore your matey!","Aww comeon, talk to ikle me @name!") - private var attackPhrase = false + lateinit var phrases: Array private var attackDelay = 0 - private var lastPhraseTime = 0 - - private fun sendPhrases() { - if (getWorldTicks() > lastPhraseTime + 5) { - playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297) - sendChat(this, phrases.random().replace("@name",player.username.capitalize())) - this.face(player) - lastPhraseTime = getWorldTicks() - } - } override fun init() { super.init() - playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297) - sendChat(this, "'Ello der ${player.username.capitalize()}! *hic*") + phrases = arrayOf( + "'Ello der ${player.username}! *hic*", + "Oi, are you der ${player.username}!", + "Dunt ignore your matey!", + "Aww comeon, talk to ikle me ${player.username}!", + "I hates you, ${player.username}!" + ) } override fun tick() { - if (RandomFunction.roll(20) && !attackPhrase) - sendPhrases() + sayLine(this, phrases, true, true) if (ticksLeft <= 10) { ticksLeft = 10 - if (!attackPhrase) - sendChat("I hates you, ${player.username.capitalize()}!").also { attackPhrase = true } - if (attackDelay <= getWorldTicks()) + if (attackDelay <= getWorldTicks()) { this.attack(player) + } } super.tick() } @@ -47,4 +39,10 @@ class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEvent this.pulseManager.clear() openDialogue(player, DrunkenDwarfDialogue(), this.asNpc()) } + + override fun onTimeUp() { + if (attackDelay <= getWorldTicks()) { + this.attack(player) + } + } } \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt index fc71ebd68..f2a3e9134 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt @@ -1,5 +1,6 @@ package content.global.ame.events.evilbob +import content.global.ame.returnPlayer import core.ServerConstants import core.api.* import core.game.dialogue.FacialExpression @@ -8,8 +9,6 @@ import core.game.interaction.InteractionListener import core.game.interaction.QueueStrength import core.game.node.entity.Entity import core.game.node.entity.player.link.emote.Emotes -import core.game.node.entity.skill.Skills -import core.game.system.task.Pulse import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneRestriction @@ -121,7 +120,7 @@ class EvilBobListeners : InteractionListener, MapArea { } 3 -> { sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.") - teleport(player, getAttribute(player, EvilBobUtils.prevLocation, Location.create(3222, 3219, 0))) + returnPlayer(player) EvilBobUtils.reward(player) EvilBobUtils.cleanup(player) resetAnimator(player) @@ -139,7 +138,7 @@ class EvilBobListeners : InteractionListener, MapArea { } override fun getRestrictions(): Array { - return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) } override fun areaEnter(entity: Entity) { diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt index fc0fe2826..4995b6b41 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt @@ -1,40 +1,22 @@ package content.global.ame.events.evilbob import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer import core.api.* import core.api.utils.WeightBasedTable -import core.game.interaction.QueueStrength import core.game.node.entity.npc.NPC -import core.game.system.timer.impl.AntiMacro +import core.game.world.map.Location import org.rs09.consts.NPCs -import org.rs09.consts.Sounds class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.EVIL_BOB_2478) { - override fun init() { super.init() sendChat("meow") - queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> - when (stage) { - 0 -> { - lock(player, 6) - sendChat(player, "No... what? Nooooooooooooo!") - animate(player, EvilBobUtils.teleAnim) - player.graphics(EvilBobUtils.telegfx) - playAudio(player, Sounds.TELEPORT_ALL_200) - EvilBobUtils.giveEventFishingSpot(player) - return@queueScript delayScript(player, 3) - } - 1 -> { - sendMessage(player, "Welcome to Scape2009.") - EvilBobUtils.teleport(player) - resetAnimator(player) - openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) - AntiMacro.terminateEventNpc(player) - return@queueScript stopExecuting(player) - } - else -> return@queueScript stopExecuting(player) - } + face(player) + kidnapPlayer(this, player, Location(3419, 4776, 0), "No... what? Nooooooooooooo!") { player, _ -> + EvilBobUtils.giveEventFishingSpot(player) + sendMessage(player, "Welcome to Scape2009.") + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) } } diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt index 9d5f4957d..58f8e5aee 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt @@ -3,7 +3,6 @@ package content.global.ame.events.evilbob import core.api.* import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills -import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics @@ -13,10 +12,8 @@ import org.rs09.consts.NPCs import org.rs09.consts.Scenery object EvilBobUtils { - const val prevLocation = "/save:evilbob:prevlocation" const val eventComplete = "/save:evilbob:eventcomplete" const val assignedFishingZone = "/save:evilbob:fishingzone" - const val fishCaught = "evilbob:fishcaught" const val attentive = "/save:evilbob:attentive" const val servantHelpDialogueSeen = "/save:evilbob:servantdialogeseen" const val attentiveNewSpot = "/save:evilbob:attentivenewspot" @@ -52,15 +49,8 @@ object EvilBobUtils { } } - fun teleport(player: Player) { - setAttribute(player, prevLocation, player.location) - player.properties.teleportLocation = Location.create(3419, 4776, 0) - } - fun cleanup(player: Player) { - player.locks.unlockTeleport() - player.properties.teleportLocation = getAttribute(player, prevLocation, null) - removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) + removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) removeAll(player, Items.FISHLIKE_THING_6202) removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK) removeAll(player, Items.FISHLIKE_THING_6206) diff --git a/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt b/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt index db54e0db9..4dfc72698 100644 --- a/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt +++ b/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt @@ -3,38 +3,47 @@ package content.global.ame.events.evilbob import core.api.* import core.game.activity.Cutscene import core.game.node.entity.player.Player +import core.game.world.map.Direction class ServantCutsceneN(player: Player) : Cutscene(player) { override fun setup() { setExit(player.location.transform(0, 0, 0)) loadRegion(13642) + addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob + addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant } override fun runStage(stage: Int) { when (stage) { 0 -> { - fadeToBlack() - timedUpdate(4) + teleport(player, 30, 41) + moveCamera(30, 37, 400, 255) + rotateCamera(30, 50, 400, 255) + openInterface(player, 186) + timedUpdate(0) } 1 -> { - teleport(player, 29, 41) - moveCamera(30, 43) // +7 from statue - openInterface(player, 186) + timedUpdate(0) + } + 2 -> { // Slow start + moveCamera(30, 49, 400, 2) timedUpdate(2) } - 2 -> { + 3 -> { // Fast middle + moveCamera(30, 44, 380, 4) + timedUpdate(6) + } + 4 -> { // Slow end + moveCamera(30, 45, 340, 2) timedUpdate(2) - rotateCamera(30, 51, 300, 100) // the statue loc - fadeFromBlack() } - 3 -> { - timedUpdate(9) - moveCamera(30, 46, 300, 2) // +4 from statue + 5 -> { + timedUpdate(2) } - 4 -> { - end{ player.locks.lockTeleport(1000000) } + 6 -> { closeInterface(player) + end(fade = false) { player.locks.lockTeleport(1000000) } } } } @@ -45,32 +54,40 @@ class ServantCutsceneS(player: Player) : Cutscene(player) { override fun setup() { setExit(player.location.transform(0, 0, 0)) loadRegion(13642) + addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob + addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant } override fun runStage(stage: Int) { when (stage) { 0 -> { - fadeToBlack() - timedUpdate(4) + teleport(player, 30, 41) + moveCamera(31, 46, 365, 255) + rotateCamera(29, 30, 365, 255) + openInterface(player, 186) + timedUpdate(0) } 1 -> { - teleport(player, 29, 41) - moveCamera(29, 38) // +7 from statue - openInterface(player, 186) - timedUpdate(2) + timedUpdate(0) } 2 -> { + moveCamera(31, 43, 480, 2) timedUpdate(2) - rotateCamera(29, 30, 300, 100) // the statue loc - fadeFromBlack() } 3 -> { - timedUpdate(9) - moveCamera(29, 35, 300, 2) // +4 from statue + moveCamera(31, 37, 455, 4) + timedUpdate(8) } 4 -> { - end{ player.locks.lockTeleport(1000000) } + moveCamera(31, 36, 395, 2) + timedUpdate(2) + } + 5 -> { + timedUpdate(3) + } + 6 -> { closeInterface(player) + end(fade = false) { player.locks.lockTeleport(1000000) } } } } @@ -81,32 +98,40 @@ class ServantCutsceneE(player: Player) : Cutscene(player) { override fun setup() { setExit(player.location.transform(0, 0, 0)) loadRegion(13642) + addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob + addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant } override fun runStage(stage: Int) { when (stage) { 0 -> { - fadeToBlack() - timedUpdate(4) + teleport(player, 30, 41) + moveCamera(25, 41, 440, 255) + rotateCamera(42, 41, 440, 255) + openInterface(player, 186) + timedUpdate(0) } 1 -> { - teleport(player, 29, 41) - moveCamera(35, 41) // +7 from statue - openInterface(player, 186) + timedUpdate(0) + } + 2 -> { // Slow start + moveCamera(28, 41, 500, 3) timedUpdate(2) } - 2 -> { + 3 -> { // Fast middle + moveCamera(34, 41, 390, 5) + timedUpdate(6) + } + 4 -> { // Slow end + moveCamera(36, 41, 340, 2) timedUpdate(2) - rotateCamera(43, 41, 300, 100) // the statue loc - fadeFromBlack() } - 3 -> { - timedUpdate(9) - moveCamera(38, 41, 300, 2) // +4 from statue + 5 -> { + timedUpdate(4) } - 4 -> { - end{ player.locks.lockTeleport(1000000) } + 6 -> { closeInterface(player) + end(fade = false) { player.locks.lockTeleport(1000000) } } } } @@ -117,34 +142,41 @@ class ServantCutsceneW(player: Player) : Cutscene(player) { override fun setup() { setExit(player.location.transform(0, 0, 0)) loadRegion(13642) + addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob + addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant } override fun runStage(stage: Int) { when (stage) { 0 -> { - fadeToBlack() - timedUpdate(4) + teleport(player, 30, 41) + moveCamera(34, 41, 325, 255) + rotateCamera(16, 40, 300, 255) + openInterface(player, 186) + timedUpdate(0) } 1 -> { - teleport(player, 29, 41) - moveCamera(25, 40) // +7 from statue - openInterface(player, 186) + timedUpdate(0) + } + 2 -> { // Slow start + moveCamera(31, 41, 440, 3) timedUpdate(2) } - 2 -> { + 3 -> { // Fast middle + moveCamera(24, 41, 330, 5) + timedUpdate(7) + } + 4 -> { // Slow end + moveCamera(23, 41, 300, 2) timedUpdate(2) - rotateCamera(18, 40, 300, 100) // the statue loc - fadeFromBlack() } - 3 -> { - timedUpdate(9) - moveCamera(22, 40, 300, 2) // +4 from statue + 5 -> { + timedUpdate(3) } - 4 -> { - end{ player.locks.lockTeleport(1000000) } + 6 -> { closeInterface(player) + end(fade = false) { player.locks.lockTeleport(1000000) } } - } } } \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt b/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt index ac26b914b..5b065f567 100644 --- a/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt +++ b/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt @@ -9,9 +9,8 @@ import core.tools.RandomFunction import org.rs09.consts.Items import content.global.ame.RandomEventNPC import core.api.utils.WeightBasedTable -import java.lang.Integer.max -val ids = 2463..2468 +val ids = (2463..2468).toList() class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) { val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!") @@ -19,8 +18,7 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN override fun init() { super.init() - val index = max(0, (player.properties.combatLevel / 20) - 1) - val id = ids.toList()[index] + val id = idForCombatLevel(ids, player) this.transform(id) this.attack(player) sendChat(phrases.random().replace("@name",player.username.capitalize())) diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt index e2d36acc0..8754a8d08 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt @@ -57,10 +57,10 @@ class FreakListeners : InteractionListener, MapArea { } override fun getRestrictions(): Array { - return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) } override fun areaEnter(entity: Entity) { entity.locks.lockTeleport(1000000) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt index cd76dc23d..84e491f89 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt @@ -1,16 +1,15 @@ package content.global.ame.events.freakyforester +import content.global.ame.returnPlayer import core.api.* import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.node.entity.player.Player -import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import core.tools.RandomFunction object FreakUtils{ const val freakNpc = NPCs.FREAKY_FORESTER_2458 - const val freakPreviousLoc = "/save:freakyf:location" const val freakTask = "/save:freakyf:task" const val freakComplete = "/save:freakyf:complete" const val pheasantKilled = "freakyf:killed" @@ -26,15 +25,9 @@ object FreakUtils{ player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc) } - fun teleport(player: Player) { - setAttribute(player, freakPreviousLoc, player.location) - teleport(player, Location.create(2599, 4777 ,0)) - } - fun cleanup(player: Player) { - player.locks.unlockTeleport() - player.properties.teleportLocation = getAttribute(player,freakPreviousLoc,null) - removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled) + returnPlayer(player) + removeAttributes(player, freakTask, freakComplete, pheasantKilled) removeAll(player, Items.RAW_PHEASANT_6178) removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK) removeAll(player, Items.RAW_PHEASANT_6179) diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt index 4b0366263..1ef52dde6 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt @@ -1,39 +1,21 @@ package content.global.ame.events.freakyforester import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer import core.api.* import org.rs09.consts.NPCs import core.api.utils.WeightBasedTable -import core.game.interaction.QueueStrength import core.game.node.entity.npc.NPC -import core.game.system.timer.impl.AntiMacro -import core.game.world.update.flag.context.Graphics -import org.rs09.consts.Sounds +import core.game.world.map.Location class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) { - override fun init() { super.init() sendChat("Ah, ${player.username}, just the person I need!") - queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> - when (stage) { - 0 -> { - lock(player, 6) - sendGraphics(Graphics(308, 100, 50), player.location) - animate(player,714) - playAudio(player, Sounds.TELEPORT_ALL_200) - return@queueScript delayScript(player, 3) - } - 1 -> { - FreakUtils.teleport(player) - FreakUtils.giveFreakTask(player) - AntiMacro.terminateEventNpc(player) - openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc) - resetAnimator(player) - return@queueScript stopExecuting(player) - } - else -> return@queueScript stopExecuting(player) - } + face(player) + kidnapPlayer(this, player, Location(2599, 4777, 0)) { player, _ -> + FreakUtils.giveFreakTask(player) + openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc) } } diff --git a/Server/src/main/content/global/ame/events/genie/GenieNPC.kt b/Server/src/main/content/global/ame/events/genie/GenieNPC.kt index 6f3cf39a1..b4700a9a5 100644 --- a/Server/src/main/content/global/ame/events/genie/GenieNPC.kt +++ b/Server/src/main/content/global/ame/events/genie/GenieNPC.kt @@ -4,27 +4,40 @@ import core.game.node.entity.npc.NPC import core.tools.RandomFunction import org.rs09.consts.NPCs import content.global.ame.RandomEventNPC +import core.api.lock import core.api.playAudio import core.api.utils.WeightBasedTable import org.rs09.consts.Sounds class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) { - val phrases = arrayOf("Greetings, @name!","Ehem... Master @name?","Are you there, Master @name?","No one ignores me!") + lateinit var phrases: Array override fun tick() { - if(RandomFunction.random(1,15) == 5){ - sendChat(phrases.random().replace("@name",player.username.capitalize())) + sayLine(this, phrases, true, true) + if (ticksLeft == 2) { + lock(player, 2) } super.tick() } override fun init() { super.init() + val honorific = if (player.isMale) "Master" else "Mistress" + phrases = arrayOf( + "Greetings, ${player.username}!", + "Ehem... $honorific ${player.username}?", + "Are you there, $honorific ${player.username}?", + "No one ignores me!" + ) playAudio(player, Sounds.GENIE_APPEAR_2301) - sendChat(phrases.random().replace("@name",player.username.capitalize())) } override fun talkTo(npc: NPC) { player.dialogueInterpreter.open(GenieDialogue(),npc) } + + override fun onTimeUp() { + noteAndTeleport() + terminate() + } } diff --git a/Server/src/main/content/global/ame/events/maze/MazeInterface.kt b/Server/src/main/content/global/ame/events/maze/MazeInterface.kt new file mode 100644 index 000000000..c3c1ab7f4 --- /dev/null +++ b/Server/src/main/content/global/ame/events/maze/MazeInterface.kt @@ -0,0 +1,305 @@ +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, 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), + ) + + private val ONE_WAY_WALL = mapOf( + Location.create(2904, 4573, 0) to setOf( // Diagonal entries + Location.create(2904, 4573, 0), + Location.create(2904, 4572, 0), + Location.create(2904, 4574, 0), + ), + Location.create(2906, 4586, 0) to setOf( // Diagonal entries + Location.create(2906, 4586, 0), + Location.create(2907, 4586, 0), + ), + Location.create(2902, 4575, 0) to setOf(Location.create(2903, 4575, 0)), + Location.create(2924, 4583, 0) to setOf(Location.create(2923, 4583, 0)), + ) + + fun initMaze(player: Player) { + setAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 300) + setVarp(player, MAZE_TIMER_VARP, (getAttribute(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, tableRoll[0].amount) + 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( + intArrayOf( + Scenery.WALL_3628, + Scenery.WALL_3629, + Scenery.WALL_3630, + Scenery.WALL_3631, + Scenery.WALL_3632, + ), + IntType.SCENERY, + "open" + ) { player, node -> + val scenery = node as core.game.node.scenery.Scenery + + if (ONE_WAY_WALL[scenery.location]?.contains(player.location) == true) { + sendDialogue(player, "I don't think that's the right way.") + } else { + DoorActionHandler.handleAutowalkDoor(player, scenery) + } + + return@on true + } + + on(Scenery.STRANGE_SHRINE_3634, IntType.SCENERY, "touch") { player, node -> + player.unhook(this) + lock(player, 12) + closeOverlay(player) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendGraphics(Graphics(86, 0, 3), player.location) + animate(player,862) + return@queueScript delayScript(player, 6) + } + 1 -> { + 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 { + return arrayOf(getRegionBorders(11591)) + } + + override fun getRestrictions(): Array { + 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) + } + } + +} diff --git a/Server/src/main/content/global/ame/events/maze/MazeNPC.kt b/Server/src/main/content/global/ame/events/maze/MazeNPC.kt new file mode 100644 index 000000000..a51f0b044 --- /dev/null +++ b/Server/src/main/content/global/ame/events/maze/MazeNPC.kt @@ -0,0 +1,32 @@ +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.node.entity.npc.NPC +import org.rs09.consts.NPCs + +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) + // Note: This event is NOT instanced: + // Sources: + // https://youtu.be/2gpzn9oNdy0 (2007) + // https://youtu.be/Tni1HURgnxg (2008) + // https://youtu.be/igdwDZOv9LU (2008) + // https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for." + // https://youtu.be/FMuKZm-Ikgs (2011) + // val region = DynamicRegion.create(11591) + kidnapPlayer(this, player, MazeInterface.STARTING_POINTS.random()) { player, _ -> + MazeInterface.initMaze(player) + removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN) + } + } + + override fun talkTo(npc: NPC) { + sendMessage(player, "He isn't interested in talking to you.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt b/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt new file mode 100644 index 000000000..f48fc76f4 --- /dev/null +++ b/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt @@ -0,0 +1,219 @@ +package content.global.ame.events.pillory + +import content.global.ame.RandomEvents +import content.global.ame.returnPlayer +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.interaction.InterfaceListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +/** + * Pillory Unlocking Interface PILLORY_189 + * + * https://www.youtube.com/watch?v=caWn7pE2mkE + * https://www.youtube.com/watch?v=TMVR5cZZwZ0 + * https://www.youtube.com/watch?v=Ym9LCDP-Q74 + * https://www.youtube.com/watch?v=_vn0QZTtI6U (Failure) + * https://www.youtube.com/watch?v=zmXDikQIua4 + * + * Child IDs + * 4 - Rotating Lock Model + * 5 6 7 - Swinging Keys Models + * 8 9 10 - Buttons for the Swinging Keys Models + * 11 12 13 14 15 16 - Padlocks at the Top + * 17 18 19 20 21 22 - Padlocks stars? Model 15272, Anim 4135 + * + * Model IDs + * Using the amazeballs ::listifmodels + * 9749, 9750, 9751, 9752 - Swinging Keys Models + * 9753, 9754, 9755, 9756 - Rotating Lock Models + * 9757 9758 locked unlock + */ +class PilloryInterface : InterfaceListener, InteractionListener, MapArea { + companion object { + const val PILLORY_LOCK_INTERFACE = 189 + const val PILLORY_ATTRIBUTE_EVENT_KEYS = "pillory:event-keys" + const val PILLORY_ATTRIBUTE_EVENT_LOCK = "pillory:event-lock" + const val PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct" + const val PILLORY_ATTRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct" + + val LOCATIONS = arrayOf( + // Varrock Cages + Location(3226, 3407, 0), + Location(3228, 3407, 0), + Location(3230, 3407, 0), + // Seers Village Cages + Location(2681, 3489, 0), + Location(2683, 3489, 0), + Location(2685, 3489, 0), + // Yannile Cages + Location(2604, 3105, 0), + Location(2606, 3105, 0), + Location(2608, 3105, 0), + ) + + fun initPillory(player: Player) { + setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) + setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.") + } + + fun randomPillory(player: Player) { + // Shuffle all 4 kinds of keys in, pick 3 for the keys, pick 1 from the 3 as the lock. + val keys = (0..3).toIntArray().let{ keys -> keys.shuffle(); return@let keys } + val lock = intArrayOf(keys[1], keys[2], keys[3]).random() // Last 3 as there are 4 keys. key[0] is fallback. + + setAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, keys) + setAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, lock) + + player.packetDispatch.sendModelOnInterface(9753 + lock, PILLORY_LOCK_INTERFACE, 4, 0) + player.packetDispatch.sendModelOnInterface(9749 + keys[1], PILLORY_LOCK_INTERFACE, 5, 0) + player.packetDispatch.sendModelOnInterface(9749 + keys[2], PILLORY_LOCK_INTERFACE, 6, 0) + player.packetDispatch.sendModelOnInterface(9749 + keys[3], PILLORY_LOCK_INTERFACE, 7, 0) + + val numberToGetCorrect = getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) + val correctCount = getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + for (i in 1.. 6) { + // Set if lock is red or green. + if (i <= correctCount) { + player.packetDispatch.sendModelOnInterface(9758, PILLORY_LOCK_INTERFACE, 10 + i, 0) + } else { + player.packetDispatch.sendModelOnInterface(9757, PILLORY_LOCK_INTERFACE, 10 + i, 0) + } + // Set if hide or show lock. + player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 10 + i, i > numberToGetCorrect) + } + } + + fun selectedKey(player: Player, buttonID: Int) { + val keys = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, intArrayOf(0, 0, 0)) + val lock = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, -1) + if (keys[buttonID] == lock) { + // CORRECT ANSWER + setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + 1) + if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, -1)) { + player.dialogueInterpreter.sendPlainMessage(true, "", "You've escaped!") + sendMessage(player, "You've escaped!") + removeAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT) + removeAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER) + closeInterface(player) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 1 -> { + val loot = RandomEvents.CERTER.loot!!.roll(player)[0] + addItemOrDrop(player, loot.id, loot.amount) + returnPlayer(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + closeInterface(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return + } + randomPillory(player) + player.dialogueInterpreter.sendPlainMessage( + true, + "", + "Correct!", + "" + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + " down, " + + (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)) + " to go!") + // Animation for the star, but it doesn't work. + player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1), false) + sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1)) + } else { + // WRONG ANSWER + player.dialogueInterpreter.close() + player.dialogueInterpreter.sendDialogues(NPCs.TRAMP_2794 , FacialExpression.OLD_ANGRY1, "Bah, that's not right.","Use the key that matches the hole", "in the spinning lock.") + if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) { + setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1) + } + setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + closeInterface(player) + } + } + } + + override fun defineInterfaceListeners() { + on(PILLORY_LOCK_INTERFACE){ player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + 8 -> selectedKey(player, 1) + 9 -> selectedKey(player, 2) + 10 -> selectedKey(player, 3) + } + return@on true + } + + onOpen(PILLORY_LOCK_INTERFACE){ player, component -> + return@onOpen true + } + } + + override fun defineListeners() { + on(Scenery.CAGE_6836, IntType.SCENERY, "unlock") { player, node -> + if (player.location in LOCATIONS) { // When you aren't inside. + randomPillory(player) + openInterface(player, PILLORY_LOCK_INTERFACE) + player.dialogueInterpreter.sendPlainMessage(true, "", "Pick the swinging key that matches the", "hole in the spinning lock.") + } else { + sendMessage(player, "You can't unlock the pillory, you'll let all the prisoners out!") + } + return@on true + } + } + + override fun defineAreaBorders(): Array { + 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 { + 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() + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt b/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt new file mode 100644 index 000000000..3917b035c --- /dev/null +++ b/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt @@ -0,0 +1,25 @@ +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.component.Component.setUnclosable +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs + +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) + kidnapPlayer(this, player, PilloryInterface.LOCATIONS.random()) { player, _ -> + PilloryInterface.initPillory(player) + setUnclosable(player, player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")) + } + } + + override fun talkTo(npc: NPC) { + sendMessage(player, "He isn't interested in talking to you.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterBorders.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterBorders.kt new file mode 100644 index 000000000..860d4d7dc --- /dev/null +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterBorders.kt @@ -0,0 +1,37 @@ +package content.global.ame.events.quizmaster + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import org.rs09.consts.NPCs + +class QuizMasterBorders : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(7754)) + } + + override fun getRestrictions(): Array { + 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) + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt new file mode 100644 index 000000000..4bb2ff79d --- /dev/null +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt @@ -0,0 +1,152 @@ +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.component.Component +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class QuizMasterDialogueFile : DialogueLabeller() { + 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 addConversation() { + assignToIds(NPCs.QUIZ_MASTER_2477) + afterClose { player -> + loadLabel(player, "question") + } + + npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "O D D O N E O U T", unclosable = true) + player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...", unclosable = true) + npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "${player?.username}!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!", unclosable = true) + goto("question") + + label("question") + manual(unclosable = true) { player, _ -> + setAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player)) + val comp = Component(QUIZMASTER_INTERFACE) + player.interfaceManager.openChatbox(comp) + return@manual comp + } + exec { player, _ -> + if (buttonID == getAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) { + // Correct Answer + setAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1) + if (getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) { + goto("winner") + } else { + goto("right") + } + } else { + goto("wrong") + } + } + + label("right") + npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!", unclosable = true) + goto("question") + + label("wrong") + npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!", unclosable = true) + goto("question") + + label("winner") + npc(FacialExpression.FRIENDLY,"CONGRATULATIONS!", "You are a WINNER!", "Please choose your PRIZE!", unclosable = true) + options( + DialogueOption("money", "1000 Coins", skipPlayer = true), + DialogueOption("item", "Random Item", skipPlayer = true) + ) + + label("money") + exec { player, _ -> + queueScript(player, 0, QueueStrength.SOFT) { _ -> + addItemOrDrop(player, Items.COINS_995, 1000) + return@queueScript stopExecuting(player) + } + } + goto("cleanup") + + label("item") + exec { player, _ -> + queueScript(player, 0, QueueStrength.SOFT) { _ -> + addItemOrDrop(player, tableRoll.roll()[0].id) + return@queueScript stopExecuting(player) + } + } + goto("cleanup") + + label("cleanup") + exec { player, _ -> + resetAnimator(player) + returnPlayer(player) + removeAttributes(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER) + } + goto("nowhere") + } +} diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt new file mode 100644 index 000000000..cccc4d0eb --- /dev/null +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt @@ -0,0 +1,39 @@ +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.node.entity.npc.NPC +import core.game.world.map.Location +import org.rs09.consts.NPCs + +/** + * 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!") + face(player) + kidnapPlayer(this, player, Location(1952, 4764, 1)) { player, _ -> + setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.") + sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case. + face(player, Location(1952, 4768, 1)) + animate(player,2378) + // Quiz dialogue gets opened automatically on zone entry. + } + } + + override fun talkTo(npc: NPC) { + openDialogue(player, QuizMasterDialogueFile(), this.asNpc()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt b/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt index b69ec7abe..dff28d7e9 100644 --- a/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt +++ b/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt @@ -4,17 +4,14 @@ import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import content.global.ame.RandomEventNPC import core.api.utils.WeightBasedTable -import java.lang.Integer.max - -val ids = 391..396 +val ids = (391..396).toList() class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){ override fun talkTo(npc: NPC) {} override fun init() { super.init() - val index = max(0, (player.properties.combatLevel / 20) - 1) - val id = ids.toList()[index] + val id = idForCombatLevel(ids, player) this.transform(id) this.attack(player) sendChat("Fishies be mine, leave dem fishies!") diff --git a/Server/src/main/content/global/ame/events/rockgolem/RockGolemBehavior.kt b/Server/src/main/content/global/ame/events/rockgolem/RockGolemBehavior.kt new file mode 100644 index 000000000..58852ec18 --- /dev/null +++ b/Server/src/main/content/global/ame/events/rockgolem/RockGolemBehavior.kt @@ -0,0 +1,86 @@ +package content.global.ame.events.rockgolem + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.InteractionType +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.update.flag.context.Animation +import org.rs09.consts.NPCs + +class RockGolemBehavior() : NPCBehavior(NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418) { + private val swingHandler = RockGolemSwingHandler() + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + return swingHandler + } + + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return super.getXpMultiplier(self, attacker) / 16.0 + } +} + +private class RockGolemSwingHandler : CombatSwingHandler(CombatStyle.RANGE) { + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + return type?.swingHandler?.canSwing(entity, victim) + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + if (entity == null || victim == null) return -1 + + val prayingRange = victim.hasProtectionPrayer(CombatStyle.RANGE) + + type = if (prayingRange) { + CombatStyle.MELEE + } else { + CombatStyle.RANGE + } + + if (type == CombatStyle.MELEE && entity.location.getDistance(victim.location) > 1) return -1 + + return type?.swingHandler?.swing(entity, victim, state) ?: 0 + } + + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + type?.swingHandler?.impact(entity, victim, state) + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + type?.swingHandler?.visualizeImpact(entity, victim, state) + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + when (type) { + CombatStyle.MELEE -> { + entity.animate(Animation(153)) + } + + CombatStyle.RANGE -> { + val speed = (100 + (Projectile.getLocation(entity).getDistance(victim!!.getLocation()) * 5)).toInt() + Projectile.create(entity, victim, 968, 48, 36, 80, speed, 5, entity.size() shl 5).send() + entity.animate(Animation(5347)) + } + + else -> {} + } + } + + override fun calculateAccuracy(entity: Entity?): Int { + return type?.swingHandler?.calculateAccuracy(entity) ?: 0 + } + + override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + return type?.swingHandler?.calculateHit(entity, victim, modifier) ?: 0 + } + + override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { + return type?.swingHandler?.calculateDefence(victim, attacker) ?: 0 + } + + override fun getSetMultiplier(e: Entity?, skillId: Int): Double { + return type?.swingHandler?.getSetMultiplier(e, skillId) ?: 0.0 + } +} diff --git a/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt b/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt index 82fda9bf4..eb3399657 100644 --- a/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt +++ b/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt @@ -4,17 +4,14 @@ import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import content.global.ame.RandomEventNPC import core.api.utils.WeightBasedTable -import kotlin.math.max - -val ids = 413..418 +val ids = (413..418).toList() class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){ override fun talkTo(npc: NPC) {} override fun init() { super.init() - val index = max(0,(player.properties.combatLevel / 20) - 1) - val id = ids.toList()[index] + val id = idForCombatLevel(ids, player) this.transform(id) this.attack(player) sendChat("Raarrrgghh! Flee human!") diff --git a/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt index 1c5a14956..99e0a0e68 100644 --- a/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt +++ b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt @@ -5,32 +5,49 @@ import core.tools.RandomFunction import org.rs09.consts.Items import org.rs09.consts.NPCs import content.global.ame.RandomEventNPC +import core.api.lock import core.api.utils.WeightBasedTable class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) { - val phrases = arrayOf("Hello, @name, can you hear me?","Sandwiches, @name!","Are you ignoring me, @name??","Yoohoo! Sandwiches, @name!","Hello, @name?", "Come get your sandwiches, @name!", "How could you ignore me like this, @name?!", "Do you even want your sandwiches, @name?") + lateinit var phrases: Array var assigned_item = 0 - val items = arrayOf(Items.BAGUETTE_6961,Items.TRIANGLE_SANDWICH_6962,Items.SQUARE_SANDWICH_6965,Items.ROLL_6963,Items.MEAT_PIE_2327,Items.KEBAB_1971,Items.CHOCOLATE_BAR_1973) + val items = arrayOf(Items.BAGUETTE_6961, Items.TRIANGLE_SANDWICH_6962, Items.SQUARE_SANDWICH_6965, Items.ROLL_6963, Items.MEAT_PIE_2327, Items.KEBAB_1971, Items.CHOCOLATE_BAR_1973) override fun tick() { - if(RandomFunction.random(1,15) == 5){ - sendChat(phrases.random().replace("@name",player.username.capitalize())) + sayLine(this, phrases, true, true) + if (ticksLeft == 2) { + lock(player, 2) } super.tick() } override fun init() { super.init() + phrases = arrayOf( + // https://www.youtube.com/watch?v=ek8r3ZS929E + // She always starts with "Sandwiches, ${player.username}!" but she ALSO picks that at random, hence duplicate it with hasOpeningPhrase = true + "Sandwiches, ${player.username}!", + "Sandwiches, ${player.username}!", + "Come on ${player.username}, I made these specially!!", + "All types of sandwiches, ${player.username}.", + "Did you hear me ${player.username}?", + "You think I made these just for fun?!!?", + "How could you ignore me like this, ${player.username}?!" //unknown if authentic but it was already here + ) assignItem() - sendChat(phrases.random().replace("@name",player.username.capitalize())) + } + + override fun onTimeUp() { + noteAndTeleport() + terminate() } fun assignItem(){ assigned_item = items.random() - player.setAttribute("sandwich-lady:item",assigned_item) + player.setAttribute("sandwich-lady:item", assigned_item) } override fun talkTo(npc: NPC) { - player.dialogueInterpreter.open(SandwichLadyDialogue(false),npc) + player.dialogueInterpreter.open(SandwichLadyDialogue(false), npc) } } diff --git a/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt b/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt index 4d991afdf..60a0f57ae 100644 --- a/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt +++ b/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt @@ -4,15 +4,13 @@ import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import content.global.ame.RandomEventNPC import core.api.utils.WeightBasedTable -import kotlin.math.* class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){ val ids = (425..430).toList() override fun talkTo(npc: NPC) {} override fun init() { super.init() - val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1)) - val id = ids[index] + val id = idForCombatLevel(ids, player) this.transform(id) this.attack(player) sendChat("Leave this place!") diff --git a/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt index cd80ad3d9..0491e01bc 100644 --- a/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt +++ b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt @@ -32,4 +32,8 @@ class StrangePlantBehavior() : NPCBehavior(NPCs.STRANGE_PLANT_408) { override fun onDeathStarted(self: NPC, killer: Entity) { AntiMacro.terminateEventNpc(killer.asPlayer()) } -} \ No newline at end of file + + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return super.getXpMultiplier(self, attacker) / 16.0 + } +} diff --git a/Server/src/main/content/global/ame/events/supriseexam/MordautDialogue.kt b/Server/src/main/content/global/ame/events/surpriseexam/MordautDialogue.kt similarity index 98% rename from Server/src/main/content/global/ame/events/supriseexam/MordautDialogue.kt rename to Server/src/main/content/global/ame/events/surpriseexam/MordautDialogue.kt index ca0e61c3f..d3bd04af0 100644 --- a/Server/src/main/content/global/ame/events/supriseexam/MordautDialogue.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/MordautDialogue.kt @@ -1,4 +1,4 @@ -package content.global.ame.events.supriseexam +package content.global.ame.events.surpriseexam import core.game.component.Component import core.game.dialogue.FacialExpression diff --git a/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManNPC.kt b/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManNPC.kt new file mode 100644 index 000000000..2a3896836 --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManNPC.kt @@ -0,0 +1,24 @@ +package content.global.ame.events.surpriseexam + +import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer +import core.api.* +import org.rs09.consts.NPCs +import core.api.utils.WeightBasedTable +import core.game.node.entity.npc.NPC +import core.game.world.map.Location + +class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) { + override fun init() { + super.init() + sendChat("Surprise exam, ${player.username}!") + face(player) + kidnapPlayer(this, player, Location(1886, 5025, 0)) { _, _ -> + /* nothing needed */ + } + } + + override fun talkTo(npc: NPC) { + sendMessage(player, "He isn't interested in talking to you.") + } +} diff --git a/Server/src/main/content/global/ame/events/supriseexam/SEDoorDialogue.kt b/Server/src/main/content/global/ame/events/surpriseexam/SEDoorDialogue.kt similarity index 90% rename from Server/src/main/content/global/ame/events/supriseexam/SEDoorDialogue.kt rename to Server/src/main/content/global/ame/events/surpriseexam/SEDoorDialogue.kt index 3fffea71b..221f4b4fe 100644 --- a/Server/src/main/content/global/ame/events/supriseexam/SEDoorDialogue.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/SEDoorDialogue.kt @@ -1,4 +1,4 @@ -package content.global.ame.events.supriseexam +package content.global.ame.events.surpriseexam import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE diff --git a/Server/src/main/content/global/ame/events/supriseexam/SEPatternInterface.kt b/Server/src/main/content/global/ame/events/surpriseexam/SEPatternInterface.kt similarity index 96% rename from Server/src/main/content/global/ame/events/supriseexam/SEPatternInterface.kt rename to Server/src/main/content/global/ame/events/surpriseexam/SEPatternInterface.kt index e445c5145..3ba12a8c0 100644 --- a/Server/src/main/content/global/ame/events/supriseexam/SEPatternInterface.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/SEPatternInterface.kt @@ -1,4 +1,4 @@ -package content.global.ame.events.supriseexam +package content.global.ame.events.surpriseexam import core.game.node.entity.npc.NPC import org.rs09.consts.Components diff --git a/Server/src/main/content/global/ame/events/supriseexam/SupriseExamListeners.kt b/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt similarity index 58% rename from Server/src/main/content/global/ame/events/supriseexam/SupriseExamListeners.kt rename to Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt index 6629982fa..ad19ffbda 100644 --- a/Server/src/main/content/global/ame/events/supriseexam/SupriseExamListeners.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt @@ -1,28 +1,29 @@ -package content.global.ame.events.supriseexam +package content.global.ame.events.surpriseexam import core.game.component.Component import core.game.node.entity.player.Player -import core.game.node.item.Item import core.game.world.map.Location import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType import content.global.handlers.iface.ExperienceInterface +import core.api.MapArea +import core.api.removeItem +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction -class SupriseExamListeners : InteractionListener { - val MORDAUT = NPCs.MR_MORDAUT_6117 - val BOOK_OF_KNOWLEDGE = Items.BOOK_OF_KNOWLEDGE_11640 +class SupriseExamListeners : InteractionListener, MapArea { override fun defineListeners() { - on(MORDAUT, IntType.NPC, "talk-to"){ player, node -> + on(NPCs.MR_MORDAUT_6117, IntType.NPC, "talk-to") { player, node -> player.faceLocation(Location.create(1886, 5024, 0)) - val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3 - player.dialogueInterpreter.open(MordautDialogue(examComplete),node.asNpc()) + val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT, 0) == 3 + player.dialogueInterpreter.open(MordautDialogue(examComplete), node.asNpc()) return@on true } - on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open"){ player, node -> + on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open") { player, node -> val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1) if(correctDoor == -1){ @@ -39,9 +40,9 @@ class SupriseExamListeners : InteractionListener { return@on true } - on(BOOK_OF_KNOWLEDGE, IntType.ITEM, "read"){ player, _ -> - player.setAttribute("caller"){skill: Int,p: Player -> - if(p.inventory.remove(Item(BOOK_OF_KNOWLEDGE))) { + on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ -> + player.setAttribute("caller") { skill: Int, p: Player -> + if (removeItem(p, Items.BOOK_OF_KNOWLEDGE_11640)) { val level = p.skills.getStaticLevel(skill) val experience = level * 15.0 p.skills.addExperience(skill, experience) @@ -54,8 +55,16 @@ class SupriseExamListeners : InteractionListener { } override fun defineDestinationOverrides() { - setDest(IntType.NPC,MORDAUT){ _, _ -> + setDest(IntType.NPC, NPCs.MR_MORDAUT_6117) { _, _ -> return@setDest Location.create(1886, 5025, 0) } } -} \ No newline at end of file + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders.forRegion(7502)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP) + } +} diff --git a/Server/src/main/content/global/ame/events/supriseexam/SurpriseExamUtils.kt b/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt similarity index 68% rename from Server/src/main/content/global/ame/events/supriseexam/SurpriseExamUtils.kt rename to Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt index d3905d358..e1cbdd5a8 100644 --- a/Server/src/main/content/global/ame/events/supriseexam/SurpriseExamUtils.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt @@ -1,21 +1,15 @@ -package content.global.ame.events.supriseexam +package content.global.ame.events.surpriseexam +import content.global.ame.returnPlayer import core.api.* import core.game.node.entity.impl.PulseType import core.game.node.entity.player.Player -import core.game.node.item.GroundItemManager -import core.game.node.item.Item import core.game.system.task.Pulse -import core.game.world.map.Location import org.rs09.consts.Components import org.rs09.consts.Items -import core.ServerConstants object SurpriseExamUtils { - - val SE_KEY_LOC = "supexam:loc" val SE_KEY_INDEX = "supexam:index" - val SE_LOGOUT_KEY = "suprise_exam" val SE_DOOR_KEY = "supexam:door" val INTER_PATTERN_CHILDS = intArrayOf(6,7,8) val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13) @@ -29,28 +23,12 @@ object SurpriseExamUtils { intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311) ) - fun teleport(player: Player){ - player.setAttribute(SE_KEY_LOC,player.location) - - registerLogoutListener(player, SE_LOGOUT_KEY){p -> - p.location = getAttribute(p, SE_KEY_LOC, ServerConstants.HOME_LOCATION) - } - - player.properties.teleportLocation = Location.create(1886, 5025, 0) - } - fun cleanup(player: Player){ - player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC,null) - clearLogoutListener(player, SE_LOGOUT_KEY) - player.removeAttribute(SE_KEY_LOC) - player.removeAttribute(SE_KEY_INDEX) - player.removeAttribute(SE_KEY_CORRECT) + returnPlayer(player) + removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT) player.pulseManager.run(object : Pulse(2){ override fun pulse(): Boolean { - val reward = Item(Items.BOOK_OF_KNOWLEDGE_11640) - if(!player.inventory.add(reward)){ - GroundItemManager.create(reward,player) - } + addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640) return true } }, PulseType.CUSTOM_1) diff --git a/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt b/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt index 2e4fb3436..3b0033972 100644 --- a/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt +++ b/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt @@ -4,17 +4,14 @@ import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import content.global.ame.RandomEventNPC import core.api.utils.WeightBasedTable -import kotlin.math.max - -val ids = 438..443 +val ids = (438..443).toList() class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){ override fun talkTo(npc: NPC) {} override fun init() { super.init() - val index = max(0,(player.properties.combatLevel / 20) - 1) - val id = ids.toList()[index] + val id = idForCombatLevel(ids, player) this.transform(id) this.attack(player) sendChat("Leave these woods and never return!") diff --git a/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt b/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt index 230d85ee8..6b43d54b4 100644 --- a/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt +++ b/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt @@ -4,15 +4,13 @@ import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import content.global.ame.RandomEventNPC import core.api.utils.WeightBasedTable -import kotlin.math.* class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){ val ids = (419..424).toList() override fun talkTo(npc: NPC) {} override fun init() { super.init() - val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1)) - val id = ids[index] + val id = idForCombatLevel(ids, player) this.transform(id) this.attack(player) sendChat("Brainsssss!") diff --git a/Server/src/main/content/global/bots/Adventurer.kt b/Server/src/main/content/global/bots/Adventurer.kt index a6c69e8e1..916503945 100644 --- a/Server/src/main/content/global/bots/Adventurer.kt +++ b/Server/src/main/content/global/bots/Adventurer.kt @@ -12,15 +12,16 @@ import core.game.world.map.Location import core.game.world.map.RegionManager import core.game.world.map.zone.ZoneBorders import core.game.world.update.flag.* -import core.tools.RandomFunction import org.json.simple.JSONArray import org.json.simple.JSONObject import core.ServerConstants +import core.api.log import core.game.bots.AIRepository import core.game.bots.CombatBotAssembler import core.game.bots.Script import core.game.interaction.IntType import core.game.interaction.InteractionListeners +import core.tools.Log import java.io.File import java.io.FileReader import java.time.LocalDateTime @@ -40,21 +41,27 @@ import kotlin.random.Random * @author Ceikry */ -//Adventure Bots v4.0.0 -Expansion Edition- +// Adventure Bots v1.1.0 : Expansion Edition (Previously v4.0.0) +// Super Grand Exchange Update class Adventurer(val style: CombatStyle): Script() { var city: Location = lumbridge - var ticks = 0 - var freshspawn = true - var sold = false - private val geloc: Location = if (Random.nextBoolean()){ - Location.create(3165, 3487, 0) - }else{ - Location.create(3164, 3492, 0) - } + var poiloc: Location = karamja + var geSocialLoc: Location = getRandomGESocialLocation() + var geClerkLoc: Location = getRandomGELocation() + var geClerksloc: Location = neGEClerk + var freshspawn: Boolean = true + var sold: Boolean = false + var poi: Boolean = false + + val chance: Int = if (cityLocationsGE.contains(city)) 3500 else 3000 + var ticks: Int = 0 var counter: Int = 0 - var random: Int = (5..30).random() + val waitTotal: Int = 8 + var returnToAdventure: Int = 0 + var geWait: Int = 0 + var geLongWait: Int = 0 val type = when(style){ CombatStyle.MELEE -> CombatBotAssembler.Type.MELEE @@ -74,23 +81,81 @@ class Adventurer(val style: CombatStyle): Script() { } override fun toString(): String { - return "${bot.name} is an Adventurer bot at ${bot.location}! State: $state - City: $city" + return "${bot.username} is an Adventurer bot " + + "at ${bot.location}! " + + "State: $state - " + + "City: $city - " + + "Ticks: $ticks - " + + "Freshspawn: $freshspawn - " + + "Sold: $sold - " + + "Counter: $counter" } var state = State.START - fun getRandomCity(): Location{ + private fun getRandomCity(): Location{ return cities.random() } - fun getRandomPoi(): Location{ + private fun getRandomPoi(): Location{ return pois.random() } + private fun getRandomGESocialLocation(): Location{ + return socialLocationsGE.random() + } + + private fun getRandomGELocation(): Location { + return cityLocationsGE.random() + } + + private fun randomNumberFromOne(maxInt: Int): Int { + return Random.nextInt(0, maxInt) + } + + private fun otherPlayersNearby(): Boolean { + val localPlayers = RegionManager.getLocalPlayers(bot) + val otherPlayers = localPlayers.filter { it.name != bot.name } + return otherPlayers.isNotEmpty() + } + + private fun checkNearBank() { + if(bankMap[city] == null){ + scriptAPI.teleport(getRandomCity().also { city = it }) + } else { + if(bankMap[city]?.insideBorder(bot) == true){ + state = State.FIND_BANK + } else { + bankMap[city]?.let { scriptAPI.walkTo(it.randomLoc) } + } + } + } + + private fun checkCounter(maxCounter: Int) { + if (counter++ >= maxCounter) { + state = State.TELEPORTING + } + } + + private fun teleportToRandomCity() { + city = getRandomCity() + when (city) { + neGEClerk -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-3,2,0,1,0)) } + swGEClerk -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-2,3,-1,0,0)) } + nwGEBanker -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-2,0,-3,2,0)) } + seGEBanker -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,0,2,-2,3,0)) } + else -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-1,1,-1,1,0)) } + } + } + + val resources = listOf( + "Rocks","Tree","Oak","Willow", + "Maple tree","Yew","Magic tree", + "Teak","Mahogany") + //TODO: Optimise and adjust how bots handle picking up ground items further. fun immerse() { - if (counter++ == 180) {state = State.TELEPORTING - } + if (counter++ >= Random.nextInt(150,300)) { state = State.TELEPORTING } val items = AIRepository.groundItems[bot] if (Random.nextBoolean()) { if (items.isNullOrEmpty()) { @@ -98,33 +163,13 @@ class Adventurer(val style: CombatStyle): Script() { state = State.LOOT_DELAY } if (bot.inventory.isFull) { - if(bankMap[city] == null){ - scriptAPI.teleport(getRandomCity().also { city = it }) - } else { - if(bankMap[city]?.insideBorder(bot) == true){ - state = State.FIND_BANK - } else { - scriptAPI.walkTo(bankMap[city]?.randomLoc ?: Location(0, 0, 0)) - } - } + checkNearBank() } } else { if (bot.inventory.isFull){ - if(bankMap[city] == null){ - scriptAPI.teleport(getRandomCity().also { city = it }) - } else { - if(bankMap[city]?.insideBorder(bot) == true){ - state = State.FIND_BANK - } else { - scriptAPI.walkTo(bankMap[city]?.randomLoc ?: Location(0, 0, 0)) - } - } + checkNearBank() } else { - val resources = listOf( - "Rocks","Tree","Oak","Willow", - "Maple tree","Yew","Magic tree", - "Teak","Mahogany") val resource = scriptAPI.getNearestNodeFromList(resources,true) if(resource != null){ if(resource.name.contains("ocks")) InteractionListeners.run(resource.id, @@ -137,18 +182,17 @@ class Adventurer(val style: CombatStyle): Script() { } fun refresh() { +// log(this::class.java, Log.WARN, "${bot.username} refreshed from $state at $city with $ticks and $counter counter.") scriptAPI.teleport(lumbridge) - freshspawn = true state = State.START } - var poi = false - var poiloc = karamja - //Adventure Bots Actual Code STARTS HERE!!! + // 100 ticks = 60 seconds override fun tick() { ticks++ - if (ticks++ >= 800) { + // Hard refresh + if (ticks >= 1000) { ticks = 0 refresh() return @@ -186,49 +230,42 @@ class Adventurer(val style: CombatStyle): Script() { } return } else { - state = State.EXPLORE + state = State.ADVENTURE } } State.START -> { if (freshspawn) { freshspawn = false - scriptAPI.randomWalkTo(lumbridge, 20) + scriptAPI.randomWalkTo(lumbridge, randomNumberFromOne(25)) } else { - city = getRandomCity() state = State.TELEPORTING } } State.TELEPORTING -> { + if (freshspawn){ freshspawn = false } + teleportToRandomCity() + poi = false + sold = false ticks = 0 counter = 0 - if (bot.location != city) { - poi = false - scriptAPI.teleport(city) - } else { - poi = false - state = State.EXPLORE - } + state = State.ADVENTURE + return } - State.EXPLORE -> { - if (counter++ == 350) { - state = State.TELEPORTING - } - - val chance = if (city == ge || city == ge2) 5000 else 2500 - if (RandomFunction.random(chance) <= 10) { - val nearbyPlayers = RegionManager.getLocalPlayers(bot) - if (nearbyPlayers.isNotEmpty()) { + State.ADVENTURE -> { + checkCounter(800) + if (randomNumberFromOne(chance) <= 10) { + if (otherPlayersNearby()) { ticks = 0 dialogue() } } - if (RandomFunction.random(1000) <= 150 && !poi) { - val roamDistance = if (city != ge && city != ge2) 225 else 7 - if ((city == ge || city == ge2) && RandomFunction.random(100) < 90) { + if (!poi && randomNumberFromOne(1000) <= 75) { + val roamDistance = if (!cityLocationsGE.contains(city)) 225 else randomNumberFromOne(5) + if (cityLocationsGE.contains(city) && randomNumberFromOne(100) < 90) { if (!bot.bank.isEmpty) { state = State.FIND_GE } @@ -238,33 +275,46 @@ class Adventurer(val style: CombatStyle): Script() { return } - if (RandomFunction.random(1000) <= 50 && poi){ + if (poi && randomNumberFromOne(1000) <= 100){ + immerse() + return + } + + if (poi && randomNumberFromOne(1000) <= 25){ + dialogue() + } + + if (poi && randomNumberFromOne(1000) <= 50){ val roamDistancePoi = when(poiloc){ - teakfarm, crawlinghands -> 5 - treegnome -> 50 - isafdar -> 40 - eaglespeek -> 40 - keldagrimout -> 30 - teak1 -> 30 - miningguild -> 5 - magics, coal -> 7 gemrocks, chaosnpc, chaosnpc2 -> 1 + magics, coalTrucks -> 7 + miningguild, teakfarm, crawlinghands -> 5 + varLumberYard -> 20 + keldagrimout, teak1 -> 30 + eaglespeek, isafdar -> 40 + treegnome -> 50 else -> 60 } scriptAPI.randomWalkTo(poiloc,roamDistancePoi) return } - if (RandomFunction.random(1000) <= 75) { - if (city != ge && city != ge2) { + if (randomNumberFromOne(1000) <= 75) { + if (!cityLocationsGE.contains(city)) { + ticks = 0 immerse() return - } else { - return + } else if (randomNumberFromOne(chance) <= 55 && otherPlayersNearby()) { + ticks = 0 + dialogue() } } - if (RandomFunction.random(20000) <= 60 && !poi) { + if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 50) { + state = State.IDLE_GE + } + + if (!poi && randomNumberFromOne(1000) <= 5) { poiloc = getRandomPoi() city = teak1 poi = true @@ -272,26 +322,24 @@ class Adventurer(val style: CombatStyle): Script() { return } - if ((city == ge || city == ge2) && RandomFunction.random(1000) >= 999) { - ticks = 0 - city = getRandomCity() + if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 100) { state = State.TELEPORTING - } - - if (city == ge || city == ge2) { return } - if (city == teak1 && counter++ >= 240){ - city = getRandomCity() - state = State.TELEPORTING + if (cityLocationsGE.contains(city)) { + return } - if (counter++ >= 240 && RandomFunction.random(100) >= 10) { + if (poi && randomNumberFromOne(1000) <= 20){ + state = State.TELEPORTING + return + } + + if (counter++ >= 750 && randomNumberFromOne(100) <= 50) { +// log(this::class.java, Log.FINE, "${bot.username} has moved on to a different city at $ticks ticks and $counter counter.") city = getRandomCity() - if (RandomFunction.random(100) % 2 == 0) { - counter = 0 - ticks = 0 + if (randomNumberFromOne(100) % 2 == 0) { state = State.TELEPORTING } else { if (citygroupA.contains(city)) { @@ -309,122 +357,122 @@ class Adventurer(val style: CombatStyle): Script() { return } - State.GE -> { - var ge = false - if (counter++ == 180) { - state = State.TELEPORTING - } - if (!sold) { - if (counter++ >= 15) { - sold = true - ge = true + State.IDLE_GE -> { + returnToAdventure = Random.nextInt(350, 750) + if (counter++ >= returnToAdventure){ + if (randomNumberFromOne(100) <= 25){ + ticks = 0 + counter = 0 + poiloc = getRandomPoi() + city = teak1 + poi = true + scriptAPI.teleport(poiloc) + state = State.ADVENTURE + return + } else { counter = 0 ticks = 0 - scriptAPI.sellAllOnGeAdv() + state = State.TELEPORTING + return + } + } + if (cityLocationsGE.contains(city)){ + if (randomNumberFromOne(1000) <= 5) { + ticks = 0 + geSocialLoc = scriptAPI.randomizeLocationInRanges(getRandomGESocialLocation(),-1,1,-1,1,0) + } else if (randomNumberFromOne(1000) <= 10) { + ticks = 0 + scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5)) + return + } + if (randomNumberFromOne(1000) <= 5 && otherPlayersNearby()){ + ticks = 0 + dialogue() + } else if (randomNumberFromOne(1000) <= 250){ return } - } else if (ge && sold) { - ge = false - city = getRandomCity() - state = State.TELEPORTING } return } State.FIND_GE -> { - if (counter++ == 180) { - state = State.TELEPORTING - } sold = false val ge: Scenery? = scriptAPI.getNearestNode("Desk", true) as Scenery? - if (ge == null || bot.bank.isEmpty) state = State.EXPLORE + if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE class GEPulse : MovementPulse(bot, ge, DestinationFlag.OBJECT) { override fun pulse(): Boolean { bot.faceLocation(ge?.location) - state = State.GE - return true + return true.also { state = State.GE } } } + if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE if (ge != null && !bot.bank.isEmpty) { - counter = 0 - scriptAPI.randomWalkTo(geloc, 3) - GameWorld.Pulser.submit(GEPulse()) + if (randomNumberFromOne(1000) <= 25 && otherPlayersNearby()){ + dialogue() + scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5)) + } else if (randomNumberFromOne(500) <= 50) { + GameWorld.Pulser.submit(GEPulse()) + } } + checkCounter(500) + return + } + + State.GE -> { + geClerksloc = clerkLocationsGe.random() + geWait = Random.nextInt(35, 100) + geLongWait = Random.nextInt(350, 750) + if (!sold) { + if (randomNumberFromOne(500) <= 25){ scriptAPI.randomWalkTo(geClerksloc, randomNumberFromOne(4))} + if (counter++ >= geWait) { + scriptAPI.randomWalkTo(geClerksloc, randomNumberFromOne(1)) + sold = true + counter = 0 + ticks = 0 + scriptAPI.sellAllOnGeAdv() + state = State.TELEPORTING + return + } + } else if (counter++ >= geLongWait) { + state = State.TELEPORTING + return + } + checkCounter(1000) return } State.FIND_BANK -> { - if (counter++ == 300) { - state = State.TELEPORTING - } val bank: Scenery? = scriptAPI.getNearestNode("Bank booth", true) as Scenery? - if (badedge.insideBorder(bot) || bot.location == badedge2 || bot.location == badedge3 || bot.location == badedge4) { - bot.randomWalk(5, 5) - } - if (bank == null) state = State.EXPLORE - class BankingPulse : MovementPulse(bot, bank, DestinationFlag.OBJECT) { - override fun pulse(): Boolean { - bot.faceLocation(bank?.location) - state = State.IDLE_BANKS - return true - } - } - if (bank != null) { - bot.pulseManager.run(BankingPulse()) + if (bank == null) { state = State.TELEPORTING } + if (bank != null && randomNumberFromOne(100) <= 5) { + scriptAPI.depositAtBank() + } else if (bank != null && randomNumberFromOne(100) <= 5){ + scriptAPI.randomWalkTo(bank.location,3) } + checkCounter(500) return } - State.IDLE_BANKS -> { - if (counter++ == 300) { - state = State.TELEPORTING - } - if (RandomFunction.random(1000) < 100) { - for (item in bot.inventory.toArray()) { - item ?: continue - when (item.id) { - 1359, 590, 1271, 995 -> continue - } - bot.bank.add(item) - bot.inventory.remove(item) - } - counter = 0 - state = State.EXPLORE - } - return - } State.FIND_CITY -> { - if (counter++ >= 600 || (city == ge || city == ge2)) { - counter = 0 + if (counter++ >= 500 || cityLocationsGE.contains(city)){ scriptAPI.teleport(getRandomCity().also { city = it }) - state = State.EXPLORE + state = State.ADVENTURE } if (bot.location.equals(city)) { - state = State.EXPLORE + state = State.ADVENTURE } else { - scriptAPI.randomWalkTo(city, 5) + scriptAPI.randomWalkTo(city, randomNumberFromOne(10)) } + checkCounter(600) return } - State.IDLE_CITY -> { - if (counter++ == 300) { - state = State.TELEPORTING - } - var random = (120..300).random() - if (counter++ == random && RandomFunction.random(1000) % 33 == 0) { - counter = 0 - state = State.EXPLORE - } - return - } } } fun dialogue() { - val localPlayer = RegionManager.getLocalPlayers(bot).random() val until = 1225 - dateCode val lineStd = dialogue.getLines("standard").rand() var lineAlt = "" @@ -455,20 +503,29 @@ class Adventurer(val style: CombatStyle): Script() { dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand() } - val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd } - .replace("@name", localPlayer.username) - .replace("@timer", until.toString()) - - scriptAPI.sendChat(chat) + var localPlayers = RegionManager.getLocalPlayers(bot) + if (localPlayers.isNotEmpty()) { + val localPlayer = localPlayers + .filter { it.name != bot.name } + .randomOrNull() + if (localPlayer != null) { + val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd } + .replace("@name", localPlayer.username) + .replace("@timer", until.toString()) + scriptAPI.sendChat(chat) + } else { + val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd } + scriptAPI.sendChat(chat) + } + } } enum class State{ START, - EXPLORE, + ADVENTURE, FIND_BANK, - IDLE_BANKS, FIND_CITY, - IDLE_CITY, + IDLE_GE, GE, TELEPORTING, LOOT, @@ -489,44 +546,94 @@ class Adventurer(val style: CombatStyle): Script() { } companion object { - val badedge = ZoneBorders(3094, 3494, 3096, 3497) - val badedge2 = Location.create(3094, 3492, 0) - val badedge3 = Location.create(3094, 3490, 0) - val badedge4 = Location.create(3094, 3494, 0) - + // Start Cities val yanille: Location = Location.create(2615, 3104, 0) val ardougne: Location = Location.create(2662, 3304, 0) val seers: Location = Location.create(2726, 3485, 0) val edgeville: Location = Location.create(3088, 3486, 0) - val ge: Location = Location.create(3168, 3487, 0) - val ge2: Location = Location.create(3161, 3493, 0) val catherby: Location = Location.create(2809, 3435, 0) val falador: Location = Location.create(2965, 3380, 0) val varrock: Location = Location.create(3213, 3428, 0) val draynor: Location = Location.create(3080, 3250, 0) val rimmington: Location = Location.create(2977, 3239, 0) val lumbridge: Location = Location.create(3222, 3219, 0) - val karamja = Location.create(2849, 3033, 0) - val alkharid = Location.create(3297, 3219, 0) - val feldiphills = Location.create(2535, 2919, 0) - val isafdar = Location.create(2241, 3217, 0) - val eaglespeek = Location.create(2333, 3579, 0) - val canafis = Location.create(3492, 3485, 0) - val treegnome = Location.create(2437, 3441, 0) - val teak1 = Location.create(2334, 3048, 0) - val teakfarm = Location.create(2825, 3085, 0) - val keldagrimout = Location.create(2724,3692,0) - val miningguild = Location.create(3046,9740,0) - val magics = Location.create(2285,3146,0) - val coal = Location.create(2581,3481,0) - val crawlinghands = Location.create(3422,3548,0) - val gemrocks = Location.create(2825,2997,0) - val chaosnpc = Location.create(2612,9484,0) - val chaosnpc2 = Location.create(2580,9501,0) - val taverly = Location.create(2909, 3436, 0) + val karamja: Location = Location.create(2849, 3033, 0) + val alkharid: Location = Location.create(3297, 3219, 0) + + // Start POI + val feldiphills: Location = Location.create(2535, 2919, 0) + val isafdar: Location = Location.create(2241, 3217, 0) + val eaglespeek: Location = Location.create(2333, 3579, 0) + val canafis: Location = Location.create(3492, 3485, 0) + val treegnome: Location = Location.create(2437, 3441, 0) + val teak1: Location = Location.create(2334, 3048, 0) + val teakfarm: Location = Location.create(2825, 3085, 0) + val keldagrimout: Location = Location.create(2724,3692, 0) + val miningguild: Location = Location.create(3046,9740, 0) + val magics: Location = Location.create(2285,3146, 0) + val coalTrucks: Location = Location.create(2581,3481, 0) + val crawlinghands: Location = Location.create(3422,3548, 0) + val gemrocks: Location = Location.create(2825,2997, 0) + val chaosnpc: Location = Location.create(2612,9484, 0) + val chaosnpc2: Location = Location.create(2586, 9501, 0) + val varLumberYard: Location = Location.create(3289, 3482, 0) + val taverly: Location = Location.create(2909, 3436, 0) + + val swGEClerk: Location = Location.create(3164, 3487, 0) + val neGEClerk: Location = Location.create(3165, 3492, 0) + val nwGEBanker: Location = Location.create(3162, 3490, 0) + val seGEBanker: Location = Location.create(3167, 3489, 0) + + val badedge = ZoneBorders(3094, 3494, 3096, 3497) + val badedge2: Location = Location.create(3094, 3492, 0) + val badedge3: Location = Location.create(3094, 3490, 0) + val badedge4: Location = Location.create(3094, 3494, 0) + var citygroupA = listOf(falador, varrock, draynor, rimmington, lumbridge, edgeville) var citygroupB = listOf(yanille, ardougne, seers, catherby) + val cities = listOf( + swGEClerk, neGEClerk, nwGEBanker, seGEBanker, + yanille, ardougne, seers, catherby, + falador, varrock, draynor, rimmington, + lumbridge, edgeville + ) + + val pois = listOf( + karamja, karamja, alkharid, + alkharid, feldiphills, feldiphills, + isafdar, eaglespeek, eaglespeek, + canafis, treegnome, treegnome, + teak1, teakfarm, keldagrimout, + miningguild, coalTrucks, crawlinghands, + magics, gemrocks, chaosnpc, chaosnpc, + chaosnpc2, taverly, + varLumberYard) + + val cityLocationsGE = listOf(swGEClerk, neGEClerk, nwGEBanker, seGEBanker) + + val socialLocationsGE = listOf( + Location.create(3158, 3483, 0), + Location.create(3165, 3480, 0), + Location.create(3172, 3483, 0), + Location.create(3174, 3489, 0), + Location.create(3171, 3497, 0), + Location.create(3164, 3499, 0), + Location.create(3157, 3497, 0), + Location.create(3155, 3489, 0), + Location.create(3167, 3492, 0), + Location.create(3162, 3492, 0), + Location.create(3162, 3487, 0), + Location.create(3167, 3487, 0) + ) + + val clerkLocationsGe = listOf( + Location.create(3165, 3492, 0), + Location.create(3164, 3492, 0), + Location.create(3164, 3487, 0), + Location.create(3165, 3487, 0) + ) + var bankMap = mapOf( falador to ZoneBorders(2950, 3374, 2943, 3368), varrock to ZoneBorders(3182, 3435, 3189, 3446), @@ -538,22 +645,10 @@ class Adventurer(val style: CombatStyle): Script() { catherby to ZoneBorders(2807, 3438, 2811, 3441) ) - val cities = listOf(yanille, ardougne, seers, catherby, falador, varrock, - draynor, rimmington, lumbridge, ge, ge2, edgeville) - - val pois = listOf( - karamja, karamja, alkharid, - alkharid, feldiphills, feldiphills, - isafdar, eaglespeek, eaglespeek, - canafis, treegnome, treegnome, - teak1, teakfarm, keldagrimout, - miningguild, coal, crawlinghands, - magics, gemrocks, chaosnpc, chaosnpc, - chaosnpc2, taverly) - private val whiteWolfMountainTop = Location(2850, 3496, 0) private val catherbyToTopOfWhiteWolf = arrayOf(Location(2856, 3442, 0), Location(2848, 3455, 0), Location(2848, 3471, 0), Location(2848, 3487, 0)) private val tavleryToTopOfWhiteWolf = arrayOf(Location(2872, 3425, 0), Location(2863, 3440, 0), Location(2863, 3459, 0), Location(2854, 3475, 0), Location(2859, 3488, 0)) + val common_stuck_locations = mapOf( // South of Tavlery dungeon ZoneBorders(2878, 3386, 2884, 3395) to { it: Adventurer -> diff --git a/Server/src/main/content/global/bots/CannonballSmelter.kt b/Server/src/main/content/global/bots/CannonballSmelter.kt index ca6406937..8ac77f7e1 100644 --- a/Server/src/main/content/global/bots/CannonballSmelter.kt +++ b/Server/src/main/content/global/bots/CannonballSmelter.kt @@ -7,8 +7,6 @@ import core.api.* import core.game.bots.* import core.game.ge.GrandExchange import core.game.interaction.DestinationFlag -import core.game.interaction.IntType -import core.game.interaction.InteractionListeners import core.game.interaction.MovementPulse import core.game.node.Node import core.game.node.entity.skill.Skills @@ -16,6 +14,7 @@ import core.game.node.item.Item import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import org.rs09.consts.Items +import content.data.Quests @PlayerCompatible @ScriptName("Falador Cannonball Smelter") @@ -273,6 +272,6 @@ class CannonballSmelter : Script() { skills.put(Skills.HITPOINTS,99) skills.put(Skills.DEFENCE,99) skills.put(Skills.SMITHING,35) - quests.add("Dwarf Cannon") + quests.add(Quests.DWARF_CANNON) } } diff --git a/Server/src/main/content/global/bots/DraynorFisher.kt b/Server/src/main/content/global/bots/DraynorFisher.kt index e8434f906..79a9bee8c 100644 --- a/Server/src/main/content/global/bots/DraynorFisher.kt +++ b/Server/src/main/content/global/bots/DraynorFisher.kt @@ -8,6 +8,8 @@ import core.game.world.map.zone.ZoneBorders import org.rs09.consts.Items import core.game.bots.SkillingBotAssembler import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners class DraynorFisher : Script() { val fishingZone = ZoneBorders(3085, 3223,3089, 3233) @@ -22,7 +24,11 @@ class DraynorFisher : Script() { scriptAPI.walkTo(fishingZone.randomLoc) else { val spot = scriptAPI.getNearestNode(316,false) - spot?.interaction?.handle(bot,spot.interaction[0]) ?: scriptAPI.walkTo(fishingZone.randomLoc) + if (spot != null) { + InteractionListeners.run(spot.id, IntType.NPC,"net",bot,spot) + } else { + scriptAPI.walkTo(fishingZone.randomLoc) + } if(bot.inventory.getMaximumAdd(Item(4151)) < 5) state = State.BANKING } diff --git a/Server/src/main/content/global/bots/FletchingBankstander.kt b/Server/src/main/content/global/bots/FletchingBankstander.kt index 201dd6f00..dd60a4e3c 100644 --- a/Server/src/main/content/global/bots/FletchingBankstander.kt +++ b/Server/src/main/content/global/bots/FletchingBankstander.kt @@ -1,12 +1,12 @@ package content.global.bots +import content.global.skill.fletching.log.LogCraftInfo +import content.global.skill.fletching.log.CraftItemWithLogScript +import core.game.bots.Script +import core.game.bots.SkillingBotAssembler import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching -import content.global.skill.fletching.FletchingPulse import core.game.node.item.Item import org.rs09.consts.Items -import core.game.bots.SkillingBotAssembler -import core.game.bots.Script class FletchingBankstander : Script(){ var state = State.FLETCHING @@ -17,7 +17,7 @@ class FletchingBankstander : Script(){ State.FLETCHING -> { bot.inventory.add(Item(Items.KNIFE_946)) bot.inventory.add(Item(Items.LOGS_1511,27)) - bot.pulseManager.run(FletchingPulse(bot, Item(Items.LOGS_1511),27, Fletching.FletchingItems.ARROW_SHAFT)) + CraftItemWithLogScript(bot, LogCraftInfo.ARROW_SHAFT, 27).invoke() State.BANKING } diff --git a/Server/src/main/content/global/bots/ManThiever.kt b/Server/src/main/content/global/bots/ManThiever.kt index 25a2638c2..75e0a6aac 100644 --- a/Server/src/main/content/global/bots/ManThiever.kt +++ b/Server/src/main/content/global/bots/ManThiever.kt @@ -5,6 +5,7 @@ import core.game.bots.SkillingBotAssembler import core.game.bots.Script import core.game.interaction.IntType import core.game.interaction.InteractionListeners +import core.game.node.entity.skill.Skills import java.util.* class ManThiever : Script() { @@ -22,6 +23,6 @@ class ManThiever : Script() { } init { - equipment.addAll(Arrays.asList(Item(1103), Item(1139), Item(1265))) + skills[Skills.THIEVING] = 20 } } \ No newline at end of file diff --git a/Server/src/main/content/global/bots/SeersFlax.kt b/Server/src/main/content/global/bots/SeersFlax.kt index d39942005..f8dcb56ab 100644 --- a/Server/src/main/content/global/bots/SeersFlax.kt +++ b/Server/src/main/content/global/bots/SeersFlax.kt @@ -1,31 +1,37 @@ package content.global.bots +import content.global.skill.crafting.spinning.SpinningItem +import content.global.skill.crafting.spinning.SpinningPulse +import core.game.bots.* import core.game.interaction.DestinationFlag import core.game.interaction.MovementPulse import core.game.node.entity.skill.Skills -import content.global.skill.crafting.spinning.SpinningItem -import content.global.skill.crafting.spinning.SpinningPulse import core.game.node.item.Item import core.game.world.map.Location import core.game.world.map.path.Pathfinder import org.rs09.consts.Items -import core.game.bots.SkillingBotAssembler -import core.game.bots.Script +@PlayerCompatible +@ScriptName("Seers' Village Flax Spinning") +@ScriptDescription("Pick flax and spin it into string. Start in the flax field near Seers' Village.") +@ScriptIdentifier("seers_flax") class SeersFlax : Script(){ + val waypoint1 = Location(2730, 3460, 0) // South of Seers' Village + val waypoint2 = Location(2737, 3441, 0) // Outside flax field var state = State.PICKING var stage = 0 var doorOpen = false override fun tick() { when(state){ - State.PICKING -> { - val flax = scriptAPI.getNearestNode(2646,true) - flax?.interaction?.handle(bot,flax.interaction[1]) - if(bot.inventory.getAmount(Items.FLAX_1779) > 25){ + if (bot.inventory.freeSlots() == 0) { state = State.TO_SPINNER + return } + + val flax = scriptAPI.getNearestNode("Flax", true) + scriptAPI.interact(bot, flax, "Pick") } State.TO_SPINNER -> { @@ -101,14 +107,13 @@ class SeersFlax : Script(){ } State.RETURN_TO_FLAX -> { - if(bot.location == Location.create(2756, 3478, 0)) - Pathfinder.find(bot,Location.create(2726, 3486, 0)).walk(bot) - if(stage == 0) - Pathfinder.find(bot,Location.create(2726, 3486, 0)).walk(bot).also { stage++ } - when(bot.location){ - Location.create(2726, 3486, 0) -> Pathfinder.find(bot,Location.create(2729, 3469, 0)).walk(bot) - Location.create(2729, 3469, 0) -> Pathfinder.find(bot,Location.create(2734, 3447, 0)).walk(bot) - Location.create(2734, 3447, 0) -> state = State.PICKING.also { stage = 0 } + val flax = scriptAPI.getNearestNode("Flax", true) + if (flax != null) { + state = State.PICKING + } else if (bot.location.withinMaxnormDistance(waypoint1, 5)) { + Pathfinder.find(bot, waypoint2).walk(bot) + } else { + Pathfinder.find(bot, waypoint1).walk(bot) } } @@ -124,7 +129,6 @@ class SeersFlax : Script(){ State.TELE_CAMELOT -> { scriptAPI.teleport(Location.create(2756, 3478, 0)) - stage = 0 state = State.RETURN_TO_FLAX } diff --git a/Server/src/main/content/global/bots/VarrockEssenceMiner.kt b/Server/src/main/content/global/bots/VarrockEssenceMiner.kt index 39ce02c55..38a9e6b5a 100644 --- a/Server/src/main/content/global/bots/VarrockEssenceMiner.kt +++ b/Server/src/main/content/global/bots/VarrockEssenceMiner.kt @@ -1,10 +1,13 @@ package content.global.bots +import content.data.Quests import core.game.bots.* import core.game.interaction.DestinationFlag import core.game.interaction.IntType import core.game.interaction.InteractionListeners import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import org.rs09.consts.Items @@ -24,6 +27,11 @@ class VarrockEssenceMiner : Script(){ when(state){ State.TO_ESSENCE -> { bot.interfaceManager.close() + if (bot.bank.getAmount(Items.PURE_ESSENCE_7936) > 500) { + state = State.TELE_GE + return + } + if(!auburyZone.insideBorder(bot)) scriptAPI.walkTo(auburyZone.randomLoc) else { @@ -99,7 +107,6 @@ class VarrockEssenceMiner : Script(){ scriptAPI.sellOnGE(Items.PURE_ESSENCE_7936) state = State.TO_ESSENCE } - } } @@ -118,4 +125,10 @@ class VarrockEssenceMiner : Script(){ script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) return script } + + init { + quests.add(Quests.RUNE_MYSTERIES) + inventory.add(Item(Items.ADAMANT_PICKAXE_1271)) + skills[Skills.MINING] = 31 + } } diff --git a/Server/src/main/content/global/dialogue/BankerDialogue.kt b/Server/src/main/content/global/dialogue/BankerDialogue.kt deleted file mode 100644 index e913ce4f0..000000000 --- a/Server/src/main/content/global/dialogue/BankerDialogue.kt +++ /dev/null @@ -1,181 +0,0 @@ -package content.global.dialogue - -import core.api.* -import core.game.node.entity.player.Player -import core.game.node.entity.player.link.IronmanMode -import core.plugin.Initializable -import core.game.dialogue.IfTopic -import core.game.dialogue.Topic -import content.global.handlers.npc.BankerNPC -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE - -@Initializable -class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - START_DIALOGUE -> when { - hasIronmanRestriction(player, IronmanMode.ULTIMATE) -> { - npcl( - core.game.dialogue.FacialExpression.ANNOYED, - "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + - "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}" - ).also { stage = END_DIALOGUE } - } - - else -> { - npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Good day, how may I help you?" - ).also { - if (hasAwaitingGrandExchangeCollections(player)) { - stage++ - } else { - stage += 2 - } - } - } - } - - 1 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Before we go any further, I should inform you that you " + - "have items ready for collection from the Grand Exchange." - ).also { stage++ } - - 2 -> showTopics( - Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to access my bank account, please.", 10), - IfTopic( - core.game.dialogue.FacialExpression.FRIENDLY, - "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", - 13, - hasActivatedSecondaryBankAccount(player) - ), - IfTopic( - core.game.dialogue.FacialExpression.FRIENDLY, - "I'd like to open a secondary bank account.", - 20, - !hasActivatedSecondaryBankAccount(player) - ), - Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to check my PIN settings.", 11), - Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to collect items.", 12), - Topic(core.game.dialogue.FacialExpression.ASKING, "What is this place?", 3), - ) - - 3 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "This is a branch of the Bank of Gielinor. We have branches in many towns." - ).also { stage++ } - - 4 -> playerl( - core.game.dialogue.FacialExpression.ASKING, - "And what do you do?" - ).also { stage++ } - - 5 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "We will look after your items and money for you. " + - "Leave your valuables with us if you want to keep them safe." - ).also { stage = END_DIALOGUE } - - 10 -> { - openBankAccount(player) - end() - } - - 11 -> { - openBankPinSettings(player) - end() - } - - 12 -> { - openGrandExchangeCollectionBox(player) - end() - } - - 13 -> { - toggleBankAccount(player) - - npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Your active bank account has been switched. " + - "You can now access your ${getBankAccountName(player)} account." - ).also { stage = 2 } - } - - 20 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Certainly. We offer secondary accounts to all our customers." - ).also { stage++ } - - 21 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable " + - "and account activation is permanent." - ).also { stage++ } - - 22 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "If your inventory does not contain enough money to cover the costs, we will complement " + - "the amount with the money inside your primary bank account." - ).also { stage++ } - - 23 -> npcl( - core.game.dialogue.FacialExpression.ASKING, - "Knowing all this, would you like to proceed with opening your secondary bank account?" - ).also { stage++ } - - 24 -> showTopics( - Topic(core.game.dialogue.FacialExpression.HAPPY, "Yes, I am still interested.", 25), - Topic(core.game.dialogue.FacialExpression.ANNOYED, "Actually, I've changed my mind.", 26) - ) - - 25 -> { - when (activateSecondaryBankAccount(player)) { - SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> { - npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Your bank account was already activated, there is no need to pay twice." - ).also { stage = END_DIALOGUE } - } - - SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> { - npcl( - core.game.dialogue.FacialExpression.ANNOYED, - "I must apologize, the transaction was not successful. Please check your " + - "primary bank account and your inventory - if there's money missing, please " + - "screenshot your chat box and contact the game developers." - ).also { stage = END_DIALOGUE } - } - - SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> { - npcl( - core.game.dialogue.FacialExpression.ANNOYED, - "It appears that you do not have the money necessary to cover the costs " + - "associated with opening a secondary bank account. I will be waiting here " + - "until you do." - ).also { stage = END_DIALOGUE } - } - - SecondaryBankAccountActivationResult.SUCCESS -> { - npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Your secondary bank account has been opened and can be accessed through any " + - "of the Bank of Gielinor's employees. Thank you for choosing our services." - ).also { stage = END_DIALOGUE } - } - } - } - - 26 -> npcl( - core.game.dialogue.FacialExpression.FRIENDLY, - "Very well. Should you decide a secondary bank account is needed, do not hesitate to " + - "contact any of the Bank of Gielinor's stationary employees. We will be happy to help." - ).also { stage = END_DIALOGUE } - } - - return true - } - - override fun getIds(): IntArray = BankerNPC.NPC_IDS -} diff --git a/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt b/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt index 3fa655c5d..6c192972c 100644 --- a/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt +++ b/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt @@ -3,160 +3,227 @@ package content.global.dialogue import content.global.skill.farming.FarmerPayOptionDialogue import content.global.skill.farming.Farmers import content.global.skill.farming.FarmingPatch -import core.game.node.entity.npc.NPC +import content.global.skill.farming.PatchType +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE @Initializable class GardenerDialoguePlugin(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { - override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { - return GardenerDialoguePlugin(player) - } - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - options("Would you look after my crops for me?","Can you sell me something?") - return true - } - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - 0 -> when(buttonId){ - 1 -> player("Would you look after my crops for me?").also { stage = 10 } - 2 -> player("Can you sell me something?").also { stage = 30 } + val patches = Farmers.forId(npc.id)!!.patches + when (stage) { + // TODO: Can fruit trees be chopped down by the gardener too? + START_DIALOGUE -> { + val patch = patches[0].getPatchFor(player) + showTopics( + IfTopic( + FacialExpression.ASKING, + "Would you chop my tree down for me?", + 1000, + patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown() + ), + IfTopic( + FacialExpression.ASKING, + "Would you look after my crops for me?", + 10, + !(patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()) + ), + Topic(FacialExpression.ASKING, "Can you give me any farming advice?", 2000), + Topic(FacialExpression.ASKING, "Can you sell me something?", 30), + Topic(FacialExpression.NEUTRAL, "That's all, thanks.", END_DIALOGUE) + ) } - 10 -> npc("I might. Which one were you thinking of?").also { stage++ } - 11 -> when(npc.id){ - Farmers.ELSTAN.id, Farmers.LYRA.id -> options("The north-western allotment.","The south-eastern allotment.").also { stage = 15 } - Farmers.DANTAERA.id, Farmers.KRAGEN.id -> options("The north allotment.","The south allotment.").also { stage = 15 } - else -> player("Uh, that one.").also { stage++ } + 10 -> { + if (patches.size > 1) { + npc("I might. Which one were you thinking of?").also { stage = 20 } + } else { + openPayGardenerDialogue(player, patches[0]) + } } - 12 -> npc("Oh, right. My bad.").also { stage++ } - 13 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[0]) - - 15 -> when(buttonId){ - 1 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[0]) - 2 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[1]) + 20 -> when (npc.id) { + Farmers.ELSTAN.id, Farmers.LYRA.id -> showTopics( + Topic(FacialExpression.NEUTRAL, "The north-western allotment.", 21), + Topic(FacialExpression.NEUTRAL, "The south-eastern allotment.", 22) + ) + Farmers.DANTAERA.id, Farmers.KRAGEN.id -> showTopics( + Topic(FacialExpression.NEUTRAL, "The northern allotment.", 21), + Topic(FacialExpression.NEUTRAL, "The southern allotment.", 22) + ) } + 21 -> openPayGardenerDialogue(player, patches[0]) + 22 -> openPayGardenerDialogue(player, patches[1]) - 30 -> npc("That depends on whether I have it to sell.","What is it that you're looking for?").also { stage++ } - 31 -> options("Some plant cure.","A bucket of compost.","A rake.","(See more items)").also { stage = 32 } - 32 -> when(buttonId){ - 1 -> player("Some plant cure.").also { stage = 100 } - 2 -> player("A bucket of compost.").also { stage = 200 } - 3 -> player("A rake.").also { stage = 300 } - 4 -> options("A watering can.","A gardening trowel.","A seed dibber.","(See previous items)").also { stage++ } - } - 33 -> when(buttonId){ - 1 -> player("A watering can.").also { stage = 400 } - 2 -> player("A gardening trowel.").also { stage = 500 } - 3 -> player("A seed dibber.").also { stage = 600 } - 4 -> options("Some plant cure.","A bucket of compost.","A rake.","(See more items)").also { stage = 32 } - } + 30 -> npc(FacialExpression.NEUTRAL, "That depends on whether I have it to sell. What is it", "that you're looking for?").also { stage++ } + 31 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Some plant cure.", 100), + Topic(FacialExpression.NEUTRAL, "A bucket of compost.", 200), + Topic(FacialExpression.NEUTRAL, "A rake.", 300), + Topic("(See more items)", 32, true) + ) + 32 -> showTopics( + Topic(FacialExpression.NEUTRAL, "A watering can.", 400), + Topic(FacialExpression.NEUTRAL, "A gardening trowel.", 500), + Topic(FacialExpression.NEUTRAL, "A seed dibber.", 600), + Topic("(See previous items)", 31, true), + Topic(FacialExpression.NEUTRAL, "Forget it.", 40, true) + ) - 100 -> npc("Plant cure, eh? I might have some put aside for myself.","Tell you what, I'll sell you some plant cure","for 25 gp if you like.").also { stage++ } - 101 -> options("Yes, that sounds like a fair price.","No thanks, I can get that much cheaper.").also { stage++ } - 102 -> when(buttonId){ + 40 -> player("Forget it, you don't have anything I need.").also { stage = END_DIALOGUE } + + 100 -> npc("Plant cure, eh? I might have some put aside for myself.", "Tell you what. I'll sell you some plant cure for 25 gp if", "you like.").also { stage++ } + 101 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 102 -> when (buttonId) { 1 -> { - player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } - if(player.inventory.remove(Item(995,25))){ - player.inventory.add(Item(Items.PLANT_CURE_6036)) + player(FacialExpression.HAPPY, "Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 25))) { + addItemOrDrop(player, Items.PLANT_CURE_6036) } else { - player.sendMessage("You need 25 gp to pay for that.") + sendMessage(player, "You need 25 gp to pay for that.") } } - 2 -> end() + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } } - 200 -> npc("A bucket of compost, eh? I might have one spare...","tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ } - 201 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ } - 202 -> when(buttonId){ + 200 -> npc("A bucket of compost, eh? I might have one spare...", "tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ } + 201 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 202 -> when (buttonId) { 1 -> { player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } - if(player.inventory.remove(Item(995,35))){ - player.inventory.add(Item(Items.COMPOST_6032)) + if (removeItem(player, Item(Items.COINS_995, 35))) { + addItemOrDrop(player, Items.COMPOST_6032) } else { - player.sendMessage("You need 35 gp to pay for that.") + sendMessage(player, "You need 35 gp to pay for that.") } } - 2 -> end() + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } } - 300 -> npc("A rake, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } - 301 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ } - 302 -> when(buttonId){ + 300 -> npc("A rake, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } + 301 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 302 -> when (buttonId) { 1 -> { player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } - if(player.inventory.remove(Item(995,15))){ - player.inventory.add(Item(Items.RAKE_5341)) + if (removeItem(player, Item(Items.COINS_995, 15))) { + addItemOrDrop(player, Items.RAKE_5341) } else { - player.sendMessage("You need 15 gp to pay for that.") + sendMessage(player, "You need 15 gp to pay for that.") } } - 2 -> end() + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } } - 400 -> npc("A watering can, eh? I might have one spare...","tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ } - 401 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ } + 400 -> npc("A watering can, eh? I might have one spare...", "tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ } + 401 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } 402 -> when(buttonId){ 1 -> { player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } - if(player.inventory.remove(Item(995,25))){ - player.inventory.add(Item(Items.WATERING_CAN8_5340)) + if (removeItem(player, Item(Items.COINS_995, 25))) { + addItemOrDrop(player, Items.WATERING_CAN8_5340) } else { - player.sendMessage("You need 25 gp to pay for that.") + sendMessage(player, "You need 25 gp to pay for that.") } } - 2 -> end() + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } } - 500 -> npc("A gardening trowel, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } - 501 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ } - 502 -> when(buttonId){ + 500 -> npc("A gardening trowel, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } + 501 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 502 -> when (buttonId) { 1 -> { player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } - if(player.inventory.remove(Item(995,15))){ - player.inventory.add(Item(Items.GARDENING_TROWEL_5325)) + if (removeItem(player, Item(Items.COINS_995, 15))) { + addItemOrDrop(player, Items.GARDENING_TROWEL_5325) } else { - player.sendMessage("You need 15 gp to pay for that.") + sendMessage(player, "You need 15 gp to pay for that.") } } - 2 -> end() + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } } - 600 -> npc("A seed dibber, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } - 601 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ } - 602 -> when(buttonId){ + 600 -> npc("A seed dibber, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } + 601 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 602 -> when (buttonId) { 1 -> { player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } - if(player.inventory.remove(Item(995,15))){ - player.inventory.add(Item(Items.SEED_DIBBER_5343)) + if (removeItem(player, Item(Items.COINS_995, 15))) { + addItemOrDrop(player, Items.SEED_DIBBER_5343) } else { - player.sendMessage("You need 15 gp to pay for that.") + sendMessage(player, "You need 15 gp to pay for that.") } } - 2 -> end() + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + // Note: This dialogue changes slightly in April 2009, and significantly in December 2009 + 1000 -> npc(FacialExpression.THINKING, "Why? You look like you could chop it down yourself!").also { stage++ } + 1001 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, you're right - I'll do it myself.", END_DIALOGUE), + Topic(FacialExpression.NEUTRAL, "I can't be bothered - I'd rather pay you to do it.", 1020) + ) + + 1020 -> npc(FacialExpression.NEUTRAL, "Well, it's a lot of hard work - if you pay me 200 GP", "I'll chop it down for you.").also { stage++ } + 1021 -> { + if (inInventory(player, Items.COINS_995, 200)) { + showTopics( + Topic(FacialExpression.NEUTRAL, "Here's 200GP - chop my tree down please.", 1022), + Topic(FacialExpression.NEUTRAL, "I don't want to pay that much, sorry.", END_DIALOGUE) + ) + } else { + player("I don't have that much money on me.").also { stage = END_DIALOGUE } // not authentic + } + } + 1022 -> { + end() + if (removeItem(player, Item(Items.COINS_995, 200))) { + patches[0].getPatchFor(player).clear() + } + } + + 2000 -> { + val advice = arrayOf( + "There are four main Farming areas - Elstan looks after an area south of Falador, Dantaera has one to the north of Catherby, Kragen has one near Ardougne, and Lyra looks after a place in north Morytania.", + "If you want to grow fruit trees you could try a few places: Catherby and Brimhaven have a couple of fruit tree patches, and I hear that the gnomes are big on that sort of thing.", + "Bittercap mushrooms can only be grown in a special patch in Morytania, near the Mort Myre swamp. There the ground is especially dank and suited to growing poisonous fungi.", + "There is a special patch for growing Belladonna - I believe it's somewhere near Draynor Manor, where the ground is a tad 'unblessed'.", + + "Don't just throw away your weeds after you've raked a patch - put them in a compost bin and make some compost.", + "Applying compost to a patch will not only reduce the chance that your crops will get diseased, but you will also grow more crops to harvest.", + "Supercompost is far better than normal compost, but more expensive to make. You need to rot the right type of item; show me an item, and I'll tell you if it's super-compostable or not.", + + "Tree seeds must be grown in a plantpot of soil into a sapling, and then transferred to a tree patch to continue growing to adulthood.", + "You don't have to buy all your plantpots you know, you can make them yourself on a pottery wheel. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.", + "You can fill plantpots with soil from Farming patches, if you have a gardening trowel.", + + "Vegetables, hops and flowers are far more likely to grow healthily if you water them periodically.", + "The only way to cure a bush or tree of disease is to prune away the diseased leaves with a pair of secateurs. For all other crops I would just apply some plant-cure.", + "If you need to be rid of your fruit trees for any reason, all you have to do is chop them down and then dig up the stump.", + + "You can put up to ten potatoes, cabbages or onions in vegetable sacks, although you can't have a mix in the same sack.", + "You can put up to five tomatoes, strawberries, apples, bananas or oranges into a fruit basket, although you can't have a mix in the same basket.", + "If you want to make your own sacks and baskets you'll need to use the loom that's near the Farming shop in Falador. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.", + "You can buy all the farming tools from farming shops, which can be found close to the allotments.", + + "Hops are good for brewing ales. I believe there's a brewery up in Keldagrim somewhere, and I've heard rumours that a place called Phasmatys used to be good for that type of thing. 'Fore they all died, of course.", + ) + npcl(FacialExpression.NEUTRAL, advice.random()).also { stage = START_DIALOGUE } } } return true } - fun checkPatch(player: Player,fPatch: FarmingPatch){ - if(fPatch.getPatchFor(player).isWeedy()){ - npc("You don't have anything planted in that patch.","Plant something and I might agree to look after it for you.").also { stage = END_DIALOGUE } - } else if(fPatch.getPatchFor(player).isGrown()){ - npc("That patch is already fully grown!","I don't know what you want me to do with it!").also { stage = END_DIALOGUE } - } else if(fPatch.getPatchFor(player).protectionPaid) { - npc("Are you alright? You've already", "paid me for that.").also { stage = END_DIALOGUE } - } else { - end() - player.dialogueInterpreter.open(FarmerPayOptionDialogue(fPatch.getPatchFor(player)),npc) - } + fun openPayGardenerDialogue(player: Player, fPatch: FarmingPatch) { + end() + openDialogue(player, FarmerPayOptionDialogue(fPatch.getPatchFor(player)), npc) } override fun getIds(): IntArray { diff --git a/Server/src/main/content/global/dialogue/ManDialoguePlugin.java b/Server/src/main/content/global/dialogue/ManDialoguePlugin.java index 36785504e..aeff88be1 100644 --- a/Server/src/main/content/global/dialogue/ManDialoguePlugin.java +++ b/Server/src/main/content/global/dialogue/ManDialoguePlugin.java @@ -22,7 +22,7 @@ public class ManDialoguePlugin extends DialoguePlugin { /** * The NPC ids that use this dialogue plugin. */ - private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 351, 352, 353, 354, 359, 360, 361, 362, 363, 726, 727, 728, 729, 730, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,}; + private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,}; public ManDialoguePlugin() { } diff --git a/Server/src/main/content/global/dialogue/TownCrierDialogue.java b/Server/src/main/content/global/dialogue/TownCrierDialogue.java index e740fbfa2..f330bda86 100644 --- a/Server/src/main/content/global/dialogue/TownCrierDialogue.java +++ b/Server/src/main/content/global/dialogue/TownCrierDialogue.java @@ -2,6 +2,7 @@ package content.global.dialogue; import content.global.handlers.item.book.GeneralRuleBook; import core.game.dialogue.DialoguePlugin; +import core.game.diary.DiaryLevel; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.diary.DiaryType; @@ -10,6 +11,10 @@ import core.game.world.GameWorld; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.tools.RandomFunction; +import org.rs09.consts.NPCs; + +import static content.region.misthalin.lumbridge.diary.LumbridgeAchivementDiary.Companion.BeginnerTasks.DRAYNOR_TALK_TO_TOWNCRIER_ABOUT_RULES; +import static core.api.ContentAPIKt.finishTask; /** * Represents the town crier dialogue plugin. @@ -127,9 +132,8 @@ public final class TownCrierDialogue extends DialoguePlugin { return true; } }); - // Find out about the Rules of Conduct from the Draynor

Town Crier - if (npc.getId() == 6136) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 10); + if (npc.getId() == NPCs.TOWN_CRIER_6136) { + finishTask(player, DiaryType.LUMBRIDGE, DiaryLevel.BEGINNER, DRAYNOR_TALK_TO_TOWNCRIER_ABOUT_RULES); } stage = 71; break; diff --git a/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java b/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java index a010c7bb5..9213cf0f6 100644 --- a/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java +++ b/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java @@ -30,6 +30,17 @@ public final class AutocastSelectPlugin extends ComponentPlugin { if (!player.getAttribute("autocast_select", false)) { return true; } + if (player.timers.getTimer("spellbook:swap") != null) { + player.getPacketDispatch().sendMessage("You cannot autocast while using Spellbook Swap."); + player.removeAttribute("autocast_select"); + player.removeAttribute("autocast_component"); + final WeaponInterface w = player.getExtension(WeaponInterface.class); + if (w != null) { + w.setAttackStyle(3); + player.getInterfaceManager().openTab(w); + } + return true; + } player.removeAttribute("autocast_select"); final WeaponInterface w = player.getExtension(WeaponInterface.class); if (w != null) { diff --git a/Server/src/main/content/global/handlers/iface/BookInterface.kt b/Server/src/main/content/global/handlers/iface/BookInterface.kt index 070b83ebd..508b8b16d 100644 --- a/Server/src/main/content/global/handlers/iface/BookInterface.kt +++ b/Server/src/main/content/global/handlers/iface/BookInterface.kt @@ -1,5 +1,6 @@ package content.global.handlers.iface +import content.global.handlers.iface.BookInterface.Companion.FANCY_BOOK_2_27 import core.api.closeInterface import core.api.getAttribute import core.api.openInterface @@ -158,9 +159,22 @@ class BookInterface : InterfaceListener { if (pageSet == getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0)) { player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false) player.packetDispatch.sendModelOnInterface(modelId, componentId, drawLineId, 0) - player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw) - } else { - player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, true) + player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw) + } + } + + /** Sets item on lineId of pageSet (0 index). Call this in the display function after pageSetup. */ + fun setItemOnPage(player: Player, pageSet: Int, itemId: Int, componentId: Int, enableLineId: Int, drawLineId: Int, zoom: Int, pitch: Int, yaw: Int) { + if (pageSet == getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0)) { + player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false) + player.packetDispatch.sendItemOnInterface(itemId, 1, componentId, drawLineId) + } + } + + /** Clears models(pictures) on lineId of pageSet (0 index). Call this in the display function after pageSetup. */ + fun clearModelsOnPage(player: Player, componentId: Int) { + BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS.forEach { drawId -> + player.packetDispatch.sendInterfaceConfig(componentId, drawId, true); } } diff --git a/Server/src/main/content/global/handlers/iface/ClanInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/ClanInterfacePlugin.java deleted file mode 100644 index 1ad3857e8..000000000 --- a/Server/src/main/content/global/handlers/iface/ClanInterfacePlugin.java +++ /dev/null @@ -1,155 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.RunScript; -import core.game.system.communication.ClanRank; -import core.game.system.communication.ClanRepository; -import core.net.amsc.MSPacketRepository; -import core.net.amsc.WorldCommunicator; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.tools.StringUtils; -import kotlin.Unit; - -import static core.api.ContentAPIKt.sendInputDialogue; -import static core.api.ContentAPIKt.setInterfaceText; - -/** - * Represents the plugin used to handle the clan interfaces. - * @author Vexia - */ -@Initializable -public final class ClanInterfacePlugin extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(590, this); - ComponentDefinition.put(589, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - switch (component.getId()) { - case 589: - switch (button) { - case 9: - if (player.getInterfaceManager().getComponent(590) != null) { - player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'"); - return true; - } - ClanRepository.openSettings(player); - return true; - case 14: - player.getDetails().getCommunication().toggleLootshare(player); - return true; - } - break; - case 590: - final ClanRepository clan = ClanRepository.get(player.getName(), true); - switch (button) { - case 23: - if (opcode == 155) { - clan.setJoinRequirement(ClanRank.NONE); - } else { - clan.setJoinRequirement(getRank(opcode)); - } - player.getDetails().getCommunication().setJoinRequirement(clan.getJoinRequirement()); - MSPacketRepository.setClanSetting(player, 0, clan.getJoinRequirement()); - player.getPacketDispatch().sendString(clan.getJoinRequirement().getInfo(), 590, 23); - break; - case 24: - clan.setMessageRequirement(getRank(opcode)); - player.getDetails().getCommunication().setMessageRequirement(clan.getMessageRequirement()); - MSPacketRepository.setClanSetting(player, 1, clan.getMessageRequirement()); - player.getPacketDispatch().sendString(clan.getMessageRequirement().getInfo(), 590, 24); - break; - case 25: - clan.setKickRequirement(getRank(opcode)); - player.getDetails().getCommunication().setKickRequirement(clan.getKickRequirement()); - MSPacketRepository.setClanSetting(player, 2, clan.getKickRequirement()); - player.getPacketDispatch().sendString(clan.getKickRequirement().getInfo(), 590, 25); - clan.update(); - break; - case 26: - if (opcode == 230) { - clan.setLootRequirement(ClanRank.ADMINISTRATOR); - } else { - clan.setLootRequirement(getRank(opcode)); - } - player.getDetails().getCommunication().setLootRequirement(clan.getLootRequirement()); - MSPacketRepository.setClanSetting(player, 3, clan.getLootRequirement()); - player.getPacketDispatch().sendString(clan.getLootRequirement().getInfo(), 590, 26); - break; - case 22: - switch (opcode) { - case 196: - clan.setName("Chat disabled"); - player.getCommunication().setClanName(""); - player.getPacketDispatch().sendString(clan.getName(), 590, 22); - if (WorldCommunicator.isEnabled()) { - MSPacketRepository.sendClanRename(player, ""); - break; - } - clan.clean(true); - break; - default: - sendInputDialogue(player, false, "Enter clan prefix:", (value) -> { - String name = StringUtils.formatDisplayName((String) value); - setInterfaceText(player, name, 590, 22); - if(WorldCommunicator.isEnabled()){ - MSPacketRepository.sendClanRename(player, name); - clan.setName(name); - return Unit.INSTANCE; - } - if (clan.getName().equals("Chat disabled")) { - player.getPacketDispatch().sendMessage("Your clan channel has now been enabled!"); - player.getPacketDispatch().sendMessage("Join your channel by clicking 'Join Chat' and typing: " + player.getUsername()); - } - clan.setName(name); - player.getCommunication().setClanName(name); - clan.update(); - return Unit.INSTANCE; - }); - break; - } - break; - } - break; - } - return true; - } - - /** - * Gets the value to set. - * @param opcode the opcode. - * @return the value. - */ - public static ClanRank getRank(int opcode) { - switch (opcode) { - case 155: - return ClanRank.NONE; - case 196: - return ClanRank.FRIEND; - case 124: - return ClanRank.RECRUIT; - case 199: - return ClanRank.CORPORAL; - case 234: - return ClanRank.SERGEANT; - case 168: - return ClanRank.LIEUTENANT; - case 166: - return ClanRank.CAPTAIN; - case 64: - return ClanRank.GENERAL; - case 53: - return ClanRank.OWNER; - } - return ClanRank.NONE; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/CrystalKeyChestPlugin.java b/Server/src/main/content/global/handlers/iface/CrystalKeyChestPlugin.java deleted file mode 100644 index 852eb4997..000000000 --- a/Server/src/main/content/global/handlers/iface/CrystalKeyChestPlugin.java +++ /dev/null @@ -1,50 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -@Initializable -public class CrystalKeyChestPlugin extends ComponentPlugin { - - private final Integer CHEST_INTERFACE = 501; - - private Player player; - - public CrystalKeyChestPlugin() { - /* - * Empty - */ - } - - public CrystalKeyChestPlugin(Player player) { - this.player = player; - } - - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(CHEST_INTERFACE, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - return false; - } - - public void constructInterface(Player player) { - Integer[] hiddenChildren = new Integer[] { 3, 4, 5, 6, 7}; - Component component = new Component(CHEST_INTERFACE); - for (int i = 3; i < hiddenChildren.length; i++) { - player.getPacketDispatch().sendInterfaceConfig(CHEST_INTERFACE, i, true); - } - player.getPacketDispatch().sendItemOnInterface(989, 1, CHEST_INTERFACE, hiddenChildren[2]); - player.getInterfaceManager().open(component); - this.player = player; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/DeathInterface.kt b/Server/src/main/content/global/handlers/iface/DeathInterface.kt new file mode 100644 index 000000000..3b0dae31f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/DeathInterface.kt @@ -0,0 +1,17 @@ +package content.global.handlers.iface + +import core.api.closeInterface +import core.game.interaction.InterfaceListener +import org.rs09.consts.Components + +class DeathInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.AIDE_DEATH_153) { player, _, _, buttonID, _, _ -> + if (buttonID == 1) { + player.savedData.globalData.setDisableDeathScreen(true) + closeInterface(player) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/DeathInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/DeathInterfacePlugin.java deleted file mode 100644 index 5b57c3078..000000000 --- a/Server/src/main/content/global/handlers/iface/DeathInterfacePlugin.java +++ /dev/null @@ -1,32 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles the death interface. - * @author Vexia - */ -@Initializable -public final class DeathInterfacePlugin extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.forId(153).setPlugin(this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - if (button == 1) { - player.getSavedData().getGlobalData().setDisableDeathScreen(true); - player.getInterfaceManager().close(); - } - return true; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/EllisDialogue.java b/Server/src/main/content/global/handlers/iface/EllisDialogue.java deleted file mode 100644 index 0a28d3495..000000000 --- a/Server/src/main/content/global/handlers/iface/EllisDialogue.java +++ /dev/null @@ -1,136 +0,0 @@ -package content.global.handlers.iface; - -import core.game.dialogue.DialoguePlugin; -import content.global.skill.crafting.TanningProduct; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.game.node.item.Item; - -/** - * Represents the ellis dialogue plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class EllisDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code EllisDialogue} {@code Object}. - */ - public EllisDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code EllisDialogue} {@code Object}. - * @param player the player. - */ - public EllisDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new EllisDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - npc("Greetings friend I am a manufacturer of leather."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - player.getInventory().refresh(); - Item items[] = player.getInventory().toArray(); - for (int i = 0; i < items.length; i++) { - if (items[i] == null) { - continue; - } - if (TanningProduct.forItemId(items[i].getId()) != null) { - npc("I see you have brought me some hides.", "Would you like me to tan them for you?"); - stage = 100; - return true; - } - } - options("Can I buy some leather?", "Leather is rather weak stuff."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - player("Can I buy some leather then?"); - stage = 10; - break; - case 2: - player("Leather is rather weak stuff."); - stage = 3000; - break; - } - break; - case 10: - npc("I make leather from animal hides. Bring me some cowhides", "and one gold coin per hide, and I'll tan them into soft", "leather for you."); - stage = 2000; - break; - case 2000: - end(); - break; - case 3000: - npc("Normal leather may be quite weak, but it's very cheap - I", "make it from cowhides for only 1 gp per hide - and it's so", "easy to craft that anyone can work with it."); - stage = 3001; - break; - case 3001: - npc("Alternatively you could try hard leather. It's not so easy", "to craft, but I only charge 3 gp per cowhide to prepare it,", "and it makes much sturdier armour."); - stage = 3002; - break; - case 3002: - player("Thanks; I'll bear it in mind."); - stage = 3003; - break; - case 3003: - end(); - break; - case 100: - options("Yes please.", "No thanks."); - stage = 101; - break; - case 101: - switch (buttonId) { - case 1: - player("Yes please."); - stage = 210; - break; - case 2: - player("No thanks."); - stage = 200; - break; - } - break; - case 210: - end(); - TanningProduct.open(player, 2824); - break; - case 200: - npc("Very well, sir, as you wish."); - stage = 201; - break; - case 201: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2824 }; - } -} diff --git a/Server/src/main/content/global/handlers/iface/EmoteTabInterface.java b/Server/src/main/content/global/handlers/iface/EmoteTabInterface.java deleted file mode 100644 index 7506f5fcb..000000000 --- a/Server/src/main/content/global/handlers/iface/EmoteTabInterface.java +++ /dev/null @@ -1,30 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.emote.Emotes; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles the emote tab interface. - * @author Vexia - * - */ -@Initializable -public final class EmoteTabInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(464, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - Emotes.handle(player, button); - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/EquipmentInterface.java b/Server/src/main/content/global/handlers/iface/EquipmentInterface.java deleted file mode 100644 index f8cfa2660..000000000 --- a/Server/src/main/content/global/handlers/iface/EquipmentInterface.java +++ /dev/null @@ -1,231 +0,0 @@ -package content.global.handlers.iface; - -import content.global.skill.summoning.familiar.BurdenBeast; -import core.api.ContentAPIKt; -import core.cache.def.impl.ItemDefinition; -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.container.Container; -import core.game.container.ContainerEvent; -import core.game.container.ContainerListener; -import core.game.container.access.InterfaceContainer; -import core.game.container.impl.EquipmentContainer; -import core.game.interaction.OptionHandler; -import core.game.node.entity.combat.DeathTask; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.prayer.PrayerType; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.net.packet.PacketRepository; -import core.net.packet.context.ContainerContext; -import core.net.packet.out.ContainerPacket; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.global.action.EquipHandler; -import core.game.interaction.IntType; -import core.game.interaction.InteractionListeners; -import core.game.world.GameWorld; -import core.tools.Log; - -/** - * Represents the equipment interface. - * @author Emperor - * - */ -@Initializable -public final class EquipmentInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(102, this); - ComponentDefinition.put(387, this); - ComponentDefinition.put(667, this); - ComponentDefinition.put(670, this); - return this; - } - - @Override - public boolean handle(final Player p, Component component, int opcode, int button, final int slot, final int itemId) { - if (component.getId() == 667) { - if (button != 14) { - return false; - } - switch (opcode) { - case 155: - p.getPulseManager().clear(); - GameWorld.getPulser().submit(new Pulse(1, p) { - @Override - public boolean pulse() { - EquipHandler.unequip(p, slot, itemId); - return true; - } - }); - return true; - case 9: - p.sendMessage(p.getEquipment().get(slot).getDefinition().getExamine()); - return true; - case 196: - GameWorld.getPulser().submit(new Pulse(1, p) { - @Override - public boolean pulse() { - operate(p, slot, itemId); - return true; - } - }); - return true; - } - return false; - } - else if (component.getId() == 670) { - switch (opcode) { - case 155: - p.getPulseManager().clear(); - final Item item = p.getInventory().get(slot); - GameWorld.getPulser().submit(new Pulse(1, p) { - @Override - public boolean pulse() { - if (item == null) return true; - InteractionListeners.run(item.getId(), IntType.ITEM,"equip",p, item); - return true; - } - }); - return true; - case 9: - p.sendMessage(p.getInventory().get(slot).getDefinition().getExamine()); - return true; - } - } - switch (opcode) { - case 206: - if (button != 28) { - return false; - } - GameWorld.getPulser().submit(new Pulse(1, p) { - @Override - public boolean pulse() { - operate(p, slot, itemId); - return true; - } - }); - return true; - default: - switch (button) { - case 52: - if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 102) { - return true; - } - - // (Highlight white items are auto destroyed on death Enum#616 (Items kept on death interface) TODO: Parse server sided - // SCRIPT 118 - Items kept on death interface CS - // ARG 0: Safe location check Takes: 0 Safe Area/2 in POH/3 in Castle Wars/4 in Trouble Brewing/5 in Barbass - int zoneType = p.getZoneMonitor().getType(); - // ARG 1: Amount of items kept on death Takes: 0/1/3/4 - Container[] itemArray = DeathTask.getContainers(p); - Container kept = itemArray[0]; - int amtKeptOnDeath = kept.itemCount(); - if (amtKeptOnDeath > 4 && zoneType == 0) { - ContentAPIKt.log(this.getClass(), Log.ERR, "Items kept on death interface should not contain more than 4 items when not in a safe zone!"); - } - // ARG 2: Item kept on death slot 0 - int slot0 = kept.getId(0); - // ARG 3: Item kept on death slot 1 - int slot1 = kept.getId(1); - // ARG 4: Item kept on death slot 2 - int slot2 = kept.getId(2); - // ARG 5: Item kept on death slot 3 - int slot3 = kept.getId(3); - // ARG 6: Player skulled Takes: 0 not skulled/1 skulled - int skulled = p.getSkullManager().isSkulled() ? 1 : 0; - // ARG 7: Player has summoning creature out Takes: 0 not out/1 Creature summoned - int hasBoB; - if (p.getFamiliarManager().hasFamiliar()) { - if (p.getFamiliarManager().getFamiliar().isBurdenBeast()) { - hasBoB = ((BurdenBeast) p.getFamiliarManager().getFamiliar()).getContainer().isEmpty() ? 0 : 1; - } else { - hasBoB = 0; - } - } else { - hasBoB = 0; - } - // ARG 8: String for effect: - // if (arg1 == 0) arg8 + " This reduces the items you keep from three to zero!" - // if (arg1 == 1) arg8 + " This reduces the items you keep from three to zero!" + "
" + "
" + "However, you also have the " + "" + "Protect Items" + "" + " prayer active, which saves you one extra item!"); - Object[] params = new Object[] { hasBoB, skulled, slot3, slot2, slot1, slot0, amtKeptOnDeath, zoneType, "You are skulled." }; - p.getPacketDispatch().sendRunScript(118, "siiooooii", params); - - p.getInterfaceManager().openComponent(102); - break; - case 28: - if (opcode == 81) { - p.getPulseManager().clear(); - GameWorld.getPulser().submit(new Pulse(1, p) { - @Override - public boolean pulse() { - EquipHandler.unequip(p, slot, itemId); - return true; - } - }); - return true; - } - break; - case 55: - if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 667) { - return true; - } - final ContainerListener listener = new ContainerListener() { - @Override - public void update(Container c, ContainerEvent e) { - PacketRepository.send(ContainerPacket.class, new ContainerContext(p, -1, -1, 98, e.getItems(), false, e.getSlots())); - } - - @Override - public void refresh(Container c) { - PacketRepository.send(ContainerPacket.class, new ContainerContext(p, -1, -1, 98, c, false)); - } - }; - p.getInterfaceManager().openComponent(667).setCloseEvent((player, c) -> { - player.removeAttribute("equip_stats_open"); - player.getInterfaceManager().closeSingleTab(); - player.getInventory().getListeners().remove(listener); - return true; - }); - p.setAttribute("equip_stats_open", true); - EquipmentContainer.update(p); - p.getInterfaceManager().openSingleTab(new Component(670)); - InterfaceContainer.generateItems(p, p.getInventory().toArray(), new String[] { "Equip" }, 670, 0, 7, 4, 93); - p.getInventory().getListeners().add(listener); - p.getInventory().refresh(); - ItemDefinition.statsUpdate(p); - p.getPacketDispatch().sendIfaceSettings(1278, 14, 667, 0, 13); - break; - } - } - return true; - } - - /** - * Operates an item. - * @param player The player. - * @param slot The container slot. - * @param itemId The item id. - */ - public void operate(Player player, int slot, int itemId) { - if (slot < 0 || slot > 13) { - return; - } - Item item = player.getEquipment().get(slot); - if (item == null) { - return; - } - if(InteractionListeners.run(item.getId(),IntType.ITEM,"operate",player,item)){ - return; - } - OptionHandler handler = item.getOperateHandler(); - if (handler != null && handler.handle(player, item, "operate")) { - return; - } - player.getPacketDispatch().sendMessage("You can't operate that."); - } - -} diff --git a/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt b/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt index be4d2599e..c7003ea83 100644 --- a/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt +++ b/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt @@ -10,6 +10,7 @@ import core.plugin.Initializable import core.plugin.Plugin import core.tools.Log import org.rs09.consts.Sounds +import content.data.Quests /** * Represents the experience interface. @@ -78,15 +79,15 @@ class ExperienceInterface() : ComponentPlugin() { } private fun checkHerblore(player: Player): Boolean{ - return (player.questRepository.isComplete("Druidic Ritual")) + return (player.questRepository.isComplete(Quests.DRUIDIC_RITUAL)) } private fun checkSummoning(player: Player): Boolean{ - return player.questRepository.isComplete("Wolf Whistle") + return player.questRepository.isComplete(Quests.WOLF_WHISTLE) } private fun checkRunecrafting(player: Player): Boolean{ - return player.questRepository.isComplete("Rune Mysteries") + return player.questRepository.isComplete(Quests.RUNE_MYSTERIES) } companion object { diff --git a/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt b/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt index 70a005ec4..69bba13d7 100644 --- a/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt +++ b/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt @@ -2,109 +2,128 @@ package content.global.handlers.iface import core.api.* import core.game.event.FairyRingDialEvent -import core.game.component.Component +import core.game.interaction.InterfaceListener import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager import core.game.system.task.Pulse +import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.map.RegionManager import core.tools.RandomFunction -import core.game.interaction.InterfaceListener -import core.game.world.GameWorld - -val RING_1 = arrayOf('a','d','c','b') -val RING_2 = arrayOf('i','l','k','j') -val RING_3 = arrayOf('p','s','r','q') +import content.data.Quests /** * Handles the fairy ring interface * @author Ceikry */ class FairyRingInterface : InterfaceListener { - - val RINGS = 734 - val TRAVEL_LOG = 735 + companion object { + const val RINGS_IFACE = 734 + const val LOG_IFACE_ID = 735 + const val VARP_F_RING = 816 + const val VB_LOG_SORT_ORDER = 4618 + const val VB_RING_1 = 2341 + const val VB_RING_2 = 2342 + const val VB_RING_3 = 2343 + val RING_1 = arrayOf('a','d','c','b') + val RING_2 = arrayOf('i','l','k','j') + val RING_3 = arrayOf('p','s','r','q') + } override fun defineInterfaceListeners() { - onOpen(RINGS){player, _ -> - player.interfaceManager.openSingleTab(Component(TRAVEL_LOG)) - player.setAttribute("fr:ring1", 0) - player.setAttribute("fr:ring2", 0) - player.setAttribute("fr:ring3", 0) - FairyRing.drawLog(player) + onOpen(RINGS_IFACE){ player, _ -> + openSingleTab(player, LOG_IFACE_ID) + saveVarp(player, VARP_F_RING) return@onOpen true } - onClose(RINGS){player, _ -> - closeTabInterface(player) - player.removeAttribute("fr:ring1") - player.removeAttribute("fr:ring2") - player.removeAttribute("fr:ring3") - setVarp(player, 816, 0) + onOpen(LOG_IFACE_ID){ player, _ -> + drawLog(player) + return@onOpen true + } + + onClose(RINGS_IFACE){ player, _ -> closeTabInterface(player) return@onClose true } - on(RINGS){player, _, _, buttonID, _, _ -> - if(player.getAttribute("fr:time",0L) > System.currentTimeMillis()) return@on true - var delayIncrementer = 1750L + on(RINGS_IFACE){ player, _, _, buttonID, _, _ -> when(buttonID){ - 23 -> delayIncrementer += increment(player,1) - 25 -> delayIncrementer += increment(player,2) - 27 -> delayIncrementer += increment(player,3) + 23 -> increment(player,1) + 25 -> increment(player,2) + 27 -> increment(player,3) 24 -> decrement(player,1) 26 -> decrement(player,2) 28 -> decrement(player,3) 21 -> confirm(player) } - player.setAttribute("fr:time",System.currentTimeMillis() + delayIncrementer) return@on true } - on(TRAVEL_LOG,12){player, _, _, _, _, _ -> + on(LOG_IFACE_ID,12){ player, _, _, _, _, _ -> toggleSortOrder(player) return@on true } } - private fun toggleSortOrder(player: Player): Long{ - val ring1index = player.getAttribute("fr:ring1",0) - var toSet = player.getAttribute("fr:sortorder",true) - toSet = !toSet - player.setAttribute("fr:sortorder",toSet) - if(toSet) { - setVarp(player, 816, ring1index) - player.setAttribute("fr:ring2",0) - player.setAttribute("fr:ring3",0) + /** + * Draws the travel log interface + * Currently, the visited logs is a bool array in globalData. Someone should migrate this to prefs or something at some point. + * On transmit of Varp 816, which all used varbits are part of here, the CS2 is invoked to populate the codes in the log and sort them correctly. + * @param player The player to draw the interface for + */ + private fun drawLog (player: Player) + { + for (i in FairyRing.values().indices) { + if (!player.savedData.globalData.hasTravelLog(i)) { + continue + } + val ring = FairyRing.values()[i] + if (ring.childId == -1) { + continue + } + setInterfaceText(player, "
${ring.tip}", LOG_IFACE_ID, ring.childId) } - return -1750L } - fun increment(player: Player,ring: Int): Long{ - val curIndex = player.getAttribute("fr:ring$ring",0) - var nextIndex = 0 - if(curIndex == 3) nextIndex = 0 - else if(curIndex == 1) nextIndex = 3 - else if(curIndex == 2) nextIndex = 2 - else nextIndex = curIndex + 1 - player.setAttribute("fr:ring$ring",nextIndex) - return if (curIndex == 1) 1750L else 0L + private fun toggleSortOrder(player: Player) { + val curSort = getVarbit(player, VB_LOG_SORT_ORDER) == 0 + setVarbit(player, VB_LOG_SORT_ORDER, if (curSort) 1 else 0) + drawLog(player) + } + + fun increment(player: Player,ring: Int) { + val vbit = when(ring) { + 1 -> VB_RING_1 + 2 -> VB_RING_2 + 3 -> VB_RING_3 + else -> return + } + val curIndex = getVarbit(player, vbit) + val nextIndex: Int = if(curIndex == 3) 0 + else curIndex + 1 + setVarbit(player, vbit, nextIndex) } fun decrement(player: Player,ring: Int){ - val curIndex = player.getAttribute("fr:ring$ring",0) - var nextIndex = 0 - if(curIndex == 0) nextIndex = 3 - else nextIndex = curIndex - 1 - player.setAttribute("fr:ring$ring",nextIndex) + val vbit = when(ring) { + 1 -> VB_RING_1 + 2 -> VB_RING_2 + 3 -> VB_RING_3 + else -> return + } + val curIndex = getVarbit(player, vbit) + val nextIndex: Int = if(curIndex == 0) 3 + else curIndex - 1 + setVarbit(player, vbit, nextIndex) } private fun confirm(player: Player){ - val ring1index = player.getAttribute("fr:ring1",0) - val ring2index = player.getAttribute("fr:ring2",0) - val ring3index = player.getAttribute("fr:ring3",0) + val ring1index = getVarbit(player, VB_RING_1) + val ring2index = getVarbit(player, VB_RING_2) + val ring3index = getVarbit(player, VB_RING_3) val code = "${RING_1[ring1index]}${RING_2[ring2index]}${RING_3[ring3index]}" val ring: FairyRing? = try { FairyRing.valueOf(code.uppercase()) @@ -160,7 +179,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int AKS(Location.create(2571, 2956, 0), "Feldip Hills: Jungle Hunter area", 25), ALQ(Location.create(3597, 3495, 0), "Morytania: Haunted Woods east of Canifis", 27) { override fun checkAccess(player: Player) : Boolean { - return requireQuest(player, "Priest in Peril", "to use this ring.") + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") } }, ALS(Location.create(2644, 3495, 0), "Kandarin: McGrubor's Wood", 29), @@ -172,7 +191,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int BKQ(Location.create(3041, 4532, 0), "Other realms: Enchanted Valley", 39), BKR(Location.create(3469, 3431, 0), "Morytania: Mort Myre, south of Canifis", 40) { override fun checkAccess(player: Player) : Boolean { - return requireQuest(player, "Priest in Peril", "to use this ring.") + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") } }, BLP(Location.create(2437, 5126, 0), "Dungeons: TzHaar area", 42), @@ -180,7 +199,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int BLR(Location.create(2740, 3351, 0), "Kandarin: Legends' Guild", 44), CIP(Location.create(2513, 3884, 0), "Islands: Miscellania", 46) { override fun checkAccess(player: Player): Boolean { - return requireQuest(player, "Fremennik Trials", "to use this ring.") + return requireQuest(player, Quests.THE_FREMENNIK_TRIALS, "to use this ring.") } }, CIQ(Location.create(2528, 3127, 0), "Kandarin: North-west of Yanille", 47), @@ -189,7 +208,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int CKR(Location.create(2801, 3003, 0), "Karamja: South of Tai Bwo Wannai Village", 56), CKS(Location.create(3447, 3470, 0), "Morytania: Canifis", 57) { override fun checkAccess(player: Player) : Boolean { - return requireQuest(player, "Priest in Peril", "to use this ring.") + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") } }, CLP(Location.create(3082, 3206, 0), "Islands: South of Draynor Village", 58), @@ -208,23 +227,4 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int open fun checkAccess(player: Player) : Boolean { return true } - - companion object { - /** - * Draws the travel log. - * @param player the player. - */ - fun drawLog(player: Player) { - for (i in FairyRing.values().indices) { - if (!player.savedData.globalData.hasTravelLog(i)) { - continue - } - val ring = FairyRing.values()[i] - if (ring.childId == -1) { - continue - } - setInterfaceText(player, "
${ring.tip}", 735, ring.childId) - } - } - } } diff --git a/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt b/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt index c395840e6..a335a5fbb 100644 --- a/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt +++ b/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt @@ -6,6 +6,7 @@ import core.game.component.ComponentDefinition import core.game.component.ComponentPlugin import core.game.container.access.InterfaceContainer import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType import core.game.node.item.Item import core.plugin.Initializable import core.plugin.Plugin @@ -162,9 +163,14 @@ class FurClothingInterface : ComponentPlugin(){ return } - removeItem(player, requiredFur, Container.INVENTORY) - removeItem(player, coins, Container.INVENTORY) - addItem(player, clothing.product.id, amount) + if (removeItem(player, requiredFur, Container.INVENTORY) && + removeItem(player, coins, Container.INVENTORY)) { + addItem(player, clothing.product.id, amount) + + if (clothing == FUR_CLOTHING.DASH_CAPE) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 2) + } + } } override fun newInstance(arg: Any?): Plugin { diff --git a/Server/src/main/content/global/handlers/iface/GameInterface.java b/Server/src/main/content/global/handlers/iface/GameInterface.java deleted file mode 100644 index 0c8754f29..000000000 --- a/Server/src/main/content/global/handlers/iface/GameInterface.java +++ /dev/null @@ -1,185 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.plugin.Initializable; -import core.game.node.entity.combat.equipment.WeaponInterface; -import core.game.node.entity.combat.equipment.WeaponInterface.WeaponInterfaces; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.info.Rights; -import core.game.world.GameWorld; -import core.plugin.Plugin; - -/** - * Represents the component plugin used for the game interface. - * @author Vexia - * - */ -@Initializable -public final class GameInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(740, this); - return this; - } - - @Override - public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { - switch (component.getId()) { - case 740: - switch (button){ - case 3: - player.getInterfaceManager().closeChatbox(); - break; - } - return true; - case 746: - switch (button){ - case 12: - player.getPacketDispatch().sendString("When you have finished playing " + GameWorld.getSettings().getName() + ", always use the button below to logout safely. ", 182, 0); - break; - case 49: - player.getPacketDispatch().sendString("Friends List - " + GameWorld.getSettings().getName() + " " + GameWorld.getSettings().getWorldId(), 550, 3); - break; - case 110: - configureWorldMap(player); - break; - } - return true; - case 548: - if (button >= 38 && button<= 44 || button >= 20 && button <= 26) { - player.getInterfaceManager().setCurrentTabIndex(getTabIndex(button)); - } - //Interface buttons that advance the Tutorial Island stages - switch (button) { - case 21://Friends Tab - player.getPacketDispatch().sendString("Friends List -" + GameWorld.getSettings().getName() + " " + GameWorld.getSettings().getWorldId(), 550, 3); - break; - case 22://Ignore Tab - break; - case 24://Settings Tab - break; - case 25://Emotes Tab - break; - case 26://Music Tab - break; - case 38://Attack Tab - if (player.getExtension(WeaponInterface.class) == WeaponInterfaces.STAFF) { - final Component c = new Component(WeaponInterfaces.STAFF.getInterfaceId()); - player.getInterfaceManager().openTab(0, c); - final WeaponInterface inter = player.getExtension(WeaponInterface.class); - inter.updateInterface(); - } - break; - case 39://Skill Tab - break; - case 40://Quest Tab - /*if (GameWorld.isEconomyWorld()) { - player.getQuestRepository().syncronizeTab(player); - } else { - player.getSavedData().getSpawnData().drawStatsTab(player); - }*/ - - player.getQuestRepository().syncronizeTab(player); - break; - case 41://Inventory Tab - player.getInventory().refresh(); - break; - case 42://Worn Equipment Tab - break; - case 43://Prayer Tab - break; - case 44://Magic Tab - break; - case 66://World map - case 110: - configureWorldMap(player); - break; - case 69://Logout - player.getPacketDispatch().sendString("When you have finished playing " + GameWorld.getSettings().getName() + ", always use the button below to logout safely. ", 182, 0); - break; - } - return true; - case 750: - switch (opcode) { - case 155: - switch (button) { - case 1: - player.getSettings().toggleRun(); - break; - } - break; - } - return true; - case 751: - switch (opcode) { - case 155: - switch (button) { - case 27: - openReport(player); - break; - } - break; - } - return true; - } - return true; - } - - /** - * World map - * Thanks, Snickerize! - */ - private void configureWorldMap(Player player) { - if (player.inCombat()) { - player.getPacketDispatch().sendMessage("It wouldn't be very wise opening the world map during combat."); - return; - } - if(player.getLocks().isInteractionLocked() || player.getLocks().isMovementLocked()){ - player.getPacketDispatch().sendMessage("You can't do this right now."); - return; - } - player.getInterfaceManager().openWindowsPane(new Component(755)); - int posHash = (player.getLocation().getZ() << 28) | (player.getLocation().getX() << 14) | player.getLocation().getY(); - player.getPacketDispatch().sendScriptConfigs(622, posHash, "", 0); - player.getPacketDispatch().sendScriptConfigs(674, posHash, "", 0); - } - - /** - * Method used to open the report interface. - * @param player the player. - */ - public static void openReport(final Player player) { - player.getInterfaceManager().open(new Component(553)).setCloseEvent((player1, c) -> { - player1.getPacketDispatch().sendRunScript(80, ""); - player1.getPacketDispatch().sendRunScript(137, ""); - return true; - }); - player.getPacketDispatch().sendRunScript(508, ""); - if (player.getDetails().getRights() != Rights.REGULAR_PLAYER) { - for (int i = 0; i < 18; i++) { - player.getPacketDispatch().sendInterfaceConfig(553, i, false); - } - } - } - - /** - * Gets the tab index. - * @param button The button id. - * @return The tab index. - */ - private static int getTabIndex(int button) { - int tabIndex = button - 38; - if (button < 27) { - tabIndex = (button - 20) + 7; - } - return tabIndex; - } - - /** - * Configures the world map for a player. - * @param player The player. - */ -} diff --git a/Server/src/main/content/global/handlers/iface/GliderInterface.java b/Server/src/main/content/global/handlers/iface/GliderInterface.java deleted file mode 100644 index 08459cefe..000000000 --- a/Server/src/main/content/global/handlers/iface/GliderInterface.java +++ /dev/null @@ -1,37 +0,0 @@ -package content.global.handlers.iface; - -import static core.api.ContentAPIKt.*; -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import content.global.travel.glider.GliderPulse; -import content.global.travel.glider.Gliders; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the glider interface component. - * @author Emperor - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class GliderInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(138, this); - return this; - } - - @Override - public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { - final Gliders glider = Gliders.forId(button); - if (glider == null) { - return true; - } - submitWorldPulse(new GliderPulse(1, player, glider)); - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/GliderInterface.kt b/Server/src/main/content/global/handlers/iface/GliderInterface.kt new file mode 100644 index 000000000..cc43ede4a --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/GliderInterface.kt @@ -0,0 +1,17 @@ +package content.global.handlers.iface + +import core.api.submitWorldPulse +import content.global.travel.glider.GliderPulse +import content.global.travel.glider.Gliders +import core.game.interaction.InterfaceListener +import org.rs09.consts.Components + +class GliderInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.GLIDERMAP_138) { player, _, _, button, _, _ -> + val glider = Gliders.forId(button) ?: return@on true + submitWorldPulse(GliderPulse(1, player, glider)) + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt b/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt index b1750ae63..d9058006e 100644 --- a/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt +++ b/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt @@ -152,11 +152,11 @@ class HairDresserInterface : ComponentPlugin(){ player.setAttribute("beard-setting",false) if(!pl.getAttribute("hairdresser-paid",false)){ val original_hair = player.getAttribute("original-hair",0) - val original_beard = player.getAttribute("original_beard",-1) - val original_color = player.getAttribute("original_color",0) + val original_beard = player.getAttribute("original-beard",-1) + val original_color = player.getAttribute("original-color",0) pl.appearance.hair.changeLook(original_hair) pl.appearance.hair.changeColor(original_color) - if(original_beard != -1) { + if (original_beard != -1) { pl.appearance.beard.changeLook(original_beard) } pl.appearance.sync() @@ -174,7 +174,7 @@ class HairDresserInterface : ComponentPlugin(){ when(button){ 199 -> player.setAttribute("beard-setting",false) 200 -> player.setAttribute("beard-setting",true) - 68,196,274 -> pay(player) + 196,274,68,100 -> pay(player) else -> when(component?.id){ 592 -> { //Female if(femaleColorButtonRange.contains(button)){ diff --git a/Server/src/main/content/global/handlers/iface/LoginInterface.kt b/Server/src/main/content/global/handlers/iface/LoginInterface.kt new file mode 100644 index 000000000..e2464c176 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/LoginInterface.kt @@ -0,0 +1,34 @@ +package content.global.handlers.iface + +import core.api.closeInterface +import core.api.runTask +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.info.login.LoginConfiguration +import org.rs09.consts.Components + +class LoginInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.WELCOME_SCREEN_378) { player, _, _, buttonID, _, _ -> + val playButton = 140 + val creditButton = 145 + val discordButton = 204 + + when (buttonID) { + playButton -> { + player.locks.lock("login", 2) + closeInterface(player) + runTask(player, 1, 0) { + LoginConfiguration.configureGameWorld(player) + } + } + creditButton -> return@on true + discordButton -> return@on true + } + return@on true + } + + onClose(Components.WELCOME_SCREEN_378) { player, _ -> + return@onClose player.locks.isLocked("login") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/LoginInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/LoginInterfacePlugin.java deleted file mode 100644 index f91a3000e..000000000 --- a/Server/src/main/content/global/handlers/iface/LoginInterfacePlugin.java +++ /dev/null @@ -1,51 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.info.login.LoginConfiguration; -import core.game.system.task.Pulse; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used for the login interface. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class LoginInterfacePlugin extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(378, this); - return null; - } - - @Override - public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { - switch (button) { - case 140: - if (player.getLocks().isLocked("login")) { - return true; - } - player.getLocks().lock("login", 2); - player.getInterfaceManager().close(); - player.getPulseManager().run(new Pulse(1) { - @Override - public boolean pulse() { - LoginConfiguration.configureGameWorld(player); - return true; - } - }); - break; - case 145://credits - break; - case 204://message centre - break; - } - return true; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/LogoutInterface.java b/Server/src/main/content/global/handlers/iface/LogoutInterface.java deleted file mode 100644 index d3a7c9c1a..000000000 --- a/Server/src/main/content/global/handlers/iface/LogoutInterface.java +++ /dev/null @@ -1,42 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.world.GameWorld; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.world.repository.Repository; - -/** - * Represents the interface used to logout of the game. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class LogoutInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(182, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - if (!player.getZoneMonitor().canLogout()) { - return true; - } - if (player.inCombat()) { - player.getPacketDispatch().sendMessage("You can't log out until 10 seconds after the end of combat."); - return true; - } - if (player.isTeleporting()) { - player.sendMessage("Please finish your teleport before logging out."); - return true; - } - Repository.getDisconnectionQueue().add(player); - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/MagicBookInterface.java b/Server/src/main/content/global/handlers/iface/MagicBookInterface.java deleted file mode 100644 index af5c87baa..000000000 --- a/Server/src/main/content/global/handlers/iface/MagicBookInterface.java +++ /dev/null @@ -1,50 +0,0 @@ -package content.global.handlers.iface; - -import content.global.skill.magic.SpellListener; -import content.global.skill.magic.SpellListeners; -import content.global.skill.magic.SpellUtils; -import core.game.event.SpellCastEvent; -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.plugin.Initializable; -import core.game.node.entity.combat.spell.MagicSpell; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.world.GameWorld; -import core.plugin.Plugin; - -/** - * Represents the magic book interface handling of non-combat spells. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class MagicBookInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(192, this); - ComponentDefinition.put(193, this); - ComponentDefinition.put(430, this); - return this; - } - - @Override - public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { - if (GameWorld.getTicks() < player.getAttribute("magic:delay", -1)) { - return true; - } - - SpellBook spellBook = component.getId() == 192 - ? SpellBook.MODERN - : component.getId() == 193 - ? SpellBook.ANCIENT - : SpellBook.LUNAR; - - SpellListeners.run(button, SpellListener.NONE, SpellUtils.getBookFromInterface(component.getId()),player,null); - boolean result = MagicSpell.castSpell(player, spellBook, button, player); - - return result; - } -} diff --git a/Server/src/main/content/global/handlers/iface/MainGameInterface.kt b/Server/src/main/content/global/handlers/iface/MainGameInterface.kt index 243337f4e..e7f4edb05 100644 --- a/Server/src/main/content/global/handlers/iface/MainGameInterface.kt +++ b/Server/src/main/content/global/handlers/iface/MainGameInterface.kt @@ -31,32 +31,13 @@ class MainGameInterface : InterfaceListener { } on(TOPLEVEL_FS){player, _, _, buttonID, _, _ -> - when (buttonID) { - 12 -> setInterfaceText(player, - "When you have finished playing " + settings!!.name + ", always use the button below to logout safely. ", - 182, - 0 - ) - 49 -> setInterfaceText(player, - "Friends List - " + settings!!.name + " " + settings!!.worldId, - 550, - 3 - ) - 110 -> configureWorldMap(player) - } + if (buttonID == 110) + configureWorldMap(player) return@on true } - on(TOPLEVEL){player, _, _, buttonID, _, _ -> when (buttonID) { - 21 -> { - player.packetDispatch.sendString( - "Friends List -" + settings!!.name + " " + settings!!.worldId, - 550, - 3 - ) - } 38 -> { if (player.getExtension(WeaponInterface::class.java) === WeaponInterfaces.STAFF) { val c = Component(WeaponInterfaces.STAFF.interfaceId) @@ -67,12 +48,7 @@ class MainGameInterface : InterfaceListener { } 40 -> player.questRepository.syncronizeTab(player) 41 -> player.inventory.refresh() - 66, 110 -> configureWorldMap(player) - 69 -> player.packetDispatch.sendString( - "When you have finished playing " + settings!!.name + ", always use the button below to logout safely. ", - 182, - 0 - ) + 66 -> configureWorldMap(player) } return@on true } @@ -95,11 +71,11 @@ class MainGameInterface : InterfaceListener { private fun configureWorldMap(player: Player) { if (player.inCombat()) { - player.packetDispatch.sendMessage("It wouldn't be very wise opening the world map during combat.") + sendMessage(player, "It wouldn't be very wise opening the world map during combat.") return } if (player.locks.isInteractionLocked || player.locks.isMovementLocked) { - player.packetDispatch.sendMessage("You can't do this right now.") + sendMessage(player, "You can't do this right now.") return } player.interfaceManager.close() diff --git a/Server/src/main/content/global/handlers/iface/MusicTabInterface.java b/Server/src/main/content/global/handlers/iface/MusicTabInterface.java deleted file mode 100644 index 579607fe5..000000000 --- a/Server/src/main/content/global/handlers/iface/MusicTabInterface.java +++ /dev/null @@ -1,57 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.info.Rights; -import core.game.node.entity.player.link.music.MusicEntry; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles the interface tab buttons. - * @author Emperor - */ -@Initializable -public final class MusicTabInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(187, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - switch (opcode) { - case 155: - switch (button) { - case 11: - player.getMusicPlayer().toggleLooping(); - return true; - case 1: - MusicEntry entry = player.getMusicPlayer().getUnlocked().get(slot); - if (entry == null) { - if(player.getRights().equals(Rights.ADMINISTRATOR)){ - for(MusicEntry ent : MusicEntry.getSongs().values()){ - if(ent.getIndex() == slot){ - player.getMusicPlayer().unlock(ent.getId()); - break; - } - } - } else { - player.getPacketDispatch().sendMessage("You have not unlocked this piece of music yet!"); - } - return true; - } - player.getMusicPlayer().setPlaying(false); - player.getMusicPlayer().play(entry); - return true; - } - break; - } - return false; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/MysticStaffEnchantInterface.kt b/Server/src/main/content/global/handlers/iface/MysticStaffEnchantInterface.kt new file mode 100644 index 000000000..6d9748d09 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/MysticStaffEnchantInterface.kt @@ -0,0 +1,57 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.InterfaceListener +import core.game.node.item.Item +import core.tools.StringUtils +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class MysticStaffEnchantInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(INTERFACE_332) { player, _, _, buttonID, _, _ -> + val staff = buttonMap[buttonID] ?: return@on true + + if (!inInventory(player, staff.basicID)) { + sendMessage(player, "You don't have a${if (StringUtils.isPlusN(getItemName(staff.basicID))) "n" else ""} ${getItemName(staff.basicID)} to enchant.") + return@on true + } + + closeInterface(player) + + if (!inInventory(player, Items.COINS_995, 40000)) { + sendNPCDialogue(player, NPCs.THORMAC_389, "I need ${String.format("%,d", 40000)} coins for materials. Come back when you have the money!", FacialExpression.NEUTRAL) + return@on true + } + + if (removeItem(player, Item(staff.basicID, 1)) && removeItem(player, Item(Items.COINS_995, 40000))) { + sendNPCDialogue(player, NPCs.THORMAC_389, "Just a moment... hang on... hocus pocus abra-cadabra... there you go! Enjoy your enchanted staff!", FacialExpression.NEUTRAL) + addItem(player, staff.enchantedID, 1) + } + return@on true + } + } + + enum class EnchantedStaff(val enchantedID: Int, val basicID: Int, val buttonID: Int) { + AIR(Items.MYSTIC_AIR_STAFF_1405, Items.AIR_BATTLESTAFF_1397, 21), + WATER(Items.MYSTIC_WATER_STAFF_1403, Items.WATER_BATTLESTAFF_1395, 22), + EARTH(Items.MYSTIC_EARTH_STAFF_1407, Items.EARTH_BATTLESTAFF_1399, 23), + FIRE(Items.MYSTIC_FIRE_STAFF_1401, Items.FIRE_BATTLESTAFF_1393, 24), + LAVA(Items.MYSTIC_LAVA_STAFF_3054, Items.LAVA_BATTLESTAFF_3053, 25), + MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26), + STEAM(Items.MYSTIC_STEAM_STAFF_11738, Items.STEAM_BATTLESTAFF_11736, 27), + } + + companion object { + private const val INTERFACE_332 = 332 + + val buttonMap = HashMap() + + init { + for (staff in EnchantedStaff.values()) { + buttonMap[staff.buttonID] = staff + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/MysticStaffEnchantingPlugin.java b/Server/src/main/content/global/handlers/iface/MysticStaffEnchantingPlugin.java deleted file mode 100644 index af798008d..000000000 --- a/Server/src/main/content/global/handlers/iface/MysticStaffEnchantingPlugin.java +++ /dev/null @@ -1,95 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import org.rs09.consts.Items; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Plugin; -import core.plugin.Initializable; -import core.tools.StringUtils; - -import java.util.HashMap; - -/** - * Represents the plugin used to handle the agility ticket interface. - * @author afaroutdude - */ -@Initializable -public final class MysticStaffEnchantingPlugin extends ComponentPlugin { - - private final Component COMPONENT = new Component(332); - private final int cost = 40000; - - protected enum EnchantedStaff { - AIR(Items.MYSTIC_AIR_STAFF_1405, Items.AIR_BATTLESTAFF_1397, 21), - WATER(Items.MYSTIC_WATER_STAFF_1403, Items.WATER_BATTLESTAFF_1395, 22), - EARTH(Items.MYSTIC_EARTH_STAFF_1407, Items.EARTH_BATTLESTAFF_1399, 23), - FIRE(Items.MYSTIC_FIRE_STAFF_1401, Items.FIRE_BATTLESTAFF_1393, 24), - LAVA(Items.MYSTIC_LAVA_STAFF_3054, Items.LAVA_BATTLESTAFF_3053, 25), - MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26); - - public final int enchanted; - public final int basic; - public final int child; - - private static final HashMap basicToEnchanted = new HashMap<>(); - private static final HashMap childToBasic = new HashMap<>(); - - static { - for (EnchantedStaff staff : EnchantedStaff.values()) { - basicToEnchanted.put(staff.basic, staff.enchanted); - childToBasic.put(staff.child, staff.basic); - } - } - - EnchantedStaff(int enchantedId, int basicId, int childId) { - this.enchanted = enchantedId; - this.basic = basicId; - this.child = childId; - } - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.forId(332).setPlugin(this); - return this; - } - - @Override - public void open(Player player, Component component) { - super.open(player, component); - // zoom doesn't work, but based on https://youtu.be/qxxhhCdxBsQ?t=75 seems correct anyway - for (EnchantedStaff staff : EnchantedStaff.values()) { - player.getPacketDispatch().sendItemZoomOnInterface(staff.basic, 240, COMPONENT.getId(), staff.child); - } - } - - @Override - public boolean handle(Player player, Component component, int opcode, int buttonId, int slot, int itemId) { - player.getPacketDispatch().sendMessage("op: " + opcode + " button: " + buttonId + " slot: "+ slot + " item: " + itemId); - - if (EnchantedStaff.childToBasic.containsKey(buttonId)) { - Item basicStaff = new Item(EnchantedStaff.childToBasic.get(buttonId)); - Item enchantedStaff = new Item(EnchantedStaff.basicToEnchanted.get(basicStaff.getId())); - - if (!player.getInventory().containsItem(basicStaff)) { - player.getPacketDispatch().sendMessage("You don't have a" + (StringUtils.isPlusN(basicStaff.getName()) ? "n " : " ") + basicStaff.getName() + " to enchant."); - return true; - } - if (!player.getInventory().contains(995, cost)) { - player.getInterfaceManager().close(); - player.getDialogueInterpreter().sendDialogues(389, null, "I need 40,000 coins for materials. Come", "back when you have the money!"); - return true; - } - if (player.getInventory().remove(basicStaff, new Item(995, cost))) { - player.getInterfaceManager().close(); - player.getDialogueInterpreter().sendDialogues(389, null, "Just a moment... hang on... hocus pocus abra-", "cadabra... there you go! Enjoy your enchanted staff!"); - player.getInventory().add(enchantedStaff); - } - } - - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/PrayerTabInterface.java b/Server/src/main/content/global/handlers/iface/PrayerTabInterface.java deleted file mode 100644 index 2d0932e89..000000000 --- a/Server/src/main/content/global/handlers/iface/PrayerTabInterface.java +++ /dev/null @@ -1,38 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.prayer.PrayerType; -import core.plugin.Initializable; -import core.plugin.Plugin; - -import static core.api.ContentAPIKt.hasRequirement; - -/** - * Represents the prayer interface. - * @author 'Vexia - */ -@Initializable -public final class PrayerTabInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(271, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - final PrayerType type = PrayerType.get(button); - if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY) - if (!hasRequirement(player, "King's Ransom")) - return true; - if (type == null) { - return true; - } - player.getPrayer().toggle(type); - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/QuestTabInterface.java b/Server/src/main/content/global/handlers/iface/QuestTabInterface.java deleted file mode 100644 index 90d580af2..000000000 --- a/Server/src/main/content/global/handlers/iface/QuestTabInterface.java +++ /dev/null @@ -1,71 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.diary.AchievementDiary; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.entity.player.link.quest.Quest; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles the quest tab reward buttons. - * @author Emperor - * @author Vexia - */ -@Initializable -public class QuestTabInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(274, this); // Quests - ComponentDefinition.put(259, this); // Achievement diary - return this; - } - - @Override - public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) { - p.getPulseManager().clear(); - switch (component.getId()) { - case 274: -// if (!GameWorld.isEconomyWorld()) { -// p.getSavedData().getSpawnData().handleButton(p, button); -// } - switch (button) { - case 3: - p.getAchievementDiaryManager().openTab(); - return true; - case 10: - break; - default: -// if (GameWorld.isEconomyWorld()) { - - Quest quest = p.getQuestRepository().forButtonId(button); - if (quest != null) { - p.getInterfaceManager().open(new Component(275)); - quest.drawJournal(p, quest.getStage(p)); - return true; - } else QuestTabUtils.showRequirementsInterface(p, button); -// } - return false; - } - break; - case 259: - switch (button) { - case 8: - p.getInterfaceManager().openTab(2, new Component(274)); - return true; - default: - AchievementDiary diary = p.getAchievementDiaryManager().getDiary(DiaryType.forChild(button)); - if (diary != null) { - diary.open(p); - } - return true; - } - } - return true; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/QuestTabUtils.kt b/Server/src/main/content/global/handlers/iface/QuestTabUtils.kt deleted file mode 100644 index d7482c089..000000000 --- a/Server/src/main/content/global/handlers/iface/QuestTabUtils.kt +++ /dev/null @@ -1,244 +0,0 @@ -package content.global.handlers.iface - -import core.game.requirement.* -import core.api.* -import core.tools.* -import core.game.node.entity.player.Player -import core.game.node.entity.skill.Skills - -import kotlin.math.* -import java.util.* - -import org.rs09.consts.* - -object QuestTabUtils { - @JvmStatic - fun showRequirementsInterface (player: Player, button: Int) { - val questName = getNameForButton (button) - val questReq = QuestRequirements.values().filter { it.questName.equals(questName, true) }.firstOrNull() ?: return - var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player) - - var messageList = ArrayList() - - val statMap = HashMap() - val questList = HashSet() - var maxQpReq = 0 - var qpPenalty = 0 - closeInterface(player) - for (req in unmetReqs) { - if (req is QuestReq) - questList.add(req.questReq.questName) - else if (req is SkillReq) { - if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level)) - statMap[req.skillId] = req.level - } - else if (req is QPReq && req.amount > maxQpReq) - maxQpReq = req.amount - else if (req is QPCumulative) - qpPenalty += req.amount - } - - messageList.add(colorize("%B[Quests Needed]")) - messageList.addAll(questList.map { "Completion of $it" }) - - messageList.add(" ") - messageList.add(colorize("%B[Skills Needed]")) - - for ((skillId, level) in statMap) { - val name = Skills.SKILL_NAME[skillId] - messageList.add("$level $name") - } - - messageList.add(" ") - messageList.add(colorize("%B[Other Reqs]")) - - val totalQpRequirement = QPReq(min(max(maxQpReq, qpPenalty), player.questRepository.getAvailablePoints())) - val (meetsQp, _) = totalQpRequirement.evaluate(player) - isMet = isMet && meetsQp - - if (isMet) - messageList.add(colorize("%GCongratulations! You've earned this one.")) - - if (!meetsQp) messageList.add("A total of ${totalQpRequirement.amount} Quest Points.") - - messageList.add("") - messageList.add(colorize("%BDISCLAIMER: If you're seeing this screen, this quest is not")) - messageList.add(colorize("%Bimplemented yet. These are the requirements that you need in order")) - messageList.add(colorize("%Bto access implemented content that would normally require this quest")) - messageList.add("") - messageList.add("If you want to see more quests enter the game, consider") - messageList.add("contributing dialogue transcripts!") - - - setInterfaceText(player, questName, Components.QUESTJOURNAL_SCROLL_275, 2) - var lineId = 11 - for(i in 0..299) { - val entry = messageList.elementAtOrNull(i) - if (entry != null) - setInterfaceText(player, entry, Components.QUESTJOURNAL_SCROLL_275, lineId++) - else - setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) - } - openInterface(player, Components.QUESTJOURNAL_SCROLL_275) - } - - fun getNameForButton (button: Int) : String { - val name = when (button) { - 10 -> "Myths of the White Lands" - 11 -> "Myths of the White Lands" - 12 -> "Free Quests" - 13 -> "Black Knights' Fortress" - 14 -> "Cook's Assistant" - 15 -> "Demon Slayer" - 16 -> "Doric's Quest" - 17 -> "Dragon Slayer" - 18 -> "Ernest the Chicken" - 19 -> "Goblin Diplomacy" - 20 -> "Imp Catcher" - 21 -> "The Knight's Sword" - 22 -> "Pirate's Treasure" - 23 -> "Prince Ali Rescue" - 24 -> "The Restless Ghost" - 25 -> "Romeo & Juliet" - 26 -> "Rune Mysteries" - 27 -> "Sheep Shearer" - 28 -> "Shield of Arrav" - 29 -> "Vampire Slayer" - 30 -> "Witch's Potion" - 31 -> "Members' Quests" - 32 -> "Animal Magnetism" - 33 -> "Between a Rock..." - 34 -> "Big Chompy Bird Hunting" - 35 -> "Biohazard" - 36 -> "Cabin Fever" - 37 -> "Clock Tower" - 38 -> "Contact!" - 39 -> "Zogre Flesh Eaters" - 40 -> "Creature of Fenkenstrain" - 41 -> "Darkness of Hallowvale" - 42 -> "Death to the Dorgeshuun" - 43 -> "Death Plateau" - 44 -> "Desert Treasure" - 45 -> "Devious Minds" - 46 -> "The Dig Site" - 47 -> "Druidic Ritual" - 48 -> "Dwarf Cannon" - 49 -> "Eadgar's Ruse" - 50 -> "Eagles' Peak" - 51 -> "Elemental Workshop I" - 52 -> "Elemental Workshop II" - 53 -> "Enakhra's Lament" - 54 -> "Enlightened Journey" - 55 -> "The Eyes of Glouphrie" - 56 -> "Fairytale I - Growing Pains" - 57 -> "Fairytale II - Cure a Queen" - 58 -> "Family Crest" - 59 -> "The Feud" - 60 -> "Fight Arena" - 61 -> "Fishing Contest" - 62 -> "Forgettable Tale..." - 63 -> "The Fremennik Trials" - 64 -> "Waterfall Quest" - 65 -> "Garden of Tranquillity" - 66 -> "Gertrude's Cat" - 67 -> "Ghosts Ahoy" - 68 -> "The Giant Dwarf" - 69 -> "The Golem" - 70 -> "The Grand Tree" - 71 -> "The Hand in the Sand" - 72 -> "Haunted Mine" - 73 -> "Hazeel Cult" - 74 -> "Heroes' Quest" - 75 -> "Holy Grail" - 76 -> "Horror from the Deep" - 77 -> "Icthlarin's Little Helper" - 78 -> "In Aid of the Myreque" - 79 -> "In Search of the Myreque" - 80 -> "Jungle Potion" - 81 -> "Legend's Quest" - 82 -> "Lost City" - 83 -> "The Lost Tribe" - 84 -> "Lunar Diplomacy" - 85 -> "Making History" - 86 -> "Merlin's Crystal" - 87 -> "Monkey Madness" - 88 -> "Monk's Friend" - 89 -> "Mountain Daughter" - 90 -> "Mourning's End Part I" - 91 -> "Mourning's End Part II" - 92 -> "Murder Mystery" - 93 -> "My Arm's Big Adventure" - 94 -> "Nature Spirit" - 95 -> "Observatory Quest" - 96 -> "One Small Favour" - 97 -> "Plague City" - 98 -> "Priest in Peril" - 99 -> "Rag and Bone Man" - 100 -> "Ratcatchers" - 101 -> "Recipe for Disaster" - 102 -> "Recruitment Drive" - 103 -> "Regicide" - 104 -> "Roving Elves" - 105 -> "Royal Trouble" - 106 -> "Rum Deal" - 107 -> "Scorpion Catcher" - 108 -> "Sea Slug" - 109 -> "The Slug Menace" - 110 -> "Shades of Mort'ton" - 111 -> "Shadow of the Storm" - 112 -> "Sheep Herder" - 113 -> "Shilo Village" - 114 -> "A Soul's Bane" - 115 -> "Spirits of the Elid" - 116 -> "Swan Song" - 117 -> "Tai Bwo Wannai Trio" - 118 -> "A Tail of Two Cats" - 119 -> "Tears of Guthix" - 120 -> "Temple of Ikov" - 121 -> "Throne of Miscellania" - 122 -> "The Tourist Trap" - 123 -> "Witch's House" - 124 -> "Tree Gnome Village" - 125 -> "Tribal Totem" - 126 -> "Troll Romance" - 127 -> "Troll Stronghold" - 128 -> "Underground Pass" - 129 -> "Wanted!" - 130 -> "Watchtower" - 131 -> "Cold War" - 132 -> "The Fremennik Isles" - 133 -> "Tower of Life" - 134 -> "The Great Brain Robbery" - 135 -> "What Lies Below" - 136 -> "Olaf's Quest" - 137 -> "Another Slice of H.A.M" - 138 -> "Dream Mentor" - 139 -> "Grim Tales" - 140 -> "King's Ransom" - 141 -> "The Path of Glouphrie" - 142 -> "Back to my Roots" - 143 -> "Land of the Goblins" - 144 -> "Dealing with Scabaras" - 145 -> "Wolf Whistle" - 146 -> "As a First Resort..." - 147 -> "Catapult Construction" - 148 -> "Kennith's Concerns" - 149 -> "Legacy of Seergaze" - 150 -> "Perils of Ice Mountain" - 151 -> "TokTz-Ket-Dill" - 152 -> "Smoking Kills" - 153 -> "Rocking Out" - 154 -> "Spirit of Summer" - 155 -> "Meeting History" - 156 -> "All Fired Up" - 157 -> "Summer's End" - 158 -> "Defender of Varrock" - 159 -> "Swept Away" - 160 -> "While Guthix Sleeps" - 161 -> "In Pyre Need" - 162 -> "Myths of the White Lands" - else -> "" - } - return name - } -} diff --git a/Server/src/main/content/global/handlers/iface/SettingTabInterface.java b/Server/src/main/content/global/handlers/iface/SettingTabInterface.java deleted file mode 100644 index c8bac8cb7..000000000 --- a/Server/src/main/content/global/handlers/iface/SettingTabInterface.java +++ /dev/null @@ -1,89 +0,0 @@ -package content.global.handlers.iface; - -import static core.api.ContentAPIKt.*; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; -import core.plugin.Plugin; - -/** - * @author 'Vexia - */ -@Initializable -public class SettingTabInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(261, this); - return this; - } - - @Override - public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) { - switch (button) { - case 10:// brightness - int brightness = button - 7; - p.getSettings().setBrightness(brightness); - break; - case 11: - case 12: - case 13: - case 14: - case 15:// music - int volume = 15 - button; - p.getSettings().setMusicVolume(volume); - break; - case 16://530 settings - /* if (TutorialSession.getExtension(p).getStage() != TutorialSession.MAX_STAGE) { - p.sendMessage("You must finish the tutorial before opening the graphic settings."); - break; - }*/ - p.getInterfaceManager().open(new Component(742)); - break; - case 18://530 settings - p.getInterfaceManager().open(new Component(743)); - break; - case 17: - case 19: - case 20:// sonund - int volume1 = 20 - button; - p.getSettings().setSoundEffectVolume(volume1); - break; - case 29: - case 30: - case 31: - case 32: - case 33:// all sound - int volume11 = 33 - button; - p.getSettings().setAreaSoundVolume(volume11); - break; - case 6:// mouse - p.getSettings().toggleMouseButton(); - break; - case 4:// effects - p.getSettings().toggleChatEffects(); - break; - case 5:// private chat - p.getSettings().toggleSplitPrivateChat(); - break; - case 7:// aid - if (p.getIronmanManager().checkRestriction()) { - return true; - } - p.getSettings().toggleAcceptAid(); - break; - case 3:// run - p.getSettings().toggleRun(); - break; - case 8:// house - p.getInterfaceManager().close(); - setVarp(p, 261, getVarp(p, 261) & 0x1); - p.getInterfaceManager().openSingleTab(new Component(398)); - break; - } - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/SkillInterface.java b/Server/src/main/content/global/handlers/iface/SkillInterface.java deleted file mode 100644 index a0ac47d21..000000000 --- a/Server/src/main/content/global/handlers/iface/SkillInterface.java +++ /dev/null @@ -1,32 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the plugin used for the skilling interface. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class SkillInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(499, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - setVarbit(player, 3288, player.getAttribute("skillMenu", -1)); - setVarbit(player, 3289, button - 10); - return true; - } -} diff --git a/Server/src/main/content/global/handlers/iface/SkillTabInterface.java b/Server/src/main/content/global/handlers/iface/SkillTabInterface.java deleted file mode 100644 index 9dba5877b..000000000 --- a/Server/src/main/content/global/handlers/iface/SkillTabInterface.java +++ /dev/null @@ -1,162 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.skill.LevelUp; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.world.GameWorld; -import core.plugin.Initializable; -import core.plugin.Plugin; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the plugin used to handle the skilling tab. - * @author Vexia - * @author Splinter - * @version 1.1 - */ -@Initializable -public final class SkillTabInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(320, this); - return this; - } - - @Override - public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) { - final SkillConfig config = SkillConfig.forId(button); - if (config == null) { - return true; - } - if (!GameWorld.getSettings().isPvp()) { - if (p.getAttribute("levelup:" + config.getSkillId(), false)) { - p.removeAttribute("levelup:" + config.getSkillId()); - LevelUp.sendFlashingIcons(p, -1); - setVarp(p, 1230, ADVANCE_CONFIGS[config.getSkillId()]); - p.getInterfaceManager().open(new Component(741)); - } else { - p.getPulseManager().clear(); - p.getInterfaceManager().open(new Component(499)); - setVarp(p, 965, config.getConfig()); - p.getAttributes().put("skillMenu", config.getConfig()); - } - } else { - if (config.getSkillId() > 6) { - p.getPacketDispatch().sendMessage("You cannot set a target level for this skill."); - return false; - } - if (p.canSpawn()) { - p.sendMessage("You must be inside Edgeville bank to set levels."); - return false; - } - } - return true; - } - - /** - * Holds all the config values of the skill advances. - */ - public static final int[] ADVANCE_CONFIGS = { - 9, 40, 17, 49, - 25, 57, 33, 641, - 659, 664, 121, 649, - 89, 114, 107, 72, - 64, 80, 673, 680, - 99, 698, 689, 705, - }; - - public enum SkillConfig { - ATTACK(125, 1, Skills.ATTACK), - STRENGTH(126, 2, Skills.STRENGTH), - DEFENCE(127, 5, Skills.DEFENCE), - RANGE(128, 3, Skills.RANGE), - PRAYER(129, 7, Skills.PRAYER), - MAGIC(130, 4, Skills.MAGIC), - RUNECRAFTING(131, 12, Skills.RUNECRAFTING), - HITPOINTS(133, 6, Skills.HITPOINTS), - AGILITY(134, 8, Skills.AGILITY), - HERBLORE(135, 9, Skills.HERBLORE), - THIEVING(136, 10, Skills.THIEVING), - CRAFTING(137, 11, Skills.CRAFTING), - FLETCHING(138, 19, Skills.FLETCHING), - SLAYER(139, 20, Skills.SLAYER), - MINING(141, 13, Skills.MINING), - SMITHING(142, 14, Skills.SMITHING), - FISHING(143, 15, Skills.FISHING), - COOKING(144, 16, Skills.COOKING), - FIREMAKING(145, 17, Skills.FIREMAKING), - WOODCUTTING(146, 18, Skills.WOODCUTTING), - FARMING(147, 21, Skills.FARMING), - CONSTRUCTION(132, 22, Skills.CONSTRUCTION), - HUNTER(140, 23, Skills.HUNTER), - SUMMONING(148, 24, Skills.SUMMONING); - - /** - * Constructs a new {@code SkillConfig} {@code Object}. - * @param button the button. - * @param config the config. - */ - SkillConfig(int button, int config, int skillId) { - this.button = button; - this.config = config; - this.skillId = skillId; - } - - /** - * Represents the button. - */ - private int button; - - /** - * Represents the config. - */ - private int config; - - /** - * The skill id. - */ - private int skillId; - - /** - * Gets the skill config. - * @param id the id. - * @return the skill config. - */ - public static SkillConfig forId(int id) { - for (SkillConfig config : SkillConfig.values()) { - if (config.button == id) - return config; - } - return null; - } - - /** - * Gets the button. - * @return the button. - */ - public int getButton() { - return button; - } - - /** - * Gets the config. - * @return the config. - */ - public int getConfig() { - return config; - } - - /** - * Gets the skill id. - * @return The skill id. - */ - public int getSkillId() { - return skillId; - } - } -} diff --git a/Server/src/main/content/global/handlers/iface/TanningInterface.java b/Server/src/main/content/global/handlers/iface/TanningInterface.java deleted file mode 100644 index aa15e4b11..000000000 --- a/Server/src/main/content/global/handlers/iface/TanningInterface.java +++ /dev/null @@ -1,90 +0,0 @@ -package content.global.handlers.iface; - -import static core.api.ContentAPIKt.*; -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import content.global.skill.crafting.TanningProduct; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; -import kotlin.Unit; - -/** - * @author Vexia - * @version 1.2 - */ -@Initializable -public class TanningInterface extends ComponentPlugin { - - /** - * Method used to create a new instance. - * @param arg - * @return - * @throws Throwable - */ - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(324, this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - TanningProduct def = null; - switch (button) { - case 1: - def = TanningProduct.SOFT_LEATHER; - break; - case 2: - def = TanningProduct.HARD_LEATHER; - break; - case 3: - def = TanningProduct.SNAKESKIN; - break; - case 4: - def = TanningProduct.SNAKESKIN2; - break; - case 5: - def = TanningProduct.GREEN_DHIDE; - break; - case 6: - def = TanningProduct.BLUEDHIDE; - break; - case 7: - def = TanningProduct.REDDHIDE; - break; - case 8: - def = TanningProduct.BLACKDHIDE; - break; - } - if (def == null) { - return true; - } - int amount = 0; - final TanningProduct deff = def; - switch (opcode){ - case 155: - amount = 1; - break; - case 196: - amount = 5; - break; - case 124: - amount = 10; - case 199: - sendInputDialogue(player, true, "Enter the amount:", (value) -> { - TanningProduct.tan(player, (int) value, deff); - return Unit.INSTANCE; - }); - break; - case 234: - amount = player.getInventory().getAmount(new Item(def.getItem(), 1)); - break; - } - TanningProduct.tan(player, amount, def); - return true; - } - -} diff --git a/Server/src/main/content/global/handlers/iface/TanningInterface.kt b/Server/src/main/content/global/handlers/iface/TanningInterface.kt new file mode 100644 index 000000000..278e991bf --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/TanningInterface.kt @@ -0,0 +1,25 @@ +package content.global.handlers.iface + +import content.global.skill.crafting.TanningProduct +import core.api.amountInInventory +import core.api.sendInputDialogue +import core.game.interaction.InterfaceListener + +class TanningInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(324) { player, _, opcode, buttonID, _, _ -> + val product = TanningProduct.forId(buttonID) + + when (opcode) { + 155 -> TanningProduct.tan(player, 1, product) + 196 -> TanningProduct.tan(player, 5, product) + 124 -> TanningProduct.tan(player, 10, product) + 199 -> sendInputDialogue(player, true, "Enter the amount:") { value -> + TanningProduct.tan(player, value as Int, product) + } + 234 -> TanningProduct.tan(player, amountInInventory(player, product.item), product) + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt b/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt index 4c98f7e0b..feb6cc5c0 100644 --- a/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt +++ b/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt @@ -127,7 +127,7 @@ private const val F_FLARES = 72 private const val F_PLAIN_TROUSERS = 70 private const val F_SHORTS = 77 -private val femaleLegIDs = intArrayOf(F_FINE_SKIRT, F_FRILLED_SKIRT, F_LAYERED_SKIRT, F_LONG_NARROW_SKIRT, F_RAGGED_SKIRT, F_TATTERED_SKIRT, F_SHORT_SKIRT, F_SASHED_SKIRT, F_FITTED_SKIRT, F_TORN_TROUSERS, F_LONG_SKIRT, F_TURN_UPS, F_FLARES, F_FLARES, F_PLAIN_TROUSERS, F_SHORTS) +private val femaleLegIDs = intArrayOf(F_FINE_SKIRT, F_FRILLED_SKIRT, F_LAYERED_SKIRT, F_LONG_NARROW_SKIRT, F_RAGGED_SKIRT, F_TATTERED_SKIRT, F_SHORT_SKIRT, F_SASHED_SKIRT, F_FITTED_SKIRT, F_TORN_TROUSERS, F_LONG_SKIRT, F_TURN_UPS, F_FLARES, F_PLAIN_TROUSERS, F_SHORTS) private val COINS = Item(995,1000) diff --git a/Server/src/main/content/global/handlers/iface/WorldMapInterface.java b/Server/src/main/content/global/handlers/iface/WorldMapInterface.java deleted file mode 100644 index 113c28bfa..000000000 --- a/Server/src/main/content/global/handlers/iface/WorldMapInterface.java +++ /dev/null @@ -1,39 +0,0 @@ -package content.global.handlers.iface; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles the world map interface. - * @author Emperor - * - */ -@Initializable -public final class WorldMapInterface extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.forId(755).setPlugin(this); - return this; - } - - //Thanks snicker! - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - switch (button) { - case 3: - player.getInterfaceManager().openWindowsPane(new Component(player.getInterfaceManager().isResizable() ? 746 : 548), 2); - player.getPacketDispatch().sendRunScript(1187, "ii", 0, 0); - player.updateSceneGraph(true); - return true; - default: - //log(this.getClass(), Log.ERR, "World map: buttonid: " + button + ", opcode: " + opcode + ", slot: " + slot); - return true; - } - } - -} diff --git a/Server/src/main/content/global/handlers/iface/WorldMapInterface.kt b/Server/src/main/content/global/handlers/iface/WorldMapInterface.kt new file mode 100644 index 000000000..cd1fc427b --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/WorldMapInterface.kt @@ -0,0 +1,23 @@ +package content.global.handlers.iface + +import core.game.component.Component +import core.game.interaction.InterfaceListener +import org.rs09.consts.Components + +class WorldMapInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.WORLDMAP_755) { player, _, _, button, _, _ -> + if (button == 3) { + val paneId = if (player.interfaceManager.isResizable) { + Components.TOPLEVEL_FULLSCREEN_746 + } else { + Components.TOPLEVEL_548 + } + player.interfaceManager.openWindowsPane(Component(paneId), 2) + player.packetDispatch.sendRunScript(1187, "ii", 0, 0) + player.updateSceneGraph(true) + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt b/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt index 49d613f43..d6d0bd1cc 100644 --- a/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt +++ b/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt @@ -1,15 +1,15 @@ package content.global.handlers.iface.bank +import content.global.dialogue.BankDepositDialogue +import content.global.dialogue.BankHelpDialogue +import core.ServerConstants import core.api.* import core.game.component.Component import core.game.container.Container +import core.game.interaction.InterfaceListener import core.game.node.entity.player.Player import org.rs09.consts.Components import org.rs09.consts.Items -import core.ServerConstants -import content.global.dialogue.BankDepositDialogue -import content.global.dialogue.BankHelpDialogue -import core.game.interaction.InterfaceListener /** * Allows the user to interact with the Bank Interface. @@ -58,8 +58,6 @@ class BankInterface : InterfaceListener { } private fun onBankInterfaceOpen(player: Player, component: Component): Boolean { - player.bank.sendBankSpace() - val settings = IfaceSettingsBuilder() .enableAllOptions() .enableSlotSwitch() @@ -74,14 +72,12 @@ class BankInterface : InterfaceListener { ServerConstants.BANK_SIZE ) + resetSearch(player) return false } private fun handleTabInteraction(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { - if (getAttribute(player, "search", false)) { - player.bank.reopen() - } - + resetSearch(player) val clickedTabIndex = -((buttonID - 41) / 2) when (opcode) { @@ -102,36 +98,16 @@ class BankInterface : InterfaceListener { private fun handleBankMenu(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { val item = player.bank.get(slot) ?: return true + resetSearch(player) when (opcode) { - OP_AMOUNT_ONE -> runWorldTask { player.bank.takeItem(slot, 1) } - OP_AMOUNT_FIVE -> runWorldTask { player.bank.takeItem(slot, 5) } - OP_AMOUNT_TEN -> runWorldTask { player.bank.takeItem(slot, 10) } - OP_AMOUNT_LAST_X -> runWorldTask { - player.bank.takeItem( - slot, - player.bank.lastAmountX - ) - } - OP_AMOUNT_X -> runWorldTask { - BankUtils.transferX( - player, - slot, - true - ) - } - OP_AMOUNT_ALL -> runWorldTask { - player.bank.takeItem( - slot, - player.bank.getAmount(item) - ) - } - OP_AMOUNT_ALL_BUT_ONE -> runWorldTask { - player.bank.takeItem( - slot, - player.bank.getAmount(item) - 1 - ) - } + OP_AMOUNT_ONE -> player.bank.takeItem(slot, 1) + OP_AMOUNT_FIVE -> player.bank.takeItem(slot, 5) + OP_AMOUNT_TEN -> player.bank.takeItem(slot, 10) + OP_AMOUNT_LAST_X -> player.bank.takeItem(slot, player.bank.lastAmountX) + OP_AMOUNT_X -> BankUtils.transferX(player, slot, true) + OP_AMOUNT_ALL -> player.bank.takeItem(slot, player.bank.getAmount(item)) + OP_AMOUNT_ALL_BUT_ONE -> player.bank.takeItem(slot, player.bank.getAmount(item) - 1) OP_EXAMINE -> { var examineText = item.definition.examine val id = item.definition.id @@ -150,6 +126,7 @@ class BankInterface : InterfaceListener { private fun handleInventoryMenu(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { val item = player.inventory.get(slot) ?: return true + resetSearch(player) when (opcode) { OP_AMOUNT_ONE -> player.bank.addItem(slot, 1) @@ -211,4 +188,11 @@ class BankInterface : InterfaceListener { return false } + + private fun resetSearch (player: Player) + { + val lastTab = getAttribute(player, "bank:lasttab", 0) + player.bank.tabIndex = lastTab + setVarc(player, 190, 1) //re-enable "Search" right-click option on search button. + } } diff --git a/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java b/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java index 853808349..9b615b305 100644 --- a/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java +++ b/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java @@ -112,7 +112,7 @@ public class GrandExchangeInterface extends ComponentPlugin { GrandExchangeOffer offer; GrandExchangeRecords records = GrandExchangeRecords.getInstance(player); if (index > -1 && (offer = records.getOffer(records.getOfferRecords()[index])) != null) { - StockMarket.withdraw(player, offer, slot >> 1); + StockMarket.withdraw(player, offer, slot >> 1, opcode); } return true; } diff --git a/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt b/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt index dd1d345d3..eba0a2435 100644 --- a/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt +++ b/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt @@ -98,7 +98,7 @@ class StockMarket : InterfaceListener { 209,211 -> if (openedOffer == null){ SystemLogger.logGE("[WARN] Player tried to withdraw item with null openedOffer!") return@on false - } else withdraw(player, openedOffer, (button - 209) shr 1) + } else withdraw(player, openedOffer, (button - 209) shr 1, op) 190 -> confirmOffer(player, tempOffer, openedIndex).also { return@on true } 194 -> player.interfaceManager.openChatbox(Components.OBJDIALOG_389) 203 -> abortOffer(player, openedOffer) @@ -342,7 +342,7 @@ class StockMarket : InterfaceListener { } @JvmStatic - fun withdraw(player: Player, offer: GrandExchangeOffer, index: Int) + fun withdraw(player: Player, offer: GrandExchangeOffer, index: Int, op: Int) { val item = offer.withdraw[index] if(item == null) @@ -351,20 +351,32 @@ class StockMarket : InterfaceListener { return } - if(hasSpaceFor(player, item)) - { - addItem(player, item.id, item.amount) - } - else - { - val note = item.noteChange - if(note == -1 || !hasSpaceFor(player, Item(note, item.amount))) - { - playAudio(player, Sounds.GE_TRADE_ERROR_4039) - sendMessage(player, "You do not have enough room in your inventory.") - return + when (op) { + // withdraw notes + 155 -> { + val note = item.noteChange + if (note == -1) { + sendMessage(player, "This item cannot be noted") + return + } + if (hasSpaceFor(player, Item(note, item.amount))) { + addItem(player, note, item.amount) + } else { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You do not have enough room in your inventory.") + return + } + } + // withdraw items + 196 -> { + if (hasSpaceFor(player, item)) { + addItem(player, item.id, item.amount) + } else { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You do not have enough room in your inventory.") + return + } } - else addItem(player, note, item.amount) } offer.withdraw[index] = null diff --git a/Server/src/main/content/global/handlers/iface/tabs/ClanTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/ClanTabInterface.kt new file mode 100644 index 000000000..c46293f59 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/ClanTabInterface.kt @@ -0,0 +1,109 @@ +package content.global.handlers.iface.tabs + +import core.api.sendInputDialogue +import core.api.sendMessage +import core.game.interaction.InterfaceListener +import core.game.system.communication.ClanRank +import core.game.system.communication.ClanRepository +import core.net.amsc.MSPacketRepository +import core.net.amsc.WorldCommunicator +import core.tools.StringUtils +import org.rs09.consts.Components + +class ClanTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.CLANJOIN_589) { player, _, _, buttonID, _, _ -> + if (buttonID == 9) { + if (player.interfaceManager.opened != null) { + sendMessage(player, "Please close the interface you have open before using 'Clan Setup'") + } else { + ClanRepository.openSettings(player) + } + } + + if (buttonID == 14) { + player.communication.toggleLootshare(player) + } + return@on true + } + + on(Components.CLANSETUP_590) { player, _, opcode, buttonID, _, _ -> + val clan = ClanRepository.get(player.name, true) + + when (buttonID) { + 22 -> { + if (opcode == 155) { + sendInputDialogue(player, false, "Enter clan prefix:", ) { value -> + val clanName = StringUtils.formatDisplayName(value.toString()) + + if (WorldCommunicator.isEnabled()) { MSPacketRepository.sendClanRename(player, clanName) } + + if (clan.name == "Chat disabled") { + sendMessage(player, "Your clan channel has now been enabled!") + sendMessage(player, "Join your channel by clicking 'Join Chat' and typing: ${player.username}") + } + + clan.name = clanName + player.communication.clanName = clanName + clan.updateSettings(player) + clan.update() + } + } + + if (opcode == 196) { + clan.name = "Chat disabled" + player.communication.clanName = "" + if (WorldCommunicator.isEnabled()) { MSPacketRepository.sendClanRename(player, player.communication.clanName) } + clan.updateSettings(player) + clan.delete() + } + } + + 23 -> { + clan.joinRequirement = getRank(opcode) + player.communication.joinRequirement = clan.joinRequirement + MSPacketRepository.setClanSetting(player, 0, clan.joinRequirement) + } + + 24 -> { + clan.messageRequirement = getRank(opcode) + player.communication.messageRequirement = clan.messageRequirement + MSPacketRepository.setClanSetting(player, 1, clan.messageRequirement) + } + + 25 -> { + clan.kickRequirement = getRank(opcode) + player.communication.kickRequirement = clan.kickRequirement + MSPacketRepository.setClanSetting(player, 2, clan.kickRequirement) + } + + 26 -> { + clan.lootRequirement = if (opcode == 155) ClanRank.ADMINISTRATOR else getRank(opcode) + player.communication.lootRequirement = clan.lootRequirement + MSPacketRepository.setClanSetting(player, 3, clan.lootRequirement) + } + + 33 -> sendMessage(player, "CoinShare is not available.") + } + + clan.updateSettings(player) + clan.update() + return@on true + } + } + + fun getRank(opcode: Int): ClanRank { + return when (opcode) { + 155 -> ClanRank.NONE + 196 -> ClanRank.FRIEND + 124 -> ClanRank.RECRUIT + 199 -> ClanRank.CORPORAL + 234 -> ClanRank.SERGEANT + 168 -> ClanRank.LIEUTENANT + 166 -> ClanRank.CAPTAIN + 64 -> ClanRank.GENERAL + 53 -> ClanRank.OWNER + else -> ClanRank.NONE + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/CombatTabInterface.java b/Server/src/main/content/global/handlers/iface/tabs/CombatTabInterface.java similarity index 98% rename from Server/src/main/content/global/handlers/iface/CombatTabInterface.java rename to Server/src/main/content/global/handlers/iface/tabs/CombatTabInterface.java index bd3938d5c..0ca513102 100644 --- a/Server/src/main/content/global/handlers/iface/CombatTabInterface.java +++ b/Server/src/main/content/global/handlers/iface/tabs/CombatTabInterface.java @@ -1,4 +1,4 @@ -package content.global.handlers.iface; +package content.global.handlers.iface.tabs; import core.game.component.Component; import core.game.component.ComponentDefinition; diff --git a/Server/src/main/content/global/handlers/iface/tabs/EmoteTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/EmoteTabInterface.kt new file mode 100644 index 000000000..db5efdd84 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/EmoteTabInterface.kt @@ -0,0 +1,14 @@ +package content.global.handlers.iface.tabs + +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.link.emote.Emotes +import org.rs09.consts.Components + +class EmoteTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.EMOTES_464) { player, _, _, buttonID, _, _ -> + Emotes.handle(player, buttonID) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/EquipmentTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/EquipmentTabInterface.kt new file mode 100644 index 000000000..e3dd69b0e --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/EquipmentTabInterface.kt @@ -0,0 +1,136 @@ +package content.global.handlers.iface.tabs + +import content.global.skill.summoning.familiar.BurdenBeast +import core.api.* + +import core.game.container.access.InterfaceContainer +import core.game.container.impl.EquipmentContainer +import core.game.global.action.EquipHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.interaction.InterfaceListener +import core.game.node.entity.combat.DeathTask +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.prayer.PrayerType +import core.tools.Log +import org.rs09.consts.Components +import org.rs09.consts.Items + +class EquipmentTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(ITEMS_KEPT_ON_DEATH_102) { player, component -> + /** + * (Highlight white items are auto destroyed on death Enum#616 (Items kept on death interface) TODO: Parse server sided + * CS2 Script 118 - Items kept on death interface + * Credit Woahscam for figuring this all out. + * @arg_0 (Int): Zone type - 0 Default/1 Safe/2 POH/3 Castle Wars/4 Trouble Brewing/5 Barbarian Assault + * @arg_1 (Int): Amount of items kept on death - 0/1/3/4 + * @arg_2 (Object): Item kept on death - slot 0 item id + * @arg_3 (Object): Item kept on death - slot 1 item id + * @arg_4 (Object): Item kept on death - slot 2 item id + * @arg_5 (Object): Item kept on death - slot 3 item id + * @arg_6 (Int): Player is skulled - 0 Not Skulled/1 Skulled + * @arg_7 (Int): Player has BoB summoned with items - 0 BoB not summoned or has no items /1 BoB summoned with items + * @arg_8 (String): String to append based on amount of items kept on death. + */ + val zoneType = player.zoneMonitor.type + val itemsKeptOnDeath = DeathTask.getContainers(player)[0] + val amountKeptOnDeath = if (!player.skullManager.isSkulled && itemsKeptOnDeath.itemCount() < 3) { + if (player.prayer[PrayerType.PROTECT_ITEMS]) 4 else 3 + } else { + itemsKeptOnDeath.itemCount() + } + val slot0 = itemsKeptOnDeath.getId(0) + val slot1 = itemsKeptOnDeath.getId(1) + val slot2 = itemsKeptOnDeath.getId(2) + val slot3 = itemsKeptOnDeath.getId(3) + val hasSkull = if (player.skullManager.isSkulled) 1 else 0 + val beast: BurdenBeast? = if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast) player.familiarManager.familiar as BurdenBeast else null + val hasBob = if (beast != null && !beast.container.isEmpty) 1 else 0 + val message = "You are skulled." + val cs2Args = arrayOf(hasBob, hasSkull, slot3, slot2, slot1, slot0, amountKeptOnDeath, zoneType, message) + + if (amountKeptOnDeath > 4 && zoneType == 0) { + log(this::class.java, Log.ERR, "Items kept on death interface should not contain more than 4 items when not in a safe zone!") + } + + player.packetDispatch.sendRunScript(118, "siiooooii", *cs2Args) + + val settings = IfaceSettingsBuilder().enableAllOptions().build() + player.packetDispatch.sendIfaceSettings(settings, 18, component.id, 0, itemsKeptOnDeath.itemCount()) + player.packetDispatch.sendIfaceSettings(settings, 21, component.id, 0, DeathTask.getContainers(player)[1].itemCount()) + return@onOpen true + } + + on(Components.WORNITEMS_387) { player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + 28 -> { + if (opcode == 81) EquipHandler.unequip(player, slot, itemID) + if (opcode == 206) operateItem(player, slot) + } + 52 -> openInterface(player, ITEMS_KEPT_ON_DEATH_102) + 55 -> openInterface(player, Components.EQUIP_SCREEN2_667) + } + return@on true + } + + onOpen(Components.EQUIP_SCREEN2_667) { player, component -> + val settings = IfaceSettingsBuilder().enableAllOptions().build() + player.packetDispatch.sendIfaceSettings(settings, 14, component.id, 0, 13) + EquipmentContainer.update(player) + openSingleTab(player, Components.INVENTORY_WEAR2_670) + return@onOpen true + } + + on(Components.EQUIP_SCREEN2_667) { player, _, opcode, buttonID, slot, itemID -> + if (buttonID == 14) { + when (opcode) { + 9 -> sendMessage(player, player.equipment.get(slot).definition.examine) + 155 -> EquipHandler.unequip(player, slot, itemID) + 196 -> operateItem(player, slot) + } + } + return@on true + } + + onClose(Components.EQUIP_SCREEN2_667) { player, _ -> + closeTabInterface(player) + return@onClose true + } + + onOpen(Components.INVENTORY_WEAR2_670) { player, component -> + InterfaceContainer.generateItems(player, player.inventory.toArray(), arrayOf("Equip"), component.id, 0, 7, 4, 93) + return@onOpen true + } + + on(Components.INVENTORY_WEAR2_670) { player, _, opcode, _, slot, _ -> + if (opcode == 9) sendMessage(player, player.inventory.get(slot).definition.examine) + if (opcode == 155) equipItem(player, slot) + return@on true + } + } + + private fun equipItem(player: Player, slot: Int) { + val item = player.inventory.get(slot) ?: return + + if (item.definition.options.any { it in arrayOf("Equip", "Wield", "Wear") } || item.id == Items.BEER_1917) { + InteractionListeners.run(item.id, IntType.ITEM, "equip", player, item) + } else { + sendMessage(player, "You can't wear that.") + } + } + + private fun operateItem(player: Player, slot: Int) { + val item = player.equipment.get(slot) ?: return + + when { + InteractionListeners.run(item.id, IntType.ITEM, "operate", player, item) -> return + item.operateHandler?.handle(player, item, "operate") == true -> return + else -> sendMessage(player, "You can't operate that.") + } + } + + companion object { + private const val ITEMS_KEPT_ON_DEATH_102 = 102 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/LogoutTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/LogoutTabInterface.kt new file mode 100644 index 000000000..f40ccd4a6 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/LogoutTabInterface.kt @@ -0,0 +1,34 @@ +package content.global.handlers.iface.tabs + +import core.api.sendMessage +import core.game.interaction.InterfaceListener +import core.game.world.repository.Repository +import org.rs09.consts.Components + +class LogoutTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.LOGOUT_182) { player, _, _, buttonID, _, _ -> + if (buttonID == 6) { + return@on when { + !player.zoneMonitor.canLogout() -> true + + player.inCombat() -> { + sendMessage(player, "You can't log out until 10 seconds after the end of combat.") + true + } + + player.isTeleporting -> { + sendMessage(player, "Please finish your teleport before logging out.") + true + } + + else -> { + Repository.disconnectionQueue.add(player) + true + } + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/MagicTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/MagicTabInterface.kt new file mode 100644 index 000000000..5cdd88867 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/MagicTabInterface.kt @@ -0,0 +1,23 @@ +package content.global.handlers.iface.tabs + +import content.global.skill.magic.SpellListener +import content.global.skill.magic.SpellListeners +import core.api.getAttribute +import core.game.interaction.InterfaceListener +import core.game.node.entity.combat.spell.MagicSpell +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.world.GameWorld + +class MagicTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + SpellBook.values().forEach { + on(it.interfaceId) { player, _, _, buttonID, _, _ -> + if (GameWorld.ticks < getAttribute(player, "magic:delay", -1)) return@on true + + SpellListeners.run(buttonID, SpellListener.NONE, it.name.lowercase(), player) + + return@on MagicSpell.castSpell(player, it, buttonID, player) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/MusicTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/MusicTabInterface.kt new file mode 100644 index 000000000..76643299c --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/MusicTabInterface.kt @@ -0,0 +1,38 @@ +package content.global.handlers.iface.tabs + +import core.api.sendMessage +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.link.music.MusicEntry +import org.rs09.consts.Components + +class MusicTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.MUSIC_V3_187) { player, _, opcode, buttonID, slot, _ -> + if (opcode == 155) { + if (buttonID == 11) { + player.musicPlayer.toggleLooping() + return@on true + } + + if (buttonID == 1) { + if (player.musicPlayer.unlocked[slot] != null) { + player.musicPlayer.play(player.musicPlayer.unlocked[slot]) + return@on true + } + + if (player.isAdmin) { + for (entry in MusicEntry.getSongs().values) { + if (entry.index == slot) { + player.musicPlayer.unlock(entry.id) + } + } + } else { + sendMessage(player, "You have not unlocked this piece of music yet!") + } + return@on true + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/PrayerTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/PrayerTabInterface.kt new file mode 100644 index 000000000..684001eaa --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/PrayerTabInterface.kt @@ -0,0 +1,14 @@ +package content.global.handlers.iface.tabs + +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.link.prayer.PrayerType +import org.rs09.consts.Components + +class PrayerTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.PRAYER_271) { player, _, _, buttonID, _, _ -> + val prayer = PrayerType.get(buttonID) ?: return@on true + return@on player.prayer.toggle(prayer) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/QuestTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/QuestTabInterface.kt new file mode 100644 index 000000000..2a9703946 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/QuestTabInterface.kt @@ -0,0 +1,36 @@ +package content.global.handlers.iface.tabs + +import content.global.handlers.iface.tabs.QuestTabUtils.showRequirementsInterface +import core.api.openInterface +import core.game.component.Component +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.link.diary.DiaryType +import org.rs09.consts.Components + +class QuestTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.QUESTJOURNAL_V2_274) { player, _, _, buttonID, _, _ -> + if (buttonID == 3) { + player.achievementDiaryManager.openTab() + } else { + val quest = player.questRepository.forButtonId(buttonID) + if (quest != null) { + openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + quest.drawJournal(player, quest.getStage(player)) + } else { + showRequirementsInterface(player, buttonID) + } + } + return@on true + } + + on(Components.AREA_TASK_259) { player, _, _, buttonID, _, _ -> + if (buttonID == 8) { + player.interfaceManager.openTab(2, Component(Components.QUESTJOURNAL_V2_274)) + } else { + player.achievementDiaryManager.getDiary(DiaryType.forChild(buttonID))?.open(player) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/QuestTabUtils.kt b/Server/src/main/content/global/handlers/iface/tabs/QuestTabUtils.kt new file mode 100644 index 000000000..40e410348 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/QuestTabUtils.kt @@ -0,0 +1,245 @@ +package content.global.handlers.iface.tabs + +import core.game.requirement.* +import core.api.* +import core.tools.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills + +import kotlin.math.* +import java.util.* + +import org.rs09.consts.* +import content.data.Quests + +object QuestTabUtils { + @JvmStatic + fun showRequirementsInterface(player: Player, button: Int) { + val questName = getNameForButton(button) + val questReq = QuestRequirements.values().filter { it.quest.questName == questName }.firstOrNull() ?: return + var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player) + + var messageList = ArrayList() + + val statMap = HashMap() + val questList = HashSet() + var maxQpReq = 0 + var qpPenalty = 0 + closeInterface(player) + for (req in unmetReqs) { + if (req is QuestReq) + questList.add(req.questReq.quest.questName) + else if (req is SkillReq) { + if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level)) + statMap[req.skillId] = req.level + } + else if (req is QPReq && req.amount > maxQpReq) + maxQpReq = req.amount + else if (req is QPCumulative) + qpPenalty += req.amount + } + + messageList.add(colorize("%B[Quests Needed]")) + messageList.addAll(questList.map { "Completion of $it" }) + + messageList.add(" ") + messageList.add(colorize("%B[Skills Needed]")) + + for ((skillId, level) in statMap) { + val name = Skills.SKILL_NAME[skillId] + messageList.add("$level $name") + } + + messageList.add(" ") + messageList.add(colorize("%B[Other Reqs]")) + + val totalQpRequirement = QPReq(min(max(maxQpReq, qpPenalty), player.questRepository.getAvailablePoints())) + val (meetsQp, _) = totalQpRequirement.evaluate(player) + isMet = isMet && meetsQp + + if (isMet) + messageList.add(colorize("%GCongratulations! You've earned this one.")) + + if (!meetsQp) messageList.add("A total of ${totalQpRequirement.amount} Quest Points.") + + messageList.add("") + messageList.add(colorize("%BDISCLAIMER: If you're seeing this screen, this quest is not")) + messageList.add(colorize("%Bimplemented yet. These are the requirements that you need in order")) + messageList.add(colorize("%Bto access implemented content that would normally require this quest")) + messageList.add("") + messageList.add("If you want to see more quests enter the game, consider") + messageList.add("contributing dialogue transcripts!") + + + setInterfaceText(player, questName, Components.QUESTJOURNAL_SCROLL_275, 2) + var lineId = 11 + for(i in 0..299) { + val entry = messageList.elementAtOrNull(i) + if (entry != null) + setInterfaceText(player, entry, Components.QUESTJOURNAL_SCROLL_275, lineId++) + else + setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) + } + openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + } + + private fun getNameForButton(button: Int) : String { + val quest = when (button) { + 10 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName + 11 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName + 12 -> "Free Quests" + 13 -> Quests.BLACK_KNIGHTS_FORTRESS.questName + 14 -> Quests.COOKS_ASSISTANT.questName + 15 -> Quests.DEMON_SLAYER.questName + 16 -> Quests.DORICS_QUEST.questName + 17 -> Quests.DRAGON_SLAYER.questName + 18 -> Quests.ERNEST_THE_CHICKEN.questName + 19 -> Quests.GOBLIN_DIPLOMACY.questName + 20 -> Quests.IMP_CATCHER.questName + 21 -> Quests.THE_KNIGHTS_SWORD.questName + 22 -> Quests.PIRATES_TREASURE.questName + 23 -> Quests.PRINCE_ALI_RESCUE.questName + 24 -> Quests.THE_RESTLESS_GHOST.questName + 25 -> Quests.ROMEO_JULIET.questName + 26 -> Quests.RUNE_MYSTERIES.questName + 27 -> Quests.SHEEP_SHEARER.questName + 28 -> Quests.SHIELD_OF_ARRAV.questName + 29 -> Quests.VAMPIRE_SLAYER.questName + 30 -> Quests.WITCHS_POTION.questName + 31 -> "Members' Quests" + 32 -> Quests.ANIMAL_MAGNETISM.questName + 33 -> Quests.BETWEEN_A_ROCK.questName + 34 -> Quests.BIG_CHOMPY_BIRD_HUNTING.questName + 35 -> Quests.BIOHAZARD.questName + 36 -> Quests.CABIN_FEVER.questName + 37 -> Quests.CLOCK_TOWER.questName + 38 -> Quests.CONTACT.questName + 39 -> Quests.ZOGRE_FLESH_EATERS.questName + 40 -> Quests.CREATURE_OF_FENKENSTRAIN.questName + 41 -> Quests.DARKNESS_OF_HALLOWVALE.questName + 42 -> Quests.DEATH_TO_THE_DORGESHUUN.questName + 43 -> Quests.DEATH_PLATEAU.questName + 44 -> Quests.DESERT_TREASURE.questName + 45 -> Quests.DEVIOUS_MINDS.questName + 46 -> Quests.THE_DIG_SITE.questName + 47 -> Quests.DRUIDIC_RITUAL.questName + 48 -> Quests.DWARF_CANNON.questName + 49 -> Quests.EADGARS_RUSE.questName + 50 -> Quests.EAGLES_PEAK.questName + 51 -> Quests.ELEMENTAL_WORKSHOP_I.questName + 52 -> Quests.ELEMENTAL_WORKSHOP_II.questName + 53 -> Quests.ENAKHRAS_LAMENT.questName + 54 -> Quests.ENLIGHTENED_JOURNEY.questName + 55 -> Quests.THE_EYES_OF_GLOUPHRIE.questName + 56 -> Quests.FAIRYTALE_I_GROWING_PAINS.questName + 57 -> Quests.FAIRYTALE_II_CURE_A_QUEEN.questName + 58 -> Quests.FAMILY_CREST.questName + 59 -> Quests.THE_FEUD.questName + 60 -> Quests.FIGHT_ARENA.questName + 61 -> Quests.FISHING_CONTEST.questName + 62 -> Quests.FORGETTABLE_TALE.questName + 63 -> Quests.THE_FREMENNIK_TRIALS.questName + 64 -> Quests.WATERFALL_QUEST.questName + 65 -> Quests.GARDEN_OF_TRANQUILITY.questName + 66 -> Quests.GERTRUDES_CAT.questName + 67 -> Quests.GHOSTS_AHOY.questName + 68 -> Quests.THE_GIANT_DWARF.questName + 69 -> Quests.THE_GOLEM.questName + 70 -> Quests.THE_GRAND_TREE.questName + 71 -> Quests.THE_HAND_IN_THE_SAND.questName + 72 -> Quests.HAUNTED_MINE.questName + 73 -> Quests.HAZEEL_CULT.questName + 74 -> Quests.HEROES_QUEST.questName + 75 -> Quests.HOLY_GRAIL.questName + 76 -> Quests.HORROR_FROM_THE_DEEP.questName + 77 -> Quests.ICTHLARINS_LITTLE_HELPER.questName + 78 -> Quests.IN_AID_OF_THE_MYREQUE.questName + 79 -> Quests.IN_SEARCH_OF_THE_MYREQUE.questName + 80 -> Quests.JUNGLE_POTION.questName + 81 -> Quests.LEGENDS_QUEST.questName + 82 -> Quests.LOST_CITY.questName + 83 -> Quests.THE_LOST_TRIBE.questName + 84 -> Quests.LUNAR_DIPLOMACY.questName + 85 -> Quests.MAKING_HISTORY.questName + 86 -> Quests.MERLINS_CRYSTAL.questName + 87 -> Quests.MONKEY_MADNESS.questName + 88 -> Quests.MONKS_FRIEND.questName + 89 -> Quests.MOUNTAIN_DAUGHTER.questName + 90 -> Quests.MOURNINGS_END_PART_I.questName + 91 -> Quests.MOURNINGS_END_PART_II.questName + 92 -> Quests.MURDER_MYSTERY.questName + 93 -> Quests.MY_ARMS_BIG_ADVENTURE.questName + 94 -> Quests.NATURE_SPIRIT.questName + 95 -> Quests.OBSERVATORY_QUEST.questName + 96 -> Quests.ONE_SMALL_FAVOUR.questName + 97 -> Quests.PLAGUE_CITY.questName + 98 -> Quests.PRIEST_IN_PERIL.questName + 99 -> Quests.RAG_AND_BONE_MAN.questName + 100 -> Quests.RATCATCHERS.questName + 101 -> Quests.RECIPE_FOR_DISASTER.questName + 102 -> Quests.RECRUITMENT_DRIVE.questName + 103 -> Quests.REGICIDE.questName + 104 -> Quests.ROVING_ELVES.questName + 105 -> Quests.ROYAL_TROUBLE.questName + 106 -> Quests.RUM_DEAL.questName + 107 -> Quests.SCORPION_CATCHER.questName + 108 -> Quests.SEA_SLUG.questName + 109 -> Quests.THE_SLUG_MENACE.questName + 110 -> Quests.SHADES_OF_MORTTON.questName + 111 -> Quests.SHADOW_OF_THE_STORM.questName + 112 -> Quests.SHEEP_HERDER.questName + 113 -> Quests.SHILO_VILLAGE.questName + 114 -> Quests.A_SOULS_BANE.questName + 115 -> Quests.SPIRITS_OF_THE_ELID.questName + 116 -> Quests.SWAN_SONG.questName + 117 -> Quests.TAI_BWO_WANNAI_TRIO.questName + 118 -> Quests.A_TAIL_OF_TWO_CATS.questName + 119 -> Quests.TEARS_OF_GUTHIX.questName + 120 -> Quests.TEMPLE_OF_IKOV.questName + 121 -> Quests.THRONE_OF_MISCELLANIA.questName + 122 -> Quests.THE_TOURIST_TRAP.questName + 123 -> Quests.WITCHS_HOUSE.questName + 124 -> Quests.TREE_GNOME_VILLAGE.questName + 125 -> Quests.TRIBAL_TOTEM.questName + 126 -> Quests.TROLL_ROMANCE.questName + 127 -> Quests.TROLL_STRONGHOLD.questName + 128 -> Quests.UNDERGROUND_PASS.questName + 129 -> Quests.WANTED.questName + 130 -> Quests.WATCHTOWER.questName + 131 -> Quests.COLD_WAR.questName + 132 -> Quests.THE_FREMENNIK_ISLES.questName + 133 -> Quests.TOWER_OF_LIFE.questName + 134 -> Quests.THE_GREAT_BRAIN_ROBBERY.questName + 135 -> Quests.WHAT_LIES_BELOW.questName + 136 -> Quests.OLAFS_QUEST.questName + 137 -> Quests.ANOTHER_SLICE_OF_HAM.questName + 138 -> Quests.DREAM_MENTOR.questName + 139 -> Quests.GRIM_TALES.questName + 140 -> Quests.KINGS_RANSOM.questName + 141 -> Quests.THE_PATH_OF_GLOUPHRIE.questName + 142 -> Quests.BACK_TO_MY_ROOTS.questName + 143 -> Quests.LAND_OF_THE_GOBLINS.questName + 144 -> Quests.DEALING_WITH_SCABARAS.questName + 145 -> Quests.WOLF_WHISTLE.questName + 146 -> Quests.AS_A_FIRST_RESORT.questName + 147 -> Quests.CATAPULT_CONSTRUCTION.questName + 148 -> Quests.KENNITHS_CONCERNS.questName + 149 -> Quests.LEGACY_OF_SEERGAZE.questName + 150 -> Quests.PERILS_OF_ICE_MOUNTAIN.questName + 151 -> Quests.TOKTZ_KET_DILL.questName + 152 -> Quests.SMOKING_KILLS.questName + 153 -> Quests.ROCKING_OUT.questName + 154 -> Quests.SPIRIT_OF_SUMMER.questName + 155 -> Quests.MEETING_HISTORY.questName + 156 -> Quests.ALL_FIRED_UP.questName + 157 -> Quests.SUMMERS_END.questName + 158 -> Quests.DEFENDER_OF_VARROCK.questName + 159 -> Quests.SWEPT_AWAY.questName + 160 -> Quests.WHILE_GUTHIX_SLEEPS.questName + 161 -> Quests.IN_PYRE_NEED.questName + 162 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName + else -> "" + } + return quest as String + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/SettingsTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/SettingsTabInterface.kt new file mode 100644 index 000000000..29a1669e9 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/SettingsTabInterface.kt @@ -0,0 +1,35 @@ +package content.global.handlers.iface.tabs + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.link.IronmanMode +import org.rs09.consts.Components + +class SettingsTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.OPTIONS_261) { player, _, _, buttonID, _, _ -> + when (buttonID) { + RUN -> player.settings.toggleRun() + CHAT_EFFECTS -> player.settings.toggleChatEffects() + SPLIT_PM -> player.settings.toggleSplitPrivateChat() + MOUSE -> player.settings.toggleMouseButton() + AID -> restrictForIronman(player, IronmanMode.STANDARD) { player.settings.toggleAcceptAid() } + HOUSE -> openSingleTab(player, Components.POH_HOUSE_OPTIONS_398) + GRAPHICS -> openInterface(player, Components.GRAPHICS_OPTIONS_742) + AUDIO -> openInterface(player, Components.SOUND_OPTIONS_743) + } + return@on true + } + } + + companion object { + const val RUN = 3 + const val CHAT_EFFECTS = 4 + const val SPLIT_PM = 5 + const val MOUSE = 6 + const val AID = 7 + const val HOUSE = 8 + const val GRAPHICS = 16 + const val AUDIO = 18 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/tabs/StatsTabInterface.kt b/Server/src/main/content/global/handlers/iface/tabs/StatsTabInterface.kt new file mode 100644 index 000000000..fbe1effc4 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/tabs/StatsTabInterface.kt @@ -0,0 +1,87 @@ +package content.global.handlers.iface.tabs + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.skill.LevelUp +import core.game.node.entity.skill.Skills +import org.rs09.consts.Components + + +class StatsTabInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.STATS_320) { player, _, _, buttonID, _, _ -> + val config = skillMap[buttonID] ?: return@on true + + if (getAttribute(player, "levelup:${config.skillID}", false)) { + removeAttributes(player, "levelup:${config.skillID}") + LevelUp.sendFlashingIcons(player, -1) + setVarp(player, 1230, ADVANCE_CONFIGS[config.skillID]) + openInterface(player, 741) + } else { + openInterface(player, Components.SKILL_GUIDE_V2_499) + setVarp(player, 965, config.configID) + setAttribute(player, "skillMenu", config.configID) + } + return@on true + } + + on(Components.SKILL_GUIDE_V2_499) { player, _, _, buttonID, _, _ -> + setVarbit(player, 3288, getAttribute(player, "skillMenu", -1)) + setVarbit(player, 3289, buttonID - 10) + return@on true + } + + on(LEVEL_UP_INTERFACE_740) { player, component, opcode, buttonID, slot, itemID -> + if (buttonID == 3) { + closeInterface(player) + } + return@on true + } + } + + enum class SkillConfig(val buttonID: Int, val configID: Int, val skillID: Int) { + ATTACK(125, 1, Skills.ATTACK), + STRENGTH(126, 2, Skills.STRENGTH), + DEFENCE(127, 5, Skills.DEFENCE), + RANGE(128, 3, Skills.RANGE), + PRAYER(129, 7, Skills.PRAYER), + MAGIC(130, 4, Skills.MAGIC), + RUNECRAFT(131, 12, Skills.RUNECRAFTING), + HITPOINTS(133, 6, Skills.HITPOINTS), + AGILITY(134, 8, Skills.AGILITY), + HERBLORE(135, 9, Skills.HERBLORE), + THIEVING(136, 10, Skills.THIEVING), + CRAFTING(137, 11, Skills.CRAFTING), + FLETCHING(138, 19, Skills.FLETCHING), + SLAYER(139, 20, Skills.SLAYER), + MINING(141, 13, Skills.MINING), + SMITHING(142, 14, Skills.SMITHING), + FISHING(143, 15, Skills.FISHING), + COOKING(144, 16, Skills.COOKING), + FIREMAKING(145, 17, Skills.FIREMAKING), + WOODCUTTING(146, 18, Skills.WOODCUTTING), + FARMING(147, 21, Skills.FARMING), + CONSTRUCTION(132, 22, Skills.CONSTRUCTION), + HUNTER(140, 23, Skills.HUNTER), + SUMMONING(148, 24, Skills.SUMMONING), + } + + companion object { + private const val LEVEL_UP_INTERFACE_740 = 740 + val skillMap= HashMap() + val ADVANCE_CONFIGS = intArrayOf( + 9, 40, 17, 49, + 25, 57, 33, 641, + 659, 664, 121, 649, + 89, 114, 107, 72, + 64, 80, 673, 680, + 99, 698, 689, 705 + ) + + init { + for (skill in SkillConfig.values()) { + skillMap[skill.buttonID] = skill + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/EctophialListener.kt b/Server/src/main/content/global/handlers/item/EctophialListener.kt index 661d0d942..a3ab4d0ca 100644 --- a/Server/src/main/content/global/handlers/item/EctophialListener.kt +++ b/Server/src/main/content/global/handlers/item/EctophialListener.kt @@ -13,6 +13,7 @@ import core.game.world.update.flag.context.Graphics import org.rs09.consts.Items import org.rs09.consts.Scenery import org.rs09.consts.Sounds +import content.data.Quests @Suppress("unused") class EctophialListener : InteractionListener { @@ -24,8 +25,7 @@ class EctophialListener : InteractionListener { delayEntity(player, fillAnimation.duration) animate(player, fillAnimation) playAudio(player, Sounds.FILL_ECTOPLASM_1132) - if (removeItem(player, Items.ECTOPHIAL_4252)) { - addItem(player, Items.ECTOPHIAL_4251) + if (removeItem(player, Items.ECTOPHIAL_4252) && addItem(player, Items.ECTOPHIAL_4251)) { sendMessage(player, "You refill the ectophial from the Ectofuntus.") } } @@ -37,7 +37,7 @@ class EctophialListener : InteractionListener { } on(Items.ECTOPHIAL_4251, IntType.ITEM, "empty") { player, node -> - if (!hasRequirement(player, "Ghosts Ahoy")) + if (!hasRequirement(player, Quests.GHOSTS_AHOY)) return@on true if (player.isTeleBlocked) { @@ -45,28 +45,29 @@ class EctophialListener : InteractionListener { return@on true } delayEntity(player, 10) - queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> - when (stage) { - 0 -> { - sendMessage(player, "You empty the ectoplasm onto the ground around your feet...") - playAudio(player, 4580) - visualize(player, emptyAnimation, emptyGraphics) - replaceSlot(player, node.asItem().slot, Item(Items.ECTOPHIAL_4252), Item(Items.ECTOPHIAL_4251)) - return@queueScript delayScript(player, emptyAnimation.duration) - } - 1 -> { - teleport(player, Location.create(3658, 3517, 0), TeleportType.ECTOPHIAL) - sendMessage(player, "...and the world changes around you.") - return@queueScript delayScript(player, 9) - } - 2 -> { - face(player, Location(3659, 3519, 0)) - refillEctophial(player) - return@queueScript stopExecuting(player) - } - else -> return@queueScript stopExecuting(player) + closeAllInterfaces(player) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You empty the ectoplasm onto the ground around your feet...") + playAudio(player, 4580) + visualize(player, emptyAnimation, emptyGraphics) + replaceSlot(player, node.asItem().slot, Item(Items.ECTOPHIAL_4252), Item(Items.ECTOPHIAL_4251)) + return@queueScript delayScript(player, emptyAnimation.duration) } + 1 -> { + teleport(player, Location.create(3658, 3517, 0), TeleportType.ECTOPHIAL) + sendMessage(player, "...and the world changes around you.") + return@queueScript delayScript(player, 9) + } + 2 -> { + face(player, Location(3659, 3519, 0)) + refillEctophial(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) } + } return@on true } } diff --git a/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt index 12771ec0b..71239cc7c 100644 --- a/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt +++ b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt @@ -17,7 +17,7 @@ class EmptyOptionListener : InteractionListener { override fun defineListeners() { on(EmptyItem.emptyItemList.toIntArray(), IntType.ITEM, "empty", "empty bowl", "empty dish") { player, node -> - if (node.name.contains("brew") || node.name.contains("potion") || node.name.lowercase(Locale.getDefault()).contains("poison") || node.name.lowercase(Locale.getDefault()).contains("serum") || node.name.contains("cure") || node.name.contains("mix") || node.name.contains("balm")) { + if (node.name.contains("brew") || node.name.contains("potion") || node.name.lowercase(Locale.getDefault()).contains("poison") || node.name.lowercase(Locale.getDefault()).contains("serum") || node.name.contains("cure") || node.name.contains("mix") || node.name.contains("balm") || node.name.contains("Super ")) { replaceSlot(player, node.asItem().slot, Item(EmptyItem.getEmpty(Items.POTION_195)!!), node.asItem()) playAudio(player, EmptyItem.getEmptyAudio(Items.POTION_195)!!) return@on true @@ -41,15 +41,41 @@ class EmptyOptionListener : InteractionListener { BUCKET_OF_COMPOST(Items.COMPOST_6032, Items.BUCKET_1925, "You empty the bucket of compost."), BUCKET_OF_SUPERCOMPOST(Items.SUPERCOMPOST_6034, Items.BUCKET_1925, "You empty the bucket of supercompost."), BUCKET_OF_SLIME(Items.BUCKET_OF_SLIME_4286, Items.BUCKET_1925, "You empty the contents of the bucket on the floor.", Sounds.LIQUID_2401), + APPLE_MUSH(Items.APPLE_MUSH_5992,Items.BUCKET_1925, "You empty the bucket of apple mush."), VIAL_OF_WATER(Items.VIAL_OF_WATER_227, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401), BOWL_OF_WATER(Items.BOWL_OF_WATER_1921, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + BOWL_OF_HOT_WATER(Items.BOWL_OF_HOT_WATER_4456, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), JUG_OF_WATER(Items.JUG_OF_WATER_1937, Items.JUG_1935, "You empty the contents of the jug onto the floor.", Sounds.LIQUID_2401), BURNT_PIE(Items.BURNT_PIE_2329, Items.PIE_DISH_2313, "You empty the pie dish."), POTION(Items.POTION_195, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401), BURNT_STEW(Items.BURNT_STEW_2005, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), NETTLE_TEA(Items.NETTLE_TEA_4239, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA_CUP(Items.CUP_OF_TEA_4242, Items.EMPTY_CUP_1980, "You empty the cup of tea.", Sounds.LIQUID_2401), + NETTLE_TEA_CUP_MILKY(Items.CUP_OF_TEA_4243, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA_PORCELAIN(Items.CUP_OF_TEA_4245, Items.PORCELAIN_CUP_4244, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA_PORCELAIN_MILKY(Items.CUP_OF_TEA_4246, Items.PORCELAIN_CUP_4244, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), NETTLE_WATER(Items.NETTLE_WATER_4237, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), NETTLE_TEA_MILKY(Items.NETTLE_TEA_4240, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + TEA_CUP_WATER(Items.CUP_OF_WATER_4458, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + TEA_CUP_HOT_WATER(Items.CUP_OF_HOT_WATER_4460, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + BUILDERS_TEA1(Items.CUP_OF_TEA_7730, Items.EMPTY_CUP_7728, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + BUILDERS_TEA1_MILKY(Items.CUP_OF_TEA_7731, Items.EMPTY_CUP_7728, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + BUILDERS_TEA2(Items.CUP_OF_TEA_7733, Items.PORCELAIN_CUP_7732, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + BUILDERS_TEA2_MILKY(Items.CUP_OF_TEA_7734, Items.PORCELAIN_CUP_7732, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + BUILDERS_TEA3(Items.CUP_OF_TEA_7736, Items.PORCELAIN_CUP_7735, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + BUILDERS_TEA3_MILKY(Items.CUP_OF_TEA_7737, Items.PORCELAIN_CUP_7735, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401), + CLAY_POT_OF_TEA4(Items.POT_OF_TEA_4_7692, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + CLAY_POT_OF_TEA3(Items.POT_OF_TEA_3_7694, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + CLAY_POT_OF_TEA2(Items.POT_OF_TEA_2_7696, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + CLAY_POT_OF_TEA1(Items.POT_OF_TEA_1_7698, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + PORCELAIN_POT_OF_TEA4(Items.POT_OF_TEA_4_7704, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + PORCELAIN_POT_OF_TEA3(Items.POT_OF_TEA_3_7706, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + PORCELAIN_POT_OF_TEA2(Items.POT_OF_TEA_2_7708, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + PORCELAIN_POT_OF_TEA1(Items.POT_OF_TEA_1_7710, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + GOLD_PORCELAIN_POT_OF_TEA4(Items.POT_OF_TEA_4_7716, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + GOLD_PORCELAIN_POT_OF_TEA3(Items.POT_OF_TEA_3_7718, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + GOLD_PORCELAIN_POT_OF_TEA2(Items.POT_OF_TEA_2_7720, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), + GOLD_PORCELAIN_POT_OF_TEA1(Items.POT_OF_TEA_1_7722, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401), BURNT_CURRY(Items.BURNT_CURRY_2013, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), BURNT_GNOMEBOWL(Items.BURNT_GNOMEBOWL_2175, Items.GNOMEBOWL_MOULD_2166, "You empty the contents of the gnomebowl onto the floor."), BURNT_EGG(Items.BURNT_EGG_7090, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."), @@ -70,7 +96,7 @@ class EmptyOptionListener : InteractionListener { emptyItemList.add(item.fullId) } for (item in ItemDefinition.getDefinitions().values) - if (item.name.contains("potion") || item.name.contains("brew") || item.name.contains("poison") || item.name.lowercase(Locale.getDefault()).contains("serum") || item.name.contains("cure") || item.name.contains("mix") || item.name.contains("balm")) { + if (item.name.contains("potion") || item.name.contains("brew") || item.name.contains("poison") || item.name.lowercase(Locale.getDefault()).contains("serum") || item.name.contains("cure") || item.name.contains("mix") || item.name.contains("balm") || item.name.contains("Super ")) { emptyItemList.add(item.id) } } diff --git a/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt b/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt index 8cea16326..c642372ff 100644 --- a/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt +++ b/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt @@ -1,85 +1,94 @@ package content.global.handlers.item +import core.ServerConstants import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.interaction.QueueStrength +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Animations import org.rs09.consts.Items import org.rs09.consts.Sounds class EnchantJewelleryTabListener : InteractionListener { - private val LVL_1_ENCHANT = mapOf( - Items.SAPPHIRE_RING_1637 to Items.RING_OF_RECOIL_2550, - Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853, - Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727, - Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074 + Items.SAPPHIRE_RING_1637 to Items.RING_OF_RECOIL_2550, + Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853, + Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727, + Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074 ) private val LVL_2_ENCHANT = mapOf( - Items.EMERALD_RING_1639 to Items.RING_OF_DUELLING8_2552, - Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521, - Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729, - Items.EMERALD_BRACELET_11076 to Items.CASTLEWAR_BRACE3_11079 + Items.EMERALD_RING_1639 to Items.RING_OF_DUELLING8_2552, + Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521, + Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729, + Items.EMERALD_BRACELET_11076 to Items.CASTLEWAR_BRACE3_11079 ) - private val LVL_3_ENCHANT = mapOf( - Items.RUBY_RING_1641 to Items.RING_OF_FORGING_2568, - Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194, - Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725, - Items.RUBY_BRACELET_11085 to Items.INOCULATION_BRACE_11088 + Items.RUBY_RING_1641 to Items.RING_OF_FORGING_2568, + Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194, + Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725, + Items.RUBY_BRACELET_11085 to Items.INOCULATION_BRACE_11088 ) - private val LVL_4_ENCHANT = mapOf( - Items.DIAMOND_RING_1643 to Items.RING_OF_LIFE_2570, - Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090, - Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731, - Items.DIAMOND_BRACELET_11092 to Items.FORINTHRY_BRACE5_11095 + Items.DIAMOND_RING_1643 to Items.RING_OF_LIFE_2570, + Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090, + Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731, + Items.DIAMOND_BRACELET_11092 to Items.FORINTHRY_BRACE5_11095 ) - private val LVL_5_ENCHANT = mapOf( - Items.DRAGONSTONE_RING_1645 to Items.RING_OF_WEALTH4_14646, - Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE4_11105, - Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY4_1712, - Items.DRAGON_BRACELET_11115 to Items.COMBAT_BRACELET4_11118 + Items.DRAGONSTONE_RING_1645 to Items.RING_OF_WEALTH_2572, + Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE_11113, + Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY_1704, + Items.DRAGON_BRACELET_11115 to Items.COMBAT_BRACELET_11126 ) - private val LVL_6_ENCHANT = mapOf( - Items.ONYX_RING_6575 to Items.RING_OF_STONE_6583, - Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128, - Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585, - Items.ONYX_BRACELET_11130 to Items.REGEN_BRACELET_11133 + Items.ONYX_RING_6575 to Items.RING_OF_STONE_6583, + Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128, + Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585, + Items.ONYX_BRACELET_11130 to Items.REGEN_BRACELET_11133 + ) + private val TAB_MAPPING = arrayOf( + Pair(Items.ENCHANT_SAPPHIRE_8016, LVL_1_ENCHANT), + Pair(Items.ENCHANT_EMERALD_8017, LVL_2_ENCHANT), + Pair(Items.ENCHANT_RUBY_8018, LVL_3_ENCHANT), + Pair(Items.ENCHANT_DIAMOND_8019, LVL_4_ENCHANT), + Pair(Items.ENCHANT_DRAGONSTN_8020, LVL_5_ENCHANT), + Pair(Items.ENCHANT_ONYX_8021, LVL_6_ENCHANT) ) override fun defineListeners() { - on(IntType.ITEM, "break") {player, node -> - delayEntity(player, 1) - queueScript(player, strength = QueueStrength.SOFT) { - - val items = when (node.id) { - 8016 -> LVL_1_ENCHANT //Sapphire - 8017 -> LVL_2_ENCHANT - 8018 -> LVL_3_ENCHANT - 8019 -> LVL_4_ENCHANT - 8020 -> LVL_5_ENCHANT - 8021 -> LVL_6_ENCHANT - else -> return@queueScript stopExecuting(player) - } - - if (inInventory(player, node.id)) { - for (item in player.inventory.toArray()) { - if (item == null) continue - val product = items[item.id] ?: continue - if (removeItem(player, node.id) && (removeItem(player, item.id))) { - addItem(player, product) - playAudio(player, Sounds.POH_TABLET_BREAK_979) - animate(player, 4069, true) - break + for ((tablet, mapping) in TAB_MAPPING) { + on(tablet, IntType.ITEM, "break") { player, _ -> + sendMessage(player, "Try using the tablet on the item instead.") //TODO authentic message + return@on true + } + for ((unenchanted, enchanted) in mapping) { + onUseWith(IntType.ITEM, tablet, unenchanted) { player, tabItem, node -> + var product = enchanted + if (product == Items.RING_OF_WEALTH_2572 && ServerConstants.RING_OF_WEALTH_TELEPORT) { + product = Items.RING_OF_WEALTH_14638 + } + if (removeItem(player, Item(tabItem.id))) { + closeAllInterfaces(player) + playAudio(player, Sounds.POH_TABLET_BREAK_979) + val anim = Animation(Animations.POH_TABLET_BREAK_4069) + animate(player, anim, true) + delayEntity(player, anim.duration) + queueScript(player, anim.duration, QueueStrength.SOFT) { + val item = node.asItem() + val ret = replaceSlot(player, item.slot, Item(product), item) + if (ret != item) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Unknown slot-replacement problem when enchanting jewellery (adding $product replaced $ret rather than $item)") + } + return@queueScript stopExecuting(player) } } + return@onUseWith true } - return@queueScript stopExecuting(player) } - return@on true - } - } + } + } } diff --git a/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt b/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt index 01d999e00..e376d2855 100644 --- a/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt +++ b/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt @@ -1,7 +1,7 @@ package content.global.handlers.item +import content.global.skill.slayer.SlayerUtils import core.api.* -import content.global.skill.slayer.Tasks import org.rs09.consts.Items import core.game.dialogue.DialogueFile import core.game.dialogue.IfTopic @@ -38,11 +38,7 @@ class EnchantedGemDialogue() : DialogueFile() { if(!hasSlayerTask(player!!)) { npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "You need something new to hunt. Come and see me when you can and I'll give you a new task.").also { stage = 1 } } else { - if(getSlayerTask(player!!) == Tasks.JAD) { - npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill TzTok-Jad!") - } else { - npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${getSlayerTaskName(player!!)}s; only ${getSlayerTaskKillsRemaining(player!!)} more to go.") - } + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player!!))}; only ${getSlayerTaskKillsRemaining(player!!)} more to go.") setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4) stage = 1 } diff --git a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt index 47947ec57..549b69051 100644 --- a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt +++ b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt @@ -11,10 +11,11 @@ import content.data.EnchantedJewellery import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.tools.START_DIALOGUE +import org.rs09.consts.Items /** * Listener for enchanted jewellery options - * @author Ceikry & downthecrop + * @author Ceikry, downthecrop, Player Name */ class EnchantedJewelleryListener : InteractionListener { @@ -33,6 +34,10 @@ class EnchantedJewelleryListener : InteractionListener { private fun handle(player: Player, node: Node, isEquipped: Boolean) { player.pulseManager.clear(PulseType.STANDARD) val item = node.asItem() + if (item.id == Items.RING_OF_LIFE_2570) { + sendMessage(player, "You can't operate that.") + return + } val jewellery = EnchantedJewellery.idMap[item.id] if (jewellery != null) { if (jewellery.isLastItemIndex(jewellery.getItemIndex(item)) && !jewellery.isCrumble) { @@ -45,19 +50,19 @@ class EnchantedJewelleryListener : InteractionListener { jewellery.use(player, item, 0, isEquipped) return } - openDialogue(player,EnchantedJewelleryDialogueFile(jewellery,item,isEquipped)) + openDialogue(player,EnchantedJewelleryDialogueFile(jewellery, item, true, isEquipped)) } } - class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val isEquipped: Boolean) : DialogueFile() { + class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val replace: Boolean, val isEquipped: Boolean) : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { when (stage) { START_DIALOGUE -> { - interpreter!!.sendOptions("Where would you like to go?", *jewellery.options) + interpreter!!.sendOptions("Where would you like to teleport to?", *jewellery.options) stage++ } 1 -> end().also { jewellery.use(player!!, item, buttonID - 1, isEquipped) } } } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt b/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt index aea9c4ba9..586967573 100644 --- a/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt +++ b/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt @@ -59,7 +59,7 @@ class ExplorersRingPlugin : InteractionListener { val item = player.inventory[slot] if (item == null) return@sendItemSelect - if (!ModernListeners().alchemize(player, item, false)) + if (!ModernListeners().alchemize(player, item, false, explorersRing = true)) return@sendItemSelect getStoreFile()[player.username.lowercase() + ":alchs"] = remaining - 1 } diff --git a/Server/src/main/content/global/handlers/item/GodBookListeners.kt b/Server/src/main/content/global/handlers/item/GodBookListeners.kt index 7e86ef581..764190e72 100644 --- a/Server/src/main/content/global/handlers/item/GodBookListeners.kt +++ b/Server/src/main/content/global/handlers/item/GodBookListeners.kt @@ -8,6 +8,9 @@ import org.rs09.consts.Items import core.game.dialogue.DialogueFile import core.game.interaction.InteractionListener import core.game.interaction.IntType +import core.game.node.Node +import core.game.node.entity.skill.Skills +import core.game.node.item.Item class GodBookListeners : InteractionListener { @@ -20,16 +23,42 @@ class GodBookListeners : InteractionListener { openDialogue(player, HOLY_DIALOGUE(BOOK.SARA)) return@on true } - on(GB_ZAMORAK, IntType.ITEM, "preach"){ player, _ -> openDialogue(player, HOLY_DIALOGUE(BOOK.ZAM)) return@on true } - on(GB_GUTHIX, IntType.ITEM, "preach"){ player, _ -> openDialogue(player, HOLY_DIALOGUE(BOOK.GUTHIX)) return@on true } + + fun bless(player: Player, node: Node, product: Int) { + if (player.skills.getStaticLevel(Skills.PRAYER) < 50) { + sendMessage(player, "You need a Prayer level of at least 50 in order to do this.") + } else if (player.skills.prayerPoints < 4) { + sendMessage(player, "You need at least 4 prayer points in order to do this.") + } else { + sendMessage(player, "You bless the ${node.asItem().name.lowercase()}.") + player.skills.decrementPrayerPoints(4.0) + replaceSlot(player, node.asItem().slot, Item(product), node.asItem()) + } + } + onUseWith(IntType.ITEM, GB_SARADOMIN, Items.UNBLESSED_SYMBOL_1716) { player, _, symbol -> + bless(player, symbol, Items.HOLY_SYMBOL_1718) + return@onUseWith true + } + onUseWith(IntType.ITEM, GB_ZAMORAK, Items.UNPOWERED_SYMBOL_1722) { player, _, symbol -> + bless(player, symbol, Items.UNHOLY_SYMBOL_1724) + return@onUseWith true + } + onUseWith(IntType.ITEM, GB_GUTHIX, Items.UNBLESSED_SYMBOL_1716) { player, _, symbol -> + bless(player, symbol, Items.HOLY_SYMBOL_1718) + return@onUseWith true + } + onUseWith(IntType.ITEM, GB_GUTHIX, Items.UNPOWERED_SYMBOL_1722) { player, _, symbol -> + bless(player, symbol, Items.UNHOLY_SYMBOL_1724) + return@onUseWith true + } } internal enum class BOOK { @@ -129,6 +158,5 @@ class GodBookListeners : InteractionListener { } }) } - } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/handlers/item/GodBookPlugin.java b/Server/src/main/content/global/handlers/item/GodBookPlugin.java index 6bdae37f1..9f955de41 100644 --- a/Server/src/main/content/global/handlers/item/GodBookPlugin.java +++ b/Server/src/main/content/global/handlers/item/GodBookPlugin.java @@ -27,7 +27,7 @@ public class GodBookPlugin extends OptionHandler { for (GodBook book : GodBook.values()) { book.getDamagedBook().getDefinition().getHandlers().put("option:check", this); } - ClassScanner.definePlugins(new PageHandler(), new GodBookItem(), new SymbolBlessHandler()); + ClassScanner.definePlugins(new PageHandler(), new GodBookItem()); return this; } @@ -51,77 +51,6 @@ public class GodBookPlugin extends OptionHandler { return true; } - /** - * Handles the blessing of a symbol with a god book. - * @author Vexia - */ - public class SymbolBlessHandler extends UseWithHandler { - - /** - * Constructs a new {@code SymbolBlessHandler} {@code Object} - */ - public SymbolBlessHandler() { - super(1716); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (GodBook book : GodBook.values()) { - addHandler(book.getBook().getId(), ITEM_TYPE, this); - } - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - Player player = event.getPlayer(); - GodBook book = GodBook.forItem(event.getUsedItem(), false); - if (book == null) { - return false; - } - final Item symbol = event.getUsedWith().asItem(); - if (player.getSkills().getLevel(Skills.PRAYER) < 50) { - player.sendMessage("You need a Prayer level of at least 50 in order to do this."); - return true; - } - if (player.getSkills().getPrayerPoints() < 4) { - player.sendMessage("You need at least 4 prayer points in order to do this."); - return true; - } - if (book == GodBook.BOOK_OF_BALANCE) { - player.getDialogueInterpreter().sendOptions("Select an Option", "Unholy symbol", "Holy symbol"); - player.getDialogueInterpreter().addAction(new DialogueAction() { - - @Override - public void handle(Player player, int buttonId) { - bless(player, symbol, buttonId == 1 ? GodBook.UNHOLY_BOOK : GodBook.HOLY_BOOK); - } - - }); - return true; - } - bless(player, symbol, book); - return true; - } - - /** - * Blesses a symbol. - * @param player the player. - * @param book the book. - */ - private void bless(Player player, Item symbol, GodBook book) { - if (!player.getInventory().containsItem(symbol)) { - return; - } - if (player.getInventory().get(symbol.getSlot()) == null) { - return; - } - player.getInventory().replace(book.getBlessItem()[0], symbol.getSlot()); - player.getSkills().decrementPrayerPoints(4); - } - - } - /** * A god book item. * @author Vexia diff --git a/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt b/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt index 087ce60e6..992d1009f 100644 --- a/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt +++ b/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt @@ -62,6 +62,7 @@ class GrandSeedPodHandler : InteractionListener { } if (opt == "squash") { + closeAllInterfaces(player) visualize(player, SQUASH_ANIM_BEGIN, SQUASH_GRAPHICS_BEGIN) delayEntity(player, 12) queueScript(player, 3, QueueStrength.SOFT) {stage: Int -> @@ -93,4 +94,4 @@ class GrandSeedPodHandler : InteractionListener { return@on true } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/handlers/item/ImplingJarListener.kt b/Server/src/main/content/global/handlers/item/ImplingJarListener.kt index 66158c78a..9fbd4060b 100644 --- a/Server/src/main/content/global/handlers/item/ImplingJarListener.kt +++ b/Server/src/main/content/global/handlers/item/ImplingJarListener.kt @@ -7,6 +7,7 @@ import core.api.utils.WeightBasedTable import core.api.utils.WeightedItem import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.global.activity.ttrail.TreasureTrailManager class ImplingJarListener : InteractionListener { @@ -15,8 +16,14 @@ class ImplingJarListener : InteractionListener { override fun defineListeners() { on(JARS, IntType.ITEM, "loot"){ player, node -> val jar = node.asItem() + val table = ImplingLoot.forId(jar.id) ?: return@on false + val effectiveTable = if (TreasureTrailManager.getInstance(player).hasClue()) { + table.excluding(*WeightBasedTable.CLUE_SCROLL_SLOTS) + } else { + table + } - val loot = ImplingLoot.forId(jar.id)?.roll()?.firstOrNull() ?: return@on false + val loot = effectiveTable.roll().firstOrNull() ?: return@on false if(removeItem(player, jar, Container.INVENTORY)) { addItemOrDrop(player, loot.id, loot.amount) diff --git a/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt b/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt index 4dd960bad..8acaa698a 100644 --- a/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt +++ b/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt @@ -4,6 +4,7 @@ import core.api.* import core.game.node.entity.player.link.quest.QuestRepository import org.rs09.consts.Items import core.game.interaction.InteractionListener +import content.data.Quests class ItemQuestRequirementListener : InteractionListener { @@ -106,7 +107,7 @@ class ItemQuestRequirementListener : InteractionListener { /* onEquip(fremennikIslesEquipment) { player, _ -> - if (!isQuestComplete(player, "Fremennik Isles")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_ISLES)) { sendMessage(player, "You must have completed The Fremennik Isles to equip this.") return@onEquip false } @@ -114,7 +115,7 @@ class ItemQuestRequirementListener : InteractionListener { } onEquip(fremennikIslesDuringQuestEquipment){ player, _ -> - if (questStage(player, "Fremennik Isles") > 0) { + if (questStage(player, Quests.THE_FREMENNIK_ISLES) > 0) { sendMessage(player, "You must have started The Fremennik Isles to equip this.") return@onEquip false } @@ -123,23 +124,23 @@ class ItemQuestRequirementListener : InteractionListener { */ onEquip(fremennikTrialsEquipment) { player, _ -> - return@onEquip hasRequirement(player, "Fremennik Trials") + return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_TRIALS) } onEquip(fremennikIslesEquipment) {player, _ -> - return@onEquip hasRequirement(player, "The Fremennik Isles") + return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_ISLES) } onEquip(avasBackpacks){ player, _ -> - return@onEquip hasRequirement(player, "Animal Magnetism") + return@onEquip hasRequirement(player, Quests.ANIMAL_MAGNETISM) } onEquip(lostCityWeapons){ player, _ -> - return@onEquip hasRequirement(player, "Lost City") + return@onEquip hasRequirement(player, Quests.LOST_CITY) } onEquip(Items.CAPE_OF_LEGENDS_1052) { player, _ -> - return@onEquip hasRequirement(player, "Legend's Quest") + return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST) } onEquip(questCapes) { player, _ -> @@ -152,84 +153,84 @@ class ItemQuestRequirementListener : InteractionListener { } onEquip(Items.WOLFBANE_2952){ player, _ -> - return@onEquip hasRequirement(player, "Priest in Peril") + return@onEquip hasRequirement(player, Quests.PRIEST_IN_PERIL) } onEquip(Items.ANCIENT_MACE_11061){ player, _ -> - return@onEquip hasRequirement(player, "Another Slice of H.A.M") + return@onEquip hasRequirement(player, Quests.ANOTHER_SLICE_OF_HAM) } onEquip(Items.ANCIENT_STAFF_4675){ player, _ -> - return@onEquip hasRequirement(player, "Desert Treasure") + return@onEquip hasRequirement(player, Quests.DESERT_TREASURE) } onEquip(Items.ELEMENTAL_SHIELD_2890) { player, _ -> - return@onEquip hasRequirement(player, "Elemental Workshop I") + return@onEquip hasRequirement(player, Quests.ELEMENTAL_WORKSHOP_I) } onEquip(crystalEquipment){ player, _ -> - return@onEquip hasRequirement(player, "Roving Elves") + return@onEquip hasRequirement(player, Quests.ROVING_ELVES) } onEquip(dragonSlayerEquipment) {player, _ -> - return@onEquip hasRequirement(player, "Dragon Slayer") + return@onEquip hasRequirement(player, Quests.DRAGON_SLAYER) } onEquip(Items.DRAGON_SCIMITAR_4587) {player, _ -> - return@onEquip hasRequirement(player, "Monkey Madness") + return@onEquip hasRequirement(player, Quests.MONKEY_MADNESS) } onEquip(Items.GLOVES_7462) {player, _ -> - return@onEquip hasRequirement(player, "Recipe for Disaster") + return@onEquip hasRequirement(player, Quests.RECIPE_FOR_DISASTER) } onEquip(Items.SLAYER_HELMET_13263) {player, _ -> - return@onEquip hasRequirement(player, "Smoking Kills") + return@onEquip hasRequirement(player, Quests.SMOKING_KILLS) } onEquip (Items.DRAGON_HALBERD_3204) {player, _ -> - return@onEquip hasRequirement(player, "Regicide") + return@onEquip hasRequirement(player, Quests.REGICIDE) } onEquip (Items.CLIMBING_BOOTS_3105) {player, _ -> - return@onEquip hasRequirement(player, "Death Plateau") + return@onEquip hasRequirement(player, Quests.DEATH_PLATEAU) } onEquip (godBooks) {player, _ -> - return@onEquip hasRequirement(player, "Horror from the Deep") + return@onEquip hasRequirement(player, Quests.HORROR_FROM_THE_DEEP) } onEquip (pharaohScepters) {player, _ -> - return@onEquip hasRequirement(player, "Icthlarin's Little Helper") + return@onEquip hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER) } onEquip (Items.DRAGON_SQ_SHIELD_1187) {player, _ -> //because I know people won't believe it: https://runescape.wiki/w/Dragon_sq_shield?oldid=899636 - return@onEquip hasRequirement(player, "Legend's Quest") + return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST) } onEquip (initiateArmour) {player, _ -> - return@onEquip hasRequirement(player, "Recruitment Drive") + return@onEquip hasRequirement(player, Quests.RECRUITMENT_DRIVE) } onEquip (proselyteArmour) {player, _ -> - return@onEquip hasRequirement(player, "The Slug Menace") + return@onEquip hasRequirement(player, Quests.THE_SLUG_MENACE) } onEquip (spiritShields) {player, _ -> - return@onEquip hasRequirement(player, "Summer's End") + return@onEquip hasRequirement(player, Quests.SUMMERS_END) } onEquip (Items.DRAGON_MACE_1434) {player, _ -> - return@onEquip hasRequirement(player, "Heroes' Quest") + return@onEquip hasRequirement(player, Quests.HEROES_QUEST) } onEquip (Items.DRAGON_BATTLEAXE_1377) {player, _ -> - return@onEquip hasRequirement(player, "Heroes' Quest") + return@onEquip hasRequirement(player, Quests.HEROES_QUEST) } onEquip (Items.DARKLIGHT_6746) {player, _ -> - return@onEquip hasRequirement(player, "Shadow of the Storm") + return@onEquip hasRequirement(player, Quests.SHADOW_OF_THE_STORM) } } } diff --git a/Server/src/main/content/global/handlers/item/LightSourceListeners.kt b/Server/src/main/content/global/handlers/item/LightSourceListeners.kt new file mode 100644 index 000000000..989746869 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/LightSourceListeners.kt @@ -0,0 +1,32 @@ +package content.global.handlers.item + +import content.data.LightSource +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Items +import kotlin.collections.toIntArray + +class LightSourceListeners : InteractionListener { + override fun defineListeners() { + val lightSourceProducts = LightSource.values().map { it.product.id }.toIntArray() + + on(lightSourceProducts, ITEM, "drop") { player, light -> + val active = LightSource.getActiveLightSource(player).product.id + if (player.location.isInRegion(10648) && light.id == active) { //Temple of Ikov dungeon + sendMessage(player, "Dropping the " + LightSource.getActiveLightSource(player).product.name.lowercase() + " would leave you without a light source.") + return@on false + } + val removed = removeItem(player, light.id) + if (removed) { + var droppedId = light.id + if (light.id == Items.MINING_HELMET_5013) { + droppedId = Items.MINING_HELMET_5014 + sendMessage(player, "The helmet goes out as you drop it.") + } + produceGroundItem(player, droppedId) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/MiningHelmetListener.kt b/Server/src/main/content/global/handlers/item/MiningHelmetListener.kt deleted file mode 100644 index 755a1cbde..000000000 --- a/Server/src/main/content/global/handlers/item/MiningHelmetListener.kt +++ /dev/null @@ -1,17 +0,0 @@ -package content.global.handlers.item - -import core.api.* -import core.game.interaction.InteractionListener -import core.game.interaction.IntType -import org.rs09.consts.Items - -class MiningHelmetListener : InteractionListener { - override fun defineListeners() { - on(Items.MINING_HELMET_5013, IntType.ITEM, "drop") { player, _ -> - val removed = removeItem(player, Items.MINING_HELMET_5013) - if (removed) produceGroundItem(player, Items.MINING_HELMET_5014) - sendMessage(player, "The helmet goes out as you drop it.") - return@on true - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/MorphItemListener.kt b/Server/src/main/content/global/handlers/item/MorphItemListener.kt new file mode 100644 index 000000000..b0b2e3857 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/MorphItemListener.kt @@ -0,0 +1,77 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +/** + * Handles morphing with the Ring of Stone and Easter Ring. + */ + +class MorphItemListener : InteractionListener, InterfaceListener { + + // the morphing items + private val morphItems = intArrayOf(Items.RING_OF_STONE_6583, Items.EASTER_RING_7927) + + // the NPCs to morph into + private val easterEggs = intArrayOf( + NPCs.EGG_3689, + NPCs.EGG_3690, + NPCs.EGG_3691, + NPCs.EGG_3692, + NPCs.EGG_3693, + NPCs.EGG_3694 + ) + private val stone = intArrayOf(NPCs.ROCKS_2626) + + // the "unmorph" interface + private val morphIface = 375 + + // equipping the morph items + override fun defineListeners() { + onEquip(morphItems) { player, item -> + morph(player, item.id) + return@onEquip false + } + } + + // the interface that appears when you morph + override fun defineInterfaceListeners() { + + // hitting the 'unmorph' button + on(morphIface){ player, _, _, buttonID, _, _ -> + when(buttonID) { + 3 -> closeAllInterfaces(player) + } + return@on true + } + + // after the interface closes + onClose(morphIface) { player, _ -> + unmorph(player) + return@onClose true + } + } + + // morphs the player + private fun morph(player: Player, item: Int) { + val morphId = when (item) { + Items.RING_OF_STONE_6583 -> stone.random() + else -> easterEggs.random() + } + playAudio(player, Sounds.EASTER06_HUMAN_INTO_EGG_1520) + stopWalk(player) + closeAllInterfaces(player) + player.appearance.transformNPC(morphId) + openInterface(player, morphIface) + } + + // unmorphs the player + private fun unmorph(player: Player) { + player.appearance.transformNPC(-1) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/MorphItemPlugin.java b/Server/src/main/content/global/handlers/item/MorphItemPlugin.java deleted file mode 100644 index 29c84d805..000000000 --- a/Server/src/main/content/global/handlers/item/MorphItemPlugin.java +++ /dev/null @@ -1,109 +0,0 @@ -package content.global.handlers.item; - -import core.cache.def.impl.ItemDefinition; -import core.game.component.CloseEvent; -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.GameWorld; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.plugin.ClassScanner; -import core.tools.RandomFunction; - -/** - * Handles a morph item. - * @author Vexia - */ -@Initializable -public class MorphItemPlugin implements Plugin { - - /** - * The easter egg ids. - */ - protected static final int[] EASTER_EGG_IDS = new int[] { 3689, 3690, 3691, 3692, 3693, 3694 }; - - /** - * The morph component. - */ - private static final Component COMPONENT = new Component(375).setCloseEvent(new CloseEvent() { - - @Override - public boolean close(Player player, Component c) { - unmorph(player); - return true; - } - - }); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ItemDefinition.forId(7927).getHandlers().put("equipment", this); - ItemDefinition.forId(6583).getHandlers().put("equipment", this); - ClassScanner.definePlugin(new MorphInterfacePlugin()); - return this; - } - - @Override - public Object fireEvent(String identifier, Object... args) { - final Player player = (Player) args[0]; - final Item item = (Item) args[1]; - switch (identifier) { - case "equip": - morph(player, item); - return false; - } - return true; - } - - /** - * Morphs the player. - * @param player the player. - * @param item the item. - */ - private void morph(Player player, Item item) { - int morphId = item.getId() == 6583 ? 2626 : EASTER_EGG_IDS[RandomFunction.random(EASTER_EGG_IDS.length)]; - player.getInterfaceManager().close(); - player.getAppearance().transformNPC(morphId); - player.getInterfaceManager().removeTabs(0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); - player.getLocks().lockMovement(GameWorld.getTicks() + 900000000); - player.getLocks().lockInteractions(GameWorld.getTicks() + 90000000); - player.getLocks().lockTeleport(GameWorld.getTicks() + 900000000); - player.getInterfaceManager().openSingleTab(COMPONENT); - player.getAppearance().sync(); - player.getWalkingQueue().reset(); - } - - /** - * Unmorphs the player. - * @param player the player. - */ - private static void unmorph(Player player) { - player.getAppearance().transformNPC(-1); - player.unlock(); - player.getInterfaceManager().restoreTabs(); - } - - /** - * Handles the morph interface plugin. - * @author Vexia - */ - public class MorphInterfacePlugin extends ComponentPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.forId(375).setPlugin(this); - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - player.getInterfaceManager().closeSingleTab(); - return true; - } - - } - -} diff --git a/Server/src/main/content/global/handlers/item/RingForgingOperateListener.kt b/Server/src/main/content/global/handlers/item/RingForgingOperateListener.kt new file mode 100644 index 000000000..f9ed2c366 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/RingForgingOperateListener.kt @@ -0,0 +1,22 @@ +package content.global.handlers.item + +import core.api.getAttribute +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class RingForgingOperateListener: InteractionListener { + override fun defineListeners() { + + on(Items.RING_OF_FORGING_2568, IntType.ITEM, "operate") { player, node -> + + //Attribute set at SmeltingPulse.java + val charges = getAttribute(player, "ringOfForgingCharges", 140) + + sendMessage(player, "You can smelt $charges more iron ore before the ring disintegrates.") + + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java b/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java index eb403f33b..e7529d646 100644 --- a/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java +++ b/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.plugin.Plugin; import content.region.morytania.quest.naturespirit.NSUtils; +import content.data.Quests; /** * Handles the Silver Sickle (b) to collect Mort Myre Fungus. @@ -28,7 +29,7 @@ public final class SilverSicklePlugin extends OptionHandler { switch (option) { case "operate": case "cast bloom": - if(player.getQuestRepository().getQuest("Nature Spirit").getStage(player) >= 75) { + if(player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT).getStage(player) >= 75) { player.getPacketDispatch().sendAnimation(9021); NSUtils.castBloom(player); } else { diff --git a/Server/src/main/content/global/handlers/item/TeleTabsListener.kt b/Server/src/main/content/global/handlers/item/TeleTabsListener.kt index 21a291360..9cc72f6c2 100644 --- a/Server/src/main/content/global/handlers/item/TeleTabsListener.kt +++ b/Server/src/main/content/global/handlers/item/TeleTabsListener.kt @@ -1,21 +1,19 @@ package content.global.handlers.item -import core.api.inInventory -import core.api.removeItem -import core.api.teleport +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE +import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager import core.game.node.item.Item import core.game.world.map.Location -import core.api.hasRequirement; class TeleTabsListener : InteractionListener { enum class TeleTabs(val item: Int, val location: Location, val exp: Double, val requirementCheck: (Player) -> Boolean = { true }) { ADDOUGNE_TELEPORT(8011, Location.create(2662, 3307, 0), 61.0, { - player -> hasRequirement(player, "Plague City"); + player -> getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false) }), AIR_ALTAR_TELEPORT(13599, Location.create(2978, 3296, 0), 0.0), ASTRAL_ALTAR_TELEPORT(13611, Location.create(2156, 3862, 0), 0.0), @@ -51,9 +49,17 @@ class TeleTabsListener : InteractionListener { val tabEnum = TeleTabs.forId(tab) if (tabEnum != null && inInventory(player,tab)) { val tabloc = tabEnum.location - if (inInventory(player, tab) && tabEnum.requirementCheck(player)) { - if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) { - removeItem(player, Item(node.id, 1)) + if (inInventory(player, tab)) { + if (tabEnum.requirementCheck(player)){ + if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) { + removeItem(player, Item(node.id, 1)) + } + } + else { + when (tabEnum){ + TeleTabs.ADDOUGNE_TELEPORT -> sendMessage(player, "You need to complete Plague City to use this tablet.") + else -> sendMessage(player, "You do not have the requirements to use this tablet.") + } } } } diff --git a/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java b/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java index 94c3b4eb7..5bbda0ffc 100644 --- a/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java +++ b/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java @@ -14,6 +14,7 @@ import core.game.world.map.zone.impl.WildernessZone; import core.plugin.Plugin; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Represents the rotten potato plugin. @@ -34,7 +35,7 @@ public final class TeleportCrystalPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - if (!hasRequirement(player, "Mourning's End Part I")) + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I)) return true; if (!WildernessZone.checkTeleport(player, 20)) { player.getPacketDispatch().sendMessage("The crystal is unresponsive."); diff --git a/Server/src/main/content/global/handlers/item/ToyListeners.kt b/Server/src/main/content/global/handlers/item/ToyListeners.kt index 973166815..edf14fa89 100644 --- a/Server/src/main/content/global/handlers/item/ToyListeners.kt +++ b/Server/src/main/content/global/handlers/item/ToyListeners.kt @@ -6,6 +6,13 @@ import core.game.world.update.flag.context.Graphics import org.rs09.consts.Items import core.game.interaction.InteractionListener import core.game.interaction.IntType +import kotlinx.coroutines.delay +import org.rs09.consts.Sounds +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking + + class ToyListeners : InteractionListener { companion object { @@ -14,10 +21,12 @@ class ToyListeners : InteractionListener { private val MARIONETTE_WALK = Animation(3004) private val MARIONETTE_BOW = Animation(3005) private val MARIONETTE_DANCE = Animation(3006) - private val MARIONETTE_GFX = arrayOf(intArrayOf(507, 508, 509, 510), intArrayOf(511, 512, 513, 514), intArrayOf(515, 516, 517, 518)) + private val MARIONETTE_GFX = + arrayOf(intArrayOf(507, 508, 509, 510), intArrayOf(511, 512, 513, 514), intArrayOf(515, 516, 517, 518)) private val SNOWGLOBE_SHAKE = Animation(7535) //Initial Shake private val SNOWGLOBE_HOLDFACE = Animation(7536) //Immediately after shake, player holds the snow globe to face - private val SNOWGLOBE_INTERFACE = 659 //After HOLDFACE this interface is displayed, player either clicks 'continue' for inv of snowballs, or 'close' for no snowballs + private val SNOWGLOBE_INTERFACE = + 659 //After HOLDFACE this interface is displayed, player either clicks 'continue' for inv of snowballs, or 'close' for no snowballs private val SNOWGLOBE_DOWNFAST = Animation(7537) //Used when player hit 'close' on the interface private val SNOWGLOBE_DOWNSLOW = Animation(7538) //Used when the player hit 'continue' on the interface private val SNOWGLOBE_STOMP = Animation(7528) //When player hits continue this animation plays @@ -34,7 +43,7 @@ class ToyListeners : InteractionListener { } override fun defineListeners() { - on(Items.CHOCATRICE_CAPE_12634, IntType.ITEM, "operate"){ player, _ -> + on(Items.CHOCATRICE_CAPE_12645, IntType.ITEM, "operate") { player, _ -> lockInteractions(player, 2) visualize(player, 8903, 1566) return@on true @@ -44,18 +53,18 @@ class ToyListeners : InteractionListener { val index = MARIONETTES.indexOf(marionette.id) lockInteractions(player, 2) - when(getUsedOption(player)) { + when (getUsedOption(player)) { "jump" -> visualize(player, MARIONETTE_JUMP, MARIONETTE_GFX[index][0]) "walk" -> visualize(player, MARIONETTE_WALK, MARIONETTE_GFX[index][1]) - "bow" -> visualize(player, MARIONETTE_BOW, MARIONETTE_GFX[index][2]) + "bow" -> visualize(player, MARIONETTE_BOW, MARIONETTE_GFX[index][2]) "dance" -> visualize(player, MARIONETTE_DANCE, MARIONETTE_GFX[index][3]) } return@on true } - on(Items.REINDEER_HAT_10507, IntType.ITEM, "operate"){ player, _ -> + on(Items.REINDEER_HAT_10507, IntType.ITEM, "operate") { player, _ -> lockInteractions(player, 2) - animate(player, 5059) + visualize(player, 5059, 859) return@on true } @@ -64,7 +73,7 @@ class ToyListeners : InteractionListener { animate(player, SNOWGLOBE_SHAKE) runTask(player, 3) { animate(player, SNOWGLOBE_HOLDFACE) - runTask(player){ + runTask(player) { openInterface(player, SNOWGLOBE_INTERFACE) } } @@ -80,17 +89,17 @@ class ToyListeners : InteractionListener { return@on true } - on(Items.TOY_KITE_12844, IntType.ITEM, "fly"){ player, _ -> + on(Items.TOY_KITE_12844, IntType.ITEM, "fly","operate") { player, _ -> lockInteractions(player, 2) animate(player, TOY_KITE_FLY) return@on true } - on(Items.YO_YO_4079, IntType.ITEM, "play", "loop", "walk", "crazy"){ player, _ -> + on(Items.YO_YO_4079, IntType.ITEM, "play", "loop", "walk", "crazy") { player, _ -> val option = getUsedOption(player) lockInteractions(player, 2) - when(option) { + when (option) { "play" -> animate(player, YOYO_PLAY) "loop" -> animate(player, YOYO_LOOP) "walk" -> animate(player, YOYO_WALK) @@ -99,11 +108,11 @@ class ToyListeners : InteractionListener { return@on true } - on(Items.ZOMBIE_HEAD_6722, IntType.ITEM, "talk-at", "display", "question"){ player, _ -> + on(Items.ZOMBIE_HEAD_6722, IntType.ITEM, "talk-at", "display", "question") { player, _ -> val option = getUsedOption(player) lockInteractions(player, 2) - when(option) { + when (option) { "talk-at" -> { animate(player, ZOMBIE_HEAD_TALK_AT) sendChat(player, "Alas!") @@ -116,5 +125,12 @@ class ToyListeners : InteractionListener { } return@on true } + on(Items.RUBBER_CHICKEN_4566, IntType.ITEM, "operate", "Dance") { player, _ -> + lockInteractions(player, 2) + visualize(player, 1835, -1) + playJingle(player, 99); + playAudio(player, 355, 100); + return@on true + } } } \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/book/GoblinBook.kt b/Server/src/main/content/global/handlers/item/book/GoblinBook.kt index 5f9661fa6..a7a276d41 100644 --- a/Server/src/main/content/global/handlers/item/book/GoblinBook.kt +++ b/Server/src/main/content/global/handlers/item/book/GoblinBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.ServerConstants +import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -244,8 +245,9 @@ class GoblinBook : InteractionListener { } override fun defineListeners() { - on(Items.GOBLIN_BOOK_10999, IntType.ITEM, "read") { player, _ -> + on(Items.GOBLIN_BOOK_10999, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_26, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt b/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt index 4813fed18..672890422 100644 --- a/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt +++ b/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -126,8 +127,9 @@ class SecurityBookPlugin : InteractionListener { } override fun defineListeners() { - on(Items.SECURITY_BOOK_9003, IntType.ITEM, "read") { player, _ -> + on(Items.SECURITY_BOOK_9003, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt b/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt index 4a67ee93f..c72efce0f 100644 --- a/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt +++ b/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -128,8 +129,9 @@ class StrongholdNotes : InteractionListener { } override fun defineListeners() { - on(Items.STRONGHOLD_NOTES_9004, IntType.ITEM, "read") { player, _ -> + on(Items.STRONGHOLD_NOTES_9004, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipment.kt b/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipment.kt new file mode 100644 index 000000000..5cdbb874a --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipment.kt @@ -0,0 +1,244 @@ +package content.global.handlers.item.equipment + +import core.game.node.item.Item +import org.rs09.consts.Items + +/** + * Barrows equipment information and utilities. + * @author 'Vexia - original code + * @author Damighty - Kotlin conversion and refactor + */ +object BarrowsEquipment { + // Barrows equipment lasts for 15 hours of combat. Each piece has 4 degradation tiers (100, 75, 50, 25). + const val DEGRADATION_TICKS_PER_TIER = (15 * 6000) / 4 // 22500 ticks per tier + private const val MAX_DURABILITY = DEGRADATION_TICKS_PER_TIER * 4 + + /** + * A data class for each Barrows piece. Holds all information related to a specific piece of Barrows gear. + * + * @param brother The Barrows brother this item belongs to. + * @param equipmentType The slot type ("weapon", "body", "legs", "helm"). + * @param itemName The formatted name of the item. + * @param baseRepairCost The full repair cost in GP. + * @param degradationStates A list of item IDs, from fully repaired (index 0) to broken (index 5). + */ + data class BarrowsItemDefinition( + val brother: String, + val equipmentType: String, + val itemName: String, + val baseRepairCost: Int, + val degradationStates: List + ) { + val repairedId: Int = degradationStates.first() + val brokenId: Int = degradationStates.last() + + /** Checks if a given item ID belongs to this specific equipment set. */ + fun contains(itemId: Int): Boolean = itemId in degradationStates + + /** Gets the degradation index for a given item ID (0=repaired, 1=100, ..., 5=broken). */ + fun getDegradationIndex(itemId: Int): Int = degradationStates.indexOf(itemId) + } + + /** All Barrows equipment data. */ + private val barrowsItemDefinitions = listOf( + // Dharok + BarrowsItemDefinition("dharok", "helm", "Dharok's helm", 60_000, + listOf(Items.DHAROKS_HELM_4716, Items.DHAROKS_HELM_100_4880, + Items.DHAROKS_HELM_75_4881, Items.DHAROKS_HELM_50_4882, + Items.DHAROKS_HELM_25_4883, Items.DHAROKS_HELM_0_4884)), + BarrowsItemDefinition("dharok", "weapon", "Dharok's greataxe", 100_000, + listOf(Items.DHAROKS_GREATAXE_4718, Items.DHAROKS_AXE_100_4886, + Items.DHAROKS_AXE_75_4887, Items.DHAROKS_AXE_50_4888, + Items.DHAROKS_AXE_25_4889, Items.DHAROKS_AXE_0_4890)), + BarrowsItemDefinition("dharok", "body", "Dharok's platebody", 90_000, + listOf(Items.DHAROKS_PLATEBODY_4720, Items.DHAROKS_BODY_100_4892, + Items.DHAROKS_BODY_75_4893, Items.DHAROKS_BODY_50_4894, + Items.DHAROKS_BODY_25_4895, Items.DHAROKS_BODY_0_4896)), + BarrowsItemDefinition("dharok", "legs", "Dharok's platelegs", 80_000, + listOf(Items.DHAROKS_PLATELEGS_4722, Items.DHAROKS_LEGS_100_4898, + Items.DHAROKS_LEGS_75_4899, Items.DHAROKS_LEGS_50_4900, + Items.DHAROKS_LEGS_25_4901, Items.DHAROKS_LEGS_0_4902)), + // Guthan + BarrowsItemDefinition("guthan", "helm", "Guthan's helm", 60_000, + listOf(Items.GUTHANS_HELM_4724, Items.GUTHANS_HELM_100_4904, + Items.GUTHANS_HELM_75_4905, Items.GUTHANS_HELM_50_4906, + Items.GUTHANS_HELM_25_4907, Items.GUTHANS_HELM_0_4908)), + BarrowsItemDefinition("guthan", "weapon", "Guthan's warspear", 100_000, + listOf(Items.GUTHANS_WARSPEAR_4726, Items.GUTHANS_SPEAR_100_4910, + Items.GUTHANS_SPEAR_75_4911, Items.GUTHANS_SPEAR_50_4912, + Items.GUTHANS_SPEAR_25_4913, Items.GUTHANS_SPEAR_0_4914)), + BarrowsItemDefinition("guthan", "body", "Guthan's platebody", 90_000, + listOf(Items.GUTHANS_PLATEBODY_4728, Items.GUTHANS_BODY_100_4916, + Items.GUTHANS_BODY_75_4917, Items.GUTHANS_BODY_50_4918, + Items.GUTHANS_BODY_25_4919, Items.GUTHANS_BODY_0_4920)), + BarrowsItemDefinition("guthan", "legs", "Guthan's chainskirt", 80_000, + listOf(Items.GUTHANS_CHAINSKIRT_4730, Items.GUTHANS_SKIRT_100_4922, + Items.GUTHANS_SKIRT_75_4923, Items.GUTHANS_SKIRT_50_4924, + Items.GUTHANS_SKIRT_25_4925, Items.GUTHANS_SKIRT_0_4926)), + // Torag + BarrowsItemDefinition("torag", "helm", "Torag's helm", 60_000, + listOf(Items.TORAGS_HELM_4745, Items.TORAGS_HELM_100_4952, + Items.TORAGS_HELM_75_4953, Items.TORAGS_HELM_50_4954, + Items.TORAGS_HELM_25_4955, Items.TORAGS_HELM_0_4956)), + BarrowsItemDefinition("torag", "weapon", "Torag's hammers", 100_000, + listOf(Items.TORAGS_HAMMERS_4747, Items.TORAGS_HAMMER_100_4958, + Items.TORAGS_HAMMER_75_4959, Items.TORAGS_HAMMER_50_4960, + Items.TORAGS_HAMMER_25_4961, Items.TORAGS_HAMMER_0_4962)), + BarrowsItemDefinition("torag", "body", "Torag's platebody", 90_000, + listOf(Items.TORAGS_PLATEBODY_4749, Items.TORAGS_BODY_100_4964, + Items.TORAGS_BODY_75_4965, Items.TORAGS_BODY_50_4966, + Items.TORAGS_BODY_25_4967, Items.TORAGS_BODY_0_4968)), + BarrowsItemDefinition("torag", "legs", "Torag's platelegs", 80_000, + listOf(Items.TORAGS_PLATELEGS_4751, Items.TORAGS_LEGS_100_4970, + Items.TORAGS_LEGS_75_4971, Items.TORAGS_LEGS_50_4972, + Items.TORAGS_LEGS_25_4973, Items.TORAGS_LEGS_0_4974)), + // Verac + BarrowsItemDefinition("verac", "helm", "Verac's helm", 60_000, + listOf(Items.VERACS_HELM_4753, Items.VERACS_HELM_100_4976, + Items.VERACS_HELM_75_4977, Items.VERACS_HELM_50_4978, + Items.VERACS_HELM_25_4979, Items.VERACS_HELM_0_4980)), + BarrowsItemDefinition("verac", "weapon", "Verac's flail", 100_000, + listOf(Items.VERACS_FLAIL_4755, Items.VERACS_FLAIL_100_4982, + Items.VERACS_FLAIL_75_4983, Items.VERACS_FLAIL_50_4984, + Items.VERACS_FLAIL_25_4985, Items.VERACS_FLAIL_0_4986)), + BarrowsItemDefinition("verac", "body", "Verac's brassard", 90_000, + listOf(Items.VERACS_BRASSARD_4757, Items.VERACS_TOP_100_4988, + Items.VERACS_TOP_75_4989, Items.VERACS_TOP_50_4990, + Items.VERACS_TOP_25_4991, Items.VERACS_TOP_0_4992)), + BarrowsItemDefinition("verac", "legs", "Verac's plateskirt", 80_000, + listOf(Items.VERACS_PLATESKIRT_4759, Items.VERACS_SKIRT_100_4994, + Items.VERACS_SKIRT_75_4995, Items.VERACS_SKIRT_50_4996, + Items.VERACS_SKIRT_25_4997, Items.VERACS_SKIRT_0_4998)), + // Ahrim + BarrowsItemDefinition("ahrim", "helm", "Ahrim's hood", 60_000, + listOf(Items.AHRIMS_HOOD_4708, Items.AHRIMS_HOOD_100_4856, + Items.AHRIMS_HOOD_75_4857, Items.AHRIMS_HOOD_50_4858, + Items.AHRIMS_HOOD_25_4859, Items.AHRIMS_HOOD_0_4860)), + BarrowsItemDefinition("ahrim", "weapon", "Ahrim's staff", 100_000, + listOf(Items.AHRIMS_STAFF_4710, Items.AHRIMS_STAFF_100_4862, + Items.AHRIMS_STAFF_75_4863, Items.AHRIMS_STAFF_50_4864, + Items.AHRIMS_STAFF_25_4865, Items.AHRIMS_STAFF_0_4866)), + BarrowsItemDefinition("ahrim", "body", "Ahrim's robetop", 90_000, + listOf(Items.AHRIMS_ROBETOP_4712, Items.AHRIMS_TOP_100_4868, + Items.AHRIMS_TOP_75_4869, Items.AHRIMS_TOP_50_4870, + Items.AHRIMS_TOP_25_4871, Items.AHRIMS_TOP_0_4872)), + BarrowsItemDefinition("ahrim", "legs", "Ahrim's robeskirt", 80_000, + listOf(Items.AHRIMS_ROBESKIRT_4714, Items.AHRIMS_SKIRT_100_4874, + Items.AHRIMS_SKIRT_75_4875, Items.AHRIMS_SKIRT_50_4876, + Items.AHRIMS_SKIRT_25_4877, Items.AHRIMS_SKIRT_0_4878)), + // Karil + BarrowsItemDefinition("karil", "helm", "Karil's coif", 60_000, + listOf(Items.KARILS_COIF_4732, Items.KARILS_COIF_100_4928, + Items.KARILS_COIF_75_4929, Items.KARILS_COIF_50_4930, + Items.KARILS_COIF_25_4931, Items.KARILS_COIF_0_4932)), + BarrowsItemDefinition("karil", "weapon", "Karil's crossbow", 100_000, + listOf(Items.KARILS_CROSSBOW_4734, Items.KARILS_X_BOW_100_4934, + Items.KARILS_X_BOW_75_4935, Items.KARILS_X_BOW_50_4936, + Items.KARILS_X_BOW_25_4937, Items.KARILS_X_BOW_0_4938)), + BarrowsItemDefinition("karil", "body", "Karil's leathertop", 90_000, + listOf(Items.KARILS_LEATHERTOP_4736, Items.KARILS_TOP_100_4940, + Items.KARILS_TOP_75_4941, Items.KARILS_TOP_50_4942, + Items.KARILS_TOP_25_4943, Items.KARILS_TOP_0_4944)), + BarrowsItemDefinition("karil", "legs", "Karil's leatherskirt", 80_000, + listOf(Items.KARILS_LEATHERSKIRT_4738, Items.KARILS_SKIRT_100_4946, + Items.KARILS_SKIRT_75_4947, Items.KARILS_SKIRT_50_4948, + Items.KARILS_SKIRT_25_4949, Items.KARILS_SKIRT_0_4950)) + ) + + /** Cached access to an item's full definition from its ID */ + private val itemIdToDefinitionMap: Map by lazy { + barrowsItemDefinitions.flatMap { def -> + def.degradationStates.map { id -> id to def } + }.toMap() + } + + /** Gets all degradation state arrays for degradation registration */ + fun getAllEquipmentSets(): Collection = barrowsItemDefinitions.map { it.degradationStates.toIntArray() } + + /** Gets all repairable Barrows item IDs (anything not fully repaired) */ + fun getAllRepairableBarrowsIds(): List = itemIdToDefinitionMap.filter { !isFullyRepaired(it.key) }.keys.toList() + + /** Gets the full definition for a Barrows item */ + @JvmStatic + fun getDefinition(itemId: Int): BarrowsItemDefinition? = itemIdToDefinitionMap[itemId] + + /** Checks if an item ID is any Barrows item */ + @JvmStatic + fun isBarrowsItem(itemId: Int): Boolean = itemId in itemIdToDefinitionMap + + /** Checks if a Barrows item is fully repaired */ + @JvmStatic + fun isFullyRepaired(itemId: Int): Boolean = getDefinition(itemId)?.repairedId == itemId + + /** Checks if a Barrows item is broken */ + @JvmStatic + fun isBroken(itemId: Int): Boolean = getDefinition(itemId)?.brokenId == itemId + + /** + * Calculates the repair cost for a degraded Barrows item + * @param item The degraded Barrows item + * @return The repair cost in GP, or -1 if the item cannot be repaired + */ + fun getRepairCost(item: Item): Int { + val def = getDefinition(item.id) ?: return -1 + if (isFullyRepaired(item.id)) return -1 + + val totalRemainingDurability = calculateTotalRemainingDurability(item, def) + val durabilityLost = MAX_DURABILITY - totalRemainingDurability + val cost = ((durabilityLost.toDouble() / MAX_DURABILITY) * def.baseRepairCost).toInt() + + return cost + } + + /** + * Reduces the durability of a Barrows item by 20% of its total remaining durability + * @param item The Barrows item + * @return The item with reduced durability, or null if the item is not a valid Barrows piece + */ + @JvmStatic + fun graveDeathDurabilityReduction(item: Item): Item? { + val def = getDefinition(item.id) ?: return null + if (isBroken(item.id)) return item + + val totalRemainingDurability = calculateTotalRemainingDurability(item, def) + val durabilityReduction = (totalRemainingDurability * 0.2).toInt() + val newRemainingDurability = totalRemainingDurability - durabilityReduction + + return createItemFromDurability(def, newRemainingDurability, item.amount) + } + + /** + * Calculates the total remaining durability ticks (charge) for a Barrows item + */ + private fun calculateTotalRemainingDurability(item: Item, def: BarrowsItemDefinition): Int { + return when (val index = def.getDegradationIndex(item.id)) { + -1 -> 0 // Invalid + 0 -> MAX_DURABILITY // Fully repaired + 5 -> 0 // Broken + else -> { + // For degraded items (100, 75, 50, 25), durability is the number of fully remaining tiers below it, plus the charge of the current tier. + // Index 1 (100) has 3 tiers below it. Index 4 (25) has 0 tiers below it. + val remainingTiers = 4 - index + (remainingTiers * DEGRADATION_TICKS_PER_TIER) + item.charge + } + } + } + + /** + * Creates a new Item instance based on a total durability value + */ + private fun createItemFromDurability(def: BarrowsItemDefinition, durability: Int, amount: Int): Item { + if (durability <= 0) { + return Item(def.brokenId, amount) + } + // Tier is 1-indexed (1=25, 2=50, 3=75, 4=100) + val tier = ((durability - 1) / DEGRADATION_TICKS_PER_TIER) + 1 + // Degradation index is 4-indexed (4=25, 3=50, 2=75, 1=100) + val degradationIndex = 5 - tier + + val newId = def.degradationStates[degradationIndex] + val newCharge = (durability - 1) % DEGRADATION_TICKS_PER_TIER + 1 + + return Item(newId, amount, newCharge) + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt b/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt index d7e57ab9e..1a0960711 100644 --- a/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt +++ b/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt @@ -4,73 +4,16 @@ import core.plugin.Initializable import core.plugin.Plugin @Initializable -class BarrowsEquipmentRegister : Plugin{ - public companion object { - // Barrows equipment lasts for 15 hours of combat, and each piece has 4 stages of degredation - @JvmField - public val TICKS = (15 * 6000) / 4 - } - - val DHAROK_HELM = arrayOf(4716,4880,4881,4882,4883,4884) - val DHAROK_AXE = arrayOf(4718,4886,4887,4888,4889,4890) - val DHAROK_BODY = arrayOf(4720,4892,4893,4894,4895,4896) - val DHAROK_LEGS = arrayOf(4722,4898,4899,4900,4901,4902) - - val GUTHAN_HELM = arrayOf(4724,4904,4905,4906,4907,4908) - val GUTHAN_SPEAR = arrayOf(4726,4910,4911,4912,4913,4914) - val GUTHAN_BODY = arrayOf(4728,4916,4917,4918,4919,4920) - val GUTHAN_SKIRT = arrayOf(4730,4922,4923,4924,4925,4926) - - val TORAG_HELM = arrayOf(4745,4952,4953,4954,4955,4956) - val TORAG_HAMMER = arrayOf(4747,4958,4959,4960,4961,4962) - val TORAG_BODY = arrayOf(4749,4964,4965,4966,4967,4968) - val TORAG_LEGS = arrayOf(4751,4970,4971,4972,4973,4974) - - val VERAC_HELM = arrayOf(4753,4976,4977,4978,4979,4980) - val VERAC_FLAIL = arrayOf(4755,4982,4983,4984,4985,4986) - val VERAC_BRASS = arrayOf(4757,4988,4989,4990,4991,4992) - val VERAC_SKIRT = arrayOf(4759,4994,4995,4996,4997,4998) - - val AHRIM_HOOD = arrayOf(4708,4856,4857,4858,4859,4860) - val AHRIM_STAFF = arrayOf(4710,4862,4863,4864,4865,4866) - val AHRIM_TOP = arrayOf(4712,4868,4869,4870,4871,4872) - val AHRIM_SKIRT = arrayOf(4714,4874,4875,4876,4877,4878) - - val KARIL_COIF = arrayOf(4732,4928,4929,4930,4931,4932) - val KARIL_CBOW = arrayOf(4734,4934,4935,4936,4937,4938) - val KARIL_TOP = arrayOf(4736,4940,4941,4942,4943,4944) - val KARIL_SKIRT = arrayOf(4738,4946,4947,4948,4949,4950) - +class BarrowsEquipmentRegister : Plugin { override fun newInstance(arg: Any?): Plugin { - EquipmentDegrader.registerSet(TICKS, AHRIM_HOOD) - EquipmentDegrader.registerSet(TICKS, AHRIM_STAFF) - EquipmentDegrader.registerSet(TICKS, AHRIM_TOP) - EquipmentDegrader.registerSet(TICKS, AHRIM_SKIRT) - EquipmentDegrader.registerSet(TICKS, KARIL_COIF) - EquipmentDegrader.registerSet(TICKS, KARIL_CBOW) - EquipmentDegrader.registerSet(TICKS, KARIL_TOP) - EquipmentDegrader.registerSet(TICKS, KARIL_SKIRT) - EquipmentDegrader.registerSet(TICKS, DHAROK_HELM) - EquipmentDegrader.registerSet(TICKS, DHAROK_AXE) - EquipmentDegrader.registerSet(TICKS, DHAROK_BODY) - EquipmentDegrader.registerSet(TICKS, DHAROK_LEGS) - EquipmentDegrader.registerSet(TICKS, GUTHAN_HELM) - EquipmentDegrader.registerSet(TICKS, GUTHAN_SPEAR) - EquipmentDegrader.registerSet(TICKS, GUTHAN_BODY) - EquipmentDegrader.registerSet(TICKS, GUTHAN_SKIRT) - EquipmentDegrader.registerSet(TICKS, TORAG_HELM) - EquipmentDegrader.registerSet(TICKS, TORAG_HAMMER) - EquipmentDegrader.registerSet(TICKS, TORAG_BODY) - EquipmentDegrader.registerSet(TICKS, TORAG_LEGS) - EquipmentDegrader.registerSet(TICKS, VERAC_HELM) - EquipmentDegrader.registerSet(TICKS, VERAC_FLAIL) - EquipmentDegrader.registerSet(TICKS, VERAC_BRASS) - EquipmentDegrader.registerSet(TICKS, VERAC_SKIRT) + BarrowsEquipment.getAllEquipmentSets().forEach { + degradationSet -> + EquipmentDegrader.registerSet(BarrowsEquipment.DEGRADATION_TICKS_PER_TIER, degradationSet.toTypedArray()) + } return this } override fun fireEvent(identifier: String?, vararg args: Any?): Any { return Unit } - } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java index 330523540..9c04d990f 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java @@ -57,7 +57,7 @@ public final class AncientMaceSpecialHandler extends MeleeSwingHandler implement state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1)); + hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1); if (entity.getSkills().getPrayerPoints() < entity.getSkills().getStaticLevel(5)) { entity.getSkills().setPrayerPoints(entity.getSkills().getPrayerPoints() + hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java index bb243ad37..2baaab97e 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java @@ -59,13 +59,10 @@ public final class BackstabSpecialHandler extends MeleeSwingHandler implements P } state.setStyle(CombatStyle.MELEE); int hit = 0; - double accuracy = 1.0; - if (!victim.getProperties().getCombatPulse().isAttacking()) { - accuracy = 1.75; - } - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, accuracy, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); - victim.getSkills().updateLevel(Skills.DEFENCE, -hit / 10, 0); + if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE]) + victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java index a4682149f..b3e276dcd 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java @@ -1,9 +1,7 @@ package content.global.handlers.item.equipment.special; import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.combat.CombatStyle; -import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.*; import core.game.node.entity.combat.ImpactHandler.HitsplatType; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.impl.Projectile; @@ -17,7 +15,6 @@ import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable; import core.plugin.Plugin; import core.tools.RandomFunction; -import core.game.node.entity.combat.RangeSwingHandler; import core.game.world.GameWorld; import core.game.world.repository.Repository; import org.rs09.consts.Sounds; @@ -34,6 +31,13 @@ import static core.api.ContentAPIKt.playGlobalAudio; @Initializable public final class ChainhitSpecialHandler extends RangeSwingHandler implements Plugin { + /** + * Constructs a new {@code ChainhitSpecialHandler} {@code Object}. + */ + public ChainhitSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + /** * The sp::ecial energy required. */ @@ -159,7 +163,7 @@ public final class ChainhitSpecialHandler extends RangeSwingHandler implements P public boolean pulse() { BattleState bs = new BattleState(entity, e); bs.setMaximumHit(calculateHit(player, e, 1.0)); - bs.setEstimatedHit(RandomFunction.RANDOM.nextInt(bs.getMaximumHit())); + bs.setEstimatedHit(RandomFunction.random(bs.getMaximumHit() + 1)); handleHit(victim, e, player, bs); ChainhitSpecialHandler.super.visualizeImpact(player, e, bs); return true; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java index fea739a85..a0801835e 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java @@ -13,6 +13,7 @@ import core.game.world.map.RegionManager; import core.game.world.update.flag.context.Graphics; import core.tools.RandomFunction; +import java.util.ArrayList; import java.util.List; /** @@ -31,13 +32,6 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler { */ private static final Graphics END_GRAPHIC = new Graphics(157, 96); - /** - * Constructs a new {@code ChinchompaSwingHandler} {@code Object}. - */ - public ChinchompaSwingHandler() { - super(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE); - } - @Override public int swing(Entity entity, Entity victim, BattleState state) { boolean multi = entity.getProperties().isMultiZone() && victim.getProperties().isMultiZone(); @@ -61,18 +55,20 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler { entity.getProperties().getCombatPulse().stop(); return -1; } - @SuppressWarnings("rawtypes") - List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(victim, 14, entity) : RegionManager.getSurroundingPlayers(victim, 14, entity); - BattleState[] targets = new BattleState[list.size()]; + + // ! Initial capacity of 14, but has dynamic size? i.e. we are not restricting to a max of 14 targets hit here now + List targetCandidates = new ArrayList<>(14); + targetCandidates.addAll(RegionManager.getSurroundingNPCs(victim, 14, entity)); + targetCandidates.addAll(RegionManager.getSurroundingPlayers(victim, 14, entity)); + BattleState[] targets = new BattleState[targetCandidates.size()]; int count = 0; - for (Object o : list) { - Entity e = (Entity) o; - if (canSwing(entity, e) != InteractionType.NO_INTERACT) { + for (Entity e : targetCandidates) { + if (canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) { BattleState s = targets[count++] = new BattleState(entity, e); s.setStyle(CombatStyle.RANGE); int hit = 0; if (isAccurateImpact(entity, e, CombatStyle.RANGE)) { - hit = RandomFunction.random(calculateHit(entity, e, 1.0)); + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); } s.setEstimatedHit(hit); } @@ -100,7 +96,7 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler { } } entity.getSkills().addExperience(Skills.HITPOINTS, hit * 1.33, true); - if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_DEFENSIVE) { + if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_LONG_RANGE) { entity.getSkills().addExperience(Skills.RANGE, hit * 2, true); entity.getSkills().addExperience(Skills.DEFENCE, hit * 2, true); } else { diff --git a/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java index dd669c168..f728dbaf2 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java @@ -57,8 +57,8 @@ public final class CleaveSpecialHandler extends MeleeSwingHandler implements Plu } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.18, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.2203)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.25) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java index 519f9462a..75ae1f8a8 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java @@ -30,7 +30,7 @@ public final class DescentOfDarknessSpecialHandler extends RangeSwingHandler imp /** * The special energy required. */ - private static final int SPECIAL_ENERGY = 65; + private static final int SPECIAL_ENERGY = 55; /** * The descent of dragons projectile. @@ -102,13 +102,13 @@ public final class DescentOfDarknessSpecialHandler extends RangeSwingHandler imp state.setMaximumHit(max); int hit = minDamage; if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.15, 1.0)) { - hit += RandomFunction.random(max - minDamage); + hit += RandomFunction.random(max - minDamage + 1); } state.setEstimatedHit(hit); if (w.getType() == WeaponType.DOUBLE_SHOT) { hit = minDamage; if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.15, 1.0)) { - hit += RandomFunction.random(max - minDamage); + hit += RandomFunction.random(max - minDamage + 1); } state.setSecondaryHit(hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java index c7b6dec41..4686eb2b8 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java @@ -57,8 +57,8 @@ public final class EnergyDrainSpecialHandler extends MeleeSwingHandler implement } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.2, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1); } if (victim instanceof Player) { ((Player) victim).getSettings().updateRunEnergy(10); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java index a22ba8c10..b85962790 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java @@ -52,8 +52,9 @@ public final class FeintSpecialHandler extends MeleeSwingHandler implements Plug } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, RandomFunction.random(1.0, 1.2))); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 0.25)) { + int minDamage = calculateHit(entity, victim, 0.2); + hit = minDamage + RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java index fefffaabd..6a89af4fc 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java @@ -46,7 +46,8 @@ public final class HamstringSpecialHandler extends RangeSwingHandler implements state.setMaximumHit(max); int hit = 0; if (isAccurateImpact(entity, victim)) { - hit = RandomFunction.random(max); + int minDamage = calculateHit(entity, victim, 0.2); + hit = minDamage + RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); } state.setEstimatedHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java index 76780908b..5589c48c0 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java @@ -57,20 +57,20 @@ public final class HealingBladeSpecialHandler extends MeleeSwingHandler implemen } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.12, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.005)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + int healthRestore = hit / 2; + double prayerRestore = hit * 0.25; + if (healthRestore < 10) { + healthRestore = 10; + } + if (prayerRestore < 5) { + prayerRestore = 5; + } + entity.getSkills().heal(healthRestore); + entity.getSkills().incrementPrayerPoints(prayerRestore); } state.setEstimatedHit(hit); - int healthRestore = hit / 2; - double prayerRestore = hit * 0.25; - if (healthRestore < 10) { - healthRestore = 10; - } - if (prayerRestore < 5) { - prayerRestore = 5; - } - entity.getSkills().heal(healthRestore); - entity.getSkills().incrementPrayerPoints(prayerRestore); return 1; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java index 42053679b..83c1e4a50 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java @@ -57,8 +57,8 @@ public final class IceCleaveSpecialHandler extends MeleeSwingHandler implements } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.075, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.005)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java index 11ddbd9f9..2e0ff5aa4 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java @@ -59,7 +59,7 @@ public final class ImpaleSpecialHandler extends MeleeSwingHandler implements Plu state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1)); + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java index 0fb647924..abdb00cc5 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java @@ -57,8 +57,8 @@ public final class JudgementSpecialHandler extends MeleeSwingHandler implements } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.25)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random((int) (calculateHit(entity, victim, 1.1) * 1.25) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java index 18af20d24..82f5b3eb3 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java @@ -49,7 +49,7 @@ public final class PhantomStrikeSpecialHandler extends RangeSwingHandler impleme state.setMaximumHit(max); int hit = 0; if (isAccurateImpact(entity, victim)) { - hit = RandomFunction.random(max); + hit = RandomFunction.random(max + 1); } state.setEstimatedHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java index aca1a0070..4fe5e5f90 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java @@ -56,10 +56,7 @@ public final class PowershotSpecialHandler extends RangeSwingHandler implements return -1; } state.setStyle(CombatStyle.RANGE); - int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.98, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); - } + int hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); state.setEstimatedHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java index 4c7ea7a83..ba3ff8ed0 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java @@ -49,7 +49,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements @Override public void impact(Entity entity, Entity victim, BattleState state) { - if (state.getTargets() != null) { + if (state != null && state.getTargets() != null) { for (BattleState s : state.getTargets()) { if (s != null) { s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s); @@ -81,13 +81,13 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements int count = 0; for (Object o : list) { Entity e = (Entity) o; - if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { + if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) { BattleState s = targets[count++] = new BattleState(entity, e); int hit = 0; if (isAccurateImpact(entity, e)) { - hit = RandomFunction.random(calculateHit(entity, e, 1.0)); + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); } - s.setStyle(CombatStyle.MELEE); + s.setStyle(CombatStyle.MELEE); s.setEstimatedHit(hit); } } @@ -103,7 +103,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements @Override public void visualizeImpact(Entity entity, Entity victim, BattleState state) { - if (state.getTargets() != null) { + if (state != null && state.getTargets() != null) { for (BattleState s : state.getTargets()) { if (s != null) { s.getVictim().animate(victim.getProperties().getDefenceAnimation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java index e489173fc..b5fc3357f 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java @@ -61,18 +61,13 @@ public final class PunctureSpecialHandler extends MeleeSwingHandler implements P return -1; } state.setStyle(CombatStyle.MELEE); - // First hit - //double accuracyMod, double defenceMod int hit = 0; - // accuracyMod defenceMod - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1306)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.15, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.15) + 1); } state.setEstimatedHit(hit); - // Second hit - // accuracyMod defenceMod - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1306)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.15, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.15) + 1); } else { hit = 0; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java index cc5e5a557..e1d043c9d 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java @@ -3,9 +3,11 @@ package content.global.handlers.item.equipment.special; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; import core.game.node.entity.combat.MeleeSwingHandler; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; import core.game.world.GameWorld; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; @@ -65,16 +67,22 @@ public final class QuickSmashSpecialHandler extends MeleeSwingHandler implements return -1; } } + if (DeathTask.isDead(victim)) { + return -1; + } if (!p.getSettings().drainSpecial(SPECIAL_ENERGY)) { return -1; } - // TODO: apply protection prayers/experience manually (since this is bypassing normal BattleState machinery) visualize(entity, victim, null); int hit = 0; if (isAccurateImpact(entity, victim)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.)); + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); } - victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MELEE); + if (victim.hasProtectionPrayer(CombatStyle.MELEE)) + hit *= (victim instanceof Player) ? 0.6 : 0; + BattleState b = new BattleState(); + b.setEstimatedHit(victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MELEE).getAmount()); + addExperience(entity, victim, b); return 1; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java index 0aef9cd2b..2e70ab9ec 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java @@ -65,15 +65,15 @@ public final class RampageSpecialHandler extends MeleeSwingHandler implements Pl p.visualize(ANIMATION, GRAPHIC); @SuppressWarnings("unused") int boost = 0; - for (int i = 0; i < 6; i++) { - if (i == 2 || i == 3 || i == 5) { - continue; + for (int i = 0; i < 7; i++) { + if (i == Skills.ATTACK || i == Skills.DEFENCE || i == Skills.RANGE || i == Skills.MAGIC) { + int drain = (int) (p.getSkills().getLevel(i) * 0.1); + boost += drain; + p.getSkills().updateLevel(i, -drain, 0); } - double drain = p.getSkills().getLevel(i) * 0.1; - boost += drain; - p.getSkills().updateLevel(i, (int) -drain, (int) (p.getSkills().getStaticLevel(i) - drain)); } - p.getSkills().updateLevel(Skills.STRENGTH, (int) (p.getSkills().getStaticLevel(Skills.STRENGTH) * 0.20)); + boost = 10 + (boost / 4); + p.getSkills().updateLevel(Skills.STRENGTH, boost, Math.max(p.getSkills().getStaticLevel(Skills.STRENGTH) + boost, p.getSkills().getLevel(Skills.STRENGTH))); return -1; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt b/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt index 9af01e7f9..a0c5f6941 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt +++ b/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt @@ -90,6 +90,8 @@ class SalamanderSwingHandler(private var style: CombatStyle) : CombatSwingHandle } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + entity ?: return 0 + //Checking style is necessary for ::calcmaxhit to function after changing attack style but before attacking checkStyle(entity) if (style == CombatStyle.MAGIC) { @@ -144,7 +146,7 @@ class SalamanderSwingHandler(private var style: CombatStyle) : CombatSwingHandle /** * The instance for the swing handler. */ - val INSTANCE = SalamanderSwingHandler(CombatStyle.MELEE) + val INSTANCE = SalamanderSwingHandler(CombatStyle.RANGE) /** * Gets the id of the tar used by a salamander. diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java index 3875ba7be..9e672f4db 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java @@ -52,9 +52,9 @@ public final class SaradominsLightningHandler extends MeleeSwingHandler implemen state.setStyle(CombatStyle.MAGIC); int hit = 0; int secondary = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.10, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1)); - secondary = 5 + RandomFunction.RANDOM.nextInt(14); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.10, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + secondary = 1 + RandomFunction.random(16); } state.setEstimatedHit(hit); state.setSecondaryHit(secondary); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java index 5d9bc30ef..b4a374d3e 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java @@ -1,5 +1,6 @@ package content.global.handlers.item.equipment.special; +import core.game.node.entity.combat.SwingHandlerFlag; import core.game.node.entity.skill.Skills; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; @@ -24,6 +25,13 @@ import static core.api.ContentAPIKt.playGlobalAudio; @Initializable public final class SeercullSpecialHandler extends RangeSwingHandler implements Plugin { + /** + * Constructs a new {@code SeercullSpecialHandler} {@code Object}. + */ + public SeercullSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + /** * The special energy required. */ @@ -57,11 +65,9 @@ public final class SeercullSpecialHandler extends RangeSwingHandler implements P if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { return -1; } - int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); + int hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getLevel(Skills.MAGIC) >= victim.getSkills().getStaticLevel(Skills.MAGIC)) victim.getSkills().updateLevel(Skills.MAGIC, -hit, 0); - } Companion.useAmmo(entity, state, victim.getLocation()); state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java index 116e993d4..eb8419c10 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java @@ -56,8 +56,8 @@ public final class SeverSpecialHandler extends MeleeSwingHandler implements Plug return -1; state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.124, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); if (victim instanceof Player) { Player p = (Player) victim; if (p.getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)) { diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java index aebbd909f..1b226c390 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java @@ -56,8 +56,8 @@ public final class ShatterSpecialHandler extends MeleeSwingHandler implements Pl } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 0.87, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.3546)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.5) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java index 808cae7a4..9f755280c 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java @@ -56,24 +56,25 @@ public final class SliceAndDiceSpecialHandler extends MeleeSwingHandler implemen return -1; } int maximum = calculateHit(entity, victim, 1.0); - int[] hits = new int[] {0, 1}; - int hit = getHit(entity, victim, maximum); + int[] hits; + int hit = getHit(entity, victim, maximum - 1, maximum / 2); if (hit > 0) { - hits = new int[] {hit, hit / 2, (hit / 2) / 2, (hit / 2) - ((hit / 2) / 2)}; + hits = new int[] {hit, hit / 2, (hit / 2) / 2, (hit / 2) / 2 + 1}; } else { - hit = getHit(entity, victim, maximum); + hit = getHit(entity, victim, maximum * 7 / 8, maximum * 3 / 8); if (hit > 0) { - hits = new int[] {0, hit, hit / 2, hit - (hit / 2)}; + hits = new int[] {0, hit, hit / 2, hit / 2 + 1}; } else { - hit = getHit(entity, victim, maximum); + hit = getHit(entity, victim, maximum * 3 / 4, maximum / 4); if (hit > 0) { - hits = new int[] {0, 0, hit / 2, (hit / 2) + 10}; + hits = new int[] {0, 0, hit, hit + 1}; } else { - hit = getHit(entity, victim, (int) (maximum * 1.5)); + hit = getHit(entity, victim, maximum * 5 / 4, maximum / 4); if (hit > 0) { hits = new int[] {0, 0, 0, hit}; } else { - hits = new int[] {0, RandomFunction.random(2)}; + hit = RandomFunction.random(2); + hits = new int[] {0, 0, hit, hit}; } } } @@ -95,9 +96,9 @@ public final class SliceAndDiceSpecialHandler extends MeleeSwingHandler implemen * @param maximum The maximum hit. * @return The hit. */ - private int getHit(Entity entity, Entity victim, int maximum) { - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 0.98)) { - return RandomFunction.random(maximum); + private int getHit(Entity entity, Entity victim, int maximum, int minimum) { + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + return RandomFunction.random(minimum, maximum + 1); } return 0; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java index e4137d26c..ba4989eda 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java @@ -59,7 +59,8 @@ public final class SmashSpecialHandler extends MeleeSwingHandler implements Plug state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, RandomFunction.random(1.0, 1.5))); + int max = calculateHit(entity, victim, 1.0); + hit = max / 4 + RandomFunction.random(max + 1); int lower = (int) (victim.getSkills().getLevel(Skills.DEFENCE) * 0.30); victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java index ddd761a21..618a0f4b2 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java @@ -3,6 +3,7 @@ package content.global.handlers.item.equipment.special; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.SwingHandlerFlag; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.impl.Projectile; import core.game.node.entity.player.Player; @@ -25,6 +26,13 @@ import static core.api.ContentAPIKt.playGlobalAudio; @Initializable public final class SnapshotSpecialHandler extends RangeSwingHandler implements Plugin { + /** + * Constructs a new {@code SnapshotSpecialHandler} {@code Object}. + */ + public SnapshotSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + /** * The special energy required. */ @@ -67,13 +75,13 @@ public final class SnapshotSpecialHandler extends RangeSwingHandler implements P int max = calculateHit(entity, victim, 1.0); state.setMaximumHit(max); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 0.9, 1.0)) { - hit = RandomFunction.random(max); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.43, 1.0)) { + hit = RandomFunction.random(max + 1); } state.setEstimatedHit(hit); hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 0.9, 1.0)) { - hit = RandomFunction.random(max); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.43, 1.0)) { + hit = RandomFunction.random(max + 1); } state.setSecondaryHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java index b3941ef7c..4d5b66609 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java @@ -60,9 +60,10 @@ public final class SnipeSpecialHandler extends RangeSwingHandler implements Plug } state.setStyle(CombatStyle.RANGE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); - victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); + if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.RANGE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE]) + victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); } Companion.useAmmo(entity, state, victim.getLocation()); state.setEstimatedHit(hit); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java index bdbef4ee4..2595b0479 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java @@ -49,7 +49,7 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements @Override public void impact(Entity entity, Entity victim, BattleState state) { - if (state.getTargets() != null) { + if (state != null && state.getTargets() != null) { for (BattleState s : state.getTargets()) { if (s != null) { s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s); @@ -82,11 +82,11 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements int count = 0; for (Object o : list) { Entity e = (Entity) o; - if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { + if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) { BattleState s = targets[count++] = new BattleState(entity, e); int hit = 0; - hit = RandomFunction.random(calculateHit(entity, e, 1.0)); - s.setStyle(CombatStyle.MELEE); + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); + s.setStyle(CombatStyle.MELEE); s.setEstimatedHit(hit); } } @@ -96,13 +96,13 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements @Override public void visualize(Entity entity, Entity victim, BattleState state) { - playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529); - entity.visualize(ANIMATION, GRAPHIC); + playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529); + entity.visualize(ANIMATION, GRAPHIC); } @Override public void visualizeImpact(Entity entity, Entity victim, BattleState state) { - if (state.getTargets() != null) { + if (state != null && state.getTargets() != null) { for (BattleState s : state.getTargets()) { if (s != null) { s.getVictim().animate(victim.getProperties().getDefenceAnimation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java index 4b7947736..6c4b9cedc 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java @@ -64,16 +64,16 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug BattleState[] targets = getTargets(entity, victim, state); state.setTargets(targets); for (BattleState s : targets) { - s.setStyle(CombatStyle.MELEE); + s.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 1, 0.94)) { - hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1)); + if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1); } s.setEstimatedHit(hit); if (s.getVictim().size() > 1) { hit = 0; - if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 1, 0.94)) { - hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1)); + if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 0.75, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1); } s.setSecondaryHit(hit); } @@ -90,7 +90,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug */ private BattleState[] getTargets(Entity entity, Entity victim, BattleState state) { if (!entity.getProperties().isMultiZone() || !victim.getProperties().isMultiZone()) { - return new BattleState[] { state }; + return new BattleState[]{state}; } Location vl = victim.getLocation(); int x = vl.getX(); @@ -102,6 +102,9 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug if (n instanceof Familiar) { continue; } + if (!n.isAttackable(entity, CombatStyle.MELEE, false)) { + continue; + } if (n.getLocation().equals(vl.transform(dir.getStepY(), dir.getStepX(), 0)) || n.getLocation().equals(vl.transform(-dir.getStepY(), -dir.getStepX(), 0))) { l.add(new BattleState(entity, n)); if (l.size() >= 3) { @@ -127,7 +130,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug @Override public void impact(Entity entity, Entity victim, BattleState state) { - if (state.getTargets() != null) { + if (state != null && state.getTargets() != null) { for (BattleState s : state.getTargets()) { if (s != null) { s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s); @@ -146,7 +149,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug @Override public void visualizeImpact(Entity entity, Entity victim, BattleState state) { - if (state.getTargets() != null) { + if (state != null && state.getTargets() != null) { for (BattleState s : state.getTargets()) { if (s != null) { s.getVictim().animate(victim.getProperties().getDefenceAnimation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java index 8982b198b..177769d5d 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java @@ -57,8 +57,8 @@ public final class WarstrikeSpecialHandler extends MeleeSwingHandler implements } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.049, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random((int) (calculateHit(entity, victim, 1.1) * 1.1) + 1); } state.setEstimatedHit(hit); if (victim instanceof Player) { @@ -68,10 +68,10 @@ public final class WarstrikeSpecialHandler extends MeleeSwingHandler implements if (left > 0) { left = -victim.getSkills().updateLevel(Skills.STRENGTH, -left, 0); if (left > 0) { - left = -victim.getSkills().updateLevel(Skills.ATTACK, -left, 0); + left = (int) -(victim.getSkills().getPrayerPoints() + left); + victim.getSkills().decrementPrayerPoints(left); if (left > 0) { - left = (int) -(victim.getSkills().getPrayerPoints() + left); - victim.getSkills().decrementPrayerPoints(left); + left = -victim.getSkills().updateLevel(Skills.ATTACK, -left, 0); if (left > 0) { left = -victim.getSkills().updateLevel(Skills.MAGIC, -left, 0); if (left > 0) diff --git a/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java index 0fda16c8c..b8f45d90f 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java @@ -57,18 +57,19 @@ public final class WeakenSpecialHandler extends MeleeSwingHandler implements Plu state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim instanceof Player) { + ((Player) victim).getPacketDispatch().sendMessage("You have been drained."); + } + // TODO 10% drain to demons + int lower = (int) (victim.getSkills().getStaticLevel(Skills.DEFENCE) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); + lower = (int) (victim.getSkills().getStaticLevel(Skills.ATTACK) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.ATTACK, -lower, 0); + lower = (int) (victim.getSkills().getStaticLevel(Skills.STRENGTH) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.STRENGTH, -lower, 0); } state.setEstimatedHit(hit); - if (victim instanceof Player) { - ((Player) victim).getPacketDispatch().sendMessage("You have been drained."); - } - int lower = (int) (victim.getSkills().getLevel(Skills.DEFENCE) * 0.05); - victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); - int lower2 = (int) (victim.getSkills().getLevel(Skills.ATTACK) * 0.05); - victim.getSkills().updateLevel(Skills.ATTACK, -lower2, 0); - int lower3 = (int) (victim.getSkills().getLevel(Skills.STRENGTH) * 0.05); - victim.getSkills().updateLevel(Skills.STRENGTH, -lower3, 0); return hit; } diff --git a/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java b/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java index 82afc70ab..57f51641e 100644 --- a/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java +++ b/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java @@ -1,5 +1,6 @@ package content.global.handlers.item.toys; +import content.global.skill.construction.decoration.pohstorage.StorableFamily; import core.game.component.Component; import core.game.component.ComponentDefinition; import core.game.component.ComponentPlugin; @@ -27,7 +28,7 @@ import static core.api.ContentAPIKt.inInventory; public class DiangoReclaimInterface extends ComponentPlugin { private static final int COMPONENT_ID = 468; public static final List ITEMS = new ArrayList<>(20); - public static final Item[] HOLIDAY_ITEMS = {new Item(Items.YO_YO_4079), new Item(Items.REINDEER_HAT_10507), new Item(Items.RUBBER_CHICKEN_4566),new Item(Items.ZOMBIE_HEAD_6722), new Item(6857), new Item(6856), new Item(6858), new Item(6859), new Item(6860), new Item(6861), new Item(6862), new Item(6863), new Item(9920), new Item(9921),new Item(9922), new Item(9923), new Item(9924), new Item(9925), new Item(11019), new Item(11020), new Item(11021), new Item(11022), new Item(11789), new Item(11949), new Item(12634), new Item(14076), new Item(14077), new Item(14081),new Item(14595), new Item(14602), new Item(14603), new Item(14605), new Item(14654), new Item(Items.RED_MARIONETTE_6867), new Item(Items.GREEN_MARIONETTE_6866), new Item(Items.BLUE_MARIONETTE_6865)}; + public static final Item[] HOLIDAY_ITEMS = {new Item(Items.YO_YO_4079), new Item(Items.REINDEER_HAT_10507), new Item(Items.WINTUMBER_TREE_10508), new Item(Items.RUBBER_CHICKEN_4566),new Item(Items.ZOMBIE_HEAD_6722), new Item(6857), new Item(6856), new Item(6858), new Item(6859), new Item(6860), new Item(6861), new Item(6862), new Item(6863), new Item(9920), new Item(9921),new Item(9922), new Item(9923), new Item(9924), new Item(9925), new Item(11019), new Item(11020), new Item(11021), new Item(11022), new Item(11789), new Item(11949), new Item(12645), new Item(14076), new Item(14077), new Item(14081),new Item(14595), new Item(14602), new Item(14603), new Item(14605), new Item(14654), new Item(Items.ICE_AMULET_14596), new Item(Items.RED_MARIONETTE_6867), new Item(Items.GREEN_MARIONETTE_6866), new Item(Items.BLUE_MARIONETTE_6865)}; //initialize the plugin, add lists of items to the ITEMS list... @Override @@ -46,7 +47,7 @@ public class DiangoReclaimInterface extends ComponentPlugin { Item[] reclaimables = getEligibleItems(player); player.setAttribute("diango-reclaimables", reclaimables); - //filter out items the player already has in their bank, inventory, or equipped + //filter out items the player already has in their bank, POH, inventory, or equipped //only send items if there are some to send if(reclaimables.length > 0) { @@ -90,7 +91,7 @@ public class DiangoReclaimInterface extends ComponentPlugin { public static Item[] getEligibleItems (Player player) { return ITEMS.stream().filter(Objects::nonNull) - .filter(item -> !player.getEquipment().containsItem(item) && !player.getInventory().containsItem(item) && !player.getBank().containsItem(item) + .filter(item -> !player.getEquipment().containsItem(item) && !player.getInventory().containsItem(item) && !player.getBank().containsItem(item) && !player.getPOHStorageState().getContainer(StorableFamily.TOY_BOX).contains(item.getId()) && (item.getId() != 14654 || (!(inInventory(player, 14655, 1) || inEquipment(player, 14656, 1)) && player.getAttribute("sotr:purchased",false)) )) diff --git a/Server/src/main/content/global/handlers/item/withitem/CalquatKeg.kt b/Server/src/main/content/global/handlers/item/withitem/CalquatKeg.kt new file mode 100644 index 000000000..56b5cb77e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/CalquatKeg.kt @@ -0,0 +1,19 @@ +package content.global.handlers.item.withitem + +import core.api.addItem +import core.api.animate +import core.api.removeItem +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class CalquatKeg : InteractionListener{ + override fun defineListeners() { + onUseWith(ITEM, Items.CALQUAT_FRUIT_5980, Items.KNIFE_946) { player, _, _ -> + if (removeItem(player, Items.CALQUAT_FRUIT_5980)){ + animate(player,2290) + addItem(player, Items.CALQUAT_KEG_5769) + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt b/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt index 207102b5f..15d12ca62 100644 --- a/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt +++ b/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt @@ -24,9 +24,11 @@ class CrystalKeyCreateListener : InteractionListener { return@onUseWith false } - addItem(player, Items.CRYSTAL_KEY_989) - sendMessage(player, "You join the loop half of a key and the tooth half of a key to make a crystal key.") + if (!addItem(player, Items.CRYSTAL_KEY_989)) { + return@onUseWith false + } + sendMessage(player, "You join the loop half of a key and the tooth half of a key to make a crystal key.") return@onUseWith true } } diff --git a/Server/src/main/content/global/handlers/item/withitem/GrindToothListener.kt b/Server/src/main/content/global/handlers/item/withitem/GrindToothListener.kt new file mode 100644 index 000000000..93a6989da --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/GrindToothListener.kt @@ -0,0 +1,24 @@ +package content.global.handlers.item.withitem + +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor +import core.game.node.item.Item + +class GrindToothListener : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.PESTLE_AND_MORTAR_233, Items.SUQAH_TOOTH_9079) { player, _, with -> + val item = with as Item + val res = replaceSlot(player, item.slot, Item(Items.GROUND_TOOTH_9082)) + if (res?.id == Items.SUQAH_TOOTH_9079) { + sendMessage(player, "You grind the suqah tooth to dust.") //https://www.youtube.com/watch?v=RdIcNH50v7I + } else { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Player ground item ${res?.name} instead of a suqah tooth - potential slot-based manipulation attempt") + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt b/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt index 1dcd15cd4..318f8a0a8 100644 --- a/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt +++ b/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt @@ -15,10 +15,11 @@ class OilFishingRodListener : InteractionListener { override fun pulse(): Boolean { when (counter++) { 1 -> { - removeItem(player, used.asItem()) && removeItem(player, with.asItem()) - addItem(player, Items.VIAL_229) - addItem(player, Items.OILY_FISHING_ROD_1585) - sendMessage(player, "You rub the oil into the fishing rod.") + if (removeItem(player, used.asItem()) && removeItem(player, with.asItem()) && + addItem(player, Items.VIAL_229) && + addItem(player, Items.OILY_FISHING_ROD_1585)) { + sendMessage(player, "You rub the oil into the fishing rod.") + } } } return false @@ -35,9 +36,10 @@ class OilFishingRodListener : InteractionListener { when (counter++) { 0 -> player.animator.animate(Animation(364)) 3 -> { - removeItem(player, Items.THIN_SNAIL_3363) - removeItem(player, Items.SAMPLE_BOTTLE_3377) - addItem(player, Items.BLAMISH_SNAIL_SLIME_1581) + if (removeItem(player, Items.THIN_SNAIL_3363) && + removeItem(player, Items.SAMPLE_BOTTLE_3377)) { + addItem(player, Items.BLAMISH_SNAIL_SLIME_1581) + } } } return false diff --git a/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt b/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt index da829ed82..f332b0590 100644 --- a/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt +++ b/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt @@ -14,11 +14,10 @@ class WatermelonOnSack : InteractionListener { override fun defineListeners() { onUseWith(IntType.ITEM, SACK, WATERMELON){ player, used, _ -> if(getStatLevel(player, Skills.FARMING) >= 23){ - removeItem(player,SACK, Container.INVENTORY) - removeItem(player,WATERMELON,Container.INVENTORY) - addItem(player, Items.SCARECROW_6059) - rewardXP(player, Skills.FARMING, 25.0) - sendMessage(player, "You stab the watermelon on top of the spear, finishing your scarecrow") + if (removeItem(player,SACK, Container.INVENTORY) && removeItem(player,WATERMELON,Container.INVENTORY) && addItem(player, Items.SCARECROW_6059)) { + rewardXP(player, Skills.FARMING, 25.0) + sendMessage(player, "You stab the watermelon on top of the spear, finishing your scarecrow") + } }else{ sendMessage(player, "Your Farming level is not high enough to do this") } diff --git a/Server/src/main/content/global/handlers/item/withnpc/BonesOnStrayDog.kt b/Server/src/main/content/global/handlers/item/withnpc/BonesOnStrayDog.kt deleted file mode 100644 index e6e7fd03a..000000000 --- a/Server/src/main/content/global/handlers/item/withnpc/BonesOnStrayDog.kt +++ /dev/null @@ -1,84 +0,0 @@ -package content.global.handlers.item.withnpc - -import core.api.removeItem -import core.api.sendChat -import core.api.sendMessage -import content.global.skill.prayer.Bones -import core.game.node.entity.npc.NPC -import core.game.node.item.Item -import org.rs09.consts.Items -import org.rs09.consts.NPCs -import core.game.interaction.InteractionListener -import core.game.interaction.IntType - -class BonesOnStrayDog : InteractionListener { - override fun defineListeners() { - val bones = Bones.array - - val dogs = intArrayOf( - NPCs.STRAY_DOG_4766, - NPCs.STRAY_DOG_4767, - NPCs.STRAY_DOG_5917, - NPCs.STRAY_DOG_5918 - ) - - onUseWith(IntType.NPC, bones, *dogs) { player, used, with -> - used as Item; with as NPC - - var woof = "Woof" - - if (removeItem(player, used)) { - sendMessage( - player, - "You feed the ${with.definition.name.lowercase()} your ${used.definition.name.lowercase()}." - ) - - when (used.id) { - Items.BURNT_BONES_528 -> { - sendMessage( - player, - "The dog looks at you, disappointed, but takes the bones anyway." - ) - - woof = "Woof..." - } - - Items.FAYRG_BONES_4830, - Items.RAURG_BONES_4832, - Items.OURG_BONES_4834 -> { - sendMessage( - player, - "The dog looks at you, confused, but takes the bones anyway." - ) - - woof = "Woof..?" - } - - Items.BABYDRAGON_BONES_534, - Items.BIG_BONES_532 -> { - sendMessage( - player, - "The dog seems to be very happy." - ) - - woof = "Woof!" - } - - Items.WYVERN_BONES_6812, - Items.DRAGON_BONES_536 -> { - sendMessage( - player, - "The dog seems to be extremely overjoyed." - ) - - woof = "WOOF!" - } - } - - sendChat(with, woof) - } - - return@onUseWith true - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/CatOnArdougneCivilian.kt b/Server/src/main/content/global/handlers/item/withnpc/CatOnArdougneCivilian.kt index 7046b50a2..e69de29bb 100644 --- a/Server/src/main/content/global/handlers/item/withnpc/CatOnArdougneCivilian.kt +++ b/Server/src/main/content/global/handlers/item/withnpc/CatOnArdougneCivilian.kt @@ -1,56 +0,0 @@ -package content.global.handlers.item.withnpc - -import core.api.Container -import core.api.* -import org.rs09.consts.Items -import org.rs09.consts.NPCs -import core.game.interaction.InteractionListener -import core.game.interaction.IntType - -class CatOnArdougneCivilian: InteractionListener { - - private val civilians = intArrayOf( - NPCs.CIVILIAN_785, - NPCs.CIVILIAN_786, - NPCs.CIVILIAN_787 - ) - - private val cats = intArrayOf( - Items.PET_CAT_1561, - Items.PET_CAT_1562, - Items.PET_CAT_1563, - Items.PET_CAT_1564, - Items.PET_CAT_1565, - Items.PET_CAT_1566, - Items.OVERGROWN_CAT_1567, - Items.OVERGROWN_CAT_1568, - Items.OVERGROWN_CAT_1569, - Items.OVERGROWN_CAT_1570, - Items.OVERGROWN_CAT_1571, - Items.OVERGROWN_CAT_1572, - Items.LAZY_CAT_6551, - Items.LAZY_CAT_6552, - Items.LAZY_CAT_6553, - Items.LAZY_CAT_6554, - Items.WILY_CAT_6555, - Items.WILY_CAT_6556, - Items.WILY_CAT_6557, - Items.WILY_CAT_6558, - Items.WILY_CAT_6559, - Items.WILY_CAT_6560, - Items.HELL_CAT_7582, - Items.OVERGROWN_HELLCAT_7581, - Items.LAZY_HELL_CAT_7584, - Items.WILY_HELLCAT_7585, - ) - - override fun defineListeners() { - onUseWith(IntType.NPC,cats,*civilians){ player, used, _ -> - sendItemDialogue(player,Items.DEATH_RUNE_560,"You hand over the cat.
You are given 100 Death Runes.") - player.familiarManager.removeDetails(used.idHash) - removeItem(player,used,Container.INVENTORY) - addItem(player,Items.DEATH_RUNE_560,100) - return@onUseWith true - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt b/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt index 31cb87218..ab0018b8d 100644 --- a/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt +++ b/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt @@ -43,7 +43,7 @@ class CiderOnForesterDialogue : DialogueFile() { end() } else if(player!!.getAttribute("seersCiderPub",-1) !in 0..3 && !player!!.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,0,6)){ - player!!.setAttribute("seersCiderPub",0) + player!!.setAttribute("seersCiderPub", 1) end() }else if(player!!.getAttribute("seersCiderPub",-1) in 0..3){ player!!.incrementAttribute("seersCiderPub",1) diff --git a/Server/src/main/content/global/handlers/item/withnpc/FeedOnStrayDog.kt b/Server/src/main/content/global/handlers/item/withnpc/FeedOnStrayDog.kt new file mode 100644 index 000000000..1c1013ac4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/FeedOnStrayDog.kt @@ -0,0 +1,118 @@ +package content.global.handlers.item.withnpc + +import core.api.removeItem +import core.api.sendChat +import core.api.sendMessage +import content.global.skill.prayer.Bones +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Meat +import content.data.MeatState +import core.api.animate +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Animations + +/** + * Represents the option Listener use-with on a stray dog. + * Use bones, raw & cooked meats + */ +class FeedOnStrayDog : InteractionListener { + override fun defineListeners() { + + val bones = Bones.array + + val consumableMeats = Meat.values() + .filter { it.state == MeatState.INEDIBLE_RAW || it.state == MeatState.EDIBLE_COOKED } + .map { it.id } + .toIntArray() + + val allAllowedItems = bones + consumableMeats + + val dogs = intArrayOf( + NPCs.STRAY_DOG_4766, + NPCs.STRAY_DOG_4767, + NPCs.STRAY_DOG_5917, + NPCs.STRAY_DOG_5918 + ) + + onUseWith(IntType.NPC, allAllowedItems, *dogs) { player, used, with -> + used as Item; with as NPC + + var woof = "Woof" + + if (removeItem(player, used)) { + sendMessage( + player, + "You feed the ${with.definition.name.lowercase()} your ${used.definition.name.lowercase()}." + ) + + animate(player, Animations.HUMAN_BURYING_BONES_827) + + when { + bones.contains(used.id) -> { + when (used.id) { + Items.BURNT_BONES_528 -> { + sendMessage( + player, + "The dog looks at you, disappointed, but takes the bones anyway." + ) + + woof = "Woof..." + } + + Items.FAYRG_BONES_4830, + Items.RAURG_BONES_4832, + Items.OURG_BONES_4834 -> { + sendMessage( + player, + "The dog looks at you, confused, but takes the bones anyway." + ) + + woof = "Woof..?" + } + + Items.BABYDRAGON_BONES_534, + Items.BIG_BONES_532 -> { + sendMessage( + player, + "The dog seems to be very happy." + ) + + woof = "Woof!" + } + + Items.WYVERN_BONES_6812, + Items.DRAGON_BONES_536 -> { + sendMessage( + player, + "The dog seems to be extremely overjoyed." + ) + + woof = "WOOF!" + } + } + } + + consumableMeats.contains(used.id) -> { + sendMessage( + player, + "The dog wagged its tail happily." + ) + + animate(with, Animation(4777)) + + woof = "Woof woof!" + } + } + + sendChat(with, woof) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt b/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt index 3209b4f45..0b54ccf55 100644 --- a/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt +++ b/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt @@ -10,27 +10,27 @@ import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.game.world.GameWorld.Pulser +import content.data.Quests class GCItemOnCat : InteractionListener { override fun defineListeners() { - val GERTCAT = "Gertrude's Cat" val BEND_DOWN = 827 onUseWith(IntType.NPC, Items.BUCKET_OF_MILK_1927, NPCs.GERTRUDES_CAT_2997) { player, used, with -> - if(getQuestStage(player, GERTCAT) == 20 && removeItem(player, used.asItem())){ + if(getQuestStage(player, Quests.GERTRUDES_CAT) == 20 && removeItem(player, used.asItem())){ addItem(player, Items.BUCKET_1925) animate(player, BEND_DOWN) //bend down sendChat(with.asNpc(), "Mew!") - setQuestStage(player, GERTCAT, 30) + setQuestStage(player, Quests.GERTRUDES_CAT, 30) } return@onUseWith true } onUseWith(IntType.NPC, Items.DOOGLE_SARDINE_1552, NPCs.GERTRUDES_CAT_2997){ player, used, with -> - if(getQuestStage(player, GERTCAT) == 30 && removeItem(player, used.asItem())){ + if(getQuestStage(player, Quests.GERTRUDES_CAT) == 30 && removeItem(player, used.asItem())){ animate(player, BEND_DOWN) sendChat(with.asNpc(), "Mew!") - setQuestStage(player, GERTCAT, 40) + setQuestStage(player, Quests.GERTRUDES_CAT, 40) } return@onUseWith true } @@ -42,7 +42,7 @@ class GCItemOnCat : InteractionListener { onUseWith(IntType.NPC, Items.THREE_LITTLE_KITTENS_13236, NPCs.GERTRUDES_CAT_2997){ player, used, with -> if(removeItem(player, used.asItem())){ - setQuestStage(player, GERTCAT, 60) + setQuestStage(player, Quests.GERTRUDES_CAT, 60) //below copied verbatim from original, I don't like it. Pulser.submit(object : Pulse(1) { var count = 0 diff --git a/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java b/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java index b939f3735..efddb3bed 100644 --- a/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java +++ b/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java @@ -14,6 +14,7 @@ import core.game.world.map.path.Pathfinder; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the plugin used to handle the use with interactions. @@ -50,7 +51,7 @@ public final class GertrudeCatUsePlugin extends UseWithHandler { public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); final NPC npc = ((NPC) event.getUsedWith()); - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); if (event.getUsedItem().getId() == 1927 && quest.getStage(player) == 20) { if (player.getInventory().remove(event.getUsedItem())) { player.getInventory().add(EMPTY_BUCKET); diff --git a/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt b/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt index dab9e0c12..3dbd34a6d 100644 --- a/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt +++ b/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt @@ -5,20 +5,19 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.data.Quests class RopeOnLadyKeli : InteractionListener { override fun defineListeners() { - val PAR = "Prince Ali Rescue" - onUseWith(IntType.NPC, Items.ROPE_954, NPCs.LADY_KELI_919) { player, used, with -> - if(getQuestStage(player, PAR) in 40..50 && getAttribute(player, "guard-drunk", false)){ + if(getQuestStage(player, Quests.PRINCE_ALI_RESCUE) in 40..50 && getAttribute(player, "guard-drunk", false)){ if(removeItem(player, used.asItem())){ sendDialogue(player, "You overpower Keli, tie her up, and put her in a cupboard.") - setQuestStage(player, PAR, 50) + setQuestStage(player, Quests.PRINCE_ALI_RESCUE, 50) setAttribute(player, "keli-gone", getWorldTicks() + 350) } } else { - if (getQuestStage(player, PAR) == 40){ + if (getQuestStage(player, Quests.PRINCE_ALI_RESCUE) == 40){ sendMessage(player, "You need to do something about the guard first.") } } diff --git a/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt b/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt index 5b78dd96b..0d5929d0a 100644 --- a/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt +++ b/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt @@ -1,7 +1,7 @@ package content.global.handlers.item.withobject +import content.data.Quests import core.api.* -import content.region.kandarin.quest.dwarfcannon.DwarfCannon import core.game.node.Node import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills @@ -19,8 +19,8 @@ class AmmoMouldOnFurnace : InteractionListener { private fun cannonBallOnUseWithHandler(player: Player, used: Node, with: Node): Boolean { face(player, with.centerLocation) - if(!isQuestComplete(player, DwarfCannon.NAME)) { - sendDialogue(player, "You need to complete the ${DwarfCannon.NAME} quest in order to do this.") + if(!isQuestComplete(player, Quests.DWARF_CANNON)) { + sendDialogue(player, "You need to complete the ${Quests.DWARF_CANNON} quest in order to do this.") return true } if (getDynLevel(player, Skills.SMITHING) < levelRequirement) { diff --git a/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt b/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt index 799084610..bbde6bc21 100644 --- a/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt +++ b/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt @@ -35,8 +35,9 @@ class SandSourceListener : InteractionListener { animate(player, ANIMATION) } - sendMessage(player, "You fill the bucket with sand.") - addItem(player, Items.BUCKET_OF_SAND_1783) + if (addItem(player, Items.BUCKET_OF_SAND_1783)) { + sendMessage(player, "You fill the bucket with sand.") + } } animationTrigger++ diff --git a/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt b/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt index 3607fda98..13ee4000a 100644 --- a/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt +++ b/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt @@ -61,8 +61,9 @@ class SapCollectListener : InteractionListener { override fun pulse(): Boolean { if (removeItem(player, Items.BUCKET_1925)) { animate(player, ANIMATION) - sendMessage(player, "You cut the tree and allow its sap to drip down into your bucket.") - addItem(player, Items.BUCKET_OF_SAP_4687) + if (addItem(player, Items.BUCKET_OF_SAP_4687)) { + sendMessage(player, "You cut the tree and allow its sap to drip down into your bucket.") + } return true } return false diff --git a/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java b/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java index 95d10cb2c..e9ef946b3 100644 --- a/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java +++ b/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java @@ -15,6 +15,7 @@ import core.game.node.scenery.Scenery; import core.plugin.Plugin; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the option handler used for smithing. @@ -68,7 +69,7 @@ public final class SmithingPlugin extends UseWithHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete("Doric's Quest")) { + if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete(Quests.DORICS_QUEST)) { player.getDialogueInterpreter().sendDialogue("Property of Doric the Dwarf."); return true; } diff --git a/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt b/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt index 45b0dad76..084e7f117 100644 --- a/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt +++ b/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt @@ -82,9 +82,11 @@ class SpiritShieldBlessListener : InteractionListener { return@onUseWith false } - addItem(player, Items.BLESSED_SPIRIT_SHIELD_13736) - sendMessage(player, "You successfully bless the shield using the holy elixir.") + if (!addItem(player, Items.BLESSED_SPIRIT_SHIELD_13736)) { + return@onUseWith false + } + sendMessage(player, "You successfully bless the shield using the holy elixir.") return@onUseWith true } diff --git a/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt b/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt index a53198e44..75652b75d 100644 --- a/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt +++ b/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt @@ -7,6 +7,7 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import core.game.interaction.InteractionListener import core.game.interaction.IntType +import core.game.world.map.Location import org.rs09.consts.Sounds /** @@ -14,8 +15,10 @@ import org.rs09.consts.Sounds * @author Ceikry */ class WaterSourceListener : InteractionListener { - //this is ugly! - private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089) + // NOTE '9695' should be removed from the array below once the sink object can be used directly, this is a temporary + // solution. + // this is ugly! + private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 9695, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089) private val nonWellableMsg = "If I drop my @ down there, I don't think I'm likely to get it back." private val animation = Animation(832) @@ -31,6 +34,11 @@ class WaterSourceListener : InteractionListener { return@onUseWith true } + if(with.id == 9695 && player.location.regionId != 11571) + { + return@onUseWith false + } + //ugly achievement code, achievement system sux if(vessel == WaterVessel.BUCKET && with.id == 11661) { @@ -59,6 +67,15 @@ class WaterSourceListener : InteractionListener { return@onUseWith true } + + // This is needed to make the crafting guild sink work, but technically it's wrong as it is the noticeboard and + // not the sink being used. This is a temporary solution until the sink object can be used directly. + setDest(IntType.SCENERY, intArrayOf(9695), "use") { player, node -> + if (player.location.regionId == 11571){ + return@setDest Location.create(2934, 3280, 0) + } + return@setDest node.location + } } private fun formatMsgText(name: String, template: String): String @@ -112,6 +129,14 @@ class WaterSourceListener : InteractionListener { FISHBOWL( inputs = intArrayOf(Items.FISHBOWL_6667), output = Items.FISHBOWL_6668 + ), + KETTLE( + inputs = intArrayOf(Items.KETTLE_7688), + output = Items.FULL_KETTLE_7690 + ), + CUP( + inputs = intArrayOf(Items.EMPTY_CUP_1980), + output = Items.CUP_OF_WATER_4458 ); companion object diff --git a/Server/src/main/content/global/handlers/npc/BankerNPC.kt b/Server/src/main/content/global/handlers/npc/BankerNPC.kt index e59ac6b69..7dff2f0d7 100644 --- a/Server/src/main/content/global/handlers/npc/BankerNPC.kt +++ b/Server/src/main/content/global/handlers/npc/BankerNPC.kt @@ -1,62 +1,54 @@ package content.global.handlers.npc +import content.global.handlers.scenery.BankBoothListener +import core.ServerConstants import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.interaction.IntType +import core.game.interaction.InteractionListener import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode import core.game.world.map.Direction import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.NPCs -import core.game.interaction.InteractionListener -import core.game.interaction.IntType -import content.global.handlers.scenery.BankBoothListener /** * Provides dialogue tree for all generic banker NPCs as well as * handles all the common interactions like 'bank' and 'collect'. * * @author vddCore + * @author Player Name */ @Initializable class BankerNPC : AbstractNPC, InteractionListener { + val NPC_IDS = intArrayOf( + NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497, + NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164, + NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198, + NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776, + NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533, + NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605, + NPCs.GUNDAI_902, + NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619, + NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, + NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050, + NPCs.BANKER_6538 + ) + companion object { private const val LUNAR_ISLE_BANK_REGION = 8253 - val SPECIAL_NPC_IDS = intArrayOf( - NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, - NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050, NPCs.ARNOLD_LYDSPOR_3824, - - /* Maximillian Sackville - Near Wilderness bounty-hunter area. */ - NPCs.BANKER_6538 - ) - - val NPC_IDS = intArrayOf( - NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497, - NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164, - NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198, - NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776, - NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533, - NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605, - NPCs.GUNDAI_902, - - NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619, - ) - - private val ALL_BANKER_NPC_IDS = intArrayOf( - *SPECIAL_NPC_IDS, - *NPC_IDS - ) - /** * This is poorly named, but performs a few checks to see if the player * is trying to access the bank on the Lunar Isle and returns a boolean * controlling whether or not to pass the quick bank or collection use. - * - * TODO - * The location of this method is shit too. Find a better place for it? */ fun checkLunarIsleRestriction(player: Player, node: Node): Boolean { if (node.location.regionId != LUNAR_ISLE_BANK_REGION) @@ -121,37 +113,35 @@ class BankerNPC : AbstractNPC, InteractionListener { private fun provideDestinationOverride(entity: Entity, node: Node): Location { val npc = node as NPC - return when(npc.id) { /* Ogress bankers are 2x2 with their spawn being offset to south-western tile. */ - NPCs.OGRESS_BANKER_7049, - NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0) - - NPCs.BANKER_6532, NPCs.BANKER_6533, - NPCs.BANKER_6534, NPCs.BANKER_6535 -> npc.location.transform(npc.direction, 1) - + NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0) /* Magnus has no bank booth nearby so we need to handle that edge case here. */ NPCs.MAGNUS_GRAM_5488 -> npc.location.transform(Direction.NORTH, 2) - + /* Special-cased NPCs, idk why */ + NPCs.BANKER_6532, NPCs.BANKER_6533, NPCs.BANKER_6534, NPCs.BANKER_6535 -> npc.location.transform(npc.direction, 1) else -> { if (npc is BankerNPC) { npc.findAdjacentBankBoothLocation()?.let { return it.second } } - return npc.location } } } override fun defineListeners() { - on(ALL_BANKER_NPC_IDS, IntType.NPC, "bank", handler = Companion::attemptBank) - on(ALL_BANKER_NPC_IDS, IntType.NPC, "collect", handler = Companion::attemptCollect) + on(NPC_IDS, IntType.NPC, "bank", handler = Companion::attemptBank) + on(NPC_IDS, IntType.NPC, "collect", handler = Companion::attemptCollect) + on(NPC_IDS, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, BankerDialogueLabellerFile(), node as NPC) + return@on true + } } override fun defineDestinationOverrides() { - setDest(IntType.NPC, ALL_BANKER_NPC_IDS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride) + setDest(IntType.NPC, NPC_IDS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride) } override fun init() { @@ -167,5 +157,167 @@ class BankerNPC : AbstractNPC, InteractionListener { } } - override fun getIds(): IntArray = ALL_BANKER_NPC_IDS + class BankerDialogueLabellerFile : DialogueLabeller() { + val BANKERS_WITH_EXTRA_OPTION = intArrayOf(NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, NPCs.BANKER_6538) + + override fun addConversation() { + exec { player, npc -> + if (npc.id == NPCs.SIRSAL_BANKER_4519 && !hasSealOfPassage(player)) { + loadLabel(player, "no seal of passage") + } + if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + if (npc.id == NPCs.JADE_4296) loadLabel(player, "uim for jade") + loadLabel(player, "uim") + } + if (npc.id == NPCs.JADE_4296) loadLabel(player, "hello for jade") + loadLabel(player, "hello") + } + label("no seal of passage") + npc(ChatAnim.ANNOYED, "What are you doing here, Fremennik?!") + player(ChatAnim.WORRIED, "I have a Seal of Pass...") + npc(ChatAnim.ANGRY, "No you don't! Begone!") + // todo: kick them out, but only one of the two banker types should do so (see historical wiki) + goto("nowhere") + label("uim for jade") + npc(ChatAnim.ANNOYED, "Greetings, warrior. I wish I could help you, but our services are not available for Ultimate Iron@g[men,women].") + goto("nowhere") + label("uim") + npc(ChatAnim.ANNOYED, "My apologies, dear @g[sir,madam], our services are not available for Ultimate Iron@g[men,women]") + goto("nowhere") + label("hello for jade") + npc("Greetings warrior, how may I help you?") + exec { player, _ -> loadLabel(player, if (hasAwaitingGrandExchangeCollections(player)) "ge collect" else "main options") } + label("hello") + npc("Good day, would you like to access your bank account?") + exec { player, _ -> loadLabel(player, if (hasAwaitingGrandExchangeCollections(player)) "ge collect" else "main options") } + label("ge collect") + npc("Before we go any further, I should inform you that you have items ready for collection from the Grand Exchange.") + goto("main options") + + label("main options") + options( + DialogueOption("how to use", "How do I use the bank?") { _, npc -> return@DialogueOption npc.id == NPCs.BANK_TUTOR_4907 }, + DialogueOption("who is the bounty hunter banker", "Who are you?") { _, npc -> return@DialogueOption npc.id == NPCs.BANKER_6538 }, + DialogueOption("access", "I'd like to access my bank account please.", expression = ChatAnim.ASKING), + DialogueOption("buy second bank", "I'd like to open a secondary bank account.") { player, _ -> return@DialogueOption ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player) }, + DialogueOption("switch second bank", "I'd like to switch to my primary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && isUsingSecondaryBankAccount(player) }, + DialogueOption("switch second bank", "I'd like to switch to my secondary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && !isUsingSecondaryBankAccount(player) }, + DialogueOption("pin", "I'd like to check my PIN settings."), + DialogueOption("collect", "I'd like to collect items."), + DialogueOption("what is this place", "What is this place?") { _, npc -> return@DialogueOption npc.id !in BANKERS_WITH_EXTRA_OPTION }, + DialogueOption("jade's employment history", "How long have you worked here?") { _, npc -> return@DialogueOption npc.id == NPCs.JADE_4296 }, + DialogueOption("is the bounty hunter banker afraid", "Aren't you afraid of working in the Wilderness?") { _, npc -> return@DialogueOption npc.id == NPCs.BANKER_6538 && !ServerConstants.SECOND_BANK } + ) + + label("how to use") + options( + DialogueOption("using bank", "Using the bank itself.", "Using the bank itself. I'm not sure how....?"), + DialogueOption("using deposit", "Using bank deposit boxes.", "Using Bank deposit boxes.... what are they?"), + DialogueOption("using PIN", "What's this PIN thing that people keep talking about?", "What's this PIN thing that people keep talking about?"), + DialogueOption("nowhere", "Goodbye.") + ) + + label("using bank") + npc("Speak to any banker and ask to see your bank", "account. If you have set a PIN you will be asked for", "it, then all the belongings you have placed in the bank", "will appear in the window. To withdraw one item, left-") + npc("click on it once.") + npc("To withdraw many, right-click on the item and select", "from the menu. The same for depositing, left-click on", "the item in your inventory to deposit it in the bank.", "Right-click on it to deposit many of the same items.") + npc("To move things around in your bank: firstly select", "Swap or Insert as your default moving mode, you can", "find these buttons on the bank window itself. Then click", "and drag an item to where you want it to appear.") + npc("You may withdraw 'notes' or 'certificates' when the", "items you are trying to withdraw do not stack in your", "inventory. This will only work for items which are", "tradeable.") + npc("For instance, if you wanted to sell 100 logs to another", "player, they would not fit in one inventory and you", "would need to do multiple trades. Instead, click the", "Note button to withdraw the logs as 'certs' or 'notes'") + npc("then withdraw the items you need.") + goto("how to use") + + label("using deposit") + npc("They look like grey pillars, there's one just over there,", "near the desk. Bank deposit boxes save so much time.", "If you're simply wanting to deposit a single item, 'Use'", "it on the deposit box.") + npc("Otherwise, simply click once on the box and it will give", "you a choice of what to deposit in an interface very", "similar to the bank itself. Very quick for when you're", "simply fishing or mining etc.") + goto("how to use") + + label("using PIN") + npc("The PIN - Personal Identification Number - can be", "set on your bank account to protect the items there in", "case someone finds out your account password. It", "consists of four numbers that you remember and tell") + npc("no one.") + npc("So if someone did manage to get your password they", "couldn't steal your items if they were in the bank.") + goto("how to use") + + label("who is the bounty hunter banker") + npc(ChatAnim.NEUTRAL, "How inconsiderate of me, dear @g[sir,madam]. My name is Maximillian Sackville and I conduct operations here on behalf of The Bank of Gielinor.") + goto("main options") + + label("access") + exec { player, _ -> openBankAccount(player) } + goto("nowhere") + + label("buy second bank") + npc("Certainly. We offer secondary accounts to all our customers.") + npc("The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable and account activation is permanent.") + npc("If your inventory does not contain enough money to cover the costs, we will complement the amount with the money inside your primary bank account.") + npc("Knowing all this, would you like to proceed with opening your secondary bank account?") + options( + DialogueOption("buy second bank yes", "Yes, I am still interested.", expression = ChatAnim.HAPPY), + DialogueOption("buy second bank no", "Actually, I've changed my mind.", expression = ChatAnim.ANNOYED) + ) + + label("buy second bank yes") + exec { player, _ -> loadLabel(player, when (activateSecondaryBankAccount(player)) { + SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> "already" + SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> "failure" + SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> "not enough cash" + SecondaryBankAccountActivationResult.SUCCESS -> "success" + }) } + label("already") + npc(ChatAnim.FRIENDLY, "Your bank account was already activated, there is no need to pay twice.") + goto("main options") + label("failure") + npc(ChatAnim.ANNOYED, "I must apologize, the transaction was not successful. Please check your primary bank account and your inventory - if there's money missing, please screenshot your chatbox and contact the game developers.") + goto("main options") + label("not enough cash") + npc(ChatAnim.ANNOYED, "It appears that you do not have the money necessary to cover the costs associated with opening a secondary bank account. I will be waiting here until you do.") + goto("main options") + label("success") + npc(ChatAnim.FRIENDLY, "Your secondary bank account has been opened and can be accessed through any of the Bank of Gielinor's employees. Thank you for choosing our services.") + goto("main options") + + label("buy second bank no") + npc("Very well. Should you decide a secondary bank account is needed, do not hesitate to contact any of the Bank of Gielinor's stationary employees. We will be happy to help.") + goto("main options") + + label("switch second bank") + exec { player, _ -> + toggleBankAccount(player) + loadLabel(player, if (isUsingSecondaryBankAccount(player)) "now secondary" else "now primary") + } + label("now primary") + npc("Your active bank account has been switched. You can now access your primary account.") + goto("main options") + label("now secondary") + npc("Your active bank account has been switched. You can now access your secondary account.") + goto("main options") + + label("pin") + exec { player, _ -> openBankPinSettings(player) } + goto("nowhere") + + label("collect") + exec { player, _ -> openGrandExchangeCollectionBox(player) } + goto("nowhere") + + label("what is this place") + npc("This is a branch of the Bank of Gielinor. We have branches in many towns.") + player("And what do you do?") + npc("We will look after your items and money for you. Leave your valuables with us if you want to keep them safe.") + goto("main options") + + label("jade's employment history") + npc(ChatAnim.FRIENDLY, "Oh, ever since the Guild opened. I like it here.") + player(ChatAnim.ASKING, "Why's that?") + npc(ChatAnim.FRIENDLY, "Well... what with all these warriors around, there's not much chance of my bank being robbed, is there?") + goto("nowhere") + + label("is the bounty hunter banker afraid") + npc(ChatAnim.NEUTRAL, "While the Wilderness is quite a dangerous place, The Bank of Gielinor offers us - roving bankers - extraordinary benefits for our hard work in hazardous environments.") + npc(ChatAnim.NEUTRAL, "This allows us to provide our services to customers regardless of their current whereabouts. Our desire to serve is stronger than our fear of the Wilderness.") + goto("nowhere") + } + } + + override fun getIds(): IntArray = NPC_IDS } diff --git a/Server/src/main/content/global/handlers/npc/ChinchompaDeathListener.kt b/Server/src/main/content/global/handlers/npc/ChinchompaDeathListener.kt new file mode 100644 index 000000000..3a146eaf4 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/ChinchompaDeathListener.kt @@ -0,0 +1,52 @@ +package content.global.handlers.npc + +import core.api.* +import core.api.playGlobalAudio +import core.api.sendGraphics +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPCBehavior +import org.rs09.consts.NPCs +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.tools.RandomFunction +import core.game.world.update.flag.context.Graphics +import core.game.node.entity.combat.ImpactHandler.HitsplatType; + +private val chinchompaIDs = intArrayOf( + NPCs.CHINCHOMPA_5079, + NPCs.CARNIVOROUS_CHINCHOMPA_5080 +) + +/** + * Minimal evasive approach to the Chinchompas exploding on death cause by combat and not by trapping. + */ +class ChinchompaDeathListener: NPCBehavior(*chinchompaIDs) { + override fun onDeathFinished(self: NPC, killer: Entity) { + + // If it 'died' from getting trapped an attribute is set of 'hunter'. + if (!self.attributes.containsKey("hunter") && killer is Player) { + val explosionLoc = self.location + val validExplosionDmgTiles = explosionLoc.surroundingTiles + + val chinExplosionGFX = Graphics(157, 96) + sendGraphics(chinExplosionGFX, explosionLoc) + playGlobalAudio(explosionLoc, 158) + + if (validExplosionDmgTiles.contains(killer.location)) { + //As weird this looks, it does allow to have a hit from 0 to 2 + val hitAmount = RandomFunction.random(0, 3) + impact(killer, hitAmount, HitsplatType.NORMAL) + } + } + } + + /** + * At content.global.skill.hunter.TrapSetting + * sets an attribute of 'hunter' during it's getCatchPulse for reward rolling, but it never cleans it up after. + * These NPCs is a member of NPC class although exists a HunterNPC class, but it's mainly used for imps. + * Logically you'd do this after death finishes, but it would interfere with the reward rolls and I fear it may affect other hunter NPCs. + */ + override fun onRespawn(self: NPC) { + self.removeAttribute("hunter") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/npc/DecantListener.kt b/Server/src/main/content/global/handlers/npc/DecantListener.kt index 9a63c78c2..368835e32 100644 --- a/Server/src/main/content/global/handlers/npc/DecantListener.kt +++ b/Server/src/main/content/global/handlers/npc/DecantListener.kt @@ -1,6 +1,7 @@ package content.global.handlers.npc import content.data.consumables.Consumables +import content.global.skill.cooking.fermenting.CalquatDecant import core.api.* import core.game.consumable.Potion import core.game.dialogue.DialogueFile @@ -14,23 +15,39 @@ class DecantListener : InteractionListener { companion object { val potions = Consumables.potions.toIntArray() + val decantables = potions + CalquatDecant.allKegIds } override fun defineListeners() { on(IntType.NPC,"decant"){ player, node -> - val (toRemove, toAdd) = decantContainer(player.inventory) - for (item in toRemove) - removeItem(player, item) - for (item in toAdd) + // Decant potions + val (potionRemove, potionAdd) = decantContainer(player.inventory) + for (item in potionRemove) + if (!removeItem(player, item)) { return@on false } + for (item in potionAdd) addItem(player, item.id, item.amount) + + // Decant kegs + val (kegRemove, kegAdd) = CalquatDecant.decantCalquat(player.inventory) + for (item in kegRemove) + if (!removeItem(player, item)) { return@on false } + for (item in kegAdd) + addItem(player, item.id, item.amount) + player.dialogueInterpreter.open(DecantingDialogue(),node.asNpc()) return@on true } - onUseWith(IntType.ITEM, potions, *potions) { player, used, with -> + onUseWith(IntType.ITEM, decantables, *decantables) { player, used, with -> if (used !is Item) return@onUseWith false if (with !is Item) return@onUseWith false + // Check if these are kegs - handle with CalquatDecant + if (CalquatDecant.isKeg(used.id) || CalquatDecant.isKeg(with.id)) { + return@onUseWith CalquatDecant.combineKegs(player, used, with) + } + + // Otherwise handle as potions // Verify these are both the same potion types val potionUsed = Consumables.getConsumableById(used.id)?.consumable as? Potion ?: return@onUseWith false val potionWith = Consumables.getConsumableById(with.id)?.consumable as? Potion ?: return@onUseWith false @@ -83,6 +100,57 @@ class DecantListener : InteractionListener { return@onUseWith true } + + // Decant keg into beer glass + onUseWith(IntType.ITEM, Items.BEER_GLASS_1919, *CalquatDecant.allKegIds) { player, used, with -> + if (used !is Item || with !is Item) return@onUseWith false + + // Determine which is the glass and which is the keg + val (glass, keg) = if (used.id == Items.BEER_GLASS_1919) { + used to with + } else { + with to used + } + + return@onUseWith CalquatDecant.pourIntoGlass(player, glass, keg) + } + + // Barbarian decanting: use a 4-dose potion and an empty vial together to make two 2-dose potions + onUseWith(IntType.ITEM, potions, Items.VIAL_229) { player, used, with -> + // Check if player has started barbarian herblore training + if (getAttribute(player, "/save:barbtraining:herblore", 0) == 0) { + return@onUseWith false + } + + if (used !is Item) return@onUseWith false + if (with !is Item) return@onUseWith false + + // Determine which item is the potion and which is the vial + val (potionItem) = if (used.id == Items.VIAL_229) { + Pair(with, used) + } else { + Pair(used, with) + } + + // Check if the potion is 4 doses + val potion = Consumables.getConsumableById(potionItem.id)?.consumable as? Potion ?: return@onUseWith false + val dose = potion.getDose(potionItem) + + if (dose != 4) { + return@onUseWith false + } + + // Get the 2-dose version of this potion by index + val twoDoseId = potion.ids[2] + + // Replace ingredients with products + replaceSlot(player, with.slot, Item(twoDoseId)) + replaceSlot(player, used.slot, Item(twoDoseId)) + + playAudio(player, 2401) + + return@onUseWith true + } } internal class DecantingDialogue : DialogueFile(){ diff --git a/Server/src/main/content/global/handlers/npc/GuardNPC.java b/Server/src/main/content/global/handlers/npc/GuardNPC.java index ccdf7e10d..9cde38cc7 100644 --- a/Server/src/main/content/global/handlers/npc/GuardNPC.java +++ b/Server/src/main/content/global/handlers/npc/GuardNPC.java @@ -15,7 +15,7 @@ public final class GuardNPC extends AbstractNPC { /** * The NPC ids of NPCs using this plugin. */ - private static final int[] ID = { 9, 32, 163, 164, 196, 197, 206, 253, 254, 255, 256, 274, 275, 296, 298, 299, 447, 448, 449, 489, 609, 678, 799, 837, 842, 862, 870, 877, 917, 1200, 1203, 1204, 1317, 1710, 1711, 1712, 2073, 2074, 2134, 2135, 2136, 2236, 2571, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 3715, 4257, 4258, 4259, 4260, 4307, 4308, 4309, 4310, 4311, 4336, 4375, 4603, 4604, 4605, 4606, 5800, 5801, 5919, 5920 }; + private static final int[] ID = { 9, 32, 163, 164, 196, 197, 206, 253, 254, 255, 256, 274, 275, 296, 298, 299, 447, 448, 449, 609, 678, 799, 837, 842, 862, 870, 877, 917, 1200, 1203, 1204, 1317, 1710, 1711, 1712, 2073, 2074, 2134, 2135, 2136, 2236, 2571, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 3715, 4257, 4258, 4259, 4260, 4307, 4308, 4309, 4310, 4311, 4336, 4375, 4603, 4604, 4605, 4606, 5800, 5801, 5919, 5920 }; /** * Constructs a new {@code GuardNPC} {@code Object}. diff --git a/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt b/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt index 5235fc82a..4f5764b0d 100644 --- a/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt +++ b/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt @@ -12,6 +12,7 @@ import core.game.system.timer.impl.AntiMacro import core.game.worldevents.holiday.HolidayRandomEventNPC import core.game.worldevents.holiday.HolidayRandomEvents import core.game.worldevents.holiday.HolidayRandoms +import org.rs09.consts.NPCs /** * Handles the NPC talk-to option. @@ -37,11 +38,18 @@ class NPCTalkListener : InteractionListener { val npc = node.asNpc() if(RandomEvents.randomIDs.contains(node.id)){ if(AntiMacro.getEventNpc(player) == null || AntiMacro.getEventNpc(player) != node.asNpc() || AntiMacro.getEventNpc(player)?.finalized == true) { - player.sendMessage("They aren't interested in talking to you.") + // Why the fuck is this here of all places? Now look at what you've made me do: + if (npc.id == NPCs.SANDWICH_LADY_3117) { + // https://www.youtube.com/watch?v=ek8r3ZS929E + player.dialogueInterpreter.sendDialogue("The sandwich lady doesn't seem interested in selling you any", "refreshments.") + } else { + sendMessage(player, "They aren't interested in talking to you.") + } } else { AntiMacro.getEventNpc(player)?.talkTo(node.asNpc()) } return@on true + //TODO bring sanity here } if (HolidayRandomEvents.holidayRandomIDs.contains(node.id) && node is HolidayRandomEventNPC) { if(HolidayRandoms.getEventNpc(player) == null || HolidayRandoms.getEventNpc(player) != node.asNpc() || HolidayRandoms.getEventNpc(player)?.finalized == true) { @@ -79,4 +87,4 @@ class NPCTalkListener : InteractionListener { return@on player.dialogueInterpreter.open(npc.id, npc) } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/handlers/npc/RatNPC.java b/Server/src/main/content/global/handlers/npc/RatNPC.java index 11f4fce94..f8a380db4 100644 --- a/Server/src/main/content/global/handlers/npc/RatNPC.java +++ b/Server/src/main/content/global/handlers/npc/RatNPC.java @@ -7,6 +7,7 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.plugin.Initializable; import core.game.world.map.Location; +import content.data.Quests; /** * Represents a rat npc. @@ -51,7 +52,7 @@ public class RatNPC extends AbstractNPC { super.finalizeDeath(killer); if (killer instanceof Player) { final Player p = ((Player) killer); - if (p.getQuestRepository().getQuest("Witch's Potion").isStarted(p)) { + if (p.getQuestRepository().getQuest(Quests.WITCHS_POTION).isStarted(p)) { GroundItemManager.create(RAT_TAIL, getLocation(), p); } } diff --git a/Server/src/main/content/global/handlers/npc/SheepBehavior.kt b/Server/src/main/content/global/handlers/npc/SheepBehavior.kt index d9767f8a4..c6ed46374 100644 --- a/Server/src/main/content/global/handlers/npc/SheepBehavior.kt +++ b/Server/src/main/content/global/handlers/npc/SheepBehavior.kt @@ -17,6 +17,7 @@ import org.rs09.consts.NPCs import org.rs09.consts.Sounds import core.game.world.map.Location import core.game.world.map.Direction +import content.data.Quests private val sheepIds = intArrayOf( NPCs.SHEEP_42, @@ -74,7 +75,7 @@ class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener { val sheep = node as NPC sheep.faceTemporary(player, 1) if (sheep.id == NPCs.SHEEP_3579) { - if (player.questRepository.getQuest("Sheep Shearer").isStarted(player)) { + if (player.questRepository.getQuest(Quests.SHEEP_SHEARER).isStarted(player)) { setAttribute(player, ATTR_IS_PENGUIN_SHEEP_SHEARED, true) } animate(player, Animation(893)) @@ -104,8 +105,10 @@ class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener { sheep.locks.lockMovement(2) sheep.transform(NPCs.SHEEP_5153) playAudio(player, Sounds.SHEAR_SHEEP_761) + if (!addItem(player, Items.WOOL_1737)) { // 5160 + return@on false + } sendMessage(player, "You get some wool.") - addItem(player, Items.WOOL_1737) // 5160 GameWorld.Pulser.submit(object : Pulse(80, sheep) { override fun pulse(): Boolean { sheep.reTransform() @@ -126,9 +129,9 @@ class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener { val sheepDirection = Direction.getDirection(sheepLocation, playerLocation) // Get direction sheep is facing, from the player's location val sheepOppositeDirection = sheepDirection.getOpposite() // Switch to opposite direction - val xWalkLocation = sheepLocation.getX() + (sheepOppositeDirection.getStepX() * 3) // Gets x location, if set, 3 steps away from player - val yWalkLocation = sheepLocation.getY() + (sheepOppositeDirection.getStepY() * 3) // Gets y location, if set, 3 steps away from player - val sheepWalkToLocation = Location(xWalkLocation, yWalkLocation, sheepLocation.getZ()); // New location for pathfinding + val xWalkLocation = sheepLocation.x + (sheepOppositeDirection.getStepX() * 3) // Gets x location, if set, 3 steps away from player + val yWalkLocation = sheepLocation.y + (sheepOppositeDirection.getStepY() * 3) // Gets y location, if set, 3 steps away from player + val sheepWalkToLocation = Location(xWalkLocation, yWalkLocation, sheepLocation.z); // New location for pathfinding sendMessage(player, messagePlayer) diff --git a/Server/src/main/content/global/handlers/npc/ShooAwayStrayDogListener.kt b/Server/src/main/content/global/handlers/npc/ShooAwayStrayDogListener.kt new file mode 100644 index 000000000..e159f89ab --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/ShooAwayStrayDogListener.kt @@ -0,0 +1,80 @@ +package content.global.handlers.npc + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.NPCs +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.update.flag.context.Animation +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import org.rs09.consts.Animations +import org.rs09.consts.Sounds + +private val strayDogsIds = intArrayOf( + NPCs.STRAY_DOG_4766, + NPCs.STRAY_DOG_4767, + NPCs.STRAY_DOG_5917, + NPCs.STRAY_DOG_5918 +) + +/** + * Represents the option Listener used to 'shoo-away' a stray dog. + * Convert from legacy plugin src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java + * @author Vexia + beckrickert + * + */ +class ShooAwayStrayDogListener : NPCBehavior(*strayDogsIds), InteractionListener { + override fun defineListeners() { + + on(strayDogsIds,IntType.NPC, "shoo-away") { player, node -> + + val theDog = node as NPC + + //Pause dog location + lock(theDog, 2) + stopWalk(theDog) + theDog.faceTemporary(player, 1) + + sendChat(player,"Thbbbbt!") + animate(player, Animations.HUMAN_BLOW_RASPBERRY_2110) + + //Dog whine sound + playAudio(player, Sounds.WOLF_DEATH_911) + sendChat(theDog,"Whine!") + + //Dog whine kneeling down animation + animate(theDog, Animation(4774)) + + //run away from player + dogWhineRunAway(player, theDog) + + return@on true + } + } +} + +fun dogWhineRunAway(player: Player, theDog: NPC) { + val playerCurLoc = player.getLocation() + val dogCurLoc = theDog.getLocation() + + //Get dog direction is facing from player's location + val dogDirection = Direction.getDirection(dogCurLoc, playerCurLoc) + val dogDirectionOpp = dogDirection.opposite + + val xWalkLoc = dogCurLoc.x + (dogDirectionOpp.stepX * 12) + val yWalkLoc = dogCurLoc.y + (dogDirectionOpp.stepY * 12) + val dogWalkToNewLoc = Location(xWalkLoc, yWalkLoc, dogCurLoc.z) + + //unlock entity movement so it can run away + unlock(theDog) + + //allow to "moon-walk" to the new location + //Does weird stuff or ignores this when in 'following' mode + //theDog.face(player) + + forceWalk(theDog, dogWalkToNewLoc, "dumb") + +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/scenery/DoogleLeafPlugin.java b/Server/src/main/content/global/handlers/scenery/DoogleLeafPlugin.java deleted file mode 100644 index 99da19d9c..000000000 --- a/Server/src/main/content/global/handlers/scenery/DoogleLeafPlugin.java +++ /dev/null @@ -1,39 +0,0 @@ -package content.global.handlers.scenery; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the doogle leaf plugin for this object. - * @author 'Vexia - * @version 1.0 - */ -public class DoogleLeafPlugin extends OptionHandler { - - /** - * Represents the leaf item. - */ - private static final Item LEAF = new Item(1573, 1); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(31155).getHandlers().put("option:pick-leaf", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - if (!player.getInventory().add(LEAF)) { - player.getPacketDispatch().sendMessage("You don't have have enough space in your inventory."); - } else { - player.getPacketDispatch().sendMessage("You pick some doogle leaves."); - } - return true; - } - -} diff --git a/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java b/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java index 295badfd8..b6d18c0fa 100644 --- a/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java +++ b/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java @@ -11,6 +11,9 @@ import core.game.world.map.Location; import core.game.world.map.RegionManager; import core.plugin.Initializable; import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; /** * Plugin used for handling the opening/closing of (double) @@ -39,6 +42,14 @@ public final class DoorManagingPlugin extends OptionHandler { if (name.contains("drawers") || name.contains("wardrobe") || name.contains("cupboard")) { switch(option) { case "open": + if (name.contains("drawers")) { + playAudio(player, Sounds.DRAWER_OPEN_64); + } else if (name.contains("wardrobe")) { + animate(player, 545, false); + playAudio(player, Sounds.WARDROBE_OPEN_96); + } else if (name.contains("cupboard")) { + playAudio(player, Sounds.CUPBOARD_OPEN_58); + } case "go-through": if (object.isActive()) { SceneryBuilder.replace(object, object.transform(object.getId() + 1), 80); @@ -46,6 +57,14 @@ public final class DoorManagingPlugin extends OptionHandler { return true; case "close": case "shut": + if (name.contains("drawers")) { + playAudio(player, Sounds.DRAWER_CLOSE_63); + } else if (name.contains("wardrobe")) { + animate(player, 544, false); + playAudio(player, Sounds.WARDROBE_CLOSE_95); + } else if (name.contains("cupboard")) { + playAudio(player, Sounds.CUPBOARD_CLOSE_57); + } SceneryBuilder.replace(object, object.transform(object.getId() - 1)); return true; } diff --git a/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java b/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java index 307c09b20..1d0fa5c07 100644 --- a/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java +++ b/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java @@ -72,7 +72,7 @@ public final class FieldPickingPlugin extends OptionHandler { player.dispatch(new ResourceProducedEvent(reward.getId(), reward.getAmount(), node, -1)); if (plant.name().startsWith("NETTLES") && (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) == null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null && !player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getName().contains("glove"))) { player.getPacketDispatch().sendMessage("You have been stung by the nettles!"); - player.getImpactHandler().manualHit(player, 2, HitsplatType.POISON); + player.getImpactHandler().manualHit(player, 6, HitsplatType.POISON); return true; } if (plant.respawn != -1 && plant != PickingPlant.FLAX) { diff --git a/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java b/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java index 0cb9a6500..9712fe790 100644 --- a/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java +++ b/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java @@ -23,6 +23,8 @@ public final class LadderManagingPlugin extends OptionHandler { SceneryDefinition.setOptionHandler("climb-up", this); SceneryDefinition.setOptionHandler("climb-down", this); SceneryDefinition.setOptionHandler("climb", this); + SceneryDefinition.setOptionHandler("walk-up", this); + SceneryDefinition.setOptionHandler("walk-down", this); return this; } diff --git a/Server/src/main/content/global/handlers/scenery/MillingListener.kt b/Server/src/main/content/global/handlers/scenery/MillingListener.kt index c61a8c82a..f88132cc1 100644 --- a/Server/src/main/content/global/handlers/scenery/MillingListener.kt +++ b/Server/src/main/content/global/handlers/scenery/MillingListener.kt @@ -85,13 +85,15 @@ class MillingListener : InteractionListener { if (removeItem(player, EMPTY_POT)) { if (getAttribute(player, "milling:sweetcorn", 0) > 0) { setAttribute(player, "/save:milling:sweetcorn", (getAttribute(player, "milling:sweetcorn", 0) - 1)) - addItem(player, POT_OF_CORNFLOUR) - sendMessage(player, if (player.getAttribute("milling:sweetcorn", 0) > 0) "You fill a pot with cornflour from the bin." else "You fill a pot with the last of the cornflour in the bin.") + if (addItem(player, POT_OF_CORNFLOUR)) { + sendMessage(player, if (player.getAttribute("milling:sweetcorn", 0) > 0) "You fill a pot with cornflour from the bin." else "You fill a pot with the last of the cornflour in the bin.") + } } else if (getAttribute(player, "milling:grain", 0) > 0) { setAttribute(player, "/save:milling:grain", (getAttribute(player, "milling:grain", 0) - 1)) - addItem(player, POT_OF_FLOUR) - sendMessage(player, if (player.getAttribute("milling:grain", 0) > 0) "You fill a pot with flour from the bin." else "You fill a pot with the last of the flour in the bin.") + if (addItem(player, POT_OF_FLOUR)) { + sendMessage(player, if (player.getAttribute("milling:grain", 0) > 0) "You fill a pot with flour from the bin." else "You fill a pot with the last of the flour in the bin.") + } } if (getAttribute(player, "milling:sweetcorn", 0) + getAttribute(player, "milling:grain", 0) <= 0) { setVarp(player, VARP, 0, true) diff --git a/Server/src/main/content/global/handlers/scenery/SignpostListener.kt b/Server/src/main/content/global/handlers/scenery/SignpostListener.kt index 837462159..583aa259d 100644 --- a/Server/src/main/content/global/handlers/scenery/SignpostListener.kt +++ b/Server/src/main/content/global/handlers/scenery/SignpostListener.kt @@ -11,18 +11,21 @@ class SignpostListener : InteractionListener { override fun defineListeners() { on(Scenery.SIGNPOST_18493, IntType.SCENERY, "read") { player, node -> if (node.asScenery().location.equals(Location(3235, 3228))) { + // Authentic setInterfaceText(player, "Head north towards Fred's farm, and the windmill.", 135, 3) // North setInterfaceText(player, "South to the swamps of Lumbridge.", 135, 9) // South setInterfaceText(player, "Cross the bridge and head east to Al Kharid or north to Varrock.", 135, 8) // East setInterfaceText(player, "West to the Lumbridge Castle and Draynor Village. Beware the goblins!", 135, 12) // West openInterface(player, Components.AIDE_COMPASS_135) } else if (node.asScenery().location.equals(Location(3261, 3230))) { + // Authentic setInterfaceText(player, "North to farms and Varrock.", 135, 3) // North setInterfaceText(player, "The River Lum lies to the south.", 135, 9) // South setInterfaceText(player, "East to Al Kharid - toll gate; bring some money.", 135, 8) // East setInterfaceText(player, "West to Lumbridge.", 135, 12) // West openInterface(player, Components.AIDE_COMPASS_135) } else if (node.asScenery().location.equals(Location(2983, 3278))) { + // Authentic setInterfaceText(player, "North to the glorious White Knights' city of Falador.", 135, 3) // North setInterfaceText(player, "South to Rimmington.", 135, 9) // South setInterfaceText(player, "East to Port Sarim and Draynor Village.", 135, 8) // East @@ -45,12 +48,14 @@ class SignpostListener : InteractionListener { } on(Scenery.SIGNPOST_24263, IntType.SCENERY, "read") { player, node -> if (node.asScenery().location.equals(Location(3268, 3332))) { + // Authentic setInterfaceText(player, "Sheep lay this way.", 135, 3) // North setInterfaceText(player, "South through farms to Al Kharid and Lumbridge.", 135, 9) // South setInterfaceText(player, "East to Al Kharid mine and follow the path north to Varrock east gate.", 135, 8) // East setInterfaceText(player, "West to Champion's Guild and Varrock south gate.", 135, 12) // West openInterface(player, Components.AIDE_COMPASS_135) } else if (node.asScenery().location.equals(Location(3283, 3333))) { + // Authentic setInterfaceText(player, "North to Varrock mine and Varrock east gate.", 135, 3) // North setInterfaceText(player, "South to large Mining area and Al Kharid.", 135, 9) // South setInterfaceText(player, "Follow the path east to the Dig Site.", 135, 8) // East @@ -66,7 +71,13 @@ class SignpostListener : InteractionListener { return@on true } on(Scenery.SIGNPOST_4132, IntType.SCENERY, "read") { player, node -> - if (node.asScenery().location.equals(Location(3166, 3286))) { + if (node.asScenery().location.equals(Location(3223, 3427))) { + setInterfaceText(player, "North to Varrock Palace.", 135, 3) // North + setInterfaceText(player, "South to the Champion's Guild.", 135, 9) // South + setInterfaceText(player, "East to the Dig Site.", 135, 8) // East + setInterfaceText(player, "West to Barbarian Village and Falador.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3166, 3286))) { setInterfaceText(player, "North to the windmill.", 135, 3) // North setInterfaceText(player, "South to a fishing pond next to Fred's farm.", 135, 9) // South setInterfaceText(player, "East to Lumbridge.", 135, 8) // East @@ -133,6 +144,56 @@ class SignpostListener : InteractionListener { } return@on true } + on(Scenery.SIGNPOST_4135, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3448, 3486))) { + setInterfaceText(player, "North to the Slayer Tower.", 135, 3) // North + setInterfaceText(player, "South to Mort Myre Swamp.", 135, 9) // South + setInterfaceText(player, "East to Canifis.", 135, 8) // East + setInterfaceText(player, "West to Varrock.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.SIGNPOST_31296, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3304, 3109))) { + // Authentic + setInterfaceText(player, "North to Al Kharid.", 135, 3) // North + setInterfaceText(player, "South to the Desert Mining Camp and Pollnivneach.", 135, 9) // South + setInterfaceText(player, "East and across the river to the Ruins of Uzer.", 135, 8) // East + setInterfaceText(player, "West to the Kalphite Lair.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.STONE_SIGNPOST_11630, IntType.SCENERY, "read") { player, node -> + // Authentic // https://youtu.be/vvHXKTOh_g4 + if (node.asScenery().location.equals(Location(2967, 3412))) { + setInterfaceText(player, "North to Goblin Village.", 135, 3) // North + setInterfaceText(player, "South to Falador.", 135, 9) // South + setInterfaceText(player, "East to Varrock.", 135, 8) // East + setInterfaceText(player, "West to Taverley.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } } /** * Old handlers of Signpost. Not all should be opening the AIDE_COMPASS. diff --git a/Server/src/main/content/global/handlers/scenery/TableListener.kt b/Server/src/main/content/global/handlers/scenery/TableListener.kt new file mode 100644 index 000000000..c35ebd27b --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/TableListener.kt @@ -0,0 +1,426 @@ +package content.global.handlers.scenery + +import content.global.skill.summoning.pet.Pets +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.graves.GraveController +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor +import core.game.node.entity.player.info.login.PlayerParser +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.config.ItemConfigParser +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +/** To allow players to place items on tables. Copies DropListener for restrictions. */ +class TableListener : InteractionListener { + companion object { + private val DROP_COINS_SOUND = Sounds.EYEGLO_COIN_10 + private val DROP_ITEM_SOUND = Sounds.PUT_DOWN_2739 + } + override fun defineListeners() { + onUseAnyWith( + IntType.SCENERY, + Scenery.TABLE_10258, + Scenery.TABLE_10414, + Scenery.TABLE_10490, + Scenery.TABLE_10509, + Scenery.TABLE_10808, + Scenery.TABLE_11202, + Scenery.TABLE_11203, + Scenery.TABLE_11500, + Scenery.TABLE_11501, + Scenery.TABLE_11502, + Scenery.TABLE_11503, + Scenery.TABLE_11504, + Scenery.TABLE_11551, + Scenery.TABLE_11619, + Scenery.TABLE_11660, + Scenery.TABLE_11682, + Scenery.TABLE_11743, + Scenery.TABLE_11748, + Scenery.TABLE_11749, + Scenery.TABLE_11849, + Scenery.TABLE_11892, + Scenery.TABLE_12106, + Scenery.TABLE_12108, + Scenery.TABLE_12386, + Scenery.TABLE_12387, + Scenery.TABLE_12388, + Scenery.TABLE_12450, + Scenery.TABLE_12541, + Scenery.TABLE_12544, + Scenery.TABLE_12734, + Scenery.TABLE_12855, + Scenery.TABLE_12884, + Scenery.TABLE_12962, + Scenery.TABLE_12971, + Scenery.TABLE_12972, + Scenery.TABLE_14044, + Scenery.TABLE_14049, + Scenery.TABLE_14163, + Scenery.TABLE_14363, + Scenery.TABLE_14762, + Scenery.TABLE_14763, + Scenery.TABLE_14920, + Scenery.TABLE_15044, + Scenery.TABLE_15092, + Scenery.TABLE_15137, + Scenery.TABLE_15680, + Scenery.TABLE_15684, + Scenery.TABLE_15719, + Scenery.TABLE_15982, + Scenery.TABLE_16169, + Scenery.TABLE_16170, + Scenery.TABLE_16562, + Scenery.TABLE_16737, + Scenery.TABLE_16738, + Scenery.TABLE_16739, + Scenery.TABLE_16740, + Scenery.TABLE_16741, + Scenery.TABLE_16742, + Scenery.TABLE_16815, + Scenery.TABLE_16827, + Scenery.TABLE_16828, + Scenery.TABLE_16874, + Scenery.TABLE_16974, + Scenery.TABLE_17099, + Scenery.TABLE_17145, + Scenery.TABLE_17235, + Scenery.TABLE_17299, + Scenery.TABLE_17348, + Scenery.TABLE_17545, + Scenery.TABLE_17546, + Scenery.TABLE_17661, + Scenery.TABLE_17662, + Scenery.TABLE_17666, + Scenery.TABLE_17762, + Scenery.TABLE_18051, + Scenery.TABLE_18059, + Scenery.TABLE_18062, + Scenery.TABLE_18314, + Scenery.TABLE_18486, + Scenery.TABLE_18902, + Scenery.TABLE_1901, + Scenery.TABLE_19158, + Scenery.TABLE_19928, + Scenery.TABLE_20058, + Scenery.TABLE_20060, + Scenery.TABLE_20351, + Scenery.TABLE_20388, + Scenery.TABLE_20996, + Scenery.TABLE_21359, + Scenery.TABLE_21360, + Scenery.TABLE_21388, + Scenery.TABLE_21389, + Scenery.TABLE_21608, + Scenery.TABLE_21609, + Scenery.TABLE_21610, + Scenery.TABLE_21793, + Scenery.TABLE_22159, + Scenery.TABLE_22160, + Scenery.TABLE_22431, + Scenery.TABLE_22672, + Scenery.TABLE_22677, + Scenery.TABLE_22678, + Scenery.TABLE_22690, + Scenery.TABLE_22693, + Scenery.TABLE_22694, + Scenery.TABLE_22705, + Scenery.TABLE_22830, + Scenery.TABLE_22831, + Scenery.TABLE_22832, + Scenery.TABLE_22844, + Scenery.TABLE_22845, + Scenery.TABLE_22846, + Scenery.TABLE_22847, + Scenery.TABLE_22848, + Scenery.TABLE_22849, + Scenery.TABLE_23177, + Scenery.TABLE_23942, + Scenery.TABLE_24011, + Scenery.TABLE_24012, + Scenery.TABLE_24013, + Scenery.TABLE_24014, + Scenery.TABLE_24028, + Scenery.TABLE_24076, + Scenery.TABLE_24084, + Scenery.TABLE_24088, + Scenery.TABLE_24104, + Scenery.TABLE_24301, + Scenery.TABLE_24302, + Scenery.TABLE_24303, + Scenery.TABLE_24307, + Scenery.TABLE_24308, + Scenery.TABLE_24309, + Scenery.TABLE_24320, + Scenery.TABLE_24335, + Scenery.TABLE_24336, + Scenery.TABLE_24667, + Scenery.TABLE_24684, + Scenery.TABLE_24900, + Scenery.TABLE_24922, + Scenery.TABLE_24927, + Scenery.TABLE_25047, + Scenery.TABLE_25603, + Scenery.TABLE_25615, + Scenery.TABLE_25733, + Scenery.TABLE_25734, + Scenery.TABLE_25778, + Scenery.TABLE_25928, + Scenery.TABLE_25930, + Scenery.TABLE_25931, + Scenery.TABLE_26020, + Scenery.TABLE_26074, + Scenery.TABLE_26142, + Scenery.TABLE_2650, + Scenery.TABLE_26783, + Scenery.TABLE_26807, + Scenery.TABLE_27014, + Scenery.TABLE_27052, + Scenery.TABLE_27056, + Scenery.TABLE_27083, + Scenery.TABLE_27245, + Scenery.TABLE_27850, + Scenery.TABLE_28199, + Scenery.TABLE_28262, + Scenery.TABLE_28508, + Scenery.TABLE_28621, + Scenery.TABLE_28628, + Scenery.TABLE_28629, + Scenery.TABLE_28660, + Scenery.TABLE_2906, + Scenery.TABLE_29131, + Scenery.TABLE_2940, + Scenery.TABLE_29467, + Scenery.TABLE_29468, + Scenery.TABLE_30074, + Scenery.TABLE_30075, + Scenery.TABLE_30076, + Scenery.TABLE_30077, + Scenery.TABLE_30078, + Scenery.TABLE_30079, + Scenery.TABLE_30080, + Scenery.TABLE_30081, + Scenery.TABLE_30222, + Scenery.TABLE_30734, + Scenery.TABLE_30827, + Scenery.TABLE_30828, + Scenery.TABLE_30830, + Scenery.TABLE_30939, + Scenery.TABLE_32121, + Scenery.TABLE_33052, + Scenery.TABLE_33054, + Scenery.TABLE_33129, + Scenery.TABLE_33159, + Scenery.TABLE_33201, + Scenery.TABLE_33202, + Scenery.TABLE_33233, + Scenery.TABLE_34204, + Scenery.TABLE_34429, + Scenery.TABLE_34431, + Scenery.TABLE_34469, + Scenery.TABLE_34470, + Scenery.TABLE_34473, + Scenery.TABLE_34474, + Scenery.TABLE_34518, + Scenery.TABLE_34519, + Scenery.TABLE_34520, + Scenery.TABLE_34521, + Scenery.TABLE_34799, + Scenery.TABLE_34927, + Scenery.TABLE_34968, + Scenery.TABLE_36255, + Scenery.TABLE_36350, + Scenery.TABLE_36366, + Scenery.TABLE_36573, + Scenery.TABLE_36574, + Scenery.TABLE_36575, + Scenery.TABLE_36576, + Scenery.TABLE_36577, + Scenery.TABLE_36578, + Scenery.TABLE_36579, + Scenery.TABLE_36580, + Scenery.TABLE_36581, + Scenery.TABLE_36582, + Scenery.TABLE_36583, + Scenery.TABLE_36584, + Scenery.TABLE_36585, + Scenery.TABLE_36586, + Scenery.TABLE_36727, + Scenery.TABLE_36728, + Scenery.TABLE_36730, + Scenery.TABLE_36731, + Scenery.TABLE_36820, + Scenery.TABLE_36821, + Scenery.TABLE_36910, + Scenery.TABLE_37160, + Scenery.TABLE_37161, + Scenery.TABLE_37162, + Scenery.TABLE_37163, + Scenery.TABLE_37164, + Scenery.TABLE_37165, + Scenery.TABLE_37166, + Scenery.TABLE_37167, + Scenery.TABLE_37350, + Scenery.TABLE_37419, + Scenery.TABLE_37815, + Scenery.TABLE_38020, + Scenery.TABLE_38021, + Scenery.TABLE_38102, + Scenery.TABLE_38316, + Scenery.TABLE_38317, + Scenery.TABLE_38318, + Scenery.TABLE_38319, + Scenery.TABLE_38320, + Scenery.TABLE_39167, + Scenery.TABLE_39168, + Scenery.TABLE_40030, + Scenery.TABLE_40031, + Scenery.TABLE_40818, + Scenery.TABLE_40819, + Scenery.TABLE_40820, + Scenery.TABLE_41105, + Scenery.TABLE_41106, + Scenery.TABLE_41107, + Scenery.TABLE_41196, + Scenery.TABLE_41289, + Scenery.TABLE_41462, + Scenery.TABLE_41469, + Scenery.TABLE_4272, + Scenery.TABLE_4372, + Scenery.TABLE_4458, + Scenery.TABLE_4459, + Scenery.TABLE_4460, + Scenery.TABLE_4461, + Scenery.TABLE_4462, + Scenery.TABLE_4463, + Scenery.TABLE_4464, + Scenery.TABLE_4651, + Scenery.TABLE_4652, + Scenery.TABLE_4653, + Scenery.TABLE_5349, + Scenery.TABLE_5879, + Scenery.TABLE_593, + Scenery.TABLE_594, + Scenery.TABLE_595, + Scenery.TABLE_596, + Scenery.TABLE_597, + Scenery.TABLE_598, + Scenery.TABLE_599, + Scenery.TABLE_600, + Scenery.TABLE_601, + Scenery.TABLE_602, + Scenery.TABLE_603, + Scenery.TABLE_604, + Scenery.TABLE_605, + Scenery.TABLE_606, + Scenery.TABLE_607, + Scenery.TABLE_6075, + Scenery.TABLE_613, + Scenery.TABLE_614, + Scenery.TABLE_616, + Scenery.TABLE_6196, + Scenery.TABLE_6197, + Scenery.TABLE_6198, + Scenery.TABLE_6199, + Scenery.TABLE_620, + Scenery.TABLE_6200, + Scenery.TABLE_6201, + Scenery.TABLE_621, + Scenery.TABLE_6211, + Scenery.TABLE_622, + Scenery.TABLE_623, + Scenery.TABLE_6231, + Scenery.TABLE_624, + Scenery.TABLE_6246, + Scenery.TABLE_7331, + Scenery.TABLE_8700, + Scenery.TABLE_8701, + Scenery.TABLE_8751, + Scenery.TABLE_8768, + Scenery.TABLE_8769, + Scenery.TABLE_9082, + Scenery.TABLE_9430, + Scenery.TABLE_9431, + Scenery.TABLE_9432, + Scenery.TABLE_9433, + Scenery.TABLE_9434, + Scenery.TABLE_9614, + Scenery.TABLE_9685, + Scenery.TABLE_9702 + ) { player, used, with -> + + used as Item + with as core.game.node.scenery.Scenery + + // Similar to DropListener.handleDropAction to keep it consistent + if (Pets.forId(used.id) != null) { + player.familiarManager.summon(used, true, true) + return@onUseAnyWith true + } + if (player.locks.equipmentLock != null) { + return@onUseAnyWith false + } + + // determine if item can be dropped + var canDrop = false; + for (option in used.getDefinition().getOptions()) { + if (option != null && (option.contains("drop"))) { + canDrop = true + } + } + if (!canDrop) { + sendMessage(player, "You cannot place this item on the table!") + return@onUseAnyWith false + } + + // Calculate nearest + val minX = with.location.x + val maxX = with.location.x + with.getSizeX() - 1 + val minY = with.location.y + val maxY = with.location.y + with.getSizeY() - 1 + val nearestX = when { + player.location.x < minX -> minX + player.location.x > maxX -> maxX + else -> player.location.x + } + val nearestY = when { + player.location.y < minY -> minY + player.location.y > maxY -> maxY + else -> player.location.y + } + + // Similar to DropListener.handleDropAction to keep it consistent + closeAllInterfaces(player) + player.animate(Animation(537)) + queueScript(player, strength = QueueStrength.SOFT) { //do this as a script to allow dropping multiple items in the same tick (authentic) + // It's possible for state to change between queueing the script and executing it at the end of the tick (https://forum.2009scape.org/viewtopic.php?f=8&t=1195-lost-bandos-chestplate-whilst-making-iron-titans&p=5292). So, sanity check: + val current = player.inventory.get(used.slot) + if (current == null || current !== used) { + return@queueScript stopExecuting(player) + } + if (player.inventory.replace(null, used.slot) !== used) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential exploit attempt when player ${player.name} tried to place on table ${used.amount}x ${used.id}. The item has been lost and will need to be refunded to the player, but how did they get this to happen?") + return@queueScript stopExecuting(player) + } + val droppedItem = used.dropItem + if (droppedItem.id == Items.COINS_995) playAudio(player, DROP_COINS_SOUND) else playAudio(player, DROP_ITEM_SOUND) + GroundItemManager.create(droppedItem, Location(nearestX, nearestY), player) + + setAttribute(player, "droppedItem:${droppedItem.id}", getWorldTicks() + 2) + PlayerParser.save(player) + return@queueScript stopExecuting(player) + } + + return@onUseAnyWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/AgilityHandler.java b/Server/src/main/content/global/skill/agility/AgilityHandler.java index 722de4afe..c12b7d4fc 100644 --- a/Server/src/main/content/global/skill/agility/AgilityHandler.java +++ b/Server/src/main/content/global/skill/agility/AgilityHandler.java @@ -139,6 +139,13 @@ public final class AgilityHandler { * @return The force movement instance, if force movement is used. */ public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message) { + return forceWalk(player, courseIndex, start, end, animation, speed, experience, message, null); + } + + /** + * Walks across an obstacle while using an explicit force-movement facing direction. + */ + public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message, Direction direction) { player.logoutListeners.put("forcewalk", p -> { p.setLocation(player.getLocation().transform(0,0,0)); return Unit.INSTANCE; @@ -158,6 +165,9 @@ public final class AgilityHandler { player.logoutListeners.remove("forcewalk"); } }; + if (direction != null) { + movement.setDirection(direction); + } movement.start(); GameWorld.getPulser().submit(movement); return movement; diff --git a/Server/src/main/content/global/skill/agility/WildernessCourse.kt b/Server/src/main/content/global/skill/agility/WildernessCourse.kt index ab6644421..d48d00a1a 100644 --- a/Server/src/main/content/global/skill/agility/WildernessCourse.kt +++ b/Server/src/main/content/global/skill/agility/WildernessCourse.kt @@ -2,6 +2,7 @@ package content.global.skill.agility import core.api.* import core.cache.def.impl.SceneryDefinition +import core.game.interaction.QueueStrength import core.game.node.Node import core.game.node.scenery.Scenery import core.game.node.entity.player.Player @@ -116,25 +117,19 @@ class WildernessCourse when (counter++) { 0 -> { 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) - println("tele") counter++ 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 } 2 -> { player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT) - println("tele") counter++ 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 } 3 -> { 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 } } @@ -174,25 +169,27 @@ class WildernessCourse private fun handleSteppingStones(player: Player, `object`: Scenery) { lock(player, 50) val fail = AgilityHandler.hasFailed(player, 1, 0.3) - val origLoc = player.location - registerLogoutListener(player, "steppingstone"){p -> - player.location = origLoc - } - submitWorldPulse(object : Pulse(2, player){ - var counter = 0 - override fun pulse(): Boolean { - if (counter == 3 && fail) { - AgilityHandler.fail(player, -1, Location.create(3001, 3963, 0), Animation.create(771), (player.skills.lifepoints * 0.26).toInt(), "...You lose your footing and fall into the lava.") - return true - } - AgilityHandler.forceWalk(player, if (counter == 5) 2 else -1, player.location, player.location.transform(-1, 0, 0), Animation.create(741), 10, if (counter == 5) 20.0 else 0.0, if (counter != 0) null else "You carefully start crossing the stepping stones...") - if(++counter == 6){ - unlock(player) - clearLogoutListener(player, "steppingstone") - } - return counter == 6 + queueScript(player, 0, QueueStrength.SOFT) { stage -> + val courseIndex = if (stage == 5) 2 else -1 + val start = player.location + val end = player.location.transform(-1, 0, 0) + val anim = Animation(741) + val xp = if (stage == 5) 20.0 else 0.0 + val message = if (stage == 0) "You carefully start crossing the stepping stones..." else null + AgilityHandler.forceWalk(player, courseIndex, start, end, anim, 10, xp, message) + if (stage == 2 && fail) { + val dest = Location(3001, 3963, 0) + val failanim = Animation(771) + val hit = (player.skills.lifepoints * 0.26).toInt() + AgilityHandler.fail(player, -1, dest, failanim, hit, "... You lose your footing and fall into the lava.") + return@queueScript stopExecuting(player) } - }) + if (stage == 5) { + unlock(player) + return@queueScript stopExecuting(player) + } + return@queueScript delayScript(player, 2) + } } /** diff --git a/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java b/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java index 773cd9907..5303bde7d 100644 --- a/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java +++ b/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java @@ -5,6 +5,9 @@ import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.system.task.MovementHook; import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.PlayerContext; +import core.net.packet.out.ClearMinimapFlag; import kotlin.Unit; import core.game.world.GameWorld; import core.game.world.map.Direction; @@ -24,6 +27,10 @@ public final class BladeTrap implements MovementHook { final Direction dir = e.getDirection(); final Player player = (Player) e; final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + player.getPulseManager().clear(); + player.getWalkingQueue().reset(); + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); + e.lock(5); if(e.isPlayer()) { diff --git a/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java b/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java index 4fb8bdb52..adb8f14fd 100644 --- a/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java +++ b/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java @@ -119,6 +119,8 @@ public final class BrimhavenCourse extends OptionHandler { final Direction dir = direction; final Direction faceDirection = Direction.get(object.getDirection().toInteger() - 1 & 3); final Location start = player.getLocation(); + player.setDirection(faceDirection); + player.faceLocation(start.transform(faceDirection)); player.getAppearance().setAnimations(Animation.create(1118 + m)); player.getAppearance().sync(); AgilityHandler.climb(player, -1, new Animation(1117 + m), start.transform(dir), 0.0, null); @@ -143,12 +145,12 @@ public final class BrimhavenCourse extends OptionHandler { } else if (count == 6) { player.getAppearance().setAnimations(); player.getAppearance().sync(); - AgilityHandler.forceWalk(player, -1, last, last.transform(dir), Animation.create(1120 + m), 5, getExp(player, 22.0), null).setDirection(faceDirection); + AgilityHandler.forceWalk(player, -1, last, last.transform(dir), Animation.create(1120 + m), 5, getExp(player, 22.0), null, faceDirection); player.logoutListeners.remove("brimcourse"); return true; } player.logoutListeners.remove("brimcourse"); - AgilityHandler.forceWalk(player, -1, last, last = last.transform(dir), Animation.create(1118 + m), 5, 0.0, null).setDirection(faceDirection); + AgilityHandler.forceWalk(player, -1, last, last = last.transform(dir), Animation.create(1118 + m), 5, 0.0, null, faceDirection); return false; } }); @@ -272,7 +274,7 @@ public final class BrimhavenCourse extends OptionHandler { public boolean pulse() { if (!finish) { setDelay(2); - AgilityHandler.fail(player, 1, player.getLocation().transform(0, 0, -3), Animation.create(189), getHitAmount(player), "You stepped on a broken piece of plank!"); + AgilityHandler.fail(player, 1, player.getLocation().transform(0, 0, -3), Animation.create(768), getHitAmount(player), "You stepped on a broken piece of plank!"); finish = true; return false; } @@ -282,7 +284,7 @@ public final class BrimhavenCourse extends OptionHandler { }); return; } - AgilityHandler.walk(player, -1, start, end, ForceMovement.WALK_ANIMATION, getExp(player, 6.0), null); + AgilityHandler.walk(player, -1, start, end, Animation.create(1426), getExp(player, 6.0), null); } /** @@ -389,6 +391,7 @@ public final class BrimhavenCourse extends OptionHandler { } break; case 3551: + case 3583: return n.getLocation(); } return null; diff --git a/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java b/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java index 086a59522..3ac7da4a3 100644 --- a/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java +++ b/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java @@ -7,6 +7,8 @@ import core.game.node.entity.impl.Projectile; import core.game.node.entity.player.Player; import core.game.system.task.MovementHook; import core.game.system.task.Pulse; +import core.net.packet.context.PlayerContext; +import core.net.packet.out.ClearMinimapFlag; import kotlin.Unit; import core.game.world.GameWorld; import core.game.world.map.Direction; @@ -29,6 +31,9 @@ public final class DartTrap implements MovementHook { final Direction dir = e.getDirection(); final Player player = (Player) e; final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + player.getPulseManager().clear(); + player.getWalkingQueue().reset(); + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); e.lock(6); if(e.isPlayer()) { diff --git a/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java b/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java index 69111c6bf..2885a7f6a 100644 --- a/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java +++ b/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java @@ -6,6 +6,9 @@ import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.system.task.MovementHook; import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.PlayerContext; +import core.net.packet.out.ClearMinimapFlag; import kotlin.Unit; import core.game.world.GameWorld; import core.game.world.map.Direction; @@ -24,6 +27,9 @@ public final class FloorSpikes implements MovementHook { final Direction dir = e.getDirection(); final Player player = (Player) e; final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + player.getPulseManager().clear(); + player.getWalkingQueue().reset(); + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); e.lock(5); if(e.isPlayer()) { diff --git a/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java b/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java index a2bc07cb2..d27a76bcf 100644 --- a/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java +++ b/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java @@ -6,6 +6,9 @@ import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.system.task.MovementHook; import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.PlayerContext; +import core.net.packet.out.ClearMinimapFlag; import kotlin.Unit; import core.game.world.GameWorld; import core.game.world.map.Direction; @@ -24,6 +27,10 @@ public final class PressurePad implements MovementHook { final Direction dir = e.getDirection(); final Player player = (Player) e; final Location start = dest.transform(-dir.getStepX(), -dir.getStepY(), 0); + player.getPulseManager().clear(); + player.getWalkingQueue().reset(); + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); + e.lock(5); if(e.isPlayer()) { diff --git a/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java b/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java index a13815767..3d2a9c1e2 100644 --- a/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java +++ b/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java @@ -6,6 +6,9 @@ import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.system.task.MovementHook; import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.PlayerContext; +import core.net.packet.out.ClearMinimapFlag; import kotlin.Unit; import core.game.world.GameWorld; import core.game.world.map.Direction; @@ -24,6 +27,9 @@ public final class SpinningBlades implements MovementHook { final Direction dir = e.getDirection(); final Player player = (Player) e; final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + player.getPulseManager().clear(); + player.getWalkingQueue().reset(); + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); e.lock(5); if(e.isPlayer()) { @@ -70,4 +76,4 @@ public final class SpinningBlades implements MovementHook { } player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(l), Animation.create(1107)); } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java index 2321706b1..efe0f727f 100644 --- a/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java +++ b/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java @@ -9,6 +9,7 @@ import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Handles the bar squeezing shortcut. @@ -61,7 +62,7 @@ public class BarSqueezeShortcut extends AgilityShortcut { @Override public boolean checkRequirements(Player player) { - if (!player.getQuestRepository().isComplete("Priest in Peril") && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) { + if (!player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL) && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) { player.getDialogueInterpreter().sendDialogue("You need to have completed Priest in Peril in order to do this."); return false; } diff --git a/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt deleted file mode 100644 index 2cefab3da..000000000 --- a/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt +++ /dev/null @@ -1,114 +0,0 @@ -package content.global.skill.agility.shortcuts - -import core.api.* -import core.game.node.entity.player.Player -import core.game.node.entity.skill.Skills -import core.game.system.task.Pulse -import core.game.world.map.Location -import core.game.world.update.flag.context.Animation -import org.rs09.consts.Items -import org.rs09.consts.Scenery -import core.game.interaction.IntType -import core.game.interaction.InteractionListener - -/** - * Handles the Catherby to Taverley grapple shortcut - * @author Byte - */ -class CatherbyGrappleShortcut : InteractionListener { - - companion object { - private val START_LOCATION: Location = Location.create(2866, 3429, 0) - private val END_LOCATION: Location = Location.create(2869,3430,0) - - private val REQUIREMENTS = hashMapOf( - Skills.AGILITY to 32, - Skills.RANGE to 35, - Skills.STRENGTH to 35 - ) - - private val VALID_CROSSBOWS = intArrayOf( - Items.MITH_CROSSBOW_9181, - Items.ADAMANT_CROSSBOW_9183, - Items.RUNE_CROSSBOW_9185, - Items.DORGESHUUN_CBOW_8880 - ) - } - - private var rocks = getScenery(Location.create(2869,3429, 0)) - - override fun defineListeners() { - flagInstant() // execute listeners instantly without determining path - - on(Scenery.ROCKS_17042, IntType.SCENERY, "grapple") { player, _ -> - if (isPlayerInRangeToGrapple(player)) { - forceWalk(player, START_LOCATION, "smart") - } else { - sendMessage(player, "Nothing interesting happens.") - return@on true - } - - if (!doesPlayerHaveRequiredItemsEquipped(player)) { - sendDialogue(player, "You need a Mithril crossbow and a Mithril grapple in order to do this.") - return@on true - } - - if (!doesPlayerHaveRequiredLevels(player)) { - sendDialogueLines(player, - "You need at least " + - REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " + - REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + ", ", - "and " + - REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut." - ) - return@on true - } - - lock(player, 15) - submitWorldPulse(object : Pulse(2) { - var counter = 0 - override fun pulse() : Boolean { - when (counter++) { - 1 -> { - face(player, END_LOCATION) - // Audit: shows player climbing (probably a wall), need a cliff climb animation - animate(player, Animation(4455)) - } - 3 -> { - // Audit: shows grapple on rocks, but there is no rope - replaceScenery(rocks!!, rocks!!.id + 1, 10) - } - 8 -> { - teleport(player, END_LOCATION) - } - 9 -> { - sendMessage(player, "You successfully grapple the rock and climb the cliffside.") - unlock(player) - return true - } - } - return false - } - }) - - return@on true - } - } - - private fun doesPlayerHaveRequiredItemsEquipped(player: Player): Boolean { - return inEquipment(player, Items.MITH_GRAPPLE_9419) && anyInEquipment(player, *VALID_CROSSBOWS) - } - - private fun doesPlayerHaveRequiredLevels(player: Player): Boolean { - for ((skill, requiredLevel) in REQUIREMENTS) { - if (!hasLevelDyn(player, skill, requiredLevel)) { - return false - } - } - return true - } - - private fun isPlayerInRangeToGrapple(player: Player): Boolean { - return inBorders(player, START_LOCATION.x - 2, START_LOCATION.y - 2, START_LOCATION.x, START_LOCATION.y) - } -} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/FaladorGrapplePlugin.java b/Server/src/main/content/global/skill/agility/shortcuts/FaladorGrapplePlugin.java deleted file mode 100644 index f9bf6f6a9..000000000 --- a/Server/src/main/content/global/skill/agility/shortcuts/FaladorGrapplePlugin.java +++ /dev/null @@ -1,145 +0,0 @@ -package content.global.skill.agility.shortcuts; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import org.rs09.consts.Items; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.impl.ForceMovement; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.net.packet.PacketRepository; -import core.net.packet.context.MinimapStateContext; -import core.net.packet.out.MinimapState; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.node.entity.skill.Skills; - -import java.util.HashMap; -import java.util.Map; - -/** - * Represents the plugin used to handle the grappling of the falador wall. - * - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class FaladorGrapplePlugin extends OptionHandler { - private static final HashMap REQUIREMENTS = new HashMap<>(); - private static String requirementsString; - - static { - REQUIREMENTS.putIfAbsent(Skills.AGILITY, 11); - REQUIREMENTS.putIfAbsent(Skills.RANGE, 19); - REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 37); - - requirementsString = "You need at least " - + REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " - + REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and " - + REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH] - + " to use this shortcut."; - } - - private static final int[] CBOWS = new int[]{ - Items.MITH_CROSSBOW_9181, - Items.ADAMANT_CROSSBOW_9183, - Items.RUNE_CROSSBOW_9185, - Items.DORGESHUUN_CBOW_8880 - }; - private static final Item MITH_GRAPPLE = new Item(9419); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(17049).getHandlers().put("option:grapple", this); - SceneryDefinition.forId(17050).getHandlers().put("option:grapple", this); - SceneryDefinition.forId(17051).getHandlers().put("option:jump", this); - SceneryDefinition.forId(17052).getHandlers().put("option:jump", this); - return this; - } - - @Override - public boolean handle(final Player player, final Node node, String option) { - Location destination; - Location current = player.getLocation(); - - switch (option) { - case "jump": - ForceMovement.run(player, - current, - node.asScenery().getId() == 17051 - ? Location.create(3033, 3390, 0) - : Location.create(3032, 3388, 0), - new Animation(7268), - 10); - break; - case "grapple": - destination = node.asScenery().getId() == 17049 - ? Location.create(3033, 3389, 1) - : Location.create(3032, 3391, 1); - - for (Map.Entry e : REQUIREMENTS.entrySet()) { - if (player.getSkills().getLevel(e.getKey()) < e.getValue()) { - player.getDialogueInterpreter().sendDialogue(requirementsString); - return true; - } - } - - if (!player.getEquipment().containsAtLeastOneItem(CBOWS) || !player.getEquipment().containsItem(MITH_GRAPPLE)) { - player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this."); - return true; - } - - player.lock(); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter = 1; - Component tab; - - @Override - public boolean pulse() { - switch (counter++) { - case 1: - player.faceLocation(destination); - player.visualize(new Animation(4455), new Graphics(760, 100)); - break; - case 8: - tab = player.getInterfaceManager().getSingleTab(); - player.getInterfaceManager().openOverlay(new Component(115)); - PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); - player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12); - break; - case 13: - player.getProperties().setTeleportLocation(destination); - break; - case 14: - player.getInterfaceManager().restoreTabs(); - if (tab != null) { - player.getInterfaceManager().openTab(tab); - } - PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); - player.getInterfaceManager().closeOverlay(); - player.getInterfaceManager().close(); - player.unlock(); - player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 1, 2); - return true; - } - return false; - } - }); - break; - } - return true; - } - - @Override - public Location getDestination(final Node moving, final Node destination) { - return destination.asScenery().getId() == 17050 ? Location.create(3032, 3388, 0) : null; - } - -} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/KaramjaGrapple.java b/Server/src/main/content/global/skill/agility/shortcuts/KaramjaGrapple.java deleted file mode 100644 index b623cf8f9..000000000 --- a/Server/src/main/content/global/skill/agility/shortcuts/KaramjaGrapple.java +++ /dev/null @@ -1,145 +0,0 @@ -package content.global.skill.agility.shortcuts; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import org.rs09.consts.Items; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Direction; -import core.game.world.map.Location; -import core.game.world.map.RegionManager; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.node.entity.skill.Skills; - -import java.util.HashMap; -import java.util.Map; - -@Initializable -public class KaramjaGrapple extends OptionHandler { - private static final HashMap REQUIREMENTS = new HashMap<>(); - private static final String requirementsString; - - static { - REQUIREMENTS.putIfAbsent(Skills.AGILITY, 53); - REQUIREMENTS.putIfAbsent(Skills.RANGE, 42); - REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 21); - - requirementsString = "You need at least " - + REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " - + REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and " - + REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH] - + " to use this shortcut."; - } - - private static final int[] CBOWS = new int[]{ - Items.MITH_CROSSBOW_9181, - Items.ADAMANT_CROSSBOW_9183, - Items.RUNE_CROSSBOW_9185, - Items.DORGESHUUN_CBOW_8880 - }; - private static final Item MITH_GRAPPLE = new Item(9419); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(17074).getHandlers().put("option:grapple", this); - // island tree 17074 +1 rope loop, +2 grappled one way, +3 grappled other way - // north tree 17056 +1 rope loop, +2 grappled - // south tree 17059 +1 rope loop, +2 grappled - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - Location destination; - Location current = player.getLocation(); - Scenery startTree, endTree; - Direction direction; - if (current.getY() > 3134) { // starting at north side - startTree = RegionManager.getObject(Location.create(2874, 3144, 0)); - endTree = RegionManager.getObject(Location.create(2873, 3125, 0)); - destination = Location.create(2874, 3127, 0); - direction = Direction.SOUTH; - } else { - startTree = RegionManager.getObject(Location.create(2873, 3125, 0)); - endTree = RegionManager.getObject(Location.create(2874, 3144, 0)); - destination = Location.create(2874, 3142, 0); - direction = Direction.NORTH; - } - Scenery islandTree = RegionManager.getObject(Location.create(2873, 3134, 0)); - - - switch (option) { - case "grapple": - - for (Map.Entry e : REQUIREMENTS.entrySet()) { - if (player.getSkills().getLevel(e.getKey()) < e.getValue()) { - player.getDialogueInterpreter().sendDialogue(requirementsString); - return true; - } - } - - if (!player.getEquipment().containsAtLeastOneItem(CBOWS) || !player.getEquipment().containsItem(MITH_GRAPPLE)) { - player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this."); - return true; - } - - player.lock(); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter = 1; - Component tab; - - @Override - public boolean pulse() { - switch (counter++) { - // TODO animations not implemented. - // See ~11min in https://www.youtube.com/watch?v=qpB53rzYqrA - // don't know how to get ropes to show up. The tree objects have grapples and stuff but don't look like the video and aren't the right directions - // splash gfx are 68 and 69, not sure why there are two - // not sure what swimming animation is, could be 4464 thru 4468 - case 1: - player.faceLocation(player.getLocation().transform(direction)); - player.animate(new Animation(4230)); - break; - case 3: - //player.getPacketDispatch().sendPositionedGraphic(67, 10, 0, player.getLocation().transform(direction, 5)); // - break; - case 4: - //ObjectBuilder.replace(startTree, startTree.transform(startTree.getId() + 1), 10); - //ObjectBuilder.replace(islandTree, islandTree.transform(islandTree.getId() + 1), 10); - break; - case 5: - break; - case 13: - player.getProperties().setTeleportLocation(destination); - break; - case 14: - player.unlock(); - player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 2, 6); - return true; - } - return false; - } - }); - break; - } - return true; - } - - @Override - public Location getDestination(final Node moving, final Node destination) { - // Run between tree and water before firing grapple - if (moving.getLocation().getY() > 3134) { // starting at north side - return Location.create(2874, 3142, 0); - } else { - return Location.create(2874, 3127, 0); - } - } -} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt index bb3120ecc..035ed53d7 100644 --- a/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt +++ b/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt @@ -40,6 +40,7 @@ class SteppingStoneShortcut : OptionHandler() { } val offset = getOffset(player,finalDest) player.debug("Offset: ${offset.first},${offset.second}") + closeAllInterfaces(player) lock(player, 3) player.locks.lockTeleport(3) queueScript(player, 2, QueueStrength.SOFT) { @@ -87,4 +88,4 @@ class SteppingStoneShortcut : OptionHandler() { */ private val ANIMATION = Animation(741) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt index 3116cecd2..e492b6b9d 100644 --- a/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt +++ b/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt @@ -19,6 +19,7 @@ class StileShortcut : InteractionListener { val startLoc = p.location.transform(direction, 1) val endLoc = p.location.transform(direction, 2) + closeAllInterfaces(p) p.walkingQueue.reset() p.walkingQueue.addPath(startLoc.x, startLoc.y) forceMove(p, startLoc, endLoc, 0, animationCycles(839), direction, 839) @@ -75,4 +76,4 @@ class StileShortcut : InteractionListener { Horizontal, Vertical } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java index 7388fde01..42cf77e34 100644 --- a/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java +++ b/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java @@ -15,6 +15,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles a tunnel shortcut. @@ -73,7 +74,7 @@ public class TunnelShortcut extends AgilityShortcut { @Override public void run(final Player player, Scenery object, String option, boolean failed) { if (object.getId() == 14922) { - if (!hasRequirement(player, "Swan Song")) + if (!hasRequirement(player, Quests.SWAN_SONG)) return; } player.lock(6); diff --git a/Server/src/main/content/global/skill/agility/shortcuts/WaterOrbGrapple.java b/Server/src/main/content/global/skill/agility/shortcuts/WaterOrbGrapple.java deleted file mode 100644 index ab59e66d7..000000000 --- a/Server/src/main/content/global/skill/agility/shortcuts/WaterOrbGrapple.java +++ /dev/null @@ -1,126 +0,0 @@ -package content.global.skill.agility.shortcuts; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import org.rs09.consts.Items; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.node.scenery.SceneryBuilder; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.map.RegionManager; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.node.entity.skill.Skills; - -import java.util.HashMap; -import java.util.Map; - -@Initializable -public class WaterOrbGrapple extends OptionHandler { - private static final HashMap REQUIREMENTS = new HashMap<>(); - private static final String requirementsString; - - static { - REQUIREMENTS.putIfAbsent(Skills.AGILITY, 36); - REQUIREMENTS.putIfAbsent(Skills.RANGE, 39); - REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 22); - - requirementsString = "You need at least " - + REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " - + REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and " - + REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH] - + " to use this shortcut."; - } - - private static final int[] CBOWS = new int[]{ - Items.MITH_CROSSBOW_9181, - Items.ADAMANT_CROSSBOW_9183, - Items.RUNE_CROSSBOW_9185, - Items.DORGESHUUN_CBOW_8880 - }; - private static final Item MITH_GRAPPLE = new Item(9419); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(17062).getHandlers().put("option:grapple", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - Location destination; - Location current = player.getLocation(); - Scenery rock = RegionManager.getObject(Location.create(2841, 3426, 0)); - Scenery tree = RegionManager.getObject(Location.create(2841, 3434, 0)); - - switch (option) { - case "grapple": - destination = Location.create(2841, 3433, 0); - - for (Map.Entry e : REQUIREMENTS.entrySet()) { - if (player.getSkills().getLevel(e.getKey()) < e.getValue()) { - player.getDialogueInterpreter().sendDialogue(requirementsString); - return true; - } - } - - if (!player.getEquipment().containsAtLeastOneItem(CBOWS) || !player.getEquipment().containsItem(MITH_GRAPPLE)) { - player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this."); - return true; - } - - player.lock(); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter = 1; - Component tab; - - @Override - public boolean pulse() { - switch (counter++) { - // TODO this animation sequence is wrong. sendPositionedGraphic doesn't work correctly, and rest of water crossing not well implemented - // See 4:24 in https://www.youtube.com/watch?v=O90y-N_vwTc - // rope gfx is 67 - // splash gfx are 68 and 69, not sure why there are two - // not sure what swimming animation is, could be 4464 thru 4468 - case 1: - player.faceLocation(destination); - player.animate(new Animation(4230)); - break; - case 3: - player.getPacketDispatch().sendPositionedGraphic(67, 10, 0, Location.create(2840,3427,0)); // - break; - case 4: - SceneryBuilder.replace(rock, rock.transform(rock.getId() + 1), 10); - SceneryBuilder.replace(tree, tree.transform(tree.getId() + 1), 10); - break; - case 5: - break; - case 13: - player.getProperties().setTeleportLocation(destination); - break; - case 14: - player.unlock(); - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 10); - return true; - } - return false; - } - }); - break; - } - return true; - } - - @Override - public Location getDestination(final Node moving, final Node destination) { - // Run between rock and stream before firing grapple - return Location.create(2841, 3427, 0); - } -} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/YanilleGrapple.java b/Server/src/main/content/global/skill/agility/shortcuts/YanilleGrapple.java deleted file mode 100644 index d37e1964a..000000000 --- a/Server/src/main/content/global/skill/agility/shortcuts/YanilleGrapple.java +++ /dev/null @@ -1,121 +0,0 @@ -package content.global.skill.agility.shortcuts; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.impl.ForceMovement; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.net.packet.PacketRepository; -import core.net.packet.context.MinimapStateContext; -import core.net.packet.out.MinimapState; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.node.entity.skill.Skills; - -import java.util.HashMap; -import java.util.Map; - -@Initializable -public class YanilleGrapple extends OptionHandler { - private static final HashMap REQUIREMENTS = new HashMap<>(); - private static String requirementsString; - - static { - REQUIREMENTS.putIfAbsent(Skills.AGILITY, 39); - REQUIREMENTS.putIfAbsent(Skills.RANGE, 21); - REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 38); - - requirementsString = "You need at least " - + REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " - + REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and " - + REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH] - + " to use this shortcut."; - } - - private static final Item MITH_CBOW = new Item(9181); - private static final Item MITH_GRAPPLE = new Item(9419); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(17047).getHandlers().put("option:grapple", this); - SceneryDefinition.forId(17048).getHandlers().put("option:jump", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - Location destination; - Location current = player.getLocation(); - - switch (option) { - case "jump": - ForceMovement.run(player, - current, - current.getY() < 3074 ? Location.create(2556,3072,0) : Location.create(2556,3075,0), - new Animation(7268), - 10); - break; - case "grapple": - destination = current.getY() < 3073 - ? Location.create(2556, 3073, 1) - : Location.create(2556, 3074, 1); - - for (Map.Entry e : REQUIREMENTS.entrySet()) { - if (player.getSkills().getLevel(e.getKey()) < e.getValue()) { - player.getDialogueInterpreter().sendDialogue(requirementsString); - return true; - } - } - - if (!player.getEquipment().containsItem(MITH_CBOW) || !player.getEquipment().containsItem(MITH_GRAPPLE)) { - player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this."); - return true; - } - - player.lock(); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter = 1; - Component tab; - - @Override - public boolean pulse() { - switch (counter++) { - case 1: - player.faceLocation(destination); - player.visualize(new Animation(4455), new Graphics(760, 100)); - break; - case 8: - tab = player.getInterfaceManager().getSingleTab(); - player.getInterfaceManager().openOverlay(new Component(115)); - PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); - player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12); - break; - case 13: - player.getProperties().setTeleportLocation(destination); - break; - case 14: - player.getInterfaceManager().restoreTabs(); - if (tab != null) { - player.getInterfaceManager().openTab(tab); - } - PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); - player.getInterfaceManager().closeOverlay(); - player.getInterfaceManager().close(); - player.unlock(); - return true; - } - return false; - } - }); - break; - } - return true; - } -} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractGrappleShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractGrappleShortcut.kt new file mode 100644 index 000000000..d6672efe1 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractGrappleShortcut.kt @@ -0,0 +1,136 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +abstract class AbstractGrappleShortcut : InteractionListener { + /** + * Make sure that you have flagInstant in your listeners. + * If you do not the player will run and try to touch the grapple point + */ + private val VALID_CROSSBOWS = intArrayOf( + Items.MITH_CROSSBOW_9181, + Items.ADAMANT_CROSSBOW_9183, + Items.RUNE_CROSSBOW_9185, + Items.DORGESHUUN_CBOW_8880 + ) + + protected abstract val REQUIREMENTS: HashMap + + protected abstract val grappleStartLocation: Location + protected abstract val grappleEndLocation: Location + + // use lazy so that the skill requirements can be populated after the child builds them + private val requirementString1: String by lazy { + "You need at least " + + REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " + + REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + "," + } + private val requirementString2: String by lazy { + "and " + + REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut." + } + + + // What needs to have its model changed during a grapple + protected abstract val grappleScenery: List + + // What animation to use when getting the player across + protected abstract val animation: Animation + // How long should the animation last (in ticks) + protected abstract val animationDuration: Int + + protected abstract fun animation(animationStage: Int, player: Player): Boolean + + + // The message that can appear if there should be one after grappling + protected val message: String? = null + + private fun getRequirementString(): Array { + val requirementString = arrayOf(requirementString1, requirementString2) + return requirementString + } + + private fun doesPlayerHaveRequiredItemsEquipped(player: Player): Boolean { + return inEquipment(player, Items.MITH_GRAPPLE_9419) && anyInEquipment(player, *VALID_CROSSBOWS) + } + + private fun doesPlayerHaveRequiredLevels(player: Player): Boolean { + for ((skill, requiredLevel) in REQUIREMENTS) { + if (!hasLevelDyn(player, skill, requiredLevel)) { + return false + } + } + return true + } + + protected open fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + return inBorders(player, startLoc.x - range, startLoc.y - range, + startLoc.x + range, startLoc.y + range) + } + + /** + * See if the [player] is close enough to the [startLoc] (based on [range] to + * try and grapple. This will return false if the [player] is too far away, + * if the player does not have the right levels or if the player does not have + * the correct gear equipped. + */ + protected fun canGrapple(player: Player, startLoc: Location, range: Int): Boolean { + if (isPlayerInRangeToGrapple(player, startLoc, range)) { + forceWalk(player, startLoc, "smart") + } else { + // todo should this be "you are too far away" or something like that? + sendMessage(player, "Nothing interesting happens.") + return false + } + + if (!doesPlayerHaveRequiredItemsEquipped(player)) { + sendDialogue(player, "You need a Mithril crossbow and a Mithril grapple in order to do this.") + return false + } + + if (!doesPlayerHaveRequiredLevels(player)) { + sendDialogueLines(player, + *getRequirementString() + ) + return false + } + return true + } + + protected fun grapple(player: Player, message: String?): Boolean { + closeAllInterfaces(player) + lock(player, animationDuration) + // TODO is this right? should we force the player to cross? + queueScript(player, strength = QueueStrength.SOFT) { stage: Int -> + if (animation(stage, player)){ + // We're done with the animation + return@queueScript stopExecuting(player) + } + else{ + return@queueScript delayScript(player, 1) + } + } + + message?.let{ + player.sendMessage(message) + } + return true + } + + + /** + * If an achievement diary can be updated it should be done here + */ + protected open fun updateDiary(player: Player): Boolean{ + return false + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractOneWayGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractOneWayGrapple.kt new file mode 100644 index 000000000..7645b0315 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractOneWayGrapple.kt @@ -0,0 +1,39 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.node.entity.player.Player + +abstract class AbstractOneWayGrapple : AbstractGrappleShortcut() { + + + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + // Point towards the grapple landing zone + face(player, grappleEndLocation) + // Start the grapple animation + animate(player, animation) + } + + 5 -> { + for (tgt in grappleScenery) { + // Add grapple effects to all scenery (for 10 ticks) + replaceScenery(tgt!!, tgt.id + 1, 10) + } + } + + 5 + animationDuration -> { + // After the animation is done teleport to the landing zone + teleport(player, grappleEndLocation) + } + + 5 + animationDuration + 1 -> { + // free the player + unlock(player) + updateDiary(player) + return true + } + } + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractTwoWayGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractTwoWayGrapple.kt new file mode 100644 index 000000000..4cbb3aa1c --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractTwoWayGrapple.kt @@ -0,0 +1,16 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location + +abstract class AbstractTwoWayGrapple : AbstractGrappleShortcut(){ + + abstract var direction: Direction? + + abstract var startLoc: Location? + abstract var endLoc: Location? + + protected abstract fun setStartEndSide(player: Player, margin: Int = 5) + protected abstract fun getGrappleScenery(direction: Direction): List +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AlKharidGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AlKharidGrapple.kt new file mode 100644 index 000000000..5f98b03e4 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AlKharidGrapple.kt @@ -0,0 +1,108 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery + +class AlKharidGrapple : AbstractTwoWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 8, Skills.RANGE to 37, Skills.STRENGTH to 19) + + // Lumbridge + override val grappleStartLocation: Location = Location(3246, 3179, 0) + + // Al Kharid + override val grappleEndLocation: Location = Location(3259, 3179, 0) + + override var direction: Direction? = null + override var startLoc: Location? = null + override var endLoc: Location? = null + + override var grappleScenery: List = listOf() + + override val animation: Animation = Animation(4230) + override val animationDuration: Int = 9 + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + face(player, endLoc!!) + animate(player, animation) + } + + 5 -> { + for (tgt in grappleScenery) { + if ((tgt!!.id == 17068)) { + // This is the raft + continue + } + replaceScenery(tgt, tgt.id + 1, 10) + } + } + + 5 + animationDuration -> { + teleport(player, endLoc!!) + } + 5 + animationDuration + 1 -> { + unlock(player) + updateDiary(player) + return true + } + } + return false + } + + override fun defineListeners() { + flagInstant() // execute listeners instantly without determining path + + on(Scenery.BROKEN_RAFT_17068, IntType.SCENERY, "grapple") { player, target -> + // Check if we are on the east or the west of the broken raft + // East = Lum + setStartEndSide(player) + if (!canGrapple(player, startLoc!!, 2)){ + return@on true + } + grapple(player,message) + return@on true + } + } + + + override fun setStartEndSide(player: Player, margin: Int) { + if (player.location.x < grappleStartLocation.x + margin){ + // We're on the west side + direction = Direction.EAST // got to jump east + startLoc = grappleStartLocation + endLoc = grappleEndLocation + } + else { + // we're on the east side + direction = Direction.WEST // got to jump west + startLoc = grappleEndLocation + endLoc = grappleStartLocation + } + + grappleScenery = getGrappleScenery(direction!!) + } + + override fun getGrappleScenery(direction: Direction): List { + val lumbridgeTree = getScenery(Location(3244, 3179, 0)) + val alKharidTree = getScenery(Location(3260, 3178, 0)) + val startTree : core.game.node.scenery.Scenery? + val endTree : core.game.node.scenery.Scenery? + val raft = getScenery(Location(3252, 3179, 0)) + if (direction == Direction.EAST){ + startTree = lumbridgeTree + endTree = alKharidTree + } + else{ + startTree = alKharidTree + endTree = lumbridgeTree + } + return listOf(startTree,endTree, raft) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/CatherbyGrappleShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/CatherbyGrappleShortcut.kt new file mode 100644 index 000000000..e5bcd2a8f --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/CatherbyGrappleShortcut.kt @@ -0,0 +1,43 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.plugin.Initializable +import kotlin.collections.HashMap + + +@Initializable +class CatherbyGrappleShortcut : AbstractOneWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 32, Skills.RANGE to 35, Skills.STRENGTH to 35) + + override val grappleStartLocation: Location = Location.create(2866, 3429, 0) + + override val grappleEndLocation: Location = Location.create(2869,3430,0) + + // todo this is the wrong animation + override val animation: Animation = Animation(4455) + + override val animationDuration: Int = 9 + + override val grappleScenery: List = listOf( + getScenery(Location.create(2869,3429, 0)) // rocks + ) + + override fun defineListeners() { + flagInstant() + + on(Scenery.ROCKS_17042, IntType.SCENERY, "grapple"){ player, _ -> + if (!canGrapple(player, grappleStartLocation, 1)) { + return@on true + } + grapple(player, message) + return@on true + } + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/FaladorGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/FaladorGrapple.kt new file mode 100644 index 000000000..58e8e2fe2 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/FaladorGrapple.kt @@ -0,0 +1,123 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.Scenery + +abstract class AbstractFaladorGrapple(private var wallGrappleInterface: WallGrappleInterface = WallGrappleInterfaceImpl()): AbstractOneWayGrapple() { + + override val animation: Animation = Animation(4455) + + override val animationDuration: Int = 14 + + // There are no scenery items to hook so don't let children override this + final override val grappleScenery: List = listOf() + + protected fun jump(player: Player, destination: Location): Boolean { + return wallGrappleInterface.jump(player, destination) + } + + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + player.faceLocation(grappleEndLocation) + visualize(player, animation, Graphics(760, 100)) + } + + 8 -> { + wallGrappleInterface.fadeToBlack(player) + } + + 13 -> teleport(player, grappleEndLocation) + 14 -> { + wallGrappleInterface.showGame(player) + unlock(player) + updateDiary(player) + return true + } + } + return false + } + +} +@Initializable +class FaladorGrappleNorth : AbstractFaladorGrapple() { + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37) + + override val grappleStartLocation: Location = Location.create(3033, 3390, 0) + + + override val grappleEndLocation: Location = Location.create(3033, 3389, 1) + + override fun defineListeners() { + flagInstant() + on(Scenery.WALL_17049, IntType.SCENERY, "grapple") { player, _ -> + if(!canGrapple(player, grappleStartLocation, 4)) { + return@on true + } + grapple(player, message) + return@on true + } + + on(Scenery.WALL_17051, IntType.SCENERY, "jump"){ player, _ -> + jump(player, grappleStartLocation) + return@on true + } + } + + override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + // Do not let the player grapple from the other side of the wall + return inBorders(player, startLoc.x - range, startLoc.y, + startLoc.x + range, startLoc.y + 2) + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 1, 2) + return true + } +} + +@Initializable +class FaladorGrappleSouth : AbstractFaladorGrapple() { + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37) + + override val grappleStartLocation: Location = Location.create(3032, 3388, 0) + + override val grappleEndLocation: Location = Location.create(3032, 3389, 1) + + override fun defineListeners() { + flagInstant() + on(Scenery.WALL_17050, IntType.SCENERY, "grapple") { player, _ -> + if(!canGrapple(player, grappleStartLocation, 4)) { + return@on true + } + grapple(player, message) + return@on true + } + + on(Scenery.WALL_17052, IntType.SCENERY, "jump"){ player, _ -> + jump(player, grappleStartLocation) + return@on true + } + } + + override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + // Do not let the player grapple from the other side of the wall + return inBorders(player, startLoc.x - range, startLoc.y, + startLoc.x + range, startLoc.y - 2) + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 1, 2) + return true + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/KaramjaGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/KaramjaGrapple.kt new file mode 100644 index 000000000..96337db8e --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/KaramjaGrapple.kt @@ -0,0 +1,108 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.Scenery + +@Initializable +class KaramjaGrapple : AbstractTwoWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 53, Skills.RANGE to 42, Skills.STRENGTH to 21) + + // South + override val grappleStartLocation: Location = Location.create(2874, 3127, 0) + + + // North + override val grappleEndLocation: Location = Location.create(2874,3142,0) + + override var direction: Direction? = null + override var startLoc: Location? = null + override var endLoc: Location? = null + + override var grappleScenery: List = listOf() + + override val animation: Animation = Animation(4230) + override val animationDuration: Int = 9 + + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + face(player, endLoc!!) + animate(player, animation) + } + + 5 -> { + for (tgt in grappleScenery) { + replaceScenery(tgt!!, tgt.id + 1, 10) + } + } + + 5 + animationDuration -> { + teleport(player, endLoc!!) + } + 5 + animationDuration + 1 -> { + unlock(player) + updateDiary(player) + return true + } + } + return false + } + + override fun defineListeners() { + flagInstant() + + on(Scenery.STRONG_TREE_17074, IntType.SCENERY, "grapple"){ player, _ -> + setStartEndSide(player) + if(!canGrapple(player, startLoc!!, 1)){ + return@on true + } + grapple(player, message) + return@on true + } + + } + + override fun setStartEndSide(player: Player, margin: Int) { + if (player.location.y > grappleEndLocation.y - margin){ // we're on the north side + direction = Direction.SOUTH // got to jump south + startLoc = grappleEndLocation + endLoc = grappleStartLocation + } + else { + direction = Direction.NORTH // got to jump north + startLoc = grappleStartLocation + endLoc = grappleEndLocation + } + + grappleScenery = getGrappleScenery(direction!!) + } + + override fun getGrappleScenery(direction: Direction): List { + val startTree : core.game.node.scenery.Scenery? + val endTree : core.game.node.scenery.Scenery? + val islandTree = getScenery(Location(2873, 3134, 0)) + if (direction == Direction.NORTH){ + startTree = getScenery(Location(2874, 3144, 0)) + endTree = getScenery(Location(2873, 3125, 0)) + } + else{ + startTree = getScenery(Location(2874, 3144, 0)) + endTree = getScenery(Location(2873, 3125, 0)) + } + return listOf(startTree,endTree, islandTree) + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 2, 6) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/WallGrappleInterface.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WallGrappleInterface.kt new file mode 100644 index 000000000..8eeadcf71 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WallGrappleInterface.kt @@ -0,0 +1,69 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.component.Component +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState + +interface WallGrappleInterface { + var tab: Component? + fun jump(player: Player, destination: Location): Boolean + fun fadeToBlack(player: Player): Component + fun showGame(player: Player): Boolean +} + + +class WallGrappleInterfaceImpl: WallGrappleInterface{ + override var tab: Component? = null + + override fun jump(player: Player, destination: Location): Boolean { + // todo this doesn't look great compared to what it used to look like + closeAllInterfaces(player) + forceWalk(player, destination,"smart" ) + face(player, destination) + // We're teleporting if we are animating so make the strength SOFT + queueScript(player, strength = QueueStrength.SOFT){ stage: Int -> + when (stage){ + 1 -> animate(player, Animation(7268)) + 2 ->{ + teleport(player, destination) + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 1) + + } + return true + } + + + override fun fadeToBlack(player: Player): Component { + // todo make this work. Right now the tab is always null + tab = player.interfaceManager.singleTab + player.interfaceManager.openOverlay(Component(115)) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12) + if (tab == null){ + println("Panic") + return Component(1) + } + return tab!! + } + + override fun showGame(player: Player): Boolean { + player.interfaceManager.restoreTabs() + if (tab != null) { + player.interfaceManager.openTab(tab) + } + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + closeOverlay(player) + closeInterface(player) + return true + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/WaterOrbGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WaterOrbGrapple.kt new file mode 100644 index 000000000..8fc2a2167 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WaterOrbGrapple.kt @@ -0,0 +1,48 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.getScenery +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import org.rs09.consts.Scenery +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable + +@Initializable +class WaterOrbGrapple : AbstractOneWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 36, Skills.RANGE to 39, Skills.STRENGTH to 22) + + override val grappleStartLocation: Location = Location.create(2841, 3427, 0) + + override val grappleEndLocation: Location = Location.create(2841, 3433, 0) + + override val animation: Animation = Animation(4230) + + override val animationDuration: Int = 9 + + override val grappleScenery: List = listOf( + getScenery(Location.create(2841, 3426, 0)), // rock + getScenery(Location.create(2841, 3434, 0)) // tree + ) + + override fun defineListeners() { + flagInstant() + + on(Scenery.CROSSBOW_TREE_17062, IntType.SCENERY, "grapple"){ player, _ -> + if (!canGrapple(player, grappleStartLocation, 1)) { + return@on true + } + grapple(player, message) + return@on true + } + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 2, 10) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/YanilleGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/YanilleGrapple.kt new file mode 100644 index 000000000..dc5351275 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/YanilleGrapple.kt @@ -0,0 +1,99 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.inBorders +import core.api.teleport +import core.api.unlock +import core.api.visualize +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.Scenery + +@Initializable +class YanilleGrapple(private var wallGrappleInterface: WallGrappleInterface = WallGrappleInterfaceImpl()): AbstractTwoWayGrapple() { + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37) + + override val grappleStartLocation: Location = Location.create(2556, 3072, 0) + + override val grappleEndLocation: Location = Location.create(2556, 3073, 1) + + override var direction: Direction? = null + override var startLoc: Location? = null + override var endLoc: Location? = null + override fun setStartEndSide(player: Player, margin: Int) { + // Start location is where you end after jumping in the opposite way + if (player.location.y > 3073 ){ + // We are north of the middle of the wall + startLoc = Location.create(2556, 3075, 0) // This is where you grapple from/land after jumping + endLoc = Location.create(2556, 3074, 1) // + } + else { + // We are south of the middle of the wall + startLoc = Location.create(2556, 3072, 0) + endLoc = Location.create(2556, 3073, 1) + } + } + + override fun getGrappleScenery(direction: Direction): List { + return emptyList() + } + + override var grappleScenery: List = listOf() + + override val animation: Animation = Animation(4455) + override val animationDuration: Int = 9 + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + player.faceLocation(endLoc) + visualize(player, animation, Graphics(760, 100)) + } + + 8 -> { + wallGrappleInterface.fadeToBlack(player) + } + + 13 -> teleport(player, endLoc!!) + 14 -> { + wallGrappleInterface.showGame(player) + unlock(player) + updateDiary(player) + return true + } + } + return false + } + + + override fun defineListeners() { + // Do not use flagListeners here + // The player needs to be able to touch the target + on(Scenery.WALL_17047, IntType.SCENERY, "grapple") { player, _ -> + setStartEndSide(player, 0) + if(!canGrapple(player, startLoc!!, 4)){ + return@on true + } + grapple(player, message) + return@on true + } + + on(Scenery.WALL_17048, IntType.SCENERY, "jump") { player, _ -> + setStartEndSide(player, 0) + wallGrappleInterface.jump(player, startLoc!!) + return@on true + } + } + + override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + // Do not let the player grapple from the other side of the wall + return inBorders( + player, startLoc.x - range, startLoc.y, + startLoc.x + range, startLoc.y - 2) + } +} diff --git a/Server/src/main/content/global/skill/construction/BuildHotspot.java b/Server/src/main/content/global/skill/construction/BuildHotspot.java index de3fd7123..c5ca6c8e7 100644 --- a/Server/src/main/content/global/skill/construction/BuildHotspot.java +++ b/Server/src/main/content/global/skill/construction/BuildHotspot.java @@ -33,7 +33,7 @@ public enum BuildHotspot { FIREPLACE(15418, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CLAY_FIREPLACE, Decoration.STONE_FIREPLACE,Decoration.MARBLE_FIREPLACE), FIREPLACE2(15267, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CLAY_FIREPLACE, Decoration.STONE_FIREPLACE,Decoration.MARBLE_FIREPLACE), CURTAINS(15419, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.TORN_CURTAINS, Decoration.CURTAINS, Decoration.OPULENT_CURTAINS), - BOOKCASE(15416, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), + BOOKCASE(15416, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), RUG(15415, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CORNER, Decoration.RED_RUG_CORNER, Decoration.OPULENT_RUG_CORNER), RUG2(15414, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_END, Decoration.RED_RUG_END, Decoration.OPULENT_RUG_END), RUG3(15413, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CENTER, Decoration.RED_RUG_CENTER, Decoration.OPULENT_RUG_CENTER), @@ -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_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), - WALL_DECORATION(15303, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), + WALL_DECORATION(15303, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), /** * 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), 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), - 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.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.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.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.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), + 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), + 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), + 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), + 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), + 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), HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL), /** @@ -186,22 +186,12 @@ public enum BuildHotspot { LANDSCAPE(15393, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.LUMBRIDGE, Decoration.THE_DESERT, Decoration.MORYTANIA, Decoration.KARAMJA, Decoration.ISAFDAR), SWORD(15395, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SILVERLIGHT, Decoration.EXCALIBUR, Decoration.DARKLIGHT), MAP(15396, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SMALL_MAP, Decoration.MEDIUM_MAP, Decoration.LARGE_MAP), - BOOKCASE2(15397, BuildHotspotType.INDIVIDUAL, 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. */ - WALL_DECORATION2(15297, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), + WALL_DECORATION2(15297, BuildHotspotType.RECURSIVE, 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), 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), @@ -237,8 +227,8 @@ public enum BuildHotspot { GLOBE(15421, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.GLOBE, Decoration.ORNAMENTAL_GLOBE, Decoration.LUNAR_GLOBE, Decoration.CELESTIAL_GLOBE, Decoration.ARMILLARY_SPHERE, Decoration.SMALL_ORREY, Decoration.LARGE_ORREY), 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), - BOOKCASE3(15425, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), - WALL_CHART(15423, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ALCHEMICAL_CHART, Decoration.ASTRONOMICAL_CHART, Decoration.INFERNAL_CHART), + 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), TELESCOPE(15424, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TELESCOPE1, Decoration.TELESCOPE2, Decoration.TELESCOPE3), /** @@ -394,7 +384,6 @@ public enum BuildHotspot { linkedHotspots.add(new BuildHotspot[] { PRISON, PRISON_DOOR }); linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT, DUNGEON_DOOR_RIGHT }); 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[] { SHELVES, SHELVES_2 }); } @@ -524,4 +513,4 @@ public enum BuildHotspot { return buildingAnimation; } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/construction/BuildingUtils.java b/Server/src/main/content/global/skill/construction/BuildingUtils.java index 424e5aa94..2ee636337 100644 --- a/Server/src/main/content/global/skill/construction/BuildingUtils.java +++ b/Server/src/main/content/global/skill/construction/BuildingUtils.java @@ -90,8 +90,6 @@ public final class BuildingUtils { for (int menuIndex = 0; menuIndex < 7; menuIndex++) { int itemsStringOffset = 97 + (menuIndex * 5); - - //97 + if (menuIndex >= hotspot.getDecorations().length || (hotspot.getDecorations()[menuIndex] != null && hotspot.getDecorations()[menuIndex].isInvisibleNode())) { for (int j = 0; j < 5; j++) { player.getPacketDispatch().sendString("", 396, itemsStringOffset + j); @@ -104,43 +102,24 @@ public final class BuildingUtils { Decoration decoration = hotspot.getDecorations()[menuIndex]; items[BUILD_INDEXES[menuIndex]] = new Item(decoration.getInterfaceItem()); player.getPacketDispatch().sendString(ItemDefinition.forId(decoration.getInterfaceItem()).getName(), 396, itemsStringOffset); - boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel(); + boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel(); //nails are checked in buildDecoration + Item[] reqItems = decoration.getItems(); + String[] reqsText = decoration.getReqsText(); for (int j = 0; j < 4; j++) { - if (j >= decoration.getItems().length) { - if (j == decoration.getItems().length && decoration.getNailAmount() > 0) { - player.getPacketDispatch().sendString("Nails: " + decoration.getNailAmount(), 396, (itemsStringOffset + 1) + j); - } else { - player.getPacketDispatch().sendString("", 396, (itemsStringOffset + 1) + j); - } - } else { - Item item = decoration.getItems()[j]; - if (!player.getInventory().containsItem(item)) { - hasRequirements = false; - } - String s = item.getName() + ": " + item.getAmount(); - /*if (j > 1 && (decoration == Decoration.RUNE_CASE1 || decoration == Decoration.RUNE_CASE2)) { - if (j == 3) { - offset--; - item = decoration.getItems()[++j]; - s = item.getName() + ": " + item.getAmount(); - } - item = decoration.getItems()[j + 1]; - s += ", " + item.getName() + ": " + item.getAmount(); - player.getPacketDispatch().sendString(s, 396, 15 + offset + j); - continue; - }*/ - player.getPacketDispatch().sendString(s, 396, (itemsStringOffset + 1) + j); + if (j < reqItems.length && !player.getInventory().containsItem(reqItems[j])) { + hasRequirements = false; } + player.getPacketDispatch().sendString(reqsText[j], 396, (itemsStringOffset + 1) + j); } if (hasRequirements) { c261Value += (1 << (menuIndex + 1)); } - setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0); + setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0); player.getPacketDispatch().sendString("Level " + decoration.getLevel(), 396, 140 + menuIndex); //player.getPacketDispatch().sendItemZoomOnInterface(items[i].protocol(), 50000, 396, 49 + i); } - setVarp(player, 261, c261Value); + setVarp(player, 261, c261Value); PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 396, 132, 8, items, false)); } @@ -349,7 +328,7 @@ public final class BuildingUtils { */ public static void removeDecoration(Player player, Scenery object) { if (object.getId() == Decoration.PORTAL.getObjectId() && player.getHouseManager().getPortalAmount() <= 1) { - player.getPacketDispatch().sendMessage("You need atleast one portal, how else would you leave your house?"); + sendMessage(player, "You need at least one portal, how else would you leave your house?"); return; } Location l = object.getLocation(); @@ -369,6 +348,10 @@ public final class BuildingUtils { if (objectId == object.getId() && hotspot.getCurrentX() == l.getChunkOffsetX() && hotspot.getCurrentY() == l.getChunkOffsetY()) { player.animate(REMOVE_ANIMATION); removeDecoration(player, region, room, hotspot, object, style); + Decoration decoration = Decoration.forObjectId(object.getId()); + for (Item item : decoration.getRefundItems()) { + addItemOrDrop(player, item.getId(), item.getAmount()); + } break; } } diff --git a/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt b/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt index a6c8beeae..750654efd 100644 --- a/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt +++ b/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt @@ -1,6 +1,7 @@ package content.global.skill.construction import core.api.sendMessage +import core.api.storeBookInHouse import core.game.dialogue.DialogueInterpreter import core.game.interaction.IntType import core.game.interaction.InteractionListener @@ -52,7 +53,7 @@ class ConstructionGuideBook : InteractionListener { override fun defineListeners() { // There is supposedly a book here. - on(Items.CONSTRUCTION_GUIDE_8463, IntType.ITEM, "read") { player, _ -> + on(Items.CONSTRUCTION_GUIDE_8463, IntType.ITEM, "read") { player, node -> if (settings!!.isDevMode && settings!!.isBeta) { for (item in RESOURCES) { if (!player.inventory.contains(item.id, item.amount)) { @@ -60,6 +61,7 @@ class ConstructionGuideBook : InteractionListener { } } } + storeBookInHouse(player, node) sendMessage(player, "Upon reading the book you discover you're supposed to use these resources to test out construction. Report all bugs on the forums.") return@on true } diff --git a/Server/src/main/content/global/skill/construction/CrestType.java b/Server/src/main/content/global/skill/construction/CrestType.java index f54466772..277c77231 100644 --- a/Server/src/main/content/global/skill/construction/CrestType.java +++ b/Server/src/main/content/global/skill/construction/CrestType.java @@ -3,6 +3,7 @@ package content.global.skill.construction; import core.game.node.entity.player.Player; import org.rs09.consts.Items; import core.game.node.entity.skill.Skills; +import content.data.Quests; /** * Family crest types. @@ -16,7 +17,7 @@ public enum CrestType implements CrestRequirement { @Override public boolean eligible(Player player) { - return player.getQuestRepository().isComplete("Shield of Arrav"); + return player.getQuestRepository().isComplete(Quests.SHIELD_OF_ARRAV); } }, ASGARNIA("the symbol of Asgarnia"), // no requirements @@ -24,21 +25,21 @@ public enum CrestType implements CrestRequirement { @Override public boolean eligible(Player player) { - return player.getQuestRepository().isComplete("The Lost Tribe"); + return player.getQuestRepository().isComplete(Quests.THE_LOST_TRIBE); } }, DRAGON("a dragon") { // requires Dragon Slayer @Override public boolean eligible(Player player) { - return player.getQuestRepository().isComplete("Dragon Slayer"); + return player.getQuestRepository().isComplete(Quests.DRAGON_SLAYER); } }, FAIRY("a fairy") { // requries Lost City @Override public boolean eligible(Player player) { - return player.getQuestRepository().isComplete("Lost City"); + return player.getQuestRepository().isComplete(Quests.LOST_CITY); } }, GUTHIX("the symbol of Guthix") { // Requires 70+ Prayer diff --git a/Server/src/main/content/global/skill/construction/Decoration.java b/Server/src/main/content/global/skill/construction/Decoration.java index 058de5a8b..4191cb1a9 100644 --- a/Server/src/main/content/global/skill/construction/Decoration.java +++ b/Server/src/main/content/global/skill/construction/Decoration.java @@ -1,6 +1,4 @@ package content.global.skill.construction; - - import core.game.node.entity.player.Player; import core.game.node.item.Item; import core.game.node.scenery.Scenery; @@ -9,1071 +7,690 @@ import org.rs09.consts.Items; /** * Represents the decorations. - * @author Emperor + * @author Emperor, Player Name * */ public enum Decoration { - /** * Garden centrepiece decorations. */ - PORTAL(13405, 8168, 1, 100.0, new Item(Items.IRON_BAR_2351, 10)), - ROCK(13406, 8169, 5, 100.0, new Item(Items.LIMESTONE_BRICK_3420, 5)), - POND(13407, 8170, 10, 100.0, new Item(Items.SOFT_CLAY_1761, 10)), - IMP_STATUE(13408, 8171, 15, 150.0, new Item(Items.LIMESTONE_BRICK_3420, 5), new Item(Items.SOFT_CLAY_1761, 5)), - SMALL_OBELISK(42004, 14657, 41, 676, new Item(Items.MARBLE_BLOCK_8786, 1), new Item(Items.SPIRIT_SHARDS_12183, 1000), new Item(Items.CRIMSON_CHARM_12160, 10), new Item(Items.BLUE_CHARM_12163, 10)), - DUNGEON_ENTRANCE(13409, 8172, 70, 500.0, new Item(Items.MARBLE_BLOCK_8786)), + PORTAL (13405, 8168, 1, 100, new Item[] { new Item(Items.IRON_BAR_2351, 10) }), + ROCK (13406, 8169, 5, 100, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 5) }), + POND (13407, 8170, 10, 100, new Item[] { new Item(Items.SOFT_CLAY_1761, 10) }), + IMP_STATUE (13408, 8171, 15, 150, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 5), new Item(Items.SOFT_CLAY_1761, 5) }), + SMALL_OBELISK (42004, 14657, 41, 676, new Item[] { new Item(Items.MARBLE_BLOCK_8786), new Item(Items.SPIRIT_SHARDS_12183, 1000), new Item(Items.CRIMSON_CHARM_12160, 10), new Item(Items.BLUE_CHARM_12163, 10) }), + DUNGEON_ENTRANCE(13409, 8172, 70, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), - /** * Garden big tree decorations. */ - BIG_DEAD_TREE(13411, 8173, 5, 31.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_DEAD_TREE_8417)), - BIG_TREE(13412, 8174, 10, 44.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_NICE_TREE_8419)), - BIG_OAK_TREE(13413, 8175, 15, 70.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_OAK_TREE_8421)), - BIG_WILLOW_TREE(13414, 8176, 30, 100.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_WILLOW_TREE_8423)), - BIG_MAPLE_TREE(13415, 8177, 45, 122.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_MAPLE_TREE_8425)), - BIG_YEW_TREE(13416, 8178, 60, 141.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_YEW_TREE_8427)), - BIG_MAGIC_TREE(13417, 8179, 75, 223.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_MAGIC_TREE_8429)), - + BIG_DEAD_TREE (13411, 8173, 5, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DEAD_TREE_8417) }), + BIG_TREE (13412, 8174, 10, 44, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_NICE_TREE_8419) }), + BIG_OAK_TREE (13413, 8175, 15, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_OAK_TREE_8421) }), + BIG_WILLOW_TREE(13414, 8176, 30, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_WILLOW_TREE_8423) }), + BIG_MAPLE_TREE (13415, 8177, 45, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAPLE_TREE_8425) }), + BIG_YEW_TREE (13416, 8178, 60, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_YEW_TREE_8427) }), + BIG_MAGIC_TREE (13417, 8179, 75, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAGIC_TREE_8429) }), + /** * Garden tree decorations. */ - DEAD_TREE(13418, 8173, 5, 31.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_DEAD_TREE_8417)), - TREE(13419, 8174, 10, 44.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_NICE_TREE_8419)), - OAK_TREE(13420, 8175, 15, 70.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_OAK_TREE_8421)), - WILLOW_TREE(13421, 8176, 30, 100.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_WILLOW_TREE_8423)), - MAPLE_TREE(13423, 8177, 45, 122.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_MAPLE_TREE_8425)), - YEW_TREE(13422, 8178, 60, 141.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_YEW_TREE_8427)), - MAGIC_TREE(13424, 8179, 75, 223.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_MAGIC_TREE_8429)), - + DEAD_TREE (13418, 8173, 5, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DEAD_TREE_8417) }), + TREE (13419, 8174, 10, 44, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_NICE_TREE_8419) }), + OAK_TREE (13420, 8175, 15, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_OAK_TREE_8421) }), + WILLOW_TREE(13421, 8176, 30, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_WILLOW_TREE_8423) }), + MAPLE_TREE (13423, 8177, 45, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAPLE_TREE_8425) }), + YEW_TREE (13422, 8178, 60, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_YEW_TREE_8427) }), + MAGIC_TREE (13424, 8179, 75, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAGIC_TREE_8429) }), + /** * Garden big plant 1 decorations. */ - FERN(13425, 8186, 1, 31.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_1_8431)), - BUSH(13426, 8187, 6, 70.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_2_8433)), - TALL_PLANT(13427, 8188, 12, 100.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_3_8435)), - + FERN (13425, 8186, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + BUSH (13426, 8187, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + TALL_PLANT(13427, 8188, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), + /** * Garden big plant 2 decorations. */ - SHORT_PLANT(13428, 8189, 1, 31.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_1_8431)), - LARGE_LEAF_PLANT(13429, 8190, 6, 70.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_2_8433)), - HUGE_PLANT(13430, 8191, 12, 100.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_3_8435)), + SHORT_PLANT (13428, 8189, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + LARGE_LEAF_PLANT(13429, 8190, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + HUGE_PLANT (13430, 8191, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), /** * Garden small plant 1 decorations. */ - PLANT(13431, 8180, 1, 31.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_1_8431)), - SMALL_FERN(13432, 8181, 6, 70.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_2_8433)), - FERN_SP(13433, 8182, 12, 100.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_3_8435)), + PLANT (13431, 8180, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + SMALL_FERN(13432, 8181, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + FERN_SP (13433, 8182, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), /** * Garden small plant 2 decorations. */ - DOCK_LEAF(13434, 8183, 1, 31.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_1_8431)), - THISTLE(13435, 8184, 6, 70.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_2_8433)), - REEDS(13436, 8185, 12, 100.0, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_PLANT_3_8435)), - + DOCK_LEAF(13434, 8183, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + THISTLE (13435, 8184, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + REEDS (13436, 8185, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), + /** * Parlour chair spot */ - CRUDE_CHAIR(13581, 8309, 1, 66.0, new Item(Items.PLANK_960, 2)), - WOODEN_CHAIR(13582, 8310, 8, 96.0, new Item(Items.PLANK_960, 3)), - ROCKING_CHAIR(13583, 8311, 14, 96.0, new Item(Items.PLANK_960, 3)), - OAK_CHAIR(13584, 8312, 19, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - OAK_ARMCHAIR(13585, 8313, 26, 180.0, new Item(Items.OAK_PLANK_8778, 3)), - TEAK_ARMCHAIR(13586, 8314, 35, 180.0, new Item(Items.TEAK_PLANK_8780, 2)), - MAHOGANY_ARMCHAIR(13587, 8315, 50, 280.0, new Item(Items.MAHOGANY_PLANK_8782, 2)), + CRUDE_CHAIR (13581, 8309, 1, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + WOODEN_CHAIR (13582, 8310, 8, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + ROCKING_CHAIR (13583, 8311, 14, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + OAK_CHAIR (13584, 8312, 19, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + OAK_ARMCHAIR (13585, 8313, 26, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + TEAK_ARMCHAIR (13586, 8314, 35, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_ARMCHAIR(13587, 8315, 50, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), /** * Rugs rugs rugs */ - BROWN_RUG_CORNER(13588, 8316, 2, 30.0, new Item(Items.BOLT_OF_CLOTH_8790, 2)), - RED_RUG_CORNER(13591, 8317, 13, 60.0, new Item(Items.BOLT_OF_CLOTH_8790, 4)), - OPULENT_RUG_CORNER(13594, 8318, 65, 360.0, new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 1)), - - BROWN_RUG_END(13589, 8316, 2, 30.0, new Item(Items.BOLT_OF_CLOTH_8790, 2)), - RED_RUG_END(13592, 8317, 13, 60.0, new Item(Items.BOLT_OF_CLOTH_8790, 4)), - OPULENT_RUG_END(13595, 8318, 65, 360.0, new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 1)), - - BROWN_RUG_CENTER(13590, 8316, 2, 30.0, new Item(Items.BOLT_OF_CLOTH_8790, 2)), - RED_RUG_CENTER(13593, 8317, 13, 60.0, new Item(Items.BOLT_OF_CLOTH_8790, 4)), - OPULENT_RUG_CENTER(13596, 8318, 65, 360.0, new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 1)), + BROWN_RUG_CORNER (13588, 8316, 2, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + RED_RUG_CORNER (13591, 8317, 13, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + OPULENT_RUG_CORNER(13594, 8318, 65, 360, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784) }), + BROWN_RUG_END (13589, 8316, 2, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + RED_RUG_END (13592, 8317, 13, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + OPULENT_RUG_END (13595, 8318, 65, 360, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784) }), + BROWN_RUG_CENTER (13590, 8316, 2, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + RED_RUG_CENTER (13593, 8317, 13, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + OPULENT_RUG_CENTER(13596, 8318, 65, 360, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784) }), /** * Parlour fireplaces */ - CLAY_FIREPLACE(13609, 8325, 3, 30.0, new Item(Items.SOFT_CLAY_1761, 3)), - STONE_FIREPLACE(13611, 8326, 33, 40.0, new Item(Items.LIMESTONE_BRICK_3420, 2)), - MARBLE_FIREPLACE(13613, 8327, 63, 500.0, new Item(Items.MARBLE_BLOCK_8786, 1)), + CLAY_FIREPLACE (13609, 8325, 3, 30, new Item[] { new Item(Items.SOFT_CLAY_1761, 3) }), + STONE_FIREPLACE (13611, 8326, 33, 40, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 2) }), + MARBLE_FIREPLACE(13613, 8327, 63, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), /** * Parlour curtain spot */ - TORN_CURTAINS(13603, 8322, 2, 132.0, new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3)), - CURTAINS(13604, 8323, 18, 225.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3)), - OPULENT_CURTAINS(13605, 8324, 40, 315.0, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3)), + TORN_CURTAINS (13603, 8322, 2, 132, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + CURTAINS (13604, 8323, 18, 225, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + OPULENT_CURTAINS(13605, 8324, 40, 315, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3) }), /** - * Parlour bookcases + * Bookcases */ - WOODEN_BOOKCASE(13597, 8319, 4, 132.0, new Item(Items.PLANK_960, 4)), - OAK_BOOKCASE(13598, 8320, 29, 225.0, new Item(Items.OAK_PLANK_8778, 3)), - MAHOGANY_BOOKCASE(13599, 8321, 40, 315.0, new Item(Items.MAHOGANY_PLANK_8782, 3)), + WOODEN_BOOKCASE (13597, 8319, 4, 115, new Item[] { new Item(Items.PLANK_960, 4) }), + OAK_BOOKCASE (13598, 8320, 29, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + MAHOGANY_BOOKCASE(13599, 8321, 40, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), - /** * Kitchen Beer Barrels * TODO: These also require cooking levels! * Basic: 1, Cider: 14, Asgarnian: 24, Greenman's: 29, D.Bitter: 39, Chef's: 54 * */ - BASIC_BEER_BARREL(13568, 8239, 7, 87.0, new Item(Items.PLANK_960, 3)), - CIDER_BARREL(13569, 8240, 12, 91.0, new Item(Items.PLANK_960, 3), new Item(Items.CIDER_5763, 8)), - ASGARNIAN_ALE_BARREL(13570, 8241, 18, 184.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.ASGARNIAN_ALE_1905, 8)), - GREENMANS_ALE_BARREL(13571, 8242, 26, 184.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.GREENMANS_ALE_1909, 8)), - DRAGON_BITTER_BARREL(13572, 8243, 36, 224.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.DRAGON_BITTER_1911, 8), new Item(Items.STEEL_BAR_2353, 2)), - CHEFS_DELIGHT_BARREL(13573, 8244, 48, 224.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.CHEFS_DELIGHT_5755, 8), new Item(Items.STEEL_BAR_2353, 2)), - - + BASIC_BEER_BARREL (13568, 8239, 7, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + CIDER_BARREL (13569, 8240, 12, 91, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.CIDER_5763, 8) }), + ASGARNIAN_ALE_BARREL(13570, 8241, 18, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.ASGARNIAN_ALE_1905, 8) }), + GREENMANS_ALE_BARREL(13571, 8242, 26, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.GREENMANS_ALE_1909, 8) }), + DRAGON_BITTER_BARREL(13572, 8243, 36, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.DRAGON_BITTER_1911, 8), new Item(Items.STEEL_BAR_2353, 2) }), + CHEFS_DELIGHT_BARREL(13573, 8244, 48, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.CHEFS_DELIGHT_5755, 8), new Item(Items.STEEL_BAR_2353, 2) }), + /** * Kitchen Tables! */ - KITCHEN_WOODEN_TABLE(13577, 8246, 12, 87.0, new Item(Items.PLANK_960, 3)), - KITCHEN_OAK_TABLE(13578, 8247, 32, 180.0, new Item(Items.OAK_PLANK_8778, 3)), - KITCHEN_TEAK_TABLE(13579, 8248, 52, 270.0, new Item(Items.TEAK_PLANK_8780, 3)), - - + KITCHEN_WOODEN_TABLE(13577, 8246, 12, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + KITCHEN_OAK_TABLE (13578, 8247, 32, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + KITCHEN_TEAK_TABLE (13579, 8248, 52, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + /** * Kitchen Stoves */ - BASIC_FIREPIT(13528, 8216, 5, 40.0, new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 1)), - FIREPIT_WITH_HOOK(13529, 8217, 11, 60.0, new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 2)), - FIREPIT_WITH_POT(13531, 8218, 17, 80.0, new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 3)), - SMALL_OVEN(13533, 8219, 24, 80.0, new Item(Items.STEEL_BAR_2353, 4)), - LARGE_OVEN(13536, 8220, 29, 100.0, new Item(Items.STEEL_BAR_2353, 5)), - BASIC_RANGE(13539, 8221, 34, 120.0, new Item(Items.STEEL_BAR_2353, 6)), - FANCY_RANGE(13542, 8222, 42, 160.0, new Item(Items.STEEL_BAR_2353, 8)), - + BASIC_FIREPIT (13528, 8216, 5, 40, new Item[] { new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353) }), + FIREPIT_WITH_HOOK(13529, 8217, 11, 60, new Item[] { new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 2) }), + FIREPIT_WITH_POT (13531, 8218, 17, 80, new Item[] { new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 3) }), + SMALL_OVEN (13533, 8219, 24, 80, new Item[] { new Item(Items.STEEL_BAR_2353, 4) }), + LARGE_OVEN (13536, 8220, 29, 100, new Item[] { new Item(Items.STEEL_BAR_2353, 5) }), + BASIC_RANGE (13539, 8221, 34, 120, new Item[] { new Item(Items.STEEL_BAR_2353, 6) }), + FANCY_RANGE (13542, 8222, 42, 160, new Item[] { new Item(Items.STEEL_BAR_2353, 8) }), + /** * Kitchen larders */ - WOODEN_LARDER(13565, 8233, 9, 228.0, new Item(Items.PLANK_960, 8)), - OAK_LARDER(13566, 8234, 33, 480.0, new Item(Items.OAK_PLANK_8778, 8)), - TEAK_LARDER(13567, 8235, 43, 750.0, new Item(Items.TEAK_PLANK_8780, 8), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - - + WOODEN_LARDER(13565, 8233, 9, 228, new Item[] { new Item(Items.PLANK_960, 8) }), + OAK_LARDER (13566, 8234, 33, 480, new Item[] { new Item(Items.OAK_PLANK_8778, 8) }), + TEAK_LARDER (13567, 8235, 43, 750, new Item[] { new Item(Items.TEAK_PLANK_8780, 8), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + /** * Kitchen shelves */ - WOODEN_SHELVES_1(13545, 8223, 6, 87.0, new Item(Items.PLANK_960, 3)), - WOODEN_SHELVES_2(13546, 8224, 12, 147.0, new Item(Items.PLANK_960, 3), new Item(Items.SOFT_CLAY_1761, 6)), - WOODEN_SHELVES_3(13547, 8225, 23, 147.0, new Item(Items.PLANK_960, 3), new Item(Items.SOFT_CLAY_1761, 6)), - OAK_SHELVES_1(13548, 8226, 34, 240.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.SOFT_CLAY_1761, 6)), - OAK_SHELVES_2(13549, 8227, 45, 240.0, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.SOFT_CLAY_1761, 6)), - TEAK_SHELVES_1(13550, 8228, 56, 330.0, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SOFT_CLAY_1761, 6)), - TEAK_SHELVES_2(13551, 8229, 67, 930.0, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SOFT_CLAY_1761, 6), new Item(Items.GOLD_LEAF_8784, 2)), - + WOODEN_SHELVES_1(13545, 8223, 6, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + WOODEN_SHELVES_2(13546, 8224, 12, 147, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + WOODEN_SHELVES_3(13547, 8225, 23, 147, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + OAK_SHELVES_1 (13548, 8226, 34, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + OAK_SHELVES_2 (13549, 8227, 45, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + TEAK_SHELVES_1 (13550, 8228, 56, 330, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + TEAK_SHELVES_2 (13551, 8229, 67, 930, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SOFT_CLAY_1761, 6), new Item(Items.GOLD_LEAF_8784, 2) }), + /** * Kitchen sinks */ - PUMP_AND_DRAIN(13559, 8230, 7, 100.0, new Item(Items.STEEL_BAR_2353, 5)), - PUMP_AND_TUB(13561, 8231, 27, 200.0, new Item(Items.STEEL_BAR_2353, 10)), - SINK(13563, 8232, 47, 300.0, new Item(Items.STEEL_BAR_2353, 15)), - - + PUMP_AND_DRAIN(13559, 8230, 7, 100, new Item[] { new Item(Items.STEEL_BAR_2353, 5) }), + PUMP_AND_TUB (13561, 8231, 27, 200, new Item[] { new Item(Items.STEEL_BAR_2353, 10) }), + SINK (13563, 8232, 47, 300, new Item[] { new Item(Items.STEEL_BAR_2353, 15) }), + /** * Kitchen cat baskets/blankets */ - CAT_BLANKET(13574, 8236, 5, 15.0, new Item(Items.BOLT_OF_CLOTH_8790, 1)), - CAT_BASKET(13575, 8237, 19, 58.0, new Item(Items.PLANK_960, 2)), - CAST_BASKET_CUSHIONED(13576, 8238, 33, 58.0, new Item(Items.PLANK_960, 2), new Item(Items.WOOL_1737, 2)), - - + CAT_BLANKET (13574, 8236, 5, 15, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790) }), + CAT_BASKET (13575, 8237, 19, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + CAST_BASKET_CUSHIONED(13576, 8238, 33, 58, new Item[] { new Item(Items.PLANK_960, 2), new Item(Items.WOOL_1737, 2) }), + /** * Dining room tables */ - DINING_TABLE_WOOD(13293, 8246, 10, 115.0, new Item(Items.PLANK_960, 4)), - DINING_TABLE_OAK(13294, 8247, 22, 240.0, new Item(Items.OAK_PLANK_8778, 4)), - DINING_TABLE_CARVED_OAK(13295, 8247, 31, 360.0, new Item(Items.OAK_PLANK_8778, 6)), - DINING_TABLE_TEAK(13296, 8248, 38, 360.0, new Item(Items.TEAK_PLANK_8780, 4)), - DINING_TABLE_CARVED_TEAK(13297, 8248, 45, 600.0, new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - DINING_TABLE_MAHOGANY(13298, 8120, 52, 840.0, new Item(Items.MAHOGANY_PLANK_8782, 6)), - DINING_TABLE_OPULENT(13299, 8121, 72, 3100.0, new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4), - new Item(Items.GOLD_LEAF_8784, 4), new Item(Items.MARBLE_BLOCK_8786, 2)), - + DINING_TABLE_WOOD (13293, 8246, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }), + DINING_TABLE_OAK (13294, 8247, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + DINING_TABLE_CARVED_OAK (13295, 8247, 31, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }), + DINING_TABLE_TEAK (13296, 8248, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + DINING_TABLE_CARVED_TEAK(13297, 8248, 45, 600, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + DINING_TABLE_MAHOGANY (13298, 8120, 52, 840, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }), + DINING_TABLE_OPULENT (13299, 8121, 72, 3100, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 4), new Item(Items.MARBLE_BLOCK_8786, 2) }), /** * Dining room benches */ - BENCH_WOODEN(13300, 8108, 10, 115.0, new Item(Items.PLANK_960, 4)), - BENCH_OAK(13301, 8109, 22, 240.0, new Item(Items.OAK_PLANK_8778, 4)), - BENCH_CARVED_OAK(13302, 8110, 31, 240.0, new Item(Items.OAK_PLANK_8778, 4)), - BENCH_TEAK(13303, 8111, 38, 360.0, new Item(Items.TEAK_PLANK_8780, 4)), - BENCH_CARVED_TEAK(13304, 8112, 44, 360.0, new Item(Items.TEAK_PLANK_8780, 4)), - BENCH_MAHOGANY(13305, 8113, 52, 560.0, new Item(Items.MAHOGANY_PLANK_8782, 6)), - BENCH_GILDED(13306, 8114, 61, 1760.0, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4)), - + BENCH_WOODEN (13300, 8108, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }), + BENCH_OAK (13301, 8109, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + BENCH_CARVED_OAK (13302, 8110, 31, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + BENCH_TEAK (13303, 8111, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + BENCH_CARVED_TEAK(13304, 8112, 44, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + BENCH_MAHOGANY (13305, 8113, 52, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }), + BENCH_GILDED (13306, 8114, 61, 1760, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4) }), + /** * Dining room bell-pulls */ - ROPE_PULL(13307, 8099, 5, 15.0, new Item(Items.ROPE_954, 1), new Item(Items.OAK_PLANK_8778, 1)), - BELL_PULL(13308, 8100, 19, 58.0, new Item(Items.TEAK_PLANK_8780, 1), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - FANCY_BELL_PULL(13309, 8101, 33, 58.0, new Item(Items.TEAK_PLANK_8780, 1), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 1)), - + ROPE_PULL (13307, 8099, 5, 15, new Item[] { new Item(Items.ROPE_954), new Item(Items.OAK_PLANK_8778) }), + BELL_PULL (13308, 8100, 19, 58, new Item[] { new Item(Items.TEAK_PLANK_8780), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + FANCY_BELL_PULL(13309, 8101, 33, 58, new Item[] { new Item(Items.TEAK_PLANK_8780), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784) }), + /** * Workshop workbench */ - WORKBENCH_WOODEN(13704, 8375, 17, 145.0, new Item(Items.PLANK_960, 1)), - WORKBENCH_OAK(13705, 8376, 32, 300.0, new Item(Items.OAK_PLANK_8778, 5)), - WORKBENCH_STEEL_FRAME(13706, 8377, 46, 440.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.STEEL_BAR_2353, 4)), - WORKBENCH_WITH_VICE(13707, 8378, 62, 750.0, new Item(Items.STEEL_FRAMED_BENCH_8377, 1), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353, 1)), - WORKBENCH_WITH_LATHE(13708, 8379, 77, 1000.0, new Item(Items.OAK_WORKBENCH_8376, 1), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353, 1)), - + WORKBENCH_WOODEN (13704, 8375, 17, 143, new Item[] { new Item(Items.PLANK_960, 5) }), + WORKBENCH_OAK (13705, 8376, 32, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + WORKBENCH_STEEL_FRAME(13706, 8377, 46, 440, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.STEEL_BAR_2353, 4) }), + WORKBENCH_WITH_VICE (13707, 8378, 62, 750, new Item[] { new Item(Items.STEEL_FRAMED_BENCH_8377), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }), + WORKBENCH_WITH_LATHE (13708, 8379, 77, 1000, new Item[] { new Item(Items.OAK_WORKBENCH_8376), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }), + /** * Workshop repair benches/stands */ - REPAIR_BENCH(13713, 8389, 15, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - WHETSTONE(13714, 8390, 35, 260.0, new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIMESTONE_BRICK_3420, 1)), - ARMOUR_STAND(13715, 8391, 55, 500.0, new Item(Items.OAK_PLANK_8778, 8), new Item(Items.LIMESTONE_BRICK_3420, 1)), - + REPAIR_BENCH(13713, 8389, 15, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + WHETSTONE (13714, 8390, 35, 260, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIMESTONE_BRICK_3420) }), + ARMOUR_STAND(13715, 8391, 55, 500, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.LIMESTONE_BRICK_3420) }), + /** * Workshop easels */ - PLUMING_STAND(13716, 8392, 16, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - SHIELD_EASEL(13717, 8393, 41, 240.0, new Item(Items.OAK_PLANK_8778, 4)), - BANNER_EASEL(13718, 8394, 66, 510.0, new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - + PLUMING_STAND(13716, 8392, 16, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + SHIELD_EASEL (13717, 8393, 41, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + BANNER_EASEL (13718, 8394, 66, 510, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + /** * Workshop crafting tables * TODO: These are upgradable hotspots, therefore crafting table 3 would require * crafting table 2 to be already built in that spot. */ - CRAFTING_TABLE_1(13709, 8380, 16, 50.0, new Item(Items.OAK_PLANK_8778, 4)), - CRAFTING_TABLE_2(13710, 8381, 25, 100.0, new Item(Items.MOLTEN_GLASS_1775, 1)), - CRAFTING_TABLE_3(13711, 8382, 34, 175.0, new Item(Items.MOLTEN_GLASS_1775, 2)), - CRAFTING_TABLE_4(13712, 8383, 42, 240.0, new Item(Items.OAK_PLANK_8778, 2)), - + CRAFTING_TABLE_1(13709, 8380, 16, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + CRAFTING_TABLE_2(13710, 8381, 25, 1, new Item[] { new Item(Items.MOLTEN_GLASS_1775) }), + CRAFTING_TABLE_3(13711, 8382, 34, 2, new Item[] { new Item(Items.MOLTEN_GLASS_1775, 2) }), + CRAFTING_TABLE_4(13712, 8383, 42, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + /** * Workshop tool stores * These are also upgradable just like the tables above. */ - TOOL_STORE_1(13699, 8384, 15, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - TOOL_STORE_2(13700, 8385, 25, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - TOOL_STORE_3(13701, 8386, 35, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - TOOL_STORE_4(13702, 8387, 44, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - TOOL_STORE_5(13703, 8388, 55, 120.0, new Item(Items.OAK_PLANK_8778, 2)), + TOOL_STORE_1(13699, 8384, 15, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_2(13700, 8385, 25, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_3(13701, 8386, 35, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_4(13702, 8387, 44, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_5(13703, 8388, 55, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), - /** * Wall-mounted decorations */ - OAK_DECORATION(13606, 8102, 16, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - TEAK_DECORATION(13606, 8103, 36, 180.0, new Item(Items.TEAK_PLANK_8780, 2)), - GILDED_DECORATION(13607, 8104, 56, 1020.0, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 2)), - + OAK_DECORATION (13606, 8102, 16, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_DECORATION (13606, 8103, 36, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + GILDED_DECORATION(13607, 8104, 56, 1020, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 2) }), + /** * Staircases. */ - OAK_STAIRCASE(13497, 8249, 27, 680.0, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 4)), - TEAK_STAIRCASE(13499, 8252, 48, 980.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 4)), - SPIRAL_STAIRCASE(13503, 8258, 67, 1040.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.LIMESTONE_BRICK_3420, 7)), - MARBLE_STAIRCASE(13501, 8257, 82, 3200.0, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 5)), - MARBLE_SPIRAL(13505, 8259, 97, 4400.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.MARBLE_BLOCK_8786, 7)), - + OAK_STAIRCASE (13497, 8249, 27, 680, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 4) }), + TEAK_STAIRCASE (13499, 8252, 48, 980, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 4) }), + SPIRAL_STAIRCASE(13503, 8258, 67, 1040, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.LIMESTONE_BRICK_3420, 7) }), + MARBLE_STAIRCASE(13501, 8257, 82, 3200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 5) }), + MARBLE_SPIRAL (13505, 8259, 97, 4400, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.MARBLE_BLOCK_8786, 7) }), + /** * Staircases going down. */ - OAK_STAIRS_DOWN(13498, 8249, 27, 680.0, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 4)), - TEAK_STAIRS_DOWN(13500, 8252, 48, 980.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 4)), - SPIRAL_STAIRS_DOWN(13504, 8258, 67, 1040.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.LIMESTONE_BRICK_3420, 7)), - MARBLE_STAIRS_DOWN(13502, 8257, 82, 3200.0, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 5)), - MARBLE_SPIRAL_DOWN(13506, 8259, 97, 4400.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.MARBLE_BLOCK_8786, 7)), - + OAK_STAIRS_DOWN (13498, 8249, 27, 680, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 4) }), + TEAK_STAIRS_DOWN (13500, 8252, 48, 980, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 4) }), + SPIRAL_STAIRS_DOWN(13504, 8258, 67, 1040, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.LIMESTONE_BRICK_3420, 7) }), + MARBLE_STAIRS_DOWN(13502, 8257, 82, 3200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 5) }), + MARBLE_SPIRAL_DOWN(13506, 8259, 97, 4400, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.MARBLE_BLOCK_8786, 7) }), + /** * Portal room decorations. */ - TEAK_PORTAL(13636, 8328, 50, 270.0, new Item(Items.TEAK_PLANK_8780, 3)), - MAHOGANY_PORTAL(13637, 8329, 65, 420.0, new Item(Items.MAHOGANY_PLANK_8782, 3)), - MARBLE_PORTAL(13638, 8330, 80, 1500.0, new Item(Items.MARBLE_BLOCK_8786, 3)), - TELEPORT_FOCUS(13640, 8331, 50, 40, new Item(Items.LIMESTONE_BRICK_3420, 2)), - GREATER_TELEPORT_FOCUS(13641, 8332, 65, 500.0, new Item(Items.MARBLE_BLOCK_8786, 1)), - SCRYING_POOL(13639, 8333, 80, 2000.0, new Item(Items.MARBLE_BLOCK_8786, 4)), - TEAK_VARROCK_PORTAL(13615, true), - MAHOGANY_VARROCK_PORTAL(13622, true), - MARBLE_VARROCK_PORTAL(13629, true), - TEAK_LUMBRIDGE_PORTAL(13616, true), + TEAK_PORTAL (13636, 8328, 50, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + MAHOGANY_PORTAL (13637, 8329, 65, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + MARBLE_PORTAL (13638, 8330, 80, 1500, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 3) }), + TELEPORT_FOCUS (13640, 8331, 50, 40, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 2) }), + GREATER_TELEPORT_FOCUS (13641, 8332, 65, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + SCRYING_POOL (13639, 8333, 80, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + TEAK_VARROCK_PORTAL (13615, true), + MAHOGANY_VARROCK_PORTAL (13622, true), + MARBLE_VARROCK_PORTAL (13629, true), + TEAK_LUMBRIDGE_PORTAL (13616, true), MAHOGANY_LUMBRIDGE_PORTAL(13623, true), - MARBLE_LUMBRIDGE_PORTAL(13630, true), - TEAK_FALADOR_PORTAL(13617, true), - MAHOGANY_FALADOR_PORTAL(13624, true), - MARBLE_FALADOR_PORTAL(13631, true), - TEAK_CAMELOT_PORTAL(13618, true), - MAHOGANY_CAMELOT_PORTAL(13625, true), - MARBLE_CAMELOT_PORTAL(13632, true), - TEAK_ARDOUGNE_PORTAL(13619, true), - MAHOGANY_ARDOUGNE_PORTAL(13626, true), - MARBLE_ARDOUGNE_PORTAL(13633, true), - TEAK_YANILLE_PORTAL(13620, true), - MAHOGANY_YANILLE_PORTAL(13627, true), - MARBLE_YANILLE_PORTAL(13634, true), - TEAK_KHARYRLL_PORTAL(13621, true), - MAHOGANY_KHARYRLL_PORTAL(13628, true), - MARBLE_KHARYRLL_PORTAL(13635, true), - + MARBLE_LUMBRIDGE_PORTAL (13630, true), + TEAK_FALADOR_PORTAL (13617, true), + MAHOGANY_FALADOR_PORTAL (13624, true), + MARBLE_FALADOR_PORTAL (13631, true), + TEAK_CAMELOT_PORTAL (13618, true), + MAHOGANY_CAMELOT_PORTAL (13625, true), + MARBLE_CAMELOT_PORTAL (13632, true), + TEAK_ARDOUGNE_PORTAL (13619, true), + MAHOGANY_ARDOUGNE_PORTAL (13626, true), + MARBLE_ARDOUGNE_PORTAL (13633, true), + TEAK_YANILLE_PORTAL (13620, true), + MAHOGANY_YANILLE_PORTAL (13627, true), + MARBLE_YANILLE_PORTAL (13634, true), + TEAK_KHARYRLL_PORTAL (13621, true), + MAHOGANY_KHARYRLL_PORTAL (13628, true), + MARBLE_KHARYRLL_PORTAL (13635, true), + /** * Skill hall decorations. */ - MITHRIL_ARMOUR(13491, 8270, 28, 135.0, new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MITHRIL_FULL_HELM_1159, 1), new Item(Items.MITHRIL_PLATEBODY_1121, 1), new Item(Items.MITHRIL_PLATESKIRT_1085, 1)), - ADAMANT_ARMOUR(13492, 8271, 28, 150.0, new Item(Items.OAK_PLANK_8778, 2), new Item(Items.ADAMANT_FULL_HELM_1161, 1), new Item(Items.ADAMANT_PLATEBODY_1123, 1), new Item(Items.ADAMANT_PLATESKIRT_1091, 1)), - RUNE_ARMOUR(13493, 8272, 28, 165.0, new Item(Items.OAK_PLANK_8778, 2),new Item(Items.RUNE_FULL_HELM_1163, 1), new Item(Items.RUNE_PLATEBODY_1127, 1), new Item(Items.RUNE_PLATESKIRT_1093, 1)), - CRAWLING_HAND(13481, 8260, 38, 211.0, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CRAWLING_HAND_7982, 1)), - COCKATRICE_HEAD(13482, 8261, 38, 224.0, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.COCKATRICE_HEAD_7983, 1)), - BASILISK_HEAD(13483, 8262, 38, 243.0, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.BASILISK_HEAD_7984, 1)), - KURASK_HEAD(13484, 8263, 58, 357.0, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KURASK_HEAD_7985, 1)), - ABYSSAL_DEMON_HEAD(13485, 8264, 58, 389.0, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.ABYSSAL_HEAD_7986, 1)), - KBD_HEAD(13486, 8265, 78, 1103.0, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KBD_HEADS_7987, 1)), - KQ_HEAD(13487, 8266, 78, 1103.0, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KQ_HEAD_7988, 1)), - MOUNTED_BASS(13488, 8267, 36, 151.0, new Item(Items.OAK_PLANK_8778, 2), new Item(Items.BIG_BASS_7990, 1)), - MOUNTED_SWORDFISH(13489, 8268, 56, 230.0, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.BIG_SWORDFISH_7992, 1)), - MOUNTED_SHARK(13490, 8269, 76, 350.0, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.BIG_SHARK_7994, 1)), - RUNE_CASE1(13507, 8095, 41, 190.0, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.FIRE_RUNE_554, 1), new Item(Items.AIR_RUNE_556, 1), new Item(Items.EARTH_RUNE_557, 1), new Item(Items.WATER_RUNE_555, 1)), - RUNE_CASE2(13508, 8095, 41, 212.0, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.BODY_RUNE_559, 1), new Item(Items.COSMIC_RUNE_564, 1), new Item(Items.CHAOS_RUNE_562, 1), new Item(Items.NATURE_RUNE_561, 1)), - - + MITHRIL_ARMOUR (13491, 8270, 28, 135, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MITHRIL_FULL_HELM_1159, 1), new Item(Items.MITHRIL_PLATEBODY_1121, 1), new Item(Items.MITHRIL_PLATESKIRT_1085, 1) }, new Item[] { new Item(Items.MITHRIL_FULL_HELM_1159, 1), new Item(Items.MITHRIL_PLATEBODY_1121, 1), new Item(Items.MITHRIL_PLATESKIRT_1085, 1) }), + ADAMANT_ARMOUR (13492, 8271, 28, 150, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.ADAMANT_FULL_HELM_1161, 1), new Item(Items.ADAMANT_PLATEBODY_1123, 1), new Item(Items.ADAMANT_PLATESKIRT_1091, 1) }, new Item[] { new Item(Items.ADAMANT_FULL_HELM_1161, 1), new Item(Items.ADAMANT_PLATEBODY_1123, 1), new Item(Items.ADAMANT_PLATESKIRT_1091, 1) }), + RUNE_ARMOUR (13493, 8272, 28, 165, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.RUNE_FULL_HELM_1163, 1), new Item(Items.RUNE_PLATEBODY_1127, 1), new Item(Items.RUNE_PLATESKIRT_1093, 1) }, new Item[] { new Item(Items.RUNE_FULL_HELM_1163, 1), new Item(Items.RUNE_PLATEBODY_1127, 1), new Item(Items.RUNE_PLATESKIRT_1093, 1) }), + CRAWLING_HAND (13481, 8260, 38, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CRAWLING_HAND_7982) }), + COCKATRICE_HEAD (13482, 8261, 38, 224, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.COCKATRICE_HEAD_7983) }), + BASILISK_HEAD (13483, 8262, 38, 243, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.BASILISK_HEAD_7984) }), + KURASK_HEAD (13484, 8263, 58, 357, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KURASK_HEAD_7985) }), + ABYSSAL_DEMON_HEAD(13485, 8264, 58, 389, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.ABYSSAL_HEAD_7986) }), + KBD_HEAD (13486, 8265, 78, 1103, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KBD_HEADS_7987) }), + KQ_HEAD (13487, 8266, 78, 1103, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KQ_HEAD_7988) }), + MOUNTED_BASS (13488, 8267, 36, 151, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.BIG_BASS_7990) }), + MOUNTED_SWORDFISH (13489, 8268, 56, 230, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.BIG_SWORDFISH_7992) }), + MOUNTED_SHARK (13490, 8269, 76, 350, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.BIG_SHARK_7994) }), + RUNE_CASE1 (13507, 8095, 41, 190, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.FIRE_RUNE_554, 1), new Item(Items.AIR_RUNE_556, 1), new Item(Items.EARTH_RUNE_557, 1), new Item(Items.WATER_RUNE_555, 1) }), + RUNE_CASE2 (13508, 8095, 41, 212, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.BODY_RUNE_559, 1), new Item(Items.COSMIC_RUNE_564, 1), new Item(Items.CHAOS_RUNE_562, 1), new Item(Items.NATURE_RUNE_561, 1) }), + /** * Games room decorations. */ - CLAY_STONE(13392, 8153, 39, 100.0, new Item(Items.SOFT_CLAY_1761, 10)), - LIMESTONE_STONE(13393, 8154, 59, 200.0, new Item(Items.LIMESTONE_BRICK_3420, 10)), - MARBLE_STONE(13394, 8155, 79, 2000.0, new Item(Items.MARBLE_BLOCK_8786, 4)), - HOOP_AND_STICK(13398, 8162, 30, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - DARTBOARD(13400, 8163, 54, 290.0, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.STEEL_BAR_2353, 1)), - ARCHERY_TARGET(13402, 8164, 81, 600.0, new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.STEEL_BAR_2353, 3)), - BALANCE_1(13395, 8156, 37, 176.0, new Item(Items.FIRE_RUNE_554, 500), new Item(Items.AIR_RUNE_556, 500), new Item(Items.EARTH_RUNE_557, 500), new Item(Items.WATER_RUNE_555, 500)), - BALANCE_2(13396, 8157, 57, 252.0, new Item(Items.FIRE_RUNE_554, 1000), new Item(Items.AIR_RUNE_556, 1000), new Item(Items.EARTH_RUNE_557, 1000), new Item(Items.WATER_RUNE_555, 1000)), - BALANCE_3(13397, 8158, 77, 356.0, new Item(Items.FIRE_RUNE_554, 2000), new Item(Items.AIR_RUNE_556, 2000), new Item(Items.EARTH_RUNE_557, 2000), new Item(Items.WATER_RUNE_555, 2000)), - OAK_CHEST(13385, 8165, 34, 240.0, new Item(Items.OAK_PLANK_8778, 4)), - TEAK_CHEST(13387, 8166, 44, 660.0, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 1)), - MAHOGANY_CHEST(13389, 8167, 54, 860.0, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 1)), - JESTER(13390, 8159, 39, 360.0, new Item(Items.TEAK_PLANK_8780, 4)), - TREASURE_HUNT(13379, 8160, 49, 800.0, new Item(Items.TEAK_PLANK_8780, 8), new Item(Items.STEEL_BAR_2353, 4)), - HANGMAN(13404, 8161, 59, 1200.0, new Item(Items.TEAK_PLANK_8780, 12), new Item(Items.STEEL_BAR_2353, 6)), - - + CLAY_STONE (13392, 8153, 39, 100, new Item[] { new Item(Items.SOFT_CLAY_1761, 10) }), + LIMESTONE_STONE(13393, 8154, 59, 200, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 10) }), + MARBLE_STONE (13394, 8155, 79, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + HOOP_AND_STICK (13398, 8162, 30, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + DARTBOARD (13400, 8163, 54, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.STEEL_BAR_2353) }), + ARCHERY_TARGET (13402, 8164, 81, 600, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.STEEL_BAR_2353, 3) }), + BALANCE_1 (13395, 8156, 37, 176, new Item[] { new Item(Items.FIRE_RUNE_554, 500), new Item(Items.AIR_RUNE_556, 500), new Item(Items.EARTH_RUNE_557, 500), new Item(Items.WATER_RUNE_555, 500) }), + BALANCE_2 (13396, 8157, 57, 252, new Item[] { new Item(Items.FIRE_RUNE_554, 1000), new Item(Items.AIR_RUNE_556, 1000), new Item(Items.EARTH_RUNE_557, 1000), new Item(Items.WATER_RUNE_555, 1000) }), + BALANCE_3 (13397, 8158, 77, 356, new Item[] { new Item(Items.FIRE_RUNE_554, 2000), new Item(Items.AIR_RUNE_556, 2000), new Item(Items.EARTH_RUNE_557, 2000), new Item(Items.WATER_RUNE_555, 2000) }), + OAK_CHEST (13385, 8165, 34, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + TEAK_CHEST (13387, 8166, 44, 660, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784) }), + MAHOGANY_CHEST (13389, 8167, 54, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }), + JESTER (13390, 8159, 39, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + TREASURE_HUNT (13379, 8160, 49, 800, new Item[] { new Item(Items.TEAK_PLANK_8780, 8), new Item(Items.STEEL_BAR_2353, 4) }), + HANGMAN (13404, 8161, 59, 1200, new Item[] { new Item(Items.TEAK_PLANK_8780, 12), new Item(Items.STEEL_BAR_2353, 6) }), + /** * Combat room decorations. */ - BOXING_RING(13129, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - FENCING_RING(13133, 8024, 41, 570.0, new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - COMBAT_RING(13137, 8025, 51, 630.0, new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - BALANCE_BEAM_LEFT(13143, 8027, 81, 1000.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5)), - BALANCE_BEAM_CENTER(13142, 8027, 81, 1000.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5)), - BALANCE_BEAM_RIGHT(13144, 8027, 81, 1000.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5)), - RANGING_PEDESTALS(13147, 8026, 71, 720.0, new Item(Items.TEAK_PLANK_8780, 8)), - MAGIC_BARRIER(13145, 8026, 71, 720.0, new Item(Items.TEAK_PLANK_8780, 8)), - NOTHING(13721, 8027, 81, 1000.0, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5)), - NOTHING2(13721, 8026, 71, 720.0, new Item(Items.TEAK_PLANK_8780, 8)), - INVISIBLE_WALL(15283, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - INVISIBLE_WALL2(15284, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - INVISIBLE_WALL3(15285, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - GLOVE_RACK(13381, 8028, 34, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - WEAPONS_RACK(13382, 8029, 44, 180.0, new Item(Items.TEAK_PLANK_8780, 2)), - EXTRA_WEAPONS_RACK(13383, 8030, 54, 440.0, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.STEEL_BAR_2353, 4)), - BOXING_MAT_CORNER(13126, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - FENCING_MAT_CORNER(13135, 8024, 41, 570.0, new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - COMBAT_MAT_CORNER(13138, 8025, 51, 630.0, new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - BOXING_MAT_SIDE(13128, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - FENCING_MAT_SIDE(13134, 8024, 41, 570.0, new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - COMBAT_MAT_SIDE(13139, 8025, 51, 630.0, new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - BOXING_MAT(13127, 8023, 32, 570.0, new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4)), - FENCING_MAT(13136, 8024, 41, 570.0, new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - COMBAT_MAT(13140, 8025, 51, 630.0, new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6)), - - + BOXING_RING (13129, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_RING (13133, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_RING (13137, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + BALANCE_BEAM_LEFT (13143, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + BALANCE_BEAM_CENTER(13142, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + BALANCE_BEAM_RIGHT (13144, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + RANGING_PEDESTALS (13147, 8026, 71, 720, new Item[] { new Item(Items.TEAK_PLANK_8780, 8) }), + MAGIC_BARRIER (13145, 8026, 71, 720, new Item[] { new Item(Items.TEAK_PLANK_8780, 8) }), + NOTHING (13721, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + NOTHING2 (13721, 8026, 71, 720, new Item[] { new Item(Items.TEAK_PLANK_8780, 8) }), + INVISIBLE_WALL (15283, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + INVISIBLE_WALL2 (15284, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + INVISIBLE_WALL3 (15285, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + GLOVE_RACK (13381, 8028, 34, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + WEAPONS_RACK (13382, 8029, 44, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + EXTRA_WEAPONS_RACK (13383, 8030, 54, 440, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.STEEL_BAR_2353, 4) }), + BOXING_MAT_CORNER (13126, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_MAT_CORNER (13135, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_MAT_CORNER (13138, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + BOXING_MAT_SIDE (13128, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_MAT_SIDE (13134, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_MAT_SIDE (13139, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + BOXING_MAT (13127, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_MAT (13136, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_MAT (13140, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + /** * Formal garden decorations */ - GAZEBO(13477, 8192, 65, 1200, new Item(Items.MAHOGANY_PLANK_8782, 8), new Item(Items.STEEL_BAR_2353, 4)), - SMALL_FOUNTAIN(13478, 8193, 71, 500, new Item(Items.MARBLE_BLOCK_8786, 1)), - LARGE_FOUNTAIN(13479, 8194, 75, 1000, new Item(Items.MARBLE_BLOCK_8786, 2)), - POSH_FOUNTAIN(13480, 8195, 81, 1500, new Item(Items.MARBLE_BLOCK_8786, 3)), - SUNFLOWER(13446, 8213, 66, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_SUNFLOWER_8457, 1)), - MARIGOLDS(13447, 8214, 71, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_MARIGOLDS_8459, 1)), - ROSES(13448, 8215, 76, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_ROSES_8461, 1)), - SUNFLOWER_BIG(13443, 8213, 66, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_SUNFLOWER_8457, 1)), - MARIGOLDS_BIG(13444, 8214, 71, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_MARIGOLDS_8459, 1)), - ROSES_BIG(13445, 8215, 76, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_ROSES_8461, 1)), - ROSEMARY(13440, 8210, 66, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_ROSEMARY_8451, 1)), - DAFFODILS(13441, 8211, 71, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_DAFFODILS_8453, 1)), - BLUEBELLS(13442, 8212, 76, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_BLUEBELLS_8455, 1)), - ROSEMARY_BIG(13437, 8210, 66, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_ROSEMARY_8451, 1)), - DAFFODILS_BIG(13438, 8211, 71, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_DAFFODILS_8453, 1)), - BLUEBELLS_BIG(13439, 8212, 76, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.BAGGED_BLUEBELLS_8455, 1)), - THORNY_HEDGE1(13456, 8203, 56, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.THORNY_HEDGE_8437, 1)), - THORNY_HEDGE2(13457, 8203, 56, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.THORNY_HEDGE_8437, 1)), - THORNY_HEDGE3(13458, 8203, 56, 70, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.THORNY_HEDGE_8437, 1)), - NICE_HEDGE1(13459, 8204, 60, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.NICE_HEDGE_8439, 1)), - NICE_HEDGE2(13461, 8204, 60, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.NICE_HEDGE_8439, 1)), - NICE_HEDGE3(13460, 8204, 60, 100, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.NICE_HEDGE_8439, 1)), - SMALL_BOX_HEDGE1(13462, 8205, 64, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.SMALL_BOX_HEDGE_8441, 1)), - SMALL_BOX_HEDGE2(13464, 8205, 64, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.SMALL_BOX_HEDGE_8441, 1)), - SMALL_BOX_HEDGE3(13463, 8205, 64, 122, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.SMALL_BOX_HEDGE_8441, 1)), - TOPIARY_HEDGE1(13465, 8206, 68, 141, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TOPIARY_HEDGE_8443, 1)), - TOPIARY_HEDGE2(13467, 8206, 68, 141, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TOPIARY_HEDGE_8443, 1)), - TOPIARY_HEDGE3(13466, 8206, 68, 141, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TOPIARY_HEDGE_8443, 1)), - FANCY_HEDGE1(13468, 8207, 72, 158, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.FANCY_HEDGE_8445, 1)), - FANCY_HEDGE2(13470, 8207, 72, 158, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.FANCY_HEDGE_8445, 1)), - FANCY_HEDGE3(13469, 8207, 72, 158, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.FANCY_HEDGE_8445, 1)), - TALL_FANCY_HEDGE1(13471, 8208, 76, 223, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TALL_FANCY_HEDGE_8447, 1)), - TALL_FANCY_HEDGE2(13473, 8208, 76, 223, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TALL_FANCY_HEDGE_8447, 1)), - TALL_FANCY_HEDGE3(13472, 8208, 76, 223, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TALL_FANCY_HEDGE_8447, 1)), - TALL_BOX_HEDGE1(13474, 8209, 80, 316, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TALL_BOX_HEDGE_8449, 1)), - TALL_BOX_HEDGE2(13476, 8209, 80, 316, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TALL_BOX_HEDGE_8449, 1)), - TALL_BOX_HEDGE3(13475, 8209, 80, 316, new int[] {BuildingUtils.WATERING_CAN}, new Item(Items.TALL_BOX_HEDGE_8449, 1)), - BOUNDARY_STONES(13449, 8196, 55, 100, new Item(Items.SOFT_CLAY_1761, 10)), - WOODEN_FENCE(13450, 8197, 59, 280, new Item(Items.PLANK_960, 10)), - STONE_WALL(13451, 8198, 63, 200, new Item(Items.LIMESTONE_BRICK_3420, 10)), - IRON_RAILINGS(13452, 8199, 67, 220, new Item(Items.IRON_BAR_2351, 10), new Item(Items.LIMESTONE_BRICK_3420, 6)), - PICKET_FENCE(13453, 8200, 71, 640, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2)), - GARDEN_FENCE(13454, 8201, 75, 940, new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 2)), - MARBLE_WALL(13455, 8202, 79, 4000, new Item(Items.MARBLE_BLOCK_8786, 10)), - - + GAZEBO (13477, 8192, 65, 1200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 8), new Item(Items.STEEL_BAR_2353, 4) }), + SMALL_FOUNTAIN (13478, 8193, 71, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + LARGE_FOUNTAIN (13479, 8194, 75, 1000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2) }), + POSH_FOUNTAIN (13480, 8195, 81, 1500, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 3) }), + SUNFLOWER (13446, 8213, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_SUNFLOWER_8457) }), + MARIGOLDS (13447, 8214, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MARIGOLDS_8459) }), + ROSES (13448, 8215, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSES_8461) }), + SUNFLOWER_BIG (13443, 8213, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_SUNFLOWER_8457) }), + MARIGOLDS_BIG (13444, 8214, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MARIGOLDS_8459) }), + ROSES_BIG (13445, 8215, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSES_8461) }), + ROSEMARY (13440, 8210, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSEMARY_8451) }), + DAFFODILS (13441, 8211, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DAFFODILS_8453) }), + BLUEBELLS (13442, 8212, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_BLUEBELLS_8455) }), + ROSEMARY_BIG (13437, 8210, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSEMARY_8451) }), + DAFFODILS_BIG (13438, 8211, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DAFFODILS_8453) }), + BLUEBELLS_BIG (13439, 8212, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_BLUEBELLS_8455) }), + THORNY_HEDGE1 (13456, 8203, 56, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.THORNY_HEDGE_8437) }), + THORNY_HEDGE2 (13457, 8203, 56, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.THORNY_HEDGE_8437) }), + THORNY_HEDGE3 (13458, 8203, 56, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.THORNY_HEDGE_8437) }), + NICE_HEDGE1 (13459, 8204, 60, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.NICE_HEDGE_8439) }), + NICE_HEDGE2 (13461, 8204, 60, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.NICE_HEDGE_8439) }), + NICE_HEDGE3 (13460, 8204, 60, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.NICE_HEDGE_8439) }), + SMALL_BOX_HEDGE1 (13462, 8205, 64, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.SMALL_BOX_HEDGE_8441) }), + SMALL_BOX_HEDGE2 (13464, 8205, 64, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.SMALL_BOX_HEDGE_8441) }), + SMALL_BOX_HEDGE3 (13463, 8205, 64, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.SMALL_BOX_HEDGE_8441) }), + TOPIARY_HEDGE1 (13465, 8206, 68, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TOPIARY_HEDGE_8443) }), + TOPIARY_HEDGE2 (13467, 8206, 68, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TOPIARY_HEDGE_8443) }), + TOPIARY_HEDGE3 (13466, 8206, 68, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TOPIARY_HEDGE_8443) }), + FANCY_HEDGE1 (13468, 8207, 72, 158, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.FANCY_HEDGE_8445) }), + FANCY_HEDGE2 (13470, 8207, 72, 158, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.FANCY_HEDGE_8445) }), + FANCY_HEDGE3 (13469, 8207, 72, 158, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.FANCY_HEDGE_8445) }), + TALL_FANCY_HEDGE1(13471, 8208, 76, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_FANCY_HEDGE_8447) }), + TALL_FANCY_HEDGE2(13473, 8208, 76, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_FANCY_HEDGE_8447) }), + TALL_FANCY_HEDGE3(13472, 8208, 76, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_FANCY_HEDGE_8447) }), + TALL_BOX_HEDGE1 (13474, 8209, 80, 316, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_BOX_HEDGE_8449) }), + TALL_BOX_HEDGE2 (13476, 8209, 80, 316, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_BOX_HEDGE_8449) }), + TALL_BOX_HEDGE3 (13475, 8209, 80, 316, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_BOX_HEDGE_8449) }), + BOUNDARY_STONES (13449, 8196, 55, 100, new Item[] { new Item(Items.SOFT_CLAY_1761, 10) }), + WOODEN_FENCE (13450, 8197, 59, 280, new Item[] { new Item(Items.PLANK_960, 10) }), + STONE_WALL (13451, 8198, 63, 200, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 10) }), + IRON_RAILINGS (13452, 8199, 67, 220, new Item[] { new Item(Items.IRON_BAR_2351, 10), new Item(Items.LIMESTONE_BRICK_3420, 6) }), + PICKET_FENCE (13453, 8200, 71, 640, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2) }), + GARDEN_FENCE (13454, 8201, 75, 940, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 2) }), + MARBLE_WALL (13455, 8202, 79, 4000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 10) }), + /** * Bedroom decorations. */ - WOODEN_BED(13148, 8031, 20, 117, new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - OAK_BED(13149, 8032, 30, 210, new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - LARGE_OAK_BED(13150, 8033, 34, 330, new Item(Items.OAK_PLANK_8778, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - TEAK_BED(13151, 8034, 40, 300, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - LARGE_TEAK_BED(13152, 8035, 45, 480, new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - FOUR_POSTER(13153, 8036, 53, 450, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - GILDED_FOUR_POSTER(13154, 8037, 60, 1330, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 2)), - OAK_CLOCK(13169, 8052, 25, 142, new Item(Items.OAK_PLANK_8778, 2), new Item(Items.CLOCKWORK_8792, 1)), - TEAK_CLOCK(13170, 8053, 55, 202, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CLOCKWORK_8792, 1)), - GILDED_CLOCK(13171, 8054, 85, 602, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.CLOCKWORK_8792, 1), new Item(Items.GOLD_LEAF_8784, 1)), - SHAVING_STAND(13162, 8045, 21, 30, new Item(Items.PLANK_960, 1), new Item(Items.MOLTEN_GLASS_1775, 1)), - OAK_SHAVING_STAND(13163, 8046, 29, 61, new Item(Items.OAK_PLANK_8778, 1), new Item(Items.MOLTEN_GLASS_1775, 1)), - OAK_DRESSER(13164, 8047, 37, 121, new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775, 1)), - TEAK_DRESSER(13165, 8048, 46, 181, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 1)), - FANCY_TEAK_DRESSER(13166, 8049, 56, 182, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2)), - MAHOGANY_DRESSER(13167, 8050, 64, 281, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 1)), - GILDED_DRESSER(13168, 8051, 74, 582, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.GOLD_LEAF_8784, 1)), - SHOE_BOX(13155, 8038, 20, 58, new Item(Items.PLANK_960, 2)), - OAK_DRAWERS(13156, 8039, 27, 120, new Item(Items.OAK_PLANK_8778, 2)), - OAK_WARDROBE(13157, 8040, 39, 180, new Item(Items.OAK_PLANK_8778, 3)), - TEAK_DRAWERS(13158, 8041, 51, 180, new Item(Items.TEAK_PLANK_8780, 2)), - TEAK_WARDROBE(13159, 8042, 63, 270, new Item(Items.TEAK_PLANK_8780, 3)), - MAHOGANY_WARDROBE(13160, 8043, 75, 420, new Item(Items.MAHOGANY_PLANK_8782, 2)), - GILDED_WARDROBE(13161, 8044, 87, 720, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784, 1)), - - + WOODEN_BED (13148, 8031, 20, 117, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + OAK_BED (13149, 8032, 30, 210, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + LARGE_OAK_BED (13150, 8033, 34, 330, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + TEAK_BED (13151, 8034, 40, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + LARGE_TEAK_BED (13152, 8035, 45, 480, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + FOUR_POSTER (13153, 8036, 53, 450, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + GILDED_FOUR_POSTER(13154, 8037, 60, 1330, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 2) }), + OAK_CLOCK (13169, 8052, 25, 142, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.CLOCKWORK_8792) }), + TEAK_CLOCK (13170, 8053, 55, 202, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CLOCKWORK_8792) }), + GILDED_CLOCK (13171, 8054, 85, 602, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.CLOCKWORK_8792), new Item(Items.GOLD_LEAF_8784) }), + SHAVING_STAND (13162, 8045, 21, 30, new Item[] { new Item(Items.PLANK_960), new Item(Items.MOLTEN_GLASS_1775) }), + OAK_SHAVING_STAND (13163, 8046, 29, 61, new Item[] { new Item(Items.OAK_PLANK_8778), new Item(Items.MOLTEN_GLASS_1775) }), + OAK_DRESSER (13164, 8047, 37, 121, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775) }), + TEAK_DRESSER (13165, 8048, 46, 181, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775) }), + FANCY_TEAK_DRESSER(13166, 8049, 56, 182, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2) }), + MAHOGANY_DRESSER (13167, 8050, 64, 281, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775) }), + GILDED_DRESSER (13168, 8051, 74, 582, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.GOLD_LEAF_8784) }), + SHOE_BOX (13155, 8038, 20, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + OAK_DRAWERS (13156, 8039, 27, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + OAK_WARDROBE (13157, 8040, 39, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + TEAK_DRAWERS (13158, 8041, 51, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + TEAK_WARDROBE (13159, 8042, 63, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + MAHOGANY_WARDROBE (13160, 8043, 75, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + GILDED_WARDROBE (13161, 8044, 87, 720, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }), + /** * Quest hall decorations. */ - ANTIDRAGON_SHIELD(13522, 8282, 47, 280, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ANTI_DRAGON_SHIELD_1540, 1)), - AMULET_OF_GLORY(13523, 8283, 47, 290, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704, 1)), - CAPE_OF_LEGENDS(13524, 8284, 47, 300, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.CAPE_OF_LEGENDS_1052, 1)), - KING_ARTHUR(13510, 8285, 35, 211, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ARTHUR_PORTRAIT_7995, 1)), - ELENA(13511, 8286, 35, 211, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ELENA_PORTRAIT_7996, 1)), - GIANT_DWARF(13512, 8287, 35, 211, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.KELDAGRIM_PORTRAIT_7997, 1)), - MISCELLANIANS(13513, 8288, 35, 311, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.MISC_PORTRAIT_7998, 1)), - LUMBRIDGE(13517, 8289, 44, 314, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.LUMBRIDGE_PAINTING_8002, 1)), - THE_DESERT(13514, 8290, 44, 314, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.DESERT_PAINTING_7999, 1)), - MORYTANIA(13518, 8291, 44, 314, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.MORYTANIA_PAINTING_8003, 1)), - KARAMJA(13516, 8292, 65, 464, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.KARAMJA_PAINTING_8001, 1)), - ISAFDAR(13515, 8293, 65, 464, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.ISAFDAR_PAINTING_8000, 1)), - SILVERLIGHT(13519, 8279, 42, 187, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SILVERLIGHT_2402, 1)), - EXCALIBUR(13521, 8280, 42, 194, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.EXCALIBUR_35, 1)), - DARKLIGHT(13520, 8281, 42, 202, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.DARKLIGHT_6746, 1)), - SMALL_MAP(13525, 8294, 38, 211, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SMALL_MAP_8004, 1)), - MEDIUM_MAP(13526, 8295, 58, 451, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.MEDIUM_MAP_8005, 1)), - LARGE_MAP(13527, 8296, 78, 591, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.LARGE_MAP_8006, 1)), - - /** - * Menagerie Decorations - */ - //OBELISK - MINI_OBELISK(44837, 15236, 41, 676, new Item(Items.MARBLE_BLOCK_8786, 1), new Item(Items.SPIRIT_SHARDS_12183, 1000), new Item(Items.GOLD_CHARM_12158, 10), new Item(Items.GREEN_CHARM_12159, 10), new Item(Items.CRIMSON_CHARM_12160, 10), new Item(Items.BLUE_CHARM_12163, 10)) - //PET_FEEDER - , - OAK_PET_FEEDER(44834, 15233, 37, 240, new Item(Items.OAK_PLANK_8778, 4)), - TEAK_PET_FEEDER(44835, 15234, 52, 380, new Item(Items.TEAK_PLANK_8780, 4)), - MAHOGANY_PET_FEEDER(44836, 15235, 67, 880, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 1)) - //PET_HOUSE - , - OAK_PET_HOUSE(44828, 15227, 37, 240, new Item(Items.OAK_PLANK_8778, 4)), - TEAK_PET_HOUSE(44829, 15228, 52, 380, new Item(Items.TEAK_PLANK_8780, 4)), - MAHOGANY_PET_HOUSE(44830, 15229, 67, 580, new Item(Items.MAHOGANY_PLANK_8782, 4)), - CONSECRATED_PET_HOUSE(44831, 15230, 92, 1580, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.MAGIC_STONE_8788, 1)), - DESECRATED_PET_HOUSE(44832, 15231, 92, 1580, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.MAGIC_STONE_8788, 1)), - NATURAL_PET_HOUSE(44833, 15232, 92, 1580, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.MAGIC_STONE_8788, 1)) - //HABITAT_SPACE - , - GARDEN_HABITAT(new int[]{ - 4497, - 4498, - 44500, - 44501, - 44502, - 44503, - 44504, - 44505, - 44506, - 44507, - 44508, - 44509, - 44510, - 44511, - 44512, - 44513, - 44514, - 44515, - 44516, - 44517, - 44518, - 44519, - 44520, - 44521, - 44522, - 44523, - 44524, - 44525, - 44526, - 44527, - 44528, - 44529, - 44530, - 44531, - 44532, - 44533, - 44534, - 44535, - 44536, - 44537, - 44538, - 44539, - 44540, - 44541, - 44542, - 44543, - 44544, - 44545, - 44546, - 44547, - 44548, - 44549, - 44550, - 44551, - 44552, - 44553, - 44554, - 44555, - 44556, - 44557, - 44558, - 44559, - 44560, - 44561, - 44562, - 44563 }, 15222, 37, 201, new Item(Items.BAGGED_PLANT_1_8431, 1), new Item(Items.BAGGED_PLANT_2_8433, 1), new Item(Items.BAGGED_PLANT_3_8435, 1)), - JUNGLE_HABITAT(new int[] - { - 44564, - 44565, - 44566, - 44567, - 44568, - 44569, - 44570, - 44571, - 44572, - 44573, - 44574, - 44575, - 44576, - 44577, - 44578, - 44579, - 44580, - 44581, - 44582, - 44583, - 44584, - 44585, - 44586, - 44587, - 44588, - 44589, - 44590, - 44591, - 44592, - 44593, - 44594, - 44595, - 44596, - 44597, - 44598, - 44599, - 44600, - 44601, - 44602, - 44603, - 44604, - 44605, - 44606, - 44607, - 44608, - 44609, - 44610, - 44611, - 44612, - 44613, - 44614, - 44615, - 44616, - 44617, - 44618, - 44619, - 44620, - 44621, - 44622, - 44623, - 44624, - 44625, - 44626, - 44627, - 44628, - 44629 }, 15223, 47, 278, new Item(Items.BAGGED_PLANT_3_8435, 3), new Item(Items.BAGGED_WILLOW_TREE_8423, 1), new Item(Items.BUCKET_OF_WATER_1929, 5)), - DESERT_HABITAT(new int[] - { - 44630, - 44631, - 44632, - 44633, - 44634, - 44635, - 44636, - 44637, - 44638, - 44639, - 44640, - 44641, - 44642, - 44643, - 44644, - 44645, - 44646, - 44647, - 44648, - 44649, - 44650, - 44651, - 44652, - 44653, - 44654, - 44655, - 44656, - 44657, - 44658, - 44659, - 44660, - 44661, - 44662, - 44663, - 44664, - 44665, - 44666, - 44667, - 44668, - 44669, - 44670, - 44671, - 44672, - 44673, - 44674, - 44675, - 44676, - 44677, - 44678, - 44679, - 44680, - 44681, - 44682, - 44683, - 44684, - 44685, - 44686, - 44687, - 44688, - 44689, - 44690, - 44691, - 44692, - 44693, - 44694, - 44695 }, 15224, 57, 238, new Item(Items.BUCKET_OF_SAND_1783, 10), new Item(Items.LIMESTONE_BRICK_3420, 5), new Item(15237, 1)), - POLAR_HABITAT(new int[] - { - 44696, - 44697, - 44698, - 44699, - 44700, - 44701, - 44702, - 44703, - 44704, - 44705, - 44706, - 44707, - 44708, - 44709, - 44710, - 44711, - 44712, - 44713, - 44714, - 44715, - 44716, - 44717, - 44718, - 44719, - 44720, - 44721, - 44722, - 44723, - 44724, - 44725, - 44726, - 44727, - 44728, - 44729, - 44730, - 44731, - 44732, - 44733, - 44734, - 44735, - 44736, - 44737, - 44738, - 44739, - 44740, - 44741, - 44742, - 44743, - 44744, - 44745, - 44746, - 44747, - 44748, - 44749, - 44750, - 44751, - 44752, - 44753, - 44754, - 44755, - 44756, - 44757, - 44758, - 44759, - 44760, - 44761 }, 15225, 67, 373, new Item(Items.AIR_RUNE_556, 1000), new Item(Items.WATER_RUNE_555, 1000), new Item(15239, 1)), - VOLCANIC_HABITAT(new int[] - { - 44762, - 44763, - 44764, - 44765, - 44766, - 44767, - 44768, - 44769, - 44770, - 44771, - 44772, - 44773, - 44774, - 44775, - 44776, - 44777, - 44778, - 44779, - 44780, - 44781, - 44782, - 44783, - 44784, - 44785, - 44786, - 44787, - 44788, - 44789, - 44790, - 44791, - 44792, - 44793, - 44794, - 44795, - 44796, - 44797, - 44798, - 44799, - 44800, - 44801, - 44802, - 44803, - 44804, - 44805, - 44806, - 44807, - 44808, - 44809, - 44810, - 44811, - 44812, - 44813, - 44814, - 44815, - 44816, - 44817, - 44818, - 44819, - 44820, - 44821, - 44822, - 44823, - 44824, - 44825, - 44826, - 44827 }, 15226, 77, 77, new Item(Items.FIRE_RUNE_554, 1000), new Item(Items.EARTH_RUNE_557, 1000), new Item(Items.BAGGED_DEAD_TREE_8417, 1), new Item(Items.STONE_SLAB_13245, 5)), - + ANTIDRAGON_SHIELD(13522, 8282, 47, 280, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ANTI_DRAGON_SHIELD_1540) }, new Item[] { new Item(Items.ANTI_DRAGON_SHIELD_1540) }), + AMULET_OF_GLORY (13523, 8283, 47, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704) }, new Item[] { new Item(Items.AMULET_OF_GLORY_1704) }, new String[] { "Teak plank: 3", "Amulet of Glory", "(uncharged): 1" }), + CAPE_OF_LEGENDS (13524, 8284, 47, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.CAPE_OF_LEGENDS_1052) }, new Item[] { new Item(Items.CAPE_OF_LEGENDS_1052) }), + KING_ARTHUR (13510, 8285, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ARTHUR_PORTRAIT_7995) }), + ELENA (13511, 8286, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ELENA_PORTRAIT_7996) }), + GIANT_DWARF (13512, 8287, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.KELDAGRIM_PORTRAIT_7997) }), + MISCELLANIANS (13513, 8288, 35, 311, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.MISC_PORTRAIT_7998) }), + LUMBRIDGE (13517, 8289, 44, 314, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.LUMBRIDGE_PAINTING_8002) }), + THE_DESERT (13514, 8290, 44, 314, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.DESERT_PAINTING_7999) }), + MORYTANIA (13518, 8291, 44, 314, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.MORYTANIA_PAINTING_8003) }), + KARAMJA (13516, 8292, 65, 464, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.KARAMJA_PAINTING_8001) }), + ISAFDAR (13515, 8293, 65, 464, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.ISAFDAR_PAINTING_8000) }), + SILVERLIGHT (13519, 8279, 42, 187, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SILVERLIGHT_2402) }, new Item[] { new Item(Items.SILVERLIGHT_2402) }), + EXCALIBUR (13521, 8280, 42, 194, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.EXCALIBUR_35) }, new Item[] { new Item(Items.EXCALIBUR_35) }), + DARKLIGHT (13520, 8281, 42, 202, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.DARKLIGHT_6746) }, new Item[] { new Item(Items.DARKLIGHT_6746) }), + SMALL_MAP (13525, 8294, 38, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SMALL_MAP_8004) }), + MEDIUM_MAP (13526, 8295, 58, 451, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.MEDIUM_MAP_8005) }), + LARGE_MAP (13527, 8296, 78, 591, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.LARGE_MAP_8006) }), /** * Study decorations. */ - GLOBE(13649, 8341, 41, 180, new Item(Items.OAK_PLANK_8778, 3)), - ORNAMENTAL_GLOBE(13650, 8342, 50, 270, new Item(Items.TEAK_PLANK_8780, 3)), - LUNAR_GLOBE(13651, 8343, 59, 570, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.GOLD_LEAF_8784, 1)), - CELESTIAL_GLOBE(13652, 8344, 68, 570, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.GOLD_LEAF_8784, 1)), - ARMILLARY_SPHERE(13653, 8345, 77, 960, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784, 2), new Item(Items.STEEL_BAR_2353, 4)), - SMALL_ORREY(13654, 8346, 86, 1320, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 3)), - LARGE_ORREY(13655, 8347, 95, 1420, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 5)), - OAK_LECTERN(13642, 8334, 40, 60, new Item(Items.OAK_PLANK_8778, 1)), - EAGLE_LECTERN(13643, 8335, 47, 120, new Item(Items.OAK_PLANK_8778, 2)), - DEMON_LECTERN(13644, 8336, 47, 120, new Item(Items.OAK_PLANK_8778, 2)), - TEAK_EAGLE_LECTERN(13645, 8337, 57, 180, new Item(Items.TEAK_PLANK_8780, 2)), - TEAK_DEMON_LECTERN(13646, 8338, 57, 180, new Item(Items.TEAK_PLANK_8780, 2)), - MAHOGANY_EAGLE_LECTERN(13647, 8339, 67, 580, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784, 1)), - MAHOGANY_DEMON_LECTERN(13648, 8340, 67, 580, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784, 1)), - CRYSTAL_BALL(13659, 8351, 42, 280, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.UNPOWERED_ORB_567, 1)), - ELEMENTAL_SPHERE(13660, 8352, 54, 580, new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.UNPOWERED_ORB_567, 1), new Item(Items.GOLD_LEAF_8784, 1)), - CRYSTAL_OF_POWER(13661, 8353, 66, 890, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.UNPOWERED_ORB_567, 1), new Item(Items.GOLD_LEAF_8784, 2)), - ALCHEMICAL_CHART(13662, 8354, 43, 30, new Item(Items.BOLT_OF_CLOTH_8790, 2)), - ASTRONOMICAL_CHART(13663, 8355, 63, 45, new Item(Items.BOLT_OF_CLOTH_8790, 3)), - INFERNAL_CHART(13664, 8356, 83, 60, new Item(Items.BOLT_OF_CLOTH_8790, 4)), - TELESCOPE1(13656, 8348, 44, 121, new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775, 1)), - TELESCOPE2(13657, 8349, 64, 181, new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 1)), - TELESCOPE3(13658, 8350, 84, 580, new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 1)), - + GLOBE (13649, 8341, 41, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + ORNAMENTAL_GLOBE (13650, 8342, 50, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + LUNAR_GLOBE (13651, 8343, 59, 570, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.GOLD_LEAF_8784) }), + CELESTIAL_GLOBE (13652, 8344, 68, 570, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.GOLD_LEAF_8784) }), + ARMILLARY_SPHERE (13653, 8345, 77, 960, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784, 2), new Item(Items.STEEL_BAR_2353, 4) }), + SMALL_ORREY (13654, 8346, 86, 1320, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 3) }), + LARGE_ORREY (13655, 8347, 95, 1420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 5) }), + OAK_LECTERN (13642, 8334, 40, 60, new Item[] { new Item(Items.OAK_PLANK_8778) }), + EAGLE_LECTERN (13643, 8335, 47, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + DEMON_LECTERN (13644, 8336, 47, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_EAGLE_LECTERN (13645, 8337, 57, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + TEAK_DEMON_LECTERN (13646, 8338, 57, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_EAGLE_LECTERN(13647, 8339, 67, 580, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }), + MAHOGANY_DEMON_LECTERN(13648, 8340, 67, 580, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }), + CRYSTAL_BALL (13659, 8351, 42, 280, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.UNPOWERED_ORB_567) }), + ELEMENTAL_SPHERE (13660, 8352, 54, 580, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.UNPOWERED_ORB_567), new Item(Items.GOLD_LEAF_8784) }), + CRYSTAL_OF_POWER (13661, 8353, 66, 890, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.UNPOWERED_ORB_567), new Item(Items.GOLD_LEAF_8784, 2) }), + ALCHEMICAL_CHART (13662, 8354, 43, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + ASTRONOMICAL_CHART (13663, 8355, 63, 45, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + INFERNAL_CHART (13664, 8356, 83, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + TELESCOPE1 (13656, 8348, 44, 121, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775) }), + TELESCOPE2 (13657, 8349, 64, 181, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775) }), + TELESCOPE3 (13658, 8350, 84, 580, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775) }), + /** * Costume room decorations. */ - OAK_TREASURE_CHEST(18804, 9839, 48, 120, new Item(Items.OAK_PLANK_8778, 2)), - TEAK_TREASURE_CHEST(18806, 9840, 66, 180, new Item(Items.TEAK_PLANK_8780, 2)), - MAHOGANY_TREASURE_CHEST(18808, 9841, 84, 280, new Item(Items.MAHOGANY_PLANK_8782, 2)), - OAK_ARMOUR_CASE(18778, 9826, 46, 180, new Item(Items.OAK_PLANK_8778, 3)), - TEAK_ARMOUR_CASE(18780, 9827, 64, 270, new Item(Items.TEAK_PLANK_8780, 3)), - MGANY_ARMOUR_CASE(18782, 9828, 82, 420, new Item(Items.MAHOGANY_PLANK_8782, 3)), - OAK_MAGIC_WARDROBE(18784, 9829, 42, 240, new Item(Items.OAK_PLANK_8778, 4)), - C_OAK_MAGIC_WARDROBE(18786, 9830, 51, 360, new Item(Items.OAK_PLANK_8778, 6)), - TEAK_MAGIC_WARDROBE(18788, 9831, 60, 360, new Item(Items.TEAK_PLANK_8780, 4)), - C_TEAK_MAGIC_WARDROBE(18790, 9832, 69, 540, new Item(Items.TEAK_PLANK_8780, 6)), - MGANY_MAGIC_WARDROBE(18792, 9833, 78, 560, new Item(Items.MAHOGANY_PLANK_8782, 4)), - GILDED_MAGIC_WARDROBE(18794, 9834, 87, 860, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 1)), - MARBLE_MAGIC_WARDROBE(18796, 9835, 96, 500, new Item(Items.MARBLE_BLOCK_8786, 1)), - OAK_CAPE_RACK(18766, 9817, 54, 240, new Item(Items.OAK_PLANK_8778, 4)), - TEAK_CAPE_RACK(18767, 9818, 63, 360, new Item(Items.TEAK_PLANK_8780, 4)), - MGANY_CAPE_RACK(18768, 9819, 72, 560, new Item(Items.MAHOGANY_PLANK_8782, 4)), - GILDED_CAPE_RACK(18769, 9820, 81, 860, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 1)), - MARBLE_CAPE_RACK(18770, 9821, 90, 500, new Item(Items.MARBLE_BLOCK_8786, 1)), - MAGIC_CAPE_RACK(18771, 9822, 99, 1000, new Item(Items.MAGIC_STONE_8788, 1)), - OAK_TOY_BOX(18798, 9836, 50, 120, new Item(Items.OAK_PLANK_8778, 2)), - TEAK_TOY_BOX(18800, 9837, 68, 180, new Item(Items.TEAK_PLANK_8780, 2)), - MAHOGANY_TOY_BOX(18802, 9838, 86, 280, new Item(Items.MAHOGANY_PLANK_8782, 2)), - OAK_COSTUME_BOX(18772, 9823, 44, 120, new Item(Items.OAK_PLANK_8778, 2)), - TEAK_COSTUME_BOX(18774, 9824, 62, 180, new Item(Items.TEAK_PLANK_8780, 2)), - MAHOGANY_COSTUME_BOX(18776, 9825, 80, 280, new Item(Items.MAHOGANY_PLANK_8782, 2)), - + OAK_TREASURE_CHEST (18804, 9839, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_TREASURE_CHEST (18806, 9840, 66, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_TREASURE_CHEST(18808, 9841, 84, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + OAK_ARMOUR_CASE (18778, 9826, 46, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + TEAK_ARMOUR_CASE (18780, 9827, 64, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + MGANY_ARMOUR_CASE (18782, 9828, 82, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + OAK_MAGIC_WARDROBE (18784, 9829, 42, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + C_OAK_MAGIC_WARDROBE (18786, 9830, 51, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }), + TEAK_MAGIC_WARDROBE (18788, 9831, 60, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + C_TEAK_MAGIC_WARDROBE (18790, 9832, 69, 540, new Item[] { new Item(Items.TEAK_PLANK_8780, 6) }), + MGANY_MAGIC_WARDROBE (18792, 9833, 78, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }), + GILDED_MAGIC_WARDROBE (18794, 9834, 87, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }), + MARBLE_MAGIC_WARDROBE (18796, 9835, 96, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + OAK_CAPE_RACK (18766, 9817, 54, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + TEAK_CAPE_RACK (18767, 9818, 63, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + MGANY_CAPE_RACK (18768, 9819, 72, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }), + GILDED_CAPE_RACK (18769, 9820, 81, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }), + MARBLE_CAPE_RACK (18770, 9821, 90, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + MAGIC_CAPE_RACK (18771, 9822, 99, 1000, new Item[] { new Item(Items.MAGIC_STONE_8788) }), + OAK_TOY_BOX (18798, 9836, 50, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_TOY_BOX (18800, 9837, 68, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_TOY_BOX (18802, 9838, 86, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + OAK_COSTUME_BOX (18772, 9823, 44, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_COSTUME_BOX (18774, 9824, 62, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_COSTUME_BOX (18776, 9825, 80, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + /** * Chapel decorations. */ - OAK_ALTAR(13179, 8062, 45, 240, new Item(Items.OAK_PLANK_8778, 4)), - TEAK_ALTAR(13182, 8063, 50, 360, new Item(Items.TEAK_PLANK_8780, 4)), - CLOTH_ALTAR(13185, 8064, 56, 390, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - MAHOGANY_ALTAR(13188, 8065, 60, 590, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - LIMESTONE_ALTAR(13191, 8066, 64, 910, new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.LIMESTONE_BRICK_3420, 2)), - MARBLE_ALTAR(13194, 8067, 70, 1030, new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.BOLT_OF_CLOTH_8790, 2)), - GILDED_ALTAR(13197, 8068, 75, 2230, new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 4)), - SMALL_STATUE(13271, 8082, 49, 40, new Item(Items.LIMESTONE_BRICK_3420, 2)), - MEDIUM_STATUE(13272, 8083, 69, 500, new Item(Items.MARBLE_BLOCK_8786, 1)), - LARGE_STATUE(13282, 8084, 89, 1500, new Item(Items.MARBLE_BLOCK_8786, 3)), - WINDCHIMES(13214, 8079, 49, 323, new Item(Items.OAK_PLANK_8778, 4), new Item(Items.STEEL_BAR_2353, 4)), - BELLS(13215, 8080, 58, 480, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.STEEL_BAR_2353, 6)), - ORGAN(13216, 8081, 69, 680, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.STEEL_BAR_2353, 6)), - SARADOMIN_SYMBOL(13172, 8055, 48, 120, new Item(Items.OAK_PLANK_8778, 2)), - ZAMORAK_SYMBOL(13173, 8056, 48, 120, new Item(Items.OAK_PLANK_8778, 2)), - GUTHIX_SYMBOL(13174, 8057, 48, 120, new Item(Items.OAK_PLANK_8778, 2)), - SARADOMIN_ICON(13175, 8058, 59, 960, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2)), - ZAMORAK_ICON(13176, 8059, 59, 960, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2)), - GUTHIX_ICON(13177, 8060, 59, 960, new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2)), - ICON_OF_BOB(13178, 8061, 71, 1160, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 2)), - STEEL_TORCHES(13202, 8070, 45, 80, new Item(Items.STEEL_BAR_2353, 2)), - WOODEN_TORCHES(13200, 8069, 49, 58, new Item(Items.PLANK_960, 2)), - STEEL_CANDLESTICKS(13204, 8071, 53, 124, new Item(Items.STEEL_BAR_2353, 6), new Item(Items.CANDLE_36, 6)), - GOLD_CANDLESTICKS(13206, 8072, 57, 46, new Item(Items.GOLD_BAR_2357, 6), new Item(Items.CANDLE_36, 6)), - INCENSE_BURNERS(13208, 8073, 61, 280, new Item(Items.OAK_PLANK_8778, 4), new Item(Items.STEEL_BAR_2353, 2)), - MAHOGANY_BURNERS(13210, 8074, 65, 600, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.STEEL_BAR_2353, 2)), - MARBLE_BURNERS(13212, 8075, 69, 1600, new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.STEEL_BAR_2353, 2)), - SHUTTERED_WINDOW(new int[] { 13253, 13226, 13235, 13244, 13217, 13262 }, 8076, 49, 228, new Item(Items.PLANK_960, 8)), - DECORATIVE_WINDOW(new int[] { 13254, 13227, 13236, 13245, 13218, 13263 }, 8077, 69, 200, new Item(Items.MOLTEN_GLASS_1775, 8)), - STAINED_GLASS(new int[] { 13255, 13228, 13237, 13246, 13219, 13264 }, 8078, 89, 400, new Item(Items.MOLTEN_GLASS_1775, 16)), + OAK_ALTAR (13179, 8062, 45, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + TEAK_ALTAR (13182, 8063, 50, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + CLOTH_ALTAR (13185, 8064, 56, 390, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + MAHOGANY_ALTAR (13188, 8065, 60, 590, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + LIMESTONE_ALTAR (13191, 8066, 64, 910, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.LIMESTONE_BRICK_3420, 2) }), + MARBLE_ALTAR (13194, 8067, 70, 1030, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + GILDED_ALTAR (13197, 8068, 75, 2230, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 4) }), + SMALL_STATUE (13271, 8082, 49, 40, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 2) }), + MEDIUM_STATUE (13272, 8083, 69, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + LARGE_STATUE (13282, 8084, 89, 1500, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 3) }), + WINDCHIMES (13214, 8079, 49, 323, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.STEEL_BAR_2353, 4) }), + BELLS (13215, 8080, 58, 480, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.STEEL_BAR_2353, 6) }), + ORGAN (13216, 8081, 69, 680, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.STEEL_BAR_2353, 6) }), + SARADOMIN_SYMBOL (13172, 8055, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + ZAMORAK_SYMBOL (13173, 8056, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + GUTHIX_SYMBOL (13174, 8057, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + SARADOMIN_ICON (13175, 8058, 59, 960, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + ZAMORAK_ICON (13176, 8059, 59, 960, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + GUTHIX_ICON (13177, 8060, 59, 960, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + ICON_OF_BOB (13178, 8061, 71, 1160, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + STEEL_TORCHES (13202, 8070, 45, 80, new Item[] { new Item(Items.STEEL_BAR_2353, 2) }), + WOODEN_TORCHES (13200, 8069, 49, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + STEEL_CANDLESTICKS(13204, 8071, 53, 124, new Item[] { new Item(Items.STEEL_BAR_2353, 6), new Item(Items.CANDLE_36, 6) }), + GOLD_CANDLESTICKS (13206, 8072, 57, 46, new Item[] { new Item(Items.GOLD_BAR_2357, 6), new Item(Items.CANDLE_36, 6) }), + INCENSE_BURNERS (13208, 8073, 61, 280, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.STEEL_BAR_2353, 2) }), + MAHOGANY_BURNERS (13210, 8074, 65, 600, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.STEEL_BAR_2353, 2) }), + MARBLE_BURNERS (13212, 8075, 69, 1600, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.STEEL_BAR_2353, 2) }), + SHUTTERED_WINDOW (new int[] { 13253, 13226, 13235, 13244, 13217, 13262 }, 8076, 49, 228, new Item[] { new Item(Items.PLANK_960, 8) }), + DECORATIVE_WINDOW (new int[] { 13254, 13227, 13236, 13245, 13218, 13263 }, 8077, 69, 200, new Item[] { new Item(Items.MOLTEN_GLASS_1775, 8) }), + STAINED_GLASS (new int[] { 13255, 13228, 13237, 13246, 13219, 13264 }, 8078, 89, 400, new Item[] { new Item(Items.MOLTEN_GLASS_1775, 16) }), /** * Throne room */ - OAK_THRONE(13665, 8357, 60, 800, new Item(Items.OAK_PLANK_8778, 5), new Item(Items.MARBLE_BLOCK_8786, 1)), - TEAK_THRONE(13666, 8358, 67, 1450, new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.MARBLE_BLOCK_8786, 2)), - MAHOGANY_THRONE(13667, 8359, 74, 2200, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 3)), - GILDED_THRONE(13668, 8360, 81, 1700, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.GOLD_LEAF_8784, 3)), - SKELETON_THRONE(13669, 8361, 88, 7003, new Item(Items.MAGIC_STONE_8788, 5), new Item(Items.MARBLE_BLOCK_8786, 4), new Item(Items.BONES_526, 5), new Item(Items.SKULL_964, 2)), - CRYSTAL_THRONE(13670, 8362, 95, 15000, new Item(Items.MAGIC_STONE_8788, 15)), - DEMONIC_THRONE(13671, 8363, 99, 25000, new Item(Items.MAGIC_STONE_8788, 25)), - OAK_LEVER(13672, 8364, 68, 300, new Item(Items.OAK_PLANK_8778, 5)), - TEAK_LEVER(13673, 8365, 78, 450, new Item(Items.TEAK_PLANK_8780, 5)), - MAHOGANY_LEVER(13674, 8366, 88, 700, new Item(Items.MAHOGANY_PLANK_8782, 5)), - FLOOR_DECORATION(new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8370, 61, 700, new Item(Items.MAHOGANY_PLANK_8782, 5)), - STEEL_CAGE(new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8371, 68, 1100, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.STEEL_BAR_2353, 20)), - FLOOR_TRAP(new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8372, 74, 770, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.CLOCKWORK_8792, 10)), - MAGIC_CIRCLE(new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8373, 82, 2700, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MAGIC_STONE_8788, 2)), - MAGIC_CAGE(new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8374, 89, 4700, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MAGIC_STONE_8788, 4)), - OAK_TRAPDOOR(13675, 8367, 68, 300, new Item(Items.OAK_PLANK_8778, 5)), - TEAK_TRAPDOOR(13676, 8368, 78, 450, new Item(Items.TEAK_PLANK_8780, 5)), - MAHOGANY_TRAPDOOR(13677, 8369, 88, 700, new Item(Items.MAHOGANY_PLANK_8782, 5)), - CARVED_TEAK_BENCH(13694, 8112, 44, 360, new Item(Items.TEAK_PLANK_8780, 4)), - MAHOGANY_BENCH(13695, 8113, 52, 560, new Item(Items.MAHOGANY_PLANK_8782, 4)), - GILDED_BENCH(13696, 8114, 61, 1760, new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4)), - OAK_DECO(13798, 8102, 16, 120.0, new Item(Items.OAK_PLANK_8778, 2)), - TEAK_DECO(13814, 8103, 36, 180.0, new Item(Items.TEAK_PLANK_8780, 2)), - GILDED_DECO(13782, 8104, 56, 1020.0, new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 2)), - ROUND_SHIELD(13734, 8105, 66, 120, new Item(Items.OAK_PLANK_8778, 2)), - SQUARE_SHIELD(13766, 8106, 76, 360, new Item(Items.TEAK_PLANK_8780, 4)), - KITE_SHIELD(13750, 8107, 86, 420, new Item(Items.MAHOGANY_PLANK_8782, 3)), - + OAK_THRONE (13665, 8357, 60, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.MARBLE_BLOCK_8786) }), + TEAK_THRONE (13666, 8358, 67, 1450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.MARBLE_BLOCK_8786, 2) }), + MAHOGANY_THRONE (13667, 8359, 74, 2200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 3) }), + GILDED_THRONE (13668, 8360, 81, 1700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.GOLD_LEAF_8784, 3) }), + SKELETON_THRONE (13669, 8361, 88, 7003, new Item[] { new Item(Items.MAGIC_STONE_8788, 5), new Item(Items.MARBLE_BLOCK_8786, 4), new Item(Items.BONES_526, 5), new Item(Items.SKULL_964, 2) }), + CRYSTAL_THRONE (13670, 8362, 95, 15000, new Item[] { new Item(Items.MAGIC_STONE_8788, 15) }), + DEMONIC_THRONE (13671, 8363, 99, 25000, new Item[] { new Item(Items.MAGIC_STONE_8788, 25) }), + OAK_LEVER (13672, 8364, 68, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + TEAK_LEVER (13673, 8365, 78, 450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5) }), + MAHOGANY_LEVER (13674, 8366, 88, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + FLOOR_DECORATION (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8370, 61, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + STEEL_CAGE (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8371, 68, 1100, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.STEEL_BAR_2353, 20) }), + FLOOR_TRAP (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8372, 74, 770, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.CLOCKWORK_8792, 10) }), + MAGIC_CIRCLE (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8373, 82, 2700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MAGIC_STONE_8788, 2) }), + MAGIC_CAGE (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8374, 89, 4700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MAGIC_STONE_8788, 4) }), + OAK_TRAPDOOR (13675, 8367, 68, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + TEAK_TRAPDOOR (13676, 8368, 78, 450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5) }), + MAHOGANY_TRAPDOOR(13677, 8369, 88, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + CARVED_TEAK_BENCH(13694, 8112, 44, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + MAHOGANY_BENCH (13695, 8113, 52, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }), + GILDED_BENCH (13696, 8114, 61, 1760, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4) }), + OAK_DECO (13798, 8102, 16, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_DECO (13814, 8103, 36, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + GILDED_DECO (13782, 8104, 56, 1020, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 2) }), + ROUND_SHIELD (13734, 8105, 66, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + SQUARE_SHIELD (13766, 8106, 76, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + KITE_SHIELD (13750, 8107, 86, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + /** * Oubliette */ - SPIKES_MID(13334, 8302, 65, 623, new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000)), - SPIKES_SIDE(13335, 8302, 65, 623, new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000)), - SPIKES_CORNER(13336, 8302, 65, 623, new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000)), - SPIKES_FL(13338, 8302, 65, 623, new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000)), - TENTACLE_MID(13331, 8303, 71, 326, new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000)), - TENTACLE_SIDE(13332, 8303, 71, 326, new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000)), - TENTACLE_CORNER(13333, 8303, 71, 326, new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000)), - TENTACLE_FL(13338, 8303, 71, 326, new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000)), - FP_FLOOR_MID(13371, 8304, 77, 357, new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000)), - FP_FLOOR_SIDE(13371, 8304, 77, 357, new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000)), - FP_FLOOR_CORNER(13371, 8304, 77, 357, new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000)), - FLAME_PIT(13337, 8304, 77, 357, new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000)), - ROCNAR_FLOOR_MID(13371, 8305, 83, 387, new Item(Items.COINS_995, 150000)), - ROCNAR_FLOOR_SIDE(13371, 8305, 83, 387, new Item(Items.COINS_995, 150000)), - ROCNAR_FLOOR_CORNER(13371, 8305, 83, 387, new Item(Items.COINS_995, 150000)), - ROCNAR(13373, 8305, 83, 387, new Item(Items.COINS_995, 150000)), - ROCNAR_FL(13338, 8305, 83, 387, new Item(Items.COINS_995, 150000)), - OAK_CAGE(13313, 8297, 65, 640, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2)), - OAK_CAGE_DOOR(13314, 8297, 65, 640, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2)), - OAK_STEEL_CAGE(13316, 8298, 70, 800, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10)), - OAK_STEEL_CAGE_DOOR(13317, 8298, 70, 800, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10)), - STEEL_CAGE_OU(13319, 8299, 75, 400, new Item(Items.STEEL_BAR_2353, 20)), - STEEL_CAGE_DOOR(13320, 8299, 75, 400, new Item(Items.STEEL_BAR_2353, 20)), - SPIKED_CAGE(13322, 8300, 80, 500, new Item(Items.STEEL_BAR_2353, 25)), - SPIKED_CAGE_DOOR(13323, 8300, 80, 500, new Item(Items.STEEL_BAR_2353, 25)), - BONE_CAGE(13325, 8301, 85, 603, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.BONES_526, 10)), - BONE_CAGE_DOOR(13326, 8301, 85, 603, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.BONES_526, 10)), - SKELETON_GUARD(13366, 8131, 70, 223, new Item(Items.COINS_995, 50000)), - GUARD_DOG(13367, 8132, 74, 273, new Item(Items.COINS_995, 75000)), - HOBGOBLIN(13368, 8133, 78, 316, new Item(Items.COINS_995, 100000)), - BABY_RED_DRAGON(13372, 8134, 82, 387, new Item(Items.COINS_995, 150000)), - HUGE_SPIDER(13370, 8135, 86, 447, new Item(Items.COINS_995, 200000)), - TROLL(13369, 8136, 90, 1000, new Item(Items.COINS_995, 1000000)), - HELLHOUND(2715, 8137, 94, 2236, new Item(Items.COINS_995, 5000000)), - OAK_LADDER(13328, 8306, 68, 300, new Item(Items.OAK_PLANK_8778, 5)), - TEAK_LADDER(13329, 8307, 78, 450, new Item(Items.TEAK_PLANK_8780, 5)), - MAHOGANY_LADDER(13330, 8308, 88, 700, new Item(Items.MAHOGANY_PLANK_8782, 5)), - DECORATIVE_BLOOD(13312, 8125, 72, 4, new Item(Items.RED_DYE_1763, 4)), - DECORATIVE_PIPE(13311, 8126, 83, 120, new Item(Items.STEEL_BAR_2353, 6)), - HANGING_SKELETON(13310, 8127, 94, 3, new Item(Items.SKULL_964, 2), new Item(Items.BONES_526, 6)), - CANDLE(13342, 8128, 72, 243, new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_CANDLE_33, 4)), - TORCH(13341, 8129, 84, 244, new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_TORCH_594, 4)), - SKULL_TORCH(13343, 8130, 94, 246, new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_TORCH_594, 4), new Item(Items.SKULL_964, 4)), - + SPIKES_MID (13334, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + SPIKES_SIDE (13335, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + SPIKES_CORNER (13336, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + SPIKES_FL (13338, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + TENTACLE_MID (13331, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + TENTACLE_SIDE (13332, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + TENTACLE_CORNER (13333, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + TENTACLE_FL (13338, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + FP_FLOOR_MID (13371, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + FP_FLOOR_SIDE (13371, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + FP_FLOOR_CORNER (13371, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + FLAME_PIT (13337, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + ROCNAR_FLOOR_MID (13371, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR_FLOOR_SIDE (13371, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR_FLOOR_CORNER(13371, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR (13373, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR_FL (13338, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + OAK_CAGE (13313, 8297, 65, 640, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2) }), + OAK_CAGE_DOOR (13314, 8297, 65, 640, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2) }), + OAK_STEEL_CAGE (13316, 8298, 70, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + OAK_STEEL_CAGE_DOOR(13317, 8298, 70, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + STEEL_CAGE_OU (13319, 8299, 75, 400, new Item[] { new Item(Items.STEEL_BAR_2353, 20) }), + STEEL_CAGE_DOOR (13320, 8299, 75, 400, new Item[] { new Item(Items.STEEL_BAR_2353, 20) }), + SPIKED_CAGE (13322, 8300, 80, 500, new Item[] { new Item(Items.STEEL_BAR_2353, 25) }), + SPIKED_CAGE_DOOR (13323, 8300, 80, 500, new Item[] { new Item(Items.STEEL_BAR_2353, 25) }), + BONE_CAGE (13325, 8301, 85, 603, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.BONES_526, 10) }), + BONE_CAGE_DOOR (13326, 8301, 85, 603, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.BONES_526, 10) }), + SKELETON_GUARD (13366, 8131, 70, 223, new Item[] { new Item(Items.COINS_995, 50000) }), + GUARD_DOG (13367, 8132, 74, 273, new Item[] { new Item(Items.COINS_995, 75000) }), + HOBGOBLIN (13368, 8133, 78, 316, new Item[] { new Item(Items.COINS_995, 100000) }), + BABY_RED_DRAGON (13372, 8134, 82, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + HUGE_SPIDER (13370, 8135, 86, 447, new Item[] { new Item(Items.COINS_995, 200000) }), + TROLL (13369, 8136, 90, 1000, new Item[] { new Item(Items.COINS_995, 1000000) }), + HELLHOUND (2715, 8137, 94, 2236, new Item[] { new Item(Items.COINS_995, 5000000) }), + OAK_LADDER (13328, 8306, 68, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + TEAK_LADDER (13329, 8307, 78, 450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5) }), + MAHOGANY_LADDER (13330, 8308, 88, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + DECORATIVE_BLOOD (13312, 8125, 72, 4, new Item[] { new Item(Items.RED_DYE_1763, 4) }), + DECORATIVE_PIPE (13311, 8126, 83, 120, new Item[] { new Item(Items.STEEL_BAR_2353, 6) }), + HANGING_SKELETON (13310, 8127, 94, 3, new Item[] { new Item(Items.SKULL_964, 2), new Item(Items.BONES_526, 6) }), + CANDLE (13342, 8128, 72, 243, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_CANDLE_33, 4) }), + TORCH (13341, 8129, 84, 244, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_TORCH_594, 4) }), + SKULL_TORCH (13343, 8130, 94, 246, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_TORCH_594, 4), new Item(Items.SKULL_964, 4) }), + /** * Dungeon corridor, junction, stairs & pit */ - OAK_DOOR_LEFT(13344, 8122, 74, 600, new Item(Items.OAK_PLANK_8778, 10)), - OAK_DOOR_RIGHT(13345, 8122, 74, 600, new Item(Items.OAK_PLANK_8778, 10)), - STEEL_DOOR_LEFT(13346, 8123, 84, 800, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10)), - STEEL_DOOR_RIGHT(13347, 8123, 84, 800, new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10)), - MARBLE_DOOR_LEFT(13348, 8124, 94, 2000, new Item(Items.MARBLE_BLOCK_8786, 4)), - MARBLE_DOOR_RIGHT(13349, 8124, 94, 2000, new Item(Items.MARBLE_BLOCK_8786, 4)), - SPIKE_TRAP(13356, 8143, 72, 223, new Item(Items.COINS_995, 50000)), - MAN_TRAP(13357, 8144, 76, 273, new Item(Items.COINS_995, 75000)), - TANGLE_TRAP(13358, 8145, 80, 316, new Item(Items.COINS_995, 100000)), - MARBLE_TRAP(13359, 8146, 84, 387, new Item(Items.COINS_995, 150000)), - TELEPORT_TRAP(13360, 8147, 88, 447, new Item(Items.COINS_995, 200000)), - - /* objID, int, lvl, exp, materials */ - PIT_DOG(39260, 18791, 70, 200, new Item(Items.COINS_995, 40000)), - PIT_OGRE(39261, 18792, 73, 234, new Item(Items.COINS_995, 55000)), - PIT_ROCK_PROTECTOR(39262, 18793, 79, 300, new Item(Items.COINS_995, 90000)), - PIT_SCABARITE(39263, 18794, 84, 387, new Item(Items.COINS_995, 150000)), - PIT_BLACK_DEMON(39264, 18795, 89, 547, new Item(Items.COINS_995, 300000)), - PIT_IRON_DRAGON(39265, 18796, 97, 2738, new Item(Items.COINS_995, 7500000)), + OAK_DOOR_LEFT (13344, 8122, 74, 600, new Item[] { new Item(Items.OAK_PLANK_8778, 10) }), + OAK_DOOR_RIGHT (13345, 8122, 74, 600, new Item[] { new Item(Items.OAK_PLANK_8778, 10) }), + STEEL_DOOR_LEFT (13346, 8123, 84, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + STEEL_DOOR_RIGHT (13347, 8123, 84, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + MARBLE_DOOR_LEFT (13348, 8124, 94, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + MARBLE_DOOR_RIGHT (13349, 8124, 94, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + SPIKE_TRAP (13356, 8143, 72, 223, new Item[] { new Item(Items.COINS_995, 50000) }), + MAN_TRAP (13357, 8144, 76, 273, new Item[] { new Item(Items.COINS_995, 75000) }), + TANGLE_TRAP (13358, 8145, 80, 316, new Item[] { new Item(Items.COINS_995, 100000) }), + MARBLE_TRAP (13359, 8146, 84, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + TELEPORT_TRAP (13360, 8147, 88, 447, new Item[] { new Item(Items.COINS_995, 200000) }), + PIT_DOG (39260, 18791, 70, 200, new Item[] { new Item(Items.COINS_995, 40000) }), + PIT_OGRE (39261, 18792, 73, 234, new Item[] { new Item(Items.COINS_995, 55000) }), + PIT_ROCK_PROTECTOR(39262, 18793, 79, 300, new Item[] { new Item(Items.COINS_995, 90000) }), + PIT_SCABARITE (39263, 18794, 84, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + PIT_BLACK_DEMON (39264, 18795, 89, 547, new Item[] { new Item(Items.COINS_995, 300000) }), + PIT_IRON_DRAGON (39265, 18796, 97, 2738, new Item[] { new Item(Items.COINS_995, 7500000) }), /** * Treasure room */ - DEMON(13378, 8138, 75, 707, new Item(Items.COINS_995, 500000)), - KALPHITE_SOLDIER(13374, 8139, 80, 866, new Item(Items.COINS_995, 750000)), - TOK_XIL(13377, 8140, 85, 2236, new Item(Items.COINS_995, 5000000)), - DAGANNOTH(13376, 8141, 90, 2738, new Item(Items.COINS_995, 7500000)), - STEEL_DRAGON(13375, 8142, 95, 3162, new Item(Items.COINS_995, 1000000)), - WOODEN_CRATE(13283, 8148, 75, 143, new Item(Items.PLANK_960, 5)), - OAK_T_CHEST(13285, 8149, 79, 340, new Item(Items.OAK_PLANK_8778, 5), new Item(Items.STEEL_BAR_2353, 2)), - TEAK_T_CHEST(13287, 8150, 83, 530, new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.STEEL_BAR_2353, 4)), - MGANY_T_CHEST(13289, 8151, 87, 1000, new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.GOLD_LEAF_8784, 1)), - MAGIC_CHEST(13291, 8152, 91, 1000, new Item(Items.MAGIC_STONE_8788, 1)), - + DEMON (13378, 8138, 75, 707, new Item[] { new Item(Items.COINS_995, 500000) }), + KALPHITE_SOLDIER (13374, 8139, 80, 866, new Item[] { new Item(Items.COINS_995, 750000) }), + TOK_XIL (13377, 8140, 85, 2236, new Item[] { new Item(Items.COINS_995, 5000000) }), + DAGANNOTH (13376, 8141, 90, 2738, new Item[] { new Item(Items.COINS_995, 7500000) }), + STEEL_DRAGON (13375, 8142, 95, 3162, new Item[] { new Item(Items.COINS_995, 1000000) }), + WOODEN_CRATE (13283, 8148, 75, 143, new Item[] { new Item(Items.PLANK_960, 5) }), + OAK_T_CHEST (13285, 8149, 79, 340, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.STEEL_BAR_2353, 2) }), + TEAK_T_CHEST (13287, 8150, 83, 530, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.STEEL_BAR_2353, 4) }), + MGANY_T_CHEST (13289, 8151, 87, 1000, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.GOLD_LEAF_8784) }), + MAGIC_CHEST (13291, 8152, 91, 1000, new Item[] { new Item(Items.MAGIC_STONE_8788) }), + /** * Style related decoration. */ - BASIC_WOOD_WINDOW(13099, -1, 1, 0.0), - BASIC_STONE_WINDOW(13091, -1, 1, 0.0), - WHITEWASHED_STONE_WINDOW(13005, -1, 1, 0.0), - FREMENNIK_WINDOW(13112, -1, 1, 0.0), - TROPICAL_WOOD_WINDOW(10816, -1, 1, 0.0), - FANCY_STONE_WINDOW(13117, -1, 1, 0.0), - + BASIC_WOOD_WINDOW (13099, -1, 1, 0), + BASIC_STONE_WINDOW (13091, -1, 1, 0), + WHITEWASHED_STONE_WINDOW (13005, -1, 1, 0), + FREMENNIK_WINDOW (13112, -1, 1, 0), + TROPICAL_WOOD_WINDOW (10816, -1, 1, 0), + FANCY_STONE_WINDOW (13117, -1, 1, 0), ; + /** * The object id. */ private final int objectId; - + /** * The item id for the interface. */ @@ -1083,17 +700,22 @@ public enum Decoration { * The level requirement. */ private final int level; - + /** * The experience gained for building this decoration. */ - private final double experience; - + private final int experience; + /** * The item required. */ private final Item[] items; - + + /** + * The items that will be refunded. + */ + private final Item[] refundItems; + /** * The tools required. */ @@ -1103,33 +725,108 @@ public enum Decoration { * The object ids depending on styling. */ private final int[] objectIds; - + /** - * If this node should be invisible to user build options + * If this node should be invisible to user build options. */ private boolean invisibleNode; - + /** - * Constructs a new {@code Portal} {@code Object}. - * @param objectId The object id. - * @param interfaceItem The item id for the building interface. - * @param level The level required. - * @param experience The experience gained. - * @param items The items required. + * The requirements text to show for this node. */ - private Decoration(int objectId, int interfaceItem, int level, double experience, Item... items) { - this(objectId, interfaceItem, level, experience, new int[] { 2347, 8794 }, items); + private String[] reqsText = {"", "", "", ""}; + + private String[] generateDefaultReqsText(Item[] items, int nailAmount) { + String[] ret = {"", "", "", ""}; + for (int i = 0; i < 4; i++) { + if (i >= items.length) { + if (i == items.length && nailAmount > 0) { + ret[i] = "Nails: " + nailAmount; + } + } else { + ret[i] = items[i].getName() + ": " + items[i].getAmount(); + } + } + return ret; } - + /** - * Constructs a new {@code Portal} {@code Object}. + * Constructs a new object, default items, default tools, default refund items, default requirements text. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + */ + Decoration(int objectId, int interfaceItem, int level, int experience) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, new Item[] {}, new Item[] {}, new String[] {}); + } + + /** + * Constructs a new object, default tools, default refund items, default requirements text. * @param objectId The object id. * @param interfaceItem The item id for the building interface. * @param level The level required. * @param experience The experience gained. * @param items The items required. */ - private Decoration(int objectId, int interfaceItem, int level, double experience, int[] tools, Item... items) { + Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}, new String[] {}); + this.reqsText = generateDefaultReqsText(items, getNailAmount()); + } + + /** + * Constructs a new object, default refund items, default requirements text. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param tools The tools needed. + * @param items The items required. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items) { + this(objectId, interfaceItem, level, experience, tools, items, new Item[] {}, new String[] {}); + this.reqsText = generateDefaultReqsText(items, getNailAmount()); + } + + /** + * Constructs a new object, no tools. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems, new String[] {}); + this.reqsText = generateDefaultReqsText(items, getNailAmount()); + } + + /** + * Constructs a new object, default tools. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems, String[] reqsText) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems, reqsText); + } + + /** + * Constructs a new object. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param tools The tools needed. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + * @param reqsText The requirements text to be shown in the interface. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems, String[] reqsText) { this.objectId = objectId; this.objectIds = null; this.interfaceItem = interfaceItem; @@ -1137,39 +834,45 @@ public enum Decoration { this.experience = experience; this.tools = tools; this.items = items; + this.refundItems = refundItems; + if (reqsText.length > 0) { + System.arraycopy(reqsText, 0, this.reqsText, 0, reqsText.length); + } } - + /** * Decoration * @param objectId * @param invisibleNode */ - private Decoration(int objectId, boolean invisibleNode) { + Decoration(int objectId, boolean invisibleNode) { this(objectId, -1, -1, -1); this.invisibleNode = true; } - + /** - * Constructs a new {@code Portal} {@code Object}. + * Constructs a new object, no tools, no refund items. * @param objectIds The object id. * @param interfaceItem The item id for the building interface. * @param level The level required. * @param experience The experience gained. * @param items The items required. */ - private Decoration(int[] objectIds, int interfaceItem, int level, double experience, Item... items) { - this(objectIds, interfaceItem, level, experience, new int[] { 2347, 8794 }, items); + Decoration(int[] objectIds, int interfaceItem, int level, int experience, Item[] items) { + this(objectIds, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}); } - + /** - * Constructs a new {@code Portal} {@code Object}. + * Constructs a new object. * @param objectIds The object id. * @param interfaceItem The item id for the building interface. * @param level The level required. * @param experience The experience gained. + * @param tools The tools needed. * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. */ - private Decoration(int[] objectIds, int interfaceItem, int level, double experience, int[] tools, Item... items) { + Decoration(int[] objectIds, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems) { this.objectId = objectIds[0]; this.objectIds = objectIds; this.interfaceItem = interfaceItem; @@ -1177,6 +880,7 @@ public enum Decoration { this.experience = experience; this.tools = tools; this.items = items; + this.refundItems = refundItems; } /** @@ -1203,7 +907,7 @@ public enum Decoration { } return null; } - + /** * Gets a decoration for the given object id * @param objectId - the object id of the built object @@ -1217,7 +921,7 @@ public enum Decoration { } return null; } - + public static Decoration forName(String name) { for (Decoration d : Decoration.values()) { if (d.name().equals(name)) { @@ -1239,7 +943,7 @@ public enum Decoration { } return 0; } - + /** * Gets the objectId. * @param style The current housing style. @@ -1251,7 +955,7 @@ public enum Decoration { } return objectId; } - + /** * Gets the objectId. * @return The objectId. @@ -1272,7 +976,7 @@ public enum Decoration { * Gets the experience. * @return The experience. */ - public double getExperience() { + public int getExperience() { return experience; } @@ -1284,6 +988,14 @@ public enum Decoration { return items; } + /** + * Gets the refund items. + * @return The refund items. + */ + public Item[] getRefundItems() { + return refundItems; + } + /** * Gets the tools. * @return The tools. @@ -1308,10 +1020,19 @@ public enum Decoration { return objectIds; } + /** + * If this node should be invisible to user build options + * @return true if so. + */ public boolean isInvisibleNode() { return invisibleNode; } - - + /** + * Gets the requirements text. + * @return The requirements text. + */ + public String[] getReqsText() { + return reqsText; + } } diff --git a/Server/src/main/content/global/skill/construction/HouseManager.java b/Server/src/main/content/global/skill/construction/HouseManager.java index b041e3c57..4db8e8191 100644 --- a/Server/src/main/content/global/skill/construction/HouseManager.java +++ b/Server/src/main/content/global/skill/construction/HouseManager.java @@ -1,9 +1,4 @@ package content.global.skill.construction; - - -//import org.arios.game.content.global.DeadmanTimedAction; -//import org.arios.game.node.entity.player.info.login.SavingModule; - import core.api.regionspec.RegionSpecification; import core.api.regionspec.contracts.FillChunkContract; import core.game.dialogue.FacialExpression; @@ -17,17 +12,14 @@ import core.game.world.map.zone.ZoneBorders; import core.game.world.map.zone.ZoneBuilder; import core.game.world.update.flag.context.Animation; import core.tools.Log; -import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import core.tools.SystemLogger; import core.game.world.GameWorld; import org.rs09.consts.Sounds; import java.awt.*; -import java.nio.ByteBuffer; import static core.api.ContentAPIKt.*; import static core.api.regionspec.RegionSpecificationKt.fillWith; @@ -106,36 +98,6 @@ public final class HouseManager { } - public void save(ByteBuffer buffer) { - buffer.put((byte) location.ordinal()); - buffer.put((byte) style.ordinal()); - if (hasServant()) { - servant.save(buffer); - } else { - buffer.put((byte) -1); - } - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 8; x++) { - for (int y = 0; y < 8; y++) { - Room room = rooms[z][x][y]; - if (room != null) { - buffer.put((byte) z).put((byte) x).put((byte) y); - buffer.put((byte) room.getProperties().ordinal()); - buffer.put((byte) room.getRotation().toInteger()); - for (int i = 0; i < room.getHotspots().length; i++) { - if (room.getHotspots()[i].getDecorationIndex() > -1) { - buffer.put((byte) i); - buffer.put((byte) room.getHotspots()[i].getDecorationIndex()); - } - } - buffer.put((byte) -1); - } - } - } - } - buffer.put((byte) -1);//Eof - } - public void parse(JSONObject data){ location = HouseLocation.values()[Integer.parseInt( data.get("location").toString())]; style = HousingStyle.values()[Integer.parseInt( data.get("style").toString())]; @@ -162,28 +124,6 @@ public final class HouseManager { } } - - public void parse(ByteBuffer buffer) { - location = HouseLocation.values()[buffer.get() & 0xFF]; - style = HousingStyle.values()[buffer.get() & 0xFF]; - servant = Servant.parse(buffer); - int z = 0; - while ((z = buffer.get()) != -1) { - if (z == 3) { - hasDungeon = true; - } - int x = buffer.get(); - int y = buffer.get(); - Room room = rooms[z][x][y] = new Room(RoomProperties.values()[buffer.get() & 0xFF]); - room.configure(style); - room.setRotation(Direction.get(buffer.get() & 0xFF)); - int spot = 0; - while ((spot = buffer.get()) != -1) { - room.getHotspots()[spot].setDecorationIndex(buffer.get() & 0xFF); - } - } - } - /** * Prepares for entering the player's house. * @param player @@ -195,6 +135,7 @@ public final class HouseManager { construct(); } player.setAttribute("poh_entry", HouseManager.this); + player.setAttribute("/save:original-loc", location.getExitLocation()); player.lock(1); player.debug("House location: " + houseRegion.getBaseLocation() + ", entry: " + getEnterLocation()); } @@ -263,7 +204,7 @@ public final class HouseManager { } /** - * Leaves this house. + * Leaves this house through the portal. * @param player The player leaving. */ public static void leave(Player player) { @@ -406,6 +347,7 @@ public final class HouseManager { Room room = rooms[0][4][3] = new Room(RoomProperties.GARDEN); room.configure(style); room.getHotspots()[0].setDecorationIndex(0); + redecorate(HousingStyle.BASIC_WOOD); this.location = location; } diff --git a/Server/src/main/content/global/skill/construction/HouseZone.java b/Server/src/main/content/global/skill/construction/HouseZone.java index dd0075f23..31a57f6f8 100644 --- a/Server/src/main/content/global/skill/construction/HouseZone.java +++ b/Server/src/main/content/global/skill/construction/HouseZone.java @@ -1,13 +1,16 @@ package content.global.skill.construction; +import core.api.Container; +import core.game.world.map.Location; +import org.rs09.consts.Items; import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.world.map.zone.MapZone; -import core.game.world.map.zone.ZoneRestriction; import core.game.world.map.RegionManager; import core.game.world.map.Region; import core.game.system.task.Pulse; +import core.game.world.map.zone.ZoneType; import static core.api.ContentAPIKt.*; @@ -37,12 +40,13 @@ public final class HouseZone extends MapZone { * Constructs the house zone object. */ public HouseZone(HouseManager house) { - super("poh-zone" + house, true, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FOLLOWERS); + super("poh-zone" + house, true); this.house = house; } @Override public void configure() { + setZoneType(ZoneType.P_O_H.getId()); unregisterOldRegions(); registerRegion(house.getHouseRegion().getId()); if (house.getDungeonRegion() != null) { @@ -81,37 +85,73 @@ public final class HouseZone extends MapZone { if (e instanceof Player) { Player p = (Player) e; HouseManager.leave(p); + return true; } - return true; + return super.death(e, killer); } @Override public boolean leave(Entity e, boolean logout) { if (e instanceof Player) { Player p = (Player) e; + + // if the player is moving between the dungeon and main house, don't trigger the leave sequence + if (house.getDungeonRegion() != null && !logout) { + // current loc + Location dest = p.getProperties().getTeleportLocation(); + int currentRegionId = p.getLocation().getRegionId(); + int houseId = house.getHouseRegion().getId(); + int dungeonId = house.getDungeonRegion().getId(); + + // check if still in house + boolean currentlyInHouse = (currentRegionId == houseId || currentRegionId == dungeonId); + + // check if moving between house regions + int destRegionId = (dest != null) ? dest.getRegionId() : -1; + boolean movingToHouse = (destRegionId == houseId || destRegionId == dungeonId); + + // if yes, return true and stop the leave sequence + if (currentlyInHouse || movingToHouse) { + return true; + } + } + + remove_items(p); + // The below tears down the house if the owner was the one who left if (house == p.getHouseManager()) { house.expelGuests(p); int toRemove = previousRegion; int dungRemove = previousDungeon; - submitWorldPulse(new Pulse(2) { + submitWorldPulse(new Pulse(1) { public boolean pulse() { Region r = RegionManager.forId(toRemove); Region dr = dungRemove != -1 ? RegionManager.forId(dungRemove) : null; RegionManager.removeRegion(toRemove); unregisterRegion(toRemove); - r.setActive(false); + r.flagInactive(); if (dungRemove != -1) { RegionManager.removeRegion(dungRemove); unregisterRegion(dungRemove); - dr.setActive(false); + dr.flagInactive(); } return true; } }); } + // Clear logout listener and original-loc (if appropriate) clearLogoutListener(p, "houselogout"); + if (!getAttribute(p, "kidnapped-by-random", false)) { + removeAttribute(p, "/save:original-loc"); + } return true; } return true; } + + private void remove_items(Player p) { + for (int item = Items.KETTLE_7688; item <= Items.CHEFS_DELIGHT_7755; item++) {//Removes all PoH versions of tea and beer barrel-related items + removeAll(p, item, Container.INVENTORY); + removeAll(p, item, Container.BoB); + } + } } diff --git a/Server/src/main/content/global/skill/construction/HousingStyle.java b/Server/src/main/content/global/skill/construction/HousingStyle.java index e4d59b90d..eace0e7bb 100644 --- a/Server/src/main/content/global/skill/construction/HousingStyle.java +++ b/Server/src/main/content/global/skill/construction/HousingStyle.java @@ -3,12 +3,16 @@ package content.global.skill.construction; import core.game.node.entity.player.Player; import core.game.node.entity.skill.Skills; +import java.util.Arrays; + /** * The styles of houses. * @author Emperor * */ public enum HousingStyle { + + // open door ids are doorId + 1 BASIC_WOOD (1, 5000, 7503, 0, 13100, 13101, 13098, Decoration.BASIC_WOOD_WINDOW), BASIC_STONE (10, 5000, 7503, 1, 13094, 13096, 1902, Decoration.BASIC_STONE_WINDOW), @@ -16,6 +20,28 @@ public enum HousingStyle { FREMENNIK_STYLE_WOOD(30, 10000, 7503, 3, 13109, 13107, 13111, Decoration.FREMENNIK_WINDOW), TROPICAL_WOOD (40, 15000, 7759, 0, 13016, 13015, 13011, Decoration.TROPICAL_WOOD_WINDOW), FANCY_STONE (50, 25000, 7759, 1, 13119, 13118, 13116, Decoration.FANCY_STONE_WINDOW); + + /** + * Array of all Dungeon Wall IDs. + * From Region 7503, Location.create(1898, 5084, 0) + */ + private static final int[] DUNGEON_WALL_IDS = { + 13019, 13020, 13021, 13022, 13023, 13024, 13025, 13026, 13027, 13028, + 13029, 13030, 13031, 13032, 13033, 13034, 13035, 13036, 13037, 13046, + 13048, 13049, 13050, 13051, 13055, 13056, 13058, 13059, 13060, 13061, + 13062, 13063, 13065, 13066, 13067, 13068, 13069, 13070, 13072, 13073, + 13074, 13075, 13076, 13077, 13079, 13080, 13081, 13082, 13083, 13084, + 13086, 13087, 13088, 13089 + }; + + /** + * Checks if the provided ID is a dungeon wall. + * @param id The object ID. + * @return {@code true} if it's a dungeon wall. + */ + public static boolean isDungeonWall(int id) { + return Arrays.binarySearch(DUNGEON_WALL_IDS, id) >= 0; + } /** * The level required. diff --git a/Server/src/main/content/global/skill/construction/RemovalDialogue.java b/Server/src/main/content/global/skill/construction/RemovalDialogue.java index 5b2a9f869..3edbc360f 100644 --- a/Server/src/main/content/global/skill/construction/RemovalDialogue.java +++ b/Server/src/main/content/global/skill/construction/RemovalDialogue.java @@ -53,10 +53,23 @@ public final class RemovalDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { pos = (int[]) args[1]; - plane = player.getLocation().getZ(); - if (HouseManager.isInDungeon(player)) { - plane = 3; - } + + if (args.length > 2 && args[2] instanceof Integer) { + plane = (Integer) args[2]; + } else { + plane = player.getLocation().getZ(); + if (HouseManager.isInDungeon(player)) { + plane = 3; + } + } + + // check if room exists + room = player.getHouseManager().getRooms()[plane][pos[0]][pos[1]]; + if (room == null || room.getProperties().isRoof()) { + interpreter.sendPlainMessage(false, "There is no room there to remove."); + return false; + } + room = player.getHouseManager().getRooms()[plane][pos[0]][pos[1]]; player.getDialogueInterpreter().sendOptions("Remove the " + (room != null ? room.getProperties().getName() : "room") + "?", "Yes", "No"); stage = 0; diff --git a/Server/src/main/content/global/skill/construction/Room.java b/Server/src/main/content/global/skill/construction/Room.java index 0353cd632..ac7b56cec 100644 --- a/Server/src/main/content/global/skill/construction/Room.java +++ b/Server/src/main/content/global/skill/construction/Room.java @@ -2,9 +2,13 @@ package content.global.skill.construction; import core.game.node.entity.player.Player; +import core.game.node.scenery.Constructed; import core.game.node.scenery.Scenery; import core.game.node.scenery.SceneryBuilder; import core.game.world.map.*; +import core.tools.Log; + +import static core.api.ContentAPIKt.log; /** * Represents a room. @@ -93,7 +97,7 @@ public final class Room { Region.load(region, true); chunk = region.getPlanes()[style.getPlane()].getRegionChunk(properties.getChunkX(), properties.getChunkY()); } - + /** * Gets the hotspot object for the given hotspot type. * @param hotspot The hotspot type. @@ -154,6 +158,7 @@ public final class Room { chunk.rotate(rotation); } if (!house.isBuildingMode()) { + placeDoors(housePlane, house, chunk); removeHotspots(housePlane, house, chunk); } } @@ -165,17 +170,17 @@ public final class Room { * @param chunk The region chunk used. */ private void removeHotspots(int housePlane, HouseManager house, BuildRegionChunk chunk) { - for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) { - for (int x = 0; x < 8; x++) { - for (int y = 0; y < 8; y++) { + if (properties.isRoof()) return; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) { Scenery object = chunk.get(x, y, i); - if (object != null && object.getDefinition().hasAction("Build")) { - if (properties.isChamber() && BuildingUtils.isDoorHotspot(object)) { - if (!placeDoors(house, chunk, object, housePlane, x, y, rotation)) { - SceneryBuilder.remove(object); - chunk.remove(object); - } - } else { + if (object != null) { + int id = object.getId(); + boolean isBuilt = object instanceof Constructed; + boolean isWall = HousingStyle.isDungeonWall(id) || id == house.getStyle().getWallId(); + boolean isDoor = id == house.getStyle().getDoorId() || id == house.getStyle().getSecondDoorId(); + if (!isBuilt && !isWall && !isDoor) { SceneryBuilder.remove(object); chunk.remove(object); } @@ -186,65 +191,92 @@ public final class Room { } /** - * Places the doors when needed. - * @param chunk The chunk. - * @param object The object. - * @param x The x-coordinate of the object. - * @param y The y-coordinate of the object. + * Replaces the door hotspots with doors, walls, or passageways as needed. + * TODO: it is believed that doors authentically remember their open/closed state for the usual duration (see e.g. https://www.youtube.com/watch?v=nRGux739h8s 1:00 vs 1:55), but this is not possible with the current HouseManager approach, which deallocates the instance as soon as the player leaves. + * @param housePlane The room's plane in house. + * @param house The house manager. + * @param chunk The region chunk used. */ - private boolean placeDoors(HouseManager house, BuildRegionChunk chunk, Scenery object, int z, int x, int y, Direction rotation) { - int doorX; - int doorY; - switch (rotation) { - case EAST: - doorX = y; - doorY = 7 - x; - break; - case SOUTH: - doorX = 7 - x; - doorY = 7 - y; - break; - case WEST: - doorX = 7 - y; - doorY = x; - break; - default: - doorX = x; - doorY = y; - break; - } - int chunkX = chunk.getCurrentBase().getChunkX(); - int chunkY = chunk.getCurrentBase().getChunkY(); - boolean houseExit = true; - Room r; - if (doorX == 0 && chunkX > 0 && (r = house.getRooms()[z][chunkX - 1][chunkY]) != null && r.getProperties().isChamber()) { - houseExit = false; - } - else if (doorX == 7 && chunkX < 7 && (r = house.getRooms()[z][chunkX + 1][chunkY]) != null && r.getProperties().isChamber()) { - houseExit = false; - } - else if (doorY == 0 && chunkY > 0 && (r = house.getRooms()[z][chunkX][chunkY - 1]) != null && r.getProperties().isChamber()) { - houseExit = false; - } - else if (doorY == 7 && chunkY < 7 && (r = house.getRooms()[z][chunkX][chunkY + 1]) != null && r.getProperties().isChamber()) { - houseExit = false; - } - int replaceId = object.getId() % 2 != 0 ? house.getStyle().getDoorId() : house.getStyle().getSecondDoorId(); - houseExit = false; - if (z != 0 && houseExit) { - r = house.getRooms()[z][chunkX][chunkY]; - if (r.getProperties().isDungeon()) { - replaceId = 13065; - } else { - replaceId = house.getStyle().getWallId(); + private void placeDoors(int housePlane, HouseManager house, BuildRegionChunk chunk) { + Room[][][] rooms = house.getRooms(); + int rx = chunk.getCurrentBase().getChunkX(); + int ry = chunk.getCurrentBase().getChunkY(); + for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Scenery object = chunk.get(x, y, i); + if (object != null && BuildingUtils.isDoorHotspot(object)) { + boolean edge = false; + Room otherRoom = null; + switch (object.getRotation()) { + case 0: //east + edge = rx == 0; + otherRoom = edge ? null : rooms[housePlane][rx - 1][ry]; + break; + case 1: //south + edge = ry == 7; + otherRoom = edge ? null : rooms[housePlane][rx][ry + 1]; + break; + case 2: //west + edge = rx == 7; + otherRoom = edge ? null : rooms[housePlane][rx + 1][ry]; + break; + case 3: //north + edge = ry == 0; + otherRoom = edge ? null : rooms[housePlane][rx][ry - 1]; + break; + default: + log(this.getClass(), Log.ERR, "Impossible rotation when placing doors??"); + } + int replaceId = getReplaceId(housePlane, house, this, edge, otherRoom, object); + if (replaceId == -1) { + continue; + } + SceneryBuilder.replace(object, object.transform(replaceId)); + } + } } } - else if (!houseExit) { - return false; - } - return SceneryBuilder.replace(object, object.transform(replaceId, object.getRotation(), chunk.getCurrentBase().transform(x, y, 0)), true, true); } - + + /** + * Checks if rooms transition between inside<>outside the house and returns the appropriate door replacement. + * @param housePlane The room's plane in house. + * @param house The house manager. + * @param room The room the door is in. + * @param edge Whether the door is adjacent to an edge. + * @param otherRoom The room the door is adjacent to. + * @param object The door object itself. + */ + private int getReplaceId(int housePlane, HouseManager house, Room room, boolean edge, Room otherRoom, Scenery object) { + boolean thisOutside = !room.getProperties().isChamber(); + if (edge && thisOutside) { + // No door or wall + return -1; + } + if (!edge) { + boolean otherOutside = otherRoom == null || !otherRoom.getProperties().isChamber(); + if (thisOutside == otherOutside) { + // Free passage, unless the other room has a blind wall here + if (otherRoom == null) { + return -1; + } + boolean exit = otherRoom.getExits()[object.getRotation()]; + if (exit) { + return -1; + } + } + if (thisOutside != otherOutside && housePlane == 0) { + // Door if we are the inside room only + if (thisOutside) { + return -1; + } + return object.getId() % 2 != 0 ? house.getStyle().getDoorId() : house.getStyle().getSecondDoorId(); + } + } + return room.getProperties().isDungeon() ? 13065 : house.getStyle().getWallId(); + } + /** * Sets the decoration index for a group of object ids * @param index The index. @@ -392,4 +424,4 @@ public final class Room { return rotation; } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/construction/RoomProperties.java b/Server/src/main/content/global/skill/construction/RoomProperties.java index 196a63c25..80bc6e6ed 100644 --- a/Server/src/main/content/global/skill/construction/RoomProperties.java +++ b/Server/src/main/content/global/skill/construction/RoomProperties.java @@ -8,11 +8,10 @@ import core.game.world.map.RegionManager; /** * Represents the room properties. - * @author Emperor + * @author Emperor, Player Name * >ORDINAL BOUND< */ public enum RoomProperties { - /** * The parlour. */ @@ -50,22 +49,21 @@ public enum RoomProperties { new Hotspot(BuildHotspot.RUG2, 5, 4), new Hotspot(BuildHotspot.RUG, 5, 5), new Hotspot(BuildHotspot.CHAIRS_1, 2, 4), - new Hotspot(BuildHotspot.FIREPLACE, 3, 7,4,7), + new Hotspot(BuildHotspot.FIREPLACE, 3, 7, 4, 7), new Hotspot(BuildHotspot.CHAIRS_3, 4, 3), new Hotspot(BuildHotspot.CHAIRS_2, 5, 4), new Hotspot(BuildHotspot.BOOKCASE, 7, 1)), - /** * The garden. (centrepiece has to be first!) */ - GARDEN(1000, 1, 0, 0, 1, Room.LAND, new Hotspot(BuildHotspot.CENTREPIECE_1, 3, 3,4,4), - new Hotspot(BuildHotspot.BIG_PLANT_2, 0, 0,1,1), - new Hotspot(BuildHotspot.BIG_TREE_1, 1, 5,2,6), + GARDEN(1000, 1, 0, 0, 1, Room.LAND, new Hotspot(BuildHotspot.CENTREPIECE_1, 3, 3, 4, 4), + new Hotspot(BuildHotspot.BIG_PLANT_2, 0, 0, 1, 1), + new Hotspot(BuildHotspot.BIG_TREE_1, 1, 5, 2, 6), new Hotspot(BuildHotspot.SMALL_PLANT_1, 3, 1), new Hotspot(BuildHotspot.SMALL_PLANT_2, 4, 5), - new Hotspot(BuildHotspot.BIG_PLANT_1, 6, 1,7,0), - new Hotspot(BuildHotspot.TREE_1, 6, 6,7,7)), + new Hotspot(BuildHotspot.BIG_PLANT_1, 6, 0, 7, 1), + new Hotspot(BuildHotspot.TREE_1, 6, 6, 7, 7)), /** * The kitchen. @@ -80,10 +78,10 @@ public enum RoomProperties { new Hotspot(BuildHotspot.WINDOW, 7, 2), new Hotspot(BuildHotspot.WINDOW, 7, 5), new Hotspot(BuildHotspot.BARRELS, 0, 6), - new Hotspot(BuildHotspot.KITCHEN_TABLE, 3, 3,4,4), - new Hotspot(BuildHotspot.STOVE, 3, 7), - new Hotspot(BuildHotspot.LARDER, 6, 0,7,1), - new Hotspot(BuildHotspot.SINK, 7, 3,7,4), + new Hotspot(BuildHotspot.KITCHEN_TABLE, 3, 3, 4, 4), + new Hotspot(BuildHotspot.STOVE, 3, 7, 4, 7), + new Hotspot(BuildHotspot.LARDER, 6, 0, 7, 1), + new Hotspot(BuildHotspot.SINK, 7, 3, 7, 4), new Hotspot(BuildHotspot.SHELVES, 1, 7), new Hotspot(BuildHotspot.SHELVES, 6, 7), new Hotspot(BuildHotspot.SHELVES_2, 7, 6)), @@ -91,7 +89,7 @@ public enum RoomProperties { /** * Dining room. */ - DINING_ROOM(5000, 10, 0, 4, 7, Room.CHAMBER, new Hotspot(BuildHotspot.FIREPLACE_DINING, 3, 7,4,7), + DINING_ROOM(5000, 10, 0, 4, 7, Room.CHAMBER, new Hotspot(BuildHotspot.FIREPLACE_DINING, 3, 7, 4, 7), new Hotspot(BuildHotspot.WINDOW, 0, 2), new Hotspot(BuildHotspot.WINDOW, 0, 5), new Hotspot(BuildHotspot.WINDOW, 2, 0), @@ -115,12 +113,12 @@ public enum RoomProperties { new Hotspot(BuildHotspot.DINING_BENCH_1, 4, 2), new Hotspot(BuildHotspot.DINING_BENCH_1, 5, 2), new Hotspot(BuildHotspot.ROPE_BELL_PULL, 0, 0), - new Hotspot(BuildHotspot.DINING_TABLE, 2, 3,5,4)), + new Hotspot(BuildHotspot.DINING_TABLE, 2, 3, 5, 4)), /** * Workshop. */ - WORKSHOP(10000, 15, 0, 0, 5, Room.CHAMBER, new Hotspot(BuildHotspot.WORKBENCH, 3, 4,4,4), + WORKSHOP(10000, 15, 0, 0, 5, Room.CHAMBER, new Hotspot(BuildHotspot.WORKBENCH, 3, 4, 4, 4), new Hotspot(BuildHotspot.WINDOW, 0, 2), new Hotspot(BuildHotspot.WINDOW, 0, 5), new Hotspot(BuildHotspot.WINDOW, 2, 0), @@ -129,9 +127,9 @@ public enum RoomProperties { new Hotspot(BuildHotspot.WINDOW, 7, 5), new Hotspot(BuildHotspot.WINDOW, 2, 7), new Hotspot(BuildHotspot.WINDOW, 5, 7), - new Hotspot(BuildHotspot.REPAIR, 7, 3,7,4), - new Hotspot(BuildHotspot.HERALDRY, 7, 6,7,7), - new Hotspot(BuildHotspot.CRAFTING, 0, 3,0,4), + new Hotspot(BuildHotspot.REPAIR, 7, 3, 7, 4), + new Hotspot(BuildHotspot.HERALDRY, 7, 6, 7, 7), + new Hotspot(BuildHotspot.CRAFTING, 0, 3, 0, 4), new Hotspot(BuildHotspot.WORKBENCH, 3, 4), new Hotspot(BuildHotspot.TOOL4, 7, 1), new Hotspot(BuildHotspot.TOOL2, 6, 0), @@ -142,10 +140,10 @@ public enum RoomProperties { /** * Bedroom. */ - BEDROOM(10000, 20, 0, 6, 7, Room.CHAMBER, new Hotspot(BuildHotspot.BED, 3, 7,4,6), - new Hotspot(BuildHotspot.FIREPLACE2, 7,4,7, 3), + BEDROOM(10000, 20, 0, 6, 7, Room.CHAMBER, new Hotspot(BuildHotspot.BED, 3, 6, 4, 7), + new Hotspot(BuildHotspot.FIREPLACE2, 7, 3, 7, 4), new Hotspot(BuildHotspot.CLOCK, 7, 0), - new Hotspot(BuildHotspot.DRESSER, 0, 7,1,7), + new Hotspot(BuildHotspot.DRESSER, 0, 7, 1, 7), new Hotspot(BuildHotspot.DRAWERS, 6, 7), new Hotspot(BuildHotspot.WINDOW, 0, 2), new Hotspot(BuildHotspot.WINDOW, 0, 5), @@ -193,9 +191,9 @@ public enum RoomProperties { new Hotspot(BuildHotspot.BEDROOM_RUG3, 6, 4)), /** - * Skill hall room. + * Skill hall. */ - SKILL_HALL(15000, 25, 0, 1, 6, Room.CHAMBER, new Hotspot(BuildHotspot.STAIRWAYS, 3, 3,4,4), + SKILL_HALL(15000, 25, 0, 1, 6, Room.CHAMBER, new Hotspot(BuildHotspot.STAIRWAYS, 3, 3, 4, 4), new Hotspot(BuildHotspot.ARMOUR_SPACE, 2, 3), new Hotspot(BuildHotspot.ARMOUR_SPACE2, 5, 3), new Hotspot(BuildHotspot.HEAD_TROPHY, 6, 7), @@ -254,7 +252,7 @@ public enum RoomProperties { new Hotspot(BuildHotspot.ATTACK_STONE, 2, 4), new Hotspot(BuildHotspot.PRIZE_CHEST, 3, 7), new Hotspot(BuildHotspot.ELEMENTAL_BALANCE, 5, 4), - new Hotspot(BuildHotspot.GAME_SPACE, 6, 0,7,1), + new Hotspot(BuildHotspot.GAME_SPACE, 6, 0, 7, 1), new Hotspot(BuildHotspot.WINDOW, 0, 2), new Hotspot(BuildHotspot.WINDOW, 0, 5), new Hotspot(BuildHotspot.WINDOW, 2, 0), @@ -318,10 +316,11 @@ public enum RoomProperties { new Hotspot(BuildHotspot.CR_INVISIBLE_WALL, 3, 5), new Hotspot(BuildHotspot.CR_INVISIBLE_WALL, 5, 3), new Hotspot(BuildHotspot.CR_INVISIBLE_WALL, 4, 2)), + /** * Quest trophy hall. */ - QUEST_HALL(25000, 35, 0, 5, 6, Room.CHAMBER, new Hotspot(BuildHotspot.QUEST_STAIRWAYS, 3, 3,4,4), + QUEST_HALL(25000, 35, 0, 5, 6, Room.CHAMBER, new Hotspot(BuildHotspot.QUEST_STAIRWAYS, 3, 3, 4, 4), new Hotspot(BuildHotspot.MAP, 7, 1), new Hotspot(BuildHotspot.SWORD, 7, 6), new Hotspot(BuildHotspot.LANDSCAPE, 6, 7), @@ -376,21 +375,11 @@ public enum RoomProperties { /** * Study. */ -/* Menagerie(30000, 37, 0, 7, 2, Room.LAND, - new Hotspot(BuildHotspot.PET_HOUSE, 1, 1), - new Hotspot(BuildHotspot.PET_FEEDER, 5, 1), - new Hotspot(BuildHotspot.OBELISK, 5, 5), - new Hotspot(BuildHotspot.HABITAT_2, 1, 5), - new Hotspot(BuildHotspot.HABITAT_1, 6, 6)),*/ - - /** - * Study. - */ - STUDY_ROOM(50000, 40, 0, 4, 5, Room.CHAMBER, new Hotspot(BuildHotspot.GLOBE, 1, 4,3,6), + STUDY_ROOM(50000, 40, 0, 4, 5, Room.CHAMBER, new Hotspot(BuildHotspot.GLOBE, 1, 4, 3, 6), new Hotspot(BuildHotspot.LECTERN, 2, 2), - new Hotspot(BuildHotspot.CRYSTAL_BALL, 5, 4), - new Hotspot(BuildHotspot.BOOKCASE3, 4, 7,3,7), - new Hotspot(BuildHotspot.BOOKCASE3, 3, 7,4,7), + new Hotspot(BuildHotspot.CRYSTAL_BALL, 5, 2), + new Hotspot(BuildHotspot.BOOKCASE3, 3, 7, 3, 7), + new Hotspot(BuildHotspot.BOOKCASE3, 4, 7, 4, 7), new Hotspot(BuildHotspot.WALL_CHART, 1, 7), new Hotspot(BuildHotspot.WALL_CHART, 6, 7), new Hotspot(BuildHotspot.WALL_CHART, 7, 1), @@ -414,22 +403,22 @@ public enum RoomProperties { new Hotspot(BuildHotspot.WINDOW, 5, 0), new Hotspot(BuildHotspot.WINDOW, 7, 2), new Hotspot(BuildHotspot.WINDOW, 7, 5), - new Hotspot(BuildHotspot.TREASURE_CHEST, 0, 3,0,4), + new Hotspot(BuildHotspot.TREASURE_CHEST, 0, 3, 0, 4), new Hotspot(BuildHotspot.ARMOUR_CASE, 2, 7), - new Hotspot(BuildHotspot.MAGIC_WARDROBE, 3, 7,5,7), + new Hotspot(BuildHotspot.MAGIC_WARDROBE, 3, 7, 5, 7), new Hotspot(BuildHotspot.CAPE_RACK, 6, 6), - new Hotspot(BuildHotspot.TOY_BOX, 7, 3,7,4), - new Hotspot(BuildHotspot.COSTUME_BOX, 3, 4,4,3)), + new Hotspot(BuildHotspot.TOY_BOX, 7, 3, 7, 4), + new Hotspot(BuildHotspot.COSTUME_BOX, 3, 3, 4, 4)), /** * Chapel room. */ CHAPEL(50000, 45, 0, 2, 5, Room.CHAMBER, - new Hotspot(BuildHotspot.ALTAR, 3, 5,4,5), + new Hotspot(BuildHotspot.ALTAR, 3, 5, 4, 5), new Hotspot(BuildHotspot.STATUE, 7, 0), new Hotspot(BuildHotspot.STATUE, 0, 0), - new Hotspot(BuildHotspot.ICON, 3,7,4, 7), - new Hotspot(BuildHotspot.MUSICAL, 7,4,7,3), + new Hotspot(BuildHotspot.ICON, 3, 7, 4, 7), + new Hotspot(BuildHotspot.MUSICAL, 7, 3, 7, 4), new Hotspot(BuildHotspot.BURNERS, 1, 5), new Hotspot(BuildHotspot.BURNERS, 6, 5), new Hotspot(BuildHotspot.CHAPEL_RUG, 3, 1), @@ -452,10 +441,10 @@ public enum RoomProperties { /** * Portal chamber. */ - PORTAL_CHAMBER(100000, 50, 0, 1, 4, Room.CHAMBER, new Hotspot(BuildHotspot.TELEPORT_FOCUS, 3, 3,4,4), - new Hotspot(BuildHotspot.PORTAL1, 0, 3,0,4), - new Hotspot(BuildHotspot.PORTAL2, 3, 7,4,7), - new Hotspot(BuildHotspot.PORTAL3, 7, 3,7,4), + PORTAL_CHAMBER(100000, 50, 0, 1, 4, Room.CHAMBER, new Hotspot(BuildHotspot.TELEPORT_FOCUS, 3, 3, 4, 4), + new Hotspot(BuildHotspot.PORTAL1, 0, 3, 0, 4), + new Hotspot(BuildHotspot.PORTAL2, 3, 7, 4, 7), + new Hotspot(BuildHotspot.PORTAL3, 7, 3, 7, 4), new Hotspot(BuildHotspot.WINDOW, 0, 2), new Hotspot(BuildHotspot.WINDOW, 0, 5), new Hotspot(BuildHotspot.WINDOW, 2, 0), @@ -469,7 +458,7 @@ public enum RoomProperties { * The formal garden. * Centrepiece should be first! */ - FORMAL_GARDEN(75000, 55, 0, 2, 1, Room.LAND, new Hotspot(BuildHotspot.CENTREPIECE_2, 3, 3,4,4), + FORMAL_GARDEN(75000, 55, 0, 2, 1, Room.LAND, new Hotspot(BuildHotspot.CENTREPIECE_2, 3, 3, 4, 4), new Hotspot(BuildHotspot.FENCING, 0, 0), new Hotspot(BuildHotspot.FENCING, 1, 0), new Hotspot(BuildHotspot.FENCING, 2, 0), @@ -621,6 +610,7 @@ public enum RoomProperties { new Hotspot(BuildHotspot.PRISON, 5, 4), new Hotspot(BuildHotspot.PRISON, 4, 5), new Hotspot(BuildHotspot.PRISON_DOOR, 3, 5)), + /** * Dungeon corridor. */ @@ -695,6 +685,9 @@ public enum RoomProperties { new Hotspot(BuildHotspot.DUNGEON_DECO, 6, 1), new Hotspot(BuildHotspot.DUNGEON_DECO, 1, 6)), + /** + * Dungeon pit. + */ DUNGEON_PIT(10000, 70, 0, 5, 2, Room.DUNGEON, new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT3, 3, 1), new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT3, 4, 1), @@ -917,7 +910,7 @@ public enum RoomProperties { * @return The name. */ public String getName() { - return name().toLowerCase().replaceAll("_", " ").replaceAll("\\d",""); + return name().toLowerCase().replaceAll("_", " ").replaceAll("\\d", ""); } /** @@ -1023,5 +1016,4 @@ public enum RoomProperties { public int getLevel() { return level; } - -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/construction/Servant.java b/Server/src/main/content/global/skill/construction/Servant.java index 63275330d..a3527bdad 100644 --- a/Server/src/main/content/global/skill/construction/Servant.java +++ b/Server/src/main/content/global/skill/construction/Servant.java @@ -5,8 +5,6 @@ import core.game.node.entity.npc.NPC; import core.game.node.item.Item; import org.json.simple.JSONObject; -import java.nio.ByteBuffer; - /** * Represents a player's servant. * @author Emperor @@ -44,26 +42,9 @@ public final class Servant extends NPC { } /** - * Saves the servant details. - * @param buffer The buffer to write on. - */ - public void save(ByteBuffer buffer) { - buffer.put((byte) type.ordinal()); - buffer.putShort((byte) uses); - if (item == null) { - buffer.putShort((short) -1); - } else { - buffer.putShort((short) item.getId()); - buffer.putInt(item.getAmount()); - } - buffer.put((byte) (greet ? 1 : 0)); - } - - /** - * Parses the servant from the buffer. + * Parses the servant from the save file. * @return The servant. */ - public static Servant parse(JSONObject data){ int type = Integer.parseInt( data.get("type").toString()); Servant servant = new Servant(ServantType.values()[type]); @@ -77,21 +58,6 @@ public final class Servant extends NPC { return servant; } - public static Servant parse(ByteBuffer buffer) { - int type = buffer.get(); - if (type == -1) { - return null; - } - Servant servant = new Servant(ServantType.values()[type]); - servant.uses = buffer.getShort() & 0xFFFF; - int itemId = buffer.getShort() & 0xFFFF; - if ((short) itemId != -1) { - servant.item = new Item(itemId, buffer.getInt()); - } - servant.greet = buffer.get() == 1; - return servant; - } - /** * Gets the item value. * @return The item. diff --git a/Server/src/main/content/global/skill/construction/decoration/BeerBarrelPlugin.java b/Server/src/main/content/global/skill/construction/decoration/BeerBarrelPlugin.java deleted file mode 100644 index dce9b7cf9..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/BeerBarrelPlugin.java +++ /dev/null @@ -1,76 +0,0 @@ -package content.global.skill.construction.decoration; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Items; - -/** - * Handles the Construction beer barrels. - * @author Splinter - */ -@Initializable -public class BeerBarrelPlugin extends UseWithHandler { - - /** - * The object ids - */ - private static final int[] OBJECTS = new int[] { - 13568, 13569, 13570, 13571, 13572, 13573 - }; - - /** - * Constructs a new {@Code BeerBarrelPlugin} {@Code Object} - */ - public BeerBarrelPlugin() { - super(1919); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int id : OBJECTS) { - addHandler(id, OBJECT_TYPE, this); - } - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - Player player = event.getPlayer(); - final Scenery object = (Scenery) event.getUsedWith(); - - if (player.getInventory().remove(new Item(Items.BEER_GLASS_1919))) { - player.animate(Animation.create(833)); - player.sendMessage("You fill up your glass."); - player.getInventory().add(new Item(getReward(object.getId()), 1)); - } - return true; - } - - /** - * Get the beer reward based on the interaced barrel. - * @return the item to give. - */ - public int getReward(int barrelId) { - switch (barrelId) { - case 13568: - return 1917; - case 13569: - return 5763; - case 13570: - return 1905; - case 13571: - return 1909; - case 13572: - return 1911; - case 13573: - return 5755; - } - return 1917; - } -} diff --git a/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt index 1ae0cc376..75a9e2207 100644 --- a/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt +++ b/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt @@ -1,13 +1,13 @@ package content.global.skill.construction.decoration +import content.global.skill.construction.BuildHotspot +import content.global.skill.construction.HousingStyle import core.cache.def.impl.SceneryDefinition import core.game.global.action.DoorActionHandler import core.game.interaction.OptionHandler import core.game.node.Node -import core.game.node.scenery.Scenery import core.game.node.entity.player.Player -import content.global.skill.construction.BuildHotspot -import content.global.skill.construction.HousingStyle +import core.game.node.scenery.Scenery import core.plugin.Initializable import core.plugin.Plugin @@ -38,11 +38,11 @@ class ConstructionDoorPlugin : OptionHandler() { } override fun handle(player: Player, node: Node, option: String): Boolean { - val `object` = node as Scenery - val second = DoorActionHandler.getSecondDoor(`object`, player) when (option) { "pick-lock", "force" -> return false //TODO } + val `object` = node as Scenery + val second = DoorActionHandler.getSecondDoor(`object`, player) DoorActionHandler.open(`object`, second, getReplaceId(`object`), getReplaceId(second), true, 500, false) return true } @@ -80,4 +80,4 @@ class ConstructionDoorPlugin : OptionHandler() { intArrayOf(13119, 13121) ) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java b/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java index a1fe9ed3e..8c22d84ab 100644 --- a/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java +++ b/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java @@ -29,15 +29,19 @@ public final class StaircasePlugin extends OptionHandler { public Plugin newInstance(Object arg) throws Throwable { ClassScanner.definePlugin(new BuildDialogue()); ClassScanner.definePlugin(new ClimbPohLadder()); - for (int i = 13497; i < 13507; i++) { + // 13497 - 13502 are normal stairs + // 13503 - 13506 are spiral stairs + for (int i = 13497; i <= 13506; i++) { SceneryDefinition.forId(i).getHandlers().put("option:climb", this); SceneryDefinition.forId(i).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(i).getHandlers().put("option:climb-down", this); SceneryDefinition.forId(i).getHandlers().put("option:remove-room", this); } + // 13409 is dungeon entrance SceneryDefinition.forId(13409).getHandlers().put("option:enter", this); SceneryDefinition.forId(13409).getHandlers().put("option:remove-room", this); - for (int id = 13328; id < 13331; id++) { + // 13328 - 13330 are dungeon ladders + for (int id = 13328; id <= 13330; id++) { SceneryDefinition.forId(id).getHandlers().put("option:climb", this); SceneryDefinition.forId(id).getHandlers().put("option:remove-room", this); } @@ -69,13 +73,47 @@ public final class StaircasePlugin extends OptionHandler { SceneryBuilder.replace(object, object.transform(object.getId() - 3)); return true; case "remove-room": - if (player.getLocation().getZ() != 0) { - player.getPacketDispatch().sendMessage("The room below is supporting this room!"); - return true; - } - return false; + + int currentZ = player.getLocation().getZ(); + int chunkX = player.getLocation().getChunkX(); + int chunkY = player.getLocation().getChunkY(); + + // must be in building mode + if(!player.getHouseManager().isBuildingMode()) { + player.getPacketDispatch().sendMessage("You can only do this in building mode."); + return true; + } + + // if you're in the dungeon, try and remove the room at Z = 0 from the house region. + if (HouseManager.isInDungeon(player)) { + player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 0); + + // From ground floor (z=0), stairs could lead to 1st floor (z=1) or the dungeon (z=3) + } else { + // garden dungeon entrance and oubliette ladders don't need a height selection + if(node.getId() == 13409 || node.getId() == 13675 || node.getId() == 13676 || node.getId() == 13677 || node.getId() == 13678 || node.getId() == 13679 || node.getId() == 13680) { + player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 3); + } else { + player.getDialogueInterpreter().sendOptions("Remove which room?", "Room Above", "Room Below", "Cancel"); + player.getDialogueInterpreter().addAction((interId, btn) -> { + if (btn == 2) { // Above + player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, currentZ + 1); + } else if (btn == 3) { // Below + if (currentZ - 1 == -1) { + player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 3); + } else { + player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, currentZ - 1); + } + + } + }); + } + + } + return true; + case "climb": - if (house.getDungeonRegion() == player.getViewport().getRegion()) { + if (HouseManager.isInDungeon(player)) { climb(player, 1, house, object); return true; } @@ -379,10 +417,11 @@ public final class StaircasePlugin extends OptionHandler { for (Direction d : dirs) { if (d == room.getRotation()) { r.setRotation(d); - Hotspot stairs = room.getStairs(); - int index = stairs != null ? stairs.getDecorationIndex() : -1; + // todo this just puts a default set of stairs in the dungeon. The below code works for skill/quest hall, but not a dungeon entrance. + //Hotspot stairs = room.getStairs(); + //int index = stairs != null ? stairs.getDecorationIndex() : -1; BuildingUtils.buildRoom(player, r, plane, roomX, roomY, r.getExits(), true); - r.getStairs().setDecorationIndex(index); + r.getStairs().setDecorationIndex(/*index*/1); end(); return true; } diff --git a/Server/src/main/content/global/skill/construction/decoration/costume/ToyBoxPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/costume/ToyBoxPlugin.kt deleted file mode 100644 index 86b5007d1..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/costume/ToyBoxPlugin.kt +++ /dev/null @@ -1,29 +0,0 @@ -package content.global.skill.construction.decoration.costume - -import core.cache.def.impl.SceneryDefinition -import core.game.interaction.OptionHandler -import content.global.handlers.item.toys.DiangoReclaimInterface -import core.game.node.Node -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.plugin.Plugin - -/** - * Handles the Toy Box POH - * ToyBoxPlugin.java - * @author Lee - * @date 10/2/2017 - */ -@Initializable -class ToyBoxPlugin : OptionHandler() { - @Throws(Throwable::class) - override fun newInstance(arg: Any?): Plugin { - SceneryDefinition.forId(18802).handlers["option:open"] = this - return this - } - - override fun handle(player: Player, node: Node, option: String): Boolean { - DiangoReclaimInterface.open(player) - return true - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/AbstractContainer.kt b/Server/src/main/content/global/skill/construction/decoration/kitchen/AbstractContainer.kt new file mode 100644 index 000000000..6086aff25 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/AbstractContainer.kt @@ -0,0 +1,78 @@ +package content.global.skill.construction.decoration.kitchen + +import core.api.addItem +import core.api.freeSlots +import core.api.sendDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE + +abstract class AbstractContainer(containerId: Int, containers: Map>>, private val containerName: String) : DialogueFile() { + + private val container = containers[containerId]!! + private val containerItemsNames = container.map { it.first } + private val containerItemsIds = container.map { it.second } + private val size = container.size + private val itemsPerPage = 4 + + private fun checkItem(player: Player, idx : Int){ + val item = containerItemsIds[idx] + if (addItem(player, item)){ + end() + } + else{ + sendDialogue(player, "You need at least one free inventory space to take from the $containerName.").also { stage = END_DIALOGUE } + } + } + + private fun createTopics(page: Int): MutableList> { + val startIndex = (page - 1) * itemsPerPage + val endIndex = (startIndex + itemsPerPage).coerceAtMost(size) + + val topics = containerItemsNames.subList(startIndex, endIndex) + .mapIndexed { index, item -> Topic(item, startIndex + index + 1, skipPlayer = true) } + .toMutableList() + + // Add "More" button if there's another page or to loop back + if (endIndex < size || page > 1) { + topics.add(Topic("More", endIndex + 1, skipPlayer = true)) + } + + return topics + } + + + + override fun handle(componentID: Int, buttonID: Int) { + if (freeSlots(player!!) == 0) { + sendDialogue(player!!, "You need at least one free inventory space to take from the $containerName.").also { stage = END_DIALOGUE } + return + } + val itemsPerPage = 4 + + when (stage) { + 0, size + 1 -> { // Initial stage or final more button clicked + val topics = createTopics(1) + showTopics(*topics.toTypedArray()).also { stage = 1 } + } + in 1..size -> { + val currentPage = (stage-1) / itemsPerPage + val startIndex = currentPage * itemsPerPage + + if (buttonID == itemsPerPage + 1) { // "More" button clicked (but not the last one) + val topics = createTopics(currentPage + 1) + showTopics(*topics.toTypedArray()).also { stage = currentPage*itemsPerPage + 1 } + } else { // Handle item selection + val itemIndex = startIndex + (buttonID - 1) + if (itemIndex < size) { + checkItem(player!!, itemIndex) + } + } + } + else -> end() + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelInteraction.kt b/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelInteraction.kt new file mode 100644 index 000000000..4c6ee0949 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelInteraction.kt @@ -0,0 +1,29 @@ +package content.global.skill.construction.decoration.kitchen + +import core.api.* +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class BeerBarrelInteraction : InteractionListener { + + companion object{ + private val barrelMap = mapOf( + org.rs09.consts.Scenery.BEER_BARREL_13568 to Items.BEER_7740, + org.rs09.consts.Scenery.CIDER_BARREL_13569 to Items.CIDER_7752, + org.rs09.consts.Scenery.ASGARNIAN_ALE_13570 to Items.ASGARNIAN_ALE_7744, + org.rs09.consts.Scenery.GREENMAN_S_ALE_13571 to Items.GREENMANS_ALE_7746, + org.rs09.consts.Scenery.DRAGON_BITTER_13572 to Items.DRAGON_BITTER_7748, + org.rs09.consts.Scenery.CHEF_S_DELIGHT_13573 to Items.CHEFS_DELIGHT_7754, + ) + } + override fun defineListeners() { + onUseWith(SCENERY, Items.BEER_GLASS_7742, *barrelMap.keys.toIntArray()){ player, used, with -> + val drinkName = with.name.lowercase().replace("barrel", "").trim()+"." + if (removeItem(player, used)){ + sendMessage(player, "You fill up your glass with $drinkName") + addItem(player, barrelMap[with.id]!!) + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelPlugin.java b/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelPlugin.java deleted file mode 100644 index eb6b3fe20..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelPlugin.java +++ /dev/null @@ -1,77 +0,0 @@ -package content.global.skill.construction.decoration.kitchen; - - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Items; - -/** - * Handles the Construction beer barrels. - * @author Splinter - */ -@Initializable -public class BeerBarrelPlugin extends UseWithHandler { - - /** - * The object ids - */ - private static final int[] OBJECTS = new int[] { - 13568, 13569, 13570, 13571, 13572, 13573 - }; - - /** - * Constructs a new {@Code BeerBarrelPlugin} {@Code Object} - */ - public BeerBarrelPlugin() { - super(1919); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int id : OBJECTS) { - addHandler(id, OBJECT_TYPE, this); - } - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - Player player = event.getPlayer(); - final Scenery object = (Scenery) event.getUsedWith(); - - if (player.getInventory().remove(new Item(Items.BEER_GLASS_1919))) { - player.animate(Animation.create(3661 + (object.getId() - 13569))); - player.sendMessage("You fill up your glass with " + object.getName().toLowerCase().replace("barrel", "").trim() + "."); - player.getInventory().add(new Item(getReward(object.getId()), 1)); - } - return true; - } - - /** - * Get the beer reward based on the interacted barrel. - * @return the item to give. - */ - public int getReward(int barrelId) { - switch (barrelId) { - case 13568: - return 1917; - case 13569: - return 5763; - case 13570: - return 1905; - case 13571: - return 1909; - case 13572: - return 1911; - case 13573: - return 5755; - } - return 1917; - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderListener.kt b/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderListener.kt new file mode 100644 index 000000000..1bff6bc47 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderListener.kt @@ -0,0 +1,42 @@ +package content.global.skill.construction.decoration.kitchen + +import core.api.openDialogue +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class LarderListener : InteractionListener { + + companion object { + private val wooden_larder_items = listOf( + "Tea Leaves" to Items.TEA_LEAVES_7738, + "Bucket of Milk" to Items.BUCKET_OF_MILK_1927 + ) + private val oak_larder_items = wooden_larder_items + listOf( + "Eggs" to Items.EGG_1944, + "Pot of Flour" to Items.POT_OF_FLOUR_1933 + ) + private val teak_larder_items = oak_larder_items + listOf( + "Potatoes" to Items.POTATO_1942, + "Garlic" to Items.GARLIC_1550, + "Onions" to Items.ONION_1957, + "Cheese" to Items.CHEESE_1985 + ) + + val larders = mapOf( + Scenery.LARDER_13565 to wooden_larder_items, + Scenery.LARDER_13566 to oak_larder_items, + Scenery.LARDER_13567 to teak_larder_items + ) + } + + override fun defineListeners() { + on(larders.keys.toIntArray(), IntType.SCENERY, "Search") { player, node -> + openDialogue(player, LarderDialogue(node.id)) + return@on true + } + } + + class LarderDialogue(shelfId: Int) : AbstractContainer(shelfId, larders, "larder") +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderPlugin.java b/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderPlugin.java deleted file mode 100644 index 9c3289cf2..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderPlugin.java +++ /dev/null @@ -1,149 +0,0 @@ -package content.global.skill.construction.decoration.kitchen; - - -import core.cache.def.impl.SceneryDefinition; -import core.plugin.Initializable; -import core.game.dialogue.DialoguePlugin; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Plugin; -import core.plugin.ClassScanner; -import org.rs09.consts.Items; - -/** - * Handles the interactions for the three Larders. - * @author Splinter - */ -@Initializable -public final class LarderPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ClassScanner.definePlugin(new LarderDialogue()); - SceneryDefinition.forId(13565).getHandlers().put("option:search", this); - SceneryDefinition.forId(13566).getHandlers().put("option:search", this); - SceneryDefinition.forId(13567).getHandlers().put("option:search", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - player.getDialogueInterpreter().open(42048, node.getId()); - return true; - } - - /** - * Dialogue options for the Larders. - * @author Splinter - * @version 1.0 - */ - public final class LarderDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code LarderDialogue} {@code Object}. - */ - public LarderDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code LarderDialogue} {@code Object}. - * - * @param player - * the player. - */ - public LarderDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new LarderDialogue(player); - } - - @Override - public boolean open(Object... args) { - int id = (int) args[0]; - switch (id) { - case 13565: - interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk"); - stage = 1; - break; - case 13566: - interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk", "Eggs", "Pot of Flour"); - stage = 1; - break; - case 13567: - interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk", "Eggs", "Pot of Flour", "More Options"); - stage = 1; - break; - } - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - if (player.getInventory().freeSlots() < 1) { - player.sendMessage("You need at least one free inventory space to take from the larder."); - end(); - return true; - } - switch (stage) { - case 1: - switch (buttonId) { - case 1: - player.getInventory().add(new Item(Items.TEA_LEAVES_7738, 1)); - end(); - break; - case 2: - player.getInventory().add(new Item(Items.BUCKET_OF_MILK_1927, 1)); - end(); - break; - case 3: - player.getInventory().add(new Item(Items.EGG_1944, 1)); - end(); - break; - case 4: - player.getInventory().add(new Item(Items.POT_OF_FLOUR_1933, 1)); - end(); - break; - case 5: - player.getDialogueInterpreter().sendOptions( - "Select an Option", "Potatoes", "Garlic", "Onions", "Cheese"); - stage = 2; - break; - } - break; - case 2: - switch (buttonId) { - case 1: - player.getInventory().add(new Item(Items.POTATO_1942, 1)); - end(); - break; - case 2: - player.getInventory().add(new Item(Items.GARLIC_1550, 1)); - end(); - break; - case 3: - player.getInventory().add(new Item(Items.ONION_1957, 1)); - end(); - break; - case 4: - player.getInventory().add(new Item(Items.CHEESE_1985, 1)); - end(); - break; - } - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 42048 }; - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfListener.kt b/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfListener.kt new file mode 100644 index 000000000..bf39a34dc --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfListener.kt @@ -0,0 +1,97 @@ +package content.global.skill.construction.decoration.kitchen + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import org.rs09.consts.Scenery + + +class ShelfListener : InteractionListener { + companion object { + // Source for text https://www.youtube.com/watch?v=SNuqelEft3Y + + private val woodshelf_1_items = listOf( + "Kettle" to Items.KETTLE_7688, + "Teapot" to Items.TEAPOT_7702, + "Cup" to Items.EMPTY_CUP_7728 + ) + + private val woodshelf_2_items = woodshelf_1_items + listOf( + "Beer glass" to Items.BEER_GLASS_7742 + ) + + private val woodshelf_3_items = woodshelf_2_items.map { (name, itemId) -> + when (name) { + "Cup" -> { + "Porcelain cup" to Items.PORCELAIN_CUP_7732 + } + + "Teapot" -> { + "Teapot" to Items.TEAPOT_7714 + } + + else -> { + name to itemId + } + } + } + listOf("Cake tin" to Items.CAKE_TIN_1887) + + private val oakshelf_1_items = woodshelf_2_items + listOf("Cake tin" to Items.CAKE_TIN_1887) + listOf("Bowl" to Items.BOWL_1923) + + private val oakshelf_2_items = oakshelf_1_items.map { (name, itemId) -> + when (name) { + "Cup" -> { + "Porcelain cup" to Items.PORCELAIN_CUP_7732 + } + + "Teapot" -> { + "Teapot" to Items.TEAPOT_7714 + } + + else -> { + name to itemId + } + } + } + listOf("Pie dish" to Items.PIE_DISH_2313) + + private val teakshelf_1_items = oakshelf_2_items + listOf( + "Pot" to Items.EMPTY_POT_1931 + ) + + private val teakshelf_2_items = teakshelf_1_items.map { (name, itemId) -> + when (name) { + "Porcelain cup" -> { + "Porcelain cup" to Items.PORCELAIN_CUP_7735 + } + + "Teapot" -> { + "Teapot" to Items.TEAPOT_7726 + } + + else -> { + name to itemId + } + } + } + listOf("Chef's Hat" to Items.CHEFS_HAT_1949) + + val shelves = mapOf( + Scenery.SHELVES_13545 to woodshelf_1_items, + Scenery.SHELVES_13546 to woodshelf_2_items, + Scenery.SHELVES_13547 to woodshelf_3_items, + Scenery.SHELVES_13548 to oakshelf_1_items, + Scenery.SHELVES_13549 to oakshelf_2_items, + Scenery.SHELVES_13550 to teakshelf_1_items, + Scenery.SHELVES_13551 to teakshelf_2_items, + ) + } + + override fun defineListeners() { + on(shelves.keys.toIntArray(), IntType.SCENERY, "Search") { player, node -> + openDialogue(player, ShelfDialogue(node.id)) + return@on true + } + } + + class ShelfDialogue(shelfId: Int) : AbstractContainer(shelfId, shelves, "shelf") +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfPlugin.java b/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfPlugin.java deleted file mode 100644 index 9fed7ebce..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfPlugin.java +++ /dev/null @@ -1,239 +0,0 @@ -package content.global.skill.construction.decoration.kitchen; - - -import core.cache.def.impl.SceneryDefinition; -import core.game.dialogue.DialoguePlugin; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.plugin.ClassScanner; -import org.rs09.consts.Items; - -/** - * Handles the shelves in the kitchen room. - * @author Splinter - */ -@Initializable -public final class ShelfPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ClassScanner.definePlugin(new ShelfDialogue()); - for (int i = 13545; i < 13552; i++) { - SceneryDefinition.forId(i).getHandlers().put("option:search", this); - } - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - player.getDialogueInterpreter().open(778341, node.getId()); - return true; - } - - /** - * Dialogue options for the shelves, what a mess! - * @author Splinter - * @version 1.0 - */ - public final class ShelfDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code ShelfDialogue} {@code Object}. - */ - public ShelfDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code ShelfDialogue} {@code Object}. - * @param player the player. - */ - public ShelfDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new ShelfDialogue(player); - } - - @Override - public boolean open(Object... args) { - int id = (int) args[0]; - switch (id) { - case 13545:// wood 1 - interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup"); - stage = 1; - break; - case 13546:// wood 2 - interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass"); - stage = 1; - break; - case 13547:// wood 3 - interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass", "Cake tin"); - stage = 1; - break; - case 13548:// oak 1 - interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass", "Bowl"); - stage = 2; - break; - case 13549:// oak 2 - interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Porcelain cup", "Empty beer glass", "More Options"); - stage = 3; - break; - case 13550:// teak 1 - case 13551: - interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Porcelain cup", "Empty beer glass", "More Options"); - stage = 5; - break; - } - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - if (player.getInventory().freeSlots() < 1) { - player.sendMessage("You need at least one free inventory space to take from the shelves."); - end(); - return true; - } - switch (stage) { - case 1:// all wood shelves - switch (buttonId) { - case 1: - end(); - player.getInventory().add(new Item(Items.KETTLE_7688, 1)); - break; - case 2: - end(); - player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); - break; - case 3: - end(); - player.getInventory().add(new Item(Items.EMPTY_CUP_7728, 1)); - break; - case 4: - end(); - player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); - break; - case 5: - end(); - player.getInventory().add(new Item(Items.CAKE_TIN_1887, 1)); - break; - } - break; - case 2:// Oak shelf #1 - switch (buttonId) { - case 1: - end(); - player.getInventory().add(new Item(Items.KETTLE_7688, 1)); - break; - case 2: - end(); - player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); - break; - case 3: - end(); - player.getInventory().add(new Item(Items.EMPTY_CUP_7728, 1)); - break; - case 4: - end(); - player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); - break; - case 5: - end(); - player.getInventory().add(new Item(Items.BOWL_1923, 1)); - break; - } - break; - case 3:// Oak shelves #2 only - switch (buttonId) { - case 1: - end(); - player.getInventory().add(new Item(Items.KETTLE_7688, 1)); - break; - case 2: - end(); - player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); - break; - case 3: - end(); - player.getInventory().add(new Item(Items.PORCELAIN_CUP_4244, 1)); - break; - case 4: - end(); - player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); - break; - case 5: - interpreter.sendOptions("Select an Option", "Bowl", "Cake tin"); - stage = 4; - break; - } - break; - case 4:// Oak shelves #2 only - switch (buttonId) { - case 1: - end(); - player.getInventory().add(new Item(Items.BOWL_1923, 1)); - break; - case 2: - end(); - player.getInventory().add(new Item(Items.CAKE_TIN_1887, 1)); - break; - } - case 5:// teak shelves - switch (buttonId) { - case 1: - end(); - player.getInventory().add(new Item(Items.KETTLE_7688, 1)); - break; - case 2: - end(); - player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); - break; - case 3: - end(); - player.getInventory().add(new Item(Items.PORCELAIN_CUP_7735, 1)); - break; - case 4: - end(); - player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); - break; - case 5: - interpreter.sendOptions("Select an Option", "Bowl", "Pie dish", "Empty pot"); - stage = 6; - break; - } - break; - case 6:// teak shelves - switch (buttonId) { - case 1: - end(); - player.getInventory().add(new Item(Items.BOWL_1923, 1)); - break; - case 2: - end(); - player.getInventory().add(new Item(Items.PIE_DISH_2313, 1)); - break; - case 3: - end(); - player.getInventory().add(new Item(Items.EMPTY_POT_1931, 1)); - break; - } - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 778341 }; - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/StoveInteraction.kt b/Server/src/main/content/global/skill/construction/decoration/kitchen/StoveInteraction.kt new file mode 100644 index 000000000..74b0c35f4 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/StoveInteraction.kt @@ -0,0 +1,88 @@ +package content.global.skill.construction.decoration.kitchen + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import org.rs09.consts.Scenery as SceneryConst +import org.rs09.consts.Items +import core.game.node.scenery.Scenery +import core.tools.secondsToTicks + + +class StoveInteraction : InteractionListener { + + // Imagine if these indexes incremented logically... + companion object{ + val valid_stoves = intArrayOf( + SceneryConst.FIREPIT_WITH_HOOK_13529, + SceneryConst.FIREPIT_WITH_POT_13531, + SceneryConst.SMALL_OVEN_13533, + SceneryConst.LARGE_OVEN_13536, + SceneryConst.STEEL_RANGE_13539, + SceneryConst.FANCY_RANGE_13542 + ) + val in_progress_stoves = intArrayOf( + SceneryConst.FIREPIT_WITH_HOOK_13530, + SceneryConst.FIREPIT_WITH_POT_13532, + SceneryConst.SMALL_OVEN_13534, + SceneryConst.LARGE_OVEN_13537, + SceneryConst.STEEL_RANGE_13541, + SceneryConst.FANCY_RANGE_13544 + + ) + val stoves_with_kettle = intArrayOf( + SceneryConst.FIREPIT_WITH_HOOK_13530, + SceneryConst.FIREPIT_WITH_POT_13532, + SceneryConst.SMALL_OVEN_13535, + SceneryConst.LARGE_OVEN_13538, + SceneryConst.STEEL_RANGE_13540, + SceneryConst.FANCY_RANGE_13543 + + ) + const val kettleBoiled = "kettle_boiled" + } + override fun defineListeners() { + onUseWith(SCENERY, Items.FULL_KETTLE_7690, *valid_stoves){ player, used, with -> + val idx = valid_stoves.indexOf(with.id) + if (removeItem(player, used)){ + replaceScenery(with as Scenery, in_progress_stoves[idx], -1) + sendMessage(player, "You place the kettle over the fire.") + setAttribute(player, kettleBoiled, 1) + queueScript(player, secondsToTicks(10), QueueStrength.SOFT){ _ -> + sendMessage(player, "The kettle boils.") + // Of course they changed how these items work so we need 2 different cases + setAttribute(player, kettleBoiled, 2) + if (with.id in intArrayOf(SceneryConst.FIREPIT_WITH_HOOK_13529, SceneryConst.FIREPIT_WITH_POT_13531)) + return@queueScript stopExecuting(player) + else{ + getScenery(with.location)?.let { replaceScenery(it, stoves_with_kettle[idx], -1) } + return@queueScript stopExecuting(player) + } + } + } + return@onUseWith true + } + + + on(stoves_with_kettle, SCENERY, "take-kettle"){ player, node -> + if (getAttribute(player, kettleBoiled, 0) == 0){ + sendMessage(player, "This is not your kettle.") + return@on false + } + else if (getAttribute(player, kettleBoiled, 0) == 1){ + sendMessage(player, "The kettle has not boiled yet.") + return@on false + } + if(addItem(player, Items.HOT_KETTLE_7691)){ + replaceScenery(node as Scenery, valid_stoves[stoves_with_kettle.indexOf(node.id)], -1) + setAttribute(player, kettleBoiled, 0) + return@on true + } + else { + sendMessage(player, "You do not have space to do that.") + return@on false + } + } + } + +} diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/POHStorageProxyContainer.java b/Server/src/main/content/global/skill/construction/decoration/pohstorage/POHStorageProxyContainer.java new file mode 100644 index 000000000..07c934d4a --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/POHStorageProxyContainer.java @@ -0,0 +1,28 @@ +package content.global.skill.construction.decoration.pohstorage; + +import core.game.container.Container; +import core.game.container.ContainerType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * A proxy Container used to indicate an item was found in POH storage. + * This is not a real container, just a dummy so that hasAnItem() can be easily extended to check POH storage + */ +public class POHStorageProxyContainer extends Container { + + public POHStorageProxyContainer(Player player) { + super(1, ContainerType.DEFAULT); + } + + // Prevents external code from trying to fetch items from this container because it doesn't actually store anything + @Override + public Item get(int slot) { + return null; + } + + @Override + public String toString() { + return "POHStorageProxyContainer"; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/Storable.kt b/Server/src/main/content/global/skill/construction/decoration/pohstorage/Storable.kt new file mode 100644 index 000000000..d4b0b71c5 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/Storable.kt @@ -0,0 +1,444 @@ +package content.global.skill.construction.decoration.pohstorage + +import content.data.Quests +import core.api.getItemName +import core.api.isQuestComplete +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import org.rs09.consts.Items + +/** + * Represents a database of all the storable items in the POH Costume Room and Bookcase across all box types. + */ + +/* + * The below function should be copied into each book's listener to store the book in the POH. It is part of ContentAPI. + * import core.api.* + * storeBookInHouse(player, node) + * + * Example: src/main/content/region/kandarin/quest/observatoryquest/AstronomyBook.kt + * + * todo: Periodically, this storables list should be audited as new books are added to the game. Make sure the new books are going in the bookcase. + */ + +// todo: Right now there is no logic to check: +// 1. for complete or incomplete sets +// 2. for single instances of an item +// This allows things like storing multiple god capes, a Rune (g) set with both platelegs and plateskirt, +// an elegant shirt/pants and blouse/skirt at once, and all 3 sets of castle wars armour at once. I don't +// think any of this is game-breaking, so have chosen to omit this logic for now. + +enum class Storable( + val displayId: Int, // display ID is the item that is shown in the UI + val takeIds: IntArray, // take IDs is the item(s) that are taken from the player's inventory + val type: StorableFamily, // the family (mapped to container) that the items get stored in + val setName: String = getItemName(displayId), // the set/book name for each item. defaults to display item + + // special properties just for the books + val bitIndex: Int = -1, // This index is used to save the big list of books the player has read, instead of having an individual attribute per book. + // todo make the quest requirement check part of a separate object against this list of books. only a subset of books are applicable. + val questReq: Quests? = null // Once read, books should only show up in the POH after completing their attached quest. https://runescape.wiki/w/Bookcase?oldid=1650176 +) { + // Books - https://runescape.wiki/w/List_of_texts_and_tomes?oldid=848552 + AbyssalBook(Items.ABYSSAL_BOOK_5520, intArrayOf(Items.ABYSSAL_BOOK_5520), type = StorableFamily.BOOKCASE, "Abyssal Research Notes", bitIndex = 0), // abyss miniquest - IMPLEMENTED + AncientBook(Items.ANCIENT_BOOK_7633, intArrayOf(Items.ANCIENT_BOOK_7633), type = StorableFamily.BOOKCASE, "The Sleeping Seven", bitIndex = 1, Quests.HORROR_FROM_THE_DEEP), // horror from the deep quest + AncientDiary(Items.DIARY_3846, intArrayOf(Items.DIARY_3846), type = StorableFamily.BOOKCASE, "Ancient Diary", bitIndex = 2, Quests.HORROR_FROM_THE_DEEP), // horror from the deep quest + ArenaBook(Items.ARENA_BOOK_6891, intArrayOf(Items.ARENA_BOOK_6891), type = StorableFamily.BOOKCASE, "Magic Training Arena Lore Book", bitIndex = 3), // mage training arena minigame + AstronomyBook(Items.ASTRONOMY_BOOK_600, intArrayOf(Items.ASTRONOMY_BOOK_600), type = StorableFamily.BOOKCASE, "Astronomy Book", bitIndex = 4, Quests.OBSERVATORY_QUEST), // observatory quest - IMPLEMENTED + BatteredBook(Items.BATTERED_BOOK_2886, intArrayOf(Items.BATTERED_BOOK_2886), type = StorableFamily.BOOKCASE, "Book of the Elemental Shield", bitIndex = 5, Quests.ELEMENTAL_WORKSHOP_I), // elemental workshop I quest - IMPLEMENTED + BatteredTome(Items.BATTERED_TOME_7634, intArrayOf(Items.BATTERED_TOME_7634), type = StorableFamily.BOOKCASE, "Histories of Hallowland", bitIndex = 6, Quests.IN_AID_OF_THE_MYREQUE), // in aid of myreque quest + BeatenBook(Items.BEATEN_BOOK_9717, intArrayOf(Items.BEATEN_BOOK_9717), type = StorableFamily.BOOKCASE, "Book of the Elemental Helm", bitIndex = 7, Quests.ELEMENTAL_WORKSHOP_II), // elemental workshop II quest + BigBookOfBangs(Items.BIG_BOOK_OF_BANGS_3230, intArrayOf(Items.BIG_BOOK_OF_BANGS_3230), type = StorableFamily.BOOKCASE, "Big Book of Bangs", bitIndex = 8, Quests.REGICIDE), // regicide quest + BindingBook(Items.BINDING_BOOK_730, intArrayOf(Items.BINDING_BOOK_730), type = StorableFamily.BOOKCASE, "Book of Binding", bitIndex = 9, Quests.LEGENDS_QUEST), // legends quest - IMPLEMENTED + BirdBook(Items.BIRD_BOOK_10173, intArrayOf(Items.BIRD_BOOK_10173), type = StorableFamily.BOOKCASE, "William Oddity's Guide to the Avian", bitIndex = 10, Quests.EAGLES_PEAK), // eagles peak quest + BookOnBaxtorian(Items.BOOK_ON_BAXTORIAN_292, intArrayOf(Items.BOOK_ON_BAXTORIAN_292), type = StorableFamily.BOOKCASE, "Book on Baxtorian", bitIndex = 11, Quests.WATERFALL_QUEST), // waterfall quest - IMPLEMENTED + BookOnChemicals(Items.BOOK_ON_CHEMICALS_711, intArrayOf(Items.BOOK_ON_CHEMICALS_711), type = StorableFamily.BOOKCASE, "Volatile chemicals - Experimental Test Notes", bitIndex = 12, Quests.THE_DIG_SITE), // dig site quest - IMPLEMENTED + BookOPiracy(Items.BOOK_O_PIRACY_7144, intArrayOf(Items.BOOK_O_PIRACY_7144), type = StorableFamily.BOOKCASE, "Book o' Piracy", bitIndex = 13, Quests.CABIN_FEVER), // cabin fever quest + BrewinGuide(Items.BREWIN_GUIDE_8989, intArrayOf(Items.BREWIN_GUIDE_8989), type = StorableFamily.BOOKCASE, "Brewin' Guide", bitIndex = 14), // trouble brewing quest/minigame + BurntDiary(Items.BURNT_DIARY_7965, intArrayOf(Items.BURNT_DIARY_7965), type = StorableFamily.BOOKCASE, "Burnt Diary", bitIndex = 15, Quests.ROYAL_TROUBLE), // royal trouble quest + CadarnLineage(Items.CADARN_LINEAGE_4209, intArrayOf(Items.CADARN_LINEAGE_4209), type = StorableFamily.BOOKCASE, "Cadarn Lineage", bitIndex = 16, Quests.ROVING_ELVES), // roving elves quest + ClockworkBook(Items.CLOCKWORK_BOOK_10594, intArrayOf(Items.CLOCKWORK_BOOK_10594), type = StorableFamily.BOOKCASE, "Clockwork Toys - A Clockwork Mechanism, Chapter 1.0", bitIndex = 17, Quests.COLD_WAR), // cold war quest + CocktailGuide(Items.COCKTAIL_GUIDE_2023, intArrayOf(Items.COCKTAIL_GUIDE_2023), type = StorableFamily.BOOKCASE, "The Blurberry Cocktail Guide", bitIndex = 18), // gnome restaurant minigame + ConstructionGuide(Items.CONSTRUCTION_GUIDE_8463, intArrayOf(Items.CONSTRUCTION_GUIDE_8463), type = StorableFamily.BOOKCASE, "Guide to Construction", bitIndex = 19), // after you buy a house from estate agent - IMPLEMENTED ish + CrumblingTome(Items.CRUMBLING_TOME_4707, intArrayOf(Items.CRUMBLING_TOME_4707), type = StorableFamily.BOOKCASE, "Legend of the Brothers", bitIndex = 20), // barrows minigame + CrystalSinging(Items.CRYSTAL_OF_SEREN_4313, intArrayOf(Items.CRYSTAL_OF_SEREN_4313), type = StorableFamily.BOOKCASE, "Crystal singing for beginners", bitIndex = 21, Quests.ROVING_ELVES), // roving elves quest + DagonhaiHistory(Items.DAGONHAI_HISTORY_11001, intArrayOf(Items.DAGONHAI_HISTORY_11001), type = StorableFamily.BOOKCASE, "History of the Dagon'hai", bitIndex = 22), // found in varrock castle library + DemonicTome(Items.DEMONIC_TOME_6749, intArrayOf(Items.DEMONIC_TOME_6749), type = StorableFamily.BOOKCASE, "The Confessions of Ellemar", bitIndex = 23, Quests.SHADOW_OF_THE_STORM), // shadow of the storm quest + DiaryHerbi(Items.DIARY_3395, intArrayOf(Items.DIARY_3395), type = StorableFamily.BOOKCASE, "Diary of Herbi Flax", bitIndex = 24, Quests.SHADES_OF_MORTTON), // shades of mort'ton quest + DrozalsJournal(Items.JOURNAL_6755, intArrayOf(Items.JOURNAL_6755), type = StorableFamily.BOOKCASE, "Drozal's Journal", bitIndex = 25, Quests.MAKING_HISTORY), // making history quest + DwarvenLore(Items.DWARVEN_LORE_4568, intArrayOf(Items.DWARVEN_LORE_4568), type = StorableFamily.BOOKCASE, "The Arzinian Being of Bordanzan", bitIndex = 26, Quests.BETWEEN_A_ROCK), // between a rock quest + EasternDiscovery(Items.EASTERN_DISCOVERY_6075, intArrayOf(Items.EASTERN_DISCOVERY_6075), type = StorableFamily.BOOKCASE, "The Exploration of the Eastern Realm", bitIndex = 27, Quests.MOURNINGS_END_PART_I), // mourning's end I quest + EasternSettlement(Items.EASTERN_SETTLEMENT_6077, intArrayOf(Items.EASTERN_SETTLEMENT_6077), type = StorableFamily.BOOKCASE, "The Settlement of the East", bitIndex = 28, Quests.MOURNINGS_END_PART_I), // mourning's end I quest + EdernsJournal(Items.EDERNS_JOURNAL_6649, intArrayOf(Items.EDERNS_JOURNAL_6649), type = StorableFamily.BOOKCASE, "Journal of Nissyen Edern", bitIndex = 29, Quests.MOURNINGS_END_PART_II), // mourning's end II quest + ExplorersNotes(Items.EXPLORERS_NOTES_11677, intArrayOf(Items.EXPLORERS_NOTES_11677), type = StorableFamily.BOOKCASE, "Beyond Trollheim", bitIndex = 30), // found in keldagrim library + EmbalmingManual(Items.EMBALMING_MANUAL_4686, intArrayOf(Items.EMBALMING_MANUAL_4686), type = StorableFamily.BOOKCASE, "The Little Book of Embalming", bitIndex = 31, Quests.ICTHLARINS_LITTLE_HELPER), // icthlarin's little helper quest + FarmingManual(Items.FARMING_MANUAL_9903, intArrayOf(Items.FARMING_MANUAL_9903), type = StorableFamily.BOOKCASE, "Farmer Gricoller's Farming Manual", bitIndex = 32, Quests.MY_ARMS_BIG_ADVENTURE), // my arm's big adventure quest + FeatheredJournal(Items.FEATHERED_JOURNAL_10179, intArrayOf(Items.FEATHERED_JOURNAL_10179), type = StorableFamily.BOOKCASE, "Feathered Journal of Arthur Artimus", bitIndex = 33, Quests.EAGLES_PEAK), // eagle's peak + GameBook(Items.GAME_BOOK_7681, intArrayOf(Items.GAME_BOOK_7681), type = StorableFamily.BOOKCASE, "Party Pete's Bumper Book of Games", bitIndex = 34), // poh game room. I think the bookshelf is the only source for this + GhrimsBook(Items.GHRIMS_BOOK_3901, intArrayOf(Items.GHRIMS_BOOK_3901), type = StorableFamily.BOOKCASE, "Managing Thine Kingdom for Noobes", bitIndex = 35, Quests.THRONE_OF_MISCELLANIA), // kingdom of misc quest + GiannesCookBook(Items.GIANNES_COOK_BOOK_2167, intArrayOf(Items.GIANNES_COOK_BOOK_2167), type = StorableFamily.BOOKCASE, "Gianne's Cook Book", bitIndex = 36), // gnome retaurant minigame - IMPLEMENTED + GlassblowingBook(Items.GLASSBLOWING_BOOK_11656, intArrayOf(Items.GLASSBLOWING_BOOK_11656), type = StorableFamily.BOOKCASE, "Glassblowing Book", bitIndex = 37), // found at the observatory + GoblinBook(Items.GOBLIN_BOOK_10999, intArrayOf(Items.GOBLIN_BOOK_10999), type = StorableFamily.BOOKCASE, "The Book of the Big High War God", bitIndex = 38), // dropped by goblins - IMPLEMENTED + GoblinSymbolBook(Items.GOBLIN_SYMBOL_BOOK_5009, intArrayOf(Items.GOBLIN_SYMBOL_BOOK_5009), type = StorableFamily.BOOKCASE, "A History of the Goblin Race", bitIndex = 39, Quests.THE_LOST_TRIBE), // lost tribe quest - IMPLEMENTED + ElvenBook(Items.THE_GREAT_DIVIDE_6079, intArrayOf(Items.THE_GREAT_DIVIDE_6079), type = StorableFamily.BOOKCASE, "The Great Divide", bitIndex = 40, Quests.MOURNINGS_END_PART_I), // mourning's end I quest + GuideBook(Items.GUIDE_BOOK_1856, intArrayOf(Items.GUIDE_BOOK_1856), type = StorableFamily.BOOKCASE, "Tourist Guide to Ardougne", bitIndex = 41), // found by estate agent in ardy - IMPLEMENTED + AHandwrittenBook(Items.A_HANDWRITTEN_BOOK_9627, intArrayOf(Items.A_HANDWRITTEN_BOOK_9627), type = StorableFamily.BOOKCASE, "Crystal Singing for Beginners (trans. Oaknock) (Transcribed from the original Elvish by Oaknock the Engineer)", bitIndex = 42, Quests.THE_EYES_OF_GLOUPHRIE), // eyes of glouphrie quest + HermansBook(Items.HERMANS_BOOK_7951, intArrayOf(Items.HERMANS_BOOK_7951), type = StorableFamily.BOOKCASE, "Dionysius: A Legend in His Own Lifetime", bitIndex = 43, Quests.SWAN_SONG), // swan song quest + HistoryOfIban(Items.HISTORY_OF_IBAN_1494, intArrayOf(Items.HISTORY_OF_IBAN_1494), type = StorableFamily.BOOKCASE, "The Tale of Iban", bitIndex = 44, Quests.UNDERGROUND_PASS), // underground pass quest + InstructionManual(Items.INSTRUCTION_MANUAL_5, intArrayOf(Items.INSTRUCTION_MANUAL_5), type = StorableFamily.BOOKCASE, "Dwarf Multicannon Manual", bitIndex = 45, Quests.DWARF_CANNON), // dwarf cannon quest - IMPLEMENTED + JossiksJournal(Items.JOURNAL_3845, intArrayOf(Items.JOURNAL_3845), type = StorableFamily.BOOKCASE, "Jossik's Diary", bitIndex = 46, Quests.HORROR_FROM_THE_DEEP), // horror from the deep quest + LeatherBook(Items.LEATHER_BOOK_7635, intArrayOf(Items.LEATHER_BOOK_7635), type = StorableFamily.BOOKCASE, "Modern Day Morytania", bitIndex = 47, Quests.IN_AID_OF_THE_MYREQUE), // in aid of the myreque quest + Manual(Items.MANUAL_3847, intArrayOf(Items.MANUAL_3847), type = StorableFamily.BOOKCASE, "Lighthouse Manual", bitIndex = 48, Quests.HORROR_FROM_THE_DEEP), // horror from the deep quest + MoonclanManual(Items.MOONCLAN_MANUAL_9078, intArrayOf(Items.MOONCLAN_MANUAL_9078), type = StorableFamily.BOOKCASE, "Basics of Magic", bitIndex = 49, Quests.LUNAR_DIPLOMACY), // lunar diplomacy quest + MyNotes(Items.MY_NOTES_11339, intArrayOf(Items.MY_NOTES_11339), type = StorableFamily.BOOKCASE, "'My notes'", bitIndex = 50), // during barbarian training + OldJournal(Items.OLD_JOURNAL_1493, intArrayOf(Items.OLD_JOURNAL_1493), type = StorableFamily.BOOKCASE, "The Journal of Randas", bitIndex = 51, Quests.UNDERGROUND_PASS), // underground pass quest + OldTome(Items.OLD_TOME_13593, intArrayOf(Items.OLD_TOME_13593), type = StorableFamily.BOOKCASE, "Old Tome", bitIndex = 52, Quests.MEETING_HISTORY), // meeting history quest + PrayerBook(Items.PRAYER_BOOK_10890, intArrayOf(Items.PRAYER_BOOK_10890), type = StorableFamily.BOOKCASE, "Prayer of Deliverance from Poisons", bitIndex = 53, Quests.THE_GREAT_BRAIN_ROBBERY), // the great brain robbery quest + PieRecipeBook(Items.PIE_RECIPE_BOOK_7162, intArrayOf(Items.PIE_RECIPE_BOOK_7162), type = StorableFamily.BOOKCASE, "Pie Recipe Book", bitIndex = 54), // from romily weaklax + PrifddinasHistory(Items.PRIFDDINAS_HISTORY_6073, intArrayOf(Items.PRIFDDINAS_HISTORY_6073), type = StorableFamily.BOOKCASE, "The Creation of Prifddinas", bitIndex = 55), // found in lletya bookshelves + QueenHelpBook(Items.QUEEN_HELP_BOOK_10562, intArrayOf(Items.QUEEN_HELP_BOOK_10562), type = StorableFamily.BOOKCASE, "Queen Help Book", bitIndex = 56), // barbarian assault minigame + RatPitsManual(Items.BOOK_6767, intArrayOf(Items.BOOK_6767), type = StorableFamily.BOOKCASE, "The RatPits Manual", bitIndex = 57, Quests.RATCATCHERS), // rat catchers quest + ScabariteNotes(Items.SCABARITE_NOTES_11975, intArrayOf(Items.SCABARITE_NOTES_11975), type = StorableFamily.BOOKCASE, "My Notes, Archaeological exploration and the cult of Scabaras", bitIndex = 58, Quests.DEALING_WITH_SCABARAS), // dealing with scabaras quest + SecurityBook(Items.SECURITY_BOOK_9003, intArrayOf(Items.SECURITY_BOOK_9003), type = StorableFamily.BOOKCASE, "" + GameWorld.settings!!.name + " Account Security", bitIndex = 59), // from stronghold of security - IMPLEMENTED + ShamansTome(Items.SHAMANS_TOME_729, intArrayOf(Items.SHAMANS_TOME_729), type = StorableFamily.BOOKCASE, "Shaman's Tome", bitIndex = 60, Quests.LEGENDS_QUEST), // legends quest - IMPLEMENTED + TheShieldOfArravBook(Items.BOOK_757, intArrayOf(Items.BOOK_757), type = StorableFamily.BOOKCASE, "The Shield of Arrav", bitIndex = 61, Quests.SHIELD_OF_ARRAV), // shield of arrav quest - IMPLEMENTED + SinkethsDiary(Items.SINKETHS_DIARY_11002, intArrayOf(Items.SINKETHS_DIARY_11002), type = StorableFamily.BOOKCASE, "Sin'keth's Diary", bitIndex = 62, Quests.WHAT_LIES_BELOW), // what lies below quest - IMPLEMENTED + StrongholdNotes(Items.STRONGHOLD_NOTES_9004, intArrayOf(Items.STRONGHOLD_NOTES_9004), type = StorableFamily.BOOKCASE, "Stronghold of Security - Notes", bitIndex = 63), // from stronghold of security - IMPLEMENTED + TarnsDiary(Items.TARNS_DIARY_10587, intArrayOf(Items.TARNS_DIARY_10587), type = StorableFamily.BOOKCASE, "The Diary of Tarn Razorlor", bitIndex = 64), // lair of tarn miniquest + Translation(Items.TRANSLATION_4655, intArrayOf(Items.TRANSLATION_4655), type = StorableFamily.BOOKCASE, "Translation Primer (Four Diamonds Translation)", bitIndex = 65, Quests.DESERT_TREASURE), // desert treasure quest - IMPLEMENTED + TranslationBook(Items.TRANSLATION_BOOK_784, intArrayOf(Items.TRANSLATION_BOOK_784), type = StorableFamily.BOOKCASE, "Gnome-English Translation Dictionary", bitIndex = 66, Quests.THE_EYES_OF_GLOUPHRIE), // eyes of glouphrie quest - IMPLEMENTED + TzhaarTouristGuide(Items.TZHAAR_TOURIST_GUIDE_13244, intArrayOf(Items.TZHAAR_TOURIST_GUIDE_13244), type = StorableFamily.BOOKCASE, "Tzhaar Tourist Guide", bitIndex = 67, Quests.TOKTZ_KET_DILL), // toktz-ket-dill quest + VarmensNotes(Items.VARMENS_NOTES_4616, intArrayOf(Items.VARMENS_NOTES_4616), type = StorableFamily.BOOKCASE, "Notes from Varmen's Expedition to Uzer", bitIndex = 68, Quests.THE_GOLEM), // the golem quest - IMPLEMENTED + WitchesDiary(Items.DIARY_2408, intArrayOf(Items.DIARY_2408), type = StorableFamily.BOOKCASE, "Witch's Diary", bitIndex = 69, Quests.WITCHS_HOUSE), // witch's house quest - IMPLEMENTED + YewnocksNotes(Items.YEWNOCKS_NOTES_11750, intArrayOf(Items.YEWNOCKS_NOTES_11750), type = StorableFamily.BOOKCASE, "Yewnock's Notes on Crystals", bitIndex = 70, Quests.THE_PATH_OF_GLOUPHRIE), // path of glouphrie quest + + // Capes - https://runescape.wiki/w/Cape_rack?oldid=848849 + LegendsCape(Items.CAPE_OF_LEGENDS_1052, intArrayOf(Items.CAPE_OF_LEGENDS_1052), type = StorableFamily.CAPE_RACK, "Legends cape"), + ObsidianCape(Items.OBSIDIAN_CAPE_6568, intArrayOf(Items.OBSIDIAN_CAPE_6568), type = StorableFamily.CAPE_RACK), + FireCape(Items.FIRE_CAPE_6570, intArrayOf(Items.FIRE_CAPE_6570), type = StorableFamily.CAPE_RACK), + TeamCape(Items.TEAM_1_CAPE_10638, (4315..4413 step 2).toList().toIntArray(), type = StorableFamily.CAPE_RACK, "Wilderness cape"), + GodCape(Items.GUTHIX_CAPE_2413, intArrayOf(Items.GUTHIX_CAPE_2413, Items.SARADOMIN_CAPE_2412, Items.ZAMORAK_CAPE_2414), type = StorableFamily.CAPE_RACK, "God cape"), + AttackCape(Items.ATTACK_CAPE_10639, intArrayOf(Items.ATTACK_CAPE_9747, Items.ATTACK_HOOD_9749, Items.ATTACK_CAPET_9748), type = StorableFamily.CAPE_RACK_SKILL), + DefenceCape(Items.DEFENCE_CAPE_10641, intArrayOf(Items.DEFENCE_CAPE_9753, Items.DEFENCE_CAPET_9754, Items.DEFENCE_HOOD_9755), type = StorableFamily.CAPE_RACK_SKILL), + StrengthCape(Items.STRENGTH_CAPE_10640, intArrayOf(Items.STRENGTH_CAPE_9750, Items.STRENGTH_CAPET_9751, Items.STRENGTH_HOOD_9752), type = StorableFamily.CAPE_RACK_SKILL), + HitpointsCape(Items.HITPOINTS_CAPE_10647, intArrayOf(Items.HITPOINTS_CAPE_9768, Items.HITPOINTS_CAPET_9769, Items.HITPOINTS_HOOD_9770), type = StorableFamily.CAPE_RACK_SKILL), + AgilityCape(Items.AGILITY_CAPE_10648, intArrayOf(Items.AGILITY_CAPE_9771, Items.AGILITY_CAPET_9772, Items.AGILITY_HOOD_9773), type = StorableFamily.CAPE_RACK_SKILL), + CookingCape(Items.COOKING_CAPE_10658, intArrayOf(Items.COOKING_CAPE_9801, Items.COOKING_CAPET_9802, Items.COOKING_HOOD_9803), type = StorableFamily.CAPE_RACK_SKILL), + ConstructionCape(Items.CONSTRUCT_CAPE_10654, intArrayOf(Items.CONSTRUCT_CAPE_9789, Items.CONSTRUCT_CAPET_9790, Items.CONSTRUCT_HOOD_9791), type = StorableFamily.CAPE_RACK_SKILL, "Construction cape"), + CraftingCape(Items.CRAFTING_CAPE_10651, intArrayOf(Items.CRAFTING_CAPE_9780, Items.CRAFTING_CAPET_9781, Items.CRAFTING_HOOD_9782), type = StorableFamily.CAPE_RACK_SKILL), + FarmingCape(Items.FARMING_CAPE_10661, intArrayOf(Items.FARMING_CAPE_9810, Items.FARMING_CAPET_9811, Items.FARMING_HOOD_9812), type = StorableFamily.CAPE_RACK_SKILL), + FiremakingCape(Items.FIREMAKING_CAPE_10659, intArrayOf(Items.FIREMAKING_CAPE_9804, Items.FIREMAKING_CAPET_9805, Items.FIREMAKING_HOOD_9806), type = StorableFamily.CAPE_RACK_SKILL), + FishingCape(Items.FISHING_CAPE_10657, intArrayOf(Items.FISHING_CAPE_9798, Items.FISHING_CAPET_9799, Items.FISHING_HOOD_9800), type = StorableFamily.CAPE_RACK_SKILL), + FletchingCape(Items.FLETCHING_CAPE_10652, intArrayOf(Items.FLETCHING_CAPE_9783, Items.FLETCHING_CAPET_9784, Items.FLETCHING_HOOD_9785), type = StorableFamily.CAPE_RACK_SKILL), + HerbloreCape(Items.HERBLORE_CAPE_10649, intArrayOf(Items.HERBLORE_CAPE_9774, Items.HERBLORE_CAPET_9775, Items.HERBLORE_HOOD_9776), type = StorableFamily.CAPE_RACK_SKILL), + MagicCape(Items.MAGIC_CAPE_10644, intArrayOf(Items.MAGIC_CAPE_9762, Items.MAGIC_CAPET_9763, Items.MAGIC_HOOD_9764), type = StorableFamily.CAPE_RACK_SKILL), + MiningCape(Items.MINING_CAPE_10655, intArrayOf(Items.MINING_CAPE_9792, Items.MINING_CAPET_9793, Items.MINING_HOOD_9794), type = StorableFamily.CAPE_RACK_SKILL), + PrayerCape(Items.PRAYER_CAPE_10643, intArrayOf(Items.PRAYER_CAPE_9759, Items.PRAYER_CAPET_9760, Items.PRAYER_HOOD_9761), type = StorableFamily.CAPE_RACK_SKILL), + RangingCape(Items.RANGING_CAPE_10642, intArrayOf(Items.RANGING_CAPE_9756, Items.RANGING_CAPET_9757, Items.RANGING_HOOD_9758), type = StorableFamily.CAPE_RACK_SKILL), + RunecraftCape(Items.RUNECRAFT_CAPE_10645, intArrayOf(Items.RUNECRAFT_CAPE_9765, Items.RUNECRAFT_CAPET_9766, Items.RUNECRAFTING_HOOD_9767), type = StorableFamily.CAPE_RACK_SKILL, "Runecrafting cape"), + SlayerCape(Items.SLAYER_CAPE_10653, intArrayOf(Items.SLAYER_CAPE_9786, Items.SLAYER_CAPET_9787, Items.SLAYER_HOOD_9788), type = StorableFamily.CAPE_RACK_SKILL), + SmithingCape(Items.SMITHING_CAPE_10656, intArrayOf(Items.SMITHING_CAPE_9795, Items.SMITHING_CAPET_9796, Items.SMITHING_HOOD_9797), type = StorableFamily.CAPE_RACK_SKILL), + ThievingCape(Items.THIEVING_CAPE_10650, intArrayOf(Items.THIEVING_CAPE_9777, Items.THIEVING_CAPET_9778, Items.THIEVING_HOOD_9779), type = StorableFamily.CAPE_RACK_SKILL), + WoodcuttingCape(Items.WOODCUTTING_CAPE_10660, intArrayOf(Items.WOODCUTTING_CAPE_9807, Items.WOODCUT_CAPET_9808, Items.WOODCUTTING_HOOD_9809), type = StorableFamily.CAPE_RACK_SKILL), + HunterCape(Items.HUNTER_CAPE_10646, intArrayOf(Items.HUNTER_CAPE_9948, Items.HUNTER_CAPET_9949, Items.HUNTER_HOOD_9950), type = StorableFamily.CAPE_RACK_SKILL), + QuestCape(Items.QUEST_POINT_CAPE_10662, intArrayOf(Items.QUEST_POINT_CAPE_9813, Items.QUEST_POINT_HOOD_9814), type = StorableFamily.CAPE_RACK_SKILL), + SummoningCape(Items.SUMMONING_CAPE_12524, intArrayOf(Items.SUMMONING_CAPE_12169, Items.SUMMONING_CAPET_12170, Items.SUMMONING_HOOD_12171), type = StorableFamily.CAPE_RACK_SKILL), + SpottedCape(Items.SPOTTED_CAPE_10663, intArrayOf(Items.SPOTTED_CAPE_10663), type = StorableFamily.CAPE_RACK, "Spotted hunting cape"), + SpottierCape(Items.SPOTTIER_CAPE_10664, intArrayOf(Items.SPOTTIER_CAPE_10664), type = StorableFamily.CAPE_RACK, "Spottier hunting cape"), + + // Fancy Dress - https://runescape.wiki/w/Fancy_dress_box?oldid=848873 + MimeCostume(Items.MIME_MASK_10629, intArrayOf(Items.MIME_MASK_3057, Items.MIME_TOP_3058, Items.MIME_LEGS_3059, Items.MIME_GLOVES_3060, Items.MIME_BOOTS_3061), type = StorableFamily.FANCY_DRESS, "Mime Costume"), + RoyalFrogCostume(Items.PRINCESS_BLOUSE_10630, intArrayOf(Items.PRINCE_TUNIC_6184, Items.PRINCE_LEGGINGS_6185, Items.PRINCESS_BLOUSE_6186, Items.PRINCESS_SKIRT_6187), type = StorableFamily.FANCY_DRESS, "Royal frog costume"), + FrogMask(Items.FROG_MASK_10721, intArrayOf(Items.FROG_MASK_6188), type = StorableFamily.FANCY_DRESS), + ZombieOutfit(Items.ZOMBIE_SHIRT_10631, intArrayOf(Items.ZOMBIE_MASK_7594, Items.ZOMBIE_SHIRT_7592, Items.ZOMBIE_TROUSERS_7593, Items.ZOMBIE_GLOVES_7595, Items.ZOMBIE_BOOTS_7596), type = StorableFamily.FANCY_DRESS, "Zombie Outfit"), + CamoOutfit(Items.CAMO_TOP_10632, intArrayOf(Items.CAMO_HELMET_6656, Items.CAMO_TOP_6654, Items.CAMO_BOTTOMS_6655), type = StorableFamily.FANCY_DRESS, "Camo outfit"), + LederhosenOutfit(Items.LEDERHOSEN_TOP_10633, intArrayOf(Items.LEDERHOSEN_TOP_6180, Items.LEDERHOSEN_SHORTS_6181, Items.LEDERHOSEN_HAT_6182), type = StorableFamily.FANCY_DRESS, "Lederhosen outfit"), + ShadeRobes(Items.SHADE_ROBE_10634, intArrayOf(Items.SHADE_ROBE_546, Items.SHADE_ROBE_548), type = StorableFamily.FANCY_DRESS, "Shade robes"), + + // Toys - https://runescape.wiki/w/Toy_box?oldid=848855 + BunnyEars(Items.BUNNY_EARS_10734, intArrayOf(Items.BUNNY_EARS_1037), type = StorableFamily.TOY_BOX), + Scythe(Items.SCYTHE_10735, intArrayOf(Items.SCYTHE_1419), type = StorableFamily.TOY_BOX), + YoYo(Items.YO_YO_10733, intArrayOf(Items.YO_YO_4079), type = StorableFamily.TOY_BOX), + RubberChicken(Items.RUBBER_CHICKEN_10732, intArrayOf(Items.RUBBER_CHICKEN_4566), type = StorableFamily.TOY_BOX), + ZombieHead(Items.ZOMBIE_HEAD_10731, intArrayOf(Items.ZOMBIE_HEAD_6722), type = StorableFamily.TOY_BOX), + EasterRing(Items.EASTER_RING_10729, intArrayOf(Items.EASTER_RING_7927), type = StorableFamily.TOY_BOX), + BobbleHat(Items.BOBBLE_HAT_9815, intArrayOf(Items.BOBBLE_HAT_6856), type = StorableFamily.TOY_BOX), + BobbleScarf(Items.BOBBLE_SCARF_9816, intArrayOf(Items.BOBBLE_SCARF_6857), type = StorableFamily.TOY_BOX), + JesterHat(Items.JESTER_HAT_6858, intArrayOf(Items.JESTER_HAT_6858), type = StorableFamily.TOY_BOX), + JesterScarf(Items.JESTER_SCARF_6859, intArrayOf(Items.JESTER_SCARF_6859), type = StorableFamily.TOY_BOX), + TriJesterHat(Items.TRI_JESTER_HAT_6860, intArrayOf(Items.TRI_JESTER_HAT_6860), type = StorableFamily.TOY_BOX), + TriJesterScarf(Items.TRI_JESTER_SCARF_6861, intArrayOf(Items.TRI_JESTER_SCARF_6861), type = StorableFamily.TOY_BOX), + WoollyHat(Items.WOOLLY_HAT_6862, intArrayOf(Items.WOOLLY_HAT_6862), type = StorableFamily.TOY_BOX), + WoollyScarf(Items.WOOLLY_SCARF_6863, intArrayOf(Items.WOOLLY_SCARF_6863), type = StorableFamily.TOY_BOX), + Marionette(Items.BLUE_MARIONETTE_10730, intArrayOf(Items.BLUE_MARIONETTE_6865,Items.GREEN_MARIONETTE_6866,Items.RED_MARIONETTE_6867), type = StorableFamily.TOY_BOX), // this authentically displays as 'blue marionette' in the source video + JackLanternMask(Items.JACK_LANTERN_MASK_10723, intArrayOf(Items.JACK_LANTERN_MASK_9920), type = StorableFamily.TOY_BOX), + SkeletonBoots(Items.SKELETON_BOOTS_10724, intArrayOf(Items.SKELETON_BOOTS_9921), type = StorableFamily.TOY_BOX), + SkeletonGloves(Items.SKELETON_GLOVES_10725, intArrayOf(Items.SKELETON_GLOVES_9922), type = StorableFamily.TOY_BOX), + SkeletonLeggings(Items.SKELETON_LEGGINGS_10726, intArrayOf(Items.SKELETON_LEGGINGS_9923), type = StorableFamily.TOY_BOX), + SkeletonShirt(Items.SKELETON_SHIRT_10727, intArrayOf(Items.SKELETON_SHIRT_9924), type = StorableFamily.TOY_BOX), + SkeletonMask(Items.SKELETON_MASK_10728, intArrayOf(Items.SKELETON_MASK_9925), type = StorableFamily.TOY_BOX), + ReindeerHat(Items.REINDEER_HAT_10722, intArrayOf(Items.REINDEER_HAT_10507), type = StorableFamily.TOY_BOX), + WintumberTree(Items.WINTUMBER_TREE_10508, intArrayOf(Items.WINTUMBER_TREE_10508), type = StorableFamily.TOY_BOX), + ChickenFeet(Items.CHICKEN_FEET_11019, intArrayOf(Items.CHICKEN_FEET_11019), type = StorableFamily.TOY_BOX), + ChickenLegs(Items.CHICKEN_LEGS_11022, intArrayOf(Items.CHICKEN_LEGS_11022), type = StorableFamily.TOY_BOX), + ChickenWings(Items.CHICKEN_WINGS_11020, intArrayOf(Items.CHICKEN_WINGS_11020), type = StorableFamily.TOY_BOX), + ChickenHead(Items.CHICKEN_HEAD_11021, intArrayOf(Items.CHICKEN_HEAD_11021), type = StorableFamily.TOY_BOX), + GrimReaperHood(Items.GRIM_REAPER_HOOD_11789, intArrayOf(Items.GRIM_REAPER_HOOD_11789), type = StorableFamily.TOY_BOX), + SnowGlobe(Items.SNOW_GLOBE_11949, intArrayOf(Items.SNOW_GLOBE_11949), type = StorableFamily.TOY_BOX), + ChocaticeCape(Items.CHOCATRICE_CAPE_12634, intArrayOf(Items.CHOCATRICE_CAPE_12645), type = StorableFamily.TOY_BOX), + WarlockTop(Items.WARLOCK_TOP_14076, intArrayOf(Items.WARLOCK_TOP_14076, Items.WITCH_TOP_14078), type = StorableFamily.TOY_BOX), + WarlockLegs(Items.WARLOCK_LEGS_14077, intArrayOf(Items.WARLOCK_LEGS_14077, Items.WITCH_SKIRT_14079), type = StorableFamily.TOY_BOX), + WarlockCloak(Items.WARLOCK_CLOAK_14081, intArrayOf(Items.WARLOCK_CLOAK_14081, Items.WITCH_CLOAK_14088), type = StorableFamily.TOY_BOX), + SantaCostumeTop(Items.SANTA_COSTUME_TOP_14595, intArrayOf(Items.SANTA_COSTUME_TOP_14595, Items.SANTA_COSTUME_TOP_14600), type = StorableFamily.TOY_BOX), + SantaCostumeLegs(Items.SANTA_COSTUME_LEGS_14603, intArrayOf(Items.SANTA_COSTUME_LEGS_14603, Items.SANTA_COSTUME_LEGS_14604), type = StorableFamily.TOY_BOX), + SantaCostumeGloves(Items.SANTA_COSTUME_GLOVES_14602, intArrayOf(Items.SANTA_COSTUME_GLOVES_14602), type = StorableFamily.TOY_BOX), + SantaCostumeBoots(Items.SANTA_COSTUME_BOOTS_14605, intArrayOf(Items.SANTA_COSTUME_BOOTS_14605), type = StorableFamily.TOY_BOX), + IceAmulet(Items.ICE_AMULET_14596, intArrayOf(Items.ICE_AMULET_14596), type = StorableFamily.TOY_BOX), + Cornucopia(Items.CORNUCOPIA_14570, intArrayOf(Items.CORNUCOPIA_14537), type = StorableFamily.TOY_BOX), + + // Treasure Trails - low - https://runescape.wiki/w/Treasure_chest?oldid=848831 + TrimmedBlackArmour(Items.BLACK_PLATEBODY_T_10690, intArrayOf(Items.BLACK_FULL_HELMT_2587, Items.BLACK_PLATEBODY_T_2583, Items.BLACK_PLATELEGS_T_2585, Items.BLACK_KITESHIELD_T_2589, Items.BLACK_PLATESKIRT_T_3472), type = StorableFamily.TREASURE_CHEST_LOW, "Trimmed black armour"), + GoldTrimmedBlackArmour(Items.BLACK_PLATEBODY_G_10691, intArrayOf(Items.BLACK_FULL_HELMG_2595, Items.BLACK_PLATEBODY_G_2591, Items.BLACK_PLATELEGS_G_2593, Items.BLACK_KITESHIELD_G_2597, Items.BLACK_PLATESKIRT_G_3473), type = StorableFamily.TREASURE_CHEST_LOW, "Gold-trimmed black armour"), + BlackHeraldicH1(Items.BLACK_HELM_H1_10699, intArrayOf(Items.BLACK_HELM_H1_10306), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic helm"), + BlackHeraldicH2(Items.BLACK_HELM_H2_10700, intArrayOf(Items.BLACK_HELM_H2_10308), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic helm"), + BlackHeraldicH3(Items.BLACK_HELM_H3_10701, intArrayOf(Items.BLACK_HELM_H3_10310), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic helm"), + BlackHeraldicH4(Items.BLACK_HELM_H4_10702, intArrayOf(Items.BLACK_HELM_H4_10312), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic helm"), + BlackHeraldicH5(Items.BLACK_HELM_H5_10703, intArrayOf(Items.BLACK_HELM_H5_10314), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic helm"), + BlackHeraldicKiteshieldH1(Items.BLACK_SHIELDH1_10665, intArrayOf(Items.BLACK_SHIELDH1_7332), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic kiteshield"), + BlackHeraldicKiteshieldH2(Items.BLACK_SHIELDH2_10668, intArrayOf(Items.BLACK_SHIELDH2_7338), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic kiteshield"), + BlackHeraldicKiteshieldH3(Items.BLACK_SHIELDH3_10671, intArrayOf(Items.BLACK_SHIELDH3_7344), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic kiteshield"), + BlackHeraldicKiteshieldH4(Items.BLACK_SHIELDH4_10674, intArrayOf(Items.BLACK_SHIELDH4_7350), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic kiteshield"), + BlackHeraldicKiteshieldH5(Items.BLACK_SHIELDH5_10677, intArrayOf(Items.BLACK_SHIELDH5_7356), type = StorableFamily.TREASURE_CHEST_LOW, "Black heraldic kiteshield"), + TrimmedStuddedArmour(Items.STUDDED_BODY_T_10681, intArrayOf(Items.STUDDED_BODY_T_7364, Items.STUDDED_CHAPS_T_7368), type = StorableFamily.TREASURE_CHEST_LOW, "Fur-trimmed studded leather"), + GoldTrimmedStuddedArmour(Items.STUDDED_BODY_G_10680, intArrayOf(Items.STUDDED_BODY_G_7362, Items.STUDDED_CHAPS_G_7366), type = StorableFamily.TREASURE_CHEST_LOW, "Gold-trimmed studded leather"), + TrimmedWizardRobes(Items.WIZARD_ROBE_T_10687, intArrayOf(Items.WIZARD_HAT_T_7396, Items.WIZARD_ROBE_T_7392, Items.BLUE_SKIRT_T_7388), type = StorableFamily.TREASURE_CHEST_LOW, "Trimmed wizard's robes"), + GoldTrimmedWizardRobes(Items.WIZARD_ROBE_G_10686, intArrayOf(Items.WIZARD_HAT_G_7394, Items.WIZARD_ROBE_G_7390, Items.BLUE_SKIRT_G_7386), type = StorableFamily.TREASURE_CHEST_LOW, "Gold-trimmed wizard's robes"), + WizardBoots(Items.WIZARD_BOOTS_10689, intArrayOf(Items.WIZARD_BOOTS_2579), type = StorableFamily.TREASURE_CHEST_LOW), + TrimmedAmuletOfMagic(Items.AMULET_OF_MAGICT_10738, intArrayOf(Items.AMULET_OF_MAGICT_10366), type = StorableFamily.TREASURE_CHEST_LOW, "Trimmed amulet of magic"), + HighwaymanMask(Items.HIGHWAYMAN_MASK_10692, intArrayOf(Items.HIGHWAYMAN_MASK_2631), type = StorableFamily.TREASURE_CHEST_LOW), + Pantaloons(Items.PANTALOONS_10744, intArrayOf(Items.PANTALOONS_10396), type = StorableFamily.TREASURE_CHEST_LOW), + PowderedWig(Items.A_POWDERED_WIG_10740, intArrayOf(Items.A_POWDERED_WIG_10392), type = StorableFamily.TREASURE_CHEST_LOW), + FlaredTrousers(Items.FLARED_TROUSERS_10742, intArrayOf(Items.FLARED_TROUSERS_10394), type = StorableFamily.TREASURE_CHEST_LOW), + SleepingCap(Items.SLEEPING_CAP_10746, intArrayOf(Items.SLEEPING_CAP_10398), type = StorableFamily.TREASURE_CHEST_LOW), + BlackBeret(Items.BLACK_BERET_10694, intArrayOf(Items.BLACK_BERET_2635), type = StorableFamily.TREASURE_CHEST_LOW), + WhiteBeret(Items.WHITE_BERET_10695, intArrayOf(Items.WHITE_BERET_2637), type = StorableFamily.TREASURE_CHEST_LOW), + BlueBeret(Items.BLUE_BERET_10693, intArrayOf(Items.BLUE_BERET_2633), type = StorableFamily.TREASURE_CHEST_LOW), + BobTheCatShirt(Items.BOB_SHIRT_10714, intArrayOf(Items.BOB_SHIRT_10316), type = StorableFamily.TREASURE_CHEST_LOW, "Bob the Cat shirt (red)"), + BobTheCatShirt1(Items.BOB_SHIRT_10715, intArrayOf(Items.BOB_SHIRT_10318), type = StorableFamily.TREASURE_CHEST_LOW, "Bob the Cat shirt (blue)"), + BobTheCatShirt2(Items.BOB_SHIRT_10716, intArrayOf(Items.BOB_SHIRT_10320), type = StorableFamily.TREASURE_CHEST_LOW, "Bob the Cat shirt (green)"), + BobTheCatShirt3(Items.BOB_SHIRT_10717, intArrayOf(Items.BOB_SHIRT_10322), type = StorableFamily.TREASURE_CHEST_LOW, "Bob the Cat shirt (black)"), + BobTheCatShirt4(Items.BOB_SHIRT_10718, intArrayOf(Items.BOB_SHIRT_10324), type = StorableFamily.TREASURE_CHEST_LOW, "Bob the Cat shirt (purple)"), + RedElegant(Items.ELEGANT_SHIRT_10750, intArrayOf(Items.RED_ELE_SHIRT_10404, Items.RED_ELE_LEGS_10406, Items.RED_ELE_BLOUSE_10424, Items.RED_ELE_SKIRT_10426), type = StorableFamily.TREASURE_CHEST_LOW, "Elegant clothes (red)"), + BlueElegant(Items.ELEGANT_SHIRT_10752, intArrayOf(Items.BLUE_ELE_SHIRT_10408, Items.BLUE_ELE_LEGS_10410, Items.BLUE_ELE_BLOUSE_10428, Items.BLUE_ELE_SKIRT_10430), type = StorableFamily.TREASURE_CHEST_LOW, "Elegant clothes (blue)"), + GreenElegant(Items.ELEGANT_SHIRT_10754, intArrayOf(Items.GREEN_ELE_SHIRT_10412,Items.GREEN_ELE_LEGS_10414, Items.GREEN_ELE_BLOUSE_10432, Items.GREEN_ELE_SKIRT_10434), type = StorableFamily.TREASURE_CHEST_LOW, "Elegant clothes (green)"), + BeretAndMask(Items.BERET_MASK_11278, intArrayOf(Items.BERET_AND_MASK_11282), type = StorableFamily.TREASURE_CHEST_LOW), + BlackCane(Items.BLACK_CANE_13163, intArrayOf(Items.BLACK_CANE_13095), type = StorableFamily.TREASURE_CHEST_LOW), + SpikedHelmet(Items.SPIKED_HELMET_13168, intArrayOf(Items.SPIKED_HELMET_13105), type = StorableFamily.TREASURE_CHEST_LOW), + + // Treasure Trails - medium - https://runescape.wiki/w/Treasure_chest?oldid=848831 + TrimmedAdamantiteArmour(Items.ADAM_PLATEBODY_T_10697, intArrayOf(Items.ADAM_FULL_HELMT_2605, Items.ADAM_PLATEBODY_T_2599, Items.ADAM_PLATELEGS_T_2601, Items.ADAM_KITESHIELD_T_2603, Items.ADAM_PLATESKIRT_T_3474), type = StorableFamily.TREASURE_CHEST_MED, "Trimmed adamantite armour"), + GoldTrimmedAdamantiteArmour(Items.ADAM_PLATEBODY_G_10698, intArrayOf(Items.ADAM_FULL_HELMG_2613, Items.ADAM_PLATEBODY_G_2607, Items.ADAM_PLATELEGS_G_2609, Items.ADAM_KITESHIELD_G_2611, Items.ADAM_PLATESKIRT_G_3475), type = StorableFamily.TREASURE_CHEST_MED, "Gold-trimmed adamantite armour"), + AdamantHeraldicH1(Items.ADAMANT_HELM_H1_10709, intArrayOf(Items.ADAMANT_HELM_H1_10296), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic helm"), + AdamantHeraldicH2(Items.ADAMANT_HELM_H2_10710, intArrayOf(Items.ADAMANT_HELM_H2_10298), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic helm"), + AdamantHeraldicH3(Items.ADAMANT_HELM_H3_10711, intArrayOf(Items.ADAMANT_HELM_H3_10300), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic helm"), + AdamantHeraldicH4(Items.ADAMANT_HELM_H4_10712, intArrayOf(Items.ADAMANT_HELM_H4_10302), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic helm"), + AdamantHeraldicH5(Items.ADAMANT_HELM_H5_10713, intArrayOf(Items.ADAMANT_HELM_H5_10304), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic helm"), + AdamantKiteshieldH1(Items.ADAMANT_SHIELDH1_10666, intArrayOf(Items.ADAMANT_SHIELDH1_7334), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic kiteshield"), + AdamantKiteshieldH2(Items.ADAMANT_SHIELDH2_10669, intArrayOf(Items.ADAMANT_SHIELDH2_7340), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic kiteshield"), + AdamantKiteshieldH3(Items.ADAMANT_SHIELDH3_10672, intArrayOf(Items.ADAMANT_SHIELDH3_7346), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic kiteshield"), + AdamantKiteshieldH4(Items.ADAMANT_SHIELDH4_10675, intArrayOf(Items.ADAMANT_SHIELDH4_7352), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic kiteshield"), + AdamantKiteshieldH5(Items.ADAMANT_SHIELDH5_10678, intArrayOf(Items.ADAMANT_SHIELDH5_7358), type = StorableFamily.TREASURE_CHEST_MED, "Adamant heraldic kiteshield"), + TrimmedGreenDhide(Items.DHIDE_BODY_T_10683, intArrayOf(Items.DHIDE_BODY_T_7372, Items.DHIDE_CHAPS_T_7380), type = StorableFamily.TREASURE_CHEST_MED, "Trimmed green dragonhide armour"), + GoldTrimmedGreenDhide(Items.DHIDE_BODYG_10682, intArrayOf(Items.DHIDE_BODYG_7370, Items.DHIDE_CHAPS_G_7378), type = StorableFamily.TREASURE_CHEST_MED, "Gold-trimmed green dragonhide armour"), + RangerBoots(Items.RANGER_BOOTS_10696, intArrayOf(Items.RANGER_BOOTS_2577), type = StorableFamily.TREASURE_CHEST_MED), + TrimmedAmuletOfStrength(Items.STRENGTH_AMULETT_10736, intArrayOf(Items.STRENGTH_AMULETT_10364), type = StorableFamily.TREASURE_CHEST_MED, "Trimmed amulet of strength"), + RedHeadband(Items.RED_HEADBAND_10768, intArrayOf(Items.RED_HEADBAND_2645), type = StorableFamily.TREASURE_CHEST_MED), + BlackHeadband(Items.BLACK_HEADBAND_10770, intArrayOf(Items.BLACK_HEADBAND_2647), type = StorableFamily.TREASURE_CHEST_MED), + BrownHeadband(Items.BROWN_HEADBAND_10772, intArrayOf(Items.BROWN_HEADBAND_2649), type = StorableFamily.TREASURE_CHEST_MED), + RedBoater(Items.RED_BOATER_10758, intArrayOf(Items.RED_BOATER_7319), type = StorableFamily.TREASURE_CHEST_MED, "Red straw boater"), + OrangeBoater(Items.ORANGE_BOATER_10760, intArrayOf(Items.ORANGE_BOATER_7321), type = StorableFamily.TREASURE_CHEST_MED, "Orange straw boater"), + GreenBoater(Items.GREEN_BOATER_10762, intArrayOf(Items.GREEN_BOATER_7323), type = StorableFamily.TREASURE_CHEST_MED, "Green straw boater"), + BlueBoater(Items.BLUE_BOATER_10764, intArrayOf(Items.BLUE_BOATER_7325), type = StorableFamily.TREASURE_CHEST_MED, "Blue straw boater"), + BlackBoater(Items.BLACK_BOATER_10766, intArrayOf(Items.BLACK_BOATER_7327), type = StorableFamily.TREASURE_CHEST_MED, "Black straw boater"), + BlackElegant(Items.ELEGANT_SHIRT_10748, intArrayOf(Items.BLACK_ELE_SHIRT_10400, Items.BLACK_ELE_LEGS_10402, Items.WHITE_ELE_BLOUSE_10420, Items.WHITE_ELE_SKIRT_10422), type = StorableFamily.TREASURE_CHEST_MED, "Elegant clothes (black)"), + PurpleElegant(Items.ELEGANT_SHIRT_10756, intArrayOf(Items.PURPLE_ELE_BLOUSE_10436, Items.PURPLE_ELE_SKIRT_10438), type = StorableFamily.TREASURE_CHEST_MED, "Elegant clothes (purple)"), + AdamantCane(Items.ADAMANT_CANE_13164, intArrayOf(Items.ADAMANT_CANE_13097), type = StorableFamily.TREASURE_CHEST_MED), + SheepMask(Items.SHEEP_MASK_13169, intArrayOf(Items.SHEEP_MASK_13107), type = StorableFamily.TREASURE_CHEST_MED), + BatMask(Items.BAT_MASK_13171, intArrayOf(Items.BAT_MASK_13111), type = StorableFamily.TREASURE_CHEST_MED), + WolfMask(Items.WOLF_MASK_13173, intArrayOf(Items.WOLF_MASK_13115), type = StorableFamily.TREASURE_CHEST_MED), + PenguinMask(Items.PENGUIN_MASK_13170, intArrayOf(Items.PENGUIN_MASK_13109), type = StorableFamily.TREASURE_CHEST_MED), + CatMask(Items.CAT_MASK_13172, intArrayOf(Items.CAT_MASK_13113), type = StorableFamily.TREASURE_CHEST_MED), + PithHelmet(Items.PITH_HELMET_13167, intArrayOf(Items.PITH_HELMET_13103), type = StorableFamily.TREASURE_CHEST_MED), + + // Treasure Trails - hard - https://runescape.wiki/w/Treasure_chest?oldid=848831 + TrimmedRuneArmour(Items.RUNE_PLATEBODY_T_10800, intArrayOf(Items.RUNE_FULL_HELM_T_2627, Items.RUNE_PLATEBODY_T_2623, Items.RUNE_PLATELEGS_T_2625, Items.RUNE_KITESHIELD_T_2629, Items.RUNE_PLATESKIRT_T_3477), type = StorableFamily.TREASURE_CHEST_HIGH, "Trimmed rune armour"), + GoldTrimmedRuneArmour(Items.RUNE_PLATEBODY_G_10798, intArrayOf(Items.RUNE_FULL_HELMG_2619, Items.RUNE_PLATEBODY_G_2615, Items.RUNE_PLATELEGS_G_2617, Items.RUNE_KITESHIELD_G_2621, Items.RUNE_PLATESKIRT_G_3476), type = StorableFamily.TREASURE_CHEST_HIGH, "Gold-trimmed rune armour"), + GildedArmour(Items.GILDED_PLATEBODY_10782, intArrayOf(Items.GILDED_FULL_HELM_3486, Items.GILDED_PLATEBODY_3481, Items.GILDED_PLATELEGS_3483, Items.GILDED_KITESHIELD_3488, Items.GILDED_PLATESKIRT_3485), type = StorableFamily.TREASURE_CHEST_HIGH, "Gold-plated rune armour"), + RuneHelmH1(Items.RUNE_HELM_H1_10704, intArrayOf(Items.RUNE_HELM_H1_10286), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic helm"), + RuneHelmH2(Items.RUNE_HELM_H2_10705, intArrayOf(Items.RUNE_HELM_H2_10288), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic helm"), + RuneHelmH3(Items.RUNE_HELM_H3_10706, intArrayOf(Items.RUNE_HELM_H3_10290), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic helm"), + RuneHelmH4(Items.RUNE_HELM_H4_10707, intArrayOf(Items.RUNE_HELM_H4_10292), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic helm"), + RuneHelmH5(Items.RUNE_HELM_H5_10708, intArrayOf(Items.RUNE_HELM_H5_10294), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic helm"), + RuneShieldH1(Items.RUNE_SHIELDH1_10667, intArrayOf(Items.RUNE_SHIELDH1_7336), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic kiteshield"), + RuneShieldH2(Items.RUNE_SHIELDH2_10670, intArrayOf(Items.RUNE_SHIELDH2_7342), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic kiteshield"), + RuneShieldH3(Items.RUNE_SHIELDH3_10673, intArrayOf(Items.RUNE_SHIELDH3_7348), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic kiteshield"), + RuneShieldH4(Items.RUNE_SHIELDH4_10676, intArrayOf(Items.RUNE_SHIELDH4_7354), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic kiteshield"), + RuneShieldH5(Items.RUNE_SHIELDH5_10679, intArrayOf(Items.RUNE_SHIELDH5_7360), type = StorableFamily.TREASURE_CHEST_HIGH, "Rune heraldic kiteshield"), + ZamorakRuneArmour(Items.ZAMORAK_PLATEBODY_10776, intArrayOf(Items.ZAMORAK_FULL_HELM_2657, Items.ZAMORAK_PLATEBODY_2653, Items.ZAMORAK_PLATELEGS_2655, Items.ZAMORAK_KITESHIELD_2659, Items.ZAMORAK_PLATESKIRT_3478), type = StorableFamily.TREASURE_CHEST_HIGH, "Zamorak rune armour"), + SaradominRuneArmour(Items.SARADOMIN_PLATE_10778, intArrayOf(Items.SARADOMIN_FULL_HELM_2665, Items.SARADOMIN_PLATEBODY_2661, Items.SARADOMIN_PLATELEGS_2663, Items.SARADOMIN_KITESHIELD_2667, Items.SARADOMIN_PLATESKIRT_3479), type = StorableFamily.TREASURE_CHEST_HIGH, "Saradomin rune armour"), + GuthixRuneArmour(Items.GUTHIX_PLATEBODY_10780, intArrayOf(Items.GUTHIX_FULL_HELM_2673, Items.GUTHIX_PLATEBODY_2669, Items.GUTHIX_PLATELEGS_2671, Items.GUTHIX_KITESHIELD_2675, Items.GUTHIX_PLATESKIRT_3480), type = StorableFamily.TREASURE_CHEST_HIGH, "Guthix rune armour"), + TrimmedBlueDhide(Items.DHIDE_BODY_T_10685, intArrayOf(Items.DHIDE_BODY_T_7376, Items.DHIDE_CHAPS_T_7384), type = StorableFamily.TREASURE_CHEST_HIGH, "Trimmed blue dragonhide armour"), + GoldTrimmedBlueDhide(Items.DHIDE_BODY_G_10684, intArrayOf(Items.DHIDE_BODY_G_7374, Items.DHIDE_CHAPS_G_7382), type = StorableFamily.TREASURE_CHEST_HIGH, "Gold-trimmed blue dragonhide armour"), + SaradominBlessedDhide(Items.SARADOMIN_DHIDE_10792, intArrayOf(Items.SARADOMIN_DHIDE_10386, Items.SARADOMIN_CHAPS_10388, Items.SARADOMIN_BRACERS_10384, Items.SARADOMIN_COIF_10390), type = StorableFamily.TREASURE_CHEST_HIGH, "Saradomin blessed dragonhide"), + GuthixBlessedDhide(Items.GUTHIX_DRAGONHIDE_10794, intArrayOf(Items.GUTHIX_DRAGONHIDE_10378, Items.GUTHIX_CHAPS_10380, Items.GUTHIX_BRACERS_10376, Items.GUTHIX_COIF_10382), type = StorableFamily.TREASURE_CHEST_HIGH, "Guthix blessed dragonhide"), + ZamorakBlessedDhide(Items.ZAMORAK_DHIDE_10790, intArrayOf(Items.ZAMORAK_DHIDE_10370, Items.ZAMORAK_CHAPS_10372, Items.ZAMORAK_BRACERS_10368, Items.ZAMORAK_COIF_10374), type = StorableFamily.TREASURE_CHEST_HIGH, "Zamorak blessed dragonhide"), + RobinHoodHat(Items.ROBIN_HOOD_HAT_10796, intArrayOf(Items.ROBIN_HOOD_HAT_2581), type = StorableFamily.TREASURE_CHEST_HIGH), + EnchantedRobes(Items.ENCHANTED_TOP_10688, intArrayOf(Items.ENCHANTED_HAT_7400, Items.ENCHANTED_TOP_7399, Items.ENCHANTED_ROBE_7398), type = StorableFamily.TREASURE_CHEST_HIGH, "Enchanted robes"), + SaradominVestments(Items.SARADOMIN_ROBE_TOP_10784, intArrayOf(Items.SARADOMIN_MITRE_10452, Items.SARADOMIN_ROBE_TOP_10458, Items.SARADOMIN_ROBE_LEGS_10464, Items.SARADOMIN_STOLE_10470, Items.SARADOMIN_CLOAK_10446, Items.SARADOMIN_CROZIER_10440), type = StorableFamily.TREASURE_CHEST_HIGH, "Saradomin vestments"), + ZamorakVestments(Items.ZAMORAK_ROBE_TOP_10786, intArrayOf(Items.ZAMORAK_MITRE_10456, Items.ZAMORAK_ROBE_TOP_10460, Items.ZAMORAK_ROBE_LEGS_10468, Items.ZAMORAK_STOLE_10474, Items.ZAMORAK_CLOAK_10450, Items.ZAMORAK_CROZIER_10444), type = StorableFamily.TREASURE_CHEST_HIGH, "Zamorak vestments"), + GuthixVestments(Items.GUTHIX_ROBE_TOP_10788, intArrayOf(Items.GUTHIX_MITRE_10454, Items.GUTHIX_ROBE_TOP_10462, Items.GUTHIX_ROBE_LEGS_10466, Items.GUTHIX_STOLE_10472, Items.GUTHIX_CLOAK_10448, Items.GUTHIX_CROZIER_10442), type = StorableFamily.TREASURE_CHEST_HIGH, "Guthix vestments"), + TrimmedAmuletOfGlory(Items.AMULET_OF_GLORYT_10719, intArrayOf(Items.AMULET_OF_GLORYT_10362), type = StorableFamily.TREASURE_CHEST_HIGH, "Trimmed amulet of glory"), + PiratesHat(Items.PIRATES_HAT_10774, intArrayOf(Items.PIRATES_HAT_2651), type = StorableFamily.TREASURE_CHEST_HIGH), + CavalierMask(Items.CAVALIER_MASK_11277, intArrayOf(Items.CAVALIER_AND_MASK_11280), type = StorableFamily.TREASURE_CHEST_HIGH), + DarkCavalier(Items.DARK_CAVALIER_10804, intArrayOf(Items.DARK_CAVALIER_2641), type = StorableFamily.TREASURE_CHEST_HIGH, "Dark brown cavalier"), + TanCavalier(Items.TAN_CAVALIER_10802, intArrayOf(Items.TAN_CAVALIER_2639), type = StorableFamily.TREASURE_CHEST_HIGH), + BlackCavalier(Items.BLACK_CAVALIER_10806, intArrayOf(Items.BLACK_CAVALIER_2643), type = StorableFamily.TREASURE_CHEST_HIGH), + RuneCane(Items.RUNE_CANE_13165, intArrayOf(Items.RUNE_CANE_13099), type = StorableFamily.TREASURE_CHEST_HIGH), + TopHat(Items.TOP_HAT_13166, intArrayOf(Items.TOP_HAT_13101), type = StorableFamily.TREASURE_CHEST_HIGH), + + // Magic Wardrobe - https://runescape.wiki/w/Magic_wardrobe?oldid=848846 + MysticBlueSet(Items.MYSTIC_HAT_10601, intArrayOf(Items.MYSTIC_HAT_4089, Items.MYSTIC_ROBE_TOP_4091, Items.MYSTIC_ROBE_BOTTOM_4093, Items.MYSTIC_GLOVES_4095, Items.MYSTIC_BOOTS_4097), type = StorableFamily.MAGIC_WARDROBE, "Mystic robes"), + MysticDarkSet(Items.MYSTIC_HAT_10602, intArrayOf(Items.MYSTIC_HAT_4099, Items.MYSTIC_ROBE_TOP_4101, Items.MYSTIC_ROBE_BOTTOM_4103, Items.MYSTIC_GLOVES_4105, Items.MYSTIC_BOOTS_4107), type = StorableFamily.MAGIC_WARDROBE, "Dark mystic robes"), + MysticLightSet(Items.MYSTIC_HAT_10603, intArrayOf(Items.MYSTIC_HAT_4109, Items.MYSTIC_ROBE_TOP_4111, Items.MYSTIC_ROBE_BOTTOM_4113, Items.MYSTIC_GLOVES_4115, Items.MYSTIC_BOOTS_4117), type = StorableFamily.MAGIC_WARDROBE, "Light mystic robes"), + SkeletalSet(Items.SKELETAL_HELM_10604, intArrayOf(Items.SKELETAL_HELM_6137, Items.SKELETAL_TOP_6139, Items.SKELETAL_BOTTOMS_6141, Items.SKELETAL_GLOVES_6153, Items.SKELETAL_BOOTS_6147), type = StorableFamily.MAGIC_WARDROBE, "Skeletal"), + InfinitySet(Items.INFINITY_TOP_10605, intArrayOf(Items.INFINITY_HAT_6918, Items.INFINITY_TOP_6916, Items.INFINITY_BOTTOMS_6924, Items.INFINITY_GLOVES_6922, Items.INFINITY_BOOTS_6920), type = StorableFamily.MAGIC_WARDROBE, "Infinity robes"), + SplitbarkSet(Items.SPLITBARK_HELM_10606, intArrayOf(Items.SPLITBARK_HELM_3385, Items.SPLITBARK_BODY_3387, Items.SPLITBARK_LEGS_3389, Items.SPLITBARK_GAUNTLETS_3391, Items.SPLITBARK_BOOTS_3393), type = StorableFamily.MAGIC_WARDROBE, "Splitbark armour"), + GhostlySet(Items.GHOSTLY_BOOTS_10607, intArrayOf(Items.GHOSTLY_ROBE_6107, Items.GHOSTLY_ROBE_6108, Items.GHOSTLY_HOOD_6109, Items.GHOSTLY_GLOVES_6110, Items.GHOSTLY_BOOTS_6106, Items.GHOSTLY_CLOAK_6111), type = StorableFamily.MAGIC_WARDROBE, "Ghostly robes"), + MoonclanSet(Items.MOONCLAN_HAT_10608, intArrayOf(Items.MOONCLAN_HELM_9068, Items.MOONCLAN_ARMOUR_9070, Items.MOONCLAN_SKIRT_9071, Items.MOONCLAN_GLOVES_9072, Items.MOONCLAN_BOOTS_9073), type = StorableFamily.MAGIC_WARDROBE, "Moonclan robes"), + LunarSet(Items.LUNAR_HELM_10609, intArrayOf(Items.LUNAR_HELM_9096, Items.LUNAR_TORSO_9097, Items.LUNAR_LEGS_9098, Items.LUNAR_GLOVES_9099, Items.LUNAR_BOOTS_9100, Items.LUNAR_CAPE_9101, Items.LUNAR_AMULET_9102, Items.LUNAR_RING_9104), type = StorableFamily.MAGIC_WARDROBE, "Lunar robes"), + RunecrafterYellow(Items.RUNECRAFTER_HAT_13656, intArrayOf(Items.RUNECRAFTER_HAT_13615, Items.RUNECRAFTER_ROBE_13614, Items.RUNECRAFTER_SKIRT_13617), type = StorableFamily.MAGIC_WARDROBE, "Runecrafter robes (yellow)"), + RunecrafterGreen(Items.RUNECRAFTER_HAT_13657, intArrayOf(Items.RUNECRAFTER_HAT_13620, Items.RUNECRAFTER_ROBE_13619, Items.RUNECRAFTER_SKIRT_13622), type = StorableFamily.MAGIC_WARDROBE, "Runecrafter robes (green)"), + RunecrafterBlue(Items.RUNECRAFTER_HAT_13658, intArrayOf(Items.RUNECRAFTER_HAT_13625, Items.RUNECRAFTER_ROBE_13624, Items.RUNECRAFTER_SKIRT_13627), type = StorableFamily.MAGIC_WARDROBE, "Runecrafter robes (blue)"), + DagonHaiSet(Items.DAGONHAI_ROBE_TOP_14497, intArrayOf(Items.DAGONHAI_HAT_14499, Items.DAGONHAI_ROBE_TOP_14497, Items.DAGONHAI_ROBE_BOTTOM_14501), type = StorableFamily.MAGIC_WARDROBE, "Dagon'Hai Robes"), + + // Armour Case - https://runescape.wiki/w/Armour_case?oldid=848835 + DecorativeArmour(Items.DECORATIVE_ARMOUR_10610, intArrayOf(Items.DECORATIVE_ARMOUR_4069, Items.DECORATIVE_SWORD_4068, Items.DECORATIVE_ARMOUR_4070, Items.DECORATIVE_HELM_4071, Items.DECORATIVE_SHIELD_4072, Items.DECORATIVE_ARMOUR_4504, Items.DECORATIVE_SWORD_4503, Items.DECORATIVE_ARMOUR_4505, Items.DECORATIVE_HELM_4506, Items.DECORATIVE_SHIELD_4507, Items.DECORATIVE_ARMOUR_4509, Items.DECORATIVE_SWORD_4508, Items.DECORATIVE_ARMOUR_4510, Items.DECORATIVE_HELM_4511, Items.DECORATIVE_SHIELD_4512), type = StorableFamily.ARMOUR_CASE, "Castlewars armour"), // should be any one colour set per wiki + VoidKnightArmour(Items.VOID_KNIGHT_TOP_10611, intArrayOf(Items.VOID_KNIGHT_TOP_8839, Items.VOID_KNIGHT_ROBE_8840, Items.VOID_KNIGHT_GLOVES_8842), type = StorableFamily.ARMOUR_CASE, "Void Knight armour"), + RogueArmour(Items.ROGUE_MASK_10612, intArrayOf(Items.ROGUE_MASK_5554, Items.ROGUE_TOP_5553, Items.ROGUE_TROUSERS_5555), type = StorableFamily.ARMOUR_CASE, "Rogue armour"), + SpinedArmour(Items.SPINED_HELM_10614, intArrayOf(Items.SPINED_HELM_6131, Items.SPINED_BODY_6133, Items.SPINED_CHAPS_6135, Items.SPINED_BOOTS_6143, Items.SPINED_GLOVES_6149), type = StorableFamily.ARMOUR_CASE, "Spined armour"), + RockshellArmour(Items.ROCK_SHELL_HELM_10613, intArrayOf(Items.ROCK_SHELL_HELM_6128, Items.ROCK_SHELL_PLATE_6129, Items.ROCK_SHELL_LEGS_6130, Items.ROCK_SHELL_BOOTS_6145, Items.ROCK_SHELL_GLOVES_6151), type = StorableFamily.ARMOUR_CASE, "Rockshell armour"), + TribalMaskP(Items.TRIBAL_MASK_10615, intArrayOf(Items.TRIBAL_MASK_6335), type = StorableFamily.ARMOUR_CASE, "Broodoo mask (poison)"), + TribalMaskD(Items.TRIBAL_MASK_10616, intArrayOf(Items.TRIBAL_MASK_6337), type = StorableFamily.ARMOUR_CASE, "Broodoo mask (disease)"), + TribalMaskC(Items.TRIBAL_MASK_10617, intArrayOf(Items.TRIBAL_MASK_6339), type = StorableFamily.ARMOUR_CASE, "Broodoo mask (combat)"), + WhiteKnightArmour(Items.WHITE_PLATEBODY_10618, intArrayOf(Items.WHITE_PLATEBODY_6617, Items.WHITE_FULL_HELM_6623, Items.WHITE_PLATELEGS_6625, Items.WHITE_PLATESKIRT_6627), type = StorableFamily.ARMOUR_CASE, "White knight armour"), + TempleKnightInitiateArmour(Items.INITIATE_HAUBERK_10619, intArrayOf(Items.INITIATE_SALLET_5574, Items.INITIATE_HAUBERK_5575, Items.INITIATE_CUISSE_5576), type = StorableFamily.ARMOUR_CASE, "Temple Knight initiate armour"), + TempleKnightProselyteArmour(Items.PROSELYTE_HAUBERK_10620, intArrayOf(Items.PROSELYTE_SALLET_9672, Items.PROSELYTE_HAUBERK_9674, Items.PROSELYTE_CUISSE_9676, Items.PROSELYTE_TASSET_9678), type = StorableFamily.ARMOUR_CASE, "Temple Knight proselyte armour"), + MournerGear(Items.MOURNER_TOP_10621, intArrayOf(Items.MOURNER_TOP_6065, Items.MOURNER_TROUSERS_6066, Items.MOURNER_BOOTS_6069, Items.MOURNER_CLOAK_6070), type = StorableFamily.ARMOUR_CASE, "Mourner gear"), + GraahkHunterGear(Items.GRAAHK_TOP_10624, intArrayOf(Items.GRAAHK_TOP_10049, Items.GRAAHK_LEGS_10047, Items.GRAAHK_HEADDRESS_10051), type = StorableFamily.ARMOUR_CASE, "Graahk hunter gear"), + LarupiaHunterGear(Items.LARUPIA_TOP_10623, intArrayOf(Items.LARUPIA_TOP_10043, Items.LARUPIA_LEGS_10041, Items.LARUPIA_HAT_10045), type = StorableFamily.ARMOUR_CASE, "Larupia hunter gear"), + KyattHunterGear(Items.KYATT_TOP_10622, intArrayOf(Items.KYATT_TOP_10037, Items.KYATT_LEGS_10035, Items.KYATT_HAT_10039), type = StorableFamily.ARMOUR_CASE, "Kyatt hunter gear"), + PolarCamouflageGear(Items.POLAR_CAMO_TOP_10628, intArrayOf(Items.POLAR_CAMO_TOP_10628, Items.POLAR_CAMO_LEGS_10067), type = StorableFamily.ARMOUR_CASE, "Polar camouflage gear"), + JungleCamouflageGear(Items.JUNGLE_CAMO_TOP_10626, intArrayOf(Items.JUNGLE_CAMO_TOP_10057, Items.JUNGLE_CAMO_LEGS_10059), type = StorableFamily.ARMOUR_CASE, "Jungle camouflage gear"), + WoodCamouflageGear(Items.WOOD_CAMO_TOP_10625, intArrayOf(Items.WOOD_CAMO_TOP_10053, Items.WOOD_CAMO_LEGS_10055), type = StorableFamily.ARMOUR_CASE, "Wood camouflage gear"), + DesertCamouflageGear(Items.DESERT_CAMO_TOP_10627, intArrayOf(Items.DESERT_CAMO_TOP_10061, Items.DESERT_CAMO_LEGS_10063), type = StorableFamily.ARMOUR_CASE, "Desert camouflage gear"), + BuildersCostume(Items.BUILDERS_SHIRT_10863, intArrayOf(Items.BUILDERS_SHIRT_10863, Items.BUILDERS_TROUSERS_10864, Items.BUILDERS_BOOTS_10865), type = StorableFamily.ARMOUR_CASE, "Builder's costume"), + LumberjackCostume(Items.LUMBERJACK_TOP_10945, intArrayOf(Items.LUMBERJACK_TOP_10939, Items.LUMBERJACK_LEGS_10940, Items.LUMBERJACK_HAT_10941), type = StorableFamily.ARMOUR_CASE, "Lumberjack costume"), + BomberJacketCostume(Items.BOMBER_JACKET_11135, intArrayOf(Items.BOMBER_JACKET_9944, Items.BOMBER_CAP_9945), type = StorableFamily.ARMOUR_CASE, "Bomber jacket costume"), + HAMRobes(Items.HAM_SHIRT_11274, intArrayOf(Items.HAM_SHIRT_4298, Items.HAM_ROBE_4300, Items.HAM_HOOD_4302, Items.HAM_CLOAK_4304, Items.HAM_LOGO_4306, Items.BOOTS_4310, Items.GLOVES_4308), type = StorableFamily.ARMOUR_CASE, "H.A.M. robes"), + VoidMelee(Items.VOID_MELEE_HELM_11676, intArrayOf(Items.VOID_MELEE_HELM_11665), type = StorableFamily.ARMOUR_CASE, "Void melee helm"), + VoidRanger(Items.VOID_RANGER_HELM_11675, intArrayOf(Items.VOID_RANGER_HELM_11664), type = StorableFamily.ARMOUR_CASE, "Void ranger helm"), + VoidMage(Items.VOID_MAGE_HELM_11674, intArrayOf(Items.VOID_MAGE_HELM_11663), type = StorableFamily.ARMOUR_CASE, "Void mage helm"), + BlackNaval(Items.BLACK_NAVAL_SHIRT_13185, intArrayOf(Items.BLACK_NAVAL_SHIRT_8956, Items.BLACK_NAVY_SLACKS_8995, Items.BLACK_TRICORN_HAT_8963),type = StorableFamily.ARMOUR_CASE, "Black naval costume"), + RedNaval(Items.RED_NAVAL_SHIRT_13183, intArrayOf(Items.RED_TRICORN_HAT_8961, Items.RED_NAVAL_SHIRT_8954, Items.RED_NAVY_SLACKS_8993), type = StorableFamily.ARMOUR_CASE, "Red naval costume"), + BlueNaval(Items.BLUE_NAVAL_SHIRT_13181, intArrayOf(Items.BLUE_TRICORN_HAT_8959, Items.BLUE_NAVAL_SHIRT_8952, Items.BLUE_NAVY_SLACKS_8991), type = StorableFamily.ARMOUR_CASE, "Blue naval costume"), + BrownNaval(Items.BROWN_NAVAL_SHIRT_13184, intArrayOf(Items.BROWN_TRICORN_HAT_8962, Items.BROWN_NAVAL_SHIRT_8955, Items.BROWN_NAVY_SLACKS_8994), type = StorableFamily.ARMOUR_CASE, "Brown naval costume"), + GreenNaval(Items.GREEN_NAVAL_SHIRT_13182, intArrayOf(Items.GREEN_TRICORN_HAT_8960, Items.GREEN_NAVAL_SHIRT_8953, Items.GREEN_NAVY_SLACKS_8992), type = StorableFamily.ARMOUR_CASE, "Green naval costume"), + GreyNaval(Items.GREY_NAVAL_SHIRT_13187, intArrayOf(Items.GREY_TRICORN_HAT_8965, Items.GREY_NAVAL_SHIRT_8958, Items.GREY_NAVY_SLACKS_8997), type = StorableFamily.ARMOUR_CASE, "Grey naval costume"), + PurpleNaval(Items.PURPLE_NAVAL_SHIRT_13186, intArrayOf(Items.PURPLE_TRICORN_HAT_8964, Items.PURPLE_NAVAL_SHIRT_8957, Items.PURPLE_NAVY_SLACKS_8996), type = StorableFamily.ARMOUR_CASE, "Purple naval costume"), + EliteBlackArmour(Items.ELITE_BLACK_PLATEBODY_14492, intArrayOf(Items.ELITE_BLACK_FULL_HELM_14494, Items.ELITE_BLACK_PLATEBODY_14492, Items.ELITE_BLACK_PLATELEGS_14490), type = StorableFamily.ARMOUR_CASE, "Elite Black Armour") + ; + + companion object { + /** + * Map of all item ids to their [Storable]. + */ + private val idToStorable: Map by lazy { + values().flatMap { storable -> + storable.takeIds.map { id -> id to storable } + }.toMap() + } + + /** + * Set of all item ids across all [Storable]. + */ + private val allItemIds: Set by lazy { idToStorable.keys } + + /** + * Precomputed set of item ids for each Storable for fast lookup. + */ + private val storableIdSets: Map> by lazy { + values().associateWith { it.takeIds.toSet() } + } + + /** + * Returns all item ids from all storables. + */ + fun allIds(): Set = allItemIds + + /** + * Finds the storable for the given item id. + */ + fun fromId(id: Int): Storable? = idToStorable[id] + + /** + * Checks if the player owns at least one item from + * the storable in equipment or bank. + */ + fun hasStorable(player: Player, storable: Storable): Boolean { + val ownedIds = (player.equipment.toArray() + player.bank.toArray()) + .mapNotNull { it?.id } + .toSet() + return storableIdSets[storable]?.any { it in ownedIds } ?: false + } + + /** + * Checks if the player owns any item + * from any storable in equipment or bank. + */ + fun hasAnyStorable(player: Player): Boolean { + val ownedIds = (player.equipment.toArray() + player.bank.toArray()) + .mapNotNull { it?.id } + .toSet() + return allItemIds.any { it in ownedIds } + } + + /** + * Checks if the player has at least one + * item from the given storable equipped. + */ + fun hasStorableEquipped(player: Player, storable: Storable): Boolean { + val equippedIds = player.equipment.toArray().mapNotNull { it?.id }.toSet() + return storableIdSets[storable]?.any { it in equippedIds } ?: false + } + + /** + * Checks if the player has at least one + * item from the given storable in inventory. + */ + fun hasStorableInInventory(player: Player, storable: Storable): Boolean { + val inventoryIds = player.inventory.toArray().mapNotNull { it?.id }.toSet() + return storableIdSets[storable]?.any { it in inventoryIds } ?: false + } + + /** + * Gets all [Storable]s that the player owns in their bank. + */ + fun getStorablesInBank(player: Player): List { + val bankIds = player.bank.toArray().mapNotNull { it?.id }.toSet() + return values().filter { storable -> + storableIdSets[storable]?.any { it in bankIds } ?: false + } + } + } +} + diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorableFamily.kt b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorableFamily.kt new file mode 100644 index 000000000..ab8832baf --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorableFamily.kt @@ -0,0 +1,18 @@ +package content.global.skill.construction.decoration.pohstorage + +/** + * Types (families) of storables in Construction's POH Costume Room or Bookcase. + */ + +enum class StorableFamily { + FANCY_DRESS, + ARMOUR_CASE, + MAGIC_WARDROBE, + TREASURE_CHEST_LOW, + TREASURE_CHEST_MED, + TREASURE_CHEST_HIGH, + BOOKCASE, + CAPE_RACK, + CAPE_RACK_SKILL, + TOY_BOX +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageContainer.kt b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageContainer.kt new file mode 100644 index 000000000..a10cc532f --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageContainer.kt @@ -0,0 +1,74 @@ +package content.global.skill.construction.decoration.pohstorage + +import org.json.simple.JSONArray +import org.json.simple.JSONObject + +/** + * This represents the container where all the POH storable items are. + */ + +class StorageContainer { + + // item IDs stored in this container + private val stored: MutableSet = mutableSetOf() + + // page index for the active interface + private var currentPage: Int = 0 + + // functions to add item, withdraw, check for, etc. + fun addItem(id: Int) { + stored.add(id) + } + + fun withdraw(id: Int): Boolean { + return stored.remove(id) + } + + fun contains(id: Int): Boolean = id in stored + + fun getItems(): List = stored.toList() + + // paging + fun getPageIndex(): Int = currentPage + + fun nextPage(totalItems: Int, pageSize: Int) { + val next = currentPage + 1 + if (next * pageSize < totalItems) { + currentPage = next + } + } + + fun prevPage() { + if (currentPage > 0) { + currentPage-- + } + } + + fun resetPage() { + currentPage = 0 + } + + // saving to json and reading back + fun toJson(): JSONObject { + val json = JSONObject() + val items = JSONArray() + stored.forEach { items.add(it) } + json["items"] = items + return json + } + + fun readJson(json: JSONObject) { + stored.clear() + val items = json["items"] as? JSONArray ?: return + for (id in items) { + stored.add((id as Number).toInt()) + } + currentPage = 0 + } + + // clear storage + fun clear() { + stored.clear() + currentPage = 0 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageInterface.kt b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageInterface.kt new file mode 100644 index 000000000..f6d9ccf81 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageInterface.kt @@ -0,0 +1,385 @@ +package content.global.skill.construction.decoration.pohstorage + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ContainerContext +import core.net.packet.out.ContainerPacket +import org.rs09.consts.Items + +/** + * Handles the interface and interactions for + * the Construction Costume Room storage boxes and Bookshelves + * https://youtu.be/tAIDQRh4U2g?si=oDaKEJT-ZPs4MoZa&t=261 + * https://www.youtube.com/watch?v=D2aVfpPCAgY&t=41s - great view of all the treasure chests + * https://youtu.be/AK6wVwumvHY?si=XAJsQeSdRlBZSM1f - mid-level costume room + * https://www.youtube.com/watch?v=sNEOq_Barlg&t=126s - 2011, but a good video + */ +class StorageInterface : InterfaceListener { + companion object { + private const val INTERFACE = 467 + private const val COMPONENT = 164 + private const val SIZE = 30 + private const val PAGE_SIZE = SIZE - 1 + private const val BUTTON_MORE = Items.MORE_10165 + private const val BUTTON_BACK = Items.BACK_10166 + + /** + * Singleton instance of the storage interface. + */ + lateinit var instance: StorageInterface + private set + + /** + * Public method to get the storage container for a specific family. + */ + fun getStorageContainer(player: Player, type: StorableFamily) = + player.getPOHStorageState().getContainer(type) + + /** + * Opens the storage box. + * + * @param player The player. + * @param type The type of storage to open. + * @param box the specific tier of storage we are opening. + */ + fun openStorage(player: Player, type: StorableFamily, box: StorageOptionPlugin.StorageBox) { + instance.openStorageForType(player, type, box) + } + + /** + * Finds the Storable enum entry associated with a given display item ID. + */ + fun findStorableByDisplayId(id: Int): Storable? = + Storable.values().find { it.displayId == id } + } + + /** + * The attribute of whether the player has read a book or not is stored in a set of two bitfields. + * There are 70 books so that's why two longs are needed. + */ + object BookcaseBitfields { + // 0-63 + const val BOOKCASE_LOW_ATTR = "/save:bookcase_bitfield_low" + // 64-127 + const val BOOKCASE_HIGH_ATTR = "/save:bookcase_bitfield_high" + + data class BookcaseBits(var low: Long, var high: Long) + + // Retrieves both Long bitfields. + fun get(player: Player): BookcaseBits { + val low = getAttribute(player, BOOKCASE_LOW_ATTR, 0L) as? Long ?: 0L + val high = getAttribute(player, BOOKCASE_HIGH_ATTR, 0L) as? Long ?: 0L + return BookcaseBits(low, high) + } + + // Sets both Long bitfields. + fun set(player: Player, bits: BookcaseBits) { + setAttribute(player, BOOKCASE_LOW_ATTR, bits.low) + setAttribute(player, BOOKCASE_HIGH_ATTR, bits.high) + } + + // Checks if a specific bit is set within the two Longs. + fun isBitSet(bits: BookcaseBits, bitIndex: Int): Boolean { + return if (bitIndex < 64) { + (bits.low and (1L shl bitIndex)) != 0L + } else { + val highIndex = bitIndex - 64 + (bits.high and (1L shl highIndex)) != 0L + } + } + + // Sets a specific bit within the two Longs. + fun setBit(bits: BookcaseBits, bitIndex: Int): BookcaseBits { + if (bitIndex < 64) { + bits.low = bits.low or (1L shl bitIndex) + } else { + val highIndex = bitIndex - 64 + bits.high = bits.high or (1L shl highIndex) + } + return bits + } + } + + init { + instance = this + } + + override fun defineInterfaceListeners() { + on(INTERFACE) { player, _, _, buttonId, _, _ -> + val typeName = getAttribute(player, "con:storage:type", null) as? String ?: return@on true + val type = StorableFamily.valueOf(typeName.uppercase()) + handleStorageInteraction(player, buttonId, type) + return@on true + } + } + + /** + * Gets the StorableFamilies that should be displayed in the interface for a given primary type. + * This handles the special case for the Cape Rack because capes are classified as two different families/types + * (normal and skillcape) but displayed in the same storage. + */ + private fun getFamiliesToDisplay(primaryType: StorableFamily): List { + return when (primaryType) { + // if the cape rack can hold skill capes, also show normal capes + StorableFamily.CAPE_RACK_SKILL -> listOf(StorableFamily.CAPE_RACK, StorableFamily.CAPE_RACK_SKILL) + // else only display the items for the primary family + else -> listOf(primaryType) + } + } + + /** + * This handles filtering the list for books. + * Only items are shown that have already been read. + * If the book is part of a quest, the quest must be complete before it shows up in the POH. + * If the index is -1 it is not a book, and not filtered. + */ + private fun getFilteredItems(player: Player, families: List, type: StorableFamily): List { + // filter for normal items + var allItems = Storable.values().filter { it.type in families } + + // filter for bookcase + if (type == StorableFamily.BOOKCASE) { + val bookcaseBits = BookcaseBitfields.get(player) + allItems = allItems.filter { storable -> + // check if read + val isRead = if (storable.bitIndex == -1) true else BookcaseBitfields.isBitSet(bookcaseBits, storable.bitIndex) + // check if quest is done + val questMet = storable.questReq == null || isQuestComplete(player, storable.questReq) + isRead && questMet + } + } + + return allItems + } + + /** + * Handles interaction with storage interface. + */ + private fun handleStorageInteraction(player: Player, buttonId: Int, type: StorableFamily) { + val container = getStorageContainer(player, type) + val families = getFamiliesToDisplay(type) + val allItems = getFilteredItems(player, families, type) + val pageIndex = container.getPageIndex() + + val pageItems = allItems.drop(pageIndex * PAGE_SIZE).take(PAGE_SIZE) + val slots = MutableList(SIZE) { null } + + var idx = 0 + pageItems.forEach { + if (idx >= SIZE) return@forEach + slots[idx++] = it + } + + val hasPrev = pageIndex > 0 + val hasNext = allItems.size > (pageIndex + 1) * PAGE_SIZE + + if (hasNext && idx < SIZE) slots[idx++] = "MORE" + if (hasPrev && idx < SIZE) slots[idx] = "BACK" + + val slotIndex = when { + buttonId in 56..(56 + (SIZE - 1) * 2) step 2 -> (buttonId - 56) / 2 + buttonId in 165..223 step 2 -> (buttonId - 165) / 2 + else -> return + } + + when (val clicked = slots.getOrNull(slotIndex)) { + "MORE" -> { + container.nextPage(allItems.size, PAGE_SIZE) + openInterface(player, INTERFACE) + updateStorageInterface(player, type) + } + "BACK" -> { + container.prevPage() + openInterface(player, INTERFACE) + updateStorageInterface(player, type) + } + is Storable -> processItemTransaction(player, clicked, type) + } + } + + /** + * Handles taking or depositing an item from/to the storage. + */ + private fun processItemTransaction(player: Player, item: Storable, type: StorableFamily) { + // container for the interface/capacity check based on the object the player clicked + val interfaceContainer = getStorageContainer(player, type) + + // container for the actual storage/retrieval based on the item's family + val targetContainer = getStorageContainer(player, item.type) + + // get stored items from the target container + val storedItems = targetContainer.getItems().toSet() + + val box = getAttribute(player, "con:storage:box", null) as? StorageOptionPlugin.StorageBox ?: return + val capacity = box.capacity + + // gets the currently stored IDs + val storedTakeIds = item.takeIds.filter { it in storedItems } + + if (storedTakeIds.isNotEmpty()) { + // withdraw items + if (freeSlots(player) < storedTakeIds.size) { + sendMessage(player, "You don't have enough inventory space.") + return + } + sendMessage(player, "You take the item from the box.") + + storedTakeIds.forEach { id -> + addItem(player, id, 1) + targetContainer.withdraw(id) + } + } else { + // deposit items + + // capacity check + if (capacity < Int.MAX_VALUE) { + + val familyToCheck = when (type) { + // for cape racks, only skillcapes are counted against the capacity + StorableFamily.CAPE_RACK_SKILL -> StorableFamily.CAPE_RACK_SKILL + // for all other storage, check against the primary family type for capacity + else -> type + } + + // check if skillcape + if (item.type == familyToCheck) { + + val capacityCheckItems = interfaceContainer.getItems().toSet() + + // calculate stored skillcapes + val storedSetsCount = Storable.values() + .filter { it.type == familyToCheck } + .count { storable -> + storable.takeIds.any { it in capacityCheckItems } + } + + // enforce capacity limits + if (storedSetsCount >= capacity) { + val message = when (familyToCheck) { + StorableFamily.CAPE_RACK_SKILL -> "You cannot store any more skillcapes in this container." + else -> "You cannot store any more items in this container." + } + sendMessage(player, message) + return + } + } + } + + val presentTakeIds = item.takeIds.filter { player.inventory.contains(it, 1) } + + if (presentTakeIds.isEmpty()) { + sendMessage(player, "You don't have that item in your inventory.") + return + } + sendMessage(player, "You put the item into the box.") + + presentTakeIds.forEach { id -> + removeItem(player, Item(id)) + targetContainer.addItem(id) + } + } + updateStorageInterface(player, type) + } + + private fun updateStorageInterface(player: Player, type: StorableFamily) { + val container = getStorageContainer(player, type) + val families = getFamiliesToDisplay(type) + val allItems = getFilteredItems(player, families, type) + val allStoredItems = mutableSetOf() + + families.forEach { family -> + val familyContainer = getStorageContainer(player, family) + allStoredItems.addAll(familyContainer.getItems()) + } + + val stored = allStoredItems.toSet() + val pageIndex = container.getPageIndex() + + val pageItems = allItems.drop(pageIndex * PAGE_SIZE).take(PAGE_SIZE) + val slots = MutableList(SIZE) { null } + + var idx = 0 + pageItems.forEach { + if (idx >= SIZE) return@forEach + slots[idx++] = it + } + + val hasPrev = pageIndex > 0 + val hasNext = allItems.size > (pageIndex + 1) * PAGE_SIZE + + if (hasNext && idx < SIZE) slots[idx++] = "MORE" + if (hasPrev && idx < SIZE) slots[idx] = "BACK" + + // names each box + val title = when { + type.name.contains("FANCY_DRESS") -> "Fancy dress box" + type.name.contains("TOY_BOX") -> "Toy box" + type.name.contains("MAGIC_WARDROBE") -> "Magic wardrobe" + type.name.contains("ARMOUR_CASE") -> "Armour case" + type.name.contains("BOOKCASE") -> "Bookcase" + type.name.contains("CAPE_RACK") -> "Cape rack" + type.name.contains("TREASURE_CHEST_LOW") -> "Low-level Treasure Trail rewards" + type.name.contains("TREASURE_CHEST_MED") -> "Medium-level Treasure Trail rewards" + type.name.contains("TREASURE_CHEST_HIGH") -> "High-level Treasure Trail rewards" + + // to catch any other name + else -> type.name.lowercase().replaceFirstChar(Char::titlecase) + " box" + } + // child 225 is the title block + setInterfaceText(player, title, INTERFACE, 225) + + val itemsArray = slots.mapNotNull { + when (it) { + is Storable -> Item(it.displayId) + "MORE" -> Item(BUTTON_MORE) + "BACK" -> Item(BUTTON_BACK) + else -> null + } + }.toTypedArray() + + PacketRepository.send( + ContainerPacket::class.java, + ContainerContext(player, INTERFACE, COMPONENT, SIZE, itemsArray, false) + ) + + repeat(SIZE) { i -> + val nameComponent = 55 + i * 2 + val iconComponent = 165 + i * 2 + val hiddenIconComponent = 166 + i * 2 + + val obj = slots[i] + val (name, isStored) = when (obj) { + is Storable -> { + val isStored = obj.takeIds.any { it in stored } + obj.setName to isStored + } + "MORE" -> "More..." to true + "BACK" -> "Back..." to true + else -> "" to false + } + + setInterfaceText(player, name, INTERFACE, nameComponent) + setComponentVisibility(player, INTERFACE, nameComponent, false) + + if (obj is Storable) { + // this displays if the items are stored or not stored + setComponentVisibility(player, INTERFACE, iconComponent, !isStored) + setComponentVisibility(player, INTERFACE, hiddenIconComponent, isStored) + } else { + // this is for navigation buttons or empty slots + setComponentVisibility(player, INTERFACE, iconComponent, true) + setComponentVisibility(player, INTERFACE, hiddenIconComponent, true) + } + } + } + + private fun openStorageForType(player: Player, type: StorableFamily, box: StorageOptionPlugin.StorageBox) { + setAttribute(player, "con:storage:type", type.name) + setAttribute(player, "con:storage:box", box) + openInterface(player, INTERFACE) + updateStorageInterface(player, type) + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageOptionPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageOptionPlugin.kt new file mode 100644 index 000000000..549b543d0 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageOptionPlugin.kt @@ -0,0 +1,182 @@ +package content.global.skill.construction.decoration.pohstorage + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.Sounds +import org.rs09.consts.Scenery as Obj + +/** + * Handles interactions with storage objects. + */ +@Initializable +class StorageOptionPlugin : OptionHandler() { + + /** + * Represents all storage boxes & configuration. + */ + enum class StorageBox(val objectIds: IntArray, val storableFamily: StorableFamily? = null, val openable: Boolean = false, val closable: Boolean = false, val capacity: Int = Int.MAX_VALUE) { + + /* Bookcase + * Wooden: all + * Oak: all + * Mahogany: all */ + BOOKCASE(intArrayOf(Obj.BOOKCASE_13597, Obj.BOOKCASE_13598, Obj.BOOKCASE_13599), StorableFamily.BOOKCASE), + + /* Cape Rack + * Oak: normal capes + * Teak: 1 skillcape + * Mahogany: 5 skillcapes + * Gilded: 10 skillcapes + * Marble: all + * Magic: all */ + CAPE_RACK(intArrayOf(Obj.OAK_CAPE_RACK_18766), StorableFamily.CAPE_RACK), + CAPE_RACK_ONE(intArrayOf(Obj.TEAK_CAPE_RACK_18767), StorableFamily.CAPE_RACK_SKILL, capacity = 1), + CAPE_RACK_FIVE(intArrayOf(Obj.MAHOGANY_CAPE_RACK_18768), StorableFamily.CAPE_RACK_SKILL, capacity = 5), + CAPE_RACK_TEN(intArrayOf(Obj.GILDED_CAPE_RACK_18769), StorableFamily.CAPE_RACK_SKILL, capacity = 10), + CAPE_RACK_ALL(intArrayOf(Obj.MARBLE_CAPE_RACK_18770, Obj.MAGIC_CAPE_RACK_18771), StorableFamily.CAPE_RACK_SKILL), + + /* Fancy Dress Box + * Oak: 2 + * Teak: 4 + * Mahogany: all */ + FANCY_BOX_2(intArrayOf(Obj.FANCY_DRESS_BOX_18773), StorableFamily.FANCY_DRESS, false, true, 2), + FANCY_BOX_4(intArrayOf(Obj.FANCY_DRESS_BOX_18775), StorableFamily.FANCY_DRESS, false, true, 4), + FANCY_BOX_ALL(intArrayOf(Obj.FANCY_DRESS_BOX_18777), StorableFamily.FANCY_DRESS, false, true), + FANCY_BOX_OPEN(intArrayOf(Obj.FANCY_DRESS_BOX_18772, Obj.FANCY_DRESS_BOX_18774, Obj.FANCY_DRESS_BOX_18776), openable = true), + + /* Toy Box + * Oak: all + * Teak: all + * Mahogany: all */ + TOY_BOX_OPEN(intArrayOf(Obj.TOY_BOX_18798, Obj.TOY_BOX_18800, Obj.TOY_BOX_18802), openable = true), + TOY_BOX_CLOSE(intArrayOf(Obj.TOY_BOX_18799, Obj.TOY_BOX_18801, Obj.TOY_BOX_18803), closable = true, storableFamily = StorableFamily.TOY_BOX), + + /* Treasure Chest + * Oak: Low + * Teak: Low, Medium + * Mahogany: Low, Medium, High */ + TREASURE_LOW(intArrayOf(Obj.TREASURE_CHEST_18805), StorableFamily.TREASURE_CHEST_LOW), + TREASURE_MED(intArrayOf(Obj.TREASURE_CHEST_18807), StorableFamily.TREASURE_CHEST_MED), + TREASURE_HIGH(intArrayOf(Obj.TREASURE_CHEST_18809), StorableFamily.TREASURE_CHEST_HIGH), + TREASURE_OPEN(intArrayOf(Obj.TREASURE_CHEST_18804, Obj.TREASURE_CHEST_18806, Obj.TREASURE_CHEST_18808), openable = true), + + /* Magic Wardobe + * Oak: 1 set + * Carved oak: 2 sets + * Teak: 3 sets + * Carved Teak: 4 sets + * Mahogany: 5 sets + * Gilded: 6 sets + * Marble: all sets */ + WARDROBE_1(intArrayOf(Obj.MAGIC_WARDROBE_18785), StorableFamily.MAGIC_WARDROBE, false, true, 1), + WARDROBE_2(intArrayOf(Obj.MAGIC_WARDROBE_18787), StorableFamily.MAGIC_WARDROBE, false, true, 2), + WARDROBE_3(intArrayOf(Obj.MAGIC_WARDROBE_18789), StorableFamily.MAGIC_WARDROBE, false, true, 3), + WARDROBE_4(intArrayOf(Obj.MAGIC_WARDROBE_18791), StorableFamily.MAGIC_WARDROBE, false, true, 4), + WARDROBE_5(intArrayOf(Obj.MAGIC_WARDROBE_18793), StorableFamily.MAGIC_WARDROBE, false, true, 5), + WARDROBE_6(intArrayOf(Obj.MAGIC_WARDROBE_18795), StorableFamily.MAGIC_WARDROBE, false, true, 6), + WARDROBE_ALL(intArrayOf(Obj.MAGIC_WARDROBE_18797), StorableFamily.MAGIC_WARDROBE), + WARDROBE_OPEN(intArrayOf(Obj.MAGIC_WARDROBE_18784, Obj.MAGIC_WARDROBE_18786, Obj.MAGIC_WARDROBE_18788, Obj.MAGIC_WARDROBE_18790, Obj.MAGIC_WARDROBE_18792, Obj.MAGIC_WARDROBE_18794, Obj.MAGIC_WARDROBE_18796), openable = true), + + /* Armour Case + * Oak: 2 + * Teak: 4 + * Mahogany: all */ + ARMOUR_2(intArrayOf(Obj.ARMOUR_CASE_18779), StorableFamily.ARMOUR_CASE, false, true, 2), + ARMOUR_4(intArrayOf(Obj.ARMOUR_CASE_18781), StorableFamily.ARMOUR_CASE, false, true, 4), + ARMOUR_ALL(intArrayOf(Obj.ARMOUR_CASE_18783), StorableFamily.ARMOUR_CASE), + ARMOUR_OPEN(intArrayOf(Obj.ARMOUR_CASE_18778, Obj.ARMOUR_CASE_18780, Obj.ARMOUR_CASE_18782), openable = true) + } + + private val allBoxes = StorageBox.values() + + override fun newInstance(arg: Any?): Plugin { + allBoxes.forEach { box -> + box.objectIds.forEach { id -> + SceneryDefinition.forId(id)?.let { def -> + if (box.storableFamily != null) def.handlers["option:search"] = this + if (box.openable) def.handlers["option:open"] = this + if (box.closable) def.handlers["option:close"] = this + } + } + } + return this + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + val obj = node as Scenery + val box = allBoxes.firstOrNull { obj.id in it.objectIds } ?: return true + + when (option) { + "search" -> { + when (obj.id) { + // special handling for med and high level treasure chests since they have a dialogue option first + Obj.TREASURE_CHEST_18807 -> { + sendDialogueOptions(player, "What sort of Treasure Trail items do you want to see?", "Low-level rewards", "Medium-level rewards") + addDialogueAction(player) { p, button -> + val family = when (button) { + 2 -> StorableFamily.TREASURE_CHEST_LOW + 3 -> StorableFamily.TREASURE_CHEST_MED + else -> null + } + family?.let { StorageInterface.openStorage(p, it, box) } + return@addDialogueAction + } + } + Obj.TREASURE_CHEST_18809 -> { + sendDialogueOptions(player, "What sort of Treasure Trail items do you want to see?", "Low-level rewards", "Medium-level rewards", "High-level rewards") + addDialogueAction(player) { p, button -> + val family = when (button) { + 2 -> StorableFamily.TREASURE_CHEST_LOW + 3 -> StorableFamily.TREASURE_CHEST_MED + 4 -> StorableFamily.TREASURE_CHEST_HIGH + else -> null + } + family?.let { StorageInterface.openStorage(p, it, box) } + return@addDialogueAction + } + } + // bookcases need to re-store the games book in them on open. I think the bookshelf is the only source. + Obj.BOOKCASE_13597 -> { + storeBookInHouse(player, Items.GAME_BOOK_7681) + box.storableFamily?.let { StorageInterface.openStorage(player, it, box) } + } + Obj.BOOKCASE_13598 -> { + storeBookInHouse(player, Items.GAME_BOOK_7681) + box.storableFamily?.let { StorageInterface.openStorage(player, it, box) } + } + Obj.BOOKCASE_13599 -> { + storeBookInHouse(player, Items.GAME_BOOK_7681) + box.storableFamily?.let { StorageInterface.openStorage(player, it, box) } + } + else -> { + // default open for rest + box.storableFamily?.let { StorageInterface.openStorage(player, it, box) } + } + } + } + "open" -> if (box.openable) openBox(player, obj) + "close" -> if (box.closable) closeBox(player, obj) + } + return true + } + + private fun openBox(player: Player, obj: Scenery) { + playAudio(player, Sounds.CHEST_OPEN_52) + animate(player, Animations.HUMAN_OPEN_CHEST_536) + replaceScenery(obj, obj.id + 1, -1) + } + + private fun closeBox(player: Player, obj: Scenery) { + playAudio(player, Sounds.CHEST_CLOSE_51) + animate(player, 538) + replaceScenery(obj, obj.id - 1, -1) + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageState.kt b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageState.kt new file mode 100644 index 000000000..9108a6013 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/pohstorage/StorageState.kt @@ -0,0 +1,37 @@ +package content.global.skill.construction.decoration.pohstorage + +import org.json.simple.JSONObject +import core.game.node.entity.player.Player + +class StorageState(val player: Player) { + + private val containers = StorableFamily.values().associateWith { StorageContainer() }.toMutableMap() + + fun getContainer(type: StorableFamily): StorageContainer = containers[type]!! + + fun toJson(): JSONObject { + val root = JSONObject() + val containerData = JSONObject() + + containers.forEach { (group, container) -> + containerData[group.name.lowercase()] = container.toJson() + } + + root["containers"] = containerData + return root + } + + fun readJson(data: JSONObject) { + val containerData = data["containers"] as? JSONObject ?: return + + for (group in StorableFamily.values()) { + val json = containerData[group.name.lowercase()] as? JSONObject ?: continue + containers[group]?.readJson(json) + } + } + + // clear storage + fun clear() { + containers.values.forEach { it.clear() } + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java index 3c658fec2..c154bef68 100644 --- a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java +++ b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java @@ -1,6 +1,7 @@ package content.global.skill.construction.decoration.portalchamber; +import content.data.Quests; import content.global.skill.construction.Hotspot; import content.global.skill.runecrafting.Rune; import core.cache.def.impl.SceneryDefinition; @@ -17,6 +18,9 @@ import core.plugin.Initializable; import core.plugin.Plugin; import core.plugin.ClassScanner; +import static content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE; +import static core.api.ContentAPIKt.*; + /** * PortalChamberPlugin * @author Clayton Williams @@ -87,9 +91,14 @@ public class PortalChamberPlugin extends OptionHandler { } for (Locations l : Locations.values()) { if (l.name().contains(identifier)) { + if ((l == Locations.ARDOUGNE && !getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)) || + (l == Locations.KHARYRLL && !isQuestComplete(player, Quests.DESERT_TREASURE))) { + sendMessage(player, "You do not have the requirements to direct the portal there."); + return; + } Item[] runes = l.runes; if (!player.getInventory().containsItems(runes)) { - player.sendMessage("You do not have the required runes to build this portal"); + sendMessage(player, "You do not have the required runes to build this portal."); return; } player.getInventory().remove(runes); diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt index 44c9750a9..b5196af4d 100644 --- a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt +++ b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt @@ -1,66 +1,72 @@ package content.global.skill.construction.decoration.questhall +import content.data.EnchantedJewellery +import content.global.handlers.item.EnchantedJewelleryListener.EnchantedJewelleryDialogueFile +import core.api.delayScript +import core.api.lock +import core.api.openDialogue import core.api.playGlobalAudio +import core.api.queueScript +import core.api.resetAnimator +import core.api.stopExecuting import core.api.teleport +import core.api.visualize import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.Node import core.game.node.entity.player.Player -import core.game.system.task.Pulse -import core.game.world.map.Location +import core.game.node.item.Item +import core.game.node.scenery.Scenery import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items import org.rs09.consts.Sounds -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit class MountedGlory : InteractionListener { - val MOUNTED_GLORY = 13523 - - val TELEPORTS = arrayOf( - Location.create(3087, 3495, 0), - Location.create(2919, 3175, 0), - Location.create(3104, 3249, 0), - Location.create(3304, 3124, 0) - ) + val TELEPORTS = EnchantedJewellery.AMULET_OF_GLORY.locations override fun defineListeners() { - on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, _ -> - mountedGloryTeleport(player,0) + on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, `object` -> + mountedGloryAction(player, `object`, 0) return@on true } - - on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, _ -> - mountedGloryTeleport(player,1) + on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, `object` -> + mountedGloryAction(player, `object`, 1) return@on true } - - on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, _ -> - mountedGloryTeleport(player,2) + on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, `object` -> + mountedGloryAction(player, `object`, 2) return@on true } - - on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, _ -> - mountedGloryTeleport(player,3) + on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, `object` -> + mountedGloryAction(player, `object`, 3) + return@on true + } + on(MOUNTED_GLORY, IntType.SCENERY, "Rub") { player, _ -> + openDialogue(player,EnchantedJewelleryDialogueFile(EnchantedJewellery.AMULET_OF_GLORY, Item(Items.AMULET_OF_GLORY4_1712), false, false)) return@on true } } - private fun mountedGloryTeleport(player : Player, int : Int) { - Executors.newSingleThreadScheduledExecutor().schedule({ - player.pulseManager.run(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 1 -> { - player.lock(5) - player.visualize(Animation(714), Graphics(308, 100, 50)) - playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) - } - 4 -> player.animator.reset().also { teleport(player, TELEPORTS[int]) } - } - return false + private fun mountedGloryAction(player : Player, `object` : Node, int : Int) { + if (player.houseManager.isBuildingMode) { + player.dialogueInterpreter.open("con:removedec", `object` as Scenery) + return + } + if (!player.zoneMonitor.teleport(1, Item(Items.AMULET_OF_GLORY_1704))) { + return + } + queueScript(player, 0, QueueStrength.SOFT) { stage -> + if (stage == 0) { + lock(player, 4) + visualize(player, Animation(714), Graphics(308, 100, 50)) + playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) } - }) - }, 0, TimeUnit.SECONDS) + resetAnimator(player) + teleport(player, TELEPORTS[int]) + return@queueScript stopExecuting(player) + } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java deleted file mode 100644 index 90d96eb80..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java +++ /dev/null @@ -1,98 +0,0 @@ -package content.global.skill.construction.decoration.questhall; - - -import core.cache.def.impl.SceneryDefinition; -import core.game.dialogue.DialogueAction; -import core.game.dialogue.DialogueInterpreter; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -import static core.api.ContentAPIKt.playGlobalAudio; - -/** - * Handles the POH Mounted Glory. - * @author Splinter - */ -@Initializable -public class MountedGloryPlugin extends OptionHandler { - - /** - * Represents the teleport animation. - */ - private static final Animation ANIMATION = new Animation(714); - - /** - * Represents the graphics to use. - */ - private static final Graphics GRAPHICS = new Graphics(308, 100, 50); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(13523).getHandlers().put("option:rub", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - DialogueInterpreter interpreter = player.getDialogueInterpreter(); - interpreter.sendOptions("Select a location.", "Edgeville", "Karamja", "Draynor Village", "Al-Kharid", "Nowhere."); - interpreter.addAction(new DialogueAction() { - - @Override - public void handle(Player player, int buttonId) { - switch (buttonId) { - case 2: - teleport(player, Location.create(3087, 3495, 0)); - break; - case 3: - teleport(player, Location.create(2919, 3175, 0)); - break; - case 4: - teleport(player, Location.create(3081, 3250, 0)); - break; - case 5: - teleport(player, Location.create(3304, 3124, 0)); - break; - } - } - - }); - return true; - } - - /** - * Method used to teleport to a location. - * @param player the player. - * @param location the location. - */ - private boolean teleport(final Player player, final Location location) { - if (player.isTeleBlocked()) { - player.sendMessage("A magical force has stopped you from teleporting."); - return false; - } - player.lock(); - player.visualize(ANIMATION, GRAPHICS); - playGlobalAudio(player.getLocation(), Sounds.TELEPORT_ALL_200); - player.getImpactHandler().setDisabledTicks(4); - GameWorld.getPulser().submit(new Pulse(4, player) { - @Override - public boolean pulse() { - player.unlock(); - player.getProperties().setTeleportLocation(location); - player.getAnimator().reset(); - return true; - } - }); - return true; - } - -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/skillhall/MountedCockatriceHead.kt b/Server/src/main/content/global/skill/construction/decoration/skillhall/MountedCockatriceHead.kt new file mode 100644 index 000000000..54472597e --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/skillhall/MountedCockatriceHead.kt @@ -0,0 +1,68 @@ +package content.global.skill.construction.decoration.skillhall + +import content.global.skill.construction.HouseManager +import core.api.openDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.repository.Repository +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery as Sceneries + +class MountedCockatriceHead : InteractionListener { + override fun defineListeners() { + on(Sceneries.COCKATRICE_HEAD_13482, IntType.SCENERY, "talk-to") { player, _ -> + val house = player.getAttribute("poh_entry", player.houseManager) + if (house == player.houseManager) { + openDialogue(player, MountedCockatriceHeadOwnerDialogue()) + } else { + val ownerName = Repository.players.first { it.houseManager == house }.username.capitalize() + openDialogue(player, MountedCockatriceHeadGuestDialogue(ownerName)) + } + return@on true + } + } +} + +class MountedCockatriceHeadOwnerDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_NORMAL, "You deaded me!").also { stage++ } + 1 -> playerl(FacialExpression.NEUTRAL, "Well, yes.").also { stage++ } + 2 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_NORMAL, "What did you do that for?").also { stage++ } + 3 -> options("A Slayer Master told me to.", "So I could mount your head on my wall.", "I just wanted to.").also { stage++ } + 4 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "A Slayer Master told me to.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "So I could mount your head on my wall.").also { stage = 20 } + 3 -> playerl(FacialExpression.NEUTRAL, "I just wanted to.").also { stage = 30 } + } + 10 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_SAD, "Why do the Slayer Masters all pick on poor cockatrice?").also { stage++ } + 11 -> playerl(FacialExpression.NEUTRAL, "They pick on lots of other creatures too.").also { stage++ } + 12 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_SAD, "Then mount one of them on your wall and let poor cockatrice rest in peace!").also { stage = END_DIALOGUE } + 20 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_SAD, "Another cockatrice falls victim to the dreaded mirror shield!").also { stage++ } + 21 -> playerl(FacialExpression.NEUTRAL, "Don't take it personally. You look good on my wall.").also { stage++ } + 22 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_SAD, "I don't care! I think I looked better with a body!").also { stage = END_DIALOGUE } + 30 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_ANGRY, "You dirty rotten swine, you!").also { stage++ } + 31 -> playerl(FacialExpression.AMAZED, "Steady on.").also { stage++ } + 32 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_ANGRY, "I will kill you with my paralyzing-type magic eyes look!").also { stage++ } + 33 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_ANGRY, "Dots appear in air between eyes and victim. Dot! Dot! Dotty!").also { stage++ } + 34 -> playerl(FacialExpression.NEUTRAL, "Er, nothing's happening...").also { stage++ } + 35 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_ANGRY, "Concentrates mental power. Eyes narrow beak clenches veins on head stand out.").also { stage++ } + 36 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_ANGRY, "Strain!").also { stage++ } + 37 -> playerl(FacialExpression.ASKING, "You're dead, cockatrice. Your eyes are glass beads. It won't work.").also { stage++ } + 38 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_ANGRY, "STRA-A-AIN!").also { stage++ } + 39 -> playerl(FacialExpression.ASKING, "I think I'll leave you to it.").also { stage = END_DIALOGUE } + } + } +} + +class MountedCockatriceHeadGuestDialogue(private val ownerName: String) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> playerl(FacialExpression.HAPPY, "Hey, a cockatrice!").also { stage++ } + 1 -> npcl(NPCs.COCKATRICE_4227, FacialExpression.CHILD_SAD, "$ownerName deaded me! That wasn't very nice!").also { stage = END_DIALOGUE } + } + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt index 826056ce3..eb4accf67 100644 --- a/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt +++ b/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt @@ -10,6 +10,7 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills import content.global.skill.construction.Decoration +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE import core.game.node.entity.combat.spell.MagicStaff import core.game.node.item.Item import core.game.system.task.Pulse @@ -84,6 +85,11 @@ class LecternPlugin : OptionHandler() { player.sendMessages("You need the Bones to Peaches ability purchased from MTA before making these.", "This requirement doesn't apply to actually using the tabs.") return false } + if(this == ARDOUGNE && !getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)){ + sendMessage(player, "You need to unlock Ardougne teleport before you can make a tablet.") + return false + + } var found = false for (d in requiredDecorations) if (d.objectId == objectId) found = true if (!found) { diff --git a/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt b/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt index 6149fae5e..ea1d8c783 100644 --- a/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt +++ b/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt @@ -26,25 +26,31 @@ class TelescopePlugin : OptionHandler() { } override fun handle(player: Player?, node: Node?, option: String?): Boolean { + val obj = node?.asScenery() as Scenery val star = ShootingStarPlugin.getStar() val delay: Int = 25000 + (25000 / 3) val timeLeft = delay - star.ticks - val fakeTimeLeftBecauseFuckPlayers = TimeUnit.MILLISECONDS.toMinutes(timeLeft * 600L) + if(RandomFunction.random(0,100) % 2 == 0) 2 else -2 - val obj = node?.asScenery() as Scenery + val window = when (obj.id) { + 13657 -> 9 + 13658 -> 2 + else -> 24 + } + val fakeTimeLeft = RandomFunction.random(-window, window+1) + TimeUnit.MILLISECONDS.toMinutes(timeLeft * 600L) player?.lock() player?.animate(ANIMATION) - player?.interfaceManager?.open(Component(782)).also { player?.unlock() - Pulser.submit(object : Pulse(2, player) { - override fun pulse(): Boolean { - if (obj.isActive) { - player?.dialogueInterpreter?.sendDialogue("You see a shooting star! The star looks like it will land","in about $fakeTimeLeftBecauseFuckPlayers minutes!") + player?.interfaceManager?.open(Component(782)).also { + player?.unlock() + Pulser.submit(object : Pulse(2, player) { + override fun pulse(): Boolean { + if (obj.isActive) { + player?.dialogueInterpreter?.sendDialogue("You see a shooting star! The star looks like it will land","in about $fakeTimeLeft minutes!") + return true + } return true } - return true - } - }) - return true - } + }) + return true + } } companion object { diff --git a/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt b/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt index b30f862d1..44a050754 100644 --- a/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt +++ b/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt @@ -4,8 +4,7 @@ import core.game.dialogue.DialoguePlugin import content.data.RepairItem import core.game.interaction.NodeUsageEvent import core.game.interaction.UseWithHandler -import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment -import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment.BarrowsFullEquipment +import content.global.handlers.item.equipment.BarrowsEquipment import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item @@ -14,8 +13,10 @@ import core.plugin.Plugin import kotlin.math.ceil import org.rs09.consts.Items +private val ALL_REPAIRABLE_ITEM_IDS = (RepairItem.repairableItemIds + BarrowsEquipment.getAllRepairableBarrowsIds()).toIntArray() + @Initializable -class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998){ +class ArmourStand : UseWithHandler(*ALL_REPAIRABLE_ITEM_IDS) { override fun newInstance(arg: Any?): Plugin { addHandler(13715, OBJECT_TYPE, this) return this @@ -24,76 +25,90 @@ class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474, override fun handle(event: NodeUsageEvent?): Boolean { event ?: return false val player = event.player - val repairItem = RepairItem.forId(event.used.id) + val usedItem = event.used.asItem() - var baseCost = 0.0 + var baseCost = 0 var product: Item? = null - if(repairItem != null){ - baseCost = repairItem.cost * 1.0 - product = repairItem.product - } else if(BarrowsEquipment.isBarrowsItem(event.used.id)){ - //Begin terrible code thanks to Vexia - val type = BarrowsEquipment.formatedName(event.used.id) - val single = BarrowsEquipment.getSingleName(type) - val equipment = BarrowsEquipment.getEquipmentType(type) - val newString = type.toLowerCase().replace(single, "").trim { it <= ' ' }.replace("'s", "") - val newewString = StringBuilder() - newewString.append(newString).append(" $equipment") - val fullequip = BarrowsFullEquipment.forName(newewString.toString()) - baseCost = BarrowsEquipment.getFormatedCost(equipment,event.used.asItem()) * 1.0 - product = fullequip.full - //End terrible code thanks to Vexia - } + val repairItem = RepairItem.forId(usedItem.id) + val barrowsDef = BarrowsEquipment.getDefinition(usedItem.id) - if((repairItem == null && baseCost == 0.0)){ + if (repairItem != null) { + baseCost = repairItem.cost + product = repairItem.product + } else if (barrowsDef != null) { + if (BarrowsEquipment.isFullyRepaired(event.used.id)) { + player.sendMessage("That item can't be repaired.") + return true + } + baseCost = BarrowsEquipment.getRepairCost(usedItem) + product = Item(barrowsDef.repairedId) + } else { player.sendMessage("That item can't be repaired.") return true } - val cost: Int = ceil(((100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0) ) / 100.0) * baseCost).toInt() - - player.dialogueInterpreter.open(58824213,event.used,cost,product) + val discountMultiplier = (100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0)) / 100.0 + val cost = ceil(discountMultiplier * baseCost).toInt() + player.dialogueInterpreter.open(58824213,usedItem, cost, product) return true } @Initializable - class RepairDialogue(player: Player? = null) : DialoguePlugin(player){ - override fun newInstance(player: Player?): DialoguePlugin { - return RepairDialogue(player) - } - var item: Item? = null - var cost: Int = 0 - var product: Item? = null + class RepairDialogue(player: Player? = null) : DialoguePlugin(player) { + + private var item: Item? = null + private var cost: Int = 0 + private var product: Item? = null + + override fun newInstance(player: Player?): DialoguePlugin = RepairDialogue(player) override fun open(vararg args: Any?): Boolean { item = args[0] as Item cost = args[1] as Int product = args[2] as Item - player.dialogueInterpreter.sendDialogue("Would you like to repair your ${(item as Item).name.toLowerCase()}","for $cost gp?") + + val itemName = item?.name?.lowercase() ?: "item" + player.dialogueInterpreter.sendDialogue( + "Would you like to repair your $itemName", + "for $cost gp?" + ) stage = 0 return true } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - item ?: return false - product ?: return false - when(stage){ - 0 -> options("Yes, please","No, thanks").also{stage++} - 1 -> when(buttonId){ - 1 -> exchangeItems(item as Item,cost,product as Item).also { end() } + val currentItem = item ?: return false + val currentProduct = product ?: return false + + when (stage) { + 0 -> { + options("Yes, please", "No, thanks") + stage++ + } + 1 -> when (buttonId) { + 1 -> { + exchangeItems(currentItem, cost, currentProduct) + end() + } 2 -> end() } } return true } - fun exchangeItems(item: Item, cost: Int, product: Item) { + private fun exchangeItems(item: Item, cost: Int, product: Item) { val coins = Item(Items.COINS_995, cost) + if (player.inventory.containsItem(coins) && player.inventory.containsItem(item)) { - player.inventory.remove(item, coins) - player.inventory.add(product) - player.sendMessage("You repair your ${product.name.toLowerCase()} for $cost.") + if (player.inventory.remove(item, coins)) { + if (player.inventory.add(product)) { + val costText = if (cost > 0) "${cost}gp" else "free" + player.sendMessage("You repair your ${product.name.lowercase()} for $costText.") + return + } + } + player.sendMessage("Report this to an administrator!") } else { player.sendMessage("You can't afford that.") } diff --git a/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.java b/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.java deleted file mode 100644 index 2341c3a2a..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.java +++ /dev/null @@ -1,171 +0,0 @@ -package content.global.skill.construction.decoration.workshop; - - -import core.cache.def.impl.ItemDefinition; -import core.cache.def.impl.SceneryDefinition; -import core.plugin.Initializable; -import core.game.dialogue.DialogueInterpreter; -import core.game.dialogue.DialoguePlugin; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.plugin.Plugin; -import core.plugin.ClassScanner; - -import java.util.ArrayList; -import java.util.List; - -/** - * Handles the 5 types of tool stores - * ToolsPlugin.java - * @author Clayton Williams - * @date Oct 29, 2015 - * - */ -@Initializable -public class ToolsPlugin extends OptionHandler { - - /** - * The different tool stores - * @author Clayton Williams - * @date Oct 29, 2015 - */ - private enum ToolStore { - - TOOLSTORE_1(13699, 8794, 1755, 2347, 1735), - TOOLSTORE_2(13700, 1925, 952, 590), - TOOLSTORE_3(13701, 1757, 1785, 1733), - TOOLSTORE_4(13702, 1595, 1597, 1592, 1599, 5523), - TOOLSTORE_5(13703, 5341, 952, 676, 5343, 5331); - - /** - * The object id of the tool store - */ - private int objectId; - - /** - * The tools included - */ - private int[] tools; - - /** - * ToolStore - * @param objectId - * @param tools - */ - ToolStore(int objectId, int... tools) { - this.objectId = objectId; - this.tools = tools; - } - - /** - * Gets the toolstore from an object id - * @param objectId - the object id - * @return - */ - private static ToolStore forId(int objectId) { - for (ToolStore t : ToolStore.values()) { - if (t.objectId == objectId) { - return t; - } - } - return null; - } - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (ToolStore t : ToolStore.values()) { - SceneryDefinition.forId(t.objectId).getHandlers().put("option:search", this); - } - ClassScanner.definePlugin(new ToolDialogue()); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - Scenery object = node.asScenery(); - ToolStore ts = ToolStore.forId(object.getId()); - if (ts != null) { - player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("con:tools"), ts); - } - return true; - } - - /** - * Handles the tool dialogue - * @author Clayton Williams - * @date Oct 29, 2015 - */ - private final class ToolDialogue extends DialoguePlugin { - - /** - * The tool store being used - */ - private ToolStore toolStore; - - /** - * ToolDialogue - */ - private ToolDialogue() { - /** - * Empty - */ - } - - /** - * ToolDialogue - * @param player - */ - public ToolDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new ToolDialogue(player); - } - - @Override - public boolean open(Object... args) { - toolStore = (ToolStore) args[0]; - List itemNames = new ArrayList(); - for(int itemId : toolStore.tools) { - ItemDefinition n = ItemDefinition.forId(itemId); - itemNames.add(n.getName()); - } - interpreter.sendOptions("Select a Tool", itemNames.toArray(new String[itemNames.size()])); - stage = 1; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 1: - Item item = new Item(toolStore.tools[buttonId - 1], 1); - if (player.getInventory().freeSlots() <= 0) { - interpreter.sendDialogue("You have no space in your inventory."); - stage = 2; - return true; - } - player.getInventory().add(item); - end(); - return true; - case 2: - end(); - return true; - } - return false; - } - - @Override - public int[] getIds() { - return new int[] { DialogueInterpreter.getDialogueKey("con:tools") }; - } - - } - -} diff --git a/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.kt new file mode 100644 index 000000000..22e3a28cb --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.kt @@ -0,0 +1,233 @@ +package content.global.skill.construction.decoration.workshop + + + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.dialogue.DialogueInterpreter +import core.game.dialogue.DialoguePlugin +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.ClassScanner.definePlugin +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +/** + * Handles the 5 types of tool stores + * ToolsPlugin.java + * @author Clayton Williams + * @date Oct 29, 2015 + */ + + +@Initializable +class ToolsPlugin : OptionHandler() { + val id =0 + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + definePlugin(ToolDialogue()) + SceneryDefinition.forId(13699).getHandlers().put("option:search", this) + SceneryDefinition.forId(13700).getHandlers().put("option:search", this) + SceneryDefinition.forId(13701).getHandlers().put("option:search", this) + SceneryDefinition.forId(13702).getHandlers().put("option:search", this) + SceneryDefinition.forId(13703).getHandlers().put("option:search", this) + return this + } + override fun handle(player: Player, node: Node, option: String?): Boolean { + openDialogue(player,DialogueInterpreter.getDialogueKey("con:tools"), node.getId()) + return true + } + + /** + * Handles the tool dialogue + * @author Clayton Williams + * @date Oct 29, 2015 + */ + private inner class ToolDialogue : DialoguePlugin { + private var id: Int? = null + /** + * Constructs a new `ToolDialogue` `Object`. + */ + constructor() + + /** + * Constructs a new `ToolDialogue` `Object`. + * + * @param player + * the player. + */ + constructor(player: Player?) : super(player) + + fun addItemMsg(player: Player, id: Int, amount: Int = 1) { + + if (!addItem(player, id,amount)){ + sendDialogue(player, "You have no space in your inventory.") + stage = 3 //Stage 3, player just needs to confirm they received the no inventory space dialogue + } else {end()} //Player received their Item, close dialogue + } + + public override fun newInstance(player: Player?): DialoguePlugin { + return ToolDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + id = args[0] as Int + when (id) { + 13699 -> { + sendDialogueOptions(player,"Select a Tool", "Saw", "Chisel", "Hammer", "Shears") + } + + 13700 -> { + sendDialogueOptions(player,"Select a Tool", "Bucket", "Knife", "Spade", "Tinderbox") + } + + 13701 -> { + sendDialogueOptions(player,"Select a Tool", "Brown apron", "Glassblowing pipe", "Needle") + } + + 13702 -> { + sendDialogueOptions(player,"Select a Tool","Amulet mould","Necklace mould","Ring mould","Holy mould","More Options" + ) + stage = 1 + } + + 13703 -> { + sendDialogueOptions(player,"Select a Tool", "Rake", "Spade", "Trowel", "Seed dibber", "Watering can") + } + } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (stage == 3) {//If reply was on full inventory confirmation, close dialogue + end() + return true + } + when (id) { + 13699 -> { + when (buttonId) { + 1 -> { + addItemMsg(player, Items.SAW_8794) + } + + 2 -> { + addItemMsg(player, Items.CHISEL_1755) + } + + 3 -> { + addItemMsg(player, Items.HAMMER_2347) + } + + 4 -> { + addItemMsg(player, Items.SHEARS_1735) + } + } + } + + 13700 -> { + when (buttonId) { + 1 -> { + addItemMsg(player, Items.BUCKET_1925) + } + + 2 -> { + addItemMsg(player, Items.KNIFE_946) + } + + 3 -> { + addItemMsg(player, Items.SPADE_952) + } + + 4 -> { + addItemMsg(player, Items.TINDERBOX_590) + } + } + } + + 13701 -> { + when (buttonId) { + 1 -> { + addItemMsg(player, Items.BROWN_APRON_1757) + } + + 2 -> { + addItemMsg(player, Items.GLASSBLOWING_PIPE_1785) + } + + 3 -> { + addItemMsg(player, Items.NEEDLE_1733) + } + } + } + + 13702 -> { + when (stage) { + 1 -> when (buttonId) { + 1 -> { + addItemMsg(player, Items.AMULET_MOULD_1595) + } + + 2 -> { + addItemMsg(player, Items.NECKLACE_MOULD_1597) + } + + 3 -> { + addItemMsg(player, Items.RING_MOULD_1592) + } + + 4 -> { + addItemMsg(player, Items.HOLY_MOULD_1599) + } + + 5 -> { + sendDialogueOptions(player, + "Select a Tool", "Bracelet mould", "Tiara mould" + ) + stage = 2 + } + } + 2 -> { + when (buttonId) { + 1 -> { + addItemMsg(player, Items.BRACELET_MOULD_11065) + } + + 2 -> { + addItemMsg(player, Items.TIARA_MOULD_5523) + } + } + } + } + } + 13703 -> { + when (buttonId) { + 1 -> { + addItemMsg(player, Items.RAKE_5341) + } + + 2 -> { + addItemMsg(player, Items.SPADE_952) + } + + 3 -> { + addItemMsg(player, Items.TROWEL_676) + } + + 4 -> { + addItemMsg(player, Items.SEED_DIBBER_5343) + } + + 5 -> { + addItemMsg(player, Items.WATERING_CAN_5331) + } + } + } + } + return true + } + override fun getIds(): IntArray { + return intArrayOf(DialogueInterpreter.getDialogueKey("con:tools")) + } + } +} diff --git a/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java b/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java index 4fd2d8c47..ddb967ebe 100644 --- a/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java +++ b/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java @@ -360,7 +360,7 @@ public class HouseServantDialogue extends DialoguePlugin { bankFetch(player, new Item(Items.MARBLE_BLOCK_8786)); break; case 3: //magic stones - bankFetch(player, new Item(Items.MAGIC_STONE_4703)); + bankFetch(player, new Item(Items.MAGIC_STONE_8788)); break; } break; diff --git a/Server/src/main/content/global/skill/cooking/CakeListener.kt b/Server/src/main/content/global/skill/cooking/CakeListener.kt new file mode 100644 index 000000000..dc8eb948f --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CakeListener.kt @@ -0,0 +1,39 @@ +package content.global.skill.cooking + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items + +class CakeListener : InteractionListener { + private val cakeArr = intArrayOf( + Items.EGG_1944, + Items.BUCKET_OF_MILK_1927, + Items.POT_OF_FLOUR_1933 + ) + + override fun defineListeners() { + onUseWith(IntType.ITEM, cakeArr, Items.CAKE_TIN_1887) { player, _, _ -> + if (getDynLevel(player, Skills.COOKING) < 40) { + sendMessage(player, "You need a Cooking level of at least 40 in order to do this.") + return@onUseWith true + } + + if(inInventory(player, Items.EGG_1944) && inInventory(player, Items.BUCKET_OF_MILK_1927) && inInventory(player, Items.POT_OF_FLOUR_1933) && inInventory(player, Items.CAKE_TIN_1887)) { + if(removeItem(player, Items.EGG_1944) && removeItem(player, Items.BUCKET_OF_MILK_1927) && removeItem(player, Items.POT_OF_FLOUR_1933) && removeItem(player, Items.CAKE_TIN_1887)){ + addItem(player, Items.EMPTY_POT_1931) + addItem(player, Items.UNCOOKED_CAKE_1889) + addItem(player, Items.BUCKET_1925) + sendMessage(player, "You mix the milk, flour and egg together to make a raw cake mix.") + + } + } + else{ + // Not sure about the authentic message + sendMessage(player, "You don't have enough ingredients to make that.") + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/CakeMakingPlugin.java b/Server/src/main/content/global/skill/cooking/CakeMakingPlugin.java deleted file mode 100644 index 084abf4c4..000000000 --- a/Server/src/main/content/global/skill/cooking/CakeMakingPlugin.java +++ /dev/null @@ -1,69 +0,0 @@ -package content.global.skill.cooking; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to make a cake. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class CakeMakingPlugin extends UseWithHandler { - - /** - * Represents the bucket of milk item. - */ - private static final Item BUCKET_OF_MILK = new Item(1927); - - /** - * Represents the egg item. - */ - private static final Item EGG = new Item(1944); - - /** - * Represents the cake tin item. - */ - private static final Item CAKE_TIN = new Item(1887); - - /** - * Represents the pot of flour item. - */ - private static final Item POT_OF_FLOUR = new Item(1933); - - /** - * Represents the uncooked cake item. - */ - private static final Item UNCOOKED_CAKE = new Item(1889); - - /** - * Constructs a new {@code CakeMakingPlugin} {@code Object}. - */ - public CakeMakingPlugin() { - super(1933); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(1887, ITEM_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - if (event.getUsedItem().getId() == 1887 && ((Item) event.getUsedWith()).getId() == 1933 || event.getUsedWith().getName().equalsIgnoreCase("cake tin") && ((Item) event.getUsedItem()).getName().equalsIgnoreCase("pot of flour")) { - if (event.getPlayer().getInventory().contains(1933, 1) && event.getPlayer().getInventory().contains(1927, 1) && event.getPlayer().getInventory().contains(1944, 1)) { - if (event.getPlayer().getInventory().remove(BUCKET_OF_MILK, EGG, CAKE_TIN, POT_OF_FLOUR)) { - event.getPlayer().getInventory().add(UNCOOKED_CAKE); - event.getPlayer().getPacketDispatch().sendMessage("You mix the milk, flour and egg together to make a raw cake mix."); - return true; - } - } - } - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/CoconutListener.kt b/Server/src/main/content/global/skill/cooking/CoconutListener.kt new file mode 100644 index 000000000..5f7da66d4 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CoconutListener.kt @@ -0,0 +1,31 @@ +package content.global.skill.cooking + +import core.api.addItem +import core.api.removeItem +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class CoconutListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.COCONUT_5974, Items.HAMMER_2347) { player, used, _ -> + if(removeItem(player, used.id)) { + addItem(player, Items.COCONUT_5976) + sendMessage(player, "You crush the coconut with a hammer.") + return@onUseWith true + } + return@onUseWith false + } + onUseWith(IntType.ITEM, Items.COCONUT_5976, Items.VIAL_229) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + addItem(player, Items.COCONUT_SHELL_5978) + addItem(player, Items.COCONUT_MILK_5935) + sendMessage(player, "You overturn the coconut into a vial.") + return@onUseWith true + } + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/CoconutMakePlugin.java b/Server/src/main/content/global/skill/cooking/CoconutMakePlugin.java deleted file mode 100644 index 7520ff115..000000000 --- a/Server/src/main/content/global/skill/cooking/CoconutMakePlugin.java +++ /dev/null @@ -1,56 +0,0 @@ -package content.global.skill.cooking; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to make a coconut. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class CoconutMakePlugin extends UseWithHandler { - - /** - * Represents the items related to coconut making plugin. - */ - private static final Item[] ITEMS = new Item[] { new Item(5974, 1), new Item(5976, 1), new Item(229), new Item(5935, 1), new Item(5978) }; - - /** - * Constructs a new {@code CoconutMakePlugin} {@code Object}. - */ - public CoconutMakePlugin() { - super(5974, 5976); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(2347, ITEM_TYPE, this); - addHandler(229, ITEM_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - final Item usedWith = (Item) event.getUsedWith(); - if (usedWith.getId() == 5974 && event.getUsedItem().getId() == 2347 || usedWith.getId() == 2347 && event.getUsedItem().getId() == 5974) { - player.getInventory().remove(ITEMS[0]); - player.getInventory().add(ITEMS[1]); - player.getPacketDispatch().sendMessage("You crush the coconut with a hammer."); - } - if (usedWith.getId() == 5976 && event.getUsedItem().getId() == 229 || usedWith.getId() == 229 && event.getUsedItem().getId() == 5976) { - player.getInventory().remove(ITEMS[1]); - player.getInventory().remove(ITEMS[2]); - player.getInventory().add(ITEMS[3]); - player.getInventory().add(ITEMS[4]); - player.getPacketDispatch().sendMessage("You overturn the coconut into a vial."); - } - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/CookableItems.java b/Server/src/main/content/global/skill/cooking/CookableItems.java index cea0f356d..4917db765 100644 --- a/Server/src/main/content/global/skill/cooking/CookableItems.java +++ b/Server/src/main/content/global/skill/cooking/CookableItems.java @@ -81,7 +81,7 @@ public enum CookableItems { // bowl foods BOWL_STEW(2003, 2001, 2005, 25, 117, 68, 392, 68, 392), BOWL_CURRY(2011, 2009, 2013, 60, 280, 38, 332, 38, 332), - BOWL_NETTLE(4239, 4237, 4239, 20, 52, 78, 412, 78, 412), + BOWL_NETTLE(4239, 4237, 4239, 20, 53, 78, 412, 78, 412), BOWL_EGG(7078, 7076, 7090, 13, 50, 0, 0, 90, 438), BOWL_ONION(7084, 1871, 7092, 43, 60, 36, 322, 36, 322), BOWL_MUSHROOM(7082, 7080, 7094, 46, 60, 16, 282, 16, 282), @@ -94,6 +94,7 @@ public enum CookableItems { RAW_OOMLIE(Items.RAW_OOMLIE_2337, 0, Items.BURNT_OOMLIE_2426, 50, 0, 0, 0, 0, 0), // always burns OOMLIE_WRAP(Items.COOKED_OOMLIE_WRAP_2343, Items.WRAPPED_OOMLIE_2341, Items.BURNT_OOMLIE_WRAP_2345, 50, 30, 106, 450, 112, 476), SEAWEED(Items.SEAWEED_401, 0, Items.SODA_ASH_1781, 0, 0, 0, 0, 0, 0), + BARLEY(Items.BARLEY_6006, 0, Items.BARLEY_MALT_6008, 0, 0, 0, 0, 0, 0), /** * Sinew gets overridden by BEEF in this enum, due to values being looked up by the items RAW id. diff --git a/Server/src/main/content/global/skill/cooking/CookingRecipePlugin.java b/Server/src/main/content/global/skill/cooking/CookingRecipePlugin.java deleted file mode 100644 index 9ef36bcaf..000000000 --- a/Server/src/main/content/global/skill/cooking/CookingRecipePlugin.java +++ /dev/null @@ -1,132 +0,0 @@ -package content.global.skill.cooking; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.dialogue.SkillDialogueHandler.SkillDialogue; -import core.game.dialogue.SkillDialogueHandler; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a cooking recipe plugin. This is used to handle the multiple - * recipes used in cooking these recipes can range from making a pizza or making - * a pie. - * @author 'Vexia - * @version 1.9 - */ -@Initializable -public final class CookingRecipePlugin extends UseWithHandler { - - /** - * Constructs a new {@code CookingRecipePlugin} {@code Object}. - */ - public CookingRecipePlugin() { - super(getAllowedNodes()); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (Recipe recipe : Recipe.RECIPES) { - for (Item ingredient : recipe.getIngredients()) { - addHandler(ingredient.getId(), ITEM_TYPE, this); - } - } - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - Recipe recipe = null; - // TODO: Transitioning to a Listener would save an O(n) pass through the recipes list on every use-with - for (Recipe temp : Recipe.RECIPES) { - if (temp.isSingular()) { - if (temp.getBase().getId() == event.getUsedItem().getId() || temp.getBase().getId() == event.getBaseItem().getId()) { - for (Item ingredient : temp.getIngredients()) { - if (ingredient.getId() == event.getBaseItem().getId() || ingredient.getId() == event.getUsedItem().getId()) { - recipe = temp; - break; - } - } - } - } else { - Item part = null; - Item ingredient = null; - for (int k = 0; k < temp.getParts().length; k++) { - for (int i = 0; i < temp.getIngredients().length; i++) { - part = temp.getParts()[k]; - ingredient = temp.getIngredients()[i]; - if (part.getId() == event.getUsedItem().getId() && ingredient.getId() == event.getBaseItem().getId() || part.getId() == event.getBaseItem().getId() && ingredient.getId() == event.getUsedItem().getId()) { - if (k == i) {// represents that this ingredient can - // mix with the other. - recipe = temp; - break; - } - } - } - } - } - } - if (recipe != null) { - final Player player = event.getPlayer(); - final Recipe recipe_ = recipe; - SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, recipe.getProduct()) { - @Override - public void create(final int amount, int index) { - player.getPulseManager().run(new Pulse(2) { - int count = 0; - @Override - public boolean pulse() { - recipe_.mix(player, event); - return ++count >= amount; - } - }); - } - - @Override - public int getAll(int index) { - return player.getInventory().getAmount(recipe_.getBase()); - } - }; - if (player.getInventory().getAmount(recipe.getBase()) == 1) { - recipe_.mix(player, event); - } else { - handler.open(); - } - return true; - } - return false; - } - - /** - * Method used to get the allowed nodes for this plugin. - * @return the allowed nodes. - */ - private final static int[] getAllowedNodes() { - List bases = new ArrayList<>(10); - for (Recipe recipe : Recipe.RECIPES) { - for (Item base : recipe.getParts()) { - if (bases.contains(base.getId())) { - continue; - } - bases.add(base.getId()); - } - if (bases.contains(recipe.getBase().getId())) { - continue; - } - bases.add(recipe.getBase().getId()); - } - int[] baseArray = new int[bases.size()]; - for (int i = 0; i < bases.size(); i++) { - baseArray[i] = bases.get(i); - } - return baseArray; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/CookingRewrite.kt b/Server/src/main/content/global/skill/cooking/CookingRewrite.kt index 76d485956..36679ef92 100644 --- a/Server/src/main/content/global/skill/cooking/CookingRewrite.kt +++ b/Server/src/main/content/global/skill/cooking/CookingRewrite.kt @@ -1,17 +1,22 @@ package content.global.skill.cooking -import core.api.amountInInventory +import content.region.misc.tutisland.handlers.TutorialStage +import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.impl.Animator import core.game.node.entity.player.Player import core.game.node.item.Item import core.game.node.scenery.Scenery +import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.Items.BREAD_DOUGH_2307 import org.rs09.consts.Items.RAW_BEAR_MEAT_2136 import org.rs09.consts.Items.RAW_BEEF_2132 import org.rs09.consts.Items.SEAWEED_401 import org.rs09.consts.Items.UNCOOKED_CAKE_1889 +import org.rs09.consts.Sounds /** * @author Ceikry @@ -27,13 +32,43 @@ class CookingRewrite : InteractionListener { list.add(Items.COOKED_MEAT_2142) list.add(RAW_BEEF_2132) list.add(RAW_BEAR_MEAT_2136) + list.add(Items.BARLEY_6006) list.add(SEAWEED_401) + list.add(Items.BOWL_OF_WATER_1921) RAW_FOODS = list.toIntArray() } override fun defineListeners() { - onUseWith(IntType.SCENERY,RAW_FOODS, *COOKING_OBJs){ player, used, with -> + if (!getAttribute(player, "/save:tutorial:complete", false)) { + // On tutorial island, we don't want to show the cook-x menu and we always want to burn our first shrimp + // This requirement of a simplified and predictable cooking system means that, for the second time, I have to reinvent the wheel of cooking + // (We only need to care about shrimp here, the tutorial island range is special and has its own separate listener) + queueScript(player, 0, QueueStrength.WEAK) { stage -> + if (stage == 0) { + val FIRE_ANIMATION = Animation(897, Animator.Priority.HIGH) + lock(player, FIRE_ANIMATION.duration) + lockInteractions(player, FIRE_ANIMATION.duration) + animate(player, FIRE_ANIMATION) + playAudio(player, Sounds.FRY_2577) + return@queueScript delayScript(player, FIRE_ANIMATION.duration) + } + val tutStage = getAttribute(player, "/save:tutorial:stage", 0) + if (tutStage < 15) { + replaceSlot(player, used.asItem().slot, Item(Items.BURNT_SHRIMP_7954), used.asItem()) + setAttribute(player, "tutorial:stage", 15) + TutorialStage.load(player, 15) + } else { + replaceSlot(player, used.asItem().slot, Item(Items.SHRIMPS_315), used.asItem()) + if (tutStage == 15) { + setAttribute(player, "tutorial:stage", 16) + TutorialStage.load(player, 16) + } + } + return@queueScript stopExecuting(player) + } + return@onUseWith true + } val item = used.asItem() val obj = with.asScenery() val range = obj.name.toLowerCase().contains("range") @@ -42,10 +77,14 @@ class CookingRewrite : InteractionListener { player.dialogueInterpreter.open(CookingDialogue(item.id,9436,true,obj,item.id)) return@onUseWith true } - BREAD_DOUGH_2307, UNCOOKED_CAKE_1889 -> if (!range) { + BREAD_DOUGH_2307, UNCOOKED_CAKE_1889, Items.BARLEY_6006 -> if (!range) { player.packetDispatch.sendMessage("You need to cook this on a range.") return@onUseWith false } + Items.BOWL_OF_WATER_1921 ->{ + cook(player, obj, Items.BOWL_OF_WATER_1921, Items.BOWL_OF_HOT_WATER_4456, 1) + return@onUseWith true + } } //cook a standard item @@ -66,7 +105,7 @@ class CookingRewrite : InteractionListener { } companion object { - val COOKING_OBJs = intArrayOf(24313,21302, 13528, 13529, 13533, 13531, 13536, 13539, 13542, 2728, 2729, 2730, 2731, 2732, 2859, 3038, 3039, 3769, 3775, 4265, 4266, 5249, 5499, 5631, 5632, 5981, 9682, 10433, 11404, 11405, 11406, 12102, 12796, 13337, 13881, 14169, 14919, 15156, 20000, 20001, 21620, 21792, 22713, 22714, 23046, 24283, 24284, 25155, 25156, 25465, 25730, 27297, 29139, 30017, 32099, 33500, 34495, 34546, 36973, 37597, 37629, 37726, 114, 4172, 5275, 8750, 16893, 22154, 34410, 34565, 114, 9085, 9086, 9087, 12269, 15398, 25440, 25441, 2724, 2725, 2726, 4618, 4650, 5165, 6093, 6094, 6095, 6096, 8712, 9374, 9439, 9440, 9441, 10824, 17640, 17641, 17642, 17643, 18039, 21795, 24285, 24329, 27251, 33498, 35449, 36815, 36816, 37426, 40110, 10377) + val COOKING_OBJs = intArrayOf(24313 ,21302, 13528, 13529, 13533, 13531, 13536, 13539, 13542, 2728, 2729, 2730, 2731, 2732, 2859, 3038, 3769, 3775, 4265, 4266, 5249, 5499, 5631, 5632, 5981, 9682, 10433, 11404, 11405, 11406, 12102, 12796, 13337, 13881, 14169, 14919, 15156, 20000, 20001, 21620, 21792, 22713, 22714, 23046, 24283, 24284, 25155, 25156, 25465, 25730, 27297, 29139, 30017, 32099, 33500, 34495, 34546, 36973, 37597, 37629, 37726, 114, 4172, 5275, 8750, 16893, 22154, 34410, 34565, 114, 9085, 9086, 9087, 12269, 15398, 25440, 25441, 2724, 2725, 2726, 4618, 4650, 5165, 6093, 6094, 6095, 6096, 8712, 9374, 9439, 9440, 9441, 10824, 17640, 17641, 17642, 17643, 18039, 18170, 21795, 24285, 24329, 27251, 33498, 35449, 36815, 36816, 37426, 40110, 10377) @JvmStatic fun cook(player: Player, `object`: Scenery?, initial: Int, product: Int, amount: Int) { diff --git a/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt b/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt index a60f89ff7..267d9ccfe 100644 --- a/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt +++ b/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt @@ -1,5 +1,6 @@ package content.global.skill.cooking +import content.region.misc.tutisland.handlers.TutorialStage import core.api.* import core.game.event.ResourceProducedEvent import core.game.node.entity.skill.Skills @@ -24,7 +25,16 @@ class DoughMakingListener : InteractionListener { FULL_WATER_CONTAINERS_TO_EMPTY_CONTAINERS.keys.toIntArray(), Items.POT_OF_FLOUR_1933 ) { player, waterContainer, flourContainer -> - openDialogue(player, DoughMakeDialogue(waterContainer.asItem(), flourContainer.asItem())) + if (getAttribute(player, "/save:tutorial:complete", false)) { + openDialogue(player, DoughMakeDialogue(waterContainer.asItem(), flourContainer.asItem())) + return@onUseWith true + } + // Continue the tutorial + replaceSlot(player, waterContainer.asItem().slot, Item(Items.BUCKET_1925), waterContainer.asItem()) + replaceSlot(player, flourContainer.asItem().slot, Item(Items.EMPTY_POT_1931), flourContainer.asItem()) + addItemOrDrop(player, Items.BREAD_DOUGH_2307) + setAttribute(player, "tutorial:stage", 20) + TutorialStage.load(player, 20) return@onUseWith true } } @@ -73,7 +83,7 @@ class DoughMakingListener : InteractionListener { sendMessage( player!!, - "You mix the flower and the water to make some ${selectedDoughProduct.itemName.toLowerCase()}." + "You mix the flour and the water to make some ${selectedDoughProduct.itemName.toLowerCase()}." ) } } else { diff --git a/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java b/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java index 051f5a14c..3e974f313 100644 --- a/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java +++ b/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java @@ -43,7 +43,6 @@ public class IntentionalBurnPulse extends StandardCookingPulse { @Override public boolean cook(Player player, Scenery object, boolean burned, int initial, int product) { - super.animate(); Item initialItem = new Item(initial); Item productItem = new Item(product); @@ -51,6 +50,7 @@ public class IntentionalBurnPulse extends StandardCookingPulse { player.getInventory().add(productItem); player.getPacketDispatch().sendMessage(getMessage(initialItem, productItem, burned)); playAudio(player, Sounds.FRY_2577); + super.animate(); return true; } return false; diff --git a/Server/src/main/content/global/skill/cooking/NettleTeaListener.kt b/Server/src/main/content/global/skill/cooking/NettleTeaListener.kt new file mode 100644 index 000000000..ac1765428 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/NettleTeaListener.kt @@ -0,0 +1,18 @@ +package content.global.skill.cooking + +import org.rs09.consts.Items +import core.api.replaceSlot +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item + +class NettleTeaListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.EMPTY_CUP_1980, Items.NETTLE_TEA_4239) { player, used, with -> + replaceSlot(player, with.asItem().slot, Item(Items.BOWL_1923), with.asItem()) + replaceSlot(player, used.asItem().slot, Item(Items.CUP_OF_TEA_4242), used.asItem()) + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/NettleTeaPlugin.java b/Server/src/main/content/global/skill/cooking/NettleTeaPlugin.java deleted file mode 100644 index 161c99991..000000000 --- a/Server/src/main/content/global/skill/cooking/NettleTeaPlugin.java +++ /dev/null @@ -1,61 +0,0 @@ -package content.global.skill.cooking; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to create nettle tea in a cup. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class NettleTeaPlugin extends UseWithHandler { - - /** - * Represents the empty cup item. - */ - private static final Item EMPTY_CUP = new Item(1980, 1); - - /** - * Represents the nettle tea item. - */ - private static final Item NETTLE_TEA = new Item(4239, 1); - - /** - * Represents the bowl item. - */ - private static final Item BOWL = new Item(1923); - - /** - * Represents the cup of tea item. - */ - private static final Item CUP_OF_TEA = new Item(4242, 1); - - /** - * Constructs a new {@code NettleTeaPlugin} {@code Object}. - */ - public NettleTeaPlugin() { - super(1980); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(4239, ITEM_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - if (player.getInventory().remove(EMPTY_CUP) && player.getInventory().remove(NETTLE_TEA)) { - player.getInventory().add(BOWL); - player.getInventory().add(CUP_OF_TEA); - } - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/NettleWaterPlugin.java b/Server/src/main/content/global/skill/cooking/NettleWaterPlugin.java deleted file mode 100644 index e8dbeb385..000000000 --- a/Server/src/main/content/global/skill/cooking/NettleWaterPlugin.java +++ /dev/null @@ -1,35 +0,0 @@ -package content.global.skill.cooking; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * @author Adam - */ -@Initializable -public class NettleWaterPlugin extends UseWithHandler { - - public NettleWaterPlugin() { - super(1921); - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - player.getInventory().remove(new Item(1921, 1)); - player.getInventory().remove(new Item(4241, 1)); - player.getInventory().add(new Item(4237, 1)); - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(4241, ITEM_TYPE, this); - return this; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/PieShellPlugin.java b/Server/src/main/content/global/skill/cooking/PieShellPlugin.java deleted file mode 100644 index 4278836e8..000000000 --- a/Server/src/main/content/global/skill/cooking/PieShellPlugin.java +++ /dev/null @@ -1,56 +0,0 @@ -package content.global.skill.cooking; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the pie shell making plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class PieShellPlugin extends UseWithHandler { - - /** - * Represents the pie sell item. - */ - private static final Item PIE_SHELL = new Item(2315, 1); - - /** - * Represents the pie dish item. - */ - private static final Item PIE_DISH = new Item(2313, 1); - - /** - * Represents the pastry dough item. - */ - private static final Item PASTRY_DOUGH = new Item(1953, 1); - - /** - * Constructs a new {@code PieMakingPlugin} {@code Object}. - */ - public PieShellPlugin() { - super(1953); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(2313, ITEM_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - if (player.getInventory().remove(PASTRY_DOUGH, PIE_DISH)) { - player.getInventory().add(PIE_SHELL); - player.getPacketDispatch().sendMessage("You put the pastry dough into the pie dish to make a pie shell."); - } - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/SkeweredFoodListener.kt b/Server/src/main/content/global/skill/cooking/SkeweredFoodListener.kt new file mode 100644 index 000000000..8465d2b88 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/SkeweredFoodListener.kt @@ -0,0 +1,38 @@ +package content.global.skill.cooking + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items + +class SkeweredFoodListener : InteractionListener { + val skewerMap = hashMapOf( + Items.RAW_CHOMPY_2876 to Items.SKEWERED_CHOMPY_7230, + Items.RAW_RABBIT_3226 to Items.SKEWERED_RABBIT_7224, + Items.RAW_BIRD_MEAT_9978 to Items.SKEWERED_BIRD_MEAT_9984, + Items.RAW_BEAST_MEAT_9986 to Items.SKEWERED_BEAST_9992 + ) + + override fun defineListeners() { + onUseWith(IntType.ITEM, skewerMap.keys.toIntArray(), Items.IRON_SPIT_7225) { player, used, with -> + val level = when (used.id) { + Items.RAW_BIRD_MEAT_9978 -> 11 + Items.RAW_RABBIT_3226 -> 16 + Items.RAW_BEAST_MEAT_9986 -> 21 + Items.RAW_CHOMPY_2876 -> 30 + else -> 0 + } + + if (getDynLevel(player, Skills.COOKING) < level) { + sendMessage(player, "You need a Cooking level of at least $level in order to do this.") + return@onUseWith true + } + if (removeItem(player, used.id) && removeItem(player, with.id)) { + skewerMap[used.id]?.let { addItem(player, it) } + return@onUseWith true + } + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/SkeweredFoodPlugin.java b/Server/src/main/content/global/skill/cooking/SkeweredFoodPlugin.java deleted file mode 100644 index 8f02bfcb9..000000000 --- a/Server/src/main/content/global/skill/cooking/SkeweredFoodPlugin.java +++ /dev/null @@ -1,115 +0,0 @@ -package content.global.skill.cooking; - -import core.game.node.entity.skill.Skills; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Items; - -/** - * Represents the plugin used to make skwered items. - * @author 'Vexia - * @date 22/12/2013 - */ -@Initializable -public class SkeweredFoodPlugin extends UseWithHandler { - - /** - * Represents the level required. - */ - private final int LEVEL = 20; - - /** - * Constructs a new {@code SkeweredFoodPlugin} {@code Object}. - */ - public SkeweredFoodPlugin() { - super(7225); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (SkeweredSet set : SkeweredSet.values()) { - addHandler(set.getRaw().getId(), ITEM_TYPE, this); - } - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - if (player.getSkills().getLevel(Skills.FIREMAKING) < LEVEL) { - player.getPacketDispatch().sendMessage("You meed a Firemaking level of at least " + LEVEL + " in order to do this."); - return true; - } - final SkeweredSet set = SkeweredSet.forItem(event.getBaseItem().getId() == 7225 ? event.getUsedItem() : event.getBaseItem()); - if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { - player.getInventory().add(set.getProduct()); - } - return true; - } - - /** - * Represents a set of skwered items. - * @author 'Vexia - * @date 22/12/2013 - */ - public enum SkeweredSet { - CHOMPY(new Item(Items.RAW_CHOMPY_2876), new Item(Items.SKEWERED_CHOMPY_7230)), - RABBIT(new Item(Items.RAW_RABBIT_3226), new Item(Items.SKEWERED_RABBIT_7224)), - BIRD(new Item(Items.RAW_BIRD_MEAT_9978), new Item(Items.SKEWERED_BIRD_MEAT_9984)), - BEAST(new Item(Items.RAW_BEAST_MEAT_9986), new Item(Items.SKEWERED_BEAST_9992)); - - /** - * Represents the raw item. - */ - private final Item raw; - - /** - * Represents the product item. - */ - private final Item product; - - /** - * Constructs a new {@code SkeweredFoodPlugin} {@code Object}. - * @param raw the raw item. - * @param product the product. - */ - private SkeweredSet(Item raw, Item product) { - this.raw = raw; - this.product = product; - } - - /** - * Gets the raw. - * @return The raw. - */ - public Item getRaw() { - return raw; - } - - /** - * Gets the product. - * @return The product. - */ - public Item getProduct() { - return product; - } - - /** - * Gets the skwered set. - * @param item the item. - * @return the set. - */ - public static SkeweredSet forItem(final Item item) { - for (SkeweredSet set : values()) { - if (set.getRaw().getId() == item.getId()) { - return set; - } - } - return null; - } - } -} diff --git a/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java b/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java index f081bed5a..34dc67319 100644 --- a/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java +++ b/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java @@ -4,6 +4,8 @@ import content.global.skill.skillcapeperks.SkillcapePerks; import core.game.event.ResourceProducedEvent; import core.game.node.entity.impl.Animator; import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.LogType; +import core.game.node.entity.player.info.PlayerMonitor; import core.game.node.entity.player.link.audio.Audio; import core.game.node.entity.skill.Skills; import core.game.node.item.GroundItemManager; @@ -15,7 +17,8 @@ import core.tools.RandomFunction; import org.rs09.consts.Items; import org.rs09.consts.Sounds; -import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.*; +import content.data.Quests; public class StandardCookingPulse extends Pulse { //range animation @@ -38,12 +41,17 @@ public class StandardCookingPulse extends Pulse { private boolean burned = false; public CookableItems properties; + private int initialAmount; + private int processedAmount; + public StandardCookingPulse(Player player, Scenery object, int initial, int product, int amount) { this.player = player; this.object = object; this.initial = initial; this.product = product; this.amount = amount; + this.initialAmount = amountInInventory(player, initial); + this.processedAmount = 0; } @Override @@ -72,7 +80,7 @@ public class StandardCookingPulse extends Pulse { this.experience = 0; if (properties != null) { // Handle Cook's Assistant range - if (object.getId() == LUMBRIDGE_RANGE && !player.getQuestRepository().isComplete("Cook's Assistant")) { + if (object.getId() == LUMBRIDGE_RANGE && !player.getQuestRepository().isComplete(Quests.COOKS_ASSISTANT)) { player.getPacketDispatch().sendMessage("You need to have completed the Cook's Assistant quest in order to use that range."); return false; } @@ -141,7 +149,6 @@ public class StandardCookingPulse extends Pulse { public boolean cook(final Player player, final Scenery object, final boolean burned, final int initial, final int product) { Item initialItem = new Item(initial); Item productItem = new Item(product); - animate(); //handle special cooking results (spits, cake, etc) that don't justify separate plugin switch (initial) { @@ -169,12 +176,18 @@ public class StandardCookingPulse extends Pulse { player.getInventory().add(productItem); player.dispatch(new ResourceProducedEvent(productItem.getId(), 1, object, initialItem.getId())); player.getSkills().addExperience(Skills.COOKING, experience, true); + processedAmount++; + if (processedAmount > initialAmount) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "cooked item (" + player.getName() + ", " + initialItem.getName() + "): initialAmount " + initialAmount + ", processedAmount " + processedAmount); + } + player.incrementAttribute("/save:stats_manager:food_cooked", 1); } else { player.dispatch(new ResourceProducedEvent(CookableItems.getBurnt(initial).getId(), 1, object, initialItem.getId())); player.getInventory().add(CookableItems.getBurnt(initial)); } player.getPacketDispatch().sendMessage(getMessage(initialItem, productItem, burned)); playAudio(player, Sounds.FRY_2577); + animate(); return true; } return false; @@ -187,6 +200,9 @@ public class StandardCookingPulse extends Pulse { if (product.getId() == Items.SODA_ASH_1781) { return "You burn the seaweed into soda ash."; } + if (product.getId() == Items.BARLEY_MALT_6008) { + return null; // Both live branches of Jagexscape lack a message for this and I can't find period evidence of a message + } if (CookableItems.intentionalBurn(food.getId())) { return "You deliberately burn the perfectly good piece of meat."; } diff --git a/Server/src/main/content/global/skill/cooking/TeaInteraction.kt b/Server/src/main/content/global/skill/cooking/TeaInteraction.kt new file mode 100644 index 000000000..5890ad372 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/TeaInteraction.kt @@ -0,0 +1,166 @@ +package content.global.skill.cooking + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items + +/** + * This deals with all tea mixtures + * cup of tea + * nettle tea + * nettle water + * nettle tea (cup) + * poh tea + * clay + * porcelain + * gold trim + * Flask + */ +class TeaInteraction : InteractionListener { + private val teaMilkMap = mapOf( + Items.NETTLE_TEA_4239 to Items.NETTLE_TEA_4240, + Items.CUP_OF_TEA_4242 to Items.CUP_OF_TEA_4243, + Items.CUP_OF_TEA_4245 to Items.CUP_OF_TEA_4246, + Items.CUP_OF_TEA_7730 to Items.CUP_OF_TEA_7731, + Items.CUP_OF_TEA_7733 to Items.CUP_OF_TEA_7734, + Items.CUP_OF_TEA_7736 to Items.CUP_OF_TEA_7737, + ) + + private val teaCupMap = mapOf( + Items.NETTLE_TEA_4239 to Items.CUP_OF_TEA_4242, + Items.NETTLE_TEA_4240 to Items.CUP_OF_TEA_4243, + Items.BOWL_OF_HOT_WATER_4456 to Items.CUP_OF_HOT_WATER_4460 + ) + + // This is specifically for the porcelain cup without a handle for Ghost Ahoy + private val teaCupPorcelainMap = mapOf( + Items.NETTLE_TEA_4239 to Items.CUP_OF_TEA_4245, + Items.NETTLE_TEA_4240 to Items.CUP_OF_TEA_4246 + ) + + private val emptyTeaPot = intArrayOf( + Items.TEAPOT_7702, + Items.TEAPOT_7714, + Items.TEAPOT_7726 + ) + + private val leafTeaPot = intArrayOf( + Items.TEAPOT_WITH_LEAVES_7700, + Items.TEAPOT_WITH_LEAVES_7712, + Items.TEAPOT_WITH_LEAVES_7724 + ) + + private val filledTeaPot = intArrayOf( + Items.POT_OF_TEA_4_7692, + Items.POT_OF_TEA_3_7694, + Items.POT_OF_TEA_2_7696, + Items.POT_OF_TEA_1_7698, + Items.POT_OF_TEA_4_7704, + Items.POT_OF_TEA_3_7706, + Items.POT_OF_TEA_2_7708, + Items.POT_OF_TEA_1_7710, + Items.POT_OF_TEA_4_7716, + Items.POT_OF_TEA_3_7718, + Items.POT_OF_TEA_2_7720, + Items.POT_OF_TEA_1_7722, + ) + + private val emptyBuilderCup = intArrayOf( + Items.EMPTY_CUP_7728, + Items.PORCELAIN_CUP_7732, + Items.PORCELAIN_CUP_7735 + ) + + override fun defineListeners() { + onUseWith(ITEM, teaMilkMap.keys.toIntArray(), Items.BUCKET_OF_MILK_1927){ player, used, with -> + if (removeItem(player, used) && removeItem(player, with)){ + addItem(player, teaMilkMap[used.id]!!) + addItem(player, Items.BUCKET_1925) + } + return@onUseWith true + } + + onUseWith(ITEM, teaCupMap.keys.toIntArray(), Items.EMPTY_CUP_1980){ player, used, with -> + if (used.id != Items.BOWL_OF_HOT_WATER_4456){ + if (getDynLevel(player, Skills.COOKING) < 20){ + sendDialogue(player, "You need a cooking level of 20 to make tea.") + return@onUseWith false + } + } + if (removeItem(player, used) && removeItem(player, with)) { + addItem(player, teaCupMap[used.id]!!) + addItem(player, Items.BOWL_1923) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.BOWL_OF_WATER_1921, Items.NETTLES_4241) { player, used, with -> + if (removeItem(player, used) && removeItem(player, with)){ + addItem(player, Items.NETTLE_WATER_4237) + } + return@onUseWith true + } + + onUseWith(ITEM, teaCupPorcelainMap.keys.toIntArray(), Items.PORCELAIN_CUP_4244){player, used, with -> + if (getDynLevel(player, Skills.COOKING) < 20){ + sendDialogue(player, "You need a cooking level of 20 to make tea.") + return@onUseWith false + } + + if(removeItem(player, used) && removeItem(player, with)){ + addItem(player, teaCupPorcelainMap[used.id]!!) + addItem(player, Items.BOWL_1923) + } + return@onUseWith true + } + + onUseWith(ITEM, emptyTeaPot, Items.TEA_LEAVES_7738) { player, used, with -> + if (removeItem(player, used) && removeItem(player, with)){ + addItem(player, used.id - 2) + } + return@onUseWith true + } + + onUseWith(ITEM, leafTeaPot, Items.HOT_KETTLE_7691) { player, used, with -> + if (getDynLevel(player, Skills.COOKING) < 20){ + sendDialogue(player,"You need to be level 20 to make tea.") + return@onUseWith false + } + if (removeItem(player, used) && removeItem(player, with)){ + addItem(player, Items.KETTLE_7688) + addItem(player, used.id - 8) + rewardXP(player, Skills.COOKING, 53.0) + + } + return@onUseWith true + } + + onUseWith(ITEM, filledTeaPot, *emptyBuilderCup) { player, used, with -> + return@onUseWith fillBuildersTea(player, used, with) + } + } + + private fun fillBuildersTea(player: Player, used: Node, with: Node) : Boolean { + if (removeItem(player, used) && removeItem(player, with)){ + // Thanks tea pot with tea leaves + if (used.id + 4 in emptyTeaPot){ + addItem(player, used.id + 4) + } + else{ + addItem(player, used.id + 2) + } + // Why do these cups have a noted form! + if (with.id == Items.EMPTY_CUP_7728){ + addItem(player, with.id + 2) + } + else{ + addItem(player, with.id + 1) + } + return true + } + return false + } +} diff --git a/Server/src/main/content/global/skill/cooking/WatermelonSliceListener.kt b/Server/src/main/content/global/skill/cooking/WatermelonSliceListener.kt new file mode 100644 index 000000000..12f1ee22d --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/WatermelonSliceListener.kt @@ -0,0 +1,20 @@ +package content.global.skill.cooking + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class WatermelonSliceListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.WATERMELON_5982, Items.KNIFE_946) { player, used, _ -> + if(removeItem(player, used.asItem())) { + addItemOrDrop(player, Items.WATERMELON_SLICE_5984, 3) + sendMessage(player, "You slice the watermelon into three slices.") + return@onUseWith true + } + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/WatermelonSlicePlugin.java b/Server/src/main/content/global/skill/cooking/WatermelonSlicePlugin.java deleted file mode 100644 index d8273968f..000000000 --- a/Server/src/main/content/global/skill/cooking/WatermelonSlicePlugin.java +++ /dev/null @@ -1,59 +0,0 @@ -package content.global.skill.cooking; - -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.item.GroundItemManager; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to slice a watermelon. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class WatermelonSlicePlugin extends UseWithHandler { - - /** - * Represents the knife item. - */ - private static final Item KNIFE = new Item(946); - - /** - * Represents the watermelon item. - */ - private static final Item WATERMELON = new Item(5982); - - /** - * Represents the watermelon slice item. - */ - private static final Item WATERMELON_SLICE = new Item(5984); - - /** - * Constructs a new {@code WatermelonSlicePlugin.java} {@code Object}. - */ - public WatermelonSlicePlugin() { - super(KNIFE.getId()); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(5982, ITEM_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - if (event.getPlayer().getInventory().remove(WATERMELON)) { - for (int i = 0; i < 3; i++) { - if (!event.getPlayer().getInventory().add(WATERMELON_SLICE)) { - GroundItemManager.create(WATERMELON_SLICE, event.getPlayer()); - } - } - event.getPlayer().getPacketDispatch().sendMessage("You slice the watermelon into three slices."); - } - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/WineFermentListener.kt b/Server/src/main/content/global/skill/cooking/WineFermentListener.kt new file mode 100644 index 000000000..1c4c67b9d --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/WineFermentListener.kt @@ -0,0 +1,30 @@ +package content.global.skill.cooking + +import content.global.skill.cooking.fermenting.WineFermentingPulse +import core.api.addItem +import core.api.getDynLevel +import core.api.removeItem +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.world.GameWorld.Pulser +import org.rs09.consts.Items + +class WineFermentListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.GRAPES_1987, Items.JUG_OF_WATER_1937) { player, used, with -> + if (getDynLevel(player, Skills.COOKING) < 35) { + sendMessage(player, "You need a cooking level of 35 to do this.") + return@onUseWith true + } + if (removeItem(player, used.id) && removeItem(player, with.id)) { + addItem(player, Items.UNFERMENTED_WINE_1995) + Pulser.submit(WineFermentingPulse(1, player)) + return@onUseWith true + } + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/WineFermentPlugin.java b/Server/src/main/content/global/skill/cooking/WineFermentPlugin.java deleted file mode 100644 index b2e96678d..000000000 --- a/Server/src/main/content/global/skill/cooking/WineFermentPlugin.java +++ /dev/null @@ -1,63 +0,0 @@ -package content.global.skill.cooking; - -import core.plugin.Initializable; -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.fermenting.WineFermentingPulse; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.GameWorld; -import core.plugin.Plugin; - -/** - * Represents the plugin used to ferment wine. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class WineFermentPlugin extends UseWithHandler { - - /** - * Represents the grapes item. - */ - private static final Item GRAPES = new Item(1987, 1); - - /** - * Represents the jug of water item. - */ - private static final Item JUG_OF_WATER = new Item(1937, 1); - - /** - * Represents the unfermented wine item. - */ - private static final Item UNFERMENTED_WINE = new Item(1995, 1); - - /** - * Constructs a new {@code WineFermentPlugin} {@code Object}. - */ - public WineFermentPlugin() { - super(1937); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(1987, ITEM_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - if (player.getSkills().getLevel(Skills.COOKING) < 35) { - player.getPacketDispatch().sendMessage("You need a cooking level of 35 to do this."); - return true; - } - if (player.getInventory().remove(GRAPES, JUG_OF_WATER)) { - player.getInventory().add(UNFERMENTED_WINE); - GameWorld.getPulser().submit(new WineFermentingPulse(1, player)); - } - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/fermenting/AppleMushListener.kt b/Server/src/main/content/global/skill/cooking/fermenting/AppleMushListener.kt new file mode 100644 index 000000000..72ffeef3d --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/AppleMushListener.kt @@ -0,0 +1,187 @@ +package content.global.skill.cooking.fermenting + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.ticksToCycles +import org.rs09.consts.Items +import org.rs09.consts.Scenery as SceneryIds + + +class AppleMushListener : InteractionListener { + + private data class BarrelLocations( + val start: Location, // Where the player begins the mushing animation from + val jump: Location, // Where the player ends the mushing animation at + val tap: Location, // Where the apple barrel's tap is located + val stand: Location // Where the player stands to collect from the tap + ) + + private val barrelLocations = mapOf( + 14747 to BarrelLocations( // Port Phasmatys + start = Location.create(3676, 9959, 0), + jump = Location.create(3676, 9957, 0), + tap = Location.create(3677, 9959, 0), + stand = Location.create(3678, 9959, 0) + ), + 11679 to BarrelLocations( // Keldagrim + start = Location.create(2914, 10193, 1), + jump = Location.create(2914, 10191, 1), + tap = Location.create(2915, 10193, 1), + stand = Location.create(2916, 10193, 1) + ), + 9780 to BarrelLocations( // Gnome Orchard + start = Location.create(2484, 3375, 0), + jump = Location.create(2484, 3373, 0), + tap = Location.create(2485, 3375, 0), + stand = Location.create(2486, 3375, 0) + ) + ) + + private val emptyAppleBarrels = intArrayOf( + SceneryIds.APPLE_BARREL_7403, + SceneryIds.APPLE_BARREL_8807 + ) + + private val fullAppleBarrels = intArrayOf( + SceneryIds.APPLE_BARREL_7404, + SceneryIds.APPLE_BARREL_8808 + ) + + private val appleTaps = intArrayOf( + SceneryIds.BARREL_TAP_7406, + SceneryIds.BARREL_TAP_8737 + ) + + private val MUSH_ANIM = Animation(2306) + + override fun defineListeners() { + + onUseWith(SCENERY, Items.COOKING_APPLE_1955, *emptyAppleBarrels) { player, _, with -> + if (getDynLevel(player, Skills.COOKING) < 14) { + sendDialogue(player, "You need a Cooking level of at least 14 in order to do this.") + return@onUseWith true + } + if (!inInventory(player, Items.COOKING_APPLE_1955, 4)) { + sendDialogue(player, "You need 4 cooking apples to make apple mush.") + return@onUseWith true + } + if (!inInventory(player, Items.BUCKET_1925)) { + sendDialogue(player, "You need a bucket to collect the apple mush.") + return@onUseWith true + } + if (inInventory(player, Items.COOKING_APPLE_1955, 4)) { + startMushing(player, with.asScenery()) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.BUCKET_1925, *appleTaps) { player, _, _ -> + if (getAttribute(player, "/save:cooking:brewing-apples", false)) { + if (removeItem(player, Item(Items.BUCKET_1925, 1))) { + addItem(player, Items.APPLE_MUSH_5992, 1) + sendMessage(player, "You fill a bucket with apple mush.") + } + removeAttribute(player, "/save:cooking:brewing-apples") + return@onUseWith true + } + sendMessage(player, "Nothing interesting happens.") + return@onUseWith false + } + } + + private fun startMushing(player: Player, barrel: Scenery) { + val initLoc = player.location + val barrelLoc = barrel.location + val locations = barrelLocations[player.location.regionId] + val startLoc = locations?.start + val jumpLoc = locations?.jump + val standLoc = locations?.stand + val tapLoc = locations?.tap + val fastStart: Boolean = initLoc == startLoc + + // https://www.youtube.com/watch?v=7I_Ec_tQ-tc + // Has to be soft or else you can log out and clog the barrel + queueScript(player, 1 ,QueueStrength.SOFT) { counter -> + when (counter) { + 0 -> { + stopWalk(player) + forceWalk(player, startLoc!!, "smart") + lock(player, MUSH_ANIM.duration + 7) + return@queueScript delayScript(player, if (fastStart) 1 else 4) + } + + 1 -> { + face(player, barrelLoc) + if (!removeItem(player, Item(Items.COOKING_APPLE_1955, 4))) { return@queueScript stopExecuting(player) } + setAttribute(player, "/save:cooking:brewing-apples", true) + return@queueScript delayScript(player, 0) + } + + 2 -> { + forceMove(player, startLoc!!, barrelLoc, 0, ticksToCycles(1), anim = MUSH_ANIM.id) + if (barrel.id == SceneryIds.APPLE_BARREL_7403) sendGraphics(414, barrelLoc) + else sendGraphics(413, barrelLoc) + swapBarrel(barrel) + return@queueScript delayScript(player, MUSH_ANIM.duration - 1) + } + + 3 -> { + forceMove(player, barrelLoc, jumpLoc!!, 0, ticksToCycles(1)) + return@queueScript delayScript(player, 2) + } + + 4 -> { + stopWalk(player) + return@queueScript delayScript(player, 1) + } + + 5 -> { + unlock(player) + stopWalk(player) + forceWalk(player, standLoc!!, "smart") + lock(player, 5) + return@queueScript delayScript(player, 4) + } + + 6 -> { + stopWalk(player) + face(player, tapLoc!!) + return@queueScript delayScript(player, 1) + } + + 7 -> { + if (removeItem(player, Item(Items.BUCKET_1925, 1))) { + addItem(player, Items.APPLE_MUSH_5992, 1) + sendMessage(player, "You fill a bucket with apple mush.") + } + removeAttribute(player, "/save:cooking:brewing-apples") + val currentBarrel = getScenery(barrelLoc) + currentBarrel?.let { swapBarrel(it) } + unlock(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + unlock(player) + } + + private fun swapBarrel(barrel: Scenery) { + val emptyIndex = emptyAppleBarrels.indexOf(barrel.id) + val fullIndex = fullAppleBarrels.indexOf(barrel.id) + val newId = when { + emptyIndex != -1 -> fullAppleBarrels[emptyIndex] + fullIndex != -1 -> emptyAppleBarrels[fullIndex] + else -> return + } + replaceScenery(barrel, newId, -1) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/fermenting/BrewGrowth.kt b/Server/src/main/content/global/skill/cooking/fermenting/BrewGrowth.kt new file mode 100644 index 000000000..a3baec569 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/BrewGrowth.kt @@ -0,0 +1,119 @@ +package content.global.skill.cooking.fermenting + +import core.api.log +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.PersistTimer +import core.tools.Log +import core.tools.secondsToTicks +import org.json.simple.JSONArray +import org.json.simple.JSONObject + +/** + * The timer for regular brewing operations + */ + +const val brewCycleTime = 6 /*hours*/ * 60 /*minutes per hour*/ * 100 /*ticks per minute*/ + +class BrewGrowth : PersistTimer(brewCycleTime, "cooking:brewing", isSoft = true) { + private val vatMap = HashMap() + lateinit var player: Player + + override fun onRegister(entity: Entity) { + player = (entity as? Player)!! + for (vat in vatMap.values.toList()){ + catchUp(vat.nextBrew) + } + } + + override fun save(root: JSONObject, entity: Entity) { + player = (entity as? Player)!! + val vats = JSONArray() + for ((key, vat) in vatMap.entries.toList()){ + val isBrewingStage = vat.stage in listOf( + BrewingStage.MIXED, + BrewingStage.BREWING1, + BrewingStage.BREWING2, + BrewingStage.DONE, + BrewingStage.MATURE, + BrewingStage.BAD + ) + + if (isBrewingStage) { + val v = JSONObject() + v["brew-ordinal"] = key + v["brew-stuff"] = vat.theStuff + v["brewing-nextBrew"] = vat.nextBrew + v["brewing-stage"] = vat.stage.ordinal + v["brewing-item"] = vat.brewingItem?.ordinal + vats.add(v) + } + } + root["brewing"] = vats + } + + override fun parse(root: JSONObject, entity: Entity) { + player = (entity as? Player)!! + val data = root["brewing"] as JSONArray + for (d in data){ + val v = d as JSONObject + val vatOrdinal = v["brew-ordinal"].toString().toInt() + val vatStuff = v["brew-stuff"].toString().toBoolean() + val vatNextBrew = v["brewing-nextBrew"].toString().toLong() + val vatStage = BrewingStage.values()[v["brewing-stage"].toString().toInt()] + val vatItem = v["brewing-item"]?.toString()?.toIntOrNull()?.let { + Brewable.values().getOrNull(it) + } + + if (vatMap[vatOrdinal] == null){ + val brewingVat = BrewingVat.values()[vatOrdinal] + val vat = Vat(player, brewingVat, vatStuff, vatNextBrew, vatStage, vatItem) + vatMap[vatOrdinal] = vat + vat.updateVat() + } + } + } + + fun getVat(brewingVat: BrewingVat, addVat: Boolean = true) : Vat { + return vatMap[brewingVat.ordinal] ?: (Vat(player, brewingVat).also { if (addVat) vatMap[brewingVat.ordinal] = it }) + } + + private fun catchUp(timeTillGrow: Long){ + if (timeTillGrow < System.currentTimeMillis()){ + val seconds = (System.currentTimeMillis() - timeTillGrow)/1000 + if (seconds > Int.MAX_VALUE){ + execute(1024) + } + else{ + val cyclesToGrow = secondsToTicks(seconds.toInt()) / brewCycleTime + execute(cyclesToGrow) + } + } + + } + + override fun run(entity: Entity): Boolean { + player = (entity as? Player)!! + return execute(0) + } + + private fun execute(count: Int) : Boolean { + for (vat in vatMap.entries.toList()){ + if (vat.value.canBrew()) + for (i in 0..count){ + val resp = vat.value.brew() + if (!resp){ + break + } + } + else { + vatMap.entries.removeIf { it.value.isVatEmpty() && it.value.isBarrelEmpty()} + } + } + return vatMap.isNotEmpty() + } + + fun getVats(): MutableCollection{ + return vatMap.values + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/fermenting/Brewable.kt b/Server/src/main/content/global/skill/cooking/fermenting/Brewable.kt new file mode 100644 index 000000000..9f6eab619 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/Brewable.kt @@ -0,0 +1,32 @@ +package content.global.skill.cooking.fermenting + +import org.rs09.consts.Items + + +enum class Brewable (val displayName: String, val itemID: Int, val level: Int, val product: IntArray, val levelXP: Double, val vatVarBitOffset: Int, + val barrelVarBitOffset: Int, val ingredientAmount: Int = 4){ + DWARVEN_STOUT("Dwarven Stout", Items.HAMMERSTONE_HOPS_5994, 19, intArrayOf(Items.DWARVEN_STOUT_1913, Items.DWARVEN_STOUT4_5777, Items.DWARVEN_STOUTM_5747, Items.DWARVEN_STOUTM4_5857), 215.0, 4, 8), + ASGARNIAN_ALE("Asgarnian Ale", Items.ASGARNIAN_HOPS_5996, 26, intArrayOf(Items.ASGARNIAN_ALE_1905, Items.ASGARNIAN_ALE4_5785, Items.ASGARNIAN_ALEM_5739, Items.ASGARNIAN_ALEM4_5865), 248.0, 10, 16), + GREENMANS_ALE("Greenman's Ale", Items.CLEAN_HARRALANDER_255, 29, intArrayOf(Items.GREENMANS_ALE_1909, Items.GREENMANS_ALE4_5793, Items.GREENMANS_ALEM_5743, Items.GREENMANS_ALEM4_5873), 281.0, 16, 24), + WIZARD_BOMB("Wizard's Mind Bomb", Items.YANILLIAN_HOPS_5998, 34, intArrayOf(Items.WIZARDS_MIND_BOMB_1907, Items.MIND_BOMB4_5801, Items.MATURE_WMB_5741, Items.MIND_BOMBM4_5881), 341.0, 22, 32), + DRAGON_BITTER("Dragon Bitter", Items.KRANDORIAN_HOPS_6000, 39, intArrayOf(Items.DRAGON_BITTER_1911, Items.DRAGON_BITTER4_5809, Items.DRAGON_BITTERM_5745, Items.DRAGON_BITTERM4_5889), 347.0, 28, 40), + MOONLIGHT_MEAD("Moonlight Mead", Items.MUSHROOM_6004, 44, intArrayOf(Items.MOONLIGHT_MEAD_2955, Items.MOONLIGHT_MEAD4_5817, Items.MOONLIGHT_MEADM_5749, Items.MLIGHT_MEADM4_5897), 380.0, 34, 48), + AXEMANS_FOLLY("Axeman's Folly", Items.OAK_ROOTS_6043, 49, intArrayOf(Items.AXEMANS_FOLLY_5751, Items.AXEMANS_FOLLY4_5825, Items.AXEMANS_FOLLYM_5753, Items.AXEMANS_FOLLYM4_5905), 413.0, 40, 56, 1), + CHEFS_DELIGHT("Chef's Delight", Items.CHOCOLATE_DUST_1975, 54, intArrayOf(Items.CHEFS_DELIGHT_5755, Items.CHEFS_DELIGHT4_5833, Items.CHEFS_DELIGHTM_5757, Items.CHEFS_DELIGHTM4_5913), 446.0, 46, 64), + SLAYERS_RESPITE("Slayer's Respite", Items.WILDBLOOD_HOPS_6002, 59, intArrayOf(Items.SLAYERS_RESPITE_5759, Items.SLAYERS_RESPITE4_5841, Items.SLAYERS_RESPITEM_5761, Items.SLAYER_RESPITEM4_5921), 479.0, 52, 72), + CIDER("cider", Items.APPLE_MUSH_5992, 14, intArrayOf(Items.CIDER_5763, Items.CIDER4_5849, Items.MATURE_CIDER_5765, Items.CIDERM4_5929), 182.0, 58, 80), + KELDA_STOUT("Kelda Stout", Items.KELDA_HOPS_6113, 22, intArrayOf(Items.KELDA_STOUT_6118), 0.0, 68, 3, 1); + + + companion object { + fun getIngredients() : IntArray{ + return values().map { it.itemID }.toIntArray() + } + + fun getBrewable(itemId: Int) : Brewable?{ + return values().find { it.itemID == itemId } + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/fermenting/BrewingListener.kt b/Server/src/main/content/global/skill/cooking/fermenting/BrewingListener.kt new file mode 100644 index 000000000..185550072 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/BrewingListener.kt @@ -0,0 +1,232 @@ +package content.global.skill.cooking.fermenting + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery + + +const val KELDAGRIM_LOC = 11679 +const val PORT_PHASMATYS_LOC = 14747 + +val varbits = mapOf( + PORT_PHASMATYS_LOC to BrewingVat.PORT_PHAS, + KELDAGRIM_LOC to BrewingVat.KELDAGRIM +) + +class BrewingListener : InteractionListener { + + private val aleIngredientsId = Brewable.getIngredients() + + private val vatsNeedingYeast = intArrayOf( + Scenery.FERMENTING_VAT_7444, // Hammerstone hops + Scenery.FERMENTING_VAT_7449, // Asgarnian hops + Scenery.FERMENTING_VAT_7454, // Harralander + Scenery.FERMENTING_VAT_7459, // Yanillian hops + Scenery.FERMENTING_VAT_7464, // Krandorian hops + Scenery.FERMENTING_VAT_7469, // Bittercap mushrooms + Scenery.FERMENTING_VAT_7474, // Oak roots + Scenery.FERMENTING_VAT_7479, // Chocolate dust + Scenery.FERMENTING_VAT_7484, // Wildblood hops + Scenery.FERMENTING_VAT_7489, // Apple mush + Scenery.FERMENTING_VAT_8871 // Kelda hops + ) + + // Const Lib is missing some of these + private val drainBarrels = intArrayOf( + Scenery.BARREL_7408, + Scenery.BARREL_7409, + Scenery.BARREL_7410, + + ) + private val barrels = intArrayOf( + Scenery.KELDA_STOUT_8870, + Scenery.DWARVEN_STOUT_7411, + Scenery.ASGARNIAN_ALE_7413, + Scenery.GREENMANS_ALE_7415, + Scenery.WIZARDS_MIND_BOMB_7417, + Scenery.DRAGON_BITTER_7419, + Scenery.MOONLIGHT_MEAD_7421, + Scenery.AXEMAN_S_FOLLY_7423, + Scenery.CHEF_S_DELIGHT_7425, + Scenery.SLAYER_S_RESPITE_7427, + Scenery.CIDER_7429, + Scenery.MATURE_DWARVEN_STOUT_7412, + Scenery.MATURE_ASGARNIAN_ALE_7414, + Scenery.MATURE_GREENMANS_ALE_7416, + Scenery.MATURE_WIZARDS_MIND_BOMB_7418, + Scenery.MATURE_DRAGON_BITTER_7420, + Scenery.MATURE_MOONLIGHT_MEAD_7422, + Scenery.MATURE_AXEMAN_S_FOLLY_7424, + Scenery.MATURE_CHEF_S_DELIGHT_7426, + Scenery.MATURE_SLAYER_S_RESPITE_7428, + Scenery.MATURE_CIDER_7430 + ) + + + override fun defineListeners() { + + // Fill an empty vat with water - self-contained operation + onUseWith(SCENERY, Items.BUCKET_OF_WATER_1929, Scenery.FERMENTING_VAT_7437) { player, _, _ -> + if (removeItem(player, Item(Items.BUCKET_OF_WATER_1929, 2))) { + queueScript(player, 0) { + addItem(player, Items.BUCKET_1925, 2) + + lock(player, Animation(2283).duration) + animate(player, Animation(2283)) + + sendMessage(player, "You add some water to the vat.") + + val vatVarbit = varbits.getValue(player.location.regionId).varbit + setVarbit(player, vatVarbit, 1, true) + return@queueScript (stopExecuting(player)) + } + } + else{ + sendDialogue(player, "You need 2 buckets of water.") + } + return@onUseWith true + } + + // Fill an empty vat with apple mush + onUseWith(SCENERY, Items.APPLE_MUSH_5992, Scenery.FERMENTING_VAT_7437) { player, used, _ -> + getVat(player).addIngredient(used as Item) + return@onUseWith true + } + + // Add barley malt to a vat with water - self-contained operation + onUseWith(SCENERY, Items.BARLEY_MALT_6008, Scenery.FERMENTING_VAT_7438) { player, _, _ -> + if (inInventory(player, Items.BARLEY_MALT_6008, 2)) { + queueScript(player, 0, QueueStrength.SOFT) { counter -> + when (counter) { + 0 -> { + if (!removeItem(player, Item(Items.BARLEY_MALT_6008, 1))) { return@queueScript stopExecuting(player) } + + lock(player, Animation(2295).duration * 2 + 2) + animate(player, Animation(2295)) + + sendMessage(player, "You add some barley malt to the vat.") + + return@queueScript delayScript(player, Animation(2295).duration + 1) + } + 1 -> { + if (!removeItem(player, Item(Items.BARLEY_MALT_6008, 1))) { return@queueScript stopExecuting(player) } + + stopWalk(player) + animate(player, Animation(2295)) + + val vatVarbit = varbits.getValue(player.location.regionId).varbit + setVarbit(player, vatVarbit, 2, true) + + return@queueScript delayScript(player, Animation(2295).duration + 1) + } + 2 -> { + stopWalk(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + else{ + sendDialogue(player, "You need 2 barley malt.") + } + return@onUseWith true + } + + // Add The Stuff to a vat with malt + onUseWith(SCENERY, Items.THE_STUFF_8988, Scenery.FERMENTING_VAT_7441) { player, _, _ -> + if (inInventory(player, Items.THE_STUFF_8988, 1)) { + getVat(player).addTheStuff() + } + return@onUseWith true + } + + // Add ingredients to a vat with malt + onUseWith(SCENERY, aleIngredientsId, Scenery.FERMENTING_VAT_7441) { player, used, _ -> + if (used.id == Items.APPLE_MUSH_5992) { + sendDialogue(player, "Apple mush needs to be added to an empty vat.") + return@onUseWith false + } + // If you try to make Kelda Stout in Port Phasmatys the vat deletes itself forever + if (used.id == Items.KELDA_HOPS_6113 && player.location.regionId != KELDAGRIM_LOC) { + sendMessage(player, "Nothing interesting happens.") + return@onUseWith false + } + // Branch off into Kelda Stout logic + if (used.id == Items.KELDA_HOPS_6113 && player.location.regionId == KELDAGRIM_LOC) { + KeldaBypasses.keldaAddHops(player) + return@onUseWith true + } + getVat(player).addIngredient(used as Item) + return@onUseWith true + } + + // Add yeast to a vat that's ready to brew + onUseWith(SCENERY, Items.ALE_YEAST_5767, *vatsNeedingYeast) { player, _, with -> + if (inInventory(player, Items.ALE_YEAST_5767, 1)) { + // Branch off into Kelda Stout logic + if (with.id == Scenery.FERMENTING_VAT_8871 && + player.location.regionId == KELDAGRIM_LOC && + getVarbit(player, 736) == 68) { // 68 = Kelda MIXED state + KeldaBypasses.keldaAddYeast(player) + return@onUseWith true + } + getVat(player).addYeast() + } + return@onUseWith true + } + + // Turn the valve to empty a vat into a barrel + on(intArrayOf(Scenery.VALVE_7442, Scenery.VALVE_7443), SCENERY, "turn") { player, _ -> + // Branch off into Kelda Stout logic + when { + (player.location.regionId == KELDAGRIM_LOC && KeldaBypasses.keldaIsBrewing(player)) -> + sendMessage(player, "The contents of the vat haven't finished fermenting yet.") + (player.location.regionId == KELDAGRIM_LOC && KeldaBypasses.keldaIsComplete(player)) -> + KeldaBypasses.keldaTurnValve(player) + else -> getVat(player).turnValve() + } + return@on true + } + + // Drain a barrel of bad ale + on(drainBarrels, SCENERY, "Drain") { player, _ -> + getVat(player).drainBarrel() + return@on true + } + + // Level a barrel (clicking on it) + on(barrels, SCENERY, "Level") { player, _ -> + queueScript(player, 1) { + val goAgain : Boolean + if (inInventory(player, Items.BEER_GLASS_1919)) { + goAgain = getVat(player).levelBarrel(Items.BEER_GLASS_1919) + } + else if (inInventory(player, Items.CALQUAT_KEG_5769)) { + goAgain = getVat(player).levelBarrel(Items.CALQUAT_KEG_5769) + } + else{ + goAgain = false + sendDialogue(player, "You need a container to level the barrel.") + } + return@queueScript if(goAgain) delayScript(player, 1) else stopExecuting(player) + } + return@on true + } + + // Level a barrel (using a container on it) + onUseWith(SCENERY, intArrayOf(Items.BEER_GLASS_1919, Items.CALQUAT_KEG_5769), *barrels) { player, used, _ -> + getVat(player).levelBarrel(used.id) + return@onUseWith true + } + } + + private fun getVat(player: Player) : Vat { + return varbits.getValue(player.location.regionId).getVat(player) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/fermenting/CalquatDecant.kt b/Server/src/main/content/global/skill/cooking/fermenting/CalquatDecant.kt new file mode 100644 index 000000000..c431bbd41 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/CalquatDecant.kt @@ -0,0 +1,217 @@ +package content.global.skill.cooking.fermenting + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items + +object CalquatDecant { + + // Consumables.java hurts my eyes so I did this instead + data class CalquatKegs ( + val emptyKeg: Int = Items.CALQUAT_KEG_5769, + val fourDose: Int, val threeDose: Int = fourDose - 2, val twoDose: Int = threeDose - 2, val oneDose: Int = twoDose - 2, val glass: Int, + val fourMature: Int, val threeMature: Int = fourMature - 2, val twoMature: Int = threeMature - 2, val oneMature: Int = twoMature - 2, val matureGlass: Int + ) + + val calquatDrinks = + Brewable.values() + .filter { it.product.size == 4 } + .associateWith { CalquatKegs ( + fourDose = it.product[1], + glass = it.product[0], + fourMature = it.product[3], + matureGlass = it.product[2] + ) + } + + // Array of all kegs with nonzero contents + val allKegIds: IntArray by lazy { + calquatDrinks.values.flatMap { keg -> + listOf( + keg.fourDose, keg.threeDose, keg.twoDose, keg.oneDose, + keg.fourMature, keg.threeMature, keg.twoMature, keg.oneMature + ) + }.distinct().toIntArray() + } + + // Reverse lookup map + private val kegLookupMap: Map> by lazy { + calquatDrinks.entries.flatMap { (brewable, kegs) -> + listOf( + kegs.fourDose, kegs.threeDose, kegs.twoDose, kegs.oneDose, + kegs.fourMature, kegs.threeMature, kegs.twoMature, kegs.oneMature + ).map { itemId -> itemId to (brewable to kegs) } + }.toMap() + } + + // Check what a keg is so it can be related to other kegs + fun getKeg(itemId: Int): Pair? = kegLookupMap[itemId] + + // Check if an item is a keg + fun isKeg(itemId: Int): Boolean = kegLookupMap.containsKey(itemId) + + // Check how full a keg is + fun getDoseByKeg(itemId: Int, kegs: CalquatKegs): Int { + return when (itemId) { + kegs.fourDose, kegs.fourMature -> 4 + kegs.threeDose, kegs.threeMature -> 3 + kegs.twoDose, kegs.twoMature -> 2 + kegs.oneDose, kegs.oneMature -> 1 + else -> 0 + } + } + + // Check if a keg contains matured ale + fun isMature(itemId: Int, kegs: CalquatKegs): Boolean { + return itemId == kegs.fourMature || itemId == kegs.threeMature || + itemId == kegs.twoMature || itemId == kegs.oneMature + } + + // Identifies a keg's category by its contents + fun getKegByDose(kegs: CalquatKegs, dose: Int, mature: Boolean): Int { + return if (!mature) { + when (dose) { + 4 -> kegs.fourDose + 3 -> kegs.threeDose + 2 -> kegs.twoDose + 1 -> kegs.oneDose + else -> kegs.emptyKeg + } + } else { + when (dose) { + 4 -> kegs.fourMature + 3 -> kegs.threeMature + 2 -> kegs.twoMature + 1 -> kegs.oneMature + else -> kegs.emptyKeg + } + } + } + + // Decanting function (NPC) - should work the same as potions + fun decantCalquat(container: core.game.container.Container): Pair, List> { + val doseCount = HashMap, Int>() // (Brewable, isMature), Total Doses + val toRemove = ArrayList() + val toAdd = ArrayList() + + // Count up all doses grouped by keg type and maturity + for (item in container.toArray()) { + if (item == null) continue + val kegInfo = getKeg(item.id) ?: continue + val (brewable, kegs) = kegInfo + val dose = getDoseByKeg(item.id, kegs) + if (dose == 0) continue + val mature = isMature(item.id, kegs) + val key = brewable to mature + doseCount[key] = (doseCount[key] ?: 0) + dose + toRemove.add(item) + } + + // Convert doses back into kegs + for ((key, totalDoses) in doseCount) { + val (brewable, mature) = key + val kegs = calquatDrinks[brewable] ?: continue + + val fullKegs = totalDoses / 4 // Number of 4-dose kegs + val remainderDose = totalDoses % 4 // Leftover doses + + if (fullKegs > 0) + toAdd.add(Item(getKegByDose(kegs, 4, mature), fullKegs)) + if (remainderDose > 0) + toAdd.add(Item(getKegByDose(kegs, remainderDose, mature))) + } + + // Add empty kegs for removed containers + val emptyKegs = toRemove.size - toAdd.sumOf { it.amount } + if (emptyKegs > 0) { + val firstKegs = calquatDrinks.values.firstOrNull() + if (firstKegs != null) + toAdd.add(Item(firstKegs.emptyKeg, emptyKegs)) + } + + return Pair(toRemove, toAdd) + } + + // Decanting function (manual) - should work the same as potions + fun combineKegs(player: Player, used: Item, with: Item): Boolean { + // Identify both kegs + val (usedBrewable, kegs) = getKeg(used.id) ?: return false + val (withBrewable, _) = getKeg(with.id) ?: return false + + // Verify the same drink is in both kegs + if (usedBrewable != withBrewable) return false + + val usedMature = isMature(used.id, kegs) + val withMature = isMature(with.id, kegs) + + // Verify the same maturity status is in both kegs + if (usedMature != withMature) return false + + // Get doses + val usedDose = getDoseByKeg(used.id, kegs) + val withDose = getDoseByKeg(with.id, kegs) + + // Disallow combining full or empty kegs + if (usedDose == 4 || withDose == 4 || usedDose == 0 || withDose == 0) { + return false + } + + val totalDosage = usedDose + withDose + val fullDoses = totalDosage / 4 + val leftoverDose = totalDosage % 4 + + // Replace the targeted keg with a (4) dose keg + if (fullDoses != 0) { + replaceSlot(player, with.slot, Item(getKegByDose(kegs, 4, usedMature)), with, Container.INVENTORY) + } + + // Replace the targeted keg with the updated dosage amount + if (leftoverDose != 0 && fullDoses == 0) { + replaceSlot(player, with.slot, Item(getKegByDose(kegs, leftoverDose, usedMature)), with, Container.INVENTORY) + + // Replace the used with keg with the updated dosage amount + } else if (leftoverDose != 0) { + replaceSlot(player, used.slot, Item(getKegByDose(kegs, leftoverDose, usedMature)), used, Container.INVENTORY) + } + + // Replace the used with keg with an empty keg + if (leftoverDose == 0 || fullDoses == 0) { + replaceSlot(player, used.slot, Item(kegs.emptyKeg), used, Container.INVENTORY) + } + + // Send message/Play sound + val amountString = when { + totalDosage >= 4 -> "four" + totalDosage == 3 -> "three" + else -> "two" + } + + sendMessage(player, "You have combined the kegs into $amountString pints.") + playAudio(player, 2401) + + return true + } + + // Decant keg into beer glass + fun pourIntoGlass(player: Player, glass: Item, keg: Item): Boolean { + // Find keg info + val kegInfo = getKeg(keg.id) ?: return false + val (_, kegs) = kegInfo + val currentDose = getDoseByKeg(keg.id, kegs) + val mature = isMature(keg.id, kegs) + if (currentDose == 0) { + return false + } + + // Fill the glass + val glassItem = if (mature) kegs.matureGlass else kegs.glass + replaceSlot(player, glass.slot, Item(glassItem), glass, Container.INVENTORY) + + // Drain the keg + val newDose = currentDose - 1 + replaceSlot(player, keg.slot, Item(getKegByDose(kegs, newDose, mature)), keg, Container.INVENTORY) + + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/fermenting/KeldaStoutGrowth.kt b/Server/src/main/content/global/skill/cooking/fermenting/KeldaStoutGrowth.kt new file mode 100644 index 000000000..37d4de77e --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/KeldaStoutGrowth.kt @@ -0,0 +1,108 @@ +package content.global.skill.cooking.fermenting + +import core.api.getVarbit +import core.api.sendMessage +import core.game.node.entity.Entity +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.system.timer.PersistTimer +import core.game.system.timer.RSTimer + +/** + * Independent brewing timer and functions exclusively for Kelda Stout + * Varbit progression: 68 (mixed) -> 69 (brewing1) -> 70 (brewing2) -> 71 (done) + */ + +class KeldaStoutGrowth : PersistTimer( 5 /*minutes*/ * 100 /*ticks per minute*/, "cooking:brewing-kelda", isSoft = true) { + lateinit var player: Player + + override fun run(entity: Entity): Boolean { + player = entity as Player + when (val currentVarbit = getVarbit(player, 736)) { + 69 -> { + setVarbit(player, 736, currentVarbit + 1) + return true + } + 70 -> { + setVarbit(player, 736, currentVarbit + 1) + sendMessage(player, "Perhaps I should have a look and see if my Kelda Stout has brewed...") + return false + } + else -> { + return false + } + } + } + + override fun getTimer(vararg args: Any): RSTimer { + return KeldaStoutGrowth() + } +} + + +object KeldaBypasses { + + fun keldaAddHops(player: Player) { + queueScript(player, 0) { + stopWalk(player) + if (!removeItem(player, Item(Items.KELDA_HOPS_6113, 1))) { return@queueScript stopExecuting(player) } + sendMessage(player, "You add some Kelda hops to the vat.") + lock(player, Animation(2295).duration + 1) + animate(player, Animation(2295)) + setVarbit(player, 736, getVarbit(player, 736) + 66) + return@queueScript stopExecuting(player) + } + } + + fun keldaAddYeast(player: Player) { + //addYeast() override + queueScript(player, 0) { + + if (!removeItem(player, Item(Items.ALE_YEAST_5767, 1))) { return@queueScript stopExecuting(player) } + addItem(player, Items.EMPTY_POT_1931) + + lock(player, Animation(2283).duration) + animate(player, Animation(2295)) + + sendMessage(player, "You add a pot of ale yeast to the vat.") + sendMessage(player, "The contents of the vat have begun to ferment.") + + setVarbit(player, 736, getVarbit(player, 736) + 1) + registerTimer(player, KeldaStoutGrowth()) + return@queueScript true + } + } + + fun keldaTurnValve(player: Player) { + queueScript(player, 0, QueueStrength.SOFT) { + + lock(player, Animation(780).duration) + animate(player, Animation(780)) + + sendMessage(player, "You turn the valve.") + + delayScript(player, 2) + + // Fill the barrel, then empty the vat + setVarbit(player, 738, 3, true) + setVarbit(player, 736, 0, true) + + sendMessage(player, "The barrel now contains 1 pint of Kelda Stout.") + return@queueScript stopExecuting(player) + } + } + + fun keldaIsBrewing(player: Player): Boolean { + val vatVarbit = getVarbit(player, 736) + return vatVarbit in 69..70 + } + + fun keldaIsComplete(player: Player): Boolean { + val vatVarbit = getVarbit(player, 736) + return vatVarbit == 71 + } +} diff --git a/Server/src/main/content/global/skill/cooking/fermenting/Vat.kt b/Server/src/main/content/global/skill/cooking/fermenting/Vat.kt new file mode 100644 index 000000000..e71f8850a --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/Vat.kt @@ -0,0 +1,366 @@ +package content.global.skill.cooking.fermenting + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items + + +class Vat (var player: Player, private val brewingVat : BrewingVat, var theStuff: Boolean, + var nextBrew: Long, var stage: BrewingStage, + var brewingItem : Brewable?) { + + private var barrelItem: Brewable? = null + + constructor(player: Player, brewingVat: BrewingVat) : + this(player, brewingVat, false, 0, BrewingStage.EMPTY, null) + + fun addTheStuff() { + if (!theStuff && removeItem(player, Item(Items.THE_STUFF_8988, 1))) { + theStuff = true + + lock(player, Animation(2283).duration) + animate(player, Animation(2283)) + + sendMessage(player, "You add The Stuff to the mixture in the vat.") + + } else { sendMessage(player, "Nothing interesting happens.") } + } + + fun addIngredient(item: Item): Boolean { + val ingredient = Brewable.getBrewable(item.id) ?: return false + if (getDynLevel(player, Skills.COOKING) < ingredient.level) { + sendDialogue(player, "You need a Cooking level of at least ${ingredient.level} in order to brew ${ingredient.displayName}.") + return false + } + if (!inInventory(player, item.id, ingredient.ingredientAmount)) { + val ingredientWord = if (ingredient.itemID == Items.MUSHROOM_6004) item.name+"s" else item.name + sendDialogue(player, "You need 4 $ingredientWord.") + return false + } + queueScript(player, 0, QueueStrength.SOFT) { counter -> + when (counter) { + 0 -> { + if (!removeItem(player, Item(item.id, 1))) { return@queueScript stopExecuting(player) } + if (ingredient.itemID == Items.APPLE_MUSH_5992) { + addItem(player, Items.BUCKET_1925) + } + + stopWalk(player) + animate(player, Animation(2295)) + + val ingredientWord = if (item.id == Items.MUSHROOM_6004) item.name+"s" else item.name + sendMessage(player, "You add some $ingredientWord to the vat.") + + if (ingredient.ingredientAmount == 1) { + lock(player, Animation(2295).duration) + + brewingItem = ingredient + stage = BrewingStage.MIXED + updateVat() + + return@queueScript stopExecuting(player) + } + + lock(player, Animation(2295).duration * 4 + 3) + return@queueScript delayScript(player, Animation(2295).duration + 1) + } + 1, 2 -> { + if (!removeItem(player, Item(item.id, 1))) { return@queueScript stopExecuting(player) } + if (ingredient.itemID == Items.APPLE_MUSH_5992) { + addItem(player, Items.BUCKET_1925) + } + + stopWalk(player) + animate(player, Animation(2295)) + + return@queueScript delayScript(player, Animation(2295).duration + 1) + } + 3 -> { + if (!removeItem(player, Item(item.id, 1))) { return@queueScript stopExecuting(player) } + if (ingredient.itemID == Items.APPLE_MUSH_5992) { + addItem(player, Items.BUCKET_1925) + } + + stopWalk(player) + animate(player, Animation(2295)) + + brewingItem = ingredient + stage = BrewingStage.MIXED + updateVat() + + return@queueScript delayScript(player, Animation(2295).duration) + } + 4 -> { + stopWalk(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return true + } + + fun addYeast() { + if (removeItem(player, Item(Items.ALE_YEAST_5767, 1))) { + addItem(player, Items.EMPTY_POT_1931) + + lock(player, Animation(2283).duration) + animate(player, Animation(2295)) + + sendMessage(player, "You add a pot of ale yeast to the vat.") + sendMessage(player, "The contents of the vat have begun to ferment.") + + stage = BrewingStage.BREWING1 + nextBrew = System.currentTimeMillis() + (brewCycleTime * 600) // ticks to ms + updateVat() + } else { + sendMessage(player, "Nothing interesting happens.") + } + } + + fun brew(forceStep: Boolean = false, forceGood: Boolean = false, forceMature: Boolean = false, forceBad: Boolean = false) : Boolean { + val resp = internalBrew(forceStep, forceGood, forceMature, forceBad) + updateVat() + return resp + } + + fun canBrew() : Boolean { + return listOf(BrewingStage.BREWING1, BrewingStage.BREWING2).any { it == stage } + } + + /** The meat of the brewing mechanic lives in the following internalBrew function + * No one has clearly documented how this should work + * Period sources are vague, unaccountable, and/or vary wildly in their claims + * https://x.com/JagexAsh/status/994867369460813824 + * Ash states that it was challenging to follow when he was trying to do it in OSRS + * + * If a good source is uncovered, this section can easily be configured to match it + * + * Current config results in the following behavior: + * Cooking level does not play a factor + * Chance to advance a step (or go bad) - 20% + * Chance to go bad when advancing - 25% + * Chance to mature (w/o The Stuff) - 05% + * Chance to mature (w/ The Stuff) - 50% + * Time per cycle (in BrewGrowth.kt) - 6 hours, or 36000 ticks + */ + + private fun internalBrew(forceStep: Boolean, forceGood: Boolean, forceMature: Boolean, forceBad: Boolean):Boolean { + nextBrew = System.currentTimeMillis() + (brewCycleTime * 600) // Ticks to ms + if (listOf(BrewingStage.BREWING1, BrewingStage.BREWING2).all{ it != stage}) { + return false + } + + // Step advancement check + if (RandomFunction.random(5) == 0 || forceStep || forceGood || forceMature || forceBad) { + if ((RandomFunction.random(4) == 0 || forceBad) && !forceGood && !forceMature) { + stage = BrewingStage.BAD + return false + } + stage = if (stage == BrewingStage.BREWING1) BrewingStage.BREWING2 else BrewingStage.DONE + } + + // Maturity check + if (stage == BrewingStage.DONE) { + sendMessage(player, "Perhaps I should have a look and see if my ${brewingItem!!.displayName} has brewed...") + val roll = if (theStuff) 2 else 20 + if ((RandomFunction.random(roll) == 0 || forceMature) && !forceGood) { + stage = BrewingStage.MATURE + } + return false + } + return true + } + + fun turnValve(){ + if (stage == BrewingStage.EMPTY) { + queueScript(player, 1) { + sendMessage(player, "Nothing interesting happens.") + return@queueScript stopExecuting(player) + } + return + } + if (getVarbit(player,this.brewingVat.varbit + 2) > 0) { + queueScript(player, 1) { + sendMessage(player, "The barrel is already full.") + return@queueScript stopExecuting(player) + } + return + } + if (stage == BrewingStage.BREWING1 || stage == BrewingStage.BREWING2) { + queueScript(player,1) { + sendMessage(player, "The contents of the vat haven't finished fermenting yet.") + return@queueScript stopExecuting(player) + } + return + } + lock(player, Animation(780).duration) + animate(player, Animation(780)) + + sendMessage(player, "You turn the valve.") + + if (stage == BrewingStage.MATURE || stage == BrewingStage.DONE) { + rewardXP(player, Skills.COOKING, brewingItem!!.levelXP) + queueScript(player, 2, QueueStrength.SOFT) { + sendMessage(player, "The barrel now contains 8 pints of ${brewingItem!!.displayName}.") + fillBarrel() + emptyVat() + updateVat() + return@queueScript stopExecuting(player) + } + } else { + fillBarrel() + emptyVat() + updateVat() + } + } + + private fun emptyVat() { + brewingItem = null + theStuff = false + stage = BrewingStage.EMPTY + updateVat() + } + + private fun fillBarrel() { + var varbitValue = 0 + when (stage){ + BrewingStage.EMPTY -> Unit + BrewingStage.WATER, + BrewingStage.MALT, + BrewingStage.MIXED, + BrewingStage.BREWING1, + BrewingStage.BREWING2 -> { + varbitValue = 4 + } + BrewingStage.DONE, + BrewingStage.MATURE -> { + barrelItem = brewingItem + val barrelAmount = 8 + + varbitValue = barrelItem?.barrelVarBitOffset ?: 0 + + if (barrelItem != null){ + varbitValue += (barrelAmount - 1) + if (stage == BrewingStage.MATURE) { + varbitValue += 128 + } + } + } + BrewingStage.BAD ->{ + varbitValue = if(brewingItem == Brewable.CIDER) 2 else 1 + } + } + setVarbit(player, this.brewingVat.varbit + 2, varbitValue, true) + } + + fun levelBarrel(container: Int): Boolean { + var value = getVarbit(player, this.brewingVat.varbit + 2) + if (value == 0) return false + + // Check for mature bit (128) and strip it for calculations + val isMature = value >= 128 + val baseValue = if (isMature) value - 128 else value + var servingsLeft = if(baseValue == 3) 1 else (baseValue % 8) + 1 + + val brewable = + if (baseValue == 3) Brewable.KELDA_STOUT + else Brewable.values()[(baseValue/8) - 1] + + val product = brewable.product + + if (container == Items.BEER_GLASS_1919) { + if(removeItem(player, container)) { + animate(player, Animation(2285)) + value-- + servingsLeft-- + val productIndex = if (isMature) 2 else 0 + sendMessage(player, "You pour a glass of ${brewable.displayName}.") + addItem(player, product[productIndex]) + } + } + else if (brewable == Brewable.KELDA_STOUT) { + sendDialogue(player, "You must use a glass to level Kelda Stout.") + return false + } + else if (container == Items.CALQUAT_KEG_5769) { + if(removeItem(player, container)){ + animate(player, Animation(2284)) + val servingsToTake = minOf(servingsLeft, 4) + value -= servingsToTake + servingsLeft -= servingsToTake + val filledKeg = CalquatDecant.calquatDrinks[brewable]!! + addItem(player, CalquatDecant.getKegByDose(filledKeg, servingsToTake, isMature)) + } + } + if (servingsLeft == 0) { + sendMessage(player, "The barrel is now empty.") + value = 0 + } + setVarbit(player, this.brewingVat.varbit + 2, value, true) + return servingsLeft != 0 + } + + fun drainBarrel() { + sendMessage(player, "You drain the barrel.") + setVarbit(player, this.brewingVat.varbit + 2, 0, true) + + } + + fun isVatEmpty(): Boolean { + return stage == BrewingStage.EMPTY + } + + fun isBarrelEmpty(): Boolean { + return getVarbit(player, (this.brewingVat.varbit + 2)) == 0 + } + + private fun getVatDisplay(): Int { + return when (stage){ + BrewingStage.EMPTY -> 0 + BrewingStage.WATER -> 1 + BrewingStage.MALT -> 2 + BrewingStage.MIXED -> brewingItem?.vatVarBitOffset ?: run { 0 } + BrewingStage.BREWING1 -> (brewingItem?.vatVarBitOffset?.plus(1)) ?: run { 0 } + BrewingStage.BREWING2 -> (brewingItem?.vatVarBitOffset?.plus(2)) ?: run { 0 } + BrewingStage.DONE -> (brewingItem?.vatVarBitOffset?.plus(3)) ?: run { 0 } + BrewingStage.MATURE -> (brewingItem?.vatVarBitOffset?.plus(4)) ?: run { 0 } + BrewingStage.BAD -> if (brewingItem == Brewable.CIDER) 65 else 64 + } + } + + fun updateVat(){ + setVarbit(player, this.brewingVat.varbit, this.getVatDisplay(), true) + } + +} + + +enum class BrewingStage { + EMPTY, + WATER, + MALT, + MIXED, + BREWING1, + BREWING2, + DONE, + MATURE, + BAD; +} + + +enum class BrewingVat(val varbit: Int) { + KELDAGRIM(736), + PORT_PHAS(737); + + fun getVat(player: Player): Vat { + val vat = getOrStartTimer(player) + return vat.getVat(this, true) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/ChocolateCakeListener.kt b/Server/src/main/content/global/skill/cooking/recipe/ChocolateCakeListener.kt new file mode 100644 index 000000000..0661c9417 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/ChocolateCakeListener.kt @@ -0,0 +1,31 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class ChocolateCakeListener : InteractionListener { + + val chocolate = intArrayOf(Items.CHOCOLATE_BAR_1973, Items.CHOCOLATE_DUST_1975) + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.CAKE_1891, *chocolate) { player, used, with -> + val product = Items.CHOCOLATE_CAKE_1897 + val level = 50 + val experience = 30.0 + val message = "" + val failMessage = "You need a Cooking level of $level in order to do that." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/CurryListener.kt b/Server/src/main/content/global/skill/cooking/recipe/CurryListener.kt new file mode 100644 index 000000000..b6be43bb4 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/CurryListener.kt @@ -0,0 +1,37 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import org.rs09.consts.Items + +class CurryListener : InteractionListener { + + val added = intArrayOf(Items.CURRY_LEAF_5970, Items.SPICE_2007) + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.UNCOOKED_STEW_2001, *added) { player, used, with -> + val product = Items.UNCOOKED_CURRY_2009 + val amountAdded = when (with.id) { + Items.CURRY_LEAF_5970 -> 3 + Items.SPICE_2007 -> 1 + else -> 0 + } + val level = 60 + val experience = 0.0 + val message = "You mix the spice with the stew." + val failMessage = "You need a Cooking level of at least $level in order to do this." + + return@onUseWith standardMix( + player, + used.asItem(), + Item(with.id, amountAdded), + product, + level, + experience, + message, + failMessage + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/HangoverRecipe.kt b/Server/src/main/content/global/skill/cooking/recipe/HangoverRecipe.kt new file mode 100644 index 000000000..063b85ce4 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/HangoverRecipe.kt @@ -0,0 +1,44 @@ +package content.global.skill.cooking.recipe + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items + +class HangoverRecipe : InteractionListener { + + companion object{ + private const val SNAPE_GRASS = Items.SNAPE_GRASS_231 + private const val HANGOVER_CURE = Items.HANGOVER_CURE_1504 + private const val BUCKET_OF_MILK = Items.BUCKET_OF_MILK_1927 + private const val CHOCOLATE_DUST = Items.CHOCOLATE_DUST_1975 + private const val CHOCOLATE_MILK = Items.CHOCOLATEY_MILK_1977 + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, CHOCOLATE_DUST, BUCKET_OF_MILK) { player, _, _ -> + if(hasLevelDyn(player, Skills.COOKING, 4)){ + if(removeItem(player, CHOCOLATE_DUST) and removeItem(player, BUCKET_OF_MILK)){ + addItem(player, CHOCOLATE_MILK) + sendItemDialogue(player, CHOCOLATE_MILK, "You mix the chocolate into the bucket.") + } + } + else { + sendDialogue(player, "You need a Cooking level of at least 4 to make chocolate milk.") + } + return@onUseWith true + } + + onUseWith(IntType.ITEM, SNAPE_GRASS, CHOCOLATE_MILK) { player, _, _ -> + if (removeItem(player, SNAPE_GRASS) && removeItem(player, CHOCOLATE_MILK)) + { + sendItemDialogue(player, HANGOVER_CURE, "You mix the snape grass into the bucket.") + addItem(player, HANGOVER_CURE) + return@onUseWith true + } + return@onUseWith false + } + + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/MixHandler.kt b/Server/src/main/content/global/skill/cooking/recipe/MixHandler.kt new file mode 100644 index 000000000..aa3b8bc59 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/MixHandler.kt @@ -0,0 +1,72 @@ +package content.global.skill.cooking.recipe + +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +fun standardMix(player: Player, used: Item, with: Item, product: Int, level: Int, experience: Double, message: String, failMessage: String): Boolean { + // Avoids sending dialogue if not enough ingredients to create (relevant only for curry leaves) + if (amountInInventory(player, used.id) < used.amount || amountInInventory(player, with.id) < with.amount) { + // Not sure about the authentic message + sendMessage(player, "You don't have enough ingredients to make that.") + return true + } + + // Avoids sending dialogue if only one can be created + if (amountInInventory(player, used.id) == used.amount || amountInInventory(player, with.id) == with.amount) { + if (getDynLevel(player, Skills.COOKING) < level) { + sendDialogue(player, failMessage) + return true + } + + if (removeItem(player, used) && removeItem(player, with)) { + sendMessage(player, message) + rewardXP(player, Skills.COOKING, experience) + addItem(player, product) + containerIngredient(player, used.id) + containerIngredient(player, with.id) + } + return true + } + + mixHandler( + player, + used, + with, + product, + level, + experience, + message, + failMessage + ).open() + return true +} + +private fun mixHandler(player: Player, used: Item, with: Item, product: Int, level: Int, experience: Double, message: String, failMessage: String): SkillDialogueHandler { + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, product.asItem()) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + MixScript(player, used, with, product, amount, level, experience, message, failMessage).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.COOKING) < level) { + sendDialogue(player, failMessage) + return false + } + return true + } + + override fun getAll(index: Int): Int { + return min( + amountInInventory(player, used.id)/used.amount, + amountInInventory(player, with.id)/with.amount + ) + } + } + return handler +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/MixScript.kt b/Server/src/main/content/global/skill/cooking/recipe/MixScript.kt new file mode 100644 index 000000000..245c078af --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/MixScript.kt @@ -0,0 +1,57 @@ +package content.global.skill.cooking.recipe + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +class MixScript( + private val player: Player, + private val used: Item, + private val with: Item, + private val product: Int, + private val sets: Int, + private val level: Int, + private val experience: Double, + private val message: String, + private val failMessage: String +) { + + private val delay = 2 + + fun invoke() { + queueScript(player, delay) { stage -> Int + if (getDynLevel(player, Skills.COOKING) < level) { + sendDialogue(player, failMessage) + return@queueScript stopExecuting(player) + } + + if (inInventory(player, used.id, used.amount) && inInventory(player, with.id, with.amount)) { + if(removeItem(player, used) && removeItem(player, with)) { + sendMessage(player, message) + rewardXP(player, Skills.COOKING, experience) + addItem(player, product) + containerIngredient(player, used.id) + containerIngredient(player, with.id) + } + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayScript(player, delay) + } + } +} + +fun containerIngredient(player: Player, ingredient: Int): Boolean{ + return when (ingredient) { + Items.BUCKET_OF_WATER_1929, Items.COMPOST_6032 -> addItem(player, Items.BUCKET_1925) + Items.FRIED_MUSHROOMS_7082 -> addItem(player, Items.BOWL_1923) + else -> false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/OomlieWrap.java b/Server/src/main/content/global/skill/cooking/recipe/OomlieWrap.java deleted file mode 100644 index d5e8ee5f7..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/OomlieWrap.java +++ /dev/null @@ -1,57 +0,0 @@ -package content.global.skill.cooking.recipe; - -import org.rs09.consts.Items; -import core.game.node.entity.skill.Skills; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * @author afaroutdude - */ -public class OomlieWrap extends Recipe { - - private static final Item OOMLIE_WRAP = new Item(Items.WRAPPED_OOMLIE_2341); - private static final Item RAW_OOMLIE = new Item(Items.RAW_OOMLIE_2337); - private static final Item PALM_LEAF = new Item(Items.PALM_LEAF_2339); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 50) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of 50 in order to do that."); - return; - } - super.mix(player, event); - } - - @Override - public Item getBase() { - return RAW_OOMLIE; - } - - @Override - public Item getProduct() { - return OOMLIE_WRAP; - } - - @Override - public Item[] getIngredients() { - return new Item[] { PALM_LEAF }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You wrap the raw oomlie in the palm leaf."; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/OomlieWrapListener.kt b/Server/src/main/content/global/skill/cooking/recipe/OomlieWrapListener.kt new file mode 100644 index 000000000..79024be71 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/OomlieWrapListener.kt @@ -0,0 +1,29 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class OomlieWrapListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.RAW_OOMLIE_2337, Items.PALM_LEAF_2339) { player, used, with -> + val product = Items.WRAPPED_OOMLIE_2341 + val level = 50 + val experience = 0.0 + val message = "You wrap the raw oomlie in the palm leaf." + val failMessage = "You need a Cooking level of at least $level in order to do that." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/PieListener.kt b/Server/src/main/content/global/skill/cooking/recipe/PieListener.kt new file mode 100644 index 000000000..8f6b1a841 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/PieListener.kt @@ -0,0 +1,79 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class PieListener : InteractionListener { + + val base = PieProduct.values().map { it.base }.toIntArray() + val added = PieProduct.values().map { it.added }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, base, *added) { player, used, with -> + val pie = PieProduct.productMap[used.id] ?: return@onUseWith true + + if (pie.added != with.id) { + return@onUseWith false + } + + val product = pie.product + val level = pie.minimumLevel + val experience = 0.0 + val message = "You fill the pie with ${pie.ingredientMessage}." + val failMessage = "You need a Cooking level of ${pie.minimumLevel} to make this." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } + + enum class PieProduct( + val base: Int, + val added: Int, + val product: Int, + val minimumLevel: Int, + val ingredientMessage: String, + ) { + REDBERRY_PIE(Items.REDBERRIES_1951, Items.PIE_SHELL_2315, Items.UNCOOKED_BERRY_PIE_2321, 10, "redberries"), + MEAT_PIE(Items.COOKED_MEAT_2142, Items.PIE_SHELL_2315, Items.UNCOOKED_MEAT_PIE_2319, 20, "meat"), + MUD_PIE_1(Items.COMPOST_6032, Items.PIE_SHELL_2315, Items.PART_MUD_PIE_7164, 29, "compost"), + MUD_PIE_2(Items.PART_MUD_PIE_7164, Items.BUCKET_OF_WATER_1929, Items.PART_MUD_PIE_7166, 29, "water"), + MUD_PIE_3(Items.PART_MUD_PIE_7166, Items.CLAY_434, Items.RAW_MUD_PIE_7168, 29, "clay"), + APPLE_PIE(Items.COOKING_APPLE_1955, Items.PIE_SHELL_2315, Items.UNCOOKED_APPLE_PIE_2317, 30, "cooking apple"), + GARDEN_PIE_1(Items.TOMATO_1982, Items.PIE_SHELL_2315, Items.PART_GARDEN_PIE_7172, 34, "tomato"), + GARDEN_PIE_2(Items.PART_GARDEN_PIE_7172, Items.ONION_1957, Items.PART_GARDEN_PIE_7174, 34, "onion"), + GARDEN_PIE_3(Items.PART_GARDEN_PIE_7174, Items.CABBAGE_1965, Items.RAW_GARDEN_PIE_7176, 34, "cabbage"), + FISH_PIE_1(Items.TROUT_333, Items.PIE_SHELL_2315, Items.PART_FISH_PIE_7182, 47, "trout"), + FISH_PIE_2(Items.PART_FISH_PIE_7182, Items.COD_339, Items.PART_FISH_PIE_7184, 47, "cod"), + FISH_PIE_3(Items.PART_FISH_PIE_7184, Items.POTATO_1942, Items.RAW_FISH_PIE_7186, 47, "potato"), + ADMIRAL_PIE_1(Items.SALMON_329, Items.PIE_SHELL_2315, Items.PART_ADMIRAL_PIE_7192, 70, "salmon"), + ADMIRAL_PIE_2(Items.PART_ADMIRAL_PIE_7192, Items.TUNA_361, Items.PART_ADMIRAL_PIE_7194, 70, "tuna"), + ADMIRAL_PIE_3(Items.PART_ADMIRAL_PIE_7194, Items.POTATO_1942, Items.RAW_ADMIRAL_PIE_7196, 70, "potato"), + WILD_PIE_1(Items.RAW_BEAR_MEAT_2136, Items.PIE_SHELL_2315, Items.PART_WILD_PIE_7202, 85, "raw bear meat"), + WILD_PIE_2(Items.PART_WILD_PIE_7202, Items.RAW_CHOMPY_2876, Items.PART_WILD_PIE_7204, 85, "raw chompy"), + WILD_PIE_3(Items.PART_WILD_PIE_7204, Items.RAW_RABBIT_3226, Items.RAW_WILD_PIE_7206, 85, "raw rabbit"), + SUMMER_PIE_1(Items.STRAWBERRY_5504, Items.PIE_SHELL_2315, Items.PART_SUMMER_PIE_7212, 95, "strawberry"), + SUMMER_PIE_2(Items.PART_SUMMER_PIE_7212, Items.WATERMELON_5982, Items.PART_SUMMER_PIE_7214, 95, "watermelon"), + SUMMER_PIE_3(Items.PART_SUMMER_PIE_7214, Items.COOKING_APPLE_1955, Items.RAW_SUMMER_PIE_7216, 95, "apple"), + ; + + companion object { + val productMap = HashMap() + + init { + for (pie in PieProduct.values()) { + productMap[pie.base] = pie + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/PieShellListener.kt b/Server/src/main/content/global/skill/cooking/recipe/PieShellListener.kt new file mode 100644 index 000000000..b0e075575 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/PieShellListener.kt @@ -0,0 +1,29 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class PieShellListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.PIE_DISH_2313, Items.PASTRY_DOUGH_1953) { player, used, with -> + val product = Items.PIE_SHELL_2315 + val level = 1 + val experience = 0.0 + val message = "You put the pastry dough into the pie dish to make a pie shell." + val failMessage = "" + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/PizzaListener.kt b/Server/src/main/content/global/skill/cooking/recipe/PizzaListener.kt new file mode 100644 index 000000000..f70c32f35 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/PizzaListener.kt @@ -0,0 +1,66 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class PizzaListener : InteractionListener { + + val base = PizzaProduct.values().map { it.base }.toIntArray() + val added = PizzaProduct.values().map { it.added }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, base, *added) { player, used, with -> + val pizza = PizzaProduct.productMap[used.id] ?: return@onUseWith true + + if (pizza.added != with.id) { + return@onUseWith false + } + + val product = pizza.product + val level = pizza.minimumLevel + val experience = pizza.experience + val message = "You add the ${pizza.message} to the pizza." + val failMessage = "You need a Cooking level of at least ${pizza.minimumLevel} in order to do this." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } + + enum class PizzaProduct( + val base: Int, + val added: Int, + val product: Int, + val minimumLevel: Int, + val experience: Double, + val message: String, + ) { + PIZZA_1(Items.TOMATO_1982, Items.PIZZA_BASE_2283, Items.INCOMPLETE_PIZZA_2285, 35, 0.0,"tomato"), + PIZZA_2(Items.CHEESE_1985, Items.INCOMPLETE_PIZZA_2285, Items.UNCOOKED_PIZZA_2287, 35, 0.0, "cheese"), + MEAT_PIZZA_1(Items.COOKED_MEAT_2142, Items.PLAIN_PIZZA_2289, Items.MEAT_PIZZA_2293, 45, 26.0, "meat"), + MEAT_PIZZA_2(Items.COOKED_CHICKEN_2140, Items.PLAIN_PIZZA_2289, Items.MEAT_PIZZA_2293, 45, 26.0, "cooked chicken"), + ANCHOVY_PIZZA(Items.ANCHOVIES_319, Items.PLAIN_PIZZA_2289, Items.ANCHOVY_PIZZA_2297, 55, 39.0, "anchovies"), + PINEAPPLE_PIZZA_1(Items.PINEAPPLE_CHUNKS_2116, Items.PLAIN_PIZZA_2289, Items.PINEAPPLE_PIZZA_2301, 65, 52.0, "pineapple"), + PINEAPPLE_PIZZA_2(Items.PINEAPPLE_RING_2118, Items.PLAIN_PIZZA_2289, Items.PINEAPPLE_PIZZA_2301, 65, 52.0, "pineapple"), + ; + + companion object { + val productMap = HashMap() + + init { + for (pizza in PizzaProduct.values()) { + productMap[pizza.base] = pizza + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/PotatoListener.kt b/Server/src/main/content/global/skill/cooking/recipe/PotatoListener.kt new file mode 100644 index 000000000..6e2cd5b5c --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/PotatoListener.kt @@ -0,0 +1,77 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class PotatoListener : InteractionListener { + + val added = PotatoProduct.values().map { it.added }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.BAKED_POTATO_6701, Items.PAT_OF_BUTTER_6697) { player, used, with -> + val product = Items.POTATO_WITH_BUTTER_6703 + val level = 39 + val experience = 40.5 + val message = "You add a pat of butter to the potato." + val failMessage = "You need a Cooking level of at least $level in order to do this." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + + onUseWith(IntType.ITEM, added, Items.POTATO_WITH_BUTTER_6703) { player, used, with -> + val topping = PotatoProduct.productMap[used.id] ?: return@onUseWith true + + val product = topping.product + val level = topping.minimumLevel + val experience = topping.experience + val message = "" + val failMessage = "You need a Cooking level of at least $level in order to do this." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } + + enum class PotatoProduct( + val added: Int, + val product: Int, + val minimumLevel: Int, + val experience: Double, + val message: String + ) { + CHEESE_POTATO(Items.CHEESE_1985, Items.POTATO_WITH_CHEESE_6705, 47, 10.0, ""), + CHILLI_POTATO(Items.CHILLI_CON_CARNE_7062, Items.CHILLI_POTATO_7054, 41, 15.0, ""), + EGG_POTATO(Items.EGG_AND_TOMATO_7064, Items.EGG_POTATO_7056, 51, 50.0, ""), + TUNA_POTATO(Items.TUNA_AND_CORN_7068, Items.TUNA_POTATO_7060, 68, 10.0, ""), + MUSHROOM_POTATO(Items.MUSHROOM_AND_ONION_7066, Items.MUSHROOM_POTATO_7058, 64, 55.0, ""), + ; + + companion object { + val productMap = HashMap() + + init { + for (topping in PotatoProduct.values()) { + productMap[topping.added] = topping + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/Recipe.java b/Server/src/main/content/global/skill/cooking/recipe/Recipe.java deleted file mode 100644 index 2402a9772..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/Recipe.java +++ /dev/null @@ -1,131 +0,0 @@ -package content.global.skill.cooking.recipe; - -import content.global.skill.cooking.recipe.pie.impl.*; -import content.global.skill.cooking.recipe.pizza.impl.AnchovyPizza; -import content.global.skill.cooking.recipe.pizza.impl.MeatPizza; -import content.global.skill.cooking.recipe.pizza.impl.PineapplePizza; -import content.global.skill.cooking.recipe.pizza.impl.PlainPizza; -import content.global.skill.cooking.recipe.potato.impl.*; -import content.global.skill.cooking.recipe.stew.CurryRecipe; -import content.global.skill.cooking.recipe.stew.StewRecipe; -import content.global.skill.cooking.recipe.topping.impl.*; -import content.global.skill.cooking.recipe.cake.ChocolateCake; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents a cooking recipe, this is dynamic that can range from a pie to a - * pizza. - * @author 'Vexia - * @date 21/12/2013 - */ -public abstract class Recipe { - - /** - * Represents the array of active recipes in 2009Scape. - */ - // TODO: - // - Making this an enum would drastically save on file/line count, since the recipes seem to mostly be plain-old-data classes - // - Making pie shells a recipe would make make-x for them just work - // - Making pineapple cutting a recipe would probably fix their make-x making all with any option - public static final Recipe[] RECIPES = new Recipe[] { - new RedberryPie(), new MeatPie(), new ApplePie(), new MudPie(), new GardenPie(), new FishPie(), new AdmiralPie(), new WildPie(), new SummerPie(), - new StewRecipe(), new CurryRecipe(), - new PlainPizza(), new MeatPizza(), new AnchovyPizza(), new PineapplePizza(), - new ChocolateCake(), - new ButterPotato(), new ChilliPotato(), new CheesePotato(), new EggPotato(), new MushroomPotato(), new TunaPotato(), - new SpicySauce(), new ChilliConCarne(), new UncookedEgg(), new EggAndTomato(), new MushroomAndOnion(), new ChoppedOnion(), new SlicedMushroom(), new ChoppedTuna(), new TunaAndCorn(), new OomlieWrap() - }; - - /** - * Method used to get the base item. - * @return the item. - */ - public abstract Item getBase(); - - /** - * Method used to get the product item. - * @return the product item. - */ - public abstract Item getProduct(); - - /** - * Method used to get the ingredients in this recipe. - * @return the ingredients. - */ - public abstract Item[] getIngredients(); - - /** - * Method used to get the part items made from ingredients. - * @return the part items. - */ - public abstract Item[] getParts(); - - /** - * Method used to get the mixing message. - * @param event the node usage event. - * @return the message used to mix. - */ - public abstract String getMixMessage(final NodeUsageEvent event); - - /** - * Method used to check if this is a singular one step recipe. - * @return True if so. - */ - public abstract boolean isSingular(); - - /** - * Method used to mix this recipes ingredients. - * @param player the player. - * @param event the event. - */ - public void mix(final Player player, final NodeUsageEvent event) { - if (getIngredients().length == 1) { - singleMix(player, event); - } else { - multipleMix(player, event); - } - } - - /** - * Method used to handle a single mixing. - * @param player the player. - * @param event the event. - */ - public void singleMix(final Player player, final NodeUsageEvent event) { - if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { - player.getInventory().add(getProduct()); - String message = getMixMessage(event); - if (message != null) { - player.getPacketDispatch().sendMessage(message); - } - } - } - - /** - * Method used to handle mixing multiple item recipes. - * @param player the player. - * @param event the event. - */ - public void multipleMix(final Player player, final NodeUsageEvent event) { - Item item = null; - int index = -1; - for (int counter = 0; counter < getIngredients().length; counter++) { - item = getIngredients()[counter]; - if (item.getId() == event.getUsedItem().getId() || item.getId() == event.getBaseItem().getId()) { - index = counter; - break; - } - } - if (index != -1) { - if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { - player.getInventory().add(getParts()[index + 1]); - String message = getMixMessage(event); - if (message != null) { - player.getPacketDispatch().sendMessage(message); - } - } - } - } -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/StewListener.kt b/Server/src/main/content/global/skill/cooking/recipe/StewListener.kt new file mode 100644 index 000000000..312aedcf0 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/StewListener.kt @@ -0,0 +1,62 @@ +package content.global.skill.cooking.recipe + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class StewListener : InteractionListener { + + val base = StewProduct.values().map { it.base }.toIntArray() + val added = StewProduct.values().map { it.added }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, base, *added) { player, used, with -> + val stew = StewProduct.productMap[used.id] ?: return@onUseWith true + + if (stew.added != with.id) { + return@onUseWith false + } + + val product = stew.product + val level = stew.minimumLevel + val experience = 0.0 + val message = "You cut up the ${stew.message} and put it into the stew." + val failMessage = "You need a Cooking level of at least ${stew.minimumLevel} in order to do this." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } + + enum class StewProduct( + val base: Int, + val added: Int, + val product: Int, + val minimumLevel: Int, + val message: String, + ) { + STEW_1(Items.POTATO_1942, Items.BOWL_OF_WATER_1921, Items.INCOMPLETE_STEW_1997, 25, "potato"), + STEW_2(Items.INCOMPLETE_STEW_1997, Items.COOKED_MEAT_2142, Items.UNCOOKED_STEW_2001, 25, "meat"), + STEW_3(Items.COOKED_MEAT_2142, Items.BOWL_OF_WATER_1921, Items.INCOMPLETE_STEW_1999, 25, "meat"), + STEW_4(Items.INCOMPLETE_STEW_1999, Items.POTATO_1942, Items.UNCOOKED_STEW_2001, 25, "potato"), + ; + + companion object { + val productMap = HashMap() + + init { + for (stew in StewProduct.values()) { + productMap[stew.base] = stew + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/ToppingListener.kt b/Server/src/main/content/global/skill/cooking/recipe/ToppingListener.kt new file mode 100644 index 000000000..68e5c55bb --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/ToppingListener.kt @@ -0,0 +1,84 @@ +package content.global.skill.cooking.recipe + +import core.api.inInventory +import core.api.sendDialogue +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class ToppingListener : InteractionListener { + + val base = ToppingProduct.values().map { it.base }.toIntArray() + val added = ToppingProduct.values().map { it.added }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, base, *added) { player, used, with -> + val topping = ToppingProduct.productMap[used.id] ?: return@onUseWith true + val verb = if (with.id == Items.COOKED_MEAT_2142) "cut" else "slice" + + if (topping.added != with.id) { + return@onUseWith false + } + + if (topping.cut_name != "" && !inInventory(player, Items.KNIFE_946)) { + sendDialogue(player, "You need a knife in order to $verb up the ${topping.cut_name}.") + return@onUseWith true + } + + val product = topping.product + val level = topping.minimumLevel + val experience = topping.experience + val message = topping.message + val failMessage = "You need a Cooking level of at least ${topping.minimumLevel} in order to do this." + + return@onUseWith standardMix( + player, + used.asItem(), + with.asItem(), + product, + level, + experience, + message, + failMessage + ) + } + } + + enum class ToppingProduct( + val base: Int, + val added: Int, + val product: Int, + val minimumLevel: Int, + val experience: Double, + val message: String, + val cut_name: String + ) { + //Tuna and Corn: https://www.youtube.com/watch?v=wAavERc9p2c + //Uncooked Egg: https://www.youtube.com/watch?v=LiLq6PhCc2M + //Bowl of sweetcorn (OSRS source is only I could find) https://www.youtube.com/watch?v=pz8epXjkKYE + + UNCOOKED_EGG(Items.EGG_1944, Items.BOWL_1923, Items.UNCOOKED_EGG_7076, 1, 0.0, "You carefully break the egg into the bowl.", ""), + BOWL_OF_SWEETCORN(Items.COOKED_SWEETCORN_5988, Items.BOWL_1923, Items.SWEETCORN_7088, 1, 0.0, "You put the cooked sweetcorn into the bowl.", ""), + SLICED_MUSHROOM(Items.MUSHROOM_6004, Items.BOWL_1923, Items.SLICED_MUSHROOMS_7080, 1, 0.0, "You chop the mushrooms into the bowl.", "mushrooms"), + CHOPPED_TUNA(Items.TUNA_361, Items.BOWL_1923, Items.CHOPPED_TUNA_7086, 1, 0.0, "You chop the tuna into the bowl.", "tuna"), + CHOPPED_ONION(Items.ONION_1957, Items.BOWL_1923, Items.CHOPPED_ONION_1871, 1, 0.0, "You chop the onion into the bowl.", "onion"), + CHOPPED_GARLIC(Items.GARLIC_1550, Items.BOWL_1923, Items.CHOPPED_GARLIC_7074, 1, 0.0, "You chop the garlic into the bowl.", "garlic"), + SPICY_SAUCE(Items.CHOPPED_GARLIC_7074, Items.GNOME_SPICE_2169, Items.SPICY_SAUCE_7072, 9, 25.0, "You mix the ingredients to make the topping.", ""), //inauthentic, used generic mixing message + CHILLI_CON_CARNE(Items.SPICY_SAUCE_7072, Items.COOKED_MEAT_2142, Items.CHILLI_CON_CARNE_7062, 9, 0.0, "You mix the ingredients to make the topping.", "meat"), //inauthentic, used generic mixing message + EGG_AND_TOMATO(Items.TOMATO_1982, Items.SCRAMBLED_EGG_7078, Items.EGG_AND_TOMATO_7064, 23, 50.0, "You mix the ingredients to make the topping.", ""), + MUSHROOM_AND_ONION(Items.FRIED_MUSHROOMS_7082, Items.FRIED_ONIONS_7084, Items.MUSHROOM_AND_ONION_7066, 57, 120.0, "You mix the ingredients to make the topping.", ""), + TUNA_AND_CORN_1(Items.CHOPPED_TUNA_7086, Items.COOKED_SWEETCORN_5988, Items.TUNA_AND_CORN_7068, 67, 204.0, "You mix the ingredients to make the topping.", ""), + TUNA_AND_CORN_2(Items.SWEETCORN_7088, Items.TUNA_361, Items.TUNA_AND_CORN_7068, 67, 204.0, "You mix the ingredients to make the topping.", "tuna"), + ; + + companion object { + val productMap = HashMap() + + init { + for (topping in ToppingProduct.values()) { + productMap[topping.base] = topping + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/recipe/cake/ChocolateCake.java b/Server/src/main/content/global/skill/cooking/recipe/cake/ChocolateCake.java deleted file mode 100644 index 97ef11d88..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/cake/ChocolateCake.java +++ /dev/null @@ -1,72 +0,0 @@ -package content.global.skill.cooking.recipe.cake; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.node.entity.skill.Skills; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the chocolate cake recipe. This recipe consists of adding a - * chocolate bar to a cake. - * @author 'Vexia - * @date 22/12/2013 - */ -public class ChocolateCake extends Recipe { - - /** - * Represents the cake item. - */ - private static final Item CAKE = new Item(1891); - - /** - * Represents the chocolate cake item. - */ - private static final Item CHOCOLATE_CAKE = new Item(1897); - - /** - * Represents the chocolate bar item. - */ - private static final Item CHOCOLATE_BAR = new Item(1973); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 50) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of 50 in order to do that."); - return; - } - super.mix(player, event); - player.getSkills().addExperience(Skills.COOKING, 30, true); - } - - @Override - public Item getBase() { - return CAKE; - } - - @Override - public Item getProduct() { - return CHOCOLATE_CAKE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { CHOCOLATE_BAR }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You add chocolate to the cake."; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/PieRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/pie/PieRecipe.java deleted file mode 100644 index 878a3333f..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/PieRecipe.java +++ /dev/null @@ -1,38 +0,0 @@ -package content.global.skill.cooking.recipe.pie; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.item.Item; - -/** - * Represents the generic recipe for a pie. - * @author 'Vexia - * @date 21/12/2013 - */ -public abstract class PieRecipe extends Recipe { - - /** - * Represents the pie shell item. - */ - protected static final Item PIE_SHELL = new Item(2315); - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public Item getBase() { - return PIE_SHELL; - } - - @Override - public String getMixMessage(final NodeUsageEvent event) { - return "You fill the pie with " + (event.getBaseItem().getId() == 2315 ? event.getUsedItem().getName().toLowerCase() : event.getBaseItem().getName().toLowerCase()) + "."; - } - - @Override - public boolean isSingular() { - return true; - } -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/AdmiralPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/AdmiralPie.java deleted file mode 100644 index 9cc6a98eb..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/AdmiralPie.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the admiral pie recipe. This recipe conists of pixing a salmon, - * tuna and potato together. - * @author 'Vexia - * @date 21/12/2013 - */ -public class AdmiralPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(7196); - - /** - * Represents the salmon ingredient item. - */ - private static final Item SALMON = new Item(329); - - /** - * Represents the tuna ingredient item. - */ - private static final Item TUNA = new Item(361); - - /** - * Represents the potato item. - */ - private static final Item POTATO = new Item(1942); - - /** - * Represents the part one pie item. - */ - private static final Item PART_ONE = new Item(7192); - - /** - * Represents the part two pie item. - */ - private static final Item PART_TWO = new Item(7194); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { SALMON, TUNA, POTATO }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/ApplePie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/ApplePie.java deleted file mode 100644 index e44917445..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/ApplePie.java +++ /dev/null @@ -1,34 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the apple pie recipe. This recipe consists of cooking apples and a - * pie shell. - * @author 'Vexia - * @date 21/12/2013 - */ -public class ApplePie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(2317); - - /** - * Represents the cooking apple item. - */ - private static final Item COOKING_APPLE = new Item(1955); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { COOKING_APPLE }; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/FishPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/FishPie.java deleted file mode 100644 index 7a1dad02f..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/FishPie.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the garden pie recipe. This pie consists of mixing, tomato, onion, - * and cabbage together. - * @author 'Vexia - * @date 21/12/2013 - */ -public class FishPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(7186); - - /** - * Represents the trout item ingredient. - */ - private static final Item TROUT = new Item(333); - - /** - * Represents the cod item ingredient. - */ - private static final Item COD = new Item(339); - - /** - * Represents the potato item. - */ - private static final Item POTATO = new Item(1942); - - /** - * Represents the part one pie item. - */ - private static final Item PART_ONE = new Item(7182); - - /** - * Represents the part two pie item. - */ - private static final Item PART_TWO = new Item(7184); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TROUT, COD, POTATO }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/GardenPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/GardenPie.java deleted file mode 100644 index 90fbe7e23..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/GardenPie.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the garden pie recipe. This pie consists of mixing, tomato, onion, - * and cabbage together. - * @author 'Vexia - * @date 21/12/2013 - */ -public class GardenPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(7176); - - /** - * Represents the tomato ingredient item. - */ - private static final Item TOMATO = new Item(1982); - - /** - * Represents the onion ingredient item. - */ - private static final Item ONION = new Item(1957); - - /** - * Represents the cabbage ingredient item. - */ - private static final Item CABBAGE = new Item(1965); - - /** - * Represents the part one pie item. - */ - private static final Item PART_ONE = new Item(7172); - - /** - * Represents the part two pie item. - */ - private static final Item PART_TWO = new Item(7174); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TOMATO, ONION, CABBAGE }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MeatPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MeatPie.java deleted file mode 100644 index 1edb223fd..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MeatPie.java +++ /dev/null @@ -1,58 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the meat pie recipe. - * @author 'Vexia - * @date 21/12/2013 - */ -public class MeatPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(2319); - - /** - * Represents the cooked meat item. - */ - private static final Item COOKED_MEAT = new Item(2142); - - /** - * Represents the cooked chicken item. - */ - private static final Item COOKED_CHICKEN = new Item(2140); - - /** - * Represents the cooked rabbit. - */ - private static final Item COOKED_RABBIT = new Item(3228); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getInventory().remove(event.getUsedItem()) && player.getInventory().remove(event.getBaseItem())) { - player.getInventory().add(getProduct()); - player.getPacketDispatch().sendMessage(getMixMessage(event)); - return; - } - } - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { COOKED_MEAT, COOKED_CHICKEN, COOKED_RABBIT }; - } - - @Override - public String getMixMessage(final NodeUsageEvent event) { - return "You fill the pie with meat."; - } -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MudPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MudPie.java deleted file mode 100644 index 64a542f46..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MudPie.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the mud pie recipe. A mud pie consists of mixing compost, water - * and clay together. - * @author 'Vexia - * @date 21/12/2013 - */ -public class MudPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(7168); - - /** - * Represents the compost item. - */ - private static final Item COMPOST = new Item(6032); - - /** - * Represents the bucket of water item. - */ - private static final Item BUCKET_OF_WATER = new Item(1929); - - /** - * Represents the clay item. - */ - private static final Item CLAY = new Item(434); - - /** - * Represents the part one pie item. - */ - private static final Item PART_ONE = new Item(7164); - - /** - * Represents the part two pie item. - */ - private static final Item PART_TWO = new Item(7166); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { COMPOST, BUCKET_OF_WATER, CLAY }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/RedberryPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/RedberryPie.java deleted file mode 100644 index 6ebbd04f6..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/RedberryPie.java +++ /dev/null @@ -1,33 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents a redberry pie recipe. - * @author 'Vexia - * @date 21/12/2013 - */ -public class RedberryPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(2321); - - /** - * Represents the redberries pie. - */ - private static final Item REDBERRIES = new Item(1951); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { REDBERRIES }; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/SummerPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/SummerPie.java deleted file mode 100644 index 14996852a..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/SummerPie.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the summer pie recipe. This recipe consists of mixing stawberry, - * watermelon, and an apple. - * @author 'Vexia - * @date 21/12/2013 - */ -public class SummerPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(7216); - - /** - * Represents the strawberry item. - */ - private static final Item STRAWBERRY = new Item(5504); - - /** - * Represents the watermelon item. - */ - private static final Item WATERMELON = new Item(5982); - - /** - * Represents the cooking apple item. - */ - private static final Item COOKING_APPLE = new Item(1955); - - /** - * Represents the part one pie item. - */ - private static final Item PART_ONE = new Item(7212); - - /** - * Represents the part two pie item. - */ - private static final Item PART_TWO = new Item(7214); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { STRAWBERRY, WATERMELON, COOKING_APPLE }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/WildPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/WildPie.java deleted file mode 100644 index 3b4decaa2..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/WildPie.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.global.skill.cooking.recipe.pie.impl; - -import content.global.skill.cooking.recipe.pie.PieRecipe; -import core.game.node.item.Item; - -/** - * Represents the wild pie recipe. This recipe consists of mixing raw beat meat, - * raw chomp, and raw rabbit into a pie shell. - * @author 'Vexia - * @date 21/12/2013 - */ -public class WildPie extends PieRecipe { - - /** - * Represents the uncooked redberry pie. - */ - private static final Item UNCOOKED_PIE = new Item(7206); - - /** - * Represents the raw bear meat item. - */ - private static final Item BEAR_MEAT = new Item(2136); - - /** - * Represents the raw chompy meat item. - */ - private static final Item CHOMPY_MEAT = new Item(2876); - - /** - * Represents the raw rabbit meat item. - */ - private static final Item RABBIT_MEAT = new Item(3226); - - /** - * Represents the part one pie item. - */ - private static final Item PART_ONE = new Item(7202); - - /** - * Represents the part two pie item. - */ - private static final Item PART_TWO = new Item(7204); - - @Override - public Item getProduct() { - return UNCOOKED_PIE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { BEAR_MEAT, CHOMPY_MEAT, RABBIT_MEAT }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/PizzaRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/PizzaRecipe.java deleted file mode 100644 index 5a1385a35..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pizza/PizzaRecipe.java +++ /dev/null @@ -1,63 +0,0 @@ -package content.global.skill.cooking.recipe.pizza; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the generic recipe for a pizza. - * @author ceikry - */ -public abstract class PizzaRecipe extends Recipe { - - /** - * Represents the plain pizza. - */ - protected static final Item PLAIN_PIZZA = new Item(2289); - - /** - * Method used to get the experience gained from adding the final - * ingredient. - * @return the experience. - */ - public abstract double getExperience(); - - /** - * Method used to get the level required. - * @return the level required. - */ - public abstract int getLevel(); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < getLevel()) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + getLevel() + " in order to do this."); - return; - } - super.singleMix(player, event); - player.getSkills().addExperience(Skills.COOKING, getExperience(), true); - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public Item getBase() { - return PLAIN_PIZZA; - } - - @Override - public String getMixMessage(final NodeUsageEvent event) { - return "You add " + event.getBaseItem().getName().toLowerCase() + " to the pizza."; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/AnchovyPizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/AnchovyPizza.java deleted file mode 100644 index 4a70625ff..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/AnchovyPizza.java +++ /dev/null @@ -1,44 +0,0 @@ -package content.global.skill.cooking.recipe.pizza.impl; - -import content.global.skill.cooking.recipe.pizza.PizzaRecipe; -import core.game.node.item.Item; - -/** - * Represents the anchovy pizza. This recipe consists of adding anchovies to a - * plain pizza. - * @author 'Vexia - * @date 22/12/2013 - */ -public class AnchovyPizza extends PizzaRecipe { - - /** - * Represents the anchovy pizza item. - */ - private static final Item ANCHOVY_PIZZA = new Item(2297); - - /** - * Represents the anchovies item. - */ - private static final Item ANCHOVIES = new Item(319); - - @Override - public double getExperience() { - return 39; - } - - @Override - public Item getProduct() { - return ANCHOVY_PIZZA; - } - - @Override - public Item[] getIngredients() { - return new Item[] { ANCHOVIES }; - } - - @Override - public int getLevel() { - return 55; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/MeatPizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/MeatPizza.java deleted file mode 100644 index b79096137..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/MeatPizza.java +++ /dev/null @@ -1,49 +0,0 @@ -package content.global.skill.cooking.recipe.pizza.impl; - -import content.global.skill.cooking.recipe.pizza.PizzaRecipe; -import core.game.node.item.Item; - -/** - * Represents the meat pizza recipe. This recipe consists of adding cooked meat - * to a plain pizza. - * @author 'Vexia - * @date 22/12/2013 - */ -public class MeatPizza extends PizzaRecipe { - - /** - * Represents the meat pizza item. - */ - private static final Item MEAT_PIZZA = new Item(2293); - - /** - * Represents the cooked meat item. - */ - private static final Item COOKED_MEAT = new Item(2142); - - /** - * Represents the cooked chicken item. - */ - private static final Item COOKED_CHICKEN = new Item(2140); - - @Override - public double getExperience() { - return 26; - } - - @Override - public int getLevel() { - return 45; - } - - @Override - public Item getProduct() { - return MEAT_PIZZA; - } - - @Override - public Item[] getIngredients() { - return new Item[] { COOKED_MEAT, COOKED_CHICKEN }; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PineapplePizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PineapplePizza.java deleted file mode 100644 index 7e4746e2f..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PineapplePizza.java +++ /dev/null @@ -1,55 +0,0 @@ -package content.global.skill.cooking.recipe.pizza.impl; - -import content.global.skill.cooking.recipe.pizza.PizzaRecipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.item.Item; - -/** - * Represents the pineapple pizza recipe. This recipe consists of mixing either - * pineapple chunks or pineapple rings. - * @author 'Vexia - * @date 22/12/2013 - */ -public class PineapplePizza extends PizzaRecipe { - - /** - * Represents the pineapple pizza item. - */ - private static final Item PINEAPPLE_PIZZA = new Item(2301); - - /** - * Represents the pineapple ring item. - */ - private static final Item PINEAPPLE_RING = new Item(2118); - - /** - * Represents the pineapple chunk item. - */ - private static final Item PINEAPPLE_CHUNKS = new Item(2116); - - @Override - public double getExperience() { - return 52; - } - - @Override - public int getLevel() { - return 65; - } - - @Override - public Item getProduct() { - return PINEAPPLE_PIZZA; - } - - @Override - public Item[] getIngredients() { - return new Item[] { PINEAPPLE_CHUNKS, PINEAPPLE_RING }; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You add the " + event.getBaseItem().getName().toLowerCase() + " to the pizza."; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PlainPizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PlainPizza.java deleted file mode 100644 index 8d624dca3..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PlainPizza.java +++ /dev/null @@ -1,81 +0,0 @@ -package content.global.skill.cooking.recipe.pizza.impl; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the plain pizza recipe. This recipe consists of mixing tomato, and - * cheese to a pizza base. - * @author 'Vexia - * @date 22/12/2013 - */ -public class PlainPizza extends Recipe { - - /** - * Represents the pizza base. - */ - private static final Item PIZZA_BASE = new Item(2283); - - /** - * Represents the uncooked pizza. - */ - private static final Item UNCOOKED_PIZZA = new Item(2287); - - /** - * Represents the incomplete pizza. - */ - private static final Item INCOMPLETE_PIZZA = new Item(2285); - - /** - * Represents the tomato ingredient item. - */ - private static final Item TOMATO = new Item(1982); - - /** - * Represents the cheese item. - */ - private static final Item CHEESE = new Item(1985); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 35) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 35 + " in order to do this."); - return; - } - super.mix(player, event); - } - - @Override - public Item getBase() { - return PIZZA_BASE; - } - - @Override - public Item getProduct() { - return UNCOOKED_PIZZA; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TOMATO, CHEESE }; - } - - @Override - public Item[] getParts() { - return new Item[] { PIZZA_BASE, INCOMPLETE_PIZZA, UNCOOKED_PIZZA }; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You add the " + event.getBaseItem().getName().toLowerCase() + " to the pizza."; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/PotatoRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/potato/PotatoRecipe.java deleted file mode 100644 index c2640a8bc..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/PotatoRecipe.java +++ /dev/null @@ -1,76 +0,0 @@ -package content.global.skill.cooking.recipe.potato; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents a generic potato topping recipe. - * @author 'Vexia - * @date 22/12/2013 - */ -public abstract class PotatoRecipe extends Recipe { - - /** - * Represents the potato with butter. - */ - private static final Item POTATO_WITH_BUTTER = new Item(6703); - - /** - * Represents the bowl item. - */ - protected static final Item BOWL = new Item(1923); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < getLevel()) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + getLevel() + " in order to do this."); - return; - } - super.singleMix(player, event); - if (isTopping()) { - player.getInventory().add(BOWL); - } - player.getSkills().addExperience(Skills.COOKING, getExperience(), true); - } - - @Override - public Item getBase() { - return POTATO_WITH_BUTTER; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return null; - } - - @Override - public boolean isSingular() { - return true; - } - - /** - * Method used to check if it is a topping recipe. - * @return True if it is a topping. - */ - public abstract boolean isTopping(); - - /** - * Method used to get the level required. - * @return the level. - */ - public abstract int getLevel(); - - /** - * Method used to get the experience gained. - * @return the experience. - */ - public abstract double getExperience(); -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ButterPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ButterPotato.java deleted file mode 100644 index b382a5029..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ButterPotato.java +++ /dev/null @@ -1,72 +0,0 @@ -package content.global.skill.cooking.recipe.potato.impl; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.node.entity.skill.Skills; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the butter potato recipe. This recipe consists of adding a pat of - * butter to a potato. - * @author 'Vexia - * @date 22/12/2013 - */ -public class ButterPotato extends Recipe { - - /** - * Represents the baked potato. - */ - private static final Item BAKED_POTATO = new Item(6701); - - /** - * Represents the potato with butter. - */ - private static final Item POTATO_WITH_BUTTER = new Item(6703); - - /** - * Represents the pat of butter. - */ - private static final Item PAT_OF_BUTTER = new Item(6697); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 39) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 39 + " in order to do this."); - return; - } - super.singleMix(player, event); - player.getSkills().addExperience(Skills.COOKING, 40.5, true); - } - - @Override - public Item getBase() { - return BAKED_POTATO; - } - - @Override - public Item getProduct() { - return POTATO_WITH_BUTTER; - } - - @Override - public Item[] getIngredients() { - return new Item[] { PAT_OF_BUTTER }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You add a pat of butter to the potato."; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/CheesePotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/CheesePotato.java deleted file mode 100644 index f111ed950..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/CheesePotato.java +++ /dev/null @@ -1,49 +0,0 @@ -package content.global.skill.cooking.recipe.potato.impl; - -import content.global.skill.cooking.recipe.potato.PotatoRecipe; -import core.game.node.item.Item; - -/** - * Represents the cheese potato. This recipe consists of mixing cheese witha - * baked potato. - * @author 'Vexia - * @date 22/12/2013 - */ -public class CheesePotato extends PotatoRecipe { - - /** - * Represents the cheese potato. - */ - private static final Item CHEESE_POTATO = new Item(6705); - - /** - * Represents the cheese item. - */ - private static final Item CHEESE = new Item(1985); - - @Override - public Item getProduct() { - return CHEESE_POTATO; - } - - @Override - public Item[] getIngredients() { - return new Item[] { CHEESE }; - } - - @Override - public boolean isTopping() { - return false; - } - - @Override - public int getLevel() { - return 47; - } - - @Override - public double getExperience() { - return 10; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ChilliPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ChilliPotato.java deleted file mode 100644 index 88c5ed146..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ChilliPotato.java +++ /dev/null @@ -1,49 +0,0 @@ -package content.global.skill.cooking.recipe.potato.impl; - -import content.global.skill.cooking.recipe.potato.PotatoRecipe; -import core.game.node.item.Item; - -/** - * Represents the chilli potato recipe. This recipe consists of adding chilli - * con carne to a baked butter potato. - * @author 'Vexia - * @date 22/12/2013 - */ -public class ChilliPotato extends PotatoRecipe { - - /** - * Represents the chilli potato item. - */ - private static final Item CHILLI_POTATO = new Item(7054); - - /** - * Represents the chilli con carne item/ - */ - private static final Item CHILLI_CON_CARNE = new Item(7062); - - @Override - public Item getProduct() { - return CHILLI_POTATO; - } - - @Override - public Item[] getIngredients() { - return new Item[] { CHILLI_CON_CARNE }; - } - - @Override - public boolean isTopping() { - return true; - } - - @Override - public int getLevel() { - return 41; - } - - @Override - public double getExperience() { - return 10; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/EggPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/EggPotato.java deleted file mode 100644 index c616591fd..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/EggPotato.java +++ /dev/null @@ -1,49 +0,0 @@ -package content.global.skill.cooking.recipe.potato.impl; - -import content.global.skill.cooking.recipe.potato.PotatoRecipe; -import core.game.node.item.Item; - -/** - * Represents the egg potato recipe. This recipe consists of mixing a egg and a - * tomato. - * @author 'Vexia - * @date 22/12/2013 - */ -public class EggPotato extends PotatoRecipe { - - /** - * Represents the egg potato. - */ - private static final Item EGG_POTATO = new Item(7056); - - /** - * Represents the topping item. - */ - private static final Item TOPPING = new Item(7064); - - @Override - public Item getProduct() { - return EGG_POTATO; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TOPPING }; - } - - @Override - public boolean isTopping() { - return true; - } - - @Override - public int getLevel() { - return 51; - } - - @Override - public double getExperience() { - return 10; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/MushroomPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/MushroomPotato.java deleted file mode 100644 index d7bfa1c2c..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/MushroomPotato.java +++ /dev/null @@ -1,49 +0,0 @@ -package content.global.skill.cooking.recipe.potato.impl; - -import content.global.skill.cooking.recipe.potato.PotatoRecipe; -import core.game.node.item.Item; - -/** - * Represents the mushrrom potato. This recipe consists of mixing a baked potato - * with mushroom and onion toppings. - * @author 'Vexia - * @date 22/12/2013 - */ -public class MushroomPotato extends PotatoRecipe { - - /** - * Represents the egg potato. - */ - private static final Item MUSHROOM_POTATO = new Item(7058); - - /** - * Represents the topping item. - */ - private static final Item TOPPING = new Item(7066); - - @Override - public Item getProduct() { - return MUSHROOM_POTATO; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TOPPING }; - } - - @Override - public boolean isTopping() { - return true; - } - - @Override - public int getLevel() { - return 64; - } - - @Override - public double getExperience() { - return 10; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/TunaPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/TunaPotato.java deleted file mode 100644 index 645d5ed2e..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/TunaPotato.java +++ /dev/null @@ -1,49 +0,0 @@ -package content.global.skill.cooking.recipe.potato.impl; - -import content.global.skill.cooking.recipe.potato.PotatoRecipe; -import core.game.node.item.Item; - -/** - * Represents the tuna potato recipe. This recipe consists of mixing tuna and - * corn toppings. - * @author 'Vexia - * @date 22/12/2013 - */ -public class TunaPotato extends PotatoRecipe { - - /** - * Represents the tuna potato. - */ - private static final Item TUNA_POTATO = new Item(7060); - - /** - * Represents the topping item. - */ - private static final Item TOPPING = new Item(7068); - - @Override - public Item getProduct() { - return TUNA_POTATO; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TOPPING }; - } - - @Override - public boolean isTopping() { - return true; - } - - @Override - public int getLevel() { - return 68; - } - - @Override - public double getExperience() { - return 10; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/stew/CurryRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/stew/CurryRecipe.java deleted file mode 100644 index 4ea78825d..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/stew/CurryRecipe.java +++ /dev/null @@ -1,89 +0,0 @@ -package content.global.skill.cooking.recipe.stew; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the curry recipe. This recipe consists of mixing 3 curry leaves or - * a spice into a stew. - * @author 'Vexia - * @date 22/12/2013 - */ -public class CurryRecipe extends Recipe { - - /** - * Represents the uncooked curry item. - */ - private static final Item UNCOOKED_CURRY = new Item(2009); - - /** - * Represents the uncooked stew item. - */ - private static final Item UNCOOKED_STEW = new Item(2001); - - /** - * Represents the spice item. - */ - private static final Item SPICE = new Item(2007); - - /** - * Represents the curry leaf. - */ - private static final Item CURRY_LEAF = new Item(5970); - - @Override - public void mix(Player player, NodeUsageEvent event) { - if (event.getBaseItem().getId() == CURRY_LEAF.getId() || event.getUsedItem().getId() == CURRY_LEAF.getId()) { - Item stew = event.getBaseItem().getId() == UNCOOKED_STEW.getId() ? event.getBaseItem() : event.getUsedItem(); - if (stew.getCharge() == 1000) { - stew.setCharge(1); - } - int charge = stew.getCharge(); - if (charge < 3) { - player.getInventory().remove(CURRY_LEAF); - stew.setCharge(charge + 1); - } else { - if (player.getInventory().remove(stew) && player.getInventory().remove(CURRY_LEAF)) { - player.getInventory().add(UNCOOKED_CURRY); - } - } - return; - } - if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { - player.getInventory().add(getProduct()); - } - } - - @Override - public Item getBase() { - return UNCOOKED_STEW; - } - - @Override - public Item getProduct() { - return UNCOOKED_CURRY; - } - - @Override - public Item[] getIngredients() { - return new Item[] { SPICE, CURRY_LEAF }; - } - - @Override - public Item[] getParts() { - return new Item[] { UNCOOKED_STEW }; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You mix the spice with the stew."; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/stew/StewRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/stew/StewRecipe.java deleted file mode 100644 index 4073bcc0e..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/stew/StewRecipe.java +++ /dev/null @@ -1,92 +0,0 @@ -package content.global.skill.cooking.recipe.stew; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the stew recipe. This recipe consists of mixing meat and a raw - * potato in a bowl of water. - * @author 'Vexia - * @date 22/12/2013 - */ -public class StewRecipe extends Recipe { - - /** - * Represents the uncooked stew item. - */ - private static final Item UNCOOKED_STEW = new Item(2001); - - /** - * Represents the bowl of water item. - */ - private static final Item BOWL_OF_WATER = new Item(1921); - - /** - * Represents the meat item. - */ - private static final Item MEAT = new Item(2142); - - /** - * Represents the potato item. - */ - private static final Item POTATO = new Item(1942); - - /** - * Represents the incomplete stew. - */ - private static final Item INCOMPLETE_STEW = new Item(1997); - - /** - * Represents the second incomplete stew. - */ - private static final Item INCOMPLETE_STEW2 = new Item(1999); - - @Override - public void mix(Player player, NodeUsageEvent event) { - Item first = event.getUsedItem(); - Item second = event.getBaseItem(); - if(first != null && second != null) { - if (player.getInventory().remove(first) && player.getInventory().remove(second)) { - if (first.getId() == BOWL_OF_WATER.getId() || second.getId() == BOWL_OF_WATER.getId()) { - player.getInventory().add(first.getId() == POTATO.getId() ? INCOMPLETE_STEW : first.getId() == MEAT.getId() ? INCOMPLETE_STEW2 : second.getId() == POTATO.getId() ? INCOMPLETE_STEW : second.getId() == MEAT.getId() ? INCOMPLETE_STEW2 : null); - } else { - player.getInventory().add(UNCOOKED_STEW); - } - player.getPacketDispatch().sendMessage(getMixMessage(event)); - } - } - } - - @Override - public Item getBase() { - return BOWL_OF_WATER; - } - - @Override - public Item getProduct() { - return UNCOOKED_STEW; - } - - @Override - public Item[] getIngredients() { - return new Item[] { MEAT, POTATO, MEAT, POTATO }; - } - - @Override - public Item[] getParts() { - return new Item[] { BOWL_OF_WATER, BOWL_OF_WATER, INCOMPLETE_STEW, INCOMPLETE_STEW2 }; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You cut up the " + (event.getUsedItem().getName().toLowerCase().contains("incomplete") ? event.getBaseItem().getName().toLowerCase() : event.getUsedItem().getName().toLowerCase().replace("cooked", "").trim()) + " and put it into the stew."; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/ToppingRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/topping/ToppingRecipe.java deleted file mode 100644 index 5c2cacb15..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/ToppingRecipe.java +++ /dev/null @@ -1,58 +0,0 @@ -package content.global.skill.cooking.recipe.topping; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents a generic topping recipe. - * @author 'Vexia - * @date 22/12/2013 - */ -public abstract class ToppingRecipe extends Recipe { - - /** - * Represents the bowl item. - */ - protected static final Item BOWL = new Item(1923); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < getLevel()) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + getLevel() + " in order to do this."); - return; - } - super.mix(player, event); - player.getSkills().addExperience(Skills.COOKING, getExperience(), true); - } - - @Override - public Item getBase() { - return BOWL; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return null; - } - - @Override - public boolean isSingular() { - return true; - } - - /** - * Method used to get the level required. - * @return the level. - */ - public abstract int getLevel(); - - /** - * Method used to get the experience gained. - * @return the experience. - */ - public abstract double getExperience(); - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChilliConCarne.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChilliConCarne.java deleted file mode 100644 index 4085d149b..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChilliConCarne.java +++ /dev/null @@ -1,81 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the chilli con carne recipe. This recipe consists of using spicy - * sauce with cooked meat. - * @author 'Vexia - * @date 22/12/2013 - */ -public class ChilliConCarne extends Recipe { - - /** - * Represents the bowl item. - */ - private static final Item SPICY_SAUCE = new Item(7072); - - /** - * Represents the chilli con carne item. - */ - private static final Item CHILLI_CON_CARNE = new Item(7062); - - /** - * Represents the cooked meat item. - */ - private static final Item COOKED_MEAT = new Item(2142); - - /** - * Represents the knife item. - */ - private static final Item KNIFE = new Item(946); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 9) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 9 + " in order to do this."); - return; - } - if (!player.getInventory().containsItem(KNIFE)) { - player.getDialogueInterpreter().sendDialogue("You need a knife in order to cut up the meat."); - return; - } - super.mix(player, event); - player.getSkills().addExperience(Skills.COOKING, 25, true); - } - - @Override - public Item getBase() { - return SPICY_SAUCE; - } - - @Override - public Item getProduct() { - return CHILLI_CON_CARNE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { COOKED_MEAT }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return "You put the cut up meat into the bowl."; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedOnion.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedOnion.java deleted file mode 100644 index 5a30107c1..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedOnion.java +++ /dev/null @@ -1,69 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import content.global.skill.cooking.recipe.topping.ToppingRecipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the chopped onion recipe. This recipe consists of using an onion - * on a bowl with a knife. - * @author 'Vexia - * @date 22/12/2013 - */ -public class ChoppedOnion extends ToppingRecipe { - - /** - * Represents the chopped onion product item. - */ - private static final Item CHOPPED_ONION = new Item(1871); - - /** - * Represents the knife used to cut the onion. - */ - private static final Item KNIFE = new Item(946); - - /** - * Represents the onion item. - */ - private static final Item ONION = new Item(1957); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (!player.getInventory().containsItem(KNIFE)) { - player.getDialogueInterpreter().sendDialogue("You need a knife in order to slice up the onion."); - return; - } - super.mix(player, event); - } - - @Override - public int getLevel() { - return 1; - } - - @Override - public double getExperience() { - return 0; - } - - @Override - public Item getProduct() { - return CHOPPED_ONION; - } - - @Override - public Item[] getIngredients() { - return new Item[] { ONION }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public boolean isSingular() { - return true; - } -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedTuna.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedTuna.java deleted file mode 100644 index 4723c61ff..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedTuna.java +++ /dev/null @@ -1,69 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import content.global.skill.cooking.recipe.topping.ToppingRecipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the chopped tuna recipe. This recipe consists of adding tuna to a - * bowl with a knife. - * @author 'Vexia - * @date 22/12/2013 - */ -public class ChoppedTuna extends ToppingRecipe { - - /** - * Represents the chopped tuna item. - */ - private static final Item CHOPPED_TUNA = new Item(7086); - - /** - * Represents the tuna item. - */ - private static final Item TUNA = new Item(361); - - /** - * Represents the knife item. - */ - private static final Item KNIFE = new Item(946); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (!player.getInventory().containsItem(KNIFE)) { - player.getDialogueInterpreter().sendDialogue("You need a knife in order to slice up the tuna."); - return; - } - super.mix(player, event); - } - - @Override - public int getLevel() { - return 1; - } - - @Override - public double getExperience() { - return 1; - } - - @Override - public Item getProduct() { - return CHOPPED_TUNA; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TUNA }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public boolean isSingular() { - return true; - } -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/EggAndTomato.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/EggAndTomato.java deleted file mode 100644 index dabf2db2b..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/EggAndTomato.java +++ /dev/null @@ -1,72 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import content.global.skill.cooking.recipe.Recipe; -import core.game.node.entity.skill.Skills; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the egg and tomato recipe. This recipe consists of mixing a tomato - * with a scrambled egg. - * @author 'Vexia - * @date 22/12/2013 - */ -public class EggAndTomato extends Recipe { - - /** - * Represents the egg and tomato. - */ - private static final Item EGG_AND_TOMATO = new Item(7064); - - /** - * Represents the scrambled egg item. - */ - private static final Item SCRAMBLED_EGG = new Item(7078); - - /** - * epresents the tomato item. - */ - private static final Item TOMATO = new Item(1982); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 23) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 23 + " in order to do this."); - return; - } - super.mix(player, event); - player.getSkills().addExperience(Skills.COOKING, 50, true); - } - - @Override - public Item getBase() { - return SCRAMBLED_EGG; - } - - @Override - public Item getProduct() { - return EGG_AND_TOMATO; - } - - @Override - public Item[] getIngredients() { - return new Item[] { TOMATO }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return null; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/MushroomAndOnion.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/MushroomAndOnion.java deleted file mode 100644 index 3b99200f7..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/MushroomAndOnion.java +++ /dev/null @@ -1,72 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the mushroom and onion recipe. This recipe consists of using a - * fried mushroom with a friend onion. - * @author 'Vexia - * @date 22/12/2013 - */ -public class MushroomAndOnion extends Recipe { - - /** - * Represents the mushroom and onion item. - */ - private static final Item MUSHROOM_AND_ONION = new Item(7066); - - /** - * Represents the fried onions item. - */ - private static final Item FRIED_ONIONS = new Item(7084); - - /** - * Represents the fried mushrooms item. - */ - private static final Item FRIED_MUSHROOMS = new Item(7082); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 57) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 57 + " in order to do this."); - return; - } - super.mix(player, event); - player.getSkills().addExperience(Skills.COOKING, 120, true); - } - - @Override - public Item getBase() { - return FRIED_MUSHROOMS; - } - - @Override - public Item getProduct() { - return MUSHROOM_AND_ONION; - } - - @Override - public Item[] getIngredients() { - return new Item[] { FRIED_ONIONS }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return null; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SlicedMushroom.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SlicedMushroom.java deleted file mode 100644 index 46f9d09f8..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SlicedMushroom.java +++ /dev/null @@ -1,69 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import content.global.skill.cooking.recipe.topping.ToppingRecipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the fried mushroom recipe. This recipe consists of using a - * mushroom on a bowl. - * @author 'Vexia - * @date 22/12/2013 - */ -public final class SlicedMushroom extends ToppingRecipe { - - /** - * Represents the sliced mushrooms item. - */ - private static final Item SLICED_MUSHROOMS = new Item(7080); - - /** - * Represents the mushroom item. - */ - private static final Item MUSHROOM = new Item(6004); - - /** - * Represents the knife item. - */ - private static final Item KNIFE = new Item(946); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (!player.getInventory().containsItem(KNIFE)) { - player.getDialogueInterpreter().sendDialogue("You need a knife in order to slice up the mushrooms."); - return; - } - super.mix(player, event); - } - - @Override - public int getLevel() { - return 1; - } - - @Override - public double getExperience() { - return 0; - } - - @Override - public Item getProduct() { - return SLICED_MUSHROOMS; - } - - @Override - public Item[] getIngredients() { - return new Item[] { MUSHROOM }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public boolean isSingular() { - return true; - } -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SpicySauce.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SpicySauce.java deleted file mode 100644 index 2b0a7e103..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SpicySauce.java +++ /dev/null @@ -1,84 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the spicy sauce recipe. This recipe consists of mixing gnome spice - * and garlic together. - * @author 'Vexia - * @date 22/12/2013 - */ -public class SpicySauce extends Recipe { - - /** - * Represents the spicy sauce item. - */ - private static final Item SPICY_SAUCE = new Item(7072); - - /** - * Represents the bowl item. - */ - private static final Item BOWL = new Item(1923); - - /** - * Represents the garlic item. - */ - private static final Item GARLIC = new Item(1550); - - /** - * Represents the chopped garlic item. - */ - private static final Item CHOPPED_GARLIC = new Item(7074); - - /** - * Represents the gnome spice item. - */ - private static final Item GNOME_SPICE = new Item(2169); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 9) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 9 + " in order to do this."); - return; - } - super.mix(player, event); - if (event.getBaseItem().getId() == GNOME_SPICE.getId() || event.getUsedItem().getId() == GNOME_SPICE.getId()) { - player.getSkills().addExperience(Skills.COOKING, 25, true); - } - } - - @Override - public Item getBase() { - return BOWL; - } - - @Override - public Item getProduct() { - return SPICY_SAUCE; - } - - @Override - public Item[] getIngredients() { - return new Item[] { GARLIC, GNOME_SPICE }; - } - - @Override - public Item[] getParts() { - return new Item[] { BOWL, CHOPPED_GARLIC, SPICY_SAUCE }; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return null; - } - - @Override - public boolean isSingular() { - return false; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/TunaAndCorn.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/TunaAndCorn.java deleted file mode 100644 index 1e2c92a6f..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/TunaAndCorn.java +++ /dev/null @@ -1,72 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import core.game.node.entity.skill.Skills; -import content.global.skill.cooking.recipe.Recipe; -import core.game.interaction.NodeUsageEvent; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the tuna and corn recipe. This recipe consists of adding cooked - * sweetcorn to a bowl of chopped tuna. - * @author 'Vexia - * @date 22/12/2013 - */ -public final class TunaAndCorn extends Recipe { - - /** - * Represents the chopped tuna item. - */ - private static final Item CHOPPED_TUNA = new Item(7086); - - /** - * Represents the cooked corn item. - */ - private static final Item COOKED_CORN = new Item(5988); - - /** - * Represents the tuna and corn item. - */ - private static final Item TUNA_AND_CORN = new Item(7068); - - @Override - public void mix(final Player player, final NodeUsageEvent event) { - if (player.getSkills().getLevel(Skills.COOKING) < 67) { - player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 57 + " in order to do this."); - return; - } - super.mix(player, event); - player.getSkills().addExperience(Skills.COOKING, 204, true); - } - - @Override - public Item getBase() { - return CHOPPED_TUNA; - } - - @Override - public Item getProduct() { - return TUNA_AND_CORN; - } - - @Override - public Item[] getIngredients() { - return new Item[] { COOKED_CORN }; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - - @Override - public String getMixMessage(NodeUsageEvent event) { - return null; - } - - @Override - public boolean isSingular() { - return true; - } - -} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/UncookedEgg.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/UncookedEgg.java deleted file mode 100644 index 61ce50394..000000000 --- a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/UncookedEgg.java +++ /dev/null @@ -1,54 +0,0 @@ -package content.global.skill.cooking.recipe.topping.impl; - -import content.global.skill.cooking.recipe.topping.ToppingRecipe; -import core.game.node.item.Item; - -/** - * Represents the uncooked egg recipe. This recipe consists of adding an - * uncooked egg into a bowl. - * @author 'Vexia - * @date 22/12/2013 - */ -public final class UncookedEgg extends ToppingRecipe { - - /** - * Represents the egg item. - */ - private static final Item EGG = new Item(1944); - - /** - * Represents the uncooked egg product. - */ - private static final Item UNCOOKED_EGG = new Item(7076); - - @Override - public int getLevel() { - return 1; - } - - @Override - public double getExperience() { - return 1; - } - - @Override - public Item getProduct() { - return UNCOOKED_EGG; - } - - @Override - public Item[] getIngredients() { - return new Item[] { EGG }; - } - - @Override - public boolean isSingular() { - return true; - } - - @Override - public Item[] getParts() { - return new Item[] {}; - } - -} diff --git a/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt b/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt index 54a82b557..5c65d0850 100644 --- a/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt +++ b/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt @@ -17,6 +17,10 @@ class BattlestaffListener : InteractionListener { onUseWith(IntType.ITEM, orbs, battlestaff) { player, used, with -> val product = BattlestaffProduct.productMap[used.id] ?: return@onUseWith true + fun getMaxAmount(_unused: Int = 0): Int { + return min(amountInInventory(player, with.id), amountInInventory(player, used.id)) + } + if (!hasLevelDyn(player, Skills.CRAFTING, product.minimumLevel)) { sendMessage(player, "You need a Crafting level of ${product.minimumLevel} to make this.") return@onUseWith true @@ -41,7 +45,7 @@ class BattlestaffListener : InteractionListener { withItems(product.producedItemId) create { _, amount -> - runTask(player, 2, amount) { + runTask(player, 2, min(amount, getMaxAmount())) { if (amount < 1) return@runTask if (removeItem(player, product.requiredOrbItemId) && removeItem(player, Items.BATTLESTAFF_1391)) { @@ -55,9 +59,7 @@ class BattlestaffListener : InteractionListener { } } - calculateMaxAmount { _ -> - min(amountInInventory(player, with.id), amountInInventory(player, used.id)) - } + calculateMaxAmount(::getMaxAmount) } return@onUseWith true diff --git a/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java b/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java index 72d19ef46..30c382180 100644 --- a/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java +++ b/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java @@ -5,6 +5,7 @@ import content.global.skill.crafting.jewellery.JewelleryCrafting; import core.game.interaction.NodeUsageEvent; import core.game.interaction.UseWithHandler; import core.plugin.Plugin; +import org.rs09.consts.Scenery; /** * Represents the plugin used to craft jewellery. @@ -17,7 +18,12 @@ public final class JewelleryCraftPlugin extends UseWithHandler { /** * Represents the ids to use for this plugin. */ - private static final int[] IDS = new int[] { 4304, 6189, 11010, 11666, 12100, 12809, 18497, 26814, 30021, 30510, 36956, 37651 }; + private static final int[] IDS = new int[]{ + Scenery.FURNACE_4304, Scenery.FURNACE_6189, Scenery.FURNACE_11010, Scenery.FURNACE_11666, + Scenery.FURNACE_12100, Scenery.FURNACE_12809, Scenery.FURNACE_18497, Scenery.CLAY_FORGE_21303, + Scenery.FURNACE_26814, Scenery.FURNACE_30021, Scenery.FURNACE_30510, Scenery.FURNACE_36956, + Scenery.FURNACE_37651 + }; /** * Constructs a new {@code JewelleryCraftPlugin} {@code Object}. diff --git a/Server/src/main/content/global/skill/crafting/PotteryPlugin.java b/Server/src/main/content/global/skill/crafting/PotteryPlugin.java index f7fa44e3a..23ddac860 100644 --- a/Server/src/main/content/global/skill/crafting/PotteryPlugin.java +++ b/Server/src/main/content/global/skill/crafting/PotteryPlugin.java @@ -56,7 +56,7 @@ public final class PotteryPlugin extends UseWithHandler { @Override public boolean handle(final NodeUsageEvent event) { final Player player = event.getPlayer(); - new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(false)) { + new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getPottery(false)) { @Override public void create(final int amount, int index) { @@ -145,7 +145,7 @@ public final class PotteryPlugin extends UseWithHandler { * @return the dialogue handler. */ public SkillDialogueHandler getSkillHandler(final Player player) { - return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(true)) { + return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getPottery(true)) { @Override public void create(final int amount, final int index) { diff --git a/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java b/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java index f4929248e..09c2ed605 100644 --- a/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java +++ b/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java @@ -34,7 +34,7 @@ public class SnakeSkinPlugin extends UseWithHandler { @Override public boolean handle(final NodeUsageEvent event) { final Player player = event.getPlayer(); - new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getSkins()) { + new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getSkins()) { @Override public void create(final int amount, int index) { diff --git a/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java b/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java index 1b1335c1c..f23d50b5f 100644 --- a/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java +++ b/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java @@ -20,7 +20,7 @@ public class SnelmCraftPlugin extends UseWithHandler { * The snelm data. */ private static final int[][] DATA = new int[][] { { 3345, 3327 }, { 3355, 3337 },// blamish - { 3349, 3341 }, { 3341, 3359 },// ochre + { 3349, 3331 }, { 3359, 3341 },// ochre { 3347, 3329 }, { 3357, 3339 },// blood { 3351, 3333 }, { 3361, 3343 },// blue { 3353, 3335 },// bark diff --git a/Server/src/main/content/global/skill/crafting/TanningProduct.java b/Server/src/main/content/global/skill/crafting/TanningProduct.java index e71f370b6..30192b4e7 100644 --- a/Server/src/main/content/global/skill/crafting/TanningProduct.java +++ b/Server/src/main/content/global/skill/crafting/TanningProduct.java @@ -15,7 +15,7 @@ public enum TanningProduct { SOFT_LEATHER(1, 1739, 1741), HARD_LEATHER(2, 1739, 1743), SNAKESKIN(3, 6287, 6289), - SNAKESKIN2(4, 6287, 6289), + SNAKESKIN2(4, 7801, 6289), GREEN_DHIDE(5, 1753, 1745), BLUEDHIDE(6, 1751, 2505), REDDHIDE(7, 1749, 2507), @@ -120,9 +120,9 @@ public enum TanningProduct { } else if (def == HARD_LEATHER) { coins = 3; } else if (def == SNAKESKIN) { - coins = 20; - } else if (def == SNAKESKIN2) { coins = 15; + } else if (def == SNAKESKIN2) { + coins = 20; } else { coins = 20; } diff --git a/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java b/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java index bc8022884..924d1364a 100644 --- a/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java +++ b/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java @@ -95,9 +95,6 @@ public final class DragonCraftPulse extends SkillPulse { player.getInventory().add(item); player.getSkills().addExperience(Skills.CRAFTING, hide.getExperience(), true); LeatherCrafting.decayThread(player); - if (LeatherCrafting.isLastThread(player)) { - LeatherCrafting.removeThread(player); - } amount--; } return amount < 1; diff --git a/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java b/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java index 4d02be91c..5a2207b4a 100644 --- a/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java +++ b/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java @@ -75,9 +75,6 @@ public final class HardCraftPulse extends SkillPulse { player.getInventory().add(item); player.getSkills().addExperience(Skills.CRAFTING, 35, true); LeatherCrafting.decayThread(player); - if (LeatherCrafting.isLastThread(player)) { - LeatherCrafting.removeThread(player); - } } amount--; return amount < 1; diff --git a/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java b/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java index 2767fbc65..02f14d1ee 100644 --- a/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java +++ b/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java @@ -1,8 +1,12 @@ package content.global.skill.crafting.armour; +import core.api.Container; import core.game.component.Component; import core.game.node.entity.player.Player; import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; /** * Represents a useful class for leather crafting related information. @@ -40,52 +44,17 @@ public final class LeatherCrafting { */ private static final Component COMPONENT = new Component(154); - /** - * Checks if its the last thrad. - * @return {@code True} if so. - */ - public static boolean isLastThread(final Player player) { - final Item thread = getThread(player); - if (thread == null) { - return false; - } - int charge = thread.getCharge(); - return charge >= 1004; - } - /** * Method used to decay thread. - */ - public static void decayThread(final Player player) { - final Item thread = getThread(player); - if (thread == null) { - return; - } - int charge = thread.getCharge(); - thread.setCharge(charge + 1); - } - - /** - * Method used to remove thread. - * @param player the player. - */ - public static void removeThread(final Player player) { - if (player.getInventory().remove(THREAD)) { - player.getPacketDispatch().sendMessage("You use a reel of your thread."); - Item thread = getThread(player); - if (thread != null) { - thread.setCharge(1000); - } - } - } - - /** - * Gets the thread. - * @param player the player. - * @return the item. + * @author Player Name */ - public static Item getThread(final Player player) { - return player.getInventory().get(player.getInventory().getSlot(THREAD)); + public static void decayThread(final Player player) { + int charges = getAttribute(player, "threadCharges", 5) - 1; + if (charges <= 0 && removeItem(player, Items.THREAD_1734, Container.INVENTORY)) { + charges = 5; + sendMessage(player, "You use a reel of your thread."); + } + setAttribute(player, "/save:threadCharges", charges); } /** diff --git a/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java b/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java index a851caaf6..be012d01c 100644 --- a/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java +++ b/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java @@ -82,9 +82,6 @@ public final class SnakeSkinPulse extends SkillPulse { player.getInventory().add(item); player.getSkills().addExperience(Skills.CRAFTING, skin.getExperience(), true); LeatherCrafting.decayThread(player); - if (LeatherCrafting.isLastThread(player)) { - LeatherCrafting.removeThread(player); - } } amount--; return amount < 1; diff --git a/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java b/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java index 2d62c165a..ab49815cf 100644 --- a/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java +++ b/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java @@ -90,10 +90,6 @@ public final class SoftCraftPulse extends SkillPulse { player.getInventory().add(item); player.getSkills().addExperience(Skills.CRAFTING, soft.getExperience(), true); LeatherCrafting.decayThread(player); - if (LeatherCrafting.isLastThread(player)) { - LeatherCrafting.removeThread(player); - } - if (soft == LeatherCrafting.SoftLeather.GLOVES) { player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 3); } diff --git a/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt index 357b69ca8..0df72d1f2 100644 --- a/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt +++ b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt @@ -1,12 +1,15 @@ package content.global.skill.crafting.lightsources +import content.data.LightSource import core.api.log +import core.api.* import core.cache.def.impl.ItemDefinition import core.game.container.Container import core.game.interaction.OptionHandler import core.game.node.Node import core.game.node.entity.player.Player import core.game.node.item.Item +import core.game.world.map.Location import core.tools.SystemLogger import core.plugin.Initializable import core.plugin.Plugin @@ -32,6 +35,12 @@ class LightSourceExtinguisher : OptionHandler(){ lightSource ?: return false.also { log(this::class.java, Log.WARN, "UNHANDLED EXTINGUISH OPTION: ID = ${node.id}") } + // For Temple of Ikov - if you are in the dark basement, do not let light source extinguish. + if(player.location.isInRegion(10648)) { + sendMessage(player, "Extinguishing the " + LightSource.getActiveLightSource(player).product.name.lowercase() + " would leave you without a light source.") + return true + } + player.inventory.replace(node.asItem(), Item(lightSource.fullID)) return true } diff --git a/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt index e25677810..b558ec38f 100644 --- a/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt +++ b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt @@ -1,12 +1,16 @@ package content.global.skill.crafting.lightsources +import core.api.* +import core.api.teleport import core.game.container.Container import core.game.event.LitLightSourceEvent import core.game.interaction.NodeUsageEvent import core.game.interaction.UseWithHandler +import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item +import core.game.world.map.Location import core.plugin.Initializable import core.plugin.Plugin @@ -66,6 +70,20 @@ class LightSourceLighter : UseWithHandler(590,36,38){ lightSource ?: return false + // For Sea Slug Quest - No lighting of any torch on the fishing platform. + if(event.player.location.isInRegion(11059)) { + event.player.sendMessage("Your tinderbox is damp from the sea crossing. It won't work here.") + return true + } + + // For Temple of Ikov - if you are in the dark basement and light a light source, switch to the light basement. + // For the listener that covers the firemaking cape perk, see content.global.skill.skillcapeperks.SkillcapePerks.kt + if(event.player.location.isInRegion(10648) && event.player.location.withinDistance(Location(2639,9738,0), 8)) { + teleport(event.player, Location.create(event.player.getLocation().x, event.player.getLocation().y + 23, event.player.getLocation().z)) + closeDialogue(event.player) + // Dark basement is region 10648, min 2639 9738 0, max 2643 9744 0. Add 23 to the Y loc to tele to light basement + } + if(!light(event.player,used,lightSource)){ event.player.sendMessage("You need a Firemaking level of at least ${lightSource.levelRequired} to light this.") } diff --git a/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java b/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java index e7af471ef..e4cf4ec71 100644 --- a/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java +++ b/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java @@ -56,7 +56,7 @@ public final class FirePotteryPulse extends SkillPulse { return false; } if (!player.getInventory().containsItem(pottery.getUnfinished())) { - player.getPacketDispatch().sendMessage("You need a " + pottery.name().toLowerCase() + "in order to do this."); + player.getPacketDispatch().sendMessage("You need a " + pottery.name().toLowerCase() + " in order to do this."); return false; } return true; diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt index 346b61b3e..6ab0e7a45 100644 --- a/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt +++ b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt @@ -31,7 +31,7 @@ class SilverCraftingListener : InterfaceListener, InteractionListener { Scenery.FURNACE_12100, Scenery.FURNACE_12809, Scenery.FURNACE_18497, Scenery.FURNACE_18525, Scenery.FURNACE_18526, Scenery.FURNACE_21879, Scenery.FURNACE_22721, Scenery.FURNACE_26814, Scenery.FURNACE_28433, Scenery.FURNACE_28434, Scenery.FURNACE_30021, Scenery.FURNACE_30510, - Scenery.FURNACE_36956, Scenery.FURNACE_37651 + Scenery.FURNACE_36956, Scenery.FURNACE_37651, Scenery.CLAY_FORGE_21303 ) private const val ATTRIBUTE_FURNACE_ID = "crafting:silver:furnace_id" diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt index 8bc77007c..338b41b47 100644 --- a/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt +++ b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt @@ -31,10 +31,8 @@ class SilverCraftingPulse( animate(player, Animations.HUMAN_FURNACE_SMELTING_3243) playAudio(player, Sounds.FURNACE_2725) - if (removeItem(player, Items.SILVER_BAR_2355, Container.INVENTORY)) { - addItem(player, product.producedItemId, product.amountProduced) + if (removeItem(player, Items.SILVER_BAR_2355, Container.INVENTORY) && addItem(player, product.producedItemId, product.amountProduced)) { rewardXP(player, Skills.CRAFTING, product.xpReward) - player.dispatch( ResourceProducedEvent( product.producedItemId, diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt b/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt index 83becbf16..98bcc014e 100644 --- a/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt +++ b/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt @@ -27,7 +27,7 @@ enum class SilverProduct( val strungId: Int ) { HOLY(BUTTON_UNBLESSED, Items.HOLY_MOULD_1599, Items.UNSTRUNG_SYMBOL_1714, 1, 16, 50.0, Items.UNBLESSED_SYMBOL_1716), - UNHOLY(BUTTON_UNHOLY, Items.UNHOLY_MOULD_1594, Items.UNSTRUNG_EMBLEM_1720, 1, 17, 50.0, Items.UNHOLY_SYMBOL_1724), + UNHOLY(BUTTON_UNHOLY, Items.UNHOLY_MOULD_1594, Items.UNSTRUNG_EMBLEM_1720, 1, 17, 50.0, Items.UNPOWERED_SYMBOL_1722), SICKLE(BUTTON_SICKLE, Items.SICKLE_MOULD_2976, Items.SILVER_SICKLE_2961, 1, 18, 50.0, -1), TIARA(BUTTON_TIARA, Items.TIARA_MOULD_5523, Items.TIARA_5525, 1, 23, 52.5, -1), SILVTHRIL_CHAIN(BUTTON_SILVTHRIL_CHAIN, Items.CHAIN_LINK_MOULD_13153, Items.SILVTHRIL_CHAIN_13154, 1, 47, 100.0, -1), diff --git a/Server/src/main/content/global/skill/farming/CompostBin.kt b/Server/src/main/content/global/skill/farming/CompostBin.kt index 617e800db..c7e7f5cc2 100644 --- a/Server/src/main/content/global/skill/farming/CompostBin.kt +++ b/Server/src/main/content/global/skill/farming/CompostBin.kt @@ -19,6 +19,19 @@ class CompostBin(val player: Player, val bin: CompostBins) { var finishedTime = 0L var isFinished = false + /** + * Resets the compost bin to its initial state. + */ + fun reset() { + items.clear() + isSuperCompost = true + isTomatoes = true + isClosed = false + finishedTime = 0L + isFinished = false + updateBit() + } + fun isFull() : Boolean { return items.size == 15 } diff --git a/Server/src/main/content/global/skill/farming/CropHarvester.kt b/Server/src/main/content/global/skill/farming/CropHarvester.kt index 779609bf8..e47820bb3 100644 --- a/Server/src/main/content/global/skill/farming/CropHarvester.kt +++ b/Server/src/main/content/global/skill/farming/CropHarvester.kt @@ -15,7 +15,7 @@ import core.plugin.Plugin import org.rs09.consts.Items import org.rs09.consts.Sounds -val livesBased = arrayOf(PatchType.HERB_PATCH, PatchType.CACTUS_PATCH, PatchType.BELLADONNA_PATCH, PatchType.HOPS_PATCH, PatchType.ALLOTMENT, PatchType.EVIL_TURNIP_PATCH) +val livesBased = arrayOf(PatchType.HERB_PATCH, PatchType.CACTUS_PATCH, PatchType.HOPS_PATCH, PatchType.ALLOTMENT) @Initializable class CropHarvester : OptionHandler() { @@ -43,14 +43,16 @@ class CropHarvester : OptionHandler() { override fun pulse(): Boolean { var reward = Item(crop) - val familiar = player.familiarManager.familiar - if (familiar != null && familiar is GiantEntNPC) { - familiar.modifyFarmingReward(fPatch, reward) - } if (!hasSpaceFor(player, reward)) { sendMessage(player, "You have run out of inventory space.") return true } + + val familiar = player.familiarManager.familiar + if (familiar != null && familiar is GiantEntNPC) { + familiar.modifyFarmingReward(fPatch, reward) + } + var requiredItem = when (fPatch.type) { PatchType.TREE_PATCH -> Items.SECATEURS_5329 else -> Items.SPADE_952 @@ -61,7 +63,13 @@ class CropHarvester : OptionHandler() { } } val anim = when (requiredItem) { - Items.SPADE_952 -> if (fPatch.type == PatchType.HERB_PATCH) Animation(2282) else Animation(830) + Items.SPADE_952 -> { + when (fPatch.type) { + PatchType.HERB_PATCH -> Animation(2282) + PatchType.FLOWER_PATCH -> Animation(2292) + else -> Animation(830) + } + } Items.SECATEURS_5329 -> if (fPatch.type == PatchType.TREE_PATCH) Animation(2277) else Animation(7227) Items.MAGIC_SECATEURS_7409 -> if (fPatch.type == PatchType.TREE_PATCH) Animation(3340) else Animation(7228) else -> Animation(0) @@ -76,27 +84,33 @@ class CropHarvester : OptionHandler() { sendMessage(player, "You lack the needed tool to harvest these crops.") return true } - if (firstHarvest) { + val sendHarvestMessages = if (fPatch.type == PatchType.FLOWER_PATCH) false else true + if (sendHarvestMessages && firstHarvest) { sendMessage(player, "You begin to harvest the $patchName.") firstHarvest = false } animate(player, anim) playAudio(player, sound) + // TODO: If a flower patch is being harvested, delay the clearing of the + // patch until after the animation has played - https://youtu.be/lg4GktlVNUY?t=75 delay = 2 - addItem(player, reward.id) + addItemOrDrop(player, reward.id,reward.amount) rewardXP(player, Skills.FARMING, plantable.harvestXP) if (patch.patch.type in livesBased) { patch.rollLivesDecrement( getDynLevel(player, Skills.FARMING), - requiredItem == Items.MAGIC_SECATEURS_7409 + inInventory(player, Items.MAGIC_SECATEURS_7409) //add ||inEquipment() check when Fairy Tale pt 1 has been implemented ) } else { patch.harvestAmt-- if (patch.harvestAmt <= 0 && crop == plantable.harvestItem) { patch.clear() } + else if (fPatch.type == PatchType.MUSHROOM_PATCH){ + patch.setCurrentState(patch.getCurrentState() + 1) + } } - if (patch.cropLives <= 0 || patch.harvestAmt <= 0) { + if (sendHarvestMessages && (patch.cropLives <= 0 || patch.harvestAmt <= 0)) { sendMessage(player, "The $patchName is now empty.") } return patch.cropLives <= 0 || patch.harvestAmt <= 0 diff --git a/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt b/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt index 21a773c20..ab170aa74 100644 --- a/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt +++ b/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt @@ -24,7 +24,15 @@ class DigUpPatchDialogue(player: Player? = null) : DialoguePlugin(player) { } if (patch?.patch?.type == PatchType.TREE_PATCH) { val isTreeStump = patch?.getCurrentState() == patch?.plantable!!.value + patch?.plantable!!.stages + 2 - if (!isTreeStump) { + if (patch!!.isGrown() && !isTreeStump) { + sendMessage(player, "You need to chop this tree down first.") // this message is not authentic + stage = 1000 + return true + } + } + if (patch?.patch?.type == PatchType.FRUIT_TREE_PATCH) { + val isTreeStump = patch?.getCurrentState() == patch?.plantable!!.value + 25 + if (patch!!.isGrown() && !isTreeStump) { sendMessage(player, "You need to chop this tree down first.") // this message is not authentic stage = 1000 return true diff --git a/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt b/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt index eeb8903f5..e048914a1 100644 --- a/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt +++ b/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt @@ -1,68 +1,152 @@ package content.global.skill.farming -import core.game.node.item.Item -import org.rs09.consts.Items +import content.data.Quests +import core.api.* import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.item.Item import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import org.rs09.consts.Items -class FarmerPayOptionDialogue(val patch: Patch): DialogueFile() { +class FarmerPayOptionDialogue(val patch: Patch, val quickPay: Boolean = false): DialogueFile() { var item: Item? = null - override fun handle(componentID: Int, buttonID: Int) { - when(stage){ - START_DIALOGUE -> { - item = patch.plantable?.protectionItem - val protectionText = when(item?.id){ - Items.COMPOST_6032 -> if(item?.amount == 1) "bucket of compost" else "buckets of compost" - Items.POTATOES10_5438 -> if(item?.amount == 1) "sack of potatoes" else "sacks of potatoes" - Items.ONIONS10_5458 -> if(item?.amount == 1) "sack of onions" else "sacks of onions" - Items.CABBAGES10_5478 -> if(item?.amount == 1) "sack of cabbages" else "sacks of cabbages" - Items.JUTE_FIBRE_5931 -> "jute fibres" - Items.APPLES5_5386 -> if(item?.amount == 1) "basket of apples" else "baskets of apples" - Items.MARIGOLDS_6010 -> "harvest of marigold" - Items.TOMATOES5_5968 -> if(item?.amount == 1) "basket of tomatoes" else "baskets of tomatoes" - Items.ORANGES5_5396 -> if(item?.amount == 1) "basket of oranges" else "baskets of oranges" - Items.COCONUT_5974 -> "coconuts" - Items.CACTUS_SPINE_6016 -> "cactus spines" - Items.STRAWBERRIES5_5406 -> if(item?.amount == 1) "basket of strawberries" else "baskets of strawberries" - Items.BANANAS5_5416 -> if(item?.amount == 1) "basket of bananas" else "baskets of bananas" - else -> item?.name?.toLowerCase() - } - if(item == null) npc("Sorry, I won't protect that.").also { stage = END_DIALOGUE } - else{ - npc("I would like ${item?.amount} $protectionText","to protect that patch.") - stage++ - } - } + var itemSecondary: Item? = null + var itemTertiary: Item? = null - 1 -> options("Sure!","No, thanks.").also { stage++ } - 2 -> { - if(player!!.inventory.containsItem(item)){ - player("Here you go.").also { stage = 10 } + fun hasAllItems(): Boolean { + return (inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount)) + && (inInventory(player!!, itemSecondary!!.id, itemSecondary!!.amount) || inInventory(player!!, note(itemSecondary!!).id, note(itemSecondary!!).amount)) + && (inInventory(player!!, itemTertiary!!.id, itemTertiary!!.amount) || inInventory(player!!, note(itemTertiary!!).id, note(itemTertiary!!).amount)) + } + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> { + if (patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()) { + // This is for the right-click "Pay" option; full dialogue is in GardenerDialoguePlugin + showTopics( + Topic("Yes, get rid of the tree.", 300, true), + Topic("No thanks.", END_DIALOGUE, true), + title = "Pay 200 gp to have the tree chopped down?" + ) + } else if (patch.protectionPaid) { + npc("I don't know what you're talking about - I'm already", "looking after that patch for you.").also { stage = 100 } + } else if (patch.isDead) { + npc("That patch is dead - it's too late for me to do", "anything about it now.").also { stage = END_DIALOGUE } + } else if (patch.isDiseased) { + npc("That patch is diseased - I can't look after it", "until it has been cured.").also { stage = END_DIALOGUE } // this dialogue is not authentic + } else if (patch.isWeedy() || patch.isEmptyAndWeeded()) { + npc(FacialExpression.NEUTRAL, "You don't have anything planted in that patch. Plant", "something and I might agree to look after it for you.").also { stage = END_DIALOGUE } + } else if (patch.isGrown()) { + npc("That patch is already fully grown!", "I don't know what you want me to do with it!").also { stage = END_DIALOGUE } } else { - item = Item(item!!.noteChange,item!!.amount) - if(player!!.inventory.containsItem(item)){ - player("Here you go.").also { stage = 10 } + item = patch.plantable?.protectionItem + itemSecondary = patch.plantable?.protectionItemSecondary + itemTertiary = patch.plantable?.protectionItemTertiary + + val protectionText = when (item?.id) { + Items.COMPOST_6032 -> if (item?.amount == 1) "bucket of compost" else "buckets of compost" + Items.POTATOES10_5438 -> if (item?.amount == 1) "sack of potatoes" else "sacks of potatoes" + Items.ONIONS10_5458 -> if (item?.amount == 1) "sack of onions" else "sacks of onions" + Items.CABBAGES10_5478 -> if (item?.amount == 1) "sack of cabbages" else "sacks of cabbages" + Items.JUTE_FIBRE_5931 -> "jute fibres" + Items.APPLES5_5386 -> if (item?.amount == 1) "basket of apples" else "baskets of apples" + Items.MARIGOLDS_6010 -> "harvest of marigold" + Items.TOMATOES5_5968 -> if (item?.amount == 1) "basket of tomatoes" else "baskets of tomatoes" + Items.ORANGES5_5396 -> if (item?.amount == 1) "basket of oranges" else "baskets of oranges" + Items.COCONUT_5974 -> "coconuts" + Items.CACTUS_SPINE_6016 -> "cactus spines" + Items.STRAWBERRIES5_5406 -> if (item?.amount == 1) "basket of strawberries" else "baskets of strawberries" + Items.BANANAS5_5416 -> if (item?.amount == 1) "basket of bananas" else "baskets of bananas" + else -> item?.name?.lowercase() + } + if (item == null) { + npc("Sorry, I won't protect that.").also { stage = END_DIALOGUE } + } else if (patch.patch.type == PatchType.SPIRIT_TREE_PATCH && quickPay + && !hasAllItems()) { + val amount = if (item?.amount == 1) "one" else item?.amount + npc(FacialExpression.HAPPY, "I want $amount $protectionText, one monkey bar,", "and one ground tooth for that.") + stage = 200 + } else if (patch.patch.type == PatchType.CALQUAT_TREE_PATCH && getQuestStage(player!!, Quests.JUNGLE_POTION) < 100) { + npc("Sorry, I won't protect that.").also { stage = END_DIALOGUE } // Cannot confirm authenticity of this line just that there should be a rejection here + } else if (quickPay && !(inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount))) { + val amount = if (item?.amount == 1) "one" else item?.amount + npc(FacialExpression.HAPPY, "I want $amount $protectionText for that.") + stage = 200 + } else if (patch.patch.type == PatchType.SPIRIT_TREE_PATCH && quickPay) { + showTopics( + //Found a 2011 source for quick-pay, but no earlier dialogue sources (https://www.youtube.com/watch?v=RdIcNH50v7I) + Topic("Yes", 20, true), + Topic("No", END_DIALOGUE, true), + title = "Pay the gnome?" + ) + } else if (quickPay) { + val amount = if (item?.amount == 1) "one" else item?.amount + showTopics( + Topic("Yes", 20, true), + Topic("No", END_DIALOGUE, true), + title = "Pay $amount $protectionText?" + ) + } else if (patch.patch.type == PatchType.SPIRIT_TREE_PATCH) { + val amount = if (item?.amount == 1) "one" else item?.amount + npc("If you like, but I want $amount $protectionText,", "one monkey bar, and one ground tooth for that.") + stage++ } else { - player("I don't have that to give.").also { stage = 20 } + val amount = if (item?.amount == 1) "one" else item?.amount + npc("If you like, but I want $amount $protectionText for that.") + stage++ } } } - 10 -> { - if(player!!.inventory.remove(item)){ - npc("Thank you! I'll keep an eye on this patch.").also { stage = END_DIALOGUE } - patch?.protectionPaid = true + 1 -> { + if (patch.patch.type == PatchType.SPIRIT_TREE_PATCH && !hasAllItems()) { + player("I'm afraid I don't have any of those at the moment.").also { stage = 10 } + } else if (!(inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount))) { + player("I'm afraid I don't have any of those at the moment.").also { stage = 10 } } else { - npc("That stuff just... vanished....").also { stage = END_DIALOGUE } + showTopics( + Topic(FacialExpression.NEUTRAL, "Okay, it's a deal.", 20), + Topic(FacialExpression.NEUTRAL, "No, that's too much.", 10) + ) } } + 10 -> npc("Well, I'm not wasting my time for free.").also { stage = END_DIALOGUE } + 20 -> { - npc("Come back when you do.") - stage = END_DIALOGUE + if (patch.patch.type == PatchType.SPIRIT_TREE_PATCH + && (removeItem(player!!, item) || removeItem(player!!, note(item!!))) + && (removeItem(player!!, itemSecondary) || removeItem(player!!, note(itemSecondary!!))) + && (removeItem(player!!, itemTertiary) || removeItem(player!!, note(itemTertiary!!)))) { + patch.protectionPaid = true + npc("That'll do nicely, ${if (player!!.isMale) "sir" else "madam"}. Leave it with me - I'll make sure", "that tree grows up good and strong.").also { stage = END_DIALOGUE } + } else if (patch.patch.type != PatchType.SPIRIT_TREE_PATCH + && removeItem(player!!, item) || removeItem(player!!, note(item!!))) { + patch.protectionPaid = true + // Note: A slight change in this dialogue was seen in a December 2009 video - https://youtu.be/7gVh42ylQ48?t=138 + npc("That'll do nicely, ${if (player!!.isMale) "sir" else "madam"}. Leave it with me - I'll make sure", "those crops grow for you.").also { stage = END_DIALOGUE } + } else { + npc("This shouldn't be happening. Please report this.").also { stage = END_DIALOGUE } + } + } + + 100 -> player("Oh sorry, I forgot.").also { stage = END_DIALOGUE } + + // Right-click "Pay" - protect patch - player doesn't have payment + 200 -> player(FacialExpression.NEUTRAL, "Thanks, maybe another time.").also { stage = END_DIALOGUE } + + // Right-click "Pay" - chop down tree + 300 -> { + if (removeItem(player!!, Item(Items.COINS_995, 200))) { + patch.clear() + dialogue("The gardener obligingly removes your tree.").also { stage = END_DIALOGUE } + } else { + dialogue("You need 200 gp to pay for that.").also { stage = END_DIALOGUE } // not authentic + } } } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt b/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt index 724ce6c73..52d7874ad 100644 --- a/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt +++ b/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt @@ -1,5 +1,6 @@ package content.global.skill.farming +import core.api.openDialogue import core.game.node.Node import core.game.node.entity.player.Player import core.game.interaction.InteractionListener @@ -8,35 +9,20 @@ import core.game.interaction.IntType class FarmerPayOptionHandler : InteractionListener { override fun defineListeners() { - on(IntType.NPC,"pay","pay (north)","pay (north-west)"){ player, node -> + on(IntType.NPC,"pay","pay (north)","pay (north-west)") { player, node -> return@on attemptPay(player,node,0) } - on(IntType.NPC,"pay (south)","pay (south-east)"){ player, node -> + on(IntType.NPC,"pay (south)","pay (south-east)") { player, node -> return@on attemptPay(player,node,1) } } - fun attemptPay(player: Player, node: Node, index: Int): Boolean{ + fun attemptPay(player: Player, node: Node, index: Int): Boolean { val farmer = Farmers.forId(node.id) ?: return false val patch = farmer.patches[index].getPatchFor(player) - if(patch.plantable == null){ - player.dialogueInterpreter.sendDialogue("I have nothing to protect in that patch.") - return true - } - - if(patch.protectionPaid){ - player.dialogueInterpreter.sendDialogue("I have already paid to protect that patch.") - return true - } - - if(patch.isGrown()){ - player.dialogueInterpreter.sendDialogue("This patch is already fully grown!") - return true - } - - player.dialogueInterpreter.open(FarmerPayOptionDialogue(patch),node.asNpc()) + openDialogue(player, FarmerPayOptionDialogue(patch, true), node.asNpc()) return true } } \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/Farmers.kt b/Server/src/main/content/global/skill/farming/Farmers.kt index 4a57feeef..360e583c5 100644 --- a/Server/src/main/content/global/skill/farming/Farmers.kt +++ b/Server/src/main/content/global/skill/farming/Farmers.kt @@ -21,7 +21,12 @@ enum class Farmers(val id: Int, val patches: Array) { FRANCIS(2327, arrayOf(FarmingPatch.ENTRANA_HOPS)), DREVEN(2335, arrayOf(FarmingPatch.CHAMPIONS_GUILD_BUSH)), TARIA(2336, arrayOf(FarmingPatch.RIMMINGTON_BUSH)), - TORRELL(2338, arrayOf(FarmingPatch.ARDOUGNE_BUSH)); + TORRELL(2338, arrayOf(FarmingPatch.ARDOUGNE_BUSH)), + FRIZZY(4560, arrayOf(FarmingPatch.PORT_SARIM_SPIRIT_TREE)), + YULF(4561, arrayOf(FarmingPatch.ETCETERIA_SPIRIT_TREE)), + PRAISTAN(4562, arrayOf(FarmingPatch.KARAMJA_SPIRIT_TREE)), + IMIAGO(8041, arrayOf(FarmingPatch.CALQUAT_TREE)) + ; companion object{ @JvmField diff --git a/Server/src/main/content/global/skill/farming/FarmingPatch.kt b/Server/src/main/content/global/skill/farming/FarmingPatch.kt index c322e4de8..d19e8871e 100644 --- a/Server/src/main/content/global/skill/farming/FarmingPatch.kt +++ b/Server/src/main/content/global/skill/farming/FarmingPatch.kt @@ -67,7 +67,8 @@ enum class FarmingPatch(val varbit: Int, val type: PatchType) { DRAYNOR_BELLADONNA(748, PatchType.BELLADONNA_PATCH), CANIFIS_MUSHROOM(746, PatchType.MUSHROOM_PATCH), ALKHARID_CACTUS(744, PatchType.CACTUS_PATCH), - EVIL_TURNIP(4291, PatchType.EVIL_TURNIP_PATCH); + EVIL_TURNIP(4291, PatchType.EVIL_TURNIP_PATCH), + CALQUAT_TREE(726, PatchType.CALQUAT_TREE_PATCH); companion object { @@ -94,6 +95,10 @@ enum class FarmingPatch(val varbit: Int, val type: PatchType) { patchNodes.addAll(8382..8383)//spirit trees patchNodes.add(8338) //spirit tree patchNodes.add(18816) //death plateau wrapper + patchNodes.add(21950) //harmony island allotment + patchNodes.add(28919) //lletya fruit patch. Was usable in 2009: https://www.youtube.com/watch?v=7sXOW4CRZ3k + //patchNodes.add(37988) Wilderness flower patch. Can only plant Limpwurt Seeds. Intentionally left out, as it is a reward from Spirit of Summer. + for (patch in patchNodes) { val def = SceneryDefinition.forId(patch) @@ -117,8 +122,8 @@ enum class FarmingPatch(val varbit: Int, val type: PatchType) { } } - fun getPatchFor(player: Player): Patch{ - var crops = getOrStartTimer (player)!! - return crops.getPatch(this) + fun getPatchFor(player: Player, addPatch : Boolean = true): Patch{ + val crops = getOrStartTimer (player) + return crops.getPatch(this, addPatch) } } diff --git a/Server/src/main/content/global/skill/farming/FarmingState.kt b/Server/src/main/content/global/skill/farming/FarmingState.kt deleted file mode 100644 index ed7f769e5..000000000 --- a/Server/src/main/content/global/skill/farming/FarmingState.kt +++ /dev/null @@ -1,43 +0,0 @@ -package content.global.skill.farming - -import core.api.* -import core.Util.clamp -import core.game.node.entity.player.Player -import core.game.system.task.Pulse -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import org.json.simple.JSONArray -import org.json.simple.JSONObject -import core.game.node.entity.state.PlayerState -import core.game.node.entity.state.State -import core.tools.SystemLogger -import java.util.concurrent.TimeUnit -import content.global.skill.farming.timers.* - -@PlayerState("farming") -/** - * Kept around solely for the purpose of porting save data from this old system to the new one. - * //TODO REMOVE BY END OF 2023 -**/ -class FarmingState(player: Player? = null) : State(player) { - override fun save(root: JSONObject) {} - override fun parse(_data: JSONObject) { - player ?: return - if(_data.containsKey("farming-bins")){ - _data["bins"] = _data["farming-bins"] - val timer = getOrStartTimer (player) - timer.parse (_data, player) - } - if(_data.containsKey("farming-patches")){ - _data["patches"] = _data["farming-patches"] - val timer = getOrStartTimer (player) - timer.parse(_data, player) - } - } - - override fun newInstance(player: Player?): State { - return FarmingState(player) - } - - override fun createPulse() {} -} diff --git a/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt b/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt index f07689362..380334445 100644 --- a/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt +++ b/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt @@ -5,7 +5,9 @@ import core.cache.def.impl.SceneryDefinition import core.game.interaction.OptionHandler import core.game.node.Node import content.global.skill.summoning.familiar.GiantEntNPC +import content.global.skill.summoning.familiar.WolpertingerNPC import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.game.system.task.Pulse @@ -75,8 +77,15 @@ class FruitAndBerryPicker : OptionHandler() { animate(player, animation) playAudio(player, Sounds.FARMING_PICK_2437) - addItemOrDrop(player, reward.id, reward.amount) - rewardXP(player, Skills.FARMING, plantable.harvestXP) + + if (familiar != null && familiar is WolpertingerNPC && patch.patch.type == PatchType.BUSH_PATCH) { + addItemOrDrop(player, reward.id, reward.amount * 2) + rewardXP(player, Skills.FARMING, plantable.harvestXP * 2) + } + else { + addItemOrDrop(player, reward.id, reward.amount) + rewardXP(player, Skills.FARMING, plantable.harvestXP) + } patch.setCurrentState(patch.getCurrentState() - 1) if (patch.patch.type == PatchType.CACTUS_PATCH) { @@ -86,6 +95,10 @@ class FruitAndBerryPicker : OptionHandler() { sendMessage(player, "You pick $determiner ${reward.name.lowercase()}.") } + if (plantable == Plantable.POISON_IVY_SEED && patch.patch == FarmingPatch.CHAMPIONS_GUILD_BUSH){ + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 0) + } + return patch.getFruitOrBerryCount() == 0 } }) diff --git a/Server/src/main/content/global/skill/farming/FruitTreeChopper.kt b/Server/src/main/content/global/skill/farming/FruitTreeChopper.kt new file mode 100644 index 000000000..288bf1e01 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/FruitTreeChopper.kt @@ -0,0 +1,62 @@ +package content.global.skill.farming + +import content.data.skill.SkillingTool +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.RandomFunction +import org.rs09.consts.Sounds + +@Initializable +class FruitTreeChopper : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.setOptionHandler("chop-down",this) + SceneryDefinition.setOptionHandler("chop down",this) + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + + val fPatch = FarmingPatch.forObject(node.asScenery()) + fPatch ?: return false + + val patch = fPatch.getPatchFor(player) + + val plantable = patch.plantable + plantable ?: return false + + if (SkillingTool.getHatchet(player) == null) { + sendMessage(player, "You do not have an axe to use.") + return true + } + + val animation = SkillingTool.getHatchet(player).animation + + submitIndividualPulse(player, object : Pulse(animation.duration) { + override fun pulse(): Boolean { + animate(player, animation) + val soundIndex = RandomFunction.random(0, woodcuttingSounds.size) + playAudio(player, woodcuttingSounds[soundIndex]) + patch.setCurrentState(patch.getCurrentState() + 19) + sendMessage(player, "You chop down the ${plantable.displayName.lowercase().removeSuffix(" sapling")}.") + return true + } + }) + return true + } + + private val woodcuttingSounds = intArrayOf( + Sounds.WOODCUTTING_HIT_3038, + Sounds.WOODCUTTING_HIT_3039, + Sounds.WOODCUTTING_HIT_3040, + Sounds.WOODCUTTING_HIT_3041, + Sounds.WOODCUTTING_HIT_3042 + ) +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/HealthChecker.kt b/Server/src/main/content/global/skill/farming/HealthChecker.kt index 43d0e24d9..1813a5145 100644 --- a/Server/src/main/content/global/skill/farming/HealthChecker.kt +++ b/Server/src/main/content/global/skill/farming/HealthChecker.kt @@ -5,6 +5,7 @@ import core.cache.def.impl.SceneryDefinition import core.game.interaction.OptionHandler import core.game.node.Node import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills import core.plugin.Initializable import core.plugin.Plugin @@ -26,7 +27,7 @@ class HealthChecker : OptionHandler() { val patch = fPatch.getPatchFor(player) val type = patch.patch.type - if (type != PatchType.BUSH_PATCH && type != PatchType.FRUIT_TREE_PATCH && type != PatchType.TREE_PATCH && type != PatchType.CACTUS_PATCH) { + if (!patch.isCheckable()) { sendMessage(player, "This shouldn't be happening. Please report this.") return true } @@ -36,13 +37,33 @@ class HealthChecker : OptionHandler() { rewardXP(player, Skills.FARMING, patch.plantable?.checkHealthXP ?: 0.0) patch.isCheckHealth = false when (type) { - PatchType.TREE_PATCH -> patch.setCurrentState(patch.getCurrentState() + 1) - PatchType.FRUIT_TREE_PATCH -> patch.setCurrentState(patch.getCurrentState() - 14) - PatchType.BUSH_PATCH -> { - sendMessage(player, "You examine the bush for signs of disease and find that it's in perfect health.") - patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 4) + PatchType.TREE_PATCH -> { + patch.setCurrentState(patch.getCurrentState() + 1) + sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.") + } + PatchType.FRUIT_TREE_PATCH -> { + patch.setCurrentState(patch.getCurrentState() - 14) + if (fPatch == FarmingPatch.BRIMHAVEN_FRUIT_TREE) { + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 12) + } + sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.") + } + PatchType.SPIRIT_TREE_PATCH -> { + patch.setCurrentState(patch.getCurrentState() - 24) + sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.") + } + PatchType.BUSH_PATCH -> { + patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 4) + sendMessage(player, "You examine the bush for signs of disease and find that it's in perfect health.") + } + PatchType.CACTUS_PATCH -> { + patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 3) + sendMessage(player, "You examine the cactus for signs of disease and find that it is in perfect health.") + } + PatchType.CALQUAT_TREE_PATCH -> { + patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 6) + sendMessage(player, "You examine the calquat tree for signs of disease and find that it is in perfect health.") } - PatchType.CACTUS_PATCH -> patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 3) else -> log(this::class.java, Log.ERR, "Unreachable patch type from when(type) switch in HealthChecker.kt") } diff --git a/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt b/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt index 3a3d47bbf..8cf6eff81 100644 --- a/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt +++ b/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt @@ -12,26 +12,29 @@ class LeprechaunNoter : InteractionListener { val LEPRECHAUNS = intArrayOf(NPCs.TOOL_LEPRECHAUN_3021,NPCs.GOTH_LEPRECHAUN_8000,NPCs.TOOL_LEPRECHAUN_4965,NPCs.TECLYN_2861) override fun defineListeners() { - onUseWith(IntType.NPC,CROPS,*LEPRECHAUNS){ player, used, with -> + onUseAnyWith(IntType.NPC,*LEPRECHAUNS) { player, used, with -> val usedItem = used.asItem() val npc = with.asNpc() val expr = when(npc.id){ - 3021 -> core.game.dialogue.FacialExpression.OLD_NORMAL + NPCs.TOOL_LEPRECHAUN_3021 -> core.game.dialogue.FacialExpression.OLD_NORMAL else -> core.game.dialogue.FacialExpression.FRIENDLY } - - if(usedItem.noteChange != usedItem.id){ - val amt = player.inventory.getAmount(usedItem.id) - if(player.inventory.remove(Item(usedItem.id,amt))){ - player.inventory.add(Item(usedItem.noteChange,amt)) + when { + (!usedItem.definition.isUnnoted) -> { // If the item is a banknote + player.dialogueInterpreter.sendDialogues(npc.id,expr,"That IS a banknote!") + } + (usedItem.id !in CROPS || usedItem.definition.noteId < 0) -> { // If the item is not a crop or cannot be noted + player.dialogueInterpreter.sendDialogues(npc.id,expr,"Nay, I can't turn that into a banknote.") + } + else -> { // Note the item + val amt = amountInInventory(player, usedItem.id) + if (removeItem(player, Item(usedItem.id, amt))) { + addItem(player, usedItem.noteChange, amt) + } + sendItemDialogue(player, usedItem.id, "The leprechaun exchanges your items for banknotes.") } - sendItemDialogue(player,usedItem.id,"The leprechaun exchanges your items for banknotes.") - } else { - // Unsure why the line below no longer functions, despite only changing the line above to be more correct. Using your note(NOT CROP) on the leprechaun no longer functions because of this. - Crash - player.dialogueInterpreter.sendDialogues(npc.id,expr,"That IS a banknote!") } - - return@onUseWith true + return@onUseAnyWith true } } } \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/Patch.kt b/Server/src/main/content/global/skill/farming/Patch.kt index 486f1d5bf..b2235419e 100644 --- a/Server/src/main/content/global/skill/farming/Patch.kt +++ b/Server/src/main/content/global/skill/farming/Patch.kt @@ -16,6 +16,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl var compost = CompostType.NONE var protectionPaid = false var cropLives = 3 + val checkablePatches = arrayOf(PatchType.TREE_PATCH, PatchType.BUSH_PATCH, PatchType.FRUIT_TREE_PATCH, PatchType.SPIRIT_TREE_PATCH, PatchType.CACTUS_PATCH, PatchType.CALQUAT_TREE_PATCH) fun setNewHarvestAmount() { val compostMod = when(compost) { @@ -29,7 +30,11 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl Plantable.WILLOW_SAPLING -> 0 else -> 1 } - if(plantable != null && plantable?.applicablePatch != PatchType.FLOWER_PATCH) { + if(plantable != null + && plantable?.applicablePatch != PatchType.FLOWER_PATCH + && plantable?.applicablePatch != PatchType.BELLADONNA_PATCH + && plantable?.applicablePatch != PatchType.MUSHROOM_PATCH + && plantable?.applicablePatch != PatchType.EVIL_TURNIP_PATCH) { harvestAmt += compostMod } cropLives = 3 + compostMod @@ -70,8 +75,6 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl var chance = when(patch.type){ PatchType.ALLOTMENT -> 8 //average of 8 per life times 3 lives = average 24 PatchType.HOPS_PATCH -> 6 //average of 6 per life times 3 lives = 18 - PatchType.BELLADONNA_PATCH -> 2 //average of 2 per life times 3 lives = 6 - PatchType.EVIL_TURNIP_PATCH -> 2 //average 2 per, same as BELLADONNA PatchType.CACTUS_PATCH -> 3 //average of 3 per life times 3 lives = 9 else -> 0 // nothing should go here, but if it does, do not give extra crops amd decrement cropLives } @@ -88,6 +91,11 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl return getCurrentState() in 0..2 } + fun isChoppedFruitTree(): Boolean { + return (patch.type == PatchType.FRUIT_TREE_PATCH) + && getCurrentState() == (plantable?.value ?: 0) + 25 + } + fun isEmptyAndWeeded(): Boolean { return getCurrentState() == 3 } @@ -123,6 +131,9 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl log(this::class.java, Log.DEBUG, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to diseased at stage $currentGrowthStage, which isn't valid.") return (state and (0x80.inv())) } + else if (state in listOf(0, 1, 2, 3)){ + // we're weedy (or an empty plot) as normal just continue + } else { log (this::class.java, Log.ERR, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to state $state at growth stage $currentGrowthStage, which isn't valid. We're not sure why this is happening.") } @@ -134,6 +145,13 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl return compost != CompostType.NONE } + /** + * Returns true if the patch is fully grown. + * + * Note: This returns true if the patch is fully weedy. + * Use `plantable == null` to check if a patch does + * not have anything planted. + */ fun isGrown(): Boolean{ return currentGrowthStage == (plantable?.stages ?: 0) } @@ -144,7 +162,10 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl PatchType.FRUIT_TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages + 20) PatchType.BUSH_PATCH -> setVarbit(player, patch.varbit, 250 + (plantable!!.ordinal - Plantable.REDBERRY_SEED.ordinal)) PatchType.CACTUS_PATCH -> setVarbit(player, patch.varbit, 31) - else -> log(this::class.java, Log.WARN, "Invalid setting of isCheckHealth for patch type: " + patch.type.name) + PatchType.TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages) + PatchType.SPIRIT_TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages + 24) + PatchType.CALQUAT_TREE_PATCH -> setVarbit(player, patch.varbit, 34) + else -> log(this::class.java, Log.WARN, "Invalid setting of isCheckHealth for patch type: " + patch.type.name + "at" + patch.name) } } else { when(patch.type){ @@ -169,6 +190,10 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl if (state != getVarbit(player, patch.varbit)) setVisualState(state) } + PatchType.SPIRIT_TREE_PATCH -> { + if(isDead) setVisualState(getSpiritTreeDeathValue()) + else if(isDiseased && !isDead) setVisualState(getSpiritTreeDiseaseValue()) + } PatchType.FRUIT_TREE_PATCH -> { if(isDead) setVisualState(getFruitTreeDeathValue()) else if(isDiseased && !isDead) setVisualState(getFruitTreeDiseaseValue()) @@ -185,9 +210,27 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl PatchType.HERB_PATCH -> { if(isDead) setVisualState(getHerbDeathValue()) else if(isDiseased && !isDead) setVisualState(getHerbDiseaseValue()) - else setVisualState((plantable?.value ?: 0) + currentGrowthStage) + else { + var state = (plantable?.value ?: 0) + currentGrowthStage + // Spirit Weed contains states with bits 0x40 and 0x80 set, which the disease-free patch scenery interprets as watered/dead + // Visually transmogrifies Spirit Weed (204-208) into Guam (4-8) while it's planted in the disease-free patch + if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB && plantable == Plantable.SPIRIT_WEED_SEED) { + state = 4 + currentGrowthStage + } + setVisualState(state) + } + } + PatchType.MUSHROOM_PATCH -> { + if(isDead) setVisualState(getMushroomDeathValue()) + else if(isDiseased && !isDead) setVisualState(getMushroomDiseaseValue()) + } + PatchType.CALQUAT_TREE_PATCH -> { + if(isDead) setVisualState(getCalquatDeathValue()) + else if(isDiseased && !isDead) setVisualState(getCalquatDiseaseValue()) + } + else -> { + log(this::class.java, Log.WARN, "Invalid patch type attempted to be displayed: " + patch.type.name) } - else -> {} } } } @@ -210,17 +253,36 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl private fun getBushDiseaseValue(): Int{ if(plantable == Plantable.POISON_IVY_SEED){ return (plantable?.value ?: 0) + currentGrowthStage + 12 - } else { + } + else if (plantable == Plantable.REDBERRY_SEED + || plantable == Plantable.CADAVABERRY_SEED){ + return (plantable?.value ?: 0) + currentGrowthStage + 65 + } + else { return (plantable?.value ?: 0) + currentGrowthStage + 64 } } private fun getBushDeathValue(): Int{ if(plantable == Plantable.POISON_IVY_SEED){ - return (plantable?.value ?: 0) + currentGrowthStage + 22 - } else { - return (plantable?.value ?: 0) + currentGrowthStage + 126 + return (plantable?.value ?: 0) + currentGrowthStage + 20 } + else if (plantable == Plantable.REDBERRY_SEED + || plantable == Plantable.CADAVABERRY_SEED + || plantable == Plantable.WHITEBERRY_SEED){ + return (plantable?.value ?: 0) + currentGrowthStage + 129 + } + else { + return (plantable?.value ?: 0) + currentGrowthStage + 128 + } + } + + private fun getSpiritTreeDiseaseValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 12 + } + + private fun getSpiritTreeDeathValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 24 } private fun getFruitTreeDiseaseValue(): Int { @@ -247,6 +309,22 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl return (plantable?.value ?: 0) + currentGrowthStage + 16 } + private fun getMushroomDiseaseValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 11 + } + + private fun getMushroomDeathValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 16 + } + + private fun getCalquatDiseaseValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 14 + } + + private fun getCalquatDeathValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 21 + } + private fun getHerbDiseaseValue(): Int { return if (plantable?.value ?: -1 <= 103) { 128 + (((plantable?.ordinal ?: 0) - Plantable.GUAM_SEED.ordinal) * 3) + currentGrowthStage - 1 @@ -264,7 +342,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl } private fun grow(){ - if((isWeedy() || isEmptyAndWeeded()) && getCurrentState() > 0) { + if((isWeedy() || isEmptyAndWeeded() || (plantable == Plantable.SCARECROW && !isGrown())) && getCurrentState() > 0) { nextGrowth = System.currentTimeMillis() + 60000 setCurrentState(getCurrentState() - 1) currentGrowthStage-- @@ -276,26 +354,37 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl return } - diseaseMod = when(compost){ + // This is so a cheat can force disease + diseaseMod = if (diseaseMod < 0) -128 else when(compost){ CompostType.NONE -> 0 CompostType.COMPOST -> 8 CompostType.SUPERCOMPOST -> 13 } - if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB && RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid && !isFlowerProtected() && patch.type != PatchType.EVIL_TURNIP_PATCH ){ - //bush, tree, fruit tree, herb and cactus can not disease on stage 1(0) of growth. - if(!((patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.CACTUS_PATCH || patch.type == PatchType.HERB_PATCH) && currentGrowthStage == 0)) { - isDiseased = true - return - } + if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB + && RandomFunction.random(128) <= (17 - diseaseMod) + && !isWatered && !isGrown() + && !protectionPaid + && !isFlowerProtected() + && patch.type != PatchType.EVIL_TURNIP_PATCH + && plantable != Plantable.POISON_IVY_SEED + && currentGrowthStage != 0){ + isDiseased = true + // If we manually set disease mod reset it back to 0 so that crops can naturally grow after being treated/accidentally attempted to disease when they cannot be + if (diseaseMod < 0) diseaseMod = 0 + return } - if((patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.TREE_PATCH || patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.CACTUS_PATCH) && plantable != null && plantable?.stages == currentGrowthStage + 1){ + if(isCheckable() && plantable != null && plantable?.stages == currentGrowthStage + 1){ isCheckHealth = true } - if((patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.CACTUS_PATCH) && plantable?.stages == currentGrowthStage){ - if((patch.type == PatchType.BUSH_PATCH && getFruitOrBerryCount() < 4) || (patch.type == PatchType.FRUIT_TREE_PATCH && getFruitOrBerryCount() < 6) || (patch.type == PatchType.CACTUS_PATCH && getFruitOrBerryCount() < 3)){ + if(arrayOf(PatchType.FRUIT_TREE_PATCH, PatchType.BUSH_PATCH, PatchType.CACTUS_PATCH, PatchType.CALQUAT_TREE_PATCH).any{ patch.type == it} && plantable?.stages == currentGrowthStage){ + if((patch.type == PatchType.BUSH_PATCH && getFruitOrBerryCount() < 4) || + (patch.type == PatchType.FRUIT_TREE_PATCH && getFruitOrBerryCount() < 6) || + (patch.type == PatchType.CACTUS_PATCH && getFruitOrBerryCount() < 3) || + (patch.type == PatchType.CALQUAT_TREE_PATCH && getFruitOrBerryCount() < 6) + ){ setCurrentState(getCurrentState() + 1) } } @@ -306,13 +395,11 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl } } - if(plantable?.stages ?: 0 > currentGrowthStage && !isGrown()){ + if((plantable?.stages ?: 0) > currentGrowthStage && !isGrown()){ currentGrowthStage++ setCurrentState(getCurrentState() + 1) isWatered = false } - - regrowIfTreeStump() } fun regrowIfTreeStump() { @@ -359,11 +446,15 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl fun getStageGrowthMinutes() : Int { var minutes = patch.type.stageGrowthTime - if(patch.type == PatchType.FRUIT_TREE_PATCH && isGrown()) { + if(arrayOf(PatchType.FRUIT_TREE_PATCH, PatchType.CALQUAT_TREE_PATCH).any{ it == patch.type } && isGrown()) { // Fruit trees take 160 minutes per stage to grow, but // restocking their fruit should take 40 minutes per fruit minutes = 40 } + else if(plantable == Plantable.WILLOW_SAPLING && isGrown()) { + // Willow Branches grow back in only 5 minutes + minutes = 5 + } return minutes } @@ -376,10 +467,16 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl FarmingPatch.CATHERBY_ALLOTMENT_S,FarmingPatch.CATHERBY_ALLOTMENT_N -> FarmingPatch.CATHERBY_FLOWER_C FarmingPatch.PORT_PHAS_ALLOTMENT_SE,FarmingPatch.PORT_PHAS_ALLOTMENT_NW -> FarmingPatch.PORT_PHAS_FLOWER_C else -> return false - }.getPatchFor(player) + }.getPatchFor(player, false) - return (fpatch.plantable != null && + if (fpatch.plantable == Plantable.SCARECROW && fpatch.plantable == plantable?.protectionFlower){ + return true + } else return (fpatch.plantable != null && (fpatch.plantable == plantable?.protectionFlower || fpatch.plantable == Plantable.forItemID(Items.WHITE_LILY_SEED_14589)) && fpatch.isGrown()) } + + fun isCheckable(): Boolean{ + return (patch.type in checkablePatches) + } } diff --git a/Server/src/main/content/global/skill/farming/PatchRaker.kt b/Server/src/main/content/global/skill/farming/PatchRaker.kt index 27bc3d8fa..21967671b 100644 --- a/Server/src/main/content/global/skill/farming/PatchRaker.kt +++ b/Server/src/main/content/global/skill/farming/PatchRaker.kt @@ -15,7 +15,7 @@ object PatchRaker { val p = patch.getPatchFor(player) val patchName = p.patch.type.displayName() var firstRake = true - if (p.isEmptyAndWeeded()) { + if (!p.isWeedy()) { sendMessage(player, "This $patchName doesn't need weeding right now.") return } @@ -35,7 +35,7 @@ object PatchRaker { } else { patch.getPatchFor(player).currentGrowthStage++ patch.getPatchFor(player).setCurrentState(++patchStage) - addItem(player, Items.WEEDS_6055) + addItem(player, Items.WEEDS_6055) //authentically destroys weeds if inventory was full rewardXP(player, Skills.FARMING, 4.0) } if (patchStage >= 3) { @@ -45,4 +45,4 @@ object PatchRaker { } }) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/farming/PatchType.kt b/Server/src/main/content/global/skill/farming/PatchType.kt index 0cbe40129..fd0836126 100644 --- a/Server/src/main/content/global/skill/farming/PatchType.kt +++ b/Server/src/main/content/global/skill/farming/PatchType.kt @@ -12,7 +12,8 @@ enum class PatchType(val stageGrowthTime: Int) { MUSHROOM_PATCH(30), BELLADONNA_PATCH(80), CACTUS_PATCH(60), - EVIL_TURNIP_PATCH(5); + EVIL_TURNIP_PATCH(5), + CALQUAT_TREE_PATCH(160); /** * Returns the display name of this PatchType. diff --git a/Server/src/main/content/global/skill/farming/Plantable.kt b/Server/src/main/content/global/skill/farming/Plantable.kt index c77d22b6e..6d08d9386 100644 --- a/Server/src/main/content/global/skill/farming/Plantable.kt +++ b/Server/src/main/content/global/skill/farming/Plantable.kt @@ -3,88 +3,90 @@ package content.global.skill.farming import core.game.node.item.Item import org.rs09.consts.Items -enum class Plantable(val itemID: Int, val value: Int, val stages: Int, val plantingXP: Double, val harvestXP: Double, val checkHealthXP: Double, val requiredLevel: Int, val applicablePatch: PatchType, val harvestItem: Int, val protectionItem: Item? = null,val protectionFlower: Plantable? = null) { +enum class Plantable(val itemID: Int, val displayName: String, val value: Int, val stages: Int, val plantingXP: Double, val harvestXP: Double, val checkHealthXP: Double, val requiredLevel: Int, val applicablePatch: PatchType, val harvestItem: Int, val protectionItem: Item? = null, val protectionFlower: Plantable? = null, val protectionItemSecondary: Item? = null, val protectionItemTertiary: Item? = null) { - //Flowers - MARIGOLD_SEED(5096,8,4,8.5,47.0,0.0,2,PatchType.FLOWER_PATCH,Items.MARIGOLDS_6010), - ROSEMARY_SEED(5097,13,4,12.0,66.5,0.0,11,PatchType.FLOWER_PATCH, Items.ROSEMARY_6014), - NASTURTIUM_SEED(5098,18,4,19.5,111.0,0.0,24,PatchType.FLOWER_PATCH,Items.NASTURTIUMS_6012), - WOAD_SEED(5099,23,4,20.5,115.5,0.0,25,PatchType.FLOWER_PATCH,Items.WOAD_LEAF_1793), - LIMPWURT_SEED(5100,28,4,21.5,120.0,0.0,26,PatchType.FLOWER_PATCH,Items.LIMPWURT_ROOT_225), - WHITE_LILY_SEED(14589,37,4,42.0,250.0,0.0,52,PatchType.FLOWER_PATCH,Items.WHITE_LILY_14583), + // Flowers + MARIGOLD_SEED(Items.MARIGOLD_SEED_5096,"marigold seed",8,4,8.5,47.0,0.0,2,PatchType.FLOWER_PATCH,Items.MARIGOLDS_6010), + ROSEMARY_SEED(Items.ROSEMARY_SEED_5097,"rosemary seed",13,4,12.0,66.5,0.0,11,PatchType.FLOWER_PATCH, Items.ROSEMARY_6014), + NASTURTIUM_SEED(Items.NASTURTIUM_SEED_5098,"nasturtium seed",18,4,19.5,111.0,0.0,24,PatchType.FLOWER_PATCH,Items.NASTURTIUMS_6012), + WOAD_SEED(Items.WOAD_SEED_5099,"woad seed",23,4,20.5,115.5,0.0,25,PatchType.FLOWER_PATCH,Items.WOAD_LEAF_1793), + LIMPWURT_SEED(Items.LIMPWURT_SEED_5100,"limpwurt seed",28,4,21.5,120.0,0.0,26,PatchType.FLOWER_PATCH,Items.LIMPWURT_ROOT_225), + WHITE_LILY_SEED(Items.WHITE_LILY_SEED_14589,"white lily seed",37,4,42.0,250.0,0.0,52,PatchType.FLOWER_PATCH,Items.WHITE_LILY_14583), - //Flower(Technically) - SCARECROW(6059,33,3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059), + // Flower (technically) + SCARECROW(Items.SCARECROW_6059,"scarecrow",36,-3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059), - //Allotments - POTATO_SEED(5318, 6, 4, 8.0, 9.0, 0.0, 1, PatchType.ALLOTMENT, Items.POTATO_1942,Item(Items.COMPOST_6032,2),MARIGOLD_SEED), - ONION_SEED(5319, 13, 4, 9.5, 10.5,0.0, 5, PatchType.ALLOTMENT,Items.ONION_1957,Item(Items.POTATOES10_5438),MARIGOLD_SEED), - CABBAGE_SEED(5324, 20, 4, 10.0, 11.5, 0.0,7, PatchType.ALLOTMENT,Items.CABBAGE_1965,Item(Items.ONIONS10_5458),ROSEMARY_SEED), - TOMATO_SEED(5322,27,4,12.5,14.0,0.0,12,PatchType.ALLOTMENT,Items.TOMATO_1982,Item(Items.CABBAGES10_5478,2),MARIGOLD_SEED), - SWEETCORN_SEED(5320,34,6,17.0,19.0,0.0,20,PatchType.ALLOTMENT,Items.SWEETCORN_5986,Item(Items.JUTE_FIBRE_5931,10),SCARECROW), - STRAWBERRY_SEED(5323,43,6,26.0,29.0,0.0,31,PatchType.ALLOTMENT,Items.STRAWBERRY_5504,Item(Items.APPLES5_5386)), - WATERMELON_SEED(5321,52,8,48.5,54.5,0.0,47,PatchType.ALLOTMENT,Items.WATERMELON_5982,Item(Items.CURRY_LEAF_5970,10),NASTURTIUM_SEED), + // Allotments + POTATO_SEED(Items.POTATO_SEED_5318, "potato seed", 6, 4, 8.0, 9.0, 0.0, 1, PatchType.ALLOTMENT, Items.POTATO_1942,Item(Items.COMPOST_6032,2),MARIGOLD_SEED), + ONION_SEED(Items.ONION_SEED_5319, "onion seed", 13, 4, 9.5, 10.5,0.0, 5, PatchType.ALLOTMENT,Items.ONION_1957,Item(Items.POTATOES10_5438),MARIGOLD_SEED), + CABBAGE_SEED(Items.CABBAGE_SEED_5324, "cabbage seed", 20, 4, 10.0, 11.5, 0.0,7, PatchType.ALLOTMENT,Items.CABBAGE_1965,Item(Items.ONIONS10_5458),ROSEMARY_SEED), + TOMATO_SEED(Items.TOMATO_SEED_5322,"tomato seed",27,4,12.5,14.0,0.0,12,PatchType.ALLOTMENT,Items.TOMATO_1982,Item(Items.CABBAGES10_5478,2),MARIGOLD_SEED), + SWEETCORN_SEED(Items.SWEETCORN_SEED_5320,"sweetcorn seed",34,6,17.0,19.0,0.0,20,PatchType.ALLOTMENT,Items.SWEETCORN_5986,Item(Items.JUTE_FIBRE_5931,10),SCARECROW), + STRAWBERRY_SEED(Items.STRAWBERRY_SEED_5323,"strawberry seed",43,6,26.0,29.0,0.0,31,PatchType.ALLOTMENT,Items.STRAWBERRY_5504,Item(Items.APPLES5_5386)), + WATERMELON_SEED(Items.WATERMELON_SEED_5321,"watermelon seed",52,8,48.5,54.5,0.0,47,PatchType.ALLOTMENT,Items.WATERMELON_5982,Item(Items.CURRY_LEAF_5970,10),NASTURTIUM_SEED), - //Hops - BARLEY_SEED(5305,49,4,8.5,9.5,0.0,3,PatchType.HOPS_PATCH,Items.BARLEY_6006,Item(Items.COMPOST_6032,3)), - HAMMERSTONE_SEED(5307,4,4,9.0,10.0,0.0,4,PatchType.HOPS_PATCH,Items.HAMMERSTONE_HOPS_5994,Item(Items.MARIGOLDS_6010)), - ASGARNIAN_SEED(5308,11,5,10.9,12.0,0.0,8,PatchType.HOPS_PATCH,Items.ASGARNIAN_HOPS_5996,Item(Items.ONIONS10_5458)), - JUTE_SEED(5306,56,5,13.0,14.5,0.0,13,PatchType.HOPS_PATCH,Items.JUTE_FIBRE_5931,Item(Items.BARLEY_MALT_6008,6)), - YANILLIAN_SEED(5309,19,6,14.5,16.0,0.0,16,PatchType.HOPS_PATCH,Items.YANILLIAN_HOPS_5998,Item(Items.TOMATOES5_5968)), - KRANDORIAN_SEED(5310,28,7,17.5,19.5,0.0,21,PatchType.HOPS_PATCH,Items.KRANDORIAN_HOPS_6000,Item(Items.CABBAGES10_5478,3)), - WILDBLOOD_SEED(5311,38,8,23.0,26.0,0.0,28,PatchType.HOPS_PATCH,Items.WILDBLOOD_HOPS_6002,Item(Items.NASTURTIUMS_6012)), + // Hops + BARLEY_SEED(Items.BARLEY_SEED_5305,"barley seed",49,4,8.5,9.5,0.0,3,PatchType.HOPS_PATCH,Items.BARLEY_6006,Item(Items.COMPOST_6032,3)), + HAMMERSTONE_SEED(Items.HAMMERSTONE_SEED_5307,"Hammerstone hop seed",4,4,9.0,10.0,0.0,4,PatchType.HOPS_PATCH,Items.HAMMERSTONE_HOPS_5994,Item(Items.MARIGOLDS_6010)), + ASGARNIAN_SEED(Items.ASGARNIAN_SEED_5308,"Asgarnian hop seed",11,5,10.9,12.0,0.0,8,PatchType.HOPS_PATCH,Items.ASGARNIAN_HOPS_5996,Item(Items.ONIONS10_5458)), + JUTE_SEED(Items.JUTE_SEED_5306,"jute plant seed",56,5,13.0,14.5,0.0,13,PatchType.HOPS_PATCH,Items.JUTE_FIBRE_5931,Item(Items.BARLEY_MALT_6008,6)), + YANILLIAN_SEED(Items.YANILLIAN_SEED_5309,"Yanillian hop seed",19,6,14.5,16.0,0.0,16,PatchType.HOPS_PATCH,Items.YANILLIAN_HOPS_5998,Item(Items.TOMATOES5_5968)), + KRANDORIAN_SEED(Items.KRANDORIAN_SEED_5310,"Krandorian hop seed",28,7,17.5,19.5,0.0,21,PatchType.HOPS_PATCH,Items.KRANDORIAN_HOPS_6000,Item(Items.CABBAGES10_5478,3)), + WILDBLOOD_SEED(Items.WILDBLOOD_SEED_5311,"Wildblood hop seed",38,8,23.0,26.0,0.0,28,PatchType.HOPS_PATCH,Items.WILDBLOOD_HOPS_6002,Item(Items.NASTURTIUMS_6012)), - //Trees - OAK_SAPLING(5370,8,4,14.0,0.0,467.3,15,PatchType.TREE_PATCH,Items.OAK_ROOTS_6043,Item(Items.TOMATOES5_5968)), - WILLOW_SAPLING(5371,15,6,25.0,0.0,1456.5,30,PatchType.TREE_PATCH,Items.WILLOW_ROOTS_6045,Item(Items.APPLES5_5386)), - MAPLE_SAPLING(5372,24,8,45.0,0.0,3403.4,45,PatchType.TREE_PATCH,Items.MAPLE_ROOTS_6047,Item(Items.ORANGES5_5396)), - YEW_SAPLING(5373,35,10,81.0,0.0,7069.9,60,PatchType.TREE_PATCH,Items.YEW_ROOTS_6049,Item(Items.CACTUS_SPINE_6016,10)), - MAGIC_SAPLING(5374,48,12,145.5,0.0,13768.3,75,PatchType.TREE_PATCH,Items.MAGIC_ROOTS_6051,Item(Items.COCONUT_5974,25)), + // Trees + OAK_SAPLING(Items.OAK_SAPLING_5370,"oak sapling",8,4,14.0,0.0,467.3,15,PatchType.TREE_PATCH,Items.OAK_ROOTS_6043,Item(Items.TOMATOES5_5968)), + WILLOW_SAPLING(Items.WILLOW_SAPLING_5371,"willow sapling",15,6,25.0,0.0,1456.5,30,PatchType.TREE_PATCH,Items.WILLOW_ROOTS_6045,Item(Items.APPLES5_5386)), + MAPLE_SAPLING(Items.MAPLE_SAPLING_5372,"maple sapling",24,8,45.0,0.0,3403.4,45,PatchType.TREE_PATCH,Items.MAPLE_ROOTS_6047,Item(Items.ORANGES5_5396)), + YEW_SAPLING(Items.YEW_SAPLING_5373,"yew sapling",35,10,81.0,0.0,7069.9,60,PatchType.TREE_PATCH,Items.YEW_ROOTS_6049,Item(Items.CACTUS_SPINE_6016,10)), + MAGIC_SAPLING(Items.MAGIC_SAPLING_5374,"magic Tree sapling",48,12,145.5,0.0,13768.3,75,PatchType.TREE_PATCH,Items.MAGIC_ROOTS_6051,Item(Items.COCONUT_5974,25)), - //Fruit Trees - APPLE_SAPLING(5496,8,6,22.0,8.5,1199.5,27,PatchType.FRUIT_TREE_PATCH,Items.COOKING_APPLE_1955,Item(Items.SWEETCORN_5986,9)), - BANANA_SAPLING(5497,35,6,28.0,10.5,1750.5,33,PatchType.FRUIT_TREE_PATCH,Items.BANANA_1963,Item(Items.APPLES5_5386,4)), - ORANGE_SAPLING(5498,72,6,35.5,13.5,2470.2,39,PatchType.FRUIT_TREE_PATCH,Items.ORANGE_2108,Item(Items.STRAWBERRIES5_5406,3)), - CURRY_SAPLING(5499,99,6,40.0,15.0,2906.9,42,PatchType.FRUIT_TREE_PATCH,Items.CURRY_LEAF_5970,Item(Items.BANANAS5_5416,5)), - PINEAPPLE_SAPLING(5500,136,6,57.0,21.5,4605.7,51,PatchType.FRUIT_TREE_PATCH,Items.PINEAPPLE_2114,Item(Items.WATERMELON_5982,10)), - PAPAYA_SAPLING(5501,163,6,72.0,27.0,6146.4,57,PatchType.FRUIT_TREE_PATCH,Items.PAPAYA_FRUIT_5972,Item(Items.PINEAPPLE_2114,10)), - PALM_SAPLING(5502,200,6,110.5,41.5,10150.1,68,PatchType.FRUIT_TREE_PATCH,Items.COCONUT_5974,Item(Items.PAPAYA_FRUIT_5972,15)), + // Fruit Trees + APPLE_SAPLING(Items.APPLE_SAPLING_5496,"apple tree sapling",8,6,22.0,8.5,1199.5,27,PatchType.FRUIT_TREE_PATCH,Items.COOKING_APPLE_1955,Item(Items.SWEETCORN_5986,9)), + BANANA_SAPLING(Items.BANANA_SAPLING_5497,"banana tree sapling",35,6,28.0,10.5,1750.5,33,PatchType.FRUIT_TREE_PATCH,Items.BANANA_1963,Item(Items.APPLES5_5386,4)), + ORANGE_SAPLING(Items.ORANGE_SAPLING_5498,"orange tree sapling",72,6,35.5,13.5,2470.2,39,PatchType.FRUIT_TREE_PATCH,Items.ORANGE_2108,Item(Items.STRAWBERRIES5_5406,3)), + CURRY_SAPLING(Items.CURRY_SAPLING_5499,"curry tree sapling",99,6,40.0,15.0,2906.9,42,PatchType.FRUIT_TREE_PATCH,Items.CURRY_LEAF_5970,Item(Items.BANANAS5_5416,5)), + PINEAPPLE_SAPLING(Items.PINEAPPLE_SAPLING_5500,"pineapple plant",136,6,57.0,21.5,4605.7,51,PatchType.FRUIT_TREE_PATCH,Items.PINEAPPLE_2114,Item(Items.WATERMELON_5982,10)), + PAPAYA_SAPLING(Items.PAPAYA_SAPLING_5501,"papaya tree sapling",163,6,72.0,27.0,6146.4,57,PatchType.FRUIT_TREE_PATCH,Items.PAPAYA_FRUIT_5972,Item(Items.PINEAPPLE_2114,10)), + PALM_SAPLING(Items.PALM_SAPLING_5502,"palm tree sapling",200,6,110.5,41.5,10150.1,68,PatchType.FRUIT_TREE_PATCH,Items.COCONUT_5974,Item(Items.PAPAYA_FRUIT_5972,15)), - //Bushes - REDBERRY_SEED(5101,5,5,11.5,4.5,64.0,10,PatchType.BUSH_PATCH,Items.REDBERRIES_1951,Item(Items.CABBAGES10_5478,4)), - CADAVABERRY_SEED(5102,15,6,18.0,7.0,102.5,22,PatchType.BUSH_PATCH,Items.CADAVA_BERRIES_753,Item(Items.TOMATOES5_5968,3)), - DWELLBERRY_SEED(5103,26,27,31.5,12.0,177.5,36,PatchType.BUSH_PATCH,Items.DWELLBERRIES_2126,Item(Items.STRAWBERRIES5_5406,3)), - JANGERBERRY_SEED(5104,38,8,50.5,19.0,284.5,48,PatchType.BUSH_PATCH,Items.JANGERBERRIES_247,Item(Items.WATERMELON_5982,6)), - WHITEBERRY_SEED(5105,51,8,78.0,29.0,437.5,59,PatchType.BUSH_PATCH,Items.WHITE_BERRIES_239,null), - POISON_IVY_SEED(5106,197,8,120.0,45.0,675.0,70,PatchType.BUSH_PATCH,Items.POISON_IVY_BERRIES_6018,null), + // Bushes + REDBERRY_SEED(Items.REDBERRY_SEED_5101,"redberry bush seed",5,5,11.5,4.5,64.0,10,PatchType.BUSH_PATCH,Items.REDBERRIES_1951,Item(Items.CABBAGES10_5478,4)), + CADAVABERRY_SEED(Items.CADAVABERRY_SEED_5102,"cadavaberry bush seed",15,6,18.0,7.0,102.5,22,PatchType.BUSH_PATCH,Items.CADAVA_BERRIES_753,Item(Items.TOMATOES5_5968,3)), + DWELLBERRY_SEED(Items.DWELLBERRY_SEED_5103,"dwellberry bush seed",26,7,31.5,12.0,177.5,36,PatchType.BUSH_PATCH,Items.DWELLBERRIES_2126,Item(Items.STRAWBERRIES5_5406,3)), + JANGERBERRY_SEED(Items.JANGERBERRY_SEED_5104,"jangerberry bush seed",38,8,50.5,19.0,284.5,48,PatchType.BUSH_PATCH,Items.JANGERBERRIES_247,Item(Items.WATERMELON_5982,6)), + WHITEBERRY_SEED(Items.WHITEBERRY_SEED_5105,"whiteberry bush seed",51,8,78.0,29.0,437.5,59,PatchType.BUSH_PATCH,Items.WHITE_BERRIES_239,Item(Items.MUSHROOM_6004,8)), + POISON_IVY_SEED(Items.POISON_IVY_SEED_5106,"poison ivy bush seed",197,8,120.0,45.0,675.0,70,PatchType.BUSH_PATCH,Items.POISON_IVY_BERRIES_6018,null), - //Herbs - GUAM_SEED(5291,4,4,11.0,12.5,0.0,9,PatchType.HERB_PATCH,Items.GRIMY_GUAM_199), - MARRENTILL_SEED(5292,11,4,13.5,15.0,0.0,14,PatchType.HERB_PATCH,Items.GRIMY_MARRENTILL_201), - TARROMIN_SEED(5293,18,4,16.0,18.0,0.0,19,PatchType.HERB_PATCH,Items.GRIMY_TARROMIN_203), - HARRALANDER_SEED(5294,25,4,21.5,24.0,0.0,26,PatchType.HERB_PATCH,Items.GRIMY_HARRALANDER_205), - RANARR_SEED(5295,32,4,27.0,30.5,0.0,32,PatchType.HERB_PATCH,Items.GRIMY_RANARR_207), - AVANTOE_SEED(5298,39,4,54.5,61.5,0.0,50,PatchType.HERB_PATCH,Items.GRIMY_AVANTOE_211), - TOADFLAX_SEED(5296,46,4,34.0,38.5,0.0,38,PatchType.HERB_PATCH,Items.GRIMY_TOADFLAX_3049), - IRIT_SEED(5297,53,4,43.0,48.5,0.0,44,PatchType.HERB_PATCH,Items.GRIMY_IRIT_209), - KWUARM_SEED(5299,68,4,69.0,78.0,0.0,56,PatchType.HERB_PATCH,Items.GRIMY_KWUARM_213), - SNAPDRAGON_SEED(5300,75,4,87.5,98.5,0.0,62,PatchType.HERB_PATCH,Items.GRIMY_SNAPDRAGON_3051), - CADANTINE_SEED(5301,82,4,106.5,120.0,0.0,67,PatchType.HERB_PATCH,Items.GRIMY_CADANTINE_215), - LANTADYME_SEED(5302,89,4,134.5,151.5,0.0,73,PatchType.HERB_PATCH,Items.GRIMY_LANTADYME_2485), - DWARF_WEED_SEED(5303,96,4,170.5,192.0,0.0,79,PatchType.HERB_PATCH,Items.GRIMY_DWARF_WEED_217), - TORSTOL_SEED(5304,103,4,199.5,224.5,0.0,85,PatchType.HERB_PATCH,Items.GRIMY_TORSTOL_219), - GOUT_TUBER(6311,192,4,105.0,45.0,0.0,29,PatchType.HERB_PATCH,Items.GOUTWEED_3261), - SPIRIT_WEED_SEED(12176, 204, 4, 32.0, 36.0, 0.0, 36, PatchType.HERB_PATCH, Items.GRIMY_SPIRIT_WEED_12174), + // Herbs + GUAM_SEED(Items.GUAM_SEED_5291,"guam seed",4,4,11.0,12.5,0.0,9,PatchType.HERB_PATCH,Items.GRIMY_GUAM_199), + MARRENTILL_SEED(Items.MARRENTILL_SEED_5292,"marrentill seed",11,4,13.5,15.0,0.0,14,PatchType.HERB_PATCH,Items.GRIMY_MARRENTILL_201), + TARROMIN_SEED(Items.TARROMIN_SEED_5293,"tarromin seed",18,4,16.0,18.0,0.0,19,PatchType.HERB_PATCH,Items.GRIMY_TARROMIN_203), + HARRALANDER_SEED(Items.HARRALANDER_SEED_5294,"harralander seed",25,4,21.5,24.0,0.0,26,PatchType.HERB_PATCH,Items.GRIMY_HARRALANDER_205), + RANARR_SEED(Items.RANARR_SEED_5295,"ranarr seed",32,4,27.0,30.5,0.0,32,PatchType.HERB_PATCH,Items.GRIMY_RANARR_207), + AVANTOE_SEED(Items.AVANTOE_SEED_5298,"avantoe seed",39,4,54.5,61.5,0.0,50,PatchType.HERB_PATCH,Items.GRIMY_AVANTOE_211), + TOADFLAX_SEED(Items.TOADFLAX_SEED_5296,"toadflax seed",46,4,34.0,38.5,0.0,38,PatchType.HERB_PATCH,Items.GRIMY_TOADFLAX_3049), + IRIT_SEED(Items.IRIT_SEED_5297,"irit seed",53,4,43.0,48.5,0.0,44,PatchType.HERB_PATCH,Items.GRIMY_IRIT_209), + KWUARM_SEED(Items.KWUARM_SEED_5299,"kwuarm seed",68,4,69.0,78.0,0.0,56,PatchType.HERB_PATCH,Items.GRIMY_KWUARM_213), + SNAPDRAGON_SEED(Items.SNAPDRAGON_SEED_5300,"snapdragon seed",75,4,87.5,98.5,0.0,62,PatchType.HERB_PATCH,Items.GRIMY_SNAPDRAGON_3051), + CADANTINE_SEED(Items.CADANTINE_SEED_5301,"cadantine seed",82,4,106.5,120.0,0.0,67,PatchType.HERB_PATCH,Items.GRIMY_CADANTINE_215), + LANTADYME_SEED(Items.LANTADYME_SEED_5302,"lantadyme seed",89,4,134.5,151.5,0.0,73,PatchType.HERB_PATCH,Items.GRIMY_LANTADYME_2485), + DWARF_WEED_SEED(Items.DWARF_WEED_SEED_5303,"dwarf weed seed",96,4,170.5,192.0,0.0,79,PatchType.HERB_PATCH,Items.GRIMY_DWARF_WEED_217), + TORSTOL_SEED(Items.TORSTOL_SEED_5304,"torstol seed",103,4,199.5,224.5,0.0,85,PatchType.HERB_PATCH,Items.GRIMY_TORSTOL_219), + GOUT_TUBER(Items.GOUT_TUBER_6311,"gout tuber",192,4,105.0,45.0,0.0,29,PatchType.HERB_PATCH,Items.GOUTWEED_3261), + SPIRIT_WEED_SEED(Items.SPIRIT_WEED_SEED_12176,"spirit weed seed", 204, 4, 32.0, 36.0, 0.0, 36, PatchType.HERB_PATCH, Items.GRIMY_SPIRIT_WEED_12174), - //Other - BELLADONNA_SEED(5281, 4, 4, 91.0, 128.0, 0.0, 63, PatchType.BELLADONNA_PATCH, Items.CAVE_NIGHTSHADE_2398), - MUSHROOM_SPORE(Items.MUSHROOM_SPORE_5282, 6, 7, 61.5, 57.7, 0.0, 53, PatchType.MUSHROOM_PATCH, Items.MUSHROOM_6004), - CACTUS_SEED(Items.CACTUS_SEED_5280, 8, 7, 66.5, 25.0, 374.0, 55, PatchType.CACTUS_PATCH, Items.CACTUS_SPINE_6016), - EVIL_TURNIP_SEED(Items.EVIL_TURNIP_SEED_12148, 4, 1, 41.0, 46.0, 0.0, 42, PatchType.EVIL_TURNIP_PATCH, Items.EVIL_TURNIP_12134) + // Special + BELLADONNA_SEED(Items.BELLADONNA_SEED_5281, "belladonna seed", 4, 4, 91.0, 128.0, 0.0, 63, PatchType.BELLADONNA_PATCH, Items.CAVE_NIGHTSHADE_2398), + MUSHROOM_SPORE(Items.MUSHROOM_SPORE_5282, "mushroom spore", 4, 6, 61.5, 57.7, 0.0, 53, PatchType.MUSHROOM_PATCH, Items.MUSHROOM_6004), + CACTUS_SEED(Items.CACTUS_SEED_5280, "cactus seed", 8, 7, 66.5, 25.0, 374.0, 55, PatchType.CACTUS_PATCH, Items.CACTUS_SPINE_6016), + EVIL_TURNIP_SEED(Items.EVIL_TURNIP_SEED_12148, "evil turnip seed", 4, 1, 41.0, 46.0, 0.0, 42, PatchType.EVIL_TURNIP_PATCH, Items.EVIL_TURNIP_12134), + CALQUAT_SAPLING(Items.CALQUAT_SAPLING_5503, "calquat tree sapling", 4, 8, 130.5, 48.5, 12096.0, 72, PatchType.CALQUAT_TREE_PATCH, Items.CALQUAT_FRUIT_5980, Item(Items.POISON_IVY_BERRIES_6018, 8)), + SPIRIT_SAPLING(Items.SPIRIT_SAPLING_5375, "spirit tree sapling", 8, 12, 199.5, 0.0, 19301.0, 83, PatchType.SPIRIT_TREE_PATCH, 0, Item(Items.MONKEY_NUTS_4012, 5), null, Item(Items.MONKEY_BAR_4014, 1), Item(Items.GROUND_TOOTH_9082, 1) ) ; - constructor(itemID: Int, value: Int, stages: Int, plantingXP: Double, harvestXP: Double, checkHealthXP: Double, requiredLevel: Int, applicablePatch: PatchType, harvestItem: Int, protectionFlower: Plantable) - : this(itemID,value,stages,plantingXP,harvestXP,checkHealthXP,requiredLevel,applicablePatch,harvestItem,null,protectionFlower) + constructor(itemID: Int, displayName: String, value: Int, stages: Int, plantingXP: Double, harvestXP: Double, checkHealthXP: Double, requiredLevel: Int, applicablePatch: PatchType, harvestItem: Int, protectionFlower: Plantable) + : this(itemID,displayName,value,stages,plantingXP,harvestXP,checkHealthXP,requiredLevel,applicablePatch,harvestItem,null,protectionFlower) companion object { @JvmField val plantables = values().map { it.itemID to it }.toMap() diff --git a/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt b/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt index ce7a4019a..b9a25c563 100644 --- a/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt +++ b/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt @@ -61,7 +61,7 @@ class SackBasketOptionHandler : OptionHandler() { appropriateProduce.amount = (max - specific) } - if(player.inventory.remove(item) && player.inventory.remove(appropriateProduce)) + if(player.inventory.remove(appropriateProduce) && player.inventory.remove(item)) player.inventory.add(Item(container.containers[specific + appropriateProduce.amount])) } diff --git a/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt b/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt index 39c83483e..5f03a292f 100644 --- a/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt +++ b/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt @@ -57,19 +57,20 @@ class SeedlingListener : InteractionListener { fun getSeedling(id: Int) : Int { return when (id) { - Items.ACORN_5312 -> Items.OAK_SEEDLING_5358 - Items.WILLOW_SEED_5313 -> Items.WILLOW_SEEDLING_5359 - Items.MAPLE_SEED_5314 -> Items.MAPLE_SEEDLING_5360 - Items.YEW_SEED_5315 -> Items.YEW_SEEDLING_5361 - Items.MAGIC_SEED_5316 -> Items.MAGIC_SEEDLING_5362 - Items.APPLE_TREE_SEED_5283 -> Items.APPLE_SEEDLING_5480 - Items.BANANA_TREE_SEED_5284 -> Items.BANANA_SEEDLING_5481 - Items.ORANGE_TREE_SEED_5285 -> Items.ORANGE_SEEDLING_5482 - Items.CURRY_TREE_SEED_5286 -> Items.CURRY_SEEDLING_5483 - Items.PINEAPPLE_SEED_5287 -> Items.PINEAPPLE_SEEDLING_5484 - Items.PAPAYA_TREE_SEED_5288 -> Items.PAPAYA_SEEDLING_5485 - Items.PALM_TREE_SEED_5289 -> Items.PALM_SEEDLING_5486 - Items.SPIRIT_SEED_5317 -> Items.SPIRIT_SEEDLING_5363 + Items.ACORN_5312 -> Items.OAK_SEEDLING_5358 + Items.WILLOW_SEED_5313 -> Items.WILLOW_SEEDLING_5359 + Items.MAPLE_SEED_5314 -> Items.MAPLE_SEEDLING_5360 + Items.YEW_SEED_5315 -> Items.YEW_SEEDLING_5361 + Items.MAGIC_SEED_5316 -> Items.MAGIC_SEEDLING_5362 + Items.APPLE_TREE_SEED_5283 -> Items.APPLE_SEEDLING_5480 + Items.BANANA_TREE_SEED_5284 -> Items.BANANA_SEEDLING_5481 + Items.ORANGE_TREE_SEED_5285 -> Items.ORANGE_SEEDLING_5482 + Items.CURRY_TREE_SEED_5286 -> Items.CURRY_SEEDLING_5483 + Items.PINEAPPLE_SEED_5287 -> Items.PINEAPPLE_SEEDLING_5484 + Items.PAPAYA_TREE_SEED_5288 -> Items.PAPAYA_SEEDLING_5485 + Items.PALM_TREE_SEED_5289 -> Items.PALM_SEEDLING_5486 + Items.SPIRIT_SEED_5317 -> Items.SPIRIT_SEEDLING_5363 + Items.CALQUAT_TREE_SEED_5290 -> Items.CALQUAT_SEEDLING_5487 else -> -1 } } @@ -87,7 +88,8 @@ class SeedlingListener : InteractionListener { Items.PINEAPPLE_SEED_5287, Items.PAPAYA_TREE_SEED_5288, Items.PALM_TREE_SEED_5289, - Items.SPIRIT_SEED_5317 + Items.SPIRIT_SEED_5317, + Items.CALQUAT_TREE_SEED_5290 ) val TREE_SEEDLINGS = intArrayOf( @@ -103,7 +105,8 @@ class SeedlingListener : InteractionListener { Items.PINEAPPLE_SEEDLING_5484, Items.PAPAYA_SEEDLING_5485, Items.PALM_SEEDLING_5486, - Items.SPIRIT_SEEDLING_5363 + Items.SPIRIT_SEEDLING_5363, + Items.CALQUAT_SEEDLING_5487, ) private val WATERING_CANS = intArrayOf(Items.WATERING_CAN8_5340,Items.WATERING_CAN7_5339,Items.WATERING_CAN6_5338,Items.WATERING_CAN5_5337,Items.WATERING_CAN4_5336,Items.WATERING_CAN3_5335,Items.WATERING_CAN2_5334,Items.WATERING_CAN1_5333) diff --git a/Server/src/main/content/global/skill/farming/Stump.kt b/Server/src/main/content/global/skill/farming/Stump.kt new file mode 100644 index 000000000..60c9bab8a --- /dev/null +++ b/Server/src/main/content/global/skill/farming/Stump.kt @@ -0,0 +1,5 @@ +package content.global.skill.farming + +class Stump(val varbit: Int, val TTL: Long) { + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt b/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt index 50ec9662f..4ad7953f9 100644 --- a/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt +++ b/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt @@ -10,6 +10,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.Components +import org.rs09.consts.Items import org.rs09.consts.NPCs /** @@ -130,10 +131,9 @@ class ToolLeprechaunOnVacationDialogue(player: Player? = null) : DialoguePlugin( } /** - * Note: - * Goth chatheads are unfortunately updated and have frozen FacialExpressions. Disabled talk-to for now. + * This Leprechaun Goth should appear once you have Spirit of Summer done, but is currently defaulted as not. */ -// @Initializable +@Initializable class ToolLeprechaunGothDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { @@ -178,7 +178,7 @@ class ToolLeprechaunGothDialogue(player: Player? = null) : DialoguePlugin(player } override fun newInstance(player: Player?): DialoguePlugin { - return ToolLeprechaunDialogue(player) + return ToolLeprechaunGothDialogue(player) } override fun getIds(): IntArray { diff --git a/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt b/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt index 980d20b07..29e0d719d 100644 --- a/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt +++ b/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt @@ -69,7 +69,7 @@ class ToolLeprechaunInterface : InterfaceListener { setHasMagicSecateurs(player,false) } } else { - sendMessage(player, "You already have one of those stored.") + sendMessage(player, "You cannot store more than one pair of secateurs in here.") } } 22 -> { @@ -80,7 +80,7 @@ class ToolLeprechaunInterface : InterfaceListener { removeItem(player, can) setWateringCan(player,can) } else { - sendMessage(player, "You already have one of those stored.") + sendMessage(player, "You cannot store more than one watering can in here.") } } 23 -> doDeposit(player, Items.GARDENING_TROWEL_5325, ::setHasGardeningTrowel, ::hasGardeningTrowel) @@ -119,7 +119,15 @@ class ToolLeprechaunInterface : InterfaceListener { depositMethod.invoke(player, true) removeItem(player, item) } else { - sendMessage(player, "You already have one of those stored.") + val itemName = when (item) { + // secateurs and watering cans are handled separately + Items.RAKE_5341 -> "rake" + Items.SEED_DIBBER_5343 -> "dibber" + Items.SPADE_952 -> "spade" + Items.GARDENING_TROWEL_5325 -> "trowel" + else -> getItemName(item).lowercase() + } + sendMessage(player, "You cannot store more than one $itemName in here.") } } diff --git a/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt b/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt index d71a7c409..e443ad061 100644 --- a/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt +++ b/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt @@ -5,7 +5,6 @@ import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.game.system.task.Pulse -import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import core.game.interaction.IntType import core.game.interaction.InteractionListener @@ -13,6 +12,7 @@ import core.game.interaction.QueueStrength import core.tools.StringUtils import core.tools.prependArticle import org.rs09.consts.Sounds +import content.data.Quests class UseWithPatchHandler : InteractionListener { val RAKE = Items.RAKE_5341 @@ -21,11 +21,14 @@ class UseWithPatchHandler : InteractionListener { val SECATEURS = Items.SECATEURS_5329 val MAGIC_SECATEURS = Items.MAGIC_SECATEURS_7409 val TROWEL = Items.GARDENING_TROWEL_5325 - val pourBucketAnim = Animation(2283) - val wateringCanAnim = Animation(2293) - val plantCureAnim = Animation(2288) - val secateursTreeAnim = Animation(2277) - val magicSecateursTreeAnim = Animation(3340) + val spadeDigAnim = getAnimation(830) + val trowelDigAnim = getAnimation(2272) + val pourBucketAnim = getAnimation(2283) + val seedDibberAnim = getAnimation(2291) + val wateringCanAnim = getAnimation(2293) + val plantCureAnim = getAnimation(2288) + val secateursTreeAnim = getAnimation(2277) + val magicSecateursTreeAnim = getAnimation(3340) @JvmField val allowedNodes = ArrayList() @@ -35,9 +38,10 @@ class UseWithPatchHandler : InteractionListener { onUseWith(IntType.SCENERY, allowedNodes.toIntArray(), *FarmingPatch.patchNodes.toIntArray()) { player, used, with -> val patch = FarmingPatch.forObject(with.asScenery()) ?: return@onUseWith true val usedItem = used.asItem() + val trimmablePatches = arrayOf(PatchType.TREE_PATCH, PatchType.BUSH_PATCH, PatchType.FRUIT_TREE_PATCH, PatchType.SPIRIT_TREE_PATCH, PatchType.CALQUAT_TREE_PATCH) if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB) { - if (!hasRequirement(player, "My Arm's Big Adventure")) + if (!hasRequirement(player, Quests.MY_ARMS_BIG_ADVENTURE)) return@onUseWith true } @@ -46,7 +50,7 @@ class UseWithPatchHandler : InteractionListener { RAKE -> PatchRaker.rake(player,patch) SEED_DIBBER -> sendMessage(player, "I should plant a seed, not the seed dibber.") SPADE -> { - val anim = getAnimation(830) + val anim = spadeDigAnim val p = patch.getPatchFor(player) if (p.isDead) { sendMessage(player, "You start digging the farming patch...") @@ -76,7 +80,7 @@ class UseWithPatchHandler : InteractionListener { } SECATEURS, MAGIC_SECATEURS -> { val p = patch.getPatchFor(player) - if (patch.type == PatchType.TREE_PATCH) { + if (patch.type in trimmablePatches) { if (p.isDiseased && !p.isDead) { submitIndividualPulse(player, object: Pulse() { override fun pulse(): Boolean { @@ -112,7 +116,7 @@ class UseWithPatchHandler : InteractionListener { return@onUseWith true } - val anim = Animation(2272) + val anim = trowelDigAnim submitIndividualPulse(player, object : Pulse(anim.duration) { override fun pulse(): Boolean { @@ -128,7 +132,7 @@ class UseWithPatchHandler : InteractionListener { Items.PLANT_CURE_6036 -> { val p = patch.getPatchFor(player) val patchName = p.patch.type.displayName() - if (p.isDiseased && !p.isDead) { + if (p.isDiseased && !p.isDead && patch.type !in trimmablePatches) { sendMessage(player, "You treat the $patchName with the plant cure.") queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> when (stage) { @@ -156,15 +160,21 @@ class UseWithPatchHandler : InteractionListener { Items.WATERING_CAN_5331,Items.WATERING_CAN1_5333,Items.WATERING_CAN2_5334,Items.WATERING_CAN3_5335,Items.WATERING_CAN4_5336,Items.WATERING_CAN5_5337,Items.WATERING_CAN6_5338,Items.WATERING_CAN7_5339,Items.WATERING_CAN8_5340 -> { val p = patch.getPatchFor(player) val t = p.patch.type - if (p.isWatered || p.isEmptyAndWeeded() || p.isGrown() || p.plantable == Plantable.SCARECROW) { - sendMessage(player, "This patch doesn't need watering.") - } else if (t == PatchType.ALLOTMENT || t == PatchType.FLOWER_PATCH || t == PatchType.HOPS_PATCH) { + if (t == PatchType.ALLOTMENT || t == PatchType.FLOWER_PATCH || t == PatchType.HOPS_PATCH) { submitIndividualPulse(player, object : Pulse() { override fun pulse(): Boolean { - if (p.isWeedy()) { + if (p.isWeedy() || p.isEmptyAndWeeded()) { sendMessage(player, "You should grow something first.") return true } + if (p.isWatered || p.isGrown() || p.plantable == Plantable.SCARECROW) { + sendMessage(player, "This patch doesn't need watering.") + return true + } + if (p.isDiseased || p.isDead) { + sendMessage(player, "Water isn't going to cure that!") + return true + } if (usedItem.id == Items.WATERING_CAN_5331) { sendMessage(player, "You need to fill the watering can first.") return true @@ -178,6 +188,8 @@ class UseWithPatchHandler : InteractionListener { return true } }) + } else { + sendMessage(player, "This patch doesn't need watering.") } } @@ -212,9 +224,9 @@ class UseWithPatchHandler : InteractionListener { val plantable = Plantable.forItemID(usedItem.id) ?: return@onUseWith false if (plantable.applicablePatch != patch.type) { - val seedNamePlural = StringUtils.plusS(plantable.name.replace("_", " ").lowercase()) + val plantableNamePlural = StringUtils.plusS(plantable.displayName) val patchType = if (plantable.applicablePatch == PatchType.ALLOTMENT) "a vegetable patch" else prependArticle(plantable.applicablePatch.displayName()) - sendMessage(player, "You can only plant $seedNamePlural in $patchType.") + sendMessage(player, "You can only plant $plantableNamePlural in $patchType.") return@onUseWith true } @@ -224,7 +236,7 @@ class UseWithPatchHandler : InteractionListener { } val p = patch.getPatchFor(player) - if (p.getCurrentState() < 3 && p.isWeedy() && plantable != Plantable.SCARECROW) { + if (p.getCurrentState() < 3 && p.isWeedy()) { sendMessage(player, "This patch needs weeding first.") return@onUseWith true } else if (p.getCurrentState() > 3) { @@ -232,66 +244,84 @@ class UseWithPatchHandler : InteractionListener { return@onUseWith true } - val plantItem = - if (patch.type == PatchType.ALLOTMENT) Item(plantable.itemID,3) else if (patch.type == PatchType.HOPS_PATCH) { - if (plantable == Plantable.JUTE_SEED) Item(plantable.itemID,3) else Item(plantable.itemID,4) - } else { - Item(plantable.itemID,1) - } - - if (patch.type == PatchType.ALLOTMENT) { - if (!player.inventory.containsItem(plantItem)) { - sendMessage(player, "You need 3 seeds to plant an allotment patch.") - return@onUseWith true - } + val plantItem = when (patch.type) { + PatchType.ALLOTMENT -> Item(plantable.itemID, 3) + PatchType.HOPS_PATCH -> if (plantable == Plantable.JUTE_SEED) Item(plantable.itemID, 3) else Item(plantable.itemID, 4) + else -> Item(plantable.itemID,1) } - if (patch.type != PatchType.FRUIT_TREE_PATCH && patch.type != PatchType.TREE_PATCH) { - if (!inInventory(player, Items.SEED_DIBBER_5343)) { - sendMessage(player, "You need a seed dibber to plant that.") - return@onUseWith true - } - } else { - if (!inInventory(player, Items.SPADE_952) && plantable != Plantable.SCARECROW) { - sendMessage(player, "You need a spade to plant that.") - return@onUseWith true - } + + if (!player.inventory.containsItem(plantItem)) { + val seedPlural = if (plantItem.amount == 1) "seed" else "seeds" + sendMessage(player, "You need ${plantItem.amount} $seedPlural to plant ${prependArticle(patch.type.displayName())}.") + return@onUseWith true } - player.lock() - if (removeItem(player, plantItem)) { - if (plantable != Plantable.SCARECROW) { - animate(player, 2291) - playAudio(player, Sounds.FARMING_DIBBING_2432) - } - val delay = if (plantable == Plantable.SCARECROW) 0 else 3 - submitIndividualPulse(player, object : Pulse(delay) { - override fun pulse(): Boolean { - if (plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 0, 7)) { - player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 7) - } - p.plant(plantable) - rewardXP(player, Skills.FARMING, plantable.plantingXP) - p.setNewHarvestAmount() - if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) { - addItem(player, Items.PLANT_POT_5350) - } - val itemAmount = if (plantItem.amount == 1) "a" else plantItem.amount - val itemName = if (plantItem.amount == 1) getItemName(plantItem.id).lowercase() else StringUtils.plusS(getItemName(plantItem.id).lowercase()) - val patchName = p.patch.type.displayName() - if (plantable == Plantable.SCARECROW) { - sendMessage(player, "You place the scarecrow in the $patchName.") - } else { - sendMessage(player, "You plant $itemAmount $itemName in the $patchName.") - } + /*if (patch == FarmingPatch.WILDERNESS_FLOWER && plantable != Plantable.LIMPWURT_SEED){ + return@onUseWith true + }*/ - player.unlock() - return true + val requiredItem = when (patch.type) { + PatchType.TREE_PATCH, PatchType.FRUIT_TREE_PATCH, PatchType.SPIRIT_TREE_PATCH, PatchType.CALQUAT_TREE_PATCH -> Items.SPADE_952 + PatchType.FLOWER_PATCH -> if (plantable == Plantable.SCARECROW) null else Items.SEED_DIBBER_5343 + else -> Items.SEED_DIBBER_5343 + } + if (requiredItem != null && !inInventory(player, requiredItem)) { + sendDialogue(player, "You need ${prependArticle(requiredItem.asItem().name.lowercase())} to plant that.") + return@onUseWith true + } + val spiritTreePlanted = (getVarbit(player, 720) > 3 || getVarbit(player, 722) > 3 || getVarbit(player, 724) > 3) + if (plantable == Plantable.SPIRIT_SAPLING && spiritTreePlanted){ + sendDialogue(player, "You already have a spirit tree. You can't plant another one.") + return@onUseWith true + } + + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + val (anim, sound) = when (requiredItem) { + Items.SPADE_952 -> Pair(spadeDigAnim, Sounds.DIGSPADE_1470) + else -> Pair(seedDibberAnim,Sounds.FARMING_DIBBING_2432) + } + animate(player, anim) + playAudio(player, sound) + val delay = if (patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.SPIRIT_TREE_PATCH || + patch.type == PatchType.CALQUAT_TREE_PATCH || plantable == Plantable.SCARECROW) 3 else 0 + return@queueScript delayScript(player,anim.duration + delay) } - }) + 1 -> { + if (removeItem(player, plantItem)) { + if (plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 0, 7)) { + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 7) + } + p.plant(plantable) + rewardXP(player, Skills.FARMING, plantable.plantingXP) + p.setNewHarvestAmount() + if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH || p.patch.type == PatchType.SPIRIT_TREE_PATCH) { + addItem(player, Items.PLANT_POT_5350) + } + + val itemAmount = + if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH || p.patch.type == PatchType.SPIRIT_TREE_PATCH) "the" + else if (plantItem.amount == 1) "a" + else plantItem.amount + val itemName = + if (plantItem.amount == 1) plantable.displayName else StringUtils.plusS( + plantable.displayName + ) + val patchName = p.patch.type.displayName() + if (plantable == Plantable.SCARECROW) { + sendMessage(player, "You place the scarecrow in the $patchName.") + } else { + sendMessage(player, "You plant $itemAmount $itemName in the $patchName.") + } + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } } } } - return@onUseWith true } } diff --git a/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt b/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt index ae3765a99..3cc14cd55 100644 --- a/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt +++ b/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt @@ -41,7 +41,7 @@ class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) { //Another more extreme example is if you planted something at 10:31 that takes 5 minutes to grow. 10:35 comes around, it hasn't been 5 minutes, so it doesn't grow, meaning //it actually grows at 10:40, an extra 4 minutes. //this code makes it so crops planted both at 10:31 and 10:34 grow at 10:35 if they are supposed to take 5 minutes for each stage. - if(patch.nextGrowth < (System.currentTimeMillis() + 240_000L) && !patch.isDead){ + if(patch.nextGrowth < (System.currentTimeMillis() + 240_000L) && !patch.isDead && !patch.isChoppedFruitTree()){ patch.nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(patch.getStageGrowthMinutes().toLong()) patch.update() } @@ -57,13 +57,21 @@ class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) { private fun runOfflineCatchupLogic() { for ((_, patch) in patchMap) { val type = patch.patch.type - val shouldPlayCatchup = !patch.isGrown() || (type == PatchType.BUSH_PATCH && patch.getFruitOrBerryCount() < 4) || (type == PatchType.FRUIT_TREE_PATCH && patch.getFruitOrBerryCount() < 6) - if(shouldPlayCatchup && patch.plantable != null && !patch.isDead){ - var stagesToSimulate = if (!patch.isGrown()) patch.plantable!!.stages - patch.currentGrowthStage else 0 - if (type == PatchType.BUSH_PATCH) - stagesToSimulate += Math.min(4, 4 - patch.getFruitOrBerryCount()) - if (type == PatchType.FRUIT_TREE_PATCH) - stagesToSimulate += Math.min(6, 6 - patch.getFruitOrBerryCount()) + val shouldPlayCatchup = !patch.isGrown() || (type == PatchType.BUSH_PATCH && patch.getFruitOrBerryCount() < 4) || (type == PatchType.FRUIT_TREE_PATCH && patch.getFruitOrBerryCount() < 6) || (patch.plantable == Plantable.WILLOW_SAPLING && patch.harvestAmt < 6) + if (shouldPlayCatchup && !patch.isDead && !patch.isChoppedFruitTree()) { + var stagesToSimulate = if (!patch.isGrown()) { + if (patch.isWeedy() || patch.isEmptyAndWeeded()) patch.currentGrowthStage % 4 + else patch.plantable!!.stages - patch.currentGrowthStage + } else 0 + + if (patch.plantable != null) { + if (type == PatchType.BUSH_PATCH) + stagesToSimulate += Math.min(4, 4 - patch.getFruitOrBerryCount()) + if (type == PatchType.FRUIT_TREE_PATCH) + stagesToSimulate += Math.min(6, 6 - patch.getFruitOrBerryCount()) + if (patch.plantable == Plantable.WILLOW_SAPLING) + stagesToSimulate += Math.min(6, 6 - patch.harvestAmt) + } val nowTime = System.currentTimeMillis() var simulatedTime = patch.nextGrowth @@ -77,8 +85,8 @@ class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) { } } - fun getPatch(patch: FarmingPatch): Patch { - return patchMap[patch] ?: (Patch(player,patch).also { patchMap[patch] = it }) + fun getPatch(patch: FarmingPatch, addPatch: Boolean ): Patch { + return patchMap[patch] ?: (Patch(player,patch).also { if (addPatch) patchMap[patch] = it }) } fun getPatches(): MutableCollection{ diff --git a/Server/src/main/content/global/skill/farming/timers/StumpGrowth.kt b/Server/src/main/content/global/skill/farming/timers/StumpGrowth.kt new file mode 100644 index 000000000..616bde43a --- /dev/null +++ b/Server/src/main/content/global/skill/farming/timers/StumpGrowth.kt @@ -0,0 +1,59 @@ +package content.global.skill.farming.timers + +import core.game.node.entity.Entity +import core.game.system.timer.* +import core.game.node.entity.player.Player +import content.global.skill.farming.* +import core.tools.ticksToSeconds +import java.util.concurrent.TimeUnit +import org.json.simple.* + +class StumpGrowth : PersistTimer (1, "farming:stump", isSoft = true) { + val stumps = ArrayList() + lateinit var player: Player + + fun addStump(varbit: Int, ttl: Int){ + stumps.add( + Stump( + varbit, + System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(ticksToSeconds(ttl).toLong()) + ) + ) + } + + override fun onRegister (entity: Entity) { + player = (entity as? Player)!! + } + + override fun run (entity: Entity) : Boolean { + val removeList = ArrayList() + for (stump in stumps) { + if (System.currentTimeMillis() > stump.TTL) { + FarmingPatch.patches[stump.varbit]?.getPatchFor(player)?.regrowIfTreeStump() + removeList.add(stump) + } + } + stumps.removeAll(removeList) + return stumps.isNotEmpty() + } + + override fun save(root: JSONObject, entity: Entity) { + val stumpArray = JSONArray() + for(s in stumps){ + val seed = JSONObject() + seed["patch"] = s.varbit + seed["ttl"] = s.TTL + stumpArray.add(seed) + } + root.put("stumps",stumpArray) + } + + override fun parse(root: JSONObject, entity: Entity) { + (root["stumps"] as JSONArray).forEach { + val s = it as JSONObject + val id = s["patch"].toString().toInt() + val ttl = s["ttl"].toString().toLong() + stumps.add(Stump(id,ttl)) + } + } +} diff --git a/Server/src/main/content/global/skill/fishing/Fish.kt b/Server/src/main/content/global/skill/fishing/Fish.kt index 46b73bee2..8ccc67f24 100644 --- a/Server/src/main/content/global/skill/fishing/Fish.kt +++ b/Server/src/main/content/global/skill/fishing/Fish.kt @@ -24,7 +24,7 @@ enum class Fish(val id: Int, val level: Int, val experience: Double, val lowChan LOBSTER(Items.RAW_LOBSTER_377, 40, 90.0, 0.16, 0.375), BASS(Items.RAW_BASS_363, 46, 100.0, 0.078, 0.16), SWORDFISH(Items.RAW_SWORDFISH_371, 50, 100.0, 0.105, 0.191), - LAVA_EEL(Items.RAW_LAVA_EEL_2148, 53, 30.0, 0.227, 0.379), + LAVA_EEL(Items.RAW_LAVA_EEL_2148, 53, 60.0, 0.227, 0.379), MONKFISH(Items.RAW_MONKFISH_7944, 62, 120.0, 0.293, 0.356), KARAMBWAN(Items.RAW_KARAMBWAN_3142, 65, 105.0, 0.414, 0.629), SHARK(Items.RAW_SHARK_383, 76, 110.0, 0.121, 0.16), diff --git a/Server/src/main/content/global/skill/fishing/FishingOption.kt b/Server/src/main/content/global/skill/fishing/FishingOption.kt index 2cf25e5e9..b75ccf9b4 100644 --- a/Server/src/main/content/global/skill/fishing/FishingOption.kt +++ b/Server/src/main/content/global/skill/fishing/FishingOption.kt @@ -20,7 +20,8 @@ enum class FishingOption(val tool: Int, val level: Int, val animation: Animation SHARK_HARPOON(Items.HARPOON_311, 76, Animation(618), null, "harpoon", Fish.SHARK), MONKFISH_NET(Items.SMALL_FISHING_NET_303, 62, Animation(621), null, "net", Fish.MONKFISH), MORTMYRE_ROD(Items.FISHING_ROD_307, 5, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.SLIMY_EEL), - LUMBDSWAMP_ROD(Items.FISHING_ROD_307, 5, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.SLIMY_EEL, Fish.FROG_SPAWN), + LUMBDSWAMP_ROD(Items.FISHING_ROD_307, 5, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.SLIMY_EEL, Fish.CAVE_EEL), + LUMBDSWAMP_NET(Items.SMALL_FISHING_NET_303, 1, Animation(621), null, "net", Fish.FROG_SPAWN), KBWANJI_NET(Items.SMALL_FISHING_NET_303, 5, Animation(621), null, "net", Fish.KARAMBWANJI), KARAMBWAN_VES(Items.KARAMBWAN_VESSEL_3157, 65, Animation(1193), intArrayOf((Items.RAW_KARAMBWANJI_3150)), "fish", Fish.KARAMBWAN), OILY_FISHING_ROD(Items.OILY_FISHING_ROD_1585, 53, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.LAVA_EEL); diff --git a/Server/src/main/content/global/skill/fishing/FishingSpot.kt b/Server/src/main/content/global/skill/fishing/FishingSpot.kt index cbfda947b..e60dcb98d 100644 --- a/Server/src/main/content/global/skill/fishing/FishingSpot.kt +++ b/Server/src/main/content/global/skill/fishing/FishingSpot.kt @@ -109,6 +109,7 @@ enum class FishingSpot(val ids: IntArray, vararg val options: FishingOption) { NPCs.FISHING_SPOT_2067, NPCs.FISHING_SPOT_2068 ), + FishingOption.LUMBDSWAMP_NET, FishingOption.LUMBDSWAMP_ROD ), SPOT_KBWANJI( diff --git a/Server/src/main/content/global/skill/fletching/AchievementDiaryAttributeKeys.kt b/Server/src/main/content/global/skill/fletching/AchievementDiaryAttributeKeys.kt new file mode 100644 index 000000000..8e3d7fe33 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/AchievementDiaryAttributeKeys.kt @@ -0,0 +1,8 @@ +package content.global.skill.fletching + +object AchievementDiaryAttributeKeys { + /** + * This attribute signifies that the fletch of the magic shortbow is complete which is the first stage of getting the achievement + */ + const val FLETCHED_UNSTRUNG_MAGIC_SHORTBOW = "diary:seers:fletch-magic-short-bow" +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/BoltCreatePlugin.java b/Server/src/main/content/global/skill/fletching/BoltCreatePlugin.java deleted file mode 100644 index 711e9b626..000000000 --- a/Server/src/main/content/global/skill/fletching/BoltCreatePlugin.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -package core.game.node.entity.skill.fletching; - -import core.game.dialogue.SkillDialogueHandler; -import core.game.dialogue.SkillDialogueHandler.SkillDialogue; -import core.game.node.entity.skill.fletching.items.bolts.Bolt; -import core.game.node.entity.skill.fletching.items.bolts.BoltPulse; -import org.crandor.game.interaction.NodeUsageEvent; -import org.crandor.game.interaction.UseWithHandler; -import org.crandor.game.node.entity.player.Player; -import org.crandor.net.packet.PacketRepository; -import org.crandor.net.packet.context.ChildPositionContext; -import org.crandor.net.packet.out.RepositionChild; -import org.crandor.plugin.InitializablePlugin; -import org.crandor.plugin.Plugin; - -*/ -/** - * Represents the bolt creating plugin. - * @author 'Vexia - * @version 1.0 - *//* - -@InitializablePlugin -public final class BoltCreatePlugin extends UseWithHandler { - - */ -/** - * Constructs a new {@code BoltCreatePlugin} {@code Object}. - *//* - - public BoltCreatePlugin() { - super(314); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (Bolt bolt : Bolt.values()) { - addHandler(bolt.getItem().getId(), ITEM_TYPE, this); - } - return this; - } - - @Override - public boolean handle(final NodeUsageEvent event) { - final Player player = event.getPlayer(); - - } - -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/BoltGemPlugin.java b/Server/src/main/content/global/skill/fletching/BoltGemPlugin.java deleted file mode 100644 index 70c38b30a..000000000 --- a/Server/src/main/content/global/skill/fletching/BoltGemPlugin.java +++ /dev/null @@ -1,45 +0,0 @@ -//package core.game.node.entity.skill.fletching; -// -//import core.game.dialogue.SkillDialogueHandler; -//import core.game.dialogue.SkillDialogueHandler.SkillDialogue; -//import core.game.node.entity.skill.fletching.items.gem.GemBolt; -//import core.game.node.entity.skill.fletching.items.gem.GemBoltPulse; -//import org.crandor.game.interaction.NodeUsageEvent; -//import org.crandor.game.interaction.UseWithHandler; -//import org.crandor.game.node.entity.player.Player; -//import org.crandor.net.packet.PacketRepository; -//import org.crandor.net.packet.context.ChildPositionContext; -//import org.crandor.net.packet.out.RepositionChild; -//import org.crandor.plugin.InitializablePlugin; -//import org.crandor.plugin.Plugin; -// -///** -// * Represents the plugin used to handle gem bolt making. -// * @author 'Vexia -// * @version 1.0 -// */ -//@InitializablePlugin -//public class BoltGemPlugin extends UseWithHandler { -// -// /** -// * Constructs a new {@code BoltGemPlugin} {@code Object}. -// */ -// public BoltGemPlugin() { -// super(45, 46, 9187, 9188, 9189, 9190, 9191, 9192, 9193, 9194); -// } -// -// @Override -// public Plugin newInstance(Object arg) throws Throwable { -// for (GemBolt bolt : GemBolt.values()) { -// addHandler(bolt.getBase().getId(), ITEM_TYPE, this); -// } -// return this; -// } -// -// @Override -// public boolean handle(final NodeUsageEvent event) { -// final Player player = event.getPlayer(); -// -// } -// -//} diff --git a/Server/src/main/content/global/skill/fletching/DartCreatePlugin.java b/Server/src/main/content/global/skill/fletching/DartCreatePlugin.java deleted file mode 100644 index c43104095..000000000 --- a/Server/src/main/content/global/skill/fletching/DartCreatePlugin.java +++ /dev/null @@ -1,49 +0,0 @@ -/* -package core.game.node.entity.skill.fletching; - -import core.game.node.entity.skill.fletching.items.darts.Dart; -import org.crandor.game.interaction.NodeUsageEvent; -import org.crandor.game.interaction.UseWithHandler; -import org.crandor.plugin.InitializablePlugin; -import org.crandor.plugin.Plugin; -import core.game.content.quest.touristrap.TouristTrap; - -*/ -/** - * Represents the plugin used to create a dart. - * @author 'Vexia - * @version 1.0 - *//* - -@InitializablePlugin -public final class DartCreatePlugin extends UseWithHandler { - - */ -/** - * Constructs a new {@code DartCreatePlugin} {@code Object}. - *//* - - public DartCreatePlugin() { - super(314); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (Dart dart : Dart.values()) { - addHandler(dart.getItem().getId(), ITEM_TYPE, this); - } - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - if (event.getPlayer().getQuestRepository().getQuest(TouristTrap.NAME).getStage(event.getPlayer()) < 60) { - event.getPlayer().getPacketDispatch().sendMessage("You need to start Tourist Trap in order to do this."); - return true; - } - event.getPlayer().getDialogueInterpreter().open(328933, event.getUsedItem(), event.getBaseItem()); - return true; - } - -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/Feathers.kt b/Server/src/main/content/global/skill/fletching/Feathers.kt new file mode 100644 index 000000000..f76b00a72 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/Feathers.kt @@ -0,0 +1,16 @@ +package content.global.skill.fletching + +import org.rs09.consts.Items + +object Feathers { + val all = intArrayOf( + Items.FEATHER_314, + Items.STRIPY_FEATHER_10087, + Items.RED_FEATHER_10088, + Items.BLUE_FEATHER_10089, + Items.YELLOW_FEATHER_10090, + Items.ORANGE_FEATHER_10091 + ) + + const val STANDARD = Items.FEATHER_314 +} diff --git a/Server/src/main/content/global/skill/fletching/FletchItem.java b/Server/src/main/content/global/skill/fletching/FletchItem.java deleted file mode 100644 index fee42d6c1..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchItem.java +++ /dev/null @@ -1,137 +0,0 @@ -/* -package core.game.node.entity.skill.fletching; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents a fletching item to make. - * @author 'Vexia - *//* - -public enum FletchItem { - ARROW_SHAFT(FletchType.LOG, new Item(52, 15), 1, 5), SHORTBOW(FletchType.LOG, new Item(50), 5, 5), - LONGBOW(FletchType.LOG, new Item(48), 10, 10), - OAK_SHORTBOW(FletchType.OAK, new Item(54), 20, 16.5), - OAK_LONGBOW(FletchType.OAK, new Item(56), 25, 25), - WILLOW_SHORTBOW(FletchType.WILLOW, new Item(60), 35, 33.3), - WILLOW_LONGBOW(FletchType.WILLOW, new Item(58), 40, 41.5), - MAPLE_SHORTBOW(FletchType.MAPLE, new Item(64), 50, 50), - MAPLE_LONGBOW(FletchType.MAPLE, new Item(62), 55, 58.3), - YEW_SHORTBOW(FletchType.YEW, new Item(68), 65, 55), - YEW_LONGBOW(FletchType.YEW, new Item(66), 70, 75), - MAGIC_SHORTBOW(FletchType.MAGIC, new Item(72), 80, 83.3), - MAGIC_LONGBOW(FletchType.MAGIC, new Item(70), 85, 91.5), - WOODEN_STOCK(FletchType.LOG, new Item(9440), 9, 6), - OAK_STOCK(FletchType.OAK, new Item(9442), 24, 16), - WILLOW_STOCK(FletchType.WILLOW, new Item(9444), 39, 22), - TEAK_STOCK(FletchType.TEAK, new Item(9446), 46, 27), - MAPLE_STOCK(FletchType.MAPLE, new Item(9448), 54, 32), - MAHOGANY_STOCK(FletchType.MAHOGANY, new Item(9450), 61, 41), - YEW_STOCK(FletchType.YEW, new Item(9452), 69, 50); - - */ -/** - * Constructs a new {@code FletchItem.java} {@code Object}. - * @param type the type. - * @param product the product. - * @param level the level. - * @param experience the experience. - *//* - - FletchItem(final FletchType type, final Item product, final int level, final double experience) { - this.type = type; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Represents the type this item pertaint o. - *//* - - private FletchType type; - - */ -/** - * Represents the product of this item. - *//* - - private Item product; - - */ -/** - * Represents the level. - *//* - - private final int level; - - */ -/** - * Represents the experience. - *//* - - private final double experience; - - */ -/** - * Gets the type. - * @return The type. - *//* - - public FletchType getType() { - return type; - } - - */ -/** - * Sets the type. - * @param type The type to set. - *//* - - public void setType(FletchType type) { - this.type = type; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Sets the product. - * @param product The product to set. - *//* - - public void setProduct(Item product) { - this.product = product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/FletchType.java b/Server/src/main/content/global/skill/fletching/FletchType.java deleted file mode 100644 index 33509c1ab..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchType.java +++ /dev/null @@ -1,88 +0,0 @@ -/* -package core.game.node.entity.skill.fletching; - -import org.crandor.game.component.Component; -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents the multiple fletching types(log types) - * @author 'Vexia - *//* - -public enum FletchType { - LOG(new Item(1511), FletchItem.ARROW_SHAFT, FletchItem.SHORTBOW, FletchItem.LONGBOW, FletchItem.WOODEN_STOCK), OAK(new Item(1521), FletchItem.OAK_SHORTBOW, FletchItem.OAK_LONGBOW, FletchItem.OAK_STOCK), WILLOW(new Item(1519), FletchItem.WILLOW_SHORTBOW, FletchItem.WILLOW_LONGBOW, FletchItem.WILLOW_STOCK), MAPLE(new Item(1517), FletchItem.MAPLE_SHORTBOW, FletchItem.MAPLE_LONGBOW, FletchItem.MAPLE_STOCK), TEAK(new Item(6333), FletchItem.TEAK_STOCK), MAHOGANY(new Item(6332), FletchItem.MAHOGANY_STOCK), YEW(new Item(1515), FletchItem.YEW_SHORTBOW, FletchItem.YEW_LONGBOW, FletchItem.YEW_STOCK), MAGIC(new Item(1513), FletchItem.MAGIC_SHORTBOW, FletchItem.MAGIC_LONGBOW); - - */ -/** - * Constructs a new {@code FletchType} {@code Object}. - * @param log the log. - * @param items the item.s - *//* - - FletchType(final Item log, final FletchItem... items) { - this.log = log; - this.items = items; - } - - */ -/** - * Represents the log of this type. - *//* - - private final Item log; - - */ -/** - * Represents the fletching items of this type. - *//* - - private FletchItem[] items; - - */ -/** - * Gets the items. - * @return The items. - *//* - - public FletchItem[] getItems() { - return items; - } - - */ -/** - * Gets the log. - * @return The log. - *//* - - public Item getLog() { - return log; - } - - */ -/** - * Method used to get the component based on type. - * @return the component. - *//* - - public Component getComponent() { - return items.length > 1 ? new Component(301 + items.length) : new Component(309); - } - - */ -/** - * Method used to get the FletchType based on the log item. - * @param item the item. - * @return the fletch type. - *//* - - public static FletchType forItem(final Item item) { - for (FletchType type : FletchType.values()) { - if (type.getLog().getId() == item.getId()) { - return type; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/Fletching.java b/Server/src/main/content/global/skill/fletching/Fletching.java deleted file mode 100644 index 4dea01354..000000000 --- a/Server/src/main/content/global/skill/fletching/Fletching.java +++ /dev/null @@ -1,353 +0,0 @@ -package content.global.skill.fletching; - -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; - -import java.util.HashMap; -public class Fletching { - public static HashMaplogMap = new HashMap<>(); - public static HashMap boltMap = new HashMap<>(); - public static HashMap dartMap = new HashMap<>(); - public static HashMap arrowHeadMap = new HashMap<>(); - public static HashMap gemMap = new HashMap<>(); - public static HashMap tipMap = new HashMap<>(); - public static HashMap stringMap = new HashMap<>(); - public static HashMap limbMap = new HashMap<>(); - static{ - Items[] itemsArray = Items.values(); - int thisLength = itemsArray.length; - for(int x = 0; x < thisLength; x++){ - Items item = itemsArray[x]; - logMap.putIfAbsent(item.id, item.items); - } - Bolts[] boltArray = Bolts.values(); - thisLength = boltArray.length; - for(int x = 0; x < thisLength; x++){ - Bolts bolt = boltArray[x]; - boltMap.putIfAbsent(bolt.unfinished,bolt); - } - Darts[] dartArray = Darts.values(); - thisLength = dartArray.length; - for(int x = 0; x < thisLength; x++){ - Darts dart = dartArray[x]; - dartMap.putIfAbsent(dart.unfinished,dart); - } - ArrowHeads[] ahArray = ArrowHeads.values(); - thisLength = ahArray.length; - for(int x = 0; x < thisLength; x++){ - ArrowHeads arrowhead = ahArray[x]; - arrowHeadMap.putIfAbsent(arrowhead.unfinished,arrowhead); - } - GemBolts[] gbArray = GemBolts.values(); - thisLength = gbArray.length; - for(int x = 0; x < thisLength; x++){ - GemBolts gem = gbArray[x]; - gemMap.putIfAbsent(gem.gem,gem); - tipMap.putIfAbsent(gem.tip,gem); - } - String[] stringArray = String.values(); - thisLength = stringArray.length; - for(int x = 0; x < thisLength; x++){ - String bow = stringArray[x]; - stringMap.putIfAbsent(bow.unfinished,bow); - } - Limb[] limbsArray = Limb.values(); - thisLength = limbsArray.length; - for(int x = 0; x < thisLength; x++){ - Limb limb = limbsArray[x]; - limbMap.putIfAbsent(limb.stock, limb); - } - } - public static FletchingItems[] getEntries(int id){ - return logMap.get(id); - } - public static boolean isLog(int id){ - return logMap.get(id) != null; - } - public static boolean isBolt(int id){ - return boltMap.get(id) != null; - } - public static boolean isDart(int id){ - return dartMap.get(id) != null; - } - public static boolean isArrowHead(int id){ - return arrowHeadMap.get(id) != null; - } - public static boolean isGemTip(int id){ - return tipMap.get(id) != null; - } - public static Item[] getItems(int id){ - FletchingItems[] entry = getEntries(id); - Item items[] = {}; - switch(entry.length){ - case 1: - items = new Item[] {new Item(entry[0].id)}; - break; - case 2: - items = new Item[] {new Item(entry[0].id), new Item(entry[1].id)}; - break; - case 3: - items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id)}; - break; - case 4: - items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id), new Item(entry[3].id)}; - break; - } - return items; - } - public enum Limb { - WOODEN_STOCK(9440,9420,9454,9, 12, new Animation(4436)), - OAK_STOCK(9442,9422,9456,24, 32, new Animation(4437)), - WILLOW_STOCK(9444,9423,9457,39, 44, new Animation(4438)), - TEAK_STOCK(9446,9425,9459,46, 54, new Animation(4439)), - MAPLE_STOCK(9448,9427,9461,54, 64, new Animation(4440)), - MAHOGANY_STOCK(9450,9429,9463,61, 82, new Animation(4441)), - YEW_STOCK(9452,9431,9465,69, 100, new Animation(4442)); - - - public int stock, limb, product,level; - public double experience; - public Animation animation; - - Limb(int stock, int limb, int product, int level, double experience, Animation animation) { - this.stock = stock; - this.limb = limb; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - } - public enum String{ - //Bows - SHORT_BOW((byte) 1,50,841,5, 5, new Animation(6678)), - LONG_BOW((byte) 1,48,839,10, 10, new Animation(6684)), - OAK_SHORTBOW((byte) 1,54,843,20, 16.5, new Animation(6679)), - OAK_LONGBOW((byte) 1,56,845,25, 25, new Animation(6685)), - WILLOW_SHORTBOW((byte) 1,60,849,35, 33.3, new Animation(6680)), - WILLOW_LONGBOW((byte) 1,58,847,40, 41.5, new Animation(6686)), - MAPLE_SHORTBOW((byte) 1,64,853,50, 50, new Animation(6681)), - MAPLE_LONGBOW((byte) 1,62,851,55, 58.3, new Animation(6687)), - YEW_SHORTBOW((byte) 1,68,857,65, 67.5, new Animation(6682)), - YEW_LONGBOW((byte) 1,66,855,70, 75, new Animation(6688)), - MAGIC_SHORTBOW((byte) 1,72,861,80, 83.3, new Animation(6683)), - MAGIC_LONGBOW((byte) 1,70,859,85, 91.5, new Animation(6689)), - - //crossbows - BRONZE_CBOW((byte) 2,9454,9174,9, 6, new Animation(6671)), - BLURITE_CBOW((byte) 2,9456,9176,24, 16, new Animation(6672)), - IRON_CBOW((byte) 2,9457,9177,39, 22, new Animation(6673)), - STEEL_CBOW((byte) 2,9459,9179,46, 27, new Animation(6674)), - MITHIRIL_CBOW((byte) 2,9461,9181,54, 32, new Animation(6675)), - ADAMANT_CBOW((byte) 2,9463,9183,61, 41, new Animation(6676)), - RUNITE_CBOW((byte) 2,9465,9185,69, 50, new Animation(6677)); - - - public int unfinished,product,string,level; - public final double experience; - public final Animation animation; - String(byte indicator, final int unfinished, final int product, final int level, final double experience, final Animation animation) { - this.unfinished = unfinished; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - switch(indicator & 0xFF){ - case 1: - this.string = org.rs09.consts.Items.BOW_STRING_1777; - break; - case 2: - this.string = org.rs09.consts.Items.CROSSBOW_STRING_9438; - break; - default: - break; - } - } - } - public enum GemBolts { - OPAL(877, org.rs09.consts.Items.OPAL_1609, 45, 879, 11, 1.6), - PEARL(9140, org.rs09.consts.Items.OYSTER_PEARL_411, 46, 880, 41, 3.2), - PEARLS(9140, org.rs09.consts.Items.OYSTER_PEARLS_413, 46, 880, 41, 3.2), - JADE(9139, org.rs09.consts.Items.JADE_1611, 9187, 9335, 26, 2.4), - RED_TOPAZ(9141, org.rs09.consts.Items.RED_TOPAZ_1613, 9188, 9336, 48, 3.9), - SAPPHIRE(9142, org.rs09.consts.Items.SAPPHIRE_1607, 9189, 9337, 56, 4.7), - EMERALD(9142, org.rs09.consts.Items.EMERALD_1605, 9190, 9338, 58, 5.5), - RUBY(9143, org.rs09.consts.Items.RUBY_1603, 9191, 9339, 63, 6.3), - DIAMOND(9143, org.rs09.consts.Items.DIAMOND_1601, 9192, 9340, 65, 7), - DRAGONSTONE(9144, org.rs09.consts.Items.DRAGONSTONE_1615, 9193, 9341, 71, 8.2), - ONYX(9144, org.rs09.consts.Items.ONYX_6573, 9194, 9342, 73, 9.4); - - public int gem,tip,base,product,level; - public double experience; - GemBolts(int base, int gem, int tip, int product, int level, double experience){ - this.gem = gem; - this.tip = tip; - this.base = base; - this.product = product; - this.level = level; - this.experience = experience; - } - - } - public enum ArrowHeads { - BRONZE_ARROW(39, 882, 1, 2.6), - IRON_ARROW(40, 884, 15, 3.8), - STEEL_ARROW(41, 886, 30, 6.3), - MITHRIL_ARROW(42, 888, 45, 8.8), - ADAMANT_ARROW(43, 890, 60, 11.3), - RUNE_ARROW(44, 892, 75, 13.8), - DRAGON_ARROW(11237, 11212, 90, 16.3), - BROAD_ARROW(13278, 4160, 52, 15); - - public int unfinished,finished,level; - public double experience; - ArrowHeads(int unfinished, int finished, int level, double experience){ - this.unfinished = unfinished; - this.finished = finished; - this.level = level; - this.experience = experience; - } - public Item getFinished(){ - return new Item(finished); - } - public Item getUnfinished(){ - return new Item(unfinished); - } - } - public enum Darts{ - BRONZE_DART(819, 806, 1, 1.8), - IRON_DART(820, 807, 22, 3.8), - STEEL_DART(821, 808, 37, 7.5), - MITHRIL_DART(822, 809, 52, 11.2), - ADAMANT_DART(823, 810, 67, 15), - RUNE_DART(824, 811, 81, 18.8), - DRAGON_DART(11232, 11230, 95, 25); - - public int unfinished, finished, level; - public double experience; - Darts(int unfinished, int finished, int level, double experience){ - this.unfinished = unfinished; - this.finished = finished; - this.level = level; - this.experience = experience; - } - public Item getFinished(){ - return new Item(finished); - } - public Item getUnfinished(){ - return new Item(unfinished); - } - } - public enum Bolts{ - BRONZE_BOLT(9375, 877, 9, 0.5), - BLURITE_BOLT(9376, 9139, 24, 1), - IRON_BOLT(9377, 9140, 39, 1.5), - SILVER_BOLT(9382, 9145, 43, 2.5), - STEEL_BOLT(9378, 9141, 46, 3.5), - MITHRIL_BOLT(9379, 9142, 54, 5), - ADAMANTITE_BOLT(9380, 9143, 61, 7), - RUNITE_BOLT(9381, 9144, 69, 10), - BROAD_BOLT(13279, 13280, 55, 3); - - public int unfinished, finished, level; - public double experience; - Bolts(int unfinished, int finished, int level, double experience){ - this.unfinished = unfinished; - this.finished = finished; - this.level = level; - this.experience = experience; - } - public Item getFinished(){ - return new Item(finished); - } - public Item getUnfinished(){ - return new Item(unfinished); - } - } - private enum Items{ - STANDARD(1511,FletchingItems.ARROW_SHAFT, FletchingItems.SHORT_BOW, FletchingItems.LONG_BOW, FletchingItems.WOODEN_STOCK), - ACHEY(2862, FletchingItems.OGRE_ARROW_SHAFT), - OAK(1521, FletchingItems.OAK_SHORTBOW, FletchingItems.OAK_LONGBOW, FletchingItems.OAK_STOCK), - WILLOW(1519, FletchingItems.WILLOW_SHORTBOW, FletchingItems.WILLOW_LONGBOW, FletchingItems.WILLOW_STOCK), - MAPLE(1517, FletchingItems.MAPLE_SHORTOW, FletchingItems.MAPLE_LONGBOW, FletchingItems.MAPLE_STOCK), - YEW(1515, FletchingItems.YEW_SHORTBOW, FletchingItems.YEW_LONGBOW, FletchingItems.YEW_STOCK), - MAGIC(1513, FletchingItems.MAGIC_SHORTBOW, FletchingItems.MAGIC_LONGBOW), - TEAK(6333, FletchingItems.TEAK_STOCK), - MAHOGANY(6332, FletchingItems.MAHOGANY_STOCK); - - - FletchingItems[] items; - int id; - Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3, FletchingItems item_4){ - items = new FletchingItems[] {item_1, item_2, item_3, item_4}; - this.id = id; - } - Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3){ - items = new FletchingItems[] {item_1, item_2, item_3}; - this.id = id; - } - Items(int id, FletchingItems item_1, FletchingItems item_2){ - items = new FletchingItems[] {item_1, item_2}; - this.id = id; - } - Items(int id, FletchingItems item_1){ - items = new FletchingItems[] {item_1}; - this.id = id; - } - } - public enum FletchingItems { - //Standard logs - ARROW_SHAFT(52, 5, 1, 15), - SHORT_BOW(50, 5, 5, 1), - LONG_BOW(48, 10, 10, 1), - WOODEN_STOCK(9440, 6, 9, 1), - - //Achey logs - OGRE_ARROW_SHAFT(2864, 6.4, 5, 4), - - //Oak logs - OAK_SHORTBOW(54, 16.5, 20, 1), - OAK_LONGBOW(56,25,25,1), - OAK_STOCK(9442, 16, 24, 1), - - //Willow logs - WILLOW_SHORTBOW(60, 33.3, 35, 1), - WILLOW_LONGBOW(58, 41.5, 40, 1), - WILLOW_STOCK(9444, 22, 39, 1), - - //Maple logs - MAPLE_SHORTOW(64, 50, 50, 1), - MAPLE_LONGBOW(62, 58.3, 55, 1), - MAPLE_STOCK(9448, 32, 54, 1), - - //Yew logs - YEW_SHORTBOW(68, 67.5, 65, 1), - YEW_LONGBOW(66, 75, 70, 1), - YEW_STOCK(9452, 50, 69, 1), - - //Magic logs - MAGIC_SHORTBOW(72, 83.3, 80,1), - MAGIC_LONGBOW(70, 91.5, 85, 1), - - //Teak - TEAK_STOCK(9446, 27, 46,1), - - //Mahogany - MAHOGANY_STOCK(9450, 41.0, 61, 1); - - - int id,level,amount,logId; - double experience; - FletchingItems(int id, double experience, int level, int amount){ - this.id = id; - this.level = level; - this.amount = amount; - this.experience = experience; - } - - public Item getItem(){ - return new Item(id); - } - } - -} diff --git a/Server/src/main/content/global/skill/fletching/FletchingListeners.kt b/Server/src/main/content/global/skill/fletching/FletchingListeners.kt deleted file mode 100644 index 54ac72b5d..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchingListeners.kt +++ /dev/null @@ -1,139 +0,0 @@ -package content.global.skill.fletching - -import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching -import content.global.skill.fletching.items.arrow.ArrowHeadPulse -import content.global.skill.fletching.items.arrow.HeadlessArrowPulse -import content.global.skill.fletching.items.bow.StringPulse -import content.global.skill.fletching.items.crossbow.LimbPulse -import core.game.node.item.Item -import core.net.packet.PacketRepository -import core.net.packet.context.ChildPositionContext -import core.net.packet.out.RepositionChild -import org.rs09.consts.Components -import org.rs09.consts.Items -import org.rs09.consts.Items.BLUE_FEATHER_10089 -import org.rs09.consts.Items.FEATHER_314 -import org.rs09.consts.Items.ORANGE_FEATHER_10091 -import org.rs09.consts.Items.RED_FEATHER_10088 -import org.rs09.consts.Items.STRIPY_FEATHER_10087 -import org.rs09.consts.Items.YELLOW_FEATHER_10090 -import core.game.dialogue.SkillDialogueHandler -import core.game.interaction.InteractionListener -import core.game.interaction.IntType - -class FletchingListeners : InteractionListener { - - val LIMBIDs = Fletching.Limb.values().map(Fletching.Limb::limb).toIntArray() - val STOCKIDs = Fletching.Limb.values().map(Fletching.Limb::stock).toIntArray() - val MITHRIL_BOLT = Items.MITHRIL_BOLTS_9142 - val MITH_GRAPPLE_TIP = Items.MITH_GRAPPLE_TIP_9416 - val ROPE = Items.ROPE_954 - val MITH_GRAPPLE = Items.MITH_GRAPPLE_9418 - val ROPE_GRAPPLE = Items.MITH_GRAPPLE_9419 - val ARROW_SHAFT = Items.ARROW_SHAFT_52 - val FLETCHED_SHAFT = Items.HEADLESS_ARROW_53 - val UNFINISHED_ARROWS = Fletching.ArrowHeads.values().map(Fletching.ArrowHeads::unfinished).toIntArray() - val FEATHERS = intArrayOf(FEATHER_314,STRIPY_FEATHER_10087,RED_FEATHER_10088,BLUE_FEATHER_10089,YELLOW_FEATHER_10090,ORANGE_FEATHER_10091) - val UNSTRUNG_BOWS = Fletching.String.values().map(Fletching.String::unfinished).toIntArray() - val STRINGS = intArrayOf(Items.BOW_STRING_1777,Items.CROSSBOW_STRING_9438) - - override fun defineListeners() { - - onUseWith(IntType.ITEM,STRINGS,*UNSTRUNG_BOWS){ player, string, bow -> - val enum = Fletching.stringMap[bow.id] ?: return@onUseWith false - if(enum.string != string.id){ - player.sendMessage("That's not the right kind of string for this.") - return@onUseWith true - } - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(enum.product)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(StringPulse(player, string.asItem(), enum, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(string.asItem()) - } - } - handler.open() - PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 215, 10)) - return@onUseWith true - } - - onUseWith(IntType.ITEM,ARROW_SHAFT,*FEATHERS){ player, shaft, feather -> - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLETCHED_SHAFT)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(HeadlessArrowPulse(player, shaft.asItem(), Item(feather.id), amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(FLETCHED_SHAFT) - } - } - handler.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM,FLETCHED_SHAFT,*UNFINISHED_ARROWS){ player, shaft, unfinished -> - val head = Fletching.arrowHeadMap[unfinished.id] ?: return@onUseWith false - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, head.getFinished()) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(ArrowHeadPulse(player, shaft.asItem(), head, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(head.getUnfinished()) - } - } - handler.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM,MITHRIL_BOLT,MITH_GRAPPLE_TIP){ player, bolt, tip -> - if(player.skills.getLevel(Skills.FLETCHING) < 59){ - player.sendMessage("You need a fletching level of 59 to make this.") - return@onUseWith true - } - if(player.inventory.remove(Item(MITHRIL_BOLT,1),tip.asItem())){ - player.inventory.add(Item(MITH_GRAPPLE)) - } - return@onUseWith true - } - - onUseWith(IntType.ITEM,ROPE,MITH_GRAPPLE){ player, rope, grapple -> - if(player.skills.getLevel(Skills.FLETCHING) < 59){ - player.sendMessage("You need a fletching level of 59 to make this.") - return@onUseWith true - } - if(player.inventory.remove(rope.asItem(),grapple.asItem())){ - player.inventory.add(Item(ROPE_GRAPPLE)) - } - return@onUseWith true - } - - onUseWith(IntType.ITEM,LIMBIDs,*STOCKIDs){ player, limb, stock -> - val limbEnum = Fletching.limbMap[stock.id] ?: return@onUseWith false - if(limbEnum.limb != limb.id){ - player.sendMessage("That's not the right limb to attach to that stock.") - return@onUseWith true - } - val handler: SkillDialogueHandler = object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(limbEnum.product)){ - override fun create(amount: Int, index: Int) { - player.pulseManager.run(LimbPulse(player, stock.asItem(), limbEnum, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(stock.asItem()) - } - } - handler.open() - PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10)) - return@onUseWith true - } - - } - -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/FletchingPlugin.java b/Server/src/main/content/global/skill/fletching/FletchingPlugin.java deleted file mode 100644 index 3ec122866..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchingPlugin.java +++ /dev/null @@ -1,131 +0,0 @@ -package content.global.skill.fletching; - -import content.global.skill.fletching.items.bolts.BoltPulse; -import content.global.skill.fletching.items.darts.DartPulse; -import org.rs09.consts.Items; -import core.game.dialogue.SkillDialogueHandler; -import core.game.dialogue.SkillDialogueHandler.SkillDialogue; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.net.packet.PacketRepository; -import core.net.packet.context.ChildPositionContext; -import core.net.packet.out.RepositionChild; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to open the fletching dialogue. - * @author Ceikry - */ -@Initializable -public class FletchingPlugin extends UseWithHandler { - - public FletchingPlugin() { - super(819,820,821,822,823,824,11232,9375,9376,9377,9382,9378,9379,9380,9381,13279,1511,1521,1519,1517,1515,1513,2862,6332,6333, Items.MAHOGANY_LOGS_6332); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - // Knife - addHandler(946, ITEM_TYPE, this); - - // Feathers plus colored feathers - addHandler(314, ITEM_TYPE,this); - addHandler(10087, ITEM_TYPE, this); - addHandler(10088, ITEM_TYPE, this); - addHandler(10089, ITEM_TYPE, this); - addHandler(10090, ITEM_TYPE, this); - addHandler(10091, ITEM_TYPE, this); - - return this; - } - - @Override - public boolean handle(final NodeUsageEvent event) { - final Player player = event.getPlayer(); - - //handle darts - if(Fletching.isDart(event.getUsedItem().getId())){ - final Fletching.Darts dart = Fletching.dartMap.get(event.getUsedItem().getId()); - SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, dart.getFinished()) { - @Override - public void create(final int amount, int index) { - player.getPulseManager().run(new DartPulse(player, event.getUsedItem(), dart, amount)); - } - @Override - public int getAll(int index) { - return player.getInventory().getAmount(event.getUsedItem()); - } - }; - handler.open(); - return true; - } - - //handle bolts - if(Fletching.isBolt(event.getUsedItem().getId()) || Fletching.isBolt(event.getUsedWith().getId())){ - // figure out which of the used items is a bolt, and which is potentially a feather - final Fletching.Bolts bolt - = Fletching.isBolt(event.getUsedItem().getId()) - ? Fletching.boltMap.get(event.getUsedItem().getId()) - : Fletching.boltMap.get(event.getUsedWith().getId()); - final int featherId - = Fletching.isBolt(event.getUsedItem().getId()) - ? event.getUsedWith().getId() - : event.getUsedItem().getId(); - final boolean hasFeather = (featherId == 314 || (featherId >= 10087 && featherId <= 10091)); - - if (hasFeather) { - SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, bolt.getFinished()) { - @Override - public void create(final int amount, int index) { - player.getPulseManager().run(new BoltPulse(player, event.getUsedItem(), bolt, new Item(featherId), amount)); - } - @Override - public int getAll(int index) { - return player.getInventory().getAmount(event.getUsedItem()); - } - }; - handler.open(); - return true; - } - return false; - } - - //handle logs - if(Fletching.isLog(event.getUsedItem().getId()) && event.getUsedWith().getId() == 946) { - final Item log = event.getUsedItem(); - Item[] items = Fletching.getItems(log.getId()); - SkillDialogue dialLength = SkillDialogue.ONE_OPTION; - switch (items.length) { - case 2: - dialLength = SkillDialogue.TWO_OPTION; - break; - case 3: - dialLength = SkillDialogue.THREE_OPTION; - break; - case 4: - dialLength = SkillDialogue.FOUR_OPTION; - break; - } - SkillDialogueHandler handler = new SkillDialogueHandler(player, dialLength, items) { - - @Override - public void create(final int amount, int index) { - final Fletching.FletchingItems item = Fletching.getEntries(log.getId())[index]; - player.getPulseManager().run(new FletchingPulse(player, log, amount, item)); - } - - @Override - public int getAll(int index) { - return player.getInventory().getAmount(log); - } - - }; - handler.open(); - return true; - } - return false; - } -} diff --git a/Server/src/main/content/global/skill/fletching/FletchingPulse.java b/Server/src/main/content/global/skill/fletching/FletchingPulse.java deleted file mode 100644 index 9c7d0d638..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchingPulse.java +++ /dev/null @@ -1,117 +0,0 @@ -package content.global.skill.fletching; - -import core.tools.RandomFunction; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.world.map.zone.ZoneBorders; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; -import core.tools.StringUtils; - -/** - * fletching skill pulse - * @author ceik - */ -public final class FletchingPulse extends SkillPulse { - - /** - * Seers bank zone borders for the diary task - */ - private static final ZoneBorders bankZone = new ZoneBorders(2721,3493,2730,3487); - - /** - * Represents the animation used in this generic pulse. - */ - private static final Animation ANIMATION = new Animation(1248); - - /** - * Represents the item we are fletching. - */ - private Fletching.FletchingItems fletch; - - /** - * Represents the amount to fletch. - */ - private int amount = 0; - - /** - * Constructs a new {@code FletchingPulse.java} {@code Object}. - * @param player - * @param node - */ - public FletchingPulse(final Player player, final Item node, final int amount, final Fletching.FletchingItems fletch) { - super(player, node); - this.amount = amount; - this.fletch = fletch; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < fletch.level) { - player.getDialogueInterpreter().sendDialogue("You need a Fletching skill of " + fletch.level + " or above to make " + (StringUtils.isPlusN(fletch.getItem().getName().replace("(u)", "").trim()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim()); - return false; - } - if (amount > player.getInventory().getAmount(node)) { - amount = player.getInventory().getAmount(node); - } - if (fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT) { - if (player.getQuestRepository().getQuest("Big Chompy Bird Hunting").getStage(player) == 0) { - player.getPacketDispatch().sendMessage("You must have started Big Chompy Bird Hunting to make those."); - return false; - } - } - return true; - } - - @Override - public void animate() { - player.animate(ANIMATION); - } - - @Override - public boolean reward() { - if(bankZone.insideBorder(player) && fletch == Fletching.FletchingItems.MAGIC_SHORTBOW) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2); - } - if (getDelay() == 1) { - super.setDelay(4); - return false; - } - if (player.getInventory().remove(node)) { - final Item item = new Item(fletch.id,fletch.amount); - if ( fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT ) { - item.setAmount(RandomFunction.random(3,6)); - } - player.getInventory().add(item); - player.getSkills().addExperience(Skills.FLETCHING, fletch.experience, true); - String message = getMessage(); - player.getPacketDispatch().sendMessage(message); - - if (fletch.id == Fletching.FletchingItems.MAGIC_SHORTBOW.id - && (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player) - || new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player)) - && !player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 2)) { - player.setAttribute("/save:diary:seers:fletch-magic-short-bow", true); - } - } else { - return true; - } - amount--; - return amount == 0; - } - - /** - * Method used to get the message of the fletch. - * @return the message. - */ - public String getMessage() { - switch (fletch) { - case ARROW_SHAFT: - return "You carefully cut the wood into 15 arrow shafts."; - default: - return "You carefully cut the wood into " + (StringUtils.isPlusN(fletch.getItem().getName()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim() + "."; - } - } -} diff --git a/Server/src/main/content/global/skill/fletching/GemBoltListener.kt b/Server/src/main/content/global/skill/fletching/GemBoltListener.kt deleted file mode 100644 index 94c09c65b..000000000 --- a/Server/src/main/content/global/skill/fletching/GemBoltListener.kt +++ /dev/null @@ -1,69 +0,0 @@ -package content.global.skill.fletching - -import content.global.skill.fletching.Fletching.GemBolts -import content.global.skill.fletching.items.gem.GemBoltCutPulse -import content.global.skill.fletching.items.gem.GemBoltPulse -import core.api.amountInInventory -import core.game.dialogue.SkillDialogueHandler -import core.game.interaction.IntType -import core.game.interaction.InteractionListener -import core.game.node.item.Item -import core.net.packet.PacketRepository -import core.net.packet.context.ChildPositionContext -import core.net.packet.out.RepositionChild -import org.rs09.consts.Items -import kotlin.math.min - -class GemBoltListener : InteractionListener { - val gems = intArrayOf( - Items.OYSTER_PEARL_411, - Items.OYSTER_PEARLS_413, - Items.OPAL_1609, - Items.JADE_1611, - Items.RED_TOPAZ_1613, - Items.SAPPHIRE_1607, - Items.EMERALD_1605, - Items.RUBY_1603, - Items.DIAMOND_1601, - Items.DRAGONSTONE_1615, - Items.ONYX_6573 - ) - val boltBases = GemBolts.values().map { it.base }.toIntArray() - val boltTips = GemBolts.values().map { it.tip }.toIntArray() - - override fun defineListeners() { - onUseWith(IntType.ITEM, Items.CHISEL_1755, *gems) { player, used, with -> - val gem = Fletching.gemMap[with.id] ?: return@onUseWith true - - object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(gem.gem)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(GemBoltCutPulse(player, used as? Item, gem, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(gem.gem) - } - }.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM, boltBases, *boltTips) {player, used, with -> - val bolt = Fletching.tipMap[with.id] ?: return@onUseWith true - if (used.id != bolt.base || with.id != bolt.tip) return@onUseWith true - - - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.product)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(GemBoltPulse(player, used as? Item, bolt, amount)) - } - - override fun getAll(index: Int): Int { - return min(amountInInventory(player, used.id), amountInInventory(player, with.id)) - } - } - handler.open() - return@onUseWith true - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/Zones.kt b/Server/src/main/content/global/skill/fletching/Zones.kt new file mode 100644 index 000000000..8c10f0c4f --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/Zones.kt @@ -0,0 +1,21 @@ +package content.global.skill.fletching + +import core.game.node.Node +import core.game.world.map.zone.ZoneBorders + +object Zones { + val seersMagicShortbowAchievementZones = arrayOf( + ZoneBorders(2721, 3489, 2724, 3493, 0), + ZoneBorders(2727, 3487, 2730, 3490, 0), + ZoneBorders(2721, 3493, 2730, 3487) + ) + + fun inAnyZone(node: Node, zones: Array): Boolean { + for (zone in zones) { + if (zone.insideBorder(node)) { + return true + } + } + return false + } +} diff --git a/Server/src/main/content/global/skill/fletching/arrow/ArrowCraftInfo.kt b/Server/src/main/content/global/skill/fletching/arrow/ArrowCraftInfo.kt new file mode 100644 index 000000000..087c688a9 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/ArrowCraftInfo.kt @@ -0,0 +1,24 @@ +package content.global.skill.fletching.arrow + +import org.rs09.consts.Items + +enum class ArrowCraftInfo(val tipItemId: Int, val arrowItemId: Int, val level: Int, val experience: Double) { + BRONZE_ARROW(Items.BRONZE_ARROWTIPS_39, Items.BRONZE_ARROW_882, 1, 1.3), + IRON_ARROW(Items.IRON_ARROWTIPS_40, Items.IRON_ARROW_884, 15, 2.5), + STEEL_ARROW(Items.STEEL_ARROWTIPS_41, Items.STEEL_ARROW_886, 30, 5.0), + MITHRIL_ARROW(Items.MITHRIL_ARROWTIPS_42, Items.MITHRIL_ARROW_888, 45, 7.5), + ADAMANT_ARROW(Items.ADAMANT_ARROWTIPS_43, Items.ADAMANT_ARROW_890, 60, 10.0), + RUNE_ARROW(Items.RUNE_ARROWTIPS_44, Items.RUNE_ARROW_892, 75, 12.5), + DRAGON_ARROW(Items.DRAGON_ARROWTIPS_11237,Items.DRAGON_ARROW_11212, 90, 15.0), + BROAD_ARROW(Items.BROAD_ARROW_HEADS_13278, Items.BROAD_ARROW_4160, 52, 15.0); + + companion object { + private val arrowCraftInfoByTipId = values().associateBy { it.tipItemId } + + val arrowTipIds: IntArray = values().map { arrowCraftInfo: ArrowCraftInfo -> arrowCraftInfo.tipItemId }.toIntArray() + + fun fromTipId(tipId: Int) : ArrowCraftInfo? { + return arrowCraftInfoByTipId[tipId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/ArrowListeners.kt b/Server/src/main/content/global/skill/fletching/arrow/ArrowListeners.kt new file mode 100644 index 000000000..2c061b3cb --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/ArrowListeners.kt @@ -0,0 +1,112 @@ +package content.global.skill.fletching.arrow + +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +@Suppress("unused") // Reflectively loaded +class ArrowListeners : InteractionListener { + private val arrowShaft = Items.ARROW_SHAFT_52 + val headlessArrow = Items.HEADLESS_ARROW_53 + + companion object { + const val FLIGHTED_OGRE_ARROW_LEVEL = 5 + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level to do this." + ) + } + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, arrowShaft, *Feathers.all) { player, shaft, feather -> + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(headlessArrow)) { + override fun create(amount: Int, index: Int) { + if (!hasSpaceFor(player, Item(headlessArrow))) { + sendDialogue(player, "You do not have enough inventory space.") + return + } + HeadlessArrowCraftScript(player, feather.id, amount).invoke() + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, headlessArrow) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM, headlessArrow, *ArrowCraftInfo.arrowTipIds) { player, headlessArrow, arrowTip -> + val arrowCraftInfo = ArrowCraftInfo.fromTipId(arrowTip.id) ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(arrowCraftInfo.arrowItemId)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + TippedArrowCraftScript(player, arrowCraftInfo, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (arrowCraftInfo == ArrowCraftInfo.BROAD_ARROW && !getSlayerFlags(player).isBroadsUnlocked()) { + sendDialogue(player, "You need to unlock the ability to create broad arrows.") + return false + } + + if (getDynLevel(player, Skills.FLETCHING) < arrowCraftInfo.level) { + sendLevelCheckFailDialog(player, arrowCraftInfo.level) + return false + } + + if (!hasSpaceFor(player, Item(arrowCraftInfo.arrowItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, arrowTip.id) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.OGRE_ARROW_SHAFT_2864, *Feathers.all) { player, ogreArrowShaft, feather -> + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(Items.FLIGHTED_OGRE_ARROW_2865)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + FlightedOgreArrowCraftScript(player, feather.id, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < FLIGHTED_OGRE_ARROW_LEVEL) { + sendLevelCheckFailDialog(player, FLIGHTED_OGRE_ARROW_LEVEL) + return false + } + + if (!hasSpaceFor(player, Item(Items.FLIGHTED_OGRE_ARROW_2865))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, Items.OGRE_ARROW_SHAFT_2864) + } + } + handler.open() + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/FlightedOgreArrowCraftScript.kt b/Server/src/main/content/global/skill/fletching/arrow/FlightedOgreArrowCraftScript.kt new file mode 100644 index 000000000..126b72aee --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/FlightedOgreArrowCraftScript.kt @@ -0,0 +1,88 @@ +package content.global.skill.fletching.arrow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +/** + * Defines the queueScript for creating a flighted ogre arrow + * @author 'Vexia + * @param player the player. + * @param idOfFeatherUsed the feather to attach to the shaft. + * @param sets the amount of sets to complete. + */ +class FlightedOgreArrowCraftScript( + private val player: Player, + private val idOfFeatherUsed: Int, + private val sets: Int +) { + + private val flightedOgreArrow = Items.FLIGHTED_OGRE_ARROW_2865 + private val ogreArrowShaft = Items.OGRE_ARROW_SHAFT_2864 + private val maximumFlightedOgreArrowsCraftableInOneStage = 6 + + private val feathersPerArrow = 4 + + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisStage(shaftsInInventory: Int, feathersInInventory: Int): Int { + val limitOfCraftableArrowsDueToFeathers = feathersInInventory / feathersPerArrow + + val totalCraftableArrows = min(shaftsInInventory, limitOfCraftableArrowsDueToFeathers) + return if (totalCraftableArrows > maximumFlightedOgreArrowsCraftableInOneStage) { + maximumFlightedOgreArrowsCraftableInOneStage + } else { + totalCraftableArrows + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < ArrowListeners.FLIGHTED_OGRE_ARROW_LEVEL) { + ArrowListeners.sendLevelCheckFailDialog(player, ArrowListeners.FLIGHTED_OGRE_ARROW_LEVEL) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val featherAmount = amountInInventory(player, idOfFeatherUsed) + val shaftAmount = amountInInventory(player, ogreArrowShaft) + + val amountToCraft = getAmountToCraftForThisStage(shaftAmount, featherAmount) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(ogreArrowShaft, amountToCraft), + Item(idOfFeatherUsed, amountToCraft * feathersPerArrow) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach $feathersPerArrow feathers to a shaft.") + else -> { + sendMessage( + player, + "You attach ${amountToCraft * feathersPerArrow} feathers to $amountToCraft arrow shafts." + ) + } + } + + rewardXP(player, Skills.FLETCHING, amountToCraft.toDouble()) + addItem(player, flightedOgreArrow, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/HeadlessArrowCraftScript.kt b/Server/src/main/content/global/skill/fletching/arrow/HeadlessArrowCraftScript.kt new file mode 100644 index 000000000..40ef4c235 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/HeadlessArrowCraftScript.kt @@ -0,0 +1,76 @@ +package content.global.skill.fletching.arrow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +/** + * Defines the queueScript for creating a headless arrow + * @author 'Vexia + * @param player the player. + * @param idOfFeatherUsed the feather to attach to the shaft. + * @param sets the amount of sets to complete. + */ +class HeadlessArrowCraftScript( + private val player: Player, + private val idOfFeatherUsed: Int, + private val sets: Int +) { + + private val headlessArrow = Items.HEADLESS_ARROW_53 + private val arrowShaft = Items.ARROW_SHAFT_52 + private val maximumHeadlessArrowsCraftableInOneStage = 15 + + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisStage(shaftsInInventory: Int, feathersInInventory: Int): Int { + val smallerItemAmount = min(shaftsInInventory, feathersInInventory) + return if (smallerItemAmount > maximumHeadlessArrowsCraftableInOneStage) { + maximumHeadlessArrowsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + val featherAmount = amountInInventory(player, idOfFeatherUsed) + val shaftAmount = amountInInventory(player, arrowShaft) + + val amountToCraft = getAmountToCraftForThisStage(shaftAmount, featherAmount) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(arrowShaft, amountToCraft), + Item(idOfFeatherUsed, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach a feather to a shaft.") + else -> { + sendMessage(player, "You attach feathers to $amountToCraft arrow shafts.") + } + } + + rewardXP(player, Skills.FLETCHING, amountToCraft.toDouble()) + addItem(player, headlessArrow, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/TippedArrowCraftScript.kt b/Server/src/main/content/global/skill/fletching/arrow/TippedArrowCraftScript.kt new file mode 100644 index 000000000..d4249b660 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/TippedArrowCraftScript.kt @@ -0,0 +1,79 @@ +package content.global.skill.fletching.arrow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +/** + * Represents the arrow head pulse to complete the headless arrow. + * @author 'Vexia + * @param player the player. + * @param arrowCraftInfo provides information about the arrow we're crafting. + * @param sets the amount of sets to complete. + */ +class TippedArrowCraftScript( + private val player: Player, + private val arrowCraftInfo: ArrowCraftInfo, + private val sets: Int +) { + + private val headlessArrow = Items.HEADLESS_ARROW_53 + private val maximumArrowsCraftableInOneStage = 15 + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisStage(headlessArrowsInInventory: Int, tipsInInventory: Int): Int { + val smallerItemAmount = min(headlessArrowsInInventory, tipsInInventory) + return if (smallerItemAmount > maximumArrowsCraftableInOneStage) { + maximumArrowsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < arrowCraftInfo.level) { + ArrowListeners.sendLevelCheckFailDialog(player, arrowCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val tipsInInventory = amountInInventory(player, arrowCraftInfo.tipItemId) + val headlessArrowsInInventory = amountInInventory(player, headlessArrow) + + val amountToCraft = getAmountToCraftForThisStage(headlessArrowsInInventory, tipsInInventory) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(headlessArrow, amountToCraft), + Item(arrowCraftInfo.tipItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach an arrow head to an arrow shaft.") + else -> { + sendMessage(player, "You attach arrow heads to $amountToCraft arrow shafts.") + } + } + + rewardXP(player, Skills.FLETCHING, arrowCraftInfo.experience * amountToCraft) + addItem(player, arrowCraftInfo.arrowItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/bolts/BoltCraftInfo.kt b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftInfo.kt new file mode 100644 index 000000000..497332a59 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftInfo.kt @@ -0,0 +1,39 @@ +package content.global.skill.fletching.bolts + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different bolts + * @property unfinishedBoltItemId the unfinished bolt (unf) Item id used to craft the dart. + * @property finishedItemId the resulting finished bolt Item id. + * @property level the level required to craft. + * @property experience the experience gained by crafting. + */ +enum class BoltCraftInfo( + val unfinishedBoltItemId: Int, + val finishedItemId: Int, + val level: Int, + val experience: Double +) { + BRONZE_BOLT(Items.BRONZE_BOLTS_UNF_9375, Items.BRONZE_BOLTS_877, 9, 0.5), + BLURITE_BOLT(Items.BLURITE_BOLTS_UNF_9376, Items.BLURITE_BOLTS_9139, 24, 1.0), + IRON_BOLT(Items.IRON_BOLTS_UNF_9377, Items.IRON_BOLTS_9140, 39, 1.5), + SILVER_BOLT(Items.SILVER_BOLTS_UNF_9382, Items.SILVER_BOLTS_9145, 43, 2.5), + STEEL_BOLT(Items.STEEL_BOLTS_UNF_9378, Items.STEEL_BOLTS_9141, 46, 3.5), + MITHRIL_BOLT(Items.MITHRIL_BOLTS_UNF_9379, Items.MITHRIL_BOLTS_9142, 54, 5.0), + ADAMANTITE_BOLT(Items.ADAMANT_BOLTSUNF_9380, Items.ADAMANT_BOLTS_9143, 61, 7.0), + RUNITE_BOLT(Items.RUNITE_BOLTS_UNF_9381, Items.RUNE_BOLTS_9144, 69, 10.0), + BROAD_BOLT(Items.UNFINISHED_BROAD_BOLTS_13279, Items.BROAD_TIPPED_BOLTS_13280, 55, 3.0); + + companion object { + private val boltCraftInfoByUnfinishedBoltIds = values().associateBy { it.unfinishedBoltItemId } + + val unfinishedBoltIds: IntArray = BoltCraftInfo.values() + .map { unfinishedBoltToBoltMapping: BoltCraftInfo -> unfinishedBoltToBoltMapping.unfinishedBoltItemId } + .toIntArray() + + fun fromUnfinishedBoltId(unfinishedBoltId: Int): BoltCraftInfo? { + return boltCraftInfoByUnfinishedBoltIds[unfinishedBoltId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/bolts/BoltCraftScript.kt b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftScript.kt new file mode 100644 index 000000000..e525e7055 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftScript.kt @@ -0,0 +1,79 @@ +package content.global.skill.fletching.bolts + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +/** + * Represents the bolt pulse class to make bolts. + * @author ceik + * @param player the player. + * @param boltCraftInfo contains information about what bolt we're crafting + * @param feather the feather we're using to craft + * @param sets the amount of sets to craft + */ +class BoltCraftScript( + private val player: Player, + private val boltCraftInfo: BoltCraftInfo, + private val feather: Item, + private val sets: Int +) { + + private val maximumBoltsCraftableInOneStage = 10 + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisSet(feathersInInventory: Int, unfinishedBoltsInInventory: Int): Int { + val smallerItemAmount = min(feathersInInventory, unfinishedBoltsInInventory) + return if (smallerItemAmount > maximumBoltsCraftableInOneStage) { + maximumBoltsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < boltCraftInfo.level) { + BoltListeners.sendLevelCheckFailDialog(player, boltCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val featherAmount = amountInInventory(player, feather.id) + val unfinishedBoltAmount = amountInInventory(player, boltCraftInfo.unfinishedBoltItemId) + + val amountToCraft = getAmountToCraftForThisSet(featherAmount, unfinishedBoltAmount) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(feather.id, amountToCraft), + Item(boltCraftInfo.unfinishedBoltItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach a feather to a bolt.") + else -> { + sendMessage(player, "You fletch $amountToCraft bolts") + } + } + + rewardXP(player, Skills.FLETCHING, boltCraftInfo.experience * amountToCraft) + addItem(player, boltCraftInfo.finishedItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/bolts/BoltListeners.kt b/Server/src/main/content/global/skill/fletching/bolts/BoltListeners.kt new file mode 100644 index 000000000..ad9d806d8 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/bolts/BoltListeners.kt @@ -0,0 +1,65 @@ +package content.global.skill.fletching.bolts + +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +@Suppress("unused") // Reflectively loaded +class BoltListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Feathers.all, *BoltCraftInfo.unfinishedBoltIds) { player, feather, unfinishedBolt -> + val boltCraftInfo = BoltCraftInfo.fromUnfinishedBoltId(unfinishedBolt.id) ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : SkillDialogueHandler( + player, + SkillDialogue.MAKE_SET_ONE_OPTION, + Item(boltCraftInfo.finishedItemId) + ) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + BoltCraftScript(player, boltCraftInfo, feather.asItem(), amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (boltCraftInfo == BoltCraftInfo.BROAD_BOLT && !getSlayerFlags(player).isBroadsUnlocked()) { + sendDialogue(player, "You need to unlock the ability to create broad bolts.") + return false + } + if (getDynLevel(player, Skills.FLETCHING) < boltCraftInfo.level) { + sendLevelCheckFailDialog(player, boltCraftInfo.level) + return false + } + if (!hasSpaceFor(player, Item(boltCraftInfo.finishedItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + + return true + } + + override fun getAll(index: Int): Int { + return min( + amountInInventory(player, feather.id), + amountInInventory(player, unfinishedBolt.id) + ) + } + } + handler.open() + return@onUseWith true + } + } + companion object { + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level in order to do this." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/crossbow/LimbingListener.kt b/Server/src/main/content/global/skill/fletching/crossbow/LimbingListener.kt new file mode 100644 index 000000000..0876d54c1 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/crossbow/LimbingListener.kt @@ -0,0 +1,80 @@ +package content.global.skill.fletching.crossbow + +import core.api.getDynLevel +import core.api.hasSpaceFor +import core.api.sendDialogue +import core.api.sendMessage +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Components + +@Suppress("unused") // Reflectively loaded +class LimbingListener : InteractionListener { + override fun defineListeners() { + onUseWith( + IntType.ITEM, + UnfinishedCrossbowCraftInfo.limbIds, + *UnfinishedCrossbowCraftInfo.stockIds + ) { player, limb, stock -> + val unfinishedCrossbowCraftInfo = UnfinishedCrossbowCraftInfo.forStockId(stock.id) ?: return@onUseWith false + if (unfinishedCrossbowCraftInfo.limbItemId != limb.id) { + sendMessage(player, "That's not the right limb to attach to that stock.") + return@onUseWith true + } + val handler: SkillDialogueHandler = object : SkillDialogueHandler( + player, + SkillDialogue.ONE_OPTION, + Item(unfinishedCrossbowCraftInfo.unstrungCrossbowItemId) + ) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + LimbingScript(player, unfinishedCrossbowCraftInfo, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < unfinishedCrossbowCraftInfo.level) { + sendLevelCheckFailDialog(player, unfinishedCrossbowCraftInfo.level) + return false + } + if (!hasSpaceFor(player, Item(unfinishedCrossbowCraftInfo.unstrungCrossbowItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + + return true + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(stock.asItem()) + } + } + handler.open() + fixTextOverlappingTheCrossbowIcon(player) + return@onUseWith true + } + } + + + private fun fixTextOverlappingTheCrossbowIcon(player: Player) { + PacketRepository.send( + RepositionChild::class.java, + ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10) + ) + } + + companion object { + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level to attach these limbs." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/crossbow/LimbingScript.kt b/Server/src/main/content/global/skill/fletching/crossbow/LimbingScript.kt new file mode 100644 index 000000000..07fb8ac43 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/crossbow/LimbingScript.kt @@ -0,0 +1,56 @@ +package content.global.skill.fletching.crossbow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * The queue script for attaching limbs. + * @author Ceikry + * @param player The player + * @param unfinishedCrossbowCraftInfo info about the unfinished (unstrung) crossbow we're crafting + * @param amount to create + */ +class LimbingScript( + private val player: Player, + private val unfinishedCrossbowCraftInfo: UnfinishedCrossbowCraftInfo, + private val amount: Int +) { + + private val initialDelay = 1 + private val subsequentDelay = 6 + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < unfinishedCrossbowCraftInfo.level) { + LimbingListener.sendLevelCheckFailDialog(player, unfinishedCrossbowCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(unfinishedCrossbowCraftInfo.stockItemId), + Item(unfinishedCrossbowCraftInfo.limbItemId) + ) + ) { + addItem(player, unfinishedCrossbowCraftInfo.unstrungCrossbowItemId, 1) + rewardXP(player, Skills.FLETCHING, unfinishedCrossbowCraftInfo.experience) + sendMessage(player, "You attach the metal limbs to the stock.") + animate(player, unfinishedCrossbowCraftInfo.animation) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/crossbow/UnfinishedCrossbowCraftInfo.kt b/Server/src/main/content/global/skill/fletching/crossbow/UnfinishedCrossbowCraftInfo.kt new file mode 100644 index 000000000..7250b02e4 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/crossbow/UnfinishedCrossbowCraftInfo.kt @@ -0,0 +1,55 @@ +package content.global.skill.fletching.crossbow + +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different unfinished (unstrung) crossbows + * @author 'Vexia + * @param stockItemId item id of the stock. + * @param limbItemId item id of the limb. + * @param unstrungCrossbowItemId item id of the product. + * @param level the level. + * @param experience the experience. + * @param animation the animation. + */ +enum class UnfinishedCrossbowCraftInfo + ( + val stockItemId: Int, + val limbItemId: Int, + val unstrungCrossbowItemId: Int, + val level: Int, + val experience: Double, + val animation: Animation +) { + WOODEN_STOCK(Items.WOODEN_STOCK_9440, Items.BRONZE_LIMBS_9420, Items.BRONZE_CBOW_U_9454, 9, 12.0, Animation(4436)), + OAK_STOCK(Items.OAK_STOCK_9442, Items.BLURITE_LIMBS_9422, Items.BLURITE_CROSSBOW_9176, 24, 32.0, Animation(4437)), + WILLOW_STOCK(Items.WILLOW_STOCK_9444, Items.IRON_LIMBS_9423, Items.IRON_CBOW_U_9457, 39, 44.0, Animation(4438)), + TEAK_STOCK(Items.TEAK_STOCK_9446, Items.STEEL_LIMBS_9425, Items.STEEL_CBOW_U_9459, 46, 54.0, Animation(4439)), + MAPLE_STOCK(Items.MAPLE_STOCK_9448, Items.MITHRIL_LIMBS_9427, Items.MITHRIL_CBOW_U_9461, 54, 64.0, Animation(4440)), + MAHOGANY_STOCK( + Items.MAHOGANY_STOCK_9450, + Items.ADAMANTITE_LIMBS_9429, + Items.ADAMANT_CBOW_U_9463, + 61, + 82.0, + Animation(4441) + ), + YEW_STOCK(Items.YEW_STOCK_9452, Items.RUNITE_LIMBS_9431, Items.RUNITE_CBOW_U_9465, 69, 100.0, Animation(4442)); + + companion object { + private val unfinishedCrossbowCraftInfoByStockId = values().associateBy { it.stockItemId } + + val limbIds: IntArray = + values().map { unfinishedCrossbowCraftInfo: UnfinishedCrossbowCraftInfo -> unfinishedCrossbowCraftInfo.limbItemId } + .toIntArray() + + val stockIds: IntArray = + values().map { unfinishedCrossbowCraftInfo: UnfinishedCrossbowCraftInfo -> unfinishedCrossbowCraftInfo.stockItemId } + .toIntArray() + + fun forStockId(stockId: Int): UnfinishedCrossbowCraftInfo? { + return unfinishedCrossbowCraftInfoByStockId[stockId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/darts/DartCraftInfo.kt b/Server/src/main/content/global/skill/fletching/darts/DartCraftInfo.kt new file mode 100644 index 000000000..488075b80 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/darts/DartCraftInfo.kt @@ -0,0 +1,36 @@ +package content.global.skill.fletching.darts + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different darts + * @author 'Vexia + * @property tipItemId the tip Item id used to craft the dart. + * @property dartItemId the resulting dart Item id. + * @property level the level required to craft. + * @property experience the experience gained by crafting. + */ +enum class DartCraftInfo( + val tipItemId: Int, + val dartItemId: Int, + val level: Int, + val experience: Double) { + + BRONZE_DART(Items.BRONZE_DART_TIP_819, Items.BRONZE_DART_806, 1, 1.8), + IRON_DART(Items.IRON_DART_TIP_820, Items.IRON_DART_807, 22, 3.8), + STEEL_DART(Items.STEEL_DART_TIP_821, Items.STEEL_DART_808, 37, 7.5), + MITHRIL_DART(Items.MITHRIL_DART_TIP_822, Items.MITHRIL_DART_809, 52, 11.2), + ADAMANT_DART(Items.ADAMANT_DART_TIP_823, Items.ADAMANT_DART_810, 67, 15.0), + RUNE_DART(Items.RUNE_DART_TIP_824, Items.RUNE_DART_811, 81, 18.8), + DRAGON_DART(Items.DRAGON_DART_TIP_11232, Items.DRAGON_DART_11230, 95, 25.0); + + companion object { + private val dartCraftInfoByTipIds = values().associateBy { it.tipItemId } + + val tipIDs: IntArray = values().map { dartCraftInfo: DartCraftInfo -> dartCraftInfo.tipItemId }.toIntArray() + + fun fromTipID(dartTipId: Int): DartCraftInfo? { + return dartCraftInfoByTipIds[dartTipId] + } + } +} diff --git a/Server/src/main/content/global/skill/fletching/darts/DartCraftScript.kt b/Server/src/main/content/global/skill/fletching/darts/DartCraftScript.kt new file mode 100644 index 000000000..baecff08c --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/darts/DartCraftScript.kt @@ -0,0 +1,78 @@ +package content.global.skill.fletching.darts + +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +/** + * Represents the queueScript to craft a dart. + * @author ceikry + * @param player the player. + * @param dartCraftInfo contains info about the dart we're crafting. + * @param sets count of sets to make + */ +class DartCraftScript( + private val player: Player, + private val dartCraftInfo: DartCraftInfo, + private var sets: Int +) { + + private val initialDelay = 1 + private val subsequentDelay = 3 + private val maximumDartsCraftableInOneStage = 10 + + private fun getAmountToCraftForThisStage(feathersInInventory: Int, dartTipsInInventory: Int): Int { + val smallerItemAmount = min(feathersInInventory, dartTipsInInventory) + return if (smallerItemAmount > maximumDartsCraftableInOneStage) { + maximumDartsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < dartCraftInfo.level) { + DartListeners.sendLevelCheckFailDialog(player, dartCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val dartTipsInInventory = amountInInventory(player, dartCraftInfo.tipItemId) + val feathersInInventory = amountInInventory(player, Feathers.STANDARD) + + val amountToCraft = getAmountToCraftForThisStage(feathersInInventory, dartTipsInInventory) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(Feathers.STANDARD, amountToCraft), + Item(dartCraftInfo.tipItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach a feather to a dart.") + else -> { + sendMessage(player, "You attach feathers to $amountToCraft darts.") + } + } + + rewardXP(player, Skills.FLETCHING, dartCraftInfo.experience * amountToCraft) + addItem(player, dartCraftInfo.dartItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/darts/DartListeners.kt b/Server/src/main/content/global/skill/fletching/darts/DartListeners.kt new file mode 100644 index 000000000..93b96d2ab --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/darts/DartListeners.kt @@ -0,0 +1,59 @@ +package content.global.skill.fletching.darts + +import content.data.Quests +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +@Suppress("unused") // Reflectively loaded +class DartListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Feathers.STANDARD, *DartCraftInfo.tipIDs) { player, feather, dartTip -> + val dartCraftInfo = DartCraftInfo.fromTipID(dartTip.id) ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : + SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(dartCraftInfo.dartItemId)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + DartCraftScript(player, dartCraftInfo, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < dartCraftInfo.level) { + sendLevelCheckFailDialog(player, dartCraftInfo.level) + return false + } + if (!isQuestComplete(player, Quests.THE_TOURIST_TRAP)) { + sendDialogue(player, "You need to have completed Tourist Trap to fletch darts.") + return false + } + if (!hasSpaceFor(player, Item(dartCraftInfo.dartItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return min( + amountInInventory(player, feather.id), + amountInInventory(player, dartTip.id) + ) + } + } + handler.open() + return@onUseWith true + } + } + companion object { + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue(player, "You need a fletching level of $level to do this.") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/AttachGemTipToBoltScript.kt b/Server/src/main/content/global/skill/fletching/gem/AttachGemTipToBoltScript.kt new file mode 100644 index 000000000..c6b1cfdfd --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/AttachGemTipToBoltScript.kt @@ -0,0 +1,77 @@ +package content.global.skill.fletching.gem + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +/** + * Represents the attaching of a gem tip to a premade bolt. + * @author Ceikry + * @param player the player. + * @param gemBoltCraftInfo crafting info for adding the gem to the bolt + * @param sets the number of sets to craft. + */ +class AttachGemTipToBoltScript( + private val player: Player, + private val gemBoltCraftInfo: GemBoltsCraftInfo, + private val sets: Int +) { + + private val initialDelay = 1 + private val subsequentDelay = 3 + private val maximumGemBoltsCraftableInOneStage = 10 + + private fun getAmountToCraftForThisPulse(untippedBoltsInInventory: Int, tipsInInventory: Int): Int { + val smallerItemAmount = min(untippedBoltsInInventory, tipsInInventory) + return if (smallerItemAmount > maximumGemBoltsCraftableInOneStage) { + maximumGemBoltsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < gemBoltCraftInfo.level) { + GemBoltListeners.sendGemTipAttachLevelCheckFailDialog(player, gemBoltCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val untippedBoltsInInventory = amountInInventory(player, gemBoltCraftInfo.untippedBoltItemId) + val tipsInInventory = amountInInventory(player, gemBoltCraftInfo.tipItemId) + + val amountToCraft = getAmountToCraftForThisPulse(untippedBoltsInInventory, tipsInInventory) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(gemBoltCraftInfo.untippedBoltItemId, amountToCraft), + Item(gemBoltCraftInfo.tipItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach the tip to the bolt.") + else -> { + sendMessage(player, "You fletch $amountToCraft bolts.") + } + } + + rewardXP(player, Skills.FLETCHING, gemBoltCraftInfo.experience * amountToCraft) + addItem(player, gemBoltCraftInfo.tippedBoltItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/CutGemsIntoBoltTipsScript.kt b/Server/src/main/content/global/skill/fletching/gem/CutGemsIntoBoltTipsScript.kt new file mode 100644 index 000000000..55ea058d0 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/CutGemsIntoBoltTipsScript.kt @@ -0,0 +1,79 @@ +package content.global.skill.fletching.gem + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * Represents the queue script for cutting gems into bolt tips + * @author Ceikry + * @param player the player. + * @param gemBoltCraftInfo represents the crafting info for the gem we're cutting. + * @param amount the amount to make. + */ +class CutGemsIntoBoltTipsScript( + private val player: Player, + private val gemBoltCraftInfo: GemBoltsCraftInfo, + private val amount: Int +) { + + private val initialDelay = 1 + private val craftDelay = 5 + private val animationDelay = 6 + + private var craftingFinished = false + + private fun invokeAnimationLoop() { + queueScript(player, 0) { + if (craftingFinished) { + return@queueScript stopExecuting(player) + } + animate(player, gemBoltCraftInfo.gemCutAnimationId) + return@queueScript delayScript(player, animationDelay) + } + } + + private fun invokeCraftLoop() { + queueScript(player, 0) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < gemBoltCraftInfo.level) { + craftingFinished = true + GemBoltListeners.sendGemTipCutLevelCheckFailDialog(player, gemBoltCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val amountOfTipsToCraft = when (gemBoltCraftInfo) { + GemBoltsCraftInfo.PEARLS -> 24 + GemBoltsCraftInfo.PEARL -> 6 + GemBoltsCraftInfo.ONYX -> 24 + else -> 12 + } + + if (removeItem(player, Item(gemBoltCraftInfo.gemItemId))) { + addItem(player, gemBoltCraftInfo.tipItemId, amountOfTipsToCraft) + rewardXP(player, Skills.FLETCHING, gemBoltCraftInfo.experience) + } else { + craftingFinished = true + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + craftingFinished = true + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, craftDelay, true) + } + } + + fun invoke() { + queueScript(player, initialDelay) { + invokeAnimationLoop() + invokeCraftLoop() + return@queueScript stopExecuting(player) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/GemBoltListeners.kt b/Server/src/main/content/global/skill/fletching/gem/GemBoltListeners.kt new file mode 100644 index 000000000..15ef1d38f --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/GemBoltListeners.kt @@ -0,0 +1,90 @@ +package content.global.skill.fletching.gem + +import core.api.amountInInventory +import core.api.getDynLevel +import core.api.hasSpaceFor +import core.api.sendDialogue +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +@Suppress("unused") // Reflectively loaded +class GemBoltListeners : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.CHISEL_1755, *GemBoltsCraftInfo.gemIds) { player, _, gem -> + val gemBoltCraftInfo = GemBoltsCraftInfo.forGemId(gem.id) ?: return@onUseWith true + + object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(gemBoltCraftInfo.gemItemId)) { + override fun create(amount: Int, index: Int) { + if (getDynLevel(player, Skills.FLETCHING) < gemBoltCraftInfo.level) { + sendGemTipCutLevelCheckFailDialog(player, gemBoltCraftInfo.level) + return + } + CutGemsIntoBoltTipsScript(player, gemBoltCraftInfo, amount).invoke() + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, gemBoltCraftInfo.gemItemId) + } + }.open() + return@onUseWith true + } + + onUseWith( + IntType.ITEM, + GemBoltsCraftInfo.untippedBoltIds, + *GemBoltsCraftInfo.boltTipIds + ) { player, untippedBolt, boltTip -> + val bolt = GemBoltsCraftInfo.forTipId(boltTip.id) ?: return@onUseWith false + if (untippedBolt.id != bolt.untippedBoltItemId) return@onUseWith false + + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.tippedBoltItemId)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + AttachGemTipToBoltScript(player, bolt, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < bolt.level) { + sendGemTipAttachLevelCheckFailDialog(player, bolt.level) + return false + } + if (!hasSpaceFor(player, Item(bolt.tippedBoltItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return min(amountInInventory(player, untippedBolt.id), amountInInventory(player, boltTip.id)) + } + } + handler.open() + return@onUseWith true + } + } + + companion object { + fun sendGemTipCutLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a Fletching level of $level or above to do that." + ) + } + + fun sendGemTipAttachLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a Fletching level of $level or above to do that." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/GemBoltsCraftInfo.kt b/Server/src/main/content/global/skill/fletching/gem/GemBoltsCraftInfo.kt new file mode 100644 index 000000000..d0e2b0f11 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/GemBoltsCraftInfo.kt @@ -0,0 +1,106 @@ +package content.global.skill.fletching.gem + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different gem tipped bolts + * @property untippedBoltItemId the base untipped bolt item id + * @property gemItemId the gem item id used to craft the bolt tips + * @property gemCutAnimationId the animation to play when the player cuts the gem + * @property tipItemId the item id of the resulting bolt tips + * @property tippedBoltItemId the item id of the finished gem-tipped bolt + * @property level the required level to craft the gem tipped bolt or tips themselves + * @property experience gained creating one set of gem tips, or per bolt tipped + */ +enum class GemBoltsCraftInfo( + var untippedBoltItemId: Int, + var gemItemId: Int, + var gemCutAnimationId: Int, + var tipItemId: Int, + var tippedBoltItemId: Int, + var level: Int, + var experience: Double +) { + OPAL(Items.BRONZE_BOLTS_877, Items.OPAL_1609, 890, Items.OPAL_BOLT_TIPS_45, Items.OPAL_BOLTS_879, 11, 1.6), + JADE(Items.BLURITE_BOLTS_9139, Items.JADE_1611, 891, Items.JADE_BOLT_TIPS_9187, Items.JADE_BOLTS_9335, 26, 2.4), + PEARL(Items.IRON_BOLTS_9140, Items.OYSTER_PEARL_411, 4470, Items.PEARL_BOLT_TIPS_46, Items.PEARL_BOLTS_880, 41, 3.2), + PEARLS( + Items.IRON_BOLTS_9140, + Items.OYSTER_PEARLS_413, + 4470, + Items.PEARL_BOLT_TIPS_46, + Items.PEARL_BOLTS_880, + 41, + 3.2 + ), + RED_TOPAZ( + Items.STEEL_BOLTS_9141, + Items.RED_TOPAZ_1613, + 892, + Items.TOPAZ_BOLT_TIPS_9188, + Items.TOPAZ_BOLTS_9336, + 48, + 3.9 + ), + SAPPHIRE( + Items.MITHRIL_BOLTS_9142, + Items.SAPPHIRE_1607, + 888, + Items.SAPPHIRE_BOLT_TIPS_9189, + Items.SAPPHIRE_BOLTS_9337, + 56, + 4.7 + ), + EMERALD( + Items.MITHRIL_BOLTS_9142, + Items.EMERALD_1605, + 889, + Items.EMERALD_BOLT_TIPS_9190, + Items.EMERALD_BOLTS_9338, + 58, + 5.5 + ), + RUBY(Items.ADAMANT_BOLTS_9143, Items.RUBY_1603, 887, Items.RUBY_BOLT_TIPS_9191, Items.RUBY_BOLTS_9339, 63, 6.3), + DIAMOND( + Items.ADAMANT_BOLTS_9143, + Items.DIAMOND_1601, + 886, + Items.DIAMOND_BOLT_TIPS_9192, + Items.DIAMOND_BOLTS_9340, + 65, + 7.0 + ), + DRAGONSTONE( + Items.RUNE_BOLTS_9144, + Items.DRAGONSTONE_1615, + 885, + Items.DRAGON_BOLT_TIPS_9193, + Items.DRAGON_BOLTS_9341, + 71, + 8.2 + ), + ONYX(Items.RUNE_BOLTS_9144, Items.ONYX_6573, 2717, Items.ONYX_BOLT_TIPS_9194, Items.ONYX_BOLTS_9342, 73, 9.4); + + companion object { + private val gemBoltCraftInfoByGemId = values().associateBy { it.gemItemId } + private val gemBoltCraftInfoByBoltTipId = values().associateBy { it.tipItemId } + + val untippedBoltIds: IntArray = + values().map { gemBoltsCraftInfo: GemBoltsCraftInfo -> gemBoltsCraftInfo.untippedBoltItemId }.distinct() + .toIntArray() + + val gemIds: IntArray = + values().map { gemBoltsCraftInfo: GemBoltsCraftInfo -> gemBoltsCraftInfo.gemItemId }.toIntArray() + + val boltTipIds: IntArray = + values().map { gemBoltsCraftInfo: GemBoltsCraftInfo -> gemBoltsCraftInfo.tipItemId }.toIntArray() + + fun forGemId(gemId: Int): GemBoltsCraftInfo? { + return gemBoltCraftInfoByGemId[gemId] + } + + fun forTipId(tipId: Int): GemBoltsCraftInfo? { + return gemBoltCraftInfoByBoltTipId[tipId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/grapple/GrappleListeners.kt b/Server/src/main/content/global/skill/fletching/grapple/GrappleListeners.kt new file mode 100644 index 000000000..46373cda0 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/grapple/GrappleListeners.kt @@ -0,0 +1,67 @@ +package content.global.skill.fletching.grapple + +import core.api.* +import core.game.interaction.Clocks +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +@Suppress("unused") // Reflectively loaded +class GrappleListeners : InteractionListener { + private val mithrilBolt = Items.MITHRIL_BOLTS_9142 + private val mithrilGrappleTip = Items.MITH_GRAPPLE_TIP_9416 + private val rope = Items.ROPE_954 + private val mithrilGrapple = Items.MITH_GRAPPLE_9418 + private val mithrilGrappleWithRope = Items.MITH_GRAPPLE_9419 + + override fun defineListeners() { + onUseWith(IntType.ITEM, mithrilBolt, mithrilGrappleTip) { player, bolt, tip -> + if (getDynLevel(player, Skills.FLETCHING) < 59) { + sendMessage(player, "You need a fletching level of 59 to make this.") + return@onUseWith true + } + queueScript(player, 0) { _ -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + if (removeItemsIfPlayerHasEnough( + player, + Item(mithrilBolt, 1), + tip.asItem() + ) + ) { + addItem(player, mithrilGrapple, 1) + } + + delayClock(player, Clocks.SKILLING, 3) + return@queueScript stopExecuting(player) + } + + + return@onUseWith true + } + + onUseWith(IntType.ITEM, rope, mithrilGrapple) { player, rope, grapple -> + if (getDynLevel(player, Skills.FLETCHING) < 59) { + sendMessage(player, "You need a fletching level of 59 to make this.") + return@onUseWith true + } + queueScript(player, 0) { _ -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + if (removeItemsIfPlayerHasEnough( + player, + rope.asItem(), + grapple.asItem() + ) + ) { + addItem(player, mithrilGrappleWithRope, 1) + } + delayClock(player, Clocks.SKILLING, 3) + return@queueScript stopExecuting(player) + } + return@onUseWith true + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java deleted file mode 100644 index c7ab5ec7c..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java +++ /dev/null @@ -1,123 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.arrow; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents the enum storing the arrow head information. - * @author 'Vexia - * @note brutal arrows after quest. - *//* - -public enum ArrowHead { - BRONZE_ARROW(new Item(39), new Item(882), 1, 2.6), - IRON_ARROW(new Item(40), new Item(884), 15, 3.8), - STEEL_ARROW(new Item(41), new Item(886), 30, 6.3), - MITHRIL_ARROW(new Item(42), new Item(888), 45, 8.8), - ADAMANT_ARROW(new Item(43), new Item(890), 60, 10), - RUNE_ARROW(new Item(44), new Item(892), 75, 13.8), - DRAGON_ARROW(new Item(11237), new Item(11212), 90, 16.3), - BROAD_ARROW(new Item(13278), new Item(4160), 52, 10); - - */ -/** - * Constructs a new {@code ArrowHead.java} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experience. - *//* - - ArrowHead(Item item, Item product, int level, double experience) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Represents the arrow tip. - *//* - - private final Item item; - - */ -/** - * Represents the product item. - *//* - - private final Item product; - - */ -/** - * Represents the level required. - *//* - - private final int level; - - */ -/** - * Represents the experience gained. - *//* - - private final double experience; - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getTips() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Gets the arrow head. - * @param item the item. - * @return the arrow head. - *//* - - public static ArrowHead forItem(final Item item) { - for (ArrowHead arrow : ArrowHead.values()) { - if (arrow.getTips().getId() == item.getId()) { - return arrow; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java deleted file mode 100644 index 5ea27c2cc..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java +++ /dev/null @@ -1,110 +0,0 @@ -package content.global.skill.fletching.items.arrow; - -import content.global.skill.slayer.SlayerManager; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the arrow head pulse to complete the headless arrow. - * @author 'Vexia - */ -public class ArrowHeadPulse extends SkillPulse { - - /** - * Represents the headless arrow item. - */ - private static final Item HEADLESS_ARROW = new Item(53); - - /** - * Represents the arrow head. - */ - private final Fletching.ArrowHeads arrow; - - /** - * Represents the sets to do. - */ - private int sets; - - /** - * Constructs a new {@code ArrowHeadPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - * @param arrow the arrow. - * @param sets the sets. - */ - public ArrowHeadPulse(final Player player, final Item node, final Fletching.ArrowHeads arrow, final int sets) { - super(player, node); - this.arrow = arrow; - this.sets = sets; - } - - @Override - public boolean checkRequirements() { - if (arrow.unfinished == 4160) { - if (!SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { - player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad arrows."); - return false; - } - } - if (player.getSkills().getLevel(Skills.FLETCHING) < arrow.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + arrow.level + " to do this."); - return false; - } - if (!hasSpaceFor(player, arrow.getFinished())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(3); - } - Item tip = arrow.getUnfinished(); - int tipAmount = player.getInventory().getAmount(arrow.unfinished); - int shaftAmount = player.getInventory().getAmount(HEADLESS_ARROW); - if (tipAmount >= 15 && shaftAmount >= 15) { - HEADLESS_ARROW.setAmount(15); - tip.setAmount(15); - player.getPacketDispatch().sendMessage("You attach arrow heads to 15 arrow shafts."); - } else { - int amount = tipAmount > shaftAmount ? shaftAmount : tipAmount; - HEADLESS_ARROW.setAmount(amount); - tip.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 ? "You attach an arrow head to an arrow shaft." : "You attach arrow heads to " + amount + " arrow shafts."); - } - if (player.getInventory().remove(HEADLESS_ARROW, tip)) { - player.getSkills().addExperience(Skills.FLETCHING, arrow.experience * tip.getAmount(), true); - Item product = arrow.getFinished(); - product.setAmount(tip.getAmount()); - player.getInventory().add(product); - } - HEADLESS_ARROW.setAmount(1); - tip.setAmount(1); - if (!player.getInventory().containsItem(HEADLESS_ARROW)) { - return true; - } - if (!player.getInventory().containsItem(tip)) { - return true; - } - sets--; - return sets == 0; - } - - @Override - public void message(int type) { - - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java deleted file mode 100644 index 3125b5669..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java +++ /dev/null @@ -1,145 +0,0 @@ -package content.global.skill.fletching.items.arrow; - -import org.rs09.consts.Items; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the arrow pulse for creating unfinished arrows. - * @author 'Vexia - */ -public final class HeadlessArrowPulse extends SkillPulse { - - /** - * Represents the headless arrow item. - */ - private final Item HEADLESS_ARROW = new Item(Items.HEADLESS_ARROW_53); - - /** - * Represents the arrow shaft item. - */ - private final Item ARROW_SHAFT = new Item(Items.ARROW_SHAFT_52); - - /** - * Represents the feather items. - */ - private static final Item[] FEATHER = new Item[] { - new Item(Items.FEATHER_314), - new Item(Items.STRIPY_FEATHER_10087), - new Item(Items.RED_FEATHER_10088), - new Item(Items.BLUE_FEATHER_10089), - new Item(Items.YELLOW_FEATHER_10090), - new Item(Items.ORANGE_FEATHER_10091) - }; - - /** - * The feather being used. - */ - private Item feather; - - /** - * Represents the amount to make. - */ - private int sets; - - /** - * Represents if we should use sets, meaning we have 15 & 15 arrow shafts and feathers. - */ - private boolean useSets = false; - - /** - * Constructs a new {@code ArrowPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public HeadlessArrowPulse(Player player, Item node, Item feather, int sets) { - super(player, node); - this.sets = sets; - this.feather = feather; - } - - @Override - public boolean checkRequirements() { - if (!player.getInventory().containsItem(ARROW_SHAFT)) { - player.getDialogueInterpreter().sendDialogue("You don't have any arrow shafts."); - return false; - } - if (feather == null || !player.getInventory().containsItem(feather)) { - player.getDialogueInterpreter().sendDialogue("You don't have any feathers."); - return false; - } - if (player.getInventory().contains(ARROW_SHAFT.getId(), 15) && player.getInventory().contains(feather.getId(), 15)) { - useSets = true; - } else { - useSets = false; - } - if (!hasSpaceFor(player, HEADLESS_ARROW.asItem())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - int featherAmount = player.getInventory().getAmount(feather); - int shaftAmount = player.getInventory().getAmount(ARROW_SHAFT); - if (getDelay() == 1) { - super.setDelay(3); - } - if (featherAmount >= 15 && shaftAmount >= 15) { - feather.setAmount(15); - ARROW_SHAFT.setAmount(15); - player.getPacketDispatch().sendMessage("You attach feathers to 15 arrow shafts."); - } else { - int amount = Math.min(featherAmount, shaftAmount); - feather.setAmount(amount); - ARROW_SHAFT.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 - ? "You attach a feathers to a shaft." : "You attach feathers to " + amount + " arrow shafts."); - } - if (player.getInventory().remove(feather, ARROW_SHAFT)) { - HEADLESS_ARROW.setAmount(feather.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, HEADLESS_ARROW.getAmount(), true); - player.getInventory().add(HEADLESS_ARROW); - } - HEADLESS_ARROW.setAmount(1); - feather.setAmount(1); - ARROW_SHAFT.setAmount(1); - if (!player.getInventory().containsItem(ARROW_SHAFT)) { - return true; - } - if (!player.getInventory().containsItem(feather)) { - return true; - } - sets--; - return sets <= 0; - } - - @Override - public void message(int type) { - } - - /** - * Gets the feather item. - * @return the item. - */ - private Item getFeather() { - int length = FEATHER.length; - for (int i = 0; i < length; i++) { - Item f = FEATHER[i]; - if (player.getInventory().containsItem(f)) { - return f; - } - } - return null; - } -} diff --git a/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java b/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java deleted file mode 100644 index f877050db..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java +++ /dev/null @@ -1,123 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.bolts; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents an enum of bolts. - * @author 'Vexia - *//* - -public enum Bolt { - BRONZE_BOLT(new Item(9375), new Item(877), 9, 0.5), - BLURITE_BOLT(new Item(9376), new Item(9139), 24, 1), - IRON_BOLT(new Item(9377), new Item(9140), 39, 1.5), - SILVER_BOLT(new Item(9382), new Item(9145), 43, 2.5), - STEEL_BOLT(new Item(9378), new Item(9141), 46, 3.5), - MITHRIL_BOLT(new Item(9379), new Item(9142), 54, 5), - ADAMANTITE_BOLT(new Item(9380), new Item(9143), 61, 7), - RUNITE_BOLT(new Item(9381), new Item(9144), 69, 10), - BROAD_BOLT(new Item(13279), new Item(13280), 55, 3); - - */ -/** - * The item required. - *//* - - private final Item item; - - */ -/** - * The product recieved. - *//* - - private final Item product; - - */ -/** - * The level required. - *//* - - private final int level; - - */ -/** - * The experience gained. - *//* - - private final double experience; - - */ -/** - * Constructs a new {@code Bolt} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experienece. - *//* - - Bolt(Item item, Item product, int level, double experience) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getItem() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the bolt for the item. - * @param item the item. - * @return the bolt. - *//* - - public static Bolt forItem(final Item item) { - for (Bolt bolt : Bolt.values()) { - if (bolt.getItem().getId() == item.getId()) { - return bolt; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java b/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java deleted file mode 100644 index b345c4276..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java +++ /dev/null @@ -1,130 +0,0 @@ -package content.global.skill.fletching.items.bolts; - -import content.global.skill.slayer.SlayerManager; -import org.rs09.consts.Items; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the bolt pulse class to make bolts. - * @author ceik - */ -public final class BoltPulse extends SkillPulse { - - /** - * Represents the feather item. - */ - private Item feather; - - /** - * Represents possible feather Items - */ - private static final Item[] FEATHER = new Item[] { - new Item(Items.FEATHER_314), - new Item(Items.STRIPY_FEATHER_10087), - new Item(Items.RED_FEATHER_10088), - new Item(Items.BLUE_FEATHER_10089), - new Item(Items.YELLOW_FEATHER_10090), - new Item(Items.ORANGE_FEATHER_10091) - }; - - /** - * Represents the bolt. - */ - private final Fletching.Bolts bolt; - - /** - * Represents the sets to do. - */ - private int sets; - - /** - * Represents if we're using sets. - */ - private boolean useSets = false; - - /** - * Constructs a new {@code BoltPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public BoltPulse(Player player, Item node, final Fletching.Bolts bolt, final Item feather, final int sets) { - super(player, node); - this.bolt = bolt; - this.sets = sets; - this.feather = feather; - } - - @Override - public boolean checkRequirements() { - if (bolt.getUnfinished().getId() == 13279) { - if (!SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { - player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad bolts."); - return false; - } - } - if (player.getSkills().getLevel(Skills.FLETCHING) < bolt.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bolt.level + " in order to do this."); - return false; - } - if (!player.getInventory().containsItem(feather)) { - return false; - } - if (!player.getInventory().containsItem(bolt.getUnfinished())) { - return false; - } - if (!player.getInventory().hasSpaceFor(bolt.getFinished())) { - player.getDialogueInterpreter().sendDialogue("You do not have enough inventory space."); - return false; - } - - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - int featherAmount = player.getInventory().getAmount(feather); - int boltAmount = player.getInventory().getAmount(bolt.unfinished); - if (getDelay() == 1) { - super.setDelay(3); - } - final Item unfinished = bolt.getUnfinished(); - if (featherAmount >= 10 && boltAmount >= 10) { - feather.setAmount(10); - unfinished.setAmount(10); - player.getPacketDispatch().sendMessage("You fletch 10 bolts."); - } else { - int amount = featherAmount > boltAmount ? boltAmount : featherAmount; - feather.setAmount(amount); - unfinished.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 ? "You attach a feather to a bolt." : "You fletch " + amount + " bolts"); - } - if (player.getInventory().remove(feather, unfinished)) { - Item product = bolt.getFinished(); - product.setAmount(feather.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, product.getAmount() * bolt.experience, true); - player.getInventory().add(product); - } - feather.setAmount(1); - if (!player.getInventory().containsItem(feather)) { - return true; - } - if (!player.getInventory().containsItem(bolt.getUnfinished())) { - return true; - } - sets--; - return sets <= 0; - } - - @Override - public void message(int type) { - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java b/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java deleted file mode 100644 index 0187f17bb..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java +++ /dev/null @@ -1,136 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.bow; - -import org.crandor.game.node.item.Item; -import org.crandor.game.world.update.flag.context.Animation; - -*/ -/** - * Represents the enum of stringing bows. - * @author 'Vexia - *//* - -public enum StringBow { - SHORT_BOW(new Item(50), new Item(841), 5, 5, new Animation(6678)), - LONG_BOW(new Item(48), new Item(839), 10, 10, new Animation(6684)), - OAK_SHORTBOW(new Item(54), new Item(843), 20, 16.5, new Animation(6679)), - OAK_LONGBOW(new Item(56), new Item(845), 25, 25, new Animation(6685)), - WILLOW_SHORTBOW(new Item(60), new Item(849), 35, 33.3, new Animation(6680)), - WILLOW_LONGBOW(new Item(58), new Item(847), 40, 41.5, new Animation(6686)), - MAPLE_SHORTBOW(new Item(64), new Item(853), 50, 50, new Animation(6681)), - MAPLE_LONGBOW(new Item(62), new Item(851), 55, 58.3, new Animation(6687)), - YEW_SHORTBOW(new Item(68), new Item(857), 65, 66, new Animation(6682)), - YEW_LONGBOW(new Item(66), new Item(855), 70, 75, new Animation(6688)), - MAGIC_SHORTBOW(new Item(72), new Item(861), 80, 83.3, new Animation(6683)), - MAGIC_LONGBOW(new Item(70), new Item(859), 85, 91.5, new Animation(6689)); - - - StringBow(final Item item, final Item product, final int level, final double experience, final Animation animation) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - - */ -/** - * The item required. - *//* - - private final Item item; - - */ -/** - * The item product. - *//* - - private final Item product; - - */ -/** - * The level required. - *//* - - private final int level; - - */ -/** - * The experience required. - *//* - - private final double experience; - - */ -/** - * The animation of stringing. - *//* - - private final Animation animation; - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getItem() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the animation. - * @return the animation. - *//* - - public Animation getAnimation() { - return animation; - } - - */ -/** - * Method used to get the string bow for the item. - * @param item the item. - * @return the string bow. - *//* - - public static StringBow forItem(final int id) { - for (StringBow bw : StringBow.values()) { - if (bw.getItem().getId() == id) { - return bw; - } - } - return null; - } -}*/ diff --git a/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java b/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java deleted file mode 100644 index fd1b2c560..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java +++ /dev/null @@ -1,92 +0,0 @@ -package content.global.skill.fletching.items.bow; - -import core.api.Container; -import core.api.ContentAPIKt; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.world.map.zone.ZoneBorders; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the skill pulse of stringing. - * - * @author Ceikry - */ -public class StringPulse extends SkillPulse { - - /** - * Represents the string bow. - */ - private final Fletching.String bow; - - /** - * The amount. - */ - private int amount; - - /** - * Constructs a new {@code StringbowPlugin.java} {@code Object}. - * - * @param player the player. - * @param node the node. - */ - public StringPulse(Player player, Item node, final Fletching.String bow, int amount) { - super(player, node); - this.bow = bow; - this.amount = amount; - } - - @Override - public boolean checkRequirements() { - if (getDelay() == 1) { - setDelay(2); - } - if (player.getSkills().getLevel(Skills.FLETCHING) < bow.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.level + " to string this bow."); - return false; - } - if (!player.getInventory().containsItem(new Item(bow.unfinished))) { - return false; - } - if (!player.getInventory().containsItem(new Item(bow.string))) { - player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings."); - return false; - } - animate(); - return true; - } - - @Override - public void animate() { - player.animate(bow.animation); - } - - @Override - public boolean reward() { - if (player.getInventory().remove(new Item(bow.unfinished), new Item(bow.string))) { - player.getInventory().add(new Item(bow.product)); - player.getSkills().addExperience(Skills.FLETCHING, bow.experience, true); - player.getPacketDispatch().sendMessage("You add a string to the bow."); - - if (bow == Fletching.String.MAGIC_SHORTBOW - && (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player) - || new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player)) - && player.getAttribute("diary:seers:fletch-magic-short-bow", false)) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2); - } - } - if (!player.getInventory().containsItem(new Item(bow.string)) || !player.getInventory().containsItem(new Item(bow.unfinished))) { - return true; - } - amount--; - return amount == 0; - } - - @Override - public void message(int type) { - } - -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java b/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java deleted file mode 100644 index cfe0cf53b..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java +++ /dev/null @@ -1,97 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.crossbow; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import org.crandor.game.node.entity.player.Player; -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents the skill pulse of stringing. - * @author 'Vexia - *//* - -public class CrossbowPulse extends SkillPulse { - - */ -/** - * Represents the bow string item. - *//* - - private final Item BOW_STRING = new Item(9438); - - */ -/** - * Represents the string bow. - *//* - - private final StringCross bow; - - */ -/** - * Represents the amount. - *//* - - private int amount; - - */ -/** - * Constructs a new {@code StringcrossbowPlugin.java} {@code Object}. - * @param player the player. - * @param node the node. - *//* - - public CrossbowPulse(Player player, Item node, final StringCross bow, int amount) { - super(player, node); - this.bow = bow; - this.amount = amount; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < bow.getLevel()) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.getLevel() + " to string this crossbow."); - return false; - } - if (!player.getInventory().containsItem(BOW_STRING)) { - player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings."); - return false; - } - return true; - } - - @Override - public void animate() { - player.animate(bow.getAnimation()); - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(5); - return false; - } - if (player.getInventory().remove(bow.getItem(), BOW_STRING)) { - player.getInventory().add(bow.getProduct()); - player.getSkills().addExperience(Skills.FLETCHING, bow.getExperience(), true); - player.getPacketDispatch().sendMessage("You add a string to the crossbow."); - } - if (!player.getInventory().containsItem(BOW_STRING) || !player.getInventory().containsItem(bow.getItem())) { - return true; - } - amount--; - return amount == 0; - } - - @Override - public void message(int type) { - switch (type) { - case 0: - break; - case 1: - break; - } - } - -}*/ diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java b/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java deleted file mode 100644 index 6ffc01413..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java +++ /dev/null @@ -1,128 +0,0 @@ -package content.global.skill.fletching.items.crossbow; - -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; - -/** - * Represents the enum for limbs. - * @author 'Vexia - */ -public enum Limb { - WOODEN_STOCK(new Item(9440), new Item(9420), new Item(9454), 9, 12, new Animation(4436)), - OAK_STOCK(new Item(9442), new Item(9422), new Item(9176), 24, 32, new Animation(4437)), - WILLOW_STOCK(new Item(9444), new Item(9423), new Item(9457), 39, 44, new Animation(4438)), - TEAK_STOCK(new Item(9446), new Item(9425), new Item(9459), 46, 54, new Animation(4439)), - MAPLE_STOCK(new Item(9448), new Item(9427), new Item(9461), 54, 64, new Animation(4440)), - MAHOGANY_STOCK(new Item(9450), new Item(9429), new Item(9463), 61, 82, new Animation(4441)), - YEW_STOCK(new Item(9452), new Item(9431), new Item(9465), 69, 100, new Animation(4442)); - - /** - * Constructs a new {@code StringcrosbowPlugin.java} {@code Object}. - * @param stock the stock. - * @param limb the limb. - * @param product the product. - * @param level the level. - * @param experience the experience. - * @param animation the animation. - */ - Limb(Item stock, Item limb, Item product, int level, double experience, Animation animation) { - this.stock = stock; - this.limb = limb; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - - /** - * The stock. - */ - private final Item stock; - - /** - * The limb. - */ - private final Item limb; - - /** - * The product. - */ - private final Item product; - - /** - * The level. - */ - private final int level; - - /** - * The experience. - */ - private final double experience; - - /** - * The animation. - */ - private final Animation animation; - - /** - * Gets the stock. - * @return The stock. - */ - public Item getStock() { - return stock; - } - - /** - * Gets the limb. - * @return The limb. - */ - public Item getLimb() { - return limb; - } - - /** - * Gets the product. - * @return The product. - */ - public Item getProduct() { - return product; - } - - /** - * Gets the level. - * @return The level. - */ - public int getLevel() { - return level; - } - - /** - * Gets the experience. - * @return The experience. - */ - public double getExperience() { - return experience; - } - - /** - * Gets the animation. - * @return The animation. - */ - public Animation getAnimation() { - return animation; - } - - /** - * Method used to get the {@link Limb} for the item. - * @param item the item. - * @return the limb. - */ - public static Limb forItems(final Item item, final Item second) { - for (Limb l : Limb.values()) { - if (l.getLimb().getId() == item.getId() && l.getStock().getId() == second.getId() || l.getLimb().getId() == second.getId() && l.getStock().getId() == item.getId()) { - return l; - } - } - return null; - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt b/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt deleted file mode 100644 index 2d6d35562..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt +++ /dev/null @@ -1,52 +0,0 @@ -package content.global.skill.fletching.items.crossbow - -import core.game.node.entity.player.Player -import core.game.node.entity.skill.SkillPulse -import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching -import core.game.node.item.Item - -/** - * Represents the skill pulse of attaching limbs. - * @author Ceikry - */ -class LimbPulse(player: Player?, node: Item, private val limb: Fletching.Limb, private var amount: Int) : SkillPulse(player, node) { - override fun checkRequirements(): Boolean { - if (player.skills.getLevel(Skills.FLETCHING) < limb.level) { - player.dialogueInterpreter.sendDialogue("You need a fletching level of " + limb.level + " to attach these limbs.") - return false - } - if (!player.inventory.containsItem(Item(limb.limb))) { - player.dialogueInterpreter.sendDialogue("That's not the correct limb to attach.") - return false - } - if(!player.inventory.containsItem(Item(limb.stock))){ - player.dialogueInterpreter.sendDialogue("That's not the correct stock for that limb.") - return false - } - return player.inventory.containsItem(Item(limb.stock)) - } - - override fun animate() { - player.animate(limb.animation) - } - - override fun reward(): Boolean { - if (delay == 1) { - super.setDelay(6) - return false - } - if (player.inventory.remove(Item(limb.stock), Item(limb.limb))) { - player.inventory.add(Item(limb.product)) - player.skills.addExperience(Skills.FLETCHING, limb.experience, true) - player.packetDispatch.sendMessage("You attach the metal limbs to the stock.") - } - if (!player.inventory.containsItem(Item(limb.limb))) { - return true - } - amount-- - return amount == 0 - } - - override fun message(type: Int) {} -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java b/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java deleted file mode 100644 index 32671c480..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java +++ /dev/null @@ -1,139 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.crossbow; - -import org.crandor.game.node.item.Item; -import org.crandor.game.world.update.flag.context.Animation; - -*/ -/** - * Represents the enum of stringing crossbows. - * @author 'Vexia - *//* - -public enum StringCross { - BRONZE_CBOW(new Item(9454), new Item(9174), 9, 6, new Animation(6671)), - BLURITE_CBOW(new Item(9456), new Item(9176), 24, 16, new Animation(6672)), - IRON_CBOW(new Item(9457), new Item(9177), 39, 22, new Animation(6673)), - STEEL_CBOW(new Item(9459), new Item(9179), 46, 27, new Animation(6674)), - MITHIRIL_CBOW(new Item(9461), new Item(9181), 54, 32, new Animation(6675)), - ADAMANT_CBOW(new Item(9463), new Item(9183), 61, 41, new Animation(6676)), - RUNITE_CBOW(new Item(9465), new Item(9185), 69, 50, new Animation(6677)); - */ -/** - * Constructs a new {@code StringcrossbowPlugin.java} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experience. - *//* - - StringCross(final Item item, final Item product, final int level, final double experience, final Animation animation) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - - */ -/** - * The item required. - *//* - - private final Item item; - - */ -/** - * The item product. - *//* - - private final Item product; - - */ -/** - * The level required. - *//* - - private final int level; - - */ -/** - * The experience required. - *//* - - private final double experience; - - */ -/** - * The animation of stringing. - *//* - - private final Animation animation; - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getItem() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the animation. - * @return the animation. - *//* - - public Animation getAnimation() { - return animation; - } - - */ -/** - * Method used to get the string bow for the item. - * @param item the item. - * @return the string bow. - *//* - - public static StringCross forItem(final Item item) { - for (StringCross bw : StringCross.values()) { - if (bw.getItem().getId() == item.getId()) { - return bw; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/darts/Dart.java b/Server/src/main/content/global/skill/fletching/items/darts/Dart.java deleted file mode 100644 index 235849496..000000000 --- a/Server/src/main/content/global/skill/fletching/items/darts/Dart.java +++ /dev/null @@ -1,96 +0,0 @@ -package content.global.skill.fletching.items.darts; - -import core.game.node.item.Item; - -/** - * Represents the enum to hold dart info. - * @author 'Vexia - */ -public enum Dart { - BRONZE_DART(new Item(819), new Item(806), 1, 1.8), - IRON_DART(new Item(820), new Item(807), 22, 3.8), - STEEL_DART(new Item(821), new Item(808), 37, 7.5), - MITHRIL_DART(new Item(822), new Item(809), 52, 11.2), - ADAMANT_DART(new Item(823), new Item(810), 67, 15), - RUNE_DART(new Item(824), new Item(811), 81, 18.8), - DRAGON_DART(new Item(11232), new Item(11230), 95, 25); - /** - * Constructs a new {@code Dart} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experience. - */ - Dart(final Item item, final Item product, final int level, final double experience) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - } - - /** - * Represents the item required. - */ - private final Item item; - - /** - * Represents the product gained. - */ - private final Item product; - - /** - * Represents the level required. - */ - private final int level; - - /** - * Represents the experience gained. - */ - private final double experience; - - /** - * Gets the item. - * @return The item. - */ - public Item getItem() { - return item; - } - - /** - * Gets the product. - * @return The product. - */ - public Item getProduct() { - return product; - } - - /** - * Gets the level. - * @return The level. - */ - public int getLevel() { - return level; - } - - /** - * Gets the experience. - * @return The experience. - */ - public double getExperience() { - return experience; - } - - /** - * Method used to get the dart for the item. - * @param item the item. - * @return the dart. - */ - public static Dart forItem(final Item item) { - for (Dart dart : Dart.values()) { - if (dart.getItem().getId() == item.getId()) { - return dart; - } - } - return null; - } -} diff --git a/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java b/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java deleted file mode 100644 index 6f21ba8d7..000000000 --- a/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java +++ /dev/null @@ -1,104 +0,0 @@ -package content.global.skill.fletching.items.darts; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the dart pulse. - * @author ceikry - */ -public final class DartPulse extends SkillPulse { - - /** - * Represents the feather item. - */ - private static final Item FEATHER = new Item(314); - - /** - * Represents the dart. - */ - private final Fletching.Darts dart; - - /** - * Represents the sets to make. - */ - private int sets; - - /** - * Constructs a new {@code DartPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public DartPulse(Player player, Item node, Fletching.Darts dart, int sets) { - super(player, node); - this.dart = dart; - this.sets = sets; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < dart.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + dart.level + " to do this."); - return false; - } - if (!player.getQuestRepository().isComplete("The Tourist Trap")){ - player.getDialogueInterpreter().sendDialogue("You need to have completed Tourist Trap to fletch darts."); - return false; - } - if (!hasSpaceFor(player, dart.getFinished())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(3); - } - final Item unfinished = dart.getUnfinished(); - final int dartAmount = player.getInventory().getAmount(unfinished); - final int featherAmount = player.getInventory().getAmount(FEATHER); - if (dartAmount >= 10 && featherAmount >= 10) { - FEATHER.setAmount(10); - unfinished.setAmount(10); - player.getPacketDispatch().sendMessage("You attach feathers to 10 darts."); - } else { - int amount = featherAmount > dartAmount ? dartAmount : featherAmount; - FEATHER.setAmount(amount); - unfinished.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 ? "You attach a feather to a dart." : "You attach feathers to " + amount + " darts."); - } - if (player.getInventory().remove(FEATHER, unfinished)) { - Item product = dart.getFinished(); - product.setAmount(FEATHER.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, dart.experience * product.getAmount(), true); - player.getInventory().add(product); - } - FEATHER.setAmount(1); - if (!player.getInventory().containsItem(FEATHER)) { - return true; - } - if (!player.getInventory().containsItem(dart.getUnfinished())) { - return true; - } - sets--; - return sets == 0; - } - - @Override - public void message(int type) { - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/gem/Gem.java b/Server/src/main/content/global/skill/fletching/items/gem/Gem.java deleted file mode 100644 index 6a3377aa4..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/Gem.java +++ /dev/null @@ -1,101 +0,0 @@ -package content.global.skill.fletching.items.gem; - -import core.game.node.item.Item; - -/** - * Represents gems to cut into bolt tips. - * @author 'Vexia - * @date 01/12/2013 - */ -public enum Gem { - OPAL(new Item(1609), new Item(45, 12), 11, 1.5), - JADE(new Item(1611), new Item(9187, 12), 26, 2.4), - RED_TOPAZ(new Item(1613), new Item(9188, 12), 48, 3.9), - SAPPHIRE(new Item(1607), new Item(9189, 12), 56, 4), - EMERALD(new Item(1605), new Item(9190, 12), 58, 5.5), - RUBY(new Item(1603), new Item(9191, 12), 63, 6.3), - DIAMOND(new Item(1601), new Item(9192, 12), 65, 7), - DRAGONSTONE(new Item(1615), new Item(9193, 12), 71, 8.2), - ONYX(new Item(6573), new Item(9194, 24), 73, 9.4); - - /** - * Constructs a new {@code Gem.java} {@code Object}. - * @param gem the gem. - * @param bolt the bolt. - * @param level the level. - * @param experience the experience. - */ - Gem(Item gem, Item bolt, int level, double experience) { - this.gem = gem; - this.bolt = bolt; - this.level = level; - this.experience = experience; - } - - /** - * Represents the gem. - */ - private final Item gem; - - /** - * Represents the bolt. - */ - private final Item bolt; - - /** - * Represents the level required. - */ - private final int level; - - /** - * Represents the experience gained. - */ - private final double experience; - - /** - * Gets the gem. - * @return The gem. - */ - public Item getGem() { - return gem; - } - - /** - * Gets the bolt. - * @return The bolt. - */ - public Item getBolt() { - return bolt; - } - - /** - * Gets the level. - * @return The level. - */ - public int getLevel() { - return level; - } - - /** - * Gets the experience. - * @return The experience. - */ - public double getExperience() { - return experience; - } - - /** - * Method used to get a gem for the item. - * @param item the item. - * @return the gem. - */ - public static Gem forItem(final Item item) { - for (Gem gem : values()) { - if (gem.getGem().getId() == item.getId()) { - return gem; - } - } - return null; - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java b/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java deleted file mode 100644 index b21e6a164..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java +++ /dev/null @@ -1,144 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.gem; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents a gem bolt. - * @author 'Vexia - * @date 01/12/2013 - *//* - -public enum GemBolt { - OPAL(new Item(877, 10), new Item(45, 10), new Item(879, 10), 11, 1.5), - PEARL(new Item(9140, 10), new Item(46, 10), new Item(880, 10), 41, 3.2), - JADE(new Item(9139, 10), new Item(9187, 10), new Item(9335, 10), 26, 2.4), - RED_TOPAZ(new Item(9141, 10), new Item(9188, 10), new Item(9336, 10), 48, 3.9), - SAPPHIRE(new Item(9142, 10), new Item(9189, 10), new Item(9337, 10), 56, 4), - EMERALD(new Item(9142, 10), new Item(9190, 10), new Item(9338, 10), 58, 5.5), - RUBY(new Item(9143, 10), new Item(9191, 10), new Item(9339, 10), 63, 6.3), - DIAMOND(new Item(9143, 10), new Item(9192, 10), new Item(9340, 10), 65, 7), - DRAGONSTONE(new Item(9144, 10), new Item(9193, 10), new Item(9341, 10), 71, 8.2), - ONYX(new Item(9144, 10), new Item(9194, 10), new Item(9342, 10), 73, 9.4); - - */ -/** - * Constructs a new {@code GemBolt} {@code Object}. - * @param base the base. - * @param tip the tip. - * @param level the level. - * @param experience the experience. - *//* - - GemBolt(Item base, Item tip, Item product, int level, double experience) { - this.base = base; - this.tip = tip; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Represents the base item. - *//* - - private final Item base; - - */ -/** - * Represents the tip to attach. - *//* - - private final Item tip; - - */ -/** - * Represents the product. - *//* - - private final Item product; - - */ -/** - * Represents the level. - *//* - - private final int level; - - */ -/** - * Represents the experience. - *//* - - private final double experience; - - */ -/** - * Gets the base. - * @return The base. - *//* - - public Item getBase() { - return base; - } - - */ -/** - * Gets the tip. - * @return The tip. - *//* - - public Item getTip() { - return tip; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the gem bolt from the id. - * @param boltt the boltt. - * @param tip the tip. - * @return the bolt. - *//* - - public static GemBolt forItems(final Item boltt, final Item tip) { - for (GemBolt bolt : values()) { - if (bolt.getBase().getId() == boltt.getId() && bolt.getTip().getId() == tip.getId() || bolt.getBase().getId() == tip.getId() && bolt.getTip().getId() == boltt.getId()) { - return bolt; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt deleted file mode 100644 index e03781529..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt +++ /dev/null @@ -1,68 +0,0 @@ -package content.global.skill.fletching.items.gem - -import core.game.node.entity.player.Player -import core.game.node.entity.skill.SkillPulse -import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching.GemBolts -import core.game.node.item.Item -import core.game.world.update.flag.context.Animation -import org.rs09.consts.Items - -/** - * Represents the gem cutting pulse(gem to bolt). - * @author Ceikry - */ -class GemBoltCutPulse -/** - * Constructs a new `GemCutPulse.java` `Object`. - * @param player the player. - * @param node the node. - * @param amount the amount. - */(player: Player?, node: Item?, - /** - * Represents the gem we're cutting. - */ - private val gem: GemBolts, - /** - * Represents the amount to make. - */ - private var amount: Int) : SkillPulse(player, node) { - /** - * Represents the ticks passed. - */ - private var ticks = 0 - - override fun checkRequirements(): Boolean { - if (player.skills.getLevel(Skills.FLETCHING) < gem.level) { - player.dialogueInterpreter.sendDialogue("You need a Fletching level of " + gem.level + " or above to do that.") - return false - } - return player.inventory.containsItem(Item(gem.gem)) - } - - override fun animate() { - if (ticks % 6 == 0) { - player.animate(ANIMATION) - } - } - - override fun reward(): Boolean { - if (++ticks % 5 != 0) { - return false - } - val reward = if (gem.gem == Items.OYSTER_PEARLS_413) Item(gem.tip, 24) else Item(gem.tip, 12) - if (player.inventory.remove(Item(gem.gem))) { - player.inventory.add(reward) - player.skills.addExperience(Skills.FLETCHING, gem.experience, true) - } - amount-- - return amount <= 0 - } - - companion object { - /** - * Represents the cutting animation. - */ - private val ANIMATION = Animation(6702) - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java deleted file mode 100644 index 4cd856e8a..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java +++ /dev/null @@ -1,91 +0,0 @@ -package content.global.skill.fletching.items.gem; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the attaching of a gem bolt to a premade bolt. - * @author Ceikry - */ -public final class GemBoltPulse extends SkillPulse { - - /** - * Represents the gem bolt being made. - */ - private Fletching.GemBolts bolt; - - /** - * Represents the sets to make. - */ - private int sets = 0; - - /** - * Represents the ticks passed. - */ - private int ticks; - - /** - * Constructs a new {@code GemBoltPulse} {@code Object}. - * @param player the player. - * @param node the node. - * @param sets the sets. - */ - public GemBoltPulse(Player player, Item node, Fletching.GemBolts bolt, int sets) { - super(player, node); - this.bolt = bolt; - this.sets = sets; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < bolt.level) { - player.getDialogueInterpreter().sendDialogue("You need a Fletching level of " + bolt.level + " or above to do that."); - return false; - } - if (!player.getInventory().containsItem(new Item(bolt.base)) || !player.getInventory().containsItem(new Item(bolt.tip))) { - return false; - } - if (!player.getInventory().hasSpaceFor(new Item(bolt.product))){ - player.getDialogueInterpreter().sendDialogue("You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - if (++ticks % 3 != 0) { - return false; - } - int baseAmount = player.getInventory().getAmount(bolt.base); - int tipAmount = player.getInventory().getAmount(bolt.tip); - Item base = new Item(bolt.base); - Item tip = new Item(bolt.tip); - Item product = new Item(bolt.product); - if(baseAmount >= 10 && tipAmount >= 10){ - base.setAmount(10); - tip.setAmount(10); - product.setAmount(10); - } else { - int amount = baseAmount > tipAmount ? tipAmount : baseAmount; - base.setAmount(amount); - tip.setAmount(amount); - product.setAmount(amount); - } - if (player.getInventory().remove(base,tip)) { - player.getInventory().add(product); - player.getSkills().addExperience(Skills.FLETCHING, bolt.experience * product.getAmount(), true); - player.getPacketDispatch().sendMessage(product.getAmount() == 1 ? "You attach the tip to the bolt." : "You fletch " + product.getAmount() + " bolts."); - } - sets--; - return sets <= 0; - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java b/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java deleted file mode 100644 index cbba3820f..000000000 --- a/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java +++ /dev/null @@ -1,85 +0,0 @@ -package content.global.skill.fletching.items.grapple; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the skill pulse used to create a mith grapple. - * @author 'Vexia - * @date 21/12/2013 - */ -public final class GrapplePulse extends SkillPulse { - - /** - * Represents the mith grapple tip. - */ - private static final Item MITH_GRAPPLE = new Item(9418); - - /** - * Represents the mithril grapple tio. - */ - private static final Item GRAPPLE_TIP = new Item(9416); - - /** - * Represents the mithril bolt. - */ - private static final Item MITHRIL_BOLT = new Item(9142); - - /** - * Represents the amount of the grapple to make. - */ - private int amount; - - /** - * Constructs a new {@code GrapplePulse} {@code Object}. - * @param player the player. - * @param node the node. - * @param amount the amount. - */ - public GrapplePulse(Player player, Item node, int amount) { - super(player, node); - this.amount = amount; - } - - @Override - public boolean checkRequirements() { - int inventoryAmount = player.getInventory().getAmount(GRAPPLE_TIP); - if (amount > inventoryAmount) { - amount = inventoryAmount; - } - if (!player.getInventory().containsItem(GRAPPLE_TIP) || !player.getInventory().containsItem(MITHRIL_BOLT)) { - return false; - } - if (player.getSkills().getLevel(Skills.FLETCHING) < 59) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of at least 59 in order to do this."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - setDelay(3); - return false; - } - if (player.getInventory().remove(GRAPPLE_TIP) && player.getInventory().remove(MITHRIL_BOLT)) { - player.getInventory().add(MITH_GRAPPLE); - player.getSkills().addExperience(Skills.FLETCHING, 5, true); - } - amount--; - return amount < 1; - } - - @Override - public void message(int type) { - - } - -} diff --git a/Server/src/main/content/global/skill/fletching/log/CraftItemWithLogScript.kt b/Server/src/main/content/global/skill/fletching/log/CraftItemWithLogScript.kt new file mode 100644 index 000000000..33e6c5524 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/CraftItemWithLogScript.kt @@ -0,0 +1,113 @@ +package content.global.skill.fletching.log + +import content.global.skill.fletching.AchievementDiaryAttributeKeys +import content.global.skill.fletching.Zones +import content.global.skill.fletching.log.GrammarHelpers.aOrAn +import content.global.skill.fletching.log.GrammarHelpers.makeFriendlyName +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items + +/** + * Represents the queueScript used to craft things by carving a log + * @author ceik + * @param player the player. + * @param logCraftInfo crafting info about what we're making out of the log + * @param amount iterations of craft to run + */ +class CraftItemWithLogScript( + private val player: Player, + private val logCraftInfo: LogCraftInfo, + private val amount: Int +) { + + private val initialDelay = 1 + + // src https://gitlab.com/2009scape/2009scape/-/merge_requests/1960#note_2702231552 + private val subsequentDelay = 3 + + private val carveLogAnimation = Animation(1248) + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < logCraftInfo.level) { + LogCraftableListeners.sendLevelCheckFailDialog(player, logCraftInfo) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + if (removeItem(player, logCraftInfo.logItemId.asItem())) { + player.animate(carveLogAnimation) + + val finishedItemName = makeFriendlyName(Item(logCraftInfo.finishedItemId).name) + + val amountToCraft = when (logCraftInfo) { + LogCraftInfo.OGRE_ARROW_SHAFT -> RandomFunction.random(2, 6) + LogCraftInfo.ARROW_SHAFT -> 15 + else -> 1 + } + + if (logCraftInfo == LogCraftInfo.OGRE_COMP_BOW) { + if (!removeItem(player, Items.WOLF_BONES_2859)) { + return@queueScript stopExecuting(player) + } + } + + sendCraftMessageToPlayer(amountToCraft, finishedItemName) + + addItem(player, logCraftInfo.finishedItemId, amountToCraft) + rewardXP(player, Skills.FLETCHING, logCraftInfo.experience) + + if (logCraftInfo == LogCraftInfo.MAGIC_SHORTBOW) { + handleSeersMagicShortbowAchievement() + } + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } + + private fun handleSeersMagicShortbowAchievement() { + if (Zones.inAnyZone(player, Zones.seersMagicShortbowAchievementZones) && + !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 2) + ) { + setAttribute( + player, + "/save:${AchievementDiaryAttributeKeys.FLETCHED_UNSTRUNG_MAGIC_SHORTBOW}", + true + ) + } + } + + private fun sendCraftMessageToPlayer(amountToCraft: Int, finishedItemName: String) { + when (logCraftInfo) { + LogCraftInfo.ARROW_SHAFT -> sendMessage( + player, + "You carefully cut the wood into $amountToCraft arrow shafts." + ) + + LogCraftInfo.OGRE_ARROW_SHAFT -> sendMessage( + player, + "You carefully cut the wood into $amountToCraft arrow shafts." + ) + + else -> sendMessage( + player, + "You carefully cut the wood into ${aOrAn(finishedItemName)} $finishedItemName." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/log/GrammarHelpers.kt b/Server/src/main/content/global/skill/fletching/log/GrammarHelpers.kt new file mode 100644 index 000000000..5863c51ea --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/GrammarHelpers.kt @@ -0,0 +1,20 @@ +package content.global.skill.fletching.log + +import core.tools.StringUtils + +object GrammarHelpers { + fun makeFriendlyName(name: String): String { + return name.replace("(u)", "").trim { it <= ' ' } + } + + /** + * Returns "a" or "an" depending on whether the word begins with a vowel + */ + @Suppress("GrazieInspection") + fun aOrAn(word: String): String { + return when (StringUtils.isPlusN(word)) { + true -> "an" + false -> "a" + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/log/LogCraftInfo.kt b/Server/src/main/content/global/skill/fletching/log/LogCraftInfo.kt new file mode 100644 index 000000000..2111606dc --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/LogCraftInfo.kt @@ -0,0 +1,63 @@ +package content.global.skill.fletching.log + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different items from logs + * @property logItemId the log item id that can be used to craft this item + * @property finishedItemId the resulting finished bolt Item id. + * @property level the level required to craft. + * @property experience the experience gained by crafting. + */ +enum class LogCraftInfo(val logItemId: Int, val finishedItemId: Int, val experience: Double, val level: Int) { + ARROW_SHAFT(Items.LOGS_1511, Items.ARROW_SHAFT_52, 5.0, 1), + SHORT_BOW(Items.LOGS_1511, Items.SHORTBOW_U_50, 5.0, 5), + LONG_BOW(Items.LOGS_1511, Items.LONGBOW_U_48, 10.0, 10), + WOODEN_STOCK(Items.LOGS_1511, Items.WOODEN_STOCK_9440, 6.0, 9), + + OGRE_ARROW_SHAFT(Items.ACHEY_TREE_LOGS_2862, Items.OGRE_ARROW_SHAFT_2864, 6.4, 5), + OGRE_COMP_BOW(Items.ACHEY_TREE_LOGS_2862, Items.UNSTRUNG_COMP_BOW_4825, 45.0, 30), + + OAK_SHORTBOW(Items.OAK_LOGS_1521, Items.OAK_SHORTBOW_U_54, 16.5, 20), + OAK_LONGBOW(Items.OAK_LOGS_1521, Items.OAK_LONGBOW_U_56, 25.0, 25), + OAK_STOCK(Items.OAK_LOGS_1521, Items.OAK_STOCK_9442, 16.0, 24), + + WILLOW_SHORTBOW(Items.WILLOW_LOGS_1519, Items.WILLOW_SHORTBOW_U_60, 33.3, 35), + WILLOW_LONGBOW(Items.WILLOW_LOGS_1519, Items.WILLOW_LONGBOW_U_58, 41.5, 40), + WILLOW_STOCK(Items.WILLOW_LOGS_1519, Items.WILLOW_STOCK_9444, 22.0, 39), + + MAPLE_SHORTBOW(Items.MAPLE_LOGS_1517, Items.MAPLE_SHORTBOW_U_64, 50.0, 50), + MAPLE_LONGBOW(Items.MAPLE_LOGS_1517, Items.MAPLE_LONGBOW_U_62, 58.3, 55), + MAPLE_STOCK(Items.MAPLE_LOGS_1517, Items.MAPLE_STOCK_9448, 32.0, 54), + + YEW_SHORTBOW(Items.YEW_LOGS_1515, Items.YEW_SHORTBOW_U_68, 67.5, 65), + YEW_LONGBOW(Items.YEW_LOGS_1515, Items.YEW_LONGBOW_U_66, 75.0, 70), + YEW_STOCK(Items.YEW_LOGS_1515, Items.YEW_STOCK_9452, 50.0, 69), + + MAGIC_SHORTBOW(Items.MAGIC_LOGS_1513, Items.MAGIC_SHORTBOW_U_72, 83.3, 80), + MAGIC_LONGBOW(Items.MAGIC_LOGS_1513, Items.MAGIC_LONGBOW_U_70, 91.5, 85), + + TEAK_STOCK(Items.TEAK_LOGS_6333, Items.TEAK_STOCK_9446, 27.0, 46), + + MAHOGANY_STOCK(Items.MAHOGANY_LOGS_6332, Items.MAHOGANY_STOCK_9450, 41.0, 61); + + + companion object { + val logIds: IntArray = LogCraftInfo.values().map { logCraftInfo: LogCraftInfo -> logCraftInfo.logItemId }.distinct().toIntArray() + + private val logCraftablesByLogId = associateCraftInfoByLogIds() + private fun associateCraftInfoByLogIds(): Map> { + val map = HashMap>() + + for (logId in logIds) { + map[logId] = LogCraftInfo.values().filter { logCraftInfo: LogCraftInfo -> logCraftInfo.logItemId == logId } + } + + return map + } + + fun forLogId(logId: Int): List? { + return logCraftablesByLogId[logId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/log/LogCraftableListeners.kt b/Server/src/main/content/global/skill/fletching/log/LogCraftableListeners.kt new file mode 100644 index 000000000..fde0d5ff4 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/LogCraftableListeners.kt @@ -0,0 +1,83 @@ +package content.global.skill.fletching.log + +import content.data.Quests +import content.global.skill.fletching.log.GrammarHelpers.aOrAn +import content.global.skill.fletching.log.GrammarHelpers.makeFriendlyName +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +@Suppress("unused") // Reflectively loaded +class LogCraftableListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.KNIFE_946, *LogCraftInfo.logIds) { player, knife, log -> + val applicableCraftInfosForLog = LogCraftInfo.forLogId(log.id) ?: return@onUseWith false + val craftableItems = + applicableCraftInfosForLog.map { logCraftable -> Item(logCraftable.finishedItemId) }.toTypedArray() + + val handler: SkillDialogueHandler = object : SkillDialogueHandler( + player, + SkillDialogue.forLength(applicableCraftInfosForLog.size), + *craftableItems + ) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements(applicableCraftInfosForLog[index])) return + CraftItemWithLogScript(player, applicableCraftInfosForLog[index], amount).invoke() + } + + private fun playerMeetsInitialRequirements(logCraftInfo: LogCraftInfo): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < logCraftInfo.level) { + sendLevelCheckFailDialog(player, logCraftInfo) + return false + } + if (logCraftInfo == LogCraftInfo.OGRE_ARROW_SHAFT && + !isQuestStarted(player, Quests.BIG_CHOMPY_BIRD_HUNTING) + ) { + sendDialogue(player, "You must have started ${Quests.BIG_CHOMPY_BIRD_HUNTING} to make those.") + return false + } + if (logCraftInfo == LogCraftInfo.OGRE_COMP_BOW) { + if (getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) { + sendMessage( + player, + "You must have started Zogre Flesh Eaters and asked Grish to string this." + ) + return false + } + if (amountInInventory(player, Items.WOLF_BONES_2859) < 1) { + sendMessage(player, "You need to have Wolf Bones in order to make this.") + return false + } + } + return true + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, log.id) + } + } + handler.open() + return@onUseWith true + } + } + + companion object { + fun sendLevelCheckFailDialog(player: Player, logCraftInfo: LogCraftInfo) { + val finishedItem = Item(logCraftInfo.finishedItemId) + val friendlyCraftedItemName = makeFriendlyName(finishedItem.name) + sendDialogue( + player, + "You need a Fletching skill of ${logCraftInfo.level} or above to make ${ + aOrAn( + friendlyCraftedItemName + ) + } $friendlyCraftedItemName." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/stringing/StringItemScript.kt b/Server/src/main/content/global/skill/fletching/stringing/StringItemScript.kt new file mode 100644 index 000000000..633e29667 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/stringing/StringItemScript.kt @@ -0,0 +1,71 @@ +package content.global.skill.fletching.stringing + +import content.global.skill.fletching.AchievementDiaryAttributeKeys +import content.global.skill.fletching.Zones +import content.global.skill.fletching.stringing.StringableCraftInfo.Companion.applicableStringId +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * Represents queueScript to string a bow/crossbow + * @author Ceikry + * @param player the player. + * @param stringableCraftInfo contains crafting information about what we're stringing + * @param amount the amount of items to string + */ +class StringItemScript( + private val player: Player, + private val stringableCraftInfo: StringableCraftInfo, + private var amount: Int +) { + private val initialDelay = 1 + private val subsequentDelay = 2 + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < stringableCraftInfo.level) { + StringingListeners.sendLevelCheckFailDialogue(player, stringableCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(stringableCraftInfo.unstrungItemId), + Item(stringableCraftInfo.applicableStringId) + ) + ) { + player.animate(stringableCraftInfo.animation) + + addItem(player, stringableCraftInfo.strungItemId, 1) + rewardXP(player, Skills.FLETCHING, stringableCraftInfo.experience) + sendMessage(player, "You add a string to the bow.") + if (stringableCraftInfo == StringableCraftInfo.MAGIC_SHORTBOW) { + handleSeersMagicShortbowAchievement() + } + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } + + private fun handleSeersMagicShortbowAchievement() { + if (Zones.inAnyZone(player, Zones.seersMagicShortbowAchievementZones) && + getAttribute(player, AchievementDiaryAttributeKeys.FLETCHED_UNSTRUNG_MAGIC_SHORTBOW, false) + ) { + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/stringing/StringableCraftInfo.kt b/Server/src/main/content/global/skill/fletching/stringing/StringableCraftInfo.kt new file mode 100644 index 000000000..38c089621 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/stringing/StringableCraftInfo.kt @@ -0,0 +1,66 @@ +package content.global.skill.fletching.stringing + +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different strung items + * @property isCrossbow is this enum for a crossbow? + * @property unstrungItemId the unstrung item Id + * @property strungItemId the resulting strung item Id + * @property level the level required to string the item + * @property experience experience gained from stringing + * @property animation the stringing animation to play + */ +enum class StringableCraftInfo( + val isCrossbow: Boolean, + val unstrungItemId: Int, + val strungItemId: Int, + val level: Int, + val experience: Double, + val animation: Animation +) { + SHORT_BOW(false, Items.SHORTBOW_U_50, Items.SHORTBOW_841, 5, 5.0, Animation(6678)), + LONG_BOW(false, Items.LONGBOW_U_48, Items.LONGBOW_839, 10, 10.0, Animation(6684)), + OAK_SHORTBOW(false, Items.OAK_SHORTBOW_U_54, Items.OAK_SHORTBOW_843, 20, 16.5, Animation(6679)), + OAK_LONGBOW(false, Items.OAK_LONGBOW_U_56, Items.OAK_LONGBOW_845, 25, 25.0, Animation(6685)), + OGRE_COMP_BOW(false, Items.UNSTRUNG_COMP_BOW_4825, Items.COMP_OGRE_BOW_4827, 30, 45.0, Animation(-1)), + WILLOW_SHORTBOW(false, Items.WILLOW_SHORTBOW_U_60, Items.WILLOW_SHORTBOW_849, 35, 33.3, Animation(6680)), + WILLOW_LONGBOW(false, Items.WILLOW_LONGBOW_U_58, Items.WILLOW_LONGBOW_847, 40, 41.5, Animation(6686)), + MAPLE_SHORTBOW(false, Items.MAPLE_SHORTBOW_U_64, Items.MAPLE_SHORTBOW_853, 50, 50.0, Animation(6681)), + MAPLE_LONGBOW(false, Items.MAPLE_LONGBOW_U_62, Items.MAPLE_LONGBOW_851, 55, 58.3, Animation(6687)), + YEW_SHORTBOW(false, Items.YEW_SHORTBOW_U_68, Items.YEW_SHORTBOW_857, 65, 67.5, Animation(6682)), + YEW_LONGBOW(false, Items.YEW_LONGBOW_U_66, Items.YEW_LONGBOW_855, 70, 75.0, Animation(6688)), + MAGIC_SHORTBOW(false, Items.MAGIC_SHORTBOW_U_72, Items.MAGIC_SHORTBOW_861, 80, 83.3, Animation(6683)), + MAGIC_LONGBOW(false, Items.MAGIC_LONGBOW_U_70, Items.MAGIC_LONGBOW_859, 85, 91.5, Animation(6689)), + + BRONZE_CBOW(true, Items.BRONZE_CBOW_U_9454, Items.BRONZE_CROSSBOW_9174, 9, 6.0, Animation(6671)), + BLURITE_CBOW(true, Items.BLURITE_CBOW_U_9456, Items.BLURITE_CROSSBOW_9176, 24, 16.0, Animation(6672)), + IRON_CBOW(true, Items.IRON_CBOW_U_9457, Items.IRON_CROSSBOW_9177, 39, 22.0, Animation(6673)), + STEEL_CBOW(true, Items.STEEL_CBOW_U_9459, Items.STEEL_CROSSBOW_9179, 46, 27.0, Animation(6674)), + MITHIRIL_CBOW(true, Items.MITHRIL_CBOW_U_9461, Items.MITH_CROSSBOW_9181, 54, 32.0, Animation(6675)), + ADAMANT_CBOW(true, Items.ADAMANT_CBOW_U_9463, Items.ADAMANT_CROSSBOW_9183, 61, 41.0, Animation(6676)), + RUNITE_CBOW(true, Items.RUNITE_CBOW_U_9465, Items.RUNE_CROSSBOW_9185, 69, 50.0, Animation(6677)); + + companion object { + val unstrungBowIds: IntArray = values().map { stringableCraftInfo: StringableCraftInfo -> stringableCraftInfo.unstrungItemId }.toIntArray() + val stringItemIds: IntArray = intArrayOf(Items.BOW_STRING_1777,Items.CROSSBOW_STRING_9438) + + private val stringableCraftInfoByUnstrungItemId = values().associateBy { it.unstrungItemId } + + fun forUnstrungBowItemId(unstrungItemId: Int): StringableCraftInfo? { + return stringableCraftInfoByUnstrungItemId[unstrungItemId] + } + + /** + * Returns the item id that should be used for stringing this enums unstrung bow + */ + val StringableCraftInfo.applicableStringId: Int + get() { + return when { + this.isCrossbow -> Items.CROSSBOW_STRING_9438 + else -> Items.BOW_STRING_1777 + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/stringing/StringingListeners.kt b/Server/src/main/content/global/skill/fletching/stringing/StringingListeners.kt new file mode 100644 index 000000000..051f8102b --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/stringing/StringingListeners.kt @@ -0,0 +1,69 @@ +package content.global.skill.fletching.stringing + +import content.data.Quests +import content.global.skill.fletching.stringing.StringableCraftInfo.Companion.applicableStringId +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Components + +@Suppress("unused") // Reflectively loaded +class StringingListeners : InteractionListener { + override fun defineListeners() { + onUseWith( + IntType.ITEM, + StringableCraftInfo.stringItemIds, + *StringableCraftInfo.unstrungBowIds + ) { player, string, unstrungBow -> + val stringableCraftInfo = StringableCraftInfo.forUnstrungBowItemId(unstrungBow.id) ?: return@onUseWith false + if (string.id != stringableCraftInfo.applicableStringId) { + sendMessage(player, "That's not the right kind of string for this.") + return@onUseWith true + } + if (stringableCraftInfo == StringableCraftInfo.OGRE_COMP_BOW && getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) { + sendMessage(player, "You must have started Zogre Flesh Eaters and asked Grish to string this.") + return@onUseWith true + } + val handler: SkillDialogueHandler = + object : + SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(stringableCraftInfo.strungItemId)) { + override fun create(amount: Int, index: Int) { + if (getDynLevel(player, Skills.FLETCHING) < stringableCraftInfo.level) { + sendLevelCheckFailDialogue(player, stringableCraftInfo.level) + return + } + StringItemScript(player, stringableCraftInfo, amount).invoke() + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, string.id) + } + } + handler.open() + fixSpacingBetweenTextAndCraftedItemIcon(player) + return@onUseWith true + } + } + + private fun fixSpacingBetweenTextAndCraftedItemIcon(player: Player) { + PacketRepository.send( + RepositionChild::class.java, + ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 215, 10) + ) + } + companion object { + fun sendLevelCheckFailDialogue(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level to string this bow." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/gather/SkillingResource.java b/Server/src/main/content/global/skill/gather/SkillingResource.java index 178f6679b..2d2b43e65 100644 --- a/Server/src/main/content/global/skill/gather/SkillingResource.java +++ b/Server/src/main/content/global/skill/gather/SkillingResource.java @@ -612,9 +612,6 @@ public enum SkillingResource { */ RUNITE_ORE_0(2107, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 452, Skills.MINING), RUNITE_ORE_1(2106, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 450, Skills.MINING), - RUNITE_ORE_2(6669, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 21296, Skills.MINING), - RUNITE_ORE_3(6671, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 21298, Skills.MINING), - RUNITE_ORE_4(6670, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 21297, Skills.MINING), RUNITE_ORE_5(14861, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 25373, Skills.MINING), RUNITE_ORE_6(14860, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 25372, Skills.MINING), RUNITE_ORE_7(14859, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 25371, Skills.MINING), @@ -632,7 +629,15 @@ public enum SkillingResource { */ GEM_ROCK_0(23567, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21297, Skills.MINING), GEM_ROCK_1(23566, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21296, Skills.MINING), - GEM_ROCK_2(23568, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21298, Skills.MINING); + GEM_ROCK_2(23568, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21298, Skills.MINING), + + /** + * Magic stone. + */ + MAGIC_STONE_0(6669, 20, 0.3, 100 | 200 << 16, 0.0, 4703, 1, "magic stone", null, 21296, Skills.MINING), + MAGIC_STONE_1(6671, 20, 0.3, 100 | 200 << 16, 0.0, 4703, 1, "magic stone", null, 21298, Skills.MINING), + MAGIC_STONE_2(6670, 20, 0.3, 100 | 200 << 16, 0.0, 4703, 1, "magic stone", null, 21297, Skills.MINING); + /** * The resources mapping. diff --git a/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt b/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt index 1cad8a28d..2f23e264c 100644 --- a/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt +++ b/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt @@ -152,7 +152,7 @@ class FishingListener : InteractionListener{ } return false } - return node.isActive && node.location.withinDistance(player.location, 1) + return node.isActive && node.location.withinMaxnormDistance(player.location, 1) } diff --git a/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt b/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt index ea254e311..3e309fb65 100644 --- a/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt +++ b/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt @@ -1,6 +1,5 @@ package content.global.skill.gather.fishing -import content.data.skill.SkillingPets import content.global.skill.fishing.Fish import content.global.skill.fishing.FishingOption import content.global.skill.skillcapeperks.SkillcapePerks @@ -124,13 +123,12 @@ class FishingPulse(player: Player?, npc: NPC, private val option: FishingOption? updateSkillTask() } player.dispatch(ResourceProducedEvent(fish!!.id, 1, node!!)) - SkillingPets.checkPetDrop(player, SkillingPets.HERON) val item = fish!! if (isActive(SkillcapePerks.GREAT_AIM, player) && RandomFunction.random(100) <= 5) { - addItem(player, item.id) + addItemOrDrop(player, item.id) player.sendMessage(colorize("%RYour expert aim catches you a second fish.")) } - addItem(player, item.id) + addItemOrDrop(player, item.id) var fishCaught = player.getAttribute(STATS_BASE + ":" + STATS_FISH, 0) player.setAttribute("/save:$STATS_BASE:$STATS_FISH", ++fishCaught) player.skills.addExperience(Skills.FISHING, fish!!.experience, true) diff --git a/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt b/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt index 2a66a2f1f..a44387209 100644 --- a/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt +++ b/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt @@ -48,6 +48,10 @@ class BarbFishingPulse(player: Player) : SkillPulse(player,NPC(1176)) { } override fun reward(): Boolean { + if (delay == 1){ + super.setDelay(5) + return false + } val stragiXP = arrayOf(5,6,7) val fishXP = arrayOf(50,70,80) val reward = getRandomFish() diff --git a/Server/src/main/content/global/skill/gather/mining/MiningListener.kt b/Server/src/main/content/global/skill/gather/mining/MiningListener.kt index d744b0a8f..ea9de8c49 100644 --- a/Server/src/main/content/global/skill/gather/mining/MiningListener.kt +++ b/Server/src/main/content/global/skill/gather/mining/MiningListener.kt @@ -1,6 +1,5 @@ package content.global.skill.gather.mining -import content.data.skill.SkillingPets import content.data.skill.SkillingTool import content.global.skill.skillcapeperks.SkillcapePerks import content.global.activity.shootingstar.StarBonus @@ -27,11 +26,11 @@ import org.rs09.consts.Items class MiningListener : InteractionListener { override fun defineListeners() { defineInteraction( - IntType.SCENERY, - MiningNode.values().map { it.id }.toIntArray(), - "mine", - persistent = true, allowedDistance = 1, - handler = ::handleMining + IntType.SCENERY, + MiningNode.values().map { it.id }.toIntArray(), + "mine", + persistent = true, allowedDistance = 1, + handler = ::handleMining ) } private val GEM_REWARDS = arrayOf(ChanceItem(1623, 1, DropFrequency.COMMON), ChanceItem(1621, 1, DropFrequency.COMMON), ChanceItem(1619, 1, DropFrequency.UNCOMMON), ChanceItem(1617, 1, DropFrequency.RARE)) @@ -39,25 +38,25 @@ class MiningListener : InteractionListener { private fun handleMining(player: Player, node: Node, state: Int) : Boolean { val resource = MiningNode.forId(node.id) val tool = SkillingTool.getPickaxe(player) - val isEssence = resource.id == 2491 + val isEssence = resource == MiningNode.RUNE_ESSENCE val isGems = resource.identifier == MiningNode.GEM_ROCK_0.identifier if (!finishedMoving(player)) return true if (state == 0) { - if (!checkRequirements(player, resource, node)) { - player.scripts.reset() - return true - } + if (!checkRequirements(player, resource, node)) { + player.scripts.reset() + return true + } anim(player, tool) - sendMessage(player, "You swing your pickaxe at the rock...") - return delayScript(player, getDelay(resource)) + sendMessage(player, "You swing your pickaxe at the rock.") + return delayScript(player, getDelay(resource, tool)) } anim(player, tool) if (!checkReward(player, resource, tool)) - return delayScript(player, getDelay(resource)) + return delayScript(player, getDelay(resource, tool)) // Reward logic var reward = resource!!.reward @@ -67,7 +66,6 @@ class MiningListener : InteractionListener { rewardAmount = calculateRewardAmount(player, isEssence, reward) // calculate amount player.dispatch(ResourceProducedEvent(reward, rewardAmount, node)) - SkillingPets.checkPetDrop(player, SkillingPets.GOLEM) // roll for pet // Reward mining experience val experience = resource!!.experience * rewardAmount @@ -96,20 +94,29 @@ class MiningListener : InteractionListener { if (reward == Items.GOLD_ORE_444 && inBorders(player, familyCrestGoldOreArea)) { reward = Items.PERFECT_GOLD_ORE_446 } - val rewardName = getItemName(reward).lowercase() + + // Prepare reward name - gems stay lowercase without "Uncut", others are lowercase + val rewardName = if (isGems) { + getItemName(reward).replace("Uncut ", "").lowercase() + } else { + getItemName(reward).substringBefore(" (").lowercase().removeSuffix(" ore") + } // Send the message for the resource reward if (isGems) { - sendMessage(player, "You get ${prependArticle(rewardName)}.") - } else { - sendMessage(player, "You get some ${rewardName.lowercase()}.") + val withArticle = prependArticle(rewardName) // "an emerald" or "a red topaz" + val parts = withArticle.split(" ", limit = 2) // ["an", "emerald"] or ["a", "red topaz"] + val article = parts[0] // "an" or "a" + val gemName = parts[1].replaceFirstChar { it.uppercase() } // "Emerald" or "Red topaz" + sendMessage(player, "You just mined $article $gemName!") + } else if (!isEssence) { + sendMessage(player, "You manage to mine some ${rewardName}.") } // Give the mining reward, increment 'rocks mined' attribute - if(addItem(player, reward, rewardAmount)) { - var rocksMined = getAttribute(player, "$STATS_BASE:$STATS_ROCKS", 0) - setAttribute(player, "/save:$STATS_BASE:$STATS_ROCKS", ++rocksMined) - } + addItemOrDrop(player, reward, rewardAmount) + var rocksMined = getAttribute(player, "$STATS_BASE:$STATS_ROCKS", 0) + setAttribute(player, "/save:$STATS_BASE:$STATS_ROCKS", rocksMined + rewardAmount) // Calculate bonus gem chance while mining if (!isEssence) { @@ -127,7 +134,7 @@ class MiningListener : InteractionListener { } if (RandomFunction.roll(chance)) { val gem = GEM_REWARDS.random() - sendMessage(player,"You find a ${gem.name}!") + sendMessage(player,"You just found ${prependArticle(gem.name.replace("Uncut ", "").lowercase())}!") if (freeSlots(player) == 0) { sendMessage(player,"You do not have enough space in your inventory, so you drop the gem on the floor.") } @@ -141,6 +148,14 @@ class MiningListener : InteractionListener { node.setActive(false) return true } + + // For essence, check inventory and continue mining + if (isEssence) { + if (freeSlots(player) == 0) { + return true + } + return delayScript(player, getDelay(resource, tool)) + } } return true } @@ -192,6 +207,10 @@ class MiningListener : InteractionListener { } private fun checkReward(player: Player, resource: MiningNode?, tool: SkillingTool): Boolean { + // Essence mining always succeeds + if (resource == MiningNode.RUNE_ESSENCE) { + return true + } val level = 1 + getDynLevel(player, Skills.MINING) + getFamiliarBoost(player, Skills.MINING) val hostRatio = Math.random() * (100.0 * resource!!.rate) var toolRatio = tool.ratio @@ -202,8 +221,20 @@ class MiningListener : InteractionListener { return hostRatio < clientRatio } - fun getDelay(resource: MiningNode) : Int { - return if (resource.id == 2491) 3 else 4 + fun getDelay(resource: MiningNode, tool: SkillingTool) : Int { + if (resource == MiningNode.RUNE_ESSENCE) { // Essence mining - speed varies by pickaxe + return when (tool) { + SkillingTool.BRONZE_PICKAXE -> 7 + SkillingTool.IRON_PICKAXE -> 6 + SkillingTool.STEEL_PICKAXE -> 5 + SkillingTool.MITHRIL_PICKAXE -> 4 + SkillingTool.ADAMANT_PICKAXE -> 3 + SkillingTool.RUNE_PICKAXE -> 2 + SkillingTool.INFERNO_ADZE2 -> if (RandomFunction.random(2) == 0) 1 else 2 //https://www.youtube.com/watch?v=9XhjSdJ4qro + else -> 4 // fallback + } + } + return 4 // normal rocks } fun anim(player: Player, tool: SkillingTool) { @@ -225,9 +256,13 @@ class MiningListener : InteractionListener { sendDialogue(player,"Your inventory is too full to hold any more gems.") return false } + if (resource == MiningNode.RUNE_ESSENCE) { + sendDialogue(player,"Your inventory is too full to hold any more essence.") + return false + } sendDialogue(player,"Your inventory is too full to hold any more ${ItemDefinition.forId(resource!!.reward).name.lowercase()}.") return false } return node.isActive } -} +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/gather/mining/MiningNode.java b/Server/src/main/content/global/skill/gather/mining/MiningNode.java index 5f7f00cf3..b271fdee2 100644 --- a/Server/src/main/content/global/skill/gather/mining/MiningNode.java +++ b/Server/src/main/content/global/skill/gather/mining/MiningNode.java @@ -403,9 +403,6 @@ public enum MiningNode{ //Runite RUNITE_ORE_0( 2107, 452, (byte) 12), RUNITE_ORE_1( 2106, 450, (byte) 12), - RUNITE_ORE_2( 6669, 21296, (byte) 12), - RUNITE_ORE_3( 6671, 21298, (byte) 12), - RUNITE_ORE_4( 6670, 21297, (byte) 12), RUNITE_ORE_5( 14861,25373, (byte) 12), RUNITE_ORE_6( 14860,25372, (byte) 12), RUNITE_ORE_7( 14859,25371, (byte) 12), @@ -437,8 +434,14 @@ public enum MiningNode{ GRANITE(10947,10945, (byte) 16), //Rubium? - RUBIUM(29746,29747, (byte) 17); + RUBIUM(29746,29747, (byte) 17), + //Magic stone (Tears of Guthix) + MAGIC_STONE_0( 6669, 21296, (byte) 18), // Was mistaken for RUNITE_ORE_2 + MAGIC_STONE_1( 6671, 21298, (byte) 18), // Was mistaken for RUNITE_ORE_3 + MAGIC_STONE_2( 6670, 21297, (byte) 18), // Was mistaken for RUNITE_ORE_4 + + ; public static List gemRockGems = new ArrayList<>(20); @@ -573,6 +576,13 @@ public enum MiningNode{ reward = 12630; level = 46; break; + case 18: + respawnRate = 100 | 200 << 16; + experience = 0.0; + rate = 0.3; + reward = 4703; + level = 20; + break; } } private static HashMap NODE_MAP = new HashMap<>(); diff --git a/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt b/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt index aa7ef70e6..4c26fac4d 100644 --- a/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt +++ b/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt @@ -3,7 +3,6 @@ package content.global.skill.gather.mining import core.api.* import core.game.event.ResourceProducedEvent import core.cache.def.impl.ItemDefinition -import content.data.skill.SkillingPets import core.game.node.Node import core.game.node.entity.impl.Animator import core.game.node.entity.npc.drop.DropFrequency @@ -11,6 +10,7 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills import content.data.skill.SkillingTool +import content.global.activity.shootingstar.StarBonus import content.global.skill.skillcapeperks.SkillcapePerks import core.game.node.item.ChanceItem import core.game.node.scenery.Scenery @@ -131,7 +131,6 @@ class MiningSkillPulse(private val player: Player, private val node: Node) : Pul rewardAmount = calculateRewardAmount(reward) // calculate amount player.dispatch(ResourceProducedEvent(reward, rewardAmount, node)) - SkillingPets.checkPetDrop(player, SkillingPets.GOLEM) // roll for pet // Reward mining experience val experience = resource!!.experience * rewardAmount @@ -164,10 +163,9 @@ class MiningSkillPulse(private val player: Player, private val node: Node) : Pul } // Give the mining reward, increment 'rocks mined' attribute - if(addItem(player, reward, rewardAmount)) { - var rocksMined = getAttribute(player, "$STATS_BASE:$STATS_ROCKS", 0) - setAttribute(player, "/save:$STATS_BASE:$STATS_ROCKS", ++rocksMined) - } + addItemOrDrop(player, reward, rewardAmount) + var rocksMined = getAttribute(player, "$STATS_BASE:$STATS_ROCKS", 0) + setAttribute(player, "/save:$STATS_BASE:$STATS_ROCKS", rocksMined + rewardAmount) // Calculate bonus gem chance while mining if (!isMiningEssence) { @@ -225,7 +223,7 @@ class MiningSkillPulse(private val player: Player, private val node: Node) : Pul } // If player has mining boost from Shooting Star, roll chance at extra ore - if (player.hasActiveState("shooting-star")) { + if (hasTimerActive(player)) { if (RandomFunction.getRandom(5) == 3) { sendMessage(player, "...you manage to mine a second ore thanks to the Star Sprite.") amount += 1 diff --git a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt index 4f7c9276f..5a4a137b8 100644 --- a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt +++ b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt @@ -1,9 +1,10 @@ package content.global.skill.gather.woodcutting -import content.data.skill.SkillingPets +import content.data.Quests import content.data.skill.SkillingTool import content.data.tables.BirdNest import content.global.skill.farming.FarmingPatch.Companion.forObject +import content.global.skill.farming.timers.StumpGrowth import content.global.skill.firemaking.Log import content.global.skill.skillcapeperks.SkillcapePerks import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive @@ -49,7 +50,7 @@ class WoodcuttingListener : InteractionListener { defineInteraction( IntType.SCENERY, ids = WoodcuttingNode.values().map { it.id }.toIntArray(), - "chop-down", "chop", "chop down", "cut down", + "chop-down", "chop", "chop down", "cut down", "cut-branch", persistent = true, allowedDistance = 1, handler = ::handleWoodcutting @@ -72,7 +73,18 @@ class WoodcuttingListener : InteractionListener { if (clockReady(player, Clocks.SKILLING)) { animateWoodcutting(player) - if (!checkReward(player, resource, tool)) + + if (resource in arrayOf(WoodcuttingNode.DRAMEN_TREE, WoodcuttingNode.SWAYING_TREE)) { + // Reward after one chop and then abort chopping (this is authentic) + queueScript(player, 1, QueueStrength.STRONG) { + sendMessage(player, "You cut a branch from the ${if (resource == WoodcuttingNode.DRAMEN_TREE) "Dramen" else "strangely musical"} tree.") + addItem(player, resource.getReward()) + return@queueScript clearScripts(player) + } + return delayClock(player, Clocks.SKILLING, 1) + } + + if (!checkReward(player, resource, tool) && !getAttribute(player, "instachop", false)) return delayClock(player, Clocks.SKILLING, 3) val reward = resource.getReward() @@ -93,7 +105,9 @@ class WoodcuttingListener : InteractionListener { ).send() //add woodcutting experience - player.getSkills().addExperience(Skills.WOODCUTTING, resource.getExperience()) + rewardAmount = calculateRewardAmount(player, reward) // calculate amount + val experience: Double = calculateExperience(player, resource, rewardAmount) + player.getSkills().addExperience(Skills.WOODCUTTING, experience, true) //nullcheck the fire, and only if it exists award the firemaking XP val fire = Log.forId(reward) @@ -107,16 +121,13 @@ class WoodcuttingListener : InteractionListener { if (reward > 0) { rewardAmount = calculateRewardAmount(player, reward) // calculate amount - SkillingPets.checkPetDrop(player, SkillingPets.BEAVER) // roll for pet //add experience val experience: Double = calculateExperience(player, resource, rewardAmount) player.getSkills().addExperience(Skills.WOODCUTTING, experience, true) //send the message for the resource reward - if (resource == WoodcuttingNode.DRAMEN_TREE) { - player.packetDispatch.sendMessage("You cut a branch from the Dramen tree.") - } else if (reward == Items.BARK_3239 && rewardAmount == 0) { + if (reward == Items.BARK_3239 && rewardAmount == 0) { player.packetDispatch.sendMessage("You chop away some bark, but it falls to pieces before you can pick it up.") } else { player.packetDispatch.sendMessage("You get some " + ItemDefinition.forId(reward).name.lowercase(Locale.getDefault()) + ".") @@ -156,7 +167,7 @@ class WoodcuttingListener : InteractionListener { //OSRS: https://oldschool.runescape.wiki/w/Woodcutting scroll down to the mechanics section //RS3 : https://runescape.wiki/w/Woodcutting scroll down to the mechanics section, and expand the tree felling chances table if (resource.getRespawnRate() > 0) { - if (RandomFunction.roll(8) || resource.identifier.toInt() == 1 || resource.identifier.toInt() == 2 || resource.identifier.toInt() == 3 || resource.identifier.toInt() == 6) { + if (RandomFunction.roll(8) || listOf(1, 2, 3, 4, 6).contains(resource.identifier.toInt()) || getAttribute(player, "instachop", false)){ if (resource.isFarming()) { val fPatch = forObject(node.asScenery()) if (fPatch != null) { @@ -168,6 +179,8 @@ class WoodcuttingListener : InteractionListener { node.isActive = true return@queueScript stopExecuting(player) } + val stumps = getOrStartTimer (player) + stumps.addStump(fPatch.varbit, resource.respawnDuration) } return true } @@ -226,6 +239,10 @@ class WoodcuttingListener : InteractionListener { player.packetDispatch.sendMessage("You do not have an axe to use.") return false } + if (node.id == org.rs09.consts.Scenery.DRAMEN_TREE_1292 && getQuestStage(player, Quests.LOST_CITY) <= 20) { + //TODO: find out if there is any authentic message to be shown + return false + } if (player.inventory.freeSlots() < 1 && node.isActive) { player.sendMessage("Your inventory is too full to hold any more " + ItemDefinition.forId(resource.getReward()).name.lowercase(Locale.getDefault()) + ".") return false @@ -253,7 +270,7 @@ class WoodcuttingListener : InteractionListener { var amount = amount var experience: Double = resource.getExperience() val reward = resource.reward - if (player.getLocation().getRegionId() == 10300) { + if (player.getLocation().regionId == 10300) { return 1.0 } diff --git a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java index 70bd09d38..d69c7fea1 100644 --- a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java +++ b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java @@ -8,7 +8,6 @@ import core.game.event.ResourceProducedEvent; import core.cache.def.impl.ItemDefinition; import core.game.container.impl.EquipmentContainer; import core.game.dialogue.FacialExpression; -import content.data.skill.SkillingPets; import core.game.node.entity.impl.Animator; import core.game.node.entity.impl.Projectile; import core.game.node.entity.player.Player; @@ -157,20 +156,14 @@ public class WoodcuttingSkillPulse extends Pulse { if (reward > 0) { reward = calculateReward(reward); // calculate rewards rewardAmount = calculateRewardAmount(reward); // calculate amount - SkillingPets.checkPetDrop(player, SkillingPets.BEAVER); // roll for pet //add experience double experience = calculateExperience(resource.reward, rewardAmount); player.getSkills().addExperience(Skills.WOODCUTTING, experience, true); - //send the message for the resource reward, and in the case of the dramen tree, authentically abort the chopping action - if (resource == WoodcuttingNode.DRAMEN_TREE) { - player.getPacketDispatch().sendMessage("You cut a branch from the Dramen tree."); - stop(); - } else { - player.getPacketDispatch().sendMessage("You get some " + ItemDefinition.forId(reward).getName().toLowerCase() + "."); - } + //send the message for the resource reward + player.getPacketDispatch().sendMessage("You get some " + ItemDefinition.forId(reward).getName().toLowerCase() + "."); //give the reward player.getInventory().add(new Item(reward, rewardAmount)); player.dispatch(new ResourceProducedEvent(reward, rewardAmount, node, -1)); @@ -204,7 +197,7 @@ public class WoodcuttingSkillPulse extends Pulse { if (resource.isFarming()) { FarmingPatch fPatch = FarmingPatch.forObject(node.asScenery()); if(fPatch != null) { - Patch patch = fPatch.getPatchFor(player); + Patch patch = fPatch.getPatchFor(player, true); patch.setCurrentState(patch.getCurrentState() + 1); } return true; diff --git a/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt b/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt index 5876c4018..ce8e7202e 100644 --- a/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt +++ b/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt @@ -6,7 +6,7 @@ package content.global.skill.herblore; * @author treevar */ public enum class BarbarianPotion { - ATTACK_POTION(123, 4, 11429, 8.0, true), ANTI_POISION_POTION(177, 6, 11433, 12.0, true), RELIC(4846, 9, 11437, 14.0, true), STRENGTH_POTION(117, 14, 11443, 17.0, true), RESTORE_POTION(129, 24, 11449, 21.0, true), ENERGY_POTION(3012, 29, 11453, 23.0, false), DEFENCE_POTION(135, 33, 11457, 25.0, false), AGILITY_POTION(3036, 37, 11461, 27.0, false), COMBAT_POTION(9743, 40, 11445, 28.0, false), PRAYER_POTION(141, 42, 11465, 29.0, false), SUPER_ATTACK_POTION(147, 47, 11469, 33.0, false), SUPER_ANTIPOISION_POTION(183, 51, 11473, 35.0, false), FISHING_POTION(153, 53, 11477, 38.0, false), SUPER_ENERGY_POTION(3020, 56, 11481, 42.0, false), HUNTER_POTION(10002, 58, 11517, 40.0, false), SUPER_STRENGTH_POTION(159, 59, 11485, 42.0, false), SUPER_RESTORE(3028, 67, 11493, 48.0, false), SUPER_DEFENCE_POTION(165, 71, 11497, 50.0, false), ANTIDOTE_PLUS(5947, 74, 11501, 52.0, false), ANTIFIRE_POTION(2456, 75, 11505, 53.0, false), RANGING_POTION(171, 80, 11509, 54.0, false), MAGIC_POTION(3044, 83, 11513, 57.0, false), ZAMORAK_BREW(191, 85, 11521, 58.0, false); + ATTACK_POTION(123, 4, 11429, 8.0, true), ANTI_POISION_POTION(177, 6, 11433, 12.0, true), RELIC(4846, 9, 11437, 14.0, true), STRENGTH_POTION(117, 14, 11443, 17.0, true), RESTORE_POTION(129, 24, 11449, 21.0, true), ENERGY_POTION(3012, 29, 11453, 23.0, false), DEFENCE_POTION(135, 33, 11457, 25.0, false), AGILITY_POTION(3036, 37, 11461, 27.0, false), COMBAT_POTION(9743, 40, 11445, 28.0, false), PRAYER_POTION(141, 42, 11465, 29.0, false), SUPER_ATTACK_POTION(147, 47, 11469, 33.0, false), SUPER_ANTIPOISION_POTION(183, 51, 11473, 35.0, false), FISHING_POTION(153, 53, 11477, 38.0, false), SUPER_ENERGY_POTION(3020, 56, 11481, 42.0, false), HUNTER_POTION(10002, 58, 11517, 40.0, false), SUPER_STRENGTH_POTION(159, 59, 11485, 42.0, false), MAGIC_ESSENCE_POTION(9023, 61, 11489, 43.0, false), SUPER_RESTORE(3028, 67, 11493, 48.0, false), SUPER_DEFENCE_POTION(165, 71, 11497, 50.0, false), ANTIDOTE_PLUS(5947, 74, 11501, 52.0, false), ANTIFIRE_POTION(2456, 75, 11505, 53.0, false), RANGING_POTION(171, 80, 11509, 54.0, false), MAGIC_POTION(3044, 83, 11513, 57.0, false), ZAMORAK_BREW(191, 85, 11521, 58.0, false); /** * Constructs a new {@code BarbarianPotion} {@Code Object}. diff --git a/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt b/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt index ec9cd70c4..b87ead3f4 100644 --- a/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt +++ b/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt @@ -61,8 +61,7 @@ class GrindItemPlugin : UseWithHandler(233) { override fun reward(): Boolean { if (node.id == Items.FISHING_BAIT_313) { - var quantity = 0 - quantity = if (amountInInventory(player, FISHING_BAIT) >= 10) { + val quantity: Int = if (amountInInventory(player, FISHING_BAIT) >= 10) { 10 } else { amountInInventory(player, FISHING_BAIT) diff --git a/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt b/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt index 7ba8cfe5a..6807e5d9e 100644 --- a/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt +++ b/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt @@ -6,6 +6,7 @@ import core.game.interaction.InteractionListener import core.game.node.entity.skill.Skills import core.game.node.item.Item import java.util.* +import content.data.Quests /** * Dirty herb cleaning listener @@ -15,7 +16,7 @@ class HerbCleanListener : InteractionListener { override fun defineListeners() { on(IntType.ITEM, "clean") { player, node -> lock(player, 1) - if (!requireQuest(player, "Druidic Ritual", "before you can use Herblore.")) return@on true + if (!requireQuest(player, Quests.DRUIDIC_RITUAL, "before you can use Herblore.")) return@on true val herb: Herbs = Herbs.forItem(node as Item) ?: return@on true if (getDynLevel(player, Skills.HERBLORE) < herb.level) { diff --git a/Server/src/main/content/global/skill/herblore/HerbTarPulse.java b/Server/src/main/content/global/skill/herblore/HerbTarPulse.java index 45793be82..247f69f62 100644 --- a/Server/src/main/content/global/skill/herblore/HerbTarPulse.java +++ b/Server/src/main/content/global/skill/herblore/HerbTarPulse.java @@ -5,6 +5,7 @@ import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; import core.game.node.item.Item; import core.game.world.update.flag.context.Animation; +import content.data.Quests; /** * Represents the pulse used to create herb tars. @@ -52,7 +53,7 @@ public final class HerbTarPulse extends SkillPulse { @Override public boolean checkRequirements() { - if (!player.getQuestRepository().isComplete("Druidic Ritual")) { + if (!player.getQuestRepository().isComplete(Quests.DRUIDIC_RITUAL)) { player.getPacketDispatch().sendMessage("You must complete the Druidic Ritual quest before you can use Herblore."); return false; } diff --git a/Server/src/main/content/global/skill/herblore/HerblorePulse.java b/Server/src/main/content/global/skill/herblore/HerblorePulse.java index fbf1a8c73..0f859ad23 100644 --- a/Server/src/main/content/global/skill/herblore/HerblorePulse.java +++ b/Server/src/main/content/global/skill/herblore/HerblorePulse.java @@ -12,6 +12,7 @@ import core.tools.RandomFunction; import org.rs09.consts.Sounds; import static core.api.ContentAPIKt.playAudio; +import content.data.Quests; /** @@ -69,7 +70,7 @@ public final class HerblorePulse extends SkillPulse { @Override public boolean checkRequirements() { - if (!player.getQuestRepository().isComplete("Druidic Ritual")) { + if (!player.getQuestRepository().isComplete(Quests.DRUIDIC_RITUAL)) { player.getPacketDispatch().sendMessage("You must complete the Druidic Ritual quest before you can use Herblore."); return false; } diff --git a/Server/src/main/content/global/skill/herblore/Herbs.java b/Server/src/main/content/global/skill/herblore/Herbs.java index 5ee4959eb..4226fb436 100644 --- a/Server/src/main/content/global/skill/herblore/Herbs.java +++ b/Server/src/main/content/global/skill/herblore/Herbs.java @@ -7,7 +7,7 @@ import core.game.node.item.Item; * @author 'Vexia */ public enum Herbs { - GUAM(new Item(199), 2.5, 3, new Item(249)), MARRENTILL(new Item(201), 3.8, 5, new Item(251)), TARROMIN(new Item(203), 5, 11, new Item(253)), HARRALANDER(new Item(205), 6.3, 20, new Item(255)), RANARR(new Item(207), 7.5, 25, new Item(257)), TOADFLAX(new Item(3049), 8, 30, new Item(2998)), SPIRIT_WEED(new Item(12174), 7.8, 35, new Item(12172)), IRIT(new Item(209), 8.8, 40, new Item(259)), AVANTOE(new Item(211), 10, 48, new Item(261)), KWUARM(new Item(213), 11.3, 54, new Item(263)), SNAPDRAGON(new Item(3051), 11.8, 59, new Item(3000)), CADANTINE(new Item(215), 12.5, 65, new Item(265)), LANTADYME(new Item(2485), 13.1, 67, new Item(2481)), DWARF_WEED(new Item(217), 13.8, 70, new Item(267)), TORSTOL(new Item(219), 15, 75, new Item(269)), SNAKE_WEED(new Item(1525), 2.5, 3, new Item(1526)), ARDRIGAL(new Item(1527), 2.5, 3, new Item(1528)), SITO_FOIL(new Item(1529), 2.5, 3, new Item(1530)), VOLENCIA_MOSS(new Item(1531), 2.5, 3, new Item(1532)), ROGUES_PUSE(new Item(1533), 2.5, 3, new Item(1534)); + GUAM(new Item(199), 2.5, 3, new Item(249)), MARRENTILL(new Item(201), 3.8, 5, new Item(251)), TARROMIN(new Item(203), 5, 11, new Item(253)), HARRALANDER(new Item(205), 6.3, 20, new Item(255)), RANARR(new Item(207), 7.5, 25, new Item(257)), TOADFLAX(new Item(3049), 8, 30, new Item(2998)), SPIRIT_WEED(new Item(12174), 7.8, 35, new Item(12172)), IRIT(new Item(209), 8.8, 40, new Item(259)), AVANTOE(new Item(211), 10, 48, new Item(261)), KWUARM(new Item(213), 11.3, 54, new Item(263)), SNAPDRAGON(new Item(3051), 11.8, 59, new Item(3000)), CADANTINE(new Item(215), 12.5, 65, new Item(265)), LANTADYME(new Item(2485), 13.1, 67, new Item(2481)), DWARF_WEED(new Item(217), 13.8, 70, new Item(267)), TORSTOL(new Item(219), 15, 75, new Item(269)), SNAKE_WEED(new Item(1525), 2.5, 3, new Item(1526)), ARDRIGAL(new Item(1527), 2.5, 3, new Item(1528)), SITO_FOIL(new Item(1529), 2.5, 3, new Item(1530)), VOLENCIA_MOSS(new Item(1531), 2.5, 3, new Item(1532)), ROGUES_PURSE(new Item(1533), 2.5, 3, new Item(1534)); /** * Represents the herb item. diff --git a/Server/src/main/content/global/skill/herblore/Tars.java b/Server/src/main/content/global/skill/herblore/Tars.java index 06484ee60..c63d783bc 100644 --- a/Server/src/main/content/global/skill/herblore/Tars.java +++ b/Server/src/main/content/global/skill/herblore/Tars.java @@ -1,13 +1,18 @@ package content.global.skill.herblore; import core.game.node.item.Item; +import org.rs09.consts.Items; /** * Represents a tar to create. * @author 'Vexia */ public enum Tars { - GUAM_TAR(Herbs.GUAM.getProduct(), 19, 30, new Item(10142)), MARRENTILL_TAR(Herbs.MARRENTILL.getProduct(), 31, 42.5, new Item(10143)), TARROMIN_TAR(Herbs.TARROMIN.getProduct(), 39, 55, new Item(10144)), HARRALANDER_TAR(Herbs.HARRALANDER.getProduct(), 44, 72.5, new Item(10145)); + GUAM_TAR(Herbs.GUAM.getProduct(), 19, 30, new Item(10142)), + GROUND_GUAM_TAR(new Item(Items.GROUND_GUAM_6681), 19, 30, new Item(10142)), + MARRENTILL_TAR(Herbs.MARRENTILL.getProduct(), 31, 42.5, new Item(10143)), + TARROMIN_TAR(Herbs.TARROMIN.getProduct(), 39, 55, new Item(10144)), + HARRALANDER_TAR(Herbs.HARRALANDER.getProduct(), 44, 72.5, new Item(10145)); /** * Represents the ingredient. diff --git a/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java b/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java index 699a03b74..aa6e48d27 100644 --- a/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java +++ b/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java @@ -9,6 +9,7 @@ import core.game.node.item.Item; public enum UnfinishedPotion { GUAM(Herbs.GUAM.getProduct(), 3, new Item(91)), MARRENTILL(Herbs.MARRENTILL.getProduct(), 5, new Item(93)), + ROGUES_PURSE(Herbs.ROGUES_PURSE.getProduct(), 5, new Item(4840)), TARROMIN(Herbs.TARROMIN.getProduct(), 12, new Item(95)), HARRALANDER(Herbs.HARRALANDER.getProduct(), 22, new Item(97)), RANARR(Herbs.RANARR.getProduct(), 30, new Item(99)), diff --git a/Server/src/main/content/global/skill/hunter/NetTrapNode.kt b/Server/src/main/content/global/skill/hunter/NetTrapNode.kt new file mode 100644 index 000000000..43b9fdad5 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/NetTrapNode.kt @@ -0,0 +1,25 @@ +package content.global.skill.hunter + +import core.api.getStatLevel +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * Handles the net trap node. + */ +class NetTrapNode( + npcIds: IntArray, + level: Int, + experience: Double, + rewards: Array, + private val summoningLevel: Int +) : TrapNode(npcIds, level, experience, intArrayOf(), rewards) { + + override fun canCatch(wrapper: TrapWrapper, npc: NPC): Boolean { + if (getStatLevel(wrapper.player, Skills.SUMMONING) < summoningLevel) { + return false + } + return super.canCatch(wrapper, npc) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java b/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java index 0492f937b..8d3493c28 100644 --- a/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java +++ b/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java @@ -1,6 +1,5 @@ package content.global.skill.hunter; -import content.data.skill.SkillingPets; import core.game.node.entity.skill.SkillPulse; import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; @@ -95,13 +94,6 @@ public final class TrapDismantlePulse extends SkillPulse { if (wrapper.getType().getSettings().clear(wrapper, 1)) { instance.deregister(wrapper); if (wrapper.isCaught()) { - if (wrapper.getType().equals(Traps.BOX_TRAP)) { - for (int i : wrapper.getReward().getNpcIds()) { - if (i == 5080 || i == 5079) { - SkillingPets.checkPetDrop(player, i == 5080 ? SkillingPets.BABY_RED_CHINCHOMPA : SkillingPets.BABY_GREY_CHINCHOMPA); - } - } - } player.getSkills().addExperience(Skills.HUNTER, wrapper.getReward().getExperience(), true); } player.getPacketDispatch().sendMessage("You dismantle the trap."); diff --git a/Server/src/main/content/global/skill/hunter/TrapNode.java b/Server/src/main/content/global/skill/hunter/TrapNode.java index ad8608779..d2cc48e01 100644 --- a/Server/src/main/content/global/skill/hunter/TrapNode.java +++ b/Server/src/main/content/global/skill/hunter/TrapNode.java @@ -1,6 +1,5 @@ package content.global.skill.hunter; -import content.data.skill.SkillingPets; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.skill.Skills; @@ -123,8 +122,4 @@ public class TrapNode { return objectIds; } - public SkillingPets getPet() { - return null; - } - } diff --git a/Server/src/main/content/global/skill/hunter/Traps.java b/Server/src/main/content/global/skill/hunter/Traps.java index f2151d660..f0cec6d54 100644 --- a/Server/src/main/content/global/skill/hunter/Traps.java +++ b/Server/src/main/content/global/skill/hunter/Traps.java @@ -9,6 +9,8 @@ import core.tools.Log; import core.tools.SystemLogger; import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; +import org.rs09.consts.NPCs; import java.util.ArrayList; import java.util.List; @@ -33,16 +35,30 @@ public enum Traps { } }), BOX_TRAP(new TrapSetting(10008, new int[] { 19187 }, new int[] { 1963, 12579, 1869, 9996, 5972, 12535 }, "lay", 19192, Animation.create(5208), new Animation(9726), 27), - new BoxTrapNode(new int[] { 5081 }, 27, 100, new Item[] { new Item(10092) }, 1), - new BoxTrapNode(new int[] { 6918, 7289, 7290, 7291, 7292 }, 27, 100, new Item[] { new Item(12184) }, 10), - new BoxTrapNode(new int[] { 1487 }, 27, 100, new Item[] { new Item(4033, 1) }, 95), - new BoxTrapNode(new int[] { 7021, 7022, 7023 }, 48, 150, new Item[] { new Item(12551, 1) }, 1), - new BoxTrapNode(new int[] { 5079 }, 53, 198, new Item[] { new Item(10033, 1) }, 1), - new BoxTrapNode(new int[] { 5428, 5430, 5449, 5450, 5451 }, 56, 150, new Item[] { new Item(12188) }, 1), - new BoxTrapNode(new int[] { 5080 }, 63, 265, new Item[] { new Item(10034, 1) }, 1), - new BoxTrapNode(new int[] { 7012, 7014 }, 66, 400, new Item[] { new Item(12535) }, 1), - new BoxTrapNode(new int[] { 8654 }, 73, 315, new Item[] { new Item(14861) }, 1), - new BoxTrapNode(new int[] { 7010, 7011 }, 77, 0, new Item[] { new Item(12539, 1) }, 1) { + new BoxTrapNode(new int[] { 5081 }, 27, 100, new Item[] { new Item(10092) }, 1), // Ferret + new BoxTrapNode(new int[] {NPCs.BABY_GECKO_6917 }, 27, 100, new Item[] { new Item(Items.BABY_GECKO_12488) }, 10), // Gecko Orange + new BoxTrapNode(new int[] {NPCs.BABY_GECKO_7285 }, 27, 100, new Item[] { new Item(Items.BABY_GECKO_12738) }, 10), // Gecko Speckled + new BoxTrapNode(new int[] {NPCs.BABY_GECKO_7286 }, 27, 100, new Item[] { new Item(Items.BABY_GECKO_12739) }, 10), // Gecko Green + new BoxTrapNode(new int[] {NPCs.BABY_GECKO_7287 }, 27, 100, new Item[] { new Item(Items.BABY_GECKO_12740) }, 10), // Gecko Blue + new BoxTrapNode(new int[] {NPCs.BABY_GECKO_7288 }, 27, 100, new Item[] { new Item(Items.BABY_GECKO_12741) }, 10), // Gecko Red + new BoxTrapNode(new int[] {NPCs.BABY_RACCOON_6997 }, 27, 100, new Item[] { new Item(Items.BABY_RACCOON_12486) }, 80), // Raccoon Gray + new BoxTrapNode(new int[] {NPCs.BABY_RACCOON_7275 }, 27, 100, new Item[] { new Item(Items.BABY_RACCOON_12734) }, 80), // Raccoon Tan + new BoxTrapNode(new int[] {NPCs.BABY_RACCOON_7276 }, 27, 100, new Item[] { new Item(Items.BABY_RACCOON_12736) }, 80), // Raccoon Red + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_6944 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12496) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7228 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12682) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7229 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12684) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7230 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12686) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7231 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12688) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7232 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12690) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7233 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12692) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7234 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12694) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7235 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12696) }, 95), // Monkey + new BoxTrapNode(new int[] { NPCs.BABY_MONKEY_7236 }, 27, 100, new Item[] { new Item(Items.BABY_MONKEY_12698) }, 95), // Monkey + new BoxTrapNode(new int[] { 7021, 7022, 7023 }, 48, 150, new Item[] { new Item(12551, 1) }, 1), // Platypus + new BoxTrapNode(new int[] { 5079 }, 53, 198, new Item[] { new Item(10033, 1) }, 1), // Chinchompa + new BoxTrapNode(new int[] { 5080 }, 63, 265, new Item[] { new Item(10034, 1) }, 1), // Red Chinchompa + new BoxTrapNode(new int[] { 7012, 7014 }, 66, 400, new Item[] { new Item(12535) }, 1), // Pawya + new BoxTrapNode(new int[] { 7010, 7011 }, 77, 0, new Item[] { new Item(12539, 1) }, 1) { // Grenwall @Override public boolean canCatch(TrapWrapper wrapper, final NPC npc) { //old xp: 726 @@ -59,11 +75,16 @@ public enum Traps { new TrapNode(new int[] { 5086 }, 37, 204, new int[] { 19208, 19208, 19217 }, new Item[] { new Item(10105), new Item(526) }), new TrapNode(new int[] { 7039 }, 44, 200, new int[] { 28939, 28940, 28941 }, new Item[] { new Item(12567), new Item(526) }), new TrapNode(new int[] { 5087 }, 51, 200, new int[] { 19209, 19210, 19216 }, new Item[] { new Item(10109), new Item(526) })), - NET_TRAP(new NetTrapSetting(), new TrapNode(new int[] { 5117 }, 29, 152, new int[] {}, new Item[] { new Item(10149) }), - new TrapNode(new int[] { 5114 }, 47, 224, new int[] {}, new Item[] { new Item(10146) }), - new TrapNode(new int[] { 6921 }, 29, 152, new int[] {}, new Item[] { new Item(12130) }), - new TrapNode(new int[] { 5115 }, 59, 272, new int[] {}, new Item[] { new Item(10147) }), - new TrapNode(new int[] { 5116 }, 67, 304, new int[] {}, new Item[] { new Item(10148) })); + NET_TRAP(new NetTrapSetting(), + new NetTrapNode(new int[] { 5117 }, 29, 152, new Item[] { new Item(10149) }, 1), // Swamp Lizard + new NetTrapNode(new int[] { 5114 }, 47, 224, new Item[] { new Item(10146) }, 1), // Orange Salamander + new NetTrapNode(new int[] { NPCs.BABY_SQUIRREL_6921 }, 29, 152, new Item[] { new Item(Items.BABY_SQUIRREL_12490) }, 60), // Squirrel Gray + new NetTrapNode(new int[] { NPCs.BABY_SQUIRREL_7309 }, 29, 152, new Item[] { new Item(Items.BABY_SQUIRREL_12754) }, 60), // Squirrel Tan + new NetTrapNode(new int[] { NPCs.BABY_SQUIRREL_7310 }, 29, 152, new Item[] { new Item(Items.BABY_SQUIRREL_12756) }, 60), // Squirrel White + new NetTrapNode(new int[] { NPCs.BABY_SQUIRREL_7311 }, 29, 152, new Item[] { new Item(Items.BABY_SQUIRREL_12758) }, 60), // Squirrel Grayish/Brown w/e + new NetTrapNode(new int[] { NPCs.BABY_SQUIRREL_7312 }, 29, 152, new Item[] { new Item(Items.BABY_SQUIRREL_12760) }, 60), // Squirrel Brown + new NetTrapNode(new int[] { 5115 }, 59, 272, new Item[] { new Item(10147) }, 1), // Red Salamander + new NetTrapNode(new int[] { 5116 }, 67, 304, new Item[] { new Item(10148) }, 1)); // Black Salamander /** * The location hooks for this node. diff --git a/Server/src/main/content/global/skill/hunter/falconry/FalconryZone.kt b/Server/src/main/content/global/skill/hunter/falconry/FalconryZone.kt new file mode 100644 index 000000000..6256604de --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/falconry/FalconryZone.kt @@ -0,0 +1,13 @@ +package content.global.skill.hunter.falconry + +import core.game.node.Node +import core.game.world.map.zone.ZoneBorders + +/** + * Used to define the zoneBorders for an MapArea listener + */ +object FalconryZone { + val piscatorisFalconryZones = arrayOf( + ZoneBorders(2364, 3573, 2394, 3620, 0) + ) +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/hunter/falconry/PiscFalconryListener.kt b/Server/src/main/content/global/skill/hunter/falconry/PiscFalconryListener.kt new file mode 100644 index 000000000..c226a4fab --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/falconry/PiscFalconryListener.kt @@ -0,0 +1,36 @@ +package content.global.skill.hunter.falconry + +import core.api.* +import core.api.MapArea +import core.game.activity.ActivityManager +import core.game.node.entity.Entity +import core.game.world.map.zone.ZoneBorders +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class PiscFalconryListener: MapArea { + override fun defineAreaBorders(): Array { + return FalconryZone.piscatorisFalconryZones + } + + /** + * When player leaves by any method other than logout/disconnect. + */ + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + if (!logout) { + // Legacy compatibility of FalconryActivityPlugin.java + removeAttribute(entity, "falconry") + + // Compatibility with StileShortcut.kt + ActivityManager.getActivity("falconry").leave(entity, false) + + removeAll(entity, Items.FALCONERS_GLOVE_10023) + removeAll(entity, Items.FALCONERS_GLOVE_10023, Container.EQUIPMENT) + + removeAll(entity, Items.FALCONERS_GLOVE_10024) + removeAll(entity, Items.FALCONERS_GLOVE_10024, Container.EQUIPMENT) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt b/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt index f4959cbae..bdc9611a9 100644 --- a/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt +++ b/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt @@ -21,6 +21,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType +import core.game.node.entity.player.link.diary.DiaryType import core.game.world.GameWorld import org.rs09.consts.Sounds @@ -262,6 +263,7 @@ class PitfallListeners : InteractionListener { } on(GRAAHK_PIT, IntType.SCENERY, "dismantle") { player, node -> lootCorpse(player, node as Scenery, 240.0, Items.GRAAHK_FUR_10099, Items.TATTY_GRAAHK_FUR_10097) + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 13) sendMessage(player, "You've caught a horned graahk!") return@on true } diff --git a/Server/src/main/content/global/skill/magic/HomeTeleportHelper.kt b/Server/src/main/content/global/skill/magic/HomeTeleportHelper.kt new file mode 100644 index 000000000..b7085b62c --- /dev/null +++ b/Server/src/main/content/global/skill/magic/HomeTeleportHelper.kt @@ -0,0 +1,48 @@ +package content.global.skill.magic + +import core.api.delayScript +import core.api.playGlobalAudio +import core.api.queueScript +import core.api.sendMessage +import core.api.stopExecuting +import core.game.event.TeleportEvent +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.game.world.map.zone.ZoneRestriction + +val HOME_ANIMATIONS = arrayOf(1722, 1723, 1724, 1725, 2798, 2799, 2800, 3195, 4643, 4645, 4646, 4847, 4848, 4849, 4850, 4851, 4852, 65535) +val HOME_GRAPHICS = arrayOf(775, 800, 801, 802, 803, 804, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 65535) +fun getAudio(count: Int): Int { + return when (count) { + 0 -> 193 + 4 -> 194 + 11 -> 195 + else -> -1 + } +} + +fun homeTeleport(player: Player, dest: Location) { + player.walkingQueue.reset() + player.pulseManager.clear() + if (player.timers.getTimer("teleblock") != null) { + sendMessage(player, "A magical force prevents you from teleporting.") + return + } + if (player.locks.isTeleportLocked || player.zoneMonitor.isRestricted(ZoneRestriction.TELEPORT)) { + sendMessage(player, "A magical force has stopped you from teleporting.") + return + } + queueScript(player, 0, QueueStrength.WEAK) { stage -> + if (stage == 18) { + player.properties.teleportLocation = dest + player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.SPELL, -1, dest)) + return@queueScript stopExecuting(player) + } + playGlobalAudio(player.location, getAudio(stage)) + player.packetDispatch.sendGraphic(HOME_GRAPHICS[stage]) + player.packetDispatch.sendAnimation(HOME_ANIMATIONS[stage]) + return@queueScript delayScript(player, 1) + } +} diff --git a/Server/src/main/content/global/skill/magic/MagicAltarListener.kt b/Server/src/main/content/global/skill/magic/MagicAltarListener.kt new file mode 100644 index 000000000..70ec07e25 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/MagicAltarListener.kt @@ -0,0 +1,82 @@ +package content.global.skill.magic + +import content.data.Quests +import core.api.animate +import core.api.hasLevelStat +import core.api.hasRequirement +import core.api.lock +import core.api.playAudio +import core.api.sendMessage +import core.game.event.SpellbookChangeEvent +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.skill.Skills +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +class MagicAltarListener : InteractionListener { + override fun defineListeners() { + on(intArrayOf(ANCIENT_ALTAR, LUNAR_ALTAR), IntType.SCENERY, "pray-at", "pray") { player, node -> + if (meetsRequirements(player, node)) { + swapSpellBook(player, node) + } + + return@on true + } + } + + private fun meetsRequirements(player: Player, altar: Node): Boolean { + val level = if (altar.id == ANCIENT_ALTAR) 50 else 65 + + if (!hasRequirement(player, if (altar.id == ANCIENT_ALTAR) Quests.DESERT_TREASURE else Quests.LUNAR_DIPLOMACY)) { + return false + } + + if (!hasLevelStat(player, Skills.MAGIC, level)) { + sendMessage(player, "You need a Magic level of at least $level in order to do this.") + return false + } + + return true + } + + private fun swapSpellBook(player : Player, altar : Node) { + lock(player, 3) + playAudio(player, Sounds.PRAYER_RECHARGE_2674) + animate(player, 645) + if (altar.id == ANCIENT_ALTAR) { + player.skills.decrementPrayerPoints(player.skills.prayerPoints) + } + val weaponInterface = player.getExtension(WeaponInterface::class.java) + if (weaponInterface != null && player.properties.autocastSpell != null) { + weaponInterface.selectAutoSpell(-1, true) + } + if (SpellBook.forInterface(player.spellBookManager.spellBook) == if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) { + player.dispatch(SpellbookChangeEvent( + SpellBook.forInterface(player.spellBookManager.spellBook), + SpellBook.MODERN, + SpellBookManager.SpellbookChangeSource.ALTAR)) + sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange drain upon your memory..." else "Modern spells activated!") + player.spellBookManager.setSpellBook(SpellBook.MODERN) + player.spellBookManager.update(player) + } else { + player.dispatch(SpellbookChangeEvent( + SpellBook.forInterface(player.spellBookManager.spellBook), + if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR, + SpellBookManager.SpellbookChangeSource.ALTAR)) + sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange wisdom fill your mind..." else "Lunar spells activated!") + player.spellBookManager.setSpellBook(if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) + player.spellBookManager.update(player) + } + } + + companion object { + private const val ANCIENT_ALTAR = Scenery.ALTAR_6552 + private const val LUNAR_ALTAR = Scenery.ALTAR_17010 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/SpellListener.kt b/Server/src/main/content/global/skill/magic/SpellListener.kt index 64383b0a7..e938f3ef0 100644 --- a/Server/src/main/content/global/skill/magic/SpellListener.kt +++ b/Server/src/main/content/global/skill/magic/SpellListener.kt @@ -47,11 +47,10 @@ abstract class SpellListener(val bookName: String) : Listener { player.sendMessage("You need a magic level of $magicLevel to cast this spell.") throw IllegalStateException() } - for(rune in runes){ - if(!SpellUtils.hasRune(player,rune)){ - player.sendMessage("You don't have enough ${rune.definition.name.lowercase()}s to cast this spell.") - throw IllegalStateException() - } + val missing = SpellUtils.hasRunes(player, runes) + if (missing != null) { + player.sendMessage("You don't have enough ${missing.definition.name.lowercase()}s to cast this spell.") + throw IllegalStateException() } for(item in specialEquipment){ if(!player.equipment.contains(item,1)){ diff --git a/Server/src/main/content/global/skill/magic/SpellListeners.kt b/Server/src/main/content/global/skill/magic/SpellListeners.kt index 95ff686a0..e390516e3 100644 --- a/Server/src/main/content/global/skill/magic/SpellListeners.kt +++ b/Server/src/main/content/global/skill/magic/SpellListeners.kt @@ -1,14 +1,14 @@ package content.global.skill.magic +import core.api.hasLineOfSight +import core.api.log import core.game.event.SpellCastEvent -import core.api.* +import core.game.interaction.MovementPulse import core.game.node.Node import core.game.node.entity.player.Player import core.game.node.entity.player.link.SpellBookManager -import core.tools.Log -import core.tools.SystemLogger -import core.game.interaction.* import core.game.world.map.path.Pathfinder +import core.tools.Log object SpellListeners { val castMap = HashMap Unit>() @@ -44,7 +44,7 @@ object SpellListeners { range = next.first method = next.second ?: return } - + player.scripts.removeWeakScripts() if (type in intArrayOf (SpellListener.NPC, SpellListener.OBJECT, SpellListener.PLAYER, SpellListener.GROUND_ITEM)) { player.pulseManager.run (object : MovementPulse (player, node, Pathfinder.SMART) { override fun pulse() : Boolean { diff --git a/Server/src/main/content/global/skill/magic/SpellUtils.kt b/Server/src/main/content/global/skill/magic/SpellUtils.kt index a80d646a5..57e8b4c6d 100644 --- a/Server/src/main/content/global/skill/magic/SpellUtils.kt +++ b/Server/src/main/content/global/skill/magic/SpellUtils.kt @@ -1,13 +1,25 @@ package content.global.skill.magic -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player import core.game.node.entity.combat.spell.CombinationRune import core.game.node.entity.combat.spell.MagicStaff import core.game.node.entity.combat.spell.Runes +import core.game.node.entity.player.Player import core.game.node.item.Item +import kotlin.math.min object SpellUtils { + /** + * Validates that the spell packet's interface matches the player's actual server-side spellbook. + * This prevents exploits where the client has a stale spellbook interface (e.g., after Spellbook Swap reverts). + * @param player The player casting the spell + * @param packetInterfaceId The interface ID from the client's spell packet + * @return true if the interfaces match (valid), false if there's a client/server desync + */ + @JvmStatic + fun validateSpellbookInterface(player : Player, packetInterfaceId : Int) : Boolean { + val actualSpellbook = player.spellBookManager.spellBook + return packetInterfaceId == actualSpellbook + } fun usingStaff(p: Player, rune: Int): Boolean { val weapon = p.equipment[3] ?: return false val staff = MagicStaff.forId(rune) ?: return false @@ -20,70 +32,57 @@ object SpellUtils { return false } - fun hasRune(p:Player,rune:Item):Boolean{ - val removeItems = p.getAttribute("spell:runes",ArrayList()) - if(usingStaff(p,rune.id)) return true - if(p.inventory.containsItem(rune)){ - removeItems.add(rune) - p.setAttribute("spell:runes",removeItems) + /** + * Validates if the player has the necessary runes to cast a spell. + * + * If the player is able to cast the spell, the "spell:runes" attribute will be set to the list of items that should + * be removed from the player's inventory after successfully casting the spell. This accounts for staves and + * combination runes. + * + * @param p The player casting the spell + * @param runes The runes and other items required to cast the spell + * @return null if the player can cast the spell or an Item representing at least one of the runes the player is missing + */ + @JvmStatic + fun hasRunes(p: Player, runes: Array): Item? { + val cost = HashMap() + // `runes` are mostly actual runes but occasionally other items like staves or unpowered orbs + for (rune in runes) { + if (usingStaff(p, rune.id)) continue + cost[rune.id] = cost.getOrDefault(rune.id, 0) + rune.amount } - val baseAmt = p.inventory.getAmount(rune.id) - var amtRemaining = rune.amount - baseAmt - val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(rune.id)) - for (r in possibleComboRunes) { - if (p.inventory.containsItem(Item(r.id)) && amtRemaining > 0) { - val amt = p.inventory.getAmount(r.id) - if (amtRemaining <= amt) { - removeItems.add(Item(r.id,amtRemaining)) - amtRemaining = 0 - break - } - removeItems.add(Item(r.id,p.inventory.getAmount(r.id))) - amtRemaining -= p.inventory.getAmount(r.id) + val toRemove = ArrayList() + + // Combination runes are used before elemental runes. + // https://runescape.wiki/w/Runecrafting?oldid=2618332#Function_and_Usage_of_Combination_Runes: + for (combo in CombinationRune.values()) { + val available = p.inventory.getAmount(combo.id) + val maxUsage = combo.types.mapNotNull { cost[it.id] }.maxOrNull() ?: 0 + if (maxUsage > 0 && available >= 0) { + val usage = min(maxUsage, available) + + toRemove.add(Item(combo.id, usage)) + // Even if a spell uses both parts of a combo rune, it should only consume a single rune. For example, + // a spell that requires an air rune and an earth rune should only consume a single dust rune. + // https://youtu.be/9gAiqEmF-Hc?t=67 + combo.types.forEach { cost[it.id] = cost.getOrDefault(it.id, 0) - usage } } } - p.setAttribute("spell:runes",removeItems) - return amtRemaining <= 0 - } - fun hasRune(p: Player, item: Item, toRemove: MutableList, message: Boolean): Boolean { - if (!usingStaff(p, item.id)) { - val hasBaseRune = p.inventory.contains(item.id, item.amount) - if (!hasBaseRune) { - val baseAmt = p.inventory.getAmount(item.id) - if (baseAmt > 0) { - toRemove.add(Item(item.id, p.inventory.getAmount(item.id))) - } - var amtRemaining = item.amount - baseAmt - val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(item.id)) - for (r in possibleComboRunes) { - if (p.inventory.containsItem(Item(r.id)) && amtRemaining > 0) { - val amt = p.inventory.getAmount(r.id) - if (amtRemaining < amt) { - toRemove.add(Item(r.id, amtRemaining)) - amtRemaining = 0 - continue - } - amtRemaining -= p.inventory.getAmount(r.id) - toRemove.add(Item(r.id, p.inventory.getAmount(r.id))) - } - } - return if (amtRemaining <= 0) { - true - } else { - p.packetDispatch.sendMessage("You don't have enough " + item.name + "s to cast this spell.") - false - } + for ((runeId, amount) in cost) { + if (amount <= 0) continue + + val available = p.inventory.getAmount(runeId) + if (available < amount) { + return Item(runeId, amount) } - toRemove.add(item) - return true - } - return true - } - fun attackableNPC(npc: NPC): Boolean{ - return npc.definition.hasAction("attack") + toRemove.add(Item(runeId, amount)) + } + + p.setAttribute("spell:runes", toRemove) + return null } @JvmStatic diff --git a/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java b/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java index 8f9a62c8e..b794a87e0 100644 --- a/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java +++ b/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java @@ -1,10 +1,21 @@ package content.global.skill.magic; +import content.data.Quests; import core.game.component.Component; import core.game.dialogue.DialoguePlugin; +import core.game.event.SpellbookChangeEvent; +import core.game.interaction.Listener; import core.game.node.entity.player.Player; -import core.plugin.Initializable; import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.SpellBookManager.SpellbookChangeSource; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.plugin.Initializable; + +import java.util.ArrayList; + +import static core.api.ContentAPIKt.hasRequirement; + /** * Handles the SpellbookSwapDialogue dialogue. @@ -73,8 +84,27 @@ public class SpellbookSwapDialogue extends DialoguePlugin { break; } final SpellBook book = type == 1 ? SpellBook.ANCIENT : SpellBook.MODERN; + if (book == SpellBook.ANCIENT && !hasRequirement(player, Quests.DESERT_TREASURE)) { + player.getPacketDispatch().sendMessage("You need to complete Desert Treasure to use Ancient Magicks."); + end(); + return true; + } + // Remove runes for Spellbook Swap + ArrayList runes = player.getAttribute("spell:runes", new ArrayList<>()); + if (!runes.isEmpty() && player.getInventory().remove(runes.toArray(new Item[0]))) { + player.removeAttribute("spell:runes"); + player.removeAttribute("tablet-spell"); + } + // Award XP + player.skills.addExperience(Skills.MAGIC, 130); + // Change book + player.dispatch(new SpellbookChangeEvent( + SpellBook.LUNAR, + book, + SpellbookChangeSource.SPELLBOOK_SWAP_CAST)); player.getSpellBookManager().setSpellBook(book); player.getInterfaceManager().openTab(new Component(book.getInterfaceId())); + player.getPacketDispatch().sendMessage("You have 2 minutes before your spellbook changes back to the Lunar Spellbook!"); end(); break; } diff --git a/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java b/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java index 3944c3c7e..a9c95ab5e 100644 --- a/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java +++ b/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java @@ -1,20 +1,26 @@ package content.global.skill.magic.ancient; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.entity.combat.spell.MagicSpell; -import core.game.node.entity.combat.spell.Runes; +import core.game.event.SpellCastEvent; import core.game.node.Node; import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; import core.game.node.entity.player.link.SpellBookManager.SpellBook; import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.entity.player.link.diary.DiaryType; import core.game.node.item.Item; import core.game.world.GameWorld; import core.game.world.map.Location; import core.plugin.Initializable; import core.plugin.Plugin; +import core.tools.Log; import core.tools.RandomFunction; +import static content.global.skill.magic.HomeTeleportHelperKt.homeTeleport; +import static core.api.ContentAPIKt.log; + /** * Represents the plugin used to handle all ancient teleporting plugins. * @author 'Vexia @@ -55,7 +61,15 @@ public final class AncientTeleportPlugin extends MagicSpell { entity.asPlayer().sendMessage("A magical force has stopped you from teleporting."); return false; } - if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), getSpellId() == 28 ? TeleportType.HOME : TeleportType.ANCIENT)) { + boolean isHomeTeleport = getSpellId() == 28; + if (isHomeTeleport) { + if (!entity.isPlayer()) { + log(this.getClass(), Log.ERR, "Why the fuck is a non-player entity trying to cast ancient-magick home teleport?!"); + return false; + } + homeTeleport((Player) entity, Location.create(3087, 3495, 0)); + entity.dispatch(new SpellCastEvent(SpellBook.ANCIENT, getSpellId(), target)); + } else if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), TeleportType.ANCIENT)) { if (!super.meetsRequirements(entity, true, true)) { entity.getTeleporter().getCurrentTeleport().stop(); return false; @@ -86,7 +100,7 @@ public final class AncientTeleportPlugin extends MagicSpell { // dareeyak teleport SpellBook.ANCIENT.register(24, new AncientTeleportPlugin(78, 88, Location.create(2966, 3696, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 3), new Item(Runes.AIR_RUNE.getId(), 2))); // carralangar teleport - SpellBook.ANCIENT.register(25, new AncientTeleportPlugin(84, 82, Location.create(3163, 3664, 0), new Item(Runes.SOUL_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2))); + SpellBook.ANCIENT.register(25, new AncientTeleportPlugin(84, 82, Location.create(3217, 3676, 0), new Item(Runes.SOUL_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2))); // annakarl teleport SpellBook.ANCIENT.register(26, new AncientTeleportPlugin(90, 100, Location.create(3287, 3883, 0), new Item(Runes.BLOOD_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2))); // ghorrock teleport diff --git a/Server/src/main/content/global/skill/magic/ancient/IceSpells.java b/Server/src/main/content/global/skill/magic/ancient/IceSpells.java index e4f287574..4b0e29ff4 100644 --- a/Server/src/main/content/global/skill/magic/ancient/IceSpells.java +++ b/Server/src/main/content/global/skill/magic/ancient/IceSpells.java @@ -1,162 +1,160 @@ -package content.global.skill.magic.ancient; - -import java.util.List; - -import core.game.node.entity.combat.spell.Runes; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.combat.spell.CombatSpell; -import core.game.node.entity.combat.spell.SpellType; -import core.game.node.entity.impl.Projectile; -import core.game.node.entity.impl.Animator.Priority; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -import static core.api.ContentAPIKt.*; - -/** - * Handles the Ice spells from the Ancient spellbook. - * @author Emperor - * @version 1.0 - */ -@Initializable -public final class IceSpells extends CombatSpell { - - /** - * The barrage orb GFX. - */ - private static final Graphics BARRAGE_ORB = new Graphics(1677, 96); //119 - - /** - * The projectile for Ice rush. - */ - private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 360, 40, 36, 52, 75, 15, 11); - - /** - * The end graphic for Ice rush. - */ - private static final Graphics RUSH_END = new Graphics(361, 96); - - /** - * The projectile for Ice barrage. - */ - private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 362, 40, 36, 52, 75, 15, 11); - - /** - * The end graphic for Ice barrage. - */ - private static final Graphics BURST_END = new Graphics(363, 0); - - /** - * The start graphic for Ice rush. - */ - private static final Graphics BLITZ_START = new Graphics(366, 96); - - /** - * The end graphic for Ice rush. - */ - private static final Graphics BLITZ_END = new Graphics(367, 96); - - /** - * The projectile for Ice barrage. - */ - private static final Projectile BARRAGE_PROJECTILE = Projectile.create((Entity) null, null, 368, 40, 36, 52, 75, 15, 11); - - /** - * The end graphic for Ice barrage. - */ - private static final Graphics BARRAGE_END = new Graphics(369, 0); - - /** - * Constructs a new {@code IceSpells} {@code Object}. - */ - public IceSpells() { - /* - * empty. - */ - } - - /** - * Constructs a new {@code IceSpells} {@Code Object} - * @param type The spell type. - * @param impactSound The impact sound id. - * @param anim The animation. - * @param start The start graphics. - * @param projectile The projectile. - * @param end The end graphics. - */ - private IceSpells(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { - super(type, SpellBook.ANCIENT, level, baseExperience, Sounds.ICE_CAST_171, impactSound, anim, start, projectile, end, runes); - } - - @Override - public void visualize(Entity entity, Node target) { - entity.graphics(graphic); - if (projectile != null) { - projectile.transform(entity, (Entity) target, false, 58, 10).send(); - } - entity.animate(animation); - playGlobalAudio(entity.getLocation(), audio.id, 20); - - } - - @Override - public void visualizeImpact(Entity entity, Entity target, BattleState state) { - if (state.isFrozen()) { - playGlobalAudio(target.getLocation(), impactAudio, 20); - target.graphics(BARRAGE_ORB); - return; - } - super.visualizeImpact(entity, target, state); - } - - @Override - public Plugin newInstance(SpellType arg) throws Throwable { - SpellBook.ANCIENT.register(0, new IceSpells(SpellType.RUSH, 58, 34.0, Sounds.ICE_RUSH_IMPACT_173, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.WATER_RUNE.getItem(2))); - SpellBook.ANCIENT.register(2, new IceSpells(SpellType.BURST, 70, 40.0, Sounds.ICE_BURST_IMPACT_170, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.WATER_RUNE.getItem(4))); - SpellBook.ANCIENT.register(1, new IceSpells(SpellType.BLITZ, 82, 46.0, Sounds.ICE_BLITZ_IMPACT_169, new Animation(1978, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3))); - SpellBook.ANCIENT.register(3, new IceSpells(SpellType.BARRAGE, 94, 52.0, Sounds.ICE_BARRAGE_IMPACT_168, new Animation(1979, Priority.HIGH), null, BARRAGE_PROJECTILE, BARRAGE_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.WATER_RUNE.getItem(6))); - return this; - } - - @Override - public void fireEffect(Entity entity, Entity victim, BattleState state) { - if (state.getEstimatedHit() == -1) { - return; - } - int ticks = (1 + (type.ordinal() - SpellType.RUSH.ordinal())) * 8; - if (state.getEstimatedHit() > -1) { - if (!hasTimerActive(victim, "frozen:immunity")) { - registerTimer(victim, spawnTimer("frozen", ticks, true)); - } else if (type == SpellType.BARRAGE) { - state.setFrozen(true); - } - } - } - - @Override - public BattleState[] getTargets(Entity entity, Entity target) { - if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { - return super.getTargets(entity, target); - } - List list = getMultihitTargets(entity, target, 9); - BattleState[] targets = new BattleState[list.size()]; - int index = 0; - for (Entity e : list) { - targets[index++] = new BattleState(entity, e); - } - return targets; - } - - @Override - public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { - return getType().getImpactAmount(entity, victim, 4); - } - -} +package content.global.skill.magic.ancient; + +import java.util.List; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Ice spells from the Ancient spellbook. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class IceSpells extends CombatSpell { + + /** + * The barrage orb GFX. + */ + private static final Graphics BARRAGE_ORB = new Graphics(1677, 96); //119 + + /** + * The projectile for Ice rush. + */ + private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 360, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Ice rush. + */ + private static final Graphics RUSH_END = new Graphics(361, 96); + + /** + * The projectile for Ice barrage. + */ + private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 362, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Ice barrage. + */ + private static final Graphics BURST_END = new Graphics(363, 0); + + /** + * The start graphic for Ice rush. + */ + private static final Graphics BLITZ_START = new Graphics(366, 96); + + /** + * The end graphic for Ice rush. + */ + private static final Graphics BLITZ_END = new Graphics(367, 96); + + /** + * The projectile for Ice barrage. + */ + private static final Projectile BARRAGE_PROJECTILE = Projectile.create((Entity) null, null, 368, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Ice barrage. + */ + private static final Graphics BARRAGE_END = new Graphics(369, 0); + + /** + * Constructs a new {@code IceSpells} {@code Object}. + */ + public IceSpells() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code IceSpells} {@Code Object} + * @param type The spell type. + * @param impactSound The impact sound id. + * @param anim The animation. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + */ + private IceSpells(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.ANCIENT, level, baseExperience, Sounds.ICE_CAST_171, impactSound, anim, start, projectile, end, runes); + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + + } + + @Override + public void visualizeImpact(Entity entity, Entity target, BattleState state) { + if (state.isFrozen()) { + playGlobalAudio(target.getLocation(), impactAudio, 20); + target.graphics(BARRAGE_ORB); + return; + } + super.visualizeImpact(entity, target, state); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.ANCIENT.register(0, new IceSpells(SpellType.RUSH, 58, 34.0, Sounds.ICE_RUSH_IMPACT_173, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.WATER_RUNE.getItem(2))); + SpellBook.ANCIENT.register(2, new IceSpells(SpellType.BURST, 70, 40.0, Sounds.ICE_BURST_IMPACT_170, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.WATER_RUNE.getItem(4))); + SpellBook.ANCIENT.register(1, new IceSpells(SpellType.BLITZ, 82, 46.0, Sounds.ICE_BLITZ_IMPACT_169, new Animation(1978, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3))); + SpellBook.ANCIENT.register(3, new IceSpells(SpellType.BARRAGE, 94, 52.0, Sounds.ICE_BARRAGE_IMPACT_168, new Animation(1979, Priority.HIGH), null, BARRAGE_PROJECTILE, BARRAGE_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.WATER_RUNE.getItem(6))); + return this; + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (state.getEstimatedHit() == -1) { + return; + } + int ticks = (type.ordinal() - 4) * 8; + if (hasTimerActive(victim, "frozen") || hasTimerActive(victim, "frozen:immunity")) { + if (type == SpellType.BARRAGE) { state.setFrozen(true); } + return; + } + registerTimer(victim, spawnTimer("frozen", ticks, true)); + } + + @Override + public BattleState[] getTargets(Entity entity, Entity target) { + if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { + return super.getTargets(entity, target); + } + List list = getMultihitTargets(entity, target, 9); + BattleState[] targets = new BattleState[list.size()]; + int index = 0; + for (Entity e : list) { + targets[index++] = new BattleState(entity, e); + } + return targets; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 4); + } + +} diff --git a/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java b/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java index 1faf6ed30..5ead4131e 100644 --- a/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java +++ b/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java @@ -112,8 +112,8 @@ public final class MiasmicSpells extends CombatSpell { @Override public Plugin newInstance(SpellType arg) throws Throwable { SpellBook.ANCIENT.register(16, new MiasmicSpells(SpellType.RUSH, 61, 36.0, 5368, 5365, new Animation(10513, Priority.HIGH), RUSH_START, null, RUSH_END, Runes.EARTH_RUNE.getItem(1), Runes.SOUL_RUNE.getItem(1), Runes.CHAOS_RUNE.getItem(2))); - SpellBook.ANCIENT.register(17, new MiasmicSpells(SpellType.BURST, 73, 42.0, 5366, 5372, new Animation(10516, Priority.HIGH), BURST_START, null, BURST_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.CHAOS_RUNE.getItem(4))); - SpellBook.ANCIENT.register(18, new MiasmicSpells(SpellType.BLITZ, 85, 48.0, 5370, 5367, new Animation(10524, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(2))); + SpellBook.ANCIENT.register(18, new MiasmicSpells(SpellType.BURST, 73, 42.0, 5366, 5372, new Animation(10516, Priority.HIGH), BURST_START, null, BURST_END, Runes.EARTH_RUNE.getItem(2), Runes.SOUL_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4))); + SpellBook.ANCIENT.register(17, new MiasmicSpells(SpellType.BLITZ, 85, 48.0, 5370, 5367, new Animation(10524, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(2))); SpellBook.ANCIENT.register(19, new MiasmicSpells(SpellType.BARRAGE, 97, 54.0, 5371, 5369, new Animation(10518, Priority.HIGH), BARRAGE_START, null, BARRAGE_END, Runes.EARTH_RUNE.getItem(4), Runes.SOUL_RUNE.getItem(4), Runes.BLOOD_RUNE.getItem(4))); return this; } diff --git a/Server/src/main/content/global/skill/magic/lunar/DreamSpell.java b/Server/src/main/content/global/skill/magic/lunar/DreamSpell.java deleted file mode 100644 index e35542f0a..000000000 --- a/Server/src/main/content/global/skill/magic/lunar/DreamSpell.java +++ /dev/null @@ -1,104 +0,0 @@ -package content.global.skill.magic.lunar; - -import core.game.node.entity.combat.spell.MagicSpell; -import core.game.node.entity.combat.spell.Runes; -import core.game.node.entity.skill.Skills; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.spell.SpellType; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the dream magic spell. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class DreamSpell extends MagicSpell { - - /** - * Represents the starting animation. - */ - private static final Animation START = Animation.create(6295); - - /** - * Represents the dreaming animation. - */ - private static final Animation DREAMING = Animation.create(6296); - - /** - * Represents the end animation. - */ - private static final Animation END = Animation.create(6297); - - /** - * Represents the graphics of this spell. - */ - private static final Graphics GRAPHIC = new Graphics(1056); - - /** - * Constructs a new {@code CureOtherSpell} {@code Object}. - */ - public DreamSpell() { - super(SpellBook.LUNAR, 79, 82, null, null, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.BODY_RUNE.getId(), 5) }); - } - - @Override - public Plugin newInstance(SpellType arg) throws Throwable { - SpellBook.LUNAR.register(10, this); - return this; - } - - @Override - public boolean cast(Entity entity, Node target) { - final Player p = (Player) entity; - if (p.getSkills().getLifepoints() == p.getSkills().getStaticLevel(Skills.HITPOINTS)) { - p.getPacketDispatch().sendMessage("You have no need to cast this spell since your hitpoints are already full."); - return false; - } - if (!meetsRequirements(entity, true, true)) { - return false; - } - p.animate(START); - p.lock(); - GameWorld.getPulser().submit(new Pulse(4, p) { - @Override - public boolean pulse() { - p.animate(DREAMING); - p.graphics(GRAPHIC); - p.unlock(); - return true; - } - - }); - p.getPulseManager().run(new Pulse(18, p) { - @Override - public boolean pulse() { - p.graphics(GRAPHIC); - p.getSkills().heal(1); - if (p.getSkills().getLifepoints() == p.getSkills().getStaticLevel(Skills.HITPOINTS)) { - stop(); - return true; - } - return false; - } - - @Override - public void stop() { - super.stop(); - p.graphics(new Graphics(-1)); - p.animate(END); - } - }); - return true; - } - -} diff --git a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt index 6ed1cfebc..fd8dc5ccd 100644 --- a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt +++ b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt @@ -5,10 +5,12 @@ import content.global.skill.farming.CompostBins import content.global.skill.farming.CompostType import content.global.skill.farming.FarmingPatch import content.global.skill.magic.SpellListener +import content.global.skill.magic.homeTeleport import content.global.skill.magic.spellconsts.Lunar import core.api.* import core.game.component.CloseEvent import core.game.component.Component +import core.game.interaction.QueueStrength import core.game.node.Node import core.game.node.entity.combat.ImpactHandler import core.game.node.entity.npc.NPC @@ -20,21 +22,32 @@ import core.game.node.scenery.Scenery import core.game.system.command.Privilege import core.game.system.config.NPCConfigParser import core.game.system.task.Pulse +import core.game.system.timer.impl.PoisonImmunity +import core.game.system.timer.impl.SkillRestore +import core.game.system.timer.impl.SpellbookSwap import core.game.world.map.Location import core.game.world.map.RegionManager import core.game.world.repository.Repository import core.game.world.update.flag.context.Animation import core.tools.RandomFunction -import org.rs09.consts.* +import org.rs09.consts.Animations +import org.rs09.consts.Components +import org.rs09.consts.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Sounds import kotlin.math.floor +private const val DREAM_HEAL_INTERVAL_TICKS = 50 +private const val DREAM_HARD_RESET_INTERVAL_TICKS = 90 +private const val DREAM_HARD_RESET_DELAY_TICKS = 0 + class LunarListeners : SpellListener("lunar"), Commands { override fun defineListeners() { // Level 0 onCast(Lunar.HOME_TELEPORT, NONE) { player, _ -> requires(player) - player.teleporter.send(Location.create(2100, 3914, 0),TeleportManager.TeleportType.HOME) + homeTeleport(player, Location.create(2100, 3914, 0)) setDelay(player,true) } @@ -169,9 +182,10 @@ class LunarListeners : SpellListener("lunar"), Commands { } // Level 79 - /** - * Dream - */ + onCast(Lunar.DREAM, NONE) { player, _ -> + requires(player, 79, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.BODY_RUNE_559, 5), Item(Items.COSMIC_RUNE_564, 1))) + dream(player) + } // Level 80 onCast(Lunar.STRING_JEWELLERY, NONE) { player, _ -> @@ -275,9 +289,14 @@ class LunarListeners : SpellListener("lunar"), Commands { */ // Level 96 - /** - * Spellbook Swap - */ + onCast(Lunar.SPELLBOOK_SWAP, NONE) { player, _ -> + requires(player, 96, arrayOf( + Item(Items.LAW_RUNE_563, 1), + Item(Items.COSMIC_RUNE_564, 2), + Item(Items.ASTRAL_RUNE_9075, 3) + )) + spellbookSwap(player) + } } // Spell handlers @@ -295,7 +314,7 @@ class LunarListeners : SpellListener("lunar"), Commands { if(playerPies.isEmpty()){ player.sendMessage("You have no pies which you have the level to cook.") - return + throw IllegalStateException() } player.pulseManager.run(object : Pulse(){ @@ -320,30 +339,38 @@ class LunarListeners : SpellListener("lunar"), Commands { } // Level 66 - fun curePlant(player: Player, obj: Scenery){ + fun curePlant(player: Player, obj: Scenery) { + if (CompostBins.forObject(obj) != null) { + sendMessage(player, "Bins don't often get diseased.") + throw IllegalStateException() + } val fPatch = FarmingPatch.forObject(obj) - if(fPatch == null){ - sendMessage(player, "You attempt to cast Cure Plant on ${obj.definition.name}!") - sendMessage(player, "Nothing interesting happens.") - return + if (fPatch == null) { + sendMessage(player, "Umm... this spell won't cure that!") + throw IllegalStateException() } val patch = fPatch.getPatchFor(player) - if(!patch.isDiseased && !patch.isWeedy() && !patch.isEmptyAndWeeded()){ - sendMessage(player, "It is growing just fine.") - return - } - if(patch.isWeedy()){ + if (patch.isWeedy()) { sendMessage(player, "The weeds are healthy enough already.") - return + throw IllegalStateException() } - if(patch.isDead){ - sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.") - return + if (patch.isEmptyAndWeeded()) { + sendMessage(player, "There's nothing there to cure.") + throw IllegalStateException() } - if(patch.isGrown()){ + if (patch.isGrown()) { sendMessage(player, "That's not diseased.") - return + throw IllegalStateException() } + if (patch.isDead) { + sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.") + throw IllegalStateException() + } + if (!patch.isDiseased) { + sendMessage(player, "It is growing just fine.") + throw IllegalStateException() + } + patch.cureDisease() removeRunes(player) addXP(player,60.0) @@ -355,7 +382,7 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun monsterExamine(player: Player, npc: NPC){ if(!npc.location.withinDistance(player.location)){ sendMessage(player, "You must get closer to use this spell.") - return + throw IllegalStateException() } face(player, npc) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293, Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, soundID = Sounds.LUNAR_STAT_SPY_3620) @@ -369,7 +396,7 @@ class LunarListeners : SpellListener("lunar"), Commands { setInterfaceText(player, "Hitpoints : ${npc.definition.handlers[NPCConfigParser.LIFEPOINTS] ?: 0}", Components.DREAM_MONSTER_STAT_522, 2) setInterfaceText(player, "Max hit : ${npc.getSwingHandler(false).calculateHit(npc, player, 1.0)}", Components.DREAM_MONSTER_STAT_522, 3) - val poisonStatus = if(npc.definition.handlers.getOrDefault(NPCConfigParser.POISON_IMMUNE,false) == true){ + val poisonStatus = if(npc.isPoisonImmune){ "This creature is immune to poison." } else "This creature is not immune to poison." @@ -391,20 +418,20 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun cureOther(player: Player, target: Node) { if(!isPlayer(target)) { sendMessage(player, "You can only cast this spell on other players.") - return + throw IllegalStateException() } val p = target.asPlayer() if(!p.isActive || p.locks.isInteractionLocked) { sendMessage(player, "This player is busy.") - return + throw IllegalStateException() } if(!p.settings.isAcceptAid) { sendMessage(player, "This player is not accepting any aid.") - return + throw IllegalStateException() } if(!isPoisoned(p)) { sendMessage(player, "This player is not poisoned.") - return + throw IllegalStateException() } player.face(p) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_OTHER_4411, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_2886) @@ -427,7 +454,7 @@ class LunarListeners : SpellListener("lunar"), Commands { if(playerEmpties.isEmpty()) { sendMessage(player, "You have nothing in your inventory that this spell can humidify.") - return + throw IllegalStateException() } removeRunes(player) @@ -449,7 +476,7 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun cureMe(player: Player) { if(!isPoisoned(player)) { sendMessage(player, "You are not poisoned.") - return + throw IllegalStateException() } removeRunes(player, true) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_ME_4411, Graphics.LUNAR_SPELLBOOK_CURE_ME_742, 90, Sounds.LUNAR_CURE_2884) @@ -492,7 +519,7 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun statSpy(player: Player, target: Node) { if(target !is Player) { sendMessage(player, "You can only cast this spell on players.") - return + throw IllegalStateException() } val stat = Components.DREAM_PLAYER_STATS_523 val statCloseEvent = CloseEvent { p, _ -> @@ -562,15 +589,61 @@ class LunarListeners : SpellListener("lunar"), Commands { if(index == size && size != 0) { removeRunes(player, true) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_SUPERGLASS_MAKE_4413, Graphics.LUNAR_SPELLBOOK_SUPERGLASS_MAKE_729, 120, Sounds.LUNAR_HEATGLASS_2896) - rewardXP(player, Skills.CRAFTING, 10.0) + rewardXP(player, Skills.CRAFTING, 10.0 * index) addXP(player, 78.0) } } // Level 79 - /** - * Dream - */ + private fun dream(player: Player) { + if (player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { + sendMessage(player, "You have no need to cast this spell since your hitpoints are already full.") + throw IllegalStateException() + } + // https://runescape.wiki/w/Dream?oldid=880976 claims Dream makes you heal 1 hp every 20 seconds + // https://oldschool.runescape.wiki/w/Dream claims that Dream has its own timer, so the Dream heals don't need + // to align with the natural heals + val timer = getOrStartTimer(player) + val dreamStartAnimationTicks = animationDuration(Animation(Animations.LUNAR_SPELLBOOK_DREAM_START_6295)) + var nextHealTick = getWorldTicks() + dreamStartAnimationTicks + DREAM_HEAL_INTERVAL_TICKS + var nextHardResetTick = -1 + var waitingForHardReset = false + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_START_6295) + removeRunes(player, true) + addXP(player, 82.0) + delayEntity(player, dreamStartAnimationTicks) + queueScript(player, dreamStartAnimationTicks, QueueStrength.WEAK) { stage: Int -> + if (stage == 0) { + sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) + playAudio(player, Sounds.LUNAR_SLEEP_3619) + return@queueScript delayScript(player, 5) + } + if (waitingForHardReset) { + waitingForHardReset = false + nextHardResetTick = getWorldTicks() + DREAM_HARD_RESET_INTERVAL_TICKS + } else if (nextHardResetTick != -1 && getWorldTicks() >= nextHardResetTick) { + // The 530 client eventually drops Dream back to idle if it only sees repeated 6296 updates + // Sending an explicit reset makes the next 6296 a full restart instead of a same-sequence refresh + resetAnimator(player) + waitingForHardReset = true + return@queueScript delayScript(player, DREAM_HARD_RESET_DELAY_TICKS) + } else if (nextHardResetTick == -1) { + nextHardResetTick = getWorldTicks() + DREAM_HARD_RESET_INTERVAL_TICKS + } + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_MID_6296) + sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) + if (getWorldTicks() >= nextHealTick) { + val amt = timer.getHealAmount(player) //accounts for regen brace + heal(player, amt) + nextHealTick += DREAM_HEAL_INTERVAL_TICKS + if (player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_END_6297) + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 5) + } + } private fun stringJewellery(player: Player) { val playerJewellery = ArrayDeque() @@ -620,23 +693,23 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun fertileSoil(player: Player, target: Scenery) { if (CompostBins.forObjectID(target.id) != null) { sendMessage(player, "No, that would be silly.") - return + throw IllegalStateException() } val fPatch = FarmingPatch.forObject(target) if(fPatch == null) { sendMessage(player, "Um... I don't want to fertilize that!") - return + throw IllegalStateException() } val patch = fPatch.getPatchFor(player) if (patch.isGrown()) { sendMessage(player, "Composting isn't going to make it get any bigger.") - return + throw IllegalStateException() } if (patch.isFertilized()) { sendMessage(player, "This patch has already been composted.") - return + throw IllegalStateException() } removeRunes(player, true) animate(player, Animations.LUNAR_SPELLBOOK_FERTILE_SOIL_4413) @@ -657,11 +730,11 @@ class LunarListeners : SpellListener("lunar"), Commands { val plankType = PlankType.getForLog(item) if (plankType == null) { sendMessage(player, "You need to use this spell on logs.") - return + throw IllegalStateException() } if (amountInInventory(player, Items.COINS_995) < plankType.price || !removeItem(player, Item(Items.COINS_995, plankType.price))) { sendMessage(player, "You need ${plankType.price} coins to convert that log into a plank.") - return + throw IllegalStateException() } lock(player, 3) setDelay(player, false) @@ -676,20 +749,20 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun energyTransfer(player: Player, target: Node) { if(!isPlayer(target)) { sendMessage(player, "You can only cast this spell on other players.") - return + throw IllegalStateException() } val targetPlayer = target.asPlayer() if(!targetPlayer.isActive || targetPlayer.locks.isInteractionLocked) { sendMessage(player, "This player is busy.") - return + throw IllegalStateException() } if(!targetPlayer.settings.isAcceptAid) { sendMessage(player, "This player is not accepting any aid.") - return + throw IllegalStateException() } if(10 >= player.skills.lifepoints) { sendMessage(player, "You need more hitpoints to cast this spell.") - return + throw IllegalStateException() } player.face(targetPlayer) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_ENERGY_TRANSFER_4411, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738, 90, Sounds.LUNAR_ENERGY_TRANSFER_2885) @@ -738,11 +811,20 @@ class LunarListeners : SpellListener("lunar"), Commands { /** * Heal Group */ - - // Level 96 - /** - * Spellbook Swap - */ + + // Level 96 + private fun spellbookSwap(player : Player) { + // Runes are removed on successful swap to another spellbook in SpellbookSwapDialogue.java + // removeRunes(player, true) + lock(player, 4) + visualizeSpell(player, 6299, 1062) + player.scripts.removeWeakScripts() + player.dialogueInterpreter.open(3264731) + registerTimer(player, SpellbookSwap()) + // XP is awarded in SpellbookSwapDialogue.java similarly to rune removal handling + // addXP(player, 130.0) + setDelay(player, false) + } // Other/Multi spell use-case private fun sendTeleport(player: Player, xp: Double, loc: Location){ @@ -770,7 +852,7 @@ class LunarListeners : SpellListener("lunar"), Commands { } override fun defineCommands() { - define("poison", privilege = Privilege.ADMIN) { player, strings -> + define("poison", privilege = Privilege.ADMIN, usage = "::poison player damage", description = "Applies poison to player for damage initial damage.") { player, strings -> if(strings.size == 3) { val dmg = strings[2].toIntOrNull() val p = Repository.getPlayerByName(strings[1]) @@ -779,7 +861,10 @@ class LunarListeners : SpellListener("lunar"), Commands { return@define } if(dmg != null) { - p.let { applyPoison(it, it, dmg) } + p.let { + removeTimer(it) + applyPoison(it, it, dmg) + } } else { sendMessage(player, "Damage must be an integer. Format:") sendMessage(player, "::poison username damage") @@ -790,7 +875,7 @@ class LunarListeners : SpellListener("lunar"), Commands { } } - define("humidifykit", privilege = Privilege.ADMIN) { player, _ -> + define("humidifykit", privilege = Privilege.ADMIN, description = "Gives you the runes and items needed to test Humidify.") { player, _ -> if(freeSlots(player) < 24) { sendMessage(player, "Not enough free space.") return@define @@ -807,6 +892,3 @@ class LunarListeners : SpellListener("lunar"), Commands { } - - - diff --git a/Server/src/main/content/global/skill/magic/lunar/SpellbookSwapSpell.java b/Server/src/main/content/global/skill/magic/lunar/SpellbookSwapSpell.java deleted file mode 100644 index 4c152b0af..000000000 --- a/Server/src/main/content/global/skill/magic/lunar/SpellbookSwapSpell.java +++ /dev/null @@ -1,84 +0,0 @@ -package content.global.skill.magic.lunar; - -import core.game.component.Component; -import core.game.node.entity.combat.spell.MagicSpell; -import core.game.node.entity.combat.spell.Runes; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.spell.SpellType; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.tools.RandomFunction; - -/** - * The spellbook swap spell. - * @author 'Vexia - */ -@Initializable -public class SpellbookSwapSpell extends MagicSpell { - - /** - * Represents the animation of this spell. - */ - private final Animation ANIMATION = new Animation(6299); - - /** - * Represents the graphics of this spell. - */ - private final Graphics GRAPHIC = new Graphics(1062); - - /** - * Constructs a new {@code SpellbookSwapSpell} {@code Object}. - */ - public SpellbookSwapSpell() { - super(SpellBook.LUNAR, 96, 130, null, null, null, new Item[] { new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 3) }); - } - - @Override - public Plugin newInstance(SpellType arg) throws Throwable { - SpellBook.LUNAR.register(12, this); - return this; - } - - @Override - public boolean cast(Entity entity, Node target) { - final Player player = (Player) entity; - if (!super.meetsRequirements(player, true, true)) { - return false; - } - player.lock(9); - player.animate(ANIMATION); - player.graphics(GRAPHIC); - player.getDialogueInterpreter().open(3264731); - final int id = RandomFunction.random(1, 500000); - player.setAttribute("spell:swap", id); - GameWorld.getPulser().submit(new Pulse(20, player) { - @Override - public boolean pulse() { - if (player.getAttribute("spell:swap", 0) == id) { - removeTemporarySpell(player); - } - return true; - } - - }); - return true; - } - - /** - * Method used to remove the temp spell swap. - * @param player the player. - */ - public static void removeTemporarySpell(final Player player) { - player.removeAttribute("spell:swap"); - player.getSpellBookManager().setSpellBook(SpellBook.LUNAR); - player.getInterfaceManager().openTab(new Component(SpellBook.LUNAR.getInterfaceId())); - } -} diff --git a/Server/src/main/content/global/skill/magic/modern/ChargeOrbSpells.java b/Server/src/main/content/global/skill/magic/modern/ChargeOrbSpells.java deleted file mode 100644 index 837a44991..000000000 --- a/Server/src/main/content/global/skill/magic/modern/ChargeOrbSpells.java +++ /dev/null @@ -1,206 +0,0 @@ -package content.global.skill.magic.modern; - -import core.game.node.entity.combat.spell.Runes; -import core.game.node.entity.combat.spell.MagicSpell; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.spell.SpellType; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.audio.Audio; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -/** - * Represents the the charging orb magic spell. - * - * @author Emperor - * @version 1.0 - */ -@Initializable -public final class ChargeOrbSpells extends MagicSpell { - - /** - * The animation. - */ - private static final Animation ANIMATION = Animation.create(791); - - /** - * The unpowered orb item. - */ - private static final Item UNPOWERED_ORB = new Item(567); - - /** - * The object id. - */ - private int objectId; - - /** - * The item id. - */ - private int itemId; - - /** - * The button that was clicked. - */ - private int buttonId; - - /** - * Constructs a new {@code ChargeOrbSpells} {@code Object} - */ - public ChargeOrbSpells() { - /* - * empty. - */ - } - - /** - * Constructs a new {@code ChargeOrbSpells} {@code Object}. - * - * @param level The level required. - * @param objectId The object id. - * @param itemId The item to add. - * @param buttonId the button clicked - * @param g The graphics. - * @param runes The runes required. - */ - public ChargeOrbSpells(int level, int objectId, int itemId, int buttonId, Graphics g, Audio a, Item... runes) { - super(SpellBook.MODERN, level, level + 10, ANIMATION, g, a, runes); - this.objectId = objectId; - this.itemId = itemId; - this.buttonId = buttonId; - } - - @Override - public Plugin newInstance(SpellType arg) throws Throwable { - SpellBook.MODERN.register(35, new ChargeOrbSpells(56, 2151, 571, 35, new Graphics(149, 96), new Audio(Sounds.CHARGE_WATER_ORB_118), Runes.WATER_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB)); - SpellBook.MODERN.register(39, new ChargeOrbSpells(60, 29415, 575, 39, new Graphics(151, 96), new Audio(Sounds.CHARGE_EARTH_ORB_115), Runes.EARTH_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB)); - SpellBook.MODERN.register(46, new ChargeOrbSpells(63, 2153, 569, 46, new Graphics(152, 96), new Audio(Sounds.CHARGE_FIRE_ORB_117), Runes.FIRE_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB)); - SpellBook.MODERN.register(49, new ChargeOrbSpells(66, 2152, 573, 49, new Graphics(150, 96), new Audio(Sounds.CHARGE_AIR_ORB_116), Runes.AIR_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB)); - return this; - } - - @Override - public boolean cast(Entity entity, Node target) { - if (!(target instanceof Scenery)) { - return false; - } - Player p = (Player) entity; - Scenery obj = (Scenery) target; - if (obj == null || obj.getId() != objectId) { - p.getPacketDispatch().sendMessage("You can't cast this spell on this object!"); - return false; - } - if (obj.getLocation().getDistance(p.getLocation()) > 3) { - p.getPacketDispatch().sendMessage("You're standing too far from the obelisk's reach."); - return false; - } - if (!p.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 9) - && objectId == 2151 - && p.getInventory().containsItems(Runes.COSMIC_RUNE.getItem(15), Runes.WATER_RUNE.getItem(150), new Item(UNPOWERED_ORB.getId(), 5))) { - p.setAttribute("/save:diary:seers:water-orb-can-earn", true); - - p.setAttribute("/save:diary:seers:water-orb", 1); - } - if (!meetsRequirements(entity, true, true)) { - return false; - } - p.faceLocation(obj.getLocation()); - visualize(p, target); - if (!p.getPulseManager().hasPulseRunning()) { - p.getPulseManager().run(new ChargeOrbPulse(p, new Item(itemId), target, buttonId)); - } - p.getInventory().add(new Item(itemId)); - return true; - } - - /** - * Represents the pulse for automatically charging orbs on obelisks. - * - * @author Splinter - * @version 1.0 - */ - public static class ChargeOrbPulse extends SkillPulse { - - /** - * The item we are going to recieve (always an orb). - */ - public Item item; - - /** - * The target of the spell. - */ - public Node target; - - /** - * The button (spell) that we clicked. - */ - public int buttonId; - - /** - * The unpowered orb item. - */ - private static final Item UNPOWERED_ORB = new Item(567, 1); - - /** - * Constructs a new {@code ChargeOrbPulse} {@code Object}. - * - * @param player the player. - * @param target the node. - * @param item the item. - * @param buttonId the clicked button - */ - public ChargeOrbPulse(Player player, Item item, Node target, int buttonId) { - super(player, item); - this.item = item; - this.target = target; - this.buttonId = buttonId; - } - - @Override - public boolean checkRequirements() { - if (player.getInventory().contains(UNPOWERED_ORB.getId(), 1)) { - return true; - } - return false; - } - - @Override - public void animate() { - player.animate(new Animation(791)); - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(4); - return false; - } - if (ChargeOrbSpells.castSpell(player, SpellBook.MODERN, buttonId, target)) { - if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 9) - && player.getAttribute("diary:seers:water-orb-can-earn", false)) { - player.setAttribute("/save:diary:seers:water-orb", 1 + player.getAttribute("diary:seers:water-orb", 0)); - } - if (player.getAttribute("diary:seers:water-orb", 0) >= 5) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 9); - player.removeAttribute("diary:seers:water-orb-can-earn"); - } - return false; - } else { - return true; - } - } - - @Override - public void stop() { - player.removeAttribute("diary:seers:water-orb-can-earn"); - } - } -} diff --git a/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java b/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java index ec23e258f..582795a81 100644 --- a/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java +++ b/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java @@ -1,5 +1,7 @@ package content.global.skill.magic.modern; +import content.region.kandarin.feldip.quest.zogreflesheaters.SkogreBehavior; +import content.region.kandarin.feldip.quest.zogreflesheaters.ZogreBehavior; import core.game.node.entity.combat.spell.Runes; import core.game.node.Node; import core.game.node.entity.Entity; @@ -15,8 +17,12 @@ import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable; import core.plugin.Plugin; +import org.rs09.consts.NPCs; import org.rs09.consts.Sounds; +import java.util.Arrays; +import java.util.List; + /** * Handles the crumble undead spell. * @author Emperor @@ -35,6 +41,15 @@ public final class CrumbleUndead extends CombatSpell { @Override public boolean cast(Entity entity, Node target) { NPC npc = target instanceof NPC ? (NPC) target : null; + // Exception for Zogres and Skogres because they are classified as OGRES in npc.getTask() as not undead, + // so you couldn't use crumble undead on it. This bypasses that. + if ( + Arrays.stream(ZogreBehavior.zogreIds).anyMatch(i -> i == npc.getId()) || + Arrays.stream(SkogreBehavior.skogreIds).anyMatch(i -> i == npc.getId()) || + npc.getId() == NPCs.SLASH_BASH_2060 + ) { + return super.cast(entity, target); + } if (npc == null || npc.getTask() == null || !npc.getTask().undead) { ((Player) entity).getPacketDispatch().sendMessage("This spell only affects the undead."); return false; diff --git a/Server/src/main/content/global/skill/magic/modern/ModernData.kt b/Server/src/main/content/global/skill/magic/modern/ModernData.kt new file mode 100644 index 000000000..793a757b5 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/ModernData.kt @@ -0,0 +1,63 @@ +package content.global.skill.magic.modern + +import core.game.node.item.Item +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +enum class ChargeOrbData( + val obelisk: Int, + val requiredRunes: Array, + val level: Int, + val experience: Double, + val graphics: Graphics, + val sound: Int, + val chargedOrb: Int +) { + CHARGE_WATER_ORB( + Scenery.OBELISK_OF_WATER_2151, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.WATER_RUNE_555, 30), Item(Items.UNPOWERED_ORB_567)), + 56, + 66.0, + Graphics(149, 90), + Sounds.CHARGE_WATER_ORB_118, + Items.WATER_ORB_571 + ), + CHARGE_EARTH_ORB( + Scenery.OBELISK_OF_EARTH_29415, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.EARTH_RUNE_557, 30), Item(Items.UNPOWERED_ORB_567)), + 60, + 70.0, + Graphics(151, 90), + Sounds.CHARGE_EARTH_ORB_115, + Items.EARTH_ORB_575 + ), + CHARGE_FIRE_ORB( + Scenery.OBELISK_OF_FIRE_2153, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.FIRE_RUNE_554, 30), Item(Items.UNPOWERED_ORB_567)), + 63, + 73.0, + Graphics(152, 90), + Sounds.CHARGE_FIRE_ORB_117, + Items.FIRE_ORB_569 + ), + CHARGE_AIR_ORB( + Scenery.OBELISK_OF_AIR_2152, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.AIR_RUNE_556, 30), Item(Items.UNPOWERED_ORB_567)), + 66, + 76.0, + Graphics(150, 90), + Sounds.CHARGE_AIR_ORB_116, + Items.AIR_ORB_573 + ); + companion object{ + val spellMap = HashMap() + + init { + for (spell in ChargeOrbData.values()) { + spellMap[spell.obelisk] = spell + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt b/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt index 8ac1b5216..777beee18 100644 --- a/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt +++ b/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt @@ -1,70 +1,47 @@ package content.global.skill.magic.modern +import content.data.Quests import content.global.skill.magic.SpellListener +import content.global.skill.magic.SpellUtils.hasRunes import content.global.skill.magic.TeleportMethod +import content.global.skill.magic.homeTeleport import content.global.skill.magic.spellconsts.Modern -import core.game.event.ItemAlchemizationEvent -import core.game.event.TeleportEvent import content.global.skill.prayer.Bones +import content.global.skill.smithing.smelting.Bar +import content.global.skill.smithing.smelting.SmeltingPulse +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners +import core.ServerConstants +import core.api.* +import core.game.diary.DiaryLevel +import core.game.event.ItemAlchemizationEvent +import core.game.event.ResourceProducedEvent +import core.game.event.TeleportEvent import core.game.interaction.MovementPulse +import core.game.node.Node import core.game.node.entity.Entity +import core.game.node.entity.combat.spell.MagicStaff +import core.game.node.entity.impl.Animator import core.game.node.entity.impl.Projectile import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager -import core.game.node.entity.player.link.audio.Audio import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills -import content.global.skill.smithing.smelting.Bar -import content.global.skill.smithing.smelting.SmeltingPulse import core.game.node.item.Item import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics import org.rs09.consts.Items -import core.ServerConstants -import core.api.* -import core.game.node.entity.combat.spell.MagicStaff -import core.game.node.entity.impl.Animator +import org.rs09.consts.Scenery import org.rs09.consts.Sounds class ModernListeners : SpellListener("modern"){ - - private val CONFUSE_START = Graphics(102, 96) - private val CONFUSE_PROJECTILE = Projectile.create(null as Entity?, null, 103, 40, 36, 52, 75, 15, 11) - private val CONFUSE_END = Graphics(104, 96) - private val WEAKEN_START = Graphics(105, 96) - private val WEAKEN_PROJECTILE = Projectile.create(null as Entity?, null, 106, 40, 36, 52, 75, 15, 11) - private val WEAKEN_END = Graphics(107, 96) - private val CURSE_START = Graphics(108, 96) - private val CURSE_PROJECTILE = Projectile.create(null as Entity?, null, 109, 40, 36, 52, 75, 15, 11) - private val CURSE_END = Graphics(110, 96) - private val VULNER_START = Graphics(167, 96) - private val VULNER_PROJECTILE = Projectile.create(null as Entity?, null, 168, 40, 36, 52, 75, 15, 11) - private val VULNER_END = Graphics(169, 96) - private val ENFEEBLE_START = Graphics(170, 96) - private val ENFEEBLE_PROJECTILE = Projectile.create(null as Entity?, null, 171, 40, 36, 52, 75, 15, 11) - private val ENFEEBLE_END = Graphics(172, 96) - private val STUN_START = Graphics(173, 96) - private val STUN_PROJECTILE = Projectile.create(null as Entity?, null, 174, 40, 36, 52, 75, 15, 11) - private val STUN_END = Graphics(107, 96) - private val LOW_ANIMATION = Animation(716, Animator.Priority.HIGH) - private val HIGH_ANIMATION = Animation(729, Animator.Priority.HIGH) - private val LOW_ALCH_ANIM = Animation(712) - private val LOW_ALCH_GFX = Graphics(112,5) - private val HIGH_ALCH_ANIM = Animation(713) - private val HIGH_ALCH_GFX = Graphics(113,5) - private val BONE_CONVERT_GFX = Graphics(141, 96) - private val BONE_CONVERT_ANIM = Animation(722) - - override fun defineListeners() { - onCast(Modern.HOME_TELEPORT, NONE){ player, _ -> if (!getAttribute(player, "tutorial:complete", false)) { return@onCast } requires(player) - player.teleporter.send(ServerConstants.HOME_LOCATION,TeleportManager.TeleportType.HOME) + homeTeleport(player, ServerConstants.HOME_LOCATION ?: Location(3222, 3218, 0)) setDelay(player,true) } @@ -88,35 +65,44 @@ class ModernListeners : SpellListener("modern"){ onCast(Modern.CAMELOT_TELEPORT, NONE){ player, _-> requires(player,45, arrayOf(Item(Items.AIR_RUNE_556,5),Item(Items.LAW_RUNE_563))) player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 1, 5) - sendTeleport(player,55.5, Location.create(2758, 3478, 0)) + if (player.achievementDiaryManager.getDiary(DiaryType.SEERS_VILLAGE).level == 2 + && (getItemFromEquipment(player, EquipmentSlot.HEAD)?.id ?: 0) == Items.SEERS_HEADBAND_14631) + sendTeleport(player,55.5,Location.create(2725, 3485, 0)) + else + sendTeleport(player,55.5, Location.create(2758, 3478, 0)) } onCast(Modern.ARDOUGNE_TELEPORT, NONE){ player, _ -> - if (!hasRequirement(player, "Plague City")) - return@onCast - requires(player,51, arrayOf(Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2))) - sendTeleport(player,61.0, Location.create(2662, 3307, 0)) + if (getAttribute(player, PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE, false)){ + requires(player,51, arrayOf(Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2))) + sendTeleport(player,61.0, Location.create(2662, 3307, 0)) + } + else { + // source https://runescape.salmoneus.net/forums/topic/289818-ardougne-teleport-help/ + sendDialogue(player, "You haven\'t learnt how to cast this spell yet") + } + return@onCast } onCast(Modern.WATCHTOWER_TELEPORT, NONE){ player, _ -> - if (!hasRequirement(player, "Watchtower")) + if (!hasRequirement(player, Quests.WATCHTOWER)) return@onCast requires(player,58, arrayOf(Item(Items.EARTH_RUNE_557,2),Item(Items.LAW_RUNE_563,2))) sendTeleport(player,68.0, Location.create(2549, 3112, 0)) } onCast(Modern.TROLLHEIM_TELEPORT, NONE){ player, _ -> - if (!hasRequirement(player, "Eadgar's Ruse")) + if (!hasRequirement(player, Quests.EADGARS_RUSE)) return@onCast requires(player,61, arrayOf(Item(Items.FIRE_RUNE_554,2),Item(Items.LAW_RUNE_563,2))) sendTeleport(player,68.0, Location.create(2891, 3678, 0)) } onCast(Modern.APE_ATOLL_TELEPORT, NONE){ player, _ -> - if (!hasRequirement(player, "Monkey Madness")) + if (!hasRequirement(player, Quests.MONKEY_MADNESS)) return@onCast requires(player,64, arrayOf(Item(Items.FIRE_RUNE_554,2),Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2),Item(Items.BANANA_1963))) - sendTeleport(player,74.0, Location.create(2754, 2784, 0)) + sendTeleport(player,74.0, Location.create(2795, 2798, 1)) } onCast(Modern.TELEPORT_TO_HOUSE, NONE){ player, _ -> @@ -151,6 +137,11 @@ class ModernListeners : SpellListener("modern"){ requires(player,60, arrayOf(Item(Items.EARTH_RUNE_557,4), Item(Items.WATER_RUNE_555,4), Item(Items.NATURE_RUNE_561,2))) boneConvert(player,false) } + + onCast(Modern.CHARGE_WATER_ORB, OBJECT, Scenery.OBELISK_OF_WATER_2151, 3, method = ::chargeOrb) + onCast(Modern.CHARGE_EARTH_ORB, OBJECT, Scenery.OBELISK_OF_EARTH_29415, 3, method = ::chargeOrb) + onCast(Modern.CHARGE_FIRE_ORB, OBJECT, Scenery.OBELISK_OF_FIRE_2153, 3, method = ::chargeOrb) + onCast(Modern.CHARGE_AIR_ORB, OBJECT, Scenery.OBELISK_OF_AIR_2152, 3, method = ::chargeOrb) } private fun boneConvert(player: Player,bananas: Boolean){ @@ -194,7 +185,7 @@ class ModernListeners : SpellListener("modern"){ } private fun superheat(player: Player,item: Item){ - if(!item.name.contains("ore") && !item.name.toLowerCase().equals("coal")){ + if(!item.name.contains("ore") && !item.name.equals("coal", true)){ player.sendMessage("You can only cast this spell on ore.") return } @@ -205,21 +196,27 @@ class ModernListeners : SpellListener("modern"){ return } - var bar = Bar.forOre(item.id) ?: return - if(bar == Bar.IRON && player.inventory.getAmount(Items.COAL_453) >= 2 && player.skills.getLevel(Skills.SMITHING) >= Bar.STEEL.level && player.inventory.contains(Items.IRON_ORE_441,1)) bar = Bar.STEEL + fun returnBar(player: Player,item: Item): Bar? { + // Loop through all metal bars starting with the highest tier + for (potentialBar in Bar.values().reversed()) { + // Check if the ore being cast on is needed for the current bar being considered + val inputOreInBar = potentialBar.ores.map{it.id}.contains(item.id) + // Check the player has all the required ores (and corresponding quantities) to make the current bar being considered + val playerHasNecessaryOres = potentialBar.ores.all{ore -> inInventory(player, ore.id, ore.amount)} + // If both tests pass return the current bar being considered as the one the spell should try to make + if (inputOreInBar && playerHasNecessaryOres) return potentialBar + } + // If none of the bars passed both tests the player must be missing a required ore + player.packetDispatch.sendMessage("You do not have the required ores to make this bar.") + return null + } + var bar = returnBar(player,item)?: return if(player.skills.getLevel(Skills.SMITHING) < bar.level){ player.sendMessage("You need a smithing level of ${bar.level} to superheat that ore.") return } - for (items in bar.ores) { - if (!player.inventory.contains(items.id, items.amount)) { - player.packetDispatch.sendMessage("You do not have the required ores to make this bar.") - return - } - } - player.lock(3) removeRunes(player) addXP(player,53.0) @@ -229,7 +226,7 @@ class ModernListeners : SpellListener("modern"){ setDelay(player,false) } - public fun alchemize(player: Player, item: Item, high: Boolean) : Boolean { + fun alchemize(player: Player, item: Item, high: Boolean, explorersRing: Boolean = false): Boolean { if(item.name == "Coins") player.sendMessage("You can't alchemize something that's already gold!").also { return false } if((!item.definition.isTradeable) && (!item.definition.isAlchemizable)) player.sendMessage("You can't cast this spell on something like that.").also { return false } @@ -248,16 +245,17 @@ class ModernListeners : SpellListener("modern"){ player.pulseManager.clear() } - val weapon = player.equipment.getItem(getItemFromEquipment(player, EquipmentSlot.WEAPON)) - if (weapon != null && !weapon.equals(MagicStaff.FIRE_RUNE)) { - player.animate(Animation(if (high) 9633 else 9625)) - player.graphics(Graphics(if (high) 1693 else 1692)) + if (explorersRing) { + visualize(player, LOW_ALCH_ANIM, EXPLORERS_RING_GFX) } else { - player.animate(Animation(if (high) 713 else 712)) - player.graphics(Graphics(if (high) 113 else 112)) + val weapon = getItemFromEquipment(player, EquipmentSlot.WEAPON) + if (weapon != null && weapon.id in MagicStaff.FIRE_RUNE.staves) { + visualize(player, if (high) HIGH_ALCH_STAFF_ANIM else LOW_ALCH_STAFF_ANIM, if (high) HIGH_ALCH_STAFF_GFX else LOW_ALCH_STAFF_GFX) + } else { + visualize(player, if (high) HIGH_ALCH_ANIM else LOW_ALCH_ANIM, if (high) HIGH_ALCH_GFX else LOW_ALCH_GFX) + } } playAudio(player, if (high) Sounds.HIGH_ALCHEMY_97 else Sounds.LOW_ALCHEMY_98) - player.dispatch(ItemAlchemizationEvent(item.id, high)) if (player.inventory.remove(Item(item.id, 1)) && coins.amount > 0) { player.inventory.add(coins) @@ -308,4 +306,81 @@ class ModernListeners : SpellListener("modern"){ addXP(player,30.0) setDelay(player,true) } -} + + private fun chargeOrb(player: Player, node: Node?) { + if (node == null) return + val spell = ChargeOrbData.spellMap[node.id] ?: return + requires(player, spell.level, spell.requiredRunes) + removeAttribute(player, "spell:runes") + face(player, node) + sendSkillDialogue(player) { + withItems(spell.chargedOrb) + calculateMaxAmount { return@calculateMaxAmount amountInInventory(player, Items.UNPOWERED_ORB_567) } + create { _, amount -> + var crafted = 0 + queueScript(player, 0) { + if (!hasLevelDyn(player, Skills.MAGIC, spell.level)) { + sendMessage(player, "You need a magic level of ${spell.level} to cast this spell.") + return@queueScript stopExecuting(player) + } + val missing = hasRunes(player, spell.requiredRunes) + if (missing != null) { + sendMessage(player, "You don't have enough ${missing.name.lowercase()}s to cast this spell.") + return@queueScript stopExecuting(player) + } + visualizeSpell(player, CHARGE_ORB_ANIM, spell.graphics, spell.sound) + removeRunes(player) + val success = addItem(player, spell.chargedOrb) + if (!success) { + return@queueScript stopExecuting(player) + } + addXP(player, spell.experience) + setDelay(player, 3) + crafted++ + + if (crafted == 5 && spell.chargedOrb == Items.WATER_ORB_571) { + player.dispatch(ResourceProducedEvent(spell.chargedOrb, crafted, node)) + } + if (amount == crafted) { return@queueScript stopExecuting(player) } + setCurrentScriptState(player, 0) + return@queueScript delayScript(player, 6) + } + } + } + return + } + companion object { + private val CONFUSE_START = Graphics(102, 96) + private val CONFUSE_PROJECTILE = Projectile.create(null as Entity?, null, 103, 40, 36, 52, 75, 15, 11) + private val CONFUSE_END = Graphics(104, 96) + private val WEAKEN_START = Graphics(105, 96) + private val WEAKEN_PROJECTILE = Projectile.create(null as Entity?, null, 106, 40, 36, 52, 75, 15, 11) + private val WEAKEN_END = Graphics(107, 96) + private val CURSE_START = Graphics(108, 96) + private val CURSE_PROJECTILE = Projectile.create(null as Entity?, null, 109, 40, 36, 52, 75, 15, 11) + private val CURSE_END = Graphics(110, 96) + private val VULNER_START = Graphics(167, 96) + private val VULNER_PROJECTILE = Projectile.create(null as Entity?, null, 168, 40, 36, 52, 75, 15, 11) + private val VULNER_END = Graphics(169, 96) + private val ENFEEBLE_START = Graphics(170, 96) + private val ENFEEBLE_PROJECTILE = Projectile.create(null as Entity?, null, 171, 40, 36, 52, 75, 15, 11) + private val ENFEEBLE_END = Graphics(172, 96) + private val STUN_START = Graphics(173, 96) + private val STUN_PROJECTILE = Projectile.create(null as Entity?, null, 174, 40, 36, 52, 75, 15, 11) + private val STUN_END = Graphics(107, 96) + private val LOW_ANIMATION = Animation(716, Animator.Priority.HIGH) + private val HIGH_ANIMATION = Animation(729, Animator.Priority.HIGH) + private val LOW_ALCH_ANIM = Animation(9623) + private val LOW_ALCH_STAFF_ANIM = Animation(9625) + private val HIGH_ALCH_ANIM = Animation(9631) + private val HIGH_ALCH_STAFF_ANIM = Animation(9633) + private val LOW_ALCH_GFX = Graphics(763) + private val HIGH_ALCH_GFX = Graphics(1691) + private val LOW_ALCH_STAFF_GFX = Graphics(1692) + private val HIGH_ALCH_STAFF_GFX = Graphics(1693) + private val EXPLORERS_RING_GFX = Graphics(1698) + private val BONE_CONVERT_GFX = Graphics(141, 96) + private val BONE_CONVERT_ANIM = Animation(722) + private val CHARGE_ORB_ANIM = Animation(726) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt b/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt index 6696eb19b..fa3d3f036 100644 --- a/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt +++ b/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt @@ -17,10 +17,14 @@ object Modern { const val SNARE = 30 const val ARDOUGNE_TELEPORT = 32 const val HIGH_ALCHEMY = 34 + const val CHARGE_WATER_ORB = 35 const val WATCHTOWER_TELEPORT = 37 + const val CHARGE_EARTH_ORB = 39 const val BONES_TO_PEACHES = 40 const val TROLLHEIM_TELEPORT = 44 + const val CHARGE_FIRE_ORB = 46 const val APE_ATOLL_TELEPORT = 47 + const val CHARGE_AIR_ORB = 49 const val VULNERABILITY = 50 const val ENFEEBLE = 53 const val ENTANGLE = 56 diff --git a/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt b/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt index e8b93e25c..5b41927aa 100644 --- a/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt +++ b/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt @@ -5,6 +5,7 @@ import core.game.event.BoneBuryEvent import core.game.interaction.Clocks import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item @@ -13,62 +14,37 @@ import org.rs09.consts.Sounds class BoneBuryListener : InteractionListener { override fun defineListeners() { - /** + + /* * Handles the bury options for bones in Bones.kt */ on(Bones.array, IntType.ITEM, "bury") { player, node -> val bones = Bones.forId(node.id) ?: return@on true + if (!clockReady(player, Clocks.SKILLING)) return@on true + if (!inInventory(player, node.id)) return@on true - // Checks if the player is delayed from burying a bone and begins the clock if none exists. - if (!clockReady(player, Clocks.SKILLING)) { - return@on true - } else { - delayClock(player, Clocks.SKILLING, 2) + stopWalk(player) + lock(player, 2) + delayClock(player, Clocks.SKILLING, 2) + sendMessage(player, "You dig a hole in the ground.") + animate(player, Animations.HUMAN_BURYING_BONES_827) + playAudio(player, Sounds.BONES_DOWN_2738) + + // A strong queue is required in the event a player moves immediately after clicking the bones + queueScript(player, 1, QueueStrength.STRONG) { + if (removeBones(player, node.asItem())) { + sendMessage(player, "You bury the bones.") + rewardXP(player, Skills.PRAYER, bones.experience) + player.dispatch(BoneBuryEvent(bones.itemId)) + } + return@queueScript stopExecuting(player) } - - // Verifies the bones are in the player's inventory. - if (!inInventory(player, bones.itemId)) { - return@on true - } - - // Replaces the bones slot in the inventory with nothing and checks that the bones are removed. - if (replaceSlot(player, node.asItem().slot, Item()) != node.asItem()) { - sendMessage(player, "The gods intervene and you keep your bones!") - return@on true - } - - buryBones(player, bones) return@on true } } - /** - * Buries the bones - * @param player the player burying the bones - * @param bones the bones being buried - */ - private fun buryBones(player: Player, bones: Bones): Boolean { - queueScript(player, 0) { stage -> - when (stage) { - 0 -> { - stopWalk(player) - lock(player, 2) - animate(player, Animations.HUMAN_BURYING_BONES_827) - playAudio(player, Sounds.BONES_DOWN_2738) - sendMessage(player, "You dig a hole in the ground.") - return@queueScript delayScript(player, 2) - } - - 1 -> { - sendMessage(player, "You bury the bones.") - rewardXP(player, Skills.PRAYER, bones.experience) - player.dispatch(BoneBuryEvent(bones.itemId)) - return@queueScript stopExecuting(player) - } - - else -> return@queueScript stopExecuting(player) - } - } - return true + private fun removeBones(player: Player, item: Item): Boolean { + val removedBones = replaceSlot(player, item.slot, Item()) + return removedBones == item && removedBones.slot == item.slot } } \ No newline at end of file diff --git a/Server/src/main/content/global/skill/prayer/PrayerAltarListener.kt b/Server/src/main/content/global/skill/prayer/PrayerAltarListener.kt new file mode 100644 index 000000000..71982f578 --- /dev/null +++ b/Server/src/main/content/global/skill/prayer/PrayerAltarListener.kt @@ -0,0 +1,166 @@ +package content.global.skill.prayer + +import core.api.* +import core.game.event.PrayerPointsRechargeEvent +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds +import content.data.Quests + +class PrayerAltarListener : InteractionListener { + override fun defineListeners() { + on(altars, IntType.SCENERY, "pray", "pray-at") { player, node -> + if (node.id == Scenery.TRIBAL_STATUE_3863 && !hasRequirement(player, Quests.TAI_BWO_WANNAI_TRIO)) { + // https://runescape.wiki/w/Tribal_Statue?oldid=1940922 + return@on true + } + + if (!pray(player, node)) { + if (node.id != Scenery.ELIDINIS_STATUETTE_10439) return@on true + } + + if (node.id == Scenery.ELIDINIS_STATUETTE_10439) { + // https://youtu.be/kEwYhnrQCu8?t=727 & https://youtu.be/b9Wy1JWDes8?t=413 + setTempLevel(player, Skills.HITPOINTS, getStatLevel(player, Skills.HITPOINTS).plus(7)) + sendMessage(player, "You feel much healthier after praying in the shrine.") + } + + if (node.id == Scenery.CHAOS_ALTAR_412) { + lock(player, 4) + queueScript(player, 4, QueueStrength.STRONG) { + sendMessage(player, "It's a trap!") + teleport(player, Location(2583, 9576, 0), TeleportManager.TeleportType.INSTANT) + return@queueScript stopExecuting(player) + } + } + return@on true + } + + on(Scenery.CHAOS_ALTAR_61, IntType.SCENERY, "check") { player, _ -> + if (getQuestStage(player, Quests.MERLINS_CRYSTAL) == 70) { + sendDialogue(player, "You find a small inscription at the bottom of the altar. It reads: 'Snarthon Candtrick Termanto'.") + setQuestStage(player, Quests.MERLINS_CRYSTAL, 80) + } else { + sendMessage(player, "An altar of the evil god Zamorak.") + } + return@on true + } + } + + private fun pray(player: Player, node: Node): Boolean { + val prayerLevel = getStatLevel(player, Skills.PRAYER).plus(if (node.id in boostedAltars) 2 else 0) + + if (player.skills.prayerPoints >= prayerLevel.toDouble()) { + sendMessage(player, "You already have full prayer points.") + return false + } + + lock(player, 3) + animate(player, 645) + playAudio(player, Sounds.PRAYER_RECHARGE_2674) + setTempLevel(player, Skills.PRAYER, prayerLevel) + sendMessage(player, "You recharge your prayer points.") + player.dispatch(PrayerPointsRechargeEvent(node)) + return true + } + + companion object { + private val altars = intArrayOf( + Scenery.ALTAR_409, + Scenery.ALTAR_2478, + Scenery.ALTAR_2479, + Scenery.ALTAR_2480, + Scenery.ALTAR_2481, + Scenery.ALTAR_2482, + Scenery.ALTAR_2483, + Scenery.ALTAR_2484, + Scenery.ALTAR_2485, + Scenery.ALTAR_2486, + Scenery.ALTAR_2487, + Scenery.ALTAR_2488, + Scenery.ALTAR_2489, + Scenery.ALTAR_2640, + Scenery.ALTAR_4008, + Scenery.ALTAR_8749, + Scenery.ALTAR_10639, + Scenery.ALTAR_10640, + Scenery.ALTAR_13179, + Scenery.ALTAR_13180, + Scenery.ALTAR_13181, + Scenery.ALTAR_13182, + Scenery.ALTAR_13183, + Scenery.ALTAR_13184, + Scenery.ALTAR_13185, + Scenery.ALTAR_13186, + Scenery.ALTAR_13187, + Scenery.ALTAR_13188, + Scenery.ALTAR_13189, + Scenery.ALTAR_13190, + Scenery.ALTAR_13191, + Scenery.ALTAR_13192, + Scenery.ALTAR_13193, + Scenery.ALTAR_13194, + Scenery.ALTAR_13195, + Scenery.ALTAR_13196, + Scenery.ALTAR_13197, + Scenery.ALTAR_13198, + Scenery.ALTAR_13199, + Scenery.ALTAR_15050, + Scenery.ALTAR_15051, + Scenery.ALTAR_18254, + Scenery.ALTAR_19145, + Scenery.ALTAR_20377, + Scenery.ALTAR_20378, + Scenery.ALTAR_20379, + Scenery.ALTAR_24343, + Scenery.ALTAR_27306, + Scenery.ALTAR_27307, + Scenery.ALTAR_27308, + Scenery.ALTAR_27309, + Scenery.ALTAR_27334, + Scenery.ALTAR_27338, + Scenery.ALTAR_27339, + Scenery.ALTAR_27661, + Scenery.ALTAR_30624, + Scenery.ALTAR_30726, + Scenery.ALTAR_34616, + Scenery.ALTAR_36972, + Scenery.ALTAR_37630, + Scenery.ALTAR_37901, + Scenery.ALTAR_37902, + Scenery.ALTAR_37903, + Scenery.ALTAR_37904, + Scenery.ALTAR_37905, + Scenery.ALTAR_37906, + Scenery.ALTAR_37907, + Scenery.ALTAR_37908, + Scenery.ALTAR_37909, + Scenery.ALTAR_37910, + Scenery.ALTAR_37911, + Scenery.ALTAR_37912, + Scenery.ALTAR_39547, + Scenery.ALTAR_39842, + Scenery.CHAOS_ALTAR_61, + Scenery.CHAOS_ALTAR_411, + Scenery.CHAOS_ALTAR_412, + Scenery.CHAOS_ALTAR_32079, + Scenery.CHAOS_ALTAR_37990, + Scenery.GORILLA_STATUE_4858, + Scenery.GORILLA_STATUE_4859, + Scenery.ALTAR_OF_GUTHIX_410, + Scenery.ALTAR_OF_GUTHIX_28698, + Scenery.ALTAR_OF_NATURE_3521, + Scenery.TRIBAL_STATUE_3863, + Scenery.ELIDINIS_STATUETTE_10439, + Scenery.DECAYED_ALTAR_37985 + ) + private val boostedAltars = intArrayOf(Scenery.ALTAR_2640, Scenery.ALTAR_OF_NATURE_3521) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/prayer/PrayerAltarPlugin.java b/Server/src/main/content/global/skill/prayer/PrayerAltarPlugin.java deleted file mode 100644 index c9cb114d7..000000000 --- a/Server/src/main/content/global/skill/prayer/PrayerAltarPlugin.java +++ /dev/null @@ -1,254 +0,0 @@ -package content.global.skill.prayer; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import core.game.node.entity.player.link.prayer.PrayerType; -import core.plugin.Initializable; -import core.game.node.entity.skill.Skills; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.entity.player.link.quest.Quest; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -import static core.api.ContentAPIKt.hasRequirement; -import static core.api.ContentAPIKt.playAudio; - -/** - * Handles the praying at an alter. - * @author Vexia - */ -@Initializable -public class PrayerAltarPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.setOptionHandler("pray-at", this); - SceneryDefinition.setOptionHandler("pray", this); - SceneryDefinition.forId(61).getHandlers().put("option:check", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - if (option.equalsIgnoreCase("check")) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); - if (quest.getStage(player) == 70) { - player.getDialogueInterpreter().sendDialogue("You find a small inscription at the bottom of the altar. It reads:", "'Snarthon Candtrick Termanto'."); - quest.setStage(player, 80); - return true; - } - player.getPacketDispatch().sendMessage("An altar of the evil god Zamorak."); - return true; - } - Altar altar = Altar.forId(node.getId()); - if (altar != null) { - altar.pray(player); - visualize(player); - return true; - } - if (player.getSkills().getPrayerPoints() == player.getSkills().getStaticLevel(Skills.PRAYER)) { - player.getPacketDispatch().sendMessage("You already have full prayer points."); - return true; - } - visualize(player); - player.getSkills().rechargePrayerPoints(); - player.getPacketDispatch().sendMessage("You recharge your Prayer points."); - if (node.getId() == 2640) { - player.getSkills().setLevel(Skills.PRAYER, player.getSkills().getStaticLevel(Skills.PRAYER) + 2); - } - if (node.getId() == 409 - && player.getLocation().withinDistance(new Location(3209, 3495, 1)) - && player.getPrayer().getActive().contains(PrayerType.SMITE)) { - player.getAchievementDiaryManager().finishTask(player,DiaryType.VARROCK,2, 4); - } - if (node.getId() == 39842 - && player.getLocation().withinDistance(new Location(2995, 3177, 0))) { - player.getAchievementDiaryManager().finishTask(player,DiaryType.FALADOR,0, 13); - } - // Seers task can be completed with either of camelot altar or seers church altar - if (node.getId() == 19145 - && player.getLocation().withinDistance(new Location(2749, 3496, 1))) { - player.getAchievementDiaryManager().finishTask(player,DiaryType.SEERS_VILLAGE,0, 10); - } - if (node.getId() == 409 - && player.getLocation().withinDistance(new Location(2694, 3462, 0))) { - player.getAchievementDiaryManager().finishTask(player,DiaryType.SEERS_VILLAGE,0, 10); - } - - if (node.getLocation().equals(new Location(2571, 9499, 0))) { - player.teleport(new Location(2583, 9576, 0)); - player.sendMessage("It's a trap!"); - return true; - } - return true; - } - - /** - * Visualizes the prayer. - * @param player the player. - */ - public void visualize(Player player) { - player.lock(3); - playAudio(player, Sounds.PRAYER_RECHARGE_2674); - player.animate(Animation.create(645)); - } - - /** - * An altar. - * @author Vexia - */ - public enum Altar { - ANCIENT(6552, SpellBook.ANCIENT.getInterfaceId(), "You feel a strange wisdom fill your mind...", "You feel a strange drain upon your memory...") { - @Override - public void pray(Player player) { - if (!hasRequirement(player, "Desert Treasure")) - return; - if (player.getSkills().getStaticLevel(Skills.MAGIC) < 50) { - player.sendMessage("You need a Magic level of at least 50 in order to do this."); - return; - } - drain(player); - if (!isPrayerType(player)) { - switchToBook(player); - player.sendMessage(getMessages()[0]); - } else { - revert(player); - player.sendMessage(getMessages()[1]); - } - } - }, - LUNAR(17010, SpellBook.LUNAR.getInterfaceId(), "Lunar spells activated!", "Modern spells activated!") { - @Override - public void pray(Player player) { - if (!hasRequirement(player, "Lunar Diplomacy")) - return; - if (player.getSkills().getStaticLevel(Skills.MAGIC) < 65) { - player.sendMessage("You need a Magic level of at least 65 in order to do this."); - return; - } - if (!isPrayerType(player)) { - switchToBook(player); - player.sendMessage(getMessages()[0]); - } else { - revert(player); - player.sendMessage(getMessages()[1]); - } - } - }; - - /** - * The id. - */ - private int id; - - /** - * The book. - */ - private int book; - - /** - * The messages. - */ - private String[] messages; - - /** - * Constructs a new {@Code Altar} {@Code Object} - * @param id the id. - * @param book the book. - * @param messages the messages. - */ - private Altar(int id, int book, String... messages) { - this.id = id; - this.book = book; - this.messages = messages; - } - - /** - * Prays at the altar. - * @param player the player. - */ - public void pray(Player player) { - - } - - /** - * Reverts the book. - * @param player the player. - */ - public void revert(Player player) { - player.getSpellBookManager().setSpellBook(SpellBook.MODERN); - player.getInterfaceManager().openTab(new Component(SpellBook.values()[SpellBook.MODERN.ordinal()].getInterfaceId())); - } - - /** - * Drains the player. - * @param player the player. - */ - public void drain(Player player) { - player.getSkills().decrementPrayerPoints(player.getSkills().getPrayerPoints()); - } - - /** - * Switches to the book. - * @param player the player. - */ - public void switchToBook(Player player) { - player.getSpellBookManager().setSpellBook(SpellBook.forInterface(book)); - player.getInterfaceManager().openTab(new Component(book)); - } - - /** - * Checks if it is the prayer type. - * @param player the player. - * @return true if so. - */ - public boolean isPrayerType(Player player) { - return player.getSpellBookManager().getSpellBook() == book; - } - - /** - * Gets an altar. - * @param id the id. - * @return the altar. - */ - public static Altar forId(int id) { - for (Altar altar : values()) { - if (id == altar.getId()) { - return altar; - } - } - return null; - } - - /** - * Gets the id. - * @return the id - */ - public int getId() { - return id; - } - - /** - * Gets the book. - * @return the book - */ - public int getBook() { - return book; - } - - /** - * Gets the messages. - * @return the messages - */ - public String[] getMessages() { - return messages; - } - } - -} diff --git a/Server/src/main/content/global/skill/runecrafting/Altar.java b/Server/src/main/content/global/skill/runecrafting/Altar.java index 29cc03953..487d61e6f 100644 --- a/Server/src/main/content/global/skill/runecrafting/Altar.java +++ b/Server/src/main/content/global/skill/runecrafting/Altar.java @@ -5,6 +5,7 @@ import core.game.node.entity.player.Player; import core.game.node.scenery.Scenery; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Represents an altar an it's relative information(corresponding ruin, etc) @@ -72,24 +73,24 @@ public enum Altar { */ public void enterRift(Player player) { if (this == ASTRAL) { - if (!hasRequirement(player, "Lunar Diplomacy")) + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return; } if (this == DEATH) { - if (!hasRequirement(player, "Mourning's End Part II")) + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_II)) return; } if (this == BLOOD) { - if (!hasRequirement(player, "Legacy of Seergaze")) + if (!hasRequirement(player, Quests.LEGACY_OF_SEERGAZE)) return; } if (this == LAW) { if (!ItemDefinition.canEnterEntrana(player)) { - player.sendMessage("You can't take weapons and armour into the law rift."); + player.sendMessage("The power of Saradomin prevents you from taking armour or weaponry to Entrana."); return; } } - if (this == COSMIC && !player.getQuestRepository().isComplete("Lost City")) { + if (this == COSMIC && !player.getQuestRepository().isComplete(Quests.LOST_CITY)) { player.getPacketDispatch().sendMessage("You need to have completed the Lost City quest in order to do that."); return; } diff --git a/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt b/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt index 68fcf10c7..7bf55dd7f 100644 --- a/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt +++ b/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt @@ -1,5 +1,6 @@ package content.global.skill.runecrafting +import content.data.Quests import content.region.misthalin.varrock.diary.VarrockAchivementDiary.Companion.EasyTasks.ENTER_EARTH_ALTAR import core.api.* import core.game.container.impl.EquipmentContainer.SLOT_HAT @@ -19,7 +20,7 @@ class MysteriousRuinListener : InteractionListener { private val animation = Animation(827) private val allowedUsed = arrayOf(1438, 1448, 1444, 1440, 1442, 5516, 1446, 1454, 1452, 1462, 1458, 1456, 1450, 1460).toIntArray() private val allowedWith = allRuins() - private val nothingInteresting = "Nothing interesting happens" + private val nothingInteresting = "Nothing interesting happens." override fun defineListeners() { onUseWith(IntType.SCENERY, allowedUsed, *allowedWith) { player, used, with -> @@ -76,9 +77,9 @@ class MysteriousRuinListener : InteractionListener { private fun checkQuestCompletion(player: Player, ruin: MysteriousRuin): Boolean { return when (ruin) { - MysteriousRuin.DEATH -> hasRequirement(player, QuestReq(MEP_2), true) - MysteriousRuin.BLOOD -> hasRequirement(player, QuestReq(SEERGAZE), true) - else -> hasRequirement(player, QuestReq(RUNE_MYSTERIES), true) + MysteriousRuin.DEATH -> hasRequirement(player, Quests.MOURNINGS_END_PART_II, true) + MysteriousRuin.BLOOD -> hasRequirement(player, Quests.LEGACY_OF_SEERGAZE, true) + else -> hasRequirement(player, Quests.RUNE_MYSTERIES, true) } } @@ -102,4 +103,4 @@ class MysteriousRuinListener : InteractionListener { }) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/runecrafting/PouchManager.kt b/Server/src/main/content/global/skill/runecrafting/PouchManager.kt index 52aba0d4b..22cc1865f 100644 --- a/Server/src/main/content/global/skill/runecrafting/PouchManager.kt +++ b/Server/src/main/content/global/skill/runecrafting/PouchManager.kt @@ -1,5 +1,6 @@ package content.global.skill.runecrafting +import core.api.* import core.game.container.Container import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills @@ -7,109 +8,131 @@ import core.game.node.item.Item import org.json.simple.JSONArray import org.json.simple.JSONObject import org.rs09.consts.Items -import core.tools.colorize /** * A class for managing rune pouches. * @param player the player this manager instance belongs to. - * @author Ceikry + * @author Ceikry, Player Name */ class PouchManager(val player: Player) { - val pouches = mapOf( - Items.SMALL_POUCH_5509 to RCPouch(3,1), - Items.MEDIUM_POUCH_5510 to RCPouch(6,25), - Items.LARGE_POUCH_5512 to RCPouch(9,50), - Items.GIANT_POUCH_5514 to RCPouch(12,75) + Items.SMALL_POUCH_5509 to RCPouch(3, 3, 1), + Items.MEDIUM_POUCH_5510 to RCPouch(6, 264, 25), + Items.LARGE_POUCH_5512 to RCPouch(9, 186, 50), + Items.GIANT_POUCH_5514 to RCPouch(12,140, 75) ) /** * Method to add essence to a pouch - * @param pouchId the id of the pouch we are adding to + * @param itemId the item ID of the pouch we are adding to * @param amount the amount of essence to add * @param essence the ID of the essence item we are trying to add - * @author Ceikry + * @author Ceikry, Player Name */ - fun addToPouch(pouchId: Int, amount: Int, essence: Int){ - if(!checkRequirement(pouchId)){ - player.sendMessage(colorize("%RYou lack the required level to use this pouch.")) + fun addToPouch(itemId: Int, amount: Int, essence: Int) { + val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId + if (!checkRequirement(pouchId)) { + sendMessage(player, "You lack the required level to use this pouch.") return } var amt = amount val pouch = pouches[pouchId] - val otherEssence = when(essence){ + val otherEssence = when(essence) { Items.RUNE_ESSENCE_1436 -> Items.PURE_ESSENCE_7936 Items.PURE_ESSENCE_7936 -> Items.RUNE_ESSENCE_1436 else -> 0 } pouch ?: return - if(amount > pouch.container.freeSlots()){ + if (amount > pouch.container.freeSlots()) { amt = pouch.container.freeSlots() } - if(amt == 0){ - player.sendMessage("This pouch is already full.") + if (amt == pouch.container.freeSlots()) { + sendMessage(player, "Your pouch is full.") //https://www.youtube.com/watch?v=wbYtRwODKTo } - if(pouch.container.contains(otherEssence,1)){ - player.sendMessage("You can only store one type of essence in each pouch.") + if (pouch.container.contains(otherEssence,1)) { + sendMessage(player, "You can only store one type of essence in each pouch.") return } - player.inventory.remove(Item(essence,amt)) - pouch.container.add(Item(essence,amt)) - } + var disappeared = false + if (itemId != Items.SMALL_POUCH_5509) { + pouch.charges -= amt + } + if (pouch.charges <= 0) { + pouch.currentCap -= when (pouchId) { + Items.MEDIUM_POUCH_5510 -> 1 + Items.LARGE_POUCH_5512 -> 2 + Items.GIANT_POUCH_5514 -> 3 + else /*small pouch*/ -> 0 + } + if (pouch.currentCap <= 0) { + // The pouch will disappear: https://runescape.wiki/w/Runecrafting_pouches?oldid=708494, https://oldschool.runescape.wiki/w/Essence_pouch + // "Degraded pouches will continue to degrade and lose essence capacity until they disappear or are repaired." implies that this is the end result of a gradual decay process + if (removeItem(player, itemId)) { + disappeared = true + sendMessage(player, "Your pouch has degraded completely.") + // Reset the pouch for when the player obtains a new one + pouch.currentCap = pouch.capacity + pouch.charges = pouch.maxCharges + pouch.remakeContainer() + replaceAllItems(player, itemId, itemId - 1) //in case the player had more copies + } + } else { + if (!isDecayedPouch(itemId)) { + replaceAllItems(player, itemId, itemId + 1) + } + sendMessage(player, "Your pouch has decayed through use.") //https://www.youtube.com/watch?v=FUcPYrgPUlQ + pouch.charges = 9 * pouch.currentCap //implied by multiple contemporaneous sources, quantified only by https://oldschool.runescape.wiki/w/Large_pouch + pouch.remakeContainer() + if (amt > pouch.currentCap) { + amt = pouch.currentCap + } + } + } + val essItem = Item(essence, amt) + if (!disappeared && removeItem(player, essItem)) { + pouch.container.add(essItem) + } + } /** * Method to withdraw rune essence from a pouch. - * @param pouchId the item ID of the pouch to withdraw from - * @author Ceikry + * @param itemId the item ID of the pouch to withdraw from + * @author Ceikry, Player Name */ - fun withdrawFromPouch(pouchId: Int){ + fun withdrawFromPouch(itemId: Int) { + val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId val pouch = pouches[pouchId] pouch ?: return - val playerFree = player.inventory.freeSlots() + val playerFree = freeSlots(player) var amount = pouch.currentCap - pouch.container.freeSlots() - if (amount > playerFree) amount = playerFree - player.debug("$amount") - if(amount == 0) return - val essence = Item(pouch.container.get(0).id,amount) - pouch.container.remove(essence) - pouch.container.shift() - player.inventory.add(essence) - if(pouch.charges-- <= 0){ - pouch.currentCap -= when(pouchId){ - 5510 -> 1 - 5512 -> 2 - 5514 -> 3 - else -> 0 - } - if(pouch.currentCap <= 0){ - player.inventory.remove(Item(pouchId)) - player.inventory.add(Item(pouchId + 1)) - player.sendMessage(colorize("%RYour ${Item(pouchId).name} has degraded completely.")) - } - pouch.remakeContainer() - pouch.charges = 10 - if(pouchId != 5509) { - player.sendMessage(colorize("%RYour ${Item(pouchId).name.toLowerCase()} has degraded slightly from use.")) + if (amount > playerFree) { + amount = playerFree + } else { + sendMessage(player, "Your pouch has no essence left in it.") //https://www.youtube.com/watch?v=wbYtRwODKTo + if (amount == 0) { + return } } - + val essence = Item(pouch.container.get(0).id, amount) + pouch.container.remove(essence) + pouch.container.shift() + addItem(player, essence.id, essence.amount) } - /** * Method to save pouches to a root JSONObject * @param root the JSONObject we are adding the "pouches" JSONArray to * @author Ceikry */ - fun save(root: JSONObject){ + fun save(root: JSONObject) { val pouches = JSONArray() - for(i in this.pouches){ + for(i in this.pouches) { val pouch = JSONObject() pouch.put("id",i.key.toString()) val items = JSONArray() - for(item in i.value.container.toArray()){ + for(item in i.value.container.toArray()) { item ?: continue val it = JSONObject() it.put("itemId",item.id.toString()) @@ -124,14 +147,13 @@ class PouchManager(val player: Player) { root.put("pouches",pouches) } - /** * Method to parse save data from a JSONArray * @param data the JSONArray that contains the data to parse * @author Ceikry */ - fun parse(data: JSONArray){ - for(e in data){ + fun parse(data: JSONArray) { + for (e in data){ val pouch = e as JSONObject val id = pouch["id"].toString().toInt() val p = pouches[id] @@ -141,7 +163,7 @@ class PouchManager(val player: Player) { p.charges = charges p.currentCap = currentCap p.remakeContainer() - for(i in pouch["container"] as JSONArray){ + for (i in pouch["container"] as JSONArray) { val it = i as JSONObject it["itemId"] ?: continue val item = it["itemId"].toString().toInt() @@ -151,33 +173,31 @@ class PouchManager(val player: Player) { } } - /** * Method for checking the level requirement for a given pouch. * @param pouchId the item ID of the pouch to check * @author Ceikry */ - fun checkRequirement(pouchId: Int): Boolean{ + fun checkRequirement(pouchId: Int): Boolean { val p = pouches[pouchId] p ?: return false return player.skills.getLevel(Skills.RUNECRAFTING) >= p.levelRequirement } - /** * Method for sending the player a message about how much space is left in a pouch - * @param pouchId the item ID of the pouch to check - * @author Ceikry + * @param itemId the item ID of the pouch to check + * @author Ceikry, Player Name */ - fun checkAmount(pouchId: Int){ + fun checkAmount(itemId: Int) { + val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId val p = pouches[pouchId] p ?: return player.sendMessage("This pouch has space for ${p.container.freeSlots()} more essence.") } - - fun isDecayedPouch(pouchId: Int): Boolean{ - if(pouchId == 5510) return false + fun isDecayedPouch(pouchId: Int): Boolean { + if (pouchId == Items.MEDIUM_POUCH_5510) return false return pouches[pouchId - 1] != null } @@ -185,12 +205,12 @@ class PouchManager(val player: Player) { * A class that represents a runecrafting pouch. * @author Ceikry */ - class RCPouch(val capacity: Int, val levelRequirement: Int){ + class RCPouch(val capacity: Int, val maxCharges: Int, val levelRequirement: Int) { var container = Container(capacity) var currentCap = capacity - var charges = 10 - fun remakeContainer(){ + var charges = maxCharges + fun remakeContainer() { this.container = Container(currentCap) } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java b/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java index dd48fe6b1..c9fa23ef5 100644 --- a/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java +++ b/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java @@ -2,6 +2,7 @@ package content.global.skill.runecrafting; import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager; import core.ServerConstants; +import core.api.Container; import core.game.container.impl.EquipmentContainer; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.player.Player; @@ -23,11 +24,13 @@ import org.rs09.consts.Sounds; import java.util.ArrayList; import java.util.Arrays; +import content.data.Quests; /** * A class used to craft runes. * * @author Vexia + * @author Player Name */ public final class RuneCraftPulse extends SkillPulse { @@ -100,47 +103,47 @@ public final class RuneCraftPulse extends SkillPulse { @Override public boolean checkRequirements() { if (altar == Altar.ASTRAL) { - if (!hasRequirement(player, "Lunar Diplomacy")) + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return false; } if (altar == Altar.DEATH) { - if (!hasRequirement(player, "Mourning's End Part II")) + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_II)) return false; } if (altar == Altar.BLOOD) { - if (!hasRequirement(player, "Legacy of Seergaze")) + if (!hasRequirement(player, Quests.LEGACY_OF_SEERGAZE)) return false; } - if (!altar.isOurania() && player.getSkills().getLevel(Skills.RUNECRAFTING) < rune.getLevel()) { - player.getPacketDispatch().sendMessage("You need a Runecrafting level of at least " + rune.getLevel() + " to craft this rune."); + if (!altar.isOurania() && getDynLevel(player, Skills.RUNECRAFTING) < rune.getLevel()) { + sendMessage(player, "You need a Runecrafting level of at least " + rune.getLevel() + " to craft this rune."); return false; } - if (combination && !player.getInventory().containsItem(PURE_ESSENCE)) { - player.getPacketDispatch().sendMessage("You need pure essence to craft this rune."); + if (combination && amountInInventory(player, PURE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need pure essence to craft this rune."); return false; } - if (!altar.isOurania() && !rune.isNormal() && !player.getInventory().containsItem(PURE_ESSENCE)) { - player.getPacketDispatch().sendMessage("You need pure essence to craft this rune."); + if (!altar.isOurania() && !rune.isNormal() && amountInInventory(player, PURE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need pure essence to craft this rune."); return false; } - if (!altar.isOurania() && rune.isNormal() && !player.getInventory().containsItem(PURE_ESSENCE) && !player.getInventory().containsItem(RUNE_ESSENCE)) { - player.getPacketDispatch().sendMessage("You need rune essence or pure essence in order to craft this rune."); + if (!altar.isOurania() && rune.isNormal() && amountInInventory(player, PURE_ESSENCE.getId()) == 0 && amountInInventory(player, RUNE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need rune essence or pure essence in order to craft this rune."); return false; } - if (altar.isOurania() && !player.getInventory().containsItem(PURE_ESSENCE)) { - player.getPacketDispatch().sendMessage("You need pure essence to craft this rune."); + if (altar.isOurania() && amountInInventory(player, PURE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need pure essence to craft this rune."); return false; } - if (combination && player.getSkills().getLevel(Skills.RUNECRAFTING) < combo.getLevel()) { - player.getPacketDispatch().sendMessage("You need a Runecrafting level of at least " + combo.getLevel() + " to combine this rune."); + if (combination && getDynLevel(player, Skills.RUNECRAFTING) < combo.getLevel()) { + sendMessage(player, "You need a Runecrafting level of at least " + combo.getLevel() + " to combine this rune."); return false; } if (node != null) { if (node.getName().contains("rune") && !hasSpellImbue()) { final Rune r = Rune.forItem(node); final Talisman t = Talisman.forName(r.name()); - if (!player.getInventory().containsItem(t.getTalisman())) { - player.getPacketDispatch().sendMessage("You don't have the correct talisman to combine this rune."); + if (amountInInventory(player, t.getTalisman().getId()) == 0) { + sendMessage(player, "You don't have the correct talisman to combine this rune."); return false; } talisman = t; @@ -167,37 +170,63 @@ public final class RuneCraftPulse extends SkillPulse { return true; } - @Override - public void message(int type) { - switch (type) { - case 1: - if (altar != Altar.OURANIA) { - player.getPacketDispatch().sendMessage("You bind the temple's power into " + (combination ? combo.getRune().getName().toLowerCase() : rune.getRune().getName().toLowerCase()) + "s."); - } else { - player.getPacketDispatch().sendMessage("You bind the temple's power into runes."); - } - break; - } - } + private static final int[][] OuraniaTable = { //https://x.com/JagexAsh/status/1312893446395506688/photo/1 + /*level up to 9*/ { 2, 7, 15, 30, 60, 105, 165, 250, 400, 700,1300,2500,5000,10000}, + /*level up to 19*/ { 3, 9, 21, 45, 85, 145, 225, 400,1000,2200,4600,6700,8500,10000}, + /*level up to 29*/ { 8, 23, 55, 110, 220, 430, 850,1650,3250,4750,6150,7500,8800,10000}, + /*level up to 39*/ { 20, 60, 120, 250, 500,1000,2000,4000,5300,6500,7600,8500,9300,10000}, + /*level up to 49*/ { 40, 120, 240, 500,1000,2000,4000,5500,6500,7300,8050,8750,9400,10000}, + /*level up to 59*/ { 80, 250, 600,1300,2650,4150,5250,6250,7000,7700,8350,8950,9500,10000}, + /*level up to 69*/ {100, 300, 700,1500,3050,4450,5500,6450,7200,7900,8500,9050,9550,10000}, + /*level up to 79*/ {200, 700,1700,3500,5000,6200,7100,7800,8300,8700,9100,9400,9700,10000}, + /*level up to 89*/ {400,1000,2450,3900,5250,6300,7100,7800,8400,8900,9300,9600,9800,10000}, + /*level up to 98*/ {650,1650,3300,4750,6100,7100,7800,8400,8900,9300,9600,9800,9900,10000}, + /*level up to 99*/ {900,2200,3750,5200,6550,7500,8100,8600,9000,9300,9600,9800,9900,10000} + }; /** * Method used to craft runes. */ private void craft() { - final Item item = new Item(getEssence().getId(), getEssenceAmount()); + final Item item = getEssenceItem(); int amount = player.getInventory().getAmount(item); - if (!altar.isOurania()) { + if (altar.isOurania()) { + if (removeItem(player, item, Container.INVENTORY)) { + sendMessage(player, "You bind the temple's power into runes."); + player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount); + + int[] OuraniaValues; + if (getDynLevel(player, Skills.RUNECRAFTING) == 99) { + OuraniaValues = OuraniaTable[10]; + } else { + int index = getDynLevel(player, Skills.RUNECRAFTING) / 10; + OuraniaValues = OuraniaTable[index]; + } + for (int i = 0; i < amount; i++) { + int roll = RandomFunction.random(10000); + Rune rune = null; + for (int j = 0; j < 14; j++) { + if (roll < OuraniaValues[j]) { + rune = Rune.values()[13 - j]; + break; + } + } + rewardXP(player, Skills.RUNECRAFTING, rune.getExperience() * 2); + addItemOrDrop(player, rune.getRune().getId(), 1); + } + } + } else { int total = 0; for(int j = 0; j < amount; j++) { // since getMultiplier is stochastic, roll `amount` independent copies total += getMultiplier(); } - Item i = new Item(rune.getRune().getId(), total); - if (player.getInventory().remove(item) && player.getInventory().hasSpaceFor(i)) { - player.getInventory().add(i); + if (removeItem(player, item, Container.INVENTORY)) { + sendMessage(player, "You bind the temple's power into " + (combination ? combo.getRune().getName().toLowerCase() : rune.getRune().getName().toLowerCase()) + "s."); + addItemOrDrop(player, rune.getRune().getId(), total); player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount); - + // Fist of guthix gloves double xp = rune.getExperience() * amount; if ((altar == Altar.AIR && inEquipment(player, Items.AIR_RUNECRAFTING_GLOVES_12863, 1)) @@ -205,7 +234,7 @@ public final class RuneCraftPulse extends SkillPulse { || (altar == Altar.EARTH && inEquipment(player, Items.EARTH_RUNECRAFTING_GLOVES_12865, 1))) { xp += xp * FOGGlovesManager.updateCharges(player, amount) / amount; } - player.getSkills().addExperience(Skills.RUNECRAFTING, xp, true); + rewardXP(player, Skills.RUNECRAFTING, xp); // Achievement Diary handling // Craft some nature runes @@ -213,7 +242,7 @@ public final class RuneCraftPulse extends SkillPulse { player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 2, 3); } // Craft 196 or more air runes simultaneously - if (altar == Altar.AIR && i.getAmount() >= 196) { + if (altar == Altar.AIR && total >= 196) { player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 2, 2); } // Craft a water rune at the Water Altar @@ -222,57 +251,34 @@ public final class RuneCraftPulse extends SkillPulse { } } - } else { - if (player.getInventory().remove(item)) { - player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount); - for (int i = 0; i < amount; i++) { - Rune rune = null; - while (rune == null) { - final Rune temp = Rune.values()[RandomFunction.random(Rune.values().length)]; - if (player.getSkills().getLevel(Skills.RUNECRAFTING) >= temp.getLevel()) { - rune = temp; - } else { - if (RandomFunction.random(3) == 1) { - rune = temp; - } - } - } - player.getSkills().addExperience(Skills.RUNECRAFTING, rune.getExperience() * 2, true); - Item runeItem = rune.getRune(); - player.getInventory().add(runeItem); - } - } } } /** * Method used to combine runes. */ - private final void combine() { + private void combine() { final Item remove = node.getName().contains("talisman") ? node : talisman != null ? talisman.getTalisman() : Talisman.forName(Rune.forItem(node).name()).getTalisman(); boolean imbued = hasSpellImbue(); - if (!imbued ? player.getInventory().remove(remove) : imbued) { + if (!imbued ? removeItem(player, remove, Container.INVENTORY) : imbued) { int amount = 0; int essenceAmt = player.getInventory().getAmount(PURE_ESSENCE); final Item rune = node.getName().contains("rune") ? Rune.forItem(node).getRune() : Rune.forName(Talisman.forItem(node).name()).getRune(); int runeAmt = player.getInventory().getAmount(rune); - if (essenceAmt > runeAmt) { - amount = runeAmt; - } else { - amount = essenceAmt; - } - if (player.getInventory().remove(new Item(PURE_ESSENCE.getId(), amount)) && player.getInventory().remove(new Item(rune.getId(), amount))) { + amount = Math.min(essenceAmt, runeAmt); + if (removeItem(player, new Item(PURE_ESSENCE.getId(), amount), Container.INVENTORY) && removeItem(player, new Item(rune.getId(), amount), Container.INVENTORY)) { for (int i = 0; i < amount; i++) { if (RandomFunction.random(1, 3) == 1 || hasBindingNecklace()) { - player.getInventory().add(new Item(combo.getRune().getId(), 1)); - player.getSkills().addExperience(Skills.RUNECRAFTING, combo.getExperience(), true); + addItemOrDrop(player, combo.getRune().getId(), 1); + rewardXP(player, Skills.RUNECRAFTING, combo.getExperience()); } } if (hasBindingNecklace()) { player.getEquipment().get(EquipmentContainer.SLOT_AMULET).setCharge(player.getEquipment().get(EquipmentContainer.SLOT_AMULET).getCharge() - 1); if (1000 - player.getEquipment().get(EquipmentContainer.SLOT_AMULET).getCharge() > 14) { - player.getEquipment().remove(BINDING_NECKLACE, true); - player.getPacketDispatch().sendMessage("Your binding necklace crumbles into dust."); + if (player.getEquipment().remove(BINDING_NECKLACE, true)) { + sendMessage(player, "Your binding necklace crumbles into dust."); + } } } } @@ -289,39 +295,21 @@ public final class RuneCraftPulse extends SkillPulse { } /** - * Gets the essence amount. + * Gets the rune essence item. * - * @return the amount of essence. + * @return the rune essence item. */ - private int getEssenceAmount() { - if (altar.isOurania() && player.getInventory().containsItem(PURE_ESSENCE)) { - return player.getInventory().getAmount(PURE_ESSENCE); + private Item getEssenceItem() { + if (altar.isOurania() && amountInInventory(player, PURE_ESSENCE.getId()) > 0) { + return new Item(PURE_ESSENCE.getId(), amountInInventory(player, PURE_ESSENCE.getId())); } - if (!rune.isNormal() && player.getInventory().containsItem(PURE_ESSENCE)) { - return player.getInventory().getAmount(PURE_ESSENCE); - } else if (rune.isNormal() && player.getInventory().containsItem(PURE_ESSENCE)) { - return player.getInventory().getAmount(PURE_ESSENCE); - } else { - return player.getInventory().getAmount(RUNE_ESSENCE); + if (!rune.isNormal() && amountInInventory(player, PURE_ESSENCE.getId()) > 0) { + return new Item(PURE_ESSENCE.getId(), amountInInventory(player, PURE_ESSENCE.getId())); } - } - - /** - * Gets the rune essence that needs to be defined. - * - * @return the item. - */ - private Item getEssence() { - if (altar.isOurania() && player.getInventory().containsItem(PURE_ESSENCE)) { - return PURE_ESSENCE; - } - if (!rune.isNormal() && player.getInventory().containsItem(PURE_ESSENCE)) { - return PURE_ESSENCE; - } else if (rune.isNormal() && player.getInventory().containsItem(PURE_ESSENCE)) { - return PURE_ESSENCE; - } else { - return RUNE_ESSENCE; + if (rune.isNormal() && amountInInventory(player, RUNE_ESSENCE.getId()) > 0) { + return new Item(RUNE_ESSENCE.getId(), amountInInventory(player, RUNE_ESSENCE.getId())); } + return new Item(PURE_ESSENCE.getId(), amountInInventory(player, PURE_ESSENCE.getId())); } /** @@ -333,7 +321,7 @@ public final class RuneCraftPulse extends SkillPulse { if (altar.isOurania()) { return 1; } - int rcLevel = player.getSkills().getLevel(Skills.RUNECRAFTING); + int rcLevel = getDynLevel(player, Skills.RUNECRAFTING); int runecraftingFormulaRevision = ServerConstants.RUNECRAFTING_FORMULA_REVISION; boolean lumbridgeDiary = player.getAchievementDiaryManager().getDiary(DiaryType.LUMBRIDGE).isComplete(1); return RuneCraftPulse.getMultiplier(rcLevel, rune, runecraftingFormulaRevision, lumbridgeDiary); @@ -348,7 +336,7 @@ public final class RuneCraftPulse extends SkillPulse { } } - if(multipleLevels.length > i && runecraftingFormulaRevision >= 573) { + if (multipleLevels.length > i && runecraftingFormulaRevision >= 573) { int a = Math.max(multipleLevels[i-1], rune.getLevel()); int b = multipleLevels[i]; if(b <= 99 || runecraftingFormulaRevision >= 581) { @@ -385,5 +373,4 @@ public final class RuneCraftPulse extends SkillPulse { public Altar getAltar() { return altar; } - } diff --git a/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt b/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt index 41779cf1f..599ca05b0 100644 --- a/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt +++ b/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt @@ -11,7 +11,7 @@ import core.tools.colorize /** * Handles the rune pouches. - * @author Ceikry + * @author Ceikry, Player Name */ class RunePouchPlugin : OptionHandler() { @Throws(Throwable::class) @@ -37,21 +37,11 @@ class RunePouchPlugin : OptionHandler() { if(preferenceFlag == 0) rEssAmt else pEssAmt ) - - if(player.pouchManager.isDecayedPouch(node.id)){ - player.debug("E2") - when(option) { //Handling for IF the pouch has already completely decayed - "drop" -> player.dialogueInterpreter.open(9878,Item(node.id)) - else -> player.sendMessage(colorize("%RThis pouch has completely decayed and needs to be repaired.")) - } - } else { - player.debug("E") - when (option) { //Normal handling - "fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id) - "empty" -> player.pouchManager.withdrawFromPouch(node.id) - "check" -> player.pouchManager.checkAmount(node.id) - "drop" -> player.dialogueInterpreter.open(9878,Item(node.id)) - } + when (option) { + "fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id) + "empty" -> player.pouchManager.withdrawFromPouch(node.id) + "check" -> player.pouchManager.checkAmount(node.id) + "drop" -> player.dialogueInterpreter.open(9878,Item(node.id)) } return true } @@ -59,4 +49,4 @@ class RunePouchPlugin : OptionHandler() { override fun isWalk(): Boolean { return false } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java b/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java index 6bb69109f..954948eaf 100644 --- a/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java +++ b/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java @@ -24,6 +24,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles runecraftign related options. @@ -52,7 +53,7 @@ public class RunecraftingPlugin extends OptionHandler { @Override public boolean handle(final Player player, Node node, String option) { - if (!player.getQuestRepository().isComplete("Rune Mysteries") && player.getDetails().getRights() != Rights.ADMINISTRATOR) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES) && player.getDetails().getRights() != Rights.ADMINISTRATOR) { player.getPacketDispatch().sendMessage("You need to finish the Rune Mysteries Quest in order to do this."); return true; } @@ -97,7 +98,7 @@ public class RunecraftingPlugin extends OptionHandler { } Altar a = Altar.forObject(((Scenery) node)); if (a == Altar.ASTRAL) { - if (!hasRequirement(player, "Lunar Diplomacy")) + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return true; } player.getPulseManager().run(new RuneCraftPulse(player, null, a, false, null)); diff --git a/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java b/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java index b7297429e..a7b6450cd 100644 --- a/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java +++ b/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java @@ -4,6 +4,9 @@ import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.replaceAllItems; /** * Handles the dark mages dialogue. @@ -140,26 +143,19 @@ public final class DarkMageDialogue extends DialoguePlugin { private boolean repair() { player.pouchManager.getPouches().forEach((id, pouch) -> { pouch.setCurrentCap(pouch.getCapacity()); - pouch.setCharges(10); - Item essence = null; - if(!pouch.getContainer().isEmpty()){ - int ess = pouch.getContainer().get(0).getId(); - int amount = pouch.getContainer().getAmount(ess); - essence = new Item(ess,amount); + pouch.setCharges(pouch.getMaxCharges()); + Item essItem = null; + if (!pouch.getContainer().isEmpty()) { + int essence = pouch.getContainer().get(0).getId(); + int amount = pouch.getContainer().getAmount(essence); + essItem = new Item(essence, amount); } pouch.remakeContainer(); - if(essence != null){ - pouch.getContainer().add(essence); + if (essItem != null) { + pouch.getContainer().add(essItem); } - if(id != 5509) { - if (player.getInventory().contains(id + 1, 1)) { - player.getInventory().remove(new Item(id + 1, 1)); - player.getInventory().add(new Item(id, 1)); - } - if (player.getBank().contains(id + 1, 1)) { - player.getBank().remove(new Item(id + 1, 1)); - player.getBank().add(new Item(id, 1)); - } + if (id != Items.SMALL_POUCH_5509) { + replaceAllItems(player, id + 1, id); } }); return true; diff --git a/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java b/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java index 1b46aa4e0..ab06e4843 100644 --- a/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java +++ b/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.item.Item; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** @@ -51,7 +52,7 @@ public final class ZamorakMageDialogue extends DialoguePlugin { public boolean open(Object... args) { npc = (NPC) args[0]; varrockMage = npc.getId() == 2261 || npc.getId() == 2260; - if (!player.getQuestRepository().isComplete("Rune Mysteries")) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { end(); player.sendMessage("The mage doesn't seem interested in talking to you."); return true; @@ -190,7 +191,7 @@ public final class ZamorakMageDialogue extends DialoguePlugin { stage++; break; case 201: - npc("And there is an ubundant supply of this 'essence' there", "you say?"); + npc("And there is an abundant supply of this 'essence' there", "you say?"); stage++; break; case 202: @@ -299,7 +300,7 @@ public final class ZamorakMageDialogue extends DialoguePlugin { switch (stage) { case 0: if (!player.hasItem(ORBS[0]) && !player.getInventory().containsItem(ORBS[1])) { - player("Uh...", "No...", "I kinda lost that orb thingy that you have me."); + player("Uh...", "No...", "I kinda lost that orb thingy that you gave me."); stage++; break; } @@ -313,14 +314,14 @@ public final class ZamorakMageDialogue extends DialoguePlugin { break; case 1: player.getInventory().add(ORBS[0], player); - npc("What?", "Incompetent fool. Take this.", "And do not make me refret allying myself with you."); + npc("What?", "Incompetent fool. Take this.", "And do not make me regret allying myself with you."); stage++; break; case 2: end(); break; case 3: - npc("I assume the task to be self-explainatory.", "What is it you wish to know?"); + npc("I assume the task to be self-explanatory.", "What is it you wish to know?"); stage++; break; case 4: @@ -328,7 +329,7 @@ public final class ZamorakMageDialogue extends DialoguePlugin { stage++; break; case 5: - npc("All I wish for you to do is to teleport to this 'rune", "essence' location from three different locations wile", "carrying the scrying orb I gave you.", "It will collect the data as you teleport."); + npc("All I wish for you to do is to teleport to this 'rune", "essence' location from three different locations while", "carrying the scrying orb I gave you.", "It will collect the data as you teleport."); stage++; break; case 6: diff --git a/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt b/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt index 0ad090fcd..7de63cfd9 100644 --- a/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt +++ b/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt @@ -1,27 +1,56 @@ package content.global.skill.skillcapeperks +import core.api.sendMessage +import core.game.container.Container import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import core.game.container.impl.EquipmentContainer +import content.data.skill.SkillcapePerks as DataSkillcapes +import content.global.skill.slayer.SlayerEquipmentFlags +import org.rs09.consts.Items +import java.util.ArrayList class SkillcapeEquipmentPlugin : InteractionListener { override fun defineListeners() { val capeIds = ArrayList() - for(cape in content.data.skill.SkillcapePerks.values()){ + for(cape in DataSkillcapes.values()){ cape.skillcapeIds.forEach { capeIds.add(it) } } val capes = capeIds.toIntArray() - - onEquip(capes){player, node -> - val skillcape = Skillcape.forId(node.id) - val perk = SkillcapePerks.forSkillcape(skillcape) - perk.activate(player) - return@onEquip true - } - + onEquip(capes){player, node -> true} onUnequip(capes){player, node -> val skillcape = Skillcape.forId(node.id) + // For Temple of Ikov. Do not let player unequip firemaking skillcape in the dark basement (need to keep an active light source). + if(player.location.isInRegion(10648) && (node.id == Items.FIREMAKING_CAPE_9804 || node.id == Items.FIREMAKING_CAPET_9805) && GameWorld.settings?.skillcape_perks == true) { + sendMessage(player, "Unequipping that skillcape would leave you without a light source.") + return@onUnequip false + } val perk = SkillcapePerks.forSkillcape(skillcape) perk.deactivate(player) return@onUnequip true } } -} \ No newline at end of file + companion object { + @JvmStatic + fun updateCapePerks(player: Player, c: Container, slot: Int) { + if (slot == EquipmentContainer.SLOT_CAPE) { + val cape = c.get(slot) + for (perk in SkillcapePerks.values()) { + if (SkillcapePerks.isActive(perk, player)) { + perk.deactivate(player) + } + } + if (cape != null) { + val skillcape = Skillcape.forId(cape.id) + val perk = SkillcapePerks.forSkillcape(skillcape) + if (perk != SkillcapePerks.NONE) { + perk.activate(player) + } + } + } + EquipmentContainer.updateBonuses(player) + SlayerEquipmentFlags.updateFlags(player) + } + } +} diff --git a/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt b/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt index 7ee273098..148696543 100644 --- a/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt +++ b/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt @@ -1,21 +1,29 @@ package content.global.skill.skillcapeperks -import core.game.component.Component -import core.game.node.entity.player.Player -import core.game.node.entity.player.link.SpellBookManager -import core.game.node.entity.player.link.TeleportManager +import content.data.Quests +import content.global.skill.farming.PatchType +import content.global.skill.farming.Plantable import content.global.skill.runecrafting.Altar -import core.game.world.map.Location -import core.game.world.map.zone.impl.DarkZone -import core.plugin.Initializable -import core.game.world.GameWorld -import content.global.skill.farming.* import core.ServerStore import core.ServerStore.Companion.getBoolean import core.ServerStore.Companion.getInt -import core.api.* +import core.api.closeDialogue +import core.api.getAttribute +import core.api.hasRequirement +import core.api.sendDialogue +import core.api.sendMessage +import core.api.teleport import core.cache.def.impl.ItemDefinition -import org.rs09.consts.Items +import core.game.component.Component +import core.game.event.SpellbookChangeEvent +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.TeleportManager +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.zone.impl.DarkZone +import core.plugin.Initializable enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? = null) { BAREFISTED_SMITHING("cape_perks:barefisted-smithing"), @@ -47,7 +55,6 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? player.dialogueInterpreter.sendDialogue("Your cape is still on cooldown.") } else { player.dialogueInterpreter.open(509871233) - store[player.name] = used + 1 } }), SEED_ATTRACTION("cape_perks:seed_attract",{player -> @@ -130,8 +137,15 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? player.setAttribute("/save:$attribute",true) } player.debug("Activated ${this.name}") - if(this == CONSTANT_GLOW) + if(this == CONSTANT_GLOW) { DarkZone.checkDarkArea(player) + // For Temple of Ikov - if you are in the dark basement and put on the firemaking cape with its 2009Scape light source perk, switch to the light basement. + // For the listener that teleports if you light a normal light source, see content.global.skill.crafting.lightsources.LightSourceLighter.kt + if(player.location.isInRegion(10648) && player.location.withinDistance(Location(2639,9738,0), 8)) { + teleport(player, Location.create(player.getLocation().x, player.getLocation().y + 23, player.getLocation().z)) + closeDialogue(player) + } + } } fun operate(player: Player){ @@ -149,70 +163,74 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? } @Initializable - class MagicCapeDialogue(player: Player? = null): core.game.dialogue.DialoguePlugin(player){ - override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { - return MagicCapeDialogue(player) - } + class MagicCapeDialogue(player : Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun newInstance(player : Player?) : core.game.dialogue.DialoguePlugin { + return MagicCapeDialogue(player) + } - override fun open(vararg args: Any?): Boolean { - when(player.spellBookManager.spellBook){ - SpellBookManager.SpellBook.ANCIENT.interfaceId -> options("Modern","Lunar") - SpellBookManager.SpellBook.MODERN.interfaceId -> options("Ancient","Lunar") - SpellBookManager.SpellBook.LUNAR.interfaceId -> options ("Modern","Ancient") - } - return true - } + override fun open(vararg args : Any?) : Boolean { + when (player.spellBookManager.spellBook) { + SpellBookManager.SpellBook.ANCIENT.interfaceId -> options("Modern", "Lunar") + SpellBookManager.SpellBook.MODERN.interfaceId -> options("Ancient", "Lunar") + SpellBookManager.SpellBook.LUNAR.interfaceId -> options("Modern", "Ancient") + } + return true + } - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - val spellbook = when(player.spellBookManager.spellBook){ - SpellBookManager.SpellBook.ANCIENT.interfaceId -> { - when(buttonId){ - 1 -> SpellBookManager.SpellBook.MODERN - 2 -> SpellBookManager.SpellBook.LUNAR - else -> null - } - } + override fun handle(interfaceId : Int, buttonId : Int) : Boolean { + val spellbook = when (player.spellBookManager.spellBook) { + SpellBookManager.SpellBook.ANCIENT.interfaceId -> { + when (buttonId) { + 1 -> SpellBookManager.SpellBook.MODERN + 2 -> SpellBookManager.SpellBook.LUNAR + else -> null + } + } - SpellBookManager.SpellBook.MODERN.interfaceId -> { - when(buttonId){ - 1 -> SpellBookManager.SpellBook.ANCIENT - 2 -> SpellBookManager.SpellBook.LUNAR - else -> null - } - } + SpellBookManager.SpellBook.MODERN.interfaceId -> { + when (buttonId) { + 1 -> SpellBookManager.SpellBook.ANCIENT + 2 -> SpellBookManager.SpellBook.LUNAR + else -> null + } + } - SpellBookManager.SpellBook.LUNAR.interfaceId -> { - when(buttonId){ - 1 -> SpellBookManager.SpellBook.MODERN - 2 -> SpellBookManager.SpellBook.ANCIENT - else -> null - } - } + SpellBookManager.SpellBook.LUNAR.interfaceId -> { + when (buttonId) { + 1 -> SpellBookManager.SpellBook.MODERN + 2 -> SpellBookManager.SpellBook.ANCIENT + else -> null + } + } - else -> null - } + else -> null + } - end() - if(spellbook != null){ - if (spellbook == SpellBookManager.SpellBook.ANCIENT) { - if (!hasRequirement(player, "Desert Treasure")) - return true - } - else if (spellbook == SpellBookManager.SpellBook.LUNAR) { - if (!hasRequirement(player, "Lunar Diplomacy")) - return true - } - player.spellBookManager.setSpellBook(spellbook) - player.interfaceManager.openTab(Component(spellbook.interfaceId)) - player.incrementAttribute("/save:cape_perks:librarian-magus-charges",-1) - } - return true - } - - override fun getIds(): IntArray { - return intArrayOf(509871234) - } + end() + if (spellbook != null) { + if (spellbook == SpellBookManager.SpellBook.ANCIENT) { + if (!hasRequirement(player, Quests.DESERT_TREASURE)) return true + } else if (spellbook == SpellBookManager.SpellBook.LUNAR) { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return true + } + val weaponInterface = player.getExtension(WeaponInterface::class.java) + if (weaponInterface != null && player.properties.autocastSpell != null) { + weaponInterface.selectAutoSpell(-1, true) + } + player.dispatch(SpellbookChangeEvent( + SpellBookManager.SpellBook.forInterface(player.spellBookManager.spellBook), + spellbook, + SpellBookManager.SpellbookChangeSource.MAGIC_CAPE_PERK)) + player.spellBookManager.setSpellBook(spellbook) + player.interfaceManager.openTab(Component(spellbook.interfaceId)) + player.incrementAttribute("/save:cape_perks:librarian-magus-charges", -1) + } + return true + } + override fun getIds() : IntArray { + return intArrayOf(509871234) + } } @Initializable @@ -222,54 +240,69 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? } override fun open(vararg args: Any?): Boolean { - options("Air","Mind","Water","Earth","More...") + altarList(0) stage = 0 return true } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - 0 -> when(buttonId){ + when(stage) { + 0 -> when(buttonId) { 1 -> sendAltar(player, Altar.AIR) 2 -> sendAltar(player, Altar.MIND) 3 -> sendAltar(player, Altar.WATER) 4 -> sendAltar(player, Altar.EARTH) - 5 -> options("Fire","Body","Cosmic","Chaos","More...").also { stage++ } + 5 -> altarList(++stage) } - 1 -> when(buttonId){ - 1 -> sendAltar(player, Altar.FIRE) - 2 -> sendAltar(player, Altar.BODY) - 3 -> sendAltar(player, Altar.COSMIC) - 4 -> sendAltar(player, Altar.CHAOS) - 5 -> options("Astral","Nature","Law","Death","More...").also { stage++ } + 1 -> when(buttonId) { + 1 -> altarList(--stage) + 2 -> sendAltar(player, Altar.FIRE) + 3 -> sendAltar(player, Altar.BODY) + 4 -> sendAltar(player, Altar.COSMIC) + 5 -> altarList(++stage) } - 2 -> when(buttonId){ - 1 -> sendAltar(player, Altar.ASTRAL) - 2 -> sendAltar(player, Altar.NATURE) - 3 -> sendAltar(player, Altar.LAW) - 4 -> sendAltar(player, Altar.DEATH) - 5 -> options("Blood","Nevermind").also { stage++ } + 2 -> when(buttonId) { + 1 -> altarList(--stage) + 2 -> sendAltar(player, Altar.CHAOS) + 3 -> sendAltar(player, Altar.ASTRAL) + 4 -> sendAltar(player, Altar.NATURE) + 5 -> altarList(++stage) } - 3 -> when(buttonId){ - 1 -> sendAltar(player, Altar.BLOOD) - 2 -> end() + 3 -> when(buttonId) { + 1 -> altarList(--stage) + 2 -> sendAltar(player, Altar.LAW) + 3 -> sendAltar(player, Altar.DEATH) + 4 -> sendAltar(player, Altar.BLOOD) + 5 -> altarList(0).also { stage = 0 } } } return true } - fun sendAltar(player: Player,altar: Altar){ + fun altarList(stage: Int) { + when (stage) { + 0 -> options("Air", "Mind", "Water", "Earth", "More...") + 1 -> options("Back...", "Fire", "Body", "Cosmic", "More...") + 2 -> options("Back...", "Chaos", "Astral", "Nature", "More...") + 3 -> options("Back...", "Law", "Death", "Blood", "More...") + } + } + + fun sendAltar(player: Player,altar: Altar) { end() - if (altar == Altar.DEATH && !hasRequirement(player, "Mourning's End Part II")) return - if (altar == Altar.ASTRAL && !hasRequirement(player, "Lunar Diplomacy")) return - if (altar == Altar.BLOOD && !hasRequirement(player, "Legacy of Seergaze")) return + if (altar == Altar.DEATH && !hasRequirement(player, Quests.MOURNINGS_END_PART_II)) return + if (altar == Altar.ASTRAL && !hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return + if (altar == Altar.BLOOD && !hasRequirement(player, Quests.LEGACY_OF_SEERGAZE)) return if (altar == Altar.LAW && !ItemDefinition.canEnterEntrana(player)) { - sendItemDialogue(player, Items.SARADOMIN_SYMBOL_8055, "No weapons or armour are permitted on holy Entrana.") + sendMessage(player, "The power of Saradomin prevents you from taking armour or weaponry to Entrana."); return } var endLoc = if (altar == Altar.ASTRAL) Location.create(2151, 3864, 0) else altar.ruin.end + val store = ServerStore.getArchive("daily-abyss-warp") + val used = store.getInt(player.name,0) + store[player.name] = used + 1 player.teleporter.send(endLoc, TeleportManager.TeleportType.TELE_OTHER) player.incrementAttribute("/save:cape_perks:abyssal_warp",-1) } diff --git a/Server/src/main/content/global/skill/slayer/FishingExplosivePlugin.java b/Server/src/main/content/global/skill/slayer/FishingExplosivePlugin.java deleted file mode 100644 index 196a4c62d..000000000 --- a/Server/src/main/content/global/skill/slayer/FishingExplosivePlugin.java +++ /dev/null @@ -1,228 +0,0 @@ -package content.global.skill.slayer; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.OptionHandler; -import core.game.interaction.UseWithHandler; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.CombatStyle; -import core.game.node.entity.combat.ImpactHandler.HitsplatType; -import core.game.node.entity.impl.Projectile; -import core.game.node.entity.npc.AbstractNPC; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.HintIconManager; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Direction; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.tools.RandomFunction; - -/** - * Represents the plugin used to handle the fishing expolosive on a omnious - * fishing spot. - * @author 'Vexia - */ -@Initializable -public final class FishingExplosivePlugin extends OptionHandler { - - /** - * Represents the ominous fishing spot ids. - */ - private final static int[] IDS = new int[] { 10087, 10088, 10089 }; - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int id : IDS) { - SceneryDefinition.forId(id).getHandlers().put("option:lure", this); - SceneryDefinition.forId(id).getHandlers().put("option:bait", this); - } - new FishingExplosiveHandler().newInstance(arg); - new MogreNPC().newInstance(arg); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - player.getPacketDispatch().sendMessage("Something seems to have scared all the fishes away..."); - return true; - } - - @Override - public Location getDestination(Node node, Node n) { - return node.getLocation(); - } - - /** - * Represents the handler for the fishing expolsive on a fishing spot. - * @author 'Vexia - * @version 1.0 - */ - public static final class FishingExplosiveHandler extends UseWithHandler { - - /** - * Represents the throwing animation. - */ - private static final Animation ANIMATION = new Animation(385); - - /** - * Represents the splashing graphics. - */ - private static final Graphics SPLASH_GRAPHIC = new Graphics(68); - - /** - * Represents the npc mogre id. - */ - private static final int MOGRE_ID = 114; - - /** - * Represents the messages used to send for the mogres. - */ - private static final String[] MESSAGES = new String[] { "Da boom-boom kill all da fishies!", "I smack you good!", "Smash stupid human!", "Tasty human!", "Human hit me on the head!", "I get you!", "Human scare all da fishies!" }; - - /** - * Constructs a new {@code FishingExplosiveHandler} {@code Object}. - */ - public FishingExplosiveHandler() { - super(6664, 12633); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int i : IDS) { - addHandler(i, OBJECT_TYPE, this); - } - return this; - } - - @Override - public boolean handle(final NodeUsageEvent event) { - final Player player = event.getPlayer(); - if (player.getAttributes().containsKey("hasMogre")) { - player.getDialogueInterpreter().sendDialogues(player, null, "Sinister as that fishing spot is, why would I want to", "explode it?"); - return true; - } - if (!player.getInventory().remove(new Item(event.getUsedItem().getId(), 1))) { - return true; - } - final int delay = (int) (2 + (player.getLocation().getDistance(event.getUsedWith().getLocation())) * 0.5); - player.animate(ANIMATION); - player.getPacketDispatch().sendMessage("You hurl the shuddering vial into the water..."); - sendProjectile(player, (Scenery) event.getUsedWith()); - GameWorld.getPulser().submit(new Pulse(delay, player) { - @Override - public boolean pulse() { - Direction dir = event.getUsedWith().getDirection(); - NPC mogre = NPC.create(MOGRE_ID, event.getUsedWith().getLocation().transform(dir.getStepX() << 1, dir.getStepY() << 1, 0)); - mogre.init(); - mogre.moveStep(); - mogre.setRespawn(false); - mogre.getProperties().getCombatPulse().attack(player); - mogre.setAttribute("player", player); - mogre.sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]); - HintIconManager.registerHintIcon(player, mogre); - if (event.getUsedItem().getId() == 12633) { - mogre.getImpactHandler().manualHit(player, 15, HitsplatType.NORMAL); - } - player.setAttribute("hasMogre", true); - mogre.graphics(SPLASH_GRAPHIC); - player.getPacketDispatch().sendMessage("...and a Mogre appears!"); - return true; - } - }); - return true; - } - - /** - * Method used to send the fishign explosive projectile. - * @param player the player. - * @param object the object. - */ - private void sendProjectile(final Player player, final Scenery object) { - Projectile p = Projectile.create(player, null, 49, 30, 20, 30, Projectile.getSpeed(player, object.getLocation())); - p.setEndLocation(object.getLocation()); - p.send(); - } - - @Override - public Location getDestination(Player player, Node with) { - return player.getLocation(); - } - } - - /** - * Represents a mogre npc. - * @author 'Vexia - * @version 1.0 - */ - public final class MogreNPC extends AbstractNPC { - - /** - * Constructs a new {@code MogreNPC} {@code Object}. - * @param id the id. - * @param location the location. - */ - public MogreNPC(int id, Location location) { - super(id, location, true); - } - - /** - * Constructs a new {@code MogreNPC} {@code Object}. - */ - public MogreNPC() { - super(0, null); - } - - @Override - public void tick() { - super.tick(); - final Player pl = getAttribute("player", null); - if (pl == null || pl.getLocation().getDistance(getLocation()) > 15) { - clear(); - } - } - - @Override - public void clear() { - super.clear(); - final Player pl = getAttribute("player", null); - if (pl != null) { - pl.removeAttribute("hasMogre"); - } - } - - @Override - public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { - final Player pl = getAttribute("player", null); - return pl != null && pl == entity && super.isAttackable(entity, style, message); - } - - @Override - public void finalizeDeath(final Entity killer) { - super.finalizeDeath(killer); - if (killer instanceof Player) { - final Player player = killer.asPlayer(); - player.getAchievementDiaryManager().finishTask(player,DiaryType.FALADOR, 2, 7); - } - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new MogreNPC(id, location); - } - - @Override - public int[] getIds() { - return new int[] { 114 }; - } - - } -} diff --git a/Server/src/main/content/global/skill/slayer/Master.java b/Server/src/main/content/global/skill/slayer/Master.java index 0a3d3619d..0ce93eb54 100644 --- a/Server/src/main/content/global/skill/slayer/Master.java +++ b/Server/src/main/content/global/skill/slayer/Master.java @@ -10,270 +10,240 @@ import java.util.List; /** * A non-garbage way of representing slayer masters + * Source for task amounts: ... + * Need to add a source for weights * @author ceik + * @author gregf */ public enum Master { - TURAEL(8273, 0, 0, new int[]{15, 50}, new int[]{0, 0, 0}, + TURAEL(8273, 3, 0, new int[]{15, 50}, new int[]{0, 0, 0}, new Task(Tasks.BANSHEE, 8), new Task(Tasks.BATS, 7), - new Task(Tasks.BIRDS, 6), new Task(Tasks.BEARS, 7), - new Task(Tasks.CAVE_BUG, 8), + new Task(Tasks.BIRDS, 6), + new Task(Tasks.CAVE_BUG, 8), new Task(Tasks.CAVE_CRAWLERS, 8), new Task(Tasks.CAVE_SLIMES, 8), - new Task(Tasks.COWS, 8), + new Task(Tasks.COWS, 8), new Task(Tasks.CRAWLING_HAND, 8), + new Task(Tasks.DESERT_LIZARDS, 8), new Task(Tasks.DOG, 7), new Task(Tasks.DWARF, 7), new Task(Tasks.GHOSTS, 7), new Task(Tasks.GOBLINS, 7), new Task(Tasks.ICE_FIENDS, 8), new Task(Tasks.KALPHITES, 6), - new Task(Tasks.DESERT_LIZARDS, 8), new Task(Tasks.MINOTAURS, 7), new Task(Tasks.MONKEYS, 6), - new Task(Tasks.RATS, 7), - new Task(Tasks.SCORPIONS, 7), + new Task(Tasks.SCORPIONS, 7), new Task(Tasks.SKELETONS, 7), - new Task(Tasks.SPIDERS, 6), + new Task(Tasks.SPIDERS, 6), new Task(Tasks.WOLVES, 7), new Task(Tasks.ZOMBIES, 7)), - MAZCHNA(8274, 20, 0, new int[]{30, 70}, new int[]{2, 5, 15}, + MAZCHNA(8274, 20, 0, new int[]{40, 70}, new int[]{2, 5, 15}, new Task(Tasks.BANSHEE, 8), - new Task(Tasks.BATS,7), - new Task(Tasks.BEARS,6), - new Task(Tasks.CATABLEPONS,8), - new Task(Tasks.CAVE_BUG,8), + new Task(Tasks.BATS, 7), + new Task(Tasks.BEARS, 6), + new Task(Tasks.CATABLEPONS, 8), + new Task(Tasks.CAVE_BUG, 8), new Task(Tasks.CAVE_CRAWLERS, 8), new Task(Tasks.CAVE_SLIMES, 8), new Task(Tasks.COCKATRICES, 8), new Task(Tasks.CRAWLING_HAND, 8), new Task(Tasks.DESERT_LIZARDS, 8), - new Task(Tasks.DOG,7), - new Task(Tasks.EARTH_WARRIORS,6), - new Task(Tasks.FLESH_CRAWLERS,7), - new Task(Tasks.GHOSTS,7), + new Task(Tasks.DOG, 7), + new Task(Tasks.EARTH_WARRIORS, 6), + new Task(Tasks.FLESH_CRAWLERS, 7), + new Task(Tasks.GHOSTS, 7), new Task(Tasks.GHOULS, 7), - new Task(Tasks.HILL_GIANTS,7), + new Task(Tasks.HILL_GIANTS, 7), new Task(Tasks.HOBGOBLINS, 7), new Task(Tasks.ICE_WARRIOR, 7), - new Task(Tasks.KALPHITES,6), - //new Task(Tasks.KILLERWATTS, 6), - //new Task(Tasks.MOGRES, 8), + new Task(Tasks.KALPHITES, 6), + new Task(Tasks.MOGRES, 8), new Task(Tasks.PYREFIENDS, 8), - new Task(Tasks.ROCK_SLUGS,8), - new Task(Tasks.SCORPIONS,7), - new Task(Tasks.SHADE,8), - new Task(Tasks.SKELETONS, 7), + new Task(Tasks.ROCK_SLUGS, 8), + new Task(Tasks.SHADE, 8), + new Task(Tasks.SKELETONS, 7), new Task(Tasks.VAMPIRES, 6), - //new Task(Tasks.WALL_BEASTS,7), + // new Task(Tasks.WALL_BEASTS, 7), new Task(Tasks.WOLVES, 7), - new Task(Tasks.ZOMBIES,7)), + new Task(Tasks.ZOMBIES, 7)), - VANNAKA(1597, 40, 0, new int[]{30, 80}, new int[]{4, 20, 60}, + VANNAKA(1597, 40, 0, new int[]{60, 120}, new int[]{4, 20, 60}, new Task(Tasks.ABERRANT_SPECTRES, 8), - new Task(Tasks.ABYSSAL_DEMONS, 5), - new Task(Tasks.ANKOU,7), - new Task(Tasks.BANSHEE,6), - new Task(Tasks.BASILISKS,8), - new Task(Tasks.BLOODVELDS,8), - new Task(Tasks.BLUE_DRAGONS,7), - new Task(Tasks.BRINE_RATS,7), - new Task(Tasks.BRONZE_DRAGONS,7), - new Task(Tasks.CAVE_BUG,7), - new Task(Tasks.CAVE_CRAWLERS,7), - new Task(Tasks.CAVE_SLIMES,7), - new Task(Tasks.COCKATRICES,8), - new Task(Tasks.CRAWLING_HAND,6), - new Task(Tasks.CROCODILES,6), - new Task(Tasks.DAGANNOTHS, 7), - new Task(Tasks.DUST_DEVILS,8), - new Task(Tasks.EARTH_WARRIORS,6), - new Task(Tasks.ELVES, 7), - //new Task(Tasks.FEVER_SPIDERS,7), - new Task(Tasks.FIRE_GIANTS,7), - new Task(Tasks.GARGOYLES, 5), - new Task(Tasks.GHOULS,7), - new Task(Tasks.GREEN_DRAGONS,6), - new Task(Tasks.HARPIE_BUG_SWARMS,8), - new Task(Tasks.HELLHOUNDS,7), - new Task(Tasks.HILL_GIANTS,7), - new Task(Tasks.HOBGOBLINS,7), - new Task(Tasks.ICE_GIANTS,7), - new Task(Tasks.ICE_WARRIOR,7), - new Task(Tasks.INFERNAL_MAGES,8), - new Task(Tasks.JELLIES,8), + new Task(Tasks.ANKOU, 7), + new Task(Tasks.BANSHEE, 6), + new Task(Tasks.BASILISKS, 8), + new Task(Tasks.BLUE_DRAGONS, 7), + new Task(Tasks.BLOODVELDS, 8), + new Task(Tasks.BRINE_RATS, 7), + new Task(Tasks.CAVE_BUG, 7), + new Task(Tasks.CAVE_CRAWLERS, 7), + new Task(Tasks.CAVE_SLIMES, 7), + new Task(Tasks.COCKATRICES, 8), + new Task(Tasks.CRAWLING_HAND, 6), + new Task(Tasks.CROCODILES, 6, new Integer[]{30, 60}), + new Task(Tasks.DAGANNOTHS, 7), + new Task(Tasks.DESERT_LIZARDS, 7, new Integer[]{30, 60}), + new Task(Tasks.DUST_DEVILS, 8), + new Task(Tasks.EARTH_WARRIORS, 6, new Integer[]{30, 60}), + new Task(Tasks.ELVES, 7, new Integer[]{30, 60}), + //new Task(Tasks.FEVER_SPIDERS, 7), + new Task(Tasks.FIRE_GIANTS, 7), + new Task(Tasks.GHOULS, 7), + new Task(Tasks.GREEN_DRAGONS, 6, new Integer[]{30, 60}), + new Task(Tasks.HARPIE_BUG_SWARMS, 8), + new Task(Tasks.HELLHOUNDS, 7), + new Task(Tasks.HILL_GIANTS, 7), + new Task(Tasks.ICE_GIANTS, 7, new Integer[]{30, 60}), + new Task(Tasks.ICE_WARRIOR, 7), + new Task(Tasks.INFERNAL_MAGES, 8), + new Task(Tasks.JELLIES, 8), new Task(Tasks.JUNGLE_HORRORS, 8), - new Task(Tasks.KALPHITES,7), - //new Task(Tasks.KILLERWATTS,6), - new Task(Tasks.KURASKS,7), - new Task(Tasks.DESERT_LIZARDS,7), - new Task(Tasks.LESSER_DEMONS,7), - //new Task(Tasks.MOGRES,7), - //new Task(Tasks.MOLANISKS,7), - new Task(Tasks.MOSS_GIANTS,7), - new Task(Tasks.NECHRYAELS, 5), - new Task(Tasks.OGRES,7), - new Task(Tasks.OTHERWORDLY_BEING,8), - new Task(Tasks.PYREFIENDS,8), - new Task(Tasks.ROCK_SLUGS,7), - new Task(Tasks.SHADE,8), - //new Task(Tasks.SEA_SNAKES,6), - //new Task(Tasks.SHADOW_WARRIORS, 8), - new Task(Tasks.SPIRTUAL_MAGES,3), - new Task(Tasks.SPIRTUAL_RANGERS, 3), - new Task(Tasks.SPIRTUAL_WARRIORS,3), - //new Task(Tasks.TERROR_DOGS,6), - new Task(Tasks.TROLLS,7), + new Task(Tasks.KALPHITES, 7), + // new Task(Tasks.KILLERWATTS, 6), + new Task(Tasks.KURASKS, 7), + new Task(Tasks.LESSER_DEMONS, 7), + new Task(Tasks.MOGRES, 7), + // new Task(Tasks.MOLANISKS, 7), + new Task(Tasks.MOSS_GIANTS, 7), + new Task(Tasks.OGRES, 7), + new Task(Tasks.OTHERWORDLY_BEING, 8), + new Task(Tasks.PYREFIENDS, 8), + new Task(Tasks.ROCK_SLUGS, 7), + // new Task(Tasks.SEA_SNAKES, 6), + new Task(Tasks.SHADE, 8), + // new Task(Tasks.SHADOW_WARRIORS, 8), + new Task(Tasks.TROLLS, 7), new Task(Tasks.TUROTHS, 8), - new Task(Tasks.VAMPIRES,7), - //new Task(Tasks.WALL_BEAST,6), - new Task(Tasks.WEREWOLFS,7)), + new Task(Tasks.VAMPIRES, 7), + // new Task(Tasks.WALL_BEASTS, 6, , new Integer[]{10, 20}), + new Task(Tasks.WEREWOLVES, 7)), CHAELDAR(1598, 70, 0, new int[]{110, 170}, new int[]{10, 50, 150}, - new Task(Tasks.ABERRANT_SPECTRES,8), - new Task(Tasks.ABYSSAL_DEMONS,12), - new Task(Tasks.AVIANSIES,9), + new Task(Tasks.ABERRANT_SPECTRES, 8), + new Task(Tasks.ABYSSAL_DEMONS, 12), new Task(Tasks.BANSHEE, 5), - new Task(Tasks.BASILISKS,7), - new Task(Tasks.BLACK_DEMONS,10), - new Task(Tasks.BLOODVELDS,8), - new Task(Tasks.BLUE_DRAGONS,8), - new Task(Tasks.BRINE_RATS,7), - new Task(Tasks.BRONZE_DRAGONS,11), - new Task(Tasks.CAVE_CRAWLERS, 5), - new Task(Tasks.CAVE_HORRORS,10), - new Task(Tasks.CAVE_SLIMES,6), - new Task(Tasks.COCKATRICES,6), - new Task(Tasks.DAGANNOTHS,11), - new Task(Tasks.DUST_DEVILS,9), - new Task(Tasks.ELVES,8), - //new Task(Tasks.FEVER_SPIDERS,7), + new Task(Tasks.BASILISKS, 7), + new Task(Tasks.BLUE_DRAGONS, 8), + new Task(Tasks.BLOODVELDS, 8), + new Task(Tasks.BRINE_RATS, 7), + new Task(Tasks.BRONZE_DRAGONS, 11, new Integer[]{30, 60}), + new Task(Tasks.CAVE_BUG, 5), + new Task(Tasks.CAVE_CRAWLERS, 5), + new Task(Tasks.CAVE_HORRORS, 10), + new Task(Tasks.CAVE_SLIMES, 6), + new Task(Tasks.COCKATRICES, 6), + new Task(Tasks.CRAWLING_HAND, 5), + new Task(Tasks.CROCODILES, 5, new Integer[]{30, 60}), + new Task(Tasks.DAGANNOTHS, 11), + new Task(Tasks.DESERT_LIZARDS, 5, new Integer[]{30, 60}), + new Task(Tasks.DUST_DEVILS, 9), + new Task(Tasks.ELVES, 8, new Integer[]{60, 90}), + //new Task(Tasks.FEVER_SPIDERS, 7), new Task(Tasks.FIRE_GIANTS, 12), - new Task(Tasks.GARGOYLES,11), - new Task(Tasks.GREATER_DEMONS,9), - new Task(Tasks.HARPIE_BUG_SWARMS,6), - new Task(Tasks.HELLHOUNDS,9), - new Task(Tasks.INFERNAL_MAGES,7), - new Task(Tasks.IRON_DRAGONS,12), + new Task(Tasks.GARGOYLES, 11), + new Task(Tasks.GREATER_DEMONS, 9), + new Task(Tasks.HARPIE_BUG_SWARMS, 6), + new Task(Tasks.HELLHOUNDS, 9), + new Task(Tasks.IRON_DRAGONS, 12, new Integer[]{30, 60}), + new Task(Tasks.INFERNAL_MAGES, 7), new Task(Tasks.JELLIES, 10), - new Task(Tasks.JUNGLE_HORRORS,10), - new Task(Tasks.KALPHITES,11), + new Task(Tasks.JUNGLE_HORRORS, 10), + new Task(Tasks.KALPHITES, 11), new Task(Tasks.KURASKS, 12), - new Task(Tasks.LESSER_DEMONS,9), - new Task(Tasks.DESERT_LIZARDS, 5), - //new Task(Tasks.MOGRES,6), - //new Task(Tasks.MOLANISKS,6), - //new Task(Tasks.MUTATED_ZYGOMITES,7), + new Task(Tasks.LESSER_DEMONS, 9), + new Task(Tasks.MOGRES, 6), + // new Task(Tasks.MOLANISKS, 6), + //new Task(Tasks.MUTATED_ZYGOMITES, 7, new Integer[]{30, 60}), new Task(Tasks.NECHRYAELS, 12), - new Task(Tasks.PYREFIENDS,6), + new Task(Tasks.PYREFIENDS, 6), new Task(Tasks.ROCK_SLUGS, 5), - //new Task(Tasks.SHADOW_WARRIORS,8), - new Task(Tasks.SKELETAL_WYVERN,7), - new Task(Tasks.SPIRTUAL_WARRIORS,4), - new Task(Tasks.SPIRTUAL_RANGERS,4), - new Task(Tasks.SPIRTUAL_MAGES,4), - new Task(Tasks.STEEL_DRAGONS,9), - new Task(Tasks.TROLLS,11), + // new Task(Tasks.SHADOW_WARRIORS, 8), + new Task(Tasks.SPIRTUAL_WARRIORS, 4), + new Task(Tasks.SPIRTUAL_RANGERS, 4), + new Task(Tasks.SPIRTUAL_MAGES, 4), + new Task(Tasks.TROLLS, 11), new Task(Tasks.TUROTHS, 10)), - //new Task(Tasks.WALL_BEASTS,6), + // new Task(Tasks.WALL_BEASTS, 6, new Integer[]{10, 20}), + // new Task(Tasks.WARPED_TERROR_BIRD, 5), + // new Task(Tasks.WARPED_TORTOISE, 5) - SUMONA(7780, 90, 35, new int[]{50, 185}, new int[]{12, 60, 180}, + SUMONA(7780, 85, 35, new int[]{120, 185}, new int[]{12, 60, 180}, new Task(Tasks.ABERRANT_SPECTRES, 15), new Task(Tasks.ABYSSAL_DEMONS, 10), - new Task(Tasks.AVIANSIES, 7), new Task(Tasks.BANSHEE, 15), new Task(Tasks.BASILISKS, 15), new Task(Tasks.BLACK_DEMONS, 10), - new Task(Tasks.BLOODVELDS, 10), new Task(Tasks.BLUE_DRAGONS, 5), + new Task(Tasks.BLOODVELDS, 10), new Task(Tasks.CAVE_CRAWLERS, 15), new Task(Tasks.CAVE_HORRORS, 15), - new Task(Tasks.CROCODILES, 4), new Task(Tasks.DAGANNOTHS, 10), - new Task(Tasks.DESERT_LIZARDS, 4), new Task(Tasks.DUST_DEVILS, 15), - new Task(Tasks.ELVES, 10), + new Task(Tasks.ELVES, 10, new Integer[]{60, 90}), new Task(Tasks.FIRE_GIANTS, 10), new Task(Tasks.GARGOYLES, 10), new Task(Tasks.GREATER_DEMONS, 10), new Task(Tasks.HELLHOUNDS, 10), - new Task(Tasks.IRON_DRAGONS, 7), + new Task(Tasks.IRON_DRAGONS, 7, new Integer[]{30, 60}), new Task(Tasks.KALPHITES, 10), new Task(Tasks.KURASKS, 15), new Task(Tasks.NECHRYAELS, 10), - // newTask(Tasks.RED_DRAGONS, 5), - new Task(Tasks.SCORPIONS, 4), + new Task(Tasks.RED_DRAGONS, 5, new Integer[]{30, 60}), + // new Task(Tasks.SCABARITES, 9, new Integer[]{30, 60}), new Task(Tasks.SPIRTUAL_MAGES, 10), new Task(Tasks.SPIRTUAL_WARRIORS, 10), - // new Task(Tasks.TERROR_DOGS, 10), + // new Task(Tasks.TERROR_DOGS, 10, new Integer[]{30, 60}), new Task(Tasks.TROLLS, 10), - new Task(Tasks.TUROTHS, 15), - new Task(Tasks.VAMPIRES, 10)), - //new Task(Tasks.WARPED_TORTOISE, 15)), + new Task(Tasks.TUROTHS, 15)), + // new Task(Tasks.WARPED_TORTOISE, 15)), - DURADEL(8275, 100, 50, new int[]{50, 199}, new int[]{15, 75, 225}, - new Task(Tasks.ABERRANT_SPECTRES,7), - new Task(Tasks.ABYSSAL_DEMONS,12), - new Task(Tasks.ANKOU,5), - new Task(Tasks.AVIANSIES,8), - new Task(Tasks.BLACK_DEMONS,8), - new Task(Tasks.BLACK_DRAGONS,9), - new Task(Tasks.BLOODVELDS,8), - new Task(Tasks.BLUE_DRAGONS,4), - new Task(Tasks.CAVE_HORRORS,4), - new Task(Tasks.DAGANNOTHS,9), - new Task(Tasks.DARK_BEASTS,11), - new Task(Tasks.DUST_DEVILS,5), - new Task(Tasks.ELVES,4), - new Task(Tasks.FIRE_GIANTS,7), - new Task(Tasks.GARGOYLES,8), - new Task(Tasks.GREATER_DEMONS,9), + DURADEL(8275, 100, 50, new int[]{130, 200}, new int[]{15, 75, 225}, + new Task(Tasks.ABERRANT_SPECTRES, 7), + new Task(Tasks.ABYSSAL_DEMONS, 12), + new Task(Tasks.BLACK_DEMONS, 8), + new Task(Tasks.BLACK_DRAGONS, 9, new Integer[]{40, 80}), + new Task(Tasks.BLOODVELDS, 8), + new Task(Tasks.DAGANNOTHS, 9), + new Task(Tasks.DARK_BEASTS, 11), + new Task(Tasks.DUST_DEVILS, 5), + new Task(Tasks.FIRE_GIANTS, 7), + new Task(Tasks.GARGOYLES, 8), + new Task(Tasks.GORAKS, 9, new Integer[]{40, 80}), + new Task(Tasks.GREATER_DEMONS, 9), new Task(Tasks.HELLHOUNDS, 10), - new Task(Tasks.IRON_DRAGONS,5), - new Task(Tasks.KALPHITES,9), - new Task(Tasks.KURASKS,4), - new Task(Tasks.MITHRIL_DRAGONS,9), - new Task(Tasks.NECHRYAELS,9), - //new Task(Tasks.RED_DRAGONS,8), - new Task(Tasks.SKELETAL_WYVERN,7), - new Task(Tasks.SPIRTUAL_MAGES,2), - new Task(Tasks.SPIRTUAL_RANGERS,2), - new Task(Tasks.SPIRTUAL_WARRIORS,2), - new Task(Tasks.STEEL_DRAGONS,7), - new Task(Tasks.SUQAHS,8), - new Task(Tasks.TROLLS,6), - new Task(Tasks.TZHAAR, 10), - new Task(Tasks.VAMPIRES,8), - // new Task(Tasks.WARPED_TERRORBIRD,8), - new Task(Tasks.WATERFIENDS,2)); - //new Task(Tasks.MUTATED_ZYGOMITES,2), - //Boss Tasks below this point - Crash - //new Task(Tasks.JAD, 1), - //new Task(Tasks.COMMANDER_ZILYANA,1), - //new Task(Tasks.CHAOS_ELEMENTAL, 1), - //new Task(Tasks.GENERAL_GRARDOOR,1), - //new Task(Tasks.GIANT_MOLE,1), - //new Task(Tasks.KING_BLACK_DRAGON,1), - //new Task(Tasks.KRIL_TSUTSAROTH,1), - //new Task(Tasks.KREE_ARRA,1)); + new Task(Tasks.IRON_DRAGONS, 5, new Integer[]{40, 80}), + new Task(Tasks.KALPHITES, 9), + new Task(Tasks.MITHRIL_DRAGONS, 9, new Integer[]{4, 8}), + new Task(Tasks.NECHRYAELS, 9), + // new Task(Tasks.SCABARITES, 9, new Integer[]{40, 80}), + new Task(Tasks.SKELETAL_WYVERN, 7, new Integer[]{40, 80}), + new Task(Tasks.SPIRTUAL_MAGES, 2), + new Task(Tasks.STEEL_DRAGONS, 7, new Integer[]{40, 80}), + new Task(Tasks.SUQAHS, 8, new Integer[]{40, 80}), + // new Task(Tasks.WARPED_TERROR_BIRD, 8), + new Task(Tasks.WATERFIENDS, 2)); - private static HashMap idMap = new HashMap<>(); + private static final HashMap idMap = new HashMap<>(); static{ Arrays.stream(Master.values()).forEach(m -> idMap.putIfAbsent(m.npc_id, m)); } - int npc_id,required_combat,required_slayer; - public int[] assignment_range; - int[] streakPoints; - public List tasks; - Master(int npc_id, int required_combat, int required_slayer, int[] assignment_range, int[] streakPoints, Task... tasks) { + final int npc_id; + final int required_combat; + final int required_slayer; + public final int[] default_assignment_range; + final int[] streakPoints; + public final List tasks; + Master(int npc_id, int required_combat, int required_slayer, int[] default_assignment_range, int[] streakPoints, Task... tasks) { this.npc_id = npc_id; this.required_combat = required_combat; this.required_slayer = required_slayer; - this.assignment_range = assignment_range; + this.default_assignment_range = default_assignment_range; this.streakPoints = streakPoints; this.tasks = new ArrayList<>(Arrays.asList(tasks)); } @@ -301,9 +271,17 @@ public enum Master { public static class Task{ public Tasks task; public Integer weight; - Task(Tasks task, Integer weight){ + public Integer[] task_range; + public Task(Tasks task, Integer weight){ this.task = task; this.weight = weight; + this.task_range = new Integer[]{null, null}; + } + + Task(Tasks task, Integer weight, Integer[] task_range){ + this.task = task; + this.weight = weight; + this.task_range = task_range; } } } diff --git a/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java b/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java index aa9e96601..0f95eb9cb 100644 --- a/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java +++ b/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java @@ -1,8 +1,7 @@ package content.global.skill.slayer; import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.*; import core.game.node.entity.combat.equipment.SwitchAttack; import content.global.handlers.item.equipment.special.DragonfireSwingHandler; import core.game.node.entity.impl.Animator.Priority; @@ -13,8 +12,6 @@ import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable; import core.tools.RandomFunction; -import core.game.node.entity.combat.CombatSwingHandler; -import core.game.node.entity.combat.MultiSwingHandler; /** * Handles a mithril dragon npc. @@ -23,15 +20,23 @@ import core.game.node.entity.combat.MultiSwingHandler; @Initializable public final class MithrilDragonNPC extends AbstractNPC { - /** - * The dragonfire attack. - */ - private static final SwitchAttack DRAGONFIRE = DragonfireSwingHandler.get(false, 52, new Animation(81, Priority.HIGH), Graphics.create(1), null, null); - /** * Handles the combat. */ - private final CombatSwingHandler combatAction = new MultiSwingHandler(true, new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 500, 20, 20, 41, 40, 18, 255)), DRAGONFIRE, new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 16, 20, 20, 41, 40, 18, 255))); + private static final SwitchAttack DRAGONFIRE = DragonfireSwingHandler.get(false, 52, new Animation(81, Priority.HIGH), Graphics.create(1), null, null); + private static final SwitchAttack MELEE = new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)); + private static final SwitchAttack MAGIC = new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 500, 20, 20, 41, 40, 18, 255)); + private static class InRangeSwitchAttack extends SwitchAttack { + public InRangeSwitchAttack(CombatSwingHandler swingHandler, Animation animation, Graphics startGraphic, Graphics endGraphic, Projectile projectile) { + super(swingHandler, animation, startGraphic, endGraphic, projectile); + } + @Override + public boolean canSelect(Entity entity, Entity victim, BattleState state) { + return CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim) == InteractionType.NO_INTERACT; //only select range if not in melee distance + } + }; + private static final SwitchAttack RANGE = new InRangeSwitchAttack(CombatStyle.RANGE.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 16, 20, 20, 41, 40, 18, 255)); + private final CombatSwingHandler combatAction = new MultiSwingHandler(true, MELEE, MAGIC, DRAGONFIRE, RANGE); /** * Constructs a new {@code MithrilDragonNPC} {@code Object}. diff --git a/Server/src/main/content/global/skill/slayer/MogreNPC.kt b/Server/src/main/content/global/skill/slayer/MogreNPC.kt new file mode 100644 index 000000000..c1f5fce49 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/MogreNPC.kt @@ -0,0 +1,33 @@ +package content.global.skill.slayer + +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import org.rs09.consts.NPCs + +/** + * Represents a mogre npc. + * @author 'Vexia + * @author gregf36665 + * @version 2.0 + */ +class MogreNPC : AbstractNPC(NPCs.MOGRE_114, null) { + + override fun tick() { + super.tick() + val victim = properties.combatPulse.getVictim() + if (victim != null) { + if (victim.location.getDistance(getLocation()) > 15) { + clear() + } + } + } + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return MogreNPC() + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOGRE_114) + } +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt b/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt index c953bf9de..e8c5e01e6 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt +++ b/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt @@ -72,7 +72,7 @@ object SlayerEquipmentFlags { val isCape = SlayerManager.getInstance(player).flags.equipmentFlags == 0x3F val hasMask = hasBlackMask(player) - return if(hasMask) 1.15 + return if(hasMask) 1.1667 else if(isCape) 1.075 else 1.0 } diff --git a/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java b/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java index 25f059d22..c8a57c44a 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java +++ b/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java @@ -15,7 +15,9 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.Initializable; + import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; /** * Represents the dialogue plugin used for a slayer master. @@ -40,11 +42,6 @@ public final class SlayerMasterDialogue extends DialoguePlugin { */ private static final Item HOLY_SYMBOL = new Item(1718); - /** - * Represents the items to use. - */ - private static final Item[] ITEMS = new Item[]{new Item(9813), new Item(9814)}; - /** * Represents the coins item. */ @@ -67,8 +64,6 @@ public final class SlayerMasterDialogue extends DialoguePlugin { private final int level = 2; - private int rerolls = 0; - /** * Constructs a new {@code SlayerMasterDialogue} {@code Object}. */ @@ -98,7 +93,7 @@ public final class SlayerMasterDialogue extends DialoguePlugin { npc = (NPC) args[0]; } master = Master.forId(args[0] instanceof NPC ? ((NPC) args[0]).getId() : (int) args[0]); - quest = player.getQuestRepository().getQuest("Animal Magnetism"); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); if (master == Master.DURADEL) { if (Skillcape.isMaster(player, Skills.SLAYER)) { @@ -118,7 +113,6 @@ public final class SlayerMasterDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - rerolls = ServerStore.getInt(getStoreFile(), player.getUsername().toLowerCase(), 0); if (isDiary) { switch (stage) { case 999: @@ -349,7 +343,7 @@ public final class SlayerMasterDialogue extends DialoguePlugin { if (player.getInventory().freeSlots() != 0) { player.getInventory().add(GEM); SlayerManager.getInstance(player).generate(master); - interpreter.sendDialogues(master.getNpc(), getExpression(master), "We'll start you off hunting " + SlayerManager.getInstance(player).getTaskName() + "'s, you'll need to", "kill " + SlayerManager.getInstance(player).getAmount() + " of them."); + interpreter.sendDialogues(master.getNpc(), getExpression(master), "We'll start you off hunting " + SlayerUtils.pluralise(SlayerManager.getInstance(player).getTaskName()) + ", you'll need to", "kill " + SlayerManager.getInstance(player).getAmount() + " of them."); stage = 510; } else if (player.getInventory().freeSlots() == 0) { player("Sorry, I don't have enough inventory space."); @@ -480,36 +474,19 @@ public final class SlayerMasterDialogue extends DialoguePlugin { stage = 999; break; } - if (!SlayerManager.getInstance(player).hasTask()) { + boolean hasTask = SlayerManager.getInstance(player).hasTask(); + boolean reroll = hasTask && master == Master.TURAEL && !Master.hasSameTask(master, player); + if (!hasTask || reroll) { SlayerManager.getInstance(player).generate(master); - if (SlayerManager.getInstance(player).getTask() == Tasks.JAD) { - interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to", "defeat the almighty TzTok-Jad."); - } else { - interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to kill", "" + SlayerManager.getInstance(player).getAmount() + " " + SlayerManager.getInstance(player).getTaskName() + "s."); - } + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to kill", "" + SlayerManager.getInstance(player).getAmount() + " " + SlayerUtils.pluralise(SlayerManager.getInstance(player).getTaskName()) + "."); stage = 844; break; } - if (Master.hasSameTask(master, player)) { - interpreter.sendDialogues(master.getNpc(), getExpression(master), "You're still hunting something. But let me check something..."); - stage = 847; - } else { - SlayerManager.getInstance(player).flags.setTaskStreak(0); - SlayerManager.getInstance(player).generate(master); - if (SlayerManager.getInstance(player).getTask() == Tasks.JAD) { - interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to", "defeat the almighty TzTok-Jad."); - } else { - interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to kill", "" + SlayerManager.getInstance(player).getAmount() + " " + SlayerManager.getInstance(player).getTaskName() + "'s."); - } - stage = 844; - } + interpreter.sendDialogues(master.getNpc(), getExpression(master), "You're still hunting something. Come back when you've","finished your task."); + stage = END_DIALOGUE; break; case 844: - if (GameWorld.getSettings().getAllow_slayer_reroll()) { - options("Got any tips for me?", "Okay, great!", "I'd like to re-roll that task."); - } else { - options("Got any tips for me?", "Okay, great!"); - } + options("Got any tips for me?", "Okay, great!"); stage++; break; case 845: @@ -522,47 +499,6 @@ public final class SlayerMasterDialogue extends DialoguePlugin { player("Okay, great!"); stage = 999; break; - case 3: - player("I'd like to re-roll this task."); - if(rerolls == 10){ - stage++; - } else { - SlayerManager.getInstance(player).clear(); - getStoreFile().put(player.getUsername().toLowerCase(), rerolls + 1); - stage = 701; - } - } - break; - case 846: - npcl(FacialExpression.NEUTRAL, "Actually, you're out of free rerolls. You can buy a reroll from my reward store, though."); - stage = END_DIALOGUE; - break; - case 847: - if(rerolls < 10){ - npcl(FacialExpression.NEUTRAL, "You do have " + (10 - rerolls) + " rerolls left today, would you like to use one?"); - stage++; - } - else { - npcl(FacialExpression.NEUTRAL, "And it also seems you're out of rerolls for today. That's unfortunate."); - stage = END_DIALOGUE; - } - break; - case 848: - options("Yes, please.", "No, thanks."); - stage++; - break; - case 849: - switch(buttonId){ - case 1: - playerl(FacialExpression.FRIENDLY, "Yes, please."); - SlayerManager.getInstance(player).clear(); - getStoreFile().put(player.getUsername().toLowerCase(), rerolls + 1); - stage = 701; - break; - case 2: - playerl(FacialExpression.NEUTRAL, "No, thanks."); - stage = END_DIALOGUE; - break; } break; case 860: @@ -606,56 +542,6 @@ public final class SlayerMasterDialogue extends DialoguePlugin { } stage = 999; break; - case 906: - switch (buttonId) { - case 1: - player("May I buy a Quest Point cape?"); - stage = 907; - break; - case 2: - interpreter.sendDialogues(master.getNpc(), FacialExpression.HALF_GUILTY, "'Ello, and what are you after, then?"); - stage = 0; - break; - } - break; - case 907: - npc("You bet, " + player.getUsername() + "! Right when you give me 99000 coins."); - stage = 908; - break; - case 908: - options("Okay, here you go.", "No, thanks."); - stage = 909; - break; - case 909: - switch (buttonId) { - case 1: - player("Okay, here you go."); - stage = 910; - break; - case 2: - end(); - break; - } - break; - case 910: - if (player.getInventory().freeSlots() < 2) { - player("I don't seem to have enough inventory space."); - stage = 999; - return true; - } - if (!player.getInventory().containsItem(COINS)) { - player("I don't seem to have enough coins with", "me at this time."); - stage = 999; - return true; - } - if (player.getInventory().remove(COINS) && player.getInventory().add(ITEMS)) { - npc("Have fun with it."); - stage = 999; - } else { - player("I don't seem to have enough coins with", "me at this time."); - stage = 999; - } - break; } return true; } @@ -696,9 +582,4 @@ public final class SlayerMasterDialogue extends DialoguePlugin { public int[] getIds() { return new int[]{70, 1598, 1596, 1597, 1599, 7780, 8275, 8273, 8274, 8649}; } - - private JSONObject getStoreFile() { - return ServerStore.getArchive("daily-slayer-rerolls"); - } - } diff --git a/Server/src/main/content/global/skill/slayer/SlayerPlugin.java b/Server/src/main/content/global/skill/slayer/SlayerPlugin.java index 35d6a4544..eb02797d6 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerPlugin.java +++ b/Server/src/main/content/global/skill/slayer/SlayerPlugin.java @@ -1,7 +1,6 @@ package content.global.skill.slayer; import core.cache.def.impl.SceneryDefinition; -import core.game.global.action.ClimbActionHandler; import core.game.global.action.DigAction; import core.game.global.action.DigSpadeHandler; import core.game.interaction.OptionHandler; @@ -12,6 +11,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles related slayer nodes. @@ -27,15 +27,12 @@ public class SlayerPlugin extends OptionHandler { @Override public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(8783).getHandlers().put("option:open", this); SceneryDefinition.forId(8785).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(23158).getHandlers().put("option:exit", this); SceneryDefinition.forId(23157).getHandlers().put("option:exit", this); SceneryDefinition.forId(15767).getHandlers().put("option:enter", this); SceneryDefinition.forId(15811).getHandlers().put("option:exit", this); SceneryDefinition.forId(15812).getHandlers().put("option:exit", this); - SceneryDefinition.forId(96).getHandlers().put("option:climb-up", this); - SceneryDefinition.forId(35121).getHandlers().put("option:climb-down", this); for (Location loc : BRYNE_DIGS) { DigSpadeHandler.register(loc, new DigAction() { @Override @@ -52,31 +49,26 @@ public class SlayerPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { switch (node.getId()) { - case 8783: - player.teleport(new Location(2044, 4649, 0)); - break; case 8785: + // Outside of trap door in East Ardy player.teleport(new Location(2543, 3327, 0)); break; case 23158: case 23157: + // Outside brine rat cave player.teleport(new Location(2729, 3733, 0)); break; case 15767: - if (!hasRequirement(player, "Cabin Fever")) + if (!hasRequirement(player, Quests.CABIN_FEVER)) return true; player.teleport(new Location(3748, 9373, 0)); + // Cave horrors - inside of cave break; case 15811: case 15812: + // Cave horrors - outside of cave player.teleport(new Location(3749, 2973, 0)); break; - case 96: - ClimbActionHandler.climb(player, null, new Location(2649, 9804, 0)); - break; - case 35121: - ClimbActionHandler.climb(player, null, new Location(2641, 9763, 0)); - break; } return true; } @@ -84,11 +76,9 @@ public class SlayerPlugin extends OptionHandler { @Override public Location getDestination(Node node, Node n) { if (n.getId() == 23158 || n.getId() == 23157) { + // Inside brine rate cave return new Location(2690, 10124, 0); } - if (n.getId() == 96) { - return new Location(2641, 9763, 0); - } return null; } diff --git a/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java b/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java index 84d54b18d..247e87b82 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java +++ b/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java @@ -17,6 +17,7 @@ import core.plugin.Plugin; import core.plugin.ClassScanner; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles the slayer reward interface plugin. @@ -309,7 +310,7 @@ public class SlayerRewardPlugin extends ComponentPlugin { @Override public boolean handle(Player player, Node node, String option) { - if (!hasRequirement(player, "Smoking Kills")) + if (!hasRequirement(player, Quests.SMOKING_KILLS)) return true; openTab(player, BUY); return true; diff --git a/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java b/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java index aa8f0e38f..682ed5bdf 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java +++ b/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java @@ -39,6 +39,8 @@ public final class SlayerTowerPlugin extends OptionHandler { SceneryDefinition.forId(4490).getHandlers().put("option:open", this); SceneryDefinition.forId(4487).getHandlers().put("option:open", this); SceneryDefinition.forId(4492).getHandlers().put("option:close", this); + SceneryDefinition.forId(10527).getHandlers().put("option:open", this); + SceneryDefinition.forId(10529).getHandlers().put("option:open", this); return this; } @@ -47,6 +49,8 @@ public final class SlayerTowerPlugin extends OptionHandler { switch (node.getId()) { case 4490: case 4487: + case 10527: + case 10529: DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); switchStatue(); return true; diff --git a/Server/src/main/content/global/skill/slayer/SlayerUtils.kt b/Server/src/main/content/global/skill/slayer/SlayerUtils.kt index 34fc944c1..c034fc557 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerUtils.kt +++ b/Server/src/main/content/global/skill/slayer/SlayerUtils.kt @@ -1,19 +1,16 @@ package content.global.skill.slayer +import core.api.setVarp import core.game.node.entity.combat.BattleState import core.game.node.entity.player.Player import core.game.node.entity.player.link.SpellBookManager.SpellBook import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills -import content.global.skill.slayer.Master -import content.global.skill.slayer.Tasks import core.tools.RandomFunction import org.rs09.consts.Items -import java.util.ArrayList -import core.api.* object SlayerUtils { - fun generate(player: Player, master: Master): Tasks? + fun generate(player: Player, master: Master): Master.Task? { val tasks: MutableList = ArrayList(10) val taskWeightSum = intArrayOf(0) @@ -24,7 +21,7 @@ object SlayerUtils { tasks.shuffle(RandomFunction.RANDOM) var rnd = RandomFunction.random(taskWeightSum[0]) for (task in tasks) { - if (rnd < task!!.weight) return task.task + if (rnd < task!!.weight) return task rnd -= task.weight } return null @@ -35,11 +32,14 @@ object SlayerUtils { return player.getSkills().getLevel(Skills.SLAYER) >= task.levelReq && !SlayerManager.getInstance(player).flags.removed.contains(task) && task.hasQuestRequirements(player) } - fun assign(player: Player, task: Tasks, master: Master) + fun assign(player: Player, task: Master.Task, master: Master) { SlayerManager.getInstance(player).master = master - SlayerManager.getInstance(player).task = task - SlayerManager.getInstance(player).amount = RandomFunction.random(master.assignment_range[0], master.assignment_range[1]) + SlayerManager.getInstance(player).task = task.task + if (task.task_range[0] == null) + SlayerManager.getInstance(player).amount = RandomFunction.random(master.default_assignment_range[0], master.default_assignment_range[1]) + else + SlayerManager.getInstance(player).amount = RandomFunction.random(task.task_range[0], task.task_range[1]) if (master == Master.DURADEL) { player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 2, 8) } else if (master == Master.VANNAKA) { @@ -57,4 +57,24 @@ object SlayerUtils { .spellBook == SpellBook.MODERN.interfaceId ) } + + @JvmStatic + fun pluralise(str: String): String { + return when (str) { + "black bear" -> "bears" + "cyclops" -> "cyclopes" + "guard dog" -> "dogs" + "dwarf" -> "dwarves" + "elf warrior" -> "elves" + "jelly" -> "jellies" + "nechryael" -> str // the plural and singular is the same + "turoth" -> str // the plural and singular is the same + "tzhaar-mej" -> "tzHaar" + "werewolf" -> "werewolves" + "wolf" -> "wolves" + "kalphite worker" -> "kalphites" + "scarab swarm" -> "scabarites" + else -> str + "s" + } + } } diff --git a/Server/src/main/content/global/skill/slayer/Tasks.java b/Server/src/main/content/global/skill/slayer/Tasks.java index d4b77c66f..15b905dba 100644 --- a/Server/src/main/content/global/skill/slayer/Tasks.java +++ b/Server/src/main/content/global/skill/slayer/Tasks.java @@ -8,104 +8,120 @@ import java.util.HashMap; import core.game.node.entity.player.Player; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * A non-garbage way of representing tasks + * Slayer level source: ... + * Combat level source: None * @author ceik + * @author gregf */ public enum Tasks { - ABERRANT_SPECTRES(65, new int[] { 1604, 1605, 1606, 1607 }, new String[] { "Aberrant spectres have an extremely potent stench that drains", "stats and life points. A nose peg, protects against the stench." }, 60, true, false), - ABYSSAL_DEMONS(85, new int[] { 1615, 4230 }, new String[] { "Abyssal Demons are nasty creatures to deal with, they aren't really part, ", "of this realm, and are able to move very quickly to trap their prey"}, 85, false, false), - ANKOU(40, new int[] { 4381, 4382, 4383 }, new String[] { "Neither skeleton nor ghost, but a combination of both." }, 1, true, false), - AVIANSIES(60, new int[] { 6245, 6243, 6235, 6232, 6244, 6246, 6233, 6241, 6238, 6237, 6240, 6242, 6239, 6234 }, new String[] { "Graceful, bird-like creature." }, 1, false, false), - BANSHEE(20, new int[] { 1612 }, new String[] { "Banshees use a piercing scream to shock their enemies,", "you'll need some Earmuffs to protect yourself from them." }, 15, true, false), - BASILISKS(40, new int[] { 1616, 1617, 4228 }, new String[] { "A mirror shield is much neccesary when hunting", "these mad creatures." }, 40, false, false), - BATS(5, new int[] { 412, 78, 1005, 2482, 3711, }, new String[] { "These little creatures are incredibly quick.", "make sure you keep your eye on them at all times." }, 1, false, false), - BEARS(13, new int[] { 106, 105, 1195, 3645, 3664, 1326, 1327 }, new String[] { "A large animal with a crunching punch." }, 1, false, false), - BIRDS(1, new int[] { 1475, 5120, 5121, 5122, 5123, 5133, 1475, 1476, 41, 951, 1017, 1401, 1402, 2313, 2314, 2315, 1016, 1550, 147, 1180, 1754, 1755, 1756, 2252, 4570, 4571, 1911, 6114, 46, 2693, 6113, 6112, 146, 149, 150, 450, 451, 1179, 1322, 1323, 1324, 1325, 1400, 2726, 2727, 3197, 138, 48, 4373, 4374, 4535, 139, 1751, 148, 1181, 6382, 2459, 2460, 2461, 2462, 2707, 2708, 6115, 6116, 3296, 6378, 1996, 3675, 3676, 6792, 6946, 7320, 7322, 7324, 7326, 7328, 1692, 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6322, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, }, new String[] { "irds aren't the most intelligent of creatures, but watch out for their", "sharp, stabbing beaks." }, 1, false, false), - BLACK_DEMONS(80, new int[] { 84, 677, 4702, 4703, 4704, 4705, 6208, }, new String[] { "Black Demons are magic creatures that are weak to magic attacks.", "They're the strongest demon and very dangerous." }, 1, false, false), - BLACK_DRAGONS(80, new int[] {54, 4673, 4674, 4675, 4676, 3376, 50 }, new String[] { "Black dragons are the strongest dragons", "watch out for their firey breath" }, 1, false, true, 40 | 80 << 16), - BLOODVELDS(50, new int[] { 1618, 1619, 6215, 7643, 7642 }, new String[] { "Bloodvelds are strange demonic creatures, they use their long rasping tongue", "to feed on just about anything they can find." }, 50, false, false), - BLUE_DRAGONS(65, new int[] { 55, 4681, 4682, 4683, 4684, 5178, 52, 4665, 4666, }, new String[] { "Blue dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, true), - BRINE_RATS(45, new int[] { 3707 }, new String[] { "Small little creatures they are, yet so very", "powerfull." }, 47, false, false), - BRONZE_DRAGONS(75, new int[] { 1590 }, new String[] { "Bronze dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, true, 30 | 60 << 16), - CATABLEPONS(35, new int[] { 4397, 4398, 4399, }, new String[] { "They use the magic spell Weaken to drain up to 15% of their", "opponent's maximum Strength level." }, 1, false, false), - CAVE_BUG(1, new int[] { 1832, 5750, }, new String[] { "It regenerates life points quickly and seems to be a good", "herblore monster." }, 7, false, false), - CAVE_CRAWLERS(10, new int[] { 1600, 1601, 1602, 1603, }, new String[] { "The poisonous parts of them are presumably removed." }, 10, false, false), - CAVE_HORRORS(85, new int[] { 4353, 4354, 4355, 4356, 4357, }, new String[] { "A Cave horror wears a creepy mask, it is", "prefered to wear a witchwood icon." }, 58, "Cabin Fever"), - CAVE_SLIMES(15, new int[] { 1831 }, new String[] { "These are lesser versions of jellies, watch out they can poison you." }, 17, false, false), - COCKATRICES(25, new int[] { 1620, 1621, 4227, }, new String[] { "A Mirror shield is necessary when", "fighting these monsters." }, 25, false, false), - COWS(5, new int[] { 1766, 1768, 2310, 81, 397, 955, 1767, 3309 }, new String[] { "Cow's may seem stupid, however they know more then", "you think. Don't under estimate them." }, 1, false, false), + ABERRANT_SPECTRES(65, new int[] { 1604, 1605, 1606, 1607, 7801, 7802, 7803, 7804 }, new String[] { "Aberrant Spectres are fetid, vile ghosts. The very", "smell of them will paralyse and harm you. A nose peg", "will help ignore their stink." }, 60, true, false), + ABYSSAL_DEMONS(85, new int[] { 1615 }, new String[] { "Abyssal Demons are nasty creatures to fight. They", "aren't really part of this realm, and are able to", "move very quickly to trap their prey."}, 85, false, false), + ANKOU(40, new int[] { 4381, 4382, 4383 }, new String[] { "Ankou are undead skeletal ghosts. They'll fight you", "up close but make sure to take advantage out of their", "limited defence." }, 1, true, false), + BANSHEE(20, new int[] { 1612 }, new String[] { "Banshees use a piercing scream to shock their enemies.", "You'll need some earmuffs to protect yourself from them." }, 15, true, false), + BASILISKS(40, new int[] { 1616, 1617 }, new String[] { "Basilisks, like Cockatrice, have a gaze which will", "paralyse and harm their prey. You'll need a Mirror", "Shield to protect you." }, 40, false, false), + BATS(5, new int[] { 412, 78, 3711 }, new String[] { "Bats are rarely found on the ground, so you'll have", "to fight them while they're airborne, which won't be", "easy for melee." }, 1, false, false), + BEARS(13, new int[] { 106, 105, 1195, 3645, 3664, 1326, 1327 }, new String[] { "Bears are tough creatures and fierce fighters, watch", "out for their powerful claws." }, 1, false, false), + BIRDS(1, new int[] { 1475, 5120, 5121, 5122, 5123, 5133, 1475, 1476, 41, 951, 1017, 1401, 1402, 2313, 2314, 2315, 1016, 1550, 147, 1180, 1754, 1755, 1756, 2252, 4570, 4571, 1911, 6114, 46, 2693, 6113, 6112, 146, 149, 150, 450, 451, 1179, 1322, 1323, 1324, 1325, 1400, 2726, 2727, 3197, 138, 48, 4373, 4374, 4535, 139, 1751, 148, 1181, 6382, 2459, 2460, 2461, 2462, 2707, 2708, 6115, 6116, 3296, 6378, 1996, 3675, 3676, 6792, 6946, 7320, 7322, 7324, 7326, 7328, 1692, 6322, 3476, 1018, 1403, }, new String[] { "Birds aren't the most intelligent of creatures, but", "watch out for their sharp stabbing beaks." }, 1, false, false), + BLACK_DEMONS(80, new int[] { 84, 677, 4702, 4703, 4704, 4705, 6208, }, new String[] { "Black Demons are magic creatures that are weak", "to magic attacks. They're a very strong", "demon and very dangerous." }, 1, false, false), + BLACK_DRAGONS(80, new int[] {54, 4673, 4674, 4675, 4676, 3376, 50 }, new String[] { "Black dragons are the strongest dragons;", "watch out for their fiery breath." }, 1, false, true), + BLOODVELDS(50, new int[] { 1618, 1619, 6215, 7643, 7642 }, new String[] { "Bloodvelds are strange demonic creatures, they use their", "long rasping tongue to feed on just about", "anything they can find." }, 50, false, false), + BLUE_DRAGONS(65, new int[] { 55, 4681, 4682, 4683, 4684, 5178, 52, 4665, 4666, }, new String[] { "Blue dragons aren't as strong as other dragons but they're", "still very powerful, watch out for their fiery breath." }, 1, false, true), + BRINE_RATS(45, new int[] { 3707 }, new String[] { "Brine rats can be found in caves that are near the", "sea. They are hairless, bad-tempered and generally", "unfriendly." }, 47, Quests.OLAFS_QUEST), + BRONZE_DRAGONS(75, new int[] { 1590 }, new String[] { "Bronze Dragons are the weakest of the metallic", "dragons, their bronze scales are far thicker than", "normal bronze armour." }, 1, false, true), + CATABLEPONS(35, new int[] { 4397, 4398, 4399, }, new String[] { "Catablepon are mythical, cow like, magical creatures", "Beware their weakening glare." }, 1, false, false), + CAVE_BUG(1, new int[] { 1832, 5750, }, new String[] { "Cave Bugs are like Cave Crawlers, except smaller and", "easier to squish, though they still have a fondness", "for plants." }, 7, false, false), + CAVE_CRAWLERS(10, new int[] { 1600, 1601, 1602, 1603, }, new String[] { "Cave Crawlers are small and fast, often hiding in", "ambush. Avoid their barbed tongue or you'll", "get poisoned." }, 10, false, false), + CAVE_HORRORS(85, new int[] { 4353, 4354, 4355, 4356, 4357, }, new String[] { "Cave Horrors can be found under Mos Le'Harmless. You", "will need a Witchwood Icon to fight them effectively." }, 58, Quests.CABIN_FEVER), + CAVE_SLIMES(15, new int[] { 1831 }, new String[] { "Cave Slimes are the lesser cousins of Jellies, though", "don't be fooled they can still be dangerous as", "they're often poisonous." }, 17, false, false), + COCKATRICES(25, new int[] { 1620, 1621, 4227, }, new String[] { "Cockatrice, like Basilisks, have a gaze which will", "paralyse and harm their prey. You'll need a Mirror", "Shield to protect you." }, 25, false, false), + COWS(5, new int[] { 81, 1766, 1768, 2310, 397, 955, 1767, 3309 }, new String[] { "Cows are bigger than you, so they'll often hit fairly", "hard but are usually fairly slow to react." }, 1, false, false), CRAWLING_HAND(1,new int[] { 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 4226, 7640, 7641 }, new String[] { "Crawling Hands are undead severed hands, fast and", "dexterous they claw their victims." }, 5, true, false), - CROCODILES(50, new int[] { 1993, 6779 }, new String[] { "Crocodiles can be found near water and marshes in and near the Kharidian Desert." }, 1, false, false), - CYCLOPES(25,new int[] { 116, 4291, 4292, 6078, 6079, 6080, 6081, 6269, 6270 }, new String[] { "Large one eyed creatures who normally wield a", "large mallet." }, 1, false, false), - DAGANNOTHS(75, new int[] { 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 2454, 2455, 2456, 2881, 2882, 2883, 2887, 2888, 3591, }, new String[] { "There are many types of Dagannoth, the most powerful being the three Dagannoth Kings." }, 1, false, false), - DARK_BEASTS(90, new int[] { 2783 }, new String[] { "A dark beast can attack using magic or melee." }, 90, false, false), - DESERT_LIZARDS(15, new int[] { 2803, 2804, 2805, 2806, 2807 }, new String[] { "Desert lizards are big Slayer monsters found in the Kharidian Desert." }, 22, false, false), - DOG(15, new int[] { 99, 3582, 6374, 1994, 1593, 1594, 3582 }, new String[] { "Dogs are much like Wolves, they are", "pack creatures which will hunt in groups." }, 1, false, false), + CROCODILES(50, new int[] { 1993, 6779 }, new String[] { "Crocodiles are large reptiles which live near water.", "You'll want to have a stabbing weapon handy for", "puncturing their thick scaly hides." }, 1, false, false), + DAGANNOTHS(75, new int[] { 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 2454, 2455, 2456, 2881, 2882, 2883, 2887, 2888, 3591, }, new String[] { "Dagannoth are large sea dwelling creatures which are", "very aggressive. You'll often find them in caves", "near sea water." }, 1, Quests.HORROR_FROM_THE_DEEP), + DARK_BEASTS(90, new int[] { 2783 }, new String[] { "Dark Beasts are large, dog-like predators.", "Their massively muscled bodies protect", "them from crushing weapons." }, 90, Quests.MOURNINGS_END_PART_II), + DESERT_LIZARDS(15, new int[] { 2803, 2804, 2805, 2806, 2807, 2808 }, new String[] { "Lizards are large reptiles with tough skin. Those", "found in the desert will need you to douse them with", "freezing water to finish them off after a tough battle." }, 22, false, false), + DOG(15, new int[] { 99, 3582, 1994, 1593, 1594, 3582 }, new String[] { "Dogs are much like Wolves, they are", "pack creatures which will hunt in groups." }, 1, false, false), DUST_DEVILS(70, new int[] { 1624 }, new String[] { "Dust Devils use clouds of dust, sand, ash and whatever", "else they can inhale to blind and disorientate", "their victims." }, 65, false, false), - DWARF(6, new int[] { 118, 120, 121, 382, 3219, 3220, 3221, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3294, 3295, 4316, 5880, 5881, 5882, 5883, 5884, 5885, 2130, 2131, 2132, 2133, 3276, 3277, 3278, 3279, 119, 2423 }, new String[] { "They are slightly resistant to Magic attacks", "and are not recommended for low levels." }, 1, false, false), - EARTH_WARRIORS(35, new int[] { 124 }, new String[] { "An Earth warrior is a monster made of earth"," which fights using melee." }, 1, false, false), - ELVES(70, new int[] { 1183, 1184, 2359, 2360, 2361, 2362, 7438, 7439, 7440, 7441 }, new String[]{"Elves are agile creatures."}, 1, false, false), - FIRE_GIANTS(65, new int[] { 110, 1582, 1583, 1584, 1585, 1586, 7003, 7004 }, new String[] { "Like other giants, Fire Giants often wield large weapons", "learn to recognise what kind of weapon it is, and act accordingly." }, 1, false, false), - FLESH_CRAWLERS(15, new int[] { 4389, 4390, 4391 }, new String[] { "Flesh crawlers are medium level monsters found on", "level 2 of the Stronghold of Security." }, 1, false, false), - GARGOYLES(80, new int[] { 1610, 1611, 6389 }, new String[] { "Gargoyles are winged creatures of stone. You'll need to fight them to", "near death before breaking them apart with a rock hammer." }, 75, false, false), - GHOSTS(13, new int[] { 103, 104, 491, 1541, 1549, 2716, 2931, 4387, 388, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 1698, 5349, 5350, 5351, 5352, 5369, 5370, 5371, 5372, 5373, 5374, 5572, 6094, 6095, 6096, 6097, 6098, 6504, 13645, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475, 13476, 13477, 13478, 13479, 13480, 13481 }, new String[] { "A Ghost is an undead monster that is found", "in various places and dungeons. " }, 1, false, false), - GHOULS(25, new int[] { 1218, 3059 }, new String[] { "Ghouls are a humanoid race and the descendants of a long-dead society", "that degraded to the point that its people ate their dead." }, 1, false, false), + DWARF(6, new int[] { 118, 120, 121, 382, 3219, 3220, 3221, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3294, 3295, 4316, 5880, 5881, 5882, 5883, 5884, 5885, 2130, 2131, 2132, 2133, 3276, 3277, 3278, 3279, 119, 2423 }, new String[] { "Dwarves are a small but tough race of miners, often", "using pickaxes to pierce their opponents armour." }, 1, false, false), + EARTH_WARRIORS(35, new int[] { 124 }, new String[] { "Earth Warriors are a kind of earth elemental,", "grind them to dust with blunt weapons." }, 1, false, false), + ELVES(70, new int[] { 1183, 1184, 2359, 2360, 2361, 2362, 2373, 7438, 7439, 7440, 7441 }, new String[]{ "Elves are quick, agile, and vicious fighters which", "often favour bows and polearms."}, 1, Quests.REGICIDE), + // Waiting for either Rum Deal or Pirate Pete and Fever Spiders before adding this assignment + FEVER_SPIDER(1, new int[] { 2850 }, new String[] { "Fever Spiders are giant spiders that carry the deadly", "Spider Fever. If you don't want to catch it I suggest", "you wear Slayer Gloves to fight them." }, 42, Quests.RUM_DEAL), + FIRE_GIANTS(65, new int[] { 110, 1582, 1583, 1584, 1585, 1586, 7003, 7004 }, new String[] { "Like other giants, Fire Giants often wield large weapons", "learn to recognise what kind of weapon it is,", "and act accordingly." }, 1, false, false), + FLESH_CRAWLERS(15, new int[] { 4389, 4390, 4391 }, new String[] { "Flesh Crawlers are scavengers and will eat you - and", "anyone else, given the chance." }, 1, false, false), + GARGOYLES(80, new int[] { 1610, 6389 }, new String[] { "Gargoyles are winged creatures of stone. You'll need", "to fight them to near death before breaking them apart", "with a rock hammer." }, 75, false, false), + GHOSTS(13, new int[] { 103, 104, 491, 1541, 1549, 2716, 2931, 4387, 388, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 1698, 5349, 5350, 5351, 5352, 5369, 5370, 5371, 5372, 5373, 5374, 5572, 6094, 6095, 6096, 6097, 6098, 6504, 13645, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475, 13476, 13477, 13478, 13479, 13480, 13481 }, new String[] { "Ghosts are undead so magic is your best bet against", "them, there is even a spell specially for fighting", "the undead." }, 1, true, false), + GHOULS(25, new int[] { 1218, 3059 }, new String[] { "Ghouls aren't undead but they are stronger and", "tougher than they look. However they're also very", "cowardly and will run if they're losing a fight." }, 1, false, false), GOBLINS(1, new int[] { 100, 101, 102, 444, 445, 489, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2678, 2679, 2680, 2681, 3060, 3264, 3265, 3266, 3267, 3413, 3414, 3415, 3726, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4407, 4408, 4409, 4410, 4411, 4412, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4499, 4633, 4634, 4635, 4636, 4637, 5786, 5824, 5855, 5856, 6125, 6126, 6132, 6133, 6279, 6280, 6281, 6282, 6283, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, 6410, 6411, 6412, 6413, 6414, 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, 6423, 6424, 6425, 6426, 6427, 6428, 6429, 6430, 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, 6490, 6491, 6492, 6493, 6494, 6495, 6496, 6497 }, new String[] { "Goblins are mostly just annoying, but they can be vicious.", "Watch out for the spears they sometimes carry." }, 1, false, false), - GORAKS(70, new int[] { 4418, 6218 }, new String[] { "Goraks can be tough monsters to fight. Be prepared." }, 1, false, false), - GREATER_DEMONS(75, new int[] { 83, 4698, 4699, 4700, 4701, 6204 }, new String[] { "Greater Demons are magic creatures so they are weak to magical attacks.", "They're the strongest demon and very dangerous." }, 1, false, false), - GREEN_DRAGONS(52, new int[] { 941, 4677, 4678, 4679, 4680, 5362 }, new String[] { "Green dragons are very powerfull, they have", "fierce fiery breath." }, 1, false, true), - HARPIE_BUG_SWARMS(45, new int[] { 3153 }, new String[] { "Harpie Bug Swarms are insectoid Slayer monsters." }, 33, false, false), - HELLHOUNDS(75, new int[] { 49, 3586, 6210, }, new String[] { "Hellhounds are mid to high level demons." }, 1, false, false), - HILL_GIANTS(25, new int[] { 117, 4689, 4690, 3058, 4691, 4692, 4693 }, new String[] { "Hill giants can hit up to 19 damage, and they only attack with Melee." }, 1, false, false), - HOBGOBLINS(20, new int[] { 122, 123, 2685, 2686, 3061, 6608, 6642, 6661, 6684, 6710, 6722, 6727, 2687, 2688, 3583, 4898, 6275 }, new String[] { "Mysterious goblin like creatures." }, 1, false, false), - ICE_FIENDS(20, new int[] { 3406, 6217, 7714, 7715, 7716 }, new String[] { "An Icefiend is a monster found on top of Ice Mountain." }, 1, false, false), - ICE_GIANTS(50, new int[] { 111, 3072, 4685, 4686, 4687 }, new String[] { "Ice Giants often wield large weapons, learn to recognise", "what kind of weapon it is, and act accordingly" }, 1, false, false), - ICE_WARRIOR(45, new int[] { 125, 145, 3073 }, new String[] { "Ice warriors, are cold magestic creatures." }, 1, false, false), - INFERNAL_MAGES(40, new int[] { 1643, 1644, 1645, 1646, 1647 }, new String[] { "Infernal Mages are dangerous spell users, beware of their magic", "spells an go properly prepared" }, 45, false, false), - IRON_DRAGONS(80, new int[] { 1591 }, new String[] { "Iron dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, true, 40 | 59 << 16), + GORAKS(70, new int[] { 4418, 6218 }, new String[] { "Goraks are extremely aggressive creatures. They have", "been imprisoned on an alternative plane, which is", "only accessible by using the fairyrings. Be extremely", "careful, their touch drains health as well as skills!" }, 1, Quests.FAIRYTALE_I_GROWING_PAINS), + GREATER_DEMONS(75, new int[] { 83, 4698, 4699, 4700, 4701, 6204 }, new String[] { "Greater Demons are magic creatures so they are weak", "to magical attacks. Though not the strongest demon,", "they are still dangerous." }, 1, false, false), + GREEN_DRAGONS(52, new int[] { 941, 4677, 4678, 4679, 4680, 5362, 742 }, new String[] { "Green Dragons are the weakest dragon but still very", "powerful, watch out for their fiery breath." }, 1, false, true), + HARPIE_BUG_SWARMS(45, new int[] { 3153 }, new String[] { "Harpie Bug Swarms are pesky critters that are hard to", "hit. You need a lit bug lantern to distract them with", "its hypnotic light." }, 33, false, false), + HELLHOUNDS(75, new int[] { 49, 3586, 6210, }, new String[] { "Hellhounds are a cross between Dogs and Demons, they", "are dangerous with a fierce bite." }, 1, false, false), + HILL_GIANTS(25, new int[] { 117, 4689, 4690, 3058, 4691, 4692, 4693 }, new String[] { "Hill Giants often wield large weapons, learn to", "recognise what kind of weapon it is and", "act accordingly." }, 1, false, false), + HOBGOBLINS(20, new int[] { 122, 123, 2685, 2686, 3061, 6608, 6642, 6661, 6684, 6710, 6722, 6727, 2687, 2688, 3583, 4898, 6275 }, new String[] { "Hobgoblins are sneaky underhanded creatures, they", "often wield spears and some times carry javelins too." }, 1, false, false), + ICE_FIENDS(20, new int[] { 3406, 6217, 7714, 7715, 7716 }, new String[] { "Icefiends are beings of ice and freezing rock, they're", "quick and agile so you'll want to be careful when", "getting close to them." }, 1, false, false), + ICE_GIANTS(50, new int[] { 111, 3072, 4685, 4686, 4687 }, new String[] { "Like other giants, Ice Giants often wield large", "weapons, learn to recognise what kind of weapon it is", "and act accordingly." }, 1, false, false), + ICE_WARRIOR(45, new int[] { 125, 145, 3073 }, new String[] { "Ice Warriors are a kind of ice elemental, shatter them", "with blunt weapons or melt them with fire." }, 1, false, false), + INFERNAL_MAGES(40, new int[] { 1643, 1644, 1645, 1646, 1647 }, new String[] { "Infernal Mages are dangerous spell users, beware of", "their magic spells and go properly prepared" }, 45, false, false), + IRON_DRAGONS(80, new int[] { 1591 }, new String[] { "Iron Dragons are some of the weaker metallic dragons,", "their iron scales are far thicker than normal", "iron armour." }, 1, false, true), JELLIES(57, new int[] { 1637, 1638, 1639, 1640, 1641, 1642 }, new String[] { "Jellies are nasty cube-like gelatinous creatures which", "absorb everything they come across into themselves." }, 52, false, false), - JUNGLE_HORRORS(65, new int[] { 4348, 4349, 4350, 4351, 4352 }, new String[] { "Jungle Horrors can be found all over Mos Le'Harmless.", "They are strong and aggressive, so watch out!" }, 1, false, false), - KALPHITES(15, new int[] { 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161 }, new String[] { "Kalaphite are large insects which live in great hives under the desert sands." }, 1, false, false), - KURASKS(65, new int[] { 1608, 1609, 4229, 7805, 7797 }, new String[] { "A kurask is a very quick creature." }, 70, false, false), - LESSER_DEMONS(60, new int[] { 82, 6203, 3064, 4694, 4695, 6206, 3064, 4696, 4697, 6101 }, new String[] { "Lesser Demons are magic creatures so they are weak to magical attacks." }, 1, false, false), - MITHRIL_DRAGONS(60, new int[] { 5363 }, new String[] { "Mithril dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, true, 5 | 9 << 16), + JUNGLE_HORRORS(65, new int[] { 4348, 4349, 4350, 4351, 4352 }, new String[] { "Jungle Horrors can be found all over Mos Le'Harmless.", "They are strong and aggressive, so watch out!" }, 1, Quests.CABIN_FEVER), + KALPHITES(15, new int[] { 1153, 1154, 1155, 1156, 1157, 1159, 1160, 1161 }, new String[] { "Kalphites are large insects which live in great hives", "under the desert sands." }, 1, false, false), + // Waiting for the killer watt plane to be implemented before adding to assignments + KILLERWATTS(1, new int[] { 3201 }, new String[] { "Killerwatts store huge amounts of energy in their", "bodies, which is released if they are touched. You'll", "need to wear heavily insulated boots to counter this", "shocking effect." }, 37, Quests.ERNEST_THE_CHICKEN), + KURASKS(65, new int[] { 1608, 1609, 4229, 7805, 7797 }, new String[] { "Kurasks are large brutal creatures with very thick", "hides. You'll need a Leaf-Tipped Spear Sword or", "Battle-axe, Broad Arrows, or a Magic Dart to harm them." }, 70, false, false), + LESSER_DEMONS(60, new int[] { 82, 6203, 3064, 4694, 4695, 6206, 3064, 4696, 4697, 6101 }, new String[] { "Lesser Demons are magic creatures so they are weak to", "magical attacks. Though they're relatively weak they", "are still dangerous." }, 1, false, false), MINOTAURS(7, new int[] { 4404, 4405, 4406 }, new String[] { "Minotaurs are large manlike creatures but you'll", "want to be careful of their horns." }, 1, false, false), - MONKEYS(1, new int[] { 132, 1463, 1464, 2301, 4344, 4363, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 1455, 1459, 1460, 1456, 1457, 1458 }, new String[] { "Small agile creatures, watch out they pinch!" }, 1, false, false), - MOSS_GIANTS(40, new int[] { 112, 1587, 1588, 1681, 4534, 4688, 4706 }, new String[] { "They are known to carry large sticks." }, 1, false, false), - NECHRYAELS(85, new int[] { 1613 }, new String[] { "Nechryael are demons of decay which summon small winged beings which", "help them fight their victems." }, 80, false, false), - OGRES(40, new int[] { 115, 374, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 3587, 6267, 7078, 7079, 7080, 7081, 7082 }, new String[] { "Ogres are brutal creatures, favouring large blunt maces and clubs", "they often attack without warning." }, 1, false, false), - OTHERWORDLY_BEING(40, new int[] { 126 }, new String[] { "A creature filled with everlasting power." }, 1, false, false), - PYREFIENDS(25, new int[] { 1633, 1634, 1635, 1636, 6216, 6631, 6641, 6660, 6668, 6683, 6709, 6721, }, new String[] { "A scorching hot creature, watch out!" }, 30, false, false), - RATS(1, new int[] { 2682, 2980, 2981, 3007, 88, 224, 4928, 4929, 4936, 4937, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 4396, 4415, 7202, 7204, 7417, 7461, 87, 446, 950, 4395, 4922, 4923, 4924, 4925, 4926, 4927, 4942, 4943, 4944, 4945, 86, 87, 446, 950, 4395, 4922, 4923, 4924, 4925, 4926, 4927, 4942, 4943, 4944, 4945 }, new String[] { "Quick little rodents!" }, 1, false, false), - ROCK_SLUGS(20, new int[] { 1631, 1632 }, new String[] { "A rock slug can leave behind a trail of his presence.." }, 20, false, false), - SCORPIONS(7, new int[] { 107, 1477, 4402, 4403, 144 }, new String[] { "A scorpion makes a piercing sound, watch out for", "its long sharp tail." }, 1, false, false), - SHADE(30, new int[] { 3617, 1250, 1241, 1246, 1248, 1250, 428, 1240 }, new String[] { "Shades are dark and mysterious", "they hide in the shadows so be wary of ambushes." }, 1, true, false), - SKELETONS(15, new int[] { 90, 91, 92, 93, 94, 459, 1471, 1575, 1973, 2036, 2037, 2715, 2717, 3065, 3151, 3291, 3581, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3844, 3850, 3851, 4384, 4385, 4386, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5359, 5365, 5366, 5367, 5368, 5381, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 5391, 5392, 5411, 5412, 5422, 6091, 6092, 6093, 6103, 6104, 6105, 6106, 6107, 6764, 6765, 6766, 6767, 6768 }, new String[] { "Skeletons are undead monsters found in various locations." }, 1, true, false), - SPIDERS(1, new int[] { 61, 1004, 1221, 1473, 1474, 63, 4401, 2034, 977, 7207, 134, 1009, 59, 60, 4400, 58, 62, 1478, 2491, 2492, 6376, 6377, }, new String[] { "Level 24 spiders are aggressive and can hit up to 60 life points." }, 1, false, false), - SPIRTUAL_MAGES(60, new int[] { 6221, 6231, 6257, 6278 }, new String[] { "They are dangerous, they hit with mage." }, 83, false, false), - SPIRTUAL_RANGERS(60, new int[] { 6220, 6230, 6256, 6276 }, new String[] { "They are dangerous, they hit with range." }, 63, false, false), - SPIRTUAL_WARRIORS(60, new int[] { 6219, 6229, 6255, 6277, }, new String[] { "They are dangerous, they hit with melee." }, 68, false, false), - STEEL_DRAGONS( 85,new int[] { 1592, 3590 }, new String[] { "Steel dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, true, 10 | 20 << 16), - TROLLS(60, new int[] { 72, 3584, 1098, 1096, 1097, 1095, 1101, 1105, 1102, 1103, 1104, 1130, 1131, 1132, 1133, 1134, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1138, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 3840, 3841, 3842, 3843, 3845, 1933, 1934, }, new String[] { "Trolls have a crushing attack, it's bets to wear a high crushing defence." }, 1, false, false), - TUROTHS(60, new int[] { 1626, 1627, 1628, 1629, 1630 }, new String[] { "Turoths are Slayer monsters that require a Slayer level of 55 to kill" }, 55, false, false), - TZHAAR(45, new int[] { 2591, 2592, 2593, 2745, 2594, 2595, 2596, 2597, 2604, 2605, 2606, 2607, 2608, 2609, 7755, 7753, 2598, 2599, 2600, 2601, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2624, 2617, 2618, 2625, 2602, 2603, 7754, 7767, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2624, 2625, 2627, 2628, 2629, 2630, 2631, 2632, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7747, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7757, 7765, 7769, 7768 }, new String[] { "Young Tzhaar's of the century are furious with your kind." }, 1, false, false), - SUQAHS (65, new int[] { 4527, 4528, 4529, 4530, 4531, 4532, 4533 }, new String[] { "Suquah are big, angry folk that inhabit Lunar Isle." }, 1, "Lunar Diplomacy"), - VAMPIRES(35, new int[] { 1023, 1220, 1223, 1225, 6214 }, new String[] { "Vampires are equipped with large fangs,", "they can do serious damage." }, 1, false, false), - WATERFIENDS(75, new int[] { 5361 }, new String[] { "A waterfiend takes no damage from fire!" }, 1, false, false), - WEREWOLFS(60, new int[] { 1665, 6006, 6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6212, 6213, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728, }, new String[] { "There temper is alot more nasty then a regular wolf!" }, 1, false, false), - WOLVES(20, new int[] { 95, 96, 97, 141, 142, 143, 839, 1198, 1330, 1558, 1559, 1951, 1952, 1953, 1954, 1955, 1956, 4413, 4414, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6829, 6830, 7005 }, new String[] { "Wolves are more agressive then dog's." }, 1, false, false), - ZOMBIES(10, new int[] { 73, 74, 75, 76, 2058, 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, }, new String[] { "Zombies are creatures with no brain, they do hit farley", "high though." }, 1, true, false), - JAD(90, new int[] { }, new String[] { "TzTok-Jad is the king of the Fight Caves." }, 1, false, false, 1 | 1 << 16), - CHAOS_ELEMENTAL(90, new int[] { 3200 }, new String[] { "The Chaos Elemental is located in the deep Wilderness." }, 1, false, false, 5 | 25 << 16), - GIANT_MOLE(75, new int[] { 3340 }, new String[] { "Fighting the Giant Mole will require a light source." }, 1, false, false, 5 | 25 << 16), - KING_BLACK_DRAGON(75, new int[] { 50 }, new String[] { "The King Black Dragon is located in the deep wilderness." }, 1, false, true, 5 | 25 << 16), - COMMANDER_ZILYANA(90, new int[] { 6247 }, new String[] { "Commander Zilyana is one of the four Godwars bosses." }, 1, false, false, 5 | 25 << 16), - GENERAL_GRARDOOR(90, new int[] { 6260 }, new String[] { "General Grardoor is one of the four Godwars bosses." }, 1, false, false, 5 | 25 << 16), - KRIL_TSUTSAROTH(90, new int[] { 6203 }, new String[] { "Kril Tsutsaroth is one of the four Godwars bosses." }, 1, false, false, 5 | 25 << 16), - KREE_ARRA(90, new int[] { 6222 }, new String[] { "Kree'arra is one of the four Godwars bosses." }, 1, false, false, 5 | 25 << 16), - SKELETAL_WYVERN(70, new int[] { 3068, 3069, 3070, 3071 }, new String[] { "A skeletal wyvern requires an elemental, mirror", "or dragonfire shield." }, 72, false, false, 24 | 39 << 16); + MITHRIL_DRAGONS(60, new int[] { 5363 }, new String[] { "Mithril dragons are more vulnerable to magic and to", "stab-based melee attacks than to anything else." }, 1, false, true), + MOGRES(1, new int[] { 114 }, new String[] { "Mogres are a type of aquatic Ogre that is", "often mistaken for a giant mudskipper. You have to force", "them out of the water with a fishing explosive." }, 32, false, false), + // Waiting for molanisks transform to be implemented before adding this to assignments + MOLANISKS(1, new int[] { 5751 }, new String[] { "Molanisks are subterranean creatures. You can find", "them in caves deep below the ground. I heard that the", "goblins have recently had trouble with some, but they", "use a bell of some sort to deal with them."}, 39, Quests.DEATH_TO_THE_DORGESHUUN), + MONKEYS(1, new int[] { 132, 1463, 1464, 2301, 4344, 4363, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 1455, 1459, 1460, 1456, 1457, 1458 }, new String[] { "Monkeys are tricky creatures, they are agile and", "fairly fast. Learn to anticipate their movements." }, 1, false, false), + MOSS_GIANTS(40, new int[] { 112, 1587, 1588, 1681, 4534, 4688, 4706 }, new String[] { "Like other giants, Moss Giants often wield large", "weapons, learn to recognise what kind of weapon it is", "and act accordingly." }, 1, false, false), + // Waiting for zygomite transform to be implemented before adding this to assignments + MUTATED_ZYGOMITES(1, new int[] { 3346, 3347 }, new String[] { "Mutated Zygomites are hard to destroy. They regenerate", "quickly so you will need to finish them with fungicide." }, 57, Quests.LOST_CITY), + NECHRYAELS(85, new int[] { 1613 }, new String[] { "Nechryael are demons of decay which summon small", "winged beings to help them fight their victims." }, 80, false, false), + OGRES(40, new int[] { 115, 374, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2060, 2801, 3419, 7078, 7079, 7080, 7081, 7082 }, new String[] { "Ogres are brutal creatures, favouring large blunt", "maces and clubs they often attack without warning." }, 1, false, false), + OTHERWORDLY_BEING(40, new int[] { 126 }, new String[] { "Otherworldly Beings are ethereal beings making them", "weak to magical attack." }, 1, false, false), + PYREFIENDS(25, new int[] { 1633, 1634, 1635, 1636, 6216, 6631, 6641, 6660, 6668, 6683, 6709, 6721, }, new String[] { "Pyrefiends are beings of fire and molten rock,", "they're quick and agile so you'll want to be careful", "when getting close to them." }, 30, false, false), + RED_DRAGONS(1, new int[] { 53, 1589, 3588, 4667, 4668, 4669, 4670, 4671, 4672 }, new String[] { "Red Dragons are very powerful, stronger than most", "dragons, watch out for their fiery breath." }, 1, false, false), + ROCK_SLUGS(20, new int[] { 1631, 1632 }, new String[] { "Rockslugs are strange stoney slugs. You'll need to", "fight them to near death before finishing them off", "with Salt." }, 20, false, false), + // Seems to need Contact or the NPCs added to dungeons before adding this assignment as a task + SCABARITES(1, new int[] { 2001, 4500, 5251, 5252, 5255, 5256, 5250, 5254, 6777, 6778, 6774, 6780, 6781, 6773 }, new String[] {"Scabarites are insectoid creatures, found beyond the", "Kharidian deserts. They can be extremely dangerous."}, 1, Quests.CONTACT), + SCORPIONS(7, new int[] { 107, 1477, 4402, 4403, 144 }, new String[] { "Scorpions are almost always poisonous, their hard", "carapace makes them resistant to crushing and", "stabbing attacks." }, 1, false, false), + SEA_SNAKES(1, new int[] { 3939, 3940 }, new String[] { "Sea Snakes are long and slithery with a venomous bite.", "The larger ones are more poisonous, so keep an eye on", "your health." }, 1, Quests.ROYAL_TROUBLE), + SHADE(30, new int[] { 3617, 1250, 1241, 1246, 1248, 1250, 428, 1240 }, new String[] { "Shades are undead so magic is your best best against", "them, you can find Shades at Mort'ton." }, 1, true, false), + // Dungeon needs to be connected to the Legend's Guild before adding this assignment as a task + SHADOW_WARRIORS(1, new int[] { 158 }, new String[] { "Shadow Warriors are dark and mysterious, they hide in", "the shadows so be wary of ambushes." }, 1, Quests.LEGENDS_QUEST), + SKELETAL_WYVERN(70, new int[] { 3068, 3069, 3070, 3071 }, new String[] { "Skeletal Wyverns are extremely dangerous and they are", "hard to hit with arrows as they slip right through.", "To stand a good chance of surviving you'll need some", "elemental shielding from its icy breath." }, 72, false, false), + SKELETONS(15, new int[] { 90, 91, 92, 93, 94, 459, 1471, 1575, 1973, 2036, 2037, 2715, 2717, 3065, 3151, 3291, 3581, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3844, 3850, 3851, 4384, 4385, 4386, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5359, 5365, 5366, 5367, 5368, 5381, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 5391, 5392, 5411, 5412, 5422, 6091, 6092, 6093, 6103, 6104, 6105, 6106, 6107, 6764, 6765, 6766, 6767, 6768, 2050, 2056, 2057, 1539, 7640 }, new String[] { "Skeletons are undead so magic is your best bet against", "them, there is even a spell specially for fighting the undead." }, 1, true, false), + SPIDERS(1, new int[] { 61, 1004, 1221, 1473, 1474, 63, 4401, 2034, 977, 7207, 134, 1009, 59, 60, 4400, 58, 62, 1478, 2491, 2492, 6376, 6377, }, new String[] { "Spiders are often poisonous, and many varieties are", "camouflaged too." }, 1, false, false), + SPIRTUAL_MAGES(60, new int[] { 6221, 6231, 6257, 6278 }, new String[] { "Spiritual mages can be found in the icy caverns near", "Trollheim, supporting the cause of their chosen god." }, 83, Quests.DEATH_PLATEAU), + SPIRTUAL_RANGERS(60, new int[] { 6220, 6230, 6256, 6276 }, new String[] { "Spiritual rangers can be found in the icy caverns near", "Trollheim, supporting the cause of their chosen god." }, 63, Quests.DEATH_PLATEAU), + SPIRTUAL_WARRIORS(60, new int[] { 6219, 6229, 6255, 6277, }, new String[] { "Spiritual warriors can be found in the icy caverns near", "Trollheim, supporting the cause of their chosen god." }, 68, Quests.DEATH_PLATEAU), + STEEL_DRAGONS( 85,new int[] { 1592, 3590 }, new String[] { "Steel dragons are dangerous and metallic, with steel", "scales that are far thicker than normal steel armour. As", "you are an accomplished slayer, I am sure you'll be", "able to deal with them easily."}, 1, false, true), + SUQAHS (65, new int[] { 4527, 4528, 4529, 4530, 4531, 4532, 4533 }, new String[] { "Suqahs can only be found on the mystical Lunar Isle.", "They are capable of melee and magic attacks and often", "drop hide, teeth and herbs!" }, 1, Quests.LUNAR_DIPLOMACY), + TERROR_DOGS(1, new int[] { 5417, 5418 }, new String[] { "Terror dogs are the personal pets of Tarn Razorlor.", "Wherever you find him, you will find them. They are", "bad-tempered and generally unfriendly." }, 40, Quests.HAUNTED_MINE), + TROLLS(60, new int[] { 72, 3584, 1098, 1096, 1097, 1095, 1101, 1105, 1102, 1103, 1104, 1130, 1131, 1132, 1133, 1134, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1138, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 3840, 3841, 3842, 3843, 3845, 1933, 1934, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 391, 392, 393, 394, 395, 396}, new String[] { "Trolls regenerate damage quickly but are still", "vulnerable to poisons, they usually use crushing", "weapons." }, 1, false, false), + TUROTHS(60, new int[] { 1622, 1611, 1623, 1626, 1627, 1628, 1629, 1630, 7800}, new String[] { "Turoth are large vicious creatures with thick hides.", "You'll need a Leaf-Tipped Spear Sword or Battle-axe,", "Broad Arrows, or a Magic Dart to harm them." }, 55, false, false), + VAMPIRES(35, new int[] { 1220, 1223, 1225, 6214 }, new String[] { "Vampires are extremely powerful beings. They feed on", "the blood of the living so watch out you don't", "get bitten." }, 1, false, false), + WALL_BEASTS(1, new int[] { 7823 }, new String[] { "Wall Beasts are really much larger creatures but", "you'll only see their arms. You'll want something", "sharp on your head to stop them grabbing you." }, 35, false, false ), + // No way to get to Poison Swamp Cave + // If a grapple is implemented from W Castle Wars to E Posion Swamps + // The dungeon connected and populated + // then these could be added as a task + WARPED_TERROR_BIRD(1, new int[] { 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, 6608 }, new String[] { "Warped Creatures can supposedly be found within a", "mysterious dungeon on the eastern edge of the Poison", "Waste. Be aware that to defeat them, you'll need to", "purify them in some way." },56, Quests.THE_PATH_OF_GLOUPHRIE), + WARPED_TORTOISE(1, new int[] { 6296, 6297 }, new String[] { "Warped Creatures can supposedly be found within a", "mysterious dungeon on the eastern edge of the Poison", "Waste. Be aware that to defeat them, you'll need to", "purify them in some way." },56, Quests.THE_PATH_OF_GLOUPHRIE), + WATERFIENDS(75, new int[] { 5361 }, new String[] { "Waterfiends are creatures of water, which live under", "the Baxtorian Lake. Their watery form is well defended", "against slashing and piercing weapons, so use", "something blunt." }, 1, false, false), + WEREWOLVES(60, new int[] { 6006, 6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6212, 6213, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728, }, new String[] { "Werewolves are feral creatures, they are strong and", "tough with sharp claws and teeth." }, 1, false, false), + WOLVES(20, new int[] { 95, 96, 97, 141, 142, 143, 839, 1198, 1330, 1558, 1559, 1951, 1952, 1953, 1954, 1955, 1956, 4413, 4414, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6829, 6830, 7005 }, new String[] { "Wolves are pack animals, so you'll always find them", "in groups. Watch out for their bite, it can be nasty." }, 1, false, false), + ZOMBIES(10, new int[] { 73, 74, 75, 76, 2060, 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, 8149, 8150, 8151, 8152, 8153, 8159, 8160, 8161, 8162, 8163, 8164, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 7641, 1465, 1466, 1467, 2837, 2838, 2839, 2840, 2841, 2842, 5629, 5630, 5631, 5632, 5633, 5634, 5635, 5636, 5637, 5638, 5639, 5640, 5641, 5642, 5643, 5644, 5645, 5646, 5647, 5648, 5649, 5650, 5651, 5652, 5653, 5654, 5655, 5656, 5657, 5658, 5659, 5660, 5661, 5662, 5663, 5664, 5665, 2843, 2844, 2845, 2846, 2847, 2848}, new String[] { "Zombies are undead so magic is your best bet against", "them, there is even a spell specially for", "fighting the undead." }, 1, true, false), + ; static final HashMap taskMap = new HashMap<>(); static{ @@ -117,8 +133,7 @@ public enum Tasks { public final int[] ids; public boolean undead = false; public boolean dragon = false; - public int amtHash; - public String questReq = ""; + public Quests questReq = null; Tasks(int combatCheck, int[] ids, String[] info, int levelReq, boolean undead, boolean dragon){ this.levelReq = levelReq; this.ids = ids; @@ -128,17 +143,7 @@ public enum Tasks { this.combatCheck = combatCheck; } - Tasks(int combatCheck, int[] ids, String[] info, int levelReq, boolean undead, boolean dragon, int amtHash){ - this.levelReq = levelReq; - this.ids = ids; - this.info = info; - this.undead = undead; - this.dragon = dragon; - this.amtHash = amtHash; - this.combatCheck = combatCheck; - } - - Tasks (int combatCheck, int[] ids, String[] info, int levelReq, String questReq) { + Tasks (int combatCheck, int[] ids, String[] info, int levelReq, Quests questReq) { this.combatCheck = combatCheck; this.ids = ids; this.info = info; @@ -155,7 +160,7 @@ public enum Tasks { } public boolean hasQuestRequirements (Player player) { - return questReq.equals("") || hasRequirement(player, questReq, false); + return questReq == null || hasRequirement(player, questReq, false); } public static Tasks forId(int id){ diff --git a/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt b/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt index e814eafcf..a1d216746 100644 --- a/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt +++ b/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt @@ -16,7 +16,7 @@ class WaterfiendBehavior : NPCBehavior(*Tasks.WATERFIENDS.ids) { true, SwitchAttack( CombatStyle.MAGIC.swingHandler, - Animation(1581, Priority.HIGH), + Animation(302, Priority.HIGH), // 299 = attack animation, 302 = idle animation. (authentic bug) null, null, Projectile.create( @@ -33,7 +33,7 @@ class WaterfiendBehavior : NPCBehavior(*Tasks.WATERFIENDS.ids) { ), SwitchAttack( CombatStyle.RANGE.swingHandler, - Animation(1581, Priority.HIGH), + Animation(302, Priority.HIGH), // 299 = attack animation, 302 = idle animation. (authentic bug) null, null, Projectile.create( diff --git a/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java b/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java index 7e8e55cd4..f86de623f 100644 --- a/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java +++ b/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java @@ -152,7 +152,7 @@ public final class AncientCavern extends MapZone implements Plugin { } }); - player.getInterfaceManager().open(c); + player.getInterfaceManager().openOverlay(c); break; case 3: PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); diff --git a/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java b/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java index c47cfff3c..af34faff2 100644 --- a/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java +++ b/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java @@ -28,7 +28,6 @@ import java.util.Map; * Handles the lumbridge dungeon. * @author Vexia */ -@Initializable public final class LumbridgeDungeon extends MapZone implements Plugin { /** diff --git a/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java b/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java index edce0a909..3dec3dd92 100644 --- a/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java +++ b/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java @@ -132,7 +132,7 @@ public final class SmokeDungeon extends MapZone implements Plugin { * @param player the player. */ private static void effect(Player player) { - int hit = 2; + int hit = 10; setDelay(player); if (RandomFunction.random(2) == 1) { player.sendChat(CHATS[RandomFunction.random(CHATS.length)]); diff --git a/Server/src/main/content/global/skill/slayer/unused-tasks b/Server/src/main/content/global/skill/slayer/unused-tasks deleted file mode 100644 index 03501f20e..000000000 --- a/Server/src/main/content/global/skill/slayer/unused-tasks +++ /dev/null @@ -1,92 +0,0 @@ - /*WALL_BEASTS(new Task(new int[] { 7823 }, new String[] { "A spiny helmet or equivalent is required to start fighting one " }, 35, new Master[] { Master.MAZCHNA }, false, Equipment.SPINY_HELMET) { - @Override - public boolean isDisabled() { - return true; - } - }), - WARPED_TERRORBIRDS(new Task(new int[] { 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6322, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, }, new String[] { "They require 56 Slayer and a Crystal chime to be killed. " }, 56, new Master[] { Master.DURADEL }, false) { - @Override - public boolean isDisabled() { - return true; - } - }), - WARPED_TORTOISES(new Task(new int[] { 6296, 6297 }, new String[] { "A warped tortoise is not as slow as they look." }, 56, new Master[] { Master.DURADEL }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ -/*CERBERUS(new Task(new int[] {8632, 8634}, new String[] {"Cerberus is about the best guard dog there is!"}, 91, new Master[] {Master.VANNAKA, Master.CHAELDAR, Master.NIEVE, Master.DURADEL}, false, 20 | 25 << 16) { - @Override - public boolean isDisabled() { - return true; - } - })*/ -/*ZYGOMITES(new Task(new int[] { 3346, 3347 }, new String[] { "Mutated zygomites are monsters that appear as Fungi until provoked." }, 57, new Master[] { Master.CHAELDAR }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ -/*SUQAHS(new Task(new int[] { 4527, 4528, 4529, 4530, 4531, 4532, 4533 }, new String[] {}, 1, new Master[] { Master.DURADEL }, false) { - @Override - public boolean isDisabled() { - return true; - } - }), - TERROR_DOG(new Task(new int[] { 5417, 5418 }, new String[] { "Terror Dogs are much like Wolves, they are pack creatures which will hunt in groups." }, 1, new Master[] { Master.VANNAKA, Master.DURADEL }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ -/*SHADOW_WARRIORS(new Task(new int[] { 158 }, new String[] { "Shadow warriors are dark and mysterious, they hide in the shadows so be wary of ambushes." }, 1, new Master[] { Master.VANNAKA, Master.CHAELDAR }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ -//MOGRES(new Task(new int[] { 114 }, new String[] { "Mogres are Slayer monsters and require level 32 Slayer to kill. " }, 32, new Master[] { Master.MAZCHNA, Master.VANNAKA }, false)), - /*MOLANISKS(new Task(new int[] { 5751 }, new String[] { "Molanisks are found attached to cave walls and must be lured", "off with a Slayer bell" }, 39, new Master[] { Master.VANNAKA }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ - - /*RED_DRAGONS(new Task(new int[] { 53, 4669, 4670, 4671, 4672, 1589, 3588, 4667, 4668, }, new String[] { "Red dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, new Master[] { Master.DURADEL }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ - /*SCABARITES(new Task(new int[] { 2009 }, new String[] { "The Scabarites are fairly strong monsters, and can hit pretty hard." }, 1, new Master[] { Master.CHAELDAR }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ - /*SEA_SNAKES(new Task(new int[] { 3943, 3939, }, new String[] { "They are quick, make sure you don't let your", "eye off of them for 1 second." }, 1, new Master[] { Master.VANNAKA }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ -/*ELVES(new Task(new int[] { 1184, 1183, 1185 }, new String[] { "Elves are quick, agile and vicious fighters which", "often favour bows and polearms." }, 1, new Master[] { Master.VANNAKA, Master.CHAELDAR, Master.NIEVE }, false) { - @Override - public boolean isDisabled() { - return true; - } - }), - FEVER_SPIDERS(new Task(new int[] { 2850 }, new String[] { "Fever Spiders are giant spiders that carry the deadly Spider Fever.", "If you don't want to catch it I suggest you wear Slayer Gloves to fight them." }, 1, new Master[] { Master.CHAELDAR, Master.DURADEL }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ - /*KILLERWATTS(new Task(new int[] { 3201, 3202 }, new String[] { "Vexia halfassed this... (this was shadow knight text)" }, 37, new Master[] { Master.VANNAKA }, false) { - @Override - public boolean isDisabled() { - return true; - } - }),*/ \ No newline at end of file diff --git a/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java b/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java index 84d4e7edf..64833097c 100644 --- a/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java +++ b/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java @@ -1,55 +1,23 @@ package content.global.skill.smithing; +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.api.Container; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; -import core.game.node.item.Item; import core.plugin.Initializable; -import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; /** * Represents the dialogue plugin used for making a dragon shield. * @author 'Vexia - * @version 1.0 + * @author Player Name + * @version 1.1 */ @Initializable public final class DragonShieldDialogue extends DialoguePlugin { - - /** - * Represents the item shield parts. - */ - private static final Item[] SHIELD_PARTS = new Item[] { new Item(2366), new Item(2368) }; - - /** - * Represents th edraconic visage item. - */ - private static final Item DRACONIC_VISAGE = new Item(11286); - - /** - * Represents the anti dragon fire shield. - */ - private static final Item ANTI_DRAGONSHIELD = new Item(1540); - - /** - * Represents the dragon fire shield item. - */ - private static final Item DRAGON_FIRESHIELD = new Item(11284); - - /** - * Represents the shield item. - */ - private static final Item SQ_SHIELD = new Item(1187); - - /** - * Represents the hammering animation. - */ - private static Animation ANIMATION = new Animation(898); - - /** - * Represents the shield type. - */ - private int type; - /** * Constructs a new {@code DragonShieldDialogue} {@code Object}. */ @@ -74,11 +42,26 @@ public final class DragonShieldDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - type = (int) args[0]; + if (!inInventory(player, Items.HAMMER_2347, 1) && !SkillcapePerks.isActive(SkillcapePerks.BAREFISTED_SMITHING, player)) { + interpreter.sendDialogue("You need a hammer to work the metal with."); + } + int type = (int) args[0]; if (type == 1) { - interpreter.sendDialogue("You set to work trying to fix the ancient shield. It's seen some", "heavy reward and needs some serious work doing to it."); + if (!(inInventory(player, Items.SHIELD_RIGHT_HALF_2368, 1) && inInventory(player, Items.SHIELD_LEFT_HALF_2366, 1))) { + interpreter.sendDialogue("You need the other half of the shield."); //todo authentic message + return false; + } + interpreter.sendDialogue("You set to work trying to fix the ancient shield. It's seen some", "heavy action and needs some serious work doing to it."); stage = 0; } else { + if (!inInventory(player, Items.ANTI_DRAGON_SHIELD_1540, 1)) { + interpreter.sendDialogue("You need an anti-dragon shield to attach the visage to."); //todo authentic message + return false; + } + if (!inInventory(player, Items.DRACONIC_VISAGE_11286, 1)) { + interpreter.sendDialogue("You don't have anything you could attach to the shield."); //todo authentic message + return false; + } interpreter.sendDialogue("You set to work, trying to attach the ancient draconic", "visage to your anti-dragonbreath shield. It's not easy to", "work with the ancient artifact and it takes all of your", "skills as a master smith."); stage = 10; } @@ -89,26 +72,26 @@ public final class DragonShieldDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - player.lock(5); - player.animate(ANIMATION); - interpreter.sendDialogue("Even for an experienced armourer it is not an easy task, but", "eventually it is ready. You have restored the dragon square shield to", "its former glory."); - if (player.getInventory().remove(SHIELD_PARTS)) { - player.getInventory().add(SQ_SHIELD); + lock(player, 5); + animate(player, 898, false); + if (removeItem(player, Items.SHIELD_RIGHT_HALF_2368, Container.INVENTORY) && removeItem(player, Items.SHIELD_LEFT_HALF_2366, Container.INVENTORY)) { + interpreter.sendDialogue("Even for an experienced armourer it is not an easy task, but", "eventually it is ready. You have restored the dragon square shield to", "its former glory."); + addItem(player, Items.DRAGON_SQ_SHIELD_1187, 1, Container.INVENTORY); + rewardXP(player, Skills.SMITHING, 75); } - player.getSkills().addExperience(Skills.SMITHING, 75, true); stage = 1; break; case 1: end(); break; case 10: - player.lock(5); - player.animate(ANIMATION); - interpreter.sendDialogue("Even for an experienced armourer it is not an easy task, but", "eventually it is ready. You have crafted the", "draconic visage and anti-dragonbreath shield into a", "dragonfire shield."); - if (player.getInventory().remove(DRACONIC_VISAGE, ANTI_DRAGONSHIELD)) { - player.getInventory().add(DRAGON_FIRESHIELD); + lock(player, 5); + animate(player, 898, false); + if (removeItem(player, Items.ANTI_DRAGON_SHIELD_1540, Container.INVENTORY) && removeItem(player, Items.DRACONIC_VISAGE_11286, Container.INVENTORY)) { + interpreter.sendDialogue("Even for an experienced armourer it is not an easy task, but", "eventually it is ready. You have crafted the", "draconic visage and anti-dragonbreath shield into a", "dragonfire shield."); + addItem(player, Items.DRAGONFIRE_SHIELD_11284, 1, Container.INVENTORY); + rewardXP(player, Skills.SMITHING, 2000); } - player.getSkills().addExperience(Skills.SMITHING, 2000); stage = 1; break; } diff --git a/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java b/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java index 1468549d2..be0190327 100644 --- a/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java +++ b/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java @@ -19,6 +19,7 @@ import core.plugin.Plugin; import java.util.ArrayList; import java.util.List; +import content.data.Quests; /** * Represents the plugin used for the furnace. @@ -64,7 +65,7 @@ public final class FurnaceOptionPlugin extends OptionHandler { private static void show(final Player player) { player.getInterfaceManager().openChatbox(311); player.getPacketDispatch().sendItemZoomOnInterface(2349, 150, 311, 4); - if (player.getQuestRepository().isComplete("The Knight's Sword")) { + if (player.getQuestRepository().isComplete(Quests.THE_KNIGHTS_SWORD)) { player.getPacketDispatch().sendString("



Blurite", 311, 20); } player.getPacketDispatch().sendItemZoomOnInterface(Bar.BLURITE.getProduct().getId(), 150, 311, 5); @@ -77,26 +78,6 @@ public final class FurnaceOptionPlugin extends OptionHandler { player.getPacketDispatch().sendItemZoomOnInterface(2363, 150, 311, 12); } - /** - * Method used to handle the tutorial island interaction. - * @param player the player. - */ - private final void handleTutorialIsland(final Player player) { - if (player.getInventory().containItems(438, 436)) { - player.animate(ANIMATION); - GameWorld.getPulser().submit(new Pulse(2, player) { - @Override - public boolean pulse() { - player.getInventory().remove(ITEMS); - player.getInventory().add(Bar.BRONZE.getProduct()); - player.getSkills().addExperience(Skills.SMITHING, Bar.BRONZE.getExperience()); - return true; - } - - }); - } - } - /** * Represents the plugin used to handle the ore on the furance. * @author 'Vexia diff --git a/Server/src/main/content/global/skill/smithing/SmithingPulse.java b/Server/src/main/content/global/skill/smithing/SmithingPulse.java index f9b7eec98..97a844d51 100644 --- a/Server/src/main/content/global/skill/smithing/SmithingPulse.java +++ b/Server/src/main/content/global/skill/smithing/SmithingPulse.java @@ -14,6 +14,7 @@ import core.tools.StringUtils; import static core.api.ContentAPIKt.hasRequirement; import static core.api.ContentAPIKt.sendDialogue; +import content.data.Quests; /** * Represents the pulse used to smith a bar. @@ -67,11 +68,11 @@ public class SmithingPulse extends SkillPulse { player.getDialogueInterpreter().sendDialogue("You need a hammer to work the metal with."); return false; } - if (!player.getQuestRepository().isComplete("The Tourist Trap") && bar.getSmithingType() == SmithingType.TYPE_DART_TIP) { + if (!player.getQuestRepository().isComplete(Quests.THE_TOURIST_TRAP) && bar.getSmithingType() == SmithingType.TYPE_DART_TIP) { player.getDialogueInterpreter().sendDialogue("You need to complete Tourist Trap to smith dart tips."); return false; } - if (!hasRequirement(player, "Death Plateau", false) && bar.getSmithingType() == SmithingType.TYPE_CLAWS) { + if (!hasRequirement(player, Quests.DEATH_PLATEAU, false) && bar.getSmithingType() == SmithingType.TYPE_CLAWS) { sendDialogue(player, "You need to complete Death Plateau to smith claws."); return false; } diff --git a/Server/src/main/content/global/skill/smithing/SmithingType.java b/Server/src/main/content/global/skill/smithing/SmithingType.java index fd38a6209..94465077e 100644 --- a/Server/src/main/content/global/skill/smithing/SmithingType.java +++ b/Server/src/main/content/global/skill/smithing/SmithingType.java @@ -106,7 +106,7 @@ public enum SmithingType { /** * Grapple Tips */ - TYPE_GRAPPLE_TIP(1, 170, 171, new int[] { 175, 176, 175, 174, 173 }, 1), + TYPE_GRAPPLE_TIP(1, 170, 171, new int[] { 176, 175, 174, 173 }, 1), /** * The studs type. diff --git a/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java b/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java index 06c55f1e1..7951ab0ed 100644 --- a/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java +++ b/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java @@ -1,9 +1,11 @@ package content.global.skill.smithing.smelting; import static core.api.ContentAPIKt.*; -import core.api.EquipmentSlot; + +import core.api.Container; import core.game.event.ResourceProducedEvent; import core.game.container.impl.EquipmentContainer; +import core.tools.Log; import org.rs09.consts.Items; import core.game.world.map.Location; import core.game.node.entity.skill.SkillPulse; @@ -16,6 +18,7 @@ import core.game.world.update.flag.context.Graphics; import core.tools.RandomFunction; import core.tools.StringUtils; import org.rs09.consts.Sounds; +import content.data.Quests; /** * Represents the pulse used to smelt. @@ -87,7 +90,7 @@ public class SmeltingPulse extends SkillPulse { if (bar == null || player == null) { return false; } - if (bar == Bar.BLURITE && !player.getQuestRepository().isComplete("The Knight's Sword")) { + if (bar == Bar.BLURITE && !player.getQuestRepository().isComplete(Quests.THE_KNIGHTS_SWORD)) { return false; } if (player.getSkills().getLevel(Skills.SMITHING) < bar.getLevel()) { @@ -175,36 +178,30 @@ public class SmeltingPulse extends SkillPulse { } /** - * Checks if the player has a ring of forging. - * - * @param player the player. - * @return {@code True} if so. - */ - public boolean hasForgingRing(Player player) { - return player.getEquipment().containsItem(RING_OF_FORGING); - } - - /** - * Checks if the forging is a succes. + * Checks if the forging is a success. * * @param player the player. * @return {@code True} if success. */ public boolean success(Player player) { if (bar == Bar.IRON && !superHeat) { - if (hasForgingRing(player)) { - Item ring = getItemFromEquipment(player, EquipmentSlot.RING); - if(ring != null){ - if(getCharge(ring) == 1000) setCharge(ring, 140); - adjustCharge(ring, -1); - if(getCharge(ring) == 0){ - player.getEquipment().remove(ring); - sendMessage(player, "Your ring of forging uses up its last charge and disintegrates."); + if (inEquipment(player, Items.RING_OF_FORGING_2568, 1)) { + int charges = getAttribute(player, "ringOfForgingCharges", 140) - 1; + if (charges <= 0) { + if (removeItem(player, Items.RING_OF_FORGING_2568, Container.EQUIPMENT)) { + charges = 140; + sendMessage(player, "Your Ring of forging uses up its last charge and disintegrates."); + // stop the smelting queue + stop(); + } else { + log(this.getClass(), Log.ERR, "Failed to delete empty ring of forging for player " + player.getName()); + return false; //unfair but prevents exploit if the impossible happens } } + setAttribute(player, "/save:ringOfForgingCharges", charges); return true; } else { - return RandomFunction.getRandom(100) <= (player.getSkills().getLevel(Skills.SMITHING) >= 45 ? 80 : 50); + return RandomFunction.nextBool(); } } return true; diff --git a/Server/src/main/content/global/skill/summoning/SummoningPouch.java b/Server/src/main/content/global/skill/summoning/SummoningPouch.java index d55af8fa0..b91634318 100644 --- a/Server/src/main/content/global/skill/summoning/SummoningPouch.java +++ b/Server/src/main/content/global/skill/summoning/SummoningPouch.java @@ -34,7 +34,7 @@ public enum SummoningPouch { /** * Represents a granite crab pouch. */ - GRANITE_CRAB_POUCH(4, 12009, 16, 31.6, 6796, 0.2, 2, false, new Item(12158), new Item(12155), new Item(440), new Item(12183, 7)), + GRANITE_CRAB_POUCH(4, 12009, 16, 21.6, 6796, 0.2, 2, false, new Item(12158), new Item(12155), new Item(440), new Item(12183, 7)), /** * Represents a spirit mosquito pouch. diff --git a/Server/src/main/content/global/skill/summoning/SummoningScroll.java b/Server/src/main/content/global/skill/summoning/SummoningScroll.java index a11c706d1..cd02a4419 100644 --- a/Server/src/main/content/global/skill/summoning/SummoningScroll.java +++ b/Server/src/main/content/global/skill/summoning/SummoningScroll.java @@ -70,8 +70,8 @@ public enum SummoningScroll { DEADLY_CLAW_SCROLL(55, 12831, 11.0, 77, 12162), ACORN_MISSILE_SCROLL(56, 12457, 1.6, 78, 12013), TITANS_CONSTITUTION_SCROLL1(57, 12824, 7.9, 79, 12802), - TITANS_CONSTITUTION_SCROLL2(58, 12824, 7.9, 79, 12806), - TITANS_CONSTITUTION_SCROLL3(59, 12824, 7.9, 79, 12804), + TITANS_CONSTITUTION_SCROLL2(58, 12824, 7.9, 79, 12804), + TITANS_CONSTITUTION_SCROLL3(59, 12824, 7.9, 79, 12806), REGROWTH_SCROLL(60, 12442, 1.6, 80, 12025), SPIKE_SHOT_SCROLL(61, 12456, 4.1, 83, 12017), EBON_THUNDER_SCROLL(62, 12837, 8.3, 83, 12788), diff --git a/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt b/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt index 2a8debf26..c47862b62 100644 --- a/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt +++ b/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt @@ -44,7 +44,7 @@ class SummoningTabListener : InterfaceListener { // Dismiss now if (player.getFamiliarManager().getFamiliar() is Pet) { val pet = player.familiarManager.familiar as Pet - player.familiarManager.removeDetails(pet.getItemIdHash()) + player.familiarManager.removeDetails(pet.getItemId()) } player.familiarManager.dismiss() } diff --git a/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java b/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java index 68d038c0d..6296daef4 100644 --- a/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java +++ b/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java @@ -34,6 +34,7 @@ import core.plugin.Plugin; import core.plugin.ClassScanner; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Handles the summoning training room. @@ -81,7 +82,7 @@ public final class SummoningTrainingRoom extends OptionHandler { public boolean handle(final Player player, Node node, String option) { Scenery object = (Scenery) node; Location loc = null; - Quest quest = player.getQuestRepository().getQuest("Wolf Whistle"); + Quest quest = player.getQuestRepository().getQuest(Quests.WOLF_WHISTLE); int questVal = quest.getStage(player) == 0 ? 0 : quest.getStage(player) > 0 && quest.getStage(player) < 100 ? 5 : 28893; switch (option) { case "close": @@ -312,7 +313,7 @@ public final class SummoningTrainingRoom extends OptionHandler { @Override public boolean open(Object... args) { cutscene = (CutscenePlugin) args[0]; - quest = player.getQuestRepository().getQuest("Wolf Whistle"); + quest = player.getQuestRepository().getQuest(Quests.WOLF_WHISTLE); fluffy = NPC.create(6990, cutscene.getBase().transform(41, 52, 1)); fluffy.init(); fluffy.faceTemporary(player, 1); diff --git a/Server/src/main/content/global/skill/summoning/familiar/BabyChinchompaNPC.java b/Server/src/main/content/global/skill/summoning/familiar/BabyChinchompaNPC.java deleted file mode 100644 index 66c03042b..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/BabyChinchompaNPC.java +++ /dev/null @@ -1,103 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.Metamorphosis; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.tools.RandomFunction; - -/** - * Handles the baby chinchompa pet. - * @author Empathy - * - */ -@Initializable -public class BabyChinchompaNPC extends Metamorphosis { - - /** - * The chinchompa ids. - */ - private static final int[] CHINCHOMPA_IDS = new int[] { 8643, 8644, 8657, 8658 }; - - /** - * Constructs a new {@code BabyChinchompaNPC} object. - */ - public BabyChinchompaNPC() { - super(CHINCHOMPA_IDS); - } - - @Override - public DialoguePlugin getDialoguePlugin() { - return new BabyChinchompaDialogue(); - } - - @Override - public int getRandomNpcId() { - int i = RandomFunction.getRandom(getIds().length - 1); - if (getIds()[i] == 8658) { - int x = RandomFunction.getRandom(30); - if (x == 1) { - return getIds()[i]; - } else { - return getIds()[i-1]; - } - } - return getIds()[i]; - } - - /** - * Handles the BabyChinchompa Dialogue. - * @author Empathy - * - */ - public final class BabyChinchompaDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code BabyChinchompaDialogue} {@code Object}. - */ - public BabyChinchompaDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code BabyChinchompaDialogue} {@code Object}. - * - * @param player the player. - */ - public BabyChinchompaDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new BabyChinchompaDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, npc.getId() != 8658 ? "Squeak! Squeak!" : "Squeaka! Squeaka!"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 8643, 8644, 8657, 8658 }; - } - } -} diff --git a/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java b/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java index d1716b3d5..02564d7e1 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java @@ -34,6 +34,7 @@ public final class CockatriceFamiliarNPC implements Plugin { ClassScanner.definePlugin(new SpiritPengatrice()); ClassScanner.definePlugin(new SpiritCoraxatrice()); ClassScanner.definePlugin(new SpiritVulatrice()); + ClassScanner.definePlugin(new SpiritSaratrice()); return this; } @@ -58,7 +59,11 @@ public final class CockatriceFamiliarNPC implements Plugin { GameWorld.getPulser().submit(new Pulse(1, familiar.getOwner(), familiar, target) { @Override public boolean pulse() { - target.getSkills().updateLevel(skill, -3, 0); + if(skill == 5) { + target.skills.decrementPrayerPoints(3); + }else { + target.getSkills().updateLevel(skill, -3, 0); + } Projectile.magic(familiar, target, 1468, 40, 36, 71, 10).send(); familiar.sendFamiliarHit(target, 10, Graphics.create(1469)); return true; @@ -297,4 +302,43 @@ public final class CockatriceFamiliarNPC implements Plugin { } } + + /** + * Represents the Spirit Saratrice familiar. + * @author Aero - DeadlyGenga + */ + public class SpiritSaratrice extends Forager { + + /** + * Constructs a new {@code SpiritSaratriceNPC} {@code Object}. + */ + public SpiritSaratrice() { + this(null, 6879); + } + + /** + * Constructs a new {@code SpiritSaratriceNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritSaratrice(Player owner, int id) { + super(owner, id, 3600, 12099, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritSaratrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.PRAYER); + } + + @Override + public int[] getIds() { + return new int[] { 6879, 6880 }; + } + + } } diff --git a/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java b/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java index ff053a5da..b369bf4d6 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java +++ b/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java @@ -55,7 +55,7 @@ public final class DismissDialoguePlugin extends DialoguePlugin { if (player.getFamiliarManager().getFamiliar() instanceof Pet) { interpreter.sendDialogues(player, null, "Run along; I'm setting you free."); Pet pet = (Pet) player.getFamiliarManager().getFamiliar(); - player.getFamiliarManager().removeDetails(pet.getItemIdHash()); + player.getFamiliarManager().removeDetails(pet.getItemId()); } else { end(); } diff --git a/Server/src/main/content/global/skill/summoning/familiar/Familiar.java b/Server/src/main/content/global/skill/summoning/familiar/Familiar.java index b74f15e6b..089db9352 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/Familiar.java +++ b/Server/src/main/content/global/skill/summoning/familiar/Familiar.java @@ -27,7 +27,6 @@ import core.tools.Log; import core.tools.RandomFunction; import core.game.node.entity.combat.CombatPulse; import core.game.node.entity.combat.CombatSwingHandler; -import core.tools.SystemLogger; import core.game.world.GameWorld; import content.global.skill.summoning.SummoningPouch; import org.rs09.consts.Sounds; @@ -36,6 +35,7 @@ import java.util.ArrayList; import java.util.List; import static core.api.ContentAPIKt.*; +import static core.api.ContentAPIKt.sendMessage; /** * Represents a familiar. @@ -82,6 +82,8 @@ public abstract class Familiar extends NPC implements Plugin { * The amount of special points left. */ protected int specialPoints = 60; + + public static final String INFINITE_SPECIAL_MOVE_ATTRIBUTE = "infinite-special-move"; /** * The pouch id. @@ -120,7 +122,30 @@ public abstract class Familiar extends NPC implements Plugin { */ private final int attackStyle; - private boolean firstCall = true; + /** + * The amount of points to drain every tick. + * This is a constant depending on the familiar's level req and time remaining (GL #1903). + * https://runescape.wiki/w/Summoning_points?oldid=2171795: "Over the life of the familiar, the number of summoning + * points drained will be equal to the level required to summon the familiar (unless you run out of summoning + * points). This means that if a player summons a bunyip with 75 Summoning points remaining, 7 points will be + * drained immediately, and 61 more will be drained over the life the bunyip, for a total of 68 points (the level of + * the bunyip)." + */ + private final double pointsPerTick; + + /** + * Keeps track of the fractional pointsPerTick that have been drained already. If >1.0, drain a point and subtract + * 1.0. Note that this means that we will never drain a point on the final tick (unless pointsPerTick turned out to + * be integer, but this case is handled by the 'ticks > 0' check in handleTickActions()). This is intentional; it + * allows us to, correctly, artificially extend the interval by one so that the drain events are evenly spaced + * throughout the lifetime of the summon (refer to the dreadfowl example below). + */ + private double fracDrain = 0.0; + + /** + * Whether this is the first call (i.e. not a renew summon). + */ + private boolean firstCall = true; /** * Constructs a new {@code Familiar} {@code Object}. @@ -141,6 +166,23 @@ public abstract class Familiar extends NPC implements Plugin { this.specialCost = specialCost; this.combatFamiliar = NPCDefinition.forId(getOriginalId() + 1).getName().equals(getName()); this.attackStyle = attackStyle; + /* The initial points are drained on summon. Then, the remaining points are drained over an interval. + * To prevent the last point from being drained only very late, we artificially extend the interval by one. + * Example: a dreadfowl drains 1 point on summon, and then needs to drain 3 points over 400 ticks. Naively + * draining a point on ticks 133, 266, and 399 allows players to save a point at the expense of just one tick. + * Instead, we drain on ticks 100, 200, and 300. + * Example 2: a spirit tz-kih drains 3 points on summon, then needs to drain 19 more points over 1800 ticks. + * This means it needs to drain a point every 90 ticks, since the 0th tick remaining will not drain. + * Example 3: a vampire bat needs to drain 27 points over 3300 ticks. It hence drains a point every ~118 ticks. + * Example 4: an abyssal titan drains 10 points on summon, then needs to drain 83 more points over 3200 ticks. + * This means it needs to drain a point every ~34 ticks. + */ + if (pouchId == -1) { + this.pointsPerTick = 0.0; + } else { + int drain = pouch.getLevelRequired() - pouch.getSummonCost() + 1; + this.pointsPerTick = (double) drain / maximumTicks; + } } /** @@ -176,17 +218,22 @@ public abstract class Familiar extends NPC implements Plugin { transform(); } } - - @Override + + @Override public void init() { init(getSpawnLocation(), true); } @Override public void handleTickActions() { - if (ticks-- % 50 == 0) { - updateSpecialPoints(-15); + ticks--; + fracDrain += pointsPerTick; + if (fracDrain > 1.0 && ticks > 0) { + fracDrain -= 1.0; owner.getSkills().updateLevel(Skills.SUMMONING, -1, 0); + } + if (ticks % 50 == 0) { + updateSpecialPoints(-15); if (!getText().isEmpty()) { super.sendChat(getText()); } @@ -214,7 +261,10 @@ public abstract class Familiar extends NPC implements Plugin { if (victim == null) { victim = owner.getAttribute("combat-attacker"); } - if (combat.getVictim() != this && victim != null && !victim.isInvisible() && getProperties().isMultiZone() && owner.getProperties().isMultiZone() && isCombatFamiliar() && !isBurdenBeast() && !isPeacefulFamiliar()) { + if (combat.getVictim() != this && victim != null && !victim.isInvisible() + && getProperties().isMultiZone() && owner.getProperties().isMultiZone() + && victim.getProperties().isMultiZone() && isCombatFamiliar() + && !isBurdenBeast() && !isPeacefulFamiliar()) { // Are you serious my brotha? getProperties().getCombatPulse().attack(victim); } } @@ -227,49 +277,121 @@ public abstract class Familiar extends NPC implements Plugin { } handleFamiliarTick(); } - + @Override public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { - if (entity == owner) { - if(message) { - owner.getPacketDispatch().sendMessage("You can't just betray your own familiar like that!"); + if (isAttackableBy(entity, style, message)) return false; + return super.isAttackable(entity, style, message); + } + + @Override + public boolean continueAttack(Entity target, CombatStyle style, boolean message) { + if (getProperties().getCombatPulse().getVictim() == target) { + return canAttackTarget(target, style, message); + } + if (target == owner) { + if (message) { + sendMessage(owner, "You can't just betray your own familiar like that!"); } return false; } - if (entity instanceof Player) { - if (!owner.isAttackable(entity, style, message)) { - return false; - } - } - if (!getProperties().isMultiZone()) { - if (entity instanceof Player && !((Player) entity).getProperties().isMultiZone()) { - if(message) { - ((Player) entity).getPacketDispatch().sendMessage("You have to be in multicombat to attack a player's familiar."); - } - return false; - } - if (entity instanceof Player) { - if(message) { - ((Player) entity).getPacketDispatch().sendMessage("This familiar is not in the a multicombat zone."); - } + return true; + } + + /** + * Checks if the familiar can attack the target (familiar as attacker). + * Called from continueAttack() when familiar initiates combat. + * + * @param target The target to attack. + * @param style The combat style. + * @param message Whether to send messages. + * + * @return true if the familiar can attack the target. + */ + private boolean canAttackTarget(Entity target, CombatStyle style, boolean message) { + if (target == owner) { + if (message) { + sendMessage(owner, "You can't just betray your own familiar like that!"); } return false; } - if (entity instanceof Player) { - if (!((Player) entity).getSkullManager().isWilderness()) { - if(message) { - ((Player) entity).getPacketDispatch().sendMessage("You have to be in the wilderness to attack a player's familiar."); + if (target instanceof Player) { + Player targetPlayer = (Player) target; + if (!targetPlayer.getSkullManager().isWilderness()) { + if (message) { + sendMessage(owner, "You have to be in the wilderness to attack a player's familiar."); } return false; } if (!owner.getSkullManager().isWilderness()) { - if(message) { - ((Player) entity).getPacketDispatch().sendMessage("This familiar's owner is not in the wilderness."); + if (message) { + sendMessage(owner, "This familiar's owner is not in the wilderness."); + } + return false; + } + if (!owner.isAttackable(target, style, false)) { + return false; + } + if (!owner.getProperties().isMultiZone()) { + if (message) { + sendMessage(owner, "You have to be in a multicombat zone to attack another player with your familiar."); } return false; } } - return super.isAttackable(entity, style, message); + + return true; + } + + /** + * Checks if the entity can attack this familiar (familiar as target). + * Called from isAttackable() when someone attacks the familiar. + * + * @param attacker The entity trying to attack the familiar. + * @param style The combat style. + * @param message Whether to send messages. + * + * @return true if the attacker cannot attack the familiar (invalid target). + */ + private boolean isAttackableBy(Entity attacker, CombatStyle style, boolean message) { + if (attacker == owner) { + if (message) { + sendMessage(owner, "You can't just betray your own familiar like that!"); + } + return true; + } + if (attacker instanceof Player) { + Player attackingPlayer = (Player) attacker; + if (!attackingPlayer.getSkullManager().isWilderness()) { + if (message) { + sendMessage(attackingPlayer, "You have to be in the wilderness to attack a player's familiar."); + } + return true; + } + if (!owner.getSkullManager().isWilderness()) { + if (message) { + sendMessage(attackingPlayer, "This familiar's owner is not in the wilderness."); + } + return true; + } + if (!owner.isAttackable(attackingPlayer, style, false)) { + return true; + } + if (!attackingPlayer.getProperties().isMultiZone()) { + if (message) { + sendMessage(attackingPlayer, "You have to be in a multicombat zone to attack a player's familiar."); + } + return true; + } + if (!this.getProperties().isMultiZone()) { + if (message) { + sendMessage(attackingPlayer, "This familiar is not in a multicombat zone."); + } + return true; + } + } + + return false; } @Override @@ -340,8 +462,8 @@ public abstract class Familiar extends NPC implements Plugin { private void sendTimeRemaining() { int minutes = ticks / 100; int centiminutes = ticks % 100; - setVarbit(owner, 4534, minutes); - setVarbit(owner, 4290, centiminutes > 49 ? 1 : 0); + setVarbit(owner, 4534, minutes); + setVarbit(owner, 4290, centiminutes > 49 ? 1 : 0); } /** @@ -374,7 +496,9 @@ public abstract class Familiar extends NPC implements Plugin { owner.getInventory().remove(new Item(scroll.getItemId())); playAudio(owner, Sounds.SPELL_4161); visualizeSpecialMove(); - updateSpecialPoints(specialCost); + if (!owner.getAttribute(INFINITE_SPECIAL_MOVE_ATTRIBUTE, false)) { + updateSpecialPoints(specialCost); + } owner.getSkills().addExperience(Skills.SUMMONING, scroll.getExperience(), true); } return true; @@ -386,9 +510,10 @@ public abstract class Familiar extends NPC implements Plugin { public void visualizeSpecialMove() { owner.visualize(Animation.create(7660), Graphics.create(1316)); } - + /** * Sends a familiar hit. + * * @param target the target. * @param maxHit the max hit. * @param graphics the graphics. @@ -405,6 +530,13 @@ public abstract class Familiar extends NPC implements Plugin { hit = RandomFunction.randomize(maxHit); } state.setEstimatedHit(hit); + if (target instanceof NPC && ((NPC) target).getTask() != null && ((NPC) target).getTask().levelReq > owner.getSkills().getLevel(Skills.SLAYER)) { + state.neutralizeHits(); + state.setPoisonDamage(-1); + if (state.getStyle() == CombatStyle.MAGIC) { + state.setEstimatedHit(-1); + } + } target.getImpactHandler().handleImpact(owner, hit, CombatStyle.MELEE, state); if (graphics != null) { target.graphics(graphics); @@ -430,7 +562,7 @@ public abstract class Familiar extends NPC implements Plugin { public void sendFamiliarHit(final Entity target, final int maxHit) { sendFamiliarHit(target, maxHit, null); } - + /** * Checks if this familiar can attack the target (used mainly for special * moves). @@ -441,11 +573,17 @@ public abstract class Familiar extends NPC implements Plugin { } if (target.getLocation().getDistance(getLocation()) > 8) { if (message) { - owner.getPacketDispatch().sendMessage("That target is too far."); + sendMessage(owner, "That target is too far."); } return false; } - if (target.getLocks().isInteractionLocked() || !target.isAttackable(this, CombatStyle.MAGIC, true)) { + if (target instanceof Player && !owner.getProperties().isMultiZone()) { + if (message) { + sendMessage(owner, "You have to be in a multicombat zone to attack another player with your familiar."); + } + return false; + } + if (target.getLocks().isInteractionLocked() || !target.isAttackable(this, CombatStyle.MAGIC, message)) { return false; } return isCombatFamiliar(); @@ -455,11 +593,13 @@ public abstract class Familiar extends NPC implements Plugin { public boolean canAttack(Entity target) { return canAttack(target, true); } - + /** * Checks if a familiar can perform a combat special attack. + * * @param target the target. * @param message show message. + * * @return {@code True} if so. */ public boolean canCombatSpecial(Entity target, boolean message) { @@ -472,6 +612,10 @@ public abstract class Familiar extends NPC implements Plugin { if (getAttribute("special-delay", 0) > GameWorld.getTicks()) { return false; } + // The special move probably should go through but with all harmful effects neutralized, but for now just block the damn thing + if (target instanceof NPC && ((NPC) target).getTask() != null && ((NPC) target).getTask().levelReq > owner.getSkills().getLevel(Skills.SLAYER)) { + return false; + } return true; } @@ -542,9 +686,9 @@ public abstract class Familiar extends NPC implements Plugin { * Sends the familiar packets. */ public void sendConfiguration() { - setVarp(owner, 448, getPouchId()); - setVarp(owner, 1174, getOriginalId()); - setVarp(owner, 1175, specialCost << 23); + setVarp(owner, 448, getPouchId()); + setVarp(owner, 1174, getOriginalId()); + setVarp(owner, 1175, specialCost << 23); sendTimeRemaining(); updateSpecialPoints(0); } @@ -565,13 +709,13 @@ public abstract class Familiar extends NPC implements Plugin { if (isInvisible()) return true; getProperties().setTeleportLocation(destination); if (!(this instanceof Pet)) { - if(firstCall) { + if (firstCall) { // TODO: Each familiar has its own initial summon sound that needs to be implemented at some point - playAudio(owner, Sounds.SUMMON_NPC_188); - firstCall = false; - } else { - playAudio(owner, Sounds.SUMMON_NPC_188); - } + playAudio(owner, Sounds.SUMMON_NPC_188); + firstCall = false; + } else { + playAudio(owner, Sounds.SUMMON_NPC_188); + } if (size() > 1) { graphics(LARGE_SUMMON_GRAPHIC); } else { @@ -607,10 +751,10 @@ public abstract class Familiar extends NPC implements Plugin { getPulseManager().clear(); owner.getInterfaceManager().removeTabs(7); owner.getFamiliarManager().setFamiliar(null); - setVarp(owner, 448, -1); - setVarp(owner, 1176, 0); - setVarp(owner, 1175, 182986); - setVarp(owner, 1174, -1); + setVarp(owner, 448, -1); + setVarp(owner, 1176, 0); + setVarp(owner, 1175, 182986); + setVarp(owner, 1174, -1); owner.getAppearance().sync(); owner.getInterfaceManager().setViewedTab(3); } @@ -624,14 +768,14 @@ public abstract class Familiar extends NPC implements Plugin { if (specialPoints > 60) { specialPoints = 60; } - setVarp(owner, 1177, specialPoints); + setVarp(owner, 1177, specialPoints); } @Override public Plugin newInstance(Object arg) throws Throwable { for (int id : getIds()) { if (FamiliarManager.getFamiliars().containsKey(id)) { - log(this.getClass(), Log.ERR, "Familiar " + id + " was already registered!"); + log(this.getClass(), Log.ERR, "Familiar " + id + " was already registered!"); return null; } FamiliarManager.getFamiliars().put(id, this); diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java index f6a4b8f90..e65c36cf1 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java @@ -1,10 +1,10 @@ package content.global.skill.summoning.familiar; +import content.data.Quests; import content.global.skill.summoning.pet.Pet; import content.global.skill.summoning.pet.Pets; import core.cache.def.impl.ItemDefinition; import core.game.component.Component; -import core.game.container.Container; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import core.game.node.entity.skill.Skills; @@ -17,10 +17,10 @@ import core.game.node.item.Item; import core.game.world.map.Location; import core.game.world.map.zone.ZoneRestriction; import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import static core.api.ContentAPIKt.*; @@ -32,15 +32,24 @@ import static core.api.ContentAPIKt.*; */ public final class FamiliarManager { + /** + * These varbits are packed into varp 1160. Legacy code added 243269632 directly to the raw varp, + * which toggled the Summoning orb visibility on every login. + * They are now written as individual varbits, but two of them remain unknown. + */ + private static final int VARBIT_SUMMONING_ORB_VISIBILITY = 4280; + private static final int VARBIT_SUMMONING_UNKNOWN1 = 4281; + private static final int VARBIT_SUMMONING_UNKNOWN2 = 4282; + /** * The familiars mapping. */ private static final Map FAMILIARS = new HashMap<>(); /** - * The pet details mapping, sorted by item id. + * The pet details mapping. */ - private final Map petDetails = new HashMap(); + private final Map> petDetails = new HashMap<>(); /** * The player. @@ -70,50 +79,74 @@ public final class FamiliarManager { this.player = player; } - public final void parse(JSONObject familiarData) { + public void parse(JSONObject familiarData) { int currentPet = -1; if (familiarData.containsKey("currentPet")) { currentPet = Integer.parseInt(familiarData.get("currentPet").toString()); } - JSONArray petDetails = (JSONArray) familiarData.get("petDetails"); - for (int i = 0; i < petDetails.size(); i++) { - JSONObject detail = (JSONObject) petDetails.get(i); - PetDetails details = new PetDetails(0); - details.updateHunger(Double.parseDouble(detail.get("hunger").toString())); - details.updateGrowth(Double.parseDouble(detail.get("growth").toString())); - int itemIdHash = Integer.parseInt(detail.get("petId").toString()); - // The below is for migrating legacy saves, which stored baby item IDs + growth stages - if (detail.containsKey("stage")) { - // The "itemIdHash" is actually the baby item ID. The "stage" gives the actual pet stage we want. - int babyItemId = itemIdHash; - int itemId = babyItemId; - int stage = Integer.parseInt(detail.get("stage").toString()); - if (stage > 0) { - Pets pets = Pets.forId(babyItemId); - itemId = pets.getNextStageItemId(itemId); - if (stage > 1) { - itemId = pets.getNextStageItemId(itemId); + if (player.version < 2) { //migrate the v1 format + for (Pets pet : Pets.values()) { + for (int id : new int[]{pet.getBabyItemId(), pet.getGrownItemId(), pet.getOvergrownItemId()}) { + if (id != -1) { + petDetails.put(id, new ArrayList()); } } - Item item = new Item(itemId); - item.setCharge(1000); //this is the default value that will correspond to the player's item - itemIdHash = item.getIdHash(); - if (currentPet != -1 && currentPet == babyItemId) { - currentPet = itemIdHash; + } + + JSONArray petDetails = (JSONArray) familiarData.get("petDetails"); + for (Object petDetail : petDetails) { + JSONObject detail = (JSONObject) petDetail; + PetDetails details = new PetDetails(0); + details.updateHunger(Double.parseDouble(detail.get("hunger").toString())); + details.updateGrowth(Double.parseDouble(detail.get("growth").toString())); + int itemId; + int itemIdHash = Integer.parseInt(detail.get("petId").toString()); + // The below is for migrating the v0 format, which stored baby item IDs + growth stages + if (detail.containsKey("stage")) { + // The itemIdHash is actually the baby item ID. The "stage" gives the actual pet stage we want. + int babyItemId = itemIdHash; + itemId = babyItemId; + int stage = Integer.parseInt(detail.get("stage").toString()); + if (stage > 0) { + Pets pets = Pets.forId(babyItemId); + itemId = pets.getNextStageItemId(itemId); + if (stage > 1) { + itemId = pets.getNextStageItemId(itemId); + } + } + } else { + itemId = itemIdHash >> 16 & 0xFFFF; //in the legacy v1 format, was hash rather than item id + } + this.petDetails.get(itemId).add(details); + } + if (currentPet > 65536) { + currentPet = currentPet >> 16 & 0xFFFF; //in the legacy v1 format, was hash rather than item id + } + } else { + JSONObject petDetails = (JSONObject) familiarData.get("petDetails"); + for (Object key : petDetails.keySet()) { + int itemId = Integer.parseInt(key.toString()); + this.petDetails.put(itemId, new ArrayList<>()); + JSONArray values = (JSONArray) petDetails.get(key.toString()); + for (Object petDetail : values) { + JSONObject detail = (JSONObject) petDetail; + PetDetails details = new PetDetails(0); + details.updateHunger(Double.parseDouble(detail.get("hunger").toString())); + details.updateGrowth(Double.parseDouble(detail.get("growth").toString())); + this.petDetails.get(itemId).add(details); } } - this.petDetails.put(itemIdHash, details); } - if (currentPet != -1) { - PetDetails details = this.petDetails.get(currentPet); - int itemId = currentPet >> 16 & 0xFFFF; - Pets pets = Pets.forId(itemId); - if (details == null) { - details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0); - this.petDetails.put(currentPet, details); + int last = this.petDetails.get(currentPet).size() - 1; + PetDetails details; + if (last < 0) { //missing data in save due to historical bug (see GL !2077) + details = new PetDetails(0); + } else { + details = this.petDetails.get(currentPet).get(last); } - familiar = new Pet(player, details, itemId, pets.getNpcId(itemId)); + Pets pets = Pets.forId(currentPet); + familiar = new Pet(player, details, currentPet, pets.getNpcId(currentPet)); } else if (familiarData.containsKey("familiar")) { JSONObject currentFamiliar = (JSONObject) familiarData.get("familiar"); int familiarId = Integer.parseInt( currentFamiliar.get("originalId").toString()); @@ -135,7 +168,11 @@ public final class FamiliarManager { if (hasFamiliar()) { familiar.init(); } - player.getFamiliarManager().setConfig(243269632); + boolean unlocked = player.getQuestRepository().isComplete(Quests.WOLF_WHISTLE); + + setVarbit(player, VARBIT_SUMMONING_ORB_VISIBILITY, unlocked ? 1 : 0); + setVarbit(player, VARBIT_SUMMONING_UNKNOWN1, 0); + setVarbit(player, VARBIT_SUMMONING_UNKNOWN2, 7); } /** @@ -147,7 +184,7 @@ public final class FamiliarManager { public void summon(Item item, boolean pet, boolean deleteItem) { boolean renew = false; if (hasFamiliar()) { - if(familiar.getPouchId() == item.getId()) { + if (familiar.getPouchId() == item.getId()) { renew = true; } else { player.getPacketDispatch().sendMessage("You already have a follower."); @@ -180,7 +217,7 @@ public final class FamiliarManager { player.getPacketDispatch().sendMessage("Invalid familiar " + npcId + " - report on 2009Scape GitLab"); return; } - if(!renew) { + if (!renew) { fam = fam.construct(player, npcId); if (fam.getSpawnLocation() == null) { player.getPacketDispatch().sendMessage("The spirit in this pouch is too big to summon here. You will need to move to a larger"); @@ -193,7 +230,7 @@ public final class FamiliarManager { } player.getSkills().updateLevel(Skills.SUMMONING, -pouch.getSummonCost(), 0); player.getSkills().addExperience(Skills.SUMMONING, pouch.getSummonExperience()); - if(!renew) { + if (!renew) { familiar = fam; spawnFamiliar(); } else { @@ -217,11 +254,10 @@ public final class FamiliarManager { * @param deleteItem the item. * @param location the location. */ - public void morphPet(final Item item, boolean deleteItem, Location location) { - if (hasFamiliar()) { - familiar.dismiss(); - } - summonPet(item, deleteItem, true, location); + public void morphPet(final Item item, boolean deleteItem, Location location, double hunger, double growth) { + int hasWarned = ((Pet) familiar).getHasWarned(); + familiar.dismiss(); + summonPet(item, deleteItem, true, location, hasWarned, hunger, growth); } /** @@ -230,7 +266,7 @@ public final class FamiliarManager { * @param deleteItem the item. */ private boolean summonPet(final Item item, boolean deleteItem) { - return summonPet(item, deleteItem, false, null); + return summonPet(item, deleteItem, false, null, 0, -1, -1); } /** @@ -238,9 +274,8 @@ public final class FamiliarManager { * @param item the item. * @param morph the pet. */ - private boolean summonPet(final Item item, boolean deleteItem, boolean morph, Location location) { + private boolean summonPet(final Item item, boolean deleteItem, boolean morph, Location location, int hasWarned, double hunger, double growth) { final int itemId = item.getId(); - int itemIdHash = item.getIdHash(); if (itemId > 8850 && itemId < 8900) { return false; } @@ -252,52 +287,27 @@ public final class FamiliarManager { player.getDialogueInterpreter().sendDialogue("You need a summoning level of " + pets.getSummoningLevel() + " to summon this."); return false; } - - // If this pet does not have an individual ID yet, we need to find it an available one. - // If it does, we need to verify that this ID is not already used for a different pet. This is needed to correct a historical bug that allowed multiple pets to be assigned the same individual ID (the historical code only checked the *current* stage item ID, failing to realize that we also need to account for *future* stage item IDs, in case the current pet grows up, resulting in a clash when it did). Saves affected by that bug will have multiple copies of the same item pointing to the same pet, which we have an opportunity to rectify now. - ArrayList taken = new ArrayList(); - Container[] searchSpace = {player.getInventory(), player.getBankPrimary(), player.getBankSecondary()}; - for (int checkId = pets.getBabyItemId(); checkId != -1; checkId = pets.getNextStageItemId(checkId)) { - Item check = new Item(checkId, 1); - for (Container container : searchSpace) { - for (Item i : container.getAll(check)) { - taken.add(i.getCharge()); - } - } + if (!this.petDetails.containsKey(itemId)) { + petDetails.put(itemId, new ArrayList()); } - PetDetails details = petDetails.get(itemIdHash); - int individual = item.getCharge(); - if (details != null) { //we have this pet on file, but we need to check that it wasn't affected by the historical bug mentioned above - details.setIndividual(individual); - int count = 0; - for (int i : taken) { - if (i == individual) { - count++; - } - } - if (count > 1) { //this pet is sadly conjoined with another individual of its kind; untangle it by initializing it anew (which is what should have happened in the first place, save the minor detail of hunger propagation from the previous stage, which we no longer have any record of) - details = null; - } - } - if (details == null) { //init new pet - details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0); - for (individual = 0; taken.contains(individual) && individual < 0xFFFF; individual++) {} - details.setIndividual(individual); - // Make a copy of the item to extract what the item's idHash will be when including the individual ID as a "charge" value. - // The copy is necessary since the player's inventory still contains the default-charged item, which we will be removing only later. - Item newItem = item.copy(); - newItem.setCharge(individual); - petDetails.put(newItem.getIdHash(), details); + int last = this.petDetails.get(itemId).size() - 1; + if (last < 0) { //new pet + last = 0; + PetDetails details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0); + this.petDetails.get(itemId).add(details); } + PetDetails details = this.petDetails.get(itemId).get(last); int npcId = pets.getNpcId(itemId); if (npcId > 0) { familiar = new Pet(player, details, itemId, npcId); + ((Pet) familiar).setHasWarned(hasWarned); + if (hunger != -1) ((Pet) familiar).getDetails().setHunger(hunger); + if (growth != -1) ((Pet) familiar).getDetails().setGrowth(growth); if (deleteItem) { player.animate(new Animation(827)); - // We cannot use player().getInventory().remove(item), because that will remove the first pet item it sees, rather than the specific one (with the specific charge value) the player clicked. - // Instead, find the specific item the player dropped by slot, and remove that specific one. - int slot = player.getInventory().getSlotHash(item); - player.getInventory().remove(item, slot, true); + if (!player.getInventory().remove(item, true)) { + return false; + } } if (morph) { morphFamiliar(location); @@ -346,6 +356,9 @@ public final class FamiliarManager { for (int food : pets.getFood()) { if (food == foodId) { player.getInventory().remove(new Item(foodId)); + if (foodId == Items.BUCKET_OF_MILK_1927) { + player.getInventory().add(new Item(Items.BUCKET_1925)); + } player.getPacketDispatch().sendMessage("Your pet happily eats the " + ItemDefinition.forId(food).getName() + "."); player.animate(new Animation(827)); npc.getDetails().updateHunger(-15.0); @@ -364,11 +377,7 @@ public final class FamiliarManager { return; } Pet pet = ((Pet) familiar); - PetDetails details = pet.getDetails(); - Item petItem = new Item(pet.getItemId()); - petItem.setCharge(details.getIndividual()); - if (player.getInventory().add(petItem)) { - petDetails.put(pet.getItemIdHash(),details); + if (player.getInventory().add(new Item(pet.getItemId()))) { player.animate(Animation.create(827)); player.getFamiliarManager().dismiss(); } @@ -423,11 +432,26 @@ public final class FamiliarManager { } /** - * Removes the details for this pet. - * @param itemIdHash The item id hash of the pet. + * Adds pet details for a new pet to that pet's stack. + * @param itemId The item id of the pet. + * @param details The new pet details. */ - public void removeDetails(int itemIdHash) { - petDetails.remove(itemIdHash); + public void addDetails(int itemId, PetDetails details) { + if (petDetails.get(itemId) == null) { + petDetails.put(itemId, new ArrayList<>()); + } + petDetails.get(itemId).add(details); + } + + /** + * Removes the details for this pet. + * @param itemId The item id of the pet. + */ + public void removeDetails(int itemId) { + int last = petDetails.get(itemId).size() - 1; + if (last >= 0) { + petDetails.get(itemId).remove(last); + } } /** @@ -446,16 +470,6 @@ public final class FamiliarManager { return true; } - /** - * Sets a config value. - * @param value the value. - */ - public void setConfig(int value) { - int current = getVarp(player, 1160); - int newVal = current + value; - setVarp(player, 1160, newVal); - } - /** * Gets the familiar. * @return The familiar. @@ -521,7 +535,7 @@ public final class FamiliarManager { } - public Map getPetDetails() { + public Map> getPetDetails() { return petDetails; } } diff --git a/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java b/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java index b66b19993..d2db30c53 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java @@ -22,7 +22,7 @@ public class GraniteLobsterNPC extends Forager { /** * The fish. */ - private static final Item[] FISH = new Item[] { new Item(383), new Item(377) }; + private static final Item[] FISH = new Item[] { new Item(383), new Item(371) }; /** * Constructs a new {@code GraniteLobsterNPC} {@code Object}. @@ -61,7 +61,7 @@ public class GraniteLobsterNPC extends Forager { @Override public void handlePassiveAction() { - if (RandomFunction.random(4) == 1) { + if (RandomFunction.random(40) == 1) { final Item item = FISH[RandomFunction.random(FISH.length)]; animate(Animation.create(8107)); Fish fish = Fish.forItem(item); diff --git a/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java b/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java index 1cc985a30..04ba4c6bc 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java @@ -43,7 +43,7 @@ public class HydraNPC extends Familiar { Scenery scenery = (Scenery)node; FarmingPatch farmingPatch = FarmingPatch.forObject(scenery); if(farmingPatch != null) { - Patch patch = farmingPatch.getPatchFor(owner); + Patch patch = farmingPatch.getPatchFor(owner, true); patch.regrowIfTreeStump(); return true; } diff --git a/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java b/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java index 43fc3702a..7e0c82d73 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java @@ -40,7 +40,7 @@ public class IbisNPC extends Forager { * @param id The id. */ public IbisNPC(Player owner, int id) { - super(owner, id, 3800, 12531, 12, new Item(361), new Item(373)); + super(owner, id, 3800, 12531, 12, new Item(359), new Item(371)); boosts.add(new SkillBonus(Skills.FISHING, 3)); } @@ -54,7 +54,7 @@ public class IbisNPC extends Forager { @Override public boolean produceItem(Item item) { if (super.produceItem(item)) { - if (item.getId() == 373) { + if (item.getId() == 371) { owner.getSkills().addExperience(Skills.FISHING, 10); } return true; diff --git a/Server/src/main/content/global/skill/summoning/familiar/KalphiteNPC.java b/Server/src/main/content/global/skill/summoning/familiar/KalphiteNPC.java deleted file mode 100644 index 62b5020a0..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/KalphiteNPC.java +++ /dev/null @@ -1,117 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.plugin.Initializable; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.Metamorphosis; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; - -/** - * Handles the kalphite princess pet. - * @author Empathy - * - */ -@Initializable -public class KalphiteNPC extends Metamorphosis { - - /** - * The kalphite ids. - */ - private static final int[] KALPHITE_IDS = new int[] { 8602, 8603 }; - - /** - * Constructs a new {@code KalphiteNPC} object. - */ - public KalphiteNPC() { - super(KALPHITE_IDS); - } - - - @Override - public DialoguePlugin getDialoguePlugin() { - return new KalphitePrincessDialogue(); - } - - /** - * Handles the KalphitePrincess dialogue. - * @author Empathy - * - */ - public final class KalphitePrincessDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code KalphitePrincessDialogue} {@code Object}. - */ - public KalphitePrincessDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code KalphitePrincessDialogue} {@code Object}. - * - * @param player the player. - */ - public KalphitePrincessDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new KalphitePrincessDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is it with your kind and potato cactus?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Truthfully?"); - stage = 1; - break; - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yeah, please."); - stage = 2; - break; - case 2: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Soup. We make a fine soup with it."); - stage = 3; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Kalphites can cook?"); - stage = 4; - break; - case 4: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Nah, we just collect it and put it there because we", "know fools like yourself will come down looking for it", "then inevitably be killed by my mother."); - stage = 5; - break; - case 5: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Evidently not, that's how I got you!"); - stage = 6; - break; - case 6: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Touch�."); - stage = 7; - break; - case 7: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 8602, 8603 }; - } - } -} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java index 545ce6345..49a79fa6a 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java @@ -3,6 +3,7 @@ package content.global.skill.summoning.familiar; import java.util.List; import core.cache.def.impl.NPCDefinition; +import core.game.node.entity.combat.equipment.WeaponInterface; import core.plugin.Initializable; import core.game.interaction.OptionHandler; import core.game.node.Node; @@ -36,7 +37,7 @@ public class SmokeDevilNPC extends Familiar { * @param id The id. */ public SmokeDevilNPC(Player owner, int id) { - super(owner, id, 4800, 12085, 6); + super(owner, id, 4800, 12085, 6, WeaponInterface.STYLE_CAST); } @Override diff --git a/Server/src/main/content/global/skill/summoning/familiar/SnakelingNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SnakelingNPC.java deleted file mode 100644 index cd6372f62..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/SnakelingNPC.java +++ /dev/null @@ -1,114 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.plugin.Initializable; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.Metamorphosis; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; - -/** - * Handles the metamorphosis of the zulrah pet. - * @author Empathy - * - */ -@Initializable -public class SnakelingNPC extends Metamorphosis { - - /** - * The snakeling ids. - */ - public static final int[] SNAKELING_IDS = new int[] { 8626, 8627, 8628 }; - - /** - * - * Constructs a new {@code SnakelingNPC} object. - */ - public SnakelingNPC() { - super(SNAKELING_IDS); - } - - @Override - public DialoguePlugin getDialoguePlugin() { - return new PetSnakelingDialogue(); - } - - /** - * Handles the pet snakeling dialogue. - * @author Empathy - * - */ - public final class PetSnakelingDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code PetSnakelingDialogue} {@code Object}. - */ - public PetSnakelingDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code PetSnakelingDialogue} {@code Object}. - * - * @param player the player. - */ - public PetSnakelingDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new PetSnakelingDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - player("Hey little snake!"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - npc(FacialExpression.OLD_NORMAL, "Soon, Zulrah shall establish dominion over this plane."); - stage = 1; - break; - case 1: - player("Wanna play fetch?"); - stage = 2; - break; - case 2: - npc(FacialExpression.OLD_NORMAL, "Submit to the almighty Zulrah."); - stage = 3; - break; - case 3: - player("Walkies? Or slidies...?"); - stage = 4; - break; - case 4: - npc(FacialExpression.OLD_NORMAL, "Zulrah's wilderness as a God will soon be demonstrated."); - stage = 5; - break; - case 5: - player("I give up..."); - stage = 6; - break; - case 6: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return SNAKELING_IDS; - } - } - -} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java index 83f1d21ae..18d4946b2 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java @@ -56,7 +56,7 @@ public class SpiritCobraNPC extends Familiar { * @author Vexia */ public enum Egg { - COCKATRICE(new Item(1944), new Item(12109)), SARATRICE(new Item(10533), new Item(12113)), ZAMATRICE(new Item(10532), new Item(12115)), GUTHATRICE(new Item(10531), new Item(12111)), CORACATRICE(new Item(11964), new Item(12119)), PENGATRICE(new Item(12483), new Item(12117)), VULATRICE(new Item(11695), new Item(12121)); + COCKATRICE(new Item(1944), new Item(12109)), SARATRICE(new Item(5077), new Item(12113)), ZAMATRICE(new Item(5076), new Item(12115)), GUTHATRICE(new Item(5078), new Item(12111)), CORACATRICE(new Item(11964), new Item(12119)), PENGATRICE(new Item(12483), new Item(12117)), VULATRICE(new Item(11965), new Item(12121)); /** * The egg item. diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.java deleted file mode 100644 index 98721c62f..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.java +++ /dev/null @@ -1,81 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.TeleportManager.TeleportType; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.game.world.map.zone.impl.WildernessZone; - -/** - * Represents the spirit graahk's dialogue - * @author Splinter - * @version 1.0 - */ -@Initializable -public final class SpiritGraahkDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code GertrudesCatDialogue} {@code Object}. - */ - public SpiritGraahkDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code GertrudesCatDialogue} {@code Object}. - * @param player the player. - */ - public SpiritGraahkDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new SpiritGraahkDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - if (!(npc instanceof Familiar)) { - return false; - } - final Familiar fam = (Familiar) npc; - if (fam.getOwner() != player) { - player.getPacketDispatch().sendMessage("This is not your familiar."); - return true; - } else { - interpreter.sendOptions("Select an Option", "Chat", "Teleport"); - } - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (buttonId) { - case 1: - player.sendMessage("The Graahk does not feel like talking now."); - end(); - break; - case 2: - if (!WildernessZone.checkTeleport(player, 20)) { - player.sendMessage("You cannot teleport with the Graahk above level 20 wilderness."); - end(); - } else { - player.getTeleporter().send(new Location(2786, 3002), TeleportType.NORMAL); - end(); - } - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 7353, 7364 }; - } -} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.kt b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.kt new file mode 100644 index 000000000..4a0c23c9e --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.kt @@ -0,0 +1,115 @@ +package content.global.skill.summoning.familiar + +import core.api.openDialogue +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.map.zone.impl.WildernessZone +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +/** + * Represents the spirit graahk's dialogue + * @author Splinter & Bishop + * @version 2.0 + */ +@Initializable +class SpiritGraahkDialogue : DialoguePlugin { + constructor() + constructor(player: Player?) : super(player) + + override fun newInstance(player: Player?): DialoguePlugin { + return SpiritGraahkDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC? + if (npc !is Familiar) { + return false + } + val fam = npc as Familiar + if (fam.getOwner() !== player) { + player.packetDispatch.sendMessage("This is not your familiar.") + return true + } else { + interpreter.sendOptions("Select an Option", "Chat", "Teleport") + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (buttonId) { + 1 -> if (player.skills.getStaticLevel(Skills.SUMMONING) >= 67) { + openDialogue(player, SpiritGraahkDialogueFile(), npc) + } else { + player.sendMessage("The Graahk does not feel like talking now.") //This message is likely inauthentic, but I cannot source the correct one so I'm keeping the default here -Bishop + end() + } + + 2 -> if (!WildernessZone.checkTeleport(player, 20)) { + player.sendMessage("You cannot teleport with the Graahk above level 20 wilderness.") + end() + } else { + player.teleporter.send(Location(2786, 3002), TeleportType.NORMAL) + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SPIRIT_GRAAHK_7363, NPCs.SPIRIT_GRAAHK_7364) + } +} + +class SpiritGraahkDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + val spiritGraahkRandomConversation = RandomFunction.random(4) + when (spiritGraahkRandomConversation) { + 0 -> loadLabel(player, "spiky spikes") + 1 -> loadLabel(player, "pet the spikes") + 2 -> loadLabel(player, "therapeutic spikes") + 3 -> loadLabel(player, "inspect the spikes") + } + } + + label("spiky spikes") + player(ChatAnim.NEUTRAL, "Your spikes are looking particularly spiky today.") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Graaaaahk raaaawr?", "(Really, you think so?)") + player(ChatAnim.HAPPY, "Yes. Most pointy, indeed.") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Raaaawr...", "(That's really kind of you to say. I was going to spike", "you but I won't now...)") + player(ChatAnim.HAPPY, "Thanks?") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "...Grrrrr ark.", "(...I'll do it later instead.)") + player(ChatAnim.HAPPY, "*Sigh!*") + + label("pet the spikes") + npc(ChatAnim.GHRAAK_SHAKE_MILD, "Graahk grrrrowl?", "(My spikes hurt, could you pet them for me?)") + player(ChatAnim.HAPPY, "Aww, of course I can I'll just... Oww! I think you drew", "blood that time.") + + label("therapeutic spikes") + npc(ChatAnim.GHRAAK_SHAKE_MILD, "Graahk!", "(Hi!)") //? + player(ChatAnim.SUSPICIOUS, "Hello. Are you going to spike me again?") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Grar rawr howl!", "(No, I got a present to apologise for last time.)") + player(ChatAnim.HAPPY, "That's really sweet, thank you.") + npc(ChatAnim.GRAAHK_NOD, "Howl graaahk rawr.", "(Here you go, it's a special cushion to make you", "comfortable.)") + player(ChatAnim.ANGRY, "It's made of spikes!") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Howl graaahk rawr.", "(Yes, but they're therapeutic spikes.)") + player(ChatAnim.ANGRY, "...") + + label("inspect the spikes") + player(ChatAnim.HAPPY, "How's your day going?") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Graaahk. Grak grak!", "(It's great! Actually I've got something to show you!)") + player(ChatAnim.HALF_ASKING, "Oh? What's that?") + npc(ChatAnim.GRAAHK_NOD, "Grrrrrk hiss graaaaa!", "(You'll need to get closer!)") + player(ChatAnim.HALF_ASKING, "I can't see anything...") + npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Grah grr aaaaahk grahk.", "(It's really small - even closer.)") + player(ChatAnim.ANGRY, "Oww! I'm going to have your spikes trimmed!") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.java deleted file mode 100644 index dd6b48975..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.java +++ /dev/null @@ -1,52 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.game.node.entity.skill.SkillBonus; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.combat.equipment.WeaponInterface; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the Spirit Graahk familiar. - * @author Aero - */ -@Initializable -public class SpiritGraahkNPC extends Familiar { - - /** - * Constructs a new {@code SpiritGraahkNPC} {@code Object}. - */ - public SpiritGraahkNPC() { - this(null, 7363); - } - - /** - * Constructs a new {@code SpiritGraahkNPC} {@code Object}. - * @param owner The owner. - * @param id The id. - */ - public SpiritGraahkNPC(Player owner, int id) { - super(owner, id, 4900, 12810, 3, WeaponInterface.STYLE_AGGRESSIVE); - boosts.add(new SkillBonus(Skills.HUNTER, 5)); - } - - @Override - public Familiar construct(Player owner, int id) { - return new SpiritGraahkNPC(owner, id); - } - - @Override - protected boolean specialMove(FamiliarSpecial special) { - if (!super.isOwnerAttackable()) { - return false; - } - call(); - return true; - } - - @Override - public int[] getIds() { - return new int[] { 7363, 7364 }; - } - -} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.kt b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.kt new file mode 100644 index 000000000..af84870d7 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.kt @@ -0,0 +1,51 @@ +package content.global.skill.summoning.familiar + +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.skill.SkillBonus +import core.game.node.entity.skill.Skills +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Spirit Graahk familiar. + * @author Aero & Bishop + */ +@Initializable +class SpiritGraahkNPC @JvmOverloads constructor(owner: Player? = null, id: Int = NPCs.SPIRIT_GRAAHK_7363) : + Familiar(owner, id, 4900, Items.SPIRIT_GRAAHK_POUCH_12810, 3, WeaponInterface.STYLE_AGGRESSIVE) { + + init { + boosts.add(SkillBonus(Skills.HUNTER, 5.0)) + } + + override fun construct(owner: Player?, id: Int): Familiar { + return SpiritGraahkNPC(owner, id) + } + + override fun specialMove(special: FamiliarSpecial): Boolean { + val target: Entity = special.target ?: return false + if (!canCombatSpecial(target)) { + return false + } + properties.combatPulse.attack(target) + return true + } + + override fun visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1316)) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SPIRIT_GRAAHK_7363, NPCs.SPIRIT_GRAAHK_7364) + } + + override fun getText(): String { + return if (RandomFunction.random(2) == 0) "Howl!" else "Rowr!" + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.java deleted file mode 100644 index 44c4678a9..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.java +++ /dev/null @@ -1,29 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.cache.def.impl.NPCDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to handle the spirit graahk familiar - * @author Splinter - */ -@Initializable -public final class SpiritGraahkOptionPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - NPCDefinition.forId(7363).getHandlers().put("option:interact", this); - return this; - } - - @Override - public boolean handle(final Player player, Node node, String option) { - player.getDialogueInterpreter().open(7353, node.asNpc()); - return true; - } - -} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.kt b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.kt new file mode 100644 index 000000000..d3b3b1e97 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.kt @@ -0,0 +1,27 @@ +package content.global.skill.summoning.familiar + +import core.cache.def.impl.NPCDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.NPCs; + +/** + * Represents the plugin used to handle the spirit graahk familiar + * @author Splinter + */ +@Initializable +class SpiritGraahkOptionPlugin : OptionHandler() { + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + NPCDefinition.forId(NPCs.SPIRIT_GRAAHK_7363).getHandlers()["option:interact"] = this + return this + } + + override fun handle(player: Player, node: Node, option: String?): Boolean { + player.dialogueInterpreter.open(NPCs.SPIRIT_GRAAHK_7364, node.asNpc()) + return true + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java index 3768df594..09a83505c 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java @@ -44,30 +44,31 @@ public class SpiritKalphiteNPC extends BurdenBeast { @Override protected boolean specialMove(FamiliarSpecial special) { - if (!isOwnerAttackable()) { - return false; - } - final List entitys = RegionManager.getLocalEntitys(owner, 6); - visualize(Animation.create(8517), Graphics.create(1350)); - GameWorld.getPulser().submit(new Pulse(1, owner) { - @Override - public boolean pulse() { - int count = 0; - for (Entity entity : entitys) { - if (count > 5) { - return true; - } - if (!canCombatSpecial(entity)) { - continue; - } - Projectile.magic(SpiritKalphiteNPC.this, entity, 1349, 40, 36, 50, 5).send(); - sendFamiliarHit(entity, 20); - count++; - } - return true; - } - }); - return false; + return false; ///bodge this for now, until someone fixes this abomination. +// if (!isOwnerAttackable()) { +// return false; +// } +// final List entitys = RegionManager.getLocalEntitys(owner, 6); +// visualize(Animation.create(8517), Graphics.create(1350)); +// GameWorld.getPulser().submit(new Pulse(1, owner) { +// @Override +// public boolean pulse() { +// int count = 0; +// for (Entity entity : entitys) { +// if (count > 5) { +// return true; +// } +// if (!canCombatSpecial(entity)) { +// continue; +// } +// Projectile.magic(SpiritKalphiteNPC.this, entity, 1349, 40, 36, 50, 5).send(); +// sendFamiliarHit(entity, 20); +// count++; +// } +// return true; +// } +// }); +// return false; } @Override diff --git a/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java index 8f6a407d8..ee216033e 100644 --- a/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java +++ b/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java @@ -9,6 +9,7 @@ import core.game.node.item.Item; import core.game.world.map.zone.ZoneBorders; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Handles summoning a familiar. @@ -26,7 +27,7 @@ public final class SummonFamiliarPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { Item item = (Item) node; - if (!player.getQuestRepository().isComplete("Wolf Whistle") && player.getAttribute("in-cutscene", null) == null) { + if (!player.getQuestRepository().isComplete(Quests.WOLF_WHISTLE) && player.getAttribute("in-cutscene", null) == null) { player.getPacketDispatch().sendMessage("You have to complete Wolf Whistle before you can summon a familiar."); return true; } diff --git a/Server/src/main/content/global/skill/summoning/familiar/VetionNPC.java b/Server/src/main/content/global/skill/summoning/familiar/VetionNPC.java deleted file mode 100644 index f939260f2..000000000 --- a/Server/src/main/content/global/skill/summoning/familiar/VetionNPC.java +++ /dev/null @@ -1,33 +0,0 @@ -package content.global.skill.summoning.familiar; - -import core.plugin.Initializable; -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.npc.Metamorphosis; - -/** - * Handles the metamorphosis of Vet'ion Jr. - * @author Empathy - * - */ -@Initializable -public class VetionNPC extends Metamorphosis { - - /** - * The Vet'ion Ids. - */ - public static final int[] VETION_IDS = new int[] { 8600, 8654 }; - - /** - * - * Constructs a new{@code VetionNPC} object. - */ - public VetionNPC() { - super(VETION_IDS); - } - - @Override - public DialoguePlugin getDialoguePlugin() { - return null; - } - -} diff --git a/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt b/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt index 79ef7c12d..4b9969574 100644 --- a/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt +++ b/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt @@ -1,11 +1,8 @@ package content.global.skill.summoning.pet import core.api.* -import core.cache.def.impl.SceneryDefinition import core.game.node.Node import core.game.node.entity.player.Player -import core.game.node.entity.skill.Skills -import core.game.node.item.GroundItemManager import core.game.interaction.* import core.tools.StringUtils @@ -69,8 +66,9 @@ class IncubatorHandler : InteractionListener { val product = egg.product val name = product.name.lowercase() - sendMessage(player, "You take your $name out of the incubator.") - addItem(player, product.id) + if (addItem(player, product.id)) { + sendMessage(player, "You take your $name out of the incubator.") + } return true } } diff --git a/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt b/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt index 6395a79eb..899deee2a 100644 --- a/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt +++ b/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt @@ -42,6 +42,13 @@ class IncubatorTimer : PersistTimer (500, "incubation") { root["eggs"] = arr } + override fun onRegister(entity: Entity) { + if (entity !is Player) return + for ((region, _) in incubatingEggs) { + setVarbit(entity.asPlayer(), varbitForRegion(region), 1, true) + } + } + override fun run (entity: Entity) : Boolean { if (entity !is Player) return false for ((_, egg) in incubatingEggs) { @@ -60,14 +67,14 @@ class IncubatorTimer : PersistTimer (500, "incubation") { } companion object { - val TAVERLY_REGION = 11573 - val TAVERLY_VARBIT = 4277 + val TAVERLEY_REGION = 11573 + val TAVERLEY_VARBIT = 4277 val YANILLE_REGION = 10288 val YANILLE_VARBIT = 4221 fun varbitForRegion (region: Int) : Int { return when (region) { - TAVERLY_REGION -> TAVERLY_VARBIT + TAVERLEY_REGION -> TAVERLEY_VARBIT YANILLE_REGION -> YANILLE_VARBIT else -> -1 } diff --git a/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java b/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java index ebeb5b477..24a387d18 100644 --- a/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java +++ b/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java @@ -67,7 +67,7 @@ public final class KittenInteractDialogue extends DialoguePlugin { interpreter.sendDialogues(player, null, "That cat sure loves to be stroked."); stage = 99; break; - case 2:// chase-vermine + case 2:// chase-vermin end(); player.sendChat("Go on puss...kill that rat!"); boolean cant = true; @@ -117,8 +117,8 @@ public final class KittenInteractDialogue extends DialoguePlugin { player.sendChat("Shoo cat!"); Pet currentPet = (Pet) player.getFamiliarManager().getFamiliar(); player.getFamiliarManager().getFamiliar().sendChat("Miaow!"); - player.getFamiliarManager().removeDetails(currentPet.getItemIdHash()); player.getFamiliarManager().getFamiliar().dismiss(); + player.getFamiliarManager().removeDetails(currentPet.getItemId()); player.getPacketDispatch().sendMessage("The cat has run away."); } end(); diff --git a/Server/src/main/content/global/skill/summoning/pet/Pet.java b/Server/src/main/content/global/skill/summoning/pet/Pet.java index e4812dac1..a115040d1 100644 --- a/Server/src/main/content/global/skill/summoning/pet/Pet.java +++ b/Server/src/main/content/global/skill/summoning/pet/Pet.java @@ -5,7 +5,6 @@ import content.global.skill.summoning.familiar.Familiar; import content.global.skill.summoning.familiar.FamiliarSpecial; import core.game.node.entity.player.Player; import core.game.node.item.Item; -import core.game.world.GameWorld; import static core.api.ContentAPIKt.*; @@ -30,7 +29,7 @@ public final class Pet extends Familiar { /** * The growth rate of the pet. */ - private double growthRate; + private final double growthRate; /** * The pets type. @@ -67,10 +66,13 @@ public final class Pet extends Familiar { @Override public void handleTickActions() { final PetDetails petDetails = details; - if (getPet().getFood().length > 0) { + if (getPet().getFood().length > 0 && !pet.isGrownCat(itemId)) { if(!SkillcapePerks.isActive(SkillcapePerks.PET_MASTERY, owner)) { double amount = itemId == pet.getBabyItemId() ? 0.025 : 0.018; - if (GameWorld.getSettings().isDevMode()) { + if (owner.getAttribute("petrate",1) == 0) { + amount = 0 ; + } + else if (owner.getAttribute("petrate",1) == 2) { amount *= 100; } petDetails.updateHunger(amount); @@ -86,8 +88,8 @@ public final class Pet extends Familiar { hasWarned = 2; } if (hunger >= 100.0 && growthRate != 0 && pet.getFood().length != 0) { - owner.getFamiliarManager().removeDetails(this.getItemIdHash()); owner.getFamiliarManager().dismiss(); + owner.getFamiliarManager().removeDetails(getItemId()); owner.getFamiliarManager().setFamiliar(null); setVarp(owner, 1175, 0); owner.sendMessage("Your pet has run away."); @@ -96,7 +98,10 @@ public final class Pet extends Familiar { double growth = petDetails.getGrowth(); double growthrate = pet.getGrowthRate(); if (growthrate > 0.000) { - if (GameWorld.getSettings().isDevMode()) { + if (owner.getAttribute("petrate",1) == 0) { + growthrate = 0; + } + else if (owner.getAttribute("petrate",1) == 2) { growthrate *= 100; } petDetails.updateGrowth(growthrate); @@ -126,16 +131,13 @@ public final class Pet extends Familiar { // then this pet is already overgrown return; } - owner.getFamiliarManager().removeDetails(this.getItemIdHash()); - owner.getFamiliarManager().dismiss(); + if (pet.isKitten(itemId)) { + owner.incrementAttribute("/save:stats_manager:cats_raised"); + } + owner.getFamiliarManager().addDetails(newItemId, details); + owner.getFamiliarManager().removeDetails(getItemId()); + owner.getFamiliarManager().morphPet(new Item(newItemId), false, location, details.getHunger(), 0); owner.getPacketDispatch().sendMessage("Your pet has grown larger."); - int npcId = pet.getNpcId(newItemId); - details.updateGrowth(-100.0); - Pet newPet = new Pet(owner, details, newItemId, npcId); - newPet.growthRate = growthRate; - newPet.hasWarned = hasWarned; - owner.getFamiliarManager().setFamiliar(newPet); - owner.getFamiliarManager().spawnFamiliar(); } @Override @@ -161,16 +163,6 @@ public final class Pet extends Familiar { return itemId; } - /** - * Gets the itemId with the individual hashed in. - * @return The itemIdHash. - */ - public int getItemIdHash() { - Item item = new Item(itemId); - item.setCharge(details.getIndividual()); - return item.getIdHash(); - } - /** * Gets the details. * @return The details. @@ -187,9 +179,36 @@ public final class Pet extends Familiar { return pet; } + /** + * Gets the hunger level. + */ + public double getHunger() { + return details.getHunger(); + } + + /** + * Gets the growth level. + */ + public double getGrowth() { + return details.getGrowth(); + } + + /** + * Gets the hunger warning level. + */ + public int getHasWarned() { + return hasWarned; + } + + /** + * Sets the hunger warning level. + */ + public void setHasWarned(int value) { + this.hasWarned = value; + } + @Override public int[] getIds() { return new int[] { 761, 762, 763, 764, 765, 766, 3505, 3598, 6969, 7259, 7260, 6964, 7249, 7251, 6960, 7241, 7243, 6962, 7245, 7247, 6966, 7253, 7255, 6958, 7237, 7239, 6915, 7277, 7278, 7279, 7280, 7018, 7019, 7020, 6908, 7313, 7316, 6947, 7293, 7295, 7297, 7299, 6911, 7261, 7263, 7265, 7267, 7269, 6919, 7301, 7303, 7305, 7307, 6949, 6952, 6955, 6913, 7271, 7273, 6945, 7319, 7321, 7323, 7325, 7327, 6922, 6942, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 6900, 6902, 6904, 6906, 768, 769, 770, 771, 772, 773, 3504, 6968, 7257, 7258, 6965, 7250, 7252, 6961, 7242, 7244, 6963, 7246, 7248, 6967, 7254, 7256, 6859, 7238, 7240, 6916, 7281, 7282, 7283, 7284, 7015, 7016, 7017, 6909, 7314, 7317, 6948, 7294, 7296, 7298, 7300, 6912, 7262, 7264, 7266, 7268, 7270, 6920, 7302, 7304, 7306, 7308, 6950, 6953, 6956, 6914, 7272, 7274, 6946, 7320, 7322, 7324, 7326, 7328, 6923, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 6901, 6903, 6905, 6907, 774, 775, 776, 777, 778, 779, 3503, 6951, 6954, 6957 }; } - } diff --git a/Server/src/main/content/global/skill/summoning/pet/PetDetails.java b/Server/src/main/content/global/skill/summoning/pet/PetDetails.java index b3e01c869..b3b0b8f05 100644 --- a/Server/src/main/content/global/skill/summoning/pet/PetDetails.java +++ b/Server/src/main/content/global/skill/summoning/pet/PetDetails.java @@ -19,11 +19,6 @@ public final class PetDetails { */ private double growth = 0.0; - /** - * The individual, an in principle arbitrary integer read off of the item's charge slot. - */ - private int individual; - /** * Constructs a new {@code PetDetails} {@code Object}. * @param growth The growth value. @@ -64,6 +59,13 @@ public final class PetDetails { return hunger; } + /** + * Sets the hunger. (You probably want to use updateHunger() instead.) + */ + public void setHunger(double value) { + this.hunger = value; + } + /** * Gets the growth. * @return The growth. @@ -73,18 +75,9 @@ public final class PetDetails { } /** - * Sets the individual. - * @param individual The individual to set. + * Sets the growth. (You probably want to use updateGrowth() instead.) */ - public void setIndividual(int individual) { - this.individual = individual; - } - - /** - * Gets the individual. - * @return The individual. - */ - public int getIndividual() { - return individual; + public void setGrowth(double value) { + this.growth = value; } } diff --git a/Server/src/main/content/global/skill/summoning/pet/Pets.java b/Server/src/main/content/global/skill/summoning/pet/Pets.java index 843075d28..3258099fc 100644 --- a/Server/src/main/content/global/skill/summoning/pet/Pets.java +++ b/Server/src/main/content/global/skill/summoning/pet/Pets.java @@ -18,23 +18,13 @@ public enum Pets { /** * A cat/kitten pet. */ - CAT(1555, 1561, 1567, 761, 768, 774, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_1(1556, 1562, 1568, 762, 769, 775, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_2(1557, 1563, 1569, 763, 770, 776, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_3(1558, 1564, 1570, 764, 771, 777, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_4(1559, 1565, 1571, 765, 772, 778, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_5(1560, 1566, 1572, 766, 773, 779, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), HELLCAT(7583, 7582, 7581, 3505, 3504, 3503, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_7(14089, 14090, 15092, 8217, 8214, 8216, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), + CAT(1555, 1561, 1567, 761, 768, 774, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_1(1556, 1562, 1568, 762, 769, 775, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_2(1557, 1563, 1569, 763, 770, 776, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_3(1558, 1564, 1570, 764, 771, 777, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_4(1559, 1565, 1571, 765, 772, 778, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_5(1560, 1566, 1572, 766, 773, 779, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), HELLCAT(7583, 7582, 7581, 3505, 3504, 3503, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_6(14089, 14090, 15092, 8217, 8214, 8216, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), /** * A clockwork cat. */ CLOCKWORK_CAT(7771, 7772, -1, 3598, -1, -1, 0.0, 0), - /** - * The firemaker's curse pets. - */ - SEARING_FLAME(22994, -1, -1, 14769, -1, -1, 0.0, 0), GLOWING_EMBER(22993, -1, -1, 14768, -1, -1, 0.0, 0), TWISTED_FIRESTARTER(22995, -1, -1, 14770, -1, -1, 0.0, 0), WARMING_FLAME(22992, -1, -1, 14767, -1, -1, 0.0, 0), - - /** - * Troll baby pet. - */ - TROLL_BABY(23030, 23030, -1, 14846, -1, -1, 0.0, 0), - /** * A bulldog pet. */ @@ -63,37 +53,7 @@ public enum Pets { /** * A terrier pet. */ - TERRIER(12512, 12513, -1, 6958, 6859, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_1(12700, 12701, -1, 7237, 7238, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_2(12702, 12703, -1, 7239, 7240, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), - - /** - * A creeping hand pet. - */ - //CREEPING_HAND(14652, -1, -1, 8619, -1, -1, 0.0033333333333333, 4, 1059), - - /** - * Minitrice pet. - */ - //MINITRICE(14653, -1, -1, 8620, -1, -1, 0.0033333333333333, 4, 225), - - /** - * Baby basilisk pet. - */ - //BABY_BASILISK(14654, -1, -1, 8621, -1, -1, 0.0033333333333333, 4, 221), - - /** - * Baby kurask pet. - */ - //BABY_KURASK(14655, -1, -1, 8622, -1, -1, 0.0033333333333333, 4, 526), - - /** - * Abyssal minion pet. - */ - //ABYSSAL_MINION(14651, -1, -1, 8624, -1, -1, 0.0033333333333333, 4, 592), - - /** - * Rune guardian pets. - */ - RUNE_GUARDIAN(15626, -1, -1, 9656, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_1(15627, -1, -1, 9657, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_2(15628, -1, -1, 9658, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_3(15629, -1, -1, 9659, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_4(15630, -1, -1, 9660, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_5(15631, -1, -1, 9661, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_6(15632, -1, -1, 9662, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_7(15633, -1, -1, 9663, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_8(15634, -1, -1, 9664, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_9(15635, -1, -1, 9665, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_10(15636, -1, -1, 9666, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_11(15637, -1, -1, 9667, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_12(15638, -1, -1, 9668, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_13(15639, -1, -1, 9669, -1, -1, 0.0033333333333333, 4), + TERRIER(12512, 12513, -1, 6958, 6959, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_1(12700, 12701, -1, 7237, 7238, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_2(12702, 12703, -1, 7239, 7240, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), /** * Gecko pet. @@ -115,11 +75,6 @@ public enum Pets { */ PENGUIN(12481, 12482, -1, 6908, 6909, -1, 0.0046296296296296, 30, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), PENGUIN_1(12763, 12762, -1, 7313, 7314, -1, 0.0046296296296296, 30, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), PENGUIN_2(12765, 12764, -1, 7316, 7317, -1, 0.0046296296296296, 30, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), - /** - * A tooth creature pet. - */ - TOOTH_CREATURE(18671, 18669, -1, 11411, 11413, -1, 0.075757575757576, 37, 1927, 1977), - /** * A giant crab pet. */ @@ -155,11 +110,6 @@ public enum Pets { */ RACCOON(12486, 12487, -1, 6913, 6914, -1, 0.0029444444444444, 80, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 2132, 2134, 2136, 2138, 10816, 9986, 9978), RACCOON_1(12734, 12735, -1, 7271, 7272, -1, 0.0029444444444444, 80, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 2132, 2134, 2136, 2138, 10816, 9986, 9978), RACCOON_2(12736, 12737, -1, 7273, 7274, -1, 0.0029444444444444, 80, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 2132, 2134, 2136, 2138, 10816, 9986, 9978), - /** - * A sneaker peeper pet. - */ - SNEAKER_PEEPER(19894, 19895, -1, 13089, 13090, -1, 0.05, 80, 221), - /** * A vulture pet. */ @@ -180,61 +130,6 @@ public enum Pets { */ BABY_DRAGON(12469, 12470, -1, 6900, 6901, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_1(12471, 12472, -1, 6902, 6903, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_2(12473, 12474, -1, 6904, 6905, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_3(12475, 12476, -1, 6906, 6907, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270); - -// /** -// * Emperor's pets (that's right, MY pet"S"). -// */ -// GIANT_WOLPERTINGER(8888, -1, -1, 6990, -1, -1, 0.0, 99), DRAKAN(8889, -1, -1, 4794, -1, -1, 0.0, 99), DILL(8890, -1, -1, 7770, -1, -1, 0.0, 99), - -// /** -// * Vexias pet. -// */ -// IMP(9952, -1, -1, 1531, -1, -1, 0.0, 99), BIG_GUY(9951, -1, -1, 3101, -1, -1, 0.0, 99), LITTLE_GUY(8887, -1, -1, 5805, -1, -1, 0.0, 99), -// -// /** -// * Godwars boss pets. -// */ -// KRIL_JR(14648, -1, -1, 8591, -1, -1, 0.0, 1), KREE_JR(14645, -1, -1, 8592, -1, -1, 0.0, 1), ZILYANA_JR(14647, -1, -1, 8593, -1, -1, 0.0, 1), GRAARDOOR_JR(14646, -1, -1, 8594, -1, -1, 0.0, 1), -// -// /** -// * Classic boss pets. -// */ -// CHAOS_ELE_JR(14638, -1, -1, 8595, -1, -1, 0.0, 1), PRINCE_BLACK_DRAGON(14649, -1, -1, 8596, -1, -1, 0.0, 1), BABY_MOLE(14642, -1, -1, 8601, -1, -1, 0.0, 1), KQ_FORM_1(14643, -1, -1, 8602, -1, -1, 0.0, 1), KQ_FORM_2(14650, -1, -1, 8603, -1, -1, 0.0, 1), DARK_CORE(14653, -1, -1, 8630, -1, -1, 0.0, 1), -// -// /** -// * The boss pets for the Dagannoths -// */ -// DAGANNOTH_SUPREME(14639, -1, -1, 8605, -1, -1, 0.0, 1), DAGANNOTH_PRIME(14640, -1, -1, 8606, -1, -1, 0.0, 1), DAGANNOTH_REX(14641, -1, -1, 8607, -1, -1, 0.0, 1), -// /** -// * The new OSRS bosses. -// */ -// CALLISTO_CUB(14658, -1, -1, 8597, -1, -1, 0.0, 1), -// SCORPIA_JR(14661, -1, -1, 8598, -1, -1, 0.0, 1), -// VENENATIS_JR(14657, -1, -1, 8654, -1, -1, 0.0, 1), -// VETION_JR(14659, -1, -1, 8600, -1, -1, 0.0, 1), -// VETION_JR_2(14660, -1, -1, 8654, -1, -1, 0.0, 1), -// RELEASE_THE_KRAKEN(14651, -1, -1, 8608, -1, -1, 0.0, 1), -// SMOKE_DEVIL(14644, -1, -1, 8609, -1, -1, 0.0, 1), -// SNAKELING_YELLOW(14654, -1, -1, 8626, -1, -1, 0.0, 1), -// SNAKELING_ORANGE(14655, -1, -1, 8627, -1, -1, 0.0, 1), -// SNAKELING_PURPLE(14656, -1, -1, 8628, -1, -1, 0.0, 1), -// /** -// * The boss pet representing the likeness of the Penance Queen -// */ -// DRAMA_QUEEN(14652, -1, -1, 8604, -1, -1, 0.0, 1), -// /** -// * The skilling pets -// */ -// BEAVER(14821, -1, -1, 8635, -1, -1, 0.0, 1), -// ROCK_GOLEM(14822, -1, -1, 8637, -1, -1, 0.0, 1), -// BABY_RED_CHINCHOMPA(14823, -1, -1, 8643, -1, -1, 0.0, 1), -// BABY_GREY_CHINCHOMPA(14824, -1, -1, 8644, -1, -1, 0.0, 1), -// BABY_BLACK_CHINCHOMPA(14825, -1, -1, 8657, -1, -1, 0.0, 1), -// BABY_GOLD_CHINCHOMPA(14826, -1, -1, 8658, -1, -1, 0.0, 1), -// HERON(14827, -1, -1, 8647, -1, -1, 0.0, 1), -// TZREK_JAD(14828, -1, -1, 8650, -1, -1, 0.0, 1); - - /** * The baby pets mapping. */ @@ -481,4 +376,44 @@ public enum Pets { } return -1; } -} \ No newline at end of file + + /** + * Checks if this pet is a kitten + * @return a boolean, true if the pet is a kitten + */ + public boolean isKitten(int id) { + switch (this) { + case CAT: + case CAT_1: + case CAT_2: + case CAT_3: + case CAT_4: + case CAT_5: + case CAT_6: + case HELLCAT: + return id == babyItemId; + default: + return false; + } + } + + /** + * Checks if this pet is a grown cat + * @return a boolean, true if the pet is a grown cat + */ + public boolean isGrownCat(int id) { + switch (this) { + case CAT: + case CAT_1: + case CAT_2: + case CAT_3: + case CAT_4: + case CAT_5: + case CAT_6: + case HELLCAT: + return id == grownItemId || id == overgrownItemId; + default: + return false; + } + } +} diff --git a/Server/src/main/content/global/skill/thieving/Pickpockets.kt b/Server/src/main/content/global/skill/thieving/Pickpockets.kt index d5e30efd1..4580f2518 100644 --- a/Server/src/main/content/global/skill/thieving/Pickpockets.kt +++ b/Server/src/main/content/global/skill/thieving/Pickpockets.kt @@ -10,7 +10,7 @@ import core.api.utils.WeightedItem import java.util.stream.IntStream enum class Pickpockets(val ids: IntArray, val requiredLevel: Int, val low: Double, val high: Double, val experience: Double, val stunDamageMin: Int, val stunDamageMax: Int, val stunTime: Int, val table: WeightBasedTable) { - MAN(intArrayOf(1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 3224, 3915, 3226, 3227, 5924, 5923), 1, 180.0, 240.0, 8.0, 1, 1,5, WeightBasedTable.create( + MAN(intArrayOf(1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2683, 2684, 3224, 3915, 3226, 3227, 5924, 5923), 1, 180.0, 240.0, 8.0, 1, 1,5, WeightBasedTable.create( WeightedItem(Items.COINS_995,3,3,1.0,true) )), FARMER(intArrayOf(7, 1757, 1758), 10, 180.0, 240.0, 14.5, 1,1,5, WeightBasedTable.create( diff --git a/Server/src/main/content/global/skill/thieving/Stall.java b/Server/src/main/content/global/skill/thieving/Stall.java index efc8ed56c..59498da4a 100644 --- a/Server/src/main/content/global/skill/thieving/Stall.java +++ b/Server/src/main/content/global/skill/thieving/Stall.java @@ -19,7 +19,7 @@ public enum Stall { CRAFTING_STALL(new Integer[]{4874, 6166}, new Integer[] { 4797, 6984 }, 5, new Item[]{new Item(1592, 1), new Item(1597, 1), new Item(1755, 1)}, 16, 12,"crafting supplies"), TEA_STALL(new Integer[]{635, 6574}, new Integer[] { 634, 6573 }, 5, new Item[]{new Item(712, 1)}, 16, 12,"tea"), SILK_STALL(new Integer[]{34383, 2560}, new Integer[] { 34381, 634 }, 20, new Item[]{new Item(950, 1)}, 24, 13,"silk"), - WINE_STALL(new Integer[]{2046}, new Integer[] { 634 }, 22, new Item[]{new Item(1935, 1), new Item(1937, 1), new Item(1993, 1), new Item(7919, 1)}, 27, 27,"wine"), //OBJECT MISSING IN CACHE + WINE_STALL(new Integer[]{14011}, new Integer[] { 634 }, 22, new Item[]{new Item(1935, 1), new Item(1937, 1), new Item(1993, 1), new Item(7919, 1)}, 27, 27,"wine"), MARKET_SEED_STALL(new Integer[]{7053}, new Integer[] { 634 }, 27, new Item[]{new Item(5096, 1), new Item(5097, 1), new Item(5101, 1), new Item(5318, 1), new Item(5319, 1), new Item(5324, 1)}, 10, 19,"seeds"), FUR_STALL(new Integer[]{ 34387, 2563, 4278}, new Integer[] { 34381, 634, 634 }, 35, new Item[]{new Item(6814, 1), new Item(958, 1)}, 36, 25,"fur"), FISH_STALL(new Integer[]{ 4277, 4705, 4707 }, new Integer[] { 634, 634, 634 }, 42, new Item[]{new Item(331, 1), new Item(359, 1), new Item(377, 1)}, 42, 27,"fish"), diff --git a/Server/src/main/content/global/skill/thieving/StallThiefPulse.java b/Server/src/main/content/global/skill/thieving/StallThiefPulse.java index 280f2cdcb..b08185335 100644 --- a/Server/src/main/content/global/skill/thieving/StallThiefPulse.java +++ b/Server/src/main/content/global/skill/thieving/StallThiefPulse.java @@ -10,14 +10,13 @@ import core.game.node.item.Item; import core.game.node.scenery.Scenery; import core.game.node.scenery.SceneryBuilder; import core.game.world.GameWorld; -import core.game.world.map.Direction; -import core.game.world.map.Location; import core.game.world.map.RegionManager; import core.game.world.update.flag.context.Animation; import core.tools.RandomFunction; import core.tools.StringUtils; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents the pulse used to thieve a stall. @@ -74,12 +73,12 @@ public final class StallThiefPulse extends SkillPulse { player.getPacketDispatch().sendMessage("You don't have enough inventory space."); return false; } - if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, "Fremennik Trials") && stall.full_ids.contains(4278)) { + if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && stall.full_ids.contains(4278)) { sendDialogue(player, "The fur trader is staring at you suspiciously. You cannot steal from his stall while he distrusts you."); return false; } - if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, "Fremennik Trials") && stall.full_ids.contains(4277)) { + if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && stall.full_ids.contains(4277)) { sendDialogue(player, "The fishmonger is staring at you suspiciously. You cannot steal from his stall while he distrusts you."); return false; } diff --git a/Server/src/main/content/global/skill/thieving/ThievingListeners.kt b/Server/src/main/content/global/skill/thieving/ThievingListeners.kt index d6123fcda..ef687a850 100644 --- a/Server/src/main/content/global/skill/thieving/ThievingListeners.kt +++ b/Server/src/main/content/global/skill/thieving/ThievingListeners.kt @@ -14,6 +14,7 @@ import core.game.interaction.IntType import core.game.node.entity.player.Player import core.game.node.item.Item import org.rs09.consts.Sounds +import content.global.activity.ttrail.TreasureTrailManager class ThievingListeners : InteractionListener { @@ -66,7 +67,12 @@ class ThievingListeners : InteractionListener { } player.animator.animate(PICKPOCKET_ANIM) - val lootTable = pickpocketRoll(player, pickpocketData.low, pickpocketData.high, pickpocketData.table) + val effectiveTable = if (TreasureTrailManager.getInstance(player).hasClue()) { + pickpocketData.table.excluding(*WeightBasedTable.CLUE_SCROLL_SLOTS) + } else { + pickpocketData.table + } + val lootTable = pickpocketRoll(player, pickpocketData.low, pickpocketData.high, effectiveTable) if(lootTable == null){ node.asNpc().face(player) node.asNpc().animator.animate(NPC_ANIM) diff --git a/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java b/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java index 3af68e890..67f0cbaa0 100644 --- a/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java +++ b/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java @@ -1,6 +1,6 @@ package content.global.travel.glider; -import content.region.kandarin.quest.grandtree.TheGrandTree; +import content.data.Quests; import core.game.component.Component; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; @@ -58,7 +58,7 @@ public final class CaptainDalburDialogue extends DialoguePlugin { stage = 1; break; case 1: - if(!isQuestComplete(player, TheGrandTree.questName)){ + if(!isQuestComplete(player, Quests.THE_GRAND_TREE)){ interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "I only fly friends of the gnomes!"); stage = END_DIALOGUE; } diff --git a/Server/src/main/content/global/travel/glider/GliderPlugin.java b/Server/src/main/content/global/travel/glider/GliderPlugin.java index c62e404d9..b3cbe634c 100644 --- a/Server/src/main/content/global/travel/glider/GliderPlugin.java +++ b/Server/src/main/content/global/travel/glider/GliderPlugin.java @@ -1,6 +1,6 @@ package content.global.travel.glider; -import content.region.kandarin.quest.grandtree.TheGrandTree; +import content.data.Quests; import core.api.ContentAPIKt; import core.cache.def.impl.NPCDefinition; import core.game.component.Component; @@ -31,7 +31,7 @@ public final class GliderPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - if(isQuestComplete(player, TheGrandTree.questName)){ + if(isQuestComplete(player, Quests.THE_GRAND_TREE)){ player.getInterfaceManager().open(new Component(138)); Gliders.sendConfig(node.asNpc(), player); } else { diff --git a/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java b/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java index f7782c200..41b226d36 100644 --- a/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java +++ b/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java @@ -11,6 +11,7 @@ import core.game.node.entity.player.link.diary.DiaryType; import core.game.node.item.Item; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents the dialogue used to handle the sailing from and to karamja. @@ -46,7 +47,7 @@ public class SeamanDialoguePlugin extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - if (args.length > 1 && player.getQuestRepository().isComplete("Pirate's Treasure")) { + if (args.length > 1 && player.getQuestRepository().isComplete(Quests.PIRATES_TREASURE)) { if (player.getEquipment().get(EquipmentContainer.SLOT_RING) != null && player.getEquipment().get(EquipmentContainer.SLOT_RING).getId() == Items.RING_OF_CHAROSA_6465) { travel(); } else if (player.getAchievementDiaryManager().getDiary(DiaryType.KARAMJA).isComplete(0)) { diff --git a/Server/src/main/content/global/travel/ship/ShipCharter.java b/Server/src/main/content/global/travel/ship/ShipCharter.java index 99121e375..4058fc375 100644 --- a/Server/src/main/content/global/travel/ship/ShipCharter.java +++ b/Server/src/main/content/global/travel/ship/ShipCharter.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents a class used to charter ships. @@ -84,7 +85,10 @@ public final class ShipCharter { */ public static int getCost(final Player player, Destination destination) { int cost = destination.getCost(player, destination); - if (player.getEquipment().containsItem(RING_OF_CHAROS)) {// TODO: cabin fever quest + if (hasRequirement(player, Quests.CABIN_FEVER)) { + cost -= Math.round((cost / 2.)); + } + if (player.getEquipment().containsItem(RING_OF_CHAROS)) { cost -= Math.round((cost / 2.)); } return cost; @@ -96,12 +100,10 @@ public final class ShipCharter { * @return the hidden childs. */ public static int[] getHiddenComponents(final Player player, Destination base) { - final Destination[] restrictions = new Destination[] { /** - * - * Destination.MOS_LE_HARMLESS, - */ - Destination.OO_GLOG, Destination.SHIPYARD, /* Destination.PORT_TYRAS, */ - Destination.CRANDOR }; + final Destination[] restrictions = new Destination[] { /* Destination.MOS_LE_HARMLESS, */ + Destination.OO_GLOG, Destination.SHIPYARD, /* Destination.PORT_TYRAS, */ + Destination.CRANDOR + }; List childs = new ArrayList<>(20); for (Destination destination : restrictions) { childs.add(destination.getXChild()); @@ -137,15 +139,20 @@ public final class ShipCharter { * @author 'Vexia */ public enum Destination { - CATHERBY(Location.create(2792, 3417, 1), 25, new int[] { 480, 0, 480, 625, 1600, 3250, 1000, 1600, 3200, 3400 }, Location.create(2797, 3414, 0), 3, 14), + CATHERBY(Location.create(2792, 3417, 1), 25, new int[] { 480, 0, 480, 1250, 1600, 3250, 1000, 1600, 3200, 3400 }, Location.create(2797, 3414, 0), 3, 14), PORT_PHASMATYS(Location.create(3705, 3503, 1), 24, new int[] { 3650, 3250, 1850, 0, 0, 0, 2050, 1850, 3200, 1100 }, Location.create(3702, 3502, 0), 2, 13) { @Override public boolean checkTravel(Player player) { - return requireQuest(player, "Priest in Peril", "to go there"); + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to go there."); } }, - CRANDOR(new Location(2792, 3417, 1), 32, new int[] { 0, 480, 480, 925, 400, 3650, 1600, 400, 3200, 3800 }, null, 10, 21), - BRIMHAVEN(Location.create(2763, 3238, 1), 28, new int[] { 0, 480, 480, 925, 400, 3650, 1600, 400, 3200, 3800 }, Location.create(2760, 3238, 0), 6, 17){ + CRANDOR(Location.create(2792, 3417, 1), 32, new int[] { 0, 480, 480, 925, 400, 3650, 1600, 400, 3200, 3800 }, null, 10, 21) { + @Override + public boolean checkTravel(Player player) { + return requireQuest(player, Quests.DRAGON_SLAYER, "to go there."); + } + }, + BRIMHAVEN(Location.create(2763, 3238, 1), 28, new int[] { 0, 480, 480, 1950, 400, 3650, 1600, 400, 3200, 3800 }, Location.create(2760, 3238, 0), 6, 17){ @Override public int getCost(Player player, Destination destination) { boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); @@ -153,7 +160,7 @@ public final class ShipCharter { return super.getCost(player, destination); } }, - PORT_SARIM(Location.create(3038, 3189, 1), 30, new int[] { 1600, 1000, 0, 325, 1280, 650, 1280, 400, 3200, 1400 }, Location.create(3039, 3193, 0), 8, 19){ + PORT_SARIM(Location.create(3038, 3189, 1), 30, new int[] { 1600, 1000, 0, 650, 1280, 650, 1280, 400, 3200, 1400 }, Location.create(3039, 3193, 0), 8, 19){ @Override public int getCost(Player player, Destination destination) { boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); @@ -161,8 +168,14 @@ public final class ShipCharter { return super.getCost(player, destination); } }, - PORT_TYRAS(Location.create(2142, 3122, 0), 23, new int[] { 3200, 3200, 3200, 1600, 3200, 3200, 3200, 3200, 0, 3200 }, Location.create(2143, 3122, 0), 1, 12), - KARAMJA(Location.create(2957, 3158, 1), 27, new int[] { 200, 480, 0, 225, 400, 1850, 0, 200, 3200, 2000 }, Location.create(2954, 3156, 0), 5, 16) { + PORT_TYRAS(Location.create(2142, 3122, 0), 23, new int[] { 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 0, 3200 }, Location.create(2143, 3122, 0), 1, 12) { + @Override + public boolean checkTravel(Player player) { + return hasRequirement(player, Quests.REGICIDE); + } + + }, + KARAMJA(Location.create(2957, 3158, 1), 27, new int[] { 200, 480, 0, 450, 400, 1850, 0, 200, 3200, 2000 }, Location.create(2954, 3156, 0), 5, 16) { @Override public int getCost(Player player, Destination destination) { boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); @@ -170,7 +183,7 @@ public final class ShipCharter { return super.getCost(player, destination); } }, - PORT_KHAZARD(Location.create(2674, 3141, 1), 29, new int[] { 1600, 1000, 0, 325, 180, 650, 1280, 400, 3200, 1400 }, Location.create(2674, 3144, 0), 7, 18){ + PORT_KHAZARD(Location.create(2674, 3141, 1), 29, new int[] { 1600, 1000, 0, 2050, 180, 650, 1280, 400, 3200, 1400 }, Location.create(2674, 3144, 0), 7, 18){ @Override public int getCost(Player player, Destination destination) { boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); @@ -178,9 +191,19 @@ public final class ShipCharter { return super.getCost(player, destination); } }, - SHIPYARD(Location.create(3001, 3032, 0), 26, new int[] { 400, 1600, 200, 225, 720, 1850, 400, 0, 3200, 900 }, Location.create(3001, 3032, 0), 4, 15), - OO_GLOG(Location.create(2623, 2857, 0), 33, new int[] { 300, 3400, 2000, 550, 5000, 2800, 1400, 900, 3200, 0}, Location.create(2622, 2857, 0), 11, 22), - MOS_LE_HARMLESS(Location.create(3671, 2931, 0), 31, new int[] { 725, 625, 1025, 0, 1025, 0, 325, 275, 1600, 500 }, Location.create(3671, 2933, 0), 9, 20); + SHIPYARD(Location.create(3001, 3032, 0), 26, new int[] { 400, 1600, 200, 450, 720, 1850, 400, 0, 3200, 900 }, Location.create(3001, 3032, 0), 4, 15) { + @Override + public boolean checkTravel(Player player) { + return requireQuest(player, Quests.THE_GRAND_TREE, "to go there."); + } + }, + OO_GLOG(Location.create(2623, 2857, 0), 33, new int[] { 300, 3400, 2000, 1100, 5000, 2800, 1400, 900, 3200, 0}, Location.create(2622, 2857, 0), 11, 22), + MOS_LE_HARMLESS(Location.create(3671, 2931, 0), 31, new int[] { 1550, 1250, 2050, 0, 2050, 0, 650, 550, 3200, 1000 }, Location.create(3671, 2933, 0), 9, 20) { + @Override + public boolean checkTravel(Player player) { + return hasRequirement(player, Quests.CABIN_FEVER); + } + }; /** * Constructs a new {@code ShipCharter} {@code Object}. diff --git a/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt b/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt index 494a79e12..2f6e9a7ed 100644 --- a/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt +++ b/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt @@ -1,9 +1,5 @@ package content.global.travel.trees -import core.api.isQuestComplete -import core.api.openDialogue -import core.api.sendDialogue -import core.api.teleport import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType @@ -12,15 +8,16 @@ import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics import org.rs09.consts.NPCs -import content.region.kandarin.quest.tree.TreeGnomeVillage import core.game.dialogue.DialogueFile import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.game.world.GameWorld.Pulser import core.tools.END_DIALOGUE +import content.data.Quests +import core.api.* class GnomeSpiritTreeListener: InteractionListener { - val spiritTrees = intArrayOf(1317,1293,1294) + val spiritTrees = intArrayOf(1317,1293,1294,8355) override fun defineListeners() { on(spiritTrees, IntType.SCENERY, "talk-to"){ player, _ -> @@ -39,14 +36,18 @@ class GnomeSpiritTreeTeleportDialogue: DialogueFile() { Location(2542, 3170, 0), Location(2461, 3444, 0), Location(2556, 3259, 0), - Location(3184, 3508, 0) + Location(3184, 3508, 0), + Location(3060, 3256, 0), //Port Sarim + Location(2613, 3856, 0), //Etceteria + Location(2800, 3203, 0) //Brimhaven + ) private val ANIMATIONS = arrayOf(Animation(7082), Animation(7084)) private val GRAPHICS = arrayOf(Graphics(1228), Graphics(1229)) fun hasQuestCompleted(player: Player): Boolean { - if (!isQuestComplete(player, TreeGnomeVillage.questName)) { + if (!isQuestComplete(player, Quests.TREE_GNOME_VILLAGE)) { sendDialogue(player, "The tree doesn't feel like talking.") stage = END_DIALOGUE return false @@ -86,6 +87,15 @@ class GnomeSpiritTreeTeleportDialogue: DialogueFile() { stage = END_DIALOGUE return } + + var plantedSpiritTreeLocation = when { + getVarbit(player!!, 720) == 20 -> "Port Sarim" + getVarbit(player!!, 722) == 20 -> "Etceteria" + getVarbit(player!!, 724) == 20 -> "Brimhaven" + else -> null + //There should never be a case where more than one spirit tree is planted. + } + if(plantedSpiritTreeLocation == null) { when (stage) { 0 -> interpreter!!.sendOptions( "Where would you like to go?", @@ -100,6 +110,29 @@ class GnomeSpiritTreeTeleportDialogue: DialogueFile() { 3 -> sendTeleport(player!!, LOCATIONS[2]) 4 -> sendTeleport(player!!, LOCATIONS[3]) } + } + } + else when (stage) { + 0 -> interpreter!!.sendOptions( + "Where would you like to go?", + "Tree Gnome Village", + "Tree Gnome Stronghold", + "Battlefield of Khazard", + "Grand Exchange", + plantedSpiritTreeLocation + ).also { stage++ } + 1 -> when (buttonID) { + 1 -> sendTeleport(player!!, LOCATIONS[0]) + 2 -> sendTeleport(player!!, LOCATIONS[1]) + 3 -> sendTeleport(player!!, LOCATIONS[2]) + 4 -> sendTeleport(player!!, LOCATIONS[3]) + 5 -> when (plantedSpiritTreeLocation) { + "Port Sarim" -> sendTeleport(player!!,LOCATIONS[4]) + "Etceteria" -> sendTeleport(player!!,LOCATIONS[5]) + "Brimhaven" -> sendTeleport(player!!,LOCATIONS[6]) + else -> stage = END_DIALOGUE + } + } } } } diff --git a/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt b/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt index c97013a0f..901bec497 100644 --- a/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt +++ b/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt @@ -2,36 +2,35 @@ package content.minigame.allfiredup import core.api.* import core.game.node.entity.player.Player -import core.tools.SystemLogger import core.game.world.map.Location import core.tools.Log /** * Various data for beacons, such as varp and offset, required FM level, etc - * @author Ceikry + * @author Ceikry, Player Name */ enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val location: Location, val experience: Double, val keeper: Int = 0) { - RIVER_SALVE("",43,5146,Location.create(3396, 3464, 0),216.2,8065), - RAG_AND_BONE("",43,5147,Location.create(3343, 3510, 0),235.8,8066), - JOLLY_BOAR("",48,5148,Location.create(3278, 3525, 0), 193.8,8067), - NORTH_VARROCK_CASTLE("",53,5149,Location.create(3236, 3527, 0),178.5,8068), - GRAND_EXCHANGE("",59,5150,Location.create(3170, 3536, 0),194.3,8069), - EDGEVILLE("",62,5151,Location.create(3087, 3516, 0),86.7,8070), - MONASTERY("",68,5152,Location.create(3034, 3518, 0),224.4,8071), - GOBLIN_VILLAGE("",72,5153,Location.create(2968, 3516, 0),194.8,8072), - BURTHORPE("",76,5154,Location.create(2940, 3565, 0),195.3,8073), - DEATH_PLATEAU("",79,5155,Location.create(2944, 3622, 0),249.9,8074), - TROLLHEIM("",83,5156,Location.create(2939, 3680, 0),201.0,8075), - GWD("",87,5157,Location.create(2937, 3773, 0),255.0,8076), - TEMPLE("",89,5158,Location.create(2946, 3836, 0),198.9), - PLATEAU("",92,5159,Location.create(2964, 3931, 0),147.9); + RIVER_SALVE("near the River Salve", 43, 5146, Location.create(3396, 3464, 0), 216.2, 8065), + RAG_AND_BONE("near the Rag and Bone Man", 43, 5147, Location.create(3343, 3510, 0), 235.8, 8066), + JOLLY_BOAR("north of the Jolly Boar", 48, 5148, Location.create(3278, 3525, 0), 193.8, 8067), + NORTH_VARROCK_CASTLE("north of Varrock Palace", 53, 5149, Location.create(3236, 3527, 0), 178.5, 8068), + GRAND_EXCHANGE("north of the Grand Exchange", 59, 5150, Location.create(3170, 3536, 0), 194.3, 8069), + EDGEVILLE("near Edgeville", 62, 5151, Location.create(3087, 3516, 0), 86.7, 8070), + MONASTERY("near the Black Knights' Fortress", 68, 5152, Location.create(3034, 3518, 0), 224.4, 8071), + GOBLIN_VILLAGE("near Goblin Village", 72, 5153, Location.create(2968, 3516, 0), 194.8, 8072), + BURTHORPE("near Burthorpe", 76, 5154, Location.create(2940, 3565, 0), 195.3, 8073), + DEATH_PLATEAU("east of Death Plateau", 79, 5155, Location.create(2944, 3622, 0), 249.9, 8074), + TROLLHEIM("east of Trollheim", 83, 5156, Location.create(2939, 3680, 0), 201.0, 8075), + GWD("east of the God Wars dungeon temple", 87, 5157, Location.create(2937, 3773, 0), 255.0, 8076), + TEMPLE("north of the small temple in the Wilderness", 89, 5158, Location.create(2946, 3836, 0), 198.9), + PLATEAU("on the Frozen Waste Plateau", 92, 5159, Location.create(2964, 3931, 0), 147.9); companion object { fun forLocation(location: Location): AFUBeacon { for (beacon in values()) { if (beacon.location.equals(location)) return beacon } - return AFUBeacon.RIVER_SALVE.also { log(this::class.java, Log.WARN, "Unhandled Beacon Location ${location.toString()}") } + return AFUBeacon.RIVER_SALVE.also { log(this::class.java, Log.WARN, "Unhandled Beacon Location ${location.toString()}") } } fun resetAllBeacons(player: Player){ @@ -42,19 +41,19 @@ enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val l } fun light(player: Player){ - setVarbit(player, varbit, 2) + setVarbit(player, varbit, 2, true) } fun diminish(player: Player){ - setVarbit(player, varbit, 3) + setVarbit(player, varbit, 3, true) } fun extinguish(player: Player){ - setVarbit(player, varbit, 0) + setVarbit(player, varbit, 0, true) } fun lightGnomish(player: Player){ - setVarbit(player, varbit, 4) + setVarbit(player, varbit, 4, true) } fun fillWithLogs(player: Player){ diff --git a/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt b/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt index 08d059bcf..1522add6c 100644 --- a/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt +++ b/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt @@ -4,12 +4,23 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item -import core.game.system.task.Pulse import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import core.game.interaction.InteractionListener import core.game.interaction.IntType -import core.game.world.GameWorld +import content.data.Quests +import core.api.delayScript +import core.api.getAttribute +import core.api.getOrStartTimer +import core.api.getQuestStage +import core.api.lock +import core.api.queueScript +import core.api.removeAttribute +import core.api.sendMessage +import core.api.setAttribute +import core.api.setQuestStage +import core.api.stopExecuting +import core.game.interaction.QueueStrength private val VALID_LOGS = intArrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521,Items.WILLOW_LOGS_1519,Items.MAPLE_LOGS_1517,Items.YEW_LOGS_1515,Items.MAGIC_LOGS_1513) private val FILL_ANIM = Animation(9136) @@ -17,15 +28,15 @@ private val LIGHT_ANIM = Animation(7307) /** * Handles interactions for beacons - * @author Ceikry + * @author Ceikry, Player Name */ class AFUBeaconListeners : InteractionListener { override fun defineListeners() { on(IntType.SCENERY,"add-logs","light"){ player, node -> val beacon = AFUBeacon.forLocation(node.location) - val questComplete = player.questRepository.isComplete("All Fired Up") - val questStage = player.questRepository.getStage("All Fired Up") + val questComplete = player.questRepository.isComplete(Quests.ALL_FIRED_UP) + val questStage = player.questRepository.getStage(Quests.ALL_FIRED_UP) if ((beacon != AFUBeacon.RIVER_SALVE && beacon != AFUBeacon.RAG_AND_BONE && !questComplete) || (beacon == AFUBeacon.RIVER_SALVE && questStage < 20 && !questComplete) @@ -68,7 +79,7 @@ class AFUBeaconListeners : InteractionListener { } AFUBeacon.GOBLIN_VILLAGE -> { - if(!player.questRepository.isComplete("Lost Tribe")){ + if(!player.questRepository.isComplete(Quests.THE_LOST_TRIBE)){ player.dialogueInterpreter.sendDialogues(NPC(beacon.keeper).getShownNPC(player), core.game.dialogue.FacialExpression.THINKING,"We no trust you outsider. You no light our beacon.","(Complete Lost Tribe to use this beacon.)") return } @@ -85,112 +96,80 @@ class AFUBeaconListeners : InteractionListener { val logs = getLogs(player,20) if (logs.id != 0 && player.inventory.remove(logs)) { - player.lock() - - var session: AFUSession? = null - if(questComplete){ - session = player.getAttribute("afu-session", null) - if(session == null) { - session = AFUSession(player) - session.init() + lock(player, FILL_ANIM.duration) + queueScript(player, 0, QueueStrength.SOFT) { stage -> + if (stage == 1) { + player.animator.animate(FILL_ANIM) + return@queueScript delayScript(player, FILL_ANIM.duration) } + setAttribute(player, "/save:beacon:${beacon.ordinal}:logsId", logs.id) + beacon.fillWithLogs(player) + return@queueScript stopExecuting(player) } - - GameWorld.Pulser.submit(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 0 -> player.animator.animate(FILL_ANIM) - 1 -> { - beacon.fillWithLogs(player) - if(questComplete){ - session?.setLogs(beacon.ordinal,logs) - } - } - 2 -> player.unlock().also {player.animator.animate(Animation.RESET); return true } - } - return false - } - }) } else { player.dialogueInterpreter.sendDialogue("You need some logs to do this.") } } - fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ - var session: AFUSession? = null - if(questComplete){ - session = player.getAttribute("afu-session",null) - if(session == null) return - } - + fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean) { if(player.inventory.contains(Items.TINDERBOX_590,1)){ - player.lock() - GameWorld.Pulser.submit(object: Pulse(){ - var counter = 0 - override fun pulse(): Boolean { - when(counter++){ - 0 -> player.animator.animate(LIGHT_ANIM) - 1 -> { - beacon.light(player) - if(questComplete){ - session?.startTimer(beacon.ordinal) - if(session?.getLitBeacons() == 6 && !player.hasFireRing()){ - player.sendMessage("Congratulations on lighting 6 beacons at once! King Roald has something for you.") - player.setAttribute("/save:afu-mini:ring",true) - } - if(session?.getLitBeacons() == 10 && !player.hasFlameGloves()){ - player.sendMessage("Congratulations on lighting 10 beacons at once! King Roald has something for you.") - player.setAttribute("/save:afu-mini:gloves",true) - } - if(session?.getLitBeacons() == 14 && !player.hasInfernoAdze()){ - player.sendMessage("Congratulations on lighting all 14 beacons! King Roald has something special for you.") - player.setAttribute("/save:afu-mini:adze",true) - } - var experience = beacon.experience - experience += session?.getBonusExperience() ?: 0.0 - player.skills.addExperience(Skills.FIREMAKING,experience) - } else { - player.questRepository.getQuest("All Fired Up").setStage(player, player.questRepository.getStage("All Fired Up") + 10) - } - } - 2 -> player.unlock().also { return true } - } - return false + lock(player, LIGHT_ANIM.duration) + queueScript(player, 0, QueueStrength.SOFT) { stage -> + if (stage == 1) { + player.animator.animate(LIGHT_ANIM) + return@queueScript delayScript(player, LIGHT_ANIM.duration) } - }) + val logsId = getAttribute(player, "/save:beacon:${beacon.ordinal}:logsId", Items.LOGS_1511) + removeAttribute(player, "/save:beacon:${beacon.ordinal}:logsId") + beacon.light(player) + if (!questComplete) { + setQuestStage(player, Quests.ALL_FIRED_UP, getQuestStage(player, Quests.ALL_FIRED_UP) + 10) + return@queueScript stopExecuting(player) + } + val timer = getOrStartTimer(player) + timer.addTime(beacon.ordinal, logsId, 20) + val lit = timer.getLitBeacons() + if (lit == 6 && !player.hasFireRing()) { + sendMessage(player, "Congratulations on lighting 6 beacons at once! King Roald has something for you.") + setAttribute(player, "/save:afu-mini:ring", true) + } + if (lit == 10 && !player.hasFlameGloves()) { + sendMessage(player, "Congratulations on lighting 10 beacons at once! King Roald has something for you.") + setAttribute(player, "/save:afu-mini:gloves", true) + } + if (lit == 14 && !player.hasInfernoAdze()) { + sendMessage(player, "Congratulations on lighting all 14 beacons! King Roald has something special for you.") + setAttribute(player, "/save:afu-mini:adze", true) + } + val xp = beacon.experience + timer.getBonusExperience() + player.skills.addExperience(Skills.FIREMAKING, xp) + return@queueScript stopExecuting(player) + } } else { player.dialogueInterpreter.sendDialogue("You need a tinderbox to light this.") } } fun restoreBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ - var session: AFUSession? = null - if(questComplete){ - session = player.getAttribute("afu-session",null) - if(session == null) return - } - val logs = getLogs(player, 5) if (logs.id != 0 && player.inventory.remove(logs)) { - player.lock() - GameWorld.Pulser.submit(object: Pulse(){ - var counter = 0 - override fun pulse(): Boolean { - when(counter++){ - 0 -> player.animator.animate(FILL_ANIM) - 1 -> beacon.light(player).also { - if(questComplete){ - session?.refreshTimer(beacon,logs.id) - } else { - player.questRepository.getQuest("All Fired Up").setStage(player, 80) - } - } - 2 -> player.unlock().also { return true } - } - return false + lock(player, FILL_ANIM.duration) + queueScript(player, 0, QueueStrength.SOFT) { stage -> + if (stage == 1) { + player.animator.animate(LIGHT_ANIM) + return@queueScript delayScript(player, LIGHT_ANIM.duration) } - }) + val backupLogsId = getAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", Items.LOGS_1511) + removeAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId") + beacon.light(player) + if (!questComplete) { + setQuestStage(player, Quests.ALL_FIRED_UP, 80) + return@queueScript stopExecuting(player) + } + val timer = getOrStartTimer(player) + timer.addTime(beacon.ordinal, backupLogsId, 5) + return@queueScript stopExecuting(player) + } } else { player.dialogueInterpreter.sendDialogue("You need some logs to do this.") } diff --git a/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt b/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt index ac6017994..22e87dfdc 100644 --- a/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt +++ b/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt @@ -1,5 +1,6 @@ package content.minigame.allfiredup +import content.data.Quests import core.game.node.entity.impl.ForceMovement import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills @@ -12,7 +13,6 @@ import org.rs09.consts.Items import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.api.* -import java.util.* /** * Handles repairing and climbing of the 3 beacon shortcuts needed to access them @@ -26,26 +26,74 @@ class AFURepairClimbHandler : InteractionListener { override fun defineListeners() { on(repairIDs, IntType.SCENERY, "repair"){ player, _ -> - var rco: RepairClimbObject = RepairClimbObject.GWD - for(ent in RepairClimbObject.values()) if(ent.destinationDown?.withinDistance(player.location,2) == true || ent.destinationUp?.withinDistance(player.location,2) == true) rco = ent - repair(player,rco) - return@on true + if (hasRequirement(player, Quests.ALL_FIRED_UP)){ + val rco: RepairClimbObject? = getClimbingObject(player) + repair(player,rco!!) + return@on true + } + return@on false } on(climbIDs, IntType.SCENERY, "climb"){ player, node -> - var rco: RepairClimbObject = RepairClimbObject.GWD - for(ent in RepairClimbObject.values()) if(ent.destinationDown?.withinDistance(player.location,2) == true || ent.destinationUp?.withinDistance(player.location,2) == true) rco = ent - climb(player,rco,node.location) + val rco: RepairClimbObject? = getClimbingObject(player) + climb(player,rco!!,node.location) return@on true } } + private fun getClimbingObject(player: Player): RepairClimbObject?{ + for(ent in RepairClimbObject.values()) + if(ent.destinationDown?.withinDistance(player.location,2) == true || + ent.destinationUp?.withinDistance(player.location,2) == true){ + return ent + } + return RepairClimbObject.GWD //the only one that does not have down/up destinations + } + private fun repair(player: Player,rco: RepairClimbObject){ + if (rco == RepairClimbObject.TEMPLE){ + // You can do this 2 different ways + val hasSmithingLevel = getStatLevel(player, Skills.SMITHING) >= 70 + val hasConstructionLevel = getStatLevel(player, Skills.CONSTRUCTION) >= 59 + + if (!hasConstructionLevel && !hasSmithingLevel){ + sendDialogue(player, "You need level 70 smithing or 59 construction for this.") + return + } + + val hasHammer = inInventory(player, Items.HAMMER_2347) + val hasSmithingItems = hasHammer && inInventory(player, Items.IRON_BAR_2351, 2) + val hasConstructionItems = hasHammer && inInventory(player, Items.PLANK_960, 2) + + if (hasSmithingLevel && hasSmithingItems){ + if (removeItem(player,Item(Items.IRON_BAR_2351, 2))) { + setVarbit(player, rco.varbit, 1, true) + return + } + } + // Only check this if the smithing repair didn't work + if (hasConstructionLevel && hasConstructionItems){ + val nails = NailType.get(player, 4) + if (nails != null){ + if (removeItem(player, Item(Items.PLANK_960, 2)) && removeItem(player, Item(nails.itemId, 4))) { + setVarbit(player, rco.varbit, 1, true) + return + } + } + } + + var msg = "You need " + msg += if (hasSmithingLevel) "a hammer and 2 iron bars" else "" + msg += if (hasSmithingLevel && hasConstructionLevel) " or " else "" + msg += if (hasConstructionLevel) "a hammer, 2 planks and 4 nails for this." else " for this." + sendDialogue(player, msg) + return + } val skill = rco.levelRequirement?.first ?: 0 val level = rco.levelRequirement?.second ?: 0 - if(player.skills.getLevel(skill) < level){ - player.dialogueInterpreter.sendDialogue("You need level $level ${Skills.SKILL_NAME[skill]} for this.") + if(getStatLevel(player, skill) < level){ + sendDialogue(player, "You need level $level ${Skills.SKILL_NAME[skill]} for this.") return } @@ -53,47 +101,40 @@ class AFURepairClimbHandler : InteractionListener { val requiredItems = when(rco){ RepairClimbObject.DEATH_PLATEAU -> { - arrayOf(Item(Items.PLANK_960,2)) + Item(Items.PLANK_960,2) } RepairClimbObject.BURTHORPE -> { - arrayOf(Item(Items.IRON_BAR_2351,2)) + Item(Items.IRON_BAR_2351,2) } RepairClimbObject.GWD -> { requiresNeedle = true - arrayOf(Item(Items.JUTE_FIBRE_5931,3)) - } - - RepairClimbObject.TEMPLE -> { - arrayOf(Item(Items.IRON_BAR_2351,2)) + Item(Items.JUTE_FIBRE_5931,3) } + else -> return } if(requiresNeedle){ - if(player.inventory.containsItem(Item(Items.NEEDLE_1733)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) { - player.inventory.remove(*requiredItems) - if (Random().nextBoolean()) player.inventory.remove(Item(Items.NEEDLE_1733)) - } else { - player.dialogueInterpreter.sendDialogue("You need a needle and ${requiredItems.map { "${it.amount} ${it.name.toLowerCase()}s" }.toString().replace("[","").replace("]","")} for this.") + if (!inInventory(player, Items.NEEDLE_1733) || !removeItem(player, requiredItems)) { + sendDialogue(player, "You need a needle and ${requiredItems.amount} ${requiredItems.name.lowercase()}s for this.") return } } else { - if(player.inventory.containsItem(Item(Items.HAMMER_2347)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) { + if(inInventory(player, Items.HAMMER_2347) && inInventory(player, requiredItems.id, requiredItems.amount)) { val nails = NailType.get(player,4) if(nails == null && rco == RepairClimbObject.DEATH_PLATEAU){ - player.dialogueInterpreter.sendDialogue("You need 4 nails for this.") + sendDialogue(player, "You need 4 nails for this.") return } else if (rco == RepairClimbObject.DEATH_PLATEAU){ - player.inventory.remove(Item(nails.itemId,4)) + removeItem(player, Item(nails.itemId,4)) } - player.inventory.remove(*requiredItems) + removeItem(player, requiredItems) } else { - player.dialogueInterpreter.sendDialogue("You need a hammer and ${requiredItems.map { "${it.amount} ${it.name.toLowerCase()}s" }.toString().replace("[","").replace("]","")} for this.") + sendDialogue(player, "You need a hammer and ${requiredItems.amount} ${requiredItems.name.lowercase()}s for this.") return } } - setVarbit(player, rco.varbit, 1, true) } @@ -105,7 +146,7 @@ class AFURepairClimbHandler : InteractionListener { DEATH_PLATEAU(5161,Location.create(2949, 3623, 0),Location.create(2954, 3623, 0), Pair(Skills.CONSTRUCTION,42)), BURTHORPE(5160,Location.create(2941, 3563, 0),Location.create(2934, 3563, 0),Pair(Skills.SMITHING,56)), GWD(5163,null,null,Pair(Skills.CRAFTING,60)), - TEMPLE(5164,Location.create(2949, 3835, 0),Location.create(2956, 3835, 0),Pair(Skills.SMITHING,64)); + TEMPLE(5164,Location.create(2949, 3835, 0),Location.create(2956, 3835, 0),Pair(0,0)); // This needs to be handled specially so don't have levels here fun getOtherLocation(player: Player): Location?{ if(player.location == destinationDown) return destinationUp diff --git a/Server/src/main/content/minigame/allfiredup/AFUSession.kt b/Server/src/main/content/minigame/allfiredup/AFUSession.kt deleted file mode 100644 index 1168a0f0f..000000000 --- a/Server/src/main/content/minigame/allfiredup/AFUSession.kt +++ /dev/null @@ -1,121 +0,0 @@ -package content.minigame.allfiredup - -import core.api.LogoutListener -import core.game.node.entity.player.Player -import core.game.node.item.Item -import core.game.system.task.Pulse -import core.game.world.GameWorld -import org.rs09.consts.Items -import core.tools.colorize - -/** - * Handles keeping track of lit beacons and their burn time remaining - * @author Ceikry - */ -class AFUSession(val player: Player? = null) : LogoutListener { - private val beaconTimers = Array(14){i -> BeaconTimer(0, AFUBeacon.values()[i]) } - private val logInventories = Array(14){Item(0,0)} - private val beaconWatched = Array(14){false} - private var isActive = false - - fun init() { - isActive = true - GameWorld.Pulser.submit(object: Pulse(){ - override fun pulse(): Boolean { - player!!.setAttribute("afu-pulse",this) - beaconTimers.forEach {timer -> - timer.ticks-- - if(timer.ticks == 300) timer.beacon.diminish(player).also { - if(beaconWatched[timer.beacon.ordinal]){ - beaconWatched[timer.beacon.ordinal] = false - timer.ticks += (getTicks(logInventories[timer.beacon.ordinal].id) * 5) - timer.beacon.light(player) - player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} watcher has used your backup logs.")) - } else { - player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_", " ")} beacon is dying!")) - } - } - if(timer.ticks == 0) timer.beacon.extinguish(player).also { player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} beacon has gone out!")) } - } - return !isActive - } - }) - player!!.setAttribute("afu-session",this) - } - - fun getLitBeacons(): Int{ - return beaconTimers.count { it.ticks > 0 } - } - - fun end(){ - isActive = false - } - - fun setLogs(beaconIndex: Int, logs: Item){ - logInventories[beaconIndex] = logs - } - - fun startTimer(beaconIndex: Int){ - val ticks = getTicks(logInventories[beaconIndex].id) * 20 - logInventories[beaconIndex] = Item(0,0) - beaconTimers[beaconIndex].ticks = ticks - } - - fun refreshTimer(beacon: AFUBeacon, logID: Int){ - val ticks = getTicks(logID) * 5 - beaconTimers.forEach { - if(it.beacon.ordinal == beacon.ordinal) it.ticks += ticks - } - } - - fun setWatcher(index: Int, logs: Item){ - beaconWatched[index] = true - logInventories[index] = logs - } - - fun isWatched(index: Int): Boolean{ - return beaconWatched[index] - } - - fun getTicks(logID: Int): Int{ - val ticks = when(logID){ - Items.LOGS_1511 -> 65 - Items.OAK_LOGS_1521 -> 68 - Items.WILLOW_LOGS_1519 -> 73 - Items.MAPLE_LOGS_1517 -> 79 - Items.YEW_LOGS_1515 -> 83 - Items.MAGIC_LOGS_1513 -> 90 - else -> 0 - } - return ticks - } - - fun getBonusExperience(): Double{ - return when(getLitBeacons()){ - 1 -> 608.4 - 2 -> 1622.4 - 3 -> 1987.4 - 4 -> 2149.6 - 5 -> 2149.6 - 6 -> 2514.6 - 7 -> 2555.2 - 8 -> 2758.0 - 9 -> 2839.1 - 10 -> 3041.9 - 11 -> 3123.0 - 12 -> 3244.7 - 13 -> 3366.4 - 14 -> 4867.4 - else -> 0.0 - } - } - - override fun logout(player: Player) { - AFUBeacon.resetAllBeacons(player) - val session: AFUSession? = player.getAttribute("afu-session",null) - session?.end() - player.removeAttribute("afu-session") - } - - internal class BeaconTimer(var ticks: Int, val beacon: AFUBeacon) -} \ No newline at end of file diff --git a/Server/src/main/content/minigame/allfiredup/AFUTimer.kt b/Server/src/main/content/minigame/allfiredup/AFUTimer.kt new file mode 100644 index 000000000..b7ee735b4 --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/AFUTimer.kt @@ -0,0 +1,104 @@ +package content.minigame.allfiredup + +import core.api.getAttribute +import core.api.log +import core.api.removeAttribute +import core.api.sendMessage +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.PersistTimer +import core.tools.Log +import core.tools.colorize +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Items + +class AFUTimer : PersistTimer(1, "AFU timer", isSoft = true) { + private val burnTicks = Array(14) { 0 } + + fun addTime(index: Int, logsId: Int, numLogs: Int) { + val ticksPerLog = when (logsId) { + Items.LOGS_1511 -> 65 + Items.OAK_LOGS_1521 -> 68 + Items.WILLOW_LOGS_1519 -> 73 + Items.MAPLE_LOGS_1517 -> 79 + Items.YEW_LOGS_1515 -> 83 + Items.MAGIC_LOGS_1513 -> 90 + else -> 0 + } + burnTicks[index] += numLogs * ticksPerLog + } + + fun getBonusExperience(): Double { + return when (getLitBeacons()) { + 1 -> 608.4 + 2 -> 1622.4 + 3 -> 1987.4 + 4 -> 2149.6 + 5 -> 2149.6 + 6 -> 2514.6 + 7 -> 2555.2 + 8 -> 2758.0 + 9 -> 2839.1 + 10 -> 3041.9 + 11 -> 3123.0 + 12 -> 3244.7 + 13 -> 3366.4 + 14 -> 4867.4 + else -> 0.0 + } + } + + fun getLitBeacons(): Int { + return burnTicks.count { it > 0 } + } + + override fun save(root: JSONObject, entity: Entity) { + val beaconArray = JSONArray() + for (i in 0..13) { + beaconArray.add(burnTicks[i]) + } + root["beacons"] = beaconArray + } + + override fun parse(root: JSONObject, entity: Entity) { + val beacons = root["beacons"] as JSONArray + for (i in 0..13) { + burnTicks[i] = beacons[i].toString().toInt() + } + } + + override fun run(entity: Entity) : Boolean { + if (entity !is Player) { + log(this::class.java, Log.ERR, "How did a non-Player light an AFU beacon?") + return false + } + val player = entity + var keepRunning = false + for (i in 0..13) { + val beacon = AFUBeacon.values()[i] + if (burnTicks[i] > 0) { + burnTicks[i]-- + if (burnTicks[i] > 0) { + keepRunning = true + } + if (burnTicks[i] == 300) { + val backupLogsId = getAttribute(player, "/save:beacon:$i:backupLogsId", 0) + if (backupLogsId != 0) { + addTime(i, backupLogsId, 5) + removeAttribute(player, "/save:beacon:$i:backupLogsId") + sendMessage(player, colorize("%RThe beacon watcher ${beacon.title} has used your backup logs.")) + } else { + beacon.diminish(player) + sendMessage(player, colorize("%RThe beacon ${beacon.title} is dying!")) + } + } else if (burnTicks[i] == 0) { + beacon.extinguish(player) + removeAttribute(player, "/save:beacon:$i:logsId") + sendMessage(player, colorize("%RThe beacon ${beacon.title} has gone out!")) + } + } + } + return keepRunning + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt b/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt index f2b25db41..d2cf48053 100644 --- a/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt +++ b/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt @@ -1,13 +1,13 @@ package content.minigame.allfiredup -import core.ServerConstants import core.game.dialogue.* import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.plugin.Initializable -import content.region.wilderness.dialogue.* +import core.api.getAttribute +import core.api.setAttribute import org.rs09.consts.Items private val VALID_LOGS = arrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513) @@ -41,10 +41,9 @@ class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { val beacon = AFUBeacon.values()[index] val logs = getLogs(player,5) - val session: AFUSession? = player.getAttribute("afu-session",null) when(stage){ 0 -> player("Hello!").also { stage++ } - 1 -> if(beacon.getState(player) == BeaconState.LIT && session?.isWatched(index) == false){ + 1 -> if (beacon.getState(player) == BeaconState.LIT && getAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", 0) == 0) { options("Can you watch this beacon for me?","Nevermind.").also { stage = 10 } } else { npc("Carry on, adventurer.").also { stage = 1000 } @@ -62,7 +61,7 @@ class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) { 13 -> npc("Great, hand them over.").also { stage++ } 14 -> player("Here you go!").also { player.inventory.remove(logs) - session?.setWatcher(index,logs) + setAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", logs.id) stage = 1000 } diff --git a/Server/src/main/content/minigame/barbassault/BarbAssaultArea.kt b/Server/src/main/content/minigame/barbassault/BarbAssaultArea.kt new file mode 100644 index 000000000..7c95758ba --- /dev/null +++ b/Server/src/main/content/minigame/barbassault/BarbAssaultArea.kt @@ -0,0 +1,18 @@ +package content.minigame.barbassault + +import core.api.MapArea +import core.api.getRegionBorders +import core.game.node.entity.Entity +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneType + +class BarbAssaultArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(7509)) + } + + override fun areaEnter(entity: Entity) { + zone.zoneType = ZoneType.BARBARIAN_ASSAULT.id + super.areaEnter(entity) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt b/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt index c0e50104d..d4b31bc8e 100644 --- a/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt +++ b/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt @@ -6,15 +6,19 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable +import core.tools.END_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs -import core.tools.END_DIALOGUE import java.text.SimpleDateFormat import java.time.temporal.ChronoUnit import java.util.* @Initializable class CaptainCainDialogue(player: Player? = null) : DialoguePlugin(player) { + companion object { + const val TORSO_PRICE = 4_500_000 + } + val sdf = SimpleDateFormat("ddMMyyyy") override fun newInstance(player: Player?): DialoguePlugin { return CaptainCainDialogue(player) @@ -38,21 +42,25 @@ class CaptainCainDialogue(player: Player? = null) : DialoguePlugin(player) { 2 -> playerl(FacialExpression.HALF_THINKING, "No, thanks.").also { stage = END_DIALOGUE } } - 10 -> npcl(FacialExpression.FRIENDLY, "Alright, then, that'll be 7,500,000 gold please.").also { stage++ } - 11 -> options("Here you go!","Nevermind.").also { stage++ } + 10 -> npcl(FacialExpression.FRIENDLY, "Alright, then, that'll be %,d gold please.".format(TORSO_PRICE)).also { stage++ } + 11 -> options("Here you go!","Never mind.").also { stage++ } 12 -> when(buttonId){ - 1 -> if(inInventory(player, 995, 7500000)) + 1 -> if(inInventory(player, 995, TORSO_PRICE)) playerl(FacialExpression.FRIENDLY, "Here you go!").also { stage = 20 } else playerl(FacialExpression.HALF_GUILTY, "Actually, I don't have that much.").also { stage = END_DIALOGUE } - 2 -> playerl(FacialExpression.FRIENDLY, "On second thought, nevermind.").also { stage = END_DIALOGUE } + 2 -> playerl(FacialExpression.FRIENDLY, "On second thought, never mind.").also { stage = END_DIALOGUE } } 20 -> { - npcl(FacialExpression.FRIENDLY, "Thank you much, kind sir. And here's your torso.") - if(removeItem(player, Item(995,7500000), Container.INVENTORY)) { - addItem(player, Items.FIGHTER_TORSO_10551, 1) + if (hasSpaceFor(player, Item(Items.FIGHTER_TORSO_10551)) || amountInInventory(player, Items.COINS_995) == TORSO_PRICE) { + npcl(FacialExpression.FRIENDLY, "Thank you much, kind sir. And here's your torso.") + if (removeItem(player, Item(Items.COINS_995, TORSO_PRICE), Container.INVENTORY)) { + addItem(player, Items.FIGHTER_TORSO_10551, 1) + } + } else { + npcl(FacialExpression.FRIENDLY, "Sorry, you don't have space for it! Give my regards to Player Name - he made me check this before I take your cash.") } stage = END_DIALOGUE } diff --git a/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java b/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java index fa8df174c..48b95f68f 100644 --- a/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java +++ b/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java @@ -151,7 +151,6 @@ public final class BarrowsActivityPlugin extends ActivityPlugin { Player player = (Player) e; PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); player.getInterfaceManager().openOverlay(OVERLAY); - setVarp(player, 0, 1); if (getVarp(player, 452) == 0) { shuffleCatacombs(player); } diff --git a/Server/src/main/content/minigame/barrows/RewardChest.kt b/Server/src/main/content/minigame/barrows/RewardChest.kt index d12f48a1e..ccb57c985 100644 --- a/Server/src/main/content/minigame/barrows/RewardChest.kt +++ b/Server/src/main/content/minigame/barrows/RewardChest.kt @@ -78,7 +78,7 @@ object RewardChest { InterfaceContainer.generateItems(player, rewards.toTypedArray(), arrayOf("Examine"), 364, 4, 3, 4) player.interfaceManager.open(Component(Components.TRAIL_REWARD_364)) - BossKillCounter.addtoBarrowsCount(player) + BossKillCounter.addToBarrowsChestCount(player) for (item in rewards) { announceIfRare(player, item) if (!player.inventory.add(item)) { diff --git a/Server/src/main/content/minigame/bountyhunter/MaximillianSackvilleDialogue.kt b/Server/src/main/content/minigame/bountyhunter/MaximillianSackvilleDialogue.kt deleted file mode 100644 index a5b047041..000000000 --- a/Server/src/main/content/minigame/bountyhunter/MaximillianSackvilleDialogue.kt +++ /dev/null @@ -1,120 +0,0 @@ -package content.minigame.bountyhunter - -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.player.Player -import core.game.node.entity.player.link.IronmanMode -import core.plugin.Initializable -import org.rs09.consts.NPCs -import core.game.dialogue.IfTopic -import core.game.dialogue.Topic -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE - -/** - * Provides dialogue tree for Maximillian Sackville, - * the Bounty Hounter roving banker. - * - * @author vddCore - */ -@Initializable -class MaximillianSackvilleDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - START_DIALOGUE -> when { - hasIronmanRestriction(player, IronmanMode.ULTIMATE) -> { - npcl( - FacialExpression.NEUTRAL, - "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + - "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}." - ).also { stage = END_DIALOGUE } - } - - else -> { - npcl( - FacialExpression.NEUTRAL, - "Good day, how may I help you?" - ).also { - if (hasAwaitingGrandExchangeCollections(player)) { - stage++ - } else { - stage += 2 - } - } - } - } - - 1 -> npcl( - FacialExpression.NEUTRAL, - "Before we go any further, I should inform you that you " + - "have items ready for collection from the Grand Exchange." - ).also { stage++ } - - 2 -> playerl( - FacialExpression.ASKING, - "Who are you?" - ).also { stage++ } - - 3 -> npcl( - FacialExpression.NEUTRAL, - "How inconsiderate of me, dear ${if (player.isMale) "sir" else "madam"}. " + - "My name is Maximillian Sackville and I conduct operations here on behalf " + - "of The Bank of Gielinor." - ).also { stage++ } - - 4 -> showTopics( - Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account.", 10), - IfTopic( - FacialExpression.NEUTRAL, - "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", - 11, - hasActivatedSecondaryBankAccount(player) - ), - Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 12), - Topic(FacialExpression.NEUTRAL, "I'd like to collect items.", 13), - Topic(FacialExpression.ASKING, "Aren't you afraid of working in the Wilderness?", 5) - ) - - 5 -> npcl( - FacialExpression.NEUTRAL, - "While the Wilderness is quite a dangerous place, The Bank of Gielinor offers " + - "us - roving bankers - extraordinary benefits for our hard work in hazardous environments." - ).also { stage++ } - - 6 -> npcl( - FacialExpression.NEUTRAL, - "This allows us to provide our services to customers regardless of their current " + - "whereabouts. Our desire to serve is stronger than our fear of the Wilderness." - ).also { stage = END_DIALOGUE } - - 10 -> { - openBankAccount(player) - end() - } - - 11 -> { - toggleBankAccount(player) - - npcl( - FacialExpression.NEUTRAL, - "Naturally. You can now access your ${getBankAccountName(player)} bank account." - ).also { stage = END_DIALOGUE } - } - - 12 -> { - openBankPinSettings(player) - end() - } - - 13 -> { - openGrandExchangeCollectionBox(player) - end() - } - } - - return true - } - - override fun getIds() = intArrayOf(NPCs.BANKER_6538) -} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/UnimplementedCraterArea.kt b/Server/src/main/content/minigame/bountyhunter/UnimplementedCraterArea.kt new file mode 100644 index 000000000..60050f9c7 --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/UnimplementedCraterArea.kt @@ -0,0 +1,75 @@ +package content.minigame.bountyhunter.handlers + +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.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.world.GameWorld + +class UnimplementedCraterArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf( + ZoneBorders(3200, 5632, 3391, 5823) + ) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player && ( + defineAreaBorders()[0].insideBorder(entity) + )) { + kickThemOut(entity) + } + } + + private fun kickThemOut(entity: Player) { + val watchdog = NPC(NPCs.BANKER_6538) + watchdog.isNeverWalks = true + watchdog.isWalks = false + watchdog.location = entity.location + watchdog.init() + entity.lock() + + runTask(watchdog, 1) { + watchdog.moveStep() + watchdog.face(entity) + openDialogue(entity, UnimplementedCraterDialogue(), watchdog) + GameWorld.Pulser.submit(object : Pulse() { + override fun pulse(): Boolean { + if (getAttribute(entity, "teleporting-away", false)) + return true + if (!entity.isActive) + poofClear(watchdog) + if (entity.dialogueInterpreter.dialogue == null || entity.dialogueInterpreter.dialogue.file == null) + openDialogue(entity, UnimplementedCraterDialogue(), watchdog) + return !watchdog.isActive || !entity.isActive + } + }) + } + } + + class UnimplementedCraterDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.WORRIED, "This is unimplemented content, and you are now stuck. Don't worry, I'll get you out of here!").also { stage++ } + 1 -> { + end() + visualize(npc!!, 1818, 343) + sendGraphics(342, player!!.location) + setAttribute(player!!, "teleporting-away", true) + runTask(player!!, 3) { + poofClear(npc!!) + teleport(player!!, Location.create(3179, 3685, 0)) + unlock(player!!) + removeAttribute(player!!, "teleporting-away") + } + } + } + } + } +} + diff --git a/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt b/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt index eed986625..24fdb55cc 100644 --- a/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt +++ b/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt @@ -18,7 +18,6 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.Sounds import rs09.game.content.activity.castlewars.areas.CastleWarsWaitingArea -import java.util.* @Suppress("unused") class CastleWarsListeners : InteractionListener { diff --git a/Server/src/main/content/minigame/castlewars/CastlewarsBook.kt b/Server/src/main/content/minigame/castlewars/CastlewarsBook.kt new file mode 100644 index 000000000..8395ece6a --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/CastlewarsBook.kt @@ -0,0 +1,146 @@ +package content.minigame.castlewars + +import content.data.Quests +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.getAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.system.command.sets.ModelViewerCommandSet.Companion.ATTRIBUTE_MODEL_NUMBER +import core.game.system.command.sets.ModelViewerCommandSet.Companion.ATTRIBUTE_PITCH +import core.game.system.command.sets.ModelViewerCommandSet.Companion.ATTRIBUTE_YAW +import core.game.system.command.sets.ModelViewerCommandSet.Companion.ATTRIBUTE_ZOOM +import core.game.system.command.sets.ModelViewerCommandSet.Companion.DEF_BOOK +import core.game.world.GameWorld +import org.rs09.consts.Items + +class CastlewarsBook : InteractionListener { + + companion object { + private val TITLE = "Castle Wars Manual" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Objective:", 38), + BookLine("The aim is to get into your", 39), + BookLine("opponents castle and take", 40), + BookLine("their team standard. Then", 41), + BookLine("bring that back and capture", 42), + BookLine("it on your teams standard. ", 43), + ), + Page( + BookLine("Toolkit:", 58), + BookLine("This useful item allows you", 59), + BookLine("to repair broken doors and", 60), + BookLine("catapults. Simply use it on", 61), + BookLine("the item to be repaired, or", 62), + BookLine("have one in your inventory", 63), + BookLine("when you select the option,", 64), + BookLine("and you'll rebuild it!", 65) + ) + ), + PageSet( + Page( + BookLine("Bandages:", 43), + BookLine("These can be used to heal", 44), + BookLine("some health and restore some", 45), + BookLine("of your running energy.", 46), + BookLine("You can also use them to", 47), + BookLine("heal fellow players.", 48), + ), + Page( + BookLine("Explosive Potion:", 58), + BookLine("A simple but effective item,", 59), + BookLine("use it to blow up your", 60), + BookLine("opponents catapult and", 61), + BookLine("barricades! It can also be", 62), + BookLine("used to clear the tunnels", 63), + BookLine("under the arena for some,", 64), + BookLine("sneak attacks into your", 65), + BookLine("opponents castle!", 66) + ) + ), + PageSet( + Page( + BookLine("Barricade:", 43), + BookLine("Use these constructs to block", 44), + BookLine("your opponents movement", 45), + BookLine("and prevent them accessing", 46), + BookLine("your castle. Each team can", 47), + BookLine("only have 10 built at any one", 48), + BookLine("time.", 49), + ), + Page( + BookLine("Bucket:", 58), + BookLine("Fill a bucket with water and", 59), + BookLine("you can use it to put out a", 60), + BookLine("burning catapult or barricade,", 61), + BookLine("but be quick or it'll be", 62), + BookLine("destroyed.", 63), + ) + ), + PageSet( + Page( + BookLine("Tinderbox:", 43), + BookLine("Logs aren't all that's", 44), + BookLine("flammable, use a tinderbox to", 45), + BookLine("set light to your opponents", 46), + BookLine("You can also use them to", 47), + BookLine("catapult and barricades.", 48), + ), + Page( + BookLine("Pickaxe:", 58), + BookLine("Use a pickaxe to mine your", 59), + BookLine("way through the tunnels", 60), + BookLine("under the arena for a sneak", 61), + BookLine("attack into your opponents", 62), + BookLine("castle. Don't forget to", 63), + BookLine("collapse the tunnels into your", 64), + BookLine(" own castle though! ", 65), + ) + ), + PageSet( + Page( + BookLine("Catapult:", 43), + BookLine("Use this war machine to", 44), + BookLine("launch rocks at your", 45), + BookLine("opponents. Just give it rough", 46), + BookLine("coordinates and let the rock", 47), + BookLine("fly, just be careful not to hit", 48), + BookLine("your team with it!", 49), + ), + Page( + BookLine("Rock:", 58), + BookLine("Used as ammo for the", 59), + BookLine("catapult, and not much else.", 60), + BookLine("Brings new meaning to the", 61), + BookLine("phrase 'flies like a rock'.", 62), + ) + ), + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_2_27, TITLE, CONTENTS) + BookInterface.clearModelsOnPage(player, BookInterface.FANCY_BOOK_2_27); + BookInterface.setItemOnPage(player, 0, Items.TOOLKIT_4051, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[17], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[17], 768, 192, 1792) + BookInterface.setItemOnPage(player, 1, Items.BANDAGES_4049, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[2], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[2], 768, 192, 1792) + BookInterface.setItemOnPage(player, 1, Items.EXPLOSIVE_POTION_4045, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[17], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[17], 768, 192, 1792) + BookInterface.setItemOnPage(player, 2, Items.BARRICADE_4053, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[2], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[2], 768, 192, 1792) + BookInterface.setItemOnPage(player, 2, Items.BUCKET_OF_WATER_1929, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[17], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[17], 768, 192, 1792) + BookInterface.setItemOnPage(player, 3, Items.TINDERBOX_590, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[2], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[2], 768, 192, 1792) + BookInterface.setItemOnPage(player, 3, Items.BRONZE_PICKAXE_1265, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[17], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[17], 768, 192, 1792) + BookInterface.setModelOnPage(player, 4, 38202, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[4], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[4], 4048, 192, 768) + BookInterface.setItemOnPage(player, 4, Items.ROCK_4043, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[17], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[17], 768, 192, 1792) + return true + } + } + + override fun defineListeners() { + on(Items.CASTLEWARS_MANUAL_4055, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt b/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt index ab1089bdc..c6b336c55 100644 --- a/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt +++ b/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt @@ -65,7 +65,6 @@ abstract class CastleWarsArea : MapArea, LogoutListener, InteractionListener { defineAreaBorders().forEach { border -> if (border.insideBorder(player)) { sendMessage(player, "You can't remove your team's colours") - // TODO: Equipping a cape or helmet causes issues return@onUnequip false } } diff --git a/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt b/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt index 2b32486aa..fb44ea7d9 100644 --- a/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt +++ b/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player import core.game.node.item.Item import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneType import core.tools.Log import core.tools.ticksPerMinute import org.rs09.consts.Components @@ -70,6 +71,7 @@ class CastleWarsGameArea : CastleWarsArea(), TickListener { override fun areaEnter(entity: Entity) { val player = entity as? Player ?: return super.areaEnter(player) + zone.zoneType = ZoneType.CASTLE_WARS.id registerTimer (player, spawnTimer("teleblock", (CastleWars.gameTimeMinutes)*60*2)) if (saradominPlayers.contains(player)) { diff --git a/Server/src/main/content/minigame/duel/DuelSession.java b/Server/src/main/content/minigame/duel/DuelSession.java index e28c9bfab..51b4a6d9b 100644 --- a/Server/src/main/content/minigame/duel/DuelSession.java +++ b/Server/src/main/content/minigame/duel/DuelSession.java @@ -263,7 +263,7 @@ public final class DuelSession extends ComponentPlugin { Player o = getOpposite(p); o.getImpactHandler().setDisabledTicks(6); o.teleport(RandomFunction.getRandomElement(DuelArea.RESPAWN_LOCATIONS)); - boolean victory = type == 0 || type == 2 || type == 1 && p.getImpactHandler().getImpactLog().containsKey(o); + boolean victory = type == 0 || type == 2 || type == 1 && p.getImpactHandler().getPlayerImpactLog().containsKey(o.getDetails().getUid()); fightState = 2; p.removeExtension(DuelSession.class); end(); diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt index 8a74870f1..d619d6539 100644 --- a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt @@ -74,8 +74,8 @@ class FishingTrawlerInteractionHandler : InteractionListener { } on(REWARD_NET, IntType.SCENERY, "inspect"){ player, _ -> - val session: FishingTrawlerSession? = player.getAttribute("ft-session",null) - if(session == null || session.boatSank){ + val rolls = player.getAttribute("/save:ft-rolls", 0) + if (rolls == 0) { player.dialogueInterpreter.sendDialogues(player, core.game.dialogue.FacialExpression.GUILTY,"I'd better not go stealing other people's fish.") return@on true } @@ -162,9 +162,8 @@ class NetLootDialogue(player: Player? = null): core.game.dialogue.DialoguePlugin } override fun open(vararg args: Any?): Boolean { - session = player.getAttribute("ft-session",null) - if(session == null) return false - rolls = ceil(session!!.fishAmount / session!!.players.size.toDouble()).toInt() + rolls = player.getAttribute("/save:ft-rolls", 0) + if (rolls == 0) return false player.dialogueInterpreter.sendOptions("Skip Junk Items?","Yes","No") stage = 0 return true @@ -177,7 +176,7 @@ class NetLootDialogue(player: Player? = null): core.game.dialogue.DialoguePlugin 2 -> TrawlerLoot.addLootAndMessage(player, level, rolls, false) } player.skills.addExperience(Skills.FISHING,(((0.015 * player.skills.getLevel(Skills.FISHING))) * player.skills.getLevel(Skills.FISHING)) * rolls) - player.removeAttribute("ft-session") + player.removeAttribute("ft-rolls") end() return true } diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt index a8e4395e2..3cabb8d72 100644 --- a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt @@ -26,6 +26,7 @@ import core.game.system.command.sets.STATS_BASE import core.tools.secondsToTicks import core.tools.ticksToSeconds import java.util.concurrent.TimeUnit +import kotlin.math.ceil import kotlin.random.Random @@ -153,6 +154,9 @@ class FishingTrawlerSession(val activity: FishingTrawlerActivity? = null) : MapA player.interfaceManager.closeOverlay() player.properties.teleportLocation = Location.create(2666, 3162, 0) player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_GAMES_WON") + val rolls = ceil(session.fishAmount / session.players.size.toDouble()).toInt() + player.removeAttribute("ft-session") + player.setAttribute("/save:ft-rolls", rolls) clearLogoutListener(player, "ft-logout") } session.zone.unregister(getRegionBorders(session.region.id)) diff --git a/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt b/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt index 70ff89220..87ed06dbe 100644 --- a/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt +++ b/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt @@ -1,8 +1,12 @@ package content.minigame.fishingtrawler import content.global.skill.fishing.Fish +import core.api.Container +import core.api.addItem +import core.api.addItemOrDrop import core.api.splitLines import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode import core.game.node.item.GroundItemManager import core.game.node.item.Item import core.game.node.item.WeightedChanceItem @@ -56,25 +60,35 @@ object TrawlerLoot { */ @JvmStatic fun addLootAndMessage(player: Player, fishLevel: Int, rolls: Int, skipJunk: Boolean) { - val frequencyList = listOf>(HashMap(), HashMap(), HashMap()) + if (rolls < 1) return + val frequencyList = listOf>(HashMap(), HashMap(), HashMap()) getLoot(fishLevel, rolls, skipJunk).forEach { - if (!player.bank.add(it)) GroundItemManager.create(it, player) when (it.id) { - in trawlerFishIds -> frequencyList[0].merge(it.name, 1, Int::plus) - in trawlerMisc -> frequencyList[1].merge(it.name, 1, Int::plus) - in junkItems -> frequencyList[2].merge(it.name, 1, Int::plus) + in trawlerFishIds -> frequencyList[0].merge(it.id, 1, Int::plus) + in trawlerMisc -> frequencyList[1].merge(it.id, 1, Int::plus) + in junkItems -> frequencyList[2].merge(it.id, 1, Int::plus) } } - player.sendMessage(colorize("%RYour reward has been sent to your bank:")) - // Extract and join each frequency maps entries as string. Split based on length, then send each line as message. + // Extract and join each frequency map's entries as items frequencyList.forEachIndexed { idx, fMap -> if (fMap.isNotEmpty()) { + // Give reward + fMap.forEach { + if (player.ironmanManager.mode == IronmanMode.ULTIMATE || !addItem(player, it.key, it.value, Container.BANK)) { + val notedIdIfFish = if (idx == 0) it.key + 1 else it.key + addItemOrDrop(player, notedIdIfFish, it.value) + } + } + // Split based on length, then send each line as message splitLines( - fMap.entries.joinToString(prefix = if (idx == 0) "Fish: " else if (idx == 1) "Misc: " else "Junk: ", postfix = ".") { "${it.key}: ${it.value}" }, + fMap.entries.joinToString(prefix = if (idx == 0) "Fish: " else if (idx == 1) "Misc: " else "Junk: ", postfix = ".") { "${Item(it.key).name}: ${it.value}" }, 85 ).forEach { player.sendMessage(it) } } } + if (player.ironmanManager.mode != IronmanMode.ULTIMATE) { + player.sendMessage(colorize("%RYour reward has been sent to your bank:")) + } } private val lootTable = arrayOf( diff --git a/Server/src/main/content/minigame/mta/EnchantSpell.kt b/Server/src/main/content/minigame/mta/EnchantSpell.kt index d6df04fe8..53f05bc13 100644 --- a/Server/src/main/content/minigame/mta/EnchantSpell.kt +++ b/Server/src/main/content/minigame/mta/EnchantSpell.kt @@ -1,6 +1,8 @@ package content.minigame.mta import content.minigame.mta.impl.EnchantingZone.Shapes +import core.ServerConstants +import core.api.replaceSlot import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.combat.spell.SpellType @@ -9,6 +11,8 @@ import core.game.node.entity.player.link.SpellBookManager.SpellBook import core.game.node.entity.player.link.audio.Audio import core.game.node.entity.combat.spell.MagicSpell import core.game.node.entity.combat.spell.Runes +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor import core.game.node.item.Item import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics @@ -47,7 +51,7 @@ class EnchantSpell : MagicSpell { return false } entity.interfaceManager.setViewedTab(6) - val enchanted = jewellery?.getOrDefault(target.id,null) + var enchanted = jewellery?.getOrDefault(target.id,null) if (enchanted == null) { entity.packetDispatch.sendMessage("You can't use this spell on this item.") @@ -56,12 +60,15 @@ class EnchantSpell : MagicSpell { if (!meetsRequirements(entity, true, true)) { return false } - - if (entity.inventory.remove(target)) { - visualize(entity, target) - entity.inventory.add(enchanted) + if (enchanted.id == Items.RING_OF_WEALTH_2572 && ServerConstants.RING_OF_WEALTH_TELEPORT) { + enchanted = Item(Items.RING_OF_WEALTH_14638) } + visualize(entity, target) + val ret = replaceSlot(entity, target.slot, enchanted) + if (ret != target) { + PlayerMonitor.log(entity, LogType.DUPE_ALERT, "Unknown slot-replacement problem when enchanting jewellery (adding $enchanted replaced $ret rather than $target)") + } //MTA-Specific Code if (entity.zoneMonitor.isInZone("Enchantment Chamber")) { @@ -184,10 +191,10 @@ class EnchantSpell : MagicSpell { SpellBook.MODERN.register(51, EnchantSpell(68, 78.0, mapOf( //Begin Jewelry Enchantment - Items.DRAGONSTONE_RING_1645 to Item(14646), - Items.DRAGON_NECKLACE_1664 to Item(Items.SKILLS_NECKLACE4_11105), - Items.DRAGONSTONE_AMMY_1702 to Item(Items.AMULET_OF_GLORY4_1712), - Items.DRAGON_BRACELET_11115 to Item(Items.COMBAT_BRACELET4_11118), + Items.DRAGONSTONE_RING_1645 to Item(Items.RING_OF_WEALTH_2572), + Items.DRAGON_NECKLACE_1664 to Item(Items.SKILLS_NECKLACE_11113), + Items.DRAGONSTONE_AMMY_1702 to Item(Items.AMULET_OF_GLORY_1704), + Items.DRAGON_BRACELET_11115 to Item(Items.COMBAT_BRACELET_11126), //Begin MTA-Specific Enchantments Items.CUBE_6899 to Item(Items.ORB_6902), Items.CYLINDER_6898 to Item(Items.ORB_6902), diff --git a/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java b/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java index e2d496492..72728d1e6 100644 --- a/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java +++ b/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java @@ -4,6 +4,7 @@ import content.minigame.mta.impl.TelekineticZone; import core.game.interaction.SpecialGroundItems; import core.game.node.Node; import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatSwingHandler; import core.game.node.entity.combat.spell.SpellType; import core.game.node.entity.combat.spell.SpellBlocks; import core.game.node.entity.impl.Projectile; @@ -24,7 +25,7 @@ import core.game.global.action.PickupHandler; import core.game.world.GameWorld; import org.rs09.consts.Sounds; -import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.*; /** * Represents the telekenitic grab spell. @@ -176,8 +177,12 @@ public final class TelekineticGrabSpell extends MagicSpell { } if (entity instanceof Player) { final Player player = (Player) entity; - if (!player.getInventory().hasSpaceFor(((Item) item))) { - player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + if (!CombatSwingHandler.isProjectileClipped(player, item, false)) { + sendMessage(player, "I can't reach that."); //TODO authentic message? + return false; + } + if (!hasSpaceFor(player, item)) { + sendMessage(player, "You don't have enough inventory space."); return false; } if (!PickupHandler.canTake(player, item, 1)) { diff --git a/Server/src/main/content/minigame/mta/impl/TelekineticZone.java b/Server/src/main/content/minigame/mta/impl/TelekineticZone.java index 1ff0f9b7e..a810548d6 100644 --- a/Server/src/main/content/minigame/mta/impl/TelekineticZone.java +++ b/Server/src/main/content/minigame/mta/impl/TelekineticZone.java @@ -32,7 +32,7 @@ import content.minigame.mta.MTAZone; /** * Handles the telekinetic zone. - * @author Vexia + * @author Vexia, Player Name */ public class TelekineticZone extends MTAZone { @@ -302,7 +302,7 @@ public class TelekineticZone extends MTAZone { } Location next = statue.getLocation().transform(dir, 1); Path path = Pathfinder.find(statue.getLocation(), next); - boolean end = !path.isSuccessful() || path.isMoveNear() || path.getPoints().size() != 1; + boolean end = !path.isSuccessful() || path.isMoveNear() || path.getPoints().size() > 2; if (end) { return true; } diff --git a/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java b/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java index 21cc7fce5..5ace493bb 100644 --- a/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java +++ b/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java @@ -80,7 +80,7 @@ public final class PCLanderZone extends MapZone { for (PestControlActivityPlugin a : activities) { if (a.getWaitingPlayers().remove(e)) { if (logout) { - e.getProperties().setTeleportLocation(a.getLeaveLocation()); + e.setLocation(a.getLeaveLocation()); } break; } diff --git a/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java b/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java index ffab29af7..9140bfda2 100644 --- a/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java +++ b/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java @@ -15,6 +15,8 @@ import core.game.node.item.Item; import core.plugin.Plugin; import core.tools.RandomFunction; +import static core.api.ContentAPIKt.getStatLevel; + /** * Represents the pest control reward interface. * @author 'Vexia @@ -185,20 +187,36 @@ public final class PCRewardInterface extends ComponentPlugin { } /** - * Method used to calculate the experience the player can recieve in this - * skill. + * Method used to calculate the experience the player can receive in this skill. * @param player the player. * @return the experience as an integer. */ - public static double calculateExperience(final Player player, final int skillId) { - int level = player.getSkills().getStaticLevel(skillId); - double divideBy = 30;//17.5-33 ideal range - if (skillId == Skills.PRAYER) { - divideBy = 67;// 34-75 ideal range - } else if (skillId == Skills.MAGIC || skillId == Skills.RANGE) { - divideBy = 29;//19.1-31 ideal range + public static int calculateExperience(final Player player, final int skillId, final int points) { + int level = getStatLevel(player, skillId); + int N = 0; + switch (skillId) { + case Skills.PRAYER: + N = 18; + break; + case Skills.MAGIC: + case Skills.RANGE: + N = 32; + break; + case Skills.ATTACK: + case Skills.STRENGTH: + case Skills.DEFENCE: + case Skills.HITPOINTS: + N = 35; + break; } - return (int) ((level * level) / divideBy) * (player.getSkills().experienceMutiplier / 2); + int xpPerPoint = (int) ((double) (level * level) / 600) * N; + double bonus = 1.0; + if (points >= 100) { + bonus = 1.1; + } else if (points >= 10) { + bonus = 1.01; + } + return (int) (points * xpPerPoint * bonus); } /** @@ -207,7 +225,7 @@ public final class PCRewardInterface extends ComponentPlugin { * @param skillId the skillId. * @return the string to send. */ - public static final String getSkillCondition(final Player player, final int skillId) { + public static String getSkillCondition(final Player player, final int skillId) { if (player.getSkills().getStaticLevel(skillId) < 25) { return RED + "Must reach level 25 first."; } @@ -221,7 +239,7 @@ public final class PCRewardInterface extends ComponentPlugin { * @return the string. */ public static String getSkillXp(final Player player, int skillId) { - return Skills.SKILL_NAME[skillId] + " - " + (int) calculateExperience(player, skillId) + " xp"; + return Skills.SKILL_NAME[skillId] + " - " + calculateExperience(player, skillId, 1) + " xp"; } /** @@ -229,7 +247,7 @@ public final class PCRewardInterface extends ComponentPlugin { * @param skill the skill index. * @return the skill child id. */ - public static final int getSkillChild(final int skill) { + public static int getSkillChild(final int skill) { return SKILL_HEADER[skill]; } @@ -264,7 +282,7 @@ public final class PCRewardInterface extends ComponentPlugin { * Method used to confirm the reward. * @param player the player. */ - public final void confirm(final Player player) { + public void confirm(final Player player) { if (!hasReward(player)) { player.getPacketDispatch().sendMessage("Please choose a reward."); return; @@ -281,9 +299,9 @@ public final class PCRewardInterface extends ComponentPlugin { if (player.getSavedData().getActivityData().getPestPoints() >= points) { player.getSavedData().getActivityData().decreasePestPoints(points); if (reward.isSkillReward()) { - final double experience = ((int) calculateExperience(player, reward.getSkill()) * points); + int experience = calculateExperience(player, reward.getSkill(), points); player.getSkills().addExperience(reward.getSkill(), experience); - message = "The Void Knight has granted you " + (int) (experience * player.getSkills().experienceMutiplier) + " " + reward.getName() + "."; + message = "The Void Knight has granted you " + experience + " " + reward.getName() + "."; } else { if (!reward.checkItemRequirement(player, option)) { return; diff --git a/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt b/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt index b54f8dd36..a295a8795 100644 --- a/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt +++ b/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt @@ -13,6 +13,7 @@ import org.rs09.consts.Items import core.game.dialogue.DialogueFile import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.data.Quests /** * Adds functionality to the pharoah's scepter @@ -23,7 +24,7 @@ class PharaohSceptre : InteractionListener { val SCEPTRES = intArrayOf(Items.PHARAOHS_SCEPTRE_9044, Items.PHARAOHS_SCEPTRE_9046, Items.PHARAOHS_SCEPTRE_9048, Items.PHARAOHS_SCEPTRE_9050) on(SCEPTRES, IntType.ITEM, "teleport", "operate"){ player, node -> - if (!hasRequirement(player, "Icthlarin's Little Helper")) + if (!hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)) return@on true val sceptre = node.asItem() diff --git a/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt b/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt index 4739bf5c2..5ebad5751 100644 --- a/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt +++ b/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt @@ -23,6 +23,7 @@ import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.game.world.GameWorld import core.plugin.ClassScanner +import content.data.Quests class GardenObjectsPlugin : InteractionListener { @@ -503,7 +504,7 @@ class GardenObjectsPlugin : InteractionListener { override fun open(vararg args: Any): Boolean { npc = args[0] as NPC - quest = player.questRepository.getQuest("Prince Ali Rescue") + quest = player.questRepository.getQuest(Quests.PRINCE_ALI_RESCUE) when (quest!!.getStage(player)) { 100 -> { interpreter.sendDialogues(player, null, "I'd like to talk about sq'irks.") @@ -819,7 +820,7 @@ class GardenObjectsPlugin : InteractionListener { stage = 10 } 2 -> { - interpreter.sendDialogues(player, null, "What is th second thing you need?") + interpreter.sendDialogues(player, null, "What is the second thing you need?") stage = 20 } 3 -> { diff --git a/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java b/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java index 4e6be91c4..bc3aa169b 100644 --- a/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java +++ b/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java @@ -11,6 +11,7 @@ import core.game.world.map.Location; import core.game.world.update.flag.context.Graphics; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Dialogue for Sorceress Apprentice @@ -238,7 +239,7 @@ public class SorceressApprenticeDialogue extends DialoguePlugin { } public static void teleport(final NPC npc, final Player player) { - if (!hasRequirement(player, "Prince Ali Rescue")) + if (!hasRequirement(player, Quests.PRINCE_ALI_RESCUE)) return; npc.faceTemporary(player, 4); npc.graphics(new Graphics(108)); diff --git a/Server/src/main/content/minigame/troublebrewing/TroubleBrewingArea.kt b/Server/src/main/content/minigame/troublebrewing/TroubleBrewingArea.kt new file mode 100644 index 000000000..55a299b4e --- /dev/null +++ b/Server/src/main/content/minigame/troublebrewing/TroubleBrewingArea.kt @@ -0,0 +1,18 @@ +package content.minigame.troublebrewing + +import core.api.MapArea +import core.api.getRegionBorders +import core.game.node.entity.Entity +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneType + +class TroubleBrewingArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(15150)) + } + + override fun areaEnter(entity: Entity) { + zone.zoneType = ZoneType.TROUBLE_BREWING.id + super.areaEnter(entity) + } +} diff --git a/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt b/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt index 787e1fc5c..04fe7686a 100644 --- a/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt +++ b/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt @@ -3,8 +3,21 @@ package content.minigame.vinesweeper import BlinkinDialogue import FarmerDialogue.Companion.FARMER_FLAG_LINES import WinkinDialogue +import content.minigame.vinesweeper.Vinesweeper.Companion.FARMERS +import content.minigame.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS +import content.minigame.vinesweeper.Vinesweeper.Companion.HOLES +import content.minigame.vinesweeper.Vinesweeper.Companion.NUMBERS +import content.minigame.vinesweeper.Vinesweeper.Companion.RABBITS +import content.minigame.vinesweeper.Vinesweeper.Companion.SEED_LOCS +import content.minigame.vinesweeper.Vinesweeper.Companion.populateSeeds +import content.minigame.vinesweeper.Vinesweeper.Companion.scheduleNPCs +import content.minigame.vinesweeper.Vinesweeper.Companion.sendPoints import core.api.* +import core.cache.def.impl.ItemDefinition import core.game.component.Component +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener import core.game.interaction.MovementPulse import core.game.node.entity.Entity import core.game.node.entity.combat.DeathTask @@ -18,6 +31,8 @@ import core.game.node.item.Item import core.game.node.scenery.Scenery import core.game.node.scenery.SceneryBuilder import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.GameWorld.ticks import core.game.world.map.Location import core.game.world.map.RegionManager import core.game.world.map.zone.ZoneBorders @@ -25,21 +40,9 @@ import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics import core.plugin.Initializable import core.tools.RandomFunction -import content.minigame.vinesweeper.Vinesweeper.Companion.FARMERS -import content.minigame.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS -import content.minigame.vinesweeper.Vinesweeper.Companion.HOLES -import content.minigame.vinesweeper.Vinesweeper.Companion.NUMBERS -import content.minigame.vinesweeper.Vinesweeper.Companion.RABBITS -import content.minigame.vinesweeper.Vinesweeper.Companion.SEED_LOCS -import content.minigame.vinesweeper.Vinesweeper.Companion.populateSeeds -import content.minigame.vinesweeper.Vinesweeper.Companion.scheduleNPCs -import content.minigame.vinesweeper.Vinesweeper.Companion.sendPoints -import core.game.interaction.InteractionListener -import core.game.interaction.IntType -import core.game.interaction.InterfaceListener -import core.game.world.GameWorld -import core.game.world.GameWorld.ticks import org.rs09.consts.* +import kotlin.math.max +import kotlin.math.min import org.rs09.consts.Graphics as Gfx import org.rs09.consts.Scenery as Sceneries @@ -60,9 +63,9 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { if(entity is Player) { entity.interfaceManager.closeOverlay() if(!logout) { - entity.sendMessage("Winkin's Farm thanks you for your visit.") - entity.sendMessage("Leftover ogleroots and flags have been returned to the establishment.") - entity.sendMessage("You have been reimbursed at a rate of 10gp per ogleroot and the flags have been collected.") + sendMessage(entity, "Winkin's Farm thanks you for your visit.") + sendMessage(entity, "Leftover ogleroots and flags have been returned to the establishment.") + sendMessage(entity, "You have been reimbursed at a rate of 10gp per ogleroot and the flags have been collected.") val flags = entity.inventory.getAmount(Item(Items.FLAG_12625)) if(flags > 0) { entity.setAttribute("/save:vinesweeper:stored-flags", flags) @@ -82,7 +85,12 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { on(Sceneries.PORTAL_29534, IntType.SCENERY, "enter") { player, _ -> val x = player.getAttribute("vinesweeper:return-tele:x", 3052) val y = player.getAttribute("vinesweeper:return-tele:y", 3304) - teleport(player, Location(x, y)) + val loc = Location(x, y) + if (ZoneBorders.forRegion(11060).insideBorder(loc) && !ItemDefinition.canEnterEntrana(player)) { + sendMessage(player, "The power of Saradomin prevents you from taking armour or weaponry to Entrana."); + return@on true + } + teleport(player, loc) return@on true } on(SIGNS, IntType.SCENERY, "read") { player, node -> @@ -210,7 +218,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { player.packetDispatch.sendInterfaceConfig(686, 60, true) val level = player.skills.getStaticLevel(Skills.FARMING) // TODO: more precise formula - val points_per_xp = if (level < 40) { 2.0*(40.0 - level.toDouble())/10.0 } else { 1.0 } + val points_per_xp = if (level < 40) { max(1.0, 2.0*(40.0 - level.toDouble())/10.0) } else { 1.0 } val points = player.getAttribute("vinesweeper:points", 0) val xp = points / points_per_xp player.skills.addExperience(Skills.FARMING, xp) @@ -369,7 +377,10 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { } fun populateSeeds() { - while(SEED_LOCS.size < MAX_SEEDS) { + val holes = countHoles() + val seeds = min(1.0 * MAX_SEEDS, holes * 0.13).toInt() + var tries = 0 // Prevent the while loop from crashing the server + while(SEED_LOCS.size < seeds && tries++ < 1000) { val loc = VINESWEEPER_BORDERS.getRandomLoc() val scenery = getScenery(loc) if(scenery != null && HOLES.contains(scenery.id)) { @@ -378,9 +389,23 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { } } - fun faceHole(player: Player, hole: Scenery) { - + private fun countHoles(): Int { + val northEastX = VINESWEEPER_BORDERS.northEastX + val northEastY = VINESWEEPER_BORDERS.northEastY + val southWestX = VINESWEEPER_BORDERS.southWestX + val southWestY = VINESWEEPER_BORDERS.southWestY + var holeCount = 0 + for (x in southWestX .. northEastX){ + for (y in southWestY .. northEastY){ + val scenery = getScenery(x, y, 0) + if(scenery != null && HOLES.contains(scenery.id)) { + holeCount++ + } + } + } + return holeCount } + fun plantFlag(player: Player, hole: Scenery) { if(player.inventory.remove(Item(Items.FLAG_12625, 1))) { player.lock() @@ -498,8 +523,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { sendNPCDialogue(player, npc.id, "I can't do that, you're teleblocked!", core.game.dialogue.FacialExpression.OLD_ANGRY1) return } - npc.animate(Animation(437)) - npc.faceTemporary(player, 1) + // https://youtu.be/61jVjmXf8tU?t=45 npc.graphics(Graphics(108)) player.lock() playAudio(player, Sounds.CURSE_ALL_125, 0, 1) diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AchiettiesDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AchiettiesDialogue.kt deleted file mode 100644 index a4585b87e..000000000 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AchiettiesDialogue.kt +++ /dev/null @@ -1,39 +0,0 @@ -import core.api.openDialogue -import core.game.dialogue.DialogueBuilder -import core.game.dialogue.DialogueBuilderFile -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.player.Player -import core.plugin.Initializable -import org.rs09.consts.NPCs - -/** - * @author qmqz - * @author Trident101 - */ - -@Initializable -class AchiettiesDialogue(player: Player? = null) : DialoguePlugin(player){ - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - openDialogue(player, AchiettiesDialogueFile(), npc) - return true - } - - override fun newInstance(player: Player?): DialoguePlugin { - return AchiettiesDialogue(player) - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.ACHIETTIES_796) - } -} - -class AchiettiesDialogueFile : DialogueBuilderFile() { - - override fun create(b: DialogueBuilder) { - b.defaultDialogue().npcl(FacialExpression.FRIENDLY, - "Greetings. Welcome to the Heroes' Guild." - ) - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt index 7984ceed8..2e1ca6b44 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt @@ -20,8 +20,8 @@ class BernaldDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { // // Garden of Tranquility has not been implemented. -// if(hasRequirement(player!!, "Garden of Tranquility")) { -// if (isQuestComplete(player!!, DeathPlateau.questName)) { +// if(hasRequirement(player!!, Quests.GARDEN_OF_TRANQUILITY)) { +// if (isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { // when (stage) { // 0 -> playerl(FacialExpression.FRIENDLY, "How are your grapes coming along?").also { stage++ } // 1 -> npc(FacialExpression.FRIENDLY, "Marvellous, thanks to your help, " + player.username + "!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt index ca982ff6c..8a885cd94 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** * Breoca Dialogue @@ -18,7 +19,7 @@ import org.rs09.consts.NPCs @Initializable class BreocaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - if(isQuestComplete(player!!, "Death Plateau")) { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt index 6eae6fa18..006641ebd 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** * Ceolburg Dialogue @@ -18,7 +19,7 @@ import org.rs09.consts.NPCs @Initializable class CeolburgDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - if(isQuestComplete(player!!, "Death Plateau")) { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt index 430da5566..2724f9c19 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt @@ -1,8 +1,7 @@ package content.region.asgarnia.burthorpe.dialogue -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau +import content.data.Quests import content.region.asgarnia.burthorpe.quest.deathplateau.DenulthDialogueFile -import content.region.asgarnia.burthorpe.quest.trollstronghold.TrollStronghold import core.api.isQuestComplete import core.api.isQuestInProgress import core.api.openDialogue @@ -25,7 +24,7 @@ class DenulthDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { // When Troll Stronghold is complete - if (isQuestComplete(player!!, TrollStronghold.questName)) { + if (isQuestComplete(player!!, Quests.TROLL_STRONGHOLD)) { when(stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } 1 -> npcl(FacialExpression.HAPPY, "Welcome back friend!").also { stage++ } @@ -49,13 +48,13 @@ class DenulthDialogue(player: Player? = null) : DialoguePlugin(player) { } // Troll Stronghold in progress - if (isQuestInProgress(player!!, TrollStronghold.questName, 1, 99)) { + if (isQuestInProgress(player!!, Quests.TROLL_STRONGHOLD, 1, 99)) { openDialogue(player!!, content.region.asgarnia.burthorpe.quest.trollstronghold.DenulthDialogueFile(), npc) return true } // When Death Plateau is completed, start Troll Stronghold - if (isQuestComplete(player!!, DeathPlateau.questName)) { + if (isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when(stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } 1 -> npcl(FacialExpression.HAPPY, "Welcome back friend!").also { stage++ } @@ -78,7 +77,7 @@ class DenulthDialogue(player: Player? = null) : DialoguePlugin(player) { ) 16 -> npcl(FacialExpression.HAPPY, "God speed friend! I would send some of my men with you, but none of them are brave enough to follow.").also { stage = END_DIALOGUE - setQuestStage(player!!, TrollStronghold.questName, 1) + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 1) } 20 -> npcl(FacialExpression.ANGRY, "You are right citizen. The White Knights have taken advantage of the old and weak king, they control most of Asgarnia, including Falador. However they do not control Burthorpe!").also { stage++ } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt index 6346fc9f6..73759083a 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt @@ -1,15 +1,16 @@ package content.region.asgarnia.burthorpe.dialogue -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau -import content.region.asgarnia.burthorpe.quest.trollstronghold.TrollStronghold +import content.data.Quests import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.dialogue.Topic import core.game.node.entity.player.Player +import core.game.node.item.Item import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import org.rs09.consts.Items import org.rs09.consts.NPCs /** @@ -24,11 +25,12 @@ class DunstanDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { // When Troll Stronghold is complete - if (isQuestComplete(player!!, TrollStronghold.questName)) { + if (isQuestComplete(player!!, Quests.TROLL_STRONGHOLD)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } 1 -> npcl(FacialExpression.FRIENDLY, "Hi! What can I do for you?").also { stage++ } 2 -> showTopics( + Topic(FacialExpression.THINKING, "Can you put some spikes on my Climbing boots?", 30), Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), Topic(FacialExpression.FRIENDLY, "How is your son getting on?", 15), @@ -42,22 +44,54 @@ class DunstanDialogue(player: Player? = null) : DialoguePlugin(player) { 15 -> npcl(FacialExpression.FRIENDLY, "He is getting on fine! He has just been promoted to Sergeant! I'm really proud of him!").also { stage++ } 16 -> playerl(FacialExpression.FRIENDLY, "I'm happy for you!").also { stage++ } 17 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 2 } + 30 -> playerl(FacialExpression.FRIENDLY, "Can you put some spikes on my Climbing boots?").also { stage++ } + 31 -> npcl(FacialExpression.NEUTRAL,"For you, no problem.").also { stage++ } + 32 -> npc(FacialExpression.THINKING, "Do you realise that you can only use the Climbing", "boots right now? The Spiked boots can only be used in", "the Icelands but no ones been able to get there for", "years!").also { stage++ } + 33 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, but I still want them.", 40, true), + Topic(FacialExpression.NEUTRAL, "Oh OK, I'll leave them thanks.", 43), + ) + 40 -> { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.") + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + npcl(FacialExpression.NEUTRAL,"Sorry, I'll need an iron bar to make the spikes.") + stage = 2 + } else { + playerl(FacialExpression.NEUTRAL,"I don't have them on me.") + stage = 2 + } + } + 41 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { stage++ + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 43 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { + stage = 2 + } } return true } // Troll Stronghold in progress - if (isQuestInProgress(player!!, TrollStronghold.questName, 1, 99)) { + if (isQuestInProgress(player!!, Quests.TROLL_STRONGHOLD, 1, 99)) { openDialogue(player!!, content.region.asgarnia.burthorpe.quest.trollstronghold.DunstanDialogueFile(), npc) return true } // When Death Plateau is complete - if (isQuestComplete(player!!, DeathPlateau.questName)) { + if (isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } 1 -> npcl(FacialExpression.FRIENDLY, "Hi! What can I do for you?").also { stage++ } 2 -> showTopics( + Topic(FacialExpression.THINKING, "Can you put some spikes on my Climbing boots?", 30), Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), Topic(FacialExpression.FRIENDLY, "How is your son getting on?", 15), @@ -70,12 +104,43 @@ class DunstanDialogue(player: Player? = null) : DialoguePlugin(player) { 15 -> npcl(FacialExpression.SAD, "He was captured by those cursed trolls! I don't know what to do. Even the imperial guard are too afraid to go rescue him.").also { stage++ } 16 -> playerl(FacialExpression.ASKING, "What happened?").also { stage++ } 17 -> npcl(FacialExpression.SAD, "Talk to Denulth, he can tell you all about it. Anything else before I get on with my work?").also { stage = 2 } + 30 -> npcl(FacialExpression.NEUTRAL,"For you, no problem.").also { stage++ } + 31 -> npc(FacialExpression.THINKING, "Do you realise that you can only use the Climbing", "boots right now? The Spiked boots can only be used in", "the Icelands but no ones been able to get there for", "years!").also { stage++ } + 32 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, but I still want them.", 40, true), + Topic(FacialExpression.NEUTRAL, "Oh OK, I'll leave them thanks.", 43), + ) + 40 -> { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.") + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + npcl(FacialExpression.NEUTRAL,"Sorry, I'll need an iron bar to make the spikes.") + stage = 2 + } else { + playerl(FacialExpression.NEUTRAL,"I don't have them on me.") + stage = 2 + } + } + 41 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { + stage = 43 + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 43 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { + stage = 2 + } } return true } // Death Plateau in progress - if (isQuestInProgress(player!!, DeathPlateau.questName, 21, 24)) { + if (isQuestInProgress(player!!, Quests.DEATH_PLATEAU, 21, 24)) { // Call the dialogue file for Dunstan from the deathplateau quest folder. openDialogue(player!!, content.region.asgarnia.burthorpe.quest.deathplateau.DunstanDialogueFile(), npc) return true diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt index 9a200f9e5..e59b3d907 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.dialogue +import core.ServerConstants import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -21,7 +22,7 @@ import core.tools.START_DIALOGUE class EmeraldBenedictDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { when (stage) { - START_DIALOGUE -> if(hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + START_DIALOGUE -> if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { npcl( FacialExpression.ANNOYED, "Get lost, tin can." @@ -53,6 +54,12 @@ class EmeraldBenedictDialogue(player: Player? = null) : DialoguePlugin(player) { 4, hasActivatedSecondaryBankAccount(player) ), + IfTopic( + FacialExpression.ASKING, + "Yes, but can you open a secondary bank account for me?", + 7, + ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player) + ), Topic(FacialExpression.ASKING, "Yes, but can you show me my PIN settings?", 5), Topic(FacialExpression.ASKING, "Yes, but can you show me my collection box?", 6), Topic(FacialExpression.ANNOYED, "Yes, thanks. And I'll keep hold of it too.", END_DIALOGUE) @@ -68,7 +75,7 @@ class EmeraldBenedictDialogue(player: Player? = null) : DialoguePlugin(player) { npcl( FacialExpression.SUSPICIOUS, "Sure thing. Feel free to rummage through whatever's in your ${getBankAccountName(player)} now." - ).also { stage = END_DIALOGUE } + ).also { stage = 2 } } 5 -> { @@ -80,10 +87,24 @@ class EmeraldBenedictDialogue(player: Player? = null) : DialoguePlugin(player) { openGrandExchangeCollectionBox(player) end() } + + 7 -> { + npcl( + FacialExpression.SUSPICIOUS, + "Sure, just give me five million in gold and I'll take care of it." + ).also { stage++ } + } + + 8 -> { + playerl( + FacialExpression.SUSPICIOUS, + "On second thought, I think I'll ask somebody more reputable..." + ).also { stage = END_DIALOGUE } + } } return true } override fun getIds(): IntArray = intArrayOf(NPCs.EMERALD_BENEDICT_2271) -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt index e9ccfc492..4fb041be6 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt @@ -1,6 +1,6 @@ package content.region.asgarnia.burthorpe.dialogue -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau +import content.data.Quests import content.region.asgarnia.burthorpe.quest.deathplateau.EohricDialogueFile import core.api.getQuestStage import core.api.openDialogue @@ -19,7 +19,7 @@ import org.rs09.consts.NPCs @Initializable class EohricDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { - if (getQuestStage(player!!, DeathPlateau.questName) >= 5) { + if (getQuestStage(player!!, Quests.DEATH_PLATEAU) >= 5) { // Call the dialogue file for Eohric from the deathplateau quest folder. openDialogue(player!!, EohricDialogueFile(), npc) return true diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt index b98a66184..62d510ac1 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt @@ -1,14 +1,12 @@ package content.region.asgarnia.burthorpe.dialogue -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau +import content.data.Quests import content.region.asgarnia.burthorpe.quest.deathplateau.HaroldDialogueFile import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.world.update.flag.context.Animation -import core.game.world.update.flag.context.Graphics import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE @@ -23,7 +21,7 @@ import org.rs09.consts.NPCs @Initializable class HaroldDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { - if (isQuestInProgress(player!!, DeathPlateau.questName, 10, 29)) { + if (isQuestInProgress(player!!, Quests.DEATH_PLATEAU, 10, 29)) { // Call the dialogue file for Harold from the deathplateau quest folder. openDialogue(player!!, HaroldDialogueFile(), npc) } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HelemosDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HelemosDialogue.kt new file mode 100644 index 000000000..aede4cd5f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HelemosDialogue.kt @@ -0,0 +1,47 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class HelemosDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, HelemosDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HelemosDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HELEMOS_797) + } +} +class HelemosDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc("Welcome to the Heroes' Guild!") + .options() + .let { optionBuilder -> + optionBuilder.option("So do you sell anything here?") + .playerl("So do you sell anything good here?") + .npcl("Why yes! We DO run an exclusive shop for our members!") + .endWith { _, player -> + openNpcShop(player, NPCs.HELEMOS_797) + end() + } + optionBuilder.option_playerl("So what can I do here?") + .npcl("Look around... there are all sorts of things to keep our guild members entertained!") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt index b8361c40a..6b0116cd3 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** * Hild Dialogue @@ -18,7 +19,7 @@ import org.rs09.consts.NPCs @Initializable class HildDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - if(isQuestComplete(player!!, "Death Plateau")) { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt index 2a7f3f280..3e3b73b90 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** * Hygd Dialogue @@ -18,7 +19,7 @@ import org.rs09.consts.NPCs @Initializable class HygdDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - if(isQuestComplete(player!!, "Death Plateau")) { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/JadeDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/JadeDialogue.kt deleted file mode 100644 index 85ebda973..000000000 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/JadeDialogue.kt +++ /dev/null @@ -1,106 +0,0 @@ -package content.region.asgarnia.burthorpe.dialogue - -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.player.Player -import core.game.node.entity.player.link.IronmanMode -import core.plugin.Initializable -import org.rs09.consts.NPCs -import core.game.dialogue.IfTopic -import core.game.dialogue.Topic -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE - -/** - * Provides a dialogue tree for Jade inside Warriors' Guild. - * - * @author vddCore - */ -@Initializable -class JadeDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - START_DIALOGUE -> if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { - npcl( - FacialExpression.NEUTRAL, - "Greetings, warrior. I wish I could help you, but " + - "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}." - ).also { stage = END_DIALOGUE } - } - else { - npcl( - FacialExpression.NEUTRAL, - "Greetings warrior, how may I help you?" - ).also { - if (hasAwaitingGrandExchangeCollections(player)) { - stage++ - } else { - stage += 2 - } - } - } - - 1 -> npcl( - FacialExpression.NEUTRAL, - "Before we go any further, I should inform you that you " + - "have items ready for collection from the Grand Exchange." - ).also { stage++ } - - 2 -> showTopics( - Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account, please.", 10), - IfTopic( - FacialExpression.NEUTRAL, - "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", - 13, - hasActivatedSecondaryBankAccount(player) - ), - Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 11), - Topic(FacialExpression.NEUTRAL, "I'd like to see my collection box.", 12), - Topic(FacialExpression.ASKING, "How long have you worked here?", 3) - ) - - 3 -> npcl( - FacialExpression.FRIENDLY, - "Oh, ever since the Guild opened. I like it here." - ).also { stage++ } - - 4 -> playerl( - FacialExpression.ASKING, - "Why's that?" - ).also { stage++ } - - 5 -> npcl( - FacialExpression.FRIENDLY, - "Well... What with all these warriors around, there's not much chance of my bank being robbed, is there?" - ).also { stage = 2 } - - 10 -> { - openBankAccount(player) - end() - } - - 11 -> { - openBankPinSettings(player) - end() - } - - 12 -> { - openGrandExchangeCollectionBox(player) - end() - } - - 13 -> { - toggleBankAccount(player) - npcl( - FacialExpression.FRIENDLY, - "Of course! Your ${getBankAccountName(player)} account is now active!" - ).also { stage = END_DIALOGUE } - } - } - - return true - } - - override fun getIds(): IntArray = intArrayOf(NPCs.JADE_4296) -} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt index 514035edc..0606c4542 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** @@ -19,7 +20,7 @@ import org.rs09.consts.NPCs @Initializable class OcgaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - if(isQuestComplete(player!!, "Death Plateau")) { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt index 4cd42579c..0570a0d24 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** * Penda Dialogue @@ -18,7 +19,7 @@ import org.rs09.consts.NPCs @Initializable class PendaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - if(isQuestComplete(player!!, "Death Plateau")) { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..5).toIntArray().random() } 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt index 84b26124e..5c0a23214 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt @@ -8,9 +8,8 @@ import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests /** * Unferth Dialogue @@ -37,7 +36,7 @@ class UnferthDialogue(player: Player? = null) : DialoguePlugin(player) { class UnferthDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onPredicate { player -> isQuestComplete(player, "A Tail of Two Cats") }.playerl( + b.onPredicate { player -> isQuestComplete(player, Quests.A_TAIL_OF_TWO_CATS) }.playerl( FacialExpression.FRIENDLY, "Hi Unferth. How are you doing?" ).npcl( FacialExpression.GUILTY, "It's just not the same without Bob around." diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java index 5c3900341..60e6c86fd 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.handlers; +import core.ServerConstants; import core.cache.def.impl.SceneryDefinition; import content.data.EnchantedJewellery; import core.game.global.action.DoorActionHandler; @@ -18,10 +19,15 @@ import core.plugin.Initializable; import core.plugin.ClassScanner; import static core.api.ContentAPIKt.hasRequirement; +import static core.api.ContentAPIKt.sendMessage; + +import content.data.Quests; +import org.rs09.consts.Items; /** * Represents the hero guild. * @author Vexia + * @author Player Name */ @Initializable public final class HeroGuildPlugin extends OptionHandler { @@ -42,8 +48,8 @@ public final class HeroGuildPlugin extends OptionHandler { switch (id) { case 2624: case 2625: - if (!hasRequirement(player, "Heroes' Quest")) - return true; + if (!hasRequirement(player, Quests.HEROES_QUEST)) + return true; DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); break; } @@ -55,6 +61,7 @@ public final class HeroGuildPlugin extends OptionHandler { /** * Handles the recharging of dragonstone jewellery. * @author Vexia + * @author Player Name */ public static final class JewelleryRechargePlugin extends UseWithHandler { @@ -64,8 +71,7 @@ public final class HeroGuildPlugin extends OptionHandler { private static final int[] IDS = new int[] { 1710, 1708, 1706, 1704, 11107, 11109, 11111, 11113, 11120, 11122, 11124, 11126, 10354, 10356, 10358, 10360, 10362, 14644,14642,14640,14638, 2572 }; /** - * Constructs a new {@Code JewelleryRechargePlugin} {@Code - * Object} + * Constructs a new JewelleryRechargePlugin object */ public JewelleryRechargePlugin() { super(IDS); @@ -82,18 +88,24 @@ public final class HeroGuildPlugin extends OptionHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - if (!hasRequirement(player, "Heroes' Quest")) - return true; + if (!hasRequirement(player, Quests.HEROES_QUEST)) { + return true; //hasRequirement shows the message + } final EnchantedJewellery jewellery; assert event.getUsedItem() != null; jewellery = EnchantedJewellery.Companion.getIdMap().get(event.getUsedItem().getId()); - if (!hasRequirement(player, "Heroes' Quest")) - return true; - if (jewellery == EnchantedJewellery.COMBAT_BRACELET || jewellery == EnchantedJewellery.SKILLS_NECKLACE) - if (!hasRequirement(player, "Legend's Quest")) - return true; - if (jewellery == null && event.getUsedItem().getId() != 2572) { - return true; + if (jewellery == null) { + return false; //nothing interesting happens + } + if (jewellery == EnchantedJewellery.RING_OF_WEALTH) { + if (!ServerConstants.RING_OF_WEALTH_TELEPORT) { + return false; + } + } + if (jewellery == EnchantedJewellery.COMBAT_BRACELET || jewellery == EnchantedJewellery.SKILLS_NECKLACE) { + if (!hasRequirement(player, Quests.LEGENDS_QUEST)) { + return true; + } } boolean fam = event.getUsedWith() instanceof NPC; if (fam && jewellery != EnchantedJewellery.AMULET_OF_GLORY & jewellery != EnchantedJewellery.AMULET_OF_GLORY_T) { @@ -112,9 +124,9 @@ public final class HeroGuildPlugin extends OptionHandler { player.getInventory().replace(rechargedItem, event.getUsedItem().getSlot()); String name = jewellery.getJewelleryName(rechargedItem); if (!fam) { - player.sendMessage("You dip the " + name + " in the fountain..."); + sendMessage(player, "You dip the " + name.toLowerCase() + " in the fountain..."); } else { - player.sendMessage("Your titan recharges the glory."); + sendMessage(player, "Your titan recharges the " + name.toLowerCase() + "."); } return true; } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt index b6b31939f..24e3f6cbc 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt @@ -5,9 +5,9 @@ import core.api.getAttribute import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills -import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * Death Plateau Quest @@ -15,16 +15,13 @@ import org.rs09.consts.Items * @author ovenbread */ @Initializable -class DeathPlateau : Quest("Death Plateau",44, 43, 1, 314, 0, 1, 80) { - companion object { - const val questName = "Death Plateau" - } +class DeathPlateau : Quest(Quests.DEATH_PLATEAU,44, 43, 1, 314, 0, 1, 80) { override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) var line = 12 var stage = getStage(player) - var started = player?.questRepository?.getStage(questName)!! > 0 + var started = player?.questRepository?.getStage(Quests.DEATH_PLATEAU)!! > 0 if(!started){ line(player, "I can start this quest by speaking to !!Denulth?? who is in his", line++) diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt index e0db1a73d..64c29cec7 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.deathplateau +import content.data.Quests import core.api.getQuestStage import core.api.getScenery import core.api.sendDialogue @@ -26,7 +27,7 @@ class DeathPlateauDoorDialogueFile(val door: Int) : DialogueFile() { if(door == 2) { npc = NPC(NPCs.TENZING_1071) - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { in 0 .. 19 -> { when (stage) { 0 -> sendDialogue(player!!, "You knock on the door.").also { stage++ } @@ -53,7 +54,7 @@ class DeathPlateauDoorDialogueFile(val door: Int) : DialogueFile() { } if(door == 3) { npc = NPC(NPCs.TENZING_1071) - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { in 0..24 -> { when (stage) { 0 -> npcl(FacialExpression.FRIENDLY, "Where do you think you're going? This is private property!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt index ed6850780..fd59d4697 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt @@ -1,10 +1,13 @@ package content.region.asgarnia.burthorpe.quest.deathplateau +import content.data.Quests +import content.global.handlers.iface.ScrollInterface import core.api.* import core.game.global.action.DoorActionHandler import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.item.GroundItemManager +import org.rs09.consts.Components import org.rs09.consts.Items import org.rs09.consts.Scenery @@ -22,24 +25,26 @@ class DeathPlateauInteractionListener : InteractionListener { Scenery.STONE_MECHANISM_3676, // 4 Outer stone plates Scenery.STONE_MECHANISM_3677 // 2 Inner stone plates ) + val combinationScroll = arrayOf( + "Red is North of Blue. Yellow is South of Purple.", + "Green is North of Purple. Blue is West of", + "Yellow. Purple is East of Red." + ) } override fun defineListeners() { - on(Scenery.DOOR_3747, SCENERY, "open") { player, _ -> - // Harold's Door - if (player.location == location(2906, 3543, 1)) { - openDialogue(player, DeathPlateauDoorDialogueFile(1)) - } else { - DoorActionHandler.handleAutowalkDoor(player, getScenery(2906, 3543, 1)) + on(Scenery.DOOR_3747, SCENERY, "open") { player, node -> + // Harold's door + when (player.location) { + location(2906, 3543, 1), location(2905, 3543, 1), location(2907, 3543, 1) -> openDialogue(player, DeathPlateauDoorDialogueFile(1)) + else -> DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } return@on true } on(Scenery.DOOR_3745, SCENERY, "open") { player, node -> - if (node.location == location(2823, 3555, 0)) { - // 1st Door to Tenzing - openDialogue(player, DeathPlateauDoorDialogueFile(2)) - } else if (node.location == location(2820, 3558, 0)) { - // 2nd Door to chicken pen - openDialogue(player, DeathPlateauDoorDialogueFile(3)) + when (node.location) { + location(2823, 3555, 0) -> openDialogue(player, DeathPlateauDoorDialogueFile(2)) //1st door to Tenzing + location(2820, 3558, 0) -> openDialogue(player, DeathPlateauDoorDialogueFile(3)) //2nd door to chicken pen + else -> DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } return@on true } @@ -50,10 +55,10 @@ class DeathPlateauInteractionListener : InteractionListener { } on(Items.COMBINATION_3102, ITEM, "read") { player, _ -> - openInterface(player, 220) - setInterfaceText(player, "Red is North of Blue. Yellow is South of Purple.", 220, 7) - setInterfaceText(player, "Green is North of Purple. Blue is West of", 220, 8) - setInterfaceText(player, "Yellow. Purple is East of Red.", 220, 9) + // https://youtu.be/C8n8Yi-J8wU?t=466 + openInterface(player, 222) + setInterfaceText(player, combinationScroll.joinToString("
"), 222, 5) + return@on true } @@ -77,16 +82,16 @@ class DeathPlateauInteractionListener : InteractionListener { GroundItemManager.get(Items.STONE_BALL_3111, location(2895, 3562, 0), player) != null && GroundItemManager.get(Items.STONE_BALL_3112, location(2895, 3563, 0), player) != null && GroundItemManager.get(Items.STONE_BALL_3113, location(2895, 3564, 0), player) != null) { - if (getQuestStage(player, DeathPlateau.questName) == 16) { + if (getQuestStage(player, Quests.DEATH_PLATEAU) == 16) { sendMessage(player, "The equipment room door has unlocked.") - setQuestStage(player, DeathPlateau.questName, 19) + setQuestStage(player, Quests.DEATH_PLATEAU, 19) } } return@onUseWith true } on(Scenery.LARGE_DOOR_3743, SCENERY, "open") { player, node -> - if (getQuestStage(player, DeathPlateau.questName) > 16) { + if (getQuestStage(player, Quests.DEATH_PLATEAU) > 16) { DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery) } else { sendMessage(player, "The door is locked.") @@ -94,4 +99,4 @@ class DeathPlateauInteractionListener : InteractionListener { return@on true } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt index 7838a6c5c..2046cf51a 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt @@ -1,14 +1,13 @@ package content.region.asgarnia.burthorpe.quest.deathplateau +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.dialogue.Topic -import core.game.node.entity.npc.NPC import core.game.node.item.Item import core.tools.END_DIALOGUE import org.rs09.consts.Items -import org.rs09.consts.NPCs /** @@ -20,7 +19,7 @@ import org.rs09.consts.NPCs class DenulthDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { in 0..4 -> { when (stage) { 0 -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } @@ -54,7 +53,7 @@ class DenulthDialogueFile : DialogueFile() { 309 -> playerl(FacialExpression.FRIENDLY, "A stone what...?!").also { stage++ } 310 -> npcl(FacialExpression.FRIENDLY, "Well citizen, the Prince is fond of puzzles. Why we couldn't just have a key is beyond me!").also { stage++ } 311 -> playerl(FacialExpression.SUSPICIOUS, "I'll get on it right away!").also { - setQuestStage(player!!, DeathPlateau.questName, 5) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 5) stage = END_DIALOGUE } } @@ -104,7 +103,7 @@ class DenulthDialogueFile : DialogueFile() { } 11 -> npcl(FacialExpression.FRIENDLY, "This certificate proves that we have accepted Dunstan's son for training in the Imperial Guard!").also { stage++ } 12 -> playerl(FacialExpression.FRIENDLY, "Thank you Denulth, I shall be back shortly!").also { - setQuestStage(player!!, DeathPlateau.questName, 23) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 23) stage = END_DIALOGUE } } @@ -155,7 +154,7 @@ class DenulthDialogueFile : DialogueFile() { stage = 8 } } - 7 -> playerl(FacialExpression.FRIENDLY, "I have opened the door but I don't have the combination on me.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "I have opened the door but I don't have the combination on me.").also { stage = END_DIALOGUE } 8 -> playerl(FacialExpression.FRIENDLY, "Yes! The door is open and here is the combination.").also { stage++ } 9 -> sendItemDialogue(player!!, Items.COMBINATION_3102, "You give Denulth the combination to the equipment room.").also { if (removeItem(player!!, Item(Items.COMBINATION_3102))) { @@ -169,7 +168,7 @@ class DenulthDialogueFile : DialogueFile() { 12 -> npcl(FacialExpression.FRIENDLY, "You are now an honourary member of the Imperial Guard!").also { stage++ } 13 -> { stage = END_DIALOGUE - finishQuest(player!!, DeathPlateau.questName) + finishQuest(player!!, Quests.DEATH_PLATEAU) } } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt index 2567c54c8..6cf2eabf4 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt @@ -3,17 +3,16 @@ package content.region.asgarnia.burthorpe.quest.deathplateau import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC import core.game.node.item.Item import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.Items -import org.rs09.consts.NPCs +import content.data.Quests class DunstanDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { 21 -> { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } @@ -29,7 +28,7 @@ class DunstanDialogueFile : DialogueFile() { 10 -> npcl(FacialExpression.FRIENDLY, "My son has just turned 16 and I'd very much like him to join the Imperial Guard. The Prince's elite forces are invite only so it's very unlikely he'll get in. If you can arrange that you have a deal!").also { stage++ } 11 -> playerl(FacialExpression.FRIENDLY, "That won't be a problem as I'm helping out the Imperial Guard!").also { stage++ } 12 -> npcl(FacialExpression.FRIENDLY, "Excellent! You'll need to bring an Iron bar for the spikes!").also { - setQuestStage(player!!, "Death Plateau", 22) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 22) stage = END_DIALOGUE } } @@ -60,7 +59,7 @@ class DunstanDialogueFile : DialogueFile() { 5 -> npcl(FacialExpression.FRIENDLY, "Thank you!").also { // Jumps to the next stage immediately in one continuous dialogue (questStage 24, stage 2). - setQuestStage(player!!, "Death Plateau", 24) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 24) stage = 2 } } @@ -84,15 +83,17 @@ class DunstanDialogueFile : DialogueFile() { 4 -> playerl(FacialExpression.FRIENDLY, "I don't have the climbing boots.").also { stage = END_DIALOGUE } 5 -> playerl(FacialExpression.FRIENDLY, "I don't have the iron bar or the climbing boots.").also { stage = END_DIALOGUE } - 7 -> sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an iron bar and the climbing boots.").also { + 7 -> sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.").also { + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) stage++ } else { stage = END_DIALOGUE } } 8 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { stage++ - addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + sendMessage(player!!, "Dunstan has given you the spiked boots.") } 9 -> playerl(FacialExpression.FRIENDLY, "Thank you!").also { stage++ } 10 -> npcl(FacialExpression.FRIENDLY, "No problem.").also { diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt index 426f4846a..8e0d5f0a6 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt @@ -4,10 +4,9 @@ import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.dialogue.Topic -import core.game.node.entity.npc.NPC import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE -import org.rs09.consts.NPCs +import content.data.Quests /** * Eohric sub dialogue file for death plateau. @@ -17,7 +16,7 @@ import org.rs09.consts.NPCs */ class EohricDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { in 5..9 -> { when (stage) { START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hi!").also { stage++ } @@ -31,7 +30,7 @@ class EohricDialogueFile : DialogueFile() { 11 -> player(FacialExpression.FRIENDLY, "Do you know where he is staying?").also { stage++ } 12 -> npc(FacialExpression.FRIENDLY, "Harold is staying at the Toad and Chicken.").also { stage++ } 13 -> player(FacialExpression.FRIENDLY, "Thanks!").also { - setQuestStage(player!!, "Death Plateau", 10) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 10) HaroldDialogueFile.resetNpc(player!!) stage = END_DIALOGUE } @@ -58,7 +57,7 @@ class EohricDialogueFile : DialogueFile() { 2 -> playerl(FacialExpression.HALF_GUILTY, "I found Harold but he won't talk to me!.").also { stage++ } 3 -> npcl(FacialExpression.THINKING, "Hmm. Harold has got in trouble a few over his drinking and gambling. Perhaps he'd open up after a drink?").also { stage++ } 4 -> playerl(FacialExpression.FRIENDLY, "Thanks, I'll try that!").also { - setQuestStage(player!!, "Death Plateau", 12) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 12) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt index 810b427b1..e4242212b 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt @@ -11,6 +11,7 @@ import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.Animations import org.rs09.consts.Items +import content.data.Quests /** * Harold sub dialogue file for death plateau. @@ -38,7 +39,7 @@ class HaroldDialogueFile : DialogueFile() { setAttribute(player!!, ATTRIBUTE_JUMPSTAGE, 0) } println(getAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, -1)) - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { 10 -> { // First time meeting. when (stage) { START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } @@ -47,7 +48,7 @@ class HaroldDialogueFile : DialogueFile() { 3 -> npcl(FacialExpression.FRIENDLY, "Yeah.").also { stage++ } 4 -> playerl(FacialExpression.HAPPY, "Denulth said that you lost the combination to the equipment room ?").also { stage++ } 5 -> npcl(FacialExpression.FRIENDLY, "I don't want to talk about it!").also { - setQuestStage(player!!, "Death Plateau", 11) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 11) stage = END_DIALOGUE } } @@ -71,7 +72,7 @@ class HaroldDialogueFile : DialogueFile() { 4 -> { if (inInventory(player!!, Items.ASGARNIAN_ALE_1905, 1)) { removeItem(player!!, Items.ASGARNIAN_ALE_1905) - setQuestStage(player!!, "Death Plateau", 12) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 12) sendMessage(player!!, "You give Harold an Asgarnian Ale.") setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, 200) sendItemDialogue(player!!, Items.ASGARNIAN_ALE_1905, "You give Harold an Asgarnian Ale.").also { stage++ } @@ -81,7 +82,7 @@ class HaroldDialogueFile : DialogueFile() { } 5 -> { end() - setQuestStage(player!!, "Death Plateau", 13) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 13) animate(npc!!, Animations.HUMAN_EATTING_829) runTask(npc!!, 5) { npcl(FacialExpression.FRIENDLY, "Arrh. That hit the spot!").also { stage = END_DIALOGUE } @@ -108,19 +109,16 @@ class HaroldDialogueFile : DialogueFile() { 21 -> playerl(FacialExpression.ASKING, "What?").also { stage++ } 22 -> npcl(FacialExpression.FRIENDLY, "I really fancy one of those Blurberry Specials. I never get over to the Gnome Stronghold so I haven't had one for ages!").also { stage++ } 23 -> { - if (removeItem(player!!, Items.BLURBERRY_SPECIAL_2064)) { + if (removeItem(player!!, Items.BLURBERRY_SPECIAL_2064) || removeItem(player!!, Items.PREMADE_BLURB_SP_2028)) { sendMessage(player!!, "You give Harold a Blurberry Special.") sendItemDialogue(player!!, Items.BLURBERRY_SPECIAL_2064, "You give Harold a Blurberry Special.").also { stage++ } - } else if (removeItem(player!!, Items.PREMADE_BLURB_SP_2028)) { - sendMessage(player!!, "You give Harold a Blurberry Special.") - sendItemDialogue(player!!, Items.PREMADE_BLURB_SP_2028, "You give Harold a Blurberry Special.").also { stage++ } } else { player(FacialExpression.FRIENDLY, "I'll go and get you one.").also { stage = END_DIALOGUE } } } 24 -> { end() - setQuestStage(player!!, DeathPlateau.questName, 14) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 14) npc!!.isWalks = false animate(npc!!, Animations.HUMAN_EATTING_829) runTask(npc!!, 4) { @@ -204,7 +202,7 @@ class HaroldDialogueFile : DialogueFile() { 37 -> npcl(FacialExpression.FRIENDLY, "I'll write you out an IOU for the rest.").also { stage++ } 38 -> { addItemOrDrop(player!!, Items.IOU_3103) - setQuestStage(player!!, DeathPlateau.questName, 15) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 15) sendMessage(player!!, "Harold has given you an IOU scribbled on some paper.") sendItemDialogue(player!!, Items.IOU_3103, "Harold has given you an IOU scribbled on some paper.").also {stage = END_DIALOGUE} } @@ -292,7 +290,7 @@ class HaroldDialogueFile : DialogueFile() { 34 -> npcl(FacialExpression.DRUNK, "I owe you the resht!").also { stage++ } 35 -> { addItemOrDrop(player!!, Items.IOU_3103) - setQuestStage(player!!, DeathPlateau.questName, 15) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 15) sendMessage(player!!, "Harold has given you an IOU scribbled on some paper.") sendItemDialogue(player!!, Items.IOU_3103, "Harold has given you an IOU scribbled on some paper.").also {stage = END_DIALOGUE} } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt index 0d44bc767..29978f609 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt @@ -1,15 +1,19 @@ package content.region.asgarnia.burthorpe.quest.deathplateau +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.node.item.Item import core.tools.END_DIALOGUE import org.rs09.consts.Items class IOUNoteDialogueFile : DialogueFile() { var a = 0 override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { in 15..16 -> { when (stage) { 0 -> player(FacialExpression.NEUTRAL, "The IOU says that Harold owes me some money.").also { stage++ } @@ -18,17 +22,14 @@ class IOUNoteDialogueFile : DialogueFile() { 3 -> { if (removeItem(player!!, Items.IOU_3103)) { addItemOrDrop(player!!, Items.COMBINATION_3102) - setQuestStage(player!!, DeathPlateau.questName, 16) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 16) sendItemDialogue(player!!, Items.COMBINATION_3102, "You have found the combination!").also { stage++ } } } 4 -> { end() stage = END_DIALOGUE - openInterface(player!!, 220) - setInterfaceText(player!!, "Red is North of Blue. Yellow is South of Purple.", 220, 7) - setInterfaceText(player!!, "Green is North of Purple. Blue is West of", 220, 8) - setInterfaceText(player!!, "Yellow. Purple is East of Red.", 220, 9) + InteractionListeners.run(Items.COMBINATION_3102, IntType.ITEM, "read", player!!, Item(Items.COMBINATION_3102)) } } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt index 3c1c90632..820fdf26e 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt @@ -5,11 +5,12 @@ import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.dialogue.Topic import core.tools.END_DIALOGUE +import content.data.Quests class SabaDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { 19 -> { when (stage) { 0 -> player(FacialExpression.FRIENDLY, "Hello!").also { stage++ } @@ -34,7 +35,7 @@ class SabaDialogueFile : DialogueFile() { 29 -> npcl(FacialExpression.HALF_GUILTY,"Before the trolls came there used to be a nettlesome Sherpa that took humans exploring or something equally stupid. Perhaps he'd know another way.").also { stage++ } 30 -> playerl(FacialExpression.FRIENDLY, "Where does this Sherpa live?").also { stage++ } 31 -> npcl(FacialExpression.ANNOYED,"I don't know but it can't be far as he used to be around all the time!").also { - setQuestStage(player!!, "Death Plateau", 20) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 20) stage = END_DIALOGUE } } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt index 3a078a77d..96d821a9f 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.deathplateau +import content.data.Quests import core.api.* import core.game.node.entity.Entity import core.game.node.entity.player.Player @@ -11,9 +12,9 @@ class SecretWayLocation : MapArea { } override fun areaEnter(entity: Entity) { - if (entity is Player && getQuestStage(entity, DeathPlateau.questName) == 25) { + if (entity is Player && getQuestStage(entity, Quests.DEATH_PLATEAU) == 25) { sendPlayerDialogue(entity, "I think this is far enough, I can see Death Plateau and it looks like the trolls haven't found the path. I'd better go and tell Denulth.") - setQuestStage(entity, DeathPlateau.questName, 26) + setQuestStage(entity, Quests.DEATH_PLATEAU, 26) } } } \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt index aacba1673..c69cb4a94 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.deathplateau +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -12,7 +13,7 @@ import org.rs09.consts.Items class TenzingDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, DeathPlateau.questName)) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { 20 -> { when (stage) { START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } @@ -34,7 +35,7 @@ class TenzingDialogueFile : DialogueFile() { 20 -> npcl(FacialExpression.FRIENDLY, "Thank you traveller!").also { stage++ } 21 -> sendItemDialogue(player!!, Items.CLIMBING_BOOTS_3105, "Tenzing has given you his Climbing boots.").also { addItemOrDrop(player!!, Items.CLIMBING_BOOTS_3105, 1) - setQuestStage(player!!, DeathPlateau.questName, 21) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 21) stage = END_DIALOGUE } 30 -> npcl(FacialExpression.ANNOYED, "Hmph.").also { stage = END_DIALOGUE } @@ -104,7 +105,7 @@ class TenzingDialogueFile : DialogueFile() { 9 -> npcl(FacialExpression.FRIENDLY, "I don't think the Trolls have found the secret way yet, if they had I would've been attacked by now.").also { stage++ } 10 -> playerl(FacialExpression.FRIENDLY, "OK thanks but I think I'd better check the path. I don't want to send the Imperial Guards to their death!").also { stage++ } 11 -> npcl(FacialExpression.FRIENDLY, "You are wise for one so young.").also { - setQuestStage(player!!, DeathPlateau.questName, 25) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 25) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AchiettiesDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AchiettiesDialogue.kt new file mode 100644 index 000000000..be02fd712 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AchiettiesDialogue.kt @@ -0,0 +1,180 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class AchiettiesDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, AchiettiesDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AchiettiesDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ACHIETTIES_796) + } +} + +class AchiettiesDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.HEROES_QUEST, 0,1) + .branch { player -> + return@branch getQuestStage(player, Quests.HEROES_QUEST) + }.let{ branch -> + branch.onValue(0) + .npcl(FacialExpression.FRIENDLY, "Greetings. Welcome to the Heroes' Guild.") + .npcl("Only the greatest heroes of this land may gain entrance to this guild.") + // - If the player's skill levels are lower than the quest requirements. (I think this is after 2009) + // linel("Before starting this quest, be aware that one or more of your skill levels are lower than what is required to fully complete it.") + .options() + .let { optionBuilder -> + optionBuilder.option("I'm a hero, may I apply to join?") + .playerl("I'm a hero. May I apply to join?") + .branch { player -> + return@branch if (HeroesQuest.hasRequirements(player)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(0) + .npcl("You're a hero? I've never heard of YOU. You are required to possess at least 55 quest points to file an application.") + .npcl("Additionally you must have completed the Shield of Arrav, Lost City, Merlin's Crystal and Dragon Slayer quests.") + .end() + return@let branch + }.onValue(1) + .betweenStage { df, player, _, _ -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 0) { + setQuestStage(player, Quests.HEROES_QUEST, 1) + } + } + .npcl("Well you seem to meet our initial requirements, so you may now begin the tasks to earn membership in the Heroes' Guild.") + .npcl("The three items required for entrance are: An Entranan Firebird feather, a Master Thieves' armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + + optionBuilder.option_playerl("Good for the foremost heroes of the land.") + .npcl("Yes. Yes it is.") + .end() + } + branch.onValue(1) + .npcl("Greetings. Welcome to the Heroes' Guild.") + .npcl("How goes thy quest adventurer?") + .playerl("It's tough. I've not done it yet.") + .npcl("Remember, the items you need to enter are:") + .npcl("An Entranan Firebirds' feather, A Master Thieves armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 2, 3, 4) + .npcl("Greetings. Welcome to the Heroes' Guild.") + .npcl("How goes thy quest adventurer?") + .playerl("It's tough. I've not done it yet.") + .npcl("Remember, the items you need to enter are:") + .npcl("An Entranan Firebirds' feather, A Master Thieves armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + + b.onQuestStages(Quests.HEROES_QUEST, 6) + .npcl("Greetings. Welcome to the Heroes' Guild.") + .npcl("How goes thy quest adventurer?") + .branch { player -> + return@branch if (HeroesQuest.allItemsInInventory(player)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("It's tough. I've not done it yet.") + .npcl("Remember, the items you need to enter are:") + .npcl("An Entranan Firebirds' feather, A Master Thieves armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + + branch.onValue(1) + .playerl("I have all the required items.") + .npcl("I see that you have. Well done. Now, to complete the quest, and gain entry to the Heroes' Guild in your final task all that you have to do is...") + .playerl("W-what? What do you mean? There's MORE?") + .npcl("I'm sorry, I was just having a little fun with you. Just a little Heroes' Guild humour there. What I really meant was") + .npcl("Congratulations! You have completed the Heroes' Guild entry requirements! You will find the door now open for you! Enter, Hero! And take this reward!") + .endWith { _, player -> + if (HeroesQuest.allItemsInInventory(player)) { + removeItem(player, Items.FIRE_FEATHER_1583) + removeItem(player, Items.LAVA_EEL_2149) + removeItem(player, Items.THIEVES_ARMBAND_1579) + if (getQuestStage(player, Quests.HEROES_QUEST) == 6) { + finishQuest(player, Quests.HEROES_QUEST) + } + } + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 100) + .npcl("Greetings. Welcome to the Heroes' Guild.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AlfonseTheWaiterDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AlfonseTheWaiterDialogue.kt new file mode 100644 index 000000000..efb262b09 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AlfonseTheWaiterDialogue.kt @@ -0,0 +1,62 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.getQuestStage +import core.api.openDialogue +import core.api.openNpcShop +import core.api.setQuestStage +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class AlfonseTheWaiterDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return AlfonseTheWaiterDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, AlfonseTheWaiterDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALFONSE_THE_WAITER_793) + } +} +class AlfonseTheWaiterDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc("Welcome to the Shrimp and Parrot.", "Would you like to order, sir?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Yes please.") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + + optionBuilder.option_playerl("No thank you.") + .end() + + optionBuilder.optionIf("Do you sell Gherkins?"){ player -> return@optionIf getQuestStage( + player, + Quests.HEROES_QUEST + ) >= 2 && HeroesQuest.isPhoenix(player) } + .playerl("Do you sell Gherkins?") + .npc("Hmmmm Gherkins eh? Ask Charlie the cook, round the", "back. He may have some 'gherkins' for you!") + .linel("Alfonse winks at you.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 2) { + setQuestStage(player, Quests.HEROES_QUEST, 3) + } + } + + optionBuilder.option("Where do you get your Karambwan from?") + .npc("We buy directly off Lubufu, a local fisherman. He", "seems to have a monopoly over Karambwan sales.") + .end() + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/CharlieTheCookDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/CharlieTheCookDialogue.kt new file mode 100644 index 000000000..2bd65f817 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/CharlieTheCookDialogue.kt @@ -0,0 +1,84 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.getQuestStage +import core.api.openDialogue +import core.api.setQuestStage +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class CharlieTheCookDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return CharlieTheCookDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, CharlieTheCookDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHARLIE_THE_COOK_794) + } +} +class CharlieTheCookDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npc(FacialExpression.ANGRY, "Hey! What are you doing back here?") + .options() + .let { optionBuilder -> + val continuePath = b.placeholder() + + optionBuilder.optionIf("I'm looking for a gherkin...") { player -> return@optionIf getQuestStage(player, Quests.HEROES_QUEST) >= 3 && HeroesQuest.isPhoenix(player) } + .playerl("I'm looking for a gherkin...") + .goto(continuePath) + + optionBuilder.optionIf("I'm a fellow member of the Phoenix Gang.") { player -> return@optionIf getQuestStage(player, Quests.HEROES_QUEST) >= 3 && HeroesQuest.isPhoenix(player) } + .playerl("I'm a fellow member of the Phoenix Gang.") + .goto(continuePath) + + optionBuilder.option_playerl("Just exploring.") + .npcl(FacialExpression.ANGRY, "Well, get out! This kitchen isn't for exploring. It's a private establishment! It's out of bounds to customers!") + .end() + + return@let continuePath.builder() + } + .npcl("Ah, a fellow Phoenix! So, tell me compadre... What brings you to sunny Brimhaven?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Sun, sand, and the fresh sea air!") + .playerl("Sun, sand, and the fresh sea air!") + .npcl("Well, can't say I blame you, compadre. I used to be a city boy myself, but have to admit it's a lot nicer living here nowadays. Brimhaven's certainly good for it.") + .playerl("I also want to steal Scarface Pete's candlesticks.") + .npcl("Ah yes, of course. The candlesticks. Well, I have to be honest with you, compadre, we haven't made much progress in that task ourselves so far.") + .npcl("We can however offer a little assistance. Setting up this restaurant was the start of things; we have a secret door out the back of here that leads through the back of Cap'n Arnav's garden.") + .npcl("Now, at the other side of Cap'n Arnav's garden, is an old side entrance to Scarface Pete's mansion. It seems to have been blocked off from the rest of the mansion some years ago and we can't seem to find a way through.") + .npcl("We're positive this is the key to entering the house undetected, however, and I promise to let you know if we find anything there.") + .playerl("Mind if I check it out for myself?") + .npcl("Not at all! The more minds we have working on the problem, the quicker we get that loot!") + .endWith { _, player -> + if (getQuestStage(player, Quests.HEROES_QUEST) == 3) { + setQuestStage(player, Quests.HEROES_QUEST, 4) + } + } + + optionBuilder.option_playerl("I want to steal Scarface Pete's candlesticks.") + .npcl("Ah yes, of course. The candlesticks. Well, I have to be honest with you, compadre, we haven't made much progress in that task ourselves so far.") + .npcl("We can however offer a little assistance. Setting up this restaurant was the start of things; we have a secret door out the back of here that leads through the back of Cap'n Arnav's garden.") + .npcl("Now, at the other side of Cap'n Arnav's garden, is an old side entrance to Scarface Pete's mansion. It seems to have been blocked off from the rest of the mansion some years ago and we can't seem to find a way through.") + .npcl("We're positive this is the key to entering the house undetected, however, and I promise to let you know if we find anything there.") + .playerl("Mind if I check it out for myself?") + .npcl("Not at all! The more minds we have working on the problem, the quicker we get that loot!") + .endWith { _, player -> + if (getQuestStage(player, Quests.HEROES_QUEST) == 3) { + setQuestStage(player, Quests.HEROES_QUEST, 4) + } + } + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GarvDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GarvDialogue.kt new file mode 100644 index 000000000..dc9433443 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GarvDialogue.kt @@ -0,0 +1,72 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GarvDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GarvDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GarvDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GARV_788) + } +} + +class GarvDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // Technically this won't happen since you have to get past Grubor. + b.onQuestStages(Quests.HEROES_QUEST, 0, 1, 2) + .npcl("Hello. What do you want?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Can I go in there?") + .npcl("No. In there is private.") + .end() + optionBuilder.option_playerl("I want for nothing!") + .npcl("You're one of a very lucky few then.") + .end() + } + + b.onQuestStages(Quests.HEROES_QUEST, 3, 4, 5, 6, 100) + // .npcl("Oi! Where do you think you're going pal?") - When you click on the door instead of Garv. + .npcl("Hello. What do you want?") + .playerl("Hi. I'm Hartigen. I've come to work here.") + .branch { player -> + return@branch if (inEquipment(player, Items.BLACK_FULL_HELM_1165) && inEquipment(player, Items.BLACK_PLATEBODY_1125) && inEquipment(player, Items.BLACK_PLATELEGS_1077)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("I assume you have your I.D. papers then?") + .branch { player -> + return@branch if (inInventory(player, Items.ID_PAPERS_1584)) { 1 } else { 0 } + }.let { branch2 -> + branch2.onValue(1) + .npcl("You'd better come in then, Grip will want to talk to you.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 3) { + setQuestStage(player, Quests.HEROES_QUEST, 4) + } + } + branch2.onValue(0) + .playerl("Uh... Yeah. About that...I must have left them in my other suit of armour.") + .end() + } + branch.onValue(0) + .npcl("Hartigen the Black Knight? I don't think so. He doesn't dress like that.") + .end() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GerrantDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GerrantDialogue.kt new file mode 100644 index 000000000..c106acdec --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GerrantDialogue.kt @@ -0,0 +1,66 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GerrantDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GerrantDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GerrantDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GERRANT_558) + } +} +class GerrantDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc(FacialExpression.HAPPY, "Welcome! You can buy fishing equipment at my store.", "We'll also buy anything you catch off you.") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Let's see what you've got then.") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + + optionBuilder.option_playerl("Sorry, I'm not interested.") + .end() + + optionBuilder.optionIf("I want to find out how to catch a lava eel.") { player -> return@optionIf getQuestStage(player, Quests.HEROES_QUEST) >= 1 } + .playerl("I want to find out how to catch a lava eel.") + .npcl("Lava eels, eh? That's a tricky one, that is. You'll need a lava-proof fishing rod. The method for making this would be to take an ordinary fishing rod, and then cover it with fire-proof blamish oil.") + .branch { player -> + return@branch if (inInventory(player, Items.BLAMISH_SNAIL_SLIME_1581)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("Of course, you knew that already.") + .playerl("So where can I fish lava eels?") + .npcl("Taverley dungeon or the lava maze in the Wilderness.") + .end() + + branch.onValue(0) + .npcl("You know... thinking about it... I may have a jar of blamish slime around here somewhere. Now where did I put it?") + .linel("Gerrant searches around a bit.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.BLAMISH_SNAIL_SLIME_1581) + } + .npcl("Aha! Here it is! Take this slime, mix it with some Harralander and water and you'll have the blamish oil you need to treat your fishing rod.") + .end() + } + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripBehavior.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripBehavior.kt new file mode 100644 index 000000000..62d72dc0d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripBehavior.kt @@ -0,0 +1,59 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GripBehavior : NPCBehavior(NPCs.GRIP_792) { + // Attacking Grip + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + // You cannot attack if you are a black arm gang member. + if (attacker is Player && HeroesQuest.isBlackArm(attacker)) { + openDialogue(attacker, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + //"I can't attack the head guard here! There are too", "many witnesses around to see me do it! I'd have the", "whole of Brimhaven after me! Besides, if he dies I want", "the promotion!" + START_DIALOGUE -> sendPlayerDialogue(attacker, "I can't attack the head guard here! There are too many witnesses around to see me do it! I'd have the whole of Brimhaven after me! Besides, if he dies I want the promotion!") .also { stage++ } + 1 -> sendDialogueLines(attacker, "Perhaps you need another player's help...?").also { + stage = END_DIALOGUE + } + } + } + }) + return false + } + return true + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (getQuestStage(killer, Quests.HEROES_QUEST) == 4) { + setQuestStage(killer, Quests.HEROES_QUEST, 5) + } + + val gi = GroundItem( + Item(Items.GRIPS_KEY_RING_1588), + self.location, + 5000, + null, + ) + gi.forceVisible = true + gi.isRemainPrivate = false + + val gim = GroundItemManager.create(gi) + gim.isRemainPrivate = false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripDialogue.kt new file mode 100644 index 000000000..4146b03e6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripDialogue.kt @@ -0,0 +1,118 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GripDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GripDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GripDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRIP_792) + } +} + +class GripDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .branch { player -> + return@branch if (getAttribute(player, HeroesQuest.attributeGripTookPapers, false)) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .goto(continuePath) + branch.onValue(0) + .playerl("Hi there. I am Hartigen, reporting for duty as your new deputy sir!") + .npcl("Ah good, at last. You took your time getting here! Now let me see...") + .npcl("I'll get your hours and duty roster sorted out in a while. Oh, and do you have your I.D. papers with you? Internal security is almost as important as external security for a guard.") + .branch { player -> + return@branch if (inInventory(player, Items.ID_PAPERS_1584)) { 1 } else { 0 } + }.let { branch -> + val continuePath2 = b.placeholder() + branch.onValue(1) + .playerl("Right here sir!") + .linel("You hand the ID papers over to Grip.") + .betweenStage { df, player, _, _ -> + if (removeItem(player, Items.ID_PAPERS_1584)) { + setAttribute(player, HeroesQuest.attributeGripTookPapers, true) + } + } + .goto(continuePath2) + branch.onValue(0) + .playerl("Oh, dear. I don't have that with me any more.") + .npcl("Well, that's no good! Go get them immediately, then report back for duty.") + .end() + return@let continuePath2.builder() + } + .goto(continuePath) + return@let continuePath.builder() + } + .options() + .let { optionBuilder -> + val returnJoin = b.placeholder() + + optionBuilder.option_playerl("So can I please guard the treasure room please?") + .npcl("Well, I might post you outside it sometimes. I prefer to be the only one allowed inside however.") + .npcl("There's some pretty valuable artefacts in there! Those keys stay ONLY with the head guard and Scarface Pete.") + .goto(returnJoin) + + optionBuilder.optionIf("So what do my duties involve?") { player -> + return@optionIf !getAttribute(player, HeroesQuest.attributeGripSaidDuties, false) + } + .betweenStage { _, player, _, _ -> + setAttribute(player, HeroesQuest.attributeGripSaidDuties, true) + } + .playerl("So what do my duties involve?") + .npcl("You'll have various guard related duties on various shifts. I'll assign specific duties as they are required as and when they become necessary. Just so you know, if anything happens to me") + .npcl("you'll need to take over as head guard here. You'll find important keys to the treasure room and Pete's quarters inside my jacket - although I doubt anything bad's going to happen to") + .npcl("me anytime soon!") + .linel("Grip laughs to himself at the thought.") + .goto(returnJoin) + + optionBuilder.option_playerl("Well, I'd better sort my new room out.") + .npcl("Yeah, I'll give you time to settle in. Better get a good night's sleep, I expect you to report for duty at oh five hundred hours tomorrow on the dot!") + .end() + + + optionBuilder.optionIf("Anything I can do now?") { player -> + return@optionIf getAttribute(player, HeroesQuest.attributeGripSaidDuties, false) + } + .playerl("Anything I can do now?") + .branch { player -> + return@branch if (inInventory(player, Items.MISCELLANEOUS_KEY_1586)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(1) + .npcl("Can't think of anything right now.") + .end() + + branch.onValue(0) + .npcl("Hmm. Well, you could find out what this key opens for me. Apparently it's for something in this building, but for the life of me I can't find what.") + .linel("Grip hands you a key.") + .endWith { _, player -> + addItemOrDrop(player, Items.MISCELLANEOUS_KEY_1586) + } + } + + returnJoin.builder() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GruborDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GruborDialogue.kt new file mode 100644 index 000000000..958d893b5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GruborDialogue.kt @@ -0,0 +1,87 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class GruborDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GruborDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GruborDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRUBOR_789) + } +} + +class GruborDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> + getQuestStage(player, Quests.HEROES_QUEST) >= 2 && + getAttribute(player, HeroesQuest.attributeGruborLetsYouIn, false) && + HeroesQuest.isBlackArm(player) + } + .playerl("Hi.") + .npcl("Hi, I'm a little busy right now.") + .end() + + b.onPredicate { player -> + getQuestStage(player, Quests.HEROES_QUEST) >= 2 && + !getAttribute(player, HeroesQuest.attributeGruborLetsYouIn, false) && + HeroesQuest.isBlackArm(player) + } + .npcl(FacialExpression.THINKING, "Yes? What do you want?") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Rabbit's foot.") + .npcl("Eh? What are you on about? Go away!") + .end() + + optionBuilder.option_playerl("Four leaved clover.") + .npcl("Oh you're one of the gang are you? Ok, hold up a second, I'll just let you in through here.") + .linel("You hear the door being unbarred from inside.") + .endWith { _, player -> + setAttribute(player, HeroesQuest.attributeGruborLetsYouIn, true) + } + + optionBuilder.option_playerl("Lucky horseshoe.") + .npcl("Eh? What are you on about? Go away!") + .end() + + optionBuilder.option_playerl("Black cat.") + .npcl("Eh? What are you on about? Go away!") + .end() + } + + + b.onPredicate { _ -> true } + .npcl(FacialExpression.THINKING, "Yes? What do you want?") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Would you like your hedges trimming?") + .npcl("Eh? Don't be daft! We don't even HAVE any hedges!") + .end() + + optionBuilder.option_playerl("I want to come in.") + .npcl("No, go away.") + .end() + + optionBuilder.option_playerl("Do you want to trade?") + .npcl("No, I'm busy.") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuest.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuest.kt new file mode 100644 index 000000000..7eadbf5e5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuest.kt @@ -0,0 +1,262 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import content.region.misthalin.varrock.quest.shieldofarrav.ShieldofArrav +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Heroes' Quest + */ +@Initializable +class HeroesQuest : Quest(Quests.HEROES_QUEST,75, 74, 1, 188, 0, 1, 15) { + /** + * Do note: "other players can help you even if they have already finished Heroes' Quest" + * 1 - Talked to Achietties to start the quest + * + * PHOENIX + * 2 - Talked to Katrine + * 3 - Talked to Alfonse + * 4 - Talked to Charlie + * 5 - HIDDEN Killed Grip (You need key from Black Arm Friend) + * 6 - Talked to Katrine with Candlestick + * BLACK ARM + * 2 - Talked to Straven + * 3 - Talked to Trobert + * 4 - Talked to Garv + * 5 - HIDDEN Unlocked Chest (You need Grip killed from Phoenix Friend) + * 6 - Talked to Katrine with Candlestick + * + * 100 - Achiettes with all the items + */ + + companion object { + const val attributeGruborLetsYouIn = "/save:quest:heroesquest-gruborletsyouin" + const val attributeGripTookPapers = "/save:quest:heroesquest-griptookpapers" + const val attributeGripSaidDuties = "/save:quest:heroesquest-gripsaidduties" + const val attributeHasOpenedBackdoor = "/save:quest:heroesquest-hasopenedbackdoor" + const val attributeHasOpenedChestDoor = "/save:quest:heroesquest-hasopenedchestdoor" + + fun checkQuestsAreComplete(player: Player): Boolean { + return isQuestComplete(player, Quests.SHIELD_OF_ARRAV) && + isQuestComplete(player, Quests.LOST_CITY) && + isQuestComplete(player, Quests.MERLINS_CRYSTAL) && + isQuestComplete(player, Quests.DRAGON_SLAYER) && + getQuestPoints(player) >= 55 + } + + /** Abstraction of Shield of Arrav isPhoenix function */ + fun isPhoenix(player: Player): Boolean { + return ShieldofArrav.isPhoenix(player) + } + + /** Abstraction of Shield of Arrav isBlackArm function */ + fun isBlackArm(player: Player): Boolean { + return ShieldofArrav.isBlackArm(player) + } + + fun hasRequirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.HERBLORE, 25), + hasLevelStat(player, Skills.MINING, 50), + hasLevelStat(player, Skills.FISHING, 53), + hasLevelStat(player, Skills.COOKING, 53), + isQuestComplete(player, Quests.SHIELD_OF_ARRAV), + isQuestComplete(player, Quests.LOST_CITY), + isQuestComplete(player, Quests.MERLINS_CRYSTAL), + isQuestComplete(player, Quests.DRAGON_SLAYER), + getQuestPoints(player) >= 55, + ).all { it } + } + + fun allItemsInInventory(player: Player): Boolean { + return inInventory(player, Items.FIRE_FEATHER_1583) && + inInventory(player, Items.LAVA_EEL_2149) && + inInventory(player, Items.THIEVES_ARMBAND_1579) + } + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player!!, Quests.HEROES_QUEST) > 0 + + if(!started){ + if (checkQuestsAreComplete(player)) { + line(player, "I can start this quest by speaking to !!Achietties?? at the", line++) + line(player, "!!Heroes' Guild?? located !!North?? of !!Taverly??", line++) + line(player, "as all required quests are complete, and I have enough QP.", line++) + } else { + line(player, "I can start this quest by speaking to !!Achietties?? at the", line++) + line(player, "!!Heroes' Guild?? located !!North?? of !!Taverly?? after completing", line++) + line(player, "!!The Shield of Arrav??", line++, isQuestComplete(player, Quests.SHIELD_OF_ARRAV)) + line(player, "!!The Lost City??", line++, isQuestComplete(player, Quests.LOST_CITY)) + line(player, "!!Merlin's Crystal??", line++, isQuestComplete(player, Quests.MERLINS_CRYSTAL)) + line(player, "!!The Dragon Slayer??", line++, isQuestComplete(player, Quests.DRAGON_SLAYER)) + line(player, "!!and gaining 55 Quest Points??", line++, getQuestPoints(player) >= 55) + } + line(player, "To complete this quest I need:", line++, false) + line(player, "!!Level 25 Herblore??", line++, hasLevelStat(player, Skills.HERBLORE, 25)) + line(player, "!!Level 50 Mining??", line++, hasLevelStat(player, Skills.MINING, 50)) + line(player, "!!Level 53 Fishing??", line++, hasLevelStat(player, Skills.FISHING, 53)) + line(player, "!!Level 53 Cooking??", line++, hasLevelStat(player, Skills.COOKING, 53)) + } else if (stage < 100) { + line(player, "!!Achietties?? will let me into the !!Heroes' Guild?? if I can get:", line++) + + // This is completely dependent on what you have in your inventory. + if (inInventory(player, Items.FIRE_FEATHER_1583)) { + line(player, "An Entranan Firebird Feather - I now have one on me!", line++, true) + } else { + line(player, "An !!Entranan Firebird Feather?? - I should check on !!Entrana??", line++) + } + + // This is completely dependent on what you have in your inventory. + if (inInventory(player, Items.LAVA_EEL_2149)) { + line(player, "A cooked lava eel - I now have one on me!", line++, true) + } else { + line(player, "A !!cooked lava eel?? - I should speak to a !!Fishing Expert??", line++) + } + + if (isPhoenix(player)) { + if (inInventory(player, Items.THIEVES_ARMBAND_1579)) { + line(player, "A Master Thieves Armband - I now have one on me!", line++, true) + } else { + line(player, "A !!Master Thieves Armband?? - the !!Phoenix Gang can help me??", line++) + } + + if (!inInventory(player, Items.THIEVES_ARMBAND_1579)) { + if (stage >= 2) { + line(player, "I spoke to Straven about the Master Thieves Armband.", line++, true) + } + + if (stage >= 3) { + line(player, "Then I told Alfonse the password 'Gherkin'.", line++, true) + } else if (stage >= 2) { + line(player, "He told me I can get one by stealing !!Pete's Candlestick??", line++) + line(player, "I should use the password he gave me at !!Brimhaven??", line++) + } + + if (stage >= 4) { + line(player, "Charlie told me about a secret door into Scarface Pete's", line++, true) + line(player, "hideout, but he couldn't find a way of getting through it.", line++, true) + } else if (stage >= 3) { + line(player, "He said, secretly speak to !!Charlie?? round the back.", line++) + } + + if (stage >= 6) { + line(player, "A rival gang member collected a candlestick for me after I", line++, true) + line(player, "killed Grip and got the Treasure Room key for them.", line++, true) + line(player, "I gave Straven Scarface Pete's candlestick, and in reward", line++, true) + line(player, "he gave me a Master Thieves Armband to prove my skills.", line++, true) + } else if (stage >= 4) { + line(player, "Maybe !!another player?? can help to get through this !!door???.", line++) + } + } + } + if (isBlackArm(player)) { + if (inInventory(player, Items.THIEVES_ARMBAND_1579)) { + line(player, "A Master Thieves Armband - I now have one on me!", line++, true) + } else { + line(player, "A !!Master Thieves Armband?? - the !!Black Arms can help me??", line++) + } + + if (!inInventory(player, Items.THIEVES_ARMBAND_1579)) { + if (stage >= 2) { + line(player, "I spoke to Katrine about the Master Thieves Armband.", line++, true) + } + + if (stage >= 3) { + line(player, "I used the Black Arm password to enter the Brimhaven HQ.", line++, true) + } else if (stage >= 2) { + line(player, "She told me I can get one by stealing !!Pete's Candlestick??", line++) + line(player, "I should use the password she gave me at !!Brimhaven??", line++) + } + + if (stage >= 4) { + line(player, "I managed to pass myself off as Hartigen and enter the", line++, true) + line(player, "HQ.", line++, true) + } else if (stage >= 3) { + line(player, "I need to disguise myself as !!Hartigen the Black Knight?? in", line++) + line(player, "order to get inside !!Scarface Pete's hideout??", line++) + } + + if (stage >= 6) { + line(player, "I collected the candlesticks with the Treasure Room key", line++, true) + line(player, "after a rival gang member killed Grip.", line++, true) + line(player, "I gave Katrine Scarface Pete's candlestick, and in reward", line++, true) + line(player, "she gave me a Master Thieves Armband to prove my skills.", line++, true) + } else if (stage >= 4) { + line(player, "I can move around the hideout, but now I need Grips keys", line++) + line(player, "to get into the treasure room and get the candlesticks.", line++) + line(player, "I need !!another player's help?? with this, as it's so risky.", line++) + } + } + } + + if (allItemsInInventory(player)) { + line(player, "Now that I have !!all the required items??, I should go and speak to", line++) + line(player, "!!Achietties?? and give them to her", line++) + } + } else { + // Everything above is replaced by this. + line(player, "I gave Achietties an Entranan Firebird Feather, A cooked", line++, true) + line(player, "lava eel from a dangerous fishing spot and after some", line++, true) + line(player, "difficulty, a Master Thief Armband.", line++, true) + line(player, "Once I had handed these over to Achietties I had proved", line++, true) + line(player, "myself worthy of entrance to the Heroes' Guild.", line++, true) + line++ + line++ + line(player,"QUEST COMPLETE!", line) + } + } + + override fun reset(player: Player) { + if (getQuestStage(player, Quests.HEROES_QUEST) == 0) { + removeAttribute(player, attributeGruborLetsYouIn) + removeAttribute(player, attributeGripTookPapers) + removeAttribute(player, attributeGripSaidDuties) + removeAttribute(player, attributeHasOpenedBackdoor) + removeAttribute(player, attributeHasOpenedChestDoor) + + // For testing: if you set quest stage to 0, it will switch your gang (blackarm <-> phoenix) + // Remember to set stage to 0 twice to keep your gang. + println("Swapping gang for Heroes Quest.") + ShieldofArrav.swapGang(player) + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Heroes Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.DRAGON_BATTLEAXE_1377, 240, 277, 5) + + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"Access to the Heroes' Guild", ln++) + drawReward(player,"A total of 29,232 XP spread", ln++) + drawReward(player,"over twelve skills", ln++) + + rewardXP(player, Skills.ATTACK, 3075.0) + rewardXP(player, Skills.DEFENCE, 3075.0) + rewardXP(player, Skills.STRENGTH, 3075.0) + rewardXP(player, Skills.HITPOINTS, 3075.0) + rewardXP(player, Skills.RANGE, 2075.0) + rewardXP(player, Skills.FISHING, 2725.0) + rewardXP(player, Skills.COOKING, 2825.0) + rewardXP(player, Skills.WOODCUTTING, 1575.0) + rewardXP(player, Skills.FIREMAKING, 1575.0) + rewardXP(player, Skills.SMITHING, 2725.0) + rewardXP(player, Skills.MINING, 2575.0) + rewardXP(player, Skills.HERBLORE, 1325.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuestListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuestListener.kt new file mode 100644 index 000000000..8764e7ba2 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuestListener.kt @@ -0,0 +1,155 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.item.GroundItem +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class HeroesQuestListener: InteractionListener { + + override fun defineListeners() { + // Black arm gang office door. + on(Scenery.DOOR_2626, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 2 && + getAttribute(player, HeroesQuest.attributeGruborLetsYouIn, false) && + HeroesQuest.isBlackArm(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, GruborDialogueFile(), NPC(NPCs.GRUBOR_789)) + } + return@on true + } + + // Kitchen entrance + on(Scenery.DOOR_2628, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 3 && HeroesQuest.isPhoenix(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "This door is locked.") + } + return@on true + } + + // Kitchen wall + on(Scenery.WALL_2629, IntType.SCENERY, "push") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 4 && HeroesQuest.isPhoenix(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, CharlieTheCookDialogueFile(), NPC(NPCs.CHARLIE_THE_COOK_794)) + } + return@on true + } + + // Mansion frontdoor + on(Scenery.DOOR_2627, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 4 && HeroesQuest.isBlackArm(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, GarvDialogueFile(), NPC(NPCs.GARV_788)) + } + return@on true + } + + // Cupboard + + on(Scenery.CUPBOARD_2636, IntType.SCENERY, "search") { player, node -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> sendNPCDialogue(player, NPCs.PIRATE_GUARD_799, "I don't think Mr Grip will like you opening that. That's his private drinks cabinet.") .also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.NEUTRAL, "He won't notice me having a quick look.", 2), + Topic(FacialExpression.NEUTRAL, "Ok, I'll leave it.", END_DIALOGUE) + ) + 2 -> end().also { + val gripNpc = findNPC(NPCs.GRIP_792) + sendChat(gripNpc!!, "Stay out of my drinks cabinet!") + forceWalk(gripNpc, Location(2777, 3198, 0), "smart") + } + } + } + }) + return@on true + } + + // Mansion backdoor + on(Scenery.DOOR_2622, IntType.SCENERY, "open") { player, node -> + if (getAttribute(player, HeroesQuest.attributeHasOpenedBackdoor, false)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "This door is locked.") + } + return@on true + } + onUseWith(IntType.SCENERY, Items.MISCELLANEOUS_KEY_1586, Scenery.DOOR_2622) { player, used, with -> + setAttribute(player, HeroesQuest.attributeHasOpenedBackdoor, true) + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + return@onUseWith true + } + + // Chest door + on(Scenery.DOOR_2621, IntType.SCENERY, "open") { player, node -> + if (getAttribute(player, HeroesQuest.attributeHasOpenedChestDoor, false)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "This door is locked.") + } + return@on true + } + onUseWith(IntType.SCENERY, Items.GRIPS_KEY_RING_1588, Scenery.DOOR_2621) { player, used, with -> + setAttribute(player, HeroesQuest.attributeHasOpenedChestDoor, true) + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + return@onUseWith true + } + + // Chest + on(Scenery.CHEST_2632, IntType.SCENERY, "open"){ player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CHEST_2633, -1) + return@on true + } + on(Scenery.CHEST_2633, IntType.SCENERY, "close"){ player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CHEST_2632, -1) + return@on true + } + on(Scenery.CHEST_2633, IntType.SCENERY, "search"){ player, node -> + if (inInventory(player, Items.PETES_CANDLESTICK_1577)) { + sendMessage(player, "You search the chest but find nothing.") + } else { + if (getQuestStage(player, Quests.HEROES_QUEST) == 4) { + setQuestStage(player, Quests.HEROES_QUEST, 5) + } + sendDialogue(player, "You find two candlesticks in the chest. So that will be one for you, and one for the person who killed Grip for you.") + addItemOrDrop(player, Items.PETES_CANDLESTICK_1577, 2) + } + return@on true + } + + // + on(Items.FIRE_FEATHER_1583, IntType.GROUNDITEM, "take") { player, groundItem -> + if (inEquipment(player, Items.ICE_GLOVES_1580)) { + addItem(player, Items.FIRE_FEATHER_1583) + removeGroundItem(groundItem as GroundItem) + } else { + sendChat(player, "Ouch!") + player.impactHandler.manualHit(player, 9, ImpactHandler.HitsplatType.NORMAL) + sendMessage(player, "It is too hot to take. You need something cold to pick it up with.") + } + return@on true + } + + // OilFishingRodListener.kt + DrinkBlamishOilListener.kt + FinishedPotion.java + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/KatrineDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/KatrineDialogueFile.kt new file mode 100644 index 000000000..f5c3f1d56 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/KatrineDialogueFile.kt @@ -0,0 +1,127 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import org.rs09.consts.Items + +class KatrineDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // 0 is handled by default in the old KatrineDialogue. + b.onQuestStages(Quests.HEROES_QUEST, 1) + .playerl("Hey.") + .npcl("Hey.") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Who are all those people in there?") + .npcl("They're just various rogues and thieves.") + .playerl("They don't say a lot...") + .npcl("Nope.") + .end() + + optionBuilder.option_playerl("Is there any way I can get the rank of master thief?") + .npcl("Master thief? Ain't we the ambitious one!") + .npcl("Well, you're gonna have to do something pretty amazing.") + .playerl("Anything you can suggest?") + .npcl("Well, some of the MOST coveted prizes in thiefdom right now are in the pirate town of Brimhaven on Karamja.") + .npcl("The pirate leader Scarface Pete has a pair of extremely valuable candlesticks.") + .npcl("His security is VERY good.") + .npcl("We, of course, have gang members in a town like Brimhaven who may be able to help you.") + .npcl("Visit our hideout in the alleyway on palm street.") + .npcl("To get in you will need to tell them the secret password 'four leaved clover'.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 1) { + setQuestStage(player, Quests.HEROES_QUEST, 2) + } + } + + } + + // This is not authentic, she falls back to a boring default conversation, but I guess people might need help during the quest + b.onQuestStages(Quests.HEROES_QUEST, 2, 3, 4) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get the rank of master thief! Now pay attention.") + .npcl("Some of the MOST coveted prizes in thiefdom right now are in the pirate town of Brimhaven on Karamja.") + .npcl("The pirate leader Scarface Pete has a pair of extremely valuable candlesticks.") + .npcl("His security is VERY good.") + .npcl("We, of course, have gang members in a town like Brimhaven who may be able to help you.") + .npcl("Visit our hideout in the alleyway on palm street.") + .npcl("To get in you will need to tell them the secret password 'four leaved clover'.") + .end() + + // As FYI, the fallback for 2,3,4 is + /** + * .options() + * .let { optionBuilder -> + * optionBuilder.option_playerl("Who are all those people in there?") + * .npcl("They're just various rogues and thieves.") + * .playerl("They don't say a lot...") + * .npcl("Nope.") + * .end() + * optionBuilder.option("Teach me to be a top class criminal!") + * .playerl("Teach me to be a top class criminal.") + * .npcl("Teach yourself.") + * .end() + * + * + * + * Player: + * I have a candlestick now! + * Katrine: + * Good for you. I'll give a master thief's armband to the one who retrieved that. I know it wasn't you. + */ + + + b.onQuestStages(Quests.HEROES_QUEST, 5) + .branch { player -> + return@branch if (inInventory(player, Items.PETES_CANDLESTICK_1577)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Who are all those people in there?") + .npcl("They're just various rogues and thieves.") + .playerl("They don't say a lot...") + .npcl("Nope.") + .end() + optionBuilder.option("I have a candlestick now.") + .playerl("I have a candlestick now!") + .npcl("Wow... is... it REALLY it?") + .npcl("This really is a FINE bit of thievery.") + .npcl("Us thieves have been trying to get hold of this one for a while!") + .npc("You wanted to be ranked as a master thief didn't you?", "Well, I guess this just about ranks as good enough!") + .linel("Katrine gives you a master thief armband.") + .endWith { _, player -> + if (removeItem(player, Items.PETES_CANDLESTICK_1577)) { + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + if (getQuestStage(player, Quests.HEROES_QUEST) == 5) { + setQuestStage(player, Quests.HEROES_QUEST, 6) + } + } + } + + branch.onValue(0) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get the rank of master thief! Now pay attention.") + .npcl("Some of the MOST coveted prizes in thiefdom right now are in the pirate town of Brimhaven on Karamja.") + .npcl("The pirate leader Scarface Pete keeps an extremely valuable candlesticks.") + .npcl("His security is VERY good.") + .npcl("We, of course, have gang members in a town like Brimhaven who may be able to help you.") + .npcl("Visit our hideout in the alleyway on palm street.") + .npcl("To get in you will need to tell them the secret password 'four leaved clover'.") + .end() + } + } + + // I lost the armband and some stupid default shit. + b.onQuestStages(Quests.HEROES_QUEST, 6) + .playerl("I have lost my master thief's armband...") + .npcl("Lucky I 'ave a spare ain't it? Don't lose it again.") + .endWith { _, player -> + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + } + + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/StravenDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/StravenDialogueFile.kt new file mode 100644 index 000000000..68d236905 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/StravenDialogueFile.kt @@ -0,0 +1,73 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import org.rs09.consts.Items + +class StravenDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // 0 is handled by default in the old StravenDialogue. + b.onQuestStages(Quests.HEROES_QUEST, 1) + .playerl("How would I go about getting a Master Thief armband?") + .npcl("Ooh... tricky stuff. Took me YEARS to get that rank.") + .npcl("Well, what some of the more aspiring thieves in our gang are working on right now is to steal some very valuable candlesticks from Scarface Pete - the pirate leader on Karamja.") + .npcl("His security is excellent, and the target very valuable so that might be enough to get you the rank.") + .npcl("Go talk to our man Alfonse, the waiter in the Shrimp and Parrot.") + .npcl("Use the secret word 'gherkin' to show you're one of us.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 1) { + setQuestStage(player, Quests.HEROES_QUEST, 2) + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 2, 3, 4) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get a Master thief's armband! Now pay attention.") + .npcl("Some of the more aspiring thieves in our gang are working on right now is to steal some very valuable candlesticks from Scarface Pete - the pirate leader on Karamja.") + .npcl("His security is excellent, and the target very valuable so that might be enough to get you the rank.") + .npcl("Go talk to our man Alfonse, the waiter in the Shrimp and Parrot.") + .npcl("Use the secret word 'gherkin' to show you're one of us.") + .end() + + + b.onQuestStages(Quests.HEROES_QUEST, 5) + .branch { player -> + return@branch if (inInventory(player, Items.PETES_CANDLESTICK_1577)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("I have retrieved a candlestick!") + .npcl("Hmmm. Not bad, not bad. Let's see it, make sure it's genuine.") + .linel("You hand Straven the candlestick.") + .playerl("So is this enough to get me a Master Thief armband?") + .npcl("Hmm... I dunno... Aww, go on then. I suppose I'm in a generous mood today.") + .linel("Straven hands you a Master Thief armband.") + .endWith { _, player -> + if (removeItem(player, Items.PETES_CANDLESTICK_1577)) { + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + if (getQuestStage(player, Quests.HEROES_QUEST) == 5) { + setQuestStage(player, Quests.HEROES_QUEST, 6) + } + } + } + + branch.onValue(0) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get a Master thief's armband! Now pay attention.") + .npcl("Some of the more aspiring thieves in our gang are working on right now is to steal some very valuable candlesticks from Scarface Pete - the pirate leader on Karamja.") + .npcl("His security is excellent, and the target very valuable so that might be enough to get you the rank.") + .npcl("Go talk to our man Alfonse, the waiter in the Shrimp and Parrot.") + .npcl("Use the secret word 'gherkin' to show you're one of us.") + .end() + } + + // I lost the armband and some stupid default shit. + b.onQuestStages(Quests.HEROES_QUEST, 6) + .playerl("I'm afraid I've lost my master thief's armband.") + .npcl("Lucky for you I have a spare. Don't lose it again!") + .endWith { _, player -> + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/TrobertDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/TrobertDialogue.kt new file mode 100644 index 000000000..12561ad44 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/TrobertDialogue.kt @@ -0,0 +1,92 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class TrobertDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, TrobertDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TrobertDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TROBERT_1884) + } +} + +class TrobertDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // Technically this won't happen since you have to get past Grubor. + b.onQuestStages(Quests.HEROES_QUEST, 0, 1) + .npcl("Welcome to our Brimhaven headquarters. I'm Trobert and I'm in charge here.") + .playerl("Pleased to meet you.") + .npcl("Likewise.") + .end() + + b.onQuestStages(Quests.HEROES_QUEST, 2) + .npcl("Welcome to our Brimhaven headquarters. I'm Trobert and I'm in charge here.") + .options() + .let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("So can you help me get Scarface Pete's candlesticks?") + .goto(continuePath) + optionBuilder.option_playerl("Pleased to meet you.") + .npcl("Likewise.") + .goto(continuePath) + return@let continuePath.builder() + } + .playerl("So can you help me get Scarface Pete's candlesticks?") + .npcl("Well, we have made some progress there. We know that one of the only keys to Pete's treasure room is carried by Grip, the head guard, so we thought it might be good to get close to him somehow.") + .npcl("Grip was taking on a new deputy called Hartigen, an Asgarnian Black Knight who was deserting the Black Knight Fortress and seeking new employment here on Brimhaven.") + .npcl("We managed to waylay him on the journey here, and steal his I.D. papers. Now all we need is to find somebody willing to impersonate him and take the deputy role to get that key for us.") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("I volunteer to undertake that mission!") + .npcl("Good good. Well, here's the ID papers, take them and introduce yourself to the guards at Scarface Pete's mansion, we'll have that treasure in no time.") + .endWith { _, player -> + addItemOrDrop(player, Items.ID_PAPERS_1584) + if(getQuestStage(player, Quests.HEROES_QUEST) == 2) { + setQuestStage(player, Quests.HEROES_QUEST, 3) + } + } + + optionBuilder.option_playerl("Well, good luck then.") + .npcl("Someone will show up eventually.") + .end() + } + + b.onQuestStages(Quests.HEROES_QUEST, 3, 4, 5) + .branch { player -> + return@branch if (inInventory(player, Items.ID_PAPERS_1584)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("How's it going?") + .playerl("Fine, thanks.") + .end() + branch.onValue(0) + .playerl("I have lost Hartigen's ID papers.") + .npcl("Well, that was careless of you, wasn't it? Fortunately for you, he had a spare. Take this one, but please try to be more careful with this one.") + .endWith { _, player -> + addItemOrDrop(player, Items.ID_PAPERS_1584) + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 6, 100) + .npcl("How's it going?") + .playerl("Fine, thanks.") + .end() + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt index 116a95063..0b04d9ba1 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt @@ -1,8 +1,8 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold +import content.data.Quests import core.api.isQuestInProgress import core.api.produceGroundItem -import core.api.transformNpc import core.game.node.entity.Entity import core.game.node.entity.combat.CombatStyle import core.game.node.entity.npc.AbstractNPC @@ -44,7 +44,7 @@ class BerryNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, locati } override fun finalizeDeath(killer: Entity?) { - if (isQuestInProgress(killer as Player, TrollStronghold.questName, 8, 10)) { + if (isQuestInProgress(killer as Player, Quests.TROLL_STRONGHOLD, 8, 10)) { produceGroundItem(killer, Items.CELL_KEY_2_3137, 1, this.location) } super.finalizeDeath(killer) diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt index 2a2b2df0a..a1d76a63e 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold +import content.data.Quests import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -13,7 +14,7 @@ import org.rs09.consts.NPCs @Initializable class DadDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (getQuestStage(player!!, TrollStronghold.questName)) { + when (getQuestStage(player!!, Quests.TROLL_STRONGHOLD)) { in 3..4 -> { when (stage) { START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "What tiny human do in troll arena? Dad challenge human to fight!").also { stage++ } @@ -27,7 +28,7 @@ class DadDialogue(player: Player? = null) : DialoguePlugin(player) { 3 -> npcl(FacialExpression.OLD_HAPPY, "Tiny human brave. Dad squish!").also { stage++ } 4 -> npc!!.attack(player).also { npc!!.skills.lifepoints = npc!!.skills.maximumLifepoints // Reset dad to max hitpoints. - setQuestStage(player!!, TrollStronghold.questName, 4) + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 4) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt index 69b9d5334..4428bf902 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold +import content.data.Quests import core.api.setQuestStage import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -13,14 +14,14 @@ class DadDialogueFile(private val dialogueNum: Int = 0) : DialogueFile() { 1 -> when (stage) { START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "No human pass through arena without defeating Dad!").also { stage = END_DIALOGUE - setQuestStage(player!!, TrollStronghold.questName, 3) + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 3) } } 2 -> when (stage) { START_DIALOGUE -> npcl(FacialExpression.OLD_NORMAL, "Tiny human brave. Dad squish!").also { stage++ } 1 -> npc!!.attack(player).also { npc!!.skills.lifepoints = npc!!.skills.maximumLifepoints // Reset dad to max hitpoints. - setQuestStage(player!!, TrollStronghold.questName, 4) + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 4) stage = END_DIALOGUE } } @@ -31,7 +32,7 @@ class DadDialogueFile(private val dialogueNum: Int = 0) : DialogueFile() { Topic(FacialExpression.ANGRY_WITH_SMILE, "I'm not done yet! Prepare to die!", 2) ) 2 -> player!!.attack(npc).also { - setQuestStage(player!!, TrollStronghold.questName, 5) + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 5) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt index d7c5e58cd..f489aa1ed 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt @@ -1,7 +1,7 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold +import content.data.Quests import core.api.* -import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.combat.BattleState import core.game.node.entity.combat.CombatStyle @@ -27,7 +27,7 @@ class DadNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, location val player = entity.asPlayer() // Attack Dad. If quest is done, you cannot attack Dad. - when (getQuestStage(player, TrollStronghold.questName)) { + when (getQuestStage(player, Quests.TROLL_STRONGHOLD)) { 3 -> openDialogue(player, DadDialogueFile(2), this.asNpc()).also { return false } 4 -> { return attackable } in 5 .. 100 -> sendMessage(player, "You don't need to fight him again.").also { return false } @@ -44,8 +44,8 @@ class DadNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, location if (opponent.skills.lifepoints < 30) { player.properties.combatPulse.stop() opponent.properties.combatPulse.stop() - if (getQuestStage(player!!.asPlayer(), TrollStronghold.questName) == 4){ - setQuestStage(player!!.asPlayer(), TrollStronghold.questName, 5) + if (getQuestStage(player!!.asPlayer(), Quests.TROLL_STRONGHOLD) == 4){ + setQuestStage(player!!.asPlayer(), Quests.TROLL_STRONGHOLD, 5) } submitWorldPulse(object : Pulse(){ var counter = 0 @@ -64,8 +64,8 @@ class DadNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, location override fun finalizeDeath(killer: Entity?) { // In case Dad gets one shotted to death. super.finalizeDeath(killer) - if (getQuestStage(killer!!.asPlayer(), TrollStronghold.questName) == 4){ - setQuestStage(killer!!.asPlayer(), TrollStronghold.questName, 5) + if (getQuestStage(killer!!.asPlayer(), Quests.TROLL_STRONGHOLD) == 4){ + setQuestStage(killer!!.asPlayer(), Quests.TROLL_STRONGHOLD, 5) } } override fun handleTickActions() { diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt index 45318ea53..2575fc4b6 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -14,7 +15,7 @@ import org.rs09.consts.Items */ class DenulthDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, TrollStronghold.questName)) { + when (getQuestStage(player!!, Quests.TROLL_STRONGHOLD)) { in 1..7 -> { when (stage) { START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "How are you getting on with rescuing Godric?").also { stage++ } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt index aa9615ea7..4cd3a3f1a 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt @@ -1,30 +1,65 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold -import core.api.finishQuest -import core.api.getQuestStage +import content.data.Quests +import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.dialogue.Topic +import core.game.node.item.Item import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import org.rs09.consts.Items class DunstanDialogueFile : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, TrollStronghold.questName)) { + when (getQuestStage(player!!, Quests.TROLL_STRONGHOLD)) { in 1..10 -> { when (stage) { START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Have you managed to rescue Godric yet?").also { stage++ } 1 -> playerl(FacialExpression.FRIENDLY, "Not yet.").also { stage++ } 2 -> npcl(FacialExpression.FRIENDLY, "Please hurry! Who knows what they will do to him? Is there anything I can do in the meantime?").also { stage++ } 3 -> showTopics( + Topic(FacialExpression.THINKING, "Can you put some spikes on my Climbing boots?", 30), Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), - Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), + Topic(FacialExpression.NEUTRAL, "Nothing, thanks.", 20), ) 10 -> npcl(FacialExpression.FRIENDLY, "So you're a smithy are you?").also { stage++ } 11 -> playerl(FacialExpression.FRIENDLY, "I dabble.").also { stage++ } 12 -> npcl(FacialExpression.FRIENDLY, "A fellow smith is welcome to use my anvil!").also { stage++ } 13 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage++ } 14 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 3 } + 20 -> npcl(FacialExpression.NEUTRAL, "All right. Speak to you later then.").also { stage = END_DIALOGUE } + 30 -> playerl("Can you put some spikes on my Climbing boots?").also { stage++ } + 31 -> npcl("For you, no problem.").also { stage++ } + 32 -> npc("Do you realise that you can only use the Climbing", "boots right now? The Spiked boots can only be used in", "the Icelands but no ones been able to get there for", "years!").also { stage++ } + 33 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, but I still want them.", 40, true), + Topic(FacialExpression.NEUTRAL, "Oh OK, I'll leave them thanks.", 43), + ) + 40 -> { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.") + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + npcl("Sorry, I'll need an iron bar to make the spikes.") + stage = 3 + } else { + playerl("I don't have them on me.") + stage = 3 + } + } + 41 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { stage++ + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 43 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { + stage = 3 + } } } 11 -> { @@ -35,7 +70,7 @@ class DunstanDialogueFile : DialogueFile() { 3 -> npcl(FacialExpression.FRIENDLY, "I have very little to offer you by way of thanks, but perhaps you will accept these family heirlooms. They were found by my great-great-grandfather, but we still don't have any idea what they do.").also { stage++ } 4 -> { stage = END_DIALOGUE - finishQuest(player!!, TrollStronghold.questName) + finishQuest(player!!, Quests.TROLL_STRONGHOLD) } } } diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt index 1a0488e69..cee11ddfc 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt @@ -1,10 +1,7 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold -import content.region.kandarin.quest.grandtree.ForemanDialogue -import content.region.kandarin.quest.grandtree.TheGrandTree +import content.data.Quests import core.api.* -import core.game.interaction.IntType -import core.game.interaction.InteractionListener import core.game.node.entity.Entity import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player @@ -25,7 +22,7 @@ class TrollGeneralsNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id } override fun finalizeDeath(killer: Entity?) { - if(isQuestInProgress(killer as Player, TrollStronghold.questName, 1, 7)) { + if(isQuestInProgress(killer as Player, Quests.TROLL_STRONGHOLD, 1, 7)) { produceGroundItem(killer, Items.PRISON_KEY_3135, 1, this.location) } super.finalizeDeath(killer) diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt index 971e7f392..6630bfa14 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt @@ -1,51 +1,37 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau import core.api.* import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * Troll Stronghold Quest * @author ovenbread */ @Initializable -class TrollStronghold : Quest("Troll Stronghold",128, 127, 1, 317, 0, 1, 50) { +class TrollStronghold : Quest(Quests.TROLL_STRONGHOLD,128, 127, 1, 317, 0, 1, 50) { - /** - * 1 - Talked to Denulth to start the quest - * 3 - Enter the Arena with Dad - * 4 - Start fighting Dad - * 5 - Dad surrenders or gets killed, allowed to exit the Arena - * 8 - Unlocks Prison Gate - * 9 - Unlocked Mad Eadgar's cell - * 10 - Unlocked Godric's cell - * 11 - Unlocked both Mad Eadgar's and Godric's cell - * 100 - Finish at Dunstan - */ - companion object { - const val questName = "Troll Stronghold" - } override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) var line = 12 var stage = getStage(player) - var started = getQuestStage(player!!, questName) > 0 + var started = getQuestStage(player!!, Quests.TROLL_STRONGHOLD) > 0 if(!started){ line(player, "I can start this quest by speaking to !!Denulth?? in his tent at", line++) line(player, "the !!Imperial Guard camp?? in !!Burthorpe?? after completing the", line++) - line(player, "!!Death Plateau Quest??", line++, isQuestComplete(player, DeathPlateau.questName)) + line(player, "!!Death Plateau Quest??", line++, isQuestComplete(player, Quests.DEATH_PLATEAU)) line++ line(player, "To complete this quest I need:", line++) line(player, "Level 15 Agility.", line++, hasLevelStat(player, Skills.AGILITY, 15)) line(player, "I also need to be able to defeat a !!level 113 Troll??.", line++) line(player, "Level 30 Thieving might be useful.", line++, hasLevelStat(player, Skills.THIEVING, 30)) - if (isQuestComplete(player, DeathPlateau.questName) && hasLevelStat(player, Skills.AGILITY, 15) && hasLevelStat(player, Skills.THIEVING, 30)) { + if (isQuestComplete(player, Quests.DEATH_PLATEAU) && hasLevelStat(player, Skills.AGILITY, 15) && hasLevelStat(player, Skills.THIEVING, 30)) { line(player, "I have all the requirements to start this quest.", line++) } } else { @@ -61,10 +47,12 @@ class TrollStronghold : Quest("Troll Stronghold",128, 127, 1, 317, 0, 1, 50) { if (stage >= 5) { line(player, "I have defeated the !!Troll Champion??", line++, true) } else if (stage >= 3) { - line(player, "I have to defeat the !!Troll Champion??", line++) + line(player, "I have accepted the !!Troll Champion's?? challenge.", line++) } - if (stage in 5..7) { - line++ + line++ + if (stage >= 7) { + line(player, "I found my way into the Troll Stronghold", line++, true) + } else if (stage >= 5) { line(player, "I have to find a way to get into the !!Troll Stronghold??", line++) } line++ diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt index 9e03991ab..f276b3944 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt @@ -1,5 +1,6 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold +import content.data.Quests import core.api.* import core.game.global.action.DoorActionHandler import core.game.interaction.IntType @@ -22,12 +23,12 @@ class TrollStrongholdListener: InteractionListener { // Entrance to arena with Dad in it. on(intArrayOf(Scenery.ARENA_ENTRANCE_3782, Scenery.ARENA_ENTRANCE_3783), IntType.SCENERY, "open"){ player, node -> // Only get the dialogue once. - if (getQuestStage(player, TrollStronghold.questName) == 1) { + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 1) { openDialogue(player, DadDialogueFile(1), findNPC(NPCs.DAD_1125)!!) } // Only allow players through when they start Troll Stronghold. // No one is allowed to go to GWD unless they start the Troll Stronghold quest. - if (getQuestStage(player, TrollStronghold.questName) > 0) { + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) > 0) { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { sendMessage(player, "You need to start the Troll Stronghold quest.") @@ -37,7 +38,7 @@ class TrollStrongholdListener: InteractionListener { // Not allowed to exit arena into the troll stronghold until Dad is defeated. on(intArrayOf(Scenery.ARENA_EXIT_3785, Scenery.ARENA_EXIT_3786), IntType.SCENERY, "open"){ player, node -> - if (getQuestStage(player, TrollStronghold.questName) < 5){ + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) < 5){ openDialogue(player, DadDialogueFile(1), findNPC(NPCs.DAD_1125)!!) } else { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) @@ -47,12 +48,12 @@ class TrollStrongholdListener: InteractionListener { // Key to unlock the prison door on(Scenery.PRISON_DOOR_3780, IntType.SCENERY, "unlock"){ player, node -> - if (getQuestStage(player, TrollStronghold.questName) >= 8){ + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) >= 8){ DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { if (inInventory(player, Items.PRISON_KEY_3135)) { - if (getQuestStage(player, TrollStronghold.questName) == 5) { - setQuestStage(player, TrollStronghold.questName, 8) + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 5) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 8) } if (removeItem(player, Items.PRISON_KEY_3135)) { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) @@ -84,7 +85,7 @@ class TrollStrongholdListener: InteractionListener { 3 -> { val success: Boolean = success(player, Skills.THIEVING) if(success){ - if(isQuestInProgress(player, TrollStronghold.questName, 8, 10)) { + if(isQuestInProgress(player, Quests.TROLL_STRONGHOLD, 8, 10)) { addItem(player, Items.CELL_KEY_1_3136) sendMessage(player, "You find a small key on Twig.") } else { @@ -124,7 +125,7 @@ class TrollStrongholdListener: InteractionListener { 3 -> { val success: Boolean = success(player, Skills.THIEVING) if(success){ - if(isQuestInProgress(player, TrollStronghold.questName, 8, 10)) { + if(isQuestInProgress(player, Quests.TROLL_STRONGHOLD, 8, 10)) { addItem(player, Items.CELL_KEY_2_3137) sendMessage(player, "You find a small key on Berry.") } else { @@ -149,10 +150,10 @@ class TrollStrongholdListener: InteractionListener { fun unlockMadEadgarCellDoor(player: Player, node: Node) { if (inInventory(player, Items.CELL_KEY_1_3136)){ sendMessage(player, "You unlock the cell door.") - if (getQuestStage(player, TrollStronghold.questName) == 8) { - setQuestStage(player, TrollStronghold.questName, 9) - } else if (getQuestStage(player, TrollStronghold.questName) == 10) { - setQuestStage(player, TrollStronghold.questName, 11) + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 8) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 9) + } else if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 10) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 11) } // Animate Mad Eadgar leaving cell. val npc = findNPC(NPCs.EADGAR_1113)!! @@ -219,10 +220,10 @@ class TrollStrongholdListener: InteractionListener { fun unlockGodricCellDoor(player: Player, node: Node) { if (inInventory(player, Items.CELL_KEY_2_3137)){ sendMessage(player, "You unlock the cell door.") - if (getQuestStage(player, TrollStronghold.questName) == 8) { - setQuestStage(player, TrollStronghold.questName, 10) - } else if (getQuestStage(player, TrollStronghold.questName) == 9) { - setQuestStage(player, TrollStronghold.questName, 11) + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 8) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 10) + } else if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 9) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 11) } // Animate Godric leaving cell. val npc = findNPC(NPCs.GODRIC_1114)!! @@ -292,7 +293,7 @@ class TrollStrongholdListener: InteractionListener { // Reentry Secret Door on(Scenery.SECRET_DOOR_3762, IntType.SCENERY, "open"){ player, _ -> - if (getQuestStage(player, TrollStronghold.questName) >= 8) { + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) >= 8) { player.properties.teleportLocation = Location.create(2824, 10050, 0) } else { sendMessage(player, "The door is locked.") diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt index 97e253d71..deb316aeb 100644 --- a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt @@ -1,16 +1,14 @@ package content.region.asgarnia.burthorpe.quest.trollstronghold -import core.api.getQuestStage +import content.data.Quests import core.api.isQuestInProgress import core.api.produceGroundItem -import core.api.transformNpc import core.game.node.entity.Entity import core.game.node.entity.combat.CombatStyle import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player import core.game.world.map.Location import core.plugin.Initializable -import core.tools.RandomFunction import org.rs09.consts.Items import org.rs09.consts.NPCs @@ -46,7 +44,7 @@ class TwigNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, locatio } override fun finalizeDeath(killer: Entity?) { - if (isQuestInProgress(killer as Player, TrollStronghold.questName, 8, 10)) { + if (isQuestInProgress(killer as Player, Quests.TROLL_STRONGHOLD, 8, 10)) { produceGroundItem(killer, Items.CELL_KEY_1_3136, 1, this.location) } super.finalizeDeath(killer) diff --git a/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java index a4a58570c..b811dbc74 100644 --- a/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java +++ b/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java @@ -5,6 +5,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the oracle dialogue plugin related to dragon slayer. @@ -43,7 +44,7 @@ public final class OracleDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Dragon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); switch (quest.getStage(player)) { case 20: player("I seek a piece of the map to the island of Crandor."); diff --git a/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt b/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt index fe7c09060..b4d949075 100644 --- a/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt +++ b/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt @@ -1,56 +1,80 @@ package content.region.asgarnia.dialogue import content.global.skill.crafting.TanningProduct +import core.api.amountInInventory +import core.api.inInventory import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC import core.plugin.Initializable +import org.rs09.consts.Items import org.rs09.consts.NPCs import core.tools.END_DIALOGUE /** + * Handles the Crafting Guild Tanner's dialogue. * @author bushtail */ @Initializable class TannerDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun newInstance(player: Player) : DialoguePlugin { + override fun newInstance(player: Player): DialoguePlugin { return TannerDialogue(player) } - override fun open(vararg args: Any?) : Boolean { + override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC npcl(FacialExpression.NEUTRAL, "Greetings friend. I am a manufacturer of leather.") stage = 0 return true } - override fun handle(interfaceId: Int, buttonId: Int) : Boolean { - when(stage) { - 0 -> options("Can I buy some leather then?", "Leather is rather weak stuff.").also{ stage++ } - 1 -> when(buttonId) { - 1 -> player(FacialExpression.ASKING,"Can I buy some leather then?").also{ stage = 10 } - 2 -> player(FacialExpression.SUSPICIOUS, "Leather is rather weak stuff.").also { stage = 20 } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + var hasHides = false + + for (tanningProduct in TanningProduct.values()) { + if (inInventory(player, tanningProduct.item)) { + hasHides = true + break + } + } + + if(hasHides) { + npcl(FacialExpression.FRIENDLY, "I see you have brought me some hides. Would you like me to tan them for you?").also { stage = 10 } + } else { + options("Can I buy some leather?", "Leather is rather weak stuff.").also { stage = 20 } + } } - 10 -> npcl(FacialExpression.FRIENDLY, "Certainly!").also { stage = 30 } - 20 -> npcl(FacialExpression.NOD_YES, "Normal leather may be quite weak, but it's very cheap - I " + - "make it from cowhides for only 1 gp per hide - and it's so easy to craft that anyone can work with it.").also{ stage++ } - 21 -> npcl(FacialExpression.HALF_THINKING, "Alternatively you could try hard leather. It's not so easy " + - "to craft, but I only charge 3 gp per cowhide to prepare it, and it makes much sturdier armour.").also{ stage++ } - 22 -> npcl(FacialExpression.FRIENDLY, "I can also tan snake hides and dragonhides, suitable for crafting" + - "into the highest quality armour for rangers.").also{ stage++ } - 23 -> player(FacialExpression.NEUTRAL, "Thanks, I'll bear it in mind.").also { stage = END_DIALOGUE } - 30 -> { - end() - TanningProduct.open(player, npc.id) + 10 -> options("Yes please.", "No thanks.").also { stage++ } + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes please.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No thanks.").also { stage = 13 } } + + 12 -> end().also { TanningProduct.open(player, NPCs.TANNER_804) } + 13 -> npcl(FacialExpression.FRIENDLY, "Very well, @g[sir,madam], as you wish.").also { stage = END_DIALOGUE } + + 20 -> when (buttonId) { + 1 -> playerl(FacialExpression.ASKING, "Can I buy some leather?").also { stage = 21 } + 2 -> playerl(FacialExpression.SUSPICIOUS, "Leather is rather weak stuff.").also { stage = 22 } + } + + 21 -> npcl(FacialExpression.FRIENDLY, "I make leather from animal hides. Bring me some cowhides and one gold coin per hide, and I'll tan them into soft leather for you.").also { stage = END_DIALOGUE } + + 22 -> npcl(FacialExpression.NOD_YES, "Normal leather may be quite weak, but it's very cheap - I make it from cowhides for only 1 gp per hide - and it's so easy to craft that anyone can work with it.").also { stage++ } + 23 -> npcl(FacialExpression.HALF_THINKING, "Alternatively you could try hard leather. It's not so easy to craft, but I only charge 3 gp per cowhide to prepare it, and it makes much sturdier armour.").also { stage++ } + 24 -> npcl(FacialExpression.FRIENDLY, "I can also tan snake hides and dragonhides, suitable for crafting into the highest quality armour for rangers.").also { stage++ } + 25 -> playerl(FacialExpression.NEUTRAL, "Thanks, I'll bear it in mind.").also { stage = END_DIALOGUE } } return true } - override fun getIds() : IntArray { + + override fun getIds(): IntArray { return intArrayOf(NPCs.TANNER_804) } diff --git a/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java index 761c0977c..b11f3845c 100644 --- a/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java +++ b/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue plugin used for thurgo. @@ -77,7 +78,7 @@ public final class ThuroDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("The Knight's Sword"); + quest = player.getQuestRepository().getQuest(Quests.THE_KNIGHTS_SWORD); player.removeAttribute("thurgo:1"); switch (quest.getStage(player)) { default: @@ -154,7 +155,7 @@ public final class ThuroDialogue extends DialoguePlugin { stage = 14; return true; } - player.getInventory().add(player.getSkills().getMasteredSkills() >= 1 ? ITEMS[1] : ITEMS[0]); + player.getInventory().add(player.getSkills().getMasteredSkills() > 1 ? ITEMS[1] : ITEMS[0]); player.getInventory().add(ITEMS[2]); interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "There you go! You're truley a master of Smithing."); stage = 16; @@ -487,7 +488,7 @@ public final class ThuroDialogue extends DialoguePlugin { stage = 14; return true; } - player.getInventory().add(player.getSkills().getMasteredSkills() >= 1 ? ITEMS[1] : ITEMS[0]); + player.getInventory().add(player.getSkills().getMasteredSkills() > 1 ? ITEMS[1] : ITEMS[0]); player.getInventory().add(ITEMS[2]); interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "There you go! You're truley a master of Smithing."); stage = 16; diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt index a829c840b..0d8e029eb 100644 --- a/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt @@ -16,12 +16,13 @@ import core.game.world.map.Location import core.plugin.Initializable import core.tools.END_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests @Initializable class DoricDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - val qStage = getQuestStage(player, "Doric's Quest") + val qStage = getQuestStage(player, Quests.DORICS_QUEST) if(qStage == 0) { npcl(FacialExpression.OLD_NORMAL, "Hello traveller, what brings you to my humble smithy?").also { stage = 0 } } else if(qStage in 1..99) { diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java index 5d026893d..8fe25153e 100644 --- a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java @@ -10,6 +10,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.Initializable; import core.game.world.GameWorld; +import content.data.Quests; /** * Represents the falador squire dialogue plugin. @@ -59,7 +60,7 @@ public final class FaladorSquireDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("The Knight's Sword"); + quest = player.getQuestRepository().getQuest(Quests.THE_KNIGHTS_SWORD); interpreter.sendOptions("What do you want to do?", "Chat", "Talk about the Falador Achievement Diary"); stage = -1; replacementReward = AchievementDiary.canReplaceReward(player, DiaryType.FALADOR, level); diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.java deleted file mode 100644 index 0332c725b..000000000 --- a/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.java +++ /dev/null @@ -1,89 +0,0 @@ -package content.region.asgarnia.falador.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue used for sir tiffy. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class SirTiffyCashienDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code SirTiffyCashienDialogue} {@code Object}. - */ - public SirTiffyCashienDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code SirTiffyCashienDialogue} {@code Object}. - * @param player the player. - */ - public SirTiffyCashienDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new SirTiffyCashienDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What ho, sirrag.", "Spiffing day for a walk in the park, what?"); - stage = 1; - break; - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Spiffing?"); - stage = 2; - break; - case 2: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Absolutely, top-hole!", "Well, can't stay and chat all day, dontchaknow!", "Ta-ta for now!"); - stage = 10; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Erm...goodbye."); - stage = 4; - break; - case 4: - end(); - break; - case 10: - npc("Would you like to look at my wares?"); - stage++; - break; - case 11: - player("Yes, please."); - stage++; - break; - case 12: - npc.openShop(player); - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2290 }; - } -} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.kt new file mode 100644 index 000000000..70abbe778 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.kt @@ -0,0 +1,120 @@ +package content.region.asgarnia.falador.dialogue + +import content.data.Quests +import content.region.asgarnia.falador.quest.recruitmentdrive.SirTiffyCashienDialogueFile +import core.ServerConstants +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class SirTiffyCashienDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + + // Completed Recruitment Drive & Start Wanted!! Quest + if (isQuestComplete(player!!, Quests.RECRUITMENT_DRIVE)) { + openDialogue(player, SirTiffyCashienAfterRecruitmentDriveQuestDialogueFile(), npc) + return true + } + + // Recruitment Drive Quest + if (isQuestInProgress(player!!, Quests.RECRUITMENT_DRIVE, 1, 99)) { + openDialogue(player, SirTiffyCashienDialogueFile(), npc) + return true + } + + // Fallback to default. + when (stage) { + START_DIALOGUE -> player("Hello.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "What ho, ${if (player.isMale) "sirrah" else "milady"}.", "Spiffing day for a walk in the park, what?").also { stage++ } + 2 -> player(FacialExpression.THINKING, "Spiffing?").also { stage++ } + 3 -> npc(FacialExpression.FRIENDLY, "Absolutely, top-hole!", "Well, can't stay and chat all day, dontchaknow!", "Ta-ta for now!").also { stage++ } + 4 -> player(FacialExpression.THINKING, "Erm...goodbye.").also { stage = END_DIALOGUE } + } + + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirTiffyCashienDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_TIFFY_CASHIEN_2290) + } +} + +// Move this to Wanted!! Quest. +class SirTiffyCashienAfterRecruitmentDriveQuestDialogueFile : DialogueBuilderFile() { + private fun dialogueChangeSpawnPoint(builder: DialogueBuilder, place: String, location: Location, tiffyLine1: String, tiffyLine2: String): DialogueBuilder { + return builder.npcl("${tiffyLine1} Are you sure?") + .options().let { optionBuilder -> + optionBuilder.option("Yes, I want to respawn in $place.") + .playerl("Yes, I want to respawn in $place.") + .npcl(tiffyLine2) + .endWith { _, player -> + setAttribute(player, "/save:spawnLocation", location) + player.properties.spawnLocation = location + } + optionBuilder.option("Actually, no thanks. I like my respawn point.") + .playerl("Actually, no thanks. I like my respawn point.") + .npcl("As you wish, what? Ta-ta for now.") + } + } + + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npc(FacialExpression.HAPPY, "What ho, @g[sirrah,milady].", "Jolly good show on the old training grounds thingy,", "what?") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Do you have any jobs for me yet?") + .npcl("Sorry dear @g[boy,gal] but we are still in the process of organising.") + .npcl("I'm sure that we will have something for you soon, so please feel free to check back later.") + // Started of Wanted! quest + .end() + optionBuilder.option("Can you explain the Gaze of Saradomin to me?") + .playerl("I don't really understand this 'Gaze of Saradomin' thing... Do you think you could explain what it does for me?") + .npcl("Certainly @g[sirrah,milady]! As you know, we Temple Knights are personally favoured by Saradomin himself.") + .npcl("And when I say personally favoured, I don't mean that sometime off in the future he's going to buy us all a drink!") + .npcl("He watches over each of us, and when we die he catches us as we fall, and ensures we arrive back at Falador castle safe and sound.") + .npcl("We usually lose some equipment when he does so, but it's a small price to pay to be hale and hearty again, what?") + .npcl("Some lucky fellows have a similar system going already, but when they die they spawn in that squalid little swamp village Lumbridge.") + .playerl("Yeah, what kind of person would want to spawn there... Certainly not me, and I never have! Honest!") + .npcl("Well, you should be glad that we offer you a step up then! Falador is clearly a far superior town to spend your time in!") + .npcl("Was there something else you wanted to ask good old Tiffy, @g[sirrah,milady]?") + .end() + optionBuilder.option("Can I buy some armour?") + .playerl("Can I buy some armour?") + // Recruitment Drive -> Initiate level, Slug Menace -> Proselyte level + .npcl("Of course dear @g[boy,gal]. I can sell you up to Initiate level items only I'm afraid.") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("Can I switch respawns please?") + .branch { player -> if (player.properties.spawnLocation == ServerConstants.HOME_LOCATION) { 1 } else { 0 } } + .let { branch -> + dialogueChangeSpawnPoint( + branch.onValue(1), + "Falador", Location(2971, 3340, 0), //https://www.youtube.com/watch?v=Mm15dHuIaVg + "Ah, so you'd like to respawn in Falador, the good old homestead!", + "Top-hole, what? Good old Fally is definitely the hot-spot nowadays!" + ) + dialogueChangeSpawnPoint( + branch.onValue(0), + "Lumbridge", ServerConstants.HOME_LOCATION ?: Location(3222, 3218, 0), + "What? You're saying you want to respawn in Lumbridge?", + "Why anyone would want to visit that smelly little swamp village of oiks is quite beyond me, I'm afraid, but the deed is done now." + ) + } + optionBuilder.option("Goodbye.") + .playerl("Well, see you around Tiffy.") + .npcl(FacialExpression.HAPPY,"Ta-ta for now, old bean!") + .end() + } + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt index 4d42d5d9f..b26643bba 100644 --- a/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt @@ -3,12 +3,12 @@ package content.region.asgarnia.falador.dialogue import content.data.tables.BirdNest import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player -import core.game.node.entity.player.link.diary.DiaryType -import core.game.node.item.GroundItemManager import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items -import core.game.diary.DiaryLevel +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.link.diary.* /** * Represents the Wyson the gardener dialogue. @@ -16,46 +16,53 @@ import core.game.diary.DiaryLevel * @version 1.0 */ @Initializable -class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { - /** - * If its a bird nest reward. - */ - private var birdNest = false - - /** - * Constructs a new `WysonTheGardenerDialogue` `Object`. - */ - constructor() { - /** - * empty. - */ - } +class WysonTheGardenerDialogue(player: Player? = null) : DialoguePlugin(player) { /** * Constructs a new `WysonTheGardenerDialogue` `Object`. + * Mole part dialogue source: https://www.youtube.com/watch?v=Dw-P9T7EhZk and https://www.youtube.com/watch?v=krZiIRupKbs * @param player the player. */ - constructor(player: Player?) : super(player) {} + //constructor(player: Player?) : super(player) {} - override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + override fun newInstance(player: Player): DialoguePlugin { return WysonTheGardenerDialogue(player) } + /** + * Choose greeting. Either you have mole parts or just the normal greeting. + */ override fun open(vararg args: Any): Boolean { npc = args[0] as NPC - birdNest = player.inventory.containsItem(MOLE_CLAW) || player.inventory.containsItem(MOLE_SKIN) - if (birdNest) { - npc("If I'm not mistaken, you've got some mole bits there!", "I'll trade 'em for bird nest if ye likes.") + if (inInventory(player, Items.MOLE_CLAW_7416, 1) && inInventory(player, Items.MOLE_SKIN_7418, 1)) { + npc("If I'm not mistaken, you've got some claws and skin", " from a big mole there! I'll trade 'em for bird nests if ye", "likes. Or was ye wantin' some woad leaves instead?") + stage = 102 + return true + } + if (inInventory(player, Items.MOLE_SKIN_7418, 1)) { + npc("If I'm not mistaken, you've got some skin from a big", "mole there! I'll trade it for bird nests if ye likes. Or", "was ye wantin' some woad leaves instead?") stage = 100 return true } + if (inInventory(player, Items.MOLE_CLAW_7416, 1)) { + npc("If I'm not mistaken, you've got some claws from a big", "mole there! I'll trade it for bird nests if ye likes. Or", "was ye wantin' some woad leaves instead?") + stage = 101 + return true + } npc("I'm the head gardener around here.", "If you're looking for woad leaves, or if you need help", "with owt, I'm yer man.") stage = 0 return true } + /** + * Dialogue. + */ override fun handle(interfaceId: Int, buttonId: Int): Boolean { when (stage) { + + /** + * Dialogue options: woad leaves. + */ 0 -> { options("Yes please, I need woad leaves.", "Sorry, but I'm not interested.") stage = 1 @@ -105,15 +112,15 @@ class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { npc("Mmmm... ok, that sounds fair.") stage = 131 } - 131 -> if (player.inventory.contains(995, 15)) { - player.inventory.remove(COINS[0]) - player.inventory.add(WOAD_LEAF) + 131 -> if (removeItem(player,Item(Items.COINS_995, 15) ,Container.INVENTORY)) { + addItemOrDrop(player, Items.WOAD_LEAF_1793, 1) + player("Thanks.") - player.packetDispatch.sendMessage("You buy a woad leaf from Wyson.") + sendMessage(player, "You buy a woad leaf from Wyson.") stage = 132 } else { end() - player.packetDispatch.sendMessage("You need 15 cold coins to buy a woad leaf.") + sendMessage(player, "You need 15 gold coins to buy a woad leaf.") } 132 -> { npc("I'll be around if you have any more gardening needs.") @@ -121,35 +128,70 @@ class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { } 133 -> end() 140 -> { - npc("Thanks for being generous", "here's an extra woad leave.") + npc("Thanks for being generous", "here's an extra woad leaf.") stage = 141 } - 141 -> if (player.inventory.contains(995, 20)) { - player.inventory.remove(COINS[1]) - var i = 0 - while (i < 2) { - player.inventory.add(WOAD_LEAF, player) - i++ - } + 141 -> if (removeItem(player,Item(Items.COINS_995, 20) ,Container.INVENTORY)) { + addItemOrDrop(player, Items.WOAD_LEAF_1793, 2) player("Thanks.") - player.packetDispatch.sendMessage("You buy two woad leaves from Wyson.") + sendMessage(player, "You buy two woad leaves from Wyson.") stage = 132 } else { end() - player.packetDispatch.sendMessage("You need 15 cold coins to buy a woad leaf.") + sendMessage(player, "You need 20 gold coins to buy a woad leaf.") } 200 -> { npc("Fair enough.") stage = 201 } 201 -> end() + + /** + * Dialogue options: mole parts. + */ 100 -> { - options("Yes, I will trade the mole claws.", "Okay, I will trade the mole skin.", "I'd like to trade both.", "No, thanks.") + options("Ok, I will trade the mole skin.", "Yes please, I need woad leaves.", "Sorry, but I'm not interested.") stage = 900 } + 101 -> { + options("Yeah, I will trade the mole claws.", "Yes please, I need woad leaves.", "Sorry, but I'm not interested.") + stage = 901 + } + 102 -> { + options("Yeah, I will trade the mole claws.", "Okay, I will trade the mole skin.", "Alright, I'll trade the claws and skin.", "Yes please, I need woad leaves.", "Sorry, but I'm not interested.") + stage = 902 + } 900 -> when (buttonId) { 1 -> { - player("Yes, I will trade the mole claws.") + player("Ok, I will trade the mole skin.") + stage = 920 + } + 2 -> { + player("Yes please, I need woad leaves.") + stage = 10 + } + 3 -> { + player("Sorry, but I'm not interested.") + stage = 200 + } + } + 901 -> when (buttonId) { + 1 -> { + player("Yeah, I will trade the mole claws.") + stage = 910 + } + 2 -> { + player("Yes please, I need woad leaves.") + stage = 10 + } + 3 -> { + player("Sorry, but I'm not interested.") + stage = 200 + } + } + 902 -> when (buttonId) { + 1 -> { + player("Yeah, I will trade the mole claws.") stage = 910 } 2 -> { @@ -157,37 +199,48 @@ class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { stage = 920 } 3 -> { - player("I'd like to trade both.") + player("Alright, I'll trade the claws and skin.") stage = 930 } 4 -> { - player("No, thanks.") - stage = 999 + player("Yes please, I need woad leaves.") + stage = 10 + } + 5 -> { + player("Sorry, but I'm not interested.") + stage = 200 } } 910 -> { - if (!player.inventory.containsItem(MOLE_CLAW)) { + if (!inInventory(player, Items.MOLE_CLAW_7416, 1)) { player("Sorry, I don't have any mole claws.") stage = 999 + } else { + addClawRewards() + npc("Pleasure doing business with ya.") + stage = 999 } - end() - addRewards() } 920 -> { - if (!player.inventory.containsItem(MOLE_SKIN)) { + if (!inInventory(player, Items.MOLE_SKIN_7418, 1)) { player("Sorry, I don't have any mole skins.") stage = 999 + } else { + addSkinRewards() + npc("Pleasure doing business with ya.") + stage = 999 } - end() - addRewards() } 930 -> { - if (!player.inventory.containsItem(MOLE_CLAW) && !player.inventory.containsItem(MOLE_SKIN)) { + if (!inInventory(player, Items.MOLE_CLAW_7416, 1) || !inInventory(player, Items.MOLE_SKIN_7418, 1)) { player("Sorry, I don't have any.") stage = 999 + } else { + addClawRewards() + addSkinRewards() + npc("Pleasure doing business with ya.") + stage = 999 } - addRewards() - end() } 999 -> end() } @@ -196,26 +249,31 @@ class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { /** * Adds nests. - * @param nestAmount the amount. */ - private fun addRewards() { - val moleClaws = player.inventory.getAmount(Items.MOLE_CLAW_7416) - val moleSkin = player.inventory.getAmount(Items.MOLE_SKIN_7418) - val nestAmount = moleClaws + moleSkin - - //Remove claws and skins - player.inventory.remove(Item(Items.MOLE_CLAW_7416,moleClaws)) - player.inventory.remove(Item(Items.MOLE_SKIN_7418, moleSkin)) - - //Add white lily seeds if the player has the hard diary done - if(moleSkin > 0 && player.achievementDiaryManager.getDiary(DiaryType.FALADOR).checkComplete(DiaryLevel.HARD)) { - player.inventory.add(Item(14589, moleSkin), player) + private fun addClawRewards() { + // count the number of claws + val nestAmount = amountInInventory(player, Items.MOLE_CLAW_7416) + // remove the counted number of skins + if(removeItem(player, Item(Items.MOLE_CLAW_7416, nestAmount), Container.INVENTORY)){ + // add the counted number of nests. one by one so they each have random contents + for (i in 0 until nestAmount) { + addItemOrDrop(player, BirdNest.getRandomNest(true).nest.id, 1) + } } + } - //Add nests - for (i in 0 until nestAmount) { - if(!player.inventory.add(Item(BirdNest.getRandomNest(true).nest.id, 1), player)){ - GroundItemManager.create(Item(BirdNest.getRandomNest(true).nest.id,1),player.location,player) + private fun addSkinRewards() { + // count the number of skins + val nestAmount = amountInInventory(player, Items.MOLE_SKIN_7418) + // remove the counted number of skins + if(removeItem(player, Item(Items.MOLE_SKIN_7418, nestAmount), Container.INVENTORY)) { + // add the counted number of nests. one by one so they each have random contents + // if Falador Hard diary is complete, add a white lilly seed + for (i in 0 until nestAmount) { + addItemOrDrop(player, BirdNest.getRandomNest(true).nest.id, 1) + if (player.achievementDiaryManager.getDiary(DiaryType.FALADOR).isComplete(2)) { + addItemOrDrop(player, Items.WHITE_LILY_SEED_14589, 1) + } } } } @@ -224,25 +282,4 @@ class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { return intArrayOf(36) } - companion object { - /** - * Represents the coins item that can be used. - */ - private val COINS = arrayOf(Item(995, 15), Item(995, 20)) - - /** - * Represents the woad leaf item. - */ - private val WOAD_LEAF = Item(1793, 1) - - /** - * The mole claw item. - */ - private val MOLE_CLAW = Item(7416) - - /** - * The mole skin. - */ - private val MOLE_SKIN = Item(7418) - } } \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt b/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt index 4578a23ee..aac922c9a 100644 --- a/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt +++ b/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt @@ -19,6 +19,7 @@ import core.game.diary.DiaryEventHookBase import core.game.diary.DiaryLevel import core.game.event.* import core.game.node.entity.skill.Skills +import core.game.world.map.Location class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) { companion object { @@ -32,7 +33,7 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) { private val WAYNES_CHAINS_AREA = ZoneBorders(2969, 3310, 2975, 3314) private val SARAHS_FARMING_SHOP_AREA = ZoneBorders(3021, 3285, 3040, 3296) private val FALADOR_GENERAL_AREA = ZoneBorders(2934, 3399, 3399, 3307) - private val CHEMIST_AREA = ZoneBorders(2929, 3213, 2936, 3207) + private val CHEMIST_AREA = ZoneBorders(2925, 3213, 2939, 3207) private val PORT_SARIM_FLOWER_PATCH = ZoneBorders(3053, 3306, 3056, 3309) @@ -211,6 +212,9 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) { ) } } + if (event.npc.id == NPCs.MOGRE_114){ + finishTask(player, DiaryLevel.HARD, HardTasks.MUDSKIPPER_POINT_KILL_MOGRE) + } } override fun onItemPurchasedFromShop(player: Player, event: ItemShopPurchaseEvent) { @@ -283,4 +287,14 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) { } } } + + override fun onPrayerPointsRecharged(player: Player, event: PrayerPointsRechargeEvent) { + if (event.altar.id == Scenery.ALTAR_39842 && event.altar.location == Location(2995, 3177, 0)) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PORT_SARIM_RECHARGE_PRAYER_POINTS + ) + } + } } \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/BankNotices.kt b/Server/src/main/content/region/asgarnia/falador/handlers/BankNotices.kt new file mode 100644 index 000000000..11a124e8b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/BankNotices.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.falador.handlers + +import content.global.handlers.iface.ScrollInterface +import content.global.handlers.iface.ScrollLine +import core.game.interaction.InteractionListener +import org.rs09.consts.Components +import org.rs09.consts.Scenery + +class BankNotices : InteractionListener { + companion object { + val CONTENTS_PIN = arrayOf( + ScrollLine("If you're worried about someone stealing items from your",3), + ScrollLine("bank, why not protect yourself with a Bank PIN?",4), + + ScrollLine("A Bank PIN is a four-digit number. It's like a password that",6), + ScrollLine("protects your bank account. If you set one, you'll be asked to",7), + ScrollLine("enter it before you can take items out of the bank.",8), + + ScrollLine("If you're interested, speak to the bankers and ask about Bank",10), + ScrollLine("PINs.",11), + + ScrollLine("But remember, KEEP YOUR PIN SECRET!",13), + ) + + val CONTENTS_PASSWORD = arrayOf( + ScrollLine("The Bank of RuneScape would like to remind customers that",4), + ScrollLine("they should NEVER tell ANYONE their password.",5), + + ScrollLine("If someone asks you to say your password, please report",7), + ScrollLine("them using the 'Report Abuse' button at the bottom of your",8), + ScrollLine("screen. ",9), + + ScrollLine("Change your password regularly, and make sure no-one else",11), + ScrollLine("could easily guess it!",12), + ) + } + + override fun defineListeners() { + on(Scenery.NOTICEBOARD_11755, SCENERY, "read") { player, _ -> + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, CONTENTS_PIN) + return@on true + } + on(Scenery.NOTICEBOARD_11756, SCENERY, "read") { player, _ -> + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, CONTENTS_PASSWORD) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java b/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java index 6564c96dd..20edbb3ac 100644 --- a/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java +++ b/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java @@ -299,7 +299,7 @@ public final class GiantMoleNPC extends AbstractNPC { super.finalizeDeath(killer); if (killer instanceof Player) { Player player = killer.asPlayer(); - BossKillCounter.addtoKillcount(player, this.getId()); + BossKillCounter.addToBossKillCount(player, this.getId()); } } diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java b/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java index 39678d7f9..1409c3aca 100644 --- a/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java +++ b/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java @@ -30,12 +30,17 @@ public final class MiningGuildPlugin extends OptionHandler { SceneryDefinition.forId(2113).getHandlers().put("option:climb-down", this); SceneryDefinition.forId(30941).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(2112).getHandlers().put("option:open", this); + SceneryDefinition.forId(35783).getHandlers().put("option:climb-down", this); return this; } @Override public boolean handle(Player player, Node node, String option) { if (option.equals("climb-down")) { + if (player.getLocation().withinDistance(Location.create(3021, 3343, 1),2)) { + ClimbActionHandler.climb(player, new Animation(0), Location.create(3017, 3343, 0)); + return true; + } if (player.getLocation().withinDistance(Location.create(3019, 3339, 0), 4)) { if (getDynLevel(player, Skills.MINING) < 60) { player.getDialogueInterpreter().open(382, NPC.create(382, Location.create(0, 0, 0)), 1); diff --git a/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java b/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java index 535885464..70ca79515 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java +++ b/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java @@ -5,6 +5,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents The KnightSword quest. @@ -23,7 +24,7 @@ public class TheKnightsSword extends Quest { * Constructs a new {@code TheKnightsSword} {@code Object}. */ public TheKnightsSword() { - super("The Knight's Sword", 22, 21, 1, 122, 0, 1, 7); + super(Quests.THE_KNIGHTS_SWORD, 22, 21, 1, 122, 0, 1, 7); } @Override diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java index 36684ff28..1fdcd3565 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java @@ -5,6 +5,7 @@ import core.game.interaction.UseWithHandler; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the plugin used to send the cabbage down the hole. @@ -29,7 +30,7 @@ public class BKCabbagePlugin extends UseWithHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest("Black Knights' Fortress"); + final Quest quest = player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS); if (quest.getStage(player) == 20) { if (event.getUsedItem().getId() == 1967) { player.getDialogueInterpreter().sendDialogue("This is the wrong sort of cabbage!"); diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java index df55f800b..b8d4dd509 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player; import core.game.node.item.Item; import core.plugin.Initializable; import core.game.world.update.flag.context.Animation; +import content.data.Quests; /** * Represents the dialogue of listening throug a grill during the black knights' @@ -117,7 +118,7 @@ public final class BKListenDialogue extends DialoguePlugin { stage = 8; break; case 8: - player.getQuestRepository().getQuest("Black Knights' Fortress").setStage(player, 20); + player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS).setStage(player, 20); end(); break; case 10: @@ -142,7 +143,7 @@ public final class BKListenDialogue extends DialoguePlugin { break; case 15: if (player.getInventory().remove(CABBAGE)) { - player.getQuestRepository().getQuest("Black Knights' Fortress").setStage(player, 30); + player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS).setStage(player, 30); interpreter.sendDialogues(player, FacialExpression.HAPPY, "Looks like my work here is done. Seems like that's", "successfully sabotaged their little secret weapon plan."); stage = 16; } diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java index 6e5da0e7d..a3a1bf405 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java @@ -5,6 +5,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the black knights fortress quest. @@ -23,7 +24,7 @@ public final class BlackKnightsFortress extends Quest { * Constructs a new {@Code BlackKnightsFortress} {@Code Object} */ public BlackKnightsFortress() { - super("Black Knights' Fortress", 14, 13, 3, 130, 0, 1, 4); + super(Quests.BLACK_KNIGHTS_FORTRESS, 14, 13, 3, 130, 0, 1, 4); } @Override diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java index 33f2a41c5..93901c19e 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java @@ -1,5 +1,6 @@ package content.region.asgarnia.falador.quest.blackknightsfortress; +import content.region.asgarnia.falador.quest.recruitmentdrive.SirAmikVarzeDialogueFile; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; @@ -8,6 +9,9 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; +import static core.api.ContentAPIKt.openDialogue; +import content.data.Quests; + /** * Represents the sir amik varze dialogue. * @author Vexia @@ -45,7 +49,7 @@ public class SirAmikVarzeDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Black Knights' Fortress"); + quest = player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS); switch (quest.getStage(player)) { case 30: interpreter.sendDialogues(player, FacialExpression.HAPPY, "I have ruined the Black Knights' invincibility potion."); @@ -72,35 +76,7 @@ public class SirAmikVarzeDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (quest.getStage(player)) { case 100: - switch (stage) { - case 0: - interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Hello, friend!"); - stage = 1; - break; - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Do you have any other quests for me to do?"); - stage = 2; - break; - case 2: - interpreter.sendDialogues(npc, FacialExpression.HALF_THINKING, "Quests, eh?", "Well, I don't have anything on the go at the moment,", "but there is an organisation that is always looking for", "capable adventurers to assist them."); - stage = 3; - break; - case 3: - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Your excellent work sorting out those Black Knights", "means I will happily write you a letter of", "recommendation."); - stage = 4; - break; - case 4: - interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Would you like me to put your name forwards to", "them?"); - stage = 5; - break; - case 5: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thanks."); - stage = 6; - break; - case 6: - end(); - break; - } + openDialogue(player, new SirAmikVarzeDialogueFile(), npc); break; case 30: switch (stage) { diff --git a/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt index 9857961b6..3c34fca1f 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt +++ b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt @@ -4,12 +4,11 @@ import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.dialogue.Topic -import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.END_DIALOGUE import org.rs09.consts.Items -import org.rs09.consts.NPCs +import content.data.Quests class DoricDoricsQuestDialogue(private val dStage: Int) : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { @@ -40,7 +39,7 @@ class DoricDoricsQuestDialogue(private val dStage: Int) : DialogueFile() { 40 -> npc(FacialExpression.OLD_NORMAL, "Clay is what I use more than anything, to make casts.", "Could you get me 6 clay, 4 copper ore, and 2 iron ore,", "please? I could pay a little, and let you use my anvils.", "Take this pickaxe with you just in case you need it.").also { stage++ } 41 -> { playerl(FacialExpression.FRIENDLY, "Certainly, I'll be right back!") - startQuest(player, "Doric's Quest") + startQuest(player, Quests.DORICS_QUEST) if(!inInventory(player, Items.BRONZE_PICKAXE_1265)) addItemOrDrop(player, Items.BRONZE_PICKAXE_1265) stage = END_DIALOGUE } @@ -65,7 +64,7 @@ class DoricDoricsQuestDialogue(private val dStage: Int) : DialogueFile() { 3 -> { if(removeItem(player, Item(Items.CLAY_434, 6)) && removeItem(player, Item(Items.COPPER_ORE_436, 4)) && removeItem(player, Item(Items.IRON_ORE_440, 2))) { sendItemDialogue(player, Items.COPPER_ORE_436, "You hand the clay, copper, and iron to Doric.") - finishQuest(player, "Doric's Quest") + finishQuest(player, Quests.DORICS_QUEST) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt index 5c04c3983..0bc49f173 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt +++ b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt @@ -7,26 +7,32 @@ import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Components import org.rs09.consts.Items +import content.data.Quests @Initializable -class DoricsQuest : Quest("Doric's Quest", 17, 16, 1, 31, 0, 1, 100) { +class DoricsQuest : Quest(Quests.DORICS_QUEST, 17, 16, 1, 31, 0, 1, 100) { override fun newInstance(`object`: Any?): Quest { return this } override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) player ?: return - var line = 11 + var line = 12 if(stage == 0) { line(player, "I can start this quest by speaking to !!Doric?? who is !!North of??", line++) line(player, "!!Falador??.", line++) + line++ line(player, "There aren't any requirements but !!Level 15 Mining?? will help.", line++) } else { if(stage in 1..99) { - line(player, "I have spoken to !!Doric??.", line++) - line(player, "I need to collect some items and bring them to !!Doric??:", line++) - line(player, "6 Clay", line++, inInventory(player, Items.CLAY_434, 6)) - line(player, "4 Copper Ore", line++, inInventory(player, Items.COPPER_ORE_436, 4)) - line(player, "2 Iron Ore", line++, inInventory(player, Items.IRON_ORE_440, 2)) + // https://www.youtube.com/watch?v=vm4BEXtMoO0 + line(player, "I have spoken to Doric. He agreed to let me use his anvils", line++, true) + line(player, "if I bring him some materials.", line++, true) + line++ + line(player, "I need to collect the following materials and bring them all", line++) + line(player, "to !!Doric??:", line++) + line(player, "!!6 Clay.??", line++, inInventory(player, Items.CLAY_434, 6)) + line(player, "!!4 Copper Ore.??", line++, inInventory(player, Items.COPPER_ORE_436, 4)) + line(player, "!!2 Iron Ore.??", line++, inInventory(player, Items.IRON_ORE_440, 2)) } if(stage == 100) { diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/AlchemicalNotes.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/AlchemicalNotes.kt new file mode 100644 index 000000000..56eaa77d1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/AlchemicalNotes.kt @@ -0,0 +1,248 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +// https://www.youtube.com/watch?v=o-bAoxIYT-A 7:27 +@Initializable +class AlchemicalNotes : InteractionListener { + companion object { + private val TITLE = "Alchemical Reactions Study" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Acetic acid and Cupric", 55), + BookLine("Sulphate:", 56), + BookLine("Endothermic.", 57), + BookLine("The Cupric is in ", 58), + BookLine("insufficient quantities to", 59), + BookLine("cause any noticeable", 60), + BookLine("reaction.", 61), + ), + Page( + BookLine("Acetic acid and Gypsum:", 66), + BookLine("Endothermic.", 67), + BookLine("Made a particularly bad", 68), + BookLine("smell, but little else that", 69), + BookLine("was productive.", 70), + ) + ), + PageSet( + Page( + BookLine("Acetic acid and Sodium", 55), + BookLine("Chloride:", 56), + BookLine("Endothermic.", 57), + BookLine("Very tasty when", 58), + BookLine("combined with fried", 59), + BookLine("potatoes at room", 60), + BookLine("temperature.", 61), + ), + Page( + BookLine("Acetic acid and", 66), + BookLine("Dihydrogen Monoxide:", 67), + BookLine("Endothermic.", 68), + BookLine("The Dihydrogen", 69), + BookLine("Monoxide served only to", 70), + BookLine("dilute the Acetic acid at", 71), + BookLine("room temperature.", 72), + ) + ), + PageSet( + Page( + BookLine("Acetic acid and Cupric", 55), + BookLine("Ore Powder:", 56), + BookLine("Endothermic.", 57), + BookLine("The powdered form of", 58), + BookLine("Cupric Ore allowed a", 59), + BookLine("lower than usual melting", 60), + BookLine("temperature, but the end", 61), + BookLine("product was non-usable.", 62), + ), + Page( + BookLine("Acetic acid and Tin Ore", 66), + BookLine("powder:", 67), + BookLine("Endothermic.", 68), + BookLine("Similar results to those", 69), + BookLine("made using Cupric Ore.", 70), + ) + ), + PageSet( + Page( + BookLine("Cupric Sulphate and", 55), + BookLine("Dihyrdogen Monoxide:", 56), + BookLine("Exothermic.", 57), + BookLine("A blue compound was", 58), + BookLine("produced, along with heat.", 59), + ), + Page( + BookLine("Cupric Sulphate and", 66), + BookLine("Gypsum:", 67), + BookLine("Endothermic.", 68), + BookLine("At room temperature, no", 69), + BookLine("useful product was", 70), + BookLine("created.", 71), + ) + ), + PageSet( + Page( + BookLine("Cupric Sulphate and", 55), + BookLine("Sodium Chloride:", 56), + BookLine("Endothermic.", 57), + BookLine("A pungent odour was", 58), + BookLine("released when combined.", 59), + ), + Page( + BookLine("Cupric Sulphate and", 66), + BookLine("Cupric Ore powder:", 67), + BookLine("Endothermic.", 68), + BookLine("The Cupric did not react", 69), + BookLine("with each other at room", 70), + BookLine("temperature.", 71), + ) + ), + PageSet( + Page( + BookLine("Cupric Sulphate and Tin", 55), + BookLine("Ore powder:", 56), + BookLine("Endothermic.", 57), + BookLine("Similar results to those", 58), + BookLine("shown with Cupric Ore,", 59), + BookLine("despite the increased", 60), + BookLine("solubility involved with", 61), + BookLine("the powdered form.", 62), + ), + Page( + BookLine("Gypsum and Dihydrogen", 66), + BookLine("Monoxide:", 67), + BookLine("Exothermic.", 68), + BookLine("A white liquid compound", 69), + BookLine("was formed, that quickly", 70), + BookLine("cooled at room", 71), + BookLine("temperature to a white", 72), + BookLine("heat resistant solid very", 73), + BookLine("similar to plaster.", 74), + BookLine("Heat was also produced,", 75), + BookLine("although not in the same", 76), + ) + ), + PageSet( + Page( + BookLine("quantity as Cupric", 55), + BookLine("Sulphate with Dihydrogen", 56), + BookLine("Monoxide", 57), + ), + Page( + BookLine("Gypsum and Sodium", 66), + BookLine("Chloride:", 67), + BookLine("Endothermic.", 68), + BookLine("The two did not seem to", 69), + BookLine("noticably mix together at", 70), + BookLine("room temperature.", 71), + ) + ), + PageSet( + Page( + BookLine("Gypsum and Culpric Ore:", 55), + BookLine("Endothermic.", 56), + BookLine("The gypsum seems quite", 57), + BookLine("resistant to most", 58), + BookLine("compounds at normal", 59), + BookLine("room temperature.", 60), + ), + Page( + BookLine("Gypsum and Tin Ore:", 66), + BookLine("Endothermic.", 67), + BookLine("Again, very similar results", 68), + BookLine("as those shown with", 69), + BookLine("Cupric Ore.", 70), + ) + ), + + PageSet( + Page( + BookLine("Sodium Chloride and", 55), + BookLine("Dihydrogen Monoxide:", 56), + BookLine("Endothermic.", 57), + BookLine("At room temperature, the", 58), + BookLine("Sodium Chloride dissolves", 59), + BookLine("quite easily. Dissolution is", 60), + BookLine("faster at higher", 61), + BookLine("temperatures.", 62), + ), + Page( + BookLine("Sodium Chloride and", 66), + BookLine("Cupric Ore:", 67), + BookLine("Endothermic.", 68), + BookLine("No visible combination at", 69), + BookLine("room temperature.", 70), + ) + ), + PageSet( + Page( + BookLine("Sodium Chloride and Tin", 55), + BookLine("Ore:", 56), + BookLine("Endothermic.", 57), + BookLine("Another very similar ", 58), + BookLine("result as with Cupric Ore.", 59), + ), + Page( + BookLine("Cupric Ore Powder and", 66), + BookLine("Tin Ore Powder:", 67), + BookLine("Endothermic.", 68), + BookLine("When both ores are in", 69), + BookLine("particulate form, a much", 70), + BookLine("lower than usual bonding", 71), + BookLine("temperature can be", 72), + BookLine("obtained.", 73), + BookLine("When combined at a", 74), + BookLine("moderate heat, (my", 75), + BookLine("laboratory heating", 76), + ) + ), + PageSet( + Page( + BookLine("apparatus) I was able to", 55), + BookLine("form liquid Bronze quite", 56), + BookLine("easily, which cooled to", 57), + BookLine("form a standard Bronze", 58), + BookLine("Bar at a temperature far", 60), + BookLine("lower than that required", 61), + BookLine("to produce in mass at a", 62), + BookLine("furnace.", 63), + ), + Page( + BookLine("Nitrous Monoxide:", 66), + BookLine("Was not able to perform", 67), + BookLine("an experimentation using", 68), + BookLine("this substance, as the", 69), + BookLine("gaseous form would", 70), + BookLine("always escape when the", 71), + BookLine("vial was opened.", 72), + ) + ) + ) + } + + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + + override fun defineListeners() { + on(Items.ALCHEMICAL_NOTES_5588, IntType.ITEM, "read") { player, _ -> + setAttribute(player, "bookInterfaceCallback", ::display) + setAttribute(player, "bookInterfaceCurrentPage", 0) + display(player, 0, 0) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/LadyTableDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/LadyTableDialogue.kt new file mode 100644 index 000000000..b1386266f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/LadyTableDialogue.kt @@ -0,0 +1,114 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +class LadyTableDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LadyTableDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return LadyTableDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.LADY_TABLE_2283) + } +} + +class LadyTableDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile(), InteractionListener { + companion object { + const val statueVarbit = 658 + const val attributeStatueStateNumber = "quest:recruitmentdrive-statuestatenumber" + val statueArray = intArrayOf(0, 7308, 7307, 7306, 7305, 7304, 7303, 7312, 7313, 7314, 7311, 7310, 7309) + } + + override fun defineListeners() { + + on(statueArray, IntType.SCENERY, "touch") { player, node -> + if( node.id == statueArray[getAttribute(player, attributeStatueStateNumber, 0)]) { + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, false, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + return@on true + } + } else { + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + openDialogue(player, LadyTableDialogueFile(2), NPC(NPCs.LADY_TABLE_2283)) + return@on true + } + } + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1) { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, false, "Please step through the portal to meet your next", "challenge.") + } + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1) { + openDialogue(player, LadyTableDialogueFile(2), NPC(NPCs.LADY_TABLE_2283)) + } + return@on true + } + + } + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> dialogueNum == 1 } + .endWith { _, player -> + submitWorldPulse(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> { + lock(player, 15) + setAttribute(player, attributeStatueStateNumber, (1..12).random()) + setVarbit(player, statueVarbit, getAttribute(player, attributeStatueStateNumber, 0)) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"Welcome, @name.", "This room will test your observation skills.") + } + 5 -> { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true, "Study the statues closely.", "There is one missing statue in this room.") + } + 10 -> { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true, "We will also mix the order up a little, to make things", "interesting for you!") + } + 15 -> { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"You have 10 seconds to memorise the statues... starting", "NOW!") + } + 20 -> { + closeDialogue(player) + } + 31 -> { // From 15 -> 16 * 600ms = 10 seconds + openOverlay(player,Components.FADE_TO_BLACK_120) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"We will now dim the lights and bring the missing statue", "back in.") + } + 34 -> { // From 15 -> 16 * 600ms = 10 seconds + setVarbit(player, statueVarbit, 0) + openOverlay(player,Components.FADE_FROM_BLACK_170) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"Please touch the statue you think has been added.") + return true + } + } + return false + } + }) + } + + b.onPredicate { player -> dialogueNum == 2 || (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1) } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, attributeStatueStateNumber) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MissCheeversDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MissCheeversDialogue.kt new file mode 100644 index 000000000..21fed50ba --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MissCheeversDialogue.kt @@ -0,0 +1,512 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +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.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +@Initializable +class MissCheeversDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MissCheeversDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return MissCheeversDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MISS_CHEEVERS_2288) + } +} + +class MissCheeversDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> dialogueNum == 0 } + .playerl(FacialExpression.FRIENDLY,"Can you give me any help?") + .npcl(FacialExpression.FRIENDLY,"No, I am sorry, but that is forbidden by our rules.") + .npcl(FacialExpression.FRIENDLY,"If you are having a particularly tough time of it, I suggest you leave and come back later when you are in a more receptive frame of mind.") + .npcl(FacialExpression.FRIENDLY,"Sometimes a break from concentration will yield fresh insight. Our aim is to test you, but not to the point of frustration!") + .playerl(FacialExpression.FRIENDLY,"Okay, thanks!") + .end() + + + b.onPredicate { _ -> dialogueNum == 1 } + .betweenStage { _, player, _, _ -> + setVarbit(player, MissCheeversRoomListeners.doorVarbit, 0) + removeAttribute(player, MissCheeversRoomListeners.attributebook) + removeAttribute(player, MissCheeversRoomListeners.attributemagnet) + removeAttribute(player, MissCheeversRoomListeners.attributeKnife) + removeAttribute(player, MissCheeversRoomListeners.attributeShears) + removeAttribute(player, MissCheeversRoomListeners.attributeTin) + removeAttribute(player, MissCheeversRoomListeners.attributeChisel) + removeAttribute(player, MissCheeversRoomListeners.attributeWire) + + removeAttribute(player, MissCheeversRoomListeners.attribute3VialsOfLiquid) + + MissCheeversRoomListeners.Companion.Vials.vialMap.map { + removeAttribute(player, it.value.attribute) + } + + MissCheeversRoomListeners.Companion.DoorVials.doorVialsRequiredMap.map { + removeAttribute(player, it.value.attribute) + } + } + .npcl(FacialExpression.FRIENDLY,"Greetings, @name. Welcome to my challenge.") + .npcl(FacialExpression.FRIENDLY,"All you need to do is leave from the opposite door to where you came in by.") + .npcl(FacialExpression.FRIENDLY,"I will warn you that this is more complicated than it may at first appear.") + .npcl(FacialExpression.FRIENDLY,"I should also warn you that there are limited supplies of the items in this room, so think carefully before using them, you may find yourself stuck and have to leave to start again!") + .npcl(FacialExpression.FRIENDLY,"Best of luck!") + .end() + } +} + +class MissCheeversRoomListeners : InteractionListener { + companion object { + + const val doorVarbit = 686 + + const val attributebook = "quest:recruitmentdrive-book" + const val attributemagnet = "quest:recruitmentdrive-magnet" + const val attributeKnife = "quest:recruitmentdrive-knife" + const val attributeShears = "quest:recruitmentdrive-shears" + const val attributeTin = "quest:recruitmentdrive-tin" + const val attributeChisel = "quest:recruitmentdrive-chisel" + const val attributeWire = "quest:recruitmentdrive-wire" + + const val attribute3VialsOfLiquid = "quest:recruitmentdrive-3vialsofliquid" + + /** Enums to map canoes to related properties. */ + enum class Vials(val itemId: Int, val attribute: String) { + CUPRIC_SULPHATE_5577(Items.CUPRIC_SULPHATE_5577, "quest:recruitmentdrive-cupricsulphate"), + ACETIC_ACID_5578(Items.ACETIC_ACID_5578, "quest:recruitmentdrive-aceticacid"), + GYPSUM_5579(Items.GYPSUM_5579, "quest:recruitmentdrive-gypsum"), + SODIUM_CHLORIDE_5580(Items.SODIUM_CHLORIDE_5580, "quest:recruitmentdrive-sodiumchloride"), + NITROUS_OXIDE_5581(Items.NITROUS_OXIDE_5581, "quest:recruitmentdrive-nitrousoxide"), + VIAL_OF_LIQUID_5582(Items.VIAL_OF_LIQUID_5582, "quest:recruitmentdrive-vialofliquid"), + TIN_ORE_POWDER_5583(Items.TIN_ORE_POWDER_5583, "quest:recruitmentdrive-tinorepowder"), + CUPRIC_ORE_POWDER_5584(Items.CUPRIC_ORE_POWDER_5584, "quest:recruitmentdrive-cupricorepowder"); + + companion object { + @JvmField + val vialMap = Vials.values().associateBy { it.itemId } + } + } + + + /** Enums to map canoes to related properties. */ + enum class DoorVials(val itemId: Int, val attribute: String) { + CUPRIC_SULPHATE_5577(Items.CUPRIC_SULPHATE_5577, "quest:recruitmentdrive-doorcupricsulphate"), + ACETIC_ACID_5578(Items.ACETIC_ACID_5578, ""), + SODIUM_CHLORIDE_5580(Items.SODIUM_CHLORIDE_5580, ""), + VIAL_OF_LIQUID_5582(Items.VIAL_OF_LIQUID_5582, "quest:recruitmentdrive-doorvialofliquid"); + + companion object { + @JvmField + val doorVialsArray = DoorVials.values().map { it.itemId }.toIntArray() + val doorVialsMap = DoorVials.values().associateBy { it.itemId } + val doorVialsRequiredMap = DoorVials.values().associateBy { it.itemId }.filter { it.value.attribute != "" } + } + } + + + fun searchingHelper(player: Player, attributeCheck: String, item: Int, searchingDescription: String, objectDescription: String) { + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, searchingDescription) + return@queueScript delayScript(player, 2) + } + 1 -> { + if (attributeCheck != "" && !getAttribute(player, attributeCheck, false)) { + setAttribute(player, attributeCheck, true) + addItem(player, item) + sendMessage(player, objectDescription) + } else { + sendMessage(player, "You don't find anything interesting.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + } + + override fun defineListeners() { + + /** Obtainable Items */ + + on(Scenery.OLD_BOOKSHELF_7327, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributemagnet, Items.MAGNET_5604, "You search the bookshelves...", "Hidden amongst the books you find a magnet.") + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7328, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributebook, Items.ALCHEMICAL_NOTES_5588, "You search the bookshelves...", "You find a book that looks like it might be helpful.") + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7329, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributeKnife, Items.KNIFE_5605, "You search the bookshelves...", "Hidden amongst the books you find a knife.") + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7330, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, "", 0, "You search the bookshelves...", "") + return@on true + } + + on(Scenery.SHELVES_7333, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.ACETIC_ACID_5578]!!.attribute, false)) { vialList.add(Items.ACETIC_ACID_5578) } + if (!getAttribute(player, Vials.vialMap[Items.VIAL_OF_LIQUID_5582]!!.attribute, false)) { vialList.add(Items.VIAL_OF_LIQUID_5582) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7334, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.CUPRIC_SULPHATE_5577]!!.attribute, false)) { vialList.add(Items.CUPRIC_SULPHATE_5577) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7335, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.GYPSUM_5579]!!.attribute, false)) { vialList.add(Items.GYPSUM_5579) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7336, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.SODIUM_CHLORIDE_5580]!!.attribute, false)) { vialList.add(Items.SODIUM_CHLORIDE_5580) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7337, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.NITROUS_OXIDE_5581]!!.attribute, false)) { vialList.add(Items.NITROUS_OXIDE_5581) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7338, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.TIN_ORE_POWDER_5583]!!.attribute, false)) { vialList.add(Items.TIN_ORE_POWDER_5583) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7339, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.CUPRIC_ORE_POWDER_5584]!!.attribute, false)) { vialList.add(Items.CUPRIC_ORE_POWDER_5584) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7340, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + val total = getAttribute(player, attribute3VialsOfLiquid, 3) + for (i in 1..total) { vialList.add(Items.VIAL_OF_LIQUID_5582) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray(), attribute3VialsOfLiquid)) + return@on true + } + + on(Scenery.CRATE_7347, IntType.SCENERY, "search") { player, node -> + if (node.location == Location(2476, 4943)) { + searchingHelper(player, attributeTin, Items.TIN_5600, "You search the crate...", "Inside the crate you find a tin.") + } else { + searchingHelper(player, "", 0, "You search the crate...", "") + } + return@on true + } + + on(Scenery.CRATE_7348, IntType.SCENERY, "search") { player, node -> + if (node.location == Location(2476, 4937)) { + searchingHelper(player, attributeChisel, Items.CHISEL_5601, "You search the crate...", "Inside the crate you find a chisel.") + } else { + searchingHelper(player, "", 0, "You search the crate...", "") + } + return@on true + } + + on(Scenery.CRATE_7349, IntType.SCENERY, "search") { player, node -> + if (node.location == Location(2475, 4943)) { + searchingHelper(player, attributeWire, Items.BRONZE_WIRE_5602, "You search the crate...", "Inside the crate you find some wire.") + } else { + searchingHelper(player, "", 0, "You search the crate...", "") + } + return@on true + } + + on(Scenery.CLOSED_CHEST_7350, IntType.SCENERY, "open") { player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.OPEN_CHEST_7351, 100) + return@on true + } + + on(Scenery.OPEN_CHEST_7351, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributeShears, Items.SHEARS_5603, "You search the chest...", "Inside the chest you find some shears.") + return@on true + } + + on(Scenery.OPEN_CHEST_7351, IntType.SCENERY, "close") { player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CLOSED_CHEST_7350, -1) + return@on true + } + + /** Combining Items the correct way */ + + onUseWith(ITEM, Items.TIN_5600, Items.GYPSUM_5579) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You empty the vial into the tin.") + addItemOrDrop(player, Items.TIN_5592) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5592, Items.VIAL_OF_LIQUID_5582) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You empty the vial into the tin.") + sendMessage(player, "You notice the tin gets quite warm as you do this.") + sendMessage(player, "A lumpy white mixture is made, that seems to be hardening.") + addItemOrDrop(player, Items.TIN_5593) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.TIN_5593, Scenery.KEY_7346) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You make an impression of the key as the white mixture hardens.") + addItemOrDrop(player, Items.TIN_5594) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5594, Items.TIN_ORE_POWDER_5583) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5595) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5595, Items.CUPRIC_ORE_POWDER_5584) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5597) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5594, Items.CUPRIC_ORE_POWDER_5584) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5596) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5596, Items.TIN_ORE_POWDER_5583) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5597) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.TIN_5597, Scenery.BUNSEN_BURNER_7332) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You heat the two powdered ores together in the tin.") + sendMessage(player, "You make a duplicate of the key in bronze.") + addItemOrDrop(player, Items.TIN_5598) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5598, Items.BRONZE_WIRE_5602, Items.CHISEL_5601, Items.KNIFE_5605) { player, used, with -> + if(removeItem(player, used.id)) { + sendMessage(player, "You prise the duplicate key out of the tin.") + addItemOrDrop(player, Items.TIN_5594) + addItemOrDrop(player, Items.BRONZE_KEY_5585) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.METAL_SPADE_5586, Scenery.BUNSEN_BURNER_7332) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You burn the wooden handle away from the spade...") + sendMessage(player, "...and are left with a metal spade with no handle.") + addItemOrDrop(player, Items.ASHES_592) + addItemOrDrop(player, Items.METAL_SPADE_5587) + } + return@onUseWith true + } + + + on(Scenery.STONE_DOOR_7343, SCENERY, "study") { player, node -> + sendDialogueLines(player, "There is a stone slab here obstructing the door.", "There is a small hole in the slab that looks like it might be for a handle.") + sendMessage(player, "It's nearly a perfect fit!") + return@on true + } + + onUseWith(SCENERY, Items.METAL_SPADE_5587, Scenery.STONE_DOOR_7343) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You slide the spade into the hole in the stone...") + sendMessage(player, "It's nearly a perfect fit!") + setVarbit(player, doorVarbit, 1) + } + return@onUseWith true + } + + onUseWith(SCENERY, DoorVials.doorVialsArray, Scenery.STONE_DOOR_7344) { player, used, _ -> + if(removeItem(player, used.id)) { + setAttribute(player, DoorVials.doorVialsMap[used.id]!!.attribute, true) + sendMessage(player, "You pour the vial onto the flat part of the spade.") + } + if (DoorVials.doorVialsRequiredMap.all { getAttribute(player, it.value.attribute, false) }) { + sendMessage(player, "Something caused a reaction when mixed!") + sendMessage(player, "The spade gets hotter, and expands slightly.") + setVarbit(player, doorVarbit, 2) + } + return@onUseWith true + } + + on(Scenery.STONE_DOOR_7344, SCENERY, "pull-spade") { player, node -> + if (DoorVials.doorVialsRequiredMap.all { getAttribute(player, it.value.attribute, false) }) { + sendMessage(player, "You pull on the spade...") + sendMessage(player, "It works as a handle, and you swing the stone door open.") + setVarbit(player, doorVarbit, 3) + } else { + sendMessage(player, "You pull on the spade...") + sendMessage(player, "It comes loose, and slides out of the hole in the stone.") + addItemOrDrop(player, Items.METAL_SPADE_5587) + setVarbit(player, doorVarbit, 0) + } + return@on true + } + + on(Scenery.OPEN_DOOR_7345, SCENERY, "walk-through") { player, node -> + if(player.location.x <= 2477) { + player.walkingQueue.addPath(2477, 4940) + player.walkingQueue.addPath(2478, 4940) + } else { + player.walkingQueue.addPath(2477, 4940) + } + return@on true + } + + + } + +} + +private class VialShelfDialogueFile(private val flaskIdsArray: IntArray, private val specialAttribute: String? = null) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true }.branch { _ -> flaskIdsArray.size }.let { branch -> + + branch.onValue(3) + // This is the only shelf with 3 vials of water. + .line("There are three vials on this shelf.") + .options("Take the vials?").let { optionBuilder -> + optionBuilder.option("Take one vial.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 3) - 1) + print(getAttribute(player, specialAttribute, 3)) + } + } + optionBuilder.option("Take two vials.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + addItemOrDrop(player, flaskIdsArray[1]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 3) - 2) + } + } + optionBuilder.option("Take all three vials.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + addItemOrDrop(player, flaskIdsArray[1]) + addItemOrDrop(player, flaskIdsArray[2]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 3) - 3) + } + } + optionBuilder.option("Don't take a vial.") + .end() + } + branch.onValue(2) + .line("There are two vials on this shelf.") + .options("Take the vials?").let { optionBuilder -> + optionBuilder.option("Take the first vial.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 2) - 1) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[0]]!!.attribute, true) + } + } + optionBuilder.option("Take the second vial.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[1]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 2) - 1) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[1]]!!.attribute, true) + } + } + optionBuilder.option("Take both vials.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + addItemOrDrop(player, flaskIdsArray[1]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 2) - 2) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[0]]!!.attribute, true) + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[1]]!!.attribute, true) + } + } + } + + branch.onValue(1) + .line("There is a vial on this shelf.") + .options("Take the vial?").let { optionBuilder -> + optionBuilder.option("YES") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 1) - 1) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[0]]!!.attribute, true) + } + } + optionBuilder.option("NO") + .end() + } + + branch.onValue(0) + .line("There is nothing of interest on these shelves.") + } + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MsHynnTerprettDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MsHynnTerprettDialogue.kt new file mode 100644 index 000000000..91be2f7a7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MsHynnTerprettDialogue.kt @@ -0,0 +1,154 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class MsHynnTerprettDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MsHynnTerprettDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return MsHynnTerprettDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MS_HYNN_TERPRETT_2289) + } +} + +class MsHynnTerprettDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + companion object { + const val attributeRandomRiddle = "quest:recruitmentdrive-randomriddle" + const val attributeRecentlyCorrect = "quest:recruitmentdrive-recentlycorrect" + } + + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> true }.branch { player -> + if (getAttribute(player, attributeRecentlyCorrect, false)) { + return@branch 3 + } else if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1) { + return@branch 2 + } else if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1) { + return@branch 1 + } else { + return@branch 0 + } + }.let { branch -> + /** Failed Branch */ + val failedStage = b.placeholder() + failedStage.builder() + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, attributeRandomRiddle) + removeAttribute(player, attributeRecentlyCorrect) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + /** Passed Branch */ + val passedStage = b.placeholder() + passedStage.builder() + .betweenStage { _, player, _, _ -> + removeAttribute(player, attributeRandomRiddle) + removeAttribute(player, attributeRecentlyCorrect) + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + } + .npc("Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + branch.onValue(3) // Passed stage + .goto(passedStage) + branch.onValue(2) // Failed stage + .goto(failedStage) + branch.onValue(1) // Already passed stage + .npc("You certainly have the wits to be a Temple Knight.", "Pass on through the portal to find your next challenge.") + .end() + branch.onValue(0) + .betweenStage { _, player, _, _ -> + if (getAttribute(player, attributeRandomRiddle, -1) !in 0..4) { + setAttribute(player, attributeRandomRiddle, (0..4).random()) + } + } + .npc("Greetings, @name.", "I am here to test your wits with a simple riddle.") + .branch { player -> getAttribute(player, attributeRandomRiddle, 0) } + .let { branch -> + branch.onValue(0) + .npc(FacialExpression.THINKING, "Here is my riddle:", "I estimate there to be one million inhabitants in the world", "of @servername, creatures and people both.") + .npc(FacialExpression.THINKING, "What number would you get if you multiply", "the number of fingers on everything's left hand, to the", "nearest million?") + .manualStage { _, player, _, _ -> + sendInputDialogue(player, false, "Enter the amount:") { value: Any -> + if(value == "0") { + setAttribute(player, attributeRecentlyCorrect, true) + } else { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + openDialogue(player, MsHynnTerprettDialogueFile(), NPC(NPCs.MS_HYNN_TERPRETT_2289)) + return@sendInputDialogue + } + } + .end() + + branch.onValue(1) + .npc(FacialExpression.THINKING, "Here is my riddle:", "Which of the following statements is true?") + .options().let { optionBuilder -> + optionBuilder.option("The number of false statements here is one.").goto(failedStage) + optionBuilder.option("The number of false statements here is two.").goto(failedStage) + optionBuilder.option("The number of false statements here is three.").goto(passedStage) + optionBuilder.option("The number of false statements here is four.").goto(failedStage) + } + + branch.onValue(2) + .npc(FacialExpression.THINKING, "Here is my riddle:", "I have both a husband and daughter.") + .npc(FacialExpression.THINKING, "My husband is four times older than my daughter. ", "In twenty years time, he will be twice as old as my", "daughter.") + .npc(FacialExpression.THINKING, "How old is my daughter now?") + .manualStage { _, player, _, _ -> + sendInputDialogue(player, true, "Enter the amount:") { value: Any -> + if(value == 10) { + setAttribute(player, attributeRecentlyCorrect, true) + } else { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + openDialogue(player, MsHynnTerprettDialogueFile(), NPC(NPCs.MS_HYNN_TERPRETT_2289)) + return@sendInputDialogue + } + } + .end() + + branch.onValue(3) + .npc(FacialExpression.THINKING, "Here is my riddle:", "Imagine that you have been captured by an enemy.", "You are to be killed, but in a moment of mercy, the", "enemy has allowed you to pick your own demise.") + .npc(FacialExpression.THINKING, "Your first choice is to be drowned in a lake of acid.") + .npc(FacialExpression.THINKING, "Your second choice is to be burned on a fire.") + .npc(FacialExpression.THINKING, "Your third choice is to be thrown to a pack of wolves", "that have not been fed in over a month.") + .npc(FacialExpression.THINKING, "Your final choice of fate is to be thrown from the walls", "of a castle, many hundreds of feet high.") + .npc(FacialExpression.THINKING, "Which fate would you be wise to choose?") + .options().let { optionBuilder -> + optionBuilder.option("The lake of acid.").goto(failedStage) + optionBuilder.option("The large fire.").goto(failedStage) + optionBuilder.option("The wolves.").goto(passedStage) + optionBuilder.option("The castle walls.").goto(failedStage) + } + + branch.onValue(4) + .npc(FacialExpression.THINKING, "Here is my riddle:", "I dropped four identical stones, into four identical", "buckets, each containing an identical amount of water.") + .npc(FacialExpression.THINKING, "The first bucket's water was at 32 degrees Fahrenheit,", "the second was at 33 degrees, the third at 34 and the", "fourth was at 35 degrees.") + .npc(FacialExpression.THINKING, "Which bucket's stone dropped to the bottom of the bucket", "last?") + .options().let { optionBuilder -> + optionBuilder.option("Bucket A (32 degrees)").goto(passedStage) + optionBuilder.option("Bucket B (33 degrees)").goto(failedStage) + optionBuilder.option("Bucket C (34 degrees)").goto(failedStage) + optionBuilder.option("Bucket D (35 degrees)").goto(failedStage) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDrive.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDrive.kt new file mode 100644 index 000000000..709256772 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDrive.kt @@ -0,0 +1,135 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Recruitment Drive Quest + * + * https://www.youtube.com/watch?v=0yvFREeXNn0 - Quest start log only. + * https://www.youtube.com/watch?v=lNlSiUvPL1o - Very good + * https://www.youtube.com/watch?v=OGWpX1WqpKM 10:12 - Final congrats page. + * https://www.youtube.com/watch?v=nu4OAswRcGg - Speaking to Tiffy after the quest (IMPORTANT!) + * https://www.youtube.com/watch?v=srFMJa4nuX0 1:47 blur ass quest log again + * https://www.youtube.com/watch?v=L7NdDTWa-1Q HAZEEL's CULT + * 1 - Speak to Sir Amik Varze. + * 2 - Sent to secret training ground. + * 3 - Finish all stages. + * 100 - Finish by talking to Tiffy. + */ +@Initializable +class RecruitmentDrive : Quest(Quests.RECRUITMENT_DRIVE, 103, 102, 1, 496, 0, 1, 2) { + companion object { + const val attributeOriginalGender = "/save:quest:recruitmentdrive-originalgender" + + // Stage state: (0: reset), (1: passed), (-1: failed) + const val attributeStagePassFailState = "/save:quest:recruitmentdrive-stagestate" + const val attributeCurrentStage = "/save:quest:recruitmentdrive-currentstage" + const val attributeStage1 = "/save:quest:recruitmentdrive-stage1" + const val attributeStage2 = "/save:quest:recruitmentdrive-stage2" + const val attributeStage3 = "/save:quest:recruitmentdrive-stage3" + const val attributeStage4 = "/save:quest:recruitmentdrive-stage4" + const val attributeStage5 = "/save:quest:recruitmentdrive-stage5" + val attributeStageArray = arrayOf(attributeStage1, attributeStage2, attributeStage3, attributeStage4, attributeStage5) + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.RECRUITMENT_DRIVE) > 0 + + if(!started){ + line(player, "I can start this quest by speaking to !!Sir Amik Varze??,", line++) + line(player, "upstairs in !!Falador Castle,??", line++) + if (isQuestComplete(player, Quests.DRUIDIC_RITUAL)) { + line(player, "with the Druidic Ritual Quest completed,", line++, true) + } else { + line(player, "with the !!Druidic Ritual Quest?? completed,", line++) + } + if (isQuestComplete(player, Quests.BLACK_KNIGHTS_FORTRESS)) { + line(player, "and since I have completed the Black Knights' Fortress", line++, true) + line(player, "Quest.", line++, true) + } else { + line(player, "and after I have completed the !!Black Knights' Fortress??", line++) + line(player, "Quest.", line++) + } + } else { + line(player, "Sir Amik Varze told me that he had put my name forward as", line++, true) + line(player, "a potential member of some mysterious organisation.", line++, true) + + if (stage >= 2) { + } else if (stage >= 1) { + line(player, "I should head to !!Falador Park?? to meet my !!Contact?? so that I", line++, false) + line(player, "can begin my !!testing for the job??", line++, false) + } + + if (stage >= 3) { + line(player, "I went to Falador Park, and met a strange old man named", line++, true) + line(player, "Tiffy.", line++, true) + line(player, "He sent me to a secret training ground, where my wits", line++, true) + line(player, "were thoroughly tested.", line++, true) + line(player, "Luckily, I was too smart to fall for any of their little tricks,", line++, true) + line(player, "and passed the test with flying colours.", line++, true) + } else if (stage >= 2) { + // http://youtu.be/Otc7ATq3tik 4:17 - I guess this is why no one opens their quest log + line(player, "A man named !!Tiffy?? brought me !!here, to the secret training??", line++, false) + line(player, "!!grounds?? so that I could be tested for the job.", line++, false) + line++ + line(player, "I should !!work out?? what I am supposed to do to complete", line++, false) + line(player, "these rooms...", line++, false) + } + + if (stage >= 4) { + line(player, "I am now an official member of the Temple Knights,", line++, true) + line(player, "although I have to wait for the paperwork to go through", line++, true) + line(player, "before I can commence working for them.", line++, true) + } else if (stage >= 3) { + line(player, "I should talk to !!Tiffy?? to become a Temple Knight.", line++, false) + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun reset(player: Player) { + removeAttribute(player, attributeOriginalGender) + removeAttribute(player, attributeStagePassFailState) + removeAttribute(player, attributeCurrentStage) + removeAttribute(player, attributeStage1) + removeAttribute(player, attributeStage2) + removeAttribute(player, attributeStage3) + removeAttribute(player, attributeStage4) + removeAttribute(player, attributeStage5) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have passed the Recruitment Drive!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.INITIATE_SALLET_5574, 230, 277, 5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "1000 Prayer, Herblore and", ln++) + drawReward(player, "Agility XP", ln++) + drawReward(player, "Gaze of Saradomin", ln++) + drawReward(player, "Temple Knight's Initiate Helm", ln) + + rewardXP(player, Skills.PRAYER, 1000.0) + rewardXP(player, Skills.HERBLORE, 1000.0) + rewardXP(player, Skills.AGILITY, 1000.0) + addItem(player, Items.INITIATE_SALLET_5574) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDriveListeners.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDriveListeners.kt new file mode 100644 index 000000000..39afdf1f4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDriveListeners.kt @@ -0,0 +1,316 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import content.data.Quests +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +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.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 core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState +import org.rs09.consts.* + +class RecruitmentDriveListeners : InteractionListener { + companion object { + + enum class Stages(val npc: Int, val startLocation: Location, val startWalkLocation: Location, val quitPortal: Int, val successDoor: Int) { + SIR_SPISHYUS(NPCs.SIR_SPISHYUS_2282, Location(2490, 4972), Location(2489, 4972), Scenery.PORTAL_7272, Scenery.DOOR_7274), + LADY_TABLE(NPCs.LADY_TABLE_2283, Location(2460, 4979), Location(2459, 4979), Scenery.PORTAL_7288, Scenery.DOOR_7302), + SIR_KUAM_FERENTSE(NPCs.SIR_KUAM_FERENTSE_2284, Location(2455, 4964), Location(2456, 4964), Scenery.PORTAL_7315, Scenery.DOOR_7317), + SIR_TINLEY(NPCs.SIR_TINLEY_2286, Location(2471, 4956), Location(2472, 4956), Scenery.PORTAL_7318, Scenery.DOOR_7320), + SIR_REN_ITCHOOD(NPCs.SIR_REN_ITCHOOD_2287, Location(2439, 4956), Location(2440, 4956), Scenery.PORTAL_7321, Scenery.DOOR_7323), + MISS_CHEEVERS(NPCs.MISS_CHEEVERS_2288, Location(2467, 4940), Location(2468, 4940), Scenery.PORTAL_7324, Scenery.DOOR_7326), + MS_HYNN_TERPRETT(NPCs.MS_HYNN_TERPRETT_2289, Location(2451, 4935), Location(2451, 4936), Scenery.PORTAL_7352, Scenery.DOOR_7354); + + companion object { + @JvmField + val indexMap = Stages.values().associateBy { it.ordinal } + val indexArray = Stages.indexMap.keys.map { it } + val quitPortalArray = Stages.indexMap.values.map { it.quitPortal }.toIntArray() + val successDoorArray = Stages.indexMap.values.map { it.successDoor }.toIntArray() + } + } + + fun shuffleStages(player: Player) { + // Obtain an array to shuffle. Must be at least [5] long. + val stagesArrayToShuffle = intArrayOf(0,1,2,3,4,5,6) // Stages.indexArray.toIntArray() + stagesArrayToShuffle.shuffle() + setAttribute(player, RecruitmentDrive.attributeStage1, stagesArrayToShuffle[0]) + setAttribute(player, RecruitmentDrive.attributeStage2, stagesArrayToShuffle[1]) + setAttribute(player, RecruitmentDrive.attributeStage3, stagesArrayToShuffle[2]) + setAttribute(player, RecruitmentDrive.attributeStage4, stagesArrayToShuffle[3]) + setAttribute(player, RecruitmentDrive.attributeStage5, stagesArrayToShuffle[4]) + setAttribute(player, RecruitmentDrive.attributeCurrentStage, 0) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + } + + fun callStartingDialogues (player: Player, npc: Int) { + when (npc) { + NPCs.SIR_SPISHYUS_2282 -> openDialogue(player, SirSpishyusDialogueFile(1), NPC(npc)) + NPCs.LADY_TABLE_2283 -> openDialogue(player, LadyTableDialogueFile(1), NPC(npc)) + NPCs.SIR_KUAM_FERENTSE_2284 -> openDialogue(player, SirKuamFerentseDialogueFile(1), NPC(npc)) + NPCs.SIR_TINLEY_2286 -> openDialogue(player, SirTinleyDialogueFile(1), NPC(npc)) + NPCs.SIR_REN_ITCHOOD_2287 -> openDialogue(player, SirRenItchwoodDialogueFile(1), NPC(npc)) + NPCs.MISS_CHEEVERS_2288 -> openDialogue(player, MissCheeversDialogueFile(1), NPC(npc)) + NPCs.MS_HYNN_TERPRETT_2289 -> openDialogue(player, MsHynnTerprettDialogueFile(1), NPC(npc)) + } + } + } + + override fun defineListeners() { + + on(Stages.quitPortalArray, IntType.SCENERY, "use") { player, node -> + FailTestCutscene(player).start() + return@on true + } + + on(Stages.successDoorArray, IntType.SCENERY, "open") { player, node -> + // This is specially for Miss Cheevers + if (inInventory(player, Items.BRONZE_KEY_5585)) { + sendMessage(player, "You use the duplicate key you made to unlock the door.") + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + // Success Door + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1) { + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + setAttribute(player, RecruitmentDrive.attributeCurrentStage, getAttribute(player, RecruitmentDrive.attributeCurrentStage, 0) + 1) + DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery) + val currentLevel = getAttribute(player, RecruitmentDrive.attributeCurrentStage, 0) + if (currentLevel >= 5) { + CompleteTestCutscene(player).start() + return@on true + } + val currentStage = getAttribute(player, RecruitmentDrive.attributeStageArray[currentLevel], 0) + val currentStageEnum = Stages.indexMap[currentStage]!! + closeDialogue(player) + + // This is specifically for Sir Spishyus to reset the fox, chicken, grain + SirSpishyusRoomListeners.resetStage(player) + + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + player.inventory.clear() + player.equipment.clear() + openOverlay(player, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player, 6) + } + 1 -> { + teleport(player, currentStageEnum.startLocation) + return@queueScript delayScript(player, 2) + } + 2 -> { + openOverlay(player, Components.FADE_FROM_BLACK_170) + return@queueScript delayScript(player, 2) + } + 3 -> { + forceWalk(player, currentStageEnum.startWalkLocation, "dumb") + return@queueScript delayScript(player, 2) + } + 4 -> { + callStartingDialogues(player, currentStageEnum.npc) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else { + if(node.id == Scenery.DOOR_7323) { + // This is specifically for SirRenItchwood + openInterface(player, Components.RD_COMBOLOCK_285) + } else { + sendMessage(player, "You have not completed this room's puzzle yet.") + } + } + return@on true + } + } + + /** Starting Recruitment Drive test cutscene */ + class StartTestCutscene(player: Player) : Cutscene(player) { + override fun setup() { + loadRegion(9805) + val currentStage = getAttribute(player, RecruitmentDrive.attributeStageArray[0], 0) + setExit(Stages.indexMap[currentStage]!!.startLocation) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + timedUpdate(6) + } + 1 -> { + dialogueLinesUpdate(NPCs.SIR_TIFFY_CASHIEN_2290, FacialExpression.HAPPY, "Here we go!", "Mind your head!") + timedUpdate(3) + } + 2 -> { + dialogueLinesUpdate(NPCs.SIR_TIFFY_CASHIEN_2290, FacialExpression.HAPPY, "Oops. Ignore the smell!", "Nearly there!") + timedUpdate(3) + } + 3 -> { + dialogueLinesUpdate(NPCs.SIR_TIFFY_CASHIEN_2290, FacialExpression.HAPPY, "And...", "Here we are!", "Best of luck!") + timedUpdate(3) + } + 4 -> { + player.inventory.clear() + player.equipment.clear() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + dialogueClose() + endWithoutFade { + val currentStage = getAttribute(player, RecruitmentDrive.attributeStageArray[0], 0) + val firstStage = Stages.indexMap[currentStage]!! + + // This is specifically for Sir Spishyus to reset the fox, chicken, grain + SirSpishyusRoomListeners.resetStage(player) + + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + fadeFromBlack() + return@queueScript delayScript(player, 2) + } + 1 -> { + forceWalk(player, firstStage.startWalkLocation, "dumb") + return@queueScript delayScript(player, 2) + } + 2 -> { + callStartingDialogues(player, firstStage.npc) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + + } + } + } + } + } + + /** Failed Recruitment Drive test cutscene */ + class FailTestCutscene(player: Player) : Cutscene(player) { + override fun setup() { + loadRegion(9805) + setExit(Location(2997, 3374)) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + closeDialogue(player) + fadeToBlack() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + timedUpdate(6) + } + 1 -> { + var clearBoss = getAttribute(player, SirKuamFerentseDialogueFile.attributeGeneratedSirLeye, NPC(0)) + if (clearBoss.id != 0) { + clearBoss.clear() + } + player.inventory.clear() + player.equipment.clear() + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + fadeFromBlack() + return@queueScript delayScript(player, 2) + } + 1 -> { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + openDialogue(player, SirTiffyCashienFailedDialogueFile(), NPC(NPCs.SIR_TIFFY_CASHIEN_2290)) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + endWithoutFade { + face(player, Location(2997, 3373)) + fadeFromBlack() + } + } + } + } + } + + /** Complete Recruitment Drive test cutscene */ + class CompleteTestCutscene(player: Player) : Cutscene(player) { + override fun setup() { + loadRegion(9805) + setExit(Location(2996, 3375)) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + if (getQuestStage(player, Quests.RECRUITMENT_DRIVE) == 2) { + setQuestStage(player, Quests.RECRUITMENT_DRIVE, 3) + } + closeDialogue(player) + fadeToBlack() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + timedUpdate(6) + } + 1 -> { + player.inventory.clear() + player.equipment.clear() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + fadeFromBlack() + return@queueScript delayScript(player, 2) + } + 1 -> { + openDialogue(player, SirTiffyCashienDialogueFile(), NPC(NPCs.SIR_TIFFY_CASHIEN_2290)) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + endWithoutFade { + face(player, Location(2997, 3373)) + fadeFromBlack() + } + } + } + } + } + + class LogoutRecruitmentDrive : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(9805)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + // This is specifically for Sir Spishyus to reset the fox, chicken, grain + SirSpishyusRoomListeners.resetStage(entity) + // Clear inventory whenever you leave the recruitment drive area + entity.inventory.clear() + entity.equipment.clear() + // Restore player normal tabs on leave + entity.interfaceManager.openDefaultTabs() + // Teleport you out if you log out. You should do this in one sitting. + if (logout) { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(entity, 0)) + teleport(entity, Location(2996, 3375)) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirAmikVarzeDialogueFile.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirAmikVarzeDialogueFile.kt new file mode 100644 index 000000000..a9aacdc6b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirAmikVarzeDialogueFile.kt @@ -0,0 +1,75 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.* +import content.data.Quests + +class SirAmikVarzeDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 0) + .npcl(FacialExpression.FRIENDLY,"Hello, friend!") + .playerl(FacialExpression.THINKING, "Do you have any other quests for me to do?") + .branch { player -> if(isQuestComplete(player, Quests.BLACK_KNIGHTS_FORTRESS) && isQuestComplete(player, Quests.DRUIDIC_RITUAL)) { 1 } else { 0 } } + .let{ branch -> + // Failure branch + branch.onValue(0) + .npcl(FacialExpression.THINKING, "A quest? Alas I do not have any quests I can offer you at this time.") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .npc("Quests, eh?", "Well, I don't have anything on the go at the moment,", "but there is an organisation that is always looking for", "capable adventurers to assist them.") + .npc(FacialExpression.FRIENDLY,"Your excellent work sorting out those Black Knights", "means I will happily write you a letter of", "recommendation.") + .npc("Would you like me to put your name forwards to", "them?") + .options().let { optionBuilder -> + optionBuilder.option ("Yes please") + .playerl("Sure thing Sir Amik, sign me up!") + .npc(FacialExpression.SUSPICIOUS,"Erm, well, this is a little embarrassing, I already HAVE", "put you forward as a potential member.") + .npc("They are the Temple Knights, and you are to", "meet Sir Tiffy Cashien in Falador park for testing", "immediately.") + .playerl("Okey dokey, I'll go do that then.") + .endWith { _, player -> + if(getQuestStage(player, Quests.RECRUITMENT_DRIVE) == 0) { + setAttribute(player, RecruitmentDrive.attributeOriginalGender, player.isMale) + setQuestStage(player, Quests.RECRUITMENT_DRIVE, 1) + } + } + optionBuilder.option_playerl("No thanks") + .end() + optionBuilder.option("Tell me about this organization...") + .npc(FacialExpression.SUSPICIOUS,"I cannot tell you much...", "They are called the Temple Knights, and are an", "organisation that was founded by Saradomin personally", "many centuries ago.") + .npc("There are many rumours and fables about their works and", "actions, but official records of their presence are non-", "existent.") + .npc("It is a secret organisation of extraordinary power and", "resourcefulness...") + .npc("Let me put it this way:", "Should you decide to take them up on their generous", "offer to join, you will find yourself in an advantageous", "position that many in this world would envy, and that few") + .npc("are called to occupy.") + .playerl("Well, that wasn't quite as helpful as I thought it would be...but thanks anyway, I guess.") + .end() + } + + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 1, 2, 3, 4) + .npcl(FacialExpression.FRIENDLY,"Hello, friend!") + .playerl(FacialExpression.THINKING, "Can I just skip the test to become a Temple Knight?") + .npcl("No, I'm afraid not. I suggest you go meet Sir Tiffy in Falador Park, he will be expecting you.") + .end() + + // This should be after the Wanted Quest, but is the placeholder until that quest is implemented. + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 100) + .npcl(FacialExpression.FRIENDLY,"Hello, friend!") + .npcl(FacialExpression.FRIENDLY,"Well @name, now that you are a White Knight, I expect you should be out there hunting Black Knights for us!") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Can you explain the White Knight honour system again?") + .npcl("Sadly we are not as rich as we once were, and there are many White Knights who foolishly lose their combat equipment.") + .npcl("We do not think it fair to make a profit from our brethren, so we will sell you equipment at cost, and rebuy it at the same cost, but we will only sell equipment to those we consider responsible enough to") + .npcl("wield it correctly.") + .npcl("By killing Black Knights, you will increase your reputation with us, by killing White Knights we will obviously think less of you.") + .npcl("You can check your White Knight reputation level by looking at your quest journal for the Wanted! Quest, or Sir Vyvin will let you know what level you are at when you go to purchase equipment.") + .npcl("Sir Vyvin can be found in Falador Castle, and he will sell you any equipment appropriate to your reputation level.") + .npcl("Have fun, and go kill some Black Knights for me!") + .playerl("Okay Amik, thanks for explaining!") + .end() + + optionBuilder.option("Okay, bye!") + .playerl("Okay, 'bye then Amik!") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirKuamFerentseDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirKuamFerentseDialogue.kt new file mode 100644 index 000000000..055845ca2 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirKuamFerentseDialogue.kt @@ -0,0 +1,58 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class SirKuamFerentseDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirKuamFerentseDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirKuamFerentseDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_KUAM_FERENTSE_2284) + } +} + +class SirKuamFerentseDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + companion object { + const val attributeGeneratedSirLeye = "quest:recruitmentdrive-generatedsirleye" + } + + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1 } + .npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + // You can't fail unless you quit the room. + b.onPredicate { _ -> true } + .npc("Ah, @name, you're finally here.", "Your task for this room is to defeat Sir Leye.", "He has been blessed by Saradomin to be undefeatable", "by any man, so it should be quite the challenge for you.") + .npc("If you are having problems, remember", "A true warrior uses his wits as much as his brawn.", "Fight smarter, not harder.") + .endWith { _, player -> + var boss = getAttribute(player, attributeGeneratedSirLeye, NPC(0)) + if (boss.id != 0) { + boss.clear() + } + boss = NPC(NPCs.SIR_LEYE_2285, player.location) + setAttribute(player, attributeGeneratedSirLeye, boss) + boss.isRespawn = false + boss.isAggressive = false + boss.isWalks = true + boss.location = Location(2460, 4963) + boss.init() + registerHintIcon(player, boss) + sendChat(boss, "No man may defeat me!") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirLeyeBehavior.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirLeyeBehavior.kt new file mode 100644 index 000000000..3f91752f7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirLeyeBehavior.kt @@ -0,0 +1,49 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.NPCs + +class SirLeyeBehavior : NPCBehavior(NPCs.SIR_LEYE_2285) { + var clearTime = 0 + + override fun tick(self: NPC): Boolean { + // You have 400 ticks to kill Sir Leye + if (clearTime++ > 400) { + clearTime = 0 + poofClear(self) + } + return true + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + val lifepoints = self.skills.lifepoints + if (attacker is Player) { + // If you are male, Sir Leye will recover to full health. + if (attacker.isMale) { + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) > lifepoints - 1) { + self.skills.lifepoints = self.getSkills().getStaticLevel(Skills.HITPOINTS) + } + } + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + clearHintIcon(killer) + setAttribute(killer, RecruitmentDrive.attributeStagePassFailState, 1) + removeAttribute(killer, SirKuamFerentseDialogueFile.attributeGeneratedSirLeye) + } + } + + // No xp from attacking this dude. + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return 0.0 + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirRenItchwoodDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirRenItchwoodDialogue.kt new file mode 100644 index 000000000..d5ddd45a0 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirRenItchwoodDialogue.kt @@ -0,0 +1,199 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.InterfaceListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +@Initializable +class SirRenItchwoodDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirRenItchwoodDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirRenItchwoodDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_REN_ITCHOOD_2287) + } +} + +class SirRenItchwoodDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + companion object { + const val attributeClueNumber = "quest:recruitmentdrive-cluenumber" + } + + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> dialogueNum in 0..1 && getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) != -1 } + .betweenStage { _, player, _, _ -> + if (getAttribute(player, attributeClueNumber, -1) !in 0..5) { + setAttribute(player, attributeClueNumber, (0..5).random()) + } + } + .npc("Greetings friend, and welcome here,", "you'll find my puzzle not so clear.", "Hidden amongst my words, it's true,", "the password for the door as a clue.") + .options().let { optionBuilder -> + optionBuilder.option_playerl ("Can I have the clue for the door?") + .branch { player -> getAttribute(player, attributeClueNumber, 0) } + .let{ branch -> + // Note: all the "I" in here are written in small case "i" (sic) + branch.onValue(0) + .npc("Better than me, you'll not find", "In rhyming and in puzzles.", "This clue so clear will tax your mind", "Entirely as it confuzzles!") + .end() + branch.onValue(1) + .npc("Feel the aching of your mind", "In puzzlement, confused.", "See the clue hidden behind", "His words, as you perused.") + .end() + branch.onValue(2) + .npc("Look closely at the words i speak;", "And study closely every part.", "See for yourself the word you seek", "Trapped for you if you're smart.") + .end() + branch.onValue(3) + .npc("More than words, i have not for you", "Except the things i say today.", "Aware are you, this is a clue?", "Take note of what i say!") + .end() + branch.onValue(4) + .npc("Rare it is that you will see", "A puzzle such as this!", "In many ways it tickles me", "Now, watching you hit and miss!") + .end() + branch.onValue(5) + .npc("This riddle of mine may confuse,", "I am quite sure of that.", "Mayhap you should closely peruse", "Every word i have spat?") + .end() + } + return@let optionBuilder.option("Can I have a different clue?") + .player("I don't get that riddle...", "Can I have a different one?") + .branch { player -> getAttribute(player, attributeClueNumber, 0) } + .let{ branch -> + branch.onValue(0) + .npc("Before you hurry through that door", "Inspect the words i spoke.", "There is a simple hidden flaw", "Ere you think my rhyme a joke.") + .end() + branch.onValue(1) + .npc("First my clue you did not see,", "I really wish you had.", "Such puzzling wordplay devilry", "Has left you kind of mad!") + .end() + branch.onValue(2) + .npc("Last time my puzzle did not help", "Apparently, so you've bidden.", "Study my speech carefully, whelp", "To find the answer, hidden.") + .end() + branch.onValue(3) + .npc("Many types have passed through here", "Even such as you amongst their sort.", "And in the end, the puzzles clear;", "The hidden word you saught.") + .end() + branch.onValue(4) + .npc("Repetition, once again", "Against good sense it goes.", "In my words, the answers plain", "Now that you see rhyme flows.") + .end() + branch.onValue(5) + .npc("Twice it is now, i have stated", "In a rhyme, what is the pass.", "Maybe my words obfuscated", "Entirely beyond your class.") + .end() + } + /* + // I'm too goddamned lazy to implement the final clue dialogue + return@let optionBuilder.option("Can I have the final clue?") + .branch { player -> getAttribute(player, attributeClueNumber, 0) } + .let{ branch -> + branch.onValue(0) + .npc("Betrayed by words the answer is", "In that what i say is the key", "There is no more help after this", "Especially no more from me.") + .end() + branch.onValue(1) + .npc("For the last time i will state", "In simple words, the clue.", "Such tricky words make you irate", "Having no idea what to do...") + .end() + branch.onValue(2) + .npc("Lo! my final speech is now", "Attended to by you.", "Study my words, and find out how", "To understand my clue!") + .end() + branch.onValue(3) + .npc("Many types have passed through here", "Even such as you amongst their sort.", "And in the end, the puzzles clear;", "The hidden word you saught.") + .end() + branch.onValue(4) + .npc("Repetition, once again", "Against good sense it goes.", "In my words, the answers plain", "Now that you see rhyme flows.") + .end() + branch.onValue(5) + .npc("Twice it is now, i have stated", "In a rhyme, what is the pass.", "Maybe my words obfuscated", "Entirely beyond your class.") + .end() + } + */ + + } + b.onPredicate { player -> dialogueNum == 2 || getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1 } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "It's sad to say,", "this test beat you.", "I'll send you to Tiffy,", "what to do?") + .endWith { _, player -> + removeAttribute(player, attributeClueNumber) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + + } +} + +class DoorLockPuzzleInterfaceListener : InterfaceListener { + + companion object { + const val temp = Components.RD_COMBOLOCK_285 + const val attributeLock1 = "quest:recruitmentdrive-lock1" + const val attributeLock2 = "quest:recruitmentdrive-lock2" + const val attributeLock3 = "quest:recruitmentdrive-lock3" + const val attributeLock4 = "quest:recruitmentdrive-lock4" + val lockArray = arrayOf(attributeLock1, attributeLock2, attributeLock3, attributeLock4) + val answers = arrayOf("BITE", "FISH", "LAST", "MEAT", "RAIN", "TIME") + } + + override fun defineInterfaceListeners() { + + onOpen(Components.RD_COMBOLOCK_285) { player, _ -> + setAttribute(player, attributeLock1, 65) + setAttribute(player, attributeLock2, 65) + setAttribute(player, attributeLock3, 65) + setAttribute(player, attributeLock4, 65) + return@onOpen true + } + + onClose(Components.RD_COMBOLOCK_285) { player, _ -> + removeAttribute(player, attributeLock1) + removeAttribute(player, attributeLock2) + removeAttribute(player, attributeLock3) + removeAttribute(player, attributeLock4) + return@onClose true + } + + on(Components.RD_COMBOLOCK_285) { player, component, opcode, buttonID, slot, itemID -> + // Child IDs for respective locks: + // 6 7 8 9 + // 10 < Lock1 > 11 12 < Lock2 > 13 14 < Lock3 > 15 16 < Lock4 > 17 + if (buttonID in 10..17) { + val position = (buttonID - 10) / 2 + val backForth = (buttonID - 10) % 2 + var newValue = getAttribute(player, lockArray[position], 65) + (if (backForth == 0) { -1 } else { 1 }) + if (newValue < 65) { newValue = 90 } // If char number is under A(65), loop back to Z(90) + if (newValue > 90) { newValue = 65 } // If char number is over Z(90), loop back to A(65) + setAttribute(player, lockArray[position], newValue) + setInterfaceText(player, newValue.toChar().toString(), Components.RD_COMBOLOCK_285, position + 6) + } + // Enter Button + if (buttonID == 18) { + val lock1 = getAttribute(player, attributeLock1, 65).toChar() + val lock2 = getAttribute(player, attributeLock2, 65).toChar() + val lock3 = getAttribute(player, attributeLock3, 65).toChar() + val lock4 = getAttribute(player, attributeLock4, 65).toChar() + val answer = arrayOf(lock1, lock2, lock3, lock4).joinToString("") + closeInterface(player) + if (answers[getAttribute(player, SirRenItchwoodDialogueFile.attributeClueNumber, 0)] == answer){ + removeAttribute(player, SirRenItchwoodDialogueFile.attributeClueNumber) + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) != -1) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + sendNPCDialogue(player, NPCs.SIR_REN_ITCHOOD_2287, "Your wit is sharp, your brains quite clear; You solved my puzzle with no fear. At puzzles I rank you quite the best, now enter the portal for your next test.") + } else { + removeAttribute(player, SirRenItchwoodDialogueFile.attributeClueNumber) + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + openDialogue(player, SirRenItchwoodDialogueFile(2), NPC(NPCs.SIR_REN_ITCHOOD_2287)) + } + } + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirSpishyusDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirSpishyusDialogue.kt new file mode 100644 index 000000000..8f6df7708 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirSpishyusDialogue.kt @@ -0,0 +1,221 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +@Initializable +class SirSpishyusDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirSpishyusDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirSpishyusDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_SPISHYUS_2282) + } +} + +class SirSpishyusDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1 } + .npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + b.onPredicate { player -> dialogueNum == 2 || getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1 } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, SirTinleyDialogueFile.attributeDoNotMove) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + b.onPredicate { _ -> true } + .npcl(FacialExpression.FRIENDLY, "Ah, welcome @name.") + .playerl(FacialExpression.FRIENDLY, "Hello there." + " What am I supposed to be doing in this room?") + .npcl(FacialExpression.FRIENDLY, "Well, your task is to take this fox, this chicken and this bag of grain across that bridge there to the other side of the room.") + .npcl(FacialExpression.FRIENDLY, "When you have done that, your task is complete.") + .playerl(FacialExpression.FRIENDLY, "Is that it?") + .npcl(FacialExpression.FRIENDLY, "Well, it is not quite as simple as that may sound.") + .npcl(FacialExpression.FRIENDLY, "Firstly, you may only carry one of the objects across the room at a time, for the bridge is old and fragile.") + .npcl(FacialExpression.FRIENDLY, "Secondly, the fox wants to eat the chicken, and the chicken wants to eat the grain. Should you ever leave the fox unattended with the chicken, or the grain unattended with the chicken, then") + .npcl(FacialExpression.FRIENDLY, "one of them will be eaten, and you will be unable to complete the test.") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll see what I can do.") + .end() + } +} +class SirSpishyusRoomListeners : InteractionListener { + companion object { + const val foxFromVarbit = 680 + const val foxToVarbit = 681 + const val chickenFromVarbit = 682 + const val chickenToVarbit = 683 + const val grainFromVarbit = 684 + const val grainToVarbit = 685 + + val fromZoneBorder = ZoneBorders(2479, 4967, 2490, 4977) + val toZoneBorder = ZoneBorders(2471, 4967, 2478, 4977) + + fun countEquipmentItems(player: Player): Int { + var count = 0 + if(inEquipment(player, Items.GRAIN_5607)) { count++ } + if(inEquipment(player, Items.FOX_5608)) { count++ } + if(inEquipment(player, Items.CHICKEN_5609)) { count++ } + return count + } + + fun checkFinished(player: Player) { + if (getVarbit(player, foxToVarbit) == 1 && getVarbit(player, chickenToVarbit) == 1 && getVarbit(player, grainToVarbit) == 1) { + sendMessage(player, "Congratulations! You have solved this room's puzzle!") + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + } + + fun checkFail(player: Player): Boolean { + return ((getVarbit(player, foxFromVarbit) == 0 && getVarbit(player, chickenFromVarbit) == 0 && getVarbit(player, grainFromVarbit) == 1) || + (getVarbit(player, foxFromVarbit) == 1 && getVarbit(player, chickenFromVarbit) == 0 && getVarbit(player, grainFromVarbit) == 0) || + (getVarbit(player, foxToVarbit) == 1 && getVarbit(player, chickenToVarbit) == 1 && getVarbit(player, grainToVarbit) == 0) || + (getVarbit(player, foxToVarbit) == 0 && getVarbit(player, chickenToVarbit) == 1 && getVarbit(player, grainToVarbit) == 1)) + } + + fun resetStage(player: Player) { + setVarbit(player, foxFromVarbit, 0) + setVarbit(player, chickenFromVarbit, 0) + setVarbit(player, grainFromVarbit, 0) + setVarbit(player, foxToVarbit, 0) + setVarbit(player, chickenToVarbit, 0) + setVarbit(player, grainToVarbit, 0) + removeItem(player, Items.GRAIN_5607, Container.EQUIPMENT) + removeItem(player, Items.FOX_5608, Container.EQUIPMENT) + removeItem(player, Items.CHICKEN_5609, Container.EQUIPMENT) + } + } + + override fun defineListeners() { + on(Scenery.PRECARIOUS_BRIDGE_7286, SCENERY, "cross") { player, node -> + if (countEquipmentItems(player) > 1) { + sendDialogue(player, "I really don't think I should be carrying more than 5Kg across that rickety bridge...") + } else if (checkFail(player)) { + openDialogue(player, SirTinleyDialogueFile(2), NPC(NPCs.SIR_SPISHYUS_2282)) // Fail + } else { + lock(player, 5) + sendMessage(player, "You carefully walk across the rickety bridge...") + player.walkingQueue.reset() + player.walkingQueue.addPath(2476, 4972) + } + return@on true + } + + on(Scenery.PRECARIOUS_BRIDGE_7287, SCENERY, "cross") { player, node -> + if (countEquipmentItems(player) > 1) { + sendDialogue(player, "I really don't think I should be carrying more than 5Kg across that rickety bridge...") + } else if (checkFail(player)) { + openDialogue(player, SirTinleyDialogueFile(2), NPC(NPCs.SIR_SPISHYUS_2282)) // Fail + } else { + lock(player, 5) + sendMessage(player, "You carefully walk across the rickety bridge...") + player.walkingQueue.reset() + player.walkingQueue.addPath(2484, 4972) + } + return@on true + } + + on(Scenery.GRAIN_7284, SCENERY, "pick-up") { player, _ -> + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + if (fromZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.CAPE.ordinal, Item(Items.GRAIN_5607), null, Container.EQUIPMENT) + setVarbit(player, grainFromVarbit, 1) + } + if (toZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.CAPE.ordinal, Item(Items.GRAIN_5607), null, Container.EQUIPMENT) + setVarbit(player, grainToVarbit, 0) + } + } + return@on true + } + onUnequip(Items.GRAIN_5607) { player, _ -> + if (fromZoneBorder.insideBorder(player)) { + removeItem(player, Items.GRAIN_5607, Container.EQUIPMENT) + setVarbit(player, grainFromVarbit, 0) + } + if (toZoneBorder.insideBorder(player)) { + removeItem(player, Items.GRAIN_5607, Container.EQUIPMENT) + setVarbit(player, grainToVarbit, 1) + checkFinished(player) + } + return@onUnequip true + } + + + on(Scenery.FOX_7277, SCENERY, "pick-up") { player, _ -> + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + if (fromZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.WEAPON.ordinal, Item(Items.FOX_5608), null, Container.EQUIPMENT) + setVarbit(player, foxFromVarbit, 1) + } + if (toZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.WEAPON.ordinal, Item(Items.FOX_5608), null, Container.EQUIPMENT) + setVarbit(player, foxToVarbit, 0) + } + } + return@on true + } + onUnequip(Items.FOX_5608) { player, _ -> + if (fromZoneBorder.insideBorder(player)) { + removeItem(player, Items.FOX_5608, Container.EQUIPMENT) + setVarbit(player, foxFromVarbit, 0) + } + if (toZoneBorder.insideBorder(player)) { + removeItem(player, Items.FOX_5608, Container.EQUIPMENT) + setVarbit(player, foxToVarbit, 1) + checkFinished(player) + } + return@onUnequip true + } + + + on(Scenery.CHICKEN_7281, SCENERY, "pick-up") { player, _ -> + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + if (fromZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.SHIELD.ordinal, Item(Items.CHICKEN_5609), null, Container.EQUIPMENT) + setVarbit(player, chickenFromVarbit, 1) + } + if (toZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.SHIELD.ordinal, Item(Items.CHICKEN_5609), null, Container.EQUIPMENT) + setVarbit(player, chickenToVarbit, 0) + } + } + return@on true + } + onUnequip(Items.CHICKEN_5609) { player, _ -> + if (fromZoneBorder.insideBorder(player)) { + removeItem(player, Items.CHICKEN_5609, Container.EQUIPMENT) + setVarbit(player, chickenFromVarbit, 0) + } + if (toZoneBorder.insideBorder(player)) { + removeItem(player, Items.CHICKEN_5609, Container.EQUIPMENT) + setVarbit(player, chickenToVarbit, 1) + checkFinished(player) + } + return@onUnequip true + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTiffyCashienDialogueFile.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTiffyCashienDialogueFile.kt new file mode 100644 index 000000000..9bd2ecf93 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTiffyCashienDialogueFile.kt @@ -0,0 +1,140 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class SirTiffyCashienDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 1) + .player(FacialExpression.FRIENDLY, "Sir Amik Varze sent me to meet you here for some", "sort of testing...") + .npc(FacialExpression.FRIENDLY, "Ah, @name!", "Amik told me all about you, dontchaknow!", "Spliffing job you you did with the old Black Knights there,", "absolutely first class.") + .playerl(FacialExpression.GUILTY, "...Thanks I think.") + // .npcl(FacialExpression.FRIENDLY, "Well, not in those exact words, but you get my point, what?") + .npc(FacialExpression.FRIENDLY, "Well, a top-notch filly like yourself is just the right sort", "we've been looking for for our organisation.") + .npcl(FacialExpression.FRIENDLY, "So, are you ready to begin testing?") + .let { path -> + val originalPath = b.placeholder() + path.goto(originalPath) + return@let originalPath.builder().options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("Testing..?") + .playerl(FacialExpression.FRIENDLY, "Testing? What exactly do you mean by testing?") + .npcl(FacialExpression.FRIENDLY, "Jolly bad show! Varze was supposed to have informed you about all this before sending you here!") + .npcl(FacialExpression.FRIENDLY, "Well, not your fault I suppose, what? Anywho, our organisation is looking for a certain specific type of person to join.") + .playerl(FacialExpression.FRIENDLY, "So... You want me to go kill some monster or something for you?") + .npcl(FacialExpression.FRIENDLY, "Not at all, old bean. There's plenty of warriors around should we require dumb muscle.") + .npcl(FacialExpression.FRIENDLY, "That's really not the kind of thing our organisation is after, what?") + .playerl(FacialExpression.FRIENDLY, "So you want me to go and fetch you some kind of common item, and then take it for delivery somewhere on the other side of the country?") + .playerl(FacialExpression.FRIENDLY, "Because I really hate doing that!") + .npcl(FacialExpression.FRIENDLY, "Haw, haw, haw! What a dull thing to ask of someone, what?") + .npcl(FacialExpression.FRIENDLY, "I know what you mean, though. I did my fair share of running errands when I was a young adventurer, myself!") + .playerl(FacialExpression.FRIENDLY, "So what exactly will this test consist of?") + .npcl(FacialExpression.FRIENDLY, "Can't let just any old riff-raff in, what? The mindless thugs and bully boys are best left in the White Knights or the city guard. We look for the top-shelf brains to join us.") + .playerl(FacialExpression.FRIENDLY, "So you want to test my brains? Will it hurt?") + .npcl(FacialExpression.FRIENDLY, "Haw, haw, haw! That's a good one!") + .npcl(FacialExpression.FRIENDLY, "Not in the slightest.. Well, maybe a bit, but we all have to make sacrifices occasionally, what?") + .playerl(FacialExpression.FRIENDLY, "What do you want me to do then?") + .npcl(FacialExpression.FRIENDLY, "It's a test of wits, what? I'll take you to our secret training grounds, and you will have to pass through a series of five separate intelligence test to prove you're our sort of adventurer.") + .npcl(FacialExpression.FRIENDLY, "Standard puzzle room rules will apply.") + .playerl(FacialExpression.THINKING, "Erm... What are standard puzzle room rules exactly?") + .npcl(FacialExpression.HAPPY, "Never done this sort of thing before, what?") + .npc("The simple rules are:", "No items or equipment to be brought with you.", "Each room is a self-contained puzzle.", "You may quit at any time.") + .npcl(FacialExpression.HAPPY, "Of course, if you quit a room, then all your progress up to that point will be cleared, and you'll have to start again from scratch.") + .npc(FacialExpression.HAPPY, "Our organisation manages to filter all the top-notch", "adventurers this way.", "So, are you ready to go?") + .goto(originalPath) + optionBuilder.option("Organisation?") + .playerl(FacialExpression.THINKING, "This organisation you keep mentioning.. Perhaps you could tell me a little about it?") + .npcl(FacialExpression.FRIENDLY, "Oh, that Amik! Jolly bad form. Did he not tell you anything that he was supposed to?") + .playerl(FacialExpression.FRIENDLY, "No. He didn't really tell me anything except to come here and meet you.") + .npcl(FacialExpression.FRIENDLY, "Well, now, old sport, let me give you the heads up and the low down, what?") + .npcl(FacialExpression.FRIENDLY, "I represent the Temple Knights. We are the premier order of Knights in Asgarnia, if not the world. Saradomin himself personally founded our order centuries ago, and we answer only to him.") + .npcl(FacialExpression.FRIENDLY, "Only the very best of the best are permitted to join, and the powers we command are formidable indeed.") + .npcl(FacialExpression.FRIENDLY, "You might say that we are the front line of defence for the entire kingdom!") + .playerl(FacialExpression.THINKING, "So what's the difference between you and the White Knights?") + .npcl(FacialExpression.FRIENDLY, "Well, in simple terms, we're better! Any fool with a sword can manage to get into the White Knights, which is mostly the reason they are so very, very incompetent, what?") + .npcl(FacialExpression.FRIENDLY, "The Temple Knights, on the other hand, have to be smarter, stronger and better than all others. We are the elite. No man controls us, for our orders come directly from Saradomin himself!") + .npcl(FacialExpression.FRIENDLY, "According to Sir Vey Lance, our head of operations, that is. He claims that everything he tells us to do is done with Saradomin's implicit permission.") + .npcl(FacialExpression.FRIENDLY, "It's not every job where you have more authority than the king, though, is it?") + .playerl(FacialExpression.THINKING, "Wait... You can order the King around?") + .npcl(FacialExpression.FRIENDLY, "Well, not me personally. I'm only in the recruitment side of things, dontchaknow, but the higher ranking members of the organisation have almost absolute power over the kingdom.") + .npcl(FacialExpression.FRIENDLY, "Plus a few others, so I hear...") + .npcl(FacialExpression.FRIENDLY, "Anyway, this is why we keep our organisation shrouded in secrecy, and why we demand such rigorous testing for all potential recruits. Speaking of which, are you ready to begin your testing?") + .goto(originalPath) + optionBuilder.option("Yes, let's go!") + .player(FacialExpression.FRIENDLY, "Yeah. this sounds right up my street.", "Let's go!") + .branch { player -> if(player.inventory.isEmpty && player.equipment.isEmpty && !player.familiarManager.hasFamiliar()) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + .npcl(FacialExpression.NEUTRAL, "Well, bad luck, old @g[guy,gal]. You'll need to have a completely empty inventory and you can't be wearing any equipment before we can accurately test you.") + .npcl(FacialExpression.HAPPY, "Don't want people cheating by smuggling stuff in, what? That includes things carried by familiars, too! Come and see me again after you've been to the old bank to drop your stuff off, what?") + .end() + return@let branch + } + .onValue(1) + .npc(FacialExpression.HAPPY, "Jolly good show!", "Now the training grounds location is a secret, so...") + .goto(continuePath) + optionBuilder.option("No, I've changed my mind.") + .player("No, I've changed my mind.") + .end() + + return@let continuePath.builder() + } + + }.endWith { _, player -> + if (getQuestStage(player, Quests.RECRUITMENT_DRIVE) == 1) { + setQuestStage(player, Quests.RECRUITMENT_DRIVE, 2) + } + RecruitmentDriveListeners.shuffleStages(player) + RecruitmentDriveListeners.StartTestCutscene(player).start() + } + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 2) + .npc(FacialExpression.FRIENDLY, "Ah, what ho!", "Back for another go at the old testing, what?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("Yes, let's go!") + .player(FacialExpression.FRIENDLY, "Yeah. this sounds right up my street.", "Let's go!") + .branch { player -> if(player.inventory.isEmpty && player.equipment.isEmpty && !player.familiarManager.hasFamiliar()) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + .npcl(FacialExpression.NEUTRAL, "Well, bad luck, old @g[guy,gal]. You'll need to have a completely empty inventory and you can't be wearing any equipment before we can accurately test you.") + .npcl(FacialExpression.HAPPY, "Don't want people cheating by smuggling stuff in, what? That includes things carried by familiars, too! Come and see me again after you've been to the old bank to drop your stuff off, what?") + .end() + return@let branch + } + .onValue(1) + .npc(FacialExpression.FRIENDLY, "Jolly good show!", "Now the training grounds location is a secret, so...") + .endWith { _, player -> + RecruitmentDriveListeners.shuffleStages(player) + RecruitmentDriveListeners.StartTestCutscene(player).start() + } + optionBuilder.option("No, I've changed my mind.") + .player("No, I've changed my mind.") + .end() + return@let continuePath.builder() + } + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 3) + .npc(FacialExpression.HAPPY, "Oh, jolly well done!", "Your performance will need to be evaluated by Sir Vey", "personally, but I don't think it's going too far ahead of", "myself to welcome you to the team!") + .endWith { _, player -> + // Get a voucher and $3000 to change gender if you did do it during the quest. + if (getAttribute(player, RecruitmentDrive.attributeOriginalGender, true) != player.isMale) { + addItemOrDrop(player, Items.MAKEOVER_VOUCHER_5606) + addItemOrDrop(player, Items.COINS_995, 3000) + } + removeAttribute(player, RecruitmentDrive.attributeOriginalGender) + finishQuest(player, Quests.RECRUITMENT_DRIVE) + } + } +} + +class SirTiffyCashienFailedDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npc(FacialExpression.SAD, "Oh, jolly bad luck, what?", "Not quite the brainbox you thought you were, eh?") + .npc(FacialExpression.HAPPY, "Well, never mind!", "You have an open invitation to join our organization, so", "when you're feeling a little smarter, come back and talk", "to me again.") + + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTinleyDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTinleyDialogue.kt new file mode 100644 index 000000000..d00cae73a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTinleyDialogue.kt @@ -0,0 +1,100 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +@Initializable +class SirTinleyDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirTinleyDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirTinleyDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_TINLEY_2286) + } +} + +class SirTinleyDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile(), MapArea { + companion object { + const val attributeDoNotMove = "quest:recruitmentdrive-donotmove" + } + + override fun create(b: DialogueBuilder) { + b.onPredicate {player -> dialogueNum == 0 && !getAttribute(player, attributeDoNotMove, false) && getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0 } + .npc("Ah, welcome @name.", "I have but one clue for you to pass this room's puzzle:", "'Patience'.") + .endWith { _, player -> + setAttribute(player, attributeDoNotMove, true) + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + return@queueScript delayScript(player, 15) + } + 1 -> { + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) != -1) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + setAttribute(player, attributeDoNotMove, false) + npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + b.onPredicate {player -> dialogueNum == 0 && !getAttribute(player, attributeDoNotMove, false) && getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1 } + .npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + // If you talk to him before time is up, you fail. + b.onPredicate { player -> dialogueNum == 0 && getAttribute(player, attributeDoNotMove, false) || dialogueNum == 2 || getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1 } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, attributeDoNotMove) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + + b.onPredicate { _ -> dialogueNum == 1 } + .npc("Ah, @name, you have arrived.", "Speak to me to begin your task.") + .endWith { _, player -> + setAttribute(player, attributeDoNotMove, false) + } + } + + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2474, 4959, 2478, 4957)) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + if(getAttribute(entity, attributeDoNotMove, false)) { + setAttribute(entity, attributeDoNotMove, false) + setAttribute(entity, RecruitmentDrive.attributeStagePassFailState, -1) + openDialogue(entity, SirTinleyDialogueFile(2), NPC(NPCs.SIR_TINLEY_2286)) + } + } + } +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java index 487467ae2..3743a5c2c 100644 --- a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java @@ -1,5 +1,6 @@ package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; +import content.data.Quests; import core.game.component.Component; import core.game.node.entity.player.link.emote.Emotes; import core.game.activity.ActivityManager; @@ -54,7 +55,7 @@ public final class GDiplomacyCutscene extends CutscenePlugin { @Override public boolean start(final Player player, final boolean login, Object... args) { - Quest quest = player.getQuestRepository().getQuest(GoblinDiplomacy.NAME); + Quest quest = player.getQuestRepository().getQuest(Quests.GOBLIN_DIPLOMACY); final NPC grubfoot = NPC.create(quest.getStage(player) == 10 ? 4495 : quest.getStage(player) == 20 ? 4497 : quest.getStage(player) == 30 ? 4498 : 4496, getBase().transform(10, 55, 0)); grubfoot.setWalks(false); npcs.add(grubfoot); @@ -182,8 +183,8 @@ public final class GDiplomacyCutscene extends CutscenePlugin { type = GrubFoot.forConfig(player); dialIndex = RandomFunction.random(DIALOGUES.length); other = Repository.findNPC(npc.getId() == 4494 ? 4493 : 4494); - quest = player.getQuestRepository().getQuest(GoblinDiplomacy.NAME); - if(player.getQuestRepository().getQuest("Lost Tribe").getStage(player) == 43){ + quest = player.getQuestRepository().getQuest(Quests.GOBLIN_DIPLOMACY); + if(player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 43){ player("Have you heard of the Dorgeshuun?"); stage = 5000; return true; @@ -367,8 +368,8 @@ public final class GDiplomacyCutscene extends CutscenePlugin { player.setAttribute("/save:tlt-goblin-emotes",true); player.getEmoteManager().unlock(Emotes.GOBLIN_BOW); player.getEmoteManager().unlock(Emotes.GOBLIN_SALUTE); - setVarbit(player, 532, 7, true); - player.getQuestRepository().getQuest("Lost Tribe").setStage(player,44); + setVarbit(player, 532, 7, true); + player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).setStage(player,44); stage++; break; case 5055: diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java index a3e744b86..ad3d9c910 100644 --- a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the demon slayer quest. @@ -15,12 +16,6 @@ import core.plugin.ClassScanner; */ @Initializable public class GoblinDiplomacy extends Quest { - - /** - * The name of the quest. - */ - public static final String NAME = "Goblin Diplomacy"; - /** * Represents the orange goblin mail. */ @@ -45,7 +40,7 @@ public class GoblinDiplomacy extends Quest { * Constructs a new {@Code GoblinDiplomacy} {@Code Object} */ public GoblinDiplomacy() { - super("Goblin Diplomacy", 20, 19, 5); + super(Quests.GOBLIN_DIPLOMACY, 20, 19, 5); } @Override @@ -87,7 +82,7 @@ public class GoblinDiplomacy extends Quest { line(player, BLUE + "I have some " + RED + "Blue Goblin Armour. " + BLUE + "I should show it to the", 12+ 7); line(player, BLUE + "generals.", 13+ 7); } else { - line(player, BLUE + "I should bring the goblins s+ 7+ 7);e " + RED + "Blue Goblin Armour", 12+ 7); + line(player, BLUE + "I should bring the goblins some " + RED + "Blue Goblin Armour", 12+ 7); line(player, BLUE + "Maybe the generals will know where to get some.", 13+ 7); } break; diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java index 0eaed3038..ca562e9c6 100644 --- a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java @@ -1,5 +1,6 @@ package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -42,7 +43,7 @@ public final class GrubfootDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(GoblinDiplomacy.NAME); + quest = player.getQuestRepository().getQuest(Quests.GOBLIN_DIPLOMACY); switch (quest.getStage(player)) { case 100: npc("Me lonely."); diff --git a/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt b/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt index 9ca8b163a..32059ef91 100644 --- a/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt +++ b/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt @@ -2,28 +2,25 @@ package content.region.asgarnia.handlers import content.global.skill.crafting.TanningProduct import core.api.* +import core.game.interaction.IntType import core.game.node.entity.skill.Skills import core.game.world.map.Location import org.rs09.consts.Items +import org.rs09.consts.NPCs import org.rs09.consts.Scenery import content.region.asgarnia.dialogue.TheDoorDialogues import core.game.interaction.InteractionListener -import core.game.interaction.IntType -import org.rs09.consts.NPCs /** - * @author bushtail + * @author bushtail, Player Name */ class CraftingGuildListeners : InteractionListener { - private val GUILD_DOOR = Scenery.GUILD_DOOR_2647 - private val REQUIRED_ITEMS = intArrayOf(Items.BROWN_APRON_1757, Items.CRAFTING_CAPE_9780, Items.CRAFTING_CAPET_9781) - override fun defineListeners() { - on(GUILD_DOOR, IntType.SCENERY, "open") { player, door -> + on(Scenery.GUILD_DOOR_2647, IntType.SCENERY, "open") { player, door -> if (player.location == Location.create(2933, 3289, 0)) { if (hasLevelStat(player, Skills.CRAFTING, 40)) { - if (anyInEquipment(player, *REQUIRED_ITEMS)) { + if (anyInEquipment(player, Items.BROWN_APRON_1757, Items.CRAFTING_CAPE_9780, Items.CRAFTING_CAPET_9781)) { openDialogue(player, TheDoorDialogues(0)) core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door.asScenery()) return@on true @@ -46,4 +43,4 @@ class CraftingGuildListeners : InteractionListener { return@on true } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/asgarnia/mudskipperpoint/MudSkipperPointListeners.kt b/Server/src/main/content/region/asgarnia/mudskipperpoint/MudSkipperPointListeners.kt new file mode 100644 index 000000000..6d31ea26b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/mudskipperpoint/MudSkipperPointListeners.kt @@ -0,0 +1,151 @@ +package content.region.asgarnia.mudskipperpoint + +import content.global.skill.slayer.MogreNPC +import content.region.asgarnia.mudskipperpoint.dialogue.SkippyBootDialogue +import content.region.asgarnia.mudskipperpoint.dialogue.SkippyBucketDialogue +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.impl.Projectile +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.RandomFunction +import core.tools.colorize +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Vars + +@Initializable +class MudSkipperPointListeners : InteractionListener { + + companion object { + private val MESSAGES = arrayOf( + "Da boom-boom kill all da fishies!", + "I smack you good!", + "Smash stupid human!", + "Tasty human!", + "Human hit me on the head!", + "I get you!", + "Human scare all da fishies!" + ) + + private val FISHING_SPOTS = intArrayOf( + Scenery.OMINOUS_FISHING_SPOT_10087, + Scenery.OMINOUS_FISHING_SPOT_10088, + Scenery.OMINOUS_FISHING_SPOT_10089 + ) + } + + private fun handleExplosives(player: Player, explosives: Item, target: Location): Boolean{ + // Check if the player has unlocked the ability to summon Mogres + if (getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE) != SkippyBucketDialogue.DONE_QUEST){ + sendDialogueLines(player, "Sinister as that fishing spot is, why would I want to", "explode it?") + return false + } + val distance = player.location.getDistance(target) + if (distance < 5){ + //too close + sendPlayerDialogue(player, "If this thing explodes, I think I should stand a liiiiitle further away.") + return false + } + if (distance > 14){ + // too far + sendPlayerDialogue(player, "I can't throw that far.") + return false + } + removeItem(player, explosives.id) + animate(player, Animation(385)) // Throw the vial + sendMessage(player, "You hurl the shuddering vial into the water...") + val projectile = Projectile.create(player, null, 49, 30, 20, 30, Projectile.getSpeed(player, target.location)) + projectile.endLocation = target.location + projectile.send() + + val delay = (2+ distance * 0.5).toInt() + queueScript(player, delay){ + val mogre = MogreNPC() + val xOffset = (player.location.x - target.location.x) % 2 + val yOffset = (player.location.y - target.location.y) % 2 + mogre.location = Location.create(target.location.x + xOffset, target.location.y + yOffset) + mogre.init() + mogre.moveStep() + mogre.isRespawn = false + mogre.attack(player) + registerHintIcon(player, mogre) + mogre.sendChat(MESSAGES[RandomFunction.random(MESSAGES.size)]) + if (explosives.id == Items.SUPER_FISHING_EXPLOSIVE_12633){ + impact(mogre, 15) + } + mogre.graphics(Graphics(68)) + sendMessage(player, "...and a Mogre appears!") + return@queueScript stopExecuting(player) + } + return true + } + + private fun soberSkippy(player: Player): Boolean { + if (getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE) > SkippyBucketDialogue.DRUNK){ + sendDialogue(player, "I think he's sober enough. And I don't want to use another bucket of water.") + return false + } + else{ + if (hasAnItem(player, Items.BUCKET_OF_WATER_1929).exists()) { + openDialogue(player, SkippyBucketDialogue()) + return true + } + else{ + sendDialogue(player, "You know, I could shock him out of it if I could find some cold water...") + return false + } + } + } + + override fun defineListeners() { + + onUseWith(IntType.SCENERY, Items.FISHING_EXPLOSIVE_6664, *FISHING_SPOTS) { player, used, with -> + handleExplosives(player, used.asItem(), with.location) + } + + onUseWith(IntType.SCENERY, Items.SUPER_FISHING_EXPLOSIVE_12633, *FISHING_SPOTS) { player, used, with -> + handleExplosives(player, used.asItem(), with.location) + } + + on(FISHING_SPOTS, IntType.SCENERY, "Lure", "Bait") { player, _ -> + sendMessage(player, "Something seems to have scared all the fishes away...") + return@on true + } + + on(Scenery.SIGNPOST_10090, IntType.SCENERY, "read") { player, _ -> + // https://runescape.wiki/w/Mudskipper_Point?oldid=969991 + sendDialogue(player, colorize("%RBEWARE OF THE MUDSKIPPERS!")) + return@on true + } + + // For some reason the 2795 wrapper does not work for sober-up + on(intArrayOf(NPCs.SKIPPY_2796, NPCs.SKIPPY_2797, NPCs.SKIPPY_2798, NPCs.SKIPPY_2799), + IntType.NPC, "sober-up") { player, _ -> + return@on soberSkippy(player) + } + + onUseWith(IntType.NPC, Items.BUCKET_OF_WATER_1929, NPCs.SKIPPY_2795) { player, _, _ -> + return@onUseWith soberSkippy(player) + } + + onUseWith(IntType.NPC, Items.FORLORN_BOOT_6663, NPCs.SKIPPY_2795){ player, _, _ -> + openDialogue(player, SkippyBootDialogue()) + return@onUseWith true + } + } + + override fun defineDestinationOverrides() { + + // Don't run towards the fishing spots when trying to lure or bait or throw explosives + setDest(IntType.SCENERY, FISHING_SPOTS, "Lure", "Bait", "use"){ entity, _ -> + return@setDest entity.location + } + } +} diff --git a/Server/src/main/content/region/asgarnia/mudskipperpoint/dialogue/SkippyDialogue.kt b/Server/src/main/content/region/asgarnia/mudskipperpoint/dialogue/SkippyDialogue.kt new file mode 100644 index 000000000..2106d6856 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/mudskipperpoint/dialogue/SkippyDialogue.kt @@ -0,0 +1,267 @@ +package content.region.asgarnia.mudskipperpoint.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Vars + + +@Initializable +class SkippyDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SkippyBucketDialogue(0, getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE))) + return true + } + + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SKIPPY_2795) + } + +} + + +class SkippyBucketDialogue(override var stage: Int = 0, val questStage: Int = 0) : DialogueFile() { + + companion object{ + // Skippy will progress through these stages as you help him + const val DRUNK = 0 + const val TENDER = 1 + const val HUNGOVER = 2 + const val DONE_QUEST = 3 + + // Dialogue branches + const val THROW_WATER = 10 + const val DRUNK_RAMBLING = 30 + const val CRAZY_PEOPLE = 40 + const val WHO_ARE_THEY = 50 + // Tea state + const val LEARN_RECIPE = 170 + const val PLAGUE_CITY_RECIPE = 180 + const val NO_TEA = 190 + // Hangover cure state + const val CURE = 220 + const val NO_CURE = 250 + const val RECIPE = 260 + const val NAME_ORIGIN = 270 + + const val ALL_DONE = 300 + } + + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SKIPPY_2796) + when (questStage){ + DRUNK -> when (stage) { + 0 -> if(hasAnItem(player!!, Items.BUCKET_OF_WATER_1929).exists()){ + playerl(FacialExpression.THINKING, "Well, I could dump this bucket of water over him. That would sober him up a little.").also { stage = THROW_WATER } + } + else { + playerl(FacialExpression.ASKING, "Are you all right? You seem a little...incoherent.").also { stage = DRUNK_RAMBLING } + } + THROW_WATER -> showTopics( + Topic("Throw the water!", THROW_WATER+ 1, true), + Topic("I think I'll leave it for now.", END_DIALOGUE) + ) + THROW_WATER + 1 -> playerl(FacialExpression.NEUTRAL, "Hey, Skippy!").also { stage++ } + THROW_WATER + 2 -> npcl(FacialExpression.DRUNK, "What?").also { + stage = END_DIALOGUE + queueScript(player!!, 1){ animationStage : Int -> + when(animationStage){ + 1 -> { + // todo get the right animation + animate(player!!, 2283) + removeItem(player!!, Items.BUCKET_OF_WATER_1929) + addItem(player!!, Items.BUCKET_1925) + setVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE, TENDER, true) + return@queueScript delayScript(player!!, 1) + } + 2 -> { + openDialogue(player!!, SkippyBucketDialogue(THROW_WATER + 4)) + return@queueScript delayScript(player!!, 1) + } + 3 -> return@queueScript stopExecuting(player!!) + else -> return@queueScript delayScript(player!!, 1) + } + } } + THROW_WATER + 4 -> npcl(FacialExpression.ANGRY, "Ahhhhhhhhhhgh! That's cold! Are you trying to kill me?").also { stage++ } + THROW_WATER + 5 -> playerl(FacialExpression.NEUTRAL, "Nope. Just sober you up. Memory coming back yet?").also { stage++ } + THROW_WATER + 6 -> npcl(FacialExpression.ANGRY, "No. But I could do with a bowl of tea to warm myself up a bit. Go grab me one and we'll talk.").also { stage++ } + THROW_WATER + 7 -> playerl(FacialExpression.ASKING, "Any particular type of tea?").also { stage++ } + THROW_WATER + 8 -> npcl(FacialExpression.ANGRY, "Nettle for preference. Just make sure it's hot.").also { stage++ } + THROW_WATER + 9 -> npcl(FacialExpression.ANGRY, "And don't throw it at me!").also { stage++ } + THROW_WATER + 10 -> playerl(FacialExpression.HALF_GUILTY, "What's your problem? You're all clean now.").also { stage = END_DIALOGUE } + + + DRUNK_RAMBLING -> npcl(FacialExpression.DRUNK, "Inc'hearnt? Inc'herant! You...you...with yer fancy book- lernin' words. You'd be more than inc'herant if youd seen...").also { stage++ } + DRUNK_RAMBLING + 1 -> npcl(FacialExpression.DRUNK, "(Dramatic pause)").also { stage++ } + DRUNK_RAMBLING + 2 -> npcl(FacialExpression.DRUNK, "THEM!").also { stage++ } + DRUNK_RAMBLING + 3 -> showTopics( + Topic("I'm sure I would as well.", CRAZY_PEOPLE), + Topic("Who are (Dramatic pause) THEY?", WHO_ARE_THEY, true) + ) + + CRAZY_PEOPLE -> playerl(FacialExpression.NEUTRAL, "I'm going over here to talk to non-crazy people now.").also { stage++ } + CRAZY_PEOPLE + 1 -> npcl(FacialExpression.DRUNK, "Yeah? Yeah? Well when THEY come floppin' into your house and eat your furniture you'll be sorry!").also { stage = END_DIALOGUE } + + WHO_ARE_THEY -> playerl(FacialExpression.NEUTRAL, "Who are").also { stage++ } + WHO_ARE_THEY + 1 -> playerl(FacialExpression.NEUTRAL, "(Dramatic pause)").also { stage++ } + WHO_ARE_THEY + 2 -> playerl(FacialExpression.NEUTRAL, "THEY?").also { stage++ } + WHO_ARE_THEY + 3 -> npcl(FacialExpression.DRUNK, "They! Those bloodthirsty, flesh-tearing devils! They are the reason I'm out here every day hurlin' bottles into the sea!").also { stage++ } + WHO_ARE_THEY + 4 -> npcl(FacialExpression.DRUNK, "They are the reason I've lost everything, except the horrifying memory of what THEY look like...").also { stage++ } + WHO_ARE_THEY + 5 -> playerl(FacialExpression.ASKING, "And what do THEY look like?").also { stage++ } + WHO_ARE_THEY + 6 -> npcl(FacialExpression.DRUNK, "Mudskippers!").also { stage++ } + WHO_ARE_THEY + 7 -> playerl(FacialExpression.ASKING, "Mudskippers?").also { stage++ } + WHO_ARE_THEY + 8 -> npcl(FacialExpression.DRUNK, "Aye, Mudskippers! Those ferocious, ravening, evil, beady-eyed terrors of the deep!").also { stage++ } + WHO_ARE_THEY + 9 -> playerl(FacialExpression.SUSPICIOUS, "I...see...").also{ stage++ } + WHO_ARE_THEY + 10 -> npcl(FacialExpression.DRUNK, " I was ambushed by them way back, see. They got the drop on me...I can't remember where, somewhere around here though.").also { stage++ } + WHO_ARE_THEY + 11 -> playerl(FacialExpression.ASKING, "These would be the mudskippers, right?").also{ stage++ } + WHO_ARE_THEY + 12 -> npcl(FacialExpression.DRUNK, "Aye! The mudskippers! Huge they were! Ten feet of glistening, muddy flesh floppin' towards me with white foam flying from their gnashing fangs!").also { stage++ } + WHO_ARE_THEY + 13 -> npcl(FacialExpression.DRUNK, "I fought them up and down the beach, with the tide rising and more of them leaping towards me with cutlasses drawn!").also { stage++ } + WHO_ARE_THEY + 14 -> playerl(FacialExpression.HALF_GUILTY, "This is fascinating, but I have to be...").also{ stage++ } + WHO_ARE_THEY + 15 -> npcl(FacialExpression.DRUNK, "Shut yer' word-hole and listen! I can't remember all the details, as I'm sure they must have hit me quite hard, but the last thing I remember before it all went black...").also { stage++ } + WHO_ARE_THEY + 16 -> npcl(FacialExpression.DRUNK, "...was one of those devils rearing over me, its eyes glowin' red with the fires of hell!").also { stage++ } + WHO_ARE_THEY + 17 -> playerl(FacialExpression.ROLLING_EYES, "Fires of hell...right. I believe you.").also { stage++ } + WHO_ARE_THEY + 18 -> npcl(FacialExpression.DRUNK, "No you don't! You think I'm crazy, like all the rest! Well, if I'm crazy, how did I get these?").also { stage++ } + WHO_ARE_THEY + 19 -> playerl(FacialExpression.ASKING, "Get what?").also { stage++ } + WHO_ARE_THEY + 20 -> sendDialogue(player!!, "Skippy shows you what appears to be massive bite scars on his legs. You're no expert, but they look like... giant mudskipper bites!").also { stage++ } + WHO_ARE_THEY + 21 -> playerl(FacialExpression.ASKING, "Giant mudskipper bites! Where did you get those?").also { stage++ } + WHO_ARE_THEY + 22 -> npcl(FacialExpression.DRUNK, "I can't remember... I've been drinking to forget the horror, and all I seem to have forgotten is where it all happened...").also { stage++ } + WHO_ARE_THEY + 23 -> playerl(FacialExpression.THINKING, "Hmmm...I suppose if I sober you up you may well start to recall.").also{ stage++ } + WHO_ARE_THEY + 24 -> npcl(FacialExpression.DRUNK, "You'll have a job. I've been drinking this for a week.").also { stage++ } + WHO_ARE_THEY + 25 -> playerl(FacialExpression.ASKING, "'Captain Braindeath's Extra Strength Rum/Drain Cleaner. Now 50% more debilitating'?").also { stage++ } + WHO_ARE_THEY + 26 -> npcl(FacialExpression.DRUNK, "It's the extra sheep tranquilizers that gives it that added kick!").also { stage++ } + WHO_ARE_THEY + 27 -> playerl(FacialExpression.NEUTRAL, "Stay here and I'll be right back. Try not to move. Or go near any open flames.").also { stage = END_DIALOGUE } + } + + TENDER -> when(stage){ + 0 -> playerl(FacialExpression.HAPPY, "Hey, Skippy!").also { stage++ } + 1 -> npcl(FacialExpression.PANICKED, "Gaah! Don't drench me again!").also { stage++ } + 2 -> playerl(FacialExpression.HALF_GUILTY, "Hey! I only did that once! Try not to be such a big baby!").also { stage++ } + 3 -> npcl(FacialExpression.HALF_THINKING, "So what are you here for then?").also { stage = if (hasAnItem(player!!, Items.NETTLE_TEA_4239).exists()) 4 else NO_TEA } + 4 -> playerl(FacialExpression.HAPPY, "I've come to give you your tea.").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY, "Excellent! I was thinking I was going to freeze out here!").also { stage++ } + 6 -> sendItemDialogue(player!!, Items.NETTLE_TEA_4239, "Skippy drinks the tea and clutches his forehead in pain.").also { + stage++ + removeItem(player!!, Items.NETTLE_TEA_4239) + setVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE, HUNGOVER, true) + } + 7 -> npcl(FacialExpression.ANNOYED, "Ohhhhh...").also { stage++ } + 8 -> playerl(FacialExpression.ASKING, "What? What's wrong?").also { stage++ } + 9 -> npcl(FacialExpression.ANNOYED, "Not so loud...I think I have a hangover...").also { stage++ } + 10 -> playerl(FacialExpression.HALF_WORRIED, "Great...Well, I doubt you can remember anything through a hangover. What a waste of nettle tea...").also { stage++ } + 11 -> npcl(FacialExpression.FURIOUS, "Hey! A little sympathy here?").also { stage++ } + 12 -> npcl(FacialExpression.ANNOYED, "Owwowwoww... must remember not to shout...").also { stage++ } + 13 -> npcl(FacialExpression.ASKING, "Look, I do know a hangover cure. If you can get me a bucket of the stuff I think I'll be okay.").also { stage = if(getQuestStage(player!!, Quests.PLAGUE_CITY) >= 14 ) PLAGUE_CITY_RECIPE else LEARN_RECIPE } + + PLAGUE_CITY_RECIPE -> playerl(FacialExpression.HALF_THINKING, "Wait... is this cure a bucket of chocolate milk and snape grass?").also { stage++ } + PLAGUE_CITY_RECIPE + 1 -> npcl(FacialExpression.HAPPY, "Yes! That's the stuff!").also { stage++ } + PLAGUE_CITY_RECIPE + 2 -> playerl(FacialExpression.HALF_THINKING, "Ahhh. Yes, I've made some of that stuff before. I should be able to get you some, no problem.").also { stage = END_DIALOGUE } + + LEARN_RECIPE -> playerl(FacialExpression.ASKING, "So what is it you need?").also { stage++ } + LEARN_RECIPE + 1 -> npcl(FacialExpression.NEUTRAL, "A bucket of milk with chocolate ground into it, with a handful of snape grass thrown in on top.").also { stage++ } + LEARN_RECIPE + 2 -> playerl(FacialExpression.ASKING, "What? Run that past me again?").also { stage ++ } + LEARN_RECIPE + 3 -> npcl(FacialExpression.NEUTRAL, "Take a bucket of milk, a bar of chocolate and some snape grass.").also { stage++ } + LEARN_RECIPE + 4 -> npcl(FacialExpression.NEUTRAL, "Grind the chocolate with a mortar and pestle.").also { stage++ } + LEARN_RECIPE + 5 -> npcl(FacialExpression.NEUTRAL, "Add the chocolate powder to the milk, then add the snape grass.").also { stage++ } + LEARN_RECIPE + 6 -> npcl(FacialExpression.NEUTRAL, "Then bring it here and I will drink it.").also { stage++ } + LEARN_RECIPE + 7 -> npcl(FacialExpression.NEUTRAL, "The end, and we all live happily ever after. Got it?").also { stage = END_DIALOGUE } + + NO_TEA -> playerl(FacialExpression.HALF_GUILTY, "No real reason. I just thought I would check up on you is all.").also { stage++ } + NO_TEA + 1 -> npcl(FacialExpression.ANGRY, "Well, I'm still wet, still cold and still waiting on that nettle tea.").also { stage = END_DIALOGUE } + } + HUNGOVER -> when(stage){ + 0 -> playerl(FacialExpression.HAPPY, "Hey, Skippy!").also{ stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "Egad! Don't you know not to shout around a guy with a hangover?").also { stage++ } + 2 -> npcl(FacialExpression.HALF_GUILTY, "Ahhhhhg...No more shouting for me...").also { stage++ } + 3 -> npcl(FacialExpression.ASKING, "What is it anyway?").also { stage = if (hasAnItem(player!!, Items.HANGOVER_CURE_1504).exists()) CURE else NO_CURE } + + CURE -> playerl(FacialExpression.HAPPY, "Well Skippy, you will no doubt be glad to hear that I got you your hangover cure!").also { stage++ } + CURE + 1 ->npcl(FacialExpression.HAPPY, "Gimme!").also { stage++ } + CURE + 2 -> sendDialogue(player!!, "Skippy chugs the hangover cure... very impressive.").also { + removeItem(player!!, Items.HANGOVER_CURE_1504) + stage++ + setVarbit(player!!, 1344, DONE_QUEST, true) + } + CURE + 3 -> npcl(FacialExpression.HAPPY, "Ahhhhhhhhhhhhhhh...").also { stage ++ } + CURE + 4 -> npcl(FacialExpression.HAPPY, "Much better...").also { stage ++ } + CURE + 5 -> playerl(FacialExpression.ASKING, "Feeling better?").also { stage ++ } + CURE + 6 -> npcl(FacialExpression.HAPPY, "Considerably.").also { stage ++ } + CURE + 7 -> playerl(FacialExpression.ASKING, "Then tell me where the mudskippers are!").also { stage++ } + CURE + 8 -> npcl(FacialExpression.NEUTRAL, "I wish you wouldn't go looking for them. Those vicious killers will tear you apart.").also { stage ++ } + CURE + 9 -> npcl(FacialExpression.HALF_THINKING, "It's all becoming clear to me now...").also { stage ++ } + CURE + 10 -> npcl(FacialExpression.HAPPY, "I was fishing using a Fishing Explosive...").also { stage ++ } + CURE + 11 -> playerl(FacialExpression.ASKING, "A Fishing Explosive?").also { stage++ } + CURE + 12 -> npcl(FacialExpression.NEUTRAL, "Well, Slayer Masters sell these highly volatile potions for killing underwater creatures.").also { stage ++ } + CURE + 13 -> npcl(FacialExpression.NEUTRAL, "If you don't feel like lobbing a net about all day you can use them to fish with...").also { stage ++ } + CURE + 14 -> npcl(FacialExpression.NEUTRAL, "But this time I was startled by what I thought was a giant mudskipper.").also { stage ++ } + CURE + 15 -> npcl(FacialExpression.NEUTRAL, "What it was, in fact, was a...").also { stage ++ } + CURE + 16 -> npcl(FacialExpression.NEUTRAL, "Dramatic Pause...").also { stage ++ } + CURE + 17 -> npcl(FacialExpression.PANICKED, "A Mogre!").also { stage ++ } + CURE + 18 -> playerl(FacialExpression.ASKING, "What exactly is a Mogre?").also { stage++ } + CURE + 19 -> npcl(FacialExpression.NEUTRAL, "A Mogre is a type of Ogre that spends most of its time underwater.").also { stage ++ } + CURE + 20 -> npcl(FacialExpression.NEUTRAL, "They hunt giant mudskippers by wearing their skins and swimming close until they can attack them.").also { stage ++ } + CURE + 21 -> npcl(FacialExpression.NEUTRAL, "When I used the Fishing Explosive I scared off all the fish, and so the Mogre got out of the water to express its extreme displeasure.").also { stage ++ } + CURE + 22 -> npcl(FacialExpression.NEUTRAL, "With an iron mace.").also { stage ++ } + CURE + 23 -> playerl(FacialExpression.ASKING, "I take it the head injury is responsible for the staggering and yelling?").also { stage++ } + CURE + 24 -> npcl(FacialExpression.NEUTRAL, "No, no.").also { stage ++ } + CURE + 25 -> npcl(FacialExpression.NEUTRAL, "My addiction to almost-lethal alcohol did that.").also { stage ++ } + CURE + 26 -> npcl(FacialExpression.NEUTRAL, "But if you are set on finding these Mogres just head south from here until you find Mudskipper Point.").also { stage ++ } + CURE + 27 -> playerl(FacialExpression.ASKING, "The mudskipper-eating monsters are to be found at Mudskipper point?").also { stage++ } + CURE + 28 -> playerl(FacialExpression.ROLLING_EYES, "Shock!").also { stage++ } + CURE + 29 -> playerl(FacialExpression.NEUTRAL, "Thanks. I'll be careful.").also { stage = END_DIALOGUE } + + NO_CURE -> playerl(FacialExpression.HALF_GUILTY, "I just came back to ask you something.").also { stage++ } + NO_CURE + 1 -> npcl(FacialExpression.ANNOYED, "What?").also { stage++ } + NO_CURE + 2 -> showTopics( + Topic("How do I make that hangover cure again?", RECIPE), + Topic("Why do they call you 'Skippy'?", NAME_ORIGIN) + ) + + RECIPE -> npcl(FacialExpression.ANGRY, "Give me strength...Here's what you do. Pay attention!").also { stage++ } + RECIPE + 1 -> npcl(FacialExpression.ANGRY, "You take a bucket of milk, a bar of chocolate and some snape grass.").also { stage++ } + RECIPE + 2 -> npcl(FacialExpression.ANGRY, "Grind the chocolate with a pestle and mortar.").also { stage++ } + RECIPE + 3 -> npcl(FacialExpression.ANGRY, "Add the chocolate powder to the milk, then add the snape grass.").also { stage++ } + RECIPE + 4 -> npcl(FacialExpression.ANGRY, "Then bring it here and I will drink it.").also { stage++ } + RECIPE + 5 -> npcl(FacialExpression.ANGRY, "Are you likely to remember that or should I go get some crayons and draw you a picture?").also { stage++ } + RECIPE + 6 -> playerl(FacialExpression.ANGRY, "Hey! I remember it now, ok! See you in a bit.").also { stage = END_DIALOGUE } + + NAME_ORIGIN -> npcl(FacialExpression.THINKING, "I think it may have something to do with my near- constant raving about mudskippers.").also { stage++ } + NAME_ORIGIN + 1 -> npcl(FacialExpression.THINKING, "That or it's something to do with that time with the dress and the field full of daisies...").also { stage = END_DIALOGUE } + } + DONE_QUEST -> when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "Hey, Skippy.").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Hey you!").also { stage++ } + 2 -> playerl(FacialExpression.ASKING, "How do I annoy the Mogres again?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY, "Go south to Mudskipper Point and lob a Fishing Explosive into the sea. You can grab them from the Slayer masters.").also { stage++ } + 4 -> playerl(FacialExpression.ASKING, "Thanks! So, what are you going to do now?").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY, "Well, I was planning on continuing my hobby of wandering up and down this bit of coastline, bellowing random threats and throwing bottles.").also { stage++ } + 6 -> npcl(FacialExpression.ASKING, "And you?").also { stage++ } + 7 -> playerl(FacialExpression.NEUTRAL, "I was planning on wandering up and down the landscape, bugging people to see if they had mindblowingly dangerous quests for me to undertake.").also { stage++ } + 8 -> npcl(FacialExpression.HAPPY, "Well, good luck with that!").also { stage++ } + 9 -> playerl(FacialExpression.HAPPY, "You too!").also { stage++ } + 10 -> npcl(FacialExpression.ROLLING_EYES, "Weirdo...").also { stage++ } + 11 -> playerl(FacialExpression.ROLLING_EYES, "Loony..").also { stage = END_DIALOGUE } + } + } + } +} + +class SkippyBootDialogue: DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SKIPPY_2796) + val expression = if (getVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE) > SkippyBucketDialogue.DRUNK) FacialExpression.ROLLING_EYES else FacialExpression.DRUNK + npcl(expression, "Thanks! Now I have two right boots!").also { stage = END_DIALOGUE } + } + +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java index 493bc1973..5f5446083 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.plugin.Initializable; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the dialogue plugin used for the npc Ahav. @@ -117,7 +118,7 @@ public final class AhabDialogue extends DialoguePlugin { stage = 28; break; case 28: - if (player.getQuestRepository().isComplete("Dragon Slayer")) { + if (player.getQuestRepository().isComplete(Quests.DRAGON_SLAYER)) { player("Well, I do have a ship that I'm not using.", "It's the Lady Lumbridge."); stage = 29; } else { diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/GerrantDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/GerrantDialogue.java deleted file mode 100644 index 1d00b97d0..000000000 --- a/Server/src/main/content/region/asgarnia/portsarim/dialogue/GerrantDialogue.java +++ /dev/null @@ -1,82 +0,0 @@ -package content.region.asgarnia.portsarim.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used for the gerrant npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class GerrantDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code GerrantDialogue} {@code Object}. - */ - public GerrantDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code GerrantDialogue} {@code Object}. - * @param player the player. - */ - public GerrantDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new GerrantDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Welcome! You can buy fishing equipment at my store.", "We'll also buy anything you catch off you."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Choose an option:", "Let's see what you've got then.", "Sorry, I'm not interested."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HAPPY, "Let's see what you've got then."); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I'm not interested."); - stage = 20; - break; - - } - break; - case 10: - end(); - npc.openShop(player); - break; - case 20: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 558 }; - } -} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java index e09ea0149..6c5e14b1e 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue used for the klarense npc. @@ -51,7 +52,7 @@ public final class KlarenseDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Dragon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); if (args.length > 1) { interpreter.sendDialogues(npc, FacialExpression.ANGRY, "Hey, stay off my ship! That's private property!"); stage = 0; diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java index 884ce1c00..e8c921159 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java @@ -41,6 +41,11 @@ public final class MonkOfEntranaDialogue extends DialoguePlugin { return new MonkOfEntranaDialogue(player); } + public void sail(Player player, Ships ship) { + ship.sail(player); + playJingle(player, 172); + } + @Override public boolean open(Object... args) { npc = (NPC) args[0]; @@ -98,7 +103,7 @@ public final class MonkOfEntranaDialogue extends DialoguePlugin { stage = 25; break; case 23: - interpreter.sendDialogues(npc, null, "Do not try and decieve us again. Come back when you", "have liad down your Zamorakian instruments of death."); + interpreter.sendDialogues(npc, null, "Do not try to deceive us again. Come back when you", "have laid down your Zamorakian instruments of death."); stage = 24; break; case 24: @@ -106,8 +111,7 @@ public final class MonkOfEntranaDialogue extends DialoguePlugin { break; case 25: end(); - Ships.PORT_SARIM_TO_ENTRANA.sail(player); - playJingle(player, 172); + sail(player, Ships.PORT_SARIM_TO_ENTRANA); if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(0, 14)) { player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 0, 14, true); } @@ -133,9 +137,7 @@ public final class MonkOfEntranaDialogue extends DialoguePlugin { stage = 511; break; case 511: - end(); - Ships.ENTRANA_TO_PORT_SARIM.sail(player); - playJingle(player, 172); + sail(player, Ships.ENTRANA_TO_PORT_SARIM); break; case 520: end(); diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java index 214b5f9f4..e3a46166c 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java @@ -12,6 +12,7 @@ import core.plugin.Initializable; import core.game.node.item.Item; import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; /** * Represents the dialogue to handle Rebeard Frank. @@ -59,7 +60,7 @@ public class RedbeardFrankDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Pirate's Treasure"); + quest = player.getQuestRepository().getQuest(Quests.PIRATES_TREASURE); npc("Arr, Matey!"); stage = 0; replacementReward = AchievementDiary.canReplaceReward(player, DiaryType.FALADOR, level); diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java index 47df99e03..8746b7e93 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java @@ -15,6 +15,7 @@ import core.game.world.update.flag.context.Animation; import core.plugin.Plugin; import core.plugin.Initializable; import core.tools.RandomFunction; +import content.data.Quests; /** * Represents the port sarim plugin. @@ -72,7 +73,7 @@ public final class PortSarimPlugin extends OptionHandler { player.getDialogueInterpreter().open(238284); break; case "attack": - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 20) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 20) { player.getPacketDispatch().sendMessage("The goblin is already in prison. You have no reason to attack him."); } else { player.getProperties().getCombatPulse().attack(node); diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java index 206b3860c..7f45a94f4 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java @@ -11,6 +11,7 @@ import core.game.world.repository.Repository; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the option handler for port sarim. @@ -206,7 +207,7 @@ public class PortsObjectPlugin extends OptionHandler { player.getPacketDispatch().sendMessage("You disembark the ship."); break; case 2593: - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) == 100) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 100) { player.getDialogueInterpreter().open(744, Repository.findNPC(744), true);// lady // lumbridge. return true; diff --git a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java index ae22be400..65ab84c0e 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java +++ b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java @@ -7,6 +7,7 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the pirates treasure quest. @@ -50,7 +51,7 @@ public final class PiratesTreasure extends Quest { * Constructs a new {@Code PiratesTreasure} {@Code Object} */ public PiratesTreasure() { - super("Pirate's Treasure", 23, 22, 2, 71, 0, 1, 4); + super(Quests.PIRATES_TREASURE, 23, 22, 2, 71, 0, 1, 4); } @Override diff --git a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java index a4f64a4dc..ce41de603 100644 --- a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java +++ b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java @@ -15,6 +15,7 @@ import core.game.node.item.Item; import core.game.node.scenery.Scenery; import core.game.world.map.Location; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the pirates treasure plugin. @@ -92,7 +93,7 @@ public final class PiratesTreasurePlugin extends OptionHandler { @Override public void run(Player player) { - final Quest quest = player.getQuestRepository().getQuest("Pirate's Treasure"); + final Quest quest = player.getQuestRepository().getQuest(Quests.PIRATES_TREASURE); player.lock(2); if (quest.getStage(player) == 20) { if (player.getSavedData().getQuestData().isGardenerAttack()) { diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialogue.kt new file mode 100644 index 000000000..317f96478 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialogue.kt @@ -0,0 +1,87 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.game.world.map.RegionManager +import core.tools.RandomFunction +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Handles Anja's dialogue. + */ +@Initializable +class AnjaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.NEUTRAL, "Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ASKING, "Hello @g[sir,madam]. What are you doing in my house?").also { stage++ } + 1 -> options("I'm just wandering around.", "I was hoping you'd give me some free stuff.", "I've come to kill you.").also { stage++ } + 2 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "I'm just wondering around.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "I was hoping you'd give me some free stuff.").also { stage = 20 } + 3 -> playerl(FacialExpression.ANGRY_WITH_SMILE, "I've come to kill you.").also { stage = 30 } + } + + 10 -> npcl(FacialExpression.NEUTRAL, "Oh dear, are you lost?").also { stage++ } + 11 -> options("Yes, I'm lost.", "No, I know where I am.").also { stage++ } + 12 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'm lost.").also { stage = 13 } + 2 -> playerl(FacialExpression.NEUTRAL, "No, I know where I am.").also { stage = 15 } + } + + 13 -> npcl(FacialExpression.FRIENDLY, "Okay, just walk north-east when you leave this house and soon you'll reach the big city of Falador.").also { stage++ } + 14 -> playerl(FacialExpression.FRIENDLY, "Thanks a lot.").also { stage = END_DIALOGUE } + 15 -> npcl(FacialExpression.ASKING, "Oh? Well, would you mind wandering somewhere else?").also { stage++ } + 16 -> npcl(FacialExpression.NEUTRAL, "This is my house.").also { stage++ } + 17 -> playerl(FacialExpression.NEUTRAL, "Meh!").also { stage = END_DIALOGUE } + + 20 -> { + val dialogues = arrayOf("Do you REALLY need it?", "I don't have much on me...", "I don't know...") + npcl(FacialExpression.NEUTRAL, dialogues[RandomFunction.random(0, 3)]) + stage++ + } + + 21 -> playerl(FacialExpression.ASKING, "I promise I'll stop bothering you!").also { stage++ } + 22 -> playerl(FacialExpression.ASKING, "Pleeease!").also { stage++ } + 23 -> playerl(FacialExpression.ASKING, "Pwetty pleathe wiv thugar on top!").also { stage++ } + 24 -> { + npcl(FacialExpression.NEUTRAL, "Oh, alright. Here you go.") + addItemOrDrop(player, Items.COINS_995, RandomFunction.random(1, 3)) + stage = END_DIALOGUE + } + + 30 -> { + stage = END_DIALOGUE + close() + + val hengel = findLocalNPC(npc, NPCs.HENGEL_2683) + if(hengel != null) + sendChat(hengel, "Aaaaarrgh!") + + sendChat(npc, "Eeeek!") + } + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AnjaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ANJA_2684) + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialoguePlugin.java b/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialoguePlugin.java deleted file mode 100644 index 36ed82c7b..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialoguePlugin.java +++ /dev/null @@ -1,144 +0,0 @@ -package content.region.asgarnia.rimmington.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.map.RegionManager; -import core.plugin.Initializable; -import core.tools.RandomFunction; - -/** - * Represents the dialogue plugin used for the anja npc. - * @author jamix77 - */ -@Initializable -public final class AnjaDialoguePlugin extends DialoguePlugin { - - /** - * - * Constructs a new @{Code AnjaDialoguePlugin} object. - */ - public AnjaDialoguePlugin() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code AjjatDialoguePlugin} {@code Object}. - * @param player the player. - */ - public AnjaDialoguePlugin(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new AnjaDialoguePlugin(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - player("Hello."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - npc("Hello sir. What are you doing in my house?"); - stage = 1; - break; - case 1: - interpreter.sendOptions("Select an Option", "I'm just wandering around.", "I was hoping you'd give me some free stuff.", "I've come to kill you."); - stage = 2; - break; - case 2: - if (buttonId == 1) { - player("I'm just wondering around."); - stage = 3; - } else if (buttonId == 2) { - player("I was hoping you'd give me some free stuff."); - stage = 10; - } else if (buttonId == 3) { - player("I've come to kill you."); - stage = 13; - } - break; - case 3: - npc("Oh dear are you lost?"); - stage++; - break; - case 4: - interpreter.sendOptions("Select an Option.", "Yes, I'm lost.", "No, I know where I am."); - stage++; - break; - case 5: - switch (buttonId) { - case 1: - player("Yes, I'm lost."); - stage =6; - break; - case 2: - player("No I know where I am."); - stage = 8; - break; - } - break; - case 6: - npc("Okay, just walk north-east when you leave this house,","and soon you'll reach the big city of Falador."); - stage++; - break; - case 7: - player("Thanks a lot."); - stage = 605; - break; - case 8: - npc("Oh? Well, would you mind wandering somewhere else?", "This is my house."); - stage++; - break; - case 9: - player("Meh!"); - stage = 605; - break; - case 10: - String[] dialogues = {"Do you REALLY need it","I don't have much on me...", "I don't know..."}; - npc(dialogues[RandomFunction.random(0, 2)]); - stage++; - break; - case 11: - interpreter.sendDialogues(player, FacialExpression.ASKING, "I promise I'll stop bothering you!", "Pleeease!","Pwetty pleathe wiv thugar on top!"); - stage++; - break; - case 12: - npc("Oh, alright. Here you go."); - player.getInventory().add(new Item(995,RandomFunction.random(1, 3))); - stage = 605; - break; - case 13: - npc.sendChat("Eeeek!"); - for (NPC npc1 : RegionManager.getLocalNpcs(player)) { - if (npc1.getName().equalsIgnoreCase("Hengel")) { - npc1.sendChat("Aaaaarrgh!"); - break; - } - } - end(); - break; - case 605: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2684 }; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.java b/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.java deleted file mode 100644 index faa29da41..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.java +++ /dev/null @@ -1,81 +0,0 @@ -package content.region.asgarnia.rimmington.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used to handle the brain archery npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class BrianArcheryDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code BrianArcheryDialogue} {@code Object}. - */ - public BrianArcheryDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code BrianArcheryDialogue} {@code Object}. - * @param player the player. - */ - public BrianArcheryDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new BrianArcheryDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Would you like to buy some archery equipment?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "No thanks, I've got all the archery equipment I need.", "Let's see what you've got, then."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thanks, I've got all the archery equipment I need."); - stage = 10; - break; - case 2: - end(); - npc.openShop(player); - break; - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Okay. Fare well on your travels."); - stage = 11; - break; - case 11: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 1860 }; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.kt new file mode 100644 index 000000000..0598231cc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.kt @@ -0,0 +1,47 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the BrianArchery's dialogue. + */ +@Initializable +class BrianArcheryDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Would you like to buy some archery equipment?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Let's see what you've got, then.", "No thanks, I've got all the archery equipment I need.").also { stage++ } + 1 -> when (buttonId) { + 1 -> end().also { openNpcShop(player, npc.id) } + 2 -> playerl(FacialExpression.HALF_GUILTY, "No thanks, I've got all the archery equipment I need.").also { stage = 10 } + } + + 10 -> { + npcl(FacialExpression.FRIENDLY, "Okay. Fare well on your travels.") + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BrianArcheryDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BRIAN_1860) + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialogue.kt new file mode 100644 index 000000000..3bae6f108 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialogue.kt @@ -0,0 +1,67 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.findLocalNPC +import core.api.sendChat +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.game.world.map.RegionManager +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the Hengel's dialogue. + */ +@Initializable +class HengelDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ASKING, "What are you doing here?").also { stage++ } + 1 -> options("I'm just wandering around.", "I was hoping you'd give me some free stuff.", "I've come to kill you.").also { stage++ } + 2 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "I'm just wondering around.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "I was hoping you'd give me some free stuff.").also { stage = 20 } + 3 -> playerl(FacialExpression.ANGRY_WITH_SMILE, "I've come to kill you.").also { stage = 30 } + } + + 10 -> npcl(FacialExpression.ASKING, "You do realise you're wandering around in my house?").also { stage++ } + 11 -> playerl(FacialExpression.NEUTRAL, "Yep.").also { stage++ } + 12 -> npcl(FacialExpression.ANNOYED, "Well please get out!").also { stage++ } + 13 -> playerl(FacialExpression.NEUTRAL, "Sheesh, keep your wig on!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.ANNOYED, "No, I jolly well wouldn't!").also { stage++ } + 21 -> npcl(FacialExpression.ANNOYED, "Get out of my house!").also { stage++ } + 22 -> playerl(FacialExpression.NEUTRAL, "Meanie!").also { stage = END_DIALOGUE } + + 30 -> { + stage = END_DIALOGUE + close() + + val anja = findLocalNPC(npc, NPCs.ANJA_2684) + if(anja != null) + sendChat(anja, "Eeeek!") + + sendChat(npc, "Aaaaarrgh!") + } + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HengelDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HENGEL_2683) + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialoguePlugin.java b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialoguePlugin.java deleted file mode 100644 index dcdc489bc..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialoguePlugin.java +++ /dev/null @@ -1,115 +0,0 @@ -package content.region.asgarnia.rimmington.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.world.map.RegionManager; -import core.plugin.Initializable; - -/** - * Represents the dialogue plugin used for the hengel npc. - * @author jamix77 - */ -@Initializable -public final class HengelDialoguePlugin extends DialoguePlugin { - - /** - * - * Constructs a new @{Code HengelDialoguePlugin} object. - */ - public HengelDialoguePlugin() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code AjjatDialoguePlugin} {@code Object}. - * @param player the player. - */ - public HengelDialoguePlugin(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new HengelDialoguePlugin(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - player("Hello."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - npc("What are you doing here?"); - stage = 1; - break; - case 1: - interpreter.sendOptions("Select an Option", "I'm just wandering around.", "I was hoping you'd give me some free stuff.", "I've come to kill you."); - stage = 2; - break; - case 2: - if (buttonId == 1) { - player("I'm just wondering around."); - stage = 3; - } else if (buttonId == 2) { - player("I was hoping you'd give me some free stuff."); - stage = 7; - } else if (buttonId == 3) { - player("I've come to kill you."); - stage = 9; - } - break; - case 3: - npc("You do realise you're wandering around in my house?"); - stage++; - break; - case 4: - player("Yep."); - stage++; - break; - case 5: - npc("Well please get out!"); - stage++; - break; - case 6: - player("Sheesh, keep your wig on!"); - stage = 605; - break; - case 7: - npc("No, I jolly well wouldn't!","Get out of my house"); - stage++; - break; - case 8: - player("Meanie!"); - stage = 605; - break; - case 9: - npc.sendChat("Aaaaarrgh!"); - for (NPC npc1 : RegionManager.getLocalNpcs(player)) { - if (npc1.getName().equalsIgnoreCase("anja")) { - npc1.sendChat("Eeeek!"); - break; - } - } - end(); - break; - case 605: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2683 }; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.java b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.java deleted file mode 100644 index 8c32a718f..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.java +++ /dev/null @@ -1,226 +0,0 @@ -package content.region.asgarnia.rimmington.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.quest.Quest; -import core.plugin.Initializable; -import core.game.node.item.Item; - -/** - * Represents the dialogue plugin used for the hetty npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class HettyDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code HettyDialogue} {@code Object}. - */ - public HettyDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code HettyDialogue} {@code Object}. - * @param player the player. - */ - public HettyDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new HettyDialogue(player); - } - - @Override - public boolean open(Object... args) { - Quest quest = player.getQuestRepository().getQuest("Witch's Potion"); - if (quest.isCompleted(player)) { - interpreter.sendDialogues(307, FacialExpression.ASKING, "How's your magic coming along?"); - stage = 0; - } - switch (quest.getStage(player)) { - case 0: - interpreter.sendDialogues(307, FacialExpression.NEUTRAL, "What could you want with an old woman like me?"); - stage = 11; - break; - case 20: - interpreter.sendDialogues(307, FacialExpression.HAPPY, "So have you found the things for the potion?"); - stage = 100; - break; - case 40: - if (args.length == 2) { - interpreter.sendDialogue("You drink from the cauldron, it tastes horrible! You feel yourself", "imbued with power."); - stage = 41; - } else { - interpreter.sendDialogues(307, FacialExpression.HALF_GUILTY, "Well are you going to drink the potion or not?"); - stage = 500; - } - break; - } - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - Quest quest = player.getQuestRepository().getQuest("Witch's Potion"); - switch (stage) { - case 0: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm practicing and slowly getting better."); - stage = 1; - break; - case 1: - interpreter.sendDialogues(307, FacialExpression.HALF_GUILTY, "Good, good."); - stage = 2; - break; - case 2: - end(); - break; - case 11: - interpreter.sendOptions("Select an Option", "I am in search of a quest.", "I've heard that you are a witch."); - stage = 12; - break; - case 12: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I am in search of a quest."); - stage = 13; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I've heard that you are a witch."); - stage = 20; - break; - } - break; - case 13: - interpreter.sendDialogues(307, FacialExpression.HAPPY, "Hmmm... Maybe I can think of something for you."); - stage = 14; - break; - case 14: - interpreter.sendDialogues(307, FacialExpression.HAPPY, "Would you like to become more proficient in the dark", "arts?"); - stage = 15; - break; - case 15: - interpreter.sendOptions("Select an Option", "Yes help me become one with my darker side.", "No I have my principles and honour."); - stage = 16; - break; - case 16: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes help me become one with my darker side."); - stage = 30; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No I have my principles and honour."); - stage = 17; - break; - } - break; - case 17: - interpreter.sendDialogues(307, FacialExpression.HALF_GUILTY, "Suit yourself, but you're missing out."); - stage = 18; - break; - case 18: - end(); - break; - case 20: - interpreter.sendDialogues(307, FacialExpression.HALF_GUILTY, "Yes it does seem to be getting fairly common", "knowledge."); - stage = 21; - break; - case 21: - interpreter.sendDialogues(307, FacialExpression.HALF_GUILTY, "I fear I may get a visit from the witch hunter of", "Falador before long."); - stage = 22; - break; - case 22: - end(); - break; - case 30: - interpreter.sendDialogues(307, FacialExpression.NEUTRAL, "Ok I'm going to make a potion to help bring out your", "darker self."); - stage = 31; - break; - case 31: - interpreter.sendDialogues(307, FacialExpression.NEUTRAL, "You will need certain ingredients."); - stage = 32; - break; - case 32: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "What do I need?"); - stage = 33; - break; - case 33: - interpreter.sendDialogues(307, FacialExpression.NEUTRAL, "You need an eye of newt, a rat's tail, and onion... Oh", "and a piece of burnt meat."); - stage = 34; - break; - case 34: - interpreter.sendDialogues(player, FacialExpression.HAPPY, "Great, I'll go get them."); - stage = 35; - break; - case 35: - quest.start(player); - quest.setStage(player, 20); - end(); - break; - case 100: - // Her:Well I can't make the potion without them! - // Remember.../You - // need an eye of newt, a rat's tail, an onion, and a/piece of - // burnt - // meat. Off you go dear! Me:end(); - if (!player.getInventory().containItems(1957, 300, 2146, 221)) { - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm afraid I don't have all of them yet."); - stage = 101; - } else { - interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes I have everything!"); - stage = 110; - } - break; - case 110: - interpreter.sendDialogues(307, FacialExpression.HAPPY, "Excellent, can I have them then?"); - stage = 111; - break; - case 111: - interpreter.sendDialogue("You pass the ingredients to Hetty and she puts them all into her", "cauldron. Hetty closes her eyes and begins to chant. The cauldron", "bubbles mysteriously."); - stage = 112; - break; - case 112: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Well, is it ready?"); - stage = 113; - break; - case 113: - if (player.getInventory().remove(new Item(1957), new Item(300), new Item(2146), new Item(221))) { - quest.setStage(player, 40); - interpreter.sendDialogues(307, FacialExpression.HAPPY, "Ok, now drink from the cauldron."); - stage = 114; - } - break; - case 114: - end(); - break; - case 101: - interpreter.sendDialogues(307, FacialExpression.NEUTRAL, "Well I can't make the potion without them! Remember...", "You need an eye of newt, a rat's tail, an onion, and a", "piece of burnt meat. Off you go dear!"); - stage = 102; - break; - case 102: - end(); - break; - case 500: - end(); - break; - case 41: - end(); - quest.finish(player); - player.getQuestRepository().syncronizeTab(player); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 307 }; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.kt new file mode 100644 index 000000000..39a15588a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.kt @@ -0,0 +1,83 @@ +package content.region.asgarnia.rimmington.dialogue + +import content.data.Quests +import content.region.asgarnia.rimmington.quest.witchpotion.HettyWitchsPotionDialogue +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the Hetty's dialogue. + */ +@Initializable +class HettyDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + val questStage = getQuestStage(player, Quests.WITCHS_POTION) + + when(questStage) { + 0 -> npcl(FacialExpression.NEUTRAL, "What could you want with an old woman like me?").also { stage = 0 } + in 1..99 -> openDialogue(player, HettyWitchsPotionDialogue(questStage), npc) + else -> npcl(FacialExpression.ASKING, "How's your magic coming along?").also { stage = 30 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("I am in search of a quest.", "I've heard that you are a witch.").also { stage++ } + 1 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "I am in search of a quest.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "I've heard that you are a witch.").also { stage = 20 } + } + + 10 -> npcl(FacialExpression.HAPPY, "Hmmm... Maybe I can think of something for you.").also { stage++ } + 11 -> npcl(FacialExpression.HAPPY, "Would you like to become more proficient in the dark arts?").also { stage++ } + 12 -> options("Yes help me become one with my darker side.", "No I have my principles and honour.", "What, you mean improve my magic?").also { stage++ } + 13 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes help me become one with my darker side.").also { stage = 14 } + 2 -> playerl(FacialExpression.NEUTRAL, "No I have my principles and honour.").also { stage = 15 } + 3 -> playerl(FacialExpression.ASKING, "What, you mean improve my magic?").also { stage = 40 } + } + + 14 -> openDialogue(player, HettyWitchsPotionDialogue(0), npc) + 15 -> npcl(FacialExpression.HALF_GUILTY, "Suit yourself, but you're missing out.").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.HALF_GUILTY, "Yes it does seem to be getting fairly common knowledge").also { stage++ } + 21 -> npcl(FacialExpression.HALF_GUILTY, "I fear I may get a visit from the witch hunter of Falador before long.").also { stage = END_DIALOGUE } + + 30 -> playerl(FacialExpression.HALF_GUILTY, "I'm practicing and slowly getting better.").also { stage++ } + 31 -> npcl(FacialExpression.HALF_GUILTY, "Good, good.").also { stage = END_DIALOGUE } + + 40 -> sendDialogue("The witch sighs.").also { stage++ } + 41 -> npcl(FacialExpression.ANNOYED, "Yes, improve your magic...").also { stage++ } + 42 -> npcl(FacialExpression.ASKING, "Do you have no sense of drama?").also { stage++ } + 43 -> options("Yes I'd like to improve my magic.", "No I'm not interested.", "Show me the mysteries of the dark arts...").also { stage++ } + 44 -> when(buttonId) { + // TODO: Find authentic source for dialogue option + 1 -> playerl(FacialExpression.NEUTRAL, "Yes I'd like to improve my magic.").also { stage = 14 } + // TODO: Find authentic source for dialogue option + 2 -> playerl(FacialExpression.NEUTRAL, "No I'm not interested.").also { stage = 15 } + 3 -> playerl(FacialExpression.NEUTRAL, "Show me the mysteries of the dark arts...").also { stage++ } + } + 45 -> sendDialogue("The witch smiles mysteriously.").also { stage = 14 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HettyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HETTY_307) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.java b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.java deleted file mode 100644 index 4197fe202..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.java +++ /dev/null @@ -1,74 +0,0 @@ -package content.region.asgarnia.rimmington.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the RimmingtonShopKeeperDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class RimmingtonShopKeeperDialogue extends DialoguePlugin { - - public RimmingtonShopKeeperDialogue() { - - } - - public RimmingtonShopKeeperDialogue(Player player) { - super(player); - } - - @Override - public int[] getIds() { - return new int[] { 531, 530 }; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Yes, please. What are you selling?", "How should I use your shop?", "No, thanks."); - stage = 1; - break; - case 1: - - switch (buttonId) { - case 1: - end(); - npc.openShop(player); - break; - case 2: - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items to the", "shop."); - stage = 10; - break; - case 3: - end(); - break; - } - - break; - case 10: - end(); - break; - } - - return true; - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new RimmingtonShopKeeperDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Can I help you at all?"); - stage = 0; - return true; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.kt new file mode 100644 index 000000000..1c637f5a5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.kt @@ -0,0 +1,44 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the RimmingtonShopKeeper dialogue. + */ +@Initializable +class RimmingtonShopKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Can I help you at all?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Yes, please. What are you selling?", "How should I use your shop?", "No, thanks.").also { stage++ } + 1 -> when (buttonId) { + 1 -> end().also { openNpcShop(player, npc.id) } + 2 -> npcl(FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items stocked as you wish. You can also sell most items to the shop.").also { stage = END_DIALOGUE } + 3 -> end() + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RimmingtonShopKeeperDialogue(player) + } + + override fun getIds(): IntArray = intArrayOf( + NPCs.SHOPKEEPER_530, + NPCs.SHOP_ASSISTANT_531 + ) +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RommikDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RommikDialogue.kt new file mode 100644 index 000000000..3cb8514cc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RommikDialogue.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the Rommik's dialogue. + */ +@Initializable +class RommikDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Would you like to buy some crafting equipment?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Let's see what you've got, then.", "No thanks, I've got all the crafting equipment I need.").also { stage++ } + 1 -> when (buttonId) { + 1 -> end().also { openNpcShop(player, npc.id) } + 2 -> playerl(FacialExpression.HALF_GUILTY, "No thanks, I've got all the crafting equipment I need.").also { stage = 10 } + } + + 10 -> { + npcl(FacialExpression.FRIENDLY, "Okay. Fare well on your travels.") + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RommikDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ROMMIK_585) + } + +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RoomikDialogue.java b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RoomikDialogue.java deleted file mode 100644 index 90962c374..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RoomikDialogue.java +++ /dev/null @@ -1,73 +0,0 @@ -package content.region.asgarnia.rimmington.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the RoomikDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class RoomikDialogue extends DialoguePlugin { - - public RoomikDialogue() { - - } - - public RoomikDialogue(Player player) { - super(player); - } - - @Override - public int[] getIds() { - return new int[] { 585 }; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Choose an option:", "Let's see what you've got, then.", "No thanks, I've got all the crafting equipment I need."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - end(); - npc.openShop(player); - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I've got all the crafting equipment I need."); - stage = 20; - break; - - } - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Okay. Fare well on your travels."); - stage = 21; - break; - case 21: - end(); - break; - } - return true; - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new RoomikDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Would you like to buy some Crafting equipment?"); - stage = 0; - return true; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt b/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt new file mode 100644 index 000000000..5dc727594 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt @@ -0,0 +1,29 @@ +package content.region.asgarnia.rimmington.handler + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * @author Player Name + */ + +class RimmingtonListeners : InteractionListener { + override fun defineListeners() { + on(9662, IntType.SCENERY, "take") { player, node -> + if (!hasSpaceFor(player, Item(Items.SPADE_952))) { + sendMessage(player, "You don't have enough inventory space to hold that item.") + return@on true + } + animate(player, 535) + playAudio(player, Sounds.PICK2_2582) + addItem(player, Items.SPADE_952) + replaceScenery(node as Scenery, 0, 50) + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/HettyWitchsPotionDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/HettyWitchsPotionDialogue.kt new file mode 100644 index 000000000..50169689b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/HettyWitchsPotionDialogue.kt @@ -0,0 +1,77 @@ +package content.region.asgarnia.rimmington.quest.witchpotion + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.item.Item +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +/** + * Handles Hetty's dialogue for the Witch's Potion Quest. + */ +class HettyWitchsPotionDialogue(private val dStage: Int) : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (dStage) { + 0 -> handleQuestStartDialogue(player) + 20 -> handleGiveItemsDialogue(player) + 40 -> npcl(FacialExpression.ANNOYED, "Well are you going to drink the potion or not?").also { stage = END_DIALOGUE } + } + } + + private fun handleQuestStartDialogue(player: Player?) { + player ?: return + when (stage) { + 0 -> npcl(FacialExpression.HAPPY, "Ok I'm going to make a potion to help bring out your darker self.").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "You will need certain ingredients.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "What do I need?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "You need an eye of newt, a rat's tail, an onion... Oh and a piece of burnt meat.").also { stage++ } + 4 -> { + playerl(FacialExpression.HAPPY, "Great, I'll go and get them.") + startQuest(player, Quests.WITCHS_POTION) + setQuestStage(player, Quests.WITCHS_POTION, 20) + stage = END_DIALOGUE + } + } + } + + private fun handleGiveItemsDialogue(player: Player?) { + player ?: return + when (stage) { + 0 -> npcl(FacialExpression.HAPPY, "So have you found the things for the potion?").also { stage++ } + 1 -> { + if (inInventory(player, Items.ONION_1957, 1) && + inInventory(player, Items.RATS_TAIL_300, 1) && + inInventory(player, Items.BURNT_MEAT_2146, 1) && + inInventory(player, Items.EYE_OF_NEWT_221, 1)) { + playerl(FacialExpression.HAPPY, "Yes I have everything!").also { stage = 20 } + } else { + playerl(FacialExpression.HALF_GUILTY, "I'm afraid I don't have all of them yet.").also { stage = 10 } + } + } + + 10 -> npcl(FacialExpression.ANNOYED, "Well I can't make the potion without them! Remember...").also { stage++ } + 11 -> npcl(FacialExpression.NEUTRAL, "You need an eye of newt, a rat's tail, an onion, and a piece of burnt meat.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Off you go dear!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.HAPPY, "Excellent, can I have them then?").also { stage++ } + 21 -> sendDialogue(player, "You pass the ingredients to Hetty and she puts them all into her cauldron. Hetty closes her eyes and begins to chant. The cauldron bubbles mysteriously.").also { stage++ } + + 22 -> playerl(FacialExpression.NEUTRAL, "Well, is it ready?").also { stage++ } + 23 -> { + // Removing the items at this stage is authentic behavior + if (removeItem(player, Item(Items.ONION_1957, 1)) && + removeItem(player, Item(Items.RATS_TAIL_300, 1)) && + removeItem(player, Item(Items.BURNT_MEAT_2146, 1)) && + removeItem(player, Item(Items.EYE_OF_NEWT_221, 1))) { + npcl(FacialExpression.HAPPY, "Ok, now drink from the cauldron.") + setQuestStage(player, Quests.WITCHS_POTION, 40) + stage = END_DIALOGUE + } + } + } + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.java b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.java deleted file mode 100644 index 9b5738527..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.java +++ /dev/null @@ -1,90 +0,0 @@ -package content.region.asgarnia.rimmington.quest.witchpotion; - -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.game.node.entity.player.link.quest.Quest; - -/** - * Represents the witch's potion quest. - * @author 'Vexia - */ -@Initializable -public class WitchsPotion extends Quest { - - /** - * Constructs a new {@code WitchsPotion} {@code Object}. - */ - public WitchsPotion() { - super("Witch's Potion", 31, 30, 1, 67, 0, 1, 3); - } - - @Override - public void drawJournal(Player player, int stage) { - super.drawJournal(player, stage); - switch (getStage(player)) { - case 0: - line(player, BLUE + "I can start this quest by speaking to " + RED + "Hetty " + BLUE + "in her house in", 4+ 7); - line(player, RED + "Rimmington" + BLUE + ", West of " + RED + "Port Sarim", 5+ 7); - break; - case 20: - line(player, "I spoke to Hetty in her house at Rimmington. hetty told me", 4+ 7); - line(player, "she could increase my magic power if I can bring her", 5+ 7); - line(player, "certain ingredients for a potion.", 6+ 7); - line(player, BLUE + "Hetty needs me to bring her the following:", 8+ 7); - if (player.getInventory().contains(1957, 1)) { - line(player, "I have an onion with me", 9+ 7); - } else { - line(player, RED + "An onion", 9+ 7); - } - if (player.getInventory().contains(1957, 1)) { - line(player, "I have an onion with me", 9+ 7); - } else { - line(player, RED + "An onion", 9+ 7); - } - if (player.getInventory().contains(300, 1)) { - line(player, "I have a rat's tail with me", 10+ 7); - } else { - line(player, RED + "A rat's tail", 10+ 7); - } - if (player.getInventory().contains(2146, 1)) { - line(player, "I have a piece of burnt meat with me", 11+ 7); - } else { - line(player, RED + "A piece of burnt meat", 11+ 7); - } - if (player.getInventory().contains(221, 1)) { - line(player, "I have an eye of newt with me", 12+ 7); - } else { - line(player, RED + "An eye of newt", 12+ 7); - } - break; - case 40: - line(player, "I brought her an onion, a rat's tail, a piece of burnt meat", 4+ 7); - line(player, "and eye of newt which she used to make a potion.", 5+ 7); - line(player, BLUE + "I should drink from the " + RED + "cauldron" + BLUE + " and improve my magic!", 7+ 7); - break; - case 100: - line(player, "I brought her an onion, a rat's tail, a piece of burnt meat", 4+ 7); - line(player, "and an eye of newt which she used to make a potion.", 5+ 7); - line(player, "I drank from the cauldron and my magic power increased!", 7+ 7); - line(player, "QUEST COMPLETE!", 9+ 7); - break; - } - } - - @Override - public void finish(Player player) { - super.finish(player); - player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); - player.getPacketDispatch().sendString("325 Magic XP", 277, 9 + 2); - player.getSkills().addExperience(Skills.MAGIC, 325); - player.getInterfaceManager().closeChatbox(); - player.getPacketDispatch().sendItemZoomOnInterface(221, 240, 277, 3 + 2); - } - - @Override - public Quest newInstance(Object object) { - // TODO Auto-generated method stub - return this; - } -} diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.kt b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.kt new file mode 100644 index 000000000..0ada42b79 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.kt @@ -0,0 +1,86 @@ +package content.region.asgarnia.rimmington.quest.witchpotion + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.Items +import content.data.Quests + +/** + * Represents the Witch's Potion Quest + */ +@Initializable +class WitchsPotion : Quest(Quests.WITCHS_POTION, 31, 30, 1, 67, 0, 1, 3) { + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + player ?: return + var line = 11 + if (stage == 0) { + line(player, "I can start this quest by speaking to !!Hetty?? who in her house in", line++) + line(player, "!!Rimmington??, West of !!Port Sarim??.", line++) + } else if (stage in 1..39) { + line(player, "I spoke to !!Hetty?? in her house at Rimmington. Hetty told me", line++, true) + line(player, "she could increase my magic power if I can bring her", line++, true) + line(player, "certain ingredients for a potion.", line++, true) + line++ + line(player, "Hetty needs me to bring her the following:", line++) + + if(inInventory(player, Items.ONION_1957, 1)) + line(player, "I have an onion with me", line++, true) + else + line(player, "!!An onion??", line++) + + if(inInventory(player, Items.RATS_TAIL_300, 1)) + line(player, "I have a rat's tail with me", line++, true) + else + line(player, "!!A rat's tail??", line++) + + if(inInventory(player, Items.BURNT_MEAT_2146, 1)) + line(player, "I have a piece of burnt meat with me", line++, true) + else + line(player, "!!A piece of burnt meat??", line++) + + if(inInventory(player, Items.EYE_OF_NEWT_221, 1)) + line(player, "I have an eye of newt with me", line++, true) + else + line(player, "!!An eye of newt??", line++) + } else if (stage in 40..99) { + line(player, "I spoke to !!Hetty?? in her house at Rimmington. Hetty told me.", line++, true) + line(player, "she could increase my magic power if I can bring her", line++, true) + line(player, "certain ingredients for a potion.", line++, true) + line(player, "I brought her an onion, a rat's tail, a piece of burnt meat", line++, true) + line(player, "and an eye of newt which she used to make a potion.", line++, true) + line(player, "I should drink from the !!cauldron?? and improve my magic!", line++) + } else if (stage == 100) { + line(player, "I have spoken to !!Hetty??.", line++, true) + line(player, "I spoke to !!Hetty?? in her house at Rimmington. Hetty told me.", line++, true) + line(player, "she could increase my magic power if I can bring her", line++, true) + line(player, "certain ingredients for a potion.", line++, true) + line(player, "I brought her an onion, a rat's tail, a piece of burnt meat", line++, true) + line(player, "and an eye of newt which she used to make a potion.", line++, true) + line(player, "I drank from the cauldron and my magic power increased!", line++, true) + line++ + line(player, "%%QUEST COMPLETE!&&", line++) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var line = 10 + + sendItemZoomOnInterface(player, Components.QUEST_COMPLETE_SCROLL_277, 5, Items.EYE_OF_NEWT_221) + drawReward(player, "1 Quest Point", line++) + drawReward(player, "325 Magic XP", line++) + + rewardXP(player, Skills.MAGIC, 325.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionListeners.kt b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionListeners.kt new file mode 100644 index 000000000..0d00cee47 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionListeners.kt @@ -0,0 +1,26 @@ +package content.region.asgarnia.rimmington.quest.witchpotion + +import content.data.Quests +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Scenery + +/** + * Interaction Listener for Witch's Potion Quest. + */ +class WitchsPotionListener : InteractionListener { + + override fun defineListeners() { + + on(Scenery.CAULDRON_2024, IntType.SCENERY, "drink from") { player, node -> + if (getQuestStage(player, Quests.WITCHS_POTION) == 40) { + sendDialogue(player, "You drink from the cauldron, it tastes horrible! You feel yourself imbued with power.") + finishQuest(player, Quests.WITCHS_POTION) + } else { + sendDialogue(player, "As nice as that looks I think I'll give it a miss for now.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionPlugin.java b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionPlugin.java deleted file mode 100644 index 745f0837c..000000000 --- a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionPlugin.java +++ /dev/null @@ -1,41 +0,0 @@ -package content.region.asgarnia.rimmington.quest.witchpotion; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.quest.Quest; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the witchs potion plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class WitchsPotionPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(2024).getHandlers().put("option:drink from", this); - SceneryDefinition.forId(2024).getHandlers().put("option:Drink From", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Witch's Potion"); - switch (quest.getStage(player)) { - case 20: - case 100: - player.getDialogueInterpreter().sendDialogues(player, null, "As nice as that looks I think I'll give it a miss for now."); - break; - case 40: - player.getDialogueInterpreter().open(307, true, 1); - break; - } - return true; - } - -} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java index e5ab79fd7..487939a33 100644 --- a/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java @@ -7,6 +7,7 @@ import core.plugin.Initializable; import core.game.node.entity.skill.Skills; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the kaqemeex dialogue plugin. @@ -55,17 +56,17 @@ public final class KaqemeexDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - if (player.getQuestRepository().isComplete("Druidic Ritual")) { + if (player.getQuestRepository().isComplete(Quests.DRUIDIC_RITUAL)) { interpreter.sendDialogues(npc, null, "Hello again. How is the Herblore going?"); stage = 600; break; } - if (player.getQuestRepository().getQuest("Druidic Ritual").getStage(player) == 10) { + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 10) { interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Hello again."); stage = 40; break; } - if (player.getQuestRepository().getQuest("Druidic Ritual").getStage(player) == 99) { + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 99) { interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "I have word from Sanfew that you have been very", "helpful in assisting him with his preparations for the", "purification ritual. As promised I will now teach you the", "ancient arts of Herblore."); stage = 200; break; @@ -74,7 +75,7 @@ public final class KaqemeexDialogue extends DialoguePlugin { stage = 1; break; case 1: - if (player.getQuestRepository().getQuest("Druidic Ritual").isStarted(player)) { + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).isStarted(player)) { if (Skillcape.isMaster(player, Skills.HERBLORE)) { interpreter.sendOptions("Select an Option", "Can I buy a Skillcape of Herblore?", "Who are you?", "Did you build this?"); stage = 800; @@ -164,7 +165,7 @@ public final class KaqemeexDialogue extends DialoguePlugin { stage = 13; break; case 26: - player.getQuestRepository().getQuest("Druidic Ritual").start(player); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).start(player); interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Excellent. Go to the village south of this place and speak", "to my fellow Sanfew who is working on the purification", "ritual. He knows better than I what is required to", "complete it."); stage = 27; break; @@ -184,7 +185,7 @@ public final class KaqemeexDialogue extends DialoguePlugin { break; case 200: end(); - player.getQuestRepository().getQuest("Druidic Ritual").finish(player); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).finish(player); break; case 500: switch (buttonId) { diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java index 3162dbdf1..399daecc7 100644 --- a/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java @@ -11,6 +11,7 @@ import core.plugin.Initializable; import core.game.node.item.Item; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Handles the PikkupstixDialogue dialogue. @@ -85,7 +86,7 @@ public final class PikkupstixDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Wolf Whistle"); + quest = player.getQuestRepository().getQuest(Quests.WOLF_WHISTLE); switch (quest.getStage(player)) { case 0: npc("You there! What are you doing here, as if I didn't have", "enough troubles?"); @@ -147,7 +148,11 @@ public final class PikkupstixDialogue extends DialoguePlugin { } break; case 100: - npc("Welcome to my humble abode. How can I help", "you?"); + if (player.getSkills().getStaticLevel(Skills.SUMMONING) == 99) { + npc(FacialExpression.AMAZED, "Why, I've never seen such raw Summoning power", "before! If anyone has the right to own a Skillcape of", "Summoning, then it is you!"); + } else { + npc("Welcome to my humble abode. How can I help", "you?"); + } break; } return true; @@ -630,7 +635,7 @@ public final class PikkupstixDialogue extends DialoguePlugin { switch (stage) { case 0: if (player.getSkills().getStaticLevel(Skills.SUMMONING) == 99) { - options("So, what's Summoning all about, then?", "Can I buy some Summoning supplies?", "Can I buy a Summoning skillcape?"); + options("Yes, please sell me a Skillcape of Summoning.", "So, what's Summoning all about then?", "Can I buy some Summoning supplies?", "Please tell me about skillcapes."); stage = 600; } else { options("So, what's Summoning all about, then?", "Can I buy some Summoning supplies?", "Please tell me about skillcapes."); @@ -755,35 +760,40 @@ public final class PikkupstixDialogue extends DialoguePlugin { case 600: switch (buttonId) { case 1: + player(FacialExpression.ASKING, "May I buy a Skillcape of Summoning, please?"); + stage = 599; + break; + case 2: player("So, what's summoning all about, then?"); stage = 10; break; - case 2: + case 3: player("Can I buy some summoning supplies, please?"); stage = 34; break; - case 3: - player("Can I buy a Skillcape of Summoning?"); - stage = 599; + case 4: + player("Please tell me about skillcapes."); + stage = 400; break; } break; case 599: - npc("Why yes you can! I must warn you that they cost", "a total of 99000 coins. Do you wish to still", "buy a skillcape of Summoning?"); + npc(FacialExpression.NEUTRAL, "That is a pretty tall order, even for someone with your", "skills, " + player.getUsername() + ". You'll have to pay a fee of 99000 coins", "to get the cape."); stage = 601; break; case 601: - options("Yes.", "No."); + options("99000 coins? I think not!", "I'll take one!"); stage = 602; break; case 602: switch (buttonId) { case 1: - player("Yes, please."); - stage = 603; + player(FacialExpression.AMAZED, "99000 coins? I think not!"); + stage = 605; break; case 2: - end(); + player(FacialExpression.HAPPY, "I'll take one!"); + stage = 603; break; } break; @@ -803,13 +813,17 @@ public final class PikkupstixDialogue extends DialoguePlugin { return true; } if (player.getInventory().add(ITEMS[player.getSkills().getMasteredSkills() > 1 ? 1 : 0], ITEMS[2])) { - player("There you go, enjoy!"); + npc(FacialExpression.HAPPY, "Excellent! Wear that cape with pride my friend."); stage = 604; } break; case 604: end(); break; + case 605: + npc(FacialExpression.NEUTRAL, "Well, keep that in mind the next time you ask. These", "things are not cheap to make you know!"); + stage = 604; + break; } break; } diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java index acf1f9f8b..0c5d09444 100644 --- a/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Handles the SanfewDialogue dialogue. @@ -40,12 +41,12 @@ public class SanfewDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - if (player.getQuestRepository().getQuest("Druidic Ritual").getStage(player) == 20) { + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 20) { interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Did you bring me the required ingredients for the", "potion?"); stage = 100; break; } - if (player.getQuestRepository().getQuest("Druidic Ritual").getStage(player) == 10) { + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 10) { interpreter.sendOptions("Select an Option", "I've been sent to help purify the Varrock stone circle.", "Actually, I don't need to speak to you."); stage = 2; break; @@ -89,7 +90,7 @@ public class SanfewDialogue extends DialoguePlugin { break; case 8: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is located somewhere in the mysterious underground", "halls which are located somewhere in the woods just", "South of here. They are too dangerous for me to go", "myself however."); - player.getQuestRepository().getQuest("Druidic Ritual").setStage(player, 20); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).setStage(player, 20); stage = 9; break; case 9: @@ -129,7 +130,7 @@ public class SanfewDialogue extends DialoguePlugin { break; case 202: player.getInventory().remove(new Item(522, 1), new Item(523, 1), new Item(524, 1), new Item(525, 1)); - player.getQuestRepository().getQuest("Druidic Ritual").setStage(player, 99); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).setStage(player, 99); player.getQuestRepository().syncronizeTab(player); interpreter.sendDialogues(npc, null, "Now go and talk to Kaqemeex and he will introduce", "you to the wonderful world of herblore and potion", "making!"); stage = 203; diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt b/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt index b53370950..90063d64c 100644 --- a/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt @@ -21,7 +21,6 @@ class VelrakDialogue(player: Player? = null) : DialoguePlugin(player) { playerl(FacialExpression.HALF_THINKING, "Are you still here?").also { stage = 100 } } else { npcl(FacialExpression.FRIENDLY, "Thank you for rescuing me! It isn't very comfy in this cell.") - removeItem(player, Items.JAIL_KEY_1591, Container.INVENTORY) } return true } @@ -42,7 +41,7 @@ class VelrakDialogue(player: Player? = null) : DialoguePlugin(player) { 2 -> playerl(FacialExpression.NEUTRAL, "No, it's too dangerous for me too.").also { stage = 15 } } - 14 -> sendItemDialogue(player, Items.DUSTY_KEY_1590, "Velrak reaches somewhere mysterious and passes you a key.").also { addItem(player, Items.DUSTY_KEY_1590, 1); stage = END_DIALOGUE } + 14 -> sendItemDialogue(player, Items.DUSTY_KEY_1590, "Velrak reaches somewhere mysterious and passes you a key.").also { addItemOrDrop(player, Items.DUSTY_KEY_1590, 1); stage = END_DIALOGUE } 15 -> npcl(FacialExpression.FRIENDLY, "I don't blame you!").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.java b/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.java deleted file mode 100644 index 83afb86c1..000000000 --- a/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.java +++ /dev/null @@ -1,83 +0,0 @@ -package content.region.asgarnia.taverley.quest; - -import core.game.component.CloseEvent; -import core.game.component.Component; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.game.node.entity.player.link.quest.Quest; - -/** - * The main type for the druidic ritual quest. - * @author Vexia - * - */ -@Initializable -public class DruidicRitual extends Quest { - - /** - * Constructs a new {@code DruidicRitual} {@code Object}. - */ - public DruidicRitual() { - super("Druidic Ritual", 48, 47, 4, 80, 0, 3, 4); - } - - @Override - public void drawJournal(Player player, int stage) { - super.drawJournal(player, stage); - player.getPacketDispatch().sendString("I can start this quest by speaking to the Kaqemeex who is at", 275, 4+ 7); - player.getPacketDispatch().sendString("the Druids Circle just North of Taverley.", 275, 5+ 7); - if (stage == 10) { - player.getPacketDispatch().sendString("I told Kaqemeex I would help them prepare their ceremony.", 275, 4+ 7); - player.getPacketDispatch().sendString("I should speak to Sanfew in the village to the South", 275, 5+ 7); - } - if (stage == 20) { - player.getPacketDispatch().sendString("", 275, 5+ 7); - player.getPacketDispatch().sendString("I told Kaqemeex I would help them prepare their ceremony.", 275, 4+ 7); - player.getPacketDispatch().sendString("Sanfew told me for the ritual they would need me to place", 275, 6+ 7); - player.getPacketDispatch().sendString("raw bear meat, raw chicken, raw rat meat, and raw beef in", 275, 7+ 7); - player.getPacketDispatch().sendString("the Cauldron of Thunder in the dungeon South of Taverley", 275, 8+ 7); - } - if (stage == 99) { - player.getPacketDispatch().sendString("I told Kaqemeex I would help them prepare their ceremony.", 275, 4+ 7); - player.getPacketDispatch().sendString("The ceremony required various meats being placed in the.", 275, 5+ 7); - player.getPacketDispatch().sendString("Cauldron of Thunder. I did this and gave them to Sanfew.", 275, 6+ 7); - player.getPacketDispatch().sendString("I should speak to Kaqemeex again and claim my reward", 275, 7+ 7); - } - if (stage == 100) { - player.getPacketDispatch().sendString("I told Kaqemeex I would help them prepare their ceremony.", 275, 4+ 7); - player.getPacketDispatch().sendString("The ceremony required various meats being placed in the.", 275, 5+ 7); - player.getPacketDispatch().sendString("Cauldron of Thunder. I did this and gave them to Sanfew.", 275, 6+ 7); - player.getPacketDispatch().sendString("Kaqemeex then taught me the basics of the skill Herblore", 275, 7+ 7); - player.getPacketDispatch().sendString("QUEST COMPLETE!", 275, 11+ 7); - } - } - - @Override - public void finish(Player player) { - super.finish(player); - player.getInterfaceManager().open(new Component(277).setCloseEvent(new CloseEvent() { - @Override - public boolean close(Player player, Component c) { - if (player != null) { - player.getDialogueInterpreter().open(455, NPC.create(455, player.getLocation()), true); - } - return true; - } - })); - player.getPacketDispatch().sendString("You have completed the Druidic Ritual Quest!", 277, 4); - player.getPacketDispatch().sendItemZoomOnInterface(249, 240, 277, 3 + 2); - player.getPacketDispatch().sendString("4 Quest Points", 277, 8 + 2); - player.getPacketDispatch().sendString("250 Herblore XP", 277, 9 + 2); - player.getPacketDispatch().sendString("Access to Herblore skill", 277, 10 + 2); - player.getSkills().addExperience(Skills.HERBLORE, 250); - player.getInterfaceManager().closeChatbox(); - } - - @Override - public Quest newInstance(Object object) { - // TODO Auto-generated method stub - return this; - } -} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.kt b/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.kt new file mode 100644 index 000000000..15440a4bd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.kt @@ -0,0 +1,93 @@ +package content.region.asgarnia.taverley.quest + +import core.api.* +import core.game.component.Component +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Druidic Ritual Quest + */ +@Initializable +class DruidicRitual : Quest(Quests.DRUIDIC_RITUAL, 48, 47, 4, 80, 0, 3, 4) { + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.DRUIDIC_RITUAL) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Kaqemeex?? who is at", line++) + line(player, "the !!Druids Circle?? just !!north?? of !!Taverly??.", line++) + } else { + line(player, "Kaqemeex and the druids are preparing a ceremony to", line++, true) + line(player, "purify the Varrock stone circle. I told Kaqemeex I would", line++, true) + line(player, "help them.", line++, true) + + if (stage >= 20) { + // Line disappears. + } else if (stage >= 10) { + line++ + line(player, "I should speak to !!Sanfew?? in the village to the !!south??.", line++) + } + + if (stage >= 99) { + line(player, "The ceremony required various meats being placed in the", line++, true) + line(player, "Cauldron of Thunder. I did this and gave them to Sanfew.", line++, true) + } else if (stage >= 20) { + line++ + line(player, "!!Sanfew?? told me for the ritual they would need me to place", line++) + line(player, "!!raw bear meat??, !!raw chicken??, !!raw rat meat??, and !!raw beef?? in", line++) + line(player, "the !!Cauldron of Thunder?? in the !!dungeon south?? of !!Taverley??.", line++) + } + + if (stage >= 100) { + line(player, "Kaqemeex then taught me the basics of the Heblore skill.", line++, true) + } else if (stage >= 99) { + line++ + line(player, "I should speak to !!Kaqemeex?? again and claim my !!reward??.", line++) + } + + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line++) + line(player, "I gained !!4 quest points??, !!250 Heblore XP?? and access to", line++) + line(player, "the !!Heblore skill??.", line) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Druidic Ritual Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.CLEAN_GUAM_249, 230, 277, 5) + + drawReward(player,"4 Quest Points", ln++) + drawReward(player,"250 Herblore XP", ln++) + drawReward(player,"Access to Herblore skill", ln++) + + rewardXP(player, Skills.HERBLORE, 250.0) + + player.interfaceManager.closeChatbox() + } + + override fun questCloseEvent(player: Player?, component: Component?) { + queueScript(player!!, 1, QueueStrength.SOFT) { + openDialogue(player,455, NPC.create(455, player.location), true) + return@queueScript stopExecuting(player) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java b/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java index a9aeecf48..29160561d 100644 --- a/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java +++ b/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java @@ -5,8 +5,10 @@ import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; +import org.rs09.consts.Items; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** @@ -21,42 +23,137 @@ public class WolfWhistle extends Quest { */ public static final Item WOLF_BONES = new Item(2859, 2); + /** + * Gates the visibility of the Summoning orb next to the minimap behind quest completion. + */ + private static final int VARBIT_SUMMONING_ORB_VISIBILITY = 4280; + /** * Constructs a new {@code WolfWhistle} {@code Object}. */ public WolfWhistle() { - super("Wolf Whistle", 146, 145, 1); + super(Quests.WOLF_WHISTLE, 146, 145, 1); } @Override public void drawJournal(Player player, int stage) { super.drawJournal(player, stage); - switch (stage) { - case 0: - line(player, BLUE + "I can begin this quest by talking to " + RED + "Pikkupstix" + BLUE + ", who lives in", 4+ 7); - line(player, RED + "Taverley.", 5+ 7); - break; - case 10: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.", 4+ 7); - break; - case 20: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.



It appears that I have underestimated the rabbit in this

case; it is some huge rabbit-wolf-monster-bird-thing. I

think I should speak to Pikkupstix to find out what is going

on.", 4+ 7); - break; - case 30: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.

It appears that I have underestimated the rabbit in this

case; it is some huge rabbit-wolf-monster-bird-thing. I

think I should speak to Pikkupstix to find out what is going

on.



I have spoken to Pikkupstix, who has promised to teach me

the secrets of Summoning if I can help dismiss the giant

wolpertinger. To do this, I need to bring him 2 lots of wolf

bones.

" + (player.getInventory().containsItem(WOLF_BONES) ? "" : "") + "I need to get 2 lots of wolf bones.", 4+ 7); - break; - case 40: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.

It appears that I have underestimated the rabbit in this

case; it is some huge rabbit-wolf-monster-bird-thing. I

think I should speak to Pikkupstix to find out what is going

on.



I have spoken to Pikkupstix, who has promised to teach me

the secrets of Summoning if I can help dismiss the giant

wolpertinger. To do this, I need to bring him 2 lots of wolf

bones.

I have given Pikkupstix all of the items he requested.



Pikkupstix has given me some gold charms, spirit shards

and pouches, with which to make a spirit wolf pouch and

some Howl scrolls. I will then be able to use them to dismiss

the giant wolpertinger.

I need to open the trapdoor with the trapdoor key that I

have been given. ", 4+ 7); - break; - case 50: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.

It appears that I have underestimated the rabbit in this

case; it is some huge rabbit-wolf-monster-bird-thing. I

think I should speak to Pikkupstix to find out what is going

on.



I have spoken to Pikkupstix, who has promised to teach me

the secrets of Summoning if I can help dismiss the giant

wolpertinger. To do this, I need to bring him 2 lots of wolf

bones.



Pikkupstix has given me some gold charms, spirit shards

and pouches, with which to make a spirit wolf pouch and

some Howl scrolls. I will then be able to use them to dismiss

the giant wolpertinger.

I have infused the 2 spirit wolf pouches, but I need to

transform one of them into scrolls at the obelisk.", 4+ 7); - break; - case 60: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.

It appears that I have underestimated the rabbit in this

case; it is some huge rabbit-wolf-monster-bird-thing. I

think I should speak to Pikkupstix to find out what is going

on.



I have spoken to Pikkupstix, who has promised to teach me

the secrets of Summoning if I can help dismiss the giant

wolpertinger. To do this, I need to bring him 2 lots of wolf

bones.



Pikkupstix has given me some gold charms, spirit shards

and pouches, with which to make a spirit wolf pouch and

some Howl scrolls. I will then be able to use them to dismiss

the giant wolpertinger.

I have infused the 2 spirit wolf pouches, but I need to

transform one of them into scrolls at the obelisk.

I have dismissed the giant wolpertinger.", 4+ 7); - break; - case 100: - line(player, "Having spoken to Pikkupstix, it seems that all I have to do

is get rid of the little rabbit upstairs in his house.

It appears that I have underestimated the rabbit in this

case; it is some huge rabbit-wolf-monster-bird-thing. I

think I should speak to Pikkupstix to find out what is going

on.



I have spoken to Pikkupstix, who has promised to teach me

the secrets of Summoning if I can help dismiss the giant

wolpertinger. To do this, I need to bring him 2 lots of wolf

bones.



Pikkupstix has given me some gold charms, spirit shards

and pouches, with which to make a spirit wolf pouch and

some Howl scrolls. I will then be able to use them to dismiss

the giant wolpertinger.

I have infused the 2 spirit wolf pouches, but I need to

transform one of them into scrolls at the obelisk.

I have dismissed the giant wolpertinger.



QUEST COMPLETE!", 4+ 7); - break; + var line = 12; + + if(stage == 0){ + line(player, "I can begin this quest by talking to !!Pikkupstix??, who lives in", line++, false); + line(player, "!!Taverly??.", line++, false); + limitScrolling(player, line, true); + } else { + if (stage >= 10) { + line(player, "Having spoken to !!Pikkupstix??, it seems that all I have to do", line++, stage >= 20); + line(player, "is get rid of the !!little rabbit upstairs in his house??.", line++, stage >= 20); + line++; + } + if (stage >= 20) { + line(player, "It appears that I have underestimated the rabbit in this", line++, stage >= 30); + line(player, "case; it is some !!huge rabbit-wolf-monster-bird-thing??. I", line++, stage >= 30); + line(player, "think I should speak to !!Pikkupstix?? to find out what is going", line++, stage >= 30); + line(player, "on.", line++, stage >= 30); + line++; + } + // Clicking on the ladder - sendMessage("There is no reason to go up there and face that thing again.") + if (stage >= 30) { + line(player, "I have spoken to !!Pikkupstix??, who has promised to teach me ", line++, stage >= 40); + line(player, "the secrets of !!Summoning?? if I can help dismiss the !!giant??", line++, stage >= 40); + line(player, "!!wolpertinger??. To do this, I need to bring him !!2 lots of wolf??", line++, stage >= 40); + line(player, "!!bones??.", line++, stage >= 40); + + if (stage == 30) { + line(player, "!!I need to get 2 lots of wolf bones.??", line++, inInventory(player, Items.WOLF_BONES_2859, 2)); + } else { + line(player, "I have given Pikkupstix all of the items he requested.", line++, true); + line++; + } + } + if (stage >= 40) { + line(player, "Pikkupstix has given me some !!gold charms??, !!spirit shards??", line++, stage >= 50); + line(player, "and !!pouches??, with which to make a !!spirit wolf pouch?? and", line++, stage >= 50); + line(player, "some !!Howl scrolls??. I will then be able to use them to dismiss", line++, stage >= 50); + line(player, "the !!giant wolpertinger??.", line++, stage >= 50); + } + if (stage == 40 && inInventory(player, Items.TRAPDOOR_KEY_12528, 1)) { + line(player, "I need to open the !!trapdoor?? with the !!trapdoor key?? that I", line++, false); + line(player, "have been given.", line++, false); + } else if (stage >= 50 || player.getAttribute("has-key", false)) { + line(player, "I have unlocked the trapdoor.", line++, true); + } + + // This part is a shitshow. + if (stage >= 50 || (stage >= 40 && (inInventory(player, Items.SPIRIT_WOLF_POUCH_12047, 1) || inInventory(player, Items.HOWL_SCROLL_12425, 1)))) { + line(player, "I need to go into Pikkupstix's !!cellar?? and !!infuse a pouch?? at", line++, stage >= 50); + line(player, "the obelisk, using the items I have been given.", line++, stage >= 50); + line++; + line(player, "I have infused the spirit wolf pouch and made some Howl", line++, stage >= 50); + line(player, "scrolls. I should speak with !!Pikkupstix?? about how to use", line++, stage >= 50); + line(player, "them.", line++, stage >= 50); + line++; + } else if (stage >= 40 && inInventory(player, Items.SPIRIT_WOLF_POUCH_12047, 2)) { + line(player, "I have infused the 2 spirit wolf pouches, but I need to", line++, false); + line(player, "transform one of them into scrolls at the obelisk.", line++, false); + } else if (stage >= 40 && player.getAttribute("has-key", false)) { + line(player, "I need to go into Pikkupstix's !!cellar?? and !!infuse a pouch?? at", line++); + line(player, "the obelisk, using the items I have been given.", line++); + line(player, "!!I need to bring 2 lots of wolf bones.??", line++, inInventory(player, Items.WOLF_BONES_2859, 2)); + line(player, "!!I need to bring the pouches.??", line++, inInventory(player, Items.POUCH_12155, 2)); + line(player, "!!I need to bring the gold charms.??", line++, inInventory(player, Items.GOLD_CHARM_12158, 2)); + line(player, "!!I need to bring the spirit shards.??", line++, inInventory(player, Items.SPIRIT_SHARDS_12183, 14)); + } + + if (stage >= 50) { + line(player, "I have been told how to use the spirit wolf pouch and Howl", line++, stage >= 60); + line(player, "scrolls. I should go back upstairs and confront the !!giant??", line++, stage >= 60); + line(player, "!!wolpertinger??.", line++, stage >= 60); + line++; + } + if (stage == 50) { // Does not stay. + if (inInventory(player, Items.SPIRIT_WOLF_POUCH_12047, 1)) { + line(player, "I have the spirit wolf pouch on me.", line++, false); + } else { + line(player, "!!I have lost the spirit wolf pouch.??", line++, false); + } + if (inInventory(player, Items.HOWL_SCROLL_12425, 1)) { + line(player, "I have the Howl scroll on me.", line++, false); + } else { + line(player, "!!I have lost the Howl scroll.??", line++, false); + } + } + + if (stage >= 60) { + // Technically, there should be an extra stage speaking to Pikkupstix here, but it is not available. + line(player, "I have banished the giant !!wolpertinger??. I should speak with", line++, true); + line(player, "!!Pikkupstix?? to get my reward.", line++, true); + line++; + if (player.getSkills().getLevel(Skills.SUMMONING) >= player.getSkills().getStaticLevel(Skills.SUMMONING) || stage >= 100) { + line(player, "I am feeling drained of Summoning skill points and need to", line++, true); + line(player, "recharge at the !!obelisk??.", line++, true); + line++; + line(player, "I have banished the giant !!wolpertinger?? and refreshed my", line++, stage >= 100); + line(player, "Summoning skill points. I should speak with !!Pikkupstix?? to", line++, stage >= 100); + line(player, "get my reward.", line++, stage >= 100); + line++; + } else { + line(player, "I am feeling drained of Summoning skill points and need to", line++); + line(player, "recharge at the !!obelisk??.", line++); + line++; + } + } + + if (stage >= 100) { + line(player, "I have been given access to the secrets of Summoning.", line++, true); + line(player,"QUEST COMPLETE!", line++); + line(player, "!!Reward:??", line++); + line(player, "1 Quest Point,", line++); + line(player, "access to the Summoning skill", line++); + line(player, "275 gold charms", line++); + line(player, "and 276 Summoning XP", line++); + } + limitScrolling(player, line, false); } } @@ -72,6 +169,7 @@ public class WolfWhistle extends Quest { player.getSkills().addExperience(Skills.SUMMONING, 276); player.getInventory().add(new Item(12158, 275), player); player.removeAttribute("searched-body"); + setVarbit(player, VARBIT_SUMMONING_ORB_VISIBILITY, 1); player.getQuestRepository().syncronizeTab(player); player.getInterfaceManager().openInfoBars(); } diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java index 3a92d309f..2574498c4 100644 --- a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java @@ -6,6 +6,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; +import content.data.Quests; /** * Created for 2009Scape @@ -32,10 +33,10 @@ public class BoyDialoguePlugin extends DialoguePlugin { @Override public boolean open(Object... args) { - final Quest quest = player.getQuestRepository().getQuest("Witch's House"); + final Quest quest = player.getQuestRepository().getQuest(Quests.WITCHS_HOUSE); player.debug(quest.isStarted(player) + " " + quest.getStage(player) ); if (!quest.isStarted(player) && quest.getStage(player) < 10) { - player("Hello young man."); + player(FacialExpression.FRIENDLY, "Hello young man."); setStage(1); return true; } @@ -45,9 +46,9 @@ public class BoyDialoguePlugin extends DialoguePlugin { return true; } if (!player.getInventory().containsItem(BALL)) { - npc( FacialExpression.OLD_NORMAL, "Have you gotten my ball back yet?"); + npc( FacialExpression.CHILD_THINKING, "Have you gotten my ball back yet?"); } else { - player("Hi, I have got your ball back. It was MUCH harder", "than I thought it would be."); + player(FacialExpression.NEUTRAL, "Hi, I have got your ball back. It was MUCH harder", "than I thought it would be."); } setStage(11); return true; @@ -55,7 +56,7 @@ public class BoyDialoguePlugin extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Witch's House"); + final Quest quest = player.getQuestRepository().getQuest(Quests.WITCHS_HOUSE); switch(stage) { case -1: end(); @@ -71,11 +72,11 @@ public class BoyDialoguePlugin extends DialoguePlugin { case 3: switch(buttonId) { case 1: - player("What's the matter?"); + player(FacialExpression.THINKING, "What's the matter?"); setStage(5); break; case 2: - player("Well if you're not going to answer then I'll go."); + player(FacialExpression.NEUTRAL, "Well if you're not going to answer then I'll go."); next(); break; } @@ -85,7 +86,7 @@ public class BoyDialoguePlugin extends DialoguePlugin { finish(); break; case 5: - npc(FacialExpression.OLD_NORMAL, "I've kicked my ball over that hedge, into that garden!", "The old lady who lives there is scary... She's locked the","ball in her wooden shed! Can you get my ball back for", "me please?"); + npc(FacialExpression.CHILD_SAD, "I've kicked my ball over that hedge, into that garden!", "The old lady who lives there is scary... She's locked the","ball in her wooden shed! Can you get my ball back for", "me please?"); next(); break; case 6: @@ -95,17 +96,17 @@ public class BoyDialoguePlugin extends DialoguePlugin { case 7: switch(buttonId) { case 1: - player("Ok, I'll see what I can do."); + player(FacialExpression.NEUTRAL, "Ok, I'll see what I can do."); setStage(10); break; case 2: - player("Get it back yourself."); + player(FacialExpression.NEUTRAL, "Get it back yourself."); next(); break; } break; case 8: - npc(FacialExpression.OLD_NORMAL, "You're a meany."); + npc(FacialExpression.CHILD_SAD, "You're a meany."); next(); break; case 9: @@ -113,13 +114,13 @@ public class BoyDialoguePlugin extends DialoguePlugin { finish(); break; case 10: - npc(FacialExpression.OLD_NORMAL, "Thanks mister!"); + npc(FacialExpression.CHILD_FRIENDLY, "Thanks mister!"); finish(); quest.start(player); break; case 11: if (!player.getInventory().containsItem(BALL)) { - player("Not yet."); + player(FacialExpression.NEUTRAL, "Not yet."); next(); } else { if (player.getInventory().remove(BALL)) @@ -128,11 +129,11 @@ public class BoyDialoguePlugin extends DialoguePlugin { } break; case 12: - npc(FacialExpression.OLD_NORMAL, "Well it's in the shed in that garden."); + npc(FacialExpression.CHILD_ANGRY, "Well it's in the shed in that garden."); finish(); break; case 13: - npc(FacialExpression.OLD_NORMAL, "Thank you so much!"); + npc(FacialExpression.CHILD_FRIENDLY, "Thank you so much!"); next(); break; case 14: diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt index 8417d0cca..0bf3fffce 100644 --- a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -129,8 +130,9 @@ class WitchesDiaryBook : InteractionListener { } override fun defineListeners() { - on(Items.DIARY_2408, IntType.ITEM, "read") { player, _ -> + on(Items.DIARY_2408, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java index 7d142974d..ab2b32e00 100644 --- a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java @@ -4,10 +4,12 @@ import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; +import content.data.Quests; /** * Created for 2009Scape * User: Ethan Kyle Millard + * https://www.youtube.com/watch?v=-RuHho3NbWg * Date: March 15, 2020 * Time: 9:21 AM */ @@ -18,31 +20,30 @@ public class WitchsHouse extends Quest { * Constructs a new {@code WitchsHouse} {@code Object}. */ public WitchsHouse() { - super("Witch's House", 124, 123, 4, 226, 0, 1, 7); + super(Quests.WITCHS_HOUSE, 124, 123, 4, 226, 0, 1, 7); } @Override public void drawJournal(Player player, int stage) { super.drawJournal(player, stage); - switch (getStage(player)) { - case 0: - line(player, "I can start this quest by speaking to the little boy", 4+ 7); - line(player, "standing by the long garden just north of Taverley", 5+ 7); - line(player, "I must be able to defeat a level 53 enemy.", 6+ 7); - break; - case 10: - line(player, "A small boy has kicked his ball over the fence into the", 4+ 7); - line(player, "nearby garden, and I have agreed to retrieve it for him.", 5+ 7); - line(player, "I should find a way into the garden where the ball is.", 6+ 7); - break; - case 100: - line(player, "A small boy has kicked his ball over the fence into the", 4+ 7); - line(player, "nearby garden, and I have agreed to retrieve it for him.", 5+ 7); - line(player, "After puzzling through the strangely elaborate security", 6+ 7); - line(player, "system, and defeating a very strange monster, I returned", 7+ 7); - line(player, "the child's ball to him, and he thanked me for my help.", 8+ 7); - line(player, "QUEST COMPLETE!", 10+ 7); - break; + var line = 12; + if(stage == 0){ + line(player, "I can start this quest by speaking to the !!little boy??", line++); + line(player, "standing by the long garden just !!north of Taverly??.", line++); + line(player, "I must be able to defeat a !!level 53 enemy??.", line++); + } else { + line(player, "A small boy kicked his ball over the fence into the nearby", line++, true); + line(player, "garden, and I have agreed to retrieve it for him.", line++, true); + if (stage == 10) { + line(player, "I should find a way into the !!garden?? where the !!ball?? is.", line++); + } + if (stage >= 100) { + line(player, "After puzzling through the strangely elaborate security", line++, true); + line(player, "system, and defeating a very strange monster, I returned", line++, true); + line(player, "the child's ball to him, and he thanked me for my help.", line++, true); + line++; + line(player,"QUEST COMPLETE!", line); + } } } diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java index 3600be5c6..5e8ccb1d9 100644 --- a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java @@ -18,6 +18,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import core.plugin.ClassScanner; import core.tools.RandomFunction; +import content.data.Quests; /** * Created for 2009Scape @@ -39,7 +40,7 @@ public class WitchsHousePlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Witch's House"); + final Quest quest = player.getQuestRepository().getQuest(Quests.WITCHS_HOUSE); final int id = node instanceof Item ? ((Item) node).getId() : node instanceof Scenery ? ((Scenery) node).getId() : node instanceof NPC ? ((NPC) node).getId() : node.getId(); // boolean killedExperiment = player.getAttribute("witchs_house:experiment_killed",false); // boolean experimentAlive = !player.getAttribute("witchs_house:experiment_killed", false); diff --git a/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt b/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt index f904fe12e..9eb7daf39 100644 --- a/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt +++ b/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt @@ -1,6 +1,6 @@ package content.region.asgarnia.trollheim.dialogue -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau +import content.data.Quests import content.region.asgarnia.burthorpe.quest.deathplateau.SabaDialogueFile import core.api.getQuestStage import core.api.openDialogue @@ -20,7 +20,7 @@ import org.rs09.consts.NPCs @Initializable class SabaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { - if (getQuestStage(player!!, DeathPlateau.questName) >= 19) { + if (getQuestStage(player!!, Quests.DEATH_PLATEAU) >= 19) { openDialogue(player!!, SabaDialogueFile(), npc) return true } diff --git a/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt b/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt index a657189c2..2101a9b77 100644 --- a/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt +++ b/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt @@ -1,6 +1,6 @@ package content.region.asgarnia.trollheim.dialogue -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau +import content.data.Quests import content.region.asgarnia.burthorpe.quest.deathplateau.TenzingDialogueFile import core.api.* import core.game.dialogue.DialoguePlugin @@ -21,7 +21,7 @@ import org.rs09.consts.NPCs @Initializable class TenzingDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { - if (isQuestInProgress(player!!, DeathPlateau.questName, 20, 29)) { + if (isQuestInProgress(player!!, Quests.DEATH_PLATEAU, 20, 29)) { openDialogue(player!!, TenzingDialogueFile(), npc) return true } diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java index b62009775..d6a2c1fc6 100644 --- a/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java @@ -202,7 +202,7 @@ public final class TrollheimPlugin extends OptionHandler { switch (id) { case 32738: if (loc.equals(new Location(2892, 10072, 0))) { - player.getProperties().setTeleportLocation(LOCATIONS[0]); + player.getProperties().setTeleportLocation(LOCATIONS[9]); return true; } player.teleport(LOCATIONS[1]); diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java index d90bd3f35..2e18d36e2 100644 --- a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java @@ -6,14 +6,14 @@ import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.combat.CombatSwingHandler; import core.game.node.entity.combat.InteractionType; import core.game.node.entity.combat.equipment.ArmourSet; -import core.game.node.entity.impl.Projectile; import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; import core.game.node.entity.player.Player; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.tools.RandomFunction; -import static core.api.ContentAPIKt.*; +import static core.api.ContentAPIKt.applyPoison; /** * Handles K'ril Tsutsaroth's combat. @@ -62,21 +62,23 @@ public final class GWDTsutsarothSwingHandler extends CombatSwingHandler { if (RandomFunction.randomize(10) < 4) { ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); style = CombatStyle.MAGIC; - } else if (RandomFunction.randomize(10) == 0) { - if (special = (victim instanceof Player)) { - ((Player) victim).getPacketDispatch().sendMessage("K'ril Tsutsaroth slams through your protection prayer, leaving you feeling drained."); - } + } else if (victim instanceof Player && RandomFunction.randomize(10) == 0) { + Player player = (Player) victim; + special = player.hasProtectionPrayer(CombatStyle.MELEE); + if (special) { + player.getPacketDispatch().sendMessage("K'ril Tsutsaroth slams through your protection prayer, leaving you feeling drained."); entity.sendChat("YARRRRRRR!"); + } } if (style.getSwingHandler().isAccurateImpact(entity, victim)) { int max = style.getSwingHandler().calculateHit(entity, victim, special ? 1.08 : 1.0); hit = RandomFunction.random(max); state.setMaximumHit(max); if (style == CombatStyle.MELEE) { - applyPoison(victim, entity, 16); + applyPoison(victim, entity, 80); } if (special) { - ((Player) victim).getSkills().decrementPrayerPoints((double) hit / 2); + victim.getSkills().decrementPrayerPoints((double) hit / 2); } } state.setEstimatedHit(hit); diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java index 4d62e0f41..ad04fa730 100644 --- a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java @@ -231,7 +231,7 @@ public final class GodwarsBossNPC extends AbstractNPC { public void finalizeDeath(Entity killer) { super.finalizeDeath(killer); if (getId() == 6222 || getId() == 6260 || getId() == 6247 || getId() == 6203) { - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); } if (minions == null) { return; diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java index c1be4295f..8803d9d88 100644 --- a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java @@ -18,6 +18,7 @@ import core.game.world.update.flag.context.Animation; import core.plugin.Plugin; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Handles the entrance hole to the godwars dungeon. @@ -67,7 +68,7 @@ public final class GodwarsEntranceHandler extends OptionHandler { }); return true; case 26338: - if (!hasRequirement(player, "Troll Stronghold")) + if (!hasRequirement(player, Quests.TROLL_STRONGHOLD)) return true; if (player.getSkills().getStaticLevel(Skills.STRENGTH) < 60) { player.getPacketDispatch().sendMessage("You need a Strength level of 60 to move this boulder."); diff --git a/Server/src/main/content/region/asgarnia/whitewolfmountain/WhiteWolfMountainListener.kt b/Server/src/main/content/region/asgarnia/whitewolfmountain/WhiteWolfMountainListener.kt new file mode 100644 index 000000000..4e84f83a4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/whitewolfmountain/WhiteWolfMountainListener.kt @@ -0,0 +1,64 @@ +package content.region.asgarnia.whitewolfmountain + +import content.data.skill.SkillingTool +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.skill.Skills +import org.rs09.consts.Scenery + +class WhiteWolfMountainListener : InteractionListener { + override fun defineListeners() { + + on(Scenery.ROCK_SLIDE_2634, SCENERY, "investigate") { player, node -> + // dtWpLjw4X0A + sendMessage(player, "These rocks contain nothing interesting.") + sendMessage(player, "They are just in the way.") + return@on true + } + + on(Scenery.ROCK_SLIDE_2634, SCENERY, "mine") { player, node -> + val pickaxe = SkillingTool.getPickaxe(player) + val rockScenery = node as core.game.node.scenery.Scenery + if (getDynLevel(player, Skills.MINING) < 50) { + sendMessage(player, "You need a mining level of 50 to mine this rock slide.") + return@on true + } + if (pickaxe == null) { + sendMessage(player, "You do not have a pickaxe to use.") + return@on true + } + animate(player, pickaxe.animation) + lock(player, 6) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + // Scenery.ROCKSLIDE_471 is the original rock. + 0 -> { + replaceScenery(rockScenery, Scenery.ROCKSLIDE_472, 2) + return@queueScript delayScript(player, 2) + } + + 1 -> { + replaceScenery(rockScenery, Scenery.ROCKSLIDE_473, 2) + return@queueScript delayScript(player, 2) + } + + 2 -> { + replaceScenery(rockScenery, 476, 2) + player.walkingQueue.reset() + if (player.location.x < 2839) { + player.walkingQueue.addPath(2840, 3517) + } else { + player.walkingQueue.addPath(2837, 3518) + } + return@queueScript delayScript(player, 2) + } + + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt index 50f351f37..a0bc89b30 100644 --- a/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt @@ -8,6 +8,7 @@ import core.plugin.Initializable import org.rs09.consts.NPCs import core.api.* +import content.data.Quests /** * Represents the ali morrisane dialogue. @@ -36,7 +37,7 @@ class AliMorrisaneDialogue(player: Player? = null) : DialoguePlugin(player) { 1 -> playerl(FacialExpression.ASKING, "If you are, then why are you still selling goods from a stall?").also { stage = 10 } 2 -> { end() - if (!hasRequirement(player, "The Feud")) + if (!hasRequirement(player, Quests.THE_FEUD)) return true npc.openShop(player) } @@ -59,7 +60,7 @@ class AliMorrisaneDialogue(player: Player? = null) : DialoguePlugin(player) { } 2 -> { end() - if (!hasRequirement(player, "The Feud")) + if (!hasRequirement(player, Quests.THE_FEUD)) return true npc.openShop(player) } diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java index c31f6d468..4331b9370 100644 --- a/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java +++ b/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java @@ -9,6 +9,7 @@ import core.game.node.scenery.Scenery; import core.game.world.map.Location; import core.plugin.Initializable; import core.game.world.map.RegionManager; +import content.data.Quests; /** * Represents the border guard dialogue plugin. @@ -80,7 +81,7 @@ public final class BorderGuardDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - if (player.getQuestRepository().getQuest("Prince Ali Rescue").getStage(player) > 50) { + if (player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE).getStage(player) > 50) { npc("You may pass for free, you are a friend of Al-Kharid."); stage = 100; } else { diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/EllisDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/EllisDialogue.kt new file mode 100644 index 000000000..6dc4a3418 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/EllisDialogue.kt @@ -0,0 +1,75 @@ +package content.region.desert.alkharid.dialogue + +import content.global.skill.crafting.TanningProduct +import core.api.inInventory +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles Ellis's dialogue. + */ +@Initializable +class EllisDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY, "Greetings friend. I am a manufacturer of leather.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + var hasHides = false + + for (tanningProduct in TanningProduct.values()) { + if (inInventory(player, tanningProduct.item)) { + hasHides = true + break + } + } + + if(hasHides) { + npcl(FacialExpression.FRIENDLY, "I see you have brought me some hides. Would you like me to tan them for you?").also { stage = 10 } + } else { + options("Can I buy some leather?", "Leather is rather weak stuff.").also { stage = 20 } + } + } + + 10 -> options("Yes please.", "No thanks.").also { stage++ } + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes please.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No thanks.").also { stage = 13 } + } + + 12 -> end().also { TanningProduct.open(player, NPCs.ELLIS_2824) } + 13 -> npcl(FacialExpression.FRIENDLY, "Very well, @g[sir,madam], as you wish.").also { stage = END_DIALOGUE } + + 20 -> when (buttonId) { + 1 -> playerl(FacialExpression.ASKING, "Can I buy some leather?").also { stage = 21 } + 2 -> playerl(FacialExpression.SUSPICIOUS, "Leather is rather weak stuff.").also { stage = 22 } + } + + 21 -> npcl(FacialExpression.FRIENDLY, "I make leather from animal hides. Bring me some cowhides and one gold coin per hide, and I'll tan them into soft leather for you.").also { stage = END_DIALOGUE } + + 22 -> npcl(FacialExpression.NOD_YES, "Normal leather may be quite weak, but it's very cheap - I make it from cowhides for only 1 gp per hide - and it's so easy to craft that anyone can work with it.").also { stage++ } + 23 -> npcl(FacialExpression.HALF_THINKING, "Alternatively you could try hard leather. It's not so easy to craft, but I only charge 3 gp per cowhide to prepare it, and it makes much sturdier armour.").also { stage++ } + 24 -> npcl(FacialExpression.FRIENDLY, "I can also tan snake hides and dragonhides, suitable for crafting into the highest quality armour for rangers.").also { stage++ } + 25 -> playerl(FacialExpression.NEUTRAL, "Thanks, I'll bear it in mind.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EllisDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ELLIS_2824) + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt index 65e45420c..cd6bd5d5e 100644 --- a/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt +++ b/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt @@ -1,11 +1,13 @@ package content.region.desert.alkharid.dialogue import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage /** * Represents the gem trader Dialogue plugin @@ -21,17 +23,8 @@ class GemTraderDialogue (player: Player? = null): DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player?.questRepository?.getStage("Family Crest") ?: -1 - if(qstage == 12){ - npc("Good day to you, traveller. ", - "Would you be interested in buying some gems?") - stage = 1 - } - else{ - npc("Good day to you, traveller. ", - "Would you be interested in buying some gems?") - stage = 2 - } + npc("Good day to you, traveller.", "Would you be interested in buying some gems?") + stage = if (getQuestStage(player, Quests.FAMILY_CREST) == 12) 1 else 2 return true } @@ -74,7 +67,7 @@ class GemTraderDialogue (player: Player? = null): DialoguePlugin(player){ 103 -> npc("Well, maybe we'll all get lucky ", "and the scorpions will deal with him.").also{ stage = 1000 - player.questRepository.getQuest("Family Crest").setStage(player, 13) + setQuestStage(player, Quests.FAMILY_CREST, 13) } 1000 -> end() diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java index ce0192046..7c711edab 100644 --- a/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java +++ b/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue used to handle the Hassan npc. @@ -52,7 +53,7 @@ public final class HassanDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); switch (quest.getStage(player)) { case 100: interpreter.sendDialogues(npc, null, "You are a friend of the town of Al-Kharid. If we have", "more tasks to complete, we will ask you. Please, keep in", "contact. Good employees are not easy to find."); diff --git a/Server/src/main/content/region/desert/alkharid/handlers/TanningNPC.java b/Server/src/main/content/region/desert/alkharid/handlers/TanningNPC.java deleted file mode 100644 index 8fdf05cc1..000000000 --- a/Server/src/main/content/region/desert/alkharid/handlers/TanningNPC.java +++ /dev/null @@ -1,30 +0,0 @@ -package content.region.desert.alkharid.handlers; - -import core.cache.def.impl.NPCDefinition; -import core.plugin.Initializable; -import content.global.skill.crafting.TanningProduct; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Plugin; - -/** - * @author 'Vexia - */ -@Initializable -public class TanningNPC extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - NPCDefinition.forId(1041).getHandlers().put("option:trade", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - TanningProduct.open(player, ((NPC) node).getId()); - return true; - } - -} diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java index 5cc974b9b..038567099 100644 --- a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java @@ -10,6 +10,7 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.game.world.GameWorld; import core.game.world.map.RegionManager; +import content.data.Quests; /** * Represents the dialogue which handles the lady keli transcript. @@ -58,7 +59,7 @@ public final class LadyKeliDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); switch (quest.getStage(player)) { case 60: case 100: diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java index 4cd5acffa..1c37aebab 100644 --- a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java @@ -6,6 +6,7 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the prince ali rescue quest. @@ -44,7 +45,7 @@ public class PrinceAliRescue extends Quest { * Constructs a new {@Code PrinceAliRescue} {@Code Object} */ public PrinceAliRescue() { - super("Prince Ali Rescue", 24, 23, 3, 273, 0, 1, 110); + super(Quests.PRINCE_ALI_RESCUE, 24, 23, 3, 273, 0, 1, 110); } @Override @@ -63,16 +64,16 @@ public class PrinceAliRescue extends Quest { break; case 10: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, BLUE + "I should go and speak to " + RED + "Osman " + BLUE + "for details on the quest.", 6+ 7); break; case 20: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); line(player, RED + "Prince Ali " + BLUE + "has been " + RED + "kidnapped " + BLUE + "but luckily the spy " + RED + "Leela " + BLUE + "has", 7+ 7); - line(player, BLUE + "found he is being held near " + RED + "Draynor village. " + BLUE + "I will need to", 8+ 7); - line(player, RED + "disguise " + BLUE + "the " + RED + "Price " + BLUE + "and " + RED + "tie " + BLUE + "up his " + RED + "captop " + BLUE + "to " + RED + "free " + BLUE + "him from", 9+ 7); + line(player, BLUE + "found he is being held near " + RED + "draynor village. " + BLUE + "I will need to", 8+ 7); //authentic typo on the 'draynor village' capitialization + line(player, RED + "disguise " + BLUE + "the " + RED + "Prince " + BLUE + "and " + RED + "tie " + BLUE + "up his " + RED + "captor " + BLUE + "to " + RED + "free " + BLUE + "him from", 9+ 7); line(player, BLUE + "their " + RED + "clutches.", 10+ 7); line(player, BLUE + "To do this I should:-", 11+ 7); line(player, BLUE + "Talk to " + RED + "Leela " + BLUE + "near " + RED + "Draynor Village " + BLUE + "for advice.", 12+ 7); @@ -84,10 +85,10 @@ public class PrinceAliRescue extends Quest { break; case 30: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); line(player, RED + "Prince Ali " + BLUE + "has been " + RED + "kidnapped " + BLUE + "but luckily the spy " + RED + "Leela " + BLUE + "has", 7+ 7); - line(player, BLUE + "found he is being held near " + RED + "Draynor village. " + BLUE + "I will need to", 8+ 7); + line(player, BLUE + "found he is being held near " + RED + "Draynor Village. " + BLUE + "I will need to", 8+ 7); line(player, RED + "disguise " + BLUE + "the " + RED + "Prince " + BLUE + "and " + RED + "tie " + BLUE + "up his " + RED + "captor " + BLUE + "to " + RED + "free " + BLUE + "him from", 9+ 7); line(player, BLUE + "their " + RED + "clutches.", 10+ 7); line(player, BLUE + "To do this I should:-", 11+ 7); @@ -96,15 +97,15 @@ public class PrinceAliRescue extends Quest { line(player, hasItem(player, ROPE) ? "I have some rope with me." : BLUE + "Get some " + RED + "rope " + BLUE + "to tie up the Princes' " + RED + "kidnapper.", 14+ 7); line(player, hasItem(player, PASTE) ? "I have some skin paste suitable for disguise with me." : BLUE + "Get something to " + RED + "colour " + BLUE + "the " + RED + "Princes' skin " + BLUE + "as a " + RED + "disguise.", 15+ 7); line(player, hasItem(player, SKIRT) ? "I have a skirt suitable for a disguise with me." : BLUE + "Get a " + RED + "skirt " + BLUE + "similar to his " + RED + "kidnapper " + BLUE + "as " + RED + "disguise.", 16+ 7); - line(player, hasItem(player, YELLOW_WIG) ? "I have a wig suitable for disguise with me." : BLUE + "Get a " + RED + "Wig " + BLUE + "to " + RED + "help disguise" + BLUE + "the " + RED + "prince.", 17+ 7); + line(player, hasItem(player, YELLOW_WIG) ? "I have a wig suitable for disguise with me." : BLUE + "Get a " + RED + "Wig " + BLUE + "to " + RED + "help disguise " + BLUE + "the " + RED + "prince.", 17+ 7); break; case 40: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); if (player.getAttribute("guard-drunk", false)) { line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); - line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "found he is being held near Draynor Village. I will need to", 8+ 7); line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); line(player, "their clutches.", 10+ 7); line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); @@ -115,32 +116,32 @@ public class PrinceAliRescue extends Quest { } else { line(player, BLUE + "Do something to prevent " + RED + "Joe the Guard " + BLUE + "seeing the", 7+ 7); line(player, BLUE + "escape.", 8+ 7); - line(player, BLUE + "Use the " + RED + "Skin potion" + BLUE + ", " + RED + "Pink Skirt" + BLUE + "," + RED + "Rope" + BLUE + "," + RED + "Blonde Wig " + BLUE + "and " + RED + "Cell", 9+ 7); + line(player, BLUE + "Use the " + RED + "Skin Potion" + BLUE + ", " + RED + "Pink Skirt" + BLUE + ", " + RED + "Rope" + BLUE + ", " + RED + "Blonde Wig " + BLUE + "and " + RED + "Cell", 9+ 7); line(player, RED + "Key" + BLUE + " to free " + RED + "Prince Ali " + BLUE + "from his cell somehow.", 10+ 7); } break; case 50: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); - line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "found he is being held near Draynor Village. I will need to", 8+ 7); line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); line(player, "their clutches.", 10+ 7); line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); line(player, "to, by getting him drunk.", 11+ 7); line(player, "With the guard disposed of, I used my rope to tie up Lady", 11+ 7); line(player, "Keli in a cupboard, so I could disguise the Prince.", 12+ 7); - line(player, BLUE + "I need to " + RED + "Unlock the cell door " + BLUE + "and then give the Prince the", 13+ 7); - line(player, RED + "Pink Skirt" + BLUE + ", the " + RED + "Skin paste " + BLUE + "and the " + RED + "Blonde Swig " + BLUE + "so that the", 14+ 7); + line(player, BLUE + "I need to " + RED + "unlock the cell door " + BLUE + "and then give the Prince the", 13+ 7); + line(player, RED + "Pink Skirt" + BLUE + ", the " + RED + "Skin Paste " + BLUE + "and the " + RED + "Blonde Wig " + BLUE + "so that they", 14+ 7); line(player, BLUE + "can safely " + RED + "escape " + BLUE + "disguised as " + RED + "Lady Keli.", 15+ 7); break; case 60: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); - line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "found he is being held near Draynor Village. I will need to", 8+ 7); line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); line(player, "their clutches.", 10+ 7); line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); @@ -154,10 +155,10 @@ public class PrinceAliRescue extends Quest { break; case 100: line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); - line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "Palace. He told me I should speak to Osman the spymaster.", 5+ 7); line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); - line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "found he is being held near Draynor Village. I will need to", 8+ 7); line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); line(player, "their clutches.", 10+ 7); line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); @@ -169,7 +170,7 @@ public class PrinceAliRescue extends Quest { line(player, "freedom with Leela after unlocking his cell door.", 15+ 7); line(player, "Hassan the chancellor rewarded me for all of my help.", 16+ 7); line(player, "I am now a friend of Al-Kharid and may pass through the", 17+ 7); - line(player, "gate leading between Lumbridge and Al-Kharid for free", 18+ 7); + line(player, "gate leading between Lumbridge and Al-Kharid for free.", 18+ 7); line(player, "QUEST COMPLETE!", 19+ 7); break; } diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java index 7327333fb..3f38c3489 100644 --- a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java @@ -13,6 +13,7 @@ import core.game.world.GameWorld; import core.game.world.map.Location; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the plugin used to handle prince ali rescue quest interaction nodes. @@ -35,7 +36,7 @@ public class PrinceAliRescuePlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + final Quest quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); final int id = node instanceof Scenery ? ((Scenery) node).getId() : node instanceof NPC ? ((NPC) node).getId() : 0; switch (id) { case 925: diff --git a/Server/src/main/content/region/desert/bandits/handlers/BanditBehavior.kt b/Server/src/main/content/region/desert/bandits/handlers/BanditBehavior.kt deleted file mode 100644 index b918f675b..000000000 --- a/Server/src/main/content/region/desert/bandits/handlers/BanditBehavior.kt +++ /dev/null @@ -1,46 +0,0 @@ -package content.region.desert.bandits.handlers - -import core.api.* -import core.game.node.entity.Entity -import core.game.node.entity.combat.BattleState -import core.game.node.entity.npc.NPC -import core.game.node.entity.npc.NPCBehavior -import core.game.world.map.RegionManager -import core.tools.RandomFunction -import org.rs09.consts.NPCs - -class BanditBehavior : NPCBehavior(NPCs.BANDIT_1926) { - override fun tick(self: NPC): Boolean { - if (!self.inCombat() && RandomFunction.roll(3) && getWorldTicks() % 5 == 0) { - val players = RegionManager.getLocalPlayers(self, 5) - for (player in players) { - if (player.inCombat()) continue - if (hasGodItem(player, God.SARADOMIN)) { - sendChat(self, "Prepare to die, Saradominist scum!") - self.attack(player) - break - } - else if (hasGodItem(player, God.ZAMORAK)) { - sendChat(self, "Prepare to die, Zamorakian scum!") - self.attack(player) - break - } - } - } - return true - } - - override fun afterDamageReceived(self: NPC, attacker: Entity, state: BattleState) { - if (getAttribute(self, "alerted-others", false)) return - val otherBandits = RegionManager.getLocalNpcs(self, 3).filter { it.id == self.id } - for (bandit in otherBandits) { - if (!bandit.inCombat()) - bandit.attack(attacker) - } - setAttribute(self, "alerted-others", true) - } - - override fun onDeathStarted(self: NPC, killer: Entity) { - removeAttribute(self, "alerted-others") - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/bandits/handlers/BanditDialogue.kt b/Server/src/main/content/region/desert/bandits/handlers/BanditDialogue.kt new file mode 100644 index 000000000..2b6d8f8ac --- /dev/null +++ b/Server/src/main/content/region/desert/bandits/handlers/BanditDialogue.kt @@ -0,0 +1,63 @@ +package content.region.desert.bandits.handlers + +import content.region.desert.quest.deserttreasure.DesertTreasure +import core.api.getAttribute +import core.api.inInventory +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class BanditDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return BanditDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, BanditDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BANDIT_1926) + } +} +class BanditDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 100) + .npcl("So you're the one who freed Azzanadra from his prison? Thank you, kind @g[sir,lady]!") + .end() + + b.onQuestStages(DesertTreasure.questName, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) + .npcl("What do you want @g[lad,lass]?") + .playerl("I'm here on an archaeological expedition for the Museum of Varrock. I believe there may be some interesting artefacts in the area.") + .branch { player -> + return@branch (0..4).random() + }.let { branch -> + branch.onValue(0) + .npcl("You are a crazy @g[man,woman]. The only thing you will find out here in the desert is your death.") + .end() + branch.onValue(1) + .npcl("I have no interest in the world that betrayed my people. Search where you will, you will find nothing.") + .end() + branch.onValue(2) + .npcl("The gods forsake us, and drove us to this place. Anything of worth has been long gone.") + .end() + branch.onValue(3) + .npcl("I'm sure there are many secrets buried beneath the sands here. The thing about this being a desert, is that they're likely to stay that way.") + .end() + branch.onValue(4) + .npcl("Do I look like I care who you are or where you came from?") + .end() + } + + b.onPredicate { _ -> true } + .npcl("Get out of this village. You are not welcome here.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/bandits/handlers/BanditNPC.kt b/Server/src/main/content/region/desert/bandits/handlers/BanditNPC.kt new file mode 100644 index 000000000..29a7809d1 --- /dev/null +++ b/Server/src/main/content/region/desert/bandits/handlers/BanditNPC.kt @@ -0,0 +1,64 @@ +package content.region.desert.bandits.handlers + +import core.api.God +import core.api.hasGodItem +import core.api.inEquipment +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BanditNPC(id: Int = NPCs.BANDIT_1926, location: Location? = null) : AbstractNPC(id, location) { + private val supportRange: Int = 3 + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return BanditNPC(id, location) + } + + override fun tick() { + if (!inCombat()) { + val players = RegionManager.getLocalPlayers(this, 5) + for (player in players) { + if (player.inCombat()) continue + if (hasGodItem(player, God.SARADOMIN)) { + sendChat("Time to die, Saradominist filth!") + attack(player) + break + } else if (hasGodItem(player, God.ZAMORAK) || inEquipment(player, Items.DAGONHAI_HAT_14499) || inEquipment(player, Items.DAGONHAI_ROBE_TOP_14497) || inEquipment(player, Items.DAGONHAI_ROBE_BOTTOM_14501)) { + sendChat("Prepare to suffer, Zamorakian scum!") + attack(player) + break + } + } + } + super.tick() + } + + //Clear target on death + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + + override fun onImpact(entity: Entity?, state: BattleState?) { + if (entity is Player) { + RegionManager.getLocalNpcs(entity, supportRange).forEach { + if (it.id == NPCs.BANDIT_1926 && !it.properties.combatPulse.isAttacking && it != this) { + it.sendChat("You picked the wrong place to start trouble!") + it.attack(entity) + } + } + } + super.onImpact(entity, state) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BANDIT_1926) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java b/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java index 577cb1151..a4a3c626a 100644 --- a/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java +++ b/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java @@ -23,6 +23,7 @@ import core.plugin.Plugin; import core.plugin.ClassScanner; import org.rs09.consts.Items; import org.rs09.consts.Sounds; +import content.data.Quests; /** @@ -158,11 +159,11 @@ public final class RugMerchantDialogue extends DialoguePlugin { } end(); destination = options.length == 1 ? options[0] : options[buttonId - 1]; - if (destination == RugDestination.UZER && !hasRequirement(player, "The Golem")) + if (destination == RugDestination.UZER && !hasRequirement(player, Quests.THE_GOLEM)) break; - else if (destination == RugDestination.BEDABIN_CAMP && !hasRequirement(player, "The Tourist Trap")) + else if (destination == RugDestination.BEDABIN_CAMP && !hasRequirement(player, Quests.THE_TOURIST_TRAP)) break; - else if (destination == RugDestination.SOPHANEM && !hasRequirement(player, "Icthlarin's Little Helper")) + else if (destination == RugDestination.SOPHANEM && !hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)) break; if(player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null){ player.sendMessage(colorize("%RYou must unequip all your weapons before you can fly on a carpet.")); diff --git a/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java b/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java index be8dde907..fcbf3077f 100644 --- a/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java +++ b/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java @@ -47,11 +47,11 @@ public final class ShantayDialogue extends DialoguePlugin { } if (args.length == 2) { player.getPacketDispatch().sendMessage("Shantay saunters over to talk with you."); - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "If you want to be let out, you have to pay a fine of", "five gold. Do you want to pay now?"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "If you want to be let out, you have to pay a fine of", "five gold. Do you want to pay now?"); stage = 703; return true; } - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "Hello effendi, I am Shantay."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Hello effendi, I am Shantay."); stage = 0; return true; } @@ -60,11 +60,11 @@ public final class ShantayDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "I see you're new. Please read the billboard poster", "before going into the desert. It'll give yer details on the", "dangers you can face."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "I see you're new. Please read the billboard poster", "before going into the desert. It'll give yer details on the", "dangers you can face."); stage = 1; break; case 1: - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "There is a heartbroken mother just past the gates and", "in the desert. Her name is Irena and she mourns her", "lost daughter. Such a shame."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "There is a heartbroken mother just past the gates and", "in the desert. Her name is Irena and she mourns her", "lost daughter. Such a shame."); stage = 2; break; case 2: @@ -74,19 +74,19 @@ public final class ShantayDialogue extends DialoguePlugin { case 3: switch (buttonId) { case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "What is this place?"); stage = 10; break; case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I see what you have to sell please?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Can I see what you have to sell please?"); stage = 20; break; case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I must be going."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I must be going."); stage = 30; break; case 4: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I want to buy a Shantay pass for 5 gold coins."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I want to buy a Shantay pass for 5 gold coins."); stage = 40; break; @@ -101,7 +101,7 @@ public final class ShantayDialogue extends DialoguePlugin { player.getInventory().add(new Item(1854)); interpreter.sendItemMessage(1854, "You purchase a Shantay Pass."); } else { - interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Sorry, I don't seem to have enough money."); } stage = 41; break; @@ -109,18 +109,18 @@ public final class ShantayDialogue extends DialoguePlugin { end(); break; case 30: - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "So long..."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "So long..."); stage = 31; break; case 31: end(); break; case 10: - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "This is the pass of Shantay. I guard this area with my", "men. I am responsible for keeping this pass open and", "repaired."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "This is the pass of Shantay. I guard this area with my", "men. I am responsible for keeping this pass open and", "repaired."); stage = 11; break; case 11: - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "My men and I prevent outlaws from getting out of the", "desert. And we stop the inexeperienced from a dry death", "in the sands. Which would you say you were?"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "My men and I prevent outlaws from getting out of the", "desert. And we stop the inexeperienced from a dry death", "in the sands. Which would you say you were?"); stage = 12; break; case 12: @@ -130,21 +130,21 @@ public final class ShantayDialogue extends DialoguePlugin { case 13: switch (buttonId) { case 1: - interpreter.sendDialogues(player, null, "I am definitely an outlaw, prepare to die."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I am definitely an outlaw, prepare to die."); stage = 700; break; case 2: - interpreter.sendDialogues(player, null, "I am a little inexperienced."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I am a little inexperienced."); stage = 710; break; case 3: - interpreter.sendDialogues(player, null, "Er, neither, I'm an adventurer."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Er, neither, I'm an adventurer."); stage = 720; break; } break; case 20: - interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "Absolutely Effendi!"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Absolutely Effendi!"); stage = 21; break; case 21: @@ -152,11 +152,11 @@ public final class ShantayDialogue extends DialoguePlugin { npc.openShop(player); break; case 700: - interpreter.sendDialogues(836, null, "Ha, very funny....."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Ha, very funny....."); stage = 701; break; case 701: - interpreter.sendDialogues(836, null, "Guards arrest him!"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Guards arrest him!"); stage = 702; break; case 702: @@ -168,7 +168,7 @@ public final class ShantayDialogue extends DialoguePlugin { public boolean pulse() { player.setAttribute("/save:shantay-jail", true); player.getProperties().setTeleportLocation(Location.create(3298, 3123, 0)); - interpreter.sendDialogues(836, null, "You'll have to stay in there until you pay the fine of", "five gold pieces. Do you want to pay now?"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "You'll have to stay in there until you pay the fine of", "five gold pieces. Do you want to pay now?"); stage = 703; return true; } @@ -181,11 +181,11 @@ public final class ShantayDialogue extends DialoguePlugin { case 704: switch (buttonId) { case 1: - interpreter.sendDialogues(player, null, "Yes, okay."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Yes, okay."); stage = 705; break; case 2: - interpreter.sendDialogues(player, null, "No thanks, you're not having my money."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thanks, you're not having my money."); stage = 800; break; } @@ -194,20 +194,20 @@ public final class ShantayDialogue extends DialoguePlugin { if (player.getInventory().remove(new Item(995, 5))) { player.getPacketDispatch().sendMessage("You hand over the five gold pieces to Shantay."); player.getPacketDispatch().sendMessage("Shantay unlocks the door to the cell."); - interpreter.sendDialogues(836, null, "Great, Effendi, now please try to keep the peace."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Great, Effendi, now please try to keep the peace."); player.removeAttribute("shantay-jail"); stage = 822; } else { - interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Sorry, I don't seem to have enough money."); stage = 825; } break; case 800: - interpreter.sendDialogues(836, null, "You have a choice. You can either pay five gold pieces", "or... You can be transported to a maximum security", "prision in Port Sarim"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "You have a choice. You can either pay five gold pieces", "or... You can be transported to a maximum security", "prison in Port Sarim"); stage = 801; break; case 801: - interpreter.sendDialogues(836, null, "Will you pay the five gold pieces?"); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Will you pay the five gold pieces?"); stage = 802; break; case 802: @@ -217,17 +217,17 @@ public final class ShantayDialogue extends DialoguePlugin { case 803: switch (buttonId) { case 1: - interpreter.sendDialogues(player, null, "Yes, okay."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Yes, okay."); stage = 820; break; case 2: - interpreter.sendDialogues(player, null, "No, do your worst!"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No, do your worst!"); stage = 804; break; } break; case 804: - interpreter.sendDialogues(836, null, "You are to be transported to a maximum security", "prision in Port Sarim. I hope you've learn an important", "lesson from this."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "You are to be transported to a maximum security", "prison in Port Sarim. I hope you've learnt an important", "lesson from this."); stage = 805; break; case 805: @@ -237,17 +237,17 @@ public final class ShantayDialogue extends DialoguePlugin { end(); break; case 820: - interpreter.sendDialogues(836, null, "Good, I see that you have come to your senses."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Good, I see that you have come to your senses."); stage = 821; break; case 821: if (player.getInventory().remove(new Item(995, 5))) { player.getPacketDispatch().sendMessage("You hand over the five gold pieces to Shantay."); player.getPacketDispatch().sendMessage("Shantay unlocks the door to the cell."); - interpreter.sendDialogues(836, null, "Great, Effendi, now please try to keep the peace."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Great, Effendi, now please try to keep the peace."); stage = 822; } else { - interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Sorry, I don't seem to have enough money."); stage = 825; } break; @@ -258,26 +258,26 @@ public final class ShantayDialogue extends DialoguePlugin { end(); break; case 710: - interpreter.sendDialogues(836, null, "Can I recommend that you purchase a full waterskin", "and a knife! These items will no doubt save your life. A", "waterskin will keep water from evaporating in the desert."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Can I recommend that you purchase a full waterskin", "and a knife! These items will no doubt save your life. A", "waterskin will keep water from evaporating in the desert."); stage = 711; break; case 711: - interpreter.sendDialogues(836, null, "And a keen woodsman with a knife can extract juice", "from a cactus. Before you go into the desert, it's", "advisable to wear desert clothes. It's very hot in the", "desert and you'll surely cook if you wear amour."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "And a keen woodsman with a knife can extract juice", "from a cactus. Before you go into the desert, it's", "advisable to wear desert clothes. It's very hot in the", "desert and you'll surely cook if you wear amour."); stage = 712; break; case 712: end(); break; case 720: - interpreter.sendDialogues(836, null, "Great, I have just the thing for you the desert adventurer.", "I sell desert clothes which will keep you cool in the heat", "of the desert. I also sell waterskins so that you won't", "die in the desert."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "Great, I have just the thing for you the desert adventurer.", "I sell desert clothes which will keep you cool in the heat", "of the desert. I also sell waterskins so that you won't", "die in the desert."); stage = 721; break; case 721: - interpreter.sendDialogues(836, null, "A waterskin and a knife help you survive from the juice", "of a cactus. Use the chest to store your items, we'll take", "them to the bank. It's hot in the desert, you'll bake in", "all that armour."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "A waterskin and a knife help you survive from the juice", "of a cactus. Use the chest to store your items, we'll take", "them to the bank. It's hot in the desert, you'll bake in", "all that armour."); stage = 722; break; case 722: - interpreter.sendDialogues(836, null, "To keep the pass open we ask for 5 gold pieces. And", "we give you a Shantay Pass, just ask to see what I sell", "to buy one."); + interpreter.sendDialogues(836, FacialExpression.NEUTRAL, "To keep the pass open we ask for 5 gold pieces. And", "we give you a Shantay Pass, just ask to see what I sell", "to buy one."); stage = 723; break; case 723: diff --git a/Server/src/main/content/region/desert/handlers/DesertZone.java b/Server/src/main/content/region/desert/handlers/DesertZone.java index 070889206..3110c7233 100644 --- a/Server/src/main/content/region/desert/handlers/DesertZone.java +++ b/Server/src/main/content/region/desert/handlers/DesertZone.java @@ -39,7 +39,7 @@ public final class DesertZone extends MapZone implements Plugin { /** * Represents data of water vessils to dry up. */ - private static final int[][] VESSILS = new int[][] { { 1937, 1935 }, { 1929, 1925 }, { 1921, 1923 }, { 227, 229 } }; + private static final int[][] VESSILS = new int[][] { { 1937, 1935 }, { 1929, 1925 }, { 1921, 1923 }, { 227, 229 }, { 4458, 1980} }; /** * Represents the animation of drinking water. diff --git a/Server/src/main/content/region/desert/handlers/KalphiteQueenArea.kt b/Server/src/main/content/region/desert/handlers/KalphiteQueenArea.kt new file mode 100644 index 000000000..e59ae6c86 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/KalphiteQueenArea.kt @@ -0,0 +1,10 @@ +package content.region.desert.handlers + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class KalphiteQueenArea : MapArea { + override fun defineAreaBorders() : Array { return arrayOf(ZoneBorders(3456, 9472, 3519, 9535, 0, true)) } + override fun getRestrictions() : Array { return arrayOf(ZoneRestriction.RANDOM_EVENTS) } +} diff --git a/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java b/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java index cff2ae212..39dbc9399 100644 --- a/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java +++ b/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java @@ -95,12 +95,12 @@ public final class KalphiteQueenNPC extends AbstractNPC { public void finalizeDeath(Entity killer) { if (getId() == 1160) { removeAttribute("disable:drop"); - reTransform(); super.finalizeDeath(killer); - BossKillCounter.addtoKillcount((Player) killer, 1160); + reTransform(); + BossKillCounter.addToBossKillCount((Player) killer, 1160); return; } - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); setAttribute("disable:drop", true); super.finalizeDeath(killer); super.setRespawnTick(-1); diff --git a/Server/src/main/content/region/desert/handlers/KhardianDesertPlugin.java b/Server/src/main/content/region/desert/handlers/KhardianDesertPlugin.java deleted file mode 100644 index ed0ba3d8c..000000000 --- a/Server/src/main/content/region/desert/handlers/KhardianDesertPlugin.java +++ /dev/null @@ -1,47 +0,0 @@ -package content.region.desert.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.global.action.DoorActionHandler; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles interactions in the khardian desert. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class KhardianDesertPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(6481).getHandlers().put("option:enter", this); - SceneryDefinition.forId(6545).getHandlers().put("option:open", this); - SceneryDefinition.forId(6547).getHandlers().put("option:open", this); - SceneryDefinition.forId(6551).getHandlers().put("option:use", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - switch (node.getId()) { - case 6481: - player.teleport(new Location(3233, 9313, 0)); - break; - case 6545: - case 6547: - // player.getPacketDispatch().sendMessage("A mystical power has sealed this door..."); - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()); - break; - case 6551: - player.teleport(new Location(3233, 2887, 0)); - break; - } - return true; - } - -} diff --git a/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java b/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java index 73a4d96dd..74ae051e1 100644 --- a/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java +++ b/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java @@ -92,7 +92,7 @@ public class ShantayPassPlugin extends OptionHandler { case "quick-pass": if (player.getLocation().getY() > 3116) { if (!inInventory(player, Items.SHANTAY_PASS_1854, 1)) { - sendNPCDialogue(player, 838, "You need a Shantay pass to get through this gate. See Shantay, he will sell you one for a very reasonable price.", FacialExpression.NEUTRAL); + sendNPCDialogue(player, 838, "You need a Shantay pass to get through this gate. See Shantay, he will sell you one for a very reasonable price.", FacialExpression.NEUTRAL, false); return true; } if (!removeItem(player, Items.SHANTAY_PASS_1854, Container.INVENTORY)) return true; diff --git a/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java b/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java index a07dcbed6..2c9f338a9 100644 --- a/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java +++ b/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java @@ -13,6 +13,7 @@ import core.plugin.Plugin; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_ALKHARID_GATE; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; +import content.data.Quests; @Initializable public class TollGateOptionPlugin extends OptionHandler { @@ -20,7 +21,7 @@ public class TollGateOptionPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { if (option.equals("pay-toll(10gp)")) { - if (player.getQuestRepository().getQuest("Prince Ali Rescue").getStage(player) > 50) { + if (player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE).getStage(player) > 50) { player.getPacketDispatch().sendMessage("The guards let you through for free."); DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); } else { diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/CurseOfZaros.kt b/Server/src/main/content/region/desert/quest/curseofzaros/CurseOfZaros.kt new file mode 100644 index 000000000..a57abef78 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/CurseOfZaros.kt @@ -0,0 +1,189 @@ +package content.region.desert.quest.curseofzaros + +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player + +/** + * Curse of Zaros is a miniquest with no quest points or final dialogue + * + * Players get the ghostly set for fashionscape. + */ +class CurseOfZaros { + companion object { + const val attributePathNumber = "/save:miniquest:curseofzaros-pathnumber" // 1 of 3. + const val attributeValdezSpoke = "/save:miniquest:curseofzaros-valdezspoke" + const val attributeRennardSpoke = "/save:miniquest:curseofzaros-rennardspoke" + const val attributeKharrimSpoke = "/save:miniquest:curseofzaros-kharrimspoke" + const val attributeLennissaSpoke = "/save:miniquest:curseofzaros-lennissaspoke" + const val attributeDhalakSpoke = "/save:miniquest:curseofzaros-dhalakspoke" + const val attributeViggoraSpoke = "/save:miniquest:curseofzaros-viggoraspoke" + + // Ghostly Robes lost: http://youtu.be/YcwYOqfG1Ys + + fun withoutGhostspeak(d: DialogueLabeller) { + fun label(label: String) { d.label(label) } + fun loadLabel(player: Player, label: String) { d.loadLabel(player, label) } + fun player(vararg messages: String) { d.player(ChatAnim.NEUTRAL, *messages) } + fun npc(vararg messages: String) { d.npc(ChatAnim.NEUTRAL, *messages) } + fun exec(callback: (player: Player, npc: NPC) -> Unit) { d.exec(callback) } + + label("noghostspeak") + exec { player, npc -> + loadLabel(player, "noghostspeak" + (1..8).random()) + } + + label("noghostspeak1") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("You don't say?") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("You don't say!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, I guess you didn't say.") + + label("noghostspeak2") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Yeah, I don't want to brag, but seriously: I am SOOOO rich....") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Yeah, I know they say money doesn't bring you happiness, but sometimes I just like to open my bank account and look at all of the stuff I own and just think to myself:") + player("Wow. I am soooooo rich.") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, us rich alive people don't want to waste all day spending time with you poor dead people, because I'm just sooooo rich I have to go now, and very possibly make myself even richer.") + player("See ya around ghosty!") + + label("noghostspeak3") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Yeah, I heard about that, ha-ha-ha!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("With a MACKEREL? Ouch!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, it was fun. Let's do it again sometime.") + + label("noghostspeak4") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Why, thank you very much!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("I know, but what are you going to do?") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, I guess that's always true in the long run. See you around, weird invisible dead person!") + + label("noghostspeak5") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Yeah it's not bad, but I prefer cooked chicken.") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Maybe, but nothing beats a home cooked pie!") + player("Man, I love pie!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("You don't say? I never knew that. Well, I must be going, see you around.") + + // This is peak 2009 memez + label("noghostspeak6") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("We get signal!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Somebody set up us the bomb!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("You have no chance to survive make your time.") + npc("Woo?") + player("All your base are belong to us.") + + label("noghostspeak7") + player("Hey, don't think you can talk to me like that!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Are you threatening me?") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Just because you're already dead, doesn't mean I can't find a way to hurt you ghosty!") + + label("noghostspeak8") + player("No, I've never been there in my life and CERTAINLY didn't steal anything when I was!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Are you calling me a liar?!?! I have never stolen a thing in my life, and I resent the implication that I am the kind of morally depraved individual that would steal someone else's hard earned") + player("money from their very pockets!") + player("Or cakes. Or fur. Repeatedly. For long periods at a time.") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well if you are going to take that attitude, then I have nothing further to say on the matter, and bid you good day!") + } + + + fun wrongPath(d: DialogueLabeller) { + fun label(label: String) { d.label(label) } + fun loadLabel(player: Player, label: String) { d.loadLabel(player, label) } + fun player(vararg messages: String) { d.player(ChatAnim.NEUTRAL, *messages) } + fun npc(vararg messages: String) { d.npc(ChatAnim.NEUTRAL, *messages) } + fun exec(callback: (player: Player, npc: NPC) -> Unit) { d.exec(callback) } + + label("wrongpath") + exec { player, npc -> + loadLabel(player, "wrongpath" + (1..7).random()) + } + + label("wrongpath1") + player("Hello there.") + npc("The endless tragedy of fate...", "Why must you torment me so?") + player("Alright, alright, calm down, calm down. All I said was 'hello'!") + + label("wrongpath2") + player("Hello there.") + npc("You can see me?") + player("Uh... yes?") + npc("And you understand my words?") + player("Well, most of them...") + npc("This is incredible! How can such a thing have come to pass?") + player("What can I say? I'm a professional.") + + label("wrongpath3") + player("Hello there.") + npc("Hello back at you.") + player("So what's a nice ghost like you doing in a place like this?") + npc("I suppose you think that's funny?") + player("Well... Mildly amusing I guess.") + npc("I don't think I want to talk to you anymore.") + + label("wrongpath4") + player("Hello there.") + npc("Hello stranger. It is rare indeed that I meet one who can see my presence, let alone one who can understand my words.") + player("Soooo.... Is it fun being a ghost?") + npc("Does it look like fun to you?") + player("Erm... Well, yes actually.") + npc("Then you are a fool, and I will waste no more words upon you.") + player("What, not even 'goodbye'?") + npc(" ") + player("Sheesh, what a grouch. You'd think you'd have more of a sense of humour being dead and all.") + + label("wrongpath5") + player("Hello there.") + npc("Mortal... Take heed of my example, and waste not your life, lest you may suffer the same fate as myself...") + player("Huh? You mean someone did this to you?") + npc("You have ascertained the truth in my words...") + player("So who did it to you? And why?") + npc("Events of moons past, I remember not clearly...") + player("Fine help you are then.") + + label("wrongpath6") + player("Hello there.") + npc("Hello stranger.") + player("So.... Invisible ghost haunting the same place for thousands of years, huh?") + npc("You have no idea...") + player("Well, bad luck and all that. See ya around!") + + label("wrongpath7") + player("Hello there.") + npc("Hello.") + player("So you're a ghost, huh?") + npc("Apparently.") + player("In which case I only have one thing to say to you:") + npc("...what?") + player("Guess you don't have the amulet of humanspeak, huh?") + npc("...huh?") + player("Yeah, that's right. WOO! WOOOWOOO WOO WOOOOWOO! Got no comeback for that, have you?") + npc("You are very strange...") + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostDhalakDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostDhalakDialogue.kt new file mode 100644 index 000000000..d8c89c1d0 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostDhalakDialogue.kt @@ -0,0 +1,149 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostDhalakDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostDhalakDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostDhalakDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2385, 2386, 2387) + } +} + +class MysteriousGhostDhalakDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2384 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeDhalakSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_HOOD_6109) || inEquipment(player, Items.GHOSTLY_HOOD_6109)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello Dhalak.") + npc("You see my form, hear my words, and know my name, yet your face I recognise not...") + npc("Be you some mighty sorcerer to bind me so?") + player("Um... Well, not really...") // player("Well, I don't mean to brag, but I guess I am with my level 99 magic...") if you are 99 lvl magic but calm the fuck down showoff + player("But that is besides the point. It is not I who has trapped you here as a ghost.") + npc("Then how comes it to be that you know my name stranger?") + player("Lennissa told me about you, and where to find you?") + npc("Lennissa? Oh that poor sweet girl... Has my foolishness cursed her as well as myself???") + player("Your foolishness?") + npc("The story shames me stranger, I wouldst rather keep it unto myself.") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Look, I don't want to force you into telling me, but perhaps sharing it with someone might relieve your guilt?") + npc("Aye... Perhaps it might at that.") + npc("So what has Lennissa told you of the events of the day this curse befell me?") + player("Well, she told me that she was working as an undercover agent of Saradomin amongst the followers of some 'Empty Lord', and when news of the theft of a god-weapon reached her, she passed the message on to") + player("you instead of taking it to Saradomin because she was scared her cover might be blown.") + npc("Aye, that is a fair account of events...") + player("But I don't understand why you didn't take her message to Saradomin?") + npc("Stranger, my foolishness was a result of my respect for Saradomin, not as a result of any attempted treachery!") + player("So why didn't you pass on Lennissa's message? As I understand it something happened with that staff that could have been avoided if you had passed her message on!") + npc("(sigh) I know not what occurred with that god-weapon, but I have my suspicions...") + npc("Let me explain myself. I was Lennissa's immediate superior, and I was often her contact for missions.") + npc("Because of this role, I had access to a larger picture of what was happening than she herself did, and I was not only well aware that her presence amongst the enemy camp had been detected, but I was also well aware that") + npc("there was a growing faction amongst them who were plotting to overthrow their master.") + player("Their master being...?") + npc("That I will not tell you. I will tempt the fates no more than I already have done.") + npc("But anyway, it had come to my attention that the Mahjarrat who had been liberated from the control of Icthlarin did not much appreciate one form of slavery to another, and under the leadership of the mighty") + npc("Zamorak were making plans to overthrow their master and take his power for themselves.") + npc("Now, as powerful, long-lived and evil as they were, they were still just mortal, and I made the decision that it would be of benefit to my Lord Saradomin for his mightiest rival to be distracted by such internal conflicts.") + player("So that is why you decided not to pass the report from Lennissa on?") + npc("Yes, but my guilt is more than simply inaction...") + npc("I knew that with such a weapon, Zamorak would be capable of launching an attack that could actually stand a chance of success, but I also knew that he would never be able to get a chance to use it in a battle for") + npc("being a god-weapon its very presence would have sung out to their leader.") + player("I'm guessing you did something about that, then?") + npc("Indeed I did. To my eternal shame, I decided that I would assist Zamorak and his henchmen in their battle, by secretly casting a spell of concealment upon the staff so that") + npc("they might use it secretly against their master.") + player("So Zamorak knew about this?") + npc("No, nobody except myself, and now you, knew that I cast such a spell....") + npc("Had I known what a threat to my Lord Saradomin Zamorak would later become, I wouldst have taken the message to Saradomin immediately! Alas, it is all too easy to see your mistakes after you") + npc("have made them...") + player("I'm confused. What exactly happened with this staff anyway? And why have all these various random people been cursed because of it?") + npc("I cannot answer your question with anything other than my own suppositions, but I do know of one who might be able to, and if any man deserved to be cursed for their actions that day, it was he!") + player("Who are you speaking of?") + npc("His name was Viggora. He was an evil man, brutal and vicious, and deadly with a blade.") + npc("He was one of the few humans Zamorak allowed to rise to a position of power amongst his rebels, possibly because he imitated those same qualities of Zamorak.") + npc("If anyone knows what Zamorak did with that god- weapon to have caused this curse to have befallen us, it would have been he, for he would have been fighting on Zamorak's very right hand side in their rebellion.") + npc("Please, if this curse can be lifted, find Viggora and find out what he has wrought upon us! I have no wealth nor magic to aid you, but take my hood as reward;") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeDhalakSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_HOOD_6109) + } + npc("it has served me well these centuries past, and may bring you luck.") + player("Where would you suggest I look for Viggora?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Dhalak, where can I find the swordsman Viggora?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Ah, the evil swordsman Viggora... A rogue like him would probably flock to his own kind.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Ah, the evil swordsman Viggora... Perhaps he has returned to his castle in the dark lands?") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Ah, the evil swordsman Viggora... Paddewwa was where he fought many battles, perhaps he has returned to one of his old haunts?") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + + player(ChatAnim.SAD, "Could I have that hat again? I seem to have misplaced it", "somewhere...") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_HOOD_6109) + } + npc("Certainly, I am not sure how, but it returned to me by", "some magic or other.") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostKharrimDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostKharrimDialogue.kt new file mode 100644 index 000000000..4d825f193 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostKharrimDialogue.kt @@ -0,0 +1,143 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostKharrimDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostKharrimDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostKharrimDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2388, 2389, 2390) + } +} + +class MysteriousGhostKharrimDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2387 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeKharrimSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_BOOTS_6106) || inEquipment(player, Items.GHOSTLY_BOOTS_6106)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello. So you must be Kharrim the messenger.") + npc("How do you know my name, stranger?") + player("Well now... I had a very interesting chat with Rennard the thief.") + player("It seems you redirected his message regarding a certain god-weapon for your own ends.") + npc("So THAT is what this is about... I should have known the deal was too good to have no repercussions...") + player("It seems as though you might be responsible for this curse that has befallen you by not delivering Rennard's message to the correct person.") + npc("Ha! That is not a truthful assessment of the story... You might think differently if you had heard my side of events.") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Please let me hear your side of the story then...") + npc("Well, if you have spoken to Rennard, then you will know that he had somehow managed to obtain a very valuable weapon, and was looking for buyers.") + npc("What he probably didn't tell you, was that he met me in a drunken stupor in some smoke filled tavern, and I offered to arrange a purchaser for his item, in exchange for a small finders fee.") + player("So you knew what the staff was?") + npc("The god-staff of Armadyl? Well, of course I did.") + npc("Honestly, you would have to be pretty slow-witted to not recognise a legendary artefact such as that.") + player("Wait, I don't understand, Rennard said that he had a buyer already in mind, and that you diverted his message to a General Zamorak instead?") + npc("Ha! Here is a word of advice for you adventurer; Never trust the words of a drunk.") + npc("Whatever he might have thought he was doing with it, in the end all that happened was he left me to arrange a purchaser for the item.") + player("So you thought you would offer it to General Zamorak?") + npc("Ah yes, Lord Zamorak. He was merely a mortal back then, you know?") + npc("Yet I could see great things in store for him even then. He had a kind of brilliant ruthlessness... And that special kind of vicious streak you see so rarely...") + npc("Well anyway, when given the task of selling a weapon forged by the very gods themselves, I naturally thought of Zamorak as a potential buyer.") + npc("I was a messenger in his employ anyway, so it was a mere trifle to find him and deliver the news, and I knew of his particular interest in armour and weaponry of all kinds.") + npc("Yes, he was always quite the connoisseur when it came to weaponry...") + npc("But I digress. I let Lord Zamorak know that there was some drunken fool with an artefact of incredible power that could probably be bought off with a few jewels and trinkets,") + npc("and he escorted me to the tavern and made the purchase there and then.") + npc("It was a satisfactory deal all around, I got a share of the sale price from Rennard, and I greatly increased my prestige amongst Zamorak and his followers.") + npc("But maybe... Perhaps the events that followed were responsible for my cursed state...") + player("Events that followed?") + npc("I can not tell you of them precisely, for I myself was not there to witness them.") + npc("I am after all, simply a messenger. When... 'it' happened, I was busy elsewhere delivering a message from Zamorak to the rest of his Mahjarrat ilk.") + player("When 'it' happened? What was 'it'?") + npc("As I have explained, I was not there, and I do not know what Zamorak did with the staff, but whatever it was resulted in his banishment by the other gods for many years.") + npc("The very strange thing was that Saradomin must have known about it, whatever it was, before it even happened...") + player("Really? Why do you say that?") + npc("Well, it was the contents of the message I was returning to Zamorak;") + npc("Lucien seemed quite certain that there was a spy for Saradomin somewhere amongst his followers named Lennissa.") + npc("If whatever happened to the staff caused this curse to befall me, then it is certain that she too would have been afflicted, because she would have been in the very heart of the action.") + npc("Hmmm....") + npc("You have given me much to think on adventurer. I would like to reward you with my sturdy messenger boots, may they aid you in your travels.") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeKharrimSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_BOOTS_6106) + } + player("But where can I find this Lennissa?") + npc("Ah yes, the whereabouts of the treacherous Lennissa...") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Hello again Kharrim.") + player("Can you remind me where to find Lennissa?") + npc("Ah yes, the whereabouts of the treacherous Lennissa...") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Well, she was always sickeningly obedient to Saradomin, so I would expect her to have run to some great place of worship of him if she was affected by the curse to try and gain his blessing.") + player("Okay, well I'll try and find her for you then.") + + label("curseofzaros2") + npc("According to Lucien's intelligence report, she had been uncovered as a spy by her constant use of ships to ferry information...") + npc("It is entirely possible she would be located somewhere coastal to this day!") + player("Okay, well I'll try and find her for you then.") + + label("curseofzaros3") + npc("Well, we knew little about her or she would have been caught and exposed as a traitor and a spy, but Lucien did mention that he had evidence that she was a great fan of ball games...") + player("Okay, well I'll try and find her for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "I lost those boots you gave me...", "Can I have some more please?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_BOOTS_6106) + } + npc(ChatAnim.SAD, "How strange...", "They seemed to return to me when you lost them...") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostLennissaDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostLennissaDialogue.kt new file mode 100644 index 000000000..74c3657d7 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostLennissaDialogue.kt @@ -0,0 +1,155 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostLennissaDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostLennissaDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostLennissaDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2391, 2392, 2393) + } +} + +class MysteriousGhostLennissaDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2390 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeLennissaSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_ROBE_6108) || inEquipment(player, Items.GHOSTLY_ROBE_6108)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello. You would be Lennissa, I take it?") + npc("Who are you? Where did you hear that name? How comes it that you can see and speak to me?") + player("Well, a ghost called Kharrim directed me towards you.") + npc("So that weasel Kharrim has been blighted by this curse too?") + npc("Ha, a good thing too. If anybody deserved such a fate it would be one such as him.") + player("I guess you didn't get along then?") + npc("No, evil scum such as he should never have been allowed to walk this world.") + npc("What lies has he told you to come here? Have you come to try and kill me?") + player("Well, I'm not sure I could if I tried, but that is not why I have come to you.") + npc("Then speak, and speak well, for I may yet be dead, but am still a danger to those who cross me.") + player("Actually, I'm trying to work out why all of you invisible ghosts seem to have been cursed.") + player("I'm not sure how exactly, but the trail seems to have led me to you...") + npc("That makes no sense... I served Saradomin faithfully my entire life, then all of a sudden I find myself reduced to this state!") + player("Well, it seems as though that may have been the cause...") + npc("What? Explain yourself.") + player("As I understand it, it was something to do with the Staff of Armadyl, and your refusal to tell Saradomin that it had been stolen...") + npc("What? But... But that is not how it happened at all!") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Then please, go ahead and tell me the events of that day in your own words...") + npc("Let me see... I had been working as a spy for my Lord Saradomin, amongst the forces of... the Empty Lord.") + player("'The Empty Lord'? Who is that?") + npc("I will not give you his name, for to do so would give him power here.") + npc("Let us just say that he was a fearsome deity, whose strength was greater than all the gods we knew of on this realm at the time.") + npc("It is probably worth mentioning that at this time we had no knowledge of the mysterious nature god Guthix.") + player("So he was stronger than Saradomin?") + npc("As Saradomin was, yes. As Saradomin is now? Who can say?") + player("I see... Please, continue.") + npc("As I say, I was working as a spy within the very camp of my Lord's enemies.") + npc("I knew that should I have been caught, I risked being killed upon the spot, but my combat skills were always formidable, and if truth be told, there was a fair amount of dissent amongst... 'his' followers anyway.") + player("How do you mean 'dissent'?") + npc("Ah, to not understand this, you must have led a sheltered life...") + npc("Let me tell you this: Evil will always breed more evil, and will never be satisfied with what it has.") + npc("The Empty Lord chose to ally himself with the dark creatures of this world, fully aware that their own natures would cause them to rally against his rule, and take every opportunity they could to betray him.") + npc("This has always been the nature of evil. Perhaps he thought his power could prevent such treachery?") + npc("This allowed me freedom amongst their camp, for it was always easy to point the finger of suspicion at some unsuspecting necromancer or foolish Mahjarrat if it seemed as though my activities had been discovered.") + npc("Similarly, should I ever be caught in the act of my sabotage, it was all too easy to bribe whoever found me or persuade them into believing it was just some minor treachery of my own, rather than my work for my") + npc("Lord Saradomin.") + player("Okay... Well, that makes sense, but I don't understand what the Staff of Armadyl had to do with this...?") + npc("As I have told you, the Empty Lord was extremely powerful, but not so powerful that he could rule over the other deities of this world without opposition.") + npc("Should he have made a move against any other god, then he could still have been easily brought down by the combined efforts of the others.") + npc("The theft of Armadyl's staff changed this however.") + npc("If he had taken possession of this god-weapon, then his power would have been so great that he could have overthrown all on this world, and made it into his own image!") + npc("I could not allow such a thing to happen!") + npc("I went immediately to my comrade Dhalak, the mage, and told him that a message had come to the lair offering this weapon for sale!") + npc("I knew that as soon as my Lord Saradomin heard this, he would contact Armadyl to inform them of the theft, and the matter would have been resolved quickly and discreetly.") + player("So you passed this information to Dhalak instead of taking it to Saradomin yourself?") + npc("To my eternal shame, I indeed failed my Lord Saradomin...") + npc("I could not risk taking the message directly, for I feared my disguise had been uncovered.") + npc("Lucien particularly had been taking an unhealthy interest in my activities, and I had a gut feeling that to make any obvious moves against the Empty Lord would have been my undoing.") + npc("But Dhalak was a noble man! I cannot believe that he would not have taken my message immediately to Lord Saradomin!") + player("Well, it seems like he didn't, but I don't know why not...") + npc("Please adventurer, discover what foul fate must have befallen him for him to have neglected his duty!") + npc("I have not much to offer as reward, but for these spare robes I wore while on assignment...") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeLennissaSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_ROBE_6108) + } + npc("Please find him and discover why I am cursed like this!") + player("Where would I be able to find this Dhalak then?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Hello Lennissa. Can you remind me where to find Dhalak?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Dhalak? Well, he was always a knowlegeable mage, so if this curse has befallen him as well, I would suspect he would be researching how to free himself of it.") + npc("I would look for a library to find him if I were you.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Dhalak? He was always a loyal follower of Saradomin... I think he would have found an altar to Saradomin so that he may pray for this curse to be lifted.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Dhalak? I know not where, but he would try and make the most of his situation if he has been cursed, and find a place to lift his spirits!") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "Could I have that rob bottom again? I seem to have", "misplaced it somewhere...") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_ROBE_6108) + } + npc(ChatAnim.SAD, "Certainly, I am not sure how, but it returned to me by", "some magic or other.") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostRennardDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostRennardDialogue.kt new file mode 100644 index 000000000..6ac1468ad --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostRennardDialogue.kt @@ -0,0 +1,151 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostRennardDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostRennardDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostRennardDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2382, 2383, 2384) + } +} + +class MysteriousGhostRennardDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2381 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeRennardSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_GLOVES_6110) || inEquipment(player, Items.GHOSTLY_GLOVES_6110)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello. You must be Rennard.") + npc("What be this? You both see me and hear me, and also know my name?") + npc("Tell me what devilry brings you here, and be quick about it afore I gut you like a fish!") + player("Well, apart from the fact I ain't scared of no ghost, I am here because I have spoken to Valdez.") + npc("Valdez? Who be that? Some foul necromancer?") + player("No, he was a ghost I met near Glarial's tomb.") + player("He seems convinced that the artefact you stole from him is responsible for him becoming cursed to be an invisible ghost.") + player("Seems like he might be onto something too, given the state of you.") + npc("A curse ye say... Aye, that makes sense...") + npc("And there was I thinking my fate be the fault of the thieving and murdering I spent me life a-doing...") + npc("So it all began the day I stole that staff, ye say? Aye, that be a story I have never told another soul...") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Why don't you tell me what happened? I might be able to help...") + npc("Well, I was making me merry way along, having just pulled off a glorious jewellery heist from a bunch of stinking dwarves...") + player("Hey, that's no way to talk about dwarves! Some of my best friends are short!") + npc("Ah, yer misunderstand me @g[lad,lass], I wasn't generalising about the whole dwarf species, I had just stolen a bundle of jewels from a very specific group of dwarves who happened to have an odious stench about them!") + player("Oh. Well I guess that's okay then. Please continue.") + npc("Well, as I headed on me merry way, hoping the foul odours that lingered in me nostrils would soon pass, I see in front of me this explorer fella, all decked out in in his fine clothing, and carrying some long package") + npc("bundled in rags.") + npc("So I says to meself, 'Rennard', I says, 'Rennard, why would some fella all dressed in his finery be carrying something wrapped in dirty rags?'.") + npc("So I thinks to meself a little more, 'Rennard', I thinks, 'Rennard, maybe that fella has something valuable in there, and he covered it in dirty rags so it don't look so valuable'.") + npc("So I coshed this fella round the back of his head with me bag of jewels, picked up his package and was on me merry way afore he comes to.") + player("So what happened then?") + npc("Well, I makes me way to the closest tavern I knew of that catered to my sort of people...") + player("You mean thieves?") + npc("Right ye are, so I makes me way to the nearest friendly tavern, and unwraps the bundle to see what it had inside.") + player("The Staff of Armadyl?") + npc("Was it? Ah, I never knew that...") + npc("Anysways, I unwraps this staff, and sees it be a god- weapon; I may be just a common thief, but I recognises a weapon not made by mortal hands when I sees one.") + player("So what did you do then?") + npc("Well, I knew such a weapon would be of great value to...") + npc("Now that's funny. Can't remember his name, now. The powerful god, lived in the North-east. Took the Mahjarrat away from under Icthlarin's") + npc("control.") + npc("Anyway, I hired me a messenger to go off and let him know I had something I was prepared to sell that I thought he'd be interested in...") + npc("Now WHY can't I remember his name? Very odd that...") + player("So you sold the staff to this god you can't remember?") + npc("Well, that's the other funny thing... He never showed up, he sent some General or other instead.") + npc("Hmmm... You know... Thinking back on that, I'm getting the feeling that messenger did a little doublecross of his own, and took") + npc("me message to the wrong fella.") + player("So what was this General's name?") + npc("His name was Zamorak. I remember thinking at the time it was odd, because the fella was a mighty powerful warrior, but was never fully trusted by...") + npc("WHY can't I remember his name???") + player("So you suspect the messenger might have taken the message to the wrong person? So you think it was an accident or deliberate?") + npc("Well that I can't tell ya, but if something happened to get me cursed, it's likely the messenger would know what more than me.") + npc("His name was Kharrim, and if he caused me to be stuck like this, I'm gonna fillet him like a dog, ghost or no!") + npc("I tell ye what, you've given me much to think about so I'd like to offer yer a gift; Here, take these, they were the gloves I stole me first cake with, they might bring yer some luck.") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeRennardSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_GLOVES_6110) + } + player("Where can I find this Kharrim then?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Hello again Rennard.") + npc("Ah, it be you again! What can I do fer ya?") + player("Can you tell me where I can find Kharrim again?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Kharrim the messenger... Well, he was always a devoted follower of old General Zamorak, and if I remember rightly Zamorak set up a small base in an old temple near Dareeyak...") + npc("You might want to check around there.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Kharrim the messenger... Last I'd heard of him, he'd headed off to Carrallagar to seek his fortune. Ya might want to check around there somewhere.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Kharrim the messenger... The last I'd heard of that weasel he was claiming he'd found some underground deposit of runite ore guarded by demons and dragons.") + npc("I suspect he was pulling some scam or other, but if you know of such a place, that might be a good place to start checking.") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "I lost those gloves you gave me...", "Can I have some more please?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_GLOVES_6110) + } + npc(ChatAnim.SAD, "It seems as though the curse that keeps me here", "extends to my very clothing...") + npc("Here, take them, some evil power returned them to", "me...") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostValdezDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostValdezDialogue.kt new file mode 100644 index 000000000..0383402f7 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostValdezDialogue.kt @@ -0,0 +1,136 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostValdezDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostValdezDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostValdezDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2381) // wrong const SICK_LOOKING_SHEEP_4_2381 -> should be correct MYSTERIOUS_GHOST_2381 + } +} + +class MysteriousGhostValdezDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (getAttribute(player, CurseOfZaros.attributeValdezSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_ROBE_6107) || inEquipment(player, Items.GHOSTLY_ROBE_6107)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + label("firsttime") + player("Hello.") + npc(ChatAnim.EXTREMELY_SHOCKED, "H-hello!") + player(ChatAnim.THINKING, "So what's up?") + npc(ChatAnim.EXTREMELY_SHOCKED, "I cannot believe it!", "You can see me?", "You understand my words?") + player("Sure can.", "So why are you hanging around here?") + npc(ChatAnim.SAD, "My tale is one of woe...", "No doubt you will have little interest in hearing it...") + npc(ChatAnim.SAD, "Though it has been so many moons since last I had", "company in this endless non-life...") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Well, actually I would like to know what happened to you to turn you into an invisible ghost.") + player(ChatAnim.SUSPICIOUS, "If only so I can make sure it doesn't happen to me...") + npc("My name is Valdez. I served my Lord Saradomin faithfully for many years, as an explorer of this strange land we had been brought to.") + npc("I remember the day this curse fell upon me clearly... I had just discovered a huge temple, hidden below the ground, of one of Saradomin's compatriots.") + npc("I am unsure who had built it, or why they had left it seemingly abandoned, but inside I located a great treasure...") + npc("It was the godstaff of Armadyl.", "Oh, how I rue my choice that day!") + player("Choice?") + npc("Aye, stranger.", "I chose that day to take it so that my Lord Saradomin's", "power and prestige could be increased by its possession.") + npc("A god-weapon!", "Do you have any comprehension of the difficulty and", "rarity in obtaining such a thing?") + npc("To find such an artefact of power just lying around, it is almost incomprehensible...") + npc("So it was there in that deserted temple that I made my", "choice.", "I took the staff, and left that temple for Entrana", "immediately.") + npc("This was the cause of my cursed state.") + player("What, you mean you gave it to Saradomin and in return he cursed you???") + player("Seems kind of ungrateful if you ask me...") + npc("No stranger, you misunderstand completely...", "Firstly my gracious Lord would never treat anyone in", "such a manner;", "If he felt it was beyond my bounds as a mere mortal") + npc("to hold such an artefact, he would simply have commanded me to return it to whence I had claimed it, and I being eternally loyal would have obeyed without question...") + player("And secondly?") + npc("And secondly, I never managed to pass the artefact on to my Lord...") + npc("The vile thief Rennard accosted me as I made my way to Entrana, and after defeating me with a sneak attack, plundered the staff from my person, and left me for dead...") + npc("I do not know what became of the staff, but I can feel in my very bones that whatever its final fate was, it is somehow related to this curse upon me...") + player("Wow", "Tough break.") + npc("I am sorry to bore you with my tale stranger, please allow me to compound my rudeness by asking you for one favour, small to perform?") + player("Eh, I won't make any promises, but if it's nothing too annoying I guess I can help you out.") + npc("Many thanks stranger, this existence tortures me...") + npc("I need you to find Rennard and if he has the staff yet reclaim it, or find out what hideous deed he performed to curse me so!") + npc("I have nothing I may offer you save this piece of clothing, please take it as payment...") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeValdezSpoke, true) + // Set the path to follow. + setAttribute(player, CurseOfZaros.attributePathNumber, (1..3).random()) + addItemOrDrop(player, Items.GHOSTLY_ROBE_6107) + } + player("Where can I find this Rennard then?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + npc("Thank you for hearing my tale...", "It has been so lonely here...") + player("Can you remind me where to find the thief Rennard who caused this curse to befall you again?") + npc("Of course...") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Ah, the infamous Rennard...", "The last I had heard of him, he had sought passage on", "a ship crewed by none but the most dastardly lowly", "pirates...") + npc("I also heard that this ship had been caught in a violent", "storm, and stranded upon rocks, where the pirates then", "made their home...") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Ah, the infamous Rennard...", "The last I had heard of that vile thief, he had joined a", "group of bandits in an evil land to the North-east of", "here, where they had made their home living outside of") + npc("the reach of the authorities that pursued them...") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Ah, the infamous Rennard...", "The last I had heard of that vile thief, he had joined a", "group of bandits in a barren land to the South-east of", "here, where they prey upon the unsuspecting visitors to") + npc("the desert awaiting the return of their dark master...") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "I lost that Robe top you gave me...", "Can I have another please?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_ROBE_6107) + } + npc(ChatAnim.SAD, "It seems as though the curse that keeps me here", "extends to my very clothing...") + npc("Here, take it, the moment you lost it, it returned to", "me...") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostViggoraDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostViggoraDialogue.kt new file mode 100644 index 000000000..dae618e1d --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostViggoraDialogue.kt @@ -0,0 +1,188 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostViggoraDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostViggoraDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostViggoraDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2394, 2395, 2396) + } +} + +class MysteriousGhostViggoraDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2393 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeViggoraSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_CLOAK_6111) || inEquipment(player, Items.GHOSTLY_CLOAK_6111)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("So... You must be the infamous Viggora.") + npc("Hold thy tongue varlet! Speak fast, how come you to find me here, and how doth you understand mine speech?") + player("You want me to hold my tongue and tell you how I found you?") + npc("Cease thy chatter and respond to my demand!") + player("Cease my chatter AND respond to your demand?") + npc("I warn thee knave, this curse upon me hath not improved my temper, these centuries past...") + player("Well, it's actually about that curse that I have come to speak to you.") + npc("Oh, be that so? Then forgive my swift anger, and speak to me of how you plan to break this curse.") + player("Erm... I didn't actually mention anything about breaking the curse...") + npc("Then what lets you dare speak to me?") + player("Well, I heard of your name from a mage called Dhalak, and I'm trying to find out what exactly caused the curse to befall him, and you as well apparently.") + npc("Ha! So the weak-willed mage was cursed along with me?") + npc("Well now, that is an interesting turn of events... Then am I to assume that Valdez, Rennard, Kharrim and Lennissa were also cursed along with me?") + player("...How did you know that?") + npc("Ha ha ha! Oh, the curse cut deeper than I had previously thought!") + npc("Stranger, this news has brought me a ray of sunshine in an otherwise dreary millennium! Please, ask any question you wish!") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Erm... Thanks, I think. So what exactly happened on that day you were all cursed?") + player("I know that Valdez discovered the Staff of Armadyl, was robbed by Rennard, who then sent Kharrim to tell Zamorak of it.") + player("Meanwhile Lennissa heard of the sale, and informed Dhalak who placed an enchantment upon it so that its power would be hidden.") + player("I still don't know what happened with the staff to cause this curse, or what you had to do with it though...") + npc("Well stranger, rest yourself awhile, and I will recount a tale of the events of that day, for I was one of the few actually there when it happened...") + player("When what happened?") + npc("When my Lord Zamorak first got his taste of godhood!") + player("Wow. Sounds like quite the dinner party anecdote.") + npc("You can take the snide venom out of your voice whelp, you came to me; 'twas not the other way round.") + player("Okay, okay. Please continue.") + npc("Well now, let us see... As you may have heard tell, my affiliation lay with General Zamorak, a mighty warrior of the Mahjarrat tribe, and my skill on the battlefield had quickly brought") + npc("me to his attention.") + npc("So pleased was he with my bloodlust that he promoted me on the battlefield once to serve in his honour guard, and let me tell you, this was a rare honour indeed, for I was the only human chosen to take such a position.") + player("Really?") + npc("Oh yes, the dragon riders, Mahjarrat, demons and vampyre warriors made up the bulk of the force, but I wager I was their equal in all ways of combat.") + npc("Ha, when I think of someone like Lucien struggling to lift a blade, in some ways I was even their better!") + player("Please continue.") + npc("Well anyway... Myself and the rest of Zamoraks honour guard were formulating stratagems in our battle-tent, when that sneaky messenger Kharrim came in offering to sell us") + npc("the god-staff of Armadyl!") + npc("Naturally, we suspected that this was some trick by our Lord to test our loyalty...") + player("Yes, who was your lord? Everyone has been very evasive about that...") + npc("Quiet fool, all things in their course; You are disrupting my train of thought!") + player("Sorry...") + npc("Well anyway, we thought it was too good to be true, yet when we visited this scummy tavern we were amazed to discover there was no trick, no test of loyalty, no hidden trap:") + npc("Somehow this fool had actually managed to obtain the god-staff of Armadyl!") + npc("Its power was incredible, you could almost feel the energies crackling around it in the air!") + player("So what happened then?") + npc("Well, with such a weapon, the plans we had been developing for a rebellion against our lord could finally be put into action, but we knew that we would have to act swiftly, before he heard that we had a weapon") + npc("capable of defeating him, and we would have to act decisively, for even amongst our group there were still those loyal to the lord - such as that pathetic fool Azzanadra.") + player("So JUST WHO WAS this lord you speak of?") + npc("And I tell thee again, I will say when it is appropriate, now do not disrupt my tale!") + player("Okay, carry on then...") + npc("So anyway, Lord Zamorak and his most trusted compatriots, namely myself, Hazeel, Drakan, Thammaron and Zemouregal made plans to overthrow our lord using the god-weapon, and by pledging") + npc("allegiance to Zamorak as our master, were each to be given a large piece of land as our own in return.") + npc("We decided to move immediately, before anyone got cold feet, or any other parties could interfere in our work, and made haste towards the castle where our Lord lived.") + npc("If Lucien had not been otherwise occupied, he would have probably accompanied us with his magicks, but it turned out the foolish Dhalak had made his involvement unnecessary with some spells of his own allowing us to") + npc("get close enough to the castle with the staff without the Empty Lord being able to sense its presence.") + player("So your lord was the one that cursed you?") + npc("I am coming to that... So anyway, we made our way to the castle, under the pretense that we had war plans against Saradomin and the other deities to discuss.") + npc("As usual, our lord was guarded well, but this was why Zamorak had brought his most trusted fighters with him.") + npc("While we distracted the Empty Lord with our feints and attacks, and kept his bodyguards busy, Lord Zamorak outflanked him, unsheathed the staff and plunged it into his back!") + npc("Ah, it was a glorious sight... At that moment I was reminded for whom I fought, and why General Zamorak had earned his nickname 'the scourge' upon the battlefield...") + player("And the next thing you know you were cursed?") + npc("No, it was not quite that simple... The Empty Lord turned away from our battle, eyes burning with hatred, and towards Zamorak instead. Seeing this, we all fought with extra vigour, so that") + npc("General Zamorak would not face our lord alone, but we were outnumbered by many hundreds of warriors and demons, and could not reach him to assist him!") + player("So what then?") + npc("Why, it was the Empty Lord versus Zamorak, in single combat! And the sight of the battle will be with me forever more...") + npc("The Empty Lord was a powerful god, stronger than any of the others awake at that time, possibly even as strong as Guthix is, and Zamorak was but a mortal: A Mahjarrat warrior all the same, with all of the") + npc("strength and power that that entails, but mortal nonetheless, but to see him fight, you would not think of him as a 'mere' anything...") + npc("He was war itself! Flurry after flurry of blows he rained upon the Empty Lord, and the very castle walls shook and quivered with their power, but the Empty Lord would not fall!") + npc("Even with the weapon of a god embedded in his back, he fought on, and with each blow our victory seemed less and less certain...") + player("So what then?") + npc("Well, then a miracle happened. Or luck. Or natural justice.") + npc("You can call it what you want, but as the Empty Lords hands wrapped tightly around Zamorak's throat, Lord Zamorak, kicking and screaming defiantly and radiant in his anger until the very last, plunged towards the") + npc("Empty Lord, who seemed to lose his footing slightly, and fell in such a way so that the staff plunged deeper into his body, but also impaled Lord Zamorak with it at the same time...") + npc("And then...") + player("And then what?") + npc("And then nothing. There was a sudden flash of bright light, and then a sudden blink of cold darkness, and it was over.") + npc("Zamorak stood over the Empty Lord who was slowly... fading from existence... And as he faded, it seemed as though... It almost seemed as though Zamorak became more real,") + npc("more solid than he had been before...") + npc("And as the Empty Lord faded from this world completely, I heard his voice, almost a whisper upon the wind, cursing all who had helped Zamorak in his victory, which as you now tell me seems to have been all who") + npc("were responsible for the staff ending up in Zamorak's hands at the castle.") + npc("As I heard it, I saw that I too was fading, just as the Empty Lord had, and I called to my brethren for their assistance, but they could no longer hear my words, nor see my form.") + npc("It was then that the other gods appeared and banished Zamorak from the world completely for daring to kill one of their kind, although as it turned out it didn't quite work out that way for them, when he returned") + npc("stronger than ever, a god himself.") + npc("But the god wars were another story entirely...") + player("But... I don't understand... If it was Zamorak who used the weapon, then why was it only you who were cursed?") + player("And the other people who were cursed, why them? Why not the other Mahjarrat for example?") + player("And just who was this 'Empty Lord' you keep speaking of?") + npc("Well, in my life I was nothing but a warrior. I had no hidden knowledge, I didn't especially care about the gods or their magics, and I certainly didn't respect them.") + npc("Now in my... I suppose this is my death. I am but a shade on the wind, unnoticed by all who pass me, until today anyway, and the only answer I can give you is that the others who were with me, the") + npc("Mahjarrats and the Vampyre, they were beings of magic.") + npc("It runs through their very veins, and ebbs through their bones.") + npc("Who knows why the curse fell as it did? Perhaps as a mere human I was more susceptible to it, when they were not. Perhaps they too are cursed, but their life spans are so") + npc("long that it will be millennia before they feel it upon them. Perhaps because it did not affect them, it extended backwards through time, to the moment the staff was") + npc("taken from its rightful place, and all who had known of its theft were cursed too. Perhaps there are others also cursed, who played no part in this tale, and were merely unlucky enough to be") + npc("in the wrong place at the wrong time...") + npc("I don't know. Things do not always happen for a reason, just as tales do not always end with all of the loose ends neatly tied up and all answers supplied.") + npc("I have simply told you the events I was witness to, for I can do no more.") + npc("You have cheered me no end to let me know that this curse that has afflicted me has not left me alone here, in this void between worlds.") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeViggoraSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_CLOAK_6111) + } + npc("Perhaps I will hunt down these others who have also been cursed as I was, but I feel I must reward you for your efforts; Here, take my cloak, it is drenched in the blood of a") + npc("thousand foes, and may bring you luck in battle.") + player("So how can I break this curse?") + npc("Who knows? If it was the death curse of the Empty Lord, there may be no way to break it.") + npc("If it was not his death curse, and he is still alive but not on this world, then the only way to break it may be to bring him back here;") + npc("But I would rather stay cursed than suffer under his rule again...") + player("But WHO was this 'Empty Lord'? WHAT was his NAME?") + npc("You do not know? You have not guessed yet?") + npc("He was Zaros.") + + label("subsequenttime") + player("Hello.") + npc("Hello yourself.") + player("I really liked your little story. Can you tell me another one?") + player("Preferably something with a big fight and lots of explosions!") + npc("...You are a very strange young @g[man,woman].") + + label("lostghostlything") + player(ChatAnim.SAD, "Can I have that cloak back?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_CLOAK_6111) + } + npc("Hmph.", "I suppose.") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt index 79a033158..397cd052f 100644 --- a/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt +++ b/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt @@ -1,102 +1,211 @@ -package rs09.game.content.dialogue.region.lletya +package content.region.desert.quest.deserttreasure -import core.api.setQuestStage +import content.global.handlers.iface.BookInterface +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player -import core.game.node.entity.skill.Skills import core.plugin.Initializable +import org.rs09.consts.Items import org.rs09.consts.NPCs -/** - * @author qmqz - */ - @Initializable +/** Known in RS3 as Asgarnia Smith */ class ArchaeologistDialogue(player: Player? = null) : DialoguePlugin(player){ - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - if (!player.questRepository.hasStarted("Desert Treasure")) { - if (player.questRepository.isComplete("The Digsite Quest") && - player.questRepository.isComplete("The Tourist Trap") && - player.questRepository.isComplete("The Temple of Ikov") && - player.questRepository.isComplete("Priest In Peril") && - player.questRepository.isComplete("Waterfall Quest") && - player.questRepository.isComplete("Troll Stronghold") && - player.skills.getStaticLevel(Skills.SLAYER) >= 10 && - player.skills.getStaticLevel(Skills.FIREMAKING) >= 50 && - player.skills.getStaticLevel(Skills.MAGIC) >= 50 && - player.skills.getStaticLevel(Skills.THIEVING) >= 53 ) { - player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } - } else { - player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 999 } - } - - } else { - - } - - return true - } - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - - 999 -> sendDialogue("He seems to be lost in his own thoughts...").also { stage = 99 } - - 0 -> npc(FacialExpression.FRIENDLY, "Howdy stranger. What brings you out to these parts?").also { stage++ } - 1 -> options("What are you doing here?", "Do you have any quests?", "Who are you?", "Nothing really.").also { stage++ } - 2 -> when (buttonId) { - //1 -> todo - 2 -> player(FacialExpression.FRIENDLY, "Do you have any quests?", "Call it a hunch, but you look like the type of man who", "might...").also { stage = 20 } - //3 -> todo - //4 -> todo - } - - 20 -> npc(FacialExpression.HALF_THINKING, "Well, it's funny you should say that.", - "I'm not sure if I would really call it a quest as such,", - "but I found this ancient stone tablet in one of my", - "excavations, and it would really help me out if you").also { stage++ } - 21 -> npc(FacialExpression.FRIENDLY, "could go and take it back to the digsite for me and get", - "it examined.").also { stage++ } - 22 -> npc(FacialExpression.NEUTRAL, "It's very old, and I don't recognise and of the", - "inscriptions on it.").also { stage++ } - 23 -> options("Yes, I'll help you.", "No thanks, I don't want to help.").also { stage++ } - 24 -> when(buttonId) { - 1 -> player(FacialExpression.FRIENDLY, "Sure, I was heading that way anyways.", - "Any particular person at the digsite you want me to", - "talk to?").also { stage = 30 } - // 2 -> todo - } - - 30 -> npc(FacialExpression.NEUTRAL, "His name's Terry Balando. Give it to nobody but him.", - "I'm sorry, I can't entrust you with the actual tablet I", - "found, but it is far too valuable to give away, but I took", - "these etchings - they should be enough for him to make").also { stage++ } - 31 -> npc(FacialExpression.NEUTRAL, "a preliminary translation on.", - "Come back and let me know what he says, I would hate", - "to waste my time excavating anything that isn't worth", - "my time as a world famous archaeologist!").also { - player.questRepository.getQuest("Desert Treasure").start(player) - setQuestStage(player, "Desert Treasure", 1) - stage = 99 - } - - - - - 99 -> end() - } - return true + openDialogue(player!!, ArchaeologistDialogueFile(), npc) + return false } - override fun newInstance(player: Player?): DialoguePlugin { return ArchaeologistDialogue(player) } - override fun getIds(): IntArray { return intArrayOf(NPCs.ARCHAEOLOGIST_1918) } } + +class ArchaeologistDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0) + .player(FacialExpression.FRIENDLY,"Hello there.") + .branch { player -> + return@branch if (DesertTreasure.hasRequirements(player)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(0) + .line("He seems to be lost in his own thoughts...") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .npc(FacialExpression.FRIENDLY, "Howdy stranger. What brings you out to these parts?") + .let { path -> + val originalPath = b.placeholder() + path.goto(originalPath) + originalPath.builder().options().let { optionBuilder -> + optionBuilder.option("What are you doing here?") + .player("Nothing much - What are you doing here?", "It doesn't seem like there's much to do out here in the", "desert!") + .npc("Well, that's where you'd be wrong.", "I work for the Archaeological Society of Varrock, and", "have been excavating around here recently.") + .npcl("Was there something you specifically wanted?") + .goto(originalPath) + optionBuilder.option("Do you have any quests?") + .player(FacialExpression.FRIENDLY, "Do you have any quests?", "Call it a hunch, but you look like the type of man who", "might...") + .npc(FacialExpression.HALF_THINKING, "Well, it's funny you should say that.", "I'm not sure if I would really call it a quest as such,", "but I found this ancient stone tablet in one of my", "excavations, and it would really help me out if you") + .npc(FacialExpression.FRIENDLY, "could go and take it back to the digsite for me and get", "it examined.") + .npc(FacialExpression.NEUTRAL, "It's very old, and I don't recognise and of the", "inscriptions on it.") + .options().let { optionBuilder2 -> + optionBuilder2.option("Yes, I'll help you.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.ETCHINGS_4654) + } + .player("Sure, I was heading that way anyway.", "Any particular person at the digsite you want me to", "talk to?") + .npc(FacialExpression.NEUTRAL, "His name's Terry Balando. Give it to nobody but him.", "I'm sorry, I can't entrust you with the actual tablet I", "found, but it is far too valuable to give away, but I took", "these etchings - they should be enough for him to make") + .npc(FacialExpression.NEUTRAL, "a preliminary translation on.", "Come back and let me know what he says, I would hate", "to waste my time excavating anything that isn't worth", "my time as a world famous archaeologist!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 0) { + setQuestStage(player, DesertTreasure.questName, 1) + } + } + optionBuilder2.option("No thanks, I don't want to help.") + .playerl("No thanks. Playing delivery boy doesn't really sound like much fun to me. ") + .npcl(" Well, okay. Can't say as I blame you for thinking that. I'll go take it there myself later I guess.") + .end() + } + optionBuilder.option("Who are you?") + .playerl(FacialExpression.THINKING, "Who are you, anyway?") + .npc(FacialExpression.EXTREMELY_SHOCKED, "You don't recognize me???", "I am the world famous Asgarnia Smith, Archaeologist", "extraordinaire!") + .npc(FacialExpression.HALF_THINKING, "I am the one who discovered the long forgotten", "Temple of Ikov!", "The one who unearthed the strange trap filled arena", "in Brimhaven!") + .npc(FacialExpression.HALF_THINKING, "I'm the leading archaeological expert of our time!", "I was voted archaeologist of the year four years", "running by the Varrock Herald! Are you REALLY", "sure you've never heard of me?") + .playerl(FacialExpression.THINKING, "No, I really haven't.") + .npc(FacialExpression.EXTREMELY_SHOCKED, "Well then, I'm confused.", "Why did you come over and speak to me if you don't", "know who I am? What do you want?") + .goto(originalPath) + optionBuilder.option("Nothing really.") + .playerl("Nothing really. I'm just wandering around for no good reason.") + .npcl("Uh-huh. Well, if you'll excuse me, I have a lot more work to do before I can bed down for the night.") + .end() + } + } + + + b.onQuestStages(DesertTreasure.questName, 1,2) + .npcl("So what did Terry Balando say about those etchings? Did he give you a translation for me?") + .playerl("Um...yeah...about that... I kind of didn't go and speak to him yet...") + .npcl("Well what are you waiting for? A written invitation? All I want you to do is take those etchings up to the digsite for me!") + .playerl("Okay, I'll do that then.") + .end() + + b.onQuestStages(DesertTreasure.questName, 3) + .playerl("Hello there.") + .npcl("So what did Terry Balando say about those etchings? Did he give you a translation for me?") + .branch { player -> + return@branch if (inInventory(player, Items.TRANSLATION_4655)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(0) + .playerl("Yeah, he did. But I don't have it with me.") + .npcl("...") + .npcl("I see.") + .npcl("Well could you go and get me that translation? It could be vital!") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .playerl("Yeah, he did. I have it here in this book.") + .npcl("Did you take a read of this? It will do you good to understand how this profession works. Here, have a read.") + .options().let { optionBuilder -> + optionBuilder.option("Read book") + .endWith { _, player -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, TranslationBook.Companion::display) + } + return@let optionBuilder + } + .option("Don't read book") + .playerl("Yeah, I did. Kind of boring really.") + .npcl("Excellent. Just give me a moment to read this, and talk to me again in a second.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 3) { + removeItem(player, Items.TRANSLATION_4655) // remove if exists + setQuestStage(player, DesertTreasure.questName, 4) + } + } + + b.onQuestStages(DesertTreasure.questName, 4) + .playerl("Hello there.") + .npcl("Hmmm. Interesting. It seems to me like there's some kind of treasure hidden out in the desert.") + .npcl("So what do you say? Fancy being a treasure hunter like me?") + .playerl("Uh... don't you mean archaeologist?") + .npcl("Yeeees... An archaeologist...") + .npcl("It's all this hot sun getting to me I think.") + .npcl("Well anyway, let's just assume there is a treasure hidden in the desert somewhere, and let's just say for the sake of argument that maybe if I found a big stash of gold and treasure I wouldn't necessarily just hand it") + .npcl("all over to the Museum of Varrock.") + .npcl("Let's also say, purely hypothetically, that if there were such a big stash of treasure and someone were to help me find it, then that hypothetical personal might be entitled to, oh, let's say a purely for the sake of") + .npcl("argument thirty percent split...") + .playerl("Fifty percent.") + .npcl("That's right!") + .npcl("A purely for the sake of argument fifty-fifty split on this hypothetical treasure, should it exist...") + .npcl("Do you see where I'm going with this?") + .playerl("You want me to help you find some treasure for a fifty percent share, as long as I don't tell anybody, and your reputation as an esteemed archaeologist with the Museum of Varrock remains intact, and nobody") + .playerl("discovers you're actually just a treasure hunter?") + .npcl("Uh... yes, but the way you said it makes it sound like I'm doing something wrong...") + .npcl("So what do you say? Partners?") + .options() + .let { optionBuilder -> + optionBuilder.option("Help him") + .playerl("Well... I guess nobody is really going to lose out on anything, and we don't even know if there is any treasure...") + .playerl("Aw, go on then. Count me in.") + .npcl("Good @g[lad,lass]! Well, if we split up we'll be able to find treasure quicker.") + .npcl("I'll continue searching around here in this Bedabin Camp, you head due South to the Bandit Village. If either of us find anything, we'll come find each other and say what, okay?") + .npcl("You head due South, see what you can find out about this tablet.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 4) { + setQuestStage(player, DesertTreasure.questName, 5) + } + } + optionBuilder.option("Don't help him") + .playerl("This all sounds very immoral, and I don't want any part of your seedy little schemes.") + .npcl("Aw, c'mon, cut me a break here man! Look, nobody is really getting hurt, right? This treasure is either going to lie around in some underground ruin, or lie around in some museum for") + .npcl("people to look at!") + .npcl("It makes sense for the people to go to all the risk to get a little payback for it, right? Besides, anything of real historical value we can hand over to the museum - we'll just keep the cash for") + .npcl("ourselves!") + .npcl("C'mon... what do you say? Partners?") + .options() + .let { optionBuilder -> + optionBuilder.option("Help him") + .playerl("Well... I guess nobody is really going to lose out on anything, and we don't even know if there is any treasure...") + .playerl("Aw, go on then. Count me in.") + .npcl("Good @g[lad,lass]! Well, if we split up we'll be able to find treasure quicker.") + .npcl("I'll continue searching around here in this Bedabin Camp, you head due South to the Bandit Village. If either of us find anything, we'll come find each other and say what, okay?") + .npcl("You head due South, see what you can find out about this tablet.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 4) { + setQuestStage(player, DesertTreasure.questName, 5) + } + } + optionBuilder.option("Don't help him") + .playerl("I don't trust anything about your little scheme, including you! I want nothing to do with this!") + .npcl("Eh, you'll come running back when you realize just how much money we could be talking here.") + .npcl("I'll see you again when you come crawling back, begging to be cut in on the deal.") + .end() + } + } + + b.onQuestStages(DesertTreasure.questName, 5) + .playerl("Hello there.") + .npcl("Hello again. You find any signs of that treasure yet?") + .playerl("Not yet...") + .npcl("Well, head south to that bandit camp. I bet if there's anything out here, they'll know about it. Don't let on it might be valuable though! Those thieves will steal it as soon as look at you!") + + b.onQuestStages(DesertTreasure.questName, 6,7,8) + .playerl("Hello there.") + .npcl("Hello again. You find any signs of that treasure yet?") + .playerl("Not as such... Although I think I'm onto something of a promising lead...") + .playerl("Did you ever hear of something called the Diamonds of Azzanadra?") + .npcl("Diamonds of Azzanadra? That sounds very promising indeed!") + .playerl("So you have heard of them?") + .npcl("Nope, never heard of them before, but you said diamonds! Diamonds are always promising!") + + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/AzzanadraDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/AzzanadraDialogue.kt new file mode 100644 index 000000000..c8401ac87 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/AzzanadraDialogue.kt @@ -0,0 +1,59 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class AzzanadraDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, AzzanadraDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return AzzanadraDialogue(player) + } + override fun getIds(): IntArray { + /* This is wrong SCARABS_1970 should be AZZANADRA_1970 */ + return intArrayOf(NPCs.SCARABS_1970, NPCs.AZZANADRA_1971) + } +} + +class AzzanadraDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 10) + .npcl(FacialExpression.OLD_DEFAULT, "I knew they could not trap me here for long!") + .npcl(FacialExpression.OLD_DEFAULT, "Well done, soldier, tell me, how goes the battle?") + .playerl(FacialExpression.THINKING, "Battle?") + .npcl(FacialExpression.OLD_DEFAULT, "You do not know of the battle?") + .npcl(FacialExpression.OLD_DEFAULT, "More time must have passed than I had thought...") + .npcl(FacialExpression.OLD_DEFAULT, "Tell me, what news of great Paddewwa? Do the shining spires of Lassar still stand? And what of glorious Annakarl? The fortress is still intact?") + .player("Uh...", "Sorry, I've never heard of them...") + .npcl(FacialExpression.OLD_SAD, "No!") + .npcl(FacialExpression.OLD_SAD, "My lord... What has become of you? I cannot hear your voice in my mind anymore!") + .npcl(FacialExpression.OLD_DEFAULT, "My thanks to you brave warrior for your help in freeing me from this accursed tomb, but it seems I have much to do to make amends.") + .npcl(FacialExpression.OLD_DEFAULT, "If the shining cities no longer stand, then it means that we must have failed my lord...") + .npcl(FacialExpression.OLD_DEFAULT, "How long have I been trapped here? Master... Have you truly been dispatched from this world?") + .npcl(FacialExpression.OLD_DEFAULT, "Warrior, for your efforts in freeing me, I offer you the gift of knowledge.") + .npcl(FacialExpression.OLD_DEFAULT, "I bestow upon you the ancient magicks, taught me by my Lord before his disappearance, may you use them well in battle for our people!") + .npcl(FacialExpression.OLD_DEFAULT, "They will replace the knowledge you previously had, but you may switch between them by praying at the altar in this room at any time.") + .npcl(FacialExpression.OLD_DEFAULT, "I trust that we shall meet again adventurer, I offer you the blessings of myself and my master in all of your endeavours!") + .npcl(FacialExpression.OLD_DEFAULT, "Now, I must leave you, for there must be some trace of my master's power left somewhere. Feel free to use the portal I shall create to return here easily in the future!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 10) { + sendMessage(player,"A strange wisdom has filled your mind...") + finishQuest(player, DesertTreasure.questName) + player.spellBookManager.setSpellBook(SpellBookManager.SpellBook.ANCIENT) + player.spellBookManager.update(player) + } + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/BartenderDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/BartenderDialogue.kt new file mode 100644 index 000000000..2e3e78954 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/BartenderDialogue.kt @@ -0,0 +1,155 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BartenderDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, BartenderDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return BartenderDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BARTENDER_1921) + } +} +class BartenderDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4) + .npcl(FacialExpression.ANNOYED, "Get out of here. I have nothing to say to the likes of you.") + .end() + + b.onQuestStages(DesertTreasure.questName, 5) + .branch { player -> + return@branch if (getAttribute(player, DesertTreasure.attributeBoughtBeer, false)) { 1 } else { 0 } + }.let{ branch -> + branch.onValue(1) + .npcl("You've had your drink, now get out of here. I have nothing to say to the-") + .playerl("No, Wait! Look, I'm here on an archaeological expedition for the Museum of Varrock.") + .playerl("I am only here looking for artefacts...") + .npcl("Oh really? Our inheritance is only sand and death. What do you expect to find out here in this desert forsaken by the gods?") + .options() + .let { optionBuilder -> + optionBuilder.option("I heard about treasure...") + .playerl("As I understand it there's some kind of hidden treasure in these parts...") + .npcl("Look around @g[pal,lady]. Does it looks like there's any treasure near here?") + .npcl("If I were you I'd get lost before someone takes a dislike to your face and removes it for you.") + .end() + + optionBuilder.option("I heard about four diamonds...") + .playerl("I heard a rumour about four diamonds or crystals...") + .npcl("The four diamonds of Azzanadra??? How came you to know of this?") + .playerl("You've heard of them then?") + .npcl("It's just a fairy tale for children. Maybe one of the village elders might know more, but it's not really something I care about.") + .npcl("Now get out of here, your sort isn't welcome in my bar.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 5) { + setQuestStage(player, DesertTreasure.questName, 6) + } + } + + optionBuilder.option("I heard about a fortress...") + .playerl("Certain things have led me to believe there may be some kind of ruined fortress around here...") + .npcl("Doubt it. What in the world would someone need to guard against in the middle of this desert?") + .npcl("A bad attack of sand? I think you're on the wrong track, mister so-called archaeologist.") + .end() + } + + branch.onValue(0) + .npcl("If you're not buying anything, I have nothing to say to you.") + .options() + .let { optionBuilder -> + optionBuilder.option("Ask about Desert Treasure") + .playerl("As I understand it there's some kind of hidden treasure in these parts...") + .npcl("Look around @g[pal,lady]. Does it looks like there's any treasure near here?") + .npcl("If I were you I'd get lost before someone takes a dislike to your face and removes it for you.") + .end() + optionBuilder.option("Buy a drink") + .branch { player -> + return@branch if (inInventory(player, Items.COINS_995, 650)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("What's that? You wanna buy a beer? It'll cost ya 650 coins.") + .options() + .let { optionBuilder -> + optionBuilder.option("Buy a beer") + .betweenStage { _, player, _, _ -> + if (removeItem(player, Item(Items.COINS_995, 650))) { + addItemOrDrop(player, Items.BANDITS_BREW_4627) + setAttribute(player, DesertTreasure.attributeBoughtBeer, true) + } + } + .npcl("There you go. Now get out, we don't like your sort around here.") + .end() + optionBuilder.option("Don't buy anything") + .npcl("Get out of my bar then! We don't like your sort round here!") + .end() + } + + branch.onValue(0) + .npcl("You ain't got the 650 coins it costs to buy it, and I'm glad 'cos I didn't want to serve you anyway.") + .end() + } + + } + } + + + b.onQuestStages(DesertTreasure.questName, 6,7,8,9,10,11) + .branch { player -> + return@branch if (getAttribute(player, DesertTreasure.attributeBoughtBeer, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("You've had your drink, now get out of here. I have nothing to say to the-") + .playerl("No, Wait! Look, I'm here on an archaeological expedition for the Museum of Varrock.") + .playerl("I am only here looking for artefacts...") + .npcl("Oh really? Our inheritance is only sand and death. What do you expect to find out here in this desert forsaken by the gods?") + .options() + .let { optionBuilder -> + optionBuilder.option("I heard about treasure...") + .playerl("As I understand it there's some kind of hidden treasure in these parts...") + .npcl("Look around @g[pal,lady]. Does it looks like there's any treasure near here?") + .npcl("If I were you I'd get lost before someone takes a dislike to your face and removes it for you.") + .end() + + optionBuilder.option("I heard about four diamonds...") + .playerl("I heard a rumour about four diamonds or crystals...") + .npcl("The four diamonds of Azzanadra??? How came you to know of this?") + .playerl("You've heard of them then?") + .npcl("It's just a fairy tale for children. Maybe one of the village elders might know more, but it's not really something I care about.") + .npcl("Now get out of here, your sort isn't welcome in my bar.") + .end() + + optionBuilder.option("I heard about a fortress...") + .playerl("Certain things have led me to believe there may be some kind of ruined fortress around here...") + .npcl("Doubt it. What in the world would someone need to guard against in the middle of this desert?") + .npcl("A bad attack of sand? I think you're on the wrong track, mister so-called archaeologist.") + .end() + + optionBuilder.option("I heard of the Diamonds of Azzanadra.") + .playerl("Tell me all you know about the Diamonds of Azzanadra.") + .npcl("Not that I think it's any of your business, but when I was a child I remember hearing the legend.") + .npcl("I don't recall it particularly well, other than they are said to contain an incredible power.") + .npcl("If you really want to hear more about it you'd be best off finding someone who cares about the past, and the history of this area, and stop bothering me.") + .end() + } + } + + b.onQuestStages(DesertTreasure.questName, 100) + .npcl("So you're the @g[fella,lass] that freed Azzanadra, huh? Fair play to ya. What will you have?") + .end() + + } +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DamisBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DamisBehavior.kt new file mode 100644 index 000000000..1b996dafc --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DamisBehavior.kt @@ -0,0 +1,81 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) { + private var disappearing = false + + override fun tick(self: NPC): Boolean { + if (disappearing) { + return true + } + val player: Player? = getAttribute(self, "target", null) + if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) { + if (player != null && !disappearing) { + disappearing = true + sendMessage(player, "Damis has vanished once more into the shadows...") + removeAttribute(player, DesertTreasure.attributeDamisInstance) + } + poofClear(self) + } + return true + } + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints && self.id == NPCs.DAMIS_1974) { + state.estimatedHit = self.skills.lifepoints + 1 + state.secondaryHit = -1 + + transformNpc(self, NPCs.DAMIS_1975, 500) + self.skills.lifepoints = self.skills.maximumLifepoints + sendChat(self, "Armour... is for restraint, not... protection...") + queueScript(self, 2, QueueStrength.NORMAL) { stage: Int -> + sendChat(self, "Now I show... you... my true power!") + self.properties.attackSpeed = 3 + return@queueScript stopExecuting(self) + } + } + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + // In second form, drain prayer by 5. + if (self.id == NPCs.DAMIS_1975) { + victim.skills.decrementPrayerPoints(5.0) + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (self.id == NPCs.DAMIS_1975) { + if (DesertTreasure.getSubStage(killer, DesertTreasure.attributeShadowStage) == 3) { + GroundItemManager.create(Item(Items.SHADOW_DIAMOND_4673), self.location, killer) + DesertTreasure.setSubStage(killer, DesertTreasure.attributeShadowStage, 100) + removeAttribute(killer, DesertTreasure.attributeFareedInstance) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt index f42498ac6..f23f6e024 100644 --- a/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt @@ -1,103 +1,544 @@ -//package rs09.game.content.quest.members.deserttreasure +package content.region.desert.quest.deserttreasure -//import core.game.node.entity.player.Player -//import core.game.node.entity.player.link.quest.Quest -//import core.game.node.entity.skill.Skills -//import core.plugin.Initializable +import content.data.Quests +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items /** - * @author qmqz + * Desert Treasure Quest + * + * https://www.youtube.com/watch?v=INaSdOAHdT8: Jesus fucking devil best shit on planet fuckall 31:57 + * https://www.youtube.com/watch?v=LAoOISdsX4w: This guy did the best initial quest journal and then ignored the rest. + * https://www.youtube.com/watch?v=3cyU36qNBpI: one impt quest log part in the front. + * https://www.youtube.com/watch?v=pY-Czja2lE4: Good shit part 2 6:24 + * https://www.youtube.com/watch?v=NB1-m_hoTPk: Blur ass quest log. + * https://www.youtube.com/watch?v=bcy54b6NnJs: Blur ass quest log. + * https://www.youtube.com/watch?v=J_dfMXFz3WQ: Blur ass quest log. + * https://www.youtube.com/watch?v=7n0OcHUNFHc: Blur ass quest log 1:07. + * https://www.youtube.com/@Gunz4Range/videos + * https://www.youtube.com/watch?v=baQ6oJOk7Gc + * https://www.youtube.com/watch?v=u0C2zW6mrcc: Blur ass ending quest log 3:23 + * https://www.youtube.com/watch?v=SUzM0WKY6jk: 1:03 + * https://www.youtube.com/watch?v=3AA5fkkBW-I: 2:05 + * + * https://www.youtube.com/watch?v=ofRV2-h3Dug: 17:21 27:45 + * + * if (VARPBIT[358] == 15) return 2; if (VARPBIT[358] == 0) return 0; return 1; }; if (arg0 == 13) */ +@Initializable +class DesertTreasure : Quest(Quests.DESERT_TREASURE,45, 44, 3, 440, 358, 0, 1, 15){ -//@Initializable -//class DesertTreasure : Quest("Desert Treasure",15, 44, 3, 440, 0, 1, 15){ + companion object { + val questName = Quests.DESERT_TREASURE + /** This is an important varbit as it is literally controlling the Quest varbit (440 Varp 0-14 bits -> 358 Varbit )*/ + const val varbitDesertTreasure = 358 // 10-15-Eblis 1924 shows up other values Eblis disappears. This is tied to the quest. - //override fun drawJournal(player: Player?, stage: Int) { - // super.drawJournal(player, stage) - // var line = 12 + // Desert Treasure Start + const val attributeBoughtBeer = "/save:quest:deserttreasure-boughtbeer" + const val attributeCountMagicLogs = "/save:quest:deserttreasure-countmagiclogs" + const val attributeCountSteelBars = "/save:quest:deserttreasure-countsteelbars" + const val attributeCountMoltenGlass = "/save:quest:deserttreasure-countmoltenglass" + const val attributeCountBones = "/save:quest:deserttreasure-countbones" + const val attributeCountAshes = "/save:quest:deserttreasure-countashes" + const val attributeCountCharcoal = "/save:quest:deserttreasure-countcharocal" + const val attributeCountBloodRune = "/save:quest:deserttreasure-countbloodrune" + const val varbitMirrors = 392 // Set to 1 to show mirrors, they are cactuses before desert treasure. - //val stage = player?.questRepository?.getStage("Desert Treasure")!! + // Blood Diamond + const val attributeBloodStage = "/save:quest:deserttreasure-bloodstage" + const val attributeDessousInstance = "quest:deserttreasure-dessousinstance" - //when (stage) { - // 0 -> { - // line(player,"I can start this quest by speaking to !!The Archaeologist??", line++) - // line(player,"who is exploring the !!Bedabin Camp?? South West of the", line++) - // line(player,"!!Shantay Pass.??", line++) - // line(player,"To complete this quest I will need:", line++) - // if (player.skills.getStaticLevel(Skills.SLAYER) < 10) { - // line(player,"Level 10 Slayer", line++) - // } else { - // line(player,"---Level 10 Slayer/--", line++) - // } - // if (player.skills.getStaticLevel(Skills.SLAYER) < 10) { - // line(player,"Level 50 Firemaking", line++) - // } - // if (player.skills.getStaticLevel(Skills.SLAYER) < 10) { - // line(player,"Level 50 Magic", line++) - // } - // if (player.skills.getStaticLevel(Skills.SLAYER) < 10) { - // line(player,"Level 53 Thieving", line++) - // } - // line(player,"I must have completed the following quests:", line++) + // Smoke Diamond + const val attributeSmokeStage = "/save:quest:deserttreasure-smokestage" + const val attributeUnlockedGate = "/save:quest:deserttreasure-unlockedgate" + const val attributeFareedInstance = "quest:deserttreasure-fareedinstance" + const val varbitStandingTorchNorthEast = 360 // North East standing torch 6406 + const val varbitStandingTorchSouthEast = 361 // South East standing torch 6408 + const val varbitStandingTorchSouthWest = 362 // South West standing torch 6410 + const val varbitStandingTorchNorthWest = 363 // North West standing torch 6412 - // if (player.questRepository.isComplete("The Digsite Quest")) { - // line(player,"---!!The digsite Quest??/--", line++) - // } else { - // line(player,"!!The digsite Quest??", line++) - // } + // Ice Diamond + const val attributeIceStage = "/save:quest:deserttreasure-icestage" + const val attributeTrollKillCount = "/save:quest:deserttreasure-iciclecount" + const val attributeKamilInstance = "quest:deserttreasure-kamilinstance" + const val varbitFrozenFather = 380 // 0-frozen 1-defrosted | Base: 1943 Iced: 1944 Broke: 1948 Reunion: 1947 + const val varbitFrozenMother = 381 // 0-frozen 1-defrosted | Base: 1945 Iced: 1946 Broke: 1950 Reunion: 1949 + const val varbitChildReunite = 382 // 0-frozen 4-reunited 5-reunited 6-varbitfails/ends (This varbit seems to manage ice stages...) + // 0 - start, 1 - feed the crying child, 2 - fought kamil, 3 - unfreeze dad/mum, 4 - reunite, 5 - all chat complete. + const val varbitCaveEntrance = 378 // 6446 0 - 6 6441 - // if (player.questRepository.isComplete("The Tourist Trap")) { - // line(player,"---!!The Tourist Trap??/--", line++) - // } else { - // line(player,"!!The Tourist Trap??", line++) - // } + // Shadow Diamond + const val attributeShadowStage = "/save:quest:deserttreasure-shadowstage" + const val attributeDamisWarning = "quest:deserttreasure-damiswarning" + const val attributeDamisInstance = "quest:deserttreasure-damisinstance" + const val varbitRingOfVisibility = 393 // Set to 1 to show ladder and other cool stuff when wearing ring of visibility. - // if (player.questRepository.isComplete("The Temple of Ikov")) { - // line(player,"---!!The Temple of Ikov??/--", line++) - // } else { - // line(player,"!!The Temple of Ikov??", line++) - // } + // Desert Treasure End + const val attributeBloodDiamondInserted = "/save:quest:deserttreasure-blooddiamondinserted" + const val attributeSmokeDiamondInserted = "/save:quest:deserttreasure-smokediamondinserted" + const val attributeIceDiamondInserted = "/save:quest:deserttreasure-icediamondinserted" + const val attributeShadowDiamondInserted = "/save:quest:deserttreasure-shadowdiamondinserted" + const val varbitBloodObelisk = 390 + const val varbitSmokeObelisk = 387 + const val varbitIceObelisk = 389 + const val varbitShadowObelisk = 388 - // if (player.questRepository.isComplete("Priest In Peril")) { - // line(player,"---!!Priest In Peril??/--", line++) - // } else { - // line(player,"!!Priest In Peril??", line++) - // } + fun completedAllSubstages(player: Player): Boolean { + return getSubStage(player, attributeBloodStage) == 100 && + getSubStage(player, attributeSmokeStage) == 100 && + getSubStage(player, attributeIceStage) == 100 && + getSubStage(player, attributeShadowStage) == 100 + } - // if (player.questRepository.isComplete("Waterfall Quest")) { - // line(player,"---!!Waterfall Quest??/--", line++) - // } else { - // line(player,"!!Waterfall Quest??", line++) - // } + fun getSubStage(player: Player, attributeName: String): Int { + return getAttribute(player, attributeName, 0) + } - // if (player.questRepository.isComplete("Troll Stronghold")) { - // line(player,"---!!Troll Stronghold??/--", line++) - // } else { - // line(player,"!!Troll Stronghold??", line++) - // } + fun setSubStage(player: Player, attributeName: String, value: Int) { + return setAttribute(player, attributeName, value) + } + + fun hasRequirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.SLAYER, 10), + hasLevelStat(player, Skills.FIREMAKING, 50), + hasLevelStat(player, Skills.MAGIC, 50), + hasLevelStat(player, Skills.THIEVING, 53), + isQuestComplete(player, Quests.THE_DIG_SITE), + isQuestComplete(player, Quests.THE_TOURIST_TRAP), + isQuestComplete(player, Quests.TEMPLE_OF_IKOV), + isQuestComplete(player, Quests.PRIEST_IN_PERIL), + isQuestComplete(player, Quests.WATERFALL_QUEST), + isQuestComplete(player, Quests.TROLL_STRONGHOLD), + ).all { it } + } + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, questName) > 0 + + if(!started){ + line(player,"I can start this quest by speaking to !!The Archaeologist??", line++) + line(player,"who is exploring the !!Bedabin Camp?? South West of the", line++) + line(player,"!!Shantay Pass??.", line++) + line(player,"To complete this quest I will need:", line++) + line(player, "Level 10 Slayer", line++, hasLevelStat(player, Skills.SLAYER, 10)) + line(player, "Level 50 Firemaking", line++, hasLevelStat(player, Skills.FIREMAKING, 50)) + line(player, "Level 50 Magic", line++, hasLevelStat(player, Skills.MAGIC, 50)) + line(player, "Level 53 Thieving", line++, hasLevelStat(player, Skills.THIEVING, 53)) + line(player,"I must have completed the following quests:", line++) // After - I have completed all of the required quests: + line(player, "The Digsite Quest", line++, isQuestComplete(player, Quests.THE_DIG_SITE)) + line(player, "The Tourist Trap", line++, isQuestComplete(player, Quests.THE_TOURIST_TRAP)) + line(player, "The Temple of Ikov", line++, isQuestComplete(player, Quests.TEMPLE_OF_IKOV)) + line(player, "Priest In Peril", line++, isQuestComplete(player, Quests.PRIEST_IN_PERIL)) + line(player, "Waterfall Quest", line++, isQuestComplete(player, Quests.WATERFALL_QUEST)) + line(player, "Troll Stronghold", line++, isQuestComplete(player, Quests.TROLL_STRONGHOLD)) + } else { + + if (stage >= 2) { + line(player, "I took some etchings of a stone tablet discovered by the", line++, true) + line(player, "archaeologist in the desert to Terry Balando at the", line++, true) + line(player, "Varrock digsite.", line++, true) + } else if (stage >= 1) { + line(player, "The !!archaeologist?? has given me some !!etchings from a??", line++, false) + line(player, "!!stone tablet?? that he discovered in the desert somewhere,", line++, false) + line(player, "and asked me to take it to an archaeological expert called", line++, false) + line(player, "!!Terry Balando?? at the Varrock !!digsite??.", line++, false) + } + + if (stage >= 4) { + line(player, "He made a rough translation, which I returned to the", line++, true) + line(player, "archaeologist.", line++, true) + } else if (stage == 3) { + line(player, "Terry Balando made some quick !!translation notes?? of the", line++, false) + line(player, "tablet and asked me to return them to the !!archaeologist?? in", line++, false) + line(player, "the !!Bedabin Camp??.", line++, false) + } else if (stage == 2) { + line(player, "I should get the !!translation notes?? from !!Terry Balando??", line++, false) + } + + if(stage >= 5) { + line(player, "The archaeologist I met in the desert seemed to think that", line++, true) + line(player, "there was some hidden treasure in the desert somewhere,", line++, true) + line(player, "I agreed to help him find it in return for a fifty percent", line++, true) + line(player, "share of whatever we found.", line++, true) + } else if (stage == 4) { + line(player, "I should find out what the !!archaeologist?? has to say about", line++, false) + line(player, "the !!translation notes??.", line++, false) + } + + if (stage >= 6) { + line(player, "I headed South and found a Bandit Camp.", line++, true) + } else if (stage >= 5) { + line(player, "I should head South to the !!Bandit Camp?? and try to find out", line++, false) + line(player, "more about this !!treasure??.", line++, false) + } + + if (stage >= 7) { + line(player, "I asked around the Bandit Camp and discovered someone", line++, true) + line(player, "who was willing to help me find the diamonds, by using a", line++, true) + line(player, "magic spell and some scrying glasses.", line++, true) + } else if (stage >= 6) { + line(player, "After some searching, the barman let slip some", line++, true) + line(player, "information about the 'Four Diamonds of Azzanadra'.", line++, true) + line(player, "I should ask around the !!Bandit Camp?? and see if anyone", line++, false) + line(player, "else has any information about the !!Four Diamonds of??", line++, false) + line(player, "!!Azzanadra??", line++, false) + } + + if (stage >= 10 || (stage >= 9 && completedAllSubstages(player))) { + // This disappears after you find all the diamonds. + } else if (stage >= 8) { + line(player, "I brought Eblis the ingredients so that he could cast the", line++, true) + line(player, "spell to see the places touched by the magic of the", line++, true) + line(player, "diamonds.", line++, true) + } else if (stage >= 7) { + // Crosses out gradually as you SUBMIT them. + line(player, "To make the scrying glasses I need to bring the following", line++, false) + // Crosses out with "I have brought him all xxx(6 Steel bars)" + line(player, "items to Eblis:", line++, false) + line(player, "!!12 Magic logs??", line++, false) + line(player, "!!6 Steel bars??", line++, false) + line(player, "!!6 Molten glass??", line++, false) + line(player, "To cast the spell I will need to bring Eblis:", line++, false) + // Crosses out with "I have brought him xxx(some bones)" + line(player, "!!Some bones??", line++, false) + line(player, "!!Some ash??", line++, false) + line(player, "!!Some charcoal??", line++, false) + line(player, "!!A blood rune??", line++, false) + } + + if (stage >= 10 || (stage >= 9 && completedAllSubstages(player))) { + // This disappears after you find all the diamonds. + } else if (stage >= 9 && !completedAllSubstages(player)) { + // This was supposed to disappear... youtu.be/J4cQMY66MI4 is old but disagrees + line(player, "I headed East into the desert and used the scrying", line++, true) + line(player, "glasses set up for me there by Eblis to try and find the", line++, true) + line(player, "Four Diamonds of Azzanadra.", line++, true) + line++ + } else if (stage >= 8) { + line(player, "I should head !!East into the desert?? and meet Eblis where he", line++, false) + line(player, "has set up the scrying glasses, and use them to try and", line++, false) + line(player, "track down the !!Four Diamonds of Azzanadra??.", line++, false) + line++ + } - // line(player,"", line++) - //} - // } - //} + // The huge one with sub quests. + if (stage >= 9 && completedAllSubstages(player)) { + line(player, "I found all four diamonds using this spell.", line++, true) + } else if (stage == 9) { + line++ + // DIAMOND OF BLOOD (DESSOUS) + // Dessous returns to his grave, bored of toying with you. // https://youtu.be/7CvfS7pypso + if (getSubStage(player, attributeBloodStage) == 100) { + line(player, "I defeated a vampire named Dessous to claim the Diamond", line++, true) + line(player, "of Blood.", line++, true) + } else if (getSubStage(player, attributeBloodStage) >= 1) { + // ZSOCwWEwimM 4:25 helped the first line. + line(player, "I discovered that the location of the Diamond of Blood was", line++, true) + line(player, "somewhere in Morytania, and in the possession of a", line++, true) + line(player, "vampire warrior named Dessous.", line++, true) - // override fun finish(player: Player) { - // var ln = 10 - // super.finish(player) - // player.packetDispatch.sendString("You have completed Desert Treasure!", 277, 4) - // player.packetDispatch.sendItemZoomOnInterface(1891, 240, 277, 5) -// - // drawReward(player,"3 Quest Points", ln++) - // drawReward(player,"20,000 Magic XP", ln++) - // drawReward(player,"Ability to use", ln++) - // drawReward(player,"Ancient Magicks", ln) + if (getSubStage(player, attributeBloodStage) >= 3) { + line(player, "I don't fully trust Malek, but he has agreed to help me kill", line++, true) + line(player, "Dessous.", line++, true) - // player.skills.addExperience(Skills.MAGIC, 20000.0) + line(player, "I made a special blessed pot, filled with blood, garlic and", line++, true) + line(player, "spices, which I used to lure Dessous from his tomb.", line++, true) + line(player, "I managed to defeat the vampire warrior Dessous, but", line++, true) + line(player, "there was no sign of the Diamond of Blood anywhere.", line++, true) + line(player, "I should find out what game !!Malek?? has been playing with", line++, false) + line(player, "me, and where I can actually find the !!Diamond of Blood??.", line++, false) + } else if (getSubStage(player, attributeBloodStage) >= 2) { + line(player, "I don't fully trust Malek, but he has agreed to help me kill", line++, true) + line(player, "Dessous.", line++, true) - // } + // None of these lines cross out when you do it. So it remains like this. + line(player, "Apparently I can find an old !!assistant of Count Draynor?? in", line++, false) + line(player, "the !!sewers of Draynor Village??, who will be able to help me", line++, false) + line(player, "make a !!sacrificial pot??", line++, false) + line(player, "I then need to take that !!sacrificial pot?? to !!Entrana?? and get", line++, false) + line(player, "it blessed by the !!head priest??", line++, false) + line(player, "When I have done that, I should return to !!Malak??, and he will", line++, false) + line(player, "provide me with some !!fresh blood??", line++, false) + line(player, "I then need to add !!garlic?? and !!spices?? to the pot in order to", line++, false) + line(player, "lure Dessous from his tomb.", line++, false) + line(player, "When I have done all of this, I must !!kill Dessous!??", line++, false) + } else if (getSubStage(player, attributeBloodStage) >= 1) { + line(player, "I should speak to !!Malek?? again and find out how exactly I", line++, false) + line(player, "can kill !!Dessous??.", line++, false) // This doesn't stay + } + } else if (getSubStage(player, attributeBloodStage) == 0) { + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Blood??.", line++, false) + } - // override fun newInstance(`object`: Any?): Quest { - // return this - // } -//} \ No newline at end of file + line++ + // DIAMOND OF SMOKE (FAREED) + // Fareed has lost interest in you, and returned to his flames. + if (getSubStage(player, attributeSmokeStage) == 100) { + line(player, "I defeated a fire warrior, and now have the Diamond of", line++, true) + line(player, "Smoke.", line++, true) + } else if (getSubStage(player, attributeSmokeStage) >= 1) { + line(player, "I entered a smokey well and lit up the path. I found a", line++, true) // Derived. + line(player, "key in a chest.", line++, true) // Derived. + line(player, "I should find out what the !!key?? unlocks.", line++, false) // Derived. + } else if (getSubStage(player, attributeSmokeStage) == 0) { + // This doesn't change to stage 1 even when you are lighting the fires... + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Smoke??.", line++, false) + } + + line++ + // DIAMOND OF ICE (KAMIL) + // Kamil vanishes on an icy wind... + if (getSubStage(player, attributeIceStage) == 100) { + line(player, "I defeated a warrior named Kamil, and now have the", line++, true) + line(player, "Diamond of Ice.", line++, true) + } else if (getSubStage(player, attributeIceStage) >= 1) { + // https://www.youtube.com/watch?v=F5F6Ds-T1P8 28:52 + line(player, "I met a crying ice troll child to the North of Trollheim.", line++, true) + if (getSubStage(player, attributeIceStage) >= 3) { + line(player, "I managed to cheer him up slightly with a sweet treat.", line++, true) + line(player, "After speaking with him, I discovered that his parents had", line++, true) + line(player, "been hurt by a 'bad man' who had the Diamond of Ice, and I", line++, true) + line(player, "agreed to help him rescue them.", line++, true) + line(player, "While heading through the icy area, I was attacked by an", line++, true) + line(player, "ice warrior named Kamil, and managed to defeat him.", line++, true) + line(player, "Was this the 'bad man' the troll child has spoken of?", line++, true) + line(player, "I should head further into the icy area to try and find", line++, false) + line(player, "them.", line++, false) + } else if (getSubStage(player, attributeIceStage) >= 2) { + line(player, "I managed to cheer him up slightly with a sweet treat.", line++, true) + line(player, "After speaking with him, I discovered that his parents had", line++, true) + line(player, "been hurt by a 'bad man' who had the Diamond of Ice, and I", line++, true) + line(player, "agreed to help him rescue them.", line++, true) + line(player, "I should head further into the icy area to try and find", line++, false) + line(player, "them.", line++, false) + } else if (getSubStage(player, attributeIceStage) >= 1) { + line(player, "I should cheer him up with something sweet.", line++, false) // Derived + } + } else if (getSubStage(player, attributeIceStage) == 0) { + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Ice??.", line++, false) + } + + line++ + // DIAMOND OF SHADOW (DAMIS) + // Damis has vanished once more into the shadows... + if (getSubStage(player, attributeShadowStage) == 100) { + line(player, "I defeated a warrior named Damis, and now have the", line++, true) + line(player, "Diamond of Shadow.", line++, true) + } else if (getSubStage(player, attributeShadowStage) >= 1) { + line(player, "A travelling merchant named Rasolo had some information", line++, true) + line(player, "about the Diamond of Shadow.", line++, true) + line(player, "Apparently it was owned by an invisible warrior, who I", line++, true) + line(player, "needed a special ring to see.", line++, true) + line(player, "Rasolo owned such a ring, but would only trade it in return", line++, true) + line(player, "for a gilded cross stolen from him by a bandit named.", line++, true) + line(player, "Laheeb.", line++, true) + if (getSubStage(player, attributeShadowStage) >= 3) { + line(player, "I found Laheeb's treasure chest, and managed to bypass", line++, true) + line(player, "the traps on it to take the gilded cross, which I returned to", line++, true) + line(player, "Rasolo.", line++, true) + line(player, "In return, he gave me the Ring of Visibility.", line++, true) + line(player, "I should put the !!Ring of Visibility?? on and try and find the", line++, false) + line(player, "hidden home of !!Damis?? - Rasolo suggested it was very", line++, false) + line(player, "close by to where he is...", line++, false) + } else if (getSubStage(player, attributeShadowStage) >= 2) { + line(player, "I found Laheeb's treasure chest, and managed to bypass", line++, true) + line(player, "the traps on it to take the gilded cross.", line++, true) + line(player, "I need to return the !!gilded cross?? to !!Rasolo??.", line++, false) // Derived + } else if (getSubStage(player, attributeShadowStage) >= 1) { + line(player, "I need to find !!Laheeb's loot?? and retrieve the stolen !!gilded??", line++, false) + line(player, "!!cross??.", line++, false) + } + } else if (getSubStage(player, attributeShadowStage) == 0) { + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Shadow??.", line++, false) + } + } + + // If you hold a diamond too long a stranger will try to kill you. + // https://oldschool.runescape.wiki/w/Transcript:Stranger + // After defeating the stranger + // player(THINKING, "I wonder what that was all about?") + + // After all 4 diamonds + // Player dialogue("I should make sure I have all four diamonds with me", "before speaking to Eblis again.") + + if (stage >= 10) { + // This disappears after you place all the diamonds. + } else if (stage >= 9 && completedAllSubstages(player)) { + line(player, "Now that I have recovered all of the !!Diamonds of??", line++, false) + line(player, "!!Azzanadra?? I should take them all to !!Eblis?? and find out what.", line++, false) + line(player, "is so special about them.", line++, false) + // This is the current message even AFTER you speak to Eblis... baQ6oJOk7Gc + } + + if (stage >= 11) { + // This disappears at the end of this quest. + } else if (stage >= 10) { + line(player, "I should explore the !!pyramid?? and see what !!treasure?? awaits", line++, false) + line(player, "me!", line++, false) + } + + if (stage >= 100) { + line(player, "At the heart of the pyramid I found a strange being, who", line++, true) + line(player, "gave me some powerful new magic spells.", line++, true) + line(player, "I can switch between my old spells and my new spells any", line++, true) + line(player, "time by using the altar there, and can avoid the traps by", line++, true) + line(player, "using the secret passage.", line++, true) + line++ + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun reset(player: Player) { + setVarbit(player, varbitChildReunite, 0, true) + + removeAttribute(player, attributeBoughtBeer) + removeAttribute(player, attributeCountMagicLogs) + removeAttribute(player, attributeCountSteelBars) + removeAttribute(player, attributeCountMoltenGlass) + removeAttribute(player, attributeCountBones) + removeAttribute(player, attributeCountAshes) + removeAttribute(player, attributeCountCharcoal) + removeAttribute(player, attributeCountBloodRune) + setVarbit(player, varbitMirrors, 0, true) + + removeAttribute(player, attributeBloodStage) + removeAttribute(player, attributeDessousInstance) + + removeAttribute(player, attributeSmokeStage) + removeAttribute(player, attributeFareedInstance) + removeAttribute(player, attributeUnlockedGate) + setVarbit(player, varbitStandingTorchNorthEast, 0, true) + setVarbit(player, varbitStandingTorchSouthEast, 0, true) + setVarbit(player, varbitStandingTorchSouthWest, 0, true) + setVarbit(player, varbitStandingTorchNorthWest, 0, true) + + removeAttribute(player, attributeIceStage) + removeAttribute(player, attributeKamilInstance) + removeAttribute(player, attributeTrollKillCount) + setVarbit(player, varbitFrozenFather, 0, true) // 0-frozen 1-defrosted + setVarbit(player, varbitFrozenMother, 0, true) // 0-frozen 1-defrosted + setVarbit(player, varbitChildReunite, 0, true) // 0-frozen 4-reunited 5-reunited 6-varbitfails/ends (This varbit seems to manage ice stages...) + setVarbit(player, varbitCaveEntrance, 0, true) // 6446 0 - 6 6441 + + removeAttribute(player, attributeShadowStage) + removeAttribute(player, attributeDamisInstance) + removeAttribute(player, attributeDamisWarning) + setVarbit(player, varbitRingOfVisibility, 0, true) // Set to 1 to show ladder when wearing ring of visibility. + + removeAttribute(player, attributeBloodDiamondInserted) + removeAttribute(player, attributeSmokeDiamondInserted) + removeAttribute(player, attributeIceDiamondInserted) + removeAttribute(player, attributeShadowDiamondInserted) + setVarbit(player, varbitBloodObelisk, 0, true) + setVarbit(player, varbitSmokeObelisk, 0, true) + setVarbit(player, varbitIceObelisk, 0, true) + setVarbit(player, varbitShadowObelisk, 0, true) + } + + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Desert Treasure Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.ANCIENT_STAFF_4675, 240, 277, 5) + + drawReward(player,"3 Quest Points", ln++) + drawReward(player,"20,000 Magic XP", ln++) + drawReward(player,"Ancient Magicks", ln) + + player.skills.addExperience(Skills.MAGIC, 20000.0) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + + // Ice: Cave Entrance Varbit + setVarbit(player, varbitCaveEntrance, getAttribute(player,attributeTrollKillCount, 0)) + + // Shadow: Ring of Visibility Ladder Varbit + if (inEquipment(player, Items.RING_OF_VISIBILITY_4657)) { + setVarbit(player, varbitRingOfVisibility, 1) + } else { + setVarbit(player, varbitRingOfVisibility, 0) + } + + // Obelisks Varbits + if (getAttribute(player, attributeBloodDiamondInserted, 0) == 1) { + setVarbit(player, varbitBloodObelisk, 1) + } else { + setVarbit(player, varbitBloodObelisk, 0) + } + + if (getAttribute(player, attributeSmokeDiamondInserted, 0) == 1) { + setVarbit(player, varbitSmokeObelisk, 1) + } else { + setVarbit(player, varbitSmokeObelisk, 0) + } + + if (getAttribute(player, attributeIceDiamondInserted, 0) == 1) { + setVarbit(player, varbitIceObelisk, 1) + } else { + setVarbit(player, varbitIceObelisk, 0) + } + + if (getAttribute(player, attributeShadowDiamondInserted, 0) == 1) { + setVarbit(player, varbitShadowObelisk, 1) + } else { + setVarbit(player, varbitShadowObelisk, 0) + } + + // Special Varbit for Ice Stage + if (getAttribute(player, attributeIceStage, 0) > 5) { + setVarbit(player, varbitChildReunite, 5) + } else { + setVarbit(player, varbitChildReunite, 0) + } + + // Stage Varbits + if(getQuestStage(player, questName) == 0) { + setVarbit(player, varbitDesertTreasure, 0, true) + setVarbit(player, varbitMirrors, 0, true) + } + if(getQuestStage(player, questName) in 1..7) { + setVarbit(player, varbitDesertTreasure, 1, true) + setVarbit(player, varbitMirrors, 0, true) + } + if(getQuestStage(player, questName) in 8..9) { + setVarbit(player, varbitDesertTreasure, 10, true) + setVarbit(player, varbitMirrors, 1, true) + } + if(getQuestStage(player, questName) == 10) { + setVarbit(player, varbitDesertTreasure, 13, true) + setVarbit(player, varbitMirrors, 1, true) + } + if(getQuestStage(player, questName) >= 100) { + setVarbit(player, varbitDesertTreasure, 15, true) + setVarbit(player, varbitMirrors, 1, true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasureListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasureListeners.kt new file mode 100644 index 000000000..3115efd3f --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasureListeners.kt @@ -0,0 +1,464 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.activity.Cutscene +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class DesertTreasureListeners : InteractionListener { + + companion object { + fun allDiamondsInserted(player: Player): Boolean{ + return getAttribute(player, DesertTreasure.attributeBloodDiamondInserted, 0) == 1 && + getAttribute(player, DesertTreasure.attributeSmokeDiamondInserted, 0) == 1 && + getAttribute(player, DesertTreasure.attributeIceDiamondInserted, 0) == 1 && + getAttribute(player, DesertTreasure.attributeShadowDiamondInserted, 0) == 1 + } + } + var temp = 6517 + + override fun defineListeners() { + + // THE MIRRORS + on(Scenery.MYSTICAL_MIRROR_6423, SCENERY, "look-into") { player, node -> + SouthMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6425, SCENERY, "look-into") { player, node -> + SouthWestMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6427, SCENERY, "look-into") { player, node -> + NorthWestMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6429, SCENERY, "look-into") { player, node -> + NorthMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6431, SCENERY, "look-into") { player, node -> + NorthEastMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6433, SCENERY, "look-into") { player, node -> + SouthEastMirrorLookCutscene(player).start() + return@on true + } + + + // THE OBELISKS + onUseWith(IntType.SCENERY, intArrayOf(Items.ICE_DIAMOND_4671, Items.SMOKE_DIAMOND_4672, Items.SHADOW_DIAMOND_4673), Scenery.OBELISK_6483) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.BLOOD_DIAMOND_4670, Scenery.OBELISK_6483) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitBloodObelisk, 1) + setAttribute(player, DesertTreasure.attributeBloodDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, intArrayOf(Items.BLOOD_DIAMOND_4670, Items.ICE_DIAMOND_4671, Items.SHADOW_DIAMOND_4673), Scenery.OBELISK_6486) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.SMOKE_DIAMOND_4672, Scenery.OBELISK_6486) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitSmokeObelisk, 1) + setAttribute(player, DesertTreasure.attributeSmokeDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, intArrayOf(Items.BLOOD_DIAMOND_4670, Items.SMOKE_DIAMOND_4672, Items.SHADOW_DIAMOND_4673), Scenery.OBELISK_6489) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.ICE_DIAMOND_4671, Scenery.OBELISK_6489) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitIceObelisk, 1) + setAttribute(player, DesertTreasure.attributeIceDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, intArrayOf(Items.BLOOD_DIAMOND_4670, Items.ICE_DIAMOND_4671, Items.SMOKE_DIAMOND_4672), Scenery.OBELISK_6492) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.SHADOW_DIAMOND_4673, Scenery.OBELISK_6492) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitShadowObelisk, 1) + setAttribute(player, DesertTreasure.attributeShadowDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + + // THE DOOR + on(intArrayOf(Scenery.PYRAMID_ENTRANCE_6545, Scenery.PYRAMID_ENTRANCE_6547), SCENERY, "open") { player, node -> + if (allDiamondsInserted(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "A mystical power has sealed this door...") + } + return@on true + } + + // THE LADDERS + on(Scenery.LADDER_6497, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2913, 4954, 3)) + return@on true + } + on(Scenery.LADDER_6504, SCENERY, "climb-up") { player, node -> + teleport(player, Location(3233, 2898, 0)) + return@on true + } + + on(Scenery.LADDER_6498, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2846, 4964, 2)) + return@on true + } + on(Scenery.LADDER_6503, SCENERY, "climb-up") { player, node -> + teleport(player, Location(2909, 4963, 3)) + return@on true + } + + on(Scenery.LADDER_6499, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2782, 4972, 1)) + return@on true + } + on(Scenery.LADDER_6502, SCENERY, "climb-up") { player, node -> + teleport(player, Location(2845, 4973, 2)) + return@on true + } + + on(Scenery.LADDER_6500, SCENERY, "climb-down") { player, node -> + teleport(player, Location(3233, 9293, 0)) + return@on true + } + on(Scenery.LADDER_6501, SCENERY, "climb-up") { player, node -> + teleport(player, Location(2783, 4941, 1)) + return@on true + } + + on((6512..6517).toIntArray(), SCENERY, "search") { player, node -> + // Technically there is loot, but I'm lazy as hell. + sendMessage(player, "You don't find anything interesting.") + return@on true + } + + // After Quest + + // Backdoor + on(Scenery.TUNNEL_6481, SCENERY, "enter") { player, node -> + if (isQuestComplete(player, DesertTreasure.questName)){ + teleport(player, Location(3233, 9313, 0)) + } else { + sendMessage(player, "This passage does not seem to lead anywhere...") // https://youtu.be/uNkBucGaqac + } + return@on true + } + + // Portal, which only appears after DT + on(Scenery.PORTAL_6551, SCENERY, "use") { player, node -> + teleport(player, Location(3233, 2887, 0)) + return@on true + } + + } +} + + +// https://www.youtube.com/watch?v=yMwp78OI2y8 + +// Ice Troll +class NorthMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(11322) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 5, 27) + moveCamera(5, 27, 1000) + rotateCamera(6, 27, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Canifis +class NorthEastMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13878) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 47, 31) + moveCamera(47, 31, 1000) + rotateCamera(43, 31, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Smoke Dungeon +class SouthEastMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13102) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 36, 20) + moveCamera(36, 20, 1000) + rotateCamera(44, 20, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Pyramid +class SouthMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(12845) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 33, 41) + moveCamera(33, 41, 1000) + rotateCamera(33, 39, 990) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Bedabin +class SouthWestMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(12590) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 40, 39) + moveCamera(40, 39, 1200) + rotateCamera(10, 39, 1200) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Rasolo +class NorthWestMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(10037) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 56, 40) + moveCamera(56, 40, 1400) + rotateCamera(56, 35, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DessousBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DessousBehavior.kt new file mode 100644 index 000000000..ec4e8a142 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DessousBehavior.kt @@ -0,0 +1,144 @@ +package content.region.desert.quest.deserttreasure + +import content.region.kandarin.quest.templeofikov.TempleOfIkov +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.* +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) { + private var disappearing = false; + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean{ + if (disappearing) { + return true + } + val player: Player? = getAttribute(self, "target", null) + if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) { + if (player != null && !disappearing) { + disappearing = true + sendMessage(player, "Dessous returns to his grave, bored of toying with you.") + removeAttribute(player, DesertTreasure.attributeDessousInstance) + } + poofClear(self) + } + + // Dessous just continually hisses independently of projectile fires. + if (self.id == NPCs.DESSOUS_1915 && self.properties.combatPulse.isInCombat) { + animate(self, Animation(1914)) + } + // This is probably the prayer flicking nonsense. + if (self.id == NPCs.DESSOUS_1914 && player != null && player.prayer.get(PrayerType.PROTECT_FROM_MELEE)) { + self.transform(NPCs.DESSOUS_1915) + Graphics.send(Graphics(86), self.location) + } else if (self.id == NPCs.DESSOUS_1915 && player != null && (player.prayer.get(PrayerType.PROTECT_FROM_MAGIC) || player.prayer.get(PrayerType.PROTECT_FROM_MISSILES))) { + self.transform(NPCs.DESSOUS_1914) + Graphics.send(Graphics(86), self.location) + } + return true + } + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + if (self.id == NPCs.DESSOUS_1915) { + // 2 x 5HP (One Magic, One Ranged) + return CombatHandler() + } else { + // Fast melee attack 3 ticks up to 19HP + return original + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + // Teleport nearer, if too far. + if (victim is Player) { + if (victim.location.getDistance(self.location) >= 5) { + Graphics.send(Graphics(86), self.location) + self.properties.teleportLocation = victim.location + Graphics.send(Graphics(86), self.location) + } + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + val player = killer + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 2) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 3) + } + removeAttribute(player, DesertTreasure.attributeDessousInstance) + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> player(FacialExpression.ANGRY, "Well that's Dessous dead, but where is the Diamond he", "was supposed to have?").also { stage++ } + 1 -> playerl(FacialExpression.ANGRY, "If Malak lied to me about it, he is going to pay!").also { + stage = END_DIALOGUE + } + } + } + }) + } + } + + /** Handler for ranged. */ + class CombatHandler : MultiSwingHandler( + SwitchAttack(CombatStyle.MAGIC.swingHandler, null), + SwitchAttack(CombatStyle.RANGE.swingHandler, null) + ) { + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + if (entity is NPC && victim is Player) { + val projectile = Projectile.create( + victim.location.transform(Location(intArrayOf(3, -3).random(),intArrayOf(3, -3).random())), + victim.location, + 350, + 0, + 0, + 0, + 60, + 0, + 255 + ) + // 2 x 5HP (One Magic, One Ranged) + state!!.estimatedHit = 5 + state.secondaryHit = 5 // I have no idea what I'm doing + queueScript(entity, 0, QueueStrength.STRONG) { stage: Int -> + when (stage) { + 0 -> { + sendChat(entity, "Hssssssssssss") + projectile.send() + return@queueScript delayScript(entity, entity.location.getDistance(victim.location).toInt()) + } + 1 -> { + return@queueScript stopExecuting(entity) + } + else -> return@queueScript stopExecuting(entity) + } + } + + } + return super.swing(entity, victim, state) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfBloodListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfBloodListeners.kt new file mode 100644 index 000000000..8105aebf7 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfBloodListeners.kt @@ -0,0 +1,134 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfBloodListeners : InteractionListener { + override fun defineListeners() { + + // Silver pot conversions + onUseWith(ITEM, Items.SILVER_POT_4660, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4664) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SILVER_POT_4660, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4662) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SILVER_POT_4662, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4666) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SILVER_POT_4664, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4666) + } + return@onUseWith true + } + // Blessed pot conversions + onUseWith(ITEM, Items.BLESSED_POT_4661, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4665) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BLESSED_POT_4661, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4663) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BLESSED_POT_4663, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4667) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BLESSED_POT_4665, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4667) + } + return@onUseWith true + } + + // You need to crush the garlic. + onUseWith(ITEM, intArrayOf(Items.SILVER_POT_4660, Items.BLESSED_POT_4661, Items.SILVER_POT_4662, Items.BLESSED_POT_4663, Items.SILVER_POT_4664, Items.BLESSED_POT_4665, Items.SILVER_POT_4666, Items.BLESSED_POT_4667 ), Items.GARLIC_1550) { player, used, with -> + sendMessage(player, "You need to crush the garlic before adding it to the pot.") + return@onUseWith true + } + + // Dessous jumps out. + onUseWith(SCENERY, Items.BLESSED_POT_4667, Scenery.VAMPIRE_TOMB_6437) { player, used, with -> + val prevNpc = getAttribute(player, DesertTreasure.attributeDessousInstance, null) + if (prevNpc != null) { + prevNpc.clear() + } + sendMessage(player, "You pour the blood from the pot onto the tomb.") + removeItem(player, used) + val scenery = with.asScenery() + // Swap to a splittable vampire tomb scenery. + replaceScenery(scenery, Scenery.VAMPIRE_TOMB_6438, Animation(1915).duration) + // Vampire Tomb breaks open. + animateScenery(player, scenery, 1915) + // 8 Bat projectiles + spawnProjectile(Location(3570, 3402), Location(3570, 3404), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3570, 3400), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3568, 3402), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3572, 3402), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3568, 3404), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3572, 3404), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3568, 3400), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3572, 3400), 350, 0, 0, 0, 60, 0) + val npc = NPC(NPCs.DESSOUS_1914) + queueScript(player, 1, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + // Projectile gfx for Dessous to jump out. + spawnProjectile(Location(3570, 3402), Location(3570, 3405), 351, 0, 0, 0, 40, 0) + return@queueScript delayScript(player, 1) + } + 1 -> { + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(3570, 3405, 0) + npc.direction = Direction.NORTH + setAttribute(player, DesertTreasure.attributeDessousInstance, npc) + setAttribute(npc, "target", player) + + npc.init() + npc.attack(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + + //sendGraphics(350, Location(3570, 3402)) + //sendGraphics(351, Location(3570, 3402)) + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfIceListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfIceListeners.kt new file mode 100644 index 000000000..c6a8de304 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfIceListeners.kt @@ -0,0 +1,168 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +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.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfIceListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.NPC, Items.CHOCOLATE_CAKE_1897, NPCs.BANDIT_1932 /* should be NPCs.TROLL_CHILD_1932 */) { player, used, with -> + if (removeItem(player, used)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeIceStage, 1) + } + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> player("Hey there little troll...", "Take this and dry those tears...").also { stage++ } + 1 -> npc(FacialExpression.OLD_NEARLY_CRYING, "(sniff)").also { + stage = END_DIALOGUE + } + } + } + }, with as NPC) + } + return@onUseWith true + } + + on(intArrayOf(Scenery.ICE_GATE_5043, Scenery.ICE_GATE_5044), SCENERY, "go-through") { player, node -> + + if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) > 1) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + sendMessage(player, "You squeeze through the large icy bars of the gate.") + // Anim 3272 to squeeze through? + if(player.location.x > 2838) { + teleport(player, Location(2837, 3739, 0)) + } else { + teleport(player, Location(2839, 3739, 0)) + } + } else { + // j_SdwOX1JWg + sendDialogueLines(player, "The bars are frozen tightly shut and a sturdy layer of ice prevents", "you from slipping through.") + } + return@on true + } + + on(Scenery.CAVE_ENTRANCE_6441, SCENERY, "enter") { player, node -> + lock(player, 3) + animate(player, 2796) // Crawling + queueScript(player, 3, QueueStrength.SOFT) { + teleport(player, Location(2874, 3720, 0)) + return@queueScript stopExecuting(player) + } + return@on true + } + + on(Scenery.CAVE_ENTRANCE_6446, SCENERY, "enter") { player, node -> + sendMessage(player, "The entrance to the cave is covered in too much ice to get through.") + return@on true + } + + on(Scenery.CAVE_EXIT_6447, SCENERY, "enter") { player, node -> + lock(player, 3) + animate(player, 2796) // Crawling + queueScript(player, 3, QueueStrength.SOFT) { + teleport(player, Location(2867, 3719, 0)) + return@queueScript stopExecuting(player) + } + return@on true + } + + on(Scenery.ICE_LEDGE_6455, SCENERY, "use") { player, node -> + + if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 3) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + if (inEquipment(player, Items.SPIKED_BOOTS_3107)) { + teleport(player, Location(2838, 3803, 1)) + } else { + sendPlayerDialogue(player, "I don't think I'll make much headway along that icy slope without some spiked boots...") + } + } else { + sendMessage(player, "You have not defeated Kamil yet.") + } + return@on true + } + + on(intArrayOf(Scenery.ICE_GATE_6461, Scenery.ICE_GATE_6462), SCENERY, "go-through") { player, node -> + + teleport(player, Location(2852, 3810, 2)) + return@on true + } + + // This is 1943 as base + on(NPCs.ICE_BLOCK_1944, NPC, "talk-to") { player, node -> + sendDialogueLines(player, "There is a thick layer of ice covering this troll.", "You will have to find some way of shattering it.") + return@on true + } + on(NPCs.ICE_BLOCK_1944, NPC, "smash-ice") { player, node -> + player.attack(node) + return@on true + } + + // This is 1945 as base + on(NPCs.ICE_BLOCK_1946, NPC, "talk-to") { player, node -> + sendDialogueLines(player, "There is a thick layer of ice covering this troll.", "You will have to find some way of shattering it.") + return@on true + } + on(NPCs.ICE_BLOCK_1946, NPC, "smash-ice") { player, node -> + player.attack(node) + return@on true + } + } +} + +/** This is while you are walking up the ice path. **/ +class ComicalTrippingIceArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf( + ZoneBorders(2815, 3775, 2880, 3839, 1), + ZoneBorders(2815, 3775, 2880, 3839, 2) + ) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + if ((1..10).random() == 1) { + lock(entity, 2) + stopWalk(entity) + animate(entity, 767) + } + } + } +} + +class IceAreaAttack : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2850, 3750, 2880, 3770)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player && + getQuestStage(entity, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(entity, DesertTreasure.attributeIceStage) == 2 && + getAttribute(entity, DesertTreasure.attributeKamilInstance, null) == null + ) { + sendMessage(entity, "You can feel an evil presence nearby...") + val npc = NPC.create(NPCs.KAMIL_1913, Location(2857, 3754, 0)) + setAttribute(entity, DesertTreasure.attributeKamilInstance, npc) + setAttribute(npc, "target", entity) + npc.isRespawn = false + npc.init() + npc.attack(entity) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfShadowListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfShadowListeners.kt new file mode 100644 index 000000000..3ca6e6a60 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfShadowListeners.kt @@ -0,0 +1,264 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfShadowListeners : InteractionListener { + + companion object { + + fun roll(player: Player): Boolean { + + val chance = RandomFunction.randomDouble(1.0, 100.0) + val successChance = RandomFunction.getSkillSuccessChance(52.0, 128.0, getDynLevel(player, Skills.THIEVING)) + + return chance < successChance + } + + fun pickAttempt(player: Player, picklockItem: Item?) { + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You attempt to pick the first lock...") + return@queueScript delayScript(player, 1) + } + + 1 -> { + if (roll(player)) { + sendMessage(player, "...You successfully picked the first lock!") + return@queueScript delayScript(player, 1) + } else { + if(picklockItem != null) { + removeItem(player, picklockItem) + } else { + removeItem(player, Items.LOCKPICK_1523) + } + sendMessage(player, "...and fail. The locking mechanism has reset itself.") + sendMessage(player, "Your lock pick snapped while attempting to pick the lock.") + impact(player, 3) + applyPoison(player, player, 6) + return@queueScript stopExecuting(player) + } + } + + 2 -> { + sendMessage(player, "You attempt to pick the second lock...") + return@queueScript delayScript(player, 1) + } + + 3 -> { + if (roll(player)) { + sendMessage(player, "...You successfully picked the second lock!") + return@queueScript delayScript(player, 1) + } else { + if(picklockItem != null) { + removeItem(player, picklockItem) + } else { + removeItem(player, Items.LOCKPICK_1523) + } + sendMessage(player, "...and fail. The locking mechanism has reset itself.") + sendMessage(player, "Your lock pick snapped while attempting to pick the lock.") + impact(player, 3) + applyPoison(player, player, 6) + return@queueScript stopExecuting(player) + } + } + + 4 -> { + sendMessage(player, "You attempt to pick the final lock...") + return@queueScript delayScript(player, 1) + } + + 5 -> { + if (roll(player)) { + sendMessage(player, "You managed to pick the final lock.") + return@queueScript delayScript(player, 1) + } else { + if(picklockItem != null) { + removeItem(player, picklockItem) + } else { + removeItem(player, Items.LOCKPICK_1523) + } + sendMessage(player, "...and fail. The locking mechanism has reset itself.") + sendMessage(player, "Your lock pick snapped while attempting to pick the lock.") + impact(player, 3) + applyPoison(player, player, 6) + return@queueScript stopExecuting(player) + } + } + + 6 -> { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 1) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeShadowStage, 2) + } + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } + } + + override fun defineListeners() { + + // Hidden entrance to the shadow dungeon. + on(Scenery.LADDER_6561, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2630, 5072)) + return@on true + } + + /** This will open up a lot of other places. Maybe have this in a general file? */ + onEquip(Items.RING_OF_VISIBILITY_4657) { player, _ -> + + if((DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) >= 3 && + getQuestStage(player, DesertTreasure.questName) >= 9) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + + setVarbit(player, DesertTreasure.varbitRingOfVisibility, 1) + return@onEquip true + } + sendMessage(player, "You need to complete part of Desert Treasure to equip this.") + return@onEquip false + } + + onUnequip(Items.RING_OF_VISIBILITY_4657) { player, _ -> + setVarbit(player, DesertTreasure.varbitRingOfVisibility, 0) + return@onUnequip true + } + + + + on(Scenery.SECURE_CHEST_6448, SCENERY, "open") { player, node -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 1) { + if (inInventory(player, Items.LOCKPICK_1523)) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> dialogue("Your skill as a thief allows you to see some kind of elaborate booby", "trapped locking mechanism on this chest.").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes", 2, true), + Topic(FacialExpression.NEUTRAL, "No", END_DIALOGUE, true), + title = "Try to open the chest?" + ) + 2 -> end().also { + if (inInventory(player, Items.LOCKPICK_1523)) { + pickAttempt(player, null) + } else { + sendMessage(player, "You need a lockpick in order to attempt this.") + } + } + } + } + }) + } else { + sendMessage(player, "You need a lockpick in order to attempt this.") + } + } else if ((DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) >= 2 && + getQuestStage(player, DesertTreasure.questName) >= 9) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + if (inInventory(player, Items.GILDED_CROSS_4674)) { + sendMessage(player, "The chest is empty.") + } else { + replaceScenery(node as core.game.node.scenery.Scenery, 6449, 2) + sendMessage(player, "Inside the chest, hidden under some rags, you find a Gilded Cross.") + addItemOrDrop(player, Items.GILDED_CROSS_4674) + } + } else { + sendPlayerDialogue(player, "These bandits are hostile enough without me trying to rob them!") + } + return@on true + } + + onUseWith(SCENERY, Items.LOCKPICK_1523, Scenery.SECURE_CHEST_6448) { player, used, with -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 1) { + pickAttempt(player, used as Item) + } else if((DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) >= 2 && + getQuestStage(player, DesertTreasure.questName) >= 9) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + sendMessage(player, "The chest is unlocked.") + } else { + sendPlayerDialogue(player, "These bandits are hostile enough without me trying to rob them!") + } + return@onUseWith true + } + + } +} + +class ShadowDungeonWarning : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2726, 5072, 2728, 5072)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + if ( + getQuestStage(entity, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) == 3 && + getAttribute(entity, DesertTreasure.attributeDamisWarning, false) + ) { + sendMessage(entity, "A voice seems to come from the walls around you;") + sendMessage(entity, "'You... do not be... long in this... place") + sendMessage(entity, "Turn... back now, or... prepare... to meet your... doom'") + getAttribute(entity, DesertTreasure.attributeDamisWarning, true) + } else if ( + getQuestStage(entity, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) == 100 + ) { + if (!inInventory(entity, Items.SHADOW_DIAMOND_4673) && !inBank(entity, Items.SHADOW_DIAMOND_4673)) { + sendMessage(entity, "The Diamond of Shadow seems to have mystically found its way back here...") + GroundItemManager.create(Item(Items.SHADOW_DIAMOND_4673), Location(2739, 5088, 0), entity) + } + } + } + } +} + +class ShadowDungeonAttack : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2731, 5085, 2748, 5097)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + if (getQuestStage(entity, DesertTreasure.questName) == 9) { + if (DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) == 3 && + getAttribute(entity, DesertTreasure.attributeDamisInstance, null) == null + ) { + val npc = NPC.create(NPCs.DAMIS_1974, Location(2739, 5088, 0)) + setAttribute(entity, DesertTreasure.attributeDamisInstance, npc) + setAttribute(npc, "target", entity) + npc.isRespawn = false + npc.walkRadius = 30 + npc.init() + npc.attack(entity) + sendChat(npc, "You should have listened to me!") + } + } else if (DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) >= 100) { + if (!inInventory(entity, Items.SHADOW_DIAMOND_4673) && !inBank(entity, Items.SHADOW_DIAMOND_4673)) { + sendMessage(entity, "The Diamond of Shadow seems to have mystically found its way back here...") + GroundItemManager.create(Item(Items.SHADOW_DIAMOND_4673), Location(2739, 5088, 0), entity) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfSmokeListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfSmokeListeners.kt new file mode 100644 index 000000000..279b6d17d --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfSmokeListeners.kt @@ -0,0 +1,180 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.timer.RSTimer +import core.game.world.map.Location +import core.tools.secondsToTicks +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfSmokeListeners : InteractionListener { + companion object { + const val timerIdentifierTorchNE = "deserttreasureNEtorch" + const val timerIdentifierTorchSE = "deserttreasureSEtorch" + const val timerIdentifierTorchSW = "deserttreasureSWtorch" + const val timerIdentifierTorchNW = "deserttreasureNWtorch" + + fun checkAllTorchesLit(player: Player) : Boolean { + return getVarbit(player, DesertTreasure.varbitStandingTorchNorthEast) == 1 && + getVarbit(player, DesertTreasure.varbitStandingTorchSouthEast) == 1 && + getVarbit(player, DesertTreasure.varbitStandingTorchSouthWest) == 1 && + getVarbit(player, DesertTreasure.varbitStandingTorchNorthWest) == 1 + } + } + + override fun defineListeners() { + on(Scenery.BURNT_CHEST_6420, SCENERY, "open") { player, node -> + if (checkAllTorchesLit(player)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeSmokeStage, 1) + } + } + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) >= 1) { + replaceScenery(node as core.game.node.scenery.Scenery, 6421, 2) + addItemOrDrop(player, Items.WARM_KEY_4656) + sendMessage(player, "You open the chest and take a key.") + } else { + sendDialogueLines(player, "There seems to be no way to open this chest. Engraved where the", "keyhole should be is a message:", "'Light the path, and find the key...'") + } + return@on true + } + + on(intArrayOf(Scenery.GATE_6451, Scenery.GATE_6452), SCENERY, "open") { player, node -> + if (getQuestStage(player, DesertTreasure.questName) == 9) { + // Set attributeUnlockedGate to true if warm key and first time unlocking the gate. + if (!getAttribute(player, DesertTreasure.attributeUnlockedGate, false) && inInventory(player, Items.WARM_KEY_4656)) { + if(removeItem(player, Items.WARM_KEY_4656)) { + sendMessage(player, "You unlock the gate and enter the room.") + setAttribute(player, DesertTreasure.attributeUnlockedGate, true) + } + } + // Fight if unlocked gate, drop recovery diamond if done. + if (getAttribute(player, DesertTreasure.attributeUnlockedGate, false)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) == 1 && + getAttribute(player, DesertTreasure.attributeFareedInstance, null) == null) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + val npc = core.game.node.entity.npc.NPC.create(NPCs.FAREED_1977, Location(3315, 9376, 0)) + setAttribute(player, DesertTreasure.attributeFareedInstance, npc) + setAttribute(npc, "target", player) + npc.isRespawn = false + npc.init() + npc.attack(player) + sendChat(npc, "You dare trespass in my realm?") + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) >= 100) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + if (!inInventory(player, Items.SMOKE_DIAMOND_4672) && !inBank(player, Items.SMOKE_DIAMOND_4672)) { + sendMessage(player, "The Diamond of Smoke seems to have mystically found its way back here...") + GroundItemManager.create(Item(Items.SMOKE_DIAMOND_4672), Location(3315, 9376, 0), player) + } + } + } else { + sendMessage(player, "The gate is locked.") + } + + } else if (getQuestStage(player, DesertTreasure.questName) in 9..100) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "The gate is locked.") + } + return@on true + } + + + on(Scenery.A_DARK_HOLE_31367, SCENERY, "enter") { player, node -> + // You have to come from the Pollnivneach Slayer Dungeon, then this will tele you back. + sendDialogueLines(player, "This hole leads to a maze of other passages. Without knowing where", "you are headed, there's no chance of reaching anywhere interesting.") + return@on true + } + + // NE Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6406, Scenery.STANDING_TORCH_6413) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchNorthEast, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchNE) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchNE, DesertTreasure.varbitStandingTorchNorthEast)) + return@onUseWith true + } + + // SE Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6408, Scenery.STANDING_TORCH_6414) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchSouthEast, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchSE) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchSE, DesertTreasure.varbitStandingTorchSouthEast)) + return@onUseWith true + } + + // SW Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6410, Scenery.STANDING_TORCH_6415) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchSouthWest, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchSW) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchSW, DesertTreasure.varbitStandingTorchSouthWest)) + return@onUseWith true + } + + // NW Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6412, Scenery.STANDING_TORCH_6416) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchNorthWest, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchNW) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchNW, DesertTreasure.varbitStandingTorchNorthWest)) + return@onUseWith true + } + } +} + +class StandingTorchTimer(private val timerIdentifier: String = "deserttreasureunknowntimer", private val torchVarbit: Int = 0) : RSTimer(secondsToTicks(150), timerIdentifier) { + override fun run(entity: Entity): Boolean { + if (entity is Player) { + when(timerIdentifier) { + DiamondOfSmokeListeners.timerIdentifierTorchNE -> sendMessage(entity, "The North-east torch burns out...") + DiamondOfSmokeListeners.timerIdentifierTorchSE -> sendMessage(entity, "The South-east torch burns out...") + DiamondOfSmokeListeners.timerIdentifierTorchSW -> sendMessage(entity, "The South-west torch burns out...") + DiamondOfSmokeListeners.timerIdentifierTorchNW -> sendMessage(entity, "The North-west torch burns out...") + else -> sendMessage(entity, "The torch burns out...") + } + setVarbit(entity, torchVarbit, 0) + } + entity.timers.removeTimer(this) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/EblisDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/EblisDialogue.kt new file mode 100644 index 000000000..11608e56c --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/EblisDialogue.kt @@ -0,0 +1,328 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class EblisDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, EblisDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return EblisDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.EBLIS_1923) + } + +} +class EblisDialogueFile : DialogueBuilderFile() { + + companion object { + fun checkAllGiven(player: Player): Boolean { + return (getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0) >= 12 && + getAttribute(player, DesertTreasure.attributeCountSteelBars, 0) >= 6 && + getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0) >= 6 && + getAttribute(player, DesertTreasure.attributeCountBones, 0) >= 1 && + getAttribute(player, DesertTreasure.attributeCountAshes, 0) >= 1 && + getAttribute(player, DesertTreasure.attributeCountCharcoal, 0) >= 1 && + getAttribute(player, DesertTreasure.attributeCountBloodRune, 0) >= 1) + } + } + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4) + .npcl("Leave us to our fate. We care nothing for the world that betrayed us, or those that come from it.") + .end() + + b.onQuestStages(DesertTreasure.questName, 5,6) + .playerl("Hello. I represent the Museum of Varrock, and I have reason to believe there may be some kinds of artefacts of historical significance in the nearby area...") + .npcl("Ah yes. The only time people care about our existence is when they think they have something to gain from us.") + .npcl("I have nothing to say to you. You and your kind are not welcome here.") + .playerl("Please, if I can just have a few minutes of your time to ask some questions...?") + .npcl("(sigh) I suppose I can spare you that. What do you wish to know about?") + .options() + .let { optionBuilder -> + optionBuilder.option("Why is this village so hostile?") + .playerl("Why are all of the people here so hostile? You would think I was asking you for money instead of just for answers to a few questions...") + .npcl("It is a long story, and I doubt you have much interest in hearing it. Your sort never are, you just take what you can of ours, and then abandon us once more to the desert.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option("No, I want to hear this story.") + .playerl("Actually, I'd be quite interested to hear what it is you have to say to excuse the attitude everybody in this village seems to have.") + .npcl("Ah, it all begun many generations ago, when our ancestors were the proud rulers of these lands...") + .npcl("My ancestors lived far to the North of here, and our lands stretched from the sea in the East to the river Lum, and the mountain of ice. From coast to coast, North to South, our domain was absolute.") + .npcl("Our god was kind to us, and blessed us with prosperity and happiness, and in return we were merciless to his enemies wherever we found them.") + .npcl("Then came the betrayal.") + .npcl("Our god was banished, leaving us helpless to our fates.") + .npcl("Without his protection, we were forced to fend for ourselves once more, against the enemies that sought to destroy us through their petty jealousies.") + .npcl("But we did not succumb without fighting! The spiteful Saradomin and pathetic Zamorak warred with each other, but the hatred they had for each other was as nothing to the hatred they held towards us!") + .npcl("With each battle they waged, we lost more and more land, unable to fight on all fronts, and were pushed further and further South into this gods-forsaken desert.") + .npcl("Our greatest hero, Azzanadra, was finally trapped in a strange stone structure to the South of here, and bound within by terrible powers...") + .npcl("And with that our lands, our homes, our very lives were stolen from us! Too weak to reclaim what was rightfully ours, we made our homes here, knowing that someday Azzanadra will") + .npcl("return with his magnificent power, and bring us back to our former glory...") + .playerl("So you're upset because of something that happened hundreds of years ago?") + .playerl("Seems to me like maybe you should find some closure, and let the past go...") + .npcl("The insults heaped upon my race will never be forgotten, will never be forgiven and will never again be overlooked.") + .npcl("Someday, a harsh wind will blow upon this land, uncovering the wrongs of the past, and we will get back what is rightfully ours. Until such a day we will bide our time here, and will") + .npcl("always be ready with our blades for our righteous vengeance.") + .end() + + optionBuilder2.option("I don't care about your story.") + .playerl("I don't really care what your story is to be honest, there is no excuse for such rudeness or hostility.") + .playerl("I have done nothing wrong to you, but everybody here treats me like I have committed some great crime against the village.") + .npcl("That is because, from our point of view, you have.") + .playerl("What? Just because I entered your village?") + .npcl("You have no right to be here! You have no right to the life you have, for it was taken at our expense!") + .playerl("Whatever... No wonder all you loonies live out here in the desert by yourselves.") + .end() + } + + optionBuilder.option("Do you know anything about treasure near here?") + .playerl("I was wondering if you knew anything about some treasure somewhere around here?") + .playerl("I have some evidence that there might be some kind of treasure hidden very close to this village...") + .npcl("If I knew of any treasure I would not choose to spend my life in this gods-forsaken desert.") + .end() + + optionBuilder.option("Do you know anything about a fortress near here?") + .playerl("Do you know anything about some kind of fortress nearby? I have reason to believe there is, or at least used to be, some kind of fortress very close to here...") + .npcl("Nobody would build anything in this wasteland unless they were forced to, to survive.") + .npcl("I know of no fortress, I know of no reason why anyone would ever bother doing anything out here in the desert.") + .end() + + + // This will only show up after you've talked to the bartender. + optionBuilder.optionIf("Tell me of the four diamonds of Azzanadra.") { player -> + return@optionIf getQuestStage(player, DesertTreasure.questName) == 6 + } + .playerl("So tell me... Did you ever hear of something called the Diamonds of Azzanadra?") + .npcl("This is the treasure which you seek???") + .npcl("Please accept my apologies noble @g[sir,madam]! I thought you were but some opportunistic thief, looking to steal what heritage we have left! Now I see that you are in fact a brave adventurer,") + .npcl("looking to restore our glories back upon us!") + .playerl("Uh... yeah... So anyway, you have heard of them?") + .npcl("Heard of them? Of course I have heard of them! They are the legacy of the great Mahjarrat hero, Azzanadra!") + .playerl("So... do you have any idea where they might be? I have a feeling they will be very valuable.") + .playerl("Uh, valuable as historical artefacts I mean, obviously.") + .npcl("They were stolen by warriors of the false god Zamorak generations ago. When you find the warriors, you will find the diamonds.") + .npcl("I suspect they will not willingly part with such objects of power however.") + .npc("Beware too, for these warriors are very powerful;", "they have taken the powers of the diamonds into themselves!") + .playerl("How do you mean?") + .npcl("Each diamond has an elemental quality...") + .npcl("There is the Diamond of Blood, the Diamond of Ice, the Diamond of Smoke and the Diamond of Shadow.") + .npcl("You should expect the warriors to have taken some aspect of these diamonds as their own...") + .playerl("Do you have any idea how I could track down these warriors somehow, then?") + .npcl("There is an ancient spell I know of that may spy upon such power... But it will require a few ingredients for it to work.") + .npcl("Should you be willing to get these ingredients for me, I will be able to locate the rough area where each of these warriors has taken refuge. The spell is imprecise, but it should help you get on the") + .npcl("right track in your search.") + .npcl("Is your desire for our freedom strong enough? Will you gather the ingredients for this spell for me?") + .options() + .let { optionBuilder2 -> + + optionBuilder2.option("Yes") + // The quest should jump to the next stage here, but I didn't want to write some weird if else here. + .playerl("Sure, what do you need?") + .npcl("For this spell, I will need to make some scrying glasses. I will need enough so that we can view the realm in its entirety.") + .npcl("When enchanted, the scrying glass will be able to let us view any area that has been influenced by the presence of the Diamonds of Azzanadra.") + .playerl("Okay, but what exactly do you need for this spell?") + .npcl("Well, six scrying glasses should be sufficient. For each scrying glass, I will need two magic logs, a steel bar and some molten glass. This makes a total of 12 magic logs, 6 pieces of molten") + .npcl("glass, and 6 steel bars.") + .npcl("In addition, for the actual spell to enchant the glasses, I will require one set of normal bones, some ash, some charcoal and a single blood rune.") + .npcl("Do you understand me, adventurer?") + .playerl("Quick question; what kind of bones do you need?") + .npcl("Standard bones. Other types of bones are of no use to me in this spell.") + .options() + .let { optionBuilder3 -> + optionBuilder3.option("Yes, I will go get those for you.") + .playerl("It's a slightly odd collection of ingredients, but I shouldn't have too much trouble getting those for you.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 6) { + setQuestStage(player, DesertTreasure.questName, 7) + } + } + + optionBuilder3.option("No, please repeat those ingredients.") + .npcl("Before I can complete the spell I will still need the following items;") + .npc("12 magic logs", "6 steel bars", "6 molten glass") + .npc("1 bones,", "1 ashes,", "1 charcoal", "and 1 blood rune.") // This is sic authentic trash dialogue. + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 6) { + setQuestStage(player, DesertTreasure.questName, 7) + } + } + + } + + optionBuilder2.option("No") + .playerl("Actually I don't feel like going on a shopping trip for you right now.") + .npcl("As you wish. I should have known not to get my hopes up that our long cursed life may soon be at an end...") + .end() + } + + optionBuilder.option("Nothing thanks.") + .playerl("Actually, there was nothing I really wanted to ask you about.") + .npcl("Yes, it is exactly like your sort to waste my time in such a way.") + .end() + } + + b.onQuestStages(DesertTreasure.questName, 7) + // Branch to check + + .branch { player -> + return@branch if (checkAllGiven(player)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("Excellent! Those are all the ingredients I need to create the scrying glasses.") + .npcl("I will find a suitable spot in the desert to the East of here, and set them up. When you are ready to begin your search, please come and find me there, I will show you how to utilise the") + .npcl("mirrors to find the diamonds.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 7) { + setQuestStage(player, DesertTreasure.questName, 8) + } + } + + branch.onValue(0) + .npcl("Before I can complete the spell I will still need the following items;") + .manualStage { df, player, _, _ -> + df.interpreter!!.sendDialogues(npc!!.id, FacialExpression.NEUTRAL, + "" + (12 - getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0)) + " magic logs", + "" + (6 - getAttribute(player, DesertTreasure.attributeCountSteelBars, 0)) + " steel bars", + "" + (6 - getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0)) + " molten glass") + } + .manualStage { df, player, _, _ -> + df.interpreter!!.sendDialogues(npc!!.id, FacialExpression.NEUTRAL, + "" + (1 - getAttribute(player, DesertTreasure.attributeCountBones, 0)) + " bones,", + "" + (1 - getAttribute(player, DesertTreasure.attributeCountAshes, 0)) + " ashes,", + "" + (1 - getAttribute(player, DesertTreasure.attributeCountCharcoal, 0)) + " charcoal", + "and " + (1 - getAttribute(player, DesertTreasure.attributeCountBloodRune, 0)) + " blood rune.") // This is sic authentic trash dialogue. + } + .end() + } + + b.onQuestStages(DesertTreasure.questName, 8,9,10) + .npcl("Meet me again in the desert East of here, I will use these ingredients to create a scrying glass for you.") + .end() + + b.onQuestStages(DesertTreasure.questName, 100) + .npcl("Meet me again in the desert East of here.") + .end() + + } +} + +class EblisCollectionsListeners : InteractionListener { + override fun defineListeners() { + + onUseWith(IntType.NPC, intArrayOf(Items.MAGIC_LOGS_1513, Items.MAGIC_LOGS_1514), NPCs.EBLIS_1923) { player, used, with -> + for(i in 0..11) { + if (inInventory(player, used.id)) { + if (getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0) < 12) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountMagicLogs, + getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0) + 1) + sendMessage(player, "You hand over a magic log.") + } + } else { + break + } + } else { + break + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.STEEL_BAR_2353, Items.STEEL_BAR_2354), NPCs.EBLIS_1923) { player, used, with -> + for(i in 0..5) { + if (inInventory(player, used.id)) { + if (getAttribute(player, DesertTreasure.attributeCountSteelBars, 0) < 6) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountSteelBars, + getAttribute(player, DesertTreasure.attributeCountSteelBars, 0) + 1) + sendMessage(player, "You hand over a steel bar.") + } + } else { + break + } + } else { + break + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.MOLTEN_GLASS_1775, Items.MOLTEN_GLASS_1776), NPCs.EBLIS_1923) { player, used, with -> + for(i in 0..5) { + if (inInventory(player, used.id)) { + if (getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0) < 6) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountMoltenGlass, + getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0) + 1) + sendMessage(player, "You hand over some molten glass.") + } + } else { + break + } + } else { + break + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.BONES_526, Items.BONES_527), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountBones, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountBones, + getAttribute(player, DesertTreasure.attributeCountBones, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, those are enough bones for the spell.") + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.ASHES_592, Items.ASHES_593), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountAshes, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountAshes, + getAttribute(player, DesertTreasure.attributeCountAshes, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, that is enough ash for the spell.") + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.CHARCOAL_973, Items.CHARCOAL_974), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountCharcoal, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountCharcoal, + getAttribute(player, DesertTreasure.attributeCountCharcoal, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, that is enough charcoal for the spell.") + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.BLOOD_RUNE_565), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountBloodRune, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountBloodRune, + getAttribute(player, DesertTreasure.attributeCountBloodRune, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, that blood rune should be sufficient for the spell.") + } + } + return@onUseWith true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/EblisMirrorsDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/EblisMirrorsDialogue.kt new file mode 100644 index 000000000..43bec25f1 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/EblisMirrorsDialogue.kt @@ -0,0 +1,127 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class EblisMirrorsDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, EblisMirrorsDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return EblisMirrorsDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.EBLIS_1924, NPCs.EBLIS_1925) + } +} +class EblisMirrorsDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 8) + .npcl("Ah, so you got here at last.") + .npc("As you may noticed, I have made the mirrors for", "the spell, and cast the enchantment upon them.") + .npc("By simply looking into each mirror, you will be able to", "see the area where the trace magics from the Diamonds", "of Azzanadra are emanating from.") + .npc("Unfortunately, I cannot narrow the search closer with", "this kind of spell, but if you search the areas shown to", "you, you may be able to find some clues leading you to", "the evil warriors of Zamorak who stole the diamonds in") + .npc("the first place.") + .player(FacialExpression.THINKING, "So you can't be anymore specific about where to look", "for these warriors and their diamonds?") + .npc("I'm afraid not, other than the direction that the mirror", "is facing will be approximately the direction you will", "need to head in.") + .npc("Make sure to come and speak to me when you have", "retrieved all four diamonds.") + .endWith { _, player -> + if (getQuestStage(player, DesertTreasure.questName) == 8) { + setQuestStage(player, DesertTreasure.questName, 9) + } + } + + b.onQuestStages(DesertTreasure.questName, 9, 10) + .branch { player -> + return@branch if (DesertTreasure.completedAllSubstages(player)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(1) + .player(FacialExpression.THINKING, "So I have all four of these Diamonds of Azzanadra, now", "what?") + .npc("Azzanadra was our greatest ever hero.", "He was unkillable, and the cowardly traitors who stole", "our lands did not know what to do with him, for his", "hatred for them was as strong as his magics.") + .npc(FacialExpression.SAD, "In the end, they cast a spell upon him, to trap him in", "the stone structure to the South of here.") + .npc(FacialExpression.ANNOYED, "They stole his very life force, the essence of his power,", "and trapped it within four crystals - the very same", "Four Diamonds which you have now recovered from", "the brigands who stole from us.") + .npc(FacialExpression.ANNOYED, "The four pillars surrounding the structure are keeping", "the containment spell intact.", "By placing a diamond into each, you will breach the", "magical defenses and begin to restore Azzanadra's") + .npcl(FacialExpression.ANNOYED, "power, and be able to enter the structure.") + .npcl("Go, place the diamonds, and free my lord Azzanadra!") + .npc(FacialExpression.FRIENDLY, "The path will be hard, for his prison is full of traps", "and danger to prevent his rescue, but he will reward you", "beyond your wildest dreams when freed!") + .npc("Quickly...", "After all these centuries, Lord Azzanadra is nearly free!", "You must spare no time, place the Diamonds upon the", "pillars and enter the pyramid so that you may free him!") + .end() + + branch.onValue(0) + .playerl("So can you give me any help on where to find these warriors and their diamonds?") + .npcl("No, the magic used in this spell is powerful, but inaccurate. The direction the scrying glass faces is roughly the direction you will find the warrior, but I'm afraid I") + .npcl("can't be any more help than that.") + .playerl("I don't understand why there are six mirrors when there are only four diamonds...") + .npcl("As I say, the enchantment is very inaccurate.") + .npcl("I can only focus upon the aura the diamonds have left behind them, so any place where the Diamonds were present for a significant period of time will still be shown - such as the Bandit Camp where I make my home.") + .npcl("My apologies, but magic is an inaccurate art in many respects.") + .npcl("Don't forget to come back here when you have collected all four diamonds.") + .end() + } + + b.onQuestStages(DesertTreasure.questName, 100) + .branch { player -> + if (inInventory(player, Items.ANCIENT_STAFF_4675)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(1) + .playerl("Hello again.") + .npcl("Greetings. I await the return of my Lord Azzanadra and of our god. I do not know why, but I feel this spot has some significance...") + .end() + + branch.onValue(0) + .npcl("So have you spoken to my Lord Azzanadra yet?") + .playerl("Yes I have.") + .npcl("And what words did he have for his followers?") + .playerl("Er... He didn't really mention you at all, but he did teach me some cool new magic spells.") + .npcl("It is understandable perhaps... His poor mind must be addled after all of those years of confinement, he would not willingly ignore his followers...") + .npcl("Anyway, if he has taught you our ancient magics, you may be interested in purchasing an ancient heirloom that was passed down to me. My ancestor fought in the ancient battles using the") + .npcl("magic of our god. This heirloom will help you with the speed of your spell-casting.") + .npcl("Normally I could not bear to part with such a priceless relic, but for your help in freeing my Lord Azzanadra, I will be prepared to sell it to you for a mere 80,000 gold.") + .npcl("Are you interested?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes please") + .branch { player -> + if (inInventory(player, Items.COINS_995, 80000)) { 1 } else { 0 } + } + .let { branch2 -> + branch2.onValue(1) + .npcl("Take care of it, it is the only heirloom from those times I possess, although rumour has it many of our ancient warriors were buried with identical weapons so that they could continue to fight for my Lord in their deaths.") + .endWith { _, player -> + if (removeItem(player, Item(Items.COINS_995, 80000))) { + addItemOrDrop(player, Items.ANCIENT_STAFF_4675) + } + } + + branch2.onValue(0) + .linel("You don't have enough money to buy that.") + .end() + } + + optionBuilder.option("No thanks") + .playerl("No, not really.") + .npcl("As you wish. Bear my offer in mind should you ever change your decision, I will remain here.") + .end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/FareedBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/FareedBehavior.kt new file mode 100644 index 000000000..71db43e71 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/FareedBehavior.kt @@ -0,0 +1,77 @@ +package content.region.desert.quest.deserttreasure + +import content.global.skill.magic.modern.WaterSpell +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.global.action.EquipHandler +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) { + private var disappearing = false + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean { + if (disappearing) { + return true + } + val player: Player? = getAttribute(self, "target", null) + if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) { + if (player != null && !disappearing) { + disappearing = true + sendMessage(player, "Fareed has lost interest in you, and returned to his flames.") + removeAttribute(player, DesertTreasure.attributeFareedInstance) + } + poofClear(self) + } + return true + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (state.style == CombatStyle.MAGIC && state.spell !is WaterSpell) { + state.neutralizeHits() + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + if (victim is Player) { + if (!inEquipment(victim, Items.ICE_GLOVES_1580)) { + val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON) + if (weapon != null) { + EquipHandler.unequip(victim, EquipmentContainer.SLOT_WEAPON, weapon.id) + sendMessage(victim, "The heat from the warrior causes you to drop your weapon.") + } +// val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON) +// if(weapon != null && removeItem(victim, weapon.id, Container.EQUIPMENT)) { +// addItemOrDrop(victim, weapon.id) +// } + } + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + addItemOrDrop(killer, Items.SMOKE_DIAMOND_4672) + sendMessage(killer, "You take the Diamond of Smoke from the ashes of the warrior.") + if (DesertTreasure.getSubStage(killer, DesertTreasure.attributeSmokeStage) == 1) { + DesertTreasure.setSubStage(killer, DesertTreasure.attributeSmokeStage, 100) + removeAttribute(killer, DesertTreasure.attributeFareedInstance) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollBehavior.kt new file mode 100644 index 000000000..5b4eeed6a --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollBehavior.kt @@ -0,0 +1,75 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.NPCs + +class FatherTrollBehavior : NPCBehavior(NPCs.ICE_TROLL_1943 /** WRONG NAME ITS ICE_BLOCK */) { + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return attacker is Player + } + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + self.properties.combatPulse.stop() + attacker.properties.combatPulse.stop() + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints) { + state.estimatedHit = self.skills.lifepoints + 1 + state.secondaryHit = -1 + self.skills.lifepoints = self.skills.maximumLifepoints // Reset life of ice block + + setVarbit(attacker, DesertTreasure.varbitFrozenFather, 1) + if (getVarbit(attacker, DesertTreasure.varbitFrozenMother) == 1) { + setVarbit(attacker, DesertTreasure.varbitChildReunite, 4) + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + openDialogue(attacker, ChatFatherAndMotherTrollDialogueFile()) + return@queueScript stopExecuting(self) + } + } else { + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + sendNPCDialogue(attacker, NPCs.TROLL_FATHER_1948, "Oh thank you! It was really cold in there! But please, you must free my wife as well! Our son is depending on us!", FacialExpression.OLD_CALM_TALK2) + return@queueScript stopExecuting(self) + } + } + } + } + } +} + +class MotherTrollBehavior : NPCBehavior(NPCs.ICE_BLOCK_1945) { + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return attacker is Player + } + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + self.properties.combatPulse.stop() + attacker.properties.combatPulse.stop() + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints) { + state.estimatedHit = self.skills.lifepoints + 1 + state.secondaryHit = -1 + self.skills.lifepoints = self.skills.maximumLifepoints // Reset life of ice block + + setVarbit(attacker, DesertTreasure.varbitFrozenMother, 1) + if (getVarbit(attacker, DesertTreasure.varbitFrozenFather) == 1) { + setVarbit(attacker, DesertTreasure.varbitChildReunite, 4) + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + openDialogue(state.attacker!!.asPlayer(), ChatFatherAndMotherTrollDialogueFile()) + return@queueScript stopExecuting(self) + } + } else { + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + sendNPCDialogue(attacker, NPCs.TROLL_MOTHER_1950, "Wow, thanks for breaking me out of that ice! But please, my husband is still trapped in there!", FacialExpression.OLD_CALM_TALK2) + return@queueScript stopExecuting(self) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollDialogue.kt new file mode 100644 index 000000000..a83ededd6 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollDialogue.kt @@ -0,0 +1,170 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.* +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +// Base: 1943 Iced: 1944 Broke: 1948 Reunion: 1947 +// Base: 1945 Iced: 1946 Broke: 1950 Reunion: 1949 + +@Initializable +class FatherTrollDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3 && + getVarbit(player, DesertTreasure.varbitFrozenFather) == 1 && + getVarbit(player, DesertTreasure.varbitFrozenMother) == 1) { + openDialogue(player!!, ChatFatherAndMotherTrollDialogueFile(), npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Oh thank you! It was really cold in there! But please, you must free my wife as well! Our son is depending on us!").also { stage = END_DIALOGUE } + } + } + }, npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 4) { + openDialogue(player!!, ChatFatherAndMotherTrollAfterDialogueFile(), npc) + } else if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 5) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Thanks again for freeing me from that ice block! I might be a troll, but it was real uncomfortable in there!").also { stage = END_DIALOGUE } + } + } + }, npc) + } + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return FatherTrollDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(1943) + } +} + +@Initializable +class MotherTrollDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + println(getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 5) + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3 && + getVarbit(player, DesertTreasure.varbitFrozenFather) == 1 && + getVarbit(player, DesertTreasure.varbitFrozenMother) == 1) { + openDialogue(player!!, ChatFatherAndMotherTrollDialogueFile(), npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Wow, thanks for breaking me out of that ice! But please, my husband is still trapped in there!").also { stage = END_DIALOGUE } + } + } + }, npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 4) { + openDialogue(player!!, ChatFatherAndMotherTrollAfterDialogueFile(), npc) + } else if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 5) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Thanks again for freeing me from that ice block! I don't know what my little snookums would have done without us!").also { stage = END_DIALOGUE } + } + } + }, npc) + } + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return MotherTrollDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.TROLL_MOTHER_1950) + } +} + +class ChatFatherAndMotherTrollDialogueFile : DialogueFile() { + // We gon do like this as the old way allows to easily jump between npcs. + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Phew! Am I glad to be out of that big ice cube! Are you okay too darling?").also { stage++ } + 1 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "Yes, I thought we were done for! Why ever did that nasty Kamil freeze us up there anyway?").also { stage++ } + 2 -> playerl("He must have been trying to protect his Diamond...").also { stage++ } + 3 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "You mean that diamond I found the other day belonged to him? But why didn't he just ask for it back? It's not like I really want it or anything!").also { stage++ } + 4 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "And how did you know we had that diamond anyway, fleshy?").also { stage++ } + 5 -> playerl("Your son told me. That's why I rescued you, it is very important that I have that diamond...").also { stage++ } + 6 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "Ooohhhhh, my poor baby! He must have been so worried about us...").also { stage++ } + 7 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Yes, but he certainly inherited his Dad's smarts!").also { stage++ } + 8 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "If he'd told this fleshy that he had the Diamond and not us, we might never have been rescued!").also { stage++ } + 9 -> playerl("Wait... what? That stupid little troll kid had the diamond all along?").also { stage++ } + 10 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "Don't you talk about my baby like that!").also { stage++ } + 11 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Now, now dear, all's well that ends well. We've been freed and this fleshy has certainly earned himself that diamond.").also { stage++ } + 12 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Let's get out of this terrible place and see our son!").also { + stage++ + if (DesertTreasure.getSubStage(player!!, DesertTreasure.attributeIceStage) == 3) { + DesertTreasure.setSubStage(player!!, DesertTreasure.attributeIceStage, 4) + } + } + + 13 -> { + queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + closeOverlay(player!!) + openOverlay(player!!, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player!!, 6) + } + 1 -> { + teleport(player!!, Location(2836, 3739, 0)) + return@queueScript delayScript(player!!, 1) + } + 2 -> { + openOverlay(player!!, Components.FADE_FROM_BLACK_170) + return@queueScript delayScript(player!!, 6) + } + 3 -> { + closeOverlay(player!!) + openDialogue(player!!, ChatFatherAndMotherTrollAfterDialogueFile()) + return@queueScript stopExecuting(player!!) + } + else -> return@queueScript stopExecuting(player!!) + } + } + end() + } + } + } +} + +class ChatFatherAndMotherTrollAfterDialogueFile : DialogueFile() { + // We gon do like this as the old way allows to easily jump between npcs. + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(NPCs.TROLL_CHILD_1933, FacialExpression.OLD_CALM_TALK2, "Mommy! Daddy! You're free!").also { stage++ } + 1 -> npc(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK1, "That's right son, and it's all thanks to this brave", "adventurer here.", "Now, make sure you hand over that diamond he was", "looking for.").also { stage++ } + 2 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK1, "It has been nothing but trouble for us, let's just get back to our cave and have dinner.").also { stage++ } + 3 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "That's right son, it's your favorite tonight too! A big plate of raw mackerel!").also { stage++ } + 4 -> npcl(NPCs.TROLL_CHILD_1933, FacialExpression.OLD_CALM_TALK2, "RAW MACKEREL! YUMMY!").also { stage++ } + 5 -> npcl(NPCs.TROLL_CHILD_1933, FacialExpression.OLD_CALM_TALK1, "Here ya go mister! Thanks for getting my mom and dad away from the bad man!").also { + stage++ + if (DesertTreasure.getSubStage(player!!, DesertTreasure.attributeIceStage) in 3 .. 4) { + addItemOrDrop(player!!, Items.ICE_DIAMOND_4671) + DesertTreasure.setSubStage(player!!, DesertTreasure.attributeIceStage, 100) + } + } + 6 -> playerl("Don't worry about it, just as long as I don't have to go back into that blizzard.").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollBehavior.kt new file mode 100644 index 000000000..1146559a4 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollBehavior.kt @@ -0,0 +1,35 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.NPCs + +class IceTrollBehavior : NPCBehavior(*iceTrollIds) { + companion object { + private val iceTrollIds = intArrayOf( + NPCs.ICE_TROLL_1936, + NPCs.ICE_TROLL_1937, + NPCs.ICE_TROLL_1938, + NPCs.ICE_TROLL_1939, + NPCs.ICE_TROLL_1940, + NPCs.ICE_TROLL_1941, + NPCs.ICE_TROLL_1942, + ) + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (getQuestStage(killer, DesertTreasure.questName) >= 9) { + val currentIceTrollKill = getAttribute(killer, DesertTreasure.attributeTrollKillCount, 0) + if (currentIceTrollKill < 5) { + setAttribute(killer, DesertTreasure.attributeTrollKillCount, currentIceTrollKill + 1) + setVarbit(killer, DesertTreasure.varbitCaveEntrance, getAttribute(killer, DesertTreasure.attributeTrollKillCount, 0)) + sendMessage(killer, "A chunk of ice falls away from the cave entrance...") + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollDialogue.kt new file mode 100644 index 000000000..ac37cb4dd --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollDialogue.kt @@ -0,0 +1,35 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class IceTrollDialogue (player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, IceTrollDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return IceTrollDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ICE_TROLL_1935) + } + +} +class IceTrollDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc(FacialExpression.OLD_LAUGH1, "Hur hur hur!", "Well look here, a puny fleshy human!") + .npc(FacialExpression.OLD_LAUGH1, "You should beware of the icy wind that runs through", "this valley, it will bring a fleshy like you to a cold end", "indeed!") + .end() + } + +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/KamilBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/KamilBehavior.kt new file mode 100644 index 000000000..f52c0d414 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/KamilBehavior.kt @@ -0,0 +1,84 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.* +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +// https://www.youtube.com/watch?v=xeu6Ncmt1fY + +class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) { + private var disappearing = false + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean { + if (disappearing) { + return true + } + val player: Player? = getAttribute(self, "target", null) + if (player == null || !self.location.withinDistance(self.properties.spawnLocation, (self.walkRadius*1.5).toInt())) { + if (player != null && !disappearing) { + disappearing = true + sendMessage(player, "Kamil vanishes on an icy wind...") + removeAttribute(player, DesertTreasure.attributeKamilInstance) + } + poofClear(self) + } + return true + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (DesertTreasure.getSubStage(killer, DesertTreasure.attributeIceStage) == 2) { + DesertTreasure.setSubStage(killer, DesertTreasure.attributeIceStage, 3) + removeAttribute(killer, DesertTreasure.attributeKamilInstance) + sendPlayerDialogue(killer, "Well, that must have been the 'bad man' that the troll kid was on about... His parents must be up ahead somewhere.") + } + } + } + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + return KamilCombatHandler() + } +} + +// All these combat shit is the most trash level thing to use or decipher. +class KamilCombatHandler: MultiSwingHandler( + SwitchAttack(CombatStyle.MELEE.swingHandler, null), +) { + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (victim is Player) { + // This is following RevenantCombatHandler.java, no idea if this is good. + // I can't be bothered to fix fucking frozen. The player can hit through frozen. What the fuck is frozen for then, to glue his fucking legs??? + if (RandomFunction.roll(3) && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) { + sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll. + impact(victim, if (victim.hasProtectionPrayer(CombatStyle.MAGIC)) 0 else 5) + impact(victim, if (victim.hasProtectionPrayer(CombatStyle.RANGE)) 0 else 5) + registerTimer(victim, spawnTimer("frozen", 7, true)) + sendMessage(victim, "You've been frozen!") + // FIXME: before the below vfx hits, there should be another one that looks kinda like a wind wave exploding at the player's feet. Hope somebody finds the id. + sendGraphics(539, victim.location) + victim.properties.combatPulse.stop() // Force the victim to stop fighting. Whatever. + // FIXME: sfx + }else { + animate(entity!!, Animation(440)) + } + } + super.impact(entity, victim, state) + } +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/MalakDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/MalakDialogue.kt new file mode 100644 index 000000000..37ccfdc53 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/MalakDialogue.kt @@ -0,0 +1,262 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MalakDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, MalakDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return MalakDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MALAK_1920) + } +} + +class MalakDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .npc("Away from me, dog.", "I have business to discuss with the barkeeper.") + .end() + + + b.onQuestStages(DesertTreasure.questName, 9) + .branch { player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 1) { + return@branch 0 // Same branch as 0 + } + return@branch DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) + }.let { branch -> + branch.onValue(0) + .npcl("A human, eh? Give me one good reason why I should not just take you to Lord Drakan now.") + // There's a ring of charos dialogue here, but its one line and doesn't change anything... + .npcl("You had better make it a good one too, or you will not survive the night, I'll wager.") + .let { builder -> + val returnJoin = b.placeholder() + builder.goto(returnJoin) + return@let returnJoin.builder() + .options() + .let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("I am here to worship Zamorak") + .playerl("I am here to worship the almighty Zamorak! Yay! Go Zamorak!") + .npcl("I see. You are a moron. You have probably settled right in with the rest of the idiots in this pathetic excuse for a village.") + .npcl("Unfortunately for you, that is not a good enough reason to explain your presence here.") + .npcl("Now tell me the reason for your coming here, or I will ensure you suffer a horrible fate indeed.") + .goto(returnJoin) + + optionBuilder.option("I am here to praise Lord Drakan") + .playerl("I am here only to serve the mighty Drakan. Yup, Drakan, he's the man.") + .npcl("I see. I would perhaps be more inclined to believe you if I could not smell the death blood of his brother Draynor upon you.") + .npcl("What are you real intentions here?") + // "If the player has not completed Vampyre Slayer" but I'm lazy again + // .npcl("Really? That is interesting, that you would want to give your life by tresspassing in this land for such an unbelievable reason.") + // .npcl("Now speak, what is your purpose in coming here?") + .goto(returnJoin) + + optionBuilder.option("I am here to worship you, oh mighty Malak") + .playerl("I am here only to serve the mighty Drakan.") + .playerl("I came here looking for you, oh mighty Malak, so that I might serve your glory.") + .npcl("Please. Do not think that I am so vain and foolish as to allow you to avoid my question with such obvious sycophancy.") + .npcl("Now tell me the reason behind your being here, or I will ensure that you suffer.") + .goto(returnJoin) + + optionBuilder.option("I am here to kill Lord Drakan") + .playerl("I am here to kill Lord Drakan, and every stinking one of his vampyre brood!") + .npcl("Hah! Most entertaining, human!") + .npcl("Now tell me the reason you are here, or we shall soon see who will be killing whom.") + .goto(returnJoin) + + optionBuilder.option("I am looking for a special Diamond...") + .playerl("I am here looking for a special diamond... I have reason to believe it is somewhere in this vicinity, and it is probably in the possession of a warrior of Zamorak.") + .playerl("I'm fairly sure it will have some kind of magical aura or something too. I don't suppose you've seen it, or know where it might be?") + .npcl("Interesting... Well perhaps we can come to a little... arrangement, human.") + .npcl("I may have information that may assist you, but you in turn will have to do something for me. What do you say? Do you think we could come to some form of") + .npcl("agreement?") + .playerl("Well, what kind of something? No offence, but you're not exactly the trustworthy type...") + .npcl("Ah, you have a healthy sense of paranoia, I see. It is not a particularly unfair request on my part...") + .npcl("All I ask is that you ensure that the current owner of the diamond is killed. For my part, I will let you know his whereabouts, and how exactly to kill him.") + .npcl("When he is dead, you may take the diamond from his corpse and do with it what you will. I have no interest in such baubles.") + .npcl("So what say you? A life for a diamond. As a mark of good faith, I will give you some information free:") + .npcl("The current owner of this diamond is named Dessous.") + .betweenStage { df, player, _, _ -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 1) + } + } + .options("Agree to this arrangement?") + .let { optionBuilder2 -> + optionBuilder2.option("Yes") + .betweenStage { df, player, _, _ -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 1) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 2) + } + } + .playerl("Well... I can't see any drawback. Okay, I accept your offer. Now tell me what you know.") + .goto(continuePath) + + optionBuilder2.option("No") + .playerl("I don't trust you, or anything you say. I'm afraid I have to decline.") + .npcl("As you wish human. I doubt anybody near here knows of the diamond you seek, however.") + .npcl("If you wish to claim it as your own, you have little choice but to accept my bargain. I will wait here until such time as you change your mind.") + .end() + } + return@let continuePath.builder() + } + } + .npcl("What I know? Hah! After you have been alive for as long as I, the things I know are enough to fill a library.") + .npcl("I'm afraid you will need to be a little more specific.") + .let { builder -> + val returnJoin = b.placeholder() + builder.goto(returnJoin) + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option("Why do you want Dessous dead?") + .playerl("I don't see exactly how this bargain benefits you... Why exactly do you want Dessous killed anyway?") + .npcl("That is an impertinent question to demand from myself.") + .npcl("However, if it will help seal our deal, I will let you know some of the details.") + .npcl("As you may or may not know, myself and my blood kin are the rulers of this land, all serving under Lord Drakan. However, we tend not to die of old age or similar") + .npcl("natural causes, which means that to gain another Lords tithe or land, there often need to be...") + .npcl("Unnatural causes of death involved. Let us just say, that Dessous is in control of some land that I myself would like some say in, and that it is not in my interest to be seen to be responsible for the") + .npcl("death of a fellow Lord.") + .npcl("It would however be extremely advantageous to myself should some random human adventurer take it upon themself to remove this rival for me... Do you understand?") + .playerl("Yes... I think so...") + .npcl("Good, we understand each other then. We will both benefit from the death of Dessous.") + .goto(returnJoin) + + optionBuilder.option("Where can I find Dessous?") + .playerl("Where can I find this Dessous?") + .npcl("He currently resides in a graveyard to the South-East of here. You will not be able to move the gravestone which he lies beneath however, you will need to find some way to") + .npcl("lure him out from his tomb.") + .playerl("And how exactly would I go about doing that?") + .npcl("Well, he is a vampyre, so fresh blood would almost certainly entice him out.") + .npcl("However, even though he is a frail and decrepit example of our species, he will be able to kill a weakling human such as yourself extremely easily. Having him in a bloodlust as he does so, will not make") + .npcl("your job any easier.") + .goto(returnJoin) + + optionBuilder.option("How can I kill Dessous?") + .playerl("So what advice can you give me on killing Dessous?") + .npcl("As ancient and weak as Dessous is, he is still more than a match for the likes of you.") + .npcl("That is, assuming you were to fight him fairly.") + .npcl("My proposal would be for you to even the odds up a little bit...") + .playerl("How would I go about doing that?") + .npcl("Well, my plan would be as follows. First, take a silver bar to the man living in the sewers in Draynor. He was an assistant to Count Draynor in some of his...") + .npcl("more interesting experiments many years past. Tell him you need a sacrificial offering pot. He will know what you speak of, it is a unique type of container used in various ancient vampyric ceremonies.") + .npcl("Then take the pot to Entrana and get it blessed by the Head Monk. This will lend the pot some holy power.") + .npcl("If you then bring that silver pot back to me, I will provide you with some fresh blood, to put into it. To that pot of blood, you will add some crushed garlic, and some spice to disguise the smell.") + .npcl("Use that pot of blood upon Dessous' tomb, and he will be unable to resist rising and drinking from it.") + .npcl("The combination of garlic, silver, and blessings from Saradomin will act upon him as a poison, and allow you to kill him.") + .npcl("This is just my suggestion of course, you may ignore it if you wish, although I offer no guarantees of your ability to defeat him otherwise.") + .npcl("Was there anything else you wanted?") + .goto(returnJoin) + + optionBuilder.option("Actually, I don't need to know anything.") + .playerl("Never mind, I will figure out all I need to know by myself.") + .npcl("As you wish. Come and see me when you have managed to kill Dessous.") + .end() + } + } + + branch.onValue(2) + .branch { player -> + return@branch if(inInventory(player, Items.BLESSED_POT_4659) || inInventory(player, Items.SILVER_POT_4658)) { 1 } else { 0} + }.let { branch2 -> + branch2.onValue(1) + .player("I found Ruantun in Draynors sewers.", "He made me this pot, now where can I get some fresh", "blood to fill it with?") + .betweenStage { df, player, _, _ -> + sendMessage(player, "Malak cuts you and pours some of your blood into the pot.") + if (removeItem(player, Items.SILVER_POT_4658)) { + addItemOrDrop(player, Items.SILVER_POT_4660) + } else if (removeItem(player, Items.BLESSED_POT_4659)) { + addItemOrDrop(player, Items.BLESSED_POT_4661) + } + animate(npc!!, 1264) + player.impactHandler.manualHit(player, 5, HitsplatType.NORMAL) + } + .linel("Malak cuts you and pours some of your blood into the pot.") // Supposed to be a sendMessage not a dialogue, but why... + .playerl("Ow!") + .npcl("There you go. As fresh as it gets.") + .playerl("Thanks for nothing.") + .npcl("Come and speak to me again when you have managed to kill Dessous.") + .end() + + branch2.onValue(0) + .npcl("Why are you still here? I notice Dessous still lives.") + .options() + .let { optionBuilder -> + optionBuilder.option("Where can I find Dessous?") + .playerl("Where can I find this Dessous?") + .npcl("He currently resides in a graveyard to the South-East of here. You will not be able to move the gravestone which he lies beneath however, you will need to find some way to") + .npcl("lure him out from his tomb.") + .playerl("And how exactly would I go about doing that?") + .npcl("Come and see my when you have prepared a silver ritual pot in the manner I have told you.") + .npcl("I will ensure that you get some fresh blood that you may taint with garlic and spices, to lure our Dessous.") + .end() + + optionBuilder.option("How do I kill Dessous again?") + .playerl("How am I supposed to kill Dessous again?") + .npcl("Take a silver bar to the man in the Draynor sewers. He will fashion a ritualistic pot for you, which you should then take to Entrana and get blessed.") + .npcl("When you have done that, come back here and speak to me, I will provide you with some fresh blood which you will then crush some garlic into, and then add some spices to hide the garlic.") + .npcl("In this way, you will be able to lure him from his tomb and he should be sufficiently weakened to be vulnerable to your attacks.") + .end() + + optionBuilder.option("Actually, I don't need to know anything.") + .playerl("Never mind, I will figure out all I need to know by myself.") + .npcl("As you wish. Come and see me when you have managed to kill Dessous.") + .end() + } + } + + branch.onValue(3) + .npcl("Ah, the wandering hero returns! I take it you have dispatched poor old Dessous for me?") + .playerl("Quit playing games with me, Malak. I want that diamond, and I want it now!") + .betweenStage { df, player, _, _ -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 3) { + addItemOrDrop(player, Items.BLOOD_DIAMOND_4670) + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 100) + } + } + .npcl("Do not take that tone of voice with me, meat. You should be thankful I have allowed you your life.") + .npcl("Here, take your precious little bauble.") + .npcl("I will take that silver pot from you as well, humans are not meant to possess such artefacts. Now get out of my sight, our deal is complete, and if I see you here again I will not hesistate to take you to") + .npcl("Lord Drakan.") + .npcl("He will be extremely pleased to meet the murderer of poor Dessous, I suspect.") + .end() + + branch.onValue(100) + .branch { player -> + return@branch if(!inInventory(player, Items.BLOOD_DIAMOND_4670)) { 1 } else { 0 } + }.let { branch2 -> + branch2.onValue(1) + .playerl("Where is the Diamond of Blood? I know you have it!") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.BLOOD_DIAMOND_4670) + } + .npcl("Do not take that tone of voice with me, meat. Here, take your bauble. I have no use for it.") + .end() + + branch2.onValue(0) + .npcl("Be lucky I have let you live, meat. Our deal is done, I wish no further dealing with you.") + .end() + + } + } + + b.onQuestStages(DesertTreasure.questName, 10,11,12,13,100) + .npcl("Be lucky I have let you live, meat. Our deal is done, I wish no further dealing with you.") + .end() + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/MummyNPC.kt b/Server/src/main/content/region/desert/quest/deserttreasure/MummyNPC.kt new file mode 100644 index 000000000..d5fed9d6e --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/MummyNPC.kt @@ -0,0 +1,18 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import org.rs09.consts.NPCs + +class MummyNPC : NPCBehavior(NPCs.MUMMY_1958) { + var clearTime = 0 + + override fun tick(self: NPC): Boolean { + if (clearTime++ > 100) { + clearTime = 0 + poofClear(self) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/PyramidArea.kt b/Server/src/main/content/region/desert/quest/deserttreasure/PyramidArea.kt new file mode 100644 index 000000000..2a28610b2 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/PyramidArea.kt @@ -0,0 +1,319 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +class PyramidArea { + companion object { + /** All The Sarcophagus Locations */ + val sarcophagusList = arrayOf( + // Level 1 + Location(2901, 4946, 3), + Location(2902, 4969, 3), + Location(2903, 4961, 3), + Location(2909, 4954, 3), + Location(2913, 4950, 3), + Location(2916, 4954, 3), + Location(2917, 4951, 3), + Location(2917, 4959, 3), + Location(2918, 4963, 3), + // Level 2 + Location(2831, 4962, 2), + Location(2837, 4970, 2), + Location(2843, 4964, 2), + Location(2847, 4947, 2), + Location(2858, 4956, 2), + Location(2858, 4973, 2), + Location(2864, 4942, 2), + Location(2868, 4948, 2), + Location(2869, 4968, 2), + // Level 3 + Location(2759, 4962, 1), + Location(2760, 4956, 1), + Location(2763, 4966, 1), + Location(2764, 4941, 1), + Location(2765, 4936, 1), + Location(2765, 4940, 1), + Location(2767, 4945, 1), + Location(2768, 4947, 1), + Location(2771, 4944, 1), + Location(2774, 4947, 1), + Location(2776, 4941, 1), + Location(2786, 4974, 1), + Location(2787, 4964, 1), + Location(2790, 4968, 1), + Location(2791, 4977, 1), + Location(2798, 4947, 1), + Location(2798, 4952, 1), + Location(2800, 4960, 1), + Location(2802, 4940, 1), + Location(2806, 4936, 1), + Location(2806, 4942, 1), + Location(2810, 4968, 1), + Location(2810, 4975, 1), + // Level 4 + Location(3208, 9315, 0), + Location(3211, 9330, 0), + Location(3217, 9295, 0), + Location(3218, 9281, 0), + Location(3221, 9313, 0), + Location(3221, 9320, 0), + Location(3221, 9324, 0), + Location(3222, 9281, 0), + Location(3225, 9308, 0), + Location(3225, 9310, 0), + Location(3226, 9312, 0), + Location(3226, 9318, 0), + Location(3227, 9288, 0), + Location(3229, 9309, 0), + Location(3231, 9297, 0), + Location(3233, 9309, 0), + Location(3234, 9297, 0), + Location(3234, 9330, 0), + Location(3236, 9302, 0), + Location(3237, 9309, 0), + Location(3240, 9312, 0), + Location(3240, 9318, 0), + Location(3241, 9282, 0), + Location(3242, 9302, 0), + Location(3246, 9282, 0), + Location(3246, 9308, 0), + Location(3246, 9324, 0), + Location(3247, 9323, 0), + Location(3249, 9293, 0), + Location(3250, 9324, 0), + Location(3251, 9323, 0), + Location(3251, 9330, 0), + Location(3251, 9337, 0), + Location(3252, 9330, 0), + Location(3252, 9337, 0), + Location(3253, 9301, 0), + Location(3254, 9324, 0), + Location(3255, 9323, 0), + Location(3255, 9330, 0), + Location(3255, 9337, 0), + Location(3256, 9330, 0), + Location(3256, 9337, 0), + Location(3257, 9289, 0), + Location(3259, 9310, 0), + Location(3259, 9313, 0), + ) + + val safeZone = ZoneBorders(3227, 9310, 3239, 9320) + + // Direction.NORTH - LEFT + // rot 0 - LEFT + // rot 1 - NORTH + // rot 2 - RIGHT + // rot 3 - SOUTH + /** Sarcophagus Opening Location (Note, they are all wrongly mapped due to Scenery) */ + fun getNewLocation(direction: Direction): Location { + return when (direction) { + Direction.NORTH -> Location(-1, 0) + Direction.WEST -> Location(0, -1) + Direction.EAST -> Location(0, 1) + Direction.SOUTH -> Location(1, 0) + else -> Location(0, 0) + } + } + + /** Sarcophagus Opening Facing (Note, they are all wrongly mapped due to Scenery) */ + fun getNewFacing(direction: Direction): Direction { + return when (direction) { + Direction.NORTH -> Direction.NORTH + Direction.WEST -> Direction.NORTH_WEST + Direction.SOUTH -> Direction.WEST + Direction.EAST -> Direction.NORTH_EAST + else -> direction + } + } + + fun nearSarcophagus(loc: Location): Location? { + for (sarcoph in sarcophagusList) { + if(loc.withinDistance(sarcoph, 3)) { + return sarcoph + } + } + return null + } + + /** Trapdoor randomly throws you out of the Pyramid. */ + fun trapdoorTrap(player: Player) { + stopWalk(player) + player.walkingQueue.reset() + forceWalk(player, Location(3233, 2887, 0), "") + lock(player, 8) + sendMessage(player, "You accidentally trigger a trap...") + // addScenery(6521, location) -> animateScenery(scenery, 1939), but 6522 does it for you. + val pitfallScenery = addScenery(6522, player.location) // Scenery - Trapdoor Scenery + animate(player, 1950) // Anim - Player Falling Animation + queueScript(player, 4, QueueStrength.SOFT) { stage -> + player.walkingQueue.reset() + when (stage) { + 0 -> { + sendGraphics(354, player.location) // Gfx - Puff of Smoke + closeOverlay(player) + openOverlay(player, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player, 2) + } + 1 -> { + removeScenery(pitfallScenery) + teleport(player, Location(3233, 2887, 0)) + sendMessage(player, "...and tumble unharmed outside the pyramid.") + closeOverlay(player) + openOverlay(player, Components.FADE_FROM_BLACK_170) + stopWalk(player) + player.walkingQueue.reset() + // animate(player, ??) // Anim - Player Getting Up https://www.youtube.com/watch?v=95OvIPFYCwg + return@queueScript delayScript(player, 3) + } + 2 -> { + player.walkingQueue.reset() + forceWalk(player, Location(3233, 2887, 0), "") + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + /** Mummies randomly spawns out of a sarcophagus. */ + fun spawnMummy(player: Player, sarcophagusLocation: Location) { + val sarcophagusScenery = getScenery(sarcophagusLocation) ?: return + val locationInFront = sarcophagusScenery.location.transform(getNewLocation(sarcophagusScenery.direction)) + // There are 6 sarcophagus, 6512 - 6517 with different door designs. + // They map nicely to 6506 - 6511 and act like a door. + // 6505 is the underlying hole scenery after the door opens, but it is done for you. + replaceScenery( + sarcophagusScenery, + sarcophagusScenery.id - 6, + 5, + getNewFacing(sarcophagusScenery.direction), + locationInFront + ) + val mummyNpc = NPC(NPCs.MUMMY_1958) + mummyNpc.isRespawn = false + mummyNpc.isWalks = false + mummyNpc.isAggressive = true + mummyNpc.location = sarcophagusScenery.location + mummyNpc.init() + mummyNpc.walkingQueue.addPath(locationInFront.x, locationInFront.y) + sendChat(mummyNpc, "Rawr!") + lock(player, 1) + stopWalk(player) + queueScript(player, 2, QueueStrength.SOFT) { stage -> + stopWalk(player) + mummyNpc.walkingQueue.addPath(locationInFront.x, locationInFront.y) + mummyNpc.isWalks = true + mummyNpc.isAggressive = true + mummyNpc.attack(player) + return@queueScript stopExecuting(player) + } + + } + + /** Scarabs randomly spawns somewhere near you. */ + fun spawnScarabs(player: Player) { + stopWalk(player) + lock(player, 3) + val scarabsLocation = Location.getRandomLocation(player.location, 3, true) + sendGraphics(356, scarabsLocation) // Gfx - Cracks before scarab appears. + val scarabNpc = NPC(NPCs.SCARABS_1969) + stopWalk(player) + queueScript(player, 2, QueueStrength.STRONG) { stage -> + stopWalk(player) + when (stage) { + 0 -> { + scarabNpc.isRespawn = false + scarabNpc.isWalks = false + scarabNpc.location = scarabsLocation + scarabNpc.init() + animate(scarabNpc, 1949) // Anim - Scarabs appearing from ground. + return@queueScript delayScript(player, 3) + } + 1 -> { + scarabNpc.isWalks = true + scarabNpc.isAggressive = true + scarabNpc.attack(player) + return@queueScript stopExecuting(player) + } + } + return@queueScript stopExecuting(player) + } + } + } +} + +class PyramidAreaFirstThree: MapArea { + + override fun defineAreaBorders(): Array { + return arrayOf( + getRegionBorders(11597), + getRegionBorders(11341), + getRegionBorders(11085), + ) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + val averageLevel = ( + getDynLevel(entity, Skills.AGILITY) + + getDynLevel(entity, Skills.THIEVING) + ) / 2.0 + val randomValue = RandomFunction.randomDouble(99.5) + + if ((1..20).random() == 1) { + // A mummy would jump out if you walk near a sarcophagus of 2 radius. + val sarcoph = PyramidArea.nearSarcophagus(entity.location) + if (sarcoph != null) { + PyramidArea.spawnMummy(entity, sarcoph) + } + } + + if ((1..80).random() == 2) { + PyramidArea.spawnScarabs(entity) + } + if (randomValue > averageLevel && (1..128).random() == 1) { + PyramidArea.trapdoorTrap(entity) + } + } + } +} + +class PyramidAreaFinal: MapArea { + + override fun defineAreaBorders(): Array { + return arrayOf( + getRegionBorders(12945), + ) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + if (!PyramidArea.safeZone.insideBorder(entity.location)) { // Safezone is talking to Azzanadra. + if ((1..20).random() == 1) { + // A mummy would jump out if you walk near a sarcophagus of 2 radius. + val sarcoph = PyramidArea.nearSarcophagus(entity.location) + if (sarcoph != null) { + PyramidArea.spawnMummy(entity, sarcoph) + } + } + if ((1..80).random() == 2) { + PyramidArea.spawnScarabs(entity) + } + } + + // No Trapdoor For The Final Level + } + } +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/RasoloDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/RasoloDialogue.kt new file mode 100644 index 000000000..273dd5d34 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/RasoloDialogue.kt @@ -0,0 +1,217 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +@Initializable +class RasoloDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, RasoloDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return RasoloDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.RASOLO_1972) + } +} + +class RasoloDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .npc("Greetings friend.", "I am Rasolo, the famous merchant.", "Would you care to see my wares?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("No") + .playerl("No, not really.") + .npcl("As you wish. I will travel wherever the business takes me.") + .end() + } + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 0 && + getQuestStage(player, DesertTreasure.questName) >= 9 + } + .npc("Greetings friend.", "I am Rasolo, the famous merchant.", "Would you care to see my wares?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("No") + .playerl("No, not really.") + .npcl("As you wish. I will travel wherever the business takes me.") + .end() + + optionBuilder.option("Ask about the Diamonds of Azzanadra") + .playerl("No, actually I was looking for something specific...") + .npcl("Hmmmm? And what would that be?") + .playerl("I am looking for one of the Diamonds of Azzanadra. I have reason to believe it may be somewhere around here...") + .npcl("Ahhh... The Shadow Diamond...") + .npcl("I know the object of which you speak. It is guarded by a fearsome warrior known as Damis, they say, who lives in the shadows, invisible to prying eyes...") + .playerl("How can I find this 'Damis' then?") + .npcl("Well now... perhaps we can help each other out here.") + .npcl("I have in my possession a small trinket, a ring, that allows its wearer to see the unseen...") + .playerl("How much do you want for it?") + .npcl("Ah, but it is not for sale... As such...") + .npcl("I am offering to trade it for an item that was rightfully mine, but that was stolen by a bandit named Laheeb.") + .npcl("The item is question is a gilded cross, that has some sentimental value to myself. I wish for you to recover this item for me, and I will happily let you have my ring of visibility.") + .playerl("Where can I find this Laheeb?") + .npcl("Well, as a travelling merchant I have roamed these lands for many years...") + .npcl("To the far east of here there is an area that is dry and barren like the desert... it is called...") + .playerl("Al Kharid?") + .npcl("...Yes, Al Kharid. Now to the south of Al Kharid there is a passageway, it is called the...") + .playerl("Shantay Pass.") + .npcl("...Yes. I didn't realise you had travelled there yourself.") + .npcl("Anyway, when you have gone through the Shantay Pass, you will find yourself in a hostile desert... You will need to bring water with you to keep your life. Now, to the south-west of this pass, you will find a small") + .npcl("village...") + .playerl("The Bedabin camp.") + .npcl(FacialExpression.ANNOYED, "If you know where Laheeb lives, why did you ask me?") + .playerl("I don't. Sorry, please continue.") + .npcl("Well, okay then. Anyway, south of this encampment there is an area where few have ever been... It is a village of murderous bandits, and treacherous") + .npcl("thieves... This is where Laheeb makes his home.") + .npcl("He will have hidden his stolen treasure somewhere in that village, I am sure of it. When you find his loot, you will find my gilded cross. Return it to me, and I will reward you with my ring") + .npcl("of visibility, so that you may find Damis. Does this seem fair to you?") + .options() + .let { optionBuilder2 -> + optionBuilder2.option("Yes") + .playerl("Not a problem. I'll be back with your cross before you know it.") + .endWith { _, player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeShadowStage, 1) + } + } + optionBuilder2.option("No") + .playerl("Sounds like too much effort to me. I'll find this Damis by myself.") + .npcl("As you wish.") + .end() + } + } + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) in 1 .. 2 && + getQuestStage(player, DesertTreasure.questName) >= 9 + } + .npcl("Have you retrieved my gilded cross for me yet?") + .branch { player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 2 && inInventory(player, Items.GILDED_CROSS_4674)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("No, not yet...") + .npcl("Well what seems to be the problem?") + .options() + .let { optionBuilder -> + optionBuilder.option("Where can I find Laheeb?") + .playerl("Where can I find this Laheeb?") + .npcl("Well, as a travelling merchant I have roamed these lands for many years...") + .npcl("To the far east of here there is an area that is dry and barren like the desert... it is called...") + .playerl("Al Kharid?") + .npcl("...Yes, Al Kharid. Now to the south of Al Kharid there is a passageway, it is called the...") + .playerl("Shantay Pass.") + .npcl("...Yes. I didn't realise you had travelled there yourself.") + .npcl("Anyway, when you have gone through the Shantay Pass, you will find yourself in a hostile desert... You will need to bring water with you to keep your life. Now, to the south-west of this pass, you will find a small") + .npcl("village...") + .playerl("The Bedabin camp.") + .npcl("If you know where Laheeb lives, why did you ask me?") + .playerl("I don't. Sorry, please continue.") + .npcl("Well, okay then. Anyway, south of this encampment there is an area where few have ever been... It is a village of murderous bandits, and treacherous") + .npcl("thieves... This is where Laheeb makes his home.") + .end() + optionBuilder.option("Can't I just buy your ring?") + .playerl("Can't I just buy your ring?") + .npcl("No, it is not for sale. Some things are more important than money, and the return of my gilded cross is one of them.") + .end() + optionBuilder.option("Is Damis near here, then?") + .playerl("Is Damis near here, then?") + .npcl("You would be surprised to know just how close he is...") + .end() + } + branch.onValue(1) + .playerl("Yes I have!") + .npcl("Excellent, excellent. Here, take this ring. While you wear it, you will be able to see the things that live in shadows...") + .npcl("And you will be able to find the entrance to Damis' lair.") + .endWith { _, player -> + if (removeItem(player, Items.GILDED_CROSS_4674)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 2) { + addItemOrDrop(player, Items.RING_OF_VISIBILITY_4657) + DesertTreasure.setSubStage(player, DesertTreasure.attributeShadowStage, 3) + } + } + } + } + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 3 && + getQuestStage(player, DesertTreasure.questName) >= 9 + } + .npcl("So how goes your quest? Did you managed to find the Diamond you were looking for yet?") + .branch { player -> + if (inInventory(player, Items.RING_OF_VISIBILITY_4657)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("Not yet...") + .npcl("Well, his lair is very close to here. I suggest you look around for it.") + .end() + + branch.onValue(0) + .playerl("I lost that ring you gave me...") + .npcl("Then by all means, take another. Only a foolish merchant would give away his only stock!") + .endWith { _, player -> + addItem(player, Items.RING_OF_VISIBILITY_4657) + } + } + + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) > 3 && + getQuestStage(player, DesertTreasure.questName) >= 9 || getQuestStage(player, DesertTreasure.questName) >= 10 + } + .npcl("Many thanks for returning my heirloom to me, adventurer. Would you like to buy something?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("No") + .playerl("No, not really.") + .npcl("As you wish. I will travel wherever the business takes me.") + .end() + + optionBuilder.optionIf("I lost that ring you gave me...") { player -> + return@optionIf !inInventory(player, Items.RING_OF_VISIBILITY_4657) + } + .playerl("I lost that ring you gave me...") + .npcl("Then by all means, take another. Only a foolish merchant would give away his only stock!") + .endWith { _, player -> + addItem(player, Items.RING_OF_VISIBILITY_4657) + } + } + + } +} + +class RasoloTradeListeners : InteractionListener { + override fun defineListeners() { + on(NPCs.RASOLO_1972, NPC, "trade") { player, node -> + openNpcShop(player, node.id) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/RuantunDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/RuantunDialogue.kt new file mode 100644 index 000000000..89fa635f7 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/RuantunDialogue.kt @@ -0,0 +1,83 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class RuantunDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, RuantunDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return RuantunDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.RUANTUN_1916) + } +} + +class RuantunDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .playerl("Hello.") + .npcl(FacialExpression.OLD_NORMAL, "You ssshould not be down here...") + .options() + .let { optionBuilder -> + optionBuilder.option("Who are you?") + .playerl("Who are you?") + .npcl(FacialExpression.OLD_NORMAL, "My name isss unimportant... I live only to ssserve my massster.") + .playerl("Um... Okay then.") + .end() + + optionBuilder.option("Why are you down here?") + .playerl("Why are you down here?") + .npcl(FacialExpression.OLD_NORMAL, "Thisss isss where I belong... Beingsss sssuch as myssself cannot abide in the light... It is in the darknesss where we find our homesss...") + .playerl("Uh... Okay then.") + .end() + + optionBuilder.option("Can I use your anvil?") + .playerl("Can I use your anvil?") + .npcl(FacialExpression.OLD_NORMAL, "Of courssse you may... I have very little ussse for it nowadaysss...") + .playerl("Uh... Thanks, I guess.") + .end() + } + + b.onQuestStages(DesertTreasure.questName, 9, 10, 100) + // Technically should happen after talking to Malak, but nah. + .playerl("Hello.") + .npcl(FacialExpression.OLD_NORMAL, "You sshould not be down here...") + .playerl("Are you an assistant to Count Draynor?") + .npc(FacialExpression.OLD_NORMAL, "I usssed to have that honour...", "Why do you ssseek me?") + .branch { player -> + return@branch if (inInventory(player, Items.SILVER_BAR_2355)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("I have a silver bar with me, I was wondering if you could make it into a 'sacrificial offering pot' for me?") + .betweenStage { df, player, _, _ -> + if (removeItem(player, Items.SILVER_BAR_2355)) { + addItemOrDrop(player, Items.SILVER_POT_4658) + } + } + .npc(FacialExpression.OLD_NORMAL, "Yesss, of courssse...", "There you are, put it to good usssse...") + .end() + + branch.onValue(0) + .playerl("I understand that you can make me a 'sacrificial offering pot' if I bring you a bar of silver?") + .npcl(FacialExpression.OLD_NORMAL, "And where did you hear thisss?") + .playerl("It was from Malak in Canifis.") + .npc(FacialExpression.OLD_NORMAL, "Ah, I sssee...", "Yesss, I know how to make sssuch an item...", "It has been many yearsss sssince I have needed to however...") + .npcl(FacialExpression.OLD_NORMAL, "It is not my wisssh to quessstion your desssire for sssuch an item, I wasss merely sssurprisssed that one sssuch as you would make sssuch a requessst...") + .npcl(FacialExpression.OLD_NORMAL, "I will happily make you thisss pot, but you mussst bring me a bar of sssilver... Alasss, I can no longer collect my own ingredientsss, and mussst remain here...") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/ScarabNPC.kt b/Server/src/main/content/region/desert/quest/deserttreasure/ScarabNPC.kt new file mode 100644 index 000000000..93dd60d7b --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/ScarabNPC.kt @@ -0,0 +1,18 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import org.rs09.consts.NPCs + +class ScarabNPC : NPCBehavior(NPCs.SCARABS_1969) { + var clearTime = 0 + + override fun tick(self: NPC): Boolean { + if (clearTime++ > 100) { + clearTime = 0 + poofClear(self) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/TranslationBook.kt b/Server/src/main/content/region/desert/quest/deserttreasure/TranslationBook.kt new file mode 100644 index 000000000..6778a0f43 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/TranslationBook.kt @@ -0,0 +1,187 @@ +package content.region.desert.quest.deserttreasure + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.storeBookInHouse +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class TranslationBook : InteractionListener { + + companion object { + private val TITLE = "Translation Primer" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("This is a rough", 55), + BookLine("translation of the stone", 56), + BookLine("tablet brought to me by", 57), + BookLine("courier earlier today.", 58), + BookLine("", 59), + BookLine("", 60), + BookLine("The cuneiforms of this", 61), + BookLine("particular tablet are far", 62), + BookLine("different to anything I", 63), + BookLine("have previously seen in", 64), + BookLine("my career as an", 65) + ), + Page( + BookLine("archaeological expert.", 66), + BookLine("", 67), + BookLine("Where possible I have", 68), + BookLine("given as accurate a", 69), + BookLine("translation as possible, but", 70), + BookLine("some of the words I have", 71), + BookLine("attempted to translate", 72), + BookLine("hold different meanings", 73), + BookLine("depending upon their", 74), + BookLine("intonation and context;", 75), + BookLine("Due to my unfamiliarity", 76) + ) + ), + PageSet( + Page( + BookLine("with this language, I have", 55), + BookLine("given possible translations", 56), + BookLine("for these words wherever", 57), + BookLine("I have encountered them.", 58), + BookLine("Wherever I have a word", 59), + BookLine("n brackets, it is a word", 60), + BookLine("which has many meanings", 61), + BookLine("depending on the context,", 62), + BookLine("although the general", 63), + BookLine("meaning should be clear", 64), + BookLine("to even a casual study.", 65) + ), + Page( + BookLine("", 66), + BookLine("", 67), + BookLine("Hopefully this translation", 68), + BookLine("will help you in your", 69), + BookLine("excavations Asgarnia, and", 70), + BookLine("as usual I look forward", 71), + BookLine("to seeing what relics you", 72), + BookLine("bring back to the", 73), + BookLine("Museum of Varrock this", 74), + BookLine("time!", 75), + BookLine("Your friend, as always,", 76) + ), + ), + PageSet( + Page( + BookLine("Terry Balando", 55), + BookLine("", 56), + BookLine("", 57), + BookLine("", 58), + BookLine("", 59), + BookLine("", 60), + BookLine("", 61), + BookLine("", 62), + BookLine("", 63), + BookLine("", 64), + BookLine("", 65) + ), + Page( + BookLine("Translation follows:", 66), + BookLine("", 67), + BookLine("", 68), + BookLine("(There are some missing", 69), + BookLine("sentence fragments here,", 70), + BookLine("presumably from a stone", 71), + BookLine("tablet preceding this one", 72), + BookLine("which you have not yet", 73), + BookLine("discovered)", 74), + BookLine("", 75), + BookLine("...the permanent", 76) + ) + ), + PageSet( + Page( + BookLine("(exile/journey) of the", 55), + BookLine("people ended.", 56), + BookLine("And so it came to pass,", 57), + BookLine("that deep in the", 58), + BookLine("(fiery/uncomfortable)", 59), + BookLine("desert, the gods", 60), + BookLine("(argued/decided) amongst", 61), + BookLine("themselves that the", 62), + BookLine("(fortress/home) would be", 63), + BookLine("the (selected/chosen) place", 64), + BookLine("that would", 65) + ), + Page( + BookLine("(imprison/conceal) the", 66), + BookLine("(wealth/power).", 67), + BookLine("Thus (guarded/protected)", 68), + BookLine("by the (unusually archaic", 69), + BookLine("word here, I believe it", 70), + BookLine("means either the sick or", 71), + BookLine("the dead depending on", 72), + BookLine("context) and", 73), + BookLine("(defended/trapped) by the", 74), + BookLine("(diamonds/crystals) of", 75), + BookLine("(this word is", 76) + ) + ), + PageSet( + Page( + BookLine("untranslatable). So it was", 55), + BookLine("that the gods left the four", 56), + BookLine("(diamonds/crystals) as the", 57), + BookLine("(key/secret).", 58), + BookLine("(Guarded/Protected) by", 59), + BookLine("the (again, this word has", 60), + BookLine("no modern equivalent)", 61), + BookLine("and held by the", 62), + BookLine("(worthy/strong) so that", 63), + BookLine("the (wealth/power) might", 64), + BookLine("forever be", 65) + ), + Page( + BookLine("(imprisoned/concealed).", 66), + BookLine("", 67), + BookLine("", 68), + BookLine("", 69), + BookLine("", 70), + BookLine("", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76) + ) + ), + PageSet( + Page( + BookLine("There seems to be some", 55), + BookLine("further missing", 56), + BookLine("information continued", 57), + BookLine("onto a further tablet, but", 58), + BookLine("from this preliminary", 59), + BookLine("translation I think you", 60), + BookLine("may be onto something", 61), + BookLine("very big indeed!", 62), + BookLine("", 63), + BookLine("", 64), + BookLine("", 65) + ), + ), + ) + fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.TRANSLATION_4655, IntType.ITEM, "read") { player, node -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/TrollChildDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/TrollChildDialogue.kt new file mode 100644 index 000000000..24cedf3ef --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/TrollChildDialogue.kt @@ -0,0 +1,142 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class TrollChildDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, TrollChildDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return TrollChildDialogue(player) + } + override fun getIds(): IntArray { + // NPCs.BANDIT_1932 is wrong, should be NPCs.TROLL_CHILD_1932 + // NPCs.TROLL_CHILD_1933, NPCs.TROLL_CHILD_1934 are varbit controlled 1932 instances. + return intArrayOf(NPCs.BANDIT_1932) + } +} +class TrollChildDialogueFile : DialogueBuilderFile() { + + companion object { + fun dialogueBeforeQuestCrying(builder: DialogueBuilder): DialogueBuilder { + // From https://youtu.be/AJaHuCuxfFg 15:19 + return builder + .playerl("Hello there.") + .line("The troll child is crying to itself.", "It is ignoring you completely.") + } + fun dialogueStillCrying(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Hello there.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Waaaaaaa!") + .line("This troll seems very upset about something.", "Maybe some sweet food would take his mind off things?") + } + fun dialogueStoppedCrying(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Hello there.") + .npc(FacialExpression.OLD_SAD,"-sniff-","H-hello there.") + .playerl("Why so sad, little troll?") + .npc(FacialExpression.OLD_NEARLY_CRYING,"It was the bad man!", "He hurt my mommy and daddy!", "He made them all freezey!") + .playerl("Bad man...?") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"He said it was because they stole his diamond! But they never did! They found it, and didn't know who it belonged to!") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"My mommy always told me stealing is wrong, they would never steal from someone!") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Then he did some wavey hand thing and my mommy and daddy got frozified!") + .playerl("A diamond you say? Listen, I think I might be able to help your parents, but I need that Diamond in return.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"-sniff- I don't think they really wanted it anyway, they would have given it back to the bad man if he'd asked before freezifying them...") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"I give you my promise mister that if you unfreeze my mommy and daddy, you can have the stupid diamond.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Do we have a deal?") + } + fun dialogueYesToHelp(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Absolutely. Don't worry kid, I'll get your parents back to you safe and sound.") + } + fun dialogueNoToHelp(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Sorry, I can't make any promises about that, and I don't think I have the time to waste trying to defrost some stupid ice trolls.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Waaaaaaa!") + } + fun dialogueHaveYouFreedThem(builder: DialogueBuilder): DialogueBuilder { + return builder + .npcl(FacialExpression.OLD_SAD,"You didn't free my mommy and daddy yet?") + .player("Not yet...") + .npc(FacialExpression.OLD_SAD,"Please try harder!", "I love my mommy and daddy!") + } + fun dialogueThankYou(builder: DialogueBuilder): DialogueBuilder { + return builder + .npc(FacialExpression.OLD_CALM_TALK1, "Thanks for all of your help!", "I'm surprised you managed to survive the blizzard,", "being a thin skinned fleshy and all!") + .player("What can I say?", "I'm a lot tougher than I look.") + } + fun dialogueLostDiamond(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("I lost that diamond of Ice you gave me...") + .npcl(FacialExpression.OLD_CALM_TALK1, "That's okay, it blew back on an icy wind... It's almost like it wants to stay here! Here, take it back, you've earned it.") + } + } + + override fun create(b: DialogueBuilder) { + // Dialogue Logic + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .let{dialogueBeforeQuestCrying(it)} + .end() + + b.onQuestStages(DesertTreasure.questName, 9) + .branch { player -> + return@branch DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) + }.let { branch -> + // Branch on sub-stages. + branch.onValue(0) + .let{dialogueStillCrying(it)} + .end() + + branch.onValue(1) + .let{dialogueStoppedCrying(it)} + .options().let { optionBuilder -> + optionBuilder.option("Yes") + .let{dialogueYesToHelp(it)} + .endWith { _, player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 1) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeIceStage, 2) + } + } + optionBuilder.option("No") + .let{dialogueNoToHelp(it)} + .end() + } + + branch.onValue(2) + .let{dialogueHaveYouFreedThem(it)} + .end() + + branch.onValue(3) + .let{dialogueHaveYouFreedThem(it)} + .end() + + branch.onValue(4) + .let{dialogueHaveYouFreedThem(it)} + .end() + + branch.onValue(100) + .branch { player -> + return@branch if (!inInventory(player, Items.ICE_DIAMOND_4671)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .let{dialogueLostDiamond(it)} + .endWith { _, player -> + addItemOrDrop(player, Items.ICE_DIAMOND_4671) + } + branch.onValue(0) + .let{dialogueThankYou(it)} + .end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt b/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt index 26e72c57f..87fc7de02 100644 --- a/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt +++ b/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt @@ -6,15 +6,16 @@ import core.api.removeItem import core.game.interaction.IntType import core.game.interaction.InteractionListener import org.rs09.consts.Items +import content.data.Quests class DarklightListener : InteractionListener { override fun defineListeners() { onUseWith(IntType.ITEM, Items.BLACK_MUSHROOM_INK_4622, Items.SILVERLIGHT_2402) { player, used, with -> - if (!hasRequirement(player, "Shadow of the Storm") || (!player.inventory.contains(Items.BLACK_MUSHROOM_INK_4622, 1) && (!player.inventory.contains(Items.SILVERLIGHT_2402, 1)))) + if (!hasRequirement(player, Quests.SHADOW_OF_THE_STORM) || (!player.inventory.contains(Items.BLACK_MUSHROOM_INK_4622, 1) && (!player.inventory.contains(Items.SILVERLIGHT_2402, 1)))) return@onUseWith false if (removeItem(player, used.id) && removeItem(player, with.id)) - addItem(player, Items.DARKLIGHT_6746) - return@onUseWith true + return@onUseWith addItem(player, Items.DARKLIGHT_6746) + return@onUseWith false } } } diff --git a/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt b/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt index b045a1cf1..19af2735d 100644 --- a/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt +++ b/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt @@ -8,6 +8,8 @@ import core.plugin.Initializable import org.rs09.consts.NPCs import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile +import content.data.Quests +import content.global.handlers.iface.ScrollLine @Initializable public final class ClayGolemDialoguePlugin(player: Player? = null) : DialoguePlugin(player) { @@ -29,22 +31,22 @@ public final class ClayGolemDialoguePlugin(player: Player? = null) : DialoguePlu class ClayGolemDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - val opt1 = b.onQuestStages("The Golem", 0) + val opt1 = b.onQuestStages(Quests.THE_GOLEM, 0) .npc("Damage... severe...", "task... incomplete...") .options() opt1 - .optionIf("Shall I try to repair you?") { player -> return@optionIf player.questRepository.getQuest("The Golem").hasRequirements(player) } + .optionIf("Shall I try to repair you?") { player -> return@optionIf player.questRepository.getQuest(Quests.THE_GOLEM).hasRequirements(player) } .playerl("Shall I try to repair you?") .npcl("Repairs... needed...") - .endWith(){ _, player -> if (player.questRepository.getStage("The Golem") < 1 ) { setQuestStage(player, "The Golem", 1) } } + .endWith(){ _, player -> if (player.questRepository.getStage(Quests.THE_GOLEM) < 1 ) { setQuestStage(player, Quests.THE_GOLEM, 1) } } opt1 .option("I'm not going to find a conversation here!") .playerl("I'm not going to find a conversation here!") .end() - b.onQuestStages("The Golem", 1) + b.onQuestStages(Quests.THE_GOLEM, 1) .npcl("Repairs... needed...") .end() - b.onQuestStages("The Golem", 2) + b.onQuestStages(Quests.THE_GOLEM, 2) .npcl("Damage repaired...") .npcl("Thank you. My body and mind are fully healed.") .npcl("Now I must complete my task by defeating the great enemy.") @@ -52,43 +54,43 @@ class ClayGolemDialogueFile : DialogueBuilderFile() { .npcl("A great demon. It broke through from its dimension to attack the city.") .npcl("The golem army was created to fight it. Many were destroyed, but we drove the demon back!") .npcl("The demon is still wounded. You must open the portal so that I can strike the final blow and complete my task.") - .endWith() { _, player -> setQuestStage(player, "The Golem", 3) } - b.onQuestStages("The Golem", 3) + .endWith() { _, player -> setQuestStage(player, Quests.THE_GOLEM, 3) } + b.onQuestStages(Quests.THE_GOLEM, 3) .npcl("The demon is still wounded. You must open the portal so that I can strike the final blow and complete my task.") .end() - b.onQuestStages("The Golem", 4) + b.onQuestStages(Quests.THE_GOLEM, 4) .npcl("My task is incomplete. You must open the portal so I can defeat the great demon.") .playerl("It's ok, the demon is dead!") .npcl("The demon must be defeated...") .playerl("No, you don't understand. I saw the demon's skeleton. It must have died of its wounds.") .npcl("Demon must be defeated! Task incomplete.") - .endWith() { _, player -> setQuestStage(player, "The Golem", 5) } - b.onQuestStages("The Golem", 5) + .endWith() { _, player -> setQuestStage(player, Quests.THE_GOLEM, 5) } + b.onQuestStages(Quests.THE_GOLEM, 5) .npcl("Task incomplete.") .playerl("Oh, how am I going to convince you?") - .endWith() { _, player -> setQuestStage(player, "The Golem", 6) } - b.onQuestStages("The Golem", 6, 7) + .endWith() { _, player -> setQuestStage(player, Quests.THE_GOLEM, 6) } + b.onQuestStages(Quests.THE_GOLEM, 6, 7) .npcl("My task is incomplete. You must open the portal so I can defeat the great demon.") .playerl("I already told you, he's dead!") .npcl("Task incomplete.") .playerl("Oh, how am I going to convince you?") - .endWith() { df, player -> if(player.questRepository.getStage("The Golem") < 7) { setQuestStage(player, "The Golem", 7) } } + .endWith() { df, player -> if(player.questRepository.getStage(Quests.THE_GOLEM) < 7) { setQuestStage(player, Quests.THE_GOLEM, 7) } } } } class ClayGolemProgramDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages("The Golem", 8) + b.onQuestStages(Quests.THE_GOLEM, 8) .npc("New instructions...", "Updating program...") .npcl("Task complete!") .npcl("Thank you. Now my mind is at rest.") - .endWith() { _, player -> finishQuest(player, "The Golem") } + .endWith() { _, player -> finishQuest(player, Quests.THE_GOLEM) } } } class CuratorHaigHalenGolemDialogue : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - val opt1 = b.onQuestStages("The Golem", 3) + val opt1 = b.onQuestStages(Quests.THE_GOLEM, 3) .npcl("Ah yes, a very impressive artefact. The people of that city were excellent sculptors.") .npcl("It's in the display case upstairs.") .playerl("No, I need to take it away with me.") @@ -106,19 +108,18 @@ class CuratorHaigHalenGolemDialogue : DialogueBuilderFile() { } } +// https://youtu.be/owPSLUB9E8k?t=261 val LETTER_LINES = arrayOf( - "", - "", - "Dearest Varmen,", - "I hope this finds you well. Here are the books you asked for", - "There has been an exciting development closer to home --", - "another city from the same period has been discovered east", - "of Varrock, and we are starting a huge excavation project", - "here. I don't know if the museum will be able to finance your", - "expedition as well as this one, so I fear your current trip will be", - "the last.", - "May Saradomin grant you a safe journey home", - "Your loving Elissa.", + ScrollLine("Dearest Varmen,", 3), + ScrollLine("I hope this finds you well. Here are the books you asked for", 4), + ScrollLine("There has been an exciting development closer to home --", 5), + ScrollLine("another city from the same period has been discovered east", 6), + ScrollLine("of Varrock, and we are starting a huge excavation project", 7), + ScrollLine("here. I don't know if the museum will be able to finance your", 8), + ScrollLine("expedition as well as this one, so I fear your current trip will be", 9), + ScrollLine("the last.", 10), + ScrollLine("May Saradomin grant you a safe journey home", 11), + ScrollLine("Your loving Elissa.", 12) ) val DISPLAY_CASE_TEXT = arrayOf("3rd age - yr 3000-4000", diff --git a/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt b/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt index 8ae98312a..4d637b890 100644 --- a/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt +++ b/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt @@ -19,9 +19,12 @@ import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.interaction.InterfaceListener import core.game.world.GameWorld +import content.data.Quests +import content.global.handlers.iface.ScrollInterface +import org.rs09.consts.Components @Initializable -class TheGolemQuest : Quest("The Golem", 70, 69, 1, 437, 0, 1, 10) { +class TheGolemQuest : Quest(Quests.THE_GOLEM, 70, 69, 1, 437, 0, 1, 10) { override fun newInstance(`object`: Any?): Quest { return this } @@ -111,19 +114,6 @@ class ClayGolemNPC : AbstractNPC { } } -class LetterListener : InterfaceListener { - override fun defineInterfaceListeners() { - onOpen(220) { player, component -> - val lines: Array = player.getAttribute("ifaces:220:lines", arrayOf()) - for(i in 0 until Math.min(lines.size, 15)) { - setInterfaceText(player, lines[i], 220, i+1) - //setInterfaceText(player, "${i}", 220, i+1) - } - return@onOpen true - } - } -} - class DisplayCaseListener : InterfaceListener { override fun defineInterfaceListeners() { onOpen(534) { player, component -> @@ -140,7 +130,7 @@ class DisplayCaseListener : InterfaceListener { class TheGolemListeners : InteractionListener { fun repairGolem(player: Player): Boolean { - if(player.questRepository.getStage("The Golem") == 1) { + if(player.questRepository.getStage(Quests.THE_GOLEM) == 1) { var clayUsed = player.getAttribute("the-golem:clay-used", 0) val msg = when(clayUsed) { 0 -> "You apply some clay to the golem's wounds. The clay begins to harden in the hot sun." @@ -157,7 +147,7 @@ class TheGolemListeners : InteractionListener { player.setAttribute("/save:the-golem:clay-used", clayUsed) updateVarps(player) if(clayUsed == 4) { - setQuestStage(player, "The Golem", 2) + setQuestStage(player, Quests.THE_GOLEM, 2) } } } @@ -213,13 +203,13 @@ class TheGolemListeners : InteractionListener { val rotation3 = player.getAttribute("the-golem:statuette-rotation:3", 0) val doorOpen = player.getAttribute("the-golem:door-open", false) var clientStage = 0 - if(player.questRepository.getStage("The Golem") > 0) { + if(player.questRepository.getStage(Quests.THE_GOLEM) > 0) { clientStage = Math.max(clientStage, 1) } if(doorOpen) { clientStage = Math.max(clientStage, 5) } - if(player.questRepository.getStage("The Golem") >= 100) { + if(player.questRepository.getStage(Quests.THE_GOLEM) >= 100) { clientStage = Math.max(clientStage, 10) } setVarbit(player, 346, clientStage) @@ -346,9 +336,9 @@ class TheGolemListeners : InteractionListener { player.sendMessage("You don't know what that would do.") return true } - if(player.questRepository.getStage("The Golem") == 7) { + if(player.questRepository.getStage(Quests.THE_GOLEM) == 7) { player.sendMessage("You insert the key and the golem's skull hinges open.") - setQuestStage(player, "The Golem", 8) + setQuestStage(player, Quests.THE_GOLEM, 8) } return true } @@ -371,9 +361,8 @@ class TheGolemListeners : InteractionListener { on(34978, IntType.SCENERY, "climb-down") { player, node -> core.game.global.action.ClimbActionHandler.climb(player, core.game.global.action.ClimbActionHandler.CLIMB_DOWN, core.game.global.action.SpecialLadders.getDestination(node.location)); return@on true } on(6372, IntType.SCENERY, "climb-up") { player, node -> core.game.global.action.ClimbActionHandler.climb(player, core.game.global.action.ClimbActionHandler.CLIMB_UP, core.game.global.action.SpecialLadders.getDestination(node.location)); return@on true } on(4615, IntType.ITEM, "read") { player, node -> - player.setAttribute("ifaces:220:lines", LETTER_LINES) player.setAttribute("/save:the-golem:read-elissa-letter", true) - openInterface(player, 220) + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, LETTER_LINES) return@on true } on(35226, IntType.SCENERY, "search") { player, node -> @@ -393,7 +382,7 @@ class TheGolemListeners : InteractionListener { if(!player.getAttribute("the-golem:seen-demon", false)) { player.sendMessage("The room is dominated by a colossal horned skeleton!") player.setAttribute("/save:the-golem:seen-demon", true) - setQuestStage(player, "The Golem", 4) + setQuestStage(player, Quests.THE_GOLEM, 4) } teleport(player, Location.create(3552, 4948, 0)) return@on true diff --git a/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt b/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt index 75cafd258..dda6a88bf 100644 --- a/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt +++ b/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.game.node.entity.player.Player @@ -288,8 +289,9 @@ class VarmensNotes : InteractionListener { } override fun defineListeners() { - on(Items.VARMENS_NOTES_4616, IntType.ITEM, "read") { player, _ -> + on(Items.VARMENS_NOTES_4616, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java index 93e263e25..4afd56007 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -48,7 +49,7 @@ public final class AlShabimDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { default: npc("Hello Effendi!"); diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java index 6f5d0444a..efb949796 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.interaction.NodeUsageEvent; import core.game.interaction.UseWithHandler; @@ -57,7 +58,7 @@ public final class AnaDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if ((quest.getStage(player) == 71 || quest.getStage(player) == 72) && args.length > 1) { player.getDialogueInterpreter().sendDialogue("You see a barrel coming to the surface. Before too long you haul it", "onto the side. The barrel seems quite heavy and you hear a muffled", "sound coming from inside."); stage = 400; @@ -277,7 +278,7 @@ public final class AnaDialogue extends DialoguePlugin { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { case 61: player.getDialogueInterpreter().open(822, event.getUsedWith(), true); @@ -320,7 +321,7 @@ public final class AnaDialogue extends DialoguePlugin { @Override public boolean isHidden(final Player player) { - Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if (quest.getStage(player) > 61) { return true; } diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java index 8cdabc88d..420714f24 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -46,7 +47,7 @@ public final class BedabinNomadDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (npc.getId()) { case 834:// guard switch (quest.getStage(player)) { diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java index 447929a6c..9de225a64 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -42,7 +43,7 @@ public final class CaptainSiadDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { default: player.getPacketDispatch().sendMessage("The captain looks up from his work as you address him."); diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java index e979daefd..9c9a08367 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java @@ -2,6 +2,7 @@ package content.region.desert.quest.thetouristrap; import java.util.List; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.npc.NPC; @@ -57,7 +58,7 @@ public final class DesertGuardDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (npc.getId()) { case 5001: switch (quest.getStage(player)) { diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java index 19b3b768f..8788371b8 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.skill.Skills; import core.game.node.entity.npc.NPC; @@ -48,7 +49,7 @@ public final class IrenaDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if (quest.getStage(player) == 95 && player.getInventory().containsItem(TouristTrap.ANNA_BARREL)) { npc("Hey, great you've found Ana!"); stage = 900; diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java index 2ee5e3456..269f4185a 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -47,7 +48,7 @@ public final class MaleSlaveDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (npc.getShownNPC(player).getId()) { case 4985: case 825: diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java index f959a1fbe..e020f6793 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.Entity; import core.game.node.entity.npc.AbstractNPC; @@ -52,7 +53,7 @@ public final class MercenaryCaptainDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { case 11: interpreter.sendDialogue("You approach the Mercenary Captain."); @@ -183,7 +184,7 @@ public final class MercenaryCaptainDialogue extends DialoguePlugin { super.finalizeDeath(killer); if (killer instanceof Player) { final Player player = (Player) killer; - final Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { case 0: case 10: diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java index c9fd6d862..4f063203c 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -46,7 +47,7 @@ public final class MercenaryDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { default: npc("What are you doing here?"); diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java index e9ef2dbb6..a748227fd 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -46,7 +47,7 @@ public final class MinecartDriverDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); switch (quest.getStage(player)) { case 90: npc("Quickly, get in the back of the cart."); diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java b/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java index 75aa27944..ae06c8e0a 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.game.interaction.Option; import core.game.node.Node; import core.game.node.entity.Entity; @@ -83,7 +84,7 @@ public final class MiningCampZone extends MapZone implements Plugin { * @return {@code True} if removed. */ public boolean checkAnna(final Player p) { - final Quest quest = p.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = p.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if (p.getAttribute("ana-delay", 0) > GameWorld.getTicks()) { return false; } diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java index e81eb6764..75f4d6134 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java @@ -14,6 +14,7 @@ import core.plugin.Initializable; import core.plugin.ClassScanner; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * The main type for the tourist trap quest. @@ -23,12 +24,6 @@ import static core.api.ContentAPIKt.*; */ @Initializable public final class TouristTrap extends Quest { - - /** - * The name of the quest. - */ - public static final String NAME = "The Tourist Trap"; - /** * The metal key item. */ @@ -113,7 +108,7 @@ public final class TouristTrap extends Quest { * Constructs a new {@code TouristTrap} {@code Object}. */ public TouristTrap() { - super(NAME, 123, 122, 2, 197, 0, 1, 30); + super(Quests.THE_TOURIST_TRAP, 123, 122, 2, 197, 0, 1, 30); } @Override diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java index e8a9750dd..463d61272 100644 --- a/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java +++ b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java @@ -1,5 +1,6 @@ package content.region.desert.quest.thetouristrap; +import content.data.Quests; import core.cache.def.impl.AnimationDefinition; import core.cache.def.impl.NPCDefinition; import core.cache.def.impl.SceneryDefinition; @@ -135,7 +136,7 @@ public final class TouristTrapPlugin extends OptionHandler { @Override public boolean handle(final Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); final int id = node.getId(); switch (option) { case "read": @@ -356,7 +357,7 @@ public final class TouristTrapPlugin extends OptionHandler { player.getInventory().add(TouristTrap.CELL_DOOR_KEY, player); player.getDialogueInterpreter().sendItemMessage(TouristTrap.CELL_DOOR_KEY, "You find a cell door key."); break; - } else if (hasItem(player, TouristTrap.WROUGHT_IRON_KEY) && player.getQuestRepository().isComplete(TouristTrap.NAME)) { + } else if (hasItem(player, TouristTrap.WROUGHT_IRON_KEY) && player.getQuestRepository().isComplete(Quests.THE_TOURIST_TRAP)) { player.getInventory().add(TouristTrap.WROUGHT_IRON_KEY, player); player.getDialogueInterpreter().sendItemMessage(TouristTrap.WROUGHT_IRON_KEY, "You find the key to the main gate."); break; @@ -633,7 +634,7 @@ public final class TouristTrapPlugin extends OptionHandler { case 516: player.getInventory().remove(TouristTrap.ANNA_BARREL); player.getBank().remove(TouristTrap.ANNA_BARREL); - player.getQuestRepository().getQuest(TouristTrap.NAME).setStage(player, 71); + player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP).setStage(player, 71); end(); break; case 0: @@ -700,7 +701,7 @@ public final class TouristTrapPlugin extends OptionHandler { @Override public boolean handle(final NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if (event.getUsedWith().getId() == 18958) {// cart if (quest.getStage(player) == 72) { player.lock(4); @@ -800,7 +801,7 @@ public final class TouristTrapPlugin extends OptionHandler { } break; case 33: - player.getQuestRepository().getQuest(TouristTrap.NAME).setStage(player, 70); + player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP).setStage(player, 70); player.getInventory().remove(TouristTrap.ANNA_BARREL); player.removeAttribute("ana-delay"); AnnaCartCutscene.this.stop(true); @@ -905,7 +906,7 @@ public final class TouristTrapPlugin extends OptionHandler { case 6: player.unlock(); player.getInterfaceManager().closeOverlay(); - player.getQuestRepository().getQuest(TouristTrap.NAME).setStage(player, 95); + player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP).setStage(player, 95); player.getInterfaceManager().close(); player.getProperties().setTeleportLocation(Location.create(3258, 3029, 0)); player.getInventory().add(TouristTrap.ANNA_BARREL); @@ -1303,7 +1304,7 @@ public final class TouristTrapPlugin extends OptionHandler { @Override public boolean open(Object... args) { barrel = (Scenery) args[0]; - quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if ((quest.getStage(player) == 70 || quest.getStage(player) == 72) && !player.hasItem(TouristTrap.ANNA_BARREL)) { interpreter.sendDialogue("You search the barrels and find Ana."); stage = 400; @@ -1402,7 +1403,7 @@ public final class TouristTrapPlugin extends OptionHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if (quest.getStage(player) == 54 && player.getInventory().containsItem(TouristTrap.TECHNICAL_PLANS)) { player.getDialogueInterpreter().open("bedabin-anvil"); return true; @@ -1436,7 +1437,7 @@ public final class TouristTrapPlugin extends OptionHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest(TouristTrap.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); if (!event.getUsedWith().getLocation().equals(Location.create(3292, 9423, 0))) { return false; } diff --git a/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java b/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java index 776b39973..60cfad2e1 100644 --- a/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java +++ b/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java @@ -2,6 +2,7 @@ package content.region.desert.sophanem.handlers; import core.cache.def.impl.SceneryDefinition; import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; import core.game.interaction.OptionHandler; import core.game.node.Node; import core.game.node.entity.player.Player; @@ -13,10 +14,11 @@ import core.plugin.Initializable; import core.plugin.Plugin; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * The plugin for handling stuff in Sophanem. - * @author jamix77 + * @author jamix77, Player Name * */ @Initializable @@ -26,6 +28,9 @@ public class SophanemPlugin extends OptionHandler { public Plugin newInstance(Object arg) throws Throwable { SceneryDefinition.forId(20277).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(20275).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(20391).getHandlers().put("option:open", this); + SceneryDefinition.forId(28514).getHandlers().put("option:open", this); + SceneryDefinition.forId(20341).getHandlers().put("option:open", this); return this; } @@ -34,15 +39,24 @@ public class SophanemPlugin extends OptionHandler { final int id = node instanceof Scenery ? ((Scenery) node).getId() : ((Item) node).getId(); switch (id) { case 20275: - if (!hasRequirement(player, "Contact!")) - break; + if (!hasRequirement(player, Quests.CONTACT)) { + break; + } ClimbActionHandler.climb(player, new Animation(827), Location.create(2799, 5160, 0)); break; case 20277: ClimbActionHandler.climb(player, new Animation(828), Location.create(3315,2796,0)); break; + case 20391: + case 28514: + if (!hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)) { + break; + } + DoorActionHandler.handleDoor(player, (Scenery) node); + break; + case 20341: + break; } return true; } - } diff --git a/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt b/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt index b654b8b27..f2b790453 100644 --- a/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt +++ b/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt @@ -1,8 +1,11 @@ package content.region.desert.ullek.handlers +import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength import core.game.world.map.Location +import core.game.world.update.flag.context.Animation import org.rs09.consts.Scenery class UllekListeners : InteractionListener { @@ -23,5 +26,17 @@ class UllekListeners : InteractionListener { player.properties.teleportLocation = Location.create(3419, 2803, 1) return@on true } + on(Scenery.REEDS_28474, IntType.SCENERY, "push through") { player, node -> + animate(player, 7633) + animateScenery(node as core.game.node.scenery.Scenery, 7634) + queueScript(player, animationDuration(Animation(7633)), QueueStrength.SOFT) { + val newLoc = node.location.transform(Location.getDelta(player.location, node.location)) + player.walkingQueue.reset() + player.walkingQueue.addPath(newLoc.x, newLoc.y) + + return@queueScript stopExecuting(player) + } + return@on true + } } } \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java b/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java index 4fed3f6b9..2af173c7d 100644 --- a/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java +++ b/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java @@ -10,8 +10,11 @@ import core.plugin.Initializable; import java.util.ArrayList; import java.util.List; +import static core.api.ContentAPIKt.addItemOrDrop; +import static core.api.ContentAPIKt.hasAnItem; + /** - * Handles the dialogue for jossik. + * Handles the dialogue for Jossik. * @author Vexia */ @Initializable @@ -71,23 +74,24 @@ public class JossikDialogue extends DialoguePlugin { case 20: boolean missing = false; for (GodBook book : GodBook.values()) { - if (player.getSavedData().getGlobalData().hasCompletedGodBook(book) && !player.hasItem(book.getBook())) { + if (player.getSavedData().getGlobalData().hasCompletedGodBook(book) && hasAnItem(player, book.getBook().getId(), true).getContainer() == null) { + // i.e.: if you have a completed book on file but you lost it missing = true; - player.getInventory().add(book.getBook(), player); - npc("As a matter of fact, I did! This book washed up on the", "beach, and I recognised it as yours!"); + addItemOrDrop(player, book.getBook().getId(), 1); } } int damaged = player.getSavedData().getGlobalData().getGodBook(); - if (damaged != -1 && !player.hasItem(GodBook.values()[damaged].getDamagedBook())) { + if (damaged != -1 && hasAnItem(player, GodBook.values()[damaged].getDamagedBook().getId(), true).getContainer() == null) { + // i.e.: if you have an uncompleted book on file but you lost it missing = true; - player.getInventory().add(GodBook.values()[damaged].getDamagedBook(), player); - npc("As a matter of fact, I did! This book washed up on the", "beach, and I recognised it as yours!"); + addItemOrDrop(player, GodBook.values()[damaged].getDamagedBook().getId(), 1); } if (missing) { + npc("As a matter of fact, I did! This book washed up on the", "beach, and I recognised it as yours!"); stage = 23; return true; } - uncompleted = new ArrayList<>(5); + uncompleted = new ArrayList<>(3); for (GodBook book : GodBook.values()) { if (!player.getSavedData().getGlobalData().hasCompletedGodBook(book)) { uncompleted.add(book); @@ -95,12 +99,12 @@ public class JossikDialogue extends DialoguePlugin { } boolean hasUncompleted = false; for (GodBook book : GodBook.values()) { - if (player.hasItem(book.getDamagedBook())) { + if (hasAnItem(player,book.getDamagedBook().getId(), true).getContainer() != null) { + // i.e.: you have an uncompleted book on file and you still have it -> do not allow the player to get a new one, GL #2035 hasUncompleted = true; } } - if (uncompleted.size() == 0 || hasUncompleted) {// all - // completed. + if (uncompleted.isEmpty() || hasUncompleted) {// all completed. npc("No, sorry adventurer, I haven't."); stage = 23; return true; diff --git a/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java b/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java index 1b2af20f7..19e639678 100644 --- a/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java +++ b/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java @@ -12,6 +12,7 @@ import core.net.packet.context.MinimapStateContext; import core.plugin.Initializable; import core.net.packet.out.MinimapState; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles the lokar searunner dialogue. @@ -110,7 +111,7 @@ public class LokarSearunnerDialogue extends DialoguePlugin { * @param location the location. */ private void travel(final Player player, final Location location) { - if (!hasRequirement(player, "Lunar Diplomacy")) + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return; player.lock(); GameWorld.getPulser().submit(new Pulse(1, player) { diff --git a/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt b/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt index e6367c387..51d160974 100644 --- a/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt +++ b/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt @@ -17,6 +17,7 @@ import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.skill.Skills import core.game.world.map.zone.ZoneBorders import org.rs09.consts.* +import content.data.Quests class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) { companion object { @@ -322,7 +323,7 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) { } // You can alternatively browse her regular clothing store to complete the task, no purchase necessary. - if (event.target.id == NPCs.YRSA_1301 && event.option == "trade" && player.questRepository.isComplete("Fremennik Trials") && inBorders(player, YRSA_SHOP_BORDERS)) { + if (event.target.id == NPCs.YRSA_1301 && event.option == "trade" && player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS) && inBorders(player, YRSA_SHOP_BORDERS)) { finishTask( player, DiaryLevel.MEDIUM, diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt index b4e2b45bf..e4ed6b691 100644 --- a/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt @@ -8,6 +8,7 @@ import content.region.fremennik.rellekka.handlers.RellekkaDestination import content.region.fremennik.rellekka.handlers.RellekkaUtils import core.tools.END_DIALOGUE import core.api.* +import content.data.Quests @Initializable class MordGunnarsDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { @@ -35,7 +36,7 @@ class MordGunnarsDialogue(player: Player? = null) : core.game.dialogue.DialogueP 2 -> { end() - if (!hasRequirement(player, "Fremennik Trials")) + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) return true RellekkaUtils.sail(player, if(npc.id == NPCs.MORD_GUNNARS_5481) RellekkaDestination.RELLEKKA_TO_JATIZSO else RellekkaDestination.JATIZSO_TO_RELLEKKA) } diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/SirsalBankerDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/SirsalBankerDialogue.kt deleted file mode 100644 index ebe225e11..000000000 --- a/Server/src/main/content/region/fremennik/lunarisle/dialogue/SirsalBankerDialogue.kt +++ /dev/null @@ -1,209 +0,0 @@ -package content.region.fremennik.lunarisle.dialogue - -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.player.Player -import core.game.node.entity.player.link.IronmanMode -import core.plugin.Initializable -import org.rs09.consts.NPCs -import core.game.dialogue.IfTopic -import core.game.dialogue.Topic -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE - -/** - * Handles Sirsal banker dialogue tree. - * - * @author vddCore - */ -@Initializable -class SirsalBankerDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - START_DIALOGUE -> if (hasSealOfPassage(player)) { - if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { - npcl( - FacialExpression.NEUTRAL, - "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + - "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}" - ).also { stage = END_DIALOGUE } - } else { - - npcl( - FacialExpression.NEUTRAL, - "Good day, how may I help you?" - ).also { - if (hasAwaitingGrandExchangeCollections(player)) { - stage++ - } else { - stage += 2 - } - } - } - } else { - playerl(FacialExpression.HALF_WORRIED, "Hi, I...") - stage = 30 - } - - 1 -> npcl( - FacialExpression.NEUTRAL, - "Before we go any further, I should inform you that you " + - "have items ready for collection from the Grand Exchange." - ).also { stage++ } - - 2 -> showTopics( - Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account, please.", 10), - IfTopic( - FacialExpression.NEUTRAL, - "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", - 13, - hasActivatedSecondaryBankAccount(player) - ), - IfTopic( - FacialExpression.NEUTRAL, - "I'd like to open a secondary bank account.", - 20, - !hasActivatedSecondaryBankAccount(player) - ), - Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 11), - Topic(FacialExpression.NEUTRAL, "I'd like to collect items.", 12), - Topic(FacialExpression.ASKING, "What is this place?", 3), - ) - - 3 -> npcl( - FacialExpression.NEUTRAL, - "This is a branch of the Bank of Gielinor. We have branches in many towns." - ).also { stage++ } - - 4 -> playerl( - FacialExpression.ASKING, - "And what do you do?" - ).also { stage++ } - - 5 -> npcl( - FacialExpression.NEUTRAL, - "We will look after your items and money for you. " + - "Leave your valuables with us if you want to keep them safe." - ).also { stage = END_DIALOGUE } - - 10 -> { - openBankAccount(player) - end() - } - - 11 -> { - openBankPinSettings(player) - end() - } - - 12 -> { - openGrandExchangeCollectionBox(player) - end() - } - - 13 -> { - toggleBankAccount(player) - - npcl( - FacialExpression.NEUTRAL, - "Your active bank account has been switched. " + - "You can now access your ${getBankAccountName(player)} account." - ).also { stage = END_DIALOGUE } - } - - 20 -> npcl( - FacialExpression.NEUTRAL, - "Certainly. We offer secondary accounts to all our customers." - ).also { stage++ } - - 21 -> npcl( - FacialExpression.NEUTRAL, - "The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable " + - "and account activation is permanent." - ).also { stage++ } - - 22 -> npcl( - FacialExpression.NEUTRAL, - "If your inventory does not contain enough money to cover the costs, we will complement " + - "the amount with the money inside your primary bank account." - ).also { stage++ } - - 23 -> npcl( - FacialExpression.ASKING, - "Knowing all this, would you like to proceed with opening your secondary bank account?" - ).also { stage++ } - - 24 -> showTopics( - Topic(FacialExpression.NEUTRAL, "Yes, I am still interested.", 25), - Topic(FacialExpression.NEUTRAL, "Actually, I've changed my mind.", 26) - ) - - 25 -> { - when (activateSecondaryBankAccount(player)) { - SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> { - npcl( - FacialExpression.NEUTRAL, - "Your bank account was already activated, there is no need to pay twice." - ).also { stage = END_DIALOGUE } - } - - SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> { - npcl( - FacialExpression.NEUTRAL, - "I must apologize, the transaction was not successful. Please check your " + - "primary bank account and your inventory - if there's money missing, please " + - "screenshot your chat box and contact the game developers." - ).also { stage = END_DIALOGUE } - } - - SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> { - npcl( - FacialExpression.NEUTRAL, - "It appears that you do not have the money necessary to cover the costs " + - "associated with opening a secondary bank account. I will be waiting here " + - "until you do." - ).also { stage = END_DIALOGUE } - } - - SecondaryBankAccountActivationResult.SUCCESS -> { - npcl( - FacialExpression.NEUTRAL, - "Your secondary bank account has been opened and can be accessed through any " + - "of the Bank of Gielinor's employees. Thank you for choosing our services." - ).also { stage = END_DIALOGUE } - } - } - } - - 26 -> npcl( - FacialExpression.NEUTRAL, - "Very well. Should you decide a secondary bank account is needed, do not hesitate to " + - "contact any of the Bank of Gielinor's stationary employees. We will be happy to help." - ).also { stage = END_DIALOGUE } - - 30 -> npcl( - FacialExpression.ANNOYED, - "What are you doing here, Fremennik?!" - ).also { stage++ } - - 31 -> playerl( - FacialExpression.WORRIED, - "I have a Seal of Pass..." - ).also { stage++ } - - 32 -> npcl( - FacialExpression.ANGRY, - "No you don't! Begone!" - ).also { stage = END_DIALOGUE } - - /* TODO: Is the above related to Lunar Diplomacy? */ - } - - return true - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.SIRSAL_BANKER_4519) - } -} diff --git a/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java b/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java index e746965b7..135470838 100644 --- a/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java +++ b/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java @@ -135,9 +135,6 @@ public class YakArmourPlugin extends UseWithHandler { player.getInventory().add(node); player.getSkills().addExperience(Skills.CRAFTING, 32, true); LeatherCrafting.decayThread(player); - if (LeatherCrafting.isLastThread(player)) { - LeatherCrafting.removeThread(player); - } player.sendMessage("You make " + node.getName().toLowerCase() + "."); } amount--; diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt index 216967b80..47b7a42e5 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,9 +19,9 @@ class BjornAndEldgrimDialogues(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { player(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } - } else if (isQuestComplete(player, "Fremennik Trials")) { + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npc(FacialExpression.DRUNK, "Hey! Itsh you again! Whatshyerfashe!").also { stage = 10 } } return true diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt index 1bc5c3712..52a931e01 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,7 +19,7 @@ class BlaninDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { player(FacialExpression.FRIENDLY, "Good day.").also { stage = 0 } } else { player(FacialExpression.FRIENDLY, "That's one less thing to worry about.").also { stage = 10 } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt index 8e6434f54..c54085080 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt @@ -7,12 +7,13 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType import core.plugin.Initializable +import content.data.Quests @Initializable class CouncilWorkerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if(getQuestStage(player, "Fremennik Trials") in 1..99){ + if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) in 1..99){ player.dialogueInterpreter.open((CouncilWorkerFTDialogue(1))) } else if(player.achievementDiaryManager.getDiary(DiaryType.FREMENNIK).isComplete(0, true)){ diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt index 586034287..d2f20660e 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,7 +19,7 @@ class DronDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Making History")) { + if (!isQuestComplete(player, Quests.MAKING_HISTORY)) { player(FacialExpression.FRIENDLY, "Excuse me.").also { stage = 0 } } else { player(FacialExpression.FRIENDLY, "Excuse me.").also { stage = 10 } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt index 8a35e9dc3..ae896659c 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,7 +19,7 @@ class FishmongerRellekkaDialogue(player: Player? = null) : DialoguePlugin(player override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npc(FacialExpression.ANNOYED, "I don't sell to outerlanders.").also { stage = END_DIALOGUE } } else { npcl(FacialExpression.FRIENDLY,"Hello there, ${player.getAttribute("fremennikname","fremmyname")}. Looking for fresh fish?").also { stage = 0 } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt index e8f11f81c..a117d29ed 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,7 +19,7 @@ class FurTraderDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npc(FacialExpression.ANNOYED, "I don't sell to outerlanders.").also { stage = END_DIALOGUE } } else { npcl(FacialExpression.FRIENDLY,"Welcome back, ${player.getAttribute("fremennikname","fremmyname")}. Have you seen the furs I have today?").also { stage = 10 } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt index bf81e8182..ba86e5be8 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,11 +19,11 @@ class IngridHradsonDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npcl(FacialExpression.ANNOYED, "Outlander, I have work to be getting on with... Please stop bothering me.").also { stage = END_DIALOGUE } - } else if (isQuestComplete(player, "Fremennik Trials") && !isQuestComplete(player, "Olaf's Quest")) { + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && !isQuestComplete(player, Quests.OLAFS_QUEST)) { npc(FacialExpression.FRIENDLY, "Good afternoon! How do you like our village?").also { stage = 0 } - } else if (isQuestComplete(player, "Fremennik Trials") && isQuestComplete(player, "Olaf's Quest")) { + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && isQuestComplete(player, Quests.OLAFS_QUEST)) { npc(FacialExpression.ASKING, "Hello again! Have you any word from my husband?").also { stage = 10 } } return true diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.java b/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.java deleted file mode 100644 index 9816e764b..000000000 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.java +++ /dev/null @@ -1,251 +0,0 @@ -package content.region.fremennik.rellekka.dialogue; - -import core.game.component.Component; -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import kotlin.Unit; -import core.game.world.GameWorld; -import core.game.world.map.Location; - -import static core.api.ContentAPIKt.*; - -/** - * Handles the jarvald dialogue. - * @author Vexia - */ -public final class JarvaldDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code JarvaldDialogue} {@code Object}. - */ - public JarvaldDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code JarvaldDialogue} {@code Object}. - * @param player the player. - */ - public JarvaldDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new JarvaldDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - if (args.length > 1) { - handleTravelStage(); - return true; - } - if (npc.getId() == 2438) { - npc("Ah, you live yet, outerlander!"); - stage = 37; - return true; - } - npc("What do you want from me outerlander?", "It is our policy not to associate with those not of our", "tribe."); - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - options("Where is your chieftain?", "What Jarvald is doing.", "Nothing"); - stage++; - break; - case 1: - switch (buttonId) { - case 1: - player("Where is your chieftain?", "I find it highly discriminatory to refuse to talk to", "someone on the grounds that they are not part of your", "tribe."); - stage = 10; - break; - case 2: - player("So what are you doing here?"); - stage = 20; - break; - case 3: - end(); - break; - } - break; - case 10: - npc("I don't rightly understand your speech outerlander, but", "my loyality is with Chieftain Brundt."); - stage++; - break; - case 11: - npc("He resides in our longhall; it is the large building over", "there, you should speak to him for he speaks for us all."); - stage++; - break; - case 12: - end(); - break; - case 20: - handleTravelStage(); - break; - case 21: - player("Hey, scary barbarian type guy, think I can join you on", "this expedition?"); - stage++; - break; - case 22: - npc("An outerlander join us on a honoured hunt???"); - stage++; - break; - case 23: - npc("Well.....", "I gues...", "I might be able to allow you to join us, although it is a", "breach of many of our customs..."); - stage++; - break; - case 24: - player("Oh, pleeeeeeease?", "I really LOVE killing stuff!"); - stage++; - break; - case 25: - npc("Well...", "I remain unconvinced that it would be wise to allow an", "outerlander to join us in such dangerous battle, but", "your ethusiasm seems genuine enough..."); - stage++; - break; - case 26: - npc("I will allow you to escort us, but you must pay me a", "sum of money first."); - stage++; - break; - case 27: - player("What?", "That's outrageous, why charge me money?", "And, uh, how much does it cost me?"); - stage++; - break; - case 28: - npc("Ah, the outerlander have stolen from my people for", "many years, in this way you can help my community", "with a small amount of money..."); - stage++; - break; - case 29: - npc("Let us say...", "1000 coins.", "Payable in advance, of course."); - stage++; - break; - case 30: - npc("For this I will take you to Waterbirth Island on my", "boat, and will bring you back here when you have had", "your fill of the hunt.", "Assuming you are still alive to wish to leave, of course."); - stage++; - break; - case 31: - setVarp(player, 520, 1 << 13, true); - end(); - break; - case 32: - options("YES", "NO"); - stage++; - break; - case 33: - switch (buttonId) { - case 1: - if (!player.getInventory().contains(995, 1000)) { - player("Sorry, I don't have enough coins."); - stage = 35; - break; - } - if (player.getInventory().remove(new Item(995, 1000))) { - sail(player, true); - } - end(); - break; - case 2: - player("No, actually I have some stuff to do here first."); - stage = 34; - break; - } - break; - case 34: - npc("As you wish.", "Come and see me when your bloodlust needs sating."); - stage++; - break; - case 35: - end(); - break; - case 36: - switch (buttonId) { - case 1: - npc("Then let us away;", "There will be death to bring here another day!"); - stage = 39; - break; - case 2: - end(); - break; - } - break; - case 37: - npc("Have you had your fill of the hunt and wish to return,", "or are you still feeling the joy of the cull?"); - stage++; - break; - case 38: - interpreter.sendOptions("Leave island?", "YES", "NO"); - stage = 36; - break; - case 39: - end(); - sail(player, false); - break; - } - return true; - } - - /** - * Sails the player to and from waterbirth. - * @param player the player. - */ - public void sail(final Player player, final boolean to) { - player.lock(); - player.getInterfaceManager().open(new Component(224)); - player.logoutListeners.put("jarvald", player1 -> { - player.setLocation(to ? Location.create(2544, 3759, 0) : Location.create(2620, 3685, 0)); - return Unit.INSTANCE; - }); - GameWorld.getPulser().submit(new Pulse(1, player) { - int count; - - @Override - public boolean pulse() { - switch (++count) { - case 5: - player.unlock(); - player.getInterfaceManager().close(); - player.getProperties().setTeleportLocation(to ? Location.create(2544, 3759, 0) : Location.create(2620, 3685, 0)); - player.getDialogueInterpreter().close(); - player.getDialogueInterpreter().sendDialogue("The ship arrives at " + (to ? "Waterbirth Island" : "Rellekka") + "."); - player.logoutListeners.remove("jarvald"); - return true; - } - return false; - } - - }); - } - - /** - * Handles the travel stage. - */ - private void handleTravelStage() { - if (npc.getId() == 2438) { - interpreter.sendOptions("Leave island?", "YES", "NO"); - stage = 36; - return; - } - if (getVarp(player, 520) == 0) { - npc("This should not concern you, outerlander.", "I am awaiting other Fremenniks to join me on an", "expedition to Waterbirth Island."); - stage = 21; - } else { - npc("So do you have the 1000 coins for my service, and are", "you ready to leave?"); - stage = 32; - } - } - - @Override - public int[] getIds() { - return new int[] { 2435, 2436, 2437, 2438 }; - } - -} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.kt new file mode 100644 index 000000000..b4dfcbdf2 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.kt @@ -0,0 +1,205 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + + +/** + * @author Player Name + */ + +@Initializable +class JarvaldDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val travelOption = args.size > 1 + val fremname = player.getAttribute("fremennikname","lebron james") + if (npc.id == NPCs.JARVALD_2438) { + // We're on Waterbirth Island + if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + if (travelOption) { + npc("So what say you, stay here for the hunt,","or return home to sweet Rellekka to feast","and drink with your tribe?").also { stage = 201 } + } else { + npc("Ah, ${fremname}! Such glorious battle","makes you feel glad of life, does it not?").also { stage = 220 } + } + } else { + if (travelOption) { + npc("Have you had your fill of the hunt and wish to return,", "or are you still feeling the joy of the cull?").also { stage = 201 } + } else { + npc("Ah, you live yet, outerlander!").also { stage = 200 } + } + } + } else { + // We're in Rellekka + if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + if (travelOption) { + npc("Of course, ${fremname}! Your presence is more than welcome","on this cull! You wish to leave now?").also { stage = 131 } + } else { + npc("Greetings, ${fremname}!").also { stage = if (fremname == "Jarvald") 100 else 102 } + } + } else { + if (travelOption) { + npc("So do you have the 1,000 coins for my service, and are", "you ready to leave?").also { stage = 41 } + } else if (isQuestInProgress(player, Quests.THE_FREMENNIK_TRIALS, 1, 100)) { + player("Hi, I don't suppose you are a member of", "the council of elders are you?").also { stage = 0 } + } else { + npc("What do you want from me outerlander?", "It is our policy not to associate with those not of our", "tribe.").also { stage = 3 } + } + } + } + return true + } + + fun sail(to: Boolean) { + lock(player, 5) + closeAllInterfaces(player) + openInterface(player, 224) + queueScript(player, 5, QueueStrength.SOFT) { + closeInterface(player) + unlock(player) + if (to) { + player.teleport(Location.create(2544, 3759, 0)) + sendDialogue("The ship arrives at Waterbirth Island.") + } else { + player.teleport(Location.create(2620, 3685, 0)) + sendDialogue("The ship arrives at Rellekka.") + } + return@queueScript stopExecuting(player) + } + } + + override fun handle(interfaceId: Int, buttonID: Int): Boolean { + val fremname = player.getAttribute("fremennikname","lebron james") + when (stage) { + 0 -> npc("No, outerlander, I have never had the honour to be asked.").also { stage++ } + 1 -> npc("I am but a lowly warrior, fighting for my people","wherever threats may appear against us...").also { stage++ } + 2 -> npc("So what do you want from me, outerlander?").also { stage++ } + 3 -> options("Where is your chieftain?", "What Jarvald is doing.", "Nothing").also { stage++ } + 4 -> when (buttonID) { + 1 -> player("Where is your chieftain?", "I find it highly discriminatory to refuse to talk to", "someone on the grounds that they are not part of your", "tribe.").also { stage++ } + 2 -> player("So what are you doing here?").also { stage = if (getVarp(player, 520) == 0) 10 else 40 } + 3 -> player("Actually, I don't think I have","anything to speak to you about...").also { stage = END_DIALOGUE } + } + 5 -> npc("I don't rightly understand your speech outerlander, but", "my loyality is with Chieftain Brundt.").also { stage++ } + 6 -> npc("He resides in our longhall; it is the large building over", "there, you should speak to him for he speaks for us all.").also { stage++ } + 7 -> end().also { stage = END_DIALOGUE } + 10 -> npc("This should not concern you, outerlander.", "I am awaiting other Fremenniks to join me on an", "expedition to Waterbirth Island.").also { stage++ } + 11 -> options("Waterbirth Island?", "Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 12 -> when (buttonID) { + 1 -> npc("It is a small crescent-shaped island","just north-west of here, outerlander.").also { stage++ } + 2 -> player("Can I come?").also { stage = 20 } + 3 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 30 } + 4 -> player("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + } + 13 -> npc("We have many legends about it,","such as the tale of the broken sky,","and the day of the green seas.").also { stage++ } + 14 -> npc("The reason I am travelling there is more serious","Fremennik business, however. I doubt an outerlander","would be interested.").also { stage++ } + 15 -> options("Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 16 -> when (buttonID) { + 1 -> player("Can I come?").also { stage = 20 } + 2 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 30 } + 3 -> player("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + } + 20 -> npc("An outerlander join us on an honoured hunt???").also { stage++ } + 21 -> npc("Well....", "I guess...", "I might be able to allow you to join us, although it is a", "breach of many of our customs...").also { stage++ } + 22 -> player("Oh, pleeeeease?", "I really LOVE killing stuff!").also { stage++ } + 23 -> npc("Well...", "I remain unconvinced that it would be wise to allow an", "outerlander to join us in such dangerous battle, but", "your ethusiasm seems genuine enough...").also { stage++ } + 24 -> npc("I will allow you to escort us, but you must pay me a", "sum of money first.").also { stage++ } + 25 -> player("What?", "That's outrageous, why charge me money?", "And, uh, how much does it cost me?").also { stage++ } + 26 -> npc("Ah, the outerlanders have stolen from my people for", "many years, in this way you can help my community", "with a small amount of money...").also { stage++ } + 27 -> npc("Let us say...", "1,000 coins.", "Payable in advance, of course.").also { stage++ } + 28 -> npc("For this I will take you to Waterbirth Island on my", "boat, and will bring you back here when you have had", "your fill of the hunt.", "Assuming you are still alive to wish to leave, of course.").also { setVarp(player, 520, 1 shl 13, true) }.also{ stage = END_DIALOGUE } + 29 -> npc("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + 30 -> npc("It is actually a helm, outerlander,","but the sentiment is appreciated nonetheless.").also { stage = END_DIALOGUE } + 40 -> npc("So do you have the 1,000 coins for my service, and are", "you ready to leave?").also { stage++ } + 41 -> options("YES", "NO").also { stage++ } + 42 -> when (buttonID) { + 1 -> if (player.inventory.contains(Items.COINS_995, 1000)) { + if (player.inventory.remove(Item(Items.COINS_995, 1000))) { + sail(true) + } + } else { + player("Sorry, I don't have enough coins.").also { stage = END_DIALOGUE } + } + 2 -> player("No, actually I have some stuff to do here first.").also { stage++ } + } + 43 -> npc("As you wish.", "Come and see me when your bloodlust needs sating.").also { stage = END_DIALOGUE } + 100 -> npc("Ah, and what a glorious name that is! Worthy of only the finest warriors!").also { stage++ } + 101 -> player("Heh. Yup, you're right there.").also { stage++ } + + 102 -> npc("So what brings you back to fair Rellekka?","It has been too long since you have drunk in the longhall","with us and sang of your battles!").also { stage++ } + 103 -> options("What Jarvald is doing.", "Nothing").also { stage++ } + 104 -> when (buttonID) { + 1 -> player("So what are you doing here?").also { stage = if (getVarp(player, 520) and (1 shl 13) == 0) 105 else 130 } + 2 -> player("Actually, I don't think I have","anything to speak to you about...").also { stage = END_DIALOGUE } + } + 105 -> npc("You have not heard, ${fremname}?","I am leading an expedition to Waterbirth Island!").also { stage++ } + 106 -> options("Waterbirth Island?", "Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 107 -> when (buttonID) { + 1 -> npc("You have not ever travelled to Waterbirth Island, ${fremname}?","I am surprised, it is a place of outstanding natural beauty.").also { stage++ } + 2 -> player("Can I come?").also { stage = 130 } + 3 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 140 } + 4 -> player("Wow, you Fremenniks sure know how to party. Well, see ya around.").also { stage = END_DIALOGUE } + } + 108 -> npc("Or at least it used to be! But things have now changed...").also { stage++ } + 109 -> player("Changed? How do you mean, changed?").also { stage++ } + 110 -> npc("It seems as though the sea-beasts known to us as","the dagger-mouths have begun their hatching once again...","And there may be others of their ilk there too.").also { stage++ } + 111 -> player("Dagger-mouths?").also { stage++ } + 112 -> npc("Aye, the dagger-mouths! The vile creatures lived","near here once, but we had thought them all driven back","to the ocean depths many moons past.").also { stage++ } + 113 -> npc("I can only imagine a dagger-mouth queen has nested","somewhere nearby and spawned her foul brood","under the sea once more, and some of them have","migrated to fair Waterbirth Island.").also { stage++ } + 114 -> player("So you're scared they might attack Rellekka?").also { stage++ } + 115 -> npc("Scared? Ha ha ha!").also { stage++ } + 116 -> npc("You wound us with your questioning, ${fremname}!").also { stage++ } + 117 -> npc("We are glad the dagger-mouths have returned to","these shores, for it means we will get the chance","to hunt them once again as our ancestors did!").also { stage++ } + 118 -> npc("When treated in the correct manner, the creatures'","remains can be used to make fine battleworthy armour!").also { setVarp(player, 520, 1 shl 13, true) }.also{ stage++ } + 119 -> options("Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 120 -> when (buttonID) { + 1 -> player("Can I come?").also { stage = 130 } + 2 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 140 } + 3 -> player("Wow, you Fremenniks sure know how to party. Well, see ya around.").also { stage = END_DIALOGUE } + } + 130 -> npc("Of course, ${fremname}! Your presence is more than welcome","on this cull! You wish to leave now?").also { stage++ } + 131 -> options("YES", "NO").also { stage++ } + 132 -> when (buttonID) { + 1 -> sail(true) + 2 -> player("No, actually I have some stuff to do here first.").also { stage = 43 } + } + 140 -> npc("Aye, that it is ${fremname}!","Skulgrimen fashioned it for me from the carcass of one","of the monsters on Waterbirth Island after our last hunt!").also { stage++ } + 141 -> npc("I hope to kill enough creatures to fashion some fine","armour as well when next we leave!").also { stage++ } + 142 -> options("Waterbirth Island?", "Can I come?", "Ok, 'bye.").also { stage++ } + 143 -> when (buttonID) { + 1 -> npc("You have not ever travelled to Waterbirth Island, ${fremname}?","I am surprised, it is a place of outstanding natural beauty.").also { stage = 108 } + 2 -> player("Can I come?").also { stage = 130 } + 3 -> player("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + } + 200 -> npc("Have you had your fill of the hunt and wish to return,", "or are you still feeling the joy of the cull?").also { stage++ } + 201 -> options("I wish to return to Rellekka.", "I want to stay here.").also { stage++ } + 202 -> when (buttonID) { + 1 -> player("I wish to return to Rellekka.").also { stage++ } + 2 -> player("I want to stay here.").also { stage = 210 } + } + 203 -> npc("Then let us away;", "There will be death to bring here another day!").also{ sail(false) } + 210 -> npc("Ha Ha Ha! A true huntsman at heart!").also { stage++ } + 211 -> npc("I myself have killed over a hundred of the dagger-","mouths, and did not think it too many!").also { stage = END_DIALOGUE } + 220 -> npc("So what say you, stay here for the hunt,","or return home to sweet Rellekka to feast","and drink with your tribe?").also { stage = 201 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JarvaldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JARVALD_2435, NPCs.JARVALD_2436, NPCs.JARVALD_2437, NPCs.JARVALD_2438) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt index 6e7db868e..296b0a7fc 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,7 +19,7 @@ class LonghallBouncerDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npcl(FacialExpression.ANNOYED, "Hey, outerlander. You can't go through there. Talent only, backstage.").also { stage = END_DIALOGUE } } else{ npcl(FacialExpression.ANNOYED, "You can't go through there. Talent only, backstage.").also { stage = 0 } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java b/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java index 766227b3a..b998fa8af 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java @@ -7,6 +7,7 @@ import content.region.fremennik.rellekka.handlers.RellekkaDestination; import content.region.fremennik.rellekka.handlers.RellekkaUtils; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles the maria gunnars dialogue. @@ -65,7 +66,7 @@ public class MariaGunnarsDialogue extends DialoguePlugin { break; case 3: end(); - if (!hasRequirement(player, "Fremennik Trials")) + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) break; if (npc.getId() == 5508) { RellekkaUtils.sail(player, RellekkaDestination.RELLEKKA_TO_NEITIZNOT); diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt index b1ae7e78d..9636f23ae 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,7 +19,7 @@ class ReesoDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npcl(FacialExpression.ANNOYED, "Please do not disturb me, outerlander. I have much to do.").also { stage = END_DIALOGUE } } else { npcl(FacialExpression.STRUGGLE, "Sorry, ${player.getAttribute("fremennikname","fremmyname")}, I must get on with my work.").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt index ecb633408..6c371733a 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt @@ -8,10 +8,11 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz - * There is no available dialogue for after Fremennik Trials, + * There is no available dialogue for after The Fremennik Trials, * only after Hero's Welcome which isn't in this revision. */ @@ -20,7 +21,7 @@ class TalkToChiefDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npcl(FacialExpression.ANNOYED, "I cannot speak to you outerlander! Talk to Brundt, the Chieftain!").also { stage = END_DIALOGUE } } else { player(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt index 59e104ce2..315312236 100644 --- a/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests /** * @author qmqz @@ -18,11 +19,11 @@ class VolfOlasfsonDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { npc(FacialExpression.ANNOYED, "Sorry, outlander, but I have things to be doing.").also { stage = END_DIALOGUE } - } else if (isQuestComplete(player, "Fremennik Trials") && !isQuestComplete(player, "Olaf's Quest")) { + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && !isQuestComplete(player, Quests.OLAFS_QUEST)) { npc(FacialExpression.FRIENDLY, "Hello there. Enjoying the view?").also { stage = 0 } - } else if (isQuestComplete(player, "Fremennik Trials") && isQuestComplete(player, "Olaf's Quest")) { + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && isQuestComplete(player, Quests.OLAFS_QUEST)) { npcl(FacialExpression.ASKING, "Hello again, friend! Does my father send any word... or treasures like before?").also { stage = 10 } } return true diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt index 33fc0d94f..cac9e67e8 100644 --- a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt @@ -5,6 +5,7 @@ import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.world.map.Location import org.rs09.consts.NPCs +import content.data.Quests /** * File to be used for anything Rellekka related. @@ -48,7 +49,7 @@ class RellekkaListeners : InteractionListener { } on(NPCs.MARIA_GUNNARS_5508, IntType.NPC, "ferry-neitiznot"){ player, _ -> - if (!hasRequirement(player, "Fremennik Trials")) + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) return@on true RellekkaUtils.sail(player, RellekkaDestination.RELLEKKA_TO_NEITIZNOT) playJingle(player, 171) @@ -62,7 +63,7 @@ class RellekkaListeners : InteractionListener { } on(NPCs.MORD_GUNNARS_5481, IntType.NPC, "ferry-jatizso"){ player, node -> - if (!hasRequirement(player, "Fremennik Trials")) + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) return@on true RellekkaUtils.sail(player, RellekkaDestination.RELLEKKA_TO_JATIZSO) playJingle(player, 171) diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java index 75d7c1e34..4698885bb 100644 --- a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java @@ -1,6 +1,5 @@ package content.region.fremennik.rellekka.handlers; -import content.region.fremennik.rellekka.dialogue.JarvaldDialogue; import content.region.fremennik.rellekka.dialogue.MariaGunnarsDialogue; import core.cache.def.impl.SceneryDefinition; import core.game.system.task.Pulse; @@ -41,7 +40,6 @@ public final class RellekkaZone extends MapZone implements Plugin { @Override public Plugin newInstance(Object arg) throws Throwable { ZoneBuilder.configure(this); - ClassScanner.definePlugin(new JarvaldDialogue()); ClassScanner.definePlugins(new RellekaOptionHandler(), new MariaGunnarsDialogue()); ClassScanner.definePlugin(new OptionHandler() { diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt index 387ccc2e7..526732374 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt @@ -6,6 +6,7 @@ import core.game.dialogue.FacialExpression import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable //Disabled because the quest isn't done yet. @@ -27,12 +28,12 @@ class AskeladdenDialogue(player: Player? = null) : DialoguePlugin(player) { stage = 35 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(FacialExpression.HAPPY,"Hello again Askeladden.") stage = 40 return true } - else if (it.questRepository.getStage("Fremennik Trials") > 0) { + else if (it.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS) > 0) { player("Hello there.") stage = 0 return true diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt index cd70b295b..ac6cc0c24 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt @@ -10,6 +10,7 @@ import core.tools.END_DIALOGUE import kotlin.random.Random import org.rs09.consts.* +import content.data.Quests @Initializable class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ @@ -42,33 +43,33 @@ class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ stage = 500 return true } - else if(player.getAttribute("fremtrials:votes",0) >= 7){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",0) >= 7) { npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") stage = 545 return true } - else if(player.getAttribute("fremtrials:votes",0) in 3..6){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",0) in 3..6) { npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") stage = 540 return true } - else if(player.getAttribute("fremtrials:votes",0) == 1){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",0) == 1) { npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") stage = 535 return true } - else if(player.getAttribute("fremtrials:votes",-1) == 0){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",-1) == 0) { npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") stage = 530 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ npcl(FacialExpression.HAPPY,"Hello again, $gender $fName. I hope your travels have brought you wealth and joy! What compels you to visit me on this day?") stage = 600 return true } - else if(player?.questRepository?.getStage("Fremennik Trials")!! == 0) { - npc("Greetings outlander!") + else if(player?.questRepository?.getStage(Quests.THE_FREMENNIK_TRIALS)!! == 0) { + npc("Greetings outerlander!") stage = 0 } return true @@ -99,7 +100,7 @@ class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ //Do you have any quests? - 300 -> {npc("Quests, you say outlander? Well, I would not call it a","quest as such, but if you are brave of heart and strong","of body, perhaps..."); stage++} + 300 -> {npc("Quests, you say outerlander? Well, I would not call it a","quest as such, but if you are brave of heart and strong","of body, perhaps..."); stage++} 301 -> {npc("No, you would not be interested. Forget I said","anything, outerlander."); stage++ } 302 -> {options("Yes, I am interested.","No, I'm not interested."); stage++ } 303 -> when(buttonId){ @@ -124,7 +125,7 @@ class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ //I think I would enjoy the challenge of becoming an honorary fremennik 320 -> {npc("As I say outerlander, you must find and speak to the","twelve members of the council of elders, and see what","tasks they might set you.");stage++} - 321 -> {npc("If you can gain the support of seven of the twelve, then","you will be accepted as one of us without question.");stage = 1000;player?.questRepository?.getQuest("Fremennik Trials")?.start(player)} + 321 -> {npc("If you can gain the support of seven of the twelve, then","you will be accepted as one of us without question.");stage = 1000;player?.questRepository?.getQuest(Quests.THE_FREMENNIK_TRIALS)?.start(player)} //That sounds too complicated for me. 322 -> {npc("Well, that's what I expect from an outerlander.");stage = 1000} @@ -172,21 +173,15 @@ class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ 545 -> playerl(FacialExpression.HAPPY,"I have seven members of the council prepared to vote in my favour now!").also { stage++ } 546 -> npcl(FacialExpression.HAPPY,"I know outerlander, for I have been closely monitoring your progress so far!").also {stage++} 547 -> npcl(FacialExpression.HAPPY,"Then let us put the formality aside, and let me personally welcome you into the Fremennik! May you bring us honour!").also { - if(player.inventory.freeSlots() >= 10){ - println(GenerateFremennikName()) player.setAttribute("/save:fremennikname", GenerateFremennikName()) stage = 560 - } - else stage = 548 - } - 548 -> sendDialogue("You require 10 free spaces in your backpack to claim your reward.").also { stage = 1000 } - 550 -> npcl(FacialExpression.HAPPY,"If you need any help with your trials, I suggest you speak to Askeladden. He is currently doing his own trials of manhood to become a true Fremennik.") + 550 -> npcl(FacialExpression.HAPPY,"If you need any help with your trials, I suggest you speak to Askeladden. He is currently doing his own trials of manhood to become a true Fremennik.").also { stage = END_DIALOGUE } 560 -> npcl(FacialExpression.HAPPY,"From this day onward, you are outerlander no more! In honour of your acceptance into the Fremennik, you gain a new name: ${player.getAttribute("fremennikname","how did u break this")}.").also { cleanupAttributes(player) - player.questRepository.getQuest("Fremennik Trials").finish(player) + player.questRepository.getQuest(Quests.THE_FREMENNIK_TRIALS).finish(player) stage = 1000 } @@ -239,7 +234,7 @@ class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ 642 -> npcl(FacialExpression.HAPPY,"As I say, my knowledge outside of this town is rather limited, and I know no more than this.").also { stage++ } 643 -> npcl(FacialExpression.HAPPY,"Was there anything else you wished to hear tell of?").also { stage = 616 } - 645 -> npcl(FacialExpression.HAPPY,"Ah, now that is something I know a great deal about. Believe it or not, all outerlanders were once orginally Fremenniks.").also { stage++ } + 645 -> npcl(FacialExpression.HAPPY,"Ah, now that is something I know a great deal about. Believe it or not, all outerlanders were once originally Fremenniks.").also { stage++ } 646 -> npcl(FacialExpression.HAPPY,"When first man came to these lands all were Fremenniks, and followed our ways. We lived a happy life, and never settled in one place for long.").also { stage++ } 647 -> npcl(FacialExpression.HAPPY,"We travelled by boat along the coastlines, never taking more from the land than could be regrown by the same time in the following year.").also { stage++ } 648 -> npcl(FacialExpression.HAPPY,"However, many moons past, some of our tribesmen were weary of constantly travelling the lands, and decided to build themselves permanent homes.").also { stage++ } @@ -264,7 +259,7 @@ class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ 1201 -> npcl(FacialExpression.HALF_THINKING, "I suppose I can grant you one temporarily, provided you meet certain requirements.").also { stage++ } 1202 -> npcl(FacialExpression.HAPPY, "Very well, $fName! Let me look you over and see if you're strong enough for this boon.").also { stage++ } 1203 -> { - if (!hasRequirement(player, "Lunar Diplomacy") || player!!.hasItem(Item(Items.SEAL_OF_PASSAGE_9083))) + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY) || player!!.hasItem(Item(Items.SEAL_OF_PASSAGE_9083))) npcl(FacialExpression.HALF_GUILTY, "I'm sorry, $fName. You just don't have the experience needed for this gift. Please come back when you've learned more.").also { stage = END_DIALOGUE } else npcl(FacialExpression.HAPPY, "Yes, yes... I see it. You've got the strength and wisdom for this gift. Please, take this. For now.").also { stage++ } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt index f3cb507fd..f9b6223af 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt @@ -5,6 +5,7 @@ import org.rs09.consts.Items import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests const val COUNCIL_WORKER = 1287 @@ -32,7 +33,7 @@ class CouncilWorkerFTDialogue(val questStage: Int, var isBeerInteraction: Boolea else if(questStage in 1..99){ when(stage){ START_DIALOGUE -> - if(getQuestStage(player!!, "Fremennik Trials") > 0) { + if(getQuestStage(player!!, Quests.THE_FREMENNIK_TRIALS) > 0) { player("I know this is an odd question, but are you","a member of the elder council?"); stage = 1 } else { end() diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt index 30f9bb225..c0c3f4f3f 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt @@ -8,6 +8,7 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable import core.tools.END_DIALOGUE +import content.data.Quests @Initializable class FishermanDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -37,9 +38,9 @@ class FishermanDialogue(player: Player? = null) : DialoguePlugin(player) { playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find an exotic and extremely odd fish, do you?") stage = 1 return true - } else if (isQuestComplete(player, "Fremennik Trials")){ + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){ player(FacialExpression.FRIENDLY, "Hello there.").also { stage = 100 } - } else if (!isQuestComplete(player, "Fremennik Trials")) { + } else if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { player(FacialExpression.FRIENDLY, "Hello there.").also { stage = 200 } } return true diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt index d50e8f42f..ec693af62 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt @@ -1,16 +1,14 @@ package core.game.content.quest.fremtrials import core.game.node.entity.player.Player -import core.api.* import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills -import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items -import content.minigame.allfiredup.AFUBeacon +import content.data.Quests @Initializable -class FremennikTrials : Quest("Fremennik Trials",64,63,3,347,0,1,10){ +class FremennikTrials : Quest(Quests.THE_FREMENNIK_TRIALS,64,63,3,347,0,1,10){ class SkillRequirement(val skill: Int?, val level: Int?) @@ -19,7 +17,7 @@ class FremennikTrials : Quest("Fremennik Trials",64,63,3,347,0,1,10){ override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) var line = 11 - val started = player?.questRepository?.getStage("Fremennik Trials")!! > 0 + val started = player?.questRepository?.getStage(Quests.THE_FREMENNIK_TRIALS)!! > 0 if(!started){ line(player,"Requirements to complete quest:",line++) diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt index e4f2c9f65..a6d1f37de 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt @@ -9,13 +9,14 @@ import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.item.Item import org.rs09.consts.Items +import content.data.Quests @Initializable class LalliDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { player?.let { println(it.getAttribute("lalliEatStew", false)) - if (it.questRepository.isComplete("Fremennik Trials")){ + if (it.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(FacialExpression.NEUTRAL,"Hello there.") stage = 100 return true @@ -45,12 +46,12 @@ class LalliDialogue(player: Player? = null) : DialoguePlugin(player){ stage = 50 return true } - if(player.questRepository.isComplete("Fremennik Trials")){ + if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(FacialExpression.HAPPY,"Hello there.") stage = 100 return true } - if (it.questRepository.getStage("Fremennik Trials") > 0) { + if (it.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS) > 0) { player("Hello there.").also { stage = 0; return true } } } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt index 689fc14d1..425c617cf 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt @@ -1,6 +1,7 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials import core.api.addItem +import core.api.getQuestStage import core.api.removeItem import core.game.node.entity.impl.Animator import core.game.node.entity.npc.NPC @@ -12,13 +13,14 @@ import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable class ManniDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ var curNPC: NPC? = NPC(0,Location(0,0,0)) override fun open(vararg args: Any?): Boolean { curNPC = args[0] as? NPC - if(player?.questRepository?.getStage("Fremennik Trials")!! > 0){ + if(player?.questRepository?.getStage(Quests.THE_FREMENNIK_TRIALS)!! > 0){ if(player?.inventory?.contains(3707, 1) == true){ playerl(core.game.dialogue.FacialExpression.HAPPY,"Hey. I got your cocktail for you.") stage = 170 @@ -55,12 +57,12 @@ class ManniDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin( return true } } - else if(player?.getAttribute("fremtrials:manni-vote",false) == true){ - npc("e have my vote!") + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player?.getAttribute("fremtrials:manni-vote",false) == true) { + npc("Ye have my vote!") stage = 1000 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(core.game.dialogue.FacialExpression.HAPPY,"Howdy!") stage = 190 return true diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt index 8af316688..baffb1143 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt @@ -5,6 +5,7 @@ import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable +import content.data.Quests @Initializable class OlafTheBard(player: Player? = null) : DialoguePlugin(player){ @@ -43,12 +44,12 @@ class OlafTheBard(player: Player? = null) : DialoguePlugin(player){ stage = 1000 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ npcl(FacialExpression.HAPPY,"Hello again to you, ${player.getAttribute("fremennikname","schlonko")}. Us bards should stick together, what can I do for you?") stage = 98 return true } - else if(player.questRepository.hasStarted("Fremennik Trials")){ + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){ npc("Hello? Yes? You want something outerlander?") stage = 0 return true diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt index 88ea2456b..c30737ab4 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt @@ -1,18 +1,20 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials -import core.api.addItem -import core.api.dumpContainer -import core.api.getQuestStage -import core.api.removeItem import core.game.node.entity.player.Player -import core.game.node.entity.player.link.diary.DiaryType import core.plugin.Initializable import core.tools.RandomFunction import core.tools.END_DIALOGUE import kotlin.random.Random +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.link.IronmanMode +import org.rs09.consts.Items +import org.rs09.consts.NPCs @Initializable -class PeerTheSeerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { +class PeerTheSeerDialogue(player: Player? = null) : DialoguePlugin(player) { val predictionOne = arrayOf("one","two","three","four","five","six","seven","eight","ten") val predictionTwo = arrayOf("black","blue","brown","cyan","green","pink","purple","red","yellow") val predictionThree = arrayOf("fire giant","ghosts","giant","goblin","green dragon","hobgoblin","lesser demon","moss giant","ogre","zombie") @@ -30,232 +32,230 @@ class PeerTheSeerDialogue(player: Player? = null) : core.game.dialogue.DialogueP override fun open(vararg args: Any?): Boolean { if(player.inventory.contains(3710,1)){ - playerl(core.game.dialogue.FacialExpression.HAPPY,"Can I have a weather forecast now please?") + playerl(FacialExpression.HAPPY,"Can I have a weather forecast now please?") stage = 15 return true } else if(player.inventory.contains(3705,1)){ - playerl(core.game.dialogue.FacialExpression.ASKING,"So, about this forecast...") + playerl(FacialExpression.ASKING,"So, about this forecast...") stage = 20 return true } else if(player.getAttribute("sigmundreturning",false) == true){ - playerl(core.game.dialogue.FacialExpression.ASKING,"I've got an item to trade but I don't know if it's for you.") + playerl(FacialExpression.ASKING,"I've got an item to trade but I don't know if it's for you.") stage = 26 return true } else if(player.getAttribute("sigmund-steps", 0) == 10){ - playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a brave and powerful warrior to act as a bodyguard?") + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a brave and powerful warrior to act as a bodyguard?") stage = 8 return true } else if(player.getAttribute("sigmund-steps", 0) == 9){ - playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a weather forecast from the Fremennik Seer do you?") + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a weather forecast from the Fremennik Seer do you?") stage = 1 return true } - else if(player.getAttribute("PeerStarted",false) && !player.inventory.isEmpty || !player.equipment.isEmpty){ - npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + else if(player.getAttribute("PeerStarted",false) && !(player.inventory.isEmpty && player.equipment.isEmpty)){ + npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") stage = 100 return true } else if(player.getAttribute("PeerStarted",false) && player.inventory.isEmpty && player.equipment.isEmpty){ - npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") stage = 110 return true } - else if(player.getAttribute("fremtrials:peer-vote",false)){ - npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:peer-vote",false)) { + npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") stage = 120 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ - npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") stage = 150 return true } - else if(player.questRepository.hasStarted("Fremennik Trials")){ - npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){ + npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") stage = 50 return true } - if (getQuestStage(player, "Fremennik Trials") == 0) { - npc(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?").also { stage = 300 } + if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) == 0) { + npc(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?").also { stage = 300 } } return true } override fun handle(interfaceId: Int, buttonId: Int): Boolean { when(stage){ - 1 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Er.... Yes, because I AM the Fremennik Seer.").also { stage++ } - 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Can I have a weather forecast then please?").also { stage++ } - 3 -> npcl(core.game.dialogue.FacialExpression.THINKING,"You require a divination of the weather? This is a simple matter for me, but I will require something in return from you for this small service.").also { stage++ } - 4 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I knew you were going to say that...").also { stage++ } - 5 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Do not fret, outerlander; it is a fairly simple matter. I require a bodyguard for protection. Find someone willing to offer me this service.").also { stage++ } - 6 -> playerl(core.game.dialogue.FacialExpression.ASKING,"That's all?").also { stage++ } - 7 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is all.").also { + 1 -> npcl(FacialExpression.ANNOYED,"Er.... Yes, because I AM the Fremennik Seer.").also { stage++ } + 2 -> playerl(FacialExpression.ASKING,"Can I have a weather forecast then please?").also { stage++ } + 3 -> npcl(FacialExpression.THINKING,"You require a divination of the weather? This is a simple matter for me, but I will require something in return from you for this small service.").also { stage++ } + 4 -> playerl(FacialExpression.ASKING,"I knew you were going to say that...").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY,"Do not fret, outerlander; it is a fairly simple matter. I require a bodyguard for protection. Find someone willing to offer me this service.").also { stage++ } + 6 -> playerl(FacialExpression.ASKING,"That's all?").also { stage++ } + 7 -> npcl(FacialExpression.HAPPY,"That is all.").also { player?.incrementAttribute("sigmund-steps",1) stage = 1000 } - 10 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"If I did, then I would simply have asked them myself now, wouldn't I, outerlander?").also { stage = 1000 } + 10 -> npcl(FacialExpression.ANNOYED,"If I did, then I would simply have asked them myself now, wouldn't I, outerlander?").also { stage = 1000 } - 15 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"I have already told you outerlander; You may have a reading from me when I have a signed contract from a warrior guaranteeing my protection.").also { stage++ } - 16 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Yeah, I know; I have one right here from Thorvald.").also { + 15 -> npcl(FacialExpression.ANNOYED,"I have already told you outerlander; You may have a reading from me when I have a signed contract from a warrior guaranteeing my protection.").also { stage++ } + 16 -> playerl(FacialExpression.HAPPY,"Yeah, I know; I have one right here from Thorvald.").also { removeItem(player,3710) addItem(player,3705) stage++ } - 17 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"You have not only persuaded one of the Fremennik to act as a servant to me, but you have enlisted the aid of mighty Thorvald himself???").also { stage++ } - 18 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You may take this forecast with my blessing outerlander. You have offered me the greatest security I can imagine.").also { stage = 1000 } + 17 -> npcl(FacialExpression.AMAZED,"You have not only persuaded one of the Fremennik to act as a servant to me, but you have enlisted the aid of mighty Thorvald himself???").also { stage++ } + 18 -> npcl(FacialExpression.HAPPY,"You may take this forecast with my blessing outerlander. You have offered me the greatest security I can imagine.").also { stage = 1000 } - 20 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Yes, outerlander?").also { stage++ } - 21 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I still don't know why you didn't just let me have one anyway in the first place. Surely it means nothing to you?").also { stage++ } - 22 -> npcl(core.game.dialogue.FacialExpression.THINKING,"That is not true, outerlander. Although I see glimpses of the future all of the time, using my powers brings the attention of the gods to me.").also { stage++ } - 23 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Some of the gods are spiteful and cruel, and I fear if I use my powers too much then I will meet with unpredictable accidents.").also { stage++ } - 24 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"This is why I needed protection.").also { stage++ } - 25 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Okay... I... think I understand...").also { stage = 1000 } + 20 -> npcl(FacialExpression.THINKING,"Yes, outerlander?").also { stage++ } + 21 -> playerl(FacialExpression.ASKING,"I still don't know why you didn't just let me have one anyway in the first place. Surely it means nothing to you?").also { stage++ } + 22 -> npcl(FacialExpression.THINKING,"That is not true, outerlander. Although I see glimpses of the future all of the time, using my powers brings the attention of the gods to me.").also { stage++ } + 23 -> npcl(FacialExpression.THINKING,"Some of the gods are spiteful and cruel, and I fear if I use my powers too much then I will meet with unpredictable accidents.").also { stage++ } + 24 -> npcl(FacialExpression.HAPPY,"This is why I needed protection.").also { stage++ } + 25 -> playerl(FacialExpression.THINKING,"Okay... I... think I understand...").also { stage = 1000 } - 26 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Not me, I'm afraid.").also { stage++ } + 26 -> npcl(FacialExpression.ANNOYED,"Not me, I'm afraid.").also { stage++ } //The Seer's Trial - 50 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } - 51 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } - 52 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Hello. I'm looking for members of the council of elders to vote for me to become a Fremennik.").also { stage++ } - 53 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Are you now? Well that is interesting. Usually outerlanders do not concern themselves with our ways like that.").also { stage++ } - 54 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"I am one of the members of the council of elders, and should you be able to prove to me that you have something to offer my clan I will vote in your favour at the next meeting.").also { stage++ } - 55 -> playerl(core.game.dialogue.FacialExpression.ASKING,"How can I prove that to you?").also { stage++ } - 56 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, I have but a simple test. This building behind me is my house. Inside I have constructed a puzzle.").also { stage++ } - 57 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As a Seer to the clan, I value intelligence very highly, so you may think of it as an intelligence test of sorts.").also { stage++ } - 58 -> playerl(core.game.dialogue.FacialExpression.THINKING,"An intelligence test? I thought barbarians were stupid!").also { stage++ } - 59 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"That is the opinion that outerlanders usually hold of my people, it is true. But that is because people often confuse knowledge with wisdom.").also { stage++ } - 60 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"My puzzle tests not what you know, but what you can work out. All members of our clan have been tested when they took their trials.").also { stage++ } - 61 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So what exactly does this puzzle consist of, then?").also { stage++ } - 62 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, firstly you must enter my house with no items, weapons or armour. Then it is a simple matter of entering through one door and leaving by the other.").also { stage++ } - 63 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I can't take anything in there with me?").also { stage++ } - 64 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander. Everything you need to complete the puzzle you will find inside the building. Nothing more.").also { stage++ } - 65 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"So what say you outerlander? You think you have the wit to earn yourself my vote?").also { stage++ } + 50 -> npcl(FacialExpression.AMAZED,"!").also { stage++ } + 51 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } + 52 -> playerl(FacialExpression.ASKING,"Hello. I'm looking for members of the council of elders to vote for me to become a Fremennik.").also { stage++ } + 53 -> npcl(FacialExpression.THINKING,"Are you now? Well that is interesting. Usually outerlanders do not concern themselves with our ways like that.").also { stage++ } + 54 -> npcl(FacialExpression.HAPPY,"I am one of the members of the council of elders, and should you be able to prove to me that you have something to offer my clan I will vote in your favour at the next meeting.").also { stage++ } + 55 -> playerl(FacialExpression.ASKING,"How can I prove that to you?").also { stage++ } + 56 -> npcl(FacialExpression.HAPPY,"Well, I have but a simple test. This building behind me is my house. Inside I have constructed a puzzle.").also { stage++ } + 57 -> npcl(FacialExpression.HAPPY,"As a Seer to the clan, I value intelligence very highly, so you may think of it as an intelligence test of sorts.").also { stage++ } + 58 -> playerl(FacialExpression.THINKING,"An intelligence test? I thought barbarians were stupid!").also { stage++ } + 59 -> npcl(FacialExpression.ANNOYED,"That is the opinion that outerlanders usually hold of my people, it is true. But that is because people often confuse knowledge with wisdom.").also { stage++ } + 60 -> npcl(FacialExpression.ANNOYED,"My puzzle tests not what you know, but what you can work out. All members of our clan have been tested when they took their trials.").also { stage++ } + 61 -> playerl(FacialExpression.ASKING,"So what exactly does this puzzle consist of, then?").also { stage++ } + 62 -> npcl(FacialExpression.HAPPY,"Well, firstly you must enter my house with no items, weapons or armour. Then it is a simple matter of entering through one door and leaving by the other.").also { stage++ } + 63 -> playerl(FacialExpression.ASKING,"I can't take anything in there with me?").also { stage++ } + 64 -> npcl(FacialExpression.HAPPY,"That is correct outerlander. Everything you need to complete the puzzle you will find inside the building. Nothing more.").also { stage++ } + 65 -> npcl(FacialExpression.HAPPY,"So what say you outerlander? You think you have the wit to earn yourself my vote?").also { stage++ } 66 -> options("Yes","No").also { stage++ } 67 -> when(buttonId){ - 1 ->{ playerl(core.game.dialogue.FacialExpression.HAPPY,"Yes, I accept your challenge, I have one small question, however...") + 1 ->{ playerl(FacialExpression.HAPPY,"Yes, I accept your challenge, I have one small question, however...") player?.setAttribute("/save:PeerStarted",true) player?.setAttribute("/save:PeerRiddle", Random.nextInt(0,3)) stage = 70 } - 2 ->{ playerl(core.game.dialogue.FacialExpression.HAPPY,"No, thinking about stuff isn't really my 'thing'. I'd rather go kill something. I'll find someone else to vote for me") + 2 ->{ playerl(FacialExpression.HAPPY,"No, thinking about stuff isn't really my 'thing'. I'd rather go kill something. I'll find someone else to vote for me") stage++ } } //No to challenge - 68 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish, outerlander.").also { stage = 1000 } + 68 -> npcl(FacialExpression.HAPPY,"As you wish, outerlander.").also { stage = 1000 } //Yes to challenge - 70 -> npcl(core.game.dialogue.FacialExpression.ASKING,"Yes outerlander?").also { stage++ } - 71 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well... you say I can bring nothing with me when I enter your house...").also { stage++ } - 72 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Yes outerlander??").also { stage++ } - 73 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well...").also { stage++ } - 74 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"Yes, outerlander???").also { stage++ } - 75 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Where is the nearest bank?").also { stage++ } - 76 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, I see your problem outerlander. The nearest bank to here is the place known to outerlanders as the Seers Village.").also { stage++ } - 77 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"It is some way South. I do however have an alternative, should you wish to take it.").also { stage++ } - 78 -> playerl(core.game.dialogue.FacialExpression.ASKING,"And what is that?").also { stage++ } - 79 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"I can store all the weapons, armour and items that you have upon you directly into your bank account.").also { stage++ } - 80 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"This will tax what little magic I possess however, so you will have to travel to the bank to withdraw them again.").also { stage++ } - 81 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"What say you outerlander? Do you wish me to do this for you?").also { stage++ } + 70 -> npcl(FacialExpression.ASKING,"Yes outerlander?").also { stage++ } + 71 -> playerl(FacialExpression.THINKING,"Well... you say I can bring nothing with me when I enter your house...").also { stage++ } + 72 -> npcl(FacialExpression.ANNOYED,"Yes outerlander??").also { stage++ } + 73 -> playerl(FacialExpression.THINKING,"Well...").also { stage++ } + 74 -> npcl(FacialExpression.ANGRY,"Yes, outerlander???").also { stage++ } + 75 -> playerl(FacialExpression.ASKING,"Where is the nearest bank?").also { stage++ } + 76 -> npcl(FacialExpression.HAPPY,"Ah, I see your problem outerlander. The nearest bank to here is the place known to outerlanders as the Seers Village.").also { stage++ } + 77 -> npcl(FacialExpression.HAPPY,"It is some way South. I do however have an alternative, should you wish to take it.").also { stage++ } + 78 -> playerl(FacialExpression.ASKING,"And what is that?").also { stage++ } + 79 -> npcl(FacialExpression.HAPPY,"I can store all the weapons, armour and items that you have upon you directly into your bank account.").also { stage++ } + 80 -> npcl(FacialExpression.HAPPY,"This will tax what little magic I possess however, so you will have to travel to the bank to withdraw them again.").also { stage++ } + 81 -> npcl(FacialExpression.HAPPY,"What say you outerlander? Do you wish me to do this for you?").also { stage++ } 82 -> options("Yes","No").also { stage++ } 83 -> when(buttonId){ 1 -> { val slotAmount = player.inventory.itemCount() + player.equipment.itemCount() - if (slotAmount < player.bank.freeSlots()){ - npcl(core.game.dialogue.FacialExpression.HAPPY,"The task is done. I wish you luck with your test, outerlander.") - dumpContainer(player,player.inventory) - dumpContainer(player,player.equipment) + if (slotAmount < player.bank.freeSlots() && slotAmount == dumpContainer(player,player.inventory) + dumpContainer(player,player.equipment)){ + npcl(FacialExpression.HAPPY,"The task is done. I wish you luck with your test, outerlander.") stage = 1000 } else { - npcl(core.game.dialogue.FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you") + npcl(FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you.") stage = 1000 } } - 2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"No thanks. Nobody touches my stuff but me!").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY,"No thanks. Nobody touches my stuff but me!").also { stage++ } } //No to banking - 84 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish, outerlander. You may attempt my little task when you have deposited your equipment in the bank").also { + 84 -> npcl(FacialExpression.HAPPY,"As you wish, outerlander. You may attempt my little task when you have deposited your equipment in the bank.").also { stage = 1000 } //Yes to banking but cannot bank - 90 -> npcl(core.game.dialogue.FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you").also { + 90 -> npcl(FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you.").also { stage = 1000 } //Returning after accepting with items. - 100 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } - 101 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } - 102 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So I can bring nothing with me when I enter your house?").also { stage++ } - 103 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander, but as I say, I can use my small skill in magic to send your items directly into your bank account from here.").also { stage++ } - 104 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You will need to manually go to the bank to withdraw them again however.").also { stage++ } - 105 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Would you like me to perform this small spell upon you, outerlander?").also { stage = 82 } + 100 -> npcl(FacialExpression.AMAZED,"!").also { stage++ } + 101 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } + 102 -> playerl(FacialExpression.ASKING,"So I can bring nothing with me when I enter your house?").also { stage++ } + 103 -> npcl(FacialExpression.HAPPY,"That is correct outerlander, but as I say, I can use my small skill in magic to send your items directly into your bank account from here.").also { stage++ } + 104 -> npcl(FacialExpression.HAPPY,"You will need to manually go to the bank to withdraw them again however.").also { stage++ } + 105 -> npcl(FacialExpression.HAPPY,"Would you like me to perform this small spell upon you, outerlander?").also { stage = 82 } //Returning after accepting without items. - 110 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } - 111 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } - 112 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So I just have to enter by one door of your house, and leave by the other?").also { stage++ } - 113 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander. Be warned it is not as easy as it may at first sound...").also { stage = 1000 } + 110 -> npcl(FacialExpression.AMAZED,"!").also { stage++ } + 111 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } + 112 -> playerl(FacialExpression.ASKING,"So I just have to enter by one door of your house, and leave by the other?").also { stage++ } + 113 -> npcl(FacialExpression.HAPPY,"That is correct outerlander. Be warned it is not as easy as it may at first sound...").also { stage = 1000 } //After completing the Seer's Trial. - 120 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } - 121 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that.").also { stage++ } - 122 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"So you will vote for me at the council?").also { stage++ } - 123 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Absolutely, outerlander. Your wisdom in passing my test marks you as worthy in my eyes.").also { stage = 1000 } + 120 -> npcl(FacialExpression.AMAZED,"!").also { stage++ } + 121 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that.").also { stage++ } + 122 -> playerl(FacialExpression.HAPPY,"So you will vote for me at the council?").also { stage++ } + 123 -> npcl(FacialExpression.HAPPY,"Absolutely, outerlander. Your wisdom in passing my test marks you as worthy in my eyes.").also { stage = 1000 } - //After Fremennik Trials - 150 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } - 151 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that.").also { - stage = if(player.achievementDiaryManager.getDiary(DiaryType.FREMENNIK).isComplete(0)){ + //After The Fremennik Trials + 150 -> npcl(FacialExpression.AMAZED,"!").also { stage++ } + 151 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that.").also { + stage = if(anyInEquipment(player, Items.FREMENNIK_SEA_BOOTS_1_14571, Items.FREMENNIK_SEA_BOOTS_2_14572, Items.FREMENNIK_SEA_BOOTS_3_14573) && !hasIronmanRestriction(player, IronmanMode.ULTIMATE)){ 200 }else 152 } - 152 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Hello Peer.").also { stage++ } - 153 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Greetings to you, brother ${player.getAttribute("fremennikname","dingle")}! What brings you to see me again?").also { stage++ } + 152 -> playerl(FacialExpression.HAPPY,"Hello Peer.").also { stage++ } + 153 -> npcl(FacialExpression.HAPPY,"Greetings to you, brother ${player.getAttribute("fremennikname","dingle")}! What brings you to see me again?").also { stage++ } 154 -> options("Can you tell my future?","Nothing really.").also{stage++} 155 -> when(buttonId){ - 1 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage++ } - 2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 } + 1 -> playerl(FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 } } - 156 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, you would like a prediction? I do not see that that would be so difficult... Wait a moment...").also { + 156 -> npcl(FacialExpression.HAPPY,"Ah, you would like a prediction? I do not see that that would be so difficult... Wait a moment...").also { stage++ } - 157 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here is your prediction: ${PREDICTIONS[prediction]}").also { stage = 1000 } + 157 -> npcl(FacialExpression.HAPPY,"Here is your prediction: ${PREDICTIONS[prediction]}").also { stage = 1000 } - 160 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, hello to you too!").also { stage = 1000 } + 160 -> npcl(FacialExpression.HAPPY,"Well, hello to you too!").also { stage = 1000 } 200 -> options("Deposit service","Can you tell my future?","Nothing really.").also{ stage++ } 201 -> when(buttonId){ - 1 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Could you deposit some things for me, please?").also { stage++ } - 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage = 156 } - 3 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 } + 1 -> playerl(FacialExpression.HAPPY,"Could you deposit some things for me, please?").also { stage++ } + 2 -> playerl(FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage = 156 } + 3 -> playerl(FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 } } - 202 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Of course, ${player.getAttribute("fremennikname","dingle")}. I am always happy to aid those who have earned the right to wear Fremennik sea boots.").also { + 202 -> npcl(FacialExpression.HAPPY,"Of course, ${player.getAttribute("fremennikname","dingle")}. I am always happy to aid those who have earned the right to wear Fremennik sea boots.").also { player.bank.openDepositBox() stage = 1000 } - 300 -> npc(core.game.dialogue.FacialExpression.NEUTRAL,"!").also { stage++ } - 301 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Ahem, sorry about that. I have no interest in talking to you just now outerlander.").also { stage = END_DIALOGUE } + 300 -> npc(FacialExpression.NEUTRAL,"!").also { stage++ } + 301 -> npcl(FacialExpression.NEUTRAL,"Ahem, sorry about that. I have no interest in talking to you just now outerlander.").also { stage = END_DIALOGUE } 1000 -> end() } return true } - override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + override fun newInstance(player: Player?): DialoguePlugin { return PeerTheSeerDialogue(player) } override fun getIds(): IntArray { - return intArrayOf(1288) + return intArrayOf(NPCs.PEER_THE_SEER_1288) } } \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt index e3d874010..2e0fd8671 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt @@ -1,32 +1,46 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.inInventory +import core.api.setAttribute import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import content.data.Quests @Initializable class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { - options("Talk about the Murder Mystery Quest","Talk about the Fremennik Trials") + options("Talk about the Murder Mystery Quest","Talk about the The Fremennik Trials") stage = START_DIALOGUE return true } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - //val murderMysteryStage = player.questRepository.isComplete("Murder Mystery") - val fremennikTrialsStage = player.questRepository.getStage("Fremennik Trials") + val murderMysteryStage = player.questRepository.getStage(Quests.MURDER_MYSTERY) + val fremennikTrialsStage = player.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS) when (stage) { START_DIALOGUE -> when (buttonId) { - 1 -> { player("Err... nevermind"); stage = END_DIALOGUE } + 1 -> { + when (murderMysteryStage) { + 0 -> npcl(FacialExpression.NEUTRAL, "I'm afraid I'm all sold out of poison at the moment. People know a bargain when they see it!").also { stage = END_DIALOGUE } + 1 -> playerl(FacialExpression.NEUTRAL, "I'm investigating the murder at the Sinclair house.").also { stage = 50 } + 100 -> npcl(FacialExpression.NEUTRAL, "I hear you're pretty smart to have solved the Sinclair Murder!").also { stage = END_DIALOGUE } + } + } 2 -> { player("Hello."); stage = 10 } } - //Fremennik Trials + //The Fremennik Trials 10 -> { /**when (fremennikTrialsStage) { 0 -> { npc("Come see me if you ever need low-alcohol beer!"); stage = END_DIALOGUE } @@ -87,6 +101,42 @@ class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) { stage++ } 45 -> { npc("Well come back when you do!"); stage = END_DIALOGUE } + + //Murder Mystery + 50 -> npcl(FacialExpression.NEUTRAL, "There was a murder at the Sinclair house??? That's terrible! And I was only there the other day too! They bought the last of my Patented Multi Purpose Poison!").also { stage++ } + 51 -> showTopics( + Topic("Patented Multi Purpose Poison?", 52), + Topic("Who did you sell Poison to at the house?", 61), + Topic("Can I buy some Poison?", 65), + IfTopic("I have this pot I found at the murder scene...", 69, inInventory(player, Items.PUNGENT_POT_1812)) + ) + 52 -> npcl(FacialExpression.NEUTRAL, "Aaaaah... a miracle of modern apothecaries!").also { stage++ } + 53 -> npcl(FacialExpression.NEUTRAL, "This exclusive concoction has been tested on all known forms of life and been proven to kill them all in varying dilutions from cockroaches to king dragons!").also { stage++ } + 54 -> npcl(FacialExpression.NEUTRAL, "So incredibly versatile, it can be used as pest control, a cleansing agent, drain cleaner, metal polish and washes whiter than white,").also { stage++ } + 55 -> npcl(FacialExpression.NEUTRAL, "all with our uniquely fragrant concoction that is immediately recognisable across the land as Peter Potter's Patented Poison potion!!!").also { stage++ } + 56 -> sendDialogue("The salesman stops for breath.").also { stage ++ } + 57 -> npcl(FacialExpression.NEUTRAL, "I'd love to sell you some but I've sold out recently. That's just how good it is! Three hundred and twenty eight people in this area alone cannot be wrong!").also { stage++ } + 58 -> npcl(FacialExpression.NEUTRAL, "Nine out of Ten poisoners prefer it in controlled tests!").also { stage++ } + 59 -> npcl(FacialExpression.NEUTRAL, "Can I help you with anything else? Perhaps I can take your name and add it to our mailing list of poison users? We will only send you information related to the use of poison and other Peter Potter Products!").also { stage++ } + 60 -> playerl(FacialExpression.NEUTRAL, "Uh... no, it's ok. Really.").also { stage = END_DIALOGUE } + + 61 -> npcl(FacialExpression.HAPPY, "Well, Peter Potter's Patented Multi Purpose Poison is a product of such obvious quality that I am glad to say I managed to sell a bottle to each of the Sinclairs!").also { stage++ } + 62 -> npcl(FacialExpression.HAPPY, "Anna, Bob, Carol, David, Elizabeth and Frank all bought a bottle! In fact they bought the last of my supplies!").also { stage++ } + 63 -> npcl(FacialExpression.HAPPY, "Maybe I can take your name and address and I will personally come and visit you when stocks return?").also { stage++ } + 64 -> playerl(FacialExpression.THINKING, "Uh...no, it's ok.") + .also { setAttribute(player, attributePoisonClue, 1)} + .also { stage = END_DIALOGUE } + + 65 -> npcl(FacialExpression.NEUTRAL, "I'm afraid I am totally out of stock at the moment after my successful trip to the Sinclairs' House the other day.").also { stage++ } + 66 -> npcl(FacialExpression.NEUTRAL, "But don't worry! Our factories are working overtime to produce Peter Potter's Patented Multi Purpose Poison!").also { stage++ } + 67 -> npcl(FacialExpression.NEUTRAL, "Possibly the finest multi purpose poison and cleaner yet available to the general market.").also { stage++ } + 68 -> npcl(FacialExpression.NEUTRAL, "And its unique fragrance makes it the number one choice for cleaners and exterminators the whole country over!").also { stage = END_DIALOGUE } + + 69 -> sendDialogue("You show the poison salesman the pot you found at the murder", "scene with the unusual smell.").also { stage ++ } + 70 -> npcl(FacialExpression.THINKING, "Hmmm... yes, that smells exactly like my Patented Multi Purpose Poison, but I don't see how it could be. It quite clearly says on the label of all bottles").also { stage++ } + 71 -> npcl(FacialExpression.THINKING, "'Not to be taken internally - EXTREMELY POISONOUS'.").also { stage++ } + 72 -> playerl(FacialExpression.THINKING, "Perhaps someone else put it in his wine?").also { stage++ } + 73 -> npcl(FacialExpression.THINKING, "Yes... I suppose that could have happened...").also { stage = END_DIALOGUE } END_DIALOGUE -> end() } return true diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt index 37e7434e9..684eece92 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt @@ -1,5 +1,6 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials +import content.data.Quests import core.api.* import core.game.node.entity.impl.Animator import core.game.node.entity.player.Player @@ -102,7 +103,7 @@ class SeersHouseListeners : InteractionListener { if(!player.getAttribute("PeerStarted",false)){ sendDialogue(player,"You should probably talk to the owner of this home.") } - if(getAttribute(player, "fremtrials:peer-vote", false)) + if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && getAttribute(player, "fremtrials:peer-vote", false)) { sendDialogue(player, "I don't need to go through that again.") return@on true diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt index d987e061e..8fd16e3fc 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt @@ -1,18 +1,20 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials import core.api.addItem +import core.api.getQuestStage import core.api.removeItem import core.game.node.entity.player.Player -import core.game.node.entity.player.info.PlayerDetails import core.game.node.item.Item import core.plugin.Initializable import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression +import content.data.Quests +import org.rs09.consts.Items @Initializable class SigliTheHuntsman(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { - if(player?.inventory?.contains(3702,1) == true){ + if(player?.inventory?.contains(Items.CUSTOM_BOW_STRING_3702, 1) == true){ npcl(FacialExpression.HAPPY,"Greetings outerlander.") stage = 165 return true @@ -37,7 +39,7 @@ class SigliTheHuntsman(player: Player? = null) : DialoguePlugin(player){ stage = 150 return true } - else if(player?.getAttribute("fremtrials:sigli-vote",false)!!){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player?.getAttribute("fremtrials:sigli-vote",false)!!) { npc("You have my vote!") stage = 1000 return true @@ -47,12 +49,12 @@ class SigliTheHuntsman(player: Player? = null) : DialoguePlugin(player){ stage = 100 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(FacialExpression.HAPPY,"Hello again Sigli.") stage = 180 return true } - else if(player.questRepository.hasStarted("Fremennik Trials")){ + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){ npc("What do you want outerlander?") stage = 0 return true @@ -103,13 +105,13 @@ class SigliTheHuntsman(player: Player? = null) : DialoguePlugin(player){ //Draugen killed 100 -> player("Thanks!").also { - player.removeAttribute("fremtrials:draugen-killed") - player.setAttribute("/save:fremtrials:sigli-vote",true) - player?.setAttribute("/save:fremtrials:votes",player.getAttribute("fremtrials:votes",0) + 1) - player?.inventory?.remove(Item(3697)) - stage = 1000 - } - + if (player.inventory.remove(Item(Items.HUNTERS_TALISMAN_3697))) { + player.removeAttribute("fremtrials:draugen-killed") + player.setAttribute("/save:fremtrials:sigli-vote", true) + player.setAttribute("/save:fremtrials:votes", player.getAttribute("fremtrials:votes", 0) + 1) + } + stage = 1000 + } 150 -> playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a map to unspoiled hunting grounds, do you?").also { stage++ } 151 -> npcl(FacialExpression.HAPPY,"Well, of course I do. I wouldn't be much of a huntsman if I didn't know where to find my prey now, would I outerlander?").also { stage++ } 152 -> playerl(FacialExpression.ASKING,"No, I guess not. So can I have it?").also { stage++ } @@ -126,9 +128,10 @@ class SigliTheHuntsman(player: Player? = null) : DialoguePlugin(player){ 161 -> npcl(FacialExpression.ANNOYED,"If I knew I would not have asked you to go and get me one, now would I?").also { stage = 1000 } 165 -> playerl(FacialExpression.HAPPY,"Here. I have your bowstring. Give me your map to the hunting grounds.").also { - removeItem(player,3702) - addItem(player,3701) - stage++ + if (removeItem(player, Items.CUSTOM_BOW_STRING_3702)) { + addItem(player, Items.TRACKING_MAP_3701) + stage++ + } } 166 -> npcl(FacialExpression.HAPPY,"Well met, outerlander. I see some hunting potential within you. Here, take my map, I was getting too dependent on it for my skill anyway.").also { stage = 1000 } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt index d00e6cf7f..947ffee6c 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt @@ -1,6 +1,7 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials import core.api.addItem +import core.api.getQuestStage import core.api.removeItem import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -8,6 +9,8 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests +import core.api.addItemOrDrop @Initializable class SigmundDialogue (player: Player? = null) : DialoguePlugin(player) { @@ -22,12 +25,12 @@ class SigmundDialogue (player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if(player.questRepository.isComplete("Fremennik Trials")){ + if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(FacialExpression.HAPPY,"Hello there!") stage = 50 return true } - else if(!player.questRepository.hasStarted("Fremennik Trials")){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) <= 0) { playerl(FacialExpression.HAPPY,"Hello there!") stage = 60 return true @@ -47,7 +50,7 @@ class SigmundDialogue (player: Player? = null) : DialoguePlugin(player) { stage = 25 return true } - else if(!player?.getAttribute("fremtrials:sigmund-vote",false)!!){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && !player?.getAttribute("fremtrials:sigmund-vote",false)!!) { playerl(FacialExpression.HAPPY,"Hello there!") stage = 1 return true @@ -107,8 +110,9 @@ class SigmundDialogue (player: Player? = null) : DialoguePlugin(player) { 36 -> npcl(FacialExpression.ASKING,"I suggest you ask around the other Fremennik in the town. A good merchant will find exactly what their customer needs somewhere.").also { stage++ } 37 -> playerl(FacialExpression.ASKING,"I was making some trades, but then I lost the goods...").also { stage++ } 38 -> npcl(FacialExpression.THINKING,"Hmmm... well try and start again at the beginning. And try to be more careful of your wares in future.").also { - addItem(player, Items.PROMISSORY_NOTE_3709) - stage = 1000 } + addItemOrDrop(player, Items.PROMISSORY_NOTE_3709) + stage = 1000 + } 40 -> npcl(FacialExpression.HAPPY,"Hello again outerlander! I am amazed once more at your apparent skill at merchanting!").also { stage++ } 41 -> playerl(FacialExpression.HAPPY,"So I can count on your vote at the council of elders?").also { stage++ } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt index f51b1cf71..4ca7edd4f 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt @@ -7,18 +7,20 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable +import content.data.Quests +import org.rs09.consts.Items @Initializable class SkulgrimenDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if(player?.inventory?.contains(3703,1) == true){ + if(player?.inventory?.contains(Items.UNUSUAL_FISH_3703,1) == true){ playerl(FacialExpression.HAPPY,"Hi there. I got your fish, so can I have that bowstring for Sigli now?") stage = 20 return true } - else if(player?.inventory?.contains(3702,1) == true){ + else if(player?.inventory?.contains(Items.CUSTOM_BOW_STRING_3702,1) == true){ playerl(FacialExpression.ASKING,"So about this bowstring... was it hard to make or something?") stage = 25 return true @@ -38,7 +40,7 @@ class SkulgrimenDialogue(player: Player? = null) : DialoguePlugin(player) { stage = 1 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ npcl(FacialExpression.HAPPY,"Hello again, ${player.getAttribute("fremennikname","ringo")}. Come to see what's for sale?") stage = 1001 return true @@ -71,9 +73,9 @@ class SkulgrimenDialogue(player: Player? = null) : DialoguePlugin(player) { 17 -> npcl(FacialExpression.ANNOYED,"Ah. I see. I already told you. Some guy down by the docks was bragging. Best ask there, I reckon.").also { stage = 1000 } 20 -> npcl(FacialExpression.HAPPY,"Ohh... That's a nice fish. Very pleased. Here. Take the bowstring. You fulfilled agreement. Only fair I do same. Good work outerlander.").also { - removeItem(player,3703) - addItem(player,3702) - stage++ + if (removeItem(player, Items.UNUSUAL_FISH_3703) && addItem(player, Items.CUSTOM_BOW_STRING_3702)) { + stage++ + } } 21 -> playerl(FacialExpression.HAPPY,"Thanks!").also { stage = 1000 } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt index c06ff2266..0f7762d8e 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt @@ -1,24 +1,26 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials import core.api.addItem +import core.api.getQuestStage import core.api.removeItem import core.game.node.entity.player.Player -import core.game.node.entity.player.info.PlayerDetails import core.plugin.Initializable import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression +import content.data.Quests +import org.rs09.consts.Items @Initializable class SwensenTheNavigator(player: Player? = null) : DialoguePlugin(player){ val gender = if (player?.isMale == true){"brother"} else "sister" val fName = player?.getAttribute("fremennikname","doug hug'em") override fun open(vararg args: Any?): Boolean { - if(player?.inventory?.contains(3705,1) == true){ + if(player?.inventory?.contains(Items.WEATHER_FORECAST_3705, 1) == true){ playerl(FacialExpression.HAPPY,"I would like your map of fishing spots.") stage = 120 return true } - else if(player?.inventory?.contains(3704,1) == true){ + else if(player?.inventory?.contains(Items.SEA_FISHING_MAP_3704, 1) == true){ playerl(FacialExpression.ASKING,"If this map of fishing spots is so valuable, why did you give it away to me so easily?") stage = 125 return true @@ -47,12 +49,12 @@ class SwensenTheNavigator(player: Player? = null) : DialoguePlugin(player){ stage = 1000 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if (player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(FacialExpression.HAPPY,"Hello!") stage = 140 return true } - else if(player.questRepository.hasStarted("Fremennik Trials")){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0) { player("Hello!") stage = 0 return true @@ -118,9 +120,9 @@ class SwensenTheNavigator(player: Player? = null) : DialoguePlugin(player){ 121 -> playerl(FacialExpression.HAPPY,"What, like this one I have here?").also { stage++ } 122 -> npcl(FacialExpression.AMAZED,"W-what...? I don't believe it! How did you...?").also { stage++ } 123 -> npcl(FacialExpression.HAPPY,"I suppose it doesn't matter, you have my gratitude outerlander! With this forecast I will be able to plan a safe course for our next raiding expedition!").also { - removeItem(player,3705) - addItem(player,3704) - stage++ + if (removeItem(player,Items.WEATHER_FORECAST_3705) && addItem(player, Items.SEA_FISHING_MAP_3704)) { + stage++ + } } 124 -> npcl(FacialExpression.HAPPY,"Here, outerlander; you may take my map of local fishing patterns with my gratitude!").also { stage = 1000 } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt index 5a6686c29..e7b48f9d3 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt @@ -21,6 +21,8 @@ import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.game.system.config.ItemConfigParser import core.game.world.GameWorld.Pulser +import content.data.Quests +import core.game.interaction.QueueStrength class TFTInteractionListeners : InteractionListener { @@ -82,8 +84,7 @@ class TFTInteractionListeners : InteractionListener { } onUseWith(IntType.ITEM,TINDERBOX,CHERRY_BOMB){ player, _, _ -> - if(removeItem(player,CHERRY_BOMB)){ - addItem(player,LIT_BOMB) + if (removeItem(player,CHERRY_BOMB) && addItem(player,LIT_BOMB)) { sendMessage(player,"You light the strange object.") } return@onUseWith true @@ -154,7 +155,7 @@ class TFTInteractionListeners : InteractionListener { sendNPCDialogue(player,1278,"Yeah you're good to go through. Olaf tells me you're some kind of outerlander bard here on tour. I doubt you're worse than Olaf is.") core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,door.asScenery()) } - getAttribute(player,"lyreConcertPlayed",false) -> { + getAttribute(player,"lyreConcertPlayed",false) || isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) -> { core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,door.asScenery()) } else -> { @@ -166,8 +167,8 @@ class TFTInteractionListeners : InteractionListener { on(LYRE_IDs, IntType.ITEM, "play"){ player, lyre -> if(getAttribute(player,"onStage",false) && !getAttribute(player,"lyreConcertPlayed",false)){ - Pulser.submit(LyreConcertPulse(player,lyre.id)) - } else if(getQuestStage(player, "Fremennik Trials") < 20 || !isQuestComplete(player, "Fremennik Trials")){ + playLyreConcert(player, lyre.id) + } else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) < 20 || !isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){ sendMessage(player,"You lack the knowledge to play this.") } else if(LYRE_IDs.isLast(lyre.id)){ sendMessage(player,"Your lyre is out of charges!") @@ -208,15 +209,17 @@ class TFTInteractionListeners : InteractionListener { return@on true } - on(SWENSEN_LADDER, IntType.SCENERY, "climb"){ player, _ -> - if(!getAttribute(player,"fremtrials:swensen-accepted",false)){ + on(SWENSEN_LADDER, IntType.SCENERY, "climb-down") { player, _ -> + if (!getAttribute(player,"fremtrials:swensen-accepted",false)) { sendNPCDialogue(player,1283,"Where do you think you're going?", core.game.dialogue.FacialExpression.ANGRY) + return@on true } + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2631, 10006, 0)) return@on true } on(THORVALD_LADDER, IntType.SCENERY, "climb-down") { player, _ -> - if (isQuestComplete(player, "Fremennik Trials") || getAttribute(player, "fremtrials:thorvald-vote", false)) { + if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) || getAttribute(player, "fremtrials:thorvald-vote", false)) { sendMessage(player,"You have no reason to go back down there.") return@on true } else if (!getAttribute(player,"fremtrials:warrior-accepted",false)) { @@ -257,13 +260,8 @@ class TFTInteractionListeners : InteractionListener { return@on true } - on(SWAYING_TREE, IntType.SCENERY, "cut-branch"){ player, node -> - player.pulseManager.run(WoodcuttingSkillPulse(player, node as Scenery)) - return@on true - } - on(SHOPNPCS, IntType.NPC, "Trade") { player, npc -> - if(isQuestComplete(player, "Fremennik Trials")){ + if(isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){ npc.asNpc().openShop(player) } else when(npc.id){ NPCs.THORA_THE_BARKEEP_1300 -> sendDialogue(player,"Only Fremenniks may buy drinks here.") @@ -352,7 +350,7 @@ class TFTInteractionListeners : InteractionListener { } } - class LyreConcertPulse(val player: Player, val Lyre: Int) : Pulse(){ + fun playLyreConcert(player: Player, lyre: Int) { val GENERIC_LYRICS = arrayOf( "${player.username?.capitalize()} is my name,", "I haven't much to say", @@ -377,7 +375,6 @@ class TFTInteractionListeners : InteractionListener { "I will simply tell you this:", "I've joined the Legends' Guild!" ) - var counter = 0 val questPoints = getQuestPoints(player) val champGuild = player.achievementDiaryManager?.hasCompletedTask(DiaryType.VARROCK, 1, 1)?: false val legGuild = questPoints >= 111 @@ -400,15 +397,17 @@ class TFTInteractionListeners : InteractionListener { else -> GENERIC_LYRICS } - override fun pulse(): Boolean { - when(counter++){ + queueScript(player, 0, QueueStrength.SOFT) { stage -> + when (stage) { 0 -> { player.lock() animate(player,1318,true) + return@queueScript delayScript(player, 1) } 2 -> { animate(player,1320,true) player.musicPlayer.play(MusicEntry.forId(165)) + return@queueScript delayScript(player, 1) } 4 -> { animate(player,1320,true) @@ -432,13 +431,15 @@ class TFTInteractionListeners : InteractionListener { } 14 ->{ setAttribute(player,"/save:lyreConcertPlayed",true) - player.removeAttribute("LyreEnchanted") - if(removeItem(player,Lyre)) - addItem(player,Items.ENCHANTED_LYRE_3690) + removeAttribute(player, "/save:LyreEnchanted") + if (removeItem(player,lyre)) { + addItem(player, Items.ENCHANTED_LYRE_3690) + } player.unlock() + return@queueScript stopExecuting(player) } } - return false + return@queueScript delayScript(player, 1) } } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt index 647d74df1..51159d5d6 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.item.Item import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable class ThoraDialogue(player: Player? = null) : DialoguePlugin(player){ @@ -36,7 +37,7 @@ class ThoraDialogue(player: Player? = null) : DialoguePlugin(player){ playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find the longhall barkeeps' legendary cocktail, do you?") stage = 1 } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ npcl(FacialExpression.HAPPY,"Hello again, $fName. I suppose you want a drink? Or are you going to try another scam with that terrible Askeladden again?") stage = 50 } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt index 0d3523007..e64080988 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt @@ -1,20 +1,23 @@ package content.region.fremennik.rellekka.quest.thefremenniktrials import core.api.addItem +import core.api.getQuestStage import core.api.removeItem import core.game.node.entity.player.Player import core.plugin.Initializable +import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests @Initializable class ThorvaldDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { - if(player?.inventory?.contains(3706,1) == true){ + if(player?.inventory?.contains(Items.CHAMPIONS_TOKEN_3706, 1) == true){ playerl(core.game.dialogue.FacialExpression.HAPPY,"I would like your contract to offer your services as a bodyguard.") stage = 215 return true } - else if(player?.inventory?.contains(3710,1) == true){ + else if(player?.inventory?.contains(Items.WARRIORS_CONTRACT_3710, 1) == true){ playerl(core.game.dialogue.FacialExpression.ASKING,"You didn't take much persuading to 'lower' yourself to a bodyguard.") stage = 220 return true @@ -39,27 +42,27 @@ class ThorvaldDialogue(player: Player? = null) : core.game.dialogue.DialoguePlug stage = 150 return true } - else if (player?.questRepository?.isComplete("Fremennik Trials")!!) { + else if (player?.questRepository?.isComplete(Quests.THE_FREMENNIK_TRIALS)!!) { playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Howdy Thorvald!") stage = 0 return true } - else if(player!!.getAttribute("fremtrials:thorvald-vote", false)!!){ + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player!!.getAttribute("fremtrials:thorvald-vote", false)!!) { playerl(core.game.dialogue.FacialExpression.FRIENDLY, "So can I count on your vote at the council of elders now Thorvald?") stage = 160 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ playerl(core.game.dialogue.FacialExpression.HAPPY,"Howdy Thorvald!") stage = 250 return true } - else if(!player.questRepository.hasStarted("Fremennik Trials")){ + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) == 0){ npcl(core.game.dialogue.FacialExpression.ANNOYED, "Leave me be, outerlander. I have nothing to say to the likes of you.") stage = 1000 return true } - else if (!player!!.getAttribute("fremtrials:thorvald-vote", false)!!) { + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && !player!!.getAttribute("fremtrials:thorvald-vote", false)!!) { if (player!!.getAttribute("fremtrials:warrior-accepted", false)!!) { options("What do I have to do again?", "Who is my opponent?", "Can't I do something else?") stage = 100 @@ -75,7 +78,7 @@ class ThorvaldDialogue(player: Player? = null) : core.game.dialogue.DialoguePlug override fun handle(interfaceId: Int, buttonId: Int): Boolean { when(stage){ - //After Fremennik Trials + //After The Fremennik Trials 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "And greetings to you too. It is good to see new blood entering the Fremennik; we gain our strength by bringing new warriors into the tribe.").also { stage = 1000 } //Warrior Trial @@ -177,9 +180,10 @@ class ThorvaldDialogue(player: Player? = null) : core.game.dialogue.DialoguePlug 216 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"It's a good thing I have the Champions' Token right here then, isn't it?").also { stage++ } 217 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah... well this is a different matter. With that token I can claim my rightful place as a champion in the Long hall!").also { stage++ } 218 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here outerlander, I can suffer the indignity of playing babysitter if it means that I can then revel with my warrior equals in the Long Hall afterwards!").also { - removeItem(player,3706) - addItem(player,3710) - stage++ + if (removeItem(player, Items.CHAMPIONS_TOKEN_3706)) { + addItem(player, Items.WARRIORS_CONTRACT_3710) + stage++ + } } 219 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here outerlander, take this contract; I will fulfill it to my utmost.").also { stage = 1000 } diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt index ef174fa42..3114af8ab 100644 --- a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt @@ -7,18 +7,20 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable +import content.data.Quests +import org.rs09.consts.Items @Initializable class YrsaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if(player?.inventory?.contains(3708,1) == true){ + if(player?.inventory?.contains(Items.FISCAL_STATEMENT_3708,1) == true){ playerl(FacialExpression.HAPPY,"Hello. Can I have those boots now? Here is a written statement from Brundt outlining future tax burdens upon Fremennik merchants and shopkeepers for the year.") stage = 15 return true } - else if(player?.inventory?.contains(3700,1) == true){ + else if(player?.inventory?.contains(Items.STURDY_BOOTS_3700,1) == true){ playerl(FacialExpression.ASKING,"Hey, these shoes look pretty comfy. Think you could make me a pair like them?") stage = 20 return true @@ -38,7 +40,7 @@ class YrsaDialogue(player: Player? = null) : DialoguePlugin(player) { stage = 1 return true } - else if(player.questRepository.isComplete("Fremennik Trials")){ + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ npcl(FacialExpression.HAPPY,"Welcome to my clothes shop. I can change your shoes, or I've got a fine selection of clothes for sale.") stage = 30 //Uncomment this out when we got the shoe shop up and running @@ -66,9 +68,9 @@ class YrsaDialogue(player: Player? = null) : DialoguePlugin(player) { 10 -> npcl(FacialExpression.NEUTRAL,"Yes I do outerlander. Only the Chieftain may permit such a thing. Talk to him.").also { stage = 1000 } 15 -> npcl(FacialExpression.HAPPY,"Certainly! Let me have a look at what he has written here, just give me a moment...").also { - removeItem(player,3708) - addItem(player,3700) - stage++ + if (removeItem(player, Items.FISCAL_STATEMENT_3708) && addItem(player, Items.STURDY_BOOTS_3700)) { + stage++ + } } 16 -> npcl(FacialExpression.HAPPY,"Yes, that all appears in order. Tell Olaf to come to me next time for shoes!").also { stage = 1000 } diff --git a/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java b/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java index e928e6179..65f5d4e43 100644 --- a/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java +++ b/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java @@ -97,7 +97,7 @@ public final class DagannothKingNPC extends AbstractNPC { public void finalizeDeath(Entity killer) { super.finalizeDeath(killer); if (getId() == 2881 || getId() == 2882 || getId() == 2883) { - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); } } diff --git a/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java b/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java index 7836a1c2c..e887f5263 100644 --- a/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java +++ b/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java @@ -146,7 +146,7 @@ public final class SpinolypNPC extends AbstractNPC { super.impact(entity, victim, state); if (super.getType() == CombatStyle.MAGIC && state.getEstimatedHit() > 0) { victim.getSkills().decrementPrayerPoints(1); - } else { + } else if (super.getType() == CombatStyle.RANGE && state.getEstimatedHit() > 0) { if (RandomFunction.random(20) == 5) { applyPoison(victim, entity, 30); } diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/PenguinKeeperDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/PenguinKeeperDialogue.kt new file mode 100644 index 000000000..9a6ccdff9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/PenguinKeeperDialogue.kt @@ -0,0 +1,62 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.addItem +import core.api.getDynLevel +import core.api.hasAnItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class PenguinKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds(): IntArray { + return intArrayOf(NPCs.PENGUIN_KEEPER_6891) + } + + companion object{ + const val YES = 20 + const val NO = 40 + const val FULL = 50 + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there. How are the penguins doing today?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "They are doing fine, thanks.").also{ + if (getDynLevel(player, Skills.SUMMONING) < 30 || hasAnItem(player, Items.PENGUIN_EGG_12483).exists()) + stage = END_DIALOGUE + else + stage++ + } + 2 -> npcl(FacialExpression.HALF_ASKING,"Actually, you might be able to help me with something - if you are interested.").also { stage++ } + 3 -> playerl(FacialExpression.ASKING, "What do you mean?").also { stage++ } + 4 -> npcl(FacialExpression.NEUTRAL, "Well, you see, the penguins have been laying so many eggs recently that we can't afford to raise them all ourselves.").also { stage++ } + 5 -> npcl(FacialExpression.ASKING, " You seem to know a bit about raising animals - would you like to raise a penguin for us? ").also { stage++ } + 6 -> showTopics( + Topic("Yes, of course.", YES), + Topic("No thanks.", NO) + ) + + YES -> npcl(FacialExpression.HAPPY, "Wonderful!").also { + if (addItem(player, Items.PENGUIN_EGG_12483)) + stage++ + else + stage = FULL + } + YES + 1 -> npcl(FacialExpression.HAPPY, "Here you go - this egg will hatch into a baby penguin.").also { stage++ } + YES + 2 -> npcl(FacialExpression.HAPPY, "They eat raw fish and aren't particularly fussy about anything, so it won't be any trouble to raise.").also { stage++ } + YES + 3 -> playerl(FacialExpression.HAPPY, "Okay, thank you very much.").also { stage = END_DIALOGUE } + + NO -> npcl(FacialExpression.NEUTRAL, " Fair enough. The offer still stands if you change your mind. ").also { stage = END_DIALOGUE } + + FULL -> npcl(FacialExpression.SAD, "You don't have inventory space though.").also { stage = END_DIALOGUE } + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java b/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java index 5b8c59117..117dbf5da 100644 --- a/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java +++ b/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java @@ -1,5 +1,6 @@ package content.region.kandarin.ardougne.handlers; +import core.ServerConstants; import core.cache.def.impl.SceneryDefinition; import core.plugin.Initializable; import core.game.dialogue.DialogueInterpreter; @@ -8,7 +9,6 @@ import core.game.interaction.OptionHandler; import core.game.node.Node; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.TeleportManager; -import core.game.node.entity.player.link.audio.Audio; import core.game.node.scenery.Scenery; import core.game.node.scenery.SceneryBuilder; import core.game.system.task.Pulse; @@ -20,10 +20,11 @@ import core.plugin.ClassScanner; import org.rs09.consts.Sounds; import static core.api.ContentAPIKt.playAudio; +import static content.region.wilderness.handlers.WildernessGateHandlerKt.enterDeepWilderness; /** * Handles wilderness levers. - * @author 'Vexia + * @author 'Vexia, Player Name * @version 1.0 */ @Initializable @@ -279,7 +280,6 @@ public final class WildernessLeverPlugin extends OptionHandler { public Location[] getLocations() { return locations; } - } /** @@ -325,7 +325,14 @@ public final class WildernessLeverPlugin extends OptionHandler { public boolean open(Object... args) { lever = (LeverSets) args[0]; id = (int) args[1]; - interpreter.sendDialogue("Warning! Pulling the lever will teleport you deep into the wilderness."); + if (ServerConstants.ENHANCED_DEEP_WILDERNESS) { + enterDeepWilderness(player, (player) -> { + lever.pull(player, lever.getIndex(id), true); + return null; + }, "Pulling the lever will teleport you into the deep wilderness."); + } else { + interpreter.sendDialogue("Warning! Pulling the lever will teleport you deep into the wilderness."); + } return true; } diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/CivilianDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/CivilianDialogue.kt deleted file mode 100644 index 0dc0d3c96..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/CivilianDialogue.kt +++ /dev/null @@ -1,44 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue - -import core.api.inEquipment -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.Items -import org.rs09.consts.NPCs - -@Initializable -class CivilianDialogue(player: Player? = null) : DialoguePlugin(player) { - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - if(inEquipment(player, Items.GAS_MASK_1506)) { - playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 4 } - } else { - playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } - } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - 0 -> npcl(FacialExpression.FRIENDLY, "I'm a bit busy to talk right now, sorry.").also { stage++ } - 1 -> playerl(FacialExpression.FRIENDLY, "Why? What are you doing?").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "Trying to kill these mice! What I really need is a cat!").also { stage++ } - 3 -> playerl(FacialExpression.FRIENDLY, "No, you're right, you don't see many around.").also { stage = END_DIALOGUE } - 4 -> npcl(FacialExpression.FRIENDLY, "If you Mourners really wanna help, why don't you do something about these mice?!").also { stage = END_DIALOGUE } - } - return true - } - - override fun newInstance(player: Player?): DialoguePlugin { - return CivilianDialogue(player) - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.CIVILIAN_785, NPCs.CIVILIAN_786, NPCs.CIVILIAN_787) - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/KilronDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/KilronDialogue.kt deleted file mode 100644 index 7cba51211..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/KilronDialogue.kt +++ /dev/null @@ -1,53 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue - -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.NPCs - -@Initializable -class KilronDialogue(player: Player? = null) : DialoguePlugin(player) { - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - if (player.questRepository.getQuest("Plague City").isCompleted(player)){ - npcl(FacialExpression.FRIENDLY, "Looks like you won't be needing the rope ladder any more, adventurer. I heard it was you who started the revolution and freed West Ardougne!").also { stage = END_DIALOGUE } - } else { - playerl(FacialExpression.FRIENDLY, "Hello there.") - } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - 0 -> npcl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } - 1 -> playerl(FacialExpression.FRIENDLY, "How are you?").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "Busy.").also { stage = END_DIALOGUE } - } - return true - } - - /* After Biohazard and before Plague's End - 0 -> playerl(FacialExpression.FRIENDLY, "Hello Kilron.").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "Hello traveller. Do you need to go back over?").also { stage++ } - 2 -> options("Not yet Kilron", "Yes I do").also { stage++ } - 3 -> when(buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Not yet Kilron.").also { stage = 4 } - 2 -> playerl(FacialExpression.FRIENDLY, "Yes I do.").also { stage = 5 } - } - 4 -> npcl(FacialExpression.FRIENDLY, "Okay, just give me the word.").also { stage = END_DIALOGUE } - 5 -> npcl(FacialExpression.FRIENDLY, "Okay, quickly now!").also { stage = END_DIALOGUE } - */ - - override fun newInstance(player: Player?): DialoguePlugin { - return KilronDialogue(player) - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.KILRON_349) - } - -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/ManDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/ManDialogue.kt deleted file mode 100644 index 006f72819..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/ManDialogue.kt +++ /dev/null @@ -1,24 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue - -import core.game.dialogue.DialogueFile -import core.game.dialogue.FacialExpression -import core.plugin.Initializable -import core.tools.END_DIALOGUE - -@Initializable -class ManDialogue : DialogueFile() { - - override fun handle(componentID: Int, buttonID: Int) { - when (stage) { - 0 -> npcl(FacialExpression.HALF_GUILTY, "We don't have good days here anymore. Curse King Tyras.").also { stage++ } - 1 -> options("Oh okay, bad day then.", "Why, what has he done?", "I'm looking for a woman called Elena.").also { stage++ } - 2 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Oh okay, bad day then.").also { stage = END_DIALOGUE } - 2 -> playerl(FacialExpression.FRIENDLY, "Why, what has he done?").also { stage = 3 } - 3 -> playerl(FacialExpression.FRIENDLY, "I'm looking for a woman called Elena.").also { stage = 4 } - } - 3 -> npcl(FacialExpression.FRIENDLY, "His army curses our city with this plague then wanders off again, leaving us to clear up the pieces.").also { stage = END_DIALOGUE } - 4 -> npcl(FacialExpression.THINKING, "Not heard of her.").also { stage = END_DIALOGUE } - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/MournersDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/MournersDialogue.kt deleted file mode 100644 index 2b1ceaac5..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/MournersDialogue.kt +++ /dev/null @@ -1,41 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue - -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.NPCs - -@Initializable -class MournersDialogue(player: Player? = null) : DialoguePlugin(player) { - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 0 } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - 0 -> npcl(FacialExpression.SAD, "What are you up to?").also { stage++ } - 1 -> playerl(FacialExpression.NEUTRAL,"Just sight-seeing.").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "This is no place for sight-seeing. Don't you know there's been a plague outbreak?").also { stage++ } - 3 -> playerl(FacialExpression.FRIENDLY, "Yes, I had heard.").also { stage++ } - 4 -> npcl(FacialExpression.FRIENDLY, "Then I suggest you leave as soon as you can.").also { stage++ } - 5 -> playerl(FacialExpression.FRIENDLY, "Thanks for the advice.").also { stage = END_DIALOGUE } - } - return true - } - - override fun newInstance(player: Player?): DialoguePlugin { - return MournersDialogue(player) - } - - override fun getIds(): IntArray { - return intArrayOf( - NPCs.MOURNER_347, NPCs.MOURNER_348, NPCs.MOURNER_357, NPCs.MOURNER_369, NPCs.MOURNER_371, NPCs.MOURNER_370) - } - -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/WomanDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/WomanDialogue.kt deleted file mode 100644 index 7e7b14fdd..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/WomanDialogue.kt +++ /dev/null @@ -1,61 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue - -import core.game.dialogue.DialogueFile -import core.game.dialogue.FacialExpression -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import core.tools.RandomFunction - -@Initializable -class WomanDialogue : DialogueFile() { - - override fun handle(componentID: Int, buttonID: Int) { - when (RandomFunction.random(1,4)) { - 1 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello, how's it going?").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "Bah, those mourners... they're meant to be helping us, but I think they're doing more harm here than good. They won't even let me send a letter out to my family.").also { stage++ } - 2 -> options("Have you seen a lady called Elena around here?", "You should stand up to them more.").also { stage++ } - 3 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Have you seen a lady called Elena around here?").also { stage = 4 } - 2 -> playerl(FacialExpression.FRIENDLY, "You should stand up to them more.").also { stage = 6 } - } - 4 -> npcl(FacialExpression.FRIENDLY, "Yes, I've seen her. Very helpful person.").also { stage++ } - 5 -> npcl(FacialExpression.FRIENDLY, "Not for the last few days though... I thought maybe she'd gone home.").also { stage = END_DIALOGUE } - 6 -> npcl(FacialExpression.FRIENDLY, "Oh I'm not one to cause a fuss.").also { stage = END_DIALOGUE } - } - - 2 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello, how's it going?").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "Life is tough.").also { stage++ } - 2 -> options("Yes, living in a plague city must be hard.", "I'm sorry to hear that.", "I'm looking for a lady called Elena.").also { stage++ } - 3 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Yes, living in a plague city must be hard.").also { stage = 4 } - 2 -> playerl(FacialExpression.FRIENDLY, "I'm sorry to hear that.").also { stage = 6 } - 3 -> playerl(FacialExpression.FRIENDLY, "I'm looking for a lady called Elena.").also { stage = 7 } - } - 4 -> npcl(FacialExpression.FRIENDLY, "Plague? Pah, that's no excuse for the treatment we've received. It's obvious pretty quickly if someone has the plague.").also { stage++ } - 5 -> npcl(FacialExpression.FRIENDLY, "I'm thinking about making a break for it. I'm perfectly healthy, not gonna infect anyone.").also { stage = END_DIALOGUE } - 6 -> npcl(FacialExpression.FRIENDLY, "Well, ain't much either you or me can do about it.").also { stage = END_DIALOGUE } - 7 -> npcl(FacialExpression.FRIENDLY, "I've not heard of her. Old Jethick knows a lot of people, maybe he'll know where you can find her.").also { stage = END_DIALOGUE } - } - - 3 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello, how's it going?").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "We don't have good days here anymore. Curse King Tyras.").also { stage++ } - 2 -> options("Oh okay, bad day then.", "Why, what has he done?", "I'm looking for a woman called Elena.").also { stage++ } - 3 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Oh okay, bad day then.").also { stage = END_DIALOGUE } - 2 -> playerl(FacialExpression.FRIENDLY, "Why, what has he done?").also { stage = 4 } - 3 -> playerl(FacialExpression.FRIENDLY, "I'm looking for a lady called Elena.").also { stage = 5 } - } - 4 -> npcl(FacialExpression.FRIENDLY, "His army curses our city with this plague then wanders off again, leaving us to clear up the pieces.").also { stage = END_DIALOGUE } - 5 -> npcl(FacialExpression.FRIENDLY, "Not heard of her.").also { stage = END_DIALOGUE } - } - 4 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello, how's it going?").also { stage++ } - 1 -> npcl(FacialExpression.HALF_ASKING, "An outsider! Can you get me out of this hell hole?").also { stage++ } - 2 -> playerl(FacialExpression.HALF_GUILTY, "Sorry, that's not what I'm here to do.").also { stage = END_DIALOGUE } - } - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/BravekDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/BravekDialogue.kt deleted file mode 100644 index bdee4777d..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/BravekDialogue.kt +++ /dev/null @@ -1,116 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena - -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.Items -import org.rs09.consts.NPCs - -@Initializable -class BravekDialogue(player: Player? = null) : DialoguePlugin(player) { - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") == 0) { - npcl(FacialExpression.ANGRY, "Go away, I'm busy! I'm... Um... In a meeting!").also { stage = END_DIALOGUE } - } else if (player.questRepository.getStage("Plague City") == 13) { - npcl(FacialExpression.NEUTRAL, "My head hurts! I'll speak to you another day...").also { stage = 1 } - } else if (player.questRepository.getStage("Plague City") == 14) { - npcl(FacialExpression.NEUTRAL, "Uurgh! My head still hurts too much to think straight. Oh for one of Trudi's hangover cures!").also { stage = 1 } - } else if (player.questRepository.getStage("Plague City") >= 16) { - npcl(FacialExpression.NEUTRAL, "Thanks again for the hangover cure.").also { stage = 1 } - } else { - npcl(FacialExpression.ANGRY, "Go away, I'm busy! I'm... Um... In a meeting!").also { stage = END_DIALOGUE } - } - return true - } - - override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { - - 13 -> when (stage) { - 1 -> playerl(FacialExpression.FRIENDLY, "This is really important though!").also { stage = 2 } - 2 -> npcl(FacialExpression.FRIENDLY, "I can't possibly speak to you with my head spinning like this... I went a bit heavy on the drink last night.").also { stage++ } - 3 -> npcl(FacialExpression.FRIENDLY, "Curse my herbalist, she made the best hangover cures. Darn inconvenient of her catching the plague.").also { stage++ } - 4 -> options("You shouldn't drink so much then!", "Do you know what's in the cure?", "Okay, goodbye.").also { stage++ } - 5 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "You shouldn't drink so much then!").also { stage = 7 } - 2 -> playerl(FacialExpression.FRIENDLY, "Do you know what's in the cure?").also { stage = 20 } - 3 -> playerl(FacialExpression.FRIENDLY, "Okay, goodbye.").also { stage = END_DIALOGUE } - } - 7 -> npcl(FacialExpression.FRIENDLY, "Well positions of responsibility are hard, I need something to take my mind off things... Especially with the problems this place has..").also { stage++ } - 8 -> playerl(FacialExpression.FRIENDLY, "I don't think drink is the solution.").also { stage++ } - 9 -> npcl(FacialExpression.FRIENDLY, "Uurgh! My head still hurts too much to think straight. Oh for one of Trudi's hangover cures!").also { stage++ } - 10 -> npcl(FacialExpression.FRIENDLY, "I'll see what I can do I suppose. Mr. Bravek, there's someone here who really needs to speak to you.").also { stage++ } - 11 -> sendNPCDialogue(player!!, NPCs.BRAVEK_711, "I suppose they can come in then. If they keep it short.").also { stage = END_DIALOGUE } - 20 -> npcl(FacialExpression.FRIENDLY, "Hmmm let me think... Ouch! Thinking isn't clever. Ah here, she did scribble it down for me.").also { stage++ } - 21 -> if (freeSlots(player!!) == 0) { - end() - sendItemDialogue(player!!, Items.A_SCRUFFY_NOTE_1508, "Bravek waves a tatty piece of paper at you, but you don't have room to take it.").also { stage = END_DIALOGUE } - } else { - end() - sendItemDialogue(player!!, Items.A_SCRUFFY_NOTE_1508, "Bravek hands you a tatty piece of paper.").also { stage++ } - addItem(player!!, Items.A_SCRUFFY_NOTE_1508) - setQuestStage(player!!, "Plague City", 14) - } - } - - 14 -> when (stage) { - 1 -> if(removeItem(player!!, Items.HANGOVER_CURE_1504)) { - playerl(FacialExpression.FRIENDLY, "Try this.").also { stage++ } - } else { - end() - stage = END_DIALOGUE - } - 2 -> { - animate(npc, 1330) // Drink hangover cure. - findLocalNPC(player!!, NPCs.BRAVEK_711)!!.sendChat("Grruurgh!") - sendItemDialogue(player!!, Items.HANGOVER_CURE_1504, "You give Bravek the hangover cure.").also { stage++ } - } - 3 -> sendDialogue(player!!, "Bravek gulps down the foul-looking liquid.").also { stage++ } - 4 -> npcl(FacialExpression.NEUTRAL, "Ooh that's much better! Thanks, that's the clearest my head has felt in a month. Ah now, what was it you wanted me to do for you?").also { stage++ } - 5 -> playerl(FacialExpression.FRIENDLY, "I need to rescue a kidnap victim named Elena. She's being held in a plague house, I need permission to enter.").also { stage++ } - 6 -> options("Ok, I'll go speak to them.", "Is that all anyone says around here?", "They won't listen to me!").also { stage++ } - 7 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Ok, I'll go speak to them.").also { stage = 6 } - 2 -> playerl(FacialExpression.FRIENDLY, "Is that all anyone says around here?").also { stage = 11 } - 3 -> playerl(FacialExpression.FRIENDLY, "They won't listen to me! They say I'm not properly equipped to go in the house, though I do have a very effective gasmask.").also { stage++ } - } - 8 -> npcl(FacialExpression.FRIENDLY, "Hmmm, well I guess they're not taking the issue of a kidnapping seriously enough. They do go a bit far sometimes.").also { stage++ } - 9 -> npcl(FacialExpression.FRIENDLY, "I've heard of Elena, she has helped us a lot... Ok, I'll give you this warrant to enter the house.").also { stage = 17 } - 11 -> npcl(FacialExpression.FRIENDLY, "Well, they know best about plague issues.").also { stage++ } - 12 -> playerl(FacialExpression.FRIENDLY, "Don't you want to take an interest in it at all?").also { stage++ } - 13 -> npcl(FacialExpression.FRIENDLY, "Nope, I don't wish to take a deep interest in plagues. That stuff is too scary for me!").also { stage++ } - 14 -> playerl(FacialExpression.FRIENDLY, "I can see why people say you're a weak leader.").also { stage++ } - 15 -> npcl(FacialExpression.FRIENDLY, "Bah, people always criticise their leaders but delegating is the only way to lead. I delegate all plague issues to the mourners.").also { stage++ } - 16 -> playerl(FacialExpression.FRIENDLY, "This whole city is a plague issue!").also { stage = 6 } - 17 -> if (freeSlots(player!!) == 0) { - end() - sendItemDialogue(player!!, Items.WARRANT_1503, "Bravek waves a warrant at you, but you don't have room to take it.").also { stage = END_DIALOGUE } - } else { - end() - sendItemDialogue(player!!, Items.WARRANT_1503, "Bravek hands you a warrant.").also { stage = END_DIALOGUE } - addItem(player!!, Items.WARRANT_1503) - setQuestStage(player!!, "Plague City", 16) - } - } - - 16 -> when (stage) { - 1 -> playerl(FacialExpression.NEUTRAL, "Not a problem, happy to help out.").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "I'm just having a little drop of whisky, then I'll feel really good.").also { stage = END_DIALOGUE } - } - - in 17..100 -> when (stage) { - 1 -> playerl(FacialExpression.FRIENDLY, "Not a problem, happy to help out.").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "I'm just having a little drop of whisky, then I'll feel really good.").also { stage = END_DIALOGUE } - } - } - return true - } - - override fun getIds(): IntArray = intArrayOf(NPCs.BRAVEK_711) -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/ClerkDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/ClerkDialogue.kt deleted file mode 100644 index 3f44c539e..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/ClerkDialogue.kt +++ /dev/null @@ -1,94 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena - -import core.api.getQuestStage -import core.api.sendNPCDialogue -import core.api.setQuestStage -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.NPCs - -@Initializable -class ClerkDialogue(player: Player? = null) : DialoguePlugin(player) { - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - npcl(FacialExpression.NEUTRAL, "Hello, welcome to the Civic Office of West Ardougne. How can I help you?").also { stage = 0 } - return true - } - - override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { - - 11 -> when (stage) { - 0 -> options("Who is through that door?", "I'm just looking thanks.").also { stage++ } - 1 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Who is through that door?").also { stage = 2 } - 2 -> playerl(FacialExpression.FRIENDLY, "I'm just looking thanks.").also { stage = END_DIALOGUE } - } - 2 -> npcl(FacialExpression.FRIENDLY, "The city warder Bravek is in there.").also { stage++ } - 3 -> playerl(FacialExpression.FRIENDLY,"Can I go in?").also { stage++ } - 4 -> npcl(FacialExpression.FRIENDLY, "He has asked not to be disturbed.").also { stage = END_DIALOGUE } - } - - 12 -> when (stage) { - 0 -> options("I need permission to enter a plague house.", "Who is through that door?", "I'm just looking thanks.").also { stage++ } - 1 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "I need permission to enter a plague house.").also { stage = 2 } - 2 -> playerl(FacialExpression.FRIENDLY, "Who is through that door?").also { stage = 12 } - 3 -> playerl(FacialExpression.FRIENDLY, "I'm just looking thanks.").also { stage = END_DIALOGUE } - } - 2 -> npcl(FacialExpression.FRIENDLY, "Rather you than me! The mourners usually deal with that stuff, you should speak to them. Their headquarters are right near the city gate.").also { stage++ } - 3 -> options("I'll try asking them then.", "Surely you don't let them run everything for you?").also { stage++ } - 4 -> when (buttonID) { - 1 -> playerl(FacialExpression.HALF_GUILTY, "I'll try asking them then.").also { stage = END_DIALOGUE } - 2 -> playerl(FacialExpression.HALF_GUILTY, "Surely you don't let them run everything for you?").also { stage = 5 } - } - 5 -> npcl(FacialExpression.FRIENDLY, "Well, they do know what they're doing here. If they did start doing something badly Bravek, the city warder, would have the power to override them. I can't see that happening though.").also { stage++ } - 6 -> options("I'll try asking them then.", "Can I speak to Bravek anyway?", "This is urgent though! Someone's been kidnapped!").also { stage++ } - 7 -> when (buttonID) { - 1 -> playerl(FacialExpression.HALF_GUILTY, "I'll try asking them then.").also { stage = END_DIALOGUE } - 2 -> playerl(FacialExpression.HALF_GUILTY, "Can I speak to Bravek anyway?").also { stage = 8 } - 3 -> playerl(FacialExpression.HALF_GUILTY, "This is urgent though! Someone's been kidnapped!").also { stage = 11 } - } - 8 -> npcl(FacialExpression.FRIENDLY, "He has asked not to be disturbed.").also { stage++ } - 9 -> options("This is urgent though! Someone's been kidnapped!", "Okay, I'll leave him alone.", "Do you know when he will be available?").also { stage++ } - 10 -> when (buttonID) { - 1 -> playerl(FacialExpression.HALF_GUILTY, "This is urgent though! Someone's been kidnapped!").also { stage = 11 } - 2 -> playerl(FacialExpression.HALF_GUILTY, "Okay, I'll leave him alone.").also { stage = END_DIALOGUE } - 3 -> playerl(FacialExpression.HALF_GUILTY, "Do you know when he will be available?").also { stage = 14 } - } - 11 -> npcl(FacialExpression.HALF_GUILTY, "I'll see what I can do I suppose.").also { stage++ } - 12 -> npcl(FacialExpression.HALF_GUILTY, "Mr Bravek, there's a man here who really needs to speak to you.").also { stage++ } - 13 -> { - end() - setQuestStage(player!!, "Plague City", 13) - sendNPCDialogue(player!!, NPCs.BRAVEK_711, "I suppose they can come in then. If they keep it short.").also { stage++ } - } - 14 -> npcl(FacialExpression.HALF_GUILTY, "Oh I don't know, an hour or so maybe.").also { stage = END_DIALOGUE } - } - - in 13..15 -> when (stage) { - 0 -> npcl(FacialExpression.FRIENDLY, "Bravek will see you now but keep it short!").also { stage++ } - 1 -> playerl(FacialExpression.FRIENDLY, "Thanks, I won't take much of his time.").also { stage = END_DIALOGUE } - } - - in 16..100 -> when (stage) { - 0 -> options("Who is through that door?", "I'm just looking thanks.").also { stage++ } - 1 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Who is through that door?").also { stage = 2 } - 2 -> playerl(FacialExpression.FRIENDLY, "I'm just looking thanks.").also { stage = END_DIALOGUE } - } - 2 -> npcl(FacialExpression.FRIENDLY, "The city warder Bravek is in there.").also { stage++ } - 3 -> playerl(FacialExpression.FRIENDLY,"Can I go in?").also { stage++ } - 4 -> npcl(FacialExpression.FRIENDLY, "I suppose so.").also { stage = END_DIALOGUE } - } - } - return true - } - - override fun getIds(): IntArray = intArrayOf(NPCs.CLERK_713) -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/EdmondDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/EdmondDialogue.kt deleted file mode 100644 index 9d77ce77b..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/EdmondDialogue.kt +++ /dev/null @@ -1,167 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena - -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.Items -import org.rs09.consts.NPCs - -@Initializable -class EdmondDialogue(player: Player? = null) : DialoguePlugin(player) { - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - if(inEquipmentOrInventory(player, Items.GAS_MASK_1506) && (player.questRepository.getStage("Plague City") == 2)) { - playerl(FacialExpression.FRIENDLY, "Hi Edmond, I've got the gas mask now.").also { stage++ } - } else if(player.questRepository.getStage("Plague City") > 2) { - playerl(FacialExpression.FRIENDLY, "Hello Edmond.").also { stage++ } - } else { - playerl(FacialExpression.FRIENDLY, "Hello old man.").also { stage++ } - } - return true - } - - override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { - - 0 -> when (stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "Sorry, I can't stop to talk...").also { stage++ } - 2 -> playerl(FacialExpression.FRIENDLY, "Why, what's wrong?").also { stage++ } - 3 -> npcl(FacialExpression.FRIENDLY, "I've got to find my daughter. I pray that she is still alive...").also { stage++ } - 4 -> options("What's happened to her?", "Well, good luck finding her.").also { stage++ } - 5 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "What's happened to her?").also { stage = 6 } - 2 -> playerl(FacialExpression.FRIENDLY, "Well, good luck finding her.").also { stage = END_DIALOGUE } - } - 6 -> npcl(FacialExpression.NEUTRAL, "Elena's a missionary and a healer. Three weeks ago she managed to cross the Ardougne wall...").also { stage++ } - 7 -> npcl(FacialExpression.NEUTRAL, "No-one's allowed to cross the wall in case they spread the plague. But after hearing the screams of suffering she felt she had to help.").also { stage++ } - 8 -> npcl(FacialExpression.NEUTRAL, "She said she'd be gone for a few days but we've heard nothing since.").also { stage++ } - 9 -> options("Tell me more about the plague.", "Can I help find her?", "I'm sorry, I have to go.").also { stage++ } - 10 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Tell me more about the plague.").also { stage = 12 } - 2 -> playerl(FacialExpression.FRIENDLY, "Can I help find her?").also { stage = 13 } - 3 -> playerl(FacialExpression.FRIENDLY, "I'm sorry, I have to go.").also { stage = END_DIALOGUE } - } - 12 -> npcl(FacialExpression.FRIENDLY, "The mourners can tell you more than me. They're the only ones allowed to cross the border. I do know the plague is a horrible way to go... That's why Elena felt she had to go help.").also { stage = 9 } - 13 -> npcl(FacialExpression.FRIENDLY, "Really, would you? I've been working on a plan to get into West Ardougne, but I'm too old and tired to carry it through.").also { stage++ } - 14 -> npcl(FacialExpression.FRIENDLY, "If you're going into West Ardougne you'll need protection from the plague. My wife made a special gas mask for Elena with dwellberries rubbed into it.").also { stage++ } - 15 -> npcl(FacialExpression.FRIENDLY, "Dwellberries help repel the virus! We need some more though...").also { stage++ } - 16 -> playerl(FacialExpression.ASKING, "Where can I find these dwellberries?").also { stage++ } - 17 -> npcl(FacialExpression.FRIENDLY, "The only place I know of is McGrubor's Wood just north of the Rangers' Guild.").also { stage++ } - 18 -> playerl(FacialExpression.FRIENDLY, "Ok, I'll go and get some.").also { stage++ } - 19 -> npcl(FacialExpression.NEUTRAL, "The foresters keep a close eye on it, but there is a back way in.").also { stage++ } - 20 -> { - end() - setQuestStage(player!!, PlagueCity.PlagueCityQuest, 1) - } - } - - 1 -> when (stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "Have you got the dwellberries yet?").also { stage++ } - 2 -> if (!inInventory(player, Items.DWELLBERRIES_2126)) { - playerl(FacialExpression.FRIENDLY, "Sorry, I'm afraid not.").also { stage = 3 } - } else { - playerl(FacialExpression.FRIENDLY, "Yes I've got some here.").also { stage = 6 } - } - 3 -> npcl(FacialExpression.NEUTRAL, "You'll probably find them in McGrubor's Wood it's just west of Seers village.").also { stage++ } - 4 -> playerl(FacialExpression.NEUTRAL, "Ok, I'll go and get some.").also { stage++ } - 5 -> npcl(FacialExpression.NEUTRAL, "The foresters keep a close eye on it, but there is a back way in.").also { stage = END_DIALOGUE } - 6 -> npcl(FacialExpression.NEUTRAL, "Take them to my wife Alrena, she's inside.").also { stage = END_DIALOGUE } - } - - 2 -> when (stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "Good stuff, now for the digging. Beneath us are the Ardougne sewers, there you'll find the access to West Ardougne.").also { stage++ } - 2 -> npcl(FacialExpression.NEUTRAL, "The problem is the soil is rock hard. You'll need to pour on several buckets of water to soften it up. I'll keep an eye out for the mourners.").also { stage++ } - 3 -> { - end() - setQuestStage(player!!, "Plague City", 3) - } - } - - 3 -> when (stage) { - 1 -> if (player!!.getAttribute("/save:elena:dig", false) == true) { - playerl(FacialExpression.NEUTRAL, "I've soaked the soil with water.").also { stage = 3 } - } else { - npcl(FacialExpression.FRIENDLY, "How's it going?").also { stage = 2 } - } - 2 -> if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 1) { - playerl(FacialExpression.NEUTRAL, "I still need to pour three more buckets of water on the soil.").also { stage = END_DIALOGUE } - } else if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 2){ - playerl(FacialExpression.NEUTRAL, "I still need to pour two more buckets of water on the soil.").also { stage = END_DIALOGUE } - } else if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 3) { - playerl(FacialExpression.NEUTRAL, "I still need to pour one more bucket of water on the soil.").also { stage = END_DIALOGUE } - } - 3 -> npcl(FacialExpression.FRIENDLY, "That's great, it should be soft enough to dig through now.").also { stage = END_DIALOGUE } - } - - 4 -> when (stage) { - 1 -> npcl(FacialExpression.FRIENDLY, "I think it's the pipe to the south that comes up in West Ardougne.").also { stage++ } - 2 -> playerl(FacialExpression.NEUTRAL, "Alright I'll check it out.").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "Once you're in the city look for a man called Jethick, he's an old friend and should help you. Send him my regards, I haven't seen him since before Elena was born.").also { stage++ } - 4 -> playerl(FacialExpression.NEUTRAL, "Alright, thanks I will.").also { stage = END_DIALOGUE } - } - - 5 -> when (stage) { - 1 -> playerl(FacialExpression.NEUTRAL, "Edmond, I can't get through to West Ardougne! There's an iron grill blocking my way, I can't pull it off alone.").also { stage++ } - 2 -> npcl(FacialExpression.NEUTRAL, "If you get some rope you could tie to the grill, then we could both pull it at the same time.").also { stage = END_DIALOGUE } - } - - 6 -> when (stage) { - 1 -> playerl(FacialExpression.NEUTRAL, "I've tied a rope to the grill over there, will you help me pull it off?").also { stage++ } - 2 -> npcl(FacialExpression.NEUTRAL, "Alright, let's get to it...").also { stage++ } - 3 -> { - end() - UndergroundCutscene(player!!).start() - } - } - - 7 -> when (stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } - 2 -> playerl(FacialExpression.NEUTRAL, "Not yet, it's a big city over there.").also { stage++ } - 3 -> npcl(FacialExpression.FRIENDLY, "Don't forget to look for my friend Jethick. He may be able to help.").also { stage = END_DIALOGUE } - } - - 8 -> when (stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } - 2 -> playerl(FacialExpression.NEUTRAL, "Not yet, it's a big city over there. Do you have a picture of Elena?").also { stage++ } - 3 -> npcl(FacialExpression.FRIENDLY, "There should be a picture of Elena in the house. Please find her quickly, I hope it's not too late.").also { stage = END_DIALOGUE } - } - - 99 -> when (stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "Thank you, thank you! Elena beat you back by minutes.").also { stage++ } - 2 -> npcl(FacialExpression.NEUTRAL, "Now I said I'd give you a reward. What can I give you as a reward I wonder?").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "Here take this magic scroll, I have little use for it but it may help you.").also { stage++ } - 4 -> { - end() - player!!.questRepository.getQuest("Plague City").finish(player) - } - } - - 100 -> when (stage) { - 1 -> if (!inInventory(player!!, Items.ARDOUGNE_TELEPORT_8011)) { - npcl(FacialExpression.FRIENDLY, "Ah hello again, and thank you again for rescuing my daughter.").also { stage = 2 } - } else { - npcl(FacialExpression.FRIENDLY, "Ah hello again, and thank you again for rescuing my daughter.").also { stage = 5 } - } - 2 -> options("Do you have any more of those scrolls?", "No problem.").also { stage++ } - 3 -> when (buttonID) { - 1 -> playerl(FacialExpression.NEUTRAL, "Do you have any more of those scrolls?").also { stage = 4 } - 2 -> playerl(FacialExpression.NEUTRAL, "No problem.").also { stage = END_DIALOGUE } - } - 4 -> npcl(FacialExpression.FRIENDLY, "Here take this magic scroll, I have little use for it but it may help you.").also { stage = 6 } - 5 -> playerl(FacialExpression.NEUTRAL, "No problem.").also { stage = END_DIALOGUE } - 6 -> { - end() - addItemOrDrop(player!!, Items.A_MAGIC_SCROLL_1505) - } - } - } - return true - } - - override fun getIds(): IntArray = intArrayOf(NPCs.EDMOND_714) -} diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MournerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MournerDialogue.kt deleted file mode 100644 index 7dc148c27..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MournerDialogue.kt +++ /dev/null @@ -1,86 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena - -import core.api.* -import core.game.dialogue.DialogueFile -import core.game.dialogue.FacialExpression -import core.game.global.action.DoorActionHandler -import core.game.node.entity.npc.NPC -import core.game.world.map.RegionManager.getObject -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.NPCs - -@Initializable -class MournerDialogue : DialogueFile() { - override fun handle(componentID: Int, buttonID: Int) { - npc = NPC(NPCs.MOURNER_3216) - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { - - in 0..6 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } - 1 -> npcl(FacialExpression.NEUTRAL, "What are you up to with old man Edmond?").also { stage++ } - 2 -> playerl(FacialExpression.FRIENDLY, "Nothing, we've just been chatting.").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "What about his daughter?").also { stage++ } - 4 -> playerl(FacialExpression.FRIENDLY, "you know about that then?").also { stage++ } - 5 -> npcl(FacialExpression.NEUTRAL, "We know about everything that goes on in Ardougne. We have to if we are to contain the plague.").also { stage++ } - 6 -> playerl(FacialExpression.FRIENDLY, "Have you see his daughter recently?").also { stage++ } - 7 -> npcl(FacialExpression.NEUTRAL, "I imagine she's caught the plague. Either way she won't be allowed out of West Ardougne, the risk is too great.").also { stage == END_DIALOGUE } - } - - 7 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } - 1 -> npcl(FacialExpression.NEUTRAL, "Been digging have we?").also { stage++ } - 2 -> playerl(FacialExpression.FRIENDLY, "What do you mean?").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "Your hands are covered in mud.Player: Oh that...").also { stage++ } - 4 -> npcl(FacialExpression.NEUTRAL, "Funny, you don't look like the gardening type.").also { stage++ } - 5 -> playerl(FacialExpression.FRIENDLY, "Oh no, I love gardening! It's my favorite pastime.").also { stage = END_DIALOGUE } - } - - 8 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } - 1 -> npcl(FacialExpression.NEUTRAL, "Do you have a problem traveller?").also { stage++ } - 2 -> playerl(FacialExpression.NEUTRAL, "No, I just wondered why you're wearing that outfit... Is it fancy dress?").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "No! It's for protection.").also { stage++ } - 4 -> playerl(FacialExpression.NEUTRAL, "Protection from what?").also { stage++ } - 5 -> npcl(FacialExpression.FRIENDLY, "The plague of course...").also { stage = END_DIALOGUE } - } - - in 9..15 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } - 1 -> npcl(FacialExpression.NEUTRAL, "Can I help you?").also { stage++ } - 2 -> playerl(FacialExpression.NEUTRAL, "What are you doing?").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "I'm guarding the border to West Ardougne. No-one except we mourners can pass through.").also { stage++ } - 4 -> playerl(FacialExpression.NEUTRAL, "Why?").also { stage++ } - 5 -> npcl(FacialExpression.FRIENDLY, "The plague of course. We can't risk cross contamination.").also { stage++ } - 6 -> playerl(FacialExpression.FRIENDLY, "Ok then, see you around.").also { stage++ } - 7 -> npcl(FacialExpression.FRIENDLY, "Maybe...").also { stage = END_DIALOGUE } - } - - 16 -> when (stage) { - 0 -> if (inBorders(player!!, 2532, 3272, 2534, 3273)) { - player!!.dialogueInterpreter.sendDialogue("The door won't open.", "You notice a black cross on the door.").also { stage = END_DIALOGUE } - } else { - playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } - } - 1 -> playerl(FacialExpression.FRIENDLY, "I have a warrant from Bravek to enter here.").also { stage++ } - 2 -> npcl(FacialExpression.NEUTRAL, "This is highly irregular. Please wait...").also { stage++ } - 3 -> { - runTask(player!!, 0) { - findLocalNPC(player!!, NPCs.MOURNER_717)!!.sendChat("Hay... I got someone here with a warrant from Bravek, what should we do?") - findLocalNPC(player!!, NPCs.MOURNER_3216)!!.sendChat("Well you can't let them in...", 1) - }.also { - end() - setQuestStage(player!!, "Plague City", 17) - DoorActionHandler.handleAutowalkDoor(player, getObject(location(2540, 3273, 0))!!.asScenery()) - sendDialogue(player!!, "You wait until the mourner's back is turned and sneak into the building.") - } - } - } - - in 17..100 -> when (stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "I'd stand away from there. That black cross means that house has been touched by the plague.").also { stage = END_DIALOGUE } - } - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/PlagueCityListeners.kt b/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/PlagueCityListeners.kt deleted file mode 100644 index 469f9302a..000000000 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/PlagueCityListeners.kt +++ /dev/null @@ -1,456 +0,0 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena - -import content.region.kandarin.ardougne.plaguecity.dialogue.ManDialogue -import content.region.kandarin.ardougne.plaguecity.dialogue.WomanDialogue -import core.api.* -import core.game.dialogue.DialogueFile -import core.game.dialogue.FacialExpression -import core.game.global.action.DoorActionHandler -import core.game.interaction.IntType -import core.game.interaction.InteractionListener -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.game.system.task.Pulse -import core.game.world.map.Direction -import core.game.world.map.Location -import core.tools.END_DIALOGUE -import org.rs09.consts.Items -import org.rs09.consts.NPCs -import org.rs09.consts.Scenery - -class PlagueCityListeners : InteractionListener { - companion object { - - const val BUCKET_USES_ATTRIBUTE = "/save:elena:bucket" - - const val BRAVEK = NPCs.BRAVEK_711 - const val HEAD_MOURNER = NPCs.HEAD_MOURNER_716 - const val BILLI = 723 - - val MANS = intArrayOf(NPCs.MAN_728,NPCs.MAN_729, NPCs.MAN_351) - val WOMANS = intArrayOf(NPCs.WOMAN_352, NPCs.WOMAN_353, NPCs.WOMAN_354, NPCs.WOMAN_360, NPCs.WOMAN_362, NPCs.WOMAN_363) - - const val MUD_PILE = Scenery.MUD_PILE_2533 - const val GRILL = Scenery.GRILL_11423 - const val MUD_PATCH = Scenery.MUD_PATCH_11418 - const val PIPE = Scenery.PIPE_2542 - const val WARDROBE = Scenery.WARDROBE_2525 - const val LEFT_DOOR = Scenery.ARDOUGNE_WALL_DOOR_9738 - const val RIGHT_DOOR = Scenery.ARDOUGNE_WALL_DOOR_9330 - const val PLAGUE_TED_DOORS = Scenery.DOOR_2537 - const val HEAD_DOORS = Scenery.DOOR_35991 - const val BARREL = Scenery.BARREL_2530 - const val SPOOKY_STAIRS_DOWN = Scenery.SPOOKY_STAIRS_2522 - const val SPOOKY_STAIRS_UP = Scenery.SPOOKY_STAIRS_2523 - const val PRISON_DOORS = Scenery.DOOR_2526 - const val BRAVEK_DOORS = Scenery.DOOR_2528 - const val MANHOLE_CLOSED = Scenery.MANHOLE_2543 - const val MANHOLE_OPEN = Scenery.MANHOLE_2544 - const val MANHOLE_COVER = Scenery.MANHOLE_COVER_2545 - - private const val SNAPE_GRASS = Items.SNAPE_GRASS_231 - private const val SPADE = Items.SPADE_952 - private const val ROPE = Items.ROPE_954 - private const val HANGOVER_CURE = Items.HANGOVER_CURE_1504 - private const val MAGIC_SCROLL = Items.A_MAGIC_SCROLL_1505 - private const val GAS_MASK = Items.GAS_MASK_1506 - private const val SMALL_KEY = Items.A_SMALL_KEY_1507 - private const val SCRUFFY_NOTE = Items.A_SCRUFFY_NOTE_1508 - private const val BOOK = Items.BOOK_1509 - private const val EMPTY_BUCKET = Items.BUCKET_1925 - private const val BUCKET_OF_MILK = Items.BUCKET_OF_MILK_1927 - private const val BUCKET_OF_WATER = Items.BUCKET_OF_WATER_1929 - private const val CHOCOLATE_DUST = Items.CHOCOLATE_DUST_1975 - private const val CHOCOLATE_MILK = Items.CHOCOLATEY_MILK_1977 - - private const val TRYING_TO_OPEN_GRILL = 3192 - private const val POUR_THE_WATER = 2283 - private const val CLIMB_LADDER = 828 - private const val GO_INTO_PIPE = 10580 - private const val TIE_THE_ROPE = 3191 - private const val DIG_WITH_SPADE = 830 - - } - - override fun defineListeners() { - - on(BILLI, IntType.NPC, "talk-to") { player, _ -> - sendMessage(player, "Billy isn't interested in talking.") - return@on true - } - - on(HEAD_MOURNER, IntType.NPC, "talk-to") { player, _ -> - openDialogue(player, HeadMournerDialogue()) - return@on true - } - - on(MANS, IntType.NPC, "talk-to") { player, _ -> - if(inBorders(player, 2496, 3280,2557, 3336)) { - openDialogue(player, ManDialogue()) - } - return@on true - } - - on(WOMANS, IntType.NPC, "talk-to") { player, _ -> - if(inBorders(player, 2496, 3280,2557, 3336)) { - openDialogue(player, WomanDialogue()) - } - return@on true - } - - on(LEFT_DOOR, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getQuest("Plague City").isCompleted(player)) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else if(inBorders(player, 2556, 3298, 2557, 3301)){ - lock(player,2) - sendMessage(player, "You pull on the large wooden doors...") - runTask(player,2){ - sendMessage(player, "...But they will not open.") - } - } else { - face(player, Location.create(2559, 3302, 0)) - sendNPCDialogue(player, NPCs.MOURNER_2349, "Oi! What are you doing? Get away from there!") - } - return@on true - } - - on(RIGHT_DOOR, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getQuest("Plague City").isCompleted(player)) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else if(inBorders(player, 2556, 3298, 2557, 3301)){ - lock(player,2) - sendMessage(player, "You pull on the large wooden doors...") - runTask(player,2){ - sendMessage(player, "...But they will not open.") - } - } else { - face(player, Location.create(2559, 3302, 0)) - sendNPCDialogue(player, NPCs.MOURNER_2349, "Oi! What are you doing? Get away from there!") - } - return@on true - } - - on(MANHOLE_CLOSED, IntType.SCENERY, "open") { player, node -> - replaceScenery(node.asScenery(), MANHOLE_OPEN, -1) - addScenery(MANHOLE_COVER, Location(2529, 3302, 0),0,10) - sendMessage(player, "You pull back the manhole cover.") - return@on true - } - - on(MANHOLE_COVER, IntType.SCENERY, "close") { player, node -> - removeScenery(node.asScenery()) - getScenery(location(2529, 3303, 0))?.let { replaceScenery(it, MANHOLE_CLOSED, -1) } - sendMessage(player, "You close the manhole cover.") - return@on true - } - - on(MANHOLE_OPEN, IntType.SCENERY, "climb-down") { player, _ -> - teleport(player, Location(2514, 9739, 0)) - sendMessage(player, "You climb down through the manhole.") - return@on true - } - - on(BRAVEK_DOORS, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getStage("Plague City") >= 13) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else { - sendNPCDialogue(player,BRAVEK,"Go away, I'm busy! I'm... Umm... In a meeting!") - } - return@on true - } - - on(MUD_PILE, IntType.SCENERY, "climb") { player, _ -> - animate(player, CLIMB_LADDER) - runTask(player, 2){ - teleport(player, Location(2566, 3332)) - sendDialogue(player, "You climb up the mud pile.") - } - return@on true - } - - on(MAGIC_SCROLL, IntType.ITEM, "read") { player, _ -> - sendItemDialogue(player, MAGIC_SCROLL, "You memorise what is written on the scroll.") - removeItem(player, MAGIC_SCROLL) - sendDialogue(player, "You can now cast the Ardougne Teleport spell provided you have the required runes and magic level.") - return@on true - } - - on(SCRUFFY_NOTE, IntType.ITEM, "read") { player, _ -> - sendMessage(player, "You guess it really says something slightly different.") - openInterface(player, 222).also { scruffyNote(player) } - return@on true - } - - on(HEAD_DOORS, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getStage("Plague City") == 11) { - openDialogue(player, HeadMournerDialogue()) - } else if (player.questRepository.getStage("Plague City") == 16) { - openDialogue(player, MournerDialogue()) - } else if (player.questRepository.getStage("Plague City") > 16) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else { - openDialogue(player, MournerDialogue()) - } - return@on true - } - - on(WARDROBE, IntType.SCENERY, "search") { player, _ -> - if (freeSlots(player) == 0 && !inEquipmentOrInventory(player, GAS_MASK)) { - sendItemDialogue(player, GAS_MASK, "You find a protective mask but you don't have enough room to take it.") - } else if (inEquipmentOrInventory(player, GAS_MASK)) { - sendMessage(player, "You search the wardrobe but you find nothing.") - } else if (player.questRepository.getStage("Plague City") >= 2) { - sendItemDialogue(player, GAS_MASK, "You find a protective mask.") - addItem(player, GAS_MASK) - } - return@on true - } - - onUseWith(IntType.SCENERY, BUCKET_OF_WATER, MUD_PATCH) { player, _, _ -> - if (player.getAttribute(BUCKET_USES_ATTRIBUTE, 0) in 0..2 && removeItem(player, BUCKET_OF_WATER)) { - animate(player, POUR_THE_WATER) - player.dialogueInterpreter.sendDialogue( - "You pour water onto the soil.", - "The soil softens slightly." - ) - player.incrementAttribute(BUCKET_USES_ATTRIBUTE, 1) - addItem(player, EMPTY_BUCKET) - return@onUseWith true - } else if (player.getAttribute(BUCKET_USES_ATTRIBUTE, 0) == 3 && removeItem(player, BUCKET_OF_WATER)) { - animate(player, POUR_THE_WATER) - player.dialogueInterpreter.sendDialogue( - "You pour water onto the soil.", - "The soil is now soft enough to dig into." - ) - player.setAttribute("/save:elena:dig", true) - addItem(player, EMPTY_BUCKET) - } else { - sendMessage(player, "Nothing interesting happens.") - } - return@onUseWith true - } - - onUseWith(IntType.SCENERY, SPADE, MUD_PATCH) { player, _, _ -> - if (player.getAttribute("/save:elena:dig", false) == true) { - player.pulseManager.run(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 0 -> sendItemDialogue(player, SPADE,"You dig deep into the soft soil... Suddenly it crumbles away!") - 1 -> animate(player, DIG_WITH_SPADE) - 3 -> { - teleport(player, Location(2518, 9759)) - setQuestStage(player, "Plague City", 4) - player.dialogueInterpreter.sendDialogue( - "You fall through...", - "...you land in the sewer.", - "Edmond follows you down the hole." - ) - return true - } - } - return false - } - }) - } else { - sendMessage(player, "Nothing interesting happens.") - } - return@onUseWith true - } - - on(GRILL, IntType.SCENERY, "open") { player, _ -> - if (player.questRepository.getStage("Plague City") == 4) { - sendDialogue(player, "The grill is too secure. You can't pull it off alone.") - animate(player, TRYING_TO_OPEN_GRILL) - setQuestStage(player, "Plague City", 5) - } else { - sendDialogue(player, "There is a grill blocking your way") - } - return@on true - } - - on(PIPE, IntType.SCENERY, "climb-up") { player, _ -> - if (player.questRepository.getStage("Plague City") >= 7 && inEquipment(player, GAS_MASK)) { - animate(player, GO_INTO_PIPE,true) - forceMove(player, Location(2514, 9739, 0), Location(2514, 9734, 0), 0, 4,Direction.SOUTH) - runTask(player, 3) { - teleport(player, Location(2529, 3304, 0)) - sendDialogue(player, "You climb up through the sewer pipe.") - } - } else if (player.questRepository.getStage("Plague City") >= 7 && !inEquipment(player, GAS_MASK)) { - sendNPCDialogue(player, NPCs.EDMOND_714, "I can't let you enter the city without your gasmask on.") - } else { - sendDialogue(player, "There is a grill blocking your way") - } - return@on true - } - - onUseWith(IntType.SCENERY, ROPE, PIPE) { player, _, _ -> - sendPlayerDialogue(player, "Maybe I should try opening it first.") - return@onUseWith true - } - - onUseWith(IntType.SCENERY, ROPE, GRILL) { player, _, _ -> - if(removeItem(player, ROPE)) { - player.pulseManager.run(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 0 -> forceWalk(player, Location.create(2514, 9740, 0), "SMART") - 2 -> face(player, Location.create(2514, 9739, 0), -1) - 3 -> { - animate(player, TIE_THE_ROPE) - setVarbit(player, 1787, 5, true) // Tied rope to the grill. - } - 4 -> { - setQuestStage(player, "Plague City", 6) - sendItemDialogue(player, ROPE, "You tie the end of the rope to the sewer pipe's grill.") - } - } - return false - } - }) - } else { - sendMessage(player, "Nothing interesting happens.") - } - return@onUseWith true - } - - class TedRehnisonDoors : DialogueFile() { - override fun handle(componentID: Int, buttonID: Int) { - npc = NPC(NPCs.TED_REHNISON_721) - when (stage) { - 0 -> if(removeItem(player!!, BOOK)){ - playerl(FacialExpression.NEUTRAL, "I'm a friend of Jethick's, I have come to return a book he borrowed.").also { stage++ } - } else { - npcl(FacialExpression.FRIENDLY, "Go away. We don't want any.").also { stage = END_DIALOGUE } - } - 1 -> npcl(FacialExpression.FRIENDLY, "Oh... why didn't you say, come in then.").also { stage++ } - 2 -> sendItemDialogue(player!!, BOOK, "You hand the book to Ted as you enter.").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "Thanks, I've been missing that.").also { stage++ } - 4 -> { - end() - DoorActionHandler.handleAutowalkDoor(player, getScenery(2531, 3328, 0)) - setQuestStage(player!!, "Plague City", 9) - } - } - } - } - - on(PLAGUE_TED_DOORS, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getStage("Plague City") >= 9) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else { - openDialogue(player, TedRehnisonDoors()) - } - return@on true - } - - on(BARREL, IntType.SCENERY, "search") { player, _ -> - if (inInventory(player, SMALL_KEY)) { - sendMessage(player, "You don't find anything interesting.") - return@on true - } else { - sendItemDialogue(player, SMALL_KEY, "You find a small key in the barrel.") - addItem(player, SMALL_KEY) - } - } - - onUseWith(IntType.ITEM, CHOCOLATE_DUST, BUCKET_OF_MILK) { player, _, _ -> - if (player.questRepository.hasStarted("Plague City") && removeItem(player, CHOCOLATE_DUST) && removeItem(player, BUCKET_OF_MILK)) { - sendItemDialogue(player, CHOCOLATE_MILK, "You mix the chocolate into the bucket.") - addItem(player, CHOCOLATE_MILK) - } else { - sendMessage(player, "Nothing interesting happens.") - } - return@onUseWith true - } - - onUseWith(IntType.ITEM, SNAPE_GRASS, CHOCOLATE_MILK) { player, _, _ -> - if (player.questRepository.hasStarted("Plague City") && removeItem(player, SNAPE_GRASS) && removeItem(player, CHOCOLATE_MILK)) { - sendItemDialogue(player, HANGOVER_CURE, "You mix the snape grass into the bucket.") - addItem(player, HANGOVER_CURE) - } else { - sendMessage(player, "Nothing interesting happens.") - } - return@onUseWith true - } - - on(SPOOKY_STAIRS_DOWN, IntType.SCENERY, "walk-down") { player, _ -> - sendMessage(player, "You walk down the stairs...") - teleport(player, Location.create(2537, 9671)) - return@on true - } - - on(SPOOKY_STAIRS_UP, IntType.SCENERY, "walk-up") { player, _ -> - teleport(player, Location.create(2536, 3271, 0)) - sendMessage(player, "You walk up the stairs...") - return@on true - } - - class ElenaDoorDialogue : DialogueFile() { - override fun handle(componentID: Int, buttonID: Int) { - npc = NPC(NPCs.ELENA_3215) - when (stage) { - 0 -> sendDialogue(player!!, "The door is locked.").also { stage++ } - 1 -> npcl(FacialExpression.CRYING, "Hey get me out of here please!").also { stage++ } - 2 -> playerl(FacialExpression.FRIENDLY, "I would do but I don't have a key.").also { stage++ } - 3 -> npcl(FacialExpression.SAD, "I think there may be one around somewhere. I'm sure I heard them stashing it somewhere.").also { stage++ } - 4 -> options("Have you caught the plague?", "Okay, I'll look for it.").also { stage++ } - 5 -> when (buttonID) { - 1 -> playerl(FacialExpression.FRIENDLY, "Have you caught the plague?").also { stage = 6 } - 2 -> playerl(FacialExpression.FRIENDLY, "Okay, I'll look for it.").also { stage = END_DIALOGUE } - } - 6 -> npcl(FacialExpression.HALF_WORRIED, "No, I have none of the symptoms.").also { stage++ } - 7 -> playerl(FacialExpression.THINKING, "Strange, I was told this house was plague infected.").also { stage++ } - 8 -> playerl(FacialExpression.THINKING, "I suppose that was a cover up by the kidnappers.").also { stage = 4 } - } - } - } - - onUseWith(IntType.SCENERY, SMALL_KEY, PRISON_DOORS) { player, _, _ -> - if (player.questRepository.getStage("Plague City") >= 16) { - DoorActionHandler.handleAutowalkDoor(player, core.game.world.map.RegionManager.getObject(Location(2539, 9672, 0))!!.asScenery()) - sendDialogue(player, "You unlock the door.") - } else { - sendMessage(player, "Nothing interesting happens.") - } - return@onUseWith true - } - - on(PRISON_DOORS, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getStage("Plague City") >= 99) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else { - openDialogue(player, ElenaDoorDialogue()) - } - return@on true - } - } - - private fun scruffyNote(player: Player) { - val scruffynotes = - arrayOf( - "Got a bncket of nnilk", - "Tlen grind sorne lhoculate", - "vnith a pestal and rnortar", - "ald the grourd dlocolate to tho milt", - "finales add 5cme snape gras5", - ) - setInterfaceText(player, scruffynotes.joinToString("
"), 222, 5) - } - - override fun defineDestinationOverrides() { - setDest(IntType.SCENERY, intArrayOf(GRILL), "open") { _, _ -> - return@setDest Location.create(2514, 9739, 0) - } - - setDest(IntType.SCENERY, intArrayOf(PIPE), "climb-up") { _, _ -> - return@setDest Location.create(2514, 9739, 0) - } - - setDest(IntType.SCENERY, intArrayOf(MANHOLE_OPEN), "climb-down") { _, _ -> - return@setDest Location.create(2529, 3304, 0) - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt index 20ac88e15..9c97b7110 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt @@ -6,13 +6,12 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable -import org.rs09.consts.Items import org.rs09.consts.Items.COINS_995 +import content.data.Quests @Initializable -class FightArena : Quest("Fight Arena", 61, 60, 2, 17, 0, 1, 14) { +class FightArena : Quest(Quests.FIGHT_ARENA, 61, 60, 2, 17, 0, 1, 14) { override fun newInstance(`object`: Any?): Quest { return this } - companion object { const val FightArenaQuest = "Fight Arena" } override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) var line = 11 diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt index 1150597ca..8e4526390 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt @@ -13,6 +13,7 @@ import core.game.world.map.Location import org.rs09.consts.Items import org.rs09.consts.NPCs import org.rs09.consts.Scenery +import content.data.Quests class FightArenaListeners : InteractionListener { companion object { @@ -100,7 +101,7 @@ class FightArenaListeners : InteractionListener { } on(FULL_ARMOR_STAND, IntType.SCENERY, "borrow") { player, _ -> - if (player.questRepository.getStage("Fight Arena") >= 10 && !inEquipmentOrInventory(player, HELMET) && !inEquipmentOrInventory(player, ARMOR) && freeSlots(player) >= 2) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 10 && !inEquipmentOrInventory(player, HELMET) && !inEquipmentOrInventory(player, ARMOR) && freeSlots(player) >= 2) { replaceScenery(FULL_ARMOR_STAND_1!!.asScenery(), EMPTY_STAND, 10,location(2619, 3196, 0)) sendMessage(player, "You borrow the suit of armour. It looks like it's just your size.") addItem(player, ARMOR, 1) @@ -162,7 +163,7 @@ class FightArenaListeners : InteractionListener { } onUseWith(IntType.SCENERY, CELL_KEY, CELL_DOOR_1) { player, _, _ -> - if (player.questRepository.getStage("Fight Arena") >= 68){ + if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 68){ sendDialogue(player, "I don't want to attract too much attention by freeing all the prisoners. I need to find Jeremy and he's not in this cell.") } else { sendMessage(player, "The cell gate is securely locked.") @@ -181,9 +182,9 @@ class FightArenaListeners : InteractionListener { } on(CENTER_DOOR, IntType.SCENERY, "open") { player, node -> - if (player.questRepository.getStage("Fight Arena") >= 91) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 91) { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else if (player.questRepository.getStage("Fight Arena") < 91) { + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) < 91) { sendNPCDialogue(player, NPCs.KHAZARD_GUARD_255, "And where do you think you're going? Only General Khazard decides who fights in the arena. Get out of here.", FacialExpression.ANNOYED) } else { sendMessage(player, "The gate is locked.") @@ -254,7 +255,7 @@ class FightArenaListeners : InteractionListener { 2 -> { end() lock(player!!, 2) - setQuestStage(player!!, FightArena.FightArenaQuest, 20) + setQuestStage(player!!, Quests.FIGHT_ARENA, 20) DoorActionHandler.handleAutowalkDoor(player, getScenery(2617, 3172, 0)) } } @@ -276,7 +277,7 @@ class FightArenaListeners : InteractionListener { 2 -> { end() lock(player!!, 2) - setQuestStage(player!!, FightArena.FightArenaQuest, 20) + setQuestStage(player!!, Quests.FIGHT_ARENA, 20) DoorActionHandler.handleAutowalkDoor(player, getScenery(2584, 3141, 0)) } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt index 945a4826b..2a4ffa5a8 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -15,7 +15,7 @@ import org.rs09.consts.NPCs class ALazyGuardDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.A_LAZY_KHAZARD_GUARD_8498) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { in 40..49 -> when (stage) { 0 -> { @@ -27,7 +27,7 @@ class ALazyGuardDialogue : DialogueFile() { 3 -> npcl(FacialExpression.FRIENDLY, "Now I just want a decent drink. Mind you, too much Khali brew and I'll fall asleep.").also { stage++ } 4 -> { end() - setQuestStage(player!!, FightArena.FightArenaQuest, 50) + setQuestStage(player!!, Quests.FIGHT_ARENA, 50) } } @@ -71,7 +71,7 @@ class ALazyGuardDialogue : DialogueFile() { 14 -> { end() setVarbit(player!!, 5627, 2) - setQuestStage(player!!, FightArena.FightArenaQuest, 68) + setQuestStage(player!!, Quests.FIGHT_ARENA, 68) } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt index a7eb7248f..11b516bbc 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena +import content.data.Quests import content.region.kandarin.ardougne.quest.arena.FightArenaListeners.Companion.General import content.region.kandarin.ardougne.quest.arena.cutscenes.JailCutscene import content.region.kandarin.ardougne.quest.arena.cutscenes.ThirdFightCutscene @@ -16,7 +16,7 @@ import org.rs09.consts.NPCs class GeneralKhazardDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.GENERAL_KHAZARD_258) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { in 68..70 -> when(stage){ 0 -> npcl(FacialExpression.FRIENDLY, "Out of the way, guard! I don't tolerate disruption when I'm watching slaves being slaughtered.").also { stage = END_DIALOGUE } @@ -109,7 +109,7 @@ class GeneralKhazardDialogue : DialogueFile() { 4 -> npcl(FacialExpression.OLD_EVIL_LAUGH, "You however have coused me much trouble today. You must remain here so that I may at least have the pleasure of killing you myself.").also { stage++ } 5 -> { end() - setQuestStage(player!!, FightArena.FightArenaQuest, 97) + setQuestStage(player!!, Quests.FIGHT_ARENA, 97) RegionManager.getNpc(player!!.location, NPCs.GENERAL_KHAZARD_258, 15) General.attack(player!!) } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt index 5d830e076..77fd6c123 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests @Initializable @@ -16,7 +17,7 @@ class GuardsDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Fight Arena") == 100) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } } else if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } @@ -51,7 +52,7 @@ class GuardsDialogue(player: Player? = null) : DialoguePlugin(player) { class KhazardGuard254Dialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Fight Arena") == 100) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } } else if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } @@ -95,7 +96,7 @@ class KhazardGuard254Dialogue(player: Player? = null) : DialoguePlugin(player) { class KhazardGuard255Dialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Fight Arena") == 100) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } } else if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } @@ -130,7 +131,7 @@ class KhazardGuard256Dialogue(player: Player? = null) : DialoguePlugin(player) { npc = args[0] as NPC if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } - } else if (player.questRepository.getStage("Fight Arena") == 100) { + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } } else { playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 3 } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt index 8d6eccb01..bd31acf9f 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena +import content.data.Quests import content.region.kandarin.ardougne.quest.arena.cutscenes.SecondFightCutscene import core.api.* import core.game.dialogue.DialogueFile @@ -11,7 +11,7 @@ import org.rs09.consts.NPCs class HengradDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.HENGRAD_263) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { in 72..87 -> when (stage) { 0 -> { @@ -34,7 +34,7 @@ class HengradDialogue : DialogueFile() { 10 -> { end() SecondFightCutscene(player!!).start() - setQuestStage(player!!, FightArena.FightArenaQuest, 88) + setQuestStage(player!!, Quests.FIGHT_ARENA, 88) } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt index 026f61151..e92454d6f 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena +import content.data.Quests import content.region.kandarin.ardougne.quest.arena.cutscenes.EscapeCutscene import core.api.* import core.game.dialogue.DialogueFile @@ -13,7 +13,7 @@ class JeremyServilADialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.JEREMY_SERVIL_265) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { 20 -> when (stage) { 0 -> { @@ -29,7 +29,7 @@ class JeremyServilADialogue : DialogueFile() { 4 -> playerl(FacialExpression.FRIENDLY, "Don't lose heart, I'll be back.").also { stage++ } 5 -> { end() - setQuestStage(player!!, FightArena.FightArenaQuest, 40) + setQuestStage(player!!, Quests.FIGHT_ARENA, 40) } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt index 7e4260779..7f87687c2 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -12,7 +12,7 @@ class JeremyServilBDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.JEREMY_SERVIL_266) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { in 1..84 -> when (stage) { 0 -> { @@ -31,7 +31,7 @@ class JeremyServilBDialogue : DialogueFile() { 1 -> npcl(FacialExpression.FRIENDLY, "Thank you, we are truly indebted to you.").also { stage++ } 2 -> { end() - setQuestStage(player!!, FightArena.FightArenaQuest, 99) + setQuestStage(player!!, Quests.FIGHT_ARENA, 99) } } @@ -47,7 +47,7 @@ class JeremyServilBDialogue : DialogueFile() { } 2 -> { end() - setQuestStage(player!!, FightArena.FightArenaQuest, 99) + setQuestStage(player!!, Quests.FIGHT_ARENA, 99) } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt index a761d2b1e..3244d30f0 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena +import content.data.Quests import core.api.face import core.api.findNPC import core.api.getQuestStage @@ -14,7 +14,7 @@ import org.rs09.consts.NPCs class JustinServilDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.JUSTIN_SERVIL_267) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { in 1..68 -> when (stage) { 0 -> playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt index d10c13e6a..96c91c8e1 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt @@ -1,10 +1,7 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena -import core.api.addItem -import core.api.getQuestStage -import core.api.removeItem -import core.api.setQuestStage +import content.data.Quests +import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -17,14 +14,14 @@ import org.rs09.consts.NPCs class KhazardBarmanDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { npc = NPC(NPCs.KHAZARD_BARMAN_259) - when (getQuestStage(player!!, FightArena.FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { in 0..49 -> { when (stage) { 0 -> playerl(FacialExpression.HAPPY, "Hello. I'll have a beer please.").also { stage = 1 } 1 -> npcl(FacialExpression.FRIENDLY, "There you go, that's two gold coins.").also { stage = 2 } 2 -> if (removeItem(player!!, Item(COINS_995, 2))) { end() - addItem(player!!, Items.BEER_1917, 1) + addItemOrDrop(player!!, Items.BEER_1917, 1) stage = END_DIALOGUE } else { end() @@ -49,7 +46,7 @@ class KhazardBarmanDialogue : DialogueFile() { 7 -> npcl(FacialExpression.FRIENDLY, "There you go, that's five gold coins. I suggest lying down before you drink it. That way you have less distance to collapse.").also { stage = 9 } 8 -> if (removeItem(player!!, Item(COINS_995, 2))){ end() - addItem(player!!, Items.BEER_1917, 1) + addItemOrDrop(player!!, Items.BEER_1917, 1) stage = END_DIALOGUE } else { end() @@ -57,8 +54,8 @@ class KhazardBarmanDialogue : DialogueFile() { } 9 -> if (removeItem(player!!, Item(COINS_995, 5))){ end() - addItem(player!!, Items.KHALI_BREW_77, 1) - setQuestStage(player!!, FightArena.FightArenaQuest, 60) + addItemOrDrop(player!!, Items.KHALI_BREW_77, 1) + setQuestStage(player!!, Quests.FIGHT_ARENA, 60) stage = END_DIALOGUE } else { end() diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt index afaadc7fe..fc30c1ca1 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt @@ -1,6 +1,5 @@ package content.region.kandarin.ardougne.quest.arena.dialogue -import content.region.kandarin.ardougne.quest.arena.FightArena.Companion.FightArenaQuest import core.api.getQuestStage import core.api.setQuestStage import core.game.dialogue.DialoguePlugin @@ -10,17 +9,18 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import core.tools.END_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests @Initializable class LadyServilDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC playerl(FacialExpression.FRIENDLY, "Hi there, looks like you're in some trouble.") - if (player.questRepository.getStage("Fight Arena") == 10) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 10) { playerl(FacialExpression.FRIENDLY, "Hello Lady Servil.") - } else if (player.questRepository.getStage("Fight Arena") == 30) { + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 30) { playerl(FacialExpression.FRIENDLY, "Lady Servil, I have managed to infiltrate General Khazard's arena.") - } else if (player.questRepository.getStage("Fight Arena") == 70) { + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 70) { playerl(FacialExpression.FRIENDLY, "Lady Servil. I freed your son, however he has returned to the arena to help your husband.").also { stage++ } } else { playerl(FacialExpression.FRIENDLY, "Hello Lady Servil.") @@ -29,7 +29,7 @@ class LadyServilDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, FightArenaQuest)) { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { 0 -> when (stage) { 0 -> npcl(FacialExpression.SAD, "Oh I wish this broken cart was my only problem. *sob* I've got to find my family.. **sob**").also { stage++ } @@ -46,7 +46,7 @@ class LadyServilDialogue(player: Player? = null) : DialoguePlugin(player) { 8 -> playerl(FacialExpression.FRIENDLY, "I'll try my best to return your family.").also { stage++ } 9 -> { end() - setQuestStage(player!!, FightArenaQuest, 10) + setQuestStage(player!!, Quests.FIGHT_ARENA, 10) npcl(FacialExpression.SAD, "Please do. My family is wealthy and can reward you handsomely. I'll be waiting here for you.").also { stage = END_DIALOGUE } } } @@ -81,7 +81,7 @@ class LadyServilDialogue(player: Player? = null) : DialoguePlugin(player) { 2 -> npcl(FacialExpression.FRIENDLY, "All I can offer in return is material wealth. Please take these coins as a sign of my gratitude.").also { stage++ } 3 -> { end() - player!!.questRepository.getQuest("Fight Arena").finish(player) + player!!.questRepository.getQuest(Quests.FIGHT_ARENA).finish(player) } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt index d43e5589a..84382f980 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt @@ -7,16 +7,17 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import core.tools.END_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests @Initializable class LocalDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Fight Arena") == 100) { + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { npcl(FacialExpression.FRIENDLY, "Hey, you're the guy from the arena! How'd you get out?").also { stage = END_DIALOGUE } - } else if (player.questRepository.getStage("Fight Arena") in 91..99) { + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) in 91..99) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 9 } - } else if (player.questRepository.getStage("Fight Arena") >= 10) { + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 10) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 7 } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt index f61475d19..f79aefcb1 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt @@ -1,6 +1,5 @@ package content.region.kandarin.ardougne.quest.arena.npc -import content.region.kandarin.ardougne.quest.arena.FightArena import content.region.kandarin.ardougne.quest.arena.dialogue.GeneralKhazardDialogue import core.api.* import core.game.node.entity.Entity @@ -11,6 +10,7 @@ import core.game.world.GameWorld import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests @Initializable class BouncerNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { @@ -52,9 +52,8 @@ class BouncerNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, loca override fun finalizeDeath(killer: Entity?) { if (killer is Player) { - val quest = "Fight Arena" - if (getQuestStage(killer, quest) >= 89) { - setQuestStage(killer, FightArena.FightArenaQuest, 91) + if (getQuestStage(killer, Quests.FIGHT_ARENA) >= 89) { + setQuestStage(killer, Quests.FIGHT_ARENA, 91) } removeAttribute(killer, "spawn-bouncer") openDialogue(killer, GeneralKhazardDialogue()) diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt index 20e75588a..700876e14 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt @@ -1,6 +1,5 @@ package content.region.kandarin.ardougne.quest.arena.npc -import content.region.kandarin.ardougne.quest.arena.FightArena import content.region.kandarin.ardougne.quest.arena.FightArenaListeners.Companion.General import content.region.kandarin.ardougne.quest.arena.dialogue.JeremyServilBDialogue import core.api.openDialogue @@ -12,6 +11,7 @@ import core.game.node.entity.player.Player import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests @Initializable class GeneralNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { @@ -31,9 +31,8 @@ class GeneralNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, loca override fun finalizeDeath(killer: Entity?) { if (killer is Player) { - val quest = "Fight Arena" - if (getQuestStage(killer, quest) == 97) { - setQuestStage(killer, FightArena.FightArenaQuest, 98) + if (getQuestStage(killer, Quests.FIGHT_ARENA) == 97) { + setQuestStage(killer, Quests.FIGHT_ARENA, 98) } openDialogue(killer, JeremyServilBDialogue()) } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt index 51010d3e4..67e2ae7fd 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt @@ -1,6 +1,5 @@ package content.region.kandarin.ardougne.quest.arena.npc -import content.region.kandarin.ardougne.quest.arena.FightArena import content.region.kandarin.ardougne.quest.arena.dialogue.GeneralKhazardDialogue import core.api.* import core.game.node.entity.Entity @@ -11,6 +10,7 @@ import core.game.world.GameWorld import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests @Initializable class OgreNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { @@ -53,9 +53,8 @@ class OgreNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, locatio override fun finalizeDeath(killer: Entity?) { if (killer is Player) { - val quest = "Fight Arena" - if (getQuestStage(killer, quest) == 68 || getQuestStage(killer, quest) == 88) { - setQuestStage(killer, FightArena.FightArenaQuest, 72) + if (getQuestStage(killer, Quests.FIGHT_ARENA) == 68 || getQuestStage(killer, Quests.FIGHT_ARENA) == 88) { + setQuestStage(killer, Quests.FIGHT_ARENA, 72) } clearHintIcon(killer) removeAttribute(killer, "spawn-ogre") diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt index 17910e77b..164464901 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt @@ -1,6 +1,5 @@ package content.region.kandarin.ardougne.quest.arena.npc -import content.region.kandarin.ardougne.quest.arena.FightArena import content.region.kandarin.ardougne.quest.arena.dialogue.GeneralKhazardDialogue import core.api.* import core.game.node.entity.Entity @@ -11,6 +10,7 @@ import core.game.world.GameWorld import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests @Initializable class ScorpionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { @@ -52,9 +52,8 @@ class ScorpionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, loc override fun finalizeDeath(killer: Entity?) { if (killer is Player) { - val quest = "Fight Arena" - if (getQuestStage(killer, quest) == 88) { - setQuestStage(killer, FightArena.FightArenaQuest, 89) + if (getQuestStage(killer, Quests.FIGHT_ARENA) == 88) { + setQuestStage(killer, Quests.FIGHT_ARENA, 89) } removeAttribute(killer, "spawn-scorpion") openDialogue(killer, GeneralKhazardDialogue()) diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/KilronDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/KilronDialogue.kt new file mode 100644 index 000000000..83be1b46c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/KilronDialogue.kt @@ -0,0 +1,51 @@ +package content.region.kandarin.ardougne.quest.biohazard.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class KilronDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hello there.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (getQuestStage(player, Quests.BIOHAZARD) > 0){ + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Hello Kilron.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello traveller. Do you need to go back over?").also { stage++ } + 2 -> showTopics( + Topic("Not yet Kilron.", 4), + Topic("Yes I do.", 5) + ) + 4 -> npcl(FacialExpression.FRIENDLY, "Okay, just give me the word.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.FRIENDLY, "Okay, quickly now!").also { stage = END_DIALOGUE } + } + + } + else { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "How are you?").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Busy.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KILRON_349) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/MournerBossDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/MournerBossDialogue.kt new file mode 100644 index 000000000..0bad783a8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/MournerBossDialogue.kt @@ -0,0 +1,149 @@ +package content.region.kandarin.ardougne.quest.biohazard.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +/** + * For some reason the level 13 mourner upstairs is called the boss + * And despite the fact that other NPCs say there's one sick person upstairs they're 2 up there. + * + * We should be using key 423 but that got incorrectly used for Lost Tribe + */ + +@Initializable +class MournerBossDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val HOLD_BREATH = 10 + const val PRAY = 20 + const val FATAL = 30 + const val HAVE_KEY = 40 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (inEquipment(player!!, Items.DOCTORS_GOWN_430)){ + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = if (hasAnItem(player!!, Items.KEY_5010).exists()) HAVE_KEY else START_DIALOGUE + 1 } + return true + } + else { + sendDialogue("The mourner doesn't feel like talking.").also { stage = END_DIALOGUE } + return false + } + } + + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE + 1 -> npcl(FacialExpression.ASKING, "A doctor? At last! I don't know what I've eaten but I feel like I'm on death's door.").also { stage++ } + START_DIALOGUE + 2 -> playerl(FacialExpression.NEUTRAL, "Hmm... interesting, sounds like food poisoning.").also { stage++ } + // Jagex didn't include a question mark here + START_DIALOGUE + 3 -> npcl(FacialExpression.ASKING, "Yes, I'd figured that out already. What can you give me to help.").also { stage++ } + START_DIALOGUE + 4 -> showTopics( + Topic("Just hold your breath and count to ten.", HOLD_BREATH), + Topic("The best I can do is pray for you.", PRAY), + Topic("There's nothing I can do, it's fatal.", FATAL) + ) + + + HOLD_BREATH -> npcl(FacialExpression.SUSPICIOUS, "What? How will that help? What kind of doctor are you?").also { stage++ } + HOLD_BREATH + 1 -> player(FacialExpression.HALF_GUILTY, "Erm... I'm new, I just started.").also { stage++ } + HOLD_BREATH + 2 -> npcl(FacialExpression.ANGRY, "You're no doctor!").also { + stage = END_DIALOGUE + fight(player) + } + + PRAY -> npcl(FacialExpression.ANGRY, "Pray for me? You're no doctor... You're an imposter!").also { + stage = END_DIALOGUE + fight(player) + } + + FATAL -> npcl(FacialExpression.PANICKED, "No, I'm too young to die! I've never even had a girlfriend.").also { stage++ } + FATAL + 1 -> playerl(FacialExpression.SAD, "That's life for you.").also { stage++ } + FATAL + 2 -> npcl(FacialExpression.ASKING, "Wait a minute, where's your equipment?").also { stage++ } + FATAL + 3 -> playerl(FacialExpression.HALF_GUILTY, "It's erm... at home.").also { stage++ } + FATAL + 4 -> npcl(FacialExpression.ANGRY, "You're no doctor!").also { + stage = END_DIALOGUE + fight(player) + } + + HAVE_KEY -> npcl(FacialExpression.NEUTRAL, "Sorry, I'd like to be left in peace.").also { stage = END_DIALOGUE } + + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_370) + } + + private fun fight(player: Player){ + queueScript(player) { stage: Int -> + if (stage == 1){ + npc.attack(player) + return@queueScript stopExecuting(player) + } + return@queueScript delayScript(player, 1) + } + } +} + +/** + * Handles the key drop from the mourner boss + */ +@Initializable +class MournerBossNPC : AbstractNPC { + var target: Player? = null + private val supportRange: Int = 5 + + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.MOURNER_370, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return MournerBossNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_370) + } + + override fun finalizeDeath(killer: Entity?) { + val p = killer as Player + if (!hasAnItem(p, Items.KEY_5010).exists()){ + queueScript(p, 1, QueueStrength.NORMAL){ stage: Int -> + when(stage){ + 0 -> { + sendMessage(p, "You search the mourner...") + } + 2 ->{ + sendMessage(p, "and find a key.") + // If the player doesn't have space bad luck + // They can kill another mourner boss + // todo change this key and fix lost tribe key at the same time + // It should be 423 here and 5010 over there + // addItemOrDrop(p, Items.KEY_5010) + return@queueScript stopExecuting(p) + } + } + return@queueScript delayScript(p, 1) + } + } + super.finalizeDeath(killer) + } + +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt index 5d4a0dba2..c06a15558 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt @@ -1,5 +1,6 @@ package content.region.kandarin.ardougne.quest.clocktower +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -22,7 +23,7 @@ class BrotherKojoDialogueFile : DialogueFile() { } return } - when (getQuestStage(player!!, ClockTower.questName)) { + when (getQuestStage(player!!, Quests.CLOCK_TOWER)) { 0 -> { when (stage) { START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello monk.").also { stage++ } @@ -49,7 +50,7 @@ class BrotherKojoDialogueFile : DialogueFile() { 32 -> player(FacialExpression.FRIENDLY, "Well, I'll do my best.").also { stage++ } 33 -> npcl(FacialExpression.HAPPY, "Thank you again! And remember to be careful, the cellar is full of strange beasts!").also { stage = END_DIALOGUE - setQuestStage(player!!, ClockTower.questName, 1) + setQuestStage(player!!, Quests.CLOCK_TOWER, 1) } } } @@ -93,7 +94,7 @@ class BrotherKojoDialogueFile : DialogueFile() { 2 -> npcl(FacialExpression.FRIENDLY, "The townsfolk will all be able to know the correct time now! Thank you so much for all of your help! And as promised, here is your reward!").also { stage++ } 3 -> { end() - finishQuest(player!!, ClockTower.questName) + finishQuest(player!!, Quests.CLOCK_TOWER) } } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt index f5e284234..2be89b1be 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt @@ -6,14 +6,14 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * https://www.youtube.com/watch?v=Cl68Z0bsRq4 */ @Initializable -class ClockTower : Quest("Clock Tower",38, 37, 1, 10, 0, 1, 8) { +class ClockTower : Quest(Quests.CLOCK_TOWER,38, 37, 1, 10, 0, 1, 8) { companion object { - const val questName = "Clock Tower" const val attributeBlueCog = "/save:quest:clocktower-bluecogplaced" const val attributeBlackCog = "/save:quest:clocktower-blackcogplaced" const val attributeWhiteCog = "/save:quest:clocktower-whitecogplaced" diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt index 1daa7e3ed..a769bac13 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt @@ -1,5 +1,6 @@ package content.region.kandarin.ardougne.quest.clocktower +import content.data.Quests import core.api.* import core.game.global.action.DoorActionHandler import core.game.interaction.IntType @@ -47,8 +48,12 @@ class ClockTowerListener : InteractionListener { if (removeItem(player, Items.WHITE_COG_20)) { sendMessage(player, "The cog fits perfectly.") setAttribute(player, ClockTower.attributeWhiteCog, true) - if (!isQuestComplete(player, ClockTower.questName)) { - setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) } } } else { @@ -62,8 +67,12 @@ class ClockTowerListener : InteractionListener { if (removeItem(player, Items.BLACK_COG_21)) { sendMessage(player, "The cog fits perfectly.") setAttribute(player, ClockTower.attributeBlackCog, true) - if (!isQuestComplete(player, ClockTower.questName)) { - setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) } } } else { @@ -77,8 +86,12 @@ class ClockTowerListener : InteractionListener { if (removeItem(player, Items.BLUE_COG_22)) { sendMessage(player, "The cog fits perfectly.") setAttribute(player, ClockTower.attributeBlueCog, true) - if (!isQuestComplete(player, ClockTower.questName)) { - setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) } } } else { @@ -92,8 +105,12 @@ class ClockTowerListener : InteractionListener { if (removeItem(player, Items.RED_COG_23)) { sendMessage(player, "The cog fits perfectly.") setAttribute(player, ClockTower.attributeRedCog, true) - if (!isQuestComplete(player, ClockTower.questName)) { - setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) } } } else { diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/AlomoneDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/AlomoneDialogue.kt new file mode 100644 index 000000000..e6c54d22a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/AlomoneDialogue.kt @@ -0,0 +1,146 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.HAZEEL_SCROLL +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class AlomoneDialogue(player: Player? = null) : DialoguePlugin(player) { + + val hazeel = HazeelNPC(NPCs.HAZEEL_892, Location.create(2607, 9669, 0)) + + override fun handle(componentID: Int, buttonID: Int, ): Boolean { + + val questStage = getQuestStage(player, Quests.HAZEEL_CULT) + + when { + // you can't access Alomone before stage 2 + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage in 2..3) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hi there.").also { stage = 20 } + } else { + npcl(FacialExpression.ANGRY, "How did YOU get in here?").also { stage ++} + } + } + // carnillean arc + 1 -> playerl(FacialExpression.NEUTRAL, "I've come for the Carnillean family armour. Hand it over, or face the consequences.").also { stage++ } + 2 -> npcl(FacialExpression.ANNOYED, "I thought I made it clear to the butler you could not be allowed to interfere with our mission. The incompetent fool must be going soft.").also { stage++ } + 3 -> playerl(FacialExpression.NEUTRAL, "So, the butler's part of your sordid little cult, huh? Why is it ALWAYS the butler? I should have known...").also { stage++ } + 4 -> npcl(FacialExpression.ANNOYED, "Well, you won't live long enough to tell anyone! DIE!!!").also { stage++ } + 5 -> { + end() + setQuestStage(player, Quests.HAZEEL_CULT, 4) + npc!!.attack(player!!) + } + + // mahjarrat arc + 20 -> npcl(FacialExpression.NEUTRAL, "Well well well... So we have a new recruit. Clivet told me of your desire to join us in our glorious task to resurrect the mighty Hazeel from his slumber.").also { stage++ } + 21 -> npcl(FacialExpression.NEUTRAL, "To accomplish this, we require the ancient words of summoning which will restore his shattered body, so that he can bring vengeance upon his enemies.").also { stage++ } + 22 -> npcl(FacialExpression.NEUTRAL, "Hazeel in his mighty cunning anticipated that he might be defeated and secured within his home somewhere a powerful magical scroll that could restore him.").also { stage++ } + 23 -> npcl(FacialExpression.NEUTRAL, "The words to this powerful enchantment are hidden within the Carnillean mansion, right under the nose of his unsuspecting foes. We already have an agent in place there").also { stage++} + 24 -> npcl(FacialExpression.NEUTRAL, "in their Butler Jones, a faithful follower of Hazeel. His loyalty to Hazeel is beyond questioning, yet he has been unsuccessful in locating the scroll containing the spell so far.").also { stage++ } + 25 -> npcl(FacialExpression.NEUTRAL, "Go back to the mansion, and assist us in finding this enchantment, so that together we can restore Hazeel to his true power and glory!").also { stage = END_DIALOGUE}.also { setQuestStage(player, Quests.HAZEEL_CULT, 4) } + } + + // stage 4 - alomone either fought or he tells you he needs scroll + // stage 5 - either returning the armour, or finding the scroll + (questStage in 4..5 && mahjarratArc(player)) -> when (stage) { + 0 -> if(npc.id == NPCs.ALOMONE_891 && !getAttribute(player, "hazeelSpawned", false)) { + playerl(FacialExpression.NEUTRAL, "Hi.").also { stage++ } + } else { + playerl(FacialExpression.NEUTRAL, "Hi.").also { stage = 12 } + } + 1 -> npcl(FacialExpression.NEUTRAL, "Have you brought me the scroll of restoration to complete the ritual?").also { stage++ } + 2 -> if(inInventory(player, HAZEEL_SCROLL)){ + playerl(FacialExpression.NEUTRAL, "Yep. Got it right here.").also { stage++ } + } else { + playerl(FacialExpression.NEUTRAL, "No, not yet.").also { stage = END_DIALOGUE } + } + 3 -> npcl(FacialExpression.NEUTRAL, "FINALLY! Quickly, give it to me and I will begin the ritual!").also { stage++ } + 4 -> sendDialogue(player, "You hand Alomone the scroll of Hazeel.").also { stage++ } + 5 -> npcl(FacialExpression.NEUTRAL, "Yes... YES! With the words contained within this scroll our Lord shall return to this realm and bring destruction to our enemies!").also { stage++ } + 6 -> npcl(FacialExpression.NEUTRAL, "Watch adventurer, and witness the glorious rebirth of Hazeel!").also { stage++ } + 7 -> npcl(FacialExpression.NEUTRAL, "Lord Hazeel... Lord Zamorak... I call upon the powers of evil... The forces of chaos... The strength of hatred...").also { stage++ } + 8 -> npcl(FacialExpression.NEUTRAL, "Sentente sillaberi junque dithmento! Ia! Ia! dextrimon encanto! termando... imcando... solly enty rando... sentente! Ia! Ia! Indenti zaggarati g'thxa!").also { stage++ } + 9 -> sendDialogue(player, "Alomone continues to recite the scroll. It is in a language you have never heard and do not understand at all.").also { stage++ } + 10 -> npcl(FacialExpression.NEUTRAL, "Dintenta! Sententa! Retenta! Q'exjta! Ia! Sottottott! Ia! Dysmenta junque fammatio svelken! Sottey! Sentey! SOLOMENT!").also { stage++ } + 11 -> { + sendDialogue(player, "As Alomone finishes reading the scroll you hear a shrill scream emanate from Hazeel's coffin.").also { stage++ } + hazeel.init() + setAttribute(player,"hazeelSpawned", true) + player.face(hazeel) + hazeel.isWalks = false + } + 12 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "My loyal followers. I have pride in you all. Never did I expect to return to this land and I see I have much to attend to.").also { stage++ } + 13 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "Soon this world will cower once more at the name Hazeel, and my fury will blaze across mine enemies just as my loyal followers gain their rewards.").also { stage++ } + 14 -> sendDialogue(player, "Hazeel turns to look at you directly.").also{ hazeel.face(player) }.also { stage++ } + 15 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "Adventurer. I know that thy efforts were principal in my return to this plain of existence. I offer you my thanks directly.").also { stage++ } + 16 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "You may not be a follower of Zamorak directly but your cunning and treachery mark you as a friend to the Mahjarrat. Rest assured; I will call on your assistance again.").also { stage++ } + 17 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "Weak as I am now, my strength shall return, and my followers will be greatly rewarded when my powers peak once more. Join me in my cause as my servant, and all").also { stage++ } + 18 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "the riches of this plane shall be yours to share, in domination over all who oppose my kind. You would be wise to pledge yourself now while you still may.").also { stage++ } + 19 -> playerl(FacialExpression.ANGRY, "I serve nobody but myself.").also { stage++ } + 20 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "Your insolence shall be overlooked this time for I am in truth in your debt. Come close: I shall reward you with wealth such as you deserve.").also { stage++ } + 21 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "Although your true reward will be later, when Zamorak and I, together, lay waste to this miserable planet, and you are spared as an ally to us.").also { stage++ } + 22 -> sendDialogue(player, "Hazeel gives you some coins. They seem to be extremely ancient.").also { stage++ } + 23 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "And now I must leave you my loyal subjects for time is short, and I have many pressing matters to address before I make my return. I must leave now, and head Northwards").also { stage++ } + 24 -> sendNPCDialogue(player, NPCs.HAZEEL_892, "to join my fellow mahjarrat and regain my strength and powers. I shall return when I am ready to fight my enemies and much blood shall flow across these lands!").also { stage++ } + 25 -> sendDialogue(player, "The cultists let out a mighty cheer.").also { stage++ } + 26 -> { + end() + removeItem(player, HAZEEL_SCROLL) + val hazeel = player.findNpcInViewport(NPCs.HAZEEL_892) + hazeel?.clear() + removeAttribute(player,"hazeelSpawned") + finishQuest(player, Quests.HAZEEL_CULT) + } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + // also valid for stages 4 and 5 in the carnillean arc. + (questStage in 4..100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hi there.").also { stage++ } + } else { + npcl(FacialExpression.ANNOYED, "You have crossed my path too many times intruder. Leave or face my wrath.").also { stage = 2 } + } + } + 1 -> npcl(FacialExpression.NEUTRAL, "Welcome, adventurer. Know that as a friend to Hazeel, you are always welcome here.").also { stage = END_DIALOGUE } + + 2 -> playerl(FacialExpression.FRIENDLY, "Yeah, whatever.").also { stage = END_DIALOGUE } + } + } + return true + } + + // function used to find any hazeels and remove them at the end of the quest. + // this has the potential to remove other players' hazeels, but the player could still complete the quest by either continuing their + // active dialogue or speaking to alomone, and just dealing with the fact that their hazeel is not on the map. relogging and restarting + // the dialogue would get these players a new hazeel. + private fun Player.findNpcInViewport(npcId: Int): NPC? { + val viewport = viewport ?: return null + for (plane in viewport.viewingPlanes) { + for (npc in plane.npcs) { + if (npc.id == npcId) { + return npc + } + } + } + return null + } + + // Hazeel is in this array because in the event the player quits the dialogue halfway through in the final stage, it can be restarted by speaking to either alomone or hazeel. + override fun getIds(): IntArray = intArrayOf(NPCs.ALOMONE_891, NPCs.HAZEEL_892) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/AlomoneNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/AlomoneNPC.kt new file mode 100644 index 000000000..83b28833a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/AlomoneNPC.kt @@ -0,0 +1,39 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.carnilleanArc +import core.api.isQuestInProgress +import core.api.produceGroundItem +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.* + +/** + * Alomone drops the Carnillean Amour during the Hazeel Cult quest. + */ + +@Initializable +class AlomoneNPC( + id: Int = 0, + location: Location? = null, +) : AbstractNPC(id, location) { + override fun construct( + id: Int, + location: Location, + vararg objects: Any, + ): AbstractNPC = AlomoneNPC(id, location) + + override fun getIds(): IntArray = intArrayOf(NPCs.ALOMONE_891) + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + if (isQuestInProgress(killer, Quests.HAZEEL_CULT, 3, 4) && carnilleanArc(killer)) { + produceGroundItem(killer, Items.CARNILLEAN_ARMOUR_2405, 1, this.location) + } + super.finalizeDeath(killer) + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ButlerJonesDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ButlerJonesDialogue.kt new file mode 100644 index 000000000..f8bcc91d3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ButlerJonesDialogue.kt @@ -0,0 +1,80 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.getQuestStage +import core.api.inEquipmentOrInventory +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class ButlerJonesDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + + when { + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage == 3) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "Hello, adventurer. Such a terrible shame about Scruffy. I wonder if the family will ever fully recover.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Anyway, I hear your quest is going well.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Really?").also { stage++ } + 4 -> npcl(FacialExpression.ANNOYED, "Oh yes. Do keep up the good work.").also { stage = END_DIALOGUE } + } + + // stage 4 - alomone either fought or he tells you he needs scroll + (questStage == 4 && mahjarratArc(player) && inEquipmentOrInventory(player, Items.HAZEELS_MARK_2406)) -> when (stage) { + 0 -> npcl(FacialExpression.NEUTRAL, "Hello again friend. I see you have the mark now; you should keep it covered up.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "That? Oh, it's nothing. Just an old amulet.").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "You don't have to pretend with me, friend! Our cause is one and the same; the sooner Lord Hazeel is avenged the better for this city... and for us!").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "So do you have any idea where the scroll with the enchantment is?").also { stage++ } + 4 -> npcl(FacialExpression.ANNOYED, "No idea I'm afraid. I KNOW it's somewhere in this house, but for the life of me I can't find it anywhere. I've searched high and low for it!").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "And Sir Ceril doesn't suspect a thing?").also { stage++ } + 6 -> npcl(FacialExpression.ANNOYED, "Ha! That silly old fool? He can't see the forest for the trees.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "I'll keep on looking then...").also { stage = END_DIALOGUE } + } + + // stage 0 - unstarted + // stage 1 - after talking to ceril + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // stage 5 - either returning the armour, or finding the scroll + // also stage 4 if you are carnillean side + (questStage in 0..5) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello. How are you today?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Good thank you, and yourself?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Very well, thank you.").also { stage = END_DIALOGUE } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage == 100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = 1 } + } else { + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 6 } + } + } + 1 -> npcl(FacialExpression.NEUTRAL, "It's an honour to be in your presence again, adventurer. I hope things are well?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not bad, thanks. Yourself?").also { stage++ } + 3 -> npcl(FacialExpression.ANNOYED, "Unfortunately, I am still forced to deal with this insufferable family. Many generations have passed, but they are still the enemy. As such, they must be kept a close eye on.").also { stage++ } + 4 -> npcl(FacialExpression.ANNOYED, "Still, I have no doubt that the time will soon come for me to leave this place. Our lord will certainly have need of me elsewhere once his current work is complete.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "I see. Well good luck with it all.").also { stage = END_DIALOGUE } + + 6 -> npcl(FacialExpression.ANNOYED, "Why hello there.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "I take it you're the new butler...?").also { stage++ } + 8 -> npcl(FacialExpression.ANNOYED, "That's right. I hear that they had some problems with the last one.").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "Yes, you could say that...").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.BUTLER_JONES_890) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/CerilCarnilleanDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/CerilCarnilleanDialogue.kt new file mode 100644 index 000000000..083e561d5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/CerilCarnilleanDialogue.kt @@ -0,0 +1,147 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.carnilleanArc +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.fakeFinish +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class CerilCarnilleanDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + when { + // stage 0 - unstarted + (questStage == 0) -> { + when (stage) { + 0 -> npcl(FacialExpression.ANGRY, "Blooming, thieving, weirdo cultists! Why don't they leave me alone? String 'em all up, that's what I say!").also { stage++ } + 1 -> options("What's wrong?", "You probably deserve it.", "You seem uptight, I'll leave you alone.").also { stage++ } + 2 -> when (buttonID) { + 1 -> playerl(FacialExpression.HALF_ASKING, "What's wrong?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "You probably deserve it.").also { stage = 20 } + 3 -> playerl(FacialExpression.FRIENDLY, "You seem uptight, I'll leave you alone.").also { stage = 21 } + } + 3 -> npcl(FacialExpression.ANGRY, "It's those blooming cultists from the forest! Those freaks keep breaking into my house!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Have they taken much?").also { stage++ } + 5 -> npcl(FacialExpression.ANGRY, "They first broke in months ago and stole a suit of armour. The strange thing is that they've broken in four times since but taken nothing.").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "And you are...?").also { stage++ } + 7 -> npcl(FacialExpression.ANGRY, "Why, I am Sir Ceril Carnillean! We really are quite a famous bloodline... who've played a vital role in the politics of Ardougne for many generations.").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "Perhaps you would be able to assist me in returning the stolen armour? For a modest cash reward of course!").also { stage++ } + 9 -> options("Yes, of course, I'd be happy to help.", "No thanks. I've got other plans.").also { stage++ } + 10 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, of course, I'd be happy to help.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "No thanks. I've got other plans.").also { stage = 19 } + } + 11 -> npcl(FacialExpression.FRIENDLY, "That's very noble of you sirrah! I caught a glimpse of the thieves leaving but due to... uh... yeah, my cold I was unable to give chase.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "They're some kind of crazy cult who dress all in black, and hang out near the cave entrance in the forest south of here.").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "How do you know that?").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "My old butler, Higson, once followed them to their hideout there. Unfortunately the next night he died in his sleep.").also { stage++ } + 15 -> playerl(FacialExpression.FRIENDLY, "That's awful!").also { stage++ } + 16 -> npcl(FacialExpression.FRIENDLY, "No, it's okay. A replacement arrived the next day. He's been great - cooks an excellent broth!").also { stage++ } + + 17 -> playerl(FacialExpression.FRIENDLY, "Ok. I'll see what I can do.").also { stage++ } + 18 -> { + end() + setQuestStage(player, Quests.HAZEEL_CULT, 1) + } + 19 -> npcl(FacialExpression.FRIENDLY, "Well no wonder I'm the one with the big house and you're the one on the streets.").also { stage = END_DIALOGUE } + 20 -> npcl(FacialExpression.FRIENDLY, "And who are you to judge me? You look like a peasant anyway. I'm wasting my time talking to you.").also { stage = END_DIALOGUE } + 21 -> npcl(FacialExpression.FRIENDLY, "Yes, I doubt you could help anyway.").also { stage = END_DIALOGUE } + } + } + + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage == 3) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello again.").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "Oh the inhumanity... the cruelty... the misery... the pain...").also { stage++ } + 2 -> npcl(FacialExpression.ANNOYED, "My son is a good boy, really, but how could he give his dinner to Scruffy without having the servants test it for poison first? How?").also { stage++ } + 3 -> npcl(FacialExpression.ANNOYED, "How could he be so thoughtless and careless? He knows we are all under threat!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Scruffy?").also { stage++ } + 5 -> npcl(FacialExpression.ANNOYED, "He's been with our family for twenty years... that's 140 in dog years! The poor dog... What did he ever do to deserve such a fate?").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "Your dog got poisoned? That's not right.").also { stage++ } + 7 -> npcl(FacialExpression.NEUTRAL, "I agree! I hope whichever evildoer is responsible gets the full weight of the law brought upon them!").also { stage++ } + 8 -> playerl(FacialExpression.NEUTRAL, "Uh... yeah... me too.").also { stage = END_DIALOGUE } + } + + // stage 4 - alomone either fought or he tells you he needs scroll + (questStage == 4 && carnilleanArc(player) && inInventory(player, Items.CARNILLEAN_ARMOUR_2405)) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Look! I've recovered your armour!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Well done! I must say I am very impressed! Come on, hand it over.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Before we send you on your way with your payment, I'll just get Jones to whip you up a batch of his special broth.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "I'd rather not if it's all the same to you. I overheard the cultists talking, and apparently Jones is in league with them.").also { stage++ } + 4 -> { + // check if we are upstairs + if(player.location.z == 1) { + npcl(FacialExpression.ANGRY, "W-what? RIGHT! You! We're going to blooming well sort this out right now once and for all!").also { stage++ } + } else { + npcl(FacialExpression.ANGRY, "W-what? RIGHT! You! Come with me upstairs! We're going to blooming-well sort this out, once and for all!").also { stage = END_DIALOGUE } + } + } + + 5 -> npcl(FacialExpression.HALF_ASKING, "Jones! This commoner says you had something to do with the theft of my armour. What do you have to say for yourself about that?").also { stage++ } + 6 -> sendNPCDialogue(player, NPCs.BUTLER_JONES_890, "It wasn't me m'lud. I am, as you know, a loyal servant.").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "Humph. Quite right too. I cannot fathom why this scoundrel would accuse you of such a crime without evidence to back up @g[his,her] accusations.").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "Right, I have decided. I have given my word as a nobleman to reward you for your efforts in retrieving my armour.").also { stage++ } + // it is authentic that the previous line ends in a period and the next line starts with a non-capital 'but' + 9 -> npcl(FacialExpression.FRIENDLY, "but I must also compensate Jones for this terrible slander you have made against him.").also { stage++ } + 10 -> { + sendDialogue(player, "Sir Ceril gives you 5 gold. Sir Ceril gives Jones 1995 gold.") + addItemOrDrop(player, Items.COINS_995, 5) + stage++ + } + 11 -> npcl(FacialExpression.ANGRY, "Now take it and leave you scoundrel! And don't darken my doorstep again!").also { stage++ } + 12 -> sendNPCDialogue(player, NPCs.BUTLER_JONES_890, "Don't worry m'lud, this fool won't be bothering us any more.").also { stage++ } + 13 -> sendDialogue(player, "Jones smirks at you. You are going to need more than words to prove Jones' treachery.").also { stage++ } + 14 -> { + end() + removeItem(player, Items.CARNILLEAN_ARMOUR_2405) + setQuestStage(player, Quests.HAZEEL_CULT, 5) + fakeFinish(player) + } + + } + + // stage 5 - either returning the armour, or finding the scroll + (questStage == 5 && carnilleanArc(player)) -> when (stage) { + // The ceril-jones-player dialogue is continued in the listener for the wardrobe where the player finds the evidence that Jones is bad. + 0 -> npcl(FacialExpression.ANGRY, "Leave, you scoundrel! And don't darken my doorstep again!").also { stage = END_DIALOGUE } + } + + // stage 1 - after talking to ceril + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // also covers stage 4 and 5 if you're playing the mahjarrat side + (questStage in 1..99) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello, Ceril.").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "That's Sir Ceril to you, you impudent scamp. Show a bit of respect to your betters. Now, shouldn't you be recovering my armour?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Yeah yeah, I'm on it.").also { stage++ } + 3 -> npcl(FacialExpression.ANNOYED, "Good. I suggest you start with that cave south of the city, near the Clock Tower. That is where the cult is based.").also { stage = END_DIALOGUE } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage == 100) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello, Ceril.").also { stage++ } + 1 -> { + if (mahjarratArc(player)) { + npcl(FacialExpression.FRIENDLY, "Oh... I may be wrong... but ever since I asked for your help, things around here have gone from bad to worse...").also { stage = 3 } + } else { + npcl(FacialExpression.FRIENDLY, "Well hello again adventurer! It's good to see you again! If it wasn't for your quick thinking the treacherous Jones would have poisoned my family and me by now! We are in your debt.").also { stage = 2 } + } + } + 2 -> playerl(FacialExpression.FRIENDLY, "Don't worry about it, a good deed is its own reward. And that 2000 gold didn't hurt either.").also { stage = END_DIALOGUE } + + 3 -> npcl(FacialExpression.NEUTRAL, "I think you'd better keep out of my way. And for the last time, it's Sir Ceril! Sir! It's not that hard to blooming remember!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.CERIL_CARNILLEAN_885) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClausTheChefDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClausTheChefDialogue.kt new file mode 100644 index 000000000..2680171c3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClausTheChefDialogue.kt @@ -0,0 +1,56 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class ClausTheChefDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + when { + + // stage 0 - unstarted + // stage 1 - after talking to ceril + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // stage 3 - poison poured in food (mahjarrat-only stage) + // stage 4 - alomone either fought or he tells you he needs scroll + // stage 5 - either returning the armour, or finding the scroll + (questStage in 0..99) -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Sorry, can't stop to chat! You would be amazed at how many meals this family gets through daily!").also { stage = END_DIALOGUE } + } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage == 100) -> { + when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hey.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "Hiya.").also { stage = 2 } + } + } + 1 -> npcl(FacialExpression.NEUTRAL, "Oh, hello there. Sorry, but I can't really talk right now. Things haven't been great here recently, and I have a lot of work to do.").also { stage = END_DIALOGUE } + + 2 -> npcl(FacialExpression.HALF_ASKING, "Well hello there adventurer! Are we fit and well?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Yep, fine thanks.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "Glad to hear it.").also { stage = END_DIALOGUE } + } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.CLAUS_THE_CHEF_886) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClivetDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClivetDialogue.kt new file mode 100644 index 000000000..34409ef83 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClivetDialogue.kt @@ -0,0 +1,162 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrCarnillean +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrHazeel +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class ClivetDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int, ): Boolean { + + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + + when { + // stage 0 - unstarted + (questStage == 0) -> when (stage) { + 0 -> npcl(FacialExpression.ANNOYED, "What do you want traveller?").also { stage++ } + 1 -> playerl(FacialExpression.ANNOYED, "Just passing by.").also { stage++ } + 2 -> npcl(FacialExpression.ANNOYED, "You have no business here.").also { stage++ } + 3 -> npcl(FacialExpression.ANGRY, "Leave...now").also { stage = END_DIALOGUE } + } + + // stage 1 - after talking to ceril + (questStage == 1) -> when (stage) { + 0 -> playerl(FacialExpression.ANNOYED, "Do you know the Carnilleans?").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "You mind your business, I'll mind mine.").also { stage++ } + 2 -> playerl(FacialExpression.ANNOYED, "Look I KNOW you're hiding something. I've heard there's a cult hideout down here.").also { stage++ } + 3 -> npcl(FacialExpression.ANGRY, "If you want to stay healthy you'll leave now.").also { stage++ } + 4 -> playerl(FacialExpression.ANNOYED, "I have my orders.").also { stage++ } + 5 -> npcl(FacialExpression.HALF_ASKING, "So... that two faced cold hearted snob has made you fall for his propaganda eh?").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "Sir Ceril Carnillean is a man of honour!").also { stage++ } + 7 -> npcl(FacialExpression.ANNOYED, "Is he now? Is he REALLY? There is a lot more to the Carnilleans than meets the eye you fool...").also { stage++ } + 8 -> npcl(FacialExpression.ANNOYED, "And none of it is honourable.").also { stage++ } + 9 -> options("What do you mean?", "I've heard enough of your rubbish.").also { stage++ } + 10 -> when (buttonID) { + 1 -> playerl(FacialExpression.HALF_ASKING, "What do you mean?").also { stage++ } + 2 -> playerl(FacialExpression.ANNOYED, "I've heard enough of your rubbish.").also { stage = 22 } + } + 11 -> npcl(FacialExpression.ANNOYED, "The Carnillean home does not belong to them. The builder of the house was Lord Hazeel, one of the Mahjarrat followers of Zamorak. Many years ago there was a civil war").also { stage++ } + 12 -> npcl(FacialExpression.ANNOYED, "in this land, and the hateful Saradominists declared war upon all Zamorakians who lived here. Lord Hazeel nobly would not repent his beliefs, and the Carnilleans harassed").also { stage++ } + 13 -> npcl(FacialExpression.ANNOYED, "Hazeel and his followers for many decades. One fateful night, under cover of darkness, they stormed his home in an angry mob torturing and butchering all loyal").also { stage++ } + 14 -> npcl(FacialExpression.ANNOYED, "Zamorakians they encountered inside. The following morning, the Carnillean forefathers moved into the empty household and claimed it as their own.").also { stage++ } + 15 -> npcl(FacialExpression.ANNOYED, "They have grown fat on the hard work of Lord Hazeel ever since. Unluckily for them Lord Hazeel as a Mahjarrat had access to powers and enchantments they knew nothing").also { stage++ } + 16 -> npcl(FacialExpression.ANNOYED, "about, and made preparations for his return when first they began to storm his home. Soon the day will come when he will return to wreak his vengeance upon the thieves!").also { stage++ } + 17 -> playerl(FacialExpression.ANNOYED, "The politics and histories of Ardougne do not concern me. I have been given a job and intend to see it through to the end.").also { stage++ } + 18 -> npcl(FacialExpression.ANNOYED, "Well then friend, perhaps I can offer you a different job then? Sooner as later Our master WILL return to this land; those faithful to him will be well rewarded.").also { stage++ } + 19 -> npcl(FacialExpression.ANNOYED, "Join our cult and assist us in his restoration, and you will be well rewarded; try and prevent his return and suffer the wrath of Zamorak and the Mahjarrat.").also { stage++ } + 20 -> options("You're crazy, I'd never help you.", "So what would I have to do?").also { stage++ } + 21 -> when (buttonID) { + 1 -> playerl(FacialExpression.DISGUSTED_HEAD_SHAKE, "You're crazy, I'd never help you.").also { stage++ } + 2 -> playerl(FacialExpression.HALF_ASKING, "So what would I have to do?").also { stage = 40 } + } + + // SET CARNILLEAN ARC + 22 -> npcl(FacialExpression.ANNOYED, "Then you are a fool. Go back to your small minded mundane little life; you will never know the glories you could have tasted as one of us!").also { stage++ } + 23 -> { + end() + setAttribute(player, attrCarnillean, true) + setQuestStage(player, Quests.HAZEEL_CULT, 2) + runTask(player, 1) { + npc.isInvisible = true + sendDialogue(player, "The man jumps onto the raft and pushes off down into the sewer system.") + sendMessage(player, "Clivet: You'll never find us...") + stage = END_DIALOGUE + } + } + + // SET MAHJARRAT ARC + 40 -> npcl(FacialExpression.NEUTRAL, "You must prove your loyalty to our cause. Killing one of the Carnillean household should be sufficient proof of your dedication to resurrecting our master Lord Hazeel.").also { stage++ } + 41 -> npcl(FacialExpression.NEUTRAL, "So what say you adventurer? Join our side against the Carnillean thieves?").also { stage++ } + 42 -> options("No. I won't do it.", "Ok, count me in.").also { stage++ } + 43 -> when (buttonID) { + 1 -> playerl(FacialExpression.DISGUSTED_HEAD_SHAKE, "No. I won't do it.").also { stage = 22 } + 2 -> playerl(FacialExpression.NEUTRAL, "Ok, count me in.").also { stage++ } + } + 44 -> npcl(FacialExpression.NEUTRAL, "Excellent. It takes a rare character to see through the cursed Carnillean lies. I can see you are a person of exactly the right character to join the followers of Hazeel.").also { stage++ } + 45 -> npcl(FacialExpression.NEUTRAL, "Here, take this poison. Pour it into their food, and once the deed is done, return here and speak to me once more.").also { stage++ } + 46 -> { + end() + setAttribute(player, attrHazeel, true) + setQuestStage(player, Quests.HAZEEL_CULT, 2) + addItemOrDrop(player, Items.POISON_273) + } + } + + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + (questStage == 2) -> when (stage) { + 0 -> { + if (mahjarratArc(player) && !inInventory(player, Items.POISON_273)) { + playerl(FacialExpression.FRIENDLY, "I need some more poison.").also { stage++ } + } else if (mahjarratArc(player) && inInventory(player, Items.POISON_273)){ + npcl(FacialExpression.FRIENDLY, "You have a mission for us, adventurer. Go to the Carnilliean household and poison Ceril Carnillean's meal to prove your loyalty.").also { stage = END_DIALOGUE } + } else { + playerl(FacialExpression.HALF_ASKING, "WHERE is the cult hideout?").also { stage = 3 } + } + } + 1 -> npcl(FacialExpression.ANNOYED, "Fool! Be more careful with it this time.").also { stage++ } + 2 -> { + end() + addItemOrDrop(player, Items.POISON_273) + } + 3 -> npcl(FacialExpression.ANNOYED, "You're more of a fool than you look if you think you will ever find it. When Lord Hazeel is revived you will be the first to grovel for his mercy!").also { stage = END_DIALOGUE } + } + + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage == 3 && mahjarratArc(player)) -> when (stage) { + 0 -> { + if (!inEquipmentOrInventory(player, Items.HAZEELS_MARK_2406)) { + playerl(FacialExpression.FRIENDLY, "I poured the poison into the Carnillean's meal as requested. It didn't quite go to plan however.").also { stage++ } + } else { + playerl(FacialExpression.HALF_ASKING, "What was I supposed to do again?").also { stage = 6 } + } + } + 1 -> npcl(FacialExpression.NEUTRAL, "Yes, we heard all about it from one of our sources. Hazeel has eyes everywhere! You have now proved your loyalty and will be rewarded when Hazeel is revived!").also { stage++ } + 2 -> playerl(FacialExpression.HALF_ASKING, "Ok. So what's next?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Here. Wear this amulet; it is called The Sign of Hazeel. Not only will it identify you as one of our brotherhood to other followers but it is also the key to finding our hideout.").also { addItemOrDrop(player, Items.HAZEELS_MARK_2406) }.also { stage++ } + 4 -> playerl(FacialExpression.NEUTRAL, "How does this amulet help do that then?").also { stage++ } + 5 -> npcl(FacialExpression.NEUTRAL, "Hazeel in his wisdom when he built this lair did so by making it inaccessible unless the flow of the sewers is controlled exactly by the sewer valves above ground.").also { stage++ } + 6 -> npcl(FacialExpression.NEUTRAL, "Each sewer valve must be correctly set before the water level is such that you may enter. The secret of the correct settings is contained in these amulets which honour him.").also { stage++ } + 7 -> npcl(FacialExpression.NEUTRAL, "Starting from left to right, follow the design of the amulet to locate each sewer valve, and then turn each so as to follow the amulet design.").also { stage++ } + 8 -> npcl(FacialExpression.NEUTRAL, "When you solve the sequence you may enter our hideout where our leader, Alomone, awaits you.").also { stage = END_DIALOGUE } + } + + // stage 4 - alomone either fought or he tells you he needs scroll + // stage 5 - either returning the armour, or finding the scroll + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage in 4..100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 4 } + } + } + 1 -> npcl(FacialExpression.FRIENDLY, "It is good to see you once more, adventurer. Glory to Hazeel!").also { stage++ } + 2 -> { + // if player doesn't have hazeel's mark they can get a new copy. + if (hasAnItem(player, Items.HAZEELS_MARK_2406).container == null) { + playerl(FacialExpression.FRIENDLY, "I've lost my Mark of Hazeel.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "Glory to Hazeel!").also { stage = END_DIALOGUE } + } + } + 3 -> npcl(FacialExpression.ANNOYED, "Here, take this.").also { addItemOrDrop(player, Items.HAZEELS_MARK_2406) }.also { stage = END_DIALOGUE } + + 4 -> npcl(FacialExpression.ANNOYED, "You may have won this battle meddler, but the war rages on. Go bother some goblins or something, for when Hazeel returns your destruction is assured.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.CLIVET_893) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClivetNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClivetNPC.kt new file mode 100644 index 000000000..c33424281 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/ClivetNPC.kt @@ -0,0 +1,35 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.* + +/** + * Clivet disappears briefly during the Hazeel Cult quest. + */ + +@Initializable +class ClivetNPC(id: Int = 0, location: Location? = null, ) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any, ): AbstractNPC = ClivetNPC(id, location) + + override fun getIds(): IntArray = intArrayOf(NPCs.CLIVET_893) + + private var invisTicks = 0 + + override fun tick() { + if (isInvisible && invisTicks <= 0) { + invisTicks = 20 + } + + if (invisTicks > 0) { + invisTicks-- + + if (invisTicks == 0) { + isInvisible = false + } + } + + super.tick() + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/GuardHCDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/GuardHCDialogue.kt new file mode 100644 index 000000000..c3e8fd224 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/GuardHCDialogue.kt @@ -0,0 +1,74 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class GuardHCDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + + when { + // stage 0 - unstarted + (questStage == 0) -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello. If you've come to admire the Carnillean family home, I must warn you not to cause any trouble.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Due to recent criminal activities against such a prominent member of Ardougnian politics, I have been sent here on special guard duty to ensure the Carnilleans' security.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Anyone caught interfering with the person or possessions of said Carnilleans will be taken to jail so quickly that their feet won't touch the floor!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Well, I wasn't actually planning on doing anything like that...").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "Glad to hear it. Let's keep it that way, hmmm?").also { stage = END_DIALOGUE } + } + } + + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage == 3) -> { + when (stage) { + 0 -> npcl(FacialExpression.SAD, "Today is a dark day. Those cultists have been back, and this time they've gone further than ever before! Murder! We can't afford to keep letting them get away with this.").also { stage = END_DIALOGUE } + } + } + + // stage 1 - after talking to ceril + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // stage 4 - alomone either fought or he tells you he needs scroll + // stage 5 - either returning the armour, or finding the scroll + (questStage in 1..99) -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello there. I hear you're after that cult who broke in the other night. It always gladdens me when civilians assist the law like this.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm just happy to be of help.").also { stage = END_DIALOGUE } + } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage == 100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 1 } + } else { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 6 } + } + } + 1 -> npcl(FacialExpression.NEUTRAL, "Hello, adventurer. It's a shame you never found that cult. We have a horrible suspicion that there's been another burglary.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "That's worrying.").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Yes, it is. The thing is, we can't even work out what they've taken! It's all very odd.").also { stage++ } + 4 -> playerl(FacialExpression.HALF_ASKING, "Is there anything more I can do to help?").also { stage++ } + 5 -> npcl(FacialExpression.NEUTRAL, "I don't think so. Sir Ceril says you've done enough.").also { stage = END_DIALOGUE } + + 6 -> npcl(FacialExpression.ANNOYED, "Well well well... if it isn't our very own local hero. Good to see you managed to clear your name. I always had faith in you!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.GUARD_887) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCult.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCult.kt new file mode 100644 index 000000000..c0d0dfa27 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCult.kt @@ -0,0 +1,198 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.HAZEEL_CULT_VARP +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrCarnillean +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrHazeel +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrSewer1R +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrSewer2R +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrSewer3L +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrSewer4R +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCultListeners.Companion.attrSewer5R +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/* HAZEEL CULT + * + * Primary video source: https://www.youtube.com/watch?v=hFBJx_xERQ4 (carnillean playthrough) + * Primary video source: https://www.youtube.com/watch?v=ZYPB823IyRk (mahjarrat playthrough) + * https://web.archive.org/web/20081217064620/http://runescape.salmoneus.net/quests/HazeelCult.html + * https://web.archive.org/web/20090121182721/http://runehq.com/guide.php?type=quest&id=00297 + * https://runescape.wiki/w/Hazeel_Cult?oldid=815270 + * + * Varp 223 - Hazeel Cult progress + * https://chisel.weirdgloop.org/varbs/display?varplayer=223 + * Values Stage Description + * 0 0 unstarted + * 2 1 after talking to ceril + * 3 2 talk to clivet (set attr for carnillean) + * 4 2 talk to clivet (set attr for mahjarrat) + * 5 3 poison poured in food (mahjarrat-only stage) + * 6 4 alomone either fought or he tells you he needs scroll + * 7 5 either returning the armour, or finding the scroll + * 9 100 quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + * + * The varp values just appear to track quest stages, so I don't update the varp at intermediate quest stages. + * + * Good source of half the quest log: https://youtu.be/Kf95y-YdviA?si=kWeA-8oa-22TttE4&t=140 + * + * Original framework of the quest and about half the dialogue is credit to szumaster. + * + */ + +@Initializable +class HazeelCult : Quest(Quests.HAZEEL_CULT, 74, 73, 1, HAZEEL_CULT_VARP, 0, 1, 9) { + + // These functions are used at various points to check whether the player is following the Carnillean's side, or Hazeel's. + companion object { + fun carnilleanArc(player: Player) : Boolean { + return (!getAttribute(player, attrHazeel, false) && getAttribute(player, attrCarnillean, false)) + } + + fun mahjarratArc(player: Player) : Boolean { + return (getAttribute(player, attrHazeel, false) && !getAttribute(player, attrCarnillean, false)) + } + + // the fake ending where you don't prove Jones guilty yet. lol. + fun fakeFinish(player: Player) { + openInterface(player, 277) + + player.packetDispatch.sendString("" + player.getQuestRepository().getPoints() + "", 277, 7) + player.packetDispatch.sendString("You have... kind of... completed the Hazeel Cult Quest!", 277, 4) + + player.packetDispatch.sendItemZoomOnInterface(Items.COINS_995, 230, 277, 5) + + player.packetDispatch.sendString("5 coins", 277, 10) + player.packetDispatch.sendString("", 277, 11) + player.packetDispatch.sendString("", 277, 12) + player.packetDispatch.sendString("", 277, 13) + player.packetDispatch.sendString("", 277, 14) + player.packetDispatch.sendString("", 277, 15) + player.packetDispatch.sendString("", 277, 16) + player.packetDispatch.sendString("", 277, 17) + } + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + + val attributeMahjarrat = mahjarratArc(player) + val attributeCarnillean = carnilleanArc(player) + + if (stage >= 0) { + line(player, "I can start the quest by talking to !!Sir Ceril Carnillean?? at", line++, stage >= 1) + line(player, "the house due !!West?? of !!Ardougne Zoo??.", line++, stage >= 1) + line++ + } + if (stage >= 1) { + line(player, "I spoke to !!Sir Ceril Carnillean?? at his house and agreed to", line++, stage >= 2) + line(player, "help him !!investigate?? the theft of a !!family heirloom??.", line++, stage >= 2) + line++ + } + if (stage >= 2) { + line(player, "I found a !!member of the cult?? called !!Clivet?? at the entrance", line++, stage >= 3) + line(player, "to the !!cult's hideout??, south of !!Ardougne??.", line++, stage >= 3) + line++ + } + + /* --------------- * + * HAZEEL SIDE + * --------------- */ + if (stage >= 3 && attributeMahjarrat && !attributeCarnillean) { + line(player, "Having decided to assist the cult in their mission to revive !!Hazeel??,", line++, stage >= 4) + line(player, "I tried to !!poison?? the !!Carnilleans?? but instead", line++, stage >= 4) + line(player, "only managed to kill their pet dog.", line++, stage >= 4) + line++ + } + if (stage >= 4 && attributeMahjarrat && !attributeCarnillean) { + line(player, "I spoke to !!Clivet?? and he told me that I had failed,", line++, stage >= 5) + line(player, "but he gave me an !!amulet?? anyway.", line++, stage >= 5) + line(player, "Then I managed to take the sewer rafts to the cult hideout.", line++, stage >= 5) + line++ + } + if (stage >= 5 && attributeMahjarrat && !attributeCarnillean) { + line(player, "I found the scroll needed to revive !!Hazeel?? in a", line++, stage >= 100) + line(player, "secret compartment upstairs at the !!Carnillean Mansion??.", line++, stage >= 100) + line++ + } + if (stage == 100 && attributeMahjarrat && !attributeCarnillean) { + line(player, "I gave !!Alomone?? the scroll from the !!Carnillean Mansion?? and", line++, true) + line(player, "helped perform the revivification of !!Hazeel??.", line++, true) + line(player, "I was rewarded for all of my help", line++, true) + line(player, "in returning !!Hazeel?? to his followers.", line++, true) + line++ + } + + /* --------------- * + * CARNILLEAN SIDE + * --------------- */ + if (stage >= 2 && attributeCarnillean && !attributeMahjarrat) { + line(player, "He told me a pack of lies about the !!Carnilleans??,", line++, stage >= 4) + line(player, "then asked me to join the !!cult??. Obviously, I refused.", line++, stage >= 4) + line(player, "I was still no closer to recovering the !!missing armour??.", line++, stage >= 4) + line(player, "After speaking to him, he jumped onto a !!raft?? and headed", line++, stage >= 4) + line(player, "into the !!sewer system??. I need to find a way to follow", line++, stage >= 4) + line++ + } + if (stage >= 4 && attributeCarnillean && !attributeMahjarrat) { + line(player, "I managed to enter !!the hideout??, kill the !!cult leader?? and", line++, stage >= 5) + line(player, "retrieve !!the armour??. I discovered that !!Jones the Butler??", line++, stage >= 5) + line(player, "was secretly a !!member of the cult?? and a !!traitor??.", line++, stage >= 5) + line++ + } + // this stage displays a 'fake' quest ending! + // https://youtu.be/hFBJx_xERQ4?si=ft_1rZGKAHpDjind&t=648 + if (stage >= 5 && attributeCarnillean && !attributeMahjarrat) { + line(player, "I returned !!the armour??, but !!Ceril?? didn't believe !!Jones was involved??", line++, stage >= 100) + line(player, "with the cult and was responsible for the theft.", line++, stage >= 100) + line++ + } + if (stage == 100 && attributeCarnillean && !attributeMahjarrat) { + line(player, "I found undeniable evidence that the !!Butler?? was", line++, true) + line(player, "involved with the cult and gave it to !!Ceril??.", line++, true) + line(player, "My name was cleared and", line++, true) + line(player, "I graciously accepted the reward for all of my help.", line++, true) + line++ + } + + /* --------------- * + * QUEST COMPLETE + * --------------- */ + if (stage == 100) { + line(player, "QUEST COMPLETE!", line, false) + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendItemZoomOnInterface(Items.COINS_995, 230, 277, 5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "2,000 Coins", ln++) + drawReward(player, "1,500 Thieving XP", ln) + + rewardXP(player, Skills.THIEVING, 1500.0) + addItemOrDrop(player, Items.COINS_995, 2000) + + // no attributes need removing on quest completion. the sewer valves are not saved, and which quest arc you chose affects the quest journal and post-quest dialogue. + } + + // use ::setqueststage 74 0 to reset quest. + override fun reset(player: Player) { + removeAttribute(player, attrSewer1R) + removeAttribute(player, attrSewer2R) + removeAttribute(player, attrSewer3L) + removeAttribute(player, attrSewer4R) + removeAttribute(player, attrSewer5R) + removeAttribute(player, attrHazeel) + removeAttribute(player, attrCarnillean) + } + + override fun newInstance(`object`: Any?): Quest = this +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCultListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCultListeners.kt new file mode 100644 index 000000000..cd6ac6007 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCultListeners.kt @@ -0,0 +1,266 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.carnilleanArc +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.* + +class HazeelCultListeners : InteractionListener { + + override fun defineListeners() { + on(CLIVET_STAIRS, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, location(2586, 3237, 0)) + sendMessage(player, "You climb up the stairs.") + return@on true + } + + on(CAVE_ENTRANCE, IntType.SCENERY, "enter") { player, _ -> + teleport(player, location(2570, 9682, 0)) + sendMessage(player, "You enter the cave.") + return@on true + } + + on(CLIVET_RAFT, IntType.SCENERY, "board") { player, node -> + // to use the raft, you must also be at either + // Carnillean Arc Stage 2 or greater, + // Mahjarrat Arc Stage 3 with Hazeel's Mark, + // Mahjarrat Arc Stage 4 or greater + val questStage = getQuestStage(player, Quests.HAZEEL_CULT) + val questReq = if( + (carnilleanArc(player) && questStage >= 2) || + (mahjarratArc(player) && inEquipmentOrInventory(player, Items.HAZEELS_MARK_2406) && questStage >= 3) || + (mahjarratArc(player) && questStage >= 4) + ) {true} else false + val raftUnlock = if( + getAttribute(player, attrSewer1R, false) && + getAttribute(player, attrSewer2R, false) && + getAttribute(player, attrSewer3L, false) && + getAttribute(player, attrSewer4R, false) && + getAttribute(player, attrSewer5R, false) && + questReq + ) {true} else false + + + // check which raft this is. + val x = node.location.x + + if (x == 2567) { // raft to cultists. only use if you've turned the valves. + if (!raftUnlock) { + sendNPCDialogue(player, CLIVET_NPC, "Hey! I don't remember saying you could use that raft!", FacialExpression.ANNOYED) + } else { + teleport(player, location(2606, 9692, 0)) + sendDialogue(player, "The raft washes up the sewer, past the islands until it reaches the end of the sewer passage.") + } + } else { // raft away from cultists. no check on this one since the valve attributes aren't saved. + teleport(player, location(2567, 9680, 0)) + sendDialogue(player, "The raft flows back to the cave entrance.") + } + return@on true + } + + /* + * Valve 1 - This is right across the bridge south of the Carnilleans' house. Turn it right. + * Valve 2 - This is right behind Carnilleans' house. Turn it right. + * Valve 3 - This is north of the cave. Turn it left. + * Valve 4 - This is south of the zoo's penguin cage. Turn it right. + * Valve 5 - Go southeast of the fourth valve, past the monk. Turn it right. + * + * All 4 of the below sources turn the valves in different orders. Text quest guides make no mention of needing a specific order, + * even though Clivet's bad-side dialogue makes it seem like it. For this implementation, the player needs to set each valve in the + * correct direction, order of the valves does not matter. + * + * Bad side - turns in order: https://www.youtube.com/watch?v=ZYPB823IyRk + * Good side - turns out of order: https://www.youtube.com/watch?v=OuEvnA6Cyrw + * Good side - turns out of order: https://www.youtube.com/watch?v=JG7E3uVx4rs + * Bad side - turns out of order: https://www.youtube.com/watch?v=T8JyyhDEVSg + * + * I allow the valve attributes to be set even if quest is unstarted, but getting on the raft checks the quest stage. + */ + + // valves 1, 2, 4, 5 should be turned right + on(SEWERS, IntType.SCENERY, "turn-right") { player, node -> + if (!player.location.withinDistance(node.asScenery().location, 2)) return@on true + + val currentSewer = node.id + when (currentSewer) { + SEWER_1 -> setAttribute(player, attrSewer1R, true) + SEWER_2 -> setAttribute(player, attrSewer2R, true) + SEWER_3 -> removeAttribute(player, attrSewer3L) + SEWER_4 -> setAttribute(player, attrSewer4R, true) + SEWER_5 -> setAttribute(player, attrSewer5R, true) + } + + lock(player, 4) + animate(player, TURN_VALVE_ANIMATION) + sendDialogueLines(player, "You turn the large metal valve to the right. Beneath your feet you", "can hear the sudden sound of rushing water from the sewer.") + return@on true + } + + // valve 3 should be turned left + on(SEWERS, IntType.SCENERY, "turn-left") { player, node -> + if (!player.location.withinDistance(node.asScenery().location, 2)) return@on true + + val currentSewer = node.id + when (currentSewer) { + SEWER_1 -> removeAttribute(player, attrSewer1R) + SEWER_2 -> removeAttribute(player, attrSewer2R) + SEWER_3 -> setAttribute(player, attrSewer3L, true) + SEWER_4 -> removeAttribute(player, attrSewer4R) + SEWER_5 -> removeAttribute(player, attrSewer5R) + } + + lock(player, 4) + animate(player, TURN_VALVE_ANIMATION) + sendDialogueLines(player, "You turn the large metal valve to the left. Beneath your feet you", "can hear the sudden sound of rushing water from the sewer.") + return@on true + } + + // this wardrobe contains some poison and an amulet, used to convince ceril that jones is a baddie + on(WARDROBE, IntType.SCENERY, "search") { player, _ -> + openDialogue(player, WardrobeRevealDialogueFile()) + return@on true + } + + // siding with Hazeel and trying to poison the Carnilleans + onUseWith(IntType.SCENERY, POISON, COOKING_RANGE) { player, _, _ -> + if (mahjarratArc(player) && removeItem(player, POISON)) { + sendDialogueLines(player, "You pour the poison into the hot pot.", "The poison dissolves into the soup.") + setQuestStage(player, Quests.HAZEEL_CULT, 3) + } else { + sendNPCDialogue(player, NPCs.CLAUS_THE_CHEF_886, "Oi - I don't want people messing around with my range!") + } + return@onUseWith true + } + + // crate in the basement. they key can only be obtained in the mahjarrat arc, which locks the secret passage, chest, and hazeel scroll to that arc as well. + on(CRATE, IntType.SCENERY, "search") { player, _ -> + if (getQuestStage(player, Quests.HAZEEL_CULT) >= 1 && + mahjarratArc(player) && + !inInventory(player, CHEST_KEY) + ) { + sendDialogue(player, "You search the crate. Under various food packages you find an old rusty key.") + addItemOrDrop(player, CHEST_KEY, 1) + } else { + sendMessage(player, "You search the crate but find nothing.") + } + return@on true + } + + // secret wall on the way up to retrieve the hazeel scroll + on(SECRET_PASSAGE, IntType.SCENERY, "Knock-at") { player, node -> + if (inInventory(player, CHEST_KEY) && player.location.y == 3274) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "There is something odd about the wall here.") + sendMessage(player, "You find a secret passageway") + } else if (player.location.y == 3275) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "Nothing interesting happens.") + } + return@on true + } + + // chest with hazeel scroll. unlocks with key, opens, and contains the scroll. + on(Scenery.CHEST_2856, IntType.SCENERY, "Open") { player, _ -> + sendMessage(player, "This chest is locked shut.") + return@on true + } + + // chest with hazeel scroll. unlocks with key, opens, and contains the scroll. + onUseWith(IntType.SCENERY, CHEST_KEY, Scenery.CHEST_2856) { player, _, _ -> + sendMessage(player, "You unlock the chest.") + animate(player, Animations.HUMAN_OPEN_CHEST_536) + addScenery(Scenery.CHEST_2857,CHEST_LOCATION, 2, 10) + removeScenery(core.game.node.scenery.Scenery(Scenery.CHEST_2856, Location(2565, 3272, 2))) + return@onUseWith true + } + + // chest with hazeel scroll. unlocks with key, opens, and contains the scroll. + on(Scenery.CHEST_2857, IntType.SCENERY, "Close") { _, _ -> + addScenery(Scenery.CHEST_2856, CHEST_LOCATION, 2, 10) + removeScenery(core.game.node.scenery.Scenery(Scenery.CHEST_2857, CHEST_LOCATION)) + return@on true + } + + // chest with hazeel scroll. unlocks with key, opens, and contains the scroll. + on(Scenery.CHEST_2857, IntType.SCENERY, "Search") { player, _ -> + val hasScroll = hasAnItem(player, HAZEEL_SCROLL).container != null + if (hasScroll) { + sendDialogue(player, "You already have the scroll from this chest.") + return@on true + } + addItemOrDrop(player, HAZEEL_SCROLL, 1) + sendItemDialogue(player, HAZEEL_SCROLL, "Inside the chest you find the Scroll of Hazeel.") + setQuestStage(player, Quests.HAZEEL_CULT, 5) + return@on true + } + } + + // interact locations for the sewer valves + override fun defineDestinationOverrides() { + setDest(IntType.SCENERY, intArrayOf(SEWER_1), "turn-right", "turn-left") { _, _ -> + return@setDest Location.create(2563, 3246, 0) + } + setDest(IntType.SCENERY, intArrayOf(SEWER_2), "turn-right", "turn-left") { _, _ -> + return@setDest Location.create(2571, 3263, 0) + } + setDest(IntType.SCENERY, intArrayOf(SEWER_3), "turn-right", "turn-left") { _, _ -> + return@setDest Location.create(2586, 3244, 0) + } + setDest(IntType.SCENERY, intArrayOf(SEWER_4), "turn-right", "turn-left") { _, _ -> + return@setDest Location.create(2597, 3262, 0) + } + setDest(IntType.SCENERY, intArrayOf(SEWER_5), "turn-right", "turn-left") { _, _ -> + return@setDest Location.create(2610, 3242, 0) + } + + } + + companion object { + const val HAZEEL_CULT_VARP = 223 + + const val attrSewer1R = "quest:hazeelcult-sewer1" + const val attrSewer2R = "quest:hazeelcult-sewer2" + const val attrSewer3L = "quest:hazeelcult-sewer3" + const val attrSewer4R = "quest:hazeelcult-sewer4" + const val attrSewer5R = "quest:hazeelcult-sewer5" + + const val attrHazeel = "/save:quest:hazeelcult-hazeel" // true when you agree to help Clivet + const val attrCarnillean = "/save:quest:hazeelcult-carnillean" // true when you DON'T agree to help Clivet + + const val CLIVET_NPC = NPCs.CLIVET_893 + const val CLIVET_RAFT = Scenery.RAFT_2849 + + const val CAVE_ENTRANCE = Scenery.CAVE_ENTRANCE_2852 + const val CLIVET_STAIRS = Scenery.STAIRS_2853 + + const val HAZEEL_SCROLL = Items.HAZEEL_SCROLL_2403 + + const val SEWER_1 = Scenery.SEWER_VALVE_2844 // Valve 1 - This is right across the bridge south of the Carnilleans' house. Turn it right. + const val SEWER_2 = Scenery.SEWER_VALVE_2845 // Valve 2 - This is right behind Carnilleans' house. Turn it right. + const val SEWER_3 = Scenery.SEWER_VALVE_2846 // Valve 3 - This is north of the cave. Turn it left. + const val SEWER_4 = Scenery.SEWER_VALVE_2847 // Valve 4 - This is south of the zoo's penguin cage. Turn it right. + const val SEWER_5 = Scenery.SEWER_VALVE_2848 // Valve 5 - Go southeast of the fourth valve, past the monk. Turn it right. + + val SEWERS = intArrayOf(SEWER_1, SEWER_2, SEWER_3, SEWER_4, SEWER_5) + + const val WARDROBE = Scenery.WARDROBE_2851 + + const val TURN_VALVE_ANIMATION = 4861 + + const val CRATE = Scenery.CRATE_34585 + const val CHEST_KEY = Items.CHEST_KEY_709 + const val POISON = Items.POISON_273 + const val COOKING_RANGE = Scenery.COOKING_RANGE_2859 + + const val SECRET_PASSAGE = Scenery.WALL_26940 + + val CHEST_LOCATION = Location(2565, 3272, 2) + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCultistDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCultistDialogue.kt new file mode 100644 index 000000000..cb986e49d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelCultistDialogue.kt @@ -0,0 +1,45 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class HazeelCultistDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int, ): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + + when { + (questStage in 1..99) -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "What? Who are you and why did you come here? It doesn't matter, leave now adventurer. While you still can.",).also { stage = END_DIALOGUE } + } + + (questStage == 100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 1 } + } else { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 2 } + } + } + 1 -> npcl(FacialExpression.FRIENDLY, "The adventurer returns! Glory to you for your efforts in bringing about the return of Lord Hazeel!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.ANNOYED, "It's the meddler! The one who blew Jones' cover! I don't know why you came to this place but it is here that you will die.").also { stage++ } + 3 -> { + end() + npc.attack(player) + } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.HAZEEL_CULTIST_894) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelNPC.kt new file mode 100644 index 000000000..ae249d3ea --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HazeelNPC.kt @@ -0,0 +1,17 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.* + +/** + * Hazeel is spawned in briefly during the Mahjarrat end of Hazeel Cult quest. + */ + +@Initializable +class HazeelNPC(id: Int = 0, location: Location? = null, ) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any, ): AbstractNPC = HazeelNPC(id, location) + + override fun getIds(): IntArray = intArrayOf(NPCs.HAZEEL_892) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HenryetaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HenryetaDialogue.kt new file mode 100644 index 000000000..bef204d6a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/HenryetaDialogue.kt @@ -0,0 +1,64 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class HenryetaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(componentID: Int, buttonID: Int): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + + when { + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage == 3) -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello. Are you okay?").also { stage++ } + 1 -> npcl(FacialExpression.SAD, "No, no I am very far from OK. Those hooligans slaughtered my precious Scruffy! I shall never recover! I am emotionally scarred for life!").also { stage = END_DIALOGUE } + 2 -> playerl(FacialExpression.NEUTRAL, "It WAS only a dog you know...").also { stage = END_DIALOGUE } + } + } + + // stage 0 - unstarted + // stage 1 - after talking to ceril + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // stage 4 - alomone either fought or he tells you he needs scroll + // stage 5 - either returning the armour, or finding the scroll + (questStage in 0..99) -> { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Oh, hello. I'm afraid I'm not very presentable at the moment. I've been under incredible stress of late! It's ruining my complexion!").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Why? What's wrong?").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "It's those awful cultists! I just don't feel safe here anymore!").also { stage = END_DIALOGUE } + } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage == 100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 1 } + } else { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 3 } + } + } + + 1 -> npcl(FacialExpression.HALF_ASKING, "Oh, it's you. I'm very disappointed that you never found those awful cultists. You're quite useless really, aren't you?").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY, "Yup, I guess I am.").also { stage = END_DIALOGUE } + + 3 -> npcl(FacialExpression.FRIENDLY, "Hello again adventurer! Since you dealt with those horrible hooligan cultists, things have vastly improved for us around here!").also { stage++ } + 4 -> playerl(FacialExpression.HAPPY, "My pleasure, Lady Henryeta.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.HENRYETA_CARNILLEAN_889) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/PhilipeDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/PhilipeDialogue.kt new file mode 100644 index 000000000..a3135eebe --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/PhilipeDialogue.kt @@ -0,0 +1,80 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.mahjarratArc +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.* + +@Initializable +class PhilipeDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle( + componentID: Int, + buttonID: Int, + ): Boolean { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + + when { + // stage 0 - unstarted + (questStage == 0) -> { + when (stage) { + 0 -> npcl(FacialExpression.CHILD_NORMAL, "Hello, how are you today?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Good thank you. And yourself?").also { stage++ } + 2 -> npcl(FacialExpression.CHILD_NORMAL, "Fine and dandy.").also { stage = END_DIALOGUE } + } + } + + // stage 3 - poison poured in food (mahjarrat-only stage) + (questStage == 3) -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.CHILD_SAD, "Someone killed Scruffy. I liked Scruffy. He never told me off.").also { stage++ } + 2 -> playerl(FacialExpression.HALF_GUILTY, "Yeah... it's a real shame.").also { stage++ } + 3 -> npcl(FacialExpression.CHILD_SAD, "I want my mommy.").also { stage = END_DIALOGUE } + } + } + + // stage 1 - after talking to ceril + // stage 2 - talk to clivet (set attr for carnillean) + // stage 2 - talk to clivet (set attr for mahjarrat) + // stage 4 - alomone either fought or he tells you he needs scroll + // stage 5 - either returning the armour, or finding the scroll + (questStage in 1..99) -> { + when (stage) { + 0 -> npcl(FacialExpression.CHILD_NORMAL, "Mommy said you're here to kill all the nasty people that keep breaking in.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Something like that.").also { stage++ } + 2 -> npcl(FacialExpression.CHILD_FRIENDLY, "Can I watch?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "No!").also { stage = END_DIALOGUE } + } + } + + // stage 100 - quest complete - either presenting proof that jones is a bad guy (duh) or resurrecting hazeel + (questStage == 100) -> when (stage) { + 0 -> { + if (mahjarratArc(player)) { + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 1 } + } else { + playerl(FacialExpression.FRIENDLY, "Hello youngster.").also { stage = 4 } + } + } + + 1 -> npcl(FacialExpression.CHILD_NORMAL, "What have you brought me? I want some more toys!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm afraid I don't have any toys.").also { stage++ } + 3 -> npcl(FacialExpression.CHILD_SAD, "Toys! I want toys!").also { stage = END_DIALOGUE } + + 4 -> npcl(FacialExpression.CHILD_NORMAL, "Daddy says you don't like Mr. Jones. Mr. Jones is nice. He brings me toys and sweets.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "Jones is a bad man, Philipe.").also { stage++ } + 6 -> npcl(FacialExpression.CHILD_NORMAL, "You're a bad " + (if (player.isMale) "man" else "lady") + " I don't like you!").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "I'll try and console myself about that disappointment somehow.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.PHILIPE_CARNILLEAN_888) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/WardrobeRevealDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/WardrobeRevealDialogue.kt new file mode 100644 index 000000000..22234e521 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/hazeelcult/WardrobeRevealDialogue.kt @@ -0,0 +1,81 @@ +package content.region.kandarin.ardougne.quest.hazeelcult + +import content.data.Quests +import content.region.kandarin.ardougne.quest.hazeelcult.HazeelCult.Companion.carnilleanArc +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * This dialogue is triggered at stage 5 of Hazeel Cult during the Carnillean Arc by searching the wardrobe for evidence. + */ + +@Initializable +class WardrobeRevealDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, WardrobeRevealDialogueFile()) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return WardrobeRevealDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf() // dialogue is triggered manually + } +} + +class WardrobeRevealDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.HAZEEL_CULT) + when { + (questStage == 5 && carnilleanArc(player!!)) -> { + when (stage) { + // note that it's authentic for the 'wardrobe' to be referred to as 'cupboard' in the dialogue. it used to be a cupboard pre-graphical update. https://youtu.be/CH7i06Noc18?si=zAdxBNlIS92cseBR&t=606 + 0 -> sendDialogue(player!!, "You search the cupboard thoroughly. You find a bottle of poison and a mysterious amulet. You pass your discovery on to Ceril.").also { stage++ } + 1 -> sendPlayerDialogue(player!!, "Ceril!").also { stage++ } + 2 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "What do you want now you scoundrel?", FacialExpression.ANGRY).also { stage++ } + 3 -> sendPlayerDialogue(player!!, "Look what I've found in the cupboard!", FacialExpression.ANGRY).also { stage++ } + 4 -> sendDialogue(player!!, "You hand Ceril the bottle of poison.").also { stage++ } + 5 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "I... I don't believe it! Poison! JONES!").also { stage++ } + 6 -> sendNPCDialogue(player!!, NPCs.BUTLER_JONES_890, "You called m'lud?").also { stage++ } + 7 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "JONES! Just WHAT is this POISON doing here???").also { stage++ } + 8 -> sendNPCDialogue(player!!, NPCs.BUTLER_JONES_890, "P-p-poison??? Yeah... uh... well, hmm... Oh, it's for Killing rats.").also { stage++ } // '...for Killing...' is authentic + 9 -> sendNPCDialogue(player!!, NPCs.BUTLER_JONES_890, "Yes, that's right. Killing rats. I am but a loyal butler sir.").also { stage++ } + 10 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "Rats eh? Yes, fair enough. Sorry to have doubted you old boy.").also { stage++ } + 11 -> sendPlayerDialogue(player!!, "Then how about this?").also { stage++ } + 12 -> sendDialogue(player!!, "You show Ceril the amulet from the cupboard.").also { stage++ } + 13 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "Wh-what??? I've seen this amulet before... The thieves that broke in... One of them was wearing an identical amulet! Jones! I don't believe it!").also { stage++ } + 14 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "Jones! We trusted you! We took you into our home!").also { stage++ } + 15 -> sendNPCDialogue(player!!, NPCs.BUTLER_JONES_890, "You senile old fool... It was all too easy! I should have killed you and your pathetic family weeks ago!", FacialExpression.ANGRY).also { stage++ } + 16 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "To think we took you in and trusted you... and this is how you repay us...").also { stage++ } + 17 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "GUARD!").also { stage++ } + 18 -> sendDialogue(player!!, "A guard rushes into the house.").also { stage++ } + 19 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "Take him away. Attempted murder and burglary.").also { stage++ } + 20 -> sendNPCDialogue(player!!, NPCs.BUTLER_JONES_890, "Don't think this is the last you have heard of me Ceril. You and your family will pay dearly for this. GLORY TO HAZEEL! ALL PRAISE ZAMORAK!").also { stage++ } + 21 -> sendNPCDialogue(player!!, NPCs.GUARD_887, "Now now. Come along quietly. There'll be no revenge where YOU'RE going - Port Sarim Jail.").also { stage++ } + 22 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "It looks like I am indebted to you sirrah!").also { stage++ } + 23 -> sendPlayerDialogue(player!!, "No problem. We all make mistakes.").also { stage++ } + 24 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "But if it weren't for you... My whole family... we could have been... I apologize for my harshness before.").also { stage++ } + 25 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "The very least I can do is to reward you for your noble efforts, and to offer my sincerest apologies as a Lord and a gentleman.").also { stage++ } + 26 -> sendPlayerDialogue(player!!, "Thank you Lord Ceril.").also { stage++ } + 27 -> sendNPCDialogue(player!!, NPCs.CERIL_CARNILLEAN_885, "No, no, thank YOU! Feel free to stop by anytime adventurer!" + ).also { + end() + finishQuest(player!!, Quests.HAZEEL_CULT) + } + } + } + + (questStage in 0..100) -> { + when(stage) { + 0 -> sendDialogue(player!!, "You search the cupboard thoroughly but find nothing of interest.").also {stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt index 3ae7c7dc4..64d4a7fa9 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt @@ -11,6 +11,7 @@ import core.game.dialogue.DialogueFile import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.tools.END_DIALOGUE +import content.data.Quests /** * Handles BrotherCedricDialogue Dialogue @@ -18,8 +19,7 @@ import core.tools.END_DIALOGUE */ class BrotherCedricDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - val questName = "Monk's Friend" - val questStage = getQuestStage(player!!, questName) + val questStage = getQuestStage(player!!, Quests.MONKS_FRIEND) when { questStage < 30 -> { when(stage) { @@ -36,7 +36,7 @@ class BrotherCedricDialogue : DialogueFile() { 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Brother Cedric are you okay?").also{stage++} 1 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Yeesshhh, I'm very, very drunk..hic..up..").also{stage++} 2 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Brother Omad needs the wine for the party.").also{stage++} - 3 -> npcl(core.game.dialogue.FacialExpression.SAD, "Oh dear, oh dear, I knew I had to do something!").also{stage = END_DIALOGUE }.also{ setQuestStage(player!!, questName, 40) } + 3 -> npcl(core.game.dialogue.FacialExpression.SAD, "Oh dear, oh dear, I knew I had to do something!").also{stage = END_DIALOGUE }.also{ setQuestStage(player!!, Quests.MONKS_FRIEND, 40) } } } questStage == 40 -> { @@ -54,7 +54,7 @@ class BrotherCedricDialogue : DialogueFile() { sendItemDialogue(player!!, Items.JUG_OF_WATER_1937, "You hand the monk a jug of water.") stage=0 player!!.inventory.remove(Item(Items.JUG_OF_WATER_1937)) - setQuestStage(player!!, questName, 41) + setQuestStage(player!!, Quests.MONKS_FRIEND, 41) } } } @@ -72,7 +72,7 @@ class BrotherCedricDialogue : DialogueFile() { } 5 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "In that case I'd better drink more wine! It helps me think.").also {stage= END_DIALOGUE } 10 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Excellent, I just need some wood.").also{stage++} - 11 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Ok, I'll see what I can find.").also{stage = END_DIALOGUE }.also{setQuestStage(player!!, questName, 42)} + 11 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Ok, I'll see what I can find.").also{stage = END_DIALOGUE }.also{setQuestStage(player!!, Quests.MONKS_FRIEND, 42)} } } questStage == 42 -> { @@ -89,7 +89,7 @@ class BrotherCedricDialogue : DialogueFile() { 4 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Ok! I'll see you later!").also{ stage= END_DIALOGUE player!!.inventory.remove(Item(Items.LOGS_1511)) - setQuestStage(player!!, questName, 50) + setQuestStage(player!!, Quests.MONKS_FRIEND, 50) } } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt index 74b322344..bea3883cc 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt @@ -14,6 +14,7 @@ import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.game.world.GameWorld.Pulser import core.tools.END_DIALOGUE +import content.data.Quests /** @@ -22,8 +23,7 @@ import core.tools.END_DIALOGUE */ class BrotherOmadDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - val questName = "Monk's Friend" - val questStage = getQuestStage(player!!, questName) + val questStage = getQuestStage(player!!, Quests.MONKS_FRIEND) when (questStage) { 0 -> { when(stage) { @@ -50,7 +50,7 @@ class BrotherOmadDialogue : DialogueFile() { } 10 -> npcl(core.game.dialogue.FacialExpression.HALF_WORRIED, "Please do. We won't be able to help you as we are peaceful men but we would be grateful for your help!").also { stage++ } 11 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Where are they?").also { stage++ } - 12 -> npcl(core.game.dialogue.FacialExpression.SAD, "They hide in a secret cave in the forest. It's hidden under a ring of stones. Please, bring back the blanket!").also { stage = END_DIALOGUE }.also { player!!.questRepository.getQuest("Monk's Friend").start(player) }.also { player!!.questRepository.syncronizeTab(player) } + 12 -> npcl(core.game.dialogue.FacialExpression.SAD, "They hide in a secret cave in the forest. It's hidden under a ring of stones. Please, bring back the blanket!").also { stage = END_DIALOGUE }.also { player!!.questRepository.getQuest(Quests.MONKS_FRIEND).start(player) }.also { player!!.questRepository.syncronizeTab(player) } } } 10 -> { @@ -70,7 +70,7 @@ class BrotherOmadDialogue : DialogueFile() { } 31 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Really, that's excellent, well done! Maybe now I will be able to get some rest.").also{stage++} 32 -> npcl(core.game.dialogue.FacialExpression.SAD, "*yawn*..I'm off to bed! Farewell brave traveller!").also{player!!.inventory.remove(Item(Items.CHILDS_BLANKET_90)) - setQuestStage(player!!, questName, 20); stage = END_DIALOGUE + setQuestStage(player!!, Quests.MONKS_FRIEND, 20); stage = END_DIALOGUE } } } @@ -105,7 +105,12 @@ class BrotherOmadDialogue : DialogueFile() { 996 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Okay traveller, take care.").also{stage = END_DIALOGUE } 997 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Of course, but we need the wine first.").also{stage = END_DIALOGUE } 42 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Oh, he won't be far. Probably out in the forest.").also{stage++} - 43 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Ok, I'll go and find him.").also { stage = END_DIALOGUE }.also{ setQuestStage(player!!, questName, 30)} + 43 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Ok, I'll go and find him.").also { stage = END_DIALOGUE }.also{ + setQuestStage( + player!!, + Quests.MONKS_FRIEND, + 30 + )} } } 30 -> { @@ -192,7 +197,7 @@ class BrotherOmadDialogue : DialogueFile() { monk.animator.animate(Animation(2109)) // Jump for joy } 25 -> if (questComplete) { - player!!.questRepository.getQuest("Monk's Friend").finish(player) + player!!.questRepository.getQuest(Quests.MONKS_FRIEND).finish(player) } } count++ diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt index 8279ba5ce..cfe48d058 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt @@ -6,6 +6,7 @@ import core.game.dialogue.DialogueFile import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.tools.END_DIALOGUE +import content.data.Quests /** * Handles MonasteryMonkDialogue Dialogue @@ -13,7 +14,7 @@ import core.tools.END_DIALOGUE */ class MonasteryMonkDialogue : DialogueFile() { override fun handle(interfaceId: Int, buttonId: Int) { - var questStage = player!!.questRepository.getStage("Monk's Friend") + var questStage = player!!.questRepository.getStage(Quests.MONKS_FRIEND) if (questStage == 0){ when(stage) { 0 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Peace brother.").also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt index cf38a3a18..c559c6a85 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt @@ -8,6 +8,7 @@ import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * Represents the "Monk's Friend" quest. @@ -15,7 +16,7 @@ import org.rs09.consts.Items */ @Initializable -class MonksFriend: Quest("Monk's Friend", 89, 88, 1, 30, 0, 1, 80) { +class MonksFriend: Quest(Quests.MONKS_FRIEND, 89, 88, 1, 30, 0, 1, 80) { override fun newInstance(`object`: Any?): Quest { return this diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/PlagueCity.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCity.kt similarity index 92% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/PlagueCity.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCity.kt index 47585fbd1..d34a8904d 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/PlagueCity.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCity.kt @@ -1,6 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity -import core.api.addItem +import content.data.Quests import core.api.addItemOrDrop import core.api.removeAttributes import core.api.rewardXP @@ -11,9 +11,8 @@ import core.plugin.Initializable import org.rs09.consts.Items @Initializable -class PlagueCity : Quest("Plague City", 98, 97, 1, 165, 0, 1, 29) { +class PlagueCity : Quest(Quests.PLAGUE_CITY, 98, 97, 1, 165, 0, 1, 29) { override fun newInstance(`object`: Any?): Quest { return this } - companion object { const val PlagueCityQuest = "Plague City" } override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) var line = 11 @@ -36,7 +35,7 @@ class PlagueCity : Quest("Plague City", 98, 97, 1, 165, 0, 1, 29) { if (stage >= 2) { line++ - line(player, "Alrena has given me a Gasmask to protect me", line++, stage >= 3) + line(player, "Alrena has given me a gas mask to protect me", line++, stage >= 3) line(player, "from the plague while in West Ardougne.", line++, stage >= 3) line++ } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCityListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCityListeners.kt new file mode 100644 index 000000000..9c5866a59 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCityListeners.kt @@ -0,0 +1,435 @@ +package content.region.kandarin.ardougne.quest.plaguecity + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners.MournerKidnapDialogueFile +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import core.tools.END_DIALOGUE +import org.rs09.consts.* +import core.game.node.scenery.Scenery as SceneryNode + +class PlagueCityListeners : InteractionListener { + companion object { + + const val BUCKET_USES_ATTRIBUTE = "/save:elena:bucket" + const val ARDOUGNE_TELE_ATTRIBUTE = "/save:Ardougne:teleport" + + private const val TRYING_TO_OPEN_GRILL = 3192 + private const val POUR_THE_WATER = 2283 + private const val CLIMB_LADDER = 828 + private const val GO_INTO_PIPE = 10580 + private const val TIE_THE_ROPE = 3191 + private const val DIG_WITH_SPADE = 830 + + } + + override fun defineListeners() { + + on(NPCs.BILLY_REHNISON_723, IntType.NPC, "talk-to") { player, _ -> + sendMessage(player, "Billy isn't interested in talking.") + return@on true + } + + on(Scenery.MANHOLE_2543, IntType.SCENERY, "open") { player, node -> + replaceScenery(node.asScenery(), Scenery.MANHOLE_2544, -1) + addScenery(Scenery.MANHOLE_COVER_2545, Location(node.location.x, node.location.y-1, 0),0,10) + sendMessage(player, "You pull back the manhole cover.") + return@on true + } + + on(Scenery.MANHOLE_COVER_2545, IntType.SCENERY, "close") { player, node -> + removeScenery(node.asScenery()) + getScenery(location(node.location.x, node.location.y+1, 0))?.let { replaceScenery(it, Scenery.MANHOLE_2543, -1) } + sendMessage(player, "You close the manhole cover.") + return@on true + } + + on(Scenery.MANHOLE_2544, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location(2514, 9739, 0)) + face(player, Location.create(2514, 9740)) + sendMessage(player, "You climb down through the manhole.") + return@on true + } + + on(Scenery.DOOR_2528, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 13) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendNPCDialogue(player, NPCs.BRAVEK_711,"Go away, I'm busy! I'm... Umm... In a meeting!") + // This typo is authentic + sendMessage(player, "The door won't open") + } + return@on true + } + + on(Scenery.MUD_PILE_2533, IntType.SCENERY, "climb") { player, _ -> + animate(player, CLIMB_LADDER) + queueScript(player, 2){ + teleport(player, Location(2566, 3332)) + sendDialogue(player, "You climb up the mud pile.") + return@queueScript true + } + return@on true + } + + on(Scenery.DUG_HOLE_11417, IntType.SCENERY, "Climb-down") { player, _ -> + teleport(player, Location(2518, 9759)) + sendDialogue(player, "You climb down the tunnel into the sewer.") + return@on true + } + + on(Items.A_MAGIC_SCROLL_1505, IntType.ITEM, "read") { player, item -> + if (removeItem(player, item)){ + if (getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)){ + sendGraphics(Graphics(157,96), player.location) + impact(player, 0) + sendMessage(player, "The scroll explodes.") + addItem(player, Items.ASHES_592) + } + else{ + setAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, true) + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendItemDialogue(player, Items.A_MAGIC_SCROLL_1505, "You memorise what is written on the scroll.").also { stage++ } + 1 -> sendDialogue(player, "You can now cast the Ardougne Teleport spell provided you have the required runes and magic level.").also { stage = END_DIALOGUE } + } + } + }) + } + return@on true + } + return@on false + } + + on(Items.A_SCRUFFY_NOTE_1508, IntType.ITEM, "read") { player, _ -> + sendMessage(player, "You guess it really says something slightly different.") + openInterface(player, 222).also { scruffyNote(player) } + return@on true + } + + class KidnapDoorDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + + when(stage) { + 0 -> { + // Face the door + face(player!!, Location.create(player!!.location.x, 3270, 0)) + sendDialogue(player!!, "The door won't open. You notice a black cross on the door.").also { stage++ } + } + 1 -> openDialogue(player!!, MournerKidnapDialogueFile(), NPC(NPCs.MOURNER_3216)) + } + } + + } + + on(Scenery.DOOR_35991, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) > 16) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else { + // Make sure we are standing in front of the door + forceWalk(player, Location.create(node.location.x, node.location.y), "smart") + openDialogue(player, KidnapDoorDialogue()) + } + return@on true + } + + on(Scenery.WARDROBE_2525, IntType.SCENERY, "search") { player, _ -> + if(getQuestStage(player, Quests.PLAGUE_CITY) >= 2){ + if (!hasAnItem(player, Items.GAS_MASK_1506).exists()){ + if(freeSlots(player) == 0) { + sendItemDialogue(player, Items.GAS_MASK_1506, "You find a protective mask but you don't have enough room to take it.") + return@on true + } + else { + sendItemDialogue(player, Items.GAS_MASK_1506, "You find a protective mask.") + addItem(player, Items.GAS_MASK_1506) + return@on true + } + } + } + // The player should not be given a mask for whatever reason + sendMessage(player, "You search the wardrobe but you find nothing.") + return@on false + } + + onUseWith(IntType.SCENERY, Items.BUCKET_OF_WATER_1929, Scenery.MUD_PATCH_11418) { player, _, _ -> + if (getAttribute(player, BUCKET_USES_ATTRIBUTE, 0) in 0..2 && removeItem(player, Items.BUCKET_OF_WATER_1929)) { + animate(player, POUR_THE_WATER) + sendDialogueLines(player, "You pour water onto the soil.", "The soil softens slightly." + ) + player.incrementAttribute(BUCKET_USES_ATTRIBUTE, 1) + addItem(player, Items.BUCKET_1925) + return@onUseWith true + } else if (getAttribute(player, BUCKET_USES_ATTRIBUTE, 0) == 3 && removeItem(player, Items.BUCKET_OF_WATER_1929)) { + animate(player, POUR_THE_WATER) + player.incrementAttribute(BUCKET_USES_ATTRIBUTE, 1) + sendDialogueLines(player, + "You pour water onto the soil.", + "The soil is now soft enough to dig into." + ) + setAttribute(player, "/save:elena:dig", true) + addItem(player, Items.BUCKET_1925) + } else { + sendDialogue(player, "You don't need to pour on any more water the soil is soft enough already.") + } + return@onUseWith true + } + + + onDig(Location.create(2566, 3332, 0)){ player: Player -> + dig(player) + } + + onUseWith(IntType.SCENERY, Items.SPADE_952, Scenery.MUD_PATCH_11418) { player, _, _ -> + dig(player) + return@onUseWith true + } + + on(Scenery.GRILL_11423, IntType.SCENERY, "open") { player, _ -> + if (getQuestStage(player, Quests.PLAGUE_CITY) == 4) { + sendDialogue(player, "The grill is too secure. You can't pull it off alone.") + animate(player, TRYING_TO_OPEN_GRILL) + setQuestStage(player, Quests.PLAGUE_CITY, 5) + } else { + sendDialogue(player, "There is a grill blocking your way") + } + return@on true + } + + on(Scenery.PIPE_2542, IntType.SCENERY, "climb-up") { player, _ -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 7) { + if (inEquipment(player, Items.GAS_MASK_1506)){ + animate(player, GO_INTO_PIPE,true) + queueScript(player, 3) { + teleport(player, Location(2529, 3304, 0)) + sendDialogue(player, "You climb up through the sewer pipe.") + return@queueScript stopExecuting(player) + } + forceMove(player, Location(2514, 9739, 0), Location(2514, 9734, 0), 0, 5,Direction.SOUTH) + } + else { + sendNPCDialogue(player, NPCs.EDMOND_714, "I can't let you enter the city without your gas mask on.") + } + } + else { + sendDialogue(player, "There is a grill blocking your way") + } + return@on true + } + + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.PIPE_2542) { player, _, _ -> + sendPlayerDialogue(player, "Maybe I should try opening it first.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.GRILL_11423) { player, _, _ -> + if(removeItem(player, Items.ROPE_954)) { + queueScript(player, 1) { stage: Int -> + when (stage) { + 0 -> forceWalk(player, Location.create(2514, 9740, 0), "SMART") + 2 -> face(player, Location.create(2514, 9739, 0), -1) + 3 -> { + animate(player, TIE_THE_ROPE) + setVarbit(player, 1787, 5, true) // Tied rope to the grill. + } + + 4 -> { + setQuestStage(player, Quests.PLAGUE_CITY, 6) + sendItemDialogue( + player, + Items.ROPE_954, + "You tie the end of the rope to the sewer pipe's grill." + ) + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 1) + } + return@onUseWith true + } else { + sendMessage(player, "Nothing interesting happens.") + } + return@onUseWith true + } + + class TedRehnisonDoors : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.TED_REHNISON_721) + when (stage) { + 0 -> { + npcl(FacialExpression.FRIENDLY, "Go away. We don't want any.").also { + if(hasAnItem(player!!, Items.BOOK_1509).exists()){ + stage++ + } else { + stage = END_DIALOGUE } + } + } + 1 -> playerl(FacialExpression.NEUTRAL, "I'm a friend of Jethick's, I have come to return a book he borrowed.").also { stage++ } + 2 -> npc(FacialExpression.FRIENDLY, "Oh... why didn't you say, come in then.").also { stage++ } + 3 -> sendItemDialogue(player!!, Items.BOOK_1509, "You hand the book to Ted as you enter.").also { + DoorActionHandler.handleAutowalkDoor(player, getScenery(2531, 3328, 0)) + setQuestStage(player!!, Quests.PLAGUE_CITY, 9) + removeItem(player!!, Items.BOOK_1509) + stage++ + } + 4 -> npcl(FacialExpression.NEUTRAL, "Thanks, I've been missing that.").also { stage = END_DIALOGUE } + } + } + } + + on(Scenery.DOOR_2537, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 9) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, TedRehnisonDoors()) + } + return@on true + } + + on(Scenery.BARREL_2530, IntType.SCENERY, "search") { player, _ -> + if (inInventory(player, Items.A_SMALL_KEY_1507)) { + sendMessage(player, "You don't find anything interesting.") + return@on true + } else { + sendItemDialogue(player, Items.A_SMALL_KEY_1507, "You find a small key in the barrel.") + addItem(player, Items.A_SMALL_KEY_1507) + } + } + + on(Scenery.SPOOKY_STAIRS_2522, IntType.SCENERY, "walk-down") { player, _ -> + sendMessage(player, "You walk down the stairs...") + teleport(player, Location.create(2537, 9671)) + return@on true + } + + on(Scenery.SPOOKY_STAIRS_2523, IntType.SCENERY, "walk-up") { player, _ -> + teleport(player, Location.create(2536, 3271, 0)) + sendMessage(player, "You walk up the stairs...") + return@on true + } + + class ElenaDoorDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.ELENA_3215) + when (stage) { + 0 -> sendDialogue(player!!, "The door is locked.").also { stage++ } + 1 -> npcl(FacialExpression.CRYING, "Hey get me out of here please!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I would do but I don't have a key.").also { stage++ } + 3 -> npcl(FacialExpression.SAD, "I think there may be one around somewhere. I'm sure I heard them stashing it somewhere.").also { stage++ } + 4 -> options("Have you caught the plague?", "Okay, I'll look for it.").also { stage++ } + 5 -> when (buttonID) { + 1 -> playerl(FacialExpression.WORRIED, "Have you caught the plague?").also { stage = 6 } + 2 -> playerl(FacialExpression.NEUTRAL, "Okay, I'll look for it.").also { stage = END_DIALOGUE } + } + 6 -> npcl(FacialExpression.HALF_WORRIED, "No, I have none of the symptoms.").also { stage++ } + 7 -> playerl(FacialExpression.THINKING, "Strange, I was told this house was plague infected.").also { stage++ } + 8 -> npcl(FacialExpression.THINKING, "I suppose that was a cover up by the kidnappers.").also { stage = END_DIALOGUE } + } + } + } + + onUseWith(IntType.SCENERY, Items.A_SMALL_KEY_1507, Scenery.DOOR_2526) { player, _, node -> + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendDialogue(player, "You unlock the door.") + return@onUseWith true + } + + on(Scenery.DOOR_2526, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 99 || hasAnItem(player, Items.A_SMALL_KEY_1507).exists()) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, ElenaDoorDialogue()) + } + return@on true + } + + onUseWith(IntType.NPC, Items.HANGOVER_CURE_1504, NPCs.BRAVEK_711) { player, _, _ -> + openDialogue(player, NPCs.BRAVEK_711) + return@onUseWith true + } + + on(Scenery.DOOR_2054, IntType.SCENERY, "open"){ player, node -> + if (isQuestComplete(player, Quests.PLAGUE_CITY)){ + DoorActionHandler.handleAutowalkDoor(player, node as SceneryNode) + } else { + sendMessage(player, "This door is locked") + } + return@on true + } + + } + + private fun dig(p : Player) { + if (getAttribute(p, "/save:elena:dig", false)) { + // Only remove the counter now that you have dug a hole + removeAttribute(p, BUCKET_USES_ATTRIBUTE) + queueScript(p, 1) { stage: Int -> + when (stage) { + 0 -> sendItemDialogue( + p, Items.SPADE_952, + "You dig deep into the soft soil... Suddenly it crumbles away!" + ) + + 1 -> animate(p, DIG_WITH_SPADE) + 3 -> { + teleport(p, Location(2518, 9759)) + setQuestStage(p, Quests.PLAGUE_CITY, 4) + setVarbit(p, Vars.VARBIT_QUEST_PLAGUE_CITY_EDMOND_TUNNELS, 1) + setVarbit(p, Vars.VARBIT_QUEST_PLAGUE_CITY_MUD_PILE, 1) + sendDialogueLines( + p, + "You fall through...", + "...you land in the sewer.", + "Edmond follows you down the hole." + ) + // We've dug the hole so don't keep track + removeAttribute(p, "/save:elena:dig") + return@queueScript stopExecuting(p) + } + } + return@queueScript delayScript(p, 1) + + } + } else { + sendMessage(p, "Nothing interesting happens.") + } + } + + // https://youtu.be/AG81LH51WME?t=302 + private fun scruffyNote(player: Player) { + val scruffynotes = + arrayOf( + "Got a bncket of nnilk", + "Tlen qrind sorne lhoculate", + "vnith a pestal and rnortar", + "ald the grourd dlocolate to tho milt", + "fnales add 5cme snape gras5", + ) + setInterfaceText(player, scruffynotes.joinToString("
"), 222, 4) + } + + override fun defineDestinationOverrides() { + setDest(IntType.SCENERY, intArrayOf(Scenery.GRILL_11423), "open") { _, _ -> + return@setDest Location.create(2514, 9739, 0) + } + + setDest(IntType.SCENERY, intArrayOf(Scenery.PIPE_2542), "climb-up") { _, _ -> + return@setDest Location.create(2514, 9739, 0) + } + + setDest(IntType.SCENERY, intArrayOf(Scenery.MANHOLE_2544), "climb-down") { _, node -> + return@setDest Location.create(node.location.x, node.location.y+1, 0) + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/UndergroundCutscene.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/UndergroundCutscene.kt similarity index 63% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/UndergroundCutscene.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/UndergroundCutscene.kt index c924cc595..eea5f2ffa 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/UndergroundCutscene.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/UndergroundCutscene.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity +import content.data.Quests import core.api.* import core.game.activity.Cutscene import core.game.dialogue.FacialExpression @@ -28,12 +29,22 @@ class UndergroundCutscene(player: Player) : Cutscene(player) { } 1 -> { - teleport(player, 18, 13) + teleport(player, 18, 12) + setVarbit(player, 1787, 2, true) // Grill removal. timedUpdate(1) } 2 -> { move(player, 18, 12) + face(player, base.transform(18, 11, 0)) + // You have to remove the stubborn previous sceneries before adding your own. + removeScenery(getScenery(base.transform(18, 11, 0))!!) + removeScenery(getScenery(base.transform(18, 12, 0))!!) + removeScenery(getScenery(base.transform(18, 13, 0))!!) + // Add the rope sceneries to animate. + addScenery(11416, base.transform(18, 11, 0),2,10) + addScenery(11412, base.transform(18, 12, 0),2,10) + addScenery(11414, base.transform(18, 13, 0),2,10) fadeFromBlack() moveCamera(21, 16) rotateCamera(18, 13) @@ -41,20 +52,22 @@ class UndergroundCutscene(player: Player) : Cutscene(player) { } 3 -> { - visualize(getNPC(EDMOND)!!, ROPE_PULL, 2270) - visualize(player, ROPE_PULL, 2270) + animate(getNPC(EDMOND)!!, ROPE_PULL) + animate(player, ROPE_PULL) + animateScenery(player, getScenery(base.transform(18, 11, 0))!!, 3189) + animateScenery(player, getScenery(base.transform(18, 12, 0))!!, 3188) + animateScenery(player, getScenery(base.transform(18, 13, 0))!!, 3188) sendChat(player, "1... 2... 3... Pull!") timedUpdate(6) } 4 -> { - setVarbit(player, 1787, 6, true) // Grill removal. face(player, getNPC(EDMOND)!!.location) timedUpdate(2) } 5 -> { - dialogueUpdate(EDMOND, FacialExpression.FRIENDLY, "Once you're in the city look for a man called Jethick, he's an old friend and should help you. Send") + dialogueUpdate(EDMOND, FacialExpression.FRIENDLY, "Once you're in the city look for a man called Jethick, he's an old friend and should help you. Send", hide=true) sendChat(getNPC(EDMOND)!!, "Once you're in the city") timedUpdate(4) } @@ -75,7 +88,7 @@ class UndergroundCutscene(player: Player) : Cutscene(player) { } 9 -> { - dialogueUpdate(EDMOND, FacialExpression.FRIENDLY, "him my regards, I Haven't seen him since before Elena was born.") + dialogueUpdate(EDMOND, FacialExpression.FRIENDLY, "him my regards, I haven't seen him since before Elena was born.", hide=true) sendChat(getNPC(EDMOND)!!, "him my regards, I haven't") timedUpdate(4) } @@ -92,17 +105,13 @@ class UndergroundCutscene(player: Player) : Cutscene(player) { 12 -> { sendChat(player, "Alright, thanks I will.") - timedUpdate(3) + // todo change this to true once no continue button player model size is fixed + sendPlayerDialogue(player,"Alright, thanks I will.", hide = false) + timedUpdate(2) } - 13 -> { - sendPlayerDialogue(player,"Alright, thanks I will.") - timedUpdate(4) - } - - 14 -> { end { - setQuestStage(player, "Plague City", 7) + setQuestStage(player, Quests.PLAGUE_CITY, 7) } } } @@ -110,6 +119,6 @@ class UndergroundCutscene(player: Player) : Cutscene(player) { companion object { private const val EDMOND = 714 - private val ROPE_PULL = 3187 + private const val ROPE_PULL = 3187 } } diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/AlrenaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/AlrenaDialogue.kt similarity index 79% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/AlrenaDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/AlrenaDialogue.kt index cd8c50d4f..56384c44b 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/AlrenaDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/AlrenaDialogue.kt @@ -1,5 +1,7 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -15,8 +17,9 @@ class AlrenaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") == 1) { - playerl(FacialExpression.FRIENDLY, "Hello, Edmond has asked me to help find your daughter.").also { stage++ } + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 1) { + // playerl formats this weirdly + player(FacialExpression.FRIENDLY, "Hello, Edmond has asked me to help find your","daughter.").also { stage++ } } else { playerl(FacialExpression.FRIENDLY, "Hello Madam.").also { stage++ } } @@ -24,7 +27,7 @@ class AlrenaDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { 0 -> when (stage) { 1 -> npcl(FacialExpression.NEUTRAL, "Oh, hello there.").also { stage++ } @@ -43,15 +46,15 @@ class AlrenaDialogue(player: Player? = null) : DialoguePlugin(player) { sendItemDialogue(player!!, Items.DWELLBERRIES_2126, "You give the dwellberries to Alrena.").also { stage++ } removeItem(player!!, Items.DWELLBERRIES_2126) } - 4 -> sendDialogue(player!!, "Alrena crushes the berries into a smooth paste. She then smears the paste over a strange mask.").also { stage++ } - 5 -> npcl(FacialExpression.FRIENDLY, "There we go, all done. While in West Ardougne you must wear this at all times, or you could catch the plague. I'll make a spare mask. I'll hide it in the wardrobe in case the mourners come in.").also { stage++ } - 6 -> sendItemDialogue(player!!, Items.GAS_MASK_1506, "Alrena gives you the mask.").also { stage++ } - 7 -> { - end() + // sendDialogue formats this weirdly + 4 -> sendDialogueLines(player!!, "Alrena crushes the berries into a smooth paste. She then smears the", "paste over a strange mask.").also { stage++ } + // npcl formats this weirdly + 5 -> npc(FacialExpression.FRIENDLY, "There we go, all done. While in West Ardougne you", "must wear this at all times, or you could catch the","plague.").also { stage++ } + 6 -> { + setQuestStage(player!!, Quests.PLAGUE_CITY, 2) addItem(player!!, Items.GAS_MASK_1506) - setQuestStage(player!!, "Plague City", 2) - setAttribute(player!!, PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) - sendNPCDialogue(player!!, NPCs.ALRENA_710, "I'll make a spare mask. I'll hide it in the wardrobe in case the mourners come in.") + sendItemDialogue(player!!, Items.GAS_MASK_1506, "Alrena gives you the mask.").also { stage++ } + // Jump down to quest stage 2 from here } 8 -> playerl(FacialExpression.NEUTRAL, "Ok, I'll go and get some.").also { stage = END_DIALOGUE } } @@ -59,6 +62,9 @@ class AlrenaDialogue(player: Player? = null) : DialoguePlugin(player) { 2 -> when (stage) { 1 -> npcl(FacialExpression.FRIENDLY, "Hello darling, I think Edmond had a good idea of how to get into West Ardougne, you should hear his idea.").also { stage++ } 2 -> playerl(FacialExpression.FRIENDLY, "Alright I'll go and see him now.").also { stage = END_DIALOGUE } + + // This gets entered from quest stage 1 + 7 -> npcl(FacialExpression.FRIENDLY, "I'll make a spare mask. I'll hide it in the wardrobe in case the mourners come in.").also { stage = END_DIALOGUE } } 3 -> when (stage) { @@ -112,19 +118,26 @@ class AlrenaDialogue(player: Player? = null) : DialoguePlugin(player) { 5 -> npcl(FacialExpression.FRIENDLY, " Yes. There should be one in the house somewhere. Let me know if you need anything else.").also { stage = END_DIALOGUE } } - in 15..98 -> when (stage) { + 15 -> when (stage) { 1 -> npcl(FacialExpression.FRIENDLY, "Hello, any word on Elena?").also { stage++ } 2 -> playerl(FacialExpression.FRIENDLY, "Not yet I'm afraid, I need to find some Snape grass first, any idea where I'd find some?").also { stage++ } 3 -> npcl(FacialExpression.FRIENDLY, "It's not common round here, though I hear it's easy to find by the coast south west of Falador.").also { stage++ } 4 -> playerl(FacialExpression.FRIENDLY, "Thanks, I'll go take a look.").also { stage++ } 5 -> playerl(FacialExpression.FRIENDLY, "I also need to get some chocolate powder for a hangover cure for the city warder.").also { stage++ } 6 -> npcl(FacialExpression.FRIENDLY, "Well I don't have any chocolate, but this may help.").also { stage++ } - 7 -> sendItemDialogue(player!!, Items.PESTLE_AND_MORTAR_233, "Alrena hands you a pestle and mortar.").also { stage++ } - 8 -> playerl(FacialExpression.FRIENDLY, "Thanks.").also { stage++ } - 9 -> { - end() + 7 -> sendItemDialogue(player!!, Items.PESTLE_AND_MORTAR_233, "Alrena hands you a pestle and mortar.").also { addItem(player!!, Items.PESTLE_AND_MORTAR_233) + stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "Thanks.").also { stage = END_DIALOGUE } + } + + in 16 .. 98 -> when(stage){ + 1 -> npcl(FacialExpression.WORRIED, "Hello, any word on Elena?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Not yet I'm afraid.").also { stage++ } + 3 -> npcl(FacialExpression.WORRIED, "Is there anything else I can do to help?").also { stage++ } + 4 -> playerl(FacialExpression.SAD, "Sorry but not right now.").also {stage = END_DIALOGUE } + } 99 -> when (stage) { diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/BravekDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/BravekDialogue.kt new file mode 100644 index 000000000..3eeb1e39e --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/BravekDialogue.kt @@ -0,0 +1,156 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BravekDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val SPEAK_ANOTHER_DAY = 10 + const val WAITING_FOR_CURE = 20 + const val CURED = 30 + const val IMPORTANT = 50 + const val DRINK_TOO_MUCH = 60 + const val CURE = 70 + const val WHAT_HELP = 80 + const val ALL_PEOPLE_SAY = 90 + const val NOT_LISTEN = 100 + const val INTEREST = 110 + const val WEAK_LEADER = 120 + } + + override fun open(vararg args: Any?): Boolean { + npc = if (args[0] is Int) NPC(args[0] as Int) else args[0] as NPC + when(getQuestStage(player, Quests.PLAGUE_CITY)){ + in 0..13 -> npcl(FacialExpression.ANNOYED, "My head hurts! I'll speak to you another day...").also { stage = SPEAK_ANOTHER_DAY } + 14 -> npcl(FacialExpression.ANNOYED, " Uurgh! My head still hurts too much to think straight. " + + "Oh for one of Trudi's hangover cures!").also { stage = if(hasAnItem(player, Items.HANGOVER_CURE_1504).exists()) WAITING_FOR_CURE else END_DIALOGUE } + 15 -> npcl(FacialExpression.FRIENDLY, "Ah now, what was it you wanted me to do for you?").also { stage = WHAT_HELP } + else -> npcl(FacialExpression.FRIENDLY, "Thanks again for the hangover cure.").also { stage = if(hasAnItem(player, Items.WARRANT_1503).exists() || getQuestStage(player, Quests.PLAGUE_CITY) >= 99) CURED else WHAT_HELP } + + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (stage){ + + SPEAK_ANOTHER_DAY -> showTopics( + Topic("This is really important though!", IMPORTANT), + Topic("Ok, goodbye.", END_DIALOGUE) + ) + + IMPORTANT -> npc(FacialExpression.ANNOYED, + "I can't possibly speak to you with my head spinning like", + "this... I went a bit heavy on the drink again last night.", + "Curse my herbalist, she made the best hang over cures.", + "Darn inconvenient of her catching the plague.").also { stage++ } + IMPORTANT + 1 -> showTopics( + Topic("Ok, goodbye.", END_DIALOGUE), + Topic(" You shouldn't drink so much then!", DRINK_TOO_MUCH), + Topic("Do you know what's in the cure?", CURE) + ) + + DRINK_TOO_MUCH -> npcl(FacialExpression.ANNOYED, "Well positions of responsibility are hard, " + + "I need something to take my mind off things... Especially with the problems this place has.").also { stage++ } + DRINK_TOO_MUCH + 1 -> showTopics( + Topic("Ok, goodbye.", END_DIALOGUE), + Topic("Do you know what's in the cure?", CURE), + Topic("I don't think drink is the solution.", DRINK_TOO_MUCH+2) + ) + DRINK_TOO_MUCH + 2 -> npcl(FacialExpression.ANNOYED, "Uurgh! My head still hurts too much to think straight. Oh for one of Trudi's hangover cures!").also { stage = END_DIALOGUE } + + CURE -> npc(FacialExpression.NEUTRAL, + "Hmmm let me think... Ouch! Thinking isn't clever. Ah", + "here, she did scribble it down for me.").also { stage++ } + CURE + 1 -> { + if(hasSpaceFor(player!!, Item(Items.A_SCRUFFY_NOTE_1508))) { + sendItemDialogue( + player!!, + Items.A_SCRUFFY_NOTE_1508, + "Bravek hands you a tatty piece of paper." + ).also { stage++ } + } + else{ + sendItemDialogue(player!!, Items.A_SCRUFFY_NOTE_1508, "Bravek waves a note in front of you but you do not have space for it").also { stage = END_DIALOGUE } + } + } + CURE + 2 ->{ + addItem(player!!, Items.A_SCRUFFY_NOTE_1508) + setQuestStage(player!!, Quests.PLAGUE_CITY, 14) + end() + } + + WAITING_FOR_CURE -> playerl(FacialExpression.NEUTRAL, "Try this.").also { stage++ } + WAITING_FOR_CURE + 1 -> { + animate(npc, 1330) // Drink hangover cure. + findLocalNPC(player!!, NPCs.BRAVEK_711)!!.sendChat("Grruurgh!") + sendItemDialogue(player!!, Items.HANGOVER_CURE_1504, "You give Bravek the hangover cure. Bravek gulps down the foul-looking liquid.").also { stage++ } + setQuestStage(player, Quests.PLAGUE_CITY, 15) + removeItem(player, Items.HANGOVER_CURE_1504) + } + WAITING_FOR_CURE + 2 -> npcl(FacialExpression.HAPPY, "Ooh that's much better! Thanks, that's the clearest my head has felt in a month." + + "Ah now, what was it you wanted me to do for you?" + ).also { stage = WHAT_HELP } + + WHAT_HELP -> playerl(FacialExpression.ASKING, "I need to rescue a kidnap victim called Elena. She's being held in a plague house, I need permission to enter.").also { stage++ } + WHAT_HELP + 1 -> npcl(FacialExpression.HALF_GUILTY, "Well the mourners deal with that sort of thing...").also { stage++ } + WHAT_HELP + 2 -> showTopics( + Topic("Ok, I'll go speak to them.", END_DIALOGUE), + Topic("Is that all anyone says around here?", ALL_PEOPLE_SAY), + Topic("They won't listen to me!", NOT_LISTEN, skipPlayer = true) + ) + + ALL_PEOPLE_SAY -> npcl(FacialExpression.HALF_GUILTY, "Well, they know best about plague issues.").also { stage++ } + ALL_PEOPLE_SAY + 1 -> showTopics( + Topic("Don't you want to take an interest in it at all?", INTEREST), + Topic("They won't listen to me!", NOT_LISTEN, skipPlayer = true) + ) + + INTEREST -> npcl(FacialExpression.HALF_GUILTY, "Nope, I don't wish to take a deep interest in plagues. That stuff is too scary for me!").also { stage++ } + INTEREST + 1 -> showTopics( + Topic("I see why people say you're a weak leader.", WEAK_LEADER), + Topic("Ok, I'll talk to the mourners.", END_DIALOGUE), + Topic("They won't listen to me!", NOT_LISTEN, skipPlayer = true) + ) + + WEAK_LEADER -> npcl(FacialExpression.ANNOYED, "Bah, people always criticise their leaders but delegating is the only way to lead. I delegate all plague issues to the mourners.").also { stage++ } + WEAK_LEADER + 1 -> playerl(FacialExpression.ANNOYED, "This whole city is a plague issue!").also { stage = END_DIALOGUE } + + NOT_LISTEN -> playerl(FacialExpression.ANNOYED, "They won't listen to me! They say I'm not properly equipped to go in the house, though I do have a very effective gas mask.").also { stage++ } + // npcl does not work + NOT_LISTEN + 1 -> npc(FacialExpression.ANNOYED, + "Hmmm, well I guess they're not taking the issue of a", + "kidnapping seriously enough. They do go a bit far", + "sometimes. I've heard of Elena, she has helped us a lot...", + "Ok, I'll give you this warrant to enter the house." + ).also { stage++ } + NOT_LISTEN + 2 -> { + if (freeSlots(player!!) == 0) { + sendItemDialogue(player!!, Items.WARRANT_1503, "Bravek waves a warrant at you, but you don't have room to take it.").also { stage = END_DIALOGUE } + } else { + sendItemDialogue(player!!, Items.WARRANT_1503, "Bravek hands you a warrant.").also { stage = END_DIALOGUE } + addItem(player!!, Items.WARRANT_1503) + setQuestStage(player!!, Quests.PLAGUE_CITY, 16) + } + } + + CURED -> playerl(FacialExpression.FRIENDLY, "Not a problem, happy to help out.").also { stage++ } + CURED + 1 -> npcl(FacialExpression.FRIENDLY, " I'm just having a little drop of whisky, then I'll feel really good.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.BRAVEK_711) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/ClerkDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/ClerkDialogue.kt new file mode 100644 index 000000000..639cd0a8b --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/ClerkDialogue.kt @@ -0,0 +1,98 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ClerkDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val TALK_AGAIN = 10 + + const val THROUGH_DOOR = 20 + const val PERMISSION = 30 + const val QUESTIONS = 40 + const val URGENT = 60 + const val RUN_EVERYTHING = 70 + const val WHEN_AVAILABLE = 80 + const val DISTURBED = 90 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (getQuestStage(player, Quests.PLAGUE_CITY) < 13) + npcl(FacialExpression.NEUTRAL, "Hello, welcome to the Civic Office of West Ardougne. How can I help you?").also { stage = QUESTIONS } + else + npcl(FacialExpression.FRIENDLY, "Bravek will see you now but keep it short!").also { stage = TALK_AGAIN } + + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + + when(stage){ + + QUESTIONS -> showTopics( + IfTopic("I need permission to enter a plague house.", PERMISSION, getQuestStage(player, Quests.PLAGUE_CITY) > 11), + Topic("Who is through that door?", THROUGH_DOOR), + Topic("I'm just looking thanks.", END_DIALOGUE), + ) + + // npcl does not wordwrap right + PERMISSION -> npc(FacialExpression.NEUTRAL, "Rather you than me! The mourners normally deal with", + "that stuff, you should speak to them. Their headquarters","are right near the city gate.").also { stage++ } + PERMISSION + 1 -> showTopics( + Topic("I'll try asking them then.", END_DIALOGUE), + Topic("Surely you don't let them run everything for you?", RUN_EVERYTHING), + Topic("This is urgent though!", URGENT, skipPlayer = true) + ) + + RUN_EVERYTHING -> npcl(FacialExpression.NEUTRAL, " Well, they do know what they're doing here. " + + "If they did start doing something badly Bravek, the city warder, would have the power to override them. " + + "I can't see that happening though.").also { stage++ } + RUN_EVERYTHING + 1 -> showTopics( + Topic("I'll try asking them then.", END_DIALOGUE), + Topic("Can I speak to Bravek anyway?", DISTURBED) + ) + + URGENT -> playerl(FacialExpression.PANICKED, " This is urgent though! Someone's been kidnapped and is being held in a plague house!").also { stage++ } + URGENT+ 1 -> npcl(FacialExpression.NEUTRAL, "I'll see what I can do I suppose.").also { stage++ } + URGENT + 2 -> npcl(FacialExpression.NEUTRAL, " Mr Bravek, there's a ${if (player.isMale) "man" else "lady"} here who really needs to speak to you.").also { + stage++ + npc = NPC(NPCs.BRAVEK_711) + } + URGENT + 3 -> npc(FacialExpression.ANNOYED, " I suppose they can come in then. If they keep it short.").also { + stage = END_DIALOGUE + setQuestStage(player, Quests.PLAGUE_CITY, 13) + } + + THROUGH_DOOR -> npcl(FacialExpression.NEUTRAL, "The city warder Bravek is in there.").also { stage++ } + THROUGH_DOOR + 1 -> playerl(FacialExpression.ASKING, " Can I go in?").also { stage = DISTURBED } + + DISTURBED -> npcl(FacialExpression.NEUTRAL, " He has asked not to be disturbed.").also { stage++ } + DISTURBED + 1 -> showTopics( + IfTopic("This is urgent though!", URGENT, getQuestStage(player, Quests.PLAGUE_CITY) > 11, skipPlayer = true), + Topic("Ok, I'll leave him alone.", END_DIALOGUE), + Topic("Do you know when he will be available?", WHEN_AVAILABLE) + ) + + WHEN_AVAILABLE -> npcl(FacialExpression.NEUTRAL, " Oh I don't know, an hour or so maybe.").also { stage = END_DIALOGUE } + + TALK_AGAIN -> playerl(FacialExpression.FRIENDLY, "Thanks, I won't take much of his time.").also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.CLERK_713) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/EdmondDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/EdmondDialogue.kt new file mode 100644 index 000000000..8b88a5c9e --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/EdmondDialogue.kt @@ -0,0 +1,268 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners +import content.region.kandarin.ardougne.quest.plaguecity.UndergroundCutscene +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class EdmondDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + val questStage = getQuestStage(player, Quests.PLAGUE_CITY) + npc = args[0] as NPC + if(inEquipmentOrInventory(player, Items.GAS_MASK_1506) && (questStage == 2)) { + playerl(FacialExpression.FRIENDLY, "Hi Edmond, I've got the gas mask now.").also { stage++ } + } + else if (questStage == 4) { + // npcl not formatted quite right + npc(FacialExpression.FRIENDLY, "I think it's the pipe to the south that comes up in West", "Ardougne.").also { stage++ } + + } + else if(questStage == 5){ + playerl( FacialExpression.NEUTRAL, + "Edmond, I can't get through to West Ardougne! There's an iron grill blocking my way, I can't pull it off alone." + ).also { stage++ } + + } + else if(questStage == 6){ + // playerl not formatted quite right + player(FacialExpression.NEUTRAL, "I've tied a rope to the grill over there, will you help me","pull it off?").also { stage++ } + + } + else if(questStage > 2) { + playerl(FacialExpression.FRIENDLY, "Hello Edmond.").also { stage++ } + } + else { + playerl(FacialExpression.FRIENDLY, "Hello old man.").also { stage++ } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + 0 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Sorry, I can't stop to talk...").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Why, what's wrong?").also { stage++ } + 3 -> npcl( + FacialExpression.FRIENDLY, + "I've got to find my daughter. I pray that she is still alive..." + ).also { stage++ } + + 4 -> options("What's happened to her?", "Well, good luck finding her.").also { stage++ } + 5 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "What's happened to her?").also { stage = 6 } + 2 -> playerl(FacialExpression.FRIENDLY, "Well, good luck finding her.").also { + stage = END_DIALOGUE + } + } + // npcl does not word wrap correctly + 6 -> npc( + FacialExpression.NEUTRAL, + "Elena's a missionary and a healer. Three weeks ago she", + "managed to cross the Ardougne wall... No-one's allowed", + "to cross the wall in case they spread the plague. But", + "after hearing the screams of suffering she felt she had" + ).also { stage++ } + + 7 -> npcl( + FacialExpression.NEUTRAL, + "to help. She said she'd be gone for a few days but we've heard nothing since." + ).also { stage++ } + + 8 -> options( + "Tell me more about the plague.", + "Can I help find her?", + "I'm sorry, I have to go." + ).also { stage++ } + + 9 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "Tell me more about the plague.").also { stage = 10 } + 2 -> playerl(FacialExpression.FRIENDLY, "Can I help find her?").also { stage = 11 } + 3 -> playerl(FacialExpression.FRIENDLY, "I'm sorry, I have to go.").also { stage = END_DIALOGUE } + } + + 10 -> npcl( + FacialExpression.FRIENDLY, + "The mourners can tell you more than me. They're the only ones allowed to cross the border. I do know the plague is a horrible way to go... That's why Elena felt she had to go help." + ).also { stage = 8 } + + 11 -> npcl( + FacialExpression.FRIENDLY, + "Really, would you? I've been working on a plan to get into West Ardougne, but I'm too old and tired to carry it through. If you're going into West Ardougne you'll need protection from the plague. My wife made a" + ).also { stage++ } + + 12 -> npcl( + FacialExpression.FRIENDLY, + "special gas mask for Elena with dwellberries rubbed into it. Dwellberries help repel the virus! We need some more though..." + ).also { stage++ } + + 13 -> playerl(FacialExpression.ASKING, "Where can I find these dwellberries?").also { stage++ } + 14 -> npcl( + FacialExpression.FRIENDLY, + "The only place I know of is McGrubor's Wood just north of the Rangers' Guild." + ).also { stage++ } + + 15 -> playerl(FacialExpression.FRIENDLY, "Ok, I'll go and get some.").also { stage++ } + 16 -> npcl( + FacialExpression.NEUTRAL, + "The foresters keep a close eye on it, but there is a back way in." + ).also { stage++ } + + 17 -> { + end() + setQuestStage(player!!, Quests.PLAGUE_CITY, 1) + } + } + + 1 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you got the dwellberries yet?").also { stage++ } + 2 -> if (!inInventory(player, Items.DWELLBERRIES_2126)) { + playerl(FacialExpression.FRIENDLY, "Sorry, I'm afraid not.").also { stage = 3 } + } else { + playerl(FacialExpression.FRIENDLY, "Yes I've got some here.").also { stage = 6 } + } + + 3 -> npcl( + FacialExpression.NEUTRAL, + "You'll probably find them in McGrubor's Wood it's just west of Seers village." + ).also { stage++ } + + 4 -> playerl(FacialExpression.NEUTRAL, "Ok, I'll go and get some.").also { stage++ } + 5 -> npcl( + FacialExpression.NEUTRAL, + "The foresters keep a close eye on it, but there is a back way in." + ).also { stage = END_DIALOGUE } + + 6 -> npcl(FacialExpression.NEUTRAL, "Take them to my wife Alrena, she's inside.").also { + stage = END_DIALOGUE + } + } + + 2 -> when (stage) { + // npcl formats this wrong + 1 -> npc( + FacialExpression.NEUTRAL, + "Good stuff, now for the digging. Beneath us are the", + "Ardougne sewers, there you'll find", + "access to West Ardougne." + ).also { stage++ } + + 2 -> npc( + FacialExpression.NEUTRAL, "The problem is the soil is rock hard. You'll need to pour", + "on several buckets of water to soften it up. I'll keep an", + "eye out for the mourners." + ).also { stage++ } + + 3 -> { + end() + setQuestStage(player!!, Quests.PLAGUE_CITY, 3) + } + } + + 3 -> when (stage) { + 1 -> if (player!!.getAttribute("/save:elena:dig", false) == true) { + playerl(FacialExpression.NEUTRAL, "I've soaked the soil with water.").also { stage = 3 } + } else { + npcl(FacialExpression.FRIENDLY, "How's it going?").also { stage = 2 } + } + + 2 -> if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 1) { + playerl( + FacialExpression.NEUTRAL, + "I still need to pour three more buckets of water on the soil." + ).also { stage = END_DIALOGUE } + } else if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 2) { + playerl( + FacialExpression.NEUTRAL, + "I still need to pour two more buckets of water on the soil." + ).also { stage = END_DIALOGUE } + } else if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 3) { + playerl( + FacialExpression.NEUTRAL, + "I still need to pour one more bucket of water on the soil." + ).also { stage = END_DIALOGUE } + } + + 3 -> npcl( + FacialExpression.FRIENDLY, + "That's great, it should be soft enough to dig through now." + ).also { stage = END_DIALOGUE } + } + + 4 -> when (stage) { + 1 -> playerl(FacialExpression.NEUTRAL, "Alright I'll check it out.").also { stage = END_DIALOGUE } + } + + 5 -> when (stage) { + 1 -> npcl( + FacialExpression.NEUTRAL, + "If you get some rope you could tie to the grill, then we could both pull it at the same time." + ).also { stage = END_DIALOGUE } + } + + 6 -> when(stage){ + 1 -> npcl(FacialExpression.NEUTRAL, "Alright, let's get to it...").also { stage++ } + 2 -> end().also{ UndergroundCutscene(player!!).start() } + } + 7-> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Not yet, it's a big city over there.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Don't forget to look for my friend Jethick. He may be able to help.").also { stage = END_DIALOGUE } + } + + 8 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Not yet, it's a big city over there. Do you have a picture of Elena?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "There should be a picture of Elena in the house. Please find her quickly, I hope it's not too late.").also { stage = END_DIALOGUE } + } + + // No source for this branch + in 9..98 -> when(stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } + 2 -> playerl(FacialExpression.SAD, "Not yet.").also { stage++ } + 3 -> npcl(FacialExpression.WORRIED, "Please find her quickly, I hope it's not too late.").also { stage = END_DIALOGUE } + } + + 99 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Thank you, thank you! Elena beat you back by minutes.").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "Now I said I'd give you a reward. What can I give you as a reward I wonder?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Here take this magic scroll, I have little use for it but it may help you.").also { stage++ } + 4 -> { + end() + player!!.questRepository.getQuest(Quests.PLAGUE_CITY).finish(player) + } + } + + 100 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Ah hello again, and thank you again for rescuing my daughter.").also { + stage = if ( + getAttribute(player, PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE, false) + || hasAnItem(player, Items.A_MAGIC_SCROLL_1505).exists()) 5 else 2 + } + 2 -> showTopics( + Topic("Do you have any more of those scrolls?", 3), + Topic("No problem.", END_DIALOGUE) + ) + 3 -> npcl(FacialExpression.FRIENDLY, "Here take this magic scroll, I have little use for it but it may help you.").also { + stage = END_DIALOGUE + addItemOrDrop(player!!, Items.A_MAGIC_SCROLL_1505) + } + 5 -> playerl(FacialExpression.NEUTRAL, "No problem.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.EDMOND_3213, NPCs.TUNNEL_EDMOND_3214) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/JethickDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/JethickDialogue.kt similarity index 60% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/JethickDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/JethickDialogue.kt index 598354db4..4ab027d70 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/JethickDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/JethickDialogue.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue +import content.data.Quests import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -15,44 +16,53 @@ class JethickDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") in 0..11) { + if (player.questRepository.getStage(Quests.PLAGUE_CITY) in 0..11) { npcl(FacialExpression.FRIENDLY, "Hello I don't recognise you. We don't get many newcomers around here.").also { stage++ } - } else if (player.questRepository.getStage("Plague City") >= 12) { + } else if (player.questRepository.getStage(Quests.PLAGUE_CITY) >= 12) { npcl(FacialExpression.FRIENDLY,"Hello. We don't get many newcomers around here.").also { stage = END_DIALOGUE } } return true } override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { in 0..1 -> when (stage) { 1 -> npcl(FacialExpression.FRIENDLY, "Well King Tyras has wandered off into the west kingdom. He doesn't care about the mess he's left here. The city warder Bravek is in charge at the moment... He's not much better.").also { stage = END_DIALOGUE } } in 7..9 -> when (stage) { - 1 -> options("Hi, I'm looking for a woman from East Ardougne called Elena.", "So who's in charge here?").also { stage++ } + 1 -> options("Hi, I'm looking for a woman from East Ardougne.", "So who's in charge here?").also { stage++ } 2 -> when (buttonID) { + // This line is authentically different than the question you click 1 -> playerl(FacialExpression.FRIENDLY, "Hi, I'm looking for a woman from East Ardougne called Elena.").also { stage = 3 } 2 -> playerl(FacialExpression.FRIENDLY, "So who's in charge here?").also { stage = END_DIALOGUE } } - 3 -> npcl(FacialExpression.FRIENDLY, "East Ardougnian women are easier to find in East Ardougne. Not many would come to West Ardougne to find one. Although the name is familiar, what does she look like?").also { stage++ } - 4 -> playerl(FacialExpression.NEUTRAL, "Um... brown hair... in her twenties...").also { stage++ } - 5 -> npcl(FacialExpression.NEUTRAL, "Hmm, that doesn't narrow it down a huge amount... I'll need to know more than that, or see a picture?").also { stage++ } - 6 -> if (inInventory(player!!, Items.PICTURE_1510)) { - sendItemDialogue(player!!, Items.PICTURE_1510, "You show Jethick the picture.").also { stage++ } + // word wrap is wrong with npcl + 3 -> npc(FacialExpression.FRIENDLY, "East Ardougnian women are easier to find in East", + "Ardougne. Not many would come to West Ardougne to", + "find one. Although the name is familiar, what does she", + "look like?").also { stage++ } + 4 -> if (inInventory(player!!, Items.PICTURE_1510)) { + sendItemDialogue(player!!, Items.PICTURE_1510, "You show Jethick the picture.").also { stage = 7 } } else { - end() - stage = END_DIALOGUE + playerl(FacialExpression.NEUTRAL, "Um... brown hair... in her twenties...").also { stage++ } } - 7 -> npcl(FacialExpression.FRIENDLY, "She came over here to help to aid plague victims. I think she is staying over with the Rehnison family. They live in the small timbered building at the far north side of town.").also { stage++ } - 8 -> npcl(FacialExpression.FRIENDLY, "I've not seen her around here for a while, mind. I don't suppose you could run me a little errand while you're over there? I borrowed this book from them, could you return it?").also { stage++ } - 9 -> options("Yes, I'll return it for you.", "No, I don't have time for that.").also { stage++ } - 10 -> when (buttonID) { - 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'll return it for you.").also { stage = 11 } + 5 -> npcl(FacialExpression.NEUTRAL, "Hmm, that doesn't narrow it down a huge amount... I'll need to know more than that, or see a picture?").also { stage = END_DIALOGUE } + + // npcl doesn't wrap right + 7 -> npc(FacialExpression.FRIENDLY, "She came over here to help to aid plague victims. I", + "think she is staying over with the Rehnison family. They", + "live in the small timbered building at the far north side", + "of town. I've not seen her around here in a while,").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "mind. ").also { stage++ } + 9 -> npcl(FacialExpression.FRIENDLY, "I don't suppose you could run me a little errand while you're over there? I borrowed this book from them, can you return it?").also { stage++ } + 10 -> options("Yes, I'll return it for you.", "No, I don't have time for that.").also { stage++ } + 11 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'll return it for you.").also { stage = 12 } 2 -> playerl(FacialExpression.NEUTRAL, "No, I don't have time for that.").also { stage = END_DIALOGUE } } - 11 -> if(freeSlots(player) == 0) { + 12 -> if(freeSlots(player) == 0) { end() sendItemDialogue(player!!, Items.BOOK_1509, "Jethick shows you the book, but you don't have room to take it.") stage = END_DIALOGUE diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/ElenaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/KidnappedElenaDialogue.kt similarity index 71% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/ElenaDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/KidnappedElenaDialogue.kt index 223bf156b..2fe574b61 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/ElenaDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/KidnappedElenaDialogue.kt @@ -1,6 +1,8 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue +import content.data.Quests import core.api.setQuestStage +import core.api.setVarbit import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -8,13 +10,14 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import core.tools.END_DIALOGUE import org.rs09.consts.NPCs +import org.rs09.consts.Vars @Initializable -class ElenaDialogue(player: Player? = null) : DialoguePlugin(player) { +class KidnappedElenaDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") >= 16) { + if (player.questRepository.getStage(Quests.PLAGUE_CITY) >= 16) { playerl(FacialExpression.FRIENDLY, "Hi, you're free to go! Your kidnappers don't seem to be about right now.").also { stage = 1 } } else { npcl(FacialExpression.FRIENDLY, "Go and see my father, I'll make sure he adequately rewards you. Now I'd better leave while I still can.").also { stage = END_DIALOGUE } @@ -29,12 +32,14 @@ class ElenaDialogue(player: Player? = null) : DialoguePlugin(player) { 3 -> npcl(FacialExpression.FRIENDLY, "Go and see my father, I'll make sure he adequately rewards you. Now I'd better leave while I still can.").also { stage++ } 4 -> { end() - setQuestStage(player!!, "Plague City", 99) + setQuestStage(player!!, Quests.PLAGUE_CITY, 99) + setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_RESCUE_ELENA, 1) + setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_EDMOND_TUNNELS, 0) stage = END_DIALOGUE } } return true } - override fun getIds(): IntArray = intArrayOf(NPCs.ELENA_3215) + override fun getIds(): IntArray = intArrayOf(NPCs.KIDNAPPED_ELENA_715) } \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MarthaRehnisonDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MarthaRehnisonDialogue.kt similarity index 89% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MarthaRehnisonDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MarthaRehnisonDialogue.kt index 79a130c2d..4b2aa051e 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MarthaRehnisonDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MarthaRehnisonDialogue.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue +import content.data.Quests import core.api.getQuestStage import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -14,7 +15,7 @@ class MarthaRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") == 9) { + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 9) { playerl(FacialExpression.NEUTRAL, "Hi, I hear a woman called Elena is staying here.").also { stage++ } } else { npcl(FacialExpression.FRIENDLY, "Any luck finding Elena yet?").also { stage++ } @@ -23,7 +24,7 @@ class MarthaRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { 9 -> when (stage) { 1 -> npcl(FacialExpression.FRIENDLY, "Yes she was staying here, but slightly over a week ago she was getting ready to go back.").also { stage++ } diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MilliRehnisonDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MilliRehnisonDialogue.kt similarity index 52% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MilliRehnisonDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MilliRehnisonDialogue.kt index 811f069d7..3f5fe54a9 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/MilliRehnisonDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MilliRehnisonDialogue.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue +import content.data.Quests import core.api.getQuestStage import core.api.setQuestStage import core.game.dialogue.DialoguePlugin @@ -15,36 +16,38 @@ class MilliRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") == 9) { + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 9) { playerl(FacialExpression.FRIENDLY, "Hello. Your parents say you saw what happened to Elena...").also { stage++ } } else { - npcl(FacialExpression.FRIENDLY, "Any luck finding Elena yet?").also { stage++ } + npcl(FacialExpression.CHILD_FRIENDLY, "Any luck finding Elena yet?").also { stage++ } } return true } override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { 9 -> when(stage) { - 1 -> npcl(FacialExpression.NEUTRAL, "*sniff* Yes I was near the south east corner when I saw Elena walking by. I was about to run to greet her when some men jumped out. They shoved a sack over her head and dragged her into a building.").also { stage++ } + // Wordwrap doesn't match using npcl + 1 -> npc(FacialExpression.CHILD_SAD, "*sniff* Yes I was near the south east corner when I", + "saw Elena walking by. I was about to run to greet her", + "when some men jumped out. They shoved a sack over", + "her head and dragged her into a building.").also { stage++ } 2 -> playerl(FacialExpression.FRIENDLY, "Which building?").also { stage++ } - 3 -> npcl(FacialExpression.NEUTRAL, "It was the boarded up building with no windows in the south east corner of West Ardougne.").also { stage++ } - 4 -> { - end() - setQuestStage(player!!, "Plague City", 11) + 3 -> npcl(FacialExpression.CHILD_NORMAL, "It was the boarded up building with no windows in the south east corner of West Ardougne.").also { stage = END_DIALOGUE + setQuestStage(player!!, Quests.PLAGUE_CITY, 11) } } in 10..98 -> when (stage) { 1 -> playerl(FacialExpression.FRIENDLY, "Not yet...").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "I wish you luck, she did a lot for us.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.CHILD_FRIENDLY, "I wish you luck, she did a lot for us.").also { stage = END_DIALOGUE } } in 99..100 -> when (stage) { 1 -> playerl(FacialExpression.FRIENDLY, "Yes, she is safe at home now.").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "That's good to hear, she helped us a lot.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.CHILD_FRIENDLY, "That's good to hear, she helped us a lot.").also { stage = END_DIALOGUE } } } return true diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/TedRehnisonDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/TedRehnisonDialogue.kt similarity index 80% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/TedRehnisonDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/TedRehnisonDialogue.kt index f7534526d..b26c60d26 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/TedRehnisonDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/TedRehnisonDialogue.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue +import content.data.Quests import core.api.getQuestStage import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -14,9 +15,9 @@ class TedRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (player.questRepository.getStage("Plague City") == 9) { + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 9) { playerl(FacialExpression.NEUTRAL, "Hi, I hear a woman called Elena is staying here.").also { stage++ } - } else if (player.questRepository.getStage("Plague City") > 9) { + } else if (player.questRepository.getStage(Quests.PLAGUE_CITY) > 9) { npcl(FacialExpression.FRIENDLY, "Any luck finding Elena yet?").also { stage++ } } else { npcl(FacialExpression.FRIENDLY, "Go away. We don't want any.").also { stage = END_DIALOGUE } @@ -25,11 +26,11 @@ class TedRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun handle(componentID: Int, buttonID: Int): Boolean { - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { 9 -> when (stage) { 1 -> npcl(FacialExpression.FRIENDLY, "Yes she was staying here, but slightly over a week ago she was getting ready to go back. However she never managed to leave. My daughter Milli was playing near the west wall when she saw some shadowy figures jump").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "out and grab her. Milli is upstairs if you wish to speak to her.").also { stage = END_DIALOGUE } + 2 -> npc(FacialExpression.FRIENDLY, "out and grab her. Milli is upstairs if you wish to speak", "to her.").also { stage = END_DIALOGUE } } in 10..98 -> when (stage) { diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerArdougneWallDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerArdougneWallDialogue.kt new file mode 100644 index 000000000..83b1c9d52 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerArdougneWallDialogue.kt @@ -0,0 +1,61 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * This is the Mourner patrolling close to the wall in E Ardougne + */ +@Initializable +class MournerArdougneWallDialogue(player: Player? = null) : DialoguePlugin(player){ + + companion object{ + const val START_DIALOGUE = 0 + const val PLAGUE = 20 + const val SYMPTOMS = 40 + } + + override fun open(vararg args: Any?): Boolean { + playerl(FacialExpression.NEUTRAL, "Hi.").also { stage = START_DIALOGUE } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.NEUTRAL, " What are you up to?").also { stage++ } + START_DIALOGUE + 1 -> playerl(FacialExpression.NEUTRAL, " Just sight-seeing.").also { stage++ } + START_DIALOGUE + 2 -> npcl(FacialExpression.NEUTRAL, "This is no place for sight-seeing. Don't you know there's been a plague outbreak?").also { stage++ } + START_DIALOGUE + 3 -> playerl(FacialExpression.NEUTRAL, " Yes, I had heard.").also { stage++ } + START_DIALOGUE + 4 -> npcl(FacialExpression.NEUTRAL, " Then I suggest you leave as soon as you can.").also { stage++ } + START_DIALOGUE + 5 -> showTopics( + Topic("What brought the plague to Ardougne?", PLAGUE), + Topic("What are the symptoms of the plague?", SYMPTOMS), + Topic("Thanks for the advice.", END_DIALOGUE), + ) + + PLAGUE -> npcl(FacialExpression.NEUTRAL, " It's all down to King Tyras of West Ardougne. " + + "'Rather than protecting his people he spends his time in the lands to the West. ").also { stage++ } + PLAGUE + 1 -> npcl(FacialExpression.NEUTRAL, "When he returned last he brought the plague with him then left before the problem became serious.").also { stage++ } + PLAGUE + 2 -> playerl(FacialExpression.ASKING, " Does he know how bad the situation is now?").also { stage++ } + PLAGUE + 3 -> npcl(FacialExpression.ANGRY, " If he did he wouldn't care. I believe he wants his people to suffer, he's an evil man.").also { stage++ } + PLAGUE + 4 -> playerl(FacialExpression.EXTREMELY_SHOCKED, " Isn't that treason?").also { stage++ } + PLAGUE + 5 -> npcl(FacialExpression.DISGUSTED_HEAD_SHAKE, " He's not my king.").also { stage = END_DIALOGUE } + + SYMPTOMS -> npcl(FacialExpression.NEUTRAL, "The first signs are typical flu symptoms. These tend to be followed by severe nightmares, horrifying hallucinations which drive many to madness.").also { stage++ } + SYMPTOMS + 1 -> playerl(FacialExpression.DISGUSTED, "Sounds nasty.").also { stage++ } + SYMPTOMS + 2 -> npcl(FacialExpression.NEUTRAL, " It gets worse. Next the victim's blood changes into a thick black tar-like liquid, at this point they're past help.").also { stage++ } + SYMPTOMS + 3 -> npcl(FacialExpression.NEUTRAL, "Their skin is cold to the touch, the victim is now brain dead. Their body however lives on driven by the virus, roaming like a zombie, spreading itself further wherever possible.").also { stage++ } + SYMPTOMS + 4 -> playerl(FacialExpression.DISGUSTED_HEAD_SHAKE, " I think I've heard enough.").also { stage = END_DIALOGUE } + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_719) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerEdmondHouseDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerEdmondHouseDialogue.kt new file mode 100644 index 000000000..97d62f0ff --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerEdmondHouseDialogue.kt @@ -0,0 +1,115 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * This is for the mourner wandering around Edmonds house + */ + +@Initializable +class MournerEdmondHouseDialogue(player: Player? = null) : DialoguePlugin(player){ + + companion object { + const val BEFORE_PLAGUE_CITY = 10 + const val BEFORE_GAS_MASK = 20 + const val BEFORE_SOFTEN_GROUND = 30 + const val SYMPTOMS1 = 40 + const val FEEL_FINE = 50 + const val PLAGUE_SOURCE1 = 60 + const val BEFORE_DIG = 70 + const val AFTER_DIG = 80 + const val AFTER_ENTER_W_ARDOUGNE = 90 + } + + override fun open(vararg args: Any?): Boolean { + when (getQuestStage(player, Quests.PLAGUE_CITY)){ + 0 -> playerl(FacialExpression.NEUTRAL, "Hello there.").also { stage = BEFORE_PLAGUE_CITY } + 1 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = BEFORE_GAS_MASK } + 2 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = BEFORE_SOFTEN_GROUND } + 3 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = BEFORE_DIG } + 4 -> playerl(FacialExpression.NEUTRAL, "Hello there.").also { stage = AFTER_DIG } + else -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = AFTER_ENTER_W_ARDOUGNE } + } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + BEFORE_PLAGUE_CITY -> npcl(FacialExpression.NEUTRAL, "Do you have a problem traveller?").also { stage++ } + BEFORE_PLAGUE_CITY + 1 -> playerl(FacialExpression.ASKING, "No, I just wondered why you're wearing that outfit... Is it fancy dress?").also { stage++ } + BEFORE_PLAGUE_CITY + 2 -> npcl(FacialExpression.NEUTRAL, "No! It's for protection.").also { stage++ } + BEFORE_PLAGUE_CITY + 3 -> playerl(FacialExpression.ASKING, "Protection from what?").also { stage++ } + BEFORE_PLAGUE_CITY + 4 -> npcl(FacialExpression.NEUTRAL, "The plague of course...").also { stage = END_DIALOGUE } + + BEFORE_GAS_MASK -> npcl(FacialExpression.NEUTRAL, "What do you want?").also { stage++ } + BEFORE_GAS_MASK + 1 -> showTopics( + Topic("Who are you?", BEFORE_GAS_MASK + 3), + Topic("Nothing, just being polite.", BEFORE_GAS_MASK + 2) + ) + BEFORE_GAS_MASK + 2 -> npcl(FacialExpression.NEUTRAL, "Hmmm, ok then. Be on your way.").also { stage = END_DIALOGUE } + BEFORE_GAS_MASK + 3 -> npcl(FacialExpression.NEUTRAL, "I'm a mourner. It's my job to help heal the plague victims of West Ardougne and to make sure the disease is contained.").also { stage++ } + BEFORE_GAS_MASK + 4 -> playerl(FacialExpression.THINKING, "Very noble of you.").also { stage++ } + BEFORE_GAS_MASK + 5 -> npcl(FacialExpression.NEUTRAL, "If you come down with any symptoms such as flu or nightmares let me know immediately.").also { stage = END_DIALOGUE } + + BEFORE_SOFTEN_GROUND -> npcl(FacialExpression.NEUTRAL, "Are you ok?").also { stage++ } + BEFORE_SOFTEN_GROUND + 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'm fine thanks.").also { stage++ } + BEFORE_SOFTEN_GROUND + 2 -> npcl(FacialExpression.NEUTRAL, "Have you experienced any plague symptoms?").also { stage++ } + BEFORE_SOFTEN_GROUND + 3 -> showTopics( + Topic("What are the symptoms?", SYMPTOMS1), + Topic("No, I feel fine", FEEL_FINE), + Topic("No, but can you tell me where the plague came from?", PLAGUE_SOURCE1) + ) + + SYMPTOMS1 -> npcl(FacialExpression.NEUTRAL, "First you'll come down with heavy flu, this is usually followed by horrifying nightmares.").also { stage++ } + SYMPTOMS1 + 1 -> playerl(FacialExpression.HALF_WORRIED, "I used to have nightmares when I was younger.").also { stage++ } + SYMPTOMS1 + 2 -> npcl(FacialExpression.NEUTRAL, "Not like these I assure you. Soon after a thick black liquid will seep from your nose and eyes.").also { stage++ } + SYMPTOMS1 + 3 -> playerl(FacialExpression.HALF_WORRIED, "Yuck!").also { stage++ } + SYMPTOMS1 + 4 -> npcl(FacialExpression.HALF_WORRIED, "When it gets to that stage there's nothing we can do for you.").also { stage = END_DIALOGUE } + + FEEL_FINE -> npcl(FacialExpression.NEUTRAL, "Well if you take a turn for the worse let me know straight away.").also { stage++ } + FEEL_FINE + 1 -> playerl(FacialExpression.HALF_WORRIED, "Can you cure it then?").also { stage++ } + FEEL_FINE + 2 -> npcl(FacialExpression.NEUTRAL, "No... But you will have to be treated.").also { stage++ } + FEEL_FINE + 3 -> playerl(FacialExpression.WORRIED, "Treated?").also { stage++ } + FEEL_FINE + 4 -> npcl(FacialExpression.NEUTRAL, "We have to take measures to contain the disease. " + + "That's why you must let us know immediately if you take a turn for the worse.").also { stage = END_DIALOGUE } + + PLAGUE_SOURCE1 -> npcl(FacialExpression.NEUTRAL, "It all started when King Tyras of West Ardougne came back from one of his visits to the lands west of here.").also { stage++ } + PLAGUE_SOURCE1 + 1 -> npcl(FacialExpression.NEUTRAL, "Some of his men must have unknowingly caught it out there and brought it back with them").also { stage = END_DIALOGUE } + + BEFORE_DIG -> npcl(FacialExpression.ASKING, "What are you up to with old man Edmond?").also { stage++ } + BEFORE_DIG + 1 -> playerl(FacialExpression.HALF_GUILTY, "Nothing, we've just been chatting.").also { stage++ } + BEFORE_DIG + 2 -> npcl(FacialExpression.ASKING, "What about his daughter?").also { stage++ } + BEFORE_DIG + 3 -> playerl(FacialExpression.HALF_GUILTY, "Oh, you know about that then?").also { stage++ } + BEFORE_DIG + 4 -> npcl(FacialExpression.NEUTRAL, "We know about everything that goes on in Ardougne. We have to if we are to contain the plague.").also { stage++ } + BEFORE_DIG + 5 -> playerl(FacialExpression.HALF_ASKING, "Have you see his daughter recently?").also { stage++ } + BEFORE_DIG + 6 -> npcl(FacialExpression.NEUTRAL, "I imagine she's caught the plague. Either way she won't be allowed out of West Ardougne, the risk is too great.").also { stage = END_DIALOGUE } + + AFTER_DIG -> npcl(FacialExpression.ASKING, "Been digging have we?").also { stage++ } + AFTER_DIG + 1 -> playerl(FacialExpression.HALF_GUILTY, "What do you mean?").also { stage++ } + AFTER_DIG + 2 -> npcl(FacialExpression.NEUTRAL, "Your hands are covered in mud.").also { stage++ } + AFTER_DIG + 3 -> playerl(FacialExpression.HALF_GUILTY, "Oh that...").also { stage++ } + AFTER_DIG + 4 -> npcl(FacialExpression.THINKING, "Funny, you don't look like the gardening type.").also { stage++ } + AFTER_DIG + 5 -> playerl(FacialExpression.NEUTRAL, "Oh no, I love gardening! It's my favorite pastime.").also { stage = END_DIALOGUE } + + AFTER_ENTER_W_ARDOUGNE -> npcl(FacialExpression.ASKING, " What are you up to?").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 1 -> playerl(FacialExpression.HALF_GUILTY, "Nothing.").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 2 -> npcl(FacialExpression.SUSPICIOUS, "I don't trust you.").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 3 -> playerl(FacialExpression.NEUTRAL, "You don't have to.").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 4 -> npcl(FacialExpression.SUSPICIOUS, "If I find you attempting to cross the wall I'll make sure you never return.").also { stage = END_DIALOGUE } + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_718) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/HeadMournerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerGuardDialogue.kt similarity index 95% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/HeadMournerDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerGuardDialogue.kt index d3e8c6d48..529554cdb 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/quest/elena/HeadMournerDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerGuardDialogue.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.quest.elena +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners +import content.data.Quests import core.api.getQuestStage import core.api.setQuestStage import core.game.dialogue.DialogueFile @@ -10,10 +11,10 @@ import core.tools.END_DIALOGUE import org.rs09.consts.NPCs @Initializable -class HeadMournerDialogue : DialogueFile() { +class MournerGuardDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - npc = NPC(NPCs.HEAD_MOURNER_716) - when (getQuestStage(player!!, PlagueCity.PlagueCityQuest)) { + npc = NPC(NPCs.MOURNER_717) + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { in 8..10 -> when (stage) { 0 -> npcl(FacialExpression.FRIENDLY, "Hmmm, how did you get over here? You're not one of this rabble. Ah well, you'll have to stay. Can't risk you going back now.").also { stage++ } @@ -37,8 +38,8 @@ class HeadMournerDialogue : DialogueFile() { 2 -> options("But I think a kidnap victim is in here.", "I fear not a mere plague.", "Thanks for the warning.").also { stage++ } 3 -> when (buttonID) { 1 -> playerl(FacialExpression.FRIENDLY, "But I think a kidnap victim is in here.").also { stage = 5 } - 2 -> playerl(FacialExpression.FRIENDLY, "I fear not a mere plague.").also { stage = 4 } - 3 -> playerl(FacialExpression.FRIENDLY, "Thanks for the warning.").also { stage = END_DIALOGUE } + 2 -> playerl(FacialExpression.FRIENDLY, "I fear not a mere plague.").also { stage = 5 } + 3 -> playerl(FacialExpression.FRIENDLY, "Thanks for the warning.").also { stage = 4 } } 4 -> playerl(FacialExpression.FRIENDLY, "Thanks for the warning.").also { stage = END_DIALOGUE } @@ -48,7 +49,7 @@ class HeadMournerDialogue : DialogueFile() { 8 -> npcl(FacialExpression.NEUTRAL, "I wouldn't get your hopes up though.").also { stage++ } 9 -> { end() - setQuestStage(player!!, "Plague City", 12) + setQuestStage(player!!, Quests.PLAGUE_CITY, 12) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerKidnapDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerKidnapDialogue.kt new file mode 100644 index 000000000..671b7d38b --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerKidnapDialogue.kt @@ -0,0 +1,184 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.global.action.DoorActionHandler +import core.game.interaction.QueueStrength +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.RegionManager +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * These are the mourners guarding the kidnap building + */ +@Initializable +class MournerKidnapDialogue(player: Player? = null) :DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MournerKidnapDialogueFile(), npc) + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_3216) + } +} + +/** + * Most of the work is in the dialogue file so the player can access this by trying to enter the room + */ +class MournerKidnapDialogueFile : DialogueFile(){ + + companion object { + const val KIDNAP = 10 + const val FEAR = 30 + const val CLEARANCE = 40 + + var closeMourner : NPC? = null + var farMourner : NPC? = null + + val eDoor: Location = Location.create(2540, 3273, 0) + val wDoor: Location = Location.create(2533, 3273, 0) + + var east = false + + } + override fun handle(componentID: Int, buttonID: Int) { + // Figure out who we are. It needs to be this since we can enter this dialogue from a door + // Do this for the first time regardless of where we are + if (stage == 0) { + RegionManager.getLocalNpcs(player!!, 2).forEach { + if (it.id == NPCs.MOURNER_3216) { + closeMourner = it + resetFace(closeMourner!!) + face(closeMourner!!, player!!) + face(player!!, closeMourner!!) + } + } + + east = player!!.location.x > 2537 + } + if (hasAnItem(player!!, Items.WARRANT_1503).exists()){ + when (stage){ + 0 -> npcl( + FacialExpression.NEUTRAL, + " I'd stand away from there. That black cross means that house has been touched by the plague." + ).also { stage++ } + + 1 -> playerl(FacialExpression.FRIENDLY, " I have a warrant from Bravek to enter here.").also { stage++ } + 2 -> npcl(FacialExpression.HALF_WORRIED, " This is highly irregular. Please wait...").also { stage++ } + 3 -> { + // Look further for the other one + RegionManager.getLocalNpcs(player!!, 10).forEach { + if (it.id == NPCs.MOURNER_3216 && it != closeMourner){ + farMourner = it + resetFace(farMourner!!) + } + } + + // I don't know why the queue has to be on this mourner to get both talking + val mournerQueue = if (east) farMourner else closeMourner + + queueScript(mournerQueue!!, 1, QueueStrength.WEAK) { animStage: Int -> + when(animStage){ + 0 -> { + end() + forceWalk(player!!, if (east) eDoor else wDoor, "smart") + face(closeMourner!!, farMourner!!) + // Legit typo + sendChat(closeMourner!!, "Hay... I got someone here with a warrant from Bravek, what should we do?") + // Immediately set the quest stage in case the player clicks again + if (getQuestStage(player!!, Quests.PLAGUE_CITY) < 17){ + setQuestStage(player!!, Quests.PLAGUE_CITY, 17) + } + return@queueScript delayScript(mournerQueue, 1) + } + 3 -> { + face(farMourner!!, closeMourner!! ) + sendChat(farMourner!!, "Well you can't let them in...") + return@queueScript delayScript(mournerQueue, 1) + } + 5 -> { + resetFace(player!!) + return@queueScript delayScript(mournerQueue, 1) + } + 6 -> { + // only walk the player if they have not walked themselves through + if (player!!.location.y > 3272) + DoorActionHandler.handleAutowalkDoor(player, getScenery (if (east) eDoor else wDoor)) + sendDialogue(player!!, "You wait until the mourner's back is turned and sneak into the building.").also { stage = END_DIALOGUE} + resetFace(closeMourner!!) + resetFace(farMourner!!) + return@queueScript delayScript(mournerQueue, 1) + } + 10 -> { + // Face north again + face(closeMourner!!, Location.create(closeMourner!!.location.x, 3275, 0)) + face(farMourner!!, Location.create(farMourner!!.location.x, 3275, 0)) + return@queueScript stopExecuting(mournerQueue) + } + } + return@queueScript delayScript(mournerQueue, 1) + } + + } + + } + } + else { + + when (stage) { + 0 -> npcl( + FacialExpression.NEUTRAL, + " I'd stand away from there. That black cross means that house has been touched by the plague." + ).also { stage = if (getQuestStage(player!!, Quests.PLAGUE_CITY) == 11) stage + 1 else END_DIALOGUE } + + 1 -> showTopics( + Topic("But I think a kidnap victim is in here.", KIDNAP), + Topic("I fear not a mere plague.", FEAR), + Topic("Thanks for the warning.", END_DIALOGUE), + ) + + KIDNAP -> npcl( + FacialExpression.NEUTRAL, + "Sounds unlikely, even kidnappers wouldn't go in there. Even if someone is in there, they're probably dead by now." + ).also { stage++ } + + KIDNAP + 1 -> showTopics( + Topic("Good point.", END_DIALOGUE), + Topic("I want to check anyway.", KIDNAP + 2) + ) + + KIDNAP + 2 -> npcl(FacialExpression.NEUTRAL, "You don't have clearance to go in there.").also { + stage = CLEARANCE + } + + FEAR -> npcl( + FacialExpression.NEUTRAL, + " That's irrelevant. You don't have clearance to go in there." + ).also { stage = CLEARANCE } + + CLEARANCE -> playerl(FacialExpression.ASKING, " How do I get clearance?").also { stage++ } + CLEARANCE + 1 -> npcl( + FacialExpression.NEUTRAL, + " Well you'd need to apply to the head mourner, or I suppose Bravek the city warder." + ).also { stage++ } + + CLEARANCE + 2 -> npcl(FacialExpression.NEUTRAL, " I wouldn't get your hopes up though.").also { + stage = END_DIALOGUE + setQuestStage(player!!, Quests.PLAGUE_CITY, 12) + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java index a7b3ccf2c..4f3dee3c2 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java @@ -5,6 +5,7 @@ import core.plugin.Initializable; import core.game.dialogue.DialoguePlugin; import core.api.*; import org.rs09.consts.Items; +import content.data.Quests; @Initializable public class HalgriveDialogue extends DialoguePlugin { @@ -21,7 +22,7 @@ public class HalgriveDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - if(player.getQuestRepository().getStage("Sheep Herder") < 10) { + if(player.getQuestRepository().getStage(Quests.SHEEP_HERDER) < 10) { player("Hello. How are you?"); stage = 0; return true; @@ -116,7 +117,7 @@ public class HalgriveDialogue extends DialoguePlugin { stage++; break; case 105: - player.getQuestRepository().getQuest("Sheep Herder").start(player); + player.getQuestRepository().getQuest(Quests.SHEEP_HERDER).start(player); player.getDialogueInterpreter().sendDialogue("The councillor gives you some poisoned sheep feed."); player.getInventory().add(SheepHerder.POISON); stage++; @@ -168,7 +169,7 @@ public class HalgriveDialogue extends DialoguePlugin { stage++; break; case 207: - player.getQuestRepository().getQuest("Sheep Herder").finish(player); + player.getQuestRepository().getQuest(Quests.SHEEP_HERDER).finish(player); end(); break; } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java index ec371b44a..55efedcf1 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java @@ -5,6 +5,7 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.plugin.Initializable; import core.game.dialogue.DialoguePlugin; +import content.data.Quests; @Initializable public class OrbonDialogue extends DialoguePlugin { @@ -21,7 +22,7 @@ public class OrbonDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - if(player.getQuestRepository().getStage("Sheep Herder") == 10){ + if(player.getQuestRepository().getStage(Quests.SHEEP_HERDER) == 10){ player("Hello doctor. I need to acquire some protective clothing","so that I can dispose of some escaped sheep infected","with the plague."); stage = 100; return true; diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java index f7a28c03b..75ed87dbf 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java @@ -10,6 +10,7 @@ import core.plugin.Initializable; import org.rs09.consts.Items; import java.util.HashMap; +import content.data.Quests; @Initializable public class SheepHerder extends Quest { @@ -35,39 +36,71 @@ public class SheepHerder extends Quest { boneMap.put(BLUE_SHEEP,BLUE_SHEEP_BONES); } - public SheepHerder(){super("Sheep Herder",113,112,4,60,0,1,3);} + public SheepHerder(){super(Quests.SHEEP_HERDER,113,112,4,60,0,1,3);} @Override public void drawJournal(Player player, int stage) { boolean hasGear = (player.getInventory().containsItem(PLAGUE_BOTTOM) && player.getInventory().containsItem(PLAGUE_TOP) || (player.getEquipment().containsItem(PLAGUE_BOTTOM) && player.getEquipment().containsItem(PLAGUE_TOP))) || stage >= 20; - int line = 11; + int line = 12; boolean sheepDead = player.getAttribute("sheep_herder:all_dead",false); super.drawJournal(player, stage); - if(stage < 10){ - line(player,"I can start this quest by speaking to !!Councillor Halgrive??",line++); - line(player, "near to the !!Zoo?? in !!East Ardougne.??",line++); + if(stage == 0){ + line(player,"I can start this quest by speaking to !!Councillor Halgrive??", line++); + line(player, "near to the !!Zoo?? in !!East Ardougne??.", line++); } else { - switch(stage){ - case 10: - line(player, "!!Councillor Halgrive?? said I should speak to !!Doctor Orbon?? about", line++, hasGear); - line(player, "Getting some protective gear.", line++, hasGear); - line(player, "I need to !!locate the diseased sheep?? and corral them !!into the pin??", line++,sheepDead); - line(player, "After which, I need to !!poison them?? and !!incinerate their bones.??", line++,sheepDead); - if(sheepDead) { - line(player,"I should inform !!Councillor Halgrive?? that I have taken care of the problem.",line++); + line(player,"Councillor Halgrive asked me to dispose of four plague", line++, true); + line(player,"bearing sheep just north of Ardougne and I accepted.", line++, true); + line(player,"He gave me some poisoned sheep feed to do this.", line++, true); + if(hasGear) { + line(player, "I bought some protective clothing from Dr. Orbon in the", line++, true); + line(player, "chapel north of Ardougne Zoo. I could now kill the sheep.", line++, true); + } else { + line(player, "!!Councillor Halgrive?? said I should speak to !!Doctor Orbon??", line++); + line(player, "about getting some protective gear.", line++); + } + if(stage == 10) { + // This is not authentic. +// line(player, "I need to !!locate the diseased sheep?? and corral them !!into the pen??", line++,sheepDead); +// line(player, "After which, I need to !!poison them?? and !!incinerate their bones.??", line++,sheepDead); + line++; + if (sheepDead) { + line(player, "I equipped a prod and then I used it to to herd the diseased", line++, true); + line(player, "sheep to a pen where I could safely kill them and", line++, true); + line(player, "incinerate their bones.", line++, true); + line(player,"I should return to !!Councillor Halgrive?? to collect the reward", line++); + line(player,"he has promised me for my hard work.", line++); + } else { + if (player.getAttribute("sheep_herder:red_dead", false)) { + line(player, "I have killed the first sheep and incinerated its bones.", line++, true); } else { - line(player, "I still need:", line++); - line(player, "A !!Red Sheep??", line++, player.getAttribute("sheep_herder:red_dead", false)); - line(player, "A !!Blue Sheep??", line++, player.getAttribute("sheep_herder:blue_dead", false)); - line(player, "A !!Green Sheep??", line++, player.getAttribute("sheep_herder:green_dead", false)); - line(player, "A !!Yellow Sheep??", line++, player.getAttribute("sheep_herder:yellow_dead", false)); + line(player, "I must find the first sheep and herd it to the special pen.", line++); } - break; - case 100: - line(player,"I helped Councillor Halgrive by putting down",line++,true); - line(player,"plague-bearing sheep.",line++,true); - line(player,"%%QUEST COMPLETE!&&",line++); - break; + if (player.getAttribute("sheep_herder:green_dead", false)) { + line(player, "I have killed the second sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the second sheep and herd it to the special", line++); + line(player, "pen.", line++); + } + if (player.getAttribute("sheep_herder:blue_dead", false)) { + line(player, "I have killed the third sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the third sheep and herd it to the special pen.", line++); + } + if (player.getAttribute("sheep_herder:yellow_dead", false)) { + line(player, "I have killed the fourth sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the fourth sheep and herd it to the special pen.", line++); + } + } + } + + if(stage >= 100) { + line(player, "I equipped a prod to herd the diseased sheep and then I", line++, true); + line(player, "used it to incinerate all four plagued sheep.", line++, true); + line(player, "I returned to let Councillor Halgrive know that the plagued", line++, true); + line(player, "sheep were no more and claimed my reward.", line++, true); + line++; + line(player, "%%QUEST COMPLETE!&&", line++, false); } } } diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/MournerUtilities.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/MournerUtilities.kt new file mode 100644 index 000000000..461a15a54 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/MournerUtilities.kt @@ -0,0 +1,57 @@ +package content.region.kandarin.ardougne.westardougne + +import core.api.EquipmentSlot +import core.api.allInEquipment +import core.api.getItemFromEquipment +import core.api.inEquipment +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +object MournerUtilities { + + const val NO_GEAR = 0 + const val JUST_MASK = 1 + const val JUST_GEAR = 2 + const val EXTRA_GEAR = 3 + + /** + * Check if the player is wearing just mourner gear + * @return 0 incomplete gear 1 mask only 2 complete gear only 3 complete gear with extras + */ + fun wearingMournerGear(player: Player): Int { + // Check that the play has all of these items + if (inEquipment(player, Items.GAS_MASK_1506)) { + // We have a mask + if (!allInEquipment( + player, Items.MOURNER_TOP_6065, Items.MOURNER_TROUSERS_6067, + Items.MOURNER_BOOTS_6069, Items.MOURNER_GLOVES_6068, Items.MOURNER_CLOAK_6070 + ) + ) { + // We have only a mask + return JUST_MASK + } + else { + // Check if we have other gear + + // These use up slots 0, 1, 4, 7, 9, 10. Check the others are empty + val mournerSlots = arrayOf( + EquipmentSlot.HEAD, EquipmentSlot.CAPE, EquipmentSlot.CHEST, + EquipmentSlot.LEGS, EquipmentSlot.HANDS, EquipmentSlot.FEET + ) + for (slot in EquipmentSlot.values()) { + // Skip the slots that we know have the gear equipped + if (mournerSlots.contains(slot)) continue + if (getItemFromEquipment(player, slot) != null) { + return EXTRA_GEAR + } + } + return JUST_GEAR + } + + } + else { + // We don't even have a mask + return NO_GEAR + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/CarlaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CarlaDialogue.kt similarity index 98% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/CarlaDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CarlaDialogue.kt index 8e1ea65e5..a3431f603 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/CarlaDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CarlaDialogue.kt @@ -1,4 +1,4 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue +package content.region.kandarin.ardougne.westardougne.dialogue import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/ChildDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ChildDialogue.kt similarity index 64% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/ChildDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ChildDialogue.kt index 96cbd880d..210d0ee8d 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/ChildDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ChildDialogue.kt @@ -1,5 +1,6 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue +package content.region.kandarin.ardougne.westardougne.dialogue +import content.region.kandarin.ardougne.westardougne.MournerUtilities import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -18,9 +19,8 @@ class ChildDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - 0 -> npcl(FacialExpression.FRIENDLY, "I'm not allowed to speak with strangers.").also { stage = END_DIALOGUE } - } + val noun = if (MournerUtilities.wearingMournerGear(player) > MournerUtilities.JUST_MASK) "mourners" else "strangers" + npcl(FacialExpression.CHILD_NORMAL, "I'm not allowed to speak with $noun.").also { stage = END_DIALOGUE } return true } @@ -29,7 +29,7 @@ class ChildDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun getIds(): IntArray { - return intArrayOf(NPCs.CHILD_6339, NPCs.CHILD_6345, NPCs.CHILD_356) + return intArrayOf(NPCs.CHILD_356, NPCs.CHILD_355) } } \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CivilianDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CivilianDialogue.kt new file mode 100644 index 000000000..dcf6f73fa --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CivilianDialogue.kt @@ -0,0 +1,181 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.region.kandarin.ardougne.westardougne.MournerUtilities +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +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, + // todo implement these cats then uncomment this + // otherwise you get an exception which just steals your cat for no runes + // Items.LAZY_CAT_6549, + // Items.LAZY_CAT_6550, + // 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, +) + +@Initializable +class CivilianDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + // Any of these + + + const val DIAG1 = 10 + const val DIAG2 = 20 + const val DIAG3 = 30 + + const val NO_CAT = 40 + const val BUY_CATS = 50 + const val REJECT_DEAL = 80 + const val WITCH_CAT = 90 + + const val MOURNER = 100 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (MournerUtilities.wearingMournerGear(player) > MournerUtilities.JUST_MASK){ + playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = MOURNER } + } + else { + when (npc.id) { + NPCs.CIVILIAN_785 -> playerl(FacialExpression.NEUTRAL, "Hello there.").also { stage = DIAG1 } + NPCs.CIVILIAN_786 -> playerl(FacialExpression.NEUTRAL, "Hi there.").also { stage = DIAG2 } + NPCs.CIVILIAN_787 -> player(FacialExpression.NEUTRAL, "Hello there.").also { stage = DIAG3 } + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + DIAG1 -> npcl(FacialExpression.HALF_GUILTY, "Oh hello, I'm sorry, I'm a bit worn out.").also { stage++ } + DIAG1 + 1 -> playerl(FacialExpression.NEUTRAL, "Busy day?").also { stage++ } + DIAG1 + 2 -> npcl(FacialExpression.HALF_GUILTY, "Oh, It's those mice! They're everywhere! " + + "What I really need is a cat. But they're hard to come by nowadays.").also { + stage = checkCat() + } + + DIAG2 -> npcl(FacialExpression.NEUTRAL, "Good day to you traveller.").also { stage++ } + DIAG2 + 1 -> playerl(FacialExpression.NEUTRAL, "What are you up to?").also { stage++ } + DIAG2 + 2 -> npcl(FacialExpression.NEUTRAL, "Chasing mice as usual! It's all I seem to do nowadays.").also { stage++ } + DIAG2 + 3 -> playerl(FacialExpression.NEUTRAL, "You must waste a lot of time?").also { stage++ } + DIAG2 + 4 -> npcl(FacialExpression.HALF_WORRIED, "Yes, but what can you do? It's not like there's many cats around here!").also{ stage = checkCat() + } + + DIAG3 -> npcl(FacialExpression.HALF_WORRIED, "I'm a bit busy to talk right now, sorry.").also { stage++ } + DIAG3 + 1 -> playerl(FacialExpression.NEUTRAL, "Why? What are you doing?").also { stage++ } + DIAG3 + 2 -> npcl(FacialExpression.HALF_WORRIED, "Trying to kill these mice! What I really need is a cat!").also { stage = checkCat() } + + NO_CAT -> playerl(FacialExpression.HALF_WORRIED, "No, you're right, you don't see many around.").also { stage = END_DIALOGUE } + + BUY_CATS -> showTopics( + Topic("I have a cat that I could sell.", BUY_CATS + 1), + Topic("Nope, they're not easy to get hold of.", END_DIALOGUE) + ) + // intentional whitespace typo + BUY_CATS + 1 -> npcl(FacialExpression.ASKING, "You don't say, is that it ?").also { stage++ } + BUY_CATS + 2 -> playerl(FacialExpression.HAPPY, "Say hello to a real mouse killer!").also { stage++ } + BUY_CATS + 3 -> npcl(FacialExpression.HALF_ASKING, "Hmmm, not bad, not bad at all. Looks like it's a lively one.").also { stage++ } + BUY_CATS + 4 -> playerl(FacialExpression.HALF_GUILTY, "Erm...kind of...").also { stage++ } + BUY_CATS + 5 -> npcl(FacialExpression.FRIENDLY, "I don't have much in the way of money. I do have these!").also { stage++ } + BUY_CATS + 6 -> sendDialogue("The peasant shows you a sack of Death Runes.").also { stage++ } + BUY_CATS + 7 -> npcl(FacialExpression.ASKING, "The dwarves bring them from the mine for us. Tell you what, I'll give you 100 Death Runes for the cat.").also { stage++ } + BUY_CATS + 8 -> showTopics( + Topic("Nope, I'm not parting for that.", REJECT_DEAL), + Topic("Ok then, you've got a deal.", BUY_CATS+9) + ) + BUY_CATS + 9 -> { + npcl(FacialExpression.HAPPY, "Great! Hand over the cat and I'll give you the runes.").also { + stage = END_DIALOGUE + for (cat in cats) { + if (removeItem(player, cat)){ + player.familiarManager.removeDetails(cat) + addItem(player, Items.DEATH_RUNE_560, 100) + break + } + } + } + } + + REJECT_DEAL -> npcl(FacialExpression.HALF_GUILTY, "Well, I'm not giving you anymore!").also { stage = END_DIALOGUE } + + WITCH_CAT -> playerl(FacialExpression.HAPPY, "I have a cat...look!").also { stage++ } + WITCH_CAT + 1 -> npcl(FacialExpression.HALF_WORRIED, "Hmmm...doesn't look like it's seen daylight in years. That's not going to catch any mice!").also { stage = END_DIALOGUE } + + + MOURNER -> npcl(FacialExpression.ANGRY, "If you Mourners really wanna help, why don't you do something about these mice?!").also { stage = END_DIALOGUE } + } + return true + } + + private fun checkCat(): Int { + return if (anyInInventory(player, *cats)) BUY_CATS + else if (inInventory(player, Items.WITCHS_CAT_1491)) WITCH_CAT + else NO_CAT + + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CIVILIAN_785, NPCs.CIVILIAN_786, NPCs.CIVILIAN_787) + } +} + + +class CatTrade : InteractionListener{ + override fun defineListeners() { + + class CatTradeDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when (stage){ + 0 -> sendDialogue(player!!, "You hand over the cat. You are given 100 Death Runes.").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Great, thanks for that!").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "That's ok, take care.").also { stage = END_DIALOGUE } + } + } + } + onUseWith(IntType.NPC, cats, NPCs.CIVILIAN_785, NPCs.CIVILIAN_786, NPCs.CIVILIAN_787){ player, used, with -> + if(removeItem(player, used)){ + val dialogue = CatTradeDialogue() + // Remove the cat + player.familiarManager.removeDetails(used.id) + addItem(player, Items.DEATH_RUNE_560, 100) + openDialogue(player, dialogue, with as NPC) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/HeadMournerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/HeadMournerDialogue.kt new file mode 100644 index 000000000..65671e952 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/HeadMournerDialogue.kt @@ -0,0 +1,115 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import content.region.kandarin.ardougne.westardougne.MournerUtilities +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import kotlin.properties.Delegates + +@Initializable +class HeadMournerDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + const val CLEARANCE = 40 + const val WHATS_A_MOURNER = 10 + const val NO_PLAGUE = 20 + const val ELENA = 30 + + const val CRAZY = 50 + const val KIDNAP = 60 + const val MASK = 70 + + var mourningGear by Delegates.notNull() + + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + mourningGear = MournerUtilities.wearingMournerGear(player) + if(mourningGear < MournerUtilities.JUST_GEAR){ + npcl(FacialExpression.ANGRY, "How did you get into West Ardougne? " + + "Ah well you'll have to stay, can't risk you spreading the plague outside.").also { stage++ } + } + else{ + npcl(FacialExpression.NEUTRAL, "Ahh... A new recruit.").also { stage++ } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(mourningGear){ + MournerUtilities.NO_GEAR, MournerUtilities.JUST_MASK -> when(stage){ + START_DIALOGUE + 1 -> showTopics( + IfTopic("I need clearance to enter a plague house.", CLEARANCE, + !isQuestComplete(player, Quests.PLAGUE_CITY) && (getQuestStage(player, Quests.PLAGUE_CITY) > 11)), + Topic("So what's a mourner?", WHATS_A_MOURNER), + Topic("I haven't got the plague though. ", NO_PLAGUE), + IfTopic("I'm looking for a woman named Elena.", ELENA, !isQuestComplete(player, Quests.PLAGUE_CITY)) + ) + + CLEARANCE -> npcl(FacialExpression.DISGUSTED, "You must be nuts, absolutely not!").also { stage++ } + CLEARANCE + 1 -> showTopics( + Topic("There's a kidnap victim inside!", KIDNAP), + Topic("I've got a gas mask though...", MASK), + Topic("Yes, I'm utterly crazy.", CRAZY) + ) + + KIDNAP -> npcl(FacialExpression.FRIENDLY, "Well they're as good as dead then, no point in trying to save them.").also { stage = END_DIALOGUE } + + MASK -> npcl(FacialExpression.FRIENDLY, "It's not regulation. Anyway you're not properly trained to deal with the plague.").also { stage++ } + MASK + 1 -> playerl(FacialExpression.FRIENDLY, "How do I get trained?").also { stage++ } + MASK + 2 -> npcl(FacialExpression.FRIENDLY, "It requires a strict 18 months of training.").also { stage++ } + MASK + 3 -> playerl(FacialExpression.FRIENDLY, "I don't have that sort of time.").also { stage = END_DIALOGUE } + + CRAZY -> npcl(FacialExpression.FRIENDLY, "You're wasting my time, I have a lot of work to do!").also { stage = END_DIALOGUE } + + WHATS_A_MOURNER -> npcl(FacialExpression.NEUTRAL, + "We're working for King Lathas of East Ardougne trying to contain the accursed plague sweeping West Ardougne." + + " We also do our best to ease these people's suffering.").also { stage++ } + WHATS_A_MOURNER + 1 -> npcl(FacialExpression.NEUTRAL, "We're nicknamed mourners because we spend a lot of" + + " time at plague victim funerals, no-one else is allowed to risk the funerals." + + " It's a demanding job, and we get little thanks from the people here.").also { stage = END_DIALOGUE } + + NO_PLAGUE -> npcl(FacialExpression.ANNOYED, "Can't risk you being a carrier. That protective clothing you have isn't regulation issue. It won't meet safety standards.").also { stage = END_DIALOGUE } + + ELENA -> npcl( + FacialExpression.NEUTRAL, + "Ah yes, I've heard of her. A healer I believe. She must be mad coming over here voluntarily." + ).also { stage++ } + + ELENA + 1 -> npcl( + FacialExpression.SAD, + "I hear rumours she has probably caught the plague now. Very tragic, a stupid waste of life." + ).also { stage = END_DIALOGUE } + + } + + MournerUtilities.JUST_GEAR, MournerUtilities.EXTRA_GEAR -> when(stage){ + START_DIALOGUE+1 ->playerl(FacialExpression.ASKING, " How do you know I'm new?").also { stage++ } + START_DIALOGUE+2 -> npcl(FacialExpression.NEUTRAL, "Because all the old members of the guard know to report to the real Head Mourner, not me.").also { if (mourningGear == MournerUtilities.EXTRA_GEAR) stage++ else stage+=2 } + START_DIALOGUE+3 -> npcl(FacialExpression.ANNOYED, "Also, none of the old timers use non-regulation gear.").also { stage++ } + START_DIALOGUE+4 -> playerl(FacialExpression.ASKING, " You're not the real overseer here?").also { stage++ } + START_DIALOGUE+5 -> npcl(FacialExpression.NEUTRAL, "No, I am just a front man, our true head is far too busy to deal with the requests of the citizens, so I conduct the day to day business here.").also { stage++ } + START_DIALOGUE+6 -> npcl(FacialExpression.NEUTRAL, "You should go and report in" + if(mourningGear == MournerUtilities.EXTRA_GEAR) ", I would lose the non-regulation gear as well if I were you." else "." ).also { stage++ } + START_DIALOGUE+7 -> playerl(FacialExpression.FRIENDLY, "Okay, thanks.").also { stage = END_DIALOGUE } + } + } + return true + } + + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HEAD_MOURNER_716) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ManWomanDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ManWomanDialogue.kt new file mode 100644 index 000000000..a86698f3d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ManWomanDialogue.kt @@ -0,0 +1,81 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class ManWomanDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + const val DIAG1 = 10 + const val DIAG2 = 20 + const val DIAG3 = 30 + const val DIAG4 = 40 + const val DIAG5 = 50 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val path = RandomFunction.random(1, 6) + val msg = when(path){ + 1,5 -> "Good day." + 2 -> "Hi there." + 3, 4 -> "Hello, how's it going?" + else -> "Hello" + } + + playerl(FacialExpression.FRIENDLY, msg).also { stage = path * 10 } + + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (stage){ + DIAG1 -> npcl(FacialExpression.HALF_ASKING, "An outsider! Can you get me out of this hell hole?").also { stage++ } + DIAG1 + 1 -> playerl(FacialExpression.SAD, "Sorry, that's not what I'm here to do.").also { stage = END_DIALOGUE } + + DIAG2 -> npcl(FacialExpression.ANNOYED, "Go away. People from the outside shut us in like animals. I have nothing to say to you.").also { stage = END_DIALOGUE } + + DIAG3 -> npcl(FacialExpression.SAD, "Life is tough.").also { stage++ } + DIAG3 + 1 -> showTopics( + Topic("Yes, living in a plague city must be hard.", DIAG3 + 2), + Topic("I'm sorry to hear that.", DIAG3 + 3), + Topic("I'm looking for a lady called Elena.", DIAG3 + 4) + ) + DIAG3 + 2 -> npcl(FacialExpression.HALF_GUILTY, "Plague? Pah, that's no excuse for the treatment we've received. It's obvious pretty quickly if someone has the plague. I'm thinking about making a break for it. I'm perfectly healthy, not gonna infect anyone.").also { stage = END_DIALOGUE } + DIAG3 + 3 -> npcl(FacialExpression.SAD, "Well, aint much either you or me can do about it.").also { stage = END_DIALOGUE } + DIAG3 + 4 -> npcl(FacialExpression.NEUTRAL, "I've not heard of her. Old Jethick knows a lot of people, maybe he'll know where you can find her.").also { stage = END_DIALOGUE } + + DIAG4 -> npcl(FacialExpression.ANNOYED, "Bah, those mourners... they're meant to be helping us, but I think they're doing more harm here than good. They won't even let me send a letter out to my family.").also{ stage++} + DIAG4 + 1 -> showTopics( + Topic("Have you seen a lady called Elena around here?", DIAG4 + 2), + Topic("You should stand up to them more.", DIAG4 + 3) + ) + DIAG4 + 2 -> npcl(FacialExpression.SAD, "Yes, I've seen her. Very helpful person. Not for the last few days though... I thought maybe she'd gone home.").also { stage = END_DIALOGUE } + DIAG4 + 3 -> npcl(FacialExpression.HALF_GUILTY, " Oh I'm not one to cause a fuss.").also { stage = END_DIALOGUE } + + DIAG5 -> npcl(FacialExpression.ANGRY, "We don't have good days here anymore. Curse King Tyras.").also { stage++ } + DIAG5 + 1 -> showTopics( + Topic("Oh ok, bad day then.", END_DIALOGUE), + Topic("Why, what has he done?", DIAG5 + 2), + Topic("I'm looking for a woman called Elena.", DIAG5 + 3) + ) + DIAG5 + 2 -> npcl(FacialExpression.ANGRY, "His army curses our city with this plague then wanders off again, leaving us to clear up the pieces.").also { stage = END_DIALOGUE } + DIAG5 + 3 -> npcl(FacialExpression.NEUTRAL, "Not heard of her.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + + return intArrayOf(NPCs.MAN_728, NPCs.MAN_729, NPCs.MAN_351, + NPCs.WOMAN_352, NPCs.WOMAN_353, NPCs.WOMAN_354, NPCs.WOMAN_360, NPCs.WOMAN_361, NPCs.WOMAN_362, NPCs.WOMAN_363) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/MournerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/MournerDialogue.kt new file mode 100644 index 000000000..da0ef56ae --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/MournerDialogue.kt @@ -0,0 +1,114 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import content.region.kandarin.ardougne.westardougne.MournerUtilities.EXTRA_GEAR +import content.region.kandarin.ardougne.westardougne.MournerUtilities.JUST_GEAR +import content.region.kandarin.ardougne.westardougne.MournerUtilities.JUST_MASK +import content.region.kandarin.ardougne.westardougne.MournerUtilities.NO_GEAR +import content.region.kandarin.ardougne.westardougne.MournerUtilities.wearingMournerGear +import core.api.getQuestStage +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MournerDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val WHATS_A_MOURNER = 10 + const val NO_PLAGUE = 20 + const val ELENA = 30 + + const val CONVO_1 = 40 + const val CONVO_2 = 50 + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(wearingMournerGear(player)){ + NO_GEAR, JUST_MASK -> { + if (npc.id == NPCs.MOURNER_717) { + when (stage) { + 0 -> npcl( + FacialExpression.HALF_ASKING, + "Hmmm, how did you get over here? You're not one of this rabble. Ah well, you'll have to stay. Can't risk you going back now." + ).also { stage++ } + + 1 -> showTopics( + Topic("So what's a mourner?", WHATS_A_MOURNER), + Topic("I haven't got the plague though... ", NO_PLAGUE), + IfTopic( + "I'm looking for a woman named Elena.", + ELENA, + getQuestStage(player, Quests.PLAGUE_CITY) in (6..98) + ) + ) + + WHATS_A_MOURNER -> npcl( + FacialExpression.NEUTRAL, + "We're working for King Lathas of East Ardougne trying to contain the accursed plague sweeping West Ardougne." + + " We also do our best to ease these people's suffering." + ).also { stage++ } + + WHATS_A_MOURNER + 1 -> npcl( + FacialExpression.NEUTRAL, "We're nicknamed mourners because we spend a lot of" + + " time at plague victim funerals, no-one else is allowed to risk the funerals." + + " It's a demanding job, and we get little thanks from the people here." + ).also { stage = END_DIALOGUE } + + ELENA -> npcl( + FacialExpression.NEUTRAL, + "Ah yes, I've heard of her. A healer I believe. She must be mad coming over here voluntarily." + ).also { stage++ } + + ELENA + 1 -> npcl( + FacialExpression.SAD, + "I hear rumours she has probably caught the plague now. Very tragic, a stupid waste of life." + ).also { stage = END_DIALOGUE } + + NO_PLAGUE -> npcl( + FacialExpression.ANNOYED, + "Can't risk you being a carrier. That protective clothing you have isn't regulation issue. It won't meet safety standards." + ).also { stage = END_DIALOGUE } + } + } + else{ + npcl(FacialExpression.ANNOYED, "Stand back citizen, do not approach me.").also { stage = END_DIALOGUE } + } + + } + JUST_GEAR -> { + when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { + stage = if((0..1).random() > 0) CONVO_1 else CONVO_2 + } + + CONVO_1 -> npcl(FacialExpression.NEUTRAL, "Good day. Are you in need of assistance?").also { stage++ } + CONVO_1 + 1 -> playerl(FacialExpression.NEUTRAL, " Yes, but I don't think you can help.").also { stage++ } + CONVO_1 + 2 -> npcl(FacialExpression.NEUTRAL, " You will be surprised at how much help the brute force of the Guard can be.").also { stage++ } + CONVO_1 + 3 -> playerl(FacialExpression.NEUTRAL, " Well I'll be sure to ask if I'm in need of some muscle.").also { stage = END_DIALOGUE } + + CONVO_2 -> npcl(FacialExpression.ANNOYED, " Good day. Are you in need of assistance?").also { stage++ } + CONVO_2 + 1 -> playerl(FacialExpression.NEUTRAL, " No, I just wanted to talk to a friendly face.").also { stage++ } + CONVO_2 + 2 -> npcl(FacialExpression.ANGRY, " Do I look friendly to you? I really must work on my scowl more.").also { stage = END_DIALOGUE } + } + + } + EXTRA_GEAR -> { + when(stage){ + 0 -> npcl(FacialExpression.ANNOYED, "You should know better than to wear non-regulation gear.").also { stage++ } + 1 -> playerl(FacialExpression.HALF_GUILTY, "Sorry, I'm new around here.").also { stage++ } + 2 -> npcl(FacialExpression.ANNOYED, "Well, you know the drill - lose the gear, I will let it pass this time.").also { stage = END_DIALOGUE } + } + } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_717, NPCs.MOURNER_348, NPCs.MOURNER_347, NPCs.MOURNER_371, NPCs.MOURNER_369) + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/NurseSarahDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/NurseSarahDialogue.kt similarity index 87% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/NurseSarahDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/NurseSarahDialogue.kt index d628c9cef..fd7fbcd9b 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/NurseSarahDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/NurseSarahDialogue.kt @@ -1,4 +1,4 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue +package content.region.kandarin.ardougne.westardougne.dialogue import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -20,7 +20,7 @@ class NurseSarahDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { when (stage) { 0 -> npcl(FacialExpression.FRIENDLY, "Hello my dear, how are you feeling?").also { stage++ } - 1 -> playerl(FacialExpression.FRIENDLY, "Hello my dear, how are you feeling?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "I'm ok thanks.").also { stage++ } 2 -> npcl(FacialExpression.FRIENDLY, "Well in that case I'd better get back to work. Take care.").also { stage++ } 3 -> playerl(FacialExpression.FRIENDLY, "You too.").also { stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/PriestDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/PriestDialogue.kt similarity index 94% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/PriestDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/PriestDialogue.kt index 6e035d659..472884667 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/PriestDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/PriestDialogue.kt @@ -1,4 +1,4 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue +package content.region.kandarin.ardougne.westardougne.dialogue import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression diff --git a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/RecruiterDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/RecruiterDialogue.kt similarity index 95% rename from Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/RecruiterDialogue.kt rename to Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/RecruiterDialogue.kt index 672414c02..3e53af8c2 100644 --- a/Server/src/main/content/region/kandarin/ardougne/plaguecity/dialogue/RecruiterDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/RecruiterDialogue.kt @@ -1,4 +1,4 @@ -package content.region.kandarin.ardougne.plaguecity.dialogue +package content.region.kandarin.ardougne.westardougne.dialogue import core.api.sendNPCDialogue import core.game.dialogue.DialoguePlugin diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MainGatesListener.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MainGatesListener.kt new file mode 100644 index 000000000..82a8cd5e3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MainGatesListener.kt @@ -0,0 +1,32 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class MainGatesListener : InteractionListener { + + override fun defineListeners() { + on(intArrayOf(Scenery.ARDOUGNE_WALL_DOOR_9738, Scenery.ARDOUGNE_WALL_DOOR_9330), IntType.SCENERY, "open") { player, node -> + if (hasRequirement(player, Quests.BIOHAZARD)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if(inBorders(player, 2556, 3298, 2557, 3301)){ + lock(player,2) + sendMessage(player, "You pull on the large wooden doors...") + queueScript(player,2){ + sendMessage(player, "...but they will not open.") + return@queueScript stopExecuting(player) + } + } else { + face(player, Location.create(2559, 3302, 0)) + sendNPCDialogue(player, NPCs.MOURNER_2349, "Oi! What are you doing? Get away from there!") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MournerHQDoors.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MournerHQDoors.kt new file mode 100644 index 000000000..2c540b027 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MournerHQDoors.kt @@ -0,0 +1,66 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +// import core.api.hasAnItem +import core.api.isQuestComplete +import core.api.openDialogue +import core.api.teleport +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +// import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class MournerHQDoors : InteractionListener { + + override fun defineListeners() { + class MournerHQDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.MOURNER_347) + // todo check only the mourner gear is equipped + when (stage){ + START_DIALOGUE -> npcl(FacialExpression.ANNOYED, "Who are you? Go away!").also { stage = END_DIALOGUE } + // Wearing extra gear + /* + Mourner: You should know better than to wear non-regulation gear. + Player: Sorry, I'm new around here. + Mourner: Well, you know the drill - lose the gear, I will let it pass this time. + */ + } + + } + } + + // Front door + on(Scenery.DOOR_2036, IntType.SCENERY, "open"){ player, node-> + //todo after Mourning's End I is implemented make this check for wearing mourner gear + if(isQuestComplete(player, Quests.PLAGUE_CITY)){ + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else{ + openDialogue(player, MournerHQDialogue()) + } + return@on true + } + + on(Scenery.TRAPDOOR_8783, IntType.SCENERY, "open"){ player, _-> + // https://youtu.be/P-ns2kyvIGs?si=_DfI-V8KCyNoRtss&t=560 + //todo after Mourning's End II is implemented make this check for a New Key 6104 + // if(hasAnItem(player, Items.NEW_KEY_6104).exists()){ + teleport(player, Location.create(2044,4649, 0)) + //} + //else{ + // sendMessage(player, "The trapdoor appears locked") + //} + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/SarahsBox.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/SarahsBox.kt new file mode 100644 index 000000000..191c4dca5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/SarahsBox.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class SarahsBox : InteractionListener { + override fun defineListeners() { + + on(Scenery.BOX_2062, IntType.SCENERY, "open") { _, node -> + val box = node as core.game.node.scenery.Scenery + replaceScenery(box, Scenery.BOX_2063, -1) + return@on true + } + + on(Scenery.BOX_2063, IntType.SCENERY, "search"){ player, _ -> + if(isQuestComplete(player, Quests.PLAGUE_CITY)){ + if(hasSpaceFor(player, Item(Items.DOCTORS_GOWN_430)) && !hasAnItem(player, Items.DOCTORS_GOWN_430).exists()){ + sendMessage(player, "You find a medical gown in the box.") + addItem(player, Items.DOCTORS_GOWN_430) + return@on true + } + } + sendMessage(player, "You search the box but find nothing") + return@on true + } + + on(Scenery.BOX_2063, IntType.SCENERY, "close") { _, node -> + replaceScenery(node.asScenery(), Scenery.BOX_2062, -1) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/WearMaskListener.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/WearMaskListener.kt new file mode 100644 index 000000000..7ed43f74e --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/WearMaskListener.kt @@ -0,0 +1,42 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import core.api.inBorders +import core.api.isQuestComplete +import core.api.openDialogue +import core.api.sendDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class WearMaskListener : InteractionListener { + override fun defineListeners() { + onUnequip(Items.GAS_MASK_1506){ player, _ -> + if (isQuestComplete(player, Quests.BIOHAZARD)){ + return@onUnequip true + } + else{ + if( + inBorders(player, 2511, 3266, 2556, 3334) || + inBorders(player, 2464, 3281, 2511, 3334) || + inBorders(player, 2461, 3281,2463, 3322) || + inBorders(player, 2435, 3307, 2463, 3322) + ){ + openDialogue(player, MaskChat()) + return@onUnequip false + } + return@onUnequip true + } + } + } +} + +class MaskChat : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + playerl(FacialExpression.WORRIED, "I should probably keep the gas mask on whilst I'm in West Ardougne.").also { stage = END_DIALOGUE } + } + +} + diff --git a/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt b/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt index ed8427af0..3300e43d5 100644 --- a/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt +++ b/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt @@ -11,6 +11,7 @@ import core.game.dialogue.Topic import core.tools.END_DIALOGUE import org.rs09.consts.Items import content.region.kandarin.seers.quest.merlinsquest.ArheinMCDialogue +import content.data.Quests /** @@ -113,7 +114,7 @@ class ArheinDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin 140 -> npcl(core.game.dialogue.FacialExpression.GUILTY,"Sorry pal, but I'm afraid I'm not quite ready to sail yet.").also { stage++ } 141 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"I'm waiting on a big delivery of candles which I need to deliver further along the coast.").also { stage = END_DIALOGUE } 500 -> npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "Yes, I do have orders to deliver there from time to time. I think I may have some bits and pieces for them when I leave here next actually.").also { - val queststage = player.questRepository.getStage("Merlin's Crystal") + val queststage = player.questRepository.getStage(Quests.MERLINS_CRYSTAL) if(queststage == 30 || queststage == 40) { loadFile(ArheinMCDialogue(queststage)) } else { diff --git a/Server/src/main/content/region/kandarin/dialogue/AstronomyBook.kt b/Server/src/main/content/region/kandarin/dialogue/AstronomyBook.kt deleted file mode 100644 index 80df6aa8c..000000000 --- a/Server/src/main/content/region/kandarin/dialogue/AstronomyBook.kt +++ /dev/null @@ -1,130 +0,0 @@ -package content.region.kandarin.dialogue - -import content.global.handlers.iface.BookInterface -import content.global.handlers.iface.BookLine -import content.global.handlers.iface.Page -import content.global.handlers.iface.PageSet -import core.ServerConstants -import core.api.setAttribute -import core.game.interaction.IntType -import core.game.interaction.InteractionListener -import core.game.node.entity.player.Player -import core.plugin.Initializable -import org.rs09.consts.Items - -@Initializable -class AstronomyBook : InteractionListener { - companion object { - private val TITLE = "The tales of Scorpius" - private val CONTENTS = arrayOf( - PageSet( - Page( - BookLine("A History of Astronomy", 55), - BookLine("in ${ServerConstants.SERVER_NAME}.", 56), - BookLine("", 57), - BookLine("At the start of the 4th age,", 58), - BookLine("a learned man by the", 59), - BookLine("name of Scorpius, known well", 60), - BookLine("for his powers of vision and", 61), - BookLine("magic, sought communion with", 62), - BookLine("the gods of the world.", 63), - BookLine("So many unanswered questions", 64), - BookLine("had he that devoted his entire", 65), - ), - Page( - BookLine("life to this cause.", 66), - BookLine("After many years of study,", 67), - BookLine("seeking knowledge from the", 68), - BookLine("wise of that time, he developed", 69), - BookLine("a machine infused with", 70), - BookLine("magical power, infused with", 71), - BookLine("the ability to pierce", 72), - BookLine("into the heavens - a huge eye", 73), - BookLine("that gave the user", 74), - BookLine("incredible site, like never", 75), - BookLine("seen before.", 76), - ) - ), - PageSet( - Page( - BookLine("As time passed, Scorpius", 55), - BookLine("grew adept at using his", 56), - BookLine("specialized skills, and followed", 57), - BookLine("the movements of stars", 58), - BookLine("in ${ServerConstants.SERVER_NAME}, which are", 59), - BookLine("mapped and named, and still", 60), - BookLine("used to this day.", 61), - BookLine("", 62), - BookLine("Before long, Scorpius", 63), - BookLine("used his knowledge", 64), - BookLine("for predicting the future,", 65), - ), - Page( - BookLine("and, in turn, he called upon", 66), - BookLine("the dark knowledge of", 67), - BookLine("Zamorakian worshipers", 68), - BookLine("to further his cause. Living", 69), - BookLine("underground, the followers", 70), - BookLine("of the dark god remained", 71), - BookLine("until the civilization of", 72), - BookLine("Ardougne grew in strength", 73), - BookLine("and control.", 74), - ) - ), - PageSet( - Page( - BookLine("The kings of that time", 55), - BookLine("worked to banish the", 56), - BookLine("Zamorakian followers in", 57), - BookLine("the area, hiding all", 58), - BookLine("reference to Scorpius's", 59), - BookLine("invention, due to", 60), - BookLine("its 'evil nature'.", 61), - BookLine("", 62), - BookLine("Years later, when the", 63), - BookLine("minds of the kings lent", 64), - BookLine("more towards the research", 65), - ), - Page( - BookLine("of the unknown, the plans", 66), - BookLine("of Scorpius were uncovered", 67), - BookLine("and the heavenly eye", 68), - BookLine("constructed again. Since then,", 69), - BookLine("many have studied the ways of", 70), - BookLine("the astronomer, Scorpius", 71), - BookLine("and in his memory a grave", 72), - BookLine("was constructed near the", 73), - BookLine("Observatory. Some claim his", 74), - BookLine("ghost still wanders nearby,", 75), - BookLine("in torment as he seeks", 76), - ) - ), - PageSet( - Page( - BookLine("the secrets of the heavens", 55), - BookLine("that can never be solved.", 56), - BookLine("Tales tell that he will", 57), - BookLine("grant those adept in the", 58), - BookLine("arts of the astronomer a", 59), - BookLine("blessing of unusual power.", 60), - BookLine("", 61), - BookLine("Here ends the tale of", 62), - BookLine("how astronomy entered", 63), - BookLine("the known world.", 64), - ) - ), - ) - } - - private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { - BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) - return true - } - - override fun defineListeners() { - on(Items.ASTRONOMY_BOOK_600, IntType.ITEM, "read") { player, _ -> - BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) - return@on true - } - } -} diff --git a/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt b/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt index 3318d9077..6c1aa1171 100644 --- a/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt +++ b/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -141,8 +142,9 @@ class BindingBook : InteractionListener { } override fun defineListeners() { - on(Items.BINDING_BOOK_730, IntType.ITEM, "read") { player, _ -> + on(Items.BINDING_BOOK_730, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt b/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt index de5a3e3c8..fd294e309 100644 --- a/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt +++ b/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt @@ -1,8 +1,10 @@ package content.region.kandarin.dialogue +import core.ServerConstants import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic import core.game.node.entity.player.Player import core.game.node.entity.player.link.IronmanMode import core.plugin.Initializable @@ -54,11 +56,16 @@ class EniolaDialogue(player: Player? = null) : DialoguePlugin(player) { 4 -> showTopics( Topic(FacialExpression.HALF_THINKING, "If you work for the bank, what are you doing here?", 10), Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account, please.", 30), + IfTopic(FacialExpression.NEUTRAL, "I'd like to open a secondary bank account.", 5, ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player)), + IfTopic(FacialExpression.NEUTRAL, "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", 40, hasActivatedSecondaryBankAccount(player)), Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 31), Topic(FacialExpression.NEUTRAL, "I'd like to see my collection box.", 32), - Topic(FacialExpression.NEUTRAL, "Never mind.", END_DIALOGUE) + IfTopic(FacialExpression.NEUTRAL, "Never mind.", END_DIALOGUE, !ServerConstants.SECOND_BANK) ) + 5 -> npcl(FacialExpression.ASKING, "Sorry, ${if (player.isMale) "sir" else "ma'am"}, the bank didn't license me for that.").also { stage++ } + 6 -> playerl(FacialExpression.HALF_GUILTY, "Oh, okay, I'll ask a banker who is stationed in an actual bank.").also { stage = END_DIALOGUE } + 10 -> npcl( FacialExpression.NEUTRAL, "My presence here is the start of a new enterprise of travelling banks. " + @@ -133,7 +140,7 @@ class EniolaDialogue(player: Player? = null) : DialoguePlugin(player) { 22 -> npcl( FacialExpression.NEUTRAL, - "I'm sorry to hear that, dear ${if (player.isMale) "sir" else "madam"}. " + "I'm sorry to hear that, dear ${if (player.isMale) "sir" else "madam"}." ).also { stage++ } 23 -> npcl( @@ -158,10 +165,15 @@ class EniolaDialogue(player: Player? = null) : DialoguePlugin(player) { openInterface(player, Components.BANK_CHARGE_ZMI_619) end() } + + 40 -> { + toggleBankAccount(player) + npcl( FacialExpression.NEUTRAL, "Your active bank account has been switched. You can now access your ${getBankAccountName(player)} account.").also { stage = END_DIALOGUE } + } } return true } override fun getIds(): IntArray = intArrayOf(NPCs.ENIOLA_6362) -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt b/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt index e663c99ba..54fe778fb 100644 --- a/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt +++ b/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -330,8 +331,9 @@ class GiannesCookBook : InteractionListener { } override fun defineListeners() { - on(Items.GIANNES_COOK_BOOK_2167, IntType.ITEM, "read") { player, _ -> + on(Items.GIANNES_COOK_BOOK_2167, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt b/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt index 9559fa9fa..3ec20f532 100644 --- a/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt +++ b/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -47,8 +48,9 @@ class ShamansTomeBook : InteractionListener { } override fun defineListeners() { - on(Items.SHAMANS_TOME_729, IntType.ITEM, "read") { player, _ -> + on(Items.SHAMANS_TOME_729, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/dialogue/ThormacDialogue.kt b/Server/src/main/content/region/kandarin/dialogue/ThormacDialogue.kt new file mode 100644 index 000000000..ed2bc611e --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/ThormacDialogue.kt @@ -0,0 +1,57 @@ +package content.region.kandarin.dialogue + +import content.region.kandarin.quest.scorpioncatcher.SCThormacDialogue +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class ThormacDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds(): IntArray { + return intArrayOf(NPCs.THORMAC_389) + } + + companion object { + const val COMPLETED_QUEST = 1000 + const val ENCHANT_DIALOGUE = 2000 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (isQuestComplete(player, Quests.SCORPION_CATCHER)){ + npc(FacialExpression.HAPPY, "Thank you for rescuing my scorpions.").also {stage = COMPLETED_QUEST} + } + else{ + openDialogue(player, SCThormacDialogue(getQuestStage(player, Quests.SCORPION_CATCHER)), npc) + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + COMPLETED_QUEST -> showTopics( + Topic(FacialExpression.HAPPY, "That's okay.", END_DIALOGUE), + Topic(FacialExpression.NEUTRAL, "You said you'd enchant my battlestaff for me", ENCHANT_DIALOGUE) + ) + + ENCHANT_DIALOGUE -> { + npcl(FacialExpression.HAPPY, "Yes, it'll cost you 40,000 coins for the materials needed though. " + + "Which sort of staff did you want enchanting?").also { stage++ } + } + ENCHANT_DIALOGUE + 1 -> { + end() + player.interfaceManager.openComponent(332) + } + + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt b/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt index 34b967093..2df29fe88 100644 --- a/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt +++ b/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt @@ -10,7 +10,7 @@ import core.tools.START_DIALOGUE /** * Provides dialogue tree for Balnea NPC involved in the - * "As a first resort..." quest. + * "As a First Resort..." quest. * * @author vddCore */ @@ -44,7 +44,7 @@ class BalneaDialogue(player: Player? = null) : DialoguePlugin(player) { ).also { stage = END_DIALOGUE } } - /* TODO: "As a First Resort..." quest dialogue file is required here. */ + /* TODO: "As a First Resort" quest dialogue file is required here. */ return true } diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt index 2865888b4..49a074680 100644 --- a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt @@ -17,6 +17,7 @@ import core.game.world.map.zone.ZoneBorders import core.game.world.map.RegionManager import core.game.world.map.Location import core.tools.RandomFunction +import content.data.Quests @Initializable class BloatedToadNPC : AbstractNPC { @@ -122,7 +123,7 @@ class BloatedToadListeners : InteractionListener, StartupListener, Commands { override fun defineListeners() { on(Items.BLOATED_TOAD_2875, IntType.ITEM, "drop") { player, used -> - val quest = player.questRepository.getQuest("Big Chompy Bird Hunting") + val quest = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) val inExtraBorder = extraBorders.filter { it.insideBorder(player) }.count() > 0 if (!borders.insideBorder(player) && !inExtraBorder) { diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt index 63df68706..2ca5b5079 100644 --- a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt @@ -24,9 +24,10 @@ import core.game.world.GameWorld import kotlin.math.min import java.util.Random +import content.data.Quests @Initializable -class ChompyBird : Quest("Big Chompy Bird Hunting", 35, 34, 2, Vars.VARP_QUEST_CHOMPY, 0, 1, 65), InteractionListener { +class ChompyBird : Quest(Quests.BIG_CHOMPY_BIRD_HUNTING, 35, 34, 2, Vars.VARP_QUEST_CHOMPY, 0, 1, 65), InteractionListener { companion object { val CAVE_ENTRANCE = Location.create(2646, 9378, 0) val CAVE_EXIT = Location.create(2630, 2997, 0) @@ -255,27 +256,6 @@ class ChompyBird : Quest("Big Chompy Bird Hunting", 35, 34, 2, Vars.VARP_QUEST_C return@onUseWith true } - onUseWith(IntType.ITEM, Items.OGRE_ARROW_SHAFT_2864, Items.FEATHER_314) { player, used, with -> - val shaftAmount = amountInInventory(player, used.id) - val featherAmount = amountInInventory(player, with.id) - var maxAmount = min(shaftAmount, featherAmount) - - submitIndividualPulse(player, object : Pulse(3) { - override fun pulse() : Boolean { - val iterAmount = min(maxAmount, 6) - if (removeItem(player, Item(Items.OGRE_ARROW_SHAFT_2864, iterAmount)) && removeItem(player, Item(Items.FEATHER_314, iterAmount))) - { - addItem(player, Items.FLIGHTED_OGRE_ARROW_2865, iterAmount) - rewardXP(player, Skills.FLETCHING, 0.9 * iterAmount) - maxAmount -= iterAmount - } - return maxAmount == 0 - } - }) - - return@onUseWith true - } - onUseWith(IntType.ITEM, Items.WOLF_BONES_2859, Items.CHISEL_1755) { player, used, with -> val maxAmount = amountInInventory(player, used.id) @@ -323,6 +303,7 @@ class ChompyBird : Quest("Big Chompy Bird Hunting", 35, 34, 2, Vars.VARP_QUEST_C val amountThisIter = min(6, getMaxAmount()) if (removeItem(player, Item(used.id, amountThisIter)) && removeItem(player, Item(with.id, amountThisIter))) { addItem(player, Items.OGRE_ARROW_2866, amountThisIter) + sendMessage(player, "You make $amountThisIter ogre arrows.") rewardXP(player, Skills.FLETCHING, 6.0) } } diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt index be7387f17..054159fd3 100644 --- a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt @@ -18,6 +18,7 @@ import core.game.node.item.Item import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest +import content.data.Quests @Initializable class RantzDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -32,7 +33,7 @@ class RantzDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?) : Boolean { npc = args[0] as NPC - val chompyBird = player.questRepository.getQuest("Big Chompy Bird Hunting") + val chompyBird = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) val chompyStage = chompyBird.getStage(player) val hasOgreBow = inInventory(player, Items.OGRE_BOW_2883) || inEquipment(player, Items.OGRE_BOW_2883) || inBank(player, Items.OGRE_BOW_2883) @@ -142,7 +143,7 @@ class BugsDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?) : Boolean { npc = args[0] as NPC - val chompyBird = player.questRepository.getQuest("Big Chompy Bird Hunting") + val chompyBird = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) val chompyStage = chompyBird.getStage(player) when (chompyStage) { @@ -172,7 +173,7 @@ class FycieDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?) : Boolean { npc = args[0] as NPC - val chompyBird = player.questRepository.getQuest("Big Chompy Bird Hunting") + val chompyBird = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) val chompyStage = chompyBird.getStage(player) when (chompyStage) { diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt index 8f0b000ed..efff701ef 100644 --- a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt @@ -153,7 +153,7 @@ class ChompyBirdNPC : AbstractNPC, InteractionListener { val bird = node.asNpc() if (!bird.getAttribute("plucked", false)) { - addItem(player, Items.FEATHER_314, RandomFunction.random(25, 32)) + addItemOrDrop(player, Items.FEATHER_314, RandomFunction.random(25, 32)) produceGroundItem(player, Items.BONES_526, 1, bird.location) produceGroundItem(player, Items.RAW_CHOMPY_2876, 1, bird.location) bird.clear() @@ -164,7 +164,7 @@ class ChompyBirdNPC : AbstractNPC, InteractionListener { return@on true } - on(Items.OGRE_BOW_2883, IntType.ITEM, "check kills") { player, _ -> + on(intArrayOf(Items.OGRE_BOW_2883, Items.COMP_OGRE_BOW_4827), IntType.ITEM, "check kills") { player, _ -> val amount = player.getAttribute("chompy-kills", 0) sendDialogue(player, "You have killed $amount chompy birds.") return@on true diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt index 94173377d..f0f1ca4ff 100644 --- a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt @@ -8,6 +8,7 @@ import core.plugin.Initializable import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player import core.game.world.map.Location +import content.data.Quests @Initializable class RantzNPC : AbstractNPC { @@ -27,7 +28,7 @@ class RantzNPC : AbstractNPC { val chompy = findLocalNPC(this, NPCs.CHOMPY_BIRD_1550) as? ChompyBirdNPC ?: return val owner = getAttribute(chompy, "owner", null) ?: return - val quest = owner.questRepository.getQuest("Big Chompy Bird Hunting") + val quest = owner.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) if (quest.getStage(owner) !in 40..50 || chompy.getAttribute("attacked", false)) return diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/BartenderDialogueFile.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/BartenderDialogueFile.kt new file mode 100644 index 000000000..b93f3a8ed --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/BartenderDialogueFile.kt @@ -0,0 +1,62 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class BartenderDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> dialogueNum == 1 } + .branch { player -> + return@branch if (getAttribute(player, ZogreFleshEaters.attributeAskedAboutTankard, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("Hello there, I found this tankard in an ogre tomb cavern. It has the emblem of this Inn on it and I wondered if you knew anything about it?") + .npcl("Oh yes, this is Brentle's mug...I'm surprised he left it just lying around down some cave. He's quite protective of it.") + .playerl("Brentle you say? So you knew him then?") + .npcl("Yeah, this belongs to 'Brentle Vahn', he's quite a common customer, though I've not seen him in a while.") + .npcl(FacialExpression.THINKING, "He was talking to some shifty looking wizard the other day. I don't know his name, but I'd recognise him if I saw him.") + .playerl("Hmm, I'm sorry to tell you this, but Brentle Vahn is dead - I believe he was murdered.") + .npcl(FacialExpression.EXTREMELY_SHOCKED, "Noooo! I'm shocked...") + .npcl("...but not surprised. He was a good customer...but I knew he would sell his sword arm and do many a dark deed if paid enough.") + .npcl(FacialExpression.SAD, "If you need help bringing the culprit to justice, you let me know.") + .endWith { _, player -> + setAttribute(player, ZogreFleshEaters.attributeAskedAboutTankard, true) + } + branch.onValue(1) + .playerl("Hello again. Can you tell me what you know about this tankard again please?") + .npcl("Oh yes, Brentle's tankard. Yeah, you've shown me this already. It belonged to Brentle Vahn, he was quite a common customer, though I've not seen him in a while.") + .npcl("He was talking to some shifty looking wizard the other day. I don't know his name, but I'd recognise him if I saw him.") + .npcl(FacialExpression.SAD, "If you need help bringing the culprit to justice, you let me know.") + .end() + } + + b.onPredicate { _ -> dialogueNum == 2 } + .iteml(Items.SITHIK_PORTRAIT_4814, "You show the portrait to the Inn keeper.") + .npcl("Yeah, that's the guy who was talking to Brentle Vahn the other day! Look at those eyes, never a more shifty looking pair will you ever see!") + .playerl("Hmm, you've just identified the man who I think sent Brentle Vahn to his death.") + .playerl("I'm trying to bring him to justice with the Wizards' Guild grand secretary. Do you think you could sign this portrait to say that he was talking to Brentle Vahn.") + .npcl("I can and I will!") + .betweenStage { df, player, _, _ -> + if (removeItem(player, Items.SITHIK_PORTRAIT_4814)) { + addItemOrDrop(player, Items.SIGNED_PORTRAIT_4816) + } + } + .iteml(Items.SIGNED_PORTRAIT_4816, "The Dragon Inn bartender signs the portrait.") + .playerl("Many thanks for your help, it's really very good of you.") + .npcl("Not at all, just doing my part.") + .end() + + + b.onPredicate { _ -> dialogueNum == 3 } + .iteml(Items.SITHIK_PORTRAIT_4815, "You show the sketch to the Inn keeper.") + .npcl("Who's that? I mean, I guess it's a picture of a person isn't it? Sorry...you've got me? And before you ask, you're not putting it up on my wall!") + .playerl("It's a portrait of Sithik Ints...don't you recognise him?") + .npcl("I'm sorry, I really am, but I just don't see it...can you make a better picture?") + .playerl("I'll try...") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrishDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrishDialogue.kt new file mode 100644 index 000000000..7e518f0ff --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrishDialogue.kt @@ -0,0 +1,184 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import content.region.kandarin.quest.templeofikov.TempleOfIkov +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GrishDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GrishDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GrishDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRISH_2038) + } +} +class GrishDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 0) + .playerl(FacialExpression.FRIENDLY, "Hello there, what's going on here?") + .npcl(FacialExpression.OLD_NORMAL, "Hey yous creature...wha's you's doing here? Yous be cleverer to be running so da sickies from da zogres don't dead ya.") + + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("I'm just looking around thanks.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creature won'ts see muchly in dis place...just da zogries coming wiv da sickies.") + .goto(returnJoin) + optionBuilder.option_playerl("What do you mean sickies?") + .npc(FacialExpression.OLD_NORMAL, "Da zogries comin wiv da sickies...yous get bashed by da", "zogries and get da sickies...den you gonna be like da", "zogries.") + .playerl(FacialExpression.FRIENDLY, "Sorry, I just don't understand...") + .betweenStage { df, player, _, _ -> + animate(npc!!, 2090) + setAttribute(player, ZogreFleshEaters.attributeAskedAboutSickies, true) + } + .npc(FacialExpression.OLD_NORMAL, "Da sickies is when yous creature goes like orange till", "green and then goes 'Urggghhhh!'", "~ Grish imitates falling down with only the white of his", "eyes visible. ~") + .goto(returnJoin); + optionBuilder.option_playerl("What are Zogres?") + .npcl(FacialExpression.OLD_NORMAL, "a Zogres are da bigun nasties wiv da sickies, deys old pals of Grish but deys jig in Jiggig when dey's full home is deep in da dirt, dey's is not da same dead'uns like was before.") + .goto(returnJoin); + optionBuilder.optionIf("Can I help in any way?") { player -> return@optionIf getAttribute(player, ZogreFleshEaters.attributeAskedAboutSickies, false) } + .playerl(FacialExpression.FRIENDLY, "Can I help in any way?") + .branch { player -> + return@branch if (ZogreFleshEaters.requirements(player)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Sorry, yous creatures, but yous is too green behind da ears for dis job Grish finks.") + .playerl(FacialExpression.ANGRY, "No, I'm not!") + .npcl(FacialExpression.OLD_ANGRY1, "Yes you are!") + .playerl(FacialExpression.ANGRY, "No, I'm not!") + .npcl(FacialExpression.OLD_ANGRY1, "Yes you are and that's final!") + .end() + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Yes creatures...yous does good fings for Grish and learn why Zogries at Jiggig and den get da Zogries back in da ground.") + .playerl("Oh, so you want me to find out why the Zogres have appeared and then find a way of burying them?") + .npcl(FacialExpression.OLD_NORMAL, "Is what Grish says! But dis is da biggy danger fing yous creatures...yous be geddin' sickies most surely...yous needs be ready..wiv da foodies un da glug-glugs.") + .playerl("Right, so you think there's a good chance that I can get ill from this, so I need to get some food and something to drink?") + .npcl(FacialExpression.OLD_NORMAL, "Yea creatures, yous just say what Grish says...not know own wordies creature?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Hmm, sorry, it sounds a bit too dangerous.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creature is not a stoopid one...stays out of dere, like clever Grish. Yous can paint circles on chest and be da Shaman too!") + .playerl("Hmm, is it too late to reconsider?") + .end() + optionBuilder.option_playerl("Ok, I'll check things out then and report back.") + .npcl(FacialExpression.OLD_NORMAL, "Is yous creatures really, really sure yous wanna do dis creatures..we's got no glug-glugs for da sickies? We's knows nuffin for da going of da sickies?") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Yes, I'm really sure!") + .npcl(FacialExpression.OLD_NORMAL,"Dats da good fing yous creature...yous does Grish a good fing. But yous know dat yous get sickies and mebe get dead!") + .playerl("If that's your idea of a pep talk, I have to say that it leaves a lot to be desired.") + .npcl(FacialExpression.OLD_NORMAL,"Yous creatures is alus says funny stuff...speaks proper like Grish!") + .manualStage() { df, player, _, _ -> + sendDoubleItemDialogue(player, Items.COOKED_CHOMPY_2878, Items.SUPER_RESTORE3_3026, "Grish hands you some food and two potions.") + } + .npcl(FacialExpression.OLD_NORMAL,"Der's yous go creatures...da best me's do for yous...and be back wivout da sickies.") + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 0) { + // Trying to prevent players from spamming to get more super restores. + addItemOrDrop(player, Items.COOKED_CHOMPY_2878, 3) + addItemOrDrop(player, Items.SUPER_RESTORE3_3026, 2) + setQuestStage(player, ZogreFleshEaters.questName, 1) + } + } + optionBuilder2.option_playerl("Hmm, sorry, it sounds a bit too dangerous.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creature is not a stoopid one...stays out of dere, like clever Grish. Yous can paint circles on chest and be da Shaman too!") + .end() + } + } + + } + optionBuilder.option_playerl("Sorry, I have to go.") + .end() + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 1,2,3,4,5,6) + .npcl(FacialExpression.OLD_NORMAL, "Yous creature dun da fing yet? Da zogries going in da dirt full home?") + .playerl("Nope, I haven't figured out why the zogres are here yet.") + .end() + + b.onQuestStages(ZogreFleshEaters.questName, 7) + .npcl(FacialExpression.OLD_NORMAL,"Yous creature dun da fing yet? Da zogries going in da ground?") + .playerl("I found who's responsible for the Zogres being here.") + .npcl(FacialExpression.OLD_NORMAL,"Where is da creature? Me's wants to squeeze him till he's a deadun...") + .playerl("The person responsible is a wizard named 'Sithik Ints' and he's going to be in serious trouble. He told me that the spell which raised the zogres from the ground will last forever.") + .playerl("I'm sorry to say, but you'll have to move the site of your ceremonial dancing somewhere else.") + .npcl(FacialExpression.OLD_NORMAL,"Dat is da bad fing creature...we's needs new Jiggig for da fallin' down jig.") + .playerl("Yes, that's right, you'll need to create a new ceremonial dance area.") + .npcl(FacialExpression.OLD_NORMAL,"Urghhh...not good fing creature, yous gotta get da ogrish old fings for da making new jiggig special. You's creature needs da key for getting in da low bury place.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.OGRE_GATE_KEY_4839) + } + .iteml(Items.OGRE_GATE_KEY_4839, "Grish gives you a crudely crafted key.") + .playerl("Oh, so you want me to go back in there and look for something for you?") + .npcl(FacialExpression.OLD_NORMAL,"Yeah creature, yous gotta get da ogrish old fings for da making new jiggig and proper in da special way.") + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 7) { + setQuestStage(player, ZogreFleshEaters.questName, 8) + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 8) + .npcl(FacialExpression.OLD_NORMAL, "Hey, you's creature got da old fings?") + .branch { player -> + return@branch if (inInventory(player, Items.OGRE_GATE_KEY_4839)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("Nope, not yet.") + .npcl(FacialExpression.OLD_NORMAL, "Yous gets 'em quick tho, cos we'ze wonna do da new Jiggig place...") + .end() + branch.onValue(0) + .playerl("I lost the key you gave me.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.OGRE_GATE_KEY_4839) + } + .iteml(Items.OGRE_GATE_KEY_4839, "Grish gives you a crudely crafted key.") + .end() + } + + b.onQuestStages(ZogreFleshEaters.questName, 9) + .branch { player -> + return@branch if (inInventory(player, Items.OGRE_ARTEFACT_4818)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Hey, you's creature got da old fings?") + .playerl("No sorry, I don't have them yet.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creatures get dem for me soon doh, yes?") + .end() // There's all the default dialogue here, but I'm lazy again. + + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Hey, you's creature got da old fings?") + .playerl("Yeah, I have them here!") + .npcl(FacialExpression.OLD_NORMAL, "Dat is da goodly fing yous creature, now's we's can make da new Jiggig place away from zogries! Yous been da big helpy fing yous creature, Grish wishin' yous good stuff for da next fings for creature.") + .npcl(FacialExpression.OLD_HAPPY, "~ Grish seems very pleased about the return of the artefacts. ~") + .playerl("Thanks, that's very nice of you!") + .endWith { _, player -> + if (removeItem(player, Items.OGRE_ARTEFACT_4818)) { + if (getQuestStage(player, ZogreFleshEaters.questName) == 9) { + finishQuest(player, ZogreFleshEaters.questName) + } + } + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 100) + .playerl("How's everything going now?") + .npcl(FacialExpression.OLD_NORMAL,"All da zogries stayin' in da oldie Jiggig, we's gonna do da new Jiggig someways else. Yous creature da good- un for geddin' da oldie fings...") + // More default dialogue, but lazy. + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrugDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrugDialogue.kt new file mode 100644 index 000000000..6081288cf --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrugDialogue.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class GrugDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GrugDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GrugDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRUG_2041) + } +} +class GrugDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npcl(FacialExpression.OLD_NORMAL, "Ukk...I's dun fer...me's don't feel legsies anymore!") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/JiggigListeners.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/JiggigListeners.kt new file mode 100644 index 000000000..718e26efc --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/JiggigListeners.kt @@ -0,0 +1,27 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class JiggigListeners : InteractionListener { + override fun defineListeners() { + on(Scenery.OGRE_COFFIN_6848, SCENERY, "open") { player, node -> + // https://youtu.be/HnRcW2iM8es + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.OGRE_COFFIN_6890, 10) + return@on true + } + + on(NPCs.UGLUG_NAR_2039, NPC, "trade") { player, node -> + if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { + openNpcShop(player, NPCs.UGLUG_NAR_2039) + } else { + sendNPCDialogue(player, NPCs.UGLUG_NAR_2039, "Me's not got no glug-glugs to sell, yous bring me da sickies glug-glug den me's open da stufsies for ya.", FacialExpression.OLD_NORMAL) + } + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/OgreGuardDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/OgreGuardDialogue.kt new file mode 100644 index 000000000..6f5193687 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/OgreGuardDialogue.kt @@ -0,0 +1,73 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class OgreGuardDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return OgreGuardDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, OgreGuardDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.OGRE_GUARD_2042) + } +} +class OgreGuardDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(ZogreFleshEaters.questName, 0) + .npcl(FacialExpression.OLD_NORMAL, "Yous needs ta stay away from dis place... yous get da sickies and mebe yous goes to dead if yous da unlucky fing.") + .playerl("Ok, thanks.") + .end() + + b.onQuestStages(ZogreFleshEaters.questName, 1) + .npcl(FacialExpression.OLD_NORMAL, "Yous needs ta stay away from dis place... yous get da sickies and mebe yous goes to dead if yous da unlucky fing.") + .playerl(FacialExpression.FRIENDLY, "But Grish has asked me to look into this place and find out why all the undead ogres are here.") + .npcl(FacialExpression.OLD_NORMAL, "Ok, dat is da big, big scary, danger fing! You's sure you's wants to go in?") + .playerl(FacialExpression.FRIENDLY, "Yes, I'm sure.") + .npcl(FacialExpression.OLD_NORMAL, "Ok, I opens da stoppa's for yous creature.") + .endWith { _, player -> + lock(player, 4) + face(npc!!, Location(2456, 3049, 0)) + // Lesson learnt here, endWith kills the npc object so tie the queueScript with the npc instead, not the player. + queueScript(npc!!, 2, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + animate(npc!!, 2102) + return@queueScript delayScript(npc!!, Animation(2102).duration) + } + 1 -> { + if(getQuestStage(player, ZogreFleshEaters.questName) == 1) { + setQuestStage(player, ZogreFleshEaters.questName, 2) + } + setVarbit(player, ZogreFleshEaters.varbitGateBashed, 1) + unlock(player) + face(npc!!, player.location) + sendNPCDialogue(player, NPCs.OGRE_GUARD_2042, "Ok der' yous goes!", FacialExpression.OLD_NORMAL) + return@queueScript stopExecuting(npc!!) + } + else -> return@queueScript stopExecuting(npc!!) + } + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 2,3,4,5,6,7,8,9,10,100) + .npcl(FacialExpression.OLD_NORMAL, "Hey yous tryin' not to get da sickies else yous be da sick-un and mebe get to be a dead-un if yous be da unlucky fing.") + .playerl(FacialExpression.FRIENDLY, "Don't worry, I know how to take care of myself.") + .end() + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/PilgDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/PilgDialogue.kt new file mode 100644 index 000000000..6eee48feb --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/PilgDialogue.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class PilgDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return PilgDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, PilgDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.PILG_2040) + } +} +class PilgDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npcl(FacialExpression.OLD_NORMAL, "Dey got me in da belly, mees gutsies feel like had a dead dead dog dinner.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SithikIntsDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SithikIntsDialogue.kt new file mode 100644 index 000000000..789251861 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SithikIntsDialogue.kt @@ -0,0 +1,388 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +/** This NPC is a scenery. */ +//@Initializable +//class SithikIntsDialogue (player: Player? = null) : DialoguePlugin(player) { +// override fun newInstance(player: Player): DialoguePlugin { +// return SithikIntsDialogue(player) +// } +// override fun handle(interfaceId: Int, buttonId: Int): Boolean { +// openDialogue(player, SithikIntsDialogueFile(), npc) +// return false +// } +// override fun getIds(): IntArray { +// return intArrayOf(NPCs.SITHIK_INTS_2061, NPCs.SITHIK_INTS_2062) +// } +//} +class SithikIntsDialogue : InteractionListener { + override fun defineListeners() { + on(Scenery.SITHIK_INTS_6888, SCENERY, "talk-to") { player, node -> + openDialogue(player, SithikIntsDialogueFile(), NPC(NPCs.SITHIK_INTS_2061)) + return@on true + } + on(Scenery.SITHIK_INTS_6889, SCENERY, "talk-to") { player, node -> + openDialogue(player, SithikIntsOgreFormDialogueFile(), NPC(NPCs.SITHIK_INTS_2062)) + return@on true + } + + on(Scenery.DRAWERS_6875, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) <= 2) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendPlayerDialogue(player, "Erk! I'd better not start rifling through peoples things without permission.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getQuestStage(player, ZogreFleshEaters.questName) in 3..4 && + (!inInventory(player, Items.BOOK_OF_PORTRAITURE_4817) || + !inInventory(player, Items.PAPYRUS_970) || + !inInventory(player, Items.CHARCOAL_973) + )) { + if (hasSpaceFor(player, Item(Items.BOOK_OF_PORTRAITURE_4817, 3))) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> { + if (!inInventory(player, Items.PAPYRUS_970) && !inInventory(player, Items.CHARCOAL_973)) { + sendDoubleItemDialogue(player, Items.CHARCOAL_973, Items.PAPYRUS_970, "You find some charcoal and papyrus.") + addItemOrDrop(player, Items.PAPYRUS_970) + addItemOrDrop(player, Items.CHARCOAL_973) + stage++ + } else if (!inInventory(player, Items.PAPYRUS_970)) { + sendItemDialogue(player, Items.PAPYRUS_970, "You find some papyrus.") + addItemOrDrop(player, Items.PAPYRUS_970) + stage++ + } else if (!inInventory(player, Items.CHARCOAL_973)) { + sendItemDialogue(player, Items.CHARCOAL_973, "You find some charcoal.") + addItemOrDrop(player, Items.CHARCOAL_973) + stage++ + } else { + sendItemDialogue(player, Items.BOOK_OF_PORTRAITURE_4817, "You also find a book on portraiture.") + addItemOrDrop(player, Items.BOOK_OF_PORTRAITURE_4817) + stage = END_DIALOGUE + } + } + 1 -> { + sendItemDialogue(player, Items.BOOK_OF_PORTRAITURE_4817, "You also find a book on portraiture.") + addItemOrDrop(player, Items.BOOK_OF_PORTRAITURE_4817) + stage = END_DIALOGUE + } + } + } + }) + } else { + sendDialogue(player, "You see some items in the drawer, but you need 3 free inventory spaces to take them.") + } + } else { + sendMessage(player, "You search but find nothing of significance.") + } + return@on true + } + + on(Scenery.CUPBOARD_6876, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) <= 2) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendPlayerDialogue(player, "Erk! I'd better not start rifling through peoples things without permission.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getQuestStage(player, ZogreFleshEaters.questName) in 3..4 && !inInventory(player, Items.NECROMANCY_BOOK_4837)) { + if (hasSpaceFor(player, Item(Items.NECROMANCY_BOOK_4837))) { + addItemOrDrop(player, Items.NECROMANCY_BOOK_4837) + sendItemDialogue(player, Items.NECROMANCY_BOOK_4837, "You find a book on Necromancy.") + setAttribute(player, ZogreFleshEaters.attributeFoundNecromanticBook, true) + } else { + sendDialogue(player, "You see an item in the cupboard, but you don't have space to put it in your inventory.") + } + } else { + sendMessage(player, "You search but find nothing of significance.") + } + return@on true + } + + onUseWith(IntType.SCENERY, Items.NECROMANCY_BOOK_4837, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"Aha! A necromantic book! What's this doing here then?").also { stage++ } + 1 -> sendItemDialogue(player, Items.NECROMANCY_BOOK_4837, "You show the Necromantic book to Sithik.").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Oh..I'm not quite sure actually...where did you find that then?").also { stage++ } + 3 -> sendPlayerDialogue(player,"I found it in this cupboard! What do you have to say for yourself?").also { stage++ } + 4 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Oh yes, that's right...I remember now. It's for my research, there's nothing really dangerous about it, unless it falls into the wrong hands. I'm sure it's pretty safe with me.").also { stage++ } + 5 -> sendPlayerDialogue(player,"Hmmm, likely story!").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + on(Scenery.WARDROBE_6877, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) <= 2) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendPlayerDialogue(player, "Erk! I'd better not start rifling through peoples things without permission.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getQuestStage(player, ZogreFleshEaters.questName) in 3..4 && !inInventory(player, Items.BOOK_OF_HAM_4829)) { + if (hasSpaceFor(player, Item(Items.BOOK_OF_HAM_4829))) { + addItemOrDrop(player, Items.BOOK_OF_HAM_4829) + sendItemDialogue(player, Items.BOOK_OF_HAM_4829, "You find a book on Philosophy written by the 'Human's Against Monsters' leader, Johanhus Albrect.") + setAttribute(player, ZogreFleshEaters.attributeFoundHamBook, true) + } else { + sendDialogue(player, "You see an item in the wardrobe, but you don't have space to put it in your inventory.") + } + } else { + sendMessage(player, "You search but find nothing of significance.") + } + return@on true + } + + onUseWith(IntType.SCENERY, Items.BOOK_OF_HAM_4829, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"What's this then?").also { stage++ } + 1 -> sendItemDialogue(player, Items.BOOK_OF_HAM_4829, "You show the HAM book to Sithik.").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "What do you mean? It's a book by the respected HAM leader Johanhus Ulsbrecht, that man speaks for a lot of people who are unhappy with the current state of affairs.").also { stage++ } + 3 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Can you honestly tell me that you've not had to fight for your life against the odd monster or two?").also { stage++ } + 4 -> sendPlayerDialogue(player,"Hmm, that may be true, but I don't universally hate all monsters, whereas I have a sneaking suspicion that you do...and ogres in particular!").also { stage++ } + 5 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hmm, that's an interesting theory, care to back it up with any facts?").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.PAPYRUS_970, Scenery.SITHIK_INTS_6888) { player, used, with -> + if(inInventory(player, Items.CHARCOAL_973)) { + if (removeItem(player, used)) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Oh lovely! You're making my portrait! Let me see it afterwards!", FacialExpression.FRIENDLY).also { stage++ } + 1 -> sendDialogue(player, "You begin sketching the irritable Sithik.").also { animate(player, 909); stage++ } + 2 -> { + val skill = Skills.CRAFTING + val level: Int = getDynLevel(player, skill) + getFamiliarBoost(player, skill) + val ratio = RandomFunction.getSkillSuccessChance(0.0, 80.0, level) + + if (ratio > 0.5) { + // Passed + sendItemDialogue(player, Items.SITHIK_PORTRAIT_4814, "You get a portrait of Sithik.") + addItemOrDrop(player, Items.SITHIK_PORTRAIT_4814) + } else { + // Failed + sendItemDialogue(player, Items.SITHIK_PORTRAIT_4815, "You get a portrait of Sithik.") + addItemOrDrop(player, Items.SITHIK_PORTRAIT_4815) + } + setAttribute(player, ZogreFleshEaters.attributeMadePortrait, true) + stage = END_DIALOGUE + } + } + } + }) + } + } else { + sendDialogue(player, "You have no charcoal with which to sketch this subject.") + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BOOK_OF_PORTRAITURE_4817, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"Oh, so explain this then?").also { stage++ } + 1 -> sendItemDialogue(player, Items.BOOK_OF_PORTRAITURE_4817, "You show the book on portraiture to Sithik.").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "It's my hobby...I'm interested in portraiture, but all art in general. It's fun, you should try it.").also { stage++ } + 3 -> sendPlayerDialogue(player,"How do I do it...").also { stage++ } + 4 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Well...you could start by reading the book!").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.SITHIK_PORTRAIT_4814, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player, "Here you go, what do you think?").also { stage++ } + 1 -> sendItemDialogue(player, Items.SITHIK_PORTRAIT_4814, "You show the sketch...").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hmmm, well it's not the most flattering of portraits, but I like the 'honesty' of the work...well done.").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.SITHIK_PORTRAIT_4815, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player, "Here you go, what do you think?").also { stage++ } + 1 -> sendItemDialogue(player, Items.SITHIK_PORTRAIT_4815, "You show the sketch...").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hmmm, well it's an interesting interpretation, but not really classic realist representation is it? It's not my favourite, but I like the 'truth' of the work...well done.").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + on(Items.CUP_OF_TEA_4838, ITEM, "take") { player, node -> + sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing? Leave my tea alone!", FacialExpression.ANNOYED) + return@on true + } + + onUseWith(IntType.SCENERY, Items.STRANGE_POTION_4836, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"Here, try some of this potion, it'll make you feel better!").also { stage++ } + 1 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Err, yuck...no way am I taking any potions or medication off you...I don't trust you!").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.GROUNDITEM, Items.STRANGE_POTION_4836, Items.CUP_OF_TEA_4838) { player, _, with -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 5) { + if (removeItem(player, Items.STRANGE_POTION_4836)) { + sendItemDialogue(player, Items.STRANGE_POTION_4836, "You pour some of the potion into the cup. Zavistic said it may take some time to have an effect.") + addItemOrDrop(player, Items.SAMPLE_BOTTLE_3377) + } + setQuestStage(player, ZogreFleshEaters.questName, 6) + } + return@onUseWith true + } + } +} + +class SithikIntsDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 0, 1, 2) + .npcl(FacialExpression.ANNOYED, "Hey... who gave you permission to come in here! Get out, get out I say.") + .playerl("Alright, alright... keep your night cap on.") + .end() + + b.onQuestStages(ZogreFleshEaters.questName, 3, 4, 5, 6) + .npcl(FacialExpression.ANNOYED, "Hey... who gave you permission to come in here! Get out, get out I say.") + .playerl("Zavistic Rarve said that I could come and talk to you and ask you a few questions.") + .betweenStage { df, player, _, _ -> + if (getQuestStage(player, ZogreFleshEaters.questName) == 3) { + setQuestStage(player, ZogreFleshEaters.questName, 4) + } + } + .npcl(FacialExpression.ANNOYED, "Oh, Zavistic...why...why would he send you to me?") + + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Do you know anything about the undead ogres at Jiggig?") + .npcl("Er...undead ogres...no, sorry, no idea what you're talking about there.") + .playerl("Hmm, is that right...") + .npcl("Well, yes, yes it is. If I knew something, I'd tell you.") + .npcl("Anyway, dead ogres you say? How strange? That must be a strange sight?") + .playerl("Very well, if you don't know anything about it, you won't mind if I look around then?") + .npcl("Well,err....well, actually yes I do mind...it's my place and I don't want strangers going through my things.") + .goto(returnJoin) + + optionBuilder.option_playerl("What do you do?") + .npcl("I'm a scholarly student of the magical arts. When I was younger I used to be an adventurer, probably just like yourself. But I lost interest in the constant fighting, looting and gaining abilities.") + .npcl("Instead I decided to focus my attention and time to study the purer form of the lost arts.") + .playerl("The lost arts? What are they?") + .npcl("Ignorant people call them the 'dark arts'. I'm talking about Necromancy, the power to bring the dead back to life - the power of the gods! Surely the most awesome power known to man.") + .playerl("Hmm, well I guess I must be an ignorant person then, because bringing the dead back to life sounds very unnatural.") + .goto(returnJoin) + + optionBuilder.option_playerl("Do you mind if I look around?") + .npcl("Well,err....well, actually yes I do mind...it's my place and I don't want strangers going through my things.") + .playerl("Well, I'm going to have a look around anyway, if you're not involved in this whole thing, you won't have anything to hide.") + .npcl("Why, if I was a few years younger I'd give you a good hiding!") + .playerl("I'm sure!") + .goto(returnJoin) + + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + builder.goto(returnJoin) + } + } +} + +class SithikIntsOgreFormDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(ZogreFleshEaters.questName, 7,8,9,100) + /* + There are some after first time dialogue, but who reads this... + .npcl("Arghhhh..what do you want now...you've turned me into a beast!") + .playerl("I've got some questions for you...and you'd better answer them well or else!") + .npcl("Ok, ok, I'll tell you anything, just turn me back into a human again!") + */ + .npcl(FacialExpression.OLD_DEFAULT, "Arghhhh..what's happened to me...you beast!") + .playerl("It's your own fault, you shouldn't have lied about your involvement with the undead Ogres at Jiggig. The potion will wear off once you've told the truth!") + .npcl(FacialExpression.OLD_DEFAULT, "Ok, ok, I admit it, I got Brentle Vahn to cast the spell to put an end to those awful Ogres...they're just disgusting creatures...") + .playerl("Ok, that's a start...now I want some answers.") + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option("How do I remove the effects of the spell from the area?") + .playerl("How do I remove the effects of the spell from the area? The ogres want to get their ceremonial dance area back and can't do that with undead walking all over it.") + .npcl(FacialExpression.OLD_DEFAULT, "Unfortunately you can't. The spell is permanent, it will last forever, the only option you have is to move the ceremonial area.") + .playerl("You're an evil man and I'm going to make you pay for this...you can stay like that forever as far as I'm concerned.") + .npcl(FacialExpression.OLD_DEFAULT, "No...no, let me try to make amends...please I can help you. Just don't leave me like this.") + .goto(returnJoin) + + optionBuilder.option_playerl("How do I get rid of the undead ogres?") + .npcl(FacialExpression.OLD_DEFAULT, "Ok, similar spells have been cast before and the only way to deal with the resulting creatures is to cordon off the area and not go in there again.") + .npcl(FacialExpression.OLD_DEFAULT, "The undead creatures usually manifest some sort of disease so it's best to attack them from a distance with a ranged weapon.") + .npcl(FacialExpression.OLD_DEFAULT, "Normal missiles like arrows and darts do very little damage to them because they're designed to destroy internal organs. This is a waste of time with undead creatures like undead ogres.") + .playerl("Yeah, clearly so what should we use?") + .npcl(FacialExpression.OLD_DEFAULT, "From my research it looks like a flat ended arrow was designed called a 'Brutal arrow'. This does large amounts of crushing damage to the creature. You can make them by using larger arrows.") + .npcl(FacialExpression.OLD_DEFAULT, "I think some Ogre hunters make them. But instead of adding an arrow tip, you hammer a large nail into the end of the shaft.") + .goto(returnJoin) + + optionBuilder.option_playerl("How do I get rid of the disease?") + .npcl(FacialExpression.OLD_DEFAULT, "My research shows that two jungle based herbs can be used, one is found near river tributaries and looks like a vine, the other is found in caves and grows on the wall.") + .npcl(FacialExpression.OLD_DEFAULT, "It's quite well camouflaged so it's unlikely that you'll find it.") + .playerl("We'll see about that!") + .goto(returnJoin) + + optionBuilder.option_playerl("Sorry, I have to go.") + .npcl(FacialExpression.OLD_DEFAULT, "But...you can't just leave me here like this!") + .end() + } + builder.goto(returnJoin) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SkogreBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SkogreBehavior.kt new file mode 100644 index 000000000..54363e66d --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SkogreBehavior.kt @@ -0,0 +1,48 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.getOrStartTimer +import core.api.inEquipment +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.spell.SpellType +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.system.timer.impl.Disease +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class SkogreBehavior : NPCBehavior(*skogreIds) { + companion object { + @JvmField + val skogreIds = intArrayOf( + NPCs.SKOGRE_2050, + NPCs.SKOGRE_2056, + NPCs.SKOGRE_2057, + ) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (inEquipment(attacker, Items.COMP_OGRE_BOW_4827)) { + return + } + if (state.spell != null && state.spell.type == SpellType.CRUMBLE_UNDEAD) { + state.estimatedHit = (state.estimatedHit * 0.5).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.5).toInt() + } + return + } + state.estimatedHit = (state.estimatedHit * 0.25).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.25).toInt() + } + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + val disease = getOrStartTimer(victim, 10) + disease.hitsLeft = 10 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SlashBashBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SlashBashBehavior.kt new file mode 100644 index 000000000..95fab62bc --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SlashBashBehavior.kt @@ -0,0 +1,100 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import content.global.handlers.item.equipment.special.DragonfireSwingHandler +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.MultiSwingHandler +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.combat.spell.SpellType +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.timer.impl.Disease +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class SlashBashBehavior : NPCBehavior(NPCs.SLASH_BASH_2060) { + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + if (victim is Player) { + val disease = getOrStartTimer(victim, 25) + disease.hitsLeft = 25 + } + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (inEquipment(attacker, Items.COMP_OGRE_BOW_4827)) { + return + } + if (state.spell != null && state.spell.type == SpellType.CRUMBLE_UNDEAD) { + state.estimatedHit = (state.estimatedHit * 0.5).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.5).toInt() + } + return + } + state.estimatedHit = (state.estimatedHit * 0.25).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.25).toInt() + } + } + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + if (killer is Player && getQuestStage(killer, ZogreFleshEaters.questName) == 8) { + drops.add(Item(Items.ZOGRE_BONES_4812, 2)) + drops.add(Item(Items.OURG_BONES_4834, 3)) + drops.add(Item(Items.OGRE_ARTEFACT_4818)) + setQuestStage(killer, ZogreFleshEaters.questName, 9) + removeAttribute(killer, ZogreFleshEaters.attributeSlashBashInstance) + } + } + + var clearTime = 0 + override fun tick(self: NPC): Boolean { + val player: Player? = getAttribute(self, "target", null) + // You have 500 ticks to kill this guy + if (clearTime++ > 500) { + poofClear(self) + clearTime = 0 + if (player != null) { + removeAttribute(player, ZogreFleshEaters.attributeSlashBashInstance) + } + + } + return true + } + + /** MELEE Swing */ + private val COMBAT_HANDLER = MultiSwingHandler(SwitchAttack(CombatStyle.MELEE.swingHandler, Animation(359))) + /** RANGE Swing (Projectile) */ + private val COMBAT_HANDLER_FAR = MultiSwingHandler(SwitchAttack(CombatStyle.RANGE.swingHandler, Animation(359), Graphics(499))) + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + val victim = self.properties.combatPulse.getVictim() ?: return original + if (victim !is Player) return original + + return if (victim.location.getDistance(self.location) >= 2) + COMBAT_HANDLER_FAR + else + COMBAT_HANDLER + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/UglugNarDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/UglugNarDialogue.kt new file mode 100644 index 000000000..aab0bfee9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/UglugNarDialogue.kt @@ -0,0 +1,78 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class UglugNarDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return UglugNarDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, UglugNarDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.UGLUG_NAR_2039) + } +} +class UglugNarDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 0) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Hey, what's going on here?") + .npcl(FacialExpression.OLD_NORMAL, "Dem's dead ogre's come out of the ground...dey's makin' da rest of us into sick-ums ...and dead-uns.") + .playerl("That doesn't sound good!") + .npcl(FacialExpression.OLD_NORMAL, "Grish want's da person go down der - see what's what!") + .end() + optionBuilder.option_playerl("What are you selling?") + .npcl(FacialExpression.OLD_NORMAL, "Me's not got no glug-glugs to sell, yous bring me da sickies glug-glug den me's open da stufsies for ya.") + .end() + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + + b.onQuestStages(ZogreFleshEaters.questName, 1,2,3,4,5,6,7,8,9,10,100) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Hello again.") + .branch { player -> + return@branch if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Hey yous creature...yous did good fings gedin that glug-glugs for da sickies! All is ogries pepels are not gettin dead cos of you.") + .end() + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Hey yous creature...yous still here?") + .playerl("Yeah, I'm going to help Grish by figuring out what went on here.") + .npcl(FacialExpression.OLD_NORMAL, "If yous finds somefin for da sickies, yous brings to me...and I's give you bright pretties, den me make more for alls pepels.") + .playerl("Hmm, ok. I'll try to bear that in mind.") + .end() + } + + optionBuilder.option_playerl("What are you selling?") + .branch { player -> + return@branch if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Me's showin' you da stufsies for yous creatures!") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Me's not got no glug-glugs to sell, yous bring me da sickies glug-glug den me's open da stufsies for ya.") + .end() + } + + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZavisticRarveDialogueFile.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZavisticRarveDialogueFile.kt new file mode 100644 index 000000000..1954334b1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZavisticRarveDialogueFile.kt @@ -0,0 +1,290 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items + +class ZavisticRarveDialogueFile : DialogueBuilderFile() { + + companion object { + private fun hasEvidences(player: Player): Int { + var count = 0 + if (inInventory(player, Items.NECROMANCY_BOOK_4837)) { count++ } + if (inInventory(player, Items.BOOK_OF_HAM_4829)) { count++ } + if (inInventory(player, Items.DRAGON_INN_TANKARD_4811)) { count++ } + if (inInventory(player, Items.SIGNED_PORTRAIT_4816)) { count++ } + return count + } + + fun dialogueBlackPrismAndTornPage(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("There's some undead ogre activity over at Jiggig, I've found some clues, I wondered if you'd have a look at them.") + .manualStage() { df, player, _, _ -> + sendDoubleItemDialogue(player, Items.BLACK_PRISM_4808, Items.TORN_PAGE_4809, "You show the prism and the necromantic half page to the aged wizard.") + } + .npcl("Hmmm, now this is interesting! Where did you get these from?") + .playerl("I got them from a nearby Ogre tomb, it's recently been infested with zombie ogres and I'm trying to work out what happened there.") + .npcl("This is very troubling @name, very troubling indeed. While it's permitted for learned members of our order to research the 'dark arts', it's absolutely forbidden to make use of such magic.") + .playerl("Do you have any leads on people that I might talk to regarding this?") + .npcl("Well a wizard by the name of 'Sithik Ints' was doing some research in this area. He may know something about it. He's lodged at that guest house to the North, though he's ill and isn't able to leave his room.") + .npcl("Why not go and talk to him, poke around a bit and see if anything comes up. Let me know how you get on. However, I doubt that 'Sithik' had anything to do with it.") + .npcl("Hmm, that black prism seems to have some magical protection. Once you've finished with this item, bring it back to me would you. I may have a reward for you.") + } + + fun dialogueGoodPortrait(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Look, I made a portrait of Sithik.") + .iteml(Items.SITHIK_PORTRAIT_4814, "You show the portrait of Sithik to Zavistic.") + .npcl("Hmm, great...but I already know what he looks like!") + } + + fun dialogueBadPortrait(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Look, I made a portrait of Sithik.") + .iteml(Items.SITHIK_PORTRAIT_4815, "You show the sketch...") + .npcl("Who the demonikin is that? Is it meant to be a portrait of Sithik, it doesn't look anything like him!") + } + + // Too lazy to do this, but this gets mentioned whenever you've shown him one of the evidence (but not all). + fun dialogueSeenEvidenceBefore(builder: DialogueBuilder): DialogueBuilder { + return builder + .npcl("Yeah, you've shown me this before...if this is all the evidence you have?") + .playerl("Please just look at it again...") + .npcl("Ok, let me look then.") + } + } + + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 2) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .branch { player -> + return@branch if (inInventory(player, Items.BLACK_PRISM_4808) && inInventory(player, Items.TORN_PAGE_4809) ) { + 3 + } else if (inInventory(player, Items.BLACK_PRISM_4808) ) { + 2 + } else if (inInventory(player, Items.TORN_PAGE_4809) ) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(3) + .let{ dialogueBlackPrismAndTornPage(it) } + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 2) { + setQuestStage(player, ZogreFleshEaters.questName, 3) + } + } + + branch.onValue(2) + .playerl("There's some undead ogre activity over at 'Jiggig', and the ogres have asked me to look into it. I think I've found a clue and I wonder if you could take a look at it for me?") + .iteml(Items.BLACK_PRISM_4808, "You show the black prism to the aged wizard.") + .npcl("Hmmm, well this is an uncommon spell component. On its own it's useless, but with certain necromantic spells it can be very powerful. Did you find anything else there?") + .branch { player -> + return@branch if (inInventory(player, Items.DRAGON_INN_TANKARD_4811)) { 1 } else { 0 } + }.let { branch2 -> + val returnJoin = b.placeholder() + branch2.onValue(0) + .goto(returnJoin) + branch2.onValue(1) + .iteml(Items.DRAGON_INN_TANKARD_4811, "You show the tankard to Zavistic.") + .playerl("Well, I found this...") + .npcl("Hmmm, no, that's not really associated with this to be honest. Did you find anything else there?") + .goto(returnJoin) + return@let returnJoin.builder() + } + .playerl("Not really.") + .npcl("I don't know what to say then, there isn't enough to go on with the clues you've shown me so far. I'd suggest going back to search a bit more, but you may just be wasting your time?") + .npcl("Hmm, but this prism does seem to have some magical protection. Once you've finished with this item, bring it back to me would you? I may have a reward for you!") + .playerl("Sure...I mean, I'll try if I remember.") + .end() + + branch.onValue(1) + .playerl("There's some undead ogre activity over at Jiggig, I've found a clue that you may be able to help with.") + .iteml(Items.TORN_PAGE_4809, "You show the necromantic half page to the aged wizard.") + .npcl("Hmm, this is a half torn spell page, it requires another spell component to be effective. Did you find anything else there?") + .branch { player -> + return@branch if (inInventory(player, Items.DRAGON_INN_TANKARD_4811)) { 1 } else { 0 } + }.let { branch2 -> + val returnJoin = b.placeholder() + branch2.onValue(0) + .goto(returnJoin) + branch2.onValue(1) + .iteml(Items.DRAGON_INN_TANKARD_4811, "You show the tankard to Zavistic.") + .playerl("Well, I found this...") + .npcl("Hmmm, no, that's not really associated with this to be honest. Did you find anything else there?") + .goto(returnJoin) + return@let returnJoin.builder() + } + .playerl("Not really.") + .npcl("I don't know what to say then, there isn't enough to go on with the clues you've shown me so far. I'd suggest going back to search a bit more, but you may just be wasting your time?") + .end() + + branch.onValue(0) + .let { builder -> + content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(builder) + } + } + + + b.onQuestStages(ZogreFleshEaters.questName, 3,4) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .let { builder -> + val returnJoin = b.placeholder() + builder.goto(returnJoin) + return@let returnJoin.builder().options() + .let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("What did you say I should do?") + .playerl("What did you say I should do?") + .npcl("You should go and have a chat with Sithik Ints, he's in that house just to the north. He's a lodger and has a room upstairs. Just tell him that I sent you to see him. He should be fine once you've mentioned my name.") + .goto(returnJoin) + optionBuilder.option_playerl("Where is Sithik?") + .npcl("He's in that house just to the north, less than a few seconds walk away. He's a lodger and has a room upstairs...he's not very well though.") + .goto(returnJoin) + optionBuilder.optionIf("I have an item that I'd like you to look at.") { player -> return@optionIf hasEvidences(player) == 1 } + .goto(continuePath) + optionBuilder.optionIf("I have an item that I'd like you to look at.") { player -> return@optionIf hasEvidences(player) > 1 } + .goto(continuePath) + optionBuilder.option("I want to ask about the magic guild") + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(it) } + optionBuilder.option_playerl("Sorry, I have to go.") + .end() + + return@let continuePath.builder() + } + } + .branch { player -> + return@branch if (inInventory(player, Items.NECROMANCY_BOOK_4837) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.NECROMANCY_BOOK_4837, "You show the Necromancy book to Zavistic.") + .playerl("I have this necromancy book as evidence that Sithik is involved with the undead ogres at Jiggig.") + .npcl("Ok, so he's researching necromancy...it doesn't mean anything in itself.") + .playerl("Yes, but if you look, you can see that there is a half torn page which matches the page I found at Jiggig.") + .npcl("Hmm, yes, but someone could have stolen that from him and then gone and cast it without his permission or to try and deliberately implicate him.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (inInventory(player, Items.BOOK_OF_HAM_4829) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.BOOK_OF_HAM_4829, "You show the HAM book to Zavistic.") + .playerl("Look, this book proves that Sithik hates all monsters and most likely Ogres with a passion.") + .npcl("So what, hating monsters isn't a crime in itself...although I suppose that it does give a motive if Sithik was involved. On its own, it's not enough evidence though.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (inInventory(player, Items.DRAGON_INN_TANKARD_4811) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.DRAGON_INN_TANKARD_4811, "You show the dragon Inn Tankard to Zavistic.") + .playerl("This is the tankard I found on the remains of Brentle Vahn!") + .npcl("That doesn't mean anything in itself, you could have gotten that from anywhere. Even from the Dragon Inn tavern! There isn't anything to link Brentle Vahn with Sithik Ints.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (inInventory(player, Items.SIGNED_PORTRAIT_4816) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.SIGNED_PORTRAIT_4816, "You show the signed portrait of Sithik to Zavistic.") + .playerl("This is a portrait of Sithik, signed by the landlord of the Dragon Inn saying that he saw Sithik and Brentle Vahn together.") + .npcl("Hmmm, well that is interesting.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (hasEvidences(player) == 4) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl("However, there isn't enough evidence for me to take the issue further at this point. If you find any further evidence bring it to me.") + .end() + return@let branch + } + .onValue(1) + .npcl("And I'm starting to think that Sithik may be involved. Here, take this potion and give some to Sithik. It'll bring on a change which should solicit some answers - tell him the effects won't revert until he's told the truth.") + .iteml(Items.STRANGE_POTION_4836 ,"Zavistic hands you a strange looking potion bottle and takes all the evidence you've accumulated so far.") + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) in 3..4) { + if (removeItem(player, Items.NECROMANCY_BOOK_4837) && + removeItem(player, Items.BOOK_OF_HAM_4829) && + removeItem(player, Items.DRAGON_INN_TANKARD_4811) && + removeItem(player, Items.SIGNED_PORTRAIT_4816)) { + addItemOrDrop(player, Items.STRANGE_POTION_4836) + } + setQuestStage(player, ZogreFleshEaters.questName, 5) + } + } + b.onQuestStages(ZogreFleshEaters.questName, 5) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .npcl("Have you used that potion yet?") + .branch { player -> + return@branch if (inInventory(player, Items.STRANGE_POTION_4836) ) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("No, not yet, what was I supposed to do again?") + .npcl("Try to use the potion on Sithik somehow, he should undergo an interesting transformation, though you'll probably want to leave the house in case there are any side effects. Then go back and question Sithik and tell") + .npcl("him the effects won't wear off until he tells the truth. In fact, that's not exactly true, but I'm sure it'll be an extra incentive to get him to be honest.") + .let { builder -> + content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(builder) + } + branch.onValue(0) + .playerl("Well, actually, I've lost it, could I have another one please?") + .npcl("Sure, but don't lose it this time.") + .iteml(Items.STRANGE_POTION_4836 ,"Zavistic hands you a bottle of strange potion.") + .endWith { _, player -> + addItemOrDrop(player, Items.STRANGE_POTION_4836) + } + } + + + b.onQuestStages(ZogreFleshEaters.questName, 6,7,8,9) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .npcl("Don't you worry about Sithik, he's not likely to be moving from his bed for a long time. When he eventually does get better, he's going to be sent before a disciplinary tribunal, then we'll sort out what's what.") + .playerl("Thanks for your help with all of this.") + .npcl("Ooohh, no thanks required. It's I who should be thanking you my friend...your investigative mind has shown how vigilant we really should be for this type of evil use of the magical arts.") + .let { builder -> + content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(builder) + } + } +} + +/** Dialogues when you use stuff on him. */ +class ZavisticRarveUseItemsDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + // SITHIK_PORTRAIT_4814 + b.onPredicate { _ -> dialogueNum == 3 } + .let{ZavisticRarveDialogueFile.dialogueGoodPortrait(it)} + .end() + + // SITHIK_PORTRAIT_4815 + b.onPredicate { _ -> dialogueNum == 4 } + .let{ZavisticRarveDialogueFile.dialogueBadPortrait(it)} + .end() + + // SIGNED_PORTRAIT_4816 + b.onPredicate { _ -> dialogueNum == 5 } + // That would continue the conversation as above if you normally talk to him. + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreBehavior.kt new file mode 100644 index 000000000..871266c92 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreBehavior.kt @@ -0,0 +1,56 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.getOrStartTimer +import core.api.inEquipment +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.spell.SpellType +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.system.timer.impl.Disease +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class ZogreBehavior : NPCBehavior(*zogreIds) { + companion object { + @JvmField + val zogreIds = intArrayOf( + NPCs.ZOGRE_2044, + NPCs.ZOGRE_2045, + NPCs.ZOGRE_2046, + NPCs.ZOGRE_2047, + NPCs.ZOGRE_2048, + NPCs.ZOGRE_2049, + NPCs.ZOGRE_2051, + NPCs.ZOGRE_2052, + NPCs.ZOGRE_2053, + NPCs.ZOGRE_2054, + NPCs.ZOGRE_2055, + ) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (inEquipment(attacker, Items.COMP_OGRE_BOW_4827)) { + return + } + if (state.spell != null && state.spell.type == SpellType.CRUMBLE_UNDEAD) { + state.estimatedHit = (state.estimatedHit * 0.5).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.5).toInt() + } + return + } + state.estimatedHit = (state.estimatedHit * 0.25).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.25).toInt() + } + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + val disease = getOrStartTimer(victim, 10) + disease.hitsLeft = 10 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEaters.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEaters.kt new file mode 100644 index 000000000..6ed8c9010 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEaters.kt @@ -0,0 +1,353 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Zogre Flesh Eaters Quest + * + * 1 - Talked to Grish + * 2 - Smashed Barricade + * 2 Cont' - Collected Stuff Underground + * A - Black Prism from Coffin + * B - Half Torn Page from Broken Lecturn + * C - Tankard from Backpack (Kill the Zombie which turns out to be Brentle Vahn) + * 3 - Talked to Zavistic Rarve with A & B only, points to where Sithik Ints is + * 4 - Talked to Sithik and challenged to incriminate him + * 4 Cont' - Collected Evidence + * A - Tankard from 2C after talking to Innkeeper + * B - Portrait of Sithik using papyrus and charcoal with questionable drawing skills + * C - Book of HAM philosophy from drawer + * D - Necromantic book + * 5 - Incriminate Sithik to Zavistic Rarve and given potion + * 6 - Turned Sithik into an Ogre with potion + * 7 - Talked to Grish + * 8 - Get Key from Grish + * 9 - Killed Slash Bash + * 100 - Returned to Grish with Ogre Artifact + * + * This quest journal is the worst; there's typos, and it is out of order. + * + * if (VARPBIT[487] > 12) return 2; if (VARPBIT[487 == 0) return 0; return 1; }; + * define_varbit 487 455 0 4 + * + */ +@Initializable +class ZogreFleshEaters : Quest(Quests.ZOGRE_FLESH_EATERS, 40, 39, 1, 455, 0, 1, 13) { + companion object { + val questName = Quests.ZOGRE_FLESH_EATERS + const val varbitGateBashed = 496 + const val varbitOgreCoffin = 488 + const val varbitSithikOgre = 495 + + const val attributeAskedAboutSickies = "quest:zogreflesheaters-askedaboutsickies" + + // 2A + const val attributeSearchedCoffin = "/save:quest:zogreflesheaters-searchedcoffin" + const val attributeBrokeLockCoffin = "/save:quest:zogreflesheaters-brokelockcoffin" + const val attributeOpenedCoffin = "/save:quest:zogreflesheaters-openedcoffin" // You can fail apparently... + const val attributeFoundBlackPrism = "/save:quest:zogreflesheaters-foundblackprism" + // 2B + const val attributeFoundHalfTornPage = "/save:quest:zogreflesheaters-foundhalftornpage" + // 2C + const val attributeFoughtZombie = "/save:quest:zogreflesheaters-foughtzombie" + const val attributeFoundTankard = "/save:quest:zogreflesheaters-foundtankard" + // 4A + const val attributeAskedAboutTankard = "quest:zogreflesheaters-askedabouttankard" + // 4B + const val attributeMadePortrait = "/save:quest:zogreflesheaters-madeportrait" + // 4C + const val attributeFoundHamBook = "/save:quest:zogreflesheaters-foundhambook" + // 4D + const val attributeFoundNecromanticBook = "/save:quest:zogreflesheaters-foundnecromanticbook" + + const val attributeSlashBashInstance = "/save:quest:zogreflesheaters-slashbashinstance" + + // Open Uglug Nar Shop with Relicym balm + const val attributeOpenUglugNarShop = "/save:quest:zogreflesheaters-openuglugnarshop" + + fun requirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.RANGE, 30), + hasLevelStat(player, Skills.SMITHING, 4), + hasLevelStat(player, Skills.HERBLORE, 8), + isQuestComplete(player, Quests.JUNGLE_POTION), + isQuestComplete(player, Quests.BIG_CHOMPY_BIRD_HUNTING), + ).all { it } + } + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + var stage = getStage(player) + + var started = getQuestStage(player, questName) > 0 + + if (!started) { + line(player, "I can !!start?? this quest by talking to !!Grish?? at the Ogrish", line++, false) + line(player, "ceremonial dance place called !!Jiggig??.", line++, false) + line(player, "To start this !!quest?? I should complete these quests:-", line++, false) + line(player, "!!Jungle Potion.??", line++, isQuestComplete(player, Quests.JUNGLE_POTION)) + line(player, "!!Big Chompy Bird Hunting.??", line++, isQuestComplete(player, Quests.BIG_CHOMPY_BIRD_HUNTING)) + line(player, "It would help if I had the following skills levels:-", line++, false) + line(player, "!!Ranged level : 30??", line++, hasLevelStat(player, Skills.RANGE, 30)) + line(player, "!!Fletching level : 30??", line++, hasLevelStat(player, Skills.FLETCHING, 30)) + line(player, "!!Smithing level : 4??", line++, hasLevelStat(player, Skills.SMITHING, 4)) + line(player, "!!Herblore level : 8??", line++, hasLevelStat(player, Skills.HERBLORE, 8)) + line(player, "Must be able to defeat a !!level 111?? foe.", line++, false) + } else if (stage < 100) { + + line(player, "I started this quest by talking to Grish, he asked me to", line++, true) + line(player, "check out the underground area where some Zombie ogres", line++, true) + line(player, "(Zogres) were coming from.", line++, true) + + if (stage >= 2) { + line(player, "I have to find a way into the ceremonial dance area and", line++, true) + line(player, "then underground.", line++, true) + line(player, "I persuaded a guard to let me past, I only had to mention", line++, true) + line(player, "Grish's name and the guard smashed the barricade down. I", line++, true) + line(player, "can enter now.", line++, true) + } else if (stage >= 1) { + line(player, "I have to find a way into the ceremonial dance area and", line++, false) + line(player, "then underground.", line++, false) + } + + if (stage >= 2) { + // Set 2A (Stays) + if (getAttribute(player, attributeFoundBlackPrism, false) || stage >= 3) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + line(player, "I have forced the lock on a coffin, maybe I can open it", line++, true) + line(player, "now?", line++, true) + line(player, "I've !!opened?? the !!coffin?? and retrieved a !!black prism??, this", line++, stage >= 3) + line(player, "may be useful.", line++, stage >= 3) + } else if (getAttribute(player, attributeOpenedCoffin, false)) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + line(player, "I have forced the lock on a coffin, maybe I can open it", line++, true) + line(player, "now?", line++, true) + line(player, "I've !!opened?? the !!coffin??, maybe there's something in it.", line++, false) + } else if (getAttribute(player, attributeBrokeLockCoffin, false)) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + line(player, "I have forced the lock on a !!coffin??, maybe I can open it", line++, false) + line(player, "now?", line++, false) + } else if (getAttribute(player, attributeSearchedCoffin, false)) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + } + } + + if (stage >= 2) { + // Set 2B (Stays) + if (getAttribute(player, attributeFoundHalfTornPage, false) || stage >= 3) { + line(player, "I found a !!half torn page?? from a !!necromatic spellbook??,", line++, stage >= 3) + line(player, "maybe this is a !!clue???", line++, stage >= 3) + } + } + + // 4 - This is the weirdest shit that is out of place. (Stays) This appears after talking to Sithik Int. + if (stage >= 4) { + line(player, "I have shown the prism and torn page to the grand", line++, true) + line(player, "secretary of the wizards guild.", line++, true) + } + + // Set 2C (Does not stay) + if (stage in 2..4 && getAttribute(player, attributeFoundTankard, false)) { + line(player, "I killed a !!human zombie?? which dropped a !!backpack??. The", line++, stage >= 3) + line(player, "!!backpack?? had the name !!'B. Vahn'?? on it, inside the !!backpack??", line++, stage >= 3) + line(player, "I found a !!tankard??.", line++, stage >= 3) + } else if (stage in 2..4 && getAttribute(player, attributeFoughtZombie, false)) { + line(player, "I killed a !!human zombie?? which dropped a !!backpack??.", line++, stage >= 3) + } + + // Stays until you find all the 3X stuff above. + if (stage in 2..4 && !(getAttribute(player, attributeFoundBlackPrism, false) && + getAttribute(player, attributeFoundHalfTornPage, false) && + getAttribute(player, attributeFoundTankard, false))) { + line(player, "I need to find out what happened here.", line++, false) // Cleared when the 3 sets above are done. + } + + // Set 4A (Does not stay) + if (stage in 2..4 && getAttribute(player, attributeAskedAboutTankard, false)) { + line(player, "The 'Dragon Inn' !!Innkeeper?? says the tankard belongs to", line++, false) + line(player, "one of his locals called !!Brentle Vahn??. He was seen talking", line++, false) + line(player, "to a !!wizard?? the other day.", line++, false) // Cleared after handed in with the rest + } + + // 3 Zavistic Rarve seen prism and page - lines disappears right after... + if (stage == 3) { + line(player, "I have shown the !!prism?? and the !!necromantic page?? to", line++, false) + line(player, "Zavistic Rarve. He's told me about a !!wizard?? named", line++, false) + line(player, "!!Sithik Ints?? who might have some information.", line++, false) + } + + // 4 Spoken with Sithik + if (stage >= 4) { + line(player, "I've spoken to !!Sithik??, I need to see if he was !!involved??", line++, stage >= 5) + line(player, "with the !!Undead Ogres at 'Jiggig'?? in some way.", line++, stage >= 5) + } + + // Only stays for 4 + if (stage == 4) { + if (getAttribute(player, attributeMadePortrait, false)) { + line(player, "I've made a !!portrait?? of !!Sithik??...not sure what this will do?", line++, false) + } + if (getAttribute(player, attributeFoundHamBook, false)) { + line(player, "I've found a !!book?? on !!HAM philosophy??...what does this prove?", line++, false) + } + if (getAttribute(player, attributeFoundNecromanticBook, false)) { + line(player, "I've found a !!necromantic book??...what does this prove?", line++, false) + } + } + + // 4 - Who the hell knows why this is here. (Stays) This appears after getting the potion. + if (stage >= 5) { + line(player, "I've talked to Zavistic Rarve regarding the prism and the", line++, true) + line(player, "torn page, he gave some information on a student called", line++, true) + line(player, "Sithik Ints, he may know more about what's happening", line++, true) + line(player, "here.", line++, true) + } + + // Beyond this is legit + if (stage >= 5) { + line(player, "Zavistic has given me some sort of !!potion??, apparently I", line++, stage >= 6) + line(player, "need to give it to !!Sithik??.", line++, stage >= 6) + } + + if (stage >= 7) { + line(player, "I came back into Sithik's room to find that he had been", line++, true) + line(player, "turned into an Ogre!", line++, true) + } else if (stage >= 6) { + line(player, "I have put some of the !!potion?? into !!Sithik's tea??, the !!potion??", line++, false) + line(player, "will take some time to act. Perhaps I should !!get out of??", line++, false) + line(player, "!!here?? in case there are any !!side effects???", line++, false) + } + + if (stage >= 8) { + line(player, "Sithik has told me how to make 'brutal arrows', which", line++, true) + line(player, "should be more effective against Zogres.", line++, true) + + line(player, "Sithik has given me some pointers on how I can make a", line++, true) + line(player, "cure disease potion, though I'm still not sure exactly which", line++, true) + line(player, "herbs I should use.", line++, true) + } else if (stage >= 7) { + line(player, "!!Sithik?? has told me that there is no way I can remove the", line++, false) + line(player, "effects of the !!necromantic curse spell?? from the !!Jiggig??", line++, false) + line(player, "area. I'll have to go back and let !!Grish?? know.", line++, false) + + line(player, "!!Sithik?? has told me how to make !!'brutal arrows'??, which", line++, false) + line(player, "should be more !!effective?? against !!Zogres??.", line++, false) + + line(player, "!!Sithik?? has given me some pointers on how I can make a", line++, false) + line(player, "!!cure disease potion??, though I'm still not sure exactly which", line++, false) + line(player, "!!herbs?? I should use.", line++, false) + } + + if (stage >= 9) { + line(player, "I've told Grish to relocated the dance area, but he needs", line++, true) + line(player, "me to get something from the tomb to so that he can do", line++, true) // "tomb to so" is authentic [sic] + line(player, "this.", line++, true) + line(player, "I need to go back into the tomb and look for some 'old'", line++, true) + line(player, "items that Grish has asked for.", line++, true) + line(player, "I should return the !!artifact?? to !!Grish??.", line++, false) + } else if (stage >= 8) { + line(player, "I've told Grish to relocated the dance area, but he needs", line++, true) + line(player, "me to get something from the tomb to so that he can do", line++, true) // "tomb to so" is authentic [sic] + line(player, "this.", line++, true) + line(player, "I need to go back into the !!tomb?? and look for some !!'old'??", line++, false) + line(player, "!!items?? that !!Grish?? has asked for.", line++, false) + } + + } else { + // The ending is COMPLETELY replaced from this entire shitshow of a quest log. + line(player, "I talked to Grish in the Jiggig area which is swarming with", line++, true) + line(player, "Zombie Ogres (Zogres) These disgusting creatures carry", line++, true) + line(player, "disease and are quite dangerous so the Ogres weren't", line++, true) + line(player, "too keen to try and sort them out.", line++, true) + + line(player, "I talked to an ogre called Grish who asked me to look into", line++, true) + line(player, "the problem. After some searching around in a tomb, I", line++, true) + line(player, "found some clues which pointed me to the human", line++, true) + line(player, "habitation of Yannile.", line++, true) + + line(player, "With the help of Zavistic Rarve, the grand secretary of", line++, true) + line(player, "the Wizards guild I was able to piece the clues together", line++, true) + line(player, "and discover that a Wizard named 'Sithik Ints' was", line++, true) + line(player, "responsible.", line++, true) + + line(player, "Unfortunately I couldn't remove the curse from the area,", line++, true) + line(player, "however, I was able to return some important artefacts to", line++, true) + line(player, "Grish, who can now set up a new ceremonial dance area for", line++, true) + line(player, "the ogres of Gu' Tanoth.", line++, true) + + line(player, "Sithik Ints also told me how to make Brutal arrows which are", line++, true) + line(player, "more effective against Zogres, and he also told me how to", line++, true) + line(player, "make a disease balm.", line++, true) + line++ + line(player,"QUEST COMPLETE!", line) + } + } + + override fun reset(player: Player) { + setVarp(player, varbitGateBashed, 0, true) + removeAttribute(player, attributeAskedAboutSickies) + removeAttribute(player, attributeSearchedCoffin) + removeAttribute(player, attributeBrokeLockCoffin) + removeAttribute(player, attributeOpenedCoffin) + removeAttribute(player, attributeFoundBlackPrism) + removeAttribute(player, attributeFoundHalfTornPage) + removeAttribute(player, attributeFoughtZombie) + removeAttribute(player, attributeFoundTankard) + removeAttribute(player, attributeAskedAboutTankard) + removeAttribute(player, attributeMadePortrait) + removeAttribute(player, attributeFoundHamBook) + removeAttribute(player, attributeFoundNecromanticBook) + removeAttribute(player, attributeOpenUglugNarShop) + + } + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Zogre Flesh Eaters!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.OGRE_ARTEFACT_4818, 240, 277, 5) + + drawReward(player,"1 Quest Point.", ln++) + drawReward(player,"Can now make Brutal Arrows", ln++) + drawReward(player,"and cure disease potions.", ln++) + drawReward(player,"2000 Ranged, Fletching and", ln++) + drawReward(player,"Herblore XP", ln++) + + player.skills.addExperience(Skills.RANGE, 2000.0) + player.skills.addExperience(Skills.FLETCHING, 2000.0) + player.skills.addExperience(Skills.HERBLORE, 2000.0) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + if(getQuestStage(player, questName) >= 2) { + setVarbit(player, varbitGateBashed, 1, true) + } else { + setVarbit(player, varbitGateBashed, 0, true) + } + if(getQuestStage(player, questName) >= 7) { + setVarbit(player, varbitSithikOgre, 1, true) + } else { + setVarbit(player, varbitSithikOgre, 0, true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEatersListeners.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEatersListeners.kt new file mode 100644 index 000000000..bd16a02b6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEatersListeners.kt @@ -0,0 +1,382 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class ZogreFleshEatersListeners : InteractionListener { + + companion object { + @JvmStatic + fun ladderMakesSithikTurnIntoOgre(player: Player) { + if(getQuestStage(player, ZogreFleshEaters.questName) == 6) { + setQuestStage(player, ZogreFleshEaters.questName, 7) + setVarbit(player, ZogreFleshEaters.varbitSithikOgre, 1) + } + } + } + + override fun defineListeners() { + // Stairs and doors + on(Scenery.STAIRS_6841, SCENERY, "climb-down") { player, node -> + sendMessage(player, "You climb down the steps.") + if (node.location == Location(2443, 9417, 2)) { + teleport(player, Location(2442, 9417, 0)) + } else { + teleport(player, Location(2477, 9437, 2)) + } + return@on true + } + on(Scenery.STAIRS_6842, SCENERY, "climb-up") { player, node -> + sendMessage(player, "You climb up the steps.") + if (node.location == Location(2443, 9417, 0)) { + teleport(player, Location(2447, 9417, 2)) + } else { + teleport(player, Location(2485, 3045, 0)) + } + return@on true + } + on(Scenery.OGRE_STONE_DOOR_6871, SCENERY, "open") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 9) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (inInventory(player, Items.OGRE_GATE_KEY_4839)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "You use the Ogre Tomb Key to unlock the door.") + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + + on(Scenery.OGRE_STONE_DOOR_6872, SCENERY, "open") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 9) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (inInventory(player, Items.OGRE_GATE_KEY_4839)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "You use the Ogre Tomb Key to unlock the door.") + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + + // Stage 2 + on(Scenery.CRUSHED_BARRICADE_6881, SCENERY, "climb-over") { player, node -> + if (player.location.x < 2456) { + val distance = player.location.getDistance(Location(2457, 3049, 0)).toInt() + forceMove(player, player.location, Location(2457, 3049, 0), 0, distance * 15, null, 1236) + } else { + val distance = player.location.getDistance(Location(2455, 3049, 0)).toInt() + forceMove(player, player.location, Location(2455, 3049, 0), 0, distance * 15, null, 1236) + } + return@on true + } + on(Scenery.CRUSHED_BARRICADE_6882, SCENERY, "climb-over") { player, node -> + if (player.location.x < 2456) { + val distance = player.location.getDistance(Location(2457, 3048, 0)).toInt() + forceMove(player, player.location, Location(2457, 3048, 0), 0, distance * 15, null, 1236) + } else { + val distance = player.location.getDistance(Location(2455, 3048, 0)).toInt() + forceMove(player, player.location, Location(2455, 3048, 0), 0, distance * 15, null, 1236) + } + return@on true + } + + // Stage 2A + on(Scenery.OGRE_COFFIN_6844, SCENERY, "search") { player, node -> + if (getVarbit(player, ZogreFleshEaters.varbitOgreCoffin) == 0) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogueLines(player, "You search the coffin and find a small geometrically shaped hole in", "the side. It looks as if this hole was made with a considerable amount", "of force, maybe the thing which made the hole is still inside?").also { stage++ } + 1 -> sendDialogueLines(player, "The lock looks quite crude, with some skill and a slender blade, you", "may be able to force it.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getVarbit(player, ZogreFleshEaters.varbitOgreCoffin) == 1) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogueLines(player, "The lid looks heavy, but now that you've unlocked it, you may be", "able to lift it. You prepare yourself.").also { stage++ } + 1 -> playerl("Urrrgggg.").also { sendChat(player, "Urrrgggg."); stage++ } + 2 -> playerl("Aarrrgghhh!").also { sendChat(player, "Aarrrgghhh!"); stage++ } + // Supposed to have a failure state here. + 3 -> playerl("Raarrrggggg! Yes!").also { sendChat(player, "Raarrrggggg! Yes!"); stage++ } + 4 -> sendDialogueLines(player, "You eventually manage to lift the lid.").also { + setVarbit(player, ZogreFleshEaters.varbitOgreCoffin, 3, true) + stage = END_DIALOGUE + } + } + } + }) + } + return@on true + } + onUseWith(IntType.SCENERY, Items.KNIFE_946, Scenery.OGRE_COFFIN_6844) { player, _, _ -> + sendItemDialogue(player, Items.KNIFE_946, + "With some skill you manage to slide the blade along the lock edge and click into place the teeth of the primitive mechanism.") + setVarbit(player, ZogreFleshEaters.varbitOgreCoffin, 1, true) + return@onUseWith true + } + + on(Scenery.OGRE_COFFIN_6845, SCENERY, "search") { player, node -> + sendItemDialogue(player, Items.BLACK_PRISM_4808, + "You find a creepy looking black prism inside.") + addItemOrDrop(player, Items.BLACK_PRISM_4808) + return@on true + } + + on(Items.BLACK_PRISM_4808, ITEM, "look-at") { player, node -> + sendItemDialogue(player, Items.BLACK_PRISM_4808, + "It looks like a smokey black gem of some sort...very creepy. Some magical force must have prevented it from being shattered when it hit the coffin.") + return@on true + } + + // Stage 2B + on(Scenery.BROKEN_LECTURN_6846, SCENERY, "search") { player, node -> + sendMessage(player, "You search the broken down lecturn.") + if (inInventory(player, Items.TORN_PAGE_4809)) { + sendMessage(player, "You find nothing.") + } else { + sendItemDialogue(player, Items.TORN_PAGE_4809, + "You find a half torn page...it has spidery writing all over it.") + addItemOrDrop(player, Items.TORN_PAGE_4809) + } + return@on true + } + + on(Items.TORN_PAGE_4809, ITEM, "read") { player, node -> + sendDialogue(player, "You don't manage to understand all of it as there is only a half page here. But it seems the spell was used to place a curse on an area and for all time raise the dead.") + return@on true + } + + // Stage 2C + on(Scenery.SKELETON_6893, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 2){ + if (getAttribute(player, ZogreFleshEaters.attributeFoughtZombie, false)) { + + if (inInventory(player, Items.RUINED_BACKPACK_4810)) { + sendMessage(player, "You find nothing on the corpse.") + } else { + sendMessage(player, "You find another backpack.") + addItemOrDrop(player, Items.RUINED_BACKPACK_4810) + } + } else { + // Zombie time. + sendMessage(player, "Something screams into life right in front of you.") + val npc = NPC(NPCs.ZOMBIE_1826) + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(2442, 9459, 2) + npc.direction = Direction.NORTH + npc.init() + npc.attack(player) + } + } else { + // At no point should this be reached since you need to start the quest anyway. + sendMessage(player, "You find nothing on the corpse.") + } + return@on true + } + on(Items.RUINED_BACKPACK_4810, ITEM, "open") { player, node -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> { + sendItemDialogue(player, Items.RUINED_BACKPACK_4810, + "Just before you open the backpack, you notice a small leather patch with the moniker: 'B.Vahn', on it.").also { stage++ } + sendItemZoomOnInterface(player, 241, 1, Items.RUINED_BACKPACK_4810, 230) + } + 1 -> sendItemDialogue(player, Items.DRAGON_INN_TANKARD_4811, + "You find an interesting looking tankard.").also { + setAttribute(player, ZogreFleshEaters.attributeFoundTankard, true) + if(removeItem(player, node)) { + addItem(player, Items.ROTTEN_FOOD_2959) + addItem(player, Items.KNIFE_946) + addItem(player, Items.DRAGON_INN_TANKARD_4811) + } + stage++ + } + 2 -> sendDoubleItemDialogue(player, Items.KNIFE_946, Items.ROTTEN_FOOD_2959, "You find a knife and some rotten food, the backpack is ripped to shreds.").also { + sendMessage(player, "You find a knife and some rotten food.") + sendMessage(player, "You find an interesting looking tankard.") + stage = END_DIALOGUE + } + } + } + }) + return@on true + } + + + on(Items.DRAGON_INN_TANKARD_4811, ITEM, "look-at") { player, node -> + sendItemDialogue(player, Items.DRAGON_INN_TANKARD_4811, + "A stout ceramic tankard with a Dragon Emblem on the side, the words, 'Ye Olde Dragon Inn' are inscribed in the bottom.") + return@on true + } + + // Zavistic Bell, Stage 2,3,4,5,6 and on (Actually should be standalone. + on(Scenery.BELL_6847, SCENERY, "ring") { player, node -> + sendMessage(player, "You ring the bell.") + // TODO: Make Zavistic appear at the bell area. + openDialogue(player, content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile(), NPC(NPCs.ZAVISTIC_RARVE_2059)) + return@on true + } + + // Stage 4A + onUseWith(IntType.NPC, Items.DRAGON_INN_TANKARD_4811, NPCs.BARTENDER_739) { player, used, with -> + openDialogue(player, BartenderDialogueFile(1), with as NPC) + return@onUseWith true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4814, NPCs.BARTENDER_739) { player, used, with -> + // The good portrait + openDialogue(player, BartenderDialogueFile(2), with as NPC) + return@onUseWith true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4815, NPCs.BARTENDER_739) { player, used, with -> + // The bad portrait + openDialogue(player, BartenderDialogueFile(3), with as NPC) + return@onUseWith true + } + on(Items.SIGNED_PORTRAIT_4816, ITEM, "look-at") { player, node -> + sendItemDialogue(player, Items.SIGNED_PORTRAIT_4816, + "You see an image of Sithik with a message underneath 'I, the bartender of the Dragon Inn, do swear that this is a true likeness of the wizzy who was talking to Brentle Vahn, my customer the other day.'") + return@on true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4814, NPCs.ZAVISTIC_RARVE_2059) { player, used, with -> + // The good portrait + openDialogue(player, ZavisticRarveUseItemsDialogueFile(3), with as NPC) + return@onUseWith true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4815, NPCs.ZAVISTIC_RARVE_2059) { player, used, with -> + // The bad portrait + openDialogue(player, ZavisticRarveUseItemsDialogueFile(4), with as NPC) + return@onUseWith true + } + + + // Stage 4B + on(Items.BOOK_OF_PORTRAITURE_4817, ITEM, "read") { player, node -> + sendDialogueLines(player, + "All interested artisans should really consider taking up the hobby of", + "portraiture. To do so, one uses a piece of papyrus on the intended", + "subject to initiate a likeness drawing activity.") + return@on true + } + + // Stage 4C + on(Items.BOOK_OF_HAM_4829, ITEM, "read") { player, node -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> { + sendDialogue(player, + "You read this book for a while, it seems to be some sort of political "+ + "manifesto about how the king doesn't do enough to safeguard the "+ + "citizens of the realm from the monsters that still thrive within the "+ + "borders. ").also { stage++ } + // This is the original, but it is too big for this to handle. +// sendDialogueLines(player, +// "You read this book for a while, it seems to be some sort of political", +// "manifesto about how the king doesn't do enough to safeguard the", +// "citizens of the realm from the monsters that still thrive within the", +// "borders. It sends out a rallying to all people who would want to", +// "stop monsters, to join the HAM movement.").also { stage++ } + } + 1 -> sendDialogue(player, "It sends out a rallying to all people who would want to stop monsters, to join the HAM movement.").also { stage++ } + 2 -> sendPlayerDialogue(player, "Hmm, Sithik must really hate monsters then, I wonder if he hates ogres in particular?").also { + stage = END_DIALOGUE + } + } + } + }) + return@on true + } + + // Stage 4D + on(Items.NECROMANCY_BOOK_4837, ITEM, "read") { player, node -> + sendDialogueLines(player, + "This book uses very strange language and some", + "incomprehensible symbols. It has a very dark and evil feeling to", + "it. As you're looking through the book, you notice that", + "one of the pages has been torn and half of it is missing.") + return@on true + } + + onUseWith(IntType.ITEM, Items.NECROMANCY_BOOK_4837, Items.TORN_PAGE_4809) { player, _, _ -> + sendDoubleItemDialogue(player, Items.NECROMANCY_BOOK_4837, Items.TORN_PAGE_4809, + "The torn page matches exactly the part where a torn out page is missing from the book. You feel sure that this page came from this book.") + return@onUseWith true + } + + // Uglug Nar Shop + onUseWith(IntType.NPC, intArrayOf(Items.RELICYMS_BALM1_4848, Items.RELICYMS_BALM2_4846, Items.RELICYMS_BALM3_4844, Items.RELICYMS_BALM4_4842), NPCs.UGLUG_NAR_2039) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendItemDialogue(player, used.id,"You show the potion to Uglug Nar.").also { stage++ } + 1 -> playerl("Hey, here you go! I brought you some of the potion which should cure the disease. You said that you would buy some from me.").also { + if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { + stage = 2 + } else { + stage = 3 + } + } + 2 -> sendNPCDialogue(player, NPCs.UGLUG_NAR_2039, "Yous creatures is da funny ones... yous already solds me's ones now..and us can now sell un to yous!", FacialExpression.OLD_NORMAL).also { stage = END_DIALOGUE } + 3 -> sendNPCDialogue(player, NPCs.UGLUG_NAR_2039, "Yous creatures done da good fing...yous get many bright pretties for dis...!", FacialExpression.OLD_NORMAL).also { stage++ } + 4 -> sendDoubleItemDialogue(player, Item(Items.COINS_995, 1000), used as Item, "You sell the potion and get 1000 coins in return.").also { + if (removeItem(player, used)) { + addItemOrDrop(player, Items.COINS_995, 1000) + setAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, true) + } + stage = END_DIALOGUE + } + } + } + }) + return@onUseWith true + } + + // Stage 8 to 9 + on(Scenery.STAND_6897, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) == 8 && + getAttribute(player, ZogreFleshEaters.attributeSlashBashInstance, null) == null + ) { + // Zombie time. + sendMessage(player, "Something stirs behind you!") + val npc = NPC(NPCs.SLASH_BASH_2060) + setAttribute(player, ZogreFleshEaters.attributeSlashBashInstance, npc) + setAttribute(npc, "target", player) + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(2478, 9446, 0) + npc.direction = Direction.EAST + npc.init() + npc.attack(player) + } else if (getQuestStage(player, ZogreFleshEaters.questName) > 8) { + if (inInventory(player, Items.OGRE_ARTEFACT_4818)) { + sendMessage(player, "You find nothing on the stand.") + } else { + sendMessage(player, "You find another artifact.") + addItemOrDrop(player, Items.OGRE_ARTEFACT_4818) + } + } else { + // At no point should this be reached since you need to start the quest anyway. + sendMessage(player, "You find nothing on the stand.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogrePotionAndFletchingListeners.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogrePotionAndFletchingListeners.kt new file mode 100644 index 000000000..1db9325ff --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogrePotionAndFletchingListeners.kt @@ -0,0 +1,109 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +public enum class BrutalArrows(val nailItem: Int, val level: Int, val product: Int, val exp: Double) { + BRONZE_BRUTAL(Items.BRONZE_NAILS_4819, 7, Items.BRONZE_BRUTAL_4773, 8.4), + IRON_BRUTAL(Items.IRON_NAILS_4820, 18, Items.IRON_BRUTAL_4778, 15.6), + STEEL_BRUTAL(Items.STEEL_NAILS_1539, 33, Items.STEEL_BRUTAL_4783, 30.6), + BLACK_BRUTAL(Items.BLACK_NAILS_4821, 38, Items.BLACK_BRUTAL_4788, 39.0), + MITHRIL_BRUTAL(Items.MITHRIL_NAILS_4822, 49, Items.MITHRIL_BRUTAL_4793, 45.0), + ADAMANT_BRUTAL(Items.ADAMANTITE_NAILS_4823, 62, Items.ADAMANT_BRUTAL_4798, 61.2), + RUNE_BRUTAL(Items.RUNE_NAILS_4824, 77, Items.RUNE_BRUTAL_4803, 75.0) + ; + + companion object { + @JvmField + val nailItemMap = values().associateBy { it.nailItem } + val nailItemArray = nailItemMap.values.map { it.nailItem }.toIntArray() + } +} +/** + * This handles potions and fletching related to zogre flesh eaters. + * + * Relicym's Balm is unique to zogre flesh eaters. + * Maybe move this to herblore when it can handle quest requirements better. + */ +class ZogrePotionAndFletchingListeners : InteractionListener { + + override fun defineListeners() { + // ROGUES_PURSE_POTIONUNF_4840 is already in UnfinishedPotion.java + onUseWith(IntType.ITEM, Items.ROGUES_PURSE_POTIONUNF_4840, Items.CLEAN_SNAKE_WEED_1526) { player, used, with -> + if (!hasLevelStat(player, Skills.HERBLORE, 8)) { + sendMessage(player, "You need a herblore level of 8 to make this mix.") + return@onUseWith true + } + if (getQuestStage(player, ZogreFleshEaters.questName) < 7) { + sendMessage(player, "You need to have partially completed Zogre Flesh Eaters to make this mix.") + return@onUseWith true + } + + if(removeItem(player, used) && removeItem(player, with)) { + sendMessage(player, "You add the snake weed to the rogues purse solution and make Relicyms Balm.") + addItem(player, Items.RELICYMS_BALM3_4844) + rewardXP(player, Skills.HERBLORE, 40.0) + } + return@onUseWith true + } + + // FletchingListeners.kt + // ACHEY_TREE_LOGS_2862 -> UNSTRUNG_COMP_BOW_4825 -> COMP_OGRE_BOW_4827 + // Requirement to wield comp ogre bow. + onEquip(Items.COMP_OGRE_BOW_4827) { player, _ -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 8){ + return@onEquip true + } + sendMessage(player, "You need to complete part of Zogre Flesh Eaters to equip this.") + return@onEquip false + } + + + onUseWith(IntType.ITEM, BrutalArrows.nailItemArray, Items.FLIGHTED_OGRE_ARROW_2865) { player, used, with -> + fun getMaxAmount(_unused: Int = 0): Int { + val tips = amountInInventory(player, used.id) + val shafts = amountInInventory(player, with.id) + return min(tips, shafts) + } + + fun process() { + val amountThisIter = min(6, getMaxAmount()) + if (removeItem(player, Item(used.id, amountThisIter)) && removeItem(player, Item(with.id, amountThisIter))) { + addItem(player, BrutalArrows.nailItemMap[used.id]!!.product, amountThisIter) + sendMessage(player, "You make $amountThisIter brutal arrows.") + rewardXP(player, Skills.FLETCHING, BrutalArrows.nailItemMap[used.id]!!.exp) + } + } + + if (getQuestStage(player, ZogreFleshEaters.questName) < 7) { + sendMessage(player, "You need to complete part of Zogre Flesh Eaters to make these.") + return@onUseWith true + } + + if (getStatLevel(player, Skills.FLETCHING) < BrutalArrows.nailItemMap[used.id]!!.level) { + sendMessage(player, "You need a Fletching level of " + BrutalArrows.nailItemMap[used.id]!!.level + " to make these.") + return@onUseWith true + } + + sendSkillDialogue(player) { + create { id, amount -> + runTask( + player, + delay = 2, + repeatTimes = min(amount, getMaxAmount() / 6 + 1), + task = ::process + ) + } + calculateMaxAmount(::getMaxAmount) + withItems(Item(BrutalArrows.nailItemMap[used.id]!!.product, 5)) + } + return@onUseWith true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZombieBrentleVahnBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZombieBrentleVahnBehavior.kt new file mode 100644 index 000000000..d24485447 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZombieBrentleVahnBehavior.kt @@ -0,0 +1,40 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.timer.impl.Disease +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** The zombie you have to fight when you click on the skeleton. */ +class ZombieBrentleVahnBehavior : NPCBehavior(NPCs.ZOMBIE_1826) { + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + val disease = getOrStartTimer(victim, 10) + disease.hitsLeft = 10 + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops backpack when killed. + if (killer is Player && getQuestStage(killer, ZogreFleshEaters.questName) in 2..4) { + drops.add(Item(Items.RUINED_BACKPACK_4810)) + setAttribute(killer, ZogreFleshEaters.attributeFoughtZombie, true) + } + } + + var clearTime = 0 + override fun tick(self: NPC): Boolean { + // You have 400 ticks to kill this guy + if (clearTime++ > 400) { + clearTime = 0 + poofClear(self) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeBarmanDialogue.kt b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeBarmanDialogue.kt new file mode 100644 index 000000000..40b59d721 --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeBarmanDialogue.kt @@ -0,0 +1,110 @@ +package content.region.kandarin.gnomestronghold.dialogue + +import core.api.addItem +import core.api.inInventory +import core.api.openDialogue +import core.api.openNpcShop +import core.api.removeItem +import core.api.sendMessage +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +private const val INGREDIENT_COST = 20 +private const val NOT_ENOUGH_MONEY_MESSAGE = "You do not have enough money to buy that." + +/** + * Handles the dialogue for the Gnome Barman NPCs in the Tree Gnome Stronghold. + * @author Broseki + */ +@Initializable +class GnomeBarmanDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return GnomeBarmanDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GnomeBarmanDialogueStart(), npc) + return false + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BARMAN_849) + } +} + +class GnomeBarmanDialogueStart : DialogueLabeller() { + override fun addConversation() { + npc(ChatAnim.OLD_HAPPY, "Good day to you. What can I get you to drink?") + options( + DialogueOption("store", "What do you have?", expression = ChatAnim.FRIENDLY, spokenText = "What do you have."), + DialogueOption("nothing", "Nothing thanks.", expression = ChatAnim.FRIENDLY), + DialogueOption( + "ingredients", "Can I buy some ingredients?", + spokenText = "I was just wanting to buy a cocktail ingredient actually.", + expression = ChatAnim.FRIENDLY + ), + ) + + label("store") + npc(ChatAnim.OLD_HAPPY, "Here, take a look at our menu.") + exec { player, npc -> + openNpcShop(player, npc.id) + } + + label("nothing") + npc(ChatAnim.OLD_HAPPY, "Okay, take it easy.") + + label("ingredients") + npc(ChatAnim.OLD_HAPPY, "Sure thing, what did you want?") + options( + DialogueOption("lemon", "A lemon.", expression = ChatAnim.FRIENDLY), + DialogueOption("orange", "An orange.", expression = ChatAnim.FRIENDLY), + DialogueOption("shaker", "A cocktail shaker.", expression = ChatAnim.FRIENDLY), + DialogueOption( + "buynothing", "Nothing thanks.", + spokenText = "Actually nothing thanks.", + expression = ChatAnim.FRIENDLY + ), + ) + + label("lemon") + npc(ChatAnim.OLD_HAPPY, "$INGREDIENT_COST coins please.") + exec { player, _ -> + if (removeItem(player, Item(Items.COINS_995, INGREDIENT_COST))) { + addItem(player, Items.LEMON_2102) + } else { + sendMessage(player, NOT_ENOUGH_MONEY_MESSAGE) + } + } + + label("orange") + npc(ChatAnim.OLD_HAPPY, "$INGREDIENT_COST coins please.") + exec { player, _ -> + if (removeItem(player, Item(Items.COINS_995, INGREDIENT_COST))) { + addItem(player, Items.ORANGE_2108) + } else { + sendMessage(player, NOT_ENOUGH_MONEY_MESSAGE) + } + } + + label("shaker") + npc(ChatAnim.OLD_HAPPY, "$INGREDIENT_COST coins please.") + exec { player, _ -> + if (removeItem(player, Item(Items.COINS_995, INGREDIENT_COST))) { + addItem(player, Items.COCKTAIL_SHAKER_2025) + } else { + sendMessage(player, NOT_ENOUGH_MONEY_MESSAGE) + } + } + + label("buynothing") + // Just end the conversation here without any further dialogue + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeWomanDialogue.kt b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeWomanDialogue.kt new file mode 100644 index 000000000..c6f7fd2fd --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeWomanDialogue.kt @@ -0,0 +1,104 @@ +package content.region.kandarin.gnomestronghold.dialogue + +import core.api.addItemOrDrop +import core.api.openDialogue +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Handled the dialogue for the Gnome Woman NPCs in the Tree Gnome Stronghold. + * @author Broseki + */ +@Initializable +class GnomeWomanDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return GnomeWomanDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Pick a random number between 0 - 5 to determine the dialogue tree to use + val randomDialogue = (0..5).random() + + when (randomDialogue) { + 0 -> openDialogue(player, GnomeWomanDialogueFile0(), npc) + 1 -> openDialogue(player, GnomeWomanDialogueFile1(), npc) + 2 -> openDialogue(player, GnomeWomanDialogueFile2(), npc) + 3 -> openDialogue(player, GnomeWomanDialogueFile3(), npc) + 4 -> openDialogue(player, GnomeWomanDialogueFile4(), npc) + else -> openDialogue(player, GnomeWomanDialogueFile5(), npc) + } + return false + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GNOME_WOMAN_168, NPCs.GNOME_WOMAN_169) + } +} + +class GnomeWomanDialogueFile0 : DialogueLabeller() { + override fun addConversation() { + player(ChatAnim.FRIENDLY, "Hello.") + npc(ChatAnim.OLD_HAPPY, "Hello adventurer. Here are some wise words:") + player(ChatAnim.FRIENDLY, "OK.") + npc(ChatAnim.OLD_CALM_TALK1, "Happiness is inward and not outward. So it does not depend on what we have but on what we are!") + } +} + +class GnomeWomanDialogueFile1 : DialogueLabeller() { + override fun addConversation() { + player(ChatAnim.FRIENDLY, "Hello.") + npc(ChatAnim.OLD_HAPPY, "Hi. I've never seen so many humans in my life.") + player(ChatAnim.LAUGH, "I've never seen so many gnomes!") + npc(ChatAnim.OLD_LAUGH1, "So we're both learning.") + } +} + +class GnomeWomanDialogueFile2 : DialogueLabeller() { + override fun addConversation() { + player(ChatAnim.FRIENDLY, "Hello.") + npc(ChatAnim.OLD_HAPPY, "Hello traveller. Are you eating properly? You look tired.") + player(ChatAnim.FRIENDLY, "I think so.") + npc(ChatAnim.OLD_CALM_TALK1, "Here, get this worm down you. It'll do you the world of good.") + item(Item(Items.KING_WORM_2162), "The gnome gives you a worm.") + exec { player, npc -> + addItemOrDrop(player, Items.KING_WORM_2162) + } + player(ChatAnim.HAPPY, "Thanks!") + } +} + +class GnomeWomanDialogueFile3 : DialogueLabeller() { + override fun addConversation() { + player(ChatAnim.FRIENDLY, "Hello.") + npc(ChatAnim.OLD_HAPPY, "Well good day to you kind sir. Are you new to these parts?") + player(ChatAnim.FRIENDLY + , "Kind of.") + npc(ChatAnim.OLD_HAPPY, "Well if you're looking for a good night out: Blurberry's cocktail bar is great!") + } +} + +class GnomeWomanDialogueFile4 : DialogueLabeller() { + override fun addConversation() { + player(ChatAnim.FRIENDLY, "Hello.") + npc(ChatAnim.OLD_CALM_TALK1, "Some people grumble because roses have thorns. I'm thankful that thorns have roses!") + player(ChatAnim.HAPPY, "Good attitude!") + } +} + +class GnomeWomanDialogueFile5 : DialogueLabeller() { + override fun addConversation() { + player(ChatAnim.FRIENDLY, "Hello.") + player(ChatAnim.FRIENDLY, "How are you?") + npc(ChatAnim.OLD_HAPPY, "Not bad, a little worn out.") + player(ChatAnim.FRIENDLY, "Maybe you should have a lie down.") + npc(ChatAnim.OLD_HAPPY, "With three kids to feed I've no time for naps!") + player(ChatAnim.HAPPY, "Sounds like hard work!") + npc(ChatAnim.OLD_HAPPY, "It is but they're worth it.") + } +} diff --git a/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java b/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java index 7cec187ec..1322bf19c 100644 --- a/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java +++ b/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java @@ -17,6 +17,7 @@ import core.game.world.map.Location; import core.plugin.Initializable; import core.plugin.Plugin; import content.global.travel.EssenceTeleport; +import content.data.Quests; /** * Represents the wizard guild plugin. @@ -35,7 +36,6 @@ public final class WizardGuildPlugin extends OptionHandler { SceneryDefinition.forId(2155).getHandlers().put("option:open", this); SceneryDefinition.forId(1722).getHandlers().put("option:climb-up", this); new WizardDistentorDialogue().init(); - new ZavisticRarveDialogue().init(); new ProfessorImblewynDialogue().init(); new WizardFrumsconeDialogue().init(); new RobeStoreDialogue().init(); @@ -74,7 +74,7 @@ public final class WizardGuildPlugin extends OptionHandler { } break; case "teleport": - if (!player.getQuestRepository().isComplete("Rune Mysteries")) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { player.getPacketDispatch().sendMessage("You need to have completed the Rune Mysteries Quest to use this feature."); return true; } @@ -133,7 +133,7 @@ public final class WizardGuildPlugin extends OptionHandler { stage = 2; break; case 2: - if (!player.getQuestRepository().isComplete("Rune Mysteries")) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { player("Nothing thanks, I'm just looking around."); stage = 4; return true; @@ -175,68 +175,6 @@ public final class WizardGuildPlugin extends OptionHandler { } - /** - * Represents the dialogue used for zavistic rarve. - * @author 'Vexia - * @version 1.0 - */ - public final class ZavisticRarveDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code ZavisticRarveDialogue} {@code Object}. - */ - public ZavisticRarveDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code ZavisticRarveDialogue} {@code Object}. - * @param player the player. - */ - public ZavisticRarveDialogue(final Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new ZavisticRarveDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - npc("What are you doing...Oh, it's you...sorry...didn't", "realise... what can I do for you?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - player("Thanks for your help with all of this."); - stage = 1; - break; - case 1: - npc("Ooohh, no thanks required. It's I who should be", "thanking you my friend...your investigative mind has", "shown how vigilant we really should be for this type of", "evil use of the magical arts."); - stage = 2; - break; - case 2: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2059 }; - } - - } - /** * Represents the wizard distentor dialogue. * @author 'Vexia diff --git a/Server/src/main/content/region/kandarin/handlers/GnomeTortoiseNPC.kt b/Server/src/main/content/region/kandarin/handlers/GnomeTortoiseNPC.kt new file mode 100644 index 000000000..84d32fdbc --- /dev/null +++ b/Server/src/main/content/region/kandarin/handlers/GnomeTortoiseNPC.kt @@ -0,0 +1,284 @@ +package content.region.kandarin.handlers + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.MultiSwingHandler +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.impl.Animator.Priority +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +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.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/* + * Behavior is based on the following sources: + * https://www.youtube.com/watch?v=u2A-_ihV_2w (november 2008) + * https://www.youtube.com/watch?v=O0EIZu7-iys (august 2009) + * https://runescape.wiki/w/Tortoise?oldid=815524 https://web.archive.org/web/20090308094532/http://runescape.wikia.com/wiki/Tortoise + * + * todo fix att, str, def? I'm not sure what is the typical way to calculate these when they are unknown. + * level 79: HP 101, max hit 12, "low attack but good defence" + * level 92: HP 121, max hit 12, "low attack but good defence" + * + * https://runescape.wiki/w/Gnome_Archer?oldid=949978 https://web.archive.org/web/20090929124104/http://runescape.wikia.com/wiki/Gnome_archer + * https://runescape.wiki/w/Gnome_Driver?oldid=1235409 https://web.archive.org/web/20090929124109/http://runescape.wikia.com:80/wiki/Gnome_driver + * https://runescape.wiki/w/Gnome_Mage?oldid=1425756 https://web.archive.org/web/20090928131013/http://runescape.wikia.com:80/wiki/Gnome_mage + */ + +@Initializable +class GnomeTortoiseNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GnomeTortoiseNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TORTOISE_3808) + } + + fun spawnGnomes(location: Location, direction: Direction) { + + //todo: sometimes the child spawns or direction is wrong on death. does a move trigger right before it dies? + + var archerLoc = location + var driverLoc = location + var mageLoc = location + + // X D X 3x3 turtle, C center + // M C A D driver, M mage, A archer + // X X X + + // If I was smart I could probably do this with vectors, but I'm dumb so just doing the possibilities by hand. + if(direction == Direction.NORTH) { + archerLoc = location.transform(1,0,0) + driverLoc = location.transform(0,1,0) + mageLoc = location.transform(-1,0,0) + }else if(direction == Direction.NORTH_EAST) { + archerLoc = location.transform(1,-1,0) + driverLoc = location.transform(1,1,0) + mageLoc = location.transform(-1,1,0) + }else if(direction == Direction.EAST) { + archerLoc = location.transform(0,-1,0) + driverLoc = location.transform(1,0,0) + mageLoc = location.transform(0,1,0) + }else if(direction == Direction.SOUTH_EAST) { + archerLoc = location.transform(-1,-1,0) + driverLoc = location.transform(1,-1,0) + mageLoc = location.transform(1,1,0) + }else if(direction == Direction.SOUTH) { + archerLoc = location.transform(-1,0,0) + driverLoc = location.transform(0,-1,0) + mageLoc = location.transform(1,0,0) + }else if(direction == Direction.SOUTH_WEST) { + archerLoc = location.transform(-1,1,0) + driverLoc = location.transform(-1,-1,0) + mageLoc = location.transform(1,-1,0) + }else if(direction == Direction.WEST) { + archerLoc = location.transform(0,1,0) + driverLoc = location.transform(-1,0,0) + mageLoc = location.transform(0,-1,0) + }else if(direction == Direction.NORTH_WEST) { + archerLoc = location.transform(1,1,0) + driverLoc = location.transform(-1,1,0) + mageLoc = location.transform(-1,-1,0) + } + + val npcArcher = GnomeArcherNPC(NPCs.GNOME_ARCHER_3814, archerLoc) + npcArcher.sendChat("Argh!") + npcArcher.init() + + val npcDriver = GnomeDriverNPC(NPCs.GNOME_DRIVER_3815, driverLoc) + npcDriver.sendChat("Nooooo! Dobbie's dead!") + npcDriver.init() + + val npcMage = GnomeMageNPC(NPCs.GNOME_MAGE_3816, mageLoc) + npcMage.sendChat("Kill the infidel!") + npcMage.init() + } + + override fun finalizeDeath(killer: Entity?) { + val turtleLoc = this.centerLocation + val turtleDir = this.direction + spawnGnomes(turtleLoc, turtleDir) + super.finalizeDeath(killer) + // todo remove this debug if not needed. It's just telling me the "direction" the tortoise dies in so I can verify the direction that the child NPCs should spawn. + if (killer is Player) { + killer.debug(direction.toString()) + } + } +} + +//handles the attack switching +class GnomeTortoiseBehavior : NPCBehavior(NPCs.TORTOISE_3808) { + + private val combatHandler = MultiSwingHandler( + true, + // per wiki source, melee has a max hit of 12 + SwitchAttack( + CombatStyle.MELEE.swingHandler, + Animation(3953, Priority.HIGH) + ), + // todo correct the projectile locations (they should originate from the range or mage gnome, not the center). not sure how to do this. + SwitchAttack( + CombatStyle.RANGE.swingHandler, + Animation(3954, Priority.HIGH), + null, + null, + Projectile.create( + null as Entity?, + null, + 10, //bronze arrow + 35, + 30, + 10, + 50, + 14, + 255 + ) + ), + // per wiki source above, spell should be water strike with the sounds of ice barrage + SwitchAttack( + CombatStyle.MAGIC.swingHandler, + Animation(3955, Priority.HIGH), + null, + null, + Projectile.create( + null as Entity?, + null, + 94, //water strike + 35, + 30, + 10, + 50, + 14, + 255 + ) + ) + ) + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + return combatHandler + } +} + +// Handles Gnome Archer behavior +class GnomeArcherNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GnomeArcherNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GNOME_ARCHER_3814) + } + + override fun init() { + super.init() + this.isRespawn = false + this.isAggressive = true + this.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() { + override fun ignoreCombatLevelDifference(): Boolean { + return true + } + }) + } +} + +class GnomeArcherBehavior : NPCBehavior(NPCs.GNOME_ARCHER_3814) { + override fun onCreation(self: NPC) { + // stops the entity from instantly moving. + delayEntity(self, 1) + setAttribute(self, "despawn-time", GameWorld.ticks + 25) + } + + override fun tick(self: NPC): Boolean { + if (!self.inCombat() && (getAttribute(self, "despawn-time", 0) <= GameWorld.ticks)) + self.clear() + return true + } +} + +// Handles Gnome Mage behavior +class GnomeMageNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GnomeMageNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GNOME_MAGE_3816) + } + + override fun init() { + super.init() + this.isRespawn = false + this.isAggressive = true + this.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() { + override fun ignoreCombatLevelDifference(): Boolean { + return true + } + }) + } +} + +class GnomeMageBehavior : NPCBehavior(NPCs.GNOME_MAGE_3816) { + override fun onCreation(self: NPC) { + // stops the entity from instantly moving. + delayEntity(self, 1) + setAttribute(self, "despawn-time", GameWorld.ticks + 25) + } + + override fun tick(self: NPC): Boolean { + if (!self.inCombat() && (getAttribute(self, "despawn-time", 0) <= GameWorld.ticks)) + self.clear() + return true + } +} + +// Handles Gnome Driver behavior +class GnomeDriverNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GnomeDriverNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GNOME_DRIVER_3815) + } + + override fun init() { + super.init() + this.isRespawn = false + this.isAggressive = true + this.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() { + override fun ignoreCombatLevelDifference(): Boolean { + return true + } + }) + } +} + +class GnomeDriverBehavior : NPCBehavior(NPCs.GNOME_DRIVER_3815) { + override fun onCreation(self: NPC) { + // stops the entity from instantly moving. + delayEntity(self, 1) + setAttribute(self, "despawn-time", GameWorld.ticks + 25) + } + + override fun tick(self: NPC): Boolean { + if (!self.inCombat() && (getAttribute(self, "despawn-time", 0) <= GameWorld.ticks)) + self.clear() + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/handlers/RasoloNPC.java b/Server/src/main/content/region/kandarin/handlers/RasoloNPC.java deleted file mode 100644 index b75407700..000000000 --- a/Server/src/main/content/region/kandarin/handlers/RasoloNPC.java +++ /dev/null @@ -1,84 +0,0 @@ -package content.region.kandarin.handlers; - -import core.cache.def.impl.NPCDefinition; -import core.game.dialogue.DialoguePlugin; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -@Initializable -public class RasoloNPC extends OptionHandler { - @Override - public Plugin newInstance(Object arg) throws Throwable { - new RosaloDialouge().init(); - NPCDefinition.forId(1972).getHandlers().put("option:talk-to",this); - NPCDefinition.forId(1972).getHandlers().put("option:trade",this); - return null; - } - - @Override - public boolean handle(Player player, Node node, String option) { - if(option.equals("trade")){ - new NPC(1972).openShop(player); - } else { - player.getDialogueInterpreter().open(1972); - } - return false; - } - - /** - * Rasolo npc - * @author ceik - */ - - public class RosaloDialouge extends DialoguePlugin{ - public RosaloDialouge(){ - /** - * - */ - } - public RosaloDialouge(Player player){super(player);} - - @Override - public DialoguePlugin newInstance(Player player) { - return new RosaloDialouge(player); - } - - @Override - public boolean open(Object... args){ - npc("Hello, would you like to see my wares?"); - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch(stage){ - case 0: - player.getDialogueInterpreter().sendOptions("Select one", "Yes, please", "No, thanks"); - stage++; - break; - case 1: - switch(buttonId){ - case 1: - end(); - new NPC(1972).openShop(player); - break; - case 2: - player("No, thanks"); - stage++; - break; - } - break; - case 2: - end(); - break; - } - return true; - } - @Override - public int[] getIds() {return new int[] {1972};} - } -} diff --git a/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt b/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt index 1fd390535..b1233b698 100644 --- a/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt +++ b/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt @@ -1,115 +1,101 @@ package content.region.kandarin.pisc.dialogue -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.player.Player +import core.ServerConstants +import core.api.addItemOrDrop +import core.api.hasActivatedSecondaryBankAccount +import core.api.hasIronmanRestriction +import core.api.isUsingSecondaryBankAccount +import core.api.openBankAccount +import core.api.openBankPinSettings +import core.api.openGrandExchangeCollectionBox +import core.api.openNpcShop +import core.api.toggleBankAccount +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC import core.game.node.entity.player.link.IronmanMode -import core.plugin.Initializable +import core.game.node.item.Item import org.rs09.consts.Items import org.rs09.consts.NPCs -import core.game.dialogue.IfTopic -import core.game.dialogue.Topic -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE -/** - * Provides the regular dialogue for Arnold Lydspor. - * TODO: Swan Song quest will need a special case handling. - * - * @author vddCore - */ -@Initializable -class ArnoldLydsporDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when (stage) { - START_DIALOGUE -> npcl( - FacialExpression.FRIENDLY, - "Ah, you come back! What you want from Arnold, heh?" - ).also { stage++ } - - 1 -> showTopics( - IfTopic( - FacialExpression.ASKING, - "Can you open my bank account, please?", - 2, - !hasIronmanRestriction(player, IronmanMode.ULTIMATE) - ), - - IfTopic( - FacialExpression.NEUTRAL, - "I'd like to check my bank PIN settings.", - 3, - !hasIronmanRestriction(player, IronmanMode.ULTIMATE) - ), - IfTopic( - FacialExpression.NEUTRAL, - "I'd like to collect items.", - 4, - !hasIronmanRestriction(player, IronmanMode.ULTIMATE) - ), - Topic(FacialExpression.ASKING, "Would you like to trade?", 5), - Topic(FacialExpression.FRIENDLY, "Nothing, I just came to chat.", 7) - ) - - 2 -> { - openBankAccount(player) - end() - } - - 3 -> { - openBankPinSettings(player) - end() - } - - 4 -> { - openGrandExchangeCollectionBox(player) - end() - } - - 5 -> npcl( - FacialExpression.FRIENDLY, - "Ja, I have wide range of stock..." - ).also { stage++ } - - 6 -> { - openNpcShop(player, NPCs.ARNOLD_LYDSPOR_3824) - end() - } - - 7 -> npcl(FacialExpression.FRIENDLY, - "Ah, that is nice - always I like to chat, but " + - "Herr Caranos tell me to get back to work! " + - "Here, you been nice, so have a present." - ).also { stage++ } - - 8 -> sendItemDialogue( - player, - Items.CABBAGE_1965, - "Arnold gives you a cabbage." - ).also { - addItemOrDrop(player, Items.CABBAGE_1965) - stage++ - } - - 9 -> playerl( - FacialExpression.HALF_THINKING, - "A cabbage?" - ).also { stage++ } - - 10 -> npcl( - FacialExpression.HAPPY, - "Ja, cabbage is good for you!" - ).also { stage++ } - - 11 -> playerl( - FacialExpression.NEUTRAL, - "Um... Thanks!" - ).also { stage = END_DIALOGUE } +class ArnoldLydsporDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.ARNOLD_LYDSPOR_3824, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, ArnoldLydsporLabellerFile(), node as NPC) + return@on true + } + on(NPCs.ARNOLD_LYDSPOR_3824, IntType.NPC, "bank") { player, _ -> + openBankAccount(player) + return@on true + } + on(NPCs.ARNOLD_LYDSPOR_3824, IntType.NPC, "collect") { player, _ -> + openGrandExchangeCollectionBox(player) + return@on true } - - return true } - override fun getIds(): IntArray = intArrayOf(NPCs.ARNOLD_LYDSPOR_3824) -} \ No newline at end of file + class ArnoldLydsporLabellerFile : DialogueLabeller() { + override fun addConversation() { + npc(ChatAnim.FRIENDLY, "Ah, you come back! What you want from Arnold, heh?") + goto("main options") + + label("main options") + options( + DialogueOption("access", "Can you open my bank account please?", expression = ChatAnim.ASKING) { player, _ -> !hasIronmanRestriction(player, IronmanMode.ULTIMATE) }, + DialogueOption("buy second bank", "I'd like to open a secondary bank account.") { player, _ -> return@DialogueOption !hasIronmanRestriction(player, IronmanMode.ULTIMATE) && ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player) }, + DialogueOption("switch second bank", "I'd like to switch to my primary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && isUsingSecondaryBankAccount(player) }, + DialogueOption("switch second bank", "I'd like to switch to my secondary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && !isUsingSecondaryBankAccount(player) }, + DialogueOption("pin", "I'd like to check my PIN settings.", expression = ChatAnim.NEUTRAL) { player, _ -> !hasIronmanRestriction(player, IronmanMode.ULTIMATE) }, + DialogueOption("collect", "I'd like to collect items.", expression = ChatAnim.NEUTRAL) { player, _ -> !hasIronmanRestriction(player, IronmanMode.STANDARD) }, + DialogueOption("trade", "Would you like to trade?", expression = ChatAnim.ASKING), + DialogueOption("chat", "Nothing, I just came to chat.", expression = ChatAnim.FRIENDLY) { player, _ -> return@DialogueOption hasIronmanRestriction(player, IronmanMode.STANDARD) || !ServerConstants.SECOND_BANK } + ) + + label("access") + exec { player, _ -> openBankAccount(player) } + goto("nowhere") + + label("buy second bank") + npc(ChatAnim.GUILTY, "I'm so sorry! My little shop does not have the fibre-optic connections to be able to open a second account. Try asking again in a brick-and-mortar building in a big city!") + player(ChatAnim.FRIENDLY, "That's okay, I understand. I will ask again in a big bank like Varrock's.") + goto("nowhere") + + label("switch second bank") + exec { + player, _ -> toggleBankAccount(player) + loadLabel(player, if (isUsingSecondaryBankAccount(player)) "now secondary" else "now primary") + } + label("now primary") + npc("Your active bank account has been switched. You can now access your primary account.") + goto("main options") + label("now secondary") + npc("Your active bank account has been switched. You can now access your secondary account.") + goto("main options") + + label("pin") + exec { player, _ -> openBankPinSettings(player) } + goto("nowhere") + + label("collect") + exec { player, _ -> openGrandExchangeCollectionBox(player) } + goto("nowhere") + + label("trade") + npc(ChatAnim.FRIENDLY, "Ja, I have wide range of stock...") + exec { player, _ -> openNpcShop(player, NPCs.ARNOLD_LYDSPOR_3824) } + goto("nowhere") + + label("chat") + npc("Ah, that is nice - always I like to chat, but Herr Caranos tell me to get back to work! Here, you been nice, so have a present.") + exec { player, _ -> addItemOrDrop(player, Items.CABBAGE_1965) } + item(Item(Items.CABBAGE_1965), "Arnold gives you a cabbage.") + player(ChatAnim.HALF_THINKING, "A cabbage?") + npc(ChatAnim.HAPPY, "Ja, cabbage is good for you!") + player(ChatAnim.NEUTRAL, "Um... Thanks!") + goto("nowhere") + } + } +} diff --git a/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java b/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java index dd3a27bd2..b926d7fde 100644 --- a/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java +++ b/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java @@ -8,6 +8,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.item.Item; +import org.rs09.consts.Items; /** * Handles the MathiasFlaconryDialogue dialogue. @@ -49,7 +50,8 @@ public class MathiasFlaconryDialogue extends DialoguePlugin { } break; case 323: - end(); + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "Well, you're welcome to come back if you change", "your mind."); + stage = 967; break; case 95: if (player.getBank().containsItem(FALCON) || player.getEquipment().containsItem(FALCON) || player.getInventory().containsItem(FALCON)) { @@ -58,7 +60,7 @@ public class MathiasFlaconryDialogue extends DialoguePlugin { return true; } if (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null || player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null) { - interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Sorry, free your hands, weapon, and shield slot first."); + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Sorry, you really need both hands free for falconry. I'd", "suggest that you put away your weapons and gloves before", "we start."); stage = 99; break; } @@ -69,11 +71,11 @@ public class MathiasFlaconryDialogue extends DialoguePlugin { stage = 97; } else { end(); - player.getPacketDispatch().sendMessage("You need 500 gold goins."); + player.getPacketDispatch().sendMessage("You need 500 gold coins."); } break; case 97: - interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Don't worry: I'll keep and eye on you to make sure", "you don't upset it roo much."); + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Don't worry; I'll keep an eye on you to make sure", "you don't upset it too much."); stage = 99; break; case 99: @@ -84,22 +86,109 @@ public class MathiasFlaconryDialogue extends DialoguePlugin { stage = 501; break; case 501: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Could I have a go with your bird?"); + interpreter.sendOptions("Select an Option", "Do you have any quests I could do?", "What is this place?", "Could I have a go with your bird?"); stage = 502; break; case 502: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you have any quests I could do?"); + stage = 600; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What is this place?"); + stage = 700; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Could I have a go with your bird?"); + stage = 800; + break; + } + break; + case 600: + interpreter.sendDialogues(5093, FacialExpression.ASKING, "A quest? What a strange notion. Do you normally go", "around asking complete strangers for quests?"); + stage = 601; + break; + case 601: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Er, yes, now you come to mention it."); + stage = 602; + break; + case 602: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Oh, ok then. Well, no, I don't; sorry."); + stage = 967; + break; + + case 700: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "A good question; straight and to the point. My name is ", "Matthias, I am a falconer, and this is where I train", "my birds."); + stage = 701; + break; + case 701: + interpreter.sendOptions("Select an Option", "Do you have any quests I could do?", "That sounds like fun; could I have a go?", "That doesn't sound like my sort of thing.", "What's this falconry thing all about then?"); + stage = 702; + break; + case 702: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you have any quests I could do?"); + stage = 600; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "That sounds like fun; could I have a go?"); + stage = 800; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That doesn't sound like my sort of thing."); + stage = 720; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's this falconry thing all about then?"); + stage = 750; + break; + } + break; + case 720: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Fair enough; it does require a great deal of patience and", "skill, so I can understand if you might feel intimidated."); + stage = 967; + break; + case 750: + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "Well, some people see it as a sport, although such a term", "does not really convey the amount of patience and", "dedication required to be proficient at the task."); + stage = 751; + break; + case 751: + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "Putting it simply, it is the training and use of birds of", "prey in hunting quarry."); + stage = 752; + break; + case 752: + interpreter.sendDialogues(player, FacialExpression.ASKING, "So it's like keeping a pet then?"); + stage = 753; + break; + case 753: + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "Not exactly, no. Such a bird can never really be", "considered tame in the same way that a dog can."); + stage = 754; + break; + case 754: + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "They can be trained to associate people or places with", "food though, and, as such, a good falconer can get a", "trained bird to do as he wishes."); + stage = 701; + break; + + case 800: if (player.getSkills().getLevel(Skills.HUNTER) < 43) { npc("Try coming back when you're more experienced", "I wouldn't want my birds being injured."); stage = 967; return true; } - interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Training falcons is a lot of work and I", "doubt you're up to the task. However, I suppose", "I could let you try hunting with one."); - stage = 503; + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Training falcons is a lot of work and I doubt you're up", "to the task. However, I suppose I could let you try", "hunting with one."); + stage = 801; break; - case 503: - interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "I have some tamer birds that I occasionally lend to rich", "noblemen who consider it a sufficiently refined sport for", "their tastes. and you look like the kind who might", "appreciate a good hunt."); + case 801: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "I have some tamer birds that I occasionally lend to rich", "noblemen who consider it a sufficiently refined sport for", "their tastes, and you look like the kind who might", "appreciate a good hunt."); + stage = 802; + break; + case 802: + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "I'd have to request a small fee, mind you; how does", "500 gold pieces sound?"); stage = 90; break; + case 900: interpreter.sendOptions("Select an Option", "Yes, please.", "No thank you."); stage = 901; @@ -125,7 +214,48 @@ public class MathiasFlaconryDialogue extends DialoguePlugin { case 967: end(); break; + + case 1000: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Ah, you're back. How are you getting along with her then?"); + stage = 1001; + break; + case 1001: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It's certainly harder than it looks."); + stage = 1002; + break; + case 1002: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Sorry, but I was talking to the falcon, not you. But yes it", "is. Have you had enough yet?"); + stage = 1003; + break; + case 1003: + interpreter.sendOptions("Select an Option", "Actually, I'd like to keep trying a little longer.", "I think I'll leave it for now."); + stage = 1004; + break; + case 1004: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Actually, I'd like to keep trying a little longer."); + stage = 1010; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I think I'll leave it for now."); + stage = 1020; + break; + } + break; + case 1010: + interpreter.sendDialogues(5093, FacialExpression.NEUTRAL, "Ok then, just come talk to me when you're done."); + stage = 967; + break; + case 1020: + player.getInventory().remove(FALCON); + player.getEquipment().remove(FALCON, true); + + interpreter.sendDialogue("You give the falcon and glove back to Matthias."); + stage = 967; + break; } + return true; } @@ -145,6 +275,11 @@ public class MathiasFlaconryDialogue extends DialoguePlugin { stage = 900; return true; } + if (player.getEquipment().contains(10024, 1) || player.getInventory().contains(10024, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello again."); + stage = 1000; + return true; + } if (args.length == 2) quick = true; if (quick) { diff --git a/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt b/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt index b33c40068..4ae4df149 100644 --- a/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt +++ b/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt @@ -9,12 +9,13 @@ import org.rs09.consts.Animations import org.rs09.consts.Items import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.data.Quests class SeaweedNetHandler : InteractionListener { override fun defineListeners() { on(NET, IntType.SCENERY, "Take-from"){ player, node -> - if (!isQuestComplete(player, "Swan Song")) + if (!isQuestComplete(player, Quests.SWAN_SONG)) { sendMessage(player, "You must complete Swan Song first.") } diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java index a43f229ad..ae586a3f3 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.dwarfcannon; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -44,7 +45,7 @@ public class CaptainLawgofDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(DwarfCannon.NAME); + quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); switch (quest.getStage(player)) { case 80: player("Hi."); diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java index 37af05ec3..8268ced31 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java @@ -8,6 +8,7 @@ import core.plugin.ClassScanner; import core.game.node.entity.skill.Skills; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents the dwarf cannon quest. @@ -15,12 +16,6 @@ import static core.api.ContentAPIKt.*; */ @Initializable public class DwarfCannon extends Quest { - - /** - * The name of this quest. - */ - public static final String NAME = "Dwarf Cannon"; - /** * The dwarf remain item. */ @@ -40,13 +35,13 @@ public class DwarfCannon extends Quest { * The mould item. */ public static final Item MOULD = new Item(4); - public static int[] railVarbits = new int[] { 2240, 2241, 2242, 2243, 2244, 2245 }; + public static int[] railVarbits = new int[] { 2240, 2241, 2242, 2243, 2244, 2245 }; /** * Constructs a new {@Code DwarfCannon} {@Code Object} */ public DwarfCannon() { - super(NAME, 49, 48, 1); + super(Quests.DWARF_CANNON, 49, 48, 1); } @Override diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java index 7739d88cf..876f9cfda 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.dwarfcannon; +import content.data.Quests; import core.cache.def.impl.SceneryDefinition; import core.game.component.Component; import core.game.component.ComponentDefinition; @@ -17,7 +18,6 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.tools.Log; -import core.tools.SystemLogger; import core.game.system.task.Pulse; import core.game.world.GameWorld; import core.game.world.map.Location; @@ -44,6 +44,7 @@ public class DwarfCannonPlugin extends OptionHandler { SceneryDefinition.forId(3).getHandlers().put("option:open", this); SceneryDefinition.forId(5).getHandlers().put("option:inspect", this); SceneryDefinition.forId(2).getHandlers().put("option:enter", this); + SceneryDefinition.forId(11).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(13).getHandlers().put("option:climb-over", this); SceneryDefinition.forId(15601).getHandlers().put("option:inspect", this); for (int i = 15; i < 21; i++) { @@ -61,14 +62,14 @@ public class DwarfCannonPlugin extends OptionHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest(DwarfCannon.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); if (quest.getStage(player) > 50) { player.getDialogueInterpreter().sendDialogues(player, null, "This should work nicely now that I've fixed it."); return true; } //setVarp(player, 1, 2041, true); setVarp(player, 0, 8, true); - player.getQuestRepository().getQuest(DwarfCannon.NAME).setStage(player, 60); + player.getQuestRepository().getQuest(Quests.DWARF_CANNON).setStage(player, 60); player.sendMessage("Well done! You've fixed the cannon! Better go and tell Captain Lawgof."); /* * Component component = new Component(409); @@ -85,7 +86,7 @@ public class DwarfCannonPlugin extends OptionHandler { @Override public boolean handle(final Player player, final Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest(DwarfCannon.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); switch (node.getId()) { case 3: if (!node.getLocation().equals(new Location(3015, 3453, 0))) { @@ -110,6 +111,13 @@ public class DwarfCannonPlugin extends OptionHandler { player.animate(Animation.create(845)); player.teleport(new Location(2619, 9797, 0), 2); break; + case 11: + if (node.getLocation().equals(new Location(2570, 3443, 1)) + && quest.getStage(player) == 20 + && !player.hasItem(DwarfCannon.DWARF_REMAINS)) { + setVarp(player, 0, 3, true); + } + return ClimbActionHandler.climbLadder(player, node.asScenery(), option); case 13: ClimbActionHandler.climb(player, new Animation(828), new Location(2623, 3391, 0)); break; @@ -309,7 +317,7 @@ public class DwarfCannonPlugin extends OptionHandler { //setVarp(player, 1, 2041, true); //setVarp(player, 0, 8, true); - player.getQuestRepository().getQuest(DwarfCannon.NAME).setStage(player, 60); + player.getQuestRepository().getQuest(Quests.DWARF_CANNON).setStage(player, 60); player.sendMessage("Well done! You've fixed the cannon! Better go and tell Captain Lawgof."); GameWorld.getPulser().submit(new Pulse(5, player) { @Override diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java index 11cc1886d..08cedded9 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.dwarfcannon; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -41,7 +42,7 @@ public class LollkDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(DwarfCannon.NAME); + quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); switch (quest.getStage(player)) { case 40: npc("Thank the heavens, you saved me!", "I thought I'd be goblin lunch for sure!"); diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java index be7fa1847..05ac29b60 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.dwarfcannon; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -49,7 +50,7 @@ public class NulodionDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(DwarfCannon.NAME); + quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); switch (quest.getStage(player)) { case 70: player("Hello there."); diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt index 9d9aea830..9923b7426 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt @@ -4,7 +4,6 @@ import content.global.handlers.iface.BookInterface import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet -import core.api.setAttribute import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt index fa22f2bed..cf4ac3326 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -87,8 +88,9 @@ class DMCManual : InteractionListener { override fun defineListeners() { - on(Items.INSTRUCTION_MANUAL_5, IntType.ITEM, "read") { player, _ -> + on(Items.INSTRUCTION_MANUAL_5, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java index 736bb57eb..0fbe40125 100644 --- a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java @@ -12,6 +12,7 @@ import core.game.node.item.Item; import core.plugin.Plugin; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * Handles the Dwarf multi-cannon. @@ -73,7 +74,7 @@ public final class DwarfMultiCannonPlugin extends OptionHandler { player.getPacketDispatch().sendMessage("You don't have all the cannon components!"); return true; } - if (!player.getQuestRepository().isComplete("Dwarf Cannon") && player.getDetails().getRights() != Rights.ADMINISTRATOR) { + if (!player.getQuestRepository().isComplete(Quests.DWARF_CANNON) && player.getDetails().getRights() != Rights.ADMINISTRATOR) { player.getPacketDispatch().sendMessage("You have to complete the Dwarf Cannon to know how to use this."); return true; } diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java index 9a62eb53b..8ed55ae9e 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java @@ -6,6 +6,7 @@ import core.plugin.Initializable; import core.game.node.entity.player.Player; import core.game.activity.ActivityManager; import core.game.dialogue.DialoguePlugin; +import content.data.Quests; @Initializable @@ -126,7 +127,7 @@ public final class BonzoDialogue extends DialoguePlugin { player.getDialogueInterpreter().sendDialogue("You are given the Hemenester fishing trophy!"); player.getInventory().add(FishingContest.FISHING_TROPHY); player.getInventory().remove(FishingContest.RAW_GIANT_CARP); - player.getQuestRepository().setStage(QuestRepository.getQuests().get("Fishing Contest"),20); + player.getQuestRepository().setStage(QuestRepository.getQuests().get(Quests.FISHING_CONTEST),20); stage = 100; break; } diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java index a48682faa..6e56d58e5 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java @@ -6,6 +6,7 @@ import core.game.node.item.GroundItemManager; import core.plugin.Initializable; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; +import content.data.Quests; @Initializable public class DwarfDialogue extends DialoguePlugin { @@ -22,7 +23,12 @@ public class DwarfDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - int questStage = player.getQuestRepository().getStage("Fishing Contest"); + int questStage = player.getQuestRepository().getStage(Quests.FISHING_CONTEST); + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) == 100){ + npc(FacialExpression.OLD_NORMAL,"Welcome, oh great fishing champion!","Feel free to pop by and use","our tunnel any time!"); + stage = 2500; + return true; + } if((questStage < 20 && questStage > 0) && !player.getInventory().containsItem(FishingContest.FISHING_PASS)){ player("I lost my fishing pass..."); stage = 1000; @@ -33,16 +39,11 @@ public class DwarfDialogue extends DialoguePlugin { stage = 2000; return true; } - if(player.getQuestRepository().getStage("Fishing Contest") >= 10 && !player.getAttribute("fishing_contest:won",false)){ + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) >= 10 && !player.getAttribute("fishing_contest:won",false)){ npc(FacialExpression.OLD_NORMAL,"Have you won yet?"); stage = 1500; return true; } - if(player.getQuestRepository().getStage("Fishing Contest") == 100){ - npc(FacialExpression.OLD_NORMAL,"Welcome, oh great fishing champion!","Feel free to pop by and use","our tunnel any time!"); - stage = 2500; - return true; - } npc(FacialExpression.OLD_NORMAL,"Hmph! What do you want?"); stage = 0; return true; @@ -172,7 +173,7 @@ public class DwarfDialogue extends DialoguePlugin { if(!player.getInventory().add(FishingContest.FISHING_PASS)){ GroundItemManager.create(FishingContest.FISHING_PASS,player.getLocation()); } - player.getQuestRepository().getQuest("Fishing Contest").start(player); + player.getQuestRepository().getQuest(Quests.FISHING_CONTEST).start(player); stage++; break; case 58: @@ -220,7 +221,7 @@ public class DwarfDialogue extends DialoguePlugin { stage++; break; case 2004: - player.getQuestRepository().getQuest("Fishing Contest").finish(player); + player.getQuestRepository().getQuest(Quests.FISHING_CONTEST).finish(player); player.getInventory().remove(FishingContest.FISHING_TROPHY); end(); break; diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java index 1e87b8df7..9e01f552e 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java @@ -5,10 +5,11 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.Initializable; import core.game.node.entity.skill.Skills; +import content.data.Quests; @Initializable public class FishingContest extends Quest { - public FishingContest(){super("Fishing Contest",62,61,1,11,0,1,5);} + public FishingContest(){super(Quests.FISHING_CONTEST,62,61,1,11,0,1,5);} public static final Item FISHING_ROD = new Item(307); public static final Item FISHING_PASS = new Item(27); public static final Item RED_VINE_WORM = new Item(25); @@ -18,27 +19,50 @@ public class FishingContest extends Quest { public static final Item GARLIC = new Item(1550); public static final Item SPADE = new Item(952); + // Winner is stranger in black if you did not do the garlic. + // https://www.youtube.com/watch?v=6zL7M8mCL30 @Override public void drawJournal(Player player, int stage) { - int line = 11; + int line = 12; super.drawJournal(player, stage); - if(stage < 10) { - line(player, "I can start this quest by trying to take the !!shortcut??", line++); - line(player, "near !!White Wolf Mountain??", line++); - line(player,"I need level !!10 Fishing?? to start this quest.",line++,player.getSkills().getLevel(Skills.FISHING) >= 10); - } else if (stage >= 10){ - line(player,"The !!mountain Dwarves' home?? would be an ideal way to get across ",line++,stage >= 20); - line(player,"White Wolf Mountain safely. However, the Dwarves aren't too",line++, stage >= 20); - line(player,"fond of strangers. They will let you through if you can !!bring ",line++, stage >= 20); - line(player,"!!them a trophy.?? The trophy is the prize for the annual Hemenster",line++,stage >= 20); - line(player,"!!fishing competition.??",line++,stage >= 20); - if(stage == 20) - line(player,"I should return to !!Austri?? or !!Vestri??.",line++); - if(stage >= 100){ - line(player,"%%QUEST COMPLETE!&&",line++); + if (stage == 0) { + line(player, "I can start this quest by speaking to the !!Dwarves?? at the", line++); + line(player, "tunnel entrances on either side of !!White Wolf Mountain??.", line++); + line(player,"!!I must have level 10 fishing.??", line++, player.getSkills().getLevel(Skills.FISHING) >= 10); + } else if ( stage < 100 ) { + line(player, "The Dwarves will let me use the tunnel through White Wolf", line++, true); + line(player, "Mountain if I can will the Hemenster Fishing Competition.", line++, true); + + if (stage >= 20) { + line(player,"I easily won the contest by catching some Giant Carp.", line++, false); + } else if (stage >= 10) { + // https://youtu.be/z4MfANC2KqI + line(player, "They gave me a !!Fishing Contest Pass?? to enter the contest.", line++, false); + line(player, "I need to bring them back the !!Hemenster Fishing Trophy??.", line++, false); } + + if (stage >= 100) { + + } else if (stage >= 20) { + // https://youtu.be/rysJl-DRihE + line(player, "I should take back the !!Trophy?? back to the !!Dwarf?? at the side of", line++, false); + line(player, "!!White Wolf Mountain?? and claim my !!reward??.", line++, false); + } + + } else { + // https://youtu.be/u5Osw_jas4A + line(player, "The Dwarves' wanted me to earn their friendship by winning", line++, true); + line(player, "the Hemenster Fishing Competition.", line++, true); + line(player, "I scared away a vampyre with some garlic and easily won the", line++, true); + line(player, "contest by catching some Giant Carp.", line++, true); + line++; + line(player,"%%QUEST COMPLETE!&&", line++); + line++; + line(player, "As a reward for getting the Fishing Competition Trophy the", line++, false); + line(player, "Dwarves will let me use their tunnel to travel quickly and", line++, false); + line(player, "safely under White Wolf Mountain anytime I wish.", line++, false); } } @@ -47,9 +71,10 @@ public class FishingContest extends Quest { int ln = 10; super.finish(player); player.getPacketDispatch().sendItemZoomOnInterface(FISHING_TROPHY.getId(), 230, 277, 5); + // https://youtu.be/8dK362LbYdE drawReward(player,"1 Quest Point",ln++); - drawReward(player,"2437 Fishing XP.",ln++); - drawReward(player,"Access to the White Wolf Mountain shortcut.",ln); + drawReward(player,"2437 Fishing XP",ln++); + drawReward(player,"Access to Tunnel shortcut",ln); player.removeAttribute("fishing_contest:garlic"); player.removeAttribute("fishing_contest:won"); player.removeAttribute("fishing_contest:pass-shown"); diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java index ec13a470a..5771f2dab 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java @@ -13,6 +13,7 @@ import core.plugin.Plugin; import org.rs09.consts.Items; import core.game.interaction.PluginInteraction; import core.game.interaction.PluginInteractionManager; +import content.data.Quests; @Initializable public class GarlicPipeInteraction extends PluginInteraction { @@ -31,7 +32,7 @@ public class GarlicPipeInteraction extends PluginInteraction { Scenery usedWith = event.getUsedWith().asScenery(); Item used = event.getUsedItem(); - if(used.getId() == Items.GARLIC_1550 && usedWith.getId() == 41 && usedWith.getLocation().equals(Location.create(2638, 3446, 0)) && player.getQuestRepository().getStage("Fishing Contest") > 0){ + if(used.getId() == Items.GARLIC_1550 && usedWith.getId() == 41 && usedWith.getLocation().equals(Location.create(2638, 3446, 0)) && player.getQuestRepository().getStage(Quests.FISHING_CONTEST) > 0){ player.getPulseManager().run(new MovementPulse(player, usedWith.getLocation().transform(0, -1, 0)) { @Override public boolean pulse() { diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java index 96829b11d..7a79ca976 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java @@ -9,6 +9,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import core.game.interaction.PluginInteraction; import core.game.interaction.PluginInteractionManager; +import content.data.Quests; @Initializable public class GateInteraction extends PluginInteraction { @@ -27,11 +28,11 @@ public class GateInteraction extends PluginInteraction { } public boolean handleGate(Player player, Node node){ - if(!player.getAttribute("fishing_contest:pass-shown",false) || player.getQuestRepository().getStage("Fishing Contest") < 10) { + if(!player.getAttribute("fishing_contest:pass-shown",false) || player.getQuestRepository().getStage(Quests.FISHING_CONTEST) < 10) { player.getPulseManager().run(new MovementPulse(player, node.asScenery().getLocation().transform(1, 0, 0)) { @Override public boolean pulse() { - if(player.getQuestRepository().getStage("Fishing Contest") >= 10){ + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) >= 10){ player.sendMessage("You should give your pass to Morris."); } else { player.sendMessage("You need a fishing pass to fish here."); diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java index c4ca0001b..97daa72b1 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java @@ -11,12 +11,13 @@ import core.plugin.Plugin; import core.game.interaction.PluginInteraction; import core.game.interaction.PluginInteractionManager; import core.game.world.repository.Repository; +import content.data.Quests; @Initializable public class StairInteraction extends PluginInteraction { @Override public boolean handle(Player player, Node node) { - if(!player.getQuestRepository().isComplete("Fishing Contest")) { + if(!player.getQuestRepository().isComplete(Quests.FISHING_CONTEST)) { Scenery object = node.asScenery(); switch (object.getId()) { case 57: diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java index 50d7e4a53..17ceb597a 100644 --- a/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java @@ -10,6 +10,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import core.game.interaction.PluginInteraction; import core.game.interaction.PluginInteractionManager; +import content.data.Quests; @Initializable public class VineInteraction extends PluginInteraction { @@ -24,7 +25,7 @@ public class VineInteraction extends PluginInteraction { @Override public boolean handle(Player player, Node node) { if(node instanceof Scenery){ - if(player.getQuestRepository().getStage("Fishing Contest") > 0 && player.getQuestRepository().getStage("Fishing Contest") < 100){ + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) > 0 && player.getQuestRepository().getStage(Quests.FISHING_CONTEST) < 100){ player.getPulseManager().run(new MovementPulse(player, node.asScenery().getLocation().transform(0, 0, 0)) { @Override public boolean pulse() { diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt index 00aa223ea..4d9c58b1c 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.grandtree +import content.data.Quests import core.api.addItemOrDrop import core.api.getQuestStage import core.api.sendDialogue @@ -10,7 +11,7 @@ import org.rs09.consts.Items class AnitaDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - when(getQuestStage(player!!, TheGrandTree.questName)){ + when(getQuestStage(player!!, Quests.THE_GRAND_TREE)){ 60 -> { if(player!!.hasItem(Item(Items.GLOUGHS_KEY_788)) && stage < 12){ when(stage){ diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt index 2afe9f1cf..186d85616 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt @@ -1,20 +1,16 @@ package content.region.kandarin.quest.grandtree -import content.region.misthalin.dorgeshuun.quest.thelosttribe.LostTribeCutscene import core.ServerConstants -import core.api.openDialogue import core.api.sendChat -import core.api.sendDialogue -import core.api.sendMessage import core.game.activity.Cutscene import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.game.world.map.Direction import core.game.world.map.Location -import core.game.global.action.DoorActionHandler -import core.game.node.entity.npc.NPC +import core.game.world.update.flag.context.Animation import org.rs09.consts.NPCs +// Source video https://www.youtube.com/watch?v=LS1Xtuz0sLA class BlackDemonCutscene(player: Player) : Cutscene(player) { override fun setup() { setExit(Location.create(2491, 9864, 0)) @@ -23,7 +19,6 @@ class BlackDemonCutscene(player: Player) : Cutscene(player) { } loadRegion(9882) addNPC(NPCs.GLOUGH_671, 48, 8, Direction.WEST) - addNPC(NPCs.BLACK_DEMON_677, 43, 9, Direction.EAST) } override fun runStage(stage: Int) { @@ -40,6 +35,8 @@ class BlackDemonCutscene(player: Player) : Cutscene(player) { rotateCamera(0, 0) sendChat(player, "Hello?") player.face(getNPC(NPCs.GLOUGH_671)!!) + addNPC(NPCs.BLACK_DEMON_677, 39, 8, Direction.EAST) + move(getNPC(NPCs.BLACK_DEMON_677)!!, 41, 8) timedUpdate(3) } 2 -> { @@ -53,7 +50,7 @@ class BlackDemonCutscene(player: Player) : Cutscene(player) { timedUpdate(10) } 4 -> { - moveCamera(55, 4,2000) + moveCamera(55, 4, 2000) rotateCamera(55, 6) timedUpdate(4) } @@ -62,24 +59,27 @@ class BlackDemonCutscene(player: Player) : Cutscene(player) { playerDialogueUpdate(FacialExpression.SCARED, "Glough?") } 6 -> { - dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "You really are becoming a headache! Well, at least now you can die knowing you were right, it will save me having to hunt you down like all the other human filth of " + ServerConstants.SERVER_NAME + "!") + dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.OLD_ANGRY1, "You really are becoming a headache! Well, at least now you can die knowing you were right, it will save me having to hunt you down like all the other human filth of " + ServerConstants.SERVER_NAME + "!") } 7 -> { playerDialogueUpdate(FacialExpression.SCARED, "You're crazy, Glough!") } 8 -> { - dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "Bah! Well, soon you'll see, the gnomes are ready to fight. In three weeks this tree will be dead wood, in ten weeks it will be 30 battleships! Finally we will rid the world of the disease called humanity!") + dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.OLD_ANGRY1, "Bah! Well, soon you'll see, the gnomes are ready to fight. In three weeks this tree will be dead wood, in ten weeks it will be 30 battleships! Finally we will rid the world of the disease called humanity!") } 9 -> { playerDialogueUpdate(FacialExpression.SCARED, "What makes you think I'll let you get away with it?") } 10 -> { - moveCamera(47,9) - rotateCamera(40, 9) - dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "Fool...meet my little friend!") + moveCamera(55, 8, 700) + rotateCamera(48, 8) + val demon = getNPC(NPCs.BLACK_DEMON_677)!! + move(demon, 46, 8) + demon.animate(Animation(64, 140)) + dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.OLD_ANGRY1, "Fool...meet my little friend!") } 11 -> { - end{ + end(fade = false){ BlackDemonNPC(NPCs.BLACK_DEMON_677, Location.create(2485, 9864, 0)).init() } } diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt index cdefc97de..112321405 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt @@ -1,13 +1,11 @@ package content.region.kandarin.quest.grandtree -import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName +import content.data.Quests import core.api.* import core.game.node.entity.Entity import core.game.node.entity.npc.AbstractNPC -import core.game.node.entity.player.Player import core.game.world.map.Location import core.plugin.Initializable -import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.interaction.InteractionListener @@ -28,7 +26,7 @@ class BlackDemonNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,lo override fun finalizeDeath(killer: Entity?) { // In the event that this npcID is used somewhere else... if(killer!!.asPlayer().location.regionId == 9882) { - setQuestStage(killer!!.asPlayer(), questName, 98) + setQuestStage(killer!!.asPlayer(), Quests.THE_GRAND_TREE, 98) this.isRespawn = false } super.finalizeDeath(killer) diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt index 1460a7399..2b225bb47 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.grandtree +import content.data.Quests import content.global.travel.glider.Gliders import core.api.getQuestStage import core.api.teleport @@ -10,7 +11,7 @@ import core.tools.END_DIALOGUE class CaptainErrdoDialogue: DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - when(getQuestStage(player!!, TheGrandTree.questName)){ + when(getQuestStage(player!!, Quests.THE_GRAND_TREE)){ 55 -> { if(player!!.location.regionId == 11567){ when(stage){ diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt index 24feddcd1..d4af65825 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.quest.grandtree -import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName +import content.data.Quests import core.ServerConstants import core.api.* import core.game.dialogue.DialogueFile @@ -18,7 +18,7 @@ import org.rs09.consts.NPCs class CharlieDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, questName)) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { 46 -> { when (stage) { 0 -> playerl("Tell me. Why would you want to kill the Grand Tree?").also { stage++ } @@ -32,7 +32,7 @@ class CharlieDialogue : DialogueFile() { 8 -> npcl("I don't know what he's up to. If you want to find out, you'd better search his home.").also { stage++ } 9 -> playerl("OK. Thanks Charlie.").also { stage++ } 10 -> npcl("Good luck!").also { - setQuestStage(player!!, questName, 47) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 47) stage = END_DIALOGUE } } @@ -79,7 +79,7 @@ class CharlieDialogue : DialogueFile() { 8 -> { unlock(player!!) npc.clear() - setQuestStage(player!!, questName, 55) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 55) return true } } @@ -102,7 +102,7 @@ class CharlieDialogue : DialogueFile() { 6 -> playerl("Where does she live?").also { stage++ } 7 -> npcl("Just west of the toad swamp.").also { stage++ } 8 -> playerl("OK, I'll see what I can find.").also { - setQuestStage(player!!, questName, 60) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 60) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt b/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt index 56381b09e..1977a47b8 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.grandtree +import content.data.Quests import core.ServerConstants import core.api.* import core.game.component.Component @@ -38,7 +39,7 @@ class ForemanNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,locat } override fun finalizeDeath(killer: Entity?) { - if(getQuestStage(killer as Player, TheGrandTree.questName) == 55) { + if(getQuestStage(killer as Player, Quests.THE_GRAND_TREE) == 55) { sendMessage(killer,"The foreman drops a piece of paper as he dies.") produceGroundItem(killer, Items.LUMBER_ORDER_787, 1, this.location) } diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt index 5b538b8d4..496184c70 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.quest.grandtree -import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -15,7 +15,7 @@ import core.tools.END_DIALOGUE class GloughDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, questName)) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { 40 -> { when (stage) { 0 -> playerl("Hello.").also { stage++ } @@ -28,7 +28,7 @@ class GloughDialogue : DialogueFile() { 7 -> npcl("I should've known! The humans are going to invade!").also { stage++ } 8 -> playerl("Never!").also { stage++ } 9 -> npcl("Your type can't be trusted! I'll take care of this! Go back to the King.").also { - setQuestStage(player!!, questName, 45) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 45) stage = END_DIALOGUE } } @@ -70,7 +70,7 @@ class GloughDialogue : DialogueFile() { } 8 -> { npc.clear() - setQuestStage(player!!, questName, 50) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 50) teleport(player!!, cell) player!!.unlock() return true diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt index 4c969c234..a0dd8b258 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt @@ -1,6 +1,5 @@ package content.region.kandarin.quest.grandtree -import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener @@ -15,6 +14,10 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.NPCs import org.rs09.consts.Sounds +import content.data.Quests +import content.global.handlers.iface.ScrollInterface +import content.global.handlers.iface.ScrollLine +import org.rs09.consts.Components class GrandTreeListeners: InteractionListener { @@ -26,12 +29,11 @@ class GrandTreeListeners: InteractionListener { Location(2473,9897,0), ) - val hazelmerescroll = Items.HAZELMERES_SCROLL_786 - - val hazelmerescrollText = arrayOf( - "Es lemanto meso pro eis prit ta Cinqo mond.", - "Mi lovos ta lemanto Daconia arpos", - "et Daconia arpos eto meriz ta priw!", + // https://youtu.be/-jfueZpRhzU?t=184 + val hazelmereScrollText = arrayOf( + ScrollLine("Es lemanto meso pro eis prit ta Cinqo mond.", 6), + ScrollLine("Mi lovos ta lemanto Daconia arpos", 7), + ScrollLine("et Daconia arpos eto meriz ta priw!", 8) ) fun unlockTUZODoor(player: Player) { @@ -84,13 +86,13 @@ class GrandTreeListeners: InteractionListener { openDialogue(player, AnitaDialogue(), npc) return@on true } - on(hazelmerescroll, IntType.ITEM, "read") { player, node -> - hazelmereScroll(player, node.asItem()) + on(Items.HAZELMERES_SCROLL_786, IntType.ITEM, "read") { player, node -> + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, hazelmereScrollText) return@on true } on(2444, IntType.SCENERY, "open"){ player, node -> - if(node.location == Location(2487,3464,2) && !isQuestComplete(player, questName)){ + if(node.location == Location(2487,3464,2) && !isQuestComplete(player, Quests.THE_GRAND_TREE)){ if(getAttribute(player, "/save:grandtree:twig1", false) && getAttribute(player, "/save:grandtree:twig2", false) && getAttribute(player, "/save:grandtree:twig3", false) && @@ -103,7 +105,10 @@ class GrandTreeListeners: InteractionListener { } on(2446, IntType.SCENERY, "open"){ player, node -> - if(node.location == Location(2463, 3497, 0) && isQuestComplete(player!!, questName)){ + if(node.location == Location(2463, 3497, 0) && isQuestComplete( + player!!, + Quests.THE_GRAND_TREE + )){ player.animator.animate(Animation(828)) // Go to tunnels teleport(player, Location(2464, 9897, 0)) @@ -115,8 +120,8 @@ class GrandTreeListeners: InteractionListener { SceneryBuilder.replace(Scenery(2436, Location(2482,3462,1)),Scenery(2437, Location(2482,3462,1)),2) sendDialogue(player,"You found a scroll!") addItemOrDrop(player, Items.INVASION_PLANS_794) - if(getQuestStage(player!!, questName) < 60) - setQuestStage(player!!, questName, 60) + if(getQuestStage(player!!, Quests.THE_GRAND_TREE) < 60) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 60) return@onUseWith true } onUseWith(IntType.SCENERY, Items.TWIGS_789, 2440){ player, used, with -> @@ -165,7 +170,7 @@ class GrandTreeListeners: InteractionListener { return@on true } on(2435, IntType.SCENERY, "search"){ player, _ -> - if(getQuestStage(player, questName) == 47){ + if(getQuestStage(player, Quests.THE_GRAND_TREE) == 47){ sendItemDialogue(player, Items.GLOUGHS_JOURNAL_785,"You've found Glough's Journal!") addItemOrDrop(player, Items.GLOUGHS_JOURNAL_785) } @@ -174,7 +179,7 @@ class GrandTreeListeners: InteractionListener { // Roots for Daconia rock on(32319, IntType.SCENERY, "search"){ player, node -> - if(getQuestStage(player, questName) < 99 || player.hasItem(Item(Items.DACONIA_ROCK_793))){ return@on true; } + if(getQuestStage(player, Quests.THE_GRAND_TREE) < 99 || player.hasItem(Item(Items.DACONIA_ROCK_793))){ return@on true; } // RNG for which root the rock is under if(node.location == roots[getAttribute(player,"grandtree:rock",1)]){ sendItemDialogue(player, Item(Items.DACONIA_ROCK_793), "You've found a Daconia rock!") @@ -192,7 +197,7 @@ class GrandTreeListeners: InteractionListener { return@on true } on(2451, IntType.SCENERY, "push"){ player, roots -> - if (hasRequirement(player, "The Grand Tree")) { + if (hasRequirement(player, Quests.THE_GRAND_TREE)) { val outsideMine = player.location == Location.create(2467, 9903, 0) || player.location == Location.create(2468, 9903, 0) if(outsideMine) { forceMove(player, player.location, player.location.transform(0, 2, 0), 25, 60, null, 819) @@ -206,14 +211,5 @@ class GrandTreeListeners: InteractionListener { return@on true } } - - private fun hazelmereScroll(player: Player, item: Item) { - val id = item.id - openInterface(player, 222).also { - when (id) { - hazelmerescroll -> setInterfaceText(player, hazelmerescrollText.joinToString("
"), 222, 6) - } - } - } } diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt index 9edb39423..ab59a6ba6 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.quest.grandtree -import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.node.item.Item @@ -10,7 +10,7 @@ import org.rs09.consts.Items class HazelmereDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, questName)) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { 10 -> { if(player!!.hasItem(Item(Items.BARK_SAMPLE_783))){ when (stage) { @@ -24,7 +24,7 @@ class HazelmereDialogue : DialogueFile() { if(removeItem(player!!, Items.BARK_SAMPLE_783)){ addItemOrDrop(player!!, Items.HAZELMERES_SCROLL_786) } - setQuestStage(player!!, questName, 20) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 20) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt index 1725f0117..5cbf67861 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.quest.grandtree -import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.interaction.MovementPulse @@ -67,7 +67,7 @@ class KingNarnodeDialogue : DialogueFile() { }) } override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, questName)) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { 0 -> { when (stage) { 0 -> npcl("Welcome Traveller. I am King Narnode. It's nice to see an outsider.").also { stage++ } @@ -222,7 +222,7 @@ class KingNarnodeDialogue : DialogueFile() { 64 -> npcl("First, I must warn the tree guardians. Please, could you tell the chief tree guardian, Glough. He lives in a tree house just in front of the Grand Tree.").also { stage++ } 65 -> npcl("If he's not there he will be at his girlfriend Anita's place. Meet me back here once you've told him.").also { stage++ } 66 -> playerl("Ok! I'll be back soon.").also { - setQuestStage(player!!, questName, 40) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 40) stage = END_DIALOGUE } } @@ -242,7 +242,7 @@ class KingNarnodeDialogue : DialogueFile() { 3 -> npcl("Yes Glough really knows what he's doing. The human has been detained until we know who else is involved. Maybe Glough was right, maybe humans are invading!").also { stage++ } 4 -> playerl("I doubt it, can I speak to the prisoner?").also { stage++ } 5 -> npcl("Certainly. He's on the top level of the tree. Be careful, it's a long way down!").also { - setQuestStage(player!!, questName, 46) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 46) stage = END_DIALOGUE } } @@ -281,7 +281,7 @@ class KingNarnodeDialogue : DialogueFile() { } 7 -> npcl("On the other hand, if Glough's right about the humans we will need an army of gnomes to protect ourselves. ").also { stage++ } 8 -> npcl("So I've decided to allow Glough to raise a mighty gnome army. The Grand Tree's still slowly dying. If it is human sabotage we must respond!").also{ - setQuestStage(player!!, questName, 70) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 70) removeItem(player!!, Item(Items.INVASION_PLANS_794), Container.INVENTORY) stage = END_DIALOGUE } @@ -383,7 +383,7 @@ class KingNarnodeUnderGroundDialogue : DialogueFile() { }) } override fun handle(componentID: Int, buttonID: Int) { - when(getQuestStage(player!!, questName)) { + when(getQuestStage(player!!, Quests.THE_GRAND_TREE)) { 98 -> when (stage) { 0 -> npcl("Traveller, you're wounded! What happened?").also { stage++ } 1 -> playerl("It's Glough! He set a demon on me!").also { stage++ } @@ -398,7 +398,7 @@ class KingNarnodeUnderGroundDialogue : DialogueFile() { 10 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"Yes sir!").also{ stage++ } 11 -> npcl("You have my full apologies Traveller! And my gratitude! A reward will have to wait though, the tree is still dying!").also {stage++} 12 -> npcl("The guards are clearing Glough's rock supply now but there must be more Daconia hidden somewhere in the roots! Help us search, we have little time!").also { - setQuestStage(player!!, questName, 99) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 99) // position of the daconia rock if(getAttribute(player!!,"treegnome:rock",0) == 0){ val answer = (1..5).random() @@ -425,7 +425,7 @@ class KingNarnodeUnderGroundDialogue : DialogueFile() { 11 -> playerl("Strange!").also { stage++ } 12 -> npcl("That's magic trees for you! All the best Traveller and thanks again!").also { stage++ } 13 -> playerl("You too, Your Highness!").also { - finishQuest(player!!, questName) + finishQuest(player!!, Quests.THE_GRAND_TREE) removeItem(player!!, Items.DACONIA_ROCK_793) stage = END_DIALOGUE } @@ -494,7 +494,7 @@ class KingNarnodeUnderGroundDialogue : DialogueFile() { 31 -> if (player!!.inventory.freeSlots() >= 2) { npcl("Up here.") stage = END_DIALOGUE - setQuestStage(player!!, questName, 10) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 10) addItemOrDrop(player!!, Items.BARK_SAMPLE_783) addItemOrDrop(player!!, Items.TRANSLATION_BOOK_784) leadUpLadder() diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt index a2a1fa0ea..1487b306c 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.grandtree +import content.data.Quests import core.api.getAttribute import core.api.getQuestStage import core.api.setAttribute @@ -13,7 +14,7 @@ class ShipyardWorkerDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { when(stage){ 0 -> npcl("Hey you! What are you up to?").also { - if(getQuestStage(player!!, TheGrandTree.questName) == 55) { + if(getQuestStage(player!!, Quests.THE_GRAND_TREE) == 55) { setAttribute(player!!, "/save:grandtree:opt1", false) setAttribute(player!!, "/save:grandtree:opt2", false) setAttribute(player!!, "/save:grandtree:opt3", false) diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt b/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt index e8bff2b27..c1b74008f 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt @@ -1,15 +1,15 @@ package content.region.kandarin.quest.grandtree -import core.api.addItemOrDrop import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable -class TheGrandTree: Quest("The Grand Tree", 71, 70, 5, 150, 0, 1, 160) { +class TheGrandTree: Quest(Quests.THE_GRAND_TREE, 71, 70, 5, 150, 0, 1, 160) { override fun newInstance(`object`: Any?): Quest { return this } @@ -96,7 +96,4 @@ class TheGrandTree: Quest("The Grand Tree", 71, 70, 5, 150, 0, 1, 160) { } } - companion object { - const val questName = "The Grand Tree" - } } diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt b/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt index a4c5c7bd9..2a4bc37c5 100644 --- a/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt +++ b/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -131,8 +132,9 @@ class TranslationBook : InteractionListener { } override fun defineListeners() { - on(Items.TRANSLATION_BOOK_784, IntType.ITEM, "read") { player, _ -> + on(Items.TRANSLATION_BOOK_784, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/AnnaDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/AnnaDialogue.kt new file mode 100644 index 000000000..7998584f2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/AnnaDialogue.kt @@ -0,0 +1,60 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonAnna +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class AnnaDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, AnnaDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return AnnaDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ANNA_814, NPCs.ANNA_6192) + } +} + +class AnnaDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "Oh really? What do you want to know then?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you when the murder happened?", 6), + IfTopic("Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)), + IfTopic("Why'd you buy poison the other day?", 10, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 3 -> npcl("It was clearly an intruder.").also { stage++ } + 4 -> playerl("Well, I don't think it was.").also { stage++ } + 5 -> npcl("It was one of our lazy servants then.").also { stage = END_DIALOGUE } + + 6 -> npcl("In the library. No one else was there so you'll just have to take my word for it.").also { stage = END_DIALOGUE } + + 7 -> sendDialogue(player!!, "You show Anna the thread from the study.") + .also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1809)) stage++ else stage = 9 } + 8 -> npcl("It's some Green thread. It's not exactly uncommon is it? My trousers are made of the same material.").also { stage = END_DIALOGUE } + + 9 -> npcl("Not really, no. Thread is fairly common.").also { stage = END_DIALOGUE } + + 10 -> npcl(FacialExpression.ANNOYED, "That useless Gardener Stanford let his compost heap fester. It's an eyesore to the garden! So I bought some poison from a travelling salesman so that I could kill off some of the wildlife living in it.") + .also { setAttribute(player!!, attributeAskPoisonAnna, true)} + .also { stage = END_DIALOGUE } + } + 100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/BobDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/BobDialogue.kt new file mode 100644 index 000000000..75455b51d --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/BobDialogue.kt @@ -0,0 +1,61 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonBob +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BobDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, BobDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return BobDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BOB_815, NPCs.BOB_6193) + } +} + +class BobDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl("I suppose I had better talk to you then.").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you when the murder happened?", 4), + IfTopic(FacialExpression.THINKING, "Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)), + IfTopic("Why'd you buy poison the other day?", 10, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 3 -> npcl("I don't really care as long as no one thinks it's me. Maybe it was that strange poison seller who headed towards the seers village.").also { stage = END_DIALOGUE } + + 4 -> npcl("I was walking by myself in the garden.").also { stage++ } + 5 -> playerl("And can anyone vouch for that?").also { stage++ } + 6 -> npcl("No. But I was.").also { stage = END_DIALOGUE } + + 7 -> sendDialogue(player!!, "You show him the thread you discovered.") + .also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1808)) stage++ else stage = 9 } + 8 -> npcl("It's some red thread. I suppose you think that's some kind of clue? It looks like the material my trousers are made of.").also { stage = END_DIALOGUE } + + 9 -> npcl(FacialExpression.THINKING, "It's some thread. Great clue. No, really.").also { stage = END_DIALOGUE } + + 10 -> npcl(FacialExpression.THINKING, "What's it to you anyway?").also { stage++ } + 11 -> npcl(FacialExpression.ANGRY, "If you absolutely must know, we had a problem with the beehive in the garden, and as all of our servants are so pathetically useless, I decided I would deal with it myself. So I did.") + .also { setAttribute(player!!, attributeAskPoisonBob, true)} + .also { stage = END_DIALOGUE } + } + 100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/CarolDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/CarolDialogue.kt new file mode 100644 index 000000000..66b283ccf --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/CarolDialogue.kt @@ -0,0 +1,59 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonCarol +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class CarolDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, CarolDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return CarolDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.CAROL_816, NPCs.CAROL_6194) + } +} + +class CarolDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl("Well, ask what you want to know then.").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you when the murder happened?", 4), + IfTopic("Do you recognise this thread?", 5, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)), + IfTopic("Why'd you buy poison the other day?", 8, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 3 -> npcl("I don't know. I think it's very convenient that you have arrived here so soon after it happened. Maybe it was you.").also { stage = END_DIALOGUE } + + 4 -> npcl("Why? Are you accusing me of something? You seem to have a very high opinion of yourself. I was in my room if you must know, alone.").also { stage = END_DIALOGUE } + + 5 -> sendDialogue(player!!, "You show Carol the thread found at the crime scene.") + .also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1808)) stage++ else stage = 7 } + 6 -> npcl("It's some red thread... it kind of looks like the Same material as my trousers. But obviously it's not.").also { stage = END_DIALOGUE } + + 7 -> npcl("It's some thread. Sorry, do you have a point here? Or do you just enjoy wasting peoples time?").also { stage = END_DIALOGUE } + + 8 -> npcl(FacialExpression.THINKING, "I don't see what on earth it has to do with you, but the drain outside was").also { stage++ } + 9 -> npcl(FacialExpression.ANNOYED, "blocked, and as nobody else here has the intelligence to even unblock a simple drain I felt I had to do it myself.") + .also { setAttribute(player!!, attributeAskPoisonCarol, true)} + .also { stage = END_DIALOGUE } + } + 100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/DavidDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/DavidDialogue.kt new file mode 100644 index 000000000..b25862064 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/DavidDialogue.kt @@ -0,0 +1,60 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonDavid +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class DavidDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DavidDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return DavidDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DAVID_817, NPCs.DAVID_6195) + } +} + +class DavidDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl("And? Make this quick. I have better things to do than be interrogated by halfwits all day.").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you when the murder happened?", 5), + IfTopic("Do you recognise this thread?", 6, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)), + IfTopic("Why'd you buy poison the other day?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 3 -> npcl("I don't really know or care. Frankly, the old man deserved to die.").also { stage++ } + 4 -> npcl("There was a suspicious red headed man who came to the house the other day selling poison now I think about it. Last I saw he was headed towards the tavern in the Seers village.").also { stage = END_DIALOGUE } + + 5 -> npcl("That is none of your business. Are we finished now, or are you just going to stand there irritating me with your idiotic questions all day?").also { stage = END_DIALOGUE } + + 6 -> sendDialogue(player!!, "You show him the thread you found on the study window.") + .also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1809)) stage++ else stage = 8 } + 7 -> npcl("It's some Green thread, like my trousers are made of. Are you finished? I'm not sure which I dislike more bout you, your face or your general bad odour.").also { stage = END_DIALOGUE } + + 8 -> npcl("No. Can I go yet? Your face irritates me.").also { stage = END_DIALOGUE } + + 9 -> npcl(FacialExpression.ANGRY, "There was a nest of spiders upstairs between the two servants' quarters. Obviously I had to kill them before our pathetic servants whined at my father some more.").also { stage++ } + 10 -> npcl(FacialExpression.THINKING, "Honestly, it's like they expect to be treated like royalty! If I had my way I would fire the whole workshy lot of them!") + .also { setAttribute(player!!, attributeAskPoisonDavid, true)} + .also { stage = END_DIALOGUE } + } + 100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/DonovanDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/DonovanDialogue.kt new file mode 100644 index 000000000..28fae9bbf --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/DonovanDialogue.kt @@ -0,0 +1,57 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class DonovanDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DonovanDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return DonovanDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DONOVAN_THE_FAMILY_HANDYMAN_806) + } +} + +class DonovanDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> npcl("I have no interest in talking to gawkers.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl("I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl("How can I help?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you at the time of the murder?", 5), + IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)), + IfTopic("Do you know why so much poison was bought recently?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 3 -> npcl("Oh... I really couldn't say. I wouldn't really want to point any fingers at anybody. If I had to make a guess I'd have to say it was probably Bob though.").also { stage++ } + 4 -> npcl("I saw him arguing with Lord Sinclair about some missing silverware from the Kitchen. It was a very heated argument.").also { stage = END_DIALOGUE } + + 5 -> npcl("Me? I was sound asleep here in the servants Quarters. It's very hard work as a handyman around here. There's always something to do!").also { stage = END_DIALOGUE } + + 6 -> npcl("Hmmm... No, I didn't, but I sleep very soundly at night.").also { stage++ } + 7 -> playerl("So you didn't hear any sounds of a struggle or any barking from the guard dog next to his study window?").also { stage++ } + 8 -> npcl("Now you mention it, no. It is odd I didn't hear anything like that. But I do sleep very soundly as I said and wouldn't necessarily have heard it if there was any such noise.").also { stage = END_DIALOGUE } + + 9 -> npcl("Well, I do know Frank bought some poison recently to clean the family crest that's outside.").also { stage++ } + 10 -> npcl("It's very old and rusty, and I couldn't clean it myself, so he said he would buy some cleaner and clean it himself. He probably just got some from that Poison Salesman who came to the door the other day...").also { stage++ } + 11 -> npcl("You'd really have to ask him though.").also { stage = END_DIALOGUE } + } + 100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE } + } + } +} + diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/ElizabethDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/ElizabethDialogue.kt new file mode 100644 index 000000000..faacbbe69 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/ElizabethDialogue.kt @@ -0,0 +1,64 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonElizabeth +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ElizabethDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ElizabethDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return ElizabethDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ELIZABETH_818, NPCs.ELIZABETH_6196) + } +} + +class ElizabethDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl("What's so important you need to bother me with then?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you when the murder happened?", 4), + IfTopic("Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)), + IfTopic("Why'd you buy poison the other day?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 3 -> npcl("Could have been anyone. The old man was an idiot. He's been asking for it for years.").also { stage = END_DIALOGUE } + + 4 -> npcl("I was out.").also { stage++ } + 5 -> playerl("Care to be any more specific?").also { stage++ } + 6 -> npcl("Not really. I don't have to justify myself to the likes of you, you know. I know the King personally you know. Now are we finished here?").also { stage = END_DIALOGUE } + + 7 -> sendDialogue(player!!, "You show her the thread from the study window.") + .also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1810)) stage++ else stage = 11 } + 8 -> npcl(" Looks like Blue thread to me. If you can't work that out for yourself I don't hold much hope of you solving this crime.").also { stage++ } + 9 -> playerl("It looks a lot like the material your trousers are made of doesn't it?").also { stage++ } + 10 -> npcl("I suppose it does. So what?").also { stage = END_DIALOGUE } + + 11 -> npcl(" It's some thread. You're not very good at this whole investigation thing are you?").also { stage = END_DIALOGUE } + + 12 -> npcl("There was a nest of mosquitos under the fountain in the garden, which I killed with poison the other day. You can see for yourself if you're capable of managing that, which I somehow doubt.").also { stage++ } + 13 -> playerl(FacialExpression.ANNOYED, "I hate mosquitos!").also { stage++ } + 14 -> npcl("Doesn't everyone?") + .also { setAttribute(player!!, attributeAskPoisonElizabeth, true)} + .also { stage = END_DIALOGUE } + } + 100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/FlypaperDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/FlypaperDialogue.kt new file mode 100644 index 000000000..952be8a03 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/FlypaperDialogue.kt @@ -0,0 +1,26 @@ +package content.region.kandarin.quest.murdermystery + +import core.api.* +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class FlypaperDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogue(player!!, "There's some flypaper in there. Should I take it?").also { stage++ } + 1 -> options("Yes, it might be useful.", "No, I don't see any need for it.").also { stage++ } + 2 -> when(buttonID) { + 1 -> if (addItem(player!!, Items.FLYPAPER_1811)){ + sendDialogue(player!!, "You take a piece of fly paper. There is still plenty of fly paper left.") + .also { stage = END_DIALOGUE } + } + else { + sendDialogue(player!!, "You don't have enough space in your inventory.") + .also { stage = END_DIALOGUE } + } + 2 -> sendDialogue(player!!, "You leave the paper in the sack.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/FountainDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/FountainDialogue.kt new file mode 100644 index 000000000..95ef1d79e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/FountainDialogue.kt @@ -0,0 +1,15 @@ +package content.region.kandarin.quest.murdermystery + +import core.api.* +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class FountainDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogue(player!!, "The fountain is swarming with mosquitos. There's a nest of them underneath the fountain.").also { stage++ } + 1 -> playerl("I hate mosquitos, they're so annoying!").also { stage++ } + 2 -> sendDialogue(player!!, "It's certainly clear nobody's used poison here.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/FrankDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/FrankDialogue.kt new file mode 100644 index 000000000..15e8af9bb --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/FrankDialogue.kt @@ -0,0 +1,60 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonFrank +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class FrankDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, FrankDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return FrankDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.FRANK_819, NPCs.FRANK_6197) + } +} + +class FrankDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl("Good for you. Now what do you want?").also { stage++ } + 2 -> npcl(FacialExpression.SAD, "...And can you spare me any money? I'm a little short...").also { stage++ } + 3 -> showTopics( + Topic("Who do you think is responsible?", 4), + Topic( "Where were you when the murder happened?", 5), + IfTopic("Do you recognise this thread?", 6, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)), + IfTopic("Why'd you buy poison the other day?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + 4 -> npcl("I don't know. You don't know how long it takes an inheritance to come through do you? I could really use that money pretty soon...").also { stage = END_DIALOGUE } + + 5 -> npcl("I don't know, somewhere around here probably. Could you spare me a few coins? I'll be able to pay you back double tomorrow it's just there's this poker night tonight in town...").also { stage = END_DIALOGUE } + + 6 -> sendDialogue(player!!, "Frank examines the thread from the crime scene.") + .also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1810)) stage++ else stage = 8 } + 7 -> npcl("It kind of looks like the same material as my trousers are made of... same colour anyway. Think it's worth anything? Can I have it? Or just some money?").also { stage = END_DIALOGUE } + + 8 -> npcl("It looks like thread to me, but I'm not exactly an expert. Is it worth something? Can I have it? Actually, can you spare me a few gold?").also { stage = END_DIALOGUE } + + 9 -> npcl("Would you like to buy some? I'm kind of strapped for cash right now. I'll sell it to you cheap. It's hardly been used at all.").also { stage++ } + 10 -> npcl("I just used a bit to clean that family crest outside up a bit. Do you think I could get much money for the family crest, actually? It's cleaned up a bit now.") + .also { setAttribute(player!!, attributeAskPoisonFrank, true)} + .also { stage = END_DIALOGUE } + } + 100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/GossipDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/GossipDialogue.kt new file mode 100644 index 000000000..095fd175d --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/GossipDialogue.kt @@ -0,0 +1,133 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class GossipDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GossipDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return GossipDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GOSSIP_813) + } +} + +class GossipDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> npcl("There's some kind of commotion up at the Sinclair place I hear. Not surprising all things considered.").also { stage = END_DIALOGUE} + 1 -> when (stage) { + 0 -> playerl("I'm investigating the murder up at the Sinclair place.").also { stage++ } + 1 -> npcl("Murder is it? Well, I'm not really surprised...").also { stage++ } + 2 -> options("What can you tell me about the Sinclairs?", "Who do you think was responsible?", "I think the butler did it.", "I am so confused about who did it.").also { stage++ } + 3 -> when(buttonID) { + 1 -> playerl("What can you tell me about the Sinclairs?").also { stage = 4 } + 2 -> playerl("Who do you think was responsible?").also { stage = 40 } + 3 -> playerl("I think the butler did it.").also { stage = 42 } + 4 -> playerl("I am so confused about who did it.").also { stage = 43 } + } + 4 -> npcl("Well, what do you want to know?").also { stage++ } + 5 -> options("Tell me about Lord Sinclair.", "Why do the Sinclairs live so far from town?", "What can you tell me about his sons?", "What can you tell me about his daughters?").also { stage++ } + 6 -> when(buttonID) { + 1 -> playerl("Tell me about Lord Sinclair.").also { stage = 7 } + 2 -> playerl("Why do the Sinclairs live so far from town?").also { stage = 10 } + 3 -> playerl("What can you tell me about his sons?").also { stage = 12 } + 4 -> playerl("What can you tell me about his daughters?").also { stage = 15 } + } + 7 -> npcl("Old Lord Sinclair was a great man with a lot of respect around these parts. More than his worthless children have anyway.").also { stage++ } + 8 -> playerl("His children? They have something to gain by his death?").also { stage++ } + 9 -> npcl("Yes. You could say that. Not that I am one to gossip.").also { stage = END_DIALOGUE } + + 10 -> npcl("Well, they used to live in the big castle, but old Lord Sinclair gave it up so that those strange knights could live there instead. So the king built him a new house to the North.").also { stage++ } + 11 -> npcl("It's more cramped than his old place, but he seemed to like it. His children were furious at him for doing it though!").also { stage = END_DIALOGUE } + + 12 -> npcl("His sons eh? They all have their own skeletons in their cupboards. You'll have to be more specific. Who are you interested in exactly?").also { stage++ } + 13 -> options("Tell me about Bob.", "Tell me about David.", "Tell me about Frank.").also { stage++ } + 14 -> when(buttonID) { + 1 -> playerl("Tell me about Bob.").also { stage = 18 } + 2 -> playerl("Tell me about David.").also { stage = 23 } + 3 -> playerl("Tell me about Frank.").also { stage = 27 } + } + + 15 -> npcl("His daughters eh? They're all nasty pieces of work, which of them specifically did you want to know about?").also { stage++ } + 16 -> options("Tell me about Anna.", "Tell me about Carol.", "Tell me about Elizabeth.").also { stage++ } + 17 -> when(buttonID) { + 1 -> playerl("Tell me about Anna.").also { stage = 30 } + 2 -> playerl("Tell me about Carol.").also { stage = 33 } + 3 -> playerl("Tell me about Elizabeth.").also { stage = 36 } + } + + 18 -> npcl("Bob is an odd character indeed... I'm not one to gossip, but I heard Bob is addicted to Tea. He can't make").also { stage++ } + 19 -> npcl("it through the day without having at least 20 cups!").also { stage++ } + 20 -> npcl("You might not think that's such a big thing, but he has spent thousands of gold to feed his habit!").also { stage++ } + 21 -> npcl("At one point he stole a lot of silverware from the kitchen and pawned it just so he could afford to buy his daily tea allowance.").also { stage++ } + 22 -> npcl("If his father ever found out, he would be in so much trouble... he might even get disowned!").also { stage = END_DIALOGUE } + + 23 -> npcl("David... oh David... not many people know this, but David really has an anger problem. He's always screaming and shouting").also { stage++ } + 24 -> npcl("at the household servants when he's angry, and they live in a state of fear, always walking on eggshells around him, but none of them have the courage").also { stage++ } + 25 -> npcl("to talk to his father about his behaviour. If they did, Lord Sinclair would almost certainly").also { stage++ } + 26 -> npcl("kick him out of the house, as some of the servants have been there longer than he has, and he definitely has no right to treat them like he does... but I'm not one to gossip about people.").also { stage = END_DIALOGUE } + + 27 -> npcl("I'm not one to talk ill of people behind their back, but Frank is a real piece of work. He is an absolutely terrible gambler...he can't pass 2 dogs in the street without putting a bet on which one will bark first!").also { stage++ } + 28 -> npcl("He has already squandered all of his allowance, and I heard he had stolen a number of paintings of his fathers to sell to try and cover his debts, but he still owes a lot of people a lot of").also { stage++ } + 29 -> npcl("money. If his father ever found out, he would stop his income, and then he would be in serious trouble!").also { stage = END_DIALOGUE } + + 30 -> npcl("Anna... ah yes... Anna has 2 great loves:").also { stage++ } + 31 -> npcl("Sewing and gardening. But one thing she has kept secret is that she once had an affair with Stanford the gardener, and tried to get him fired when they broke up,").also { stage++ } + 32 -> npcl("by killing all of the flowers in the garden. If her father ever found out she had done that he would be so furious he would probably disown her.").also { stage = END_DIALOGUE } + + 33 -> npcl("Oh Carol... she is such a fool. You didn't hear this from me, but I heard a while ago she was conned out of a lot of money by a travelling salesman who sold her a box full").also { stage++ } + 34 -> npcl("of beans by telling her they were magic. But they weren't. She sold some rare books from the library to cover her debts, but").also { stage++ } + 35 -> npcl("her father would be incredibly annoyed if he ever found out - he might even throw her out of the house!").also { stage = END_DIALOGUE } + + 36 -> npcl("Elizabeth? Elizabeth has a strange problem... She cannot help herself, but is always stealing small objects - it's pretty sad that she is rich enough to afford to buy things, but would rather steal them instead.").also { stage++ } + 37 -> npcl("Now, I don't want to spread stories, but I heard she even stole a silver needle from her father that had great sentimental value for him.").also { stage++ } + 38 -> npcl("He was devastated when it was lost, and cried for a week thinking he had lost it!").also { stage++ } + 39 -> npcl("If he ever found out that it was her who had stolen it he would go absolutely mental, maybe even disowning her!").also { stage = END_DIALOGUE } + + 40 -> npcl("Well, I guess it could have been an intruder, but with that big guard dog of theirs I seriously doubt it. I suspect it was someone closer to home...").also { stage ++ } + 41 -> npcl("Especially as I heard that the poison salesman in the Seers' village made a big sale to one of the family the other day.") + .also { setAttribute(player!!, attributeNoiseClue, true)} + .also { stage = END_DIALOGUE } + + 42 -> npcl("And I think you've been reading too many cheap detective novels. Hobbes is kind of uptight, but his loyalty to old Lord Sinclair is beyond question.").also { stage = END_DIALOGUE } + + 43 -> playerl("Think you could give me any hints?") + .also { when (RandomFunction.random(4)) { //RS3 wiki seems to indicate this is fully random, not based off of progression + 0 -> stage = 44 + 1 -> stage = 46 + 2 -> stage = 47 + 3 -> stage = 48 + 4 -> stage = 51 + } + } + 44 -> npcl("Well, I don't know if it's related, but I heard from that Poison Salesman in town that he sold some poison to one of the Sinclair family").also { stage++ } + 45 -> npcl("the other day. I don't think he has any stock left now though...").also { stage = END_DIALOGUE } + + 46 -> npcl("Well, I don't know how much help this is, but I heard their guard dog will bark loudly at anyone it doesn't recognise. Maybe you should find out if anyone heard anything suspicious?") + .also { stage = END_DIALOGUE } + + 47 -> npcl("Well, this might be of some help to you. My father was in the guards when he was younger and he always said that there isn't a crime that can't be solved through careful examination of the crime scene and all surrounding areas.").also { stage = END_DIALOGUE } + + 48 -> npcl("I don't know how much help this is to you, but my dad was in the guard once and he told me the marks on your hands are totally unique. He calls them 'finger prints'.").also { stage++ } + 49 -> npcl("He said you can find them easily on any shiny metallic surface, by using a fine powder to mark out where the marks are and then using some sticky paper to lift the print from the object.").also { stage++ } + 50 -> npcl("I bet if you could find a way to get everyone's 'finger prints' you could solve the crime pretty easily!").also { stage = END_DIALOGUE } + + 51 -> npcl("My father used to be in the guard, he always wrote himself notes on a piece of paper so he could keep track of information easily.").also { stage++ } + 52 -> npcl("Maybe you should try that? Don't forget to thank me if I help you solve the case!").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/GuardDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/GuardDialogue.kt new file mode 100644 index 000000000..d661a6aae --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/GuardDialogue.kt @@ -0,0 +1,220 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeRandomMurderer +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.clueCount +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.solvedMystery +import core.ServerConstants.Companion.SERVER_NAME +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GuardDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GuardDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return GuardDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARD_812, NPCs.GUARD_6191) + } +} + +class GuardDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val KILLER = when (getAttribute(player!!, attributeRandomMurderer, 0)) { + 0 -> "Anna" + 1 -> "Bob" + 2 -> "Carol" + 3 -> "David" + 4 -> "Elizabeth" + 5 -> "Frank" + else -> "Anna" + } + val POISONSPOT = when (getAttribute(player!!, attributeRandomMurderer, 0)) { + 0 -> "compost heap" + 1 -> "beehive" + 2 -> "drain" + 3 -> "spiders nest" + 4 -> "fountain" + 5 -> "Sinclair Crest" + else -> "compost heap" + } + val KILLERMALE = when (getAttribute(player!!, attributeRandomMurderer, 0)) { + 1, 3, 5 -> true + else -> false + } + val EVIDENCE = (1796..1822).toList().toIntArray() //All Murder Mystery related items are between these item ids + + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "What's going on here?").also { stage++ } + 1 -> npcl(FacialExpression.SAD, "Oh, it's terrible! Lord Sinclair has been murdered and we don't have any clues as to who or why. We're totally baffled!").also { stage++ } + 2 -> npcl(FacialExpression.SAD, "If you can help us we will be very grateful.").also { stage++ } + 3 -> options("Sure, I'll help.", "You should do your own dirty work.").also { stage++ } + 4 -> when (buttonID) { + 1 -> playerl(FacialExpression.HAPPY, "Sure, I'll help.").also { stage++ } + 2 -> playerl("You should do your own dirty work.").also { stage = 8 } + } + 5 -> npcl(FacialExpression.HAPPY, "Thanks a lot!").also { stage++ } + 6 -> playerl(FacialExpression.NEUTRAL, "What should I be doing to help?").also { stage++ } + 7 -> npcl(FacialExpression.NEUTRAL, "Look around and investigate who might be responsible. The Sarge said every murder leaves clues to who done it, but frankly we're out of our depth here.") + .also { setAttribute(player!!, attributeRandomMurderer, RandomFunction.random(5))} + .also { setQuestStage(player!!, Quests.MURDER_MYSTERY, 1) } + .also { stage = END_DIALOGUE } + + 8 -> npcl("Get lost then, this is private property! ...Unless you'd like to be taken in for questioning yourself?").also { stage = END_DIALOGUE } + } + 1 -> when (stage) { + 0 -> options("What should I be doing to help again?", "How did Lord Sinclair die?", "I know who did it!").also { stage++ } + 1 -> when(buttonID) { + 1 -> playerl("What should I be doing to help?").also { stage = 2 } + 2 -> playerl("How did Lord Sinclair die?").also { stage = 3 } + 3 -> playerl(FacialExpression.HAPPY, "I know who did it!") + .also { + stage = if (solvedMystery(player!!)) 46 + else if (clueCount(player!!) == 1) { + if (inInventory(player!!, Items.KILLERS_PRINT_1815)) { + 41 + } + else if (getAttribute(player!!, attributePoisonClue,0) == 2) { + 37 + } + else 33 + } + else if (clueCount(player!!) > 1) 32 + else 6 + } + } + 2 -> npcl("Look around and investigate who might be responsible. The Sarge said every murder leaves clues to who done it, but frankly we're out of our depth here.").also { stage = END_DIALOGUE } + + 3 -> npcl("Well, it's all very mysterious. Mary, the maid, found the body in the study next to his bedroom on the east wing of the ground floor.").also { stage++ } + 4 -> npcl("The door was found locked from the inside, and he seemed to have been stabbed, but there was an odd smell in the room. Frankly, I'm stumped.").also { stage = END_DIALOGUE } + + 5 -> npcl("Really? That was quick work! Who?").also { stage++ } + 6 -> options("It was an intruder!", "The butler did it!", "It was one of the servants!", "It was one of his family!").also { stage++ } + 7 -> when (buttonID) { + 1 -> playerl("It was an intruder!").also { stage = 10 } + 2 -> playerl("The butler did it!").also { stage = 8 } + 3 -> playerl("It was one of the servants!").also { stage = 13 } + 4 -> playerl("It was one of his family!").also { stage = 20 } + } + 8 -> npcl("I hope you have proof to that effect. We have to arrest someone for this and it seems to me that only the actual murderer would gain by falsely accusing someone.").also { stage++ } + 9 -> npcl("Although having said that the butler is kind of shifty looking...").also { stage = END_DIALOGUE } + + 10 -> npcl("That's what we were thinking too. That someone broke in to steal something, was discovered by Lord Sinclair, stabbed him and ran.").also { stage++ } + 11 -> npcl("It's odd that apparently nothing was stolen though... Find out something has been stolen,").also { stage++ } + 12 -> npcl("and the case is closed, but the murdered man was a friend of the King and it's more than my job's worth not to investigate fully.").also { stage = END_DIALOGUE } + + 13 -> npcl("Oh really? Which one?").also { stage++ } + 14 -> options("It was one of the women.", "It was one of the men.").also { stage++ } + 15 -> when (buttonID) { + 1 -> playerl("It was one of the women.").also { stage = 16 } + 2 -> playerl("It was one of the men.").also { stage = 18 } + } + 16 -> options("It was so obviously Louisa The Cook.", "It must have been Mary The Maid.").also { stage++ } + 17 -> when (buttonID) { + 1 -> playerl("It was so obviously Louisa The Cook.").also { stage = 27 } + 2 -> playerl("It must have been Mary The Maid.").also { stage = 27 } + } + + 18 -> options("It can only be Donovan the Handyman.", "Pierre the Dog Handler. No question", "Hobbes the Butler. The butler *always* did it.", "You must know it was Stanford The Gardener.").also { stage++ } + 19-> when (buttonID) { + 1 -> playerl("It can only be Donovan the Handyman.").also { stage = 27 } + 2 -> playerl("Pierre the Dog Handler. No question.").also { stage = 27 } + 3 -> playerl("Hobbes the Butler. The butler *always* did it.").also { stage = 8 } + 4 -> playerl("You must know it was Stanford The Gardener.").also { stage = 27 } + } + + 20 -> npcl("Oh really? Which one?").also { stage++ } + 21 -> options("It was one of the women.", "It was one of the men.").also { stage++ } + 22 -> when (buttonID) { + 1 -> playerl("It was one of the women.").also { stage = 23 } + 2 -> playerl("It was one of the men.").also { stage = 25 } + } + 23 -> options("I know it was Anna.", "I am so sure it was Carol.", "I'll bet you anything it was Elizabeth.").also { stage++ } + 24 -> when (buttonID) { + 1 -> playerl("I know it was Anna.").also { stage = 27 } + 2 -> playerl("I am so sure it was Carol.").also { stage = 27 } + 3 -> playerl("I'll bet you anything it was Elizabeth.").also { stage = 27 } + } + 25 -> options("I'm certain it was Bob.", "It was David. No doubt about it.", "If it wasn't Frank I'll eat my shoes.").also { stage++ } + 26 -> when (buttonID) { + 1 -> playerl("I'm certain it was Bob.").also { stage = 27 } + 2 -> playerl("It was David. No doubt about it.").also { stage = 27 } + 3 -> playerl("If it wasn't Frank I'll eat my shoes.").also { stage = 27 } + } + 27 -> sendDialogue(player!!, "You tell the guard who you suspect of the crime.").also { stage++ } + 28 -> npcl("Great work, show me the evidence and we'll take them to the dungeons.").also { stage++ } + 29 -> npcl("You *DO* have evidence of their crime, right?").also { stage++ } + 30 -> playerl("Uh...").also { stage++ } + 31 -> npcl("Tch. You wouldn't last a day in the guards with sloppy thinking like that. Come see me when you have some proof of your accusations.").also { stage = END_DIALOGUE } + + 32 -> showTopics( + IfTopic("I have proof that it wasn't any of the servants.", 33, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810), true), + IfTopic("I have proof one of the family lied about the poison.", 37, getAttribute(player!!, attributePoisonClue, 0) == 2, true), + IfTopic("I have the finger prints of the culprit.", 41, inInventory(player!!, Items.KILLERS_PRINT_1815), true) + ) + 33 -> playerl("I have proof that it wasn't any of the servants!").also { stage++ } + 34 -> sendDialogue(player!!, "You show the guard the thread you found on the window.").also { stage ++ } + 35 -> playerl("All the servants dress in black so it couldn't have been one of them.").also { stage++ } + 36 -> npcl("That's some good work there. I guess it wasn't a servant. You still haven't proved who did do it though.").also { stage = END_DIALOGUE } + + 37 -> playerl("I have proof that $KILLER is lying about the poison.").also { stage++ } + 38 -> npcl("Oh really? How did you get that?").also { stage++ } + 39 -> sendDialogue(player!!, "You tell the guard about the " + + when (getAttribute(player!!, attributeRandomMurderer, 0)) { + 4 -> "mosquitos at the fountain." + 5 -> "tarnished family crest." + else -> "$POISONSPOT." + }).also { stage++ } + 40 -> npcl("Hmm. That's some good detective work there, we need more evidence before we can close the case though. Keep up the good work.").also { stage = END_DIALOGUE } + + 41 -> playerl("I have the fingerprints of the culprit!").also { stage++ } + 42 -> playerl("I have $KILLER's fingerprints here, you can see for yourself they match the fingerprints on the murder weapon exactly.").also { stage++ } + 43 -> sendDialogue(player!!,"You show the guard the finger prints evidence.").also { stage++ } + 44 -> npcl("... I'm impressed. How on earth did you think of something like that? I've never heard of such a technique for finding criminals before!").also { stage++ } + 45 -> npcl("This will come in very handy in the future but we can't arrest someone on just this. I'm afraid you'll still need to find more evidence before we can close this case completely.").also { stage = END_DIALOGUE } + + 46 -> playerl(FacialExpression.HAPPY, "I have conclusive proof who the killer was.").also { stage++ } + 47 -> npcl(FacialExpression.HAPPY, "You do? That's excellent work. Let's hear it then.").also { stage++ } + 48 -> playerl("I don't think it was an intruder, and I don't think Lord Sinclair was killed by being stabbed.").also { stage++ } + 49 -> npcl("Hmmm? Really? Why not?").also { stage++ } + 50 -> playerl(FacialExpression.HAPPY, "Nobody heard the guard dog barking, which it would have if it had been an intruder who was responsible.").also { stage++ } + 51 -> playerl("Nobody heard any signs of a struggle either. I think the knife was there to throw suspicion away from the real culprit.").also { stage++ } + 52 -> npcl("Yes, that makes sense. But who did do it then?").also { stage++ } + 53 -> sendDialogue(player!!, "You prove to the guard the thread matches $KILLER's clothes.").also { stage++ } + 54 -> npcl("Yes, I'd have to agree with that... but we need more evidence!").also { stage++ } + 55 -> sendDialogue(player!!, "You prove to the guard $KILLER did not use the poison on the $POISONSPOT.").also { stage++ } + 56 -> npcl("Excellent work - have you considered a career as a detective? But I'm afraid it's still not quite enough...").also { stage++ } + 57 -> sendDialogue(player!!, "You match $KILLER's finger prints with those on the dagger found in the body of Lord Sinclair.").also { stage++ } + 58 -> npcl(FacialExpression.HAPPY, "Yes. There's no doubt about it. It must have been $KILLER who killed " + if (KILLERMALE) {"his"} else {"her"} + " father. All of the guards must congratulate you on your excellent work in helping us to solve this case.").also { stage++ } + 59 -> npcl("We don't have many murders here in $SERVER_NAME and I'm afraid we wouldn't have been able to solve it by ourselves. We will hold " + if (KILLERMALE) {"him"} else {"her"} + " here under house arrest until such time as we bring " + if (KILLERMALE) {"him"} else {"her"} + " to trial.").also { stage++ } + 60 -> npcl("You have our gratitude, and I'm sure the rest of the family's as well, in helping to apprehend the murderer. I'll just take the evidence from you now.").also { stage++ } + 61 -> sendDialogue(player!!, "You hand over all the evidence.").also { stage++ } + 62 -> npcl(FacialExpression.HAPPY, "Please accept this reward from the family!").also { stage++ } + 63 -> finishQuest(player!!, Quests.MURDER_MYSTERY) + .also { + player!!.inventory.removeAll(EVIDENCE) + player!!.bank.removeAll(EVIDENCE) + player!!.equipment.removeAll(EVIDENCE) + } + .also { stage = END_DIALOGUE } + } + 100 -> when (stage) { + 0 -> npcl("Excellent work on solving the murder! All of the guards I know are very impressed, and don't worry, we have the murderer under guard until they can be taken to trial.").also { stage++ } + 1 -> playerl("Is there anything else I can do? Seems awfully quiet up at the house, considering their sibling has just been arrested.").also { stage++ } + 2 -> npcl("Nothing right now, we have it all under control.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/HobbesDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/HobbesDialogue.kt new file mode 100644 index 000000000..75e67d2d6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/HobbesDialogue.kt @@ -0,0 +1,62 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class HobbesDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, HobbesDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return HobbesDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOBBES_808) + } +} + +class HobbesDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> npcl("This is private property! Please leave!").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you at the time of the murder?", 6), + IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)), + IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + + 3 -> npcl("Well, in my considered opinion it must be David. The man is nothing more than a bully And I happen to know that poor Lord Sinclair and David had a massive argument in the living").also { stage++ } + 4 -> npcl("room about the way he treats the staff, the other day. I did not intend to overhear their conversation, but they were shouting so loudly I could not help but Overhear it. David definitely used the words").also { stage++ } + 5 -> npcl("'I am going to kill you!' as well. I think he should be the prime suspect. He has a nasty temper that one.").also { stage = END_DIALOGUE } + + 6 -> npcl("I was assisting the cook with the evening meal. I gave Mary His Lordships' dinner, and sent her to take it to him, then heard the scream as she found the body.").also { stage = END_DIALOGUE } + + 7 -> npcl("How do you mean 'suspicious'?").also { stage++ } + 8 -> playerl("Any sounds of a struggle with Lord Sinclair?").also { stage++ } + 9 -> npcl("No, I definitely didn't hear anything like that.").also { stage++ } + 10 -> playerl("How about the guard dog barking at all?").also { stage++ } + 11 -> npcl("You know, now you come to mention it I don't believe I did. I suppose that is Proof enough that it could not have been an intruder who is responsible.").also { stage = END_DIALOGUE } + + 12 -> npcl("Well, I do know that Elizabeth was extremely annoyed by the mosquito nest under the fountain in the garden, and was going to do something about it. I suspect any poison she bought would have been").also { stage++ } + 13 -> npcl ("enough to get rid of it. A Good job, too. I hate mosquitos.").also { stage++ } + 14 -> playerl("Yeah, so do I.").also { stage++ } + 15 -> npcl("You'd really have to ask her though.").also { stage = END_DIALOGUE } + } + 100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE } + } + } +} + diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/LouisaDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/LouisaDialogue.kt new file mode 100644 index 000000000..f8c7306a7 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/LouisaDialogue.kt @@ -0,0 +1,59 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class LouisaDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LouisaDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return LouisaDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.LOUISA_809) + } +} + +class LouisaDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> npcl("I'm far too upset to talk to random people right now.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you at the time of the murder?", 6), + IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)), + IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + + 3 -> npcl("Elizabeth.").also { stage ++ } + 4 -> npcl("Her father confronted her about her constant petty thieving, and was devastated to find she had stolen a silver needle which had meant a lot to him.").also { stage++ } + 5 -> npcl("You could hear their argument from Lumbridge!").also { stage = END_DIALOGUE } + + 6 -> npcl("I was right here with Hobbes and Mary. You can't suspect me surely!").also { stage = END_DIALOGUE } + + 7 -> npcl("Suspicious? What do you mean suspicious?").also { stage++ } + 8 -> playerl("Any sounds of a struggle with an intruder for example?").also { stage++ } + 9 -> npcl("No, I'm sure I don't recall any such thing.").also { stage++ } + 10 -> playerl("How about the guard dog barking at an intruder?").also { stage++ } + 11 -> npcl("No, I didn't. If you don't have anything else to ask can You go and leave me alone now? I have a lot of cooking to do for this evening.").also { stage = END_DIALOGUE } + + 12 -> npcl("I told Carol to buy some from that strange poison salesman and clean the drains before they began to smell any worse. She was the one who blocked them in the first place with a load").also { stage++ } + 13 -> npcl("of beans that she bought for some reason. There were far too many to eat, and they were almost rotten when she bought them anyway! You'd really have to ask her though.").also { stage = END_DIALOGUE } + } + 100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/MaryDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/MaryDialogue.kt new file mode 100644 index 000000000..07388707c --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/MaryDialogue.kt @@ -0,0 +1,59 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MaryDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MaryDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return MaryDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MARY_810) + } +} + +class MaryDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you at the time of the murder?", 5), + IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)), + IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + + 3 -> npcl("Oh I don't know... Frank was acting kind of funny... After that big argument him and the Lord had the other day by the beehive... so").also { stage ++ } + 4 -> npcl("I guess maybe him... but it's really scary to think someone here might have been responsible. I actually hope it was a burglar...").also { stage = END_DIALOGUE } + + 5 -> npcl("I was with Hobbes and Louisa in the Kitchen helping to prepare Lord Sinclair's meal, and then when I took it to his study... I saw... oh, it was horrible... he was...").also { stage++ } + 6 -> sendDialogue(player!!, "She seems to be on the verge of crying. You decide not to push her anymore for details.").also { stage = END_DIALOGUE} + + 7 -> npcl("I don't really remember hearing anything out of the ordinary.").also { stage++ } + 8 -> playerl("No sounds of a struggle then?").also { stage++ } + 9 -> npcl("No, I don't remember hearing anything like that.").also { stage++ } + 10 -> playerl("How about the guard dog barking?").also { stage++ } + 11 -> npcl("Oh that horrible dog is always barking at noting but I don't think I did...").also { stage = END_DIALOGUE } + + 12 -> npcl("I overheard Anna saying to Stanford that if he didn't do something about the state of his compost heap, she was going to.").also { stage++ } + 13 -> npcl("She really doesn't get on well with Stanford, I really have no idea why. You'd really have to ask her though.").also { stage = END_DIALOGUE } + } + 100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/MurderMystery.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/MurderMystery.kt new file mode 100644 index 000000000..23ec627b1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/MurderMystery.kt @@ -0,0 +1,156 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +// https://www.youtube.com/watch?v=f1Eou5i5hBo at 2:29 +// https://www.youtube.com/watch?v=BwO4JhZdQKo at 25:20 +// https://www.youtube.com/watch?v=u5Osw_jas4A at 26:35 +// https://www.youtube.com/watch?v=f1Eou5i5hBo +// https://www.youtube.com/watch?v=9Q2aLUg44SQ at 10:02 +// https://www.youtube.com/watch?v=_lTUessdfOM 6:18 + +/** + * Murder Mystery Quest + */ +@Initializable +class MurderMystery : Quest(Quests.MURDER_MYSTERY, 93, 92, 3, 192, 0, 1, 2) { + + companion object { + const val questName = "Murder Mystery" + + const val attributeRandomMurderer = "/save:quest:murdermystery-randommurderer" //Alphabetical, 0 for Anna, 1 for Bob, 2 for Carol, 3 for David, 4 for Elizabeth, 5 for Frank + const val attributeTakenThread = "/save:quest:murdermystery-takenthread" //true after taking thread for the first time from window + const val attributeNoiseClue = "/save:quest:murdermystery-noiseclue" //true on learning of the barking dog for the first time + const val attributePoisonClue = "/save:quest:murdermystery-poisonclue" //1 after learning poison was bought, 2 after finding liar + const val attributeAskPoisonAnna = "/save:quest:murdermystery-askpoisonanna" //true after asking Anna about poison + const val attributeAskPoisonBob = "/save:quest:murdermystery-askpoisonbob" //true after asking Bob about poison + const val attributeAskPoisonCarol = "/save:quest:murdermystery-askpoisoncarol" //true after asking Carol about poison + const val attributeAskPoisonDavid = "/save:quest:murdermystery-askpoisondavid" //true after asking David about poison + const val attributeAskPoisonElizabeth = "/save:quest:murdermystery-askpoisonelizabeth" //true after asking Elizabeth about poison + const val attributeAskPoisonFrank = "/save:quest:murdermystery-askpoisonfrank" //true after asking Anna about poison + + fun clueCount(player: Player) : Int { + var count = 0 + if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) { + count++ + } + if (inInventory(player, Items.KILLERS_PRINT_1815)) { + count ++ + } + if (getAttribute(player, attributePoisonClue,0) == 2) { + count ++ + } + return count + } + + fun solvedMystery(player: Player) : Boolean { + return ( + ( inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810) ) + && inInventory(player, Items.KILLERS_PRINT_1815) + && getAttribute(player, attributePoisonClue,0) == 2 + && getAttribute(player, attributeNoiseClue, false) + ) + } + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.MURDER_MYSTERY) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to one of the !!Guards?? at", line++, false) + line(player, "the !!Sinclair Mansion??, North of the !!Seer's Village??.", line++, false) + } else if (stage < 100) { + line(player, "Lord Sinclair, a prominent nobleman, had been horribly", line++, true) + line(player, "murdered at his mansion. The guards had been sent to", line++, true) + line(player, "investigate his murder, but have been completely stuck.", line++, true) + + if (solvedMystery(player)) { + line(player, "One of the guards asked me for my help in solving the", line++, true) + line(player, "murder. After careful examination of the crime scene and", line++, true) + line(player, "interrogating all suspects, I worked out who was guilty.", line++, true) + } else { + line(player, "One of the !!guards?? has asked me for my help in solving the", line++, false) + line(player, "murder. I should !!examine the crime scene?? very closely for", line++, false) + line(player, "evidence, and !!interrogate everybody?? in the area carefully.", line++, false) + } + + // This may not be a stage but an attribute when all the evidence is collected. + if (solvedMystery(player)) { + line(player, "I have !!indisputable evidence?? of who the murderer must be.", line++, false) + line(player, "I should take it to one of the !!Guards?? immediately.", line++, false) + } else { + line++ + if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) { + line(player, "I have found some !!coloured thread??. It might be useful.", line++, false) + } + if (inInventory(player, Items.CRIMINALS_DAGGER_1813) || inInventory(player, Items.CRIMINALS_DAGGER_1814)) { + line(player, "I have taken the !!murder weapon??. I think it might help me.", line++, false) + } + if (inInventory(player, Items.PUNGENT_POT_1812)) { + line(player, "I have a !!strange smelling pot??. It seems like a clue.", line++, false) + } + } + } else { + line(player, "One of the guards asked me for my help in solving the", line++, true) + line(player, "murder. After careful examination of the crime scene and", line++, true) + line(player, "interrogating all suspects, I worked out who was guilty.", line++, true) + line(player, "I took the evidence I had collected to the Guards and", line++, true) + line(player, "explained how it could identify the killer. Impressed", line++, true) + line(player, "with my deductions, the killer was arrested and I was", line++, true) + line(player, "given a fair reward for my help in solving the crime.", line++, true) + line++ + line(player,"QUEST COMPLETE!", line) + } + + } + + override fun reset(player: Player) { + removeAttribute(player, attributeRandomMurderer) + removeAttribute(player, attributeNoiseClue) + removeAttribute(player, attributePoisonClue) + removeAttribute(player, attributeTakenThread) + removeAttribute(player, attributeAskPoisonAnna) + removeAttribute(player, attributeAskPoisonBob) + removeAttribute(player, attributeAskPoisonCarol) + removeAttribute(player, attributeAskPoisonDavid) + removeAttribute(player, attributeAskPoisonElizabeth) + removeAttribute(player, attributeAskPoisonFrank) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Murder Mystery quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.COINS_617, 230, 277, 5) + + drawReward(player, "3 Quest Points", ln++) + drawReward(player, "2000 coins", ln++) + drawReward(player, "1406 Crafting XP", ln++) + + addItem(player, Items.COINS_995, 2000) + rewardXP(player, Skills.CRAFTING, 1406.0) + + removeAttribute(player, attributeNoiseClue) + removeAttribute(player, attributePoisonClue) + removeAttribute(player, attributeTakenThread) + removeAttribute(player, attributeAskPoisonAnna) + removeAttribute(player, attributeAskPoisonBob) + removeAttribute(player, attributeAskPoisonCarol) + removeAttribute(player, attributeAskPoisonDavid) + removeAttribute(player, attributeAskPoisonElizabeth) + removeAttribute(player, attributeAskPoisonFrank) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/MurderMysteryListeners.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/MurderMysteryListeners.kt new file mode 100644 index 000000000..bf9184584 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/MurderMysteryListeners.kt @@ -0,0 +1,442 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonAnna +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonBob +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonCarol +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonDavid +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonElizabeth +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonFrank +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeRandomMurderer +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeTakenThread +import core.api.* +import core.game.interaction.InteractionListener +import core.game.node.item.GroundItem +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class MurderMysteryListeners : InteractionListener { + companion object { + val UNDUSTEDEVIDENCE = intArrayOf( + Items.CRIMINALS_DAGGER_1813, + Items.PUNGENT_POT_1812, + Items.SILVER_NECKLACE_1796, + Items.SILVER_CUP_1798, + Items.SILVER_BOTTLE_1800, + Items.SILVER_BOOK_1802, + Items.SILVER_NEEDLE_1804, + Items.SILVER_POT_1806 + ) + val DUSTEDEVIDENCE = intArrayOf( + Items.CRIMINALS_DAGGER_1814, + Items.SILVER_NECKLACE_1797, + Items.SILVER_CUP_1799, + Items.SILVER_BOTTLE_1801, + Items.SILVER_BOOK_1803, + Items.SILVER_NEEDLE_1805, + Items.SILVER_POT_1807 + ) + val SILVERBARRELS = intArrayOf( + Scenery.ANNA_S_BARREL_2656, + Scenery.BOB_S_BARREL_2657, + Scenery.CAROL_S_BARREL_2658, + Scenery.DAVID_S_BARREL_2659, + Scenery.ELIZABETH_S_BARREL_2660, + Scenery.FRANK_S_BARREL_2661 + ) + val POISONSPOTS = intArrayOf( + Scenery.SINCLAIR_FAMILY_COMPOST_HEAP_26120, + Scenery.SINCLAIR_FAMILY_BEEHIVE_26121, + Scenery.SINCLAIR_MANSION_DRAIN_2843, + Scenery.SPIDERS__NEST_26109, + Scenery.SINCLAIR_FAMILY_FOUNTAIN_2654, + Scenery.SINCLAIR_FAMILY_CREST_2655 + ) + val SUSPECTPRINTS = intArrayOf( + Items.ANNAS_PRINT_1816, + Items.BOBS_PRINT_1817, + Items.CAROLS_PRINT_1818, + Items.DAVIDS_PRINT_1819, + Items.ELIZABETHS_PRINT_1820, + Items.FRANKS_PRINT_1821 + ) + } + + override fun defineListeners() { + on(Items.CRIMINALS_DAGGER_1813, GROUNDITEM, "take") { player, groundItem -> + when (getQuestStage(player, Quests.MURDER_MYSTERY)) { + 1 -> { + if (inInventory(player, Items.CRIMINALS_DAGGER_1813) || inInventory(player, Items.CRIMINALS_DAGGER_1814)) { + sendDialogue(player, "I already have the murder weapon.") + } + else if (addItem(player, Items.CRIMINALS_DAGGER_1813)) { + removeGroundItem(groundItem as GroundItem) + sendDialogue(player, "This knife doesn't seem sturdy enough to have killed Lord Sinclair.") + } + return@on true + } + else -> { + sendDialogue(player, "You need the guards' permission to do that.") + return@on true + } + } + } + on(Items.PUNGENT_POT_1812, GROUNDITEM, "take") { player, groundItem -> + when (getQuestStage(player, Quests.MURDER_MYSTERY)) { + 1 -> { + if (inInventory(player, Items.PUNGENT_POT_1812)) { + sendDialogue(player, "I already have the poisoned pot.") + } else if (addItem(player, Items.PUNGENT_POT_1812)) { + removeGroundItem(groundItem as GroundItem) + sendDialogue(player, "It seems like Lord Sinclair was drinking from this before he died.") + } + return@on true + } + else -> { + sendDialogue(player, "You need the guards' permission to do that.") + return@on true + } + } + } + on(intArrayOf(Scenery.STURDY_WOODEN_GATE_2664, Scenery.STURDY_WOODEN_GATE_2665), SCENERY, "investigate") { player, _ -> + when (getQuestStage(player, Quests.MURDER_MYSTERY)) { + 1 -> { + sendDialogue(player, "As you approach the gate the guard dog starts barking loudly at you. There is no way an intruder could have committed the murder. It must have been someone the dog knew to get past it quietly.") + setAttribute(player, attributeNoiseClue, true) + return@on true + } + else -> { + sendDialogue(player, "You need the guards' permission to do that.") + return@on true + } + } + } + on(Scenery.SMASHED_WINDOW_26110, SCENERY, "investigate") { player, _ -> + when (getQuestStage(player, Quests.MURDER_MYSTERY)) { + 1 -> { + sendDialogue(player, "Some thread seems to have been caught on a loose nail on the window.") + if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) { + sendMessage(player, "You have already taken the thread.") + } + else if (getAttribute(player, attributeTakenThread, false)) { + if (hasSpaceFor(player, Item(Items.CRIMINALS_THREAD_1808))) { + when (getAttribute(player, attributeRandomMurderer, 0)) { + 1, 2 -> addItem(player, Items.CRIMINALS_THREAD_1808) + 0, 3 -> addItem(player, Items.CRIMINALS_THREAD_1809) + else -> addItem(player, Items.CRIMINALS_THREAD_1810) + } + sendMessage(player, "Lucky for you there's some thread left. You should be less careless in the future.") + } + } + else { + if (hasSpaceFor(player, Item(Items.CRIMINALS_THREAD_1808))) { + when (getAttribute(player, attributeRandomMurderer, 0)) { + 1, 2 -> addItem(player, Items.CRIMINALS_THREAD_1808) + 0, 3 -> addItem(player, Items.CRIMINALS_THREAD_1809) + else -> addItem(player, Items.CRIMINALS_THREAD_1810) + } + sendMessage(player, "You take the thread.") + setAttribute(player, attributeTakenThread, true) + } + } + return@on true + } + else -> { + sendDialogue(player, "You need the guards' permission to do that.") + return@on true + } + } + } + on(Scenery.SMASHED_WINDOW_26110, SCENERY, "break") { player, _ -> + sendDialogue(player, "You don't want to damage evidence!") + return@on true + } + on(Scenery.SACKS_2663, SCENERY, "investigate") { player, _ -> + when (getQuestStage(player, Quests.MURDER_MYSTERY)) { + 1 -> { + openDialogue(player, FlypaperDialogue()) + return@on true + } + else -> { + sendDialogue(player, "You need the guards' permission to do that.") + return@on true + } + } + } + on(SILVERBARRELS, SCENERY, "search") { player, node -> + when (getQuestStage(player, Quests.MURDER_MYSTERY)) { + 1 -> { + when (node.id) { + Scenery.ANNA_S_BARREL_2656 -> { + if (inInventory(player, Items.SILVER_NECKLACE_1796) || inInventory(player, Items.SILVER_NECKLACE_1797)) { + sendDialogue(player, "I already have Anna's Necklace.") + } + else if (addItem(player, Items.SILVER_NECKLACE_1796)){ + sendDialogue(player, "There's something shiny hidden at the bottom. You take Anna's Silver Necklace.") + } + } + Scenery.BOB_S_BARREL_2657 -> { + if (inInventory(player, Items.SILVER_CUP_1798) || inInventory(player, Items.SILVER_CUP_1799)) { + sendDialogue(player, "I already have Bob's cup.") + } + else if (addItem(player, Items.SILVER_CUP_1798)){ + sendDialogue(player, "There's something shiny hidden at the bottom. You take Bob's silver cup.") + } + } + Scenery.CAROL_S_BARREL_2658 -> { + if (inInventory(player, Items.SILVER_BOTTLE_1800) || inInventory(player, Items.SILVER_BOTTLE_1801)) { + sendDialogue(player, "I already have Carol's bottle.") + } + else if (addItem(player, Items.SILVER_BOTTLE_1800)){ + sendDialogue(player, "There's something shiny hidden at the bottom. You take Carol's silver bottle.") + } + } + Scenery.DAVID_S_BARREL_2659 -> { + if (inInventory(player, Items.SILVER_BOOK_1802) || inInventory(player, Items.SILVER_BOOK_1803)) { + sendDialogue(player, "I already have David's book.") + } + else if (addItem(player, Items.SILVER_BOOK_1802)){ + sendDialogue(player, "There's something shiny hidden at the bottom. You take David's silver book.") + } + } + Scenery.ELIZABETH_S_BARREL_2660 -> { + if (inInventory(player, Items.SILVER_NEEDLE_1804) || inInventory(player, Items.SILVER_NEEDLE_1805)) { + sendDialogue(player, "I already have Elizabeth's Needle.") + } + else if (addItem(player, Items.SILVER_NEEDLE_1804)){ + sendDialogue(player, "There's something shiny hidden at the bottom. You take Elizabeth's silver needle.") + } + } + Scenery.FRANK_S_BARREL_2661 -> { + if (inInventory(player, Items.SILVER_POT_1806) || inInventory(player, Items.SILVER_POT_1807)) { + sendDialogue(player, "I already have Frank's pot.") + } + else if (addItem(player, Items.SILVER_POT_1806)){ + sendDialogue(player, "There's something shiny hidden at the bottom. You take Frank's silver pot.") + } + } + } + return@on true + } + else -> { + sendDialogue(player, "You need the guards' permission to do that.") + return@on true + } + } + } + on(POISONSPOTS, SCENERY, "investigate") { player, node -> + when (node.id) { + Scenery.SINCLAIR_FAMILY_COMPOST_HEAP_26120 -> { + if (!getAttribute(player, attributeAskPoisonAnna, false)) { + sendDialogue(player, "It's a heap of compost.") + } + else if (getAttribute(player, attributeRandomMurderer, 0) == 0) { + sendDialogue(player, "The compost is teeming with maggots. Somebody should really do something about it. It's certainly clear nobody's used poison here.") + setAttribute(player, attributePoisonClue, 2) + } + else { + sendDialogue(player, "There is a faint smell of poison behind the smell of the compost.") + } + } + Scenery.SINCLAIR_FAMILY_BEEHIVE_26121 -> { + if (!getAttribute(player, attributeAskPoisonBob, false)) { + sendDialogue(player, "It's a very old beehive.") + } + else if (getAttribute(player, attributeRandomMurderer, 0) == 1) { + sendDialogue(player, "The beehive buzzes with activity. These bees definitely don't seem poisoned at all.") + setAttribute(player, attributePoisonClue, 2) + } + else { + sendDialogue(player, "The hive is empty. There are a few dead bees and a faint smell of poison.") + } + } + Scenery.SINCLAIR_MANSION_DRAIN_2843 -> { + if (!getAttribute(player, attributeAskPoisonCarol, false)) { + sendDialogue(player, "It's the drains from the kitchen.") + } + else if (getAttribute(player, attributeRandomMurderer, 0) == 2) { + sendDialogue(player, "The drain is totally blocked. It really stinks. No, it REALLY smells bad. It's certainly clear nobody's cleaned it recently.") + setAttribute(player, attributePoisonClue, 2) + } + else { + sendDialogue(player, "The drain seems to have been recently cleaned. You can still smell the faint aroma of poison.") + } + } + Scenery.SPIDERS__NEST_26109 -> { + if (!getAttribute(player, attributeAskPoisonDavid, false)) { + sendDialogue(player, "It looks like a spiders' nest of some kind...") + } + else if (getAttribute(player, attributeRandomMurderer, 0) == 3) { + sendDialogue(player, "There is a spiders' nest here. You estimate there must be at least a few hundred spiders ready to hatch. It's certainly clear nobody's used poison here.") + setAttribute(player, attributePoisonClue, 2) + } + else { + sendDialogue(player, "A faint smell of poison and a few dead spiders is all that remains of the spiders nest.") + } + } + Scenery.SINCLAIR_FAMILY_FOUNTAIN_2654 -> { + if (!getAttribute(player, attributeAskPoisonElizabeth, false)) { + sendDialogue(player, "A fountain with large numbers of insects around the base.") + } + else if (getAttribute(player, attributeRandomMurderer, 0) == 4) { + openDialogue(player, FountainDialogue()) + setAttribute(player, attributePoisonClue, 2) + } + else { + sendDialogue(player, "There are a lot of dead mosquitos around the base of the fountain. A faint smell of poison is in the air, but the water seems clean.") + } + } + Scenery.SINCLAIR_FAMILY_CREST_2655 -> { + if (!getAttribute(player, attributeAskPoisonFrank, false)) { + sendDialogue(player, "The Sinclair Family Crest is hung up here.") + } + else if (getAttribute(player, attributeRandomMurderer, 0) == 5) { + sendDialogue(player, "It looks like the Sinclair family crest but it is very dirty. You can barely make it out under all of the grime. It's certainly clear nobody's cleaned it recently.") + setAttribute(player, attributePoisonClue, 2) + } + else { + sendDialogue(player, "The Sinclair family crest. It's shiny and freshly polished and has a slight smell of poison.") + } + } + + } + return@on true + } + onUseWith(ITEM, UNDUSTEDEVIDENCE, Items.POT_OF_FLOUR_1933) { player, used, _ -> + when (used.id) { + Items.CRIMINALS_DAGGER_1813 -> { + removeItem(player, used) + addItem(player, Items.CRIMINALS_DAGGER_1814) + sendMessage(player, "You sprinkle a small amount of flour on the murder weapon.") + sendMessage(player, "The murder weapon is now coated with a thin layer of flour.") + } + Items.PUNGENT_POT_1812 -> { + sendMessage(player, "You sprinkle a small amount of flour on the strange smelling pot.") + sendMessage(player, "The surface isn't shiny enough to take a fingerprint from.") + } + Items.SILVER_NECKLACE_1796 -> { + removeItem(player, used) + addItem(player, Items.SILVER_NECKLACE_1797) + sendMessage(player, "You sprinkle the flour on Anna's necklace.") + sendMessage(player, "The necklace is now coated with a thin layer of flour.") + } + Items.SILVER_CUP_1798 -> { + removeItem(player, used) + addItem(player, Items.SILVER_CUP_1799) + sendMessage(player, "You sprinkle the flour on Bob's cup.") + sendMessage(player, "The cup is now coated with a thin layer of flour.") + } + Items.SILVER_BOTTLE_1800 -> { + removeItem(player, used) + addItem(player, Items.SILVER_BOTTLE_1801) + sendMessage(player, "You sprinkle the flour on Carol's bottle.") + sendMessage(player, "The bottle is now coated with a thin layer of flour.") + } + Items.SILVER_BOOK_1802 -> { + removeItem(player, used) + addItem(player, Items.SILVER_BOOK_1803) + sendMessage(player, "You sprinkle the flour on David's book.") + sendMessage(player, "The Book is now coated with a thin layer of flour.") + } + Items.SILVER_NEEDLE_1804 -> { + removeItem(player, used) + addItem(player, Items.SILVER_NEEDLE_1805) + sendMessage(player, "You sprinkle the flour on Elizabeth's needle.") + sendMessage(player, "The Needle is now coated with a thin layer of flour.") + } + Items.SILVER_POT_1806 -> { + removeItem(player, used) + addItem(player, Items.SILVER_POT_1807) + sendMessage(player, "You sprinkle the flour on Frank's pot") + sendMessage(player, "The Pot is now coated with a thin layer of flour.") + } + } + removeItem(player, Items.POT_OF_FLOUR_1933) + addItem(player, Items.EMPTY_POT_1931) + return@onUseWith true + } + onUseWith(ITEM, DUSTEDEVIDENCE, Items.FLYPAPER_1811) { player, used, _ -> + removeItem(player, Items.FLYPAPER_1811) + when (used.id) { + Items.CRIMINALS_DAGGER_1814 -> { + removeItem(player, used) + addItem(player, Items.CRIMINALS_DAGGER_1813) + addItem(player, Items.UNKNOWN_PRINT_1822) + sendMessage(player, "You use the flypaper on the floury dagger.") + sendMessage(player, "You have a clean impression of the murderer's finger prints.") + } + Items.SILVER_NECKLACE_1797 -> { + removeItem(player, used) + addItem(player, Items.SILVER_NECKLACE_1796) + addItem(player, Items.ANNAS_PRINT_1816) + sendMessage(player, "You use the flypaper on the flour covered necklace.") + sendMessage(player, "You have a clean impression of Anna's finger prints.") + } + Items.SILVER_CUP_1799 -> { + removeItem(player, used) + addItem(player, Items.SILVER_CUP_1798) + addItem(player, Items.BOBS_PRINT_1817) + sendMessage(player, "You use the flypaper on the flour covered cup.") + sendMessage(player, "You have a clean impression of Bob's finger prints.") + } + Items.SILVER_BOTTLE_1801 -> { + removeItem(player, used) + addItem(player, Items.SILVER_BOTTLE_1800) + addItem(player, Items.CAROLS_PRINT_1818) + sendMessage(player, "You use the flypaper on the flour covered bottle.") + sendMessage(player, "You have a clean impression of Carol's finger prints.") + } + Items.SILVER_BOOK_1803 -> { + removeItem(player, used) + addItem(player, Items.SILVER_BOOK_1802) + addItem(player, Items.DAVIDS_PRINT_1819) + sendMessage(player, "You use the flypaper on the flour covered book.") + sendMessage(player, "You have a clean impression of David's finger prints.") + } + Items.SILVER_NEEDLE_1805 -> { + removeItem(player, used) + addItem(player, Items.SILVER_NEEDLE_1804) + addItem(player, Items.ELIZABETHS_PRINT_1820) + sendMessage(player, "You use the flypaper on the flour covered needle.") + sendMessage(player, "You have a clean impression of Elizabeth's finger prints.") + } + Items.SILVER_POT_1807 -> { + removeItem(player, used) + addItem(player, Items.SILVER_POT_1806) + addItem(player, Items.FRANKS_PRINT_1821) + sendMessage(player, "You use the flypaper on the flour covered pot.") + sendMessage(player, "You have a clean impression of Frank's finger prints.") + } + } + return@onUseWith true + } + onUseWith(ITEM, SUSPECTPRINTS, Items.UNKNOWN_PRINT_1822) { player, used, with -> + val SUSPECT = when (used.id) { + Items.ANNAS_PRINT_1816 -> "Anna" + Items.BOBS_PRINT_1817 -> "Bob" + Items.CAROLS_PRINT_1818 -> "Carol" + Items.DAVIDS_PRINT_1819 -> "David" + Items.ELIZABETHS_PRINT_1820 -> "Elizabeth" + Items.FRANKS_PRINT_1821 -> "Frank" + else -> "Anna" + } + if (used.id == getAttribute(player, attributeRandomMurderer, 0) + Items.ANNAS_PRINT_1816) { + sendDialogue(player, "The fingerprints are an exact match to $SUSPECT's.") + removeItem(player, with.id) + addItem(player, Items.KILLERS_PRINT_1815) + } + else { + sendDialogue(player, "They don't seem to be the same. I guess that clears $SUSPECT of the crime. You destroy the useless fingerprint.") + removeItem(player, used.id) + } + return@onUseWith true + } + onUseWith(SCENERY, intArrayOf(Items.SILVER_POT_1806, Items.PUNGENT_POT_1812), Scenery.BARREL_OF_FLOUR_26122) { player, _, _ -> + sendDialogue(player, "You probably shouldn't use evidence from a crime scene to keep flour in.") + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/PierreDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/PierreDialogue.kt new file mode 100644 index 000000000..7d94c0677 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/PierreDialogue.kt @@ -0,0 +1,58 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class PierreDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, PierreDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return PierreDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.PIERRE_807) + } +} + +class PierreDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> npcl("The Guards told me not to talk to anyone.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you at the time of the murder?", 5), + IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)), + IfTopic("Do you know why so much poison was bought recently?", 11, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + + 3 -> npcl("Honestly? I think it was Carol.").also { stage++ } + 4 -> npcl("I saw her in a huge argument with Lord Sinclair in the library the other day. It was something to do with stolen books. She definitely seemed upset enough to have done it afterwards.").also { stage = END_DIALOGUE } + + 5 -> npcl("I was in town at the inn. When I got back the house was swarming with guards who told me what had happened. Sorry.").also { stage = END_DIALOGUE } + + 6 -> npcl("Well, like what?").also { stage++ } + 7 -> playerl("Any sounds of a struggle with Lord Sinclair?").also { stage++ } + 8 -> npcl("No, I don't remember hearing anything like that.").also { stage++ } + 9 -> playerl("How about the guard dog barking at all?").also { stage++ } + 10 -> npcl("I hear him bark all the time. It's one of his favourite things to do. I can't say I did the night of the murder though as I wasn't close enough to hear either way.").also { stage = END_DIALOGUE } + + 11 -> npcl("Well, I know David said that he was going to do something about the spiders' nest that's between the two servants' quarters upstairs.").also { stage++ } + 12 -> npcl("He made a big deal about it to Mary the Maid, calling her useless and incompetent. I felt quite sorry for her actually. You'd really have to ask him though.").also { stage = END_DIALOGUE } + } + 100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/murdermystery/StanfordDialogue.kt b/Server/src/main/content/region/kandarin/quest/murdermystery/StanfordDialogue.kt new file mode 100644 index 000000000..ea70f1a92 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/murdermystery/StanfordDialogue.kt @@ -0,0 +1,58 @@ +package content.region.kandarin.quest.murdermystery + +import content.data.Quests +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue +import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class StanfordDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, StanfordDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return StanfordDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.STANFORD_811) + } +} + +class StanfordDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){ + 0 -> npcl("Have you no shame? We are all grieving at the moment.").also { stage = END_DIALOGUE } + 1 -> when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ } + 2 -> showTopics( + Topic("Who do you think is responsible?", 3), + Topic( "Where were you at the time of the murder?", 5), + IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)), + IfTopic("Do you know why so much poison was bought recently?", 11, getAttribute(player!!, attributePoisonClue, 0) > 0) + ) + + 3 -> npcl("It was Anna. She is seriously unbalanced. She trashed the garden once then tried to blame it on me! I bet it was her. It's just the kind of thing she'd do!").also { stage++ } + 4 -> npcl("She really hates me and was arguing with Lord Sinclair about trashing the garden a few days ago.").also { stage = END_DIALOGUE } + + 5 -> npcl("Right here, by my little shed. It's very cosy to sit and think in.").also { stage = END_DIALOGUE } + + 6 -> npcl("Not that I remember.").also { stage++ } + 7 -> playerl("So no sounds of a struggle between Lord Sinclair and an intruder?").also { stage++ } + 8 -> npcl("Not to the best of my recollection.").also { stage++ } + 9 -> playerl("How about the guard dog barking?").also { stage++ } + 10 -> npcl("Not that I can recall.").also { stage = END_DIALOGUE } + + 11 -> npcl("Well, Bob mentioned to me the other day he wanted to get rid of the bees in that hive over there. I think I saw him buying poison").also { stage++ } + 12 -> npcl("from that poison salesman the other day. I assume it was to sort out those bees. You'd really have to ask him though.").also { stage = END_DIALOGUE } + } + 100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/AstronomyBook.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/AstronomyBook.kt new file mode 100644 index 000000000..9af08c1b1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/AstronomyBook.kt @@ -0,0 +1,171 @@ +package content.region.kandarin.quest.observatoryquest + +import content.global.handlers.iface.* +import core.ServerConstants +import core.api.storeBookInHouse +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Astronomy Book + */ +class AstronomyBook : InteractionListener { + companion object { + private const val TITLE = "THE TALE OF SCORPIUS" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("THE TALE OF", 55), + BookLine("SCORPIUS: ", 56), + BookLine("", 57), + BookLine("A History of Astronomy", 58), + BookLine("in ${ServerConstants.SERVER_NAME}.", 59), + BookLine("", 60), + BookLine("At the start of the 4th", 61), + BookLine("Age, a learned man by", 62), + BookLine("the name of Scorpius,", 63), + BookLine("known well for his powers", 64), + BookLine("of vision and magic,", 65), + ), + Page( + BookLine("sought communion with", 66), + BookLine("the gods of the world. So", 67), + BookLine("many unanswered", 68), + BookLine("questions had he that he", 69), + BookLine("devoted his entire lif to", 70), + BookLine("the cause.", 71), + BookLine("", 72), + BookLine("After many years of", 73), + BookLine("study, seeking knowledge", 74), + BookLine("from the wise of that", 75), + BookLine("time, he developed a", 76), + ) + ), + PageSet( + Page( + BookLine("machine infused with", 55), + BookLine("magical power, infused", 56), + BookLine("with the ability to pierce", 57), + BookLine("into the very heavens - a", 58), + BookLine("huge eye that gave the", 59), + BookLine("user incredible sight, like", 60), + BookLine("never before.", 61), + BookLine("", 62), + BookLine("", 63), + BookLine("", 64), + BookLine("", 65), + ), + Page( + BookLine("As time passed, Scorpius", 66), + BookLine("grew adept at using his", 67), + BookLine("specialized skills, and", 68), + BookLine("followed the movements of", 69), + BookLine("the stars in ${ServerConstants.SERVER_NAME}", 70), + BookLine("which he mapped and", 71), + BookLine("named, and are still used", 72), + BookLine("to this very day.", 73), + BookLine("", 74), + BookLine("Before long, Scorpius", 75), + BookLine("used his knowledge for", 76), + ) + ), + PageSet( + Page( + BookLine("predicting the future,", 55), + BookLine("and, in turn, he called", 56), + BookLine("upon the dark knowledge", 57), + BookLine("of Zamorakian", 58), + BookLine("worshippers to further his", 59), + BookLine("cause. Living below", 60), + BookLine("ground, the followers of", 61), + BookLine("the dark god remained", 62), + BookLine("until the civilisation of", 63), + BookLine("Ardougne grew in", 64), + BookLine("strength and control.", 65), + ), + Page( + BookLine("", 66), + BookLine("", 67), + BookLine("", 68), + BookLine("", 69), + BookLine("", 70), + BookLine("", 71), + BookLine("The kings of that time", 72), + BookLine("worked to banish the", 73), + BookLine("Zamorakian followers in", 74), + BookLine("the area, hiding all", 75), + BookLine("references to Scorpius's", 76), + ) + ), + PageSet( + Page( + BookLine("invention, due to its 'evil", 55), + BookLine("nature'.", 56), + BookLine("", 57), + BookLine("Years after, when the", 58), + BookLine("minds of the kings lent", 59), + BookLine("more towards the", 60), + BookLine("research of the unknown,", 61), + BookLine("the plans of Scorpius", 62), + BookLine("were uncovered and the", 63), + BookLine("heavenly eye constructed", 64), + BookLine("again.", 65), + ), + Page( + BookLine("Since then, many have", 66), + BookLine("studied the ways of the", 67), + BookLine("astronomer, Scorpius, and", 68), + BookLine("in his memory a grave", 69), + BookLine("was constructed near the", 70), + BookLine("Observatory.", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76), + ) + ), + + PageSet( + Page(), + Page( + BookLine("Some claim his ghost still", 66), + BookLine("wanders nearby, in", 67), + BookLine("torment as he seeks the", 68), + BookLine("secrets of the heavens", 69), + BookLine("that can never be solved.", 70), + BookLine("Tales tell that he will", 71), + BookLine("grant those adept in the", 72), + BookLine("arts of the astronomer a", 73), + BookLine("blessing of unusual", 74), + BookLine("power.", 75), + BookLine("", 76), + ) + ), + PageSet( + Page( + BookLine("Here ends the tale of how", 55), + BookLine("astronomy entered the", 56), + BookLine("known world.", 57), + ), + Page() + ), + ) + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + BookInterface.setModelOnPage(player,2, 27071, BookInterface.FANCY_BOOK_3_49, 33, 34, 1020, 0, 0) + BookInterface.setModelOnPage(player,4, 27069, BookInterface.FANCY_BOOK_3_49, 17, 18, 1224, 0, 0) + return true + } + } + + override fun defineListeners() { + on(Items.ASTRONOMY_BOOK_600, IntType.ITEM, "read") { player, node -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/GoblinDialogues.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/GoblinDialogues.kt new file mode 100644 index 000000000..5d676d5de --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/GoblinDialogues.kt @@ -0,0 +1,152 @@ +package content.region.kandarin.quest.observatoryquest + +import core.api.* +import core.game.dialogue.* +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class GoblinDialogues : InteractionListener { + override fun defineListeners() { + on(NPCs.GREASYCHEEKS_6127, NPC, "talk-to") { player, node -> + openDialogue(player, GreasycheeksDialogueFile(), node as NPC) + return@on true + } + on(NPCs.SMELLYTOES_6128, NPC, "talk-to") { player, node -> + openDialogue(player, SmellytoesDialogueFile(), node as NPC) + return@on true + } + on(NPCs.CREAKYKNEES_6129, NPC, "talk-to") { player, node -> + openDialogue(player, CreakykneesDialogueFile(), node as NPC) + return@on true + } + } +} + +class GreasycheeksDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.GREASYCHEEKS_6127) + player("Hello.") + npc(ChatAnim.OLD_NORMAL, "Shush! I'm concentrating.") + player("Oh, sorry.") + } +} + +class SmellytoesDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.SMELLYTOES_6128) + player("Hi there.") + npc(ChatAnim.OLD_NORMAL, "Hey, ids me matesh!") + player("Sorry, have we met?") + npc(ChatAnim.OLD_NORMAL, "Yeah! you wazsh wiv me in dat pub overy by hill!") + player("I have no idea what you're going on about.") + npc(ChatAnim.OLD_NORMAL, "Glad yeeash remembers.") + } +} + +class CreakykneesDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.CREAKYKNEES_6129) + player("Where did you get that lens?") + npc(ChatAnim.OLD_NORMAL, "From that strange metal thing up on the hill.") + player(ChatAnim.ANGRY, "You should give that back!") + npc(ChatAnim.OLD_NORMAL, "Even if it's cracked?") + player("Ah, well, I suppose it's of no use. But, still.") + } +} + +@Initializable +class GreasycheeksNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return GreasycheeksNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GREASYCHEEKS_6127) + } + + override fun handleTickActions() { + super.handleTickActions() + if (RandomFunction.roll(12)) { + sendChat(this, arrayOf( + "Cook, cook, cook!", + "I'm so hungry!", + "This is gonna taste sooo good!", + ).random()) + } + } +} + +@Initializable +class SmellytoesNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return SmellytoesNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SMELLYTOES_6128) + } + + override fun handleTickActions() { + super.handleTickActions() + if (RandomFunction.roll(12)) { + sendChat(this, arrayOf( + "Doh ray meeee laa doh faaa!", + "La la la! Do di dum dii!", + ).random()) + } + } +} + +@Initializable +class CreakykneesNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return CreakykneesNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CREAKYKNEES_6129) + } + + override fun handleTickActions() { + super.handleTickActions() + if (RandomFunction.roll(12)) { + sendChat(this, arrayOf( + "Was that a spark?", + "Come on! Please light!", + ).random()) + } + } +} +@Initializable +class LostGoblinNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return LostGoblinNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GOBLIN_6125) + } + + override fun handleTickActions() { + super.handleTickActions() + if (RandomFunction.roll(12)) { + sendChat(this, arrayOf( + "Which way should I go?", + "These dungeons are such a maze.", + "Where's the exit?!?", + "This is the fifth time this week. I'm lost!", + "I've been wandering around down here for hours.", + "How do you get back to the village?", + "I hate being so lost!", + "How could I be so disoriented?", + "Where am I? I'm so lost.", + "I know the exit's around here, somewhere." + ).random()) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/GoblinGuardNPC.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/GoblinGuardNPC.kt new file mode 100644 index 000000000..963438628 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/GoblinGuardNPC.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.quest.observatoryquest + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class GoblinGuardNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GoblinGuardNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SLEEPING_GUARD_6122, NPCs.GOBLIN_GUARD_489) + } + + override fun finalizeDeath(entity: Entity) { + if (entity is Player) { + val player = entity.asPlayer() + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) >= 4) { + setAttribute(player, ObservatoryQuest.attributeKilledGuard, true) + } + super.finalizeDeath(player) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryAssistantDialogue.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryAssistantDialogue.kt new file mode 100644 index 000000000..5c7f1f7eb --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryAssistantDialogue.kt @@ -0,0 +1,238 @@ +package content.region.kandarin.quest.observatoryquest + +import content.data.Quests +import content.region.kandarin.quest.observatoryquest.ObservatoryQuest.Companion.attributeReceivedWine +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ObservatoryAssistantDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return ObservatoryAssistantDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ObservatoryAssistantDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.OBSERVATORY_ASSISTANT_6118, 10022) + } +} + +class ObservatoryAssistantDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.OBSERVATORY_ASSISTANT_6118) + + exec { player, npc -> + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 0) { + loadLabel(player, "observatoryQuest0") + } else if (getAttribute(player, attributeReceivedWine, false)) { + loadLabel(player, "receivedwine") + } else if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 100) { + loadLabel(player, "observatoryqueststage100") + } else { + loadLabel(player, "randomStart" + (1..4).random()) + } + } + + label("observatoryQuest0") + player(FacialExpression.ASKING, "Hi, are you busy?") + npc("Me? I'm always busy.") + npc("See that man there? That's the professor. If he had his way, I think he'd never let me sleep!") + npc("Anyway, how might I help you?") + options( + DialogueOption("wonderingwhat", "I was wondering what you do here."), + DialogueOption("justlooking", "Just looking around, thanks."), + DialogueOption("looktelescope", "Can I have a look through that telescope?", expression = FacialExpression.ASKING) + ) + + label("wonderingwhat") + npc("Glad you ask. This is the Observatory reception. Up on the cliff is the Observatory dome, from which you can view the heavens. Usually...") + player(FacialExpression.ASKING, "What do you mean, 'usually'?") + npc("*Ahem*. Back to work, please.") + npc("I'd speak with the professor. He'll explain.") + + label("justlooking") + npc("Okay, just don't break anything. If you need any help, let me know.") + line("The assistant continues with his work.") + + label("looktelescope") + npc("You can. You won't see much though.") + player(FacialExpression.ASKING, "And that's because?") + npc("Just talk to the professor. He'll fill you in.") + + label("randomStart1") + player(FacialExpression.ASKING, "Can I interrupt you?") + npc("I suppose so. Please be quick though.") + goto("afterRandomStart") + + label("randomStart2") + player(FacialExpression.ASKING, "Might I have a word?") + npc("Sure, how can I help you?") + goto("afterRandomStart") + + label("randomStart3") + player("Hello there.") + npc("Yes?") + goto("afterRandomStart") + + label("randomStart4") + player(FacialExpression.ASKING, "Can I speak with you?") + npc("Why, of course. What is it?") + goto("afterRandomStart") + + + label("afterRandomStart") + exec { player, npc -> + loadLabel(player, "observatoryqueststage" + getQuestStage(player, Quests.OBSERVATORY_QUEST)) + } + + label("observatoryqueststage1") + exec { player, _ -> + if (inInventory(player, Items.PLANK_960, 3)) { + loadLabel(player, "enoughplanks") + } + else if (inInventory(player, Items.PLANK_960)) { + loadLabel(player, "someplanks") + } + else { + loadLabel(player, "notenoughplanks") + } + } + + label("notenoughplanks") + player(FacialExpression.ASKING,"Where can I find planks of wood? I need some for the telescope's base.") + npc("I understand planks can be found at Port Khazard, to the east of here. There are some at the Barbarian Outpost, too.") + npc("Failing that, you could always ask the Sawmill Operator. He's to the north-east of Varrock, by the Lumber Yard.") + + label("enoughplanks") + player("I've got some planks for the telescope's base.") + npc("Good work! The professor has been eagerly awaiting them.") + + label("someplanks") + player("I've got a plank.") + npc("That's nice.") + player("You know, for the telescope's base.") + npc("Well done. Remember that you'll need three in total.") + + label("observatoryqueststage2") + exec { player, _ -> + if(inInventory(player, Items.BRONZE_BAR_2349)) { + loadLabel(player, "hasbronzebar") + } else { + loadLabel(player, "nohasbronzebar") + } + } + + label("nohasbronzebar") + player(FacialExpression.ASKING, "Can you help me? How do I go about getting a bronze bar?") + npc("You'll need to use tin and copper ore on a furnace to produce this metal.") + player("Right you are.") + + label("hasbronzebar") + player("The bronze bar is ready, and waiting for the professor.") + npc("He'll surely be pleased. Go ahead and give it to him.") + + label("observatoryqueststage3") + exec { player, _ -> + if(inInventory(player, Items.MOLTEN_GLASS_1775)) { + loadLabel(player, "hasmoltenglass") + } else { + loadLabel(player, "nohasmoltenglass") + } + } + + label("nohasmoltenglass") + player(FacialExpression.ASKING, "What's the best way for me to get molten glass?") + npc("There are many ways, but I'd suggest making it yourself. Get yourself a bucket of sand and some soda ash, which you can get from using seaweed with a furnace. Use the soda ash and sand together in a") + npc("furnace and bang - molten glass is all yours. There's a book about it on the table if you want to know more.") + player("Thank you!") + + label("hasmoltenglass") + player("I've managed to get hold of some molten glass.") + npc("I suggest you have a word with the professor, in that case.") + + label("observatoryqueststage4") + exec { player, _ -> + if(inInventory(player, Items.LENS_MOULD_602)) { + loadLabel(player, "haslensmould") + } else { + loadLabel(player, "nohaslensmould") + } + } + + label("nohaslensmould") + player(FacialExpression.ASKING, "Where can I find this lens mould you mentioned?") + npc("I'm sure I heard one of those goblins talking about it. I bet they've hidden it somewhere. Probably using it for some strange purpose, I'm sure.") + player(FacialExpression.ASKING, "What makes you say that?") + npc("I had a nice new star chart, until recently. I went out to do an errand for the professor the other day, only to see a goblin using it...") + npc("...as some kind of makeshift hankey to blow his nose!") + player("Oh dear.") + npc("You may want to look through the dungeon they have under their little village.") + player("Thanks for the advice.") + + label("haslensmould") + player("I have the lens mould.") + npc("Well done on finding that! I am honestly quite impressed. Make sure you take it straight to the professor.") + player("Will do.") + + label("observatoryqueststage5") + exec { player, _ -> + if(inInventory(player, Items.OBSERVATORY_LENS_603)) { + loadLabel(player, "haslens") + } else { + loadLabel(player, "nohaslens") + } + } + + label("nohaslens") + player(FacialExpression.ASKING, "How should I make this lens?") + npc("Just use the molten glass with the mould. Simple.") + player("Thanks!") + + label("haslens") + player("Do you like this lens? Good, huh?") + npc("Nice. What's that scratch?") + player("Oh, erm, that's a feature.") + player("Yes, that's it! Indubitably, it facilitates the triangulation of photonic illumination to the correct...") + npc("Stop! You can't confuse me with big words. Just pray the professor doesn't notice.") + + label("observatoryqueststage6") + player("Hello again.") + npc("Ah, it's the telescope repairman! The professor is waiting for you in the Observatory.") + player("How can I get to the Observatory?") + npc("Well, since the bridge was ruined, you will have to travel through the dungeon under the goblins' settlement.") + + label("observatoryqueststage100") + player("Hi assistant.") + player("Wait a minute.") + player(FacialExpression.ASKING, "What's your real name?") + npc(FacialExpression.ASKING, "My real name?") + player(FacialExpression.ASKING, "I only know you as the professor's assistant. What's your actual name?") + npc("Patrick.") + player("Hi Patrick, I'm @name.") + npc("Well, hello again, and thanks for helping out the professor.") + npc(" Oh, and, believe it or not, his name is Mambo-duna-roona, but don't tell him I told you.") + player(FacialExpression.AMAZED, "You made that up!") + npc("No, honest! Anyways, you've made my life much easier. Have a drink on me!") + item(Item(Items.JUG_OF_WINE_1993), "The assistant gives you some wine.") + exec { player, _ -> + addItemOrDrop(player, Items.JUG_OF_WINE_1993) + setAttribute(player, attributeReceivedWine, true) + } + player("Thanks very much.") + npc("No problem. Scorpius would be proud.") + player(FacialExpression.ASKING, "Sorry?") + npc("You may want to check out that book on the table, and perhaps look around for a grave...") + + label("receivedwine") + npc(FacialExpression.ASKING, "How was the wine?") + player(FacialExpression.DRUNK, "That was good stuff, *hic*! Wheresh the professher?") + npc(FacialExpression.ASKING, "The professor? He's up in the Observatory. Since the bridge was ruined, you will have to travel through the dungeon under the goblins' settlement.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryCutscene.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryCutscene.kt new file mode 100644 index 000000000..0eae2b1ab --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryCutscene.kt @@ -0,0 +1,199 @@ +package content.region.kandarin.quest.observatoryquest + +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import org.rs09.consts.Animations +import org.rs09.consts.NPCs +import content.region.kandarin.quest.observatoryquest.ObservatoryQuest.Companion.attributeFinishedCutscene +import core.game.world.map.Location + +class ObservatoryCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(Location(2438, 3163)) + loadRegion(9777) + addNPC(PROFESSOR, 7, 25, Direction.SOUTH) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(5) + } + 1 -> { + teleport(player, 6, 27) + face(player, getNPC(PROFESSOR)!!.location) + rotateCamera(9, 25, 300) + moveCamera(25, 22, 1800) + timedUpdate(5) + } + 2 -> { + fadeFromBlack() + dialogueLinesUpdate("~ The Observatory ~", "The great eye into the heavens.") + } + 3 -> { + moveCamera(14, 10, 1800, 10) + timedUpdate(3) + } + 4 -> { + moveCamera(6, 10, 1800, 10) + timedUpdate(3) + } + 5 -> { + moveCamera(0, 32, 1800, 10) + timedUpdate(3) + } + 6 -> { + moveCamera(4, 36, 1600, 10) + timedUpdate(3) + } + 7 -> { + rotateCamera(7, 25, 300, 5) + moveCamera(13, 40, 1800, 10) + timedUpdate(3) + } + 8 -> { + moveCamera(12, 36, 1800, 5) + timedUpdate(5) + } + 9 -> { + fadeToBlack() + timedUpdate(5) + } + 10 -> { + moveCamera(5, 21, 500) + rotateCamera(6, 27, 100) + timedUpdate(3) + } + 11 -> { + fadeFromBlack() + timedUpdate(5) + } + 12 -> { + playerDialogueUpdate(FacialExpression.NEUTRAL, "Hi professor!") + } + 13 -> { + face(getNPC(PROFESSOR)!!, player.location) + timedUpdate(3) + } + 14 -> { + animate(getNPC(PROFESSOR)!!, WAVE) + dialogueUpdate(PROFESSOR, FacialExpression.HAPPY, "Oh, hi there.") + } + 15 -> { + dialogueUpdate(PROFESSOR, FacialExpression.HAPPY, "I'm just adding the finishing touches.") + } + 16 -> { + playerDialogueUpdate(FacialExpression.HAPPY, "Okay, don't let me interrupt.") + } + 17 -> { + dialogueUpdate(PROFESSOR, FacialExpression.NEUTRAL, "Thank you.") + } + 18 -> { + face(getNPC(PROFESSOR)!!, Location(136, 25)) + dialogueUpdate(PROFESSOR, FacialExpression.NEUTRAL, "Right, let's get this finished.") + } + 19 -> { + animate(getNPC(PROFESSOR)!!, THINKING) + sendChat(getNPC(PROFESSOR)!!, "Hmmmm...") + timedUpdate(5) + } + 20 -> { + move(getNPC(PROFESSOR)!!, 7, 23) + rotateCamera(9, 23, 100) + moveCamera(12, 30, 300) + timedUpdate(3) + } + 21 -> { + move(getNPC(PROFESSOR)!!, 10, 26) + timedUpdate(10) + } + 22 -> { + face(getNPC(PROFESSOR)!!, Location(135, 25)) + animate(getNPC(PROFESSOR)!!, FIX) + sendChat(getNPC(PROFESSOR)!!, "Bit of a tap here...") + timedUpdate(3) + } + 23 -> { + move(getNPC(PROFESSOR)!!, 11, 26) + timedUpdate(5) + } + 24 -> { + face(getNPC(PROFESSOR)!!, player.location) + dialogueUpdate(PROFESSOR, FacialExpression.HAPPY, "@name, I'm just going upstairs to finish off.") + } + 25 -> { + playerDialogueUpdate(FacialExpression.HAPPY, "Right-oh.") + } + 26 -> { + face(getNPC(PROFESSOR)!!, Location(140, 25)) + timedUpdate(3) + } + 27 -> { + teleport(getNPC(PROFESSOR)!!, 11, 22, 1) + teleport(player, 14,29,1) + face(getNPC(PROFESSOR)!!, Location(2442, 3158, 1)) + moveCamera(6, 20, 400) + rotateCamera(10, 24, 400) + timedUpdate(5) + } + 28 -> { + move(getNPC(PROFESSOR)!!, 7, 27) + moveCamera(10, 20, 400, 1) + rotateCamera(7, 27, 50, 20) + timedUpdate(10) + } + 29 -> { + sendChat(getNPC(PROFESSOR)!!, "In goes the lens.") + timedUpdate(3) + } + 30 -> { + animate(getNPC(PROFESSOR)!!, TUNEUP) + timedUpdate(20) + } + 31 -> { + sendChat(getNPC(PROFESSOR)!!, "And one final adjustment.") + move(getNPC(PROFESSOR)!!, 10, 29) + timedUpdate(6) + } + 32 -> { + move(getNPC(PROFESSOR)!!, 10, 25) + face(getNPC(PROFESSOR)!!, Location(137, 26)) + timedUpdate(6) + } + 33 -> { + face(getNPC(PROFESSOR)!!, Location(137, 26)) + animate(getNPC(PROFESSOR)!!, CRANK) + sendChat(getNPC(PROFESSOR)!!, "And all our work pays off.") + timedUpdate(6) + } + 34 -> { + animate(getNPC(PROFESSOR)!!, CHEER) + timedUpdate(10) + } + 35 -> { + moveCamera(6, 27, 500, 5) + rotateCamera(10, 25, 50, 5) + timedUpdate(3) + } + 36 -> { + end { + setAttribute(player, attributeFinishedCutscene, true) + } + } + } + } + + companion object { + val PROFESSOR = NPCs.OBSERVATORY_PROFESSOR_6121 + val WAVE = Animations.HUMAN_WAVE_863 + val THINKING = 6844 + val FIX = 6847 + val TUNEUP = 6848 + val CRANK = 6845 + val CHEER = Animations.HUMAN_CHEER_862 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryProfessorDialogue.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryProfessorDialogue.kt new file mode 100644 index 000000000..380334049 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryProfessorDialogue.kt @@ -0,0 +1,676 @@ +package content.region.kandarin.quest.observatoryquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import content.region.kandarin.quest.observatoryquest.ObservatoryQuest.Companion.attributeReceivedWine +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ObservatoryProfessorDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return ObservatoryProfessorDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ObservatoryProfessorDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.OBSERVATORY_ASSISTANT_6119, NPCs.OBSERVATORY_ASSISTANT_6120) + } +} + +class ObservatoryProfessorDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.OBSERVATORY_PROFESSOR_488) + + npc("What would you like to talk about?") + options( + DialogueOption("observatoryquest", "Talk about the Observatory Quest.", skipPlayer = true), + DialogueOption("treasuretrails", "Talk about the Treasure Trails.", skipPlayer = true), + ) + + label("observatoryquest") + exec { player, npc -> + loadLabel(player, "observatoryqueststage" + getQuestStage(player, Quests.OBSERVATORY_QUEST)) + } + + label("observatoryqueststage0") + player("Hi, I was...") + npc(FacialExpression.FRIENDLY, "Welcome to the magnificent wonder of the Observatory, where wonder is all around you, where the stars can be clutched from the heavens!") + player("Wow, nice intro.") + npc(FacialExpression.FRIENDLY, "Why, thanks! How might I help you?") + options( + DialogueOption("totallylost", "I'm totally lost."), + DialogueOption("whatwhat", "An Observatory?", expression = FacialExpression.THINKING), + DialogueOption("nah", "I'm just passing through."), + ) + + label("totallylost") + npc(FacialExpression.THINKING, "Lost? It must have been those pesky goblins that led you astray.") + npc("Head north-east to find the city of Ardougne.") + player("I'm sure I'll find the way.") + player("Thanks for all your help.") + npc(FacialExpression.FRIENDLY, "No problem at all. Come and visit again!") + line("The professor carries on with his studies.") + + label("nah") + npc("Fair enough. Not everyone is interested in this place, I suppose.") + + label("whatwhat") + npc(FacialExpression.FRIENDLY, "Of course. We have a superb telescope up in the Observatory, on the hill.") + npc(FacialExpression.FRIENDLY, "A truly marvellous invention, the likes of which you'll never behold again.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Well, it would be if it worked.") + npc(FacialExpression.ANGRY, "Don't interrupt!") + player(FacialExpression.THINKING, "What? It doesn't work?") + npc("Oh, no, no, no. Don't listen to him, he's joking. Aren't you, my FAITHFUL assistant?") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Nope, dead serious. Hasn't been working for a long time.") + npc(FacialExpression.ANGRY, "Arghhh! Get back to work and stop sticking your nose in!") + player("So, it's broken. How come?") + npc(FacialExpression.SAD, "Oh, I suppose there's no use keeping it secret. Did you see those houses outside?") + player("Up on the hill? Yes, I've seen them.") + npc("It's a horde of goblins.") + npc(FacialExpression.SAD, "Since they moved here they have caused nothing but trouble.") + npc("Last week, my telescope was tampered with.") + npc(FacialExpression.ANGRY, "Now, parts need replacing before it can be used again. They've even been messing around in the dungeons under this area. Something needs to be done.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Strikes me that this visitor could help us.") + npc(FacialExpression.ANGRY, "Stop being so rude.") + npc("...") + npc("Although, he has a point. What do you say?") + player(FacialExpression.THINKING, "What, me?") + options( + DialogueOption("yestoquest", "Sounds interesting. How can I help?", "Sounds interesting, what can I do for you?", FacialExpression.FRIENDLY), + DialogueOption("notoquest", "Oh, sorry, I don't have time for that."), + ) + + label("notoquest") + npc("Oh dear. I really do need some help.") + npc("If you see anyone who can help then please send them my way.") + + label("yestoquest") + exec { player, _ -> + if(getQuestStage(player, Quests.OBSERVATORY_QUEST) == 0) { + setQuestStage(player, Quests.OBSERVATORY_QUEST, 1) + } + } + npc(FacialExpression.FRIENDLY, "Oh, thanks so much.") + npc(FacialExpression.FRIENDLY, "I shall need some materials for the telescope, so it can be used again.") + npc("Let's start with three planks of wood for the telescope base. My assistant will help with obtaining these, won't you?") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "As if I don't have enough work to do. Seems I don't have a choice.") + npc(FacialExpression.FRIENDLY, "Go talk to him if you need some advice.") + player(FacialExpression.FRIENDLY, "Okay, I'll be right back.") + + label("observatoryqueststage1") + player(FacialExpression.FRIENDLY, "Hi again!") + npc(FacialExpression.FRIENDLY, "It's my helping hand, back again.") + npc(FacialExpression.THINKING, "Do you have the planks yet?") + exec { player, _ -> + if(inInventory(player, Items.PLANK_960, 3)) { + loadLabel(player, "enoughplanks") + } else { + loadLabel(player, "notenoughplanks") + } + } + + label("notenoughplanks") + player("Sorry, not yet. Three planks was it?") + npc("It was indeed.") + + label("enoughplanks") + player("Yes, I've got them. Here they are.") + exec { player, _ -> + if(removeItem(player, Item(Items.PLANK_960, 3))) { + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 1) { + setQuestStage(player, Quests.OBSERVATORY_QUEST, 2) + } + } + } + npc(FacialExpression.FRIENDLY, "Well done. This will make a big difference.") + npc(FacialExpression.FRIENDLY, "Now, the bronze for the tube. Oh, assistant!") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Okay, okay, ask me if you need any help, @name.") + + label("observatoryqueststage2") + player("Hi.") + npc("The traveller returns!") + player("Still working hard?") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Some of us are.") + npc(FacialExpression.ANGRY, "What did I tell you about speaking when spoken to?") + npc(FacialExpression.THINKING, "So, @name, you have the bronze bar?") + exec { player, _ -> + if(inInventory(player, Items.BRONZE_BAR_2349)) { + loadLabel(player, "hasbronzebar") + } else { + loadLabel(player, "nohasbronzebar") + } + } + + label("nohasbronzebar") + player("Not yet.") + npc("Please bring me one, then.") + + label("hasbronzebar") + player(FacialExpression.FRIENDLY, "I certainly do. Here you go.") + exec { player, _ -> + if(removeItem(player, Item(Items.BRONZE_BAR_2349))) { + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 2) { + setQuestStage(player, Quests.OBSERVATORY_QUEST, 3) + } + } + } + npc(FacialExpression.FRIENDLY, "Great. Now all I need is the lens made.") + npc(FacialExpression.FRIENDLY, "Please get me some molten glass.") + npc("Oi! Lazy bones!") + player(FacialExpression.AMAZED, "What? I'm not lazy.") + npc("Not you! I'm talking to my assistant.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Calm down old man, I heard. @name, I'm here if you need any help.") + npc("Thank you. Wait a minute, who are you calling 'old'?") + + label("observatoryqueststage3") + npc("How are you getting on finding me some molten glass?") + exec { player, _ -> + if(inInventory(player, Items.MOLTEN_GLASS_1775)) { + loadLabel(player, "hasmoltenglass") + } else { + loadLabel(player, "nohasmoltenglass") + } + } + + label("nohasmoltenglass") + player("Still working on it.") + npc("I really need it. Please hurry.") + + label("hasmoltenglass") + player(FacialExpression.FRIENDLY, "Here it is.") + exec { player, _ -> + if(removeItem(player, Item(Items.MOLTEN_GLASS_1775))) { + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 3) { + setQuestStage(player, Quests.OBSERVATORY_QUEST, 4) + } + } + } + npc(FacialExpression.FRIENDLY, "Excellent work, let's make the lens.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "It'll need to be made to an exact shape and size.") + npc("Well, obviously, hence why we have a lens mould.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Not any more. One of those goblins took it.") + npc(FacialExpression.SAD, "Great, just what I need. @name, I don't suppose you could find it?") + player(FacialExpression.FRIENDLY, "I'll have a look - where should I start?") + npc(FacialExpression.FRIENDLY, "No idea. You could ask my USELESS assistant if you want.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "What have I done to deserve this?") + + label("observatoryqueststage4") + npc(FacialExpression.THINKING, "Did you bring me the mould?") + exec { player, _ -> + if(inInventory(player, Items.LENS_MOULD_602)) { + loadLabel(player, "haslensmould") + } else { + loadLabel(player, "nohaslensmould") + } + } + + label("nohaslensmould") + player("Still looking for it.") + npc("Please try and find it; my assistant may be able to help.") + + label("haslensmould") + player(FacialExpression.HAPPY, "I certainly have. You'll never guess what they were doing with it.") + npc("Well, from the smell I'd guess cooking some vile concoction.") + player(FacialExpression.HAPPY, "Wow, good guess. Well, here you go.") + npc(FacialExpression.NEUTRAL, NPCs.OBSERVATORY_ASSISTANT_6118, "Please don't give that to him. Last time he tried any Crafting, I had to spend a week cleaning up after the explosion.") + player("Explosion?") + npc(FacialExpression.SUSPICIOUS, "Erm, yes. I think in this instance you had probably better do it.") + player("I suppose it's better I don't ask.") + npc(FacialExpression.HAPPY,"You can use the mould with molten glass to make a new lens.") + exec { player, _ -> + if(inInventory(player, Items.LENS_MOULD_602)) { + addItemOrDrop(player, Items.MOLTEN_GLASS_1775) + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 4) { + setQuestStage(player, Quests.OBSERVATORY_QUEST, 5) + } + } + } + item(Item(Items.MOLTEN_GLASS_1775), "The professor gives you back the molten glass.") + + + label("observatoryqueststage5") + npc("Is the lens finished?") + exec { player, _ -> + if(inInventory(player, Items.OBSERVATORY_LENS_603)) { + loadLabel(player, "haslens") + } else { + loadLabel(player, "nohaslens") + } + } + + label("nohaslens") + player("How do I make it again?") + npc("Use the molten glass with the mould.") + player("Huh. Simple.") + + label("haslens") + player("Yes, here it is. You may as well take this mould too.") //No source if no mould present + line("The player hands the observatory professor the observatory lens.") + npc("Wonderful, at last I can fix the telescope.") + npc("Would you accompany me to the Observatory? You simply must see the telescope in operation.") + player("Sounds interesting. Count me in.") + npc("Superb. You'll have to go via the dungeon under the goblin settlement, seeing as the bridge is broken. You'll find stairs up to the Observatory from there.") + player("Okay. See you there.") + exec { player, _ -> + setVarbit(player, ObservatoryQuest.telescopeVarbit, 1, true) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + openOverlay(player, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player, 4) + } + 1 -> { + if(removeItem(player, Item(Items.OBSERVATORY_LENS_603))) { + removeItem(player, Item(Items.LENS_MOULD_602)) + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 5) { + setQuestStage(player, Quests.OBSERVATORY_QUEST, 6) + } + } + return@queueScript delayScript(player, 1) + } + 2 -> { + openOverlay(player, Components.FADE_FROM_BLACK_170) + return@queueScript delayScript(player, 2) + } + 3 -> { + sendDialogueLines(player, "The professor has gone ahead to the Observatory dome. Best you", "follow him to see the finished telescope.") + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + + + } + + label("observatoryqueststage6") + npc("Hello, friend.") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) != null) { + loadLabel(player, "hasviewtelescope") + } else { + loadLabel(player, "nohasviewtelescope") + } + } + label("nohasviewtelescope") + // http://youtu.be/cK5suqcw3qU + player("Hi, this really is impressive.") + npc("Certainly is. Please, take a look through the telescope and tell me what you see.") + + label("hasviewtelescope") + player("I've had a look through the telescope.") + npc("What did you see? If you're not sure, you can find out by looking at the star charts dotted around the walls downstairs.") + player("It was...") + goto("page1") + + + label("page1") + options( + DialogueOption("Aquarius", "Aquarius", skipPlayer = true), + DialogueOption("Capricorn", "Capricorn", skipPlayer = true), + DialogueOption("Sagittarius", "Sagittarius", skipPlayer = true), + DialogueOption("Scorpio", "Scorpio", skipPlayer = true), + DialogueOption("page2", "~ next ~", skipPlayer = true), + ) + + label("page2") + options( + DialogueOption("page1", "~ previous ~", skipPlayer = true), + DialogueOption("Libra", "Libra", skipPlayer = true), + DialogueOption("Virgo", "Virgo", skipPlayer = true), + DialogueOption("Leo", "Leo", skipPlayer = true), + DialogueOption("page3", "~ next ~", skipPlayer = true), + ) + + label("page3") + options( + DialogueOption("page2", "~ previous ~", skipPlayer = true), + DialogueOption("Cancer", "Cancer", skipPlayer = true), + DialogueOption("Gemini", "Gemini", skipPlayer = true), + DialogueOption("Taurus", "Taurus", skipPlayer = true), + DialogueOption("page4", "~ next ~", skipPlayer = true), + ) + + label("page4") + options( + DialogueOption("page3", "~ previous ~", skipPlayer = true), + DialogueOption("Aries", "Aries", skipPlayer = true), + DialogueOption("Pisces", "Pisces", skipPlayer = true), + ) + + label("Aquarius") + player("Aquarius!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 19) { + loadLabel(player, "Aquariuscorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Aquariuscorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Aquarius, the water-bearer.") + npc("It seems suitable, then, to award you with water runes!") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.WATER_RUNE_555, 25) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Aries") + player("Aries!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 20) { + loadLabel(player, "Ariescorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Ariescorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Aries, the ram.") + npc("A fierce fighter. I'm sure he'll look down on you and improve your Attack for such insight.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + rewardXP(player, Skills.ATTACK, 875.0) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Cancer") + player("Cancer!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 21) { + loadLabel(player, "Cancercorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Cancercorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Cancer, the crab.") + npc("An armoured creature - I think I shall reward you with an amulet of protection.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.AMULET_OF_DEFENCE_1729) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Capricorn") + player("Capricorn!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 22) { + loadLabel(player, "Capricorncorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Capricorncorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Capricorn, the goat.") + npc("Capricorn will surely reward your insight with an increase to your Strength.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + rewardXP(player, Skills.STRENGTH, 875.0) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Gemini") + player("Gemini!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 23) { + loadLabel(player, "Geminicorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Geminicorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Gemini, the twins.") + npc("With the double nature of Gemini, I can't offer you anything more suitable than a two-handed weapon.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.BLACK_2H_SWORD_1313) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Leo") + player("Leo!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 24) { + loadLabel(player, "Leocorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Leocorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Leo, the lion.") + npc("I think the majestic power of the lion will raise your Hitpoints.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + rewardXP(player, Skills.HITPOINTS, 875.0) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Libra") + player("Libra!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 25) { + loadLabel(player, "Libracorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Libracorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Libra, the scales.") + npc("Hmmm, balance, law, order - I shall award you with law runes!") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.LAW_RUNE_563, 25) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Pisces") + player("Pisces!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 26) { + loadLabel(player, "Piscescorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Piscescorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Pisces, the fish.") + npc("What's more suitable as a reward than some tuna?") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.TUNA_361, 3) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Sagittarius") + player("Sagittarius!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 27) { + loadLabel(player, "Sagittariuscorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Sagittariuscorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Sagittarius, the centaur.") + npc("As you've spotted the archer, I shall reward you with a maple longbow.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.MAPLE_LONGBOW_851) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Scorpio") + player("Scorpio!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 28) { + loadLabel(player, "Scorpiocorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Scorpiocorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Scorpio, the scorpion.") + npc("I think weapon poison would make a suitable reward.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.WEAPON_POISON_187) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Taurus") + player("Taurus!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 29) { + loadLabel(player, "Tauruscorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Tauruscorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Taurus, the bull.") + npc("This Strength potion should be a suitable reward.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + addItemOrDrop(player, Items.SUPER_STRENGTH1_161) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("Virgo") + player("Virgo!") + exec { player, _ -> + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == 30) { + loadLabel(player, "Virgocorrect") + } else { + loadLabel(player, "wrongstar") + } + } + + label("Virgocorrect") + npc("That's exactly it!") + player("Yes! Woo hoo!") + npc("That's Virgo, the virtuous.") + npc("Virgo will surely provide you with an increase to Defence.") + // Usually it is given here, but I don't want loopholes. + npc("By Saradomin's earlobes! You must be a friend of the gods indeed.") + npc("Look in your backpack for your reward, in payment for your work.") + exec { player, _ -> + rewardXP(player, Skills.DEFENCE, 875.0) + addItemOrDrop(player, Items.UNCUT_SAPPHIRE_1623) + finishQuest(player, Quests.OBSERVATORY_QUEST) + } + + label("wrongstar") + npc("I'm afraid not. Have another look. Remember, you can check the star charts on the walls for reference.") + + // http://youtu.be/Z5RRnZl2vTg + label("observatoryqueststage100") + npc("Thanks for all your help with the telescope. What can I do for you?") + options( + DialogueOption("needmorehelp", "Do you need any more help with the telescope?", expression = FacialExpression.ASKING), + DialogueOption("mambodunaroona", "Is it true your name is Mambo-duna-roona?", expression = FacialExpression.ASKING) { player, _ -> + return@DialogueOption getAttribute(player, attributeReceivedWine, false) + }, + DialogueOption("nevermind", "Nothing, thanks."), + ) + + label("needmorehelp") + npc("Not right now,") + npc("but the stars may hold a secret for you.") + + label("nevermind") + npc("Okay, no problem. See you again.") + + label("treasuretrails") + npc("Welcome back! How can I help you today?") + player("Can you teach me to solve treasure trail clues?") + npc("Ah, I get asked about treasure trails all the time! Listen carefully and I shall tell you what I know...") + npc("Lots of clues have degrees and minutes written on them. These are the coordinates of the place where the treasure is buried.") + npc("You have to walk to the correct spot, so that your coordinates are exactly the same as the values written on the clue scroll.") + npc("To do this, you must use a sextant, a watch and a chart to find your own coordinates.") + npc("Once you know the coordinates of the place where you are, you know which way you have to walk to get to the place where the treasure is!") + player("Riiight. So where do I get those items from?") + npc("I think Murphy, the owner of the fishing trawler moored south of Ardougne, might be able to spare you a sextant. Then the nearest Clock Tower is south of Ardougne - you could probably get a watch there. I've") + npc("got plenty of charts myself, here have one.") + + label("mambodunaroona") + npc(FacialExpression.AMAZED, "How do you know tha-") + npc(FacialExpression.SUSPICIOUS, "I mean, of course not, what a silly idea.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuest.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuest.kt new file mode 100644 index 000000000..ce6ba2513 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuest.kt @@ -0,0 +1,159 @@ +package content.region.kandarin.quest.observatoryquest + +import content.data.Quests +import core.api.* +import core.api.setVarp +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +// http://youtu.be/TWIkCRRea8A The initial quest log. +// http://youtu.be/onHNm9Z5L-o The best full quest log. +// http://youtu.be/cq-jGTXXHuE +// http://youtu.be/ekYr30h43ag Scorpius. +/** + * Observatory Quest + */ +@Initializable +class ObservatoryQuest : Quest(Quests.OBSERVATORY_QUEST, 96, 95, 2,112, 0, 1, 7) { + + companion object { + val questName = Quests.OBSERVATORY_QUEST + const val observatoryVarp = 112 + const val goblinStoveVarbit = 3837 + const val telescopeVarbit = 3838 + + const val starChartsInterface = 104 + const val telescopeInterface = 552 + const val dungeonWarning = 560 + + const val attributeKilledGuard = "/save:quest:observatoryquest-killedguard" + const val attributeUnlockedGate = "/save:quest:observatoryquest-unlockedgate" + const val attributeTelescopeStar = "/save:quest:observatoryquest-telescopestar" // NULL - not seen telescope, 19 - 30 one of the random star patterns + const val attributeReceivedWine = "/save:quest:observatoryquest-receivedwine" + const val attributeReceivedMould = "/save:quest:observatoryquest-receivedmould" + const val attributeRandomChest = "/save:quest:observatoryquest-randomchest" + const val attributeFinishedCutscene = "/save:quest:observatoryquest-finishedcutscene" + + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, questName) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to the !!professor?? in the", line++, false) + line(player, "!!Observatory reception, south-west of Ardougne.??", line++, false) + } else { + line(player, "I can start this quest by speaking to the professor in the", line++, true) + line(player, "Observatory reception, south-west of Ardougne.", line++, true) + + if (stage >= 5) { + line(player, "I should take the letter the Examiner has given me to the", line++, true) + line(player, "Curator of Varrock Museum, for his approval.", line++, true) + line++ + } else if (stage >= 1) { + line(player, "Seems the observatory telescope needs repairing, due to", line++) + line(player, "the nearby goblins. The !!professor?? wants me to help by", line++) + line(player, "getting the following, with the help of his !!assistant??:", line++) + line++ + } + if (stage >= 2) { + line(player, "!!3 plain wooden planks??", line++, true) + } else if (stage >= 1) { + line(player, "!!3 plain wooden planks??", line++, inInventory(player, Items.PLANK_960, 3)) + } + if (stage >= 3) { + line(player, "!!1 bronze bar??", line++, true) + } else if (stage >= 2) { + line(player, "!!1 bronze bar??", line++, inInventory(player, Items.BRONZE_BAR_2349)) + } + if (stage >= 4) { + line(player, "!!1 molten glass??", line++, true) + } else if (stage >= 3) { + line(player, "!!1 molten glass??", line++, inInventory(player, Items.MOLTEN_GLASS_1775)) + } + if (stage >= 5) { + line(player, "!!1 lens mould??", line++, true) + } else if (stage >= 4) { + line(player, "!!1 lens mould??", line++) + } + + if (stage >= 6) { + line(player, "The professor was pleased to have all the pieces needed", line++, true) + line(player, "to fix the telescope. Apparently, the professor's last", line++, true) + line(player, "attempt at Crafting ended in disaster. So, he wants me to", line++, true) + line(player, "create the lens by using the molten glass with the mould.", line++, true) + line(player, "Fine by me!", line++, true) + } else if (stage >= 5) { + line(player, "The !!professor?? was pleased to have all the pieces needed", line++) + line(player, "to fix the telescope. Apparently, the professor's last", line++) + line(player, "attempt at Crafting ended in disaster. So, he wants me to", line++) + line(player, "create the !!lens?? by using the !!molten glass?? with the !!mould??.", line++) + line(player, "Fine by me!", line++) + } + + if (stage >= 100) { + line(player, "The professor has gone ahead to the Observatory. He", line++, true) + line(player, "wants me to meet him there by travelling through the", line++, true) + line(player, "dungeon below it.", line++, true) + } else if (stage >= 6) { + line(player, "The !!professor?? has gone ahead to the !!Observatory??. He", line++) + line(player, "wants me to meet him there by travelling through the", line++) + line(player, "!!dungeon?? below it.", line++) + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Observatory Quest!", 277, 4) + // This image is special since it isn't an item, but a standalone model. + player.packetDispatch.sendModelOnInterface(1174, 277, 5, 0) // Scenery 2210, Model 1174 + player.packetDispatch.sendAngleOnInterface(277, 5, 2040, 0, 1836) + + drawReward(player, "2 Quest Points", ln++) + drawReward(player, "2,250 Crafting XP", ln++) + drawReward(player, "A payment depending on", ln++) + drawReward(player, "which constellation you", ln++) + drawReward(player, "observed", ln++) + + rewardXP(player, Skills.CRAFTING, 2250.0) + } + + override fun updateVarps(player: Player) { + setVarp(player, observatoryVarp, getQuestStage(player, questName), true) + if(getQuestStage(player, questName) >= 6) { + setVarbit(player, telescopeVarbit, 1, true) + } else { + setVarbit(player, telescopeVarbit, 0, true) + } + if(getQuestStage(player, questName) >= 7) { + setVarp(player, observatoryVarp, 7, true) + } + } + + override fun reset(player : Player) { + removeAttribute(player, attributeKilledGuard) + removeAttribute(player, attributeUnlockedGate) + removeAttribute(player, attributeTelescopeStar) + removeAttribute(player, attributeReceivedWine) + removeAttribute(player, attributeReceivedMould) + removeAttribute(player, attributeRandomChest) + removeAttribute(player, attributeFinishedCutscene) + setVarbit(player, 3837, 0, true) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuestInterfaces.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuestInterfaces.kt new file mode 100644 index 000000000..a6627b98a --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuestInterfaces.kt @@ -0,0 +1,59 @@ +package content.region.kandarin.quest.observatoryquest + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.world.map.Location + +class ObservatoryQuestInterfaces : InterfaceListener { + + companion object { + + val buttonToNameMapping = mapOf( + 19 to "Aquarius", + 20 to "Aries", + 21 to "Cancer", + 22 to "Capricorn", + 23 to "Gemini", + 24 to "Leo", + 25 to "Libra", + 26 to "Pisces", + 27 to "Sagittarius", + 28 to "Scorpio", + 29 to "Taurus", + 30 to "Virgo", + ) + + val buttonToStarObjectMapping = mapOf( + 19 to 27064, + 20 to 27066, + 21 to 27067, + 22 to 27061, + 23 to 27068, + 24 to 27058, + 25 to 27057, + 26 to 27062, + 27 to 27056, + 28 to 27055, + 29 to 27059, + 30 to 27060, + ) + } + + override fun defineInterfaceListeners() { + on(ObservatoryQuest.starChartsInterface) { player, component, opcode, buttonID, slot, itemID -> + if(buttonToStarObjectMapping.contains(buttonID)){ + // 55 57 + player.packetDispatch.sendModelOnInterface(buttonToStarObjectMapping[buttonID]!!, ObservatoryQuest.starChartsInterface, 55, 0) + setInterfaceText(player, buttonToNameMapping[buttonID]!!, ObservatoryQuest.starChartsInterface, 57) + } + return@on true + } + on(ObservatoryQuest.dungeonWarning) { player, _, _, buttonID, _, _ -> + when (buttonID) { + 17 -> teleport(player, Location(2355, 9394)).also { closeInterface(player) } + 18 -> closeInterface(player) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuestListeners.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuestListeners.kt new file mode 100644 index 000000000..c718f9a10 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/ObservatoryQuestListeners.kt @@ -0,0 +1,294 @@ +package content.region.kandarin.quest.observatoryquest + +import content.data.Quests +import content.region.kandarin.quest.observatoryquest.ObservatoryQuest.Companion.attributeFinishedCutscene +import content.region.kandarin.quest.observatoryquest.ObservatoryQuest.Companion.attributeRandomChest +import core.ServerConstants +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class ObservatoryQuestListeners : InteractionListener { + + companion object { + val chestMap = mapOf( + Scenery.CHEST_2191 to Scenery.CHEST_2194, + Scenery.CHEST_25385 to Scenery.CHEST_25386, + Scenery.CHEST_25387 to Scenery.CHEST_25388, + Scenery.CHEST_25389 to Scenery.CHEST_25390, + Scenery.CHEST_25391 to Scenery.CHEST_25392 + ) + + val reverseChestMap = chestMap.map { (k, v) -> v to k }.toMap() + + /* Comments show only the default order BEFORE randomization. A randomized + number (0-10) is calculated the first time the player goes down the stairs, + and is then added to the map value modulo 11, rotating the map. + */ + + val chestLocations = mapOf( + Location(2333, 9405) to 0, // key + Location(2312, 9400) to 1, // spider + Location(2310, 9374) to 2, // spider + Location(2348, 9383) to 3, // empty + Location(2356, 9380) to 4, // spider + Location(2359, 9376) to 5, // empty + Location(2360, 9366) to 6, // empty + Location(2351, 9361) to 7, // spider + Location(2364, 9355) to 8, // antipoison + Location(2335, 9374) to 9, // spider + Location(2326, 9360) to 10) // empty + } + + override fun defineListeners() { + + on(Scenery.SIGNPOST_25397, SCENERY, "read") { player, _ -> + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val servername = ServerConstants.SERVER_NAME + when(stage){ + 0 -> sendDialogueLines(player, "~ The Observatory ~", "Step ahead to the reception if you wish to explore $servername's most", "magnificent invention.").also { + stage++ + } + 1 -> player(FacialExpression.NEUTRAL, "Magnificent invention? I've seen some pretty magnificent", "things in my time. It'll have to be pretty impressive.").also { stage = END_DIALOGUE } + } + } + }) + return@on true + } + + on(Scenery.ORRERY_25401, SCENERY, "view") { player, _ -> + sendChat(player, "Oooooh, bizarre!") + return@on true + } + + on(Scenery.STAIRS_25432, SCENERY, "climb-down") { player, _ -> + openInterface(player, 560) + if (getAttribute(player, attributeRandomChest, null) == null) { + setAttribute(player, attributeRandomChest, RandomFunction.random(11)) + } + return@on true + } + // http://youtu.be/Kg84MYXgo-M -> You can always go to the observatory, no matter which stage. + on(Scenery.STAIRS_25429, SCENERY, "climb up") { player, node -> + if (node.location == Location(2335, 9351)) { + if (!getAttribute(player, attributeFinishedCutscene, false) && getQuestStage(player, Quests.OBSERVATORY_QUEST) == 6) { + ObservatoryCutscene(player).start() + } + else teleport(player, Location(2439, 3164)) + } else { + teleport(player, Location(2457, 3186)) + } + return@on true + } + + on(Scenery.STAIRS_25434, SCENERY, "climb-down") { player, _ -> + teleport(player, Location(2335, 9350)) + return@on true + } + + on(Scenery.STAIRS_25431, SCENERY, "climb-up") { player, _ -> + teleport(player, Location(2443, 3160, 1)) + return@on true + } + + on(Scenery.STAIRS_25437, SCENERY, "climb-down") { player, _ -> + teleport(player, Location(2444, 3162, 0)) + return@on true + } + + // All chests + on(chestMap.keys.toIntArray(), SCENERY, "open") { player, node -> + animate(player, 536) + sendMessage(player, "You open the chest.") + chestMap[node.id]?.let { replaceScenery(node as core.game.node.scenery.Scenery, it, 240) } + return@on true + } + on(chestMap.values.toIntArray(), SCENERY, "close") { player, node -> + animate(player, 535) + reverseChestMap[node.id]?.let { replaceScenery(node as core.game.node.scenery.Scenery, it, -1) } + return@on true + } + + on(chestMap.values.toIntArray(), SCENERY, "search") { player, node -> + val chest = chestLocations[node.location]?.plus(getAttribute(player, attributeRandomChest, 0))?.mod(11) + when (chest) { + 0 -> { + if (inInventory(player, Items.GOBLIN_KITCHEN_KEY_601) || getQuestStage(player, Quests.OBSERVATORY_QUEST) != 4 || getAttribute(player, ObservatoryQuest.attributeUnlockedGate, false)) { + sendMessage(player, "You search the chest.") + sendMessage(player, "The chest is empty.") + } else { + lock(player,2) + queueScript(player, 2, QueueStrength.STRONG) { + if (inInventory(player, Items.GOBLIN_KITCHEN_KEY_601)) { + return@queueScript stopExecuting(player) + } + addItemOrDrop(player, Items.GOBLIN_KITCHEN_KEY_601) + sendItemDialogue(player, Items.GOBLIN_KITCHEN_KEY_601,"You find a kitchen key.") + return@queueScript stopExecuting(player) + } + } + animate(player, 537) + return@on true + } + 1, 2, 4, 7, 9 -> { + sendMessage(player, "You search the chest.") + if (findLocalNPC(player, NPCs.POISON_SPIDER_1009) != null) { + sendMessage(player, "The chest is empty.") + animate(player, 537) + return@on true + } + sendMessage(player, "The chest contains a poisonous spider.") + val npc = NPC(NPCs.POISON_SPIDER_1009) + npc.location = player.location + npc.init() + npc.isRespawn = false + npc.moveStep() + npc.face(player) + animate(player, 537) + return@on true + } + 8 -> { + sendMessage(player, "You search the chest.") + lock(player,2) + queueScript(player, 2, QueueStrength.STRONG) { + addItemOrDrop(player, Items.ANTIPOISON1_179) + sendMessage(player,"This chest contains some antipoison.") + return@queueScript stopExecuting(player) + } + animate(player, 537) + return@on true + } + else -> { + sendMessage(player, "You search the chest.") + sendMessage(player, "The chest is empty.") + animate(player, 537) + return@on true + } + } + } + + on(intArrayOf(Scenery.KITCHEN_GATE_2199, Scenery.KITCHEN_GATE_2200), SCENERY, "open") { player, node -> + if (getAttribute(player, ObservatoryQuest.attributeUnlockedGate, false)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (getAttribute(player, ObservatoryQuest.attributeKilledGuard, false)) { + if (removeItem(player, Items.GOBLIN_KITCHEN_KEY_601)) { + sendMessage(player, "The gate unlocks.") + sendMessage(player, "The key is useless now. You discard it.") + setAttribute(player, ObservatoryQuest.attributeUnlockedGate, true) + sendPlayerDialogue(player, "I had better be quick, there may be more guards about.") + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + // http://youtu.be/ZkUF-0eonls + sendMessage(player, "The gate is locked.") + } + } else if (getQuestStage(player, Quests.OBSERVATORY_QUEST) >= 4){ + sendMessage(player, "If you open the gate, the guard will hear you. You need to get rid of him.") + } else sendMessage(player, "The gate is locked.") + return@on true + } + + on(NPCs.SLEEPING_GUARD_6122, NPC, "prod") { player, node -> + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) < 4) { + return@on true + } + sendChat(node as NPC, "Oi, how dare you wake me up!") + transformNpc(node, NPCs.GOBLIN_GUARD_489, 400) + node.attack(player) + return@on true + } + + on(Scenery.GOBLIN_STOVE_25440, SCENERY, "inspect") { player, _ -> + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> sendDialogueLines(player, "The goblins appear to have been using the lens mould to cook their", "stew!").also { stage++ } + 1 -> sendDialogueLines(player, "You shake out its contents and take it with you.").also { animate(player, 537); stage++ } + 2 -> end().also { + sendChat(player, "Euuuw, that smells awful!") + setVarbit(player, ObservatoryQuest.goblinStoveVarbit ,1) + addItemOrDrop(player, Items.LENS_MOULD_602) + } + } + } + }) + return@on true + } + + on(Scenery.GOBLIN_STOVE_25441, SCENERY, "inspect") { player, _ -> + if (!inInventory(player, Items.LENS_MOULD_602)) addItemOrDrop(player, Items.LENS_MOULD_602) + return@on true + } + + onUseWith(ITEM, Items.LENS_MOULD_602, Items.MOLTEN_GLASS_1775) { player, _, with -> + if (getStatLevel(player, Skills.CRAFTING) < 10) { + sendMessage(player, "You need a crafting level of 10 to do this.") + return@onUseWith true + } + + sendMessage(player, "You pour the molten glass into the mould.") + sendMessage(player, "You clasp it together.") + sendItemDialogue(player, Items.OBSERVATORY_LENS_603, "It has produced a small, convex glass disc.") + if (removeItem(player, with)) { + addItemOrDrop(player, Items.OBSERVATORY_LENS_603) + } + return@onUseWith true + } + + on(intArrayOf(Scenery.STAR_CHART_25578, Scenery.STAR_CHART_25579, Scenery.STAR_CHART_25580, Scenery.STAR_CHART_25581, Scenery.STAR_CHART_25582, Scenery.STAR_CHART_25583), SCENERY, "look-at") { player, _ -> + openInterface(player, ObservatoryQuest.starChartsInterface) + return@on true + } + + on(intArrayOf(Scenery.TELESCOPE_25438, Scenery.TELESCOPE_25439), SCENERY, "view") { player, _ -> + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) >= 100) { + openDialogue(player, TelescopeDialogue(), NPC(NPCs.OBSERVATORY_PROFESSOR_488)) + } + else if (getQuestStage(player, Quests.OBSERVATORY_QUEST) >= 6) { + if (getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) == null) { + setAttribute(player, ObservatoryQuest.attributeTelescopeStar, (19..30).random()) + } + val randomStar = getAttribute(player, ObservatoryQuest.attributeTelescopeStar, null) + openInterface(player, ObservatoryQuest.telescopeInterface) + player.packetDispatch.sendModelOnInterface(ObservatoryQuestInterfaces.buttonToStarObjectMapping[randomStar]!!, ObservatoryQuest.telescopeInterface, 7, 0) + } else { + sendMessage(player, "The telescope is broken.") + } + return@on true + } + + on(intArrayOf(Scenery.DOOR_25526, Scenery.DOOR_25527), SCENERY, "open") { player, _ -> + sendMessage(player, "The door is locked.") + return@on true + } + + on(Scenery.GRAVE_OF_SCORPIUS_2211, SCENERY, "read") { player, _ -> + sendMessage(player, "Here lies Scorpius: Only those who have seen beyond the stars may seek his counsel.") + return@on true + } + } +} + +class TelescopeDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npcl(FacialExpression.ASKING, "What do you see now?").also { stage++ } + 1 -> playerl("I can see a constellation through the telescope. It looks like Scorpio.").also { stage++ } + 2 -> npcl("Scorpio? Interesting. How very fitting.").also { stage++ } + 3 -> playerl(FacialExpression.ASKING, " What do you mean?").also { stage++ } + 4 -> npcl("Scorpius, the founder of all we know relating to astronomy. There's a book about him in the reception. Perhaps you should check it out, you might learn something.").also { stage++ } + 5 -> playerl("Then perhaps I shall.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/PoisonSpiderBehavior.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/PoisonSpiderBehavior.kt new file mode 100644 index 000000000..dc4f0b74d --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/PoisonSpiderBehavior.kt @@ -0,0 +1,20 @@ +package content.region.kandarin.quest.observatoryquest + +import core.api.getAttribute +import core.api.setAttribute +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.GameWorld +import org.rs09.consts.NPCs + +class PoisonSpiderBehavior : NPCBehavior(NPCs.POISON_SPIDER_1009) { + override fun onCreation(self: NPC) { + setAttribute(self, "despawn-time", GameWorld.ticks + 100) + } + + override fun tick(self: NPC): Boolean { + if (getAttribute(self, "despawn-time", 0) <= GameWorld.ticks && !self.inCombat()) + self.clear() + return true + } +} diff --git a/Server/src/main/content/region/kandarin/quest/observatoryquest/SpiritOfScorpiusDialogue.kt b/Server/src/main/content/region/kandarin/quest/observatoryquest/SpiritOfScorpiusDialogue.kt new file mode 100644 index 000000000..6d8fd5815 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/observatoryquest/SpiritOfScorpiusDialogue.kt @@ -0,0 +1,110 @@ +package content.region.kandarin.quest.observatoryquest + +import content.data.Quests +import content.region.kandarin.quest.observatoryquest.ObservatoryQuest.Companion.attributeReceivedMould +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class SpiritOfScorpiusDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return SpiritOfScorpiusDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SpiritOfScorpiusDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SPIRIT_OF_SCORPIUS_492) + } +} + +class SpiritOfScorpiusDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.SPIRIT_OF_SCORPIUS_492) + + exec { player, npc -> + if (getQuestStage(player, Quests.OBSERVATORY_QUEST) == 100) { + if (!inEquipment(player, Items.GHOSTSPEAK_AMULET_552)) loadLabel(player, "noghostspeak") + else loadLabel(player, "observatoryqueststage100") + } else loadLabel(player, "observatoryquestincomplete") + } + + label("observatoryquestincomplete") + line("They seem to be ignoring you.") + + label("noghostspeak") + line("This powerful spirit seems capable of speaking to you", "even though you are not wearing an Amulet of Ghostspeak.") + exec { player, _ -> + loadLabel(player, "observatoryqueststage100") + } + + label("observatoryqueststage100") + npc("Who treads upon my grave?") + options( + DialogueOption("wisdom", "I seek your wisdom.") { player, _ -> + return@DialogueOption !getAttribute(player, attributeReceivedMould, false) + }, + DialogueOption("anothermould", "I need another unholy symbol mould.", "I need another mould for the unholy symbol.") { player, _ -> + return@DialogueOption getAttribute(player, attributeReceivedMould, false) + }, + DialogueOption("blessing", "I have come to seek your blessing."), + DialogueOption("killyou", "I have come to kill you.") + ) + + label("wisdom") + npc("Indeed, I feel you have beheld the far places in the heavens. My Lord instructs me to help you.") + item(Item(Items.UNHOLY_MOULD_1594), "An unholy mould appears in your inventory.") + exec { player, _ -> + addItemOrDrop(player, Items.UNHOLY_MOULD_1594) + setAttribute(player, attributeReceivedMould, true) + } + npc("Here is a mould to make a token for our Lord; a mould for the unholy symbol of Zamorak. Return to me when you desire my blessing.") + + label("anothermould") + exec { player, _ -> + if (inInventory(player, Items.UNHOLY_MOULD_1594)) { + loadLabel(player, "hasmould") + } + else { + addItemOrDrop(player, Items.UNHOLY_MOULD_1594) + loadLabel(player, "lostmould") + } + } + + label("hasmould") + npc("One you already have, another is not needed. Leave me be.") + + label("lostmould") + npc("A lost object is easy to replace. The loss of the affections of our Lord is impossible to forgive.") + + label("blessing") + exec { player, _ -> + if (inInventory(player, Items.UNPOWERED_SYMBOL_1722)) { + loadLabel(player, "canbless") + } + else loadLabel(player, "cannotbless") + } + + label("canbless") + npc("I see you have the unholy symbol of our Lord. I will bless it for you.") + line("The ghost mutters in a strange voice.", "The unholy symbol throbs with power.") + exec { player, _ -> + removeItem(player, Items.UNPOWERED_SYMBOL_1722) + addItemOrDrop(player, Items.UNHOLY_SYMBOL_1724) + } + npc("The symbol of our Lord has been blessed with power! My master calls.") + + + label("cannotbless") + npc("No blessing will be given to those who have no symbol of our Lord's love.") + + label("killyou") + npc("The might of mortals, to me, is as the dust to the sea.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCPeksaDialogue.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCPeksaDialogue.kt new file mode 100644 index 000000000..79df6ceac --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCPeksaDialogue.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +class SCPeksaDialogue(val questStage: Int) : DialogueFile() { + + companion object { + const val ASK_ABOUT_SCORPION = START_DIALOGUE + const val ASK_FOR_HELP = 20 + const val THANK_YOU = 30 + + } + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + // Word wrap issues + ASK_ABOUT_SCORPION -> npc("Now how could you know about that, I wonder?", "Mind you, I don't have it anymore.").also { stage++ } + ASK_ABOUT_SCORPION + 1 -> npcl(" I gave it as a present to my brother Ivor when I visited our outpost in the west.").also { stage++ } + ASK_ABOUT_SCORPION + 2 -> npcl("Well, actually I hid it in his bed so it would nip him. It was a bit of a surprise gift.").also { stage++ } + + ASK_ABOUT_SCORPION + 3 -> showTopics( + Topic("So where is this outpost?", ASK_FOR_HELP), + Topic("Thanks for the information", THANK_YOU, true) + ) + + ASK_FOR_HELP -> npcl("Its a fair old trek to the west, across the White Wolf Mountains. Then head west, north-west until you see the axes and horned helmets.").also { stage= + THANK_YOU } + + THANK_YOU -> { + playerl("Thanks for the information").also { stage++ } + setQuestStage(player!!, Quests.SCORPION_CATCHER, ScorpionCatcher.QUEST_STATE_PEKSA_HELP) + } + THANK_YOU + 1 -> npcl ("No problems! Tell Ivor I said hi!").also { stage = END_DIALOGUE } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCSeerDialogue.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCSeerDialogue.kt new file mode 100644 index 000000000..a15b267c2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCSeerDialogue.kt @@ -0,0 +1,79 @@ +package content.region.kandarin.quest.scorpioncatcher + +import content.region.kandarin.seers.dialogue.SeerDialogue +import core.api.sendDialogue +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +class SCSeerDialogue(val questStage: Int, private val dialogueEntry: Int) : DialogueFile() { + + companion object { + const val FIRST_SCORPION_HELP = 20 + const val FIRST_SCORPION_THORMAC = 30 + const val FIRST_SCORPION_GUIDE = 40 + const val OTHER_SCORPIONS = 50 + + + // There are many ways that this dialogue can be entered + const val ENTRY_HELP = SeerDialogue.SC_QUEST_HELP + const val ENTRY_FRIEND = SeerDialogue.SC_QUEST_FRIEND + const val ENTRY_OTHERS = SeerDialogue.SC_QUEST_OTHER_SCORPIONS + + } + + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> when (dialogueEntry){ + ENTRY_HELP -> npcl("Well you have come to the right place. I am a master of animal detection.").also { stage = FIRST_SCORPION_HELP } + ENTRY_FRIEND -> npcl(FacialExpression.NEUTRAL, "What does the old fellow want?").also { stage = FIRST_SCORPION_THORMAC } + // word wrap doesn't work again + ENTRY_OTHERS -> npc(FacialExpression.NEUTRAL, "Well, I've checked my looking glass. There seems to be", + "a kharid scorpion in a little village to the east,", + "surrounded by lots of uncivilized-looking warriors.", + "Some kind of merchant there seems to have picked it up.").also { stage = OTHER_SCORPIONS } + else -> { + println("Invalid entry to SCSeerDialogue $dialogueEntry") + end() + } + } + + FIRST_SCORPION_THORMAC -> playerl( + FacialExpression.NEUTRAL, + "He's lost his valuable lesser Kharid scorpions." + ).also { stage++ } + FIRST_SCORPION_THORMAC + 1 -> npcl( + FacialExpression.HAPPY, + "Well you have come to the right place. I am a master of animal detection." + ).also { stage = FIRST_SCORPION_GUIDE } + + FIRST_SCORPION_HELP -> npcl("Do you need to locate any particular scorpion? Scorpions are a creature somewhat in abundance.").also { stage++ } + FIRST_SCORPION_HELP + 1 -> playerl("I'm looking for some lesser Kharid scorpions. They belong to Thormac the Sorcerer.").also { + stage = FIRST_SCORPION_GUIDE + } + + FIRST_SCORPION_GUIDE -> npcl(FacialExpression.HAPPY, "Let me look into my looking glass.").also { stage++ } + FIRST_SCORPION_GUIDE + 1 -> sendDialogue(player!!, "The Seer produces a small mirror.").also { stage++ } + FIRST_SCORPION_GUIDE + 2 -> sendDialogue(player!!, "The Seer gazes into the mirror.").also { stage++ } + FIRST_SCORPION_GUIDE + 3 -> sendDialogue(player!!, "The Seer smooths his hair with his hand.").also { stage++ } + FIRST_SCORPION_GUIDE + 4 -> npcl("I can see a scorpion that you seek. It would appear to be near some nasty spiders. I can see two coffins there as well.").also { stage++ } + FIRST_SCORPION_GUIDE + 5 -> npcl("The scorpion seems to be going through some crack in the wall. Its gone into some sort of secret room.").also { stage++ } + FIRST_SCORPION_GUIDE + 6 -> npcl("Well see if you can find the scorpion then, and I'll try and get you some information on the others.").also { + setQuestStage(player!!, Quests.SCORPION_CATCHER, ScorpionCatcher.QUEST_STATE_DARK_PLACE) + stage = END_DIALOGUE + } + + OTHER_SCORPIONS -> npcl ("That's all I can tell about that scorpion.").also { stage++ } + OTHER_SCORPIONS + 1 -> playerl("Any more scorpions?").also { stage++ } + OTHER_SCORPIONS + 2 -> npcl ("It's good that you should ask. I have information on the last scorpion for you.").also { stage++ } + OTHER_SCORPIONS + 3 -> npcl ("It seems to be in some sort of upstairs room. There seems to be some sort of brown clothing lying on a table.").also { + setQuestStage(player!!, Quests.SCORPION_CATCHER, ScorpionCatcher.QUEST_STATE_OTHER_SCORPIONS) + stage = END_DIALOGUE + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCThormacDialogue.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCThormacDialogue.kt new file mode 100644 index 000000000..9422c9d06 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCThormacDialogue.kt @@ -0,0 +1,135 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import core.ServerConstants +import core.api.* +import core.game.dialogue.Topic +import core.game.node.item.Item +import org.rs09.consts.Items +import content.data.Quests + +class SCThormacDialogue(val questStage: Int) : DialogueFile() { + + companion object { + const val ASK_FOR_HELP = 10 + const val HOW_TO_CATCH = 30 + const val WHY_SHOULD_I_START = 50 + + const val WAITING_FOR_SCORPIONS = 100 + const val GIVE_ANOTHER_CAGE = 110 + + const val GOT_THEM_ALL = 200 + const val FULL_INVENTORY = 300 + } + + + override fun handle(componentID: Int, buttonID: Int) { + when (stage){ + START_DIALOGUE -> if (questStage == 0) { + npcl(FacialExpression.FRIENDLY, "Hello I am Thormac the Sorcerer, " + + "I don't suppose you could be of assistance to me?").also { stage = ASK_FOR_HELP } + } + else { + npcl(FacialExpression.NEUTRAL, "How goes your quest?").also { + stage = if (hasAnItem(player!!, Items.SCORPION_CAGE_463).exists()){ + // Player has all the scorpions caught + GOT_THEM_ALL + } else { + WAITING_FOR_SCORPIONS + } + } + } + + ASK_FOR_HELP -> showTopics( + Topic(FacialExpression.HAPPY,"What do you need assistance with?", ASK_FOR_HELP+1), + Topic(FacialExpression.NEUTRAL, "I'm a little busy.", END_DIALOGUE) + ) + ASK_FOR_HELP+1 -> npcl(FacialExpression.WORRIED, " I've lost my pet scorpions. " + + "They're lesser Kharid scorpions, a very rare breed.").also { stage++ } + ASK_FOR_HELP+2 -> npcl(FacialExpression.WORRIED, "I left their cage door open, now I don't know where they've gone.").also { stage++ } + ASK_FOR_HELP+3 -> npcl(FacialExpression.WORRIED, "There's three of them, and they're quick little beasties. " + + "They're all over " + ServerConstants.SERVER_NAME + ".").also { stage++ } + ASK_FOR_HELP+4 -> showTopics( + Topic(FacialExpression.ASKING, "So how would I go about catching them then?", HOW_TO_CATCH), + Topic(FacialExpression.ASKING, "What's in it for me?", WHY_SHOULD_I_START), + Topic(FacialExpression.NEUTRAL, "I'm not interested then.", END_DIALOGUE) + ) + + WHY_SHOULD_I_START -> npcl(FacialExpression.WORRIED, "Well I suppose I can aid you with my skills as a staff sorcerer. " + + "Most battlestaffs around here are a bit puny. I can beef them up for you a bit.").also { + // Need to recheck the quest stage since it may have been changed in this dialogue + if (getQuestStage(player!!, Quests.SCORPION_CATCHER) == 0) { + stage++ + } else { + stage = END_DIALOGUE + } + } + WHY_SHOULD_I_START+1 -> showTopics( + Topic(FacialExpression.ASKING, "So how would I go about catching them then?", HOW_TO_CATCH), + Topic(FacialExpression.NEUTRAL, "I'm not interested then.", END_DIALOGUE) + ) + + HOW_TO_CATCH -> npcl(FacialExpression.WORRIED, "Well I have a scorpion cage here which you can " + + "use to catch them in.").also { + if (hasSpaceFor(player!!,Item(Items.SCORPION_CAGE_456))) stage++ + else stage = FULL_INVENTORY + } + HOW_TO_CATCH+1 -> { + sendItemDialogue(player!!, Items.SCORPION_CAGE_456, "Thormac gives you a cage.").also { stage++ } + startQuest(player!!, Quests.SCORPION_CATCHER) + addItemOrDrop(player!!, Items.SCORPION_CAGE_456) + } + HOW_TO_CATCH+2 -> npcl(FacialExpression.WORRIED, "If you go up to the village of Seers, to the North of " + + "here, one of them will be able to tell you where the scorpions are now.").also { stage++ } + HOW_TO_CATCH+3 -> showTopics( + Topic(FacialExpression.ASKING, "What's in it for me?", WHY_SHOULD_I_START), + Topic(FacialExpression.NEUTRAL, "Ok, I will do it then.", END_DIALOGUE ) + ) + + + WAITING_FOR_SCORPIONS -> { + if (!hasAnItem(player!!, arrayOf(Items.SCORPION_CAGE_456, Items.SCORPION_CAGE_457, Items.SCORPION_CAGE_458, + Items.SCORPION_CAGE_459, Items.SCORPION_CAGE_460, Items.SCORPION_CAGE_461, + Items.SCORPION_CAGE_462), false).exists()){ + playerl(FacialExpression.SAD, "I've lost my cage.").also { stage = GIVE_ANOTHER_CAGE } + } else { + playerl(FacialExpression.NEUTRAL, "I've not caught all the scorpions yet.").also { stage++ } + } + } + WAITING_FOR_SCORPIONS+1 -> npcl(FacialExpression.WORRIED, "Well remember to go speak to the Seers" + + " North of here, if you need any help.").also { stage = END_DIALOGUE } + + GIVE_ANOTHER_CAGE -> { + player!!.inventory.add(Item(Items.SCORPION_CAGE_456)) + // Clear all attributes keeping track of the scorpions + player!!.removeAttribute("scorpion_catcher:caught_taverly") + player!!.removeAttribute("scorpion_catcher:caught_barb") + player!!.removeAttribute("scorpion_catcher:caught_monk") + npcl(FacialExpression.NEUTRAL, "Ok, here's another cage. You're almost as bad" + + " at losing things as me.").also { stage = END_DIALOGUE } + } + + GOT_THEM_ALL -> { + playerl ("I have retrieved all your scorpions.").also { stage++ } + } + GOT_THEM_ALL+1 ->{ + npcl(FacialExpression.HAPPY, "Aha, my little scorpions home at last!").also { stage++ } + player!!.inventory.remove(Item(Items.SCORPION_CAGE_463)) + + // Don't need to keep track of which scorpions have been caught anymore + player!!.removeAttribute("scorpion_catcher:caught_taverly") + player!!.removeAttribute("scorpion_catcher:caught_barb") + player!!.removeAttribute("scorpion_catcher:caught_monk") + } + GOT_THEM_ALL+2 ->{ + end().also { finishQuest(player!!, Quests.SCORPION_CATCHER) } + } + + + FULL_INVENTORY -> npcl("You don't have space to hold a cage").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCWallListener.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCWallListener.kt new file mode 100644 index 000000000..864f2ce08 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCWallListener.kt @@ -0,0 +1,37 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.api.getQuestStage +import core.api.sendMessage +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Scenery +import content.data.Quests + +class SCWallListener : InteractionListener { + + override fun defineListeners() { + on(Scenery.OLD_WALL_2117, IntType.SCENERY, "search"){ player, node -> + // You can only go through if you are doing the quest + //https://youtu.be/crc-47rwjvE?feature=shared&t=841 + // Otherwise the crack reverts back to normal + // Doesn't make any sense but that's authentic... + if ((ScorpionCatcher.QUEST_STATE_DARK_PLACE .. 99).contains(getQuestStage(player, Quests.SCORPION_CATCHER))) { + // Check what side the player is on and teleport them to the other + if (player.location == Location(2875, 9799, 0)){ + sendMessage(player, "You've found a secret door") + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else{ + // We're leaving the room + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + } + else{ + sendMessage(player, "You search the wall but find nothing.") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcher.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcher.kt new file mode 100644 index 000000000..2c314f0d6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcher.kt @@ -0,0 +1,148 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class ScorpionCatcher : Quest(Quests.SCORPION_CATCHER, 108, 107, 1, 76, 0, 1, 6) { + companion object { + const val QUEST_STATE_NOT_STARTED = 0 + const val QUEST_STATE_TALK_SEERS = 10 + const val QUEST_STATE_DARK_PLACE = 20 + const val QUEST_STATE_OTHER_SCORPIONS = 30 + const val QUEST_STATE_PEKSA_HELP = 40 + const val QUEST_STATE_DONE = 100 + + const val ATTRIBUTE_TAVERLEY = "scorpion_catcher:caught_taverly" + const val ATTRIBUTE_BARB = "scorpion_catcher:caught_barb" + const val ATTRIBUTE_MONK = "scorpion_catcher:caught_monk" + + } + + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + + var ln = 12 + + val caughtTaverly = player!!.getAttribute(ATTRIBUTE_TAVERLEY, false) + val caughtBarb = player.getAttribute(ATTRIBUTE_BARB, false) + val caughtMonk = player.getAttribute(ATTRIBUTE_MONK, false) + + if (stage == QUEST_STATE_NOT_STARTED){ + line(player, "I can start this quest by speaking to !!Thormac?? who is in the", ln++) + line(player, "!!Sorcerer's Tower?? south-west of !!Catherby??", ln++) + ln++ //blank line + line(player, "Requirements:", ln++) + line(player, "Level 31 Prayer", ln, player.skills.staticLevels[Skills.PRAYER] >= 31) + } else { + line(player, "I've spoken to Thormac in the Sorcerer's Tower south-west", ln++, true) + line(player, "of Catherby. He's lost his pet Kharid Scorpions and needs", ln++, true) + line(player, "my help to find them.", ln++, true) + + // 10 -> 20 + if (stage >= QUEST_STATE_DARK_PLACE) { + ln++ + line(player, "I've spoken to a Seer and been given the location of one", ln++, true) + line(player, "of the Kharid Scorpions.", ln++, true) + } else if (stage >= QUEST_STATE_TALK_SEERS) { + ln++ + line(player, "I need to go to the !!Seers' Village?? and talk to the !!Seer??", ln++) + line(player, "about the lost !!Kharid Scorpions??.", ln++) + } + + // 20 -> 20 + 1st Scorpion + if (stage >= QUEST_STATE_DARK_PLACE && caughtTaverly || stage >= QUEST_STATE_OTHER_SCORPIONS) { + ln++ + line(player, "The first Kharid Scorpion is in a secret room near some", ln++, true) + line(player, "nasty spiders with two coffins nearby.", ln++, true) + } else if (stage >= QUEST_STATE_DARK_PLACE) { + ln++ + line(player, "The first !!Kharid Scorpion?? is in a secret room near some", ln++) + line(player, "!!nasty spiders?? with two !!coffins?? nearby.", ln++) + // Jan 21, 2010 version has a slightly updated but similar location. +// line(player, "The first !!Kharid Scorpion?? is in a !!dark place between a lake??", ln++) +// line(player, "and a !!holy island??. It will be close when you enter.", ln++) + ln++ + line(player, "I'll need to talk to a !!Seer?? again one I've caught the first", ln++) + line(player, "!!Kharid Scorpion??.", ln++) + } + + // 20 + 1st Scorpion -> 30 + if (stage >= QUEST_STATE_OTHER_SCORPIONS) { + // This line disappears when the you talk to the Seer again. + } else if (stage >= QUEST_STATE_DARK_PLACE && caughtTaverly){ + // Todo check this line + ln++ + line(player, "I should go back to the Seer and ask about the other", ln++) + line(player, "scorpions.", ln++) + } + + // 30 -> 40 + if (stage >= QUEST_STATE_OTHER_SCORPIONS){ + ln++ + val barb_strike = caughtBarb || (stage == QUEST_STATE_PEKSA_HELP) + line(player, "The second !!Kharid Scorpion?? has been in a !!village of??", ln++, barb_strike || stage == QUEST_STATE_DONE) + line(player, "!!uncivilised-looking warriors in the east??. It's been picked up", ln++, barb_strike || stage == QUEST_STATE_DONE) + line(player, "by some sort of !!merchant??.", ln++, barb_strike || stage == QUEST_STATE_DONE) + // Jan 21, 2010 version has a slightly updated but similar location. +// line(player, "The second !!Kharid Scorpion?? was once in a !!village two??", ln++, barb_strike || stage == QUEST_STATE_DONE) +// line(player, "!!canoe trips from lumbridge??. A !!shopkeeper?? there picked it up.", ln++, barb_strike || stage == QUEST_STATE_DONE) + if (stage == QUEST_STATE_PEKSA_HELP){ + // todo check this block + ln++ + line(player, "I spoke with !!Peksa?? who said he sent it to his brother", ln++, caughtBarb) + line(player, "at the !!Barbarian outpost.??", ln++, caughtBarb) + } + ln++ + line(player, "The third !!Kharid Scorpion?? is in some sort of !!upstairs room??", ln++, caughtMonk || stage == QUEST_STATE_DONE) + line(player, "with !!brown clothing on a table??.", ln++, caughtMonk || stage == QUEST_STATE_DONE) + // Jan 21, 2010 version has a slightly updated but similar location. +// line(player, "The third !!Kharid Scorpion?? is in an !!upstairs room?? with !!brown??", ln++, caughtMonk || stage == QUEST_STATE_DONE) +// line(player, "!!clothing on a table?? The clothing is adorned with a golden", ln++, caughtMonk || stage == QUEST_STATE_DONE) +// line(player, "four-pointed star. You should start looking where monks", ln++, caughtMonk || stage == QUEST_STATE_DONE) +// line(player, "reside.", ln++, caughtMonk || stage == QUEST_STATE_DONE) + } + + // 40 -> 100 + if (stage == QUEST_STATE_DONE) { + // This line disappears when you complete the quest. + } else if (caughtBarb && caughtTaverly && caughtMonk && stage >= QUEST_STATE_OTHER_SCORPIONS){ + ln++ + line(player, "I need to take the !!Kharid Scorpions?? to !!Thormac??.", ln) + } + + // 100 + if (stage == QUEST_STATE_DONE) { + ln++ + line(player, "I've spoken to Thormac and he thanked me for finding his", ln++, true) + line(player, "pet Kharid Scorpions.", ln++, true) + ln++ + ln++ + line(player, "QUEST COMPLETE!", ln) + return + } + + } + } + + override fun finish(player: Player?) { + var ln = 10 + super.finish(player) + player!!.packetDispatch.sendString("You have completed the Scorpion Catcher Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.SCORPION_CAGE_463, 240, 277, 5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "6625 Strength XP", ln) + + player.skills.addExperience(Skills.STRENGTH, 6625.0) + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcherUseListener.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcherUseListener.kt new file mode 100644 index 000000000..3b95da47b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcherUseListener.kt @@ -0,0 +1,88 @@ +package content.region.kandarin.quest.scorpioncatcher + +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_TAVERLEY +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_BARB +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_MONK +import core.api.* +import core.game.node.item.Item +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.system.config.NPCConfigParser +import core.game.world.GameWorld +import core.tools.Log +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class ScorpionCatcherUseListener : InteractionListener { + override fun defineListeners() { + val scorpToAttr = mapOf( + /* 385 - Barbarian + * 386 - Taverley + * 387 - Monastery + */ + NPCs.KHARID_SCORPION_385 to ATTRIBUTE_BARB, + NPCs.KHARID_SCORPION_386 to ATTRIBUTE_TAVERLEY, + NPCs.KHARID_SCORPION_387 to ATTRIBUTE_MONK + ) + val cageToScorps = mapOf( + /* Taverley(386) Barbarian(385) Monastery(387) + * TBM + * 456 --- + * 457 O-- + * 458 00- + * 459 -0- + * 460 -00 + * 461 --0 + * 462 0-0 + * 463 000 + */ + Items.SCORPION_CAGE_456 to setOf(), + Items.SCORPION_CAGE_457 to setOf(NPCs.KHARID_SCORPION_386), + Items.SCORPION_CAGE_458 to setOf(NPCs.KHARID_SCORPION_386, NPCs.KHARID_SCORPION_385), + Items.SCORPION_CAGE_459 to setOf(NPCs.KHARID_SCORPION_385), + Items.SCORPION_CAGE_460 to setOf(NPCs.KHARID_SCORPION_385, NPCs.KHARID_SCORPION_387), + Items.SCORPION_CAGE_461 to setOf(NPCs.KHARID_SCORPION_387), + Items.SCORPION_CAGE_462 to setOf(NPCs.KHARID_SCORPION_386, NPCs.KHARID_SCORPION_387), + Items.SCORPION_CAGE_463 to setOf(NPCs.KHARID_SCORPION_386, NPCs.KHARID_SCORPION_385, NPCs.KHARID_SCORPION_387) + ) + + fun catchScorpion(player: Player, item: Node, scorpion: Node): Boolean { + val haveInCage = cageToScorps[item.id] ?: return false + if (scorpion.id in haveInCage) { + sendMessage(player, "You already have this scorpion in this cage.") //TODO check this message + return true + } + val newScorpionSet = haveInCage + setOf(scorpion.id) + var newItem: Int? = null + for ((cage, scorps) in cageToScorps) { + if (scorps == newScorpionSet) { + newItem = cage + } + } + if (newItem == null) { + log(this::class.java, Log.ERR, "Error looking up new scorpion cage item - this isn't possible") + return false + } + val attribute = scorpToAttr[scorpion.id] + if (removeItem(player, Item(item.id, 1)) && addItem(player, newItem)) { + sendMessage(player, "You catch a scorpion!") + setAttribute(player, "/save:$attribute", true) + runTask(player, 2) { + scorpion.asNpc().respawnTick = GameWorld.ticks + scorpion.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return true + } + return false + } + + for (scorp in scorpToAttr.keys) { + for (cage in cageToScorps.keys) { + onUseWith(IntType.NPC, cage, scorp) { player, usedCage, usedScorp -> + return@onUseWith catchScorpion(player, usedCage, usedScorp) + } + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt index 0b700a2d3..5dbcbb4e5 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.* import core.game.dialogue.FacialExpression import core.game.node.entity.Entity @@ -7,7 +8,6 @@ import core.game.node.entity.combat.BattleState import core.game.node.entity.combat.CombatStyle import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player -import core.game.system.task.Pulse import core.game.world.map.Location import org.rs09.consts.NPCs @@ -64,8 +64,8 @@ class FireWarriorOfLesarkusNPC(id: Int = 0, val player: Player?, location: Locat if (entity is Player) { val player = entity.asPlayer() removeAttribute(player, TempleOfIkov.attributeWarriorInstance) - if(getQuestStage(player, TempleOfIkov.questName) == 3) { - setQuestStage(player, TempleOfIkov.questName, 4) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 3) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 4) } super.finalizeDeath(player) } diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt index 6101484c1..846c5204f 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.isQuestComplete import core.game.node.entity.Entity import core.game.node.entity.npc.NPC @@ -21,7 +22,7 @@ class GuardianOfArmadylBehavior : NPCBehavior(*guardianOfArmadylIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops Pendant of Armadyl after quest complete when killed. - if (killer is Player && isQuestComplete(killer, TempleOfIkov.questName)) { + if (killer is Player && isQuestComplete(killer, Quests.TEMPLE_OF_IKOV)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.ARMADYL_PENDANT_87)) } diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt index 50a9293e4..c8900621f 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile @@ -143,8 +144,8 @@ class GuardianOfArmadylDialogueFile : DialogueBuilderFile() { .item(Items.ARMADYL_PENDANT_87, "The guardian has given you a pendant.") .endWith { _, player -> setAttribute(player, TempleOfIkov.attributeChosenEnding, 1) - if (getQuestStage(player, TempleOfIkov.questName) == 5) { - setQuestStage(player, TempleOfIkov.questName, 6) + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 5) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 6) } addItemOrDrop(player, Items.ARMADYL_PENDANT_87) } diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt index c6b3c93d2..c093d134e 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile @@ -26,11 +27,25 @@ class LucienDialogue (player: Player? = null) : DialoguePlugin(player) { class LucienDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(TempleOfIkov.questName, 100) - .endWith { _, player -> - sendMessage(player, "You have completed the Temple of Ikov quest.") + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 100) + .playerl("I thought I killed you?!") + .npcl("Ha! Ha! Ha!") + .npcl("You can not kill me human!") + .branch { player -> + return@branch if (inInventory(player, Items.PENDANT_OF_LUCIEN_86)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .end() + branch.onValue(0) + .playerl("I've lost the pendant you gave me.") + .npcl("Have another, it will remind you of my power!") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.PENDANT_OF_LUCIEN_86) + } + .item(Items.PENDANT_OF_LUCIEN_86, "Lucien has given you another pendant!") + .end() } - b.onQuestStages(TempleOfIkov.questName, 1,2,3,4,5,6,7) + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 1, 2, 3, 4, 5, 6, 7) .npcl("I told you not to meet me here again!") .branch { player -> return@branch if (inInventory(player, Items.PENDANT_OF_LUCIEN_86)) { 1 } else { 0 } @@ -51,7 +66,7 @@ class LucienDialogueFile : DialogueBuilderFile() { .end() } - b.onQuestStages(TempleOfIkov.questName, 0) + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 0) .npcl("I seek a hero to go on an important mission!") .options().let { optionBuilder -> val returnJoin = b.placeholder() @@ -86,8 +101,8 @@ class LucienDialogueFile : DialogueBuilderFile() { .npcl("I cannot stay here much longer. ") .npcl("I will be west of the Grand Exchange in Varrock. I have a small holding up there.") .endWith { _, player -> - if(getQuestStage(player, TempleOfIkov.questName) == 0) { - setQuestStage(player, TempleOfIkov.questName, 1) + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 0) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 1) } } optionBuilder.option_playerl("Oh no! Sounds far too dangerous!") diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt index 48cf0b890..2ba1dd6b7 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.* import core.game.dialogue.* import core.game.node.entity.player.Player @@ -23,11 +24,13 @@ class LucienEndingDialogue (player: Player? = null) : DialoguePlugin(player) { class LucienEndingDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(TempleOfIkov.questName, 100) + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 100) .endWith { _, player -> + // After quest is over: https://www.youtube.com/watch?v=81DXjfsFcMM + sendMessage(player, "You feel that fighting this individual will be of little practical use.") sendMessage(player, "You have completed the Temple of Ikov quest.") } - b.onQuestStages(TempleOfIkov.questName, 1,2,3,4,5,6,7) + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 1, 2, 3, 4, 5, 6, 7) .npcl(FacialExpression.FRIENDLY, "Have you got the Staff of Armadyl yet?") .branch { player -> return@branch if (inInventory(player, Items.STAFF_OF_ARMADYL_84)) { 1 } else { 0 } @@ -44,8 +47,8 @@ class LucienEndingDialogueFile : DialogueBuilderFile() { .npcl(FacialExpression.FRIENDLY, "I can feel the power of the staff running through me! I will be more powerful and they shall bow down to me!") .npcl(FacialExpression.FRIENDLY, "I suppose you want your reward? I shall grant you much power!") .endWith { _, player -> - if(getQuestStage(player, TempleOfIkov.questName) == 6) { - finishQuest(player, TempleOfIkov.questName) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 6) { + finishQuest(player, Quests.TEMPLE_OF_IKOV) } } optionBuilder.option_playerl("No, not yet.") diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt index c4d7a4319..18e8e429b 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.node.entity.Entity @@ -40,8 +41,8 @@ class LucienEndingNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, when(stage){ 0 -> npcl("You have defeated me for now! I shall reappear in the North!").also { stage++ } 1 -> end().also { - if(getQuestStage(player, TempleOfIkov.questName) == 6) { - finishQuest(player, TempleOfIkov.questName) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 6) { + finishQuest(player, Quests.TEMPLE_OF_IKOV) } } } diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt index 0edb793e8..ebfc4773b 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt @@ -1,11 +1,12 @@ package content.region.kandarin.quest.templeofikov import core.api.* -import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * Temple of Ikov Quest @@ -28,10 +29,9 @@ import org.rs09.consts.Items * D - Found ice arrows */ @Initializable -class TempleOfIkov : Quest("Temple of Ikov", 121, 120, 1,26, 0, 1, 80 /* 80 or 90 since there's 2 endings */) { +class TempleOfIkov : Quest(Quests.TEMPLE_OF_IKOV, 121, 120, 1,26, 0, 1, 80 /* 80 or 90 since there's 2 endings */) { companion object { - const val questName = "Temple of Ikov" const val attributeChosenEnding = "/save:quest:templeofikov-chosenending" const val attributeDisabledTrap = "/save:quest:templeofikov-disabledtrap" @@ -49,7 +49,7 @@ class TempleOfIkov : Quest("Temple of Ikov", 121, 120, 1,26, 0, 1, 80 /* 80 or 9 var line = 12 var stage = getStage(player) - var started = getQuestStage(player, questName) > 0 + var started = getQuestStage(player, Quests.TEMPLE_OF_IKOV) > 0 if (!started) { line(player, "I can start this quest at the !!Flying Horse Inn?? in !!Ardougne??", line++, false) @@ -59,6 +59,7 @@ class TempleOfIkov : Quest("Temple of Ikov", 121, 120, 1,26, 0, 1, 80 /* 80 or 9 line(player, "Level 42 !!Thieving??", line++, hasLevelStat(player, Skills.THIEVING, 42)) line(player, "Level 40 !!Ranged??", line++, hasLevelStat(player, Skills.RANGE, 40)) line(player, "Ability to defeat a level 84 enemy with Ranged.", line++, false) + limitScrolling(player, line, true) } else { if (stage >= 2) { line(player, "Lucien has asked me to retrieve the !!Staff of Armadyl?? from", line++, true) @@ -165,8 +166,8 @@ class TempleOfIkov : Quest("Temple of Ikov", 121, 120, 1,26, 0, 1, 80 /* 80 or 9 line++ line(player,"QUEST COMPLETE!", line) } + limitScrolling(player, line, false) } - } override fun reset(player: Player) { diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt index 6a832b230..7f4c3d09c 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt @@ -1,15 +1,15 @@ package content.region.kandarin.quest.templeofikov -import content.global.ame.events.drilldemon.DrillDemonUtils -import content.global.ame.events.drilldemon.SeargentDamienDialogue +import content.data.LightSource +import content.data.Quests import content.global.skill.agility.AgilityHandler +import content.global.skill.skillcapeperks.SkillcapePerks import core.api.* import core.game.global.action.DoorActionHandler import core.game.global.action.PickupHandler 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.skill.Skills import core.game.node.item.GroundItem import core.game.node.item.Item @@ -20,7 +20,6 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.NPCs import org.rs09.consts.Scenery -import org.rs09.consts.Sounds class TempleOfIkovListeners : InteractionListener { @@ -63,8 +62,8 @@ class TempleOfIkovListeners : InteractionListener { // 1 - 2 Walk past the gate. You must always wear the pendant to get past this gate. on(intArrayOf(Scenery.GATE_94, Scenery.GATE_95), SCENERY, "open") { player, node -> if (inEquipment(player, Items.PENDANT_OF_LUCIEN_86)){ - if(getQuestStage(player, TempleOfIkov.questName) == 1) { - setQuestStage(player, TempleOfIkov.questName, 2) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 1) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 2) } DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { @@ -87,8 +86,8 @@ class TempleOfIkovListeners : InteractionListener { replaceScenery(node.asScenery(), 88, 3) animate(player, Animation(2140)) if (getAttribute(player, TempleOfIkov.attributeDisabledTrap, false)) { - if(getQuestStage(player, TempleOfIkov.questName) == 2) { - setQuestStage(player, TempleOfIkov.questName, 3) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 2) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 3) } } else { AgilityHandler.fail(player, 2, Location.create(2682, 9855, 0), Animation(770), 20, "You slip and fall to the pit below.") @@ -117,6 +116,26 @@ class TempleOfIkovListeners : InteractionListener { // https://www.youtube.com/watch?v=6ZGpJNeGLJ0 // sendDialogue("Hmm...bit dark down here! I'm not going to venture far!") + // Ikov dungeon top stairs to either boots of lightness or the dark room + on(Scenery.STAIRS_35121, SCENERY, "Climb-down") { player, node -> + if (LightSource.hasActiveLightSource(player) || SkillcapePerks.isActive(SkillcapePerks.CONSTANT_GLOW, player)) { // has light source + teleport(player, Location.create(2641, 9763, 0)) + } else { // doesn't have light source + teleport(player, Location.create(2641, 9740, 0)) + sendDialogueLines(player, "Hmm...bit dark down here! I'm not going to venture far!") + } + true + } + + // Ikov dungeon bottom stairs (lit) to top stairs + on(Scenery.STAIRS_96, SCENERY, "Climb-up") { player, node -> + teleport(player, Location.create(2649, 9804, 0)) + } + + // Ikov dungeon bottom stairs (dark) to top stairs + on(Scenery.STAIRS_33232, SCENERY, "Climb-up") { player, node -> + teleport(player, Location.create(2649, 9804, 0)) + } // B: Attach lever, authentic if you log out, the lever is lost, and you have to do that bridge again onUseWith(SCENERY, Items.LEVER_83, Scenery.LEVER_BRACKET_86) { player, used, with -> @@ -142,7 +161,10 @@ class TempleOfIkovListeners : InteractionListener { // C: Gate opens after attached lever on(intArrayOf(Scenery.GATE_89, Scenery.GATE_90), SCENERY, "open") { player, node -> - if (getAttribute(player, TempleOfIkov.attributeIceChamberAccess, false) || getQuestStage(player, TempleOfIkov.questName) >= 4){ + if (getAttribute(player, TempleOfIkov.attributeIceChamberAccess, false) || getQuestStage( + player, + Quests.TEMPLE_OF_IKOV + ) >= 4){ // To be nice, you can "reset" the chest location by opening the gate. // This is a failsafe if the attribute gets "stuck", although I doubt it will happen. setAttribute(player, TempleOfIkov.attributeRandomChest, chestLocations.random()) @@ -189,7 +211,7 @@ class TempleOfIkovListeners : InteractionListener { // 3: Allow access to Fire Warrior Door after pulling the lever on(Scenery.DOOR_92, SCENERY, "open") { player, node -> removeAttribute(player, TempleOfIkov.attributeWarriorInstance) - if (getQuestStage(player, TempleOfIkov.questName) >= 3){ + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) >= 3){ DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { sendMessage(player, "The door won't open.") @@ -200,7 +222,7 @@ class TempleOfIkovListeners : InteractionListener { // 3 - 4: Calls for the Fire Warrior, allows passing when Fire Warrior is defeated. on(Scenery.DOOR_93, SCENERY, "open") { player, node -> - if (getQuestStage(player, TempleOfIkov.questName) >= 4){ + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) >= 4){ DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { if (getAttribute(player, TempleOfIkov.attributeWarriorInstance, null) == null) { @@ -240,7 +262,7 @@ class TempleOfIkovListeners : InteractionListener { } on(Items.STAFF_OF_ARMADYL_84, IntType.GROUNDITEM,"take") { player, node -> - if (getQuestStage(player, TempleOfIkov.questName) >= 6 && getAttribute(player, TempleOfIkov.attributeChosenEnding, 0) == 1){ + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) >= 6 && getAttribute(player, TempleOfIkov.attributeChosenEnding, 0) == 1){ sendMessage(player, "You decide not to steal the staff as you have agreed to help the Guardians") } val npcs = findLocalNPCs(player, intArrayOf(NPCs.GUARDIAN_OF_ARMADYL_274, NPCs.GUARDIAN_OF_ARMADYL_275), 4) @@ -248,8 +270,8 @@ class TempleOfIkovListeners : InteractionListener { sendChat(npcs[0], "That is not thine to take!") npcs[0].attack(player) } else { - if(getQuestStage(player, TempleOfIkov.questName) == 5) { - setQuestStage(player, TempleOfIkov.questName, 6) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 5) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 6) setAttribute(player, TempleOfIkov.attributeChosenEnding, 2) } PickupHandler.take(player, node as GroundItem) diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt index d525d1eb3..aa34d7d76 100644 --- a/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.templeofikov +import content.data.Quests import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile @@ -28,7 +29,7 @@ class WineldaDialogue (player: Player? = null) : DialoguePlugin(player) { class WineldaDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(TempleOfIkov.questName, 5,6,7,100) + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 5, 6, 7, 100) .playerl(FacialExpression.FRIENDLY, "Hi again. Could you do the honours again please?") .npcl(FacialExpression.FRIENDLY, "Certainly! We helps those that helps poor Winelda!") .endWith { _, player -> @@ -56,8 +57,8 @@ class WineldaDialogueFile : DialogueBuilderFile() { .npcl(FacialExpression.FRIENDLY, "Good! Good! My potion is nearly ready! Bubble, bubble, toil and trouble!") .npcl(FacialExpression.FRIENDLY, "Now we shows them ours magic! Hold on tight!") .endWith { _, player -> - if(getQuestStage(player, TempleOfIkov.questName) == 4) { - setQuestStage(player, TempleOfIkov.questName, 5) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 4) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 5) } // There's a cutscene, but I'm lazy man. teleport(player, Location(2664, 9876, 0)) diff --git a/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt index eb707dbf5..afc028e55 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt @@ -1,12 +1,13 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE class BallistaDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) if (questStage > 30) { when (stage) { 0 -> sendDialogue(player!!, "The Khazard stronghold has already been breached.").also { stage = END_DIALOGUE } @@ -28,7 +29,7 @@ class BallistaDialogue : DialogueFile(){ when (buttonID) { answer -> { sendDialogue(player!!, "The huge spear flies through the air and screams down directly into the Khazard stronghold. A deafening crash echoes over the battlefield as the front entrance is reduced to rubble.") - setQuestStage(player!!, TreeGnomeVillage.questName, 31) + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 31) } else -> sendDialogue(player!!, "The huge spear completely misses the Khazard stronghold!") } diff --git a/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt index 083066d20..e758479a2 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt @@ -1,30 +1,32 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import org.rs09.consts.Items import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class CommanderMontaiDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) if (questStage == 10) { when(stage) { 0 -> playerl("Hello.").also { stage++ } - 1 -> npcl("Hello traveller, are you here to help or just to watch?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello traveller, are you here to help or just to watch?").also { stage++ } 2 -> playerl("I've been sent by King Bolren to retrieve the orb of protection.").also { stage++ } - 3 -> npcl("Excellent we need all the help we can get.").also { stage++ } - 4 -> npcl("I'm Commander Montai. The orb is in the Khazard stronghold to the north, but until we weaken their defences we can't get close.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Excellent we need all the help we can get.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "I'm Commander Montai. The orb is in the Khazard stronghold to the north, but until we weaken their defences we can't get close.").also { stage++ } 5 -> playerl("What can I do?").also { stage++ } - 6 -> npcl("Firstly we need to strengthen our own defences. We desperately need wood to make more battlements, once the battlements are gone it's all over. Six loads of normal logs should do it.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Firstly we need to strengthen our own defences. We desperately need wood to make more battlements, once the battlements are gone it's all over. Six loads of normal logs should do it.").also { stage++ } 7 -> options("Ok, I'll gather some wood.", "Sorry, I no longer want to be involved.").also { stage++ } 8 -> when (buttonID) { 1 -> playerl("Ok, I'll gather some wood.").also { stage = 10 } 2 -> playerl("Sorry, I no longer want to be involved.").also { stage = 9 } } - 9 -> npcl("That's a shame, we could have done with your help.").also { stage = END_DIALOGUE } - 10 -> npcl("Please be as quick as you can, I don't know how much longer we can hold out.").also { - setQuestStage(player!!, TreeGnomeVillage.questName, 20) + 9 -> npcl(FacialExpression.OLD_NORMAL, "That's a shame, we could have done with your help.").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.OLD_NORMAL, "Please be as quick as you can, I don't know how much longer we can hold out.").also { + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 20) stage = END_DIALOGUE } } @@ -32,73 +34,73 @@ class CommanderMontaiDialogue : DialogueFile(){ if(inInventory(player!!, Items.LOGS_1511,6)){ when(stage) { 0 -> playerl("Hello.").also { stage++ } - 1 -> npcl("Hello again, we're still desperate for wood soldier.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello again, we're still desperate for wood soldier.").also { stage++ } 2 -> playerl("I have some here. (You give six loads of logs to the commander.)").also{ stage++ } 3 -> { // Remove the 6 normal logs for(i in 1..6) { removeItem(player!!,Items.LOGS_1511) } - setQuestStage(player!!, TreeGnomeVillage.questName, 25) - npcl("That's excellent, now we can make more defensive battlements. Give me a moment to organize the troops and then come speak to me. I'll inform you of our next phase of attack.") + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 25) + npcl(FacialExpression.OLD_NORMAL, "That's excellent, now we can make more defensive battlements. Give me a moment to organize the troops and then come speak to me. I'll inform you of our next phase of attack.") stage = END_DIALOGUE } } } else { when(stage) { 0 -> playerl("Hello.").also { stage++ } - 1 -> npcl("Hello again, we're still desperate for wood soldier. We need six loads of normal logs.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello again, we're still desperate for wood soldier. We need six loads of normal logs.").also { stage++ } 2 -> playerl("I'll see what I can do.").also { stage++ } - 3 -> npcl("Thank you.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Thank you.").also { stage = END_DIALOGUE } } } } else if (questStage == 25) { when(stage) { 0 -> playerl("How are you doing Montai?").also { stage++ } - 1 -> npcl("We're hanging in there soldier. For the next phase of our attack we need to breach their stronghold.").also { stage++ } - 2 -> npcl("The ballista can break through the stronghold wall, and then we can advance and seize back the orb.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "We're hanging in there soldier. For the next phase of our attack we need to breach their stronghold.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "The ballista can break through the stronghold wall, and then we can advance and seize back the orb.").also { stage++ } 3 -> playerl("So what's the problem?").also { stage++ } - 4 -> npcl("From this distance we can't get an accurate enough shot. We need the correct coordinates of the stronghold for a direct hit. I've sent out three tracker gnomes to gather them.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "From this distance we can't get an accurate enough shot. We need the correct coordinates of the stronghold for a direct hit. I've sent out three tracker gnomes to gather them.").also { stage++ } 5 -> playerl("Have they returned?").also { stage++ } - 6 -> npcl("I'm afraid not, and we're running out of time. I need you to go into the heart of the battlefield, find the trackers, and bring back the coordinates.").also { stage++ } - 7 -> npcl("Do you think you can do it?").also { stage++ } + 6 -> npcl(FacialExpression.OLD_NORMAL, "I'm afraid not, and we're running out of time. I need you to go into the heart of the battlefield, find the trackers, and bring back the coordinates.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Do you think you can do it?").also { stage++ } 8 -> options("No, I've had enough of your battle.", "I'll try my best.").also { stage++ } 9 -> when(buttonID) { 1 -> playerl("No, I've had enough of your battle.").also { stage = 10 } 2 -> playerl("I'll try my best.").also { stage = 11 } } - 10 -> npcl("I understand, this isn't your fight.").also { stage = END_DIALOGUE } - 11 -> npcl("Thank you, you're braver than most.").also { stage++ } - 12 -> npcl("I don't know how long I will be able to hold out. Once you have the coordinates come back and fire the ballista right into those monsters.").also { stage++ } - 13 -> npcl("If you can retrieve the orb and bring safety back to my people, none of the blood spilled on this field will be in vain.").also { - setQuestStage(player!!, TreeGnomeVillage.questName, 30) + 10 -> npcl(FacialExpression.OLD_NORMAL, "I understand, this isn't your fight.").also { stage = END_DIALOGUE } + 11 -> npcl(FacialExpression.OLD_NORMAL, "Thank you, you're braver than most.").also { stage++ } + 12 -> npcl(FacialExpression.OLD_NORMAL, "I don't know how long I will be able to hold out. Once you have the coordinates come back and fire the ballista right into those monsters.").also { stage++ } + 13 -> npcl(FacialExpression.OLD_NORMAL, "If you can retrieve the orb and bring safety back to my people, none of the blood spilled on this field will be in vain.").also { + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 30) stage = END_DIALOGUE } } } else if (questStage == 30) { when(stage) { 0 -> playerl("Hello.").also { stage++ } - 1 -> npcl("Hello warrior. We need the coordinates for a direct hit from the ballista.").also { stage++ } - 2 -> npcl("Once you have a direct hit you will be able to enter the stronghold and retrieve the orb.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello warrior. We need the coordinates for a direct hit from the ballista.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Once you have a direct hit you will be able to enter the stronghold and retrieve the orb.").also { stage = END_DIALOGUE } } } else if (questStage == 31) { if(inInventory(player!!,Items.ORB_OF_PROTECTION_587)){ when(stage) { 0 -> playerl("I have the orb of protection.").also { stage++ } - 1 -> npcl("Incredible, for a human you really are something.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_HAPPY, "Incredible, for a human you really are something.").also { stage++ } 2 -> playerl("Thanks... I think!").also { stage++ } - 3 -> npcl("I'll stay here with my troops and try and hold Khazard's men back. You return the orb to the gnome village. Go as quick as you can, the village is still unprotected.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_NORMAL, "I'll stay here with my troops and try and hold Khazard's men back. You return the orb to the gnome village. Go as quick as you can, the village is still unprotected.").also { stage = END_DIALOGUE } } } else { when(stage) { 0 -> playerl("I've breached the stronghold.").also { stage++ } - 1 -> npcl("I saw, that was a beautiful sight. The Khazard troops didn't know what hit them.").also { stage++ } - 2 -> npcl("Now is the time to retrieve the orb. It's all in your hands. I'll be praying for you.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "I saw, that was a beautiful sight. The Khazard troops didn't know what hit them.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Now is the time to retrieve the orb. It's all in your hands. I'll be praying for you.").also { stage = END_DIALOGUE } } } } else if (questStage != 0){ when(stage) { 0 -> playerl("Hello Montai, how are you?").also { stage++ } - 1 -> npcl("I'm ok, this battle is going to take longer to win than I expected. The Khazard troops won't give up even without the orb.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "I'm ok, this battle is going to take longer to win than I expected. The Khazard troops won't give up even without the orb.").also { stage++ } 2 -> playerl("Hang in there.").also { stage = END_DIALOGUE } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt index 61636b90f..708033a0d 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import core.game.component.Component import core.game.node.entity.player.Player @@ -10,7 +11,7 @@ import org.rs09.consts.Items import core.game.dialogue.DialogueFile import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeEntrance import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeVillage -import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.questName +import core.game.dialogue.FacialExpression import core.game.world.GameWorld.Pulser import core.tools.END_DIALOGUE @@ -38,37 +39,37 @@ class ElkoyDialogue : DialogueFile(){ }) } override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) val locY = player!!.location.y val followLocation = if(locY > 3161) "village" else "exit" when { inInventory(player!!, Items.ORBS_OF_PROTECTION_588) && followLocation == "exit" -> { when(stage) { 0 -> playerl("Hello Elkoy. I have the orb.").also { stage++ } - 1 -> npcl("Take it to King Bolren, I'm sure he'll be pleased to see you.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_HAPPY, "Take it to King Bolren, I'm sure he'll be pleased to see you.").also { stage++ } 2 -> options("Alright, I'll do that.", "Can you guide me out of the maze now?").also { stage++ } 3 -> when(buttonID) { 1 -> playerl("Alright, I'll do that.").also { stage = END_DIALOGUE } 2 -> playerl("Can you guide me out of the maze now?").also { stage = 4 } } - 4 -> npcl("If you like, but please take the orb to King Bolren soon.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "If you like, but please take the orb to King Bolren soon.").also { stage++ } 5 -> { travelCutscene(player!!, mazeEntrance) stage++ } - 6 -> npcl("Here we are. Please don't lose the orb!").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Here we are. Please don't lose the orb!").also { stage = END_DIALOGUE } } } inInventory(player!!, Items.ORB_OF_PROTECTION_587) -> { when(stage) { 0 -> playerl("Hello Elkoy.").also { stage++ } - 1 -> npcl("You're back! And the orb?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "You're back! And the orb?").also { stage++ } 2 -> playerl("I have it here.").also { stage++ } 3 -> { if(locY > 3161){ - npcl("You're our saviour. Please return it to the village and we are all saved. Would you like me to show you the way to the village?").also { stage++ } + npcl(FacialExpression.OLD_NORMAL, "You're our saviour. Please return it to the village and we are all saved. Would you like me to show you the way to the village?").also { stage++ } } else { - npcl("Take the orb to King Bolren, I'm sure he'll be pleased to see you.").also { stage = END_DIALOGUE } + npcl(FacialExpression.OLD_NORMAL, "Take the orb to King Bolren, I'm sure he'll be pleased to see you.").also { stage = END_DIALOGUE } } } 4 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } @@ -76,24 +77,24 @@ class ElkoyDialogue : DialogueFile(){ 1 -> playerl("Yes please.").also { stage = 7 } 2 -> playerl("No thanks Elkoy.").also { stage = 6 } } - 6 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Ok then, take care.").also { stage = END_DIALOGUE } 7 -> travelCutscene(player!!, mazeVillage).also { stage++ } - 8 -> npcl("Here we are. Take the orb to King Bolren, I'm sure he'll be pleased to see you.").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.OLD_NORMAL, "Here we are. Take the orb to King Bolren, I'm sure he'll be pleased to see you.").also { stage = END_DIALOGUE } } } inInventory(player!!, Items.ORBS_OF_PROTECTION_588) || questStage == 100 -> { when(stage) { 0 -> playerl("Hello Elkoy.").also { stage++ } - 1 -> npcl("You truly are a hero.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_HAPPY, "You truly are a hero.").also { stage++ } 2 -> playerl("Thanks.").also { stage++ } - 3 -> npcl("You saved us by defeating the warlord. I'm humbled and wish you well.").also { stage++ } - 4 -> npcl("Would you like me to show you the way to the ${followLocation}?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NORMAL, "You saved us by defeating the warlord. I'm humbled and wish you well.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "Would you like me to show you the way to the ${followLocation}?").also { stage++ } 5 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } 6 -> when(buttonID) { 1 -> playerl("Yes please.").also { stage = 8 } 2 -> playerl("No thanks Elkoy.").also { stage = 7 } } - 7 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Ok then, take care.").also { stage = END_DIALOGUE } 8 -> { if(followLocation == "village") { travelCutscene(player!!, mazeVillage) @@ -104,33 +105,33 @@ class ElkoyDialogue : DialogueFile(){ stage++ } } - 9 -> npcl("Here we are. Have a safe journey.").also { stage = END_DIALOGUE } - 10 -> npcl("Here we are. Feel free to have a look around.").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.OLD_NORMAL, "Here we are. Have a safe journey.").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.OLD_NORMAL, "Here we are. Feel free to have a look around.").also { stage = END_DIALOGUE } } } questStage == 0 -> { when(stage) { 0 -> playerl("Hello there.").also { stage++ } - 1 -> npcl("Hello, welcome to our maze. I'm Elkoy the tree gnome.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello, welcome to our maze. I'm Elkoy the tree gnome.").also { stage++ } 2 -> playerl("I haven't heard of your sort.").also { stage++ } - 3 -> npcl("There's not many of us left. Once you could find tree gnomes anywhere in the world, now we hide in small groups to avoid capture.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_SAD, "There's not many of us left. Once you could find tree gnomes anywhere in the world, now we hide in small groups to avoid capture.").also { stage++ } 4 -> playerl("Capture from whom?").also { stage++ } - 5 -> npcl("Tree gnomes have been hunted for so called 'fun' since as long as I can remember.").also { stage++ } - 6 -> npcl("Our main threat nowadays are General Khazard's troops. They know no mercy, but are also very dense. They'll never find their way through our maze.").also { stage++ } - 7 -> npcl("Have fun.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.OLD_NORMAL, "Tree gnomes have been hunted for so called 'fun' since as long as I can remember.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Our main threat nowadays are General Khazard's troops. They know no mercy, but are also very dense. They'll never find their way through our maze.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Have fun.").also { stage = END_DIALOGUE } } } questStage in 1..39 -> { when (stage) { - 0 -> npcl("Oh my! The orb, they have the orb. We're doomed.").also { stage++ } + 0 -> npcl(FacialExpression.OLD_DISTRESSED, "Oh my! The orb, they have the orb. We're doomed.").also { stage++ } 1 -> playerl("Perhaps I'll be able to get it back for you.").also { stage++ } - 2 -> npcl("Would you like me to show you the way to the ${followLocation}?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Would you like me to show you the way to the ${followLocation}?").also { stage++ } 3 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } 4 -> when (buttonID) { 1 -> playerl("Yes please.").also { stage = 6 } 2 -> playerl("No thanks Elkoy.").also { stage = 5 } } - 5 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.OLD_NORMAL, "Ok then, take care.").also { stage = END_DIALOGUE } 6 -> { if(followLocation == "village") travelCutscene(player!!, mazeVillage) @@ -138,20 +139,20 @@ class ElkoyDialogue : DialogueFile(){ travelCutscene(player!!, mazeEntrance) stage++ } - 7 -> npcl("Here we are. I hope you get the orb back soon.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Here we are. I hope you get the orb back soon.").also { stage = END_DIALOGUE } } } questStage == 40 -> { when(stage) { 0 -> playerl("Hello Elkoy.").also { stage++ } - 1 -> npcl("Did you hear? Khazard's men have pillaged the village! They slaughtered many, and took the other orbs in an attempt to lead us out of the maze. When will the misery end?").also { stage++ } - 2 -> npcl("Would you like me to show you the way to the ${followLocation}?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Did you hear? Khazard's men have pillaged the village! They slaughtered many, and took the other orbs in an attempt to lead us out of the maze. When will the misery end?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Would you like me to show you the way to the ${followLocation}?").also { stage++ } 3 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } 4 -> when(buttonID) { 1 -> playerl("Yes please.").also { stage = 6 } 2 -> playerl("No thanks Elkoy.").also { stage = 5 } } - 5 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.OLD_NORMAL, "Ok then, take care.").also { stage = END_DIALOGUE } 6 -> { if(followLocation == "village") { travelCutscene(player!!, mazeVillage) @@ -161,8 +162,8 @@ class ElkoyDialogue : DialogueFile(){ stage++ } } - 7 -> npcl("Please try to get our orbs back for us, otherwise the village is doomed!").also { stage = END_DIALOGUE } - 8 -> npcl("Here we are. Despite what has happened here, I hope you feel welcome.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Please try to get our orbs back for us, otherwise the village is doomed!").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.OLD_NORMAL, "Here we are. Despite what has happened here, I hope you feel welcome.").also { stage = END_DIALOGUE } } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt index a4d3df749..b70b6449b 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt @@ -1,12 +1,13 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.getQuestStage import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE class KhazardWarlordDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) if(questStage == 31){ when(stage) { 0 -> playerl("Hello there.").also { stage++ } diff --git a/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt index f1a246287..736612730 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.addItemOrDrop import core.api.getQuestStage import core.api.sendDialogue @@ -27,7 +28,7 @@ class KhazardWarlordNPC(id: Int = 0, location: Location? = null) : AbstractNPC(i } override fun finalizeDeath(killer: Entity?) { - if(getQuestStage(killer as Player, TreeGnomeVillage.questName) == 40) { + if(getQuestStage(killer as Player, Quests.TREE_GNOME_VILLAGE) == 40) { sendDialogue(killer,"As the warlord falls to the ground, a ghostly vapour floats upwards from his battle-worn armour. You search his satchel and find the orbs of protection.") addItemOrDrop(killer, Items.ORBS_OF_PROTECTION_588) } diff --git a/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt index 169f6b016..89f6d5c11 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import core.game.system.task.Pulse import core.game.world.map.Location @@ -9,49 +10,49 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.dialogue.DialogueFile import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeEntrance -import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.questName +import core.game.dialogue.FacialExpression import core.game.world.GameWorld import core.tools.END_DIALOGUE class KingBolrenDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) when { questStage < 10 -> { when (stage) { 0 -> playerl("Hello.").also { stage++ } - 1 -> npcl("Well hello stranger. My name's Bolren, I'm the king of the tree gnomes.").also { stage++ } - 2 -> npcl("I'm surprised you made it in, maybe I made the maze too easy.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Well hello stranger. My name's Bolren, I'm the king of the tree gnomes.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "I'm surprised you made it in, maybe I made the maze too easy.").also { stage++ } 3 -> playerl("Maybe.").also { stage++ } - 4 -> npcl("I'm afraid I have more serious concerns at the moment. Very serious.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "I'm afraid I have more serious concerns at the moment. Very serious.").also { stage++ } 5 -> options("I'll leave you to it then.", "Can I help at all?").also { stage++ } 6 -> when (buttonID) { 1 -> playerl("I'll leave you to it then.").also { stage = 7 } 2 -> playerl("Can I help at all?").also { stage = 8 } } - 7 -> npcl("Ok, take care.").also { stage = END_DIALOGUE } - 8 -> npcl("I'm glad you asked.").also { stage++ } - 9 -> npcl("The truth is my people are in grave danger. We have always been protected by the Spirit Tree. No creature of dark can harm us while its three orbs are in place.").also { stage++ } - 10 -> npcl("We are not a violent race, but we fight when we must. Many gnomes have fallen battling the dark forces of Khazard to the North.").also { stage++ } - 11 -> npcl("We became desperate, so we took one orb of protection to the battlefield. It was a foolish move.").also { stage++ } - 12 -> npcl("Khazard troops seized the orb. Now we are completely defenceless.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Ok, take care.").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.OLD_NORMAL, "I'm glad you asked.").also { stage++ } + 9 -> npcl(FacialExpression.OLD_SAD, "The truth is my people are in grave danger. We have always been protected by the Spirit Tree. No creature of dark can harm us while its three orbs are in place.").also { stage++ } + 10 -> npcl(FacialExpression.OLD_SAD, "We are not a violent race, but we fight when we must. Many gnomes have fallen battling the dark forces of Khazard to the North.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_SAD, "We became desperate, so we took one orb of protection to the battlefield. It was a foolish move.").also { stage++ } + 12 -> npcl(FacialExpression.OLD_NORMAL, "Khazard troops seized the orb. Now we are completely defenceless.").also { stage++ } 13 -> playerl("How can I help?").also { stage++ } - 14 -> npcl("You would be a huge benefit on the battlefield. If you would go there and try to retrieve the orb, my people and I will be forever grateful.").also { stage++ } + 14 -> npcl(FacialExpression.OLD_NORMAL,"You would be a huge benefit on the battlefield. If you would go there and try to retrieve the orb, my people and I will be forever grateful.").also { stage++ } 15 -> options("I would be glad to help.", "I'm sorry but I won't be involved.").also { stage++ } 16 -> when (buttonID) { 1 -> playerl("I would be glad to help.").also { stage = 18 } 2 -> playerl("I'm sorry but I won't be involved.").also { stage = 17 } } - 17 -> npcl("Ok then, travel safe.").also { stage = END_DIALOGUE } - 18 -> npcl("Thank you. The battlefield is to the north of the maze. Commander Montai will inform you of their current situation.").also { stage++ } - 19 -> npcl("That is if he's still alive.").also { stage++ } - 20 -> npcl("My assistant shall guide you out. Good luck friend, try your best to return the orb.").also { + 17 -> npcl(FacialExpression.OLD_NORMAL, "Ok then, travel safe.").also { stage = END_DIALOGUE } + 18 -> npcl(FacialExpression.OLD_NORMAL, "Thank you. The battlefield is to the north of the maze. Commander Montai will inform you of their current situation.").also { stage++ } + 19 -> npcl(FacialExpression.OLD_NORMAL, "That is if he's still alive.").also { stage++ } + 20 -> npcl(FacialExpression.OLD_NORMAL, "My assistant shall guide you out. Good luck friend, try your best to return the orb.").also { stage++ } 21 -> { teleport(player!!, mazeEntrance) - sendNPCDialogue(player!!, NPCs.ELKOY_5179, "We're out of the maze now. Please hurry, we must have the orb if we are to survive.") - setQuestStage(player!!, questName, 10) + sendNPCDialogue(player!!, NPCs.ELKOY_5179, "We're out of the maze now. Please hurry, we must have the orb if we are to survive.", FacialExpression.OLD_NORMAL) + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 10) stage = END_DIALOGUE } } @@ -59,7 +60,7 @@ class KingBolrenDialogue : DialogueFile() { questStage < 31 -> { when (stage) { 0 -> playerl("Hello Bolren.").also { stage++ } - 1 -> npcl("Hello traveller, we must retrieve the orb. It's being held by Khazard troops north of here.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello traveller, we must retrieve the orb. It's being held by Khazard troops north of here.").also { stage++ } 2 -> playerl("Ok, I'll try my best.").also { stage = END_DIALOGUE } } } @@ -67,32 +68,32 @@ class KingBolrenDialogue : DialogueFile() { if(inInventory(player!!,Items.ORB_OF_PROTECTION_587)){ when(stage) { 0 -> playerl("I have the orb.").also { stage++ } - 1 -> npcl("Oh my... The misery, the horror!").also { stage++ } + 1 -> npcl(FacialExpression.OLD_DISTRESSED, "Oh my... The misery, the horror!").also { stage++ } 2 -> playerl("King Bolren, are you OK?").also { stage++ } - 3 -> npcl("Thank you traveller, but it's too late. We're all doomed.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_DISTRESSED, "Thank you traveller, but it's too late. We're all doomed.").also { stage++ } 4 -> playerl("What happened?").also { stage++ } - 5 -> npcl("They came in the night. I don't know how many, but enough.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DISTRESSED, "They came in the night. I don't know how many, but enough.").also { stage++ } 6 -> playerl("Who?").also { stage++ } - 7 -> npcl("Khazard troops. They slaughtered anyone who got in their way. Women, children, my wife.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_DISTRESSED, "Khazard troops. They slaughtered anyone who got in their way. Women, children, my wife.").also { stage++ } 8 -> playerl("I'm sorry.").also { stage++ } - 9 -> npcl("They took the other orbs, now we are defenceless.").also { stage++ } + 9 -> npcl(FacialExpression.OLD_BOWS_HEAD_SAD, "They took the other orbs, now we are defenceless.").also { stage++ } 10 -> playerl("Where did they take them?").also { stage++ } - 11 -> npcl("They headed north of the stronghold. A warlord carries the orbs.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_NORMAL, "They headed north of the stronghold. A warlord carries the orbs.").also { stage++ } 12 -> options("I will find the warlord and bring back the orbs.", "I'm sorry but I can't help.").also { stage++ } 13 -> when(buttonID) { 1 -> playerl("I will find the warlord and bring back the orbs.").also { stage = 15 } 2 -> playerl("I'm sorry but I can't help.").also { stage = 14 } } - 14 -> npcl("I understand, this isn't your battle.").also { stage = END_DIALOGUE } - 15 -> npcl("You are brave, but this task will be tough even for you. I wish you the best of luck. Once again you are our only hope.").also { stage++ } - 16 -> npcl("I will safeguard this orb and pray for your safe return. My assistant will guide you out.").also { + 14 -> npcl(FacialExpression.OLD_NORMAL, "I understand, this isn't your battle.").also { stage = END_DIALOGUE } + 15 -> npcl(FacialExpression.OLD_NORMAL, "You are brave, but this task will be tough even for you. I wish you the best of luck. Once again you are our only hope.").also { stage++ } + 16 -> npcl(FacialExpression.OLD_NORMAL, "I will safeguard this orb and pray for your safe return. My assistant will guide you out.").also { stage++ } 17 -> { if(removeItem(player!!,Items.ORB_OF_PROTECTION_587)){ teleport(player!!,mazeEntrance) - setQuestStage(player!!, questName,40) - sendNPCDialogue(player!!, NPCs.ELKOY_5179, "Good luck friend.") + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 40) + sendNPCDialogue(player!!, NPCs.ELKOY_5179, "Good luck friend.", FacialExpression.OLD_NORMAL) } stage = END_DIALOGUE } @@ -100,9 +101,9 @@ class KingBolrenDialogue : DialogueFile() { } else { when(stage) { 0 -> playerl("Hello Bolren.").also { stage++ } - 1 -> npcl("Do you have the orb?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Do you have the orb?").also { stage++ } 2 -> playerl("No, I'm afraid not.").also { stage++ } - 3 -> npcl("Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } } } } @@ -110,12 +111,12 @@ class KingBolrenDialogue : DialogueFile() { if(inInventory(player!!,Items.ORBS_OF_PROTECTION_588)){ when(stage) { 0 -> playerl("Bolren, I have returned.").also { stage++ } - 1 -> npcl("You made it back! Do you have the orbs?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "You made it back! Do you have the orbs?").also { stage++ } 2 -> playerl("I have them here.").also { stage++ } - 3 -> npcl("Hooray, you're amazing. I didn't think it was possible but you've saved us.").also { stage++ } - 4 -> npcl("Once the orbs are replaced we will be safe once more. We must begin the ceremony immediately.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_HAPPY, "Hooray, you're amazing. I didn't think it was possible but you've saved us.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "Once the orbs are replaced we will be safe once more. We must begin the ceremony immediately.").also { stage++ } 5 -> playerl("What does the ceremony involve?").also { stage++ } - 6 -> npcl("The spirit tree has looked over us for centuries. Now we must pay our respects.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_NORMAL, "The spirit tree has looked over us for centuries. Now we must pay our respects.").also { stage++ } 7 -> sendDialogue(player!!,"The gnomes begin to chant. Meanwhile, King Bolren holds the orbs of protection out in front of him.").also { stage++ } 8 -> { // Orbs fly up, gnomes chant, spirit tree animates @@ -158,7 +159,7 @@ class KingBolrenDialogue : DialogueFile() { }) // This loops back to the start of the handle.. if(removeItem(player!!,Items.ORBS_OF_PROTECTION_588)){ - setQuestStage(player!!,questName,99) + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 99) } stage = 0 } @@ -166,31 +167,36 @@ class KingBolrenDialogue : DialogueFile() { } else { when(stage) { 0 -> playerl("Bolren, I have returned.").also { stage++ } - 1 -> npcl("You made it back! Do you have the orbs?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "You made it back! Do you have the orbs?").also { stage++ } 2 -> playerl("No, I'm afraid not.").also { stage++ } - 3 -> npcl("Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } } } } questStage == 99 -> { when(stage){ - 0 -> npcl("Now at last my people are safe once more. We can live in peace again.").also { stage++ } + 0 -> npcl(FacialExpression.OLD_NORMAL, "Now at last my people are safe once more. We can live in peace again.").also { stage++ } 1 -> playerl("I'm pleased I could help.").also { stage++ } - 2 -> npcl("You are modest brave traveller.").also { stage++ } - 3 -> npcl("Please, for your efforts take this amulet. It's made from the same sacred stone as the orbs of protection. It will help keep you safe on your journeys.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "You are modest brave traveller.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Please, for your efforts take this amulet. It's made from the same sacred stone as the orbs of protection. It will help keep you safe on your journeys.").also { stage++ } 4 -> playerl("Thank you King Bolren.").also { stage++ } - 5 -> npcl("The tree has many other powers, some of which I cannot reveal. As a friend of the gnome people, I can now allow you to use the tree's magic to teleport to other trees grown from related seeds.").also { - finishQuest(player!!,questName) + 5 -> npcl(FacialExpression.OLD_NORMAL, "The tree has many other powers, some of which I cannot reveal. As a friend of the gnome people, I can now allow you to use the tree's magic to teleport to other trees grown from related seeds.").also { + finishQuest(player!!, Quests.TREE_GNOME_VILLAGE) stage = END_DIALOGUE } } } - isQuestComplete(player!!, questName) -> { + isQuestComplete(player!!, Quests.TREE_GNOME_VILLAGE) -> { when(stage) { - 0 -> playerl("Hello Bolren.").also { stage++ } - 1 -> npcl("Thank you for your help traveler.").also { stage = END_DIALOGUE } + 0 -> playerl("Hello again Bolren.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Well hello, it's good to see you again.").also { stage = if (hasAnItem(player!!, Items.GNOME_AMULET_589).container != null) END_DIALOGUE else 2 } + 2 -> playerl("I've lost my amulet.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Oh dear. Here, take another. We are truly indebted to you.").also { + addItemOrDrop(player!!, Items.GNOME_AMULET_589) + stage = END_DIALOGUE + } } } } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt index 7f29582d1..2571454a9 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt @@ -1,17 +1,18 @@ package content.region.kandarin.quest.tree import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class LieutenantSchepburDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { when(stage) { - 0 -> npcl("Move into position lads! eh? Who are you and what do you want?").also { stage++ } + 0 -> npcl(FacialExpression.OLD_NORMAL, "Move into position lads! eh? Who are you and what do you want?").also { stage++ } 1 -> playerl("Who are you then?").also { stage++ } - 2 -> npcl("Lieutenant Schepbur, commanding officer of the new Armoured Tortoise Regiment.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Lieutenant Schepbur, commanding officer of the new Armoured Tortoise Regiment.").also { stage++ } 3 -> playerl("There's only two tortoises here, that's hardly a regiment.").also { stage++ } - 4 -> npcl("This is just the beginning! Gnome breeders and trainers are already working to expand the number of units. Soon we'll have hundreds of these beauties, nay thousands! And they will not only carry mages and").also { stage++ } - 5 -> npcl("archers but other fiendish weapons of destruction of gnome devising. An army of giant tortoises will march upon this battlefield and rain the fire of our wrath upon all our enemies! Nothing will be able to stop us!").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "This is just the beginning! Gnome breeders and trainers are already working to expand the number of units. Soon we'll have hundreds of these beauties, nay thousands! And they will not only carry mages and").also { stage++ } + 5 -> npcl(FacialExpression.OLD_NORMAL, "archers but other fiendish weapons of destruction of gnome devising. An army of giant tortoises will march upon this battlefield and rain the fire of our wrath upon all our enemies! Nothing will be able to stop us!").also { stage++ } 6 -> playerl("Oooookayy...... I'll leave you to it then....").also { stage = END_DIALOGUE } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt index b78813553..b6a0ff54c 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt @@ -1,13 +1,14 @@ package content.region.kandarin.quest.tree import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class LocalGnomeDialogue : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { when (stage) { 0 -> playerl("Hello little man.").also { stage++ } - 1 -> npcl("Little man stronger than big man. Hee hee, lardi dee, lardi da.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_LAUGH1, "Little man stronger than big man. Hee hee, lardi dee, lardi da.").also { stage = END_DIALOGUE } } } } \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt index f8cfde14e..3038fed58 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt @@ -1,47 +1,49 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.inInventory import core.api.getQuestStage import org.rs09.consts.Items import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class RemsaiDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) when { inInventory(player!!,Items.ORBS_OF_PROTECTION_588) -> { when(stage) { 0 -> playerl("I've returned.").also { stage++ } - 1 -> npcl("You're back, well done brave adventurer. Now the orbs are safe we can perform the ritual for the spirit tree. We can live in peace once again.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "You're back, well done brave adventurer. Now the orbs are safe we can perform the ritual for the spirit tree. We can live in peace once again.").also { stage = END_DIALOGUE } } } inInventory(player!!, Items.ORB_OF_PROTECTION_587) -> { when(stage) { 0 -> playerl("Hello Remsai.").also { stage++ } - 1 -> npcl("Hello, did you find the orb?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello, did you find the orb?").also { stage++ } 2 -> playerl("I have it here.").also { stage++ } - 3 -> npcl("You're our saviour.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_HAPPY, "You're our saviour.").also { stage = END_DIALOGUE } } } questStage < 40 -> { when(stage) { 0 -> playerl("Hello Remsai.").also { stage++ } - 1 -> npcl("Hello, did you find the orb?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hello, did you find the orb?").also { stage++ } 2 -> playerl("No, I'm afraid not.").also { stage++ } - 3 -> npcl("Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } } } questStage == 40 -> { when(stage) { 0 -> playerl("Are you ok?").also { stage++ } - 1 -> npcl("Khazard's men came. Without the orb we were defenceless. They killed many and then took our last hope, the other orbs. Now surely we're all doomed. Without them the spirit tree is useless.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_DISTRESSED, "Khazard's men came. Without the orb we were defenceless. They killed many and then took our last hope, the other orbs. Now surely we're all doomed. Without them the spirit tree is useless.").also { stage = END_DIALOGUE } } } questStage > 40 -> { when(stage) { 0 -> playerl("I've returned.").also { stage++ } - 1 -> npcl("You're back, well done brave adventurer. Now the orbs are safe we can perform the ritual for the spirit tree. We can live in peace once again.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "You're back, well done brave adventurer. Now the orbs are safe we can perform the ritual for the spirit tree. We can live in peace once again.").also { stage = END_DIALOGUE } } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt index b9b22bd34..d4a4919fb 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt @@ -1,43 +1,45 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import org.rs09.consts.Items import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class TrackerGnomeOneDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) when { questStage >= 40 -> { when (stage) { 0 -> playerl("Hello").also { stage++ } - 1 -> npcl("When will this battle end? I feel like I've been fighting forever.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_BOWS_HEAD_SAD, "When will this battle end? I feel like I've been fighting forever.").also { stage = END_DIALOGUE } } } questStage > 30 -> { if(inInventory(player!!, Items.ORB_OF_PROTECTION_587)){ when(stage) { 0 -> playerl("How are you tracker?").also { stage++ } - 1 -> npcl("Now we have the orb I'm much better. They won't stand a chance without it.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Now we have the orb I'm much better. They won't stand a chance without it.").also { stage = END_DIALOGUE } } } else { when(stage) { 0 -> playerl("Hello again.").also { stage++ } - 1 -> npcl("Well done, you've broken down their defences. This battle must be ours.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Well done, you've broken down their defences. This battle must be ours.").also { stage = END_DIALOGUE } } } } questStage == 30 -> { when (stage) { 0 -> playerl("Do you know the coordinates of the Khazard stronghold?").also { stage++ } - 1 -> npcl("I managed to get one, although it wasn't easy.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "I managed to get one, although it wasn't easy.").also { stage++ } 2 -> sendDialogue(player!!, "The gnome tells you the height coordinate.").also { setAttribute(player!!, "/save:treegnome:tracker1", true) stage++ } 3 -> playerl("Well done.").also { stage++ } - 4 -> npcl("The other two tracker gnomes should have the other coordinates if they're still alive.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "The other two tracker gnomes should have the other coordinates if they're still alive.").also { stage++ } 5 -> playerl("OK, take care.").also { stage = END_DIALOGUE } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt index 607e087d5..de00880e0 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt @@ -1,7 +1,9 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class TrackerGnomeThreeDialogue : DialogueFile(){ @@ -13,36 +15,36 @@ class TrackerGnomeThreeDialogue : DialogueFile(){ 4 to "My legs and your legs.") override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) when { questStage == 30 -> { when(stage) { 0 -> playerl("Are you OK?").also { stage++ } - 1 -> npcl("OK? Who's OK? Not me! Hee hee!").also { stage++ } + 1 -> npcl(FacialExpression.OLD_LAUGH1, "OK? Who's OK? Not me! Hee hee!").also { stage++ } 2 -> playerl("What's wrong?").also { stage++ } - 3 -> npcl("You can't see me, no one can. Monsters, demons, they're all around me!").also { stage++ } + 3 -> npcl(FacialExpression.OLD_LAUGH1, "You can't see me, no one can. Monsters, demons, they're all around me!").also { stage++ } 4 -> playerl("What do you mean?").also { stage++ } - 5 -> npcl("They're dancing, all of them, hee hee.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_LAUGH1, "They're dancing, all of them, hee hee.").also { stage++ } 6 -> sendDialogue(player!!,"He's clearly lost the plot.").also { stage++ } 7 -> playerl("Do you have the coordinate for the Khazard stronghold?").also { stage++ } - 8 -> npcl("Who holds the stronghold?").also { stage++ } + 8 -> npcl(FacialExpression.OLD_NORMAL, "Who holds the stronghold?").also { stage++ } 9 -> playerl("What?").also { stage++ } 10 -> { // Generate the x coordinate answer if(getAttribute(player!!,"treegnome:xcoord",0) == 0){ val answer = (1..4).random() - npcl(xcoordMap[answer]) + npcl(FacialExpression.OLD_NORMAL, xcoordMap[answer]) setAttribute(player!!,"/save:treegnome:xcoord",answer) } else { - npcl(xcoordMap[getAttribute(player!!,"treegnome:xcoord",1)]) + npcl(FacialExpression.OLD_NORMAL, xcoordMap[getAttribute(player!!,"treegnome:xcoord",1)]) } stage++ } 11 -> playerl("You're mad").also { stage++ } - 12 -> npcl("Dance with me, and Khazard's men are beat.").also { stage++ } + 12 -> npcl(FacialExpression.OLD_LAUGH1, "Dance with me, and Khazard's men are beat.").also { stage++ } 13 -> sendDialogue(player!!,"The toll of war has affected his mind.").also { stage++ } 14 -> playerl("I'll pray for you little man.").also { stage++ } - 15 -> npcl("All day we pray in the hay, hee hee.").also { + 15 -> npcl(FacialExpression.OLD_LAUGH1, "All day we pray in the hay, hee hee.").also { setAttribute(player!!, "/save:treegnome:tracker3", true) stage = END_DIALOGUE } @@ -51,13 +53,13 @@ class TrackerGnomeThreeDialogue : DialogueFile(){ questStage == 31 -> { when(stage) { 0 -> playerl("Hello again.").also { stage++ } - 1 -> npcl("Don't talk to me, you can't see me. No one can, just the demons.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_BOWS_HEAD_SAD, "Don't talk to me, you can't see me. No one can, just the demons.").also { stage = END_DIALOGUE } } } questStage > 31 -> { when(stage) { 0 -> playerl("Hello").also { stage++ } - 1 -> npcl("I feel dizzy, where am I? Oh dear, oh dear I need some rest.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "I feel dizzy, where am I? Oh dear, oh dear I need some rest.").also { stage++ } 2 -> playerl("I think you do.").also { stage = END_DIALOGUE } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt index f17211fd2..d4bbd63c0 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt @@ -1,47 +1,49 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import org.rs09.consts.Items import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE class TrackerGnomeTwoDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - val questStage = getQuestStage(player!!, TreeGnomeVillage.questName) + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) when { questStage == 30 -> { when (stage) { 0 -> playerl("Are you OK?").also { stage++ } - 1 -> npcl("They caught me spying on the stronghold. They beat and tortured me.").also { stage++ } - 2 -> npcl("But I didn't crack. I told them nothing. They can't break me!").also { stage++ } + 1 -> npcl(FacialExpression.OLD_DISTRESSED, "They caught me spying on the stronghold. They beat and tortured me.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_LAUGH1, "But I didn't crack. I told them nothing. They can't break me!").also { stage++ } 3 -> playerl("I'm sorry little man.").also { stage++ } - 4 -> npcl("Don't be. I have the position of the stronghold!").also { stage++ } + 4 -> npcl(FacialExpression.OLD_LAUGH1, "Don't be. I have the position of the stronghold!").also { stage++ } 5 -> sendDialogue(player!!, "The gnome tells you the y coordinate.").also { setAttribute(player!!, "/save:treegnome:tracker2", true) stage++ } 6 -> playerl("Well done.").also { stage++ } - 7 -> npcl("Now leave before they find you and all is lost.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Now leave before they find you and all is lost.").also { stage++ } 8 -> playerl("Hang in there.").also { stage++ } - 9 -> npcl("Go!").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.OLD_NORMAL, "Go!").also { stage = END_DIALOGUE } } } questStage >= 40 -> { when(stage) { 0 -> playerl("Hello").also { stage++ } - 1 -> npcl("When will this battle end? I feel like I've been locked up my whole life.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_DISTRESSED, "When will this battle end? I feel like I've been locked up my whole life.").also { stage = END_DIALOGUE } } } questStage > 30 -> { if(inInventory(player!!,Items.ORB_OF_PROTECTION_587)){ when(stage) { 0 -> playerl("How are you tracker?").also { stage++ } - 1 -> npcl("Now we have the orb I'm much better. Soon my comrades will come and free me.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Now we have the orb I'm much better. Soon my comrades will come and free me.").also { stage = END_DIALOGUE } } } else { when(stage) { 0 -> playerl("Hello again.").also { stage++ } - 1 -> npcl("Well done, you've broken down their defences. This battle must be ours.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Well done, you've broken down their defences. This battle must be ours.").also { stage = END_DIALOGUE } } } } diff --git a/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt index a87e2ca96..14f04896f 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt @@ -8,9 +8,10 @@ import core.game.node.entity.skill.Skills import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable -class TreeGnomeVillage: Quest("Tree Gnome Village", 125, 124, 2, 111, 0, 1, 9) { +class TreeGnomeVillage: Quest(Quests.TREE_GNOME_VILLAGE, 125, 124, 2, 111, 0, 1, 9) { override fun newInstance(`object`: Any?): Quest { return this } @@ -91,6 +92,5 @@ class TreeGnomeVillage: Quest("Tree Gnome Village", 125, 124, 2, 111, 0, 1, 9) companion object { val mazeVillage = Location(2515,3159,0) val mazeEntrance = Location(2504,3192,0) - const val questName = "Tree Gnome Village" } } \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt index f57509046..71471bf43 100644 --- a/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt +++ b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt @@ -1,5 +1,6 @@ package content.region.kandarin.quest.tree +import content.data.Quests import core.api.* import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player @@ -92,17 +93,25 @@ class TreeGnomeVillageListeners : InteractionListener { return@on true } on(closedChest, IntType.SCENERY, "open"){ player, node -> - SceneryBuilder.replace(node.asScenery(), Scenery(openedChest, node.location, node.asScenery().rotation),10) + replaceScenery(node.asScenery(), openedChest, -1) val upperGuard: NPC = RegionManager.getNpc(player.location, NPCs.KHAZARD_COMMANDER_478, 6) ?: return@on true upperGuard.sendChat("Oi. You! Get out of there.") upperGuard.attack(player) return@on true } on(openedChest, IntType.SCENERY, "search"){ player, _ -> - if(!inInventory(player,Items.ORB_OF_PROTECTION_587)){ - sendDialogue(player,"You search the chest. Inside you find the gnomes' stolen orb of protection.") - addItemOrDrop(player,Items.ORB_OF_PROTECTION_587) + if (getQuestStage(player, Quests.TREE_GNOME_VILLAGE) >= 31) { + if (!hasAnItem(player, Items.ORB_OF_PROTECTION_587).exists()) { + sendDialogue(player, "You search the chest. Inside you find the gnomes' stolen orb of protection.") + addItemOrDrop(player, Items.ORB_OF_PROTECTION_587) + return@on true + } } + sendMessage(player, "You search the chest but find nothing.") + return@on false + } + on(openedChest, IntType.SCENERY, "close"){ _, node -> + replaceScenery(node.asScenery(), closedChest, -1) return@on true } on(strongholdDoor, IntType.SCENERY, "open"){ player, node -> @@ -118,9 +127,7 @@ class TreeGnomeVillageListeners : InteractionListener { } fun squeezeThrough(player: Player){ - val squeezeAnim = Animation.create(3844) - - var dest = if (player.location.y >= 3161) + val dest = if (player.location.y >= 3161) player.location.transform(Direction.SOUTH, 1) else player.location.transform(Direction.NORTH, 1) @@ -132,7 +139,7 @@ class TreeGnomeVillageListeners : InteractionListener { val climbAnimation = Animation(839) val wallLoc = Location(2509,3253,0) override fun handle(componentID: Int, buttonID: Int) { - if(getQuestStage(player!!, TreeGnomeVillage.questName) > 30){ + if(getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) > 30){ val northSouth = if (player!!.location.y <= wallLoc.y) Direction.NORTH else Direction.SOUTH when(stage){ 0 -> sendDialogue(player!!,"The wall has been reduced to rubble. It should be possible to climb over the remains").also{ stage++ } diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java index 91285e36d..6d3f2bee6 100644 --- a/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.waterfall; +import content.data.Quests; import core.game.dialogue.DialogueInterpreter; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; @@ -27,7 +28,7 @@ public class AlmeraDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest(WaterFall.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); switch (stage) { /* Main dialogue sequence */ case 0: @@ -136,7 +137,7 @@ public class AlmeraDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - final Quest quest = player.getQuestRepository().getQuest(WaterFall.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); if (quest.getStage(player) == 100) { interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Almera."); stage = 7; @@ -146,4 +147,4 @@ public class AlmeraDialogue extends DialoguePlugin { } return true; } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt b/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt index c3f1bf63f..c4c0d1ef0 100644 --- a/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt +++ b/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt @@ -1,10 +1,12 @@ package content.region.kandarin.quest.waterfall +import content.data.Quests import content.global.handlers.iface.BookInterface import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -143,16 +145,17 @@ class BaxtorianBook : InteractionListener { ) private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) - if (player.questRepository.getQuest(WaterFall.NAME).getStage(player) == 20) { - player.questRepository.getQuest(WaterFall.NAME).setStage(player, 30) + if (player.questRepository.getQuest(Quests.WATERFALL_QUEST).getStage(player) == 20) { + player.questRepository.getQuest(Quests.WATERFALL_QUEST).setStage(player, 30) } return true } } override fun defineListeners() { - on(Items.BOOK_ON_BAXTORIAN_292, IntType.ITEM, "read") { player, _ -> + on(Items.BOOK_ON_BAXTORIAN_292, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java index 5e59576fe..e8c3262ad 100644 --- a/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java +++ b/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.waterfall; +import content.data.Quests; import core.game.dialogue.DialogueInterpreter; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; @@ -27,7 +28,7 @@ public class HudonDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest(WaterFall.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); switch (stage) { case 100: // Generic end to the dlg @@ -109,7 +110,7 @@ public class HudonDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - final Quest quest = player.getQuestRepository().getQuest(WaterFall.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); if (quest.getStage(player) >= 20) { interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So you're still here."); stage = 20; @@ -119,4 +120,4 @@ public class HudonDialogue extends DialoguePlugin { } return true; } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java b/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java index 467bef439..33030e29a 100644 --- a/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java +++ b/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java @@ -1,5 +1,6 @@ package content.region.kandarin.quest.waterfall; +import content.data.Quests; import core.plugin.Initializable; import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; @@ -13,17 +14,11 @@ import core.plugin.ClassScanner; */ @Initializable public class WaterFall extends Quest { - - /** - * The name of this quest. - */ - public static final String NAME = "Waterfall"; - /** * Constructs a new {@code WaterFall} {@code Object}. */ public WaterFall() { - super("Waterfall", 65, 64, 1, 65, 0, 1, 10); + super(Quests.WATERFALL_QUEST, 65, 64, 1, 65, 0, 1, 10); } @Override diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java index 5bcac3376..2a10ebe5c 100644 --- a/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java +++ b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java @@ -3,6 +3,7 @@ package content.region.kandarin.quest.waterfall; import java.util.ArrayList; import java.util.List; +import content.data.Quests; import core.cache.def.impl.ItemDefinition; import core.cache.def.impl.NPCDefinition; import core.cache.def.impl.SceneryDefinition; @@ -130,7 +131,7 @@ public final class WaterfallPlugin extends OptionHandler { @Override public boolean handle(final Player player, Node node, String option) { final int id = node.getId(); - final Quest quest = player.getQuestRepository().getQuest(WaterFall.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); if (quest == null) { player.sendMessage("Error! Waterfall quest cannot be found."); return true; @@ -141,7 +142,7 @@ public final class WaterfallPlugin extends OptionHandler { player.getPulseManager().run(new Pulse(2, player) { @Override public boolean pulse() { - if ((player.getEquipment().containsAtLeastOneItem(295) || player.getInventory().contains(295, 1)) || player.getQuestRepository().isComplete("Waterfall")) { + if ((player.getEquipment().containsAtLeastOneItem(295) || player.getInventory().contains(295, 1)) || player.getQuestRepository().isComplete(Quests.WATERFALL_QUEST)) { player.getPacketDispatch().sendMessage("You walk through the door."); player.teleport(new Location(2575, 9861)); } else { @@ -425,7 +426,7 @@ public final class WaterfallPlugin extends OptionHandler { public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); Item useditem = event.getUsedItem(); - final Quest quest = player.getQuestRepository().getQuest(WaterFall.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); final Scenery object = (Scenery) event.getUsedWith(); if (useditem.getId() == ROPE.getId() && object.getId() == 1996 || object.getId() == 1997) { diff --git a/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt b/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt index ca348787d..10ea45b99 100644 --- a/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt +++ b/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt @@ -3,12 +3,11 @@ package content.region.kandarin.quest.whileguthixsleeps import core.api.getQuestStage import core.api.hasLevelStat import core.api.isQuestComplete -import core.api.rewardXP import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills -import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * While Guthix Sleeps Quest @@ -18,17 +17,14 @@ import org.rs09.consts.Items * */ //@Initializable -class WhileGuthixSleeps : Quest("While Guthix Sleeps", 161, 160, 5,5491, 0, 1, 900) { +class WhileGuthixSleeps : Quest(Quests.WHILE_GUTHIX_SLEEPS, 161, 160, 5, 5491, 0, 1, 900) { - companion object { - const val questName = "While Guthix Sleeps" - } override fun drawJournal(player: Player, stage: Int) { super.drawJournal(player, stage) var line = 12 var stage = getStage(player) - var started = getQuestStage(player, questName) > 0 + var started = getQuestStage(player, Quests.WHILE_GUTHIX_SLEEPS) > 0 if (!started) { line(player, "I can start this quest by speaking to !!Radimus Erkle?? in the", line++, false) @@ -44,18 +40,43 @@ class WhileGuthixSleeps : Quest("While Guthix Sleeps", 161, 160, 5,5491, 0, 1, 9 line(player, "!!Level 65 Farming??", line++, hasLevelStat(player, Skills.FARMING, 65)) line(player, "!!Level 23 Summoning??", line++, hasLevelStat(player, Skills.SUMMONING, 23)) line(player, "I also need to have completed the following quests:", line++, false) - line(player, "!!Recipe for Disaster??", line++, isQuestComplete(player, "Recipe for Disaster")) - line(player, "!!Mourning's Ends Part II - The Temple of Light??", line++, isQuestComplete(player, "Mourning's End Part II")) - line(player, "!!Swan Song??", line++, isQuestComplete(player, "Swan Song")) - line(player, "!!Zogre Flesh Eaters??", line++, isQuestComplete(player, "Zogre Flesh Eaters")) - line(player, "!!Path of Glouphrie??", line++, isQuestComplete(player, "Path of Glouphrie")) - line(player, "!!Summer's End??", line++, isQuestComplete(player, "Summer's End")) - line(player, "!!Legends' Quest??", line++, isQuestComplete(player, "Legends' Quest")) - line(player, "!!Dream Mentor??", line++, isQuestComplete(player, "Dream Mentor")) - line(player, "!!Hand in the Sand??", line++, isQuestComplete(player, "The Hand in the Sand")) - line(player, "!!Tears of Guthix??", line++, isQuestComplete(player, "Tears of Guthix")) - line(player, "!!King's Ransom??", line++, isQuestComplete(player, "King's Ransom")) - line(player, "!!Defender of Varrock??", line++, isQuestComplete(player, "Defender of Varrock")) + line( + player, + "!!Recipe for Disaster??", + line++, + isQuestComplete(player, Quests.RECIPE_FOR_DISASTER) + ) + line( + player, + "!!Mourning's Ends Part II - The Temple of Light??", + line++, + isQuestComplete(player, Quests.MOURNINGS_END_PART_II) + ) + line(player, "!!Swan Song??", line++, isQuestComplete(player, Quests.SWAN_SONG)) + line( + player, + "!!Zogre Flesh Eaters??", + line++, + isQuestComplete(player, Quests.ZOGRE_FLESH_EATERS) + ) + line(player, "!!Path of Glouphrie??", line++, isQuestComplete(player, Quests.THE_PATH_OF_GLOUPHRIE)) + line(player, "!!Summer's End??", line++, isQuestComplete(player, Quests.SUMMERS_END)) + line(player, "!!Legends' Quest??", line++, isQuestComplete(player, Quests.LEGENDS_QUEST)) + line(player, "!!Dream Mentor??", line++, isQuestComplete(player, Quests.DREAM_MENTOR)) + line( + player, + "!!Hand in the Sand??", + line++, + isQuestComplete(player, Quests.THE_HAND_IN_THE_SAND) + ) + line(player, "!!Tears of Guthix??", line++, isQuestComplete(player, Quests.TEARS_OF_GUTHIX)) + line(player, "!!King's Ransom??", line++, isQuestComplete(player, Quests.KINGS_RANSOM)) + line( + player, + "!!Defender of Varrock??", + line++, + isQuestComplete(player, Quests.DEFENDER_OF_VARROCK) + ) line(player, "!!Be eligible for entry to the Warriors' Guild??", line++) line(player, "!!Defeated Bork in the Chaos Tunnels??", line++) line(player, "!!And gain a total of 270 quest points.??", line++) @@ -68,7 +89,7 @@ class WhileGuthixSleeps : Quest("While Guthix Sleeps", 161, 160, 5,5491, 0, 1, 9 var ln = 10 super.finish(player) player.packetDispatch.sendString("You have completed While Guthix Sleeps!", 277, 4) - player.packetDispatch.sendItemZoomOnInterface(Items.LONGBOW_839,230,277,5) + player.packetDispatch.sendItemZoomOnInterface(Items.LONGBOW_839, 230, 277, 5) drawReward(player, "5 Quest Points", ln++) drawReward(player, "Lump of dragon metal.", ln++) diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java b/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java index d8f856276..5cc97311a 100644 --- a/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java @@ -52,6 +52,6 @@ public final class CamelotGuardDialogue extends DialoguePlugin { @Override public int[] getIds() { - return new int[] { 812 }; + return new int[] { 6183, 6184 }; } } diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt b/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt index 87eac97a9..323e82d85 100644 --- a/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt +++ b/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt @@ -1,37 +1,41 @@ package content.region.kandarin.seers.dialogue -import core.Util import core.game.dialogue.DialoguePlugin import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.player.link.diary.AchievementDiary import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import core.ServerStore +import core.ServerStore.Companion.getBoolean +import org.json.simple.JSONObject @Initializable class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { - val diary = player.achievementDiaryManager.getDiary(DiaryType.SEERS_VILLAGE) - if (diary.levelRewarded.any()) { + //determine reward level that has been claimed + var gotoStage = 0 + //want the highest value, so this is checked hardest->easiest + if (AchievementDiary.hasClaimedLevelRewards(player,DiaryType.SEERS_VILLAGE,2)) { + gotoStage = 102 + } + else if (AchievementDiary.hasClaimedLevelRewards(player,DiaryType.SEERS_VILLAGE,1)) { + gotoStage = 101 + } + else if (AchievementDiary.hasClaimedLevelRewards(player,DiaryType.SEERS_VILLAGE,0)) { + gotoStage = 100 + } + //give reward, or proceed to normal dialogue + if (gotoStage != 0) { player("Hello there. Are you Geoff-erm-Flax? I've been told that", "you'll give me some flax.") - // If 1 day has not passed since last flax reward - if (player.getAttribute("diary:seers:flax-timer", 0) > System.currentTimeMillis()) { - stage = 98 - return true - } - // If player cannot receive flax reward - if (!player.inventory.hasSpaceFor(Item(Items.FLAX_1780, 1))) { - stage = 99 - return true - } - // Determine flax reward by seers diary reward status - when (diary.reward) { - -1 -> stage = 999 - 0 -> stage = 100 - 1 -> stage = 101 - 2 -> stage = 102 - } - } else { + //Already claimed flax else no room else give correct reward + stage = if (getStoreFile().getBoolean(player.username.lowercase())) { 98 } + else if (!player.inventory.hasSpaceFor(Item(Items.FLAX_1780, 1))) { 99 } + else { gotoStage } + } + //If the diary has not been completed + else { player("Hello there. You look busy.") stage = 0 } @@ -46,7 +50,7 @@ class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) { when (stage) { 999 -> end() 0 -> npc("Yes, I am very busy. Picking GLORIOUS flax.", "The GLORIOUS flax won't pick itself. So I pick it.", "I pick it all day long.").also { stage++ } - 1 -> player("Wow, all that flax must really mount up. What do you do with it all?").also { stage++ } + 1 -> player("Wow, all that flax must really mount up.", "What do you do with it all?").also { stage++ } 2 -> npc("I give it away! I love picking the GLORIOUS flax,", "but, if I let it all mount up, I wouldn't have any", "room for more GLORIOUS flax.").also { stage++ } 3 -> player("So, you're just picking the flax for fun? You must", "really like flax.").also { stage++ } 4 -> npc("'Like' the flax? I don't just 'like' flax. The", "GLORIOUS flax is my calling, my reason to live.", "I just love the feeling of it in my hands!").also { stage++ } @@ -55,7 +59,7 @@ class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) { 7 -> player("I know this area! It's, erm, Seers' Village. There's", "a pub and, er, a bank.").also { stage++ } 8 -> npc("Pah! You call that local knowledge? Perhaps if you", "were wearing some kind of item from one of the", "seers, I might trust you.").also { stage = 999 } - 98 -> npc("I've already given you your GLORIOUS flax", "for the day. Come back tomorrow.").also { stage = 999 } // TODO find accurate dialogue + 98 -> npc("Don't be greedy. Other people want GLORIOUS flax too.", "You can have some more tomorrow.").also { stage = 999 } // TODO find accurate dialogue, no source found yet, so I'm using the modern RS3 dialogue from wiki source (https://runescape.wiki/w/Transcript:Geoffrey) 99 -> npc("Yes, but your inventory is full. Come back", "when you have some space for GLORIOUS flax.").also { stage = 999 } // TODO find accurate dialogue 100 -> {rewardFlax(30, "Yes. The seers have instructed me to give you an", "allowance of 30 GLORIOUS flax a day. I'm not going", "to argue with them, so here you go.")} // TODO find accurate dialogue 101 -> {rewardFlax(60, "Yes. Stankers has instructed me to give you an", "allowance of 60 GLORIOUS flax a day. I'm not going", "to argue with a dwarf, so here you go.")} // TODO find accurate dialogue @@ -67,7 +71,7 @@ class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) { fun rewardFlax(n: Int, vararg messages: String): Unit { npc(*messages) player.inventory.add(Item(Items.FLAX_1780, n)) - player.setAttribute("/save:diary:seers:flax-timer", Util.nextMidnight(System.currentTimeMillis())) + getStoreFile()[player.username.toLowerCase()] = true stage = 999 } @@ -75,4 +79,8 @@ class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) { return intArrayOf(8590) } -} + fun getStoreFile(): JSONObject { + return ServerStore.getArchive("daily-seers-flax") + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialogue.kt b/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialogue.kt new file mode 100644 index 000000000..e241c34f2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialogue.kt @@ -0,0 +1,108 @@ +package content.region.kandarin.seers.dialogue + +import content.region.kandarin.seers.diary.SeerDiaryDialogue +import content.region.kandarin.quest.scorpioncatcher.SCSeerDialogue +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher +import core.api.getAttribute +import core.api.getQuestStage +import core.api.isQuestInProgress +import core.api.openDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import content.data.Quests + + + +@Initializable +class SeerDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SEER_388) + } + + companion object { + const val OTHER_TOPIC = 10 + const val DIARY = 20 + const val SC_QUEST = 30 + + const val SC_QUEST_HELP = 40 + const val SC_QUEST_FRIEND = 50 + const val SC_QUEST_OTHER_SCORPIONS = 60 + + const val MANY_GREETINGS = 70 + const val POWER = 80 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.WORRIED, "Uh, what was that dark force? I've never sensed anything like it...").also { stage = START_DIALOGUE } // https://www.youtube.com/watch?v=mYsxit46rGo May 14 2010 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val scorpionCatcherQuestStage = getQuestStage(player, Quests.SCORPION_CATCHER) + when (stage) { + START_DIALOGUE -> + npcl(FacialExpression.NEUTRAL, "Anyway, sorry about that.").also { stage++ } + START_DIALOGUE+1 -> { + if (isQuestInProgress(player, Quests.SCORPION_CATCHER, 1, 99)) { + showTopics( + Topic("Talk about Scorpion Catcher.", SC_QUEST, true), + Topic("Talk about Achievement Diary.", DIARY, true) + ) + } + else { + showTopics( + Topic("Talk about something else.", OTHER_TOPIC, true), + Topic("Talk about achievement diary.", DIARY, true) + ) + } + } + + SC_QUEST -> { + if (scorpionCatcherQuestStage == ScorpionCatcher.QUEST_STATE_TALK_SEERS) { + showTopics( + Topic("I need to locate some scorpions.", SC_QUEST_HELP,), + Topic("Your friend Thormac sent me to speak to you.", SC_QUEST_FRIEND,), + Topic("I seek knowledge and power!", POWER) + ) + } + else if ((scorpionCatcherQuestStage == ScorpionCatcher.QUEST_STATE_DARK_PLACE) and + getAttribute(player!!, ScorpionCatcher.ATTRIBUTE_TAVERLEY, false) + ) { + playerl( + FacialExpression.NEUTRAL, + "Hi, I have retrieved the scorpion from near the spiders." + ).also { stage = SC_QUEST_OTHER_SCORPIONS } + } + else { + npcl(FacialExpression.NEUTRAL, "Good luck finding those scorpions.").also { stage = END_DIALOGUE } + } + } + SC_QUEST_HELP, SC_QUEST_FRIEND, SC_QUEST_OTHER_SCORPIONS -> { + // Use the current stage value as the entry point to Seers + openDialogue(player, SCSeerDialogue(scorpionCatcherQuestStage, stage), npc) + } + + OTHER_TOPIC -> showTopics( + Topic("Many greetings.", MANY_GREETINGS), + Topic("I seek knowledge and power!", POWER) + ) + DIARY -> openDialogue(player, SeerDiaryDialogue(), npc) + + MANY_GREETINGS -> npcl(FacialExpression.NEUTRAL, + "Remember, whenever you set out to do something, something else must be done first.").also { stage = END_DIALOGUE } + + POWER -> npcl(FacialExpression.NEUTRAL, "Knowledge comes from experience, power comes from battleaxes.").also { stage = END_DIALOGUE } + + } + return true + } +} diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialoguePlugin.java b/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialoguePlugin.java deleted file mode 100644 index 327e2e4d4..000000000 --- a/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialoguePlugin.java +++ /dev/null @@ -1,154 +0,0 @@ -package content.region.kandarin.seers.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.link.diary.AchievementDiary; -import core.game.node.entity.player.link.diary.DiaryType; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the SeerDialoguePlugin dialogue. - * - * @author 'afaroutdude - */ -@Initializable -public class SeerDialoguePlugin extends DialoguePlugin { - - public SeerDialoguePlugin() { - } - - public SeerDialoguePlugin(Player player) { - super(player); - } - - @Override - public int[] getIds() { - return new int[]{388}; - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new SeerDialoguePlugin(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - // npc("Uh, what was that dark force? I've never sensed", "anything like it..."); // https://www.youtube.com/watch?v=mYsxit46rGo May 14 2010 - // npc("Anyway, sorry about that."); - options("Talk about something else.", "Talk about achievement diary."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - int level = 0; - - switch (stage) { - case 999: - end(); - break; - case 0: - switch (buttonId) { - case 1: - npc("Many greetings."); - stage = 1; - break; - case 2: - if (AchievementDiary.canReplaceReward(player, DiaryType.SEERS_VILLAGE, 0)) { - player("I seem to have lost my seers' headband..."); - stage = 80; - break; - } - else if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.SEERS_VILLAGE, 0)) { - player("Can you remind me what my headband does?"); - stage = 90; - break; - } - else if (AchievementDiary.canClaimLevelRewards(player, DiaryType.SEERS_VILLAGE, 0)) { - player("Hi. I've completed the Easy tasks in my Achievement", "Diary."); - stage = 200; - break; - } - else { - player("Hi! Can you help me out with the Achievement Diary", "tasks?"); - stage = 101; - break; - } - } - break; - case 80: - AchievementDiary.grantReplacement(player, DiaryType.SEERS_VILLAGE, 0); - npc("Here's your replacement. Please be more careful."); - stage = 999; - break; - case 90: - npc("Your headband marks you as an honourary seer.", "Geoffrey - who works in the field to the", "south - will give you free flax every day."); - stage = 999; - break; - case 100: - npc("I certainly do - we have a set of tasks spanning Seers'", "Village, Catherby, Hemenster and the Sinclair Mansion.", "Just complete the tasks listed in the Achievement Diary", "and they will be ticked off automatically."); - stage = 999; - break; - case 101: - npc("I'm afraid not. It is important that adventurers", "complete the tasks unaided. That way, only the truly", "worthy collect the spoils."); - stage = 999; - break; - case 200: - npc("Well done, adventurer. You are clearly a " + (player.isMale() ? "man" : "woman") + "of", "great wisdom. I have a gift for you."); - stage++; - break; - case 201: - if (!AchievementDiary.flagRewarded(player, DiaryType.SEERS_VILLAGE, 0)) { - npc("Come back when you have two free inventory slots."); - stage = 999; - } else { - interpreter.sendItemMessage(AchievementDiary.getRewards(DiaryType.SEERS_VILLAGE, 0)[0], "The seer hands you a strange-looking headband and a", "rusty lamp."); - stage++; - } - break; - case 202: - npc("You are now an honourary seer and Geoffrey - who", "works in the field to the south - will give you free flax", "every day. Don't call him 'Geoffrey' though: he prefers", "to be known as 'Flax'."); - stage++; - break; - case 203: - player("Flax? What sort of name is that for a person."); - stage++; - break; - case 204: - npc("I know, I know. The poor boy is a simple soul - he just", "really loves picking flax. A little too much, I fear."); - stage=999; - break; - - case 1: - options("Many greetings.", "I seek knowledge and power!"); - stage = 2; - break; - case 2: - switch (buttonId) { - case 1: - player("Many greetings."); - stage = 10; - break; - case 2: - player("I seek knowledge and power!"); - stage = 20; - break; - } - break; - case 10: - npc("Remember, whenever you set out to do something,", "something else must be done first."); - stage = 999; - break; - case 20: - npc("Knowledge comes from experience, power", "comes from battleaxes."); - stage = 999; - break; - } - return true; - } - -} diff --git a/Server/src/main/content/region/kandarin/seers/diary/SeerDiaryDialogue.kt b/Server/src/main/content/region/kandarin/seers/diary/SeerDiaryDialogue.kt new file mode 100644 index 000000000..e0eb61789 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/diary/SeerDiaryDialogue.kt @@ -0,0 +1,87 @@ +package content.region.kandarin.seers.diary + +import core.api.sendItemDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class SeerDiaryDialogue : DialogueFile() { + + companion object { + + const val LOST_HEAD_BAND = 20 + const val HEAD_BAND_HELP = 30 + const val CLAIM_HEAD_BAND = 40 + const val ASK_FOR_HELP = 50 + } + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE ->{ + if (AchievementDiary.canReplaceReward(player, DiaryType.SEERS_VILLAGE, 0)) { + playerl(FacialExpression.SAD, "I seem to have lost my seers' headband...").also { + stage = LOST_HEAD_BAND + } + } else if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.SEERS_VILLAGE, 0)) { + playerl(FacialExpression.ASKING, "Can you remind me what my headband does?").also { + stage = HEAD_BAND_HELP + } + } else if (AchievementDiary.canClaimLevelRewards(player, DiaryType.SEERS_VILLAGE, 0)) { + playerl( + FacialExpression.HAPPY, + "Hi. I've completed the Easy tasks in my Achievement Diary." + ).also { + stage = CLAIM_HEAD_BAND + } + } else { + playerl(FacialExpression.ASKING, "Do you have an Achievement Diary for me?").also { + stage = ASK_FOR_HELP + } + } + } + + + LOST_HEAD_BAND -> { + if (AchievementDiary.grantReplacement(player, DiaryType.SEERS_VILLAGE, 0)) + npcl(FacialExpression.ANNOYED, "Here's your replacement. Please be more careful.").also { + stage = END_DIALOGUE + } + else + // This line is just guessed + npcl(FacialExpression.HALF_GUILTY, "It seems your inventory is full").also { stage = END_DIALOGUE } + } + HEAD_BAND_HELP -> npcl(FacialExpression.NEUTRAL, "Your headband marks you as an honourary seer. Geoffrey - who works in the field to the south - will give you free flax every day.").also { + stage = END_DIALOGUE + } + + // This has to be npc otherwise wordwrap goes wrong and extends to 5 lines + ASK_FOR_HELP -> npc(FacialExpression.HAPPY, "I certainly do - we have a set of tasks spanning Seers'", "Village, Catherby, Hemenster and the Sinclair Mansion.", + "Just complete the tasks listed in the Achievement Diary", "and they will be ticked off automatically.").also { stage++ } + ASK_FOR_HELP + 1 -> playerl(FacialExpression.ASKING, "Can you help me out with the Achievement Diary tasks?").also { stage++ } + ASK_FOR_HELP + 2 -> npcl(FacialExpression.SAD, + "I'm afraid not. It is important that adventurers complete the tasks unaided. That way, only the truly worthy collect the spoils.").also { + stage = END_DIALOGUE + } + + CLAIM_HEAD_BAND -> npcl(FacialExpression.HAPPY, "Well done, adventurer. You are clearly a "+(if (player!!.isMale) "man" else "woman")+" of great wisdom. I have a gift for you.").also { stage++ } + CLAIM_HEAD_BAND + 1 -> { + if (!AchievementDiary.flagRewarded(player, DiaryType.SEERS_VILLAGE, 0)) { + npcl(FacialExpression.NEUTRAL, "Come back when you have two free inventory slots.").also { + stage = END_DIALOGUE + } + } else { + sendItemDialogue(player!!, AchievementDiary.getRewards(DiaryType.SEERS_VILLAGE, 0)[0], + "The seer hands you a strange-looking headband and a rusty lamp.").also { stage++ } + } + } + CLAIM_HEAD_BAND + 2 -> npcl(FacialExpression.HAPPY, "You are now an honourary seer and Geoffrey - who works in the field to the south - will give you free flax every day. Don't call him 'Geoffrey' though: he prefers to be known as 'Flax'.").also { stage++ } + CLAIM_HEAD_BAND + 3 -> playerl(FacialExpression.ASKING, "Flax? What sort of name is that for a person?").also { stage++ } + CLAIM_HEAD_BAND + 4 -> npcl(FacialExpression.NEUTRAL, "I know, I know. The poor boy is a simple soul - he just really loves picking flax. A little too much, I fear.").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt b/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt index b358cf83b..bd9e90188 100644 --- a/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt +++ b/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt @@ -9,11 +9,13 @@ import core.game.diary.DiaryLevel import core.game.event.* import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.player.link.prayer.PrayerType import core.game.node.item.Item import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import org.rs09.consts.Items import org.rs09.consts.NPCs +import org.rs09.consts.Scenery class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) { companion object { @@ -29,6 +31,7 @@ class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) private val SEERS_VILLAGE_AREA = ZoneBorders(2687, 3455, 2742, 3507) private val SEERS_BANK_AREA = ZoneBorders(2721, 3490, 2730, 3493) private val SEERS_COAL_TRUCKS_AREA = ZoneBorders(2690, 3502, 2699, 3508) + private val SEERS_COURTHOUSE_AREA = ZoneBorders(2732, 3467, 2739, 3471) private val RANGING_GUILD_LOCATION = Location(2657, 3439) @@ -98,6 +101,14 @@ class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) } override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + if (event.source.id == Scenery.OBELISK_OF_WATER_2151 && event.amount >= 5) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.CHARGE_5_WATER_ORBS_AT_ONCE + ) + } + when (player.viewport.region.id) { 10805 -> if (event.itemId == Items.FLAX_1779) { progressIncrementalTask( @@ -288,7 +299,7 @@ class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) finishTask( player, DiaryLevel.HARD, - HardTasks.HIGH_ALCH_MAGIC_SHORTBOW_INSIDE_BANK + HardTasks.HIGH_ALCH_MAGIC_SHORTBOW_INSIDE_BANK ) } } @@ -299,7 +310,7 @@ class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) finishTask( player, DiaryLevel.HARD, - HardTasks.DIAL_FAIRY_RING_MCGRUBORS_WOOD + HardTasks.DIAL_FAIRY_RING_MCGRUBORS_WOOD ) } } @@ -309,7 +320,47 @@ class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) finishTask( player, DiaryLevel.EASY, - EasyTasks.BUY_CANDLE + EasyTasks.BUY_CANDLE + ) + } + + if (event.currency.id == Items.ARCHERY_TICKET_1464) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.RANGING_GUILD_BUY_SOMETHING_FOR_TICKETS + ) + } + } + + override fun onInterfaceOpened(player: Player, event: InterfaceOpenEvent) { + if (event.component.id == 332) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.THORMAC_SORCERER_TALK_ABOUT_MYSTIC_STAVES + ) + } + } + + override fun onPrayerPointsRecharged(player: Player, event: PrayerPointsRechargeEvent) { + if (player.viewport.region.id == 10806) { + if (event.altar.id == Scenery.ALTAR_409 || event.altar.id == Scenery.ALTAR_19145) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PRAY_AT_ALTAR + ) + } + } + } + + override fun onAreaVisited(player: Player) { + if (inBorders(player, SEERS_COURTHOUSE_AREA) && player.prayer.equals(PrayerType.PIETY)) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.ENTER_SEERS_COURTHOUSE_WITH_PIETY ) } } diff --git a/Server/src/main/content/region/kandarin/seers/handlers/SeersCageUnlockPlugin.java b/Server/src/main/content/region/kandarin/seers/handlers/SeersCageUnlockPlugin.java deleted file mode 100644 index 8f0f09929..000000000 --- a/Server/src/main/content/region/kandarin/seers/handlers/SeersCageUnlockPlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -package content.region.kandarin.seers.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to unlock the sheers cage. - * @author 'Vexia - * @versio 1.0 - */ -@Initializable -public final class SeersCageUnlockPlugin extends OptionHandler { - - @Override - public boolean handle(Player player, Node node, String option) { - player.getPacketDispatch().sendMessage("You can't unlock the pillory, you'll let all the prisoners out!"); - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(6836).getHandlers().put("option:unlock", this); - return this; - } - -} diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt index 4e3854225..8d25adaf1 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt @@ -1,12 +1,13 @@ package content.region.kandarin.seers.quest.elementalworkshop import content.global.handlers.iface.BookInterface -import core.api.setAttribute import core.api.setQuestStage import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player import org.rs09.consts.Items +import content.data.Quests +import core.api.* /** * Battered book handler for the Elemental Workshop I quest @@ -23,7 +24,7 @@ class BatteredBookHandler : InteractionListener { BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) if (BookInterface.isLastPage(pageNum, CONTENTS.size)) { if (EWUtils.currentStage(player) == 0) { - setQuestStage(player, "Elemental Workshop I", 1) + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 1) } } return true @@ -31,8 +32,9 @@ class BatteredBookHandler : InteractionListener { } override fun defineListeners() { - on(Items.BATTERED_BOOK_2886, IntType.ITEM, "read") { player, _ -> + on(Items.BATTERED_BOOK_2886, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt index f742d5a21..f43ac6bed 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt @@ -16,6 +16,7 @@ import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.currentStag import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.tools.Log +import content.data.Quests /** * Listeners for the Elemental Workshop I quest @@ -102,7 +103,7 @@ class EWListeners : InteractionListener { } // Player needs to receive a battered book sendItemDialogue(player, Item(Items.BATTERED_BOOK_2886), "You find a book titled 'The Elemental Shield'.") - addItem(player, batteredBook.id) + addItemOrDrop(player, batteredBook.id) return@on true } @@ -119,7 +120,7 @@ class EWListeners : InteractionListener { } sendItemDialogue(player, Item(Items.SLASHED_BOOK_9715), "You find a book titled 'The Elemental Shield'.") - addItem(player, slashedBook.id) + addItemOrDrop(player, slashedBook.id) if (player.inventory.addIfDoesntHave(batteredKey)) { sendItemDialogue(player, Item(Items.BATTERED_KEY_2887),"You also find a key.") } @@ -140,7 +141,7 @@ class EWListeners : InteractionListener { sendMessage(player, "Inside you find a small, old, battered key.") replaceSlot(player, with.asItem().slot, slashedBook) addItemOrDrop(player, Items.BATTERED_KEY_2887) - setQuestStage(player, "Elemental Workshop I", 3) + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 3) return true } } @@ -177,8 +178,8 @@ class EWListeners : InteractionListener { return@on true } // Increment quest stage - if (getQuestStage(player, "Elemental Workshop I") < 5) { - setQuestStage(player, "Elemental Workshop I", 5) + if (getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I) < 5) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 5) } // Allow player through the wall sendMessage(player, "You use the battered key to open the doors.") @@ -200,7 +201,7 @@ class EWListeners : InteractionListener { sendPlayerDialogue(player, "Now to explore this area thoroughly, to find what " + "forgotten secrets it contains.", core.game.dialogue.FacialExpression.NEUTRAL) - setQuestStage(player, "Elemental Workshop I", 7) + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 7) } return@on true } @@ -236,7 +237,7 @@ class EWListeners : InteractionListener { on(Scenery.CRATE_3400, IntType.SCENERY, "search") { player, _ -> if (!getAttribute(player, "/save:ew1:got_needle", false)) { setAttribute(player, "/save:ew1:got_needle", true) - addItem(player, Items.NEEDLE_1733) + addItemOrDrop(player, Items.NEEDLE_1733) sendMessage(player, "You find a needle.") } else { sendMessage(player, "You search the crate but find nothing.") @@ -248,7 +249,7 @@ class EWListeners : InteractionListener { on(Scenery.CRATE_3394, IntType.SCENERY, "search") { player, _ -> if (!getAttribute(player, "/save:ew1:got_leather", false)) { setAttribute(player, "/save:ew1:got_leather", true) - addItem(player, Items.LEATHER_1741) + addItemOrDrop(player, Items.LEATHER_1741) sendMessage(player, "You find some leather.") } else { sendMessage(player, "You search the crate but find nothing.") @@ -289,8 +290,8 @@ class EWListeners : InteractionListener { sendMessage(player, "Following the instructions in the book you make an elemental shield.") } // Check to see if the quest is completed, if not, complete the quest - if (!player.questRepository.getQuest("Elemental Workshop I").isCompleted(player)) { - player.questRepository.getQuest("Elemental Workshop I").finish(player) + if (!player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).isCompleted(player)) { + player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).finish(player) } return@onUseWith true } diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt index 142f10c69..a2629fcb1 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt @@ -4,8 +4,8 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.game.node.entity.player.Player -import org.rs09.consts.Vars import core.api.* +import content.data.Quests /** * Utils for the Elemental Workshop I quest @@ -102,6 +102,6 @@ object EWUtils { } fun currentStage(player: Player): Int { - return player.questRepository.getStage("Elemental Workshop I") + return player.questRepository.getStage(Quests.ELEMENTAL_WORKSHOP_I) } } diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt index 397faad13..097b61613 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.Vars import core.game.system.command.Privilege +import content.data.Quests /** * Elemental Workshop I @@ -29,7 +30,7 @@ import core.game.system.command.Privilege * @author Woah, with love */ @Initializable -class ElementalWorkshopQuest : Quest("Elemental Workshop I", 52, 51, 1), Commands { +class ElementalWorkshopQuest : Quest(Quests.ELEMENTAL_WORKSHOP_I, 52, 51, 1), Commands { override fun newInstance(`object`: Any?): Quest { return this @@ -112,7 +113,7 @@ class ElementalWorkshopQuest : Quest("Elemental Workshop I", 52, 51, 1), Command } override fun defineCommands() { - define("resetew", Privilege.ADMIN) { player, _ -> + define("resetew", Privilege.ADMIN, description = "Resets Elemental Workshop I progress and teleports you to the start.") { player, _ -> setAttribute(player, "/save:ew1:got_needle", false) setAttribute(player, "/save:ew1:got_leather", false) setAttribute(player, "/save:ew1:bellows_fixed", false) @@ -128,7 +129,7 @@ class ElementalWorkshopQuest : Quest("Elemental Workshop I", 52, 51, 1), Command addItem(player, Items.HAMMER_2347) addItem(player, Items.COAL_453, 4) } - define("readyew", Privilege.ADMIN) { player, _ -> + define("readyew", Privilege.ADMIN, description = "Sets Elemental Workshop I furnace as ready (queststage->95, changes all required attributes/varbits)") { player, _ -> val enabled = 1 setAttribute(player, "/save:ew1:got_needle", true) setAttribute(player, "/save:ew1:got_leather", true) diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt index c59014ec4..1309b550f 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt @@ -4,6 +4,7 @@ import core.game.dialogue.FacialExpression import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests /** * @author lila @@ -19,7 +20,7 @@ class ArheinMCDialogue (val questStage: Int) : DialogueFile() { START_DIALOGUE -> playerl(FacialExpression.NEUTRAL, "Can you drop me off on the way down please?").also { stage++ } 1 -> { npcl(FacialExpression.ANNOYED,"I don't think Sir Mordred would like that. He wants as few outsiders visiting as possible. I wouldn't want to lose his business.") - val quest = player!!.questRepository.getQuest("Merlin's Crystal") + val quest = player!!.questRepository.getQuest(Quests.MERLINS_CRYSTAL) player!!.questRepository.setStage(quest, 40) stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java index 0c422017d..286b845f1 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue plugin used for king arthur. @@ -48,7 +49,7 @@ public final class BeggarDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); switch (stage) { case 1: if (quest.getStage(player) == 60 && player.getAttribute("beggar_npc") != null) { diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java index 003add8ff..46b402ed3 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java @@ -11,6 +11,7 @@ import core.game.node.item.Item; import core.plugin.Plugin; import core.game.shops.Shops; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the dialogue plugin used to handle the candle maker npc. @@ -56,7 +57,7 @@ public final class CandleMakerDialogue extends DialoguePlugin { @Override public boolean handle(Player player, Node node, String option) { NPC npc = node.asNpc(); - Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); if (quest.getStage(player) > 60) { Shops.openId(player, 56); } else { @@ -78,7 +79,7 @@ public final class CandleMakerDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); switch (stage) { case 2: if (quest.getStage(player) == 50 || quest.getStage(player) == 60) {// the player has defeated mordred and learned about the black candles diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java index 694cc4c04..ea84952e5 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java @@ -8,6 +8,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the dialogue plugin used for king arthur. @@ -56,7 +57,7 @@ public final class KingArthurDialogue extends DialoguePlugin { stage = 80; return true; } else { - Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); if (quest.getStage(player) == 99) { player("I have freed Merlin from his crystal!"); stage = 900; @@ -80,7 +81,7 @@ public final class KingArthurDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); switch (stage) { case 900: end(); diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java index 1c2a16978..15a6c5ce4 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java @@ -3,8 +3,8 @@ package content.region.kandarin.seers.quest.merlinsquest; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; -import content.region.kandarin.seers.quest.merlinsquest.TheLadyOfTheLake; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the merlin's crystal quest. @@ -17,7 +17,7 @@ public final class MerlinCrystal extends Quest { * Constructs a new {@code MerlinCrystal} {@code Object}. */ public MerlinCrystal() { - super("Merlin's Crystal", 87, 86, 6, 14, 0, 1, 7); + super(Quests.MERLINS_CRYSTAL, 87, 86, 6, 14, 0, 1, 7); } @Override diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java index 66a51581b..82a53c48c 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.scenery.Scenery; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the quest node plugin handler. @@ -23,7 +24,7 @@ public class MerlinCrystalOptionPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); switch (id) { case 247: diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java index ce2695d38..e90ecbfd1 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java @@ -1,6 +1,5 @@ package content.region.kandarin.seers.quest.merlinsquest; -import core.cache.def.impl.ItemDefinition; import core.cache.def.impl.SceneryDefinition; import core.game.activity.ActivityManager; import core.game.activity.CutscenePlugin; @@ -9,13 +8,10 @@ import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; import core.game.global.action.ClimbActionHandler; import core.game.global.action.DoorActionHandler; -import core.game.global.action.DropListener; import core.game.interaction.NodeUsageEvent; import core.game.interaction.OptionHandler; import core.game.interaction.UseWithHandler; import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.impl.ForceMovement; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -24,12 +20,12 @@ import core.game.node.scenery.Scenery; import core.game.node.scenery.SceneryBuilder; import core.game.system.task.Pulse; import core.game.world.GameWorld; -import core.game.world.map.Direction; import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.plugin.Plugin; import core.plugin.ClassScanner; +import content.data.Quests; /** * Handles the Merlin's Crystal Dialogue/Interactions. @@ -73,7 +69,7 @@ public final class MerlinCrystalPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); final int id = node instanceof Item ? ((Item) node).getId() : node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); switch (id) { case 62: @@ -178,7 +174,7 @@ public final class MerlinCrystalPlugin extends OptionHandler { @Override public boolean open(Object... args) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); if (quest.getStage(player) == 99) { npc = (NPC) args[0]; npc("Thank you! Thank you! Thank you!"); @@ -328,8 +324,8 @@ public final class MerlinCrystalPlugin extends OptionHandler { if (p != null) { p.stop(false); } - if (player.getQuestRepository().getQuest("Merlin's Crystal").getStage(player) == 30) { - player.getQuestRepository().getQuest("Merlin's Crystal").setStage(player, 40); + if (player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).getStage(player) == 30) { + player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).setStage(player, 40); } player.unlock(); player.getProperties().setTeleportLocation(Location.create(2778, 3401, 0)); @@ -449,7 +445,7 @@ public final class MerlinCrystalPlugin extends OptionHandler { @Override public boolean isHidden(final Player player) { - if (player.getQuestRepository().getQuest("Merlin's Crystal").getStage(player) == 60 && this.getAttribute("beggar_owner", "").equals(player.getUsername())) { + if (player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).getStage(player) == 60 && this.getAttribute("beggar_owner", "").equals(player.getUsername())) { return false; } return true; diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt index f7a5e87ad..3a24ee325 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt @@ -8,13 +8,14 @@ import core.game.global.action.DropListener import core.game.node.entity.npc.NPC import core.game.node.entity.impl.ForceMovement import org.rs09.consts.Items +import content.data.Quests class MerlinListeners : InteractionListener { private val BONE_DROP_LOCATION = Location(2780, 3515, 0) override fun defineListeners() { on (Items.BAT_BONES_530, IntType.ITEM, "drop") { player, node -> - val merlinStage = getQuestStage(player, "Merlin's Crystal") + val merlinStage = getQuestStage(player, Quests.MERLINS_CRYSTAL) var doingQuest = player.location == BONE_DROP_LOCATION && merlinStage == 80 var hasAuxiliaryRequirements = inInventory(player, Items.LIT_BLACK_CANDLE_32) && getAttribute(player, "thrantax_npc", null) == null diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java index c94ab7d0b..0f3d5b858 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java @@ -4,6 +4,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the dialogue plugin used for Sir Gawain. @@ -40,7 +41,7 @@ public final class SirGawainDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); npc("Good day to you " + (player.isMale() ? "sir" : "madam") + "!"); stage = 0; diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java index 14f4bd3ca..594645e0d 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the dialogue plugin used for Sir Kay. @@ -42,7 +43,7 @@ public final class SirKayDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); options("Hello.", "Talk about achievement diary."); stage = 0; diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java index 09b3eb285..b8d5b8d8a 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java @@ -4,6 +4,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the dialogue plugin used for king arthur. @@ -42,7 +43,7 @@ public final class SirLancelotDialogue extends DialoguePlugin { npc = (NPC) args[0]; npc("Greetings! I am Sir Lancelot, the greatest Knight in the", "land! What do you want?"); - quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); stage = 0; return true; } diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java index 9ce08250b..2732d5667 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Handles the dialogue for Sir Lucan @@ -42,7 +43,7 @@ public class SirLucan extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); if (quest.getStage(player) == 100) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Congratulations on freeing Merlin!"); stage = 20; diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java index c7ec62b1c..6065a1b2e 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java @@ -9,6 +9,7 @@ import core.game.system.task.Pulse; import core.game.world.GameWorld; import core.game.world.map.Location; import core.game.world.update.flag.context.Graphics; +import content.data.Quests; /** * Handles Sir Mordred @@ -50,7 +51,7 @@ public class SirMordredNPC extends AbstractNPC { super.getSkills().setLifepoints(50); if (killer != null && killer.isPlayer()) { final Player p = ((Player) killer); - Quest quest = p.getQuestRepository().getQuest("Merlin's Crystal"); + Quest quest = p.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); if (quest.getStage(p) == 40) { quest.setStage(p, 50); p.getQuestRepository().syncronizeTab(p); diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java index 61420baa8..50b4e2de2 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Handles the SirPalomedes dialogue. @@ -41,7 +42,7 @@ public class SirPalomedes extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); if (quest.getStage(player) == 100) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Congratulations on freeing Merlin!"); stage = 20; diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt index 625bf6a7a..e1ed69c03 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType import core.game.node.item.Item import org.rs09.consts.Items +import content.data.Quests /** * Handles the LadyOfTheLake dialogue. @@ -35,7 +36,7 @@ class TheLadyOfTheLake(player: Player? = null) : DialoguePlugin(player) { } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - val quest = player.questRepository.getQuest("Merlin's Crystal") + val quest = player.questRepository.getQuest(Quests.MERLINS_CRYSTAL) when (stage) { 0 -> options("Who are you?", "I seek the sword Excalibur.", "Good day.").also { stage = 1 } 1 -> when (buttonId) { diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java index fd9b4a68e..d30d76d33 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java @@ -6,6 +6,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Handles the thrantax dialogue. @@ -41,7 +42,7 @@ public class ThrantaxDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); switch (stage) { case 0: interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Now what were those magic words again?"); diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java index d96b52f7c..16efc79b6 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java @@ -4,6 +4,7 @@ import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.node.entity.npc.NPC; import core.game.world.map.Location; +import content.data.Quests; /** * Handles the thrantax npc. @@ -28,7 +29,7 @@ public class ThrantaxNPC extends NPC { @Override public boolean isHidden(final Player player) { - if (player.getQuestRepository().getQuest("Merlin's Crystal").getStage(player) == 80 && this.getAttribute("thrantax_owner", "").equals(player.getUsername())) { + if (player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).getStage(player) == 80 && this.getAttribute("thrantax_owner", "").equals(player.getUsername())) { return false; } return true; diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/BaileyDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/BaileyDialogue.kt new file mode 100644 index 000000000..67d446af2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/BaileyDialogue.kt @@ -0,0 +1,24 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.BaileyDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class BaileyDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return BaileyDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, BaileyDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BAILEY_695) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt index 477aa8020..cc3b0ad95 100644 --- a/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt @@ -1,41 +1,29 @@ package content.region.kandarin.witchhaven.dialogue +import content.region.kandarin.witchhaven.quest.seaslug.CarolineDialogueFile +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills import core.plugin.Initializable +import org.rs09.consts.Items import org.rs09.consts.NPCs -/** - * @author qmqz - */ - @Initializable class CarolineDialogue(player: Player? = null) : DialoguePlugin(player){ - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - player(FacialExpression.FRIENDLY,"Hello again.").also { stage = 0 } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - 0 -> npc(FacialExpression.FRIENDLY, "Hello traveller, how are you?").also { stage++ } - 1 -> player(FacialExpression.FRIENDLY, "Not bad thanks, yourself?").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "I'm good. Busy as always looking after Kent and Kennith but no complaints.").also { stage = 99 } - - 99 -> end() - } - return true - } - - override fun newInstance(player: Player?): DialoguePlugin { + override fun newInstance(player: Player): DialoguePlugin { return CarolineDialogue(player) } - + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, CarolineDialogueFile(), npc) + return true + } override fun getIds(): IntArray { return intArrayOf(NPCs.CAROLINE_696) } -} +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt index 4d99bdf08..5f7432efa 100644 --- a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt @@ -1,5 +1,7 @@ package content.region.kandarin.witchhaven.dialogue +import content.region.kandarin.witchhaven.quest.seaslug.HolgartDialogueFile +import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -7,37 +9,18 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs -/** - * @author qmqz - */ - @Initializable class HolgartDialogue(player: Player? = null) : DialoguePlugin(player){ - fun gender (male : String = "sir", female : String = "madam") = if (player.isMale) male else female - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - 0 -> npc(FacialExpression.FRIENDLY, "Well hello " + gender() + ", beautiful day isn't it?").also { stage++ } - 1 -> player(FacialExpression.FRIENDLY, "Not bad I suppose.").also { stage++ } - 2 -> npc(FacialExpression.FRIENDLY, "Just smell that sea air... beautiful.").also { stage++ } - 3 -> player(FacialExpression.FRIENDLY, "Hmm... lovely...").also { stage = 99 } - - 99 -> end() - } - return true - } - - override fun newInstance(player: Player?): DialoguePlugin { + override fun newInstance(player: Player): DialoguePlugin { return HolgartDialogue(player) } - + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, HolgartDialogueFile(), npc) + return true + } override fun getIds(): IntArray { - return intArrayOf(NPCs.HOLGART_4866) + return intArrayOf(NPCs.HOLGART_700) + // return intArrayOf(NPCs.HOLGART_4866) } } diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartIslandDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartIslandDialogue.kt new file mode 100644 index 000000000..883bdd746 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartIslandDialogue.kt @@ -0,0 +1,27 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.HolgartIslandDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +// This is to handle when Holgart is on the fishing platform. +@Initializable +class HolgartIslandDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return HolgartIslandDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, HolgartIslandDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOLGART_698) + // return intArrayOf(NPCs.HOLGART_4866) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartPlatformDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartPlatformDialogue.kt new file mode 100644 index 000000000..3ac3027c9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartPlatformDialogue.kt @@ -0,0 +1,27 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.HolgartPlatformDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +// This is to handle when Holgart is on the fishing platform. +@Initializable +class HolgartPlatformDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return HolgartPlatformDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, HolgartPlatformDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOLGART_699, NPCs.FISHERMAN_4871) + // return intArrayOf(NPCs.HOLGART_4866) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/KennithDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KennithDialogue.kt new file mode 100644 index 000000000..2ad5de63a --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KennithDialogue.kt @@ -0,0 +1,45 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.KennithDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +class KennithDialogue : InteractionListener { + + override fun defineListeners() { + on(NPCs.KENNITH_4864, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, KennithDialogueFile(), npc) + return@on true + } + } + + // Because Kennith is behind the counter + override fun defineDestinationOverrides() { + setDest(IntType.NPC, intArrayOf(NPCs.KENNITH_4864),"talk-to"){ _, _ -> + return@setDest Location.create(2765, 3286, 1) + } + } +} + +// INSTEAD OF THIS as Kennith is unreachable. +//@Initializable +//class KennithDialogue(player: Player? = null) : DialoguePlugin(player){ +// override fun newInstance(player: Player): DialoguePlugin { +// return KennithDialogue(player) +// } +// override fun handle(interfaceId: Int, buttonId: Int): Boolean { +// // Fallback to default. Always the start of Sea Slug +// openDialogue(player!!, KennithDialogueFile(), npc) +// return true +// } +// override fun getIds(): IntArray { +// // Base is CAROLINE_697 (Should be named KENNITH_697) +// return intArrayOf(NPCs.CAROLINE_697, NPCs.KENNITH_4864) +// } +//} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/KentDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KentDialogue.kt new file mode 100644 index 000000000..25b3c447e --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KentDialogue.kt @@ -0,0 +1,24 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.KentDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class KentDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return KentDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, KentDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + // Base is CAROLINE_697 (Should be named KENNITH_697) + return intArrayOf(NPCs.KENT_701) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchavenVillagerDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchavenVillagerDialogue.kt new file mode 100644 index 000000000..8bb49bd9b --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchavenVillagerDialogue.kt @@ -0,0 +1,83 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class WitchavenVillagerDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return WitchavenVillagerDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, WitchavenVillagerDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.WITCHAVEN_VILLAGER_4883, NPCs.WITCHAVEN_VILLAGER_4884, + NPCs.WITCHAVEN_VILLAGER_4885, NPCs.WITCHAVEN_VILLAGER_4886, + NPCs.WITCHAVEN_VILLAGER_4887, NPCs.WITCHAVEN_VILLAGER_4888) + } +} + +class WitchavenVillagerDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .player(FacialExpression.FRIENDLY, "Hello there.") + .branch { player -> + return@branch (0 .. 4).random() + }.let { branch -> + branch.onValue(0) + .npcl("What have you got to be so cheerful about?") + .playerl("Well, it's another nice day.") + .npcl("Ha! Try worrying about how you feed a family with no job. Then tell me how nice the day is!") + .playerl("Okay, I guess I've caught you at a bad time. Goodbye.") + .end() + + branch.onValue(1) + .npcl("Hmm? Oh, hello there.") + .playerl("Are you okay? You seem a bit preoccupied.") + .npcl("It's nothing stranger. No need to concern yourself.") + .end() + + branch.onValue(2) + .npcl("Spare a coin mister?") + .playerl("What do you need it for?") + .npcl("For a poor unemployed fisherman what needs to eat.") + .playerl("Why don't you just fish for some food?") + .npcl("Err... Goodbye mister.") + .end() + + branch.onValue(3) + .npcl("Can you believe they did this to us?") + .playerl("Wha...") + .npcl("I mean, what did they think would happen?") + .playerl("Who...") + .npcl("Building that whacking great Fishing Platform just off the coast.") + .playerl("Fish...") + .npcl("Dratted thing stole all of our trade.") + .playerl("Excuse...") + .npcl("I'm sorry, I'm too angry to speak right now. Goodbye") + .end() + + branch.onValue(4) + .npcl("With our nets and gear we're faring,") + .npcl("On the wild and wasteful ocean,") + .npcl("It's there on the deep that we harvest and reap our bread,") + .npcl("As we hunt the bonny shoals of herring.") + .playerl("That's a lovely song.") + .npcl("Aye lad, and sing it every day we did.") + .npcl("'Till the Fishing Platform came and ruined everything.") + .playerl("Oh, I'm sorry.") + .npcl("No need lad, it not be your fault.") + .end() + } + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchhavenVillageDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchhavenVillageDialogue.kt deleted file mode 100644 index 38b0f00e8..000000000 --- a/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchhavenVillageDialogue.kt +++ /dev/null @@ -1,78 +0,0 @@ -package content.region.kandarin.witchhaven.dialogue - -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable -import org.rs09.consts.NPCs - -/** - * @author qmqz - */ - -@Initializable -class WitchhavenVillageDialogue(player: Player? = null) : DialoguePlugin(player){ - - private val conversations = arrayOf (0, 7, 11, 19, 24) - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - player(FacialExpression.FRIENDLY, "Hello there.").also { stage = conversations.random() } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - - 0 -> sendDialogue("Their eyes are staring vacantly into space.").also { stage++ } - 1 -> npc(FacialExpression.NEUTRAL, "Ye mariners all, as ye pass by,").also { stage++ } - 2 -> npc(FacialExpression.NEUTRAL, "Come in and drink if you are dry,").also { stage++ } - 3 -> npc(FacialExpression.NEUTRAL, "Come spend, me lads, your money brisk,").also { stage++ } - 4 -> npc(FacialExpression.NEUTRAL, "And pop your nose in a jug of this.").also { stage++ } - 5 -> player(FacialExpression.NEUTRAL, "You're not fooling anyone you know.").also { stage++ } - 6 -> npc(FacialExpression.NEUTRAL, "We fooled you easily enough.").also { stage = 99 } - - 7 -> sendDialogue("Their eyes are staring vacantly into space.").also { stage++ } - 8 -> npc(FacialExpression.NEUTRAL, "Free. She is free...").also { stage++ } - 9 -> player(FacialExpression.NEUTRAL, "What?").also { stage++ } - 10 -> npc(FacialExpression.NEUTRAL, "The mother is free.").also { stage = 99 } - - 11 -> sendDialogue("Their eyes are staring vacantly into space.").also { stage++ } - 12 -> npc(FacialExpression.NEUTRAL, "You! You did it!").also { stage++ } - 13 -> player(FacialExpression.NEUTRAL, "I didn't mean to!").also { stage++ } - 14 -> npc(FacialExpression.NEUTRAL, "You killed him!").also { stage++ } - 15 -> player(FacialExpression.NEUTRAL, "It was an accide... Killed who?").also { stage++ } - 16 -> npc(FacialExpression.NEUTRAL, "Our Prince, you killed our Prince.").also { stage++ } - 17 -> player(FacialExpression.NEUTRAL, "Oh that, yes I did.").also { stage++ } - 18 -> npc(FacialExpression.NEUTRAL, "Leave us alone.").also { stage = 99 } - - 19 -> sendDialogue("Their eyes are staring vacantly into space.").also { stage++ } - 20 -> npc(FacialExpression.NEUTRAL, "Soon now... So soon...").also { stage++ } - 21 -> npc(FacialExpression.NEUTRAL, "The stars are almost right.").also { stage++ } - 22 -> player(FacialExpression.NEUTRAL, "For what?").also { stage++ } - 23 -> npc(FacialExpression.NEUTRAL, ". . .").also { stage = 99 } - - 24 -> sendDialogue("Their eyes are staring vacantly into space.").also { stage++ } - 25 -> npc(FacialExpression.NEUTRAL, "Ahh, our saviour.").also { stage++ } - 26 -> player(FacialExpression.NEUTRAL, "Please don't remind me.").also { stage++ } - 27 -> npc(FacialExpression.NEUTRAL, "Do not worry, soon your regret will be gone.").also { stage++ } - 28 -> player(FacialExpression.NEUTRAL, "If you think you will get to me...").also { stage++ } - 29 -> npc(FacialExpression.NEUTRAL, "All in good time.").also { stage = 99 } - - - 99 -> end() - } - return true - } - - override fun newInstance(player: Player?): DialoguePlugin { - return WitchhavenVillageDialogue(player) - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.WITCHAVEN_VILLAGER_4883, NPCs.WITCHAVEN_VILLAGER_4884, - NPCs.WITCHAVEN_VILLAGER_4885, NPCs.WITCHAVEN_VILLAGER_4886, - NPCs.WITCHAVEN_VILLAGER_4887, NPCs.WITCHAVEN_VILLAGER_4888) - } -} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/BaileyDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/BaileyDialogueFile.kt new file mode 100644 index 000000000..9b6399d99 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/BaileyDialogueFile.kt @@ -0,0 +1,68 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class BaileyDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 4) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.SCARED, "What? Who are you? Come inside quickly!") + .npcl(FacialExpression.SCARED, "What are you doing here?") + .playerl("I'm trying to find out what happened to a boy named Kennith.") + .npcl("Oh you mean Kent's son. He's around somewhere, probably hiding if he knows what's good for him.") + .playerl(FacialExpression.THINKING, "Hiding from what? What's got you so frightened?") + .npcl("Haven't you seen all those things out there?") + .playerl(FacialExpression.THINKING, "The sea slugs?") + .npcl(FacialExpression.SUSPICIOUS, "It all began about a week ago. We pulled up a haul of deep sea flatfish. Mixed in with them we found these slug things, but thought nothing of it.") + .npcl(FacialExpression.SUSPICIOUS, "Not long after that my friends began to change, now they spend all day pulling in hauls of fish, only to throw back the fish and keep those nasty sea slugs.") + .npcl(FacialExpression.SUSPICIOUS, "What am I supposed to do with those? I haven't figured out how to kill one yet. If I put them near the stove they squirm and jump away.") + .playerl(FacialExpression.THINKING, "I doubt they would taste too good.") + .npcl(FacialExpression.ANGRY, "This is no time for humour.") + .playerl("I'm sorry, I didn't mean to upset you.") + .npcl(FacialExpression.SCARED, "That's okay. I just can't shake the feeling that this is the start of something... Terrible.") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 5) + .playerl("Hello.") + .npcl(FacialExpression.EXTREMELY_SHOCKED, "Oh, thank the gods it's you. They've all gone mad I tell you, one of the fishermen tried to throw me into the sea!") + .playerl("They're all being controlled by the sea slugs.") + .npcl("I figured as much.") + .playerl("I need to get Kennith off this platform, but I can't get past the fishermen.") + .npcl("The sea slugs are scared of heat... I figured that out when I tried to cook them.") + .npcl("Here.") + .betweenStage { _, player, _, _ -> + addItemOrDrop(player, Items.UNLIT_TORCH_596) + } + .iteml(Items.UNLIT_TORCH_596, "Bailey gives you a torch.") + .npcl("I doubt the fishermen will come near you if you can get this torch lit. The only problem is all the wood and flint are damp... I can't light a thing!") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 5) { + setQuestStage(player, Quests.SEA_SLUG, 6) + } + } + + // We aren't going to give you a spare torch. Go get an unlit torch somewhere else. + b.onQuestStages(Quests.SEA_SLUG, 6, 7, 8) + .playerl("Hello.") + .npcl("Oh, thank the gods it's you. They've all gone mad I tell you, one of the fishermen tried to throw me into the sea!") + .playerl("They're all being controlled by the sea slugs.") + .npcl("I figured as much.") + .playerl("I need to get Kennith off this platform, but I can't get past the fishermen.") + .npcl("The sea slugs are scared of heat... I figured that out when I tried to cook them.") + .npcl("I doubt the fishermen will come near you if you can get this torch lit. The only problem is all the wood and flint are damp... I can't light a thing!") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 9, 10, 100) + .playerl("I've managed to light the torch.") + .npcl("Well done traveller, you'd better get Kennith out of here soon. The fishermen are becoming stranger by the minute, and they keep pulling up those blasted sea slugs.") + .playerl("Don't worry I'm working on it.") + .npcl("Just be sure to watch your back. The fishermen seem to have taken notice of you.") + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/CarolineDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/CarolineDialogueFile.kt new file mode 100644 index 000000000..bd6892832 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/CarolineDialogueFile.kt @@ -0,0 +1,71 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.skill.Skills + +class CarolineDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.SAD, "Is there any chance you could help me?") + .playerl(FacialExpression.THINKING, "What's wrong?") + .npcl("It's my husband, he works on a fishing platform. Once a month he takes our son, Kennith, out with him.") + .npcl(FacialExpression.THINKING, "They usually write to me regularly, but I've heard nothing all week. It's very strange.") + .playerl("Maybe the post was lost!") + .npcl(FacialExpression.THINKING, "Maybe, but no-one's heard from the other fishermen on the platform. Their families are becoming quite concerned.") + .branch { player -> + return@branch if (hasLevelStat(player, Skills.FIREMAKING, 30)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl("However, I don't think you are ready to visit the platform.") + .line("You need Level 30 Firemaking to start the Sea Slug quest.") + .end() + return@let branch.onValue(1) + } + .npcl(FacialExpression.HALF_THINKING, "Is there any chance you could visit the platform and find out what's going on?") + .options().let { optionBuilder -> + optionBuilder.option_playerl("I suppose so, how do I get there?") + .npcl("That's very good of you @name. My friend Holgart will take you there.") + .playerl("Ok, I'll go and see if they're ok.") + .npcl("I'll reward you for your time. It'll give me peace of mind to know Kennith and my husband, Kent, are safe.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 0) { + setQuestStage(player, Quests.SEA_SLUG, 1) + } + } + optionBuilder.option_playerl("I'm sorry, I'm too busy.") + .npcl(FacialExpression.SAD, "That's a shame.") + .playerl("Bye.") + .npcl("Bye.") + .end() + } + + b.onQuestStages(Quests.SEA_SLUG, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + .playerl("Hello Caroline.") + .npcl("Brave @name, have you any news about my son and his father?") + .playerl("I'm working on it now Caroline.") + .npcl("Please bring them back safe and sound.") + .playerl("I'll do my best.") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 11) + .playerl("Hello.") + .npcl("Brave @name, you've returned!") + .npcl("Kennith told me about the strange goings-on at the platform. I had no idea it was so serious.") + .npcl("I could have lost my son and my husband if it wasn't for you.") + .playerl("We found Kent stranded on an island.") + .npcl("Yes. Holgart told me and sent a rescue party out. Kent's back home now, resting with Kennith. I don't think he'll be doing any fishing for a while.") + .npcl("Here, take these Oyster pearls as a reward. They're worth quite a bit and can be used to make lethal crossbow bolts.") + .playerl(FacialExpression.FRIENDLY, "Thanks!") + .npcl(FacialExpression.FRIENDLY, "Thank you. Take care of yourself @name.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 11) { + finishQuest(player, Quests.SEA_SLUG) + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/FishermanDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/FishermanDialogue.kt new file mode 100644 index 000000000..ba344e520 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/FishermanDialogue.kt @@ -0,0 +1,102 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class FishermanDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return FishermanDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, FishermanDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.FISHERMAN_702, NPCs.FISHERMAN_703, NPCs.FISHERMAN_704) + } +} + +class FishermanDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .player(FacialExpression.FRIENDLY, "Hello there.") + .line("Their eyes are staring vacantly into space.") + .branch { player -> + return@branch (1 .. 1).random() + }.let { branch -> + branch.onValue(0) + .npc(FacialExpression.AMAZED, "Ye mariners all, as ye pass by,") + .npc(FacialExpression.AMAZED, "Come in and drink if you are dry,") + .npc(FacialExpression.AMAZED, "Come spend, me lads, your money brisk,") + .npc(FacialExpression.AMAZED, "And pop your nose in a jug of this.") + .player("You're not fooling anyone you know.") + .npc(FacialExpression.AMAZED, "We fooled you easily enough.") + .end() + + branch.onValue(1) + .npcl(FacialExpression.AMAZED,"You are not part of our family...") + .playerl("Umm. Not last time I checked.") + .npcl(FacialExpression.AMAZED,"Soon you will be... Soon you will...") + .end() + + branch.onValue(2) + .npcl(FacialExpression.AMAZED,"Keep away human... Leave or face the deep blue...") + .playerl("Pardon?") + .npcl(FacialExpression.AMAZED,"You will all end up in the blue... Deep deep under the blue...") + .end() + + branch.onValue(3) + .npcl(FacialExpression.AMAZED,"Lost to us.. She is Lost to us...") + .playerl("Who is lost?") + .npcl(FacialExpression.AMAZED,"Trapped by the light... Lost and trapped...") + .playerl("Ermm... So you don't want to tell me then?") + .npcl(FacialExpression.AMAZED,"Trapped... In stone and darkness...") + .end() + + branch.onValue(4) + .npcl(FacialExpression.AMAZED,"Must find family...") + .playerl("What?") + .npcl(FacialExpression.AMAZED,"Soon we will all be together...") + .playerl("Are you ok?") + .npcl(FacialExpression.AMAZED,"Must find family... They are all under the blue... Deep deep under the blue...") + .playerl("Ermm... I'll leave you to it then.") + .end() + + branch.onValue(5) + .npcl(FacialExpression.AMAZED,"Free of the deep blue we are...") + .npcl(FacialExpression.AMAZED,"We must find...") + .playerl("Yes?") + .npcl(FacialExpression.AMAZED,"a new home...") + .npcl(FacialExpression.AMAZED,"We must leave this place...") + .playerl("Where will you go?") + .npcl(FacialExpression.AMAZED,"Away.. Away to her...") + .playerl("Riiight.") + .end() + + branch.onValue(6) + .npcl(FacialExpression.AMAZED,"Below the deep, deep blue she waits...") + .playerl("Who waits?") + .npcl(FacialExpression.AMAZED,"They came to her with fire and faith...") + .playerl("Who? Who came to who?") + .npcl(FacialExpression.AMAZED,"Too many... Too many...") + .playerl("Too many what? Make sense!") + .npcl(FacialExpression.AMAZED,"Locked away for all eternity...") + .playerl("You'd better start making sense Sonny Jim or I'll...") + .npcl(FacialExpression.AMAZED,"Free... Soon to be free...") + .end() + + branch.onValue(7) + .npcl(FacialExpression.AMAZED,"Must escape the blue.. Deep deep blue") + .playerl("Pardon?") + .npcl(FacialExpression.AMAZED,"Family... Under the blue... Must escape the blue...") + .end() + } + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartDialogueFile.kt new file mode 100644 index 000000000..559ce7335 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartDialogueFile.kt @@ -0,0 +1,101 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class HolgartDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Well hello @g[m'lad,m'laddy]. Beautiful day isn't it?") + .playerl("Not bad I suppose.") + .npcl("Just smell that sea air... beautiful.") + .playerl(FacialExpression.THINKING, "Hmm... lovely...") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 1) + .npcl(FacialExpression.FRIENDLY, "Hello, m'hearty.") + .playerl("I would like a ride on your boat to the fishing platform.") + .npcl(FacialExpression.SAD, "I'm afraid it isn't sea worthy, it's full of holes. To fill the holes I'll need some swamp paste.") + .playerl(FacialExpression.THINKING, "Swamp paste?") + .npcl("Yes, swamp tar mixed with flour and heated over a fire.") + .branch { player -> + return@branch if (inInventory(player, Items.SWAMP_PASTE_1941)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("Where can I find swamp tar?") + .npcl("Unfortunately the only supply of swamp tar is in the swamps below Lumbridge. It's too far for an old man like me to travel.") + .npcl("If you make me some swamp paste I'll give you a ride in my boat.") + .playerl("I'll see what I can do.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 1) { + setQuestStage(player, Quests.SEA_SLUG, 2) + } + } + branch.onValue(1) + .npcl("In fact, unless me nose be mistaken, you've got some in yer pack.") + .playerl("Oh yes, I forgot about that stuff. Can you use it?") + .npcl("Aye @g[lad,lass]. That be perfect.") + .betweenStage { _, player, _, _ -> + removeItem(player, Items.SWAMP_PASTE_1941) + } + .iteml(Items.SWAMP_PASTE_1941, "You give Holgart the swamp paste.") + // Cutscene + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 1) { + setQuestStage(player, Quests.SEA_SLUG, 3) + } + } + } + + b.onQuestStages(Quests.SEA_SLUG, 2) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl("Hello, m'hearty. Did you manage to make some swamp paste?") + .branch { player -> + return@branch if (inInventory(player, Items.SWAMP_PASTE_1941)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("I'm afraid not.") + .npcl("It's simply swamp tar mixed with flour heated over a fire. Unfortunately the only supply of swamp tar is in the swamps below Lumbridge.") + .npcl("I can't fix my row boat without it.") + .playerl("Ok, I'll try to find some.") + .end() + branch.onValue(1) + .playerl("Yes, I have some here.") + .betweenStage { _, player, _, _ -> + removeItem(player, Items.SWAMP_PASTE_1941) + } + .iteml(Items.SWAMP_PASTE_1941, "You give Holgart the swamp paste.") + // Cutscene + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 2) { + setQuestStage(player, Quests.SEA_SLUG, 3) + } + } + + } + + + b.onQuestStages(Quests.SEA_SLUG, 3, 4, 5, 6, 7, 8, 9, 10, 11, 100) + .playerl(FacialExpression.FRIENDLY, "Hello, Holgart.") + .npcl("Hello again land lover. There's some strange goings on, on that platform, I tell you.") + .options().let { optionBuilder -> + optionBuilder.option("Will you take me there?") + .playerl(FacialExpression.THINKING, "Will you take me there?") + .npcl("Of course m'hearty. If that's what you want.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 0) + } + + optionBuilder.option_playerl("I'm keeping away from there.") + .npcl("Fair enough m'hearty.") + .end() + } + + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartIslandDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartIslandDialogueFile.kt new file mode 100644 index 000000000..49ab8c4ab --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartIslandDialogueFile.kt @@ -0,0 +1,22 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class HolgartIslandDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 100) + .playerl("We'd better get back to the platform so we can see what's going on.") + .npcl(FacialExpression.SUSPICIOUS, "You're right. It all sounds pretty creepy.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 3) + } + b.onQuestStages(Quests.SEA_SLUG, 4) + .playerl("Where are we?") + .npc("Someway off mainland still. You'd better see if me old", "matey's okay.") + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartPlatformDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartPlatformDialogueFile.kt new file mode 100644 index 000000000..f9678899d --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartPlatformDialogueFile.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class HolgartPlatformDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 100) + .playerl(FacialExpression.FRIENDLY, "Hey, Holgart.") + .npcl("Have you had enough of this place yet? It's really starting to scare me.") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Okay, let's go back.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 1) + } + optionBuilder.option_playerl("No, I'm going to stay a while.") + .npcl("Okay... you're the boss.") + .end() + } + + b.onQuestStages(Quests.SEA_SLUG, 4) + .playerl("Holgart, something strange is going on here.") + .npcl("You're telling me, none of the sailors seem to remember who I am.") + .playerl("Apparently Kennith's father left for help a couple of days ago.") + .npcl("That's a worry, no-one's heard from him on shore. Come on, we'd better go look for him.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 2) + } + + b.onQuestStages(Quests.SEA_SLUG, 11) + .playerl("Did you get the kid back to shore?") + .npcl("Yes, he's safe and sound with his parents. Your turn to return to land now adventurer.") + .playerl("Looking forward to it.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 1) + } + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KennithDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KennithDialogueFile.kt new file mode 100644 index 000000000..a12f2e9b8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KennithDialogueFile.kt @@ -0,0 +1,69 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class KennithDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3) + .playerl(FacialExpression.THINKING, "Are you okay young one?") + .npcl(FacialExpression.CHILD_SAD, "No, I want daddy!") + .playerl("Where is your father?") + .npcl(FacialExpression.CHILD_SAD, "He went to get help days ago.") + .npcl(FacialExpression.CHILD_SAD, "The nasty fishermen tried to throw me and daddy into the sea. So he told me to hide here.") + .playerl("That's good advice, you stay here and I'll go try and find your father.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 3) { + setQuestStage(player, Quests.SEA_SLUG, 4) + } + } + b.onQuestStages(Quests.SEA_SLUG, 4, 5, 6) + .playerl(FacialExpression.THINKING, "Are you okay?") + .npcl(FacialExpression.CHILD_SAD, "I want to see daddy!") + .playerl("I'm working on it.") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 7) + .playerl("Hello Kennith, are you okay?") + .npcl(FacialExpression.CHILD_SAD, "No, I want my daddy.") + .playerl("You'll be able to see him soon. First we need to get you back to land, come with me to the boat.") + .npcl(FacialExpression.CHILD_SURPRISED, "No!") + .playerl("What, why not?") + .npcl(FacialExpression.CHILD_SURPRISED, "I'm scared of those nasty sea slugs. I won't go near them.") + .playerl("Okay, you wait here and I'll go figure another way to get you out.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 7) { + setQuestStage(player, Quests.SEA_SLUG, 8) + } + } + + b.onQuestStages(Quests.SEA_SLUG, 8) + // This stage is unfortunately left out. You can't interact with Kennith authentically. + .end() + + b.onQuestStages(Quests.SEA_SLUG, 9) + .playerl("Kennith, I've made an opening in the wall. You can come out through there.") + .npcl(FacialExpression.CHILD_THINKING, "Are there any sea slugs on the other side?") + .playerl("Not one.") + .npcl(FacialExpression.CHILD_THINKING, "How will I get downstairs?") + .playerl("I'll figure that out in a moment.") + .npcl(FacialExpression.CHILD_NORMAL, "Ok, when you have I'll come out.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 9) { + setQuestStage(player, Quests.SEA_SLUG, 10) + } + } + + b.onQuestStages(Quests.SEA_SLUG, 10) + // This stage is also unfortunately left out. You can't interact with Kennith authentically. + .end() + + b.onQuestStages(Quests.SEA_SLUG, 11, 100) + // Kennith is varp swapped out, so is no longer here. + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KentDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KentDialogueFile.kt new file mode 100644 index 000000000..1e9fee52c --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KentDialogueFile.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class KentDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 4, 5, 6) + .npcl("Oh thank Saradomin! I thought I'd be left out here forever.") + .playerl("Your wife sent me out to find you and your boy. Kennith's fine by the way, he's on the platform.") + .npcl("I knew the row boat wasn't sea worthy. I couldn't risk bringing him along but you must get him off that platform.") + .playerl("What's going on here?") + .npcl("Five days ago we pulled in a huge catch. As well as fish we caught small slug like creatures, hundreds of them.") + .npcl("That's when the fishermen began to act strange.") + .npcl("It was the sea slugs, they attack themselves to your body and somehow take over the mind of the carrier.") + .npcl("I told Kennith to hide until I returned but I was washed up here.") + .npcl("Please go back and get my boy, you can send help for me later.") + .npcl(FacialExpression.EXTREMELY_SHOCKED, "@name wait!") + .betweenStage { _, player, _, _ -> + visualize(npc!!, 4807, 790) + sendMessage(player, "*slooop*") + sendMessage(player, "He pulls a sea slug from under your top.") + } + .npcl("A few more minutes and that thing would have full control of your body.") + .playerl(FacialExpression.EXTREMELY_SHOCKED, "Yuck! Thanks Kent.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 4) { + setQuestStage(player, Quests.SEA_SLUG, 5) + } + } + + b.onQuestStages(Quests.SEA_SLUG, 5, 6, 7, 8, 9, 10, 11, 100) + .playerl("Hello.") + .npcl("Oh my, I must get back to shore.") + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlug.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlug.kt new file mode 100644 index 000000000..ef3424233 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlug.kt @@ -0,0 +1,186 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Sea Slug Quest + * + * Note that the varp 159 controls the quest AND some environments: + * The BADLY_REPAIRED_WALL_18381 disappears after varp 159 is set to 9 + * KENNITH_4864 disappears after varp 159 is set to 11 + * KENNITH_4865 (but ID 4864) appears after varp 159 is set to 11 + * + * https://www.youtube.com/watch?v=lf83SACuIDw (This is amazing) + * https://www.youtube.com/watch?v=VnghpKbUqKw + * https://www.youtube.com/watch?v=thHuATlGYag + * https://www.youtube.com/watch?v=VR91Rbyuou4 (This has many other unvisited paths) + */ +@Initializable +class SeaSlug : Quest(Quests.SEA_SLUG, 109, 108, 1,159, 0, 1, 12) { + + companion object { + const val questVarp = 159 + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.SEA_SLUG) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Caroline?? who is !!East??", line++, false) + line(player, "!!of Ardougne??.", line++, false) + line++ + line(player, "Requirements:", line++, false) + // I think this is an old line. I saw it being the other line for 30 Firemaking reqs. + line(player, "You'll need level 30 !!Firemaking??", line++, hasLevelStat(player, Skills.FIREMAKING, 30)) + // line(player, "!!Level 30 Firemaking??", line++, hasLevelStat(player, Skills.FIREMAKING, 30)) + } else { + line(player, "I have spoken to Caroline and agreed to help", line++, true) + line++ + + if (stage >= 3) { + line(player, "I gave Holgart the Swamp Paste and his boat is now ready", line++, true) + line(player, "to take me to the Fishing Platform", line++, true) + } else if (stage >= 2) { + // authentic from https://www.youtube.com/watch?v=VnghpKbUqKw + line(player, "I've spoken to !!Holgart?? but his boat is broken", line++, false) + line(player, "He needs me to bring him some !!Swamp Paste??", line++, false) + line++ + line(player, "I can make !!Swamp Paste?? by mixing !!Swamp Tar?? with !!Flour?? and", line++, false) + line(player, "then heating the mixture on a !!Fire??", line++, false) + line(player, "I can find !!Swamp Tar?? in the !!Swamp South of Lumbridge??", line++, false) + line++ + line(player, "I need to get to the !!Fishing Platform?? and find out what's", line++, false) + line(player, "happened to Kent and Kennith", line++, false) + } else if (stage >= 1) { + // derived + line(player, "I need to speak to !!Holgart??.", line++, false) + } + + if (stage >= 5) { + line++ + line(player, "I've found Kennith, he's hiding behind some boxes.", line++, true) + line++ + line(player, "I've found Kent on a small island", line++, true) + } else if (stage >= 4) { + line++ + line(player, "I've found Kennith, he's hiding behind some boxes.", line++, true) + line++ + line(player, "I need to find !!Kent??", line++, false) + } else if (stage >= 3) { + line++ + line(player, "I need to find !!Kent?? and !!Kennith??", line++, false) + } + + if (stage >= 9) { + line++ + line(player, "!!Kent?? has asked me to help !!Kennith?? escape", line++, true) + } else if (stage >= 5) { + line++ + line(player, "!!Kent?? has asked me to help !!Kennith?? escape", line++, false) + } + + if (stage >= 9) { + line(player, "After speaking to Bailey, I found that Sea Slugs are", line++, true) + line(player, "afraid of heat.", line++, true) + line(player, "I should find a way of lighting this damp torch.", line++, true) + } else if (stage >= 6) { + line(player, "After speaking to !!Bailey??, I found that Sea Slugs are", line++, false) + line(player, "afraid of heat.", line++, false) + line(player, "I should find a way of lighting this damp torch.", line++, false) + } + + if (stage >= 8) { + // Disappears + } else if (stage >= 7) { + // Derived + line(player, "I should talk to !!Kennith??", line++, false) + } + + if (stage >= 9) { + line(player, "I've created an opening to let Kennith escape", line++, true) + } else if (stage >= 8) { + // Derived + line(player, "I need to find a way to get !!Kennith?? out", line++, false) + } + + if (stage >= 10) { + line++ + line(player, "Kennith can't get downstairs without some help", line++, true) + } else if (stage >= 9) { + // Derived + line++ + line(player, "I should talk to !!Kennith?? again", line++, false) + } + + + if (stage >= 11) { + line++ + line(player, "I've used the Crane to lower Kennith into the boat", line++, true) + } else if (stage >= 10) { + line++ + line(player, "!!Kennith?? won't go near the !!Sea Slugs??", line++, false) + line(player, "I need to find another way to get him out", line++, false) + } + + if (stage >= 100) { + line++ + line(player, "I've spoken to Caroline and she thanked me for", line++, true) + line(player, "rescuing her family from the Sea Slugs", line++, true) + } else if (stage >= 11) { + line++ + line(player, "I need to take the boat back to shore and talk to !!Caroline??", line++, false) + } + + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + + } + + override fun reset(player: Player) { + // removeAttribute(player, attributeTalkedToHolgart) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Sea Slug!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.SEA_SLUG_1466,230,277,5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "7175 Fishing XP", ln++) + drawReward(player, "Oyster pearls", ln++) + + rewardXP(player, Skills.FISHING, 7175.0) + addItemOrDrop(player, Items.OYSTER_PEARLS_413) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + // The quest stages are perfectly aligned with the varp since the varp controls npcs and sceneries + if (getQuestStage(player, Quests.SEA_SLUG) >= 12) { + setVarp(player, questVarp, 12, true) // Except for stage 100 which is varp set to 12 obviously. + } else { + setVarp(player, questVarp, getQuestStage(player, Quests.SEA_SLUG), true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlugListeners.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlugListeners.kt new file mode 100644 index 000000000..79a1b10ab --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlugListeners.kt @@ -0,0 +1,196 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.global.action.ClimbActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class SeaSlugListeners : InteractionListener { + + companion object { + + // The boat travels are animated nicely for you by un-hiding child 10 - 13 + val BOAT_TRAVEL_CHILD = arrayOf(10, 11, 12, 13) + val BOAT_TRAVEL_TICKS = arrayOf(5, 9, 8, 7) + val BOAT_TRAVEL_DESTINATION = arrayOf( + Location(2782, 3273), // From LAND to PLATFORM + Location(2721, 3304), // From PLATFORM to LAND + Location(2800, 3320), // From PLATFORM to ISLAND + Location(2782, 3273), // From ISLAND to PLATFORM + ) + val BOAT_TRAVEL_DIALOGUE = arrayOf( + "You arrive at the fishing platform.", // From LAND to PLATFORM + "The boat arrives at Witchaven.", // From PLATFORM to LAND + "You arrive on a small island.", // From PLATFORM to ISLAND + "You arrive at the fishing platform.", // From ISLAND to PLATFORM + ) + + fun seaslugBoatTravel(player: Player, travelIndex: Int) { + if (travelIndex == 0) { + // Prevent bringing lit torches. + while(removeItem(player, Items.LIT_TORCH_594)) { + sendMessage(player, "Your torch goes out on the crossing.") + addItemOrDrop(player, Items.UNLIT_TORCH_596) + } + } + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when(stage){ + 0 -> { + closeOverlay(player) + openOverlay(player, Components.FADE_TO_BLACK_120) + lock(player, 2) + return@queueScript delayScript(player, 1) + } + 1 -> { + teleport(player, BOAT_TRAVEL_DESTINATION[travelIndex]) + openOverlay(player, Components.SEASLUG_BOAT_TRAVEL_461) + setComponentVisibility(player, Components.SEASLUG_BOAT_TRAVEL_461, BOAT_TRAVEL_CHILD[travelIndex], false) + lock(player, BOAT_TRAVEL_TICKS[travelIndex]) + return@queueScript delayScript(player, BOAT_TRAVEL_TICKS[travelIndex]) + } + 2 -> { + sendDialogue(player, BOAT_TRAVEL_DIALOGUE[travelIndex]) + player.interfaceManager.closeOverlay() + openOverlay(player, Components.FADE_FROM_BLACK_170) + return@queueScript stopExecuting(player) + } + } + return@queueScript stopExecuting(player) + } + } + + } + override fun defineListeners() { + // https://www.youtube.com/watch?v=VR91Rbyuou4 + // Your tinderbox is damp from the sea crossing. It won't light here. + // Your torch goes out on the crossing. + + onUseWith(IntType.ITEM, Items.SWAMP_TAR_1939, Items.POT_OF_FLOUR_1933){ player, used, with -> + val toRemove = Item(used.id, 1, used.asItem().slot) + if(removeItem(player, toRemove) && removeItem(player, with)) { + sendMessage(player, "You mix the flour with the swamp tar.") + sendMessage(player, "It mixes into a paste.") + addItemOrDrop(player, Items.EMPTY_POT_1931) + addItemOrDrop(player, Items.RAW_SWAMP_PASTE_1940) + } + return@onUseWith true + } + + // You can only cook it using firewood. + // sendMessage(player, "You can't cook that in a range.") + onUseWith(SCENERY, Items.RAW_SWAMP_PASTE_1940, Scenery.FIRE_2732) { player, used, with -> + val toRemove = Item(used.id, 1, used.asItem().slot) + if(removeItem(player, toRemove)) { + sendMessage(player, "You warm the paste over the fire. It thickens into a sticky goo.") + addItemOrDrop(player, Items.SWAMP_PASTE_1941) + } + return@onUseWith true + } + + + on(Scenery.LADDER_18324, IntType.SCENERY, "climb-up") { player, _ -> + if (getQuestStage(player, Quests.SEA_SLUG) in 5..6) { + if (getQuestStage(player, Quests.SEA_SLUG) == 6 && inInventory(player, Items.LIT_TORCH_594)) { + setQuestStage(player, Quests.SEA_SLUG, 7) + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, Location(2784, 3285, 1)) + } else { + animate(player, 4785) + sendMessage(player, "You attempt to climb up the ladder.") + sendMessage(player, "The fisherman approach you...") + sendMessage(player, "and smack you on the head with a fishing rod!") + sendMessage(player, "Ouch!") + sendChat(player, "Ouch!") + player.impactHandler.manualHit(player, 4, ImpactHandler.HitsplatType.NORMAL) + } + } else { + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, Location(2784, 3285, 1)) + } + return@on true + } + on(Scenery.LADDER_18325, IntType.SCENERY, "climb-down") { player, _ -> + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, Location(2784, 3287, 0)) + return@on true + } + + on(Scenery.BADLY_REPAIRED_WALL_18381, IntType.SCENERY, "kick") { player, _ -> + if(getQuestStage(player, Quests.SEA_SLUG) == 8) { + animate(player, 4804) + sendMessage(player, "You kick the loose panel.") + sendMessage(player, "The wood is rotted and crumbles away...") + sendMessage(player, "... leaving an opening big enough for Kennith to climb through.") + setQuestStage(player, Quests.SEA_SLUG, 9) + } else { + // https://youtu.be/OM-akv7oIZ0 2:41 + sendMessage(player, "You kick the loose panel...") + sendMessage(player, "... but nothing interesting happens.") + } + return@on true + } + + on(Scenery.CRANE_18327, IntType.SCENERY, "rotate") { player, node -> + if(getQuestStage(player, Quests.SEA_SLUG) == 10) { + // This is supposed to be a cutscene, but goddamn do I hate programming cutscenes. + lock(player, 6) + player.dialogueInterpreter.sendPlainMessage(true, "Kennith scrambles through the broken wall...") + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CRANE_18326, 6) + animateScenery(node as core.game.node.scenery.Scenery, 4798) + setQuestStage(player, Quests.SEA_SLUG, 11) + queueScript(player, 6, QueueStrength.SOFT) { stage: Int -> + sendDialogue(player, "Down below, you see Holgart collect the boy from the crane and lead him away to safety.") + return@queueScript stopExecuting(player) + } + } else { + sendMessage(player, "You rotate the crane around.") + animateScenery(node as core.game.node.scenery.Scenery, 4796) + } + return@on true + } + + onUseWith(IntType.ITEM, Items.DAMP_STICKS_1467, Items.BROKEN_GLASS_1469){ player, used, with -> + if(removeItem(player, used)) { + visualize(player, 4809, 791) + addItemOrDrop(player, Items.DRY_STICKS_1468) + } + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.DRY_STICKS_1468, Items.UNLIT_TORCH_596){ player, bolt, tip -> + addItemOrDrop(player, Items.LIT_TORCH_594) + return@onUseWith true + } + + on(Items.DRY_STICKS_1468, ITEM, "rub-together") { player, _ -> + sendMessage(player, "You rub together the dry sticks and the sticks catch alight.") + if(removeItem(player, Items.UNLIT_TORCH_596)) { + sendMessage(player, "You place the smouldering twigs to your torch.") + sendMessage(player, "Your torch lights.") + addItemOrDrop(player, Items.LIT_TORCH_594) + } + return@on true + } + + + on(NPCs.SEA_SLUG_1006, IntType.NPC, "take") { player, _ -> + sendMessage(player, "You pick up the sea slug.") + sendMessage(player, "It sinks its teeth deep into your hand.") + sendMessage(player, "You drop the sea slug.") + sendChat(player, "Ouch!") + impact(player, 3, HitsplatType.NORMAL) + return@on true + } + + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.java b/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.java deleted file mode 100644 index 08f548ac6..000000000 --- a/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.java +++ /dev/null @@ -1,96 +0,0 @@ -package content.region.kandarin.yanille.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used for the leon npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class LeonDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code LeonDialogue} {@code Object}. - */ - public LeonDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code LeonDialogue} {@code Object}. - * @param player the player. - */ - public LeonDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new LeonDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendOptions("Select an Option", "What is this place?", "Can I have a go with your crossbow?", "What are you holding there?"); - stage = 1; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.ASKING, "What is this place?"); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Can I have a go with your crossbow?"); - stage = 20; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.ASKING, "What are you holding there?"); - stage = 30; - break; - - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "This is Aleck's Hunter Emporium. Basically, it's just a", "shop with fancy name; you can buy various weapons", "and traps here."); - stage = 11; - break; - case 11: - end(); - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm afraid with it being a prototype, I've only got a few", "for my own testing purposes."); - stage = 21; - break; - case 21: - end(); - break; - case 30: - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "This? This is a prototype for a new type of crossbow", "I've been designing."); - stage = 31; - break; - case 31: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 5111 }; - } -} diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.kt b/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.kt new file mode 100644 index 000000000..f5e3b2463 --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.kt @@ -0,0 +1,134 @@ +package content.region.kandarin.yanille.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class LeonDialogue (player: Player? = null) : DialoguePlugin(player) { + + companion object { + const val WHAT_IS_THIS_PLACE = 10 + const val BUY_GEAR = 20 + const val ABOUT_CBOW = 30 + const val ABOUT_AMMO = 40 + const val BYE = 50 + const val CRAZY = 60 + const val TRADE = 70 + const val MAKE_OWN_AMMO = 80 + const val CRAFT_AMMO = 90 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (hasAnItem(player, Items.HUNTERS_CROSSBOW_10156).exists()) npcl(FacialExpression.HAPPY, "Oh, hey, you have one of my crossbows! How's it working for you?") + else sendItemDialogue(player, Items.HUNTERS_CROSSBOW_10156,"Leon is gazing intently at the crossbow in his hands.") + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> showTopics( + IfTopic("It's okay, thanks.", 0, hasAnItem(player, Items.HUNTERS_CROSSBOW_10156).exists()), + Topic("What is this place?", WHAT_IS_THIS_PLACE), + Topic("Can you tell me about your crossbow?", ABOUT_CBOW), + Topic("Tell me about the ammo for your crossbow.", ABOUT_AMMO), + Topic("I'll be off now, excuse me.", BYE), + + ) + + WHAT_IS_THIS_PLACE -> npcl(FacialExpression.NEUTRAL, "This is Aleck's Hunter Emporium. Basically, it's just a shop with a fancy name; you can buy various weapons and traps here.").also { stage++ } + WHAT_IS_THIS_PLACE + 1 -> showTopics( + Topic("Can I buy some equipment from the shop then?", BUY_GEAR), + Topic("Can you tell me about your crossbow?", ABOUT_CBOW), + Topic("Tell me about the ammo for your crossbow.", ABOUT_AMMO), + Topic("I'll be off now, excuse me.", BYE) + ) + + BUY_GEAR -> npcl(FacialExpression.NEUTRAL, "Oh, this isn't my shop; the owner is Aleck over there behind the counter.").also { stage++ } + BUY_GEAR + 1 -> npcl(FacialExpression.NEUTRAL, "I experiment with weapon designs. I'm here because I've been trying to convince people to back my research and maybe sell some of my products - like this one I'm holding - in their shops.").also { stage++ } + BUY_GEAR + 2 -> npcl(FacialExpression.SAD, "Aleck doesn't seem to be interested, though.").also { stage++ } + BUY_GEAR + 3 -> showTopics( + Topic("Can you tell me about your crossbow?", ABOUT_CBOW), + Topic("Tell me about the ammo for your crossbow.", ABOUT_AMMO), + Topic("I'll be off now, excuse me.", BYE) + ) + + ABOUT_CBOW -> npcl(FacialExpression.HAPPY, "It's good, isn't it? I designed it to incorporate the bones of various animals in its construction.").also { stage++ } + ABOUT_CBOW + 1 -> npcl(FacialExpression.HAPPY, "It's a fair bit faster than an ordinary crossbow too; it'll take you far less time to reload between shots.").also { stage++ } + ABOUT_CBOW + 2 -> showTopics( + Topic("That's crazy, it'll never work!", CRAZY), + Topic("That sounds good. Let's trade.", TRADE) + ) + + CRAZY -> npcl(FacialExpression.HALF_THINKING, "That's what they said about my wind-powered mouse traps, too.").also { stage++ } + CRAZY + 1 -> playerl(FacialExpression.HALF_WORRIED, "And did they work?").also { stage++ } + CRAZY + 2 -> npcl(FacialExpression.HALF_THINKING, "Well, they only ran into problems because people kept insisting on trying to use them indoors.").also { stage++ } + CRAZY + 3 -> npcl(FacialExpression.HAPPY, "Anyway, I think my crossbow invention is showing a lot more promise.").also { stage = 0 } + + TRADE -> { + end() + openNpcShop(player, npc.id) + } + + ABOUT_AMMO -> npcl(FacialExpression.NEUTRAL, "Ah, I admit as a result of its... er... unique construction, it won't take just any old bolts.").also { stage++ } + ABOUT_AMMO + 1 -> npcl(FacialExpression.NEUTRAL, "If you can supply the materials and a token fee, I'd be happy to make some for you.").also { stage++ } + ABOUT_AMMO + 2 -> npcl(FacialExpression.NEUTRAL, "I need kebbit spikes, lots of 'em. Not all kebbits have spikes, mind you. You'll be wanting prickly kebbits or, even better, razor-backed kebbits to get material hard enough.").also { stage++ } + ABOUT_AMMO + 3 -> showTopics( + Topic("Can't I just make my own?", MAKE_OWN_AMMO), + Topic("Okay, can you make ammo for me?", CRAFT_AMMO) + ) + + MAKE_OWN_AMMO -> npcl(FacialExpression.HALF_THINKING, "Yes, I suppose you could, although you'll need a steady hand with a knife and a chisel.").also { stage++ } + MAKE_OWN_AMMO + 1 -> npcl(FacialExpression.HALF_THINKING, "The bolts have an unusual diameter, but basically you'll just need to be able to carve kebbit spikes into straight shafts.").also { stage++ } + MAKE_OWN_AMMO + 2 -> npcl(FacialExpression.NEUTRAL, "Meanwhile, since you're here, I can make some for you if you have the materials.").also { stage = 0 } + + // OSRS suggests this may be inauthentic and there should be a make x interface. + // No 2009 sources found saying that though + CRAFT_AMMO -> npcl(FacialExpression.NEUTRAL, "Sure what type of bolts do you want?").also { stage++ } + CRAFT_AMMO + 1 -> showTopics( + Topic("Kebbit bolts.", CRAFT_AMMO + 2), + Topic("Long kebbit bolts.", CRAFT_AMMO + 3) + ) + CRAFT_AMMO + 2 -> { + if (hasAnItem(player!!, Items.KEBBIT_SPIKE_10105).exists() && inInventory(player, Items.COINS_995, 20)){ + if(removeItem(player, Items.KEBBIT_SPIKE_10105) && removeItem(player, Item(Items.COINS_995, 20))){ + addItem(player, Items.KEBBIT_BOLTS_10158, 6) + sendItemDialogue(player, Items.KEBBIT_BOLTS_10158, "You hand the weapon designer one spike and 20 coins. In return he presents you with 6 bolts.").also { stage = END_DIALOGUE } + } + } + else{ + sendItemDialogue(player, Items.KEBBIT_SPIKE_10105, "You need 1 kebbit spike and 20 coins to make 6 kebbit bolts.").also { stage = END_DIALOGUE } + } + } + CRAFT_AMMO + 3 -> { + if (hasAnItem(player!!, Items.LONG_KEBBIT_SPIKE_10107).exists() && inInventory(player, Items.COINS_995, 24)){ + if(removeItem(player, Items.LONG_KEBBIT_SPIKE_10107) && removeItem(player, Item(Items.COINS_995, 40))){ + addItem(player, Items.LONG_KEBBIT_BOLTS_10159, 6) + sendItemDialogue(player, Items.LONG_KEBBIT_BOLTS_10159, "You hand the weapon designer one long spike and 40 coins. In return he presents you with 6 long bolts.").also { stage = END_DIALOGUE } + } + } + else{ + sendItemDialogue(player, Items.LONG_KEBBIT_SPIKE_10107, "You need 1 long kebbit spike and 40 coins to make 6 kebbit bolts.").also { stage = END_DIALOGUE } + } + } + + BYE -> npcl(FacialExpression.NEUTRAL, "Well, if you ever find yourself in need of that innovative edge, you can always find me here.").also { stage++ } + BYE + 1 -> playerl(FacialExpression.HALF_ROLLING_EYES, "...thanks").also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LEON_5111) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/ZavisticRarveDialogue.kt b/Server/src/main/content/region/kandarin/yanille/dialogue/ZavisticRarveDialogue.kt new file mode 100644 index 000000000..9ccbedc95 --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/ZavisticRarveDialogue.kt @@ -0,0 +1,120 @@ +package content.region.kandarin.yanille.dialogue + +import content.region.kandarin.feldip.quest.zogreflesheaters.ZogreFleshEaters +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ZavisticRarveDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return ZavisticRarveDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ZavisticRarveDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ZAVISTIC_RARVE_2059) + } +} +class ZavisticRarveDialogueFile : DialogueBuilderFile() { + + companion object { + fun dialogueInitialTalk(builder: DialogueBuilder) : DialogueBuilder { + return builder + .branch { player -> + return@branch if (getQuestStage(player, ZogreFleshEaters.questName) > 3 /* || hand in the sand quest */) { + 1 + } else { + 0 + } + }.let { branch2 -> + val returnJoin = builder.placeholder() + branch2.onValue(1) + .npcl("What are you doing...Oh, it's you...sorry...didn't realise...what can I do for you?") + // There is a fork here if you are doing hand in the sand. + .goto(returnJoin) + branch2.onValue(0) + .npcl("What are you doing bothering me? Don't you think some of us have work to do?") + .playerl("I thought you were here to help?") + .npcl("Well... I am, I suppose, anyway... we're very busy here, hurry up, what do you want?") + .goto(returnJoin) + return@let returnJoin.builder() + } + } + + fun dialogueInitialTalkViaBell(builder: DialogueBuilder) : DialogueBuilder { + return builder + .branch { player -> + return@branch if (getQuestStage(player, ZogreFleshEaters.questName) > 3 /* || hand in the sand quest */) { + 1 + } else { + 0 + } + }.let { branch2 -> + val returnJoin = builder.placeholder() + branch2.onValue(1) + .npcl("What are you doing...Oh, it's you...sorry...didn't realise...what can I do for you?") + .goto(returnJoin) + branch2.onValue(0) + .npcl("What are you doing ringing that bell?! Don't you think some of us have work to do?") + .playerl("But I was told to ring the bell if I wanted some attention.") + .npcl("Well...anyway...we're very busy here, hurry up what do you want?") + .goto(returnJoin) + return@let returnJoin.builder() + } + } + + fun defaultTalk(continueBuilder: DialogueBuilder) { + continueBuilder.let { builder -> + val returnJoin = builder.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("What is there to do in the Wizards' Guild?") + .npcl("This is the finest wizards' establishment in the land.") + .npcl("We have magic portals to the other towers of wizardry around Gielinor.") + .npcl("We have a particularly wide collection of runes in our rune shop.") + .npcl("We sell some of the finest mage robes in the land and we have a training area full of zombies for you to practice your magic on.") + .goto(returnJoin) + optionBuilder.option_playerl("What are the requirements to get in the Wizards' Guild?") + .npcl("You need a magic level of 66, the high magic energy level is too dangerous for anyone below that level.") + .goto(returnJoin) + optionBuilder.option_playerl("What do you do in the Guild?") + .npcl("I'm the Grand Secretary for the Wizards' Guild, I have lots of correspondence to keep up with, as well as attending to the discipline of the more problematic guild members.") + .goto(returnJoin) + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + builder.goto(returnJoin) + } + } + } + + + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> isQuestComplete(player, ZogreFleshEaters.questName) } + .let { dialogueInitialTalk(it) } + .let { defaultTalk(it) } + + // This is during the ZogreFleshEaters quest + b.onPredicate { player -> isQuestInProgress(player, ZogreFleshEaters.questName, 2, 99) } + .manualStage() { df, player, _, _ -> + openDialogue(player, content.region.kandarin.feldip.quest.zogreflesheaters.ZavisticRarveDialogueFile(), npc!!) + } + .end() + + b.onPredicate { _ -> true } + .let { dialogueInitialTalk(it) } + .let { defaultTalk(it) } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/AlfonseWaiterDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/AlfonseWaiterDialogue.java deleted file mode 100644 index 72c201399..000000000 --- a/Server/src/main/content/region/karamja/brimhaven/dialogue/AlfonseWaiterDialogue.java +++ /dev/null @@ -1,92 +0,0 @@ -package content.region.karamja.brimhaven.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin for the npc alfonse the waiter. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class AlfonseWaiterDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code AlfonseWaiterDialogue} {@code Object}. - */ - public AlfonseWaiterDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code AlfonseWaiterDialogue} {@code Object}. - * @param player the player. - */ - public AlfonseWaiterDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new AlfonseWaiterDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Welcome to the Shrimp and Parrot.", "Would you like to order, sir?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you.", "Where do you get your Karambwan from?"); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thank you."); - stage = 20; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where do you get your Karambwan from?"); - stage = 30; - break; - } - break; - case 10: - end(); - npc.openShop(player); - break; - case 20: - end(); - break; - case 30: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "We buy directly off Lubufu, a local fisherman. He", "seems to have a monopoly over Karambwan sales."); - stage = 31; - break; - case 31: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 793 }; - } -} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/GarvDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/GarvDialogue.java deleted file mode 100644 index 8f995db1e..000000000 --- a/Server/src/main/content/region/karamja/brimhaven/dialogue/GarvDialogue.java +++ /dev/null @@ -1,88 +0,0 @@ -package content.region.karamja.brimhaven.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the garv dialogue plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class GarvDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code GarvDialogue} {@code Object}. - */ - public GarvDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code GarvDialogue} {@code Object}. - * @param player the player. - */ - public GarvDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new GarvDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello. What do you want?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Can I go in there?", "I want for nothing!"); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I go in there?"); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I want for nothing!"); - stage = 20; - break; - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No. In there is private."); - stage = 11; - break; - case 11: - end(); - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're one of a very lucky few then."); - stage = 21; - break; - case 21: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 788 }; - } -} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/GruborDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/GruborDialogue.java deleted file mode 100644 index c181f9399..000000000 --- a/Server/src/main/content/region/karamja/brimhaven/dialogue/GruborDialogue.java +++ /dev/null @@ -1,99 +0,0 @@ -package content.region.karamja.brimhaven.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the grubor dialogue plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class GruborDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code GruborDialogue} {@code Object}. - */ - public GruborDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code GruborDialogue} {@code Object}. - * @param player the player. - */ - public GruborDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new GruborDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes? What do you want?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Would you like your hedges trimming?", "I want to come in.", "Do you want to trade?"); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Would you like your hedges trimming?"); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I want to come in."); - stage = 20; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you want to trade?"); - stage = 30; - break; - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Eh? Don't be daft! We don't even HAVE any hehdges!"); - stage = 11; - break; - case 11: - end(); - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, go away."); - stage = 21; - break; - case 21: - end(); - break; - case 30: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, I'm busy."); - stage = 31; - break; - case 31: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 789 }; - } -} diff --git a/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt index ddb5c270a..e2b43bc28 100644 --- a/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt +++ b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt @@ -44,21 +44,6 @@ class BrimhavenListeners : InteractionListener { */ private const val RESTAURANT_REAR_DOOR = Scenery.DOOR_1591 - /** - * Represents the door of the Black Arm Gang office used in the Heroes' Quest. - */ - private const val GANG_OFFICE_DOOR = Scenery.DOOR_2626 - - /** - * Represents the door guarded by Garv on ScarFace Pete's mansion used in the Heroes' Quest. - */ - private const val MANSION_DOOR = Scenery.DOOR_2627 - - /** - * Represents the kitchen door in the Shrimp and Parrot restaurant used in the Heroes' Quest. - */ - private const val RESTAURANT_KITCHEN_DOOR = Scenery.DOOR_2628 - /** * Represents Lubufu's karambwan fishing spot unlocked in Tai Bwo Wannai Trio. */ @@ -108,21 +93,6 @@ class BrimhavenListeners : InteractionListener { return@on true } - on(GANG_OFFICE_DOOR, IntType.SCENERY, "open") { player, _ -> - openDialogue(player, 789, Repository.findNPC(789)!!) - return@on true - } - - on(MANSION_DOOR, IntType.SCENERY, "open") { player, _ -> - openDialogue(player, 788, Repository.findNPC(788)!!, true) - return@on true - } - - on(RESTAURANT_KITCHEN_DOOR, IntType.SCENERY, "open") { player, _ -> - sendMessage(player, "The door is securely closed.") - return@on true - } - on(KARAMBWAN_FISHING_SPOT, IntType.NPC, "fish") { player, _ -> sendNPCDialogue( player, diff --git a/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java b/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java index 164df698b..b32c1bfa0 100644 --- a/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java +++ b/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java @@ -10,6 +10,7 @@ import core.plugin.Initializable; import core.game.world.map.Location; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents the dialogue plugin used to handle the customs officer. @@ -54,7 +55,7 @@ public final class CustomsOfficerDialogue extends DialoguePlugin { public boolean open(Object... args) { npc = (NPC) args[0]; if (args.length > 1) { - if (player.getQuestRepository().isComplete("Pirate's Treasure")) { + if (player.getQuestRepository().isComplete(Quests.PIRATES_TREASURE)) { if (player.getInventory().containsItem(RUM)) { interpreter.sendDialogues(npc, null, "Aha, trying to smuggle rum are we?"); stage = 900; diff --git a/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java b/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java index 826467b8b..a29ad6b17 100644 --- a/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java +++ b/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java @@ -7,6 +7,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the customs officer plugin. @@ -25,7 +26,7 @@ public final class CustomsOfficerPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - if (!player.getQuestRepository().isComplete("Pirate's Treasure")) { + if (!player.getQuestRepository().isComplete(Quests.PIRATES_TREASURE)) { player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node)); player.getPacketDispatch().sendMessage("You may only use the Pay-fare option after completing Pirate's Treasure."); return true; diff --git a/Server/src/main/content/region/karamja/handlers/TribesmanNPC.java b/Server/src/main/content/region/karamja/handlers/TribesmanNPC.java deleted file mode 100644 index 184357c1d..000000000 --- a/Server/src/main/content/region/karamja/handlers/TribesmanNPC.java +++ /dev/null @@ -1,48 +0,0 @@ -package content.region.karamja.handlers; - -import core.game.node.entity.npc.AbstractNPC; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.game.system.config.NPCConfigParser; - -/** - * Represents the tribesamn npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class TribesmanNPC extends AbstractNPC { - - /** - * Represents the npc ids. - */ - private static final int[] IDS = new int[] { 191, 2496, 2497 }; - - /** - * Constructs a new {@code TribesmanNPC} {@code Object}. - * @param id the id. - * @param location the location. - */ - public TribesmanNPC(int id, Location location) { - super(id, location, true); - getDefinition().getHandlers().put(NPCConfigParser.POISONOUS, true); - } - - /** - * Constructs a new {@code TribesmanNPC} {@code Object}. - */ - public TribesmanNPC() { - super(0, null); - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new TribesmanNPC(id, location); - } - - @Override - public int[] getIds() { - return IDS; - } - -} diff --git a/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java index 9263035b8..5639c3b20 100644 --- a/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java +++ b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java @@ -14,6 +14,7 @@ import core.tools.RandomFunction; import core.tools.StringUtils; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * The main type or the jungle potion quest. @@ -23,16 +24,11 @@ import static core.api.ContentAPIKt.*; @Initializable public final class JunglePotion extends Quest { - /** - * The name of the quest. - */ - public static final String NAME = "Jungle Potion"; - /** * Constructs a new {@code JunglePotion} {@code Object}. */ public JunglePotion() { - super(NAME, 81, 80, 1, 175, 0, 1, 12); + super(Quests.JUNGLE_POTION, 81, 80, 1, 175, 0, 1, 12); } @Override @@ -119,7 +115,7 @@ public final class JunglePotion extends Quest { }); } }, - PALM_TREE(2577, Herbs.ARDRIGAL, 20, "You are looking for Ardrigal. It is related to the palm", "and grows in its brothers shady profusion."), SITO_FOIL(2579, Herbs.SITO_FOIL, 30, "You are looking for Sito Foil, and it grows best where", "the ground has been blackened by the living flame."), VOLENCIA_MOSS(2581, Herbs.VOLENCIA_MOSS, 40, "You are looking for Volencia Moss. It clings to rocks", "for its existence. It is difficult to see, so you must", "search for it well."), ROGUES_PURSE(32106, Herbs.ROGUES_PUSE, 50, "It inhabits the darkness of the underground, and grows", "in the caverns to the north. A secret entrance to the", "caverns is set into the northern cliffs, be careful Bwana.") { + PALM_TREE(2577, Herbs.ARDRIGAL, 20, "You are looking for Ardrigal. It is related to the palm", "and grows in its brothers shady profusion."), SITO_FOIL(2579, Herbs.SITO_FOIL, 30, "You are looking for Sito Foil, and it grows best where", "the ground has been blackened by the living flame."), VOLENCIA_MOSS(2581, Herbs.VOLENCIA_MOSS, 40, "You are looking for Volencia Moss. It clings to rocks", "for its existence. It is difficult to see, so you must", "search for it well."), ROGUES_PURSE(32106, Herbs.ROGUES_PURSE, 50, "It inhabits the darkness of the underground, and grows", "in the caverns to the north. A secret entrance to the", "caverns is set into the northern cliffs, be careful Bwana.") { @Override public void search(final Player player, final Scenery object) { final Animation animation = Animation.create(2097); diff --git a/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java index d1ac8fcf9..5828060ba 100644 --- a/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java +++ b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java @@ -1,5 +1,6 @@ package content.region.karamja.quest.junglepotion; +import content.data.Quests; import core.cache.def.impl.SceneryDefinition; import core.game.dialogue.DialogueInterpreter; import core.game.dialogue.DialoguePlugin; @@ -33,7 +34,7 @@ public final class JunglePotionPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest(JunglePotion.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.JUNGLE_POTION); switch (node.getId()) { case 2584: player.getDialogueInterpreter().open("jogre_dialogue"); diff --git a/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java b/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java index df5e52885..267bef03c 100644 --- a/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java +++ b/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java @@ -1,5 +1,6 @@ package content.region.karamja.quest.junglepotion; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -48,7 +49,7 @@ public final class TrufitusDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(JunglePotion.NAME); + quest = player.getQuestRepository().getQuest(Quests.JUNGLE_POTION); switch (quest.getStage(player)) { case 0: npc("Greetings Bwana! I am Trufitus Shakaya of the Tai", "Bwo Wannai village."); diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt index 74ce79ed9..a8d2da26e 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -116,8 +117,9 @@ class ArdougneGuideBook : InteractionListener { } override fun defineListeners() { - on(Items.GUIDE_BOOK_1856, IntType.ITEM, "read") { player, _ -> + on(Items.GUIDE_BOOK_1856, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt index a8d6ba8ea..54ec527f3 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt @@ -14,6 +14,7 @@ import core.ServerConstants import core.api.playAudio import core.game.world.GameWorld import org.rs09.consts.Sounds +import content.data.Quests @Initializable class CrompertyDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { @@ -32,7 +33,7 @@ class CrompertyDialogue(player: Player? = null) : core.game.dialogue.DialoguePlu 1 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Two jobs? That's got to be tough.").also { stage = 5 } 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So, what have you invented?").also { stage = 10 } 3 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Can you teleport me to the Rune Essence?").also { - if(player.questRepository.isComplete("Rune Mysteries")){ + if(player.questRepository.isComplete(Quests.RUNE_MYSTERIES)){ EssenceTeleport.teleport(npc,player) end() } @@ -73,7 +74,7 @@ class CrompertyDialogue(player: Player? = null) : core.game.dialogue.DialoguePlu 28 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish.").also { stage = 1000 } 30 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Okey dokey! Ready?").also { - stage = if(player.questRepository.hasStarted("Tribal Totem") && player.questRepository.getStage("Tribal Totem") < 50) { + stage = if(player.questRepository.hasStarted(Quests.TRIBAL_TOTEM) && player.questRepository.getStage(Quests.TRIBAL_TOTEM) < 50) { 35 } else 31 @@ -110,12 +111,12 @@ class CrompertyDialogue(player: Player? = null) : core.game.dialogue.DialoguePlu npc.sendChat("Dipsolum sententa sententi!") GameWorld.Pulser.submit(object : Pulse(1) { var counter = 0 - var delivered = player.questRepository.getStage("Tribal Totem") >= 25 + var delivered = player.questRepository.getStage(Quests.TRIBAL_TOTEM) >= 25 override fun pulse(): Boolean { when(counter++){ 2 -> { if(delivered) { - player.questRepository.getQuest("Tribal Totem").setStage(player,30) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,30) player.properties.teleportLocation = LOCATIONS[1] } else player.properties.teleportLocation = LOCATIONS[0] diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt index da8cd274e..09cc8aea8 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt @@ -4,12 +4,13 @@ import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable +import content.data.Quests @Initializable class HoracioDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { - if(player.questRepository.hasStarted("Tribal Totem")){ + if(player.questRepository.hasStarted(Quests.TRIBAL_TOTEM)){ npcl(FacialExpression.HAPPY,"It's a fine day to be out in a garden, isn't it? ") stage = 5 } diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt index 9f35bc75f..1e72fbd22 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt @@ -7,15 +7,16 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable class KangaiMauDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { - if(!player.questRepository.hasStarted("Tribal Totem")){ + if(!player.questRepository.hasStarted(Quests.TRIBAL_TOTEM)){ npcl(FacialExpression.HAPPY,"Hello. I'm Kangai Mau of the Rantuki Tribe.") stage = 0 - } else if(isQuestComplete(player, "Tribal Totem")) { + } else if(isQuestComplete(player, Quests.TRIBAL_TOTEM)) { npcl(FacialExpression.HAPPY, "Many greetings esteemed thief.") stage = 40 } @@ -23,7 +24,7 @@ class KangaiMauDialogue(player: Player? = null) : DialoguePlugin(player) { npcl(FacialExpression.ASKING,"Have you got our totem back?") stage = 35 } - else if(player.questRepository.hasStarted("Tribal Totem")){ + else if(player.questRepository.hasStarted(Quests.TRIBAL_TOTEM)){ npcl(FacialExpression.ASKING,"Have you got our totem back?") stage = 30 } @@ -55,8 +56,8 @@ class KangaiMauDialogue(player: Player? = null) : DialoguePlugin(player) { 20 -> playerl(FacialExpression.THINKING,"How can I find Handlemoret's house? Ardougne IS a big place...").also { stage++ } 21 -> npcl(FacialExpression.ANNOYED,"I don't know Ardougne. You tell me.").also { stage++ } 22 -> playerl(FacialExpression.HAPPY,"Ok, I will get it back.").also { - player.questRepository.getQuest("Tribal Totem").start(player) - player.questRepository.getQuest("Tribal Totem").setStage(player, 10) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).start(player) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player, 10) stage++ } 23 -> npcl(FacialExpression.HAPPY,"Best of luck with that adventurer").also { stage = 1000 } @@ -66,8 +67,8 @@ class KangaiMauDialogue(player: Player? = null) : DialoguePlugin(player) { 35 -> playerl(FacialExpression.HAPPY,"Yes I have.").also { stage++ } 36 -> npcl(FacialExpression.HAPPY,"You have??? Many thanks brave adventurer! Here, have some freshly cooked Karamjan fish, caught specially by my tribe.").also { stage++ } 37 -> sendDialogue("You hand over the totem").also { - if(!isQuestComplete(player, "Tribal Totem") && removeItem(player, Items.TOTEM_1857)) { - player.questRepository.getQuest("Tribal Totem").finish(player) + if(!isQuestComplete(player, Quests.TRIBAL_TOTEM) && removeItem(player, Items.TOTEM_1857)) { + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).finish(player) stage = 1000 } else { stage = 1000 diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt index 6a4c0cbf2..2bd933011 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt @@ -5,12 +5,13 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests @Initializable class RPDTEmployeeDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npcl(FacialExpression.HAPPY,"Welcome to R.P.D.T.!") - stage = if(player.questRepository.getStage("Tribal Totem") == 20){ + stage = if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) == 20){ 5 }else 0 return true @@ -22,7 +23,7 @@ class RPDTEmployeeDialogue(player: Player? = null) : DialoguePlugin(player) { 5 -> playerl(FacialExpression.ASKING,"So, when are you going to deliver this crate?").also { stage++ } 6 -> npcl(FacialExpression.THINKING,"Well... I guess we could do it now...").also { - player.questRepository.getQuest("Tribal Totem").setStage(player,25) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,25) stage = 1000 } diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt index dbb4c6096..97a16f7d9 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt @@ -8,6 +8,7 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.data.Quests class TribalTotemListeners : InteractionListener { @@ -22,19 +23,21 @@ class TribalTotemListeners : InteractionListener { override fun defineListeners() { on(frontDoor, IntType.SCENERY, "Open"){ player, door -> - if(player.questRepository.getStage("Tribal Totem") >= 35){ + if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) >= 35){ core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,door.asScenery()) } - sendMessage(player,"The door is locked shut.") + else { + sendMessage(player,"The door is locked shut.") + } return@on true } on(realCrate, IntType.SCENERY, "Investigate"){ player, node -> - if(player.questRepository.getStage("Tribal Totem") in 1..19 && !player.inventory.containsAtLeastOneItem(Items.ADDRESS_LABEL_1858)){ - sendDialogue(player,"There is a label on this crate. It says; To Lord Handelmort, Handelmort Mansion Ardogune.You carefully peel it off and take it.") - addItem(player,Items.ADDRESS_LABEL_1858,1) + if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) in 1..19 && !player.inventory.containsAtLeastOneItem(Items.ADDRESS_LABEL_1858)){ + sendDialogue(player,"There is a label on this crate. It says; To Lord Handelmort, Handelmort Mansion, Ardougne.You carefully peel it off and take it.") + addItemOrDrop(player,Items.ADDRESS_LABEL_1858,1) } - else if(player.questRepository.getStage("Tribal Totem") in 1..19 && player.inventory.containsAtLeastOneItem(Items.ADDRESS_LABEL_1858)){ + else if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) in 1..19 && player.inventory.containsAtLeastOneItem(Items.ADDRESS_LABEL_1858)){ sendDialogue(player,"There was a label on this crate, but it's gone now since you took it!") } return@on true @@ -48,7 +51,7 @@ class TribalTotemListeners : InteractionListener { onUseWith(IntType.SCENERY,label,wizCrate){ player, used, with -> sendDialogue(player,"You carefully place the delivery address label over the existing label, covering it completely.") removeItem(player,label) - player.questRepository.getQuest("Tribal Totem").setStage(player,20) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,20) return@onUseWith true } @@ -95,7 +98,8 @@ class TribalTotemListeners : InteractionListener { on(openChest, IntType.SCENERY, "Search"){ player, node -> if(!player.inventory.containsAtLeastOneItem(Items.TOTEM_1857)){ sendDialogue(player,"Inside the chest you find the tribal totem.") - addItem(player,Items.TOTEM_1857) + addItemOrDrop(player,Items.TOTEM_1857) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,35) } else{ sendDialogue(player,"Inside the chest you don't find anything because you already took the totem!") diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt index ea707ce49..c89baea9e 100644 --- a/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt @@ -1,7 +1,6 @@ package content.region.karamja.quest.tribaltotem import core.api.rewardXP -import core.game.content.quest.fremtrials.FremennikTrials import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills @@ -9,9 +8,10 @@ import core.game.node.item.GroundItemManager import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable -class TribalTotem : Quest("Tribal Totem",126,125,1,200,0,1,5){ +class TribalTotem : Quest(Quests.TRIBAL_TOTEM,126,125,1,200,0,1,5){ class SkillRequirement(val skill: Int?, val level: Int?) val requirements = arrayListOf() @@ -19,14 +19,14 @@ class TribalTotem : Quest("Tribal Totem",126,125,1,200,0,1,5){ override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) var line = 11 - val started = player?.questRepository?.getStage("Tribal Totem")!! > 0 + val started = player?.questRepository?.getStage(Quests.TRIBAL_TOTEM)!! > 0 if(!started){ - line(player,"I can start this quest by speaking to !!Kangai Mau?? in",line++) - line(player,"!!Shrimp & Parrot?? restaurant in Brimhaven.",line++) + line(player,"I can start this quest by speaking to !!Kangai Mau?? in !!the??",line++) + line(player,"!!Shrimp & Parrot?? restaurant in Brimhaven",line++) line += 1 line(player,"To complete this quest I need:",line++) - line(player,"!!Level 21 Theiving??",line++, player?.skills?.getStaticLevel(Skills.THIEVING)!! >= 21) + line(player,"!!Level 21 Thieving??",line++, player?.skills?.getStaticLevel(Skills.THIEVING)!! >= 21) } else if(started && stage != 100){ if(stage >= 10){ diff --git a/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java b/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java index 5176ad97b..e06e1ad09 100644 --- a/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java +++ b/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java @@ -12,6 +12,7 @@ import core.plugin.Initializable; import core.plugin.Plugin; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** @@ -41,7 +42,7 @@ public class BrokenCartBypass extends OptionHandler { }); } public final boolean handle(Player player, Node node, String options){ - if (!hasRequirement(player, "Shilo Village")) + if (!hasRequirement(player, Quests.SHILO_VILLAGE)) return true; Location location = new Location(0,0); Location playerloc = new Location(player.getLocation().getX(),player.getLocation().getY()); diff --git a/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt b/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt index b432a0cf9..1b15bbcab 100644 --- a/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt +++ b/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt @@ -14,6 +14,7 @@ import core.tools.END_DIALOGUE import org.rs09.consts.Components import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests class ShiloCart : InteractionListener { @@ -67,7 +68,7 @@ class ShiloCart : InteractionListener { class CartQuickPay : DialogueFile(){ override fun handle(interfaceId: Int, buttonId: Int) { - if (!hasRequirement(player!!, "Shilo Village")) return; + if (!hasRequirement(player!!, Quests.SHILO_VILLAGE)) return; val shilo = npc?.id == 510; when (stage) { 0 -> if(inInventory(player!!,Items.COINS_995,10)){ @@ -103,7 +104,7 @@ class CartQuickPay : DialogueFile(){ class CartTravelDialogue : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { - if (!hasRequirement(player!!, "Shilo Village")) return; + if (!hasRequirement(player!!, Quests.SHILO_VILLAGE)) return; val shilo = npc?.id == 510; when (stage) { 0 -> npcl("I am offering a cart ride to " + (if (shilo) "Shilo Village" else "Brimhaven") + " if you're interested? It will cost 10 gold coins. Is that Ok?").also { stage++ } @@ -117,4 +118,4 @@ class CartTravelDialogue : DialogueFile(){ 4 -> openDialogue(player!!,CartQuickPay(),npc!!) } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarDialogue.kt b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarDialogue.kt new file mode 100644 index 000000000..bac301a6a --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarDialogue.kt @@ -0,0 +1,49 @@ +package content.region.karamja.tzhaar.handlers + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class TzHaarDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HALF_GUILTY, "Can I help you JalYt-Ket-${player.username}?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "What do you have to trade?", 10, true), + Topic(FacialExpression.HALF_GUILTY, "What did you call me?", 20), + Topic(FacialExpression.HALF_GUILTY, "No I'm fine thanks.", END_DIALOGUE), + ) + 10 -> end().also { openNpcShop(player, npc.id) } + 20 -> npcl(FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?").also { stage++ } + 21 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?", 22), + Topic(FacialExpression.HALF_GUILTY, "I guess so...", 25), + Topic(FacialExpression.HALF_GUILTY, "No I'm not!", END_DIALOGUE) + ) + + 22 -> npcl(FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?").also { stage++ } + 23 -> playerl(FacialExpression.HALF_GUILTY, "Well yes I suppose I am...").also { stage++ } + 24 -> npcl(FacialExpression.HALF_GUILTY, "Then you JalYt-Ket!").also { stage = END_DIALOGUE } + + 25 -> npcl(FacialExpression.HALF_GUILTY, "Well then, no problems.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TZHAAR_HUR_TEL_2620, NPCs.TZHAAR_HUR_LEK_2622, NPCs.TZHAAR_MEJ_ROH_2623) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJah.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJah.java deleted file mode 100644 index 09653c566..000000000 --- a/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJah.java +++ /dev/null @@ -1,313 +0,0 @@ -package content.region.karamja.tzhaar.handlers; - -import core.game.dialogue.DialogueInterpreter; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; -import core.game.world.GameWorld; - -/** - * Handles the TzHaarMejJal dialogue. - * @author 'Vexia - * @author Empathy - * @author Logg - */ -@Initializable -public class TzHaarMejJah extends DialoguePlugin { - private static final Item APPEARANCE_FEE = new Item(6529, 8000); // 8000 tokkul, about the same as you get from failing jad - - public TzHaarMejJah() { - - } - - public TzHaarMejJah(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new TzHaarMejJah(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You want help JalYt-Ket-" + player.getUsername() + "?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - if (GameWorld.getSettings().getJad_practice_enabled()) { - if (player.getAttribute("fc_practice_jad", false)) { - interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "About my challenge...", "No I'm fine thanks."); - } else { - interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "I want to challenge Jad directly.", "No I'm fine thanks."); - } - } else { - interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "No I'm fine thanks."); - } - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - if (player.getInventory().containItems(6570)) { - interpreter.open(DialogueInterpreter.getDialogueKey("firecape-exchange"), npc); - break; - } - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What did you call me?"); - stage = 20; - break; - case 3: - if (GameWorld.getSettings().getJad_practice_enabled()) { - if (player.getAttribute("fc_practice_jad", false)) { - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "About my challenge..."); - stage = 64; - } else { - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "The challenge is too long.", "I want to challenge Jad directly."); - stage = 50; - } - } else { - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks."); - stage = 30; - } - break; - case 4: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks."); - stage = 30; - break; - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the fight caves, TzHaar-Xil made it for practice,", "but many JalYt come here to fight too.", "Just enter the cave and make sure you're prepared."); - stage = 11; - break; - case 11: - interpreter.sendOptions("Select an Option", "Are there any rules?", "Ok thanks."); - stage = 12; - break; - case 12: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are there any rules?"); - stage = 14; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok thanks."); - stage = 13; - break; - } - break; - case 13: - end(); - break; - case 14: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Rules? Survival is the only rule in there."); - stage = 15; - break; - case 15: - interpreter.sendOptions("Select an Option", "Do I win anything?", "Sounds good."); - stage = 16; - break; - case 16: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do I win anything?"); - stage = 17; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds good."); - stage = 13; - break; - - } - break; - case 17: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You ask a lot of questions.", "Might give you TokKul if you last long enough."); - stage = 18; - break; - case 18: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "..."); - stage = 19; - break; - case 19: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Before you ask, TokKul is like your Coins."); - stage = 500; - break; - case 500: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gold is like you JalYt, soft and easily broken, we use", "hard rock forged in fire like TzHaar!"); - stage = 501; - break; - case 501: - end(); - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?"); - stage = 21; - break; - case 21: - interpreter.sendOptions("Select an Option", "What's a 'JalYt-Ket'?", "I guess so...", "No I'm not!"); - stage = 22; - break; - case 22: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?"); - stage = 100; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so..."); - stage = 200; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm not!"); - stage = 300; - break; - } - break; - case 100: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?"); - stage = 101; - break; - case 101: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well yes I suppose I am..."); - stage = 102; - break; - case 102: - end(); - break; - case 200: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so...."); - stage = 201; - break; - case 201: - end(); - break; - case 300: - end(); - break; - case 30: - end(); - break; - - case 50: - interpreter.sendDialogues(npc, FacialExpression.DISGUSTED_HEAD_SHAKE, "I thought you strong and tough", "but you want skip endurance training?"); - stage = 57; - break; - case 57: - interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Maybe you not JalYt-Ket afterall."); - stage = 58; - break; - case 58: - interpreter.sendOptions("Select an Option", "I don't have time for it, man.", "No, I'm JalYt-Ket!"); - stage = 51; - break; - case 51: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have time for it, man."); - stage = 52; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I'm JalYt-Ket! I swear!", "I'll do the training properly."); - stage = 30; - break; - } - break; - case 52: - interpreter.sendDialogues(npc, FacialExpression.DISGUSTED_HEAD_SHAKE, "JalYt, you know you not get reward","if you not do training properly, ok?"); - stage = 56; - break; - case 56: - interpreter.sendOptions("Select an Option", "That's okay, I don't need a reward.", "Oh, nevermind then."); - stage = 53; - break; - case 53: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's okay, I don't need a reward."); - stage = 54; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, nevermind then."); - stage = 30; - break; - } - break; - case 54: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I just wanna fight the big guy."); - stage = 55; - break; - case 55: - interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Okay JalYt.","TzTok-Jad not show up for just anyone."); - stage = 59; - break; - case 59: - interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "You give 8000 TokKul, TzTok-Jad know you serious.", "You get it back if you victorious."); - stage = 60; - break; - case 60: - interpreter.sendOptions("Select an Option", "That's fair, here's 8000 TokKul.", "I don't have that much on me, but I'll go get it.", "TzTok-Jad must be old and tired to not just accept my challenge."); - stage = 61; - case 61: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's fair, here's 8000 TokKul."); - if (!player.getInventory().containsItem(APPEARANCE_FEE)) { - stage = 62; - break; - } - if (player.getInventory().remove(APPEARANCE_FEE)) { - stage = 69; - } else { - stage = 62; - } - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have that much on me, but I'll go get it."); - stage = 30; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "TzTok-Jad must be old and tired", "to not just accept my challenge."); - stage = 63; - break; - } - break; - case 62: - interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "JalYt, you not have the TokKul.", "You come back when you are serious."); - stage = 30; - break; - case 63: - interpreter.sendDialogues(npc, FacialExpression.ANGRY, "JalYt-Mor, you the old and tired one.", "You the one not want to do proper training."); - stage = 30; - break; - case 64: - interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "TzTok-Jad is waiting for you.", "Do not make TzTok-Jad wait long."); - stage = 30; - break; - case 69: - interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Okay JalYt. Enter cave when you are prepared.", "You find TzTok-Jad waiting for JalYt challenger."); - player.setAttribute("fc_practice_jad", true); - stage = 30; - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { DialogueInterpreter.getDialogueKey("tzhaar-mej"), 2617 }; - } -} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJal.kt b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJal.kt new file mode 100644 index 000000000..a0b865ca7 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJal.kt @@ -0,0 +1,167 @@ +package content.region.karamja.tzhaar.handlers + +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.GameWorld.settings +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Handles the TzHaarMejJal dialogue. + * @author 'Vexia + * @author Empathy + * @author Logg + */ +@Initializable +class TzHaarMejJal(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HALF_GUILTY, "You want help JalYt-Ket-${player.username}?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> showTopics( + if (inInventory(player, Items.FIRE_CAPE_6570)) { + Topic(FacialExpression.HALF_GUILTY, "I have a fire cape here.", 100) + } else { + Topic(FacialExpression.HALF_GUILTY, "What is this place?", 10) + }, + Topic(FacialExpression.HALF_GUILTY, "What did you call me?", 20), + IfTopic(FacialExpression.HALF_GUILTY, "About my challenge...", 50, getAttribute(player, "fc_practice_jad", false) && settings!!.jad_practice_enabled), + IfTopic("I want to challenge Jad directly.", 30, !getAttribute(player, "fc_practice_jad", false) && settings!!.jad_practice_enabled, skipPlayer = true), + Topic(FacialExpression.HALF_GUILTY, "No I'm fine thanks.", END_DIALOGUE) + ) + + 10 -> npc(FacialExpression.HALF_GUILTY, + "This is the fight caves, TzHaar-Xil made it for practice,", + "but many JalYt come here to fight too.", + "Just enter the cave and make sure you're prepared." + ).also { stage++ } + + 11 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "Are there any rules?", 12), + Topic(FacialExpression.HALF_GUILTY, "Ok thanks.", END_DIALOGUE) + ) + + 12 -> npcl(FacialExpression.HALF_GUILTY, "Rules? Survival is the only rule in there.").also { stage++ } + 13 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "Do I win anything?", 14), + Topic(FacialExpression.HALF_GUILTY, "Sounds good.", END_DIALOGUE) + ) + + 14 -> npc(FacialExpression.HALF_GUILTY, + "You ask a lot of questions.", + "Might give you TokKul if you last long enough." + ).also { stage++ } + 15 -> playerl(FacialExpression.HALF_GUILTY, "...").also { stage ++ } + 16 -> npcl(FacialExpression.HALF_GUILTY, "Before you ask, TokKul is like your Coins.").also { stage++ } + 17 -> npc(FacialExpression.HALF_GUILTY, + "Gold is like you JalYt, soft and easily broken, we use", + "hard rock forged in fire like TzHaar!" + ).also{ stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?").also { stage++ } + 21 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?", 22), + Topic(FacialExpression.HALF_GUILTY, "I guess so...", END_DIALOGUE), + Topic(FacialExpression.HALF_GUILTY, "No I'm not!", END_DIALOGUE) + ) + + 22 -> npcl(FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?").also { stage++ } + 23 -> playerl(FacialExpression.HALF_GUILTY, "Well yes I suppose I am...").also { stage = END_DIALOGUE } + + 30 -> player(FacialExpression.HALF_GUILTY, + "The challenge is too long.", + "I want to challenge Jad directly." + ).also { stage++ } + 31 -> npc(FacialExpression.DISGUSTED_HEAD_SHAKE, + "I thought you strong and tough", + "but you want skip endurance training?" + ).also { stage++ } + 32 -> npcl(FacialExpression.NEUTRAL, "Maybe you not JalYt-Ket afterall.").also { stage++ } + 33 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "I don't have time for it, man.", 35), + Topic("No, I'm JalYt-Ket!", 34, skipPlayer = true) + ) + + 34 -> player(FacialExpression.HALF_GUILTY, + "No, I'm JalYt-Ket! I swear!", + "I'll do the training properly." + ).also { stage = END_DIALOGUE } + + 35 -> npc(FacialExpression.DISGUSTED_HEAD_SHAKE, + "JalYt, you know you not get reward", + "if you not do training properly, ok?" + ).also { stage++ } + 36 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "That's okay, I don't need a reward.", 37), + Topic(FacialExpression.HALF_GUILTY, "Oh, nevermind then.", END_DIALOGUE) + ) + + 37 -> playerl(FacialExpression.NEUTRAL, "I just wanna fight the big guy.").also { stage++ } + 38 -> npc(FacialExpression.NEUTRAL, + "Okay JalYt.", + "TzTok-Jad not show up for just anyone." + ).also { stage++ } + 39 -> npc(FacialExpression.NEUTRAL, + "You give 8000 TokKul, TzTok-Jad know you serious.", + "You get it back if you victorious." + ).also { stage++ } + 40 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "That's fair, here's 8000 TokKul.", 41), + Topic(FacialExpression.HALF_GUILTY, "I don't have that much on me, but I'll go get it.", END_DIALOGUE), + Topic("TzTok-Jad must be old and tired to not just accept my challenge.", 42, skipPlayer = true) + ) + + 41 -> if (removeItem(player, Item(Items.TOKKUL_6529, 8000))) { + npc(FacialExpression.NEUTRAL, + "Okay JalYt. Enter cave when you are prepared.", + "You find TzTok-Jad waiting for JalYt challenger." + ) + .also { setAttribute(player, "fc_practice_jad", true) } + .also { stage = END_DIALOGUE } + } else npc(FacialExpression.NEUTRAL, + "JalYt, you not have the TokKul.", + "You come back when you are serious." + ).also { stage = END_DIALOGUE } + + 42 -> player(FacialExpression.HALF_GUILTY, + "TzTok-Jad must be old and tired", + "to not just accept my challenge." + ).also { stage++ } + 43 -> npc(FacialExpression.ANGRY, + "JalYt-Mor, you the old and tired one.", + "You the one not want to do proper training." + ).also { stage = END_DIALOGUE } + + 50 -> npc(FacialExpression.NEUTRAL, + "TzTok-Jad is waiting for you.", + "Do not make TzTok-Jad wait long." + ).also { stage = END_DIALOGUE } + + 100 -> sendDialogueOptions(player, "Sell your fire cape?", "Yes, sell it for 8,000 TokKul.", "No, keep it.").also { stage++ } + 101 -> when (buttonId) { + 1 -> npcl(FacialExpression.OLD_NORMAL, "Hand your cape here, young JalYte.").also { stage++ } + 2 -> end() + } + 102 -> end().also { if (removeItem(player, Items.FIRE_CAPE_6570)) addItem(player, Items.TOKKUL_6529, 8000) } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return TzHaarMejJal(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TZHAAR_MEJ_JAL_2617) + } +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzRekJadNPC.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzRekJadNPC.java deleted file mode 100644 index 2c5993906..000000000 --- a/Server/src/main/content/region/karamja/tzhaar/handlers/TzRekJadNPC.java +++ /dev/null @@ -1,263 +0,0 @@ -package content.region.karamja.tzhaar.handlers; - -import core.cache.def.impl.NPCDefinition; -import core.game.dialogue.DialogueInterpreter; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.repository.Repository; -import core.plugin.Plugin; -import core.plugin.ClassScanner; -import core.plugin.Initializable; -import core.tools.RandomFunction; - -/** - * Handles everything in regards to jad pet. - * @author Empathy - * - */ -@Initializable -public class TzRekJadNPC extends OptionHandler { - - /** - * The tzhaar mej id. - */ - private static final int TZHAAR_MEJ_ID = 2617; - - /** - * The firecape item. - */ - private static final Item FIRECAPE = new Item(6570); - - /** - * The tokkul item. - */ - private static final Item TOKKUL = new Item(6529); - - /** - * The jad item. - */ - private static final Item JAD_PET = new Item(14828); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - NPCDefinition.forId(TZHAAR_MEJ_ID).getHandlers().put("option:exchange fire cape", this); - ClassScanner.definePlugins(new TzhaarMejJalDialogue(), new TzRekJadDialogue()); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - switch (option) { - case "exchange fire cape": - player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey(player.getInventory().containsItem(FIRECAPE) ? "firecape-exchange" : "tzhaar-mej"), node.asNpc()); - break; - } - return true; - } - - /** - * Handles the TzhaarMejJal Dialogue to gamble for jad pet. - * @author Empathy - * - */ - public final class TzhaarMejJalDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code TzhaarMejJalDialogue} {@code Object}. - */ - public TzhaarMejJalDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code TzhaarMejJalDialogue} {@code Object}. - * - * @param player the player. - */ - public TzhaarMejJalDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new TzhaarMejJalDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have a fire cape here."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Sell your fire cape?", "Yes, sell it for 8,000 TokKul.", "No, keep it.", "Bargain for TzRek-Jad."); - stage = 1; - break; - case 1: - switch(buttonId) { - case 1: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, player.getInventory().containsItems(FIRECAPE) ? "Hand your cape here, young JalYte." : "You not have firecape, JalYt."); - stage = 10; - break; - case 2: - end(); - break; - case 3: - interpreter.sendOptions("Sacrifice your firecape?", "Yes, I know I won't get my cape back.", "No, I like my cape!"); - stage = 20; - break; - } - break; - case 10: - if (player.getInventory().containsItem(FIRECAPE)) { - if (player.getInventory().remove(FIRECAPE)) { - TOKKUL.setAmount(8000); - player.getInventory().add(TOKKUL); - TOKKUL.setAmount(1); - } - } - end(); - break; - case 20: - switch (buttonId) { - case 1: - if (player.hasItem(JAD_PET)) { - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Best you train one TzRek-Jad only."); - stage = 21; - break; - } - if (player.getFamiliarManager().hasFamiliar()) { - if (player.getFamiliarManager().getFamiliar().getId() == 8650) { - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Best you train one TzRek-Jad only."); - stage = 21; - break; - } - } - if (player.getInventory().remove(FIRECAPE)) { - int r = RandomFunction.getRandom(200); - if (r == 1) { - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You lucky. Better train him good else TzTok-Jad find", "you, JalYt."); - if (!player.getFamiliarManager().hasFamiliar()) { - player.getFamiliarManager().summon(JAD_PET, true); - player.sendNotificationMessage("You have a funny feeling like you're being followed."); - } else if (player.getInventory().freeSlots() > 0) { - player.getInventory().add(JAD_PET); - player.sendNotificationMessage("You feel something weird sneaking into your backpack."); - } - Repository.sendNews(player.getUsername() + " now commands a miniature TzTok-Jad!"); - } else { - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You not lucky. Maybe next time, JalYt."); - } - } - stage = 21; - break; - case 2: - end(); - break; - } - break; - case 21: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { DialogueInterpreter.getDialogueKey("firecape-exchange") }; - } - } - - /** - * Handles the TzRekJad dialogue. - * @author Empathy - * - */ - public final class TzRekJadDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code TzRekJadDialogue} {@code Object}. - */ - public TzRekJadDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code TzRekJadDialogue} {@code Object}. - * - * @param player the player. - */ - public TzRekJadDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new TzRekJadDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - int i = RandomFunction.getRandom(1); - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, i == 1 ? "Do you miss your people?" : "Are you hungry?"); - stage = (i == 1 ? 0 : 5); - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Mej-TzTok-Jad Kot-Kl!"); - stage = 1; - break; - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No.. I don't think so."); - stage = 2; - break; - case 2: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Jal-Zek Kl?"); - stage = 3; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, no, I wouldn't hurt you."); - stage = 4; - break; - case 4: - end(); - break; - case 5: - interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Kl-Kra!"); - stage = 6; - break; - case 6: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ooookay..."); - stage = 4; - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 8650 }; - } - } - -} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarCityPlugin.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarCityPlugin.java deleted file mode 100644 index b4b23b029..000000000 --- a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarCityPlugin.java +++ /dev/null @@ -1,198 +0,0 @@ -package content.region.karamja.tzhaar.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.activity.ActivityManager; -import core.game.dialogue.DialoguePlugin; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.scenery.Scenery; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used for tzhaar city. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class TzhaarCityPlugin extends OptionHandler { - - /** - * Represents the locations to use. - */ - private static final Location[] LOCATIONS = new Location[] { Location.create(2480, 5175, 0), Location.create(2866, 9571, 0) }; - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(31284).getHandlers().put("option:enter", this);// karamja - // cave. - SceneryDefinition.forId(9359).getHandlers().put("option:enter", this);// tzhaar - // exit - SceneryDefinition.forId(9356).getHandlers().put("option:enter", this); - SceneryDefinition.forId(9369).getHandlers().put("option:pass", this); - new TzhaarDialogue().init(); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - int id = ((Scenery) node).getId(); - switch (option) { - case "enter": - switch (id) { - case 31284: - player.getProperties().setTeleportLocation(LOCATIONS[0]); - break; - case 9359: - player.getProperties().setTeleportLocation(LOCATIONS[1]); - break; - case 9356: - if (player.getFamiliarManager().hasFamiliar()) { - player.getPacketDispatch().sendMessage("You can't enter this with a follower."); - break; - } - ActivityManager.start(player, "fight caves", false); - break; - } - break; - case "pass": - switch (id) { - case 9369: - ActivityManager.start(player, "fight pits", false); - break; - } - break; - } - return true; - } - - /** - * Represents the dialogue plugin used for the tzhaar npcs. - * @author 'Vexia - * @version 1.0 - */ - public static final class TzhaarDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code TzhaarDialogue} {@code Object}. - */ - public TzhaarDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code TzhaarDialogue} {@code Object}. - * @param player the player. - */ - public TzhaarDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new TzhaarDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - npc("Can I help you JalYt-Ket-" + player.getUsername() + "?"); - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - options("What do you have to trade?", "What did you call me?", "No I'm fine thanks."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - end(); - npc.openShop(player); - break; - case 2: - player("What did you call me?"); - stage = 20; - break; - case 3: - player("No I'm fine thanks."); - stage = 30; - break; - } - break; - case 10: - break; - case 20: - npc("Are you not JalYt-Ket?"); - stage = 21; - break; - case 21: - options("What's a 'JalYt-Ket'?", "I guess so...", "No I'm not!"); - stage = 22; - break; - case 22: - switch (buttonId) { - case 1: - player("What's a 'JalYt-Ket'?"); - stage = 100; - break; - case 2: - player("I guess so..."); - stage = 120; - break; - case 3: - player("No I'm not!"); - stage = 130; - break; - } - break; - case 100: - npc("That what you are... you tough and strong no?"); - stage = 101; - break; - case 101: - player("Well yes I suppose I am..."); - stage = 102; - break; - case 102: - npc("Then you JalYt-Ket!"); - stage = 103; - break; - case 103: - end(); - break; - case 120: - npc("Well then, no problems."); - stage = 121; - break; - case 121: - end(); - break; - case 130: - end(); - break; - case 23: - end(); - break; - case 30: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2620, 2622, 2623 }; - } - - } -} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java index e1baca76a..5a4cdfd11 100644 --- a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java @@ -1,6 +1,5 @@ package content.region.karamja.tzhaar.handlers; -import content.global.skill.slayer.SlayerManager; import core.game.event.NPCKillEvent; import core.game.activity.ActivityPlugin; import content.data.BossKillCounter; @@ -10,8 +9,6 @@ import core.game.node.entity.Entity; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.entity.skill.Skills; -import content.global.skill.slayer.Tasks; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.game.node.scenery.Scenery; @@ -23,6 +20,7 @@ import core.plugin.Initializable; import core.tools.RandomFunction; import core.game.world.GameWorld; import core.game.world.repository.Repository; +import org.rs09.consts.NPCs; import java.util.ArrayList; import java.util.List; @@ -62,7 +60,7 @@ public final class TzhaarFightCavesPlugin extends ActivityPlugin { * @param player The player. */ public TzhaarFightCavesPlugin(Player player) { - super("fight caves", true, true, true, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS); + super("fight caves", true, true, true, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FOLLOWERS); super.player = player; } @@ -147,11 +145,6 @@ public final class TzhaarFightCavesPlugin extends ActivityPlugin { public void leave(Player player, int wave) { activeNPCs.clear(); player.getProperties().setTeleportLocation(getSpawnLocation()); - player.getSkills().restore(); - player.timers.removeTimer("poison"); - player.timers.removeTimer("disease"); - player.timers.removeTimer("teleblock"); - player.getSettings().updateRunEnergy(-100); boolean practice = player.getAttribute("fc_practice_jad", false); if (wave == 63) { if (!practice) { @@ -167,12 +160,7 @@ public final class TzhaarFightCavesPlugin extends ActivityPlugin { } player.getPacketDispatch().sendMessage("You were victorious!"); if (!practice) { - BossKillCounter.addtoKillcount(player, 2745); - if (SlayerManager.getInstance(player).getTask() == Tasks.JAD) { - player.getSkills().addExperience(Skills.SLAYER, 25000); - SlayerManager.getInstance(player).clear(); - player.sendMessage("You receive 25,000 slayer experience for defeating TzTok-Jad."); - } + BossKillCounter.addToBossKillCount(player, NPCs.TZTOK_JAD_2745); player.getDialogueInterpreter().sendDialogues(2617, null, "You even defeated TzTok-Jad, I am most impressed!", "Please accept this gift as a reward."); Repository.sendNews(player.getUsername() + " has been victorious in defeating TzTok-Jad for a firecape!"); } else { diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarListeners.kt b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarListeners.kt new file mode 100644 index 000000000..f785ecd0b --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarListeners.kt @@ -0,0 +1,36 @@ +package content.region.karamja.tzhaar.handlers + +import core.api.sendNPCDialogueLines +import core.api.teleport +import core.game.activity.ActivityManager +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class TzhaarListeners : InteractionListener { + override fun defineListeners() { + on(intArrayOf(31284, 9359, 9356), IntType.SCENERY, "enter") { player, node -> + when (node.id) { + 31284 -> teleport(player, Location.create(2480, 5175, 0)) + 9359 -> teleport(player, Location.create(2866, 9571, 0)) + 9356 -> { + if (player.familiarManager.hasFamiliar()) { + sendNPCDialogueLines(player, NPCs.TZHAAR_MEJ_JAL_2617, FacialExpression.ANGRY, false, "No Kimit-Zil in the cave! This is a fight for YOU,", "not your friends!") + } else ActivityManager.start(player, "fight caves", false) + } + } + return@on true + } + + on(9369, IntType.SCENERY, "pass") { player, _ -> + ActivityManager.start(player, "fight pits", false) + return@on true + } + + on(31292, IntType.SCENERY, "go-through") { _, _ -> + return@on false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/marim/SolihibDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/SolihibDialogue.kt new file mode 100644 index 000000000..381e3e856 --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/SolihibDialogue.kt @@ -0,0 +1,42 @@ +package content.region.misc.apeatoll.dialogue.marim + +import content.data.Quests +import core.api.hasRequirement +import core.api.openNpcShop +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs + +class SolihibDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.SOLIHIB_1433, IntType.NPC, "talk-to") { player, node -> + if (!hasRequirement(player, Quests.MONKEY_MADNESS)) return@on true + DialogueLabeller.open(player, SolihibDialogueLabellerFile(), node as NPC) + return@on true + } + on(NPCs.SOLIHIB_1433, IntType.NPC, "trade") { player, _ -> + if (!hasRequirement(player, Quests.MONKEY_MADNESS)) return@on true + openNpcShop(player, NPCs.SOLIHIB_1433) + return@on true + } + } + + class SolihibDialogueLabellerFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.SOLIHIB_1433) + + npc(ChatAnim.FRIENDLY, "Would you like to buy or sell some food?") + options( + DialogueOption("trade", "Yes, please."), + DialogueOption("nowhere", "No, thanks.") + ) + label("trade") + exec { player, _ -> openNpcShop(player, NPCs.SOLIHIB_1433) } + goto("nowhere") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java b/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java index beaaccd03..15e7f8803 100644 --- a/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java +++ b/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java @@ -8,6 +8,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the dialogue plugin used for a cave monk. @@ -52,7 +53,7 @@ public final class CaveMonk extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Lost City"); + quest = player.getQuestRepository().getQuest(Quests.LOST_CITY); switch (quest.getStage(player)) { case 0: case 10: diff --git a/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt b/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt index c650a958d..4f177c848 100644 --- a/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt +++ b/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt @@ -1,59 +1,63 @@ package content.region.misc.entrana.dialogue -import core.api.addItemOrDrop +import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs -/** - * @author qmqz - */ - @Initializable class HighPriestEntranaDialogue(player: Player? = null) : DialoguePlugin(player){ - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - - if (!player.questRepository.isComplete("Heroes' Quest")) { - npc(FacialExpression.FRIENDLY, "Many greetings. Welcome to our fair island.").also { stage = 10 } - } else { - options("Have you seen a pair of ice gloves?", "Ask about Entrana").also { stage = 5 } - } - - - return true - } - override fun handle(interfaceId: Int, buttonId: Int): Boolean { when(stage){ - 1 -> npcl(FacialExpression.FRIENDLY, "and devoted the island to those who wish peace for the world.").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "The inhabitants of this island are mostly monks who spend their time meditating on Saradomin's ways.").also { stage++ } - 3 -> npcl(FacialExpression.FRIENDLY, "Of course, there are now more pilgrims to this holy site, since Saradomin defeated Zamorak in the battle of Lumbridge. It is good that so many see Saradomin's true glory!").also { stage = 99 } - - 5 -> when (buttonId) { - 1 -> npcl(FacialExpression.FRIENDLY, "By which you mean the pair of mythical gloves you stole from the cold dead body of the Queen of the Ice?").also { stage = 20 } - 2 -> npcl(FacialExpression.FRIENDLY,"You are standing on the holy island of Entrana. It was here that Saradomin first stepped upon Gielinor. In homage to Saradomin's first arrival, we have built a great church,").also { stage = 1 } + // Ice gloves were NOT reclaimable till 2017. + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Many greetings. Welcome to our fair island.").also { + if (inInventory(player, Items.SILVER_POT_4658) || + inInventory(player, Items.SILVER_POT_4660) || + inInventory(player, Items.SILVER_POT_4662) || + inInventory(player, Items.SILVER_POT_4664) || + inInventory(player, Items.SILVER_POT_4666)) { + stage = 6 + } else { + stage = 1 + } } + 1 -> npcl(FacialExpression.FRIENDLY, "You are standing on the holy island of Entrana. It was here that Saradomin first stepped upon Gielinor.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "In homage to Saradomin's first arrival, we have built a great church, and devoted the island to those who wish peace for the world.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "The inhabitants of this island are mostly monks who spend their time meditating on Saradomin's ways.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "Of course, there are now more pilgrims to this holy site, since Saradomin defeated Zamorak in the battle of Lumbridge.").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "It is good that so many see Saradomin's true glory!").also { stage = END_DIALOGUE } - 10 -> npc(FacialExpression.FRIENDLY, "Enjoy our stay here. May it be spiritually uplifting!").also { stage = 99 } - - 20 -> player(FacialExpression.SUSPICIOUS, "Er...").also { stage++ } - 21 -> npcl(FacialExpression.ANNOYED, "The gloves that you acquired to aid you in plucking the Entranan firebird? Another victim of your murderous nature, I should add.").also { stage++ } - 22 -> npcl(FacialExpression.ANNOYED, "The ice gloves that, from context, I would assume you have lost, if not carelessly discarded?").also { stage++ } - - 23 -> player(FacialExpression.FRIENDLY, "Those ice gloves, yes.").also { stage++ } - 24 -> sendDialogue("The high priest of Entrana shivers as he hands you your lost ice gloves.").also { - addItemOrDrop(player, Items.ICE_GLOVES_1580, 1) - stage++ + 6 -> playerl(FacialExpression.FRIENDLY, "Hi, I was wondering, can you quickly bless this for me?").also { stage++ } + 7 -> npc(FacialExpression.FRIENDLY, "A somewhat strange request, but I see no harm in it.", "There you go.", "May Saradomin walk with you.").also { + if (inInventory(player, Items.SILVER_POT_4658)) { + if (removeItem(player, Items.SILVER_POT_4658)) { + addItemOrDrop(player, Items.BLESSED_POT_4659) + } + } else if (inInventory(player, Items.SILVER_POT_4660)) { + if (removeItem(player, Items.SILVER_POT_4660)) { + addItemOrDrop(player, Items.BLESSED_POT_4661) + } + } else if (inInventory(player, Items.SILVER_POT_4662)) { + if (removeItem(player, Items.SILVER_POT_4662)) { + addItemOrDrop(player, Items.BLESSED_POT_4663) + } + } else if (inInventory(player, Items.SILVER_POT_4664)) { + if (removeItem(player, Items.SILVER_POT_4664)) { + addItemOrDrop(player, Items.BLESSED_POT_4665) + } + } else if (inInventory(player, Items.SILVER_POT_4666)) { + if (removeItem(player, Items.SILVER_POT_4666)) { + addItemOrDrop(player, Items.BLESSED_POT_4667) + } + } + stage = END_DIALOGUE } - 25 -> npcl(FacialExpression.ANNOYED, "One of my monks found these gloves. If only to spare this world from further carnage, I return them to you.").also { stage = 99 } - - 99 -> end() } return true } @@ -65,4 +69,4 @@ class HighPriestEntranaDialogue(player: Player? = null) : DialoguePlugin(player) override fun getIds(): IntArray { return intArrayOf(NPCs.HIGH_PRIEST_216) } -} +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/entrana/handlers/EntranaListeners.kt b/Server/src/main/content/region/misc/entrana/handlers/EntranaListeners.kt new file mode 100644 index 000000000..105321131 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/handlers/EntranaListeners.kt @@ -0,0 +1,56 @@ +package content.region.misc.entrana.handlers + +import content.global.travel.ship.Ships +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Listeners for the Entrana monks' fast-travel option + * @author Player Name + */ + +fun sail(player: Player?, ship: Ships) { + ship.sail(player) + playJingle(player!!, 172) +} + +class EntranaListeners : InteractionListener { + override fun defineListeners() { + for (npc in arrayOf(NPCs.MONK_OF_ENTRANA_2730, NPCs.MONK_OF_ENTRANA_658, NPCs.MONK_OF_ENTRANA_2731)) { + on(npc, IntType.NPC, "take-boat") { player, _ -> + sail(player, Ships.ENTRANA_TO_PORT_SARIM) + return@on true + } + } + + for (npc in arrayOf(NPCs.MONK_OF_ENTRANA_2728, NPCs.MONK_OF_ENTRANA_657, NPCs.MONK_OF_ENTRANA_2729)) { + on(npc, IntType.NPC, "take-boat") { player, _ -> + if (!ItemDefinition.canEnterEntrana(player)) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + this.npc = NPC(npc) + when (stage) { + 0 -> npc("NO WEAPONS OR ARMOUR are permitted on holy", "Entrana AT ALL. We will not allow you to travel there", "in breach of mighty Saradomin's edict.").also { stage++ } + 1 -> npc("Do not try to deceive us again. Come back when you", "have laid down your Zamorakian instruments of death.").also { stage = END_DIALOGUE } + } + } + }) + return@on true + } + sail(player, Ships.PORT_SARIM_TO_ENTRANA) + if (!player.achievementDiaryManager.getDiary(DiaryType.FALADOR).isComplete(0, 14)) { + player.achievementDiaryManager.getDiary(DiaryType.FALADOR).updateTask(player, 0, 14, true) + } + return@on true + } + } + } +} diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt index 974f22438..97d0d8dbb 100644 --- a/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt @@ -1,51 +1,110 @@ package content.region.misc.keldagrim.dialogue -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.dialogue.Topic -import core.game.node.entity.player.Player +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.item.Item import core.plugin.Initializable -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE +import org.rs09.consts.Items import org.rs09.consts.NPCs + @Initializable -class BlandebirDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(stage){ - START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello, I wonder if you could help me on this whole brewing thing...").also { stage++ } - 1 -> npcl(FacialExpression.OLD_DEFAULT, "I might be able to - what do you need to know?").also { stage++ } - 2 -> showTopics( - Topic(FacialExpression.FRIENDLY, "How do I brew ales?", 3), - Topic(FacialExpression.FRIENDLY, "How do I brew cider?", 6), - Topic(FacialExpression.FRIENDLY, "What do I do once my ale has matured?", 8), - Topic(FacialExpression.FRIENDLY, "Do you have any spare ale yeast?", 9), - Topic(FacialExpression.FRIENDLY, "That's all I need to know, thanks.", END_DIALOGUE), +class BlandebirDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.BLANDEBIR_2321, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, BlandebirDialogueFile(), node as NPC) + return@on true + } + } +} + + +class BlandebirDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.BLANDEBIR_2321) + + player(ChatAnim.FRIENDLY, "Hello, I wonder if you could help me on this whole brewing thing...") + npc(ChatAnim.OLD_DEFAULT, "I might be able to - what do you need to know?") + goto("main_menu") + + label("main_menu") { + options( + DialogueOption("how_brew_ales", "How do I brew ales?", expression = ChatAnim.HALF_ASKING, spokenText = "How do I brew ales?"), + DialogueOption("how_brew_cider", "How do I brew cider?", expression = ChatAnim.HALF_ASKING, spokenText = "How do I brew cider?"), + DialogueOption("what_when_matured", "What do I do once my ale has matured?", expression = ChatAnim.HALF_ASKING, spokenText = "What do I do once my ale has matured?"), + DialogueOption("buy_yeast", "Do you have any spare ale yeast?", expression = ChatAnim.HALF_ASKING, spokenText = "Do you have any spare ale yeast?"), + DialogueOption("end", "That's all I need to know, thanks.") ) - 3 -> npcl(FacialExpression.OLD_DEFAULT, "Well first off you need to fill the vat with water - two bucketfuls should do the trick. Then you'll need to put in two handfuls of barley malt - that's roasted barley by the way.").also { stage++ } - 4 -> npcl(FacialExpression.OLD_DEFAULT, "After that you'll be putting your main ingredient in - this will decide which ale it is you're brewing. There should be some good guides around with recipes in.").also { stage++ } - 5 -> npcl(FacialExpression.OLD_DEFAULT, "Lastly you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.").also { - stage = 2 - } - 6 -> npcl(FacialExpression.OLD_DEFAULT, "First you'll need some apples. You'll need to crush them using this cider-press - four apples should make a full bucket of apple-mush. Take four buckets of mush and fill up the vat.").also { stage++ } - 7 -> npcl(FacialExpression.OLD_DEFAULT, "After that you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.").also { - stage = 2 - } - 8 -> npcl(FacialExpression.OLD_DEFAULT, "Well, once you've got a full vat of the good stuff, just turn the valve and your barrel will fill up with eight pints of whatever your chosen tipple is. Mind it's an empty barrel, though.").also { - stage = 2 - } - 9 -> npcl(FacialExpression.OLD_DEFAULT, "Well, as a matter of fact I do, although I wouldn't describe it as spare. This ale yeast I've got is the best money can buy, but if you've got a pot I'll fill it for you for 25GP - very cheap as it happens.").also { - stage = 2 + } + + label("how_brew_ales") { + npc(ChatAnim.OLD_DEFAULT, "Well first off you need to fill the vat with water - two bucketfuls should do the trick. Then you'll need to put in two handfuls of barley malt - that's roasted barley by the way.") + npc(ChatAnim.OLD_DEFAULT, "After that you'll be putting your main ingredient in - this will decide which ale it is you're brewing. There should be some good guides around with recipes in.") + npc(ChatAnim.OLD_DEFAULT, "Lastly you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.") + goto("main_menu") + } + + label("how_brew_cider") { + npc(ChatAnim.OLD_DEFAULT, "First you'll need some apples. You'll need to crush them using this cider-press - four apples should make a full bucket of apple-mush. Take four buckets of mush and fill up the vat.") + npc(ChatAnim.OLD_DEFAULT, "After that you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.") + goto("main_menu") + } + + label("what_when_matured") { + npc(ChatAnim.OLD_DEFAULT, "Well, once you've got a full vat of the good stuff, just turn the valve and your barrel will fill up with eight pints of whatever your chosen tipple is. Mind it's an empty barrel, though.") + goto("main_menu") + } + + label("buy_yeast") { + npc(ChatAnim.OLD_DEFAULT, "Well, as a matter of fact I do, although I wouldn't describe it as spare. This ale yeast I've got is the best money can buy, but if you've got a pot I'll fill it for you for 25GP - very cheap as it happens.") + options( + DialogueOption("confirm_buy", "That's a good deal - please fill my pot with ale yeast for 25GP."), + DialogueOption("end", "No, that's too much I'm afraid.") + ) + } + + label("confirm_buy") { + exec { player, npc -> + if (!inInventory(player, Items.EMPTY_POT_1931, 1)) { + loadLabel(player, "no_pot") + } else if (!inInventory(player, Items.COINS_995, 25)) { + loadLabel(player, "no_coins") + } else { + loadLabel(player, "process_purchase") + } } } - return true - } - override fun newInstance(player: Player?): DialoguePlugin { - return BlandebirDialogue(player) - } + label("no_pot") { + npc(ChatAnim.OLD_DEFAULT, "I'm afraid you'll need a pot for me to put the yeast in.") + goto("end") + } - override fun getIds(): IntArray { - return intArrayOf(NPCs.BLANDEBIR_2321) + label("no_coins") { + line("You can not afford that.") + goto("end") + } + + label("process_purchase") { + exec { player, npc -> + val emptyPots = amountInInventory(player, Items.EMPTY_POT_1931) + val coins = amountInInventory(player, Items.COINS_995) + val canAfford = coins / 25 + val quantity = minOf(emptyPots, canAfford) + + if (removeItem(player, Item(Items.EMPTY_POT_1931, quantity)) && removeItem(player, Item(Items.COINS_995, quantity * 25))) { + addItem(player, Items.ALE_YEAST_5767, quantity) + } + } + goto("main_menu") + } + + label("end") { + } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt index d534f02fb..9cd9bdca0 100644 --- a/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt @@ -1,5 +1,6 @@ package content.region.misc.keldagrim.dialogue +import content.data.Quests import core.api.addItemOrDrop import core.api.inInventory import core.api.isQuestComplete @@ -41,7 +42,7 @@ class KjutDialogue(player: Player? = null) : DialoguePlugin(player) { stage = END_DIALOGUE } 6 -> { - if (isQuestComplete(player, "Forgettable Tale of a Drunken Dwarf")) { + if (isQuestComplete(player, Quests.FORGETTABLE_TALE)) { npcl(FacialExpression.OLD_DEFAULT, "I thought you would know plenty!").also { stage = 14 } } else { npcl(FacialExpression.OLD_DEFAULT, "Just go out in the streets, they can't be hard to find!").also { stage = 7 } diff --git a/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt index 06dcb2ac5..20d4d5771 100644 --- a/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt +++ b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt @@ -9,18 +9,19 @@ import core.game.world.map.Location import org.rs09.consts.Components import core.game.world.GameWorld import core.api.* +import content.data.Quests object KeldagrimCartMethods { @JvmStatic fun goToKeldagrim(player: Player){ - if (!hasRequirement(player, "The Giant Dwarf")) + if (!hasRequirement(player, Quests.THE_GIANT_DWARF)) return GameWorld.Pulser.submit(TravelToKeldagrimPulse(player)) } @JvmStatic fun leaveKeldagrimTo(player: Player, dest: Location){ - if (!hasRequirement(player, "The Giant Dwarf")) + if (!hasRequirement(player, Quests.THE_GIANT_DWARF)) return GameWorld.Pulser.submit(TravelFromKeldagrimPulse(player,dest)) } @@ -68,7 +69,7 @@ class TravelFromKeldagrimPulse(val player: Player, val dest: Location): Pulse(){ class TravelToKeldagrimPulse(val player: Player) : Pulse(){ var counter = 0 - var cartNPC = NPC(1546) + var cartNPC = NPC(1544) override fun pulse(): Boolean { when(counter++){ 0 -> player.lock().also { player.interfaceManager.open(Component(115)) } diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt index 9f2a60285..e2ece679c 100644 --- a/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt @@ -7,6 +7,7 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs +import content.data.Quests /** * @author qmqz @@ -17,7 +18,7 @@ class FishmongerMiscDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Throne of Miscellania")) { + if (!isQuestComplete(player, Quests.THRONE_OF_MISCELLANIA)) { npcl(FacialExpression.FRIENDLY,"Greetings, Sir. Get your fresh fish here! I've heard that the Etceterian fish is stored in a cow shed.").also { stage = 0 } } else { npcl(FacialExpression.FRIENDLY,"Greetings, Your Highness. Have some fresh fish! I've heard that the Etceterian fish is stored in a cow shed.").also { stage = 0 } diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt index c46e2f42e..6320d5ad1 100644 --- a/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt @@ -22,7 +22,7 @@ class FlowerGirlDialogue(player: Player? = null) : DialoguePlugin(player){ //issues getting throne of miscellania status /* - when (player.questRepository.getQuest("Throne of Miscellania").isCompleted(player)) { + when (player.questRepository.getQuest(Quests.THRONE_OF_MISCELLANIA).isCompleted(player)) { true -> npc(FacialExpression.HAPPY, "Good day, Your Royal Highness.").also { stage = 1 } false -> npc(FacialExpression.NEUTRAL, "Hello.").also { stage = 1 } } @@ -39,7 +39,7 @@ class FlowerGirlDialogue(player: Player? = null) : DialoguePlugin(player){ 2 -> { /* - when (player.questRepository.getQuest("Throne of Miscellania").isCompleted(player)) { + when (player.questRepository.getQuest(Quests.THRONE_OF_MISCELLANIA).isCompleted(player)) { true -> npc(FacialExpression.HAPPY, "I'm selling flowers, 15gp for three. Would you like some, Your Highness?").also { stage++ } false -> npc(FacialExpression.NEUTRAL, "I'm selling flowers, 15gp for three. Would you like some?").also { stage++ } } diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/BankerTutorDialogue.java b/Server/src/main/content/region/misc/tutisland/dialogue/BankerTutorDialogue.java deleted file mode 100644 index c6a121500..000000000 --- a/Server/src/main/content/region/misc/tutisland/dialogue/BankerTutorDialogue.java +++ /dev/null @@ -1,155 +0,0 @@ -package content.region.misc.tutisland.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the banker tutor dialogue. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class BankerTutorDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code BankerTutorDialogue} {@code Object}. - * @param player the player. - */ - public BankerTutorDialogue(final Player player) { - super(player); - } - - /** - * Constructs a new {@code BankerTutorDialogue} {@code Object}. - */ - public BankerTutorDialogue() { - /** - * empty. - */ - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new BankerTutorDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = args[0] instanceof NPC ? (NPC) args[0] : null; - npc("Good day, would you like to access your bank account?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - options("How do I use the bank?", "I'd like to access my bank account please.", "I'd like to check my PIN settings."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - options("Using the bank itself.", "Using Bank deposit boxes.", "What's this PIN thing that people keep talking about?", "Goodbye."); - stage = 9; - break; - case 2: - end(); - player.getBank().open(); - break; - case 3: - end(); - player.getBankPinManager().openSettings(); - break; - } - break; - case 9: - switch (buttonId) { - case 1: - player("Using the bank itself. I'm not sure how....?"); - stage = 10; - break; - case 2: - player("Using Bank deposit boxes.... what are they?"); - stage = 20; - break; - case 3: - player("What's this PIN thing that people keep talking about?"); - stage = 30; - break; - case 4: - player("Goodbye."); - stage = 99; - break; - } - break; - case 10: - npc("Speak to any banker and ask to see your bank", "account. If you have set a PIN you will be asked for", "it, then all the belongings you have placed in the bank", "will appear in the window. To withdraw one item, left-"); - stage = 11; - break; - case 11: - npc("click on it once."); - stage = 12; - break; - case 12: - npc("To withdraw many, right-click on the item and select", "from the menu. The same for depositing, left-click on", "the item in your inventory to deposit it in the bank.", "Right-click on it to deposit many of the same items."); - stage = 13; - break; - case 13: - npc("To move things around in your bank: firstly select", "Swap or Insert as your default moving mode, you can", "find these buttons on the bank window itself. Then click", "and drag an item to where you want it to appear."); - stage = 14; - break; - case 14: - npc("You may withdraw 'notes' or 'certificates' when the", "items you are trying to withdraw do not stack in your", "inventory. This will only work for items which are", "tradeable."); - stage = 15; - break; - case 15: - npc("For instance, if you wanted to sell 100 logs to another", "player, they would not fit in one inventory and you", "would need to do multiple trades. Instead, click the", "Note button to do withdraw the logs as 'certs' or 'notes',"); - stage = 16; - break; - case 16: - npc("then withdraw the items you need."); - stage = 99; - break; - case 20: - npc("They look like grey pillars, there's one just over there,", "near the desk. Bank deposit boxes save so much time.", "If you're simply wanting to deposit a single item, 'Use'", "it on the deposit box."); - stage = 21; - break; - case 21: - npc("Otherwise, simply click once on the box and it will give", "you a choice of what to deposit in an interface very", "similar to the bank itself. Very quick for when you're", "simply fishing or mining etc."); - stage = 22; - break; - case 22: - end(); - break; - case 30: - npc("The PIN - Personal Identification Number - can be", "set on your bank account to protect the items there in", "case someone finds out your account password. It", "consists of four numbers that you remember and tell"); - stage = 31; - break; - case 31: - npc("no one."); - stage = 32; - break; - case 32: - npc("So if someone did manage to get your password they", "couldn't steal your items if they were in the bank."); - stage = 33; - break; - case 33: - end(); - break; - case 99: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 4907 }; - } - -} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/RatPenDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/RatPenDialogue.kt new file mode 100644 index 000000000..3728d6d9c --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/RatPenDialogue.kt @@ -0,0 +1,15 @@ +package content.region.misc.tutisland.dialogue + +import content.region.misc.tutisland.handlers.sendStageDialog +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller + +/** + * Vannaka's angry dialogue when you try to enter his rat pen before you're supposed to + */ +class RatPenDialogue : DialogueLabeller() { + override fun addConversation() { + npc(ChatAnim.ANGRY, "Oi, get away from there!", "Don't enter my rat pen unless I say so!") + exec { player, _ -> sendStageDialog(player) } + } +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt index 3a16f44c9..f19f67a64 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt @@ -9,10 +9,11 @@ import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import core.game.component.Component.setUnclosable /** * Handles Skippy's skip tutorial dialogue - * @author Ceikry + * @author Ceikry, Player Name */ @Initializable class SkipTutorialDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -21,13 +22,13 @@ class SkipTutorialDialogue(player: Player? = null) : DialoguePlugin(player) { } override fun open(vararg args: Any?): Boolean { - npcl(FacialExpression.FRIENDLY, "Hey, would you like to skip to the end? Choose wisely! This is the only time you get this choice.") + setUnclosable(player, npcl(FacialExpression.FRIENDLY, "Hey, would you like to skip to the end? Choose wisely! This is the only time you get this choice.")) return true } override fun handle(interfaceId: Int, buttonId: Int): Boolean { when(stage){ - 0 -> options("Yes, I'd like to skip the tutorial.", "No thanks.").also { stage++ } + 0 -> options("Yes, I'd like to skip the tutorial.", "No, thanks.").also { stage++ } 1 -> when(buttonId) { 1 -> { diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt index 21c914b98..4e0385178 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt @@ -1,119 +1,108 @@ package content.region.misc.tutisland.dialogue -import core.api.addItem +import core.api.addItemOrDrop import core.api.inInventory import core.api.setAttribute -import core.game.component.Component -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import content.region.misc.tutisland.handlers.sendStageDialog +import core.api.getAttribute +import core.api.inEquipment +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.item.Item -/** - * Handles the survival expert's dialogue - * @author Ceikry - */ -@Initializable -class SurvivalExpertDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun newInstance(player: Player?): DialoguePlugin { - return SurvivalExpertDialogue(player) +class SurvivalExpertDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.SURVIVAL_EXPERT_943, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, SurvivalExpertDialogueFile(), node as NPC) + return@on true + } } +} - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - val tutStage = player?.getAttribute("tutorial:stage", 0) ?: 0 - when(tutStage) - { - 4 -> Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.FRIENDLY, - "Hello there, newcomer. My name is Brynna. My job is", - "to teach you a few survival tips and tricks. First off", - "we're going to start with the most basic survival skill of", - "all: making a fire." - ) - ) +class SurvivalExpertDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.SURVIVAL_EXPERT_943) - 11 -> Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.FRIENDLY, - "Well done! Next we need to get some food in our", - "bellies. We'll need something to cook. There are shrimp", - "in the pond there, so let's catch and cook some." - ) - ) - - 5, 14, 15 -> { - if(!inInventory(player, Items.BRONZE_AXE_1351)) - { - player.dialogueInterpreter.sendItemMessage(Items.BRONZE_AXE_1351, "The Survival Expert gives you a spare bronze axe.") - addItem(player, Items.BRONZE_AXE_1351) + exec { player, _ -> + when (val stage = getAttribute(player, "/save:tutorial:stage", 0)) { + 4 -> loadLabel(player, "hello") + 5, 6, 7, 8, 9, 10, 12, 13, 14 -> { + if (!inInventory(player, Items.BRONZE_AXE_1351) && !inEquipment(player, Items.BRONZE_AXE_1351)) { + loadLabel(player, "spare axe") + } + if (!inInventory(player, Items.TINDERBOX_590)) { + loadLabel(player, "spare tinderbox") + } + if (stage >= 11 && !inInventory(player, Items.SMALL_FISHING_NET_303)) { + loadLabel(player, "spare net") + } + loadLabel(player, "nowhere") } - if(!inInventory(player, Items.TINDERBOX_590)) - { - player.dialogueInterpreter.sendItemMessage(Items.TINDERBOX_590, "The Survival Expert gives you a spare tinderbox.") - addItem(player, Items.TINDERBOX_590) - } - return false + 11 -> loadLabel(player, "fishing") + else -> loadLabel(player, "nowhere") } } - return true - } - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(player?.getAttribute("tutorial:stage", 0)) - { - 4 -> when(stage) - { - 0 -> { - Component.setUnclosable( - player, - interpreter.sendDoubleItemMessage( - Items.TINDERBOX_590, - Items.BRONZE_AXE_1351, - "The Survival Guide gives you a tinderbox and a bronze axe!" - ) - ) - addItem(player, Items.TINDERBOX_590) - addItem(player, Items.BRONZE_AXE_1351) - stage++ - } - 1 -> { - end() - setAttribute(player, "tutorial:stage", 5) - TutorialStage.load(player, 5) - } + label("hello") + npc(ChatAnim.FRIENDLY, "Hello there, newcomer. My name is Brynna. My job is to teach you a few survival tips and tricks. First off we're going to start with the most basic survival skill of all: making a fire.", unclosable = true) + exec { player, _ -> + addItemOrDrop(player, Items.TINDERBOX_590) + addItemOrDrop(player, Items.BRONZE_AXE_1351) + } + item(Item(Items.TINDERBOX_590), Item(Items.BRONZE_AXE_1351), "The Survival Guide gives you a tinderbox and a bronze", "axe!", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 5) + TutorialStage.load(player, 5) + } + goto("nowhere") + + label("fishing") + npc(ChatAnim.FRIENDLY, "Well done! Next we need to get some food in our bellies. We'll need something to cook. There are shrimp in the pond there, so let's catch and cook some.", unclosable = true) + exec { player, _ -> addItemOrDrop(player, Items.SMALL_FISHING_NET_303) } + item(Item(Items.SMALL_FISHING_NET_303), "The Survival Guide gives you a", "net!", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 12) + TutorialStage.load(player, 12) + } + goto("nowhere") + + label("spare axe") + exec { player, _ -> addItemOrDrop(player, Items.BRONZE_AXE_1351) } + item(Item(Items.BRONZE_AXE_1351), "The Survival Guide gives you a spare bronze axe.", unclosable = true) + exec { player, _ -> + if (!inInventory(player, Items.TINDERBOX_590)) { + loadLabel(player, "spare tinderbox") } - - 11 -> when(stage){ - 0 -> { - Component.setUnclosable( - player, - interpreter.sendItemMessage(303, "The Survival Guide gives you a net!") - ) - addItem(player, Items.SMALL_FISHING_NET_303) - stage++ - } - 1 -> { - end() - setAttribute(player, "tutorial:stage", 12) - TutorialStage.load(player, 12) - } + val stage = getAttribute(player, "/save:tutorial:stage", 0) + if (stage >= 11 && !inInventory(player, Items.SMALL_FISHING_NET_303)) { + loadLabel(player, "spare net") } } - return true - } + goto("nowhere") //closes the dialogue, letting the hook reopen the tutorial stage dialog as appropriate - override fun getIds(): IntArray { - return intArrayOf(NPCs.SURVIVAL_EXPERT_943) - } + label("spare tinderbox") + exec { player, _ -> addItemOrDrop(player, Items.TINDERBOX_590) } + item(Item(Items.TINDERBOX_590), "The Survival Guide gives you a spare tinderbox.", unclosable = true) + exec { player, _ -> + val stage = getAttribute(player, "/save:tutorial:stage", 0) + if (stage >= 11 && !inInventory(player, Items.SMALL_FISHING_NET_303)) { + loadLabel(player, "spare net") + } + } + goto("nowhere") -} \ No newline at end of file + label("spare net") + exec { player, _ -> addItemOrDrop(player, Items.SMALL_FISHING_NET_303) } + item(Item(Items.SMALL_FISHING_NET_303), "The Survival Guide gives you a spare net.", unclosable = true) + goto("nowhere") + + label("nowhere") + exec { player, _ -> sendStageDialog(player) } + } +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt index 4e73a799d..1ab335e26 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt @@ -1,95 +1,106 @@ package content.region.misc.tutisland.dialogue -import core.api.* -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import content.region.misc.tutisland.handlers.sendStageDialog +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.item.Item -/** - * Handles the combat instructor's dialogue - * @author Ceikry - */ -@Initializable -class TutorialCombatInstructorDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun newInstance(player: Player?): DialoguePlugin { - return TutorialCombatInstructorDialogue(player) - } - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - - when(getAttribute(player, "tutorial:stage", 0)) - { - 44 -> playerl(FacialExpression.FRIENDLY, "Hi! My name's ${player.username}.") - 47 -> npcl(FacialExpression.FRIENDLY, "Very good, but that little butter knife isn't going to protect you much. Here, take these.") - 53 -> playerl(FacialExpression.FRIENDLY, "I did it! I killed a giant rat!") - 54 -> { - player.dialogueInterpreter.sendDoubleItemMessage(Items.SHORTBOW_841, Items.BRONZE_ARROW_882, "The Combat Guide gives you some bronze arrows and a shortbow!") - if(!inInventory(player, Items.SHORTBOW_841) && !inEquipment(player, Items.SHORTBOW_841)) - addItem(player, Items.SHORTBOW_841) - if(!inInventory(player, Items.BRONZE_ARROW_882) && !inEquipment(player, Items.BRONZE_ARROW_882)) - addItem(player, Items.BRONZE_ARROW_882, 30) - } +class CombatInstructorDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.COMBAT_INSTRUCTOR_944, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, CombatInstructorDialogueFile(), node as NPC) + return@on true } - return true } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(getAttribute(player, "tutorial:stage", 0)) - { - 44 -> when(stage){ - 0 -> npcl(FacialExpression.ANGRY, "Do I look like I care? To me you're just another newcomer who thinks they're ready to fight.").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "I'm Vannaka, the greatest swordsman alive.").also { stage++ } - 2 -> npcl(FacialExpression.FRIENDLY, "Let's get started by teaching you to wield a weapon.").also { stage++ } - 3 -> { - end() - setAttribute(player, "tutorial:stage", 45) - TutorialStage.load(player, 45) - } - } - - 47 -> when(stage){ - 0 -> { - addItemOrDrop(player, Items.BRONZE_SWORD_1277) - addItemOrDrop(player, Items.WOODEN_SHIELD_1171) - sendDoubleItemDialogue(player, Items.BRONZE_SWORD_1277, Items.WOODEN_SHIELD_1171, "The Combat Guide gives you a bronze sword and a wooden shield!") - stage++ - } - 1 -> { - end() - setAttribute(player, "tutorial:stage", 48) - TutorialStage.load(player, 48) - } - } - - 53 -> when(stage){ - 0 -> npcl(FacialExpression.FRIENDLY, "I saw, ${player.username}. You seem better at this than I thought. Now that you have grasped basic swordplay, let's move on.").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "Let's try some ranged attacking, with this you can kill foes from a distance. Also, foes unable to reach you are as good as dead. You'll be able to attack the rats, without entering the pit.").also { stage++ } - 2 -> { - sendDoubleItemDialogue(player, Items.SHORTBOW_841, Items.BRONZE_ARROW_882, "The Combat Guide gives you some bronze arrows and a shortbow!") - if(!inInventory(player, Items.SHORTBOW_841) && !inEquipment(player, Items.SHORTBOW_841)) - addItem(player, Items.SHORTBOW_841) - if(!inInventory(player, Items.BRONZE_ARROW_882) && !inEquipment(player, Items.BRONZE_ARROW_882)) - addItem(player, Items.BRONZE_ARROW_882, 30) - stage++ - } - 3 -> { - end() - setAttribute(player, "tutorial:stage", 54) - TutorialStage.load(player, 54) - } - } - } - return true - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.COMBAT_INSTRUCTOR_944) - } - +} + +class CombatInstructorDialogueFile : DialogueLabeller() { + fun lostWeapon(player: Player, id: Int): Boolean { + return !inInventory(player, id) && !inEquipment(player, id) + } + + override fun addConversation() { + assignToIds(NPCs.COMBAT_INSTRUCTOR_944) + + exec { player, _ -> + when (getAttribute(player, "tutorial:stage", 0)) { + 44 -> loadLabel(player, "hello") + 47 -> loadLabel(player, "butter") + 48, 49, 50, 51, 52 -> loadLabel(player, if (lostWeapon(player, Items.BRONZE_SWORD_1277)) "lost sword" else if (lostWeapon(player, Items.WOODEN_SHIELD_1171)) "lost shield" else "nowhere") + 53 -> loadLabel(player, "killed rat") + 54 -> loadLabel(player, if (lostWeapon(player, Items.SHORTBOW_841)) "lost bow" else if (lostWeapon(player, Items.BRONZE_ARROW_882)) "lost arrows" else "nowhere") + else -> loadLabel(player, "nowhere") + } + } + + label("hello") + player(ChatAnim.FRIENDLY, "Hi! My name's ${player?.username}.", unclosable = true) + npc(ChatAnim.ANGRY, "Do I look like I care? To me you're just another newcomer who thinks they're ready to fight.", unclosable = true) + npc(ChatAnim.FRIENDLY, "I'm Vannaka, the greatest swordsman alive.", unclosable = true) + npc(ChatAnim.FRIENDLY, "Let's get started by teaching you to wield a weapon.", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 45) + TutorialStage.load(player, 45) + } + + label("butter") + npc(ChatAnim.FRIENDLY, "Very good, but that little butter knife isn't going to protect you much. Here, take these.", unclosable = true) + exec { player, _ -> + addItemOrDrop(player, Items.BRONZE_SWORD_1277) + addItemOrDrop(player, Items.WOODEN_SHIELD_1171) + } + item(Item(Items.BRONZE_SWORD_1277), Item(Items.WOODEN_SHIELD_1171), "The Combat Guide gives you a bronze sword and a", "wooden shield!", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 48) + TutorialStage.load(player, 48) + } + goto("nowhere") + + label("lost sword") + exec { player, _ -> addItemOrDrop(player, Items.BRONZE_SWORD_1277) } + item(Item(Items.BRONZE_SWORD_1277), "The Combat Guide gives you a spare sword.", unclosable = true) + exec { player, _ -> if (lostWeapon(player, Items.WOODEN_SHIELD_1171)) loadLabel(player, "lost shield") } + goto("nowhere") + + label("lost shield") + exec { player, _ -> addItemOrDrop(player, Items.WOODEN_SHIELD_1171) } + item(Item(Items.WOODEN_SHIELD_1171), "The Combat Guide gives you a spare shield.", unclosable = true) + goto("nowhere") + + label("killed rat") + player(ChatAnim.FRIENDLY, "I did it! I killed a giant rat!", unclosable = true) + npc(ChatAnim.FRIENDLY, "I saw, ${player?.username}. You seem better at this than I thought. Now that you have grasped basic swordplay, let's move on.", unclosable = true) + npc(ChatAnim.FRIENDLY, "Let's try some ranged attacking, with this you can kill foes from a distance. Also, foes unable to reach you are as good as dead. You'll be able to attack the rats, without entering the pit.", unclosable = true) + exec { player, _ -> + addItemOrDrop(player, Items.SHORTBOW_841) + addItemOrDrop(player, Items.BRONZE_ARROW_882, 30) + } + item(Item(Items.SHORTBOW_841), Item(Items.BRONZE_ARROW_882), "The Combat Guide gives you some bronze arrows and", "a shortbow!", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 54) + TutorialStage.load(player, 54) + } + goto("nowhere") + + label("lost bow") + exec { player, _ -> addItemOrDrop(player, Items.SHORTBOW_841) } + item(Item(Items.SHORTBOW_841), "The Combat Guide gives you a spare bow.", unclosable = true) + goto("nowhere") + + label("lost arrows") + exec { player, _ -> addItemOrDrop(player, Items.BRONZE_ARROW_882, 10) } + item(Item(Items.BRONZE_ARROW_882), "You receive some spare arrows.", unclosable = true) + goto("nowhere") + + label("nowhere") + exec { player, _ -> sendStageDialog(player) } + } } diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt index 305911ae5..d94bcd922 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt @@ -7,11 +7,12 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import core.game.component.Component.setUnclosable import core.game.world.GameWorld.settings /** * Handles the finance tutor's dialogue - * @author Ceikry + * @author Ceikry, Player Name */ @Initializable class TutorialFinanceAdvisorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { @@ -23,8 +24,8 @@ class TutorialFinanceAdvisorDialogue(player: Player? = null) : core.game.dialogu npc = args[0] as NPC when(getAttribute(player, "tutorial:stage", 0)) { - 58 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello, who are you?") - 59 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Move along, now.").also { return false } + 58 -> setUnclosable(player, playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello, who are you?")) + 59 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Move along, now.")) } return true } @@ -32,21 +33,22 @@ class TutorialFinanceAdvisorDialogue(player: Player? = null) : core.game.dialogu override fun handle(interfaceId: Int, buttonId: Int): Boolean { when(getAttribute(player, "tutorial:stage", 0)){ 58 -> when(stage++){ - 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm the Financial Advisor. I'm here to tell people how to make money.") - 1 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Okay. How can I make money then?") - 2 -> npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "How you can make money? Quite.") - 3 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well there are three basic ways of making money here: combat, quests, and trading. I will talk you through each of them very quickly.") - 4 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Let's start with combat as it is probably still fresh in your mind. Many enemies, both human and monster will drop items when they die.") - 5 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Now, the next way to earn money quickly is by quests. Many people on " + settings!!.name + " have things they need doing, which they will reward you for.") - 6 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "By getting a high level in skills such as Cooking, Mining, Smithing or Fishing, you can create or catch your own items and sell them for pure profit.") - 7 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Lastly, we have jobs you can get from tutors in Lumbridge. These pay very handsomely early on!").also { stage++ } - 8 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, that about covers it. Move along now.") + 0 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm the Financial Advisor. I'm here to tell people how to make money.")) + 1 -> setUnclosable(player, playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Okay. How can I make money then?")) + 2 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "How you can make money? Quite.")) + 3 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well there are three basic ways of making money here: combat, quests, and trading. I will talk you through each of them very quickly.")) + 4 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Let's start with combat as it is probably still fresh in your mind. Many enemies, both human and monster will drop items when they die.")) + 5 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Now, the next way to earn money quickly is by quests. Many people on " + settings!!.name + " have things they need doing, which they will reward you for.")) + 6 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "By getting a high level in skills such as Cooking, Mining, Smithing or Fishing, you can create or catch your own items and sell them for pure profit.")) + 7 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Lastly, we have jobs you can get from tutors in Lumbridge. These pay very handsomely early on!")).also { stage++ } + 8 -> setUnclosable(player, npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, that about covers it. Move along now.")) 9 -> { end() setAttribute(player, "tutorial:stage", 59) TutorialStage.load(player, 59) } } + 59 -> TutorialStage.load(player, 59) } return true } @@ -54,5 +56,4 @@ class TutorialFinanceAdvisorDialogue(player: Player? = null) : core.game.dialogu override fun getIds(): IntArray { return intArrayOf(NPCs.FINANCIAL_ADVISOR_947) } - } \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt index 2221a4d79..68707766d 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt @@ -1,205 +1,229 @@ package content.region.misc.tutisland.dialogue +import content.global.handlers.iface.RulesAndInfo import content.region.misc.tutisland.handlers.* +import core.ServerConstants import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player import core.game.node.entity.player.link.IronmanMode import core.game.node.entity.player.link.TeleportManager import core.game.node.item.Item +import core.game.world.GameWorld import core.game.world.map.Location import core.plugin.Initializable +import core.worker.ManagementEvents import org.rs09.consts.Items import org.rs09.consts.NPCs import proto.management.JoinClanRequest -import core.ServerConstants -import content.global.handlers.iface.RulesAndInfo -import core.game.world.GameWorld -import core.tools.END_DIALOGUE -import core.worker.ManagementEvents -/** - * Handles the magic tutor's dialogue - * @author Ceikry - */ @Initializable -class TutorialMagicTutorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { - private val STARTER_PACK = arrayOf( - Item(1351, 1), - Item(590, 1), - Item(303, 1), - Item(315, 1), - Item(1925, 1), - Item(1931, 1), - Item(2309, 1), - Item(1265, 1), - Item(1205, 1), - Item(1277, 1), - Item(1171, 1), - Item(841, 1), - Item(882, 25), - Item(556, 25), - Item(558, 15), - Item(555, 6), - Item(557, 4), - Item(559, 2) - ) - private val STARTER_BANK = arrayOf(Item(995, 25)) - - override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { - return TutorialMagicTutorDialogue(player) - } - - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - when(getAttribute(player, "tutorial:stage", 0)) - { - 67 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello.") - 69 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Good. This is a list of your spells. Currently you can only cast one offensive spell called Wind Strike. Let's try it out on one of those chickens.") - 70 -> if(!inInventory(player, Items.AIR_RUNE_556) && !inInventory(player, Items.MIND_RUNE_558)) - { - player.dialogueInterpreter.sendDoubleItemMessage(Items.AIR_RUNE_556, Items.MIND_RUNE_558, "You receive some spare runes.") - addItem(player, Items.AIR_RUNE_556, 15) - addItem(player, Items.MIND_RUNE_558, 15) - return false +class TutorialMagicTutorDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.MAGIC_INSTRUCTOR_946, NPC, "talk-to") { player, _ -> + val stage = getAttribute(player, "tutorial:stage", 0) + if (stage == 70 && inInventory(player, Items.AIR_RUNE_556) && inInventory(player, Items.MIND_RUNE_558)) { + // Player should be killing chickens instead, and could be. Instead of opening the dialogue and doing nothing (which will make you lose the tutorial island dialog), do nothing at all + return@on true } - 71 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Alright, last thing. Are you interested in being an ironman or changing your experience rate?") - else -> return false + openDialogue(player, TutorialMagicTutorDialogueFile(), NPC(NPCs.MAGIC_INSTRUCTOR_946)) + return@on true } - return true } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(getAttribute(player, "tutorial:stage", 0)) - { - 67 -> when(stage++){ - 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Good day, newcomer. My name is Terrova. I'm here to tell you about Magic. Let's start by opening your spell list.") - 1 -> { - end() - setAttribute(player, "tutorial:stage", 68) - TutorialStage.load(player, 68) - } - } - 69 -> when(stage++){ - 0 -> { - sendDoubleItemDialogue(player, Items.AIR_RUNE_556, Items.MIND_RUNE_558, "Terrova gives you 15 air runes and 15 mind runes!") - addItemOrDrop(player, Items.AIR_RUNE_556, 5) - addItemOrDrop(player, Items.MIND_RUNE_558, 5) - } - 1 -> { - end() - setAttribute(player, "tutorial:stage", 70) - TutorialStage.load(player, 70) - } - } - 71 -> when(stage){ - 0 -> options("Set Ironman Mode (current: ${player.ironmanManager.mode.name})", "Change XP Rate (current: ${player.skills.experienceMutiplier}x)", "I'm ready now.").also { stage++ } - 1 -> when(buttonId){ - 1 -> options("None","Standard","Hardcore (Permadeath!)","Ultimate","Nevermind.").also { stage = 10 } - 2 -> options("1.0x","2.5x","5.0x","10x").also { stage = 20 } - 3 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, you're all finished here now. I'll give you a reasonable number of starting items when you leave.").also { stage = 30 } - } - - 10 -> { - stage = 0 - if(buttonId < 5) - { - val mode = IronmanMode.values()[buttonId - 1] - player.dialogueInterpreter.sendDialogue("You set your ironman mode to: ${mode.name}.") - player.ironmanManager.mode = mode - if (player.skills.experienceMutiplier == 10.0 && mode != IronmanMode.HARDCORE) player.skills.experienceMutiplier = 5.0 - } - else - { - handle(interfaceId, 0) - } - } - - 20 -> { - val rates = arrayOf(1.0,2.5,5.0,10.0) - val rate = rates[buttonId - 1] - if(rate == 10.0 && player.ironmanManager.mode != IronmanMode.HARDCORE) { - player.dialogueInterpreter.sendDialogue("10.0x is only available to Hardcore Ironmen!") - stage = 0 - return true - } - player.dialogueInterpreter.sendDialogue("You set your XP rate to: ${rate}x.") - player.skills.experienceMutiplier = rate - stage = 0 - } - - 30 -> player.dialogueInterpreter.sendOptions("Leave Tutorial Island?", "Yes, I'm ready.", "No, not yet.").also { stage++ } - 31 -> when(buttonId) - { - 1 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm ready to go now, thank you.").also { stage = 40 } - 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm not quite ready to go yet, thank you.").also { stage = END_DIALOGUE } - } - - 40 -> { - setAttribute(player, "/save:tutorial:complete", true) - setVarbit(player, 3756, 0) - teleport(player, Location.create(3233, 3230), TeleportManager.TeleportType.NORMAL) - closeOverlay(player) - - player.inventory.clear() - player.bank.clear() - player.equipment.clear() - player.interfaceManager.restoreTabs() - player.interfaceManager.setViewedTab(3) - player.inventory.add(*STARTER_PACK) - player.bank.add(*STARTER_BANK) - - if(player.ironmanManager.mode == IronmanMode.HARDCORE) - { - setAttribute(player, "/save:permadeath", true) - } - else if(player.skills.experienceMutiplier == 10.0) - { - player.skills.experienceMutiplier = 5.0 - } - - //This overwrites the stuck dialogue after teleporting to Lumbridge for some reason - //Dialogue from 2007 or thereabouts - //Original is five lines, but if the same is done here it will break. Need to find another way of showing all this information. - interpreter.sendDialogue( - "Welcome to Lumbridge! To get more help, simply click on the", - "Lumbridge Guide or one of the Tutors - these can be found by looking", - "for the question mark icon on your mini-map. If you find you are lost", - "at any time, look for a signpost or use the Lumbridge Home Port Spell." - ) - stage = 12 - TutorialStage.removeHintIcon(player) - - player.unhook(TutorialKillReceiver) - player.unhook(TutorialFireReceiver) - player.unhook(TutorialResourceReceiver) - player.unhook(TutorialUseWithReceiver) - player.unhook(TutorialInteractionReceiver) - player.unhook(TutorialButtonReceiver) - RulesAndInfo.openFor(player) - - if (GameWorld.settings!!.enable_default_clan) { - player.communication.currentClan = ServerConstants.SERVER_NAME.toLowerCase() - - val clanJoin = JoinClanRequest.newBuilder() - clanJoin.clanName = ServerConstants.SERVER_NAME.toLowerCase() - clanJoin.username = player.name - - ManagementEvents.publish(clanJoin.build()) - } - } - - 12 -> { - player.setAttribute("close_c_", true) - end() - } - } - } - return true - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.MAGIC_INSTRUCTOR_946) - } - +} + +class TutorialMagicTutorDialogueFile : DialogueLabeller() { + override fun addConversation() { + val STARTER_PACK = arrayOf( + Item(Items.BRONZE_AXE_1351), + Item(Items.TINDERBOX_590), + Item(Items.SMALL_FISHING_NET_303), + Item(Items.SHRIMPS_315), + Item(Items.BUCKET_1925), + Item(Items.EMPTY_POT_1931), + Item(Items.BREAD_2309), + Item(Items.BRONZE_PICKAXE_1265), + Item(Items.BRONZE_DAGGER_1205), + Item(Items.BRONZE_SWORD_1277), + Item(Items.WOODEN_SHIELD_1171), + Item(Items.SHORTBOW_841), + Item(Items.BRONZE_ARROW_882, 25), + Item(Items.AIR_RUNE_556, 25), + Item(Items.MIND_RUNE_558, 15), + Item(Items.WATER_RUNE_555, 6), + Item(Items.EARTH_RUNE_557, 4), + Item(Items.BODY_RUNE_559, 2) + ) + val STARTER_BANK = arrayOf(Item(Items.COINS_995, 25)) + + exec { player, _ -> + when (getAttribute(player, "tutorial:stage", 0)) { + 67 -> loadLabel(player, "hello") + 69 -> loadLabel(player, "spelllist") + 70 -> { + if (!inInventory(player, Items.AIR_RUNE_556, 1) || !inInventory(player, Items.MIND_RUNE_558, 1)) { + loadLabel(player, "givemorerunes") + } else { + goto("nowhere") + } + } + 71 -> loadLabel(player, "finishedtutorial") + else -> goto("nowhere") + } + } + + label("hello") + player(ChatAnim.FRIENDLY, "Hello.", unclosable = true) + npc(ChatAnim.FRIENDLY, "Good day, newcomer. My name is Terrova. I'm here to tell you about Magic. Let's start by opening your spell list.", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 68) + TutorialStage.load(player, 68) + } + + label("spelllist") + npc(ChatAnim.FRIENDLY, "Good. This is a list of your spells. Currently you can only cast one offensive spell called Wind Strike. Let's try it out on one of those chickens.", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 70) + addItemOrDrop(player, Items.AIR_RUNE_556, 15) + addItemOrDrop(player, Items.MIND_RUNE_558, 15) + } + item(Item(Items.AIR_RUNE_556), Item(Items.MIND_RUNE_558), "Terrova gives you 15 air runes and 15 mind runes!", unclosable = true) + exec { player, _ -> TutorialStage.load(player, 70) } + + label("givemorerunes") + exec { player, _ -> + addItemOrDrop(player, Items.AIR_RUNE_556, 5) + addItemOrDrop(player, Items.MIND_RUNE_558, 5) + } + item(Item(Items.AIR_RUNE_556), Item(Items.MIND_RUNE_558), "You receive some spare runes.", unclosable = true) + exec { player, _ -> TutorialStage.load(player, 70) } + + label("finishedtutorial") + exec { player, _ -> + if (ServerConstants.XP_RATES || ServerConstants.IRONMAN) { + loadLabel(player, "talk about inauthentic") + } else { + loadLabel(player, "leave") + } + } + + label("talk about inauthentic") + npc(ChatAnim.FRIENDLY, "Alright, last thing. Are you interested in our inauthentic ${ServerConstants.SERVER_NAME} features?", unclosable = true) + goto("inauthentic") + + label("inauthentic") + options( + DialogueOption("xprate","Change XP rate (current: ${player?.skills?.experienceMultiplier}x)", skipPlayer = true) { _, _ -> + return@DialogueOption ServerConstants.XP_RATES + }, + DialogueOption("ironman","Set ironman mode (current: ${player?.ironmanManager?.mode?.name?.toLowerCase()})", skipPlayer = true) { _, _ -> + return@DialogueOption ServerConstants.IRONMAN + }, + DialogueOption("leave","I'm ready now."), + unclosable = true) + + label("xprate") + options( + DialogueOption("1.0x","1.0x (default)", skipPlayer = true), + DialogueOption("2.5x","2.5x", skipPlayer = true), + DialogueOption("5.0x","5.0x", skipPlayer = true), + title = "Change XP rate (current: ${player?.skills?.experienceMultiplier}x)", + unclosable = true + ) + for (rate in doubleArrayOf(1.0, 2.5, 5.0)) { + label("${rate}x") + exec { player, _ -> player.skills.experienceMultiplier = rate } + manual(unclosable = true) { player, _ -> player.dialogueInterpreter.sendDialogue("You set your XP rate to: ${rate}x.") } + goto("inauthentic") + } + + label("ironman") + options( + DialogueOption("NONE","None (default)", skipPlayer = true), + DialogueOption("STANDARD","Standard", skipPlayer = true), + DialogueOption("ULTIMATE","Ultimate (no bank)", skipPlayer = true), + title = "Change ironman mode (current: ${player?.ironmanManager?.mode?.name?.toLowerCase()}x)" + ) + for (mode in arrayOf(IronmanMode.NONE, IronmanMode.STANDARD, IronmanMode.ULTIMATE)) { + label(mode.name) + exec { player, _ -> player.ironmanManager.mode = mode } + manual(unclosable = true){ player, _ -> return@manual player.dialogueInterpreter.sendDialogue("You set your ironman mode to: ${mode.name.toLowerCase()}.") } + exec { player, _ -> loadLabel(player, if (player.ironmanManager.mode == IronmanMode.NONE) "inauthentic" else "ironwarning") } + } + + label("ironwarning") + manual(unclosable = true) { player, _ -> player.dialogueInterpreter.sendDialogue(*splitLines("WARNING: You have selected an ironman mode. This is an uncompromising mode that WILL completely restrict your ability to trade. This MAY leave you unable to complete certain content, including quests.")) } + goto("inauthentic") + + label("leave") + npc(ChatAnim.FRIENDLY, "Well, you're all finished here now. I'll give you a reasonable number of starting items when you leave.", unclosable = true) + options( + DialogueOption("leave:yes","Yes, I'm ready.","I'm ready to go now, thank you.", ChatAnim.FRIENDLY), + DialogueOption("nowhere","No, not yet.","I'm not quite ready to go yet, thank you.", ChatAnim.FRIENDLY), + title = "Leave Tutorial Island?", + unclosable = true + ) + + label("leave:yes") + manual { player, _ -> + setAttribute(player, "/save:tutorial:complete", true) + setVarbit(player, 3756, 0) + setVarp(player, 281, 1000, true) + teleport(player, Location.create(3233, 3230), TeleportManager.TeleportType.NORMAL) + closeOverlay(player) + + player.inventory.clear() + player.bank.clear() + player.equipment.clear() + player.interfaceManager.restoreTabs() + player.interfaceManager.setViewedTab(3) + player.inventory.add(*STARTER_PACK) + player.bank.add(*STARTER_BANK) + + TutorialStage.removeHintIcon(player) + player.unhook(TutorialKillReceiver) + player.unhook(TutorialFireReceiver) + player.unhook(TutorialResourceReceiver) + player.unhook(TutorialUseWithReceiver) + player.unhook(TutorialInteractionReceiver) + player.unhook(TutorialButtonReceiver) + player.unhook(TutorialDialogPreserver) + + if (GameWorld.settings!!.enable_default_clan) { + player.communication.currentClan = ServerConstants.SERVER_NAME.toLowerCase() + + val clanJoin = JoinClanRequest.newBuilder() + clanJoin.clanName = ServerConstants.SERVER_NAME.toLowerCase() + clanJoin.username = player.name + + ManagementEvents.publish(clanJoin.build()) + } + + // This shows the actual dialog, which is what this manual stage is for. + // Dialog is from 2007 or thereabouts. + // Original is five lines, but if the same is done here it will break. Need to find another way of showing all this information. + player.dialogueInterpreter.sendDialogue( + "Welcome to Lumbridge! To get more help, simply click on the", + "Lumbridge Guide or one of the Tutors - these can be found by looking", + "for the question mark icon on your mini-map. If you find you are lost", + "at any time, look for a signpost or use the Lumbridge Home Port Spell." + ) + if (ServerConstants.RULES_AND_INFO_ENABLED) { + RulesAndInfo.openFor(player) + // The teleport finishing will release the player, so we need to relock them here + queueScript(player, 4, QueueStrength.SOFT) { _ -> + player.lock() + return@queueScript stopExecuting(player) + } + } + return@manual null + } + + label("nowhere") + exec { player, _ -> sendStageDialog(player) } + } } diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt index 2db699406..89d985f29 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt @@ -1,7 +1,7 @@ package content.region.misc.tutisland.dialogue import core.api.* -import core.game.component.Component +import core.game.component.Component.setUnclosable import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -25,32 +25,17 @@ class TutorialMasterChefDialogue(player: Player? = null) : DialoguePlugin(player npc = args[0] as NPC when(getAttribute(player, "tutorial:stage", 0)) { - 18 -> Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.FRIENDLY, - "Ah! Welcome, newcomer. I am the Master Chef, Lev. It", - "is here I will teach you how to cook food truly fit for a", - "king." - ) - ) - - 19,20 -> { - if(!inInventory(player, Items.BREAD_DOUGH_2307)) - { - if(!inInventory(player, Items.BUCKET_OF_WATER_1929)) - { - sendItemDialogue(player, Items.BUCKET_OF_WATER_1929, "The Master Chef gives you another bucket of water.") - addItem(player, Items.BUCKET_OF_WATER_1929) - TutorialStage.load(player, 19) + 18 -> setUnclosable(player, interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Ah! Welcome, newcomer. I am the Master Chef, Lev. It", "is here I will teach you how to cook food truly fit for a", "king.")) + 19, 20 -> { + if (!inInventory(player, Items.BREAD_DOUGH_2307)) { + if (!inInventory(player, Items.BUCKET_OF_WATER_1929)) { + setUnclosable(player, player.dialogueInterpreter.sendItemMessage(Items.BUCKET_OF_WATER_1929, "The Master Chef gives you another bucket of water.")) + addItemOrDrop(player, Items.BUCKET_OF_WATER_1929) return false } - if(!inInventory(player, Items.POT_OF_FLOUR_1933)) - { - sendItemDialogue(player, Items.POT_OF_FLOUR_1933, "The Master Chef gives you another pot of flour.") - addItem(player, Items.POT_OF_FLOUR_1933) - TutorialStage.load(player, 19) + if (!inInventory(player, Items.POT_OF_FLOUR_1933)) { + setUnclosable(player, player.dialogueInterpreter.sendItemMessage(Items.POT_OF_FLOUR_1933, "The Master Chef gives you another pot of flour.")) + addItemOrDrop(player, Items.POT_OF_FLOUR_1933) return false } } @@ -61,54 +46,21 @@ class TutorialMasterChefDialogue(player: Player? = null) : DialoguePlugin(player } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(getAttribute(player, "tutorial:stage", 0)) - { - 18 -> when(stage) - { - 0 -> Component.setUnclosable( - player, - interpreter.sendDialogues( - player, - FacialExpression.HALF_GUILTY, - "I already know how to cook. Brynna taught me just", - "now." - ) - ).also { stage++ } - 1 -> Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.LAUGH, - "Hahahahahaha! You call THAT cooking? Some shrimp", - "on an open log fire? Oh, no, no no. I am going to", - "teach you the fine art of cooking bread." - ) - ).also { stage++ } - 2 -> Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.FRIENDLY, - "And no fine meal is complete without good music, so", - "we'll cover that while you're here too." - ) - ).also { stage++ } + when (getAttribute(player, "tutorial:stage", 0)) { + 18 -> when(stage) { + 0 -> setUnclosable(player, interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I already know how to cook. Brynna taught me just", "now.")).also { stage++ } + 1 -> setUnclosable(player, interpreter.sendDialogues(npc, FacialExpression.LAUGH, "Hahahahahaha! You call THAT cooking? Some shrimp", "on an open log fire? Oh, no, no no. I am going to", "teach you the fine art of cooking bread.")).also { stage++ } + 2 -> setUnclosable(player, interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "And no fine meal is complete without good music, so", "we'll cover that while you're here too.")).also { stage++ } 3 -> { - Component.setUnclosable( - player, - interpreter.sendDoubleItemMessage( - Items.BUCKET_OF_WATER_1929, - Items.POT_OF_FLOUR_1933, - "The Cooking Guide gives you a bucket of water and a pot of flour." - ) - ) - addItem(player, Items.BUCKET_OF_WATER_1929) - addItem(player, Items.POT_OF_FLOUR_1933) + setUnclosable(player, interpreter.sendDoubleItemMessage(Items.BUCKET_OF_WATER_1929, Items.POT_OF_FLOUR_1933, "The Cooking Guide gives you a bucket of water and a","pot of flour.")) + addItemOrDrop(player, Items.BUCKET_OF_WATER_1929) + addItemOrDrop(player, Items.POT_OF_FLOUR_1933) stage++ + setAttribute(player, "tutorial:stage", 19) + TutorialStage.load(player, 19) } 4 -> { end() - setAttribute(player, "tutorial:stage", 19) TutorialStage.load(player, 19) } } diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt index ad9f6c77e..fc1f96c81 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt @@ -1,107 +1,95 @@ package content.region.misc.tutisland.dialogue -import core.api.addItem -import core.api.getAttribute -import core.api.inInventory -import core.api.setAttribute -import core.game.dialogue.DialoguePlugin -import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import content.region.misc.tutisland.handlers.sendStageDialog +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.item.Item -/** - * Handles the mining tutor's dialogue - * @author Ceikry - */ -@Initializable -class TutorialMiningInstructorDialogue(player: Player? = null) : DialoguePlugin(player) { - override fun newInstance(player: Player?): DialoguePlugin { - return TutorialMiningInstructorDialogue(player) +class MiningInstructorDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.MINING_INSTRUCTOR_948, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, MiningInstructorDialogueFile(), node as NPC) + return@on true + } + } +} + +class MiningInstructorDialogueFile : DialogueLabeller() { + fun lostPickaxe(player: Player): Boolean { + return !inInventory(player, Items.BRONZE_PICKAXE_1265) && !inEquipment(player, Items.BRONZE_PICKAXE_1265) } - override fun open(vararg args: Any?): Boolean { - npc = args[0] as NPC - when(getAttribute(player, "tutorial:stage", 0)) { - 30 -> npcl(FacialExpression.FRIENDLY, "Hi there. You must be new around here. So what do I call you? 'Newcomer' seems so impersonal, and if we're going to be working together, I'd rather tell you by name.") - 34 -> playerl(FacialExpression.FRIENDLY, "I prospected both types of rock! One set contains tin and the other has copper ore inside.") - 35 -> { - if(!inInventory(player, Items.BRONZE_PICKAXE_1265)) { - addItem(player, Items.BRONZE_PICKAXE_1265) - player.dialogueInterpreter.sendItemMessage(Items.BRONZE_PICKAXE_1265, "Dezzick gives you a bronze pickaxe!") - stage = 3 - } - else { - TutorialStage.load(player, 35) - } - } - 40 -> playerl(FacialExpression.ASKING, "How do I make a weapon out of this?") - 41 -> { - if(!inInventory(player, Items.HAMMER_2347)) { - addItem(player, Items.HAMMER_2347) - player.dialogueInterpreter.sendItemMessage(Items.HAMMER_2347, "Dezzick gives you a hammer!") - stage = 3 - } - else - { - end() - TutorialStage.load(player, 41) - } + override fun addConversation() { + assignToIds(NPCs.MINING_INSTRUCTOR_948) + + exec { player, _ -> + when (getAttribute(player, "tutorial:stage", 0)) { + 30 -> loadLabel(player, "hello") + 34 -> loadLabel(player, "prospected") + 35, 36, 37, 38, 39 -> loadLabel(player, if (lostPickaxe(player)) "lost pickaxe" else "nowhere") + 40 -> loadLabel(player, "make wep") + 41, 42, 43, 44, 45, 46 -> loadLabel(player, if (lostPickaxe(player)) "lost pickaxe" else if (!inInventory(player, Items.HAMMER_2347)) "lost hammer" else "nowhere") + else -> loadLabel(player, "nowhere") } } - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(getAttribute(player, "tutorial:stage", 0)) { - 30 -> when(stage) { - 0 -> playerl(FacialExpression.FRIENDLY, "You can call me ${player.username}.").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "Ok then, ${player.username}. My name is Dezzick and I'm a miner by trade. Let's prospect some of these rocks.").also { stage++ } - 2 -> { - end() - setAttribute(player, "tutorial:stage", 31) - TutorialStage.load(player, 31) - } - } - - 34,35 -> when(stage) { - 0 -> npcl(FacialExpression.FRIENDLY, "Absolutely right, ${player.username}. These two ore types can be smelted together to make bronze.").also { stage++ } - 1 -> npcl(FacialExpression.FRIENDLY, "So now you know what ore is in the rocks over there, why don't you have a go at mining some tin and copper? Here, you'll need this to start with.").also { stage++ } - 2 -> { - addItem(player, Items.BRONZE_PICKAXE_1265) - player.dialogueInterpreter.sendItemMessage(Items.BRONZE_PICKAXE_1265, "Dezzick gives you a bronze pickaxe!") - stage++ - } - 3 -> { - end() - setAttribute(player, "tutorial:stage", 35) - TutorialStage.load(player, 35) - } - } - - 40,41 -> when(stage){ - 0 -> npcl(FacialExpression.FRIENDLY, "Okay, I'll show you how to make a dagger out of it. You'll be needing this..").also { stage++ } - 1 -> { - addItem(player, Items.HAMMER_2347) - player.dialogueInterpreter.sendItemMessage(Items.HAMMER_2347, "Drezzick gives you a hammer!") - stage++ - } - 2 -> { - end() - setAttribute(player, "tutorial:stage", 41) - TutorialStage.load(player, 41) - } - } + label("hello") + npc(ChatAnim.FRIENDLY, "Hi there. You must be new around here. So what do I call you? 'Newcomer' seems so impersonal, and if we're going to be working together, I'd rather tell you by name.", unclosable = true) + player(ChatAnim.FRIENDLY, "You can call me ${player?.username}.", unclosable = true) + npc(ChatAnim.FRIENDLY, "Ok then, ${player?.username}. My name is Dezzick and I'm a miner by trade. Let's prospect some of these rocks.", unclosable = true) + exec { player, _ -> + setAttribute(player, "tutorial:stage", 31) + TutorialStage.load(player, 31) } - return true - } + label("prospected") + player(ChatAnim.FRIENDLY, "I prospected both types of rock! One set contains tin and the other has copper ore inside.", unclosable = true) + npc(ChatAnim.FRIENDLY, "Absolutely right, ${player?.username}. These two ore types can be smelted together to make bronze.", unclosable = true) + npc(ChatAnim.FRIENDLY, "So now you know what ore is in the rocks over there, why don't you have a go at mining some tin and copper? Here, you'll need this to start with.", unclosable = true) + exec { player, _ -> + addItem(player, Items.BRONZE_PICKAXE_1265) + setAttribute(player, "tutorial:stage", 35) + TutorialStage.load(player, 35) + } + item(Item(Items.BRONZE_PICKAXE_1265), "Dezzick gives you a bronze pickaxe!", unclosable = true) + goto("nowhere") - override fun getIds(): IntArray { - return intArrayOf(NPCs.MINING_INSTRUCTOR_948) + label("make wep") + player(ChatAnim.ASKING, "How do I make a weapon out of this?", unclosable = true) + npc(ChatAnim.FRIENDLY, "Okay, I'll show you how to make a dagger out of it. You'll be needing this.", unclosable = true) + exec { player, _ -> + addItem(player, Items.HAMMER_2347) + setAttribute(player, "tutorial:stage", 41) + TutorialStage.load(player, 41) + } + item(Item(Items.HAMMER_2347), "Dezzick gives you a hammer!", unclosable = true) + goto("nowhere") + + label("lost pickaxe") + exec { player, _ -> addItem(player, Items.BRONZE_PICKAXE_1265) } + item(Item(Items.BRONZE_PICKAXE_1265), "Dezzick gives you a spare pickaxe.", unclosable = true) + exec { player, _ -> + val stage = getAttribute(player, "/save:tutorial:stage", 0) + if (stage >= 41 && !inInventory(player, Items.HAMMER_2347)) { + loadLabel(player, "lost hammer") + } + } + goto("nowhere") + + label("lost hammer") + exec { player, _ -> addItem(player, Items.HAMMER_2347) } + item(Item(Items.HAMMER_2347), "Dezzick gives you a spare hammer.", unclosable = true) + goto("nowhere") + + label("nowhere") + exec { player, _ -> sendStageDialog(player) } } } \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt index 5278dc65d..3fb71bd16 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt @@ -9,6 +9,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import core.game.component.Component.setUnclosable /** * Handles the prayer guide's dialogue @@ -24,9 +25,9 @@ class TutorialPrayerDialogue(player: Player? = null) : DialoguePlugin(player) { npc = args[0] as NPC when(getAttribute(player, "tutorial:stage", 0)) { - 60 -> npcl(FacialExpression.FRIENDLY, "Greetings! I'd just like to briefly go over two topics with you: Prayer, and Friend's.") - 62 -> npcl(FacialExpression.FRIENDLY, "Prayers have all sorts of wonderful benefits! From boosting defence and damage, to protecting you from outside damage, to saving items on death!") - 65 -> npcl(FacialExpression.FRIENDLY, "For your friend and ignore lists, it's quite simple really! Use your friend list to keep track of players who you like, and ignore those you don't!") + 60 -> setUnclosable(player, npcl(FacialExpression.FRIENDLY, "Greetings! I'd just like to briefly go over two topics with you: Prayer, and Friend's.")) + 62 -> setUnclosable(player, npcl(FacialExpression.FRIENDLY, "Prayers have all sorts of wonderful benefits! From boosting defence and damage, to protecting you from outside damage, to saving items on death!")) + 65 -> setUnclosable(player, npcl(FacialExpression.FRIENDLY, "For your friend and ignore lists, it's quite simple really! Use your friend list to keep track of players who you like, and ignore those you don't!")) } return true } @@ -35,8 +36,8 @@ class TutorialPrayerDialogue(player: Player? = null) : DialoguePlugin(player) { when(getAttribute(player, "tutorial:stage", 0)) { 60 -> when(stage++){ - 0 -> playerl(FacialExpression.FRIENDLY, "Alright, sounds fun!") - 1 -> npcl(FacialExpression.FRIENDLY, "Right, so first thing: Prayer. Prayer is trained by offering bones to the gods, and can grant you many boons!") + 0 -> setUnclosable(player, playerl(FacialExpression.FRIENDLY, "Alright, sounds fun!")) + 1 -> setUnclosable(player, npcl(FacialExpression.FRIENDLY, "Right, so first thing: Prayer. Prayer is trained by offering bones to the gods, and can grant you many boons!")) 2 -> { end() setAttribute(player, "tutorial:stage", 61) @@ -45,8 +46,8 @@ class TutorialPrayerDialogue(player: Player? = null) : DialoguePlugin(player) { } 62 -> when(stage++){ - 0 -> playerl(FacialExpression.AMAZED, "Very cool!") - 1 -> npcl(FacialExpression.FRIENDLY, "Next up, let's talk about friends.") + 0 -> setUnclosable(player, playerl(FacialExpression.AMAZED, "Very cool!")) + 1 -> setUnclosable(player, npcl(FacialExpression.FRIENDLY, "Next up, let's talk about friends.")) 2 -> { end() setAttribute(player, "tutorial:stage", 63) diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt index 015928854..716bc2cf4 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt @@ -12,6 +12,7 @@ import core.plugin.Initializable import org.rs09.consts.Components import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import core.game.component.Component.setUnclosable /** * Handles the quest guide's dialogue @@ -27,7 +28,7 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player npc = args[0] as NPC when(getAttribute(player, "tutorial:stage", 0)) { - 27 -> Component.setUnclosable( + 27 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -37,7 +38,7 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player ) ) - 28 -> Component.setUnclosable( + 28 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -57,7 +58,7 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player when(getAttribute(player, "tutorial:stage", 0)) { 27 -> { - Component.setUnclosable( + setUnclosable( player, interpreter.sendPlaneMessageWithBlueTitle( "Open the Quest Journal.", @@ -72,7 +73,7 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player } 28 -> when(stage) { - 0 -> Component.setUnclosable( + 0 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -83,7 +84,7 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player "to begin." ) ).also { stage++ } - 1 -> Component.setUnclosable( + 1 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -93,7 +94,7 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player "see marking my house." ) ).also { stage++ } - 2 -> Component.setUnclosable( + 2 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -118,5 +119,4 @@ class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player override fun getIds(): IntArray { return intArrayOf(NPCs.QUEST_GUIDE_949) } - } diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt index 4d7653695..b3611f89e 100644 --- a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt @@ -1,7 +1,6 @@ package content.region.misc.tutisland.dialogue import core.api.setAttribute -import core.game.component.Component import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -9,10 +8,12 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs import content.region.misc.tutisland.handlers.TutorialStage +import core.game.component.Component.setUnclosable /** - * Handles the RuneSccape guide's dialogue + * Handles the 2009scape guide's dialogue * @author Ceikry + * @author Player Name */ @Initializable class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -23,26 +24,12 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC val tutStage = player?.getAttribute("tutorial:stage", 0) ?: 0 - if(tutStage < 2) { - end() - player.dialogueInterpreter.sendDialogues(npc,FacialExpression.HALF_GUILTY,"Greetings! Please follow the onscreen, instructions!") - return false - } else { - Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.HALF_GUILTY, - "Greetings! Please follow the onscreen", - "instructions!" - ) - ) - } - - if(tutStage == 2) - { + if (tutStage < 2) { + setUnclosable(player, player.dialogueInterpreter.sendDialogues(npc,FacialExpression.HALF_GUILTY,"Greetings! Please follow the onscreen instructions!")) + stage = 99 + } else if (tutStage == 2) { player.lock() - Component.setUnclosable( + setUnclosable( player, interpreter.sendDialogues( npc, @@ -52,26 +39,17 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { ) ) stage = 0 - return true - } - else - { - Component.setUnclosable( - player, - interpreter.sendDialogues( - npc, - FacialExpression.HALF_GUILTY, - "Please follow the onscreen instructions!" - ) - ) - return false + } else { + setUnclosable(player, player.dialogueInterpreter.sendDialogues(npc,FacialExpression.HALF_GUILTY,"Please follow the onscreen instructions!")) + stage = 99 } + return true } override fun handle(interfaceId: Int, buttonId: Int): Boolean { when(stage) { - 0 -> Component.setUnclosable( + 0 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -81,7 +59,7 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { ) ).also { stage++ } - 1 -> Component.setUnclosable( + 1 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -92,7 +70,7 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { ) ).also { stage++ } - 2 -> Component.setUnclosable( + 2 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -104,7 +82,7 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { ) ).also { stage++ } - 3 -> Component.setUnclosable( + 3 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -114,7 +92,7 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { ) ).also { stage++ } - 4 -> Component.setUnclosable( + 4 -> setUnclosable( player, interpreter.sendDialogues( npc, @@ -130,6 +108,11 @@ class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { setAttribute(player, "tutorial:stage", 3) TutorialStage.load(player, 3) } + 99 -> { + end() + val tutStage = player?.getAttribute("tutorial:stage", 0) ?: 0 + TutorialStage.load(player, tutStage) + } } return true } diff --git a/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java b/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java index 6d7b8a5b1..56845ac8b 100644 --- a/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java +++ b/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.game.world.map.Location; +import content.data.Quests; /** * Handles the tutorial rat npc. @@ -65,7 +66,7 @@ public class RatTutorialNPC extends AbstractNPC { } final Player p = ((Player) killer); if (killer instanceof Player) { - if (p.getQuestRepository().getQuest("Witch's Potion").isStarted(p)) { + if (p.getQuestRepository().getQuest(Quests.WITCHS_POTION).isStarted(p)) { GroundItemManager.create(new Item(300), getLocation(), p); } } diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialArea.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialArea.kt new file mode 100644 index 000000000..082da760b --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialArea.kt @@ -0,0 +1,10 @@ +package content.region.misc.tutisland.handlers + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class TutorialArea : MapArea { + override fun defineAreaBorders() : Array { return arrayOf(12079, 12080, 12335, 12336, 12436, 12592).map { ZoneBorders.forRegion(it) }.toTypedArray() } + override fun getRestrictions() : Array { return arrayOf(ZoneRestriction.RANDOM_EVENTS) } +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialDialogs.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialDialogs.kt new file mode 100644 index 000000000..78a493dcd --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialDialogs.kt @@ -0,0 +1,554 @@ +package content.region.misc.tutisland.handlers + +import core.api.getAttribute +import core.api.inInventory +import core.game.component.Component.setUnclosable +import core.game.event.DialogueCloseEvent +import core.game.event.EventHook +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.GameWorld.settings +import org.rs09.consts.Items +import kotlin.also + +fun sendStageDialog(player: Player, stage: Int) { + val message = when (stage) { + 0 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Getting started", + "To start the tutorial use your left mouse button to click on the", + "" + settings!!.name + " Guide in this room. He is indicated by a flashing", + "yellow arrow above his head. If you can't see him, use your", + "keyboard's arrow keys to rotate the view." + ) + 1 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "", + "Game options", + "Please click on the flashing spanner icon found at the bottom", + "right of your screen. This will display your game options." + ) + 2 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Game Options", + "In the interface, you can now see a variety of options such as", + "screen brightness, sound and music volume and whether you", + "want to accept aid from other player's or not. Don't worry", + "about these too much for now; they will become easier as you", + "explore the game. Talk to the " + settings!!.name + " Guide to continue." + ) + 3 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Interacting with scenery", + "You can interact with many items of scenery by simply clicking", + "on them. Right clicking will also give more options. Feel free to", + "try it with the things in this room, then click on the door", + "indicated with the yellow arrow to go though to the next", + "instructor." + ) + 4 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Moving around", + "Follow the path to find the next instructor. Clicking on the", + "ground will walk you to that point. You can also navigate by", + "clicking on the minimap in the top-right corner of your screen.", + "Talk to Survival Expert by the pond to continue the tutorial." + ) + 5 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Viewing the items that you were given.", + "Click on the flashing backpack icon to the right-hand side of", + "the main window to view your inventory. Your inventory is a list", + "of everything you have in your backpack.", + "" + ) + 6 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cut down a tree", + "You can click on the backpack icon at any time to view the", + "items that you currently have in your inventory. You will see", + "that you now have an axe in your inventory. Use this to get", + "some logs by clicking on one of the trees in the area." + ) + 7 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to cut down the tree. Sit back", + "for a moment while " + (if (player.appearance.isMale) "he" else "she") + " does all the hard work.", + "" + ) + 8 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Making a fire", + "Well done! You managed to cut some logs from the tree! Next,", + "use the tinderbox in your inventory to light the logs.", + "First click on the tinderbox to 'use' it.", + "Then click on the logs in your inventory to light them." + ) + 9 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to light the fire.", + "This should only take a few seconds.", + "" + ) + 10 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You gained some experience.", + "", + "Click on the flashing bar graph icon near the inventory button", + "to see your skill state.", + "" + ) + 11 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your skill stats", + "Here you will see how good your skills are. As you move your", + "mouse over any of the icons in this tab, the small yellow popup", + "box will show you the exact amount of experience you have", + "and how much is needed to get to the next level. Speak to the survival guide." + ) + 12 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Catch some shrimp", + "Click on the bubbling fishing spot, indicated by the flashing", + "arrow. Remember, you can check your inventory by clicking the", + "backpack icon.", + "" + ) + 13 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "This should only take a few seconds.", + "As you gain Fishing experience you'll find that there are many", + "types of fish and many ways to catch them." + ) + 14 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cooking your shrimp", + "Now you have caught some shrimp, let's cook it. First light a", + "fire: chop down a tree and then use the tinderbox on the logs.", + "If you've lost your axe or tinderbox Brynna will give you", + "another." + ).also { + if (!inInventory(player, Items.RAW_SHRIMPS_317, 1)) { + setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cooking your shrimp", + "Now right click on the shrimp and select the use option. Next,", + "left click on the fire you just lit. If while doing this you look in", + "the top left of the screen, you will see the instruction that", + "you're giving your character." + ) + ) + } + } + 15 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Burning your shrimp", + "You have just burnt your first shrimp. This is normal. As you", + "get more experience in Cooking you will burn stuff less often.", + "Let's try cooking without burning it this time. First catch some", + "more shrimp, then use them on a fire." + ) + 16 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Well done, you've just cooked your first " + settings!!.name + " meal.", + "If you'd like a recap on anything you've learnt so far, speak to", + "the Survival Expert. You can now move on to the next", + "instructor. Click on the gate shown and follow the path.", + "Remember, you can move the camera with the arrow keys." + ) + 17 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Find your next instructor", + "Follow the path until you get to the door with the yellow arrow", + "above it. Click on the door to open it. Notice the mini map in the", + "top right; this shows a top down view of the area around you.", + "This can also be used for navigation." + ) + 18 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Find your next instructor", + "Talk to the chef indicated. He will teach you the more advanced", + "aspects of Cooking such as combining ingredients. He will also", + "teach you about your Music Player.", + "" + ) + 19 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Making dough", + "This is the base for many of the meals. To make dough we must", + "mix flour and water. First, right click the bucket of water and", + "select use, then left click on the pot of flour.", + "" + ) + 20 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cooking dough", + "Now you have made dough, you can cook it. To cook the dough,", + "use it with the range shown by the arrow. If you lose your", + "dough, talk to Lev - he will give you more ingredients.", + "" + ) + 21 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Cooking dough", + "Well done! Your first loaf of bread. As you gain experience in", + "Cooking, you will be able to make other things like pies, cakes", + "and even kebabs. Now you've got the hang of cooking, let's", + "move on. Click on the flashing icon in the bottom right to see", + "the flashing icon in the bottom right to see the Music Player." + ) + 22 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "The Music Player", + "From this interface you can control the music that is played.", + "As you explore the world and complete quests, more of the", + "tunes will become unlocked. Once you've examined this menu,", + "use the next door to continue. If you need a recap on anything", + "you've learnt so far, speak to the Master Chef." + ) + 23 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Emotes", + "", + "Now how about showing some feelings? You will see a flashing", + "icon in the shape of a person. Click on that to access your", + "emotes." + ) + 24 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Emotes", + "For those situations where words don't quite describe how you feel try", + "an emote. Go ahead try one out! You might notice that some of the", + "emotes are grey and cannot be used now. Don't worry! As you", + "progress further into the game you'll gain access to all sorts of things." + ) + 25 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Running", + "", + "It's only a short distance to the next guide.", + "Why not try running there? To do this, click on the run icon", + "next to the minimap." + ) + 26 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Run to the next guide", + "Now that you have the run button turned on, follow the path", + "until you come to the end. You may notice that the number on", + "the button goes down. This is your run energy. If your run", + "energy reaches zero, you'll stop running. Click on the door to", + "pass through it." + ) + 27 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Talk with the Quest Guide.", + "", + "He will tell you all about quests.", + "", + "" + ) + 28 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your Quest Journal", + "", + "This is your Quest Journal, a list of all the quests in the game.", + "Talk to the Quest Guide again for an explanation.", + "" + ) + 29 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Moving on", + "It's time to enter some caves. Click on the ladder to go down to", + "the next area.", + "" + ) + 30 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Mining and Smithing", + "", + "Next let's get you a weapon, or more to the point, you can", + "make your first weapon yourself. Don't panic, the Mining", + "Instructor will help you. Talk to him and he'll tell you all about it." + ) + 31 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Prospecting", + "To prospect a mineable rock, just right click it and select the", + "'prospect rock' option. This will tell you the type of ore you can", + "mine from it. Try it now on one of the rocks indicated.", + "" + ) + 32 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to prospect the rock. This", + "should only take a few seconds.", + "" + ) + 33 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "It's tin.", + "", + "So now you know there's tin in the grey rocks, try prospecting the", + "brown ones next.", + "" + ) + 34 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "It's copper.", + "", + "Talk to the Mining Instructor to find out about these types of", + "ore and how you can mine them.", + "He'll even give you the required tools.", + ) + 35 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Mining", + "", + "It's quite simple really. All you need to do is right click on the", + "rock and select 'mine' You can only mine when you have a", + "pickaxe. So give it a try: first mine one tin ore.", + ) + 36 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to mine the rock.", + "This should only take a few seconds.", + "" + ) + 37 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Mining", + "", + "Now you have some tin ore you just need some copper ore,", + "then you'll have all you need to create a bronze bar. As you", + "did before right click on the copper rock and select 'mine'." + ) + 38 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Smelting", + "You should now have both some copper and tin ore. So let's", + "smelt them to make a bronze bar. To do this, right click on", + "either tin or copper ore and select use then left click on the", + "furnace. Try it now." + ) + 39, 40 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You've made a bronze bar!", + "", + "Speak to the Mining Instructor and he'll show you how to make", + "it into a weapon.", + "" + ) + 41 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Smithing a dagger", + "To smith you'll need a hammer - like the one you were given by", + "Dezzick - access to an anvil like the one with the arrow over it", + "and enough metal bars to make what you are trying to smith.", + "To start the process, use the bar on one of the anvils." + ) + 42 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Smithing a dagger.", + "Now you have the Smithing menu open, you will see a list of all", + "the things you can make. Only the dagger can be made at your", + "skill level; this is shown by the white text under it. You'll need", + "to select the dagger to continue." + ) + 43 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You've finished in this area.", + "", + "So let's move on. Go through the gates shown by the arrow.", + "Remember, you may need to move the camera to see your", + "surroundings. Speak to the guide for a recap at any time.", + ) + 44 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Combat", + "", + "In this area you will find out about combat with swords and", + "bows. Speak to the guide and he will tell you all about it.", + "" + ) + 45 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Wielding weapons", + "", + "You now have access to a new interface. Click on the flashing", + "icon of a man, the one to the right of your backpack icon.", + "" + ) + 46 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your worn inventory.", + "From here you can see what items you have equipped. Let's", + "get one of those slots filled, go back to your inventory and", + "right click your dagger, select wield from the menu.", + "" + ) + 47 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "You're now holding your dagger.", + "Clothes, armour, weapons and many other items are equipped", + "like this. You can unequip items by clicking on the item in the", + "worn equipment. You can close this window by clicking on the", + "small 'x' in the top-right hand corner. Speak to the Combat", + "Instructor." + ) + 48 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Unequipping items.", + "In your worn inventory panel, right click on the dagger and", + "select the remove option from the drop down list. After you've", + "unequipped the dagger, wield the sword and shield. As you", + "pass the mouse over an item you will see its name appear at", + "the top left of the screen." + ) + 49 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Combat interface.", + "", + "Click on the flashing crossed swords icon to see the combat", + "interface.", + "" + ) + 50 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "This is your combat interface.", + "From this interface you can select the type of attack your", + "character will use. Different monsters have different", + "weaknesses. If you hover your mouse over the buttons, you", + "will see the type of XP you will receive when using each type of", + "attack. Now you have the tools needed for battle why not slay", + "some rats. Click on the gates indicated to continue." + ) + 51 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Attacking", + "To attack the rat, click it and select the attack option. You", + "will then walk over to it and start hitting it.", + "", + "" + ) + 52 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Sit back and watch.", + "While you are fighting you will see a bar over your head. The", + "bar shows how much health you have left. Your opponent will", + "have one too. You will continue to attack the rat until it's dead", + "or you do something else." + ) + 53 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Well done, you've made your first kill!", + "", + "Pass through the gate and talk to the Combat Instructor; he", + "will give you your next task.", + "" + ) + 54 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Rat ranging", + "Now you have a bow and some arrows. Before you can use", + "them you'll need to equip them. Once equipped with the", + "ranging gear try killing another rat. Remember: to attack, right", + "click on the monster and select attack." + ) + 55 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Moving on.", + "You have completed the tasks here. To move on, click on the", + "ladder shown. If you need to go over any of what you learnt", + "here, just talk to the Combat Instructor and he'll tell you what", + "he can." + ) + 56 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Banking.", + "Follow the path and you will come to the front of a building.", + "This is the 'Bank of " + settings!!.name + "' where you can store all your", + "most valued items. To open your bank box just right click on an", + "open booth indicated and select 'use'." + ) + 57 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your bank box.", + "You can store stuff here for safekeeping. If you die, anything", + "in your bank will be saved. To deposit something, right click it", + "and select 'Deposit-1'. Once you've had a good look, close the", + "window and move on through the door indicated." + ) + 58 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Financial advice", + "", + "The guide here will tell you all about making cash. Just click on", + "him to hear what he's got to say.", + "" + ) + 59 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "", + "Continue through the next door.", + "", + "" + ) + 60 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Prayer", + "Follow the path to the chapel and enter it.", + "Once inside talk to the monk. He'll tell you all about the Prayer", + "skill.", + "" + ) + 61 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your Prayer List", + "", + "Click on the flashing icon to open the Prayer List.", + "", + "" + ) + 62 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Your Prayer List", + "", + "Talk with Brother Brace and he'll tell you all about prayers.", + "" + ) + 63 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Friends list", + "You should now see another new icon. Click on the flashing", + "smiling face to open your Friend List.", + "" + ) + 64 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your Friends List.", + "", + "This will be explained by Brother Brace shortly, but first click", + "on the other flashing face in the interface.", + "" + ) + 65 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your Ignore List.", + "The two lists, Friends and Ignore - can be very helpful for", + "keeping track of when your friends are online or for blocking", + "messages from people you simply don't like. Speak with", + "Brother Brace and he will tell you more." + ) + 66 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Your final instructor!", + "You're almost finished on tutorial island. Pass through the", + "door to find the path leading to your final instructor.", + "" + ) + 67 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your final instructor!", + "Just follow the path to the Wizard's house, where you will be", + "shown how to cast spells. Just talk with the mage indicated to", + "find out more.", + "" + ) + 68 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Open up your final tab.", + "", + "Open up the Magic Spellbook tab by clicking on the flashing", + "icon next to the Prayer List tab you just learned about.", + "" + ) + 69 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "This is your spell list.", + "", + "Ask the mage about it.", + "" + ) + 70 -> player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Cast Wind Strike at a chicken.", + "Now you have the runes you should see the Wind Strike icon at the", + "top-left of your spellbook, second in from the left. Walk over", + "to the caged chickens, click the Wind Strike icon and then", + "select one of the chickens to cast it on. It may take several", + "tries." + ) + 71 -> player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You have almost completed the tutorial!", + "", + "All you need to do now is teleport to the mainland. Just speak", + "with Terrova and he'll tell you how to do that.", + "" + ) + else -> null + } + setUnclosable(player, message ?: return) +} + +fun sendStageDialog(entity: Entity) { + val player = entity as Player + val stage = getAttribute(player, "tutorial:stage", 0) + sendStageDialog(player, stage) +} + +// Because we don't have proper interface stacking, the above unclosable dialogs can still be closed, if a new dialog +// opens up over it and that dialog *is* closable. This is the case for npc dialogs and the smelting interface. Fake the +// authentic behavior by making sure we reopen our unclosable dialog when this happens. +object TutorialDialogPreserver : EventHook { + override fun process(entity: Entity, event: DialogueCloseEvent) { + sendStageDialog(entity) + } +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt index 655c16d1c..c65191bb1 100644 --- a/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt @@ -7,13 +7,30 @@ import core.game.node.entity.player.Player import content.global.skill.fishing.FishingSpot import content.global.skill.gather.mining.MiningNode import content.global.skill.gather.woodcutting.WoodcuttingNode +import core.api.animate +import core.api.delayScript +import core.api.forceWalk +import core.api.inInventory +import core.api.lock +import core.api.lockInteractions +import core.api.playAudio +import core.api.queueScript +import core.api.replaceSlot +import core.api.stopExecuting import core.game.event.* +import core.game.interaction.QueueStrength +import core.game.node.entity.impl.Animator +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds /** * Event receivers for tutorial island - * @author Ceikry + * @author Ceikry, Player Name */ object TutorialButtonReceiver : EventHook { @@ -77,7 +94,7 @@ object TutorialButtonReceiver : EventHook } //Open equipment tab SD:548,42 HD:746,45 - 45 -> if((event.iface == 548 && event.buttonId == 42) || (event.iface == 746 && event.buttonId == 45)){ + 45, 46 -> if((event.iface == 548 && event.buttonId == 42) || (event.iface == 746 && event.buttonId == 45)){ setAttribute(entity, "tutorial:stage", 46) TutorialStage.load(entity, 46) } @@ -136,18 +153,6 @@ object TutorialInteractionReceiver : EventHook TutorialStage.load(entity, 13) } - //Prospect rock - Tin - 31 -> if(MiningNode.forId(event.target.id)?.identifier?.equals(2.toByte()) == true && event.option == "prospect"){ - setAttribute(entity, "tutorial:stage", 32) - TutorialStage.load(entity, 32) - } - - //Prospect rock- Copper - 33 -> if(MiningNode.forId(event.target.id)?.identifier?.equals(1.toByte()) == true && event.option == "prospect"){ - setAttribute(entity, "tutorial:stage", 34) - TutorialStage.load(entity, 34) - } - //Mine rock - Tin 35 -> if(MiningNode.forId(event.target.id)?.identifier?.equals(2.toByte()) == true && event.option == "mine"){ setAttribute(entity, "tutorial:stage", 36) @@ -211,30 +216,12 @@ object TutorialResourceReceiver : EventHook TutorialStage.load(entity, 14) } - //Cook a shrimp - 14,15 -> if(event.itemId == Items.BURNT_SHRIMP_7954) - { - setAttribute(entity, "tutorial:stage", 15) - TutorialStage.load(entity, 15) - } - else if(event.itemId == Items.SHRIMPS_315) - { - setAttribute(entity, "tutorial:stage", 16) - TutorialStage.load(entity, 16) - } - //Make some bread dough 19 -> if(event.itemId == Items.BREAD_DOUGH_2307) { setAttribute(entity, "tutorial:stage", 20) TutorialStage.load(entity, 20) } - //Bake some bread - 20 -> if(event.itemId == Items.BREAD_2309 || event.itemId == Items.BURNT_BREAD_2311) { - setAttribute(entity, "tutorial:stage", 21) - TutorialStage.load(entity, 21) - } - //Mine some tin ore 36 -> if(event.itemId == Items.TIN_ORE_438){ setAttribute(entity, "tutorial:stage", 37) diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialFurnaceListener.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialFurnaceListener.kt deleted file mode 100644 index c4139d6f5..000000000 --- a/Server/src/main/content/region/misc/tutisland/handlers/TutorialFurnaceListener.kt +++ /dev/null @@ -1,50 +0,0 @@ -package content.region.misc.tutisland.handlers - -import core.api.* -import core.game.event.ResourceProducedEvent -import core.game.node.entity.skill.Skills -import content.global.skill.smithing.smelting.Bar -import core.game.system.task.Pulse -import core.game.world.update.flag.context.Animation -import org.rs09.consts.Items -import org.rs09.consts.Scenery -import core.game.interaction.IntType -import core.game.interaction.InteractionListener - -/** - * Listener for tutorial island furnace - * @author Byte - */ -class TutorialFurnaceListener : InteractionListener { - - companion object { - private val ANIMATION = Animation(833) - - private val ORES = intArrayOf( - Items.TIN_ORE_438, - Items.COPPER_ORE_436 - ) - } - - override fun defineListeners() { - onUseWith(IntType.SCENERY, ORES, Scenery.FURNACE_3044) { player, _, _ -> - if (!inInventory(player, Items.TIN_ORE_438) || !inInventory(player, Items.COPPER_ORE_436)) { - return@onUseWith true - } - - animate(player, ANIMATION) - submitIndividualPulse(player, object: Pulse(2) { - override fun pulse(): Boolean { - removeItem(player, Items.TIN_ORE_438) - removeItem(player, Items.COPPER_ORE_436) - addItem(player, Items.BRONZE_BAR_2349) - rewardXP(player, Skills.SMITHING, Bar.BRONZE.experience) - player.dispatch(ResourceProducedEvent(Items.BRONZE_BAR_2349, 1, player, Items.COPPER_ORE_436)) - return true - } - }) - - return@onUseWith true - } - } -} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt index c7dd26f50..5a143acfb 100644 --- a/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt @@ -1,13 +1,25 @@ package content.region.misc.tutisland.handlers +import content.global.skill.smithing.smelting.Bar +import content.region.misc.tutisland.dialogue.RatPenDialogue import core.api.* +import core.game.event.ResourceProducedEvent import core.game.node.scenery.Scenery import core.game.system.task.Pulse import core.game.world.map.Location import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType +import core.game.interaction.QueueStrength +import core.game.node.entity.impl.Animator +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item import core.game.world.repository.Repository +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Sounds /** * Handles tutorial-specific node interactions @@ -16,10 +28,13 @@ import core.game.world.repository.Repository class TutorialListeners : InteractionListener { val GUIDE_HOUSE_DOOR = 3014 val COOKS_DOOR = 3017 + val RANGE = 3039 val COOKS_EXIT = 3018 val QUEST_ENTER = 3019 val QUEST_LADDER = 3029 val QUEST_EXIT_LADDER = 3028 + val TIN_ROCK = 3043 + val COPPER_ROCK = 3042 val COMBAT_EXIT = 3030 val BANK_EXIT = 3024 val FINANCE_EXIT = 3025 @@ -27,6 +42,7 @@ class TutorialListeners : InteractionListener { val FIRST_GATE = intArrayOf(3015,3016) val COMBAT_GATES = intArrayOf(3020,3021) val RAT_GATES = intArrayOf(3022, 3023) + val FURNACE = 3044 override fun defineListeners() { on(GUIDE_HOUSE_DOOR, IntType.SCENERY, "open"){ player, door -> @@ -60,6 +76,36 @@ class TutorialListeners : InteractionListener { return@on true } + fun cookBread(player: Player, dough: Item): Boolean { + if (getAttribute(player, "tutorial:stage", 0) < 20) { + return true + } + // Need to reinvent the wheel of cooking. Yes, I do. On tutorial island, we don't want the default stuff like asking the player what dough they want to make. + queueScript(player, 0, QueueStrength.WEAK) { stage -> + if (stage == 0) { + val RANGE_ANIMATION = Animation(883, Animator.Priority.HIGH) + lock(player, RANGE_ANIMATION.duration) + lockInteractions(player, RANGE_ANIMATION.duration) + animate(player, RANGE_ANIMATION) + playAudio(player, Sounds.FRY_2577) + return@queueScript delayScript(player, RANGE_ANIMATION.duration) + } else { + replaceSlot(player, dough.slot, Item(Items.BREAD_2309), dough) + setAttribute(player, "tutorial:stage", 21) + TutorialStage.load(player, 21) + return@queueScript stopExecuting(player) + } + } + return true + } + on(RANGE, IntType.SCENERY, "use") { player, _ -> + val dough = player.inventory.get(Item(Items.BREAD_DOUGH_2307)) ?: return@on true + return@on cookBread(player, dough) + } + onUseWith(IntType.SCENERY, Items.BREAD_DOUGH_2307, RANGE) { player, dough, _ -> + return@onUseWith cookBread(player, dough as Item) + } + on(COOKS_EXIT, IntType.SCENERY, "open"){ player, door -> if(getAttribute(player, "tutorial:stage", 0) != 22) return@on true @@ -105,23 +151,41 @@ class TutorialListeners : InteractionListener { return@on true } - on(COMBAT_GATES, IntType.SCENERY, "open"){ player, gate -> - if(getAttribute(player, "tutorial:stage", 0) != 43) + on(TIN_ROCK, IntType.SCENERY, "prospect") { player, _ -> + if (getAttribute(player, "tutorial:stage", 0) != 31) { return@on true + } + setAttribute(player, "tutorial:stage", 32) + TutorialStage.load(player, 32) + return@on true + } + on(COPPER_ROCK, IntType.SCENERY, "prospect") { player, _ -> + if (getAttribute(player, "tutorial:stage", 0) != 33) { + return@on true + } + setAttribute(player, "tutorial:stage", 34) + TutorialStage.load(player, 34) + return@on true + } - setAttribute(player, "tutorial:stage", 44) - TutorialStage.load(player, 44) + on(COMBAT_GATES, IntType.SCENERY, "open"){ player, gate -> + if (getAttribute(player, "tutorial:stage", 0) < 43) { + return@on true + } + if (getAttribute(player, "tutorial:stage", 0) == 43) { + setAttribute(player, "tutorial:stage", 44) + TutorialStage.load(player, 44) + } core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, gate as Scenery) } on(RAT_GATES, IntType.SCENERY, "open") { player, gate -> val stage = getAttribute(player, "tutorial:stage", 0) - if(stage !in 50..53){ - player.dialogueInterpreter.sendDialogues(NPCs.COMBAT_INSTRUCTOR_944, core.game.dialogue.FacialExpression.ANGRY, "Oi, get away from there!","Don't enter my rat pen unless I say so!") + if (stage !in 50..53) { + openDialogue(player, RatPenDialogue(), NPC(NPCs.COMBAT_INSTRUCTOR_944)) return@on true } - - if(stage == 50) { + if (stage == 50) { setAttribute(player, "tutorial:stage", 51) TutorialStage.load(player, 51) } @@ -130,11 +194,14 @@ class TutorialListeners : InteractionListener { } on(COMBAT_EXIT, IntType.SCENERY, "climb-up") { player, ladder -> - if(getAttribute(player, "tutorial:stage", 0) != 55) + val stage = getAttribute(player, "tutorial:stage", 0) + if (stage < 55) { return@on true - - setAttribute(player, "tutorial:stage", 56) - TutorialStage.load(player, 56) + } + if (stage == 55) { + setAttribute(player, "tutorial:stage", 56) + TutorialStage.load(player, 56) + } core.game.global.action.ClimbActionHandler.climbLadder(player, ladder.asScenery(), "climb-up") } @@ -165,5 +232,28 @@ class TutorialListeners : InteractionListener { core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) } + fun smeltBronzeBar(player: Player): Boolean { + if (getAttribute(player, "tutorial:stage", 0) < 38) { + return true + } + if (!inInventory(player, Items.COPPER_ORE_436) || !inInventory(player, Items.TIN_ORE_438)) { + return true + } + animate(player, 833) + queueScript(player, 2, QueueStrength.WEAK) { + if (removeItem(player, Items.COPPER_ORE_436) && removeItem(player, Items.TIN_ORE_438)) { + addItem(player, Items.BRONZE_BAR_2349) + rewardXP(player, Skills.SMITHING, Bar.BRONZE.experience) + player.dispatch(ResourceProducedEvent(Items.BRONZE_BAR_2349, 1, player, Items.COPPER_ORE_436)) + TutorialStage.load(player, 39) + } + return@queueScript stopExecuting(player) + } + return true + } + on(FURNACE, IntType.SCENERY, "use") { player, _ -> smeltBronzeBar(player) } + for (item in arrayOf(Items.COPPER_ORE_436, Items.TIN_ORE_438)) { + onUseWith(IntType.SCENERY, item, FURNACE) { player, _, _ -> smeltBronzeBar(player) } + } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt index 0fafa1c84..50eeddb00 100644 --- a/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt @@ -12,13 +12,13 @@ import core.game.world.map.Location import org.rs09.consts.Components import core.api.Event import core.game.world.GameWorld.Pulser -import core.game.world.GameWorld.settings import core.game.world.repository.Repository -import org.rs09.consts.Items +import org.rs09.consts.NPCs /** * Loads stage-relevant tutorial data * @author Ceikry + * @author Player Name */ object TutorialStage { /** @@ -26,28 +26,30 @@ object TutorialStage { * @param player the player to perform the actions on * @param stage the stage to load */ - fun load(player: Player, stage: Int, login: Boolean = false){ - if(login) - { + fun load(player: Player, stage: Int, login: Boolean = false) { + if (login) { player.hook(Event.ButtonClicked, TutorialButtonReceiver) player.hook(Event.Interacted, TutorialInteractionReceiver) player.hook(Event.ResourceProduced, TutorialResourceReceiver) player.hook(Event.UsedWith, TutorialUseWithReceiver) player.hook(Event.FireLit, TutorialFireReceiver) player.hook(Event.NPCKilled, TutorialKillReceiver) + player.hook(Event.DialogueClosed, TutorialDialogPreserver) openOverlay(player, Components.TUTORIAL_PROGRESS_371) player.packetDispatch.sendInterfaceConfig(371, 4, true) } - updateProgressBar(player) - when(stage) - { + when(stage) { 0 -> { lock(player, 10) teleport(player, Location.create(3094, 3107, 0)) hideTabs(player, login) CharacterDesign.open(player) + // We have two dialogs in this stage. This is awkward, but not a problem. + // The first dialog is impossible to close in any way, so we can send it here manually. + // The second dialog could be lost by e.g. talking to an npc, so this dialog gets implemented in + // TutorialDialogs.kt, which has the hook for restoring it if it does get lost. Component.setUnclosable( player, player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( @@ -59,380 +61,133 @@ object TutorialStage { ) ).also { runTask(player, 10) { - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Getting started", - "To start the tutorial use your left mouse button to click on the", - "" + settings!!.name + " Guide in this room. He is indicated by a flashing", - "yellow arrow above his head. If you can't see him, use your", - "keyboard's arrow keys to rotate the view." - ) - ) + sendStageDialog(player, stage) } } } - - 1 -> { hideTabs(player, login) player.interfaceManager.openTab(Component(Components.OPTIONS_261)) setVarbit(player, 3756, 12) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "", - "Game options", - "Please click on the flashing spanner icon found at the bottom", - "right of your screen. This will display your game options." - ) - ) + sendStageDialog(player, stage) } - 2 -> { setVarbit(player, 3756, 0) hideTabs(player, login) - registerHintIcon(player, Repository.findNPC(945)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "Game Options", - "In the interface, you can now see a variety of options such as", - "screen brightness, sound and music volume and whether you", - "want to accept aid from other player's or not. Don't worry", - "about these too much for now; they will become easier as you", - "explore the game. Talk to the " + settings!!.name + " Guide to continue." - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.RUNESCAPE_GUIDE_945)!!) + sendStageDialog(player, stage) } - 3 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3098, 3107, 0), 125) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "Interacting with scenery", - "You can interact with many items of scenery by simply clicking", - "on them. Right clicking will also give more options. Feel free to", - "try it with the things in this room, then click on the door", - "indicated with the yellow arrow to go though to the next", - "instructor." - ) - ) + sendStageDialog(player, stage) } - 4 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(943)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Moving around", - "Follow the path to find the next instructor. Clicking on the", - "ground will walk you to that point. You can also navigate by", - "clicking on the minimap in the top-right corner of your screen.", - "Talk to Survival Expert by the pond to continue the tutorial." - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.SURVIVAL_EXPERT_943)!!) + sendStageDialog(player, stage) } - 5 -> { hideTabs(player, login) player.interfaceManager.openTab(Component(Components.INVENTORY_149)) setVarbit(player, 3756, 4) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Viewing the items that you were given.", - "Click on the flashing backpack icon to the right-hand side of", - "the main window to view your inventory. Your inventory is a list", - "of everything you have in your backpack.", - "" - ) - ) + sendStageDialog(player, stage) } - 6 -> { hideTabs(player, login) setVarbit(player, 3756, 4) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Cut down a tree", - "You can click on the backpack icon at any time to view the", - "items that you currently have in your inventory. You will see", - "that you now have an axe in your inventory. Use this to get", - "some logs by clicking on one of the trees in the area." - ) - ) + sendStageDialog(player, stage) } - 7 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Please wait.", - "", - "Your character is now attempting to cut down the tree. Sit back", - "for a moment while " + (if (player.appearance.isMale) "he" else "she") + " does all the hard work.", - "" - ) - ) + sendStageDialog(player, stage) } - 8 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Making a fire", - "Well done! You managed to cut some logs from the tree! Next,", - "use the tinderbox in your inventory to light the logs.", - "First click on the tinderbox to 'use' it.", - "Then click on the logs in your inventory to light them." - ) - ) + sendStageDialog(player, stage) } - 9 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Please wait.", - "", - "Your character is now attempting to light the fire.", - "This should only take a few seconds.", - "" - ) - ) + sendStageDialog(player, stage) } - 10 -> { hideTabs(player, login) player.interfaceManager.openTab(Component(Components.STATS_320)) setVarbit(player, 3756, 2) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "You gained some experience.", - "", - "Click on the flashing bar graph icon near the inventory button", - "to see your skill state.", - "" - ) - ) + sendStageDialog(player, stage) } - 11 -> { hideTabs(player, login) setVarbit(player, 3756, 2) - registerHintIcon(player, Repository.findNPC(943)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Your skill stats", - "Here you will see how good your skills are. As you move your", - "mouse over any of the icons in this tab, the small yellow popup", - "box will show you the exact amount of experience you have", - "and how much is needed to get to the next level. Speak to the survival guide." - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.SURVIVAL_EXPERT_943)!!) + sendStageDialog(player, stage) } - 12 -> { hideTabs(player, login) setVarp(player, 406, 2) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(952)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Catch some shrimp", - "Click on the bubbling fishing spot, indicated by the flashing", - "arrow. Remember, you can check your inventory by clicking the", - "backpack icon.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.FISHING_SPOT_952)!!) + sendStageDialog(player, stage) } - 13 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Please wait.", - "", - "This should only take a few seconds.", - "As you gain Fishing experience you'll find that there are many", - "types of fish and many ways to catch them." - ) - ) + sendStageDialog(player, stage) } - 14 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Cooking your shrimp", - "Now you have caught some shrimp, let's cook it. First light a", - "fire: chop down a tree and then use the tinderbox on the logs.", - "If you've lost your axe or tinderbox Brynna will give you", - "another." - ).also { - if (!inInventory(player, Items.RAW_SHRIMPS_317, 1)) { - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Cooking your shrimp", - "Now right click on the shrimp and select the use option. Next,", - "left click on the fire you just lit. If while doing this you look in", - "the top left of the screen, you will see the instruction that", - "you're giving your character." - ) - ) - } - } - ) + sendStageDialog(player, stage) } - 15 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Burning your shrimp", - "You have just burnt your first shrimp. This is normal. As you", - "get more experience in Cooking you will burn stuff less often.", - "Let's try cooking without burning it this time. First catch some", - "more shrimp, then use them on a fire." - ) - ) + sendStageDialog(player, stage) } - 16 -> { hideTabs(player, login) + removeHintIcon(player) registerHintIcon(player, Location.create(3089, 3091, 0), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Well done, you've just cooked your first " + settings!!.name + " meal.", - "If you'd like a recap on anything you've learnt so far, speak to", - "the Survival Expert. You can now move on to the next", - "instructor. Click on the gate shown and follow the path.", - "Remember, you can move the camera with the arrow keys." - ) - ) + sendStageDialog(player, stage) } - 17 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Location.create(3078, 3084, 0), 125) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Find your next instructor", - "Follow the path until you get to the door with the yellow arrow", - "above it. Click on the door to open it. Notice the mini map in the", - "top right; this shows a top down view of the area around you.", - "This can also be used for navigation." - ) - ) + registerHintIcon(player, Location.create(3079, 3084, 0), 125) + sendStageDialog(player, stage) } - 18 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(942)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Find your next instructor", - "Talk to the chef indicated. He will teach you the more advanced", - "aspects of Cooking such as combining ingredients. He will also", - "teach you about your Music Player.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.MASTER_CHEF_942)!!) + sendStageDialog(player, stage) } - 19 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Making dough", - "This is the base for many of the meals. To make dough we must", - "mix flour and water. First, right click the bucket of water and", - "select use, then left click on the pot of flour.", - "" - ) - ) + sendStageDialog(player, stage) } - 20 -> { hideTabs(player, login) registerHintIcon(player, Location.create(3076, 3081, 0), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Cooking dough", - "Now you have made dough, you can cook it. To cook the dough,", - "use it with the range shown by the arrow. If you lose your", - "dough, talk to Lev - he will give you more ingredients.", - "" - ) - ) + sendStageDialog(player, stage) } - 21 -> { hideTabs(player, login) removeHintIcon(player) player.interfaceManager.openTab(Component(Components.MUSIC_V3_187)) setVarbit(player, 3756, 14) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "Cooking dough", - "Well done! Your first loaf of bread. As you gain experience in", - "Cooking, you will be able to make other things like pies, cakes", - "and even kebabs. Now you've got the hang of cooking, let's", - "move on. Click on the flashing icon in the bottom right to see", - "the flashing icon in the bottom right to see the Music Player." - ) - ) + sendStageDialog(player, stage) } - 22 -> { hideTabs(player, login) setVarbit(player, 3756, 0) - registerHintIcon(player, Location.create(3072, 3090, 0), 125) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "The Music Player", - "From this interface you can control the music that is played.", - "As you explore the world and complete quests, more of the", - "tunes will become unlocked. Once you've examined this menu,", - "use the next door to continue. If you need a recap on anything", - "you've learnt so far, speak to the Master Chef." - ) - ) + registerHintIcon(player, Location.create(3073, 3090, 0), 125) + sendStageDialog(player, stage) } - 23 -> { hideTabs(player, login) setVarbit(player, 3756, 13) @@ -440,159 +195,59 @@ object TutorialStage { player.interfaceManager.openTab(Component(Components.EMOTES_464)) stopWalk(player) player.locks.lockMovement(100000) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Emotes", - "", - "Now how about showing some feelings? You will see a flashing", - "icon in the shape of a person. Click on that to access your", - "emotes." - ) - ) + sendStageDialog(player, stage) } - 24 -> { hideTabs(player, login) setVarbit(player, 3756, 0) player.locks.lockMovement(100000) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Emotes", - "For those situations where words don't quite describe how you feel try", - "an emote. Go ahead try one out! You might notice that some of the", - "emotes are grey and cannot be used now. Don't worry! As you", - "progress further into the game you'll gain access to all sorts of things." - ) - ) + sendStageDialog(player, stage) } - 25 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Running", - "", - "It's only a short distance to the next guide.", - "Why not try running there? To do this, click on the run icon", - "next to the minimap." - ) - ) + sendStageDialog(player, stage) } - 26 -> { hideTabs(player, login) - registerHintIcon(player, Repository.findNPC(949)!!) + registerHintIcon(player, Repository.findNPC(NPCs.QUEST_GUIDE_949)!!) player.locks.unlockMovement() - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "Run to the next guide", - "Now that you have the run button turned on, follow the path", - "until you come to the end. You may notice that the number on", - "the button goes down. This is your run energy. If your run", - "energy reaches zero, you'll stop running. Click on the door to", - "pass through it." - ) - ) + sendStageDialog(player, stage) } - 27 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(949)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Talk with the Quest Guide.", - "", - "He will tell you all about quests.", - "", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.QUEST_GUIDE_949)!!) + sendStageDialog(player, stage) } - 28 -> { hideTabs(player, login) setVarbit(player, 3756, 0) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Your Quest Journal", - "", - "This is your Quest Journal, a list of all the quests in the game.", - "Talk to the Quest Guide again for an explanation.", - "" - ) - ) + sendStageDialog(player, stage) } - 29 -> { hideTabs(player, login) removeHintIcon(player) setVarbit(player, 3756, 0) registerHintIcon(player, Location.create(3088, 3119, 0), 15) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "Moving on", - "It's time to enter some caves. Click on the ladder to go down to", - "the next area.", - "" - ) - ) + sendStageDialog(player, stage) } - 30 -> { hideTabs(player, login) removeHintIcon(player) setVarbit(player, 3756, 0) - registerHintIcon(player, Repository.findNPC(948)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Mining and Smithing", - "", - "Next let's get you a weapon, or more to the point, you can", - "make your first weapon yourself. Don't panic, the Mining", - "Instructor will help you. Talk to him and he'll tell you all about it." - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.MINING_INSTRUCTOR_948)!!) + sendStageDialog(player, stage) } - 31 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3076, 9504, 0), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Prospecting", - "To prospect a mineable rock, just right click it and select the", - "'prospect rock' option. This will tell you the type of ore you can", - " mine from it. Try it now on one of the rocks indicated.", - "" - ) - ) + sendStageDialog(player, stage) } - 32 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Please wait.", - "", - "Your character is now attempting to prospect the rock. This", - "should only take a few seconds.", - "" - ) - ) + sendStageDialog(player, stage) Pulser.submit(object : Pulse(3) { override fun pulse(): Boolean { setAttribute(player, "tutorial:stage", 33) @@ -601,196 +256,79 @@ object TutorialStage { } }) } - 33 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3086, 9501, 0), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "It's tin.", - "", - "So now you know there's tin in the grey rocks, try prospecting the", - "brown ones next.", - "" - ) - ) + sendStageDialog(player, stage) } - 34 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(948)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "It's copper.", - "", - "Talk to the Mining Instructor to find out about these types of", - "ore and how you can mine them.", - "He'll even give you the required tools.", - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.MINING_INSTRUCTOR_948)!!) + sendStageDialog(player, stage) } - 35 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3076, 9504), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Mining", - "", - "It's quite simple really. All you need to do is right click on the", - "rock and select 'mine' You can only mine when you have a", - "pickaxe. So give it a try: first mine one tin ore.", - ) - ) + sendStageDialog(player, stage) } - 36 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Please wait.", - "", - "Your character is now attempting to mine the rock.", - "This should only take a few seconds.", - "" - ) - ) + sendStageDialog(player, stage) } - 37 -> { hideTabs(player, login) registerHintIcon(player, Location.create(3086, 9501), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Mining", - "", - "Now you have some tin ore you just need some copper ore,", - "then you'll have all you need to create a bronze bar. As you", - "did before right click on the copper rock and select 'mine'." - ) - ) + sendStageDialog(player, stage) } - 38 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3079, 9496), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Smelting", - "You should now have both some copper and tin ore. So let's", - "smelt them to make a bronze bar. To do this, right click on", - "either tin or copper ore and select use then left click on the", - "furnace. Try it now." - ) - ) + sendStageDialog(player, stage) + } + 39 -> { + sendStageDialog(player, stage) } - - //39 -> {} - 40 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(948)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "You've made a bronze bar!", - "", - "Speak to the Mining Instructor and he'll show you how to make", - "it into a weapon.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.MINING_INSTRUCTOR_948)!!) + sendStageDialog(player, stage) } - 41 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3083, 9499), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Smithing a dagger", - "To smith you'll need a hammer - like the one you were given by", - "Dezzick - access to an anvil like the one with the arrow over it", - "and enough metal bars to make what you are trying to smith.", - "To start the process, use the bar on one of the anvils." - ) - ) + sendStageDialog(player, stage) } - 42 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Smithing a dagger.", - "Now you have the Smithing menu open, you will see a list of all", - "the things you can make. Only the dagger can be made at your", - "skill level; this is shown by the white text under it. You'll need", - "to select the dagger to continue." - ) - ) + sendStageDialog(player, stage) } - 43 -> { hideTabs(player, login) registerHintIcon(player, Location.create(3095, 9502), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "You've finished in this area.", - "", - "So let's move on. Go through the gates shown by the arrow.", - "Remember, you may need to move the camera to see your", - "surroundings. Speak to the guide for a recap at any time.", - ) - ) + sendStageDialog(player, stage) } - 44 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(944)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Combat", - "", - "In this area you will find out about combat with swords and", - "bows. Speak to the guide and he will tell you all about it.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.COMBAT_INSTRUCTOR_944)!!) + sendStageDialog(player, stage) } - 45 -> { hideTabs(player, login) removeHintIcon(player) runTask(player, 10) { - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Wielding weapons", - "", - "You now have access to a new interface. Click on the flashing", - "icon of a man, the one to the right of your backpack icon.", - "" - ) - ) + // this part needs sendStageDialog because you could just be logging in here + sendStageDialog(player, stage) }.also { + // for this part, you are locked into the interface so we don't need sendStageDialog here hideTabs(player, login) removeHintIcon(player) player.interfaceManager.openTab(Component(Components.WORNITEMS_387)) @@ -807,429 +345,174 @@ object TutorialStage { ) } } - 46 -> { hideTabs(player, login) setVarbit(player, 3756, 0) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "This is your worn equipment.", - "From here you can see what items you have equipped. You will", - "notice the button 'Show Equipment Stats'. Click on this now to", - "display the details of what you have equipped.", - "" - ) - ) + sendStageDialog(player, stage) } - 47 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "You're now holding your dagger.", - "Clothes, armour, weapons and many other items are equipped", - "like this. You can unequip items by clicking on the item in the", - "worn equipment. You can close this window by clicking on the", - "small 'x' in the top-right hand corner. Speak to the Combat", - "Instructor." - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.COMBAT_INSTRUCTOR_944)!!) + sendStageDialog(player, stage) } - 48 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "Unequipping items.", - "In your worn inventory panel, right click on the dagger and", - "select the remove option from the drop down list. After you've", - "unequipped the dagger, wield the sword and shield. As you", - "pass the mouse over an item you will see its name appear at", - "the top left of the screen." - ) - ) + sendStageDialog(player, stage) } - 49 -> { hideTabs(player, login) setVarbit(player, 3756, 1) var wepInter = player.getExtension(WeaponInterface::class.java) - if(wepInter == null) - { + if (wepInter == null) { wepInter = WeaponInterface(player) player.addExtension(WeaponInterface::class.java, wepInter) } player.interfaceManager.openTab(wepInter) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Combat interface.", - "", - "Click on the flashing crossed swords icon to see the combat", - "interface.", - "" - ) - ) + sendStageDialog(player, stage) } - 50 -> { hideTabs(player, login) setVarbit(player, 3756, 0) - registerHintIcon(player, Location.create(3110,9518,0), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "This is your combat interface.", - "From this interface you can select the type of attack your", - "character will use. Different monsters have different", - "weaknesses. If you hover your mouse over the buttons, you", - "will see the type of XP you will receive when using each type of", - "attack. Now you have the tools needed for battle why not slay", - "some rats. Click on the gates indicated to continue." - ) - ) + registerHintIcon(player, Location.create(3111,9518,0), 75) + sendStageDialog(player, stage) } - 51 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Attacking", - "To attack the rat, click it and select the attack option. You", - "will then walk over to it and start hitting it.", - "", - "" - ) - ) + //FIXME: add a hint arrow over the rat closest to you that is not in combat with somebody else. https://www.youtube.com/watch?v=FGQ2BZrJIug. The below should work but doesn't. + registerHintIcon(player, Repository.findNPC(NPCs.GIANT_RAT_86)!!) + sendStageDialog(player, stage) } - 52 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Sit back and watch.", - "While you are fighting you will see a bar over your head. The", - "bar shows how much health you have left. Your opponent will", - "have one too. You will continue to attack the rat until it's dead", - "or you do something else." - ) - ) + //FIXME: add a hint arrow over the rat you're in combat with (also in the ranging part btw). https://www.youtube.com/watch?v=FGQ2BZrJIug + sendStageDialog(player, stage) } - 53 -> { hideTabs(player, login) removeHintIcon(player) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Well done, you've made your first kill!", - "", - "Pass through the gate and talk to the Combat Instructor; he", - "will give you your next task.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.COMBAT_INSTRUCTOR_944)!!) + sendStageDialog(player, stage) } - 54 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Rat ranging", - "Now you have a bow and some arrows. Before you can use", - "them you'll need to equip them. Once equipped with the", - "ranging gear try killing another rat. Remember: to attack, right", - "click on the monster and select attack." - ) - ) + sendStageDialog(player, stage) } - 55 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3111,9526), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Moving on.", - "You have completed the tasks here. To move on, click on the", - "ladder shown. If you need to go over any of what you learnt", - "here, just talk to the Combat Instructor and he'll tell you what", - "he can." - ) - ) + sendStageDialog(player, stage) } - 56 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3122,3124), 50) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Banking.", - "Follow the path and you will come to the front of a building.", - "This is the 'Bank of " + settings!!.name + "' where you can store all your", - "most valued items. To open your bank box just right click on an", - "open booth indicated and select 'use'." - ) - ) + sendStageDialog(player, stage) } - 57 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3125, 3124), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "This is your bank box.", - "You can store stuff here for safekeeping. If you die, anything", - "in your bank will be saved. To deposit something, right click it", - "and select 'Deposit-1'. Once you've had a good look, close the", - "window and move on through the door indicated." - ) - ) + sendStageDialog(player, stage) } - 58 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(947)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Financial advice", - "", - "The guide here will tell you all about making cash. Just click on", - "him to hear what he's got to say.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.FINANCIAL_ADVISOR_947)!!) + sendStageDialog(player, stage) } - 59 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3130, 3124, 0), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "", - "Continue through the next door.", - "", - "" - ) - ) + sendStageDialog(player, stage) } - 60 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(954)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Prayer", - "Follow the path to the chapel and enter it.", - "Once inside talk to the monk. He'll tell you all about the Prayer", - "skill.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.BROTHER_BRACE_954)!!) + sendStageDialog(player, stage) } - 61 -> { hideTabs(player, login) removeHintIcon(player) player.interfaceManager.openTab(Component(Components.PRAYER_271)) setVarbit(player, 3756, 6) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Your Prayer List", - "", - "Click on the flashing icon to open the Prayer List.", - "", - "" - ) - ) + sendStageDialog(player, stage) } - 62 -> { hideTabs(player, login) - registerHintIcon(player, Repository.findNPC(954)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "Your Prayer List", - "", - "Talk with Brother Brace and he'll tell you all about prayers.", - "" - ) - ) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(NPCs.BROTHER_BRACE_954)!!) + sendStageDialog(player, stage) } - 63 -> { hideTabs(player, login) removeHintIcon(player) player.interfaceManager.openTab(Component(Components.FRIENDS2_550)) setVarbit(player, 3756, 9) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "Friends list", - "You should now see another new icon. Click on the flashing", - "smiling face to open your Friend List.", - "" - ) - ) + sendStageDialog(player, stage) } - 64 -> { hideTabs(player, login) setVarbit(player, 3756, 10) player.interfaceManager.openTab(Component(Components.IGNORE2_551)) player.interfaceManager.openTab(Component(Components.CLANJOIN_589)) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "This is your Friends List.", - "", - "This will be explained by Brother Brace shortly, but first click", - "on the other flashing face in the interface.", - "" - ) - ) + sendStageDialog(player, stage) } - 65 -> { hideTabs(player, login) setVarbit(player, 3756, 0) - registerHintIcon(player, Repository.findNPC(945)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "This is your Ignore List.", - "The two lists, Friends and Ignore - can be very helpful for", - "keeping track of when your friends are online or for blocking", - "messages from people you simply don't like. Speak with", - "Brother Brace and he will tell you more." - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.BROTHER_BRACE_954)!!) + sendStageDialog(player, stage) } - 66 -> { hideTabs(player, login) removeHintIcon(player) registerHintIcon(player, Location.create(3122,3102), 75) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "Your final instructor!", - "You're almost finished on tutorial island. Pass through the", - "door to find the path leading to your final instructor.", - "" - ) - ) + sendStageDialog(player, stage) } - 67 -> { hideTabs(player, login) removeHintIcon(player) - registerHintIcon(player, Repository.findNPC(946)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Your final instructor!", - "Just follow the path to the Wizard's house, where you will be", - "shown how to cast spells. Just talk with the mage indicated to", - "find out more.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.MAGIC_INSTRUCTOR_946)!!) + sendStageDialog(player, stage) } - 68 -> { hideTabs(player, login) removeHintIcon(player) player.interfaceManager.openTab(Component(player.spellBookManager.spellBook)) setVarbit(player, 3756, 7) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "Open up your final tab.", - "", - "Open up the Magic Spellbook tab by clicking on the flashing", - "icon next to the Prayer List tab you just learned about.", - "" - ) - ) + sendStageDialog(player, stage) } - 69 -> { hideTabs(player, login) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "", - "This is your spell list.", - "", - "Ask the mage about it.", - "" - ) - ) + removeHintIcon(player) + setVarbit(player, 3756, 0) + registerHintIcon(player, Repository.findNPC(NPCs.MAGIC_INSTRUCTOR_946)!!) + sendStageDialog(player, stage) } - 70 -> { hideTabs(player, login) - registerHintIcon(player, Repository.findNPC(41)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendScrollMessageWithBlueTitle( - "Cast Wind Strike at a chicken.", - "Now you have the runes you should see the Wind Strike icon at the", - "top-left of your spellbook, second in from the left. Walk over", - "to the caged chickens, click the Wind Strike icon and then", - "select one of the chickens to cast it on. It may take several", - "tries." - ) - ) + removeHintIcon(player) + //FIXME: as with the rats, the below should work, but doesn't + registerHintIcon(player, Repository.findNPC(NPCs.CHICKEN_41)!!) + sendStageDialog(player, stage) } - 71 -> { removeHintIcon(player) player.interfaceManager.restoreTabs() - registerHintIcon(player, Repository.findNPC(946)!!) - Component.setUnclosable( - player, - player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( - "You have almost completed the tutorial!", - "", - "All you need to do now is teleport to the mainland. Just speak", - "with Terrova and he'll tell you how to do that.", - "" - ) - ) + registerHintIcon(player, Repository.findNPC(NPCs.MAGIC_INSTRUCTOR_946)!!) + sendStageDialog(player, stage) } } } @JvmStatic - public fun hideTabs(player: Player, login: Boolean) + fun hideTabs(player: Player, login: Boolean) { val stage = getAttribute(player, "tutorial:stage", 0) if(login && player.interfaceManager.tabs.isNotEmpty()) @@ -1249,10 +532,9 @@ object TutorialStage { player.interfaceManager.openTab(Component(Components.QUESTJOURNAL_V2_274)) if(stage > 45) player.interfaceManager.openTab(Component(Components.WORNITEMS_387)) - if(stage > 49){ + if(stage > 46){ var wepInter = player.getExtension(WeaponInterface::class.java) - if(wepInter == null) - { + if (wepInter == null) { wepInter = WeaponInterface(player) player.addExtension(WeaponInterface::class.java, wepInter) } diff --git a/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java b/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java index a40f65f84..c20c65f72 100644 --- a/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java +++ b/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java @@ -178,8 +178,8 @@ public final class CharacterDesign { case 40: player.getSettings().toggleMouseButton(); break; - case 92://hair style - case 93: + case 92://hair style left arrow + case 93://hair style right arrow changeLook(player, 0, buttonId == 93); break; case 97: @@ -348,18 +348,23 @@ public final class CharacterDesign { private static int getValue(Player player, String key, int index, int currentIndex, boolean increment) { int[] array = player.getAttribute("male", player.getAppearance().isMale()) ? MALE_LOOK_IDS[index] : FEMALE_LOOK_IDS[index]; int val = 0; - if (increment && currentIndex + 1 > array.length -1) { - val = (int) array[0]; - currentIndex = 0; - } else if (!increment && currentIndex -1 < 0) { - val = (int) array[array.length -1]; - currentIndex = array.length -1; - } else if (increment) { - val = (int) array[currentIndex + 1]; - currentIndex++; + if (player.isArtificial() && index <= 1) { + currentIndex = RandomFunction.random(array.length -1); + val = array[currentIndex]; } else { - val = (int) array[currentIndex - 1]; - currentIndex--; + if (increment && currentIndex + 1 > array.length -1) { + val = (int) array[0]; + currentIndex = 0; + } else if (!increment && currentIndex -1 < 0) { + val = (int) array[array.length -1]; + currentIndex = array.length -1; + } else if (increment) { + val = (int) array[currentIndex + 1]; + currentIndex++; + } else { + val = (int) array[currentIndex - 1]; + currentIndex--; + } } player.setAttribute(key + ":" + index, currentIndex); return val; diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt index 0f79e6733..7154caa96 100644 --- a/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt +++ b/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt @@ -9,6 +9,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests @Initializable class FairyQueenDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -20,7 +21,7 @@ class FairyQueenDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (!isQuestComplete(player, "Fairytale II - Cure a Queen")) { + if (!isQuestComplete(player, Quests.FAIRYTALE_II_CURE_A_QUEEN)) { options( "How do crops and such survive down here?", "What's so good about this place?" ).also { stage = START_DIALOGUE } diff --git a/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt b/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt index a023e5b30..bdc56980b 100644 --- a/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt +++ b/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt @@ -9,6 +9,7 @@ import core.game.world.map.Location import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.Scenery +import content.data.Quests class EvilChickenLairListener: InteractionListener { override fun defineListeners() { @@ -17,7 +18,7 @@ class EvilChickenLairListener: InteractionListener { addClimbDest(Location.create(2455, 4380, 0), Location.create(2441, 4381, 0)) onUseWith(IntType.SCENERY, Items.RAW_CHICKEN_2138, Scenery.CHICKEN_SHRINE_12093) { player, _, _ -> - if (!hasRequirement(player, "Legend's Quest")) + if (!hasRequirement(player, Quests.LEGENDS_QUEST)) return@onUseWith false if(removeItem(player,(Item(Items.RAW_CHICKEN_2138)))){ @@ -33,6 +34,10 @@ class EvilChickenLairListener: InteractionListener { } return@onUseWith true } + onUseWith(IntType.SCENERY, Items.EGG_1944, Scenery.CHICKEN_SHRINE_12093) { player, _, _ -> + sendMessage(player, "Nice idea, but nothing interesting happens.") + return@onUseWith true + } onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.TUNNEL_ENTRANCE_12253) { player, _, node -> if(removeItem(player, Item(Items.ROPE_954))) replaceScenery(node as core.game.node.scenery.Scenery, Scenery.TUNNEL_ENTRANCE_12254, 100) diff --git a/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt b/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt index 37072b1e5..72a003a7b 100644 --- a/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt +++ b/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt @@ -1,22 +1,26 @@ package content.region.misc.zanaris.handlers -import core.api.* -import core.game.component.Component +import content.global.handlers.iface.FairyRingInterface +import core.api.anyInEquipment +import core.api.hasRequirement +import core.api.openInterface +import core.game.interaction.IntType +import core.game.interaction.InteractionListener import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager.TeleportType import core.game.world.map.Location import org.rs09.consts.Items -import core.game.interaction.InteractionListener -import core.game.interaction.IntType +import content.data.Quests /** * Handles interactions with fairy rings * @author Ceikry */ -private val RINGS = intArrayOf(12003, 12095, 14058, 14061, 14064, 14067, 14070, 14073, 14076, 14079, 14082, 14085, 14088, 14091, 14094, 14097, 14100, 14103, 14106, 14109, 14112, 14115, 14118, 14121, 14124, 14127, 14130, 14133, 14136, 14139, 14142, 14145, 14148, 14151, 14154, 14157, 14160, 16181, 16184, 23047, 27325, 37727) +private val RINGS = intArrayOf(12095, 14058, 14061, 14064, 14067, 14070, 14073, 14076, 14079, 14082, 14085, 14088, 14091, 14094, 14097, 14100, 14103, 14106, 14109, 14112, 14115, 14118, 14121, 14124, 14127, 14130, 14133, 14136, 14139, 14142, 14145, 14148, 14151, 14154, 14157, 14160, 16181, 16184, 23047, 27325, 37727) private const val MAIN_RING = 12128 private const val ENTRY_RING = 12094 +private const val MARKETPLACE_RING = 12003 class FairyRingPlugin : InteractionListener { @@ -24,7 +28,8 @@ class FairyRingPlugin : InteractionListener { on(RINGS, IntType.SCENERY, "use"){ player, _ -> if (!fairyMagic(player)) return@on true - player.teleporter.send(Location.create(2412, 4434, 0), TeleportType.FAIRY_RING) + val mainRingLocation = Location.create(2412, 4434, 0) + player.teleporter.send(mainRingLocation, TeleportType.FAIRY_RING) return@on true } on(MAIN_RING, IntType.SCENERY, "use"){ player, _ -> @@ -33,15 +38,20 @@ class FairyRingPlugin : InteractionListener { return@on true } on(ENTRY_RING, IntType.SCENERY, "use") { player, _ -> - if (!fairyMagic(player)) return@on true - player.teleporter.send(Location.create(3203, 3168, 0), TeleportType.FAIRY_RING) + val lumbridgeSwampShed = Location.create(3203, 3168, 0) + player.teleporter.send(lumbridgeSwampShed, TeleportType.FAIRY_RING) + return@on true + } + on(MARKETPLACE_RING, IntType.SCENERY, "use"){ player, _ -> + val alKharidBank = Location.create(3260, 3156, 0) + player.teleporter.send(alKharidBank, TeleportType.FAIRY_RING) return@on true } } private fun fairyMagic(player: Player) : Boolean { - if (!hasRequirement(player, "Fairytale I - Growing Pains")) { // should be converted to a FTP2 stage requirement once FTP2 is implemented + if (!hasRequirement(player, Quests.FAIRYTALE_I_GROWING_PAINS)) { // should be converted to a FTP2 stage requirement once FTP2 is implemented player.sendMessage("The fairy ring is inert.") return false } @@ -52,17 +62,7 @@ class FairyRingPlugin : InteractionListener { return true } - private fun reset(player: Player) { - player.removeAttribute("fairy-delay") - player.removeAttribute("fairy_location_combo") - for (i in 0..2) { - setVarp(player, 816 + i, 0) - } - } - private fun openFairyRing(player: Player) { - reset(player) - player.interfaceManager.openSingleTab(Component(735)) - player.interfaceManager.open(Component(734)) + openInterface(player, FairyRingInterface.RINGS_IFACE) } } diff --git a/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt index 890d74eb9..f40c15c12 100644 --- a/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt +++ b/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt @@ -1,5 +1,7 @@ package content.region.misthalin.barbvillage.dialogue +import content.region.kandarin.quest.scorpioncatcher.SCPeksaDialogue +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher import core.api.getQuestStage import core.api.openDialogue import core.game.dialogue.DialoguePlugin @@ -12,6 +14,7 @@ import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.NPCs +import content.data.Quests @Initializable class PeksaDialogue(player: Player? = null) : DialoguePlugin(player){ @@ -34,8 +37,7 @@ class PeksaDialogue(player: Player? = null) : DialoguePlugin(player){ showTopics( Topic("I could be, yes.", GO_SHOPPING), Topic("No, I'll pass on that.", LEAVE), - // todo get the quest state from Scorpion catcher to make this work - // IfTopic("Scorpion Stuff", SCORPION_CATCHER, getQuestStage(player, "Scorpion Catcher") == 50) + IfTopic("I've heard you have a small scorpion in your possession.", DIALOGUE_SCORPION_CATCHER, getQuestStage(player, Quests.SCORPION_CATCHER) == ScorpionCatcher.QUEST_STATE_OTHER_SCORPIONS) ) } @@ -48,9 +50,9 @@ class PeksaDialogue(player: Player? = null) : DialoguePlugin(player){ npcl(FacialExpression.HALF_GUILTY, "Well, come back if you change your mind.").also { stage = END_DIALOGUE } } - // DIALOGUE_SCORPION_CATCHER -> { - // openDialogue(player, PeksaDialogueSC(), npc) - // } + DIALOGUE_SCORPION_CATCHER -> { + openDialogue(player, SCPeksaDialogue(getQuestStage(player, Quests.SCORPION_CATCHER)), npc) + } } return true diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java index 1adee0589..0608d0fea 100644 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java @@ -4,7 +4,6 @@ import core.api.Container; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.emote.Emotes; -import core.game.node.item.Item; import org.rs09.consts.Items; import static core.api.ContentAPIKt.addItem; diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java index 8cef49bf4..1135cefd5 100644 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java @@ -56,7 +56,7 @@ public final class GrainOfPlentyDialogue extends DialoguePlugin { break; } player.getSavedData().getGlobalData().getStrongHoldRewards()[1] = true; - interpreter.sendDialogue("...congratualtions adventurer, you have been deemed worthy of this", "reward. You have also unlocked the Slap Head emote!"); + interpreter.sendDialogue("...congratulations adventurer, you have been deemed worthy of this", "reward. You have also unlocked the Slap Head emote!"); stage = 1; player.getEmoteManager().unlock(Emotes.SLAP_HEAD); break; diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt new file mode 100644 index 000000000..0fc1f9dd7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt @@ -0,0 +1,164 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + +import core.api.runTask +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.GameWorld.settings +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class GuardDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val DIALOGUE_COMPLETED = START_DIALOGUE + const val DIALOGUE_NOT_COMPLETED = 50 + + } + + override fun open(vararg args: Any?): Boolean { + val hasRead = player.savedData.globalData.hasReadPlaques() + if (hasRead) { + npcl(FacialExpression.HALF_GUILTY, "Can I help you?").also { stage = DIALOGUE_COMPLETED } + } + else { + npcl(FacialExpression.FURIOUS, "Ahem! Can I help you?").also { stage = DIALOGUE_NOT_COMPLETED } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + DIALOGUE_COMPLETED -> { + playerl( + FacialExpression.HALF_GUILTY, "Can I go upstairs?" + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 1 -> { + npcl( + FacialExpression.FURIOUS, + "Yes, citizen. Before you do I am instructed to give " + + "you one final piece of information" + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 2 -> { + playerl(FacialExpression.HALF_GUILTY, "Oh, okay then.").also { stage++ } + } + + DIALOGUE_COMPLETED + 3 -> { + npcl( + FacialExpression.HALF_GUILTY, + "In your travels around " + settings!!.name + ", should you find a player who acts in a " + + "way that breaks on of our rules, you should report them." + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 4 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Reporting is very simple and easy to do. Simply click the Report Abuse button at " + + "the bottom of the screen and you will be shown the following screen:" + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 5 -> { + player.interfaceManager.openComponent(700) + runTask(player, 5) { + if (player != null) { + player.interfaceManager.close() + } + return@runTask + }.also { stage++ } + } + + DIALOGUE_COMPLETED + 6 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Simply enter the player's name in the box and click the rule that the offender was breaking." + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 7 -> { + playerl(FacialExpression.HALF_GUILTY, "Okay. Then what?").also { stage++ } + } + + DIALOGUE_COMPLETED + 8 -> { + npcl( + FacialExpression.HALF_GUILTY, + "That's it! It really is that simple and it only takes a moment to do. " + + "Now you may enter the training centre. Good luck, citizen." + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 9 -> { + playerl(FacialExpression.HALF_GUILTY, "Thanks!").also { stage = END_DIALOGUE } + } + + DIALOGUE_NOT_COMPLETED -> { + playerl( + FacialExpression.HALF_GUILTY, "I'd like to go up to the training centre please." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 1 -> { + npcl(FacialExpression.FURIOUS, "Sorry, citizen, you can't go up there.").also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 2 -> { + playerl(FacialExpression.OLD_SNEAKY, "Why not?").also { stage++ } + + } + DIALOGUE_NOT_COMPLETED + 3 -> { + npcl( + FacialExpression.ANNOYED, + "You must learn about player safety before entering the training centre." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 4 -> { + playerl(FacialExpression.HALF_GUILTY, "Oh. How do I do that?").also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 5 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Each of these gublinches have been caught breaking the rules of " + settings!!.name + ". " + + "You should read the plaques on each of their cells to learn what they did wrong." + ).also { stage++ } + + } + DIALOGUE_NOT_COMPLETED + 6 -> { + playerl( + FacialExpression.HALF_GUILTY, + "Oh, right. I can enter the training centre once I have done that?" + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 7 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Yes. Once you have have examined each of the plaques, come and speak to me " + + "and I will tell you about the Report Abuse function." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 8 -> { + npcl( + FacialExpression.HALF_GUILTY, + "After that, I can let you into the training centre, upstairs." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 9 -> { + playerl(FacialExpression.HALF_GUILTY, "Okay, thanks for the help.").also { stage = END_DIALOGUE } + player.sendMessage("You need to read the jail plaques before the guard will allow you upstairs.") + } + } + return true + + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARD_7142) + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialoguePlugin.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialoguePlugin.java deleted file mode 100644 index 777ffcfa3..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialoguePlugin.java +++ /dev/null @@ -1,144 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import core.game.component.Component; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.tools.Log; -import core.tools.SystemLogger; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; - -import static core.api.ContentAPIKt.log; - -/** - * @author Tyler Telis - */ -public class GuardDialoguePlugin extends DialoguePlugin { - - /** - * Constructs a new {@code GuardDialogue} instance. - * @param player The {@code Player} instance. - */ - public GuardDialoguePlugin(Player player) { - super(player); - } - - /** - * Constructs a new {@code GuardDialoguePlugin} instance. - */ - public GuardDialoguePlugin() { - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new GuardDialoguePlugin(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - boolean read = player.getSavedData().getGlobalData().hasReadPlaques(); - interpreter.sendDialogues(npc, read ? FacialExpression.HALF_GUILTY : FacialExpression.FURIOUS, read ? "Can I help you?" : "Ahem! Can I help you?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - boolean read = player.getSavedData().getGlobalData().hasReadPlaques(); - switch (stage) { - case -1:// END dialogue stage. - end(); - break; - case 0: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, read ? "Can I go upstairs?" : "I'd like to go up to the training centre please."); - increment(); - break; - case 1: - interpreter.sendDialogues(npc, FacialExpression.FURIOUS, !read ? "Sorry, citizen, you can't go up there." : "", "Yes, citizen. Before you do I am instructed to give", "you one final piece of information"); - increment(); - break; - case 2: - interpreter.sendDialogues(player, read ? FacialExpression.HALF_GUILTY : FacialExpression.OLD_SNEAKY, read ? "Oh, okay then." : "Why not?"); - increment(); - break; - case 3: - if (!read) { - npc("You must learn about player safety before
entering the training centre."); - } else { - npc("In your travels around " + GameWorld.getSettings().getName() + ", should you find a", "player who acts in a way that breaks on of our rules,", "you should report them."); - } - increment(); - break; - case 4: - interpreter.sendDialogues(read ? npc : player, FacialExpression.HALF_GUILTY, !read ? "Oh. How do I do that?" : "Reporting is very simple and easy to do. Simply click", "the Report Abuse button at the bottom of the screen", "and you will be shown the following screen:"); - stage = read ? 10 : stage + 1; - break; - case 5: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Each of these gublinches have been caught breaking the", "Rules of " + GameWorld.getSettings().getName() + ". You should read the plaques on", "each of their cells to learn what they did wrong."); - increment(); - break; - case 6: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, right. I can enter the training centre once I have", "done that?"); - increment(); - break; - case 7: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes. Once you have have examined each of the plaques,", "come and speak to me and I will tell you about the", "Report Abuse function."); - increment(); - break; - case 8: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "After that, I can let you into the training centre,", "upstairs."); - increment(); - break; - case 9: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, thanks for the help."); - player.getPacketDispatch().sendMessage("You need to read the jail plaques before the guard will allow you upstairs."); - stage = -1; - break; - case 10: - if (read) { - player.getInterfaceManager().open(new Component(700)); - GameWorld.getPulser().submit(new Pulse(5) { - - @Override - public boolean pulse() { - if (player != null) { - player.getInterfaceManager().close(); - } - return true; - } - - }); - stage = 12; - } - break; - case 12: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Simply enter the player's name in the box and click the", "rule that the offender was breaking."); - stage = 13; - break; - case 13: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay. Then what?"); - stage = 14; - break; - case 14: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's it! It reall is that simple and it only takes a ", "moment to do. Now you may enter the training", "centre. Good luck, citizen."); - stage = 15; - break; - case 15: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks!"); - stage = -1; - break; - default: - log(this.getClass(), Log.ERR, "Unhandled dialogue stage=" + stage); - } - return false; - } - - @Override - public int[] getIds() { - return new int[] { 7142 }; - } - -} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PSOptionHandler.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PSOptionHandler.java deleted file mode 100644 index 742b4be80..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PSOptionHandler.java +++ /dev/null @@ -1,176 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_DOWN_STAIRS; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_ID_ENTER; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_LEAVE; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_LOCATION_ENTER; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_LOCATION_LEAVE; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_STAIRS_DOWN; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_STAIRS_UP; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_UP_STAIRS; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.TEST_PAPER_ITEM_ID; -import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.forId; - -import core.cache.def.impl.ItemDefinition; -import core.cache.def.impl.SceneryDefinition; -import core.game.dialogue.DialogueAction; -import core.game.global.action.DoorActionHandler; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.emote.Emotes; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.node.scenery.SceneryBuilder; -import core.game.world.map.Location; -import core.plugin.Plugin; - -import content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JailPlaques; - -import static core.api.ContentAPIKt.*; - - -/** - * @author Tyler Telis - */ -public class PSOptionHandler extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(JAIL_ENTRANCE_ID_ENTER).getHandlers().put("option:use", this); - SceneryDefinition.forId(JAIL_ENTRANCE_LEAVE).getHandlers().put("option:leave", this); - SceneryDefinition.forId(JAIL_STAIRS_UP).getHandlers().put("option:climb-up", this); - SceneryDefinition.forId(JAIL_STAIRS_DOWN).getHandlers().put("option:climb-down", this); - SceneryDefinition.forId(29732).getHandlers().put("option:open", this); - SceneryDefinition.forId(29624).getHandlers().put("option:open", this); - SceneryDefinition.forId(29728).getHandlers().put("option:enter", this); - SceneryDefinition.forId(29735).getHandlers().put("option:pull-back", this); - SceneryDefinition.forId(29623).getHandlers().put("option:use", this); - SceneryDefinition.forId(29730).getHandlers().put("option:pull", this); - SceneryDefinition.forId(29731).getHandlers().put("option:pull", this); - SceneryDefinition.forId(29577).getHandlers().put("option:open", this); - SceneryDefinition.forId(29578).getHandlers().put("option:search", this); - ItemDefinition.forId(TEST_PAPER_ITEM_ID).getHandlers().put("option:take exam", this); - SceneryDefinition.forId(29729).getHandlers().put("option:climb", this); - for (JailPlaques plaque : JailPlaques.values()) { - SceneryDefinition.forId(plaque.getObjectId()).getHandlers().put("option:read-plaque on", this); - } - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - int config = getVarp(player, 1203); - boolean locked = config == (1 << 29) || config == (0 << 26); - switch (node.getId()) { - case 29577:// chest - SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(29578), 60); - return true; - case 29578: - switch (option) { - case "search": - int stage = player.getSavedData().getGlobalData().getTestStage(); - if (stage == 3) { - player.getEmoteManager().unlock(Emotes.SAFETY_FIRST); - player.getInventory().add(new Item(995, 10000), player); - player.getInventory().add(new Item(12629), player); - player.getDialogueInterpreter().sendItemMessage(12629, "You open the chest to find a large pile of gold, along with a pair of safety gloves. Also in the chest is the secret of the 'Safety First' emote."); - player.getSavedData().getGlobalData().setTestStage(4); - } else if (stage == 4) { - if (!player.hasItem(new Item(12629))) { - player.getInventory().add(new Item(12629), player); - player.getDialogueInterpreter().sendItemMessage(12629, "You find a pair of safety gloves."); - } else { - player.getDialogueInterpreter().sendDialogue("You already have a pair of safety gloves."); - } - } - return true; - } - return true; - case 29730:// lever - case 29731:// level down - if (!locked) { - player.sendMessage("You hear cogs and gears moving and the sound of heavy locks falling into place."); - config = (1 << 29); - } else { - player.sendMessage("You hear the cogs and gears moving and a distant unlocking sound."); - config += (1 << 26); - } - setVarp(player, 1203, config, true); - return true; - case 29624: - if (locked) { - player.sendMessage("The door seems to be locked by some kind of mechanism."); - } else { - if (player.getLocation().getZ() == 2) { - player.teleport(new Location(3177, 4266, 0)); - } else { - player.teleport(new Location(3177, 4269, 2)); - } - } - return true; - case 29729: - player.teleport(new Location(3078, 3463, 0)); - return true; - case 29623: - player.teleport(new Location(3077, 4235, 0)); - return true; - case 29735: - player.getDialogueInterpreter().sendDialogue("There appears to be a tunnel behind the poster."); - player.getDialogueInterpreter().addAction(new DialogueAction() { - - @Override - public void handle(Player player, int buttonId) { - player.teleport(new Location(3140, 4230, 2)); - } - - }); - return true; - case 29732: - if (!player.getSavedData().getGlobalData().hasReadPlaques()) { - player.sendMessage("This door is locked."); - } else { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()); - } - return true; - case 29728: - if (player.getSavedData().getGlobalData().getTestStage() < 3) { - player.sendMessage("You need to complete the player safety test first."); - return true; - } - player.teleport(new Location(3158, 4280, 3)); - return true; - } - if (node instanceof Scenery) { - Scenery object = (Scenery) node; - JailPlaques plaque = forId(object.getId()); - if (plaque != null) { - plaque.read(player, object); - return true; - } else if (object.getId() == JAIL_ENTRANCE_ID_ENTER || object.getId() == JAIL_ENTRANCE_LEAVE) { - player.getProperties().setTeleportLocation(object.getId() == JAIL_ENTRANCE_ID_ENTER ? JAIL_ENTRANCE_LOCATION_ENTER : JAIL_ENTRANCE_LOCATION_LEAVE); - return true; - } else if (object.getId() == JAIL_STAIRS_UP || object.getId() == JAIL_STAIRS_DOWN) { - if (!player.getSavedData().getGlobalData().hasReadPlaques() && object.getId() != JAIL_STAIRS_DOWN) { - player.getPacketDispatch().sendMessage("You need to read the jail plaques before the guard will allow you upstairs."); - return true; - } - player.getProperties().setTeleportLocation(object.getId() == JAIL_STAIRS_UP ? JAIL_UP_STAIRS : JAIL_DOWN_STAIRS); - return true; - } - } else if (node instanceof Item) { - Item item = (Item) node; - if (player.getSavedData().getGlobalData().getTestStage() >= 2) { - player.sendMessage("You have already completed the test!"); - return true; - } - if (item.getId() == TEST_PAPER_ITEM_ID) { - player.removeAttribute("s-stage"); - player.getDialogueInterpreter().open("player_safety", node.getId()); - return true; - } - } - return false; - } - -} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.java deleted file mode 100644 index 41a110c0b..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.java +++ /dev/null @@ -1,269 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import core.game.component.Component; -import core.game.component.ComponentPlugin; -import core.game.dialogue.DialogueInterpreter; -import core.game.dialogue.DialoguePlugin; -import core.game.node.entity.player.Player; -import core.plugin.Plugin; - -/** - * Handles the player safety test. - * @author Tyler Telis - * @author Vexia - */ -public class PlayerSafetyTest extends DialoguePlugin { - - /** - * The check box button ids. - */ - public static int ANSWER_1 = 3, ANSWER_2 = 4, ANSWER_3 = 12; - - /** - * Constructs a new {@Code PlayerSafetyTest} {@Code Object} - * @param player the player. - */ - public PlayerSafetyTest(Player player) { - super(player); - } - - /** - * Constructs a new {@code PlayerSafetyTest} instance. - */ - public PlayerSafetyTest() { - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new PlayerSafetyTest(player); - } - - @Override - public boolean open(Object... args) { - stage = player.getAttribute("s-stage", 0); - if (args.length >= 2) { - handleQuiz(Integer.parseInt(String.valueOf(args[1]))); - } else { - stage = 0; - sendTest(); - } - return true; - } - - /** - * Sends the test. - */ - public void sendTest() { - Component component = getComponentForStage(stage); - component.setPlugin(new ComponentPlugin() { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - if (player == null) { - return false; - } - if (player.getDialogueInterpreter().getDialogue() == null) { - player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("player_safety"), "reopen", button); - } - if (player.getDialogueInterpreter().getDialogue() == null) { - return false; - } - return player.getDialogueInterpreter().getDialogue().handle(component.getId(), button); - } - - }); - player.getInterfaceManager().open(component); - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - return handleQuiz(buttonId); - } - - private boolean handleQuiz(int buttonId) { - if (buttonId == 48 || buttonId == 39 || buttonId == 40) { - if (stage >= TestQuestions.values().length) { - player.getInterfaceManager().close(); - player.getSavedData().getGlobalData().setTestStage(2); - player.sendMessage("Well done! You completed the exams."); - player.getDialogueInterpreter().sendDialogue("Congratulations! The test has been completed. Hand the paper in to", "Professor Henry for marking."); - return false; - } else { - sendTest(); - } - return true; - } - if (stage == TestQuestions.values().length) {// Last question. - player.getDialogueInterpreter().getDialogue().end(); - return true; - } - if (forStage(stage).answer(player, buttonId)) { - return true; - } - return true; - } - - @Override - public boolean close() { - player.setAttribute("s-stage", stage); - return super.close(); - } - - /** - * A test question. - * @author Tyler Tellis - */ - public enum TestQuestions { - QUESTION_1(697, ANSWER_2) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 26, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 37 : 43, false); - } - }, - QUESTION_2(699, ANSWER_2) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 20, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 31 : 34, false); - } - }, - QUESTION_3(707, ANSWER_1) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 20, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 31 : 35, false); - } - }, - QUESTION_4(710, 9) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 20, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 31 : 34, false); - } - }, - QUESTION_5(704, 10) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 26, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 37 : 40, false); - } - }, - QUESTION_6(694, 10) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 20, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 31 : 34, false); - } - }, - QUESTION_8(696, 4) { - @Override - public void showAnswer(Player player, boolean correct, int interfaceId) { - player.getPacketDispatch().sendInterfaceConfig(interfaceId, 20, false); - player.getPacketDispatch().sendInterfaceConfig(interfaceId, correct ? 31 : 34, false); - } - }; - - /** - * The interface id. - */ - private int interfaceId; - - /** - * The correct button id to click. - */ - private int correctButton; - - /** - * Constructs a new {@Code TestQuestions} {@Code Object} - * @param interfaceId the interface. - * @param correctButton the button. - */ - private TestQuestions(int interfaceId, int correctButton) { - this.interfaceId = interfaceId; - this.correctButton = correctButton; - } - - /** - * Answers a question. - * @param player the player. - * @param buttonId the button id. - * @return {@code True} if so. - */ - public boolean answer(Player player, int buttonId) { - boolean correct = buttonId == correctButton; - if (interfaceId == 710 && buttonId == 9) { - correct = true; - } else if (interfaceId == 704 && buttonId == 10) { - correct = true; - } else if (interfaceId == 696 && buttonId == 4) { - correct = true; - } - showAnswer(player, correct, interfaceId); - if (correct) { - player.getDialogueInterpreter().getDialogue().increment(); - } - return player.getInterfaceManager().getComponent(interfaceId) != null; - } - - /** - * Shows the answer. - * @param player the player. - * @param correct the correct. - * @param interfaceId the id. - */ - public abstract void showAnswer(Player player, boolean correct, int interfaceId); - - /** - * Gets the value. - * @return the value. - */ - public int value() { - return ordinal(); - } - - /** - * Gets the inter id. - * @return the id. - */ - public int getInterfaceId() { - return interfaceId; - } - - /** - * Gets the correct button. - * @return the button. - */ - public int getCorrectButton() { - return correctButton; - } - } - - @Override - public int[] getIds() { - return new int[] { DialogueInterpreter.getDialogueKey("player_safety") }; - } - - /** - * Gets a new component for the stage. - * @param stage The stage; - * @return The {@code Component} instance. - */ - public static Component getComponentForStage(int stage) { - return new Component(forStage(stage).getInterfaceId()); - } - - /** - * Gets it for the stage. - * @param stage the stage. - * @return the question. - */ - public static TestQuestions forStage(int stage) { - return TestQuestions.values()[stage]; - } -} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.kt new file mode 100644 index 000000000..98ad6723b --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.kt @@ -0,0 +1,102 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import core.plugin.Initializable + + +// /** +// * Handles the player safety test. +// * Java version +// * @author Tyler Telis +// * @author Vexia +// * Kotlin +// * @author gregf36665 +// */ +@Initializable +class PlayerSafetyTest : InterfaceListener { + + companion object { + private val testQuestions = listOf( + TestQuestion(697, 26, mapOf(4 to 37, 3 to 40, 5 to 43), 4), + TestQuestion(699, 20, mapOf(4 to 31, 3 to 34), 4), + TestQuestion(707, 20, mapOf(3 to 31, 4 to 35, 5 to 35), 3), + TestQuestion(710, 20, mapOf(9 to 31, 10 to 34), 9), + TestQuestion(704, 26, mapOf(10 to 37, 12 to 43, 11 to 40), 10), + // todo figure out why these 2 are not working + // TestQuestion(694, 20, mapOf(12 to 31, 13 to 34), 13), + // TestQuestion(708, 26, mapOf(12 to 31, 13 to 34), 12), + TestQuestion(696, 20, mapOf(4 to 31, 3 to 34, 5 to 34), 4) + + + ) + private var testQuestionNumber = 0 + } + + /** + * Define a new Test Question + * interfaceId: the base ID for the test question + * baseChild: the ID of the Component child + * answers: A map of button press: child to display + * correctOption: The button number for the correct option + */ + class TestQuestion(val interfaceId: Int, val baseChild : Int, val answers : Map, val correctOption: Int){ + + fun showAnswer(player: Player, button : Int){ + setComponentVisibility(player, interfaceId, baseChild, false) + answers[button]?.let { setComponentVisibility(player, interfaceId, it, false) } + return + } + } + + private fun checkAnswer(player: Player, button: Int){ + val question = testQuestions[testQuestionNumber] + question.showAnswer(player, button) + if (button == question.correctOption){ + testQuestionNumber += 1 + } + } + + private fun completedTest(player: Player) { + closeInterface(player) + player.savedData.globalData.testStage = 2 + sendMessage(player,"Well done! You completed the exams.") + sendDialogue(player, "Congratulations! The test has been completed. " + + "Hand the paper in to Professor Henry for marking.") + } + + fun update(player: Player){ + // Close all open interfaces + closeInterface(player) + // Open the correct one now + testQuestions.forEachIndexed(){ index, testQuestion -> + if (index == testQuestionNumber){ + openInterface(player, testQuestion.interfaceId) + } + } + } + + override fun defineInterfaceListeners() { + onOpen(697) { _, _ -> + testQuestionNumber = 0 // Set the testQuestionNumber back to 0 on first launch + return@onOpen true + } + for (question in testQuestions){ + on(question.interfaceId) { player, _, _, buttonID, _, _ -> + if (buttonID in 0..35) { + checkAnswer(player, buttonID) + } + else{ + update(player) + if (testQuestionNumber == testQuestions.size) { + completedTest(player) + return@on true + } + } + return@on true + } + } + } +} + diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.java deleted file mode 100644 index d4cffed76..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.java +++ /dev/null @@ -1,221 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import core.ServerConstants; -import core.api.Container; -import core.game.component.Component; -import core.game.node.entity.player.link.emote.Emotes; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import org.rs09.consts.Items; - -import static core.api.ContentAPIKt.*; - -/** - * @author Tyler Telis - */ -public class ProfessorHenryDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code ProfessorHenryDialogue} instance. - * @param player The {@code Player} instance. - */ - public ProfessorHenryDialogue(Player player) { - super(player); - } - - /** - * Constructs a new {@code ProfessorHenryDialogue} instance. - */ - public ProfessorHenryDialogue() { - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new ProfessorHenryDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - stage = 0; - if (player.getSavedData().getGlobalData().getTestStage() == 2 && player.getInventory().contains(12626, 1)) { - player("Hello, Professor."); - stage = 900; - return true; - } - if (player.getSavedData().getGlobalData().getTestStage() >= 3) { - npc("Good job " + player.getUsername() + " you completed the test!"); - stage = 800; - return true; - } - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Hello."); - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 800: - end(); - break; - case 900: - npc("Ah, " + player.getUsername() + ". How's the test going?"); - stage++; - break; - case 901: - player("I think I've finished."); - stage++; - break; - case 902: - npc("Excellent! Let me just mark the paper for you then."); - stage++; - break; - case 903: - npc("Hmm. Uh-huh, yes I see. Good! Yes, that's right."); - stage++; - break; - case 904: - npc("Excellent! Allow me to reward you for your work. I", "have these two old lamps that you may find useful."); - stage++; - break; - case 905: - npc("Also, there is an old jail block connected to the cells", "below the training centre, which have been overrun with", "vicious creatures. If you search around the jail cells", "downstairs, you should find it easily enough."); - stage++; - break; - case 906: - npc("Now, your rewards."); - stage++; - break; - case 907: - if (player.getInventory().freeSlots() == 0) { - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "It seems your inventory is full."); - stage = -1; - return false; - } - - if (removeItem(player, Items.TEST_PAPER_12626, Container.INVENTORY)) { - showReward(player); - end(); - } - break; - case -1: - end(); - break; - case 0: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "Hello what?"); - increment(); - break; - case 1: - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Uh...hello there?"); - increment(); - break; - case 2: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "Hello, 'Professor'. Manners cost nothing, you know.", "When you're in my classroom, I ask that you use the", "proper address for my station."); - increment(); - break; - case 3: - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Your station?"); - increment(); - break; - case 4: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "Yes. It means 'position', so to speak."); - increment(); - break; - case 5: - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Oh, okay."); - increment(); - break; - case 6: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "Now, what can I do for you, exactly?"); - increment(); - break; - case 7: - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "What is this place?"); - increment(); - break; - case 8: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "This is the Misthalin Training Centre of Ezcelience. It", "is where bold adventurers, such as yourself, can come", "to learn of the dangers of the wide world and gain", "some valuable experience at the same time."); - increment(); - break; - case 9: - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "What can I do here?"); - increment(); - break; - case 10: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "Here you can take part in the Player Safety test: a set", "of valuable lessons to learn about staying safe in ", ServerConstants.SERVER_NAME + "."); - increment(); - break; - case 11: - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "I can give you a test paper to take and, once", "completed, you can bring it back to me for marking.", "Would you like to take the test?", "It will not cost you anything"); - increment(); - break; - case 12: - interpreter.sendOptions("Select an Option", "Yes, please", "Not right now, thanks."); - increment(); - break; - case 13: - if (buttonId == 1) { - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Yes, please."); - increment(); - } else if (buttonId == 2) { - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Not right now, thanks."); - stage = -1; - } - break; - case 14: - if (player.getInventory().freeSlots() == 0) { - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "It seems your inventory is full."); - stage = -1; - return false; - } else if (player.getInventory().containItems(StrongHoldOfPlayerSafetyPlugin.TEST_PAPER_ITEM_ID)) { - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "You already have a test, please fill it out", "and return it to me."); - stage = -1; - return false; - } - player.getSavedData().getGlobalData().setTestStage(1); - player.getInventory().add(new Item(StrongHoldOfPlayerSafetyPlugin.TEST_PAPER_ITEM_ID)); - sendNormalDialogue(npc, FacialExpression.HALF_GUILTY, "Right then. Here is the test paper. When you have", "completed all the questions, bring it back to me for", "marking."); - increment(); - break; - case 15: - sendNormalDialogue(player, FacialExpression.HALF_GUILTY, "Okay, thanks."); - stage = -1; - break; - } - return false; - } - - /** - * Shows the reward for the player. - * @param player the player. - */ - private void showReward(Player player) { - setVarp(player, 1203, 1 << 29, true); - player.getSavedData().getGlobalData().setTestStage(3); - player.getQuestRepository().syncronizeTab(player); - player.getInterfaceManager().open(new Component(277)); - for (int i = 9; i < 18; i++) { - player.getPacketDispatch().sendString("", 277, i); - } - player.getPacketDispatch().sendString("You have completed the Player Safety test!", 277, 4); - player.getPacketDispatch().sendString("2 Experience lamps", 277, 9); - player.getPacketDispatch().sendString("Access to the Stronghold of", 277, 10); - player.getPacketDispatch().sendString("Player Safety Dungeon", 277, 11); - player.getPacketDispatch().sendString("The Safety First' emote", 277, 12); - player.getPacketDispatch().sendString(player.getQuestRepository().getPoints() + "", 277, 7); - player.getPacketDispatch().sendItemZoomOnInterface(12626, 240, 277, 5); - if (!player.hasItem(new Item(4447, 2))) { - player.getInventory().add(new Item(4447, 2), player); - } - player.getEmoteManager().unlock(Emotes.SAFETY_FIRST); - } - - @Override - public int[] getIds() { - return new int[] { 7143 }; - } - -} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.kt new file mode 100644 index 000000000..3361fedce --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.kt @@ -0,0 +1,144 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + +import core.ServerConstants +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.emote.Emotes +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ProfessorHenryDialogue(player : Player? = null) : DialoguePlugin(player){ + + companion object{ + const val HAND_IN_TEST = 10 + const val MEETING = 100 + const val GET_TEST = 200 + const val iFace = 277 + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage){ + START_DIALOGUE -> { + if (player.savedData.globalData.testStage == 2 && inInventory(player, Items.TEST_PAPER_12626)){ + // The player has the test and has completed it but need it marked + player("Hello, Professor.").also { stage = HAND_IN_TEST} + } + else if (player.savedData.globalData.testStage >= 3){ + // The player has already had their test marked and taken + npcl(FacialExpression.HAPPY, "Good job ${player.username}, you completed the test!").also { stage = END_DIALOGUE } + return true + } + else{ + player(FacialExpression.NEUTRAL, "Hello.").also { stage = MEETING } + } + } + MEETING -> npcl(FacialExpression.ANNOYED, "Hello what?").also { stage++ } + MEETING + 1 -> playerl(FacialExpression.HALF_GUILTY, "Uh...hello there?").also { stage++ } + MEETING + 2 -> npcl(FacialExpression.HALF_GUILTY, "Hello, 'Professor'. Manners cost nothing, you know. " + + "When you're in my classroom, I ask that you use the proper address for my station.").also { stage++ } + MEETING + 3 -> playerl(FacialExpression.HALF_GUILTY, "Your station?").also { stage++ } + MEETING + 4 -> npcl(FacialExpression.HALF_GUILTY, "Yes. It means 'position', so to speak.").also { stage++ } + MEETING + 5 -> playerl(FacialExpression.HALF_GUILTY, "Oh, okay.").also { stage++ } + MEETING + 6 -> npcl(FacialExpression.HALF_GUILTY, "Now, what can I do for you, exactly?").also { stage++ } + MEETING + 7 -> playerl(FacialExpression.HALF_GUILTY, "What is this place?").also { stage++ } + MEETING + 8 -> npcl(FacialExpression.HALF_GUILTY, "This is the Misthalin Training Centre of Excellence. " + + "It is where bold adventurers, such as yourself, can come to learn of the dangers of " + + "the wide world and gain some valuable experience at the same time.").also { stage++ } + MEETING + 9 -> playerl(FacialExpression.HALF_GUILTY, "What can I do here?").also { stage++ } + MEETING + 10 -> npcl(FacialExpression.HALF_GUILTY, "Here you can take part in the Player Safety test: " + + "a set of valuable lessons to learn about staying safe " + + "in ${ServerConstants.SERVER_NAME}.").also { stage++ } + MEETING + 11 -> npcl(FacialExpression.HALF_GUILTY, "I can give you a test paper to take and, once completed, " + + "you can bring it back to me for marking. Would you like to take the test? " + + "It will not cost you anything.").also { stage++ } + MEETING + 12 -> + showTopics( + Topic("Yes, please.", GET_TEST), + Topic("Not right now, thanks.", END_DIALOGUE) + ) + + GET_TEST -> { + if (player.inventory.isFull) { + npcl(FacialExpression.HALF_GUILTY, "It seems your inventory is full.").also { stage = END_DIALOGUE } + } else if (amountInInventory(player, Items.TEST_PAPER_12626) > 0) { + npcl( + FacialExpression.HALF_GUILTY, + "You already have a test, please fill it out and return it to me." + ).also { stage = END_DIALOGUE } + } else { + player.savedData.globalData.testStage = 1 + addItem(player, Items.TEST_PAPER_12626) + npcl( FacialExpression.HALF_GUILTY, "Right then. Here is the test paper. " + + "When you have completed all the questions, bring it back to me for marking." + ).also { stage ++ } + } + } + GET_TEST + 1 -> playerl(FacialExpression.HALF_GUILTY, "Okay, thanks.").also { stage = END_DIALOGUE } + + HAND_IN_TEST -> npcl(FacialExpression.HAPPY, + "Ah, ${player.username}. How's the test going?").also { stage ++ } + HAND_IN_TEST + 1 -> playerl(FacialExpression.NEUTRAL, "I think I've finished.").also { stage++ } + HAND_IN_TEST + 2 -> npcl(FacialExpression.HAPPY, "Excellent! Let me just mark the paper for you then.").also { stage++ } + HAND_IN_TEST + 3 -> npcl(FacialExpression.HAPPY, "Hmm. Uh-huh, yes I see. Good! Yes, that's right.").also{ stage++ } + HAND_IN_TEST + 4-> npcl(FacialExpression.HAPPY, "Excellent! Allow me to reward you for your work. " + + "I have these two old lamps that you may find useful.").also { stage++ } + // This needs to be npc for word wrap + HAND_IN_TEST + 5 -> npc("Also, there is an old jail block connected to the cells", + "below the training centre, which have been overrun with", + "vicious creatures. If you search around the jail cells", + "downstairs, you should find it easily enough.").also { stage++ } + HAND_IN_TEST + 6 -> npcl(FacialExpression.HAPPY, "Now, your rewards.").also { stage++ } + HAND_IN_TEST + 7 ->{ + // Check for at least 1 slot + // Player will get 2 lamps but we will take the test from them + if (freeSlots(player) >= 1){ + showReward().also { stage = END_DIALOGUE } + } + else { + npcl(FacialExpression.SAD, "You do not have space in your inventory for the rewards").also { stage = END_DIALOGUE } + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PROFESSOR_HENRY_7143) + } + + private fun showReward(){ + // Show the poster tunnel + setVarp(player, 1203, 1 shl 29, true) + player.savedData.globalData.testStage = 3 + + if (removeItem(player, Items.TEST_PAPER_12626)) { + addItem(player, Items.ANTIQUE_LAMP_4447, 2) + } + player.emoteManager.unlock(Emotes.SAFETY_FIRST) + + openInterface(player, iFace) + + // Clear the other lines + for (i in 9.. 18){ + player.packetDispatch.sendString("", iFace, i) + } + + player.packetDispatch.sendString("You have completed the Player Safety test!", iFace, 4) + player.packetDispatch.sendString(player.getQuestRepository().points.toString() + "", iFace, 7) + + player.packetDispatch.sendString("2 Experience lamps", iFace, 9) + player.packetDispatch.sendString("Access to the Stronghold of", iFace, 10) + player.packetDispatch.sendString("Player Safety Dungeon", iFace, 11) + player.packetDispatch.sendString("The Safety First' emote", iFace, 12) + + sendItemZoomOnInterface(player, iFace, 5, Items.TEST_PAPER_12626) + + } +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/SafetyMapZone.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/SafetyMapZone.java deleted file mode 100644 index 940125f7c..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/SafetyMapZone.java +++ /dev/null @@ -1,15 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import core.game.world.map.zone.MapZone; - -public class SafetyMapZone extends MapZone { - - public SafetyMapZone() { - super("strong hold of player safety", true); - } - - @Override - public void configure() { - - } -} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyListener.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyListener.kt new file mode 100644 index 000000000..68fd59034 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyListener.kt @@ -0,0 +1,333 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + + import core.api.* + import core.game.activity.Cutscene + import core.game.component.Component + import core.game.global.action.DoorActionHandler + import core.game.interaction.IntType + import core.game.interaction.InteractionListener + import core.game.interaction.InterfaceListener + import core.game.node.Node + import core.game.node.entity.player.Player + import core.game.node.entity.player.link.emote.Emotes + import core.game.node.scenery.Scenery + import core.game.world.map.Location + import org.rs09.consts.Items + import org.rs09.consts.NPCs + import org.rs09.consts.Scenery as SceneryConst + + +@Suppress("unused") + class StrongHoldOfPlayerSafetyListener : InteractionListener{ + + companion object{ + private val plaquesToIface = mapOf( // Door to interface + SceneryConst.JAIL_DOOR_29595 to 701, + SceneryConst.JAIL_DOOR_29596 to 703, + SceneryConst.JAIL_DOOR_29597 to 711, + SceneryConst.JAIL_DOOR_29598 to 695, + SceneryConst.JAIL_DOOR_29599 to 312, + SceneryConst.JAIL_DOOR_29600 to 706, + SceneryConst.JAIL_DOOR_29601 to 698, + ) + + private val creviceClimbedAttribute = "/save:player_strong:crevice_climbed" + + } + override fun defineListeners() { + + // Test + on(Items.TEST_PAPER_12626, IntType.ITEM, "take exam") { player, _ -> + if (player.savedData.globalData.testStage == 2){ + sendMessage(player, "You have already completed the test. Hand it in to Professor Henry for marking.") + } + else{ + openInterface(player, 697) + } + return@on true + } + + // Students + on(intArrayOf(NPCs.STUDENT_7151, NPCs.STUDENT_7152, NPCs.STUDENT_7153, NPCs.STUDENT_7154, + NPCs.STUDENT_7155, NPCs.STUDENT_7156, NPCs.STUDENT_7157), IntType.NPC, "Talk-to") { player, _ -> + sendMessage(player, "This student is trying to focus on their work.") + return@on true + } + + // Jail teleports + on(SceneryConst.JAIL_ENTRANCE_29603, IntType.SCENERY, "use") { player, _-> + teleport(player, Location.create(3082, 4229, 0)) + return@on true + } + on(SceneryConst.JAIL_ENTRANCE_29602, IntType.SCENERY, "leave") { player, _ -> + teleport(player, Location.create(3074, 3456, 0)) + return@on true + } + on(SceneryConst.STAIRS_29589, IntType.SCENERY, "climb-up") { player, _ -> + if (player.globalData.hasReadPlaques()){ + teleport(player, Location.create(3083, 3452, 0)) + } + else{ + sendMessage(player, "You need to read the jail plaques before the guard will allow you upstairs") + } + + return@on true + } + // Exam room + on(SceneryConst.DOOR_29732, IntType.SCENERY, "open") { player, node -> + if (player.globalData.testStage > 0){ + // The player has talked to the prof + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else{ + sendMessage(player, "The door is locked") + } + return@on true + } + on(SceneryConst.STAIRS_29592, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3086, 4247, 0)) + return@on true + } + + // crevice (and rope) + on(SceneryConst.CREVICE_29728, IntType.SCENERY, "enter"){ player, _ -> + if (getAttribute(player, creviceClimbedAttribute, false)){ + teleport(player, Location.create(3159, 4279, 3)) + } + else{ + // todo find what the crevice should say + sendMessage(player, "There's no way down") + } + return@on true + } + on(SceneryConst.ROPE_29729, IntType.SCENERY, "climb"){ player, _ -> + if (!getAttribute(player, creviceClimbedAttribute, false)){ + setAttribute(player, creviceClimbedAttribute, true) + } + teleport(player, Location.create(3077, 3462, 0)) + return@on true + } + + // Plaques + on(intArrayOf(SceneryConst.JAIL_DOOR_29595, SceneryConst.JAIL_DOOR_29596, SceneryConst.JAIL_DOOR_29597, + SceneryConst.JAIL_DOOR_29598, SceneryConst.JAIL_DOOR_29599, SceneryConst.JAIL_DOOR_29600, + SceneryConst.JAIL_DOOR_29601) , IntType.SCENERY, "Read-plaque on") { player, node -> + read(player, node) + return@on true + } + + // The dungeon + on(SceneryConst.POSTER_29586, IntType.SCENERY, "pull-back") { player, _ -> + sendDialogue(player, "There appears to be a tunnel behind this poster.") + teleport(player, Location.create(3140, 4230, 2)) + return@on true + } + on(SceneryConst.TUNNEL_29623, IntType.SCENERY, "use") {player, _ -> + teleport(player, Location.create(3077, 4235, 0)) + return@on true + } + + on(SceneryConst.AN_OLD_LEVER_29730, IntType.SCENERY, "pull") {player, _ -> + sendMessage(player, "You hear the cogs and gears moving and a distant unlocking sound.") + setVarp(player, 1203, (1 shl 29) or (1 shl 26), true) + return@on true + } + + on(SceneryConst.AN_OLD_LEVER_29731, IntType.SCENERY, "pull") {player, _ -> + sendMessage(player, "You hear cogs and gears moving and the sound of heavy locks falling into place.") + setVarp(player, 1203, 1 shl 29, true) + return@on true + } + + // the same jail door is used in 4 different places + on(SceneryConst.JAIL_DOOR_29624, IntType.SCENERY, "open") { player, _ -> + if (getVarp(player, 1203) and (1 shl 26) == 0) { + // The door is locked + sendMessage(player, "The door seems to be locked by some kind of mechanism.") + return@on true + } + if (player.location.z == 2) { + // Floor 2 to hidden tunnel + teleport(player, Location.create(3177, 4266, 0)) + } + else if (player.location.z == 1){ + // Floor 1 to hidden tunnel + teleport(player, Location.create(3143, 4270, 0)) + } + else { + // Leaving the hidden tunnel + if (player.location.x < 3150){ + // Leaving by the west exit (to floor 1) + teleport(player, Location.create(3142, 4272, 1)) + } + else{ + // Must be exiting by the east exit (to floor 2) + teleport(player, Location.create(3177, 4269, 2)) + } + } + return@on true + } + + // the 4 stairs in the middle of the 1st/2nd floor + // NE + on(SceneryConst.STAIRS_29667, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3160, 4249, 1)) + return@on true + } + on(SceneryConst.STAIRS_29668, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3158, 4250, 2)) + return@on true + } + + // SE + on(SceneryConst.STAIRS_29663, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3160, 4246, 1)) + return@on true + } + on(SceneryConst.STAIRS_29664, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3158, 4245, 2)) + return@on true + } + + // SW + on(SceneryConst.STAIRS_29655, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3146, 4246, 1)) + return@on true + } + on(SceneryConst.STAIRS_29656, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3149, 4244, 2)) + return@on true + } + + // NW + on(SceneryConst.STAIRS_29659, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3146, 4249, 1)) + return@on true + } + on(SceneryConst.STAIRS_29660, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3148, 4250, 2)) + return@on true + } + + + // rewards chest + on(SceneryConst.TREASURE_CHEST_29577, IntType.SCENERY, "open"){ player, _ -> + setVarbit(player, 4499, 1, true) + return@on true + } + on(SceneryConst.TREASURE_CHEST_29578, IntType.SCENERY, "search"){ player, _ -> + // Give the player rewards + if (player.globalData.testStage == 3){ + // Check the player has enough slots + if ((freeSlots(player) == 0) or + ((freeSlots(player) == 1) and !inInventory(player, Items.COINS_995))){ + sendDialogue(player, "You do not have enough inventory space!") + } + else{ + player.emoteManager.unlock(Emotes.SAFETY_FIRST) + addItem(player, Items.COINS_995, 10000) + addItem(player, Items.SAFETY_GLOVES_12629) + sendItemDialogue(player, Items.SAFETY_GLOVES_12629, + "You open the chest to find a large pile of gold, along with a pair of safety gloves. ") + + player.globalData.testStage = 4 + } + } + else { + // The player may have lost their gloves + if (hasAnItem(player, Items.SAFETY_GLOVES_12629).exists()){ + sendDialogue(player, "The chest is empty") + } + else{ + if (freeSlots(player) == 0){ + sendDialogue(player, "You do not have enough inventory space!") + } + else { + addItem(player, Items.SAFETY_GLOVES_12629) + sendItemDialogue( + player, Items.SAFETY_GLOVES_12629, + "You open the chest to find a pair of safety gloves." + ) + } + } + + } + return@on true + } + } + + fun read(player: Player, plaque: Node){ + if (plaque !is Scenery) return + player.interfaceManager.openChatbox(plaquesToIface[plaque.id]!!) + } + + + class PlaqueListener : InterfaceListener { + + var scene : PlaqueCutscene? = null + + override fun defineInterfaceListeners() { + for ((index, iface) in plaquesToIface.values.withIndex()){ + onClose(iface){ player, _ -> + scene?.end(fade = false) + player.globalData.readPlaques[index] = true + return@onClose true + } + + onOpen(iface) { player, component -> + scene = PlaqueCutscene(player, component) + scene?.start(hideMiniMap = false) + return@onOpen true + } + + on(iface) { player, _, _, buttonID, _, _ -> + // If thumbs up is clicked + if (buttonID == 2){ + scene?.incrementStage() + player.interfaceManager.closeChatbox() + } + return@on true + } + } + } + + class PlaqueCutscene(player: Player, val component: Component): Cutscene(player) { + + // Since the component does not know the door's location + // there needs to be some translation from player position + // to the door location. This is component -> rotation (dx, dy) + private val rotationMapping = mapOf( + 701 to listOf(-1, 0), + 703 to listOf(-1, 0), + 711 to listOf(-1, 0), + 695 to listOf(0, 1), + 312 to listOf(1, 0), + 706 to listOf(1, 0), + 698 to listOf(1, 0), + ) + + override fun setup() { + setExit(player.location) + } + + override fun runStage(stage: Int) { + when (stage){ + 0 -> { + // Go to head height + moveCamera(player.location.localX, player.location.localY, 245, speed = 50) + // Spin in the right direction + rotateCamera(player.location.localX + rotationMapping[component.id]!![0], + player.location.localY + rotationMapping[component.id]!![1], + 245, speed = 50) + } + 1 -> { + resetCamera() + } + } + } + + } + + } + + } diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyPlugin.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyPlugin.java deleted file mode 100644 index f286c6058..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyPlugin.java +++ /dev/null @@ -1,211 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import core.game.component.CloseEvent; -import core.game.component.Component; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.game.node.scenery.Scenery; -import core.game.world.map.Location; -import core.net.packet.PacketRepository; -import core.net.packet.context.CameraContext; -import core.net.packet.context.CameraContext.CameraType; -import core.net.packet.out.CameraViewPacket; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.plugin.ClassScanner; - -/** - * @author Tyler Telis - */ -@Initializable -public class StrongHoldOfPlayerSafetyPlugin implements Plugin { - - /** - * when u pull back the poster and the dialogue pops up - * you get teleported to this map tile: [3140, 4230, 2] - */ - - /** - * The jail object ids. - */ - public static final int JAIL_ENTRANCE_ID_ENTER = 29603, JAIL_ENTRANCE_LEAVE = 29602, JAIL_STAIRS_UP = 29589, JAIL_STAIRS_DOWN = 29592; - - /** - * The guard NPC id. - */ - public static final int GUARD_NPC_ID = 7142; - - /** - * The test item id. - */ - public static final int TEST_PAPER_ITEM_ID = 12626; - - /** - * The jail {@code Location}'s - */ - public static final Location JAIL_ENTRANCE_LOCATION_ENTER = Location.create(3082, 4229, 0), JAIL_ENTRANCE_LOCATION_LEAVE = Location.create(3074, 3456, 0), JAIL_UP_STAIRS = Location.create(3083, 3452, 0), JAIL_DOWN_STAIRS = Location.create(3086, 4247, 0); - - @Override - public Plugin newInstance(Object object) throws Throwable { - ClassScanner.definePlugin(new PSOptionHandler()); - ClassScanner.definePlugin(new GuardDialoguePlugin()); - ClassScanner.definePlugin(new PlayerSafetyTest()); - ClassScanner.definePlugin(new ProfessorHenryDialogue()); - return this; - } - - @Override - public Object fireEvent(String identifier, Object... object) { - return null; - } - - public enum JailPlaques { - - /** - * This sneaky gublinch wanted to set up a webcam conversation with a - * player! The player refused and sensibly used the Report Abuse button - * to enable us to catch him. - */ - PLAQUE_1(29599, 312), - - /** - * This naughty gublinchette gave a player her email address. The wise - * player hit the Report Abuse button straight away, allowing us to - * catch her! - */ - PLAQUE_2(29598, 695), - - /** - * This evil gublinch asked a younger player where she went to school. - * The player was smart enough to not tell the gublinch and report him - * instead. - */ - PLAQUE_3(29597, 711), - - /** - * This vile gublinchette was asking a player for his home address. The - * clever player didn't give her their address, but used the Report - * Abuse button to report her instead. - */ - PLAQUE_4(29596, 703), - - /** - * This sly gublinch wanted to meet one of his player friends in the - * real world. The player obviously refused and reported him straight - * away. - */ - PLAQUE_5(29600, 706), - - /** - * This cheeky gublinch claimed to be a Jagex Moderator! He was reported - * straight away and dealt with. - */ - PLAQUE_6(29601, 698), - - /** - * This wretched gublinch was asking a player for his telephone number. - * The player helped us catch him by refusing to give their information - * away and reporting the gublinch straight away! - */ - PLAQUE_7(29595, 701); - - /** - * The object id & interface id. - */ - private int objectId, interfaceId; - - /** - * Constructs a new {@code JailPlaques} instance. - * @param objectId The object id of the jail plague. - * @param interfaceId The interface id to send on the chat box. - */ - private JailPlaques(int objectId, int interfaceId) { - this.objectId = objectId; - this.interfaceId = interfaceId; - } - - /** - * Gets the object id. - * @return objectId. - */ - public int getObjectId() { - return objectId; - } - - /** - * Gets the interface id. - * @return interfaceId. - */ - public int getInterfaceId() { - return interfaceId; - } - - /** - * Gets the value of the jail-plaque. - * @return The ordinal. - */ - public int value() { - return ordinal(); - } - - /** - * Sends the jail-plague interface. - * @param player The {@code Player} instance. - */ - public void read(Player player, Scenery object) { - int x = object.getLocation().getX(); - int y = object.getLocation().getY(); - int rotationX = x; - int rotationY = y; - Component component = new Component(interfaceId); - PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.SET, x, y, 245, 1, 50)); - PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, rotationX, rotationY, 245, 1, 50)); - player.getInterfaceManager().openChatbox(component); - component.setCloseEvent(new CloseEvent() { - - @Override - public boolean close(Player player, Component c) { - PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 0, 1, 100)); - if (!player.getSavedData().getGlobalData().getReadPlaques()[value()]) { - player.getSavedData().getGlobalData().getReadPlaques()[value()] = true; - } - return true; - } - - }); - component.setPlugin(new ComponentPlugin() { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - return this; - } - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - switch (button) { - case 2: - player.getInterfaceManager().closeChatbox(); - player.getSavedData().getGlobalData().getReadPlaques()[value()] = true; - return true; - } - return false; - } - - }); - } - } - - /** - * Find the {@link JailPlaques} instance for the object id. - * @param objectId The object id. - * @return The {@link JailPlaques} instance. - */ - public static JailPlaques forId(int objectId) { - for (JailPlaques plaque : JailPlaques.values()) { - if (plaque.getObjectId() == objectId) { - return plaque; - } - } - return null; - } -} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/Student.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/Student.java deleted file mode 100644 index a9977779a..000000000 --- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/Student.java +++ /dev/null @@ -1,30 +0,0 @@ -package content.region.misthalin.barbvillage.stronghold.playersafety; - -import core.cache.def.impl.NPCDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Handles interactions with exam center students, to address #106 - * @author ceik - */ -@Initializable -public class Student extends OptionHandler { - public Plugin newInstance(Object arg) throws Throwable { - NPCDefinition.forId(7153).getHandlers().put("option:talk-to",this); - NPCDefinition.forId(7154).getHandlers().put("option:talk-to",this); - NPCDefinition.forId(7155).getHandlers().put("option:talk-to",this); - NPCDefinition.forId(7156).getHandlers().put("option:talk-to",this); - NPCDefinition.forId(7157).getHandlers().put("option:talk-to",this); - return this; - } - public final boolean handle(Player player, Node node, String options){ - if(options.equals("talk-to")){ - player.getPacketDispatch().sendMessage("This student is trying to focus on their work."); - } - return true; - } -} diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt index a13b7c858..e8310e992 100644 --- a/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt @@ -5,6 +5,7 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -70,8 +71,9 @@ class ChemicalsBook : InteractionListener { } override fun defineListeners() { - on(Items.BOOK_ON_CHEMICALS_711, IntType.ITEM, "read") { player, _ -> + on(Items.BOOK_ON_CHEMICALS_711, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt index f60eca32f..d9f94dfba 100644 --- a/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.digsite.dialogue +import content.data.Quests import content.region.misthalin.digsite.quest.thedigsite.TheDigSite import core.api.* import core.game.dialogue.* @@ -29,7 +30,7 @@ class ExaminerDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(TheDigSite.questName, 100) + b.onQuestStages(Quests.THE_DIG_SITE, 100) .npcl(FacialExpression.HAPPY, "Hello there! My colleague tells me you helped to uncover a hidden altar to the god Zaros.") .npcl(FacialExpression.HAPPY, "A great scholar and archaeologist indeed! Good health and prosperity to you.") .options().let { optionBuilder -> @@ -43,10 +44,21 @@ class ExaminerDialogueFile : DialogueBuilderFile() { } } - b.onQuestStages(TheDigSite.questName, 6,7,8,9,10,11,12) - .npcl(FacialExpression.FRIENDLY, "Well, what are you doing here? Get digging!") + b.onQuestStages(Quests.THE_DIG_SITE, 6, 7, 8, 9, 10, 11, 12) + .branch { player -> if(inInventory(player, Items.TROWEL_676)) { 0 } else { 1 } } + .let{ branch -> + branch.onValue(0) + .npcl(FacialExpression.FRIENDLY, "Well, what are you doing here? Get digging!") + .end() + branch.onValue(1) + .playerl("I have lost my trowel.") + .npcl("Deary me. That was a good one as well. It's a good job I have another. Here you go...") + .endWith { _, player -> + addItemOrDrop(player, Items.TROWEL_676) + } + } - b.onQuestStages(TheDigSite.questName, 5) + b.onQuestStages(Quests.THE_DIG_SITE, 5) .playerl(FacialExpression.FRIENDLY, "Hello.") .npcl(FacialExpression.FRIENDLY, "Ah, hello again.") .options().let { optionBuilder -> @@ -169,8 +181,8 @@ class ExaminerDialogueFile : DialogueBuilderFile() { .playerl(FacialExpression.FRIENDLY, "I can dig wherever I want now!") .npcl(FacialExpression.FRIENDLY, "Perhaps you should use your newfound skills to find an artefact on the digsite that will impress the archaeological expert.") .endWith { _, player -> - if(getQuestStage(player, TheDigSite.questName) == 5) { - setQuestStage(player, TheDigSite.questName, 6) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 5) { + setQuestStage(player, Quests.THE_DIG_SITE, 6) } openInterface(player, 444) setInterfaceText(player, player.username, 444, 5) @@ -178,7 +190,7 @@ class ExaminerDialogueFile : DialogueBuilderFile() { } - b.onQuestStages(TheDigSite.questName, 4) + b.onQuestStages(Quests.THE_DIG_SITE, 4) .playerl(FacialExpression.FRIENDLY, "Hello.") .npcl(FacialExpression.FRIENDLY, "Hello again.") .options().let { optionBuilder -> @@ -301,8 +313,8 @@ class ExaminerDialogueFile : DialogueBuilderFile() { } .npcl(FacialExpression.FRIENDLY, "You have now passed the Earth Sciences level 2 intermediate exam. Here is your certificate. Of course, you'll want to get studying for your next exam now!") .endWith { _, player -> - if(getQuestStage(player, TheDigSite.questName) == 4) { - setQuestStage(player, TheDigSite.questName, 5) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 4) { + setQuestStage(player, Quests.THE_DIG_SITE, 5) } openInterface(player, 441) setInterfaceText(player, player.username, 441, 5) @@ -310,13 +322,13 @@ class ExaminerDialogueFile : DialogueBuilderFile() { } - b.onQuestStages(TheDigSite.questName, 1,2,3) + b.onQuestStages(Quests.THE_DIG_SITE, 1, 2, 3) // This is kinda messy due to the dialogue being reused in different stages. .branch { player -> - if (getQuestStage(player, TheDigSite.questName) == 2 && !inInventory(player, Items.SEALED_LETTER_683)){ + if (getQuestStage(player, Quests.THE_DIG_SITE) == 2 && !inInventory(player, Items.SEALED_LETTER_683)){ return@branch 1 // Reuse quest stage 1 if sealed letter is not in inventory. } - return@branch getQuestStage(player, TheDigSite.questName) + return@branch getQuestStage(player, Quests.THE_DIG_SITE) } .let{ branch -> val continuePath = b.placeholder() @@ -360,8 +372,8 @@ class ExaminerDialogueFile : DialogueBuilderFile() { if (inInventory(player, Items.SEALED_LETTER_683)) { removeItem(player, Items.SEALED_LETTER_683) } - if(getQuestStage(player, TheDigSite.questName) == 2) { - setQuestStage(player, TheDigSite.questName, 3) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 2) { + setQuestStage(player, Quests.THE_DIG_SITE, 3) } } .npcl(FacialExpression.NEUTRAL, "Good, good. We will begin the exam...") @@ -481,8 +493,8 @@ class ExaminerDialogueFile : DialogueBuilderFile() { .endWith { _, player -> // Because of onQuestStages and onPredicate, changing quest stage before the dialogue finishes breaks the flow. // As every stage, the onQuestStages and onPredicate functions are ran, so changing the values will switch out the stages. - if(getQuestStage(player, TheDigSite.questName) == 3) { - setQuestStage(player, TheDigSite.questName, 4) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 3) { + setQuestStage(player, Quests.THE_DIG_SITE, 4) } openInterface(player, 440) setInterfaceText(player, player.username, 440, 5) @@ -511,8 +523,8 @@ class ExaminerDialogueFile : DialogueBuilderFile() { .npcl(FacialExpression.FRIENDLY, "He's also a very busy man, so I write the letters and he justs stamps them if he approves.") .playerl(FacialExpression.FRIENDLY, "Oh, I see. I'll ask him if he'll approve me, and bring my stamped letter back here. Thanks.") .endWith { _, player -> - if(getQuestStage(player, TheDigSite.questName) == 0) { - setQuestStage(player, TheDigSite.questName, 1) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 0) { + setQuestStage(player, Quests.THE_DIG_SITE, 1) } } optionBuilder.option_playerl("Interesting...") diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt index 43001efaf..64af6e116 100644 --- a/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt @@ -1,6 +1,6 @@ package content.region.misthalin.digsite.dialogue -import content.region.misthalin.digsite.quest.thedigsite.TheDigSite +import content.data.Quests import core.api.* import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -13,7 +13,7 @@ import org.rs09.consts.NPCs @Initializable class ResearcherDialogue (player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { - if (isQuestComplete(player, TheDigSite.questName)){ + if (isQuestComplete(player, Quests.THE_DIG_SITE)){ when (stage) { START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Hello there. What are you doing here?").also { stage++ } 1 -> playerl(FacialExpression.FRIENDLY, "Just looking around at the moment.").also { stage++ } diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt index 6672f61aa..3f4ea3d0e 100644 --- a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.digsite.quest.thedigsite +import content.region.desert.quest.deserttreasure.DesertTreasure import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile @@ -8,6 +9,7 @@ import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player import core.plugin.Initializable +import org.rs09.consts.Items @Initializable @@ -26,6 +28,64 @@ class ArchaeologicalExpertDialogue (player: Player? = null) : DialoguePlugin(pla class ArchaeologicalExpertDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { + b.onQuestStages(DesertTreasure.questName, 4,5,6,7,8,9,10,11,12,13,14,15,100) + .npc("Hello again.", "Was that translation any use to Asgarnia?") + .playerl("I think it was, thanks!") + .end() + + b.onQuestStages(DesertTreasure.questName, 3) + .branch { player -> + return@branch if (inInventory(player, Items.TRANSLATION_4655)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npc("Hello again.", "Was that translation any use to Asgarnia?") + .playerl(FacialExpression.SUSPICIOUS, "I, uh, kind of didn't take it to him yet...") + .npc(FacialExpression.THINKING, "Whyever not?", "You're the strangest delivery @g[boy,girl] I've ever met!") + .end() + branch.onValue(0) + .playerl("I lost that translation you gave me...") + .npcl("Oh, no matter, I mostly remember what it said anyway! Here you go!") + .endWith { _, player -> + addItemOrDrop(player, Items.TRANSLATION_4655) + } + } + b.onQuestStages(DesertTreasure.questName, 2) + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.TRANSLATION_4655) + } + .npcl("There you go, that book contains the sum of my translating ability. If you would be so kind as to take that back to Asgarnia, I think it will reassure him that he is on the") + .npcl("right track for a find of great archaeological importance!") + .playerl("Wow! You write really quickly don't you?") + .npcl("What can I say? It's a skill I picked up through my many years of taking field notes!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 2) { + setQuestStage(player, DesertTreasure.questName, 3) + } + } + + b.onQuestStages(DesertTreasure.questName, 1) + .playerl("Hello, are you Terry Balando?") + .npcl("That's right, who wants to know...?") + .npcl("Ah yes, I recognise you! You're the fellow who found that strange artefact about Zaros for the museum, aren't you? What can I do for you now?") + .playerl("That's right. I was in the desert down by the Bedabin Camp, and I found an archaeologist who asked me to deliver this to you.") + .npcl("You spoke to the legendary Asgarnia Smith??? Quickly, let me see what he had to give you! He is always at the forefront of archaeological breakthroughs!") + .betweenStage { df, player, _, _ -> + removeItem(player, Items.ETCHINGS_4654) // remove if exists + } + .playerl("So what does the inscription say? Anything interesting?") + .npcl("This... this is fascinating! These cuneiforms seem to predate even the settlement we are excavating here... Yes, yes, this is most interesting indeed!") + .playerl("Can you translate it for me?") + .npc("Well, I am not familiar with this particular language, but", "the similarities inherent in the pictographs seem to show", "a prevalent trend towards a syllabary consistent with", "the phonemes we have discovered in this excavation!") + .playerl("Um... So, can you translate it for me or not?") + .npcl("Well, unfortunately this is the only example of this particular language I have ever seen, but I might be able to make a rough translation, of sorts...") + .npcl("It might be slightly obscure on the finer details, but it should be good enough to understand the rough meaning of what was originally written. Please, just wait a moment, I will write up what I can") + .npcl("translate into a journal for you. Then you can take it back to Asgarnia, I think he will be extremely interested in the translation!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 1) { + setQuestStage(player, DesertTreasure.questName, 2) + } + } + // Fallback dialogue. b.onPredicate { player -> true } .playerl(FacialExpression.FRIENDLY, "Hello. Who are you?") diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt index cec1d1051..296e9fce0 100644 --- a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt @@ -1,10 +1,9 @@ package content.region.misthalin.digsite.quest.thedigsite -import content.region.misthalin.digsite.dialogue.ArchaeologistcalExpertUsedOnDialogueFile +import content.data.Quests import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile -import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.interaction.IntType import core.game.interaction.InteractionListener @@ -109,8 +108,8 @@ class ArchaeologicalExpertListenerDialogueFile(val it: Int) : DialogueBuilderFil if (removeItem(player, Items.ANCIENT_TALISMAN_681)) { addItemOrDrop(player, Items.INVITATION_LETTER_696) } - if(getQuestStage(player, TheDigSite.questName) == 6) { - setQuestStage(player, TheDigSite.questName, 7) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 6) { + setQuestStage(player, Quests.THE_DIG_SITE, 7) } } @@ -124,8 +123,8 @@ class ArchaeologicalExpertListenerDialogueFile(val it: Int) : DialogueBuilderFil .item(Items.GOLD_BAR_2357, "The expert gives you two gold bars as payment.") .endWith { _, player -> if (removeItem(player, Items.STONE_TABLET_699)) { - if(getQuestStage(player, TheDigSite.questName) == 11) { - finishQuest(player, TheDigSite.questName) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 11) { + finishQuest(player, Quests.THE_DIG_SITE) } } } diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt index 054541082..38830c490 100644 --- a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.digsite.quest.thedigsite +import content.data.Quests import core.api.* import core.game.dialogue.* import core.game.interaction.IntType @@ -64,8 +65,8 @@ class DigsiteWorkmanDialogueFile : DialogueBuilderFile() { .npc(FacialExpression.FRIENDLY, "I give permission... blah de blah... err. Okay, that's all in", "order, you may use the mineshaft now. I'll hang onto", "this scroll, shall I?") .endWith { _, player -> removeItem(player, Items.INVITATION_LETTER_696) - if(getQuestStage(player, TheDigSite.questName) == 7) { - setQuestStage(player, TheDigSite.questName, 8) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 7) { + setQuestStage(player, Quests.THE_DIG_SITE, 8) } } } diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt index 7e0764190..5ac84d0f5 100644 --- a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.digsite.quest.thedigsite +import content.data.Quests import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile @@ -28,10 +29,10 @@ class StudentGreenDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(TheDigSite.questName, 6,7,8,9,10,11,12,13,100) + b.onQuestStages(Quests.THE_DIG_SITE, 6, 7, 8, 9, 10, 11, 12, 13, 100) .npcl(FacialExpression.FRIENDLY, " Oh, hi again. News of your find has spread fast; you are quite famous around here now.") - b.onQuestStages(TheDigSite.questName, 5) + b.onQuestStages(Quests.THE_DIG_SITE, 5) .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "I need more help with the exam.") @@ -42,7 +43,7 @@ class StudentGreenDialogueFile : DialogueBuilderFile() { setAttribute(player, TheDigSite.attributeStudentGreenExam3ObtainAnswer, true) } - b.onQuestStages(TheDigSite.questName, 4) + b.onQuestStages(Quests.THE_DIG_SITE, 4) .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "I need more help with the exam.") @@ -52,7 +53,7 @@ class StudentGreenDialogueFile : DialogueBuilderFile() { .endWith { _, player -> setAttribute(player, TheDigSite.attributeStudentGreenExam2ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 3 && getAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, false)} .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "I need more help with the exam.") @@ -62,7 +63,7 @@ class StudentGreenDialogueFile : DialogueBuilderFile() { .endWith { _, player -> setAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 3 && getAttribute(player, TheDigSite.attributeStudentGreenExam1Talked, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentGreenExam1Talked, false)} .branch { player -> return@branch if (inInventory(player, Items.ANIMAL_SKULL_671)) { 1 } else { 0 } }.let{ branch -> @@ -86,7 +87,7 @@ class StudentGreenDialogueFile : DialogueBuilderFile() { } return@let branch } - b.onQuestStages(TheDigSite.questName, 3) + b.onQuestStages(Quests.THE_DIG_SITE, 3) .playerl(FacialExpression.FRIENDLY, "Hello there. Can you help me with the Earth Sciences exams at all?") .npcl(FacialExpression.FRIENDLY, "Well... Maybe I will if you help me with something.") .playerl(FacialExpression.FRIENDLY, "What's that?") @@ -127,7 +128,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 5 && getAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 5 && getAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, false)} .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "I am stuck on some more exam questions.") @@ -138,7 +139,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { setAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 5 && getAttribute(player, TheDigSite.attributeStudentPurpleExam3Talked, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 5 && getAttribute(player, TheDigSite.attributeStudentPurpleExam3Talked, false)} .branch { player -> return@branch if (inInventory(player, Items.OPAL_1609) || inInventory(player, Items.UNCUT_OPAL_1625)) { 1 } else { 0 } }.let{ branch -> @@ -170,7 +171,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { return@let branch } - b.onQuestStages(TheDigSite.questName, 5) + b.onQuestStages(Quests.THE_DIG_SITE, 5) .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "What, you want more help?") .playerl(FacialExpression.FRIENDLY, "Err... Yes please!") @@ -184,7 +185,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { setAttribute(player, TheDigSite.attributeStudentPurpleExam3Talked, true) } - b.onQuestStages(TheDigSite.questName, 4) + b.onQuestStages(Quests.THE_DIG_SITE, 4) .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "I am stuck on some more exam questions.") @@ -194,7 +195,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { .endWith { _, player -> setAttribute(player, TheDigSite.attributeStudentPurpleExam2ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 3 && getAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, false)} .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "I am stuck on some more exam questions.") @@ -204,7 +205,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { .endWith { _, player -> setAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 3 && getAttribute(player, TheDigSite.attributeStudentPurpleExam1Talked, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentPurpleExam1Talked, false)} .branch { player -> return@branch if (inInventory(player, Items.TEDDY_673)) { 1 } else { 0 } }.let{ branch -> @@ -229,7 +230,7 @@ class StudentPurpleDialogueFile : DialogueBuilderFile() { } return@let branch } - b.onQuestStages(TheDigSite.questName, 3) + b.onQuestStages(Quests.THE_DIG_SITE, 3) .playerl(FacialExpression.FRIENDLY, "Hello there. Can you help me with the Earth Sciences exams at all?") .npcl(FacialExpression.FRIENDLY, "I can if you help me...") .playerl(FacialExpression.FRIENDLY, "How can I do that?") @@ -266,7 +267,7 @@ class StudentBrownDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(TheDigSite.questName, 5) + b.onQuestStages(Quests.THE_DIG_SITE, 5) .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "There are more exam questions I'm stuck on.") @@ -277,7 +278,7 @@ class StudentBrownDialogueFile : DialogueBuilderFile() { setAttribute(player, TheDigSite.attributeStudentBrownExam3ObtainAnswer, true) } - b.onQuestStages(TheDigSite.questName, 4) + b.onQuestStages(Quests.THE_DIG_SITE, 4) .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "There are more exam questions I'm stuck on.") @@ -287,7 +288,7 @@ class StudentBrownDialogueFile : DialogueBuilderFile() { .endWith { _, player -> setAttribute(player, TheDigSite.attributeStudentBrownExam2ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 3 && getAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, false)} .playerl(FacialExpression.FRIENDLY, "Hello there.") .npcl(FacialExpression.FRIENDLY, "How's it going?") .playerl(FacialExpression.FRIENDLY, "There are more exam questions I'm stuck on.") @@ -297,7 +298,7 @@ class StudentBrownDialogueFile : DialogueBuilderFile() { .endWith { _, player -> setAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, true) } - b.onPredicate { player -> getQuestStage(player, TheDigSite.questName) == 3 && getAttribute(player, TheDigSite.attributeStudentBrownExam1Talked, false)} + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentBrownExam1Talked, false)} .playerl(FacialExpression.FRIENDLY, "Hello there. How's the study going?") .npcl(FacialExpression.FRIENDLY, "I'm getting there. Have you found my special cup yet?") .branch { player -> @@ -319,7 +320,7 @@ class StudentBrownDialogueFile : DialogueBuilderFile() { } return@let branch } - b.onQuestStages(TheDigSite.questName, 3) + b.onQuestStages(Quests.THE_DIG_SITE, 3) .playerl(FacialExpression.FRIENDLY, "Hello there. Can you help me with the Earth Sciences exams at all?") .npcl(FacialExpression.FRIENDLY, "I can't do anything unless I find my special cup.") .playerl(FacialExpression.FRIENDLY, "Your what?") diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt index a368c031d..a32e9f6f8 100644 --- a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt @@ -1,12 +1,12 @@ package content.region.misthalin.digsite.quest.thedigsite -import content.region.morytania.quest.creatureoffenkenstrain.CreatureOfFenkenstrain import core.api.* import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * The Dig Site Quest @@ -29,9 +29,8 @@ import org.rs09.consts.Items * 100 - Talked to expert after showing him the STONE_TABLET_699 */ @Initializable -class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { +class TheDigSite : Quest(Quests.THE_DIG_SITE, 47, 46, 2, 131, 0, 1, 9) { companion object { - const val questName = "The Dig Site" const val attributeStudentGreenExam1Talked = "/save:quest:thedigsite-studentgreenexam1talked" const val attributeStudentGreenExam1ObtainAnswer = "/save:quest:thedigsite-studentgreenexam1obtainanswer" const val attributeStudentPurpleExam1Talked = "/save:quest:thedigsite-studentpurpleexam1talked" @@ -83,7 +82,7 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { var line = 11 var stage = getStage(player) - var started = getQuestStage(player, questName) > 0 + var started = getQuestStage(player, Quests.THE_DIG_SITE) > 0 if(!started){ line++ @@ -93,6 +92,7 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { line(player, "Level 10 Agility", line++, hasLevelStat(player, Skills.AGILITY, 10)) line(player, "Level 10 Herblore", line++, hasLevelStat(player, Skills.HERBLORE, 10)) line(player, "Level 25 Thieving", line++, hasLevelStat(player, Skills.THIEVING, 25)) + limitScrolling(player, line, true) } else { line(player, "I should speak to an examiner about taking Earth Science", line++, true) line(player, "Exams.", line++, true) @@ -136,23 +136,23 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { line(player, "the exams.", line++) } if (stage >= 4 || getAttribute(player, attributeStudentBrownExam1Talked, false)) { - line(player, "I need to speak to the student in the brown top about the", line++, true) + line(player, "I need to speak to the student in the orange top about the", line++, true) line(player, "exams.", line++, true) } else if (stage >= 3) { - line(player, "I need to speak to the student in the brown top about the", line++) + line(player, "I need to speak to the student in the orange top about the", line++) line(player, "exams.", line++) } if (stage >= 4 || getAttribute(player, attributeStudentGreenExam1ObtainAnswer, false)) { line(player, "I have agreed to help the student in the green top.", line++, true) - line(player, "He has lost his animal skull and thinks he may have", line++, true) - line(player, "dropped it around the site. I need to find it and return", line++, true) - line(player, "it to him. Maybe one of the workmen has picked it up?", line++, true) + line(player, "He has lost his Animal Skull and thinks he may have", line++, true) + line(player, "dropped it around the digsite. I need to find it and return it", line++, true) + line(player, "to him. Maybe one of the workmen has picked it up?", line++, true) } else if (stage >= 3 && getAttribute(player, attributeStudentGreenExam1Talked, false)) { line(player, "I have agreed to help the student in the green top.", line++) - line(player, "He has lost his animal skull and thinks he may have", line++) - line(player, "dropped it around the site. I need to find it and return", line++) - line(player, "it to him. Maybe one of the workmen has picked it up?", line++) + line(player, "He has lost his !!Animal Skull?? and thinks he may have", line++) + line(player, "dropped it around the digsite. I need to find it and return it", line++) + line(player, "to him. Maybe one of the workmen has picked it up?", line++) } if (stage >= 4) { line(player, "I should talk to him to see if he can help with my exams.", line++, true) @@ -166,38 +166,36 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { if (stage >= 4 || getAttribute(player, attributeStudentPurpleExam1ObtainAnswer, false)) { line(player, "I have agreed to help the student in the purple skirt.", line++, true) - line(player, "She has lost her lucky teddy bear mascot and thinks she", line++, true) - line(player, "may have dropped it by the strange relic at the centre of", line++, true) - line(player, "the campus, maybe in a bush. I need to find it and return", line++, true) - line(player, "it to her.", line++, true) + line(player, "She has lost her Lucky Mascot and thinks she may have", line++, true) + line(player, "dropped it around the large urns on the digsite. I need to", line++, true) + line(player, "find it and return it to her.", line++, true) } else if (stage >= 3 && getAttribute(player, attributeStudentPurpleExam1Talked, false)) { line(player, "I have agreed to help the student in the purple skirt.", line++) - line(player, "She has lost her lucky teddy bear mascot and thinks she", line++) - line(player, "may have dropped it by the strange relic at the centre of", line++) - line(player, "the campus, maybe in a bush. I need to find it and return", line++) - line(player, "it to her.", line++) + line(player, "She has lost her !!Lucky Mascot?? and thinks she may have", line++) + line(player, "dropped it around the large urns on the digsite. I need to", line++) + line(player, "find it and return it to her.", line++) } if (stage >= 4) { line(player, "I should talk to her to see if she can help with my exams.", line++, true) - line(player, "She gave me an answer to one of the questions on the first", line++, true) - line(player, "exam.", line++, true) + line(player, "She gave me an answer to one of the questions on the", line++, true) + line(player, "first exam.", line++, true) } else if (stage >= 3 && getAttribute(player, attributeStudentPurpleExam1ObtainAnswer, false)) { line(player, "I should talk to her to see if she can help with my exams.", line++) - line(player, "She gave me an answer to one of the questions on the first", line++) - line(player, "exam.", line++) + line(player, "She gave me an answer to one of the questions on the", line++) + line(player, "first exam.", line++) } if (stage >= 4 || getAttribute(player, attributeStudentBrownExam1ObtainAnswer, false)) { - line(player, "I have agreed to help the student in the brown top.", line++, true) - line(player, "He has lost his special cup and thinks he may have dropped", line++, true) - line(player, "it while he was near the panning site, possibly in the", line++, true) - line(player, "water. I need to find it and return it.", line++, true) + line(player, "I have agreed to help the student in the orange top.", line++, true) + line(player, "He has lost his Special Cup and thinks he may have", line++, true) + line(player, "dropped it around the tents near the panning site. I need", line++, true) + line(player, "to find it and return it.", line++, true) } else if (stage >= 3 && getAttribute(player, attributeStudentBrownExam1Talked, false)) { - line(player, "I have agreed to help the student in the brown top.", line++) - line(player, "He has lost his special cup and thinks he may have dropped", line++) - line(player, "it while he was near the panning site, possibly in the", line++) - line(player, "water. I need to find it and return it.", line++) + line(player, "I have agreed to help the student in the orange top.", line++) + line(player, "He has lost his !!Special Cup?? and thinks he may have", line++) + line(player, "dropped it around the tents near the panning site. I need", line++) + line(player, "to find it and return it.", line++) } if (stage >= 4) { line(player, "I should talk to him to see if he can help with my exams.", line++, true) @@ -226,11 +224,11 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { } if (stage >= 5) { - line(player, "I need to study for my second exam. Perhaps the students", line++, true) - line(player, "on the site can help?", line++, true) + line(player, "I need to study for my second exam. Perhaps the three", line++, true) + line(player, "students on the digsite can help me again?", line++, true) } else if (stage >= 4) { - line(player, "I need to study for my second exam. Perhaps the students", line++) - line(player, "on the site can help?", line++) + line(player, "I need to study for my second exam. Perhaps the three", line++) + line(player, "students on the digsite can help me again?", line++) } if (stage >= 5 || getAttribute(player, attributeStudentGreenExam2ObtainAnswer, false)) { line(player, "I need to speak to the student in the green top about the", line++, true) @@ -241,16 +239,16 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { } if (stage >= 5 || getAttribute(player, attributeStudentPurpleExam2ObtainAnswer, false)) { line(player, "I need to speak to the student in the purple skirt about", line++, true) - line(player, "the exams. 2 ", line++, true) + line(player, "the exams.", line++, true) } else if (stage >= 4) { line(player, "I need to speak to the student in the purple skirt about", line++) line(player, "the exams.", line++) } if (stage >= 5 || getAttribute(player, attributeStudentBrownExam2ObtainAnswer, false)) { - line(player, "I need to speak to the student in the brown top about the", line++, true) + line(player, "I need to speak to the student in the orange top about the", line++, true) line(player, "exams.", line++, true) } else if (stage >= 4) { - line(player, "I need to speak to the student in the brown top about the", line++) + line(player, "I need to speak to the student in the orange top about the", line++) line(player, "exams.", line++) } if (stage >= 5) { @@ -269,11 +267,11 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { } if (stage >= 6) { - line(player, "I need to study for my third exam. Perhaps the students", line++, true) - line(player, "on the site can help?", line++, true) + line(player, "I should research for my third exam. Perhaps the students", line++, true) + line(player, "can help me again?", line++, true) } else if (stage >= 5) { - line(player, "I need to study for my third exam. Perhaps the students", line++) - line(player, "on the site can help?", line++) + line(player, "I should research for my third exam. Perhaps the students", line++) + line(player, "can help me again?", line++) } if (stage >= 6 || getAttribute(player, attributeStudentGreenExam3ObtainAnswer, false)) { line(player, "I need to speak to the student in the green top about the", line++, true) @@ -284,7 +282,7 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { } if (stage >= 6 || getAttribute(player, attributeStudentPurpleExam3Talked, false)) { line(player, "I need to speak to the student in the purple skirt about", line++, true) - line(player, "the exams. 3", line++, true) + line(player, "the exams.", line++, true) } else if (stage >= 5) { line(player, "I need to speak to the student in the purple skirt about", line++) line(player, "the exams.", line++) @@ -295,10 +293,10 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { line(player, "I need to bring her an Opal.", line++) } if (stage >= 6 || getAttribute(player, attributeStudentBrownExam3ObtainAnswer, false)) { - line(player, "I need to speak to the student in the brown top about the", line++, true) + line(player, "I need to speak to the student in the orange top about the", line++, true) line(player, "exams.", line++, true) } else if (stage >= 5) { - line(player, "I need to speak to the student in the brown top about the", line++) + line(player, "I need to speak to the student in the orange top about the", line++) line(player, "exams.", line++) } if (stage >= 6) { @@ -364,6 +362,7 @@ class TheDigSite : Quest("The Dig Site", 47, 46, 2, 131, 0, 1, 9) { line++ line(player,"QUEST COMPLETE!", line) } + limitScrolling(player, line, false) } } diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt index c6745cf98..a79a331bd 100644 --- a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt @@ -1,5 +1,6 @@ package content.region.misthalin.digsite.quest.thedigsite +import content.data.Quests import content.global.skill.thieving.ThievingListeners import core.api.* import core.api.utils.PlayerCamera @@ -162,7 +163,7 @@ class TheDigSiteListeners : InteractionListener { return@on true } sendMessage(player, "You attempt to pick the workman's pocket...") - if (getQuestStage(player, TheDigSite.questName) == 3) { + if (getQuestStage(player, Quests.THE_DIG_SITE) == 3) { player.animator.animate(ThievingListeners.PICKPOCKET_ANIM) val rollOutcome = ThievingListeners.pickpocketRoll(player, 84.0, 240.0, workmanPickpocketingTable) if (rollOutcome != null) { @@ -363,7 +364,7 @@ class TheDigSiteListeners : InteractionListener { val level3DigRight = ZoneBorders(3370, 3437, 3377, 3442) val level3DigLeft = ZoneBorders(3350, 3404, 3357, 3412) if (level3DigRight.insideBorder(player.location) || level3DigLeft.insideBorder(player.location)) { - if (getQuestStage(player, TheDigSite.questName) >= 6) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 6) { queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> when (stage) { 0 -> { @@ -392,7 +393,7 @@ class TheDigSiteListeners : InteractionListener { val level2Dig = ZoneBorders(3350, 3424, 3363, 3430) if (level2Dig.insideBorder(player.location)) { - if (getQuestStage(player, TheDigSite.questName) >= 5) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 5) { queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> when (stage) { 0 -> { @@ -422,7 +423,7 @@ class TheDigSiteListeners : InteractionListener { val level1DigCentre = ZoneBorders(3360, 3402, 3363, 3414) val level1DigRight = ZoneBorders(3367, 3403, 3372, 3414) if (level1DigCentre.insideBorder(player.location) || level1DigRight.insideBorder(player.location)) { - if (getQuestStage(player, TheDigSite.questName) >= 4) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 4) { queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> when (stage) { 0 -> { @@ -452,7 +453,7 @@ class TheDigSiteListeners : InteractionListener { val trainingDigLeft = ZoneBorders(3352, 3396, 3357, 3400) val trainingDigRight = ZoneBorders(3367, 3397, 3372, 3400) if (trainingDigLeft.insideBorder(player.location) || trainingDigRight.insideBorder(player.location)) { - if (getQuestStage(player, TheDigSite.questName) >= 3) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 3) { queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> when (stage) { 0 -> { @@ -483,12 +484,12 @@ class TheDigSiteListeners : InteractionListener { // 8: North East Winch goes to Doug Deeping on(Scenery.WINCH_2350, SCENERY, "operate") { player, _ -> - if (getQuestStage(player, TheDigSite.questName) >= 11) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 11) { sendMessage(player, "You try to climb down the rope...") sendMessage(player, "You lower yourself into the shaft...") teleport(player, Location(3369, 9763)) sendMessage(player, "You find yourself in a cavern...") - } else if (getQuestStage(player, TheDigSite.questName) >= 8) { + } else if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { if (getAttribute(player, TheDigSite.attributeRopeNorthEastWinch, false)) { sendMessage(player, "You try to climb down the rope...") sendMessage(player, "You lower yourself into the shaft...") @@ -520,7 +521,7 @@ class TheDigSiteListeners : InteractionListener { // 8: Tie rope to winch onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.WINCH_2350) { player, used, with -> if (removeItem(player, used)) { - if (getQuestStage(player, TheDigSite.questName) >= 8) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { setAttribute(player, TheDigSite.attributeRopeNorthEastWinch, true) sendMessage(player, "You tie the rope to the bucket.") } else { @@ -545,12 +546,12 @@ class TheDigSiteListeners : InteractionListener { // 8: West Winch goes to Skeletons, Explosion and Stone Tablet on(Scenery.WINCH_2351, SCENERY, "operate") { player, _ -> - if (getQuestStage(player, TheDigSite.questName) >= 11) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 11) { sendMessage(player, "You try to climb down the rope...") sendMessage(player, "You lower yourself into the shaft...") teleport(player, Location(3352, 9753)) sendMessage(player, "You find yourself in a cavern...") - } else if (getQuestStage(player, TheDigSite.questName) >= 8) { + } else if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { if (getAttribute(player, TheDigSite.attributeRopeWestWinch, false)) { sendMessage(player, "You try to climb down the rope...") sendMessage(player, "You lower yourself into the shaft...") @@ -581,7 +582,7 @@ class TheDigSiteListeners : InteractionListener { // 8: Tie rope to winch onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.WINCH_2351) { player, used, with -> if (removeItem(player, used)) { - if (getQuestStage(player, TheDigSite.questName) >= 8) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { setAttribute(player, TheDigSite.attributeRopeWestWinch, true) sendMessage(player, "You tie the rope to the bucket.") } else { @@ -614,14 +615,14 @@ class TheDigSiteListeners : InteractionListener { // 8: Investigating brick. Transitions to stage 9. on(Scenery.BRICK_2362, SCENERY, "search") { player, _ -> - if(getQuestStage(player, TheDigSite.questName) == 8) { + if(getQuestStage(player, Quests.THE_DIG_SITE) == 8) { sendPlayerDialogue(player, "Hmmm, there's a room past these bricks. If I could move them out of the way then I could find out what's inside. Maybe there's someone around here who can help...", FacialExpression.THINKING) - setQuestStage(player, TheDigSite.questName, 9) + setQuestStage(player, Quests.THE_DIG_SITE, 9) } - if(getQuestStage(player, TheDigSite.questName) == 9) { + if(getQuestStage(player, Quests.THE_DIG_SITE) == 9) { sendPlayerDialogue(player, "Hmmm, there's a room past these bricks. If I could move them out of the way then I could find out what's inside. Maybe there's someone around here who can help...", FacialExpression.THINKING) } - if(getQuestStage(player, TheDigSite.questName) == 10) { + if(getQuestStage(player, Quests.THE_DIG_SITE) == 10) { sendPlayerDialogue(player, "The brick is covered with the chemicals I made.", FacialExpression.THINKING) } return@on true @@ -749,12 +750,12 @@ class TheDigSiteListeners : InteractionListener { // 8/9: Pouring CHEMICAL_COMPOUND_707 on brick. Transitions to stage 10. onUseWith(SCENERY, Items.CHEMICAL_COMPOUND_707, Scenery.BRICK_2362) { player, used, with -> - if (getQuestStage(player, TheDigSite.questName) == 9) { + if (getQuestStage(player, Quests.THE_DIG_SITE) == 9) { if(removeItem(player, used)) { addItemOrDrop(player, Items.VIAL_229) sendMessage(player, "You pour the compound over the bricks...") sendPlayerDialogue(player, "Ok, the mixture is all over the bricks. I need some way to ignite this compound.", FacialExpression.THINKING) - setQuestStage(player, TheDigSite.questName, 10) + setQuestStage(player, Quests.THE_DIG_SITE, 10) } } return@onUseWith true @@ -762,8 +763,8 @@ class TheDigSiteListeners : InteractionListener { // 10: Lighting brick. Transitions to stage 11. onUseWith(SCENERY, Items.TINDERBOX_590, Scenery.BRICK_2362) { player, used, with -> - if(getQuestStage(player, TheDigSite.questName) == 10) { - setQuestStage(player, TheDigSite.questName, 11) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 10) { + setQuestStage(player, Quests.THE_DIG_SITE, 11) lock(player, 15) queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> when (stage) { @@ -825,43 +826,53 @@ class TheDigSiteListeners : InteractionListener { } on(Items.UNIDENTIFIED_LIQUID_702, ITEM, "drop") { player, node -> - removeItem(player, node) - impact(player, 25) - sendChat(player, "Ow! The liquid exploded!") - sendMessage(player, "You were injured by the burning liquid.") - return@on true + if (removeItem(player, node)) { + impact(player, 25) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + return@on false } on(Items.NITROGLYCERIN_703, ITEM, "drop") { player, node -> - removeItem(player, node) - impact(player, 35) - sendChat(player, "Ow! The nitroglycerin exploded!") - sendMessage(player, "You were injured by the burning liquid.") - return@on true + if (removeItem(player, node)) { + impact(player, 35) + sendChat(player, "Ow! The nitroglycerin exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + return@on false } on(Items.MIXED_CHEMICALS_705, ITEM, "drop") { player, node -> - removeItem(player, node) - impact(player, 45) - sendChat(player, "Ow! The liquid exploded!") - sendMessage(player, "You were injured by the burning liquid.") - return@on true + if (removeItem(player, node)) { + impact(player, 45) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + return@on false } on(Items.MIXED_CHEMICALS_706, ITEM, "drop") { player, node -> - removeItem(player, node) - impact(player, 55) - sendChat(player, "Ow! The liquid exploded!") - sendMessage(player, "You were injured by the burning liquid.") - return@on true + if (removeItem(player, node)) { + impact(player, 55) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + return@on false } on(Items.CHEMICAL_COMPOUND_707, ITEM, "drop") { player, node -> - removeItem(player, node) - impact(player, 65) - sendChat(player, "Ow! The liquid exploded!") - sendMessage(player, "You were injured by the burning liquid.") - return@on true + if (removeItem(player, node)) { + impact(player, 65) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + return@on false } // Scenery not tied to quest diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt index efdb1a9be..a05bfeb93 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.dialogue +import content.data.Quests import core.game.component.Component import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -23,7 +24,7 @@ class MistagDialogue (player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - val ltStage = player.questRepository.getStage("Lost Tribe") + val ltStage = player.questRepository.getStage(Quests.THE_LOST_TRIBE) if(args.size > 1 && args[1] == "greeting"){ npc("A human knows ancient greeting?") diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt index 6813ad0b9..4d6feec03 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt @@ -29,7 +29,7 @@ class CaveGoblinMinerNPC(id: Int = 0, location: Location? = null) : AbstractNPC( mining = (id > 2074) if(properties.combatPulse.isAttacking && mining){ - transform(id - 6) + transformWithHpCarryover(id - 6) this.isWalks = true this.walkRadius = 4 this.isNeverWalks = false diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt index 93bb1f871..c71192c37 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.api.* import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -48,7 +49,7 @@ class DukeHoracioTLTDialogue(val questStage: Int) : DialogueFile() { "this mystery. If there is a blocked tunnel then perhaps", "you should try to un-block it." ) - player!!.questRepository.getQuest("Lost Tribe").setStage(player, 30) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 30) stage = END_DIALOGUE } } @@ -108,7 +109,7 @@ class DukeHoracioTLTDialogue(val questStage: Int) : DialogueFile() { "brooch. The librarian in Varrock might be able to help", "identify the symbol." ) - player!!.questRepository.getQuest("Lost Tribe").setStage(player, 40) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 40) stage = END_DIALOGUE } } @@ -140,7 +141,7 @@ class DukeHoracioTLTDialogue(val questStage: Int) : DialogueFile() { player!!.name.capitalize() + ", I would still like you to find out more", "about this tribe. It cannot hurt to know one's enemy." ) - player!!.questRepository.getQuest("Lost Tribe").setStage(player, 45) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 45) stage = END_DIALOGUE } } @@ -169,7 +170,7 @@ class DukeHoracioTLTDialogue(val questStage: Int) : DialogueFile() { 4 -> { npc("Unless it is returned, I am afraid I will have no option", "but war.") - player!!.questRepository.getQuest("Lost Tribe").setStage(player, 47) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 47) stage = END_DIALOGUE } } @@ -216,7 +217,7 @@ class DukeHoracioTLTDialogue(val questStage: Int) : DialogueFile() { "their leader to sign it." ) addItemOrDrop(player!!, Items.PEACE_TREATY_5012) - player!!.questRepository.getQuest("Lost Tribe").setStage(player, 50) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 50) setVarbit(player!!, 532, 9, true) stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt index 57c14a8f0..d6d5ed9ab 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.game.component.Component import core.game.component.ComponentDefinition import core.game.component.ComponentPlugin @@ -23,11 +24,11 @@ class HistoryOfTheGoblinRace : ComponentPlugin() { player ?: return super.open(player, component) player.packetDispatch.sendInterfaceConfig(183,17,true) - val qstage = player.questRepository.getQuest("Lost Tribe").getStage(player) + val qstage = player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) component?.setCloseEvent { player, c -> if(qstage == 42 || qstage == 41 ) { player.dialogueInterpreter.sendDialogues(player, FacialExpression.THINKING, "Hey... The symbol of the 'Dorgeshuun' tribe looks just", "like the symbol on the brooch I found.") - player.questRepository.getQuest("Lost Tribe").setStage(player, 43) + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 43) } player.removeAttribute("hgr-index") true diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt index fec111418..2bbcda87a 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt @@ -8,13 +8,14 @@ import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items import core.api.* +import content.data.Quests @Initializable /** * Represents the lost tribe quest and quest journal * @author Ceikry */ -class LostTribe : Quest("Lost Tribe",84,83,1) { +class LostTribe : Quest(Quests.THE_LOST_TRIBE,84,83,1) { override fun newInstance(`object`: Any?): Quest { return this } @@ -27,8 +28,8 @@ class LostTribe : Quest("Lost Tribe",84,83,1) { line(player,"I can start this quest by speaking to !!Sigmund?? in !!Lumbridge??",line++) line(player,"!!Castle.??",line++) line(player,"I must have completed:",line++) - line(player,"Rune Mysteries",line++,player?.questRepository?.isComplete("Rune Mysteries") == true) - line(player,"Goblin Diplomacy",line++,player?.questRepository?.isComplete("Goblin Diplomacy") == true) + line(player,"Rune Mysteries" ,line++,player?.questRepository?.isComplete(Quests.RUNE_MYSTERIES) == true) + line(player,"Goblin Diplomacy" ,line++,player?.questRepository?.isComplete(Quests.GOBLIN_DIPLOMACY) == true) line(player,"and have:",line++) line(player,"Level 17 mining",line++,player.skills.getLevel(Skills.MINING) >= 17) line(player,"Level 13 agility",line++,player.skills.getLevel(Skills.AGILITY) >= 13) diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt index a9413b011..f155df3f5 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.api.animate import core.api.face import core.game.activity.Cutscene @@ -105,7 +106,7 @@ class LostTribeCutscene(player: Player) : Cutscene(player) { } 19 -> { end { - player.questRepository.getQuest("Lost Tribe").finish(player) + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).finish(player) } } } diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt index 53c5cdf1e..de266e188 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.api.addItemOrDrop import core.cache.def.impl.ItemDefinition import core.cache.def.impl.NPCDefinition @@ -12,6 +13,7 @@ import core.game.node.item.Item import core.plugin.Initializable import core.plugin.Plugin import org.rs09.consts.Items +import core.api.* private val BOOK = Item(Items.GOBLIN_SYMBOL_BOOK_5009) @Initializable @@ -37,9 +39,10 @@ class LostTribeOptionHandler : OptionHandler(){ node ?: return false when(node.id){ 5008 -> player.interfaceManager.open(Component(50)) - 5009 -> player.interfaceManager.open(Component(183)) + 5009 -> player.interfaceManager.open(Component(183)).also { storeBookInHouse(player, node) } 6916 -> { - if(!player.inventory.containsItem(BOOK) && !player.bank.containsItem(BOOK) && player.questRepository.getQuest("Lost Tribe").getStage(player) >= 41){ + if(!player.inventory.containsItem(BOOK) && !player.bank.containsItem(BOOK) && player.questRepository.getQuest( + Quests.THE_LOST_TRIBE).getStage(player) >= 41){ player.dialogueInterpreter.sendDialogue("'A History of the Goblin Race.' This must be it.") player.inventory.add(BOOK) } else { @@ -47,10 +50,10 @@ class LostTribeOptionHandler : OptionHandler(){ } } 6911 -> { - if(!player.inventory.containsItem(Item(Items.SILVERWARE_5011)) && player.questRepository.getQuest("Lost Tribe").getStage(player) == 48){ + if(!player.inventory.containsItem(Item(Items.SILVERWARE_5011)) && player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 48){ player.dialogueInterpreter.sendItemMessage(Items.SILVERWARE_5011,"You find the missing silverware!") addItemOrDrop(player, Items.SILVERWARE_5011) - player.questRepository.getQuest("Lost Tribe").setStage(player,49) + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,49) } else { player.sendMessage("You find nothing.") } diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt index 8e01d2f77..8c637a839 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.game.component.Component import core.game.dialogue.FacialExpression import core.game.dialogue.DialogueFile @@ -20,7 +21,8 @@ class MistagLTDialogue(val isGreeting: Boolean, val questStage: Int) : DialogueF 4 -> player("Did you break in to the castle cellar?").also { stage++ } 5 -> npc("It was an accident. We were following a seam of iron","and suddenly we found ourselves in a room!").also { stage++ } 6 -> npc("We blocked up our tunnel behind us and ran back","here. Then we did what cave goblins always do when","there is a problem: we hid and hoped it would go away.").also { stage++ } - 7 -> npc("We meant no harm! Please tell the ruler of the above","people that we want to make peace.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest("Lost Tribe").setStage(player,46) } + 7 -> npc("We meant no harm! Please tell the ruler of the above","people that we want to make peace.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest( + Quests.THE_LOST_TRIBE).setStage(player,46) } } } @@ -32,7 +34,7 @@ class MistagLTDialogue(val isGreeting: Boolean, val questStage: Int) : DialogueF 2 -> player("Did you break in to the castle cellar?").also { stage++ } 3 -> npc("It was an accident. We were following a seam of iron","and suddenly we found ourselves in a room!").also { stage++ } 4 -> npc("We blocked up our tunnel behind us and ran back","here. Then we did what cave goblins always do when","there is a problem: we hid and hoped it would go away.").also { stage++ } - 5 -> npc("We meant no harm! Please tell the ruler of the above","people that we want to make peace.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest("Lost Tribe").setStage(player,46) } + 5 -> npc("We meant no harm! Please tell the ruler of the above","people that we want to make peace.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,46) } } } diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt index 62c3b392d..a1a871135 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.game.interaction.NodeUsageEvent import core.game.interaction.UseWithHandler import core.game.node.entity.skill.Skills @@ -25,7 +26,7 @@ class PickaxeOnRubble : UseWithHandler(1265,1267,1269,1271,1273,1275){ override fun handle(event: NodeUsageEvent?): Boolean { val player = event?.player ?: return false - val stage = player.questRepository.getQuest("Lost Tribe").getStage(player) + val stage = player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) if(stage < 30){ player.dialogueInterpreter.sendItemMessage(event.usedItem.id,"I should probably figure out what happened","before vandalizing the castle more.") return true diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt index fa6194e68..a4e519efa 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.game.node.item.Item import core.game.system.task.Pulse import core.game.world.update.flag.context.Animation @@ -25,7 +26,7 @@ class PickpocketSigmund : InteractionListener { when(counter++){ 0 -> player.animator.animate(Animation(881)) 3 -> { - if(player.questRepository.getQuest("Lost Tribe").getStage(player) == 47 && !player.inventory.containsItem(Item(Items.KEY_423))){ + if(player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 47 && !player.inventory.containsItem(Item(Items.KEY_423))){ player.inventory.add(Item(Items.KEY_423)) player.dialogueInterpreter.sendItemMessage(Items.KEY_423,"You find a small key on Sigmund.") } else { diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt index 246b139f8..ef26dc557 100644 --- a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt @@ -1,5 +1,6 @@ package content.region.misthalin.dorgeshuun.quest.thelosttribe +import content.data.Quests import core.cache.def.impl.SceneryDefinition import core.game.interaction.OptionHandler import core.game.node.Node @@ -23,14 +24,14 @@ class SigmundChestHandler : OptionHandler() { override fun handle(player: Player?, node: Node?, option: String?): Boolean { player ?: return false - if(player.questRepository.getQuest("Lost Tribe").getStage(player) == 47 && player.inventory.contains(Items.KEY_423,1)){ + if(player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 47 && player.inventory.contains(Items.KEY_423,1)){ player.inventory.remove(Item(Items.KEY_423)) for(item in arrayOf(Items.HAM_ROBE_4300,Items.HAM_SHIRT_4298,Items.HAM_HOOD_4302).map { Item(it) }){ if(!player.inventory.add(item)){ GroundItemManager.create(item,player) } } - player.questRepository.getQuest("Lost Tribe").setStage(player,48) + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,48) } else { player.sendMessage("This chest requires a key.") } diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java index 7e3dbe614..fe7fb4830 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java @@ -9,6 +9,7 @@ import core.game.node.item.Item; import core.game.world.map.Location; import core.plugin.Initializable; import core.game.world.update.flag.context.Animation; +import content.data.Quests; /** * Represents the dialogue plugin used for the aggie npc. @@ -115,7 +116,7 @@ public final class AggieDialogue extends DialoguePlugin { stage = 42; return true; } - quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); npc("What can I help you with?"); stage = 0; return true; diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java index 8351ddd49..b7b91c6d8 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue of the Joe guard NPC. @@ -49,7 +50,7 @@ public final class JoeGuardDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); switch (quest.getStage(player)) { case 40: if (player.getAttribute("guard-drunk", false)) { diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java index 026f2ff53..133cebfb1 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represnets the dialogue used to handle the Leela npc. @@ -76,7 +77,7 @@ public final class LeelaDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); switch (quest.getStage(player)) { case 60: case 100: diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java index 3cc707120..afa313cd1 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.plugin.Initializable; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the miss schism dialogue plugin. @@ -90,7 +91,7 @@ public final class MissSchismDialogue extends DialoguePlugin { break; case 110: - if (player.getQuestRepository().isComplete("Vampire Slayer")) { + if (player.getQuestRepository().isComplete(Quests.VAMPIRE_SLAYER)) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, there's nothing to tell NOW. You killed it."); stage = 111; } else { @@ -156,7 +157,7 @@ public final class MissSchismDialogue extends DialoguePlugin { stage = 23; break; case 23: - if(player.getQuestRepository().isComplete("Vampire Slayer")) { + if(player.getQuestRepository().isComplete(Quests.VAMPIRE_SLAYER)) { interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, now that I've cleared the vampire out of the manor,", "I guess you won't have too much trouble turning it into a", "museum."); stage = 24; } else { diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java index eb6270e1e..e7d150cf7 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the dialogue plugin used for the morgan npc. @@ -39,9 +40,9 @@ public final class MorganDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest("Vampire Slayer"); + quest = player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Vampire Slayer"); + quest = player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); if (quest.getStage(player) == 0) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please please help us, bold adventurer!"); stage = 0; diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java index eb500dfe2..cb13ff920 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java @@ -8,6 +8,7 @@ import core.game.node.item.Item; import core.game.system.task.Pulse; import core.plugin.Initializable; import core.game.world.GameWorld; +import content.data.Quests; /** * Represents the dialogue used to handle the Pricne Ali NPC. @@ -52,7 +53,7 @@ public class PrinceAliDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Prince Ali Rescue"); + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); switch (quest.getStage(player)) { case 50: interpreter.sendDialogues(player, null, "Prince, I come to rescue you."); diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java b/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java index 294c14ec7..b90bdc349 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java @@ -14,6 +14,7 @@ import core.game.world.repository.Repository; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.game.world.update.flag.context.Graphics; +import content.data.Quests; /** * Represents the plugin dialogue to handle the interaction with professor @@ -81,7 +82,7 @@ public class ProfessorOddensteinPlugin extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - final Quest quest = player.getQuestRepository().getQuest("Ernest the Chicken"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); switch (quest.getStage(player)) { case 0: case 10: @@ -102,7 +103,7 @@ public class ProfessorOddensteinPlugin extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Ernest the Chicken"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); switch (quest.getStage(player)) { case 0: case 100: diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java index 25796ff04..3480ca1b4 100644 --- a/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the dialogue used to handle the interaction between veronica. @@ -39,7 +40,7 @@ public class VeronicaDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Ernest the Chicken"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); switch (quest.getStage(player)) { case 0: switch (stage) { @@ -169,7 +170,7 @@ public class VeronicaDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - final Quest quest = player.getQuestRepository().getQuest("Ernest the Chicken"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); switch (quest.getStage(player)) { case 0: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can you please help me? I'm in a terrible spot of", "trouble."); diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorChairNPC.kt b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorChairNPC.kt new file mode 100644 index 000000000..423e57dec --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorChairNPC.kt @@ -0,0 +1,141 @@ +package content.region.misthalin.draynor.handlers + +import core.api.hasLineOfSight +import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.impl.PulseType +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.plugin.Initializable + +/** + * Represents the Draynor Manor Chair NPC, these are the chairs that follow the player + * around the manor. + * + * @author Broseki + */ + +private const val DRAYNOR_MANOR_CHAIR_NPC_ID = 3293 +private const val FOLLOWING_DISTANCE = 5 +private const val STOP_FOLLOWING_DISTANCE = 30 + +@Initializable +class DraynorManorChairNPC(id: Int = DRAYNOR_MANOR_CHAIR_NPC_ID, location: Location? = null) : + AbstractNPC(id, location) { + + // The player this NPC is currently following, null if nobody is being followed + private var following: Player? = null + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return DraynorManorChairNPC(id, location) + } + + override fun handleTickActions() { + super.handleTickActions() + val closestPlayer = findClosestPlayer() + // If there is a player nearby, follow them + if (closestPlayer != null && following != closestPlayer) { + stopFollowing() + following = closestPlayer + follow(closestPlayer) + following?.let { face(it) } + } else { + // If we didn't find a player within `FOLLOWING_DISTANCE` + // but we are following a player, check that they are still + // within `STOP_FOLLOWING_DISTANCE`, if they are gone, stop + // trying to follow them. + following?.let { player -> + if (findDistanceToPlayer(player) > STOP_FOLLOWING_DISTANCE + || !player.isActive + || player.isInvisible) { + stopFollowing() + } else { + if (!pulseManager.hasPulseRunning()) { + follow(player) + } + face(player) + } + } + } + } + + /** + * Stops following `following` + */ + fun stopFollowing() { + following = null + resetWalk() + pulseManager.clear(PulseType.STANDARD) + } + + /** + * Finds the closest player to the current entity within `FOLLOWING_DISTANCE` + * that is currently in the chair's line of sight. + * + * @return The Player object representing the closest player, or null if there are no players nearby. + */ + fun findClosestPlayer(): Player? { + val players = RegionManager.getLocalPlayers(this, FOLLOWING_DISTANCE) + if (players.isEmpty()) { + return null + } + + var closestPlayer: Player? = null + var closestDistance = Double.MAX_VALUE + + for (player in players) { + // Make sure the chair does not try to start + // following a player in another room + if (!hasLineOfSight(this, player)) { + continue + } + + // If the player is invisible, don't follow them + if (player.isInvisible) { + continue + } + + val distance = findDistanceToPlayer(player) + if (distance < closestDistance) { + closestDistance = distance + closestPlayer = player + } + } + + return closestPlayer + } + + /** + * Calculates the distance between the current entity and the specified player. + * + * @param player The player whose distance from the current entity is to be calculated. + * @return The distance between the current entity and the specified player as a Double value. + */ + fun findDistanceToPlayer(player: Player): Double { + return this.location.getDistance(player.location) + } + + /** + * Triggers the current entity to follow the specified player using a movement pulse. + * + * @param player The player that the entity should follow. + */ + fun follow(player: Player) { + pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) { + override fun pulse(): Boolean { + return false + } + }), PulseType.STANDARD) + } + + override fun getIds(): IntArray { + return intArrayOf(DRAYNOR_MANOR_CHAIR_NPC_ID) + } + + override fun shouldPreventStacking(mover: Entity?): Boolean { + return mover is DraynorManorChairNPC + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorHouseZone.kt b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorHouseZone.kt new file mode 100644 index 000000000..529b497a6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorHouseZone.kt @@ -0,0 +1,57 @@ +package content.region.misthalin.draynor.handlers + +import core.game.node.entity.Entity +import core.game.world.map.Location +import core.game.world.map.RegionManager.getLocalNpcs +import core.game.world.map.path.Pathfinder +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Represents the interior of Draynor Manor. + * + * @author Broseki + */ +@Initializable +class DraynorManorHouseZone : MapZone("Draynor Manor House", true), Plugin { + + override fun newInstance(arg: Any?): Plugin { + ZoneBuilder.configure(this) + return this + } + + override fun move(e: Entity, loc: Location?, destination: Location): Boolean { + for (n in getLocalNpcs(e, 5)) { + if (n.isInvisible() || n === e) { + continue + } + if (n.shouldPreventStacking(e)) { + val s1 = e.size() + val s2 = n.size() + val x = destination.x + val y = destination.y + val l = n.getLocation() + if (Pathfinder.isStandingIn(x, y, s1, s1, l.x, l.y, s2, s2)) { + return false + } + } + } + return true + } + + override fun enter(entity: Entity?): Boolean { + return super.enter(entity) + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any? { + return null + } + + override fun configure() { + register(ZoneBorders(3097, 3373, 3119, 3364)) + register(ZoneBorders(3090, 3363, 3126, 3354)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java index 0dcfe9778..0d81ec43b 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.draynor.quest.anma; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -41,7 +42,7 @@ public final class AliceDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); switch (quest.getStage(player)) { default: options("What are you selling?", "I'm okay, thank you."); diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java index 691c9b1f0..b584565ff 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.draynor.quest.anma; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; import core.game.node.entity.player.Player; @@ -52,7 +53,7 @@ public final class AliceHusbandDialogue extends DialoguePlugin { npc("Wooo wooo wooooo!"); return true; } - quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); switch (quest.getStage(player)) { case 0: npc("Hi, I don't feel like talking."); diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java index 4e2f9dc9c..a04a6c9de 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java @@ -11,6 +11,7 @@ import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.HammerM import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.ResearchNoteHandler; import core.plugin.Initializable; import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.UndeadTreePlugin; +import content.data.Quests; /** * Handles the animal magnetism quest. @@ -18,12 +19,6 @@ import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.UndeadT */ @Initializable public final class AnimalMagnetism extends Quest { - - /** - * The name of this quest. - */ - public static String NAME = "Animal Magnetism"; - /** * The crone made amulet item. */ @@ -103,7 +98,7 @@ public final class AnimalMagnetism extends Quest { * Constructs a new {@code AnimalMagnetism} {@code Object}. */ public AnimalMagnetism() { - super("Animal Magnetism", 33, 32, 1); + super(Quests.ANIMAL_MAGNETISM, 33, 32, 1); } @Override @@ -219,9 +214,9 @@ public final class AnimalMagnetism extends Quest { @Override public boolean hasRequirements(Player player) { - requirements[0] = player.getQuestRepository().isComplete("The Restless Ghost"); - requirements[1] = player.getQuestRepository().isComplete("Ernest the Chicken"); - requirements[2] = player.getQuestRepository().isComplete("Priest in Peril"); + requirements[0] = player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST); + requirements[1] = player.getQuestRepository().isComplete(Quests.ERNEST_THE_CHICKEN); + requirements[2] = player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL); requirements[3] = player.getSkills().getStaticLevel(Skills.RANGE) >= 30; requirements[4] = player.getSkills().getStaticLevel(Skills.SLAYER) >= 18; requirements[5] = player.getSkills().getStaticLevel(Skills.CRAFTING) >= 19; diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java index 141e8a52f..6156fe9bd 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java @@ -19,7 +19,6 @@ import core.game.node.Node; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.TeleportManager.TeleportType; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.game.system.task.Pulse; @@ -33,9 +32,9 @@ import core.game.world.update.flag.context.Animation; import core.plugin.Plugin; import core.plugin.ClassScanner; import core.tools.RandomFunction; -import org.rs09.consts.Sounds; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Handles the animal magnetism plugin. @@ -62,14 +61,14 @@ public final class AnimalMagnetismPlugin extends OptionHandler { public boolean handle(Player player, Node node, String option) { switch (node.getId()) { case 5167: - if (!hasRequirement(player, "Creature of Fenkenstrain")) { + if (!hasRequirement(player, Quests.CREATURE_OF_FENKENSTRAIN)) { break; } player.teleport(new Location(3577, 9927)); break; case 5198: case 5199: - if (player.getQuestRepository().getQuest(AnimalMagnetism.NAME).getStage(player) == 0) { + if (player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM).getStage(player) == 0) { player.getDialogueInterpreter().sendDialogues((NPC) node, null, "Hello there, I'm busy with my research. Come back in a", "bit, could you?"); break; } @@ -198,7 +197,7 @@ public final class AnimalMagnetismPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); if (quest.getStage(player) <= 28) { SkillingTool tool = SkillingTool.getHatchet(player); if (tool == null || tool.ordinal() < 4) { @@ -243,7 +242,7 @@ public final class AnimalMagnetismPlugin extends OptionHandler { public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); final Animation animation = getAnimation(event.getUsedItem().getId()); - final Quest quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); player.animate(animation, 2); if (quest.getStage(player) == 28) { quest.setStage(player, 29); @@ -293,7 +292,7 @@ public final class AnimalMagnetismPlugin extends OptionHandler { final Object[] data = getIndex(button); final boolean toggled = (boolean) data[1]; final int[] configs = getConfigs((int) data[0]); - final Quest quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); player.getPacketDispatch().sendInterfaceConfig(480, configs[0], !toggled); player.getPacketDispatch().sendInterfaceConfig(480, (int) data[2], toggled); if (quest.getStage(player) == 33) { diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt index 18f6a0438..da0a40472 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.game.world.map.Direction import org.rs09.consts.Animations import org.rs09.consts.NPCs +import content.data.Quests class AnmaCutscene(player: Player) : Cutscene(player) { override fun setup() { @@ -182,7 +183,7 @@ class AnmaCutscene(player: Player) : Cutscene(player) { } 32 -> { end { - setQuestStage(player, "Animal Magnetism", 20) + setQuestStage(player, Quests.ANIMAL_MAGNETISM, 20) } } } diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java index ce546f229..bae10eb6d 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java @@ -3,6 +3,7 @@ package content.region.misthalin.draynor.quest.anma; import java.util.ArrayList; import java.util.List; +import content.data.Quests; import core.game.container.Container; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.skill.Skills; @@ -55,7 +56,7 @@ public final class AvaDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); if (!quest.hasRequirements(player)) { player.getPacketDispatch().sendMessage("She doesn't seem interested in talking to you."); return false; diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt index 511e4137f..9607a29ca 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt @@ -11,6 +11,7 @@ import core.game.interaction.InteractionListener import core.game.interaction.IntType import core.tools.secondsToTicks import core.tools.colorize +import content.data.Quests /** * Handles Ava's device @@ -19,7 +20,7 @@ import core.tools.colorize class AvasDevice : InteractionListener, EventHook { override fun defineListeners() { onEquip(devices) { player, _ -> - if (!isQuestComplete(player, "Animal Magnetism")) { + if (!isQuestComplete(player, Quests.ANIMAL_MAGNETISM)) { sendMessage(player, "You need to complete Animal Magnetism to equip this.") return@onEquip false } diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java index c5f97165f..eb76716f4 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import content.region.misthalin.lumbridge.quest.therestlessghost.RestlessGhost; +import content.data.Quests; /** * Handles the dialogue used for the old crone. @@ -49,7 +50,7 @@ public final class OldCronDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Animal Magnetism"); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); switch (quest.getStage(player)) { case 16: case 17: diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java index 2e53bb979..7c23e06c0 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.draynor.quest.anma; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -45,7 +46,7 @@ public final class WitchDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(AnimalMagnetism.NAME); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); switch (quest.getStage(player)) { case 25: npc("Hello, hello, my poppet. What brings you to my little", "room?"); diff --git a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java index bc29f3b16..8fbf7d11f 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.plugin.Initializable; import core.game.node.entity.player.Player; +import content.data.Quests; /** * Represents the dialogue which handles the interaction with ernest. @@ -73,12 +74,12 @@ public final class ErnestDialogue extends DialoguePlugin { * Method used to finish the quest. */ public void finish() { - if (player.getQuestRepository().isComplete("Ernest the Chicken")) { + if (player.getQuestRepository().isComplete(Quests.ERNEST_THE_CHICKEN)) { npc.clear(); return; } npc.clear(); - player.getQuestRepository().getQuest("Ernest the Chicken").finish(player); + player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN).finish(player); } @Override diff --git a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java index d18e635cd..58a9fecef 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java @@ -8,6 +8,7 @@ import core.game.node.item.Item; import core.game.world.map.Location; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the ernest the chicken quest. @@ -40,7 +41,7 @@ public final class ErnestTheChicken extends Quest { * Constructs a new {@code ErnestTheChicken} {@code Object}. */ public ErnestTheChicken() { - super("Ernest the Chicken", 19, 18, 4, 32, 0, 1, 3); + super(Quests.ERNEST_THE_CHICKEN, 19, 18, 4, 32, 0, 1, 3); } @Override @@ -128,7 +129,7 @@ public final class ErnestTheChicken extends Quest { @Override public boolean isHidden(final Player player) { - return player.getQuestRepository().getQuest("Ernest the Chicken").getStage(player) == 100 || player.getAttribute("ernest-hide", false); + return player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN).getStage(player) == 100 || player.getAttribute("ernest-hide", false); } @Override @@ -174,7 +175,7 @@ public final class ErnestTheChicken extends Quest { @Override public boolean isHidden(final Player player) { Player target = getAttribute("target", null); - if (target != null && target.getQuestRepository().getQuest("Ernest the Chicken").getStage(player) == 100) { + if (target != null && target.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN).getStage(player) == 100) { clear(); return super.isHidden(player); } diff --git a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java index 6231e659e..94e7f13cb 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java @@ -4,6 +4,7 @@ import core.plugin.Initializable; import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the vampire quest. @@ -16,7 +17,7 @@ public class VampireSlayer extends Quest { * Constructs a new {@code VampireSlayer} {@code Object}. */ public VampireSlayer() { - super("Vampire Slayer", 30, 29, 3, 178, 0, 1, 3); + super(Quests.VAMPIRE_SLAYER, 30, 29, 3, 178, 0, 1, 3); } @Override diff --git a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java index 35d9e8df3..17c72b2f2 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java @@ -11,6 +11,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.game.world.map.Location; import core.tools.RandomFunction; +import content.data.Quests; /** * Handles the Vampie Slayer npc. @@ -127,7 +128,7 @@ public class VampireSlayerNPC extends AbstractNPC { return; } final Player p = ((Player) killer); - final Quest quest = p.getQuestRepository().getQuest("Vampire Slayer"); + final Quest quest = p.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); if (p.getInventory().containsItem(HAMMER) && p.getInventory().remove(STAKE)) { if (quest.getStage(p) == 30) { quest.finish(p); diff --git a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java index 243b76966..f8f582536 100644 --- a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java +++ b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java @@ -11,6 +11,7 @@ import core.game.node.scenery.Scenery; import core.game.world.map.Location; import core.plugin.Initializable; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the plugin to handle vampire slayer node handling. @@ -51,7 +52,7 @@ public final class VampireSlayerPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Vampire Slayer"); + final Quest quest = player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); switch (option) { case "open": int id = ((Scenery) node).getId(); diff --git a/Server/src/main/content/region/misthalin/edgeville/handlers/PosterListener.kt b/Server/src/main/content/region/misthalin/edgeville/handlers/PosterListener.kt deleted file mode 100644 index 63de7555e..000000000 --- a/Server/src/main/content/region/misthalin/edgeville/handlers/PosterListener.kt +++ /dev/null @@ -1,18 +0,0 @@ -package content.region.misthalin.edgeville.handlers - -import core.api.sendDialogue -import core.api.teleport -import core.game.world.map.Location -import org.rs09.consts.Scenery -import core.game.interaction.IntType -import core.game.interaction.InteractionListener - -class PosterListener : InteractionListener { - override fun defineListeners() { - on(Scenery.POSTER_29586, IntType.SCENERY, "pull-back") { player, _ -> - sendDialogue(player, "There appears to be a tunnel behind this poster.") - teleport(player, Location.create(3140, 4230, 2)) - return@on true - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.java deleted file mode 100644 index e98e13693..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.java +++ /dev/null @@ -1,569 +0,0 @@ -package content.region.misthalin.lumbridge.dialogue; - -import core.cache.def.impl.ItemDefinition; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import content.data.RepairItem; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.diary.AchievementDiary; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.item.Item; -import content.global.handlers.item.equipment.BarrowsEquipmentRegister; - -/** - * Represents the dialogue plugin used for the bob npc who repairs items. - * @author 'Vexia - * @version 1.0 - */ -public final class BobDialogue extends DialoguePlugin { - - /** - * Represents the item id being repaired. - */ - private int itemId = 0; - - /** - * Represents the item being repaired. - */ - private Item item; - - /** - * Represents the item repairing. - */ - private static RepairItem repairitem = null; - - /** - * The achievement diary. - */ - private final int level = 1; - - /** - * Constructs a new {@code BobDialogue} {@code Object}. - */ - public BobDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code BobDialogue} {@code Object}. - * @param player the player. - */ - public BobDialogue(Player player) { - super(player); - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 754: - options("Yes, please.", "No, thank you."); - stage = 755; - break; - case 755: - switch (buttonId) { - case 1: - player("Yes, please."); - stage = 757; - break; - case 2: - player("No, thank you."); - stage = 756; - break; - } - break; - case 756: - end(); - break; - case 757: - end(); - if (repairitem != null) { - if (!player.getInventory().contains(995, repairitem.getCost())) { - end(); - player.getPacketDispatch().sendMessage("You don't have enough to pay him."); - break; - } - if (!player.getInventory().contains(itemId, 1)) { - end(); - return true; - } - player.getInventory().remove(new Item(995, repairitem.getCost())); - if (player.getInventory().remove(new Item(itemId, 1))) { - player.getInventory().add(repairitem.getProduct()); - } - String cost = "free"; - if (repairitem.getCost() != 0) { - cost = repairitem.getCost() + "gp"; - } - player.getPacketDispatch().sendMessage("Bob fixes your " + ItemDefinition.forId(itemId).getName().toLowerCase().replace("broken", "").trim() + " for " + cost + "."); - } - if (repairitem == null) { - String cost = "free"; - String type = BarrowsEquipment.formatedName(itemId); - String single = BarrowsEquipment.getSingleName(type); - String equipment = BarrowsEquipment.getEquipmentType(type); - String newString = type.toLowerCase().replace(single, "").trim().replace("'s", ""); - StringBuilder newewString = new StringBuilder(); - newewString.append(newString).append(" " + equipment); - final BarrowsEquipment.BarrowsFullEquipment fullequip = BarrowsEquipment.BarrowsFullEquipment.forName(newewString.toString()); - if (BarrowsEquipment.getFormatedCost(equipment, item) != 0) { - cost = String.valueOf(BarrowsEquipment.getFormatedCost(equipment, item) + "gp"); - } - if (!player.getInventory().contains(995, BarrowsEquipment.getFormatedCost(equipment, item))) { - end(); - player.getPacketDispatch().sendMessage("You don't have enough to pay him."); - break; - } - if (fullequip == null || fullequip.getFull() == null) { - player.getPacketDispatch().sendMessage("Report this to an administrator!"); - return true; - } - if (!player.getInventory().contains(itemId, 1)) { - end(); - return true; - } - player.getInventory().remove(new Item(995, BarrowsEquipment.getFormatedCost(equipment, item))); - if (player.getInventory().remove(new Item(itemId, 1))) { - player.getInventory().add(fullequip.getFull()); - } - player.getPacketDispatch().sendMessage("Bob fixes your " + equipment + " for " + cost + "."); - } - break; - case 678: - end(); - break; - case 0: - switch (buttonId) { - case 1: - player("Give me a quest!"); - stage = -5; - break; - case 2: - player("Have you anything to sell?"); - stage = 10; - break; - case 3: - player("Can you repair my items for me?"); - stage = 20; - break; - case 4: - player("I'd like to talk about Achievement Diaries."); - stage = 30; - break; - } - break; - case -5: - interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "Get yer own!"); - stage = -4; - break; - case -4: - end(); - break; - case 10: - npc("Yes! I buy and sell axes! Take your pick (or axe)!"); - stage = 11; - break; - case 11: - end(); - npc.openShop(player); - break; - case 20: - npc("Of course I'll repair it, though the materials may cost", "you. Just hand me the item and I'll have a look."); - stage = 21; - break; - case 21: - end(); - break; - case 30: - if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) { - player("I've done all the medium tasks in my Lumbridge", "Achievement Diary."); - stage = 150; - break; - } - if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) { - player("I've seemed to have lost my explorer's ring..."); - stage = 160; - break; - } - options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); - stage = 31; - break; - case 31: - switch (buttonId) { - case 1: - player("What is the Achievement Diary?"); - stage = 110; - break; - case 2: - player("What are the rewards?"); - stage = 120; - break; - case 3: - player("How do I claim the rewards?"); - stage = 130; - break; - case 4: - player("See you later!"); - stage = 140; - break; - } - break; - case 110: - npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made in the world of", "Gielinor. In Lumbridge and Draynor I can help you", "discover some very useful things indeed."); - stage++; - break; - case 111: - npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts."); - stage++; - break; - case 112: - npc("You can access your Achievement Diary by going to", "the Quest Journal. When you've opened the Quest", "Journal click on the green star icon on the top right", "hand corner. This will open the diary."); - stage = 30; - break; - case 120: - npc("Ah, well there are different rewards for each", "Achievement Diary. For completing the Lumbridge and", "Draynor diary you are presented with an explorer's", "ring."); - stage++; - break; - case 121: - npc("This ring will become increasingly useful with each", "section of the diary that you complete."); - stage = 30; - break; - case 130: - npc("You need to complete the tasks so that they're all ticked", "off, then you can claim your reward. Most of them are", "straightforward although you might find some required", "quests to be started, if not finished."); - stage++; - break; - case 131: - npc("To claim the explorer's ring speak to Explorer Jack", " in Lumbridge, Ned in Draynor Village or myself."); - stage = 30; - break; - case 140: - end(); - break; - case 150: - npc("Yes I see that, you'll be wanting your", "reward then I assume?"); - stage++; - break; - case 151: - player("Yes please."); - stage++; - break; - case 152: - AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level); - npc("This ring is a representation of the adventures you", "went on to complete your tasks."); - stage ++; - break; - case 153: - player("Wow, thanks!"); - stage = 30; - break; - case 160: - AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level); - npc("You better be more careful this time."); - stage = -1; - break; - } - - return true; - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new BobDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - boolean repair = false; - boolean wrong = false; - if (npc.getId() == 3797 && args.length == 1) { - player("Can you repair my items for me?"); - stage = 20; - return true; - } - if (args.length == 1) { - options("Give me a quest!", "Have you anything to sell?", "Can you repair my items for me?", "Talk about Achievement Diaries"); - stage = 0; - return true; - } - if (args[1] != null) { - repair = (boolean) args[1]; - } - if (args[2] != null) { - wrong = (boolean) args[2]; - } - if (args[3] != null) { - repairitem = RepairItem.forId((int) args[3]); - itemId = (int) args[3]; - } - if (args[4] != null) { - item = (Item) args[4]; - } - if (repair && !wrong) { - String cost = "free"; - if (repairitem != null) { - if (repairitem.getCost() != 0) { - cost = String.valueOf(repairitem.getCost() + "gp"); - } - } else { - String type = BarrowsEquipment.formatedName(itemId); - String single = BarrowsEquipment.getSingleName(type); - String equipment = BarrowsEquipment.getEquipmentType(type); - String newString = type.toLowerCase().replace(single, "").trim().replace("'s", ""); - StringBuilder newewString = new StringBuilder(); - newewString.append(newString).append(" " + equipment); - if (BarrowsEquipment.getFormatedCost(equipment, item) != 0) { - cost = String.valueOf(BarrowsEquipment.getFormatedCost(equipment, item) + "gp"); - } - } - npc("Quite badly damaged, but easy to repair. Would you", "like me to repair it for " + cost + "?"); - stage = 754; - return true; - } - if (repair == true && wrong == true) { - npc("Sorry friend, but I can't do anything with that."); - stage = 678; - return true; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 519, 3797 }; - } - - /** - * Barrows equipment information. - * @author 'Vexia - */ - public static class BarrowsEquipment { - - /** - * Represents the base names. - */ - private String[] base = new String[] { "dharok", "verac", "ahrim", "torag", "guthan" }; - - /** - * The weapon names. - */ - private static final String[] weapon_names = new String[] { "flail", "greataxe", "spear", "x-bow", "hammer", "hammers", "staff" }; - - /** - * The weapon body names. - */ - private static final String[] body_names = new String[] { "top", "platebody", "body" }; - - /** - * The helm names. - */ - private static final String[] helm_names = new String[] { "hood", "helm", "coif" }; - - /** - * The leg names. - */ - private static final String[] leg_names = new String[] { "skirt", "legs", "plateskirt", "platelegs" }; - - /** - * The prices. - */ - private static final Object[][] prices = new Object[][] { { "weapon", 100 }, { "body", 90 }, { "legs", 80 }, { "helm", 60 } }; - - /** - * Represents the items. - */ - private static final Object[][] ITEMS = { { 4856, "Ahrim's hood" }, { 4857, "Ahrim's hood" }, { 4858, "Ahrim's hood" }, { 4859, "Ahrim's hood" }, { 4860, "Ahrim's hood" }, { 4862, "Ahrim's staff" }, { 4863, "Ahrim's staff" }, { 4864, "Ahrim's staff" }, { 4865, "Ahrim's staff" }, { 4866, "Ahrim's staff" }, { 4868, "Ahrim's top" }, { 4869, "Ahrim's top" }, { 4870, "Ahrim's top" }, { 4871, "Ahrim's top" }, { 4872, "Ahrim's top" }, { 4874, "Ahrim's skirt" }, { 4875, "Ahrim's skirt" }, { 4876, "Ahrim's skirt" }, { 4877, "Ahrim's skirt" }, { 4878, "Ahrim's skirt" }, { 4880, "Dharok's helm" }, { 4881, "Dharok's helm" }, { 4882, "Dharok's helm" }, { 4883, "Dharok's helm" }, { 4884, "Dharok's helm" }, { 4886, "Dharok's greataxe" }, { 4887, "Dharok's greataxe" }, { 4888, "Dharok's greataxe" }, { 4889, "Dharok's greataxe" }, { 4890, "Dharok's greataxe" }, { 4892, "Dharok's platebody" }, { 4893, "Dharok's platebody" }, { 4894, "Dharok's platebody" }, { 4895, "Dharok's platebody" }, { 4896, "Dharok's platebody" }, { 4898, "Dharok's platelegs" }, { 4899, "Dharok's platelegs" }, { 4900, "Dharok's platelegs" }, { 4901, "Dharok's platelegs" }, { 4902, "Dharok's platelegs" }, { 4904, "Guthan's helm" }, { 4905, "Guthan's helm" }, { 4906, "Guthan's helm" }, { 4907, "Guthan's helm" }, { 4908, "Guthan's helm" }, { 4910, "Guthan's spear" }, { 4911, "Guthan's spear" }, { 4912, "Guthan's spear" }, { 4913, "Guthan's spear" }, { 4914, "Guthan's spear" }, { 4916, "Guthan's body" }, { 4917, "Guthan's body" }, { 4918, "Guthan's body" }, { 4919, "Guthan's body" }, { 4920, "Guthan's body" }, { 4922, "Guthan's skirt" }, { 4923, "Guthan's skirt" }, { 4924, "Guthan's skirt" }, { 4925, "Guthan's skirt" }, { 4926, "Guthan's skirt" }, { 4928, "Karil's coif" }, { 4929, "Karil's coif" }, { 4930, "Karil's coif" }, { 4931, "Karil's coif" }, { 4932, "Karil's coif" }, { 4934, "Karil's x-bow" }, { 4935, "Karil's x-bow" }, { 4936, "Karil's x-bow" }, { 4937, "Karil's x-bow" }, { 4938, "Karil's x-bow" }, { 4940, "Karil's top" }, { 4941, "Karil's top" }, { 4942, "Karil's top" }, { 4943, "Karil's top" }, { 4944, "Karil's top" }, { 4946, "Karil's skirt" }, { 4947, "Karil's skirt" }, { 4948, "Karil's skirt" }, { 4949, "Karil's skirt" }, { 4950, "Karil's skirt" }, { 4952, "Torag's helm" }, { 4953, "Torag's helm" }, { 4954, "Torag's helm" }, { 4955, "Torag's helm" }, { 4956, "Torag's helm" }, { 4958, "Torag's hammers" }, { 4959, "Torag's hammers" }, { 4960, "Torag's hammers" }, { 4961, "Torag's hammers" }, { 4962, "Torag's hammers" }, { 4964, "Torag's body" }, { 4965, "Torag's body" }, { 4966, "Torag's body" }, { 4967, "Torag's body" }, { 4968, "Torag's body" }, { 4970, "Torag's legs" }, { 4971, "Torag's legs" }, { 4972, "Torag's legs" }, { 4973, "Torag's legs" }, { 4974, "Torag's legs" }, { 4976, "Verac's helm" }, { 4977, "Verac's helm" }, { 4978, "Verac's helm" }, { 4979, "Verac's helm" }, { 4980, "Verac's helm" }, { 4982, "Verac's flail" }, { 4983, "Verac's flail" }, { 4984, "Verac's flail" }, { 4985, "Verac's flail" }, { 4986, "Verac's flail" }, { 4988, "Verac's top" }, { 4989, "Verac's top" }, { 4990, "Verac's top" }, { 4991, "Verac's top" }, { 4992, "Verac's top" }, { 4994, "Verac's skirt" }, { 4995, "Verac's skirt" }, { 4996, "Verac's skirt" }, { 4997, "Verac's skirt" }, { 4998, "Verac's skirt" } }; - - /** - * Gets the cost. - * @param name the name. - * @return the price. - */ - public static int getFormatedCost(String name, Item item) { - int ticks = BarrowsEquipmentRegister.TICKS; - int[] degrades = new int[] { 100, 75, 50, 25, 0 }; - for (int i = 0; i < prices.length; i++) { - String check = (String) prices[i][0]; - if (check.equals(name)) { - int degrade = 0; - for (int d : degrades) { - if (item.getName().contains(String.valueOf(d))) { - degrade = d; - break; - } - } - degrade -= 25 - (25 * ((double)item.getCharge() / (double)ticks)); - int max = (int) prices[i][1] * 1000; - return (int) (max - (max * (degrade * 0.01))); - } - } - return 0; - } - - /** - * Gets the cost of the item type. - * @param name the name. - * @return the return type. - */ - public static int getCost(String name) { - for (int i = 0; i < prices.length; i++) { - String check = (String) prices[i][0]; - if (check.equals(name)) { - return (int) prices[i][1]; - } - } - return 0; - } - - /** - * Represents if an item is a barrows item. - * @param id the id. - * @return {@code True} if so. - */ - public static boolean isBarrowsItem(int id) { - for (int i = 0; i < ITEMS.length; i++) { - if ((int) ITEMS[i][0] == id) { - return true; - } - } - return false; - } - - /** - * Gets the formatted name. - * @param id the id. - * @return the name. - */ - public static String formatedName(int id) { - for (int i = 0; i < ITEMS.length; i++) { - if ((int) ITEMS[i][0] == id) { - return (String) ITEMS[i][1]; - } - } - return null; - } - - /** - * Gets the equipment type. - * @param name the name. - * @return the type. - */ - public static String getEquipmentType(String name) { - name = name.toLowerCase().replace("verac's", "").replace("karil's", "").replace("dharok's", "").replace("torag's", "").replace("guthan's", "").replace("ahrim's", "").trim(); - for (int i = 0; i < weapon_names.length; i++) { - if (weapon_names[i].contains(name)) { - return "weapon"; - } - } - for (int k = 0; k < body_names.length; k++) { - if (body_names[k].contains(name)) { - return "body"; - } - } - for (int z = 0; z < leg_names.length; z++) { - if (leg_names[z].contains(name)) { - return "legs"; - } - } - for (int q = 0; q < helm_names.length; q++) { - if (helm_names[q].contains(name)) { - return "helm"; - } - } - return null; - } - - /** - * Method used t get its single name. - * @param name the name. - * @return the name. - */ - public static String getSingleName(String name) { - name = name.toLowerCase().replace("verac's", "").replace("karil's", "").replace("dharok's", "").replace("torag's", "").replace("guthan's", "").replace("ahrim's", "").trim(); - for (int i = 0; i < weapon_names.length; i++) { - if (weapon_names[i].contains(name)) { - return weapon_names[i]; - } - } - for (int k = 0; k < body_names.length; k++) { - if (body_names[k].contains(name)) { - return body_names[k]; - } - } - for (int z = 0; z < leg_names.length; z++) { - if (leg_names[z].contains(name)) { - return leg_names[z]; - } - } - for (int q = 0; q < helm_names.length; q++) { - if (helm_names[q].contains(name)) { - return helm_names[q]; - } - } - return null; - } - - /** - * Gets the bases. - * @return the base. - */ - public String[] getBase() { - return base; - } - - /** - * Represents the multiple full barrows equipment items. - * @author 'Vexia - * @version 1.0 - */ - public enum BarrowsFullEquipment { - VERAC_LEGS(new Item(4759, 1)), VERAC_TOP(new Item(4757, 1)), VERAC_WEAPON(new Item(4755, 1)), VERAC_HELM(new Item(4753, 1)), TORAG_LEGS(new Item(4751, 1)), TORAG_BODY(new Item(4749, 1)), TORAG_HELM(new Item(4745, 1)), TORAG_WEAPON(new Item(4747, 1)), KARIL_HELM(new Item(4732, 1)), KARIL_WEAPON(new Item(4734, 1)), KARIL_BODY(new Item(4736, 1)), KARIL_LEGS(new Item(4738, 1)), GUTHAN_HELM(new Item(4724, 1)), GUTHAN_BODY(new Item(4728, 1)), GUTHAN_LEGS(new Item(4730, 1)), GUTHAN_WEAPON(new Item(4726, 1)), DHAROK_HELM(new Item(4716, 1)), DHAROK_BODY(new Item(4720, 1)), DHAROK_LEGS(new Item(4722, 1)), DHAROK_WEAPON(new Item(4718, 1)), AHRIM_HELM(new Item(4708, 1)), AHRIM_BODY(new Item(4712, 1)), AHRIM_LEGS(new Item(4714, 1)), AHRIM_WEAPON(new Item(4710, 1)); - - /** - * Constructs a new {@code BarrowsEquipment} {@code Object}. - * @param full the full item. - */ - BarrowsFullEquipment(Item full) { - this.full = full; - } - - /** - * Represents the full item. - */ - private final Item full; - - /** - * for name - * @param name thename. - * @return the equipment. - */ - public static BarrowsFullEquipment forName(String name) { - if (name.equals("guthan body body")) { - name = "guthan body"; - } else if (name.equals("torag body body")) { - name = "torag body"; - } else if (name.equals("verac body")) { - name = "verac top"; - } - for (BarrowsFullEquipment barrow : BarrowsFullEquipment.values()) { - if (barrow.name().toLowerCase().replace("_", " ").trim().equalsIgnoreCase(name)) { - return barrow; - } - } - return null; - } - - /** - * Gets the full. - * @return The full. - */ - public Item getFull() { - return full; - } - } - - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.kt new file mode 100644 index 000000000..c759ef0b2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.kt @@ -0,0 +1,266 @@ +package content.region.misthalin.lumbridge.dialogue + +import content.data.RepairItem +import content.global.handlers.item.equipment.BarrowsEquipment +import core.cache.def.impl.ItemDefinition +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import core.plugin.Initializable + +/** + * Represents the dialogue plugin used for the bob npc who repairs items. + * @author 'Vexia + * @author Damighty - Kotlin conversion + * @version 1.0 + */ +@Initializable +class BobDialogue(player: Player? = null) : DialoguePlugin(player) { + + /** + * Represents the item id being repaired. + */ + private var itemId = 0 + + /** + * Represents the item being repaired. + */ + private lateinit var item: Item + + /** + * Represents the item repairing. + */ + private var repairItem: RepairItem? = null + + /** + * The achievement diary. + */ + private val level = 1 + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 754 -> { + options("Yes, please.", "No, thank you.") + stage = 755 + } + 755 -> when (buttonId) { + 1 -> { + player("Yes, please.") + stage = 757 + } + 2 -> { + player("No, thank you.") + stage = 756 + } + } + 756 -> end() + 757 -> { + end() + val repairItemDef = RepairItem.forId(itemId) + + if (repairItemDef != null) { + // Standard repairable items + if (!player.inventory.contains(995, repairItemDef.cost)) { + player.packetDispatch.sendMessage("You don't have enough to pay him.") + return true + } + if (player.inventory.remove(Item(itemId, 1))) { + player.inventory.remove(Item(995, repairItemDef.cost)) + player.inventory.add(repairItemDef.product) + val costText = if (repairItemDef.cost > 0) "${repairItemDef.cost}gp" else "free" + player.packetDispatch.sendMessage("Bob fixes your ${item.name.lowercase().replace("broken", "").trim()} for $costText.") + } + } else { + // Barrows items + val barrowsDef = BarrowsEquipment.getDefinition(itemId) ?: return true + val repairCost = BarrowsEquipment.getRepairCost(item) + + if (!player.inventory.contains(995, repairCost)) { + player.packetDispatch.sendMessage("You don't have enough to pay him.") + return true + } + if (player.inventory.remove(Item(itemId, 1))) { + player.inventory.remove(Item(995, repairCost)) + player.inventory.add(Item(barrowsDef.repairedId)) + val costText = if (repairCost > 0) "${repairCost}gp" else "free" + player.packetDispatch.sendMessage("Bob fixes your ${barrowsDef.itemName.lowercase()} for $costText.") + } + } + return true + } + 678 -> end() + 0 -> when (buttonId) { + 1 -> { + player("Give me a quest!") + stage = -5 + } + 2 -> { + player("Have you anything to sell?") + stage = 10 + } + 3 -> { + player("Can you repair my items for me?") + stage = 20 + } + 4 -> { + player("I'd like to talk about Achievement Diaries.") + stage = 30 + } + } + -5 -> { + interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "Get yer own!") + stage = -4 + } + -4 -> end() + 10 -> { + npc("Yes! I buy and sell axes! Take your pick (or axe)!") + stage = 11 + } + 11 -> { + end() + npc.openShop(player) + } + 20 -> { + npc("Of course I'll repair it, though the materials may cost", "you. Just hand me the item and I'll have a look.") + stage = 21 + } + 21 -> end() + 30 -> { + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) { + player("I've done all the medium tasks in my Lumbridge", "Achievement Diary.") + stage = 150 + } else if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) { + player("I've seemed to have lost my explorer's ring...") + stage = 160 + } else { + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later.") + stage = 31 + } + } + 31 -> when (buttonId) { + 1 -> { + player("What is the Achievement Diary?") + stage = 110 + } + 2 -> { + player("What are the rewards?") + stage = 120 + } + 3 -> { + player("How do I claim the rewards?") + stage = 130 + } + 4 -> { + player("See you later!") + stage = 140 + } + } + 110 -> { + npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made in the world of", "Gielinor. In Lumbridge and Draynor I can help you", "discover some very useful things indeed.") + stage++ + } + 111 -> { + npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts.") + stage++ + } + 112 -> { + npc("You can access your Achievement Diary by going to", "the Quest Journal. When you've opened the Quest", "Journal click on the green star icon on the top right", "hand corner. This will open the diary.") + stage = 30 + } + 120 -> { + npc("Ah, well there are different rewards for each", "Achievement Diary. For completing the Lumbridge and", "Draynor diary you are presented with an explorer's", "ring.") + stage++ + } + 121 -> { + npc("This ring will become increasingly useful with each", "section of the diary that you complete.") + stage = 30 + } + 130 -> { + npc("You need to complete the tasks so that they're all ticked", "off, then you can claim your reward. Most of them are", "straightforward although you might find some required", "quests to be started, if not finished.") + stage++ + } + 131 -> { + npc("To claim the explorer's ring speak to Explorer Jack", " in Lumbridge, Ned in Draynor Village or myself.") + stage = 30 + } + 140 -> end() + 150 -> { + npc("Yes I see that, you'll be wanting your", "reward then I assume?") + stage++ + } + 151 -> { + player("Yes please.") + stage++ + } + 152 -> { + AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level) + npc("This ring is a representation of the adventures you", "went on to complete your tasks.") + stage++ + } + 153 -> { + player("Wow, thanks!") + stage = 30 + } + 160 -> { + AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level) + npc("You better be more careful this time.") + stage = -1 + } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return BobDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + var repair = false + var wrong = false + + if (npc.id == 3797 && args.size == 1) { + player("Can you repair my items for me?") + stage = 20 + return true + } + + if (args.size == 1) { + options("Give me a quest!", "Have you anything to sell?", "Can you repair my items for me?", "Talk about Achievement Diaries") + stage = 0 + return true + } + + if (args.size > 1) repair = args[1] as Boolean + if (args.size > 2) wrong = args[2] as Boolean + if (args.size > 3) { + repairItem = RepairItem.forId(args[3] as Int) + itemId = args[3] as Int + } + if (args.size > 4) item = args[4] as Item + + if (repair && !wrong) { + val cost = RepairItem.forId(itemId)?.cost ?: BarrowsEquipment.getRepairCost(item) + val costText = if (cost > 0) "${cost}gp" else "free" + npc("Quite badly damaged, but easy to repair. Would you", "like me to repair it for $costText?") + stage = 754 + return true + } + + if (repair && wrong) { + npc("Sorry friend, but I can't do anything with that.") + stage = 678 + return true + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(519, 3797) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.java deleted file mode 100644 index dbe66ddbf..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.java +++ /dev/null @@ -1,129 +0,0 @@ -package content.region.misthalin.lumbridge.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.game.world.GameWorld; - -/** - * Represents the dialogue plugin used for the donie npc. - * @author 'Vexia - * @version 1.00 - */ -@Initializable -public final class DonieDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code DonieDialogue} {@code Object}. - */ - public DonieDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code DonieDialogue} {@code Object}. - * @param player the player. - */ - public DonieDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new DonieDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there, can I help you?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Where am I?", "How are you today?", "Your shoe lace is untied."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where am I?"); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How are you today?"); - stage = 20; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Your shoe lace is untied."); - stage = 30; - break; - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the town of Lumbridge my friend."); - stage = 11; - break; - case 11: - interpreter.sendOptions("Select an Option", "Where am I?", "How are you today?", "Your shoe lace is untied."); - stage = 1; - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Aye, not too bad thank you. Lovely weather in", "" + GameWorld.getSettings().getName() + " this fine day."); - stage = 21; - break; - case 21: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Weather?"); - stage = 22; - break; - case 22: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes weather, you know."); - stage = 23; - break; - case 23: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The state or condition of the atmosphere at a time and", "place, with respect to variables such as temperature,", "moisture, wind velocity, and barometric pressure."); - stage = 24; - break; - case 24: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "..."); - stage = 25; - break; - case 25: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Not just a pretty face eh? Ha ha ha."); - stage = 26; - break; - case 26: - end(); - break; - case 30: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No it's not!"); - stage = 31; - break; - case 31: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No you're right. I have nothing to back that up."); - stage = 32; - break; - case 32: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Fool! Leave me alone!"); - stage = 33; - break; - case 33: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 2238 }; - } -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.kt new file mode 100644 index 000000000..d699af8c3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.kt @@ -0,0 +1,59 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import core.game.world.GameWorld.settings +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class DonieDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return DonieDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DonieDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DONIE_2238) + } +} + +class DonieDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.DONIE_2238) + + npc(ChatAnim.FRIENDLY, "Hello there, can I help you?") + options( + DialogueOption("whereami", "Where am I?", expression = ChatAnim.THINKING), + DialogueOption("howareyou", "How are you today?"), + DialogueOption("shoelace", "Your shoe lace is untied.", skipPlayer=true), + ) + + label("whereami") + npc("This is the town of Lumbridge my friend.") + + label("howareyou") + npc("Aye, not too bad thank you. Lovely weather in", ""+ (GameWorld.settings?.name ?: "2009Scape") +" this fine day.") + player("Weather?") + npc("Yes weather, you know.") + npc("The state or condition of the atmosphere at a time and", "place, with respect to variables such as temperature,", "moisture, wind velocity, and barometric pressure.") + player("...") + npc("Not just a pretty face eh? Ha ha ha.") + + label("shoelace") + open(player!!, DonieDialogueShoelaceFile(), npc!!) + + } +} +class DonieDialogueShoelaceFile : DialogueLabeller() { + override fun addConversation() { + player("Your shoe lace is untied.") + npc(ChatAnim.ANGRY, "No it's not!") + player("No you're right. I have nothing to back that up.") + npc(ChatAnim.ANGRY, "Fool! Leave me alone!") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt index 59e3b4775..da9ead1cc 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt @@ -10,6 +10,7 @@ import content.region.misthalin.lumbridge.quest.runemysteries.DukeHoracioRMDialo import content.region.misthalin.dorgeshuun.quest.thelosttribe.DukeHoracioTLTDialogue import core.tools.DIALOGUE_INITIAL_OPTIONS_HANDLE import core.tools.END_DIALOGUE +import content.data.Quests /** * Core dialogue plugin for Duke Horacio, redirects to more specific DialogueFiles. @@ -23,11 +24,11 @@ class DukeHoracioDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any): Boolean { npc = args[0] as NPC - if ((player.questRepository.getQuest("Dragon Slayer").getStage(player) == 100 && !player.inventory.containsItem(DragonSlayer.SHIELD) && !player.bank.containsItem(DragonSlayer.SHIELD) )|| (player.questRepository.getQuest("Dragon Slayer").isStarted(player) && !player.questRepository.getQuest("Dragon Slayer").isCompleted(player))) { - addOption("Dragon Slayer", DukeHoracioDSDialogue(player.questRepository.getStage("Dragon Slayer"))) + if ((player.questRepository.getQuest(Quests.DRAGON_SLAYER).getStage(player) == 100 && !player.inventory.containsItem(DragonSlayer.SHIELD) && !player.bank.containsItem(DragonSlayer.SHIELD) )|| (player.questRepository.getQuest(Quests.DRAGON_SLAYER).isStarted(player) && !player.questRepository.getQuest(Quests.DRAGON_SLAYER).isCompleted(player))) { + addOption("Dragon Slayer", DukeHoracioDSDialogue(player.questRepository.getStage(Quests.DRAGON_SLAYER))) } - if (!player.questRepository.isComplete("Lost Tribe") && player.questRepository.getQuest("Lost Tribe").isStarted(player)) { - addOption("Lost Tribe", DukeHoracioTLTDialogue(player.questRepository.getStage("Lost Tribe"))) + if (!player.questRepository.isComplete(Quests.THE_LOST_TRIBE) && player.questRepository.getQuest(Quests.THE_LOST_TRIBE).isStarted(player)) { + addOption("Lost Tribe", DukeHoracioTLTDialogue(player.questRepository.getStage(Quests.THE_LOST_TRIBE))) } if (!sendChoices()) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings. Welcome to my castle.") @@ -66,8 +67,8 @@ class DukeHoracioDialogue(player: Player? = null) : DialoguePlugin(player) { } 20 -> { npc("Let me see...") - if (!player.questRepository.isComplete("Rune Mysteries")) { - loadFile(DukeHoracioRMDialogue(player.questRepository.getStage("Rune Mysteries"))) + if (!player.questRepository.isComplete(Quests.RUNE_MYSTERIES)) { + loadFile(DukeHoracioRMDialogue(player.questRepository.getStage(Quests.RUNE_MYSTERIES))) } else { stage++ } diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt index 151f8e034..357c76e2d 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt @@ -11,6 +11,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests @Initializable class FredTheFarmerDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -20,8 +21,8 @@ class FredTheFarmerDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any): Boolean { npc = args[0] as NPC - if (getQuestStage(player, "Sheep Shearer") in 1..99) { - openDialogue(player, SSFredTheFarmerDialogue(getQuestStage(player, "Sheep Shearer")), npc) + if (getQuestStage(player, Quests.SHEEP_SHEARER) in 1..99) { + openDialogue(player, SSFredTheFarmerDialogue(getQuestStage(player, Quests.SHEEP_SHEARER)), npc) } else { npc(FacialExpression.ANGRY, "What are you doing on my land? You're not the one", "who keeps leaving all my gates open and letting out all", "my sheep are you?").also { stage = START_DIALOGUE } } @@ -31,7 +32,7 @@ class FredTheFarmerDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { when (stage) { START_DIALOGUE -> showTopics( - IfTopic(FacialExpression.NEUTRAL, "I'm looking for a quest.", 1000, getQuestStage(player!!, "Sheep Shearer") == 0), + IfTopic(FacialExpression.NEUTRAL, "I'm looking for a quest.", 1000, getQuestStage(player!!, Quests.SHEEP_SHEARER) == 0), Topic(FacialExpression.HALF_GUILTY, "I'm looking for something to kill.", 100), Topic(FacialExpression.HALF_GUILTY, "I'm lost.", 200) ) @@ -40,7 +41,7 @@ class FredTheFarmerDialogue(player: Player? = null) : DialoguePlugin(player) { 200 -> npc(FacialExpression.HALF_GUILTY, "How can you be lost? Just follow the road east and", "south. You'll end up in Lumbridge fairly quickly.").also { stage = END_DIALOGUE } - 1000 -> openDialogue(player, SSFredTheFarmerDialogue(getQuestStage(player, "Sheep Shearer")), npc) + 1000 -> openDialogue(player, SSFredTheFarmerDialogue(getQuestStage(player, Quests.SHEEP_SHEARER)), npc) } return true } diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java index 59b1f70f6..97610d36f 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java @@ -98,7 +98,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { stage = 41; break; case 2: - npc("Your current XP rate is: " + player.getSkills().experienceMutiplier); + npc("Your current XP rate is: " + player.getSkills().experienceMultiplier); stage = 11; break; case 3: @@ -123,7 +123,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { break; case 11: - if (player.getSkills().experienceMutiplier == 5.0) { + if (player.getSkills().experienceMultiplier == 5.0) { player.newPlayer = player.getSkills().getTotalLevel() < 50; options("Change xp rate", "Nevermind."); stage++; @@ -152,7 +152,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { switch(buttonId){ case 1: if(player.newPlayer) { - player.getSkills().experienceMutiplier = 1.0; + player.getSkills().experienceMultiplier = 1.0; stage = 14; } else { stage = 15; @@ -161,7 +161,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { break; case 2: if(player.newPlayer){ - player.getSkills().experienceMutiplier = 2.5; + player.getSkills().experienceMultiplier = 2.5; stage = 14; } else { stage = 15; @@ -173,7 +173,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { return true; case 4: if (player.newPlayer) { - player.getSkills().experienceMutiplier = 10.0; + player.getSkills().experienceMultiplier = 10.0; stage = 14; } else { stage = 15; @@ -183,7 +183,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { npc("One moment, please..."); break; case 14: - npc("Tada, your xp rate is now " + player.getSkills().experienceMutiplier); + npc("Tada, your xp rate is now " + player.getSkills().experienceMultiplier); stage = 131; break; case 15: @@ -376,7 +376,7 @@ public final class HansDialoguePlugin extends DialoguePlugin { switch (buttonId) { case 1: interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Tada! Your experience rate is now 10x.", "Happy Scaping!"); - player.getSkills().experienceMutiplier = 10.0; + player.getSkills().experienceMultiplier = 10.0; stage = 50; break; case 2: diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt index f2f157707..d01bdf614 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt @@ -13,6 +13,7 @@ import org.rs09.consts.NPCs import core.game.dialogue.IfTopic import core.game.dialogue.Topic import core.tools.END_DIALOGUE +import content.data.Quests @Initializable class LumbridgeGuideDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -23,8 +24,8 @@ class LumbridgeGuideDialogue(player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { val staff = player.isStaff val ironman = player.ironmanManager.isIronman - val sheepShearerComplete = isQuestComplete(player, "Sheep Shearer") - val cooksAssistantComplete = isQuestComplete(player, "Cook's Assistant") + val sheepShearerComplete = isQuestComplete(player, Quests.SHEEP_SHEARER) + val cooksAssistantComplete = isQuestComplete(player, Quests.COOKS_ASSISTANT) when (stage) { 0 -> npcl(FacialExpression.FRIENDLY, "Greetings, adventurer. I am Phileas, the Lumbridge Guide. I am here to give information and directions to new players. Do you require any help?").also { stage++ } diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java index f384019e9..e4e521668 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java @@ -7,6 +7,7 @@ import core.plugin.Initializable; import core.game.node.entity.player.Player; import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; /** @@ -35,7 +36,7 @@ public class SigmundDialogue extends DialoguePlugin { public boolean open(Object... args) { npc = (NPC) args[0]; interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can I help you?"); - if(player.getQuestRepository().getQuest("Lost Tribe").getStage(player) > 0 && player.getQuestRepository().getQuest("Lost Tribe").getStage(player) < 100){ + if(player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) > 0 && player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) < 100){ npc("Have you found out what it was?"); stage = 34; return true; @@ -80,12 +81,12 @@ public class SigmundDialogue extends DialoguePlugin { end(); break; case 10: - if(player.getQuestRepository().hasStarted("Lost Tribe") && !player.getQuestRepository().isComplete("Lost Tribe")){ + if(player.getQuestRepository().hasStarted(Quests.THE_LOST_TRIBE) && !player.getQuestRepository().isComplete(Quests.THE_LOST_TRIBE)){ npc("No, not right now."); stage = 12; break; } - if(player.getQuestRepository().isComplete("Goblin Diplomacy") && player.getQuestRepository().isComplete("Rune Mysteries") && !player.getQuestRepository().hasStarted("Lost Tribe")){ + if(player.getQuestRepository().isComplete(Quests.GOBLIN_DIPLOMACY) && player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES) && !player.getQuestRepository().hasStarted(Quests.THE_LOST_TRIBE)){ npc("There was recently some damage to the castle cellar.","Part of the wall has collapsed."); stage = 30; break; @@ -107,7 +108,7 @@ public class SigmundDialogue extends DialoguePlugin { case 31: npc("You should ask other people around the town if they","saw anything."); stage = END_DIALOGUE; - player.getQuestRepository().getQuest("Lost Tribe").start(player); + player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).start(player); player.setAttribute("/save:tlt-witness", TLTNPCS[0]); break; case 34: diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/SirVantDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SirVantDialogue.kt new file mode 100644 index 000000000..8b61bea29 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SirVantDialogue.kt @@ -0,0 +1,53 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Sir Vant Dialogue + * + * @comments + * I'll be honest, this is a waste of time. + * Sir Vant is part of the new tutorial between 14 July 2008 and 17 Sept 2009, a.k.a. Tutorial 2(Learing the Ropes). + * Learning the Ropes was no longer in use by the time 530 came around. They were already working on Tutorial 3(Unstable Foundations) with a different dialogue that was fully voiced. Learning the Ropes was removed eventually. + * I'm doing this to preserve the dialogue during this period, as there are sceneries left around for this. + * So much effort was put into Tutorial 1(Tutorial Island), that this shouldn't replace it. In fact, modern RS3 has tried to multiple times between 2016 and 2022, but they always end up going back to Tutorial Island. For example, Tutorial Island was removed on 28 November 2012, returned as a special underwater version on 14 December 2015, and was fully reinstated on 14 May 2018. + */ +@Initializable +class SirVantDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirVantDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirVantDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_VANT_7942) + } +} + +class SirVantDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { true } + .npcl(FacialExpression.HAPPY,"Hello there. I'm Sir Vant.") + .playerl(FacialExpression.THINKING, "Why are you down in this cave?") + .npcl("I'm guarding the entrance to the dragon's lair.") + .playerl(FacialExpression.WORRIED, "Dragon?") + .npcl("Yes, but not just any dragon - this one has three heads.") + .playerl("So why don't you kill it?") + .npc(FacialExpression.SAD,"I'm too exhausted, but I can hold it off. I've sent for", "more help from Falador, but it might be a while before", "the message gets there.") + .playerl("I could kill the dragon for you.") // Technically you have a list of options, but they are all a repeat of tutorial with an action cutscene. + .npc("Thank you very much for the offer; however, I would", "be remiss in my duties as a White Knight of Falador if", "I were to let you do that.") + //.npc("Thank you very much for the offer; however, I would", " be remiss in my duties as a White Knight of Falador if", "I were to let you do that. Here, for your kind thoughts", "you may have these old lamps.") + // He gives you 2 exp lamps of 250XP each, but I didn't want to implement it. + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt b/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt index af65c278c..965dcb157 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt @@ -19,6 +19,8 @@ import core.game.diary.AreaDiaryTask import core.game.diary.DiaryEventHookBase import core.game.diary.DiaryLevel import core.game.event.* +import content.data.Quests +import core.game.node.entity.player.link.SpellBookManager class LumbridgeAchivementDiary : DiaryEventHookBase(DiaryType.LUMBRIDGE) { @@ -346,7 +348,7 @@ class LumbridgeAchivementDiary : DiaryEventHookBase(DiaryType.LUMBRIDGE) { override fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) { when (event.dialogue) { is DukeHoracioDSDialogue -> { - val dragonSlayerStage = getQuestStage(player, "Dragon Slayer") + val dragonSlayerStage = getQuestStage(player, Quests.DRAGON_SLAYER) if ((dragonSlayerStage == 100 && event.currentStage == 4) || event.currentStage == 12) { @@ -400,14 +402,12 @@ class LumbridgeAchivementDiary : DiaryEventHookBase(DiaryType.LUMBRIDGE) { } override fun onSpellCast(player: Player, event: SpellCastEvent) { - when (event.spellId) { - Modern.LUMBRIDGE_TELEPORT -> { - finishTask( - player, - DiaryLevel.MEDIUM, - MediumTasks.CAST_LUMBRIDGE_TELEPORT - ) - } + if (event.spellBook == SpellBookManager.SpellBook.MODERN && event.spellId == Modern.LUMBRIDGE_TELEPORT) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CAST_LUMBRIDGE_TELEPORT + ) } } diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.java deleted file mode 100644 index 12025ef46..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.java +++ /dev/null @@ -1,48 +0,0 @@ -package content.region.misthalin.lumbridge.handlers; - -import content.region.misthalin.lumbridge.dialogue.BobDialogue; -import content.data.RepairItem; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.plugin.Plugin; -import core.plugin.Initializable; -import core.plugin.ClassScanner; - -/** - * Represents the plugin used to handle an item being used on bob. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class BobRepairItem extends UseWithHandler { - - /** - * Constructs a new {@code BobRepairItem} {@code Object}. - */ - public BobRepairItem() { - super(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(519, NPC_TYPE, this); - addHandler(3797, NPC_TYPE, this); - ClassScanner.definePlugin(new BobDialogue()); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - final RepairItem repair = RepairItem.forId(event.getUsedItem().getId()); - if (repair == null && !BobDialogue.BarrowsEquipment.isBarrowsItem(event.getUsedItem().getId())) { - player.getDialogueInterpreter().open(519, ((NPC) event.getUsedWith()), true, true, null); - return true; - } - player.getDialogueInterpreter().open(519, ((NPC) event.getUsedWith()), true, false, event.getUsedItem().getId(), event.getUsedItem()); - return true; - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.kt new file mode 100644 index 000000000..d939865f1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.kt @@ -0,0 +1,47 @@ +package content.region.misthalin.lumbridge.handlers + +import content.global.handlers.item.equipment.BarrowsEquipment +import content.data.RepairItem +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.npc.NPC +import core.plugin.Plugin +import core.plugin.Initializable + +private val ALL_REPAIRABLE_ITEM_IDS = (RepairItem.repairableItemIds + BarrowsEquipment.getAllRepairableBarrowsIds()).toIntArray() + +/** + * Handles items being used on Bob for repair services. + * @author 'Vexia + * @author Damighty - Kotlin conversion + */ +@Initializable +class BobRepairItem : UseWithHandler(*ALL_REPAIRABLE_ITEM_IDS) { + + override fun newInstance(arg: Any?): Plugin { + addHandler(519, NPC_TYPE, this) + addHandler(3797, NPC_TYPE, this) + return this + } + + override fun handle(event: NodeUsageEvent): Boolean { + val player = event.player + val item = event.usedItem + val npc = event.usedWith as NPC + + val isBarrowsItem = BarrowsEquipment.isBarrowsItem(item.id) + + if (isBarrowsItem) { + if (BarrowsEquipment.isFullyRepaired(item.id)) { + player.dialogueInterpreter.open(519, npc, true, true, item.id) + return true + } + } else if (RepairItem.forId(item.id) == null) { + player.dialogueInterpreter.open(519, npc, true, true) + return true + } + + player.dialogueInterpreter.open(519, npc, true, false, item.id, item) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java index ecdbd5bed..7a810e667 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java @@ -22,6 +22,7 @@ import core.plugin.Initializable; import core.tools.RandomFunction; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles the lumbridge basement. @@ -55,7 +56,6 @@ public class LumbridgeBasementPlugin extends OptionHandler { SceneryDefinition.forId(40849).getHandlers().put("option:jump-down", this); SceneryDefinition.forId(40260).getHandlers().put("option:climb-through", this); SceneryDefinition.forId(41077).getHandlers().put("option:crawl-through", this); - ClassScanner.definePlugins(new LightCreatureNPC(), new LightCreatureHandler()); SceneryBuilder.add(new Scenery(40260, Location.create(2526, 5828, 2), 2)); return this; } @@ -170,92 +170,4 @@ public class LumbridgeBasementPlugin extends OptionHandler { return null; } - /** - * Handles the sapphire lantern on a light creature. - * @author Vexia - * - */ - public class LightCreatureHandler extends UseWithHandler { - - /** - * Constructs the {@code LightCreatureHandler} - */ - public LightCreatureHandler() { - super( 4700, 4701, 4702); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(2021, NPC_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Player player = event.getPlayer(); - if (!hasRequirement(player, "While Guthix Sleeps")) - return true; - player.lock(2); - player.teleport(Location.create(2538, 5881, 0)); - return true; - } - - @Override - public Location getDestination(Player player, Node with) { - if (player.getLocation().withinDistance(with.getLocation())) { - return player.getLocation(); - } - return null; - } - - } - - - /** - * Handles the light creature npc. - * @author Vexia - * - */ - public class LightCreatureNPC extends AbstractNPC { - - /** - * Constructs the {@code LightCreatureNPC} - */ - public LightCreatureNPC() { - super(0, null); - this.setWalks(true); - this.setWalkRadius(10); - } - - /** - * Constructs the {@code LightCreatureNPC} - */ - public LightCreatureNPC(int id, Location location) { - super(id, location); - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new LightCreatureNPC(id, location); - } - - @Override - public void handleTickActions() { - if (!getLocks().isMovementLocked()) { - if (isWalks() && !getPulseManager().hasPulseRunning() && nextWalk < GameWorld.getTicks()) { - setNextWalk(); - Location l = getLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0); - if (canMove(l)) { - Pathfinder.find(this, l, true, Pathfinder.PROJECTILE).walk(this); - } - } - } - } - - @Override - public int[] getIds() { - return new int[] {2021}; - } - - } } diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java index e170abbe7..0a0d61107 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java @@ -1,5 +1,6 @@ package content.region.misthalin.lumbridge.handlers; +import core.api.Container; import core.cache.def.impl.SceneryDefinition; import core.game.node.entity.player.link.diary.DiaryType; import core.game.component.Component; @@ -21,6 +22,9 @@ import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.plugin.Plugin; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; /** * Represents the node option handler for lumbridge. @@ -45,6 +49,7 @@ public final class LumbridgeNodePlugin extends OptionHandler { SceneryDefinition.forId(22114).getHandlers().put("option:open", this); SceneryDefinition.forId(29355).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(37655).getHandlers().put("option:view", this); + SceneryDefinition.forId(org.rs09.consts.Scenery.LOGS_36974).getHandlers().put("option:take-axe", this); return this; } @@ -114,8 +119,13 @@ public final class LumbridgeNodePlugin extends OptionHandler { case 37655: player.getInterfaceManager().open(new Component(270)); break; - - + case org.rs09.consts.Scenery.LOGS_36974: + if (!addItem(player, Items.BRONZE_AXE_1351, 1, Container.INVENTORY)) { + sendMessage(player, "You don't have enough inventory space to hold that item."); + } else { + replaceScenery(node.asScenery(), org.rs09.consts.Scenery.LOGS_36975, 300, null); + } + return true; } return true; } diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHoleListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHoleListener.kt new file mode 100644 index 000000000..e5602d5b7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHoleListener.kt @@ -0,0 +1,63 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.Scenery as Sceneries +import core.game.component.Component +import core.game.global.action.ClimbActionHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation + +class LumbridgeSwampHoleListener : InteractionListener { + + val CAVE_ENTRANCE = Sceneries.DARK_HOLE_5947 + val CAVE_EXIT_ROPE = Sceneries.CLIMBING_ROPE_5946 + val WARNING_SIGN = Sceneries.WARNING_SIGN_15566 + val TOOL_STORE_FULL = Sceneries.TOOLS_10375 + val TOOL_STORE_EMPTY = 10373 + + override fun defineListeners() { + on(CAVE_ENTRANCE, IntType.SCENERY, "climb-down") { player, _ -> + if (!player.getSavedData().getGlobalData().hasTiedLumbridgeRope()) { + sendDialogue(player, "There is a sheer drop below the hole. You will need a rope.") + } else { + val insideCave = Location.create(3168, 9572, 0) + ClimbActionHandler.climb(player, Animation(Animations.HUMAN_BURYING_BONES_827), insideCave) + } + + return@on true + } + on(CAVE_EXIT_ROPE, IntType.SCENERY, "climb") { player, _ -> + val outsideCave = Location.create(3169, 3173, 0) + player.getProperties().setTeleportLocation(outsideCave); + return@on true + } + on(WARNING_SIGN, IntType.SCENERY, "read") { player, _ -> + player.getPacketDispatch().sendString("~-~-~ WARNING ~-~-~", 220, 5); + player.getPacketDispatch().sendString("Noxious gases vent into this cave.", 220, 7); + player.getPacketDispatch().sendString("Naked flames may cause an explosion!", 220, 8); + player.getPacketDispatch().sendString("Beware of vicious head-grabbing beasts!", 220, 10); + player.getPacketDispatch().sendString("Contact a Slayer master for protective headgear.", 220, 11); + player.getInterfaceManager().open(Component(220)); + return@on true + } + on(TOOL_STORE_FULL, IntType.SCENERY, "take") { player: Player, node: Node -> + if(freeSlots(player) < 2) { + sendDialogue(player, "You do not have enough inventory space.") + } + else if (player.getInventory().add(Item(Items.RAKE_5341), Item(Items.SPADE_952))) { + SceneryBuilder.replace((node as Scenery), (node as Scenery).transform(TOOL_STORE_EMPTY), 300); + } + + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHolePlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHolePlugin.java deleted file mode 100644 index e22f68882..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHolePlugin.java +++ /dev/null @@ -1,73 +0,0 @@ -package content.region.misthalin.lumbridge.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import core.game.global.action.ClimbActionHandler; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.node.scenery.SceneryBuilder; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to handle the swamp hole. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class LumbridgeSwampHolePlugin extends OptionHandler { - - /** - * Represents the top location. - */ - private static final Location TOP = Location.create(3169, 3173, 0); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(10375).getHandlers().put("option:take", this); - SceneryDefinition.forId(5947).getHandlers().put("option:climb-down", this); - SceneryDefinition.forId(5946).getHandlers().put("option:climb", this); - SceneryDefinition.forId(15566).getHandlers().put("option:read", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - switch (option) { - case "climb-down": - if (!player.getSavedData().getGlobalData().hasTiedLumbridgeRope()) { - player.getDialogueInterpreter().open(70099, "There is a sheer drop below the hole. You will need a rope."); - return true; - } else { - ClimbActionHandler.climb(player, new Animation(827), Location.create(3168, 9572, 0)); - } - case "climb": - player.getProperties().setTeleportLocation(TOP); - break; - case "take": - if (player.getInventory().freeSlots() < 2) { - player.getPacketDispatch().sendMessage("You do not have enough inventory space."); - return true; - } - if (player.getInventory().add(new Item(5341), new Item(952))) { - SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(10373), 300); - } - break; - case "read": - player.getPacketDispatch().sendString("~-~-~ WARNING ~-~-~", 220, 5); - player.getPacketDispatch().sendString("Noxious gases vent into this cave.", 220, 7); - player.getPacketDispatch().sendString("Naked flames may cause an explosion!", 220, 8); - player.getPacketDispatch().sendString("Beware of vicious head-grabbing beasts!", 220, 10); - player.getPacketDispatch().sendString("Contact a Slayer master for protective headgear.", 220, 11); - player.getInterfaceManager().open(new Component(220)); - break; - } - return true; - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt index 22aef3339..2b5a9003d 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt @@ -6,5 +6,5 @@ import core.game.world.map.zone.ZoneRestriction class TormentedDemonArea : MapArea { override fun defineAreaBorders() : Array { return arrayOf (ZoneBorders.forRegion(10329)) } - override fun getRestrictions() : Array { return arrayOf (ZoneRestriction.CANNON) } + override fun getRestrictions() : Array { return arrayOf (ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS) } } diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java index 87f5de168..17942de67 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java @@ -184,7 +184,7 @@ public class TormentedDemonNPC extends AbstractNPC { super.finalizeDeath(killer); reTransform(); fireShield = true; - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); } @Override diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/WallBeastBehavior.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/WallBeastBehavior.kt new file mode 100644 index 000000000..309fc9e0e --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/WallBeastBehavior.kt @@ -0,0 +1,145 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import core.game.interaction.MovementPulse +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.repository.Repository +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * NPCs.WALL_BEAST_7823 starts out as NPCs.HOLE_IN_THE_WALL_2058 first. + * On death, it will respawn a new hole in the wall. + * + * h2QAZzGds9o + * + * npc anim 1807 + * {3161,9547,0,0,3}-{3164,9556,0,0,4}-{3162,9574,0,0,3}-{3198,9554,0,0,7}-{3198,9572,0,0,1}-{3215,9560,0,0,1}-{3216,9588,0,0,1}- + */ +class WallBeastBehavior : NPCBehavior(NPCs.HOLE_IN_THE_WALL_2058, NPCs.WALL_BEAST_7823) { + override fun onCreation(self: NPC) { + // This NPC should never move. + self.walkRadius = 0 + self.isNeverWalks = true + } + + override fun onDeathFinished(self: NPC, entity: Entity) { + self.reTransform() + // I don't think this is needed since the respawn will be immediate. + } +} + +class WallBeastNTrigger : MapArea { + + companion object { + /** Finds the nearest NPC of npcId to location. */ + fun findNearestNPC(location: Location, npcId: Int): NPC? { + // maybe replace contentAPI's version of this + return Repository.npcs + .filter { it.id == npcId } + .toMutableList() + .sortedWith { a, b -> + return@sortedWith (Location.getDistance(a.location, location) - Location.getDistance(b.location, location)).toInt() + } + .firstOrNull() + } + + fun isHelmetInEquipment(entity: Player): Boolean { + return inEquipment(entity, Items.SPINY_HELMET_4551) || + inEquipment(entity, Items.SLAYER_HELMET_13263) || + inEquipment(entity, Items.SPIKED_HELMET_13105) || + inEquipment(entity, Items.SLAYER_HELMET_E_14636) || + inEquipment(entity, Items.SLAYER_HELMET_CHARGED_14637) + } + } + override fun defineAreaBorders(): Array { + // The goals here are in order + return arrayOf( + ZoneBorders(3161,9546,3161,9546), + ZoneBorders(3164,9555,3164,9555), + ZoneBorders(3162,9573,3162,9573), + ZoneBorders(3198,9553,3198,9553), + ZoneBorders(3198,9571,3198,9571), + ZoneBorders(3215,9559,3215,9559), + ZoneBorders(3216,9587,3216,9587), + ) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + val nearbyWallbeast = findNearestNPC(entity.location, NPCs.HOLE_IN_THE_WALL_2058) // wallbeasts are always 1 square north. + // println(nearbyWallbeast) + if (nearbyWallbeast != null) { + lock(entity, 2) + stopWalk(entity) + // Stop walk doesn't stop the player from walking on. + // You have to clear the movement pulse that is continually feeding the walk location. + val movementPulse = entity.getPulseManager().current; + if (movementPulse is MovementPulse) { + movementPulse.stop(); + } + face(entity, nearbyWallbeast.location) + queueScript(nearbyWallbeast, 2, QueueStrength.STRONG) { stage: Int -> + when (stage) { + 0 -> { + if (isHelmetInEquipment(entity)) { + animate(nearbyWallbeast, 1805) + } else { + animate(nearbyWallbeast, 1806) + } + return@queueScript delayScript(nearbyWallbeast, 1) + } + 1 -> { + if (isHelmetInEquipment(entity)) { + // You can only attack the wallbeast if you have a helmet + transformNpc(nearbyWallbeast, NPCs.WALL_BEAST_7823, 300) + return@queueScript stopExecuting(nearbyWallbeast) + } else { + animate(nearbyWallbeast, 1807) + return@queueScript delayScript(nearbyWallbeast, 4) + } + } + 2 -> { + animate(nearbyWallbeast, 1808) + return@queueScript stopExecuting(nearbyWallbeast) + } + else -> return@queueScript stopExecuting(nearbyWallbeast) + } + } + queueScript(entity, 2, QueueStrength.STRONG) { stage: Int -> + when (stage) { + 0 -> { + if (isHelmetInEquipment(entity)) { + return@queueScript stopExecuting(entity) + } + lock(entity, 5) + return@queueScript delayScript(entity, 1) + } + + 1 -> { + animate(entity, 1810) // 734 + return@queueScript delayScript(entity, 4) + } + + 2 -> { + // I don't know how much they are supposed to hit... osrs says up to 18... + impact(entity, (13 .. 18).random() , HitsplatType.NORMAL) + animate(entity, 1811) // 734 + return@queueScript stopExecuting(entity) + } + + else -> return@queueScript stopExecuting(entity) + } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt index 790b6aec2..54d38f426 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt @@ -4,6 +4,7 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable +import content.data.Quests /** * The Quest Journal and Configuration for the Cook's Assistant Quest. @@ -11,7 +12,7 @@ import core.plugin.Initializable */ @Initializable -class CooksAssistant : Quest("Cook's Assistant",15, 14, 1, 29, 0, 1, 2){ +class CooksAssistant : Quest(Quests.COOKS_ASSISTANT,15, 14, 1, 29, 0, 1, 2){ val MILK = 1927 val FLOUR = 1933 val EGG = 1944 @@ -21,7 +22,7 @@ class CooksAssistant : Quest("Cook's Assistant",15, 14, 1, 29, 0, 1, 2){ super.drawJournal(player, stage) var line = 12 - var stage = player?.questRepository?.getStage("Cook's Assistant")!! + var stage = player?.questRepository?.getStage(Quests.COOKS_ASSISTANT)!! if(stage < 10){ //If the quest has not been started diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt index 67e96da73..ae7b6439f 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt @@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable +import content.data.Quests /** * Dialogue for the Lumbridge Cook. @@ -29,16 +30,16 @@ class LumbridgeCookDialogue (player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if(player?.questRepository?.getQuest("Lost Tribe")?.getStage(player) == 10){ + if (player?.questRepository?.getQuest(Quests.THE_LOST_TRIBE)?.getStage(player) == 10) { player("Did you see what happened in the cellar?") stage = 0 return true } - if (player?.questRepository?.getQuest("Cook's Assistant")!!.getStage(player) <= 0) { //If the player has ot started cook's assistant + if (player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)!!.getStage(player) <= 0) { //If the player has ot started cook's assistant npc(FacialExpression.SAD, "What am I to do?") stage = 0 return true - } else if (player?.questRepository?.getQuest("Cook's Assistant")!!.getStage(player) in 10..99) { //During the Cook's Assistant Quest + } else if (player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)!!.getStage(player) in 10..99) { //During the Cook's Assistant Quest if (player.getAttribute("cooks_assistant:all_submitted", false) || (player.getAttribute("cooks_assistant:milk_submitted", false) && player.getAttribute("cooks_assistant:flour_submitted", false) && player.getAttribute("cooks_assistant:egg_submitted", false))){ //If the player has handed all the ingredients to the chef but did not continue the dialogue npc(FacialExpression.HAPPY, "You've brought me everything I need! I am saved!", "Thank you!") stage = 200 @@ -57,14 +58,14 @@ class LumbridgeCookDialogue (player: Player? = null) : DialoguePlugin(player){ } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - if(player.questRepository.getQuest("Lost Tribe").getStage(player) == 10){ + if (player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 10) { when(stage){ //Lost Tribe 0 -> npc("Last night I was in the kitchen and I heard a noise","from the cellar. I opened the trapdoor and saw a","creature dart into a hole in the wall.").also { stage++ } 1 -> npc("It looked a bit like a goblin, but it had big bulging eyes.","It wasn't wearing armour, but it had this odd helmet","with a light on it.").also { stage++ } 2 -> npc("The tunnel was too dark for me to follow it, so I went","to tell the Duke. But when we went down to the cellar","the hole had been blocked up, and no one believes me.").also { stage++ } 3 -> player("I believe you.").also { stage++ } - 4 -> npc("Thank you, ${player.username}! If you can convince the Duke","I'm telling the truth then we can get to the bottom of","this mystery.").also { stage = 1000; player.questRepository.getQuest("Lost Tribe").setStage(player,20) } + 4 -> npc("Thank you, ${player.username}! If you can convince the Duke","I'm telling the truth then we can get to the bottom of","this mystery.").also { stage = 1000; player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,20) } 5 -> end() } return true @@ -117,7 +118,7 @@ class LumbridgeCookDialogue (player: Player? = null) : DialoguePlugin(player){ 44 -> npc(FacialExpression.ANGRY, "I AM a real cook! I haven't got time to be chatting", "about culinary fashion. I'm in desperate need of help!").also { stage = 21 } //Yes, I'll help you - 50 -> npc(FacialExpression.HAPPY, "Oh thank you, thank you. I need milk, an egg and", "flour. I'd be very grateful if you can get them for me.").also{ player?.questRepository?.getQuest("Cook's Assistant")?.start(player!!); stage++ } + 50 -> npc(FacialExpression.HAPPY, "Oh thank you, thank you. I need milk, an egg and", "flour. I'd be very grateful if you can get them for me.").also{ player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)?.start(player!!); stage++ } 51 -> player(FacialExpression.NEUTRAL, "So where do I find these ingredients then?").also { stage = 60 } //Where do I find these ingredients? @@ -241,10 +242,10 @@ class LumbridgeCookDialogue (player: Player? = null) : DialoguePlugin(player){ 203 -> npc(FacialExpression.NEUTRAL, "Maybe, but I won't be holding my breath.").also { stage++ } //Activate the Cook's Assistant Quest Complete Certificate - 204 -> end().also { player?.questRepository?.getQuest("Cook's Assistant")?.finish(player!!) } + 204 -> end().also { player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)?.finish(player!!) } //Dialogue after Cook's Assistant Completion - 300 -> if(player.questRepository.getQuest("Lost Tribe").getStage(player) == 10) { + 300 -> if(player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 10) { player("Do you know what happened in the castle cellar?").also { stage = 600 } } else { options("I am getting strong and mighty.", "I keep on dying.", "Can I use your range?").also { stage++ } diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/DramenTreeListener.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/DramenTreeListener.kt deleted file mode 100644 index 735e384d7..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/DramenTreeListener.kt +++ /dev/null @@ -1,46 +0,0 @@ -package content.region.misthalin.lumbridge.quest.lostcity - -import core.game.node.scenery.Scenery -import content.data.skill.SkillingTool -import content.global.skill.gather.woodcutting.WoodcuttingSkillPulse -import core.game.world.map.Location -import org.rs09.consts.NPCs -import org.rs09.consts.Scenery as Sceneries -import core.game.interaction.InteractionListener -import core.api.getQuestStage -import core.api.sendMessage -import core.game.interaction.IntType - -class DramenTreeListener : InteractionListener { - - override fun defineListeners() { - - on(Sceneries.DRAMEN_TREE_1292, IntType.SCENERY, "chop down"){ player, node -> - val questStage = getQuestStage(player,"Lost City") - if (SkillingTool.getHatchet(player) == null) { - sendMessage(player,"You do not have an axe which you have the level to use.") - return@on true - } - if (questStage < 20) { - return@on true - } - if (questStage == 20) { - if (player.getAttribute("treeSpawned", false)) { - return@on true - } - val spirit = TreeSpiritNPC(NPCs.TREE_SPIRIT_655, Location(2862, 9734, 0)) - spirit.target = player - spirit.init() - spirit.attack(player) - player.setAttribute("treeSpawned", true) - spirit.sendChat("You must defeat me before touching the tree!") - return@on true - } - - player.pulseManager.run(WoodcuttingSkillPulse(player, node as Scenery)) - return@on true - } - - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt index f83e0248a..89f48fe42 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt @@ -1,21 +1,29 @@ package content.region.misthalin.lumbridge.quest.lostcity +import core.api.Event +import core.api.LoginListener +import core.api.clearScripts +import core.api.getQuestStage +import core.game.event.EventHook +import core.game.event.InteractionEvent +import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.game.node.item.Item +import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery /** * LostCity class for the Lost City quest - * @author lila - * @author Vexia - * @author Aero + * @author lila, Vexia, Aero, Player Name */ @Initializable -class LostCity : Quest("Lost City", 83, 82, 3, 147, 0, 1, 6) { - +class LostCity : Quest(Quests.LOST_CITY, 83, 82, 3, 147, 0, 1, 6), LoginListener { class SkillRequirement(val skill: Int?, val level: Int?) val requirements = arrayListOf() @@ -66,9 +74,45 @@ class LostCity : Quest("Lost City", 83, 82, 3, 147, 0, 1, 6) { line(player, BLUE + "and be able to defeat a " + RED + "Level 101 Spirit without weapons", line++) } + private val DramenTreeHook = object : EventHook { + override fun process(entity: Entity, event: InteractionEvent) { + if (event.target.id == Scenery.DRAMEN_TREE_1292 && event.option == "chop down") { + val player = entity as Player + val questStage = getQuestStage(player, Quests.LOST_CITY) + if (questStage == 20) { + if (player.getAttribute("treeSpawned", false)) { + return + } + val spirit = TreeSpiritNPC(NPCs.TREE_SPIRIT_655, Location(2862, 9734, 0)) + spirit.target = player + spirit.init() + spirit.attack(player) + player.setAttribute("treeSpawned", true) + spirit.sendChat("You must defeat me before touching the tree!") + } + } + } + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + if (stage <= 20) { + player.hook(Event.Interacted, DramenTreeHook) + } + if (stage == 21) { + player.unhook(DramenTreeHook) + } + } + + override fun login(player: Player) { + if (getQuestStage(player, Quests.LOST_CITY) <= 20) { + player.hook(Event.Interacted, DramenTreeHook) + } + } + override fun newInstance(`object`: Any?): Quest { requirements.add(SkillRequirement(Skills.WOODCUTTING, 36)) requirements.add(SkillRequirement(Skills.CRAFTING, 31)) return this } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt index c922a107e..32bef2049 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt @@ -13,6 +13,7 @@ import core.game.interaction.IntType import org.rs09.consts.Scenery as Sceneries import core.game.interaction.InteractionListener import core.game.world.GameWorld +import content.data.Quests /** * This class covers some listeners for the Lost City quest @@ -27,12 +28,11 @@ class LostCityListeners : InteractionListener { // the shed teleport, to allow players to access zanaris if they enter the shed while wielding the dramen staff on(Sceneries.DOOR_2406, IntType.SCENERY,"open"){ player, node -> core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,node as Scenery) - val quest = "Lost City" val isOutsideShed = player.location.x < node.location.x - val canDramenTeleport = inEquipment(player,Items.DRAMEN_STAFF_772) && ( getQuestStage(player,quest) > 20 ) && isOutsideShed - if(canDramenTeleport) { + val canDramenTeleport = inEquipment(player,Items.DRAMEN_STAFF_772) && getQuestStage(player, Quests.LOST_CITY) > 20 && isOutsideShed + if (canDramenTeleport) { var count = 0 - // pulser to handle the teleport. after 2 ticks it checks if the player hasnt completed lost city; if so, then it finishes the quest after the teleport + // pulser to handle the teleport. after 2 ticks it checks if the player hasn't completed Lost City; if so, then it finishes the quest after the teleport GameWorld.Pulser.submit(object : Pulse(2) { override fun pulse(): Boolean { when (count++) { @@ -44,9 +44,9 @@ class LostCityListeners : InteractionListener { teleport(player, Location(2452, 4473, 0), TeleportType.FAIRY_RING) } } - 1 -> return isQuestComplete(player,quest) + 1 -> return isQuestComplete(player, Quests.LOST_CITY) 2 -> { - finishQuest(player,quest) + finishQuest(player, Quests.LOST_CITY) return true } } @@ -66,8 +66,8 @@ class LostCityListeners : InteractionListener { if (removeItem(player, Item(Items.DRAMEN_BRANCH_771, 1), Container.INVENTORY)) { sendDialogue(player,"You carve the branch into a staff.") addItem(player, Items.DRAMEN_STAFF_772, 1, Container.INVENTORY) - } } + } return@onUseWith true } } diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt index 8a3e0baf2..15800e2f7 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt @@ -5,6 +5,7 @@ import core.plugin.Initializable import org.rs09.consts.NPCs import core.api.getQuestStage import core.api.setQuestStage +import content.data.Quests /** * ShamusDialogue, to handle the dialogue of Shamus the Leprechaun from the Lost City quest @@ -13,9 +14,6 @@ import core.api.setQuestStage */ @Initializable class ShamusDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { - - val quest = "Lost City" - override fun open(vararg args: Any?): Boolean { npcl(core.game.dialogue.FacialExpression.ANNOYED,"Ay yer big elephant! Yer've caught me, to be sure! What would an elephant like yer be wanting wid ol' Shamus then?") stage = 0 @@ -23,7 +21,7 @@ class ShamusDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin } override fun handle(interfaceId: Int, buttonId: Int): Boolean { - when(getQuestStage(player,quest)) { + when(getQuestStage(player, Quests.LOST_CITY)) { 0 -> when(stage++) { 0 -> playerl(core.game.dialogue.FacialExpression.THINKING, "I'm not sure.") 1 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Well you'll have to be catchin' me again when yer are, elephant!") @@ -45,7 +43,7 @@ class ShamusDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin 12 -> end().also { ShamusTreeListener.disappearShamus() sendDialogue("The leprechaun magically disappears.") - setQuestStage(player,quest,20) + setQuestStage(player, Quests.LOST_CITY, 20) } } else -> when(stage++) { diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt index 0449ca69e..754a82d69 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt @@ -1,7 +1,6 @@ package content.region.misthalin.lumbridge.quest.lostcity import core.game.node.entity.Entity -import core.game.node.entity.combat.CombatStyle import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player import core.game.world.map.Location @@ -10,6 +9,7 @@ import org.rs09.consts.NPCs import core.api.getQuestStage import core.api.sendDialogue import core.api.setQuestStage +import content.data.Quests /** * TreeSpiritNPC class to handle the tree spirit that spawns out of the dramen tree @@ -47,9 +47,8 @@ class TreeSpiritNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, l override fun finalizeDeath(killer: Entity) { super.finalizeDeath(killer) if (killer is Player) { - val quest = "Lost City" - if (getQuestStage(killer,quest) == 20) { - setQuestStage(killer,quest,21) + if (getQuestStage(killer, Quests.LOST_CITY) == 20) { + setQuestStage(killer, Quests.LOST_CITY,21) sendDialogue(killer, "With the Tree Spirit defeated you can now chop the tree.") } } diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt index a82989f47..9281c9153 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt @@ -7,6 +7,7 @@ import core.game.dialogue.Topic import core.tools.END_DIALOGUE import core.api.getQuestStage import core.api.startQuest +import content.data.Quests /** * WarriorDialogue, to handle the dialogue for the Warrior in the Lost City quest @@ -17,7 +18,7 @@ import core.api.startQuest class WarriorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { - when(getQuestStage(player,"Lost City")) { + when(getQuestStage(player,Quests.LOST_CITY)) { 10 -> playerl(core.game.dialogue.FacialExpression.THINKING,"So let me get this straight: I need to search the trees around here for a leprechaun; and then when I find him, he will tell me where this 'Zanaris' is?").also { stage = 1000 } 20, 21 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Have you found anything yet?").also { stage = 2000 } 100 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Hey, thanks for all the information. It REALLY helped me out in finding the lost city of Zanaris and all.").also { stage = 3000 } @@ -49,7 +50,7 @@ class WarriorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugi 6 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"So a leprechaun knows where Zanaris is eh?").also { stage = 600 } 7 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Thanks for the help!").also { stage = 700 } 8 -> end().also { - startQuest(player,"Lost City") + startQuest(player,Quests.LOST_CITY) } 100 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"We're looking for Zanaris...GAH! I mean we're not here for any particular reason at all.").also { stage = 3 } 101 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Well we're on an adventure right now. Mind you, this is OUR adventure and we don't want to share it - find your own!").also { stage = 2 } diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt index 7eb8b9547..42ad4fa36 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt @@ -6,6 +6,7 @@ import core.game.node.item.Item import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests class DukeHoracioRMDialogue(val questStage: Int) : DialogueFile() { @@ -29,7 +30,7 @@ class DukeHoracioRMDialogue(val questStage: Int) : DialogueFile() { 10 -> npc("Thank you very much, stranger. I am sure the head", "wizard will reward you for such an interesting find.").also { stage++ } 11 -> { interpreter!!.sendDialogue("The Duke hands you an " + Quest.BLUE + "air talisman.").also { stage++ } - player!!.questRepository.getQuest("Rune Mysteries").start(player) + player!!.questRepository.getQuest(Quests.RUNE_MYSTERIES).start(player) if (!player!!.inventory.add(TALISMAN)) { GroundItemManager.create(TALISMAN, player!!.location, player) } diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java index ebe46af39..85e329907 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java @@ -3,6 +3,7 @@ package content.region.misthalin.lumbridge.quest.runemysteries; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the rune mysteries fortress quest. @@ -15,7 +16,7 @@ public class RuneMysteries extends Quest { * Constructs a new {@code RuneMysteries} {@code Object}. */ public RuneMysteries() { - super("Rune Mysteries", 27, 26, 1, 63, 0, 1, 6); + super(Quests.RUNE_MYSTERIES, 27, 26, 1, 63, 0, 1, 6); } @Override diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt index 9392a5926..12a1af387 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt @@ -6,6 +6,7 @@ import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.Items +import content.data.Quests class SSFredTheFarmerDialogue(val questStage: Int) : DialogueFile() { companion object { @@ -58,7 +59,7 @@ class SSFredTheFarmerDialogue(val questStage: Int) : DialogueFile() { 2000 -> { // NOTE: In a July 2009 video, this only happens when the dialogue ends - startQuest(player!!, "Sheep Shearer") + startQuest(player!!, Quests.SHEEP_SHEARER) npc(FacialExpression.NEUTRAL, "Good! Now one more thing, do you actually know how", "to shear a sheep?").also { stage++ } } 2001 -> options("Of course!", "Err. No, I don't know actually.").also { stage++ } @@ -150,7 +151,7 @@ class SSFredTheFarmerDialogue(val questStage: Int) : DialogueFile() { 30101 -> { val ballsOfWoolDelivered = SheepShearer.deliverBallsOfWool(player!!) if (SheepShearer.getBallsOfWoolRequired(player!!) == 0) { - setQuestStage(player!!, "Sheep Shearer", 90) + setQuestStage(player!!, Quests.SHEEP_SHEARER, 90) player(FacialExpression.HAPPY, "That's the last of them.").also { stage = 30300 } } else { sendDialogue(player!!, "You give Fred $ballsOfWoolDelivered balls of wool").also { stage = 30200 } @@ -162,7 +163,7 @@ class SSFredTheFarmerDialogue(val questStage: Int) : DialogueFile() { 30202 -> player(FacialExpression.NEUTRAL, "Ok I'll work on it.").also { stage = END_DIALOGUE } 30300 -> npc(FacialExpression.SAD, "I guess I'd better pay you then.").also { stage++ } - STAGE_FINISH_QUEST -> finishQuest(player!!, "Sheep Shearer").also { stage = END_DIALOGUE } + STAGE_FINISH_QUEST -> finishQuest(player!!, Quests.SHEEP_SHEARER).also { stage = END_DIALOGUE } 31000 -> npc(FacialExpression.NEUTRAL, "You need to collect ${SheepShearer.getBallsOfWoolRequired(player!!)} more balls of wool.").also { stage++ } 31001 -> { diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt index a30669774..634041363 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt @@ -8,9 +8,10 @@ import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items import kotlin.math.min +import content.data.Quests @Initializable -class SheepShearer : Quest("Sheep Shearer", 28, 27, 1, 179, 0, 20, 21) { +class SheepShearer : Quest(Quests.SHEEP_SHEARER, 28, 27, 1, 179, 0, 20, 21) { companion object { val ATTR_NUM_BALLS_OF_WOOL_DELIVERED = "/save:sheep-shearer:num-balls-of-wool-delivered" val ATTR_IS_PENGUIN_SHEEP_SHEARED = "/save:sheep-shearer:is-penguin-sheep-sheared" diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/JunaDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/JunaDialogue.kt new file mode 100644 index 000000000..b5a2a1685 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/JunaDialogue.kt @@ -0,0 +1,204 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +/** + * Anim 2056 - Juna puts head into itself + * Anim 2055 - Juna lifts tail + */ +class JunaDialogue : InteractionListener { + override fun defineListeners() { + // Juna is a scenery. + on(Scenery.JUNA_31302, SCENERY, "talk-to") { player, _ -> + openDialogue(player, JunaDialogueFile(), NPC(NPCs.JUNA_2023)) + return@on true + } + // This is quest varbit 451 controlled. When it is set to 2, JUNA changes in ID + on(Scenery.JUNA_31303, SCENERY, "talk-to") { player, node -> + openDialogue(player, JunaDialogueFile(), NPC(NPCs.JUNA_2023)) + return@on true + } + } +} + +class JunaDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.TEARS_OF_GUTHIX, 0) + .branch { player -> if(TearsOfGuthix.hasRequirements(player)) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + // Inauthentic, but absolutely no source on this... + .npcl(FacialExpression.OLD_NORMAL, "You are not strong enough of an adventurer to partake this quest. Come back when you are stronger.") + .linel("You do not meet the quest requirements for Tears of Guthix.") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Tell me... a story...") + .playerl(FacialExpression.THINKING, "A story?") + .npcl(FacialExpression.OLD_NORMAL, "I have been waiting here three thousand years, guarding the Tears of Guthix. I serve my master faithfully, but I am bored.") + .npcl(FacialExpression.OLD_NORMAL, "An adventurer such as yourself must have many tales to tell. If you can entertain me, I will let you into the cave for a time.") + .npcl(FacialExpression.OLD_NORMAL, "The more I enjoy your story, the more time I will give you in the cave.") + .npcl(FacialExpression.OLD_NORMAL, "Then you can drink of the power of balance, which will make you stronger in whatever area you are weakest.") + + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Okay...") + .linel("You tell Juna some stories of your adventures.") + // Yes I know. + .playerl("Blah blah blah something about recent quest I did that I'm forced to talk about, but looks like you want me to shut up.") + .npcl(FacialExpression.OLD_NORMAL,"Blah blah blah that's so cool, I'm totally interested in what you are saying and am totally not falling asleep at this point.") + // ^ I'm not going to type out 120 fucking quest dialogue for shit you wouldn't care reading. + .npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. I will let you into the cave for a short time.") + .npcl(FacialExpression.OLD_NORMAL,"But first you will need to make a bowl in which to collect the tears.") + // The camera pans south to the part of the cave containing guthix-infused rocks. + .npcl(FacialExpression.OLD_NORMAL,"There is a cave on the south side of the chasm that is similarly infused with the power of Guthix. The stone in that cave is the only substance that can catch the Tears of Guthix.") + .npcl(FacialExpression.OLD_NORMAL,"Mine some stone from that cave, make it into a bowl, and bring it to me, and then I will let you catch the Tears.") + .endWith { _, player -> + if(getQuestStage(player, Quests.TEARS_OF_GUTHIX) == 0) { + setQuestStage(player, Quests.TEARS_OF_GUTHIX, 1) + } + } + + optionBuilder.option_playerl("Not now.") + .end() + + optionBuilder.option_playerl("What are the Tears of Guthix?") + .npcl(FacialExpression.OLD_NORMAL, "The Third Age of the world was a time of great conflict, of destruction never seen before or since, when all the gods save Guthix warred for control.") + .npcl(FacialExpression.OLD_NORMAL, "The colossal Wyrms, of whom today's dragons are a pale reflection, turned all the sky to fire, while on the ground armies of foot soldiers, goblins and trolls and humans, filled the valleys and plains with blood.") + .npcl(FacialExpression.OLD_NORMAL, "In time the noise of the conflict woke Guthix from His deep slumber, and He rose and stood in the centre of the battlefield so that the splendour of His wrath filled the world, and He called for the conflict to cease!") + .npcl(FacialExpression.OLD_NORMAL, "Silence fell, for the gods knew that none could challenge the power of the mighty Guthix -- for His power is that of nature itself, to which all other things are subject, in the end.") + .npcl(FacialExpression.OLD_NORMAL, "Guthix reclaimed that which had been stolen from Him, and went back underground to return to His sleep and continue to draw the world's power into Himself.") + .npcl(FacialExpression.OLD_NORMAL, "But on His way into the depths of the earth He sat and rested in this cave; and, thinking of the battle-scarred desert that now stretched from one side of His world to the other, He wept.") + .npcl(FacialExpression.OLD_NORMAL, "And so great was His sorrow, and so great was His life- giving power, that the rocks themselves began to weep with Him.") + .npcl(FacialExpression.OLD_NORMAL, "Later, Guthix noticed that the rocks continued to weep, and that their tears were infused with a small part of His power.") + .npcl(FacialExpression.OLD_NORMAL, "So He set me, His servant, to guard the cave, and He entrusted to me the task of judging who was and was not worthy to access the tears.") + .npcl(FacialExpression.OLD_NORMAL, "Tell me... a story...") + .goto(returnJoin) + } + return@let builder.goto(returnJoin) + } + + + b.onQuestStages(Quests.TEARS_OF_GUTHIX, 1) + .npc(FacialExpression.OLD_NORMAL, "Before you can collect the Tears of Guthix you must", "make a bowl out of the stone in the cave on the south", "of the chasm.") + .branch { player -> if(inInventory(player, Items.STONE_BOWL_4704)) { 1 } else { 0 } } + .let{ branch -> + branch.onValue(0) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("But I don't know how to reach the cave!") + .npcl(FacialExpression.OLD_NORMAL, "I will tell you the story of the light-creatures.") + .npcl(FacialExpression.OLD_NORMAL, "Myriad and beautiful were the creatures and civilizations of the early ages of the world. Gielinor was a work of art, shaped lovingly over the millennia by the creative mind of Guthix.") + .npcl(FacialExpression.OLD_NORMAL, "Only the sturdiest races survived the Godwars, and even then only by abandoning their high culture and gearing their societies towards war. Of the more delicate races there is now no trace, and almost no memory.") + .npcl(FacialExpression.OLD_NORMAL, "One such race had bodies as fragile as snowflakes, yet they built crystal cities that stood for a thousand years.") + .npcl(FacialExpression.OLD_NORMAL, "The wind would whisper through the spires and fill them with sweet harmonies, and the rising sun would shine through the precious gems that studded the towers and create inter plays of light as if rainbows were dancing.") + .npcl(FacialExpression.OLD_NORMAL, "Indeed, so marvellous was this light-show at its height that the patterns of light themselves became alive, and great flocks of luminous creatures rode along the gem- cast beams, each drawn to its own colour.") + .npcl(FacialExpression.OLD_NORMAL, "The creatures you see floating in this chasm are the last sorry remnants of that age. I do not know how they made their way here and survived to this time, but I am grateful for their company.") + .end() + + optionBuilder.option_playerl("What are the Tears of Guthix?") + .npcl(FacialExpression.OLD_NORMAL, "The Third Age of the world was a time of great conflict, of destruction never seen before or since, when all the gods save Guthix warred for control.") + .npcl(FacialExpression.OLD_NORMAL, "The colossal Wyrms, of whom today's dragons are a pale reflection, turned all the sky to fire, while on the ground armies of foot soldiers, goblins and trolls and humans, filled the valleys and plains with blood.") + .npcl(FacialExpression.OLD_NORMAL, "In time the noise of the conflict woke Guthix from His deep slumber, and He rose and stood in the centre of the battlefield so that the splendour of His wrath filled the world, and He called for the conflict to cease!") + .npcl(FacialExpression.OLD_NORMAL, "Silence fell, for the gods knew that none could challenge the power of the mighty Guthix -- for His power is that of nature itself, to which all other things are subject, in the end.") + .npcl(FacialExpression.OLD_NORMAL, "Guthix reclaimed that which had been stolen from Him, and went back underground to return to His sleep and continue to draw the world's power into Himself.") + .npcl(FacialExpression.OLD_NORMAL, "But on His way into the depths of the earth He sat and rested in this cave; and, thinking of the battle-scarred desert that now stretched from one side of His world to the other, He wept.") + .npcl(FacialExpression.OLD_NORMAL, "And so great was His sorrow, and so great was His life- giving power, that the rocks themselves began to weep with Him.") + .npcl(FacialExpression.OLD_NORMAL, "Later, Guthix noticed that the rocks continued to weep, and that their tears were infused with a small part of His power.") + .npcl(FacialExpression.OLD_NORMAL, "So He set me, His servant, to guard the cave, and He entrusted to me the task of judging who was and was not worthy to access the tears.") + .end() + + optionBuilder.option_playerl("Not now.") + .end() + } + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) + .playerl("I have a bowl.") + .npcl(FacialExpression.OLD_NORMAL, "I will keep your bowl for you, so that you may collect the tears many times in the future.") + .npcl(FacialExpression.OLD_NORMAL, "Now... tell me another story, and I will let you collect the tears for the first time.") + .endWith { _, player -> + if (removeItem(player, Items.STONE_BOWL_4704)) { + finishQuest(player, Quests.TEARS_OF_GUTHIX) + } + } + + b.onQuestStages(Quests.TEARS_OF_GUTHIX, 100) + .npcl(FacialExpression.OLD_NORMAL, "Tell me... a story...") + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Okay...") + .linel("You tell Juna some stories of your adventures.") + // Yes I know. + .playerl("Blah blah blah something about recent quest I did that I'm forced to talk about, but looks like you want me to shut up.") + .npcl(FacialExpression.OLD_NORMAL,"Blah blah blah that's so cool, I'm totally interested in what you are saying and am totally not falling asleep at this point.") + // ^ I'm not going to type out 120 fucking quest dialogue for shit you wouldn't care reading. + .branch { player -> + if(TearsOfGuthix.daysLeft(player) > 0 && TearsOfGuthix.xpLeft(player) > 0 && TearsOfGuthix.questPointsLeft(player) > 0) { + 3 + } else if(TearsOfGuthix.xpLeft(player) > 0 && TearsOfGuthix.questPointsLeft(player) > 0) { + 2 + } else if(TearsOfGuthix.daysLeft(player) > 0) { + 1 + } else { + 0 // Success branch + } + } + .let{ branch -> + // https://www.youtube.com/watch?v=X3M9CiS_BeU if not enough time has passed. + branch.onValue(3) + .manualStage { df, player, _, _ -> npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. But I will not permit any adventurer to access the tears more than once a week. Come back in " + TearsOfGuthix.daysLeft(player).toString() + " days.") } + .npcl(FacialExpression.OLD_NORMAL,"You should use that time to have more adventures! You may not re-enter the cave until you have more stories to tell.") + .manualStage { df, player, _, _ -> sendDialogue(player, "You cannot enter the cave again until you have gained either one quest point or " + TearsOfGuthix.xpLeft(player) + " total XP.") } + .end() + + branch.onValue(2) + .npc(FacialExpression.OLD_NORMAL,"Your story has entertained me. But it is a poor sort", "of adventurer who only tells stories of the past and", "does not find new stories to tell. I will not let you", "into the cave again until you have had more adventures.") + .manualStage { df, player, _, _ -> sendDialogue(player, "You cannot enter the cave again until you have gained either one quest point or " + TearsOfGuthix.xpLeft(player) + " total XP.") } + .end() + + branch.onValue(1) + .manualStage { df, player, _, _ -> npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. But I will not permit any adventurer to access the tears more than once a week. Come back in " + TearsOfGuthix.daysLeft(player).toString() + " days.") } + .end() + + return@let branch + }.onValue(0) + .npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. I will let you into the cave for a short time.") + .branch { player -> if(TearsOfGuthix.isHandsFree(player)) { 1 } else { 0 } } + .let{ branch -> + // https://www.youtube.com/watch?v=J76OGo-hHlA your hands must be free. + branch.onValue(0) + .npc(FacialExpression.OLD_NORMAL,"But you must have both hands free to carry the bowl.", "Speak to me again when your hands are free.") + .end() + return@let branch + }.onValue(1) + // https://www.youtube.com/watch?v=Mj3pW-Brv9c + .npc(FacialExpression.OLD_NORMAL,"Collect as much as you can from the blue streams. If", "you let in water from the green streams, it will take", "away from the blue. For Guthix is god of balance, and", "balance lies in the juxtaposition of opposites.") + .endWith { _, player -> + TearsOfGuthixMinigame.startGame(player) + } + + optionBuilder.option_playerl("Not now.") + .end() + } + return@let builder.goto(returnJoin) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/LightCreatureBehavior.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/LightCreatureBehavior.kt new file mode 100644 index 000000000..daa8c6885 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/LightCreatureBehavior.kt @@ -0,0 +1,129 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.GameWorld.ticks +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class LightCreatureBehavior : NPCBehavior(NPCs.LIGHT_CREATURE_2021) { + + companion object { + fun moveLightCreature(self: NPC, location: Location) { + self.setNextWalk() + Pathfinder.find(self, location, true, Pathfinder.PROJECTILE).walk(self) + } + + } + + override fun tick(self: NPC): Boolean { + if (!self.locks.isMovementLocked) { + self.isWalks = true + self.walkRadius = 20 + if (self.isWalks && !self.pulseManager.hasPulseRunning() && self.nextWalk < ticks) { + self.setNextWalk() + val l: Location = self.location.transform(-5 + RandomFunction.random(self.walkRadius), -5 + RandomFunction.random(self.walkRadius), 0) + if (self.canMove(l)) { + Pathfinder.find(self, l, true, Pathfinder.PROJECTILE).walk(self) + } + } + } + return true + } + +} + +/* + + /** + * Handles the sapphire lantern on a light creature. + * @author Vexia + * + */ + public class LightCreatureHandler extends UseWithHandler { + + /** + * Constructs the {@code LightCreatureHandler} + */ + public LightCreatureHandler() { + super( 4700, 4701, 4702); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2021, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (!hasRequirement(player, "While Guthix Sleeps")) + return true; + player.lock(2); + player.teleport(Location.create(2538, 5881, 0)); + return true; + } + + @Override + public Location getDestination(Player player, Node with) { + if (player.getLocation().withinDistance(with.getLocation())) { + return player.getLocation(); + } + return null; + } + + } + + + /** + * Handles the light creature npc. + * @author Vexia + * + */ + public class LightCreatureNPC extends AbstractNPC { + + /** + * Constructs the {@code LightCreatureNPC} + */ + public LightCreatureNPC() { + super(0, null); + this.setWalks(true); + this.setWalkRadius(10); + } + + /** + * Constructs the {@code LightCreatureNPC} + */ + public LightCreatureNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new LightCreatureNPC(id, location); + } + + @Override + public void handleTickActions() { + if (!getLocks().isMovementLocked()) { + if (isWalks() && !getPulseManager().hasPulseRunning() && nextWalk < GameWorld.getTicks()) { + setNextWalk(); + Location l = getLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0); + if (canMove(l)) { + Pathfinder.find(this, l, true, Pathfinder.PROJECTILE).walk(this); + } + } + } + } + + @Override + public int[] getIds() { + return new int[] {2021}; + } + + } +} + */ \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthix.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthix.kt new file mode 100644 index 000000000..072c108a8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthix.kt @@ -0,0 +1,133 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Tears of Guthix Quest + * + * Most of the attributes are for the minigame. + * In order to reset, setQuestStage + * + * if (VARPBIT[451] > 1) return 2; if (VARPBIT[451] == 0) return 0; return 1; }; if (arg0 == 88) + */ +@Initializable +class TearsOfGuthix : Quest(Quests.TEARS_OF_GUTHIX, 120, 119, 1, 449, 451, 0, 1, 2) { + + companion object { + const val attributePreviousDate = "/save:quest:tearsofguthix-previousdateofaccess" // The date in milliseconds in which TOG was played. + const val attributePreviousXPAmount = "/save:quest:tearsofguthix-previousxpamount" // The last snapshot of XP user had. + const val attributePreviousQuestPoints = "/save:quest:tearsofguthix-previousquestpoints" // The last snapshot of quest points user had. + + fun isHandsFree(player: Player): Boolean { + return getItemFromEquipment(player, EquipmentSlot.WEAPON) == null + && getItemFromEquipment(player, EquipmentSlot.SHIELD) == null + } + + fun daysLeft(player: Player): Int { + val currentTime = System.currentTimeMillis() + val previousTime = getAttribute(player, attributePreviousDate, 0) + + val numberOfDaysLeft = (currentTime - previousTime) / 86400000L + return 6 - numberOfDaysLeft.toInt() + } + + fun xpLeft(player: Player): Int { + val currentXP = player.skills.totalXp + val previousXP = getAttribute(player, attributePreviousXPAmount, 0) + return 100000 - (currentXP - previousXP) + } + + fun questPointsLeft(player: Player): Int { + val currentQuestPoints = getQuestPoints(player) + val previousQuestPoints = getAttribute(player, attributePreviousQuestPoints, 0) + return 1 - (currentQuestPoints - previousQuestPoints) + } + + fun hasRequirements(player: Player): Boolean { + return arrayOf( + getQuestPoints(player) >= 43, + hasLevelStat(player, Skills.FIREMAKING, 49), + hasLevelStat(player, Skills.CRAFTING, 20), + hasLevelStat(player, Skills.MINING, 20), + ).all { it } + } + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.TEARS_OF_GUTHIX) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Juna the serpent?? who", line++, false) + line(player, "lives deep in the !!Lumbridge Swamp Caves??.", line++, false) + line(player, "I will need to have:", line++, false) + line(player, "Level 49 firemaking", line++, hasLevelStat(player, Skills.FIREMAKING, 49)) + line(player, "!!Level 20 crafting??", line++, hasLevelStat(player, Skills.CRAFTING, 20)) + line(player, "!!Level 20 mining??", line++, hasLevelStat(player, Skills.MINING, 20)) + line(player, "!!43 quest points??", line++, getQuestPoints(player) >= 43) + line(player, "!!Level 49 crafting would be an advantage??", line++, hasLevelStat(player, Skills.CRAFTING, 49)) + line(player, "!!Level 49 smithing would be an advantage??", line++, hasLevelStat(player, Skills.SMITHING, 49)) + } else if (stage < 100) { + line(player, "I met Juna the serpent in a deep chasm beneath the", line++, true) + line(player, "Lumbridge Swamp Caves.", line++, true) + line(player, "I told her a story and she said she would let me into the", line++, false) + line(player, "Tears of Guthix cave if I brought her a !!bowl?? made from the", line++, false) + line(player, "stone in !!the cave on the South side of the chasm??.", line++, false) + } else { + line(player, "I met Juna the serpent in a deep chasm beneath the", line++, true) + line(player, "Lumbridge Swamp Caves. I made a bowl out of magical", line++, true) + line(player, "stone in order to catch the Tears of Guthix.", line++, true) + line++ + line(player,"QUEST COMPLETE!", line++) + line++ + line(player, "Now Juna will let me into the cave to collect the Tears if I", line++, false) + line(player, "!!tell her stories?? of my adventures.", line++, false) + // TOG Minigame + if (daysLeft(player) > 0 && xpLeft(player) > 0 && questPointsLeft(player) > 0) { + line(player, "I will be able to collect the Tears of Guthix !!in " + daysLeft(player) + " days??, as", line++, false) + line(player, "long as I gain either !!1 Quest Point?? or !!" + xpLeft(player) + " total XP??", line++, false) + } else if (xpLeft(player) > 0 && questPointsLeft(player) > 0) { + line(player, "I will be able to collect the Tears of Guthix, as long as I", line++, false) + line(player, "gain either !!1 Quest Point?? or !!" + xpLeft(player) + " total XP??", line++, false) + } else if (daysLeft(player) > 0) { + line(player, "I will be able to collect the Tears of Guthix !!in " + daysLeft(player) + " days??.", line++, false) + } else { + line(player, "I have had enough adventures to tell Juna more stories,", line++, false) + line(player, "and a week has passed since I last collected the Tears. I", line++, false) + line(player, "can visit Juna again now.", line++, false) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Tears of Guthix quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.STONE_BOWL_4704,230,277,5) + + drawReward(player, "1 quest point", ln++) + drawReward(player, "1,000 Crafting XP", ln++) + drawReward(player, "Access to the Tears of Guthix", ln++) + drawReward(player, "cave", ln++) + + rewardXP(player, Skills.CRAFTING, 1000.0) + } + + override fun reset(player: Player) { + removeAttribute(player, attributePreviousDate) + removeAttribute(player, attributePreviousXPAmount) + removeAttribute(player, attributePreviousQuestPoints) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixListeners.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixListeners.kt new file mode 100644 index 000000000..bd7c48800 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixListeners.kt @@ -0,0 +1,143 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class TearsOfGuthixListeners : InteractionListener { + + companion object { + fun crossTheChasm(player: Player, with: NPC) { + // Unless you have time to animate this, this fucking thing is waaay too complicated. + // THIS IS JUST AESTHETICS + // You have to do the following: + // 1 - Get the light creature to your location. + // 2 - Animate both you and the light creature to float up. + // 3 - Walk both YOU AND THE LIGHT CREATURE to the other side. + // 4 - Float both you and the light creature to the ground. + // + // 2046 - Magically float into the air + // 2047 - Magically float back to the ground + // 2048 - Keep floating in the air + + // Instead you will just get fucking thrown to that other side. + val lightCreature = with as NPC + sendMessage(player, "The light-creature is attracted to your beam and comes towards you...") + LightCreatureBehavior.moveLightCreature(lightCreature, player.location) + // Could also do player.appearance.setAnimations(Animation(913)) which is the group animation for floating. + if (player.location.y > 9516) { + forceMove(player, player.location, Location.create(3229, 9504, 2), 0, 400, null, 2048) + } else { + forceMove(player, player.location, Location.create(3228, 9527, 2), 0, 400, null, 2048) + } + } + } + + override fun defineListeners() { + // Similar to RockClimbShortcut.kt + on(Scenery.ROCKS_6673, SCENERY, "climb") { player, _ -> + if (player.location.x > 3240) { + ForceMovement.run(player, player.location, Location.create(player.location).transform(-2, 0, 0), Animation(1148), Animation(1148), Direction.WEST, 13).endAnimation = Animation.RESET + } else { + ForceMovement.run(player, player.location, Location.create(player.location).transform(2, 0, 0), Animation(1148), Animation(1148), Direction.WEST, 13).endAnimation = Animation.RESET + } + return@on true + } + // Similar to RockClimbShortcut.kt + on(Scenery.ROCKS_6672, SCENERY, "climb") { player, _ -> + if (player.location.x > 3239) { + sendMessage(player, "You could climb down here, but it is too uneven to climb up.") + } else { + ForceMovement.run(player, player.location, Location.create(player.location).transform(2, 0, 0), Animation(1148), Animation(1148), Direction.WEST, 13).endAnimation = Animation.RESET + } + return@on true + } + + // Please note: part of this is already done in craftBullseyeLantern() except for the swapping out which is here. + onUseWith(ITEM, Items.BULLSEYE_LANTERN_4548, Items.SAPPHIRE_1607) { player, used, with -> + sendMessage(player, "You swap the lantern's lens for a sapphire.") + if(removeItem(player, with) && removeItem(player, used)) { + addItemOrDrop(player, Items.SAPPHIRE_LANTERN_4701) + addItemOrDrop(player, Items.LANTERN_LENS_4542) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SAPPHIRE_LANTERN_4701, Items.LANTERN_LENS_4542) { player, used, with -> + sendMessage(player, "You swap the lantern's sapphire for a lens.") + if(removeItem(player, with) && removeItem(player, used)) { + addItemOrDrop(player, Items.BULLSEYE_LANTERN_4548) + addItemOrDrop(player, Items.SAPPHIRE_1607) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BULLSEYE_LANTERN_4549, Items.SAPPHIRE_1607) { player, used, with -> + sendMessage(player, "The lantern is too hot to do that while it is lit.") + return@onUseWith true + } + onUseWith(ITEM, Items.SAPPHIRE_LANTERN_4702, Items.LANTERN_LENS_4542) { player, used, with -> + sendMessage(player, "The lantern is too hot to do that while it is lit.") + return@onUseWith true + } + + // MAGIC_STONE are set in MiningNode, but I can't change the messages without screwing up + // When examining ore: sendMessage(player, "This rock contains a magical kind of stone.") + // When mining: sendMessage(player, "You manage to mine some stone.") + // If you have stone in your inventory: sendMessage(player, "You have already mined some stone. You don't need any more.") + + // Note: The construction MAGIC_STONE is MAGIC_STONE_8788 NOT MAGIC_STONE_4703 WHICH IS FOR TEARS OF GUTHIX + onUseWith(ITEM, Items.MAGIC_STONE_4703, Items.CHISEL_1755) { player, used, with -> + sendMessage(player, "You make a stone bowl.") + if(removeItem(player, used)) { + addItemOrDrop(player, Items.STONE_BOWL_4704) + } + return@onUseWith true + } + + onUseWith(NPC, Items.SAPPHIRE_LANTERN_4702, NPCs.LIGHT_CREATURE_2021) { player, used, with -> + if (hasRequirement(player, Quests.WHILE_GUTHIX_SLEEPS)) { + // Options when you have WGS - B6KHH7AQc2Q + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> interpreter!!.sendOptions("Select an Option", "Across the Chasm.", "Into the Chasm.").also { stage++ } + 1 -> when(buttonID){ + 1 -> { + crossTheChasm(player, with as NPC) + end() + } + 2 -> { + // This was old. + player.lock(2) + player.teleport(Location.create(2538, 5881, 0)) + end() + } + } + } + } + }) + } else { + crossTheChasm(player, with as NPC) + } + return@onUseWith true + } + + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC, intArrayOf(NPCs.LIGHT_CREATURE_2021),"use"){ player, node -> + return@setDest player.location + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt new file mode 100644 index 000000000..ab27cbd71 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt @@ -0,0 +1,402 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.component.Component +import core.game.event.EventHook +import core.game.event.TickEvent +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.node.entity.skill.Skills +import core.game.node.item.Item +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.Animation +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +/** + * // ::setvarbit 454 (varp 449 7-11) 0-10 where its just time bar length + * // ::setvarbit 455 (varp 449 12-20) X where x is number of points he gets + * + * anim 2040 - Hold bowl + * anim 2041 - Walk with ToG Bowl + * anim 2042 - Run with ToG Bowl + * anim 2043 - Fill ToG bowl + * anim 2044 - Finish filling from ToG + * anim 2045 - Drink from bowl + * + */ +class TearsOfGuthixMinigame : InteractionListener, EventHook, MapArea { + companion object { + + const val varbitTimeBar = 454 + const val varbitPoints = 455 + const val attributeTicksRemaining = "minigame:tearsofguthix-ticksremaining" + const val attributeTearsCollected = "minigame:tearsofguthix-tearscollected" + const val attributeIsCollecting = "minigame:tearsofguthix-iscollecting" + + // In order specified by RS + private val rewardArray = arrayOf( + Skills.COOKING, + Skills.CRAFTING, + Skills.FIREMAKING, + Skills.FISHING, + Skills.MAGIC, + Skills.MINING, + Skills.PRAYER, + Skills.RANGE, + Skills.RUNECRAFTING, + Skills.SMITHING, + Skills.WOODCUTTING, + Skills.AGILITY, + Skills.HERBLORE, + Skills.FLETCHING, + Skills.THIEVING, + Skills.SLAYER, + Skills.ATTACK, + Skills.DEFENCE, + Skills.STRENGTH, + Skills.HITPOINTS, + Skills.FARMING, + Skills.CONSTRUCTION, + Skills.HUNTER, + Skills.SUMMONING, // This isn't but lmao. + ) + // In order specified by RS + val rewardText = arrayOf( + "You have a brief urge to cook some food.", + "Your fingers feel nimble and suited to delicate work.", + "You have a brief urge to set light to something.", + "You gain a deep understanding of the creatures of the sea.", + "You feel the power of the runes surging through you. ", + "You gain a deep understanding of the stones of the earth.", + "You suddenly feel very close to the gods.", + "Your aim improves.", + "You gain a deep understanding of runes.", + "You gain a deep understanding of all types of metal.", + "You gain a deep understanding of the trees in the wood.", + "You feel very nimble.", + "You gain a deep understanding of all kinds of strange plants.", + "You gain a deep understanding of wooden sticks.", + "You feel your respect for others' property slipping away.", + "You gain a deep understanding of many strange creatures.", + "You feel a brief surge of aggression.", + "You feel more able to defend yourself.", + "Your muscles bulge.", + "You feel very healthy.", + "You gain a deep understanding of the cycles of nature.", + "You feel homesick.", + "You briefly experience the joy of the hunt.", + "You feel at one with nature.", + ) + + /** Calculates the XP to reward. */ + fun rewardTears(player: Player) { + val lowestSkill = rewardArray.reduce{ acc, curr -> + // If you don't have construction, you cannot earn xp on it. + if (curr == Skills.CONSTRUCTION && !hasHouse(player)) { + acc + } + // If you don't have Druidic Ritual completed, you cannot earn xp on it. + else if (curr == Skills.HERBLORE && !isQuestComplete(player, Quests.DRUIDIC_RITUAL)) { + acc + } + // If you don't have Rune Mysteries, you cannot earn xp on it. + else if (curr == Skills.RUNECRAFTING && !isQuestComplete(player, Quests.RUNE_MYSTERIES)) { + acc + } + // If you don't have Wolf Whistle, you cannot earn xp on it. + else if (curr == Skills.SUMMONING && !isQuestComplete(player, Quests.WOLF_WHISTLE)) { + acc + } + else if (player.skills.getExperience(acc) <= player.skills.getExperience(curr)) { + acc + } else { + curr + } + } + + var perTearXP = 60.0 // Caps at level 30, giving 60 per XP. + if (getStatLevel(player, lowestSkill) < 30) { + perTearXP = (getStatLevel(player, lowestSkill) - 1) * 1.724137 // From 50/29 + perTearXP += 10 + } + + sendMessage(player, rewardText[rewardArray.indexOf(lowestSkill)]) + + val tearsCollected = getAttribute(player, attributeTearsCollected, 0) + rewardXP(player, lowestSkill, perTearXP * tearsCollected) + } + + /** Opens interface, walks the player to the center and start game. */ + fun startGame(player: Player) { + lock(player, 15) + // Opens the Tears of Guthix Interface in the tab. + player.interfaceManager.openSingleTab(Component(Components.TOG_WATER_BOWL_4)) + // Sets up the interface varbits. + setAttribute(player, attributeTicksRemaining, getQuestPoints(player) + 15) // 15 to offset the stupid walking. + setAttribute(player, attributeTearsCollected, 0) + setVarbit(player, varbitTimeBar, 10) + setVarbit(player,varbitPoints, 0) + + // Forces the player to hold a bowl and animate accordingly. + replaceSlot(player, EquipmentSlot.WEAPON.ordinal, Item(Items.STONE_BOWL_4704), null, Container.EQUIPMENT) + // Change the player's SET ANIMATIONS to the bowl holding set. Found using ::ranim + player.appearance.setAnimations(Animation(357)) // THIS WAS TRIAL AND ERROR AND WAS FUCKING HARD TO FIND + player.appearance.sync() + + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + val distance = player.location.getDistance(Location(3251, 9516, 2)).toInt() + 1// Per tick? + forceMove(player, player.location, Location(3251, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 1 -> { + face(player, Location(3252, 9516, 2)) + val junaScenery = getScenery(Location(3252, 9516, 2)) + if (junaScenery != null) { + animateScenery(junaScenery, 2055) + } + return@queueScript delayScript(player, 2) + } + 2 -> { + val distance = player.location.getDistance(Location(3253, 9516, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 3 -> { + face(player, Location(3253, 9517, 2)) + return@queueScript delayScript(player, 2) + } + 4 -> { + val distance = player.location.getDistance(Location(3253, 9517, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9517, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 5 -> { + face(player, Location(3257, 9517, 2)) + return@queueScript delayScript(player, 2) + } + 6 -> { + val distance = player.location.getDistance(Location(3257, 9517, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3257, 9517, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 7 -> { + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + fun endGame(player: Player) { + lock(player, 22) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "Your time in the cave is up.") + val distance = player.location.getDistance(Location(3253, 9517, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9517, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 1 -> { + face(player, Location(3253, 9516, 2)) + return@queueScript delayScript(player, 2) + } + 2 -> { + val distance = player.location.getDistance(Location(3253, 9516, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 3 -> { + face(player, Location(3251, 9516, 2)) + val junaScenery = getScenery(Location(3252, 9516, 2)) + if (junaScenery != null) { + animateScenery(junaScenery, 2055) + } + return@queueScript delayScript(player, 2) + } + 4 -> { + val distance = player.location.getDistance(Location(3251, 9516, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3251, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 5 -> { + sendMessage(player, "You drink the liquid...") + animate(player, 2045) + return@queueScript delayScript(player, 3) + } + 6 -> { + rewardTears(player) + setAttribute(player, TearsOfGuthix.attributePreviousDate, System.currentTimeMillis()) + setAttribute(player, TearsOfGuthix.attributePreviousXPAmount, player.skills.totalXp) + setAttribute(player, TearsOfGuthix.attributePreviousQuestPoints, getQuestPoints(player)) + removeAttribute(player, attributeTearsCollected) + if (player.interfaceManager.singleTab?.id == 4) { + player.interfaceManager.closeSingleTab() + } + player.interfaceManager.restoreTabs() + removeItem(player, Items.STONE_BOWL_4704, Container.EQUIPMENT) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + } + + override fun defineListeners() { + + on(Scenery.WEEPING_WALL_6660, SCENERY, "collect-from") { player, node -> + animate(player, 2043) + val index = TearsOfGuthixGlobalTick.allWalls.indexOf(node.location) + setAttribute(player, attributeIsCollecting, index) + return@on true + } + + } + + // Timer step per tick while you are in the minigame. + override fun process(entity: Entity, event: TickEvent) { + if (entity is Player) { + if (getAttribute(entity, attributeTicksRemaining, -1) > 0) { + setAttribute(entity, attributeTicksRemaining, getAttribute(entity, attributeTicksRemaining, 0) - 1) + setVarbit(entity, varbitTimeBar, (getAttribute(entity, attributeTicksRemaining, 0) * 10 / getQuestPoints(entity)), false) + if (getAttribute(entity, attributeIsCollecting, 0) != 0) { + val currentArrayIndex = getAttribute(entity, attributeIsCollecting, 0) + val currentTearState = TearsOfGuthixGlobalTick.globalWallState[currentArrayIndex] + if (currentTearState == 1) { + setAttribute(entity, attributeTearsCollected, getAttribute(entity, attributeTearsCollected, 0) + 1) + } else if (currentTearState == 2 && getAttribute(entity, attributeTearsCollected, 0) > 0){ + setAttribute(entity, attributeTearsCollected, getAttribute(entity, attributeTearsCollected, 0) - 1) + } + setVarbit(entity, varbitPoints, getAttribute(entity, attributeTearsCollected, 0)) + } + } else if (getAttribute(entity, attributeTicksRemaining, -1) == 0) { + removeAttribute(entity, attributeTicksRemaining) + endGame(entity) + } + } + } + + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(3253, 9513, 3262, 9522, 2)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + if (getAttribute(entity, attributeTicksRemaining, 0) <= 0) { + removeItem(entity, Items.STONE_BOWL_4704, Container.EQUIPMENT) + teleport(entity, Location(3251, 9516, 2)) + } else { + entity.hook(Event.Tick, this) + } + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + entity.unhook(this) + if (logout) { + removeItem(entity, Items.STONE_BOWL_4704, Container.EQUIPMENT) + removeAttribute(entity, attributeTearsCollected) + removeAttribute(entity, attributeTicksRemaining) + teleport(entity, Location(3251, 9516, 2)) + } + } + } + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + entity.hook(Event.Tick, this) + setAttribute(entity, attributeIsCollecting, 0) // If you move, you ain't collecting + } + } +} + +/** + * Global Tick class to randomize the walls consistently for everyone. + */ +class TearsOfGuthixGlobalTick : TickListener { + + companion object { + var ticks = 0 + var globalWallState = intArrayOf(0, 0, 2, 1, 2, 1, 0, 0, 2, 1) + val allWalls = arrayOf( + // Blank + Location(0, 0, 0), + // Left Walls + Location(3258, 9520, 2), + Location(3261, 9516, 2), + Location(3261, 9518, 2), + Location(3257, 9514, 2), + Location(3259, 9514, 2), + // Right Walls + Location(3257, 9520, 2), + Location(3259, 9520, 2), + Location(3261, 9517, 2), + Location(3258, 9514, 2), + ) + } + + override fun tick() { + // Do this every 10 ticks. + if (ticks++ > 10) { ticks = 0 } else { return } + // Shuffle the walls + val wallStates = intArrayOf(0, 0, 0, 1, 1, 1, 2, 2, 2) // 0 is absent, 1 is blue, 2 is green + wallStates.shuffle() + globalWallState = intArrayOf(0) + wallStates + + /* + * Explanation: The walls are layered sceneries, which makes it rabidly fucked to change them. + * What I did was to add the tears scenery first (essentially overriding the tears scenery), + * then add the WEEPING_WALL_6660 right after it so that the interactions are still there. + * this is how a layer is like: + * 1 - WEEPING_WALL_6660 - No model, but holds the option "collect-from" + * 2 - BLUE/GREEN/ABSENT - Model of the blue/green/absent waterfall. + * 3 - WEEPING_WALL_6664 - The actual model, but not interactive. + * 6661 - 6664 is left side, 6665 to 6668 is right side + */ + wallStates.forEachIndexed { index, state -> + val scenery = getScenery(allWalls[index + 1])!! + val newSceneryId = if (state == 2) { + if (index + 1 <= 5) { + Scenery.GREEN_TEARS_6662 + } else { + Scenery.GREEN_TEARS_6666 + } + } else if (state == 1) { + if (index + 1 <= 5) { + Scenery.BLUE_TEARS_6661 + } else { + Scenery.BLUE_TEARS_6665 + } + } else { + if (index + 1 <= 5) { + Scenery.ABSENCE_OF_TEARS_6663 + } else { + Scenery.ABSENCE_OF_TEARS_6667 + } + } + addScenery(core.game.node.scenery.Scenery( + newSceneryId, + scenery.location, + 4, + scenery.rotation + )) + addScenery(core.game.node.scenery.Scenery(Scenery.WEEPING_WALL_6660, scenery.location, 0, scenery.rotation)) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java index c301fc637..acf0ca8c2 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.link.diary.DiaryType; import core.plugin.Initializable; import core.game.node.entity.player.Player; import core.game.dialogue.DialoguePlugin; +import content.data.Quests; /** @@ -42,7 +43,7 @@ public final class FatherAereckDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - int questStage = player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player); + int questStage = player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player); if (questStage == 10) { npc("Have you got rid of the ghost yet?"); stage = 520; @@ -72,7 +73,7 @@ public final class FatherAereckDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - if (player.getQuestRepository().isComplete("The Restless Ghost")) { + if (player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { interpreter.sendOptions("What would you like to say?", "Can you change my gravestone now?", "Who's Saradomin?", "Nice place you've got here."); stage = 1; } else { @@ -128,7 +129,7 @@ public final class FatherAereckDialogue extends DialoguePlugin { end(); break; case 510: - player.getQuestRepository().getQuest(RestlessGhost.NAME).start(player); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).start(player); player.getQuestRepository().syncronizeTab(player); npc("Thank you. The problem is, there is a ghost in the", "church graveyard. I would like you to get rid of it."); stage = 511; diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java index abedfb9a0..219c0c562 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java @@ -1,5 +1,7 @@ package content.region.misthalin.lumbridge.quest.therestlessghost; +import content.data.Quests; +import core.game.dialogue.FacialExpression; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.diary.DiaryType; @@ -40,7 +42,7 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - npc("Go away! I'm meditating!"); + npc(FacialExpression.ANGRY, "Go away! I'm meditating!"); stage = 0; return true; } @@ -49,14 +51,14 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - if (player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player) == 0) { - options("Well, that's friendly.", "I've come to respossess your house."); + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 0) { + options("Well, that's friendly.", "I've come to repossess your house."); stage = 1; - } else if (player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player) == 10) { - options("Well, that's friendly.", "I've come to respossess your house.", "Father Aereck sent me to talk to you."); + } else if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 10) { + options("Well, that's friendly.", "Father Aereck sent me to talk to you.", "I've come to repossess your house."); stage = 500; - } else if (player.getGameAttributes().getAttributes().containsKey("restless-ghost:urhney") || player.getQuestRepository().isComplete(RestlessGhost.NAME)) { - options("Well, that's friendly.", "I've come to respossess your house.", "I've lost the Amulet of Ghostspeak."); + } else if (player.getGameAttributes().getAttributes().containsKey("restless-ghost:urhney") || player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { + options("Well, that's friendly.", "I've lost the Amulet of Ghostspeak.", "I've come to repossess your house."); stage = 514; } break; @@ -67,17 +69,17 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { stage = 10; break; case 2: - player("I've come to repossess your house."); - stage = 20; - break; - case 3: player("Father Aereck sent me to talk to you."); stage = 501; break; + case 3: + player("I've come to repossess your house."); + stage = 20; + break; } break; case 501: - npc("I suppose I'd better talk to you then. What problems", "has he got himself into this time?"); + npc(FacialExpression.ANGRY, "I suppose I'd better talk to you then. What problems", "has he got himself into this time?"); stage = 502; break; case 502: @@ -85,23 +87,23 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { stage = 503; break; case 503: - npc("Oh, the silly fool."); + npc(FacialExpression.ANGRY, "Oh, the silly fool."); stage = 504; break; case 504: - npc("I leave town for just five months, and ALREADY he", "can't manage."); + npc(FacialExpression.ANGRY, "I leave town for just five months, and ALREADY he", "can't manage."); stage = 505; break; case 505: - npc("(sigh)"); + npc(FacialExpression.SAD, "(sigh)"); stage = 506; break; case 506: - npc("Well, I can't go back and exorcise it. I vowed not to", "leave this place. Until I had done a full two years of", "prayer and meditation."); + npc(FacialExpression.ANGRY, "Well, I can't go back and exorcise it. I vowed not to", "leave this place. Until I had done a full two years of", "prayer and meditation."); stage = 507; break; case 507: - npc("Tell you what I can do though; take this amulet."); + npc(FacialExpression.NEUTRAL, "Tell you what I can do though; take this amulet."); stage = 508; break; case 508: @@ -112,20 +114,20 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { } interpreter.sendItemMessage(552, "Father Urhney hands you an amulet."); player.getInventory().add(new Item(552, 1)); - player.getQuestRepository().getQuest(RestlessGhost.NAME).setStage(player, 20); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 20); player.getGameAttributes().setAttribute("/save:restless-ghost:urhney", true); stage = 509; break; case 509: - npc("It is an Amulet of Ghostspeak."); + npc(FacialExpression.NEUTRAL, "It is an Amulet of Ghostspeak."); stage = 510; break; case 510: - npc("So called, because when you wear it you can speak to", "ghosts. A lot of ghosts are doomed to be ghosts because", "they have left some important task uncompleted."); + npc(FacialExpression.NEUTRAL, "So called, because when you wear it you can speak to", "ghosts. A lot of ghosts are doomed to be ghosts because", "they have left some important task uncompleted."); stage = 511; break; case 511: - npc("Maybe if you know what this task is, you can get rid of", "the ghost. I'm not making any gurantees mind you,", "but it is the best I can do right now."); + npc(FacialExpression.NEUTRAL, "Maybe if you know what this task is, you can get rid of", "the ghost. I'm not making any guarantees mind you,", "but it is the best I can do right now."); stage = 512; break; case 512: @@ -142,12 +144,12 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { stage = 10; break; case 2: - player("I've come to repossess your house."); - stage = 20; + player(FacialExpression.NEUTRAL, "I've lost the Amulet of Ghostspeak."); + stage = 515; break; case 3: - player("I've lost the Amulet of Ghostpeak."); - stage = 515; + player("I've come to repossess your house."); + stage = 20; break; } break; @@ -170,14 +172,14 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { stage = 518; break; case 517: - npc("What are you talking about? I can see you've got it", "in your bank!"); + npc(FacialExpression.ANGRY, "You come here wasting my time... Has it even", "occurred to you to look in your bank? Now GO", "AWAY!"); stage = 518; break; case 518: end(); break; case 519: - npc("How careless can you get? Those things aren't easy to", "come by you know! It's a good job I've got a spare."); + npc(FacialExpression.ANGRY, "How careless can you get? Those things aren't easy to", "come by you know! It's a good job I've got a spare."); stage = 520; break; case 520: @@ -187,7 +189,7 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { stage = 521; break; case 521: - npc("Be more careful this time."); + npc(FacialExpression.ANGRY, "Be more careful this time."); stage = 522; break; case 522: @@ -251,7 +253,7 @@ public final class FatherUhrneyDialogue extends DialoguePlugin { stage = 102; break; case 102: - player("Sorry. I mus thave got the wrong address. All the", "houses look the same around here."); + player("Sorry. I must have got the wrong address. All the", "houses look the same around here."); stage = 103; break; case 103: diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java index ccf60a649..11fd553b1 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java @@ -9,6 +9,7 @@ import core.plugin.Initializable; import core.plugin.ClassScanner; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** @@ -18,22 +19,16 @@ import static core.api.ContentAPIKt.*; */ @Initializable public class RestlessGhost extends Quest { - - /** - * The name of the quest. - */ - public static final String NAME = "The Restless Ghost"; - /** * The ghost speak amulet. */ public static final Item AMULET = new Item(552); - + /** * Constructs a new {@Code RestlessGhost} {@Code Object} */ public RestlessGhost() { - super(NAME, 25, 24, 1, 107, 0, 4, 5); + super(Quests.THE_RESTLESS_GHOST, 25, 24, 1, 107, 0, 4, 5); } @Override diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java index b282450cd..41b9f046b 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.lumbridge.quest.therestlessghost; +import content.data.Quests; import core.game.node.entity.npc.NPC; import core.plugin.Initializable; import core.game.node.entity.player.Player; @@ -43,17 +44,17 @@ public class RestlessGhostDialogue extends DialoguePlugin { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooo wooo wooooo!"); stage = 1; } else { - if (player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player) == 20) { + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 20) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Not very good actually."); stage = 500; break; } - if (player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player) == 30) { + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 30) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing finding my skull?"); stage = 520; break; } - if (player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player) == 40) { + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 40) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing finding my skull?"); stage = 550; break; @@ -111,7 +112,7 @@ public class RestlessGhostDialogue extends DialoguePlugin { break; case 511: interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok. I will try and get the skull back for you, then you", "can rest in peace."); - player.getQuestRepository().getQuest(RestlessGhost.NAME).setStage(player, 30); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 30); stage = 512; break; case 512: diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java index 15e31d74a..d19f260a1 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java @@ -1,5 +1,6 @@ package content.region.misthalin.lumbridge.quest.therestlessghost; +import content.data.Quests; import core.cache.def.impl.SceneryDefinition; import core.game.interaction.OptionHandler; import core.game.node.Node; @@ -106,11 +107,11 @@ public final class RestlessGhostPlugin extends OptionHandler { searchAltar(player, object); break; case 15051: - if (!player.getQuestRepository().isComplete(RestlessGhost.NAME) && !player.getBank().containsItem(SKULL) && !player.getInventory().containsItem(SKULL)) { + if (!player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST) && !player.getBank().containsItem(SKULL) && !player.getInventory().containsItem(SKULL)) { player.getInventory().add(SKULL); player.getPacketDispatch().sendMessage("You find another skull."); } - player.getQuestRepository().getQuest(RestlessGhost.NAME).setStage(player, 40); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 40); break; case 2145: toggleCoffin(player, object); @@ -132,7 +133,7 @@ public final class RestlessGhostPlugin extends OptionHandler { player.animate(open ? OPEN_ANIM : CLOSE_ANIM); SceneryBuilder.replace(object, object.transform(open ? 15061 : 2145)); player.getPacketDispatch().sendMessage("You " + (open ? "open" : "close") + " the coffin."); - if (open && !player.getQuestRepository().isComplete(RestlessGhost.NAME)) { + if (open && !player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { sendGhost(); } } @@ -161,7 +162,7 @@ public final class RestlessGhostPlugin extends OptionHandler { */ private void searchAltar(final Player player, final Scenery object) { final boolean hasSkull = object.getId() == 15051; - if (player.getQuestRepository().getQuest(RestlessGhost.NAME).getStage(player) != 30) { + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) != 30) { player.getPacketDispatch().sendMessage("You search the altar and find nothing."); return; } @@ -170,7 +171,7 @@ public final class RestlessGhostPlugin extends OptionHandler { GroundItemManager.create(SKULL, player); } setVarp(player, 728, 5, true); - player.getQuestRepository().getQuest(RestlessGhost.NAME).setStage(player, 40); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 40); player.getPacketDispatch().sendMessage("The skeleton in the corner suddenly comes to life!"); sendSkeleton(player); } @@ -259,7 +260,7 @@ public final class RestlessGhostPlugin extends OptionHandler { if (this.getRespawnTick() > GameWorld.getTicks()) { return true; } - return player.getQuestRepository().isComplete(RestlessGhost.NAME) || (pl != null && player != pl); + return player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST) || (pl != null && player != pl); } @Override diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java index 58bb7d0b1..4a899c64a 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java @@ -1,5 +1,6 @@ package content.region.misthalin.lumbridge.quest.therestlessghost; +import content.data.Quests; import core.api.Container; import core.game.interaction.NodeUsageEvent; import core.game.interaction.UseWithHandler; @@ -42,7 +43,7 @@ public final class RestlessGhostSkull extends UseWithHandler { } if (removeItem(event.getPlayer(), Items.SKULL_964, Container.INVENTORY)) { event.getPlayer().getPacketDispatch().sendMessage("You put the skull in the coffin."); - event.getPlayer().getQuestRepository().getQuest(RestlessGhost.NAME).finish(event.getPlayer()); + event.getPlayer().getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).finish(event.getPlayer()); } return true; } diff --git a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java index 3cc8a184c..91f1f33ef 100644 --- a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java +++ b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.content.quest.members.asoulsbane.SoulsBaneLaunaDialogue; import core.plugin.PluginManager; +import content.data.Quests; */ /** @@ -14,10 +15,8 @@ import core.plugin.PluginManager; @Initializable public class ASoulsBane extends Quest { - public static final String NAME = "A Soul's Bane"; - public ASoulsBane() { - super(NAME, 115, 114, 1, 709, 0, 1, 1261); + super(Quests.A_SOULS_BANE, 115, 114, 1, 709, 0, 1, 1261); } // config 710 does a lot of shit diff --git a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt index 1813665e6..b19d00484 100644 --- a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt +++ b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt @@ -4,6 +4,8 @@ import core.api.* import core.game.interaction.InteractionListener import core.game.world.map.Location import org.rs09.consts.Scenery +import content.data.Quests +import core.game.node.entity.player.link.diary.DiaryType // Temporary access since the monsters in there drop nothing. class ASoulsBaneListener : InteractionListener { @@ -13,8 +15,9 @@ class ASoulsBaneListener : InteractionListener { } override fun defineListeners() { on(RIFT_IDS, SCENERY, "enter") { player, _ -> - if (hasRequirement(player, "A Soul's Bane")) { + if (hasRequirement(player, Quests.A_SOULS_BANE)) { teleport(player, Location(3297, 9824, 0)) + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 9) } return@on true } diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java b/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java index 9731861ef..c21b288a8 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.scenery.Scenery; +import content.data.Quests; /** * Represents the door peril dialogue. @@ -46,7 +47,7 @@ public final class DoorPerilDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { door = (Scenery) args[0]; - Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); if (quest.getStage(player) == 10) { interpreter.sendDialogue("You knock at the door...You hear a voice from inside.", "Who are you, and what do you want?"); stage = 0; @@ -106,7 +107,7 @@ public final class DoorPerilDialogue extends DialoguePlugin { stage = 10; break; case 10: - Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); quest.setStage(player, 11); end(); break; diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java index 5f1dc8b97..4d06a70d8 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue plugin used for the drezel npc. @@ -49,7 +50,7 @@ public final class DrezelDialogue extends DialoguePlugin { npc = (NPC) args[0]; npc.setName("Drezel"); NPCDefinition.forId(getIds()[0]).setName("Drezel"); - Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); if (quest.getStage(player) == 13) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello."); stage = 0; @@ -68,7 +69,7 @@ public final class DrezelDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + final Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); switch (stage) { case 0: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh! You do not appear to be on of those Zamorakians", "who imprisoned me here! Who are you and why are", "you here?"); @@ -369,7 +370,7 @@ public final class DrezelDialogue extends DialoguePlugin { stage = 802; break; case 802: - Quest quests = player.getQuestRepository().getQuest("Priest in Peril"); + Quest quests = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); quests.setStage(player, 17); end(); break; diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java index 20072af6c..06c77b5cc 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java @@ -13,6 +13,7 @@ import org.rs09.consts.NPCs; import content.region.morytania.quest.naturespirit.NSDrezelDialogue; import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; /** * Represents the dialogue plugin used for the drezel monument. @@ -52,7 +53,7 @@ public final class DrezelMonumentDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); if (quest.getStage(player) == 17) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, " + player.getUsername() + ". I see you finally made it down here.", "Things are worse than I feared. I'm not sure if I will", "be able to repair the damage."); stage = 900; @@ -79,7 +80,7 @@ public final class DrezelMonumentDialogue extends DialoguePlugin { stage = 420; }*/ - quest = player.getQuestRepository().getQuest("Nature Spirit"); + quest = player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT); if(quest.getStage(player) <= 5){ interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings again adventurer, How go your travels in", "Morytania? Is it as evil as I have heard?"); @@ -95,7 +96,7 @@ public final class DrezelMonumentDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + final Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); switch (stage) { case 400: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, " + player.getUsername() + ". For all the assistance you have given", "both myself and Misthalin in your actions, I cannot let", "you pass without warning you."); diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt b/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt index aba02ad76..d8f8f35d8 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt @@ -3,6 +3,7 @@ package content.region.misthalin.quest.priestinperil import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests class KingRoaldPIPDialogue(val questStage: Int) : DialogueFile() { @@ -25,7 +26,7 @@ class KingRoaldPIPDialogue(val questStage: Int) : DialogueFile() { 8 -> when(buttonID){ 1 -> { player("Sure. I don't have anything better to do right now.") - player!!.questRepository.getQuest("Priest in Peril").start(player) + player!!.questRepository.getQuest(Quests.PRIEST_IN_PERIL).start(player) stage++ } 2 -> { @@ -58,7 +59,7 @@ class KingRoaldPIPDialogue(val questStage: Int) : DialogueFile() { 9 -> npc("You get back there and do whatever is necessary to", "safeguard my kingdom from attack, or I will see you", "beheaded for high treason!").also { stage++ } 10 -> { player("Y-yes your Highness.") - player!!.questRepository.getQuest("Priest in Peril").setStage(player,13) + player!!.questRepository.getQuest(Quests.PRIEST_IN_PERIL).setStage(player,13) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java b/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java index c7811d7cd..9ca6c99be 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java @@ -8,6 +8,7 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.plugin.Initializable; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the monk of zamorak npc. @@ -57,7 +58,7 @@ public final class MonkOfZamorakNPC extends AbstractNPC { public void finalizeDeath(final Entity killer) { super.finalizeDeath(killer); final Player p = ((Player) killer); - final Quest quest = p.getQuestRepository().getQuest("Priest in Peril"); + final Quest quest = p.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); if (quest.isStarted(p)) { GroundItemManager.create(GOLDEN_KEY, getLocation(), p); } diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java index b123278b8..c14d08d0d 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the Quest priest in peril. @@ -18,7 +19,7 @@ public class PriestInPeril extends Quest { * Constructs a new {@code PriestInPeril} {@code Object}. */ public PriestInPeril() { - super("Priest in Peril", 99, 98, 1, 302, 0, 1, 100); + super(Quests.PRIEST_IN_PERIL, 99, 98, 1, 302, 0, 1, 100); } @Override diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java index 4e0c6ef3d..538afabc8 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java @@ -15,6 +15,7 @@ import core.game.world.map.Location; import core.plugin.Initializable; import core.plugin.Plugin; import org.rs09.consts.NPCs; +import content.data.Quests; /** * Represents the quest node plugin handler. @@ -22,6 +23,7 @@ import org.rs09.consts.NPCs; */ @Initializable public class PriestInPerilOptionPlugin extends OptionHandler { + /** * (non-Javadoc) * @see Plugin#newInstance(Object) @@ -92,7 +94,7 @@ public class PriestInPerilOptionPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Priest in Peril"); + final Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); switch (option) { case "study": @@ -105,6 +107,8 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 2347; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); message = "Saradomin is the hammer that crushes evil everywhere."; } if (id == 3498) { @@ -113,6 +117,8 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 1733; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); message = "Saradomin is the needle that binds our lives together."; } if (id == 3495) { @@ -121,6 +127,8 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 1931; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); message = "Saradomin is the vessel that keeps our lives from harm."; } if (id == 3497) { @@ -129,6 +137,8 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 314; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); message = "Saradomin is the delicate touch that brushes us with love."; } if (id == 3494) { @@ -137,6 +147,8 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 36; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 256, 0); message = "Saradomin is the light that shines throughout our lives."; } if (id == 3499) { @@ -145,6 +157,8 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 2944; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 256, 0); message = "Saradomin is the key that unlocks the mysteries of life."; } if (id == 3493) { @@ -153,10 +167,13 @@ public class PriestInPerilOptionPlugin extends OptionHandler { } else { item = 590; } + player.getPacketDispatch().sendItemZoomOnInterface(item, 320, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 320, 256, 0); message = "Saradomin is the spark that lights the fire in our hearts."; } player.getPacketDispatch().sendString(message, 272, 17); - player.getPacketDispatch().sendItemZoomOnInterface(item, 175, 272, 4); + // In SD, this is fine. in HD, this gets clipped when you zoom out too much or zoom in too much. + //player.getPacketDispatch().sendItemZoomOnInterface(item, 175, 272, 4); break; case "take-from": player.getImpactHandler().handleImpact(player, 2, CombatStyle.MELEE); @@ -178,7 +195,7 @@ public class PriestInPerilOptionPlugin extends OptionHandler { break; case 3443: /** the barrier. */ - if (!player.getQuestRepository().isComplete("Priest in Peril")) { + if (!player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL)) { player.getPacketDispatch().sendMessage("A magic force prevents you from passing through."); } else { player.getProperties().setTeleportLocation(Location.create(3425, 3485, 0)); diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt index dfc4e05fc..61a36a6c8 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt @@ -7,6 +7,7 @@ import org.rs09.consts.NPCs import org.rs09.consts.Scenery import core.game.interaction.IntType import core.game.interaction.InteractionListener +import content.data.Quests /** * Listener for Priest in Peril usage interactions @@ -76,7 +77,12 @@ class PriestInPerilUseListener : InteractionListener { } onUseWith(IntType.SCENERY, Items.GOLDEN_KEY_2944, Scenery.MONUMENT_3499) { player, used, _ -> - if (!getAttribute(player, "priest_in_peril:key", false) && removeItem(player, used)) { + // See GL #2112 and sources therein for why we do it this way + val hasNeverGrabbedKey = !getAttribute(player, "priest_in_peril:key", false) + val needsKeyForQuestStage = getQuestStage(player, Quests.PRIEST_IN_PERIL) <= 15 + val hasTotallyLostKey = !hasAnItem(player, Items.IRON_KEY_2945, true).exists() + val giveNewKey = hasNeverGrabbedKey || (needsKeyForQuestStage && hasTotallyLostKey) + if (giveNewKey && removeItem(player, used)) { addItem(player, Items.IRON_KEY_2945) sendMessage(player, "You swap the golden key for the iron key.") setAttribute(player, "/save:priest_in_peril:key", true) @@ -101,7 +107,7 @@ class PriestInPerilUseListener : InteractionListener { return@onUseWith false } - setQuestStage(player, "Priest in Peril", 15) + setQuestStage(player, Quests.PRIEST_IN_PERIL, 15) sendMessage(player, "You have unlocked the cell door.") val npc = core.game.node.entity.npc.NPC.create(NPCs.DREZEL_7690, player.location) @@ -117,7 +123,7 @@ class PriestInPerilUseListener : InteractionListener { } addItem(player, Items.BUCKET_1925) - setQuestStage(player, "Priest in Peril", 16) + setQuestStage(player, Quests.PRIEST_IN_PERIL, 16) sendMessage(player, "You pour the blessed water over the coffin...") return@onUseWith true diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java b/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java index c7bc48ebf..23dcd52c7 100644 --- a/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.world.map.Location; +import content.data.Quests; /** * Handles the temple guardian npc. @@ -49,7 +50,7 @@ public class TempleGuardianNPC extends AbstractNPC { public void finalizeDeath(final Entity killer) { super.finalizeDeath(killer); final Player p = ((Player) killer); - final Quest quest = p.getQuestRepository().getQuest("Priest in Peril"); + final Quest quest = p.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); if (quest.getStage(p) == 11) { quest.setStage(p, 12); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt index cd3590531..932997b5f 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt @@ -1,5 +1,6 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC @@ -20,7 +21,7 @@ class BatBehavior : NPCBehavior(*batIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Bat Wing during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.BAT_WING_7833)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt index 644372584..c489832bc 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt @@ -1,10 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.* import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -27,7 +27,7 @@ class BearBehavior : NPCBehavior(*bearIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Bear Ribs during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.BEAR_RIBS_7815)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt index f3aede96b..cd4cd6c4f 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt @@ -1,10 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -21,7 +21,7 @@ class BigFrogBehavior : NPCBehavior(*bigFrogIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Big Frog Leg during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.BIG_FROG_LEG_7908)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt index bad83bbf6..0ffe43400 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt @@ -1,5 +1,6 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC @@ -29,7 +30,7 @@ class GiantBatBehavior : NPCBehavior(*giantBatIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Giant Bat Wing during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.GIANT_BAT_WING_7827)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt index ba1f06f82..b670f24de 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt @@ -1,10 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -35,7 +35,7 @@ class GiantRatBehavior : NPCBehavior(*giantRatIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Giant Rat Bone during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.GIANT_RAT_BONE_7824)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt index 168f3dcde..923b9a5ef 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt @@ -1,11 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman -import content.global.handlers.npc.ChromaticDragonBehavior +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -179,7 +178,7 @@ class GoblinBehavior : NPCBehavior(*goblinIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Goblin Skull during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.GOBLIN_SKULL_7812)) } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt index 98c505819..2646a8676 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt @@ -1,10 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -45,7 +45,7 @@ class MonkeyBehavior : NPCBehavior(*monkeyIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Monkey Paw during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.MONKEY_PAW_7854)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt index 440a279b4..9351b6c1b 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt @@ -1,6 +1,6 @@ package content.region.misthalin.silvarea.quest.ragandboneman -import content.region.asgarnia.burthorpe.quest.deathplateau.DeathPlateau +import content.data.Quests import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression @@ -14,7 +14,7 @@ class OddOldManDialogueFile : DialogueFile() { // BONES_3674 is the Sack on ODD_OLD_MAN_3670 // There are probably FacialExpressions for the bone sack, but that's too much work. override fun handle(componentID: Int, buttonID: Int) { - when (getQuestStage(player!!, RagAndBoneMan.questName)) { + when (getQuestStage(player!!, Quests.RAG_AND_BONE_MAN)) { 0 -> { when (stage) { START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Can I help you with something?").also { stage++ } @@ -82,7 +82,7 @@ class OddOldManDialogueFile : DialogueFile() { 57 -> npcl(FacialExpression.FRIENDLY, "It takes a while for the vinegar to evaporate, but the bone will be nice and clean in the end.").also { stage++ } 58 -> playerl(FacialExpression.FRIENDLY, "All right, I'll be back later.").also { stage++ } 59 -> npcl(FacialExpression.FRIENDLY, "Bye!").also { - setQuestStage(player!!, RagAndBoneMan.questName, 1) + setQuestStage(player!!, Quests.RAG_AND_BONE_MAN, 1) stage = END_DIALOGUE } @@ -137,7 +137,7 @@ class OddOldManDialogueFile : DialogueFile() { 8 -> npcl(FacialExpression.FRIENDLY, "I'm always on the lookout for fresh bones, so if you see some bring them right over.").also { stage++ } 9 -> playerl(FacialExpression.FRIENDLY, "No problem, I'll be sure to bring anything you might like over if I find something.").also { stage++ } 10 -> playerl(FacialExpression.FRIENDLY, "I can't wait to see the displays once they are finished.").also { stage++ } - 11 -> finishQuest(player!!, RagAndBoneMan.questName).also { + 11 -> finishQuest(player!!, Quests.RAG_AND_BONE_MAN).also { end() } 20 -> playerl(FacialExpression.FRIENDLY, "Not at the moment. Can you just give me a run down on which bones I have left to get?").also { stage++ } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt index 0da5e32ec..97e5e9a35 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt @@ -6,6 +6,7 @@ import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * Rag and Bone Man Quest @@ -24,9 +25,8 @@ import org.rs09.consts.Items * Quest Journal 2012 https://www.youtube.com/watch?v=0I8fNTeAwA8&t=764 */ @Initializable -class RagAndBoneMan : Quest("Rag and Bone Man",100, 99, 2, 714, 0, 1, 4) { +class RagAndBoneMan : Quest(Quests.RAG_AND_BONE_MAN,100, 99, 2, 714, 0, 1, 4) { companion object { - const val questName = "Rag and Bone Man" const val attributeGoblinBone = "/save:quest:ragandboneman-goblinbonesubmit" const val attributeBearBone = "/save:quest:ragandboneman-bearbonesubmit" const val attributeBigFrogBone = "/save:quest:ragandboneman-bigfrogbonesubmit" diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt index fa54dabbe..b98630ed6 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt @@ -1,10 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.* import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -25,7 +25,7 @@ class RamBehavior : NPCBehavior(*ramIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Ram Skull during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.RAM_SKULL_7818)); } diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt index 54f5ba15e..894f0261d 100644 --- a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt @@ -1,10 +1,10 @@ package content.region.misthalin.silvarea.quest.ragandboneman +import content.data.Quests import core.api.isQuestInProgress import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.npc.drop.DropFrequency import core.game.node.entity.player.Player import core.game.node.item.Item import core.tools.RandomFunction @@ -23,7 +23,7 @@ class UnicornBehavior : NPCBehavior(*unicornIds) { override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { super.onDropTableRolled(self, killer, drops) // Drops the Unicorn Bone during Rag and Bone Man quest - if (killer is Player && isQuestInProgress(killer, RagAndBoneMan.questName, 1, 99)) { + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { if(RandomFunction.roll(4)) { drops.add(Item(Items.UNICORN_BONE_7821)); } diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java index 73f8b00bc..d9ca490aa 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java @@ -8,6 +8,7 @@ import core.game.node.item.GroundItem; import core.game.node.item.GroundItemManager; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue plugin used for the apothecary npc. @@ -67,12 +68,12 @@ public final class ApothecaryDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - if (player.getQuestRepository().getQuest("Romeo & Juliet").getStage(player) == 40) { + if (player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) == 40) { interpreter.sendDialogues(player, null, "Apothecary. Father Lawrence sent me."); stage = 500; return true; } - if (player.getQuestRepository().getQuest("Romeo & Juliet").getStage(player) == 50) { + if (player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) == 50) { if (!player.getInventory().contains(753, 1)) { npc("Keep searching for those Cadava berries. They're needed", "for the potion."); stage = 507; @@ -83,7 +84,7 @@ public final class ApothecaryDialogue extends DialoguePlugin { return true; } } - if (player.getQuestRepository().getQuest("Romeo & Juliet").getStage(player) == 60) { + if (player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) == 60) { if (!player.getInventory().contains(756, 1) && !player.getBank().contains(756, 1)) { if (player.getInventory().contains(753, 1)) { npc("Well done. You have the berries."); @@ -237,7 +238,7 @@ public final class ApothecaryDialogue extends DialoguePlugin { stage = 506; break; case 506: - player.getQuestRepository().getQuest("Romeo & Juliet").setStage(player, 50); + player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).setStage(player, 50); interpreter.sendDialogues(player, null, "Ok, thanks."); stage = 507; break; @@ -262,7 +263,7 @@ public final class ApothecaryDialogue extends DialoguePlugin { stage = 640; break; case 640: - player.getQuestRepository().getQuest("Romeo & Juliet").setStage(player, 60); + player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).setStage(player, 60); end(); break; } diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java index 953bd1b72..ab062f4b4 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue plugin used for the baraek npc. @@ -61,7 +62,7 @@ public final class BaraekDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Shield of Arrav"); + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); switch (quest.getStage(player)) { case 30: if (!player.getInventory().containsItem(FUR)) { diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java index a906641b0..0e14e004f 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java @@ -8,6 +8,7 @@ import core.game.node.item.GroundItem; import core.game.node.item.GroundItemManager; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue used for dr harlow. @@ -56,10 +57,10 @@ public final class DrHarlowDialogue extends DialoguePlugin { public boolean handle(int interfaceId, int buttonId) { switch (stage) { case 0: - if (player.getQuestRepository().getQuest("Vampire Slayer").getStage(player) == 10) { + if (player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).getStage(player) == 10) { interpreter.sendOptions("Select an Option", "No, you've had enough.", "Morgan needs your help!"); stage = 1; - } else if (player.getQuestRepository().getQuest("Vampire Slayer").getStage(player) == 20) { + } else if (player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).getStage(player) == 20) { if (player.getInventory().contains(1917, 1)) { interpreter.sendDialogues(player, null, "Here you go."); stage = 20; @@ -67,7 +68,7 @@ public final class DrHarlowDialogue extends DialoguePlugin { interpreter.sendDialogues(player, null, "I'll just go and buy one."); stage = 2; } - } else if (player.getQuestRepository().getQuest("Vampire Slayer").getStage(player) == 30) { + } else if (player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).getStage(player) == 30) { if (!player.getBank().contains(1549, 1) && !player.getInventory().contains(1549, 1)) { if (!player.getInventory().add(ITEMS[0])) { GroundItem item = new GroundItem(ITEMS[0], npc.getLocation(), player); @@ -122,7 +123,7 @@ public final class DrHarlowDialogue extends DialoguePlugin { stage = 10; break; case 10: - player.getQuestRepository().getQuest("Vampire Slayer").setStage(player, 20); + player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).setStage(player, 20); end(); break; case 2: @@ -131,7 +132,7 @@ public final class DrHarlowDialogue extends DialoguePlugin { case 20: if (player.getInventory().remove(ITEMS[1])) { interpreter.sendItemMessage(1917, "You give a beer to Dr Harlow."); - player.getQuestRepository().getQuest("Vampire Slayer").setStage(player, 30); + player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).setStage(player, 30); stage = 21; } break; diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java index 6e45fa50c..db0f198ad 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the father lawrence dialogue plugin. @@ -35,7 +36,7 @@ public final class FatherLawrenceDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - final Quest quest = player.getQuestRepository().getQuest("Romeo & Juliet"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); if (quest.getStage(player) < 30) { interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh to be a father in the times of whiskey."); stage = 0; @@ -68,7 +69,7 @@ public final class FatherLawrenceDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Romeo & Juliet"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); switch (stage) { case 0: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I sing and I drink and I wake up in gutters."); diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java index 531243cb8..e9a4ea493 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java @@ -1,7 +1,6 @@ package content.region.misthalin.varrock.dialogue; import content.global.skill.summoning.pet.Pet; -import content.global.skill.summoning.pet.PetDetails; import core.game.container.Container; import core.game.dialogue.DialoguePlugin; import core.game.dialogue.FacialExpression; @@ -13,10 +12,9 @@ import core.plugin.Initializable; import core.tools.RandomFunction; import org.rs09.consts.Items; -import java.util.Map; +import content.data.Quests; -import static core.api.ContentAPIKt.freeSlots; -import static core.api.ContentAPIKt.inInventory; +import static core.api.ContentAPIKt.*; /** * Represents the gertrude dialogue plugin. @@ -56,8 +54,7 @@ public final class GertrudeDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); - switch (quest.getStage(player)) { + switch (getQuestStage(player, Quests.GERTRUDES_CAT)) { case 0: interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, are you OK?"); break; @@ -95,7 +92,7 @@ public final class GertrudeDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (stage) { case 0: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do I look OK? Those kids drive me crazy."); @@ -423,7 +420,7 @@ public final class GertrudeDialogue extends DialoguePlugin { * @return the item. */ public Item getKitten() { - return new Item(RandomFunction.random(1555, 1560)); + return new Item(RandomFunction.random(1555, 1561)); } @Override diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java index edca24e12..93d5a003e 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java @@ -8,6 +8,7 @@ import core.game.system.task.Pulse; import core.game.world.GameWorld; import core.plugin.Initializable; import core.game.world.update.flag.context.Animation; +import content.data.Quests; /** * Represents the gertrude cat dialogue plugin. @@ -53,7 +54,7 @@ public final class GertrudesCatDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (stage) { case 545: end(); diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java index b4e712799..6c00a6bae 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java @@ -52,9 +52,10 @@ public final class GrandExchangeClerk extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { + String salutation = player.isMale() ? "sir" : "madam"; switch (stage) { case 0: - npc("Good day to you, sir, How can I help?"); + npc("Good day to you, " + salutation + ", how can I help?"); stage = 1; break; case 1: @@ -80,13 +81,13 @@ public final class GrandExchangeClerk extends DialoguePlugin { stage = 40; break; case 5: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm fine actually."); + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm fine, actually."); stage = 50; break; } break; case 10: - npc("Only too happy to help you, sir."); + npc("Only too happy to help you, " + salutation + "."); stage = 11; break; case 11: @@ -94,7 +95,7 @@ public final class GrandExchangeClerk extends DialoguePlugin { StockMarket.openFor(player); break; case 20: - npc("As you wish, sir."); + npc("As you wish, " + salutation + "."); stage = 21; break; case 21: @@ -110,7 +111,7 @@ public final class GrandExchangeClerk extends DialoguePlugin { GrandExchangeRecords.getInstance(player).openHistoryLog(player); break; case 40: - npc("It would be my pleasure, sir."); + npc("It would be my pleasure, " + salutation + "."); stage = 41; break; case 41: @@ -118,7 +119,7 @@ public final class GrandExchangeClerk extends DialoguePlugin { ExchangeItemSets.openFor(player); break; case 50: - npc("If you say so, sir."); + npc("If you say so, " + salutation + "."); stage = 51; break; case 51: diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java index ce33e799b..4cf81e311 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java @@ -7,13 +7,11 @@ import core.plugin.Initializable; import core.game.node.entity.player.Player; /** - * Represents the dialogue plugin used for kanel. - * @author 'Vexia - * @version 1.0 + * Kanel - Child in Gertrude's House */ @Initializable public final class KanelDialogue extends DialoguePlugin { - + // https://www.youtube.com/watch?v=ANI7DaRVEbg /** * Constructs a new {@code KanelDialogue} {@code Object}. */ @@ -39,7 +37,7 @@ public final class KanelDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Hello there."); stage = 0; return true; } @@ -49,15 +47,15 @@ public final class KanelDialogue extends DialoguePlugin { switch (stage) { case 0: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hel-lo?"); + interpreter.sendDialogues(npc, FacialExpression.CHILD_THINKING, "Hel-lo?"); stage = 1; break; case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Right. Goodbye."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Right. Goodbye."); stage = 2; break; case 2: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Bye?"); + interpreter.sendDialogues(npc, FacialExpression.CHILD_THINKING, "Bye?"); stage = 3; break; case 3: diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt index b4e0f7ecf..1f775acc6 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt @@ -11,6 +11,7 @@ import content.region.misthalin.quest.priestinperil.KingRoaldPIPDialogue import core.tools.DIALOGUE_INITIAL_OPTIONS_HANDLE import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests /** * Central dialogue plugin for King Roald. Reroutes to the more specific DialogueFiles @@ -32,15 +33,15 @@ class KingRoaldDialogue(player: Player? = null) : DialoguePlugin(player) { return true } - if(player.questRepository.isComplete("Priest in Peril")) { - if (!player.questRepository.hasStarted("All Fired Up") || player.questRepository.getQuest("All Fired Up").getStage(player) == 90) { - addOption("All Fired Up", KingRoaldAFUDialogue(player.questRepository.getStage("All Fired Up"))) + if(player.questRepository.isComplete(Quests.PRIEST_IN_PERIL)) { + if (!player.questRepository.hasStarted(Quests.ALL_FIRED_UP) || player.questRepository.getQuest(Quests.ALL_FIRED_UP).getStage(player) == 90) { + addOption("All Fired Up", KingRoaldAFUDialogue(player.questRepository.getStage(Quests.ALL_FIRED_UP))) } } else { - addOption("Priest in Peril", KingRoaldPIPDialogue(player.questRepository.getStage("Priest in Peril"))) + addOption("Priest in Peril", KingRoaldPIPDialogue(player.questRepository.getStage(Quests.PRIEST_IN_PERIL))) } - if (player.questRepository.getQuest("Shield of Arrav").isStarted(player) && !player.questRepository.getQuest("Shield of Arrav").isCompleted(player)) { + if (player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).isStarted(player) && !player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).isCompleted(player)) { addOption("Shield of Arrav", KingRoaldArravDialogue()) } diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/KnockAtBankDoor.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/KnockAtBankDoor.kt new file mode 100644 index 000000000..d62ded784 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/KnockAtBankDoor.kt @@ -0,0 +1,59 @@ +package content.region.misthalin.varrock.dialogue + +import core.api.lock +import core.api.queueScript +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +class KnockAtBankDoor : DialogueFile() { + private val femaleBankerNPC = NPC(NPCs.BANKER_45) + private val maleBankerNPC = NPC(NPCs.BANKER_44) + private val femaleBankerDoorLoc = Location(3182, 3434, 0) + + override fun handle(componentID: Int, buttonID: Int) { + npc = if (player!!.location == femaleBankerDoorLoc) femaleBankerNPC else maleBankerNPC + + when (stage) { + START_DIALOGUE -> { + player!!.dialogueInterpreter.sendPlainMessage( + true, "Knock knock..." + ).also { + lock(player!!, 3) + queueScript(player!!, 3) { + npcl(FacialExpression.NEUTRAL, "Who's there?") + stage++ + return@queueScript true + } + } + } + + 1 -> showTopics( + Topic("I'm ${player!!.username}. Please let me in.", 10), + Topic("Boo.", 20), + Topic("Kanga.", 30), + Topic("Thank.", 40), + Topic("Doctor.", 50) + ) + 10 -> npcl("No. Staff only beyond this point. You can't come in here.").also { stage = END_DIALOGUE } + 20 -> npcl("Boo who?").also { stage++ } + 21 -> playerl("There's no need to cry!").also { stage++ } + 22 -> npcl(FacialExpression.FURIOUS, "What? I'm not... oh, just go away!").also { stage = END_DIALOGUE } + 30 -> npcl("Kanga who?").also { stage++ } + 31 -> playerl("No, 'kangaroo'.").also { stage++ } + 32 -> npcl(FacialExpression.FURIOUS, "Stop messing about and go away!").also { stage = END_DIALOGUE } + 40 -> npcl("Thank who?").also { stage++ } + 41 -> playerl("You're welcome!").also { stage++ } + 42 -> npcl(FacialExpression.FURIOUS, "Stop it!").also { stage = END_DIALOGUE } + 50 -> npcl( + FacialExpression.FURIOUS, + "Doctor. wh.. hang on, I'm not falling for that one again! Go away." + ).also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardDialogue.java deleted file mode 100644 index b988a0eb7..000000000 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardDialogue.java +++ /dev/null @@ -1,88 +0,0 @@ -package content.region.misthalin.varrock.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.global.action.DoorActionHandler; -import core.game.node.entity.player.Player; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.game.world.map.RegionManager; - -/** - * Represents the museum guard dialogue. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class MuseumGuardDialogue extends DialoguePlugin { - - /** - * Represents the gate location. - */ - private static final Location LOCATION = new Location(3261, 3446, 0); - - /** - * Constructs a new {@code MuseumGuardDialogue} {@code Object}. - */ - public MuseumGuardDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code MuseumGuardDialogue} {@code Object}. - * @param player the player. - */ - public MuseumGuardDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new MuseumGuardDialogue(player); - } - - @Override - public boolean open(Object... args) { - interpreter.sendDialogues(5941, FacialExpression.HALF_GUILTY, "Welcome! Would you like to go into the Dig Site", "archaeology cleaning area?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Yes, I'll go in!", "No thanks, I'll take a look around out there."); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, I'll go in!"); - stage = 20; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I'll take a look around out there."); - stage = 3; - break; - } - break; - case 3: - end(); - break; - case 20: - end(); - DoorActionHandler.handleAutowalkDoor(player, RegionManager.getObject(LOCATION)); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 5941 }; - } - -} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardVarrockDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardVarrockDialogue.java deleted file mode 100644 index 9bfee30fa..000000000 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardVarrockDialogue.java +++ /dev/null @@ -1,69 +0,0 @@ -package content.region.misthalin.varrock.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the MuseumGuardVarrockDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class MuseumGuardVarrockDialogue extends DialoguePlugin { - - public MuseumGuardVarrockDialogue() { - - } - - public MuseumGuardVarrockDialogue(Player player) { - super(player); - } - - @Override - public int[] getIds() { - return new int[] { 5943 }; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - - switch (stage) { - case 0: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, how do I get in?"); - stage = 2; - break; - case 2: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, the main entrance is 'round the front. Just head", "west then north slightly, you can't miss it!"); - stage = 3; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What about these doors?"); - stage = 4; - break; - case 4: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "They're primarily for the workmen bringing finds from the", "Dig Site, but you can go through if you want."); - stage = 5; - break; - case 5: - end(); - break; - } - - return true; - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new MuseumGuardVarrockDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there. Come to see the new museum?"); - stage = 0; - return true; - } -} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardsDialoguePlugin.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardsDialoguePlugin.kt new file mode 100644 index 000000000..6880892b7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardsDialoguePlugin.kt @@ -0,0 +1,90 @@ +package content.region.misthalin.varrock.dialogue + +import content.data.Quests +import content.region.misthalin.varrock.handlers.MuseumInteractionListener.Companion.handleMuseumDoor +import core.api.forceWalk +import core.api.getScenery +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class DoorGuardDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.NEUTRAL, "Hello there. Come to see the new museum?").also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.NEUTRAL, "Yes, how do I get in?").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "Well, the main entrance is 'round the front. Just head west then north slightly, you can't miss it!").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "What about these doors?").also { stage++ } + 3 -> { + if (isQuestComplete(player, Quests.THE_DIG_SITE)) { + npcl(FacialExpression.NEUTRAL, "They're primarily for the workmen bringing finds from the Dig Site, but you can go through if you want.").also { stage++ } + } else { + npcl(FacialExpression.NEUTRAL, "They're for the workmen bringing finds from the Dig Site; sorry, but you can't go through.").also { stage = END_DIALOGUE } + } + } + 4 -> playerl(FacialExpression.NEUTRAL, "Okay, thanks.").also { stage++ } + 5 -> { + end() + handleMuseumDoor(player, getScenery(3264, 3441, 0)) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DoorGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MUSEUM_GUARD_5943) + } +} + +@Initializable +class GateGuardDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + // Shows the player walking to this spot first https://www.youtube.com/watch?v=t-oeY3a-ZSA&t=53s + if (player.location != Location(3261, 3447)) forceWalk(player, Location(3261, 3447), "smart") + + if (isQuestComplete(player, Quests.THE_DIG_SITE)) { + npcl(FacialExpression.NEUTRAL, "Welcome! Would you like to go into the Dig Site archaeology cleaning area?").also { stage = START_DIALOGUE } + } else { + npcl(FacialExpression.NEUTRAL, "You're not permitted in this area.").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> showTopics( + Topic("Yes, I'll go in!", 1, true), + Topic("No thanks, I'll take a look around out here.", END_DIALOGUE, true) + ) + 1 -> { + end() + handleMuseumDoor(player, getScenery(3261, 3446, 0)) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GateGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MUSEUM_GUARD_5941) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java index 6d7afec28..9cf02f497 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java @@ -7,12 +7,11 @@ import core.plugin.Initializable; import core.game.node.entity.player.Player; /** - * Handles the PhilopDialogue dialogue. - * @author 'Vexia + * Philop - Child in Gertrude's House */ @Initializable public class PhilopDialogue extends DialoguePlugin { - + // https://www.youtube.com/watch?v=ANI7DaRVEbg public PhilopDialogue() { } @@ -31,23 +30,23 @@ public class PhilopDialogue extends DialoguePlugin { switch (stage) { case 0: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gwwrr!"); + interpreter.sendDialogues(npc, FacialExpression.CHILD_ANGRY, "Gwwrr!"); stage = 1; break; case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err, hello there. What's that you have there?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Err, hello there. What's that you have there?"); stage = 2; break; case 2: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gwwwrrr! Dwa-gon Gwwwwrrrr!"); + interpreter.sendDialogues(npc, FacialExpression.CHILD_ANGRY, "Gwwwrrr! Dwa-gon Gwwwwrrrr!"); stage = 3; break; case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Enjoy playing with your dragon, then."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Enjoy playing with your dragon, then."); stage = 4; break; case 4: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gwwwrrr!"); + interpreter.sendDialogues(npc, FacialExpression.CHILD_ANGRY, "Gwwwrrr!"); stage = 5; break; case 5: diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java index ed93e45e1..26eac9af2 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java @@ -247,7 +247,7 @@ public class RomilyWeaklaxDialogue extends DialoguePlugin { @Override public boolean handle(NodeUsageEvent event) { if (!event.getPlayer().getAchievementDiaryManager().getDiary(DiaryType.VARROCK).isComplete(2,5)) { - event.getPlayer().getDialogueInterpreter().open(3205, event.getUsedItem()); + event.getPlayer().getDialogueInterpreter().open(3205, event.getUsedWith().asNpc(), event.getUsedItem()); } return true; } diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java index 7c875fd45..d17b6b329 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue plugin used for the shilop npc. @@ -55,25 +56,25 @@ public final class ShilopDialogue extends DialoguePlugin { } else if (args[0] instanceof Integer) { id = (Integer) args[0]; } - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (quest.getStage(player)) { case 0: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello again."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); stage = 0; break; case 10: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there, I've been looking for you."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello there, I've been looking for you."); stage = 100; break; case 20: case 30: case 40: case 50: - interpreter.sendDialogues(player, null, "Where did you say you saw Fluffs?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where did you say you saw Fluffs?"); stage = 130; break; default: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello again."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); stage = 0; break; } @@ -82,26 +83,26 @@ public final class ShilopDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (stage) { case 0: - interpreter.sendDialogues(id, FacialExpression.OLD_NORMAL, "You think you're tough do you?"); + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "You think you're tough do you?"); stage = 1; break; case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Pardon?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Pardon?"); stage = 2; break; case 2: - interpreter.sendDialogues(id, FacialExpression.OLD_NORMAL, "I can beat anyone up!"); + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "I can beat anyone up!"); stage = 3; break; case 3: - interpreter.sendDialogues(783, FacialExpression.OLD_NORMAL, "He can you know!"); + interpreter.sendDialogues(783, FacialExpression.CHILD_ANGRY, "He can you know!"); stage = 4; break; case 4: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Really?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Really?"); stage = 5; break; case 5: @@ -112,59 +113,59 @@ public final class ShilopDialogue extends DialoguePlugin { end(); break; case 100:// stage 10 - interpreter.sendDialogues(id, FacialExpression.OLD_NORMAL, "I didn't mean to take it! I just forgot to pay."); + interpreter.sendDialogues(id, FacialExpression.CHILD_SURPRISED, "I didn't mean to take it! I just forgot to pay."); stage = 101; break; case 101: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What? I'm trying to help your mum find Fluffs."); + interpreter.sendDialogues(player, FacialExpression.THINKING, "What? I'm trying to help your mum find Fluffs."); stage = 102; break; case 102: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "I might be able to help. Fluffs followed me to our secret", "play area and I haven't seen her since."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "I might be able to help. Fluffs followed me to our secret", "play area and I haven't seen her since."); stage = 103; break; case 103: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where is this play area?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where is this play area?"); stage = 104; break; case 104: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "If I told you that, it wouldn't be a secret."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "If I told you that, it wouldn't be a secret."); stage = 105; break; case 105: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What will make you tell me?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "What will make you tell me?"); stage = 106; break; case 106: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "Well...now you ask, I am a bit short on cash."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SUSPICIOUS, "Well...now you ask, I am a bit short on cash."); stage = 107; break; case 107: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How much?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "How much?"); stage = 108; break; case 108: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "10 coins."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "10 coins."); stage = 109; break; case 109: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "10 coins?!"); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SURPRISED, "10 coins?!"); stage = 110; break; case 110: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "I'll handle this."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_NORMAL, "I'll handle this."); stage = 111; break; case 111: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "100 coins should cover it."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_FRIENDLY, "100 coins should cover it."); stage = 112; break; case 112: - interpreter.sendDialogues(player, null, "100 coins! Why should I pay you?"); + interpreter.sendDialogues(player, FacialExpression.ANGRY, "100 coins! Why should I pay you?"); stage = 113; break; case 113: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "You shouldn't, but we won't help otherwise. We never", "liked that cat anyway, so what do you say?"); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_NORMAL, "You shouldn't, but we won't help otherwise. We never", "liked that cat anyway, so what do you say?"); stage = 114; break; case 114: @@ -174,17 +175,17 @@ public final class ShilopDialogue extends DialoguePlugin { case 115: switch (buttonId) { case 1: - interpreter.sendDialogues(player, null, "I'm not paying you a penny."); + interpreter.sendDialogues(player, FacialExpression.ANGRY, "I'm not paying you a penny."); stage = 116; break; case 2: - interpreter.sendDialogues(player, null, "Okay then, I'll pay."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay then, I'll pay."); stage = 118; break; } break; case 116: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "Okay then, I'll find another way to make money."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "Okay then, I'll find another way to make money."); stage = 117; break; case 117: @@ -206,26 +207,26 @@ public final class ShilopDialogue extends DialoguePlugin { quest.setStage(player, 20); break; case 119: - interpreter.sendDialogues(player, null, "There you go, now where did you see Fluffs?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "There you go, now where did you see Fluffs?"); stage = 120; break; case 120: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "We play at an abandoned lumber mill to the north east.", "Just beyond the Jolly Boar Inn. I saw Fluffs running", "around in there."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_NORMAL, "We play at an abandoned lumber mill to the north east.", "Just beyond the Jolly Boar Inn. I saw Fluffs running", "around in there."); stage = 121; break; case 121: - interpreter.sendDialogues(player, null, "Anything else?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Anything else?"); stage = 122; break; case 122: - interpreter.sendDialogues(id == 781 ? 783 : 781, null, "Well, you'll have to find the broken fence to get in. I'm", "sure you can manage that."); + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "Well, you'll have to find the broken fence to get in. I'm", "sure you can manage that."); stage = 123; break; case 123: end(); break; case 130: - interpreter.sendDialogues(id, null, "Weren't you listening? I saw the flea bag in the old", "lumber mill just north east of here. Just walk past the", "Jolly Boar Inn and you should find it."); + interpreter.sendDialogues(id, FacialExpression.CHILD_SIDE_EYE, "Weren't you listening? I saw the flea bag in the old", "lumber mill just north east of here. Just walk past the", "Jolly Boar Inn and you should find it."); stage = 131; break; case 131: diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt index 57b98c3e2..e61b9d5dc 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt @@ -5,13 +5,14 @@ import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player import org.rs09.consts.Items -class SinkethsDiary - : InteractionListener { +// This is not formatted well. See _-88E9n9jWA +class SinkethsDiary : InteractionListener { // Obtainable during the What Lies Below quest. companion object { private val TITLE = "Sin'keth's diary" @@ -192,10 +193,11 @@ class SinkethsDiary } override fun defineListeners() { - on(Items.SINKETHS_DIARY_11002, IntType.ITEM, "read") { player, _ -> + on(Items.SINKETHS_DIARY_11002, IntType.ITEM, "read") { player, node -> setAttribute(player, "bookInterfaceCallback", ::display) setAttribute(player, "bookInterfaceCurrentPage", 0) display(player, 0, 0) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java index f25b6048d..02deb3337 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.plugin.Initializable; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue used for wilough. @@ -55,25 +56,25 @@ public final class WiloughDialogue extends DialoguePlugin { } else if (args[0] instanceof Integer) { id = (int) args[0]; } - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (quest.getStage(player)) { case 0: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello again."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); stage = 0; break; case 10: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there, I've been looking for you."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello there, I've been looking for you."); stage = 100; break; case 20: case 30: case 40: case 50: - interpreter.sendDialogues(player, null, "Where did you say you saw Fluffs?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where did you say you saw Fluffs?"); stage = 130; break; default: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello again."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); stage = 0; break; } @@ -82,26 +83,26 @@ public final class WiloughDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (stage) { case 0: - interpreter.sendDialogues(id, FacialExpression.HALF_GUILTY, "You think you're tough do you?"); + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "You think you're tough do you?"); stage = 1; break; case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Pardon?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Pardon?"); stage = 2; break; case 2: - interpreter.sendDialogues(id, FacialExpression.HALF_GUILTY, "I can beat anyone up!"); + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "I can beat anyone up!"); stage = 3; break; case 3: - interpreter.sendDialogues(781, FacialExpression.HALF_GUILTY, "He can you know!"); + interpreter.sendDialogues(781, FacialExpression.CHILD_ANGRY, "He can you know!"); stage = 4; break; case 4: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Really?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Really?"); stage = 5; break; case 5: @@ -112,59 +113,59 @@ public final class WiloughDialogue extends DialoguePlugin { end(); break; case 100:// stage 10 - interpreter.sendDialogues(id, FacialExpression.HALF_GUILTY, "I didn't mean to take it! I just forgot to pay."); + interpreter.sendDialogues(id, FacialExpression.CHILD_SURPRISED, "I didn't mean to take it! I just forgot to pay."); stage = 101; break; case 101: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What? I'm trying to help your mum find Fluffs."); + interpreter.sendDialogues(player, FacialExpression.THINKING, "What? I'm trying to help your mum find Fluffs."); stage = 102; break; case 102: - interpreter.sendDialogues(id == 783 ? 781 : 783, null, "I might be able to help. Fluffs followed me to our secret", "play area and I haven't seen her since."); + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SIDE_EYE, "Ohh...well, in that case I might be able to help. Fluffs", "followed me to my super secret hideout, I haven't seen", "her since. She's probably off eating small creatures", "somewhere."); stage = 103; break; case 103: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where is this play area?"); + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where is this secret hideout? I really need to find that", "cat for your mum."); stage = 104; break; case 104: - interpreter.sendDialogues(id == 783 ? 781 : 783, null, "If I told you that, it wouldn't be a secret."); + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SIDE_EYE, "If I told you that, it wouldn't be a secret."); stage = 105; break; case 105: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What will make you tell me?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "What will make you tell me?"); stage = 106; break; case 106: - interpreter.sendDialogues(id == 783 ? 781 : 783, null, "Well...now you ask, I am a bit short on cash."); + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SUSPICIOUS, "Well...now you ask, I am a bit short on cash."); stage = 107; break; case 107: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How much?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "How much?"); stage = 108; break; case 108: - interpreter.sendDialogues(id == 783 ? 781 : 783, null, "10 coins."); + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SIDE_EYE, "10 coins."); stage = 109; break; case 109: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "10 coins?!"); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_SURPRISED, "10 coins?!"); stage = 110; break; case 110: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "I'll handle this."); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_NORMAL, "I'll handle this."); stage = 111; break; case 111: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "100 coins should cover it."); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_FRIENDLY, "100 coins should cover it."); stage = 112; break; case 112: - interpreter.sendDialogues(player, null, "100 coins! Why should I pay you?"); + interpreter.sendDialogues(player, FacialExpression.ANGRY, "100 coins! Why should I pay you?"); stage = 113; break; case 113: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "You shouldn't, but we won't help otherwise. We never", "liked that cat anyway, so what do you say?"); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_NORMAL, "You shouldn't, but we won't help otherwise. We never", "liked that cat anyway, so what do you say?"); stage = 114; break; case 114: @@ -174,17 +175,17 @@ public final class WiloughDialogue extends DialoguePlugin { case 115: switch (buttonId) { case 1: - interpreter.sendDialogues(player, null, "I'm not paying you a penny."); + interpreter.sendDialogues(player, FacialExpression.ANGRY, "I'm not paying you a penny."); stage = 116; break; case 2: - interpreter.sendDialogues(player, null, "Okay then, I'll pay."); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay then, I'll pay."); stage = 118; break; } break; case 116: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "Okay then, I'll find another way to make money."); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_SIDE_EYE, "Okay then, I'll find another way to make money."); stage = 117; break; case 117: @@ -205,26 +206,26 @@ public final class WiloughDialogue extends DialoguePlugin { } break; case 119: - interpreter.sendDialogues(player, null, "There you go, now where did you see Fluffs?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "There you go, now where did you see Fluffs?"); stage = 120; break; case 120: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "We play at an abandoned lumber mill to the north east.", "Just beyond the Jolly Boar Inn. I saw Fluffs running", "around in there."); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_NORMAL, "We play at an abandoned lumber mill to the north east.", "Just beyond the Jolly Boar Inn. I saw Fluffs running", "around in there."); stage = 121; break; case 121: - interpreter.sendDialogues(player, null, "Anything else?"); + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Anything else?"); stage = 122; break; case 122: - interpreter.sendDialogues(id == 783 ? 783 : id, null, "Well, you'll have to find the broken fence to get in. I'm", "sure you can manage that."); + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_SIDE_EYE, "Well, you'll have to find the broken fence to get in. I'm", "sure you can manage that."); stage = 123; break; case 123: end(); break; case 130: - interpreter.sendDialogues(id, null, "Weren't you listening? I saw the flea bag in the old", "lumber mill just north east of here. Just walk past the", "Jolly Boar Inn and you should find it."); + interpreter.sendDialogues(id, FacialExpression.CHILD_SIDE_EYE, "Weren't you listening? I saw the flea bag in the old", "lumber mill just north east of here. Just walk past the", "Jolly Boar Inn and you should find it."); stage = 131; break; case 131: diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt index 76d8eefb3..949786650 100644 --- a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt @@ -4,7 +4,7 @@ import content.global.handlers.iface.BookInterface import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet -import core.api.setAttribute +import core.api.storeBookInHouse import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player @@ -144,7 +144,7 @@ class AbyssalBook : InteractionListener { BookLine("- if the barriers between", 57), BookLine("these dimensions are", 58), BookLine("sufficiently weakened,", 59), - BookLine("there ma exist the", 60), + BookLine("there may exist the", 60), BookLine("possibility of an alternative", 61), BookLine("method to proceed", 62), BookLine("with Operation:", 63), @@ -371,8 +371,9 @@ class AbyssalBook : InteractionListener { } override fun defineListeners() { - on(Items.ABYSSAL_BOOK_5520, IntType.ITEM, "read") { player, _ -> + on(Items.ABYSSAL_BOOK_5520, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt b/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt index 19a1f06aa..f49899210 100644 --- a/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt +++ b/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt @@ -21,6 +21,7 @@ import core.game.diary.DiaryLevel import core.game.event.* import core.game.node.entity.player.link.SpellBookManager import core.game.node.entity.skill.Skills +import content.data.Quests class VarrockAchivementDiary : DiaryEventHookBase(DiaryType.VARROCK) { companion object { @@ -203,7 +204,7 @@ class VarrockAchivementDiary : DiaryEventHookBase(DiaryType.VARROCK) { ) } - if (player.questRepository.isComplete("Dragon Slayer")) { + if (player.questRepository.isComplete(Quests.DRAGON_SLAYER)) { if (event.target.id == NPCs.OZIACH_747 && event.option == "trade" && inBorders(player, OZIACH_SHOP)) { finishTask( player, diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.java b/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.java deleted file mode 100644 index 0ada0d65e..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.java +++ /dev/null @@ -1,64 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.game.node.entity.npc.AbstractNPC; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.tools.RandomFunction; - -/** - * Represents the representation of the benny npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class BennyNPC extends AbstractNPC { - - /** - * The NPC ids of NPCs using this plugin. - */ - private static final int[] ID = { 5925 }; - - /** - * Represents the random messages for benny to display. - */ - private static final String[] MESSAGES = new String[] { "Read all about it!", "Varrock Herald, on sale here!", "Buy your Varrock Herald now!", "Extra! Extra! Read all about it!", "Varrock Herald, now only 50 gold!" }; - - /** - * Constructs a new {@code BennyNPC} {@code Object}. - */ - public BennyNPC() { - super(0, null); - } - - /** - * Constructs a new {@code BennyNPC} {@code Object}. - * @param id the id. - * @param location the location. - */ - private BennyNPC(int id, Location location) { - super(id, location); - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new BennyNPC(id, location); - } - - @Override - public void tick() { - super.tick(); - if (RandomFunction.random(0, 12) == 5) { - sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]); - } - } - - @Override - public int[] getIds() { - return ID; - } - - @Override - public int getWalkRadius() { - return 6; - } -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.kt b/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.kt new file mode 100644 index 000000000..1e047b4d2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.kt @@ -0,0 +1,39 @@ +package content.region.misthalin.varrock.handlers + +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class BennyNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return BennyNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BENNY_5925) + } + + override fun handleTickActions() { + super.handleTickActions() + if (RandomFunction.roll(12)) { + core.api.sendChat(this, messages.random()) + } + } + + override fun getWalkRadius(): Int { + return 6 + } + + companion object { + private val messages = arrayOf( + "Read all about it!", + "Varrock Herald, on sale here!", + "Buy your Varrock Herald now!", + "Extra! Extra! Read all about it!", + "Varrock Herald, now only 50 gold!" + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/BrassKeyDoorPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/BrassKeyDoorPlugin.java deleted file mode 100644 index 0e74482b9..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/BrassKeyDoorPlugin.java +++ /dev/null @@ -1,43 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.global.action.DoorActionHandler; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.scenery.Scenery; -import core.game.world.map.Location; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to handle the brass key door plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class BrassKeyDoorPlugin extends OptionHandler { - - @Override - public boolean handle(Player player, Node node, String option) { - if (player.getInventory().contains(983, 1)) { - DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); - } else { - player.getPacketDispatch().sendMessage("This door is locked."); - return true; - } - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(1804).getHandlers().put("option:open", this); - return this; - } - - @Override - public Location getDestination(Node node, Node n) { - return DoorActionHandler.getDestination(((Player) node), ((Scenery) n)); - } - -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ChampionsArenaPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/ChampionsArenaPlugin.java deleted file mode 100644 index 7539754d3..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/ChampionsArenaPlugin.java +++ /dev/null @@ -1,37 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.scenery.Scenery; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the champions arena plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class ChampionsArenaPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(10556).getHandlers().put("option:open", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); - switch (id) { - case 10556: - player.getDialogueInterpreter().open(3050, true, true); - break; - } - return true; - } - -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/GuidorDoorPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/GuidorDoorPlugin.java deleted file mode 100644 index fa4da00a0..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/GuidorDoorPlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the guidor door plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class GuidorDoorPlugin extends OptionHandler { - - @Override - public boolean handle(Player player, Node node, String option) { - player.getDialogueInterpreter().open(342, true, true); - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(2032).getHandlers().put("option:open", this); - return this; - } - -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java index fc5c15e86..277d7d634 100644 --- a/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java @@ -14,6 +14,7 @@ import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; import core.plugin.Plugin; import core.tools.RandomFunction; +import content.data.Quests; /** * Represents the plugin used for handling a lumber yard crate. @@ -30,7 +31,7 @@ public final class LumberYardCratePlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); switch (option) { case "squeeze-under": Location dest = null; diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumGatePlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumGatePlugin.java deleted file mode 100644 index 1ce507bb3..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumGatePlugin.java +++ /dev/null @@ -1,36 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.global.action.DoorActionHandler; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.scenery.Scenery; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used for the museum gate plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class MuseumGatePlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(24536).getHandlers().put("option:open", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - if (player.getLocation().getY() >= 3447) { - player.getDialogueInterpreter().open(5941); - } else { - DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); - return true; - } - return true; - } -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInteractionListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInteractionListener.kt new file mode 100644 index 000000000..f72eed5d1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInteractionListener.kt @@ -0,0 +1,125 @@ +package content.region.misthalin.varrock.handlers + +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class MuseumInteractionListener : InteractionListener { + override fun defineListeners() { + // Basement Stairs + addClimbDest(Location(3255, 3451, 0), Location(1759, 4958, 0)) + addClimbDest(Location(1758, 4959, 0), Location(3258, 3452, 0)) + + on(mapObject, IntType.SCENERY, "look-at", "take") { player, node -> + if (getUsedOption(player) == "take") { + if (!addItem(player, Items.MUSEUM_MAP_11184)) { + sendMessage(player, "You don't have enough space in your inventory.") + } + } else { + when (node.id) { + Scenery.MAP_24390 -> setAttribute(player, "iface:527:floor", "main") + Scenery.MAP_24391 -> setAttribute(player, "iface:527:floor", "second") + Scenery.MAP_24392 -> setAttribute(player, "iface:527:floor", "top") + } + openInterface(player, Components.VM_MUSEUM_MAP_527) + } + return@on true + } + + on(Items.MUSEUM_MAP_11184, IntType.ITEM, "look-at") { player, node -> + openInterface(player, Components.VM_MUSEUM_MAP_527) + return@on true + } + + on(Scenery.INFORMATION_BOOTH_24452, IntType.SCENERY, "look-at") { player, node -> + // TODO: I cannot find anything that shows what this does in 2009. + sendMessage(player, "Nothing interesting happens.") + return@on true + } + + on(doorsToDigsite, IntType.SCENERY, "open") { player, node -> + if (node.id == Scenery.GATE_24536) { + if (player.location.y <= 3446) { + handleMuseumDoor(player, node.asScenery()) + } else { + openDialogue(player, NPCs.MUSEUM_GUARD_5941) + } + return@on true + } else { + if (player.location.y >= 3442) { + handleMuseumDoor(player, node.asScenery()) + } else { + openDialogue(player, NPCs.MUSEUM_GUARD_5943) + } + } + return@on true + } + + on(Scenery.TOOLS_24535, IntType.SCENERY, "take") { player, node -> + sendDialogueOptions( + player, + "Which tool would you like?", + "Trowel", + "Rock pick", + "Specimen brush", + "Leather gloves", + "Leather boots" + ) + addDialogueAction(player) { _, button -> + val item = when (button) { + 2 -> Items.TROWEL_676 + 3 -> Items.ROCK_PICK_675 + 4 -> Items.SPECIMEN_BRUSH_670 + 5 -> Items.LEATHER_GLOVES_1059 + 6 -> Items.LEATHER_BOOTS_1061 + else -> return@addDialogueAction + } + val name = item.asItem().name.lowercase() + val word = if (name.startsWith("leather")) "pair of " else "" + + if (!addItem(player, item)) { + sendMessage(player, "You don't have enough space in your inventory.") + } else { + sendItemDialogue(player, item, "You take a $word$name from the rack.") + } + } + return@on true + } + + on(naturalHistoryPlaques, IntType.SCENERY, "study") { player, node -> + openInterface(player, 533) + return@on true + } + } + + companion object { + private val doorsToDigsite = intArrayOf(Scenery.GATE_24536, Scenery.DOOR_24565, Scenery.DOOR_24567) + private val mapObject = intArrayOf(Scenery.MAP_24390, Scenery.MAP_24391, Scenery.MAP_24392) + private val naturalHistoryPlaques = intArrayOf( + Scenery.PLAQUE_24605, Scenery.PLAQUE_24606, Scenery.PLAQUE_24607, Scenery.PLAQUE_24608, + Scenery.PLAQUE_24609, Scenery.PLAQUE_24610, Scenery.PLAQUE_24611, Scenery.PLAQUE_24612, + Scenery.PLAQUE_24613, Scenery.PLAQUE_24614, Scenery.PLAQUE_24615, Scenery.PLAQUE_24616, + Scenery.PLAQUE_24617, Scenery.PLAQUE_24618 + ) + + fun handleMuseumDoor(player: Player, door: core.game.node.scenery.Scenery?) { + val npc = if (door?.id == Scenery.GATE_24536) findLocalNPC(player, NPCs.MUSEUM_GUARD_5941) else findLocalNPC(player, NPCs.MUSEUM_GUARD_5943) + val animation = if (DoorActionHandler.getEndLocation(player, door).y > player.location.y) Animation(6391) else Animation(6392) + + if (npc != null) { + animate(npc, animation) + queueScript(player, animationDuration(animation)) { DoorActionHandler.handleAutowalkDoor(player, door) } + } else { + DoorActionHandler.handleAutowalkDoor(player, door) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInterfaceListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInterfaceListener.kt new file mode 100644 index 000000000..e31f4cefe --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInterfaceListener.kt @@ -0,0 +1,91 @@ +package content.region.misthalin.varrock.handlers + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class MuseumInterfaceListener : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(Components.VM_MUSEUM_MAP_527) { player, _ -> + showMapFloor(player, getAttribute(player, "iface:527:floor", "main")) + removeAttribute(player, "iface:527:floor") + return@onOpen true + } + + on(Components.VM_MUSEUM_MAP_527) { player, _, _, buttonID, _, _ -> + showMapFloor(player, when (buttonID) { + in mapButtonsToBasement -> "basement" + in mapButtonsToMainFloor -> "main" + in mapButtonsToSecondFloor -> "second" + in mapButtonsToTopFloor -> "top" + else -> return@on true + }) + return@on true + } + + onOpen(NATURAL_HISTORY_EXAM_533) { player, component -> + // The model for each display is confusing as hell. Some are objects and some are NPCs. + val model = getScenery(1763, 4937, 0)?.definition?.modelIds?.first() + player.packetDispatch.sendModelOnInterface(model!!, component.id, 3, 0) + + // Showing this child makes child 28 - 31 visible. + setComponentVisibility(player, component.id, 27, false) + + // The case number to display. + setInterfaceText(player, "1", component.id, 25) + + // The question text. + setInterfaceText(player, "When will the Natural History Quiz be implemented?", component.id, 28) + + // The choices. + setInterfaceText(player, "Never.", component.id, 29) + setInterfaceText(player, "In 2 days.", component.id, 30) + setInterfaceText(player, "After Barbarian Assault.", component.id, 31) + return@onOpen true + } + + on(NATURAL_HISTORY_EXAM_533) { player, component, opcode, buttonID, slot, itemID -> + if (buttonID in 29..31) { + closeInterface(player) + setVarbit(player, 3637, 1, false) + playAudio(player, Sounds.VM_GAIN_KUDOS_3653) + sendNPCDialogue(player, NPCs.ORLANDO_SMITH_5965, "Nice job, mate. That looks about right.") + } + return@on true + } + } + companion object { + private const val NATURAL_HISTORY_EXAM_533 = 533 + + private val mapButtonsToBasement = intArrayOf(41, 186) + private val mapButtonsToMainFloor = intArrayOf(117, 120, 187, 188) + private val mapButtonsToSecondFloor = intArrayOf(42, 44, 152, 153) + private val mapButtonsToTopFloor = intArrayOf(42, 44, 118, 119) + + private fun showMapFloor(player: Player, floor: String) { + when (floor) { + "basement" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 2, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 7, false) + } + "main" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 3, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 7, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 2, false) + } + "second" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 2, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 5, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 3, false) + } + "top" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 3, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 5, false) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumMapArea.kt b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumMapArea.kt new file mode 100644 index 000000000..cdb5dcb96 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumMapArea.kt @@ -0,0 +1,29 @@ +package content.region.misthalin.varrock.handlers + +import core.api.MapArea +import core.api.closeOverlay +import core.api.openOverlay +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Components + +class MuseumMapArea : MapArea { + override fun defineAreaBorders(): Array { + val vmArea = ZoneBorders(3253, 3442, 3267, 3455) + val vmBasementArea = ZoneBorders(1730, 4932, 1788, 4988) + return arrayOf(vmArea, vmBasementArea) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + openOverlay(entity.asPlayer(), Components.VM_KUDOS_532) + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + closeOverlay(entity.asPlayer()) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java deleted file mode 100644 index d21dee850..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java +++ /dev/null @@ -1,43 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.NPCDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the option plugin used to shoo away a dog. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class ShooAwayStrayDogPlugin extends OptionHandler { - - /** - * Represents the animatio to use. - */ - private static final Animation ANIMATION = new Animation(2110); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - NPCDefinition.forId(5917).getHandlers().put("option:shoo-away", this); - NPCDefinition.setOptionHandler("shoo-away", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - player.sendChat("Thbbbbt!"); - player.animate(ANIMATION); - NPC dog = (NPC) node; - dog.sendChat("Whine!"); - dog.moveStep(); - dog.getPulseManager().clear(); - return true; - } - -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockBrokenCart.java b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockBrokenCart.java deleted file mode 100644 index 22d6b9e7e..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockBrokenCart.java +++ /dev/null @@ -1,28 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * @author 'Vexia - */ -@Initializable -public class VarrockBrokenCart extends OptionHandler { - - @Override - public boolean handle(Player player, Node node, String option) { - player.getDialogueInterpreter().open(70099, "You search the cart but are surprised to find very little there. It's a", "little odd for a travelling trader not to have anything to trade."); - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(23055).getHandlers().put("option:search", this); - return this; - } - -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockCensusInterface.kt b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockCensusInterface.kt new file mode 100644 index 000000000..6cb95f014 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockCensusInterface.kt @@ -0,0 +1,27 @@ +package content.region.misthalin.varrock.handlers + +import core.api.getVarbit +import core.api.setVarbit +import core.game.interaction.InterfaceListener + +class VarrockCensusInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(INTERFACE_ID) { player, _, _, buttonID, _, _ -> + when (buttonID) { + 2 -> setVarbit(player, VARBIT_ID, getVarbit(player, VARBIT_ID).plus(1)) + 3 -> setVarbit(player, VARBIT_ID, getVarbit(player, VARBIT_ID).minus(1)) + else -> return@on true + } + return@on true + } + + onClose(INTERFACE_ID) { player, _ -> + setVarbit(player, VARBIT_ID, 0) + return@onClose true + } + } + companion object { + const val INTERFACE_ID = 794 + const val VARBIT_ID = 5390 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockInteractionListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockInteractionListener.kt new file mode 100644 index 000000000..1610dafb6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockInteractionListener.kt @@ -0,0 +1,91 @@ +package content.region.misthalin.varrock.handlers + +import content.region.misthalin.varrock.dialogue.KnockAtBankDoor +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +class VarrockInteractionListener : InteractionListener { + override fun defineListeners() { + // Varrock Sewer Manhole + on(VARROCK_MANHOLE, IntType.SCENERY, "open", "close") { player, node -> + if (getUsedOption(player) == "open") { + playAudio(player, Sounds.MANHOLE_OPEN_75) + replaceScenery(node.asScenery(), Scenery.VARROCK_MANHOLE_OPEN_882, 100) + } else { + playAudio(player, Sounds.MANHOLE_CLOSE_74) + replaceScenery(node.asScenery(), Scenery.VARROCK_MANHOLE_CLOSED_881, -1) + } + return@on true + } + + // Phoenix Gang Hideout Plaque + on(Scenery.PLAQUE_23636, IntType.SCENERY, "read") { player, _ -> + openInterface(player, VTAM_IFACE) + return@on true + } + + // Varrock Census in the palace Library + on(Scenery.VARROCK_CENSUS_37209, IntType.SCENERY, "read") { player, _ -> + sendPlayerDialogue(player, "Hmm. The Varrock Census - year 160. That means it's nine years out of date.") + addDialogueAction(player) { _, buttonID -> + if (buttonID == 6) { + openInterface(player, VARROCK_CENSUS_IFACE) + } + } + return@on true + } + + // Broken Cart next to Rat Burgiss + on(Scenery.BROKEN_CART_23055, IntType.SCENERY, "search") { player, node -> + sendDialogue(player, "You search the cart but are surprised to find very little there. " + + "It's a little odd for a travelling trader not to have anything to trade.") + return@on true + } + + on(openOptionNodes, IntType.SCENERY, "open") { player, node -> + when (node.id) { + // Guidor's Bedroom Door + Scenery.BEDROOM_DOOR_2032 -> { + openDialogue(player, NPCs.GUIDORS_WIFE_342, true, true) + } + + // Guidor's Drawers + Scenery.DRAWERS_17466 -> { + sendMessage(player, "The drawers are locked shut.") + } + + // Brass Key Door to Edgeville Dungeon + Scenery.DOOR_1804 -> { + if (inInventory(player, Items.BRASS_KEY_983)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "This door is locked.") + } + } + } + return@on true + } + + // Varrock West Bank Door + on(Scenery.DOOR_24389, IntType.SCENERY, "knock-at") { player, node -> + openDialogue(player, KnockAtBankDoor()) + return@on true + } + + // TODO: Cooking Guild + // TODO: Fix Achievements + } + companion object { + private val VARROCK_MANHOLE = intArrayOf(Scenery.VARROCK_MANHOLE_CLOSED_881, Scenery.VARROCK_MANHOLE_OPEN_882) + private val openOptionNodes = intArrayOf(Scenery.BEDROOM_DOOR_2032, Scenery.DRAWERS_17466, Scenery.DOOR_1804) + private const val VTAM_IFACE = 531 + private const val VARROCK_CENSUS_IFACE = 794 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockNodePlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockNodePlugin.java deleted file mode 100644 index eb2307284..000000000 --- a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockNodePlugin.java +++ /dev/null @@ -1,313 +0,0 @@ -package content.region.misthalin.varrock.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.component.Component; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.global.action.ClimbActionHandler; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.node.scenery.SceneryBuilder; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to handle node interactions in varrock. - * - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class VarrockNodePlugin extends OptionHandler { - - /** - * Represents the bronze axe item. - */ - private static final Item BRONZE_AXE = new Item(1351); - - /** - * Represents the spade item. - */ - private static final Item SPADE = new Item(952); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(24357).getHandlers().put("option:climb-up", this); - SceneryDefinition.forId(24359).getHandlers().put("option:climb-down", this); - SceneryDefinition.forId(5581).getHandlers().put("option:take-axe", this); - SceneryDefinition.forId(36974).getHandlers().put("option:take-axe", this); - SceneryDefinition.forId(24427).getHandlers().put("option:walk-up", this); - SceneryDefinition.forId(24428).getHandlers().put("option:walk-down", this); - SceneryDefinition.forId(1749).getHandlers().put("option:climb-down", this); - SceneryDefinition.forId(23636).getHandlers().put("option:read", this); - SceneryDefinition.forId(24389).getHandlers().put("option:knock-at", this); - SceneryDefinition.forId(9662).getHandlers().put("option:take", this); - SceneryDefinition.forId(29534).getHandlers().put("option:enter", this); - SceneryDefinition.forId(17985).getHandlers().put("option:climb-down", this); - SceneryDefinition.forId(24366).getHandlers().put("option:climb-up", this); - return this; - } - - @Override - public boolean handle(final Player player, Node node, String option) { - final int id = node instanceof Scenery ? ((Scenery) node).getId() : ((Item) node).getId(); - switch (id) { - case 24366: - ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(3237, 3459)); - return true; - case 29534: - player.getDialogueInterpreter().open(543543); - return true; - case 17985: - ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(3204, 9910), "You enter the murky sewers."); - return true; - case 24389: - player.getDialogueInterpreter().open(KnockatDoorDialogue.ID, player.getLocation().getX() == 3182 ? 45 : 44); - break; - case 28094: - player.getDialogueInterpreter().sendDialogues(player, FacialExpression.THINKING, "I don't think I should go inside."); - break; - case 23636: - player.getInterfaceManager().open(new Component(531)); - break; - case 1749: - if (player.getLocation().getZ() == 2 && player.getLocation().getDistance(new Location(3096, 3433, 2)) < 4) { - ClimbActionHandler.climb(player, new Animation(827), Location.create(3097, 3432, 1)); - return true; - } else if (player.getLocation().getZ() == 1 && player.getLocation().getDistance(new Location(3095, 3433, 1)) < 4) { - ClimbActionHandler.climb(player, new Animation(827), Location.create(3096, 3432, 0)); - return true; - } - ClimbActionHandler.climbLadder(player, (Scenery) node, option); - return true; - case 5581: - case 36974: - if (!player.getInventory().add(BRONZE_AXE)) { - player.getPacketDispatch().sendMessage("You don't have enough inventory space."); - return true; - } - SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(5582), 5000); - break; - case 24357: - if (player.getLocation().getDistance(Location.create(3188, 3358, 0)) < 3) { - ClimbActionHandler.climb(player, new Animation(828), Location.create(3188, 3354, 1)); - return true; - } - if (((Scenery) node).getLocation().equals(new Location(3156, 3435, 0))) { - ClimbActionHandler.climb(player, new Animation(828), Location.create(3155, 3435, 1)); - return true; - } - ClimbActionHandler.climbLadder(player, (Scenery) node, option); - return true; - - case 24359: - if (player.getLocation().getDistance(Location.create(3231, 3382, 1)) < 3) { - ClimbActionHandler.climb(player, null, Location.create(3231, 3386, 0)); - return true; - } - ClimbActionHandler.climbLadder(player, (Scenery) node, option); - return true; - - case 24427: //varrock museum stairs that lead upstairs - if (player.getLocation().getDistance(Location.create(1758, 4959, 0)) < 3) { - ClimbActionHandler.climb(player, new Animation(-1), Location.create(3258, 3452, 0)); - return true; - } - return true; - - case 24428: //varrock museum stairs that lead downstairs - if (player.getLocation().getDistance(Location.create(3255, 3451, 0)) < 4) { - ClimbActionHandler.climb(player, new Animation(-1), Location.create(1759, 4958, 0)); - return true; - } - return true; - case 9662: - if (!player.getInventory().hasSpaceFor(SPADE)) { - player.getPacketDispatch().sendMessage("Not enough inventory space."); - return true; - } - player.getInventory().add(SPADE); - SceneryBuilder.replace((Scenery) node, ((Scenery) node).transform(0), 250); - return true; - } - return true; - } - - @Override - public boolean isWalk() { - return false; - } - - @Override - public boolean isWalk(final Player player, final Node node) { - return !(node instanceof Item); - } - - /** - * Represents the dialogue used for the knocking at a door in varrock bank. - * - * @author 'Vexia - * @version 1.0 - */ - public final class KnockatDoorDialogue extends DialoguePlugin { - - /** - * Represents the id of this dialogue. - */ - private static final int ID = 903042893; - - /** - * Represents the id to use. - */ - private int npcId; - - /** - * Constructs a new {@code KnockatDoorDialogue} {@code Object}. - */ - public KnockatDoorDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code KnockatDoorDialogue} {@code Object}. - * - * @param player the player. - */ - public KnockatDoorDialogue(final Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new KnockatDoorDialogue(player); - } - - @Override - public boolean open(Object... args) { - npcId = (int) args[0]; - player("I don't think I'm ever going to be allowed in there."); - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - player.lock(3); - interpreter.sendPlainMessage(true, "Knock knock..."); - GameWorld.getPulser().submit(new Pulse(3, player) { - @Override - public boolean pulse() { - interpreter.sendDialogues(npcId, null, "Who's there?"); - stage = 1; - return true; - } - }); - break; - case 1: - options("I'm " + player.getUsername() + ". Please let me in.", "Boo.", "Kanga.", "Thank.", "Doctor."); - stage = 2; - break; - case 2: - switch (buttonId) { - case 1: - player("I'm " + player.getUsername() + ". Please let me in."); - stage = 10; - break; - case 2: - player("Boo."); - stage = 20; - break; - case 3: - player("Kanga."); - stage = 30; - break; - case 4: - player("Thank."); - stage = 40; - break; - case 5: - player("Doctor."); - stage = 50; - break; - } - break; - case 10: - interpreter.sendDialogues(npcId, null, "No. Staff only beyond this point.", "You can't come in here."); - stage = 11; - break; - case 11: - end(); - break; - case 20: - interpreter.sendDialogues(npcId, null, "Boo who?"); - stage = 21; - break; - case 21: - player("There's no need to cry!"); - stage = 22; - break; - case 22: - interpreter.sendDialogues(npcId, FacialExpression.FURIOUS, "What? I'm not... oh, just go away!"); - stage = 23; - break; - case 23: - end(); - break; - case 30: - interpreter.sendDialogues(npcId, null, "Kanga who?"); - stage = 31; - break; - case 31: - player("No, 'kangaroo'."); - stage = 32; - break; - case 32: - interpreter.sendDialogues(npcId, FacialExpression.FURIOUS, "Stop messing about and go away!"); - stage = 33; - break; - case 33: - end(); - break; - case 40: - interpreter.sendDialogues(npcId, null, "Thank who?"); - stage = 41; - break; - case 41: - player("You're welcome!"); - stage = 42; - break; - case 42: - interpreter.sendDialogues(npcId, FacialExpression.FURIOUS, "Stop it!"); - stage = 43; - break; - case 43: - end(); - break; - case 50: - interpreter.sendDialogues(npcId, FacialExpression.FURIOUS, "Doctor. wh.. hang on, I'm not falling for that one again!", "Go away."); - stage = 51; - break; - case 51: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[]{903042893}; - } - - } -} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt b/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt index 795b33ce1..22243ca0b 100644 --- a/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt +++ b/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt @@ -17,6 +17,7 @@ import org.json.simple.JSONObject import org.rs09.consts.Items import core.ServerStore import core.ServerStore.Companion.getInt +import content.data.Quests /** * Represents the plugin used for buying a battle staff from zeke. @@ -70,7 +71,7 @@ class ZaffPlugin : OptionHandler() { override fun open(vararg args: Any): Boolean { npc = args[0] as NPC - quest = player.questRepository.getQuest("What Lies Below") + quest = player.questRepository.getQuest(Quests.WHAT_LIES_BELOW) interpreter.sendDialogues( npc, core.game.dialogue.FacialExpression.HALF_GUILTY, @@ -391,16 +392,18 @@ class ZaffPlugin : OptionHandler() { ammount = getStoreFile().getInt(player.username.toLowerCase()) var amt = value as Int if(amt > maxStaffs - ammount) amt = maxStaffs - ammount + if(amt == 0){ + return@sendInputDialogue + } val coinage = amt * 7000 if(!inInventory(player, Items.COINS_995, coinage)){ sendDialogue(player, "You can't afford that many.") return@sendInputDialogue } - - if(amt == 0){ + if(!hasSpaceFor(player, Item(Items.BATTLESTAFF_1392, amt)) && amountInInventory(player, Items.COINS_995) > coinage){ + sendDialogue(player, "You don't have enough inventory space.") return@sendInputDialogue } - if(removeItem(player, Item(Items.COINS_995, coinage), Container.INVENTORY)){ addItem(player, Items.BATTLESTAFF_1392, amt) getStoreFile()[player.username.toLowerCase()] = amt + ammount diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt index f6f8d2c70..56e81b3bb 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt @@ -1,20 +1,24 @@ package content.region.misthalin.varrock.quest.allfiredup +import content.data.Quests +import content.minigame.allfiredup.AFUBeacon +import core.api.setVarbit import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items -import content.minigame.allfiredup.AFUBeacon -import core.api.* /** * Represents the "All Fired Up" quest. * @author Ceikry */ @Initializable -class AllFiredUp : Quest("All Fired Up", 157, 156, 1){ +class AllFiredUp : Quest(Quests.ALL_FIRED_UP, 157, 156, 1, + 1282 /*this is actually unused*/, + 5133 /*source: ::varbits 1282, after trial and error confirmed that I need ::setvarp 1282 0 QUEST_STAGE*/, + 0, 1, 90) { //not started -- in progress -- completed override fun newInstance(`object`: Any?): Quest { return this } @@ -23,52 +27,118 @@ class AllFiredUp : Quest("All Fired Up", 157, 156, 1){ super.drawJournal(player, stage) var line = 11 player ?: return - if(stage == 0){ - line(player, "I can start this quest by speaking to !!King Roald?? in Varrock Palace.", line++) + if (stage == 0) { + line(player, "I can start this quest by speaking to !!King Roald?? in !!Varrock??", line++) + line(player, "!!Palace??.", line++) line++ line(player, "To start this quest, I require:", line++) line(player, "!!43 Firemaking??", line++, player.skills.getLevel(Skills.FIREMAKING) >= 43) - line(player, "!!Completion of Priest in Peril??", line++, player.questRepository.isComplete("Priest in Peril")) - + line(player, "!!Completion of Priest in Peril??", line++, player.questRepository.isComplete(Quests.PRIEST_IN_PERIL)) + limitScrolling(player, line, true) } else { - if(stage >= 10){ - line(player, "!!King Roald?? needs me to test the !!beacons??. He has sent me", line++, stage >= 20) - line(player, "to speak with !!Blaze Sharpeye??, by the beacon near the !!River Salve??.", line++, stage >= 20) + line(player, "I have agreed to help King Roald test the beacon network", line++, true) + line(player, "that he hopes will serve as an early warning system,", line++, true) + line(player, "should Misthalin and Asgarnia come under attack from", line++, true) + line(player, "Morytania or the Wilderness.", line++, true) + + if (stage > 10) { + line(player, "I've spoken with the head fire-tender, Blaze Sharpeye", line++, true) + line(player, "who is stationed near the Temple of Paterdomus, at the", line++, true) + line(player, "source of the River Salve.", line++, true) + } else if (stage == 10) { + line(player, "!!King Roald?? asked me to talk to the head fire-tender !!Blaze??", line++, false) + line(player, "!!Sharpeye?? who is stationed near the !!Temple of??", line++, false) + line(player, "!!Paterdomus??, at the source of the !!River Salve??.", line++, false) } - if(stage >= 20){ - line(player, "Blaze Sharpeye asked me to light the !!beacon??. I'm going to need:", line++, stage >= 30) - line(player, "20 logs of a single kind", line++, stage >= 30) - line(player, "A tinderbox", line++, stage >= 30) + + if (stage > 20) { + // Replaced with stage 30 text. + } else if (stage == 20) { + line(player, "!!Blaze?? has asked me to light the nearby !!beacon??.", line++, false) + line(player, "To light the !!beacon??, I need to add !!twenty logs?? of the same", line++, false) + line(player, "type and then light the fire with a !!tinderbox??.", line++, false) } - if(stage == 30){ - line(player, "I lit the beacon. I should speak to !!Blaze Sharpeye?? again.", line++, stage >= 40) + + if (stage > 30) { + line(player, "I've lit the beacon near Blaze by loading it with twenty logs", line++, true) + line(player, "and lighting them with a tinderbox.", line++, true) + } else if (stage == 30) { + line(player, "!!Blaze?? has asked me to light the nearby !!beacon??.", line++, false) + line(player, "I've placed !!twenty logs?? on the !!beacon?? and lit the fire with", line++, false) + line(player, "my !!tinderbox??. Now that it's blazing brightly, perhaps I", line++, false) + line(player, "should speak with !!Blaze??.", line++, false) } - if(stage >= 40){ - line(player, "Blaze Sharpeye asked me to go and speak with !!Squire Fyre?? near the !!limestone quarry??.", line++, stage >= 50) + + if (stage > 40) { + // Replaced with stage 50 text. + } else if (stage == 40) { + line(player, "!!Blaze?? has now asked me to light the !!beacon?? tended by", line++, false) + line(player, "!!Squire Fyre??, which is located just west of the !!Rag and??", line++, false) + line(player, "!!Bone Man??'s hovel.", line++, false) + line(player, "I need permission from !!Squire Fyre?? to light the !!beacon??", line++, false) } - if(stage >= 50){ - line(player, "Squire Fyre permitted me to light the !!beacon??. I'm going to need:", line++, stage >= 60) - line(player, "20 logs of a single kind", line++, stage >= 60) - line(player, "A tinderbox", line++, stage >= 60) + + if (stage > 50) { + // Replaced with stage 60 text. + } else if (stage == 50) { + line(player, "!!Blaze?? has now asked me to light the !!beacon?? tended by", line++, false) + line(player, "!!Squire Fyre??, which is located just west of the !!Rag and??", line++, false) + line(player, "!!Bone Man??'s hovel.", line++, false) + line(player, "To light the !!beacon??, I need to add !!twenty logs?? of the same", line++, false) + line(player, "type and then light the fire with a !!tinderbox??.", line++, false) } - if(stage == 60){ - line(player, "I should return to !!Blaze Sharpeye??.", line++) + + if (stage > 60) { + line(player, "Blaze has now asked me to light the beacon tended by", line++, true) + line(player, "Squire Fyre, near the Rag and Bone Man's hovel. I've", line++, true) + line(player, "loaded it with logs and set it alight; it's now blazing", line++, true) + line(player, "brightly.", line++, true) + } else if (stage == 60) { + line(player, "!!Blaze?? has now asked me to light the !!beacon?? tended by", line++, false) + line(player, "!!Squire Fyre??, which is located just west of the !!Rag and??", line++, false) + line(player, "!!Bone Man??'s hovel.", line++, false) + line(player, "I've placed twenty logs on the !!beacon?? and lit the fire with", line++, false) + line(player, "my tinderbox. Now that it's blazing brightly, perhaps I", line++, false) + line(player, "should speak with Blaze.", line++, false) } - if(stage >= 70){ - line(player, "Blaze asked me to add more logs to the dying fire. I'll need:", line++, stage >= 80) - line(player, "5 logs of a single kind", line++, stage >= 80) - line(player, "A tinderbox", line++, stage >= 80) + + if (stage > 70) { + // Replaced with stage 80 text. + } else if (stage == 70) { + line(player, "!!Blaze?? has now asked me to maintain the nearby !!beacon??.", line++, false) + line(player, "To maintain the !!beacon??, I need to add !!five logs?? of the same", line++, false) + line(player, "type.", line++, false) } - if(stage == 80){ - line(player, "I should speak to !!Blaze?? again.", line++) + + if (stage > 80) { + line(player, "Blaze has explained how to maintain a beacon. When the", line++, true) + line(player, "fire begins to die out, five more logs can be added to", line++, true) + line(player, "restore a beacon to its blazing state. I've tended the", line++, true) + line(player, "beacon near Blaze and have reported back to him.", line++, true) + } else if (stage == 80) { + line(player, "!!Blaze?? has explained how to maintain a beacon. When the", line++, false) + line(player, "fire begins to die out, !!five more logs?? can be added to", line++, false) + line(player, "restore a beacon to its blazing state.", line++, false) + line(player, "!!Blaze?? has asked me to maintain the !!beacon?? nearest him.", line++, false) } - if(stage == 90){ - line(player, "I should report to !!King Roald??.", line++) + + if (stage > 90) { + // Replaced with stage 100 complete text. + } else if (stage == 90){ + line(player, "I need to talk to !!King Roald?? in !!Varrock Palace?? to claim my", line++, false) + line(player, "reward.", line++, false) } - if(stage == 100){ - line(player, "I helped King Roald test the beacon network", line++) - line(player, " and have gained full access to it.", line++) + + if (stage == 100) { + line(player, "I spoke to King Roald who thanked me for helping and", line++, true) + line(player, "rewarded me with 20,000gp and 5,500 Firemaking XP. He", line++, true) + line(player, "told me that if I'm able to light six, ten and all fourteen", line++, true) + line(player, "fires simultaneously, he'll have further rewards for me.", line++, true) + line++ + line++ + line(player,"QUEST COMPLETE!", line) } + limitScrolling(player, line, false) } } @@ -83,13 +153,6 @@ class AllFiredUp : Quest("All Fired Up", 157, 156, 1){ player.skills.addExperience(Skills.FIREMAKING, 5500.0) player.inventory.add(Item(995,20000)) AFUBeacon.resetAllBeacons(player) - setVarbit(player, 1283, 0) player.questRepository.syncronizeTab(player) } - - override fun getConfig(player: Player?, stage: Int): IntArray { - if(stage == 100) return intArrayOf(1282, 90) - if(stage > 0) return intArrayOf(1282, 1) - else return intArrayOf(1282, 0) - } } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt index 200749835..9f85e6603 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable +import content.data.Quests @Initializable class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -14,7 +15,7 @@ class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player?.questRepository?.getStage("All Fired Up") ?: -1 + val qstage = player?.questRepository?.getStage(Quests.ALL_FIRED_UP) ?: -1 when(qstage){ 0 -> player.dialogueInterpreter.sendDialogue("He seems uninterested in talking.").also { stage = 1000 } 10 -> player("So, what's going on?").also { stage = 100 } @@ -48,7 +49,7 @@ class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { 112 -> npc("Our technique is super-secret, but quite effective. All","you do is put twenty logs of the same type on a","beacon and...").also { stage++ } 113 -> npc(FacialExpression.AMAZED,"SET IT ON FIRE WITH A TINDERBOX!").also { stage++ } 114 -> player("You really enjoy your job, don't you?").also { stage++ } - 115 -> npc("Yes. Yes I do. Now, why don't you go over there and","try lighting that beacon. Show us what you've got.").also { stage++; player.questRepository.getQuest("All Fired Up").setStage(player,20) } + 115 -> npc("Yes. Yes I do. Now, why don't you go over there and","try lighting that beacon. Show us what you've got.").also { stage++; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,20) } 116 -> options("Does it matter what type of log I use?","Okay.").also { stage++ } 117 -> when(buttonId){ 1 -> player("Does it matter what type of log I use?").also { stage = 150 } @@ -61,7 +62,7 @@ class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { 201 -> npc("Well, apparently, not for someone of your Firemaking","calibre and expertise. Now that you've got the hang of","things, we can get this show on the road.").also { stage++ } 202 -> npc("If you'd be so kind as to light the beacon to the west","and report back to me, I can make sure I can clearly","see its glow on the horizon.").also { stage++ } 203 -> npc("It's near the limestone quarry, north-east of Varrock,","west of the Rag and Bone Man's hovel.").also { stage++ } - 204 -> npc("My colleague, Squire Fyre, is tending that beacon.","She'll help you out if you run into any trouble.").also { stage = 116; player.questRepository.getQuest("All Fired Up").setStage(player,40) } + 204 -> npc("My colleague, Squire Fyre, is tending that beacon.","She'll help you out if you run into any trouble.").also { stage = 116; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,40) } //Stage = 60 300 -> player("Can you really see it from this far away?").also { stage++ } @@ -69,7 +70,7 @@ class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { 302 -> npc("This beacon, however, is struggling at the moment.","Do you see how the fire has died down?").also { stage++ } 303 -> player("Hmm, yes. The fire is a bit smaller and the logs look","rather charred.").also { stage++ } 304 -> npc("If a beacon's fire starts to die down, you can restore it","to its blazing glory by adding five logs.").also { stage++ } - 305 -> npc("You wouldn't mind topping this one up for me, would","you? Oh, how I love to see things burn!").also { stage++; player.questRepository.getQuest("All Fired Up").setStage(player, 70) } + 305 -> npc("You wouldn't mind topping this one up for me, would","you? Oh, how I love to see things burn!").also { stage++; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player, 70) } 306 -> options("Oh, alright, then.","Don't you have logs of your own you can use?").also { stage++ } 307 -> when(buttonId){ 1 -> player("Oh, alright, then.").also { stage++ } @@ -94,7 +95,7 @@ class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { 410 -> npc("Imminently, I'm sure - we're just waiting for the word","from King Roald. Speaking of which, have you reported","back to him about the progress we've made?").also { stage++ } 411 -> player("Not yet, I'm afraid.").also { stage++ } 412 -> npc("Well, what are you waiting for? This is a serious","matter! I'm sure King Roald is on the edge of his","throne, waiting for the news.").also { stage++ } - 413 -> player("I'll get right on that.").also { stage = 1000; player.questRepository.getQuest("All Fired Up").setStage(player,90) } + 413 -> player("I'll get right on that.").also { stage = 1000; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,90) } 420 -> npc("Yes... YES HAHAHAHA FIRE").also { stage = 412 } 1000 -> end() diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt index bd84874bc..4c5d4480a 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt @@ -4,6 +4,7 @@ import core.game.node.entity.skill.Skills import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests class KingRoaldAFUDialogue(val questStage: Int) : DialogueFile() { @@ -85,7 +86,7 @@ class KingRoaldAFUDialogue(val questStage: Int) : DialogueFile() { 17 -> { player("Thank you, Your Majesty. I'll seek out Blaze", "right away.") stage = END_DIALOGUE - player!!.questRepository.getQuest("All Fired Up").start(player) + player!!.questRepository.getQuest(Quests.ALL_FIRED_UP).start(player) } END_DIALOGUE -> end() @@ -103,7 +104,7 @@ class KingRoaldAFUDialogue(val questStage: Int) : DialogueFile() { 6 -> npc("There is much more to be done and this is but a", "pittance compared to what I'm willing to offer for", "further assistance!").also { stage++ } 7 -> { end() - player!!.questRepository.getQuest("All Fired Up").finish(player) + player!!.questRepository.getQuest(Quests.ALL_FIRED_UP).finish(player) } } } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt index ca33ddff3..606e784dc 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import content.minigame.allfiredup.BeaconState import core.api.* +import content.data.Quests @Initializable class SquireFyreDialogue(player: Player? = null) : DialoguePlugin(player){ @@ -15,7 +16,7 @@ class SquireFyreDialogue(player: Player? = null) : DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player.questRepository.getQuest("All Fired Up").getStage(player) + val qstage = player.questRepository.getQuest(Quests.ALL_FIRED_UP).getStage(player) when(qstage){ 40 -> player("Hi there. I'm helping Blaze and King Roald test the","beacon network. Can you see it from here? Blaze said","you have pretty sharp eyes.").also { stage = 100 } else -> npc("Carry on, friend.").also { stage = 1000 } @@ -27,7 +28,7 @@ class SquireFyreDialogue(player: Player? = null) : DialoguePlugin(player){ when(stage){ 100 -> npc("Of course I can see it. I haven't spent my entire life","practising my seeing skills for nothing! I'm happy to","report that the fire near Blaze is burning brightly.").also { stage++ } 101 -> player("Terrific! Blaze has asked me to light this fire as well, so","he can see how things look from his vantage point.").also { stage++ } - 102 -> npc("Be my guest!").also { stage++; player.questRepository.getQuest("All Fired Up").setStage(player,50); setVarbit(player, 5146, BeaconState.DYING.ordinal) } + 102 -> npc("Be my guest!").also { stage++; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,50); setVarbit(player, 5146, BeaconState.DYING.ordinal) } 103 -> options("How do I light the beacon?","I suppose you don't have any logs I could have?","Okay, thanks.").also { stage++ } 104 -> when(buttonId){ 1 -> player("How do I light the beacon?").also { stage = 110 } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt index 8ede2454c..d498fd07a 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt @@ -6,6 +6,7 @@ import core.game.activity.ActivityManager import core.game.node.entity.Entity import core.game.node.entity.player.Player import org.rs09.consts.Items +import content.data.Quests class DSCutsceneTrigger : MapArea { @@ -16,7 +17,7 @@ class DSCutsceneTrigger : MapArea { override fun areaEnter(entity: Entity) { if (entity !is Player) return - val quest = entity.questRepository.getQuest("Demon Slayer") + val quest = entity.questRepository.getQuest(Quests.DEMON_SLAYER) val alreadyInCutscene = getAttribute(entity, "demon-slayer:cutscene", false) val hasSilverlight = inInventory(entity, Items.SILVERLIGHT_2402) || inEquipment(entity, Items.SILVERLIGHT_2402) diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java index b8a37841a..253484745 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java @@ -11,6 +11,7 @@ import core.game.world.update.flag.context.Animation; import core.plugin.Plugin; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** @@ -51,7 +52,7 @@ public final class DSlayerDrainPlugin extends UseWithHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - final Quest quest = player.getQuestRepository().getQuest("Demon Slayer"); + final Quest quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); if (player.getInventory().remove(BUCKET_OF_WATER)) { player.getInventory().add(BUCKET); player.animate(ANIMATION); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java index 2fc51558f..0492bb2a9 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java @@ -12,6 +12,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the demon slayer quest. @@ -50,7 +51,7 @@ public class DemonSlayer extends Quest { * Constructs a new {@Code DemonSlayer} {@Code Object} */ public DemonSlayer() { - super("Demon Slayer", 16, 15, 3, 222, 0, 1, 3); + super(Quests.DEMON_SLAYER, 16, 15, 3, 222, 0, 1, 3); } @Override @@ -196,7 +197,7 @@ public class DemonSlayer extends Quest { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Demon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); switch (quest.getStage(player)) { default: interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What are you doing up here? Only the palace guards", "are allowed up here."); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java index 7a90c6fd0..7c46309f0 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java @@ -30,6 +30,7 @@ import core.net.packet.out.CameraViewPacket; import core.net.packet.out.MinimapState; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents the cutscene during the combat of fighting delrith the demon. @@ -121,7 +122,7 @@ public final class DemonSlayerCutscene extends CutscenePlugin { return true; } final Player player = ((Player) entity); - final Quest quest = player.getQuestRepository().getQuest("Demon Slayer"); + final Quest quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); boolean in = player.getAttribute("demon-slayer:cutscene", false); if (quest.getStage(player) == 30 && !in && (player.getEquipment().containsItem(DemonSlayer.SILVERLIGHT) || player.getInventory().containsItem(DemonSlayer.SILVERLIGHT))) { ActivityManager.start(player, "Demon Slayer Cutscene", false); @@ -422,7 +423,7 @@ public final class DemonSlayerCutscene extends CutscenePlugin { cutscene.end(); cutscene.delrith.clear(); setVarp(player, 222, 5653570, true); - player.getQuestRepository().getQuest("Demon Slayer").finish(player); + player.getQuestRepository().getQuest(Quests.DEMON_SLAYER).finish(player); end(); return true; } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java index 1a051a67b..87740d6df 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java @@ -2,7 +2,6 @@ package content.region.misthalin.varrock.quest.demonslayer; import core.cache.def.impl.NPCDefinition; import core.cache.def.impl.SceneryDefinition; -import core.game.global.action.ClimbActionHandler; import core.game.interaction.OptionHandler; import core.game.node.Node; import core.game.node.entity.npc.NPC; @@ -10,12 +9,11 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.game.node.scenery.Scenery; -import core.game.node.scenery.SceneryBuilder; import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; import core.plugin.Plugin; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** @@ -37,9 +35,6 @@ public final class DemonSlayerPlugin extends OptionHandler { @Override public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(881).getHandlers().put("option:open", this); - SceneryDefinition.forId(882).getHandlers().put("option:close", this); - SceneryDefinition.forId(882).getHandlers().put("option:climb-down", this); SceneryDefinition.forId(DRAIN_ID).getHandlers().put("option:search", this); SceneryDefinition.forId(17429).getHandlers().put("option:take", this); NPCDefinition.forId(DemonSlayerCutscene.DELRITH).getHandlers().put("option:attack", this); @@ -49,7 +44,7 @@ public final class DemonSlayerPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Demon Slayer"); + final Quest quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); final int id = node instanceof Scenery ? ((Scenery) node).getId() : node instanceof Item ? ((Item) node).getId() : ((NPC) node).getId(); switch (id) { case 880: @@ -71,23 +66,6 @@ public final class DemonSlayerPlugin extends OptionHandler { player.sendMessage("You search the castle drain and find nothing of value."); } return true; - case 881: - SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(882)); - break; - case 882: - switch (option) { - case "climb-down": - if (node.getLocation().equals(new Location(3237, 3458, 0))) { - ClimbActionHandler.climb(player, new Animation(828), SEWER_LOCATION); - } else { - ClimbActionHandler.climbLadder(player, (Scenery) node, option); - } - break; - case "close": - SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(881)); - break; - } - break; case 17429: if (quest.getStage(player) == 20 && player.getInventory().add(DemonSlayer.FIRST_KEY)) { setVarp(player, 222, 4757762, true); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java index 3e318c85c..7d0c85262 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java @@ -17,6 +17,7 @@ import core.net.packet.PacketRepository; import core.net.packet.context.CameraContext; import core.net.packet.context.CameraContext.CameraType; import core.net.packet.out.CameraViewPacket; +import content.data.Quests; /** * Represents the dialogue which handles the transcript for the gypsy aris. @@ -75,7 +76,7 @@ public final class GypsyArisDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Demon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); switch (quest.getStage(player)) { case 100: npc("Greetings young one."); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java index a0fc32221..8be176a64 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java @@ -1,6 +1,5 @@ package content.region.misthalin.varrock.quest.demonslayer; -import content.region.misthalin.draynor.handlers.DraynorNodePlugin; import core.api.Container; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; @@ -16,6 +15,7 @@ import org.rs09.consts.Items; import static core.api.ContentAPIKt.*; import static core.tools.DialogueConstKt.END_DIALOGUE; import static core.tools.GlobalsKt.colorize; +import content.data.Quests; /** * Represents the dialogue which handles the Sir Prysin NPC. @@ -64,7 +64,7 @@ public class SirPyrsinDialogue extends DialoguePlugin { } else if (args[0] instanceof Integer) { id = ((int) args[0]); } - quest = player.getQuestRepository().getQuest("Demon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); switch (quest.getStage(player)) { case 30: npc(id, "Have you sorted that demon out yet?"); @@ -481,7 +481,7 @@ public class SirPyrsinDialogue extends DialoguePlugin { private final void handleDefault(int buttonId) { switch (stage) { case 0: - if(getQuestStage(player, "Demon Slayer") == 100) + if(getQuestStage(player, Quests.DEMON_SLAYER) == 100) options("I am a mighty adventurer. Who are you?", "I'm not sure, I was hoping you could tell me.", "Hey can you give me another Silverlight"); else options("I am a mighty adventurer. Who are you?", "I'm not sure, I was hoping you could tell me."); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java index b16a415a2..5ea8e3622 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java @@ -12,6 +12,7 @@ import core.game.system.task.Pulse; import core.game.world.GameWorld; import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; +import content.data.Quests; /** * Represents the dialogue used to handle the Traiborn NPC. @@ -60,7 +61,7 @@ public class TraibornDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Demon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); switch (quest.getStage(player)) { case 20: if (player.getAttribute("demon-slayer:traiborn", false)) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java index 918451e1c..190989d52 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java @@ -10,6 +10,7 @@ import core.net.packet.PacketRepository; import core.net.packet.context.CameraContext; import core.net.packet.context.CameraContext.CameraType; import core.net.packet.out.CameraViewPacket; +import content.data.Quests; /** * Represents the wally cutscene plugin. @@ -54,7 +55,7 @@ public class WallyCutscenePlugin extends CutscenePlugin { @Override public void fade() { - player.getQuestRepository().getQuest("Demon Slayer").start(player); + player.getQuestRepository().getQuest(Quests.DEMON_SLAYER).start(player); player.getDialogueInterpreter().open(882, Repository.findNPC(882), this); } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java index 149fb9609..096bbba01 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java @@ -5,6 +5,9 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +import static core.api.ContentAPIKt.getQuestStage; /** * Represents the cabin boy jenkins dialogue. @@ -12,12 +15,6 @@ import core.game.node.entity.player.link.quest.Quest; */ @Initializable public class CabinBoyJenkins extends DialoguePlugin { - - /** - * Represents the quest instance. - */ - private Quest quest; - /** * Constructs a new {@code CabinBoyJenkins} {@code Object}. */ @@ -43,8 +40,7 @@ public class CabinBoyJenkins extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Dragon Slayer"); - switch (quest.getStage(player)) { + switch (getQuestStage(player, Quests.DRAGON_SLAYER)) { case 20: npc("Ahoy! Whay d'ye think of yer ship then?"); stage = 0; @@ -60,7 +56,7 @@ public class CabinBoyJenkins extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - switch (quest.getStage(player)) { + switch (getQuestStage(player, Quests.DRAGON_SLAYER)) { case 40: case 30: switch (stage) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java index e6c55249d..0501b06f0 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java @@ -6,6 +6,7 @@ import core.game.node.Node; import core.game.node.entity.player.Player; import core.game.world.map.Location; import core.plugin.Plugin; +import content.data.Quests; /** * Represents the dragon slayer magic door plugin. @@ -40,7 +41,7 @@ public final class DSMagicDoorPlugin extends UseWithHandler { @Override public boolean handle(NodeUsageEvent event) { final Player player = event.getPlayer(); - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) < 20) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) < 20) { return true; } if (player.getInventory().remove(event.getUsedItem())) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java index 846fc7f90..4040b3190 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java @@ -3,6 +3,7 @@ package content.region.misthalin.varrock.quest.dragonslayer; import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.player.Player; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the dragon slayer npc. @@ -39,7 +40,7 @@ public final class DSNedNPC extends AbstractNPC { @Override public boolean isHidden(final Player player) { - return player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 30 && player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 40; + return player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 30 && player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 40; } @Override diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt index 8b6bb5ec5..3bb325be9 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt @@ -23,13 +23,14 @@ import core.integrations.discord.Discord import core.plugin.ClassScanner.definePlugins import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests /** * Represents the dragon slayer quest. * @author Vexia - Converted to Kotlin with use of event hooks by not-Vexia */ @Initializable -class DragonSlayer : Quest("Dragon Slayer", 18, 17, 2, 176, 0, 1, 10), LoginListener { +class DragonSlayer : Quest(Quests.DRAGON_SLAYER, 18, 17, 2, 176, 0, 1, 10), LoginListener { override fun newInstance(`object`: Any?): Quest { definePlugins( CrandorMapPlugin(), @@ -323,7 +324,7 @@ class DragonSlayer : Quest("Dragon Slayer", 18, 17, 2, 176, 0, 1, 10), LoginList } override fun login(player: Player) { - if (getQuestStage(player, this.name) == 20) { + if (getQuestStage(player, this.quest) == 20) { player.hook(Event.SpellCast, SpellCastHook) player.hook(Event.PickedUp, PickedUpHook) } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java index 40044126c..b1a4fbc34 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java @@ -28,6 +28,7 @@ import core.net.packet.out.MinimapState; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents the dragon slayer cutscene. @@ -103,7 +104,7 @@ public final class DragonSlayerCutscene extends CutscenePlugin { player.animate(ANIMATION); player.getDialogueInterpreter().close(); player.getDialogueInterpreter().sendDialogue("You are knocked unconscious and later awake on an ash-strewn", "beach."); - player.getQuestRepository().getQuest("Dragon Slayer").setStage(player, 40); + player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).setStage(player, 40); player.getSavedData().getQuestData().setDragonSlayerAttribute("repaired", false); setVarp(player, 177, 8257540); setVarp(player, 176, 8); @@ -292,7 +293,7 @@ public final class DragonSlayerCutscene extends CutscenePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Dragon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); if (args.length > 1) { cutscene = ((DragonSlayerCutscene) args[1]); npc("Ah it's good to feel that salt spray on my face once", "again!"); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java index 85af8e2ed..f16658df0 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java @@ -25,6 +25,7 @@ import core.plugin.Plugin; import java.util.List; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** @@ -101,24 +102,14 @@ public final class DragonSlayerPlugin extends OptionHandler { SceneryDefinition.forId(25161).getHandlers().put("option:climb-over", this); NPCDefinition.forId(742).getHandlers().put("option:attack", this); NPCDefinition.forId(745).getHandlers().put("option:attack", this); - // guild - SceneryDefinition.forId(24357).getHandlers().put("option:climb-up", this); - SceneryDefinition.forId(10558).getHandlers().put("option:open", this); - SceneryDefinition.forId(10560).getHandlers().put("option:climb-up", this); return this; } @Override public boolean handle(final Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Dragon Slayer"); + final Quest quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); final int id = node instanceof Item ? ((Item) node).getId() : node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); switch (id) { - case 10560: - ClimbActionHandler.climb(player, new Animation(828), Location.create(3191, 3355, 0)); - break; - case 10558: - ClimbActionHandler.climb(player, new Animation(-1), Location.create(3189, 9758, 0)); - return true; case 1755: if (player.getLocation().withinDistance(Location.create(2939, 9656, 0))) { ClimbActionHandler.climb(player, new Animation(828), Location.create(2939, 3256, 0)); @@ -127,20 +118,13 @@ public final class DragonSlayerPlugin extends OptionHandler { return true; } break; - case 24357: - if (player.getLocation().getDistance(Location.create(3188, 3358, 0)) < 3) { - ClimbActionHandler.climb(player, new Animation(828), Location.create(3188, 3354, 1)); - } else { - ClimbActionHandler.climbLadder(player, (Scenery) node, "climb-up"); - } - break; case 742: - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for"); player.getPacketDispatch().sendMessage("your reward!"); return true; } - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) > 40) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) > 40) { player.getPacketDispatch().sendMessage("You have already slain Elvarg the dragon."); return true; } @@ -153,16 +137,16 @@ public final class DragonSlayerPlugin extends OptionHandler { movement.run(player, 10); return true; } - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for"); player.getPacketDispatch().sendMessage("your reward!"); return true; } - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) > 40) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) > 40) { player.getPacketDispatch().sendMessage("You have already slain the dragon."); return true; } - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) == 40 && !player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD)) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && !player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD)) { ForceMovement movement = new ForceMovement(player, player.getLocation(), player.getLocation().transform(player.getLocation().getX() == 2845 ? 2 : -2, 0, 0), new Animation(839)); movement.run(player, 10); if (player.getLocation().getX() <= 2845) { @@ -181,7 +165,7 @@ public final class DragonSlayerPlugin extends OptionHandler { player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 2); break; case 2606: - if (player.getLocation().getY() < 9600 && !player.getSavedData().getQuestData().getDragonSlayerAttribute("memorized") && player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 100) { + if (player.getLocation().getY() < 9600 && !player.getSavedData().getQuestData().getDragonSlayerAttribute("memorized") && player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 100) { player.getPacketDispatch().sendMessage("The door is securely locked."); } else { if (!player.getSavedData().getQuestData().getDragonSlayerAttribute("memorized")) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java index 047821ec9..fa25a9fdb 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java @@ -20,12 +20,12 @@ import core.game.world.map.Direction; import core.game.world.map.Location; import core.game.world.map.RegionManager; import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable; import core.tools.RandomFunction; import content.global.handlers.item.equipment.special.DragonfireSwingHandler; import static core.api.ContentAPIKt.calculateDragonfireMaxHit; +import content.data.Quests; /** @@ -154,14 +154,14 @@ public final class ElvargNPC extends AbstractNPC { return super.isAttackable(entity, style, message); } final Player player = (Player) entity; - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { if(message) { player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for"); player.getPacketDispatch().sendMessage("your reward!"); } return false; } - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) > 40) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) > 40) { if(message) { player.getPacketDispatch().sendMessage("You have already slain Elvarg."); } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java index c96f8361a..a94d7ba5e 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java @@ -5,6 +5,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; +import content.data.Quests; /** * Represents the guild master dialogue at the champions guild related to dragon slayer. @@ -46,7 +47,7 @@ public final class GuildmasterDialogue extends DialoguePlugin { if (player.getQuestRepository().getPoints() < 32) { return true; } - quest = player.getQuestRepository().getQuest("Dragon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); npc("Greetings!"); if (quest.getStage(player) == 10) { stage = 0; @@ -225,7 +226,7 @@ public final class GuildmasterDialogue extends DialoguePlugin { stage = 112; break; case 112: - npc("Then, of course, you'll need to find a captain willy to", "sail to Crandor, and I'm not sure where you'd find one", "of them!"); + npc("Then, of course, you'll need to find a captain willing to", "sail to Crandor, and I'm not sure where you'd find one", "of them!"); stage = 113; break; case 113: @@ -286,7 +287,7 @@ public final class GuildmasterDialogue extends DialoguePlugin { handleDescription(buttonId); break; case 2: - player("I talked to Oziach and he have me a quest."); + player("I talked to Oziach and he gave me a quest."); stage = 3; break; } @@ -332,7 +333,7 @@ public final class GuildmasterDialogue extends DialoguePlugin { stage = 14; break; case 14: - npc("Some refuegees managed to escape in fishing boats.", "They landed on the coast, north of Rimmington, and", "set up camp but the dragon followed them and burned", "the camp to the ground."); + npc("Some refugees managed to escape in fishing boats.", "They landed on the coast, north of Rimmington, and", "set up camp but the dragon followed them and burned", "the camp to the ground."); stage = 15; break; case 15: diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt index 5cecdad45..7b59f9c70 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt @@ -1,9 +1,9 @@ package content.region.misthalin.varrock.quest.dragonslayer -import content.region.misthalin.varrock.quest.dragonslayer.DragonSlayer import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests private const val SHIP_DIALOGUE = 2000 class NedDSDialogue(val questStage: Int) : DialogueFile() { @@ -49,7 +49,7 @@ class NedDSDialogue(val questStage: Int) : DialogueFile() { 2006 -> { if (player!!.inventory.remove(DragonSlayer.CRANDOR_MAP)) { interpreter!!.sendItemMessage(DragonSlayer.CRANDOR_MAP.id, "You hand the map to Ned.") - player!!.questRepository.getQuest("Dragon Slayer").setStage(player, 30) + player!!.questRepository.getQuest(Quests.DRAGON_SLAYER).setStage(player, 30) stage++ } else stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt index 46d87047a..dcc331bf6 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt @@ -11,6 +11,7 @@ import content.region.desert.alkharid.quest.princealirescue.NedPARDialogue import content.region.misthalin.lumbridge.diary.NedDiaryDialogue import core.game.world.GameWorld.settings import core.tools.END_DIALOGUE +import content.data.Quests /** @@ -41,8 +42,8 @@ class NedDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(pl override fun handle(interfaceId: Int, buttonId: Int): Boolean { when (stage) { 0 -> { - val dSlayerStage = player.questRepository.getStage("Dragon Slayer") - val parStage = player.questRepository.getStage("Prince Ali Rescue") + val dSlayerStage = player.questRepository.getStage(Quests.DRAGON_SLAYER) + val parStage = player.questRepository.getStage(Quests.PRINCE_ALI_RESCUE) showTopics( IfTopic("I'd like to talk about Dragon Slayer.", NedDSDialogue(dSlayerStage), dSlayerStage == 20 || dSlayerStage == 30), IfTopic("I'd like to talk about Prince Ali Rescue.", NedPARDialogue(parStage), parStage == 20 || parStage == 30 || parStage == 40 || parStage == 50), diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java index c24850f15..faebde0bd 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java @@ -5,6 +5,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; +import content.data.Quests; /** * Represents the dialogue used to handle the oziach dialogue. @@ -43,7 +44,7 @@ public final class OziachDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Dragon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); player.debug("" + quest.getStage(player)); switch (quest.getStage(player)) { case 100: @@ -261,7 +262,7 @@ public final class OziachDialogue extends DialoguePlugin { case 6: end(); int heads = player.getInventory().getAmount(DragonSlayer.ELVARG_HEAD); - if (player.getInventory().remove(new Item(DragonSlayer.ELVARG_HEAD.getId(),heads)) && !player.getQuestRepository().getQuest("Dragon Slayer").isCompleted(player)) { + if (player.getInventory().remove(new Item(DragonSlayer.ELVARG_HEAD.getId(),heads)) && !player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).isCompleted(player)) { quest.finish(player); } break; diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java index 9a69a3bd8..84feb6bfc 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.integrations.discord.Discord; +import content.data.Quests; /** * Represents the dialogue used to handle the wormbrain npc related to the @@ -51,7 +52,7 @@ public final class WormbrainDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Dragon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); switch (quest.getStage(player)) { default: npc("Whut you want?"); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java index 25c81de50..f755bd88f 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java @@ -6,6 +6,7 @@ import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.player.Player; import core.game.node.item.GroundItemManager; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the worm brain npc. @@ -44,7 +45,7 @@ public final class WormbrainNPC extends AbstractNPC { public void finalizeDeath(final Entity killer) { super.finalizeDeath(killer); if (killer instanceof Player) { - if (((Player) killer).getQuestRepository().getQuest("Dragon Slayer").getStage(killer.asPlayer()) == 20 && !((Player) killer).getInventory().containsItem(DragonSlayer.WORMBRAIN_PIECE) && !((Player) killer).getBank().containsItem(DragonSlayer.WORMBRAIN_PIECE)) { + if (((Player) killer).getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(killer.asPlayer()) == 20 && !((Player) killer).getInventory().containsItem(DragonSlayer.WORMBRAIN_PIECE) && !((Player) killer).getBank().containsItem(DragonSlayer.WORMBRAIN_PIECE)) { GroundItemManager.create(DragonSlayer.WORMBRAIN_PIECE, getLocation(), ((Player) killer)); ((Player) killer).getPacketDispatch().sendMessage("Wormbrain drops a map piece on the floor."); } @@ -55,7 +56,7 @@ public final class WormbrainNPC extends AbstractNPC { public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { if (entity instanceof Player) { final Player player = (Player) entity; - if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 20) { + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 20) { if(message) { player.getPacketDispatch().sendMessage("The goblin is already in prison. You have no reason to attack him."); } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java index 679922780..65a602673 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java @@ -8,6 +8,9 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.game.world.map.Location; import core.tools.RandomFunction; +import content.data.Quests; + +import static core.api.ContentAPIKt.getQuestStage; /** * Represents a zombie rat npc related to dragon slayer and witch's potion. @@ -52,12 +55,10 @@ public final class ZombieRatNPC extends AbstractNPC { super.finalizeDeath(killer); if (killer instanceof Player) { final Player p = ((Player) killer); - Quest quest = p.getQuestRepository().getQuest("Dragon Slayer"); if (RandomFunction.random(0, 4) == 2) { - GroundItemManager.create(DragonSlayer.RED_KEY, getLocation(), ((Player) killer)); + GroundItemManager.create(DragonSlayer.RED_KEY, getLocation(), p); } - quest = p.getQuestRepository().getQuest("Witch's Potion"); - if (quest.getStage(p) > 0 && quest.getStage(p) < 100) { + if (getQuestStage(p, Quests.WITCHS_POTION) > 0 && getQuestStage(p, Quests.WITCHS_POTION) < 100) { GroundItemManager.create(RAT_TAIL, getLocation(), p); } GroundItemManager.create(new Item(526), getLocation(), p); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt index 6b8c402a8..1961c4586 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable class AvanDialogue (player: Player? = null): DialoguePlugin(player) { @@ -19,7 +20,7 @@ class AvanDialogue (player: Player? = null): DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player?.questRepository?.getStage("Family Crest") ?: -1 + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 if (qstage == 100) { options("Can you change my gauntlets for me?", "Nevermind") @@ -101,7 +102,7 @@ class AvanDialogue (player: Player? = null): DialoguePlugin(player) { 15 -> player("Well, I'll see what I can do.").also{ stage = 1000 - player.questRepository.getQuest("Family Crest").setStage(player, 14) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 14) } 100 -> player("I'm still after that 'perfect gold'.").also { stage++ } @@ -128,7 +129,7 @@ class AvanDialogue (player: Player? = null): DialoguePlugin(player) { "with a red precious stone, and a perfect gold ring to match.").also { stage = 1000 } 300 -> sendDialogue("You hand Avan the perfect gold ring and necklace.").also{ - player.questRepository.getQuest("Family Crest").setStage(player, 16) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 16) player.inventory.remove(Item(774), Item(773)) player.inventory.add(CREST_PIECE_AVAN) stage++ diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt index 8a29de6e1..89dd53a2f 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt @@ -5,6 +5,7 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable +import content.data.Quests @Initializable @@ -15,7 +16,7 @@ class BootDialogue (player: Player? = null): DialoguePlugin(player){ override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player?.questRepository?.getStage("Family Crest") ?: -1 + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 if(qstage < 14 || qstage > 14){ npc(FacialExpression.OLD_NORMAL,"Hello tall person.") @@ -61,7 +62,7 @@ class BootDialogue (player: Player? = null): DialoguePlugin(player){ 21 -> npc("I don't believe it's exactly easy to get to though...").also { stage = 1000 - player.questRepository.getQuest("Family Crest").setStage(player, 15) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 15) } 1000 -> end() } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt index e25e5e60c..618bf40ec 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable @@ -20,7 +21,7 @@ class CalebDialogue (player: Player? = null): DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player?.questRepository?.getStage("Family Crest") ?: -1 + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 if (qstage == 100) { options("Can you change my gauntlets for me?", "Nevermind") @@ -122,7 +123,7 @@ class CalebDialogue (player: Player? = null): DialoguePlugin(player) { 207 -> when(buttonId){ 1 -> npc("You will? It would help me a lot!").also{stage = 1000}.also{ - player.questRepository.getQuest("Family Crest").setStage(player, 11) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 11) } 2 -> npc("It's a valuable family heirloom. " , @@ -141,7 +142,7 @@ class CalebDialogue (player: Player? = null): DialoguePlugin(player) { 301 -> sendDialogue("You exchange the fish for Caleb's piece of the crest.").also{stage++}.also{ player.inventory.remove(Item(315),Item(329), Item(361), Item(365), Item(373)) player.inventory.add(CREST_PIECE) - player.questRepository.getQuest("Family Crest").setStage(player, 12) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 12) } 302 -> options("Uh... what happened to the rest of it?" , "Thank you very much!").also{stage++} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt index fc2655329..1ca3002f0 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt @@ -1,4 +1,4 @@ -package plugin.quest.members.familycrest +package content.region.misthalin.varrock.quest.familycrest import core.game.node.entity.Entity @@ -10,10 +10,11 @@ import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBuilder import core.plugin.Initializable import core.plugin.Plugin -import content.region.misthalin.varrock.quest.familycrest.ChronozonNPC -import core.game.node.item.Item +import core.api.getQuestStage +import core.api.hasAnItem import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests @Initializable @@ -23,7 +24,7 @@ class ChronozonCaveZone: MapZone("FC ChronozoneZone", true), Plugin { var chronozon = ChronozonNPC(NPCs.CHRONOZON_667, spawnLoc) override fun configure() { - register(ZoneBorders(3082, 9929, 3091, 9940)) + register(ZoneBorders(3079, 9927, 3095, 9944)) } override fun move(e: Entity?, from: Location?, to: Location?): Boolean { @@ -34,8 +35,9 @@ class ChronozonCaveZone: MapZone("FC ChronozoneZone", true), Plugin { if (e != null) { if (e.isPlayer) { val player = e as Player - if (player.questRepository.getQuest("Family Crest").getStage(e) in (19..99) && - !player.hasItem(Item(Items.CREST_PART_781))){ + if (getQuestStage(player,Quests.FAMILY_CREST) in (19..99) && + !hasAnItem(player, Items.CREST_PART_781).exists() + ){ // Chronozon is allowed to spawn (quest stage right and the player doesn't have the crest part) // Now check there is not one already if(!RegionManager.getLocalNpcs(spawnLoc, 5).contains(chronozon)){ @@ -50,6 +52,18 @@ class ChronozonCaveZone: MapZone("FC ChronozoneZone", true), Plugin { } return false } + + + override fun leave(e: Entity?, logout: Boolean): Boolean { + if (e!!.isPlayer){ + if (RegionManager.getLocalPlayers(spawnLoc, 5).size <= 0){ + // There are no other players close by + chronozon.clear() + } + } + return super.leave(e, logout) + } + override fun newInstance(arg: Unit?): Plugin { ZoneBuilder.configure(this) return this diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt index 6bdbc0d27..954e5b02e 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt @@ -7,6 +7,7 @@ import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.player.Player import core.game.world.map.Location import org.rs09.consts.NPCs +import content.data.Quests class ChronozonNPC(id: Int, location: Location?) : AbstractNPC(NPCs.CHRONOZON_667, Location(3086, 9936, 0)){ @@ -29,14 +30,6 @@ class ChronozonNPC(id: Int, location: Location?) : AbstractNPC(NPCs.CHRONOZON_66 return intArrayOf(NPCs.CHRONOZON_667) } - override fun handleTickActions() { - super.handleTickActions() - if (!targetplayer.isActive || targetplayer.getLocation().getDistance(getLocation()) > 15) { - clear() - } - - } - override fun checkImpact(state: BattleState?) { if (state != null) { if(amountOfAirDamageTaken == 0 || amountOfWaterDamageTaken == 0 || @@ -80,8 +73,10 @@ class ChronozonNPC(id: Int, location: Location?) : AbstractNPC(NPCs.CHRONOZON_66 override fun finalizeDeath(killer: Entity?) { if(killer == targetplayer) { - if (targetplayer.questRepository.getStage("Family Crest") != 20){ - targetplayer.questRepository.getQuest("Family Crest").setStage(targetplayer, 20) + if (targetplayer.questRepository.getStage(Quests.FAMILY_CREST) != 20){ + targetplayer.questRepository.getQuest(Quests.FAMILY_CREST).setStage(targetplayer, 20) + // Make sure to despawn Chronozon + this.clear() } } clear() diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt index 746f1ebfd..fc857c7e6 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt @@ -6,6 +6,8 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests +import core.game.node.entity.player.link.diary.DiaryType @Initializable @@ -18,19 +20,17 @@ class DimintheisDialogue(player: Player? = null): core.game.dialogue.DialoguePlu return DimintheisDialogue(player) } - private val questName = "Family Crest" - override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val questStage = getQuestStage(player, questName) - val questComplete = isQuestComplete(player, questName) + val questStage = getQuestStage(player, Quests.FAMILY_CREST) + val questComplete = isQuestComplete(player, Quests.FAMILY_CREST) if (questStage == 20 && inInventory(player, Items.FAMILY_CREST_782)) { player("I have retrieved your crest.").also{ stage = 5000 } return true } - val hasGauntlets = hasAnItem(player, Items.COOKING_GAUNTLETS_775, Items.GOLDSMITH_GAUNTLETS_776, Items.CHAOS_GAUNTLETS_777, Items.FAMILY_GAUNTLETS_778).container != null + val hasGauntlets = hasAnItem(player, arrayOf(Items.COOKING_GAUNTLETS_775, Items.GOLDSMITH_GAUNTLETS_776, Items.CHAOS_GAUNTLETS_777, Items.FAMILY_GAUNTLETS_778), true).container != null if (questComplete && hasGauntlets) { npc("Thank you for saving our family honour, ", @@ -134,7 +134,7 @@ class DimintheisDialogue(player: Player? = null): core.game.dialogue.DialoguePlu 1 -> npc("I thank you greatly adventurer!").also { stage++ } 2 -> npc("I realise it was a lot to ask of a stranger.").also { stage = 1000 } } - 2012 -> if(startQuest(player, questName)) { + 2012 -> if(startQuest(player, Quests.FAMILY_CREST)) { npc("If you find Caleb, or my other sons... please... ", "let them know their father still loves them...").also { stage = 1000 } } else { @@ -167,13 +167,14 @@ class DimintheisDialogue(player: Player? = null): core.game.dialogue.DialoguePlu "they should be able to imbue them with a skill for you.").also { stage = 1000 if (removeItem(player, Items.FAMILY_CREST_782)) { - finishQuest(player, questName) + finishQuest(player, Quests.FAMILY_CREST) } } 6000 -> npc("Not to worry, here they are").also { stage = 1000 addItem(player, getAttribute(player, "family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778)) + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 9) } 1000 -> end() diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt index 0303ba3f8..2b8f1aef9 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt @@ -10,7 +10,7 @@ import core.game.node.entity.skill.Skills import core.plugin.Initializable import core.tools.Log import org.rs09.consts.Items -import core.tools.SystemLogger +import content.data.Quests /** * Represents the "Family Crest" quest. @@ -18,7 +18,7 @@ import core.tools.SystemLogger */ @Initializable -class FamilyCrest: Quest("Family Crest", 59, 58, 1, 148, 0, 1, 11) { +class FamilyCrest: Quest(Quests.FAMILY_CREST, 59, 58, 1, 148, 0, 1, 11) { override fun newInstance(`object`: Any?): Quest { return this @@ -124,10 +124,4 @@ class FamilyCrest: Quest("Family Crest", 59, 58, 1, 148, 0, 1, 11) { } setAttribute(player, "/save:family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778) } - - /*override fun getConfig(player: Player?, stage: Int): IntArray { - if(stage == 100) return intArrayOf(1282, 90) - if(stage > 0) return intArrayOf(1282, 1) - else return intArrayOf(1282, 0) - }*/ } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt index 2ed748bab..9c12e517a 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt @@ -6,6 +6,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.data.Quests class JohnathonAntiPosionInteraction: InteractionListener { override fun defineListeners() { @@ -14,14 +15,14 @@ class JohnathonAntiPosionInteraction: InteractionListener { onUseWith(IntType.NPC, poisons, NPCs.JOHNATHON_668){ player, used, with -> val npc = with.asNpc() val antip = used.asItem() - val stage = getQuestStage(player, "Family Crest") + val stage = getQuestStage(player, Quests.FAMILY_CREST) val index = poisons.indexOf(used.id) val returnItem = if(index + 1 == poisons.size) Items.VIAL_229 else poisons[index + 1] if(stage == 17 && removeItem(player, antip)){ addItem(player, returnItem) - setQuestStage(player, "Family Crest", 18) + setQuestStage(player, Quests.FAMILY_CREST, 18) openDialogue(player, NPCs.JOHNATHON_668, npc) } else { sendMessage(player, "Nothing interesting happens.") diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt index 8942d0ab8..c0e6d6f35 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable class JohnathonDialogue(player: Player? = null): DialoguePlugin(player) { @@ -18,7 +19,7 @@ class JohnathonDialogue(player: Player? = null): DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = (args[0] as NPC).getShownNPC(player) - val qstage = player?.questRepository?.getStage("Family Crest") ?: -1 + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 if (qstage == 100) { options("Can you change my gauntlets for me?", "Nevermind") @@ -53,7 +54,7 @@ class JohnathonDialogue(player: Player? = null): DialoguePlugin(player) { "too much... My head... " , "will not... stop spinning...").also { stage++ } 4 -> sendDialogue("Sweat is pouring down Jonathons' face.").also { stage = 1000 - player.questRepository.getQuest("Family Crest").setStage(player, 17) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 17) } 100 -> npc("Ooooh... thank you... Wow! " , @@ -68,7 +69,7 @@ class JohnathonDialogue(player: Player? = null): DialoguePlugin(player) { "I lost a lot of equipment in our last battle when he " , "bested me and forced me away from his den. He probably still has it now.").also{ stage = 200 - player.questRepository.getQuest("Family Crest").setStage(player, 19) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 19) } 200 -> options("So is this Chronozon hard to defeat?", "Where can I find Chronozon?", "So how did you end up getting poisoned?", "I will be on my way now.").also{stage++} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt index d0b7f8541..af534f4d8 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt @@ -11,6 +11,7 @@ import core.net.packet.out.ConstructScenery import core.net.packet.out.UpdateAreaPosition import core.game.interaction.InteractionListener import core.game.interaction.IntType +import content.data.Quests fun doDoor(player: Player, scenery: Scenery) { val d = if(scenery.rotation == 0 || scenery.rotation == 3) { -1 } else { 0 } @@ -50,7 +51,7 @@ class WitchavenLeverInteraction : InteractionListener { override fun defineListeners() { on(LEVERS, IntType.SCENERY, "pull") { player, node -> val baseId = if(node.id % 2 == 0) { node.id - 1 } else { node.id } - if(player.questRepository.getQuest("Family Crest").getStage(player) == 0) { + if(player.questRepository.getQuest(Quests.FAMILY_CREST).getStage(player) == 0) { player.sendMessage("Nothing interesting happens.") } val old = player.getAttribute("family-crest:witchaven-lever:${baseId}", false) @@ -80,7 +81,7 @@ class WitchavenLeverInteraction : InteractionListener { val northA = player.getAttribute("family-crest:witchaven-lever:${NORTH_LEVER_A}", false) val northB = player.getAttribute("family-crest:witchaven-lever:${NORTH_LEVER_B}", false) val south = player.getAttribute("family-crest:witchaven-lever:${SOUTH_LEVER}", false) - val questComplete = player.questRepository.getQuest("Family Crest").getStage(player) >= 100 + val questComplete = player.questRepository.getQuest(Quests.FAMILY_CREST).getStage(player) >= 100 // Authentic door formulae from https://gitlab.com/open-runescape-classic/core/-/blob/develop/server/plugins/com/openrsc/server/plugins/authentic/quests/members/FamilyCrest.java#L575-657 val canPass = when(node.id) { NORTH_DOOR -> !northA && (south || northB) diff --git a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java index 7fa4028e2..fd90e43a0 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java @@ -4,6 +4,7 @@ import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the plugin used for the fluff npc. @@ -41,7 +42,7 @@ public final class FluffNPC extends AbstractNPC { @Override public boolean isHidden(final Player player) { - if (player.getQuestRepository().getQuest("Gertrude's Cat").getStage(player) < 20) { + if (player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT).getStage(player) < 20) { return true; } return player.getAttribute("hidefluff", 0L) > System.currentTimeMillis(); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java index 3abadbd9c..c4eb02518 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java @@ -8,6 +8,9 @@ import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.tools.RandomFunction; +import static core.api.ContentAPIKt.addItemOrBank; +import content.data.Quests; + /** * Represents the gertrudes fortress quest. * @author 'Vexia @@ -19,7 +22,7 @@ public class GertrudesCat extends Quest { * Constructs a new {@code GertrudesCat} {@code Object}. */ public GertrudesCat() { - super("Gertrude's Cat", 67, 66, 1, 180, 0, 1, 100); + super(Quests.GERTRUDES_CAT, 67, 66, 1, 180, 0, 1, 100); } @Override @@ -79,12 +82,12 @@ public class GertrudesCat extends Quest { player.getPacketDispatch().sendString("1525 Cooking XP", 277, 10 + 2); player.getPacketDispatch().sendString("A chocolate cake", 277, 11 + 2); player.getPacketDispatch().sendString("A bowl of stew", 277, 12 + 2); - player.getPacketDispatch().sendString("Raise cats.", 277, 13 + 2); + player.getPacketDispatch().sendString("The ability to raise cats", 277, 13 + 2); player.getSkills().addExperience(Skills.COOKING, 1525); player.getPacketDispatch().sendItemZoomOnInterface(kitten.getId(), 240, 277, 3 + 2); setStage(player, 100); if (player.getFamiliarManager().hasFamiliar()) { - player.getInventory().add(kitten); + addItemOrBank(player, kitten.getId(), 1); } else { player.getFamiliarManager().summon(kitten, true, false); } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java index 9b1714bd4..51ab6f1b5 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java @@ -7,6 +7,7 @@ import core.game.world.GameWorld; import core.game.world.map.Location; import core.plugin.Initializable; import core.tools.RandomFunction; +import content.data.Quests; /** * Represents the lumber kittens at the lumber yard. @@ -77,7 +78,7 @@ public final class LumberKittenNPC extends AbstractNPC { @Override public boolean isHidden(final Player player) { - Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat"); + Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); if (hidden) { return true; } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java index b8d37f6d0..7d6b190e4 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java @@ -15,6 +15,7 @@ import core.game.world.map.path.Path; import core.game.world.map.path.Pathfinder; import core.game.world.repository.Repository; import core.game.world.update.flag.context.Animation; +import content.data.Quests; /** * Represents the dialogue of the juliet NPC. @@ -67,7 +68,7 @@ public final class JulietDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest("Romeo & Juliet"); + quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); npc = (NPC) args[0]; if (args.length > 1) { cutscene = (JulietCutscenePlugin) args[1]; @@ -123,7 +124,7 @@ public final class JulietDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Romeo & Juliet"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); final NPC phil = cutscene != null ? cutscene.getPhillipia() : (NPC) Repository.findNPC(3325); final NPC dad = cutscene != null ? cutscene.getNPCS().get(2) : (NPC) Repository.findNPC(3324); switch (stage) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java index 549692660..d87164ef7 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java @@ -4,6 +4,7 @@ import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the juliet npc. @@ -41,7 +42,7 @@ public final class JulietNPC extends AbstractNPC { @Override public boolean isHidden(final Player player) { - return player.getQuestRepository().getQuest("Romeo & Juliet").getStage(player) > 60 && player.getQuestRepository().getQuest("Romeo & Juliet").getStage(player) < 100; + return player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) > 60 && player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) < 100; } @Override diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java index ecb1d1d4d..17a33f20b 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java @@ -21,6 +21,7 @@ import core.net.packet.context.CameraContext; import core.net.packet.context.CameraContext.CameraType; import core.plugin.Initializable; import core.net.packet.out.CameraViewPacket; +import content.data.Quests; /** * Represents the romeo and juliet cutscene plugin. @@ -93,7 +94,7 @@ public final class RJCutscenePlugin extends CutscenePlugin { @Override public void fade() { - player.getQuestRepository().getQuest("Romeo & Juliet").finish(player); + player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).finish(player); } @Override @@ -169,7 +170,7 @@ public final class RJCutscenePlugin extends CutscenePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - Quest quest = player.getQuestRepository().getQuest("Romeo & Juliet"); + Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); switch (stage) { case 0: interpreter.sendOptions("Select an Option", "No sorry. I haven't seen her.", "Perhaps I could help to find her for you?"); @@ -771,7 +772,7 @@ public final class RJCutscenePlugin extends CutscenePlugin { @Override public boolean open(Object... args) { - Quest quest = player.getQuestRepository().getQuest("Romeo & Juliet"); + Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); npc = (NPC) args[0]; if (args.length > 1) { cutscene = (RJCutscenePlugin) args[1]; diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java index 744214e26..2e5945316 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java @@ -3,6 +3,7 @@ package content.region.misthalin.varrock.quest.romeo; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the romeo and juliet quest. @@ -15,7 +16,7 @@ public class RomeoJuliet extends Quest { * Constructs a new {@code RomeoJuliet} {@code Object}. */ public RomeoJuliet() { - super("Romeo & Juliet", 26, 25, 5, 144, 0, 1, 100); + super(Quests.ROMEO_JULIET, 26, 25, 5, 144, 0, 1, 100); } @Override @@ -29,7 +30,8 @@ public class RomeoJuliet extends Quest { case 10: line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); line(player, "feels. For some reason he can't just do this himself.", 5+ 7); - line(player, BLUE + "All I need to do now is find " + RED + "Juliet.", 6+ 7); + // https://www.youtube.com/watch?v=ush_RVY4tvw + line(player, BLUE + "I should go and speak to " + RED + "Juliet" + BLUE + ", wherever she is?", 7+ 7); break; case 20: line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); @@ -113,6 +115,7 @@ public class RomeoJuliet extends Quest { line(player, BLUE + "I have to find " + RED + "Romeo" + BLUE + " and tell him what's happened.", 18+ 7); break; case 100: + // https://www.youtube.com/watch?v=m4bZ4GmHxRs line(player, "Romeo and Juliet can be together in peace.", 4+ 7); line(player, "I went to the Apothecary regarding making this cadava", 5+ 7); line(player, "potion, and he told me to bring him some cadava berries.", 6+ 7); @@ -121,14 +124,14 @@ public class RomeoJuliet extends Quest { line(player, "I told Romeo what was going to happen, but I'm not exactly", 9+ 7); line(player, "sure he understood what was happening. Ah well, I was", 10+ 7); line(player, "rewarded for all of my help regardless.", 11+ 7); - line(player, "QUEST COMPLETE!", 12+ 7); + line(player, "QUEST COMPLETE!", 13+ 7); break; } } @Override public void finish(Player player) { - if(player.getQuestRepository().getQuest("Romeo & Juliet").isCompleted(player)){ + if(player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).isCompleted(player)){ return; } super.finish(player); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java index e520a3ce9..0034cddca 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java @@ -55,7 +55,7 @@ public class RomeoNPC extends AbstractNPC { /*if (speakDelay < GameWorld.getTicks()) { speakDelay = GameWorld.getTicks() + 30; for (Player p : RegionManager.getLocalPlayers(this, 2)) { - if (!p.getInterfaceManager().isOpened() && RandomFunction.random(0, 8) == 2 && p.getQuestRepository().getQuest("Romeo & Juliet").getStage(p) == 0) { + if (!p.getInterfaceManager().isOpened() && RandomFunction.random(0, 8) == 2 && p.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(p) == 0) { if (p.getDialogueInterpreter().getDialogue() != null || p.getDialogueInterpreter().getDialogueStage() != null) { continue; } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt index 5b6d6ba3f..3ba076b35 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt @@ -6,6 +6,7 @@ import core.game.node.item.Item import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests /** * @author qmqz @@ -13,8 +14,6 @@ import org.rs09.consts.NPCs @Initializable class CharlieTheTrampDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ - var q = "Shield of Arrav" - override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC npc(core.game.dialogue.FacialExpression.FRIENDLY,"Spare some change guv?").also { stage = 0 } @@ -70,11 +69,11 @@ class CharlieTheTrampDialogue(player: Player? = null) : core.game.dialogue.Dialo 282 -> npc(core.game.dialogue.FacialExpression.AFRAID, "But don't upset her, she's pretty dangerous.").also { stage++ } 283 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "I also heard that Reldo the librarian knows more about them, go talk to him.").also { stage++ } 284 -> { - if (!player.questRepository.hasStarted(q)) { - player.questRepository.getQuest(q).start(player) - player.questRepository.getQuest(q).setStage(player,50) + if (!player.questRepository.hasStarted(Quests.SHIELD_OF_ARRAV)) { + player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).start(player) + player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).setStage(player,50) } else if (!ShieldofArrav.isBlackArm(player) && !ShieldofArrav.isPhoenix(player)) { - player.questRepository.getQuest(q).setStage(player, 50) + player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).setStage(player, 50) } end() } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt index aa24c2ca2..67422ee21 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt @@ -1,7 +1,6 @@ package content.region.misthalin.varrock.quest.shieldofarrav import content.region.desert.quest.thegolem.CuratorHaigHalenGolemDialogue -import content.region.misthalin.digsite.quest.thedigsite.TheDigSite import core.api.* import core.game.dialogue.* import core.game.node.entity.player.Player @@ -10,6 +9,7 @@ import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests class CuratorHaigHalenDialogue (player: Player? = null) : DialoguePlugin(player) { override fun handle(interfaceId: Int, buttonId: Int): Boolean { @@ -18,7 +18,7 @@ class CuratorHaigHalenDialogue (player: Player? = null) : DialoguePlugin(player) if (player.getQuestRepository().points >= 50 && !player.achievementDiaryManager.hasCompletedTask(DiaryType.VARROCK, 0, 12)) { player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 0, 12) } - if (getQuestStage(player, TheDigSite.questName) == 1 && inInventory(player, Items.UNSTAMPED_LETTER_682) ) { + if (getQuestStage(player, Quests.THE_DIG_SITE) == 1 && inInventory(player, Items.UNSTAMPED_LETTER_682) ) { stage = 11 // Couldn't do a dialogueFile for digsite as it needs to resume the topic after. } stage++ @@ -26,11 +26,12 @@ class CuratorHaigHalenDialogue (player: Player? = null) : DialoguePlugin(player) 1 -> showTopics( Topic(FacialExpression.FRIENDLY, "Have you any interesting news?", 2), Topic(FacialExpression.FRIENDLY, "Do you know where I could find any treasure?", 8), - IfTopic(FacialExpression.FRIENDLY, "I've lost the letter of recommendation.", 18, getQuestStage(player, TheDigSite.questName) == 2 && !inInventory(player, Items.SEALED_LETTER_683)), + IfTopic(FacialExpression.FRIENDLY, "I've lost the letter of recommendation.", 18, + getQuestStage(player, Quests.THE_DIG_SITE) == 2 && !inInventory(player, Items.SEALED_LETTER_683)), IfTopic("I have the Shield of Arrav", CuratorHaigHalenSOADialogue(), - getQuestStage(player, "Shield of Arrav") == 70, false), + getQuestStage(player, Quests.SHIELD_OF_ARRAV) == 70, false), IfTopic("I'm looking for a statuette recovered from the city of Uzer.", CuratorHaigHalenGolemDialogue(), - getQuestStage(player, "The Golem") == 3, false) + getQuestStage(player, Quests.THE_GOLEM) == 3, false) ) 2 -> npcl(FacialExpression.FRIENDLY, "Yes, we found a rather interesting island to the north of Morytania. We believe that it may be of archaeological significance.").also { stage++ } 3 -> playerl(FacialExpression.FRIENDLY, "Oh? That sounds interesting.").also { stage++ } @@ -61,8 +62,8 @@ class CuratorHaigHalenDialogue (player: Player? = null) : DialoguePlugin(player) stage++ } 16 -> playerl(FacialExpression.FRIENDLY, "Ok, I will. Thanks, see you later.").also { - if(getQuestStage(player, TheDigSite.questName) == 1) { - setQuestStage(player, TheDigSite.questName, 2) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 1) { + setQuestStage(player, Quests.THE_DIG_SITE, 2) } stage = 1 } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java index 9208ad74b..f5be4a4b0 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.game.world.map.Location; +import content.data.Quests; /** * Represents the npc to handle Johnny the beard npc. @@ -43,10 +44,12 @@ public final class JohnnyBeardNPC extends AbstractNPC { @Override public void finalizeDeath(final Entity killer) { super.finalizeDeath(killer); - final Player p = ((Player) killer); - final Quest quest = p.getQuestRepository().getQuest("Shield of Arrav"); - if (quest.getStage(p) == 60 && ShieldofArrav.isPhoenixMission(p) && !p.getInventory().containsItem(ShieldofArrav.INTEL_REPORT) && !p.getBank().containsItem(ShieldofArrav.INTEL_REPORT)) { - GroundItemManager.create(ShieldofArrav.INTEL_REPORT, getLocation(), p); + if (killer instanceof Player) { + final Player p = ((Player) killer); + final Quest quest = p.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + if (quest.getStage(p) == 60 && ShieldofArrav.isPhoenixMission(p) && !p.getInventory().containsItem(ShieldofArrav.INTEL_REPORT) && !p.getBank().containsItem(ShieldofArrav.INTEL_REPORT)) { + GroundItemManager.create(ShieldofArrav.INTEL_REPORT, getLocation(), p); + } } } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java index 101f9366a..53f90edcd 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java @@ -1,10 +1,14 @@ package content.region.misthalin.varrock.quest.shieldofarrav; +import content.region.asgarnia.burthorpe.quest.heroesquest.KatrineDialogueFile; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; +import content.data.Quests; + +import static core.api.ContentAPIKt.openDialogue; /** * Represents the katrine NPC dialogue. @@ -48,11 +52,19 @@ public final class KatrineDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Shield of Arrav"); + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); switch (quest.getStage(player)) { - case 80: - case 90: case 100: + if (ShieldofArrav.isBlackArm(player)) { + Quest heroesQuest = player.getQuestRepository().getQuest(Quests.HEROES_QUEST); + if (0 < heroesQuest.getStage(player) && heroesQuest.getStage(player) < 100) { + openDialogue(player, new KatrineDialogueFile(), npc); + break; + } + } + // Continues below if not during the Heroes' Quest + case 90: + case 80: case 70: if (ShieldofArrav.isPhoenix(player)) { npc("You've got some guts coming here, Phoenix guy!"); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt index 9135bd1d5..26238d76d 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt @@ -1,11 +1,11 @@ package content.region.misthalin.varrock.quest.shieldofarrav -import content.region.misthalin.varrock.quest.shieldofarrav.ShieldofArrav import core.game.node.item.GroundItemManager import core.game.node.item.Item import core.game.dialogue.DialogueFile import core.tools.END_DIALOGUE import core.tools.START_DIALOGUE +import content.data.Quests private val CERTIFICATE = Item(769) @@ -46,7 +46,7 @@ class KingRoaldArravDialogue() : DialogueFile() { if (!player!!.inventory.add(Item(995, 600))) { GroundItemManager.create(Item(995, 600), player) } - player!!.questRepository.getQuest("Shield of Arrav").finish(player) + player!!.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).finish(player) stage = END_DIALOGUE } } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java index 8d2859688..91bee2817 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.link.diary.AchievementDiary; import core.game.node.entity.player.link.diary.DiaryType; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; +import content.data.Quests; /** * Represents the dialogue to handle reldo. @@ -55,14 +56,14 @@ public class ReldoDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - knightSword = player.getQuestRepository().getQuest("The Knight's Sword"); - shieldArrav = player.getQuestRepository().getQuest("Shield of Arrav"); + knightSword = player.getQuestRepository().getQuest(Quests.THE_KNIGHTS_SWORD); + shieldArrav = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); if (args.length == 2 && ((String) args[1]).equals("book")) { player("Aha! 'The Shield of Arrav'! Exactly what I was looking", "for."); stage = 3; return true; } - if(player.getQuestRepository().getQuest("Lost Tribe").getStage(player) == 40 && player.getInventory().contains(Items.BROOCH_5008,1)){ + if(player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 40 && player.getInventory().contains(Items.BROOCH_5008,1)){ options("Hello stranger.","I have a question about my Achievement Diary.","Ask about the brooch."); } else { options("Hello stranger.", "I have a question about my Achievement Diary."); @@ -237,7 +238,7 @@ public class ReldoDialogue extends DialoguePlugin { break; case 2005: npc("The other day I filed a book about ancient goblin tribes.","It's somewhere on the west end of the library, I think.","Maybe that will be of some use."); - player.getQuestRepository().getQuest("Lost Tribe").setStage(player,42); + player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).setStage(player,42); stage++; break; case 2006: diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java index 2b51df2cf..80a581a22 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java @@ -23,6 +23,7 @@ import core.game.global.action.PickupHandler; import core.game.world.repository.Repository; import java.util.List; +import content.data.Quests; /** * Represents the shield of arrav plugin. @@ -59,7 +60,7 @@ public final class ShieldArravPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Shield of Arrav"); + final Quest quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); final int id = node instanceof Scenery ? ((Scenery) node).getId() : node instanceof Item ? ((Item) node).getId() : ((NPC) node).getId(); switch (id) { case 769: diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java index ee91ad5d6..4b427035d 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java @@ -6,6 +6,7 @@ import core.game.node.item.Item; import core.plugin.Initializable; import content.region.misthalin.varrock.dialogue.KingRoaldDialogue; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the shield of arrav quest. @@ -54,7 +55,7 @@ public class ShieldofArrav extends Quest { * Constructs a new {@Code ShieldofArrav} {@Code Object} */ public ShieldofArrav() { - super("Shield of Arrav", 29, 28, 1, 145, 0, 1, 7); + super(Quests.SHIELD_OF_ARRAV, 29, 28, 1, 145, 0, 1, 7); } @Override @@ -225,6 +226,22 @@ public class ShieldofArrav extends Quest { player.setAttribute("/save:black-arm-gang", true); } + /** + * Swaps the gang. + * @param player the player. + */ + public static void swapGang(final Player player) { + if(isPhoenix(player)) { + player.setAttribute("/save:black-arm-gang", true); + player.setAttribute("/save:phoenix-gang", false); + } else if(isBlackArm(player)) { + player.setAttribute("/save:black-arm-gang", false); + player.setAttribute("/save:phoenix-gang", true); + } else { + player.setAttribute("/save:phoenix-gang", true); + } + } + /** * Method used to check if the player is part of the phoenix gang. * @param player the player. diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt index faebb66c3..867aa08d3 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt @@ -4,11 +4,14 @@ import content.global.handlers.iface.BookInterface import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page import content.global.handlers.iface.PageSet -import core.api.setAttribute import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.entity.player.Player import org.rs09.consts.Items +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage +import core.api.storeBookInHouse /** * Shield of Arrav Book @@ -18,7 +21,7 @@ import org.rs09.consts.Items */ class ShieldofArravBook : InteractionListener { companion object { - private val TITLE = "Shield of Arrav" + private val TITLE = "The Shield of Arrav" private val CONTENTS = arrayOf( PageSet( Page( @@ -86,8 +89,8 @@ class ShieldofArravBook : InteractionListener { private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) if (BookInterface.isLastPage(pageNum, CONTENTS.size)) { - if (player.questRepository.getQuest("Shield of Arrav").getStage(player) == 10) { - player.questRepository.getQuest("Shield of Arrav").setStage(player, 20) + if (getQuestStage(player, Quests.SHIELD_OF_ARRAV) == 10) { + setQuestStage(player, Quests.SHIELD_OF_ARRAV, 20) } } return true @@ -95,8 +98,9 @@ class ShieldofArravBook : InteractionListener { } override fun defineListeners() { - on(Items.BOOK_757, IntType.ITEM, "read") { player, _ -> + on(Items.BOOK_757, IntType.ITEM, "read") { player, node -> BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + storeBookInHouse(player, node) return@on true } } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java index 6b26f29c9..f12d9cef4 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java @@ -5,6 +5,10 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; +import content.data.Quests; +import content.region.asgarnia.burthorpe.quest.heroesquest.StravenDialogueFile; + +import static core.api.ContentAPIKt.openDialogue; /** * Represents the dialogue which handles the straven NPC. @@ -43,9 +47,17 @@ public class StravenDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Shield of Arrav"); + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); switch (quest.getStage(player)) { case 100: + if (ShieldofArrav.isPhoenix(player)) { + Quest heroesQuest = player.getQuestRepository().getQuest(Quests.HEROES_QUEST); + if (0 < heroesQuest.getStage(player) && heroesQuest.getStage(player) < 100) { + openDialogue(player, new StravenDialogueFile(), npc); + break; + } + } + // Continues below if not during the Heroes' Quest case 70: if (ShieldofArrav.isPhoenix(player)) { npc("Greetings fellow gang member."); @@ -321,7 +333,7 @@ public class StravenDialogue extends DialoguePlugin { stage = 47; break; case 47: - npc("Although having said that, a rival gang of ours, er,", "theirs, called the Black Arm Gang is supposedly metting", "a contact from Port Sarim today in the Blue Moon", "Inn."); + npc("Although having said that, a rival gang of ours, er,", "theirs, called the Black Arm Gang is supposedly meeting", "a contact from Port Sarim today in the Blue Moon", "Inn."); stage = 48; break; case 48: diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java index c521eb492..e0f0f5fc6 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java @@ -4,6 +4,7 @@ import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; /** * Represents the dialogue which handles the weapons master. @@ -42,7 +43,7 @@ public final class WeaponsMasterDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Shield of Arrav"); + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); switch (quest.getStage(player)) { default: if (args.length > 1) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java index 6e68c8dca..645995cdb 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.varrock.quest.whatliesbelow; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; @@ -40,7 +41,7 @@ public class AnnaJonesDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - quest = player.getQuestRepository().getQuest(WhatLiesBelow.NAME); + quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); switch (quest.getStage(player)) { default: if (args.length >= 2) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java index e4c9bdc19..9649f5fa3 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java @@ -1,5 +1,6 @@ package content.region.misthalin.varrock.quest.whatliesbelow; +import content.data.Quests; import core.game.node.entity.Entity; import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.player.Player; @@ -39,7 +40,7 @@ public class OutlawNPC extends AbstractNPC { super.finalizeDeath(killer); if (killer instanceof Player) { Player p = killer.asPlayer(); - Quest quest = p.getQuestRepository().getQuest(WhatLiesBelow.NAME); + Quest quest = p.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); if (quest.getStage(p) == 10) { int amount = p.getInventory().getAmount(WhatLiesBelow.RATS_PAPER) + p.getBank().getAmount(WhatLiesBelow.RATS_PAPER); if (amount < 5) { diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java index 11b84906c..0a8e97bc6 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.varrock.quest.whatliesbelow; +import content.data.Quests; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; @@ -52,7 +53,7 @@ public class RatBurgissDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(WhatLiesBelow.NAME); + quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); options("Hello there!", "I have a question about my Achievement Diary."); stage = -1; return true; diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java index 1f4cf375f..838900d75 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java @@ -1,5 +1,6 @@ package content.region.misthalin.varrock.quest.whatliesbelow; +import content.data.Quests; import core.game.activity.ActivityManager; import core.game.dialogue.DialoguePlugin; import core.game.node.entity.npc.NPC; @@ -50,7 +51,7 @@ public class SurokMagisDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(WhatLiesBelow.NAME); + quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); switch (quest.getStage(player)) { default: npc("Excuse me?"); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java index 718d90602..d1c154c5d 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java @@ -297,6 +297,7 @@ public class WLBelowCutscene extends CutscenePlugin { @Override public void configure() { region = DynamicRegion.create(12854); + region.setMusicId(250); setRegionBase(); registerRegion(region.getId()); } diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java index 7f3b85182..09c27bcd9 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java @@ -1,5 +1,6 @@ package content.region.misthalin.varrock.quest.whatliesbelow; +import content.data.Quests; import core.cache.def.impl.SceneryDefinition; import core.game.component.Component; import core.game.node.entity.player.link.diary.DiaryType; @@ -56,7 +57,7 @@ public class WLBelowPlugin extends OptionHandler { @Override public boolean handle(final Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest(WhatLiesBelow.NAME); + final Quest quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); switch (option) { case "summon": case "operate": diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java index b31d5b058..0b0238179 100644 --- a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java @@ -9,6 +9,7 @@ import core.game.node.item.Item; import core.plugin.ClassScanner; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * The what lies below quest. @@ -17,12 +18,6 @@ import static core.api.ContentAPIKt.*; */ @Initializable public class WhatLiesBelow extends Quest { - - /** - * The name of the quest. - */ - public static final String NAME = "What Lies Below"; - /** * The bowl item. */ @@ -78,16 +73,6 @@ public class WhatLiesBelow extends Quest { */ public static final Item BEACON_RING = new Item(Items.BEACON_RING_11014); - /** - * The requirement messages. - */ - private static final String[] REQS = new String[] { - "Have level 35 Runecrafting.", - "Be able to defeat a level 47 enemy.", - "I need to have completed the Rune Mysteries quest.", - "Have a Mining level of 42 to use the Chaos Tunnel." - }; - /** * The requirements. */ @@ -97,7 +82,7 @@ public class WhatLiesBelow extends Quest { * Constructs a new {@Code WhatLiesBelow} {@Code Object} */ public WhatLiesBelow() { - super(NAME, 136, 135, 1); + super(Quests.WHAT_LIES_BELOW, 136, 135, 1); } @Override @@ -109,36 +94,81 @@ public class WhatLiesBelow extends Quest { @Override public void drawJournal(Player player, int stage) { super.drawJournal(player, stage); - switch (stage) { - case 0: - line(player, "I can start this quest by speaking to Rat Burgiss on theroad south of Varrock.Before I begin I will need to:" + getReqMessage(player), 11); - break; - case 10: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.I need to kill outlaws west of Varrock so that I can collect 5 of Rat's papers.", 11); - break; - case 20: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.I need to kill outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magisin Varrock.", 11); - break; - case 30: - case 40: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.Surok, a Wizard in Varrock, has asked me to complete a task for him.I need to kill the outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magis in Varrock. I need to talk to Surok about thesecret he has for me.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also needto find or buy an empty bowl.", 11); - break; - case 50: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.Surok, a Wizard in Varrock, has asked me to complete a task for him.I need to kill the outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magis in Varrock. I need to talk to Surok about thesecret he has for me.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to take the glowing wand I have created back to Surok in Varrockwith an empty bowl.I need to deliver Surok's letter to Rat who is waiting for me southof Varrock. I should speak to Rat again; he is waiting for me south of Varrock", 11); - break; - case 60: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.Surok, a Wizard in Varrock, has asked me to complete a task for him.I need to kill the outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magis in Varrock. I need to talk to Surok about thesecret he has for me.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to take the glowing wand I have created back to Surok in Varrockwith an empty bowl.I need to deliver Surok's letter to Rat who is waiting for me southof Varrock.I should speak to Rat again; he is waiting for me south of VarrockI need to speak to Zaff of Zaff's Staffs in Varrock.", 11); - break; - case 70: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.Surok, a Wizard in Varrock, has asked me to complete a task for him.I need to kill the outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magis in Varrock. I need to talk to Surok about thesecret he has for me.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to take the glowing wand I have created back to Surok in Varrockwith an empty bowl.I need to deliver Surok's letter to Rat who is waiting for me southof Varrock.I should speak to Rat again; he is waiting for me south of VarrockI need to speak to Zaff of Zaff's Staffs in Varrock.I need to tell Surok in Varrock that he is under arrest.", 11); - break; - case 80: - case 90: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.Surok, a Wizard in Varrock, has asked me to complete a task for him.I need to kill the outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magis in Varrock. I need to talk to Surok about thesecret he has for me.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to take the glowing wand I have created back to Surok in Varrockwith an empty bowl.I need to deliver Surok's letter to Rat who is waiting for me southof Varrock.I should speak to Rat again; he is waiting for me south of VarrockI need to speak to Zaff of Zaff's Staffs in Varrock.I need to tell Surok in Varrock that he is under arrest.I need to defeat King Roald in Varrock so that Zaff can remove themind-control spell.I need to tell Rat what has happened; he is waiting for mesouth of Varrock.", 11); - break; - case 100: - line(player, "Rat, a trader in Varrock, has asked me to help him with a task.Surok, a Wizard in Varrock, has asked me to complete a task for him.I need to kill the outlaws west of Varrock so that I can collect5 of Rat's papers.I have delivered Rat's folder to him. Perhaps Ishould speak to him again.I need to deliver Rat's letter to Surok Magis in Varrock. I need to talk to Surok about thesecret he has for me.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to infuse the metal wand with chaos runes at the Chaos Altar.I also need to find or buy an empty bowl.I need to take the glowing wand I have created back to Surok in Varrockwith an empty bowl.I need to deliver Surok's letter to Rat who is waiting for me southof Varrock.I should speak to Rat again; he is waiting for me south of VarrockI need to speak to Zaff of Zaff's Staffs in Varrock.I need to tell Surok in Varrock that he is under arrest.I need to defeat King Roald in Varrock so that Zaff can remove themind-control spell.I need to tell Rat what has happened; he is waiting for mesouth of Varrock.QUEST COMPLETE!I have been given information about the Chaos Tunnel.Zaff has given me the Beacon Ring.", 11); - break; + var line = 12; + + if(stage == 0){ + line(player, "I can start this quest by speaking to !!Rat Burgiss?? on the", line++); + line(player, "road south of !!Varrock??.", line++); + line(player, "Before I begin I will need to:", line++); + line(player, "Have level 35 !!Runecrafting??.", line++, getStatLevel(player, Skills.RUNECRAFTING) >= 35); + line(player, "Be able to defeat a !!level 47 enemy??.", line++); + line(player, "I need to have completed the !!Rune Mysteries?? quest.", line++, isQuestComplete(player, Quests.RUNE_MYSTERIES)); + line(player, "Have a !!Mining?? level of 42 to use the !!Chaos Tunnel??.", line++, getStatLevel(player, Skills.MINING) >= 42); + } else { + // These are somehow at the top with different stage when crossed out. + if (stage >= 10) { + line(player, "!!Rat??, a trader in Varrock, has asked me to help him with a", line++, stage >= 30); + line(player, "task.", line++, stage >= 30); + } + if (stage >= 30) { + line(player, "!!Surok??, a Wizard in Varrock, has asked me to complete a", line++, stage >= 50); + line(player, "task for him.", line++, stage >= 50); + } + // End + + if (stage >= 10) { + line(player, "I need to kill !!outlaws?? west of Varrock so that I can collect 5", line++, stage >= 20); + line(player, "of Rat's !!papers??.", line++, stage >= 20); + if (inInventory(player, Items.FULL_FOLDER_11007, 1)) { + line(player, "I should take the !!full folder?? back to Rat.", line++); + } + } + if (stage >= 20) { + line(player, "I have delivered Rat's folder to him. Perhaps I should", line++, stage >= 30); + line(player, "should speak to him again.", line++, stage >= 30); + // Should be separated stages + line(player, "I need to deliver !!Rat's?? letter to !!Surok Magis?? in !!Varrock??.", line++, stage >= 30); + // Should be separated stages + line(player, "I need to talk to !!Surok?? about the secret he has for me.", line++, stage >= 30); + } + if (stage >= 30) { + line(player, "I need to infuse the !!metal wand?? with !!chaos runes?? at the", line++, stage >= 50); + line(player, "!!Chaos Altar??. I also need to find or buy an empty !!bowl??.", line++, stage >= 50); + } + if (stage >= 50) { + line(player, "I need to take the !!glowing wand?? I have created back to", line++, true); + line(player, "!!Surok?? in Varrock along with an empty !!bowl??.", line++, true); + // Should be separated stages + line(player, "I need to deliver !!Surok's letter?? to !!Rat?? who is waiting for me", line++, true); + line(player, "south of Varrock.", line++, true); + // Should be separated stages + line(player, "I should speak to !!Rat?? again; he is waiting for me south of", line++, stage >= 60); + line(player, "Varrock.", line++, stage >= 60); + } + if (stage >= 60) { + line(player, "I need to speak to !!Zaff?? of !!Zaff's Staffs?? in Varrock.", line++, stage >= 70); + } + if (stage >= 70) { + line(player, "I need to tell !!Surok?? in Varrock that he is under arrest.", line++, stage >= 80); + } + if (stage >= 80) { + line(player, "I need to defeat !!King Roald?? in Varrock so that !!Zaff?? can", line++, true); + line(player, "remove the mind-control spell.", line++, true); + // Should be separated stages + line(player, "I need to tell !!Rat?? what has happened; he is waiting for me", line++, stage >= 100); + line(player, "south of Varrock.", line++, stage >= 100); + } + if (stage >= 100) { + line++; + line++; + line(player,"QUEST COMPLETE!", line++); + line++; + line(player, "I have been given information about the !!Chaos Tunnel??.", line++); + line(player, "Zaff has given me the !!Beacon Ring??.", line++); + line++; + line(player, "I have also been given !!8,000 Runecrafting XP, 2000??.", line++); + line(player, "!!Defence XP?? and !!1 Quest Point??.", line++); + } } } @@ -161,29 +191,13 @@ public class WhatLiesBelow extends Quest { player.getQuestRepository().syncronizeTab(player); } - /** - * Gets the req message. - * @return the message. - */ - public String getReqMessage(Player player) { - hasRequirements(player); - String s = ""; - for (int i = 0; i < requirements.length; i++) { - String l = REQS[i]; - if (requirements[i]) { - l = l.replace("", "").replace("", "").trim(); - } - s += (requirements[i] ? "" : "") + l + ""; - } - return s; - } @Override public boolean hasRequirements(Player player) { requirements[0] = player.getSkills().getStaticLevel(Skills.RUNECRAFTING) >= 35; requirements[1] = false; requirements[3] = player.getSkills().getStaticLevel(Skills.MINING) >= 42; - requirements[2] = player.getQuestRepository().isComplete("Rune Mysteries"); + requirements[2] = player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES); return requirements[0] && requirements[2] && requirements[3]; } @@ -198,7 +212,7 @@ public class WhatLiesBelow extends Quest { } else if (stage > 0 && stage < 100) { return new int[] { id, 1 }; } - setVarp(player, 1181, (1 << 8) + (1 << 9), true); + setVarp(player, 1181, (1 << 8) + (1 << 9), true); return new int[] { id, 502 }; } diff --git a/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java b/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java index 37c40a125..4f4200c9e 100644 --- a/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java +++ b/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java @@ -14,6 +14,7 @@ import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; import content.region.misthalin.varrock.quest.demonslayer.DemonSlayer; +import content.data.Quests; /** * Represents the dialogue used to handle the Traiborn NPC. @@ -68,7 +69,7 @@ public class TraibornDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest("Demon Slayer"); + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); switch (quest.getStage(player)) { case 20: if (player.getAttribute("demon-slayer:traiborn", false)) { diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/TalismanMapInterface.kt b/Server/src/main/content/region/misthalin/wiztower/handlers/TalismanMapInterface.kt new file mode 100644 index 000000000..b97893d88 --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/TalismanMapInterface.kt @@ -0,0 +1,21 @@ +package content.region.misthalin.wiztower.handlers + +import core.api.* +import core.game.interaction.InteractionListener +import org.rs09.consts.Scenery +import org.rs09.consts.Components + +// http://youtu.be/T62dugdfzSQ +/** Map for talismans in Wizard Tower basement. I display everything, because let's be real, you can find this online... */ +class TalismanMapInterface : InteractionListener { + override fun defineListeners() { + on(intArrayOf(Scenery.MAP_38421, Scenery.MAP_38422), SCENERY, "study") { player, node -> + openInterface(player, Components.RCGUILD_MAP_780) + // Air talisman to Death talisman + for(i in 35..48) { + setComponentVisibility(player, Components.RCGUILD_MAP_780, i, false) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java b/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java index 2cf368836..01b970fd8 100644 --- a/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java @@ -10,7 +10,6 @@ import core.game.global.action.ClimbActionHandler; import core.game.global.action.DoorActionHandler; import core.game.interaction.OptionHandler; import core.game.node.Node; -import core.game.node.entity.Entity; import core.game.node.entity.combat.spell.CombatSpell; import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.npc.AbstractNPC; @@ -39,6 +38,7 @@ import kotlin.Unit; import content.global.travel.EssenceTeleport; import core.game.world.GameWorld; import core.plugin.ClassScanner; +import content.data.Quests; /** * Represents the plugins used related to the wizard tower. @@ -81,7 +81,7 @@ public final class WizardTowerPlugin extends OptionHandler { public boolean handle(Player player, Node node, String option) { switch (option) { case "teleport": - if (!player.getQuestRepository().isComplete("Rune Mysteries")) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { player.getPacketDispatch().sendMessage("You need to have completed the Rune Mysteries Quest to use this feature."); return true; } @@ -311,7 +311,7 @@ public final class WizardTowerPlugin extends OptionHandler { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - Quest quest = player.getQuestRepository().getQuest("Imp Catcher"); + Quest quest = player.getQuestRepository().getQuest(Quests.IMP_CATCHER); switch (quest.getStage(player)) { case 0: player("Give me a quest!"); @@ -331,7 +331,7 @@ public final class WizardTowerPlugin extends OptionHandler { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Imp Catcher"); + final Quest quest = player.getQuestRepository().getQuest(Quests.IMP_CATCHER); switch (quest.getStage(player)) { case 0: switch (stage) { @@ -1041,7 +1041,7 @@ public final class WizardTowerPlugin extends OptionHandler { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Rune Mysteries"); + final Quest quest = player.getQuestRepository().getQuest(Quests.RUNE_MYSTERIES); switch (stage) { case 0: if (quest.getStage(player) == 100) { @@ -1542,7 +1542,7 @@ public final class WizardTowerPlugin extends OptionHandler { @Override public boolean open(Object... args) { npc = (NPC) args[0]; - final Quest quest = player.getQuestRepository().getQuest("Rune Mysteries"); + final Quest quest = player.getQuestRepository().getQuest(Quests.RUNE_MYSTERIES); if (quest.getStage(player) == 40) { npc("My gratitude to you adventurer for bringing me these", "research notes. I notice that you brought the head", "wizard a special talisman that was the key to our finally", "unlocking the puzzle."); stage = 900; @@ -1559,7 +1559,7 @@ public final class WizardTowerPlugin extends OptionHandler { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Rune Mysteries"); + final Quest quest = player.getQuestRepository().getQuest(Quests.RUNE_MYSTERIES); switch (stage) { case 0: if (quest.getStage(player) == 30) { @@ -1577,7 +1577,7 @@ public final class WizardTowerPlugin extends OptionHandler { stage = 950; return true; } - if (!player.getQuestRepository().isComplete("Rune Mysteries")) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { options("Yes please!", "Oh, it's a rune shop. No thank you, then."); stage = 100; } else { diff --git a/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java b/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java index a24c4d6d6..d077a59f1 100644 --- a/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java +++ b/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java @@ -10,6 +10,7 @@ import core.game.node.scenery.SceneryBuilder; import core.game.world.map.Location; import core.plugin.Initializable; import core.game.world.map.RegionManager; +import content.data.Quests; /** * Represents the imp catcher quest. @@ -48,7 +49,7 @@ public class ImpCatcher extends Quest { * Constructs a new {@Code ImpCatcher} {@Code Object} */ public ImpCatcher() { - super("Imp Catcher", 21, 20, 1, 160, 0, 1, 2); + super(Quests.IMP_CATCHER, 21, 20, 1, 160, 0, 1, 2); } @Override diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/BrosDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/BrosDialogue.java deleted file mode 100644 index 416cdc7f6..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/BrosDialogue.java +++ /dev/null @@ -1,61 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used for the bros np.c - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class BrosDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code BrosDialogue} {@code Object}. - */ - public BrosDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code BrosDialogue} {@code Object}. - * @param player the player. - */ - public BrosDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new BrosDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Out of my way, punk"); - stage = 1; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 1: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6026, 6032 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/GregoryDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/GregoryDialogue.java deleted file mode 100644 index 20dd7f484..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/GregoryDialogue.java +++ /dev/null @@ -1,61 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used for the gregory npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class GregoryDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code GregoryDialogue} {@code Object}. - */ - public GregoryDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code GregoryDialogue} {@code Object}. - * @param player the player. - */ - public GregoryDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new GregoryDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If I were as ugly as you I would not dare to show my", "face in public!"); - stage = 1; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 1: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6033, 6027, 6043, 6036, 6040, 6038, 6045 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/HumanWerewolfDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/HumanWerewolfDialogue.kt new file mode 100644 index 000000000..9763d0ae3 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/HumanWerewolfDialogue.kt @@ -0,0 +1,66 @@ +package content.region.morytania.canifis.dialogue + +import core.api.anyInEquipment +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +@Initializable +class HumanWerewolfDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage){ + START_DIALOGUE -> { + // There are 10 random different messages for all of the werewolves in human form + // If you have the Ring of Charos they think you're a werewolf and talk differently + if (anyInEquipment(player, Items.RING_OF_CHAROS_4202, Items.RING_OF_CHAROSA_6465)){ + // Nice talks + when ((1..10).random()){ + 1 -> npcl(FacialExpression.HAPPY, "I bet you have wonderful paws.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.NEUTRAL, "A very miserable day, altogether... enjoy it while it lasts.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.ASKING, "If you catch anyone promise me you'll share.").also { stage = END_DIALOGUE } + 4 -> npcl(FacialExpression.ASKING, "I haven't smelt you around here before...").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.FRIENDLY, "You smell familiar...").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.ASKING, "Seen any humans around here? I'm v-e-r-y hungry.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.FRIENDLY, "You look to me like someone with a healthy taste for blood.").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.FRIENDLY, "Good day to you, my friend.").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.ASKING, "Fancy going up to the castle for a bit of a snack?").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.NEUTRAL, "Give me a moment, I have a bit of someone stuck in my teeth...").also { stage = END_DIALOGUE } + } + } + else { + // Mean talks + when ((1..10).random()){ + 1 -> npcl(FacialExpression.ANNOYED, "If I were as ugly as you I would not dare to show my face in public!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.ANGRY, "Out of my way, punk.").also { stage = END_DIALOGUE } + // The only one that has a path + 3 -> npcl(FacialExpression.ASKING, "Hmm... you smell strange...").also { stage++ } + 4 -> npcl(FacialExpression.ANGRY, "Leave me alone.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.ANNOYED, "Don't talk to me again if you value your life!").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.ANNOYED, "Get lost!").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.ANNOYED, "I don't have anything to give you so leave me alone, mendicant.").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.ANGRY, "Have you no manners?").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.ANNOYED, "I don't have time for this right now.").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.ANGRY, "I have no interest in talking to a pathetic meat bag like yourself.").also{ stage = END_DIALOGUE} + } + } + } + // There's one path that the player can respond to (3 without the ring) + 1 -> playerl(FacialExpression.ASKING, "Strange how?").also { stage++ } + 2 -> npcl(FacialExpression.EVIL_LAUGH, "Like a human!").also { stage++ } + 3 -> playerl(FacialExpression.PANICKED, "Oh! Er... I just ate one is why!").also { stage = END_DIALOGUE } + else -> { + end() + } + } + return true + } + + override fun getIds(): IntArray { + return (6026..6046).toIntArray() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/IrinaDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/IrinaDialogue.java deleted file mode 100644 index 730f38a6e..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/IrinaDialogue.java +++ /dev/null @@ -1,61 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used for the irina npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class IrinaDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code IrinaDialogue} {@code Object}. - */ - public IrinaDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code IrinaDialogue} {@code Object}. - * @param player the player. - */ - public IrinaDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new IrinaDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Out of my way, punk."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6035 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/JosephDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/JosephDialogue.java deleted file mode 100644 index 95b68dc2c..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/JosephDialogue.java +++ /dev/null @@ -1,61 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue plugin used for the joseph npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class JosephDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code JosephDialogue} {@code Object}. - */ - public JosephDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code JosephDialogue} {@code Object}. - * @param player the player. - */ - public JosephDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new JosephDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I have no interest in talking to a pathetic meat bag like", "yourself."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6029 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/MalakDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/MalakDialogue.java deleted file mode 100644 index b4e1d290f..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/MalakDialogue.java +++ /dev/null @@ -1,57 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue used for malak. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public class MalakDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code MalakDialogue} {@code Object}. - */ - public MalakDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code MalakDialogue} {@code Object}. - * @param player the player. - */ - public MalakDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new MalakDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Away from me, dog.", "I have business to discuss with the barkeeper."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - end(); - return true; - } - - @Override - public int[] getIds() { - return new int[] { 1920 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/NikitiaDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/NikitiaDialogue.java deleted file mode 100644 index 404f49f74..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/NikitiaDialogue.java +++ /dev/null @@ -1,48 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the NikitiaDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class NikitiaDialogue extends DialoguePlugin { - - public NikitiaDialogue() { - - } - - public NikitiaDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new NikitiaDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Don't talk to me again if you value your life!"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - end(); - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6042 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt index 97b81b311..41b7314a2 100644 --- a/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt +++ b/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt @@ -10,10 +10,9 @@ import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.item.Item import core.plugin.Initializable -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs +import content.data.Quests /** * Roavar dialogue. @@ -37,8 +36,8 @@ class RoavarDialogue (player: Player? = null) : DialoguePlugin(player) { 1 -> showTopics( Topic(FacialExpression.HALF_GUILTY, "Can I buy a beer?", 10, false), - Topic(FacialExpression.HALF_GUILTY, "Can I hear some gossip", 20, false), - IfTopic(FacialExpression.HALF_GUILTY, "Can I buy something to eat?", RoavarDialogueFile(1), player.getQuestRepository().getQuest("Creature of Fenkenstrain").getStage(player) == 2, false), + Topic(FacialExpression.HALF_GUILTY, "Can I hear some gossip?", 20, false), + IfTopic(FacialExpression.HALF_GUILTY, "Can I buy something to eat?", RoavarDialogueFile(1), player.getQuestRepository().getQuest(Quests.CREATURE_OF_FENKENSTRAIN).getStage(player) == 2, false), Topic(FacialExpression.HALF_GUILTY, "Nothing thanks.", 40, false) ) @@ -82,7 +81,7 @@ class RoavarDialogue (player: Player? = null) : DialoguePlugin(player) { } 21 -> end() - 30 -> stage = if (inInventory(player, 2963, 1)) { + 30 -> stage = if (inInventory(player, Items.SILVER_SICKLEB_2963, 1)) { npc(FacialExpression.HALF_GUILTY, "I don't have a spare lying around, sorry friend.", "Hopefully you'll find something else that can protect you", "against ghasts!") 31 } else { @@ -102,7 +101,7 @@ class RoavarDialogue (player: Player? = null) : DialoguePlugin(player) { npc(FacialExpression.HALF_GUILTY, "Oh, nevermind. It seems your backpack is full.") } else { sendDialogue(player, "The bartender hands you a silver sickle.") - addItem(player, 2963) + addItemOrDrop(player, Items.SILVER_SICKLEB_2963) } stage = 31 } diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.java deleted file mode 100644 index f053085ca..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.java +++ /dev/null @@ -1,103 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.plugin.Initializable; -import content.global.skill.crafting.TanningProduct; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Handles the SbottDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class SbottDialogue extends DialoguePlugin { - - public SbottDialogue() { - - } - - public SbottDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new SbottDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello stranger. Would you like to me to tan any hides for", "you?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - // interpreter.sendDialogues(npc, FacialExpression.NORMAL, - // "Soft leather - 2 gp per hide","Hard leather - 5 gp per hide","Snakeskins - 25 gp per hide","Dragon leather - 45 gp per hide."); - interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Soft leather - 1 gp per hide", "Hard leather - 3 gp per hide", "Snakeskins - 20 gp per hide", "Dragon leather - 20 gp per hide."); - stage = 1; - break; - case 1: - player.getInventory().refresh(); - Item items[] = player.getInventory().toArray(); - for (int i = 0; i < items.length; i++) { - if (items[i] == null) { - continue; - } - if (TanningProduct.forItemId(items[i].getId()) != null) { - interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "I see you have brought me some hides.", "Would you like me to tan them for you?"); - stage = 100; - return true; - } - } - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I haven't any hides."); - stage = 2; - break; - case 2: - end(); - break; - case 100: - interpreter.sendOptions("Select an Option", "Yes please.", "No thanks."); - stage = 101; - break; - case 101: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please."); - stage = 210; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thanks."); - stage = 200; - break; - } - break; - case 210: - end(); - TanningProduct.open(player, 2824); - break; - case 200: - interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Very well, sir, as you wish."); - stage = 201; - break; - case 201: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 1041 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.kt new file mode 100644 index 000000000..b315f4b01 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.kt @@ -0,0 +1,67 @@ +package content.region.morytania.canifis.dialogue + +import content.global.skill.crafting.TanningProduct +import core.api.inInventory +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles Sbott's dialogue. + */ +@Initializable +class SbottDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Hello stranger. Would you like to me to tan any hides for you?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + //0 -> npc(FacialExpression.HAPPY, "Soft leather - 2 gp per hide", "Hard leather - 5 gp per hide", "Snakeskins - 25 gp per hide", "Dragon leather - 45 gp per hide.").also { stage++ } + 0 -> npc(FacialExpression.HAPPY, "Soft leather - 1 gp per hide", "Hard leather - 3 gp per hide", "Snakeskins - 20 gp per hide", "Dragon leather - 20 gp per hide.").also { stage++ } + 1 -> { + var hasHides = false + + for (tanningProduct in TanningProduct.values()) { + if (inInventory(player, tanningProduct.item)) { + hasHides = true + break + } + } + + if(hasHides) { + npcl(FacialExpression.FRIENDLY, "I see you have brought me some hides. Would you like me to tan them for you?").also { stage = 10 } + } else { + playerl(FacialExpression.HALF_GUILTY, "No thanks, I haven't any hides.").also { stage = END_DIALOGUE } + } + } + + 10 -> options("Yes please.", "No thanks.").also { stage++ } + + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes please.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No thanks.").also { stage = 13 } + } + + 12 -> end().also { TanningProduct.open(player, NPCs.SBOTT_1041) } + 13 -> npcl(FacialExpression.FRIENDLY, "Very well, @g[sir,madam], as you wish.").also { stage = END_DIALOGUE } + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SbottDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SBOTT_1041) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/SofiyaDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/SofiyaDialogue.java deleted file mode 100644 index 7735eab73..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/SofiyaDialogue.java +++ /dev/null @@ -1,52 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the SofiyaDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class SofiyaDialogue extends DialoguePlugin { - - public SofiyaDialogue() { - - } - - public SofiyaDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new SofiyaDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Out of my way punk."); - stage = 1; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 1: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6039, 6030, 6037 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/SvetlanaDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/SvetlanaDialogue.java deleted file mode 100644 index 0d72329fe..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/SvetlanaDialogue.java +++ /dev/null @@ -1,48 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the SvetlanaDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class SvetlanaDialogue extends DialoguePlugin { - - public SvetlanaDialogue() { - - } - - public SvetlanaDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new SvetlanaDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm... you smell strange..."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - end(); - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6034 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.java deleted file mode 100644 index eedae1210..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.java +++ /dev/null @@ -1,76 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Handles the TaxidermistDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class TaxidermistDialogue extends DialoguePlugin { - - public TaxidermistDialogue() { - - } - - public TaxidermistDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new TaxidermistDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, hello. Have you got something you want", "preserving?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - interpreter.sendOptions("Select an Option", "Yes please", "Not right now"); - stage = 1; - break; - case 1: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes please."); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Not right now."); - stage = 20; - break; - - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Give it to me to look at then."); - stage = 11; - break; - case 11: - end(); - break; - case 20: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 4246 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.kt new file mode 100644 index 000000000..abaefb1d0 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.kt @@ -0,0 +1,43 @@ +package content.region.morytania.canifis.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +open class TaxidermistDialogue(player: Player? = null) : DialoguePlugin(player) { + companion object{ + const val YES = 10 + const val NO = 20 + const val WHAT = 30 + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.HAPPY, "Oh, hello. Have you got something you want preserving?").also { stage++ } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE + 1 -> showTopics( + Topic("Yes please.", YES), + Topic("Not right now.", NO), + Topic("What?", WHAT) + ) + + YES -> npcl(FacialExpression.HAPPY, "Give it to me to look at then.").also { stage = END_DIALOGUE } + NO -> npcl(FacialExpression.ANNOYED, "Well, you go kill things so I can stuff them, eh?").also { stage = END_DIALOGUE } + WHAT -> npcl(FacialExpression.NEUTRAL, " If you bring me a monster head or a very big fish, I can preserve it for you so you can mount it in your house.").also { stage++ } + WHAT + 1 -> npcl(FacialExpression.HAPPY, "I hear there are all sorts of exotic creatures in the Slayer Tower -- I'd like a chance to stuff one of them!").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TAXIDERMIST_4246) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/YadvigaDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/YadvigaDialogue.java deleted file mode 100644 index a78bbdbc6..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/YadvigaDialogue.java +++ /dev/null @@ -1,61 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the yadviga dialogue plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class YadvigaDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code YadvigaDialogue} {@code Object}. - */ - public YadvigaDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code YadvigaDialogue} {@code Object}. - * @param player the player. - */ - public YadvigaDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new YadvigaDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Get lost!"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6041 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/YuriDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/YuriDialogue.java deleted file mode 100644 index 0920c953d..000000000 --- a/Server/src/main/content/region/morytania/canifis/dialogue/YuriDialogue.java +++ /dev/null @@ -1,57 +0,0 @@ -package content.region.morytania.canifis.dialogue; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; - -/** - * Represents the dialogue used for the yuri npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class YuriDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code YuriDialogue} {@code Object}. - */ - public YuriDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code YuriDialogue} {@code Object}. - * @param player the player. - */ - public YuriDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new YuriDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm... you smell strange..."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - end(); - return true; - } - - @Override - public int[] getIds() { - return new int[] { 6028 }; - } -} diff --git a/Server/src/main/content/region/morytania/canifis/handlers/CanafisWereWolfPlugin.java b/Server/src/main/content/region/morytania/canifis/handlers/CanafisWereWolfPlugin.java deleted file mode 100644 index 76ad461e0..000000000 --- a/Server/src/main/content/region/morytania/canifis/handlers/CanafisWereWolfPlugin.java +++ /dev/null @@ -1,66 +0,0 @@ -package content.region.morytania.canifis.handlers; - -import core.cache.def.impl.NPCDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to handle the attacking of a werwolf. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class CanafisWereWolfPlugin extends OptionHandler { - - /** - * Represents the animation to use. - */ - private static final Animation ANIMATION = new Animation(6543); - - /** - * Represents the id to transform into. - */ - private static final int TRANSFORM_ID = 6006; - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int i = 6026; i < 6046; i++) { - NPCDefinition.forId(i).getHandlers().put("option:attack", this); - } - return this; - } - - @Override - public boolean handle(final Player player, Node node, String option) { - if (!player.getEquipment().contains(2952, 1)) { - player.lock(2); - final NPC n = (NPC) node; - final NPC newN = NPC.create(TRANSFORM_ID, n.getLocation()); - newN.init(); - newN.animate(ANIMATION); - n.clear(); - newN.lock(2); - newN.setRespawn(false); - newN.setAttribute("original", n.getId()); - newN.setAttribute("loc", n.getProperties().getSpawnLocation()); - GameWorld.getPulser().submit(new Pulse(2) { - @Override - public boolean pulse() { - newN.getProperties().getCombatPulse().attack(player); - return true; - } - }); - } else { - player.getProperties().getCombatPulse().attack(node); - } - return true; - } - -} diff --git a/Server/src/main/content/region/morytania/canifis/handlers/CanafisWerewolfNPC.kt b/Server/src/main/content/region/morytania/canifis/handlers/CanafisWerewolfNPC.kt new file mode 100644 index 000000000..369aa550f --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/handlers/CanafisWerewolfNPC.kt @@ -0,0 +1,64 @@ +package content.region.morytania.canifis.handlers + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.skill.Skills +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.DeathTask +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +class WerewolfBehavior : NPCBehavior(*HUMAN_NPCS) { + companion object { + // There are 20 humans that can turn into werewolves. They are all in series, so a range toIntArray() is easier. + private val HUMAN_NPCS = (6026 .. 6045).toIntArray() + private val WEREWOLF_NPCS = (6006 .. 6025).toIntArray() + private val HUMAN_OUT_ANIMATION = Animation(6554) + private val WEREWOLF_IN_ANIMATION = Animation(6543) // This is not used as there is a corresponding gfx. + private val WEREWOLF_IN_GFXS = (1079 .. 1098).toIntArray() // Play each werewolf's gfx with the animation. + } + + override fun afterDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if(DeathTask.isDead(self)){ + // Don't transform if you are killed + return + } + if (attacker is Player) { + if (!inEquipment(attacker, Items.WOLFBANE_2952, 1) && self.id in HUMAN_NPCS) { + delayAttack(self, 3) + delayAttack(attacker, 3) + lock(self, 3) + queueScript(self, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + visualize(self, HUMAN_OUT_ANIMATION, WEREWOLF_IN_GFXS[self.id - 6026]) + return@queueScript delayScript(self, WEREWOLF_IN_ANIMATION.duration) + } + 1 -> { + val humanMaxLp = self.getSkills().getMaximumLifepoints() + transformNpcWithHpCarryover(self, WEREWOLF_NPCS[self.id - 6026], 200) + self.getSkills().heal(self.getSkills().getMaximumLifepoints() - humanMaxLp) + return@queueScript delayScript(self, 1) + } + 2 -> { + self.properties.combatPulse.attack(attacker) + return@queueScript stopExecuting(self) + } + else -> return@queueScript stopExecuting(self) + } + } + } + } + } + + override fun onRespawn(self: NPC) { + if (self.id in WEREWOLF_NPCS){ + self.reTransform() + } + super.onRespawn(self) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/handlers/TaxidermistInteraction.kt b/Server/src/main/content/region/morytania/canifis/handlers/TaxidermistInteraction.kt new file mode 100644 index 000000000..d7ead3a88 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/handlers/TaxidermistInteraction.kt @@ -0,0 +1,100 @@ +package content.region.morytania.canifis.handlers + +import content.region.morytania.canifis.dialogue.TaxidermistDialogue +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class TaxidermistInteraction : InteractionListener { + + enum class StuffableItem(val toStuff : Int, val product : Int, val message : String, val cost : Int){ + BASS(Items.BIG_BASS_7989, Items.BIG_BASS_7990, "That's a mighty fine sea bass you've caught there.", 1000), + SWORDFISH(Items.BIG_SWORDFISH_7991, Items.BIG_SWORDFISH_7992, "Don't point that thing at me!", 2500), + SHARK(Items.BIG_SHARK_7993,Items.BIG_SHARK_7994, "That's quite a fearsome shark! You've done everyone a service by removing it from the sea!", 5000), + CRAWLING_HAND(Items.CRAWLING_HAND_7975,Items.CRAWLING_HAND_7982, "That's a very fine crawling hand.", 1000), + COCKATRICE(Items.COCKATRICE_HEAD_7976, Items.COCKATRICE_HEAD_7983, "A cockatrice! Beautiful, isn't it? Look at the plumage!", 2000), + BASILISK( Items.BASILISK_HEAD_7977, Items.BASILISK_HEAD_7984, "My, he's a scary-looking fellow, isn't he? He'll look good on your wall!",4000), + KURASK(Items.KURASK_HEAD_7978, Items.KURASK_HEAD_7985, "A kurask? Splendid! Look at those horns!", 6000), + ABYSSAL(Items.ABYSSAL_HEAD_7979, Items.ABYSSAL_HEAD_7986, "Goodness, an abyssal demon!", 12000), + KBD(Items.KBD_HEADS_7980, Items.KBD_HEADS_7987, " This must be a King Black Dragon!", 50000), + KQ(Items.KQ_HEAD_7981, Items.KQ_HEAD_7988, " That must be the biggest kalphite I've ever seen!", 50000) + } + class TaxidermistTradeDialogue : DialogueFile() { + companion object{ + const val TRADE = 10 + const val YES = 20 + const val NO = 30 + const val POOR = 40 + } + + lateinit var stuffableItem : StuffableItem + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.HAPPY, stuffableItem.message).also { + stage = when(stuffableItem){ + StuffableItem.ABYSSAL -> stage + 1 + StuffableItem.KBD -> stage + 2 + StuffableItem.KQ -> stage + 3 + else -> TRADE + } + } + START_DIALOGUE + 1 -> npcl(FacialExpression.HAPPY, "See how it's still glowing? I'll have to use some magic to preserve that.").also { stage = TRADE } + START_DIALOGUE + 2 -> npcl(FacialExpression.HAPPY, "I'll have to get out my heavy duty tools -- this skin's as tough as iron!").also { stage = TRADE } + START_DIALOGUE + 3 -> npcl(FacialExpression.HAPPY, "Preserving insects is always tricky. I'll have to be careful...").also { stage = TRADE } + + TRADE -> npcl(FacialExpression.HAPPY, "I can preserve that for you for ${stuffableItem.cost} coins.").also { stage++ } + TRADE + 1 -> showTopics( + Topic("Yes please.", YES), + Topic("No thanks.", NO) + ) + YES -> { + if (inInventory(player!!, Items.COINS_995, stuffableItem.cost)){ + if (removeItem(player!!, stuffableItem.toStuff) && removeItem(player!!, Item(Items.COINS_995, stuffableItem.cost))){ + addItem(player!!, stuffableItem.product) + npcl(FacialExpression.HAPPY, "There you go!").also { stage = END_DIALOGUE } + } + } + else { + playerl(FacialExpression.SAD, "But I don't have enough money on me.").also { stage = POOR } + } + } + + POOR -> npcl(FacialExpression.ANNOYED, "Don't waste my time, then!").also { stage = END_DIALOGUE } + + NO -> npcl(FacialExpression.NEUTRAL, "All right, come back if you change your mind, eh?").also { stage = END_DIALOGUE } + } + } + + } + + override fun defineListeners() { + + onUseAnyWith(IntType.NPC, NPCs.TAXIDERMIST_4246) { player, used, with -> + val item = used.id + StuffableItem.values().map { if(it.toStuff == item){ + val dialogueFile = TaxidermistTradeDialogue() + dialogueFile.stuffableItem = it + openDialogue(player, dialogueFile, with as NPC) + return@onUseAnyWith true + } + } + + when (item) { + // all fish + Items.RAW_CHICKEN_2138 -> sendNPCDialogue(player, with.id, "Killing a chicken is hardly worth boasting about!") + else -> sendNPCDialogue(player, with.id, "Don't be silly, I can't preserve that!") + } + return@onUseAnyWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/canifis/handlers/WerewolfNPC.java b/Server/src/main/content/region/morytania/canifis/handlers/WerewolfNPC.java deleted file mode 100644 index 3884bbf56..000000000 --- a/Server/src/main/content/region/morytania/canifis/handlers/WerewolfNPC.java +++ /dev/null @@ -1,50 +0,0 @@ -package content.region.morytania.canifis.handlers; - -import core.game.node.entity.Entity; -import core.game.node.entity.npc.AbstractNPC; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.world.map.Location; - -/** - * Represents the tutorial chicken npc. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class WerewolfNPC extends AbstractNPC { - - /** - * Constructs a new {@code WerewolfNPC} {@code Object}. - * @param id the id. - * @param location the location. - */ - public WerewolfNPC(int id, Location location) { - super(id, location, true); - } - - /** - * Constructs a new {@code WerewolfNPC} {@code Object}. - */ - public WerewolfNPC() { - super(0, null); - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new WerewolfNPC(id, location); - } - - @Override - public void finalizeDeath(Entity killer) { - super.finalizeDeath(killer); - NPC nn = NPC.create(getAttribute("original", 6026), getAttribute("loc", getLocation())); - nn.init(); - } - - @Override - public int[] getIds() { - return new int[] { 6006 }; - } - -} diff --git a/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt b/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt index 6748596f5..cb80df540 100644 --- a/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt +++ b/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt @@ -70,8 +70,9 @@ class MortMyreGhastNPC : AbstractNPC { val consumable = Consumables.getConsumableById(i.id) if(consumable != null && consumable.consumable is Food) { hasFood = true - removeItem(player, i, Container.INVENTORY) - addItem(player, Items.ROTTEN_FOOD_2959) + if (removeItem(player, i, Container.INVENTORY)) { + addItem(player, Items.ROTTEN_FOOD_2959) + } sendMessage(player, "You feel something attacking your backpack, and smell a terrible stench.") break } diff --git a/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt b/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt index 19429c4bd..5edfa55f7 100644 --- a/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt +++ b/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt @@ -11,6 +11,7 @@ import org.rs09.consts.NPCs import core.game.bots.AIPlayer import core.game.dialogue.DialogueFile import core.game.world.GameWorld +import content.data.Quests class MorytaniaArea : MapArea { override fun defineAreaBorders(): Array { @@ -22,7 +23,7 @@ class MorytaniaArea : MapArea { override fun areaEnter(entity: Entity) { if (entity is Player && entity !is AIPlayer && ( - !isQuestComplete(entity, "Priest in Peril") || //not allowed to be anywhere in Morytania + !isQuestComplete(entity, Quests.PRIEST_IN_PERIL) || //not allowed to be anywhere in Morytania defineAreaBorders()[1].insideBorder(entity) //Werewolf agility course is not implemented )) { kickThemOut(entity) diff --git a/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt b/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt index ccce9cbaf..254bbd4a0 100644 --- a/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt +++ b/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt @@ -13,6 +13,9 @@ import org.rs09.consts.Scenery import core.game.interaction.InteractionListener import core.game.interaction.IntType import kotlin.random.Random +import content.data.Quests +import core.game.interaction.InterfaceListener +import org.rs09.consts.Components /** * File to be used for anything Morytania related. @@ -39,12 +42,15 @@ class MorytaniaListeners : InteractionListener { on(SWAMP_GATES, IntType.SCENERY, "open"){ player, node -> if(player.location.y == 3457){ core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "You skip gladly out of murky Mort Myre.") + removeTimer(player) GlobalScope.launch { findLocalNPC(player, NPCs.ULIZIUS_1054)?.sendChat("Oh my! You're still alive!", 2) } } else { - if (player.questRepository.hasStarted("Nature Spirit")) { - core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + if (player.questRepository.hasStarted(Quests.NATURE_SPIRIT)) { + setAttribute(player, "swampgate", node) + openInterface(player, Components.CWS_WARNING_20_580) } else { sendNPCDialogue( player, @@ -96,4 +102,24 @@ class MorytaniaListeners : InteractionListener { return@on true } } +} + +class warningInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(Components.CWS_WARNING_20_580) { player, _, _, buttonID, _, _ -> + when(buttonID) { + 17 -> { + val gate = getAttribute(player, "swampgate", null) as? core.game.node.scenery.Scenery + if (gate != null) { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, gate) + sendMessage(player, "You walk into the gloomy atmosphere of Mort Myre.") + } + closeInterface(player) + } + 18 -> closeInterface(player) + } + removeAttribute(player, "swampgate") + return@on true + } + } } \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/handlers/MoyrtniaSwampPlugin.java b/Server/src/main/content/region/morytania/handlers/MoyrtniaSwampPlugin.java deleted file mode 100644 index 69e663f47..000000000 --- a/Server/src/main/content/region/morytania/handlers/MoyrtniaSwampPlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -package content.region.morytania.handlers; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the mortynia swamp plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class MoyrtniaSwampPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(3506).getHandlers().put("option:open", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - player.getDialogueInterpreter().sendDialogue("There's a message attached to this gate, it reads:~", "~ Mort Myre is a dangerous Ghast infested swamp. ~", "~ Do not enter if you value your life. ~", "~ All persons wishing to enter must see Drezel. ~"); - return true; - } - -} diff --git a/Server/src/main/content/region/morytania/handlers/SwampDecayHandler.kt b/Server/src/main/content/region/morytania/handlers/SwampDecayHandler.kt new file mode 100644 index 000000000..995294730 --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/SwampDecayHandler.kt @@ -0,0 +1,148 @@ +package content.region.morytania.handlers + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.PersistTimer +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerFlag +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import kotlin.random.Random + + +/** + * The area for swamp decay + */ +class SwampDecayArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf( + ZoneBorders(3392, 3328, 3519, 3455) + ) + } + + /** + * Sources: + * General mechanic: https://runescape.wiki/w/Swamp_decay + * Historic damage: https://runescape.wiki/w/Mort_Myre_Swamp?oldid=1961846 + * Precise area: https://oldschool.runescape.wiki/w/Swamp_decay + * Video: https://www.youtube.com/watch?v=gkw959x8Q6s + * Video: https://www.youtube.com/watch?v=N86RywmEyEU + */ + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + getOrStartTimer(entity) + } + super.areaEnter(entity) + } + +} + +/** + * The timer for swamp decay + */ +class SwampDecayTimer : PersistTimer (200, "swampdecay", isSoft = true, flags = arrayOf(TimerFlag.ClearOnDeath)) { + companion object { + // Silver sickle, Rod of Ivandis, or Ivandis Flail in equip or inv will protect the player. + private val PROTECTIVE_ITEMS = intArrayOf( + Items.SILVER_SICKLEB_2963, + Items.ROD_OF_IVANDIS10_7639, + Items.ROD_OF_IVANDIS9_7640, + Items.ROD_OF_IVANDIS8_7641, + Items.ROD_OF_IVANDIS7_7642, + Items.ROD_OF_IVANDIS6_7643, + Items.ROD_OF_IVANDIS5_7644, + Items.ROD_OF_IVANDIS4_7645, + Items.ROD_OF_IVANDIS3_7646, + Items.ROD_OF_IVANDIS2_7647, + Items.ROD_OF_IVANDIS1_7648, + Items.IVANDIS_FLAIL_30_13117, + Items.IVANDIS_FLAIL_29_13118, + Items.IVANDIS_FLAIL28_13119, + Items.IVANDIS_FLAIL_27_13120, + Items.IVANDIS_FLAIL_26_13121, + Items.IVANDIS_FLAIL_25_13122, + Items.IVANDIS_FLAIL_24_13123, + Items.IVANDIS_FLAIL_23_13124, + Items.IVANDIS_FLAIL_22_13125, + Items.IVANDIS_FLAIL_21_13126, + Items.IVANDIS_FLAIL_20_13127, + Items.IVANDIS_FLAIL_19_13128, + Items.IVANDIS_FLAIL_18_13129, + Items.IVANDIS_FLAIL_17_13130, + Items.IVANDIS_FLAIL_16_13131, + Items.IVANDIS_FLAIL_15_13132, + Items.IVANDIS_FLAIL_14_13133, + Items.IVANDIS_FLAIL_13_13134, + Items.IVANDIS_FLAIL_12_13135, + Items.IVANDIS_FLAIL_11_13136, + Items.IVANDIS_FLAIL_10_13137, + Items.IVANDIS_FLAIL_9_13138, + Items.IVANDIS_FLAIL_8_13139, + Items.IVANDIS_FLAIL_7_13140, + Items.IVANDIS_FLAIL_6_13141, + Items.IVANDIS_FLAIL_5_13142, + Items.IVANDIS_FLAIL_4_13143, + Items.IVANDIS_FLAIL_3_13144, + Items.IVANDIS_FLAIL_2_13145, + Items.IVANDIS_FLAIL_1_13146 + ) + } + + // returning false stops the timer. returning true keeps it running. + override fun run(entity: Entity): Boolean { + if (entity !is Player) return false + + // player is outside the zone + if (entity.location.x !in 3392..3519 || entity.location.y !in 3328..3455) { + sendMessage(entity, "The swamp decay effect is now over.") + return false + } + + // the nature spirit camp zone is safe + if (entity.location.x in 3435..3445 && entity.location.y in 3331..3442) { + sendMessage(entity, "The aura of Filliman's camp protects you from the swamp.") + return true + } + + // protected + if (hasProtection(entity)) { + return true + } + + // decayed (2-4 random damage) + sendMessage(entity, "The swamp decays you!") + impact(entity, Random.nextInt(2, 5)) + visualize(entity, -1, 255) + return true + } + + override fun onRegister(entity: Entity) { + if (entity !is Player) return + } + + override fun getTimer(vararg args: Any): RSTimer { + val t = SwampDecayTimer() + t.runInterval = args.getOrNull(0) as? Int ?: 200 + return t + } + + // always remember your protection + private fun hasProtection(player: Player): Boolean { + for (itemId in PROTECTIVE_ITEMS) { + if (inEquipmentOrInventory(player, itemId)) { + val prot = when(itemId) { + 2963 -> "blessed silver sickle" + in 7639..7648 -> "rod of Ivandis" + in 13117..13146 -> "Ivandis flail" + else -> "item" // fallback + } + sendMessage(player, "The power of the $prot prevents the swamp decay.") + visualize(player, -1, 259) + return true + } + } + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java index 23d8093fe..40f395cf4 100644 --- a/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java +++ b/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java @@ -82,13 +82,13 @@ public final class GhostDiscipleDialogue extends DialoguePlugin { stage++; break; case 1: - options("What is the Ectofunuts?", "Where do I get ectoplasm from?", "How do I grind bones?", "How do I receive Ectotokens?", "Thanks for your time."); + options("What is the Ectofuntus?", "Where do I get ectoplasm from?", "How do I grind bones?", "How do I receive Ectotokens?", "Thanks for your time."); stage++; break; case 2: switch (buttonId) { case 1: - player("What is the Ectofunuts?"); + player("What is the Ectofuntus?"); stage = 10; break; case 2: diff --git a/Server/src/main/content/region/morytania/phas/dialogue/MetarialusDialogue.kt b/Server/src/main/content/region/morytania/phas/dialogue/MetarialusDialogue.kt new file mode 100644 index 000000000..cefb117d4 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/MetarialusDialogue.kt @@ -0,0 +1,127 @@ +package content.region.morytania.phas.dialogue + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +@Initializable +class MetarialusDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.METARIALUS_2322, IntType.NPC, "talk-to") { player, node -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)) { + DialogueLabeller.open(player, MetarialusDialogueFile(), node as NPC) + return@on true + } else { + DialogueLabeller.open(player, MetarialusDialogueNoGhostSpeakFile(), node as NPC) + return@on true + } + } + } +} + + +class MetarialusDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.METARIALUS_2322) + + player(ChatAnim.FRIENDLY, "Hello, I wonder if you could help me on this whole brewing thing...") + npc(ChatAnim.NEUTRAL, "I might be able to - what do you need to know?") + goto("main_menu") + + label("main_menu") { + options( + DialogueOption("how_brew_ales", "How do I brew ales?", expression = ChatAnim.HALF_ASKING, spokenText = "How do I brew ales?"), + DialogueOption("how_brew_cider", "How do I brew cider?", expression = ChatAnim.HALF_ASKING, spokenText = "How do I brew cider?"), + DialogueOption("what_when_matured", "What do I do once my ale has matured?", expression = ChatAnim.HALF_ASKING, spokenText = "What do I do once my ale has matured?"), + DialogueOption("buy_yeast", "Do you have any spare ale yeast?", expression = ChatAnim.HALF_ASKING, spokenText = "Do you have any spare ale yeast?"), + DialogueOption("end", "That's all I need to know, thanks.") + ) + } + + label("how_brew_ales") { + npc(ChatAnim.NEUTRAL, "Well first off you need to fill the vat with water - two bucketfuls should do the trick. Then you'll need to put in two handfuls of barley malt - that's roasted barley by the way.") + npc(ChatAnim.NEUTRAL, "After that you'll be putting your main ingredient in - this will decide which ale it is you're brewing. There should be some good guides around with recipes in.") + npc(ChatAnim.NEUTRAL, "Lastly you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.") + goto("main_menu") + } + + label("how_brew_cider") { + npc(ChatAnim.NEUTRAL, "First you'll need some apples. You'll need to crush them using this cider-press - four apples should make a full bucket of apple-mush. Take four buckets of mush and fill up the vat.") + npc(ChatAnim.NEUTRAL, "After that you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.") + goto("main_menu") + } + + label("what_when_matured") { + npc(ChatAnim.NEUTRAL, "Well, once you've got a full vat of the good stuff, just turn the valve and your barrel will fill up with eight pints of whatever your chosen tipple is. Mind it's an empty barrel, though.") + goto("main_menu") + } + + label("buy_yeast") { + npc(ChatAnim.NEUTRAL, "Well, as a matter of fact I do, although I wouldn't describe", + "it as spare. This ale yeast I've got is the best money can", + "buy, but if you've got a pot I'll fill it for you for", + "5 ecto-tokens - very cheap as it happens.") + options( + DialogueOption("confirm_buy", "That's a good deal - please fill my pot with ale yeast for 5 ecto-tokens."), + DialogueOption("end", "No, that's too much I'm afraid.") + ) + } + + label("confirm_buy") { + exec { player, npc -> + if (!inInventory(player, Items.EMPTY_POT_1931, 1)) { + loadLabel(player, "no_pot") + } else if (!inInventory(player, Items.ECTO_TOKEN_4278, 5)) { + loadLabel(player, "no_tokens") + } else { + loadLabel(player, "process_purchase") + } + } + } + + label("no_pot") { + npc(ChatAnim.NEUTRAL, "I'm afraid you'll need a pot for me to put the yeast in.") + goto("end") + } + + label("no_tokens") { + line("You can not afford that.") + goto("end") + } + + label("process_purchase") { + exec { player, npc -> + val emptyPots = amountInInventory(player, Items.EMPTY_POT_1931) + val tokens = amountInInventory(player, Items.ECTO_TOKEN_4278) + val canAfford = tokens / 5 + val quantity = minOf(emptyPots, canAfford) + + if (removeItem(player, Item(Items.EMPTY_POT_1931, quantity)) && removeItem(player, Item(Items.ECTO_TOKEN_4278, quantity * 5))) { + addItem(player, Items.ALE_YEAST_5767, quantity) + } + } + goto("main_menu") + } + + label("end") { + } + } +} + + +class MetarialusDialogueNoGhostSpeakFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.METARIALUS_2322) + + npc(ChatAnim.WORRIED, "Wooo Woo ooo wooowoo!") // Placeholder taken from restless ghost, can't find source for his no-ghostspeak text + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt index a5d0843da..7a07c5a44 100644 --- a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt @@ -1,5 +1,6 @@ package content.region.morytania.quest.creatureoffenkenstrain +import content.data.Quests import content.global.handlers.iface.BookInterface import content.global.handlers.iface.BookLine import content.global.handlers.iface.Page @@ -46,7 +47,7 @@ class BookcaseEastDialogueFile : DialogueFile() { 4 -> sendDialogue(player!!, "The book is appallingly dull.").also { stage = END_DIALOGUE } } 2 -> { - if (getQuestStage(player!!, CreatureOfFenkenstrain.questName) == 2) { + if (getQuestStage(player!!, Quests.CREATURE_OF_FENKENSTRAIN) == 2) { sendItemDialogue(player!!, Items.OBSIDIAN_AMULET_4188, "You find an obsidian amulet in the secret compartment.").also { addItemOrDrop(player!!, Items.OBSIDIAN_AMULET_4188, 1) stage = END_DIALOGUE @@ -67,7 +68,7 @@ class BookcaseEastDialogueFile : DialogueFile() { class ChimneySweepingOnABudgetBook { companion object { - private val TITLE = "Chimney Sweeping on a Budget " + private val TITLE = "Chimney Sweeping on a Budget" val CONTENTS = arrayOf( PageSet( Page( @@ -102,4 +103,4 @@ class ChimneySweepingOnABudgetBook { return true } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt index 3e3b3137b..dd7dccc9b 100644 --- a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt @@ -6,8 +6,7 @@ import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Items - -val CREATURE_OF_FENKENSTRAIN = "Creature of Fenkenstrain" +import content.data.Quests /** * Creature of Fenkenstrain Quest @@ -27,10 +26,9 @@ val CREATURE_OF_FENKENSTRAIN = "Creature of Fenkenstrain" * 100 - Stoped Fenkenstrain by stealing ring of charos */ @Initializable -class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, 0, 1, 9) { +class CreatureOfFenkenstrain : Quest(Quests.CREATURE_OF_FENKENSTRAIN, 41, 40, 2, 399, 0, 1, 9) { companion object { - const val questName = "Creature of Fenkenstrain" const val attributeArms = "/save:quest:creatureoffenkenstrain-arms" const val attributeLegs = "/save:quest:creatureoffenkenstrain-legs" const val attributeTorso = "/save:quest:creatureoffenkenstrain-torso" @@ -46,7 +44,7 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, var line = 12 var stage = getStage(player) - var started = getQuestStage(player, questName) > 0 + var started = getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 0 if(!started){ line(player, "I can start this quest by reading the signpost in the", line++, false) @@ -56,8 +54,9 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, line(player, "Level 20 Crafting", line++, hasLevelStat(player, Skills.CRAFTING, 20)) line(player, "Level 25 Theiving", line++, hasLevelStat(player, Skills.THIEVING, 25)) line(player, "I also need to have completed the following quests:", line++, false) - line(player, "Priest in Peril", line++, isQuestComplete(player, "Priest in Peril")) - line(player, "Restless Ghost", line++, isQuestComplete(player, "The Restless Ghost")) + line(player, "Priest in Peril", line++, isQuestComplete(player, Quests.PRIEST_IN_PERIL)) + line(player, "Restless Ghost", line++, isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) + limitScrolling(player, line, true) } else { line(player, "I read the signpost in Canifis, which tells of a butler", line++, true) line(player, "position that is available at the castle to the northeast.", line++, true) @@ -67,12 +66,13 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, } else if (stage >= 1) { line(player, "I should go up to the castle and speak to !!Dr Fenkenstrain??", line++, false) } - line++ if (stage >= 3) { - line(player, "I gave a torso, some arms and legs, and a head to Fenkenstrain,", line++, true) - line(player, "who then wanted a needle and 5 lots of thread, so that he could", line++, true) - line(player, "sew the bodyparts together and create his creature.", line++, true) + line(player, "I gave a torso, some arms and legs, and a head to", line++, true) + line(player, "Fenkenstrain, who then wanted a needle and 5 lots of", line++, true) + line(player, "thread, so that he could sew the bodyparts together and", line++, true) + line(player, "create his creature.", line++, true) } else if (stage >= 2) { + line++ line(player, "I need to find these body parts for !!Fenkenstrain??:", line++, false) line(player, "a pair of !!arms??", line++, false) line(player, "a pair legs !!legs??", line++, false) @@ -84,7 +84,6 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, line(player, "elsewhere, so perhaps I should look at the graves in the", line++, false) line(player, "local area", line++, false) } - line++ if (stage >= 4) { line(player, "I brought Fenkenstrain a needle and 5 quantities of", line++, true) line(player, "thread.", line++, true) @@ -92,15 +91,13 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, line(player, "I need to bring !!Fenkenstrain?? a !!needle?? and !!5 quantities??", line++, false) line(player, "!!of thread??.", line++, false) } - line++ if (stage >= 5) { line(player, "I repaired the lightning conductor, and Fenkenstrain", line++, true) line(player, "brought the Creature to life.", line++, true) } else if (stage >= 4) { - line(player, "I need to repair the !!lightning conductor?? on the", line++, false) - line(player, "!!balcony?? above.", line++, false) + line(player, "!!Fenkenstrain?? has ordered me to repair the lightning", line++, false) + line(player, "conductor.", line++, false) } - line++ if (stage == 5) { line(player, "!!Fenkenstrain?? wants to talk to me.", line++, false) line++ @@ -115,10 +112,9 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, line(player, "The !!Creature?? went on a rampage, and !!Fenkenstrain?? wants", line++, false) line(player, "me to go up the !!Tower?? to destroy it.", line++, false) } - line++ if (stage >= 8) { - line(player, "I stole Fenkenstrain's Ring of Charos, and he released me from", line++, true) - line(player, "his service.", line++, true) + line(player, "I stole Fenkenstrain's Ring of Charos, and he released", line++, true) + line(player, "me from his service.", line++, true) } else if (stage >= 7) { line(player, "I must find a way to stop Fenkenstrain's experiments.", line++, false) } @@ -126,6 +122,7 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, line++ line(player,"QUEST COMPLETE!", line) } + limitScrolling(player, line, false) } } @@ -133,8 +130,8 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, return arrayOf( hasLevelStat(player, Skills.CRAFTING, 20), hasLevelStat(player, Skills.THIEVING, 25), - isQuestComplete(player, "Priest in Peril"), - isQuestComplete(player, "The Restless Ghost"), + isQuestComplete(player, Quests.PRIEST_IN_PERIL), + isQuestComplete(player, Quests.THE_RESTLESS_GHOST), ).all { it } } @@ -172,10 +169,10 @@ class CreatureOfFenkenstrain : Quest("Creature of Fenkenstrain", 41, 40, 2, 399, override fun updateVarps(player: Player) { // This is a bit of a hack. I didn't manage to align the quest with the varp, // so I had to include both stage 3 and 4 to varp value 3 to show the creature. - if(getQuestStage(player, questName) == 4) { + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 4) { setVarp(player, fenkenstrainVarp, 3, true) } - if(getQuestStage(player, questName) >= 8) { + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) >= 8) { setVarp(player, fenkenstrainVarp, 8, true) } } diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt index a79c8940e..7a0aea3bc 100644 --- a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt @@ -1,15 +1,12 @@ package content.region.morytania.quest.creatureoffenkenstrain -import content.global.travel.canoe.CanoeListener +import content.data.Quests import core.api.* import core.game.dialogue.FacialExpression import core.game.global.action.DoorActionHandler import core.game.global.action.PickupHandler import core.game.interaction.InteractionListener -import core.game.node.Node -import core.game.node.entity.player.Player import core.game.node.item.GroundItem -import core.game.node.item.Item import core.game.system.task.Pulse import core.game.world.map.Location import core.game.world.update.flag.context.Animation @@ -64,7 +61,7 @@ class CreatureOfFenkenstrainListeners : InteractionListener { // 1: Reading Signpost to start the quest on(Items.NULL_5164, SCENERY, "read") { player, _ -> - if (getQuestStage(player, CreatureOfFenkenstrain.questName) < 7 ) { + if (getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) < 7 ) { sendDialogueLines( player, "The signpost has a note pinned onto it. The note says:", @@ -79,8 +76,11 @@ class CreatureOfFenkenstrainListeners : InteractionListener { "'AAARRGGGHHHHH!!!!!'", ) } - if(getQuest(player, CreatureOfFenkenstrain.questName).hasRequirements(player) && getQuestStage(player, CreatureOfFenkenstrain.questName) == 0) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 1) + if(getQuest(player, Quests.CREATURE_OF_FENKENSTRAIN).hasRequirements(player) && getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) == 0) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 1) } return@on true } @@ -199,7 +199,7 @@ class CreatureOfFenkenstrainListeners : InteractionListener { on(Items.NULL_5167, SCENERY, "search") { player, node -> val scenery = node.asScenery() if(getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedMemorial, false) || - getQuestStage(player, CreatureOfFenkenstrain.questName) > 2) { + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 2) { animateScenery(player, scenery, 1620) var dest: Location? = null if(scenery.location.equals(Location(3505, 3571))) { @@ -230,7 +230,7 @@ class CreatureOfFenkenstrainListeners : InteractionListener { on(Items.NULL_5167, SCENERY, "push") { player, node -> val scenery = node.asScenery() if (getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedMemorial, false) || - getQuestStage(player, CreatureOfFenkenstrain.questName) > 2) { + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 2) { animateScenery(player, scenery, 1620) var dest: Location? = null if(scenery.location.equals(Location(3505, 3571))) { @@ -256,7 +256,7 @@ class CreatureOfFenkenstrainListeners : InteractionListener { // 5: Garden Shed Door on(Scenery.DOOR_5174, SCENERY, "open") { player, node -> if (getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedShed, false) || - getQuestStage(player, CreatureOfFenkenstrain.questName) >= 5) { + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) >= 5) { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else if (inInventory(player, Items.SHED_KEY_4186)) { if (removeItem(player, Items.SHED_KEY_4186)) { @@ -272,7 +272,7 @@ class CreatureOfFenkenstrainListeners : InteractionListener { // 5: Garden Shed Door onUseWith(SCENERY, Items.SHED_KEY_4186, Scenery.DOOR_5174) { player, used, with -> if (getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedShed, false) || - getQuestStage(player, CreatureOfFenkenstrain.questName) >= 5) { + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) >= 5) { DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) } else if (removeItem(player, used)) { DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) @@ -346,8 +346,8 @@ class CreatureOfFenkenstrainListeners : InteractionListener { return@on true } if (removeItem(player, Items.CONDUCTOR_4201)) { - if(getQuestStage(player, CreatureOfFenkenstrain.questName) == 4) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 5) + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 4) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 5) } sendDialogue(player, "You repair the lightning conductor not one moment too soon - a tremendous bold of lightning melts the new lightning conductor, and power blazes throughout the castle, if only briefly.") val scenery = node.asScenery() @@ -359,7 +359,10 @@ class CreatureOfFenkenstrainListeners : InteractionListener { // 6: Enter jail above on(Scenery.DOOR_5172, SCENERY, "open") { player, node -> - if (inInventory(player, Items.TOWER_KEY_4185) || getQuestStage(player, CreatureOfFenkenstrain.questName) > 7) { + if (inInventory(player, Items.TOWER_KEY_4185) || getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) > 7) { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { sendMessage(player, "The door is locked.") @@ -377,10 +380,10 @@ class CreatureOfFenkenstrainListeners : InteractionListener { // 7: Pickpocket Ring of Charos from Fenkenstrain on(NPCs.DR_FENKENSTRAIN_1670, NPC, "pickpocket") { player, node -> - if (getQuestStage(player, CreatureOfFenkenstrain.questName) == 7) { + if (getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 7) { sendMessage(player, "You steal the Ring of Charos from Fenkenstrain.") - finishQuest(player, CreatureOfFenkenstrain.questName) - } else if (getQuestStage(player, CreatureOfFenkenstrain.questName) > 7 && hasAnItem(player, Items.RING_OF_CHAROS_4202).container == null) { + finishQuest(player, Quests.CREATURE_OF_FENKENSTRAIN) + } else if (getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 7 && hasAnItem(player, Items.RING_OF_CHAROS_4202).container == null) { // Allow Fenkenstrain to be pickpocketed beyond the quest if the ring is lost. addItemOrDrop(player, Items.RING_OF_CHAROS_4202, 1) sendMessage(player, "You steal the Ring of Charos from Fenkenstrain.") diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt index a4fcea45d..c6e848f86 100644 --- a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt @@ -1,5 +1,6 @@ package content.region.morytania.quest.creatureoffenkenstrain +import content.data.Quests import core.api.* import core.game.dialogue.* import core.game.node.entity.player.Player @@ -65,13 +66,13 @@ class DrFenkenstrainDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(CREATURE_OF_FENKENSTRAIN, 0) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 0) .npcl("Have you come to apply for the job?") .playerl(FacialExpression.THINKING, "What job?") .npcl("I've posted a note on the signpost in Canifis about it. Go take a look at it first.") .end() - b.onQuestStages(CREATURE_OF_FENKENSTRAIN, 1) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 1) .npcl("Have you come to apply for the job?") .options().let { optionBuilder -> val continuePath = b.placeholder() @@ -127,12 +128,12 @@ class DrFenkenstrainDialogueFile : DialogueBuilderFile() { .npcl("I need you to get me enough dead body parts for me to stitch together a complete body, which I plan to bring to life.") .playerl("Right...okay...if you insist.") .endWith { _, player -> - if(getQuestStage(player, CreatureOfFenkenstrain.questName) == 1) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 2) + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 1) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 2) } } - b.onQuestStages(CreatureOfFenkenstrain.questName, 2) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 2) .options().let { optionBuilder -> val continuePath = b.placeholder() @@ -184,12 +185,12 @@ class DrFenkenstrainDialogueFile : DialogueBuilderFile() { .npcl("Oh bother! I haven't got a needle or thread!") .npcl("Go and get me a needle, and I'll need 5 lots of thread.") .endWith { _, player -> - if(getQuestStage(player, CreatureOfFenkenstrain.questName) == 2) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 3) + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 2) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 3) } } - b.onQuestStages(CreatureOfFenkenstrain.questName, 3) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 3) .npcl("Where are my needle and thread, @name?") // Dialogue path to look for 1 needle. .let{ builder -> return@let hasPart(builder, Item(Items.NEEDLE_1733, 1), CreatureOfFenkenstrain.attributeNeedle, "Ah, a needle. Wonderful.") } @@ -219,19 +220,19 @@ class DrFenkenstrainDialogueFile : DialogueBuilderFile() { .playerl("Repair the lightning conductor, right. Can I have a break, soon? By law I'm entitled to 15 minutes every-") .npcl("Repair the conductor and BEGONE!!") .endWith { _, player -> - if(getQuestStage(player, CreatureOfFenkenstrain.questName) == 3) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 4) + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 3) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 4) } } - b.onQuestStages(CreatureOfFenkenstrain.questName, 4) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 4) .playerl(FacialExpression.THINKING, "How do I repair the lighting conductor?") .npcl("Oh, it would be easier to do it myself! If you find a conductor mould you should be able to cast a new one.") .npcl("Remember this, @name, my experiment will only work with a conductor made from silver.") .end() - b.onQuestStages(CreatureOfFenkenstrain.questName, 5) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 5) .playerl("So did it work, then?") .npcl("Yes, I'm afraid it did, @name - all too well.") .playerl(FacialExpression.SUSPICIOUS, "I can't see it anywhere.") @@ -244,19 +245,19 @@ class DrFenkenstrainDialogueFile : DialogueBuilderFile() { .playerl(FacialExpression.SUSPICIOUS, "What do you want me to do about it?") .npcl("Destroy it!!! Take the key to the Tower and take back the life I never should have granted!!!") .endWith() { df, player -> - if(getQuestStage(player, CreatureOfFenkenstrain.questName) == 5) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 6) + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 5) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 6) } addItemOrDrop(player, Items.TOWER_KEY_4185) } - b.onQuestStages(CreatureOfFenkenstrain.questName, 6) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 6) .npcl("So have you destroyed it?!!?") .playerl("Not yet.") .npcl("Please, hurry - save me!!!!") .end() - b.onQuestStages(CreatureOfFenkenstrain.questName, 7) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 7) .npcl("So have you destroyed it?!!?") .playerl("Never, now that he has told me the truth!") .npcl("Oh my, oh my, this is exactly what I feared!") @@ -265,7 +266,7 @@ class DrFenkenstrainDialogueFile : DialogueBuilderFile() { .npcl("No! I refuse to release you! You must help me build another creature to destroy this dreadful mistake!!") .end() - b.onQuestStages(CreatureOfFenkenstrain.questName, 8, 100) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 8, 100) .npcl("theyrecomingtogetme theyrecomingtogetme...") .playerl("It is all you deserve. Lord Rologarth is master of this castle once more. Let him protect you - if he wants to.") .npcl("theyrecomingtogetme theyrecomingtogetme...") diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt index 712ab5100..6c7bd9830 100644 --- a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt @@ -1,12 +1,10 @@ package content.region.morytania.quest.creatureoffenkenstrain +import content.data.Quests import core.api.* import core.game.dialogue.* import core.game.node.entity.player.Player -import core.game.node.item.Item import core.plugin.Initializable -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs import java.util.* @@ -20,7 +18,7 @@ class GardenerGhostDialogue (player: Player? = null) : DialoguePlugin(player) { if (gardenerGhost.location.withinDistance(gardenerGhost.graveLocation, 5)) { sendChat(gardenerGhost, "Here is the place where I met me' maker.") } else { - sendChat(gardenerGhost, "Go " + gardenerGhost.location.deriveDirection(gardenerGhost.graveLocation).name.lowercase(Locale.getDefault()).replace('_', '-') + ", mate") + sendChat(gardenerGhost, "Go " + gardenerGhost.location.deriveDirection(gardenerGhost.graveLocation)!!.name.lowercase(Locale.getDefault()).replace('_', '-') + ", mate") gardenerGhost.continueFollowing(player) } } else { @@ -41,7 +39,7 @@ class GardenerGhostDialogueFile : DialogueBuilderFile() { b.onPredicate { player -> !player.equipment.containsAtLeastOneItem(Items.GHOSTSPEAK_AMULET_552) } .npcl("Wooo wooo wooooo.") .end() - b.onQuestStages(CreatureOfFenkenstrain.questName, *(0 .. 8).toIntArray(), 100) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, *(0..8).toIntArray(), 100) .options().let { optionBuilder -> optionBuilder.option("Tell me about Fenkenstrain.") .playerl("Can you tell me anything about Fenkenstrain?") @@ -57,14 +55,20 @@ class GardenerGhostDialogueFile : DialogueBuilderFile() { .npcl("Don't worry yerself. I'm not worried about bein' dead. Worse things could happen, I suppose.") .npcl("One thing I do know is, there ain't no lord of the castle anymore, 'cept for old Fenky. Makes ya think a bit, don't it?") .end() - optionBuilder.optionIf("Do you know where the key to the shed is?") { player -> return@optionIf getQuestStage(player, CreatureOfFenkenstrain.questName) == 4 } + optionBuilder.optionIf("Do you know where the key to the shed is?") { player -> return@optionIf getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) == 4 } .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") .npcl("Got it right 'ere in my pocket. Here you go.") .iteml(4186, "The headless gardener hands you a rusty key.") .endWith { _, player -> addItemOrDrop(player, Items.SHED_KEY_4186) } - optionBuilder.optionIf("Do you know where I can find a lightning conductor mould is?") { player -> return@optionIf getQuestStage(player, CreatureOfFenkenstrain.questName) == 4 } + optionBuilder.optionIf("Do you know where I can find a lightning conductor mould is?") { player -> return@optionIf getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) == 4 } .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") .npcl("A conductor mould, you say? Let me see...") .npcl("There used to be a bloke 'ere, sort of an 'andyman 'e was. Did everything 'round the place - fixed what was broke, swept the chimneys and the like. He would 'ave had a mould, I imagine.") @@ -80,7 +84,10 @@ class GardenerGhostDialogueFile : DialogueBuilderFile() { .playerl("Would you show me where the place was?") .npcl("Well, oi s'pose oi've got ten minutes to spare.") .endWith { df, player -> (df.npc!! as GardenerGhostNPC).startFollowing(player) } - optionBuilder.optionIf("What's your name?") { player -> return@optionIf getQuestStage(player, CreatureOfFenkenstrain.questName) < 4 } + optionBuilder.optionIf("What's your name?") { player -> return@optionIf getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) < 4 } .playerl("What's your name?") .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") .npcl("Me name? It's been a moivellous long while, mate, since I had any use for such a thing as a name.") diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt index de32db2a3..6fd066de5 100644 --- a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt @@ -1,11 +1,11 @@ package content.region.morytania.quest.creatureoffenkenstrain +import content.data.Quests import core.api.* import core.game.dialogue.DialogueBuilder import core.game.dialogue.DialogueBuilderFile import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression -import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.NPCs @@ -27,7 +27,7 @@ class LordRologarthDialogue (player: Player? = null) : DialoguePlugin(player) { class LordRologarthDialogueFile : DialogueBuilderFile() { override fun create(b: DialogueBuilder) { - b.onQuestStages(CreatureOfFenkenstrain.questName, 6) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 6) .playerl("I am commanded to destroy you, creature!") .npcl("Oh that's *hic* not very *hic* nice ...") .playerl("Are you feeling ok?") @@ -49,11 +49,11 @@ class LordRologarthDialogueFile : DialogueBuilderFile() { .playerl("That's it - I'm leaving this dreadful place, whether I get paid or not. Is there anything I can do for you before I leave?") .npcl("Only one - please stop Fenkenstrain from carrying on his experiments, once and for all, so that no other poor soul has to endure suffering such as that of my people and I.") .endWith() { df, player -> - if(getQuestStage(player, CreatureOfFenkenstrain.questName) == 6) { - setQuestStage(player, CreatureOfFenkenstrain.questName, 7) + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 6) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 7) } } - b.onQuestStages(CreatureOfFenkenstrain.questName, 7) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 7) .playerl(FacialExpression.THINKING, "Do you know how I can stop Fenkenstrain's experiments?") .npcl("Take the Ring of Charos from him.") .playerl(FacialExpression.THINKING, "What is this ring?") @@ -61,7 +61,7 @@ class LordRologarthDialogueFile : DialogueBuilderFile() { .npcl("The Ring of Charos has many powers, but Fenkenstrain has bent them to his down evil purposes. Without the power of the ring, he will not be able to raise the dead from their sleep.") .npcl("It has one other, extremely important use - it confuses the werewolves' senses, making them believe that they smell one of their own kind. Without the ring, Fenkenstrain will be at their mercy.") .end() - b.onQuestStages(CreatureOfFenkenstrain.questName, 8, 100) + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 8, 100) .npcl("How goes it, friend?") .playerl("I stole the Ring of Charos from Fenkenstrain.") .npcl("I saw him climb up into the Tower to hide. It doesn't matter - soon the werewolves will come for him, and his experiments will be forever ceased.") diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt index 4ff9d60c4..8bfa2330f 100644 --- a/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt @@ -11,11 +11,12 @@ import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.tools.END_DIALOGUE import org.rs09.consts.Sounds +import content.data.Quests class NSDrezelDialogue : DialogueFile() { var questStage = 0 override fun handle(componentID: Int, buttonID: Int) { - questStage = player!!.questRepository.getStage("Nature Spirit") + questStage = player!!.questRepository.getStage(Quests.NATURE_SPIRIT) if(questStage <= 5){ when(stage){ @@ -51,12 +52,12 @@ class NSDrezelDialogue : DialogueFile() { if(questStage == 0){ repeat(3) { addItemOrDrop(player!!, Items.MEAT_PIE_2327, 1) } repeat(3) { addItemOrDrop(player!!, Items.APPLE_PIE_2323, 1) } - player!!.questRepository.getQuest("Nature Spirit").setStage(player!!, 5) + player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player!!, 5) } stage++ } 23 -> npcl(FacialExpression.NEUTRAL, "Please take this food to Filliman, he'll probably appreciate a bit of cooked food. Now, he's never revealed where he lives in the swamps but I guess he'd be to the south, search for him won't you?").also { stage++ } - 24 -> playerl(FacialExpression.FRIENDLY, "I'll do my very best, don't worry, if he's in there and he's still alive I'll definitely find him.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest("Nature Spirit").start(player!!) } + 24 -> playerl(FacialExpression.FRIENDLY, "I'll do my very best, don't worry, if he's in there and he's still alive I'll definitely find him.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).start(player!!) } } } @@ -85,7 +86,7 @@ class NSDrezelDialogue : DialogueFile() { } else if(questStage == 40){ - npcl(FacialExpression.NEUTRAL, "There you go my friend, you're now blessed. It's funny, now I look at you, there seems to be something of the faith about you. Anyway, good luck with your quest!").also { stage = END_DIALOGUE; player!!.questRepository.getQuest("Nature Spirit").setStage(player!!, 45) } + npcl(FacialExpression.NEUTRAL, "There you go my friend, you're now blessed. It's funny, now I look at you, there seems to be something of the faith about you. Anyway, good luck with your quest!").also { stage = END_DIALOGUE; player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player!!, 45) } } else { @@ -106,7 +107,7 @@ private class BlessingPulse(val drezel: NPC, val player: Player) : Pulse(){ when(ticks){ 0 -> animate(drezel, 1162).also { spawnProjectile(drezel, player, 268); playAudio(player, Sounds.PRAYER_RECHARGE_2674) } 2 -> visualize(player, Animation(645), Graphics(267, 100)) - 4 -> unlock(player).also { player.questRepository.getQuest("Nature Spirit").setStage(player, 40); return true } + 4 -> unlock(player).also { player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, 40); return true } } ticks++ return false diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt index c8e5a1b4a..b580aa4f3 100644 --- a/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt @@ -17,9 +17,9 @@ import core.game.shops.Shops import core.game.interaction.InteractionListener import core.game.interaction.IntType import content.region.morytania.handlers.MortMyreGhastNPC -import core.tools.SystemLogger import core.tools.END_DIALOGUE import core.tools.Log +import content.data.Quests class NSListeners : InteractionListener { @@ -63,7 +63,7 @@ class NSListeners : InteractionListener { } on(GROTTO_ENTRANCE, IntType.SCENERY, "enter"){ player, node -> - val questStage = player.questRepository.getQuest("Nature Spirit").getStage(player) + val questStage = player.questRepository.getQuest(Quests.NATURE_SPIRIT).getStage(player) if(questStage < 55) { val npc = core.game.node.entity.npc.NPC.create(NPCs.FILLIMAN_TARLOCK_1050, Location.create(3440, 3336, 0)) npc.init() @@ -76,7 +76,7 @@ class NSListeners : InteractionListener { } on(GROTTO_ALTAR, IntType.SCENERY, "search"){ player, node -> - val stage = player.questRepository.getStage("Nature Spirit") + val stage = player.questRepository.getStage(Quests.NATURE_SPIRIT) if(stage == 55){ openDialogue(player, FillimanCompletionDialogue(), NPC(NPCs.FILLIMAN_TARLOCK_1050)) return@on true @@ -101,7 +101,7 @@ class NSListeners : InteractionListener { } on(WISHING_WELL, IntType.SCENERY, "make-wish"){ player, node -> - if(player.questRepository.isComplete("Nature Spirit") && player.questRepository.isComplete("Wolf Whistle")) + if(player.questRepository.isComplete(Quests.NATURE_SPIRIT) && player.questRepository.isComplete(Quests.WOLF_WHISTLE)) Shops.openId(player, 241) else sendDialogue(player, "You can't do that yet.") @@ -132,8 +132,7 @@ class NSListeners : InteractionListener { } on(SPELLCARD, IntType.ITEM, "cast"){ player, node -> - if(NSUtils.castBloom(player)){ - removeItem(player, node.asItem(), Container.INVENTORY) + if (NSUtils.castBloom(player) && removeItem(player, node.asItem(), Container.INVENTORY)) { addItem(player, Items.A_USED_SPELL_2969) } return@on true @@ -141,7 +140,7 @@ class NSListeners : InteractionListener { on(intArrayOf(DRUID_POUCH, DRUID_POUCH_EMPTY), IntType.ITEM, "fill"){ player, node -> - if(player.questRepository.getStage("Nature Spirit") >= 75) { + if(player.questRepository.getStage(Quests.NATURE_SPIRIT) >= 75) { if (amountInInventory(player, PEAR) >= 3) { if (node.id != Items.DRUID_POUCH_2958) { removeItem(player, node, Container.INVENTORY) @@ -183,7 +182,7 @@ class NSListeners : InteractionListener { } onUseWith(IntType.NPC, Items.SECATEURS_5329, NPCs.NATURE_SPIRIT_1051) {player, used, with -> - if (!hasRequirement(player, "Fairytale I - Growing Pains")) + if (!hasRequirement(player, Quests.FAIRYTALE_I_GROWING_PAINS)) return@onUseWith true if (amountInInventory(player, Items.COINS_995) < 40000) { sendDialogue(player, "You need 40,000 coins to do this.") @@ -253,7 +252,7 @@ class CompleteSpellPulse(val player: Player) : Pulse(2){ override fun pulse(): Boolean { when(counter++){ 0 -> repeat(6) { spawnProjectile(locations[it], dest, 268, 0, 1000, 0, 40, 20) } - 1 -> player.questRepository.getQuest("Nature Spirit").setStage(player, 60) + 1 -> player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, 60) 2 -> player.teleport(player.location.transform(0,0,1)) 3 -> openDialogue(player, NPCs.NATURE_SPIRIT_1051, findLocalNPC(player, NPCs.NATURE_SPIRIT_1051) as NPC).also { unlock(player); return true } } diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt index cfdd8ea17..7559ff085 100644 --- a/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt @@ -6,7 +6,6 @@ import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player -import core.game.node.entity.player.link.quest.Quest import core.game.system.task.Pulse import core.game.world.map.Location import core.game.world.update.flag.context.Graphics @@ -14,6 +13,7 @@ import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests @Initializable class NSTarlockDialogue(player: Player? = null) : DialoguePlugin(player) { @@ -25,7 +25,7 @@ class NSTarlockDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - val quest = player.questRepository.getQuest("Nature Spirit") + val quest = player.questRepository.getQuest(Quests.NATURE_SPIRIT) questStage = quest.getStage(player) if(questStage > 10 && !inEquipment(player, Items.GHOSTSPEAK_AMULET_552)){ @@ -127,7 +127,7 @@ class NSTarlockDialogue(player: Player? = null) : DialoguePlugin(player) { playerl(FacialExpression.NEUTRAL, "Could I have another bloom scroll please?").also { stage++ } } else end() 74 -> npcl(FacialExpression.NEUTRAL, "Sure, but please look after this one.").also { stage++ } - 75 -> sendDialogue("The spirit of Filliman Tarlock gives you","another bloom spell.").also { addItem(player, Items.DRUIDIC_SPELL_2968); stage = END_DIALOGUE } + 75 -> sendDialogue("The spirit of Filliman Tarlock gives you","another bloom spell.").also { addItemOrDrop(player, Items.DRUIDIC_SPELL_2968); stage = END_DIALOGUE } //has fungus 80 -> sendDialogue("You show the fungus to Filliman.").also { stage++ } @@ -190,7 +190,7 @@ class NSTarlockDialogue(player: Player? = null) : DialoguePlugin(player) { npcl(FacialExpression.NEUTRAL, "No, you've already got one!").also { stage = END_DIALOGUE } } else { npcl(FacialExpression.NEUTRAL, "Sure, but look after this one.") - addItem(player, Items.DRUIDIC_SPELL_2968) + addItemOrDrop(player, Items.DRUIDIC_SPELL_2968) stage = END_DIALOGUE } @@ -234,7 +234,7 @@ class NSTarlockDialogue(player: Player? = null) : DialoguePlugin(player) { } fun setQuest(stage: Int){ - player.questRepository.getQuest("Nature Spirit").setStage(player, stage) + player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, stage) } } \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt index 03263c6c4..1a59aa8df 100644 --- a/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt @@ -58,7 +58,7 @@ object NSUtils { if(pouchAmt == 1) shouldAddEmptyPouch = true if(pouchAmt > 0 && removeItem(player, Items.DRUID_POUCH_2958, Container.INVENTORY)){ if(shouldAddEmptyPouch){ - addItem(player, Items.DRUID_POUCH_2957) + addItemOrDrop(player, Items.DRUID_POUCH_2957) } spawnProjectile(player, attacker, 268) submitWorldPulse(object : Pulse(){ diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt index fe4913223..bdf92adea 100644 --- a/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt @@ -12,11 +12,12 @@ import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs import core.tools.END_DIALOGUE +import content.data.Quests @Initializable class NatureSpiritDialogue(player: Player? = null) : DialoguePlugin(player){ - val questStage = player?.questRepository?.getStage("Nature Spirit") ?: 0 + val questStage = player?.questRepository?.getStage(Quests.NATURE_SPIRIT) ?: 0 override fun newInstance(player: Player?): DialoguePlugin { return NatureSpiritDialogue(player) } @@ -114,7 +115,7 @@ class NatureSpiritDialogue(player: Player? = null) : DialoguePlugin(player){ //killed all dem buggers bruv 350 -> npcl(FacialExpression.NEUTRAL, "Many thanks my friend, you have completed your quest!").also { stage++ } - 351 -> end().also { player.questRepository.getQuest("Nature Spirit").finish(player) } + 351 -> end().also { player.questRepository.getQuest(Quests.NATURE_SPIRIT).finish(player) } } return true @@ -146,7 +147,7 @@ class NatureSpiritDialogue(player: Player? = null) : DialoguePlugin(player){ if(removeItem(player, Items.SILVER_SICKLE_2961, Container.INVENTORY)){ addItem(player, Items.SILVER_SICKLEB_2963) unlock(player) - player.questRepository.getQuest("Nature Spirit").setStage(player, 70) + player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, 70) openDialogue(player, NPCs.NATURE_SPIRIT_1051, findLocalNPC(player, NPCs.NATURE_SPIRIT_1051) as NPC) sendMessage(player, "Your sickle has been blessed! You can bless a new sickle by dipping it into the grotto waters.") } @@ -158,6 +159,6 @@ class NatureSpiritDialogue(player: Player? = null) : DialoguePlugin(player){ } fun setQuest(stage: Int){ - player!!.questRepository.getQuest("Nature Spirit").setStage(player!!, stage) + player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player!!, stage) } } \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt index 026a4c04e..87d7107b0 100644 --- a/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt @@ -6,9 +6,10 @@ import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills import core.plugin.Initializable import org.rs09.consts.Items +import content.data.Quests @Initializable -class NatureSpiritQuest : Quest("Nature Spirit", 95, 94, 2, 307, 0, 1, 110 ) { +class NatureSpiritQuest : Quest(Quests.NATURE_SPIRIT, 95, 94, 2, 307, 0, 1, 110 ) { override fun newInstance(`object`: Any?): Quest { return this } @@ -16,92 +17,179 @@ class NatureSpiritQuest : Quest("Nature Spirit", 95, 94, 2, 307, 0, 1, 110 ) { override fun drawJournal(player: Player?, stage: Int) { super.drawJournal(player, stage) player ?: return - var line = 11 + var line = 12 if(stage == 0){ - line(player, "I can start this quest by speaking to !!Drezel?? in the !!temple of Saradomin??.", line++) - } else { - if(stage >= 10){ - line(player, "After talking to Drezel in the temple of Saradomin I've",line++, true) - line(player,"agreed to look for a Druid called Filliman Tarlock.", line++, true) + line(player, "I can start this quest by speaking to !!Drezel?? in the temple.", line++) + line(player, /* The "to" is [sic] */"to !!Saradomin?? at the mouth of the river !!Salve??.", line++) + line(player, "I first need to complete :", line++) + line(player, "!!The Restless Ghost.??", line++, isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) + line(player, "!!Priest in Peril.??", line++, isQuestComplete(player, Quests.PRIEST_IN_PERIL)) + if (isQuestComplete(player, Quests.THE_RESTLESS_GHOST) && isQuestComplete(player, Quests.PRIEST_IN_PERIL)) { + line(player, "I've completed all the quest requirements.", line++) } + line(player, "In order to complete this quest !!level 18 crafting?? would be", line++, getStatLevel(player, Skills.CRAFTING) >= 18) + line(player, "an advantage.", line++, getStatLevel(player, Skills.CRAFTING) >= 18) + if (getStatLevel(player, Skills.CRAFTING) >= 18) { + line(player, "I have a suitable crafting level for this quest.", line++) + } + if (isQuestComplete(player, Quests.THE_RESTLESS_GHOST) && isQuestComplete(player, Quests.PRIEST_IN_PERIL) && getStatLevel(player, Skills.CRAFTING) >= 18) { + line(player, "I have all the requirements for this quest.", line++) + } + } else if (stage < 100) { + line(player, "After talking to Drezel in the temple of Saradomin I've", line++, true) + line(player, "agreed to look for a Druid called Filliman Tarlock.", line++, true) - if(stage == 10){ - line(player, "I need to look for !!Filliman Tarlock?? in the !!Swamps?? of Mort",line++) + if (stage >= 15) { + line(player, "I've found a spirit in the swamp which I think might be", line++, true) + line(player, "Filliman Tarlock.", line++, true) + } else if (stage >= 10) { + line(player, "I need to look for !!Filliman Tarlock?? in the !!Swamps?? of Mort", line++) line(player, "Myre. I should be wary of !!Ghasts??.", line++) } - if(stage == 15){ - line(player, "I located a !!spirit?? in the swamp. I believe he's", line++, false) - line(player, "!!Filliman Tarlock?? but I can't understand him.",line++, false) + if (stage >= 20) { + line(player, "I've communicated with Fillman using the amulet of", line++, true) + line(player, "ghostspeak.", line++, true) + } else if (stage >= 15) { + // Questionable + line(player, "I located a !!spirit?? in the swamp. I believe he's", line++) + line(player, "!!Filliman Tarlock?? but I can't understand him.", line++) } - if(stage == 20){ - line(player, "I located !!Filliman Tarlock?? in the swamp. I believe he's",line++) - line(player, "dead but he doesn't believe me. I need to convince him.", line++) + if (stage >= 25) { + line(player, "I managed to convince Fillman that he's a ghost.", line++, true) + } else if (stage >= 20) { + line(player, "I think I need to convince this poor fellow !!Tarlock?? that he's", line++) + line(player, "actually !!dead??!", line++) } - if(stage >= 25){ - line(player, "I located Filliman Tarlock in the swamp and managed to",line++,true) - line(player, "convince him that he is in fact a ghost. ", line++, true) + if (stage >= 30) { + line(player, "Fillman is looking for his journal to help him plan what his", line++, true) + line(player, "next step is.", line++, true) + line(player, "I've given Filliman his journal. I wonder what he plans to do", line++, true) + line(player, "now?", line++, true) + } else if (stage >= 25){ + line(player, "Fillman is looking for his !!journal?? to help him plan what his", line++, true) + line(player, "next step is.", line++, true) + // Questionable +// line(player, "Filliman needs his !!journal?? to figure out what to do",line++) +// line(player, "next. He mentioned something about a !!knot??.", line++) } - if(stage == 25){ - line(player, "Filliman needs his !!journal?? to figure out what to do",line++) - line(player, "next. He mentioned something about a !!knot??.", line++) + if (stage >= 35) { + line(player, "I've agreed to help Fillman become a nature spirit.", line++, true) + line(player, "I need to find 'something from nature', 'something of", line++, true) + line(player, "faith' and 'something of the spirit-to-become freely", line++, true) + line(player, "given'.", line++, true) + } else if (stage >= 30) { + // Derived by squinting hard + line(player, "!!Filliman?? might need !!my help?? with his !!plan??.", line++) + // Questionable +// line(player, "I should speak to !!Filliman Tarlock?? to see what I can", line++) +// line(player, "do to help.", line++) } - if(stage >= 30){ - line(player, "I recovered Filliman's journal for him.", line++, true) + if (stage >= 40) { + line(player, "Filliman gave me a 'bloom' spell to cast in the swamp.", line++, true) + line(player, "With the bloom spell I can collect 'Something of nature.'", line++, true) + line(player, "I've been blessed at the temple by Drezel.", line++, true) + } else if (stage >= 35) { + line(player, "!!Filliman?? gave me a '!!bloom??' spell but I need to be !!blessed?? at", line++) + line(player, "the !!temple?? before I can cast it. I am supposed to collect", line++) + line(player, "'!!something from nature??'.", line++) } - if(stage == 30) { - line(player, "I should speak to !!Filliman Tarlock?? to see what I can",line++) - line(player, "do to help.", line++) + if (stage >= 45) { + // Disappears. + } else if (stage >= 40) { + line(player, "I should return to !!Filliman?? to see what I need to do.", line++) } - if(stage >= 40){ - line(player, "I've gone and gotten blessed by Drezel.", line++, true) + if (stage in 45 until 55){ + if (NSUtils.hasPlacedFungus(player)) { + line(player, "I've cast the bloom spell in the swamp.", line++, true) + line(player, "I collected a Mort Myre Fungi.", line++, true) + line(player, "I think I have collected 'something of nature'.", line++, true) + } else if (inInventory(player, Items.MORT_MYRE_FUNGUS_2970)) { + line(player, "I've cast the bloom spell in the swamp.", line++, true) + line(player, "I collected a Mort Myre Fungi.", line++, true) + line(player, "I have a !!Mort Myre Fungi??, I hope this is what !!Fillman??",line++) + line(player, "wanted.",line++) + } else { + // Questionable +// if(stage == 50){ +// line(player, "I know for a fact the fungus is !!something of Nature??.", line++, false) +// } + line(player, "I need to collect '!!something of nature??'.", line++) + } + + // Just stand on the damn thing. + line(player, "I need to find '!!something with faith??'.",line++, false) + + if (NSUtils.hasPlacedCard(player)) { + line(player, "The spell scroll was absorbed into the spirit stone I think I", line++, true) + line(player, "have collected 'something of spirit-to-become freely", line++, true) + line(player, "given.'", line++, true) + } else { + line(player, "I need to find :",line++) + line(player, "'!!something of the spirit-to-be freely given??.'", line++) + } } - if(stage >= 35) { - line(player, "I've agreed to help Filliman become a Nature Spirit.",line++, true) + if (stage >= 55) { + line(player, "I managed to get all the required items that Fillman asked.", line++, true) + line(player, "for. He says that he can cast the spell now which will", line++, true) + line(player, "transform him into a Nature Spirit.", line++, true) } - if(stage == 35){ - line(player, "The first thing Filliman needs me to do is go and get",line++) - line(player, "blessed by !!Drezel?? in the temple of Saradomin.",line++) + if (stage >= 60) { + line(player, "I entered Fillimans grotto as he asked me to.", line++, true) // no apostrophe is sic + line(player, "Filliman has turned into a nature spirit, it was an", line++, true) + line(player, "impressive transformation!", line++, true) + line(player, "Filliman says he can help me to defeat the ghasts.", line++, true) + } else if (stage >= 55) { + // Questionable + line(player, "!!Filliman?? has asked me to enter his !!grotto??.", line++) } - if (stage == 40){ - line(player, "I should return to !!Filliman?? to see what I need to do.", line++, false) + if (stage >= 70) { + line(player, "Filliman has blessed the silver sickle for me.", line++, true) + // --- Should be separate stage, but we don't have it. + // line(player, "I need to use the !!sickle?? to make the swamp bloom.", line++) + line(player, "I cast the bloom spell in the swamp.", line++, true) + // --- Should be separate stage, but we don't have it. + // line(player, "I need to collect some !!bloomed items?? from the swamp", line++) + // line(player, "and put them into a druid pouch.", line++) + line(player, "I collected some bloomed items from the swamp an put", line++, true) + line(player, "them into a druid pouch.", line++, true) + } else if (stage >= 60) { + // Questionable + line(player, "I need to bring a silver sickle for !!Filliman?? to bless.", line++) } - - if(stage in 45 until 55){ - line(player, "In order to help Filliman I need to find 3 things:", line++, false) - line(player, "Something of !!Faith??.",line++, false) - line(player, "Something of !!Nature??.", line++, stage >= 50) - line(player, "Something of the !!spirit-to-be freely given??.", line++, false) - } - - if(stage == 50){ - line(player, "I know for a fact the fungus is !!something of Nature??.", line++, false) - } - - if(stage >= 55){ - line(player, "I've helped Filliman complete the spell.", line++, true) - } - - if(stage == 55){ - line(player, "Filliman has asked me to meet him back inside the !!grotto??.", line++, false) - } - - if(stage == 75){ - line(player, "I need to go and kill !!3 Ghasts?? for Filliman.", line++, false) - } - - if(stage >= 100){ - line(player,"%%QUEST COMPLETE!&&",line++) + // We don't have this stage. +// if (stage >= 80) { +// line(player, "The druid pouch made a ghast appear which I attacked and", line++, true) +// line(player, "killed.", line++, true) +// line(player, "I've killed two ghasts now.", line++, true) +// line(player, "I've killed three ghasts now.", line++, true) +// line(player, "I should tell !!Filliman?? that I've killed the !!three ghasts??.", line++, true) +// } else + if (stage >= 75){ + line(player, "!!Filliman?? asked me to kill !!three Ghasts??.", line++, false) } + } else { + // The final text is a summary of the quest. + line(player, "Drezel, a priest of Saradomin, asked me to look for the", line++, true) + line(player, "druid Filliman Tarlock in the swamps of Mort Myre. However", line++, true) + line(player, "Filliman had been slain and appeared as a ghost. After", line++, true) + line(player, "persuading Filliman that he was in fact dead I helped him to", line++, true) + line(player, "make a transformation into a Nature Spirit.", line++, true) + line++ + line(player, "In return for this help Filliman blessed a silver sickle and", line++, true) + line(player, "showed me how to defeat the ghasts of Mort Myre.", line++, true) + line(player, "He also gave me some kill experience in crafting,", line++, true) + line(player, "hitpoints and defence.", line++, true) + line(player, "%%QUEST COMPLETE!&&",line++) } } diff --git a/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java b/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java index 844cc01c2..b8d7628f1 100644 --- a/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java +++ b/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java @@ -6,6 +6,7 @@ import core.plugin.Initializable; import core.game.node.entity.player.Player; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles the quarter master dialogue. @@ -42,7 +43,7 @@ public final class QuarterMasterDialogue extends DialoguePlugin { public boolean open(Object... args) { npc = (NPC) args[0]; npc("Hi, would you like to see my wares?"); - if (!hasRequirement(player, "Regicide")) { + if (!hasRequirement(player, Quests.REGICIDE)) { end(); return true; } diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java index 283f98467..67b9ddad7 100644 --- a/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import org.rs09.consts.Items; +import content.data.Quests; /** * Handles Eluned's Dialogue for Roving Elves. @@ -28,7 +29,7 @@ public class ElunedDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Roving Elves"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); switch (stage) { case 500: end(); @@ -180,7 +181,7 @@ public class ElunedDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - final Quest quest = player.getQuestRepository().getQuest("Roving Elves"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); if (quest.getStage(player) == 10) { interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hey there... Islwyn said you may be able to help me.", "He told me you know how to consecrate ground for an", "elven burial. I need to reconsecrate Glarial's resting", "place."); stage = 1; diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java index b24862a1f..2d111e7cd 100644 --- a/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; +import content.data.Quests; /** * Handles Islwyn's dialogue for Roving Elves. @@ -29,7 +30,7 @@ public class IslwynDialogue extends DialoguePlugin { @Override public boolean handle(int interfaceId, int buttonId) { - final Quest quest = player.getQuestRepository().getQuest("Roving Elves"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); switch (stage) { case 500: end(); @@ -171,7 +172,7 @@ public class IslwynDialogue extends DialoguePlugin { stage = 21; break; case 21: - interpreter.sendDoubleItemMessage(RovingElves.CRYSTAL_BOW_FULL, RovingElves.CRYSTAL_SHIELD_FULL, "Islwyn shows you a crystal bow and a crystal shield."); + interpreter.sendDoubleItemMessage(RovingElves.CRYSTAL_BOW_FULL.getId(), RovingElves.CRYSTAL_SHIELD_FULL.getId(), "Islwyn shows you a crystal bow and a crystal shield."); stage = 22; break; case 22: @@ -355,8 +356,8 @@ public class IslwynDialogue extends DialoguePlugin { @Override public boolean open(Object... args) { - final Quest quest = player.getQuestRepository().getQuest("Roving Elves"); - final Quest waterfall = player.getQuestRepository().getQuest("Waterfall"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + final Quest waterfall = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); if (quest.getStage(player) == 0 && waterfall.isCompleted(player)) { interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); stage = 0; diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java index 842f3cc9b..82685174f 100644 --- a/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java @@ -13,6 +13,7 @@ import core.game.node.item.Item; import core.game.world.map.Location; import core.plugin.Plugin; import core.plugin.ClassScanner; +import content.data.Quests; /** * The level 84 Moss Giant in Glarial's tomb. @@ -47,7 +48,7 @@ public final class MossGiantGuardianNPC extends AbstractNPC { super.finalizeDeath(killer); if (killer instanceof Player) { final Player player = (Player) killer; - final Quest quest = player.getQuestRepository().getQuest("Roving Elves"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); if (quest.getStage(player) == 15 && !player.getInventory().contains(RovingElves.CONSECRATION_SEED.getId(), 1)) { player.getPacketDispatch().sendMessages("A small grey seed drops on the ground."); GroundItemManager.create(new Item(RovingElves.CONSECRATION_SEED.getId()), getLocation(), player); diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java index 52546a877..91d68130e 100644 --- a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java @@ -6,6 +6,7 @@ import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.Initializable; import core.plugin.ClassScanner; +import content.data.Quests; /** * The Roving Elves quest. @@ -43,7 +44,7 @@ public class RovingElves extends Quest { * Constructs a new {@Code RovingElves} {@Code Object} */ public RovingElves() { - super("Roving Elves", 105, 104, 1, 402, 0, 1, 6); + super(Quests.ROVING_ELVES, 105, 104, 1, 402, 0, 1, 6); } @Override diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java index e24874c99..144b624c1 100644 --- a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.List; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles all the agility obstacles for Roving Elves. @@ -96,7 +97,7 @@ public final class RovingElvesObstacles extends OptionHandler { switch (node.getId()) { case 8742: - if (!hasRequirement(player, "Mourning's End Part I")) + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I)) return true; player.teleport(player.getLocation().transform(EAST_WEST, 2)); break; diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java index 243e4823a..38616e8d4 100644 --- a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java @@ -12,6 +12,7 @@ import core.game.world.GameWorld; import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; import core.plugin.Plugin; +import content.data.Quests; /** * Master plugin file for Roving Elves. @@ -39,7 +40,7 @@ public final class RovingElvesPlugin extends OptionHandler { @SuppressWarnings("static-access") @Override public boolean handle(final Player player, Node node, String option) { - final Quest quest = player.getQuestRepository().getQuest("Roving Elves"); + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); if (quest == null) { player.sendMessage("Error! RovingElves quest cannot be found, please contact an admin!"); return true; diff --git a/Server/src/main/content/region/wilderness/handlers/BorkNPC.java b/Server/src/main/content/region/wilderness/handlers/BorkNPC.java index 1b603410b..53bd862e5 100644 --- a/Server/src/main/content/region/wilderness/handlers/BorkNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/BorkNPC.java @@ -118,7 +118,7 @@ public class BorkNPC extends AbstractNPC { @Override public void finalizeDeath(Entity killer){ super.finalizeDeath(killer); - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); } @Override @@ -532,6 +532,7 @@ public class BorkNPC extends AbstractNPC { public void configure() { region = DynamicRegion.create(12374); region.setMulticombat(true); + region.setMusicId(488); setRegionBase(); registerRegion(region.getId()); } diff --git a/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java b/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java index 4da67fe93..9e4f6f758 100644 --- a/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java @@ -82,7 +82,7 @@ public class ChaosElementalNPC extends AbstractNPC { @Override public void finalizeDeath(Entity killer) { super.finalizeDeath(killer); - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); } /** diff --git a/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java b/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java index e25b2405e..6d1f06cfc 100644 --- a/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java +++ b/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java @@ -28,6 +28,7 @@ import core.plugin.ClassScanner; import core.tools.RandomFunction; import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; /** * Handles the chaos tunnels. @@ -233,7 +234,7 @@ public final class ChaosTunnelZone extends MapZone implements Plugin { */ private void teleport(Player player, Scenery object) { if (object.getLocation().getX() == 3142 && object.getLocation().getY() == 5545) { - if (hasRequirement(player, "What Lies Below")) + if (hasRequirement(player, Quests.WHAT_LIES_BELOW)) commenceBorkBattle(player); return; } @@ -266,7 +267,7 @@ public final class ChaosTunnelZone extends MapZone implements Plugin { * @param player The player. */ private void commenceBorkBattle(Player player) { - if (ServerStore.getBoolean(getStoreFile(), player.getUsername().toLowerCase()) && GameWorld.getSettings().isHosted()) { + if (ServerStore.getBoolean(getStoreFile(), player.getUsername().toLowerCase(), false) && GameWorld.getSettings().isHosted()) { player.getPacketDispatch().sendMessage("The portal's magic is too weak to teleport you right now."); return; } diff --git a/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java b/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java index ea1849876..0b71e76e6 100644 --- a/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java @@ -2,15 +2,11 @@ package content.region.wilderness.handlers; import content.data.BossKillCounter; import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.combat.CombatStyle; -import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.*; import core.game.node.entity.combat.ImpactHandler.HitsplatType; -import core.game.node.entity.combat.MultiSwingHandler; import core.game.node.entity.combat.equipment.SwitchAttack; import core.game.node.entity.combat.equipment.Weapon; import core.game.node.entity.impl.Projectile; -import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.npc.NPC; import core.game.node.entity.npc.NPCBehavior; import core.game.node.entity.player.Player; @@ -22,7 +18,6 @@ import core.game.world.map.RegionManager; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable; -import core.plugin.Plugin; import core.tools.RandomFunction; import org.rs09.consts.NPCs; @@ -32,7 +27,6 @@ import java.util.List; /** * Handles the Corporeal beast NPC. * @author Emperor - * */ @Initializable public final class CorporealBeastNPC extends NPCBehavior { @@ -41,19 +35,24 @@ public final class CorporealBeastNPC extends NPCBehavior { * The combat handler. */ private final MultiSwingHandler combatHandler = new CombatHandler(); - + /** * The dark energy core NPC. */ public NPC darkEnergyCore; - + + /** + * Whether to force a dark core spawn roll on our next swing (only done if we just got hit >= 32 damage). + */ + public boolean forceCoreRoll = false; + /** * Constructs a new {@code CorporealBeastNPC} {@code Object}. */ public CorporealBeastNPC() { - super(new int[]{NPCs.CORPOREAL_BEAST_8133}); + super(new int[] { NPCs.CORPOREAL_BEAST_8133 }); } - + @Override public void onCreation(NPC self) { self.configureBossData(); @@ -64,71 +63,80 @@ public final class CorporealBeastNPC extends NPCBehavior { return combatHandler; } - @Override - public void beforeDamageReceived(NPC self, Entity attacker, BattleState state) { - if(state.getStyle() == CombatStyle.MELEE || state.getStyle() == CombatStyle.RANGE) { - Weapon w = state.getWeapon(); - String name = w != null ? w.getName() : ""; - if(w == null || name.toLowerCase().indexOf("spear") == -1) { - if(state.getEstimatedHit() > 0) { - state.setEstimatedHit(state.getEstimatedHit()/2); - } - if(state.getSecondaryHit() > 0) { - state.setSecondaryHit(state.getSecondaryHit()/2); - } - } - } - if(state.getEstimatedHit() > 100) { - state.setEstimatedHit(100); - } - if(state.getSecondaryHit() > 100) { - state.setSecondaryHit(100); - } - } + @Override + public void beforeDamageReceived(NPC self, Entity attacker, BattleState state) { + if (state.getStyle() == CombatStyle.MELEE || state.getStyle() == CombatStyle.RANGE) { + Weapon w = state.getWeapon(); + String name = w != null ? w.getName() : ""; + if (w == null || name.toLowerCase().indexOf("spear") == -1) { + if (state.getEstimatedHit() > 0) { + state.setEstimatedHit(state.getEstimatedHit() / 2); + } + if (state.getSecondaryHit() > 0) { + state.setSecondaryHit(state.getSecondaryHit() / 2); + } + } + } + if (state.getEstimatedHit() >= 32) { + CorporealBeastNPC corp = (CorporealBeastNPC) self.behavior; + corp.forceCoreRoll = true; + } + if (state.getEstimatedHit() > 100) { + state.setEstimatedHit(100); + } + if (state.getSecondaryHit() > 100) { + state.setSecondaryHit(100); + } + } @Override public void onDeathFinished(NPC self, Entity killer) { - BossKillCounter.addtoKillcount((Player) killer, NPCs.CORPOREAL_BEAST_8133); + BossKillCounter.addToBossKillCount((Player) killer, NPCs.CORPOREAL_BEAST_8133); if (darkEnergyCore != null) { darkEnergyCore.clear(); darkEnergyCore = null; } } - + /** * Handles the Corporeal beast's combat. * @author Emperor - * */ static class CombatHandler extends MultiSwingHandler { - /** * Constructs a new {@code CombatHandler} {@code Object}. */ public CombatHandler() { super( - //Melee (crush) - new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10057)).setMaximumHit(52), - //Melee (slash) - new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10058)).setMaximumHit(51), - //Magic (drain skill) - new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1823, 60, 36, 41, 46)).setMaximumHit(55), - //Magic (location based) - new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1824, 60, 36, 41, 46)).setMaximumHit(42), - //Magic (hit through prayer) - new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1825, 60, 36, 41, 46)).setMaximumHit(66) - ); + //Melee (crush) + new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10057)).setMaximumHit(51), + //Melee (slash) + new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10058)).setMaximumHit(51), + //Magic (drain skill, blocked by prayer) + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1823, 60, 36, 41, 46)).setMaximumHit(55), + //Magic (location-based, hits through prayer) + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1824, 60, 36, 41, 46)).setMaximumHit(42), + //Magic (hits through prayer) + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1825, 60, 36, 41, 46)).setMaximumHit(65) + ); } @Override public int swing(Entity entity, Entity victim, BattleState state) { - spawnDarkCore(entity, (CorporealBeastNPC)((NPC) entity).behavior, victim); + // If we're below the right HP threshold, roll a chance to spawn the dark core + CorporealBeastNPC corp = (CorporealBeastNPC) ((NPC) entity).behavior; + double thresh = entity.getSkills().getMaximumLifepoints() * (0.3 + (entity.getViewport().getCurrentPlane().getPlayers().size() * 0.05)); + if (corp.forceCoreRoll || entity.getSkills().getLifepoints() < thresh) { + rollDarkCore(entity, corp, victim); + corp.forceCoreRoll = false; + } + // If we can stomp, do that for our turn if (doStompAttack(entity)) { entity.getProperties().getCombatPulse().setNextAttack(entity.getProperties().getAttackSpeed()); return -1; } - //Location based attack. + // Location-based attack. if (super.getNext().getProjectile() != null && super.getNext().getProjectile().getProjectileId() == 1824) { setCurrent(getNext()); CombatStyle style = getCurrent().getStyle(); @@ -142,18 +150,17 @@ public final class CorporealBeastNPC extends NPCBehavior { } return super.swing(entity, victim, state); } - + /** - * Spawns a dark core. + * Rolls a 1/8 chance to spawn a dark core. * @param npc The corporeal beast NPC. * @param victim The victim. */ - private void spawnDarkCore(Entity corp, final CorporealBeastNPC npc, Entity victim) { - if (npc.darkEnergyCore != null && npc.darkEnergyCore.isActive()) { + private void rollDarkCore(Entity corp, final CorporealBeastNPC npc, Entity victim) { + if (npc.darkEnergyCore != null && npc.darkEnergyCore.isActive() && !DeathTask.isDead(npc.darkEnergyCore)) { return; } - double max = corp.getSkills().getMaximumLifepoints() * (0.3 + (corp.getViewport().getCurrentPlane().getPlayers().size() * 0.05)); - if (corp.getSkills().getLifepoints() > max) { + if (!RandomFunction.roll(8)) { return; } Location l = RegionManager.getTeleportLocation(victim.getLocation(), 3); @@ -163,8 +170,8 @@ public final class CorporealBeastNPC extends NPCBehavior { GameWorld.getPulser().submit(new Pulse(2, corp) { @Override public boolean pulse() { - if (npc.darkEnergyCore == null) - return true; + if (npc.darkEnergyCore == null) + return true; npc.darkEnergyCore.init(); return true; } @@ -184,6 +191,7 @@ public final class CorporealBeastNPC extends NPCBehavior { boolean secondStage = false; List players = RegionManager.getLocalPlayers(entity); Location[] locations = null; + @Override public boolean pulse() { if (!secondStage) { @@ -215,11 +223,14 @@ public final class CorporealBeastNPC extends NPCBehavior { locations = null; return true; } + private void hit(Player p) { - int max = p.hasProtectionPrayer(CombatStyle.MAGIC) ? 13 : 42; int hit = 0; if (isAccurateImpact(entity, p)) { - hit = RandomFunction.random(max); + hit = RandomFunction.random(42); + if (p.hasProtectionPrayer(CombatStyle.MAGIC)) { + hit = (int) (hit * 0.6); + } } p.getImpactHandler().handleImpact(entity, hit, CombatStyle.MAGIC); } @@ -252,7 +263,7 @@ public final class CorporealBeastNPC extends NPCBehavior { } return false; } - + @Override public void adjustBattleState(Entity entity, Entity victim, BattleState state) { super.adjustBattleState(entity, victim, state); @@ -262,10 +273,9 @@ public final class CorporealBeastNPC extends NPCBehavior { int skill = random == 0 ? Skills.PRAYER : random == 1 ? Skills.MAGIC : Skills.SUMMONING; int drain = 1 + RandomFunction.random(6); if ((skill == Skills.PRAYER ? victim.getSkills().getPrayerPoints() : victim.getSkills().getLevel(skill)) < 1) { - victim.getImpactHandler().manualHit(entity, drain, HitsplatType.NORMAL,2); + victim.getImpactHandler().manualHit(entity, drain, HitsplatType.NORMAL, 2); ((Player) victim).getPacketDispatch().sendMessage("Your Hitpoints have been slightly drained!"); - } - else { + } else { if (skill == Skills.PRAYER) { victim.getSkills().decrementPrayerPoints(drain); } else { @@ -278,11 +288,13 @@ public final class CorporealBeastNPC extends NPCBehavior { } } } - + @Override protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) { if (getCurrent().getProjectile() == null || getCurrent().getProjectile().getProjectileId() != 1825) { hit = (int) entity.getFormattedHit(state, hit); + } else if (victim.hasProtectionPrayer(CombatStyle.MAGIC)) { + hit = (int) (hit * 0.6); } return formatHit(victim, hit); } diff --git a/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt b/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt index 83b64acc2..5568d5460 100644 --- a/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt +++ b/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt @@ -5,6 +5,7 @@ import core.game.node.entity.player.Player import core.game.interaction.InterfaceListener import core.game.world.GameWorld import core.api.* +import content.data.Quests /** * Handles the corporeal beast warning interface @@ -16,7 +17,7 @@ class CorporealBeastWarningInterface : InterfaceListener { override fun defineInterfaceListeners() { on(COMPONENT_ID,17){player,component,_,_,_,_ -> - if (!hasRequirement(player, "Summer's End")) + if (!hasRequirement(player, Quests.SUMMERS_END)) return@on true if(player.getAttribute("corp-beast-cave-delay",0) <= GameWorld.ticks) { player.properties.teleportLocation = player.location.transform(4, 0, 0).also { close(player,component) } diff --git a/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java b/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java index bcc8930cd..0695955ba 100644 --- a/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java @@ -9,6 +9,8 @@ import core.game.node.entity.player.Player; import core.game.system.task.Pulse; import core.game.world.GameWorld; import core.game.world.map.Location; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; import core.plugin.Initializable; import core.tools.RandomFunction; @@ -16,8 +18,7 @@ import static core.api.ContentAPIKt.*; /** * Handles the Dark Energy Core NPC. - * @author Emperor - * + * @author Emperor, Player Name */ @Initializable public final class DarkEnergyCoreNPC extends AbstractNPC { @@ -31,21 +32,22 @@ public final class DarkEnergyCoreNPC extends AbstractNPC { * The amount of ticks. */ private int ticks = 0; - + /** * The amount of failed attacks. */ private int fails = 0; - + /** * Constructs a new {@code DarkEnergyCoreNPC} {@code Object}. */ public DarkEnergyCoreNPC() { this(8127, null); } - + /** * Constructs a new {@code DarkEnergyCoreNPC} {@code Object}. + * * @param id The NPC id. * @param location The location. */ @@ -59,14 +61,15 @@ public final class DarkEnergyCoreNPC extends AbstractNPC { if (objects.length > 0) { core.master = (NPC) objects[0]; } + core.setRespawn(false); return core; } - + @Override public boolean canStartCombat(Entity victim) { return false; //No combat needed. } - + @Override public void handleTickActions() { ticks++; @@ -91,8 +94,11 @@ public final class DarkEnergyCoreNPC extends AbstractNPC { if (jump) { Entity victim = master.getProperties().getCombatPulse().getVictim(); if (++fails >= 3 && victim != null && victim.getViewport().getCurrentPlane() == getViewport().getCurrentPlane()) { - jump(victim.getLocation()); - fails = 0; + Path path = Pathfinder.find(getLocation(), victim.getLocation(), 1); + if (path.isSuccessful() || !path.isMoveNear()) { + jump(victim.getLocation()); + fails = 0; + } } } else { fails = 0; @@ -119,7 +125,6 @@ public final class DarkEnergyCoreNPC extends AbstractNPC { @Override public int[] getIds() { - return new int[] { 8127 }; + return new int[]{8127}; } - } diff --git a/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt b/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt deleted file mode 100644 index 929375a65..000000000 --- a/Server/src/main/content/region/wilderness/handlers/DeepWildyThreat.kt +++ /dev/null @@ -1,152 +0,0 @@ -package content.region.wilderness.handlers - -import content.region.wilderness.handlers.revenants.RevenantController -import content.region.wilderness.handlers.revenants.RevenantNPC -import content.region.wilderness.handlers.revenants.RevenantType -import core.api.* -import core.game.node.entity.Entity -import core.game.node.entity.combat.CombatStyle -import core.game.node.entity.combat.DeathTask -import core.game.node.entity.npc.NPC -import core.game.node.entity.npc.NPCBehavior -import core.game.node.entity.player.Player -import core.game.node.item.Item -import core.game.system.command.Privilege -import core.game.system.timer.PersistTimer -import core.game.system.timer.impl.Disease -import core.game.world.map.path.Pathfinder -import core.game.world.map.zone.impl.WildernessZone -import core.game.world.update.flag.context.Graphics -import core.tools.RandomFunction -import core.tools.colorize -import org.json.simple.JSONObject - -object DeepWildyThreat { - @JvmStatic fun getThreat (player: Player) : Int { - return getOrStartTimer(player).ticksLeft - } - - @JvmStatic fun adjustThreat (player: Player, amount: Int) { - val timer = getOrStartTimer(player) - timer.ticksLeft += amount - if (timer.ticksLeft >= 2500 && timer.lastMessage < 2000) { - sendMessage(player, colorize("%RYou sense a great wrath upon you.")) - timer.lastMessage = 2000 - } else if (timer.ticksLeft >= 1000 && timer.lastMessage < 1000) { - sendMessage(player, colorize("%RYou sense watchful eyes upon you.")) - timer.lastMessage = 1000 - } else if (timer.ticksLeft >= 500 && timer.lastMessage < 500) { - sendMessage(player, colorize("%RYou sense a dark presence.")) - timer.lastMessage = 500 - } - } -} - -class DWThreatTimer : PersistTimer(1, "dw-threat"), Commands { - var ticksLeft = 0 - var lastMessage = 0 - var currentRev: NPC? = null - var forceSpawn = false - - override fun run(entity: Entity): Boolean { - if (ticksLeft-- <= 0) return false - if (ticksLeft > 3000) ticksLeft = 3000 - if (ticksLeft % 5 != 0) return true - if (entity !is Player) return false - if (!entity.skullManager.isWilderness) return true - - val rollchance = - if (ticksLeft >= 2500) 10 - else if (ticksLeft >= 2000) 200 - else if (ticksLeft >= 1500) 400 - else if (ticksLeft >= 1000) 800 - else if (ticksLeft >= 500) 1500 - else 2_000_000 - - if ((currentRev == null || DeathTask.isDead(currentRev) || !currentRev!!.isActive) && (forceSpawn || RandomFunction.roll(rollchance))) { - forceSpawn = false - val type = RevenantType.getClosestHigherOrEqual(entity.properties.currentCombatLevel) - val npc = NPC.create(type.ids.random(), entity.location) - npc.isRespawn = false - npc.behavior = RevGuardianBehavior() - npc.init() - npc.setAttribute("dw-threat-target", entity) - RevenantController.unregisterRevenant(npc as RevenantNPC, false) - currentRev = npc - } else if (currentRev != null && !currentRev!!.location.withinDistance(entity.location, 25) && currentRev!!.properties.teleportLocation == null) { - poofClear(currentRev!!) - currentRev = null - } - - return true - } - - override fun save(root: JSONObject, entity: Entity) { - root["threat-time-remaining"] = ticksLeft.toString() - root["threat-forceSpawn"] = (currentRev != null).toString() - } - - override fun parse(root: JSONObject, entity: Entity) { - ticksLeft = root["threat-time-remaining"]?.toString()?.toIntOrNull() ?: 0 - forceSpawn = root["threat-forceSpawn"]?.toString()?.toBoolean() ?: false - } - - override fun defineCommands() { - define("dwthreat", Privilege.ADMIN, "", "") {player, _ -> - val timer = getOrStartTimer(player) - notify(player, "Current Threat: ${timer.ticksLeft}") - } - } -} - -class RevGuardianBehavior : NPCBehavior() { - val deathMessages = arrayOf("Curses upon thee!", "Rot in blight!", "Suffer my wrath!", "Nevermore!", "May ye be undone!") - var chats = arrayOf("Leave this place!", "Suffer!", "Death to thee!", "Flee, coward!", "Leave my resting place!", "Let me rest in peace!", "Thou belongeth to me!") - - override fun tick(self: NPC): Boolean { - val target = getAttribute(self, "dw-threat-target", null) ?: return true - if (!target.isActive || DeathTask.isDead(target)) { - self.clear() - return true - } - if (target.properties.teleportLocation != null && self.properties.teleportLocation == null) { - if (WildernessZone.isInZone(target.properties.teleportLocation)) - self.properties.teleportLocation = target.properties.teleportLocation - } - self.attack(target) - return true - } - - override fun onCreation(self: NPC) { - Graphics.send(Graphics(86), self.location) - sendChat(self, chats.random()) - } - - override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { - val target = getAttribute(self, "dw-threat-target", null) - if (attacker != target) { - if (shouldSendMessage && attacker is Player) - sendMessage(attacker, "This revenant is focused on someone else.") - return false - } - return super.canBeAttackedBy(self, attacker, style, shouldSendMessage) - } - - override fun onDeathStarted(self: NPC, killer: Entity) { - val target = getAttribute(self, "dw-threat-target", null) ?: return - sendChat(self, deathMessages.random()) - val disease = getOrStartTimer(target, 25) - disease.hitsLeft = 25 - } - - override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { - val target = getAttribute(self, "dw-threat-target", null) ?: return - if (killer != target) drops.clear() - val timer = getOrStartTimer(target) - timer.ticksLeft = 0 - } - - override fun getPathfinderOverride(self: NPC): Pathfinder? { - return Pathfinder.SMART - } -} diff --git a/Server/src/main/content/region/wilderness/handlers/KingBlackDragonArea.kt b/Server/src/main/content/region/wilderness/handlers/KingBlackDragonArea.kt new file mode 100644 index 000000000..7940a2468 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/KingBlackDragonArea.kt @@ -0,0 +1,14 @@ +package content.region.wilderness.handlers + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class KingBlackDragonArea : MapArea { + override fun defineAreaBorders() : Array { + return arrayOf(ZoneBorders(2256, 4680, 2287, 4711, 0, true)) + } + override fun getRestrictions() : Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java b/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java index ab5559616..75f8a94de 100644 --- a/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java @@ -14,6 +14,7 @@ import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import core.game.world.GameWorld; import core.game.world.map.Location; import core.game.world.update.flag.context.Animation; import core.plugin.Initializable; @@ -48,7 +49,7 @@ public final class KingBlackDragonNPC extends AbstractNPC { @Override public void finalizeDeath(Entity killer) { super.finalizeDeath(killer); - BossKillCounter.addtoKillcount((Player) killer, this.getId()); + BossKillCounter.addToBossKillCount((Player) killer, this.getId()); } /** @@ -127,7 +128,6 @@ public final class KingBlackDragonNPC extends AbstractNPC { @Override public void adjustBattleState(Entity entity, Entity victim, BattleState state) { if (style == CombatStyle.RANGE) { - fireType.getTask().exec(victim, entity); state.setStyle(null); DRAGONFIRE.adjustBattleState(entity, victim, state); state.setStyle(CombatStyle.RANGE); @@ -184,6 +184,9 @@ public final class KingBlackDragonNPC extends AbstractNPC { @Override public void impact(Entity entity, Entity victim, BattleState state) { + if (style != CombatStyle.MELEE && victim.getImpactHandler().getDisabledTicks() <= GameWorld.getTicks()) { + fireType.getTask().exec(victim, entity); + } style.getSwingHandler().impact(entity, victim, state); } diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessAreaZone.java b/Server/src/main/content/region/wilderness/handlers/WildernessAreaZone.java deleted file mode 100644 index acf3727c6..000000000 --- a/Server/src/main/content/region/wilderness/handlers/WildernessAreaZone.java +++ /dev/null @@ -1,575 +0,0 @@ -package content.region.wilderness.handlers; - -import core.game.dialogue.DialogueAction; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.global.action.DoorActionHandler; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.gather.SkillingResource; -import content.data.skill.SkillingTool; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.Option; -import core.game.interaction.UseWithHandler; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.npc.AbstractNPC; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.map.zone.MapZone; -import core.game.world.map.zone.ZoneBorders; -import core.game.world.map.zone.ZoneBuilder; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.plugin.ClassScanner; - -import java.util.ArrayList; -import java.util.List; - -/** - * Handles the Wilderness Area Zone. - * @author Empathy - * @author Vexia - * - */ -@Initializable -public class WildernessAreaZone extends MapZone implements Plugin { - - /** - * The list of players in the arena. - */ - private final List players = new ArrayList<>(20); - - /** - * Constructs a new {@code WildernessAreaZone} {@code Object} - */ - public WildernessAreaZone() { - super("Wilderness Area Zone", true); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ZoneBuilder.configure(this); - ClassScanner.definePlugins(new MandrithDialoguePlugin(), new PilesDialoguePlugin(), new PilesItemHandler(), new RuniteGolemNPC()); - return this; - } - - @Override - public boolean interact(Entity e, final Node node, Option option) { - if (e instanceof Player) { - Player player = e.asPlayer(); - switch (node.getId()) { - case 42044: - switch (option.getName()) { - case "Open": - if (player.getLocation().equals(Location.create(3184, 3945, 0))) { - if (player.getInventory().contains(995, 7500)) { - player.getDialogueInterpreter().sendOptions("Pay 7500 coins?", "Yes", "No"); - player.getDialogueInterpreter().addAction(new DialogueAction() { - - @Override - public void handle(Player player, int buttonId) { - switch (buttonId) { - case 2: - if (player.getInventory().remove(new Item(995, 7500))) { - DoorActionHandler.handleDoor(player, node.asScenery()); - player.sendMessage("You pay 7500 coins and enter the resource arena."); - } - break; - } - } - - }); - return true; - } - player.sendMessage("You do not have enough coins to enter the Arena."); - return true; - } - DoorActionHandler.handleDoor(player, node.asScenery()); - return true; - case "Players-inside": - if (player.getLocation().getY() < 3495) { - player.sendMessage("All you see is the barren wasteland of the Wilderness."); - return true; - } - String message = "You peek inside the gate and see no adventurers inside the arena."; - if (players.size() > 0) { - message = players.size() == 1 ? "You peek inside the gate and see 1 adventurer inside the arena." : "You peek inside the gate and see " + players.size() + " inside the arena."; - } - player.getDialogueInterpreter().sendDialogue(message); - break; - } - break; - case 8666: - switch (option.getName()) { - case "Mine": - player.getPulseManager().run(new RuniteGolemMinePulse(player, node.asNpc())); - return true; - case "Prospect": - player.sendMessages("You examine the rock for ores...", "This rock contains runite ore."); - return true; - } - break; - } - } - return super.interact(e, node, option); - } - - @Override - public Object fireEvent(String identifier, Object... args) { - return null; - } - - @Override - public void configure() { - register(new ZoneBorders(3174, 3924, 3196, 3945)); - } - - @Override - public boolean enter(Entity e) { - if (e instanceof Player) { - Player p = e.asPlayer(); - players.add(p); - } - return super.enter(e); - } - - @SuppressWarnings("deprecation") - @Override - public boolean leave(Entity e, boolean logout) { - if (e instanceof Player) { - Player p = e.asPlayer(); - players.remove(p); - if (logout && p.getLocation().getY() <= 3944) { - p.setLocation(Location.create(3184, 3945, 0)); - return true; - } - } - return super.leave(e, logout); - } - - /** - * The mining of a runite golem. - * @author Vexia - * - */ - public class RuniteGolemMinePulse extends SkillPulse { - - /** - * The skilling tool used. - */ - private SkillingTool tool; - - /** - * The ticks. - */ - private int ticks; - - /** - * Constructs a new @{Code RuniteGolemMinePulse} object. - * @param player The player. - * @param node The node. - */ - public RuniteGolemMinePulse(Player player, NPC node) { - super(player, node); - } - - @Override - public void start() { - resource = SkillingResource.RUNITE_ORE_0; - if (node.getId() != 8666) { - player.getPacketDispatch().sendMessage("This rock contains no ore."); - return; - } - if (resource == null) { - return; - } - super.start(); - } - - - @Override - public boolean checkRequirements() { - if (node.getId() != 8666) { - return false; - } - if (player.getSkills().getLevel(resource.getSkillId()) < resource.getLevel()) { - player.getPacketDispatch().sendMessage("You need a " + Skills.SKILL_NAME[resource.getSkillId()] + " level of " + resource.getLevel() + " to mine this rock."); - return false; - } - if ((tool = SkillingTool.getPickaxe(player)) == null) { - player.getPacketDispatch().sendMessage("You do not have a pickaxe to use."); - return false; - } - if (player.getInventory().freeSlots() < 1) { - player.getDialogueInterpreter().sendDialogue("Your inventory is too full to hold any more runite ore."); - return false; - } - return true; - } - - @Override - public void animate() { - if (tool != null) { - player.animate(tool.getAnimation()); - } - } - - @Override - public boolean reward() { - if (++ticks % 4 != 0) { - return false; - } - if (!checkReward()) { - return false; - } - node.transform(8667); - node.setAttribute("reward-tick", GameWorld.getTicks() + resource.getRespawnDuration()); - final Item item = new Item(resource.getReward()); - player.getInventory().add(item); - player.getSkills().addExperience(resource.getSkillId(), resource.getExperience(), true); - return true; - } - - /** - * Checks if the player gets rewarded. - * @return {@code True} if so. - */ - private boolean checkReward() { - int skill = Skills.MINING; - int level = 1 + player.getSkills().getLevel(skill) + player.getFamiliarManager().getBoost(skill); - double hostRatio = Math.random() * (100.0 * resource.getRate()); - double clientRatio = Math.random() * ((level - resource.getLevel()) * (1.0 + tool.getRatio())); - return hostRatio < clientRatio; - } - } - - /** - * Handles the runite golem npc. - * @author Vexia - * - */ - public class RuniteGolemNPC extends AbstractNPC { - - /** - * The respawn time. - */ - private int respawn = -1; - - /** - * Constructs a new @{Code RuniteGolemNPC} object. - * @param id The npc id. - * @param location The location. - */ - public RuniteGolemNPC(int id, Location location) { - super(id, location); - } - - /** - * Constructs a new @{Code RuniteGolemNPC} object. - */ - public RuniteGolemNPC() { - super(-1, null); - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new RuniteGolemNPC(id, location); - } - - @Override - public void init() { - super.init(); - setAggressive(false); - } - - @Override - public void sendImpact(BattleState state) { - super.sendImpact(state); - if (state.getEstimatedHit() > 16) { - state.setEstimatedHit(16); - } - } - - @Override - public void handleTickActions() { - super.handleTickActions(); - if (isAggressive()) { - setAggressive(false); - } - if (respawn != -1 && respawn < GameWorld.getTicks() && getId() > 8664) { - transform(8664); - unlock(); - } - if (getId() == 8667) { - int rewardTick = getAttribute("reward-tick", -1); - if (rewardTick != -1 && rewardTick < GameWorld.getTicks()) { - transform(8666); - } - } - } - - @Override - public void finalizeDeath(Entity killer) { - respawn = GameWorld.getTicks() + 500; - fullRestore(); - getProperties().setTeleportLocation(getLocation()); - setRespawnTick(0); - setInvisible(false); - transform(8666); - lock(); - faceLocation(null); - face(null); - } - - @Override - public int[] getIds() { - return new int[] {8664}; - } - - - } - - /** - * Handles the item on piles interaction. - * @author Vexia - * - */ - public static class PilesItemHandler extends UseWithHandler { - - /** - * The allowed items for piles. - */ - private static final int[] ALLOWED = new int[] {14937, 14939, 449, 447, 440, 444, 453, 451, 1515, 1513, 2349, 9467,2351,2355,2353,2357,2359,2361,2363}; - - /** - * Constructs a new @{Code PilesItemHandler} object. - */ - public PilesItemHandler() { - super(); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(8663, NPC_TYPE, this); - return this; - } - - @Override - public boolean handle(final NodeUsageEvent event) { - final Player player = event.getPlayer(); - for (int itemId : ALLOWED) { - if (event.getUsedItem().getId() == itemId) { - final int amount = player.getInventory().getAmount(itemId); - final int price = 50 * amount; - if (!player.getInventory().contains(995, price)) { - player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OLD_NORMAL, "I'll need 50 coins per item."); - return true; - } - player.getDialogueInterpreter().sendOptions("Banknote " + amount + " x " + event.getUsedItem().getName() + "?", "Yes - " + price + " gp", "Cancel"); - player.getDialogueInterpreter().addAction((player1, buttonId) -> { - if (player1.getInventory().remove(new Item(995, price)) && player1.getInventory().remove(new Item(event.getUsedItem().getId(), amount))) { - player1.getInventory().add(new Item(event.getUsedItem().getNoteChange(), amount)); - player1.getDialogueInterpreter().sendItemMessage(event.getUsedItem().getId(), "Piles converts your items to banknotes."); - } - }); - return true; - } - } - player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OLD_NORMAL, "Sorry, I wasn't expecting anyone to want to convert", "that sort of item, so I haven't any banknotes for it."); - return true; - } - - @Override - public boolean isDynamic() { - return true; - } - } - - /** - * Handles the Piles dialogue. - * @author Vexia - * - */ - public class PilesDialoguePlugin extends DialoguePlugin { - - /** - * Constructs a new @{Code PilesDialoguePlugin} object. - */ - public PilesDialoguePlugin() { - /* - * empty. - */ - } - - /** - * Constructs a new @{Code PilesDialoguePlugin} object. - * @param player The player. - */ - public PilesDialoguePlugin(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new PilesDialoguePlugin(player); - } - - @Override - public boolean open(Object... args) { - npc("Hello. I can convert items to banknotes, for 50 coins", "per item. Just hand me the items you'd like me to", "convert."); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - options("Who are you?", "Thanks."); - stage++; - break; - case 1: - switch (buttonId) { - case 1: - player("Who are you?"); - stage = 10; - break; - case 2: - player("Thanks."); - stage = 2; - break; - } - break; - case 2: - end(); - break; - case 10: - npc("I'm Piles. I lived in Draynor Village when I was", "young, where I saw three men working in the market,", "converting items to banknotes."); - stage++; - break; - case 11: - npc("Their names were Niles, Miles and Giles. I'm trying to", "be like them, so I've changed my name and started this", "business here."); - stage++; - break; - case 12: - player("Thanks."); - stage = 2; - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] {8663}; - } - - } - - /** - * Handles the Mandrith dialogue. - * @author Empathy - * - */ - public class MandrithDialoguePlugin extends DialoguePlugin { - - /** - * - * Constructs a new @{Code MandrithDialoguePlugin} object. - */ - public MandrithDialoguePlugin() { - /* - * empty - */ - } - - /** - * - * Constructs a new @{Code MandrithDialoguePlugin} object. - * @param player - */ - public MandrithDialoguePlugin(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new MandrithDialoguePlugin(player); - } - - @Override - public boolean open(Object... args) { - player("Who are you and what is this place?" ); - stage = 1; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 1: - npc("My name is Mandrith." ); - stage = 2; - break; - case 2: - npc("I collect valuable resources and pawn off access to them", "to foolish adventurers, like yourself" ); - stage = 3; - break; - case 3: - npc("You should take a look inside my arena. There's an", "abundance of valuable resources inside." ); - stage = 4; - break; - case 4: - player("And I can take whatever I want?" ); - stage = 5; - break; - case 5: - npc("It's all yours. All I ask is that you pay the upfront fee." ); - stage = 6; - break; - case 6: - player("Will others be able to kill me inside?" ); - stage = 7; - break; - case 7: - npc("Yes. These walls will only hold them back for so long." ); - stage = 8; - break; - case 8: - player("You'll stop them though, right?" ); - stage = 9; - break; - case 9: - npc("Haha! For the right price, I won't deny anyone access", "to my arena. Even if their intention is to kill you." ); - stage = 10; - break; - case 10: - player("Right..." ); - stage = 11; - break; - case 11: - npc("My arena holds many treasure that I've acquired at", "great expense, adventurer. Their bounty can come at a", "price." ); - stage = 12; - break; - case 12: - npc("One day, adventurer, I will boast ownership of a much", "larger, much more dangerous arena than this. Take", "advantage of this offer while it lasts." ); - stage = 13; - break; - case 13: - end(); - break; - } - return false; - } - - @Override - public int[] getIds() { - return new int[] { 8662 }; - } - } -} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java index 4c93fdf39..20b1c8719 100644 --- a/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java +++ b/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java @@ -52,6 +52,10 @@ public final class WildernessDitchPlugin extends OptionHandler { player.faceLocation(node.getLocation()); Scenery ditch = (Scenery) node; player.setAttribute("wildy_ditch", ditch); + /* + + Comment out the annoying ditch warning until the doomsayer has been implemented so that players can disable it properly. + if(!player.isArtificial()) { if (ditch.getRotation() % 2 == 0) { if (player.getLocation().getY() <= node.getLocation().getY()) { @@ -65,6 +69,7 @@ public final class WildernessDitchPlugin extends OptionHandler { } } } + */ WildernessInterfacePlugin.handleDitch(player); } diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt b/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt index d65982858..2f0ed6a1f 100644 --- a/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt +++ b/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt @@ -1,9 +1,10 @@ package content.region.wilderness.handlers +import content.region.wilderness.handlers.WildernessGateHandler.GateDialogue +import core.ServerConstants import core.api.* import core.game.interaction.* import core.game.node.entity.player.Player -import core.game.node.scenery.Scenery import core.game.node.Node import core.game.global.action.DoorActionHandler import core.game.dialogue.* @@ -16,39 +17,57 @@ class WildernessGateHandler : InteractionListener { on (gates, IntType.SCENERY, "open", handler = ::handleGate) } - private fun handleGate (player: Player, node: Node) : Boolean { - if (player.location.y > 3890) { - val isEntering = !player.skullManager.isDeepWilderness() - - if (isEntering) - openDialogue(player, GateDialogue(node.asScenery())) - else { - if (player.properties.combatPulse.isInCombat) + private fun handleGate(player: Player, node: Node) : Boolean { + if (player.location.y > 3890 && ServerConstants.ENHANCED_DEEP_WILDERNESS) { + val isEntering = !player.skullManager.isDeepWilderness + if (isEntering) { + fun enter(player: Player) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + player.skullManager.isDeepWilderness = true + } + enterDeepWilderness(player, ::enter, "Beyond this gate you enter the deep wilderness!") + } else { + if (player.properties.combatPulse.isInCombat) { sendMessage(player, "You cannot leave while you are under attack.") - else { + } else { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) player.skullManager.isDeepWilderness = false } } - } else DoorActionHandler.handleAutowalkDoor (player, node.asScenery()) + } else DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) return true } - class GateDialogue (val gate: Scenery) : DialogueFile() { + class GateDialogue(val callback: (Player) -> Unit, val firstLine: String) : DialogueFile() { override fun handle (interfaceId: Int, buttonId: Int) { when (stage) { - 0 -> sendDialogueLines(player!!, "WARNING!", "Beyond this gate you enter the deep wilderness!", "Anyone will be able to attack you without consequence!", "You WILL NOT be able to leave during combat!").also { stage++ } - 1 -> showTopics ( + 0 -> sendDialogueLines(player!!, "WARNING!", firstLine, "Anyone will be able to attack you without consequence!", "You WILL NOT be able to leave during combat!").also { stage++ } + 1 -> sendDialogueLines(player!!, "While you are there, you will be skulled:","you will lose all your items if you die!","The skull will go away when you leave the deep wilderness.").also { stage++ } + 2 -> sendDialogueLines(player!!, "If you are risking sufficient value, the skull will become red.","This increases your chances of receiving special loot from killing","revenants and the Chaos Elemental!").also { stage++ } + 3 -> showTopics( Topic(FacialExpression.NEUTRAL, "I wish to proceed.", 10, true), - Topic(FacialExpression.NEUTRAL, "Nevermind.", END_DIALOGUE, true) + Topic(FacialExpression.NEUTRAL, "I wish to proceed, and don't show this warning again.", 11, true), + Topic(FacialExpression.NEUTRAL, "Never mind.", END_DIALOGUE, true) ) - 10 -> { + 10 -> { end() - DoorActionHandler.handleAutowalkDoor (player!!, gate) - player!!.skullManager.isDeepWilderness = true + callback(player!!) + } + 11 -> { + player!!.setAttribute("/save:skip-deep-wilderness-warning", true) + end() + callback(player!!) } } } } } + +fun enterDeepWilderness(player: Player, callback: (Player) -> Unit, firstLine: String) { + if (player.getAttribute("/save:skip-deep-wilderness-warning",false)) { + callback(player) + } else { + openDialogue(player, GateDialogue(callback, firstLine)) + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java index 40597b85b..26bb09c1a 100644 --- a/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java +++ b/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java @@ -16,6 +16,7 @@ import core.plugin.Plugin; import org.rs09.consts.Sounds; import static core.api.ContentAPIKt.*; +import content.data.Quests; /** * Represents a plugin used to handle wilderness nodes. @@ -49,7 +50,7 @@ public final class WildernessPlugin extends OptionHandler { ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, Location.create(3239, 3606, 0), "You climb up the ladder to the surface."); break; case 39188: - if (!hasRequirement(player, "Defender of Varrock")) + if (!hasRequirement(player, Quests.DEFENDER_OF_VARROCK)) break; ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, Location.create(3241, 9991, 0), "You descend into the cavern below."); break; diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java index 01040043e..0c509175f 100644 --- a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java @@ -74,8 +74,10 @@ public class RevenantCombatHandler extends MultiSwingHandler { } } } - if (!isPoisoned(victim) && (WildernessZone.getWilderness(entity) >= 50 || entity.getId() == 6998)) { - applyPoison(victim, entity, 6); + if (entity.getId() == 6998) { + applyPoison(victim, entity, 40); + } else if (WildernessZone.getWilderness(entity) >= 50) { + applyPoison(victim, entity, 30); } super.impact(entity, victim, state); } diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt index 1a1bdc055..fed2f91ec 100644 --- a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt @@ -9,7 +9,7 @@ import core.game.world.update.flag.context.Graphics import core.tools.RandomFunction import core.ServerConstants import core.api.* -import core.tools.SystemLogger +import core.game.node.entity.combat.InteractionType import core.game.system.command.Privilege import core.game.world.GameWorld import core.game.world.map.path.Pathfinder @@ -28,10 +28,21 @@ class RevenantController : TickListener, Commands { private var expectedRevAmount: Int = ServerConstants.REVENANT_POPULATION private var groupPatrolQueue = ArrayList() + // Movement tracking for stuck detection + private val movementStartTick = HashMap() + private val lastKnownLocation = HashMap() + private val failedAttempts = HashMap() + // Stuck detector config + private const val STUCK_CHECK_INTERVAL = 10 // ticks + private const val MAX_FAILED_ATTEMPTS = 5 + @JvmStatic fun registerRevenant(revenantNPC: RevenantNPC) { trackedRevenants.add(revenantNPC) taskTimeRemaining[revenantNPC] = 0 currentTask[revenantNPC] = RevenantTask.NONE + movementStartTick[revenantNPC] = GameWorld.ticks + lastKnownLocation[revenantNPC] = revenantNPC.location + failedAttempts[revenantNPC] = 0 Repository.RENDERABLE_NPCS.add(revenantNPC) } @@ -39,19 +50,188 @@ class RevenantController : TickListener, Commands { trackedRevenants.remove(revenantNPC) taskTimeRemaining.remove(revenantNPC) currentTask.remove(revenantNPC) + movementStartTick.remove(revenantNPC) + lastKnownLocation.remove(revenantNPC) + failedAttempts.remove(revenantNPC) + groupPatrolQueue.remove(revenantNPC) if (removeRender) Repository.RENDERABLE_NPCS.remove(revenantNPC) } + private fun route(vararg coords: Pair): Array = + Array(coords.size) { Location.create(coords[it].first, coords[it].second) } + + // All routes that revs attempt to path through val routes = listOf( - arrayOf(Location.create(3070, 3651), Location.create(3083, 3640), Location.create(3106, 3645), Location.create(3133, 3647), Location.create(3149, 3642), Location.create(3160, 3654), Location.create(3171, 3665, 0), Location.create(3189, 3663, 0), Location.create(3202, 3675, 0), Location.create(3217, 3660, 0), Location.create(3235, 3661, 0), Location.create(3235, 3661, 0), Location.create(3279, 3650, 0), Location.create(3269, 3636, 0), Location.create(3253, 3632, 0), Location.create(3236, 3638, 0), Location.create(3220, 3637, 0), Location.create(3203, 3634, 0), Location.create(3187, 3631, 0), Location.create(3166, 3633, 0), Location.create(3160, 3616, 0), Location.create(3148, 3604, 0), Location.create(3134, 3596, 0), Location.create(3118, 3590, 0), Location.create(3104, 3597, 0)), - arrayOf(Location.create(3077, 3565, 0), Location.create(3093, 3559, 0), Location.create(3110, 3566, 0), Location.create(3127, 3574, 0), Location.create(3146, 3571, 0), Location.create(3164, 3575, 0), Location.create(3183, 3573, 0), Location.create(3197, 3587, 0), Location.create(3215, 3584, 0), Location.create(3233, 3576, 0), Location.create(3251, 3573, 0), Location.create(3269, 3577, 0), Location.create(3287, 3569, 0), Location.create(3305, 3568, 0), Location.create(3321, 3576, 0), Location.create(3338, 3584, 0), Location.create(3352, 3573, 0), Location.create(3354, 3554, 0), Location.create(3342, 3541, 0), Location.create(3324, 3536, 0), Location.create(3306, 3543, 0), Location.create(3290, 3544, 0), Location.create(3272, 3545, 0), Location.create(3255, 3546, 0), Location.create(3239, 3539, 0), Location.create(3222, 3543, 0), Location.create(3206, 3548, 0), Location.create(3189, 3549, 0), Location.create(3173, 3552, 0), Location.create(3157, 3549, 0), Location.create(3140, 3548, 0), Location.create(3122, 3548, 0), Location.create(3110, 3555, 0)), - arrayOf(Location.create(3318, 3691, 0), Location.create(3307, 3700, 0), Location.create(3290, 3696, 0), Location.create(3277, 3706, 0), Location.create(3260, 3706, 0), Location.create(3250, 3707, 0), Location.create(3245, 3723, 0), Location.create(3254, 3735, 0), Location.create(3251, 3754, 0), Location.create(3243, 3768, 0), Location.create(3253, 3780, 0), Location.create(3238, 3783, 0), Location.create(3224, 3793, 0), Location.create(3206, 3786, 0), Location.create(3192, 3780, 0), Location.create(3170, 3787, 0), Location.create(3156, 3800, 0), Location.create(3148, 3814, 0), Location.create(3148, 3814, 0), Location.create(3127, 3840, 0), Location.create(3124, 3856, 0), Location.create(3124, 3872, 0), Location.create(3116, 3892, 0)), - arrayOf(Location.create(2949, 3890, 0), Location.create(2965, 3899, 0), Location.create(2984, 3900, 0), Location.create(2998, 3895, 0), Location.create(3016, 3898, 0), Location.create(3032, 3893, 0), Location.create(3048, 3897, 0), Location.create(3068, 3894, 0), Location.create(3084, 3898, 0), Location.create(3101, 3895, 0), Location.create(3118, 3897, 0), Location.create(3136, 3893, 0), Location.create(3154, 3900, 0), Location.create(3172, 3895, 0), Location.create(3189, 3892, 0), Location.create(3206, 3897, 0), Location.create(3222, 3890, 0), Location.create(3240, 3897, 0), Location.create(3259, 3892, 0), Location.create(3278, 3895, 0), Location.create(3296, 3892, 0), Location.create(3313, 3899, 0), Location.create(3331, 3888, 0), Location.create(3345, 3880, 0)), - arrayOf(Location.create(3308, 3941, 0), Location.create(3301, 3925, 0), Location.create(3287, 3915, 0), Location.create(3276, 3922, 0), Location.create(3266, 3938, 0), Location.create(3267, 3952, 0), Location.create(3250, 3949, 0), Location.create(3235, 3944, 0), Location.create(3219, 3944, 0), Location.create(3206, 3938, 0), Location.create(3194, 3929, 0), Location.create(3182, 3921, 0), Location.create(3174, 3936, 0), Location.create(3180, 3952, 0), Location.create(3167, 3960, 0), Location.create(3155, 3959, 0), Location.create(3141, 3953, 0), Location.create(3126, 3954, 0), Location.create(3110, 3961, 0), Location.create(3093, 3962, 0), Location.create(3078, 3953, 0), Location.create(3066, 3942, 0), Location.create(3059, 3929, 0), Location.create(3049, 3916, 0), Location.create(3033, 3924, 0), Location.create(3020, 3921, 0), Location.create(3010, 3913, 0), Location.create(2993, 3906, 0), Location.create(2977, 3911, 0), Location.create(2970, 3928, 0)) + route( + 3070 to 3651, 3083 to 3640, 3106 to 3645, 3133 to 3647, 3149 to 3642, + 3160 to 3654, 3171 to 3665, 3189 to 3663, 3202 to 3675, 3217 to 3660, + 3235 to 3661, 3235 to 3661, 3279 to 3650, 3269 to 3636, 3253 to 3632, + 3236 to 3638, 3220 to 3637, 3203 to 3634, 3187 to 3631, 3166 to 3633, + 3160 to 3616, 3148 to 3604, 3134 to 3596, 3118 to 3590, 3104 to 3597, + ), + route( + 3077 to 3565, 3093 to 3559, 3110 to 3566, 3127 to 3574, 3146 to 3571, + 3164 to 3575, 3183 to 3573, 3197 to 3587, 3215 to 3584, 3233 to 3576, + 3251 to 3573, 3269 to 3577, 3287 to 3569, 3305 to 3568, 3321 to 3576, + 3338 to 3584, 3352 to 3573, 3354 to 3554, 3342 to 3541, 3324 to 3536, + 3306 to 3543, 3290 to 3544, 3272 to 3545, 3255 to 3546, 3239 to 3539, + 3222 to 3543, 3206 to 3548, 3189 to 3549, 3173 to 3552, 3157 to 3549, + 3140 to 3548, 3122 to 3548, 3110 to 3555, + ), + route( + 3318 to 3691, 3307 to 3700, 3290 to 3696, 3277 to 3706, 3260 to 3706, + 3250 to 3707, 3245 to 3723, 3254 to 3735, 3251 to 3754, 3243 to 3768, + 3253 to 3780, 3238 to 3783, 3224 to 3793, 3206 to 3786, 3192 to 3780, + 3170 to 3787, 3156 to 3800, 3148 to 3814, 3148 to 3814, 3127 to 3840, + 3124 to 3856, 3124 to 3872, 3116 to 3892, + ), + route( + 2949 to 3890, 2965 to 3899, 2984 to 3900, 2998 to 3895, 3016 to 3898, + 3032 to 3893, 3048 to 3897, 3068 to 3894, 3084 to 3898, 3101 to 3895, + 3118 to 3897, 3136 to 3893, 3154 to 3900, 3172 to 3895, 3189 to 3892, + 3206 to 3897, 3222 to 3890, 3240 to 3897, 3259 to 3892, 3278 to 3895, + 3296 to 3892, 3313 to 3899, 3331 to 3888, 3345 to 3880, + ), + route( + 3308 to 3941, 3301 to 3925, 3287 to 3915, 3276 to 3922, 3266 to 3938, + 3267 to 3952, 3250 to 3949, 3235 to 3944, 3219 to 3944, 3206 to 3938, + 3194 to 3929, 3182 to 3921, 3174 to 3936, 3180 to 3952, 3167 to 3960, + 3155 to 3959, 3141 to 3953, 3126 to 3954, 3110 to 3961, 3093 to 3962, + 3078 to 3953, 3066 to 3942, 3059 to 3929, 3049 to 3916, 3033 to 3924, + 3020 to 3921, 3010 to 3913, 2993 to 3906, 2977 to 3911, 2970 to 3928, + ), + route( + 3308 to 3941, 3301 to 3925, 3297 to 3914, 3286 to 3910, 3259 to 3912, + 3267 to 3952, 3251 to 3921, 3236 to 3918, 3222 to 3922, 3209 to 3920, + 3190 to 3933, 3177 to 3939, 3175 to 3951, 3167 to 3960, 3155 to 3959, + 3135 to 3951, 3134 to 3921, 3126 to 3914, 3108 to 3907, 3087 to 3910, + 3077 to 3925, 3076 to 3937, 3066 to 3942, 3059 to 3929, 3049 to 3916, + 3033 to 3924, 3020 to 3921, 3010 to 3913, 2993 to 3906, 2977 to 3911, + 2970 to 3928, + ), ) - val spawnLocations = listOf(Location.create(3075, 3553, 0), Location.create(3077, 3563, 0), Location.create(3077, 3578, 0), Location.create(3093, 3581, 0), Location.create(3103, 3570, 0), Location.create(3101, 3564, 0), Location.create(3030, 3596, 0), Location.create(3015, 3598, 0), Location.create(3000, 3593, 0), Location.create(2986, 3588, 0), Location.create(2969, 3701, 0), Location.create(2982, 3689, 0), Location.create(2967, 3689, 0), Location.create(2953, 3711, 0), Location.create(2966, 3759, 0), Location.create(2989, 3759, 0), Location.create(2986, 3741, 0), Location.create(2961, 3763, 0), Location.create(2969, 3808, 0), Location.create(3004, 3816, 0)) + // Routes that Dark Beasts are too fat for + private val largeNpcIncompatibleRoutes = setOf(4) + + val spawnLocations = listOf( + 3075 to 3553, 3077 to 3563, 3077 to 3578, 3093 to 3581, 3103 to 3570, + 3101 to 3564, 3030 to 3596, 3015 to 3598, 3000 to 3593, 2986 to 3588, + 2969 to 3701, 2982 to 3689, 2967 to 3689, 2953 to 3713, 2966 to 3759, + 2989 to 3759, 2986 to 3741, 2961 to 3763, 2969 to 3808, 3004 to 3816, + ).map { (x, y) -> Location.create(x, y) } + + /** + * Revenant stuck detector + * Makes sure Revenants are either moving, intentionally waiting to act, or are in legitimate combat + * If they aren't, they're passed to the stuck handler + */ + private fun checkIfStuck(revenantNPC: RevenantNPC): Boolean { + val lastTick = movementStartTick[revenantNPC] ?: 0 + val lastLoc = lastKnownLocation[revenantNPC] ?: revenantNPC.location + + // Period between checks - configure above + if (lastTick == 0 || (GameWorld.ticks - lastTick) < STUCK_CHECK_INTERVAL) { + return false + } + + // Check if positioned exactly at a patrol route start location (likely intentionally inactive) + val routeStartLocations = routes.map { it[0] } + val isAtRouteStart = routeStartLocations.any { it.equals(revenantNPC.location) } + + // Check if in legitimate combat + val combatPulse = revenantNPC.properties.combatPulse + val victim = combatPulse.getVictim() + val isInLegitimateCombat = if (victim != null) { + val interactionType = combatPulse.canInteract() + interactionType == InteractionType.STILL_INTERACT // The merits of MOVE_INTERACT regarding establishing a legitimate combat state are covered by the distanceMoved check a few lines from now + } else { + false + } + + if (isAtRouteStart || isInLegitimateCombat) { //If the Revenant has a good reason to not be moving, skip the movement check + movementStartTick[revenantNPC] = GameWorld.ticks + lastKnownLocation[revenantNPC] = revenantNPC.location + failedAttempts[revenantNPC] = 0 + return false + } + + // Check if the revenant has moved + val distanceMoved = revenantNPC.location.getDistance(lastLoc) + val isStuck = distanceMoved <= 2 + + // Reset the timer to check if they are stuck, since we are checking now + movementStartTick[revenantNPC] = GameWorld.ticks + + // Clear the Revenant's demerits towards being timed out if it is not stuck + if (!isStuck) { + lastKnownLocation[revenantNPC] = revenantNPC.location + failedAttempts[revenantNPC] = 0 + } + + return isStuck + } + + /** + * Revenant stuck handler + * Tries to help the Revenant escape after giving it a demerit + * If the Revenant gets too many demerits, it will be timed out instead + * NOTE: times out Revenants in unloaded regions as they have no land to path to and thus cannot move + */ + private fun handleStuckRevenant(revenantNPC: RevenantNPC) { + val attempts = failedAttempts[revenantNPC] ?: 0 + failedAttempts[revenantNPC] = attempts + 1 + + if (attempts + 1 > MAX_FAILED_ATTEMPTS) { + poofClear(revenantNPC) + revenantNPC.setAttribute("done", true) + return + } + + // The stuck Revenant will attempt to unstick itself + val escapeLocation = getNextLocation(revenantNPC) + revenantNPC.pulseManager.run(object : MovementPulse(revenantNPC, escapeLocation, Pathfinder.SMART) { + override fun pulse(): Boolean { + return true + } + }) + } + + /** + * Finds a random location to try to move to that is within the Wilderness + */ + fun getNextLocation(revenantNPC: RevenantNPC): Location { + val rawNextX = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius) + val nextX = maxOf(rawNextX, 2951) + val rawNextY = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius) + val nextY = maxOf(rawNextY, 3523) + return revenantNPC.location.transform(nextX, nextY, 0) + } + + /** + * Determines how far Revenants can deviate from their path + */ + private fun getPathVariance(revenantNPC: RevenantNPC, isGroup: Boolean): Int { + return when { + isGroup -> 4 + revenantNPC.size() >= 3 -> 2 // Dark Beasts are fat, so keep them close to their safe routes + else -> 10 + } + } + + /** + * Gets a random route for patrols + * Will not assign Dark Beasts to routes they are too fat for + */ + private fun getSuitableRoute(revenantNPC: RevenantNPC): Array { + val availableRoutes = if (revenantNPC.size() >= 3) { + routes.filterIndexed { index, _ -> index !in largeNpcIncompatibleRoutes } + } else { + routes + } + return availableRoutes.random() + } } override fun tick() { @@ -87,20 +267,19 @@ class RevenantController : TickListener, Commands { } override fun defineCommands() { - define("setrevcap", Privilege.ADMIN) {player, strings -> + define("setrevcap", Privilege.ADMIN, "::setrevcap amount", "Sets revenant spawn cap to amount") {player, strings -> val amt = strings[1].toInt() expectedRevAmount = amt } - define("listrevs", Privilege.ADMIN) {player, strings -> + define("listrevs", Privilege.ADMIN, description = "Logs the IDs and locations of all tracked revenants.") {player, strings -> for (rev in trackedRevenants) { log(this::class.java, Log.FINE, "REV ${rev.id}-${rev.name} @ ${rev.location.toString()}") } - log(this::class.java, Log.FINE, "Total of ${trackedRevenants.size} revenants spawned.") } - define("clearrevs", Privilege.ADMIN) {_, _ -> + define("clearrevs", Privilege.ADMIN, description = "Despawns all revenants.") {_, _ -> for (rev in trackedRevenants.toTypedArray()) rev.clear() } } @@ -114,7 +293,13 @@ class RevenantController : TickListener, Commands { private val MAX_ROAM_TICKS: Int = 250 override fun execute(revenantNPC: RevenantNPC) { - if (!canMove(revenantNPC)) return + + if (checkIfStuck(revenantNPC)) { + handleStuckRevenant(revenantNPC) + return + } + + if (!canMoveBasic(revenantNPC)) return val nextLoc = getNextLocation(revenantNPC) revenantNPC.pulseManager.run(object : MovementPulse(revenantNPC, nextLoc, Pathfinder.SMART) { @@ -124,22 +309,15 @@ class RevenantController : TickListener, Commands { } }) } - - override fun assign(revenantNPC: RevenantNPC) { - taskTimeRemaining[revenantNPC] = RandomFunction.random(MAX_ROAM_TICKS) - } - - fun canMove(revenantNPC: RevenantNPC) : Boolean { - return !revenantNPC.walkingQueue.isMoving + private fun canMoveBasic(revenantNPC: RevenantNPC): Boolean { + return !revenantNPC.walkingQueue.isMoving && !revenantNPC.pulseManager.hasPulseRunning() && !revenantNPC.properties.combatPulse.isAttacking && !revenantNPC.properties.combatPulse.isInCombat } - fun getNextLocation(revenantNPC: RevenantNPC) : Location { - val nextX = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius) - val nextY = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius) - return revenantNPC.location.transform(nextX, nextY, 0) + override fun assign(revenantNPC: RevenantNPC) { + taskTimeRemaining[revenantNPC] = RandomFunction.random(MAX_ROAM_TICKS) } }, PATROLLING_ROUTE { @@ -149,7 +327,7 @@ class RevenantController : TickListener, Commands { if (canGroup(revenantNPC)) { addToPatrolGroup(revenantNPC) } else { - revenantNPC.setAttribute("route", routes.random()) + revenantNPC.setAttribute("route", getSuitableRoute(revenantNPC)) revenantNPC.setAttribute("routeidx", -1) } } @@ -159,7 +337,9 @@ class RevenantController : TickListener, Commands { groupPatrolQueue.add(revenantNPC) if (groupPatrolQueue.size == 3) { - val groupRoute = routes.random() + // Gets a route suitable for the largest NPC in the group + val largestNPC = groupPatrolQueue.maxByOrNull { it.size() } ?: revenantNPC + val groupRoute = getSuitableRoute(largestNPC) for (rev in groupPatrolQueue) { rev.setAttribute("route", groupRoute) rev.setAttribute("routeidx", -1) @@ -176,7 +356,12 @@ class RevenantController : TickListener, Commands { val route = revenantNPC.getAttribute>("route", null) val routeIdx = revenantNPC.getAttribute("routeidx", -1) - if (!canMove(revenantNPC)) return + if (checkIfStuck(revenantNPC)) { + handleStuckRevenant(revenantNPC) + return + } + + if (!canMoveAdvanced(revenantNPC)) return if (isGroup && route == null) { //if this is a grouped rev and we are waiting on more revs still taskTimeRemaining[revenantNPC] = 50 //just to make sure it doesn't time out roaming... @@ -199,7 +384,7 @@ class RevenantController : TickListener, Commands { revenantNPC.setAttribute("done", true) return } - val pathVariance = if (isGroup) 4 else 10 + val pathVariance = getPathVariance(revenantNPC, isGroup) val nextLoc = route[routeIdx].transform( RandomFunction.random(-pathVariance, pathVariance), RandomFunction.random(-pathVariance, pathVariance), @@ -213,9 +398,8 @@ class RevenantController : TickListener, Commands { revenantNPC.setAttribute("routeidx", routeIdx + 1) } } - - fun canMove(revenantNPC: RevenantNPC) : Boolean { - return !revenantNPC.walkingQueue.isMoving + private fun canMoveAdvanced(revenantNPC: RevenantNPC) : Boolean { + return !revenantNPC.walkingQueue.isMoving && !revenantNPC.pulseManager.hasPulseRunning() && !revenantNPC.properties.combatPulse.isAttacking && !revenantNPC.properties.combatPulse.isInCombat diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java index c63797294..6e0d0e6fb 100644 --- a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java @@ -26,7 +26,7 @@ import static core.api.ContentAPIKt.playGlobalAudio; /** * Handles a revenant NPC. - * @author Ceikry-ish (mostly Vexia code still) + * @author Ceikry-ish (mostly Vexia code still), Player Name */ @Initializable public class RevenantNPC extends AbstractNPC { @@ -88,6 +88,7 @@ public class RevenantNPC extends AbstractNPC { configureBonuses(); super.configure(); this.swingHandler = new RevenantCombatHandler(getProperties().getAttackAnimation(), getProperties().getMagicAnimation(), getProperties().getRangeAnimation()); + setAttribute("food-items", 20); } @Override @@ -116,16 +117,23 @@ public class RevenantNPC extends AbstractNPC { public void tick() { skills.pulse(); getWalkingQueue().update(); - if (this.getViewport().getRegion().isActive()) + if (this.getViewport().getRegion().isActive()) { getUpdateMasks().prepare(this); - if (!DeathTask.isDead(this) && getSkills().getLifepoints() <= (getSkills().getStaticLevel(Skills.HITPOINTS) / 2) && getAttribute("eat-delay", 0) < GameWorld.getTicks()) { - lock(3); - getProperties().getCombatPulse().delayNextAttack(3); - getSkills().heal(10); - for (Player p : RegionManager.getLocalPlayers(this)) { - playAudio(p, Sounds.EAT_2393); + } + if (!DeathTask.isDead(this)) { + int curhp = getSkills().getLifepoints(); + int maxhp = getSkills().getStaticLevel(Skills.HITPOINTS); + int fooditems = getAttribute("food-items", 0); + if (curhp < maxhp / 2 && fooditems > 0 && getAttribute("eat-delay", 0) < GameWorld.getTicks()) { + lock(3); + getProperties().getCombatPulse().delayNextAttack(3); + getSkills().heal(maxhp / 6); + for (Player p : RegionManager.getLocalPlayers(this)) { + playAudio(p, Sounds.EAT_2393); + } + setAttribute("eat-delay", GameWorld.getTicks() + 6); + setAttribute("food-items", fooditems - 1); } - setAttribute("eat-delay", GameWorld.getTicks() + 6); } behavior.tick(this); if (aggressiveHandler != null && aggressiveHandler.selectTarget()) { @@ -196,9 +204,9 @@ public class RevenantNPC extends AbstractNPC { public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { if (entity instanceof Player) { if (!hasAcceptableCombatLevel(entity.asPlayer()) && !entity.asPlayer().isAdmin()) { - if(message) { - entity.asPlayer().sendMessage("The level difference between you and your opponent is too great."); - } + if (message) { + entity.asPlayer().sendMessage("The level difference between you and your opponent is too great."); + } return false; } } diff --git a/Server/src/main/core/Server.kt b/Server/src/main/core/Server.kt index fd128d949..cf46e2823 100644 --- a/Server/src/main/core/Server.kt +++ b/Server/src/main/core/Server.kt @@ -3,20 +3,23 @@ package core import core.api.log import core.game.system.SystemManager import core.game.system.SystemState -import core.net.NioReactor -import core.tools.TimeStamp -import kotlinx.coroutines.* -import core.tools.SystemLogger import core.game.system.config.ServerConfigParser import core.game.world.GameWorld -import core.game.world.repository.Repository +import core.net.NioReactor +import core.net.websocket.GameWebSocketServer +import core.net.websocket.WebSocketTls import core.tools.Log +import core.tools.NetworkReachability +import core.tools.TimeStamp +import kotlinx.coroutines.* import java.io.File import java.io.FileWriter import java.lang.management.ManagementFactory import java.lang.management.ThreadMXBean import java.net.BindException +import java.net.URL import java.util.* +import kotlin.math.max import kotlin.system.exitProcess @@ -43,6 +46,11 @@ object Server { @JvmStatic var reactor: NioReactor? = null + @JvmStatic + var webSocketServer: GameWebSocketServer? = null + + var networkReachability = NetworkReachability.Reachable + /** * The main method, in this method we load background utilities such as * cache and our world, then end with starting networking. @@ -67,6 +75,16 @@ object Server { try { reactor = NioReactor.configure(43594 + GameWorld.settings?.worldId!!) reactor!!.start() + if (ServerConstants.WEBSOCKET_ENABLED) { + val websocketPort = if (ServerConstants.WEBSOCKET_PORT > 0) { + ServerConstants.WEBSOCKET_PORT + } else { + 53594 + GameWorld.settings?.worldId!! + } + webSocketServer = GameWebSocketServer(websocketPort, 1) + WebSocketTls.configure(webSocketServer!!) + webSocketServer!!.start() + } } catch (e: BindException) { log(this::class.java, Log.ERR, "Port " + (43594 + GameWorld.settings?.worldId!!) + " is already in use!") throw e @@ -95,6 +113,11 @@ object Server { GlobalScope.launch { delay(20000) while (running) { + val timeStart = System.currentTimeMillis() + if (!checkConnectivity()) + networkReachability = NetworkReachability.Unreachable + else + networkReachability = NetworkReachability.Reachable if (System.currentTimeMillis() - lastHeartbeat > 7200 && running) { log(this::class.java, Log.ERR, "Triggering reboot due to heartbeat timeout") log(this::class.java, Log.ERR, "Creating thread dump...") @@ -115,12 +138,36 @@ object Server { if (!SystemManager.isTerminated()) exitProcess(0) } - delay(625) + val timeNow = System.currentTimeMillis() + delay(max(0L, 625 - (timeNow - timeStart))) } } } } + private fun checkConnectivity(): Boolean + { + //Has to be done this way because you can't actually ping in Java unless you run the whole thing as root + val urls = ServerConstants.CONNECTIVITY_CHECK_URL.split(",") + var timeout = ServerConstants.CONNECTIVITY_TIMEOUT + if (timeout * urls.size > 5000) //Limit timeout down to 5000ms so other watchdog functions continue as expected. + timeout = 5000 / urls.size + for (targetUrl in urls) { + try { + val url = URL(targetUrl) + val conn = url.openConnection() + conn.connectTimeout = timeout + conn.connect() + conn.getInputStream().close() + return true + } catch (e: Exception) { + log(this::class.java, Log.WARN, "${targetUrl} failed to respond. Are we offline?") + continue + } + } + return false + } + @JvmStatic fun heartbeat() { lastHeartbeat = System.currentTimeMillis() diff --git a/Server/src/main/core/ServerConstants.backup b/Server/src/main/core/ServerConstants.backup deleted file mode 100644 index 3c4d50610..000000000 --- a/Server/src/main/core/ServerConstants.backup +++ /dev/null @@ -1,217 +0,0 @@ -package core - -import core.game.system.SystemShutdownHook -import core.game.system.mysql.SQLManager -import core.game.world.map.Location -import core.tools.mysql.Database -import core.tools.secondsToTicks -import org.json.simple.JSONObject -import java.io.File -import java.math.BigInteger - -/** - * A class holding various variables for the server. - * @author Ceikry - */ -class ServerConstants { - companion object { - @JvmField - var SHUTDOWN_HOOK: Thread = Thread(SystemShutdownHook()) - - @JvmField - var DATA_PATH: String? = null - - //path to the cache - @JvmField - var CACHE_PATH: String? = null - - //path for the server store (obsolete, but kept for the sake of system sanity.) - @JvmField - var STORE_PATH: String? = null - - //path for player saves - @JvmField - var PLAYER_SAVE_PATH: String? = null - - @JvmField - var PLAYER_ATTRIBUTE_PATH = "ish"; - - //path to the various config files, such as npc_spawns.json - var CONFIG_PATH: String? = null - - @JvmField - var GRAND_EXCHANGE_DATA_PATH: String? = null - - @JvmField - var RDT_DATA_PATH: String? = null - - @JvmField - var OBJECT_PARSER_PATH: String? = null - - @JvmField - var SCRIPTS_PATH: String? = null - - @JvmField - var DIALOGUE_SCRIPTS_PATH: String? = null - - @JvmField - var LOGS_PATH: String? = null - - @JvmField - var BOT_DATA_PATH: String? = null - - //the max number of players. - @JvmField - var MAX_PLAYERS = 0 - - //the max number of NPCs - @JvmField - var MAX_NPCS = 0 - - //the location where new players are placed on login. - @JvmField - var START_LOCATION: Location? = null - - //Location for all home teleports/respawn location - @JvmField - var HOME_LOCATION: Location? = null - - //the name for the database - @JvmField - var DATABASE_NAME: String? = null - - //username for the database - @JvmField - var DATABASE_USER: String? = null - - //password for the database - @JvmField - var DATABASE_PASS: String? = null - - //address for the database - @JvmField - var DATABASE_ADDRESS: String? = null - - @JvmField - var DATABASE_PORT: String? = null - - @JvmField - var WRITE_LOGS: Boolean = false - - @JvmField - var BANK_SIZE: Int = 496 - - @JvmField - var GE_AUTOSAVE_FREQUENCY = secondsToTicks(3600) //1 hour - - @JvmField - var GE_AUTOSTOCK_ENABLED = false - - //location names for the ::to command. - val TELEPORT_DESTINATIONS = arrayOf( - arrayOf(Location.create(2974, 4383, 2), "corp", "corporal", "corporeal"), - arrayOf(Location.create(2659, 2649, 0), "pc", "pest control", "pest"), - arrayOf(Location.create(3293, 3184, 0), "al kharid", "alkharid", "kharid"), - arrayOf(Location.create(3222, 3217, 0), "lumbridge", "lumby"), - arrayOf(Location.create(3110, 3168, 0), "wizard tower", "wizards tower", "tower", "wizards"), - arrayOf(Location.create(3083, 3249, 0), "draynor", "draynor village"), - arrayOf(Location.create(3019, 3244, 0), "port sarim", "sarim"), - arrayOf(Location.create(2956, 3209, 0), "rimmington"), - arrayOf(Location.create(2965, 3380, 0), "fally", "falador"), - arrayOf(Location.create(2895, 3436, 0), "taverley"), - arrayOf(Location.create(3080, 3423, 0), "barbarian village", "barb"), - arrayOf(Location.create(3213, 3428, 0), "varrock"), - arrayOf(Location.create(3164, 3485, 0), "grand exchange", "ge"), - arrayOf(Location.create(2917, 3175, 0), "karamja"), - arrayOf(Location.create(2450, 5165, 0), "tzhaar"), - arrayOf(Location.create(2795, 3177, 0), "brimhaven"), - arrayOf(Location.create(2849, 2961, 0), "shilo village", "shilo"), - arrayOf(Location.create(2605, 3093, 0), "yanille"), - arrayOf(Location.create(2663, 3305, 0), "ardougne", "ardy"), - arrayOf(Location.create(2450, 3422, 0), "gnome stronghold", "gnome"), - arrayOf(Location.create(2730, 3485, 0), "camelot", "cammy", "seers"), - arrayOf(Location.create(2805, 3435, 0), "catherby"), - arrayOf(Location.create(2659, 3657, 0), "rellekka"), - arrayOf(Location.create(2890, 3676, 0), "trollheim"), - arrayOf(Location.create(2914, 3746, 0), "godwars", "gwd", "god wars"), - arrayOf(Location.create(3180, 3684, 0), "bounty hunter", "bh"), - arrayOf(Location.create(3272, 3687, 0), "clan wars", "clw"), - arrayOf(Location.create(3090, 3957, 0), "mage arena", "mage", "magearena", "arena"), - arrayOf(Location.create(3069, 10257, 0), "king black dragon", "kbd"), - arrayOf(Location.create(3359, 3416, 0), "digsite"), - arrayOf(Location.create(3488, 3489, 0), "canifis"), - arrayOf(Location.create(3428, 3526, 0), "slayer tower", "slayer"), - arrayOf(Location.create(3502, 9483, 2), "kalphite queen", "kq", "kalphite hive", "kalphite"), - arrayOf(Location.create(3233, 2913, 0), "pyramid"), - arrayOf(Location.create(3419, 2917, 0), "nardah"), - arrayOf(Location.create(3482, 3090, 0), "uzer"), - arrayOf(Location.create(3358, 2970, 0), "pollnivneach", "poln"), - arrayOf(Location.create(3305, 2788, 0), "sophanem"), - arrayOf(Location.create(2898, 3544, 0), "burthorpe", "burthorp"), - arrayOf(Location.create(3088, 3491, 0), "edge", "edgeville"), - arrayOf(Location.create(3169, 3034, 0), "bedabin"), - arrayOf(Location.create(3565, 3289, 0), "barrows"), - arrayOf(Location.create(3016, 3513, 0), "bkf", "black knights fortress"), - arrayOf(Location.create(3052, 3481, 0), "monastery") - ) - - @JvmField - var DATABASE: Database? = null - - //if SQL is enabled - @JvmField - var MYSQL = true - - //the server name - @JvmField - var SERVER_NAME: String = "" - - //The RSA_KEY for the server. - @JvmField - var EXPONENT = BigInteger("52317200263721308660411803146360972546561037484450290559823448967617618536819222494429186211525706853703641369936136465589036631055945454547936148730495933263344792588795811788941129493188907621550836988152620502378278134421731002382361670176785306598134280732756356458964850508114958769985438054979422820241") - - //The MODULUS for the server. - @JvmField - var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051") - - /** - * Parses a JSONObject and retrieves the values for all settings in this file. - * @author Ceikry - * @param data : The JSONObject to parse. - */ - fun parse(data: JSONObject) { - MAX_PLAYERS = data["max_players"].toString().toInt() - MAX_NPCS = data["max_npcs"].toString().toInt() - - START_LOCATION = JSONUtils.parseLocation(data["new_player_location"].toString()) - HOME_LOCATION = JSONUtils.parseLocation(data["home_location"].toString()) - - DATA_PATH = JSONUtils.parsePath(data["data_path"].toString()) - CACHE_PATH = JSONUtils.parsePath(data["cache_path"].toString()) - STORE_PATH = JSONUtils.parsePath(data["store_path"].toString()) - PLAYER_SAVE_PATH = JSONUtils.parsePath(data["save_path"].toString()) - CONFIG_PATH = JSONUtils.parsePath(data["configs_path"].toString()) - PLAYER_ATTRIBUTE_PATH = PLAYER_SAVE_PATH + "attributes" + File.separator - GRAND_EXCHANGE_DATA_PATH = JSONUtils.parsePath(data["grand_exchange_data_path"].toString()) - BOT_DATA_PATH = JSONUtils.parsePath(data["bot_data_path"].toString()) - RDT_DATA_PATH = JSONUtils.parsePath(data["rare_drop_table_path"].toString()) - OBJECT_PARSER_PATH = JSONUtils.parsePath(data["object_parser_path"].toString()) - SCRIPTS_PATH = JSONUtils.parsePath(data["scripts_path"].toString()) - DIALOGUE_SCRIPTS_PATH = JSONUtils.parsePath(data["dialogue_scripts_path"].toString()) - if(data.containsKey("logs_path")){ - LOGS_PATH = data["logs_path"].toString() - } - if(data.containsKey("writeLogs")){ - WRITE_LOGS = data["writeLogs"] as Boolean - } - - DATABASE_NAME = data["database_name"].toString() - DATABASE_USER = data["database_username"].toString() - DATABASE_PASS = data["database_password"].toString() - DATABASE_ADDRESS = data["database_address"].toString() - DATABASE_PORT = data["database_port"].toString() - - DATABASE = Database(DATABASE_ADDRESS, DATABASE_NAME, DATABASE_USER, DATABASE_PASS) - } - } -} \ No newline at end of file diff --git a/Server/src/main/core/ServerConstants.kt b/Server/src/main/core/ServerConstants.kt index bad28925c..8c5f493a4 100644 --- a/Server/src/main/core/ServerConstants.kt +++ b/Server/src/main/core/ServerConstants.kt @@ -17,6 +17,9 @@ class ServerConstants { companion object { var NOAUTH_DEFAULT_ADMIN: Boolean = true + @JvmField + var CURRENT_SAVEFILE_VERSION = 4 + @JvmField var DAILY_ACCOUNT_LIMIT = 3 @@ -158,7 +161,7 @@ class ServerConstants { var LOG_CUTSCENE = true @JvmField - var RULES_AND_INFO_ENABLED = true + var RULES_AND_INFO_ENABLED = false @JvmField var WATCHDOG_ENABLED = true @@ -236,6 +239,8 @@ class ServerConstants { arrayOf(Location.create(2660, 3158, 0), "fishing trawler", "trawler"), arrayOf(Location.create(2800, 3667, 0), "mountain camp"), arrayOf(Location.create(2575, 3250, 0), "clocktower"), + arrayOf(Location.create(2544, 3759, 0), "waterbirth"), + arrayOf(Location.create(2899, 4450, 0), "dks"), arrayOf(CastleWars.lobbyBankArea.randomLoc, "cwars", "castle wars", "castle war", "castlewars", "castlewar", "castle") ) @@ -287,13 +292,16 @@ class ServerConstants { var DRAGON_AXE_USE_OSRS_SPEC = false @JvmField - var ENABLE_GLOBALCHAT = false + var ENABLE_GLOBAL_CHAT = false @JvmField var MAX_PATHFIND_DISTANCE = 25 @JvmField - var IRONMAN_ICONS = false + var XP_RATES = false + + @JvmField + var IRONMAN = false @JvmField var PLAYER_STOCK_CLEAR_INTERVAL = 1 @@ -305,16 +313,19 @@ class ServerConstants { var BOTSTOCK_LIMIT = 5000 @JvmField - var BETTER_AGILITY_PYRAMID_GP = true + var BETTER_AGILITY_PYRAMID_GP = false @JvmField - var BETTER_DFS = true + var BETTER_DFS = false @JvmField - var NEW_PLAYER_ANNOUNCEMENT = true + var NEW_PLAYER_ANNOUNCEMENT = false @JvmField - var HOLIDAY_EVENT_RANDOMS = true + var INAUTHENTIC_CANDLELIGHT_RANDOM = false + + @JvmField + var HOLIDAY_EVENT_RANDOMS = false @JvmField var FORCE_HALLOWEEN_EVENTS = false @@ -326,9 +337,57 @@ class ServerConstants { var FORCE_EASTER_EVENTS = false @JvmField - var RUNECRAFTING_FORMULA_REVISION = 581 + var APRIL_FOOLS_EVENT = false + + @JvmField + var FORCE_APRIL_FOOLS = false + + @JvmField + var RUNECRAFTING_FORMULA_REVISION = 530 + + @JvmField + var ENHANCED_DEEP_WILDERNESS = false + + @JvmField + var WILDERNESS_EXCLUSIVE_LOOT = false + + @JvmField + var SHOOTING_STAR_RING = false + + @JvmField + var RING_OF_WEALTH_TELEPORT = false + + @JvmField + var SECOND_BANK = false + + @JvmField + var PLAYER_COMMANDS = false + + @JvmField + var BOOSTED_TRAWLER_REWARDS = false @JvmField var STARTUP_MOMENT = Calendar.getInstance() + + @JvmField + var CONNECTIVITY_CHECK_URL = "https://google.com,https://2009scape.org" + + @JvmField + var CONNECTIVITY_TIMEOUT = 500 + + @JvmField + var WEBSOCKET_ENABLED = false + + @JvmField + var WEBSOCKET_PORT = 0 + + @JvmField + var WEBSOCKET_TLS_ENABLED = false + + @JvmField + var WEBSOCKET_TLS_KEYSTORE_PATH = "" + + @JvmField + var WEBSOCKET_TLS_KEYSTORE_PASSWORD = "" } } diff --git a/Server/src/main/core/ServerStore.kt b/Server/src/main/core/ServerStore.kt index ad2678584..52df7fb52 100644 --- a/Server/src/main/core/ServerStore.kt +++ b/Server/src/main/core/ServerStore.kt @@ -113,18 +113,18 @@ class ServerStore : PersistWorld { } @JvmStatic - fun JSONObject.getString(key: String): String { - return this[key] as? String ?: "nothing" + fun JSONObject.getString(key: String, default: String = "nothing"): String { + return this[key] as? String ?: default } @JvmStatic - fun JSONObject.getLong(key: String): Long { - return this[key] as? Long ?: 0L + fun JSONObject.getLong(key: String, default: Long = 0L): Long { + return this[key] as? Long ?: default } @JvmStatic - fun JSONObject.getBoolean(key: String): Boolean { - return this[key] as? Boolean ?: false + fun JSONObject.getBoolean(key: String, default: Boolean = false): Boolean { + return this[key] as? Boolean ?: default } fun List.toJSONArray(): JSONArray{ diff --git a/Server/src/main/core/api/Container.kt b/Server/src/main/core/api/Container.kt index 590d94a61..bdcfd4900 100644 --- a/Server/src/main/core/api/Container.kt +++ b/Server/src/main/core/api/Container.kt @@ -3,5 +3,6 @@ package core.api enum class Container { INVENTORY, BANK, - EQUIPMENT + EQUIPMENT, + BoB } \ No newline at end of file diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 8bd1ef83e..7423518a7 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -1,36 +1,68 @@ package core.api import com.moandjiezana.toml.Toml +import content.data.Quests +import content.data.consumables.* +import content.data.skill.SkillingTool +import content.global.handlers.iface.ge.StockMarket +import content.global.skill.construction.decoration.pohstorage.StorableFamily +import content.global.skill.construction.decoration.pohstorage.StorageInterface +import content.global.skill.slayer.SlayerEquipmentFlags +import content.global.skill.slayer.SlayerFlags +import content.global.skill.slayer.SlayerManager +import content.global.skill.slayer.Tasks +import content.global.skill.summoning.familiar.BurdenBeast +import core.ServerConstants +import core.api.utils.PlayerStatsCounter +import core.api.utils.Vector +import core.cache.def.impl.AnimationDefinition import core.cache.def.impl.ItemDefinition import core.cache.def.impl.SceneryDefinition import core.cache.def.impl.VarbitDefinition +import core.game.activity.Cutscene import core.game.component.Component +import core.game.consumable.* import core.game.container.impl.EquipmentContainer +import core.game.dialogue.DialogueFile +import core.game.dialogue.SkillDialogueHandler +import core.game.diary.DiaryLevel +import core.game.ge.GrandExchangeRecords +import core.game.interaction.* import core.game.node.Node import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatSwingHandler import core.game.node.entity.combat.ImpactHandler import core.game.node.entity.impl.Animator import core.game.node.entity.impl.ForceMovement import core.game.node.entity.impl.Projectile import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor import core.game.node.entity.player.link.HintIconManager import core.game.node.entity.player.link.IronmanMode import core.game.node.entity.player.link.TeleportManager import core.game.node.entity.player.link.audio.Audio +import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.player.link.emote.Emotes -import core.game.node.entity.player.link.quest.QuestRepository import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.link.quest.QuestRepository import core.game.node.entity.skill.Skills -import content.data.skill.SkillingTool -import content.global.skill.slayer.Tasks -import content.global.skill.summoning.familiar.BurdenBeast import core.game.node.item.GroundItem import core.game.node.item.GroundItemManager import core.game.node.item.Item import core.game.node.scenery.Scenery import core.game.node.scenery.SceneryBuilder +import core.game.requirement.* +import core.game.shops.Shops +import core.game.system.config.ItemConfigParser +import core.game.system.config.ServerConfigParser import core.game.system.task.Pulse +import core.game.system.timer.* +import core.game.system.timer.impl.* +import core.game.world.GameWorld +import core.game.world.GameWorld.Pulser import core.game.world.map.Direction import core.game.world.map.Location import core.game.world.map.RegionManager @@ -39,48 +71,21 @@ import core.game.world.map.path.Pathfinder import core.game.world.map.zone.MapZone import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBuilder +import core.game.world.repository.Repository +import core.game.world.update.flag.* import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag +import core.game.world.update.flag.context.* +import core.net.packet.PacketRepository +import core.net.packet.context.DefaultContext +import core.net.packet.context.MusicContext +import core.net.packet.out.AudioPacket +import core.net.packet.out.MusicPacket +import core.tools.* import org.rs09.consts.Items import org.rs09.consts.NPCs -import core.game.dialogue.DialogueFile -import core.game.dialogue.SkillDialogueHandler -import core.api.utils.GlobalKillCounter -import core.game.shops.Shops -import core.game.ge.GrandExchangeRecords -import core.game.interaction.InteractionListeners -import content.global.handlers.iface.ge.StockMarket -import content.global.skill.slayer.SlayerManager -import content.data.consumables.* -import core.game.activity.Cutscene -import core.game.interaction.* -import core.game.node.entity.player.info.LogType -import core.game.node.entity.player.info.PlayerMonitor -import core.tools.SystemLogger -import core.game.system.config.ItemConfigParser -import core.game.system.config.ServerConfigParser -import core.game.world.GameWorld -import core.game.world.GameWorld.Pulser -import core.game.world.repository.Repository -import core.game.consumable.* -import core.ServerConstants -import core.api.utils.Vector -import core.cache.def.impl.AnimationDefinition -import core.game.node.entity.player.link.quest.Quest -import core.tools.* -import core.game.world.update.flag.* -import core.game.world.update.flag.context.* -import core.game.requirement.* -import core.net.packet.PacketRepository -import core.net.packet.context.MusicContext -import core.net.packet.out.MusicPacket -import core.game.system.timer.* -import core.game.system.timer.impl.* -import core.game.node.entity.combat.CombatSwingHandler -import core.net.packet.context.DefaultContext -import core.net.packet.out.AudioPacket import org.rs09.consts.Sounds -import java.util.regex.* import java.io.* +import java.util.regex.* import kotlin.math.* /** @@ -195,6 +200,18 @@ fun inEquipment(player: Player, id: Int, amount: Int = 1): Boolean { return amountInEquipment(player, id) >= amount } +/** + * Check if any item is in a player's inventory + * @param player the player + * @param ids the set of item ids to check + * @return true if the player has at least one of the items in their inventory, false if none are present + */ +fun anyInInventory(player: Player, vararg ids: Int): Boolean { + return ids.any{ id -> + inInventory(player, id) + } +} + /** * Check if an item exists in a player's equipment or inventory * @param player the player whose equipment to check @@ -249,17 +266,58 @@ class ContainerisedItem(val container: core.game.container.Container?, val itemI } /** - * Check if player has any of the specified item IDs equipped, in inventory, or in banks - * Returns a ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found + * Check if player has the specified item ID equipped, in inventory, or in their bank + * @param id The item ID to check + * @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found */ -fun hasAnItem(player: Player, vararg ids: Int): ContainerisedItem { - for (searchSpace in arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary)) { +fun hasAnItem(player: Player, id: Int): ContainerisedItem { + return hasAnItem(player, arrayOf(id), false) +} + +/** + * Check if player has the specified item ID equipped, in inventory, or in their bank + * @param id The item ID to check + * @param checkSecondBank Whether to check the player's second bank. + * @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found + */ +fun hasAnItem(player: Player, id: Int, checkSecondBank: Boolean): ContainerisedItem { + return hasAnItem(player, arrayOf(id), checkSecondBank) +} + +/** + * Check if player has any of the specified item IDs equipped, in inventory, or in their bank + * @param ids An array of item IDs to check + * @param checkSecondBank Whether to check the player's second bank. + * @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found + */ +fun hasAnItem(player: Player, ids: Array, checkSecondBank: Boolean): ContainerisedItem { + // Search bank/equip/inv and return if item is found there. + val searchSpace = if (checkSecondBank) { + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary) + } else { + arrayOf(player.inventory, player.equipment, player.bankPrimary) + } + for (container in searchSpace) { for (id in ids) { - if (searchSpace.containItems(id)) { - return ContainerisedItem(searchSpace, id) + if (container.containItems(id)) { + return ContainerisedItem(container, id) } } } + + // Check all costume storage containers and return if item is found there. + for (id in ids) { + if (StorableFamily.values().any { family -> + player.getPOHStorageState() + .getContainer(family) + .contains(id) + }) { + // Note that this proxy container is a fake container just used to get the correct return type. + return ContainerisedItem(player.POHStorageProxyContainer, id) + } + } + + // Item is not found. return ContainerisedItem(null, -1) } @@ -302,9 +360,33 @@ fun removeItem(player: Player, item: T, container: Container = Container.INV Container.INVENTORY -> player.inventory.remove(it) Container.BANK -> player.bank.remove(it) || player.bankSecondary.remove(it) Container.EQUIPMENT -> player.equipment.remove(it) + Container.BoB -> { + if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast) + (player.familiarManager.familiar as BurdenBeast).container.remove(it) + else + false + } } } +/** + * Remove items in a players inventory + * Checks that the player has enough first + * @param player + * @param items the items to remove + */ +fun removeItemsIfPlayerHasEnough(player: Player, vararg items: Item): Boolean { + for (item in items) { + if (amountInInventory(player, item.id) >= 1) continue + return false + } + for (item in items) { + if (removeItem(player, item)) continue + return false + } + return true +} + /** * Add an item to the given player's given container * @param player the player whose container to modify @@ -318,6 +400,12 @@ fun addItem(player: Player, id: Int, amount: Int = 1, container: Container = Con Container.INVENTORY -> player.inventory Container.BANK -> player.bank Container.EQUIPMENT -> player.equipment + Container.BoB -> { + if(player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast) + (player.familiarManager.familiar as BurdenBeast).container + else + return false + } } return cont.add(Item(id, amount)) @@ -328,6 +416,7 @@ fun addItem(player: Player, id: Int, amount: Int = 1, container: Container = Con * @param player the player whose container to modify * @param slot the slot to use * @param item the item to replace the slot with + * @param currentItem the current item that is being replaced * @param container the Container to modify * @return the item that was previously in the slot, or null if none. */ @@ -336,6 +425,7 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null Container.INVENTORY -> player.inventory Container.EQUIPMENT -> player.equipment Container.BANK -> player.bank + Container.BoB -> (player.familiarManager.familiar as BurdenBeast).container } if (item.id == 65535 || item.amount <= 0) { @@ -347,7 +437,7 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null } if (cont.remove(currentItem, slot, true)) { - return cont.replace(item, slot) + return cont.replace(item, slot) ?: currentItem } PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential slot-replacement-based dupe attempt, slot: $slot, item: $item") @@ -355,11 +445,54 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null Container.INVENTORY -> Container.EQUIPMENT else -> Container.INVENTORY } - if (removeItem(player, currentItem, other)) - return cont.replace(item, slot) + if (removeItem(player, currentItem, other)) { + return cont.replace(item, slot) ?: currentItem + } return null } +/** + * Replaces all items a player owns anywhere (equipment, inventory, bank, second bank) + * @param player the player whose inventory to remove the item from + * @param itemId the item ID to replace + * @param replaceId the replacement item ID + * @author Player Name + */ +fun replaceAllItems(player: Player, itemId: Int, replaceId: Int) { + val item = Item(itemId) + val containers = if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast()) { + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary, (player.familiarManager.familiar as BurdenBeast).container) + } else { + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary) + } + for (container in containers) { + val hasItems = container.getAll(item) + if (!item.definition.isStackable && container != player.bankPrimary && container != player.bankSecondary) { + // just replace + for (target in hasItems) { + val newItem = Item(replaceId, target.amount) + container.replace(newItem, target.slot, true) + } + } else { + // add to existing stack if possible + if (hasItems.size > 0) { + val target = hasItems[0] + var count = 0 + for (x in hasItems) { + count += x.amount + } + val newItem = Item(replaceId, count) + container.replace(newItem, target.slot, true) + } + if (hasItems.size > 1) { + for (i in 1 until hasItems.size) { + container.remove(hasItems[i], hasItems[i].slot, true) + } + } + } + } +} + /** * Add an item with a variable quantity or drop it if a player does not have enough space * @param player the player whose inventory to add to @@ -378,6 +511,26 @@ fun addItemOrDrop(player: Player, id: Int, amount: Int = 1) { } } +/** + * Add an item with a variable quantity or bank it if a player does not have enough space, or drop it if that still doesn't work + * @param player the player whose inventory to add to + * @param id the ID of the item to add to the player's inventory + * @param amount the amount of the ID to add to the player's inventory, defaults to 1 + */ +fun addItemOrBank(player: Player, id: Int, amount: Int = 1) { + val item = Item(id, amount) + if (!player.inventory.add(item)) { + if (player.ironmanManager.mode != IronmanMode.ULTIMATE && player.bankPrimary.add(item)) { + sendMessage(player, colorize("%RThe ${item.name} has been sent to your bank.")) + } else if (player.ironmanManager.mode != IronmanMode.ULTIMATE && player.bankSecondary.add(item)) { + sendMessage(player, colorize("%RThe ${item.name} has been sent to your secondary bank.")) + } else { + GroundItemManager.create(item, player) + sendMessage(player, colorize("%RAs your inventory and bank account(s) are all full, the ${item.name} has been placed on the ground under your feet. Don't forget to grab it. (Also consider cleaning out some stuff, maybe? I mean, Jesus!)")) + } + } +} + /** * Clears an NPC with the "poof" smoke graphics commonly seen with random event NPCs. * @param npc the NPC object to initialize @@ -901,6 +1054,14 @@ fun openDialogue(player: Player, dialogue: Any, vararg args: Any) { } } +/** + * Closes any opened dialogue. + */ +fun closeDialogue(player: Player) { + player.dialogueInterpreter.close() + player.interfaceManager.closeChatbox() +} + /** * Gets an NPC with the given ID from the repository. * @param id the ID of the NPC to locate @@ -1181,6 +1342,25 @@ fun transformNpc(npc: NPC, transformTo: Int, restoreTicks: Int) { }) } +/** + * Transforms an NPC for the given number of ticks with hp carryover + * @param npc the NPC object to transform + * @param transformTo the ID of the NPC to turn into + * @param restoreTicks the number of ticks until the NPC returns to normal + */ +fun transformNpcWithHpCarryover(npc: NPC, transformTo: Int, restoreTicks: Int) { + npc.transformWithHpCarryover(transformTo) + queueScript(npc, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> return@queueScript delayScript(npc, restoreTicks) + else -> { + npc.reTransform() + return@queueScript stopExecuting(npc) + } + } + } +} + /** * Produces a Location object using the given x,y,z values */ @@ -1227,10 +1407,19 @@ fun getVarbit (player: Player, varbitId: Int) : Int { @JvmOverloads fun setVarp (player: Player, varpIndex: Int, value: Int, save: Boolean = false) { player.varpMap[varpIndex] = value - player.saveVarp[varpIndex] = save + if (player.saveVarp[varpIndex] != true && save) + player.saveVarp[varpIndex] = true //only set if we're choosing to save. Prevents accidental unsaving. if you REALLY want to unsave a varp, use unsaveVarp. player.packetDispatch.sendVarp(varpIndex, value) } +fun saveVarp (player: Player, varpIndex: Int) { + player.saveVarp[varpIndex] = true +} + +fun unsaveVarp (player: Player, varpIndex: Int) { + player.saveVarp.remove(varpIndex) +} + @JvmOverloads fun setVarbit (player: Player, def: VarbitDefinition, value: Int, save: Boolean = false) { val mask = def.mask @@ -1251,6 +1440,11 @@ fun setVarbit (player: Player, varbitId: Int, value: Int, save: Boolean = false) setVarbit (player, def, value, save) } +fun setVarc (player: Player, varc: Int, value: Int) +{ + player.packetDispatch.sendVarcUpdate(varc.toShort(), value) +} + fun reinitVarps (player: Player) { for ((index, value) in player.varpMap) { setVarp(player, index, value, player.saveVarp[index] ?: false) @@ -1542,6 +1736,14 @@ fun removeAll(player: Player, item: T, container: Container = Container.INVE player.bank.remove(Item(it, amountInPrimary)) && player.bankSecondary.remove(Item(it, amountInSecondary)) } Container.INVENTORY -> player.inventory.remove(Item(it, amountInInventory(player, it))) + Container.BoB -> { + if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast){ + val cont = (player.familiarManager.familiar as BurdenBeast).container + cont.remove(Item(it, cont.getAmount(it))) + } + else + false + } } } @@ -1583,14 +1785,25 @@ fun closeTabInterface(player: Player) { player.interfaceManager.closeSingleTab() } +/** + * Closes any open (both chat and non-chat) interfaces for the player + * @param player the player to close the interfaces for + */ +fun closeAllInterfaces(player: Player) { + player.interfaceManager.close() + player.interfaceManager.closeChatbox() + player.dialogueInterpreter.close() +} + /** * Sends a dialogue that uses the player's chathead. * @param player the player to send the dialogue to * @param msg the message to send. * @param expr the FacialExpression to use. An enum exists for these called FacialExpression. Defaults to FacialExpression.FRIENDLY + * @param hide should the continue button be hidden? */ -fun sendPlayerDialogue(player: Player, msg: String, expr: core.game.dialogue.FacialExpression = core.game.dialogue.FacialExpression.FRIENDLY) { - player.dialogueInterpreter.sendDialogues(player, expr, *splitLines(msg)) +fun sendPlayerDialogue(player: Player, msg: String, expr: core.game.dialogue.FacialExpression = core.game.dialogue.FacialExpression.FRIENDLY, hide: Boolean = false) { + player.dialogueInterpreter.sendDialogues(player, expr, hide, *splitLines(msg)) } /** @@ -1604,14 +1817,28 @@ fun sendPlayerOnInterface(player: Player, iface: Int, child: Int) { } /** - * Sends a dialogue that uses the player's chathead. + * Sends a dialogue that uses the npc's chathead. * @param player the player to send the dialogue to * @param npc the ID of the NPC to use for the chathead * @param msg the message to send. * @param expr the FacialExpression to use. An enum exists for these called FacialExpression. Defaults to FacialExpression.FRIENDLY + * @param hide should the continue button be hidden? */ -fun sendNPCDialogue(player: Player, npc: Int, msg: String, expr: core.game.dialogue.FacialExpression = core.game.dialogue.FacialExpression.FRIENDLY) { - player.dialogueInterpreter.sendDialogues(npc, expr, *splitLines(msg)) +fun sendNPCDialogue(player: Player, npc: Int, msg: String, expr: core.game.dialogue.FacialExpression = core.game.dialogue.FacialExpression.FRIENDLY, + hide: Boolean = false) { + player.dialogueInterpreter.sendDialogues(npc, expr, hide, *splitLines(msg)) +} + +/** + * Sends a dialogue that uses the npc's chathead. + * @param player the player to send the dialogue to + * @param npc the ID of the NPC to use for the chathead + * @param expr the FacialExpression to use. An enum exists for these called FacialExpression. + * @param msg the message to send. + */ +fun sendNPCDialogueLines(player: Player, npc: Int, expr: core.game.dialogue.FacialExpression, hideContinue: Boolean, vararg msgs: String) { + val dialogueComponent = player.dialogueInterpreter.sendDialogues(npc, expr, *msgs) + player.packetDispatch.sendInterfaceConfig(dialogueComponent.id, msgs.size + 4, hideContinue) } /** @@ -1692,8 +1919,11 @@ fun sendItemDialogue(player: Player, item: Any, message: String) { * @param item2 the ID of the second item to show * @param message the text to display */ -fun sendDoubleItemDialogue(player: Player, item1: Int, item2: Int, message: String) { - player.dialogueInterpreter.sendDoubleItemMessage(item1, item2, message) +fun sendDoubleItemDialogue(player: Player, item1: Any, item2: Any, message: String) { + when (item1) { + is Item -> player.dialogueInterpreter.sendDoubleItemMessage(item1, item2 as Item, *splitLines(message)) + is Int -> player.dialogueInterpreter.sendDoubleItemMessage(item1, item2 as Int, *splitLines(message)) + } } /** @@ -1767,7 +1997,7 @@ fun runTask(entity: Entity, delay: Int = 0, repeatTimes: Int = 1, task: () -> Un entity.pulseManager.run(object : Pulse(delay) { override fun pulse(): Boolean { task.invoke() - return --cycles == 0 + return --cycles <= 0 } }) } @@ -1784,29 +2014,33 @@ fun getQuestPoints(player: Player): Int { /** * Gets the stage for the given quest for the given player */ -fun getQuestStage(player: Player, quest: String): Int { +fun getQuestStage(player: Player, quest: Quests): Int { return player.questRepository.getStage(quest) } /** * Sets the stage for the given quest for the given player */ -fun setQuestStage(player: Player, quest: String, stage: Int) { +fun setQuestStage(player: Player, quest: Quests, stage: Int) { player.questRepository.setStage(QuestRepository.getQuests()[quest]!!, stage) player.questRepository.syncronizeTab(player) } /** - * Check if a quest is in progress + * Check if a quests' stage for a given player is (inclusively) between the provided start and end stage */ -fun isQuestInProgress(player: Player, quest: String, startStage: Int, endStage: Int): Boolean { +fun isQuestInProgress(player: Player, quest: Quests, startStage: Int, endStage: Int): Boolean { return player.questRepository.getStage(quest) in startStage..endStage } +fun isQuestStarted(player: Player, quest: Quests): Boolean { + return getQuestStage(player, quest) > 0 +} + /** * Check if a quest is complete */ -fun isQuestComplete(player: Player, quest: String): Boolean { +fun isQuestComplete(player: Player, quest: Quests): Boolean { return player.questRepository.getStage(quest) == 100 } @@ -1816,7 +2050,7 @@ fun isQuestComplete(player: Player, quest: String): Boolean { * @param quest The quest name string * @return the quest object */ -fun getQuest(player: Player, quest: String): Quest { +fun getQuest(player: Player, quest: Quests): Quest { return player.questRepository.getQuest(quest) } @@ -1824,7 +2058,7 @@ fun getQuest(player: Player, quest: String): Quest { /** * Check if a player meets the requirements to start a quest, and then starts it if they do. Returns success bool */ -fun startQuest(player: Player, quest: String): Boolean { +fun startQuest(player: Player, quest: Quests): Boolean { val quest = player.questRepository.getQuest(quest) val canStart = quest.hasRequirements(player) if (!canStart) return false @@ -1835,7 +2069,7 @@ fun startQuest(player: Player, quest: String): Boolean { /** * Finishes a quest, gives rewards, marks as completed, etc */ -fun finishQuest(player: Player, quest: String) { +fun finishQuest(player: Player, quest: Quests) { player.questRepository.getQuest(quest).finish(player) } @@ -1932,7 +2166,7 @@ fun runcs2 (player: Player, scriptId: Int, vararg arguments: Any) { * @param callback a callback to handle the selection. The parameters passed to the callback are the slot in the inventory of the selected item, and the 0-9 index of the option clicked. **/ @JvmOverloads -fun sendItemSelect (player: Player, vararg options: String, keepAlive: Boolean = false, callback: (slot: Int, optionIndex: Int) -> Unit) { +fun sendItemSelect(player: Player, vararg options: String, keepAlive: Boolean = false, callback: (slot: Int, optionIndex: Int) -> Unit) { player.interfaceManager.openSingleTab(Component(12)) val scriptArgs = arrayOf ((12 shl 16) + 18, 93, 4, 7, 0, -1, "", "", "", "", "", "", "", "", "") for (i in 0 until min(9, options.size)) @@ -1949,11 +2183,11 @@ fun sendItemSelect (player: Player, vararg options: String, keepAlive: Boolean = fun announceIfRare(player: Player, item: Item) { if (item.definition.getConfiguration(ItemConfigParser.RARE_ITEM, false)) { sendNews("${player.username} has just received: ${item.amount} x ${item.name}.") - GlobalKillCounter.incrementRareDrop(player, item) + PlayerStatsCounter.incrementRareDrop(player, item) } } -fun hasRequirement (player: Player, req: QuestReq, message: Boolean = true) : Boolean { +fun hasRequirement(player: Player, req: QuestReq, message: Boolean = true) : Boolean { var (isMet, unmetReqs) = req.evaluate(player) val messageList = ArrayList() @@ -1974,9 +2208,9 @@ fun hasRequirement (player: Player, req: QuestReq, message: Boolean = true) : Bo if (isMet) return true if (unmetReqs.size == 2 && unmetReqs[0] is QuestReq) { - messageList.add ("This requires completion of ${(unmetReqs[0] as QuestReq).questReq.questName} to access.") + messageList.add ("This requires completion of ${(unmetReqs[0] as QuestReq).questReq.quest} to access.") } else { - messageList.add ("You need the pre-reqs for ${req.questReq.questName} to access this.") + messageList.add ("You need the pre-reqs for ${req.questReq.quest} to access this.") messageList.add ("Please check the page in your quest journal for more info.") } @@ -1988,8 +2222,8 @@ fun hasRequirement (player: Player, req: QuestReq, message: Boolean = true) : Bo } @JvmOverloads -fun hasRequirement (player: Player, quest: String, message: Boolean = true) : Boolean { - val questReq = QuestRequirements.values().filter { it.questName.equals(quest, true) }.firstOrNull() ?: return false +fun hasRequirement(player: Player, quest: Quests, message: Boolean = true) : Boolean { + val questReq = QuestRequirements.values().firstOrNull { it.quest == quest } ?: return false return hasRequirement(player, QuestReq(questReq), message) } @@ -2030,6 +2264,10 @@ fun dumpContainer(player: Player, container: core.game.container.Container): Int var dumpedCount = 0 run beginDepositing@{ + if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + return@beginDepositing + } + container.toArray().filterNotNull().forEach { item -> if (!bank.hasSpaceFor(item)) { sendMessage(player, "You have no more space in your bank.") @@ -2045,10 +2283,13 @@ fun dumpContainer(player: Player, container: core.game.container.Container): Int sendMessage(player, "A magical force prevents you from removing your ${item.name}.") return@forEach } + if (SlayerEquipmentFlags.isSlayerEq(item.id)) { + SlayerEquipmentFlags.updateFlags(player) + } } container.remove(item) - bank.add(unnote(item)) + bank.add(unnote(item), false) dumpedCount++ } } @@ -2174,6 +2415,68 @@ fun Player.getCutscene(): Cutscene? { return getAttribute(this, Cutscene.ATTRIBUTE_CUTSCENE, null) } +/** + * Stores a book in the POH storage + * If this is the first time reading the book, store it in POH bookcase if eligible + * @param player the player + * @param itemID the ID of the book that was interacted with + * @return True if the item was identified and processed (whether read or not) + * False if the node was not a book or did not have a bitIndex + */ +fun storeBookInHouse(player: Player, itemId: Int): Boolean { + // find the corresponding Storable object + val storable = StorageInterface.findStorableByDisplayId(itemId) ?: return false + + // check if the storable is tracked + if (storable.bitIndex == -1) { + return true + } + + // retrieve bitfields where the values of already-read books are stored, and if the book has been read previously + val bits = StorageInterface.BookcaseBitfields.get(player) + val isRead = StorageInterface.BookcaseBitfields.isBitSet(bits, storable.bitIndex) + + // special check for games book. It isn't normally available and is only obtainable from the bookcase. You can't read it without first having it, and if you lose it you can't go back to somewhere else to get a new copy. Thus, it is always spawned in. + if(itemId == Items.GAME_BOOK_7681) { + val updatedBits = StorageInterface.BookcaseBitfields.setBit(bits, storable.bitIndex) + val container = StorageInterface.getStorageContainer(player, StorableFamily.BOOKCASE) + if (!isRead) { + StorageInterface.BookcaseBitfields.set(player, updatedBits) + container.addItem(itemId) + } else { + container.addItem(itemId) + } + + return true + } + + // if book is not read, store it in house + if (!isRead) { + // update bitfields + val updatedBits = StorageInterface.BookcaseBitfields.setBit(bits, storable.bitIndex) + StorageInterface.BookcaseBitfields.set(player, updatedBits) + + // add to the POH container + val container = StorageInterface.getStorageContainer(player, StorableFamily.BOOKCASE) + container.addItem(itemId) + } + return true +} + +/** + * Stores a book in the POH storage + * If this is the first time reading the book, store it in POH bookcase if eligible + * Used inside interaction listeners ("read") on nodes (books) + * @param player the player + * @param node the node (book) that was interacted with + * @return True if the item was identified and processed (whether read or not) + * False if the node was not a book or did not have a bitIndex + */ +fun storeBookInHouse(player: Player, node: Node): Boolean { + val bookId = (node as? Item)?.id ?: return false + return storeBookInHouse(player, bookId) +} + fun Player.getCutsceneStage(): Int { return getAttribute(this, Cutscene.ATTRIBUTE_CUTSCENE_STAGE, 0) } @@ -2296,7 +2599,11 @@ fun getSlayerTip(player: Player): Array { * @return the task flags as Int. */ fun getSlayerTaskFlags(player: Player): Int { - return SlayerManager.getInstance(player).flags.taskFlags + return getSlayerFlags(player).taskFlags +} + +fun getSlayerFlags(player: Player): SlayerFlags { + return SlayerManager.getInstance(player).flags } /** @@ -2681,15 +2988,15 @@ fun getCredits(player: Player) : Int { } /** - * Asserts that a quest is required, and sends the player "You must have completed the $questName quest $message" + * Asserts that a quest is required, and sends the player "You must have completed the $quest quest $message" * @param player the player we are checking - * @param questName the name of the quest we are checking for - * @param message the text appended to "You must have completed the $questName quest ..." if the quest is not complete. + * @param quest the quest we are checking for + * @param message the text appended to "You must have completed the $quest quest ..." if the quest is not complete. * @return whether or not the quest has been completed */ -fun requireQuest(player: Player, questName: String, message: String) : Boolean { - if (!isQuestComplete(player, questName)) { - sendMessage(player, "You must have completed the $questName quest $message") +fun requireQuest(player: Player, quest: Quests, message: String) : Boolean { + if (!isQuestComplete(player, quest)) { + sendMessage(player, "You must have completed the $quest quest $message") return false } return true @@ -2820,14 +3127,18 @@ fun queueScript(entity: Entity, delay: Int = 1, strength: QueueStrength = QueueS } /** - * Sets the clock to the value of WORLD_TICSK + ticks. + * Sets the clock to the value of WORLD_TICKS + ticks. * @param entity the entity whose clock we are updating * @param clock the clock we are updating. Please use [core.game.interaction.Clocks] for this argument. * @param ticks the number of ticks to delay by + * @param delayScript whether to delay the script by the number of ticks passed in. * @return always returns false so this can be used as a script return value. **/ -fun delayClock(entity: Entity, clock: Int, ticks: Int) : Boolean { +fun delayClock(entity: Entity, clock: Int, ticks: Int, delayScript: Boolean = false) : Boolean { entity.clocks[clock] = getWorldTicks() + ticks + if (delayScript) { + return delayScript(entity, ticks) + } return false } @@ -2880,11 +3191,18 @@ fun applyPoison (entity: Entity, source: Entity, severity: Int) { if(hasTimerActive(entity)) { return } + if(entity.isPoisonImmune()) { + return + } val existingTimer = getTimer(entity) if (existingTimer != null) { - existingTimer.severity = severity - existingTimer.damageSource = source + if (existingTimer.severity > severity) { + return + } else { + existingTimer.severity = severity + existingTimer.damageSource = source + } } else { registerTimer(entity, spawnTimer(source, severity)) } @@ -2994,7 +3312,7 @@ fun calculateDragonfireMaxHit(entity: Entity, maxDamage: Int, wyvern: Boolean = if (entity is Player) { hasShield = hasDragonfireShieldProtection(entity, wyvern) - hasPotion = !wyvern && getAttribute(entity, "fire:immune", 0) >= getWorldTicks() + hasPotion = !wyvern && hasTimerActive(entity) hasPrayer = entity.prayer.get(PrayerType.PROTECT_FROM_MAGIC) if (sendMessage) { @@ -3038,4 +3356,33 @@ fun openSingleTab(player: Player, component: Int) { player.interfaceManager.openSingleTab(Component(component)) } +/** + * Finish an achievement diary task for the player. + * @param player the player who just finished the task. + * @param diary the diary the task belongs to. + * @param level the level of the task. + * @param task The task that was just finished. + */ +fun finishTask(player: Player, diary: DiaryType, level: DiaryLevel, task: Int) { + player.achievementDiaryManager.finishTask(player, diary, getDiaryLevelIndex(diary, level), task) +} + +/** + * Resolves a [DiaryLevel] to an index for a specific diary. + * @param diary The diary the task belongs to. + * @param level The task level in the diary. + * @throws IllegalArgumentException if the level is not present in the diary. + * @return the index of the level that can be used with [core.game.node.entity.player.link.diary.AchievementDiaryManager.finishTask]. + */ +fun getDiaryLevelIndex(diary: DiaryType, level: DiaryLevel): Int { + val levelName = level.name.lowercase().replaceFirstChar { c -> c.uppercase() } + val levelIndex = diary.levelNames.indexOf(levelName) + + if (levelIndex < 0) { + throw IllegalArgumentException("'$levelName' was not found in diary '$diary'.") + } + + return levelIndex +} + private class ContentAPI diff --git a/Server/src/main/core/api/Event.kt b/Server/src/main/core/api/Event.kt index 1c1bc1ea1..a572dc4bb 100644 --- a/Server/src/main/core/api/Event.kt +++ b/Server/src/main/core/api/Event.kt @@ -23,6 +23,7 @@ object Event { @JvmStatic val AttributeSet = AttributeSetEvent::class.java @JvmStatic val AttributeRemoved = AttributeRemoveEvent::class.java @JvmStatic val SpellCast = SpellCastEvent::class.java + @JvmStatic val SpellbookChanged = SpellbookChangeEvent::class.java @JvmStatic val ItemAlchemized = ItemAlchemizationEvent::class.java @JvmStatic val ItemEquipped = ItemEquipEvent::class.java @JvmStatic val ItemUnequipped = ItemUnequipEvent::class.java diff --git a/Server/src/main/core/api/God.kt b/Server/src/main/core/api/God.kt index 58c880a97..70eb2b0fd 100644 --- a/Server/src/main/core/api/God.kt +++ b/Server/src/main/core/api/God.kt @@ -20,14 +20,11 @@ enum class God(vararg val validItems: Int) { Items.BANDOS_TASSETS_11726, ), SARADOMIN( - Items.ANCIENT_SYMBOL_11181, - Items.GILDED_KITESHIELD_3489, + Items.DAMAGED_BOOK_3839, Items.HOLY_BOOK_3840, Items.HOLY_SYMBOL_1718, - Items.HOLY_SYMBOL_4682, Items.MONKS_ROBE_542, Items.MONKS_ROBE_544, - Items.RUNE_HERALDIC_HELM_8488, Items.SARADOMIN_BRACERS_10384, Items.SARADOMIN_CAPE_2412, Items.SARADOMIN_CHAPS_10388, @@ -43,26 +40,16 @@ enum class God(vararg val validItems: Int) { Items.SARADOMIN_PLATEBODY_2661, Items.SARADOMIN_PLATELEGS_2663, Items.SARADOMIN_PLATESKIRT_3479, - Items.SARADOMIN_PLATESKIRT_3675, Items.SARADOMIN_ROBE_LEGS_10464, Items.SARADOMIN_ROBE_TOP_10458, Items.SARADOMIN_STAFF_2415, Items.SARADOMIN_STOLE_10470, Items.SARADOMIN_SWORD_11730, - Items.SARADOMIN_SYMBOL_8055, - Items.STEEL_HERALDIC_HELM_8706, ), ZAMORAK( - Items.DAGONHAI_HAT_14499, - Items.DAGONHAI_ROBE_TOP_14497, - Items.DAGONHAI_ROBE_BOTTOM_14501, Items.DAMAGED_BOOK_3841, - Items.RUNE_HERALDIC_HELM_8494, - Items.STEEL_HERALDIC_HELM_8712, Items.UNHOLY_BOOK_3842, Items.UNHOLY_SYMBOL_1724, - Items.UNHOLY_SYMBOL_3852, - Items.UNHOLY_SYMBOL_4683, Items.ZAMORAK_BRACERS_10368, Items.ZAMORAK_CAPE_2414, Items.ZAMORAK_CHAPS_10372, @@ -81,17 +68,17 @@ enum class God(vararg val validItems: Int) { Items.ZAMORAK_PLATEBODY_2653, Items.ZAMORAK_PLATELEGS_2655, Items.ZAMORAK_PLATESKIRT_3478, - Items.ZAMORAK_PLATESKIRT_3674, Items.ZAMORAK_ROBE_LEGS_10468, Items.ZAMORAK_ROBE_TOP_10460, Items.ZAMORAK_ROBE_TOP_10786, Items.ZAMORAK_STAFF_2417, Items.ZAMORAK_STOLE_10474, - Items.ZAMORAK_SYMBOL_8056, + Items.ZAMORAK_ROBE_1033, + Items.ZAMORAK_ROBE_1035, ), GUTHIX( - Items.STEEL_HERALDIC_HELM_8692, - Items.RUNE_HERALDIC_HELM_8474, + Items.DAMAGED_BOOK_3843, + Items.BOOK_OF_BALANCE_3844, Items.GUTHIX_BRACERS_10376, Items.GUTHIX_CAPE_10720, Items.GUTHIX_CHAPS_10380, @@ -100,30 +87,18 @@ enum class God(vararg val validItems: Int) { Items.GUTHIX_CROZIER_10442, Items.GUTHIX_DRAGONHIDE_10378, Items.GUTHIX_DRAGONHIDE_10794, - Items.GUTHIX_FULL_HELM_13833, Items.GUTHIX_FULL_HELM_2673, - Items.GUTHIX_KITESHIELD_13834, Items.GUTHIX_KITESHIELD_2675, Items.GUTHIX_MITRE_10454, Items.GUTHIX_MJOLNIR_6760, Items.GUTHIX_PLATEBODY_10780, Items.GUTHIX_PLATEBODY_2669, - Items.GUTHIX_PLATEBODY_13830, Items.GUTHIX_PLATELEGS_2671, - Items.GUTHIX_PLATELEGS_13831, - Items.GUTHIX_PLATESKIRT_13832, Items.GUTHIX_PLATESKIRT_3676, Items.GUTHIX_ROBE_LEGS_10466, Items.GUTHIX_ROBE_TOP_10462, Items.GUTHIX_ROBE_TOP_10788, Items.GUTHIX_STAFF_2416, Items.GUTHIX_STOLE_10472, - Items.GUTHIX_SYMBOL_8057 - ), - ZAROS( - Items.ANCIENT_STAFF_13406, - Items.ANCIENT_STAFF_4675, - Items.ANCIENT_MACE_11061, - Items.ANCIENT_BOOK_7633, ) } diff --git a/Server/src/main/core/api/utils/GlobalKillCounter.kt b/Server/src/main/core/api/utils/GlobalKillCounter.kt deleted file mode 100644 index eaecfe982..000000000 --- a/Server/src/main/core/api/utils/GlobalKillCounter.kt +++ /dev/null @@ -1,120 +0,0 @@ -package core.api.utils - -import core.api.ShutdownListener -import core.api.StartupListener -import core.game.node.entity.player.Player -import core.tools.SystemLogger -import java.io.File -import java.io.FileReader -import java.io.FileWriter -import org.json.simple.JSONObject -import org.json.simple.parser.JSONParser -import core.ServerConstants -import core.api.log -import core.game.node.item.Item -import core.tools.Log -import core.tools.SystemLogger.logShutdown -import core.tools.SystemLogger.logStartup - -class GlobalKillCounter : StartupListener, ShutdownListener { - override fun startup() { - logStartup("Parsing Global Kill Counts") - val file = File(ServerConstants.DATA_PATH + File.separator + "global_kill_stats.json") - if(!file.exists()) { - return - } - - val reader = FileReader(file) - val parser = JSONParser() - try { - val data = parser.parse(reader) as JSONObject - val tmp_kills = data.get("kills") - populate(kills, tmp_kills) - val tmp_rare_drops = data.get("rare_drops") - populate(rare_drops, tmp_rare_drops) - } catch (e: Exception){ - log(this::class.java, Log.ERR, "Failed parsing ${file.name} - stack trace below.") - e.printStackTrace() - } - } - - override fun shutdown() { - logShutdown("Saving Global Kill Counts") - val data = JSONObject() - data.put("kills", saveField(kills)) - data.put("rare_drops", saveField(rare_drops)) - val file = File(ServerConstants.DATA_PATH + File.separator + "global_kill_stats.json") - FileWriter(file).use { it.write(data.toJSONString()); it.flush(); it.close() } - } - - companion object { - val kills: HashMap> = HashMap() - val rare_drops: HashMap> = HashMap() - - @JvmStatic - fun populate(field: HashMap>, obj: Any?) { - if(obj != null && obj is JSONObject) { - for((player, tmp_kc) in obj.asIterable()) { - if(player is String) { - val kc: HashMap = HashMap() - for((npc_id, count) in (tmp_kc as JSONObject).asIterable()) { - kc.put(java.lang.Long.parseLong(npc_id as String), count as Long) - } - field.put(player, kc) - } - } - } - } - - @JvmStatic - fun saveField(field: HashMap>): JSONObject { - val tmp_kills = JSONObject() - for((player, kc) in field.asIterable()) { - val tmp_kc = JSONObject() - for((id, count) in kc.asIterable()) { - tmp_kc.put(id, count) - } - tmp_kills.put(player, tmp_kc) - } - return tmp_kills - } - - @JvmStatic - fun save() { - - } - - @JvmStatic - fun incrementKills(player: Player, npc_id: Int) { - val player_kills = kills.getOrPut(player.username, { HashMap() }) - val old_amount = player_kills.getOrElse(npc_id.toLong(), { 0 }) - player_kills.put(npc_id.toLong(), 1 + old_amount) - } - - @JvmStatic - fun incrementRareDrop(player: Player, item: Item) { - val player_drops = rare_drops.getOrPut(player.username, { HashMap() }) - val old_amount = player_drops.getOrElse(item.id.toLong(), { 0 }) - player_drops.put(item.id.toLong(), item.amount + old_amount) - } - - @JvmStatic - fun getKills(player: Player, npc_id: Int): Long { - return kills.getOrElse(player.username, { HashMap() }).getOrElse(npc_id.toLong(), { 0 }) - } - - @JvmStatic - fun getKills(player: Player, npc_ids: IntArray): Long { - var sum: Long = 0 - for(npc_id in npc_ids) { - sum += getKills(player, npc_id) - } - return sum - } - - @JvmStatic - fun getRareDrops(player: Player, item_id: Int): Long { - return rare_drops.getOrElse(player.username, { HashMap() }).getOrElse(item_id.toLong(), { 0 }) - } - } -} diff --git a/Server/src/main/core/api/utils/Permadeath.kt b/Server/src/main/core/api/utils/Permadeath.kt index d74c6fef9..478c9b90a 100644 --- a/Server/src/main/core/api/utils/Permadeath.kt +++ b/Server/src/main/core/api/utils/Permadeath.kt @@ -1,31 +1,73 @@ -package core.api.utils.Permadeath +package core.api.utils -import core.api.* +import content.global.skill.construction.HouseLocation +import content.minigame.blastfurnace.BFPlayerState +import content.minigame.blastfurnace.BlastFurnace +import core.ServerConstants +import core.api.isUsingSecondaryBankAccount +import core.api.teleport +import core.api.toggleBankAccount import core.game.node.entity.player.Player import core.game.node.entity.player.VarpManager import core.game.node.entity.player.info.login.PlayerSaver +import core.game.node.entity.player.link.IronmanMode import core.game.node.entity.player.link.SavedData +import core.game.node.entity.player.link.SpellBookManager import core.game.node.entity.player.link.diary.DiaryType import core.game.node.entity.player.link.quest.QuestRepository import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager import core.game.world.map.Location +import java.util.ArrayList fun permadeath(target: Player) { teleport(target, Location.create(3094, 3107, 0)) - target.equipment.clear() + + // Core target.inventory.clear() + target.bank.clear() + target.bankSecondary.clear() + for (i in target.bankPrimary.tabStartSlot.indices) { + target.bankPrimary.tabStartSlot[i] = 0 + } + for (i in target.bankSecondary.tabStartSlot.indices) { + target.bankSecondary.tabStartSlot[i] = 0 + } if (isUsingSecondaryBankAccount(target)) { toggleBankAccount(target) } - target.bank.clear() - target.bankSecondary.clear() - target.skills = Skills(target) - target.clearAttributes() - target.savedData = SavedData(target) - target.questRepository = QuestRepository(target) + target.equipment.clear() target.varpManager = VarpManager(target) target.varpMap.clear() target.saveVarp.clear() + target.timers.clearTimers() + + // Skills + target.skills = Skills(target) + + // Settings can be kept + + // Quests + target.questRepository = QuestRepository(target) + + // Appearance doesn't matter because you're going to tutorial island anyway + + // Spellbook + target.spellBookManager.setSpellBook(SpellBookManager.SpellBook.MODERN) + + // Saved data + target.savedData = SavedData(target) + + // Autocast + target.properties.autocastSpell = null + + // Player monitor is a no-op + + // Music player + target.musicPlayer.clearUnlocked() + + // Familiar manager if (target.familiarManager.hasFamiliar()) { target.familiarManager.dismiss() } @@ -33,6 +75,15 @@ fun permadeath(target: Player) { for (key in petKeys) { target.familiarManager.removeDetails(key) } + + // Bank pin data + target.bankPinManager.doCancelPin() + + // House data + target.houseManager.createNewHouseAt(HouseLocation.NOWHERE) + target.getPOHStorageState().clear() + + // Achievements for (type in DiaryType.values()) { val diary = target.achievementDiaryManager.getDiary(type) for (level in 0 until diary.levelStarted.size) { @@ -41,7 +92,45 @@ fun permadeath(target: Player) { } } } - target.musicPlayer.clearUnlocked() + + // Xp rate + target.skills.experienceMultiplier = 1.0 + + // Ironman data + target.ironmanManager.mode = IronmanMode.NONE + + // Emote data + target.emoteManager.emotes.clear() + + // Stat manager is a no-op + + // Attributes + target.clearAttributes() + + // Pouches + for (pouch in target.pouchManager.pouches.values) { + pouch.container.clear() + pouch.currentCap = pouch.capacity + pouch.charges = pouch.maxCharges + pouch.remakeContainer() + } + + // Destroy any dropped items to prevent droptrading to yourself after death + val droppedItems = ArrayList(); + for (item in GroundItemManager.getItems()) { + if (item.dropperUid == target.details.uid) { + droppedItems.add(item) + } + } + for (item in droppedItems) { + GroundItemManager.destroy(item) + } + + // grep -R savePlayer: jobs, treasure trails, brawling gloves, slayer manager, barcrawl, ge history will simply not get saved if we don't run the hooks + // Only the Blast Furnace needs to be reset explicitly + BlastFurnace.playerStates[target.details.uid] = BFPlayerState(target) + + // Sayonara PlayerSaver(target).save() target.clear() } diff --git a/Server/src/main/core/api/utils/PlayerStatsCounter.kt b/Server/src/main/core/api/utils/PlayerStatsCounter.kt new file mode 100644 index 000000000..3337c3de7 --- /dev/null +++ b/Server/src/main/core/api/utils/PlayerStatsCounter.kt @@ -0,0 +1,253 @@ +package core.api.utils + +import core.api.StartupListener +import core.game.node.entity.player.Player +import java.io.File +import java.io.FileReader +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.game.node.item.Item +import core.game.world.GameWorld +import core.integrations.sqlite.SQLiteProvider +import core.tools.Log +import core.tools.SystemLogger.logStartup +import kotlin.io.path.Path + +class PlayerStatsCounter( + private val dbPath: String = Path(ServerConstants.DATA_PATH ?: "", "playerstats", "player_stats.db").toString() +) : StartupListener { + + override fun startup() { + logStartup("Loading Player Stats") + + db = SQLiteProvider(dbPath, expectedTables) + db.initTables() + + if (!tableHasData()) { // TODO: Remove check, porter and raw inserts once SQLite tracking is proven and the live server has been updated + portLegacyKillCounterJsonToSQLite() + } + } + + companion object { + lateinit var db: SQLiteProvider + + private fun resolveUIDFromPlayerUsername(playerUsername: String): Int { + return GameWorld.accountStorage.getAccountInfo(playerUsername).uid + } + + private fun portLegacyKillCounterJsonToSQLite() { + val file = File(Path(ServerConstants.DATA_PATH ?: "", "global_kill_stats.json").toString()) + if (!file.exists()) { + return + } + + val reader = FileReader(file) + val parser = JSONParser() + try { + val data = parser.parse(reader) as JSONObject + val json_kills = data.get("kills") + if (json_kills != null && json_kills is JSONObject) { + var progress = 1 + val totalPlayers = json_kills.size + for ((player, killStats) in json_kills.asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Porting kill counters for player $progress/$totalPlayers" + ) + if (player is String) { + val playerUid = resolveUIDFromPlayerUsername(player.replace(" ", "_")) + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Player $player ($playerUid)" + ) + for ((npc_id, count) in (killStats as JSONObject).asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Inserting kill for $player ($playerUid, $npc_id, $count)" + ) + incrementKills( + playerUid, + (npc_id as String).toInt(), + count as Long + ) + } + } + progress++ + } + } + val json_rare_drops = data.get("rare_drops") + if (json_rare_drops != null && json_rare_drops is JSONObject) { + var progress = 1 + val totalPlayers = json_rare_drops.size + for ((player, rareDrops) in json_rare_drops.asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Porting rare drops for player $progress/$totalPlayers" + ) + if (player is String) { + val playerUid = resolveUIDFromPlayerUsername(player.replace(" ", "_")) + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Player $player ($playerUid)" + ) + for ((item_id, count) in (rareDrops as JSONObject).asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Inserting rare drop for $player ($playerUid, $item_id, $count)" + ) + incrementRareDrop( + playerUid, + (item_id as String).toInt(), + count as Long + ) + } + } + progress++ + } + } + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Failed parsing ${file.name} - stack trace below.") + e.printStackTrace() + } + } + + private val killsTableDefinition = """ + CREATE TABLE kills( + player_uid INTEGER, + entity_id INTEGER, + kills INTEGER, + PRIMARY KEY(player_uid, entity_id)) + """.trimIndent() + + private val rareDropsTableDefinition = """ + CREATE TABLE rare_drops( + player_uid INTEGER, + item_id INTEGER, + amount INTEGER, + PRIMARY KEY (player_uid, item_id)) + """.trimIndent() + + private val getKillsRowCountSql = """ + SELECT COUNT(1) FROM kills; + """.trimIndent() + + private val insertOrIncrementKillSql = """ + INSERT INTO kills (player_uid, entity_id, kills) + VALUES (?, ?, ?) + ON CONFLICT(player_uid, entity_id) DO UPDATE SET kills = kills + ?; + """.trimIndent() + + private val insertOrIncrementRareDropSql = """ + INSERT INTO rare_drops (player_uid, item_id, amount) + VALUES (?, ?, ?) + ON CONFLICT(player_uid, item_id) DO UPDATE SET amount = amount + ?; + """.trimIndent() + + private val getRareDropsSql = """ + SELECT amount FROM rare_drops WHERE player_uid=? AND item_id=? + """.trimIndent() + + private fun createGetKillsSql(countOfEntitiesToSearchFor: Int): String { + if (countOfEntitiesToSearchFor < 1) { + throw Exception("Should be at least 1") + } + val entitySearchParameterMarkers = "?" + ",?".repeat(countOfEntitiesToSearchFor - 1) + return """ + SELECT SUM(kills) FROM kills WHERE player_uid=? AND entity_id IN ($entitySearchParameterMarkers) + """.trimIndent() + } + + private val expectedTables = hashMapOf( + "kills" to killsTableDefinition, + "rare_drops" to rareDropsTableDefinition, + ) + + private fun tableHasData(): Boolean { + var hasData = false + db.run { conn -> + val statement = conn.prepareStatement(getKillsRowCountSql) + val result = statement.executeQuery() + if (result.next()) { + val rowCount = result.getInt(1) + hasData = rowCount > 0 + } + } + return hasData + } + + @JvmStatic + private fun incrementKills(playerUid: Int, npcId: Int, kills: Long) { + db.run { conn -> + val statement = conn.prepareStatement(insertOrIncrementKillSql) + statement.setInt(1, playerUid) + statement.setInt(2, npcId) + statement.setLong(3, kills) + statement.setLong(4, kills) + statement.execute() + } + } + + @JvmStatic + fun incrementKills(player: Player, npcId: Int) { + incrementKills(player.details.uid, npcId, 1) + } + + @JvmStatic + private fun incrementRareDrop(playerUid: Int, itemId: Int, amount: Long) { + db.run { conn -> + val statement = conn.prepareStatement(insertOrIncrementRareDropSql) + statement.setInt(1, playerUid) + statement.setInt(2, itemId) + statement.setLong(3, amount) + statement.setLong(4, amount) + statement.execute() + } + } + + @JvmStatic + fun incrementRareDrop(player: Player, item: Item) { + incrementRareDrop(player.details.uid, item.id, item.amount.toLong()) + } + + @JvmStatic + fun getKills(player: Player, npcIds: IntArray): Long { + var kills: Long = 0 + db.run { conn -> + val statement = conn.prepareStatement(createGetKillsSql(npcIds.size)) + statement.setInt(1, player.details.uid) + for (npcIdParamIndex in npcIds.indices) { + // +2 because the statement parameterIndexes start at 1 and the first param is the player uid + statement.setInt(npcIdParamIndex + 2, npcIds[npcIdParamIndex]) + } + val result = statement.executeQuery() + if (result.next()) { + kills = result.getLong(1) + } + } + return kills + } + + @JvmStatic + fun getRareDrops(player: Player, itemId: Int): Long { + var rareDropsForItem: Long = 0 + db.run { conn -> + val statement = conn.prepareStatement(getRareDropsSql) + statement.setInt(1, player.details.uid) + statement.setInt(2, itemId) + val result = statement.executeQuery() + if (result.next()) { + rareDropsForItem = result.getLong(1) + } + } + return rareDropsForItem + } + } +} diff --git a/Server/src/main/core/api/utils/WeightBasedTable.kt b/Server/src/main/core/api/utils/WeightBasedTable.kt index 79466bffe..39505c241 100644 --- a/Server/src/main/core/api/utils/WeightBasedTable.kt +++ b/Server/src/main/core/api/utils/WeightBasedTable.kt @@ -42,27 +42,48 @@ open class WeightBasedTable : ArrayList() { return roll(receiver, 1) } - open fun roll(receiver: Entity? = null, times: Int = 1): ArrayList{ - val items = ArrayList((guaranteedItems.size + 1) * times) + open fun roll(receiver: Entity?, times: Int = 1): ArrayList { + val weightedItemsToDrop = ArrayList() - for (i in 0 until times) { - items.addAll(guaranteedItems) + repeat(times) { + // Guaranteed items + for (item in guaranteedItems) { + if (isSpecialSlot(item.id)) { + val rolls = RandomFunction.random(item.minAmt, item.maxAmt) + repeat(rolls) { + weightedItemsToDrop.add(item) + } + } else { + // Add just one instance with amount set by getItem() + weightedItemsToDrop.add(item) + } + } - if (size == 1) { - items.add(get(0)) - } else if (isNotEmpty()) { + // Weighted roll (one per table roll) + if (isNotEmpty()) { var rngWeight = RandomFunction.randomDouble(totalWeight) for (item in this) { rngWeight -= item.weight if (rngWeight <= 0) { - items.add(item) + if (isSpecialSlot(item.id)) { + val rolls = RandomFunction.random(item.minAmt, item.maxAmt) + repeat(rolls) { + weightedItemsToDrop.add(item) + } + } else { + weightedItemsToDrop.add(item) + } break } } } } - return convertWeightedItems(items, receiver) + return convertWeightedItems(weightedItemsToDrop, receiver) + } + + private fun isSpecialSlot(id: Int): Boolean { + return id == SLOT_HDT || id == SLOT_USDT // extend this if a drop table is not dropping multiple times } fun convertWeightedItems(weightedItems: ArrayList, receiver: Entity?): ArrayList { @@ -161,6 +182,22 @@ open class WeightBasedTable : ArrayList() { return this } + fun excluding(vararg ids: Int): WeightBasedTable { + val idSet = ids.toHashSet() + val filtered = WeightBasedTable() + for (item in this) { + if (item.id !in idSet) { + filtered.add(item) + } + } + for (item in guaranteedItems) { + if (item.id !in idSet) { + filtered.add(item) + } + } + return filtered + } + companion object { @JvmStatic fun create(vararg items: WeightedItem): WeightBasedTable { @@ -176,6 +213,7 @@ open class WeightBasedTable : ArrayList() { val SLOT_CLUE_EASY = Items.TOOLKIT_1 val SLOT_CLUE_MEDIUM = Items.ROTTEN_POTATO_5733 val SLOT_CLUE_HARD = Items.GRANITE_LOBSTER_POUCH_12070 + val CLUE_SCROLL_SLOTS = intArrayOf(SLOT_CLUE_EASY, SLOT_CLUE_MEDIUM, SLOT_CLUE_HARD) val SLOT_CELEDT = Items.NULL_799 val SLOT_USDT = Items.SACRED_CLAY_POUCH_CLASS_1_14422 val SLOT_HDT = Items.SACRED_CLAY_POUCH_CLASS_2_14424 diff --git a/Server/src/main/core/cache/Cache.java b/Server/src/main/core/cache/Cache.java index ce4ed3c25..3459d58b9 100644 --- a/Server/src/main/core/cache/Cache.java +++ b/Server/src/main/core/cache/Cache.java @@ -145,7 +145,7 @@ public final class Cache { buffer.putInt(0); continue; } - buffer.putInt(cacheFileManagers[index].getInformation().getInformationContainer().getCrc()); + buffer.putInt(cacheFileManagers[index].getInformation().informationContainer.getCrc()); buffer.putInt(cacheFileManagers[index].getInformation().getRevision()); } return buffer.array(); diff --git a/Server/src/main/core/cache/CacheFile.java b/Server/src/main/core/cache/CacheFile.java index a03642895..bd21a8a0d 100644 --- a/Server/src/main/core/cache/CacheFile.java +++ b/Server/src/main/core/cache/CacheFile.java @@ -66,7 +66,7 @@ public final class CacheFile { return null; } if (xteaKeys != null && (xteaKeys[0] != 0 || xteaKeys[1] != 0 || xteaKeys[2] != 0 || xteaKeys[3] != 0)) { - packedData = XTEACryption.decrypt(xteaKeys, ByteBuffer.wrap(packedData), 5, packedData.length).array(); + packedData = XTEACryption.Companion.decrypt(xteaKeys, ByteBuffer.wrap(packedData), 5, packedData.length).array(); } return ContainersInformation.unpackCacheContainer(packedData); } diff --git a/Server/src/main/core/cache/StoreFile.java b/Server/src/main/core/cache/StoreFile.java deleted file mode 100644 index 50e1728d0..000000000 --- a/Server/src/main/core/cache/StoreFile.java +++ /dev/null @@ -1,72 +0,0 @@ -package core.cache; - -import java.nio.ByteBuffer; - -/** - * Represents a file used in the server store. - * @author Emperor - */ -public final class StoreFile { - - /** - * If the data can change during server runtime. - */ - private boolean dynamic; - - /** - * The file data. - */ - private byte[] data; - - /** - * Constructs a new {@code StoreFile} {@code Object}. - */ - public StoreFile() { - /* - * empty. - */ - } - - /** - * Puts the data on the buffer. - * @param buffer The buffer. - */ - public void put(ByteBuffer buffer) { - byte[] data = new byte[buffer.remaining()]; - buffer.get(data); - this.data = data; - } - - /** - * Creates a byte buffer containing the file data. - * @return The buffer. - */ - public ByteBuffer data() { - return ByteBuffer.wrap(data); - } - - /** - * Sets the data. - * @param data The data. - */ - public void setData(byte[] data) { - this.data = data; - } - - /** - * Gets the dynamic. - * @return The dynamic. - */ - public boolean isDynamic() { - return dynamic; - } - - /** - * Sets the dynamic. - * @param dynamic The dynamic to set. - */ - public void setDynamic(boolean dynamic) { - this.dynamic = dynamic; - } - -} \ No newline at end of file diff --git a/Server/src/main/core/cache/crypto/ISAACCipher.java b/Server/src/main/core/cache/crypto/ISAACCipher.java deleted file mode 100644 index 16cd85b18..000000000 --- a/Server/src/main/core/cache/crypto/ISAACCipher.java +++ /dev/null @@ -1,271 +0,0 @@ -package core.cache.crypto; - -/** - *

An implementation of an ISAAC cipher. See - * http://en.wikipedia.org/wiki/ISAAC_(cipher) for more information.

- *

This implementation is based on the one written by Bob Jenkins, which is - * available at - * http://www.burtleburtle.net/bob/java/rand/Rand.java.

- * @author Graham Edgecombe - */ -public class ISAACCipher { - - /** - * The golden ratio. - */ - public static final int RATIO = 0x9e3779b9; - - /** - * The log of the size of the results and memory arrays. - */ - public static final int SIZE_LOG = 8; - - /** - * The size of the results and memory arrays. - */ - public static final int SIZE = 1 << SIZE_LOG; - - /** - * For pseudorandom lookup. - */ - public static final int MASK = (SIZE - 1) << 2; - - /** - * The count through the results. - */ - private int count = 0; - - /** - * The results. - */ - private int results[] = new int[SIZE]; - - /** - * The internal memory state. - */ - private int memory[] = new int[SIZE]; - - /** - * The accumulator. - */ - private int a; - - /** - * The last result. - */ - private int b; - - /** - * The counter. - */ - private int c; - - /** - * Creates the ISAAC cipher. - * @param seed The seed. - */ - public ISAACCipher(int[] seed) { - for (int i = 0; i < seed.length; i++) { - results[i] = seed[i]; - } - init(true); - } - - /** - * Gets the next value. - * @return The next value. - */ - public int getNextValue() { - if (count-- == 0) { - isaac(); - count = SIZE - 1; - } - return 0;//results[count]; - } - - /** - * Generates 256 results. - */ - public void isaac() { - int i, j, x, y; - b += ++c; - for (i = 0, j = SIZE / 2; i < SIZE / 2;) { - x = memory[i]; - a ^= a << 13; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - - x = memory[i]; - a ^= a >>> 6; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - - x = memory[i]; - a ^= a << 2; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - - x = memory[i]; - a ^= a >>> 16; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - } - for (j = 0; j < SIZE / 2;) { - x = memory[i]; - a ^= a << 13; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - - x = memory[i]; - a ^= a >>> 6; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - - x = memory[i]; - a ^= a << 2; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - - x = memory[i]; - a ^= a >>> 16; - a += memory[j++]; - memory[i] = y = memory[(x & MASK) >> 2] + a + b; - results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; - } - } - - /** - * Initialises the ISAAC. - * @param flag Flag indicating if we should perform a second pass. - */ - public void init(boolean flag) { - int i; - int a, b, c, d, e, f, g, h; - a = b = c = d = e = f = g = h = RATIO; - for (i = 0; i < 4; ++i) { - a ^= b << 11; - d += a; - b += c; - b ^= c >>> 2; - e += b; - c += d; - c ^= d << 8; - f += c; - d += e; - d ^= e >>> 16; - g += d; - e += f; - e ^= f << 10; - h += e; - f += g; - f ^= g >>> 4; - a += f; - g += h; - g ^= h << 8; - b += g; - h += a; - h ^= a >>> 9; - c += h; - a += b; - } - for (i = 0; i < SIZE; i += 8) { - if (flag) { - a += results[i]; - b += results[i + 1]; - c += results[i + 2]; - d += results[i + 3]; - e += results[i + 4]; - f += results[i + 5]; - g += results[i + 6]; - h += results[i + 7]; - } - a ^= b << 11; - d += a; - b += c; - b ^= c >>> 2; - e += b; - c += d; - c ^= d << 8; - f += c; - d += e; - d ^= e >>> 16; - g += d; - e += f; - e ^= f << 10; - h += e; - f += g; - f ^= g >>> 4; - a += f; - g += h; - g ^= h << 8; - b += g; - h += a; - h ^= a >>> 9; - c += h; - a += b; - memory[i] = a; - memory[i + 1] = b; - memory[i + 2] = c; - memory[i + 3] = d; - memory[i + 4] = e; - memory[i + 5] = f; - memory[i + 6] = g; - memory[i + 7] = h; - } - if (flag) { - for (i = 0; i < SIZE; i += 8) { - a += memory[i]; - b += memory[i + 1]; - c += memory[i + 2]; - d += memory[i + 3]; - e += memory[i + 4]; - f += memory[i + 5]; - g += memory[i + 6]; - h += memory[i + 7]; - a ^= b << 11; - d += a; - b += c; - b ^= c >>> 2; - e += b; - c += d; - c ^= d << 8; - f += c; - d += e; - d ^= e >>> 16; - g += d; - e += f; - e ^= f << 10; - h += e; - f += g; - f ^= g >>> 4; - a += f; - g += h; - g ^= h << 8; - b += g; - h += a; - h ^= a >>> 9; - c += h; - a += b; - memory[i] = a; - memory[i + 1] = b; - memory[i + 2] = c; - memory[i + 3] = d; - memory[i + 4] = e; - memory[i + 5] = f; - memory[i + 6] = g; - memory[i + 7] = h; - } - } - isaac(); - count = SIZE; - } - -} \ No newline at end of file diff --git a/Server/src/main/core/cache/crypto/ISAACCipher.kt b/Server/src/main/core/cache/crypto/ISAACCipher.kt new file mode 100644 index 000000000..d3fab467b --- /dev/null +++ b/Server/src/main/core/cache/crypto/ISAACCipher.kt @@ -0,0 +1,213 @@ +package core.cache.crypto + +/** + * An implementation of an ISAAC cipher. + * See [http://en.wikipedia.org/wiki/ISAAC_(cipher)](http://en.wikipedia.org/wiki/ISAAC_(cipher)) for more information. + * Based on the one written by Bob Jenkins, which is available at + * [http://www.burtleburtle.net/bob/java/rand/Rand.java](http://www.burtleburtle.net/bob/java/rand/Rand.java). + */ +class ISAACCipher(seed: IntArray) { + companion object { + /** Golden ratio in 32 bit unsigned int. */ + const val RATIO = -0x61c88647 + /** The base 2 log of the size of the results and memory arrays. */ + const val SIZE_LOG = 8 + /** The size of the results and memory arrays. */ + const val SIZE = 1 shl SIZE_LOG + /** For pseudorandom lookup. */ + const val MASK = SIZE - 1 shl 2 + } + /** The count through the results. */ + private var count = 0 + /** The results. */ + private val results = IntArray(SIZE) + /** The internal memory state. */ + private val memory = IntArray(SIZE) + /** The accumulator. */ + private var a = 0 + /** The last result. */ + private var b = 0 + /** The counter. */ + private var c = 0 + + /** + * Creates the ISAAC cipher. + * @param seed The seed. + */ + init { + for (i in seed.indices) { + results[i] = seed[i] + } + init(true) + } + + val nextValue: Int + /** + * Gets the next value. + * @return The next value. + */ + get() { + if (count-- == 0) { + isaac() + count = SIZE - 1 + } + return 0 //results[count]; + } + + /** + * Generates 256 results. + */ + fun isaac() { + var i: Int + var j: Int + var x: Int + var y: Int + b += ++c + i = 0 + j = SIZE / 2 + while (i < SIZE / 2) { + x = memory[i] + a = a xor (a shl 13) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + x = memory[i] + a = a xor (a ushr 6) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + x = memory[i] + a = a xor (a shl 2) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + x = memory[i] + a = a xor (a ushr 16) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + } + j = 0 + while (j < SIZE / 2) { + x = memory[i] + a = a xor (a shl 13) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + x = memory[i] + a = a xor (a ushr 6) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + x = memory[i] + a = a xor (a shl 2) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + x = memory[i] + a = a xor (a ushr 16) + a += memory[j++] + y = memory[x and MASK shr 2] + a + b + memory[i] = y + b = memory[y shr SIZE_LOG and MASK shr 2] + x + results[i++] = b + } + } + + /** + * Initialises the ISAAC. + * @param flag Flag indicating if we should perform a second pass. + */ + fun init(flag: Boolean) { + var a = RATIO + var b = a; var c = b; var d = c; var e = d; var f = e; var g = f; var h = g + var i = 0 + while (i < 4) { + a = a xor (b shl 11); d += a; b += c + b = b xor (c ushr 2); e += b; c += d + c = c xor (d shl 8); f += c; d += e + d = d xor (e ushr 16); g += d; e += f + e = e xor (f shl 10); h += e; f += g + f = f xor (g ushr 4); a += f; g += h + g = g xor (h shl 8); b += g; h += a + h = h xor (a ushr 9); c += h; a += b + ++i + } + i = 0 + while (i < SIZE) { + if (flag) { + a += results[i] + b += results[i + 1] + c += results[i + 2] + d += results[i + 3] + e += results[i + 4] + f += results[i + 5] + g += results[i + 6] + h += results[i + 7] + } + a = a xor (b shl 11); d += a; b += c + b = b xor (c ushr 2); e += b; c += d + c = c xor (d shl 8); f += c; d += e + d = d xor (e ushr 16); g += d; e += f + e = e xor (f shl 10); h += e; f += g + f = f xor (g ushr 4); a += f; g += h + g = g xor (h shl 8); b += g; h += a + h = h xor (a ushr 9); c += h; a += b + memory[i] = a + memory[i + 1] = b + memory[i + 2] = c + memory[i + 3] = d + memory[i + 4] = e + memory[i + 5] = f + memory[i + 6] = g + memory[i + 7] = h + i += 8 + } + if (flag) { + i = 0 + while (i < SIZE) { + a += memory[i] + b += memory[i + 1] + c += memory[i + 2] + d += memory[i + 3] + e += memory[i + 4] + f += memory[i + 5] + g += memory[i + 6] + h += memory[i + 7] + a = a xor (b shl 11); d += a; b += c + b = b xor (c ushr 2); e += b; c += d + c = c xor (d shl 8); f += c; d += e + d = d xor (e ushr 16); g += d; e += f + e = e xor (f shl 10); h += e; f += g + f = f xor (g ushr 4); a += f; g += h + g = g xor (h shl 8); b += g; h += a + h = h xor (a ushr 9); c += h; a += b + memory[i] = a + memory[i + 1] = b + memory[i + 2] = c + memory[i + 3] = d + memory[i + 4] = e + memory[i + 5] = f + memory[i + 6] = g + memory[i + 7] = h + i += 8 + } + } + isaac() + count = SIZE + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/crypto/ISAACPair.java b/Server/src/main/core/cache/crypto/ISAACPair.java deleted file mode 100644 index 83c4654b9..000000000 --- a/Server/src/main/core/cache/crypto/ISAACPair.java +++ /dev/null @@ -1,45 +0,0 @@ -package core.cache.crypto; - -/** - * Represents a ISAAC key pair, for both input and output. - * @author `Discardedx2 - */ -public final class ISAACPair { - - /** - * The input cipher. - */ - private ISAACCipher input; - - /** - * The output cipher. - */ - private ISAACCipher output; - - /** - * Constructs a new {@code ISAACPair} {@code Object}. - * @param input The input cipher. - * @param output The output cipher. - */ - public ISAACPair(ISAACCipher input, ISAACCipher output) { - this.input = input; - this.output = output; - } - - /** - * Gets the input cipher. - * @return The input cipher. - */ - public ISAACCipher getInput() { - return input; - } - - /** - * Gets the output cipher. - * @return The output cipher. - */ - public ISAACCipher getOutput() { - return output; - } - -} diff --git a/Server/src/main/core/cache/crypto/ISAACPair.kt b/Server/src/main/core/cache/crypto/ISAACPair.kt new file mode 100644 index 000000000..9056c7a9d --- /dev/null +++ b/Server/src/main/core/cache/crypto/ISAACPair.kt @@ -0,0 +1,9 @@ +package core.cache.crypto + +/** + * Represents a ISAAC key pair, for both input and output. + */ +class ISAACPair( + val input: ISAACCipher, + val output: ISAACCipher +) diff --git a/Server/src/main/core/cache/crypto/XTEACryption.java b/Server/src/main/core/cache/crypto/XTEACryption.java deleted file mode 100644 index 7ed799e58..000000000 --- a/Server/src/main/core/cache/crypto/XTEACryption.java +++ /dev/null @@ -1,124 +0,0 @@ -package core.cache.crypto; - -import java.nio.ByteBuffer; - -/** - * Holds XTEA cryption methods. - * @author ? - * @author Emperor - */ -public final class XTEACryption { - - /** - * The delta value - */ - private static final int DELTA = -1640531527; - - /** - * The sum. - */ - private static final int SUM = -957401312; - - /** - * The amount of "cryption cycles". - */ - private static final int NUM_ROUNDS = 32; - - /** - * Constructs a new {@code XTEACryption}. - */ - private XTEACryption() { - /* - * empty. - */ - } - - /** - * Decrypts the contents of the buffer. - * @param keys The cryption keys. - * @param buffer The buffer. - */ - public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer) { - return decrypt(keys, buffer, buffer.position(), buffer.limit()); - } - - /** - * Decrypts the buffer data. - * @param keys The keys. - * @param buffer The buffer to decrypt. - * @param offset The offset of the data to decrypt. - * @param length The length. - * @return The decrypted data. - */ - public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer, int offset, int length) { - int numBlocks = (length - offset) / 8; - int[] block = new int[2]; - for (int i = 0; i < numBlocks; i++) { - int index = i * 8 + offset; - block[0] = buffer.getInt(index); - block[1] = buffer.getInt(index + 4); - decipher(keys, block); - buffer.putInt(index, block[0]); - buffer.putInt(index + 4, block[1]); - } - return buffer; - } - - /** - * Deciphers the values. - * @param keys The cryption key. - * @param block The values to decipher. - */ - private static void decipher(int[] keys, int[] block) { - long sum = SUM; - for (int i = 0; i < NUM_ROUNDS; i++) { - block[1] -= (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5)); - sum -= DELTA; - block[0] -= ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum); - } - } - - /** - * Encrypts the contents of the byte buffer. - * @param keys The cryption keys. - * @param buffer The buffer to encrypt. - */ - public static void encrypt(int[] keys, ByteBuffer buffer) { - encrypt(keys, buffer, buffer.position(), buffer.limit()); - } - - /** - * Encrypts the buffer data. - * @param keys The keys. - * @param buffer The buffer to encrypt. - * @param offset The offset of the data to encrypt. - * @param length The length. - * @return The encrypted data. - */ - public static void encrypt(int[] keys, ByteBuffer buffer, int offset, int length) { - int numBlocks = (length - offset) / 8; - int[] block = new int[2]; - for (int i = 0; i < numBlocks; i++) { - int index = i * 8 + offset; - block[0] = buffer.getInt(index); - block[1] = buffer.getInt(index + 4); - encipher(keys, block); - buffer.putInt(index, block[0]); - buffer.putInt(index + 4, block[1]); - } - } - - /** - * Enciphers the values of the block. - * @param keys The cryption keys. - * @param block The block to encipher. - */ - private static void encipher(int[] keys, int[] block) { - long sum = 0; - for (int i = 0; i < NUM_ROUNDS; i++) { - block[0] += ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum); - sum += DELTA; - block[1] += (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5)); - } - } -} \ No newline at end of file diff --git a/Server/src/main/core/cache/crypto/XTEACryption.kt b/Server/src/main/core/cache/crypto/XTEACryption.kt new file mode 100644 index 000000000..f87477008 --- /dev/null +++ b/Server/src/main/core/cache/crypto/XTEACryption.kt @@ -0,0 +1,97 @@ +package core.cache.crypto + +import java.nio.ByteBuffer + +/** Holds XTEA(eXtended Tiny Encryption Algorithm) encryption/decryption methods. Usually used for RS Map decryption. */ +class XTEACryption { + companion object { + // Purely Static Class + // XTEA consts https://scispace.com/pdf/xtea-cryptography-implementation-in-android-chatting-app-3pg6ownewx.pdf + /** Fibonacci hashing. Math.pow(2,32) * Math.sqrt(5)-1)/2 => 32 bits(int) multiply by reciprocal of golden ratio. */ + private const val DELTA = -1640531527 // Formula cast to unsigned int. + /** DELTA << 5. Essentially multiply DELTA by NUM_ROUNDS or number of rounds. */ + private const val SUM = -957401312 // 0xC6EF3720 + /** The amount of "cryption cycles". */ + private const val NUM_ROUNDS = 32 + /** Constant to manipulate the key index in decipher/encrypt. This was a magic number randomly selected by RS. */ + private const val KEY_SCRAMBLE = 0x1933 + + /** + * Decrypts the buffer data. + * @param keys The keys. + * @param buffer The buffer to decrypt. + * @param offset The offset of the data to decrypt. + * @param length The length. + * @return The decrypted data. + */ + fun decrypt(keys: IntArray, buffer: ByteBuffer, offset: Int, length: Int): ByteBuffer { + val numBlocks = (length - offset) / 8 + val block = IntArray(2) + for (i in 0 until numBlocks) { + val index = i * 8 + offset + block[0] = buffer.getInt(index) + block[1] = buffer.getInt(index + 4) + decipher(keys, block) + buffer.putInt(index, block[0]) + buffer.putInt(index + 4, block[1]) + } + return buffer + } + + /** + * Deciphers the values of the block using the Tiny Encryption Algorithm (TEA). + * This algorithm relies on a Feistel network, using bitwise operations and + * modular subtraction to remove confusion(block[0] line) and diffusion(block[1] line). + * + * @param keys 128-bit key (4x32-bit int). + * @param block 64-bit data block (2x32-bit int) to be decrypted. + */ + private fun decipher(keys: IntArray, block: IntArray) { + var sum = + SUM.toLong() // Running decreasing sum to ensure different round constants - should become 0 at the end. + for (i in 0 until NUM_ROUNDS) { + block[1] -= (keys[(sum and KEY_SCRAMBLE.toLong() ushr 11).toInt()] + sum xor (block[0] + (block[0] shl 4 xor (block[0] ushr 5))).toLong()).toInt() + sum -= DELTA.toLong() + block[0] -= (((block[1] shl 4 xor (block[1] ushr 5)) + block[1]).toLong() xor keys[(sum and 0x3L).toInt()] + sum).toInt() + } + } + /** === Encryption functions below are not used unless you are modifying the cache. === */ + /** + * Encrypts the buffer data. + * @param keys The keys. + * @param buffer The buffer to encrypt. + * @param offset The offset of the data to encrypt. + * @param length The length. + * @return The encrypted data. + */ + fun encrypt(keys: IntArray, buffer: ByteBuffer, offset: Int, length: Int) { + val numBlocks = (length - offset) / 8 + val block = IntArray(2) + for (i in 0 until numBlocks) { + val index = i * 8 + offset + block[0] = buffer.getInt(index) + block[1] = buffer.getInt(index + 4) + encipher(keys, block) + buffer.putInt(index, block[0]) + buffer.putInt(index + 4, block[1]) + } + } + + /** + * Enciphers the values of the block using the Tiny Encryption Algorithm (TEA). + * This algorithm relies on a Feistel network, using bitwise operations and + * modular addition to provide confusion(block[0] line) and diffusion(block[1] line). + * + * @param keys 128-bit key (4x32-bit int). + * @param block 64-bit data block (2x32-bit int) to be encrypted. + */ + private fun encipher(keys: IntArray, block: IntArray) { + var sum: Long = 0 // Running sum to ensure different round constants - should match SUM at the end. + for (i in 0 until NUM_ROUNDS) { + block[0] += (((block[1] shl 4 xor (block[1] ushr 5)) + block[1]).toLong() xor keys[(sum and 0x3L).toInt()] + sum).toInt() + sum += DELTA.toLong() + block[1] += (keys[(sum and KEY_SCRAMBLE.toLong() ushr 11).toInt()] + sum xor (block[0] + (block[0] shl 4 xor (block[0] ushr 5))).toLong()).toInt() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/impl/ClothDefinition.java b/Server/src/main/core/cache/def/impl/ClothDefinition.java index 27c63cc53..c100c16ef 100644 --- a/Server/src/main/core/cache/def/impl/ClothDefinition.java +++ b/Server/src/main/core/cache/def/impl/ClothDefinition.java @@ -1,7 +1,6 @@ package core.cache.def.impl; import java.nio.ByteBuffer; -import java.util.Arrays; import core.ServerConstants; import core.cache.Cache; diff --git a/Server/src/main/core/cache/def/impl/ItemDefinition.java b/Server/src/main/core/cache/def/impl/ItemDefinition.java index 60baf51ea..b7c17e5ec 100644 --- a/Server/src/main/core/cache/def/impl/ItemDefinition.java +++ b/Server/src/main/core/cache/def/impl/ItemDefinition.java @@ -1,6 +1,5 @@ package core.cache.def.impl; -import core.ServerConstants; import core.api.EquipmentSlot; import core.cache.Cache; import core.cache.def.Definition; @@ -12,17 +11,12 @@ import core.game.node.entity.skill.Skills; import core.game.node.item.Item; import core.game.node.item.ItemPlugin; import core.game.world.GameWorld; -import core.net.packet.PacketRepository; -import core.net.packet.out.WeightUpdate; -import core.plugin.Plugin; import core.tools.Log; import core.tools.StringUtils; -import core.tools.SystemLogger; import core.game.system.config.ItemConfigParser; import org.rs09.consts.Items; import java.nio.ByteBuffer; -import java.text.DecimalFormat; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -33,7 +27,6 @@ import static core.api.ContentAPIKt.log; /** * Represents an item's definitions. - * @author Jagex * @author Emperor */ public class ItemDefinition extends Definition { @@ -611,8 +604,12 @@ public class ItemDefinition extends Definition { * @return {@code True} if so. */ public static boolean canEnterEntrana(Player player) { - Container[] container = new Container[] { player.getInventory(), player.getEquipment() }; - for (Container c : container) { + Container[] containers = new Container[] { player.getInventory(), player.getEquipment() }; + if (player.getFamiliarManager().hasFamiliar() && !player.getFamiliarManager().hasPet()) { + return false; + } + + for (Container c : containers) { for (Item i : c.toArray()) { if (i == null) { continue; @@ -651,6 +648,7 @@ public class ItemDefinition extends Definition { Items.BOOK_OF_BALANCE_3844, Items.DAMAGED_BOOK_3843, Items.WIZARD_BOOTS_2579, + Items.COMBAT_BRACELET_11126, Items.COMBAT_BRACELET1_11124, Items.COMBAT_BRACELET2_11122, Items.COMBAT_BRACELET3_11120, @@ -666,8 +664,28 @@ public class ItemDefinition extends Definition { Items.HAM_HOOD_4302, Items.HAM_CLOAK_4304, Items.HAM_LOGO_4306, - Items.GLOVES_4308, - Items.BOOTS_4310 + Items.ZAMORAK_ROBE_1033, + Items.ZAMORAK_ROBE_1035, + Items.PRIEST_GOWN_426, + Items.PRIEST_GOWN_428, + Items.DRUIDS_ROBE_538, + Items.DRUIDS_ROBE_540, + Items.FLOWERS_2460, + Items.FLOWERS_2462, + Items.FLOWERS_2464, + Items.FLOWERS_2466, + Items.FLOWERS_2468, + Items.FLOWERS_2470, + Items.FLOWERS_2472, + Items.FLOWERS_2474, + Items.FLOWERS_2476, + Items.FIXED_DEVICE_6082, + Items.GHOSTLY_BOOTS_6106, + Items.GHOSTLY_ROBE_6107, + Items.GHOSTLY_ROBE_6108, + Items.GHOSTLY_HOOD_6109, + Items.GHOSTLY_GLOVES_6110, + Items.GHOSTLY_CLOAK_6111 )); private static final HashSet entranaBannedItems = new HashSet(Arrays.asList( /**Items.BUTTERFLY_NET_10010, easing the restriction until barehanded implementation**/ @@ -676,15 +694,10 @@ public class ItemDefinition extends Definition { Items.CANNON_BASE_6, Items.CANNON_STAND_8, Items.CANNON_FURNACE_12, - Items.COOKING_GAUNTLETS_775, - Items.CHAOS_GAUNTLETS_777, - Items.GOLDSMITH_GAUNTLETS_776, - Items.KARAMJA_GLOVES_1_11136, - Items.KARAMJA_GLOVES_2_11138, - Items.KARAMJA_GLOVES_3_11140, - Items.VYREWATCH_TOP_9634, - Items.VYREWATCH_LEGS_9636, - Items.VYREWATCH_SHOES_9638 + Items.ZAMORAK_STOLE_10474, + Items.EXPLORERS_RING_1_13560, + Items.EXPLORERS_RING_2_13561, + Items.EXPLORERS_RING_3_13562 )); @@ -699,11 +712,11 @@ public class ItemDefinition extends Definition { if (entranaBannedItems.contains(getId())) { return false; } - if (equipSlot(getId()) == EquipmentSlot.AMMO) { + if (equipSlot(getId()) == EquipmentSlot.AMMO || equipSlot(getId()) == EquipmentSlot.NECK || equipSlot(getId()) == EquipmentSlot.RING) { return true; } - if (getName().toLowerCase().startsWith("ring") || getName().toLowerCase().startsWith("amulet")) { - return true; + if (hasAction("summon")) { + return false; } int[] bonuses = getConfiguration(ItemConfigParser.BONUS); return bonuses == null || Arrays.stream(bonuses).allMatch(x -> x == 0); @@ -1543,27 +1556,6 @@ public class ItemDefinition extends Definition { */ private static final String[] BONUS_NAMES = { "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Summoning: ", "Strength: ", "Prayer: " }; - /** - * Updates the equipment stats interface. - * @param player The player to update for. - */ - public static void statsUpdate(Player player) { - if (!player.getAttribute("equip_stats_open", false)) { - return; - } - int index = 0; - int[] bonuses = player.getProperties().getBonuses(); - for (int i = 36; i < 50; i++) { - if (i == 47) { - continue; - } - int bonus = bonuses[index]; - String bonusValue = bonus > -1 ? ("+" + bonus) : Integer.toString(bonus); - player.getPacketDispatch().sendString(BONUS_NAMES[index++] + bonusValue, 667, i); - } - player.getPacketDispatch().sendString("Attack bonus", 667, 34); - } - /** * Checks if it has a plugin. * @return {@code True} if so. diff --git a/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java b/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java index f68060e46..881e4040d 100644 --- a/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java +++ b/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java @@ -2,7 +2,6 @@ package core.cache.def.impl; import core.cache.Cache; import core.tools.Log; -import core.tools.SystemLogger; import core.game.world.GameWorld; import java.lang.reflect.Array; diff --git a/Server/src/main/core/cache/def/impl/SceneryDefinition.java b/Server/src/main/core/cache/def/impl/SceneryDefinition.java index 60ba83f99..6172d7828 100644 --- a/Server/src/main/core/cache/def/impl/SceneryDefinition.java +++ b/Server/src/main/core/cache/def/impl/SceneryDefinition.java @@ -7,7 +7,6 @@ import core.game.interaction.OptionHandler; import core.game.node.entity.player.Player; import core.game.node.scenery.Scenery; import core.tools.Log; -import core.tools.SystemLogger; import core.game.world.GameWorld; import java.nio.ByteBuffer; diff --git a/Server/src/main/core/cache/misc/Container.java b/Server/src/main/core/cache/misc/Container.java deleted file mode 100644 index 9760845ff..000000000 --- a/Server/src/main/core/cache/misc/Container.java +++ /dev/null @@ -1,109 +0,0 @@ -package core.cache.misc; - -/** - * A container. - * @author Dragonkk - */ -public class Container { - - /** - * The version. - */ - private int version; - - /** - * The CRC. - */ - private int crc; - - /** - * The name hash. - */ - private int nameHash; - - /** - * If updated. - */ - private boolean updated; - - /** - * Construct a new container. - */ - public Container() { - nameHash = -1; - version = -1; - crc = -1; - } - - /** - * Set the version. - * @param version - */ - public void setVersion(int version) { - this.version = version; - } - - /** - * Update the version. - */ - public void updateVersion() { - version++; - updated = true; - } - - /** - * Get the version. - * @return The version. - */ - public int getVersion() { - return version; - } - - /** - * Get the next version. - * @return The next version. - */ - public int getNextVersion() { - return updated ? version : version + 1; - } - - /** - * Set the CRC. - * @param crc The cRC. - */ - public void setCrc(int crc) { - this.crc = crc; - } - - /** - * Get the CRC. - * @return The CRC. - */ - public int getCrc() { - return crc; - } - - /** - * Set the name hash. - * @param nameHash The name hash. - */ - public void setNameHash(int nameHash) { - this.nameHash = nameHash; - } - - /** - * Get the name hash. - * @return The name hash. - */ - public int getNameHash() { - return nameHash; - } - - /** - * If is updated. - * @return If is updated. - */ - public boolean isUpdated() { - return updated; - } -} diff --git a/Server/src/main/core/cache/misc/Container.kt b/Server/src/main/core/cache/misc/Container.kt new file mode 100644 index 000000000..3e1b481d6 --- /dev/null +++ b/Server/src/main/core/cache/misc/Container.kt @@ -0,0 +1,7 @@ +package core.cache.misc + +data class Container( + var version: Int = -1, + var crc: Int = -1, + var nameHash: Int = -1 +) \ No newline at end of file diff --git a/Server/src/main/core/cache/misc/ContainersInformation.java b/Server/src/main/core/cache/misc/ContainersInformation.java deleted file mode 100644 index f786c1d2f..000000000 --- a/Server/src/main/core/cache/misc/ContainersInformation.java +++ /dev/null @@ -1,228 +0,0 @@ -package core.cache.misc; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.zip.CRC32; - -import core.cache.bzip2.BZip2Decompressor; -import core.cache.gzip.GZipDecompressor; - -/** - * A class holding the containers information. - * @author Dragonkk - */ -public final class ContainersInformation { - - /** - * The information container. - */ - private Container informationContainer; - - /** - * The protocol. - */ - private int protocol; - - /** - * The revision. - */ - private int revision; - - /** - * The container indexes. - */ - private int[] containersIndexes; - - /** - * The containers. - */ - private FilesContainer[] containers; - - /** - * If files have to be named. - */ - private boolean filesNamed; - - /** - * If it has to be whirpool. - */ - private boolean whirpool; - - /** - * The data. - */ - private final byte[] data; - - /** - * Construct a new containers information. - * @param informationContainerPackedData The information container data - * packed. - */ - public ContainersInformation(byte[] informationContainerPackedData) { - this.data = Arrays.copyOf(informationContainerPackedData, informationContainerPackedData.length); - informationContainer = new Container(); - informationContainer.setVersion((informationContainerPackedData[informationContainerPackedData.length - 2] << 8 & 0xff00) + (informationContainerPackedData[-1 + informationContainerPackedData.length] & 0xff)); - CRC32 crc32 = new CRC32(); - crc32.update(informationContainerPackedData); - informationContainer.setCrc((int) crc32.getValue()); - decodeContainersInformation(unpackCacheContainer(informationContainerPackedData)); - } - - /** - * Unpacks a container. - * @param packedData The packed container data. - * @return The unpacked data. - */ - public static final byte[] unpackCacheContainer(byte[] packedData) { - ByteBuffer buffer = ByteBuffer.wrap(packedData); - int compression = buffer.get() & 0xFF; - int containerSize = buffer.getInt(); - if (containerSize < 0 || containerSize > 5000000) { - return null; - // throw new RuntimeException(); - } - if (compression == 0) { - byte unpacked[] = new byte[containerSize]; - buffer.get(unpacked, 0, containerSize); - return unpacked; - } - int decompressedSize = buffer.getInt(); - if (decompressedSize < 0 || decompressedSize > 20000000) { - return null; - // throw new RuntimeException(); - } - byte decompressedData[] = new byte[decompressedSize]; - if (compression == 1) { - BZip2Decompressor.decompress(decompressedData, packedData, containerSize, 9); - } else { - GZipDecompressor.decompress(buffer, decompressedData); - } - return decompressedData; - } - - /** - * Get the container indexes. - * @return The container indexes. - */ - public int[] getContainersIndexes() { - return containersIndexes; - } - - /** - * Get the containers. - * @return The containers. - */ - public FilesContainer[] getContainers() { - return containers; - } - - /** - * Get the information container. - * @return The information container. - */ - public Container getInformationContainer() { - return informationContainer; - } - - /** - * Get the revision. - * @return The revision. - */ - public int getRevision() { - return revision; - } - - /** - * Decode the containers information. - * @param data The data. - */ - public void decodeContainersInformation(byte[] data) { - ByteBuffer buffer = ByteBuffer.wrap(data); - protocol = buffer.get() & 0xFF; - if (protocol != 5 && protocol != 6) { - throw new RuntimeException(); - } - revision = protocol < 6 ? 0 : buffer.getInt(); - int nameHash = buffer.get() & 0xFF; - filesNamed = (0x1 & nameHash) != 0; - whirpool = (0x2 & nameHash) != 0; - containersIndexes = new int[buffer.getShort() & 0xFFFF]; - int lastIndex = -1; - for (int index = 0; index < containersIndexes.length; index++) { - containersIndexes[index] = (buffer.getShort() & 0xFFFF) + (index == 0 ? 0 : containersIndexes[index - 1]); - if (containersIndexes[index] > lastIndex) { - lastIndex = containersIndexes[index]; - } - } - containers = new FilesContainer[lastIndex + 1]; - for (int index = 0; index < containersIndexes.length; index++) { - containers[containersIndexes[index]] = new FilesContainer(); - } - if (filesNamed) { - for (int index = 0; index < containersIndexes.length; index++) { - containers[containersIndexes[index]].setNameHash(buffer.getInt()); - } - } - byte[][] filesHashes = null; - if (whirpool) { - filesHashes = new byte[containers.length][]; - for (int index = 0; index < containersIndexes.length; index++) { - filesHashes[containersIndexes[index]] = new byte[64]; - buffer.get(filesHashes[containersIndexes[index]], 0, 64); - } - } - for (int index = 0; index < containersIndexes.length; index++) { - containers[containersIndexes[index]].setCrc(buffer.getInt()); - } - for (int index = 0; index < containersIndexes.length; index++) { - containers[containersIndexes[index]].setVersion(buffer.getInt()); - } - for (int index = 0; index < containersIndexes.length; index++) { - containers[containersIndexes[index]].setFilesIndexes(new int[buffer.getShort() & 0xFFFF]); - } - for (int index = 0; index < containersIndexes.length; index++) { - int lastFileIndex = -1; - for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { - containers[containersIndexes[index]].getFilesIndexes()[fileIndex] = (buffer.getShort() & 0xFFFF) + (fileIndex == 0 ? 0 : containers[containersIndexes[index]].getFilesIndexes()[fileIndex - 1]); - if (containers[containersIndexes[index]].getFilesIndexes()[fileIndex] > lastFileIndex) { - lastFileIndex = containers[containersIndexes[index]].getFilesIndexes()[fileIndex]; - } - } - containers[containersIndexes[index]].setFiles(new Container[lastFileIndex + 1]); - for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { - containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]] = new Container(); - } - } - if (whirpool) { - for (int index = 0; index < containersIndexes.length; index++) { - for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { - containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setVersion(filesHashes[containersIndexes[index]][containers[containersIndexes[index]].getFilesIndexes()[fileIndex]]); - } - } - } - if (filesNamed) { - for (int index = 0; index < containersIndexes.length; index++) { - for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { - containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setNameHash(buffer.getInt()); - } - } - } - } - - /** - * If is whirpool. - * @return If is whirpool {@code true}. - */ - public boolean isWhirpool() { - return whirpool; - } - - /** - * Gets the data. - * @return The data. - */ - public byte[] getData() { - return data; - } - -} diff --git a/Server/src/main/core/cache/misc/ContainersInformation.kt b/Server/src/main/core/cache/misc/ContainersInformation.kt new file mode 100644 index 000000000..831eb954b --- /dev/null +++ b/Server/src/main/core/cache/misc/ContainersInformation.kt @@ -0,0 +1,145 @@ +package core.cache.misc + +import core.cache.bzip2.BZip2Decompressor +import core.cache.gzip.GZipDecompressor +import java.nio.ByteBuffer +import java.util.* +import java.util.zip.CRC32 + +class ContainersInformation(informationContainerPackedData: ByteArray) { + @JvmField + val informationContainer: Container + private var protocol = 0 + var revision = 0 + var containersIndexes: IntArray = intArrayOf() + var containers: Array = arrayOf() + private var filesNamed = false // If files has to be named + private var whirpool = false // Flag for whirpool + val data: ByteArray + + init { + data = Arrays.copyOf(informationContainerPackedData, informationContainerPackedData.size) + informationContainer = Container() + informationContainer.version = + (informationContainerPackedData[informationContainerPackedData.size - 2].toInt() shl 8 and 0xff00) + (informationContainerPackedData[-1 + informationContainerPackedData.size].toInt() and 0xff) + val crc32 = CRC32() + crc32.update(informationContainerPackedData) + informationContainer.crc = crc32.value.toInt() + decodeContainersInformation(unpackCacheContainer(informationContainerPackedData)) + } + + fun decodeContainersInformation(data: ByteArray?) { + val buffer = ByteBuffer.wrap(data) + protocol = buffer.get().toInt() and 0xFF + if (protocol != 5 && protocol != 6) { + throw RuntimeException() + } + revision = if (protocol < 6) 0 else buffer.getInt() + val nameHash = buffer.get().toInt() and 0xFF + filesNamed = 0x1 and nameHash != 0 + whirpool = 0x2 and nameHash != 0 + containersIndexes = IntArray(buffer.getShort().toInt() and 0xFFFF) + var lastIndex = -1 + for (index in containersIndexes.indices) { + val containerIndex = + (buffer.getShort().toInt() and 0xFFFF) + if (index == 0) 0 else containersIndexes[index - 1] + containersIndexes[index] = containerIndex + if (containerIndex > lastIndex) { + lastIndex = containerIndex + } + } + containers = arrayOfNulls(lastIndex + 1) + for (containerIdx in containersIndexes) { + containers[containerIdx] = FilesContainer() + } + if (filesNamed) { + for (containerIdx in containersIndexes) { + containers[containerIdx]!!.nameHash = buffer.getInt() + } + } + var filesHashes: Array? = null + if (whirpool) { + filesHashes = arrayOfNulls(containers.size) + for (containerIdx in containersIndexes) { + filesHashes[containerIdx] = ByteArray(64) + buffer[filesHashes[containerIdx], 0, 64] + } + } + for (containerIdx in containersIndexes) { + containers[containerIdx]!!.crc = buffer.getInt() + } + for (containerIdx in containersIndexes) { + containers[containerIdx]!!.version = buffer.getInt() + } + for (containerIdx in containersIndexes) { + containers[containerIdx]!!.filesIndexes = IntArray(buffer.getShort().toInt() and 0xFFFF) + } + for (containerIdx in containersIndexes) { + val container = containers[containerIdx] + val filesIndexes = container!!.filesIndexes + var lastFileIndex = -1 + for (fileIndex in filesIndexes!!.indices) { + val fileIdx = + (buffer.getShort().toInt() and 0xFFFF) + if (fileIndex == 0) 0 else filesIndexes[fileIndex - 1] + filesIndexes[fileIndex] = fileIdx + if (fileIdx > lastFileIndex) { + lastFileIndex = fileIdx + } + } + val files = arrayOfNulls(lastFileIndex + 1) + container.files = files + for (fileIdx in filesIndexes) { + files[fileIdx] = Container() + } + } + if (whirpool) { + for (containerIdx in containersIndexes) { + val container = containers[containerIdx] + val containerHashes = filesHashes!![containerIdx] + val files = container!!.files + for (fileIdx in container.filesIndexes!!) { + files!![fileIdx]!!.version = containerHashes!![fileIdx].toInt() + } + } + } + if (filesNamed) { + for (containerIdx in containersIndexes) { + val container = containers[containerIdx] + val files = container!!.files + for (fileIdx in container.filesIndexes!!) { + files!![fileIdx]!!.nameHash = buffer.getInt() + } + } + } + } + + companion object { + @JvmStatic + fun unpackCacheContainer(packedData: ByteArray?): ByteArray? { + val buffer = ByteBuffer.wrap(packedData) + val compression = buffer.get().toInt() and 0xFF + val containerSize = buffer.getInt() + if (containerSize < 0 || containerSize > 5000000) { + return null + // throw new RuntimeException(); + } + if (compression == 0) { + val unpacked = ByteArray(containerSize) + buffer[unpacked, 0, containerSize] + return unpacked + } + val decompressedSize = buffer.getInt() + if (decompressedSize < 0 || decompressedSize > 20000000) { + return null + // throw new RuntimeException(); + } + val decompressedData = ByteArray(decompressedSize) + if (compression == 1) { + BZip2Decompressor.decompress(decompressedData, packedData, containerSize, 9) + } else { + GZipDecompressor.decompress(buffer, decompressedData) + } + return decompressedData + } + } +} diff --git a/Server/src/main/core/cache/misc/FilesContainer.java b/Server/src/main/core/cache/misc/FilesContainer.java deleted file mode 100644 index 5f14e448f..000000000 --- a/Server/src/main/core/cache/misc/FilesContainer.java +++ /dev/null @@ -1,57 +0,0 @@ -package core.cache.misc; - -/** - * A class holding the file containers. - * @author Dragonkk - */ -public final class FilesContainer extends Container { - - /** - * The file indexes. - */ - private int[] filesIndexes; - - /** - * The files. - */ - private Container[] files; - - /** - * Construct a new files container. - */ - public FilesContainer() { - - } - - /** - * Set the files. - * @param containers The files. - */ - public void setFiles(Container[] containers) { - this.files = containers; - } - - /** - * Get the files. - * @return The files. - */ - public Container[] getFiles() { - return files; - } - - /** - * Set the file indexes. - * @param containersIndexes The file indexes. - */ - public void setFilesIndexes(int[] containersIndexes) { - this.filesIndexes = containersIndexes; - } - - /** - * Get the file indexes. - * @return The file indexes. - */ - public int[] getFilesIndexes() { - return filesIndexes; - } -} diff --git a/Server/src/main/core/cache/misc/FilesContainer.kt b/Server/src/main/core/cache/misc/FilesContainer.kt new file mode 100644 index 000000000..192ca3389 --- /dev/null +++ b/Server/src/main/core/cache/misc/FilesContainer.kt @@ -0,0 +1,9 @@ +package core.cache.misc + +data class FilesContainer( + var version: Int = -1, + var crc: Int = -1, + var nameHash: Int = -1, + var filesIndexes: IntArray? = null, + var files: Array? = null +) \ No newline at end of file diff --git a/Server/src/main/core/cache/misc/buffer/BufferInputStream.java b/Server/src/main/core/cache/misc/buffer/BufferInputStream.java deleted file mode 100644 index a801c870d..000000000 --- a/Server/src/main/core/cache/misc/buffer/BufferInputStream.java +++ /dev/null @@ -1,39 +0,0 @@ -package core.cache.misc.buffer; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; - -/** - * Handles the reading of data from a byte buffer. - * @author Emperor - */ -public final class BufferInputStream extends InputStream { - - /** - * The buffer to write on. - */ - private final ByteBuffer buffer; - - /** - * The buffer input stream. - * @param buffer The buffer. - */ - public BufferInputStream(ByteBuffer buffer) throws IOException { - this.buffer = buffer; - } - - @Override - public int read() throws IOException { - return buffer.get(); - } - - /** - * Gets the buffer. - * @return The buffer. - */ - public ByteBuffer getBuffer() { - return buffer; - } - -} diff --git a/Server/src/main/core/cache/misc/buffer/BufferOutputStream.java b/Server/src/main/core/cache/misc/buffer/BufferOutputStream.java deleted file mode 100644 index 88ea2ac69..000000000 --- a/Server/src/main/core/cache/misc/buffer/BufferOutputStream.java +++ /dev/null @@ -1,57 +0,0 @@ -package core.cache.misc.buffer; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -/** - * Handles the writing of data on a byte buffer. - * @author Emperor - */ -public final class BufferOutputStream extends OutputStream { - - /** - * The buffer to write on. - */ - private final ByteBuffer buffer; - - /** - * Constructs a new {@code BufferOutputStream} {@code Object}. - * @param buffer The buffer to write on. - * @throws IOException When an I/O exception occurs. - * @throws SecurityException If a security manager exists and its - * checkPermission method denies enabling subclassing. - */ - public BufferOutputStream(ByteBuffer buffer) throws IOException, SecurityException { - super(); - this.buffer = buffer; - } - - @Override - public void write(int b) throws IOException { - buffer.put((byte) b); - } - - @Override - public void flush() { - /* - * empty. - */ - } - - @Override - public void close() { - /* - * empty. - */ - } - - /** - * Gets the buffer. - * @return The buffer. - */ - public ByteBuffer getBuffer() { - return buffer; - } - -} \ No newline at end of file diff --git a/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.java b/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.java deleted file mode 100644 index fb04ae272..000000000 --- a/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.java +++ /dev/null @@ -1,182 +0,0 @@ -package core.cache.misc.buffer; - -import java.io.ObjectInputStream; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - -/** - * Holds utility methods for reading/writing a byte buffer. - * @author Emperor - */ -public final class ByteBufferUtils { - - /** - * Gets a string from the byte buffer. - * @param buffer The byte buffer. - * @return The string. - */ - public static String getString(ByteBuffer buffer) { - StringBuilder sb = new StringBuilder(); - byte b; - while ((b = buffer.get()) != 0) { - sb.append((char) b); - } - return sb.toString(); - } - - /** - * Puts a string on the byte buffer. - * @param s The string to put. - * @param buffer The byte buffer. - */ - public static void putString(String s, ByteBuffer buffer) { - buffer.put(s.getBytes(StandardCharsets.UTF_8)).put((byte) 0); - } - - /** - * Gets a string from the byte buffer. - * @param s The string. - * @param buffer The byte buffer. - * @return The string. - */ - public static ByteBuffer putGJ2String(String s, ByteBuffer buffer) { - byte[] packed = new byte[256]; - int length = packGJString2(0, packed, s); - return buffer.put((byte) 0).put(packed, 0, length).put((byte) 0); - } - - /** - * Decodes the XTEA encryption. - * @param keys The keys. - * @param start The start index. - * @param end The end index. - * @param buffer The byte buffer. - */ - public static void decodeXTEA(int[] keys, int start, int end, ByteBuffer buffer) { - int l = buffer.position(); - buffer.position(start); - int length = (end - start) / 8; - for (int i = 0; i < length; i++) { - int firstInt = buffer.getInt(); - int secondInt = buffer.getInt(); - int sum = 0xc6ef3720; - int delta = 0x9e3779b9; - for (int j = 32; j-- > 0;) { - secondInt -= keys[(sum & 0x1c84) >>> 11] + sum ^ (firstInt >>> 5 ^ firstInt << 4) + firstInt; - sum -= delta; - firstInt -= (secondInt >>> 5 ^ secondInt << 4) + secondInt ^ keys[sum & 3] + sum; - } - buffer.position(buffer.position() - 8); - buffer.putInt(firstInt); - buffer.putInt(secondInt); - } - buffer.position(l); - } - - /** - * Converts a String to an Integer? - * @param position The position. - * @param buffer The buffer used. - * @param string The String to convert. - * @return The Integer. - */ - public static int packGJString2(int position, byte[] buffer, String string) { - int length = string.length(); - int offset = position; - for (int i = 0; length > i; i++) { - int character = string.charAt(i); - if (character > 127) { - if (character > 2047) { - buffer[offset++] = (byte) ((character | 919275) >> 12); - buffer[offset++] = (byte) (128 | ((character >> 6) & 63)); - buffer[offset++] = (byte) (128 | (character & 63)); - } else { - buffer[offset++] = (byte) ((character | 12309) >> 6); - buffer[offset++] = (byte) (128 | (character & 63)); - } - } else - buffer[offset++] = (byte) character; - } - return offset - position; - } - - /** - * Gets a tri-byte from the buffer. - * @param buffer The buffer. - * @return The value. - */ - public static int getMedium(ByteBuffer buffer) { - return ((buffer.get() & 0xFF) << 16) + ((buffer.get() & 0xFF) << 8) + (buffer.get() & 0xFF); - } - - /** - * Gets a smart from the buffer. - * @param buffer The buffer. - * @return The value. - */ - public static int getSmart(ByteBuffer buffer) { - int peek = buffer.get() & 0xFF; - if (peek <= Byte.MAX_VALUE) { - return peek; - } - return ((peek << 8) | (buffer.get() & 0xFF)) - 32768; - } - - /** - * Gets a smart from the buffer. - * @param buffer The buffer. - * @return The value. - */ - public static int getBigSmart(ByteBuffer buffer) { - int value = 0; - int current = getSmart(buffer); - while (current == 32767) { - current = getSmart(buffer); - value += 32767; - } - value += current; - return value; - } - - /* *//** - * Writes an object on the buffer. - * @param buffer The buffer to write on. - * @param o The object. - */ - /* - * public static void putObject(ByteBuffer buffer, Object o) { ByteBuffer b; - * try (ObjectOutputStream out = new ObjectOutputStream(new - * BufferOutputStream(b = ByteBuffer.allocate(99999)))) { - * out.writeObject(o); b.flip(); } catch (Throwable e) { - * e.printStackTrace(); b = (ByteBuffer) ByteBuffer.allocate(0).flip(); } - * buffer.putInt(b.remaining()); if (b.remaining() > 0) { buffer.put(b); } } - */ - - /** - * Gets an object from the byte buffer. - * @param buffer The buffer. - * @return The object. - */ - public static Object getObject(ByteBuffer buffer) { - int length = buffer.getInt(); - if (length > 0) { - byte[] bytes = new byte[length]; - buffer.get(bytes); - try (ObjectInputStream str = new ObjectInputStream(new BufferInputStream(ByteBuffer.wrap(bytes)))) { - return (Object) str.readObject(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - return null; - } - - /** - * Constructs a new {@code ByteBufferUtils} {@code Object}. - */ - private ByteBufferUtils() { - /* - * empty. - */ - } -} \ No newline at end of file diff --git a/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.kt b/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.kt new file mode 100644 index 000000000..73d72df70 --- /dev/null +++ b/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.kt @@ -0,0 +1,142 @@ +package core.cache.misc.buffer + +import java.nio.ByteBuffer +import java.nio.charset.StandardCharsets + +object ByteBufferUtils { + /** + * Gets a string from the byte buffer. + * @param buffer The byte buffer. + * @return The string. + */ + @JvmStatic + fun getString(buffer: ByteBuffer): String { + val sb = StringBuilder() + var b: Byte + while (buffer.get().also { b = it }.toInt() != 0) { + sb.append(Char(b.toUShort())) + } + return sb.toString() + } + + /** + * Puts a string on the byte buffer. + * @param s The string to put. + * @param buffer The byte buffer. + */ + @JvmStatic + fun putString(s: String, buffer: ByteBuffer) { + buffer.put(s.toByteArray(StandardCharsets.UTF_8)).put(0.toByte()) + } + + /** + * Gets a string from the byte buffer. + * @param s The string. + * @param buffer The byte buffer. + * @return The string. + */ + fun putGJ2String(s: String, buffer: ByteBuffer): ByteBuffer { + val packed = ByteArray(256) + val length = packGJString2(0, packed, s) + return buffer.put(0.toByte()).put(packed, 0, length).put(0.toByte()) + } + + /** + * Decodes the XTEA encryption. + * @param keys The keys. + * @param start The start index. + * @param end The end index. + * @param buffer The byte buffer. + */ + fun decodeXTEA(keys: IntArray, start: Int, end: Int, buffer: ByteBuffer) { + val l = buffer.position() + buffer.position(start) + val length = (end - start) / 8 + for (i in 0 until length) { + var firstInt = buffer.getInt() + var secondInt = buffer.getInt() + var sum = -0x3910c8e0 + val delta = -0x61c88647 + var j = 32 + while (j-- > 0) { + secondInt -= keys[sum and 0x1c84 ushr 11] + sum xor (firstInt ushr 5 xor (firstInt shl 4)) + firstInt + sum -= delta + firstInt -= (secondInt ushr 5 xor (secondInt shl 4)) + secondInt xor keys[sum and 3] + sum + } + buffer.position(buffer.position() - 8) + buffer.putInt(firstInt) + buffer.putInt(secondInt) + } + buffer.position(l) + } + + /** + * Converts a String to an Integer? + * @param position The position. + * @param buffer The buffer used. + * @param string The String to convert. + * @return The Integer. + */ + @JvmStatic + fun packGJString2(position: Int, buffer: ByteArray, string: String): Int { + val length = string.length + var offset = position + var i = 0 + while (length > i) { + val character = string[i].code + if (character > 127) { + if (character > 2047) { + buffer[offset++] = (character or 919275 shr 12).toByte() + buffer[offset++] = (128 or (character shr 6 and 63)).toByte() + buffer[offset++] = (128 or (character and 63)).toByte() + } else { + buffer[offset++] = (character or 12309 shr 6).toByte() + buffer[offset++] = (128 or (character and 63)).toByte() + } + } else buffer[offset++] = character.toByte() + i++ + } + return offset - position + } + + /** + * Gets a tri-byte from the buffer. + * @param buffer The buffer. + * @return The value. + */ + @JvmStatic + fun getMedium(buffer: ByteBuffer): Int { + return (buffer.get().toInt() and 0xFF shl 16) + (buffer.get().toInt() and 0xFF shl 8) + (buffer.get() + .toInt() and 0xFF) + } + + /** + * Gets a smart from the buffer. + * @param buffer The buffer. + * @return The value. + */ + @JvmStatic + fun getSmart(buffer: ByteBuffer): Int { + val peek = buffer.get().toInt() and 0xFF + return if (peek <= Byte.MAX_VALUE) { + peek + } else (peek shl 8 or (buffer.get().toInt() and 0xFF)) - 32768 + } + + /** + * Gets a smart from the buffer. + * @param buffer The buffer. + * @return The value. + */ + @JvmStatic + fun getBigSmart(buffer: ByteBuffer): Int { + var value = 0 + var current = getSmart(buffer) + while (current == 32767) { + current = getSmart(buffer) + value += 32767 + } + value += current + return value + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/activity/Cutscene.kt b/Server/src/main/core/game/activity/Cutscene.kt index 68c4bba85..a75dcb4b5 100644 --- a/Server/src/main/core/game/activity/Cutscene.kt +++ b/Server/src/main/core/game/activity/Cutscene.kt @@ -57,6 +57,15 @@ abstract class Cutscene(val player: Player) { base = region.baseLocation } + /** + * Immediately closes the player's overlay. + */ + fun closeOverlay() + { + logCutscene("Close ${player.username}'s overlay.") + player.interfaceManager.closeOverlay() + } + /** * Fade the player's view to black. This process can be safely assumed to take about 8 ticks to complete. */ @@ -113,14 +122,38 @@ abstract class Cutscene(val player: Player) { * @param expression the FacialExpression the NPC should use * @param message the message to send * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + * @param hide Should the continue button be hidden? */ - fun dialogueUpdate(npcId: Int, expression: core.game.dialogue.FacialExpression, message: String, onContinue: () -> Unit = {incrementStage()}) + fun dialogueUpdate(npcId: Int, expression: core.game.dialogue.FacialExpression, message: String, onContinue: () -> Unit = {incrementStage()}, hide: Boolean = false) { logCutscene("Sending NPC dialogue update.") - sendNPCDialogue(player, npcId, message, expression) + sendNPCDialogue(player, npcId, message, expression, hide) player.dialogueInterpreter.addAction { _,_ -> onContinue.invoke() } } + /** + * Sends a dialogue to the player using the given NPC ID, which updates the cutscene stage by default when continued. + * @param npcId the ID of the NPC to send a dialogue for + * @param expression the FacialExpression the NPC should use + * @param message the message to send + * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + */ + fun dialogueLinesUpdate(npcId: Int, expression: core.game.dialogue.FacialExpression, vararg message: String, onContinue: () -> Unit = {incrementStage()}) + { + logCutscene("Sending NPC dialogue lines update.") + sendNPCDialogueLines(player, npcId, expression, true, *message) + player.dialogueInterpreter.addAction { _,_ -> onContinue.invoke() } + } + + /** + * Forces the dialogue to close. + */ + fun dialogueClose() + { + logCutscene("Sending dialogue close.") + closeDialogue(player) + } + /** * Sends a non-NPC dialogue to the player, which updates the cutscene stage by default when continued * @param message the message to send @@ -133,6 +166,18 @@ abstract class Cutscene(val player: Player) { player.dialogueInterpreter.addAction {_,_ -> onContinue.invoke()} } + /** + * Sends a non-NPC dialogue to the player, which updates the cutscene stage by default when continued + * @param message the message to send + * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + */ + fun dialogueLinesUpdate(vararg message: String, onContinue: () -> Unit = {incrementStage()}) + { + logCutscene("Sending standard dialogue lines update.") + sendDialogueLines(player, *message) + player.dialogueInterpreter.addAction {_,_ -> onContinue.invoke()} + } + /** * Sends a player dialogue, which updates the cutscene stage by default when continued * @param expression the FacialExpression to use @@ -223,13 +268,19 @@ abstract class Cutscene(val player: Player) { logCutscene("Added NPC $id at location LOCAL[$regionX,$regionY,$plane] GLOBAL[${npc.location.x},${npc.location.y},$plane]") } - fun start() + fun start(){ + start(true) + } + + fun start(hideMiniMap: Boolean) { logCutscene("Starting cutscene for ${player.username}.") region = RegionManager.forId(player.location.regionId) base = RegionManager.forId(player.location.regionId).baseLocation setup() - PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + if (hideMiniMap) { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + } runStage(player.getCutsceneStage()) setAttribute(player, ATTRIBUTE_CUTSCENE, this) setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, 0) @@ -242,22 +293,21 @@ abstract class Cutscene(val player: Player) { AntiMacro.pause(player) } + /** - * Ends this cutscene, fading the screen to black, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method. + * Ends this cutscene, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method. * @param endActions (optional) a method that executes when the cutscene fully completes */ - fun end(endActions: (() -> Unit)? = null) + fun endWithoutFade(endActions: (() -> Unit)? = null) { ended = true - fadeToBlack() GameWorld.Pulser.submit(object : Pulse(){ var tick: Int = 0 override fun pulse(): Boolean { when(tick++) { - 8 -> player.properties.teleportLocation = exitLocation - 9 -> fadeFromBlack() - 16 -> { + 0 -> player.properties.teleportLocation = exitLocation + 1 -> { return true } } @@ -288,6 +338,54 @@ abstract class Cutscene(val player: Player) { }) } + /** + * Ends this cutscene, fading the screen to black, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method. + * @param fade (optional) should the cutscene fade to black? + * @param endActions (optional) a method that executes when the cutscene fully completes + */ + fun end(fade: Boolean = true, endActions: (() -> Unit)? = null) + { + ended = true + if (fade) fadeToBlack() + GameWorld.Pulser.submit(object : Pulse(){ + var tick: Int = 0 + override fun pulse(): Boolean { + if (fade) { + when (tick++) { + 8 -> player.properties.teleportLocation = exitLocation + 9 -> fadeFromBlack() + 16 -> return true + else -> return false + } + } + else player.properties.teleportLocation = exitLocation + return true + } + + override fun stop() { + super.stop() + player ?: return + player.removeAttribute(ATTRIBUTE_CUTSCENE) + player.removeAttribute(ATTRIBUTE_CUTSCENE_STAGE) + player.properties.isSafeZone = false + player.properties.safeRespawn = ServerConstants.HOME_LOCATION + player.interfaceManager.restoreTabs() + player.unlock() + clearNPCs() + player.unhook(CUTSCENE_DEATH_HOOK) + player.logoutListeners.remove("cutscene") + AntiMacro.unpause(player) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + try { + endActions?.invoke() + } catch (e: Exception) { + log(this::class.java, Log.ERR, "There's some bad nasty code in ${this::class.java.simpleName} end actions!") + e.printStackTrace() + } + } + }) + } + /** * Moves the camera to the specified regionX and regionY * @param regionX the region-local X coordinate to move the camera to (0-63) diff --git a/Server/src/main/core/game/bots/AIPBuilder.java b/Server/src/main/core/game/bots/AIPBuilder.java index e79c95447..fb619f730 100644 --- a/Server/src/main/core/game/bots/AIPBuilder.java +++ b/Server/src/main/core/game/bots/AIPBuilder.java @@ -91,7 +91,7 @@ public final class AIPBuilder { //Varrock Ge bank RandomAfkPlayer(new Location(3189, 3439)); - //Home Bank + // Lunar Island Bank RandomAfkPlayer(new Location(2099, 3918)); } diff --git a/Server/src/main/core/game/bots/AIPlayer.java b/Server/src/main/core/game/bots/AIPlayer.java index 079875dec..e54fe732a 100644 --- a/Server/src/main/core/game/bots/AIPlayer.java +++ b/Server/src/main/core/game/bots/AIPlayer.java @@ -109,7 +109,7 @@ public class AIPlayer extends Player { * Generates bot stats/equipment/etc based on OSRScopyLine */ public void updateRandomValues() { - this.getAppearance().setGender(RandomFunction.random(5) == 1 ? Gender.FEMALE : Gender.MALE); + this.getAppearance().setGender(RandomFunction.random(3) == 1 ? Gender.FEMALE : Gender.MALE); int setTo = RandomFunction.random(0,10); CharacterDesign.randomize(this,true); this.setDirection(Direction.values()[new Random().nextInt(Direction.values().length)]); //Random facing dir diff --git a/Server/src/main/core/game/bots/CombatBotAssembler.kt b/Server/src/main/core/game/bots/CombatBotAssembler.kt index 7655d98e9..ebbed1402 100644 --- a/Server/src/main/core/game/bots/CombatBotAssembler.kt +++ b/Server/src/main/core/game/bots/CombatBotAssembler.kt @@ -53,7 +53,7 @@ class CombatBotAssembler { val bot = CombatBot(location) generateStats(bot, tier, Skills.RANGE, Skills.DEFENCE) - gearRangedBot(bot, crossbow ?: Random().nextInt() % 2 == 0) + gearRangedBot(bot, (crossbow ?: (Random().nextInt() % 2)) == 0) return bot } @@ -82,7 +82,7 @@ class CombatBotAssembler { fun MeleeAdventurer(tier: Tier, location: Location): CombatBot { val bot = CombatBot(location) var max = 0 - val level = RandomFunction.random(25, 65).also {max = 99 } + val level = RandomFunction.random(25, 69).also {max = 99 } generateStats(bot,tier,Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE) bot.skills.setStaticLevel(Skills.HITPOINTS, level) bot.skills.setStaticLevel(Skills.ATTACK, level + 5) @@ -114,7 +114,7 @@ class CombatBotAssembler { fun RangeAdventurer(tier: Tier, location: Location): CombatBot { val bot = CombatBot(location) var max = 0 - val level = RandomFunction.random(35, 65).also {max = 75 } + val level = RandomFunction.random(35, 69).also {max = 75 } generateStats(bot,tier,Skills.ATTACK, Skills.STRENGTH) bot.skills.setStaticLevel(Skills.HITPOINTS, level) bot.skills.setStaticLevel(Skills.DEFENCE, level) diff --git a/Server/src/main/core/game/bots/GeneralBotCreator.kt b/Server/src/main/core/game/bots/GeneralBotCreator.kt index 361247a36..7e3cb5478 100644 --- a/Server/src/main/core/game/bots/GeneralBotCreator.kt +++ b/Server/src/main/core/game/bots/GeneralBotCreator.kt @@ -98,7 +98,7 @@ class GeneralBotCreator { }*/ if(!botScript.running) return true //has to be separated this way or it double-submits the respawn pulse. - if (botPulsesTriggeredThisTick++ >= 50) + if (botPulsesTriggeredThisTick++ >= 75) return false val idleRoll = RandomFunction.random(10) diff --git a/Server/src/main/core/game/bots/Script.java b/Server/src/main/core/game/bots/Script.java index cda961420..9c5da330a 100644 --- a/Server/src/main/core/game/bots/Script.java +++ b/Server/src/main/core/game/bots/Script.java @@ -1,5 +1,6 @@ package core.game.bots; +import content.data.Quests; import core.game.node.entity.player.Player; import core.game.node.item.Item; @@ -13,7 +14,7 @@ public abstract class Script { public ArrayList inventory = new ArrayList<>(20); public ArrayList equipment = new ArrayList<>(20); public Map skills = new HashMap<>(); - public ArrayList quests = new ArrayList<>(20); + public ArrayList quests = new ArrayList<>(20); public Player bot; @@ -31,7 +32,7 @@ public abstract class Script { for (Map.Entry skill : skills.entrySet()) { setLevel(skill.getKey(), skill.getValue()); } - for (String quest : quests) { + for (Quests quest : quests) { bot.getQuestRepository().setStage(bot.getQuestRepository().getQuest(quest), 100); } for (Item i : equipment) { diff --git a/Server/src/main/core/game/bots/ScriptAPI.kt b/Server/src/main/core/game/bots/ScriptAPI.kt index 85ac568c1..c2ac69649 100644 --- a/Server/src/main/core/game/bots/ScriptAPI.kt +++ b/Server/src/main/core/game/bots/ScriptAPI.kt @@ -54,6 +54,7 @@ import kotlin.math.pow import kotlin.math.sqrt import core.ServerConstants import core.api.utils.Vector +import kotlin.random.Random class ScriptAPI(private val bot: Player) { val GRAPHICSUP = Graphics(1576) @@ -396,6 +397,20 @@ class ScriptAPI(private val bot: Player) { } } + /** + * @param location the location you want the coordinates randomized for. + * @param xMin the minimum range value X coordinates should be randomized by, must be xMin <= xMax ex: -1 min 1 max. + * @param xMax the maximum range value X coordinates should be randomized by, must be xMin <= xMax ex: -1 min 1 max. + * @param yMin the minimum range value Y coordinates should be randomized by, must be yMin <= yMax ex: -1 min 1 max. + * @param yMax the maximum range value Y coordinates should be randomized by, must be yMin <= yMax ex: -1 min 1 max. + * @param staticZ this value is static and does not change from what is given, must be actual Z value of location. + * @author Kermit + */ + fun randomizeLocationInRanges(location: Location, xMin: Int, xMax: Int, yMin: Int, yMax: Int, staticZ: Int): Location { + val newX = location.x + Random.nextInt(xMin, xMax) + val newY = location.y + Random.nextInt(yMin, yMax) + return Location(newX, newY, staticZ) + } /** * The iterator for long-distance walking. Limited by doors and large obstacles like mountains. @@ -487,7 +502,10 @@ class ScriptAPI(private val bot: Player) { } val canSell = GrandExchange.addBotOffer(actualId, itemAmt) if (canSell && saleIsBigNews(actualId, itemAmt)) { - Repository.sendNews(SERVER_GE_NAME + " just offered " + itemAmt + " " + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE.") + Repository.sendGrandExchangeNews( + SERVER_GE_NAME + " just offered " + itemAmt + " " + + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE." + ) } bot.bank.remove(Item(id, itemAmt)) bot.bank.refresh() @@ -517,7 +535,10 @@ class ScriptAPI(private val bot: Player) { } val canSell = GrandExchange.addBotOffer(actualId, itemAmt) if (canSell && saleIsBigNews(actualId, itemAmt)) { - Repository.sendNews(SERVER_GE_NAME + " just offered " + itemAmt + " " + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE.") + Repository.sendGrandExchangeNews( + SERVER_GE_NAME + " just offered " + itemAmt + " " + + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE." + ) } bot.bank.remove(item) bot.bank.refresh() @@ -553,7 +574,10 @@ class ScriptAPI(private val bot: Player) { 1517 -> continue 1519 -> continue 1521 -> continue - else -> Repository.sendNews(SERVER_GE_NAME + " just offered " + itemAmt + " " + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE.") + else -> Repository.sendGrandExchangeNews( + SERVER_GE_NAME + " just offered " + itemAmt + " " + + ItemDefinition.forId(actualId).name.lowercase() + " on the GE." + ) } } bot.bank.remove(item) @@ -562,7 +586,35 @@ class ScriptAPI(private val bot: Player) { return true } } - bot.pulseManager.run(toCounterPulseAll()) + if (ge != null) { + bot.pulseManager.run(toCounterPulseAll()) + } + } + + /** + * Function to bank all items that are not excluded at a nearby bank. + * @author Kermit & Ceikry + */ + fun depositAtBank(){ + val bank: Scenery? = getNearestNode("Bank booth", true) as Scenery? + class BankingPulse : MovementPulse(bot, bank, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(bank?.location) + for (item in bot.inventory.toArray()) { + item ?: continue + when (item.id) { + Items.RUNE_AXE_1359, Items.TINDERBOX_590, Items.ADAMANT_PICKAXE_1271, Items.COINS_995 -> continue + } + bot.bank.add(item) + bot.inventory.remove(item) + } +// log(this::class.java, Log.FINE, "${bot.username} Just finished banking at ${bot.location} || Bank contents: ${bot.bank}") + return true + } + } + if (bank != null) { + bot.pulseManager.run(BankingPulse()) + } } /** diff --git a/Server/src/main/core/game/bots/SkillingBotAssembler.kt b/Server/src/main/core/game/bots/SkillingBotAssembler.kt index 4e47773fa..decb90a85 100644 --- a/Server/src/main/core/game/bots/SkillingBotAssembler.kt +++ b/Server/src/main/core/game/bots/SkillingBotAssembler.kt @@ -2,6 +2,7 @@ package core.game.bots import core.game.node.item.Item import core.game.world.map.Location +import org.rs09.consts.Items class SkillingBotAssembler { fun produce(type: Wealth, loc: Location): AIPlayer { @@ -39,7 +40,161 @@ class SkillingBotAssembler { RICH } - val POORSETS = arrayOf(listOf(542,544), listOf(581), listOf(6654,6655,6656), listOf(6654,6656), listOf(636,646), listOf(638,648), listOf(), listOf(), listOf()) - val AVGSETS = arrayOf(listOf(2649,342,344), listOf(2651,542,544), listOf(6654,6655,6656), listOf(6139,6141), listOf(9923,9924,9925), listOf(10400,10402,2649), listOf(10404,10406), listOf(12971,12978)) - val RICHSETS = arrayOf(listOf(10330,10332,2649), listOf(12873,12880,1046), listOf(13858,13861,13864), listOf(13887,13893), listOf(3481,3483), listOf(2653,2655), listOf(2661,2663), listOf(2591,2593), listOf(14490,14492)) + val POORSETS = arrayOf( + listOf(Items.BLACK_ROBE_581, Items.BLACK_SKIRT_1015, Items.STAFF_OF_AIR_1381), + listOf(Items.BLACK_ROBE_581, Items.BLACK_SKIRT_1015), + listOf(Items.BLACK_ROBE_581, Items.BLACK_SKIRT_1015, Items.WIZARD_HAT_1017), + listOf(), // No equipment + listOf(Items.WIZARD_HAT_579), + listOf(Items.WIZARD_HAT_579, Items.STAFF_OF_AIR_1381), + listOf(Items.WIZARD_HAT_579, Items.STAFF_1379), + listOf(Items.WIZARD_HAT_579, Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011), + listOf(Items.WIZARD_HAT_579, Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.TIARA_5525), + listOf(Items.WIZARD_HAT_579, Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.TEAM_1_CAPE_4315), + listOf(Items.WIZARD_HAT_579, Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.STAFF_OF_AIR_1381), + listOf(Items.WIZARD_HAT_579, Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.STAFF_OF_WATER_1383), + listOf(Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011), + listOf(Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.TIARA_5525), + listOf(Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.TEAM_1_CAPE_4315), + listOf(Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.STAFF_OF_AIR_1381), + listOf(Items.WIZARD_ROBE_577, Items.BLUE_SKIRT_1011, Items.STAFF_OF_WATER_1383), + listOf(), // No equipment + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_PLATEBODY_1119, Items.STEEL_KITESHIELD_1193, Items.STEEL_LONGSWORD_1295, Items.TEAM_29_CAPE_4371), + listOf(Items.STEEL_PLATESKIRT_1083, Items.STEEL_PLATEBODY_1119, Items.STEEL_KITESHIELD_1193, Items.STEEL_LONGSWORD_1295, Items.TEAM_30_CAPE_4373), + listOf(Items.STEEL_PLATESKIRT_1083, Items.STEEL_PLATEBODY_1119, Items.STEEL_FULL_HELM_1157, Items.TEAM_30_CAPE_4373), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_CHAINBODY_1105, Items.STEEL_FULL_HELM_1157, Items.TEAM_31_CAPE_4375), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_PLATEBODY_1119, Items.TEAM_29_CAPE_4371), + listOf(Items.STEEL_PLATESKIRT_1083, Items.STEEL_PLATEBODY_1119, Items.TEAM_30_CAPE_4373), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_CHAINBODY_1105, Items.TEAM_31_CAPE_4375), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_CHAINBODY_1105, Items.STEEL_2H_SWORD_1311, Items.TEAM_34_CAPE_4381), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_CHAINBODY_1105, Items.STEEL_SCIMITAR_1325, Items.TEAM_35_CAPE_4383), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_CHAINBODY_1105, Items.STEEL_BATTLEAXE_1365, Items.TEAM_35_CAPE_4383), + listOf(Items.STEEL_PLATELEGS_1069, Items.STEEL_CHAINBODY_1105, Items.STEEL_BATTLEAXE_1365, Items.STEEL_SQ_SHIELD_1177, Items.TEAM_35_CAPE_4383), + listOf(), // No equipment + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.IRON_KITESHIELD_1191, Items.IRON_LONGSWORD_1293, Items.TEAM_36_CAPE_4385), + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.IRON_2H_SWORD_1309, Items.TEAM_37_CAPE_4387), + listOf(Items.IRON_PLATESKIRT_1081, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.IRON_SCIMITAR_1323, Items.TEAM_32_CAPE_4377), + listOf(Items.IRON_PLATESKIRT_1081, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.IRON_BATTLEAXE_1363, Items.TEAM_32_CAPE_4377), + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_CHAINBODY_1101, Items.IRON_KITESHIELD_1191, Items.IRON_LONGSWORD_1293, Items.TEAM_33_CAPE_4379), + listOf(Items.IRON_PLATESKIRT_1081, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.TEAM_39_CAPE_4391), + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.TEAM_37_CAPE_4387), + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_PLATEBODY_1115, Items.IRON_SCIMITAR_1323, Items.TEAM_32_CAPE_4377), + listOf(Items.IRON_PLATESKIRT_1081, Items.IRON_PLATEBODY_1115, Items.TEAM_32_CAPE_4377), + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_CHAINBODY_1101, Items.TEAM_33_CAPE_4379), + listOf(Items.IRON_PLATESKIRT_1081, Items.IRON_PLATEBODY_1115, Items.IRON_FULL_HELM_1153, Items.TEAM_32_CAPE_4377), + listOf(Items.IRON_PLATESKIRT_1081, Items.IRON_CHAINBODY_1101, Items.IRON_FULL_HELM_1153, Items.TEAM_32_CAPE_4377), + listOf(Items.IRON_PLATELEGS_1067, Items.IRON_CHAINBODY_1101, Items.IRON_FULL_HELM_1153, Items.TEAM_33_CAPE_4379), + listOf(), // No equipment + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_PLATEBODY_1117,Items.BRONZE_FULL_HELM_1155,Items.BRONZE_KITESHIELD_1189,Items.BRONZE_LONGSWORD_1291,Items.TEAM_27_CAPE_4367), + listOf(Items.BRONZE_PLATESKIRT_1087,Items.BRONZE_PLATEBODY_1117,Items.BRONZE_FULL_HELM_1155,Items.BRONZE_KITESHIELD_1189,Items.BRONZE_LONGSWORD_1291,Items.TEAM_27_CAPE_4367), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_PLATEBODY_1117,Items.BRONZE_FULL_HELM_1155,Items.BRONZE_2H_SWORD_1307, Items.TEAM_28_CAPE_4369), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_CHAINBODY_1103), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_CHAINBODY_1103,Items.BRONZE_2H_SWORD_1307), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_CHAINBODY_1103,Items.BRONZE_SCIMITAR_1321), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_CHAINBODY_1103,Items.BRONZE_BATTLEAXE_1375), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_CHAINBODY_1103,Items.BRONZE_BATTLEAXE_1375,Items.BRONZE_SQ_SHIELD_1173), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_PLATEBODY_1117, Items.TEAM_27_CAPE_4367), + listOf(Items.BRONZE_PLATELEGS_1075,Items.BRONZE_PLATEBODY_1117,Items.BRONZE_FULL_HELM_1155, Items.TEAM_27_CAPE_4367), + listOf(Items.BRONZE_PLATESKIRT_1087,Items.BRONZE_CHAINBODY_1103), + listOf(Items.BRONZE_PLATESKIRT_1087,Items.BRONZE_CHAINBODY_1103,Items.BRONZE_FULL_HELM_1155), + listOf(Items.BRONZE_PLATESKIRT_1087,Items.BRONZE_CHAINBODY_1103,Items.BRONZE_FULL_HELM_1155, Items.TEAM_28_CAPE_4369), + listOf(Items.BRONZE_PLATESKIRT_1087,Items.BRONZE_PLATEBODY_1117, Items.TEAM_28_CAPE_4369), + listOf(), // No equipment + listOf(Items.LEATHER_BODY_1129,Items.LEATHER_CHAPS_1095), + listOf(), // No equipment + listOf(Items.STUDDED_CHAPS_1097,Items.STUDDED_BODY_1133), + listOf(Items.MIME_LEGS_3059,Items.MIME_TOP_3058,Items.MIME_BOOTS_3061,Items.MIME_GLOVES_3060,Items.MIME_MASK_3057), + listOf(Items.MIME_LEGS_3059,Items.MIME_TOP_3058,Items.MIME_BOOTS_3061,Items.MIME_GLOVES_3060), + listOf(Items.MONKS_ROBE_542,Items.MONKS_ROBE_544), + listOf(Items.CHICKEN_LEGS_11022,Items.CHICKEN_WINGS_11020,Items.CHICKEN_HEAD_11021,Items.CHICKEN_FEET_11019), + listOf(Items.TOY_KITE_12844,Items.CHOCATRICE_CAPE_12634), + listOf(), // No equipment + listOf(Items.WHITE_APRON_1005, Items.CHEFS_HAT_1949), + listOf(Items.TEAM_10_CAPE_4333), + listOf(Items.TEAM_2_CAPE_4317), + listOf(), // No equipment + listOf(), // No equipment + listOf(), // No equipment + listOf()) + + val AVGSETS = arrayOf( + listOf(Items.SKELETAL_TOP_6139, Items.SKELETAL_BOTTOMS_6141), + listOf(Items.SKELETON_LEGGINGS_9923, Items.SKELETON_SHIRT_9924, Items.SKELETON_MASK_9925), + listOf(Items.BLACK_ELE_SHIRT_10400,Items.BLACK_ELE_LEGS_10402,Items.BROWN_HEADBAND_2649), + listOf(Items.RED_ELE_SHIRT_10404,Items.RED_ELE_LEGS_10406), + listOf(Items.COMBAT_ROBE_TOP_100_12971, Items.COMBAT_ROBE_BOTTOM_100_12978), + listOf(Items.COMBAT_ROBE_TOP_100_12971, Items.COMBAT_ROBE_BOTTOM_100_12978, Items.COMBAT_HOOD_100_12964), + listOf(Items.COMBAT_ROBE_TOP_100_12971, Items.COMBAT_ROBE_BOTTOM_100_12978, Items.RUNE_BERSERKER_SHIELD_100_12929), + listOf(Items.COMBAT_ROBE_TOP_100_12971, Items.COMBAT_ROBE_BOTTOM_100_12978, Items.ADAMANT_BERSERKER_SHIELD_100_12915), + listOf(Items.DRUIDIC_MAGE_TOP_100_12894, Items.DRUIDIC_MAGE_BOTTOM_100_12901, Items.DRUIDIC_MAGE_HOOD_100_12887), + listOf(), // No equipment + listOf(Items.MITHRIL_PLATELEGS_1071, Items.MITHRIL_PLATEBODY_1121, Items.MITHRIL_KITESHIELD_1197, Items.MITHRIL_LONGSWORD_1299, Items.TEAM_29_CAPE_4371), + listOf(Items.MITHRIL_PLATESKIRT_1085, Items.MITHRIL_PLATEBODY_1121, Items.MITHRIL_KITESHIELD_1197, Items.MITHRIL_LONGSWORD_1299, Items.TEAM_30_CAPE_4373), + listOf(Items.MITHRIL_PLATELEGS_1071, Items.MITHRIL_PLATEBODY_1121, Items.TEAM_29_CAPE_4371), + listOf(Items.MITHRIL_PLATESKIRT_1085, Items.MITHRIL_PLATEBODY_1121, Items.TEAM_30_CAPE_4373), + listOf(Items.MITHRIL_PLATESKIRT_1085, Items.MITHRIL_CHAINBODY_1109, Items.TEAM_30_CAPE_4373), + listOf(Items.MITHRIL_PLATELEGS_1071, Items.MITHRIL_CHAINBODY_1109, Items.TEAM_31_CAPE_4375), + listOf(Items.MITHRIL_PLATELEGS_1071, Items.MITHRIL_CHAINBODY_1109, Items.MITHRIL_2H_SWORD_1315, Items.TEAM_34_CAPE_4381), + listOf(Items.MITHRIL_PLATELEGS_1071, Items.MITHRIL_CHAINBODY_1109, Items.MITHRIL_SCIMITAR_1329, Items.TEAM_35_CAPE_4383), + listOf(Items.MITHRIL_PLATELEGS_1071, Items.MITHRIL_CHAINBODY_1109, Items.MITHRIL_BATTLEAXE_1369, Items.TEAM_36_CAPE_4385), + listOf(), // No equipment + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_PLATEBODY_1124,Items.ADAMANT_KITESHIELD_1199,Items.ADAMANT_LONGSWORD_1301, Items.TEAM_29_CAPE_4371), + listOf(Items.ADAMANT_PLATESKIRT_1091,Items.ADAMANT_PLATEBODY_1124,Items.ADAMANT_KITESHIELD_1199,Items.ADAMANT_LONGSWORD_1301, Items.TEAM_30_CAPE_4373), + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_PLATEBODY_1124, Items.TEAM_29_CAPE_4371), + listOf(Items.ADAMANT_PLATESKIRT_1091,Items.ADAMANT_PLATEBODY_1124, Items.TEAM_30_CAPE_4373), + listOf(Items.ADAMANT_PLATESKIRT_1091,Items.ADAMANT_CHAINBODY_1111, Items.TEAM_30_CAPE_4373), + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_CHAINBODY_1111, Items.TEAM_31_CAPE_4375), + listOf(Items.ADAMANT_PLATESKIRT_1091,Items.ADAMANT_CHAINBODY_1111,Items.ADAMANT_FULL_HELM_1161, Items.TEAM_30_CAPE_4373), + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_CHAINBODY_1111,Items.ADAMANT_FULL_HELM_1161, Items.TEAM_31_CAPE_4375), + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_CHAINBODY_1111,Items.ADAMANT_2H_SWORD_1317, Items.TEAM_34_CAPE_4381), + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_CHAINBODY_1111,Items.ADAMANT_SCIMITAR_1331, Items.TEAM_35_CAPE_4383), + listOf(Items.ADAMANT_PLATELEGS_1073,Items.ADAMANT_CHAINBODY_1111,Items.ADAMANT_BATTLEAXE_1371, Items.TEAM_35_CAPE_4383), + listOf(), // No equipment + listOf(Items.GREEN_DHIDE_BODY_1135,Items.GREEN_DHIDE_CHAPS_1099,Items.GREEN_DHIDE_VAMB_1065,Items.GREEN_DHIDE_COIF_100_12936,Items.AVAS_ACCUMULATOR_10499), + listOf(Items.GREEN_DHIDE_BODY_1135,Items.GREEN_DHIDE_CHAPS_1099,Items.GREEN_DHIDE_VAMB_1065,Items.GREEN_DHIDE_COIF_100_12936,Items.ADAMANT_CROSSBOW_9183,Items.AVAS_ACCUMULATOR_10499), + listOf(Items.TEAM_10_CAPE_4333), + listOf(Items.TEAM_1_CAPE_4315), + listOf(), // No equipment + listOf(), // No equipment + listOf()) + + val RICHSETS = arrayOf( + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_PLATEBODY_1127,Items.RUNE_KITESHIELD_1201,Items.RUNE_FULL_HELM_1163,Items.RUNE_LONGSWORD_1303,Items.TEAM_29_CAPE_4371), + listOf(Items.RUNE_PLATESKIRT_1093,Items.RUNE_PLATEBODY_1127,Items.RUNE_KITESHIELD_1201,Items.RUNE_FULL_HELM_1163,Items.RUNE_LONGSWORD_1303,Items.TEAM_30_CAPE_4373), + listOf(Items.RUNE_PLATESKIRT_1093,Items.RUNE_PLATEBODY_1127, Items.TEAM_29_CAPE_4371), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_PLATEBODY_1127,Items.RUNE_FULL_HELM_1163,Items.TEAM_29_CAPE_4371), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_PLATEBODY_1127,Items.RUNE_BERSERKER_SHIELD_100_12929,Items.TEAM_29_CAPE_4371), + listOf(Items.RUNE_PLATESKIRT_1093,Items.RUNE_PLATEBODY_1127,Items.TEAM_30_CAPE_4373), + listOf(Items.RUNE_PLATESKIRT_1093,Items.RUNE_CHAINBODY_1113,Items.TEAM_30_CAPE_4373), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_CHAINBODY_1113,Items.TEAM_31_CAPE_4375), + listOf(Items.RUNE_PLATESKIRT_1093,Items.RUNE_CHAINBODY_1113,Items.RUNE_FULL_HELM_1163,Items.TEAM_30_CAPE_4373), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_CHAINBODY_1113,Items.RUNE_FULL_HELM_1163,Items.TEAM_31_CAPE_4375), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_CHAINBODY_1113,Items.RUNE_2H_SWORD_1319,Items.TEAM_34_CAPE_4381), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_CHAINBODY_1113,Items.RUNE_SCIMITAR_1333,Items.TEAM_35_CAPE_4383), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_CHAINBODY_1113,Items.RUNE_BATTLEAXE_1373,Items.TEAM_35_CAPE_4383), + listOf(Items.RUNE_PLATELEGS_1079,Items.RUNE_PLATEBODY_1127,Items.ABYSSAL_WHIP_4151,Items.TEAM_29_CAPE_4371), + listOf(), // No equipment + listOf(Items.RUNE_PLATEBODY_G_2615,Items.RUNE_PLATELEGS_G_2618,Items.RUNE_KITESHIELD_G_2621,Items.RUNE_FULL_HELMG_2619, Items.TEAM_27_CAPE_4367), + listOf(Items.RUNE_PLATEBODY_T_2623,Items.RUNE_PLATELEGS_T_2625,Items.RUNE_KITESHIELD_T_2629,Items.RUNE_FULL_HELM_T_2627, Items.TEAM_27_CAPE_4367), + listOf(Items.GILDED_PLATEBODY_3481,Items.GILDED_PLATELEGS_3483,Items.CAPE_1030), + listOf(Items.ZAMORAK_PLATEBODY_2653,Items.ZAMORAK_PLATELEGS_2655,Items.ZAMORAK_FULL_HELM_2657), + listOf(Items.SARADOMIN_PLATEBODY_2661,Items.SARADOMIN_PLATELEGS_2663,Items.SARADOMIN_FULL_HELM_2665), + listOf(Items.GUTHIX_PLATEBODY_2669,Items.GUTHIX_PLATELEGS_2671,Items.GUTHIX_FULL_HELM_2673), + listOf(Items.ZAMORAK_PLATEBODY_2653,Items.ZAMORAK_PLATELEGS_2655,Items.ZAMORAK_FULL_HELM_2657,Items.ZAMORAK_CAPE_2414), + listOf(Items.SARADOMIN_PLATEBODY_2661,Items.SARADOMIN_PLATELEGS_2663,Items.SARADOMIN_FULL_HELM_2665,Items.SARADOMIN_CAPE_2412), + listOf(Items.GUTHIX_PLATEBODY_2669,Items.GUTHIX_PLATELEGS_2671,Items.GUTHIX_FULL_HELM_2673,Items.GUTHIX_CAPE_2413), + listOf(Items.THIRD_AGE_ROBE_10340,Items.THIRD_AGE_ROBE_TOP_10338,Items.SANTA_HAT_1050), + listOf(), // No equipment + listOf(Items.DRAGON_PLATELEGS_4087,Items.DRAGON_CHAINBODY_3140,Items.ABYSSAL_WHIP_4151,Items.DRAGON_FULL_HELM_11335), + listOf(Items.DRAGON_PLATELEGS_4087,Items.DRAGON_CHAINBODY_3140,Items.DRAGONFIRE_SHIELD_11283,Items.DRAGON_FULL_HELM_11335), + listOf(), // No equipment + listOf(Items.BLACK_DHIDE_BODY_2503,Items.BLACK_DHIDE_CHAPS_2497,Items.BLACK_DHIDE_VAMB_2491,Items.RUNE_CROSSBOW_9185,Items.AVAS_ACCUMULATOR_10499), + listOf(Items.BLACK_DHIDE_BODY_2503,Items.BLACK_DHIDE_CHAPS_2497,Items.BLACK_DHIDE_VAMB_2491,Items.BLACK_DHIDE_COIF_100_12957,Items.RUNE_CROSSBOW_9185,Items.RUNE_KITESHIELD_1201), + listOf(Items.ELITE_BLACK_PLATEBODY_14492,Items.ELITE_BLACK_PLATELEGS_14490, Items.ELITE_BLACK_FULL_HELM_14494), + listOf(Items.BATTLE_ROBE_BOTTOM_100_12880,Items.BATTLE_ROBE_TOP_100_12873,Items.PURPLE_PARTYHAT_1046), + listOf(Items.ZURIELS_ROBE_BOTTOM_13862,Items.ZURIELS_ROBE_TOP_13858,Items.ZURIELS_HOOD_13864,Items.ZURIELS_HOOD_13864,Items.ZURIELS_STAFF_13867), + listOf(Items.VESTAS_CHAINBODY_13887,Items.VESTAS_PLATESKIRT_13893), + listOf(), // No equipment + listOf(), // No equipment + listOf()) } diff --git a/Server/src/main/core/game/consumable/Potion.java b/Server/src/main/core/game/consumable/Potion.java index 60afb00c3..89912d9f1 100644 --- a/Server/src/main/core/game/consumable/Potion.java +++ b/Server/src/main/core/game/consumable/Potion.java @@ -1,12 +1,16 @@ package core.game.consumable; import content.data.consumables.Consumables; +import core.game.interaction.QueueStrength; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.audio.Audio; import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; import org.rs09.consts.Sounds; -import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.*; public class Potion extends Drink { @@ -15,7 +19,7 @@ public class Potion extends Drink { private static final Audio SOUND = new Audio(2401, 1, 1); public Potion(final int[] ids, final ConsumableEffect effect, final String... messages) { - super(ids, effect, messages); + super(ids, effect, new Animation(829), messages); } @Override @@ -55,13 +59,17 @@ public class Potion extends Drink { } final int dosesLeft = ids.length - consumedDoses; player.getPacketDispatch().sendMessage("You drink some of your " + getFormattedName(item) + "."); - if (dosesLeft > 1) { - player.getPacketDispatch().sendMessage("You have " + dosesLeft + " doses of potion left."); - } else if (dosesLeft == 1) { - player.getPacketDispatch().sendMessage("You have 1 dose of potion left."); - } else { - player.getPacketDispatch().sendMessage("You have finished your potion."); - } + // Remaining dosages message should be delayed - https://youtu.be/n6CCf4Rj8Lg?t=79 + queueScript(player, 2, QueueStrength.SOFT, false, (Integer stage) -> { + if (dosesLeft > 1) { + player.getPacketDispatch().sendMessage("You have " + dosesLeft + " doses of potion left."); + } else if (dosesLeft == 1) { + player.getPacketDispatch().sendMessage("You have 1 dose of potion left."); + } else { + player.getPacketDispatch().sendMessage("You have finished your potion."); + } + return stopExecuting(player); + }); } public int getDose(Item potion){ diff --git a/Server/src/main/core/game/container/Container.java b/Server/src/main/core/game/container/Container.java index f0d512069..5cecb6905 100644 --- a/Server/src/main/core/game/container/Container.java +++ b/Server/src/main/core/game/container/Container.java @@ -8,7 +8,6 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.rs09.consts.Items; -import java.nio.ByteBuffer; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -221,7 +220,7 @@ public class Container { public boolean add(Item item, boolean fireListener, int preferredSlot) { item = item.copy(); int maximum = getMaximumAdd(item); - if (maximum == 0 || (item.getDefinition().isStackable() && item.getAmount() == 0)) { + if (maximum == 0) { return false; } if (preferredSlot > -1 && items[preferredSlot] != null) { @@ -560,30 +559,6 @@ public class Container { return -1; } - /** - * Parses the container data from the byte buffer. - * - * @param buffer The byte buffer. - * @return The total value of all items (G.E price > Store price > High - * alchemy price). - */ - public int parse(ByteBuffer buffer) { - int slot; - int total = 0; - while ((slot = buffer.getShort()) != -1) { - int id = buffer.getShort() & 0xFFFF; - int amount = buffer.getInt(); - int charge = buffer.getInt(); - if (id >= ItemDefinition.getDefinitions().size() || slot >= items.length || slot < 0) { - continue; - } - Item item = items[slot] = new Item(id, amount, charge); - item.setIndex(slot); - total += item.getValue(); - } - return total; - } - public void parse(JSONArray itemArray){ AtomicInteger total = new AtomicInteger(0); itemArray.forEach(item -> { @@ -601,30 +576,6 @@ public class Container { }); } - /** - * Saves the item data on the byte buffer. - * - * @param buffer The byte buffer. - * @return The total value of all items (G.E price > Store price > High - * alchemy price). - */ - public long save(ByteBuffer buffer) { - long totalValue = 0; - for (int i = 0; i < items.length; i++) { - Item item = items[i]; - if (item == null) { - continue; - } - buffer.putShort((short) i); - buffer.putShort((short) item.getId()); - buffer.putInt(item.getAmount()); - buffer.putInt(item.getCharge()); - totalValue += item.getValue(); - } - buffer.putShort((short) -1); - return totalValue; - } - /** * Copies the container to this container. * diff --git a/Server/src/main/core/game/container/impl/BankContainer.java b/Server/src/main/core/game/container/impl/BankContainer.java index 7c7bd1ddc..b27ecf700 100644 --- a/Server/src/main/core/game/container/impl/BankContainer.java +++ b/Server/src/main/core/game/container/impl/BankContainer.java @@ -1,12 +1,10 @@ package core.game.container.impl; -import core.api.IfaceSettingsBuilder; -import core.game.container.access.InterfaceContainer; -import kotlin.ranges.IntRange; -import org.rs09.consts.Vars; import core.ServerConstants; +import core.api.IfaceSettingsBuilder; import core.game.component.Component; import core.game.container.*; +import core.game.container.access.InterfaceContainer; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.IronmanMode; import core.game.node.item.Item; @@ -15,8 +13,8 @@ import core.game.world.GameWorld; import core.net.packet.PacketRepository; import core.net.packet.context.ContainerContext; import core.net.packet.out.ContainerPacket; - -import java.nio.ByteBuffer; +import kotlin.ranges.IntRange; +import org.rs09.consts.Vars; import static core.api.ContentAPIKt.*; @@ -129,15 +127,12 @@ public final class BankContainer extends Container { }); player.getInterfaceManager().openSingleTab(new Component(763)); super.refresh(); - player.getInventory().getListeners().add(listener); player.getInventory().refresh(); - setVarp(player, 1249, lastAmountX); + player.getInventory().getListeners().add(listener); + setVarp(player, 1249, lastAmountX); int settings = new IfaceSettingsBuilder().enableOptions(new IntRange(0, 5)).enableExamine().enableSlotSwitch().build(); player.getPacketDispatch().sendIfaceSettings(settings, 0, 763, 0, 27); - player.getPacketDispatch().sendRunScript(1451, ""); open = true; - setTabConfigurations(); - sendBankSpace(); } public void open(Player player) { @@ -155,38 +150,16 @@ public final class BankContainer extends Container { BankContainer.this.close(); return true; }); - refresh(listener); player.getInterfaceManager().openSingleTab(new Component(763)); - player.getInventory().getListeners().add(player.getBank().listener); + refresh(listener); player.getInventory().refresh(); - setVarp(player, 1249, lastAmountX); + player.getInventory().getListeners().add(player.getBank().listener); + setVarp(player, 1249, lastAmountX); player.getPacketDispatch().sendIfaceSettings(1278, 73, 762, 0, SIZE); int settings = new IfaceSettingsBuilder().enableOptions(new IntRange(0,5)).enableExamine().enableSlotSwitch().build(); player.getPacketDispatch().sendIfaceSettings(settings, 0, 763, 0, 27); player.getPacketDispatch().sendRunScript(1451, ""); open = true; - this.player.getBank().setTabConfigurations(player); - - } - - @Override - public long save(ByteBuffer buffer) { - buffer.putInt(lastAmountX); - buffer.put((byte) tabStartSlot.length); - for (int j : tabStartSlot) { - buffer.putShort((short) j); - } - return super.save(buffer); - } - - @Override - public int parse(ByteBuffer buffer) { - lastAmountX = buffer.getInt(); - int length = buffer.get() & 0xFF; - for (int i = 0; i < length; i++) { - tabStartSlot[i] = buffer.getShort(); - } - return super.parse(buffer); } /** @@ -225,14 +198,9 @@ public final class BankContainer extends Container { } item = new Item(item.getId(), amount, item.getCharge()); - boolean unnote = !item.getDefinition().isUnnoted(); + Item add = item.toUnnotedItem(); - Item add = unnote ? new Item(item.getDefinition().getNoteId(), amount, item.getCharge()) : item; - if (unnote && !add.getDefinition().isUnnoted()) { - add = item; - } - - int maxCount = super.getMaximumAdd(add); + int maxCount = getMaximumAdd(add); if (amount > maxCount) { add.setAmount(maxCount); item.setAmount(maxCount); @@ -242,7 +210,7 @@ public final class BankContainer extends Container { } } - if (player.getInventory().remove(item, slot, true)) { + if (player.getInventory().remove(item, slot, false)) { int preferredSlot = -1; if (tabIndex != 0 && tabIndex != 10 && !super.contains(add.getId(), 1)) { preferredSlot = tabStartSlot[tabIndex] + getItemsInTab(tabIndex); @@ -250,21 +218,9 @@ public final class BankContainer extends Container { increaseTabStartSlots(tabIndex); } super.add(add, true, preferredSlot); - setTabConfigurations(); + player.getInventory().update(); } } - - /** - * Re-opens the bank interface. - */ - public void reopen() { - if (!open) { - return; - } - player.getInterfaceManager().close(); - open(); - refresh(); - } /** * Takes a item from the bank container and adds one to the inventory @@ -300,17 +256,14 @@ public final class BankContainer extends Container { add = item; } if (super.remove(item, slot, false)) { - player.getInventory().add(add); + player.getInventory().add(add, false); } - int tabId = getTabByItemSlot(slot); if (get(slot) == null) { + int tabId = getTabByItemSlot(slot); decreaseTabStartSlots(tabId); - } - setTabConfigurations(); - shift(); - if (player.getAttribute("search", false)) { - reopen(); - } + shift(); + } else update(); + player.getInventory().update(); } /** @@ -319,7 +272,7 @@ public final class BankContainer extends Container { */ public void updateLastAmountX(int amount) { this.lastAmountX = amount; - setVarp(player, 1249, amount); + setVarp(player, 1249, amount); } /** @@ -386,8 +339,7 @@ public final class BankContainer extends Container { * Sends the bank space values on the interface. */ public void sendBankSpace() { - player.getPacketDispatch().sendString(Integer.toString(capacity() - freeSlots()), 762, 97); - player.getPacketDispatch().sendString(Integer.toString(capacity()), 762, 98); + setVarc(player, 192, capacity() - freeSlots()); } /** @@ -411,47 +363,17 @@ public final class BankContainer extends Container { replace(tempTabItems[i], slot, false); } refresh(); //We only refresh once. - setTabConfigurations(); } /** * Sets the tab configs. */ public void setTabConfigurations() { - int value = getItemsInTab(1); - value += getItemsInTab(2) << 10; - value += getItemsInTab(3) << 20; - setVarp(player, 1246, value); - value = getItemsInTab(4); - value += getItemsInTab(5) << 10; - value += getItemsInTab(6) << 20; - setVarp(player, 1247, value); - value = -2013265920; - value += (134217728 * (tabIndex == 10 ? 0 : tabIndex)); - value += getItemsInTab(7); - value += getItemsInTab(8) << 10; - setVarp(player, 1248, value); + for (int i = 0; i < 8; i++) { + setVarbit(player, 4885 + i, getItemsInTab(i + 1)); + } } - - /** - * Sets the tab configs. - */ - public void setTabConfigurations(Player player) { - int value = getItemsInTab(1); - value += getItemsInTab(2) << 10; - value += getItemsInTab(3) << 20; - setVarp(player, 1246, value); - value = getItemsInTab(4); - value += getItemsInTab(5) << 10; - value += getItemsInTab(6) << 20; - setVarp(player, 1247, value); - value = -2013265920; - value += (134217728 * (tabIndex == 10 ? 0 : tabIndex)); - value += getItemsInTab(7); - value += getItemsInTab(8) << 10; - setVarp(player, 1248, value); - } - + /** * Gets the amount of items in one tab. * @param tabId The tab index. @@ -483,7 +405,7 @@ public final class BankContainer extends Container { * @return If items have to be noted {@code true}. */ public boolean isNoteItems() { - return getVarbit(player, Vars.VARBIT_IFACE_BANK_NOTE_MODE) == 1; + return getVarbit(player, Vars.VARBIT_IFACE_BANK_NOTE_MODE) == 1; } /** @@ -491,7 +413,7 @@ public final class BankContainer extends Container { * @param noteItems If items have to be noted {@code true}. */ public void setNoteItems(boolean noteItems) { - setVarbit(player, Vars.VARBIT_IFACE_BANK_NOTE_MODE, noteItems ? 1 : 0, true); + setVarbit(player, Vars.VARBIT_IFACE_BANK_NOTE_MODE, noteItems ? 1 : 0, true); } /** @@ -515,14 +437,9 @@ public final class BankContainer extends Container { * @param tabIndex The tabIndex to set. */ public void setTabIndex(int tabIndex) { - this.tabIndex = tabIndex; - - /* - * Kludge to update the interface - * after dumping all to prevent - * "invisible" items in slots. - */ - update(true); + this.tabIndex = tabIndex == 0 ? 10 : tabIndex; + setVarbit(player, 4893, tabIndex + 1); + setAttribute(player, "bank:lasttab", tabIndex); } /** @@ -530,7 +447,7 @@ public final class BankContainer extends Container { * @param insertItems The insert items value. */ public void setInsertItems(boolean insertItems) { - setVarbit(player, Vars.VARBIT_IFACE_BANK_INSERT_MODE, insertItems ? 1 : 0, true); + setVarbit(player, Vars.VARBIT_IFACE_BANK_INSERT_MODE, insertItems ? 1 : 0, true); } /** @@ -538,7 +455,7 @@ public final class BankContainer extends Container { * @return {@code True} if inserting items mode is enabled. */ public boolean isInsertItems() { - return getVarbit(player, Vars.VARBIT_IFACE_BANK_INSERT_MODE) == 1; + return getVarbit(player, Vars.VARBIT_IFACE_BANK_INSERT_MODE) == 1; } /** @@ -549,6 +466,11 @@ public final class BankContainer extends Container { return open; } + @Override + public int getMaximumAdd(Item item) { + return super.getMaximumAdd(item.toUnnotedItem()); + } + /** * Listens to the bank container. * @author Emperor @@ -572,22 +494,22 @@ public final class BankContainer extends Container { public void update(Container c, ContainerEvent event) { if (c instanceof BankContainer) { PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 762, 64000, 95, event.getItems(), false, event.getSlots())); + player.getBank().setTabConfigurations(); + player.getBank().sendBankSpace(); } else { PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 763, 64000, 93, event.getItems(), false, event.getSlots())); } - player.getBank().setTabConfigurations(); - player.getBank().sendBankSpace(); } @Override public void refresh(Container c) { if (c instanceof BankContainer) { PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 762, 64000, 95, c.toArray(), c.capacity(), false)); + player.getBank().setTabConfigurations(); + player.getBank().sendBankSpace(); } else { PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 763, 64000, 93, c.toArray(), 28, false)); } - player.getBank().setTabConfigurations(); - player.getBank().sendBankSpace(); } } } diff --git a/Server/src/main/core/game/container/impl/EquipmentContainer.java b/Server/src/main/core/game/container/impl/EquipmentContainer.java index 8ecc54bf5..d398d9f3b 100644 --- a/Server/src/main/core/game/container/impl/EquipmentContainer.java +++ b/Server/src/main/core/game/container/impl/EquipmentContainer.java @@ -1,5 +1,6 @@ package core.game.container.impl; +import content.global.skill.skillcapeperks.SkillcapeEquipmentPlugin; import content.global.skill.skillcapeperks.SkillcapePerks; import core.game.container.Container; import core.game.container.ContainerEvent; @@ -16,6 +17,7 @@ import core.plugin.Plugin; import org.jetbrains.annotations.Nullable; import core.game.interaction.InteractionListeners; import core.game.system.config.ItemConfigParser; +import org.rs09.consts.Components; import java.util.ArrayList; @@ -210,7 +212,7 @@ public final class EquipmentContainer extends Container { for(Item currentItem : currentItems) { Plugin plugin = currentItem.getDefinition().getConfiguration("equipment", null); if (plugin != null) { - Object object = plugin.fireEvent("unequip", player, currentItem, newItem); + Object object = plugin.fireEvent("unequip", player, currentItem); if (object != null && !((Boolean) object)) { canContinue = false; break; @@ -275,6 +277,8 @@ public final class EquipmentContainer extends Container { updateDefenceAnimation = true; } else if (slot == EquipmentContainer.SLOT_SHIELD) { updateDefenceAnimation = true; + } else if (slot == EquipmentContainer.SLOT_CAPE) { + SkillcapeEquipmentPlugin.updateCapePerks(player, c, slot); } } if (updateDefenceAnimation) { @@ -303,11 +307,11 @@ public final class EquipmentContainer extends Container { player.removeAttribute("dfs_spec"); player.getProperties().getCombatPulse().setHandler(null); if (!player.getSettings().isSpecialToggled()) { - setVarp(player, 301, 0); + setVarp(player, 301, 0); } } player.getAppearance().setAnimations(); - player.updateAppearance(); + player.updateAppearance(); player.getSettings().updateWeight(); updateBonuses(player); } @@ -323,9 +327,6 @@ public final class EquipmentContainer extends Container { if (item != null) { int[] bonus = item.getDefinition().getConfiguration(ItemConfigParser.BONUS, new int[15]); for (int i = 0; i < bonus.length; i++) { - if (i == 14 && bonuses[i] != 0) { - continue; - } bonuses[i] += bonus[i]; } } @@ -352,7 +353,9 @@ public final class EquipmentContainer extends Container { bonuses[10] += increase; } player.getProperties().setBonuses(bonuses); - update(player); + if (player.getInterfaceManager().hasMainComponent(Components.EQUIP_SCREEN2_667)) { + update(player); + } } /** @@ -360,9 +363,6 @@ public final class EquipmentContainer extends Container { * @param player The player to update for. */ public static void update(Player player) { - if (!player.getInterfaceManager().hasMainComponent(667)) { - return; - } int index = 0; int[] bonuses = player.getProperties().getBonuses(); for (int i = 36; i < 50; i++) { @@ -373,6 +373,7 @@ public final class EquipmentContainer extends Container { String bonusValue = bonus > -1 ? ("+" + bonus) : Integer.toString(bonus); player.getPacketDispatch().sendString(BONUS_NAMES[index++] + bonusValue, 667, i); } + player.getSettings().updateWeight(); player.getPacketDispatch().sendString("Attack bonus", 667, 34); } } diff --git a/Server/src/main/core/game/dialogue/DialogueBuilder.kt b/Server/src/main/core/game/dialogue/DialogueBuilder.kt index 454ea29a5..5b1f542c5 100644 --- a/Server/src/main/core/game/dialogue/DialogueBuilder.kt +++ b/Server/src/main/core/game/dialogue/DialogueBuilder.kt @@ -1,11 +1,12 @@ package core.game.dialogue +import content.data.Quests import core.api.splitLines import core.game.node.entity.player.Player import core.tools.END_DIALOGUE import java.util.regex.Pattern -val DEBUG_DIALOGUE = true +val DEBUG_DIALOGUE = false val NUMBER_PATTERN1 = Pattern.compile("^(\\d+) \\[label", Pattern.MULTILINE) val NUMBER_PATTERN2 = Pattern.compile("(\\d+) -> (\\d+)") @@ -295,6 +296,14 @@ class DialogueBuilder(var target: DialogueBuilderFile, var clauseIndex: Int = -1 } } + /** + * The first if-statement to a dialogue. At minimum, you must have "b.onPredicate { _ -> true }" + * PLEASE BE CAREFUL ABOUT HAVING COMPLEX PREDICATE. + * If at any point during a dialogue that the predicate is not satisfied, + * it will block further dialogue progression and any dialogue will suddenly disappear. + * e.g. onPredicate(x==2) but during dialogue you set x=3, dialogue after it will disappear. + * Think of this as a repeated filter at every dialogue step. + */ fun onPredicate(predicate: (player: Player) -> Boolean): DialogueBuilder { target.data.add(DialogueClause(predicate, ArrayList())) clauseIndex = target.data.size - 1 @@ -303,7 +312,7 @@ class DialogueBuilder(var target: DialogueBuilderFile, var clauseIndex: Int = -1 fun defaultDialogue(): DialogueBuilder { return onPredicate({ _ -> return@onPredicate true}) } - fun onQuestStages(name: String, vararg stages: Int): DialogueBuilder { + fun onQuestStages(name: Quests, vararg stages: Int): DialogueBuilder { return onPredicate() { player -> val questStage = player.questRepository.getStage(name) return@onPredicate stages.contains(questStage) diff --git a/Server/src/main/core/game/dialogue/DialogueFile.kt b/Server/src/main/core/game/dialogue/DialogueFile.kt index 92beaf0a6..c73e3dbab 100644 --- a/Server/src/main/core/game/dialogue/DialogueFile.kt +++ b/Server/src/main/core/game/dialogue/DialogueFile.kt @@ -108,8 +108,8 @@ abstract class DialogueFile { interpreter!!.sendDialogues(entity, expression, *messages) } - open fun options(vararg options: String?) { - interpreter!!.sendOptions("Select an Option", *options) + open fun options(vararg options: String?, title: String = "Select an Option") { + interpreter!!.sendOptions(title, *options) } /** @@ -151,7 +151,7 @@ abstract class DialogueFile { player?.dialogueInterpreter?.sendDialogue(*messages) } - fun showTopics(vararg topics: Topic<*>): Boolean { + fun showTopics(vararg topics: Topic<*>, title: String = "Select an Option"): Boolean { val validTopics = ArrayList() topics.filter { if(it is IfTopic) it.showCondition else true }.forEach { topic -> interpreter!!.activeTopics.add(topic) @@ -161,7 +161,7 @@ abstract class DialogueFile { return true } else if (validTopics.size == 1) { - val topic = topics[0] + val topic = topics.filter { it.text == validTopics[0] }[0] if(topic.toStage is DialogueFile) { val topicFile = topic.toStage as DialogueFile interpreter!!.dialogue.loadFile(topicFile) @@ -172,7 +172,7 @@ abstract class DialogueFile { interpreter!!.activeTopics.clear() return false } - else { options(*validTopics.toTypedArray()) + else { options(*validTopics.toTypedArray(), title = title) return false } } diff --git a/Server/src/main/core/game/dialogue/DialogueInterpreter.java b/Server/src/main/core/game/dialogue/DialogueInterpreter.java index 06a93a303..ccc4a94c0 100644 --- a/Server/src/main/core/game/dialogue/DialogueInterpreter.java +++ b/Server/src/main/core/game/dialogue/DialogueInterpreter.java @@ -10,6 +10,7 @@ import core.game.node.entity.Entity; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.item.Item; +import core.game.world.GameWorld; import core.net.packet.PacketRepository; import core.net.packet.context.ChildPositionContext; import core.net.packet.context.ContainerContext; @@ -322,95 +323,91 @@ public final class DialogueInterpreter { /** * Send a message with an item next to it. - * @param itemId The item id. + * Accepts item IDs. */ public Component sendItemMessage(int itemId, String... messages) { - if(1 <= messages.length && messages.length < 4) { - ArrayList packedMessages = new ArrayList(); - for(int i = 0; i < messages.length/2; i++) { - packedMessages.add(messages[i] + "
" + messages[i+1]); - } - if(messages.length % 2 == 1) { - packedMessages.add(messages[messages.length-1]); - } - - int interfaceId = 241 + (packedMessages.size() - 1); - player.getInterfaceManager().openChatbox(interfaceId); - player.getPacketDispatch().sendItemOnInterface(itemId, 1, interfaceId, 1); - ItemDefinition itemDef = ItemDefinition.forId(itemId); - player.getPacketDispatch().sendAngleOnInterface(interfaceId, 1, itemDef.getModelZoom() / 2, itemDef.getModelRotationX(), itemDef.getModelRotationY()); - player.getPacketDispatch().sendString("", interfaceId, 3); - for(int i = 0; i < packedMessages.size(); i++) { - //System.out.printf("sendItemMessage[%d]: %s\n", i, packedMessages[i]); - player.getPacketDispatch().sendString(packedMessages.get(i), interfaceId, 4+i); - } - } else { - int interfaceId = 131; - //int interfaceId = 173; - //int interfaceId = 519; - //int interfaceId = 757; - //int interfaceId = 760; - player.getInterfaceManager().openChatbox(interfaceId); - String message = messages[0]; - for (int i = 1; i < messages.length; i++) { - message += "
" + messages[i]; - } - switch(interfaceId) { - case 131: - player.getPacketDispatch().sendString(message, 131, 1); - player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2); - break; - case 173: - player.getPacketDispatch().sendString(message, 173, 4); - player.getPacketDispatch().sendString("", 173, 3); - player.getPacketDispatch().sendItemOnInterface(itemId, 1, 173, 1); - break; - case 519: - player.getPacketDispatch().sendString(message, 519, 1); - player.getPacketDispatch().sendItemOnInterface(itemId, 1, 519, 0); - break; - case 757: - player.getPacketDispatch().sendString(message, 757, 2); - player.getPacketDispatch().sendString("", 757, 1); - player.getPacketDispatch().sendItemOnInterface(itemId, 1, 757, 0); - break; - case 760: - player.getPacketDispatch().sendString(message, 760, 0); - player.getPacketDispatch().sendItemOnInterface(itemId, 1, 760, 1); - break; - } - } - return player.getInterfaceManager().getChatbox(); + return sendItemMessage(new Item(itemId), messages); } /** * Send a message with an item next to it. + * Accepts Items. */ public Component sendItemMessage(final Item item, String... messages) { - return sendItemMessage(item.getId(), messages); - } - - /** - * Send a message with an item next to it. - * @param message The message. - */ - public Component sendDoubleItemMessage(int first, int second, String message) { - player.getInterfaceManager().openChatbox(131); - player.getPacketDispatch().sendString(message, 131, 1); - player.getPacketDispatch().sendItemOnInterface(first, 1, 131, 0); - player.getPacketDispatch().sendItemOnInterface(second, 1, 131, 2); + // Select interface based on number of messages - 241 (1 line) to 244 (4 lines) + int interfaceId = 240 + messages.length; + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, false); + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 2, false); + // Hide or empty the title, since double item messages do not have them. (Child 3) + player.getPacketDispatch().sendString("", interfaceId, 3); + // Loop and print messages on Child 4,5,6,7 based on messages count. + for(int i = 0; i < messages.length; i++) { + player.getPacketDispatch().sendString(messages[i], interfaceId, 4+i); + } + // Set the first Item (child 1) + ItemDefinition itemDef = ItemDefinition.forId(item.getId()); + player.getPacketDispatch().sendItemOnInterface(item.getId(), item.getAmount(), interfaceId, 2); + player.getPacketDispatch().sendAngleOnInterface(interfaceId, 2, itemDef.getModelZoom() / 2, itemDef.getModelRotationX(), itemDef.getModelRotationY()); + player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 2, 45, 45); + // Hide the second item which seems to be used for double items (child 1) + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, true); + // Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title) + player.getInterfaceManager().openChatbox(interfaceId); + // These are old interfaces which made no sense to use them. +// player.getPacketDispatch().sendString(message, 131, 1); +// player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2); +// player.getPacketDispatch().sendString(message, 173, 4); +// player.getPacketDispatch().sendString("", 173, 3); +// player.getPacketDispatch().sendItemOnInterface(itemId, 1, 173, 1); +// player.getPacketDispatch().sendString(message, 519, 1); +// player.getPacketDispatch().sendItemOnInterface(itemId, 1, 519, 0); +// player.getPacketDispatch().sendString(message, 757, 2); +// player.getPacketDispatch().sendString("", 757, 1); +// player.getPacketDispatch().sendItemOnInterface(itemId, 1, 757, 0); +// player.getPacketDispatch().sendString(message, 760, 0); +// player.getPacketDispatch().sendItemOnInterface(itemId, 1, 760, 1); return player.getInterfaceManager().getChatbox(); } /** - * Send a message with an item next to it. - * @param message The message. + * Send a message with two items next to it. + * Accepts item IDs. */ - public Component sendDoubleItemMessage(Item first, Item second, String message) { - player.getInterfaceManager().openChatbox(131); - player.getPacketDispatch().sendString(message, 131, 1); - player.getPacketDispatch().sendItemOnInterface(first.getId(), first.getAmount(), 131, 0); - player.getPacketDispatch().sendItemOnInterface(second.getId(), second.getAmount(), 131, 2); + public Component sendDoubleItemMessage(int first, int second, String... message) { + return sendDoubleItemMessage(new Item(first), new Item(second), message); + } + + /** + * Send a message with two items next to it. + * Accepts Items. + * Note that interface 241 to 244 contains 2 childs for images, which is used for sendDoubleItemMessage. + * @param first The first item to display. + * @param second The second item to display. + * @param messages The array of messages, one message per line. + */ + public Component sendDoubleItemMessage(Item first, Item second, String... messages) { + // Select interface based on number of messages - 241 (1 line) to 244 (4 lines) + int interfaceId = 240 + messages.length; + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, false); + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 2, false); + // Hide or empty the title, since double item messages do not have them. + player.getPacketDispatch().sendString("", interfaceId, 3); + // Loop and print messages on child 4,5,6,7 based on messages count. + for(int i = 0; i < messages.length; i++) { + player.getPacketDispatch().sendString(messages[i], interfaceId, 4+i); + } + // Set the first item + ItemDefinition itemDef = ItemDefinition.forId(first.getId()); + player.getPacketDispatch().sendItemOnInterface(first.getId(), first.getAmount(), interfaceId, 1); + player.getPacketDispatch().sendAngleOnInterface(interfaceId, 1, (int)(itemDef.getModelZoom() / 1.5), itemDef.getModelRotationX(), itemDef.getModelRotationY()); + player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 1, 40, 40); + // Set the second items + ItemDefinition itemDef2 = ItemDefinition.forId(second.getId()); + player.getPacketDispatch().sendItemOnInterface(second.getId(), second.getAmount(), interfaceId, 2); + player.getPacketDispatch().sendAngleOnInterface(interfaceId, 2, (int)(itemDef2.getModelZoom() / 1.5), itemDef2.getModelRotationX(), itemDef2.getModelRotationY()); + player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 2, 60, 65); + // Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title) + player.getInterfaceManager().openChatbox(interfaceId); return player.getInterfaceManager().getChatbox(); } @@ -433,7 +430,7 @@ public final class DialogueInterpreter { * @return The chatbox component. */ public Component sendDialogues(Entity entity, int expression, String... messages) { - return sendDialogues(entity instanceof Player ? -1 : ((NPC) entity).getShownNPC(player).getId(), expression, messages); + return sendDialogues(entity instanceof Player ? -1 : ((NPC) entity).getShownNPC(player).getId(), expression, false, messages); } /** @@ -441,12 +438,11 @@ public final class DialogueInterpreter { * @param npcId The npc id. * @param expression The entity's facial expression. * @param messages The messages. - * @param hide the continue. + * @param hide should the continue button be hidden? * @return The chatbox component. */ public Component sendDialogues(int npcId, FacialExpression expression, boolean hide, String... messages) { - sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages); - return player.getInterfaceManager().getChatbox(); + return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), hide, messages); } /** @@ -457,34 +453,18 @@ public final class DialogueInterpreter { * @return The chatbox component. */ public Component sendDialogues(Entity entity, FacialExpression expression, boolean hide, String... messages) { - sendDialogues(entity, expression, messages); - player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide); - return player.getInterfaceManager().getChatbox(); + return sendDialogues(entity.getId(), expression == null ? -1 : expression.getAnimationId(), hide, messages); } /** * Send dialogues based on the amount of specified messages. * @param expression The entity's facial expression. * @param messages The messages. - * @param hide the continue. + * @param hide should the continue button be hidden? * @return The chatbox component. */ public Component sendDialogues(Entity entity, int expression, boolean hide, String... messages) { - sendDialogues(entity, expression, messages); - player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide); - return player.getInterfaceManager().getChatbox(); - } - - /** - * Send dialogues based on the amount of specified messages. - * @param expression The entity's facial expression. - * @param messages The messages. - * @return The chatbox component. - */ - public Component sendDialogues(int npcId, int expression, boolean hide, String... messages) { - sendDialogues(npcId, expression, messages); - player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide); - return player.getInterfaceManager().getChatbox(); + return sendDialogues(entity.getId(), expression, hide, messages); } /** @@ -495,12 +475,13 @@ public final class DialogueInterpreter { * @return The chatbox component. */ public Component sendDialogues(int npcId, FacialExpression expression, String... messages) { - return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages); + return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(),false, messages); } static Pattern GENDERED_SUBSTITUTION = Pattern.compile("@g\\[([^,]*),([^\\]]*)\\]"); public static String doSubstitutions(Player player, String msg) { msg = msg.replace("@name", player.getUsername()); + msg = msg.replace("@servername", GameWorld.getSettings().getName()); StringBuilder sb = new StringBuilder(); Matcher m = GENDERED_SUBSTITUTION.matcher(msg); int index = player.isMale() ? 1 : 2; @@ -510,7 +491,6 @@ public final class DialogueInterpreter { m.appendTail(sb); return sb.toString(); } - /** * Send dialogues based on the amount of specified messages. * @param npcId The npc id. @@ -519,29 +499,49 @@ public final class DialogueInterpreter { * @return The chatbox component. */ public Component sendDialogues(int npcId, int expression, String... messages) { + return sendDialogues(npcId, expression, false, messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param npcId The npc id. + * @param expression The entity's facial expression. + * @param messages The messages. + * @param hide should the continue button be hidden? + * @return The chatbox component. + */ + public Component sendDialogues(int npcId, int expression, boolean hide, String... messages) { if (messages.length < 1 || messages.length > 4) { System.err.println("Invalid amount of messages: " + messages.length); return null; } boolean npc = npcId > -1; int interfaceId = (npc ? 240 : 63) + messages.length; + interfaceId += hide ? 4 : 0; if (expression == -1) { expression = FacialExpression.HALF_GUILTY.getAnimationId(); } + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, true); + player.getPacketDispatch().sendInterfaceConfig(interfaceId, 2, false); player.getPacketDispatch().sendAnimationInterface(expression, interfaceId, 2); if (npc) { player.getPacketDispatch().sendItemOnInterface(-1, 1, interfaceId, 1); + player.getPacketDispatch().sendItemOnInterface(-1, 1, interfaceId, 2); player.getPacketDispatch().sendNpcOnInterface(npcId, interfaceId, 2); + player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 2, 45, 45); + player.getPacketDispatch().sendAngleOnInterface(interfaceId, 2, 2150, 40, 1882); player.getPacketDispatch().sendString(NPCDefinition.forId(npcId).getName(), interfaceId, 3); } else { + player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 2, 426, 45); // 423 is 47 * 9 player.getPacketDispatch().sendPlayerOnInterface(interfaceId, 2); player.getPacketDispatch().sendString(player.getUsername(), interfaceId, 3); } for (int i = 0; i < messages.length; i++) { - player.getPacketDispatch().sendString(doSubstitutions(player, messages[i].toString()), interfaceId, (i + 4)); + player.getPacketDispatch().sendString(doSubstitutions(player, messages[i]), interfaceId, (i + 4)); } - player.getInterfaceManager().openChatbox(interfaceId); player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, false); + // Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title) + player.getInterfaceManager().openChatbox(interfaceId); return player.getInterfaceManager().getChatbox(); } @@ -561,6 +561,7 @@ public final class DialogueInterpreter { for (int i = 0; i < options.length; i++) { player.getPacketDispatch().sendString(options[i].toString(), interfaceId, i + 2); } + // Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title) player.getInterfaceManager().openChatbox(interfaceId); return player.getInterfaceManager().getChatbox(); } diff --git a/Server/src/main/core/game/dialogue/DialogueLabeller.kt b/Server/src/main/core/game/dialogue/DialogueLabeller.kt new file mode 100644 index 000000000..1d39ce22b --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueLabeller.kt @@ -0,0 +1,398 @@ +package core.game.dialogue + +import core.api.Event +import core.api.InputType +import core.api.face +import core.api.openDialogue +import core.api.splitLines +import core.game.component.Component +import core.game.component.Component.setUnclosable +import core.game.event.DialogueCloseEvent +import core.game.event.EventHook +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item + +/** Alias FacialExpression to ChatAnim for compatibility. */ +typealias ChatAnim = FacialExpression +/** Alias InputType to InputType for compatibility. */ +typealias InputType = InputType +/** Create container class DialogueOption for [DialogueLabeller.options] */ +class DialogueOption( + val goto: String, // Required: Label to go to if player selects option. + val option: String, // Required: Printed text on the option list. + val spokenText: String = option, // Optional: Option selected will be spoken text unless provided here. + val expression: ChatAnim = ChatAnim.NEUTRAL, // Optional: Player expression to show. + val skipPlayer: Boolean = false, // Optional: Skips the player spoken text (if wildly different) + val optionIf: ((player: Player, npc: NPC) -> Boolean)? = null // Optional: Function to show/not show option. +) + +/** + * DialogueLabeller is another way to organize a dialogue file. + * It shares the same dialogue layout as another project for portability. + * - Uses [stage] is for the current loop and [super.stage] as the "next" stage + * - Have [dialogueCounter] assign stages and guards for each option/player/npc dialogue + * - Assign [exec] and [goto] the same [dialogueCounter] to execute all in one pass + * - Save [label] to a HashMap to refer to when using [goto] + * - Loops again when a [goto] is encountered, ends when no [stageHit] during a stage + * + * ! WARNING: DO NOT use functions in DialogueFile as it will cause unexpected behavior. + * + * ! HELP: There are snippets below that you can copy and modify to use as part of your code. + */ +abstract class DialogueLabeller : DialogueFile() { + + companion object { + /** + * Makes NPC stop in its tracks and look at player. + * An alternative to setting up DialoguePlugin(player) to be used in InteractionListener. + */ + fun open(player: Player, dialogue: Any, npc: NPC) { + face(npc, player.location) + npc.setDialoguePlayer(player) // This prevents random walking in [NPC.java handleTickActions()] + npc.getWalkingQueue().reset() + npc.getPulseManager().clear() + openDialogue(player, dialogue, npc) + } + } + + /** Maps labels to stage numbers, to make jumps. */ + val labelStageMap = HashMap () + /** Assigns the number to each dialogue line. */ + var dialogueCounter = 0 + /** Set [stage] to start off (1 when there is an initial label). */ + var startingStage: Int? = null + /** Keeps the current stage for the whole cycle. */ + override var stage = -1 + /** Assigns the number to each stage. */ + var stageHit = false + /** Jump to next stage number when hitting a goto. */ + var jumpTo: Int? = null + /** ButtonID on every click */ + var buttonID: Int? = null + /** Filtered options from option stage 1 for storing the order for option stage 2 and 3 */ + var filteredOptions: List = listOf() + /** ButtonID when user clicks on an option */ + var optButton: Int? = null + /** Input value after a user enters a value */ + var optInput: Any? = null + + /** Implement this function instead of overriding handle. */ + abstract fun addConversation() + + /** Helper functions to create an individual stage for each of the dialogue stages. */ + private fun assignIndividualStage(unclosable: Boolean = false, callback: () -> Component?) { + if (startingStage == null) { startingStage = 0 } + if (stage == dialogueCounter && jumpTo == null) { // Run this stage when the stage equals to the dialogueCounter of this dialogue + val component = callback() // CALLBACK FUNCTION + if (unclosable && component != null) { + setUnclosable(player, component) + } + super.stage++ // Increment the stage to the next stage (only applies after a pass) + stageHit = true // Flag that the stage was hit, so that it doesn't close the dialogue + } + dialogueCounter++ // Increment the dialogueCounter to assign each line of dialogue + } + + /** Formats a vararg messages or falls back to message to an array for spread function. */ + private fun formatMessages(messages: Array?, message: String = ""): Array { + return if (messages == null || messages.isEmpty()) { + splitLines(message) + } else if (messages.size > 1) { + messages + } else { + splitLines(messages[0]) // A single line message is similar to a splitLine returning 1 line. + } + } + + /** Does absolutely nothing but to make it look like the other API. */ + fun assignToIds(npcid: Int) { /* super.npc = NPC(npcid) */ } + + /** Marks the start of a series of dialogue that can be jumped to using a [goto]. You can nest after label(...) with a {} purely for organization only. */ + fun label(vararg label: String, nesting: () -> Unit = {}) { + if (startingStage == null) { startingStage = 1 } + dialogueCounter++ + for (l in label) { labelStageMap[l] = dialogueCounter } + nesting() + } + + /** Jumps to a [label] after a series of dialogue. */ + fun goto(label: String) { + if (stage == dialogueCounter && jumpTo == null) { + jumpTo = labelStageMap[label] + } + } + + /** Jumps to a [label] inside an [exec]. */ + fun loadLabel(player: Player, label: String) { + goto(label) + } + + /** + * Executes the callback between stages and can be used for branching with [loadLabel]. + * You can chain as many exec as you like since they read sequentially. + * You can also read [options] and [input] values here via [optButton] and [optInput]. + */ + fun exec(callback: (player: Player, npc: NPC) -> Unit) { + if (startingStage == null) { startingStage = 0 } + if (stage == dialogueCounter && jumpTo == null) { + callback(player!!, npc!!) + } + } + + /** Manual stage. For custom creation of an individual stage. Must call interpreter in some form. **/ + fun manual(unclosable: Boolean = false, callback: (player: Player, npc: NPC) -> Component?) { + assignIndividualStage(unclosable) { return@assignIndividualStage callback(player!!, npc!!) } + } + + /** Dialogue player/playerl. Shows player chathead with text. **/ + fun player(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String, unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendDialogues(player, chatAnim, *formatMessages(messages)) } + } + /** Dialogue player/playerl. Shows player chathead with text. **/ + fun player(vararg messages: String) { player(ChatAnim.NEUTRAL, *messages) } + @Deprecated("Use player() instead.", ReplaceWith("player(chatAnim, *messages)")) + fun playerl(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use player() instead.") } + @Deprecated("Use player() instead.", ReplaceWith("player(*messages)")) + fun playerl(vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use player() instead.") } + + /** Dialogue npc/npcl. Shows npc chathead with text. **/ + fun npc(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String, unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendDialogues(npc, chatAnim, *formatMessages(messages)) } + } + /** Dialogue npc/npcl. Shows npcId chathead with text. **/ + fun npc(chatAnim: ChatAnim = ChatAnim.NEUTRAL, npcId: Int = npc!!.id, vararg messages: String, unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendDialogues(NPC(npcId), chatAnim, *formatMessages(messages)) } + } + /** Dialogue npc/npcl. Shows npcId chathead with text. **/ + fun npc(npcId: Int = npc!!.id, vararg messages: String, unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendDialogues(NPC(npcId), ChatAnim.NEUTRAL, *formatMessages(messages)) } + } + /** Dialogue npc/npcl. Shows npc chathead with text. **/ + fun npc(vararg messages: String) { npc(ChatAnim.NEUTRAL, *messages) } + @Deprecated("Use npc() instead.", ReplaceWith("npc(chatAnim, *messages)")) + fun npcl(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use npc() instead.") } + @Deprecated("Use npc() instead.", ReplaceWith("npc(*messages)")) + fun npcl(vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use npc() instead.") } + + /** Dialogue item/iteml. Shows item with text. **/ + fun item(item: Item, vararg messages: String, message: String = "", unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendItemMessage(item, *formatMessages(messages, message)) } + } + @Deprecated("Use item() instead.", ReplaceWith("item(item, *messages)")) + fun iteml(item: Item, vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use item() instead.") } + + /** Dialogue overloaded doubleItem/doubleIteml. Shows two items with text. **/ + fun item(item: Item, item2: Item, vararg messages: String, message: String = "", unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendDoubleItemMessage(item, item2, *formatMessages(messages, message)) } + } + + /** Dialogue line/linel. Simply shows text. **/ + fun line(vararg messages: String, unclosable: Boolean = false) { + assignIndividualStage(unclosable) { return@assignIndividualStage interpreter!!.sendDialogue(*messages) } + } + @Deprecated("Use line() instead.", ReplaceWith("line(*messages)")) + fun linel(vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use line() instead.") } + + /** Dialogue option. Shows the option dialogue with choices for the user to select. **/ + fun options(vararg options: DialogueOption, title: String = "Select an Option", unclosable: Boolean = false) { + // Filter out options that aren't shown. + // Stage Part 1: Options List Dialogue + assignIndividualStage(unclosable) { + filteredOptions = options.filter{ if (it.optionIf != null) { it.optionIf.invoke(player!!, npc!!) } else { true } } + if (filteredOptions.size == 1) { // If there is only one option left, jump to that option. + jumpTo = labelStageMap[filteredOptions[0].goto] + return@assignIndividualStage null + } + return@assignIndividualStage interpreter!!.sendOptions(title, *filteredOptions.map{ it.option }.toTypedArray()) + } + // Stage Part 2: Show spoken text. + val opt = if (buttonID != null && buttonID in 1..filteredOptions.size) { filteredOptions[buttonID!! - 1] } else { null } + assignIndividualStage(unclosable) { + var component: Component? = null + if (opt?.skipPlayer == true) { + jumpTo = stage + 1 + } else { + component = interpreter!!.sendDialogues(player, opt?.expression ?: ChatAnim.NEUTRAL, *(splitLines(opt?.spokenText ?: " "))) + } + optButton = buttonID // transfer the buttonID to a temp memory for the next stage + return@assignIndividualStage component + } + // Stage Part 3: Jump To goto + if (stage == dialogueCounter && optButton != null && optButton in 1..filteredOptions.size) { + jumpTo = labelStageMap[filteredOptions[optButton!! - 1].goto] + } + dialogueCounter++ + } + @Deprecated("Use options(DialogueOption()) and not options(string).", ReplaceWith("options(DialogueOption(options))")) + override fun options(vararg options: String?, title: String) { throw Exception("Deprecated DialogueLabel: Use options(DialogueOption()) and not options(string).") } + + /** Dialogue input. Shows the input dialogue with an input box for the user to type in. Read [optInput] for the value. **/ + fun input(type: InputType, prompt: String = "Enter the amount") { + assignIndividualStage { + // These are similar to calling sendInputDialogue + when (type) { + InputType.AMOUNT -> interpreter!!.sendInput(true, prompt) + InputType.NUMERIC -> interpreter!!.sendInput(false, prompt) + InputType.STRING_SHORT -> interpreter!!.sendInput(true, prompt) // Only 12 letters + InputType.STRING_LONG -> interpreter!!.sendLongInput(prompt) // Very long text, can overflow. + InputType.MESSAGE -> interpreter!!.sendMessageInput(prompt) + } + if (type == InputType.AMOUNT) { + player!!.setAttribute("parseamount", true) + } + // This runscript is the same runscript as the one in ContentAPI sendInputDialogue + player!!.setAttribute("runscript") { value: Any -> + optInput = value + // The next line is a hack. Because this prompt overlays the actual chat box, we trigger the next dialogue with a call to handle. + interpreter!!.handle(player!!.interfaceManager.chatbox.id, 2) + } + player!!.setAttribute("input-type", type) + return@assignIndividualStage null + } + } + /** Dialogue input. Shows the input dialogue with an input box for the user to type in. Read [optInput] in an [exec] function for the value. **/ + fun input(numeric: Boolean, prompt: String = "Enter the amount") { input( if (numeric) { InputType.NUMERIC } else { InputType.STRING_SHORT }, prompt) } + + /** Runs arbitrary code when the dialogue closes, once. **/ + fun afterClose(callback: (player: Player) -> Unit) { + val hook = object : EventHook { + override fun process(entity: Entity, event: DialogueCloseEvent) { + val you = entity as Player + you.unhook(this) + callback(you) + } + } + player!!.hook(Event.DialogueClosed, hook) + } + + /** Calls another dialogue file. Always use this to open another dialogue file instead of calling openDialogue() in exec{} due to interfaces clashing. **/ + fun open(player: Player, dialogue: Any, vararg args: Any) { + assignIndividualStage { + core.api.openDialogue(player, dialogue, *args) + return@assignIndividualStage null + } + } + + /** WARNING: DIALOGUE LABELLER WILL BREAK IN CERTAIN FUNCTIONS. USE open() instead. */ + fun openDialogue(player: Player, dialogue: Any, vararg args: Any) { + core.api.openDialogue(player, dialogue, *args) + } + + /** Hook onto the handle function of DialogueFile. This function gets called every loop with a super.stage. */ + override fun handle(componentID: Int, buttonID: Int) { + this.buttonID = buttonID + startingStage = null + /** This -1 stage is to read labels into a hashmap and to find the starting stage. */ + if (stage == -1) { + dialogueCounter = 0 + addConversation() // Force all labels to be recorded into hashmap. + super.stage = startingStage ?: 0 + } + for (i in 0..10) { // Limit to 10 jumpTo PER DIALOGUE LINE to prevent infinite looping/ping-ponging jumps. + if (jumpTo != null) { // If jumpTo is set, set the super.stage stage as the new jumpTo stage. + super.stage = jumpTo as Int + jumpTo = null + } + stageHit = false + stage = super.stage // [stage] is for the current loop. [super.stage] is treated as the "next" stage. + dialogueCounter = 0 + addConversation() // MAIN CALLBACK FUNCTION + // If there is no jumpTo set, or jumpTo is set to the same stage as this(infinite loop), exit. + if (jumpTo == null || jumpTo == stage) { + break + } + } + // If a dialogue stage is not hit, end the dialogue. + if (!stageHit) { + end() + } + } +} + +/* +// COPY PASTA SNIPPETS SECTION FOR QUICK BOILERPLATES + +// STANDARD: Initializing with DialoguePlugin. +@Initializable +class DonieDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return DonieDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DonieDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DONIE_2238) + } +} +class DonieDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.DONIE_2238) + + npc(ChatAnim.FRIENDLY, "Hello there, can I help you?") + goto("nowhere") + } +} + +// NEW! (EXPERIMENTAL): Initializing with InteractionListener. +class SomeDudeDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.PRIEST_OF_GUTHIX_8555, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, SomeDudeDialogueLabellerFile(), node as NPC) + return@on true + } + } +} + +// Exec with quest stage branches. +exec { player, npc -> + when(getQuestStage(player, SomeQuest.questName)) { + 100 -> loadLabel(player, "SomeQuestStage100") + 10, 20 -> loadLabel(player, "SomeQuestStage10") + else -> { + loadLabel(player, "SomeQuestStage0") + } + } +} + +// Exec to move quest stage up. +exec { player, npc -> + if (getQuestStage(player, SomeQuest.questName) == 0) { + setQuestStage(player, SomeQuest.questName, 10) + } +} + +// Exec to add item, set attribute. +exec { player, npc -> + if (removeItem(player, Items.ITEM_1)) { + addItemOrDrop(player, Items.ITEM_2) + } + if (getAttribute(player, attributeSomething, null) == null) { + setAttribute(player, attributeSomething, player.location) + } +} + +// Open to another dialogue file. +npc("I'm going to another file.") +open(player!!, SomeDialogueFile2(), npc!!) +... +class SomeDialogueFile2 : DialogueLabeller() { + override fun addConversation() { + npc("This is another file.") + } +} + +// Options with all the different controls. +options( + DialogueOption("Label1", "Line 1 Say", expression=ChatAnim.THINKING), + DialogueOption("Label2", "Line 2 Huh", skipPlayer=true), + DialogueOption("Label3", "Line 3 Blah", spokenText="I say something else", expression=ChatAnim.FRIENDLY), + DialogueOption("Label4", "Line 4 What") { player, npc -> + return@DialogueOption false // Don't show + } +) + +*/ \ No newline at end of file diff --git a/Server/src/main/core/game/dialogue/DialoguePlugin.java b/Server/src/main/core/game/dialogue/DialoguePlugin.java index 635b41c2b..18d17dd37 100644 --- a/Server/src/main/core/game/dialogue/DialoguePlugin.java +++ b/Server/src/main/core/game/dialogue/DialoguePlugin.java @@ -276,8 +276,8 @@ public abstract class DialoguePlugin implements Plugin { * Method used to send options. * @param options the options. */ - public void options(final String... options) { - interpreter.sendOptions("Select an Option", options); + public Component options(final String... options) { + return interpreter.sendOptions("Select an Option", options); } /** diff --git a/Server/src/main/core/game/dialogue/FacialExpression.java b/Server/src/main/core/game/dialogue/FacialExpression.java index e3011a5a3..8b4f2eb8c 100644 --- a/Server/src/main/core/game/dialogue/FacialExpression.java +++ b/Server/src/main/core/game/dialogue/FacialExpression.java @@ -90,6 +90,9 @@ public enum FacialExpression { //9855-9857 are like disgusted? does it just repeat after this? //Child Chathead? + CHILD_ANGRY(7168), + CHILD_SIDE_EYE(7169), + CHILD_RECALLING(7170), CHILD_EVIL_LAUGH(7171), CHILD_FRIENDLY(7172), CHILD_NORMAL(7173), @@ -98,9 +101,37 @@ public enum FacialExpression { CHILD_THINKING(7176), CHILD_SAD(7177), CHILD_GUILTY(7178), - CHILD_SUSPICIOUS(7179); //TODO: More? + CHILD_SUSPICIOUS(7179), + CHILD_SURPRISED(7180), + + //Familiar Chatheads + GRAAHK_NOD(6551), + GHRAAK_SHAKE_MILD(6553), + GHRAAK_SHAKE_VIGOROUS(6555), + ; //TODO: More? + + /* + * From some sources: here's a potential list of chatheads. + * // 667 + * Chat animation group: 1540; linked animations: [7, 8, 9, 6824] + * Chat animation group: 1489; potentially all familiars; linked animations: [225, 6550, 6551, 6552, 6553, 6555, 8372, 8373, 8374, 8375, 8581, 8582, 9178, 9179, 9180, 9181, 9183, 9187, 9189, 9190, 9192, 9202] + * Chat animation group: 82; linked animations: [554, 555, 556, 557, 562, 563, 564, 565, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 610, 611, 612, 613, 614, 615, 616, 617] + * Chat animation group: 84; linked animations: [558, 559, 560, 561] + * Chat animation group: 80; linked animations: [584, 585, 586, 587] + * Chat animation group: 78; linked animations: [3874] + * Chat animation group: 77; linked animations: [4119, 4120, 4121, 4122] + * Chat animation group: 1124; linked animations: [4843, 4844, 4845, 4846, 8388, 8389, 8390, 8391, 8392, 8393, 8394, 8403, 8404, 8405, 8406, 8898, 8899, 8900] + * Chat animation group: 1309; linked animations: [5661, 5662, 5663, 5665] + * Chat animation group: 1421; linked animations: [6244, 6245, 6246, 7636, 7637, 7638, 7639, 8380, 8381, 8382, 8383, 8475, 8476, 8477, 8478] + * Chat animation group: 1627; linked animations: [7168, 7169, 7170, 7171, 7172, 7173, 7176, 7177, 7178, 7179, 7180, 8824] + * Chat animation group: 1698; linked animations: [7539, 7540, 7541, 7542, 8447, 8448, 8449, 8450] + * Chat animation group: 1885; linked animations: [8395, 8396, 8397, 8398] + * Chat animation group: 1882; linked animations: [8411, 8412, 8413, 8414] + * Chat animation group: 1887; linked animations: [8443, 8444, 8445, 8446, 9315, 9316, 9317, 9318, 9319] + * Chat animation group: 1906; linked animations: [8579, 8580, 8583, 8584, 8585, 8656, 8657, 8659, 8660, 8661, 8662] + */ /** * The animation id. diff --git a/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt b/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt index 58e692b23..acc07905c 100644 --- a/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt +++ b/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt @@ -19,25 +19,11 @@ open class SkillDialogueHandler( /** * Represents the skill dialogue type. */ - val type: SkillDialogue?, vararg data: Any) { - /** - * Gets the player. - * @return The player. - */ - - /** - * Gets the type. - * @return The type. - */ - - /** - * Gets the passed data. - * @return the data. - */ - /** - * Represents the object data passed through. - */ - val data: Array + val type: SkillDialogue?, + /** + * The items that can be created through this dialog. + */ + vararg val items: Item) { /** * Method used to open a skill dialogue. @@ -70,7 +56,7 @@ open class SkillDialogueHandler( * @return the amount. */ open fun getAll(index: Int): Int { - return player.inventory.getAmount(data[0] as Item) + return player.inventory.getAmount(items[0]) } /** @@ -107,7 +93,7 @@ open class SkillDialogueHandler( private val length: Int) { ONE_OPTION(309, 5, 1) { override fun display(player: Player, handler: SkillDialogueHandler) { - val item = handler.data[0] as Item + val item = handler.items[0] player.packetDispatch.sendString("



" + item.name, 309, 6) player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 309, 2) PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 6, 60, 20)) @@ -125,7 +111,7 @@ open class SkillDialogueHandler( }, MAKE_SET_ONE_OPTION(582, 4, 1) { override fun display(player: Player, handler: SkillDialogueHandler) { - val item = handler.data[0] as Item + val item = handler.items[0] // Send item + item name to interface player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 582, 2) @@ -163,8 +149,8 @@ open class SkillDialogueHandler( override fun display(player: Player, handler: SkillDialogueHandler) { var item: Item player.interfaceManager.openChatbox(306) - for (i in handler.data.indices) { - item = handler.data[i] as Item + for (i in handler.items.indices) { + item = handler.items[i] player.packetDispatch.sendString("



" + handler.getName(item), 303, 7 + i) player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 303, 2 + i) } @@ -190,11 +176,11 @@ open class SkillDialogueHandler( }, THREE_OPTION(304, 8, 3) { override fun display(player: Player, handler: SkillDialogueHandler) { - var item: Item? = null + var item: Item? for (i in 0..2) { - item = handler.data[i] as Item + item = handler.items[i] player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 304, 2 + i) - player.packetDispatch.sendString("



" + item!!.name, 304, 304 - 296 + i * 4) + player.packetDispatch.sendString("



" + item.name, 304, 304 - 296 + i * 4) } } @@ -219,10 +205,10 @@ open class SkillDialogueHandler( }, FOUR_OPTION(305, 9, 4) { override fun display(player: Player, handler: SkillDialogueHandler) { - var item: Item? = null + var item: Item? for (i in 0..3) { - item = handler.data[i] as Item - player.packetDispatch.sendItemZoomOnInterface(item!!.id, 135, 305, 2 + i) + item = handler.items[i] + player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 305, 2 + i) player.packetDispatch.sendString("



" + item.name, 305, 305 - 296 + i * 4) } } @@ -255,8 +241,8 @@ open class SkillDialogueHandler( override fun display(player: Player, handler: SkillDialogueHandler) { var item: Item player.interfaceManager.openChatbox(306) - for (i in handler.data.indices) { - item = handler.data[i] as Item + for (i in handler.items.indices) { + item = handler.items[i] player.packetDispatch.sendString("



" + handler.getName(item), 306, 10 + 4 * i) player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 306, 2 + i) PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 306, 2 + i, positions[i][0], positions[i][1])) @@ -361,14 +347,4 @@ open class SkillDialogueHandler( */ const val SKILL_DIALOGUE = 3 shl 16 } - - /** - * Constructs a new `SkillDialogueHandler` `Object`. - * @param player the player. - * @param type the type. - * @param data the data. - */ - init { - this.data = data as Array - } } \ No newline at end of file diff --git a/Server/src/main/core/game/diary/DiaryEventHookBase.kt b/Server/src/main/core/game/diary/DiaryEventHookBase.kt index 4fb85b0cd..692759fd9 100644 --- a/Server/src/main/core/game/diary/DiaryEventHookBase.kt +++ b/Server/src/main/core/game/diary/DiaryEventHookBase.kt @@ -180,16 +180,7 @@ abstract class DiaryEventHookBase(private val diaryType: DiaryType) : MapArea, L ) } - private fun findIndexFor(level: DiaryLevel): Int { - val levelName = level.name.lowercase().replaceFirstChar { c -> c.uppercase() } - val levelIndex = diaryType.levelNames.indexOf(levelName) - - if (levelIndex < 0) { - throw IllegalArgumentException("'$levelName' was not found in diary '$diaryType'.") - } - - return levelIndex - } + private fun findIndexFor(level: DiaryLevel): Int = getDiaryLevelIndex(diaryType, level) protected open fun onAreaVisited(player: Player) { areaTasks.forEach { diff --git a/Server/src/main/core/game/event/Events.kt b/Server/src/main/core/game/event/Events.kt index 900b41629..b11d6241b 100644 --- a/Server/src/main/core/game/event/Events.kt +++ b/Server/src/main/core/game/event/Events.kt @@ -6,6 +6,7 @@ import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.player.link.SpellBookManager.SpellbookChangeSource import core.game.node.entity.player.link.TeleportManager.TeleportType import core.game.node.entity.player.link.prayer.PrayerType import core.game.node.item.Item @@ -34,6 +35,7 @@ data class InterfaceCloseEvent(val component: Component) : Event data class AttributeSetEvent(val entity: Entity, val attribute: String, val value: Any) : Event data class AttributeRemoveEvent(val entity: Entity, val attribute: String) : Event data class SpellCastEvent(val spellBook: SpellBook, val spellId: Int, val target: Node? = null) : Event +data class SpellbookChangeEvent(val oldSpellBook: SpellBook, val newSpellBook: SpellBook, val source: SpellbookChangeSource) : Event data class ItemAlchemizationEvent(val itemId: Int, val isHigh: Boolean) : Event data class ItemEquipEvent(val itemId: Int, val slotId: Int) : Event data class ItemUnequipEvent(val itemId: Int, val slotId: Int) : Event diff --git a/Server/src/main/core/game/ge/GrandExchange.kt b/Server/src/main/core/game/ge/GrandExchange.kt index 5b763bf71..4472ed2f1 100644 --- a/Server/src/main/core/game/ge/GrandExchange.kt +++ b/Server/src/main/core/game/ge/GrandExchange.kt @@ -6,14 +6,11 @@ import core.cache.def.impl.ItemDefinition import core.game.node.entity.player.Player import core.game.node.entity.player.info.PlayerDetails import core.game.system.command.Privilege -import core.game.system.config.ItemConfigParser import core.game.system.task.Pulse import core.game.world.GameWorld import core.game.world.repository.Repository import core.tools.Log import core.tools.SystemLogger -import core.tools.colorize -import org.rs09.consts.Sounds import java.lang.Integer.max import java.util.concurrent.LinkedBlockingDeque @@ -83,31 +80,24 @@ class GrandExchange : StartupListener, Commands { } override fun defineCommands() { - define("addbotoffer", Privilege.ADMIN) {player, strings -> + define("addbotoffer", Privilege.ADMIN, "::addbotoffer item-id amount", "Adds a GE bot sell offer for the given item ID and amount.") {player, strings -> val id = strings[1].toInt() val amount = strings[2].toInt() addBotOffer(id, amount) notify(player, "Added ${amount}x ${getItemName(id)} to the bot offers.") } - define("bange", Privilege.ADMIN) {player, strings -> + define("bange", Privilege.ADMIN, "::bange item-id", "Bans/blacklists the specified item from GE trades.") {player, strings -> val id = strings[1].toInt() PriceIndex.banItem(id) notify(player, "Banned ${getItemName(id)} from GE trade.") } - define("allowge", Privilege.ADMIN) {player, strings -> + define("allowge", Privilege.ADMIN, "::allowge item-id", "Allows/whitelists the specified item to be traded on the GE.") {player, strings -> val id = strings[1].toInt() PriceIndex.allowItem(id) notify(player, "Allowed ${getItemName(id)} for GE trade.") } - - define("geprivacy", Privilege.STANDARD) {player, _ -> - val current = getAttribute(player, "ge-exclude", false) - val new = !current - notify(player, "Your name is now ${if (new) colorize("%RHIDDEN") else colorize("%RSHOWN")}.") - setAttribute(player, "/save:ge-exclude", new) - } } companion object { @@ -131,15 +121,11 @@ class GrandExchange : StartupListener, Commands { @JvmStatic fun getRecommendedPrice(itemID: Int, from_bot: Boolean = false): Int { - var base = max(PriceIndex.getValue(itemID), getItemDefPrice(itemID)) + var base = PriceIndex.getValue(itemID) if (from_bot) base = (max(BotPrices.getPrice(itemID), base) * 1.10).toInt() return base } - private fun getItemDefPrice(itemID: Int): Int { - return max(itemDefinition(itemID).getConfiguration(ItemConfigParser.GE_PRICE) ?: 0, itemDefinition(itemID).value) - } - @JvmStatic fun getOfferStats(itemID: Int, sale: Boolean) : String { @@ -235,8 +221,9 @@ class GrandExchange : StartupListener, Commands { //GrandExchangeRecords.getInstance(player).update(offer) if (offer.sell && !player.isArtificial) { - val username = if (getAttribute(player, "ge-exclude", false)) "?????" else player.username - Repository.sendNews(username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.") + Repository.sendGrandExchangeNews( + player.username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE." + ) } if (ServerConstants.I_AM_A_CHEATER) { @@ -278,9 +265,6 @@ class GrandExchange : StartupListener, Commands { seller.completedAmount += amount buyer.completedAmount += amount - if(seller.amountLeft < 1 && seller.player != null) - playAudio(seller.player!!, Sounds.GE_COLLECT_COINS_4042) - seller.addWithdrawItem(995, amount * if(sellerBias) buyer.offeredValue else seller.offeredValue) buyer.addWithdrawItem(seller.itemID, amount) @@ -310,12 +294,13 @@ class GrandExchange : StartupListener, Commands { } */ - seller.update() - val sellerPlayer = Repository.uid_map[seller.playerUID] - sellerPlayer?.let { GrandExchangeRecords.getInstance(sellerPlayer).visualizeRecords() } - buyer.update() - val buyerPlayer = Repository.uid_map[buyer.playerUID] - buyerPlayer?.let { GrandExchangeRecords.getInstance(buyerPlayer).visualizeRecords() } + for (entity in arrayOf(buyer, seller)) { + entity.update() + val player = Repository.uid_map[entity.playerUID] ?: continue + val records = GrandExchangeRecords.getInstance(player) + records.visualizeRecords() + records.updateNotification = true + } } private fun canUpdatePriceIndex(seller: GrandExchangeOffer, buyer: GrandExchangeOffer): Boolean { diff --git a/Server/src/main/core/game/ge/GrandExchangeOffer.kt b/Server/src/main/core/game/ge/GrandExchangeOffer.kt index 919427567..eee8594dd 100644 --- a/Server/src/main/core/game/ge/GrandExchangeOffer.kt +++ b/Server/src/main/core/game/ge/GrandExchangeOffer.kt @@ -146,10 +146,7 @@ class GrandExchangeOffer() { visualize(player) stmt.close() - val username = if (getAttribute(player ?: return@run, "ge-exclude", false)) "?????" - else player?.username ?: "?????" - - Discord.postNewOffer(sell, itemID, offeredValue, amount, username) + Discord.postNewOffer(sell, itemID, offeredValue, amount, player?.username ?: return@run) } } } diff --git a/Server/src/main/core/game/ge/GrandExchangeRecords.kt b/Server/src/main/core/game/ge/GrandExchangeRecords.kt index 63aa20848..e970c01bb 100644 --- a/Server/src/main/core/game/ge/GrandExchangeRecords.kt +++ b/Server/src/main/core/game/ge/GrandExchangeRecords.kt @@ -22,6 +22,7 @@ import java.util.* class GrandExchangeRecords(private val player: Player? = null) : PersistPlayer, LoginListener { var history = arrayOfNulls(5) val offerRecords = arrayOfNulls(6) + var updateNotification = false override fun login(player: Player) { val instance = GrandExchangeRecords(player) diff --git a/Server/src/main/core/game/ge/GrandExchangeTimer.kt b/Server/src/main/core/game/ge/GrandExchangeTimer.kt new file mode 100644 index 000000000..2e68ca5f4 --- /dev/null +++ b/Server/src/main/core/game/ge/GrandExchangeTimer.kt @@ -0,0 +1,24 @@ +package core.game.ge + +import core.api.hasAwaitingGrandExchangeCollections +import core.api.playJingle +import core.api.sendMessage +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.RSTimer + +class GrandExchangeTimer : RSTimer(500, "GE periodic poll", isSoft = true, isAuto = true) { + override fun run(entity: Entity) : Boolean { + if (entity !is Player) return false + val player = entity + val records = GrandExchangeRecords.getInstance(player) + if (records.updateNotification) { + records.updateNotification = false + if (hasAwaitingGrandExchangeCollections(player)) { + sendMessage(player, "One or more of your Grand Exchange offers have been updated.") + playJingle(player, 284) + } + } + return true + } +} diff --git a/Server/src/main/core/game/global/Skillcape.java b/Server/src/main/core/game/global/Skillcape.java index 619b87f04..4ae5ef8a5 100644 --- a/Server/src/main/core/game/global/Skillcape.java +++ b/Server/src/main/core/game/global/Skillcape.java @@ -1,5 +1,6 @@ package core.game.global; +import content.global.skill.construction.decoration.pohstorage.StorableFamily; import core.game.container.Container; import core.game.dialogue.FacialExpression; import core.game.dialogue.FacialExpression; @@ -66,6 +67,25 @@ public final class Skillcape { } } } + + // trim any skillcapes in the player's POH storage + content.global.skill.construction.decoration.pohstorage.StorageState poh = player.getPOHStorageState(); + content.global.skill.construction.decoration.pohstorage.StorageContainer rack = poh.getContainer(StorableFamily.CAPE_RACK_SKILL); + + // count the capes + java.util.List toReplace = new java.util.ArrayList<>(); + for (int itemId : rack.getItems()) { + if (getCapeIndex(new Item(itemId)) != -1) { + toReplace.add(itemId); + } + } + + // replace the untrimmed IDs with trimmed IDs + for (int oldId : toReplace) { + int skillIndex = getCapeIndex(new Item(oldId)); + rack.withdraw(oldId); + rack.addItem(getTrimmed(skillIndex).getId()); + } } /** diff --git a/Server/src/main/core/game/global/action/ClimbActionHandler.java b/Server/src/main/core/game/global/action/ClimbActionHandler.java index f9042b724..1914c2440 100644 --- a/Server/src/main/core/game/global/action/ClimbActionHandler.java +++ b/Server/src/main/core/game/global/action/ClimbActionHandler.java @@ -77,9 +77,11 @@ public final class ClimbActionHandler { } switch (option) { case "climb-up": + case "walk-up": endLadder = getLadder(startLadder, false); break; case "climb-down": + case "walk-down": if (startLadder.getName().equals("Trapdoor")) { animation = CLIMB_DOWN; } diff --git a/Server/src/main/core/game/global/action/DoorActionHandler.java b/Server/src/main/core/game/global/action/DoorActionHandler.java index 98a886839..02234e136 100644 --- a/Server/src/main/core/game/global/action/DoorActionHandler.java +++ b/Server/src/main/core/game/global/action/DoorActionHandler.java @@ -1,5 +1,6 @@ package core.game.global.action; +import content.data.Quests; import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.diary.DiaryType; @@ -84,10 +85,6 @@ public final class DoorActionHandler { return; } DoorConfigLoader.Door d = DoorConfigLoader.Companion.forId(object.getId()); - if (d != null && !d.getQuestRequirement().equals("")) { - if (!hasRequirement(player, d.getQuestRequirement())) - return; - } if (d == null || d.isAutoWalk()) { handleAutowalkDoor(player, object); return; @@ -118,7 +115,9 @@ public final class DoorActionHandler { if (object.getCharge() == IN_USE_CHARGE) { return false; } - final Scenery second = (object.getId() == 3) ? null : getSecondDoor(object, entity); + // TODO: Maybe have this passed in as an optional parameter or overload handleAutowalkDoor? + boolean ignoreSecondDoor = (object.getId() == 3628 || object.getId() == 3629 || object.getId() == 3630 || object.getId() == 3631|| object.getId() == 3632); // Ignore second door for Maze Random + final Scenery second = (object.getId() == 3 || ignoreSecondDoor) ? null : getSecondDoor(object, entity); entity.lock(4); final Location loc = entity.getLocation(); if (entity instanceof Player) { diff --git a/Server/src/main/core/game/global/action/DropListener.kt b/Server/src/main/core/game/global/action/DropListener.kt index e183cbd58..254b582ff 100644 --- a/Server/src/main/core/game/global/action/DropListener.kt +++ b/Server/src/main/core/game/global/action/DropListener.kt @@ -12,6 +12,8 @@ import core.game.node.item.GroundItemManager import core.game.node.item.Item import core.game.system.config.ItemConfigParser import content.global.skill.summoning.pet.Pets +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor import org.rs09.consts.Items import org.rs09.consts.Sounds @@ -33,7 +35,7 @@ class DropListener : InteractionListener { } private fun handleDropAction(player: Player, node: Node) : Boolean { val option = getUsedOption(player) - var item = node as? Item ?: return false + val item = node as? Item ?: return false if (option == "drop") { if (Pets.forId(item.id) != null) { player.familiarManager.summon(item, true, true) @@ -43,11 +45,21 @@ class DropListener : InteractionListener { sendMessage(player, "You cannot drop items on top of graves!") return false } - if (getAttribute(player, "equipLock:${node.id}", 0 ) > getWorldTicks()) + if (player.locks.equipmentLock != null) { return false + } - queueScript (player, strength = QueueStrength.SOFT) { - if (player.inventory.replace(null, item.slot) != item) return@queueScript stopExecuting(player) + closeAllInterfaces(player) + queueScript(player, strength = QueueStrength.SOFT) { //do this as a script to allow dropping multiple items in the same tick (authentic) + // It's possible for state to change between queueing the script and executing it at the end of the tick (https://forum.2009scape.org/viewtopic.php?f=8&t=1195-lost-bandos-chestplate-whilst-making-iron-titans&p=5292). So, sanity check: + val current = player.inventory.get(item.slot) + if (current == null || current !== item) { + return@queueScript stopExecuting(player) + } + if (player.inventory.replace(null, item.slot) !== item) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential exploit attempt when player ${player.name} tried to drop ${item.amount}x ${item.id}. The item has been lost and will need to be refunded to the player, but how did they get this to happen?") + return@queueScript stopExecuting(player) + } val droppedItem = item.dropItem if (droppedItem.id == Items.COINS_995) playAudio(player, DROP_COINS_SOUND) else playAudio(player, DROP_ITEM_SOUND) GroundItemManager.create(droppedItem, player.location, player) diff --git a/Server/src/main/core/game/global/action/EquipHandler.kt b/Server/src/main/core/game/global/action/EquipHandler.kt index bab80e779..29299e238 100644 --- a/Server/src/main/core/game/global/action/EquipHandler.kt +++ b/Server/src/main/core/game/global/action/EquipHandler.kt @@ -33,11 +33,19 @@ class EquipHandler : InteractionListener { fun handleEquip(player: Player, node: Node) { val item = node.asItem() + val itemEquipmentSlot = item.definition.getConfiguration(ItemConfigParser.EQUIP_SLOT, -1) - if (item == null || player.inventory[item.slot] != item || item.name.toLowerCase().contains("goblin mail")) { + val currentEquippedItem = player.equipment[itemEquipmentSlot] + if (item == null || currentEquippedItem == item || item.name.toLowerCase().contains("goblin mail")) { return } + if(currentEquippedItem != null){ + if(!InteractionListeners.run(currentEquippedItem.id, player, currentEquippedItem, false)){ + return + } + } + val equipStateListener = item.definition.getConfiguration>("equipment", null) if (equipStateListener != null) { val bool = equipStateListener.fireEvent("equip", player, item) @@ -45,7 +53,7 @@ class EquipHandler : InteractionListener { return } } - if (!InteractionListeners.run(node.id, player, node, true)) { + if (!InteractionListeners.run(node.id, player, item, true)) { return } @@ -70,7 +78,6 @@ class EquipHandler : InteractionListener { playAudio(player, item.definition.getConfiguration(ItemConfigParser.EQUIP_AUDIO, 2244)) if (player.properties.autocastSpell != null) { - val itemEquipmentSlot = item.definition.getConfiguration(ItemConfigParser.EQUIP_SLOT, -1) if (itemEquipmentSlot == EquipmentContainer.SLOT_WEAPON) { player.properties.autocastSpell = null diff --git a/Server/src/main/core/game/global/action/SpecialLadders.java b/Server/src/main/core/game/global/action/SpecialLadders.java index 467ad84d4..532bd896a 100644 --- a/Server/src/main/core/game/global/action/SpecialLadders.java +++ b/Server/src/main/core/game/global/action/SpecialLadders.java @@ -3,6 +3,7 @@ package core.game.global.action; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.diary.DiaryType; import core.game.world.map.Location; +import content.region.kandarin.feldip.quest.zogreflesheaters.ZogreFleshEatersListeners; import java.util.Arrays; import java.util.HashMap; @@ -18,18 +19,27 @@ public enum SpecialLadders implements LadderAchievementCheck { SWENSEN_UP(Location.create(2665, 10037, 0),Location.create(2649, 3661, 0)), FOG_ENTER(Location.create(3240,3575,0),Location.create(1675,5599,0)), FOG_LEAVE(Location.create(1673,5598,0),Location.create(3242, 3574, 0)), - INTRO_LEAVE(Location.create(2522, 4999, 0),Location.create(3230, 3240, 0)), + INTRO_ENTER(Location.create(3230,3241,0),Location.create(3290, 4936, 0)), + INTRO_LEAVE(Location.create(3290, 4935, 0),Location.create(3230, 3240, 0)), JATIZSO_MINE_UP(Location.create(2406,10188,0),Location.create(2397, 3811, 0)), JATIZSO_MINE_DOWN(Location.create(2397, 3812, 0), Location.create(2405, 10188, 0)), JATIZSO_SHOUT_TOWER_UP(Location.create(2373, 3800, 2),Location.create(2374, 3800, 0)), JATIZSO_SHOUT_TOWER_DOWN(Location.create(2373, 3800, 0),Location.create(2374, 3800, 2)), + // sendMessage(player, "You descend into the somewhat smoky depths of the well, to the accompaniment of") + // sendMessage(player, "eery wails.") https://youtu.be/x8abdpkJ6ZA + POLLNIVNEACH_SLAYER_DUNGEON_UP(Location.create(3358,2971,0), Location.create(3359,9354,0)), + // sendMessage(player, "You nimbly climb up the bucket rope, emerging into Pollnivneach's bustling square.") https://youtu.be/LVwbmCNjlzQ + POLLNIVNEACH_SLAYER_DUNGEON_DOWN(Location.create(3358,9352,0), Location.create(3358,2970,0)), ALKHARID_ZEKE_UP(Location.create(3284,3186,0), Location.create(3284,3190,1)), ALKHARID_ZEKE_DOWN(Location.create(3284,3190,1), Location.create(3284,3186,0)), ALKHARID_CRAFTING_UP(Location.create(3311,3187,0),Location.create(3314,3187,1)), ALKHARID_CRAFTING_DOWN(Location.create(3314,3187,1),Location.create(3310,3187,0)), ALKHARID_SOCRCERESS_UP(Location.create(3325,3142,0),Location.create(3325,3139,1)), ALKHARID_SOCRCERESS_DOWN(Location.create(3325,3139,1),Location.create(3325,3143,0)), + KHARIDIAN_DESERT_SUMMONING_UP(Location.create(3299,9318,0),Location.create(3303,2897,0)), + KHARIDIAN_DESERT_SUMMONING_DOWN(Location.create(3304,2897,0),Location.create(3299,9317,0)), + SHADOW_DUNGEON_UP(new Location(2629, 5072,0), new Location(2548, 3421,0)), CLOCKTOWER_HIDDEN_LADDER(Location.create(2572,9631,0),Location.create(2572,3230,0)), @@ -58,6 +68,9 @@ public enum SpecialLadders implements LadderAchievementCheck { CASTLEWARS_ZAMORAK_OUTERWALL_STAIRS_UP(Location.create(2382, 3130, 0), Location.create(2383, 3132, 0)), CASTLEWARS_ZAMOUTER_WALL_STAIRS_DOWN(Location.create(2382, 3132, 0), Location.create(2382, 3129, 0)), + WHITE_WOLF_MOUNTAIN_FAKE_LADDER_1_UP(Location.create(2837, 9927, 0), Location.create(2837, 3527, 0)), + WHITE_WOLF_MOUNTAIN_FAKE_LADDER_2_UP(Location.create(2823, 9930, 0), Location.create(2823, 3529, 0)), + PORT_SARIM_RAT_PITS_DOWN(new Location(3018,3232,0), new Location(2962,9650,0)) { @Override public void checkAchievement(Player player) { @@ -71,6 +84,13 @@ public enum SpecialLadders implements LadderAchievementCheck { PATERDOMUS_TEMPLE_STAIRCASE_SOUTH_DOWN(new Location(3415, 3486,1), new Location(3414, 3486,0)), PHASMATYS_BAR_DOWN(new Location(3681,3498,0), new Location(3682,9961,0)), PHASMATYS_BAR_UP(new Location(3682,9962,0), new Location(3681,3497,0)), + YANNILE_HOUSE_DOWN(new Location(2597, 3107,1), new Location(2597, 3107,0)), + YANNILE_HOUSE_UP(new Location(2597, 3107,0), new Location(2597, 3107,1)) { + @Override + public void checkAchievement(Player player) { + ZogreFleshEatersListeners.ladderMakesSithikTurnIntoOgre(player); + } + }, SEERS_VILLAGE_SPINNING_HOUSE_ROOFTOP_UP(new Location(2715,3472,1), new Location(2714,3472,3)) { @Override public void checkAchievement(Player player) { diff --git a/Server/src/main/core/game/interaction/InteractionListeners.kt b/Server/src/main/core/game/interaction/InteractionListeners.kt index c28113500..e3cab3e34 100644 --- a/Server/src/main/core/game/interaction/InteractionListeners.kt +++ b/Server/src/main/core/game/interaction/InteractionListeners.kt @@ -164,6 +164,7 @@ object InteractionListeners { @JvmStatic fun run(id: Int, player: Player, node: Node, isEquip: Boolean): Boolean{ + player.scripts.removeWeakScripts() player.dispatch(InteractionEvent(node, if(isEquip) "equip" else "unequip")) if(isEquip){ return equipListeners["equip:$id"]?.invoke(player,node) ?: true @@ -174,6 +175,7 @@ object InteractionListeners { @JvmStatic fun run(used: Node, with: Node, type: IntType, player: Player): Boolean{ + player.scripts.removeWeakScripts() val flag = when(type){ IntType.NPC, IntType.PLAYER -> DestinationFlag.ENTITY IntType.SCENERY -> DestinationFlag.OBJECT @@ -224,6 +226,8 @@ object InteractionListeners { @JvmStatic fun run(id: Int, type: IntType, option: String, player: Player, node: Node): Boolean{ + player.scripts.removeWeakScripts() + val flag = when(type){ IntType.PLAYER -> DestinationFlag.ENTITY IntType.GROUNDITEM -> DestinationFlag.ITEM diff --git a/Server/src/main/core/game/interaction/MovementPulse.java b/Server/src/main/core/game/interaction/MovementPulse.java index ca60a54cf..b378a8a1f 100644 --- a/Server/src/main/core/game/interaction/MovementPulse.java +++ b/Server/src/main/core/game/interaction/MovementPulse.java @@ -11,6 +11,7 @@ import core.game.world.GameWorld; import core.game.world.map.Direction; import core.game.world.map.Location; import core.game.world.map.Point; +import core.game.world.map.RegionManager; import core.game.world.map.path.Path; import core.game.world.map.path.Pathfinder; import core.net.packet.PacketRepository; @@ -220,6 +221,12 @@ public abstract class MovementPulse extends Pulse { clearInferiorScripts(); mover.face(null); + if (canInteractWithoutMoving()) { + if (interactImmediately()) { + stop(); + return true; + } + } updatePath(); if (tryInteract()) { @@ -236,7 +243,24 @@ public abstract class MovementPulse extends Pulse { int radius = destination instanceof Entity && ((Entity)destination).getWalkingQueue().hasPath() ? 1 : 0; if (interactLocation == null) return false; - if (Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius) { + boolean atInteractLocation = Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius; + // Check if already in a valid interaction position for entity destinations + boolean canInteractFromCurrentPosition = false; + if (!atInteractLocation && destination instanceof Entity) { + Entity target = (Entity) destination; + Location dl = target.getLocation(); + boolean onSameTile = ml.getX() == dl.getX() && ml.getY() == dl.getY() && ml.getZ() == dl.getZ(); + if (!onSameTile) { + canInteractFromCurrentPosition = Pathfinder.canInteract( + ml.getX(), ml.getY(), mover.size(), + dl.getX(), dl.getY(), target.size(), target.size(), + 0, // walkFlag - "can interact from any unblocked direction" + ml.getZ(), + RegionManager::getClippingFlag + ); + } + } + if (atInteractLocation || canInteractFromCurrentPosition) { try { if (near || pulse()) { if (mover instanceof Player) { @@ -256,6 +280,66 @@ public abstract class MovementPulse extends Pulse { return false; } + /** + * Checks if the mover can interact with an entity destination from their + * current position without needing to move. + * + * @return true if the mover can interact without moving + */ + private boolean canInteractWithoutMoving() { + if (!(destination instanceof Entity)) { + return false; + } + Entity target = (Entity) destination; + Location ml = mover.getLocation(); + Location dl = target.getLocation(); + if (ml.getX() == dl.getX() && ml.getY() == dl.getY() && ml.getZ() == dl.getZ()) { + return false; + } + if (isInsideEntity(mover.getLocation())) { + return false; + } + if (target.getWalkingQueue().hasPath()) { // For moving entities, allow interaction from 1 tile away + int distance = Math.max( + Math.abs(ml.getX() - dl.getX()), + Math.abs(ml.getY() - dl.getY()) + ); + if (distance <= target.size()) { + return true; + } + } + return Pathfinder.canInteract( + ml.getX(), ml.getY(), mover.size(), + dl.getX(), dl.getY(), target.size(), target.size(), + 0, // walkFlag - "can interact from any unblocked direction" + ml.getZ(), + RegionManager::getClippingFlag + ); + } + + /** + * Immediately performs the interaction without pathfinding. + * Called when the player is already in a valid interaction position. + * + * @return true if interaction was successful and pulse should stop + */ + private boolean interactImmediately() { + if (destination instanceof Entity) { + mover.face((Entity) destination); + } + try { + if (pulse()) { + if (mover instanceof Player) { + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext((Player) mover)); + } + return true; + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + private boolean validate() { if (mover == null || destination == null || mover.getViewport().getRegion() == null || hasInactiveNode()) { return false; @@ -312,7 +396,7 @@ public abstract class MovementPulse extends Pulse { if (interactLocation == null) interactLocation = loc; - if (destination instanceof Entity || interactLocation == null || (!mover.getWalkingQueue().hasPath() && interactLocation.getDistance(mover.getLocation()) > 0) || (usingTruncatedPath && destination.getLocation().getDistance(mover.getLocation()) < 14)) { + if (destination instanceof Entity || interactLocation == null || (mover.getWalkingQueue().getQueue().size() <= 1 && interactLocation.getDistance(mover.getLocation()) > 0) || (usingTruncatedPath && destination.getLocation().getDistance(mover.getLocation()) < 14)) { if (!checkAllowMovement()) return; if (destination instanceof Entity && previousLoc != null && previousLoc.equals(loc) && mover.getWalkingQueue().hasPath()) @@ -380,44 +464,49 @@ public abstract class MovementPulse extends Pulse { return canMove; } - private Location checkForEntityPathInterrupt(Location loc) { - Location ml = mover.getLocation(); - Location dl = destination.getLocation(); - // Lead the target if they're walking/running, unless they're already within interaction range - if(loc != null && destination instanceof Entity) { - WalkingQueue wq = ((Entity)destination).getWalkingQueue(); - if(wq.hasPath()) { - Point[] points = wq.getQueue().toArray(new Point[0]); - if(points.length > 0) { - Point p = points[0]; - Point predictiveIntersection = null; - for(int i=0; i 0) { + Point p = points[0]; + Point predictiveIntersection = null; + for (int i = 0; i < points.length; i++) { + Location closestBorder = getClosestBorderToPoint(points[i], loc.getZ()); - int moverDist = Math.max(Math.abs(ml.getX() - closestBorder.getX()), Math.abs(ml.getY() - closestBorder.getY())); - float movementRatio = moverDist / (float) ((i + 1) / (mover.getWalkingQueue().isRunning() ? 2 : 1)); - if (predictiveIntersection == null && movementRatio <= 1.0) { //try to predict an intersection point on the path if possible - predictiveIntersection = points[i]; - break; - } + if (!RegionManager.isTeleportPermitted(closestBorder)) { // A nasty hack to discard invalid intersection points + continue; + } + int moverDist = Math.max(Math.abs(ml.getX() - closestBorder.getX()), Math.abs(ml.getY() - closestBorder.getY())); + float movementRatio = moverDist / (float) ((i + 1) / (mover.getWalkingQueue().isRunning() ? 2 : 1)); + if (predictiveIntersection == null && movementRatio <= 1.0) { //try to predict an intersection point on the path if possible + predictiveIntersection = points[i]; + break; + } + // Otherwise, we target the farthest point along target's planned movement that's within 1 tick's running, + // this ensures the player will run to catch up to the target if able. + if (moverDist <= 2) { + p = points[i]; + } + } + if (predictiveIntersection != null) + p = predictiveIntersection; - // Otherwise, we target the farthest point along target's planned movement that's within 1 tick's running, - // this ensures the player will run to catch up to the target if able. - if(moverDist <= 2) { - p = points[i]; - } - } + Location endLoc = getClosestBorderToPoint(p, loc.getZ()); - if (predictiveIntersection != null) - p = predictiveIntersection; - - Location endLoc = getClosestBorderToPoint(p, loc.getZ()); - return endLoc; - } - } - } - return loc; - } + if (!RegionManager.isTeleportPermitted(endLoc)) { // Basically a prayer + return loc; + } + return endLoc; + } + } + } + return loc; + } private Location getClosestBorderToPoint (Point p, int plane) { Vector pathDiff = Vector.betweenLocs (destination.getLocation(), Location.create(p.getX(), p.getY(), plane)); diff --git a/Server/src/main/core/game/interaction/ScriptProcessor.kt b/Server/src/main/core/game/interaction/ScriptProcessor.kt index ec6da95a4..2c638f35f 100644 --- a/Server/src/main/core/game/interaction/ScriptProcessor.kt +++ b/Server/src/main/core/game/interaction/ScriptProcessor.kt @@ -1,6 +1,7 @@ package core.game.interaction import core.api.* +import core.game.bots.AIPlayer import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.npc.NPC @@ -10,11 +11,10 @@ import core.game.node.scenery.Scenery import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.map.path.Pathfinder -import core.game.bots.AIPlayer import core.tools.Log -import core.tools.SystemLogger +import java.io.PrintWriter +import java.io.StringWriter import java.lang.Integer.max -import java.io.* class ScriptProcessor(val entity: Entity) { private var apScript: Script<*>? = null @@ -91,17 +91,12 @@ class ScriptProcessor(val entity: Entity) { } fun processQueue() : Boolean { - var strongInQueue = false - var softInQueue = false var anyExecuted = false - strongInQueue = hasTypeInQueue(QueueStrength.STRONG) - softInQueue = hasTypeInQueue(QueueStrength.SOFT) + val strongInQueue = hasTypeInQueue(QueueStrength.STRONG) - if (softInQueue || strongInQueue) { + if (strongInQueue) { if (entity is Player) { - entity.interfaceManager.close() - entity.interfaceManager.closeChatbox() - entity.dialogueInterpreter.close() + closeAllInterfaces(entity) } } @@ -118,10 +113,8 @@ class ScriptProcessor(val entity: Entity) { continue if (script.nextExecution > GameWorld.ticks) continue - if ((script.strength == QueueStrength.STRONG || script.strength == QueueStrength.SOFT) && entity is Player) { - entity.interfaceManager.close() - entity.interfaceManager.closeChatbox() - entity.dialogueInterpreter.close() + if ((script.strength == QueueStrength.STRONG) && entity is Player) { + closeAllInterfaces(entity) } script.nextExecution = GameWorld.ticks + 1 val finished = executeScript(script) @@ -142,10 +135,8 @@ class ScriptProcessor(val entity: Entity) { } if (script.nextExecution > GameWorld.ticks) continue - if ((script.strength == QueueStrength.STRONG || script.strength == QueueStrength.SOFT)) { - entity.interfaceManager.close() - entity.interfaceManager.closeChatbox() - entity.dialogueInterpreter.close() + if ((script.strength == QueueStrength.STRONG)) { + closeAllInterfaces(entity) } script.nextExecution = GameWorld.ticks + 1 val finished = executeScript(script) @@ -284,9 +275,7 @@ class ScriptProcessor(val entity: Entity) { return } if (strength == QueueStrength.STRONG && entity is Player) { - entity.interfaceManager.close() - entity.interfaceManager.closeChatbox() - entity.dialogueInterpreter.close() + closeAllInterfaces(entity) } script.nextExecution = max(GameWorld.ticks + 1, script.nextExecution) queue.add(script) diff --git a/Server/src/main/core/game/interaction/UseWithHandler.java b/Server/src/main/core/game/interaction/UseWithHandler.java index c38a5e6bc..4c5a6f414 100644 --- a/Server/src/main/core/game/interaction/UseWithHandler.java +++ b/Server/src/main/core/game/interaction/UseWithHandler.java @@ -134,7 +134,9 @@ public abstract class UseWithHandler implements Plugin { event.getPlayer().getPulseManager().run(new MovementPulse(event.getPlayer(), event.getUsedWith()) { @Override public boolean pulse() { - event.getPlayer().debug("Unhandled use with interaction: item used: " + event.getUsed() + " with: " + event.getUsedWith()); + event.getPlayer().debug("Unhandled use with interaction:"); + event.getPlayer().debug("Used: " + event.getUsed()); + event.getPlayer().debug("With: " + event.getUsedWith()); event.getPlayer().getPacketDispatch().sendMessage("Nothing interesting happens."); return true; } diff --git a/Server/src/main/core/game/node/entity/Entity.java b/Server/src/main/core/game/node/entity/Entity.java index c1c930645..ffaa8f461 100644 --- a/Server/src/main/core/game/node/entity/Entity.java +++ b/Server/src/main/core/game/node/entity/Entity.java @@ -78,7 +78,7 @@ public abstract class Entity extends Node { /** * The pulse manager. */ - private final PulseManager pulseManager = new PulseManager(); + private final PulseManager pulseManager = new PulseManager(this); /** * The impact handler. @@ -450,6 +450,9 @@ public abstract class Entity extends Node { if (!entity.getZoneMonitor().continueAttack(this, style, message)) { return false; } + if (!this.getZoneMonitor().continueAttack(entity, style, message)) { + return false; + } return true; } @@ -489,10 +492,25 @@ public abstract class Entity extends Node { } /** - * Checks if an entity can continue it's attack. - * @param target the target. - * @param style the style. - * @return {@code True} if so. + * Checks if an entity can continue its attack. + * + *

This method is called during attack validation to determine if the attacking entity should be + * allowed to continue attacking the target. It's invoked by + * {@link core.game.world.map.zone.ZoneMonitor#continueAttack(Node, CombatStyle, boolean)} + * as part of the attack validation chain.

+ * + *

The default implementation returns {@code true}, allowing the attack to proceed. + * Subclasses should override this method to implement entity-specific attack restrictions.

+ * + *

This method is distinct from {@link #isAttackable(Entity, CombatStyle, boolean)}, which + * checks if this entity can be attacked by another entity. The {@code continueAttack} method + * checks if this entity can attack the given target.

+ * + * @param target the target entity being attacked + * @param style the combat style being used + * @param message whether to send a message to the player explaining why the attack cannot continue + * + * @return {@code true} if the entity can continue attacking the target */ public boolean continueAttack(Entity target, CombatStyle style, boolean message) { return true; @@ -660,7 +678,7 @@ public abstract class Entity extends Node { /** * Registers a new force chat update flag to the update masks. * @param string The string. - * @return {@code True} if succesful. + * @return {@code True} if successful. */ public boolean sendChat(String string) { return getUpdateMasks().register(EntityFlag.ForceChat, string); diff --git a/Server/src/main/core/game/node/entity/combat/BattleState.java b/Server/src/main/core/game/node/entity/combat/BattleState.java index e75aac19d..4a12b5966 100644 --- a/Server/src/main/core/game/node/entity/combat/BattleState.java +++ b/Server/src/main/core/game/node/entity/combat/BattleState.java @@ -9,6 +9,7 @@ import core.game.node.entity.combat.spell.CombatSpell; /** * Represents an entity's current battle state. + * * @author Emperor */ public final class BattleState { @@ -99,6 +100,7 @@ public final class BattleState { /** * Constructs a new {@code BattleState} {@Code Object} + * * @param victim The victim entity. */ public BattleState(Entity entity, Entity victim) { @@ -134,6 +136,7 @@ public final class BattleState { /** * Gets the estimatedHit. + * * @return The estimatedHit. */ public int getEstimatedHit() { @@ -142,6 +145,7 @@ public final class BattleState { /** * Sets the estimated hit. + * * @param estimatedHit The estimated hit to set. */ public void setEstimatedHit(int estimatedHit) { @@ -164,6 +168,7 @@ public final class BattleState { /** * Gets the recoilDamage. + * * @return The recoilDamage. */ public int getRecoilDamage() { @@ -172,6 +177,7 @@ public final class BattleState { /** * Sets the recoilDamage. + * * @param recoilDamage The recoilDamage to set. */ public void setRecoilDamage(int recoilDamage) { @@ -236,6 +242,7 @@ public final class BattleState { /** * Gets the maximumHit. + * * @return The maximumHit. */ public int getMaximumHit() { @@ -244,6 +251,7 @@ public final class BattleState { /** * Sets the maximumHit. + * * @param maximumHit The maximumHit to set. */ public void setMaximumHit(int maximumHit) { @@ -252,6 +260,7 @@ public final class BattleState { /** * Gets the rangeWeapon. + * * @return The rangeWeapon. */ public RangeWeapon getRangeWeapon() { @@ -260,6 +269,7 @@ public final class BattleState { /** * Sets the rangeWeapon. + * * @param rangeWeapon The rangeWeapon to set. */ public void setRangeWeapon(RangeWeapon rangeWeapon) { @@ -268,6 +278,7 @@ public final class BattleState { /** * Gets the ammunition. + * * @return The ammunition. */ public Ammunition getAmmunition() { @@ -276,6 +287,7 @@ public final class BattleState { /** * Sets the ammunition. + * * @param ammunition The ammunition to set. */ public void setAmmunition(Ammunition ammunition) { @@ -284,6 +296,7 @@ public final class BattleState { /** * Gets the frozen. + * * @return The frozen. */ public boolean isFrozen() { @@ -292,6 +305,7 @@ public final class BattleState { /** * Sets the frozen. + * * @param frozen The frozen to set. */ public void setFrozen(boolean frozen) { @@ -300,6 +314,7 @@ public final class BattleState { /** * Gets the style. + * * @return The style. */ public CombatStyle getStyle() { @@ -308,6 +323,7 @@ public final class BattleState { /** * Sets the style. + * * @param style The style to set. */ public void setStyle(CombatStyle style) { @@ -316,6 +332,7 @@ public final class BattleState { /** * Gets the armourEffect. + * * @return The armourEffect. */ public ArmourSet getArmourEffect() { @@ -324,6 +341,7 @@ public final class BattleState { /** * Sets the armourEffect. + * * @param armourEffect The armourEffect to set. */ public void setArmourEffect(ArmourSet armourEffect) { @@ -332,6 +350,7 @@ public final class BattleState { /** * Gets the attacking entity. + * * @return The entity. */ public Entity getAttacker() { @@ -340,10 +359,9 @@ public final class BattleState { public int getTotalDamage() { int hit = Math.max(estimatedHit, 0) + Math.max(secondaryHit, 0); - if (targets != null) { for (BattleState s : targets) { - if (s != null) { + if (s != null && s != this) { hit += Math.max(s.getEstimatedHit(), 0) + Math.max(s.getSecondaryHit(), 0); } } diff --git a/Server/src/main/core/game/node/entity/combat/CombatPulse.kt b/Server/src/main/core/game/node/entity/combat/CombatPulse.kt index 0473df0a0..074a656e9 100644 --- a/Server/src/main/core/game/node/entity/combat/CombatPulse.kt +++ b/Server/src/main/core/game/node/entity/combat/CombatPulse.kt @@ -296,9 +296,13 @@ class CombatPulse( } setVictim(victim) entity.onAttack(victim as Entity?) + if (isAttacking) { + victim.scripts.removeWeakScripts() + } - if (!isAttacking) + if (!isAttacking) { entity.pulseManager.run(this) + } } /** @@ -427,6 +431,7 @@ class CombatPulse( } handler.adjustBattleState(entity, victim!!, state) handler.addExperience(entity, victim, state) + handler.postSwing(entity, victim, state) handler.visualize(entity, victim, state) if (delay - 1 < 1) { handler.visualizeImpact(entity, victim, state) @@ -468,7 +473,7 @@ class CombatPulse( } init { - movement = object : MovementPulse(entity, null, DestinationFlag.ENTITY) { + movement = object : MovementPulse(entity, null) { override fun pulse(): Boolean { return false } diff --git a/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt index b5633d588..d4324b233 100644 --- a/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt @@ -31,10 +31,14 @@ import kotlin.math.floor * Handles a combat swing. * @author Emperor * @author Ceikry - Kotlin refactoring, general cleanup + * @author Player Name - converted `flags` to ArrayList */ abstract class CombatSwingHandler(var type: CombatStyle?) { - var flags: Array = emptyArray() - constructor(type: CombatStyle?, vararg flags: SwingHandlerFlag) : this(type) { this.flags = flags } + var flags: ArrayList = ArrayList(SwingHandlerFlag.values().size) + constructor(type: CombatStyle?, vararg flags: SwingHandlerFlag) : this(type) { + this.flags = arrayListOf(*flags) + } + /** * The mapping of the special attack handlers. */ @@ -173,26 +177,21 @@ abstract class CombatSwingHandler(var type: CombatStyle?) { * @return `True` if the hit is accurate. */ fun isAccurateImpact(entity: Entity?, victim: Entity?, style: CombatStyle?, accuracyMod: Double, defenceMod: Double): Boolean { - var mod = 1.33 + var mod = 1.0 if (victim == null || style == null) { return false } if (victim is Player && entity is Familiar && victim.prayer[PrayerType.PROTECT_FROM_SUMMONING]) { mod = 0.0 } - val attack = calculateAccuracy(entity) * accuracyMod * mod * getSetMultiplier(entity, Skills.ATTACK) - val defence = calculateDefence(victim, entity) * defenceMod * getSetMultiplier(victim, Skills.DEFENCE) + val attack = calculateAccuracy(entity) * accuracyMod * mod + val defence = calculateDefence(victim, entity) * defenceMod val chance: Double = if (attack > defence) { - 1 - ((defence + 2) / ((2 * attack) + 1)) + 1 - ((defence + 2) / (2 * (attack + 1))) } else { - attack / ((2 * defence) + 1) + attack / (2 * (defence + 1)) } - val ratio = chance * 100 - val accuracy = floor(ratio) - val block = floor(101 - ratio) - val acc = Math.random() * accuracy - val def = Math.random() * block - return (acc > def).also { if(entity?.username?.toLowerCase() == "test10") log(this::class.java, Log.FINE, "Should hit: $it") } + return Math.random() < chance } /** @@ -248,16 +247,22 @@ abstract class CombatSwingHandler(var type: CombatStyle?) { return InteractionType.STILL_INTERACT } - private fun canStepTowards(entity: Entity, victim: Entity): InteractionType { + protected fun canStepTowards(entity: Entity, victim: Entity): InteractionType { val closestVictimTile = victim.getClosestOccupiedTile(entity.location) val closestEntityTile = entity.getClosestOccupiedTile(closestVictimTile) val dir = closestEntityTile.deriveDirection(closestVictimTile) ?: return InteractionType.STILL_INTERACT //if we cannot derive a direction, it's because both tiles are the same, so hand off control to the main logic which already handles this case var next = closestEntityTile - while (next.getDistance(closestVictimTile) > 3) { //skip the initial gap in distance if it exists, because standard pathfinding would already stop us before this point if something was between us and the NPC or vice versa + //Skip the initial gap in distance if it exists, because standard pathfinding would already stop us before this point if something was between us and the NPC or vice versa. + //A fixed-direction walk can only arrive within its starting distance in steps; on oblique approaches it + //passes beside the target and never converges, so the walk is hard-capped at that many steps. + val maxSkipSteps = next.getDistance(closestVictimTile).toInt() + 1 + for (i in 0 until maxSkipSteps) { + if (next.getDistance(closestVictimTile) <= 3) break next = next.transform(dir) } + if (next.getDistance(closestVictimTile) > 3) return InteractionType.STILL_INTERACT //never converged (oblique approach), so defer to the range checks instead var result: InteractionType = InteractionType.STILL_INTERACT val maxIterations = next.getDistance(closestVictimTile).toInt() @@ -532,6 +537,12 @@ abstract class CombatSwingHandler(var type: CombatStyle?) { } } + /** + * Hook for operations that conceptually happen during swing but could mess with experience granting logic if they + * happened earlier. + */ + open fun postSwing(entity: Entity?, victim: Entity?, state: BattleState?) {} + /** * Gets the formated hit. * @param attacker The attacking entity. @@ -669,5 +680,6 @@ enum class SwingHandlerFlag { IGNORE_STAT_BOOSTS_DAMAGE, IGNORE_STAT_BOOSTS_ACCURACY, IGNORE_PRAYER_BOOSTS_DAMAGE, - IGNORE_PRAYER_BOOSTS_ACCURACY + IGNORE_PRAYER_BOOSTS_ACCURACY, + IGNORE_STAT_REDUCTION } diff --git a/Server/src/main/core/game/node/entity/combat/DeathTask.java b/Server/src/main/core/game/node/entity/combat/DeathTask.java index 3ea456d7b..da308856d 100644 --- a/Server/src/main/core/game/node/entity/combat/DeathTask.java +++ b/Server/src/main/core/game/node/entity/combat/DeathTask.java @@ -82,8 +82,8 @@ public final class DeathTask extends NodeTask { e.getProperties().setTeleportLocation(spawn); e.unlock(); e.finalizeDeath(killer); - e.getImpactHandler().getImpactLog().clear();// check if this needs to be - // before finalize + e.getImpactHandler().getNpcImpactLog().clear();// check if this needs to be before finalize + e.getImpactHandler().getPlayerImpactLog().clear();// check if this needs to be before finalize e.getImpactHandler().setDisabledTicks(4); e.dispatch(new SelfDeathEvent(killer)); } diff --git a/Server/src/main/core/game/node/entity/combat/ImpactHandler.java b/Server/src/main/core/game/node/entity/combat/ImpactHandler.java index af9f3794c..b3a6a6bec 100644 --- a/Server/src/main/core/game/node/entity/combat/ImpactHandler.java +++ b/Server/src/main/core/game/node/entity/combat/ImpactHandler.java @@ -1,12 +1,11 @@ package core.game.node.entity.combat; -import core.ServerConstants; +import content.data.EnchantedJewellery; import core.game.container.impl.EquipmentContainer; import core.game.node.entity.skill.Skills; import content.global.skill.summoning.familiar.Familiar; import content.global.skill.summoning.pet.Pet; import core.game.node.entity.Entity; -import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.prayer.PrayerType; import core.game.node.item.Item; @@ -14,12 +13,13 @@ import core.game.system.task.Pulse; import core.game.bots.AIPlayer; import core.game.world.GameWorld; import core.game.world.map.zone.ZoneType; +import core.game.world.repository.Repository; +import org.rs09.consts.Items; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; -import java.util.stream.Collectors; /** * Class used for handling combat impacts. @@ -38,9 +38,14 @@ public final class ImpactHandler { private int disabledTicks; /** - * The impact log. + * The NPC impact log. */ - private final Map impactLog = new HashMap<>(); + private final Map npcImpactLog = new HashMap<>(); + + /** + * The player impact log. This is by player uid to cope with players relogging. + */ + private final Map playerImpactLog = new HashMap<>(); /** * Gets the current hitsplats to show. @@ -166,11 +171,14 @@ public final class ImpactHandler { return null; } if (hit > 0) { - Integer value = impactLog.get(source); - if (value == null) { - value = 0; + if (source instanceof Player) { + int uid = source.asPlayer().getDetails().getUid(); + Integer value = playerImpactLog.get(uid); + playerImpactLog.put(uid, value == null ? hit : hit + value); + } else { + Integer value = npcImpactLog.get(source); + npcImpactLog.put(source, value == null ? hit : hit + value); } - impactLog.put(source, hit + value); } if (style != null && style.getSwingHandler() != null && source instanceof Player) { Player player = source.asPlayer(); @@ -200,12 +208,13 @@ public final class ImpactHandler { impactQueue.add(impact); if (entity instanceof Player && !dead) { final Player p = entity.asPlayer(); - if (p.getZoneMonitor().getType() != ZoneType.SAFE.getId() && p.getSkullManager().getLevel() <= 30 && (p.getEquipment().contains(2570, 1))) { + if (p.getZoneMonitor().getType() != ZoneType.SAFE.getId() && (p.getEquipment().contains(Items.RING_OF_LIFE_2570, 1))) { int percentage = (int) (entity.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.10); if (p.getSkills().getLifepoints() <= percentage) { - p.getEquipment().remove(new Item(2570)); - p.sendMessage("Your ring of life saves you and in the process is destroyed."); - p.teleport(ServerConstants.HOME_LOCATION); + Item rolItem = new Item(Items.RING_OF_LIFE_2570); + if (EnchantedJewellery.RING_OF_LIFE.attemptTeleport(p, rolItem, 0, true, true)) { + p.sendMessage("Your ring of life saves you and in the process is destroyed."); + } } } } @@ -246,35 +255,48 @@ public final class ImpactHandler { if (entity instanceof Player) { return killer; } + if (killer instanceof AIPlayer) return killer; + int damage = -1; - for (Entity e : impactLog.keySet()) { - if (e == this.entity) { - continue; + if (playerImpactLog.isEmpty()) { + for (Entity e : npcImpactLog.keySet()) { + if (e == this.entity) { + continue; + } + int amount = npcImpactLog.get(e); + if (amount > damage) { + damage = amount; + entity = e; + } } - int amount = impactLog.get(e); - if (amount > damage || (entity instanceof NPC && e instanceof Player)) { + return entity; + } + + int player = 0; //needs to be fake-initialized because java is dumb + for (int uid : playerImpactLog.keySet()) { + int amount = playerImpactLog.get(uid); + if (amount > damage) { damage = amount; - entity = e; + player = uid; } } - return entity; + return Repository.getPlayerByUid(player); } /** - * Gets the impact log. - * @return The impact log. + * Gets the npc impact log. + * @return The npc impact log. */ - public Map getImpactLog() { - return impactLog; + public Map getNpcImpactLog() { + return npcImpactLog; } /** - * Gets the impact log filtered for Player objects - * @return The impact log of each Player and their damage + * Gets the player impact log. + * @return The player impact log. */ - public Map getPlayerImpactLog() { - return impactLog.entrySet().stream().filter(entry -> entry.getKey() instanceof Player).collect( - Collectors.toMap(m -> m.getKey().asPlayer(), m -> m.getValue())); + public Map getPlayerImpactLog() { + return playerImpactLog; } /** @@ -388,4 +410,4 @@ public final class ImpactHandler { public static enum HitsplatType { MISS, NORMAL, POISON, DISEASE, NORMAL_1, VENOM; } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt index c7d850781..0062c20d9 100644 --- a/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt @@ -1,5 +1,7 @@ package core.game.node.entity.combat +import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.skill.summoning.SummoningPouch import core.game.node.entity.Entity import core.game.node.entity.combat.equipment.ArmourSet import core.game.node.entity.combat.spell.SpellType @@ -61,7 +63,7 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) for (s in state.targets) { var hit = -1 s.spell = spell - if (isAccurateImpact(entity, s.victim, CombatStyle.MAGIC, 1.3, 1.0)) { + if (isAccurateImpact(entity, s.victim, CombatStyle.MAGIC)) { s.maximumHit = max hit = RandomFunction.random(max) } @@ -136,31 +138,31 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) } override fun calculateAccuracy(entity: Entity?): Int { - val baseLevel = entity!!.skills.getStaticLevel(Skills.MAGIC) - var spellRequirement = baseLevel - if (entity is Player) { - if (entity.getProperties().spell != null) { - spellRequirement = entity.getProperties().spell.level - } else if (entity.getProperties().autocastSpell != null) { - spellRequirement = entity.getProperties().autocastSpell.level + entity ?: return 0 + + val styleAttackBonus = entity.properties.bonuses[WeaponInterface.BONUS_MAGIC] + 64 + when (entity) { + is Player -> { + var effectiveMagicLevel = entity.skills.getLevel(Skills.MAGIC, true).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveMagicLevel = floor(effectiveMagicLevel + (entity.prayer.getSkillBonus(Skills.MAGIC) * effectiveMagicLevel)) + effectiveMagicLevel += 8 + effectiveMagicLevel *= getSetMultiplier(entity, Skills.MAGIC) + effectiveMagicLevel = floor(effectiveMagicLevel) + + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveMagicLevel *= styleAttackBonus + else effectiveMagicLevel *= 64 + + return effectiveMagicLevel.toInt() + } + is NPC -> { + val magicLevel = entity.skills.getLevel(Skills.MAGIC) + 9 + return magicLevel * styleAttackBonus } } - var spellBonus = 0.0 - if (baseLevel > spellRequirement) { - spellBonus = (baseLevel - spellRequirement) * .3 - } - val level = entity.skills.getLevel(Skills.MAGIC, true) - var prayer = 1.0 - if (entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) { - prayer += entity.prayer.getSkillBonus(Skills.MAGIC) - } - val additional = getSetMultiplier(entity, Skills.MAGIC) - val effective = floor(level * prayer * additional + spellBonus) - val bonus = - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) - entity.properties.bonuses[WeaponInterface.BONUS_MAGIC] - else 0 - return floor((effective + 8) * (bonus + 64) / 10).toInt() + + return 0 } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { @@ -183,14 +185,32 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) } override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { - val level = victim!!.skills.getLevel(Skills.DEFENCE, true) - var prayer = 1.0 - if (victim is Player) { - prayer += victim.prayer.getSkillBonus(Skills.MAGIC) + victim ?: return 0 + attacker ?: return 0 + + val styleDefenceBonus = victim.properties.bonuses[WeaponInterface.BONUS_MAGIC + 5] + 64 + when (victim) { + is Player -> { + var effectiveDefenceLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefenceLevel = floor(effectiveDefenceLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefenceLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefenceLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 + effectiveDefenceLevel *= getSetMultiplier(victim, Skills.DEFENCE) + + var effectiveMagicLevel = victim.skills.getLevel(Skills.MAGIC).toDouble() + effectiveMagicLevel = floor(effectiveMagicLevel + (victim.prayer.getSkillBonus(Skills.MAGIC) * effectiveMagicLevel)) + + effectiveDefenceLevel = effectiveDefenceLevel * 0.3 + effectiveMagicLevel * 0.7 + 8 + effectiveDefenceLevel *= familiarDefenceBonus(victim) + return effectiveDefenceLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.MAGIC) + 9 + return defLevel * styleDefenceBonus + } } - val effective = floor(level * prayer * 0.3) + victim.skills.getLevel(Skills.MAGIC, true) * 0.7 - val equipment = victim.properties.bonuses[WeaponInterface.BONUS_MAGIC + 5] - return floor((effective + 8) * (equipment + 64) / 10).toInt() + + return 0 } override fun getSetMultiplier(e: Entity?, skillId: Int): Double { @@ -202,6 +222,20 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) return 1.0 } + /** + * Check to see whether the player is receiving a defensive bonus from an active familiar. + * - Wolpertinger => +5% + */ + private fun familiarDefenceBonus(e: Entity?): Double { + if (e !is Player) return 1.0 + val fam = try { + e.familiarManager?.familiar + } catch (ex: Exception) { + null + } ?: return 1.0 + return if (fam.pouchId == SummoningPouch.WOLPERTINGER_POUCH.pouchId) 1.05 else 1.0 + } + override fun addExperience(entity: Entity?, victim: Entity?, state: BattleState?) { if (state?.spell != null && entity is Player) { state.spell.addExperience(entity, state.totalDamage) diff --git a/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt index d755c269d..7f9b668d8 100644 --- a/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt @@ -3,6 +3,8 @@ package core.game.node.entity.combat import content.global.skill.skillcapeperks.SkillcapePerks import content.global.skill.slayer.SlayerEquipmentFlags import content.global.skill.slayer.SlayerManager +import content.global.skill.slayer.Tasks +import content.global.skill.summoning.SummoningPouch import core.api.* import core.api.EquipmentSlot import core.game.container.impl.EquipmentContainer @@ -29,34 +31,34 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) * Constructs a new `MeleeSwingHandler` {@Code Object}. */ : CombatSwingHandler(CombatStyle.MELEE, *flags) { - override fun canSwing(entity: Entity, victim: Entity): InteractionType? { - //Credits wolfenzi, https://www.rune-server.ee/2009scape-development/rs2-server/snippets/608720-arios-hybridding-improve.html - var distance = if (usingHalberd(entity)) 2 else 1 - var type = InteractionType.STILL_INTERACT - var goodRange = canMelee(entity, victim, distance) - if (!goodRange && victim.properties.combatPulse.getVictim() !== entity && victim.walkingQueue.isMoving && entity.size() == 1) { - type = InteractionType.MOVE_INTERACT - distance += if (entity.walkingQueue.isRunningBoth) 2 else 1 - goodRange = canMelee(entity, victim, distance) - } - if (!isProjectileClipped(entity, victim, !usingHalberd(entity))) { - return InteractionType.NO_INTERACT - } - val isRunning = entity.walkingQueue.runDir != -1 - val enemyRunning = victim.walkingQueue.runDir != -1 - // THX 4 fix tom <333. - if (super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { - val maxDistance = if (isRunning) if (enemyRunning) 3 else 4 else 2 - if (entity.walkingQueue.isMoving - && entity.location.getDistance(victim.location) <= maxDistance) { - return type - } else if (goodRange) { - if (type == InteractionType.STILL_INTERACT) entity.walkingQueue.reset() - return type - } - } - return InteractionType.NO_INTERACT - } + override fun canSwing(entity : Entity, victim : Entity) : InteractionType? { + //Credits wolfenzi, https://www.rune-server.ee/2009scape-development/rs2-server/snippets/608720-arios-hybridding-improve.html + var distance = if (usingHalberd(entity)) 2 else 1 + var type = InteractionType.STILL_INTERACT + var goodRange = canMelee(entity, victim, distance) + if (!goodRange && victim.properties.combatPulse.getVictim() !== entity && victim.walkingQueue.isMoving && entity.size() == 1) { + type = InteractionType.MOVE_INTERACT + distance += if (entity.walkingQueue.isRunningBoth) 2 else 1 + goodRange = canMelee(entity, victim, distance) + } + if (!isProjectileClipped(entity, victim, !usingHalberd(entity))) { + return InteractionType.NO_INTERACT + } + val isRunning = entity.walkingQueue.runDir != -1 + val enemyRunning = victim.walkingQueue.runDir != -1 + // THX 4 fix tom <333. + if (super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { + val maxDistance = if (isRunning) if (enemyRunning) 3 else 4 else 2 + if (entity.walkingQueue.isMoving && entity.location.getDistance(victim.location) <= maxDistance && goodRange) { + return type + } else if (goodRange) { + if (canStepTowards(entity, victim) == InteractionType.NO_INTERACT) return InteractionType.NO_INTERACT + if (type == InteractionType.STILL_INTERACT) entity.walkingQueue.reset() + return type + } + } + return InteractionType.NO_INTERACT + } override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { var hit = 0 @@ -64,11 +66,14 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) if (entity is Player) { state.weapon = Weapon(entity.equipment[3]) } - if (entity!!.properties.armourSet === ArmourSet.VERAC && RandomFunction.random(100) < 21) { + if (entity!!.properties.armourSet == ArmourSet.VERAC && RandomFunction.roll(4)) { state.armourEffect = ArmourSet.VERAC } - if (state.armourEffect === ArmourSet.VERAC || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { - val max = calculateHit(entity, victim, 1.0) + if (state.armourEffect == ArmourSet.VERAC || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + var max = calculateHit(entity, victim, 1.0) + if (victim != null) { + if (entity is NPC && state.armourEffect == ArmourSet.VERAC && victim.hasProtectionPrayer(CombatStyle.MELEE)) max = max * 2 / 3 + } state.maximumHit = max hit = RandomFunction.random(max + 1) } @@ -111,16 +116,23 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) val name = entity.equipment.getNew(3).name var damage = -1 if (name.contains("(p++") || name.contains("(s)") || name.contains("(kp)")) { - damage = 68 + damage = 30 } else if (name.contains("(p+)")) { - damage = 58 + damage = 25 } else if (name.contains("(p)")) { - damage = 48 + damage = 20 } if (damage > -1 && RandomFunction.random(10) < 4) { applyPoison (victim, entity, damage) } } + } else if (entity is NPC) { + val poisonous = entity.isPoisonous + val damage = entity.poisonSeverity() + + if (poisonous && damage > -1 && RandomFunction.random(10) < 4) { + applyPoison (victim, entity, damage) + } } super.adjustBattleState(entity, victim, state) } @@ -128,68 +140,86 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) override fun calculateAccuracy(entity: Entity?): Int { //formula taken from wiki: https://oldschool.runescape.wiki/w/Damage_per_second/Melee#Step_six:_Calculate_the_hit_chance Yes I know it's old school. It's the best resource we have for potentially authentic formulae. entity ?: return 0 - var effectiveAttackLevel = entity.skills.getLevel(Skills.ATTACK).toDouble() - if(entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) - effectiveAttackLevel = floor(effectiveAttackLevel + (entity.prayer.getSkillBonus(Skills.ATTACK) * effectiveAttackLevel)) - if(entity.properties.attackStyle.style == WeaponInterface.STYLE_ACCURATE) effectiveAttackLevel += 3 - else if(entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveAttackLevel += 1 - effectiveAttackLevel += 8 - if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.PRECISION_STRIKES, entity)){ //Attack skillcape perk - effectiveAttackLevel += 6 - } - effectiveAttackLevel *= getSetMultiplier(entity, Skills.ATTACK) - effectiveAttackLevel = floor(effectiveAttackLevel) - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) - effectiveAttackLevel *= (entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64) - else effectiveAttackLevel *= 64 + val styleAttackBonus = entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64 + when (entity) { + is Player -> { + var effectiveAttackLevel = entity.skills.getLevel(Skills.ATTACK).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveAttackLevel = floor(effectiveAttackLevel + (entity.prayer.getSkillBonus(Skills.ATTACK) * effectiveAttackLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_ACCURATE) effectiveAttackLevel += 3 + else if(entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveAttackLevel += 1 + effectiveAttackLevel += 8 + if(SkillcapePerks.isActive(SkillcapePerks.PRECISION_STRIKES, entity)){ //Attack skillcape perk + effectiveAttackLevel += 6 + } + effectiveAttackLevel *= getSetMultiplier(entity, Skills.ATTACK) + effectiveAttackLevel = floor(effectiveAttackLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveAttackLevel *= styleAttackBonus + else effectiveAttackLevel *= 64 - val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none" + val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none" - // attack bonus for specialized equipments (salve amulets, slayer equips) - if (entity is Player) { - val amuletId = getItemFromEquipment(entity, EquipmentSlot.NECK)?.id ?: 0 - if ((amuletId == Items.SALVE_AMULET_4081 || amuletId == Items.SALVE_AMULETE_10588) && checkUndead(victimName)) { - effectiveAttackLevel *= if (amuletId == Items.SALVE_AMULET_4081) 1.15 else 1.2 - } else if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) { - effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape - if (getSlayerTask(entity)?.dragon == true && inEquipment(entity, Items.DRAGON_SLAYER_GLOVES_12862)) - effectiveAttackLevel *= 1.1 + // attack bonus for specialized equipments (salve amulets, slayer equips) + val amuletId = getItemFromEquipment(entity, EquipmentSlot.NECK)?.id ?: 0 + if ((amuletId == Items.SALVE_AMULET_4081 || amuletId == Items.SALVE_AMULETE_10588) && checkUndead(victimName)) { + effectiveAttackLevel *= if (amuletId == Items.SALVE_AMULET_4081) 1.15 else 1.2 + } else if (getSlayerTask(entity)?.let { task -> + val victimId = entity.properties.combatPulse?.getVictim()?.id ?: 0 + task.ids.contains(victimId) || (task == Tasks.KALPHITES && (victimId == 1158)) // Kalphite Queen phase 1 + } == true) { + effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape + if (getSlayerTask(entity)?.dragon == true && inEquipment(entity, Items.DRAGON_SLAYER_GLOVES_12862)) + effectiveAttackLevel *= 1.1 + } + + return effectiveAttackLevel.toInt() + } + is NPC -> { + val attackLevel = entity.skills.getLevel(Skills.ATTACK) + 9 + return attackLevel * styleAttackBonus } } - return floor(effectiveAttackLevel).toInt() + return 0 + + } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { - val level = entity!!.skills.getLevel(Skills.STRENGTH) - var bonus = entity.properties.bonuses[11] - var prayer = 1.0 - if (entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) { - prayer += entity.prayer.getSkillBonus(Skills.STRENGTH) - } - var cumulativeStr = floor(level * prayer) - if (entity.properties.attackStyle.style == WeaponInterface.STYLE_AGGRESSIVE) { - cumulativeStr += 3.0 - } else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) { - cumulativeStr += 1.0 + entity ?: return 0 + + var styleStrengthBonus = entity.properties.bonuses[11] + 64 + when (entity) { + is Player -> { + var effectiveStrengthLevel = entity.skills.getLevel(Skills.STRENGTH).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) + effectiveStrengthLevel = floor(effectiveStrengthLevel + (entity.prayer.getSkillBonus(Skills.STRENGTH) * effectiveStrengthLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_AGGRESSIVE) effectiveStrengthLevel += 3 + else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveStrengthLevel += 1 + effectiveStrengthLevel += 8 + effectiveStrengthLevel *= getSetMultiplier(entity, Skills.STRENGTH) + effectiveStrengthLevel = floor(effectiveStrengthLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) + effectiveStrengthLevel *= styleStrengthBonus + else effectiveStrengthLevel *= 64 + if (getSlayerTask(entity)?.let { task -> + val victimId = entity.properties.combatPulse?.getVictim()?.id ?: 0 + task.ids.contains(victimId) || (task == Tasks.KALPHITES && (victimId == 1158)) // Kalphite Queen phase 1 + } == true) { + effectiveStrengthLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape + } + + return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt() + } + is NPC -> { + val strengthLevel = entity.skills.getLevel(Skills.STRENGTH) + 9 + return (floor((0.5 + (strengthLevel * styleStrengthBonus / 640.0))) * modifier).toInt() + } } - //Strength skillcape perk - if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.FINE_ATTUNEMENT, entity) && getItemFromEquipment(entity, EquipmentSlot.WEAPON)?.definition?.getRequirement(Skills.STRENGTH) != 0) - bonus = ceil(bonus * 1.20).toInt() - - if (flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) - bonus = 0 - - cumulativeStr *= getSetMultiplier(entity, Skills.STRENGTH) - - if(entity is Player && getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) - cumulativeStr *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer helm/black mask/skillcape - - /*val hit = (16 + cumulativeStr + bonus / 8 + cumulativeStr * bonus * 0.016865) * modifier - return (hit / 10).toInt() + 1*/ - return ((1.3 + (cumulativeStr / 10) + (bonus / 80) + ((cumulativeStr * bonus) / 640)) * modifier).toInt() + return 0 } override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { @@ -197,19 +227,20 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) victim ?: return 0 attacker ?: return 0 - when(victim){ + val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 + when (victim) { is Player -> { var effectiveDefenceLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() effectiveDefenceLevel = floor(effectiveDefenceLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefenceLevel)) - if(victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE) effectiveDefenceLevel += 3 - else if(victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefenceLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 effectiveDefenceLevel += 8 - effectiveDefenceLevel = floor(effectiveDefenceLevel) - return floor(effectiveDefenceLevel * (victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64)).toInt() + effectiveDefenceLevel *= getSetMultiplier(victim, Skills.DEFENCE) + effectiveDefenceLevel *= familiarDefenceBonus(victim) + return effectiveDefenceLevel.toInt() * styleDefenceBonus } is NPC -> { - val defLevel = victim.skills.getLevel(Skills.DEFENCE) - val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 + val defLevel = victim.skills.getLevel(Skills.DEFENCE) + 9 return defLevel * styleDefenceBonus } } @@ -222,10 +253,14 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) return 1.0 + (e!!.skills.maximumLifepoints - e.skills.lifepoints) * 0.01 } + var multiplier = 1.0 if(e is Player && e.isWearingVoid(CombatStyle.MELEE) && (skillId == Skills.ATTACK || skillId == Skills.STRENGTH)) { - return 1.1 + multiplier += 0.1 } - return 1.0 + if (e is Player && e.properties.armourSet === ArmourSet.BERSERKER_NECKLACE_SETS && skillId == Skills.STRENGTH) { + multiplier += 0.2 + } + return multiplier } override fun getArmourSet(e: Entity?): ArmourSet? { @@ -238,6 +273,9 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) if (ArmourSet.VERAC.isUsing(e)) { return ArmourSet.VERAC } + if (ArmourSet.BERSERKER_NECKLACE_SETS.isUsing(e)) { + return ArmourSet.BERSERKER_NECKLACE_SETS + } return if (ArmourSet.TORAG.isUsing(e)) { ArmourSet.TORAG } else super.getArmourSet(e) @@ -253,6 +291,25 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) || name == "Skeleton" || name == "Zogre" || name == "Spiritual Mage") } + /** + * Check to see whether the player is receiving a defensive bonus from an active familiar. + * - Iron Titan => +10% + * - Steel Titan => +15% + */ + private fun familiarDefenceBonus(e: Entity?): Double { + if (e !is Player) return 1.0 + val fam = try { + e.familiarManager?.familiar + } catch (ex: Exception) { + null + } ?: return 1.0 + return when (fam.pouchId) { + SummoningPouch.IRON_TITAN_POUCH.pouchId -> 1.10 + SummoningPouch.STEEL_TITAN_POUCH.pouchId -> 1.15 + else -> 1.0 + } + } + companion object { /** * Checks if the entity is using a halberd. diff --git a/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt index 41ac8dca3..a3d6d5fec 100644 --- a/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt @@ -8,7 +8,7 @@ import core.tools.RandomFunction /** * Handles combat swings with switching combat styles. * @author Emperor - * @author Ceirky, Kotlin conversion + * @author Ceikry, Kotlin conversion */ open class MultiSwingHandler(meleeDistance: Boolean, vararg attacks: SwitchAttack) : CombatSwingHandler(CombatStyle.RANGE) { /** @@ -27,7 +27,7 @@ open class MultiSwingHandler(meleeDistance: Boolean, vararg attacks: SwitchAttac protected var current: SwitchAttack /** - * The current attack. + * The next attack. */ protected var next: SwitchAttack @@ -119,6 +119,9 @@ open class MultiSwingHandler(meleeDistance: Boolean, vararg attacks: SwitchAttac override fun addExperience(entity: Entity?, victim: Entity?, state: BattleState?) { current.handler.addExperience(entity, victim, state) } + override fun postSwing(entity: Entity?, victim: Entity?, state: BattleState?) { + current.handler.postSwing(entity, victim, state) + } override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { if (current.isUseHandler) { current.handler.visualizeImpact(entity, victim, state) diff --git a/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt index 325dd3f78..5eeed5f21 100644 --- a/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt @@ -1,6 +1,7 @@ package core.game.node.entity.combat import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.skill.summoning.SummoningPouch import core.api.* import core.game.container.impl.EquipmentContainer import core.game.node.entity.Entity @@ -13,14 +14,14 @@ import core.game.node.entity.skill.Skills import core.game.node.item.GroundItem import core.game.node.item.GroundItemManager import core.game.node.item.Item +import core.game.system.config.ItemConfigParser import core.game.system.task.Pulse +import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.map.RegionManager import core.game.world.update.flag.context.Graphics -import core.tools.RandomFunction -import core.tools.SystemLogger -import core.game.world.GameWorld import core.tools.Log +import core.tools.RandomFunction import java.util.* import kotlin.math.ceil import kotlin.math.floor @@ -30,11 +31,10 @@ import kotlin.math.floor * @author Emperor * @author Ceikry, conversion to Kotlin + cleanup */ -open class RangeSwingHandler (vararg flags: SwingHandlerFlag) +open class RangeSwingHandler (vararg flags: SwingHandlerFlag) : CombatSwingHandler(CombatStyle.RANGE, *flags) { /** * Constructs a new `RangeSwingHandler` {@Code Object}. */ - : CombatSwingHandler(CombatStyle.RANGE, *flags) { override fun canSwing(entity: Entity, victim: Entity): InteractionType? { if (!isProjectileClipped(entity, victim, false)) { return InteractionType.NO_INTERACT @@ -75,15 +75,24 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) return -1 } var hit = 0 - if (isAccurateImpact(entity, victim, CombatStyle.RANGE)) { - val max = calculateHit(entity, victim, 1.0).also { if(entity?.name?.toLowerCase() == "test10") log(this::class.java, Log.FINE, "Damage: $it") } + val armourPierce = state.ammunition != null && state.ammunition.effect != null && state.ammunition.effect == BoltEffect.DIAMOND && state.ammunition.effect.canFire(state) + if (armourPierce || isAccurateImpact(entity, victim, CombatStyle.RANGE)) { + val max: Int + if (armourPierce) { + state.ammunition.effect.impact(state) + flags.add(SwingHandlerFlag.IGNORE_STAT_REDUCTION) + max = (calculateHit(entity, victim, 1.0) * 1.15).toInt() + flags.remove(SwingHandlerFlag.IGNORE_STAT_REDUCTION) + } else { + max = calculateHit(entity, victim, 1.0) + } state.maximumHit = max hit = RandomFunction.random(max + 1) } state.estimatedHit = hit if (state.weapon.type == WeaponType.DOUBLE_SHOT) { if (isAccurateImpact(entity, victim, CombatStyle.RANGE)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)) + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1) } state.secondaryHit = hit } @@ -92,10 +101,15 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) } if(state.estimatedHit > victim.skills.lifepoints) state.estimatedHit = victim.skills.lifepoints if(state.estimatedHit + state.secondaryHit > victim.skills.lifepoints) state.secondaryHit -= ((state.estimatedHit + state.secondaryHit) - victim.skills.lifepoints) - useAmmo(entity, state, victim.location) return 1 + ceil(entity.location.getDistance(victim.location) * 0.3).toInt() } + override fun postSwing(entity: Entity?, victim: Entity?, state: BattleState?) { + // Using the last piece of ammo in swing causes experience calculations to assume we're using unarmed combat + // which gives wrong experience values. Delay ammo consumption until later to avoid this problem. + useAmmo(entity!!, state!!, victim!!.location) + } + /** * Configures the range data. * @param entity The entity. @@ -124,6 +138,13 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) if (state.ammunition != null && entity is Player) { val damage = state.ammunition.poisonDamage if (state.estimatedHit > 0 && damage > 8 && RandomFunction.random(10) < 4) { + applyPoison(victim, entity, damage) + } + } else if (entity is NPC) { + val poisonous = entity.isPoisonous + val damage = entity.poisonSeverity() + + if (poisonous && damage > -1 && RandomFunction.random(10) < 4) { applyPoison (victim, entity, damage) } } @@ -161,7 +182,7 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) } override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { - if (state!!.ammunition != null && state.ammunition.effect != null && state.ammunition.effect.canFire(state)) { + if (state!!.ammunition != null && state.ammunition.effect != null && state.ammunition.effect != BoltEffect.DIAMOND && state.ammunition.effect.canFire(state)) { state.ammunition.effect.impact(state) } val hit = state.estimatedHit @@ -183,56 +204,100 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) override fun calculateAccuracy(entity: Entity?): Int { entity ?: return 0 - var effectiveRangedLevel = entity.skills.getLevel(Skills.RANGE).toDouble() - if(entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) - effectiveRangedLevel = floor(effectiveRangedLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveRangedLevel)) - if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveRangedLevel += 3 - effectiveRangedLevel += 8 - effectiveRangedLevel *= getSetMultiplier(entity, Skills.RANGE) - if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.ACCURATE_MARKSMAN,entity)) effectiveRangedLevel *= 1.1 - effectiveRangedLevel = floor(effectiveRangedLevel) - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) - effectiveRangedLevel *= (entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64) - else effectiveRangedLevel *= 64 + val styleAttackBonus = entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64 + when (entity) { + is Player -> { + var effectiveRangedLevel = entity.skills.getLevel(Skills.RANGE).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveRangedLevel = floor(effectiveRangedLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveRangedLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveRangedLevel += 3 + effectiveRangedLevel += 8 + effectiveRangedLevel += familiarOffenceBonus(entity) + effectiveRangedLevel *= getSetMultiplier(entity, Skills.RANGE) + if(SkillcapePerks.isActive(SkillcapePerks.ACCURATE_MARKSMAN,entity)) effectiveRangedLevel *= 1.1 - return floor(effectiveRangedLevel).toInt() + effectiveRangedLevel = floor(effectiveRangedLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveRangedLevel *= styleAttackBonus + else effectiveRangedLevel *= 64 + + return effectiveRangedLevel.toInt() + } + is NPC -> { + val rangedLevel = entity.skills.getLevel(Skills.RANGE) + 9 + return rangedLevel * styleAttackBonus + } + } + + return 0 } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { - val level = entity!!.skills.getLevel(Skills.RANGE) - val bonus = entity.properties.bonuses[14] - var prayer = 1.0 - if (entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) { - prayer += entity.prayer.getSkillBonus(Skills.RANGE) - } - var cumulativeStr = floor(level * prayer) - if (entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) { - cumulativeStr += 3.0 - } - cumulativeStr *= getSetMultiplier(entity, Skills.RANGE) + entity ?: return 0 - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) - cumulativeStr *= (bonus + 64) - else cumulativeStr *= 64 + var styleStrengthBonus = entity.properties.bonuses[14] + 64 + when (entity) { + is Player -> { + if(entity.equipment[EquipmentContainer.SLOT_WEAPON] != null && RangeWeapon.get(entity.equipment[EquipmentContainer.SLOT_WEAPON].id).ammunitionSlot != EquipmentContainer.SLOT_ARROWS && entity.equipment[EquipmentContainer.SLOT_ARROWS] != null) + styleStrengthBonus -= entity.equipment[EquipmentContainer.SLOT_ARROWS].definition.getConfiguration(ItemConfigParser.BONUS)[14] + var effectiveStrengthLevel = entity.skills.getLevel(Skills.RANGE).toDouble() + if (flags.contains(SwingHandlerFlag.IGNORE_STAT_REDUCTION)) { + val staticLevel = entity.skills.getStaticLevel(Skills.RANGE).toDouble() + if (staticLevel > effectiveStrengthLevel) { + effectiveStrengthLevel = staticLevel + } + } + if (!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) + effectiveStrengthLevel = floor(effectiveStrengthLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveStrengthLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveStrengthLevel += 3 + effectiveStrengthLevel += 8 + effectiveStrengthLevel += familiarOffenceBonus(entity) + effectiveStrengthLevel *= getSetMultiplier(entity, Skills.RANGE) + effectiveStrengthLevel = floor(effectiveStrengthLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) + effectiveStrengthLevel *= styleStrengthBonus + else effectiveStrengthLevel *= 64 - return floor((1.5 + (ceil(cumulativeStr) / 640.0)) * modifier).toInt() - //return ((14 + cumulativeStr + bonus / 8 + cumulativeStr * bonus * 0.016865) * modifier).toInt() / 10 + 1 + return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt() + } + is NPC -> { + val rangedLevel = entity.skills.getLevel(Skills.RANGE) + 9 + return (floor((0.5 + (rangedLevel * styleStrengthBonus / 640.0))) * modifier).toInt() + } + } + + return 0 } override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { victim ?: return 0 attacker ?: return 0 - val defLevel = victim.skills.getLevel(Skills.DEFENCE) val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 - return defLevel * styleDefenceBonus + when (victim) { + is Player -> { + var effectiveDefLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefLevel = floor(effectiveDefLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefLevel += 1 + effectiveDefLevel += 8 + effectiveDefLevel *= getSetMultiplier(victim, Skills.DEFENCE) + return effectiveDefLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.DEFENCE) + 9 + return defLevel * styleDefenceBonus + } + } + + return 0 } override fun getSetMultiplier(e: Entity?, skillId: Int): Double { if(skillId == Skills.RANGE) { if(e is Player && e.isWearingVoid(CombatStyle.RANGE)) { - return 1.1 + return 1.2 } } return 1.0 @@ -244,6 +309,22 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) } else super.getArmourSet(e) } + /** + * Check to see whether the player is receiving an offensive bonus from an active familiar. + * - Geyser Titan => 1 + 3% of ranged level + */ + private fun familiarOffenceBonus(e: Entity?): Double { + if (e !is Player) return 0.0 + val fam = try { + e.familiarManager?.familiar + } catch (ex: Exception) { + null + } ?: return 0.0 + return if (fam.pouchId == SummoningPouch.GEYSER_TITAN_POUCH.pouchId) { + 1.0 + ceil(e.skills.getLevel(Skills.RANGE) * 0.03) + } else 0.0 + } + companion object { /** * Checks if the entity has the ammunition needed to proceed. diff --git a/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java b/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java index 33461f024..a7b895166 100644 --- a/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java +++ b/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java @@ -74,7 +74,7 @@ public final class Ammunition { * Loads all the {@code Ammunition} info to the mapping. * @return {@code True}. */ - public static final boolean initialize() { + public static boolean initialize() { Document doc; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -141,7 +141,7 @@ public final class Ammunition { * @param id The ammo id. * @return The ammunition object. */ - public static final Ammunition get(int id) { + public static Ammunition get(int id) { return AMMUNITION.get(id); } @@ -189,7 +189,7 @@ public final class Ammunition { } /** - * Sets the baeffect. + * Sets the effect. * @param effect the effect to set. */ public void setEffect(BoltEffect effect) { diff --git a/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java b/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java index 16097c032..5b7a7e3af 100644 --- a/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java +++ b/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java @@ -8,6 +8,7 @@ import core.game.node.entity.player.Player; import core.game.node.item.Item; import core.game.world.update.flag.context.Graphics; import core.tools.RandomFunction; +import org.rs09.consts.Items; /** * Represents the types of armour sets. @@ -21,7 +22,7 @@ public enum ArmourSet { AHRIM(new Graphics(401, 96), new int[][] { { 4708, 4856, 4857, 4858, 4859 }, { 4710, 4862, 4863, 4864, 4865 }, { 4712, 4868, 4869, 4870, 4871 }, { 4714, 4874, 4875, 4876, 4877 } }) { @Override public boolean effect(Entity e, Entity victim, BattleState state) { - if (RandomFunction.random(100) < 20) { + if (RandomFunction.random(100) < 25 && state.getEstimatedHit() > -1) { victim.getSkills().updateLevel(Skills.STRENGTH, -5, 0); return true; } @@ -78,8 +79,8 @@ public enum ArmourSet { KARIL(new Graphics(400, 96), new int[][] { { 4732, 4928, 4929, 4930, 4931 }, { 4734, 4934, 4935, 4936, 4937 }, { 4736, 4940, 4941, 4942, 4943 }, { 4738, 4946, 4947, 4948, 4949 } }) { @Override public boolean effect(Entity e, Entity victim, BattleState state) { - if (state.getEstimatedHit() > 9 && RandomFunction.random(100) < 20) { - victim.getSkills().updateLevel(Skills.AGILITY, -(state.getEstimatedHit() / 10), 0); + if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 25) { + victim.getSkills().updateLevel(Skills.AGILITY, -(victim.getSkills().getDynamicLevels()[Skills.AGILITY] / 5), 0); return true; } return false; @@ -100,7 +101,7 @@ public enum ArmourSet { TORAG(new Graphics(399, 96), new int[][] { { 4745, 4952, 4953, 4954, 4955 }, { 4747, 4958, 4959, 4960, 4961 }, { 4749, 4964, 4965, 4966, 4967 }, { 4751, 4970, 4971, 4972, 4973 } }) { @Override public boolean effect(Entity e, Entity victim, BattleState state) { - if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 20) { + if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 25) { if (victim instanceof Player) { ((Player) victim).getSettings().updateRunEnergy(20); } @@ -129,6 +130,15 @@ public enum ArmourSet { } return super.isUsing(e); } + }, + /** + * Berserker Necklace sets + */ + BERSERKER_NECKLACE_SETS(null, new int[][] { { Items.BERSERKER_NECKLACE_11128 }, { Items.TOKTZ_XIL_AK_6523, Items.TOKTZ_XIL_EK_6525, Items.TZHAAR_KET_EM_6527, Items.TZHAAR_KET_OM_6528 } }) { + @Override + public boolean isUsing(Entity e) { + return super.isUsing(e); + } }; /** @@ -148,8 +158,9 @@ public enum ArmourSet { */ private ArmourSet(Graphics endGraphic, int[][] set) { this.endGraphic = endGraphic; - this.sets = new Item[4][5]; + this.sets = new Item[set.length][]; for (int i = 0; i < set.length; i++) { + sets[i] = new Item[set[i].length]; for (int k = 0; k < sets[i].length; k++) { sets[i][k] = new Item(set[i][k]); } @@ -197,7 +208,7 @@ public enum ArmourSet { } } } - return hits == 4; + return hits == sets.length; } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java b/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java index eabede5ff..71d26d8b6 100644 --- a/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java +++ b/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java @@ -21,7 +21,6 @@ import static core.api.ContentAPIKt.*; */ public enum BoltEffect { OPAL(9236, Graphics.create(749), new Audio(2918)) { - @Override public void impact(BattleState state) { state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(3, 20)); @@ -33,7 +32,6 @@ public enum BoltEffect { }, JADE(9237, new Graphics(755), new Audio(2916)) { - @Override public void impact(BattleState state) { if (state.getVictim() instanceof Player) { @@ -59,7 +57,6 @@ public enum BoltEffect { }, PEARL(9238, Graphics.create(750), new Audio(2920)) { - @Override public void impact(BattleState state) { state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(3, 20)); @@ -108,12 +105,11 @@ public enum BoltEffect { EMERALD(9241, new Graphics(752), new Audio(2919)) { @Override public void impact(BattleState state) { - applyPoison(state.getVictim(), state.getAttacker(), 40); + applyPoison(state.getVictim(), state.getAttacker(), 40); super.impact(state); } }, RUBY(9242, new Graphics(754), new Audio(2911, 1)) { // in this case, volume is the number of times to play the sound... - @Override public void impact(BattleState state) { // hit target for 20% of their HP, hit self for 10% of HP int victimPoints = (int) (state.getVictim().getSkills().getLifepoints() * 0.20); @@ -135,15 +131,8 @@ public enum BoltEffect { return super.canFire(state) && state.getAttacker().getSkills().getLifepoints() - playerPoints >= 1; } }, - DIAMOND(9243, new Graphics(758), new Audio(2913)) { - @Override - public void impact(BattleState state) { - state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(5, 14)); // unauthentic, needs fixing - super.impact(state); - } - }, + DIAMOND(9243, new Graphics(758), new Audio(2913)) { /* handled in RangeSwingHandler.kt::swing(entity: Entity?, victim: Entity?, state: BattleState?) */ }, DRAGON(9244, new Graphics(756), new Audio(2915)) { - @Override public void impact(BattleState state) { state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(17, 29)); @@ -165,10 +154,8 @@ public enum BoltEffect { } return super.canFire(state); } - }, ONYX(9245, new Graphics(753), new Audio(2917)) { - @Override public void impact(BattleState state) { int newDamage = (int) (state.getEstimatedHit() * 0.25); @@ -239,14 +226,22 @@ public enum BoltEffect { victim.graphics(graphics); } } - + /** * Checks if the effect can fire. + * * @param state the state. + * * @return {@code True} if so. */ public boolean canFire(BattleState state) { - return RandomFunction.random(13) == 5; + // Never fires on slayer monster that player lacks level requirement for. Inauthentic(?) + // and should be considered a TODO: temporary abuse prevention measure (bolt effect on slayer monsters) + boolean rollSuccess = RandomFunction.random(13) == 5; + if (!(state.getVictim() instanceof NPC)) return rollSuccess; + if (!(state.getAttacker() instanceof Player) || ((NPC) state.getVictim()).getTask() == null) return rollSuccess; + if (state.getVictim().asNpc().getTask().levelReq > state.getAttacker().asPlayer().getSkills().getLevel(Skills.SLAYER)) return false; + return rollSuccess; } /** @@ -270,5 +265,4 @@ public enum BoltEffect { public int getItemId() { return itemId; } - } diff --git a/Server/src/main/core/game/node/entity/combat/graves/Grave.kt b/Server/src/main/core/game/node/entity/combat/graves/Grave.kt index efd2f9b17..e330489a9 100644 --- a/Server/src/main/core/game/node/entity/combat/graves/Grave.kt +++ b/Server/src/main/core/game/node/entity/combat/graves/Grave.kt @@ -1,5 +1,6 @@ package core.game.node.entity.combat.graves +import content.global.handlers.item.equipment.BarrowsEquipment import core.api.clearHintIcon import core.api.registerHintIcon import core.api.sendMessage @@ -49,7 +50,7 @@ class Grave : AbstractNPC { this.ownerUid = player.details.uid this.ownerUsername = player.username - this.location = location + this.location = player.getAttribute("/save:original-loc",location) this.isRespawn = false this.isWalks = false this.isNeverWalks = true @@ -65,7 +66,11 @@ class Grave : AbstractNPC { continue } - val finalItem = GraveController.checkTransform(item) + val finalItem = if (BarrowsEquipment.isBarrowsItem(item.id) && !BarrowsEquipment.isFullyRepaired(item.id)) { + BarrowsEquipment.graveDeathDurabilityReduction(item) ?: item + } else { + GraveController.checkTransform(item) + } val gi = GroundItemManager.create(finalItem, this.location, player) gi.isRemainPrivate = true diff --git a/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt b/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt index a57a76562..00e0e0b1b 100644 --- a/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt +++ b/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt @@ -17,6 +17,7 @@ import org.rs09.consts.Items import core.ServerStore import core.game.interaction.InteractionListener import core.game.interaction.IntType +import core.game.interaction.QueueStrength import core.game.system.command.Privilege import core.game.world.GameWorld import core.game.world.map.zone.impl.WildernessZone @@ -36,18 +37,16 @@ class GraveController : PersistWorld, TickListener, InteractionListener, Command } override fun defineCommands() { - define("forcegravedeath", Privilege.ADMIN, "", "Forces a death that should produce a grave.") {player, _ -> + define("forcegravedeath", Privilege.ADMIN, "", "Forces a death that should produce a grave.") { player, _ -> player.details.rights = Rights.REGULAR_PLAYER setAttribute(player, "tutorial:complete", true) player.impactHandler.manualHit(player, player.skills.lifepoints, ImpactHandler.HitsplatType.NORMAL) - notify(player, "Grave created at ${player.location}") - GameWorld.Pulser.submit(object : Pulse(15) { - override fun pulse(): Boolean { - player.details.rights = Rights.ADMINISTRATOR - sendMessage(player, "Rights restored") - return true - } - }) + notify(player, "Grave created at ${player.getAttribute("/save:original-loc", player.location)}") + queueScript(player, 15, QueueStrength.SOFT) { stage: Int -> + player.details.rights = Rights.ADMINISTRATOR + sendMessage(player, "Rights restored") + return@queueScript stopExecuting(player) + } } } @@ -106,6 +105,12 @@ class GraveController : PersistWorld, TickListener, InteractionListener, Command return true } + val gOwner = Repository.uid_map[g.ownerUid] + if (gOwner != null && gOwner.ironmanManager.isIronman) { + sendMessage(player, "This grave belongs to an Ironman.") + return true + } + if (getStatLevel(player, Skills.PRAYER) < 70) { sendMessage(player, "You need a Prayer level of 70 to bless a grave.") return true @@ -125,7 +130,6 @@ class GraveController : PersistWorld, TickListener, InteractionListener, Command playAudio(player, Sounds.PRAYER_RECHARGE_2674) animate(player, 645) - val gOwner = Repository.uid_map[g.ownerUid] if (gOwner != null) { sendMessage(gOwner, colorize("%RYour grave has been blessed.")) } @@ -290,4 +294,4 @@ class GraveController : PersistWorld, TickListener, InteractionListener, Command } } } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt b/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt index fb2f2927e..86a589f17 100644 --- a/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt +++ b/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt @@ -43,7 +43,7 @@ class GravePurchaseInterface : InterfaceListener { val cost = selectedType.cost val requirement = selectedType.requiredQuest - if (requirement.isNotEmpty() && !isQuestComplete(player, requirement)) { + if (requirement != null && !isQuestComplete(player, requirement)) { sendDialogue(player, "That gravestone requires completion of $requirement.") return@on true } diff --git a/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt b/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt index 7d4f7bc5b..1a9105873 100644 --- a/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt +++ b/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt @@ -1,8 +1,9 @@ package core.game.node.entity.combat.graves import org.rs09.consts.NPCs +import content.data.Quests -enum class GraveType(val npcId: Int, val cost: Int, val durationMinutes: Int, val isMembers: Boolean, val requiredQuest: String = "", val text: String) { +enum class GraveType(val npcId: Int, val cost: Int, val durationMinutes: Int, val isMembers: Boolean, val requiredQuest: Quests? = null, val text: String) { MEM_PLAQUE(NPCs.GRAVE_MARKER_6565, 0, 2, false, text = "In memory of @name,
who died here."), FLAG(NPCs.GRAVE_MARKER_6568, 50, 2, false, text = MEM_PLAQUE.text), SMALL_GS(NPCs.GRAVESTONE_6571, 500, 2, false, text = "In loving memory of our dear friend @name,
who died in this place @mins ago."), @@ -12,9 +13,9 @@ enum class GraveType(val npcId: Int, val cost: Int, val durationMinutes: Int, va SARA_SYMBOL(NPCs.SARADOMIN_SYMBOL_6583, 50000, 4, true, text = "@name,
an enlightened servant of Saradomin,
perished in this place."), ZAM_SYMBOL(NPCs.ZAMORAK_SYMBOL_6586, 50000, 4, true, text = "@name,
a most bloodthirsty follower of Zamorak,
perished in this place."), GUTH_SYMBOL(NPCs.GUTHIX_SYMBOL_6589, 50000, 4, true, text = "@name,
who walked with the Balance of Guthix,
perished in this place."), - BAND_SYMBOL(NPCs.BANDOS_SYMBOL_6592, 50000, 4, true, requiredQuest = "Land of the Goblins", text = "@name,
a vicious warrior dedicated to Bandos,
perished in this place. "), - ARMA_SYMBOL(NPCs.ARMADYL_SYMBOL_6595, 50000, 4, true, requiredQuest = "Temple of Ikov", text = "@name,
a follower of the Law of Armadyl,
perished in this place."), - ZARO_SYMBOL(NPCs.MEMORIAL_STONE_6598, 50000, 4, true, requiredQuest = "Desert Treasure", text = "@name,
servant of the Unknown Power,
perished in this place."), + BAND_SYMBOL(NPCs.BANDOS_SYMBOL_6592, 50000, 4, true, requiredQuest = Quests.LAND_OF_THE_GOBLINS, text = "@name,
a vicious warrior dedicated to Bandos,
perished in this place. "), + ARMA_SYMBOL(NPCs.ARMADYL_SYMBOL_6595, 50000, 4, true, requiredQuest = Quests.TEMPLE_OF_IKOV, text = "@name,
a follower of the Law of Armadyl,
perished in this place."), + ZARO_SYMBOL(NPCs.MEMORIAL_STONE_6598, 50000, 4, true, requiredQuest = Quests.DESERT_TREASURE, text = "@name,
servant of the Unknown Power,
perished in this place."), ANGEL_DEATH(NPCs.MEMORIAL_STONE_6601, 500000, 5, true, text = "Ye frail mortals who gaze upon this sight,
forget not the fate of @name, once mighty, now
surrendered to the inescapable grasp of destiny.
Requiescat in pace."); companion object { diff --git a/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java b/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java index 3601d6849..30cf2f238 100644 --- a/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java +++ b/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java @@ -1,5 +1,6 @@ package core.game.node.entity.combat.spell; +import content.global.skill.summoning.familiar.Familiar; import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.combat.InteractionType; @@ -13,6 +14,7 @@ import core.game.node.entity.player.link.SpellBookManager; import core.game.node.entity.player.link.audio.Audio; import core.game.node.item.Item; import core.game.world.map.RegionManager; +import core.game.world.map.zone.impl.WildernessZone; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import org.rs09.consts.Sounds; @@ -106,27 +108,42 @@ public abstract class CombatSpell extends MagicSpell { } - /** - * Gets a list of possible targets for a multihitting spell. - * @param entity The caster of the spell. - * @param target The victim. - * @param max The max amount of victims. - * @return The list of targets. - */ - public List getMultihitTargets(Entity entity, Entity target, int max) { - List list = new ArrayList<>(20); - list.add(target); - boolean npc = target instanceof NPC; - for (Entity e : npc ? RegionManager.getSurroundingNPCs(target) : RegionManager.getSurroundingPlayers(target)) { - if (e != target && e != entity && CombatStyle.MAGIC.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { - list.add(e); + /** + * Gets a list of valid targets for a multihitting spell. + * @param entity The caster of the spell. + * @param target The primary victim. + * @param max The maximum number of extra victims that may be hit. + * @return The list of targets (the primary target is always at index 0). + */ + public List getMultihitTargets(Entity entity, Entity target, int max) { + List victims = new ArrayList<>(20); + victims.add(target); + + List surrounding = new ArrayList<>(); + surrounding.addAll(RegionManager.getSurroundingPlayers(target)); + surrounding.addAll(RegionManager.getSurroundingNPCs(target)); + + for (Entity e : surrounding) { + if (e == target || e == entity) { + continue; + } + if (CombatStyle.MAGIC.getSwingHandler().canSwing(entity, e) == InteractionType.NO_INTERACT || !e.isAttackable(entity, CombatStyle.MAGIC, false)) { + continue; + } + if (e instanceof Familiar) { + Player owner = ((Familiar) e).getOwner(); + if (owner != entity && WildernessZone.getInstance().continueAttack(entity, owner, CombatStyle.MAGIC, true)) { + victims.add(e); + } + } else { + victims.add(e); } if (--max < 1) { break; } } - return list; - } + return victims; + } /** * Visualizes the impact. @@ -235,4 +252,4 @@ public abstract class CombatSpell extends MagicSpell { return SPLASH_GRAPHIC; } -} +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java b/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java index 12059a76c..544372bba 100644 --- a/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java +++ b/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java @@ -1,8 +1,7 @@ package core.game.node.entity.combat.spell; -import core.game.component.Component; +import content.global.skill.magic.SpellUtils; import core.game.event.SpellCastEvent; -import core.game.node.entity.skill.Skills; import core.game.node.Node; import core.game.node.entity.Entity; import core.game.node.entity.combat.CombatSwingHandler; @@ -10,6 +9,7 @@ import core.game.node.entity.combat.equipment.WeaponInterface; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.SpellBookManager.SpellBook; import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.skill.Skills; import core.game.node.item.Item; import core.game.world.GameWorld; import core.game.world.update.flag.context.Animation; @@ -18,7 +18,6 @@ import core.plugin.Plugin; import core.tools.RandomFunction; import java.util.ArrayList; -import java.util.List; import static core.api.ContentAPIKt.playGlobalAudio; @@ -121,11 +120,6 @@ public abstract class MagicSpell implements Plugin { p.faceTemporary((Entity) target, 1); } if (spell.cast(p, target)) { - if (book != SpellBook.LUNAR && p.getAttribute("spell:swap", 0) != 0) { - p.removeAttribute("spell:swap"); - p.getSpellBookManager().setSpellBook(SpellBook.LUNAR); - p.getInterfaceManager().openTab(new Component(SpellBook.LUNAR.getInterfaceId())); - } if (!combatSpell) { p.getSkills().addExperience(Skills.MAGIC, spell.getExperience(p), true); } @@ -229,16 +223,17 @@ public abstract class MagicSpell implements Plugin { if (runes == null) { return true; } - List toRemove = new ArrayList<>(20); - for (Item item : runes) { - if (!hasRune(p, item, toRemove, message)) { - return false; + Item missing = SpellUtils.hasRunes(p, runes); + if (missing != null) { + if (message) { + p.getPacketDispatch().sendMessage("You don't have enough " + missing.getName() + "s to cast this spell."); } + return false; } if (remove) { - toRemove.forEach(i -> { - p.getInventory().remove(i); - }); + ArrayList toRemove = p.getAttribute("spell:runes", new ArrayList<>()); + toRemove.forEach(i -> p.getInventory().remove(i)); + p.removeAttribute("spell:runes"); } return true; } @@ -261,49 +256,6 @@ public abstract class MagicSpell implements Plugin { return true; } - /** - * Checks if the player has a rune to remove. - * @param p the player. - * @param item the item. - * @param toRemove the list of items to remove. - * @param message the message. - * @return {@code True} if so. - */ - public boolean hasRune(Player p, Item item, List toRemove, boolean message) { - if (!usingStaff(p, item.getId())) { - boolean hasBaseRune = p.getInventory().contains(item.getId(),item.getAmount()); - if(!hasBaseRune){ - int baseAmt = p.getInventory().getAmount(item.getId()); - if(baseAmt > 0){ - toRemove.add(new Item(item.getId(),p.getInventory().getAmount(item.getId()))); - } - int amtRemaining = item.getAmount() - baseAmt; - List possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(item.getId())); - for(CombinationRune r : possibleComboRunes){ - if(p.getInventory().containsItem(new Item(r.id)) && amtRemaining > 0){ - int amt = p.getInventory().getAmount(r.id); - if(amtRemaining < amt){ - toRemove.add(new Item(r.id,amtRemaining)); - amtRemaining = 0; - continue; - } - amtRemaining -= p.getInventory().getAmount(r.id); - toRemove.add(new Item(r.id,p.getInventory().getAmount(r.id))); - } - } - if(amtRemaining <= 0){ - return true; - } else { - p.getPacketDispatch().sendMessage("You don't have enough " + item.getName() + "s to cast this spell."); - return false; - } - } - toRemove.add(item); - return true; - } - return true; - } - /** * Adds the experience for casting this spell. * @param entity The entity to reward with experience. diff --git a/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java b/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java index 103a63264..6664e721b 100644 --- a/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java +++ b/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java @@ -27,7 +27,7 @@ public enum MagicStaff { /** * Represents the earth rune staves. */ - EARTH_RUNE(557, 3053, 3055, 3056, 1385, 1399, 1407, 557, 6563, 6562); + EARTH_RUNE(557, 3053, 3054, 3055, 3056, 1385, 1399, 1407, 557, 6563, 6562); /** * The magic staves mapping. diff --git a/Server/src/main/core/game/node/entity/impl/Animator.java b/Server/src/main/core/game/node/entity/impl/Animator.java index 3afafb41b..430c4d551 100644 --- a/Server/src/main/core/game/node/entity/impl/Animator.java +++ b/Server/src/main/core/game/node/entity/impl/Animator.java @@ -2,7 +2,6 @@ package core.game.node.entity.impl; import core.game.interaction.Clocks; import core.game.node.entity.Entity; -import core.game.node.entity.npc.NPC; import core.game.world.GameWorld; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; diff --git a/Server/src/main/core/game/node/entity/impl/PulseManager.java b/Server/src/main/core/game/node/entity/impl/PulseManager.java index 74a78e7cc..6f93e1250 100644 --- a/Server/src/main/core/game/node/entity/impl/PulseManager.java +++ b/Server/src/main/core/game/node/entity/impl/PulseManager.java @@ -17,6 +17,12 @@ import java.util.HashMap; */ public final class PulseManager { + private final Entity entity; + + public PulseManager(Entity entity) { + this.entity = entity; + } + /** * The movement pulse. */ @@ -61,6 +67,9 @@ public final class PulseManager { } public void clear() { + entity.scripts.removeWeakScripts(); + entity.scripts.removeNormalScripts(); + currentPulses.forEach((type, pulse) -> { if (type != PulseType.STRONG && pulse != null) pulse.stop(); }); @@ -70,6 +79,9 @@ public final class PulseManager { * Clears the pulses. */ public boolean clear(PulseType pulseType) { + entity.scripts.removeWeakScripts(); + entity.scripts.removeNormalScripts(); + Pulse pulse = currentPulses.get(pulseType); if (pulse != null) { diff --git a/Server/src/main/core/game/node/entity/npc/Metamorphosis.java b/Server/src/main/core/game/node/entity/npc/Metamorphosis.java deleted file mode 100644 index 9b3175aed..000000000 --- a/Server/src/main/core/game/node/entity/npc/Metamorphosis.java +++ /dev/null @@ -1,94 +0,0 @@ -package core.game.node.entity.npc; - -import core.cache.def.impl.NPCDefinition; -import core.game.dialogue.DialoguePlugin; -import content.global.skill.summoning.familiar.Familiar; -import content.global.skill.summoning.pet.Pets; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Plugin; -import core.plugin.ClassScanner; -import core.tools.RandomFunction; - -/** - * A superclass plugin for any pets that have a metamorphosis option. - * @author Empathy - * - */ -public abstract class Metamorphosis extends OptionHandler { - - /** - * The ids of the possible npcs to metamorph into. - */ - protected int[] ids; - - - /** - * Constructs a new {@code Metamorphosis} {@code Object}. - * @param ids the id to transform. - */ - public Metamorphosis(int...ids) { - this.ids = ids; - } - - /** - * The dialogue plugin for the pet. - * @return the plugin. - */ - public abstract DialoguePlugin getDialoguePlugin(); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int id : getIds()) { - NPCDefinition.forId(id).getHandlers().put("option:metamorphosis", this); - } - if (getDialoguePlugin() != null) { - ClassScanner.definePlugin(getDialoguePlugin()); - } - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - Familiar familiar = (Familiar) node; - switch (option) { - case "metamorphosis": - if (player.getFamiliarManager().isOwner(familiar)) { - int newNpc = player.getFamiliarManager().getFamiliar().getId(); - while (newNpc == player.getFamiliarManager().getFamiliar().getId()) { - newNpc = getRandomNpcId(); - } - for (Pets p : Pets.values()) { - if (p.getBabyNpcId() == newNpc) { - player.getFamiliarManager().morphPet(new Item(p.getBabyItemId()), false, player.getFamiliarManager().getFamiliar().getLocation()); - break; - } - } - player.getPacketDispatch().sendMessage("You transform your " + player.getFamiliarManager().getFamiliar().getName() + "!"); - } else { - player.getPacketDispatch().sendMessage("This is not your familiar."); - } - break; - } - return true; - } - - /** - * Gets a random npc id. - * @return - */ - public int getRandomNpcId() { - int i = RandomFunction.getRandom(getIds().length - 1); - return getIds()[i]; - } - - /** - * Gets the npc ids. - * @return the id. - */ - public int[] getIds() { - return ids; - } -} diff --git a/Server/src/main/core/game/node/entity/npc/NPC.java b/Server/src/main/core/game/node/entity/npc/NPC.java index 31dcd8ca3..18334251e 100644 --- a/Server/src/main/core/game/node/entity/npc/NPC.java +++ b/Server/src/main/core/game/node/entity/npc/NPC.java @@ -8,7 +8,6 @@ import core.game.interaction.MovementPulse; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.spell.CombatSpell; -import core.game.node.entity.combat.CombatPulse; import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.combat.spell.DefaultCombatSpell; import core.game.node.entity.combat.equipment.WeaponInterface; @@ -29,7 +28,7 @@ import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.game.world.update.flag.*; import core.tools.RandomFunction; -import core.api.utils.GlobalKillCounter; +import core.api.utils.PlayerStatsCounter; import core.api.utils.Vector; import core.game.shops.Shops; import core.game.node.entity.combat.CombatSwingHandler; @@ -384,7 +383,7 @@ public class NPC extends Entity { this.movementIndex = 0; this.pathBoundMovement = true; } - + @Override public void checkImpact(BattleState state) { super.checkImpact(state); @@ -392,24 +391,42 @@ public class NPC extends Entity { behavior.beforeDamageReceived(this, entity, state); if (task != null && entity instanceof Player && task.levelReq > entity.getSkills().getLevel(Skills.SLAYER)) { state.neutralizeHits(); + state.setPoisonDamage(-1); + if (state.getStyle() == CombatStyle.MAGIC) { + state.setEstimatedHit(-1); + } + } + if (task != null && entity instanceof Familiar && task.levelReq > ((Familiar) entity).getOwner().getSkills().getLevel(Skills.SLAYER)) { + state.neutralizeHits(); + state.setPoisonDamage(-1); + if (state.getStyle() == CombatStyle.MAGIC) { + state.setEstimatedHit(-1); + } } } - + @Override public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { if (isInvisible()) { return false; } if (task != null && entity instanceof Player && task.levelReq > entity.getSkills().getLevel(Skills.SLAYER)) { - if(message) { - ((Player) entity).getPacketDispatch().sendMessage("You need a higher slayer level to know how to wound this monster."); - } + if (message) { + ((Player) entity).getPacketDispatch().sendMessage("You need a higher slayer level to know how to wound this monster."); + } } - if (!behavior.canBeAttackedBy(this, entity, style, message)) - return false; + if (!behavior.canBeAttackedBy(this, entity, style, message)) return false; return super.isAttackable(entity, style, message); } + @Override + public boolean continueAttack(Entity target, CombatStyle style, boolean message) { + if (isInvisible()) { + return false; + } + return true; + } + @Override public int getDragonfireProtection(boolean fire) { return 0; @@ -477,7 +494,6 @@ public class NPC extends Entity { public boolean pulse() { getProperties().getCombatPulse().stop(); getLocks().unlockMovement(); - fullRestore(); getImpactHandler().setDisabledTicks(0); removeAttribute("return-to-spawn"); removeAttribute("return-to-spawn-pulse"); @@ -523,6 +539,9 @@ public class NPC extends Entity { return false; } + public int getNextWalk() { + return nextWalk; + } /** * Sets the next walk. */ @@ -561,6 +580,14 @@ public class NPC extends Entity { return definition.getConfiguration(NPCConfigParser.POISON_IMMUNE, false); } + public boolean isPoisonous() { + return definition.getConfiguration(NPCConfigParser.POISONOUS, false); + } + + public int poisonSeverity() { + return definition.getConfiguration(NPCConfigParser.POISON_AMOUNT, 0); + } + @Override public void finalizeDeath(Entity killer) { super.finalizeDeath(killer); @@ -570,12 +597,12 @@ public class NPC extends Entity { Player p = !(killer instanceof Player) ? null : (Player) killer; if (p != null) { p.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_ENEMIES_KILLED); - GlobalKillCounter.incrementKills(p, originalId); + PlayerStatsCounter.incrementKills(p, originalId); } handleDrops(p, killer); if (!isRespawn()) clear(); - isRespawning = true; + isRespawning = true; behavior.onDeathFinished(this, killer); killer.dispatch(new NPCKillEvent(this)); setRespawnTick(GameWorld.getTicks() + definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 17)); @@ -724,6 +751,18 @@ public class NPC extends Entity { return this; } + /** + * Transforms this NPC with HP carried over from pre-transformed entity. + * HP adjustments (ie healing/scaling HP to new maximum) should be done manually per-NPC + * @param id The new NPC id. + */ + public NPC transformWithHpCarryover(int id) { + int lp = getSkills().getLifepoints(); + this.transform(id); + getSkills().setLifepoints(lp); + return this; + } + /** * Transforms this NPC back to original. */ @@ -740,7 +779,8 @@ public class NPC extends Entity { */ protected Location getMovementDestination() { if (!pathBoundMovement || movementPath == null || movementPath.length < 1) { - Location returnToSpawnLocation = getProperties().getSpawnLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0); + int radius = getWalkRadius() / 2; + Location returnToSpawnLocation = getProperties().getSpawnLocation().transform(RandomFunction.random(-radius, radius+1), RandomFunction.random(-radius, radius+1), 0); int dist = (int) Location.getDistance(location, returnToSpawnLocation); int pathLimit = 14; if (dist > pathLimit) { diff --git a/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt b/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt index 55f9b99e6..e4fa6676b 100644 --- a/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt +++ b/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt @@ -113,10 +113,8 @@ open class NPCBehavior(vararg val ids: Int = intArrayOf()) : ContentInterface { * @param shouldSendMessage whether the core combat code believes you should send a message e.g. "You can't attack this NPC with that weapon" * @return whether the attacker should be able to attack this NPC. */ - open fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean) : Boolean { - if (attacker is Player && !self.definition.hasAction("attack")) - return false - return true + open fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return !(attacker is Player && !self.definition.hasAction("attack") && !self.definition.hasAction("smash-ice")) } /** diff --git a/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java b/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java index 0e525cf95..50f93be3f 100644 --- a/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java +++ b/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java @@ -72,9 +72,9 @@ public class AggressiveBehavior { if (entity instanceof NPC && target instanceof Player) { NPC npc = (NPC) entity; if (npc.getAggressiveHandler() != null && npc.getAggressiveHandler().isAllowTolerance() && !WildernessZone.isInZone(npc)) { - if (RegionManager.forId(regionId).isTolerated(target.asPlayer())) { - return false; - } + if (RegionManager.forId(regionId).isTolerated(target.asPlayer())) { + return false; + } } } int level = target.getProperties().getCurrentCombatLevel(); @@ -84,9 +84,9 @@ public class AggressiveBehavior { return true; } - public boolean ignoreCombatLevelDifference() { - return false; - } + public boolean ignoreCombatLevelDifference() { + return false; + } /** * Gets the priority flag. @@ -132,9 +132,9 @@ public class AggressiveBehavior { */ public Entity getLogicalTarget(Entity entity, List possibleTargets) { Entity target = null; - int comparingFlag = Integer.MAX_VALUE; + double comparingFlag = Double.MAX_VALUE; for (Entity e : possibleTargets) { - int flag = getPriorityFlag(e); + double flag = (double)getPriorityFlag(e) + Math.random(); if (flag <= comparingFlag) { comparingFlag = flag; target = e; diff --git a/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java b/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java index 31397a4c4..baacc117b 100644 --- a/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java +++ b/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java @@ -147,7 +147,7 @@ public final class NPCDropTables { List players = RegionManager.getLocalPlayers(npc, 16); List looters = new ArrayList<>(20); for (Player p : players) { - if (p != null && p.getCommunication().getClan() != null && p.getCommunication().getClan() == player.getCommunication().getClan() && p.getCommunication().isLootShare() && p.getCommunication().getLootRequirement().ordinal() >= p.getCommunication().getClan().getLootRequirement().ordinal() && npc.getImpactHandler().getImpactLog().containsKey(p)) { + if (p != null && p.getCommunication().getClan() != null && p.getCommunication().getClan() == player.getCommunication().getClan() && p.getCommunication().isLootShare() && p.getCommunication().getLootRequirement().ordinal() >= p.getCommunication().getClan().getLootRequirement().ordinal()) { looters.add(p); } } diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index a55ff25a8..d21c591fc 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -1,11 +1,14 @@ package core.game.node.entity.player; +import content.global.handlers.item.equipment.BarrowsEquipment; import content.global.handlers.item.equipment.special.SalamanderSwingHandler; +import content.global.skill.construction.decoration.pohstorage.POHStorageProxyContainer; +import content.global.skill.construction.decoration.pohstorage.StorageState; import content.global.skill.runecrafting.PouchManager; -import core.api.EquipmentSlot; +import content.global.skill.slayer.SlayerEquipmentFlags; +import core.api.ContentAPIKt; import core.game.component.Component; import core.game.container.Container; -import core.game.container.ContainerType; import core.game.container.impl.BankContainer; import core.game.container.impl.EquipmentContainer; import core.game.container.impl.InventoryListener; @@ -44,6 +47,7 @@ import core.game.system.task.Pulse; import core.game.world.map.*; import core.game.world.map.build.DynamicRegion; import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.ZoneRestriction; import core.game.world.map.zone.ZoneType; import core.game.world.update.flag.PlayerFlags; import core.game.world.update.flag.*; @@ -69,8 +73,6 @@ import core.game.node.entity.combat.CombatSwingHandler; import content.global.handlers.item.equipment.EquipmentDegrader; import core.game.node.entity.combat.graves.Grave; import core.game.node.entity.combat.graves.GraveController; -import core.game.node.entity.state.State; -import core.game.node.entity.state.StateRepository; import core.game.world.GameWorld; import core.game.world.repository.Repository; import core.game.world.update.MapChunkRenderer; @@ -87,10 +89,11 @@ import java.util.*; import java.util.concurrent.TimeUnit; import static core.api.ContentAPIKt.*; -import static core.api.utils.Permadeath.PermadeathKt.permadeath; +import static core.api.utils.PermadeathKt.permadeath; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_DEATHS; import static core.tools.GlobalsKt.colorize; +import static org.rs09.consts.Items.BONES_526; /** * Represents a player entity. @@ -120,14 +123,30 @@ public class Player extends Entity { public VarpManager varpManager = new VarpManager(this); - public HashMap varpMap = new HashMap<>(); - public HashMap saveVarp = new HashMap<>(); + public HashMap varpMap = new HashMap<>(); - public HashMap states = new HashMap<>(); + public HashMap saveVarp = new HashMap<>(); public HashMap> logoutListeners = new HashMap<>(); - /** + public Boolean isAfkLogout; + + private StorageState POHStorageState; + + public final Container POHStorageProxyContainer = new POHStorageProxyContainer(this); + + public StorageState getPOHStorageState() { + if (POHStorageState == null) { + POHStorageState = new StorageState(this); + } + return POHStorageState; + } + + public void setPOHStorageState(StorageState state) { + this.POHStorageState = state; + } + + /** * The inventory. */ private final Container inventory = new Container(28).register(new InventoryListener(this)); @@ -152,21 +171,6 @@ public class Player extends Entity { */ public boolean useSecondaryBank = false; - /** - * The Blast Furnace Coal Container. - */ - public final Container blastCoal = new Container(225, ContainerType.NEVER_STACK); - - /** - * The Blast Furnace Ore Container. - */ - public final Container blastOre = new Container(28, ContainerType.NEVER_STACK); - - /** - * The Blast Furnace Bars Container. - */ - public final Container blastBars = new Container(28, ContainerType.NEVER_STACK); - /** * The packet dispatcher. */ @@ -310,11 +314,18 @@ public class Player extends Entity { * The amount of targets that the player can shoot left for the archery minigame. */ private int archeryTargets = 0; - private int archeryTotal = 0; - public byte[] opCounts = new byte[255]; + /** + * The save file version. + */ + public int version = ServerConstants.CURRENT_SAVEFILE_VERSION; + /** + * Packet administration. + * opCounts is used to enforce an authentic limit of 10 of each inbound packet per user per tick. + */ + public byte[] opCounts = new byte[255]; public int invalidPacketCount = 0; /** @@ -331,10 +342,8 @@ public class Player extends Entity { @Override public void init() { - if(!artificial) - log(this.getClass(), Log.INFO, getUsername() + " initialising..."); if (!artificial) { - getProperties().setSpawnLocation(ServerConstants.HOME_LOCATION); + log(this.getClass(), Log.INFO, getUsername() + " initialising..."); getDetails().getSession().setObject(this); } super.init(); @@ -467,11 +476,23 @@ public class Player extends Entity { settings.setSpecialEnergy(100); } - //Decrements prayer points + // Decrement prayer points getPrayer().tick(); - //update wealth tracking + // Update wealth tracking checkForWealthUpdate(false); + + // Check if the player is on the map, runs only every 6 seconds for performance reasons. + // This is only a sanity check to detect improper usage of the 'original-loc' attribute, hence only do this work if the attribute is set. + // Does not run if the player is currently in the middle of a kidnap sequence (to avoid false positives while the teleport is taking place). + if (GameWorld.getTicks() % 10 == 0 && ContentAPIKt.getAttribute(this, "/save:original-loc", null) != null && !ContentAPIKt.getAttribute(this, "kidnapped-by-random", false)) { + int rid = location.getRegionId(); + Region r = RegionManager.forId(rid); + if (!(r instanceof DynamicRegion) && !getZoneMonitor().isRestricted(ZoneRestriction.OFF_MAP)) { + log(this.getClass(), Log.ERR, "Player " + getUsername() + " has the original-loc attribute set but isn't actually off-map! This indicates a bug in the code that set that attribute. The original-loc is " + getAttribute("/save:original-loc") + ", the current region is " + rid + ". Good luck debugging!"); + ContentAPIKt.removeAttribute(this, "original-loc"); + } + } } private void checkForWealthUpdate(boolean force) { @@ -494,21 +515,21 @@ public class Player extends Entity { if (i == null) break; totalWealth += (long) i.getDefinition().getValue() * i.getAmount(); } - GrandExchangeRecords ge = GrandExchangeRecords.getInstance(this); - for (int i=0; i<6; i++) { - GrandExchangeOffer offer = ge.getOffer(i); - if (offer != null) { - totalWealth += offer.cacheValue(); - } - } + GrandExchangeRecords ge = GrandExchangeRecords.getInstance(this); + for (int i=0; i<6; i++) { + GrandExchangeOffer offer = ge.getOffer(i); + if (offer != null) { + totalWealth += offer.cacheValue(); + } + } - // This can lead to a false positive of up to 3 * 187.5k, but only for 3 ticks while a cannon is being constructed - if (this.getAttribute("dmc", null) != null) { - totalWealth += ItemDefinition.forId(Items.CANNON_BASE_6).getValue(); - totalWealth += ItemDefinition.forId(Items.CANNON_STAND_8).getValue(); - totalWealth += ItemDefinition.forId(Items.CANNON_BARRELS_10).getValue(); - totalWealth += ItemDefinition.forId(Items.CANNON_FURNACE_12).getValue(); - } + // This can lead to a false positive of up to 3 * 187.5k, but only for 3 ticks while a cannon is being constructed + if (this.getAttribute("dmc", null) != null) { + totalWealth += ItemDefinition.forId(Items.CANNON_BASE_6).getValue(); + totalWealth += ItemDefinition.forId(Items.CANNON_STAND_8).getValue(); + totalWealth += ItemDefinition.forId(Items.CANNON_BARRELS_10).getValue(); + totalWealth += ItemDefinition.forId(Items.CANNON_FURNACE_12).getValue(); + } long diff = previousWealth == -1 ? 0L : totalWealth - previousWealth; setAttribute("/save:last-wealth", totalWealth); @@ -551,15 +572,15 @@ public class Player extends Entity { return this.getIndex() | 0x8000; } - @Override - public void onAttack (Entity e) { - if (e instanceof Player) { - Player p = (Player) e; - if (skullManager.isWildernessDisabled()) { - return; - } - } - } + @Override + public void onAttack (Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + if (skullManager.isWildernessDisabled()) { + return; + } + } + } @Override public CombatSwingHandler getSwingHandler(boolean swing) { @@ -588,7 +609,7 @@ public class Player extends Entity { @Override public void commenceDeath(Entity killer) { - if (!isPlaying()) return; + if (!isPlaying()) return; super.commenceDeath(killer); if (prayer.get(PrayerType.RETRIBUTION)) { prayer.startRetribution(killer); @@ -611,10 +632,8 @@ public class Player extends Entity { if (this.isArtificial() && killer instanceof NPC) { return; } - if (killer instanceof Player && getWorldTicks() - killer.getAttribute("/save:last-murder-news", 0) >= 500) { - Item wep = getItemFromEquipment((Player) killer, EquipmentSlot.WEAPON); - sendNews(killer.getUsername() + " has murdered " + getUsername() + " with " + (wep == null ? "their fists." : (StringUtils.isPlusN(wep.getName()) ? "an " : "a ") + wep.getName())); - killer.setAttribute("/save:last-murder-news", getWorldTicks()); + if (killer instanceof Player && !Objects.equals(killer.getName(), getName())) { // the latter happens if you died via typeless damage from an external cause, e.g. bugs in a dark cave without a light source + ContentAPIKt.sendMessage((Player) killer, "You have defeated " + getUsername() + "."); } getPacketDispatch().sendMessage("Oh dear, you are dead!"); incrementAttribute("/save:"+STATS_BASE+":"+STATS_DEATHS); @@ -622,27 +641,22 @@ public class Player extends Entity { packetDispatch.sendTempMusic(90); if (!getZoneMonitor().handleDeath(killer) && (!getProperties().isSafeZone() && getZoneMonitor().getType() != ZoneType.SAFE.getId()) && getDetails().getRights() != Rights.ADMINISTRATOR) { //If player was a Hardcore Ironman, announce that they died - if (this.getIronmanManager().getMode().equals(IronmanMode.HARDCORE)){ //if this was checkRestriction, ultimate irons would be moved to HARDCORE_DEAD as well + if (this.getIronmanManager().getMode().equals(IronmanMode.HARDCORE)) { //if this was checkRestriction, ultimate irons would be moved to HARDCORE_DEAD as well String gender = this.isMale() ? "man " : "woman "; if (getAttributes().containsKey("permadeath")) { Repository.sendNews("Permadeath Hardcore Iron" + gender + " " + this.getUsername() + " has fallen. Total Level: " + this.getSkills().getTotalLevel()); // Not enough room for XP permadeath(this); return; - } else { - Repository.sendNews("Hardcore Iron " + gender + " " + this.getUsername() + " has fallen. Total Level: " + this.getSkills().getTotalLevel()); // Not enough room for XP - this.getIronmanManager().setMode(IronmanMode.STANDARD); - asPlayer().getSavedData().getActivityData().setHardcoreDeath(true); - this.sendMessage("You have fallen as a Hardcore Iron Man, your Hardcore status has been revoked."); } } - GroundItemManager.create(new Item(526), getLocation(), k); + GroundItemManager.create(new Item(BONES_526), this.getAttribute("/save:original-loc",location), k); final Container[] c = DeathTask.getContainers(this); for (Item i : getEquipment().toArray()) { if (i == null) continue; InteractionListeners.run(i.getId(), this, i, false); Plugin equipPlugin = i.getDefinition().getConfiguration("equipment", null); - if (equipPlugin != null) equipPlugin.fireEvent("unequip"); + if (equipPlugin != null) equipPlugin.fireEvent("unequip", this, i); } boolean canCreateGrave = GraveController.allowGenerate(this); @@ -657,11 +671,13 @@ public class Player extends Entity { if (item == null) continue; if (killer instanceof Player) itemsLost.append(getItemName(item.getId())).append("(").append(item.getAmount()).append("), "); + if (GraveController.shouldCrumble(item.getId())) continue; if (GraveController.shouldRelease(item.getId())) continue; - if (!item.getDefinition().isTradeable()) { + + if (!BarrowsEquipment.isBarrowsItem(item.getId()) && !item.getDefinition().isTradeable()) { if (killer instanceof Player) { int value = item.getDefinition().getAlchemyValue(true); if (getStatLevel(killer, Skills.MAGIC) < 55) value /= 2; @@ -669,7 +685,14 @@ public class Player extends Entity { continue; } else stayPrivate = true; } - item = GraveController.checkTransform(item); + if (BarrowsEquipment.isBarrowsItem(item.getId())) { + if (!BarrowsEquipment.isBroken(item.getId())) { + int brokenItemId = Objects.requireNonNull(BarrowsEquipment.getDefinition(item.getId())).getBrokenId(); + item = new Item(brokenItemId, item.getAmount()); + } + } else { + item = GraveController.checkTransform(item); + } GroundItem gi = GroundItemManager.create(item, location, killer instanceof Player ? (Player) killer : this); gi.setRemainPrivate(stayPrivate); } @@ -682,6 +705,7 @@ public class Player extends Entity { } equipment.clear(); + SlayerEquipmentFlags.updateFlags(this); inventory.clear(); inventory.addAll(c[0]); familiarManager.dismiss(); @@ -689,6 +713,10 @@ public class Player extends Entity { skullManager.setSkulled(false); removeAttribute("combat-time"); getPrayer().reset(); + removeAttribute("original-loc"); //in case you died inside a random event + interfaceManager.openDefaultTabs(); //in case you died inside a random that had blanked them + setComponentVisibility(this, 548, 69, false); //reenable the logout button (SD) + setComponentVisibility(this, 746, 12, false); //reenable the logout button (HD) super.finalizeDeath(killer); appearance.sync(); if (!getSavedData().getGlobalData().isDeathScreenDisabled()) { @@ -742,21 +770,49 @@ public class Player extends Entity { if (entity instanceof NPC && !((NPC) entity).getDefinition().hasAction("attack") && !((NPC) entity).isIgnoreAttackRestrictions(this)) { return false; } - if (entity instanceof Player) { - Player p = (Player) entity; - if (p.getSkullManager().isWilderness() && skullManager.isWilderness()) { - if (!GameWorld.getSettings().getWild_pvp_enabled()) - return false; - if (p.getSkullManager().hasWildernessProtection()) - return false; - if (skullManager.hasWildernessProtection()) - return false; - return true; - } else return false; - } + if (entity instanceof Player) { + Player p = (Player) entity; + if (p.getSkullManager().isWilderness() && skullManager.isWilderness()) { + if (!GameWorld.getSettings().getWild_pvp_enabled()) + return false; + if (p.getSkullManager().hasWildernessProtection()) + return false; + if (skullManager.hasWildernessProtection()) + return false; + return super.isAttackable(entity, style, message); + } else return false; + } return super.isAttackable(entity, style, message); } + @Override + public boolean continueAttack(Entity target, CombatStyle style, boolean message) { + if (target instanceof NPC) { + NPC npc = (NPC) target; + NPC shown = npc.getShownNPC(this); + boolean canAttack = shown.getDefinition().hasAction("attack") + || shown.getDefinition().hasAction("smash-ice"); + if (!canAttack && !npc.isIgnoreAttackRestrictions(this)) { + return false; + } + } + if (target instanceof Player) { + Player p = (Player) target; + if (p.getSkullManager().isWilderness() && skullManager.isWilderness()) { + if (GameWorld.getSettings() == null || !GameWorld.getSettings().getWild_pvp_enabled()) { + return false; + } + if (p.getSkullManager().hasWildernessProtection()) { + return false; + } + return !skullManager.hasWildernessProtection(); + } else { + return false; + } + } + return true; + } + @Override public boolean isPoisonImmune() { return timers.getTimer("poison:immunity") != null; @@ -1341,7 +1397,6 @@ public class Player extends Entity { return "Player [name=" + name + ", getRights()=" + getRights() + "]"; } - public String getCustomState() { return customState; } @@ -1367,37 +1422,15 @@ public class Player extends Entity { this.archeryTotal = archeryTotal; } - public boolean hasActiveState(String key){ - State state = states.get(key); - if(state != null && state.getPulse() != null){ - return true; + public void updateAppearance() { + getUpdateMasks().register(EntityFlag.Appearance, this); + } + + public void incrementInvalidPacketCount() { + invalidPacketCount++; + if (invalidPacketCount >= 5) { + clear(); + log(this.getClass(), Log.ERR, "Disconnecting " + getName() + " for having a high rate of invalid packets. Potential packet bot misbehaving, or simply really bad connection."); } - return false; } - - public State registerState(String key){ - return StateRepository.forKey(key, this); - } - - public void clearState(String key){ - State state = states.get(key); - if(state == null) return; - Pulse pulse = state.getPulse(); - if(pulse != null) { - pulse.stop(); - } - states.remove(key); - } - - public void updateAppearance() { - getUpdateMasks().register(EntityFlag.Appearance, this); - } - - public void incrementInvalidPacketCount() { - invalidPacketCount++; - if (invalidPacketCount >= 5) { - clear(); - log(this.getClass(), Log.ERR, "Disconnecting " + getName() + " for having a high rate of invalid packets. Potential packet bot misbehaving, or simply really bad connection."); - } - } } diff --git a/Server/src/main/core/game/node/entity/player/info/Rights.java b/Server/src/main/core/game/node/entity/player/info/Rights.java index c50de0e95..95009c23a 100644 --- a/Server/src/main/core/game/node/entity/player/info/Rights.java +++ b/Server/src/main/core/game/node/entity/player/info/Rights.java @@ -25,11 +25,11 @@ public enum Rights { if (c != Rights.REGULAR_PLAYER && c != null) { return c.toInteger(); } - if (ServerConstants.IRONMAN_ICONS) { - if (player.getIronmanManager().isIronman()) { - return player.getIronmanManager().getMode().getIcon(); - } - } + if (ServerConstants.IRONMAN) { + if (player.getIronmanManager().isIronman()) { + return player.getIronmanManager().getMode().getIcon(); + } + } return 0; } diff --git a/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java b/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java index 4dc80dda2..fb50ee051 100644 --- a/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java +++ b/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java @@ -1,6 +1,5 @@ package core.game.node.entity.player.info.login; -import core.game.component.CloseEvent; import core.game.component.Component; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.emote.Emotes; @@ -14,12 +13,10 @@ import core.ServerConstants; import core.game.interaction.InteractionListeners; import content.global.handlers.iface.RulesAndInfo; import core.tools.Log; -import core.tools.SystemLogger; import core.game.world.GameWorld; import core.game.world.repository.Repository; import core.game.world.update.UpdateSequence; import core.game.node.entity.player.link.SpellBookManager; -import core.game.node.item.GroundItemManager; import java.util.ArrayList; import java.util.Date; @@ -30,6 +27,7 @@ import java.util.stream.IntStream; import static core.api.ContentAPIKt.*; import static core.tools.GlobalsKt.colorize; +import content.data.Quests; /** @@ -49,22 +47,17 @@ public final class LoginConfiguration { */ private static final Component LOBBY_PANE = new Component(549); + /** + * The lobby interface component. + */ + private static final Component LOBBY_INTERFACE = new Component(378); + /** * The lobby message of the week models & constant to be set for auto selecting the models */ private static final int[] MESSAGE_MODEL = {15, 16, 17, 18, 19, 20, 21, 22, 23, 405, 447, 622, 623, 679, 715, 800}; private static int messModel; - /** - * The lobby interface close event. - */ - private static final Component LOBBY_INTERFACE = new Component(378).setCloseEvent(new CloseEvent() { - @Override - public boolean close(Player player, Component c) { - return player.getLocks().isLocked("login"); - } - }); - /** * Constructs a new {@Code LoginConfiguration} {@Code Object} */ @@ -103,25 +96,25 @@ public final class LoginConfiguration { } } Repository.getLobbyPlayers().add(player); - player.getPacketDispatch().sendString(getLastLogin(player), 378, 116); - player.getPacketDispatch().sendString("Welcome to " + GameWorld.getSettings().getName(), 378, 115); - player.getPacketDispatch().sendString(" ", 378, 37); - player.getPacketDispatch().sendString("Want to stay up to date with the latest news and updates? Join our
discord by using the link below!", 378, 38); - player.getPacketDispatch().sendString(" ", 378, 39); - player.getPacketDispatch().sendString("Discord Invite", 378, 14); - player.getPacketDispatch().sendString("Discord Invite", 378, 129); - player.getPacketDispatch().sendString("Credits", 378, 94); - player.getPacketDispatch().sendString(player.getDetails().getCredits() + "", 378, 96); - player.getPacketDispatch().sendString(" ", 378, 229); - player.getPacketDispatch().sendString("Want to contribute to " + ServerConstants.SERVER_NAME + "?
Visit the GitLab using the link below!", 378, 230); - player.getPacketDispatch().sendString(" ", 378, 231); - player.getPacketDispatch().sendString("Github", 378, 240); - player.getPacketDispatch().sendString(GameWorld.getSettings().getMessage_string(), messModel, getMessageChild(messModel)); - player.getPacketDispatch().sendString("You can gain more credits by voting, reporting bugs and various other methods of contribution.", 378, 93); + setInterfaceText(player, "Welcome to " + ServerConstants.SERVER_NAME, 378, 115); + setInterfaceText(player, getLastLogin(player), 378, 116); + setInterfaceText(player, "", 378, 37); + setInterfaceText(player, "Want to stay up to date with the latest news and updates? Join our discord by using the link on our website!", 378, 38); + setInterfaceText(player, "", 378, 39); + setInterfaceText(player, "Discord Invite", 378, 14); + setInterfaceText(player, "Discord Invite", 378, 129); + setInterfaceText(player, "You can gain more credits by reporting bugs and various other methods of contribution.", 378, 93); + setInterfaceText(player, player.getDetails().getCredits() + "", 378, 96); + setInterfaceText(player, "Credits", 378, 94); + setInterfaceText(player, "", 378, 229); + setInterfaceText(player, "Want to contribute to " + ServerConstants.SERVER_NAME + "? Visit the GitLab using the link on our website!", 378, 230); + setInterfaceText(player, "", 378, 231); + setInterfaceText(player, "Github", 378, 240); + setInterfaceText(player, GameWorld.getSettings().getMessage_string(), messModel, getMessageChild(messModel)); player.getInterfaceManager().openWindowsPane(LOBBY_PANE); player.getInterfaceManager().setOpened(LOBBY_INTERFACE); - PacketRepository.send(Interface.class, new InterfaceContext(player, 549, 2, 378, true)); - PacketRepository.send(Interface.class, new InterfaceContext(player, 549, 3, messModel, true));//UPDATE `configs` SET `value`=FLOOR(RAND()*(25-10)+10) WHERE key_="messageInterface" + PacketRepository.send(Interface.class, new InterfaceContext(player, LOBBY_PANE.getId(), 2, 378, true)); + PacketRepository.send(Interface.class, new InterfaceContext(player, LOBBY_PANE.getId(), 3, messModel, true));//UPDATE `configs` SET `value`=FLOOR(RAND()*(25-10)+10) WHERE key_="messageInterface" player.getDetails().setLastLogin(System.currentTimeMillis()); } @@ -140,9 +133,11 @@ public final class LoginConfiguration { player.updateAppearance(); player.getPlayerFlags().setUpdateSceneGraph(true); player.getPacketDispatch().sendInterfaceConfig(226, 1, true); + if(player.getGlobalData().getTestStage() == 3 && !player.getEmoteManager().isUnlocked(Emotes.SAFETY_FIRST)){ player.getEmoteManager().unlock(Emotes.SAFETY_FIRST); } + for (Item item : player.getEquipment().toArray()) { //Run equip hooks for all items equipped on login. //We should have already been doing this. @@ -150,37 +145,28 @@ public final class LoginConfiguration { if (item == null) continue; player.getEquipment().remove(item); if (!InteractionListeners.run(item.getId(), player, item, true) || !player.getEquipment().add(item, true, false)) { - if (player.getInventory().add(item)) - player.sendMessage (colorize("%RAs you can no longer wear " + item.getName() + ", it has been unequipped.")); - else if (player.getBankPrimary().add(item)) - player.sendMessage (colorize("%RAs you can no longer wear " + item.getName() + ", it has been sent to your bank.")); - else if (player.getBankSecondary().add(item)) - player.sendMessage (colorize("%RAs you can no longer wear " + item.getName() + ", it has been sent to your secondary bank.")); - else { - player.sendMessage (colorize("%RAs you can no longer wear " + item.getName() + ", and your inventory and both banks are full,")); - player.sendMessage (colorize("%RIt has been placed on the ground under your feet. Don't forget to grab it.")); - player.sendMessage ("(Also, consider cleaning out your banks maybe? I mean jesus.)"); - GroundItemManager.create (item, player); - } + player.sendMessage(colorize("%RAs you can no longer wear " + item.getName() + ", it has been unequipped.")); + addItemOrBank(player, item.getId(), item.getAmount()); } } + SpellBookManager.SpellBook currentSpellBook = SpellBookManager.SpellBook.forInterface(player.getSpellBookManager().getSpellBook()); - if (currentSpellBook == SpellBookManager.SpellBook.ANCIENT && !hasRequirement(player, "Desert Treasure")) { + if (currentSpellBook == SpellBookManager.SpellBook.ANCIENT && !hasRequirement(player, Quests.DESERT_TREASURE)) { player.sendMessage(colorize("%RAs you can no longer use Ancient Magic, you have been set back to Modern.")); player.getSpellBookManager().setSpellBook(SpellBookManager.SpellBook.MODERN); - } else if (currentSpellBook == SpellBookManager.SpellBook.LUNAR && !hasRequirement(player, "Lunar Diplomacy")) { + } else if (currentSpellBook == SpellBookManager.SpellBook.LUNAR && !hasRequirement(player, Quests.LUNAR_DIPLOMACY)) { player.sendMessage(colorize("%RAs you can no longer use Lunar Magic, you have been set back to Modern.")); player.getSpellBookManager().setSpellBook(SpellBookManager.SpellBook.MODERN); } player.getSpellBookManager().update(player); + // 1050 is checked client-side for making piety/chivalry disallowed sfx, likely due to the minigame requirement. // Set it here unconditionally until the minigame is implemented. - setVarbit(player, 3909, 8, false); + if (hasRequirement(player, Quests.KINGS_RANSOM, false)) { + setVarbit(player, 3909, 8, false); + } if(ServerConstants.RULES_AND_INFO_ENABLED) RulesAndInfo.openFor(player); - /*if (GameWorld.getSettings().isPvp()) { - player.getPacketDispatch().sendString("", 226, 1); - }*/ /*if (TutorialSession.getExtension(player).getStage() != 73) { TutorialStage.load(player, TutorialSession.getExtension(player).getStage(), true); }*/ @@ -213,21 +199,14 @@ public final class LoginConfiguration { * @param player the player. Fullscreen mode Object id: */ public static final void welcome(final Player player) { - if (GameWorld.getSettings().isPvp()) { - player.getPacketDispatch().sendString("", 226, 0); - } if (player.isArtificial()) { - return; } - player.getPacketDispatch().sendMessage("Welcome to " + GameWorld.getSettings().getName() + "."); - //player.getPacketDispatch().sendMessage("You are currently playing in beta version 1.2"); + player.getPacketDispatch().sendMessage("Welcome to " + ServerConstants.SERVER_NAME + "."); if (player.getDetails().isMuted()) { player.getPacketDispatch().sendMessage("You are muted."); player.getPacketDispatch().sendMessage("To prevent further mutes please read the rules."); } -// ResourceAIPManager.get().load(player); -// ResourceAIPManager.get().save(player); } /** @@ -247,7 +226,8 @@ public final class LoginConfiguration { player.getPacketDispatch().sendRunEnergy(); player.getFamiliarManager().login(); player.getInterfaceManager().openDefaultTabs(); - player.getPacketDispatch().sendString("Friends List - World " + GameWorld.getSettings().getWorldId(), 550, 3); + setInterfaceText(player, "Friends List - " + ServerConstants.SERVER_NAME + " " + GameWorld.getSettings().getWorldId(), 550, 3); + setInterfaceText(player, "When you have finished playing " + ServerConstants.SERVER_NAME + ", always use the button below to logout safely.", 182, 0); player.getQuestRepository().syncronizeTab(player); player.getInterfaceManager().close(); player.getEmoteManager().refresh(); @@ -267,11 +247,11 @@ public final class LoginConfiguration { return 8; } else if (interfaceId == 16) { return 6; - } else if (interfaceId == 17 || interfaceId == 15 || interfaceId == 18 || interfaceId == 19 || interfaceId == 21 || interfaceId == 22 || interfaceId == 447 || interfaceId == 405) { - return 4; } else if (interfaceId == 20 || interfaceId == 623) { return 5; - } else if (interfaceId == 23 || interfaceId == 800) { + } else if (interfaceId == 15 || interfaceId == 18 || interfaceId == 19 || interfaceId == 21 || interfaceId == 22 || interfaceId == 447 || interfaceId == 405) { + return 4; + } else if (interfaceId == 17 || interfaceId == 23 || interfaceId == 800) { return 3; } else if (interfaceId == 715) { return 2; @@ -296,12 +276,8 @@ public final class LoginConfiguration { * @return the last login. */ public static String getLastLogin(Player player) { - String lastIp = player.getDetails().accountInfo.getLastUsedIp(); - if (lastIp.equals("")) { - lastIp = player.getDetails().getIpAddress(); - } - player.getDetails().accountInfo.setLastUsedIp(player.getDetails().getIpAddress()); - String string = "You last logged in @timeAgo from: " + lastIp; + player.getPacketDispatch().sendLastLoginInfo(); + String string = "You last logged in @timeAgo from:"; long time = player.getDetails().getLastLogin(); Date lastLogin = new Date(time); Date current = new Date(); diff --git a/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt b/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt index 85fdf972a..649db34a5 100644 --- a/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt +++ b/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt @@ -1,11 +1,12 @@ package core.game.node.entity.player.info.login +import core.ServerConstants import core.api.* +import core.auth.AuthResponse import core.game.node.entity.player.Player import core.game.node.entity.player.info.PlayerDetails import core.game.system.SystemManager import core.game.system.task.Pulse -import core.auth.AuthResponse import core.game.world.GameWorld import core.game.world.GameWorld.loginListeners import core.game.world.repository.Repository @@ -27,8 +28,7 @@ class LoginParser(val details: PlayerDetails) { parser = PlayerParser.parse(player) ?: throw IllegalStateException("Failed parsing save for: " + player.username) //Parse core } - catch (e: Exception) - { + catch (e: Exception) { e.printStackTrace() Repository.removePlayer(player) flag(AuthResponse.ErrorLoadingProfile) @@ -37,9 +37,11 @@ class LoginParser(val details: PlayerDetails) { override fun pulse(): Boolean { try { if (details.session.isActive) { + player.properties.spawnLocation = getAttribute(player, "/save:spawnLocation", ServerConstants.HOME_LOCATION) loginListeners.forEach(Consumer { listener: LoginListener -> listener.login(player) }) //Run our login hooks parser.runContentHooks() //Run our saved-content-parsing hooks player.details.session.setObject(player) + player.getDetails().accountInfo.lastUsedIp = player.getDetails().getIpAddress() if (reconnect) { reconnect(player) } else { diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt index e5984d7e2..74d82e646 100644 --- a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt @@ -1,7 +1,5 @@ package core.game.node.entity.player.info.login -import content.global.skill.farming.CompostBins -import content.global.skill.farming.FarmingPatch import core.JSONUtils import core.api.PersistPlayer import core.game.node.entity.combat.spell.CombatSpell @@ -18,8 +16,6 @@ import core.ServerConstants import core.api.log import core.game.node.entity.combat.graves.GraveController import core.game.node.entity.combat.graves.GraveType -import core.tools.SystemLogger -import core.game.world.GameWorld import core.tools.Log import java.io.File import java.io.FileReader @@ -48,14 +44,12 @@ class PlayerSaveParser(val player: Player) { reader ?: log(this::class.java, Log.WARN, "Couldn't find save file for ${player.name}, or save is corrupted.").also { read = false } if (read) { saveFile = parser.parse(reader) as JSONObject - } - - if (read) { parseData() } } fun parseData() { + parseVersion() parseCore() parseAttributes() parseSkills() @@ -64,7 +58,6 @@ class PlayerSaveParser(val player: Player) { parseAppearance() parseGrave() parseVarps() - parseStates() parseSpellbook() parseSavedData() parseAutocastSpell() @@ -80,7 +73,7 @@ class PlayerSaveParser(val player: Player) { parseStatistics() parseAchievements() parsePouches() - parsePouches() + parsePOHStorable() } fun runContentHooks() @@ -100,6 +93,12 @@ class PlayerSaveParser(val player: Player) { player.pouchManager.parse(saveFile!!["pouches"] as JSONArray) } + fun parsePOHStorable() { + val storableRaw = saveFile?.get("pohstorage") ?: return + val storableJson = storableRaw as JSONObject + player.getPOHStorageState().readJson(storableJson) + } + fun parseAttributes() { if (saveFile!!.containsKey("attributes")) { val attrData = saveFile!!["attributes"] as JSONArray @@ -180,22 +179,6 @@ class PlayerSaveParser(val player: Player) { player.bankPinManager.parse(bpData) } - fun parseStates() { - player.states.clear() - if (saveFile!!.containsKey("states")) { - val states: JSONArray = saveFile!!["states"] as JSONArray - for (state in states) { - val s = state as JSONObject - val stateId = s["stateKey"].toString() - if(player.states[stateId] != null) continue - val stateClass = player.registerState(stateId) - stateClass?.parse(s) - stateClass?.init() - player.states.put(stateId,stateClass) - } - } - } - fun parseFamiliars() { val familiarData = saveFile!!["familiarManager"] as JSONObject player.familiarManager.parse(familiarData) @@ -330,9 +313,6 @@ class PlayerSaveParser(val player: Player) { player.bankPrimary.parse(bank) player.bankSecondary.parse(bankSecondary) player.equipment.parse(equipment) - bBars?.let{player.blastBars.parse(it)} - bOre?.let{player.blastOre.parse(bOre)} - bCoal?.let{player.blastCoal.parse(bCoal)} player.location = JSONUtils.parseLocation(location) if (varpData != null) { @@ -355,13 +335,10 @@ class PlayerSaveParser(val player: Player) { val skillData = saveFile!!["skills"] as JSONArray player.skills.parse(skillData) player.skills.experienceGained = saveFile!!["totalEXP"].toString().toDouble() - player.skills.experienceMutiplier = saveFile!!["exp_multiplier"].toString().toDouble() - if (GameWorld.settings?.default_xp_rate != 5.0) { - player.skills.experienceMutiplier = GameWorld.settings?.default_xp_rate!! - } + player.skills.experienceMultiplier = saveFile!!["exp_multiplier"].toString().toDouble() val divisor: Double - if(player.skills.experienceMutiplier >= 10 && !player.attributes.containsKey("permadeath")){ //exclude permadeath HCIMs from XP squish - divisor = player.skills.experienceMutiplier / 5.0 + if(player.skills.experienceMultiplier >= 10 && !player.attributes.containsKey("permadeath")){ //exclude permadeath HCIMs from XP squish + divisor = player.skills.experienceMultiplier / 5.0 player.skills.correct(divisor) } if (saveFile!!.containsKey("milestone")) { @@ -377,5 +354,11 @@ class PlayerSaveParser(val player: Player) { player.settings.parse(settingsData) } - + fun parseVersion() { + saveFile ?: return + player.version = 0 + if (saveFile!!.containsKey("version")) { + player.version = saveFile!!["version"].toString().toInt() + } + } } diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt index d9d8a0c4f..351c8dc34 100644 --- a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt @@ -19,7 +19,6 @@ import org.json.simple.JSONObject import java.io.File import java.io.FileWriter import java.io.IOException -import java.lang.Math.ceil import javax.script.ScriptEngineManager import java.util.* @@ -36,6 +35,7 @@ class PlayerSaver (val player: Player){ } fun populate(): JSONObject { val saveFile = JSONObject() + saveVersion(saveFile) saveCoreData(saveFile) saveSkills(saveFile) saveSettings(saveFile) @@ -47,7 +47,6 @@ class PlayerSaver (val player: Player){ savePlayerMonitor(saveFile) saveMusicPlayer(saveFile) saveFamiliarManager(saveFile) - saveStateManager(saveFile) saveBankPinData(saveFile) saveHouseData(saveFile) saveAchievementData(saveFile) @@ -56,6 +55,7 @@ class PlayerSaver (val player: Player){ saveStatManager(saveFile) saveAttributes(saveFile) savePouches(saveFile) + savePOHStorageRoom(saveFile) contentHooks.forEach { it.savePlayer(player, saveFile) } return saveFile } @@ -96,6 +96,14 @@ class PlayerSaver (val player: Player){ player.pouchManager.save(root) } + fun savePOHStorageRoom(root: JSONObject) { + root.put("pohstorage", player.getPOHStorageState().toJson()) + } + + fun saveVersion(root: JSONObject){ + root.put("version", player.version) + } + fun saveAttributes(root: JSONObject){ if(player.gameAttributes.savedAttributes.isNotEmpty()){ val attrs = JSONArray() @@ -258,32 +266,23 @@ class PlayerSaver (val player: Player){ root.put("bankPinManager",bankPinManager) } - fun saveStateManager(root: JSONObject){ - val states = JSONArray() - player.states.forEach{key,clazz -> - if(clazz != null && clazz.pulse != null) { - val stateObj = JSONObject() - stateObj.put("stateKey", key) - clazz.save(stateObj) - states.add(stateObj) - } - } - root.put("states",states) - } - fun saveFamiliarManager(root: JSONObject){ val familiarManager = JSONObject() - val petDetails = JSONArray() + val petDetails = JSONObject() player.familiarManager.petDetails.map { - val detail = JSONObject() - detail.put("petId",it.key.toString()) - detail.put("hunger",it.value.hunger.toString()) - detail.put("growth",it.value.growth.toString()) - petDetails.add(detail) + val petId = it.key + val petData = JSONArray() + for (v in it.value) { + val pet = JSONObject() + pet.put("hunger",v.hunger.toString()) + pet.put("growth",v.growth.toString()) + petData.add(pet) + } + petDetails.put(petId.toString(), petData) } familiarManager.put("petDetails",petDetails) if(player.familiarManager.hasPet()){ - familiarManager.put("currentPet",(player.familiarManager.familiar as Pet).getItemIdHash().toString()) + familiarManager.put("currentPet",(player.familiarManager.familiar as Pet).getItemId().toString()) } else if (player.familiarManager.hasFamiliar()){ val familiar = JSONObject() familiar.put("originalId",player.familiarManager.familiar.originalId.toString()) @@ -328,7 +327,6 @@ class PlayerSaver (val player: Player){ fun saveGlobalData(root: JSONObject){ val globalData = JSONObject() - globalData.put("tutorialStage",player.savedData.globalData.tutorialStage.toString()) globalData.put("homeTeleportDelay",player.savedData.globalData.homeTeleportDelay.toString()) globalData.put("lumbridgeRope",player.savedData.globalData.hasTiedLumbridgeRope()) globalData.put("apprentice",player.savedData.globalData.hasSpokenToApprentice()) @@ -557,19 +555,19 @@ class PlayerSaver (val player: Player){ val skill = JSONObject() skill.put("id",i.toString()) skill.put("static",player.skills.staticLevels[i].toString()) - if(i == Skills.HITPOINTS){ - skill.put("dynamic",player.skills.lifepoints.toString()) - } else if (i == Skills.PRAYER){ - skill.put("dynamic",ceil(player.skills.prayerPoints).toInt().toString()) - } else { - skill.put("dynamic",player.skills.dynamicLevels[i].toString()) + skill.put("dynamic",player.skills.dynamicLevels[i].toString()) + if (i == Skills.HITPOINTS) { + skill.put("lifepoints",player.skills.lifepoints.toString()) + } + if (i == Skills.PRAYER) { + skill.put("prayerPoints",player.skills.prayerPoints.toString()) } skill.put("experience",player.skills.getExperience(i).toString()) skills.add(skill) } root.put("skills",skills) root.put("totalEXP",player.skills.experienceGained.toString()) - root.put("exp_multiplier",player.skills.experienceMutiplier.toString()) + root.put("exp_multiplier",player.skills.experienceMultiplier.toString()) if(player.skills.combatMilestone > 0 || player.skills.skillMilestone > 0){ val milestone = JSONObject() milestone.put("combatMilestone",player.skills.combatMilestone.toString()) @@ -604,15 +602,6 @@ class PlayerSaver (val player: Player){ val bankSecondary = saveContainer(player.bankSecondary) coreData.put("bankSecondary",bankSecondary) - val bBars = saveContainer(player.blastBars) - coreData.put("blastBars",bBars) - - val bOre = saveContainer(player.blastOre) - coreData.put("blastOre",bOre) - - val bCoal = saveContainer(player.blastCoal) - coreData.put("blastCoal",bCoal) - val bankTabs = JSONArray() for(i in player.bankPrimary.tabStartSlot.indices){ val tab = JSONObject() diff --git a/Server/src/main/core/game/node/entity/player/info/login/SaveVersionHooks.kt b/Server/src/main/core/game/node/entity/player/info/login/SaveVersionHooks.kt new file mode 100644 index 000000000..f1d5e4819 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/SaveVersionHooks.kt @@ -0,0 +1,104 @@ +package core.game.node.entity.player.info.login + +import content.data.Quests +import content.global.skill.summoning.pet.Pets +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import core.ServerConstants +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.Log +import org.rs09.consts.Items +import org.rs09.consts.Vars + +/** + * Runs one-time save-version-related hooks. + * @author Player Name + */ + +class SaveVersionHooks : LoginListener { + override fun login(player: Player) { + if (player.version < ServerConstants.CURRENT_SAVEFILE_VERSION) { + log(this::class.java, Log.FINE, "Upgrading ${player.name} from ${player.version} to ${ServerConstants.CURRENT_SAVEFILE_VERSION}") + + if (player.version < 1) { // GL !1811 + // Give out crafting hoods if the player bought any crafting capes when the hoods were not obtainable + var hasHoods = 0 + var hasCapes = 0 + val searchSpace = arrayOf(player.inventory, player.bankPrimary, player.bankSecondary) + for (container in searchSpace) { + for (hood in container.getAll(Item(Items.CRAFTING_HOOD_9782))) { + hasHoods += hood.amount + } + for (id in arrayOf(Items.CRAFTING_CAPE_9780, Items.CRAFTING_CAPET_9781)) { + for (cape in container.getAll(Item(id))) { + hasCapes += cape.amount + } + } + } + val need = hasCapes - hasHoods + if (need > 0) { + sendMessage(player, "You are being given $need crafting hood(s), because we think you bought $need crafting cape(s) when the hoods were still unobtainable.") + addItemOrBank(player, Items.CRAFTING_HOOD_9782, need) + } + + // Unlock Surok's Theme if eligible + if (getQuestStage(player, Quests.WHAT_LIES_BELOW) > 70) { + player.musicPlayer.unlock(250, false) + } + + // Migrate random-event saved location attributes to the uniform naming scheme + for (old in arrayOf("/save:drilldemon:original-loc","/save:evilbob:prevlocation","/save:freakyf:location","supexam:loc")) { + val oldloc = player.getAttribute(old, player.location) + if (oldloc != player.location) { + player.setAttribute("/save:original-loc", oldloc) + } + player.removeAttribute(old) + } + + // Set the missing tutorial island varp if eligible + if (getAttribute(player, "/save:tutorial:complete", false)) { + setVarp(player, 281, 1000, true) + } + } + + if (player.version < 2) { //GL !1799 + // Most of the migration for this MR happens in FamiliarManager.java, but we fix up any pet items here + val pets = Pets.values() + for (pet in pets) { + for (id in arrayOf(pet.babyItemId, pet.grownItemId, pet.overgrownItemId)) { + replaceAllItems(player, id, id) + // The trick here is that replaceAllItems ignores the item charge value, and will hence cause it to be lost, making all pets authentically stack again + } + } + } + + if (player.version < 3) { + // Damage control on Plague city. There are a few varbits that should have been set for spawning + when (getQuestStage(player, Quests.PLAGUE_CITY)){ + in 6..98 -> setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_EDMOND_TUNNELS, 1) // Edmond is in the tunnel + in 99..100 ->setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_RESCUE_ELENA, 1) // Elena is free + } + } + + if (player.version < 4) { //GL !2065 + replaceAllItems(player, Items.BLURBERRY_SPECIAL_9520, Items.BLURBERRY_SPECIAL_2064) + replaceAllItems(player, Items.BLURBERRY_SPECIAL_9521, Items.BLURBERRY_SPECIAL_2065) + replaceAllItems(player, Items.LAMP_6796, Items.LAMP_2528) + replaceAllItems(player, Items.RUNE_SHIELDH1_10667, Items.RUNE_SHIELDH1_7336) + replaceAllItems(player, Items.RUNE_SHIELDH2_10670, Items.RUNE_SHIELDH2_7342) + replaceAllItems(player, Items.RUNE_SHIELDH3_10673, Items.RUNE_SHIELDH3_7348) + replaceAllItems(player, Items.RUNE_SHIELDH4_10676, Items.RUNE_SHIELDH4_7354) + replaceAllItems(player, Items.RUNE_SHIELDH5_10679, Items.RUNE_SHIELDH5_7360) + replaceAllItems(player, Items.ADAMANT_SHIELDH1_10666, Items.ADAMANT_SHIELDH1_7334) + replaceAllItems(player, Items.ADAMANT_SHIELDH2_10669, Items.ADAMANT_SHIELDH2_7340) + replaceAllItems(player, Items.ADAMANT_SHIELDH3_10672, Items.ADAMANT_SHIELDH3_7346) + replaceAllItems(player, Items.ADAMANT_SHIELDH4_10675, Items.ADAMANT_SHIELDH4_7352) + replaceAllItems(player, Items.ADAMANT_SHIELDH5_10678, Items.ADAMANT_SHIELDH5_7358) + } + + // Finish up + player.version = ServerConstants.CURRENT_SAVEFILE_VERSION + } + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/BankPinManager.java b/Server/src/main/core/game/node/entity/player/link/BankPinManager.java index b4dc61d26..321b5f8bf 100644 --- a/Server/src/main/core/game/node/entity/player/link/BankPinManager.java +++ b/Server/src/main/core/game/node/entity/player/link/BankPinManager.java @@ -470,17 +470,25 @@ public class BankPinManager { } /** - * Cancels the pin. + * Cancels the pin and shows the correct interface. */ public void cancelPin(String... messages) { + doCancelPin(); + playAudio(player, Sounds.PIN_CANCEL_1042); + openSettings(messages); + } + + /** + * Actually cancels the pin. + */ + public void doCancelPin() { status = PinStatus.NO_PIN; pendingDelay = -1; pin = null; unlocked = false; - playAudio(player, Sounds.PIN_CANCEL_1042); - openSettings(messages); } + /** * Checks if the pin is an easy guess. * @return {@code True} if so. diff --git a/Server/src/main/core/game/node/entity/player/link/GlobalData.java b/Server/src/main/core/game/node/entity/player/link/GlobalData.java index 4286f1939..62873b245 100644 --- a/Server/src/main/core/game/node/entity/player/link/GlobalData.java +++ b/Server/src/main/core/game/node/entity/player/link/GlobalData.java @@ -10,12 +10,6 @@ import org.json.simple.JSONObject; * @author 'Vexia */ public final class GlobalData { - - /** - * Represents the tutorial stage. - */ - private int tutorialStage; - /** * Represents the home teleport delay. */ @@ -298,7 +292,6 @@ public final class GlobalData { private boolean macroDisabled = false; public void parse(JSONObject data){ - tutorialStage = Integer.parseInt( data.get("tutorialStage").toString()); homeTeleportDelay = Long.parseLong(data.get("homeTeleportDelay").toString()); lumbridgeRope = (boolean) data.get("lumbridgeRope"); apprentice = (boolean) data.get("apprentice"); @@ -467,22 +460,6 @@ public final class GlobalData { playerTestStage = stage; } - /** - * Gets the tutorialStage. - * @return The tutorialStage. - */ - public int getTutorialStage() { - return tutorialStage; - } - - /** - * Sets the tutorialStage. - * @param tutorialStage The tutorialStage to set. - */ - public void setTutorialStage(int tutorialStage) { - this.tutorialStage = tutorialStage; - } - /** * Gets the homeTeleportDelay. * @return The homeTeleportDelay. @@ -821,8 +798,8 @@ public final class GlobalData { } /** - * Gets the read plagues. - * @return The plague + * Gets the read plaques. + * @return The plaques */ public boolean[] getReadPlaques() { return readPlaques; diff --git a/Server/src/main/core/game/node/entity/player/link/IronmanMode.java b/Server/src/main/core/game/node/entity/player/link/IronmanMode.java index 2573b3fe4..3aa5e2a7a 100644 --- a/Server/src/main/core/game/node/entity/player/link/IronmanMode.java +++ b/Server/src/main/core/game/node/entity/player/link/IronmanMode.java @@ -5,7 +5,7 @@ package core.game.node.entity.player.link; * @author Vexia */ public enum IronmanMode { - // HARDCORE_DEAD has to be before Ultimate so that it does not adopt it's restrictions (on the basis of >= in IronmanManager.java?) + // HARDCORE_DEAD has to be before Ultimate so that it does not adopt its restrictions (on the basis of >= in IronmanManager.java) NONE(-1), STANDARD(5), HARDCORE(6), ULTIMATE(7); /** diff --git a/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java b/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java index 08adc715b..de6bb8233 100644 --- a/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java +++ b/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java @@ -3,7 +3,6 @@ package core.game.node.entity.player.link; import core.game.node.entity.player.Player; import core.game.node.scenery.Scenery; import core.tools.Log; -import core.tools.SystemLogger; import core.game.system.task.Pulse; import core.game.world.GameWorld; import core.game.world.map.Location; @@ -202,7 +201,12 @@ public final class PacketDispatch { * @param childId The child id. */ public void sendPlayerOnInterface(int interfaceId, int childId) { - PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, interfaceId, childId)); + // fixme right now for iface 68-71 the player is massive + // The zoom for the other windows is 2150 + // for these 4 individuals it should be 796 but dmc.setZoom doesn't work + DisplayModelContext dmc = new DisplayModelContext(player, interfaceId, childId); + dmc.setZoom(796); // this appears to do nothing + PacketRepository.send(DisplayModel.class, dmc); } /** @@ -219,6 +223,10 @@ public final class PacketDispatch { PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.MODEL, modelID,zoom,interfaceId,childId,new Object())); } + public void sendRepositionOnInterface(int interfaceId, int childId, int positionX, int positionY){ + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, interfaceId, childId, positionX, positionY)); + } + public void sendAngleOnInterface(int interfaceId, int childId, int zoom, int pitch, int yaw){ PacketRepository.send(InterfaceSetAngle.class, new DefaultContext(player, pitch, zoom, yaw, interfaceId, childId)); } @@ -422,8 +430,11 @@ public final class PacketDispatch { PacketRepository.send(CSConfigPacket.class, new CSConfigContext(player, id, value, type, params)); } - public void resetInterface(int id) - { + public void resetInterface(int id) { PacketRepository.send(ResetInterface.class, new InterfaceContext(player, 0, 0, id, false)); } + + public void sendLastLoginInfo() { + PacketRepository.send(LastLoginInfo.class, new PlayerContext(player)); + } } diff --git a/Server/src/main/core/game/node/entity/player/link/QuestData.java b/Server/src/main/core/game/node/entity/player/link/QuestData.java index aa58c395f..110c89e01 100644 --- a/Server/src/main/core/game/node/entity/player/link/QuestData.java +++ b/Server/src/main/core/game/node/entity/player/link/QuestData.java @@ -5,7 +5,6 @@ import core.game.node.item.Item; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import java.nio.ByteBuffer; import java.util.Arrays; /** @@ -97,19 +96,6 @@ public final class QuestData { witchsExperimentStage = Integer.parseInt( data.get("witchsExperimentStage").toString()); } - /** - * Saves the desert treasure node. - * @param buffer The buffer. - */ - private final void saveDesertTreasureNode(ByteBuffer buffer) { - buffer.put((byte) 8); - for (int i = 0; i < desertTreasure.length; i++) { - Item item = desertTreasure[i]; - buffer.putShort((short) item.getId()); - buffer.put((byte) item.getAmount()); - } - } - /** * Gets the draynorLever. * @return The draynorLever. diff --git a/Server/src/main/core/game/node/entity/player/link/SavedData.java b/Server/src/main/core/game/node/entity/player/link/SavedData.java index fc62f3a72..a0e005592 100644 --- a/Server/src/main/core/game/node/entity/player/link/SavedData.java +++ b/Server/src/main/core/game/node/entity/player/link/SavedData.java @@ -2,8 +2,6 @@ package core.game.node.entity.player.link; import core.game.node.entity.player.Player; -import java.nio.ByteBuffer; - /** * Represents a managing class of saved data related to ingame interactions, * such as questing data, npc talking data, etc. @@ -39,45 +37,6 @@ public class SavedData { this.player = player; } - /** - * Method used to save an activity var that isn't valued at default. - * @param buffer the buffer. - * @param var the variable to save. - */ - public static final void save(final ByteBuffer buffer, final Object var, final int index) { - if (var instanceof Integer ? (int) var != 0 : var instanceof Double ? (double) var != 0.0 : var instanceof Byte ? (byte) var != 0 : var instanceof Short ? (short) var != 0 : var instanceof Long ? (long) var != 0L : var instanceof Boolean ? (boolean) var != false : var != null) { - buffer.put((byte) index); - if (var instanceof Integer) { - buffer.putInt((int) var); - } else if (var instanceof Byte) { - buffer.put((byte) var); - } else if (var instanceof Short) { - buffer.putShort((short) var); - } else if (var instanceof Long) { - buffer.putLong((long) var); - } else if (var instanceof Boolean) { - buffer.put((byte) 1); - } else if (var instanceof Double) { - buffer.putDouble((double) var); - } else if (var instanceof double[]) { - double[] doubleArray = ((double[]) var); - for (int i = 0; i < doubleArray.length; i++) { - buffer.putDouble(doubleArray[i]); - } - } else if (var instanceof boolean[]) { - boolean[] booleanArray = ((boolean[]) var); - for (int i = 0; i < booleanArray.length; i++) { - buffer.put((byte) (booleanArray[i] ? 1 : 0)); - } - } else if (var instanceof int[]) { - int[] intArray = ((int[]) var); - for (int i = 0; i < intArray.length; i++) { - buffer.putInt(intArray[i]); - } - } - } - } - /** * Gets the boolean value. * @param value the value. @@ -87,15 +46,6 @@ public class SavedData { return value == 1; } - /** - * Gets the boolean value. - * @param buffer the buffer. - * @return the value. - */ - public static boolean getBoolean(ByteBuffer buffer) { - return getBoolean(buffer.get()); - } - /** * Gets the activityData. * @return The activityData. diff --git a/Server/src/main/core/game/node/entity/player/link/Settings.java b/Server/src/main/core/game/node/entity/player/link/Settings.java index 640e44723..920a65629 100644 --- a/Server/src/main/core/game/node/entity/player/link/Settings.java +++ b/Server/src/main/core/game/node/entity/player/link/Settings.java @@ -4,12 +4,8 @@ import core.game.system.config.ItemConfigParser; import org.json.simple.JSONObject; import core.game.node.entity.player.Player; import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; import core.net.packet.IoBuffer; -import java.nio.ByteBuffer; - import static core.api.ContentAPIKt.*; @@ -199,61 +195,9 @@ public final class Settings { } /** - * Writes the settings on the byte buffer. - * @param buffer The byte buffer. + * Parses the settings from the save file. + * @param settingsData The JSON object. */ - public void save(ByteBuffer buffer) { - buffer.put((byte) 1).put((byte) brightness).put((byte) musicVolume).put((byte) soundEffectVolume).put((byte) areaSoundVolume).put((byte) (singleMouseButton ? 1 : 0)).put((byte) (disableChatEffects ? 1 : 0)).put((byte) (splitPrivateChat ? 1 : 0)).put((byte) (acceptAid ? 1 : 0)).put((byte) (runToggled ? 1 : 0)).put((byte) publicChatSetting).put((byte) privateChatSetting).put((byte) clanChatSetting).put((byte) tradeSetting).put((byte) assistSetting).put(((byte) runEnergy)); - if (!player.getProperties().isRetaliating()) { - buffer.put((byte) 2); - } - if (specialEnergy != 100) { - buffer.put((byte) 3).put((byte) specialEnergy); - } - if (attackStyleIndex != 0) { - buffer.put((byte) 4).put((byte) attackStyleIndex); - } - buffer.put((byte) 0); - } - - /** - * Parses the settings from the byte buffer. - * @param buffer The byte buffer. - */ - public void parse(ByteBuffer buffer) { - int opcode; - while ((opcode = buffer.get() & 0xFF) != 0) { - switch (opcode) { - case 1: - brightness = buffer.get(); - musicVolume = buffer.get(); - soundEffectVolume = buffer.get(); - areaSoundVolume = buffer.get(); - singleMouseButton = buffer.get() == 1; - disableChatEffects = buffer.get() == 1; - splitPrivateChat = buffer.get() == 1; - acceptAid = buffer.get() == 1; - runToggled = buffer.get() == 1; - publicChatSetting = buffer.get(); - privateChatSetting = buffer.get(); - clanChatSetting = buffer.get(); - tradeSetting = buffer.get(); - assistSetting = buffer.get(); - runEnergy = buffer.get(); - break; - case 2: - player.getProperties().setRetaliating(false); - break; - case 3: - specialEnergy = buffer.get() & 0xFF; - break; - case 4: - attackStyleIndex = buffer.get(); - break; - } - } - } - public void parse(JSONObject settingsData){ brightness = Integer.parseInt( settingsData.get("brightness").toString()); musicVolume = Integer.parseInt( settingsData.get("musicVolume").toString()); diff --git a/Server/src/main/core/game/node/entity/player/link/SkullManager.java b/Server/src/main/core/game/node/entity/player/link/SkullManager.java index fd50bdeca..7b3f97c33 100644 --- a/Server/src/main/core/game/node/entity/player/link/SkullManager.java +++ b/Server/src/main/core/game/node/entity/player/link/SkullManager.java @@ -236,7 +236,7 @@ public final class SkullManager { } public void setDeepWilderness (boolean deepWildy) { - if(deepWildy) { + if(ServerConstants.ENHANCED_DEEP_WILDERNESS && deepWildy) { updateDWSkullIcon(); } else { removeDWSkullIcon(); diff --git a/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java b/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java index f5dbc2de4..72fd3005a 100644 --- a/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java +++ b/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java @@ -4,9 +4,11 @@ import core.game.component.Component; import core.game.node.entity.combat.spell.MagicSpell; import core.game.node.entity.player.Player; - import java.util.HashMap; import java.util.Map; +import java.util.Objects; + +import static core.api.ContentAPIKt.setVarbit; /** * Represents a managing class of a players spell book. @@ -15,7 +17,7 @@ import java.util.Map; public final class SpellBookManager { /** - * Represents the current interface if of the spellbook. + * Represents the current interface if of the spell book. */ private int spellBook = SpellBook.MODERN.getInterfaceId(); @@ -23,25 +25,26 @@ public final class SpellBookManager { * Constructs a new {@code SpellBookManager} {@code Object}. */ public SpellBookManager() { - /** + /* * empty. */ } /** * Sets the spell book. - * @param book + * @param book the spell book. */ public void setSpellBook(SpellBook book) { this.spellBook = book.getInterfaceId(); } /** - * Updates the - * @param player + * Updates the spell book. + * @param player the player. */ public void update(Player player) { - player.getInterfaceManager().openTab(new Component(SpellBook.forInterface(this.spellBook).getInterfaceId())); + player.getInterfaceManager().openTab(new Component(spellBook)); + setVarbit(player, 357, Objects.requireNonNull(SpellBook.forInterface(spellBook)).ordinal()); } /** @@ -53,7 +56,17 @@ public final class SpellBookManager { } /** - * Represents a characters spellbook. + * All the possible ways a SpellBook can get changed. + */ + public enum SpellbookChangeSource { + ALTAR, + MAGIC_CAPE_PERK, + SPELLBOOK_SWAP_CAST, + SPELLBOOK_SWAP_RESTORE + } + + /** + * Represents a characters spell book. * @author 'Vexia * @author Emperor */ @@ -131,5 +144,4 @@ public final class SpellBookManager { return spells.get(buttonId); } } - } \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java index 140ecf405..723b62b48 100644 --- a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java +++ b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java @@ -26,16 +26,6 @@ public class TeleportManager { */ public static final int WILDY_TELEPORT = 1 << 16 | 8; - /** - * The animations used in the home teleport. - */ - private final static int[] HOME_ANIMATIONS = {1722, 1723, 1724, 1725, 2798, 2799, 2800, 3195, 4643, 4645, 4646, 4847, 4848, 4849, 4850, 4851, 4852, 65535}; - - /** - * The graphics used in the home teleport. - */ - private final static int[] HOME_GRAPHICS = {775, 800, 801, 802, 803, 804, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 65535}; - /** * The entity being handled. */ @@ -62,7 +52,6 @@ public class TeleportManager { */ public TeleportManager(Entity entity) { this.entity = entity; - lastTeleport = TeleportType.HOME.getPulse(entity, ServerConstants.HOME_LOCATION); } /** @@ -108,6 +97,7 @@ public class TeleportManager { if (teleportType != -1) { if (entity instanceof Player) { Player p = (Player) entity; + p.scripts.setDelay(GameWorld.getTicks() + 12); p.getDialogueInterpreter().close(); } } @@ -116,16 +106,11 @@ public class TeleportManager { } this.teleportType = teleportType; entity.getWalkingQueue().reset(); - lastTeleport = currentTeleport; currentTeleport = type.getPulse(entity, location); entity.getPulseManager().clear(); - if (type == TeleportType.HOME) { - entity.getPulseManager().run(type.getPulse(entity, location)); - } else { - entity.lock(12); - entity.getImpactHandler().setDisabledTicks(teleportType == -1 ? 5 : 12); - GameWorld.getPulser().submit(currentTeleport); - } + entity.lock(12); + entity.getImpactHandler().setDisabledTicks(teleportType == -1 ? 5 : 12); + GameWorld.getPulser().submit(currentTeleport); if (entity instanceof Player) { ((Player) entity).getInterfaceManager().close(); } @@ -135,7 +120,7 @@ public class TeleportManager { /** * Fires a random event. * @param entity The entity teleporting. - * @param location The destination lcoation. + * @param location The destination location. */ public static void fireRandom(Entity entity, Location location) { if (entity instanceof Player && entity.getTeleporter().getTeleportType() == 0) { @@ -143,22 +128,6 @@ public class TeleportManager { } } - /** - * Get the home teleport audio based on tick count. - * @param count - */ - private static int getAudio(int count){ - switch(count){ - case 0: - return 193; - case 4: - return 194; - case 11: - return 195; - } - return -1; - } - /** * Gets the entity. * @return the Entity @@ -167,14 +136,6 @@ public class TeleportManager { return entity; } - /** - * Gets the last teleport pulse. - * @return the Pulse - */ - public final Pulse getLastTeleport() { - return lastTeleport; - } - /** * Gets the current teleport pulse. * @return the Pulse @@ -183,7 +144,6 @@ public class TeleportManager { return currentTeleport; } - /** * Represents a NodeType for Teleporter * @author SonicForce41 @@ -330,57 +290,6 @@ public class TeleportManager { }; } }, - HOME(new TeleportSettings(4847, 4857, 800, 804)) { - @Override - public Pulse getPulse(final Entity entity, final Location location) { - return new TeleportPulse(entity) { - int count; - Player player; - - @Override - public boolean pulse() { - switch (count) { - case 18: - player.getProperties().setTeleportLocation(location); - return true; - default: - playGlobalAudio(entity.getLocation(), getAudio(count)); - player.getPacketDispatch().sendGraphic(HOME_GRAPHICS[count]); - player.getPacketDispatch().sendAnimation(HOME_ANIMATIONS[count]); - break; - } - count++; - return false; - } - @Override - public void start() { - player = ((Player) entity); - /*if (player.getSavedData().getGlobalData().getHomeTeleportDelay() > System.currentTimeMillis() && !player.isDonator()) { - long milliseconds = player.getSavedData().getGlobalData().getHomeTeleportDelay() - System.currentTimeMillis(); - int minutes = (int) Math.round(milliseconds / 120000); - if (minutes > 15) { - player.getSavedData().getGlobalData().setHomeTeleportDelay(System.currentTimeMillis() + 1200000); - milliseconds = player.getSavedData().getGlobalData().getHomeTeleportDelay() - System.currentTimeMillis(); - minutes = (int) Math.round(milliseconds / 120000); - } - if (minutes != 0) { - player.getPacketDispatch().sendMessage("You need to wait another " + minutes + " " + (minutes == 1 ? "minute" : "minutes") + " to cast this spell."); - stop(); - return; - } - }*/ - super.start(); - } - - @Override - public void stop() { - super.stop(); - entity.getAnimator().forceAnimation(new Animation(-1)); - player.graphics(new Graphics(-1)); - } - }; - } - }, OBELISK(new TeleportSettings(8939, 8941, 661, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { diff --git a/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java b/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java index 1643dac95..875798165 100644 --- a/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java +++ b/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java @@ -114,13 +114,12 @@ public class AchievementDiary { } child++; } - // sendString(player, builder.toString(), 11); - //Changes the size of the scroll bar - //player.getPacketDispatch().sendRunScript(1207, "i", new Object[] { 330 }); - //sendString(player, builder.toString(), 11); if (!player.getInterfaceManager().isOpened()) { player.getInterfaceManager().open(new Component(DIARY_COMPONENT)); } + // Changes the size of the scroll bar (see 1207.cs2 for more) + // (args1: 1 is to start from top of scroll) (args0: child-12 lines to display) + player.getPacketDispatch().sendRunScript(1207, "ii", 1, child - 10); } /** @@ -207,7 +206,7 @@ public class AchievementDiary { } if(complete){ completedLevels.add(level); - } else if(completedLevels.contains(level)) completedLevels.remove(level); + } else if(completedLevels.contains(level)) completedLevels.remove((Object) level); } } @@ -225,18 +224,6 @@ public class AchievementDiary { drawStatus(player); } - public boolean checkComplete(DiaryLevel level){ - if(type != DiaryType.LUMBRIDGE && level == DiaryLevel.BEGINNER){ - return false; - } - - if(level == DiaryLevel.BEGINNER){ - return completedLevels.contains(level.ordinal()); - } - - return completedLevels.contains(level.ordinal() - 1); - } - /** * Sends a string on the diary interface. * @param player the player. @@ -489,7 +476,7 @@ public class AchievementDiary { /** * Determines if a replacement reward can be given for the particular diary and level. - * Checks to make sure the player has completed the level and claimed the rewards, and has not completed + * Checks to make sure the player has completed the level and claimed the rewards, and has not claimed * the next diary level. * @param player the player to check * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. @@ -497,11 +484,11 @@ public class AchievementDiary { * @return whether or not a replacement can be granted. */ public static boolean canReplaceReward(Player player, DiaryType type, int level) { - Item reward = type.getRewards(level)[0]; - return hasCompletedLevel(player, type, level) - && !hasCompletedLevel(player, type, level + 1) + Item reward = type.getRewards(level)[0]; + boolean claimed = hasCompletedLevel(player, type, level) && hasClaimedLevelRewards(player, type, level) && !player.hasItem(reward); + return level == 2 ? claimed : claimed && !hasClaimedLevelRewards(player, type, level+1); } /** @@ -543,14 +530,18 @@ public class AchievementDiary { /** * Checks if a player can claim the rewards for the given level of the given diary - * Checks to make sure the player hasn't completed the next level. + * Checks to make sure the player hasn't claimed the next level. * @param player the player to check * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. * @param level the level to check * @return whether or not the player can claim the rewards */ public static boolean canClaimLevelRewards(Player player, DiaryType type, int level) { - return !hasCompletedLevel(player, type, level + 1) && hasCompletedLevel(player, type, level) && !hasClaimedLevelRewards(player, type, level); + if (level == 2) + // Cannot be a higher level to claim + return hasCompletedLevel(player, type, level) && !hasClaimedLevelRewards(player, type, level); + else + return !hasClaimedLevelRewards(player, type, level + 1) && hasCompletedLevel(player, type, level) && !hasClaimedLevelRewards(player, type, level); } /** diff --git a/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java b/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java index a91f4b5bc..dbbb06e81 100644 --- a/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java +++ b/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java @@ -1,8 +1,8 @@ package core.game.node.entity.player.link.diary; import core.game.node.entity.player.Player; -import org.rs09.consts.Items; import core.game.node.item.Item; +import org.rs09.consts.Items; /** * An achievement diary type. @@ -34,14 +34,14 @@ public enum DiaryType { "Use Vigroy and Hajedy's cart service", "Earn 100% favour in the village of Tai Bwo Wannai Cleanup", // todo tai bwo wannai cleanup "Cook a spider on stick", // todo tai bwo wannai cleanup - "Charter the Lady of the Waves from Cairn Isle to Port Khazard", // todo verify + "Charter the Lady of the Waves from Cairn Isle to Port Khazard", "Cut a log from a teak tree", "Cut a log from a mahogany tree", "Catch a karambwan", // todo need Tai Bwo Wannai Trio "Exchange gems, a gout tuber, trading sticks for a machete", // todo "Use the gnome glider to travel to Karamja", - "Grow a healthy fruit tree in the patch near Brimhaven", // todo verify - "Trap a Horned Graahk", // todo need to implement pitfall trapping + "Grow a healthy fruit tree in the patch near Brimhaven", + "Trap a Horned Graahk", "Chop the vines to gain deeper access to Brimhaven Dungeon", "Cross the lava using the stepping stones within Brimhaven

Dungeon", "Climb the stairs within Brimhaven Dungeon", @@ -118,7 +118,7 @@ public enum DiaryType { "Select a colour for a new kitten", // TODO need ring of charos(a) and garden of tranquility to start "Use the shortcut under the wall, north-west of the Grand

Exchange", "Enter the A Soul's Bane rift", - "Teleport to the Digsite using a Digsite pendant", // TODO need Digsite and museum + "Teleport to the Digsite using a Digsite pendant", "Craft an earth tiara on the Earth Altar", "Pickpocket a guard in the Varrock Palace courtyard", "Use the teleport to Varrock spell", @@ -140,7 +140,7 @@ public enum DiaryType { "Craft an air battlestaff", "Give your player-owned house a tropical wood or fancy stone

finish at the Varrock estate agent's", "Make a Varrock teleport tablet on a mahogany lectern", - "Obtain a new set of Family Crest gauntlets from Dimintheis", // TODO need family crest + "Obtain a new set of Family Crest gauntlets from Dimintheis", "Make a Waka Canoe near Edgeville", "Use the Home Teleport spell in the Ancient Magicks spellbook

to teleport to Edgeville", "Use the skull sceptre to teleport to Barbarian Village" diff --git a/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java b/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java index e859a598d..2bda2ca57 100644 --- a/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java +++ b/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java @@ -1,5 +1,6 @@ package core.game.node.entity.player.link.emote; +import content.data.Quests; import core.game.container.impl.EquipmentContainer; import core.game.node.entity.player.info.Rights; import core.game.world.map.Direction; @@ -14,6 +15,7 @@ import core.game.world.GameWorld; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; +import static core.api.ContentAPIKt.playJingle; /** * Represents an emote. * @@ -50,10 +52,10 @@ public enum Emotes { SHRUG(8, Animation.create(2113)), CHEER(9, Animation.create(862)), BECKON(10, Animation.create(864)), - //Switch laugh id 11, to 12, and switch Jump id 12 to 11. Id's were mismatched. - //This caused the LAUGH to proc JUMP_FOR_JOY and JUMP_FOR_JOY to proc LAUGH! :) - JUMP_FOR_JOY(11, Animation.create(2109)), - LAUGH(12, Animation.create(861)), + //Switch laugh id 11, to 12, and switch Jump id 12 to 11. Id's were mismatched. + //This caused the LAUGH to proc JUMP_FOR_JOY and JUMP_FOR_JOY to proc LAUGH! :) + JUMP_FOR_JOY(11, Animation.create(2109)), + LAUGH(12, Animation.create(861)), YAWN(13, Animation.create(2111)) { @Override public void play(Player player) { @@ -105,7 +107,7 @@ public enum Emotes { public void play(Player player) { if(player.getLocation().getRegionId() == 13206 && !player.getAttribute("mistag-greeted", false)) { RegionManager.getLocalNpcs(player).forEach(npc -> { - if (npc.getId() == 2084 && npc.getLocation().withinDistance(player.getLocation(), 3) && player.getQuestRepository().getQuest("Lost Tribe").getStage(player) == 45) { + if (npc.getId() == 2084 && npc.getLocation().withinDistance(player.getLocation(), 3) && player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 45) { player.getDialogueInterpreter().open(2084,npc,"greeting"); player.setAttribute("/save:mistag-greeted",true); } @@ -166,7 +168,12 @@ public enum Emotes { } }, SNOWMAN_DANCE(40, Animation.create(7531), "This emote can be unlocked by playing a Christmas holiday event."), - AIR_GUITAR(41, Animation.create(2414), Graphics.create(1537), "This emote can be accessed by unlocking 200 pieces of music."), + AIR_GUITAR(41, Animation.create(2414), Graphics.create(1537), "This emote can be accessed by unlocking 200 pieces of music.") { + public void play(Player player) { + playJingle(player, 302); + super.play(player); + } + }, SAFETY_FIRST(42, Animation.create(8770), Graphics.create(1553), "You can't use this emote yet. Visit the Stronghold of Player safety to
unlock it."), EXPLORE(43, Animation.create(9990), Graphics.create(1734), "You can't use this emote yet. You must complete all the Lumbridge
and Draynor beginner tasks to unlock it."), TRICK(44, Animation.create(10530), Graphics.create(1863), "This emote can be unlocked by playing a Halloween holiday event."), @@ -174,7 +181,7 @@ public enum Emotes { GIVE_THANKS(46, "This emote can be unlocked by playing a Thanksgiving holiday event.") { @Override public void play(final Player player) { - GameWorld.getPulser().submit(new Pulse(1, player) { + GameWorld.getPulser().submit(new Pulse(1, player) { int counter; @Override @@ -291,7 +298,7 @@ public enum Emotes { } /** - * Handles the reward button for an emote. + * Handles the button for an emote. * * @param player the player. * @param buttonId the button id. @@ -415,4 +422,4 @@ public enum Emotes { return lockedMessage; } -} +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java b/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java index 77f55b618..163cdadc5 100644 --- a/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java +++ b/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java @@ -10,9 +10,7 @@ import core.net.packet.context.StringContext; import core.net.packet.out.MusicPacket; import core.net.packet.out.StringPacket; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; +import java.util.*; import static core.api.ContentAPIKt.*; @@ -36,7 +34,7 @@ public final class MusicPlayer { /** * The configuration ids. */ - private static final int[] CONFIG_IDS = { 20, 21, 22, 23, 24, 25, 298, 311, 346, 414, 464, 598, 662, 721, 906, 1009, 1104, 1136, 180, 1202, 1381, 1394, }; + private static final int[] CONFIG_IDS = { 20, 21, 22, 23, 24, 25, 298, 311, 346, 414, 464, 598, 662, 721, 906, 1009, 1104, 1136, 1180, 1202}; /** * The player. @@ -139,12 +137,11 @@ public final class MusicPlayer { int[] values = new int[CONFIG_IDS.length]; for (MusicEntry entry : unlocked.values()) { int listIndex = entry.getIndex(); - int index = (listIndex + 1) / 32; + int index = listIndex / 32; if (index >= CONFIG_IDS.length) { - continue; } - values[index] |= 1 << (listIndex - (index * 32)); + values[index] |= 1 << (listIndex & 31); } for (int i = 0; i < CONFIG_IDS.length; i++) { setVarp(player, CONFIG_IDS[i], values[i]); @@ -200,10 +197,9 @@ public final class MusicPlayer { public void unlock(int id, boolean play) { MusicEntry entry = MusicEntry.forId(id); if (entry == null) { - return; } - if (!unlocked.containsKey(entry.getIndex())) { + if (!entry.getName().equals(" ") && !unlocked.containsKey(entry.getIndex())) { unlocked.put(entry.getIndex(), entry); player.getPacketDispatch().sendMessage("You have unlocked a new music track: " + entry.getName() + "."); refreshList(); diff --git a/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java b/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java index e8fba525e..41f7dfbf2 100644 --- a/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java +++ b/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java @@ -1,5 +1,6 @@ package core.game.node.entity.player.link.prayer; +import content.data.Quests; import core.game.node.entity.player.link.diary.DiaryType; import core.game.node.entity.skill.SkillBonus; import core.game.node.entity.skill.Skills; @@ -221,11 +222,20 @@ public enum PrayerType { * @return True if it is permitted. */ public boolean permitted(final Player player) { - if (player.getSkills().getStaticLevel(Skills.PRAYER) < getLevel() || player.getSkills().getStaticLevel(Skills.DEFENCE) < defenceReq) { - playAudio(player, Sounds.PRAYER_OFF_2673); - player.getDialogueInterpreter().sendDialogue("You need a Prayer level of " + getLevel() + (player.getSkills().getStaticLevel(Skills.DEFENCE) < defenceReq ? (" and a Defence level of " + defenceReq) : "") + " to use " + StringUtils.formatDisplayName(name().toLowerCase().replace("_", " ")) + "."); + if (!hasLevelStat(player, Skills.PRAYER, level) || !hasLevelStat(player, Skills.DEFENCE, defenceReq)) { + sendDialogue(player, "You need a " + (!hasLevelStat(player, Skills.PRAYER, level) ? "Prayer level of " + level + (!hasLevelStat(player, Skills.DEFENCE, defenceReq) ? " and a " : "") : "") + (!hasLevelStat(player, Skills.DEFENCE, defenceReq) ? "Defence level of " + defenceReq : "") + " to use " + StringUtils.formatDisplayName(name().toLowerCase().replace("_", " ")) + "."); return false; } + + if (defenceReq == 65 || defenceReq == 70) { + if (!hasRequirement(player, Quests.KINGS_RANSOM)) { + return false; + } else { + if (getVarbit(player, 3909) != 8) { + setVarbit(player, 3909, 8, false); + } + } + } return true; } @@ -241,17 +251,12 @@ public enum PrayerType { player.getPrayer().getActive().add(this); iconify(player, getIcon(player, this)); playAudio(player, sound.id); - - if (this == PrayerType.PIETY - && new ZoneBorders(2732, 3467, 2739, 3471, 0).insideBorder(player)) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 3); - } - player.dispatch (new PrayerActivatedEvent(this)); + player.dispatch (new PrayerActivatedEvent(this)); } else { player.getPrayer().getActive().remove(this); playAudio(player, Sounds.CANCEL_PRAYER_2663); findNextIcon(player); - player.dispatch (new PrayerDeactivatedEvent(this)); + player.dispatch (new PrayerDeactivatedEvent(this)); } return true; } diff --git a/Server/src/main/core/game/node/entity/player/link/quest/Quest.java b/Server/src/main/core/game/node/entity/player/link/quest/Quest.java index 5819ee669..e210f04c4 100644 --- a/Server/src/main/core/game/node/entity/player/link/quest/Quest.java +++ b/Server/src/main/core/game/node/entity/player/link/quest/Quest.java @@ -1,5 +1,6 @@ package core.game.node.entity.player.link.quest; +import content.data.Quests; import core.game.component.Component; import core.game.node.entity.player.Player; import core.plugin.Plugin; @@ -50,9 +51,9 @@ public abstract class Quest implements Plugin { public static final int REWARD_COMPONENT = 277; /** - * The name of the quest. + * The quest as a Quests item (currently only used for the quest's name). */ - private final String name; + private final Quests quest; /** * The index id of the quest. @@ -75,15 +76,30 @@ public abstract class Quest implements Plugin { private final int[] configs; /** - * Constructs a new {@Code Quest} {@Code Object} - * @param name The name. - * @param index The index. - * @param buttonId The button Id. - * @param questPoints The rewarded quest points. - * @param configs The configs. + * Constructs a new {@link Quest} + * @param quest of the quest. Prereqs reference this + * @param index of the quest, usually buttonId + 1 + * @param buttonId of the quest on the quest list in game + * @param questPoints rewarded after completing quest + * @param configs of Varp/Varbit and values to set the quest color to red/yellow/green. e.g. {234, 0, 1, 10} + *

+ * Configs are made of either 4/5 numbers:
+ * 4 numbers: {1: VARP to set, 2: red quest name, 3: yellow quest name, 4: green quest name}
+ * 5 numbers: {1: VARP(Ignored), 2: VARPBIT to set, 3: red quest name, 4: yellow quest name, 5: green quest name}
+ *
+ * VARP/VARPBIT is set to values before/during/after quest at stage 0/1-99/100. + * Get these values from the VARPTOOL.
+ *
+ * If you see VARP (e.g. ./get_varp.sh 120):
+ * if (VARP[26] == 80 || VARP[26] == 90) return 2; if (VARP[26] == 0) return 0; return 1; }; if (arg0 == 89)
+ * Use 4 numbers: {26, 0, 1, 80} -> {VARP, return 0, return 1, return 2}
+ *
+ * If you see VARPBIT (e.g. ./get_varp.sh 119):
+ * if (VARPBIT[451] > 1) return 2; if (VARPBIT[451] == 0) return 0; return 1; }; if (arg0 == 88)
+ * Use 5 numbers: {0, 451, 0, 1, 2} -> {Ignore, VARPBIT, return 0, return 1, return 2}
*/ - public Quest(String name, int index, int buttonId, int questPoints, int...configs) { - this.name = name; + public Quest(Quests quest, int index, int buttonId, int questPoints, int...configs) { + this.quest = quest; this.index = index; this.buttonId = buttonId; this.questPoints = questPoints; @@ -116,7 +132,7 @@ public abstract class Quest implements Plugin { for (int i = 0; i < 311; i++) { player.getPacketDispatch().sendString("" , JOURNAL_COMPONENT, i); } - player.getPacketDispatch().sendString("" + getName() + "", JOURNAL_COMPONENT, 2); + player.getPacketDispatch().sendString("" + getQuest() + "", JOURNAL_COMPONENT, 2); } @@ -125,8 +141,8 @@ public abstract class Quest implements Plugin { * @param player The player. */ public void finish(Player player) { - if(player.getQuestRepository().isComplete(name)) { - throw new IllegalStateException("Tried to complete quest " + name + " twice, which is not allowed!"); + if(player.getQuestRepository().isComplete(quest)) { + throw new IllegalStateException("Tried to complete quest " + quest + " twice, which is not allowed!"); } for (int i = 0; i < 18; i++) { if (i == 9 || i == 3 || i == 6) { @@ -137,9 +153,12 @@ public abstract class Quest implements Plugin { player.getQuestRepository().setStage(this, 100); player.getQuestRepository().incrementPoints(getQuestPoints()); player.getQuestRepository().syncronizeTab(player); - player.getInterfaceManager().open(new Component(277)); + player.getInterfaceManager().open(new Component(277).setCloseEvent((p, c) -> { + this.questCloseEvent(p, c); + return true; + })); player.getPacketDispatch().sendString("" + player.getQuestRepository().getPoints() + "", 277, 7); - player.getPacketDispatch().sendString("You have completed the " + getName() + " Quest!", 277, 4); + player.getPacketDispatch().sendString("You have completed the " + getQuest() + " Quest!", 277, 4); player.getPacketDispatch().sendMessage("Congratulations! Quest complete!"); int questJingles[] = {152, 153, 154}; playJingle(player, questJingles[new Random().nextInt(3)]); @@ -151,6 +170,12 @@ public abstract class Quest implements Plugin { */ public void reset(Player player) {} + /** + * Function callback when closing the quest. + * Override this to follow up on dialogue after the component closes. + */ + public void questCloseEvent(Player player, Component component) {} + /** * Draws a line on the journal component. * @param player The player. @@ -190,6 +215,20 @@ public abstract class Quest implements Plugin { player.getPacketDispatch().sendString(crossed ? "" + send + "" : send, JOURNAL_COMPONENT, line); } + /** + * Limits the quest log scroll to the number of lines minus 9. + * Assumes that you start at line = 11 or line = 12. + * Call this function at the end of the drawJournal function like: limitScroll(player, line); + * @param player The player. + * @param line The number of lines to scroll. Due to sendRunScript, it handles less than 12 lines pretty well. + * @param startFromTop Whether to open the log at the top, defaults to opening the log at the very bottom. + */ + public void limitScrolling(Player player, int line, boolean startFromTop) { + // sendRunScript reverses the objects you pass in + // (args1: 0 is to start from bottom of scroll) (args0: child-12 lines to display) + player.getPacketDispatch().sendRunScript(1207, "ii", startFromTop ? 1 : 0, line - 9); // -9 to give text some padding instead of line - 11 or 12 + } + /** * Draws text on the quest reward component. * @param player The player. @@ -217,8 +256,13 @@ public abstract class Quest implements Plugin { */ public int[] getConfig(Player player, int stage) { if (configs.length < 4) { - throw new IndexOutOfBoundsException("Quest -> " + name + " configs array length was not valid. config length = " + configs.length + "!"); + throw new IndexOutOfBoundsException("Quest -> " + quest + " configs array length was not valid. config length = " + configs.length + "!"); } + if (configs.length >= 5) { + // {questVarpId, questVarbitId, valueToSet} + return new int[] {configs[0], configs[1], stage == 0 ? configs[2] : stage >= 100 ? configs[4] : configs[3]}; + } + // {questVarpId, valueToSet} return new int[] {configs[0], stage == 0 ? configs[1] : stage >= 100 ? configs[3] : configs[2]}; } @@ -265,8 +309,8 @@ public abstract class Quest implements Plugin { * Gets the name. * @return the name. */ - public String getName() { - return name; + public Quests getQuest() { + return quest; } /** @@ -293,17 +337,9 @@ public abstract class Quest implements Plugin { return questPoints; } - /** - * Gets the configs. - * @return the configs. - */ - public int[] getConfigs() { - return configs; - } - @Override public String toString() { - return "Quest [name=" + name + ", index=" + index + ", buttonId=" + buttonId + ", questPoints=" + questPoints + ", configs=" + Arrays.toString(configs) + "]"; + return "Quest [name=" + quest + ", index=" + index + ", buttonId=" + buttonId + ", questPoints=" + questPoints + ", configs=" + Arrays.toString(configs) + "]"; } } diff --git a/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java b/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java index ac7ac5cee..02ccf6b29 100644 --- a/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java +++ b/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java @@ -1,9 +1,9 @@ package core.game.node.entity.player.link.quest; +import content.data.Quests; import core.game.node.entity.player.Player; import core.tools.Log; -import core.tools.SystemLogger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; @@ -25,7 +25,7 @@ public final class QuestRepository { /** * The static mapping of instanced quests. */ - private static final Map QUESTS = new TreeMap<>(); + private static final Map QUESTS = new TreeMap<>(); /** * The mapping of quest indexes with related stages. @@ -74,8 +74,17 @@ public final class QuestRepository { int[] config = null; for(Quest quest : QUESTS.values()){ config = quest.getConfig(player,getStage(quest)); - - setVarp(player, config[0], config[1]); + + // {questVarpId, questVarbitId, valueToSet} + if (config.length == 3) { + // This is to set quests with VARPBIT, ignoring VARP value + setVarbit(player, config[1], config[2]); + } else { + // This is the original VARP quests + // {questVarpId, valueToSet} + setVarp(player, config[0], config[1]); + } + quest.updateVarps(player); } } @@ -91,7 +100,7 @@ public final class QuestRepository { if(oldStage < stage) { quests.put(quest.getIndex(), stage); } else { - log(this.getClass(), Log.WARN, String.format("Nonmonotonic QuestRepository.setStage call for player \"%s\", quest \"%s\", old stage %d, new stage %d", player.getName(), quest.getName(), oldStage, stage)); + log(this.getClass(), Log.WARN, String.format("Nonmonotonic QuestRepository.setStage call for player \"%s\", quest \"%s\", old stage %d, new stage %d", player.getName(), quest.getQuest(), oldStage, stage)); } } @@ -189,51 +198,49 @@ public final class QuestRepository { /** * Checks if the quest is complete. * - * @param name The name of the quest. + * @param quest The quest. * @return {@code True} if so. */ - public boolean isComplete(String name) { - Quest quest = getQuest(name); - if (quest == null) { - log(this.getClass(), Log.ERR, "Error can't check if quest is complete for " + name); + public boolean isComplete(Quests quest) { + Quest theQuest = getQuest(quest); + if (theQuest == null) { + log(this.getClass(), Log.ERR, "Error can't check if quest is complete for " + quest); return false; } - return quest.getStage(player) >= 100; + return theQuest.getStage(player) >= 100; } /** * Checks if the quest has at least started. * - * @param name The name of the quest. + * @param quest The quest by id. * @return {@code True} if so. */ - public boolean hasStarted(String name) { - Quest quest = getQuest(name); + public boolean hasStarted(Quests quest) { + Quest theQuest = getQuest(quest); if (quest == null) { - log(this.getClass(), Log.ERR, "Error can't check if quest is complete for " + name); + log(this.getClass(), Log.ERR, "Error can't check if quest is complete for " + quest); return false; } - return quest.getStage(player) > 0; + return theQuest.getStage(player) > 0; } /** - * Gets the stage of quest by name. - * - * @param name The name of the quest. + * Gets the stage of quest by id. + * @param quest The quest. * @return The stage. */ - public int getStage(String name) { - var quest = QUESTS.get(name); - if (quest == null) { + public int getStage(Quests quest) { + var theQuest = QUESTS.get(quest); + if (theQuest == null) { return 0; } - return getStage(quest); + return getStage(theQuest); } /** * Gets the stage of a quest. - * * @param quest The quest. * @return The stage. */ @@ -242,13 +249,12 @@ public final class QuestRepository { } /** - * Gets the quest by name. - * - * @param name The name. + * Gets the quest by id. + * @param quest The quest. * @return The quest. */ - public Quest getQuest(String name) { - return QUESTS.get(name); + public Quest getQuest(Quests quest) { + return QUESTS.get(quest); } /** @@ -275,7 +281,7 @@ public final class QuestRepository { * @param quest The quest. */ public static void register(Quest quest) { - QUESTS.put(quest.getName(), quest); + QUESTS.put(quest.getQuest(), quest); } /** @@ -283,7 +289,7 @@ public final class QuestRepository { * * @return the quests. */ - public static Map getQuests() { + public static Map getQuests() { return QUESTS; } diff --git a/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java index c58521aab..22fab5af3 100644 --- a/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java +++ b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java @@ -161,7 +161,8 @@ public final class TradeContainer extends Container { String targetMac = target.getDetails().getMacAddress(); String playerHost = player.getDetails().getCompName(); String targetHost = target.getDetails().getCompName(); - if (item.getId() == 11174 || item.getId() == 11173 || item.getId() == 759) { + // Ironman trading exceptions for Shield of Arrav and Heroes Quest + if (item.getId() == 11174 || item.getId() == 11173 || item.getId() == 759 || item.getId() == 1586 || item.getId() == 1577) { return true; } if (player.getIronmanManager().isIronman() || target != null && target.getIronmanManager().isIronman()) { diff --git a/Server/src/main/core/game/node/entity/skill/Skills.java b/Server/src/main/core/game/node/entity/skill/Skills.java index 88d56aac9..06a978589 100644 --- a/Server/src/main/core/game/node/entity/skill/Skills.java +++ b/Server/src/main/core/game/node/entity/skill/Skills.java @@ -1,34 +1,32 @@ package core.game.node.entity.skill; -import content.global.skill.skillcapeperks.SkillcapePerks; -import core.game.event.DynamicSkillLevelChangeEvent; -import core.game.event.XPGainEvent; import content.global.handlers.item.equipment.brawling_gloves.BrawlingGloves; import content.global.handlers.item.equipment.brawling_gloves.BrawlingGlovesManager; +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.ServerConstants; +import core.game.event.DynamicSkillLevelChangeEvent; +import core.game.event.XPGainEvent; import core.game.node.entity.Entity; import core.game.node.entity.combat.ImpactHandler; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.PlayerMonitor; import core.game.node.entity.player.link.request.assist.AssistSession; import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; import core.net.packet.PacketRepository; import core.net.packet.context.SkillContext; import core.net.packet.out.SkillLevel; +import core.plugin.CorePluginTypes.XPGainPlugins; import kotlin.Pair; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import core.game.node.entity.player.info.PlayerMonitor; -import core.game.world.GameWorld; -import core.game.world.repository.Repository; -import core.plugin.CorePluginTypes.XPGainPlugins; import org.rs09.consts.Items; -import org.rs09.consts.Sounds; -import java.nio.ByteBuffer; import java.util.ArrayList; import static core.api.ContentAPIKt.getWorldTicks; -import static core.api.ContentAPIKt.playAudio; import static java.lang.Math.floor; import static java.lang.Math.max; @@ -41,7 +39,7 @@ public final class Skills { /** * Represents the constant modifier of experience. */ - public double experienceMutiplier = 5.0; + public double experienceMultiplier = 1.0; /** * The maximum experience multiplier. @@ -289,7 +287,7 @@ public final class Skills { private double getExperienceMod(int slot, double experience, boolean playerMod, boolean multiplyer) { //Keywords for people ctrl + Fing the project //xprate xp rate xp multiplier skilling rate - return experienceMutiplier; + return experienceMultiplier; /*if (!(entity instanceof Player)) { return 1.0; } @@ -363,46 +361,38 @@ public final class Skills { int staticLevel = getStaticLevel(i); setLevel(i, staticLevel); } - if (entity instanceof Player) { - playAudio(entity.asPlayer(), Sounds.PRAYER_RECHARGE_2674); - } rechargePrayerPoints(); } - /** - * Parses the skill data from the buffer. - * @param buffer The byte buffer. - */ - public void parse(ByteBuffer buffer) { - for (int i = 0; i < 24; i++) { - experience[i] = ((double) buffer.getInt() / 10D); - dynamicLevels[i] = buffer.get() & 0xFF; - if (i == HITPOINTS) { - lifepoints = dynamicLevels[i]; - } else if (i == PRAYER) { - prayerPoints = dynamicLevels[i]; - } - staticLevels[i] = buffer.get() & 0xFF; - } - experienceGained = buffer.getInt(); - } - public void parse(JSONArray skillData){ for(int i = 0; i < skillData.size(); i++){ JSONObject skill = (JSONObject) skillData.get(i); int id = Integer.parseInt( skill.get("id").toString()); - dynamicLevels[id] = Integer.parseInt( skill.get("dynamic").toString()); - if (id == HITPOINTS) { - lifepoints = dynamicLevels[i]; - } else if (id == PRAYER) { - prayerPoints = dynamicLevels[i]; - } - staticLevels[id] = Integer.parseInt( skill.get("static").toString()); + dynamicLevels[id] = Integer.parseInt(skill.get("dynamic").toString()); + staticLevels[id] = Integer.parseInt(skill.get("static").toString()); experience[id] = Double.parseDouble(skill.get("experience").toString()); + int version = entity instanceof Player ? entity.asPlayer().version : ServerConstants.CURRENT_SAVEFILE_VERSION; + if (i == HITPOINTS) { + if (version < 3 && !skill.containsKey("lifepoints")) { //!1881 + lifepoints = dynamicLevels[id]; + dynamicLevels[id] = staticLevels[id]; + } else { + lifepoints = Integer.parseInt(skill.get("lifepoints").toString()); + } + } + if (i == PRAYER) { + if (version < 3 && !skill.containsKey("prayerPoints")) { //!1881 + prayerPoints = dynamicLevels[id]; + dynamicLevels[id] = staticLevels[id]; + } else { + prayerPoints = Double.parseDouble(skill.get("prayerPoints").toString()); + } + } } } public void correct(double divisor){ + // XP squish for legacy x20 accounts for(int i = 0; i < staticLevels.length; i++){ experience[i] /= divisor; staticLevels[i] = getStaticLevelByExperience(i); @@ -414,40 +404,10 @@ public final class Skills { setLifepoints(staticLevels[i]); } } - experienceMutiplier = 5.0; + experienceMultiplier = 5.0; updateCombatLevel(); } - public void parseExpRate(ByteBuffer buffer) { - experienceMutiplier = buffer.getDouble(); - if(GameWorld.getSettings().getDefault_xp_rate() != experienceMutiplier){ - experienceMutiplier = GameWorld.getSettings().getDefault_xp_rate(); - } - } - - /** - * Saves the skill data on the buffer. - * @param buffer The byte buffer. - */ - public void save(ByteBuffer buffer) { - for (int i = 0; i < 24; i++) { - buffer.putInt((int) (experience[i] * 10)); - if (i == HITPOINTS) { - buffer.put((byte) lifepoints); - } else if (i == PRAYER) { - buffer.put((byte) Math.ceil(prayerPoints)); - } else { - buffer.put((byte) dynamicLevels[i]); - } - buffer.put((byte) staticLevels[i]); - } - buffer.putInt((int) experienceGained); - } - - public void saveExpRate(ByteBuffer buffer) { - buffer.putDouble(experienceMutiplier); - } - /** * Refreshes all the skill levels. */ @@ -866,7 +826,7 @@ public final class Skills { */ public int getMasteredSkills() { int count = 0; - for (int i = 0; i < 23; i++) { + for (int i = 0; i < staticLevels.length; i++) { if (getStaticLevel(i) >= 99) { count++; } diff --git a/Server/src/main/core/game/node/entity/state/PlayerState.kt b/Server/src/main/core/game/node/entity/state/PlayerState.kt deleted file mode 100644 index bfc15b2c4..000000000 --- a/Server/src/main/core/game/node/entity/state/PlayerState.kt +++ /dev/null @@ -1,3 +0,0 @@ -package core.game.node.entity.state - -annotation class PlayerState(val key: String) diff --git a/Server/src/main/core/game/node/entity/state/State.kt b/Server/src/main/core/game/node/entity/state/State.kt deleted file mode 100644 index 20dcd9385..000000000 --- a/Server/src/main/core/game/node/entity/state/State.kt +++ /dev/null @@ -1,42 +0,0 @@ -package core.game.node.entity.state - -import core.game.node.entity.player.Player -import core.game.system.task.Pulse -import org.json.simple.JSONObject -import core.game.world.GameWorld.Pulser - -/** - * A class representing a state that the player or some associated thing can be in. - * @param player The player the state is for - * @author Ceikry - */ -abstract class State(val player: Player? = null) { - var pulse: Pulse? = null - - /** - * Saves any additional data the state might need to the player's save. - */ - abstract fun save(root: JSONObject) - - /** - * Parses any additional saved data the state might have. - */ - abstract fun parse(_data: JSONObject) - - /** - * Returns a new instance of the class constructed for the player. - */ - abstract fun newInstance(player: Player? = null) : State - - /** - * Method used to define the pulse the state uses. - * Called during the init method of the state, which is done during save parsing and done - * manually when first creating a state. - */ - abstract fun createPulse() - fun init() { - createPulse() - pulse ?: return - Pulser.submit(pulse!!) - } -} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/state/StatePulse.java b/Server/src/main/core/game/node/entity/state/StatePulse.java deleted file mode 100644 index c4f006be0..000000000 --- a/Server/src/main/core/game/node/entity/state/StatePulse.java +++ /dev/null @@ -1,89 +0,0 @@ -package core.game.node.entity.state; - -import core.game.node.entity.Entity; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; - -import java.nio.ByteBuffer; - -/** - * Represents a state pulse. - * @author Emperor - */ -public abstract class StatePulse extends Pulse { - - /** - * The entity. - */ - protected final Entity entity; - - /** - * Constructs a new {@code StatePulse} {@code Object}. - * @param entity The entity. - * @param ticks The amount of ticks. - */ - public StatePulse(Entity entity, int ticks) { - super(ticks, entity); - super.stop(); - this.entity = entity; - } - - /** - * Checks if data has to be saved. - * @return {@code True} if so. - */ - public abstract boolean isSaveRequired(); - - /** - * Saves the state data. - * @param buffer The buffer. - */ - public abstract void save(ByteBuffer buffer); - - /** - * Parses the state data. - * @param entity The entity. - * @param buffer The buffer. - * @return The state pulse created. - */ - public abstract StatePulse parse(Entity entity, ByteBuffer buffer); - - /** - * Creates a new instance of this state pulse. - * @param entity The entity. - * @param args The arguments. - * @return The state pulse. - */ - public abstract StatePulse create(Entity entity, Object... args); - - /** - * Checks if this pulse can be ran for the given entity. - * @param entity The entity. - * @return {@code True} if so. - */ - public boolean canRun(Entity entity) { - return true; - } - - /** - * Called when the pulse gets manually removed. - */ - public void remove() { - /* - * empty. - */ - } - - /** - * Runs the pulse. - */ - public void run() { - if (isRunning()) { - return; - } - restart(); - start(); - GameWorld.getPulser().submit(this); - } - -} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/state/StateRepository.kt b/Server/src/main/core/game/node/entity/state/StateRepository.kt deleted file mode 100644 index 8e437e6f4..000000000 --- a/Server/src/main/core/game/node/entity/state/StateRepository.kt +++ /dev/null @@ -1,41 +0,0 @@ -package core.game.node.entity.state - -import core.api.StartupListener -import core.game.node.entity.player.Player -import io.github.classgraph.ClassGraph - -class StateRepository : StartupListener{ - override fun startup() { - loadStateClasses() - } - - companion object { - val states = HashMap() - - fun loadStateClasses() - { - val result = ClassGraph().enableClassInfo().enableAnnotationInfo().acceptPackages("content").scan() - result.getClassesWithAnnotation("core.game.node.entity.state.PlayerState").forEach{ - val key = it.getAnnotationInfo("core.game.node.entity.state.PlayerState").parameterValues[0].value as String - val clazz = it.loadClass().newInstance() - if(clazz is State) { - states.put(key, clazz) - } - } - } - - @JvmStatic - fun forKey(key: String, player: Player): State?{ - val state = states[key] - if(player.hasActiveState(key)){ - return states[key] - } - if(state != null){ - val clazz = state.newInstance(player) - player.states[key] = clazz - return clazz - } - return null - } - } -} diff --git a/Server/src/main/core/game/node/entity/state/impl/FireResistantPulse.java b/Server/src/main/core/game/node/entity/state/impl/FireResistantPulse.java deleted file mode 100644 index b00e4cbbd..000000000 --- a/Server/src/main/core/game/node/entity/state/impl/FireResistantPulse.java +++ /dev/null @@ -1,77 +0,0 @@ -package core.game.node.entity.state.impl; - -import core.game.node.entity.Entity; -import core.game.node.entity.player.Player; -import core.game.node.entity.state.StatePulse; -import core.game.world.GameWorld; - -import java.nio.ByteBuffer; - -/** - * The pulse used for fire resistant. - * @author Vexia - */ -public class FireResistantPulse extends StatePulse { - - /** - * The time to finish. - */ - private static int END_TIME = GameWorld.getSettings().isDevMode() ? 30 : 600; - - /** - * The current tick. - */ - private int currentTick; - - /** - * If the potion is an extended antifire. - */ - private boolean extended; - - /** - * Constructs a new {@Code FireResistantPulse} {@Code Object} - * @param entity the entity. - * @param ticks the ticks. - */ - public FireResistantPulse(Entity entity, int ticks, int currentTick, boolean extended) { - super(entity, ticks); - this.extended = extended; - this.currentTick = currentTick; - } - - @Override - public boolean isSaveRequired() { - return true; - } - - @Override - public void save(ByteBuffer buffer) { - buffer.putInt(currentTick); - } - - @Override - public StatePulse parse(Entity entity, ByteBuffer buffer) { - return new FireResistantPulse(entity, 1, buffer.getInt(), extended); - } - - @Override - public StatePulse create(Entity entity, Object... args) { - return new FireResistantPulse(entity, 1, 0, (boolean) args[0]); - } - - @Override - public boolean pulse() { - if(extended && currentTick == 0 && END_TIME < 1200){ - END_TIME += 600; - } - if (entity instanceof Player) { - if (currentTick == (END_TIME - 25)) { - entity.asPlayer().getPacketDispatch().sendMessage("Your resistance to dragonfire is about to run out."); - } else if (currentTick == (END_TIME - 1)) { - entity.asPlayer().getPacketDispatch().sendMessage("Your resistance to dragonfire has run out."); - } - } - return ++currentTick >= END_TIME; - } - -} \ No newline at end of file diff --git a/Server/src/main/core/game/node/item/GroundItem.java b/Server/src/main/core/game/node/item/GroundItem.java index dfdfe92f1..ba5c4e272 100644 --- a/Server/src/main/core/game/node/item/GroundItem.java +++ b/Server/src/main/core/game/node/item/GroundItem.java @@ -202,9 +202,13 @@ public class GroundItem extends Item { this.removed = removed; } + /** + * Gets the dropper uid. + */ public int getDropperUid() { return dropperUid; } + @Override public String toString() { return "GroundItem [dropper=" + (dropper != null ? dropper.getUsername() : dropper) + ", ticks=" + ticks + ", decayTime=" + decayTime + ", remainPrivate=" + remainPrivate + ", removed=" + removed + "]"; diff --git a/Server/src/main/core/game/node/item/Item.java b/Server/src/main/core/game/node/item/Item.java index f84c7d648..c95077106 100644 --- a/Server/src/main/core/game/node/item/Item.java +++ b/Server/src/main/core/game/node/item/Item.java @@ -135,6 +135,19 @@ public class Item extends Node{ return getId(); } + /** + * Converts noted items into unnoted items. + * + * @return The unnoted version of the item. Returns the original Item if already unnoted. + */ + public Item toUnnotedItem() { + if (definition.isUnnoted()) { + return this; + } else { + return new Item(definition.getNoteId(), getAmount(), getCharge()); + } + } + /** * @return the id */ @@ -196,14 +209,6 @@ public class Item extends Node{ return idHash; } - /** - * Sets the id hash. - * @param hash the hash to set - */ - public void setIdHash(int hash) { - this.idHash = hash; - } - /** * Checks if the item has a wrapper plugin. * @return {@code True} if so. diff --git a/Server/src/main/core/game/requirement/Requirement.kt b/Server/src/main/core/game/requirement/Requirement.kt index 0cbd1c508..d43b68dac 100644 --- a/Server/src/main/core/game/requirement/Requirement.kt +++ b/Server/src/main/core/game/requirement/Requirement.kt @@ -7,6 +7,7 @@ import core.game.node.entity.skill.Skills import kotlin.math.min import java.util.ArrayList +import content.data.Quests interface Requirement { abstract fun evaluate (player: Player) : Pair> @@ -22,7 +23,7 @@ open class SkillReq (val skillId: Int, val level: Int, val soft: Boolean = false open class QuestReq (val questReq: QuestRequirements, val stageRequired: Int = 100) : Requirement { override fun evaluate (player: Player) : Pair> { - val quest = QuestRepository.getQuests()[questReq.questName] + val quest = QuestRepository.getQuests()[questReq.quest] val unmetRequirements = ArrayList() var isMet = true if (quest == null) { @@ -57,143 +58,144 @@ open class QPCumulative (val amount: Int) : Requirement { } } -enum class QuestRequirements (val questName: String, vararg val requirements: Requirement) { - COOK_ASSIST ("Cook's Assistant"), - DEMON_SLAYER ("Demon Slayer"), - DORIC_QUEST ("Doric's Quest"), - DRAGON_SLAYER ("Dragon Slayer", QPReq(32)), - ERNEST ("Ernest the Chicken"), - GOBLIN_DIP ("Goblin Diplomacy"), - IMP_CATCHER ("Imp Catcher"), - KNIGHT_SWORD ("The Knight's Sword", SkillReq(Skills.MINING, 10, true)), - PIRATE_T ("Pirate's Treasure"), - ALI_RESCUE ("Prince Ali Rescue"), - RESTLESS_GHOST ("The Restless Ghost"), - ROMEO ("Romeo & Juliet"), - RUNE_MYST ("Rune Mysteries"), - SHEEP ("Sheep Shearer"), - ARRAV ("Shield of Arrav"), - VAMPIRE ("Vampire Slayer"), - DORIC ("Doric's Quest"), - RUNE_MYSTERIES("Rune Mysteries"), - BLACK_KNIGHT("Black Knights' Fortress", QPReq(12)), - WITCH_POTION ("Witch's Potion"), - DRUIDIC_RITUAL ("Druidic Ritual"), - LOST_CITY ("Lost City", SkillReq(Skills.CRAFTING, 31, true), SkillReq(Skills.WOODCUTTING, 36, true)), - WITCH_HOUSE ("Witch's House"), - MERLIN ("Merlin's Crystal"), - HERO ("Heroes' Quest", QPReq(55), SkillReq(Skills.COOKING, 53, true), SkillReq(Skills.FISHING, 53, true), SkillReq(Skills.HERBLORE, 25, true), SkillReq(Skills.MINING, 50, true), QuestReq(ARRAV), QuestReq(LOST_CITY), QuestReq(MERLIN), QuestReq(DRAGON_SLAYER)), - SCORP_CATCHER ("Scorpion Catcher", SkillReq(Skills.PRAYER, 31)), - FAMILY_CREST ("Family Crest", SkillReq(Skills.MINING, 40, true), SkillReq(Skills.SMITHING, 40, true), SkillReq(Skills.MAGIC, 59, true), SkillReq(Skills.CRAFTING, 40, true)), - FISHING_CONTEST ("Fishing Contest", SkillReq(Skills.FISHING, 10)), - TOTEM ("Tribal Totem", SkillReq(Skills.THIEVING, 21)), - MONK ("Monk's Friend"), - IKOV ("Temple of Ikov", SkillReq(Skills.THIEVING, 42, true), SkillReq(Skills.RANGE, 40)), - CLOCK_TOWER ("Clock Tower"), - GRAIL ("Holy Grail", QuestReq (MERLIN), SkillReq (Skills.ATTACK, 20)), - GNOME_VILLAGE ("Tree Gnome Village"), - FIGHT_ARENA ("Fight Arena"), - HAZEEL ("Hazeel Cult"), - SHEEP_HERDER ("Sheep Herder"), - PLAGUE_CITY ("Plague City"), - SEA_SLUG ("Sea Slug", SkillReq(Skills.FIREMAKING, 30, true)), - WATERFALL ("Waterfall Quest"), - POTION ("Jungle Potion", SkillReq(Skills.HERBLORE, 3, true), QuestReq(DRUIDIC_RITUAL)), - GRAND_TREE ("The Grand Tree", SkillReq(Skills.AGILITY, 25, true)), - BIOHAZARD ("Biohazard", QuestReq(PLAGUE_CITY)), - UNDERGROUND_PASS ("Underground Pass", SkillReq (Skills.RANGE, 25), QuestReq(BIOHAZARD), QuestReq(PLAGUE_CITY)), - OBSERVATORY ("Observatory Quest"), - TOURIST ("The Tourist Trap", SkillReq (Skills.FLETCHING, 10, true), SkillReq(Skills.SMITHING, 20, true)), - WATCHTOWER ("Watchtower", SkillReq (Skills.MAGIC, 14, true), SkillReq(Skills.THIEVING, 15, true), SkillReq (Skills.AGILITY, 25, true), SkillReq (Skills.HERBLORE, 14, true), SkillReq(Skills.MINING, 40, true)), - DWARF_CANNON ("Dwarf Cannon"), - MURDER_MYS ("Murder Mystery"), - DIG_SITE ("Dig Site", SkillReq(Skills.AGILITY, 10, true), SkillReq (Skills.HERBLORE, 10, true), SkillReq (Skills.THIEVING, 25, true)), - GERTRUDE ("Gertrude's Cat"), - SHILO ("Shilo Village", QuestReq(POTION), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.AGILITY, 32, true)), - LEGEND ("Legend's Quest", QPReq(107), SkillReq(Skills.AGILITY, 50, true), SkillReq(Skills.CRAFTING, 50, true), SkillReq(Skills.HERBLORE, 45, true), SkillReq(Skills.MAGIC, 56, true), SkillReq(Skills.MINING, 52, true), SkillReq(Skills.PRAYER, 42, true), SkillReq(Skills.SMITHING, 50, true), SkillReq(Skills.STRENGTH, 50, true), SkillReq(Skills.THIEVING, 50, true), SkillReq(Skills.WOODCUTTING, 50, true), QuestReq(FAMILY_CREST), QuestReq(HERO), QuestReq(SHILO), QuestReq(UNDERGROUND_PASS), QuestReq(WATERFALL)), - DEATH_PLATEAU ("Death Plateau"), - TROLL_STRONGHOLD ("Troll Stronghold", QuestReq(DEATH_PLATEAU), SkillReq(Skills.AGILITY, 15, true)), - EADGAR ("Eadgar's Ruse", QuestReq (DRUIDIC_RITUAL), QuestReq (TROLL_STRONGHOLD), SkillReq(Skills.HERBLORE, 31, true)), - CHOMPY ("Big Chompy Bird Hunting", SkillReq (Skills.FLETCHING, 5, true), SkillReq (Skills.COOKING, 30, true), SkillReq(Skills.RANGE, 30, false)), - ELEMENTAL_W1 ("Elemental Workshop I", SkillReq(Skills.MINING, 20, true), SkillReq(Skills.SMITHING, 20, true), SkillReq(Skills.CRAFTING, 20, true)), - PRIEST ("Priest in Peril"), - NATURE_SPIRIT ("Nature Spirit", QuestReq(PRIEST), QuestReq(RESTLESS_GHOST)), - REGICIDE ("Regicide", QuestReq (UNDERGROUND_PASS), SkillReq (Skills.CRAFTING, 10), SkillReq(Skills.AGILITY, 56, true)), - TAI_BWO ("Tai Bwo Wannai Trio", SkillReq (Skills.AGILITY, 15, true), SkillReq(Skills.COOKING, 30), SkillReq(Skills.FISHING, 65, true), QuestReq(POTION)), - SHADES ("Shades of Mort'ton", QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.HERBLORE, 15, true), SkillReq(Skills.FIREMAKING, 5, true)), - FREM_TRIALS ("Fremennik Trials", SkillReq(Skills.FLETCHING, 25, true), SkillReq(Skills.WOODCUTTING, 40, true), SkillReq(Skills.CRAFTING, 40, true)), - HORROR_DEEP ("Horror from the Deep", SkillReq(Skills.AGILITY, 35, true)), - THRONE ("Throne of Miscellania", QuestReq(HERO), QuestReq(FREM_TRIALS)), - MONKEY ("Monkey Madness", QuestReq(GRAND_TREE), QuestReq(GNOME_VILLAGE)), - MINE ("Haunted Mine", QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 35, true)), - TROLL_ROMANCE ("Troll Romance", QuestReq(TROLL_STRONGHOLD), SkillReq(Skills.AGILITY, 28, true)), - SEARCH_MYREQUE ("In Search of the Myreque", QuestReq(NATURE_SPIRIT), SkillReq(Skills.AGILITY, 25, true)), - FENKENSTRAIN ("Creature of Fenkenstrain", QuestReq(PRIEST), QuestReq(RESTLESS_GHOST), SkillReq(Skills.THIEVING, 25, true), SkillReq(Skills.CRAFTING, 20, true)), - ROVING_ELVES ("Roving Elves", QuestReq(REGICIDE), QuestReq(WATERFALL), SkillReq(Skills.AGILITY, 56, true)), - GHOSTS_AHOY ("Ghosts Ahoy", QuestReq(PRIEST), QuestReq(RESTLESS_GHOST), SkillReq(Skills.AGILITY, 25, true), SkillReq(Skills.COOKING, 20, true)), - FAVOR ("One Small Favor", QuestReq(RUNE_MYSTERIES), QuestReq(SHILO), SkillReq(Skills.AGILITY, 36, true), SkillReq(Skills.CRAFTING, 25, true), SkillReq(Skills.HERBLORE, 18, true), SkillReq(Skills.SMITHING, 30, true)), - MOUNTAIN_DAUGHTER ("Mountain Daughter", SkillReq(Skills.AGILITY, 20, true)), - BETWEEN_ROCK ("Between a Rock...", QuestReq(DWARF_CANNON), QuestReq(FISHING_CONTEST), SkillReq(Skills.DEFENCE, 30, true), SkillReq(Skills.MINING, 40, true), SkillReq(Skills.SMITHING, 50, true)), - FEUD ("The Feud", SkillReq(Skills.THIEVING, 30)), - GOLEM ("The Golem", SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.THIEVING, 25, true)), - DESERT ("Desert Treasure", QuestReq (DIG_SITE), QuestReq (IKOV), QuestReq(TOURIST), QuestReq(TROLL_STRONGHOLD), QuestReq(PRIEST), QuestReq(WATERFALL), SkillReq(Skills.THIEVING, 53), SkillReq(Skills.MAGIC, 50), SkillReq(Skills.FIREMAKING, 50, true), SkillReq(Skills.SLAYER, 10)), - ICTHLARIN ("Icthlarin's Little Helper", QuestReq (GERTRUDE)), - TEARS_OF_GUTHIX ("Tears of Guthix", QPReq(43), SkillReq(Skills.FIREMAKING, 49, true), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.MINING, 20, true)), - LOST_TRIBE ("Lost Tribe", QuestReq(GOBLIN_DIP), QuestReq(RUNE_MYSTERIES), SkillReq(Skills.AGILITY, 13, true), SkillReq(Skills.THIEVING, 13, true), SkillReq(Skills.MINING, 17, true)), - GIANT_DWARF ("The Giant Dwarf", SkillReq(Skills.CRAFTING, 12, true), SkillReq(Skills.FIREMAKING, 16, true), SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.THIEVING, 14, true)), - RECRUITMENT_DRIVE ("Recruitment Drive", QuestReq (BLACK_KNIGHT), QuestReq(DRUIDIC_RITUAL)), - MEP_1 ("Mourning's End Part I", SkillReq(Skills.RANGE, 60), SkillReq(Skills.THIEVING, 50), QuestReq(ROVING_ELVES), QuestReq(CHOMPY), QuestReq(SHEEP_HERDER)), - FORGETTABLE ("Forgettable Tale of a Drunken Dwarf", SkillReq (Skills.COOKING, 22, true), SkillReq(Skills.FARMING, 17, true), QuestReq(GIANT_DWARF), QuestReq(FISHING_CONTEST)), - GARDEN ("Garden of Tranquility", QuestReq(FENKENSTRAIN), SkillReq(Skills.FARMING, 25)), - TWO_CATS ("A Tale of Two Cats", QuestReq(ICTHLARIN)), - WANTED ("Wanted!", QPReq(32), QuestReq(RECRUITMENT_DRIVE), QuestReq(LOST_TRIBE), QuestReq(PRIEST)), - MEP_2 ("Mourning's End Part II", QuestReq(MEP_1)), - ZOGRE ("Zogre Flesh Eaters", QuestReq(CHOMPY), QuestReq(POTION), SkillReq(Skills.SMITHING, 4, true), SkillReq(Skills.HERBLORE, 8, true), SkillReq(Skills.RANGE, 30)), - RUM_DEAL ("Rum Deal", QuestReq(ZOGRE), QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 42, true), SkillReq(Skills.FISHING, 50, true), SkillReq(Skills.FARMING, 40, true), SkillReq(Skills.PRAYER, 47, true), SkillReq(Skills.SLAYER, 42)), - SHADOW ("Shadow of the Storm", SkillReq(Skills.CRAFTING, 30, true), QuestReq(GOLEM), QuestReq(DEMON_SLAYER)), - HISTORY ("Making History", QuestReq(PRIEST), QuestReq(RESTLESS_GHOST)), - RATCATCHERS ("Ratcatchers", QuestReq(ICTHLARIN), QuestReq(GIANT_DWARF)), - SPIRITS_ELID ("Spirits of the Elid", SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.RANGE, 37, true), SkillReq(Skills.MINING, 37, true), SkillReq(Skills.THIEVING, 37, true)), - DEVIOUS ("Devious Minds", SkillReq(Skills.SMITHING, 65, true), SkillReq(Skills.RUNECRAFTING, 50, true), SkillReq(Skills.FLETCHING, 50, true), QuestReq(WANTED), QuestReq(TROLL_STRONGHOLD), QuestReq(DORIC)), - SAND ("The Hand in the Sand", SkillReq(Skills.THIEVING, 17, true), SkillReq(Skills.CRAFTING, 49, true)), - ENAKHRA ("Enakhra's Lament", SkillReq(Skills.CRAFTING, 50, true), SkillReq(Skills.FIREMAKING, 45, true), SkillReq(Skills.PRAYER, 43, true), SkillReq(Skills.MAGIC, 39, true)), - CABIN_FEVER ("Cabin Fever", QuestReq(PIRATE_T), QuestReq(RUM_DEAL), SkillReq(Skills.AGILITY, 42), SkillReq(Skills.CRAFTING, 45), SkillReq(Skills.SMITHING, 50), SkillReq(Skills.RANGE, 40)), - FAIRYTALE_1 ("Fairytale I - Growing Pains", QuestReq(LOST_CITY), QuestReq(NATURE_SPIRIT)), - RFD ("Recipe for Disaster", QPReq(175), QuestReq(COOK_ASSIST), SkillReq(Skills.COOKING, 70, true), SkillReq(Skills.AGILITY, 48, true), SkillReq(Skills.MINING, 50, true), SkillReq(Skills.FISHING, 53, true), SkillReq(Skills.THIEVING, 53, true), SkillReq(Skills.HERBLORE, 25, true), SkillReq(Skills.MAGIC, 59, true), SkillReq(Skills.SMITHING, 40, true), SkillReq(Skills.FIREMAKING, 50, true), SkillReq(Skills.RANGE, 40), SkillReq(Skills.CRAFTING, 40, true), SkillReq(Skills.FLETCHING, 10, true), SkillReq(Skills.WOODCUTTING, 36, true), QuestReq(FISHING_CONTEST), QuestReq(GOBLIN_DIP), QuestReq(CHOMPY), QuestReq(MURDER_MYS), QuestReq(NATURE_SPIRIT), QuestReq(WITCH_HOUSE), QuestReq(GERTRUDE), QuestReq(SHADOW), QuestReq(LEGEND), QuestReq(MONKEY), QuestReq(DESERT), QuestReq(HORROR_DEEP)), - AID_MYREQUE ("In Aid of the Myreque", QuestReq(SEARCH_MYREQUE), SkillReq(Skills.AGILITY, 25, true), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.MINING, 15), SkillReq(Skills.MAGIC, 7, true)), - SOUL_BANE ("A Soul's Bane"), - BONE_MAN_1 ("Rag and Bone Man I"), - SWAN ("Swan Song", QPReq(100), SkillReq(Skills.MAGIC, 66, true), SkillReq(Skills.COOKING, 62, true), SkillReq(Skills.FISHING, 62, true), SkillReq(Skills.SMITHING, 45, true), SkillReq(Skills.FIREMAKING, 42, true), SkillReq(Skills.CRAFTING, 40, true), QuestReq(FAVOR), QuestReq(GARDEN)), - ROYAL_TROUBLE ("Royal Trouble", SkillReq(Skills.AGILITY, 40, true), SkillReq(Skills.SLAYER, 40, true), QuestReq(THRONE)), - DEATH_DORGESHUUN ("Death to the Dorgeshuun", QuestReq(LOST_TRIBE), SkillReq(Skills.AGILITY, 23, true), SkillReq(Skills.THIEVING, 23, true)), - FAIRYTALE_2 ("Fairytale II - Cure a Queen", QuestReq(FAIRYTALE_1), SkillReq(Skills.THIEVING, 40), SkillReq(Skills.FARMING, 49, true), SkillReq(Skills.HERBLORE, 57, true)), - LUNAR_DIPLOMACY ("Lunar Diplomacy", QuestReq(FREM_TRIALS), QuestReq(LOST_CITY), QuestReq(RUNE_MYSTERIES), QuestReq(SHILO), SkillReq(Skills.HERBLORE, 5), SkillReq(Skills.CRAFTING, 61), SkillReq(Skills.DEFENCE, 40), SkillReq(Skills.FIREMAKING, 49), SkillReq(Skills.MAGIC, 65), SkillReq(Skills.MINING, 60), SkillReq(Skills.WOODCUTTING, 55)), - GLOUPHRIE ("The Eyes of Glouphrie", QuestReq(GRAND_TREE), SkillReq(Skills.CONSTRUCTION, 5), SkillReq(Skills.MAGIC, 46)), - HALLOWVALE ("Darkness of Hallowvale", QuestReq(AID_MYREQUE), SkillReq(Skills.CONSTRUCTION, 5, true), SkillReq(Skills.MINING, 20), SkillReq(Skills.THIEVING, 22), SkillReq(Skills.AGILITY, 26, true), SkillReq(Skills.CRAFTING, 32), SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.STRENGTH, 40)), - SLUG_MENACE ("The Slug Menace", QuestReq(WANTED), QuestReq(SEA_SLUG), SkillReq(Skills.CRAFTING, 30), SkillReq(Skills.RUNECRAFTING, 30), SkillReq(Skills.SLAYER, 30), SkillReq(Skills.THIEVING, 30)), - ELEMENTAL_W2 ("Elemental Workshop II", QuestReq(ELEMENTAL_W1), SkillReq(Skills.MAGIC, 20, true), SkillReq(Skills.SMITHING, 30, true)), - ARM_ADVENTURE ("My Arm's Big Adventure", SkillReq(Skills.FARMING, 29, true), SkillReq(Skills.WOODCUTTING, 10), QuestReq(EADGAR), QuestReq(FEUD), QuestReq(POTION)), - ENL_JOURNEY ("Enlightened Journey", QPReq(20), SkillReq(Skills.FIREMAKING, 20, true), SkillReq(Skills.FARMING, 30, true), SkillReq(Skills.CRAFTING, 36, true)), - EAGLE ("Eagles' Peak", SkillReq(Skills.HUNTER, 27, true)), - ANMA ("Animal Magnetism", QuestReq(RESTLESS_GHOST), QuestReq(ERNEST), QuestReq(PRIEST), SkillReq(Skills.SLAYER, 18), SkillReq(Skills.CRAFTING, 19), SkillReq(Skills.RANGE, 30), SkillReq(Skills.WOODCUTTING, 35)), - CONTACT ("Contact!", QuestReq(ALI_RESCUE), QuestReq(ICTHLARIN)), - COLD_WAR ("Cold War", SkillReq(Skills.HUNTER, 10), SkillReq(Skills.AGILITY, 30, true), SkillReq(Skills.CRAFTING, 30), SkillReq(Skills.CONSTRUCTION, 34), SkillReq(Skills.THIEVING, 15)), - FREM_ISLES ("The Fremennik Isles", QuestReq(FREM_TRIALS), SkillReq(Skills.CONSTRUCTION, 20, true)), - BRAIN_ROBBERY ("The Great Brain Robbery", SkillReq(Skills.CRAFTING, 16), SkillReq(Skills.CONSTRUCTION, 30), SkillReq(Skills.PRAYER, 50), QuestReq(FENKENSTRAIN), QuestReq(CABIN_FEVER), QuestReq(RFD)), - WHAT_LIES_BELOW ("What Lies Below", QuestReq(RUNE_MYSTERIES), SkillReq(Skills.RUNECRAFTING, 35)), - OLAF ("Olaf's Quest", QuestReq(FREM_TRIALS), SkillReq(Skills.FIREMAKING, 40, true), SkillReq(Skills.WOODCUTTING, 50, true)), - ANOTHER_SLICE ("Another Slice of H.A.M", SkillReq(Skills.ATTACK, 15), SkillReq(Skills.PRAYER, 25), QuestReq(DEATH_DORGESHUUN), QuestReq(GIANT_DWARF), QuestReq(DIG_SITE)), - DREAM_MENTOR ("Dream Mentor", QuestReq(LUNAR_DIPLOMACY), QuestReq(EADGAR)), - GRIM_TALES ("Grim Tales", QuestReq(WITCH_HOUSE), SkillReq(Skills.FARMING, 45, true), SkillReq(Skills.HERBLORE, 52, true), SkillReq(Skills.THIEVING, 58, true), SkillReq(Skills.AGILITY, 59, true), SkillReq(Skills.WOODCUTTING, 71, true)), - KINGS_RANSOM ("King's Ransom", SkillReq(Skills.MAGIC, 45), SkillReq(Skills.MINING, 45, true), SkillReq(Skills.DEFENCE, 65), QuestReq(BLACK_KNIGHT), QuestReq(GRAIL), QuestReq(MURDER_MYS), QuestReq(FAVOR)), - TOWER_OF_LIFE ("Tower of Life", SkillReq(Skills.CONSTRUCTION, 10)), - BONE_MAN_2 ("Rag and Bone Man II", SkillReq(Skills.SLAYER, 40, true), SkillReq(Skills.DEFENCE, 20), QuestReq(BONE_MAN_1), QuestReq(FREM_TRIALS), QuestReq(FENKENSTRAIN), QuestReq(ZOGRE), QuestReq(WATERFALL)), - LAND_GOBLINS ("Land of the Goblins", QuestReq(ANOTHER_SLICE), QuestReq(FISHING_CONTEST), SkillReq(Skills.AGILITY, 38), SkillReq(Skills.FISHING, 40), SkillReq(Skills.THIEVING, 45), SkillReq(Skills.HERBLORE, 48)), - PATH_GLOUPHRIE ("The Path of Glouphrie", QuestReq(GLOUPHRIE), QuestReq(GNOME_VILLAGE), QuestReq(WATERFALL), SkillReq(Skills.AGILITY, 45), SkillReq(Skills.RANGE, 47), SkillReq(Skills.SLAYER, 56), SkillReq(Skills.STRENGTH, 60), SkillReq(Skills.THIEVING, 56)), - DEFENDER_VARROCK ("Defender of Varrock", QuestReq(ARRAV), QuestReq(KNIGHT_SWORD), QuestReq(DEMON_SLAYER), QuestReq(IKOV), QuestReq(FAMILY_CREST), QuestReq(WHAT_LIES_BELOW), QuestReq(GARDEN), SkillReq(Skills.AGILITY, 51), SkillReq(Skills.HUNTER, 51), SkillReq(Skills.MINING, 59), SkillReq(Skills.SMITHING, 54)), - SPIRIT_OF_SUMMER ("Spirit of Summer", QuestReq(RESTLESS_GHOST), SkillReq(Skills.CONSTRUCTION, 40), SkillReq(Skills.FARMING, 26), SkillReq(Skills.PRAYER, 35), SkillReq(Skills.SUMMONING, 19)), - SUMMERS_END ("Summer's End", QuestReq(SPIRIT_OF_SUMMER), SkillReq(Skills.FIREMAKING, 47), SkillReq(Skills.HUNTER, 35), SkillReq(Skills.MINING, 45), SkillReq(Skills.PRAYER, 55), SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.WOODCUTTING, 37)), - SEERGAZE ("Legacy of Seergaze", QuestReq(HALLOWVALE), SkillReq(Skills.AGILITY, 29), SkillReq(Skills.CONSTRUCTION, 20), SkillReq(Skills.CRAFTING, 47), SkillReq(Skills.FIREMAKING, 40), SkillReq(Skills.MAGIC, 49), SkillReq(Skills.MINING, 35), SkillReq(Skills.SLAYER, 31)), - SMOKING_KILLS ("Smoking Kills", QuestReq(RESTLESS_GHOST), QuestReq(ICTHLARIN), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.SLAYER, 35)), - WHILE_GUTHIX_SLEEPS ("While Guthix Sleeps", SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.HUNTER, 55), SkillReq(Skills.THIEVING, 60), SkillReq(Skills.DEFENCE, 65), SkillReq(Skills.FARMING, 65), SkillReq(Skills.HERBLORE, 65), SkillReq(Skills.MAGIC, 75), QuestReq(DEFENDER_VARROCK), QuestReq(DREAM_MENTOR), QuestReq(SAND), QuestReq(KINGS_RANSOM), QuestReq(LEGEND), QuestReq(MEP_2), QuestReq(PATH_GLOUPHRIE), QuestReq(RFD), QuestReq(SUMMERS_END), QuestReq(SWAN), QuestReq(TEARS_OF_GUTHIX), QuestReq(ZOGRE)) +enum class QuestRequirements(val quest: Quests, vararg val requirements: Requirement) { + COOK_ASSIST (Quests.COOKS_ASSISTANT), + DEMON_SLAYER (Quests.DEMON_SLAYER), + DORIC_QUEST (Quests.DORICS_QUEST), + DRAGON_SLAYER (Quests.DRAGON_SLAYER, QPReq(32)), + ERNEST (Quests.ERNEST_THE_CHICKEN), + GOBLIN_DIP (Quests.GOBLIN_DIPLOMACY), + IMP_CATCHER (Quests.IMP_CATCHER), + KNIGHT_SWORD (Quests.THE_KNIGHTS_SWORD, SkillReq(Skills.MINING, 10, true)), + PIRATE_T (Quests.PIRATES_TREASURE), + ALI_RESCUE (Quests.PRINCE_ALI_RESCUE), + RESTLESS_GHOST (Quests.THE_RESTLESS_GHOST), + ROMEO (Quests.ROMEO_JULIET), + RUNE_MYST (Quests.RUNE_MYSTERIES), + SHEEP (Quests.SHEEP_SHEARER), + ARRAV (Quests.SHIELD_OF_ARRAV), + VAMPIRE (Quests.VAMPIRE_SLAYER), + DORIC (Quests.DORICS_QUEST), + RUNE_MYSTERIES(Quests.RUNE_MYSTERIES), + BLACK_KNIGHT(Quests.BLACK_KNIGHTS_FORTRESS, QPReq(12)), + WITCH_POTION (Quests.WITCHS_POTION), + DRUIDIC_RITUAL (Quests.DRUIDIC_RITUAL), + LOST_CITY (Quests.LOST_CITY, SkillReq(Skills.CRAFTING, 31, true), SkillReq(Skills.WOODCUTTING, 36, true)), + WITCH_HOUSE (Quests.WITCHS_HOUSE), + MERLIN (Quests.MERLINS_CRYSTAL), + HERO (Quests.HEROES_QUEST, QPReq(55), SkillReq(Skills.COOKING, 53, true), SkillReq(Skills.FISHING, 53, true), SkillReq(Skills.HERBLORE, 25, true), SkillReq(Skills.MINING, 50, true), QuestReq(ARRAV), QuestReq(LOST_CITY), QuestReq(MERLIN), QuestReq(DRAGON_SLAYER)), + SCORP_CATCHER (Quests.SCORPION_CATCHER, SkillReq(Skills.PRAYER, 31)), + FAMILY_CREST (Quests.FAMILY_CREST, SkillReq(Skills.MINING, 40, true), SkillReq(Skills.SMITHING, 40, true), SkillReq(Skills.MAGIC, 59, true), SkillReq(Skills.CRAFTING, 40, true)), + FISHING_CONTEST (Quests.FISHING_CONTEST, SkillReq(Skills.FISHING, 10)), + TOTEM (Quests.TRIBAL_TOTEM, SkillReq(Skills.THIEVING, 21)), + MONK (Quests.MONKS_FRIEND), + IKOV (Quests.TEMPLE_OF_IKOV, SkillReq(Skills.THIEVING, 42, true), SkillReq(Skills.RANGE, 40)), + CLOCK_TOWER (Quests.CLOCK_TOWER), + GRAIL (Quests.HOLY_GRAIL, QuestReq (MERLIN), SkillReq (Skills.ATTACK, 20)), + GNOME_VILLAGE (Quests.TREE_GNOME_VILLAGE), + FIGHT_ARENA (Quests.FIGHT_ARENA), + HAZEEL (Quests.HAZEEL_CULT), + SHEEP_HERDER (Quests.SHEEP_HERDER), + PLAGUE_CITY (Quests.PLAGUE_CITY), + SEA_SLUG (Quests.SEA_SLUG, SkillReq(Skills.FIREMAKING, 30, true)), + WATERFALL (Quests.WATERFALL_QUEST), + POTION (Quests.JUNGLE_POTION, SkillReq(Skills.HERBLORE, 3, true), QuestReq(DRUIDIC_RITUAL)), + GRAND_TREE (Quests.THE_GRAND_TREE, SkillReq(Skills.AGILITY, 25, true)), + BIOHAZARD (Quests.BIOHAZARD, QuestReq(PLAGUE_CITY)), + UNDERGROUND_PASS (Quests.UNDERGROUND_PASS, SkillReq (Skills.RANGE, 25), QuestReq(BIOHAZARD), QuestReq(PLAGUE_CITY)), + OBSERVATORY (Quests.OBSERVATORY_QUEST), + TOURIST (Quests.THE_TOURIST_TRAP, SkillReq (Skills.FLETCHING, 10, true), SkillReq(Skills.SMITHING, 20, true)), + WATCHTOWER (Quests.WATCHTOWER, SkillReq (Skills.MAGIC, 14, true), SkillReq(Skills.THIEVING, 15, true), SkillReq (Skills.AGILITY, 25, true), SkillReq (Skills.HERBLORE, 14, true), SkillReq(Skills.MINING, 40, true)), + DWARF_CANNON (Quests.DWARF_CANNON), + MURDER_MYS (Quests.MURDER_MYSTERY), + DIG_SITE (Quests.THE_DIG_SITE, SkillReq(Skills.AGILITY, 10, true), SkillReq (Skills.HERBLORE, 10, true), SkillReq (Skills.THIEVING, 25, true)), + GERTRUDE (Quests.GERTRUDES_CAT), + SHILO (Quests.SHILO_VILLAGE, QuestReq(POTION), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.AGILITY, 32, true)), + LEGEND (Quests.LEGENDS_QUEST, QPReq(107), SkillReq(Skills.AGILITY, 50, true), SkillReq(Skills.CRAFTING, 50, true), SkillReq(Skills.HERBLORE, 45, true), SkillReq(Skills.MAGIC, 56, true), SkillReq(Skills.MINING, 52, true), SkillReq(Skills.PRAYER, 42, true), SkillReq(Skills.SMITHING, 50, true), SkillReq(Skills.STRENGTH, 50, true), SkillReq(Skills.THIEVING, 50, true), SkillReq(Skills.WOODCUTTING, 50, true), QuestReq(FAMILY_CREST), QuestReq(HERO), QuestReq(SHILO), QuestReq(UNDERGROUND_PASS), QuestReq(WATERFALL)), + DEATH_PLATEAU (Quests.DEATH_PLATEAU), + TROLL_STRONGHOLD (Quests.TROLL_STRONGHOLD, QuestReq(DEATH_PLATEAU), SkillReq(Skills.AGILITY, 15, true)), + EADGAR (Quests.EADGARS_RUSE, QuestReq (DRUIDIC_RITUAL), QuestReq (TROLL_STRONGHOLD), SkillReq(Skills.HERBLORE, 31, true)), + CHOMPY (Quests.BIG_CHOMPY_BIRD_HUNTING, SkillReq (Skills.FLETCHING, 5, true), SkillReq (Skills.COOKING, 30, true), SkillReq(Skills.RANGE, 30, false)), + ELEMENTAL_W1 (Quests.ELEMENTAL_WORKSHOP_I, SkillReq(Skills.MINING, 20, true), SkillReq(Skills.SMITHING, 20, true), SkillReq(Skills.CRAFTING, 20, true)), + PRIEST (Quests.PRIEST_IN_PERIL), + NATURE_SPIRIT (Quests.NATURE_SPIRIT, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST)), + REGICIDE (Quests.REGICIDE, QuestReq (UNDERGROUND_PASS), SkillReq (Skills.CRAFTING, 10), SkillReq(Skills.AGILITY, 56, true)), + TAI_BWO (Quests.TAI_BWO_WANNAI_TRIO, SkillReq (Skills.AGILITY, 15, true), SkillReq(Skills.COOKING, 30), SkillReq(Skills.FISHING, 65, true), QuestReq(POTION)), + SHADES (Quests.SHADES_OF_MORTTON, QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.HERBLORE, 15, true), SkillReq(Skills.FIREMAKING, 5, true)), + FREM_TRIALS (Quests.THE_FREMENNIK_TRIALS, SkillReq(Skills.FLETCHING, 25, true), SkillReq(Skills.WOODCUTTING, 40, true), SkillReq(Skills.CRAFTING, 40, true)), + HORROR_DEEP (Quests.HORROR_FROM_THE_DEEP, SkillReq(Skills.AGILITY, 35, true)), + THRONE (Quests.THRONE_OF_MISCELLANIA, QuestReq(HERO), QuestReq(FREM_TRIALS)), + MONKEY (Quests.MONKEY_MADNESS, QuestReq(GRAND_TREE), QuestReq(GNOME_VILLAGE)), + MINE (Quests.HAUNTED_MINE, QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 35, true)), + TROLL_ROMANCE (Quests.TROLL_ROMANCE, QuestReq(TROLL_STRONGHOLD), SkillReq(Skills.AGILITY, 28, true)), + SEARCH_MYREQUE (Quests.IN_SEARCH_OF_THE_MYREQUE, QuestReq(NATURE_SPIRIT), SkillReq(Skills.AGILITY, 25, true)), + FENKENSTRAIN (Quests.CREATURE_OF_FENKENSTRAIN, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST), SkillReq(Skills.THIEVING, 25, true), SkillReq(Skills.CRAFTING, 20, true)), + ROVING_ELVES (Quests.ROVING_ELVES, QuestReq(REGICIDE), QuestReq(WATERFALL), SkillReq(Skills.AGILITY, 56, true)), + GHOSTS_AHOY (Quests.GHOSTS_AHOY, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST), SkillReq(Skills.AGILITY, 25, true), SkillReq(Skills.COOKING, 20, true)), + FAVOR (Quests.ONE_SMALL_FAVOUR, QuestReq(RUNE_MYSTERIES), QuestReq(SHILO), SkillReq(Skills.AGILITY, 36, true), SkillReq(Skills.CRAFTING, 25, true), SkillReq(Skills.HERBLORE, 18, true), SkillReq(Skills.SMITHING, 30, true)), + MOUNTAIN_DAUGHTER (Quests.MOUNTAIN_DAUGHTER, SkillReq(Skills.AGILITY, 20, true)), + BETWEEN_ROCK (Quests.BETWEEN_A_ROCK, QuestReq(DWARF_CANNON), QuestReq(FISHING_CONTEST), SkillReq(Skills.DEFENCE, 30, true), SkillReq(Skills.MINING, 40, true), SkillReq(Skills.SMITHING, 50, true)), + FEUD (Quests.THE_FEUD, SkillReq(Skills.THIEVING, 30)), + GOLEM (Quests.THE_GOLEM, SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.THIEVING, 25, true)), + DESERT (Quests.DESERT_TREASURE, QuestReq (DIG_SITE), QuestReq (IKOV), QuestReq(TOURIST), QuestReq(TROLL_STRONGHOLD), QuestReq(PRIEST), QuestReq(WATERFALL), SkillReq(Skills.THIEVING, 53), SkillReq(Skills.MAGIC, 50), SkillReq(Skills.FIREMAKING, 50, true), SkillReq(Skills.SLAYER, 10)), + ICTHLARIN (Quests.ICTHLARINS_LITTLE_HELPER, QuestReq (GERTRUDE)), + TEARS_OF_GUTHIX (Quests.TEARS_OF_GUTHIX, QPReq(43), SkillReq(Skills.FIREMAKING, 49, true), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.MINING, 20, true)), + LOST_TRIBE (Quests.THE_LOST_TRIBE, QuestReq(GOBLIN_DIP), QuestReq(RUNE_MYSTERIES), SkillReq(Skills.AGILITY, 13, true), SkillReq(Skills.THIEVING, 13, true), SkillReq(Skills.MINING, 17, true)), + GIANT_DWARF (Quests.THE_GIANT_DWARF, SkillReq(Skills.CRAFTING, 12, true), SkillReq(Skills.FIREMAKING, 16, true), SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.THIEVING, 14, true)), + RECRUITMENT_DRIVE (Quests.RECRUITMENT_DRIVE, QuestReq (BLACK_KNIGHT), QuestReq(DRUIDIC_RITUAL)), + MEP_1 (Quests.MOURNINGS_END_PART_I, SkillReq(Skills.RANGE, 60), SkillReq(Skills.THIEVING, 50), QuestReq(ROVING_ELVES), QuestReq(CHOMPY), QuestReq(SHEEP_HERDER)), + FORGETTABLE (Quests.FORGETTABLE_TALE, SkillReq (Skills.COOKING, 22, true), SkillReq(Skills.FARMING, 17, true), QuestReq(GIANT_DWARF), QuestReq(FISHING_CONTEST)), + GARDEN (Quests.GARDEN_OF_TRANQUILITY, QuestReq(FENKENSTRAIN), SkillReq(Skills.FARMING, 25)), + TWO_CATS (Quests.A_TAIL_OF_TWO_CATS, QuestReq(ICTHLARIN)), + WANTED (Quests.WANTED, QPReq(32), QuestReq(RECRUITMENT_DRIVE), QuestReq(LOST_TRIBE), QuestReq(PRIEST)), + MEP_2 (Quests.MOURNINGS_END_PART_II, QuestReq(MEP_1)), + ZOGRE (Quests.ZOGRE_FLESH_EATERS, QuestReq(CHOMPY), QuestReq(POTION), SkillReq(Skills.SMITHING, 4, true), SkillReq(Skills.HERBLORE, 8, true), SkillReq(Skills.RANGE, 30)), + RUM_DEAL (Quests.RUM_DEAL, QuestReq(ZOGRE), QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 42, true), SkillReq(Skills.FISHING, 50, true), SkillReq(Skills.FARMING, 40, true), SkillReq(Skills.PRAYER, 47, true), SkillReq(Skills.SLAYER, 42)), + SHADOW (Quests.SHADOW_OF_THE_STORM, SkillReq(Skills.CRAFTING, 30, true), QuestReq(GOLEM), QuestReq(DEMON_SLAYER)), + HISTORY (Quests.MAKING_HISTORY, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST)), + RATCATCHERS (Quests.RATCATCHERS, QuestReq(ICTHLARIN), QuestReq(GIANT_DWARF)), + SPIRITS_ELID (Quests.SPIRITS_OF_THE_ELID, SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.RANGE, 37, true), SkillReq(Skills.MINING, 37, true), SkillReq(Skills.THIEVING, 37, true)), + DEVIOUS (Quests.DEVIOUS_MINDS, SkillReq(Skills.SMITHING, 65, true), SkillReq(Skills.RUNECRAFTING, 50, true), SkillReq(Skills.FLETCHING, 50, true), QuestReq(WANTED), QuestReq(TROLL_STRONGHOLD), QuestReq(DORIC)), + SAND (Quests.THE_HAND_IN_THE_SAND, SkillReq(Skills.THIEVING, 17, true), SkillReq(Skills.CRAFTING, 49, true)), + ENAKHRA (Quests.ENAKHRAS_LAMENT, SkillReq(Skills.CRAFTING, 50, true), SkillReq(Skills.FIREMAKING, 45, true), SkillReq(Skills.PRAYER, 43, true), SkillReq(Skills.MAGIC, 39, true)), + CABIN_FEVER (Quests.CABIN_FEVER, QuestReq(PIRATE_T), QuestReq(RUM_DEAL), SkillReq(Skills.AGILITY, 42), SkillReq(Skills.CRAFTING, 45), SkillReq(Skills.SMITHING, 50), SkillReq(Skills.RANGE, 40)), + FAIRYTALE_1 (Quests.FAIRYTALE_I_GROWING_PAINS, QuestReq(LOST_CITY), QuestReq(NATURE_SPIRIT)), + RFD (Quests.RECIPE_FOR_DISASTER, QPReq(175), QuestReq(COOK_ASSIST), SkillReq(Skills.COOKING, 70, true), SkillReq(Skills.AGILITY, 48, true), SkillReq(Skills.MINING, 50, true), SkillReq(Skills.FISHING, 53, true), SkillReq(Skills.THIEVING, 53, true), SkillReq(Skills.HERBLORE, 25, true), SkillReq(Skills.MAGIC, 59, true), SkillReq(Skills.SMITHING, 40, true), SkillReq(Skills.FIREMAKING, 50, true), SkillReq(Skills.RANGE, 40), SkillReq(Skills.CRAFTING, 40, true), SkillReq(Skills.FLETCHING, 10, true), SkillReq(Skills.WOODCUTTING, 36, true), QuestReq(FISHING_CONTEST), QuestReq(GOBLIN_DIP), QuestReq(CHOMPY), QuestReq(MURDER_MYS), QuestReq(NATURE_SPIRIT), QuestReq(WITCH_HOUSE), QuestReq(GERTRUDE), QuestReq(SHADOW), QuestReq(LEGEND), QuestReq(MONKEY), QuestReq(DESERT), QuestReq(HORROR_DEEP)), + AID_MYREQUE (Quests.IN_AID_OF_THE_MYREQUE, QuestReq(SEARCH_MYREQUE), SkillReq(Skills.AGILITY, 25, true), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.MINING, 15), SkillReq(Skills.MAGIC, 7, true)), + SOUL_BANE (Quests.A_SOULS_BANE), + BONE_MAN_1 (Quests.RAG_AND_BONE_MAN), + SWAN (Quests.SWAN_SONG, QPReq(100), SkillReq(Skills.MAGIC, 66, true), SkillReq(Skills.COOKING, 62, true), SkillReq(Skills.FISHING, 62, true), SkillReq(Skills.SMITHING, 45, true), SkillReq(Skills.FIREMAKING, 42, true), SkillReq(Skills.CRAFTING, 40, true), QuestReq(FAVOR), QuestReq(GARDEN)), + ROYAL_TROUBLE (Quests.ROYAL_TROUBLE, SkillReq(Skills.AGILITY, 40, true), SkillReq(Skills.SLAYER, 40, true), QuestReq(THRONE)), + DEATH_DORGESHUUN (Quests.DEATH_TO_THE_DORGESHUUN, QuestReq(LOST_TRIBE), SkillReq(Skills.AGILITY, 23, true), SkillReq(Skills.THIEVING, 23, true)), + FAIRYTALE_2 (Quests.FAIRYTALE_II_CURE_A_QUEEN, QuestReq(FAIRYTALE_1), SkillReq(Skills.THIEVING, 40), SkillReq(Skills.FARMING, 49, true), SkillReq(Skills.HERBLORE, 57, true)), + LUNAR_DIPLOMACY (Quests.LUNAR_DIPLOMACY, QuestReq(FREM_TRIALS), QuestReq(LOST_CITY), QuestReq(RUNE_MYSTERIES), QuestReq(SHILO), SkillReq(Skills.HERBLORE, 5), SkillReq(Skills.CRAFTING, 61), SkillReq(Skills.DEFENCE, 40), SkillReq(Skills.FIREMAKING, 49), SkillReq(Skills.MAGIC, 65), SkillReq(Skills.MINING, 60), SkillReq(Skills.WOODCUTTING, 55)), + GLOUPHRIE (Quests.THE_EYES_OF_GLOUPHRIE, QuestReq(GRAND_TREE), SkillReq(Skills.CONSTRUCTION, 5), SkillReq(Skills.MAGIC, 46)), + HALLOWVALE (Quests.DARKNESS_OF_HALLOWVALE, QuestReq(AID_MYREQUE), SkillReq(Skills.CONSTRUCTION, 5, true), SkillReq(Skills.MINING, 20), SkillReq(Skills.THIEVING, 22), SkillReq(Skills.AGILITY, 26, true), SkillReq(Skills.CRAFTING, 32), SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.STRENGTH, 40)), + SLUG_MENACE (Quests.THE_SLUG_MENACE, QuestReq(WANTED), QuestReq(SEA_SLUG), SkillReq(Skills.CRAFTING, 30), SkillReq(Skills.RUNECRAFTING, 30), SkillReq(Skills.SLAYER, 30), SkillReq(Skills.THIEVING, 30)), + ELEMENTAL_W2 (Quests.ELEMENTAL_WORKSHOP_II, QuestReq(ELEMENTAL_W1), SkillReq(Skills.MAGIC, 20, true), SkillReq(Skills.SMITHING, 30, true)), + ARM_ADVENTURE (Quests.MY_ARMS_BIG_ADVENTURE, SkillReq(Skills.FARMING, 29, true), SkillReq(Skills.WOODCUTTING, 10), QuestReq(EADGAR), QuestReq(FEUD), QuestReq(POTION)), + ENL_JOURNEY (Quests.ENLIGHTENED_JOURNEY, QPReq(20), SkillReq(Skills.FIREMAKING, 20, true), SkillReq(Skills.FARMING, 30, true), SkillReq(Skills.CRAFTING, 36, true)), + EAGLE (Quests.EAGLES_PEAK, SkillReq(Skills.HUNTER, 27, true)), + ANMA (Quests.ANIMAL_MAGNETISM, QuestReq(RESTLESS_GHOST), QuestReq(ERNEST), QuestReq(PRIEST), SkillReq(Skills.SLAYER, 18), SkillReq(Skills.CRAFTING, 19), SkillReq(Skills.RANGE, 30), SkillReq(Skills.WOODCUTTING, 35)), + CONTACT (Quests.CONTACT, QuestReq(ALI_RESCUE), QuestReq(ICTHLARIN)), + COLD_WAR (Quests.COLD_WAR, SkillReq(Skills.HUNTER, 10), SkillReq(Skills.AGILITY, 30, true), SkillReq(Skills.CRAFTING, 30), SkillReq(Skills.CONSTRUCTION, 34), SkillReq(Skills.THIEVING, 15)), + FREM_ISLES (Quests.THE_FREMENNIK_ISLES, QuestReq(FREM_TRIALS), SkillReq(Skills.CONSTRUCTION, 20, true)), + BRAIN_ROBBERY (Quests.THE_GREAT_BRAIN_ROBBERY, SkillReq(Skills.CRAFTING, 16), SkillReq(Skills.CONSTRUCTION, 30), SkillReq(Skills.PRAYER, 50), QuestReq(FENKENSTRAIN), QuestReq(CABIN_FEVER), QuestReq(RFD)), + WHAT_LIES_BELOW (Quests.WHAT_LIES_BELOW, QuestReq(RUNE_MYSTERIES), SkillReq(Skills.RUNECRAFTING, 35)), + OLAF (Quests.OLAFS_QUEST, QuestReq(FREM_TRIALS), SkillReq(Skills.FIREMAKING, 40, true), SkillReq(Skills.WOODCUTTING, 50, true)), + ANOTHER_SLICE (Quests.ANOTHER_SLICE_OF_HAM, SkillReq(Skills.ATTACK, 15), SkillReq(Skills.PRAYER, 25), QuestReq(DEATH_DORGESHUUN), QuestReq(GIANT_DWARF), QuestReq(DIG_SITE)), + DREAM_MENTOR (Quests.DREAM_MENTOR, QuestReq(LUNAR_DIPLOMACY), QuestReq(EADGAR)), + GRIM_TALES (Quests.GRIM_TALES, QuestReq(WITCH_HOUSE), SkillReq(Skills.FARMING, 45, true), SkillReq(Skills.HERBLORE, 52, true), SkillReq(Skills.THIEVING, 58, true), SkillReq(Skills.AGILITY, 59, true), SkillReq(Skills.WOODCUTTING, 71, true)), + KINGS_RANSOM (Quests.KINGS_RANSOM, SkillReq(Skills.MAGIC, 45), SkillReq(Skills.MINING, 45, true), SkillReq(Skills.DEFENCE, 65), QuestReq(BLACK_KNIGHT), QuestReq(GRAIL), QuestReq(MURDER_MYS), QuestReq(FAVOR)), + TOWER_OF_LIFE (Quests.TOWER_OF_LIFE, SkillReq(Skills.CONSTRUCTION, 10)), + BONE_MAN_2 (Quests.RAG_AND_BONE_MAN, SkillReq(Skills.SLAYER, 40, true), SkillReq(Skills.DEFENCE, 20), QuestReq(BONE_MAN_1), QuestReq(FREM_TRIALS), QuestReq(FENKENSTRAIN), QuestReq(ZOGRE), QuestReq(WATERFALL)), + LAND_GOBLINS (Quests.LAND_OF_THE_GOBLINS, QuestReq(ANOTHER_SLICE), QuestReq(FISHING_CONTEST), SkillReq(Skills.AGILITY, 38), SkillReq(Skills.FISHING, 40), SkillReq(Skills.THIEVING, 45), SkillReq(Skills.HERBLORE, 48)), + PATH_GLOUPHRIE (Quests.THE_PATH_OF_GLOUPHRIE, QuestReq(GLOUPHRIE), QuestReq(GNOME_VILLAGE), QuestReq(WATERFALL), SkillReq(Skills.AGILITY, 45), SkillReq(Skills.RANGE, 47), SkillReq(Skills.SLAYER, 56), SkillReq(Skills.STRENGTH, 60), SkillReq(Skills.THIEVING, 56)), + DEFENDER_VARROCK (Quests.DEFENDER_OF_VARROCK, QuestReq(ARRAV), QuestReq(KNIGHT_SWORD), QuestReq(DEMON_SLAYER), QuestReq(IKOV), QuestReq(FAMILY_CREST), QuestReq(WHAT_LIES_BELOW), QuestReq(GARDEN), SkillReq(Skills.AGILITY, 51), SkillReq(Skills.HUNTER, 51), SkillReq(Skills.MINING, 59), SkillReq(Skills.SMITHING, 54)), + SPIRIT_OF_SUMMER (Quests.SPIRIT_OF_SUMMER, QuestReq(RESTLESS_GHOST), SkillReq(Skills.CONSTRUCTION, 40), SkillReq(Skills.FARMING, 26), SkillReq(Skills.PRAYER, 35), SkillReq(Skills.SUMMONING, 19)), + SUMMERS_END (Quests.SUMMERS_END, QuestReq(SPIRIT_OF_SUMMER), SkillReq(Skills.FIREMAKING, 47), SkillReq(Skills.HUNTER, 35), SkillReq(Skills.MINING, 45), SkillReq(Skills.PRAYER, 55), SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.WOODCUTTING, 37)), + SEERGAZE (Quests.LEGACY_OF_SEERGAZE, QuestReq(HALLOWVALE), SkillReq(Skills.AGILITY, 29), SkillReq(Skills.CONSTRUCTION, 20), SkillReq(Skills.CRAFTING, 47), SkillReq(Skills.FIREMAKING, 40), SkillReq(Skills.MAGIC, 49), SkillReq(Skills.MINING, 35), SkillReq(Skills.SLAYER, 31)), + SMOKING_KILLS (Quests.SMOKING_KILLS, QuestReq(RESTLESS_GHOST), QuestReq(ICTHLARIN), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.SLAYER, 35)), + WHILE_GUTHIX_SLEEPS (Quests.WHILE_GUTHIX_SLEEPS, SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.HUNTER, 55), SkillReq(Skills.THIEVING, 60), SkillReq(Skills.DEFENCE, 65), SkillReq(Skills.FARMING, 65), SkillReq(Skills.HERBLORE, 65), SkillReq(Skills.MAGIC, 75), QuestReq(DEFENDER_VARROCK), QuestReq(DREAM_MENTOR), QuestReq(SAND), QuestReq(KINGS_RANSOM), QuestReq(LEGEND), QuestReq(MEP_2), QuestReq(PATH_GLOUPHRIE), QuestReq(RFD), QuestReq(SUMMERS_END), QuestReq(SWAN), QuestReq(TEARS_OF_GUTHIX), QuestReq(ZOGRE)), + ALL_FIRED_UP (Quests.ALL_FIRED_UP, QuestReq(PRIEST), SkillReq(Skills.FIREMAKING, 43)) } diff --git a/Server/src/main/core/game/shops/Shop.kt b/Server/src/main/core/game/shops/Shop.kt index d19a4c2ec..9d8425993 100644 --- a/Server/src/main/core/game/shops/Shop.kt +++ b/Server/src/main/core/game/shops/Shop.kt @@ -62,17 +62,18 @@ class Shop(val title: String, val stock: Array, val general: Boolean = fun showTab(player: Player, main: Boolean) { - val cont = if (main) getAttribute(player, "shop-cont", null) ?: return else playerStock + val mainCont = getAttribute(player, "shop-cont", null) ?: return + val cont = if (main) mainCont else playerStock if(!main) { - cont.listeners.remove(listenerInstances[player.details.uid]) + mainCont.listeners.remove(listenerInstances[player.details.uid]) playerStock.listeners.add(listenerInstances[player.details.uid]) } else { playerStock.listeners.remove(listenerInstances[player.details.uid]) - cont.listeners.add(listenerInstances[player.details.uid]) + mainCont.listeners.add(listenerInstances[player.details.uid]) } val settings = IfaceSettingsBuilder() @@ -167,7 +168,12 @@ class Shop(val title: String, val stock: Array, val general: Boolean = Items.TOKKUL_6529 -> item.definition.getConfiguration(ItemConfigParser.TOKKUL_PRICE, 1) Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, 1) Items.CASTLE_WARS_TICKET_4067 -> item.definition.getConfiguration(ItemConfigParser.CASTLE_WARS_TICKET_PRICE, 1) - else -> getGPCost(Item(item.id, 1), if (isMainStock) stock[item.slot].amount else playerStock[slot].amount, if (isMainStock) item.amount else playerStock[slot].amount) + else -> { + val fixedPrice = fixedPriceItems[item.id] + fixedPrice ?: getGPCost(Item(item.id, 1), + if (isMainStock) stock[item.slot].amount else playerStock[slot].amount, + if (isMainStock) item.amount else playerStock[slot].amount) + } } return Item(currency, price) @@ -210,13 +216,16 @@ class Shop(val title: String, val stock: Array, val general: Boolean = } } - val price = when(currency) - { - Items.TOKKUL_6529 -> (item.definition.getConfiguration(ItemConfigParser.TOKKUL_PRICE, 1) / 10.0).toInt() // selling items authentically return 10x less tokkul (floored/truncated) than the item's shop price - Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, 1) - Items.CASTLE_WARS_TICKET_4067 -> item.definition.getConfiguration(ItemConfigParser.CASTLE_WARS_TICKET_PRICE, 1) - else -> getGPSell(Item(shopItemId, 1), stockAmt, currentAmt) - } + val price = when (currency) { + // selling items authentically return 10x less tokkul (floored/truncated) than the item's shop price + Items.TOKKUL_6529 -> (item.definition.getConfiguration(ItemConfigParser.TOKKUL_PRICE, 1) / 10.0).toInt() + Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, 1) + Items.CASTLE_WARS_TICKET_4067 -> item.definition.getConfiguration(ItemConfigParser.CASTLE_WARS_TICKET_PRICE, 1) + else -> { + val fixedPrice = fixedPriceItems[shopItemId] + fixedPrice ?: getGPSell(Item(shopItemId, 1), stockAmt, currentAmt) + } + } if(!general && stockAmt == 0 && shopSlot == -1) { @@ -293,10 +302,17 @@ class Shop(val title: String, val stock: Array, val general: Boolean = if(cost.id == -1) sendMessage(player, "This shop cannot sell that item.").also { return TransactionStatus.Failure("Shop cannot sell this item") } if(currency == Items.COINS_995){ - var amt = item.amount - var inStockAmt = inStock.amount - while(amt-- > 1) - cost.amount += getGPCost(Item(item.id, 1), if (isMainStock) stock[slot].amount else playerStock[slot].amount, --inStockAmt) + val fixedPrice = fixedPriceItems[item.id] + if (fixedPrice != null) { + // Fixed price items: simple multiplication + cost.amount = fixedPrice * item.amount + } else { + // Dynamic pricing: calculate cost for each item as stock depletes + var amt = item.amount + var inStockAmt = inStock.amount + while(amt-- > 1) + cost.amount += getGPCost(Item(item.id, 1), if (isMainStock) stock[slot].amount else playerStock[slot].amount, --inStockAmt) + } } else { cost.amount = cost.amount * item.amount } @@ -379,7 +395,10 @@ class Shop(val title: String, val stock: Array, val general: Boolean = return TransactionStatus.Failure("Attempt to sell to full shop.") } - if(currency == Items.COINS_995 && item.amount > 1){ + val fixedPrice = fixedPriceItems[id] + if (fixedPrice != null) { + profit.amount = fixedPrice * item.amount + } else if(currency == Items.COINS_995 && item.amount > 1){ var amt = item.amount var inStockAmt = container!![shopSlot]?.amount ?: playerStock.getAmount(id) while(amt-- > 1) @@ -446,11 +465,17 @@ class Shop(val title: String, val stock: Array, val general: Boolean = return Pair(isPlayerStock, shopSlot) } - companion object { - //General stores globally share player stock (weird quirk, right?) - val generalPlayerStock = Container(40, ContainerType.SHOP) - val listenerInstances = HashMap() - } + companion object { + //General stores globally share player stock (weird quirk, right?) + val generalPlayerStock = Container(40, ContainerType.SHOP) + val listenerInstances = HashMap() + + // Items with fixed prices that don't fluctuate based on stock (both buy & sell price) + val fixedPriceItems = mapOf( + Items.SPIRIT_SHARDS_12183 to 25, + Items.POUCH_12155 to 1 + ) + } sealed class TransactionStatus { class Success : TransactionStatus() diff --git a/Server/src/main/core/game/shops/Shops.kt b/Server/src/main/core/game/shops/Shops.kt index 94408357e..b79b354f2 100644 --- a/Server/src/main/core/game/shops/Shops.kt +++ b/Server/src/main/core/game/shops/Shops.kt @@ -20,6 +20,7 @@ import org.rs09.consts.Components import org.rs09.consts.Items import org.rs09.consts.NPCs import java.io.FileReader +import content.data.Quests /** * The "controller" class for shops. Handles opening shops from various NPC interactions and updating stock, etc. @@ -67,7 +68,8 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe return@map }} } else { - items.add(ShopItem(item, amount.toInt(), tokens.getOrNull(2)?.toIntOrNull() ?: 100)) + val restockRate = tokens.getOrNull(2)?.toIntOrNull() ?: 100 + items.add(ShopItem(item, amount.toInt(), restockRate)) idsInStock[item] = true } } catch (e: Exception) { @@ -126,8 +128,8 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe override fun defineListeners() { on(IntType.NPC, "trade", "shop"){ player, node -> val npc = node as NPC - if (npc.id == 2824) { - TanningProduct.open(player, 2824) + if (npc.id == 2824 || npc.id == 1041 || npc.id == 804) { + TanningProduct.open(player, npc.id) return@on true } if (npc.id == 7601) { @@ -149,7 +151,7 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe } on(NPCs.FUR_TRADER_1316, IntType.NPC, "trade") { player, node -> - if (!isQuestComplete(player, "Fremennik Trials")) { + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { sendNPCDialogue(player, NPCs.FUR_TRADER_1316, "I don't sell to outerlanders.", core.game.dialogue.FacialExpression.ANNOYED).also { END_DIALOGUE } } else { shopsByNpc[node.id]?.openFor(player) @@ -158,7 +160,7 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe } on(NPCs.CANDLE_MAKER_562, IntType.NPC, "trade") { player, node -> - if (getQuestStage(player, "Merlin's Crystal") > 60) { + if (getQuestStage(player, Quests.MERLINS_CRYSTAL) > 60) { openId(player, 56) } else { shopsByNpc[node.id]?.openFor(player) @@ -282,13 +284,13 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe } override fun defineCommands() { - define("openshop", Privilege.ADMIN) { player, args -> + define("openshop", Privilege.ADMIN, "::openshop shop-id", "Opens the shop interface for shop-id.") { player, args -> if(args.size < 2) reject(player, "Usage: ::openshop shopId") val shopId = args[1].toInt() shopsById[shopId]?.openFor(player) } - define("shopscript") { player, args -> + define("shopscript", usage = "::shopscript object", description = "Runs CS2 script 25 with string \"vg\" and objects \"object, 92\"") { player, args -> val arg1 = args[1].toInt() player.packetDispatch.sendRunScript(25, "vg", arg1, 92) //Run CS2 script 25, with args 868? and 92(our container id) } diff --git a/Server/src/main/core/game/system/SystemTermination.java b/Server/src/main/core/game/system/SystemTermination.java index a1557f381..813b16fe3 100644 --- a/Server/src/main/core/game/system/SystemTermination.java +++ b/Server/src/main/core/game/system/SystemTermination.java @@ -45,6 +45,10 @@ public final class SystemTermination { log(this.getClass(), Log.INFO, "Stopping all bots..."); AIRepository.clearAllBots(); Server.getReactor().terminate(); + if (Server.getWebSocketServer() != null) { + Server.getWebSocketServer().stop(1000, "Server shutting down"); + Server.setWebSocketServer(null); + } log(this.getClass(), Log.INFO, "Stopping all pulses..."); GameWorld.getMajorUpdateWorker().stop(); for (Iterator it = Repository.getPlayers().iterator(); it.hasNext();) { diff --git a/Server/src/main/core/game/system/command/Command.kt b/Server/src/main/core/game/system/command/Command.kt index fdbc56d90..c76e42a61 100644 --- a/Server/src/main/core/game/system/command/Command.kt +++ b/Server/src/main/core/game/system/command/Command.kt @@ -2,18 +2,28 @@ package core.game.system.command import core.game.node.entity.player.Player import core.ServerConstants +import core.api.sendChat +import core.game.node.entity.player.info.Rights import core.game.world.GameWorld import kotlin.collections.ArrayList /** * Base class for Commands in the new system. Can pass a lambda as part of the constructor or after the constructor. - * @author Ceikry + * @author Ceikry, Player Name */ class Command(val name: String, val privilege: Privilege, val usage: String = "UNDOCUMENTED", val description: String = "UNDOCUMENTED", val handle: (Player, Array) -> Unit) { fun attemptHandling(player: Player, args: Array?){ args ?: return - if(player.rights.ordinal >= privilege.ordinal || GameWorld.settings?.isDevMode == true || ServerConstants.I_AM_A_CHEATER){ + val hasRights = player.rights == Rights.ADMINISTRATOR || (ServerConstants.PLAYER_COMMANDS && player.rights.ordinal >= privilege.ordinal) + val isDev = GameWorld.settings?.isDevMode == true + val isCheater = ServerConstants.I_AM_A_CHEATER + if (hasRights || isDev || isCheater) { handle(player,args) + } else if (ServerConstants.PLAYER_COMMANDS || args[0] == "bank") { + // Authentically, if you attempt to use a command you shouldn't have access to, the game is supposed to say the below line. + // We do this for all our custom commands if they are enabled (in which case this will only trigger for commands above your privilege level), + // otherwise we only do it for the one command we have evidence existed authentically, "bank" (https://www.reddit.com/r/2007scape/comments/3n1c4d/hey_everyone_i_just_tried_to_do_something_very/) + sendChat(player, "Hey, everyone, I just tried to do something very silly!") } } } diff --git a/Server/src/main/core/game/system/command/CommandSystem.kt b/Server/src/main/core/game/system/command/CommandSystem.kt index 8912a531a..3601182b0 100644 --- a/Server/src/main/core/game/system/command/CommandSystem.kt +++ b/Server/src/main/core/game/system/command/CommandSystem.kt @@ -1,7 +1,7 @@ package core.game.system.command import core.game.node.entity.player.Player -import core.game.system.command.CommandSet +import core.tools.colorize /** * Represents a managing system used to dispatch incoming commands. @@ -21,9 +21,11 @@ class CommandSystem { if(command == null) { for (set in CommandSet.values()) { if (set.interpret(player, arguments[0], *arguments)) { + player.sendMessage(colorize("-->%Y${arguments[0]}: Deprecated command")) return true } } + player.sendMessage(colorize("-->%R${arguments[0]}: command not found")) } else { try { command.attemptHandling(player, arguments) diff --git a/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt b/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt index adaf066ad..17d98c883 100644 --- a/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt +++ b/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt @@ -48,6 +48,7 @@ class VisualCommand : CommandPlugin() { "invisible", "invis", "seti" -> { player!!.isInvisible = !player.isInvisible player.sendMessage("You are now " + (if (player.isInvisible) "invisible" else "rendering") + " for other players.") + return true } "maxkc" -> { var i = 0 @@ -120,6 +121,7 @@ class VisualCommand : CommandPlugin() { } location = Location.create(args[2]!!.toInt(), args[3]!!.toInt(), if (args.size > 4) args[4]!!.toInt() else 0) player!!.packetDispatch.sendPositionedGraphic(args[1]!!.toInt(), if (args.size > 5) args[5]!!.toInt() else 0, if (args.size > 6) args[6]!!.toInt() else 0, location) + return true } "npc" -> { if (args!!.size < 2) { @@ -174,8 +176,14 @@ class VisualCommand : CommandPlugin() { player!!.debug("Is tele allowed here? " + RegionManager.isTeleportPermitted(player!!.location)) return true } - "oib" -> player!!.interfaceManager.openInfoBars() - "char" -> CharacterDesign.open(player) + "oib" -> { + player!!.interfaceManager.openInfoBars() + return true + } + "char" -> { + CharacterDesign.open(player) + return true + } "savenpc" -> return true "objwithanim" -> { val go = Scenery(toInteger(args!![1]!!), player!!.location, 0) @@ -189,7 +197,7 @@ class VisualCommand : CommandPlugin() { return true } location = if (args.size > 2) Location.create(args[1]!!.toInt(), args[2]!!.toInt(), player!!.location.z) else player!!.location - `object` = RegionManager.getObject(location) + `object` = RegionManager.getObject(location!!) if (`object` == null) { player!!.debug("error: object not found in region cache.") return true @@ -212,7 +220,10 @@ class VisualCommand : CommandPlugin() { player!!.interfaceManager.openComponent(componentId) return true } - "ti" -> player!!.packetDispatch.sendInterfaceConfig(90, 87, false) + "ti" -> { + player!!.packetDispatch.sendInterfaceConfig(90, 87, false) + return true + } "iconfig", "inter_config" -> { if (args!!.size < 2) { player!!.debug("syntax error: interface-id child hidden") @@ -252,6 +263,7 @@ class VisualCommand : CommandPlugin() { } }) } + return true } "loop_anim_on_i" -> { var anim = toInteger(args!![1]!!) @@ -262,12 +274,14 @@ class VisualCommand : CommandPlugin() { return false } }) + return true } "send_i_anim" -> { val iface = args?.getOrNull(0) ?: return true val anim = args.getOrNull(1) ?: return true player?.packetDispatch?.sendAnimationInterface(toInteger(anim), toInteger(iface),7) + return true } "loop_inter" -> { val st = toInteger(args!![1]!!) diff --git a/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt b/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt index ada26eaca..d06258333 100644 --- a/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt @@ -1,5 +1,10 @@ package core.game.system.command.sets +import core.api.animate +import core.api.delayScript +import core.api.queueScript +import core.api.stopExecuting +import core.game.interaction.QueueStrength import core.game.node.entity.npc.NPC import core.game.system.task.Pulse import core.game.world.update.flag.context.Animation @@ -27,6 +32,28 @@ class AnimationCommandSet : CommandSet(Privilege.ADMIN) { player.animate(animation) } + define("anims", Privilege.ADMIN, "::anims <(opt) Duration Per Animation>", "Plays animations from the From ID to the To ID, with a delay of 3 between animations, unless specified otherwise"){ player, args -> + + if (args.size < 3) { + reject(player, "Syntax error: ::anims <(opt) Duration Per Animation>") + } + val animationFrom = args[1].toInt() + val animationTo = args[2].toInt() + val animationDelay = (args.getOrNull(3) ?: "3").toInt() + + queueScript(player, 1, QueueStrength.STRONG) { stage: Int -> + val animationId = animationFrom + stage + animate(player, animationId, true) + notify(player, "Playing animation $animationId") + + if (animationId == animationTo) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayScript(player, animationDelay) + } + } + /** * Force the player to loop animation */ @@ -56,11 +83,23 @@ class AnimationCommandSet : CommandSet(Privilege.ADMIN) { if (args.size < 2) { reject(player, "Syntax error: ::ranim ") } - try { - player.appearance.setAnimations(Animation.create(args[1].toInt())) - player.appearance.sync() - } catch (e: NumberFormatException) { - reject(player, "Syntax error: ::ranim ") + if (args.size > 2) { + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = args[1].toInt() + override fun pulse(): Boolean { + player.appearance.setAnimations(Animation.create(id)) + player.appearance.sync() + player.sendChat("Current: $id") + return ++id >= args[2].toInt() + } + }) + } else { + try { + player.appearance.setAnimations(Animation.create(args[1].toInt())) + player.appearance.sync() + } catch (e: NumberFormatException) { + reject(player, "Syntax error: ::ranim ") + } } } diff --git a/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt b/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt index ac8ee0324..70e797b0c 100644 --- a/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt @@ -18,13 +18,13 @@ class MusicCommandSet : CommandSet(Privilege.STANDARD){ /** * Command that lets you play a specific song */ - define("playsong"){player,args -> + define("playsong", usage = "::playsong song-id", description = "Plays the music track song-id."){player,args -> if(args.size < 2){ - reject(player,"Usage: ::playsong songID") + reject(player,"Usage: ::playsong ") } val id = args[1].toIntOrNull() if(id == null){ - reject(player,"Please use a valid integer for the song id.") + reject(player,"Please use a valid integer for the song ID.") } player.musicPlayer.play(MusicEntry.forId(id!!)) notify(player,"Now playing song $id") @@ -32,13 +32,13 @@ class MusicCommandSet : CommandSet(Privilege.STANDARD){ /** * Command that lets you play a specific jingle */ - define("playjingle"){player,args -> + define("playjingle", usage = "::playjingle jingle-id", description = "Plays the sound effect with ID jingle-id."){player,args -> if(args.size < 2){ - reject(player,"Usage: ::playjingle jingleID") + reject(player,"Usage: ::playjingle ") } val id = args[1].toIntOrNull() if(id == null){ - reject(player,"Please use a valid integer for the jingle id.") + reject(player,"Please use a valid integer for the jingle ID.") } PacketRepository.send(MusicPacket::class.java, MusicContext(player, id!!, true)) notify(player,"Now playing jingle $id") @@ -49,7 +49,7 @@ class MusicCommandSet : CommandSet(Privilege.STANDARD){ * this is mostly useful for custom tracks that aren't in the ingame * music player yet. */ - define("playid"){player,arg -> + define("playid", usage = "::playid song-id", description = "Plays a music track by musicId instead of numeric music track ID."){player,arg -> if (arg.size < 2) reject(player, "Needs more args.") val id = arg[1].toIntOrNull() @@ -63,7 +63,7 @@ class MusicCommandSet : CommandSet(Privilege.STANDARD){ * Command that unlocks all music tracks for the player * Restricted to ADMIN access only. */ - define("allmusic", Privilege.ADMIN){ player, _ -> + define("allmusic", Privilege.ADMIN, description = "Unlocks every music track for you."){ player, _ -> for (me in MusicEntry.getSongs().values) { player.musicPlayer.unlock(me.id) } @@ -71,9 +71,9 @@ class MusicCommandSet : CommandSet(Privilege.STANDARD){ /** * Command that lets you play an audio id */ - define("audio", Privilege.ADMIN, "::audio id loops[optional]", "Plays audio by id") { player, args -> + define("audio", Privilege.ADMIN, "::audio id loops[optional]", "Plays audio by ID. Loopable with optional integer argument.") { player, args -> if (args.size < 2 || args.size > 3) - reject(player, "Usage: ::audio id loops[optional]") + reject(player, "Usage: ::audio loops[optional]") val id = args[1].toInt() val loops = if (args.size > 2) args[2].toInt() else 1 playAudio(player, id, 0, loops) @@ -81,9 +81,9 @@ class MusicCommandSet : CommandSet(Privilege.STANDARD){ /** * Command that lets you play an audio id globally by playername or coords */ - define("globalaudio", Privilege.ADMIN, "::globalaudio id radius[max 15] location[player name or x y z]", "Play global audio by id, radius, and location") { player, args -> + define("globalaudio", Privilege.ADMIN, "::globalaudio id radius[max 15] location[player name OR x y z]", "Play global audio by ID, radius, and location") { player, args -> if (args.size < 3) - reject(player, "Usage: ::globalaudio id radius[max 15] location[player name or x y z]") + reject(player, "Usage: ::globalaudio id radius[max 15] location[player name OR x y z]") val loc = when (args.size) { 6 -> Location(args[3].toInt(),args[4].toInt(),args[5].toInt()) 4 -> Repository.getPlayerByName(args[3])?.location diff --git a/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt b/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt index 25c5fb2e1..825dd326d 100644 --- a/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt @@ -4,6 +4,7 @@ import core.plugin.Initializable import core.game.system.command.Command import core.game.system.command.Privilege import core.api.* +import core.game.interaction.QueueStrength @Initializable class ConfigCommandSet : CommandSet(Privilege.ADMIN){ @@ -12,7 +13,7 @@ class ConfigCommandSet : CommandSet(Privilege.ADMIN){ /** * Sets a range of configs to a maximum value */ - define("sconfigrange"){player, args -> + define("sconfigrange", usage = "::sconfigrange start-id end-id", description = "Sets each varp from start-id (inclusive) up to end-id (exclusive) to Integer.MAX_VALUE."){player, args -> if (args.size < 3) { reject(player, "usage: sconfigrange idlo idhi") } @@ -27,7 +28,7 @@ class ConfigCommandSet : CommandSet(Privilege.ADMIN){ /** * Sets a range of configs to 0 */ - define("sconfigrange0"){player, args -> + define("sconfigrange0", usage = "::sconfigrange0 start-id end-id", description = "Sets each varp from start-id (inclusive) up to end-id (exclusive) to 0."){player, args -> if (args.size < 3) { reject(player, "usage: sconfigrange0 idlo idhi") } @@ -44,11 +45,33 @@ class ConfigCommandSet : CommandSet(Privilege.ADMIN){ */ define("iface", Privilege.ADMIN, "::iface Interface ID", "Opens the interface with the given ID."){player, args -> if (args.size < 2) { - reject(player, "usage: iface id") + reject(player, "usage: ::iface ") return@define } val id = args[1].toIntOrNull() ?: reject(player, "INVALID INTERFACE ID") player.interfaceManager.openComponent(id as Int) } + + define("ifaces", Privilege.ADMIN, "::ifaces <(opt) Duration Per Interface>", "Opens interfaces from the From ID to the To ID, with a delay of 3 between each, unless specified otherwise"){ player, args -> + + if (args.size < 3) { + reject(player, "Syntax error: ::anims <(opt) Duration Per Interface>") + } + val ifaceFrom = args[1].toInt() + val ifaceTo = args[2].toInt() + val ifaceDelay = (args.getOrNull(3) ?: "3").toInt() + + queueScript(player, 1, QueueStrength.WEAK) { stage: Int -> + val ifaceId = ifaceFrom + stage + player.interfaceManager.openComponent(ifaceId) + notify(player, "Opening interface $ifaceId") + + if (ifaceId == ifaceTo) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayScript(player, ifaceDelay) + } + } } } diff --git a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt index 0e4efde67..25ef32fef 100644 --- a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt @@ -1,15 +1,16 @@ package core.game.system.command.sets import content.global.activity.jobs.JobManager -import content.global.skill.slayer.Master +import content.global.skill.construction.decoration.pohstorage.Storable +import content.global.skill.construction.decoration.pohstorage.StorableFamily import core.api.* import core.cache.Cache import core.cache.def.impl.DataMap import core.cache.def.impl.NPCDefinition import core.cache.def.impl.VarbitDefinition import core.cache.def.impl.Struct -import core.game.dialogue.DialogueFile import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.player.link.SpellBookManager import core.game.node.entity.player.link.diary.DiaryType @@ -20,7 +21,6 @@ import core.plugin.Initializable import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.rs09.consts.Items -import core.tools.SystemLogger import core.game.system.command.Privilege import java.io.BufferedWriter import java.io.File @@ -28,25 +28,98 @@ import java.io.FileWriter import java.util.Arrays import core.net.packet.PacketWriteQueue import core.tools.Log -import core.game.world.update.flag.* -import core.game.world.update.flag.context.* -import core.game.node.entity.impl.* +import core.game.node.entity.player.info.Rights +import core.game.node.entity.skill.Skills import core.game.world.map.Location +import core.game.world.map.RegionManager.getLocalEntitys +import core.game.world.repository.Repository +import org.json.simple.JSONArray +import kotlin.collections.set +import content.global.activity.penguinhns.Penguin +import content.global.activity.penguinhns.PenguinHNSEvent +import content.global.activity.penguinhns.PenguinManager +import content.global.activity.penguinhns.PenguinManager.Companion.penguins +import content.global.activity.penguinhns.PenguinManager.Companion.spawner +import content.global.activity.penguinhns.PenguinManager.Companion.tagMapping +import content.global.activity.penguinhns.PenguinManager.Companion.updateStoreFile +import core.ServerStore.Companion.toJSONArray +import org.rs09.consts.NPCs @Initializable class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { - val farmKitItems = arrayListOf(Items.RAKE_5341, Items.SPADE_952, Items.SEED_DIBBER_5343, Items.WATERING_CAN8_5340, Items.SECATEURS_5329, Items.GARDENING_TROWEL_5325) + val farmKitItems = arrayListOf(Items.RAKE_5341, Items.SPADE_952, Items.SEED_DIBBER_5343, Items.WATERING_CAN8_5340, Items.SECATEURS_5329, Items.GARDENING_TROWEL_5325,Items.COMPOST_6032, Items.SUPERCOMPOST_6034, Items.PLANT_CURE_6036) val runeKitItems = arrayListOf(Items.AIR_RUNE_556, Items.EARTH_RUNE_557, Items.FIRE_RUNE_554, Items.WATER_RUNE_555, Items.MIND_RUNE_558, Items.BODY_RUNE_559, Items.DEATH_RUNE_560, Items.NATURE_RUNE_561, Items.CHAOS_RUNE_562, Items.LAW_RUNE_563, Items.COSMIC_RUNE_564, Items.BLOOD_RUNE_565, Items.SOUL_RUNE_566, Items.ASTRAL_RUNE_9075) + + fun getPlayerFromArgs(player: Player, args: Array, startindex: Int = 1): Player? { + val n = args.slice(startindex until args.size).joinToString("_") + if (n == "") { //no argument given -> return self player + return player + } + val target = Repository.getPlayerByName(n) + if (target == null) { + reject(player, "Could not find a player named '$n'") + } + return target + } + override fun defineCommands() { - /** - * Gives the player a set of tools used to test farming stuff. - */ define("farmkit", Privilege.ADMIN, "", "Provides a kit of various farming equipment."){player,_ -> for(item in farmKitItems){ player.inventory.add(Item(item)) } } + /** + * Adds a subset of POH storable item takeIds to the player's bank, filtered by StorableFamily type. These are stored in the costume room or bookcase. + * Usage: ::pohstorableitems [TYPE] + * Example: ::pohstorableitems BOOKCASE + * Example: ::pohstorableitems TREASURE_CHEST_MED + */ + define("pohstorableitems", Privilege.ADMIN, "::pohstorableitems TYPE", "Adds POH storable items to bank. To see TYPEs, use the command with no argument.") { player, args -> + // Check for the argument (StorableFamily type) + val typeArg = if (args.size > 1) args[1].uppercase() else null + + val allStorables = Storable.values() + + // Filter the list of items based on the provided argument + val itemsToProcess = if (typeArg != null) { + try { + val targetFamily = StorableFamily.valueOf(typeArg) + allStorables.filter { it.type == targetFamily } + } catch (e: IllegalArgumentException) { + sendMessage(player, "Error: Unknown StorableFamily type '$typeArg'. Valid types are:") + StorableFamily.values().forEach { family -> + sendMessage(player, family.toString()) + } + return@define + } + } else { + // If no argument is provided, default to all storables + sendMessage(player, "Valid types are:") + StorableFamily.values().forEach { family -> + sendMessage(player, family.toString()) + } + return@define + } + + if (itemsToProcess.isEmpty()) { + sendMessage(player, "No storable items found for type: '$typeArg'.") + return@define + } + + var totalItemsAdded = 0 + + // Process the filtered list of storables + itemsToProcess.forEach { storable -> + storable.takeIds.forEach { itemId -> + if (player.bank.add(Item(itemId))) { + totalItemsAdded++ + } + } + } + return@define + } + define("cs2", Privilege.ADMIN, "::cs2 id args", "Allows you to call arbitrary cs2 scripts during runtime") {player, args -> var scriptArgs = ArrayList() if (args.size == 2) { @@ -61,7 +134,7 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { } } - define("cleardiary", Privilege.ADMIN) { player, _ -> + define("cleardiary", Privilege.ADMIN, description = "Resets all achievement diary progress.") { player, _ -> for (type in DiaryType.values()) { val diary = player.achievementDiaryManager.getDiary(type) for (level in 0 until diary.levelStarted.size) { @@ -73,7 +146,7 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { sendMessage(player, "All achievement diaries cleared successfully.") } - define("clearjob", Privilege.ADMIN) { player, _ -> + define("clearjob", Privilege.ADMIN, description = "Clears your current job assignment.") { player, _ -> val playerJobManager = JobManager.getInstance(player) playerJobManager.job = null playerJobManager.jobAmount = -1 @@ -95,18 +168,18 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { player.spellBookManager.update(player) } - define("killme", Privilege.ADMIN, "", "Does exactly what it says on the tin.") { player, _ -> + define("killme", Privilege.ADMIN, description = "Literally kills you in-game even") { player, _ -> player.impactHandler.manualHit(player, player.skills.lifepoints, HitsplatType.NORMAL) } - define("struct") {player, args -> + define("struct", usage = "::struct struct-id", description = "Logs the struct definition for the given cache id.") {player, args -> val mapId = args[1].toIntOrNull() ?: return@define val def = Struct.get(mapId) log(this::class.java, Log.FINE, def.toString()) } - define("datamap") {player, args -> + define("datamap", usage = "::datamap data-map-id", description = "Logs the data map definition for the given cache id.") {player, args -> val mapId = args[1].toIntOrNull() ?: return@define val def = DataMap.get(mapId) @@ -117,15 +190,16 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { val dump = File("structs.txt") val writer = BufferedWriter(FileWriter(dump)) val index = Cache.getIndexes()[2] - val containers = index.information.containers[26].filesIndexes - for(fID in containers) - { - val file = index.getFileData(26, fID) - if(file != null){ - val def = Struct.parse(fID, file) - if(def.dataStore.isEmpty()) continue //no data in struct. - writer.write(def.toString()) - writer.newLine() + val containers = index.information.containers[26]!!.filesIndexes + if (containers != null) { + for(fID in containers) { + val file = index.getFileData(26, fID) + if(file != null){ + val def = Struct.parse(fID, file) + if(def.dataStore.isEmpty()) continue //no data in struct. + writer.write(def.toString()) + writer.newLine() + } } } writer.flush() @@ -141,15 +215,16 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { for(cID in containers) { - val fileIndexes = index.information.containers[cID].filesIndexes - for(fID in fileIndexes) - { - val file = index.getFileData(cID, fID) - if(file != null){ - val def = DataMap.parse((cID shl 8) or fID, file) - if(def.keyType == '?') continue //Empty definition - only a 0 present in the cachefile data. - writer.write(def.toString()) - writer.newLine() + val fileIndexes = index.information.containers[cID]!!.filesIndexes + if (fileIndexes != null) { + for(fID in fileIndexes) { + val file = index.getFileData(cID, fID) + if(file != null){ + val def = DataMap.parse((cID shl 8) or fID, file) + if(def.keyType == '?') continue //Empty definition - only a 0 present in the cachefile data. + writer.write(def.toString()) + writer.newLine() + } } } } @@ -157,18 +232,35 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { writer.close() } - define("rolldrops", Privilege.ADMIN, "::rolldrops NPC ID AMOUNT", "Rolls the given NPC drop table AMOUNT times.") { player: Player, args: Array -> - if(args.size < 2){ - reject(player,"Usage: ::rolldrops npcid amount") + define( + "rolldrops", + Privilege.ADMIN, + "::rolldrops NPC ID AMOUNT [true|false]", + "Rolls the given NPC drop table AMOUNT times. Add true to persist the items in your bank." + ) { player: Player, args: Array -> + if (args.size < 3) { + reject(player, "Usage: ::rolldrops npcid amount [true|false]") } - val container = player.dropLog val npcId = args[1].toInt() val amount = args[2].toInt() + val container = when (args.getOrNull(3)) { + "true" -> player.bank + "false", null -> { + player.dropLog.clear() + player.dropLog + } + + else -> { + reject(player, "Usage: ::rolldrops npcid amount [true|false]") + return@define + } + + } - container.clear() val drops = NPCDefinition.forId(npcId).dropTables.table.roll(player, amount) - for(drop in drops) container.add(drop, false) + + for (drop in drops) container.add(drop, false) container.open(player) } @@ -191,11 +283,11 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { } } - define("testpacket") { player, _ -> + define("testpacket", description = "Sends the reset-interface packet to the client.") { player, _ -> PacketWriteQueue.write(ResetInterface(), PlayerContext(player)) } - define("npcsearch", Privilege.STANDARD, "npcsearch name", "Searches for NPCs that match the name either in main or children.") {player, strings -> + define("npcsearch", Privilege.STANDARD, "::npcsearch name", "Searches for NPCs that match the name either in main or children.") {player, strings -> val name = strings.slice(1 until strings.size).joinToString(" ").lowercase() for (id in 0 until 9000) { val def = NPCDefinition.forId(id) @@ -213,7 +305,7 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { } } - define("itemsearch") {player, args -> + define("itemsearch", Privilege.STANDARD, "::itemsearch name", "Searches for items that match the name.") {player, args -> val itemName = args.copyOfRange(1, args.size).joinToString(" ").lowercase() for (i in 0 until 15000) { val name = getItemName(i).lowercase() @@ -222,7 +314,7 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { } } - define("runekit", Privilege.ADMIN, "", "Gives 1k of each Rune type" ) { player, args -> + define("runekit", Privilege.ADMIN, "", "Gives 1000 of each rune type. We love casting spells" ) { player, args -> for(item in runeKitItems) { addItem(player, item, 1000) } @@ -244,23 +336,23 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { setAttribute (player, "routedraw", !getAttribute(player, "routedraw", false)) } - define ("fmstart", Privilege.ADMIN, "", "") {player, _ -> + define ("fmstart", Privilege.ADMIN, description = "Marks your current tile as the force-movement start point.") {player, _ -> setAttribute(player, "fmstart", Location.create(player.location)) } - define ("fmend", Privilege.ADMIN, "", "") {player, _ -> + define ("fmend", Privilege.ADMIN, description = "Marks your current tile as the force-movement destination.") {player, _ -> setAttribute(player, "fmend", Location.create(player.location)) } - define ("fmspeed", Privilege.ADMIN, "", "") {player, args -> + define ("fmspeed", Privilege.ADMIN, "::fmspeed start-speed", "Sets the starting force-movement speed (client cycles between steps) used by ::testfm.") {player, args -> setAttribute(player, "fmspeed", args[1].toIntOrNull() ?: 10) } - define ("fmspeedend", Privilege.ADMIN, "", "") {player, args -> + define ("fmspeedend", Privilege.ADMIN, "::fmspeedend end-speed", "Sets the ending speed (client cycles between steps) used by ::testfm.") {player, args -> setAttribute(player, "fmspeedend", args[1].toIntOrNull() ?: 10) } - define("testfm", Privilege.ADMIN, "", "") { player, _ -> + define("testfm", Privilege.ADMIN, description = "Runs the configured force-movement from the saved start to end point.") { player, _ -> val start = getAttribute(player, "fmstart", Location.create(player.location)) val end = getAttribute(player, "fmend", Location.create(player.location)) val speed = getAttribute(player, "fmspeed", 10) @@ -269,7 +361,7 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { forceMove(player, start, end, speed, speedEnd, anim = ani) } - define("fmanim", Privilege.ADMIN, "", "") {player, args -> + define("fmanim", Privilege.ADMIN, "::fmanim animation-id", "Sets the animation id to play during ::testfm.") {player, args -> setAttribute(player, "fmanim", args[1].toIntOrNull() ?: -1) } @@ -294,5 +386,127 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { player.sendMessage(" ${timer.identifier}") } } - } + + define("setpestpoints", Privilege.ADMIN, "::setpestpoints points player_name[optional]", "Sets your (or player_names) Pest Control points to points") { player, args -> + val target = getPlayerFromArgs(player, args, 2) ?: return@define + val points = args[1].toIntOrNull() + if (points == null) { + reject(player, "No valid 'points' argument given") + } + target.savedData.activityData.pestPoints = points!! + } + + define("makeadmin", Privilege.ADMIN, "::makeadmin player_name", "Permanently gives admin rights to player_name (or self if empty)") { player, args -> + val target = getPlayerFromArgs(player, args, 1) ?: return@define + target.details.rights = Rights.ADMINISTRATOR + sendMessage(player, "Gave admin rights to ${target.username}.") + sendMessage(target, "You've been given admin rights by ${player.username}!") + } + + define("dropadmin", Privilege.ADMIN, "::dropadmin", "Permanently drops admin rights from self") { player, _ -> + player.details.rights = Rights.REGULAR_PLAYER + sendMessage(player, "Dropped admin rights.") + } + + define("max", Privilege.ADMIN, "::max player_name", "Sets all skills to 99s for player_name (or self if empty)") { player, args -> + val target = getPlayerFromArgs(player, args, 1) ?: return@define + var index = 0 + Skills.SKILL_NAME.forEach { + target.skills.setStaticLevel(index,99) + target.skills.setLevel(index,99) + index++ + } + target.skills.updateCombatLevel() + } + + define("noobme", Privilege.ADMIN, "::noobme player_name", "Sets player_name (or self if empty) back to default stats") { player, args -> + val target = getPlayerFromArgs(player, args, 1) ?: return@define + var index = 0 + Skills.SKILL_NAME.forEach { + val level = if (index == Skills.HITPOINTS) 10 else 1 + target.skills.setStaticLevel(index, level) + target.skills.setLevel(index, level) + index++ + } + target.skills.updateCombatLevel() + } + + define("setlevel", Privilege.ADMIN, "::setlevel SKILL NAME LEVEL PLAYER", "Sets SKILL NAME to LEVEL for PLAYER (self if omitted)."){player,args -> + if (args.size < 3) reject(player,"Usage: ::setlevel skillname level") + val skillname = args[1] + val desiredLevel: Int? = args[2].toIntOrNull() + if (desiredLevel == null) { + reject(player, "Level must be an integer.") + } + if (desiredLevel!! > 99) reject(player,"Level must be 99 or lower.") + val skill = Skills.getSkillByName(skillname) + if (skill < 0) reject(player, "Must use a valid skill name!") + val target = getPlayerFromArgs(player, args, 3) ?: return@define + target.skills.setStaticLevel(skill,desiredLevel) + target.skills.setLevel(skill,desiredLevel) + target.skills.updateCombatLevel() + } + + define("addxp", Privilege.ADMIN, "::addxp skill name | id xp", "Add xp to skill") { player, args -> + if (args.size < 3) reject(player, "Usage: ::addxp skill name | id xp player(optional)") + val target = getPlayerFromArgs(player, args, 3) ?: return@define + + val skill = args[1].toIntOrNull() ?: Skills.getSkillByName(args[1]) + if (skill < 0 || skill >= Skills.NUM_SKILLS) reject(player, "Must use valid skill name or id.") + + val xp = args[2].toDoubleOrNull() + if (xp == null || xp <= 0) reject(player, "Xp must be a positive number.") + + target.skills.addExperience(skill, xp!!) + } + + define("renewpenguins", Privilege.ADMIN, "", "Generates a fresh set of weekly penguins") { player, _ -> + val spawnedOrdinals = (PenguinHNSEvent.getStoreFile()["spawned-penguins"] as JSONArray).map { it.toString().toInt() } + val penguinNPCs = arrayListOf(NPCs.BARREL_8104, NPCs.BUSH_8105,NPCs.CACTUS_8107,NPCs.CRATE_8108,NPCs.ROCK_8109,NPCs.TOADSTOOL_8110) + + spawnedOrdinals.forEach { + val peng = Penguin.values()[it] + val nearNPCs = getLocalEntitys(peng.location,1) + nearNPCs.forEach { npc -> + if (npc.id in penguinNPCs) { + poofClear(npc as NPC) + } + } + } + penguins = spawner.spawnPenguins(10) + PenguinHNSEvent.getStoreFile()["spawned-penguins"] = penguins.toJSONArray() + tagMapping.clear() + for (p in penguins) { + tagMapping.put(p, JSONArray()) + val pengCoord = Penguin.values()[p].location + player.debug("Penguin spawned at:$pengCoord") + } + updateStoreFile() + player.debug("Penguin positions have been renewed") + } + + define("spawnpenguin",Privilege.ADMIN,"::spawnPenguin Ordinal","Adds a new Penguin spawn to this weeks list based on the ordinal provided 0-64"){player,args-> + if (args.size!=2) reject (player,"Usage: ::spawnpenguin Ordinal") + val ordinal = args[1].toIntOrNull() + if (ordinal == null) reject(player,"Ordinal must be an integer.") + if (ordinal!! > 64 || ordinal < 0) reject(player,"Ordinal must be in the range 0-64 inclusive.") + + val store = PenguinHNSEvent.getStoreFile() + val ordinals = (store["spawned-penguins"] as? JSONArray) + ?.map { it.toString().toInt() } + ?.toMutableList() + ?: mutableListOf() + val peng = Penguin.values()[ordinal] + NPC(peng.id,peng.location) + .also { PenguinManager.npcs.add(it); it.isNeverWalks = true; it.isWalks = false }.init() + tagMapping.clear() + for (p in ordinals) { + tagMapping.put(p, JSONArray()) + } + updateStoreFile() + val pengCoords = peng.location + player.debug("Penguin spawned at:$pengCoords") + } + + } } diff --git a/Server/src/main/core/game/system/command/sets/FunCommandSet.kt b/Server/src/main/core/game/system/command/sets/FunCommandSet.kt index 4db7d398f..05b59c153 100644 --- a/Server/src/main/core/game/system/command/sets/FunCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/FunCommandSet.kt @@ -3,11 +3,13 @@ package core.game.system.command.sets import content.global.handlers.item.SpadeDigListener import content.region.misc.tutisland.handlers.iface.CharacterDesign import core.api.* +import core.ServerStore import core.game.dialogue.DialogueFile import core.game.node.entity.combat.ImpactHandler import core.game.node.entity.npc.NPC 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.system.command.Privilege import core.game.system.task.Pulse import core.game.world.GameWorld @@ -17,8 +19,9 @@ import core.game.world.repository.Repository.getPlayerByName import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics import core.plugin.Initializable -import core.tools.END_DIALOGUE import core.tools.RandomFunction +import core.tools.Log +import org.json.simple.JSONArray import org.json.simple.JSONObject import org.rs09.consts.Sounds import java.awt.HeadlessException @@ -30,24 +33,88 @@ import kotlin.streams.toList class FunCommandSet : CommandSet(Privilege.ADMIN) { var npcs: List = ArrayList() + private val TREASURE_KEY = "fun_command_buried_treasures" + private val treasures = ArrayList() + + init { + loadTreasures() + } + + /** + * I hope ceikry doesn't punish me for this ~ used SkillcapePerks for a base idea tried to make it modular. + * Supports persistence across reboots for bury, buryitem, and burymessage supporting all command arguments. + */ + private fun loadTreasures() { + + val archive = ServerStore.getArchive(TREASURE_KEY) + if (!archive.containsKey("data")) return + + try { + val array = archive["data"] as JSONArray + + for (obj in array) { + + val json = obj as JSONObject + val x = (json["x"] as Long).toInt() + val y = (json["y"] as Long).toInt() + val z = (json["z"] as Long).toInt() + val loc = Location.create(x, y, z) + + val type = TreasureType.valueOf(json["type"] as String) + val hiderName = json["hiderName"] as? String ?: "Unknown" + val hideName = json["hideName"] as? Boolean ?: false + val customMessage = json["customMessage"] as? String + val message = json["message"] as? String ?: "" + + val items = ArrayList() + if (json.containsKey("items")) { + val itemsJson = json["items"] as JSONArray + for (i in itemsJson) { + val itemObj = i as JSONObject + val id = (itemObj["id"] as Long).toInt() + val amount = (itemObj["amount"] as Long).toInt() + items.add(Item(id, amount)) + } + } + + val treasure = BuriedTreasure(loc, type, items, message, hiderName, hideName, customMessage) + treasures.add(treasure) + registerTreasureListener(treasure) + } + log(FunCommandSet::class.java, Log.DEBUG, "Loaded ${treasures.size} buried treasures.") + } catch (e: Exception) { + log(FunCommandSet::class.java, Log.ERR, "Failed to load buried treasures: ${e.message}") + e.printStackTrace() + } + } override fun defineCommands() { /** * Force animation + messages on all NPCs in a radius of 10 from the player. + * Add an optional 3rd argument if cycling through a range of animation ids. */ - define("npcanim", Privilege.ADMIN, "::npcanim Animation ID") { player, args -> + define("npcanim", Privilege.ADMIN, "::npcanim animation-id [end-animation-id]", "Makes nearby NPCs play animation-id, or loop that id up to end-animation-id.") { player, args -> if (args.size < 2) { reject(player, "Syntax error: ::npcanim ") } npcs = RegionManager.getLocalNpcs(player.location, 10) for (n in npcs) { - n.sendChat(args.slice(1 until args.size).joinToString(" ")) n.lock(6) n.faceTemporary(player, 6) - n.animator.animate(Animation(args[1].toInt())) - n.animate(Animation.create(-1), 6) + if (args.size == 2) { + n.sendChat(args.slice(1 until args.size).joinToString(" ")) + n.animate(Animation(args[1].toInt())) + n.animate(Animation.create(-1), 6) + } + if (args.size == 3) { + var count = 0 + for(animNum in args[1].toInt()..args[2].toInt()) { + count++ + n.animate(Animation(animNum), count*6) + } + } } } @@ -140,14 +207,14 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) { /** * Opens up the makeover interface */ - define("makeover", Privilege.MODERATOR){ player, _ -> + define("makeover", Privilege.MODERATOR, description = "Opens the makeover interface for your character."){ player, _ -> CharacterDesign.open(player) } /** * Copies your current appearance and equipment as JSON to the clipboard */ - define("dumpappearance", Privilege.MODERATOR){ player, _ -> + define("dumpappearance", Privilege.MODERATOR, description = "Copies your appearance and equipment as JSON to the clipboard."){ player, _ -> val json = JSONObject() PlayerSaver(player).saveAppearance(json) val equipJson = PlayerSaver(player).saveContainer(player.equipment) @@ -165,19 +232,39 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) { /** * Bury inventory at current location */ - define("bury"){player, _ -> + define("bury", description = "Buries your entire inventory at your current location for treasure hunters. Required true/false to hide players name and an optional custom message."){player, args -> if(player.inventory.isEmpty){ reject(player, "You have no items to bury.") } + if (args.size < 2) { + reject(player, "Usage: ::bury true | false [custom news message]") + return@define + } + + val hideName = when(args[1].lowercase()) { + "true" -> true + "false" -> false + else -> { + reject(player, "Invalid argument. Usage: ::bury true | false [custom news message]") + return@define + } + } + + val customMessage = if (args.size > 2) { + args.slice(2 until args.size).joinToString(" ") + } else { + null + } + player.dialogueInterpreter.open(object : DialogueFile(){ override fun handle(componentID: Int, buttonID: Int) { when(stage){ - 0 -> dialogue("This will bury your whole inventory in this spot.","Are you sure?").also { stage++ } + 0 -> dialogue("This will bury your whole inventory at this spot.","Are you sure?").also { stage++ } 1 -> options("Yes","No").also { stage++ } 2 -> when(buttonID){ - 1 -> bury(player).also { end() } - 2 -> stage = END_DIALOGUE + 1 -> bury(player, hideName, customMessage).also { end() } + 2 -> end() } } } @@ -185,6 +272,78 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) { } + /** + * Bury a secret message at current location for a player to find. + */ + define("burymessage", description = "Buries a secret message at your current location."){ player, args -> + if (args.size < 2) { + reject(player, "Usage: ::burymessage [message]") + return@define + } + + val message = args.slice(1 until args.size).joinToString(" ") + val loc = Location.create(player.location) + + if(SpadeDigListener.listeners.containsKey(loc)){ + reject(player, "There is already something buried here.") + return@define + } + + val treasure = BuriedTreasure(loc, TreasureType.MESSAGE, emptyList(), message, player.username, false, null) + treasures.add(treasure) + saveTreasures() + registerTreasureListener(treasure) + + notify(player, "You have buried the message '$message' at $loc") + log(FunCommandSet::class.java, Log.DEBUG, "Message buried by ${player.username} at $loc: \"$message\"") + } + + /** + * Bury a specific item at current location + */ + define("buryitem", description = "Buries a specific item at your current location."){ player, args -> + if (args.size < 3) { + reject(player, "Usage: ::buryitem item id true | false [custom message]") + return@define + } + + val itemId = args[1].toIntOrNull() + if (itemId == null) { + reject(player, "Invalid item ID.") + return@define + } + + val hideName = when(args[2].lowercase()) { + "true" -> true + "false" -> false + else -> { + reject(player, "Invalid argument. Usage: ::buryitem item id true | false [custom message]") + return@define + } + } + + val customMessage = if (args.size > 3) { + args.slice(3 until args.size).joinToString(" ") + } else { + null + } + + player.dialogueInterpreter.open(object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> dialogue("This will bury a ${Item(itemId).name} at this spot.","Are you sure?").also { stage++ } + 1 -> options("Yes","No").also { stage++ } + 2 -> when(buttonID){ + 1 -> buryItem(player, itemId, hideName, customMessage).also { end() } + 2 -> end() + } + } + } + }) + + + } + define("appearance", Privilege.ADMIN, "", "Allows you to change your appearance."){ player, _ -> CharacterDesign.reopen(player) } @@ -193,7 +352,7 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) { * Cast a weakened version of ice barrage on nearby players within the defined radius. * This spell will never kill or freeze a player */ - define("barrage", Privilege.ADMIN, "::barrage radius ", "Cast a weak barrage on all nearby players. Will never kill players") { player, args -> + define("barrage", Privilege.ADMIN, "::barrage radius", "Cast a weak Ice Barrage on all nearby players. Will never kill players") { player, args -> if (args.size != 2) reject(player, "Usage: ::barrage radius[max = 50]") val radius = if (args[1].toInt() > 50) 50 else args[1].toInt() @@ -207,21 +366,141 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) { p.graphics(Graphics(369, 0)) } } + + /** + * Toggles pet hunger to off, normal, or dev + * 0 = No hunger/growth mode (hunger/growth does not progress) + * 1 = Normal hunger/growth mode (1x speed) + * 2 = Dev hunger/growth mode (100x speed) + */ + define("petrate", Privilege.ADMIN, "::petrate 0-2", "Sets pet hunger and growth to off, normal, or dev."){ player, args -> + if(args.size < 2) { + notify(player, "Pet mode is currently ${player.getAttribute("petrate", 1)}") + return@define + } + val mode = args[1].toIntOrNull() ?: (-1).also { reject(player, "Please enter a valid number") } + if (mode in 0 .. 2) { + player.setAttribute("petrate", mode) + notify(player, "Setting pet mode to $mode") + } + else { + reject(player, "Only modes 0-2 are valid") + } + } + + /** + * Toggle instant woodcutting. + */ + define("instachop", Privilege.ADMIN, "", "Fells trees after a single log is gathered."){ player, _ -> + player.setAttribute("instachop", !player.getAttribute("instachop", false)) + notify(player,"Instachop mode " + if (player.getAttribute("instachop", false)) "on." else "off.") + } + } - fun bury(player: Player){ + fun bury(player: Player, hideName: Boolean = false, customMessage: String? = null){ + val loc = Location.create(player.location) - val inv = player.inventory.toArray().filterNotNull() - SpadeDigListener.registerListener(player.location){ p -> - for(item in inv){ - addItemOrDrop(p, item.id, item.amount) - sendMessage(p, "You dig and find ${if(item.amount > 1) "some" else "a"} ${item.name}") - } - sendNews("${player.username} has found the hidden treasure! Congratulations!!!") - SpadeDigListener.listeners.remove(loc) + if(SpadeDigListener.listeners.containsKey(loc)){ + notify(player, "There is already something buried here.") + return } + + val inv = player.inventory.toArray().filterNotNull().toList() + if (inv.isEmpty()) { + notify(player, "You have nothing to bury.") + return + } + + val treasure = BuriedTreasure(loc, TreasureType.ITEM, inv, "", player.username, hideName, customMessage) + treasures.add(treasure) + saveTreasures() + registerTreasureListener(treasure) + player.inventory.clear() notify(player, "You have buried your loot at ${loc.toString()}") + log(FunCommandSet::class.java, Log.DEBUG, "Loot buried by ${player.username} at $loc. Masked: $hideName") } + fun buryItem(player: Player, itemId: Int, hideName: Boolean, customMessage: String? = null) { + val loc = Location.create(player.location) + if(SpadeDigListener.listeners.containsKey(loc)){ + notify(player, "There is already something buried here.") + return + } + + val treasure = BuriedTreasure(loc, TreasureType.ITEM, listOf(Item(itemId, 1)), "", player.username, hideName, customMessage) + treasures.add(treasure) + saveTreasures() + registerTreasureListener(treasure) + + notify(player, "You have buried item ${Item(itemId).name} at $loc") + log(FunCommandSet::class.java, Log.DEBUG, "Item $itemId buried by ${player.username} at $loc. Masked: $hideName") + } + + private fun registerTreasureListener(t: BuriedTreasure) { + + SpadeDigListener.registerListener(t.location) { p -> + log(FunCommandSet::class.java, Log.DEBUG, "SpadeDigListener triggered for ${p.username} at ${t.location}") + + if (t.type == TreasureType.ITEM) { + for(item in t.items){ + addItemOrDrop(p, item.id, item.amount) + sendMessage(p, "You dig and find ${if(item.amount > 1) "some" else "a"} ${item.name}") + } + val finderName = if (t.hideName) "Someone" else p.username + val message = t.customMessage ?: "$finderName has found the hidden treasure! Congratulations!!!" + sendNews(message) + } else { + sendMessage(p, t.message) + } + + SpadeDigListener.listeners.remove(t.location) + treasures.remove(t) + saveTreasures() + } + } + + private fun saveTreasures() { + + val array = JSONArray() + + for (t in treasures) { + val json = JSONObject() + json["x"] = t.location.x + json["y"] = t.location.y + json["z"] = t.location.z + json["type"] = t.type.name + json["hiderName"] = t.hiderName + json["hideName"] = t.hideName + if (t.customMessage != null) json["customMessage"] = t.customMessage + json["message"] = t.message + + val itemsArray = JSONArray() + for (i in t.items) { + val itemObj = JSONObject() + itemObj["id"] = i.id + itemObj["amount"] = i.amount + itemsArray.add(itemObj) + } + json["items"] = itemsArray + + array.add(json) + } + val archive = ServerStore.getArchive(TREASURE_KEY) + archive["data"] = array + } + + private data class BuriedTreasure( + val location: Location, + val type: TreasureType, + val items: List, + val message: String, + val hiderName: String, + val hideName: Boolean, + val customMessage: String? + ) + + private enum class TreasureType { ITEM, MESSAGE } + } diff --git a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt index 7a96b1381..0727f65db 100644 --- a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt @@ -1,12 +1,14 @@ package core.game.system.command.sets -import content.global.handlers.iface.RulesAndInfo +import content.global.handlers.iface.* +import content.global.skill.summoning.familiar.Familiar +import content.global.skill.cooking.fermenting.BrewGrowth import content.global.skill.farming.timers.* import content.minigame.fishingtrawler.TrawlerLoot import content.region.misthalin.draynor.quest.anma.AnmaCutscene import core.ServerConstants import core.api.* -import core.api.utils.Permadeath.permadeath +import core.api.utils.permadeath import core.cache.def.impl.NPCDefinition import core.cache.def.impl.SceneryDefinition import core.cache.def.impl.VarbitDefinition @@ -19,22 +21,47 @@ import core.game.node.entity.player.info.Rights import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.game.node.scenery.Scenery +import core.game.system.command.Command import core.game.system.command.CommandMapping import core.game.system.command.Privilege import core.game.system.communication.CommunicationInfo import core.game.world.map.RegionManager +import core.game.world.repository.GE_NEWS_MUTE_ATTRIBUTE import core.game.world.map.build.DynamicRegion import core.game.world.repository.Repository +import core.game.node.entity.combat.equipment.WeaponInterface import core.plugin.Initializable import core.tools.Log import core.tools.StringUtils import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.rs09.consts.Components +import org.rs09.consts.Items import java.awt.HeadlessException import java.awt.Toolkit import java.awt.datatransfer.StringSelection +private const val INFINITE_SPECIAL_ATTRIBUTE = "infinite-special" +private const val ALLOW_ADMIN_AGGRESSION_ATTRIBUTE = "/save:allow_admin_aggression" + +private fun resolveBooleanToggle(player: Player, args: Array, attribute: String): Boolean? { + return when { + args.size < 2 -> !player.getAttribute(attribute, false) + args[1].equals("true", ignoreCase = true) -> true + args[1].equals("false", ignoreCase = true) -> false + else -> null + } +} + +private fun setBooleanAttribute(player: Player, attribute: String, enabled: Boolean, label: String) { + if (enabled) { + setAttribute(player, attribute, true) + } else { + removeAttribute(player, attribute) + } + sendMessage(player, "$label is now ${if (enabled) "enabled" else "disabled"}.") +} + @Initializable class MiscCommandSet : CommandSet(Privilege.ADMIN){ override fun defineCommands() { @@ -46,10 +73,11 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ player.toggleDebug() } - define("calc_accuracy", Privilege.STANDARD, "::calc_accuracy NPC ID", "Calculates and prints your current chance to hit a given NPC."){ player, args -> + define("calcaccuracy", Privilege.STANDARD, "::calcaccuracy NPC ID", "Calculates and prints your current chance to hit a given NPC."){ player, args -> val handler = player.getSwingHandler(false) player.sendMessage("handler type: ${handler.type}") - player.sendMessage("calculateAccuracy: ${handler.calculateAccuracy(player)}") + val accuracy = handler.calculateAccuracy(player) + player.sendMessage("calculateAccuracy: ${accuracy}") if (args.size > 1) { @@ -57,14 +85,31 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ val npc = NPC(npcId) npc.initConfig() player.sendMessage("npc: ${npc.name}. npc defence: ${npc.skills.getLevel(Skills.DEFENCE)}") - player.sendMessage("calculateDefence: ${handler.calculateDefence(npc, player)}") + val defence = handler.calculateDefence(npc, player) + player.sendMessage("calculateDefence: ${defence}") + val chance: Double = if (accuracy > defence) { + 1.0 - ((defence + 2.0) / (2.0 * (accuracy + 1.0))) + } else { + accuracy / (2.0 * (defence + 1.0)) + } + player.sendMessage("chance to hit: ${chance}") } } - define("anmacs", Privilege.ADMIN) { player, _ -> + define("anmacs", Privilege.ADMIN, description = "Starts the AnmaCutscene sequence for testing.") { player, _ -> AnmaCutscene(player).start() } + define("setsaveversion", Privilege.ADMIN, "::setsaveversion version", "Overrides your save version to version so migration logic can run.") { player, args -> + try{ + player.version = args[1].toInt() + notify(player, "Setting save version to ${player.version}") + } + catch (nfe: NumberFormatException){ + reject(player, "Save versions can only be an integer") + } + } + /** * Prints player's current location */ @@ -104,17 +149,69 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ notify(player, "Do you mean ::loc?") } - define("calcmaxhit", Privilege.STANDARD, "", "Calculates and shows you your current max hit.") { player, _ -> + define("calcmaxhit", Privilege.STANDARD, description = "Calculates and prints your current maximum hit.") { player, _ -> val swingHandler = player.getSwingHandler(false) val hit = swingHandler.calculateHit(player, player, 1.0) - notify(player, "max hit (${(swingHandler as Object).getClass().getName()}): ${hit}") + notify(player, "max hit: ${hit} (${(swingHandler as Object).getClass().getName()})") + } + + define("calcdefence", Privilege.STANDARD, "::calcdefence NPC ID", "Calculates and prints your current raw defence values for Melee, Ranged and Magic against a given NPC.") { player, args -> + val meleeHandler = core.game.node.entity.combat.MeleeSwingHandler() + val rangeHandler = core.game.node.entity.combat.RangeSwingHandler() + val magicHandler = core.game.node.entity.combat.MagicSwingHandler() + var attacker: core.game.node.entity.Entity = player + if (args.size > 1) { + val npcId = args[1].toInt() + val npc = NPC(npcId) + npc.initConfig() + attacker = npc + notify(player, "Calculating defence against NPC: ${npc.name} (ID=$npcId)") + val bonuses = npc.properties.bonuses + var maxBonus = Int.MIN_VALUE + var maxIndex = 0 + for (i in 0..4) { + if (i in bonuses.indices) { + val v = bonuses[i] + if (v > maxBonus) { + maxBonus = v + maxIndex = i + } + } + } + if (maxBonus == Int.MIN_VALUE) { + maxBonus = 0 + maxIndex = 0 + } + npc.properties.attackStyle = WeaponInterface.AttackStyle(WeaponInterface.STYLE_CONTROLLED,maxIndex) + } else { + notify(player, "Calculating defence against yourself (no NPC specified).") + } + fun hitChance(accuracy: Int, defence: Int): Double { + return if (accuracy > defence) { + 1.0 - ((defence + 2.0) / (2.0 * (accuracy + 1.0))) + } else { + accuracy / (2.0 * (defence + 1.0)) + } + } + val meleeAccuracy = meleeHandler.calculateAccuracy(attacker) + val meleeDefence = meleeHandler.calculateDefence(player, attacker) + val meleeChance = hitChance(meleeAccuracy, meleeDefence) + notify(player, "Your melee defence: $meleeDefence; Attacker accuracy: $meleeAccuracy; Chance to be hit: $meleeChance") + val rangeAccuracy = rangeHandler.calculateAccuracy(attacker) + val rangeDefence = rangeHandler.calculateDefence(player, attacker) + val rangeChance = hitChance(rangeAccuracy, rangeDefence) + notify(player, "Your range defence: $rangeDefence; Attacker accuracy: $rangeAccuracy; Chance to be hit: $rangeChance") + val magicAccuracy = magicHandler.calculateAccuracy(attacker) + val magicDefence = magicHandler.calculateDefence(player, attacker) + val magicChance = hitChance(magicAccuracy, magicDefence) + notify(player, "Your magic defence: $magicDefence; Attacker accuracy: $magicAccuracy; Chance to be hit: $magicChance") } /** * Empty a player's inventory * ADMIN only (for obvious reasons) */ - define("empty", Privilege.ADMIN, "", "Empties your inventory."){player,_-> + define("empty", Privilege.ADMIN, "", "Empties/clears your inventory."){player,_-> player.inventory.clear() player.inventory.refresh() } @@ -178,25 +275,38 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ } /** - * Shows the player a list of currently active GE sell offers + * Shows the player a list of currently active GE sell offers or toggles muting sell offer News announcements. */ - define("ge", Privilege.STANDARD, "::ge MODE (Modes: buying, selling, search, bots, botsearch)", "Various commands for viewing GE offers.") { player, args -> - if(args.size < 2){ - reject(player, "Usage: ::ge mode", "Available modes: buying, selling, search, bots, botsearch") + define( + "ge", + Privilege.STANDARD, + "::ge MODE (Modes: buying, selling, search, bots, botsearch, mute)", + "Various commands for viewing GE offers." + ) { player, args -> + if (args.size < 2) { + reject(player, "Usage: ::ge mode", "Available modes: buying, selling, search, bots, botsearch, mute") } - val mode = args[1] - when(mode){ + when (mode) { "buying" -> showGeBuy(player) "selling" -> showGeSell(player) - "search" -> sendInputDialogue(player, InputType.STRING_LONG, "Enter search term:"){value -> - showOffers(player, value as String) - } + "search" -> showGeInputDialogue(player, args, ::showOffers) "bots" -> showGeBots(player) - "botsearch" -> sendInputDialogue(player, InputType.STRING_LONG, "Enter search term:"){value -> - showGeBotsearch(player, value as String) + "botsearch" -> showGeInputDialogue(player, args, ::showGeBotsearch) + "mute" -> { + val currentlyMuted = getAttribute(player, GE_NEWS_MUTE_ATTRIBUTE, false) + if (currentlyMuted) { + removeAttribute(player, GE_NEWS_MUTE_ATTRIBUTE) + } else { + setAttribute(player, GE_NEWS_MUTE_ATTRIBUTE, true) + } + sendMessage(player, "GE sell offer news is now ${if (currentlyMuted) "visible" else "hidden"}.") } - else -> reject(player, "Invalid mode used. Available modes are: buying, selling, search") + + else -> reject( + player, + "Invalid mode used. Available modes are: buying, selling, search, bots, botsearch, mute" + ) } } /** @@ -209,11 +319,8 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ */ define("commands", Privilege.STANDARD, "::commands page", "Lists all the commands (you are here.)"){player, args -> val page = if (args.size > 1) (args[1].toIntOrNull() ?: 1) - 1 else 0 - var lineid = 11 - var pages = CommandMapping.getPageIndices(player.rights.ordinal) - var end = if (page < (pages.size - 1)) pages[page + 1] else CommandMapping.getCommands().size - - player.interfaceManager.close() + val pages = CommandMapping.getPageIndices(player.rights.ordinal) + val end = if (page < (pages.size - 1)) pages[page + 1] else CommandMapping.getCommands().size if (page < 0) { reject(player, "Usage: ::commands page") @@ -223,44 +330,106 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ reject(player, "That page number is too high, you don't have access to that many.") } - for (i in 0..310) { - player.packetDispatch.sendString("", Components.QUESTJOURNAL_SCROLL_275, i) - } + val title = "Commands" + if (pages.size > 1) " (${page + 1}/${pages.size})" else "" + var lineId = setupScrollInterface(player, title) - player.packetDispatch.sendString( - "Commands" + if (pages.size > 1) " (${page + 1}/${pages.size})" else "", - Components.QUESTJOURNAL_SCROLL_275, - 2 - ) - - for(i in pages[page] until end) { - var command = CommandMapping.getCommands()[i] - var title = "${command.name}" - var rights = command.privilege.ordinal - var icon = rights - 1 + val command = CommandMapping.getCommands()[i] + lineId = displayCommandInScroll(player, command, player.rights.ordinal, lineId) - - if (rights > player.rights.ordinal) continue - - if (rights > 0) - title = "() $title" - - player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, lineid++) - - if (command.usage.isNotEmpty()) - player.packetDispatch.sendString("Usage: ${command.usage}", Components.QUESTJOURNAL_SCROLL_275, lineid++) - - if (command.description.isNotEmpty()) - player.packetDispatch.sendString(command.description, Components.QUESTJOURNAL_SCROLL_275, lineid++) - - player.packetDispatch.sendString("-------------------------------", Components.QUESTJOURNAL_SCROLL_275, lineid++) - - if (lineid > 306) { - player.packetDispatch.sendString("To view the next page, use ::commands ${page + 2}", Components.QUESTJOURNAL_SCROLL_275, lineid) + if (lineId > 306) { + player.packetDispatch.sendString("To view the next page, use ::commands ${page + 2}", Components.QUESTJOURNAL_SCROLL_275, lineId) break } + } + player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275)) + } + /* + * Search for commands + */ + define("commandsearch", Privilege.STANDARD, "::commandsearch search term [--chat]", "Searches for commands containing the given term."){player, args -> + if (args.size < 2) { + reject(player, "Usage: ::commandsearch [--chat]") + return@define + } + val rawArguments = args.copyOfRange(1, args.size) + val chatMode = rawArguments.any { it.equals("--chat", ignoreCase = true) } + val searchRaw = rawArguments.filterNot { it.equals("--chat", ignoreCase = true) } + if (searchRaw.isEmpty()) { + reject(player, "Usage: ::commandsearch [--chat]") + return@define + } + val search = searchRaw.joinToString(" ").lowercase() + if (search.length < 2) { + reject(player, "Search term must be at least 2 characters long") + return@define + } + val playerRights = player.rights.ordinal + val allMatchingCommands = CommandMapping.getCommands() + .filter { command -> + command.name.lowercase().contains(search) || + command.usage.lowercase().contains(search) || + command.description.lowercase().contains(search) + } + if (allMatchingCommands.isEmpty()) { + notify(player, "No commands found matching '$search'") + return@define + } + val accessibleCommands = allMatchingCommands + .filter { it.privilege.ordinal <= playerRights } + .sortedBy { it.name } + val inaccessibleCount = allMatchingCommands.count { it.privilege.ordinal > playerRights } + if (chatMode) { + for (command in accessibleCommands) { + val cmdargs = if (command.usage.isNotEmpty()) { + val parts = command.usage.split(" ", limit = 2) + if (parts.size > 1) parts[1] else "" + } else { + "" + } + val formattedMessage = if (cmdargs.isNotEmpty()) { + "CMD: ${command.name} ARGS: $cmdargs DESC: ${command.description}" + } else { + "CMD: ${command.name} DESC: ${command.description}" + } + val chunks = chunkText(formattedMessage, 70) + chunks.forEach { notify(player, it) } + } + if (accessibleCommands.isEmpty()) { + notify(player, "Found $inaccessibleCount command(s) matching '$search' but you don't have permission to use any of them") + } else { + val summary = "Found ${accessibleCommands.size} accessible command(s) for '$search'" + if (inaccessibleCount > 0) { + notify(player, summary) + notify(player, "($inaccessibleCount additional command(s) require higher privileges)") + } else { + notify(player, summary) + } + } + return@define + } + var lineId = setupScrollInterface(player, "Command Search: '$search'") + if (accessibleCommands.isEmpty()) { + player.packetDispatch.sendString("No accessible commands found.", Components.QUESTJOURNAL_SCROLL_275, lineId++) + } + for (command in accessibleCommands) { + lineId = displayCommandInScroll(player, command, playerRights, lineId) + if (lineId > 306) { + player.packetDispatch.sendString( + "Results truncated. Use ::commandsearch $search --chat", + Components.QUESTJOURNAL_SCROLL_275, + lineId + ) + break + } + } + if (inaccessibleCount > 0 && lineId <= 306) { + player.packetDispatch.sendString( + "$inaccessibleCount more command(s) need higher privileges.", + Components.QUESTJOURNAL_SCROLL_275, + lineId + ) } player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275)) } @@ -292,78 +461,6 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ player.dialogueInterpreter.close() } - - /** - * Max account stats - */ - define("max", Privilege.ADMIN, "", "Gives you all 99s."){player,_ -> - var index = 0 - Skills.SKILL_NAME.forEach { - player.skills.setStaticLevel(index,99) - player.skills.setLevel(index,99) - index++ - } - player.skills.updateCombatLevel() - } - - define("noobme", Privilege.ADMIN, "", "Sets you back to default stats."){ player,_ -> - var index = 0 - Skills.SKILL_NAME.forEach { - if (index == Skills.HITPOINTS) { - player.skills.setStaticLevel(index,10) - player.skills.setLevel(index,10) - index++ - } else { - player.skills.setStaticLevel(index,1) - player.skills.setLevel(index,1) - index++ - } - } - player.skills.updateCombatLevel() - } - - /** - * Set a specific skill to a specific level - */ - define("setlevel", Privilege.ADMIN, "::setlevel SKILL NAME LEVEL PLAYER", "Sets SKILL NAME to LEVEL for PLAYER (self if omitted)."){player,args -> - if(args.size < 3) reject(player,"Usage: ::setlevel skillname level") - val skillname = args[1] - val desiredLevel: Int? = args[2].toIntOrNull() - if(desiredLevel == null){ - reject(player, "Level must be an integer.") - } - if(desiredLevel!! > 99) reject(player,"Level must be 99 or lower.") - val skill = Skills.getSkillByName(skillname) - if(skill < 0) reject(player, "Must use a valid skill name!") - var target = player - if (args.size > 3) { - val n = args.slice(3 until args.size).joinToString("_") - val foundtarget = Repository.getPlayerByName(n) - if (foundtarget == null) { - reject(player,"Invalid player \"${n}\" or player not online") - } - target = foundtarget!! - } - target.skills.setStaticLevel(skill,desiredLevel) - target.skills.setLevel(skill,desiredLevel) - target.skills.updateCombatLevel() - } - - /** - * Add xp to skill - */ - define("addxp", Privilege.ADMIN, "::addxp skill name | id xp", "Add xp to skill") { player, args -> - if (args.size != 3) reject(player, "Usage: ::addxp skill name | id xp") - - val skill = args[1].toIntOrNull() ?: Skills.getSkillByName(args[1]) - if (skill < 0 || skill >= Skills.NUM_SKILLS) reject(player, "Must use valid skill name or id.") - - val xp = args[2].toDoubleOrNull() - if (xp == null || xp <= 0) reject(player, "Xp must be a positive number.") - - player.skills.addExperience(skill, xp!!) - } - define("completediaries", Privilege.ADMIN, "", "Completes all diaries."){player,_ -> player.achievementDiaryManager.diarys.forEach { for(level in it.taskCompleted.indices){ @@ -390,7 +487,7 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ permadeath(target) } - define("log", Privilege.ADMIN){player,_ -> + define("log", Privilege.ADMIN, description = "Adds your current coordinates to the location log buffer."){player,_ -> var log: ArrayList? = player.getAttribute("loc-log") log = log ?: ArrayList() val locString = "{${player.location.x},${player.location.y},${player.location.z},1,0}" @@ -398,7 +495,7 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ player.setAttribute("loc-log",log) } - define("logdone"){player,_ -> + define("logdone", description = "Copies the queued location log to your clipboard and clears it."){player,_ -> val log: ArrayList? = player.getAttribute("loc-log") log ?: return@define @@ -427,18 +524,18 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ TrawlerLoot.addLootAndMessage(player, player.skills.getLevel(Skills.FISHING), rolls, false) } - define("fillbank", Privilege.ADMIN, "", "Right as it says on the tin."){player,_ -> + define("fillbank", Privilege.ADMIN, description = "Fills your bank with sequential item IDs."){player,_ -> for(i in 0 until ServerConstants.BANK_SIZE){ player.bank.add(Item(i)) } } - define("emptybank", Privilege.ADMIN, "", "Right as it says on the tin."){player,_ -> + define("emptybank", Privilege.ADMIN, description = "Clears your bank contents."){player,_ -> player.bank.clear() player.bank.update() } - define("setconfig", Privilege.ADMIN, "", "DEPRECATED: Use setvarp or setvarbit."){player,args -> + define("setconfig", Privilege.ADMIN, "::setconfig config-id value", "DEPRECATED: use ::setvarp or ::setvarbit. Sets the raw varp config-id to value."){player,args -> if(args.size < 3){ reject(player,"Syntax: ::setconfig configID value") } @@ -447,7 +544,7 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ setVarp(player, configID, configValue) } - define("getobjectvarp"){player,args -> + define("getobjectvarp", usage = "::getobjectvarp object-id", description = "Looks up which varp controls the state of object-id."){player,args -> if(args.size < 2){ reject(player,"Syntax: ::getobjectvarp objectid") } @@ -455,7 +552,7 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ notify(player, "${VarbitDefinition.forObjectID(SceneryDefinition.forId(objectID).varbitID).varpId}") } - define("define_varbit", Privilege.ADMIN, "::define_varbit VARBIT ID", "Prints information about the given varbit."){ player, args -> + define("define_varbit", Privilege.ADMIN, "::define_varbit ", "Prints detailed information about ."){ player, args -> if(args.size < 2) { reject(player, "Syntax: ::define_varbit varbitId") } @@ -464,25 +561,39 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ } - define("setvarbit", Privilege.ADMIN, "::setvarbit VARBIT ID VALUE", ""){ + define("setvarbit", Privilege.ADMIN, "::setvarbit varbit-id value", "Sets varbit-id to value for your player."){ player,args -> if(args.size != 3){ - reject(player,"Usage: ::setvarbit varbit value") + reject(player,"Usage: ::setvarbit ") } val index = args[1].toIntOrNull() val value = args[2].toIntOrNull() if(index == null || value == null){ - reject(player,"Usage ::setvarbit index offset value") + reject(player,"Usage ::setvarbit ") } setVarbit(player, index!!, value!!) } - define("getvarbit", Privilege.ADMIN, "::getvarbit VARBIT ID", "") { + define("setvarbits", Privilege.ADMIN, "::setvarbits FROM VARBIT ID TO VARBIT ID VALUE", ""){ + player,args -> + if(args.size != 4){ + reject(player,"Usage: ::setvarbits ") + } + val fromIndex = args[1].toIntOrNull()!! + val toIndex = args[2].toIntOrNull()!! + val value = args[3].toIntOrNull()!! + + for (index in fromIndex..toIndex) { + setVarbit(player, index, value) + } + } + + define("getvarbit", Privilege.ADMIN, "::getvarbit VARBIT ID", "Prints the current value of VARBIT ID.") { player, args -> if (args.size != 2) - reject(player, "Usage: ::getvarbit id") + reject(player, "Usage: ::getvarbit ") val index = args[1].toIntOrNull() ?: return@define notify(player, "Varbit $index: Currently ${getVarbit(player, index)}") } @@ -528,13 +639,31 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ } define("finishbins", Privilege.ADMIN, "", "Finishes any in-progress compost bins."){ player, _ -> + val bins = getOrStartTimer(player).getBins() + for (bin in bins) { + if (!bin.isFinished && bin.isClosed) bin.finish() + } } - define("addcredits", Privilege.ADMIN){ player, _ -> + define("resetbins", Privilege.ADMIN, "", "Resets the player's compost bins to their initial states."){ player, _ -> + val bins = getOrStartTimer(player).getBins() + for (bin in bins) bin.reset() + } + + define("diseasecrops", Privilege.ADMIN, "", "Disease all crops"){ player, _ -> + val state = getOrStartTimer(player) + for (patch in state.getPatches()){ + patch.diseaseMod = -128 + patch.nextGrowth = System.currentTimeMillis() + 1 + } + state.run(player) + } + + define("addcredits", Privilege.ADMIN, description = "Adds 100 ::shop credits to your account."){ player, _ -> player.details.credits += 100 } - define("getnpcparent"){player,args -> + define("getnpcparent", usage = "::getnpcparent npc-id", description = "Finds the parent NPC whose child list includes npc-id."){player,args -> if(args.size < 2){ reject(player,"Usage: ::getnpcparent npcid") } @@ -555,29 +684,49 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ notify(player,"No parent NPC found.") } } - define("infinitespecial", Privilege.ADMIN){ player, args -> - val usageStr = "Usage: ::infinitespecial true|false" - if(args.size < 2){ - reject(player, usageStr) - } - when(args[1]){ - "true" -> player.setAttribute("infinite-special", true) - "false" -> player.removeAttribute("infinite-special") - else -> reject(player, usageStr) - } - } - define("allowaggro", Privilege.ADMIN, "allowaggro true | false", "Toggle NPCs aggroing on you") { player, args -> - val usageStr = "Usage: ::allowaggro true | false" - if(args.size < 2) { - notify(player, "Allow admin aggression is currently ${player.getAttribute("/save:allow_admin_aggression", false)}") + define( + "infinitespecial", + Privilege.ADMIN, + "::infinitespecial [true|false]", + "Toggles infinite special attack energy for your player (special-attack flag)." + ) { player, args -> + val enabled = resolveBooleanToggle(player, args, INFINITE_SPECIAL_ATTRIBUTE) + if (enabled == null) { + reject(player, "Usage: ::infinitespecial [true|false]") return@define } - when(args[1]) { - "true" -> player.setAttribute("/save:allow_admin_aggression", true) - "false" -> player.setAttribute("/save:allow_admin_aggression", false) - else -> reject(player, usageStr) + setBooleanAttribute(player, INFINITE_SPECIAL_ATTRIBUTE, enabled, "Infinite special attack") + } + define( + "infinitespecialmove", + Privilege.ADMIN, + "::infinitespecialmove [true|false]", + "Toggles infinite Summoning familiar special move points for your player." + ) { player, args -> + val enabled = resolveBooleanToggle(player, args, Familiar.INFINITE_SPECIAL_MOVE_ATTRIBUTE) + if (enabled == null) { + reject(player, "Usage: ::infinitespecialmove [true|false]") + return@define } - notify(player, "Setting aggro ${args[1]}") + setBooleanAttribute( + player, + Familiar.INFINITE_SPECIAL_MOVE_ATTRIBUTE, + enabled, + "Infinite familiar special move energy" + ) + } + define( + "allowaggro", + Privilege.ADMIN, + "::allowaggro [true|false]", + "Toggles NPCs aggroing on you as an admin." + ) { player, args -> + val enabled = resolveBooleanToggle(player, args, ALLOW_ADMIN_AGGRESSION_ATTRIBUTE) + if (enabled == null) { + reject(player, "Usage: ::allowaggro [true|false]") + return@define + } + setBooleanAttribute(player, ALLOW_ADMIN_AGGRESSION_ATTRIBUTE, enabled, "Admin NPC aggression") } define("rules", Privilege.STANDARD, "", "Shows the rules."){ player, _ -> @@ -606,6 +755,187 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ sendDialogue(player, "Wrong pin. Try again.") } } + + define("setplayerstrong", Privilege.ADMIN, "setplayerstrong 0-4", + "Set the player progress through the Stronghold of Player Safety test."){player, args -> + /* + * 0 = Not started + * 1 = Received test + * 2 = Completed test, needs to be marked + * 3 = Test marked + * 4 = Dungeon cleared + */ + if(args.size < 2){ + notify(player, "Player Stronghold progression currently: ${player.savedData.globalData.testStage}") + return@define + } + val stage = args[1].toIntOrNull() ?: (-1).also { reject(player, "Please enter a valid number") } + if (stage in 0 .. 4){ + player.savedData.globalData.testStage = stage + notify(player, "Setting test stage to $stage") + if (stage in 0..2){ + setVarp(player, 1203, 0, true) + notify(player, "The poster passage is now hidden") + } + else{ + setVarp(player, 1203, 1 shl 29, true) + notify(player, "The poster passage is now usable") + } + if (stage == 4){ + setVarbit(player, 4499, 1,true) + notify(player, "The loot has been taken already") + } + else { + setVarbit(player, 4499, 0, true) + notify(player, "The loot can be reacquired") + } + } + else{ + reject(player, "Only stages 0-4 are valid") + } + } + + define("setplaqueread", Privilege.ADMIN, "setplaqueread true/false", + "Set the plaques in the player safety stronghold to read or not read."){player, args -> + if (args.size == 1) { + notify( + player, + "Currently the plaques ${if (player.savedData.globalData.hasReadPlaques()) "have" else "have not"} been read" + ) + return@define + } + when(args[1]) { + "true" -> setPlaqueReadStatus(player, true) + "false" -> setPlaqueReadStatus(player, false) + else -> reject(player, "Only true or false can be used") + + } + notify(player, "Setting plaques read to: ${args[1]}") + + } + define("brewkit", Privilege.ADMIN, "brewkit 0-10", + "Give yourself everything you need to brew ales."){ player, args -> + if (args.size == 1) { + sendMessage(player, "Kit numbers: 0 - Dwarven Stout, 1 - Asgarnian Ale, 2 - Greenman's Ale,") + sendMessage(player, "Kit numbers: 3 - Wizard's Mind Bomb, 4 - Dragon Bitter, 5 - Moonlight Mead,") + sendMessage(player, "Kit numbers: 6 - Axeman's Folly, 7 - Chef's Delight, 8 - Slayer's Respite,") + sendMessage(player, "Kit numbers: 9 - Cider, 10 - Kelda Stout") + return@define + } + val item = + when (args[1].toInt()) { + 0 -> Items.HAMMERSTONE_HOPS_5994 + 1 -> Items.ASGARNIAN_HOPS_5996 + 2 -> Items.CLEAN_HARRALANDER_255 + 3 -> Items.YANILLIAN_HOPS_5998 + 4 -> Items.KRANDORIAN_HOPS_6000 + 5 -> Items.MUSHROOM_6004 + 6 -> Items.OAK_ROOTS_6043 + 7 -> Items.CHOCOLATE_DUST_1975 + 8 -> Items.WILDBLOOD_HOPS_6002 + 9 -> Items.APPLE_MUSH_5992 + 10 -> Items.KELDA_HOPS_6113 + else -> { + reject(player, "Invalid brew kit specified.") + return@define + } + } + addItemOrDrop(player, Items.BUCKET_OF_WATER_1929, if(args[1].toInt() == 9) 0 else 2) + addItemOrDrop(player, Items.BARLEY_MALT_6008, if(args[1].toInt() == 9) 0 else 2) + addItemOrDrop(player, item, if(args[1].toInt() == 6 || args[1].toInt() == 10) 1 else 4) + addItemOrDrop(player, Items.ALE_YEAST_5767) + return@define + } + + define("brew", Privilege.ADMIN, "brew mode", + "0: force natural step, 1: force good step without maturity, 2: force good step with maturity, 3: force bad step"){ player, args -> + var forceStep = false + var forceGood = false + var forceMature = false + var forceBad = false + if (args.size == 1){ + forceStep = true + } + if (args.size != 1){ + when(args[1].toIntOrNull()){ + 0 -> forceStep = true + 1 -> forceGood = true + 2 -> forceMature = true + 3 -> forceBad = true + else -> reject(player, "${args[1]} is not a valid option.") + } + } + + val vats = getOrStartTimer(player).getVats() + for (vat in vats){ + vat.brew(forceStep, forceGood, forceMature, forceBad) + } + } + } + + fun setupScrollInterface(player: Player, title: String): Int { + player.interfaceManager.close() + for (i in 0..310) { + player.packetDispatch.sendString("", Components.QUESTJOURNAL_SCROLL_275, i) + } + player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, 2) + return 11 + } + + fun displayCommandInScroll(player: Player, command: Command, playerRights: Int, lineId: Int): Int { + val privilegeLevel = command.privilege.ordinal + if (privilegeLevel > playerRights) return lineId + val titleIcon = privilegeLevel - 1 + var title = command.name + if (privilegeLevel > 0) { + title = "() $title" + } + var currentLineId = lineId + player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, currentLineId++) + if (command.usage.isNotEmpty()) { + val usageText = "Usage: ${command.usage}" + val usageChunks = chunkText(usageText, 70) + for (chunk in usageChunks) { + player.packetDispatch.sendString(chunk, Components.QUESTJOURNAL_SCROLL_275, currentLineId++) + } + } + if (command.description.isNotEmpty()) { + val descChunks = chunkText(command.description, 70) + for (chunk in descChunks) { + player.packetDispatch.sendString(chunk, Components.QUESTJOURNAL_SCROLL_275, currentLineId++) + } + } + player.packetDispatch.sendString("-------------------------------", Components.QUESTJOURNAL_SCROLL_275, currentLineId++) + return currentLineId + } + + fun chunkText(text: String, maxLength: Int = 70): List { + if (text.length <= maxLength) return listOf(text) + val chunks = mutableListOf() + var remaining = text + while (remaining.length > maxLength) { + var breakPoint = maxLength + for (i in maxLength downTo 1) { + if (remaining[i - 1] == ' ') { + breakPoint = i + break + } + } + chunks.add(remaining.take(breakPoint).trim()) + remaining = remaining.substring(breakPoint).trim() + } + if (remaining.isNotEmpty()) { + chunks.add(remaining) + } + return chunks + } + + fun setPlaqueReadStatus(player: Player, status: Boolean){ + // For some reason the loop has to be this way to have read write access + for (i in 0 until player.savedData.globalData.readPlaques.size){ + player.savedData.globalData.readPlaques[i] = status + } + } fun showGeBotsearch(player: Player, searchTerm: String) @@ -621,19 +951,14 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ offerPrice[offer.itemID] = offer.offeredValue } - val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) - var lineId = 11 - - closeInterface(player) - setScrollTitle(player, "Bot Stock - \"$searchTerm\"") - for(i in 0..299) { - val offer = entries.elementAtOrNull(i) - if (offer != null) - setInterfaceText(player, "${getItemName(offer.key)} (x${offer.value}) -> Price: ${offerPrice[offer.key]}gp", Components.QUESTJOURNAL_SCROLL_275, lineId++) - else - setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Price: ${offerPrice[entry.key]}gp") } - openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + showGeBook(player, "Bot Stock - \"$searchTerm\"", leftLines, rightLines) } fun showGeBots(player: Player) @@ -649,19 +974,14 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ offerPrice[offer.itemID] = offer.offeredValue } - val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) - var lineId = 11 - - closeInterface(player) - setScrollTitle(player, "Bot Stock") - for(i in 0..299) { - val offer = entries.elementAtOrNull(i) - if (offer != null) - setInterfaceText(player, "${getItemName(offer.key)} (x${offer.value}) -> Price: ${offerPrice[offer.key]}gp", Components.QUESTJOURNAL_SCROLL_275, lineId++) - else - setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Price: ${offerPrice[entry.key]}gp") } - openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + showGeBook(player, "Bot Stock", leftLines, rightLines) } fun showGeSell(player: Player){ @@ -683,19 +1003,14 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ lowestPrice[offer.itemID] = price } - val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) - var lineId = 11 - - closeInterface(player) - setScrollTitle(player, "Active Sell Offers") - for(i in 0..299) { - val offer = entries.elementAtOrNull(i) - if (offer != null) - setInterfaceText(player, "${getItemName(offer.key)} (x${offer.value}) -> Lowest: ${lowestPrice[offer.key]}gp", Components.QUESTJOURNAL_SCROLL_275, lineId++) - else - setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Price: ${lowestPrice[entry.key]}gp") } - openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + showGeBook(player, "Active Sell Offers", leftLines, rightLines) } fun showGeBuy(player: Player){ @@ -717,28 +1032,27 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ highestPrice[offer.itemID] = price } - val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) - var lineId = 11 - - closeInterface(player) - setScrollTitle(player, "Active Buy Offers") - for(i in 0..299) { - val offer = entries.elementAtOrNull(i) - if (offer != null) - setInterfaceText(player, "${getItemName(offer.key)} (x${offer.value}) -> Highest: ${highestPrice[offer.key]}gp", Components.QUESTJOURNAL_SCROLL_275, lineId++) - else - setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Highest: ${highestPrice[entry.key]}gp") } - openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + showGeBook(player, "Active Buy Offers", leftLines, rightLines) } fun showOffers(player: Player, searchTerm: String){ val offers = GrandExchange.getValidOffers().filter { getItemName(it.itemID).contains(searchTerm, true) || getItemName(it.itemID).equals(searchTerm, true) } - val buyingAmount = HashMap() + if (offers.isEmpty()) { + sendMessage(player, "No results.") + return + } + + val buyingAmount = HashMap() val buyingHighest = HashMap() val sellingAmount = HashMap() val sellingLowest = HashMap() - for(offer in offers) { if(offer.sell) @@ -765,39 +1079,64 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ } } - closeInterface(player) - setScrollTitle(player, "Results for \"$searchTerm\"") - - var lineId = 11 - for(i in 0..299) { - if(i > buyingAmount.keys.size) - { - val offer = sellingAmount.entries.elementAtOrNull(i - buyingAmount.keys.size) - if(offer != null) { - setInterfaceText(player, "[SELLING] ${getItemName(offer.key)} (x${offer.value}) -> Lowest: ${sellingLowest[offer.key]}gp", Components.QUESTJOURNAL_SCROLL_275, lineId++) - continue - } + val numLines = offers.size + 1 + val leftLines = ArrayList(numLines) + val rightLines = ArrayList(numLines) + for (i in 0..numLines) { + if (i < buyingAmount.keys.size) { + val offer = buyingAmount.entries.elementAtOrNull(i) ?: continue + leftLines.add("[BUYING] ${getItemName(offer.key)} (x${offer.value})") + rightLines.add("Highest: ${buyingHighest[offer.key]}gp") + } else if (i == buyingAmount.keys.size) { + leftLines.add("") + rightLines.add("") + } else { + val offer = sellingAmount.entries.elementAtOrNull(i - buyingAmount.keys.size - 1) ?: continue + leftLines.add("[SELLING] ${getItemName(offer.key)} (x${offer.value})") + rightLines.add("Lowest: ${sellingLowest[offer.key]}gp") } - else if(i < buyingAmount.keys.size) - { - val offer = buyingAmount.entries.elementAtOrNull(i) - if(offer != null) { - setInterfaceText(player, "[BUYING] ${getItemName(offer.key)} (x${offer.value}) -> Highest: ${buyingHighest[offer.key]}gp", Components.QUESTJOURNAL_SCROLL_275, lineId++) - continue - } - } - else { - setInterfaceText(player, " ", Components.QUESTJOURNAL_SCROLL_275, lineId++) - continue - } - - setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) } - openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + showGeBook(player, "Results for \"$searchTerm\"", leftLines, rightLines) } - fun setScrollTitle(player: Player, text: String){ - setInterfaceText(player, text, Components.QUESTJOURNAL_SCROLL_275, 2) + private fun showGeInputDialogue(player: Player, args: Array, op: (Player, String) -> (Unit)) { + if (args.size > 2) { + val target = args.copyOfRange(2, args.size).joinToString(" ").lowercase() + op(player, target) + } else { + sendInputDialogue(player, InputType.STRING_LONG, "Enter search term:",) { value -> + op(player, value as String) + } + } } + private fun showGeBook(player: Player, title: String, leftLines: ArrayList, rightLines: ArrayList) { + if (leftLines.size == 0) { + sendMessage(player, "No results.") + return + } + val lineIds = BookInterface.FANCY_BOOK_26_LINE_IDS + val contents = ArrayList() + val leftChunks = leftLines.chunked(15) + val rightChunks = rightLines.chunked(15) + for (i in leftChunks.indices) { + val size = leftChunks[i].size + val leftPageLines = ArrayList(size) + val rightPageLines = ArrayList(size) + for (j in leftChunks[i].indices) { + leftPageLines.add(BookLine(leftChunks[i][j], lineIds[j+3])) //+3 to skip title and buttons + rightPageLines.add(BookLine(rightChunks[i][j], lineIds[j+3+15])) //+15 because right pages have different ids + } + val leftPage = Page(*leftPageLines.toTypedArray()) + val rightPage = Page(*rightPageLines.toTypedArray()) + contents.add(PageSet(leftPage, rightPage)) + } + + closeInterface(player) + fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_26, title, contents.toTypedArray()) + return true + } + BookInterface.openBook(player, BookInterface.FANCY_BOOK_26, ::display) + } } diff --git a/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt b/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt index 0d9074356..f5b22a4dd 100644 --- a/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt @@ -84,7 +84,7 @@ class ModelViewerCommandSet : CommandSet(Privilege.ADMIN) { } } override fun defineCommands() { - define("models"){ player, args -> + define("models", description = "Opens the in-game model viewer toolkit."){ player, args -> // Bad number of args if(args.size > 2){ @@ -96,4 +96,4 @@ class ModelViewerCommandSet : CommandSet(Privilege.ADMIN) { return@define } } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt b/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt index 13d0d9e79..8fd7550ef 100644 --- a/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt @@ -37,7 +37,7 @@ class ModerationCommandSet : CommandSet(Privilege.MODERATOR){ * Kick a player * ============================================================================================================= */ - define("kick", Privilege.MODERATOR){ player, args -> + define("kick", Privilege.MODERATOR, "::kick ", "Disconnects the specified player from the game."){ player, args -> val playerToKick: Player? = Repository.getPlayerByName(args[1]) if (playerToKick != null) { playerToKick.clear() diff --git a/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt b/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt index fa25eb4b5..e168c7a1e 100644 --- a/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt @@ -18,7 +18,7 @@ class PlayerAttributeCommandSet : CommandSet(Privilege.ADMIN) { /** * Gets the value of an attribute on a player. */ - define("getattribute") { player, args -> + define("getattribute", usage = "::getattribute [player] attribute", description = "Prints the value of the chosen attribute on you or another player. Omit [player] to use on self.") { player, args -> if (args.size < 2) { reject(player, "Usage ::getattribute [playername] attributename") } @@ -48,7 +48,7 @@ class PlayerAttributeCommandSet : CommandSet(Privilege.ADMIN) { /** * Sets the value of an attribute on a player. */ - define("setattribute") { player, args -> + define("setattribute", usage = "::setattribute [player] attribute value", description = "Sets a simple attribute on you or another player.") { player, args -> if (args.size < 2) { reject(player, "Usage ::setattribute [playername] attributename value") } diff --git a/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt b/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt index 6c7bc19c6..c8c414c38 100644 --- a/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt @@ -1,11 +1,13 @@ package core.game.system.command.sets +import core.api.log import core.game.component.Component import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.QuestRepository import core.plugin.Initializable import core.game.system.command.Privilege import core.game.world.repository.Repository +import core.tools.Log @Initializable class QuestCommandSet : CommandSet(Privilege.ADMIN){ @@ -13,53 +15,81 @@ class QuestCommandSet : CommandSet(Privilege.ADMIN){ /** * Completes all quests */ - define("allquest"){player,_-> + define("allquest", description = "Instantly completes every quest for your account."){player,_-> for (quest in QuestRepository.getQuests().values) { - quest.finish(player) + try { + quest.finish(player) + } catch (e: Exception){ + e.message?.let { log(this.javaClass, Log.WARN, it) } + continue + } } } /** * Displays the currently implemented quests with debug information */ - define("quest"){player,args -> - if (args.size < 3) { - val lookupP = if (args.size == 1) { - player - } else if (Repository.getPlayerByName(args[1]) != null) { - Repository.getPlayerByName(args[1]) ?: return@define + define("quest", + usage = "::quest [-p username] [quest-filter]", + description = "Shows quest stages for you, or for [username] if -p is used. Add optional text to filter by quest name." + ) { player, args -> + + var target = player + var filter: String? = null + + if (args.size > 1) { + if (args[1].equals("-p", ignoreCase = true)) { + // need at least 3 arguments if -p is used: command, -p, username + if (args.size < 3) { + reject(player, "ERROR: Missing player name. Usage: ::quest -p [quest-filter]") + return@define + } + + val playerName = args[2] + target = Repository.getPlayerByName(playerName) ?: run { + reject(player, "ERROR: Username '$playerName' not found.") + return@define + } + + // arguments after the player name are the quest filter + if (args.size > 3) { + filter = args.drop(3).joinToString(" ") + } } else { - reject(player, "ERROR: Username not found. Usage: ::quest ") - return@define + // no -p, so the arguments are the quest filter + filter = args.drop(1).joinToString(" ") } - sendQuestsDebug(player, lookupP) - } else { - reject(player, "Usage: ::quest || ::quest ") } + sendQuestsDebug(player, target, filter) } /** * Sets stage of quest */ - define("setqueststage"){player,args -> - if (args.size < 2) { + define("setqueststage", usage = "::setqueststage quest-index stage", description = "Sets quest quest-index to stage stage; use ::quest to find indices."){player,args -> + if (args.size < 3) { reject(player,"You must specify the index# of a quest, and a stage number") } val quest = args[1].toIntOrNull() ?: reject(player,"INVALID QUEST") val stage = args[2].toIntOrNull() ?: reject(player,"INVALID STAGE") val questObject = player.questRepository.forIndex(quest as Int) - player.questRepository.setStageNonmonotonic(questObject, stage as Int) - if (stage == 0){ - questObject.reset(player) + if (questObject == null){ + reject(player, "$quest did not match anything in the quest repository") + } + else{ + player.questRepository.setStageNonmonotonic(questObject, stage as Int) + if (stage == 0) { + questObject.reset(player) + } + questObject.updateVarps(player) + notify(player, "Setting " + questObject.quest + " to stage $stage") } - questObject.updateVarps(player) - notify(player, "Setting " + questObject.name + " to stage $stage") } /** * Displays the currently implemented quests */ - define("quests", Privilege.STANDARD){ player, _ -> + define("quests", Privilege.STANDARD, description = "Opens the quests interface listing current implementations."){ player, _ -> sendQuests(player) } } @@ -77,31 +107,56 @@ class QuestCommandSet : CommandSet(Privilege.ADMIN){ player.packetDispatch.sendString("" + "Available Quests" + "", 275, 2) for (q in QuestRepository.getQuests().toSortedMap().values) { // Add a space to beginning and end of string for the strikethrough - player.packetDispatch.sendString("" + (if (q.isCompleted(player)) " " else "") + q.name + " ", 275, lineId++) + player.packetDispatch.sendString("" + (if (q.isCompleted(player)) " " else "") + q.quest + " ", 275, lineId++) } } /** * Sends the list of quests with debug information * @param admin the player. + * @param lookupUser the target player to view quests for. + * @param questFilter optional string to filter quests by name. */ - private fun sendQuestsDebug(admin: Player?, lookupUser: Player?) { + private fun sendQuestsDebug(admin: Player?, lookupUser: Player?, questFilter: String? = null) { admin!!.interfaceManager.open(Component(275)) + + // clear interface lines for (i in 0..310) { admin.packetDispatch.sendString("", 275, i) } + var lineId = 11 + + // title admin.packetDispatch.sendString("${lookupUser!!.username}'s Quest Debug", 275, 2) - for (q in QuestRepository.getQuests().values) { - // Add a space to beginning and end of string for the strikethrough + + // filtered quests + val questsToDisplay = QuestRepository.getQuests().values.filter { q -> + questFilter.isNullOrBlank() || q.quest.toString().contains(questFilter, ignoreCase = true) + } + + // no quests to filter + if (questsToDisplay.isEmpty()) { + admin.packetDispatch.sendString("No quests found matching: $questFilter", 275, lineId++) + return + } + + for (q in questsToDisplay) { + // can't display more than 308 lines + if (lineId >= 308) { + admin.packetDispatch.sendString("List truncated (too many results).", 275, lineId) + break + } + val stage = lookupUser.questRepository.getStage(q) val statusColor = when { stage >= 100 -> "80ff00" stage in 1..99 -> "ff8400" else -> "ff0000" } - admin.packetDispatch.sendString("${q.name}", 275, lineId++) - admin.packetDispatch.sendString("Index: ${q.index} | Stage: ${lookupUser.questRepository.getStage(q)}", 275, lineId++) + + admin.packetDispatch.sendString("${q.quest}", 275, lineId++) + admin.packetDispatch.sendString("Index: ${q.index} | Stage: ${stage}", 275, lineId++) admin.packetDispatch.sendString(" ", 275, lineId++) } } diff --git a/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt b/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt index 62e952d5b..0f2e32426 100644 --- a/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt @@ -15,7 +15,7 @@ class SlayerCommandSet : CommandSet(Privilege.ADMIN){ /** * Finishes a player's slayer task (the correct way) */ - define("finishtask"){player,_ -> + define("finishtask", description = "Spawns a finisher NPC so your current Slayer task ends instantly."){player,_ -> notify(player, "Kill the npc that spawned to finish your task.") SlayerManager.getInstance(player).amount = 1 val finisher = NPC(SlayerManager.getInstance(player).task?.npcs?.get(0) ?: 0, player.location) @@ -26,7 +26,7 @@ class SlayerCommandSet : CommandSet(Privilege.ADMIN){ /** * Set slayer points */ - define("setslayerpoints"){player,args -> + define("setslayerpoints", usage = "::setslayerpoints amount", description = "Sets your Slayer points total to amount."){player,args -> if(args.size < 2){ reject(player,"Usage: ::setslayerpoints amount") } @@ -45,11 +45,12 @@ class SlayerCommandSet : CommandSet(Privilege.ADMIN){ val npc = (args[1].toIntOrNull() ?: reject(player, "Must enter valid npc id")) as Int val task = (Tasks.forId(npc) ?: reject(player, "Must enter valid npc id")) as Tasks + val masterTask = Master.Task(task, 1) val amount = args.getOrNull(2)?.toIntOrNull() ?.let { if (it !in 1..255) reject(player, "Amount must be an integer: 1-255.") else it } as Int? val slayer = SlayerManager.getInstance(player) - if (slayer.hasTask()) slayer.task = task else SlayerUtils.assign(player, task, Master.values().random()) + if (slayer.hasTask()) slayer.task = task else SlayerUtils.assign(player, masterTask, Master.values().random()) if (amount != null) slayer.amount = amount setVarp(player, 2502, slayer.flags.taskFlags shr 4) } diff --git a/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt b/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt index 4189fb575..468bdaf96 100644 --- a/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt @@ -1,12 +1,12 @@ package core.game.system.command.sets import core.api.log +import core.api.sendMessage import core.cache.Cache import core.game.node.scenery.Scenery import core.game.node.scenery.SceneryBuilder import core.game.node.entity.npc.NPC import core.game.node.item.Item -import core.tools.SystemLogger import core.game.system.command.CommandPlugin import core.plugin.Initializable import core.game.system.command.Privilege @@ -20,27 +20,48 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){ /** * Spawns an npc with the given ID */ - define("npc"){player,args -> + define("npc", usage = "::npc npc-id [amount] [iswalks]", description = "Spawns one or more NPCs at your location, optionally letting them walk."){player,args -> if (args.size < 2) { - reject(player,"syntax error: id (optional) direction") + reject(player, "syntax: id (required) amount (optional) isWalks (optional)") return@define } - val npc = NPC.create(CommandPlugin.toInteger(args[1]!!), player!!.location) - npc.setAttribute("spawned:npc", true) - npc.isRespawn = false - npc.direction = player.direction - npc.init() - npc.isWalks = args.size > 2 - val npcString = "{" + npc.location.x + "," + npc.location.y + "," + npc.location.z + "," + (if (npc.isWalks) "1" else "0") + "," + npc.direction.ordinal + "}" + val amount = if (args.size > 2) CommandPlugin.toInteger(args[2]) else 1 + if (amount < 1) { + reject(player, "Invalid amount") + return@define + } + if (amount > 900) { + reject(player, "Based on experience, spawning that many NPCs at once is a bad idea") + return@define + } + var isWalks = false + if (args.size > 3) { + if (args[3] == "true") { + isWalks = true + } else if (args[3] != "" && args[3] != "false") { + reject(player, "The \"isWalks\" argument only accepts \"true\" and \"false\"") + return@define + } + } + var npcString = "" + for (i in 1..amount) { + val npc = NPC.create(CommandPlugin.toInteger(args[1]), player.location) + npc.setAttribute("spawned:npc", true) + npc.isRespawn = false + npc.direction = player.direction + npc.init() + npc.isWalks = isWalks + npcString = "{" + npc.location.x + "," + npc.location.y + "," + npc.location.z + "," + (if (npc.isWalks) "1" else "0") + "," + npc.direction.ordinal + "}" + println(npcString) + } val clpbrd = Toolkit.getDefaultToolkit().systemClipboard clpbrd.setContents(StringSelection(npcString), null) - println(npcString) } /** * Spawns an item with the given ID */ - define("item"){player,args -> + define("item", usage = "::item item-id [amount]", description = "Spawns the specified item stack into your inventory."){player,args -> if (args.size < 2) { reject(player,"You must specify an item ID") return@define @@ -60,10 +81,37 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){ player.inventory.add(item) } + + /** + * Spawns multiple items with the given ID + */ + define("items", usage = "::items start-id end-id [amount]", description = "Loops through item ids from 'start-id' to 'end-id' and spawns 'amount' of them in your inventory."){player,args -> + if (args.size < 3) { + reject(player,"You must specify start and end item ids.") + return@define + } + val start = args[1].toIntOrNull() ?: return@define + val end = args[2].toIntOrNull() ?: return@define + var amount = (args.getOrNull(3) ?: "1").toInt() + for (id in start..end) { + if (id > Cache.getItemDefinitionsSize()) { + reject(player,"Item ID '$id' out of range.") + return@define + } + val item = Item(id, amount) + val max = player.inventory.getMaximumAdd(item) + if (amount > max) { + amount = max + } + item.setAmount(amount) + player.inventory.add(item) + } + } + /** * Spawn object with given ID at the player's location */ - define("object"){player,args -> + define("object", usage = "::object object-id [type] [rotation]", description = "Spawns an object at your tile with optional type and rotation."){player,args -> if (args!!.size < 2) { reject(player,"syntax error: id (optional) type rotation or rotation") return@define @@ -73,7 +121,7 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){ log(this::class.java, Log.FINE, "object = $`object`") } - define("objectgrid") { player, args -> + define("objectgrid", usage = "::objectgrid start-id end-id type rotation", description = "Spawns a 10-wide grid cycling through the given object id range.") { player, args -> if(args!!.size != 5) { reject(player, "Usage: objectgrid beginId endId type rotation") return@define diff --git a/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt b/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt index f39d94ee6..431cb84be 100644 --- a/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt +++ b/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt @@ -7,6 +7,8 @@ const val STATS_LOGS = "logs_chopped" const val STATS_FISH = "fish_caught" const val STATS_ROCKS = "rocks_mined" const val STATS_RC = "essence_crafted" +const val STATS_FOOD_COOKED = "food_cooked" +const val STATS_CATS_RAISED = "cats_raised" const val STATS_PK_KILLS = "player_kills" const val STATS_PK_DEATHS = "player_deaths" const val STATS_ALKHARID_GATE = "alkharid_gate" diff --git a/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt b/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt index 33ff9a4bc..ad8cf75da 100644 --- a/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt @@ -11,7 +11,7 @@ import core.game.node.entity.player.Player import core.plugin.Initializable import org.rs09.consts.Items import org.rs09.consts.NPCs -import core.api.utils.GlobalKillCounter +import core.api.utils.PlayerStatsCounter import core.game.system.command.Privilege import core.game.world.repository.Repository import java.util.* @@ -67,6 +67,8 @@ class StatsCommandSet : CommandSet(Privilege.STANDARD) { 77 -> sendLine(player,"Rocks Mined: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_ROCKS",0)}",i) 78 -> sendLine(player,"Fish Caught: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_FISH",0)}",i) 79 -> sendLine(player, "Essence Crafted: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_RC",0)}", i) + 80 -> sendLine(player, "Food Cooked: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_FOOD_COOKED",0)}", i) + 81 -> sendLine(player, "Cats Raised: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_CATS_RAISED",0)}", i) //Boss KC 82 -> sendLine(player, "KBD KC: ${globalData.bossCounters.get(BossKillCounter.KING_BLACK_DRAGON.ordinal)}",i) @@ -89,69 +91,69 @@ class StatsCommandSet : CommandSet(Privilege.STANDARD) { } 1 -> { when(i) { - 97 -> sendLine(player, "Turoths: ${GlobalKillCounter.getKills(queryPlayer, TUROTH_IDS)}", i) - 68 -> sendLine(player, "Kurasks: ${GlobalKillCounter.getKills(queryPlayer, KURASK_IDS)}", i) - 69 -> sendLine(player, "Leaf-bladed swords: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.LEAF_BLADED_SWORD_13290)}", i) + 97 -> sendLine(player, "Turoths: ${PlayerStatsCounter.getKills(queryPlayer, TUROTH_IDS)}", i) + 68 -> sendLine(player, "Kurasks: ${PlayerStatsCounter.getKills(queryPlayer, KURASK_IDS)}", i) + 69 -> sendLine(player, "Leaf-bladed swords: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.LEAF_BLADED_SWORD_13290)}", i) 70 -> sendLine(player, SPACER,i) - 71 -> sendLine(player, "Gargoyles: ${GlobalKillCounter.getKills(queryPlayer, GARGOYLE_IDS)}", i) - 72 -> sendLine(player, "Granite mauls: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GRANITE_MAUL_4153)}", i) + 71 -> sendLine(player, "Gargoyles: ${PlayerStatsCounter.getKills(queryPlayer, GARGOYLE_IDS)}", i) + 72 -> sendLine(player, "Granite mauls: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GRANITE_MAUL_4153)}", i) 73 -> sendLine(player, SPACER,i) - 74 -> sendLine(player, "Spiritual mages: ${GlobalKillCounter.getKills(queryPlayer, SPIRITUAL_MAGE_IDS)}", i) - 75 -> sendLine(player, "Dragon boots: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DRAGON_BOOTS_11732)}", i) + 74 -> sendLine(player, "Spiritual mages: ${PlayerStatsCounter.getKills(queryPlayer, SPIRITUAL_MAGE_IDS)}", i) + 75 -> sendLine(player, "Dragon boots: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DRAGON_BOOTS_11732)}", i) 76 -> sendLine(player, SPACER,i) - 77 -> sendLine(player, "Abyssal demons: ${GlobalKillCounter.getKills(queryPlayer, NPCs.ABYSSAL_DEMON_1615)}", i) - 78 -> sendLine(player, "Abyssal whips: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.ABYSSAL_WHIP_4151)}", i) + 77 -> sendLine(player, "Abyssal demons: ${PlayerStatsCounter.getKills(queryPlayer, intArrayOf(NPCs.ABYSSAL_DEMON_1615))}", i) + 78 -> sendLine(player, "Abyssal whips: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.ABYSSAL_WHIP_4151)}", i) 79 -> sendLine(player, SPACER,i) - 80 -> sendLine(player, "Dark beasts: ${GlobalKillCounter.getKills(queryPlayer, NPCs.DARK_BEAST_2783)}", i) - 81 -> sendLine(player, "Dark bows: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DARK_BOW_11235)}", i) + 80 -> sendLine(player, "Dark beasts: ${PlayerStatsCounter.getKills(queryPlayer, intArrayOf(NPCs.DARK_BEAST_2783))}", i) + 81 -> sendLine(player, "Dark bows: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DARK_BOW_11235)}", i) - 82 -> sendLine(player, "Green Dragons: ${GlobalKillCounter.getKills(queryPlayer, GREEN_DRAGON_IDS)}", i) - 83 -> sendLine(player, "Blue Dragons: ${GlobalKillCounter.getKills(queryPlayer, BLUE_DRAGON_IDS)}", i) - 84 -> sendLine(player, "Red Dragons: ${GlobalKillCounter.getKills(queryPlayer, RED_DRAGON_IDS)}", i) - 85 -> sendLine(player, "Black Dragons: ${GlobalKillCounter.getKills(queryPlayer, BLACK_DRAGON_IDS)}", i) + 82 -> sendLine(player, "Green Dragons: ${PlayerStatsCounter.getKills(queryPlayer, GREEN_DRAGON_IDS)}", i) + 83 -> sendLine(player, "Blue Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BLUE_DRAGON_IDS)}", i) + 84 -> sendLine(player, "Red Dragons: ${PlayerStatsCounter.getKills(queryPlayer, RED_DRAGON_IDS)}", i) + 85 -> sendLine(player, "Black Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BLACK_DRAGON_IDS)}", i) 86 -> sendLine(player, SPACER,i) - 87 -> sendLine(player, "Bronze Dragons: ${GlobalKillCounter.getKills(queryPlayer, BRONZE_DRAGON_IDS)}", i) - 88 -> sendLine(player, "Iron Dragons: ${GlobalKillCounter.getKills(queryPlayer, IRON_DRAGON_IDS)}", i) - 89 -> sendLine(player, "Steel Dragons: ${GlobalKillCounter.getKills(queryPlayer, STEEL_DRAGON_IDS)}", i) - 90 -> sendLine(player, "Mithril Dragons: ${GlobalKillCounter.getKills(queryPlayer, MITHRIL_DRAGON_IDS)}", i) - 91 -> sendLine(player, "Skeletal Wyverns: ${GlobalKillCounter.getKills(queryPlayer, SKELETAL_WYVERN_IDS)}", i) + 87 -> sendLine(player, "Bronze Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BRONZE_DRAGON_IDS)}", i) + 88 -> sendLine(player, "Iron Dragons: ${PlayerStatsCounter.getKills(queryPlayer, IRON_DRAGON_IDS)}", i) + 89 -> sendLine(player, "Steel Dragons: ${PlayerStatsCounter.getKills(queryPlayer, STEEL_DRAGON_IDS)}", i) + 90 -> sendLine(player, "Mithril Dragons: ${PlayerStatsCounter.getKills(queryPlayer, MITHRIL_DRAGON_IDS)}", i) + 91 -> sendLine(player, "Skeletal Wyverns: ${PlayerStatsCounter.getKills(queryPlayer, SKELETAL_WYVERN_IDS)}", i) 92 -> sendLine(player, SPACER,i) - 93 -> sendLine(player, "Draconic visages: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DRACONIC_VISAGE_11286)}", i) + 93 -> sendLine(player, "Draconic visages: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DRACONIC_VISAGE_11286)}", i) else -> sendLine(player,"",i) } } 2 -> { when(i) { - 97 -> sendLine(player, "Ahrim's hood: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_HOOD_4708)}", i) - 68 -> sendLine(player, "Ahrim's staff: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_STAFF_4710)}", i) - 69 -> sendLine(player, "Ahrim's robetop: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBETOP_4712)}", i) - 70 -> sendLine(player, "Ahrim's robeskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBESKIRT_4714)}", i) + 97 -> sendLine(player, "Ahrim's hood: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_HOOD_4708)}", i) + 68 -> sendLine(player, "Ahrim's staff: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_STAFF_4710)}", i) + 69 -> sendLine(player, "Ahrim's robetop: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBETOP_4712)}", i) + 70 -> sendLine(player, "Ahrim's robeskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBESKIRT_4714)}", i) 71 -> sendLine(player, SPACER,i) - 72 -> sendLine(player, "Dharok's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_HELM_4716)}", i) - 73 -> sendLine(player, "Dharok's greataxe: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_GREATAXE_4718)}", i) - 74 -> sendLine(player, "Dharok's platebody: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATEBODY_4720)}", i) - 75 -> sendLine(player, "Dharok's platelegs: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATELEGS_4722)}", i) + 72 -> sendLine(player, "Dharok's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_HELM_4716)}", i) + 73 -> sendLine(player, "Dharok's greataxe: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_GREATAXE_4718)}", i) + 74 -> sendLine(player, "Dharok's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATEBODY_4720)}", i) + 75 -> sendLine(player, "Dharok's platelegs: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATELEGS_4722)}", i) 76 -> sendLine(player, SPACER,i) - 77 -> sendLine(player, "Guthan's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_HELM_4724)}", i) - 78 -> sendLine(player, "Guthan's warspear: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_WARSPEAR_4726)}", i) - 79 -> sendLine(player, "Guthan's platebody: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_PLATEBODY_4728)}", i) - 80 -> sendLine(player, "Guthan's chainskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_CHAINSKIRT_4730)}", i) + 77 -> sendLine(player, "Guthan's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_HELM_4724)}", i) + 78 -> sendLine(player, "Guthan's warspear: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_WARSPEAR_4726)}", i) + 79 -> sendLine(player, "Guthan's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_PLATEBODY_4728)}", i) + 80 -> sendLine(player, "Guthan's chainskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_CHAINSKIRT_4730)}", i) - 82 -> sendLine(player, "Karil's coif: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_COIF_4732)}", i) - 83 -> sendLine(player, "Karil's crossbow: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_CROSSBOW_4734)}", i) - 84 -> sendLine(player, "Karil's leathertop: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERTOP_4736)}", i) - 85 -> sendLine(player, "Karil's leatherskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERSKIRT_4738)}", i) + 82 -> sendLine(player, "Karil's coif: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_COIF_4732)}", i) + 83 -> sendLine(player, "Karil's crossbow: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_CROSSBOW_4734)}", i) + 84 -> sendLine(player, "Karil's leathertop: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERTOP_4736)}", i) + 85 -> sendLine(player, "Karil's leatherskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERSKIRT_4738)}", i) 86 -> sendLine(player, SPACER,i) - 87 -> sendLine(player, "Torag's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_HELM_4745)}", i) - 88 -> sendLine(player, "Torag's hammers: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_HAMMERS_4747)}", i) - 89 -> sendLine(player, "Torag's platebody: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATEBODY_4749)}", i) - 90 -> sendLine(player, "Torag's platelegs: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATELEGS_4751)}", i) + 87 -> sendLine(player, "Torag's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_HELM_4745)}", i) + 88 -> sendLine(player, "Torag's hammers: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_HAMMERS_4747)}", i) + 89 -> sendLine(player, "Torag's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATEBODY_4749)}", i) + 90 -> sendLine(player, "Torag's platelegs: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATELEGS_4751)}", i) 91 -> sendLine(player, SPACER,i) - 92 -> sendLine(player, "Verac's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_HELM_4753)}", i) - 93 -> sendLine(player, "Verac's flail: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_FLAIL_4755)}", i) - 94 -> sendLine(player, "Verac's brassard: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_BRASSARD_4757)}", i) - 95 -> sendLine(player, "Verac's plateskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_PLATESKIRT_4759)}", i) + 92 -> sendLine(player, "Verac's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_HELM_4753)}", i) + 93 -> sendLine(player, "Verac's flail: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_FLAIL_4755)}", i) + 94 -> sendLine(player, "Verac's brassard: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_BRASSARD_4757)}", i) + 95 -> sendLine(player, "Verac's plateskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_PLATESKIRT_4759)}", i) else -> sendLine(player,"",i) } } @@ -165,7 +167,7 @@ class StatsCommandSet : CommandSet(Privilege.STANDARD) { } override fun defineCommands() { - define("stats"){ player, args -> + define("stats", usage = "::stats [player-name]", description = "Opens the statistics book for you or the specified player."){ player, args -> // Bad number of args if(args.size > 2){ diff --git a/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt b/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt index 2581bb4bb..d4e48ca9c 100644 --- a/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt @@ -20,7 +20,7 @@ class SystemCommandSet : CommandSet(Privilege.ADMIN) { /** * Start an update countdown */ - define("update") { player, args -> + define("update", usage = "::update [seconds]", description = "Flags the world for an update, optionally using [seconds] as the countdown.") { player, args -> if (args.size > 1) { SystemManager.getUpdater().setCountdown(args[1].toInt()) } @@ -30,7 +30,7 @@ class SystemCommandSet : CommandSet(Privilege.ADMIN) { /** * Cancel an update countdown */ - define("cancelupdate") { player, _ -> + define("cancelupdate", description = "Cancels any active update countdown.") { player, _ -> SystemManager.getUpdater().cancel() } @@ -230,7 +230,7 @@ class SystemCommandSet : CommandSet(Privilege.ADMIN) { player.inventory.add(Item(Items.ROTTEN_POTATO_5733)) } - define("shutdown", Privilege.ADMIN) { player, _ -> + define("shutdown", Privilege.ADMIN, description = "Immediately terminates the server process. Do NOT test on a remote server you don't own.") { player, _ -> exitProcess(0) } diff --git a/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt b/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt index 2cbc404e2..30e4107c9 100644 --- a/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt @@ -139,6 +139,30 @@ class TeleportCommandSet : CommandSet(Privilege.ADMIN){ } } + /** + * Finds a list of objects/sceneries in a region + */ + define("findobjs", Privilege.ADMIN, "::findobjs REGION ID SCENERY ID", "Finds all locations of scenery objects of id."){player, args -> + if(args.size < 4) reject(player, "Usage: region_id scenery_id") + val regionId = args[1].toInt() + val sceneryId = args[2].toInt() + val sceneryIdEnd = args[3].toInt() + + val region = RegionManager.forId(regionId) + + GlobalScope.launch { + for (plane in region.planes) { + for (objects in plane.objects.filterNotNull()) { + for (parent in objects.filterNotNull()) { + if (parent.id in sceneryId..sceneryIdEnd) { + println(parent.location) + } + } + } + } + } + } + /** * Teleport to a specific player */ diff --git a/Server/src/main/core/game/system/communication/CommunicationInfo.java b/Server/src/main/core/game/system/communication/CommunicationInfo.java index 895d45865..8135e7315 100644 --- a/Server/src/main/core/game/system/communication/CommunicationInfo.java +++ b/Server/src/main/core/game/system/communication/CommunicationInfo.java @@ -1,12 +1,10 @@ package core.game.system.communication; -import core.cache.misc.buffer.ByteBufferUtils; import core.game.node.entity.player.Player; import core.tools.Log; import org.jetbrains.annotations.NotNull; import proto.management.PrivateMessage; import core.auth.UserAccountInfo; -import core.tools.SystemLogger; import core.game.system.mysql.SQLTable; import core.game.system.task.Pulse; import core.game.world.GameWorld; @@ -19,7 +17,6 @@ import core.net.packet.out.ContactPackets; import core.tools.StringUtils; import core.worker.ManagementEvents; -import java.nio.ByteBuffer; import java.util.*; import java.util.Map.Entry; @@ -215,27 +212,6 @@ public final class CommunicationInfo { } } - /** - * Roar temp - * @param buffer - */ - public void parsePrevious(ByteBuffer buffer) { - int size = buffer.get() & 0xFF; - for (int i = 0; i < size; i++) { - String name = ByteBufferUtils.getString(buffer); - Contact contact = new Contact(name); - contact.setRank(ClanRank.FRIEND); - contacts.put(name, contact); - } - size = buffer.get() & 0xFF; - for (int i = 0; i < size; i++) { - blocked.add(ByteBufferUtils.getString(buffer)); - } - if (buffer.get() == 1) { - ByteBufferUtils.getString(buffer); - } - } - /** * Sends a message to the target. * @param player The player sending the message. diff --git a/Server/src/main/core/game/system/config/DoorConfigLoader.kt b/Server/src/main/core/game/system/config/DoorConfigLoader.kt index 4839e713c..04d23c978 100644 --- a/Server/src/main/core/game/system/config/DoorConfigLoader.kt +++ b/Server/src/main/core/game/system/config/DoorConfigLoader.kt @@ -31,14 +31,12 @@ class DoorConfigLoader { door.isFence = e["fence"].toString().toBoolean() door.isMetal = e["metal"].toString().toBoolean() door.isAutoWalk = e["autowalk"]?.toString()?.toBoolean() ?: false - door.questRequirement = e["questRequirement"]?.toString() ?: "" DOORS[door.id] = door val replacedDoor = Door(door.replaceId) replacedDoor.replaceId = door.id replacedDoor.isFence = door.isFence replacedDoor.isMetal = door.isMetal replacedDoor.isAutoWalk = door.isAutoWalk - replacedDoor.questRequirement = door.questRequirement DOORS[door.replaceId] = replacedDoor count++ } diff --git a/Server/src/main/core/game/system/config/GroundSpawnLoader.kt b/Server/src/main/core/game/system/config/GroundSpawnLoader.kt index baf00ce02..d57ac9031 100644 --- a/Server/src/main/core/game/system/config/GroundSpawnLoader.kt +++ b/Server/src/main/core/game/system/config/GroundSpawnLoader.kt @@ -10,12 +10,10 @@ import org.json.simple.JSONObject import org.json.simple.parser.JSONParser import core.ServerConstants import core.api.log -import core.tools.SystemLogger import core.game.world.GameWorld import core.game.world.repository.Repository import core.tools.Log import java.io.* -import java.nio.ByteBuffer class GroundSpawnLoader { val parser = JSONParser() @@ -65,21 +63,11 @@ class GroundSpawnLoader { return "GroundSpawn [name=" + getName() + ", respawnRate=" + respawnRate + ", loc=" + getLocation() + "]" } - /** - * Method used to save this ground item to a byte buffer. - * @param buffer the buffer. - */ - fun save(buffer: ByteBuffer) { - buffer.putInt(respawnRate) - buffer.putShort(id.toShort()) - buffer.putInt(amount) - buffer.putShort((getLocation().x and 0xFFFF).toShort()).putShort((getLocation().y and 0xFFFF).toShort()).put(getLocation().z.toByte()) - } - /** * Method used to initialize this spawn. */ fun init(): GroundItem { + if (respawnRate shr 16 == 0) respawnRate = respawnRate or (respawnRate shl 16) return GroundItemManager.create(this) } diff --git a/Server/src/main/core/game/system/config/MusicConfigLoader.kt b/Server/src/main/core/game/system/config/MusicConfigLoader.kt index 2b11d4fff..3f5cc60cf 100644 --- a/Server/src/main/core/game/system/config/MusicConfigLoader.kt +++ b/Server/src/main/core/game/system/config/MusicConfigLoader.kt @@ -22,10 +22,7 @@ class MusicConfigLoader { val parser = JSONParser() var reader: FileReader? = null fun load(){ - var count = 0 - reader = FileReader(ServerConstants.CONFIG_PATH + "music_configs.json") - var configs = parser.parse(reader) as JSONArray - + // Populate the server data map val songs = DataMap.get(1351) val names = DataMap.get(1345) @@ -35,7 +32,24 @@ class MusicConfigLoader { MusicEntry.getSongs().putIfAbsent(songId, entry) } - for(config in configs){ + // Parse the region-wide music config file + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "music_regions.json") + var configs = parser.parse(reader) as JSONArray + for(config in configs) { + val e = config as JSONObject + val region = Integer.parseInt(e["region"].toString()) + val id = Integer.parseInt(e["id"].toString()) + RegionManager.forId(region).music = id + count++ + } + log(this::class.java, Log.FINE, "Parsed $count region music configs.") + + // Parse the file with tile-specific music locations + count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "music_tiles.json") + configs = parser.parse(reader) as JSONArray + for(config in configs) { val e = config as JSONObject val musicId = Integer.parseInt(e["id"].toString()) val string = e["borders"].toString() @@ -43,9 +57,6 @@ class MusicConfigLoader { var tokens: Array? = null var borders: ZoneBorders? = null for (border in borderArray) { - if(border.isEmpty()){ - continue - } tokens = border.replace("{", "").replace("}", "").split(",").toTypedArray() borders = ZoneBorders(tokens[0].toInt(), tokens[1].toInt(), tokens[2].toInt(), tokens[3].toInt()) if (border.contains("[")) { //no exception borders @@ -59,8 +70,6 @@ class MusicConfigLoader { e = exception.replace("[", "").replace("]", "").split(",".toRegex()).toTypedArray() borders.addException(ZoneBorders(e[0].toInt(), e[1].toInt(), e[2].toInt(), e[3].toInt())) } - e = null - exceptions = null } val zone = MusicZone(musicId, borders) for (id in borders.getRegionIds()) { @@ -69,6 +78,6 @@ class MusicConfigLoader { } count++ } - log(this::class.java, Log.FINE, "Parsed $count music configs.") + log(this::class.java, Log.FINE, "Parsed $count tile music configs.") } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/system/config/RangedConfigLoader.kt b/Server/src/main/core/game/system/config/RangedConfigLoader.kt index 41a85f4b3..6c54cbd55 100644 --- a/Server/src/main/core/game/system/config/RangedConfigLoader.kt +++ b/Server/src/main/core/game/system/config/RangedConfigLoader.kt @@ -8,7 +8,6 @@ import core.game.node.entity.combat.equipment.BoltEffect import core.game.node.entity.combat.equipment.RangeWeapon import core.game.node.entity.impl.Projectile import core.game.node.entity.npc.NPC -import core.tools.SystemLogger import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics diff --git a/Server/src/main/core/game/system/config/ServerConfigParser.kt b/Server/src/main/core/game/system/config/ServerConfigParser.kt index 5996a508f..58e3e6ebf 100644 --- a/Server/src/main/core/game/system/config/ServerConfigParser.kt +++ b/Server/src/main/core/game/system/config/ServerConfigParser.kt @@ -76,8 +76,6 @@ object ServerConfigParser { isQuickChat = false, isLootshare = false, msAddress = data.getString("server.msip"), - default_xp_rate = data.getDouble("world.default_xp_rate"), - allow_slayer_reroll = data.getBoolean("world.allow_slayer_reroll"), enable_default_clan = data.getBoolean("world.enable_default_clan"), enable_bots = data.getBoolean("world.enable_bots"), autostock_ge = data.getBoolean("world.autostock_ge"), @@ -148,23 +146,41 @@ object ServerConfigParser { ServerConstants.NOAUTH_DEFAULT_ADMIN = data.getBoolean("server.noauth_default_admin", false) ServerConstants.DRAGON_AXE_USE_OSRS_SPEC = data.getBoolean("world.dragon_axe_use_osrs_spec", false) ServerConstants.DISCORD_OPENRSC_HOOK = data.getString("integrations.openrsc_integration_webhook", "") - ServerConstants.ENABLE_GLOBALCHAT = data.getBoolean("world.enable_globalchat", true) + ServerConstants.ENABLE_GLOBAL_CHAT = data.getBoolean("world.enable_global_chat", false) ServerConstants.MAX_PATHFIND_DISTANCE = data.getLong("server.max_pathfind_dist", 25L).toInt() - ServerConstants.IRONMAN_ICONS = data.getBoolean("world.ironman_icons", false) + ServerConstants.XP_RATES = data.getBoolean("world.xp_rates", false) + ServerConstants.IRONMAN = data.getBoolean("world.ironman", false) ServerConstants.PLAYER_STOCK_CLEAR_INTERVAL = data.getLong("world.playerstock_clear_mins", 180L).toInt() ServerConstants.PLAYER_STOCK_RECIRCULATE = data.getBoolean("world.playerstock_bot_offers", true) ServerConstants.BOTSTOCK_LIMIT = data.getLong("world.botstock_limit", 5000L).toInt() - ServerConstants.BETTER_AGILITY_PYRAMID_GP = data.getBoolean("world.better_agility_pyramid_gp", true) + ServerConstants.BETTER_AGILITY_PYRAMID_GP = data.getBoolean("world.better_agility_pyramid_gp", false) ServerConstants.GRAFANA_PATH = data.getPath("integrations.grafana_log_path") ServerConstants.GRAFANA_LOGGING = data.getBoolean("integrations.grafana_logging", false) ServerConstants.GRAFANA_TTL_DAYS = data.getLong("integrations.grafana_log_ttl_days", 7L).toInt() - ServerConstants.BETTER_DFS = data.getBoolean("world.better_dfs", true) - ServerConstants.NEW_PLAYER_ANNOUNCEMENT = data.getBoolean("world.new_player_announcement", true) - ServerConstants.HOLIDAY_EVENT_RANDOMS = data.getBoolean("world.holiday_event_randoms", true) + ServerConstants.BETTER_DFS = data.getBoolean("world.better_dfs", false) + ServerConstants.NEW_PLAYER_ANNOUNCEMENT = data.getBoolean("world.new_player_announcement", false) + ServerConstants.INAUTHENTIC_CANDLELIGHT_RANDOM = data.getBoolean("world.inauthentic_candlelight_random", false) + ServerConstants.HOLIDAY_EVENT_RANDOMS = data.getBoolean("world.holiday_event_randoms", false) ServerConstants.FORCE_HALLOWEEN_EVENTS = data.getBoolean("world.force_halloween_randoms", false) ServerConstants.FORCE_CHRISTMAS_EVENTS = data.getBoolean("world.force_christmas_randoms", false) ServerConstants.FORCE_EASTER_EVENTS = data.getBoolean("world.force_easter_randoms", false) - ServerConstants.RUNECRAFTING_FORMULA_REVISION = data.getLong("world.runecrafting_formula_revision", 581).toInt() + ServerConstants.APRIL_FOOLS_EVENT = data.getBoolean("world.april_fools_event", false) + ServerConstants.FORCE_APRIL_FOOLS = data.getBoolean("world.force_april_fools", false) + ServerConstants.RUNECRAFTING_FORMULA_REVISION = data.getLong("world.runecrafting_formula_revision", 530).toInt() + ServerConstants.ENHANCED_DEEP_WILDERNESS = data.getBoolean("world.enhanced_deep_wilderness", false) + ServerConstants.WILDERNESS_EXCLUSIVE_LOOT = data.getBoolean("world.wilderness_exclusive_loot", false) + ServerConstants.SHOOTING_STAR_RING = data.getBoolean("world.shooting_star_ring", false) + ServerConstants.RING_OF_WEALTH_TELEPORT = data.getBoolean("world.ring_of_wealth_teleport", false) + ServerConstants.SECOND_BANK = data.getBoolean("world.second_bank", false) + ServerConstants.PLAYER_COMMANDS = data.getBoolean("world.player_commands", false) + ServerConstants.BOOSTED_TRAWLER_REWARDS = data.getBoolean("world.boosted_trawler_rewards", false) + ServerConstants.CONNECTIVITY_CHECK_URL = data.getString("server.connectivity_check_url", "https://google.com,https://2009scape.org") + ServerConstants.CONNECTIVITY_TIMEOUT = data.getLong("server.connectivity_timeout", 500L).toInt() + ServerConstants.WEBSOCKET_ENABLED = data.getBoolean("server.websocket_enabled", false) + ServerConstants.WEBSOCKET_PORT = data.getLong("server.websocket_port", 0L).toInt() + ServerConstants.WEBSOCKET_TLS_ENABLED = data.getBoolean("server.websocket_tls_enabled", false) + ServerConstants.WEBSOCKET_TLS_KEYSTORE_PATH = data.getString("server.websocket_tls_keystore_path", "") + ServerConstants.WEBSOCKET_TLS_KEYSTORE_PASSWORD = data.getString("server.websocket_tls_keystore_password", "") val logLevel = data.getString("server.log_level", "VERBOSE").uppercase() ServerConstants.LOG_LEVEL = parseEnumEntry(logLevel) ?: LogLevel.VERBOSE diff --git a/Server/src/main/core/game/system/config/XteaParser.kt b/Server/src/main/core/game/system/config/XteaParser.kt index 6b7f81ad8..9eb4f569c 100644 --- a/Server/src/main/core/game/system/config/XteaParser.kt +++ b/Server/src/main/core/game/system/config/XteaParser.kt @@ -13,13 +13,9 @@ import kotlin.collections.HashMap class XteaParser { companion object{ val REGION_XTEA = HashMap() - val DEFAULT_REGION_KEYS = intArrayOf(14881828, -6662814, 58238456, 146761213) - fun getRegionXTEA(regionId: Int): IntArray? { //Uses the xtea's from the sql to unlock regions - - return REGION_XTEA[regionId] - - return DEFAULT_REGION_KEYS //This one grabs the keys from the SQL - // return DEFAULT_REGION_KEYS;//This one only uses the default keys at the top,{ 14881828, -6662814, 58238456, 146761213 }. Unsure why they chose these numbers. + private val DEFAULT_REGION_KEYS = intArrayOf(0, 0, 0, 0) + fun getRegionXTEA(regionId: Int): IntArray { //Uses the xtea's from the sql to unlock regions + return REGION_XTEA.getOrDefault(regionId, DEFAULT_REGION_KEYS) } } val parser = JSONParser() diff --git a/Server/src/main/core/game/system/timer/RSTimer.kt b/Server/src/main/core/game/system/timer/RSTimer.kt index a995bac75..75770b7bc 100644 --- a/Server/src/main/core/game/system/timer/RSTimer.kt +++ b/Server/src/main/core/game/system/timer/RSTimer.kt @@ -24,8 +24,15 @@ abstract class RSTimer (var runInterval: Int, val identifier: String = "generict **/ open fun getInitialRunDelay() : Int { return runInterval } + /** + * Called by core code before the timer is first registered. Called after parse on PersistTimers. + * Called before the timer has been added to the timer list. + **/ + open fun beforeRegister (entity: Entity) {} + /** * Called by core code when the timer is first registered. Called after parse on PersistTimers. + * Called after the timer has been added to the timer list. **/ open fun onRegister (entity: Entity) {} diff --git a/Server/src/main/core/game/system/timer/TimerManager.kt b/Server/src/main/core/game/system/timer/TimerManager.kt index fd63b7ec5..92bd50e8c 100644 --- a/Server/src/main/core/game/system/timer/TimerManager.kt +++ b/Server/src/main/core/game/system/timer/TimerManager.kt @@ -13,8 +13,9 @@ class TimerManager (val entity: Entity) { val toRemoveTimers = ArrayList() fun registerTimer (timer: RSTimer) { + timer.beforeRegister(entity) + newTimers.add(timer) timer.onRegister(entity) - newTimers.add (timer) } fun processTimers () { diff --git a/Server/src/main/core/game/system/timer/impl/Disease.kt b/Server/src/main/core/game/system/timer/impl/Disease.kt index 7d270e0a9..cfc72ac84 100644 --- a/Server/src/main/core/game/system/timer/impl/Disease.kt +++ b/Server/src/main/core/game/system/timer/impl/Disease.kt @@ -20,7 +20,7 @@ class Disease : PersistTimer (30, "disease", flags = arrayOf(TimerFlag.ClearOnDe hitsLeft = root["hitsLeft"].toString().toInt() } - override fun onRegister (entity: Entity) { + override fun beforeRegister (entity: Entity) { if (hasTimerActive(entity)) removeTimer(entity, this) else if (entity is Player) diff --git a/Server/src/main/core/game/system/timer/impl/DragonFireImmunity.kt b/Server/src/main/core/game/system/timer/impl/DragonFireImmunity.kt new file mode 100644 index 000000000..2f2a2b9e5 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/DragonFireImmunity.kt @@ -0,0 +1,47 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.tools.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.json.simple.* +import org.rs09.consts.Sounds + +/** + * A timer that replicates the behavior of Dragon Fire immunity mechanics. Runs every tick. + * Will notify the player of various levels of remaining Dragon Fire immunity, and then remove itself once it has run out. + * This timer is a "soft" timer, meaning it will tick down even while other timers would normally stall (e.g. during entity delays or when the entity has a modal open.) +**/ +class DragonFireImmunity : PersistTimer (1, "dragonfire:immunity", isSoft = true, flags = arrayOf(TimerFlag.ClearOnDeath)) { + var ticksRemaining = 0 + + override fun save (root: JSONObject, entity: Entity) { + root["ticksRemaining"] = ticksRemaining.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + ticksRemaining = root["ticksRemaining"].toString().toInt() + } + + override fun run (entity: Entity) : Boolean { + ticksRemaining-- + + if (entity is Player && ticksRemaining == secondsToTicks(30)) { + sendMessage(entity, colorize("%RYou have 30 seconds remaining on your antifire potion.")) + playAudio(entity, Sounds.CLOCK_TICK_1_3120, 0, 3) + } + else if (entity is Player && ticksRemaining == 0) { + sendMessage(entity, colorize("%RYour antifire potion has expired.")) + playAudio(entity, Sounds.DRAGON_POTION_FINISHED_2607) + } + + return ticksRemaining > 0 + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = DragonFireImmunity() + t.ticksRemaining = args.getOrNull(0) as? Int ?: 100 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Frozen.kt b/Server/src/main/core/game/system/timer/impl/Frozen.kt index 94c5456a4..23a2fa7e5 100644 --- a/Server/src/main/core/game/system/timer/impl/Frozen.kt +++ b/Server/src/main/core/game/system/timer/impl/Frozen.kt @@ -1,47 +1,50 @@ -package core.game.system.timer.impl - -import core.game.system.timer.* -import core.api.* -import core.game.node.entity.Entity -import core.game.node.entity.player.Player -import core.game.world.repository.Repository -import org.json.simple.* - -class Frozen : PersistTimer (1, "frozen", flags = arrayOf(TimerFlag.ClearOnDeath)) { - var shouldApplyImmunity = false - - override fun save (root: JSONObject, entity: Entity) { - root["ticksLeft"] = (nextExecution - getWorldTicks()).toString() - root["applyImmunity"] = shouldApplyImmunity - } - - override fun parse (root: JSONObject, entity: Entity) { - runInterval = root["ticksLeft"].toString().toInt() - shouldApplyImmunity = root["applyImmunity"] as? Boolean ?: false - } - - override fun onRegister (entity: Entity) { - if (hasTimerActive(entity)) { - removeTimer(entity, this) - return - } - if (hasTimerActive(entity)) { - removeTimer(entity, this) - return - } - } - - override fun run (entity: Entity) : Boolean { - if (shouldApplyImmunity) { - registerTimer (entity, spawnTimer(7)) - } else (entity as? Player)?.debug ("Can't apply immunity") - return false - } - - override fun getTimer (vararg args: Any) : RSTimer { - val inst = Frozen() - inst.runInterval = args.getOrNull(0) as? Int ?: 10 - inst.shouldApplyImmunity = args.getOrNull(1) as? Boolean ?: false - return inst - } -} +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.repository.Repository +import org.json.simple.* + +class Frozen : PersistTimer (1, "frozen", flags = arrayOf(TimerFlag.ClearOnDeath)) { + var shouldApplyImmunity = false + + override fun save (root: JSONObject, entity: Entity) { + root["ticksLeft"] = (nextExecution - getWorldTicks()).toString() + root["applyImmunity"] = shouldApplyImmunity + } + + override fun parse (root: JSONObject, entity: Entity) { + runInterval = root["ticksLeft"].toString().toInt() + shouldApplyImmunity = root["applyImmunity"] as? Boolean ?: false + } + + override fun beforeRegister (entity: Entity) { + if (hasTimerActive(entity)) { + removeTimer(entity, this) + return + } + if (hasTimerActive(entity)) { + removeTimer(entity, this) + return + } + if (entity is Player) { + sendMessage(entity as Player, "You have been frozen!") + } + } + + override fun run (entity: Entity) : Boolean { + if (shouldApplyImmunity) { + registerTimer (entity, spawnTimer(7)) + } else (entity as? Player)?.debug ("Can't apply immunity") + return false + } + + override fun getTimer (vararg args: Any) : RSTimer { + val inst = Frozen() + inst.runInterval = args.getOrNull(0) as? Int ?: 10 + inst.shouldApplyImmunity = args.getOrNull(1) as? Boolean ?: false + return inst + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Miasmic.kt b/Server/src/main/core/game/system/timer/impl/Miasmic.kt index d9c1eca18..9af8ee3ad 100644 --- a/Server/src/main/core/game/system/timer/impl/Miasmic.kt +++ b/Server/src/main/core/game/system/timer/impl/Miasmic.kt @@ -15,7 +15,7 @@ class Miasmic : PersistTimer (1, "miasmic", flags = arrayOf(TimerFlag.ClearOnDea return false } - override fun onRegister (entity: Entity) { + override fun beforeRegister (entity: Entity) { if (hasTimerActive(entity)) removeTimer(entity, this) if (hasTimerActive(entity)) diff --git a/Server/src/main/core/game/system/timer/impl/Poison.kt b/Server/src/main/core/game/system/timer/impl/Poison.kt index 2f4c58cf9..ececf51f6 100644 --- a/Server/src/main/core/game/system/timer/impl/Poison.kt +++ b/Server/src/main/core/game/system/timer/impl/Poison.kt @@ -1,10 +1,13 @@ package core.game.system.timer.impl +import content.global.skill.summoning.familiar.Familiar import core.game.system.timer.* import core.api.* import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills import core.game.world.repository.Repository import org.json.simple.* @@ -20,14 +23,6 @@ class Poison : PersistTimer (30, "poison", flags = arrayOf(TimerFlag.ClearOnDeat lateinit var damageSource: Entity var severity = 0 - set (value) { - if (value != field - 1 && value % 10 == 8) {//This was Arios's incorrect attempt at replicating severity, convert it to correct values. - (damageSource as? Player)?.debug ("[PoisonTimer] Warning: Converting suspect Arios severity into true severity. If numbers look wrong, this could be why.") - field = (value / 10) * 5 - (damageSource as? Player)?.debug ("[PoisonTimer] Warning: New Severity: $field.") - } else field = value - } - override fun save (root: JSONObject, entity: Entity) { root["source-uid"] = (damageSource as? Player)?.details?.uid ?: -1 root["severity"] = severity.toString() @@ -38,17 +33,31 @@ class Poison : PersistTimer (30, "poison", flags = arrayOf(TimerFlag.ClearOnDeat damageSource = Repository.getPlayerByUid (uid) ?: entity severity = root["severity"].toString().toInt() } - - override fun onRegister (entity: Entity) { - if (entity is Player) { - sendMessage(entity, "You have been poisoned.") - entity.debug ("[Poison] -> Received for $severity severity.") - } - if (damageSource is Player) - (damageSource as? Player)?.debug ("[Poison] -> Applied for $severity severity.") - } + + override fun onRegister(entity : Entity) { + if (entity is Player) { + sendMessage(entity, "You have been poisoned.") + entity.debug("[Poison] -> Received for $severity severity.") + } + if (damageSource is Player) { + (damageSource as? Player)?.debug("[Poison] -> Applied for $severity severity.") + // this is ass, and preventing poisoning slayer monster player lacks lv req for should be done but prob not here & not like this. same for familiars + if (entity is NPC && entity.task != null && entity.task.levelReq > damageSource.skills.getLevel(Skills.SLAYER)) { + (damageSource as? Player)?.debug("[Poison] -> Removed poison from ${entity.name} ${entity.location} due to Slayer reqs!") + removeTimer(entity, this) + } + } + if (damageSource is Familiar) { + val owner : Player? = (damageSource as Familiar).owner + if (owner != null && entity is NPC && entity.task != null && entity.task.levelReq > owner.skills.getLevel(Skills.SLAYER)) { + owner.debug("[Poison] -> Removed poison from ${entity.name} ${entity.location} due to Slayer reqs!") + removeTimer(entity, this) + } + } + } override fun run (entity: Entity) : Boolean { + entity.scripts.removeWeakScripts() entity.impactHandler.manualHit ( damageSource, getDamageFromSeverity (severity--), @@ -62,8 +71,6 @@ class Poison : PersistTimer (30, "poison", flags = arrayOf(TimerFlag.ClearOnDeat override fun getTimer (vararg args: Any) : RSTimer { val timer = Poison() - for (arg in args) - println(arg) timer.damageSource = args[0] as? Entity ?: return timer timer.severity = args[1] as? Int ?: return timer return timer diff --git a/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt b/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt index 1695fce7b..c90608e58 100644 --- a/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt +++ b/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt @@ -31,11 +31,7 @@ class PoisonImmunity : PersistTimer (1, "poison:immunity", isSoft = true, flags override fun run (entity: Entity) : Boolean { ticksRemaining-- - if (entity is Player && ticksRemaining == secondsToTicks(30)) { - sendMessage(entity, colorize("%RYou have 30 seconds remaining on your poison immunity.")) - playAudio(entity, Sounds.CLOCK_TICK_1_3120, 0, 3) - } - else if (entity is Player && ticksRemaining == 0) { + if (entity is Player && ticksRemaining == 0) { sendMessage(entity, colorize("%RYour poison immunity has expired.")) playAudio(entity, Sounds.DRAGON_POTION_FINISHED_2607) } diff --git a/Server/src/main/core/game/system/timer/impl/SkillRestore.kt b/Server/src/main/core/game/system/timer/impl/SkillRestore.kt index 7f1a8bcac..f14d46abe 100644 --- a/Server/src/main/core/game/system/timer/impl/SkillRestore.kt +++ b/Server/src/main/core/game/system/timer/impl/SkillRestore.kt @@ -19,7 +19,7 @@ class SkillRestore : RSTimer (1, "skillrestore", isAuto = true, isSoft = true) { var skills = entity.skills for (i in 0 until 24) { - if (i == Skills.PRAYER) continue + if (i == Skills.PRAYER || i == Skills.SUMMONING) continue if (ticksSinceLastRestore[i]++ >= restoreTicks[i]) { if (i == Skills.HITPOINTS && entity.skills.lifepoints < entity.skills.maximumLifepoints) { skills.heal (getHealAmount(entity)) @@ -48,7 +48,7 @@ class SkillRestore : RSTimer (1, "skillrestore", isAuto = true, isSoft = true) { (entity as? Player)?.debug("Registered skill restoration timer.") } - private fun getHealAmount (entity: Entity) : Int { + fun getHealAmount (entity: Entity) : Int { if (entity !is Player) return 1 val gloves = getItemFromEquipment (entity, EquipmentSlot.HANDS) diff --git a/Server/src/main/core/game/system/timer/impl/Skulled.kt b/Server/src/main/core/game/system/timer/impl/Skulled.kt index fee4474ab..f8e8bcd76 100644 --- a/Server/src/main/core/game/system/timer/impl/Skulled.kt +++ b/Server/src/main/core/game/system/timer/impl/Skulled.kt @@ -19,6 +19,11 @@ class Skulled : PersistTimer (1, "skulled", flags = arrayOf(TimerFlag.ClearOnDea return false } + override fun onRemoval (entity: Entity) { + if (entity !is Player) return + entity.skullManager.reset() + } + override fun getTimer (vararg args: Any) : RSTimer { val t = Skulled() t.runInterval = args.getOrNull(0) as? Int ?: 500 diff --git a/Server/src/main/core/game/system/timer/impl/SpellbookSwap.kt b/Server/src/main/core/game/system/timer/impl/SpellbookSwap.kt new file mode 100644 index 000000000..b689e3a0a --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/SpellbookSwap.kt @@ -0,0 +1,99 @@ +package core.game.system.timer.impl + +import core.api.Event.DialogueClosed +import core.api.Event.SpellCast +import core.api.Event.SpellbookChanged +import core.api.clearLogoutListener +import core.api.registerLogoutListener +import core.api.removeTimer +import core.game.event.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.player.link.SpellBookManager.SpellbookChangeSource +import core.game.system.timer.PersistTimer +import core.tools.minutesToTicks + +/** + * A timer dedicated to the handling of the Lunar spell Spellbook Swap. + */ +class SpellbookSwap : PersistTimer(runInterval = minutesToTicks(2), identifier = "spellbook:swap") { + + private val spellCastHook = object : EventHook { + override fun process(entity : Entity, event : SpellCastEvent) { + if (event.spellBook == SpellBook.LUNAR && event.spellId == 12) return // Ignore spellbook swap itself + revertSpellbook(entity) + removeTimer(entity) + } + } + + private val spellBookChangeHook = object : EventHook { + override fun process(entity : Entity, event : SpellbookChangeEvent) { + if (event.source != SpellbookChangeSource.SPELLBOOK_SWAP_CAST + && event.source != SpellbookChangeSource.SPELLBOOK_SWAP_RESTORE) { + removeTimer(entity) + } + } + } + + private val dialogueCloseHook = object : EventHook { + override fun process(entity : Entity, event : DialogueCloseEvent) { + if (event.dialogue?.getIds()?.contains(3264731) != true) return // Spellbook swap selection dialogue + if (entity !is Player) return + if (SpellBook.forInterface(entity.spellBookManager.spellBook) == SpellBook.LUNAR) { + entity.removeAttribute("spell:runes") + removeTimer(entity) + } + } + } + + override fun run(entity : Entity) : Boolean { + revertSpellbook(entity) + return false + } + + override fun onRegister(entity : Entity) { + entity.hook(SpellCast, spellCastHook) + entity.hook(SpellbookChanged, spellBookChangeHook) + entity.hook(DialogueClosed, dialogueCloseHook) + if (entity is Player) { + registerLogoutListener(entity, "spellbook:swap") { player -> + revertSpellbook(player) + } + } + } + + override fun onRemoval(entity : Entity) { + entity.unhook(spellCastHook) + entity.unhook(spellBookChangeHook) + entity.unhook(dialogueCloseHook) + if (entity is Player) { + clearLogoutListener(entity, "spellbook:swap") + } + } + + private fun revertSpellbook(entity : Entity) { + if (entity !is Player) return + if (SpellBook.forInterface(entity.spellBookManager.spellBook) == SpellBook.LUNAR) return + // Clear autocast + val weaponInterface = entity.getExtension(WeaponInterface::class.java) + if (weaponInterface != null && entity.properties.autocastSpell != null) { + weaponInterface.selectAutoSpell(-1, true) + } + // Close autocast selection interface if it's still open + if (entity.getAttribute("autocast_select", false)) { + entity.removeAttribute("autocast_select") + entity.removeAttribute("autocast_component") + if (weaponInterface != null) { + entity.interfaceManager.openTab(weaponInterface) + } + } + entity.dispatch(SpellbookChangeEvent( + SpellBook.forInterface(entity.spellBookManager.spellBook), + SpellBook.LUNAR, + SpellbookChangeSource.SPELLBOOK_SWAP_RESTORE)) + entity.spellBookManager.setSpellBook(SpellBook.LUNAR) + entity.spellBookManager.update(entity) + } +} diff --git a/Server/src/main/core/game/world/GameSettings.kt b/Server/src/main/core/game/world/GameSettings.kt index c75a55efd..e113dbbe3 100644 --- a/Server/src/main/core/game/world/GameSettings.kt +++ b/Server/src/main/core/game/world/GameSettings.kt @@ -69,8 +69,6 @@ class GameSettings * The address of the Management server. */ var msAddress: String, - var default_xp_rate: Double, - var allow_slayer_reroll: Boolean, var enable_default_clan: Boolean, var enable_bots: Boolean, var autostock_ge: Boolean, @@ -88,17 +86,16 @@ class GameSettings /**"Lobby" interface * The message of the week models to display - * 15 & 22 = keys & lock || 16 = fly swat || 17 = person with question marks || 18 & 447 = wise old man - * 19 = man & woman with mouth closed || 20 = man & lock & key || 21 = closed chests - * 23 = snowmen || 405 = Construction houses || 622 = Two sets of 3 people range, mage, melee - * 623 = Woodcutting || 679 = Summoning || 715 = Easter || 800 = Halloween - * Any value that isn't one listed above = random selection + * 15 & 22 = Lock w/key & keys || 16 = Fly swatters || 17 = Man & woman with question marks + * 18 & 447 = Wise old man & woman || 19 = Man with mouth zipped & woman talking || 20 = Man & lock w/key + * 21 = Chests that open & close || 23 = Christmas || 405 = Construction houses + * 622 = Two sets 3 people range, mage, melee 623 = Woodcutting || 679 = Summoning || 715 = Easter || 800 = Halloween */ var message_model: Int, /**"Lobby" interface * The message of the week text - * The "child" for writing text to these interfaces is located inside of LoginConfiguration.java + * The "child" for writing text to these interfaces is located inside LoginConfiguration.java * method: getMessageChild */ var message_string: String @@ -127,8 +124,6 @@ class GameSettings val activity = data["activity"].toString() val pvpWorld = data["pvpWorld"] as Boolean val msip = data["msip"].toString() - val default_xp_rate = data["default_xp_rate"].toString().toDouble() - val allow_slayer_reroll = data["allow_slayer_reroll"] as Boolean val enable_default_clan = data["enable_default_clan"] as Boolean val enable_bots = data["enable_bots"] as Boolean val autostock_ge = data["autostock_ge"] as Boolean @@ -158,8 +153,6 @@ class GameSettings false, false, msip, - default_xp_rate, - allow_slayer_reroll, enable_default_clan, enable_bots, autostock_ge, diff --git a/Server/src/main/core/game/world/ImmerseWorld.kt b/Server/src/main/core/game/world/ImmerseWorld.kt index 2efed45a8..2adee483f 100644 --- a/Server/src/main/core/game/world/ImmerseWorld.kt +++ b/Server/src/main/core/game/world/ImmerseWorld.kt @@ -11,6 +11,7 @@ import core.game.bots.SkillingBotAssembler import java.util.Timer import java.util.concurrent.Executors import kotlin.concurrent.schedule +import kotlin.random.Random class ImmerseWorld : StartupListener { @@ -24,6 +25,12 @@ class ImmerseWorld : StartupListener { var assembler = CombatBotAssembler() var skillingBotAssembler = SkillingBotAssembler() + private fun randomizeLocationInRanges(location: Location, xMin: Int, xMax: Int, yMin: Int, yMax: Int): Location { + val newX = location.x + Random.nextInt(xMin, xMax) + val newY = location.y + Random.nextInt(yMin, yMax) + return Location(newX, newY, 0) + } + fun spawnBots() { if(GameWorld.settings!!.enable_bots) @@ -43,10 +50,10 @@ class ImmerseWorld : StartupListener { } } - fun immerseAdventurer() { - for (i in 0..(GameWorld.settings?.max_adv_bots ?: 50)) { - var random: Long = (10000..300000).random().toLong() - Timer().schedule(random) { + fun immerseAdventurer(){ + for (i in 0..(GameWorld.settings?.max_adv_bots ?: 50)){ + var random = Random.nextInt(20000, 400000).toLong() + Timer().schedule(random){ spawn_adventurers() } } @@ -55,14 +62,17 @@ class ImmerseWorld : StartupListener { fun spawn_adventurers() { val lumbridge = Location.create(3221, 3219, 0) val tiers = listOf(CombatBotAssembler.Tier.LOW, CombatBotAssembler.Tier.MED) - GeneralBotCreator( - Adventurer(CombatStyle.MELEE), - assembler.MeleeAdventurer(tiers.random(), lumbridge) - ) - GeneralBotCreator( - Adventurer(CombatStyle.RANGE), - assembler.RangeAdventurer(tiers.random(), lumbridge) - ) + if (Random.nextBoolean()) { + GeneralBotCreator( + Adventurer(CombatStyle.MELEE), + assembler.MeleeAdventurer(tiers.random(), randomizeLocationInRanges(lumbridge,-1,1,-1,1)) + ) + } else { + GeneralBotCreator( + Adventurer(CombatStyle.RANGE), + assembler.RangeAdventurer(tiers.random(), randomizeLocationInRanges(lumbridge,-1,1,-1,1)) + ) + } } fun immerseFishingGuild() { diff --git a/Server/src/main/core/game/world/map/BuildRegionChunk.java b/Server/src/main/core/game/world/map/BuildRegionChunk.java index 8f97d6c0a..008937301 100644 --- a/Server/src/main/core/game/world/map/BuildRegionChunk.java +++ b/Server/src/main/core/game/world/map/BuildRegionChunk.java @@ -6,6 +6,7 @@ import core.game.node.item.GroundItem; import core.game.node.item.Item; import core.game.node.scenery.Constructed; import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; import core.tools.Log; import core.tools.SystemLogger; import core.game.world.map.build.LandscapeParser; @@ -100,11 +101,12 @@ public class BuildRegionChunk extends RegionChunk { for (int x = 0; x < SIZE; x++) { for (int y = 0; y < SIZE; y++) { for (int i = 0; i < objects.length; i++) { - copy[i][x][y] = objects[i][x][y]; - objects[i][x][y] = null; + Scenery object = copy[i][x][y] = objects[i][x][y]; + if (object != null) { + SceneryBuilder.remove(object); + this.remove(object); + } } - plane.getObjects()[baseX + x][baseY + y] = null; - plane.getFlags().clearFlag(baseX + x, baseY + y); } } clear(); diff --git a/Server/src/main/core/game/world/map/Location.java b/Server/src/main/core/game/world/map/Location.java deleted file mode 100644 index ea7d1794c..000000000 --- a/Server/src/main/core/game/world/map/Location.java +++ /dev/null @@ -1,563 +0,0 @@ -package core.game.world.map; - -import core.game.interaction.DestinationFlag; -import core.game.node.Node; -import core.game.world.map.path.Path; -import core.game.world.map.path.Pathfinder; -import core.tools.RandomFunction; -import org.jetbrains.annotations.NotNull; -import core.api.utils.Vector; - -import java.util.ArrayList; -import java.util.List; -import java.lang.Math; - -/** - * Represents a location on the world map. - * @author Emperor - */ -public final class Location extends Node { - - /** - * The x-coordinate. - */ - private int x; - - /** - * The y-coordinate. - */ - private int y; - - /** - * The plane. - */ - private int z; - - /** - * Constructs a new {@code Location} {@code Object}. - * @param x The x-coordinate. - * @param y The y-coordinate. - * @param z The z-coordinate. - */ - public Location(int x, int y, int z) { - super(null, null); - super.destinationFlag = DestinationFlag.LOCATION; - this.x = x; - this.y = y; - if (z < 0) { - z += 4; - } - this.z = z; - } - - /** - * Constructs a new {@code Location} {@code Object} - * @param x The x-coordinate. - * @param y The y-coordinate. - */ - public Location(int x, int y) { - this(x, y, 0); - } - - /** - * Constructs a new {@code Location} {@code Object}. - * @param x The x-coordinate. - * @param y The y coordinate. - * @param z The z-coordinate. - * @param randomizer The amount we should randomize the x and y coordinates - * with (x + random(randomizer), y + random(randomizer)). - */ - public Location(int x, int y, int z, int randomizer) { - this(x + RandomFunction.getRandom(randomizer), y + RandomFunction.getRandom(randomizer), z); - } - - /** - * Construct a new Location. - * @param x The x-coordinate. - * @param y The y-coordinate. - * @param z The z-coordinate. - * @return The constructed location. - */ - public static Location create(int x, int y, int z) { - return new Location(x, y, z); - } - - public static Location create(int x, int y) { - return new Location(x, y, 0); - } - - /** - * Creates a new instance of the given location. - * @param location The given location. - * @return The new instance. - */ - public static Location create(Location location) { - return create(location.getX(), location.getY(), location.getZ()); - } - - /** - * Creates a location instance with coordinates being the difference between - * {@code other} & {@code location}. - * @param location The first location. - * @param other The other location. - * @return The delta location. - */ - public static Location getDelta(Location location, Location other) { - return Location.create(other.x - location.x, other.y - location.y, other.z - location.z); - } - - /** - * Gets a random location near the main location. - * @param main The main location. - * @param radius The radius. - * @param reachable If the locations should be able to reach eachother. - * @return The location. - */ - public static Location getRandomLocation(Location main, int radius, boolean reachable) { - Location location = RegionManager.getTeleportLocation(main, radius); - if (!reachable) { - return location; - } - Path path = Pathfinder.find(main, location, false, Pathfinder.DUMB); - if (!path.isSuccessful()) { - location = main; - if (!path.getPoints().isEmpty()) { - Point p = path.getPoints().getLast(); - location = Location.create(p.getX(), p.getY(), main.getZ()); - } - } - return location; - } - - @Override - public Location getLocation() { - return this; - } - - /** - * Checks if this location is right next to the node (assuming the node is - * size 1x1). - * @param node The node to check. - * @return {@code True} if this location is 1 tile north, west, south or - * east of the node location. - */ - public boolean isNextTo(Node node) { - Location l = node.getLocation(); - if (l.getY() == y) { - return l.getX() - x == -1 || l.getX() - x == 1; - } - if (l.getX() == x) { - return l.getY() - y == -1 || l.getY() - y == 1; - } - return false; - } - - /** - * Gets the region id. - * @return The region id. - */ - public int getRegionId() { - return (x >> 6) << 8 | (y >> 6); - } - - /** - * Compares the users region with the one given - * @return True if user is in given region - */ - public boolean isInRegion(int region) { - return getRegionId() == region; - } - - /** - * Gets the location incremented by the given coordinates. - * @param dir The direction to transform this location. - * @return The location. - */ - public Location transform(Direction dir) { - return transform(dir, 1); - } - - /** - * Gets the location incremented by the given coordinates. - * @param dir The direction to transform this location. - * @param steps The amount of steps to move in this direction. - * @return The location. - */ - public Location transform(Direction dir, int steps) { - return new Location(x + (dir.getStepX() * steps), y + (dir.getStepY() * steps), this.z); - } - - /** - * Gets the location incremented by the given coordinates. - * @param l incremental location - * @return The location. - */ - public Location transform(Location l) { - return new Location(x + l.getX(), y + l.getY(), this.z + l.getZ()); - } - - /** - * Gets the location incremented by the given coordinates. - * @param diffX The x-difference. - * @param diffY The y-difference. - * @param z The height difference. - * @return The location. - */ - public Location transform(int diffX, int diffY, int z) { - return new Location(x + diffX, y + diffY, this.z + z); - } - - /** - * Checks if the other location is within viewing distance. - * @param other The other location. - * @return If you're within the other distance. - */ - public boolean withinDistance(Location other) { - return withinDistance(other, MapDistance.RENDERING.getDistance()); - } - - /** - * Returns if a player is within a specified distance. - * @param other The other location. - * @param dist The amount of distance. - * @return If you're within the other distance. - */ - public boolean withinDistance(Location other, int dist) { - if (other.z != z) { - return false; - } - - int a = (other.x - x); - int b = (other.y - y); - double product = Math.sqrt((a*a) + (b*b)); - return product <= dist; - } - - /** - * Returns if a player is within a specified distance using max norm distance. - * @param other The other location. - * @param dist The amount of distance. - * @return If you're within the other distance. - */ - public boolean withinMaxnormDistance(Location other, int dist) { - if (other.z != z) { - return false; - } - - int a = Math.abs(other.x - x); - int b = Math.abs(other.y - y); - double max = Math.max(a, b); - return max <= dist; - } - - /** - * Returns the distance between you and the other. - * @param other The other location. - * @return The amount of distance between you and other. - */ - public double getDistance(Location other) { - int xdiff = this.getX() - other.getX(); - int ydiff = this.getY() - other.getY(); - return Math.sqrt(xdiff * xdiff + ydiff * ydiff); - } - - /** - * Returns the distance between the first and the second specified distance. - * @param first The first location. - * @param second The other location. - * @return The amount of distance between first and other. - */ - public static double getDistance(Location first, Location second) { - int xdiff = first.getX() - second.getX(); - int ydiff = first.getY() - second.getY(); - return Math.sqrt(xdiff * xdiff + ydiff * ydiff); - } - - /** - * Gets the 8 tiles surrounding this location as an ArrayList - */ - public ArrayList getSurroundingTiles() { - ArrayList locs = new ArrayList<>(); - - locs.add(transform(-1,-1,0));//SW - locs.add(transform(0,-1,0)); //S - locs.add(transform(1,-1,0)); //SE - locs.add(transform(1,0,0)); //E - locs.add(transform(1,1,0)); //NE - locs.add(transform(0,1,0)); //N - locs.add(transform(-1,1,0));//NW - locs.add(transform(-1,0,0));//W - - return locs; - } - - public ArrayList getCardinalTiles() { - ArrayList locs = new ArrayList<>(); - - locs.add(transform(-1, 0, 0)); - locs.add(transform(0, -1, 0)); - locs.add(transform(1, 0, 0)); - locs.add(transform(0, 1, 0)); - return locs; - } - - /** - * Gets a square of 3 x 3 tiles as an ArrayList - */ - public ArrayList get3x3Tiles() { - ArrayList locs = new ArrayList<>(); - locs.add(transform(0,0,0)); //Center - locs.add(transform(0,1,0)); //N - locs.add(transform(1,1,0)); //NE - locs.add(transform(1,0,0)); //E - locs.add(transform(1,-1,0)); //SE - locs.add(transform(0,-1,0)); //S - locs.add(transform(-1,-1,0));//SW - locs.add(transform(-1,0,0));//W - locs.add(transform(-1,1,0));//NW - return locs; - } - - /** - * Gets the x position on the region chunk. - * @return The x position on the region chunk. - */ - public int getChunkOffsetX() { - int x = getLocalX(); - //return x - ((x / RegionChunk.SIZE) * RegionChunk.SIZE); - return x & 7; - } - - /** - * Gets the y position on the region chunk. - * @return The y position on the region chunk. - */ - public int getChunkOffsetY() { - int y = getLocalY(); - //return y - ((y / RegionChunk.SIZE) * RegionChunk.SIZE); - return y & 7; - } - - /** - * Gets the base location for the chunk this location is in. - * @return The base location. - */ - public Location getChunkBase() { - return create(getRegionX() << 3, getRegionY() << 3, z); - } - - /** - * Gets the region x-coordinate. - * @return The region x-coordinate. - */ - public int getRegionX() { - return x >> 3; - } - - /** - * Gets the region y-coordinate. - * @return The region y-coordinate. - */ - public int getRegionY() { - return y >> 3; - } - - /** - * Gets the local x-coordinate on the current region in [0, 64). - * @return The local x-coordinate. - */ - public int getLocalX() { - return x & 63; - } - - /** - * Gets the local y-coordinate on the current region in [0, 64). - * @return The local y-coordinate. - */ - public int getLocalY() { - return y & 63; - } - - /** - * Gets the scene x-coordinate in [48, 55] (note that 104/2 = 52). - * @return The local x-coordinate. - */ - public int getSceneX() { - return x - ((getRegionX() - 6) << 3); - } - - /** - * Gets the local y-coordinate in [48, 55] (note that 104/2 = 52). - * @return The local y-coordinate. - */ - public int getSceneY() { - return y - ((getRegionY() - 6) << 3); - } - - /** - * Gets the local x-coordinate. - * @param loc The location containing the regional coordinates. - * @return The local x-coordinate. - */ - public int getSceneX(Location loc) { - return x - ((loc.getRegionX() - 6) << 3); - } - - /** - * Gets the local y-coordinate. - * @param loc The location containing the regional coordinates. - * @return The local y-coordinate. - */ - public int getSceneY(Location loc) { - return y - ((loc.getRegionY() - 6) << 3); - } - - /** - * Gets the chunk's x-coordinate (0-7). - * @return The x in the (8x8) region. - */ - public int getChunkX() { - return getLocalX() >> 3; - } - - /** - * Gets the chunk's y-coordinate (0-7). - * @return The y in the (8x8) region. - */ - public int getChunkY() { - return getLocalY() >> 3; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof Location)) { - return false; - } - Location loc = (Location) other; - return loc.x == x && loc.y == y && loc.z == z; - } - - /** - * Checks if these coordinates equal this location. - * @param x the x. - * @param y the y. - * @param z the x. - * @return {@code True} if so. - */ - public boolean equals(int x, int y, int z) { - return equals(new Location(x, y, z)); - } - - @Override - public String toString() { - return "[" + x + ", " + y + ", " + z + "]"; - } - - public static Location fromString(String locString) { - String trimmed = locString.replace("[", "").replace("]", ""); - String[] tokens = trimmed.split(","); - return Location.create( - Integer.parseInt(tokens[0].trim()), - Integer.parseInt(tokens[1].trim()), - Integer.parseInt(tokens[2].trim()) - ); - } - - @Override - public int hashCode() { - return z << 30 | x << 15 | y; - } - - /** - * Gets the x. - * @return The x. - */ - public int getX() { - return x; - } - - /** - * Sets the x. - * @param x The x to set. - */ - public void setX(int x) { - this.x = x; - } - - /** - * Gets the y. - * @return The y. - */ - public int getY() { - return y; - } - - /** - * Sets the y. - * @param y The y to set. - */ - public void setY(int y) { - this.y = y; - } - - /** - * Gets the z. - * @return The z. - */ - public int getZ() { - return z % 4; - } - - /** - * Sets the z. - * @param z The z to set. - */ - public void setZ(int z) { - this.z = z; - } - - @NotNull - public List getStepComponents(Direction dir) { - List output = new ArrayList<>(2); - int stepX = dir.getStepX(); - int stepY = dir.getStepY(); - - if (stepX != 0) output.add(transform(stepX, 0, 0)); - if (stepY != 0) output.add(transform(0, stepY, 0)); - return output; - } - - public Direction deriveDirection(Location location) { - int diffX = location.x - this.x; - int diffY = location.y - this.y; - - diffX = diffX >= 0 ? Math.min(diffX, 1) : -1; - diffY = diffY >= 0 ? Math.min(diffY, 1) : -1; - - StringBuilder sb = new StringBuilder(); - - if (diffY != 0) { - if (diffY > 0) { - sb.append("NORTH"); - } else { - sb.append("SOUTH"); - } - } - - if (diffX != 0) { - if (sb.length() > 0) sb.append("_"); - if (diffX > 0) { - sb.append("EAST"); - } else { - sb.append("WEST"); - } - } - - if (sb.length() == 0) return null; - return Direction.valueOf(sb.toString()); - } - - public Location transform (Vector vector) { - return Location.create(this.x + (int) Math.floor(vector.getX()), this.y + (int) Math.floor(vector.getY())); - } -} diff --git a/Server/src/main/core/game/world/map/Location.kt b/Server/src/main/core/game/world/map/Location.kt new file mode 100644 index 000000000..a202e4a49 --- /dev/null +++ b/Server/src/main/core/game/world/map/Location.kt @@ -0,0 +1,257 @@ +package core.game.world.map + +import core.api.utils.Vector +import core.game.interaction.DestinationFlag +import core.game.node.Node +import core.game.world.map.RegionManager.getTeleportLocation +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import kotlin.math.* + +/** + * Specify a position (x,y,z), implements [Node]. + * - Coordinates x and y can be negative for delta values. Values ±16,383. + * - Coordinate z (level) has a quirk, this class doesn't let you init with a negative z. Values 0 - 3. + */ +/* +Official Terms + - Zones: 8x8 tiles + - Map Squares: 64x64 tiles + - Build Area: 104x104 tiles (13 x 13 chunks centered around player's chunk) - client's loaded area + +Some Definitions: + - Cardinal: Four Base Direction (N E S W) + - Diagonal: Four Diagonal directions (NE SE SW NW) + - Compass: All 8 directions (For this game, compass in relation to 8-point Cardinal+Diagonal) + - Euclidean distance: Straight-line length of two points. Direct calculation. e.g. [2,3] distance=√13(≈3.61) + - Manhattan distance: Cardinal length of two points. Count of steps along grid lines. e.g. [2,3] distance=5 + - Chebyshev distance: Cardinal+Diagonal length of two points. Count of king moves to make. e.g. [2,3] distance=3 + */ +class Location(var hash: LocationHash) : Node(null, null) { + @JvmOverloads + constructor(x: Int, y: Int, z: Int = 0) : this( + LocationHash(x, y, (z % 4 + 4) % 4) // The previous z calc didn't make sense since they play around with negative numbers. + ) + constructor(location: Location) : this(location.hash) + constructor(x: Int, y: Int, z: Int, randomizer: Int) : + this(x + RandomFunction.getRandom(randomizer), y + RandomFunction.getRandom(randomizer), z) + init { super.destinationFlag = DestinationFlag.LOCATION } // This is to set the type of [Node]. + + // Map properties directly to the underlying hash for convenience + var x: Int + get() = hash.x + set(value) { hash = LocationHash(value, y, z) } + + var y: Int + get() = hash.y + set(value) { hash = LocationHash(x, value, z) } + + var z: Int + get() = hash.z + set(value) { hash = LocationHash(x, y, (value % 4 + 4) % 4) } + + companion object { + // Alternate static constructors + @JvmStatic @JvmOverloads fun create(x: Int, y: Int, z: Int = 0): Location = Location(x, y, z) + @JvmStatic fun create(location: Location): Location = Location(location) + /** @return new Location parsed from a string format "[x, y, z]". */ + fun fromString(locString: String): Location { + val coordinates = locString.removeSurrounding("[", "]").split(",").map { it.trim().toInt() } + return create(coordinates[0], coordinates[1], coordinates[2]) + } + + /** @return Straight-line(Euclidean) distance between two locations. */ + @JvmStatic fun getDistance(first: Location, second: Location): Double { + val xDiff: Int = first.x - second.x + val yDiff: Int = first.y - second.y + return sqrt((xDiff * xDiff + yDiff * yDiff).toDouble()) + } + + /** @return A location representing the delta between two locations. This is not a good function because it doesn't care about z. */ + @JvmStatic fun getDelta(location: Location, other: Location): Location = create(other.x - location.x, other.y - location.y, other.z - location.z) + + /** @return A random location within radius, optionally verifying reachability. */ + fun getRandomLocation(main: Location, radius: Int, reachable: Boolean): Location { + val loc = getTeleportLocation(main, radius) + if (!reachable) return loc + val path = Pathfinder.find(main, loc, false, Pathfinder.DUMB) + if (!path.isSuccessful && path.points.isNotEmpty()) { + return create(path.points.last.x, path.points.last.y, main.z) + } else if (path.isSuccessful) { + return loc + } else { + return main + } + } + } + + // Function overrides of Node class and Java class + override fun getLocation(): Location = this + override fun toString(): String = "[$x, $y, $z]" + override fun hashCode(): Int = hash.hash + override fun equals(other: Any?): Boolean { + return when (other) { + is Location -> other.hash == this.hash + is LocationHash -> other == this.hash + else -> false + } + } + fun equals(x: Int, y: Int, z: Int): Boolean = hash == LocationHash(x, y, z) + + // Derived variables. Please note the following isn't a 1-1 representation of what is officially used. + + // Region - (Officially: Map Square) 64x64 + /** Unique index "key" (Officially: region_uid) for a 64x64 area. Made of x and y joined bitwise together. Used in xteas.json. */ + val regionId: Int get() = x shr 6 shl 8 or (y shr 6) // Cuts off the end 6 bits of both x y and joins them together. E.g. 10392 + /** The chunk x index for this position (x/8). For sets of 8x8 area. THIS IS NAMED WRONG, THIS IS A CHUNK(8) NOT REGION(64). */ + val regionX: Int get() = x shr 3 // shr 3 is essentially divide by 8 + /** The chunk y index for this position (y/8). For sets of 8x8 area. THIS IS NAMED WRONG, THIS IS A CHUNK(8) NOT REGION(64). */ + val regionY: Int get() = y shr 3 // shr 3 is essentially divide by 8 + // Local - x,y position inside a region + /** The relative x position inside a region(64x64). */ + val localX: Int get() = x and 63 // and 63 is essentially modulo 64 + /** The relative y position inside a region(64x64). */ + val localY: Int get() = y and 63 // and 63 is essentially modulo 64 + /** @return Check if it is in the same region id. */ + fun isInRegion(region: Int): Boolean = regionId == region + + // Chunk - (Officially: Zones) 8x8 + val chunkBase: Location get() = create(regionX shl 3, regionY shl 3, z) + /** The chunk x index for this position RELATIVE to a region[localX](x/8). THIS IS NOT GLOBAL CHUNK X. */ + val chunkX: Int get() = localX shr 3 // shr 3 is essentially divide by 8 (note this is localX) + /** The chunk y index for this position RELATIVE to a region[localY](y/8). THIS IS NOT GLOBAL CHUNK Y. */ + val chunkY: Int get() = localY shr 3 // shr 3 is essentially divide by 8 (note this is localX) + /** The relative x position inside a chunk(8x8). */ + val chunkOffsetX: Int get() = localX and 7 // and 7 is essentially modulo 8 + /** The relative y position inside a chunk(8x8). */ + val chunkOffsetY: Int get() = localY and 7 // and 7 is essentially modulo 8 + + // Scene - (Officially: Build Area) 104x104 - Made of 13x13 chunks(8x8) + /** The relative x position inside a scene(104x104). Used for client viewport rendering. */ + val sceneX: Int get() = x - (regionX - 6 shl 3) // Centers the current region at [7chunk,7chunk] + /** The relative y position inside a scene(104x104). Used for client viewport rendering. */ + val sceneY: Int get() = y - (regionY - 6 shl 3) // Centers the current region at [7chunk,7chunk] + /** @return The local scene x-coordinate relative to another location's regionX. */ + fun getSceneX(loc: Location): Int = x - (loc.regionX - 6 shl 3) + /** @return The local scene y-coordinate relative to another location's regionY. */ + fun getSceneY(loc: Location): Int = y - (loc.regionY - 6 shl 3) + + + + /** @return The location incremented by another location's coordinates. (POTENTIAL Z PROBLEMS HERE) */ + // TODO: THE FOLLOWING TRANSFORM HAS SHIT Z HANDLING. + fun transform(l: Location): Location = Location(x + l.x, y + l.y, (z + l.z) % 4) + /** @return The location incremented by specific x, y, z differences. */ + fun transform(diffX: Int, diffY: Int, z: Int): Location = Location(x + diffX, y + diffY, (this.z + z) % 4) + /** @return The location incremented by direction and steps. */ + @JvmOverloads fun transform(dir: Direction, steps: Int = 1): Location = Location(x + dir.stepX * steps, y + dir.stepY * steps, z) + /** Location transformed by a Vector. Limit usage to more complicated functionality. */ + fun transform(vector: Vector): Location = create(x + floor(vector.x).toInt(), y + floor(vector.y).toInt()) + + + /** @return True if this location is 1 tile N, W, S, or E of the node. THIS CAN BE REFACTORED OUT. */ + fun isNextTo(node: Node): Boolean { + val l = node.location + return if (l.y == y) abs(l.x - x) == 1 else if (l.x == x) abs(l.y - y) == 1 else false + } + + /** @return True if this other location is within dist of this location. */ + @JvmOverloads fun withinDistance(other: Location, dist: Int = MapDistance.RENDERING.distance): Boolean { + if (other.z != z) return false + return getDistance(this, other) <= dist + } + + /** @return True if within specified distance using max norm (Chebyshev) distance. */ + fun withinMaxnormDistance(other: Location, dist: Int): Boolean = if (other.z != z) false else max(abs(other.x - x), abs(other.y - y)) <= dist + + /** @return The straight-line(Euclidean) distance between this and another location. */ + fun getDistance(other: Location): Double = getDistance(this, other) + + /** @returns ArrayList of the 8 cardinal and diagonal tiles. Order is important and follows [Direction] indexing **/ + val surroundingTiles: ArrayList get() { + val locations = ArrayList() + locations.add(transform(-1, -1, 0)) + locations.add(transform(0, -1, 0)) + locations.add(transform(1, -1, 0)) + locations.add(transform(1, 0, 0)) + locations.add(transform(1, 1, 0)) + locations.add(transform(0, 1, 0)) + locations.add(transform(-1, 1, 0)) + locations.add(transform(-1, 0, 0)) + return locations + } + + /** @returns ArrayList of the 4 cardinal direction tiles. Order is important and follows [Direction] indexing **/ + val cardinalTiles: ArrayList get() { + val locations = ArrayList() + locations.add(transform(-1, 0, 0)) + locations.add(transform(0, -1, 0)) + locations.add(transform(1, 0, 0)) + locations.add(transform(0, 1, 0)) + return locations + } + + + /** + * Gets the directional components of a movement step. + * TODO: would prefer this in the other place. This doesn't exactly belong here since this isn't a common function for other instances of Location + * + * we can move diagonally but there's no melee attacking diagonally. its gotta be from N, W, S or E. + * if we are moving diagonally, we then need to check if we can attack from one of the valid directions. + * in other words we need to check the two tiles that share a corner with our destination and make sure they can be attacked from + * + * picture this: you are at (0,0). im at (1,1). you want to strangle my head off, so you got to check + * 1. to the west of destination: (1,1) + (-1,0) = (0,1) or north from where you started + * 2. to the south of the destination: (1,1) + (0,-1) = (1,0) or east from where you started + * this function is used only by CombatSwingHandler.kt and assumes that we return the X tiles, west or east, FIRST + * and then the Y tiles South and North. + */ + fun getStepComponents(dir: Direction): List { + val output = ArrayList(2) + if (dir.stepX != 0) output.add(transform(-dir.stepX, 0, 0)) + if (dir.stepY != 0) output.add(transform(0, -dir.stepY, 0)) + return output + } + + /** @return the Direction of the another location relative to this one. */ + fun deriveDirection(location: Location): Direction? { + val dx = (location.x - x).let { if (it >= 0) min(it, 1) else -1 } + val dy = (location.y - y).let { if (it >= 0) min(it, 1) else -1 } + val sb = StringBuilder() + if (dy != 0) sb.append(if (dy > 0) "NORTH" else "SOUTH") + if (dx != 0) { if (sb.isNotEmpty()) sb.append("_"); sb.append(if (dx > 0) "EAST" else "WEST") } + return if (sb.isEmpty()) null else Direction.valueOf(sb.toString()) + } + + /** + * Locations as an Integer rather than a Location object. This is for space efficiency. + * Inner class, because this is only used here, and to avoid adding another standard until this replaces Location + * + * 32 bits for an int (z z x x x x x x x x x x x x x x x y y y y y y y y y y y y y y y) + * - Rightmost set of 15 bits is for y (can handle negative numbers) + * - Middle set of 15 bits is for x (can handle negative numbers) + * - Leftmost set of 2 bits is for z + * + * Since x and y occupy 15 bits (0 to 32,767) it becomes => 1 sign + 14 bits (e.g., 16,384) for range of ±16,383. + */ + @JvmInline + value class LocationHash(val hash: Int) { + constructor(x: Int, y: Int, z: Int = 0) : this( + ((z and 0x3) shl 30) or + ((x and 0x7FFF) shl 15) or + (y and 0x7FFF) + ) + val x: Int get() { + val raw = (hash ushr 15) and 0x7FFF + // If the 15th bit is set, it's a negative number in 15-bit range + return if (raw >= 0x4000) raw - 0x8000 else raw + } + + val y: Int get() { + val raw = hash and 0x7FFF + // If the 15th bit is set, it's a negative number + return if (raw >= 0x4000) raw - 0x8000 else raw + } + val z: Int get() = hash ushr 30 + } +} diff --git a/Server/src/main/core/game/world/map/Region.java b/Server/src/main/core/game/world/map/Region.java index c615df34a..ff87d8e6b 100644 --- a/Server/src/main/core/game/world/map/Region.java +++ b/Server/src/main/core/game/world/map/Region.java @@ -11,7 +11,6 @@ import core.game.world.map.build.LandscapeParser; import core.game.world.map.build.MapscapeParser; import core.game.world.map.zone.RegionZone; import core.tools.Log; -import core.tools.SystemLogger; import core.game.system.config.XteaParser; import core.game.world.GameWorld; import core.game.world.repository.Repository; @@ -62,7 +61,12 @@ public class Region { private final List regionZones = new ArrayList<>(20); /** - * The music zones lying in this region. + * The region-wide music track ID for this region. + */ + private int music = -1; + + /** + * Any tile-specific music zones lying in this region. */ private final List musicZones = new ArrayList<>(20); @@ -268,14 +272,14 @@ public class Region { } } - public boolean flagInactive(boolean force) { - if (unload(this, force)) { - active = false; - return true; - } else { - return false; - } - } + public boolean flagInactive(boolean force) { + if (unload(this, force)) { + active = false; + return true; + } else { + return false; + } + } /** * Flags the region as inactive. @@ -345,7 +349,7 @@ public class Region { } } - public static boolean unload(Region r) { + public static boolean unload(Region r) { return unload(r, false); } @@ -374,10 +378,10 @@ public class Region { } } } - if (r.isBuild()) - r.setLoaded(false); - r.activityPulse.stop(); - return true; + if (r.isBuild()) + r.setLoaded(false); + r.activityPulse.stop(); + return true; } /** @@ -473,6 +477,21 @@ public class Region { return planes; } + /** + * Sets the region-wide music track. + */ + public void setMusic(int music) { + this.music = music; + } + + /** + * Gets the region-wide music track + * @return The music entry ID + */ + public int getMusic() { + return this.music; + } + /** * Gets the regionZones. * @return The regionZones. diff --git a/Server/src/main/core/game/world/map/RegionManager.kt b/Server/src/main/core/game/world/map/RegionManager.kt index 91ccf4f25..9fb7b848b 100644 --- a/Server/src/main/core/game/world/map/RegionManager.kt +++ b/Server/src/main/core/game/world/map/RegionManager.kt @@ -312,23 +312,37 @@ object RegionManager { if (owner == null || node == null) { return null } - var destination: Location? = null outer@ for (i in 0..7) { val dir = Direction.get(i) - inner@for(j in 0 until node.size()) { - val l = owner.location.transform(dir, j) - for (x in 0 until node.size()) { - for (y in 0 until node.size()) { - if (isClipped(l.transform(x, y, 0))) { - continue@inner - } + var stepX = dir.stepX + var stepY = dir.stepY + // For objects that are larger than 1, the below corrects for the fact that their origin is on the SW tile + if (dir.stepX < 0) { + stepX -= (node.size() - 1) + } + if (dir.stepY < 0) { + stepY -= (node.size() - 1) + } + if (owner.size() > 1) { //e.g. if you used ::pnpc to morph yourself into a large NPC + if (dir.stepX > 0) { + stepX += (owner.size() - 1) + } + if (dir.stepY > 0) { + stepY += (owner.size() - 1) + } + } + val l = owner.location.transform(stepX, stepY, 0) + // Check if ALL target tiles are unclipped + for (x in 0 until node.size()) { + for (y in 0 until node.size()) { + if (isClipped(l.transform(x, y, 0))) { + continue@outer } } - destination = l - break@outer } + return l } - return destination + return null } /** @@ -769,10 +783,10 @@ object RegionManager { for (regionX in ((l.regionX - 6) shr 3)..((l.regionX + 6) shr 3)) { for (regionY in ((l.regionY - 6) shr 3)..((l.regionY + 6) shr 3)) { for (player in forId((regionX shl 8) or regionY).planes[l.z].players) { - if (player.location.x >= l.getX() - xdist && - player.location.x <= l.getX() + xdist && - player.location.y >= l.getY() - ydist && - player.location.y <= l.getY() + ydist) { + if (player.location.x >= l.x - xdist && + player.location.x <= l.x + xdist && + player.location.y >= l.y - ydist && + player.location.y <= l.y + ydist) { players.add(player) } } diff --git a/Server/src/main/core/game/world/map/RegionPlane.java b/Server/src/main/core/game/world/map/RegionPlane.java index 6557bf62b..f83724ec0 100644 --- a/Server/src/main/core/game/world/map/RegionPlane.java +++ b/Server/src/main/core/game/world/map/RegionPlane.java @@ -257,13 +257,21 @@ public final class RegionPlane { public void add(GroundItem item) { Location l = item.getLocation(); RegionChunk c = getRegionChunk(l.getLocalX() / RegionChunk.SIZE, l.getLocalY() / RegionChunk.SIZE); + // This adds it to the chunk to be interactable with. if (!c.getItems().add(item)) { return; } GroundItem g = (GroundItem) item; if (g.isPrivate()) { if (g.getDropper() != null) { - PacketRepository.send(ConstructGroundItem.class, new BuildItemContext(g.getDropper(), item)); + // Limit it to the region(8x8 square) you are in +/-2 regions, as the chunk loader will load it all over again. + // This is based on MapChunkRenderer which seems to "update" 2 chunks away. + // Look at RegionChunk.java ConstructGroundItem.write(buffer, item); + if (Math.abs(g.getDropper().getLocation().getRegionX() - l.getRegionX()) <= 2 && + Math.abs(g.getDropper().getLocation().getRegionY() - l.getRegionY()) <= 2 && + g.getDropper().getLocation().getZ() == l.getZ()) { + PacketRepository.send(ConstructGroundItem.class, new BuildItemContext(g.getDropper(), item)); + } } return; } diff --git a/Server/src/main/core/game/world/map/zone/MapZone.java b/Server/src/main/core/game/world/map/zone/MapZone.java index 630d06194..7adb16dfc 100644 --- a/Server/src/main/core/game/world/map/zone/MapZone.java +++ b/Server/src/main/core/game/world/map/zone/MapZone.java @@ -130,12 +130,25 @@ public abstract class MapZone implements Zone { } /** - * Checks if the entity is able to continue attacking the target. - * @param e the attacking entity. - * @param target The target. - * @param style The combat style used. - * @param message If a message should be send. - * @return {@code True} if so. + * Checks if the entity is able to continue attacking the target within this zone. + * + *

This method is called during attack validation to determine if zone-specific rules + * allow the attack to proceed. It's invoked by + * {@link core.game.world.map.zone.ZoneMonitor#continueAttack(Node, CombatStyle, boolean)} + * for each zone the attacking entity is in.

+ * + *

The default implementation returns {@code true}, allowing the attack to proceed. + * Subclasses should override this method to implement zone-specific attack restrictions.

+ *

This method is part of the attack validation chain: + * {@link Entity#isAttackable(Entity, CombatStyle, boolean)} -> + * {@link core.game.world.map.zone.ZoneMonitor#continueAttack(Node, CombatStyle, boolean)} -> + * {@code MapZone.continueAttack()} + {@link Entity#continueAttack(Entity, CombatStyle, boolean)}

+ * + * @param e the attacking entity + * @param target the target node being attacked + * @param style the combat style being used + * @param message whether to send a message to the player explaining why the attack cannot continue + * @return {@code true} if the zone allows the attack to continue */ public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { return true; @@ -164,14 +177,23 @@ public abstract class MapZone implements Zone { if (multi || e.isIgnoreMultiBoundaries(t) || e.getZoneMonitor().isIgnoreMultiBoundaries(t)) { return true; } + Entity attacker = e instanceof Familiar ? ((Familiar) e).getOwner() : e; Entity target = t.getAttribute("combat-attacker", e); - if (t.getAttribute("combat-time", -1L) > time && target != e && target.isActive()) { + if (target instanceof Familiar) { + target = ((Familiar) target).getOwner(); + } + if (t.getAttribute("combat-time", -1L) > time && target != attacker && target.isActive()) { if (message && e instanceof Player) { ((Player) e).getPacketDispatch().sendMessage("Someone else is already fighting this" + (t instanceof Player ? " player." : ".")); } return false; } - if (e.getAttribute("combat-time", -1L) > time && (target = e.getAttribute("combat-attacker", t)) != t && target.isActive()) { + Entity attackerOnE = e.getAttribute("combat-attacker", t); + if (attackerOnE instanceof Familiar) { + attackerOnE = ((Familiar) attackerOnE).getOwner(); + } + Entity tResolved = t instanceof Familiar ? ((Familiar) t).getOwner() : t; + if (e.getAttribute("combat-time", -1L) > time && attackerOnE != tResolved && attackerOnE.isActive()) { if (t.getId() == 1614 || t.getId() == 1613) { return true; } diff --git a/Server/src/main/core/game/world/map/zone/ZoneMonitor.java b/Server/src/main/core/game/world/map/zone/ZoneMonitor.java index c592b398c..65b4a0322 100644 --- a/Server/src/main/core/game/world/map/zone/ZoneMonitor.java +++ b/Server/src/main/core/game/world/map/zone/ZoneMonitor.java @@ -5,6 +5,7 @@ import core.game.node.Node; import core.game.node.entity.Entity; import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.music.MusicEntry; import core.game.node.entity.player.link.music.MusicZone; import core.game.node.entity.player.link.request.RequestType; import core.game.node.item.Item; @@ -15,6 +16,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import core.game.world.map.Region; import org.rs09.consts.Items; /** @@ -24,12 +26,12 @@ import org.rs09.consts.Items; public final class ZoneMonitor { /** - * The set of dragonstone teleport jewellery, which allow teleporting from up to and including level 30 wildy. - * Used to check if a player can teleport from 20 < level <= 30 wildy, see canTeleportByDragonstoneJewellery. + * The set of jewellery which allow teleporting from up to and including level 30 wildy. + * Used to check if a player can teleport from 20 < level <= 30 wildy, see canTeleportByJewellery. * Note: the check is based on the nextJewellery (see EnchantedJewellery.kt), so this list should not contain the (4) items, and should contain the empty ones. * @author Player Name */ - static final Set DRAGONSTONE_TELEPORT_JEWELLERY = Set.of( + static final Set MID_WILDY_TELEPORT_JEWELLERY = Set.of( Items.AMULET_OF_GLORY_1704, Items.AMULET_OF_GLORY1_1706, Items.AMULET_OF_GLORY2_1708, @@ -49,7 +51,8 @@ public final class ZoneMonitor { Items.RING_OF_WEALTH_14638, Items.RING_OF_WEALTH1_14640, Items.RING_OF_WEALTH2_14642, - Items.RING_OF_WEALTH3_14644 + Items.RING_OF_WEALTH3_14644, + Items.RING_OF_LIFE_2570 ); /** @@ -235,7 +238,7 @@ public final class ZoneMonitor { * @return {@code True} if so. */ public boolean teleport(int type, Node node) { - if (type != -1 && entity.isTeleBlocked() && !canTeleportByDragonstoneJewellery(type, node)) { + if (type != -1 && entity.isTeleBlocked() && !canTeleportByJewellery(type, node)) { if (entity.isPlayer()) { entity.asPlayer().sendMessage("A magical force has stopped you from teleporting."); } @@ -250,11 +253,11 @@ public final class ZoneMonitor { } /** - * Checks if a player can teleport with a dragonstone jewellery piece in >= 1 <= 30 wilderness level + * Checks if a player can teleport with a jewellery piece in >= 1 <= 30 wilderness level * @return {@code True} if so. */ - private boolean canTeleportByDragonstoneJewellery(int type, Node node) { - if (type != 1 || !DRAGONSTONE_TELEPORT_JEWELLERY.contains(node.asItem().getId())) { + private boolean canTeleportByJewellery(int type, Node node) { + if (type != 1 || !MID_WILDY_TELEPORT_JEWELLERY.contains(node.asItem().getId())) { return false; } if (entity.timers.getTimer("teleblock") != null) @@ -395,21 +398,25 @@ public final class ZoneMonitor { for (Iterator it = musicZones.iterator(); it.hasNext();) { MusicZone zone = it.next(); if (!zone.getBorders().insideBorder(l.getX(), l.getY())) { - zone.leave(player, false); - it.remove(); + if (zone.leave(player, false)) { + it.remove(); + } } } - for (MusicZone zone : player.getViewport().getRegion().getMusicZones()) { - if (!zone.getBorders().insideBorder(l.getX(), l.getY())) { - continue; - } - if (!musicZones.contains(zone)) { + Region r = player.getViewport().getRegion(); + for (MusicZone zone : r.getMusicZones()) { + if (zone.getBorders().insideBorder(l.getX(), l.getY())) { zone.enter(player); - musicZones.add(zone); + return; } } - if (musicZones.isEmpty() && !player.getMusicPlayer().isPlaying()) { - player.getMusicPlayer().playDefault(); + int music = r.getMusic(); + if (music == -1) { + if (!player.getMusicPlayer().isPlaying()) { + player.getMusicPlayer().playDefault(); + } + } else { + player.getMusicPlayer().unlock(music, true); } } diff --git a/Server/src/main/core/game/world/map/zone/ZoneRestriction.java b/Server/src/main/core/game/world/map/zone/ZoneRestriction.java index f73b50014..64dd971db 100644 --- a/Server/src/main/core/game/world/map/zone/ZoneRestriction.java +++ b/Server/src/main/core/game/world/map/zone/ZoneRestriction.java @@ -31,7 +31,7 @@ public enum ZoneRestriction { */ CANNON, /** - * Do not spawn a grave if a player dies here + * Do not spawn a grave if a player dies here. */ GRAVES, @@ -39,6 +39,14 @@ public enum ZoneRestriction { * No teleporting allowed. */ TELEPORT, + + /** + * This region is not a part of the normal overworld or cave system. + * Used for temporary areas that use the 'original-loc' attribute to teleport the player back when they are done in the area. + * Example: non-dynamic/non-instanced random-event areas (e.g. Damien's bootcamp) + * Dynamic regions are implicitly off-map and do not require this attribute. + */ + OFF_MAP, ; /** @@ -48,4 +56,4 @@ public enum ZoneRestriction { public int getFlag() { return 1 << ordinal(); } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/world/map/zone/impl/DarkZone.java b/Server/src/main/core/game/world/map/zone/impl/DarkZone.java index 1340dcde2..5d955031a 100644 --- a/Server/src/main/core/game/world/map/zone/impl/DarkZone.java +++ b/Server/src/main/core/game/world/map/zone/impl/DarkZone.java @@ -85,6 +85,7 @@ public final class DarkZone extends MapZone implements EventHook{ public void configure() { register(new ZoneBorders(1728, 5120, 1791, 5247)); registerRegion(12693); + registerRegion(12948); registerRegion(12949); register(new ZoneBorders(3306,9661,3222,9600)); register(new ZoneBorders(3717,9473,3841,9346)); diff --git a/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java b/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java index f2b5a5886..77477b3b1 100644 --- a/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java +++ b/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java @@ -85,6 +85,9 @@ public final class MultiwayCombatZone extends MapZone { register(new ZoneBorders(3097, 4224, 3225, 4317)); register(new ZoneBorders(3116, 5412, 3362, 5584)); register(new ZoneBorders(3078, 5520, 3123, 5552, 0)); + // Ice queen + register(new ZoneBorders(2855, 9928, 2880, 9968)); + registerRegion(11318); //White wolf mountain registerRegion(11844); //Corporeal beast registerRegion(10329);//TDS registerRegion(13370);//Venenatis diff --git a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java index 6b1f27270..cce6ab1d4 100644 --- a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java +++ b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java @@ -2,7 +2,6 @@ package core.game.world.map.zone.impl; import content.global.handlers.item.equipment.brawling_gloves.BrawlingGloves; import content.global.skill.summoning.familiar.Familiar; -import content.region.wilderness.handlers.DeepWildyThreat; import core.game.component.Component; import core.game.interaction.Option; import core.game.node.Node; @@ -23,6 +22,7 @@ import core.game.world.map.zone.ZoneBorders; import core.game.world.map.zone.ZoneRestriction; import core.game.world.repository.Repository; import core.tools.RandomFunction; +import org.rs09.consts.Items; import org.rs09.consts.NPCs; @@ -41,8 +41,8 @@ public final class WildernessZone extends MapZone { */ private static final WildernessZone INSTANCE = new WildernessZone(new ZoneBorders(2944, 3525, 3400, 3975), new ZoneBorders(3070, 9924, 3135, 10002), ZoneBorders.forRegion(12192), ZoneBorders.forRegion(12193), ZoneBorders.forRegion(11937)); - public static final String WILDERNESS_PROT_ATTR = "/save:wilderness-protection-active"; - public static final String WILDERNESS_HIGHER_NEXTFEE = "/save:wilderness-higher-next-fee"; + public static final String WILDERNESS_PROT_ATTR = "/save:wilderness-protection-active"; + public static final String WILDERNESS_HIGHER_NEXTFEE = "/save:wilderness-higher-next-fee"; /** * The zone borders. @@ -92,50 +92,39 @@ public final class WildernessZone extends MapZone { } private void rollWildernessExclusiveLoot(Entity e, Entity killer) { - if (!(killer instanceof Player)) return; + if (!(killer instanceof Player)) return; + if (!(e instanceof NPC)) return; + if (!(e.getId() == NPCs.CHAOS_ELEMENTAL_3200 || e.asNpc().getName().contains("Revenant"))) return; - boolean isDeepWildy = ((Player) killer).getSkullManager().isDeepWilderness(); - boolean isRevOrCele = e.asNpc().getName().contains("Revenant") || e.getId() == NPCs.CHAOS_ELEMENTAL_3200; - boolean isSufficientRisk = ((Player) killer).getAttribute("deepwild-value-risk", 0L) > SkullManager.DEEP_WILD_DROP_RISK_THRESHOLD; - boolean isValidTarget = e instanceof NPC && ((isDeepWildy && isSufficientRisk) || isRevOrCele); + int pvpGearRate = getNewDropRate(e.asNpc().getDefinition().getCombatLevel()); + boolean higherRate = ((Player) killer).getSkullManager().isDeepWilderness() && ((Player) killer).getAttribute("deepwild-value-risk", 0L) > SkullManager.DEEP_WILD_DROP_RISK_THRESHOLD; + if (higherRate) { + pvpGearRate /= 2; + } + int cEleGloveRate = 50; + int normalGloveRate = higherRate ? 100 : (int) ((1.0 / (1.0 - Math.pow(1.0 - (1.0 / (double) pvpGearRate), 16.0))) * 5.0 / 6.0); - if (isDeepWildy) { - DeepWildyThreat.adjustThreat((Player) killer, 50); + if (RandomFunction.roll(e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? cEleGloveRate : normalGloveRate)) { + byte glove = (byte) RandomFunction.random(1, 14); + Item reward = new Item(BrawlingGloves.forIndicator(glove).getId()); + GroundItemManager.create(reward, e.asNpc().getDropLocation(), killer.asPlayer()); + String npcString = e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? "the Chaos Elemental" : ("a " + e.asNpc().getName().toLowerCase()); + Repository.sendNews(killer.getUsername() + " has received " + reward.getName().toLowerCase() + " from " + npcString + "!"); + } + for (int j : PVP_GEAR) { + boolean chance = RandomFunction.roll(pvpGearRate); + if (chance) { + Item reward; + if (j == Items.MORRIGANS_JAVELIN_13879 || j == Items.MORRIGANS_THROWING_AXE_13883) { + reward = new Item(j, RandomFunction.random(15, 50)); + } else { + reward = new Item(j); } - - if (!isValidTarget) return; - - int pvpGearRate = getNewDropRate(e.asNpc().getDefinition().getCombatLevel()); - if (isDeepWildy && isRevOrCele) - pvpGearRate /= 2; - - int cEleGloveRate = isDeepWildy ? 50 : 150; - int normalGloveRate = isDeepWildy && isRevOrCele ? 100 : (int)((1.0/(1.0-Math.pow(1.0 - (1.0/(double)pvpGearRate), 16.0))) * 5.0 / 6.0); - - if (RandomFunction.roll(e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? cEleGloveRate : normalGloveRate)) { - byte glove = (byte) RandomFunction.random(1, 13); - Item reward = new Item(BrawlingGloves.forIndicator(glove).getId()); - GroundItemManager.create(reward, e.asNpc().getDropLocation(), killer.asPlayer()); - Repository.sendNews(killer.getUsername() + " has received " + reward.getName().toLowerCase() + " from a " + e.asNpc().getName() + "!"); - if (isDeepWildy) - DeepWildyThreat.adjustThreat((Player) killer, 750); - } - - for (int j : PVP_GEAR) { - boolean chance = RandomFunction.roll(pvpGearRate); - if (chance) { - Item reward; - if (j == 13879 || j == 13883) { // checks if it's a javelin or throwing axe - reward = new Item(j, RandomFunction.random(15, 50)); - } else { - reward = new Item(j); - } - Repository.sendNews(killer.asPlayer().getUsername() + " has received a " + reward.getName() + " from a " + e.asNpc().getName() + "!"); - GroundItemManager.create(reward, ((NPC) e).getDropLocation(), killer.asPlayer()); - if (isDeepWildy) - DeepWildyThreat.adjustThreat((Player) killer, 3000); - } - } + GroundItemManager.create(reward, ((NPC) e).getDropLocation(), killer.asPlayer()); + String npcString = e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? "the Chaos Elemental" : ("a " + e.asNpc().getName().toLowerCase()); + Repository.sendNews(killer.asPlayer().getUsername() + " has received a " + reward.getName() + " from " + npcString + "!"); + } + } } /** @@ -156,8 +145,6 @@ public final class WildernessZone extends MapZone { return super.interact(e, target, option); } - - @Override public boolean enter(Entity e) { if (e instanceof Player) { @@ -168,17 +155,6 @@ public final class WildernessZone extends MapZone { p.getSkullManager().setWilderness(true); p.getSkullManager().setLevel(getWilderness(p)); } - for (int i = 0; i < 7; i++) { - if (i == 5 || i == 3) { - continue; - } - if(p.getAttributes().containsKey("overload") || p.getSkills().getLevel(i) > 118){ - if (p.getSkills().getLevel(i) > p.getSkills().getStaticLevel(i)) { - p.getSkills().setLevel(i, p.getSkills().getStaticLevel(i)); - p.removeAttribute("overload"); - } - } - } if (p.getFamiliarManager().hasFamiliar() && !p.getFamiliarManager().hasPet()) { Familiar familiar = p.getFamiliarManager().getFamiliar(); familiar.transform(); @@ -287,6 +263,23 @@ public final class WildernessZone extends MapZone { return false; } } + if (e instanceof Player && target instanceof NPC && ((NPC) target).getName().contains("Revenant")) { + Player p = (Player) e; + NPC npc = (NPC) target; + int level = p.getSkullManager().getLevel(); + int npcWildLevel = getWilderness(npc); + if (npcWildLevel < level) { + level = npcWildLevel; + } + int combat = p.getProperties().getCurrentCombatLevel(); + int npcCombat = npc.getDefinition().getCombatLevel(); + if (combat - level > npcCombat || combat + level < npcCombat) { + if (message) { + p.getPacketDispatch().sendMessage("The level difference between you and your opponent is too great."); + } + return false; + } + } return true; } @@ -324,12 +317,12 @@ public final class WildernessZone extends MapZone { * @return the level. */ public static int getWilderness(Entity e) { - int y = e.getLocation().getY(); - if(6400 < y) { - return ((y - 9920) / 8) + 1; - } else { - return ((y - 3520) / 8) + 1; - } + int y = e.getLocation().getY(); + if(6400 < y) { + return ((y - 9920) / 8) + 1; + } else { + return ((y - 3520) / 8) + 1; + } } /** diff --git a/Server/src/main/core/game/world/repository/DisconnectionQueue.kt b/Server/src/main/core/game/world/repository/DisconnectionQueue.kt index b1fcf12ea..dd0c7ee98 100644 --- a/Server/src/main/core/game/world/repository/DisconnectionQueue.kt +++ b/Server/src/main/core/game/world/repository/DisconnectionQueue.kt @@ -4,11 +4,9 @@ import core.api.log import core.game.node.entity.player.Player import core.game.node.entity.player.info.login.PlayerParser import core.game.system.task.TaskExecutor -import core.tools.SystemLogger import core.game.world.GameWorld import core.tools.Log -import java.util.* -import java.util.concurrent.ConcurrentHashMap +import core.tools.secondsToTicks /** * Handles disconnecting players queuing. @@ -37,7 +35,10 @@ class DisconnectionQueue { else { //Make sure there's no room for the disconnection queue to stroke out and leave someone logged in for 10 years. queueTimers[it.key] = (queueTimers[it.key] ?: 0) + 3 - if ((queueTimers[it.key] ?: Int.MAX_VALUE) >= 1500) { + val isValidAFKLogout = it.value?.player?.isAfkLogout == true + val seconds = if (isValidAFKLogout) 30 else 5 * 60 //30 seconds for AFK logout, 5 minutes for normal logout + val ticksNeeded = secondsToTicks(seconds) + if ((queueTimers[it.key] ?: Int.MAX_VALUE) >= ticksNeeded) { it.value?.player?.let { player -> player.finishClear() Repository.removePlayer(player) diff --git a/Server/src/main/core/game/world/repository/Repository.kt b/Server/src/main/core/game/world/repository/Repository.kt index 575bcb0f2..0b97f197c 100644 --- a/Server/src/main/core/game/world/repository/Repository.kt +++ b/Server/src/main/core/game/world/repository/Repository.kt @@ -1,15 +1,17 @@ package core.game.world.repository -import core.game.node.entity.npc.NPC import content.region.wilderness.handlers.revenants.RevenantNPC +import core.ServerConstants +import core.api.sendMessage +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.RegionManager -import core.ServerConstants import core.game.world.update.UpdateSequence -import java.util.* import java.util.concurrent.CopyOnWriteArrayList +const val GE_NEWS_MUTE_ATTRIBUTE = "/save:ge:news-mute" + /** * The repository holding all node lists, etc in the game world. * @author Emperor @@ -55,20 +57,7 @@ object Repository { */ @JvmStatic val disconnectionQueue = DisconnectionQueue() - /** - * Sends a market update message to all players. - * @param string The string. - * @param color The color. - */ - @JvmOverloads - fun sendMarketUpdate(string: String, icon: Int = 12, color: String = "") { - val players: Array = playerNames.values.toTypedArray() - val size = players.size - for (i in 0 until size) { - val player = players[i] as Player ?: continue - player.sendMessage("" + color + "Market Update: " + string) - } - } + /** * Send a news message to all players. * @param string The string. @@ -76,11 +65,23 @@ object Repository { */ @JvmStatic fun sendNews(string: String, icon: Int = 12, color: String = "CC6600") { + sendNews(string, icon, color, false) + } + + @JvmStatic + fun sendGrandExchangeNews(string: String, icon: Int = 12, color: String = "CC6600") { + sendNews(string, icon, color, true) + } + + @JvmStatic + fun sendNews(string: String, icon: Int, color: String, isGeNews: Boolean) { + if (!ServerConstants.ENABLE_GLOBAL_CHAT) return val players: Array = playerNames.values.toTypedArray() val size = players.size for (i in 0 until size) { - val player = players[i] as Player ?: continue - player.sendMessage("News: $string") + val player = players[i] as? Player ?: continue + if (isGeNews && player.getAttribute(GE_NEWS_MUTE_ATTRIBUTE, false)) continue + sendMessage(player, "News: $string") } } diff --git a/Server/src/main/core/game/world/update/PlayerRenderer.kt b/Server/src/main/core/game/world/update/PlayerRenderer.kt index 0fb1068bc..e192463d7 100644 --- a/Server/src/main/core/game/world/update/PlayerRenderer.kt +++ b/Server/src/main/core/game/world/update/PlayerRenderer.kt @@ -107,7 +107,7 @@ object PlayerRenderer { if (offsetX < 0) { offsetX += 32 } - val appearance = info.appearanceStamps[other.index and 0x800] != other.updateMasks.appearanceStamp + val appearance = info.appearanceStamps[other.index] != other.updateMasks.appearanceStamp val update = appearance || other.updateMasks.isUpdateRequired || other.updateMasks.hasSynced() buffer.putBits(1, if (update) 1 else 0) buffer.putBits(5, offsetX) @@ -117,7 +117,7 @@ object PlayerRenderer { info.localPlayers.add(other) if (update) { if (appearance) { - info.appearanceStamps[other.index and 0x800] = other.updateMasks.appearanceStamp + info.appearanceStamps[other.index] = other.updateMasks.appearanceStamp } writeMaskUpdates(player, other, flags, appearance, true) } diff --git a/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt b/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt index bcc1e3356..a83f0235c 100644 --- a/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt +++ b/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt @@ -11,7 +11,6 @@ import core.tools.* import core.api.* import core.game.world.GameWorld -import java.nio.charset.StandardCharsets import kotlin.reflect.* import kotlin.math.max @@ -28,12 +27,13 @@ sealed class PlayerFlags530 (p: Int, o: Int, f: EntityFlag) : EFlagProvider (530 else buffer.p1 (context.chatIcon) val chatBuf = ByteArray(256) - chatBuf[0] = context.text.length.toByte() + val encodedText = CP1252.toBytes(context.text) + chatBuf[0] = encodedText.size.toByte() val offset = 1 + StringUtils.encryptPlayerChat ( chatBuf, 0, 1, - context.text.length, - context.text.toByteArray(StandardCharsets.UTF_8) + encodedText.size, + encodedText ) buffer.p1 (offset + 1) buffer.putReverse (chatBuf, 0, offset) diff --git a/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt b/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt index cf63a2e6d..e1108a473 100644 --- a/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt +++ b/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt @@ -155,7 +155,7 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands { define("forcehrevents", Privilege.ADMIN, "::forcehrevents [eventname]", "Force enable holiday random events.") { player, args -> if (args.size == 1) { - notify(player, "Holidays: halloween, christmas") + notify(player, "Holidays: halloween, christmas, aprilfools") return@define } val event = args[1] @@ -183,6 +183,12 @@ class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands { registerTimer(p, HolidayRandoms()) } } + "aprilfools" -> { + ServerConstants.FORCE_APRIL_FOOLS = true + for (p in Repository.players) { + notify(p, colorize("%GApril Fools is now active!")) + } + } else -> reject(player, "Invalid event!") } } diff --git a/Server/src/main/core/game/worldevents/holiday/aprilfools/AprilFoolsEvent.kt b/Server/src/main/core/game/worldevents/holiday/aprilfools/AprilFoolsEvent.kt new file mode 100644 index 000000000..4a4f11a72 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/aprilfools/AprilFoolsEvent.kt @@ -0,0 +1,40 @@ +package core.game.worldevents.holiday.aprilfools + +import core.ServerConstants +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.emote.Emotes +import core.game.system.command.Privilege +import core.tools.colorize +import java.util.Calendar + +class AprilFoolsEvent : Commands, LoginListener { + private fun isActive(): Boolean { + if (ServerConstants.FORCE_APRIL_FOOLS) return true + if (!ServerConstants.APRIL_FOOLS_EVENT) return false + val cal = Calendar.getInstance() + return cal.get(Calendar.MONTH) == Calendar.APRIL && cal.get(Calendar.DAY_OF_MONTH) == 1 + } + + override fun login(player: Player) { + if (!isActive()) return + sendMessage(player, colorize("Use command ::wheel to spin the new prize wheel!", "00ffff")) + } + + override fun defineCommands() { + define("wheel", Privilege.STANDARD) { player, args -> + if (!isActive()) { + sendMessage(player, colorize("-->%R${args[0]}: command not found")) + return@define + } + if (getAttribute(player, "aprilfools:wheelspun", false)) { + sendMessage(player, "I'm not falling for that again.") + return@define + } + sendNews("${player.username} just tried to spin the wheel!") + sendChat(player, "I'm spinning!") + emote(player, Emotes.SPIN) + setAttribute(player, "aprilfools:wheelspun", true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt index 79991e5bb..f0b5a76c3 100644 --- a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt @@ -1,6 +1,5 @@ package core.game.worldevents.holiday.christmas.randoms -import core.api.addItem import core.api.addItemOrDrop import core.api.getAttribute import core.game.dialogue.DialogueFile diff --git a/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt b/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt index 43d33ba40..6b129b906 100644 --- a/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt +++ b/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt @@ -26,7 +26,7 @@ import core.tools.colorize import org.rs09.consts.Items import java.util.* -class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, LoginListener { +class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, LoginListener, Commands { private val spawnedItems = ArrayList() private var timeUntilNextEggSpawn = 0 private var currentLoc = "" @@ -65,6 +65,13 @@ class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, Log player.hook(Event.XpGained, xpEventHook) } + override fun defineCommands() { + define("eggspawntest") {player, _ -> + notify(player, "Spawning 10 eggs nearby...") + repeat(10) { spawnEggFor(player) } + } + } + object xpEventHook : EventHook { override fun process(entity: Entity, event: XPGainEvent) { @@ -76,17 +83,12 @@ class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, Log val activeEggRate = if (GameWorld.settings!!.isDevMode) EGG_RATE_DEV else EGG_RATE - if (RandomFunction.roll(activeEggRate)) { - val dirs = Direction.values() - val dir = dirs[RandomFunction.random(dirs.size)] - val loc = entity.location.transform(dir, 3) - if (!Pathfinder.find(entity, loc).isSuccessful) return - GroundItemManager.create(Item(eggs.random()), loc, entity) - sendMessage(entity, colorize("%RAn egg has appeared nearby.")) - } + if (RandomFunction.roll(activeEggRate)) + spawnEggFor(entity) } } + fun getRandomLocations() : Pair> { val toReturn = ArrayList() @@ -251,7 +253,7 @@ class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, Log Location.create(3089, 3481, 0),Location.create(3084, 3479, 0),Location.create(3108, 3499, 0), Location.create(3110, 3517, 0),Location.create(3091, 3512, 0),Location.create(3092, 3507, 0), Location.create(3081, 3513, 0),Location.create(3079, 3513, 1),Location.create(3080, 3508, 1), - Location.create(3108, 3499, 0),Location.create(3093, 3467, 0)) + Location.create(3093, 3467, 0)) val TREE_GNOME_STRONGHOLD_SPOTS = arrayOf( Location.create(2480, 3507, 0),Location.create(2486, 3513, 0),Location.create(2453, 3512, 0), @@ -288,6 +290,17 @@ class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, Log } } + fun spawnEggFor (player: Player) + { + val dirs = Direction.values() + val dir = dirs[RandomFunction.random(dirs.size)] + var loc = player.location.transform(dir, 3) + val path = Pathfinder.find(player, loc) + loc = Location.create(path.points.last.x, path.points.last.y, loc.z) + GroundItemManager.create(Item(eggs.random()), loc, player) + sendMessage(player, colorize("%RAn egg has appeared nearby.")) + } + val lootTable = WeightBasedTable.create( WeightedItem(Items.EASTER_EGG_1962, 1, 15, 0.10), WeightedItem(Items.PURPLE_SWEETS_10476, 5, 15, 0.10), diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt index dea7ff063..037c9ba10 100644 --- a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt @@ -15,7 +15,7 @@ class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { this.behavior = SpiderHolidayRandomBehavior() playGlobalAudio(this.location, Sounds.SPIDER_4375) var stomped = false - queueScript(this,4, QueueStrength.SOFT) { stage: Int -> + queueScript(this, 4, QueueStrength.SOFT) { stage: Int -> when (stage) { 0 -> { sendChat(player, "Eww a spider!") @@ -32,7 +32,7 @@ class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { } 2 -> { if (stomped) { - impact(this, 1, ImpactHandler.HitsplatType.NORMAL) + impact(this, 2, ImpactHandler.HitsplatType.NORMAL) } else { sendMessage(player, "The spider runs away.") playGlobalAudio(this.location, Sounds.SPIDER_4375) @@ -47,4 +47,4 @@ class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { override fun talkTo(npc: NPC) { } -} \ No newline at end of file +} diff --git a/Server/src/main/core/net/IoSession.java b/Server/src/main/core/net/IoSession.java index 7e61dc28c..956b1d9da 100644 --- a/Server/src/main/core/net/IoSession.java +++ b/Server/src/main/core/net/IoSession.java @@ -122,12 +122,45 @@ public class IoSession { * @param service The executor service. */ public IoSession(SelectionKey key, ExecutorService service) { + this(key, service, resolveRemoteAddress(key)); + } + + /** + * Constructs a new {@code IoSession} with an explicit remote address. + * @param key The selection key. + * @param service The executor service. + * @param remoteAddress The remote address. + */ + public IoSession(SelectionKey key, ExecutorService service, String remoteAddress) { this.key = key; this.service = service; - this.address = getRemoteAddress().replaceAll("/", "").split(":")[0]; + this.address = normalizeRemoteAddress(remoteAddress); this.js5Queue = new JS5Queue(this); } + private static String resolveRemoteAddress(SelectionKey key) { + if (key == null || !(key.channel() instanceof SocketChannel)) { + return "127.0.0.1"; + } + try { + return ((SocketChannel) key.channel()).getRemoteAddress().toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + private static String normalizeRemoteAddress(String remoteAddress) { + if (remoteAddress == null || remoteAddress.trim().isEmpty()) { + return "127.0.0.1"; + } + String normalized = remoteAddress.replace("/", ""); + int separator = normalized.lastIndexOf(':'); + if (separator > 0) { + return normalized.substring(0, separator); + } + return normalized; + } + /** * Fires a write event created using the current event producer. * @param context The event context. @@ -213,9 +246,11 @@ public class IoSession { return; } active = false; - key.cancel(); - SocketChannel channel = (SocketChannel) key.channel(); - channel.socket().close(); + if (key != null) { + key.cancel(); + SocketChannel channel = (SocketChannel) key.channel(); + channel.socket().close(); + } if (getPlayer() != null) { try { getPlayer().clear(); @@ -435,4 +470,4 @@ public class IoSession { this.clientInfo = clientInfo; } -} \ No newline at end of file +} diff --git a/Server/src/main/core/net/NioReactor.java b/Server/src/main/core/net/NioReactor.java index 42fea5a1d..fb07b826d 100644 --- a/Server/src/main/core/net/NioReactor.java +++ b/Server/src/main/core/net/NioReactor.java @@ -143,6 +143,21 @@ public final class NioReactor implements Runnable { */ public void terminate() { running = false; + try { + if (channel != null) { + if (channel.getChannel() != null) { + channel.getChannel().close(); + } + if (channel.getSocket() != null) { + channel.getSocket().close(); + } + channel.getSelector().wakeup(); + channel.getSelector().close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + service.shutdownNow(); } } \ No newline at end of file diff --git a/Server/src/main/core/net/packet/PacketProcessor.kt b/Server/src/main/core/net/packet/PacketProcessor.kt index 78be623b3..c05798490 100644 --- a/Server/src/main/core/net/packet/PacketProcessor.kt +++ b/Server/src/main/core/net/packet/PacketProcessor.kt @@ -1,82 +1,95 @@ package core.net.packet -import core.game.event.ButtonClickEvent +import content.global.ame.events.maze.MazeInterface +import content.global.handlers.iface.ge.StockMarket +import content.global.skill.magic.SpellListener +import content.global.skill.magic.SpellListeners +import content.global.skill.magic.SpellUtils +import content.global.skill.summoning.familiar.FamiliarSpecial +import core.ServerConstants import core.api.getAttribute +import core.api.log import core.api.sendMessage -import core.api.tryPop +import core.api.utils.Vector import core.cache.def.impl.ItemDefinition import core.cache.def.impl.NPCDefinition import core.cache.def.impl.SceneryDefinition import core.game.container.Container import core.game.container.impl.BankContainer -import core.game.node.Node -import core.game.node.entity.player.Player -import core.game.node.entity.player.info.Rights -import core.game.node.entity.player.info.login.LoginConfiguration -import core.game.node.entity.player.link.SpellBookManager -import core.game.node.entity.combat.spell.MagicSpell -import content.global.skill.summoning.familiar.FamiliarSpecial -import core.game.node.item.GroundItemManager -import core.game.node.item.Item -import core.game.node.scenery.Scenery -import core.game.system.communication.ClanRank -import core.game.system.communication.CommunicationInfo -import core.game.system.task.Pulse -import core.game.world.map.Location -import core.game.world.map.RegionManager -import core.game.world.update.flag.context.ChatMessage -import core.game.world.update.flag.* -import core.net.amsc.MSPacketRepository -import core.net.packet.context.PlayerContext -import core.net.packet.out.ClearMinimapFlag -import org.rs09.consts.Components -import proto.management.ClanMessage -import proto.management.JoinClanRequest -import proto.management.LeaveClanRequest -import core.ServerConstants +import core.game.event.ButtonClickEvent import core.game.ge.GrandExchange.Companion.getOfferStats import core.game.ge.GrandExchange.Companion.getRecommendedPrice import core.game.ge.GrandExchangeOffer import core.game.ge.PriceIndex -import content.global.handlers.iface.ge.StockMarket -import content.global.skill.magic.SpellListener -import content.global.skill.magic.SpellListeners -import content.global.skill.magic.SpellUtils -import core.api.log import core.game.interaction.* +import core.game.node.Node +import core.game.node.entity.combat.spell.MagicSpell +import core.game.node.entity.player.Player import core.game.node.entity.player.info.LogType import core.game.node.entity.player.info.PlayerMonitor -import core.tools.SystemLogger +import core.game.node.entity.player.info.Rights +import core.game.node.entity.player.info.login.LoginConfiguration +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery import core.game.system.command.CommandSystem +import core.game.system.communication.ClanRank +import core.game.system.communication.CommunicationInfo import core.game.system.communication.GlobalChat +import core.game.system.task.Pulse import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.RegionManager import core.game.world.repository.Repository +import core.game.world.update.flag.EntityFlag +import core.game.world.update.flag.context.ChatMessage +import core.net.amsc.MSPacketRepository +import core.net.packet.context.PlayerContext import core.net.packet.`in`.Packet import core.net.packet.`in`.RunScript +import core.net.packet.out.ClearMinimapFlag import core.tools.Log import core.worker.ManagementEvents -import core.api.utils.Vector +import org.rs09.consts.Components +import proto.management.ClanMessage +import proto.management.JoinClanRequest +import proto.management.LeaveClanRequest import java.io.PrintWriter import java.io.StringWriter import java.lang.Math.min import java.util.* object PacketProcessor { - val queue = LinkedList() + private var queue = LinkedList() + private var processingQueue = LinkedList() + private val queueLock = Any() @JvmStatic fun enqueue(pkt: Packet) { - queue.addLast(pkt) + synchronized(queueLock) { + queue.addLast(pkt) + } } @JvmStatic fun processQueue() { - var countThisCycle = queue.size + synchronized(queueLock) { + if (queue.isEmpty()) { + return + } + val queued = queue + queue = processingQueue + processingQueue = queued + } val sw = StringWriter() val pw = PrintWriter(sw) var pkt: Packet - while (countThisCycle-- > 0) { - pkt = queue.tryPop(Packet.NoProcess()) ?: return + while (processingQueue.isNotEmpty()) { + pkt = processingQueue.pollFirst() ?: return if (pkt is Packet.NoProcess) { - queue.clear() + synchronized(queueLock) { + queue.clear() + } + processingQueue.clear() return } try { @@ -187,7 +200,7 @@ object PacketProcessor { offer.itemID = pkt.itemId offer.sell = false if (!PriceIndex.canTrade(pkt.itemId)) { - sendMessage(pkt.player, "That item is blacklisted from the grand exchange.") + sendMessage(pkt.player, "That item is blacklisted from the Grand Exchange.") return } offer.player = pkt.player @@ -207,13 +220,14 @@ object PacketProcessor { if (pkt.player.details.isMuted) pkt.player.sendMessage("You have been muted due to breaking a rule.") else { - if (ServerConstants.ENABLE_GLOBALCHAT && pkt.message.startsWith("//")) { + if (ServerConstants.ENABLE_GLOBAL_CHAT && pkt.message.startsWith("//")) { if (getAttribute(pkt.player, GlobalChat.ATTR_GLOBAL_MUTE, false)) return val messages = splitChatMessage(pkt.message.substring(2), pkt.player.name.length + 3, false) for (message in messages) { if (message.isNotBlank()) + PlayerMonitor.logChat(pkt.player, "global", message) GlobalChat.process(pkt.player.username, message, Rights.getChatIcon(pkt.player)) } return @@ -227,6 +241,7 @@ object PacketProcessor { builder.clanName = pkt.player.communication.clan.owner.lowercase().replace(" ", "_") builder.message = message builder.rank = Rights.getChatIcon(pkt.player) + PlayerMonitor.logChat(pkt.player, "clan", message) ManagementEvents.publish(builder.build()) } return @@ -308,7 +323,10 @@ object PacketProcessor { } is Packet.TrackingAfkTimeout -> { if (pkt.player.details.rights != Rights.ADMINISTRATOR) + { + pkt.player.isAfkLogout = true pkt.player.packetDispatch.sendLogout() + } } is Packet.TrackingCameraPos -> { //TODO Refactor the player monitor to be actually useful and log this @@ -417,6 +435,11 @@ object PacketProcessor { return if (player.getAttribute("magic:delay", -1) > GameWorld.ticks) return + // Validate spell packet interface matches player's actual spellbook + // This is to prevent player being able to cast spells when client has stale interface (e.g. after Spellbook swap reverts) + if (iface in intArrayOf(192, 193, 430)) { + if (!SpellUtils.validateSpellbookInterface(player, iface)) return + } val book = SpellUtils.getBookFromInterface(iface) if (book != "none") SpellListeners.run(child, type, book, player, target) @@ -521,7 +544,7 @@ object PacketProcessor { player.debug("Slot: ${pkt.slot}, ItemID: ${pkt.itemId}") player.debug("RCM Index: ${pkt.optIndex}, Op: ${pkt.opcode}") player.debug("-------------------------------------") - if (player.dialogueInterpreter.dialogue != null && pkt.opcode != 132 && pkt.iface != 64) + if (player.dialogueInterpreter.dialogue != null && pkt.opcode != 132 && pkt.iface != 64 && pkt.iface != 746) player.dialogueInterpreter.close() if (player.locks.isComponentLocked) return @@ -667,6 +690,11 @@ object PacketProcessor { if (pkt.id == 6899) scenery = Scenery(6899, Location(3221, 9618)) + // Random Event Maze chests are overridden by the walls, which needs to be hacked in. + if ((scenery?.id == 3626 || scenery?.id == 3635) && (objId in 3635..3636)) { + scenery = MazeInterface.overrideScenery(scenery, objId) + } + // Family crest levers don't have varps associated with them, so their state is validated with attributes // instead, and they always appear as their down/odd variant in the server's map if (objId in 2421..2426 && objId % 2 == 0) { diff --git a/Server/src/main/core/net/packet/PacketRepository.java b/Server/src/main/core/net/packet/PacketRepository.java index 60c6fddb0..e2656b02a 100644 --- a/Server/src/main/core/net/packet/PacketRepository.java +++ b/Server/src/main/core/net/packet/PacketRepository.java @@ -75,9 +75,10 @@ public final class PacketRepository { OUTGOING_PACKETS.put(InstancedLocationUpdate.class, new InstancedLocationUpdate()); // OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); // OUTGOING_PACKETS.put(Varbit.class, new Varbit()); - OUTGOING_PACKETS.put(ResetInterface.class, new ResetInterface()); + OUTGOING_PACKETS.put(ResetInterface.class, new ResetInterface()); OUTGOING_PACKETS.put(VarcUpdate.class, new VarcUpdate()); OUTGOING_PACKETS.put(InterfaceSetAngle.class, new InterfaceSetAngle()); + OUTGOING_PACKETS.put(LastLoginInfo.class, new LastLoginInfo()); } /** @@ -105,5 +106,4 @@ public final class PacketRepository { } } } - -} +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/PacketWriteQueue.kt b/Server/src/main/core/net/packet/PacketWriteQueue.kt index fad453300..ed3de3d43 100644 --- a/Server/src/main/core/net/packet/PacketWriteQueue.kt +++ b/Server/src/main/core/net/packet/PacketWriteQueue.kt @@ -1,18 +1,18 @@ package core.net.packet import core.api.log -import core.api.tryPop import core.net.packet.out.* import core.tools.Log import core.tools.SystemLogger import java.io.PrintWriter import java.io.StringWriter import java.util.* -import java.util.concurrent.locks.ReentrantLock class PacketWriteQueue { companion object { - private val packetsToWrite = LinkedList>() + private var packetsToWrite = LinkedList>() + private var packetsToFlush = LinkedList>() + private val queueLock = Any() @JvmStatic fun handle(packet: OutgoingPacket, context: T) { @@ -34,16 +34,25 @@ class PacketWriteQueue { log(this::class.java, Log.ERR, "${packet::class.java.simpleName} tried to queue with a null context!") return } - packetsToWrite.add(QueuedPacket(packet, context)) + synchronized(queueLock) { + packetsToWrite.add(QueuedPacket(packet, context)) + } } @JvmStatic fun flush() { - var countThisCycle = packetsToWrite.size + synchronized(queueLock) { + if (packetsToWrite.isEmpty()) { + return + } + val queued = packetsToWrite + packetsToWrite = packetsToFlush + packetsToFlush = queued + } val sw = StringWriter() val pw = PrintWriter(sw) - while (countThisCycle-- > 0) { - val pkt = packetsToWrite.tryPop(null) ?: continue + while (packetsToFlush.isNotEmpty()) { + val pkt = packetsToFlush.pollFirst() ?: continue try { write(pkt.out, pkt.context) } catch (e: Exception) { diff --git a/Server/src/main/core/net/packet/context/ContainerContext.java b/Server/src/main/core/net/packet/context/ContainerContext.java index 7b4a3ea9c..411a812cd 100644 --- a/Server/src/main/core/net/packet/context/ContainerContext.java +++ b/Server/src/main/core/net/packet/context/ContainerContext.java @@ -34,7 +34,9 @@ public final class ContainerContext implements Context { /** * The items. */ - private final Item[] items; + private Item[] items; + + public int[] ids; /** * The length of the array to send. @@ -115,6 +117,17 @@ public final class ContainerContext implements Context { this.slots = null; } + public ContainerContext(Player player, int interfaceId, int childId, int containerId, int[] items) { + this.player = player; + this.interfaceId = interfaceId; + this.childId = childId; + this.containerId = containerId; + this.ids = items; + this.length = items.length; + this.split = false; + this.slots = null; + } + /** * Constructs a new {@code ContainerContext} {@code Object}. * @param player The player. diff --git a/Server/src/main/core/net/packet/out/CommunicationMessage.java b/Server/src/main/core/net/packet/out/CommunicationMessage.java index 5cd5e592d..77e86af95 100644 --- a/Server/src/main/core/net/packet/out/CommunicationMessage.java +++ b/Server/src/main/core/net/packet/out/CommunicationMessage.java @@ -6,6 +6,7 @@ import core.net.packet.IoBuffer; import core.net.packet.OutgoingPacket; import core.net.packet.PacketHeader; import core.net.packet.context.MessageContext; +import core.tools.CP1252; import core.tools.StringUtils; import core.game.bots.AIPlayer; @@ -21,20 +22,21 @@ public final class CommunicationMessage implements OutgoingPacket { } } } else { - buffer.putShort(context.getItems().length); - for (Item item : context.getItems()) - if (item != null) { - int amount = item.getAmount(); - if (amount < 0 || amount > 254) { - buffer.putS(255).putInt(amount); - } else { - buffer.putS(amount); - } - buffer.putShort(item.getId() + 1); - } else { - buffer.putS(0).putShort(0); + if (context.ids != null) + { + buffer.p2(context.getLength()); + for (int i = 0; i < context.getLength(); i++) + { + buffer.putS(1); + buffer.p2(context.ids[i] + 1); } + } + else { + buffer.putShort(context.getItems().length); + for (Item item : context.getItems()) + if (item != null) { + int amount = item.getAmount(); + if (amount < 0 || amount > 254) { + buffer.putS(255).putInt(amount); + } else { + buffer.putS(amount); + } + buffer.putShort(item.getId() + 1); + } else { + buffer.putS(0).putShort(0); + } + } } } buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); diff --git a/Server/src/main/core/net/packet/out/LastLoginInfo.kt b/Server/src/main/core/net/packet/out/LastLoginInfo.kt new file mode 100644 index 000000000..1892cf487 --- /dev/null +++ b/Server/src/main/core/net/packet/out/LastLoginInfo.kt @@ -0,0 +1,15 @@ +package core.net.packet.out + +import core.net.packet.IoBuffer +import core.net.packet.OutgoingPacket +import core.net.packet.context.PlayerContext +import java.net.Inet4Address + +class LastLoginInfo : OutgoingPacket { + override fun send(context: PlayerContext) { + val buffer = IoBuffer(164) + buffer.imp4(Inet4Address.getByName(context.player.details.ipAddress).hashCode()) + buffer.cypherOpcode(context.player.session.isaacPair.output) + context.player.session.write(buffer) + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/UpdateSceneGraph.java b/Server/src/main/core/net/packet/out/UpdateSceneGraph.java index 5601c6757..a93435b18 100644 --- a/Server/src/main/core/net/packet/out/UpdateSceneGraph.java +++ b/Server/src/main/core/net/packet/out/UpdateSceneGraph.java @@ -24,10 +24,7 @@ public final class UpdateSceneGraph implements OutgoingPacket for (int regionY = (player.getLocation().getRegionY() - 6) / 8; regionY <= ((player.getLocation().getRegionY() + 6) / 8); regionY++) { int[] keys = XteaParser.Companion.getRegionXTEA(regionX << 8 | regionY); for (int i = 0; i < 4; i++) { - if (keys != null) buffer.putIntB(keys[i]); - else - buffer.putIntB(0); } } } diff --git a/Server/src/main/core/net/websocket/GameWebSocketServer.kt b/Server/src/main/core/net/websocket/GameWebSocketServer.kt new file mode 100644 index 000000000..dcd7d3f3f --- /dev/null +++ b/Server/src/main/core/net/websocket/GameWebSocketServer.kt @@ -0,0 +1,73 @@ +package core.net.websocket + +import core.api.log +import core.net.IoSession +import core.tools.Log +import org.java_websocket.WebSocket +import org.java_websocket.handshake.ClientHandshake +import org.java_websocket.server.WebSocketServer +import java.net.InetSocketAddress +import java.nio.ByteBuffer +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors + +class GameWebSocketServer(port: Int, poolSize: Int) : WebSocketServer(InetSocketAddress(port)) { + private val service: ExecutorService = Executors.newFixedThreadPool(poolSize) { runnable -> + Thread(runnable, "WebSocketIo").apply { + isDaemon = true + } + } + private val sessions = ConcurrentHashMap() + + init { + // This pool processes websocket frames; it is not a cap on connected webclients. + setTcpNoDelay(true) + setReuseAddr(true) + } + + override fun onOpen(conn: WebSocket, handshake: ClientHandshake) { + sessions[conn] = WebSocketIoSession(conn, service) + } + + override fun onClose(conn: WebSocket, code: Int, reason: String, remote: Boolean) { + val session = sessions.remove(conn) + if (session != null && session.isActive) { + session.disconnect() + } + } + + override fun onMessage(conn: WebSocket, message: String) { + log(javaClass, Log.WARN, "Closing websocket client ${conn.remoteSocketAddress}: text frames are unsupported.") + conn.close(1003, "Binary frames only") + } + + override fun onMessage(conn: WebSocket, message: ByteBuffer) { + val session: IoSession = sessions[conn] ?: run { + conn.close(1011, "Session not initialized") + return + } + val copy = ByteBuffer.allocate(message.remaining()) + copy.put(message) + copy.flip() + service.execute(session.producer.produceReader(session, copy)) + } + + override fun onError(conn: WebSocket?, ex: Exception?) { + if (ex != null) { + log(javaClass, Log.ERR, "WebSocket server error: ${ex.message}") + } + if (conn != null) { + sessions.remove(conn)?.disconnect() + } + } + + override fun onStart() { + log(javaClass, Log.INFO, "WebSocket listener started on port $port.") + } + + override fun stop(timeout: Int, closeMessage: String) { + super.stop(timeout, closeMessage) + service.shutdownNow() + } +} diff --git a/Server/src/main/core/net/websocket/WebSocketIoSession.kt b/Server/src/main/core/net/websocket/WebSocketIoSession.kt new file mode 100644 index 000000000..49693ec09 --- /dev/null +++ b/Server/src/main/core/net/websocket/WebSocketIoSession.kt @@ -0,0 +1,41 @@ +package core.net.websocket + +import core.net.IoSession +import org.java_websocket.WebSocket +import org.java_websocket.exceptions.WebsocketNotConnectedException +import java.nio.ByteBuffer +import java.util.concurrent.ExecutorService + +class WebSocketIoSession( + private val socket: WebSocket, + service: ExecutorService +) : IoSession(null, service, socket.remoteSocketAddress?.toString() ?: "127.0.0.1") { + + override fun queue(buffer: ByteBuffer?) { + if (buffer == null || !socket.isOpen) { + return + } + val copy = buffer.slice() + val data = ByteArray(copy.remaining()) + copy.get(data) + try { + socket.send(data) + } catch (e: WebsocketNotConnectedException) { + disconnect() + } + } + + override fun write() { + // WebSocket sessions bypass the SelectionKey-backed TCP write queue. + } + + override fun disconnect() { + if (!isActive) { + return + } + super.disconnect() + if (socket.isOpen) { + socket.close() + } + } +} diff --git a/Server/src/main/core/net/websocket/WebSocketTls.kt b/Server/src/main/core/net/websocket/WebSocketTls.kt new file mode 100644 index 000000000..981afe060 --- /dev/null +++ b/Server/src/main/core/net/websocket/WebSocketTls.kt @@ -0,0 +1,45 @@ +package core.net.websocket + +import core.ServerConstants +import core.api.log +import core.game.system.config.ServerConfigParser +import core.tools.Log +import org.java_websocket.server.DefaultSSLWebSocketServerFactory +import java.io.FileInputStream +import java.security.KeyStore +import javax.net.ssl.KeyManagerFactory +import javax.net.ssl.SSLContext + +object WebSocketTls { + + private const val KEYSTORE_TYPE = "PKCS12" + + fun configure(server: GameWebSocketServer) { + if (!ServerConstants.WEBSOCKET_TLS_ENABLED) { + return + } + server.setWebSocketFactory(DefaultSSLWebSocketServerFactory(createContext())) + } + + private fun createContext(): SSLContext { + val keystorePath = ServerConstants.WEBSOCKET_TLS_KEYSTORE_PATH.trim() + if (keystorePath.isEmpty()) { + throw IllegalStateException("server.websocket_tls_enabled is true but websocket_tls_keystore_path is blank") + } + val resolvedKeystorePath = ServerConfigParser.parsePath(keystorePath) + val keystorePassword = ServerConstants.WEBSOCKET_TLS_KEYSTORE_PASSWORD.toCharArray() + + val keyStore = KeyStore.getInstance(KEYSTORE_TYPE) + FileInputStream(resolvedKeystorePath).use { input -> + keyStore.load(input, keystorePassword) + } + + val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) + keyManagerFactory.init(keyStore, keystorePassword) + + val sslContext = SSLContext.getInstance("TLS") + sslContext.init(keyManagerFactory.keyManagers, null, null) + log(WebSocketTls::class.java, Log.INFO, "Configured secure websocket listener using keystore $resolvedKeystorePath.") + return sslContext + } +} diff --git a/Server/src/main/core/tools/CP1252.java b/Server/src/main/core/tools/CP1252.java index 9269b8710..c3f42e54a 100644 --- a/Server/src/main/core/tools/CP1252.java +++ b/Server/src/main/core/tools/CP1252.java @@ -1,18 +1,22 @@ package core.tools; -public class CP1252 { - private static char[] charMap = {'\u20ac', '\0', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', +public final class CP1252 { + private static final char[] CHAR_MAP = {'\u20ac', '\0', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\0', '\u017d', '\0', '\0', '\u2018', '\u2019', '\u201c', '\u201d', '\u2022', '\u2013', '\u2014', '\u02dc', '\u2122', '\u0161', '\u203a', '\u0153', '\0', '\u017e', '\u0178'}; + private CP1252() { + /* utility class */ + } + public static char getFromByte(byte value) { int out = value & 0xff; if (out == 0) { throw new IllegalArgumentException("Non cp1252 character 0x" + Integer.toString(out, 16) + " provided"); } if (out >= 128 && out < 160) { - int cp1252 = charMap[out - 128]; + int cp1252 = CHAR_MAP[out - 128]; if (cp1252 == 0) { cp1252 = 63; } @@ -20,4 +24,26 @@ public class CP1252 { } return (char) out; } + + public static byte getByte(char value) { + if ((value > 0 && value < 128) || (value >= 160 && value <= 255)) { + return (byte) value; + } + + for (int i = 0; i < CHAR_MAP.length; i++) { + if (CHAR_MAP[i] != 0 && CHAR_MAP[i] == value) { + return (byte) (i + 128); + } + } + + return 63; + } + + public static byte[] toBytes(CharSequence value) { + byte[] out = new byte[value.length()]; + for (int i = 0; i < value.length(); i++) { + out[i] = getByte(value.charAt(i)); + } + return out; + } } diff --git a/Server/src/main/core/tools/NetworkReachability.kt b/Server/src/main/core/tools/NetworkReachability.kt new file mode 100644 index 000000000..d27f3bd60 --- /dev/null +++ b/Server/src/main/core/tools/NetworkReachability.kt @@ -0,0 +1,6 @@ +package core.tools + +enum class NetworkReachability { + Reachable, + Unreachable +} \ No newline at end of file diff --git a/Server/src/main/core/tools/RandomFunction.java b/Server/src/main/core/tools/RandomFunction.java index 7e8dd580f..b74092a20 100644 --- a/Server/src/main/core/tools/RandomFunction.java +++ b/Server/src/main/core/tools/RandomFunction.java @@ -35,6 +35,7 @@ public class RandomFunction { /** * Method used to ease the access of the random class. + * In certain cases, it is inclusive from the min value and exclusive from the max values specified. * @param a the minimum random value. * @param b the maximum random value. * @return the value as an {@link Integer}. @@ -49,9 +50,9 @@ public class RandomFunction { * @param chance the 1/chance rate for the roll to succeed * @return true if you hit the roll, false otherwise */ - public static boolean roll(int chance){ + public static boolean roll(int chance) { if (chance <= 1) return true; - return random(chance + 1) == chance / 2; + return random(chance) == 1; } /** diff --git a/Server/src/main/core/tools/StringUtils.java b/Server/src/main/core/tools/StringUtils.java index 84ac0e3e0..bc55800b6 100644 --- a/Server/src/main/core/tools/StringUtils.java +++ b/Server/src/main/core/tools/StringUtils.java @@ -502,7 +502,7 @@ public final class StringUtils { return ""; int charsDecoded = 0; int i_4_ = 0; - String s = ""; + StringBuilder s = new StringBuilder(totalChars); for (;;) { byte i_7_ = (byte) buffer.get(); if (i_7_ >= 0) @@ -511,7 +511,7 @@ public final class StringUtils { i_4_ = anIntArray241[i_4_]; int i_8_; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (totalChars <= ++charsDecoded) break; i_4_ = 0; @@ -521,7 +521,7 @@ public final class StringUtils { else i_4_++; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (++charsDecoded >= totalChars) break; i_4_ = 0; @@ -531,7 +531,7 @@ public final class StringUtils { else i_4_ = anIntArray241[i_4_]; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (totalChars <= ++charsDecoded) break; i_4_ = 0; @@ -541,7 +541,7 @@ public final class StringUtils { else i_4_ = anIntArray241[i_4_]; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (totalChars <= ++charsDecoded) break; @@ -552,7 +552,7 @@ public final class StringUtils { else i_4_++; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (++charsDecoded >= totalChars) break; i_4_ = 0; @@ -562,7 +562,7 @@ public final class StringUtils { else i_4_ = anIntArray241[i_4_]; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (totalChars <= ++charsDecoded) break; i_4_ = 0; @@ -572,7 +572,7 @@ public final class StringUtils { else i_4_++; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (totalChars <= ++charsDecoded) break; i_4_ = 0; @@ -582,13 +582,13 @@ public final class StringUtils { else i_4_++; if ((i_8_ = anIntArray241[i_4_]) < 0) { - s += (char) (byte) (i_8_ ^ 0xffffffff); + s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff))); if (++charsDecoded >= totalChars) break; i_4_ = 0; } } - return s; + return s.toString(); } catch (RuntimeException runtimeexception) { runtimeexception.printStackTrace(); } diff --git a/Server/src/main/core/tools/SystemLogger.kt b/Server/src/main/core/tools/SystemLogger.kt index eb65de9ea..dc5b96560 100644 --- a/Server/src/main/core/tools/SystemLogger.kt +++ b/Server/src/main/core/tools/SystemLogger.kt @@ -19,7 +19,7 @@ import java.util.* object SystemLogger { val t = Terminal() val errT = t.forStdErr() - val formatter = SimpleDateFormat("HH:mm:ss") + val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX") private fun getTime(): String{ return "[" + formatter.format(Date(System.currentTimeMillis())) +"]" diff --git a/Server/src/main/core/worker/MajorUpdateWorker.kt b/Server/src/main/core/worker/MajorUpdateWorker.kt index e4553a6ec..29d48faa8 100644 --- a/Server/src/main/core/worker/MajorUpdateWorker.kt +++ b/Server/src/main/core/worker/MajorUpdateWorker.kt @@ -1,25 +1,25 @@ package core.worker -import core.api.submitWorldPulse -import core.game.system.task.Pulse -import core.plugin.CorePluginTypes.Managers import core.Server import core.ServerConstants import core.ServerStore import core.api.log -import core.tools.SystemLogger +import core.api.submitWorldPulse +import core.game.system.task.Pulse import core.game.world.GameWorld import core.game.world.repository.Repository import core.game.world.update.UpdateSequence +import core.integrations.grafana.Grafana import core.net.packet.PacketProcessor import core.net.packet.PacketWriteQueue +import core.plugin.CorePluginTypes.Managers import core.tools.Log +import core.tools.NetworkReachability import core.tools.colorize import java.lang.Long.max import java.text.SimpleDateFormat import java.util.* import kotlin.system.exitProcess -import core.integrations.grafana.* /** * Handles the running of pulses and writing of masks, etc @@ -38,7 +38,11 @@ class MajorUpdateWorker { Grafana.startTick() val start = System.currentTimeMillis() Server.heartbeat() - handleTickActions() + + if (Server.networkReachability == NetworkReachability.Reachable) + handleTickActions() + else + tickOffline() for (player in Repository.players.filter { !it.isArtificial }) { if (System.currentTimeMillis() - player.session.lastPing > 20000L) { @@ -62,12 +66,18 @@ class MajorUpdateWorker { ServerStore.clearDailyEntries() if (ServerConstants.DAILY_RESTART) { + for (player in Repository.players.filter { !it.isArtificial }) { + player.packetDispatch.sendSystemUpdate(500) + } Repository.sendNews(colorize("%RSERVER GOING DOWN FOR DAILY RESTART IN 5 MINUTES!")) ServerConstants.DAILY_RESTART = false submitWorldPulse(object : Pulse(100) { var counter = 0 override fun pulse(): Boolean { counter++ + for (player in Repository.players.filter { !it.isArtificial }) { + player.packetDispatch.sendSystemUpdate((5 - counter) * 100) + } if (counter == 5) { exitProcess(0) } @@ -89,6 +99,12 @@ class MajorUpdateWorker { log(this::class.java, Log.FINE, "Update worker stopped.") } + fun tickOffline() + { + Repository.disconnectionQueue.update() //continue processing disconnection queue + GameWorld.pulse() //continue incrementing the global tick count + } + fun handleTickActions(skipPulseUpdate: Boolean = false) { try { var packetStart = System.currentTimeMillis() diff --git a/Server/src/test/kotlin/PlayerStatsCounterTests.kt b/Server/src/test/kotlin/PlayerStatsCounterTests.kt new file mode 100644 index 000000000..1b2ce9bc7 --- /dev/null +++ b/Server/src/test/kotlin/PlayerStatsCounterTests.kt @@ -0,0 +1,111 @@ +import core.api.utils.PlayerStatsCounter +import core.game.node.item.Item +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import java.io.File + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class PlayerStatsCounterTests { + companion object { + private const val TEST_DB_PATH = "player_stats_test.db" + private val counter = PlayerStatsCounter(TEST_DB_PATH) + init { + TestUtils.preTestSetup() + counter.startup() + } + @AfterAll @JvmStatic fun cleanup() { + File(TEST_DB_PATH).delete() + } + } + + @Test fun testKillIncrementShouldAddOneKillForNewPlayer() { + val testPlayer = TestUtils.getMockPlayer("test_kill_inc") + val testNPCId = 10 + + val oldKills = PlayerStatsCounter.getKills(testPlayer, IntArray(testNPCId)) + Assertions.assertEquals(0, oldKills) + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId) + + val newKills = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId)) + Assertions.assertEquals(1, newKills) + } + + @Test fun testGetKillShouldReturnKillsForSinglePlayer() { + val testPlayer = TestUtils.getMockPlayer("kill_single_player_1") + val testPlayer2 = TestUtils.getMockPlayer("kill_single_player_2") + val testNPCId = 10 + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId) + + PlayerStatsCounter.incrementKills(testPlayer2,testNPCId) + PlayerStatsCounter.incrementKills(testPlayer2,testNPCId) + + val kills = PlayerStatsCounter.getKills(testPlayer2, intArrayOf(testNPCId)) + Assertions.assertEquals(2, kills) + } + + @Test fun testGetKillShouldReturnSumForAllNPCsForAGivenPlayer() { + val testPlayer = TestUtils.getMockPlayer("test_sum_npcs") + val testNPCId1 = 10 + val testNPCId2 = 11 + val testNPCId3 = 12 + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId1) + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId2) + PlayerStatsCounter.incrementKills(testPlayer,testNPCId2) + PlayerStatsCounter.incrementKills(testPlayer,testNPCId2) + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId3) + PlayerStatsCounter.incrementKills(testPlayer,testNPCId3) + + val killsForNPCs1And2 = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId1, testNPCId2)) + Assertions.assertEquals(4, killsForNPCs1And2) + val killsForAllNPCs = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId1, testNPCId2, testNPCId3)) + Assertions.assertEquals(6, killsForAllNPCs) + } + + @Test fun testRewardIncrementShouldAddOneRewardForNewPlayer() { + val testPlayer = TestUtils.getMockPlayer("test_reward_inc") + val itemId = 10 + + val oldRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(0, oldRareDrops) + + PlayerStatsCounter.incrementRareDrop(testPlayer, Item(itemId)) + + val newRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(1, newRareDrops) + } + + @Test fun testGetRewardsShouldReturnRewardsForSinglePlayer() { + val testPlayer = TestUtils.getMockPlayer("reward_single_player_1") + val testPlayer2 = TestUtils.getMockPlayer("reward_single_player_2") + val testItemId = 10 + + PlayerStatsCounter.incrementRareDrop(testPlayer,Item(testItemId)) + + PlayerStatsCounter.incrementRareDrop(testPlayer2,Item(testItemId)) + PlayerStatsCounter.incrementRareDrop(testPlayer2,Item(testItemId)) + + val rareDrops = PlayerStatsCounter.getRareDrops(testPlayer2, testItemId) + Assertions.assertEquals(2, rareDrops) + } + + @Test fun testGetRewardsShouldHonourItemAmountWhenIncrementing() { + val testPlayer = TestUtils.getMockPlayer("test_reward_inc_itemamount") + val itemId = 10 + + val itemAmount: Long = 5 + + val oldRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(0, oldRareDrops) + + PlayerStatsCounter.incrementRareDrop(testPlayer, Item(itemId, itemAmount.toInt())) + + val newRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(itemAmount, newRareDrops) + } +} diff --git a/Server/src/test/kotlin/QuestTests.kt b/Server/src/test/kotlin/QuestTests.kt index f400e1bb2..0a4fa7bc8 100644 --- a/Server/src/test/kotlin/QuestTests.kt +++ b/Server/src/test/kotlin/QuestTests.kt @@ -1,3 +1,4 @@ +import content.data.Quests import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.player.link.quest.QuestRepository import org.junit.jupiter.api.Assertions @@ -10,7 +11,7 @@ class QuestTests { testPlayer = TestUtils.getMockPlayer("test") } - class TestQuest : Quest("Test Quest", 0, 0, 1, 1, 0, 1, 2) { + class TestQuest : Quest(Quests.TEST_QUEST, 0, 0, 1, 1, 0, 1, 2) { override fun newInstance(`object`: Any?): Quest { return this } @@ -25,13 +26,13 @@ class QuestTests { @Test fun registerShouldMakeQuestImmediatelyAvailable() { QuestRepository.register(testQuest) - Assertions.assertNotNull(QuestRepository.getQuests()[testQuest.name]) + Assertions.assertNotNull(QuestRepository.getQuests()[testQuest.quest]) } @Test fun registerShouldMakeQuestImmediatelyAvailableToInstances() { QuestRepository.register(testQuest) val instance = QuestRepository(testPlayer) - Assertions.assertNotNull(instance.getQuest(testQuest.name)) + Assertions.assertNotNull(instance.getQuest(testQuest.quest)) } @Test fun getStageOnUnstartedQuestShouldNotThrowException() { @@ -54,8 +55,8 @@ class QuestTests { Assertions.assertThrows(IllegalStateException::class.java, { QuestRepository.register(testQuest) val repo = QuestRepository(testPlayer) - repo.getQuest("Test Quest").finish(testPlayer) - repo.getQuest("Test Quest").finish(testPlayer) + repo.getQuest(Quests.TEST_QUEST).finish(testPlayer) + repo.getQuest(Quests.TEST_QUEST).finish(testPlayer) }, "Quest completed twice without throwing an exception or threw wrong exception!") } } \ No newline at end of file diff --git a/Server/src/test/kotlin/content/CombatTests.kt b/Server/src/test/kotlin/content/CombatTests.kt index 55ffc715e..762ed8406 100644 --- a/Server/src/test/kotlin/content/CombatTests.kt +++ b/Server/src/test/kotlin/content/CombatTests.kt @@ -2,6 +2,10 @@ package content import TestUtils import content.global.handlers.item.equipment.special.ChinchompaSwingHandler +import core.api.EquipmentSlot +import core.game.container.impl.EquipmentContainer.updateBonuses +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners import core.game.node.entity.combat.MagicSwingHandler import core.game.node.entity.combat.MeleeSwingHandler import core.game.node.entity.combat.RangeSwingHandler @@ -9,8 +13,10 @@ import core.game.node.entity.combat.SwingHandlerFlag import core.game.node.entity.combat.equipment.WeaponInterface import core.game.node.entity.player.link.prayer.PrayerType import core.game.node.entity.skill.Skills +import core.game.node.item.Item import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test +import org.rs09.consts.Items class CombatTests { init { @@ -115,12 +121,17 @@ class CombatTests { } } - @Test fun chinchompaSwingHandlerIgnoresStatsForDamage() { + @Test fun chinchompaSwingHandlerIgnoresAmmoSlotForDamage() { val handler = ChinchompaSwingHandler() TestUtils.getMockPlayer("chinchompaStatTest").use { p -> + p.skills.staticLevels[Skills.RANGE] = 99 + p.skills.dynamicLevels[Skills.RANGE] = 99 + p.equipment.replace(Item(Items.CHINCHOMPA_10033), EquipmentSlot.WEAPON.ordinal) + updateBonuses(p) val damageBaseline = handler.calculateHit(p, p, 1.0) - p.properties.bonuses[14] = 250 + p.equipment.replace(Item(Items.DRAGON_ARROW_11212), EquipmentSlot.AMMO.ordinal) + updateBonuses(p) Assertions.assertEquals(damageBaseline, handler.calculateHit(p, p, 1.0)) } } diff --git a/Server/src/test/kotlin/content/RandomEventTests.kt b/Server/src/test/kotlin/content/RandomEventTests.kt index 9ab1aa02f..e28f1045b 100644 --- a/Server/src/test/kotlin/content/RandomEventTests.kt +++ b/Server/src/test/kotlin/content/RandomEventTests.kt @@ -7,6 +7,9 @@ import core.api.* import core.game.system.timer.impl.AntiMacro import core.game.world.map.Location import core.game.world.map.zone.impl.WildernessZone +import content.region.wilderness.handlers.KingBlackDragonArea +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBuilder import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.rs09.consts.Items @@ -132,6 +135,28 @@ class RandomEventTests { } } + @Test fun randomEventShouldNotSpawnInKingBlackDragonLair() { + TestUtils.getMockPlayer("antimacronospawninkbdlair").use { p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer was null!") + TestUtils.advanceTicks(5, false) + + // Manually configure KBD lair zone like ClassScanner does for MapArea instances + val kbdArea = KingBlackDragonArea() + val zone = object : MapZone(kbdArea.javaClass.simpleName + "MapArea", true, *kbdArea.getRestrictions()) {} + for(border in kbdArea.defineAreaBorders()) zone.register(border) + ZoneBuilder.configure(zone) + + val kbdLocation = Location.create(2273, 4698, 0) // KBD spawn location + p.location = kbdLocation + + Assertions.assertEquals(kbdLocation, p.location) + + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + Assertions.assertNull(AntiMacro.getEventNpc(p), "Random event should not spawn in KBD lair but one was found!") + } + } + //FIXME //@Test fun randomEventShouldNotSpawnIfOneAlreadyActive() { // TestUtils.getMockPlayer("antimacronospawnifalreadyhas").use { p -> diff --git a/Server/src/test/kotlin/content/ZamorakBrewTests.kt b/Server/src/test/kotlin/content/ZamorakBrewTests.kt new file mode 100644 index 000000000..42d6c099a --- /dev/null +++ b/Server/src/test/kotlin/content/ZamorakBrewTests.kt @@ -0,0 +1,67 @@ +package content + +import TestUtils +import content.data.consumables.Consumables +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class ZamorakBrewTests { + companion object { + init { + TestUtils.preTestSetup() + } + } + + @Test + fun zamorakBrewShouldDamageTenPercentOfCurrentLifepointsPlusTwo() { + TestUtils.getMockPlayer("zammybrewdrinker").use { p -> + p.skills.setStaticLevel(Skills.HITPOINTS, 99) + p.skills.lifepoints = 6 + p.inventory.clear() + p.inventory.add(Item(Items.ZAMORAK_BREW4_2450)) + + Consumables.getConsumableById(Items.ZAMORAK_BREW4_2450) + .consumable + .consume(p.inventory.get(0), p) + + Assertions.assertEquals(4, p.skills.lifepoints) + } + } + + @Test + fun zamorakMixDamageShouldBeBasedOnLifepointsBeforeItHeals() { + TestUtils.getMockPlayer("zammymixdrinker").use { p -> + p.skills.setStaticLevel(Skills.HITPOINTS, 99) + p.skills.lifepoints = 6 + p.inventory.clear() + p.inventory.add(Item(Items.ZAMORAK_MIX2_11521)) + + Consumables.getConsumableById(Items.ZAMORAK_MIX2_11521) + .consumable + .consume(p.inventory.get(0), p) + + // Damage on pre-drink lifepoints (10% of 6 + 2 = 2), then heal 6: 6 - 2 + 6 = 10 + Assertions.assertEquals(10, p.skills.lifepoints) + } + } + + @Test + fun zamorakMixShouldNotKillAtLowLifepoints() { + TestUtils.getMockPlayer("zammymixlowhp").use { p -> + p.skills.setStaticLevel(Skills.HITPOINTS, 99) + p.skills.lifepoints = 2 + p.inventory.clear() + p.inventory.add(Item(Items.ZAMORAK_MIX2_11521)) + + Consumables.getConsumableById(Items.ZAMORAK_MIX2_11521) + .consumable + .consume(p.inventory.get(0), p) + + // Hitsplat shows 2 (10% of 2 + 2), but the heal lands first: 2 + 6 - 2 = 6, no death + Assertions.assertEquals(6, p.skills.lifepoints) + } + } +} diff --git a/Server/src/test/kotlin/content/region/wilderness/handlers/KBDBreathEffectTests.kt b/Server/src/test/kotlin/content/region/wilderness/handlers/KBDBreathEffectTests.kt new file mode 100644 index 000000000..d40bef56b --- /dev/null +++ b/Server/src/test/kotlin/content/region/wilderness/handlers/KBDBreathEffectTests.kt @@ -0,0 +1,56 @@ +package content.region.wilderness.handlers + +import TestUtils +import core.api.getTimer +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.equipment.FireType +import core.game.system.timer.impl.Poison +import core.game.world.map.Location +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class KBDBreathEffectTests { + init { + TestUtils.preTestSetup() + } + + @Test fun toxicBreathShouldPoisonOnImpactNotOnLaunch() { + val kbd = KingBlackDragonNPC(50, Location.create(2273, 4698, 0)) + val handler = kbd.getSwingHandler(false) + // KBD rolls a random FireType per swing, force toxic breath for determinism + val fireTypeField = handler.javaClass.getDeclaredField("fireType") + fireTypeField.isAccessible = true + fireTypeField.set(handler, FireType.TOXIC_BREATH) + + TestUtils.getMockPlayer("kbdbreathtiming").use { player -> + val state = BattleState(kbd, player) + state.estimatedHit = 0 + + handler.adjustBattleState(kbd, player, state) + Assertions.assertNull(getTimer(player), "Breath effect must not apply on the launch tick.") + + handler.impact(kbd, player, state) + Assertions.assertNotNull(getTimer(player), "Breath effect must apply when the attack lands.") + } + } + + @Test fun toxicBreathShouldNotPoisonVictimWhoTeleportedMidFlight() { + val kbd = KingBlackDragonNPC(50, Location.create(2273, 4698, 0)) + val handler = kbd.getSwingHandler(false) + val fireTypeField = handler.javaClass.getDeclaredField("fireType") + fireTypeField.isAccessible = true + fireTypeField.set(handler, FireType.TOXIC_BREATH) + + TestUtils.getMockPlayer("kbdbreathteleport").use { player -> + val state = BattleState(kbd, player) + state.estimatedHit = 0 + + handler.adjustBattleState(kbd, player, state) + // Disable impacts like TeleportManager.send does for a real teleport + player.impactHandler.setDisabledTicks(12) + + handler.impact(kbd, player, state) + Assertions.assertNull(getTimer(player), "Breath effect must not apply to a victim whose impacts are disabled (teleported away).") + } + } +} diff --git a/Server/src/test/kotlin/core/PathfinderTests.kt b/Server/src/test/kotlin/core/PathfinderTests.kt index f38eecb68..84f6c640c 100644 --- a/Server/src/test/kotlin/core/PathfinderTests.kt +++ b/Server/src/test/kotlin/core/PathfinderTests.kt @@ -235,7 +235,7 @@ class PathfinderTests { TestUtils.advanceTicks(5, false) Assertions.assertEquals(true, npc.getAttribute("return-to-spawn", false)) TestUtils.advanceTicks(50, false) - Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION) <= 9) + Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION!!) <= 9) } } @@ -254,7 +254,7 @@ class PathfinderTests { RegionManager.forId(npc.location.regionId).flagInactive(true) TestUtils.advanceTicks(50, false) Assertions.assertEquals(false, npc.getAttribute("return-to-spawn", false)) - Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION) <= 5) + Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION!!) <= 5) } } } \ No newline at end of file diff --git a/Server/src/test/kotlin/core/game/node/entity/skill/SkillsTests.kt b/Server/src/test/kotlin/core/game/node/entity/skill/SkillsTests.kt new file mode 100644 index 000000000..22c9dcffb --- /dev/null +++ b/Server/src/test/kotlin/core/game/node/entity/skill/SkillsTests.kt @@ -0,0 +1,43 @@ +package core.game.node.entity.skill + +import TestUtils.getMockPlayer +import core.game.node.entity.player.info.login.PlayerSaveParser +import core.game.node.entity.player.info.login.PlayerSaver +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class SkillsTests { + init { + TestUtils.preTestSetup() + } + + @Test + fun saveDynamicLevelsTest() { + val player = getMockPlayer("") + + // Test migration of old save versions with incorrectly-saved dynamic levels + val jsonparser = JSONParser() + val json = jsonparser.parse("[{\"static\":\"55\",\"dynamic\":\"55\",\"id\":\"0\",\"experience\":\"177895.0\"},{\"static\":\"21\",\"dynamic\":\"21\",\"id\":\"1\",\"experience\":\"5120.0\"},{\"static\":\"23\",\"dynamic\":\"23\",\"id\":\"2\",\"experience\":\"6682.799999999999\"},{\"static\":\"26\",\"dynamic\":\"20\",\"id\":\"3\",\"experience\":\"9001.000000000002\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"4\",\"experience\":\"0.0\"},{\"static\":\"23\",\"dynamic\":\"20\",\"id\":\"5\",\"experience\":\"6772.5\"},{\"static\":\"37\",\"dynamic\":\"37\",\"id\":\"6\",\"experience\":\"28180.0\"},{\"static\":\"54\",\"dynamic\":\"54\",\"id\":\"7\",\"experience\":\"164425.0\"},{\"static\":\"40\",\"dynamic\":\"40\",\"id\":\"8\",\"experience\":\"40975.5\"},{\"static\":\"24\",\"dynamic\":\"24\",\"id\":\"9\",\"experience\":\"7260.0\"},{\"static\":\"40\",\"dynamic\":\"40\",\"id\":\"10\",\"experience\":\"40200.0\"},{\"static\":\"35\",\"dynamic\":\"35\",\"id\":\"11\",\"experience\":\"23750.0\"},{\"static\":\"60\",\"dynamic\":\"60\",\"id\":\"12\",\"experience\":\"292409.0\"},{\"static\":\"11\",\"dynamic\":\"11\",\"id\":\"13\",\"experience\":\"1371.5\"},{\"static\":\"75\",\"dynamic\":\"75\",\"id\":\"14\",\"experience\":\"1254300.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"15\",\"experience\":\"0.0\"},{\"static\":\"42\",\"dynamic\":\"42\",\"id\":\"16\",\"experience\":\"47742.5\"},{\"static\":\"10\",\"dynamic\":\"10\",\"id\":\"17\",\"experience\":\"1160.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"18\",\"experience\":\"0.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"19\",\"experience\":\"0.0\"},{\"static\":\"5\",\"dynamic\":\"5\",\"id\":\"20\",\"experience\":\"500.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"21\",\"experience\":\"0.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"22\",\"experience\":\"0.0\"},{\"static\":\"11\",\"dynamic\":\"11\",\"id\":\"23\",\"experience\":\"1429.0\"}]") as JSONArray + player.version = 1 + player.skills.parse(json) + Assertions.assertTrue(player.skills.prayerPoints == 20.0) + Assertions.assertTrue(player.skills.lifepoints == 20) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.PRAYER] == 23) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.HITPOINTS] == 26) + + // Test that serializing and parsing them again correctly updates the dynamic levels and keeps the hp/prayer points + player.version = 2 + val root = JSONObject() + PlayerSaver(player).saveSkills(root) + val saveparser = PlayerSaveParser(player) + saveparser.saveFile = root + saveparser.parseSkills() + Assertions.assertTrue(player.skills.prayerPoints == 20.0) + Assertions.assertTrue(player.skills.lifepoints == 20) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.PRAYER] == 23) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.HITPOINTS] == 26) + } +} diff --git a/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt b/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt index 8ad73cdaf..74f5af5d0 100644 --- a/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt +++ b/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt @@ -62,14 +62,25 @@ class EasterEventTests { sampleB = inst.getRandomLocations() } Assertions.assertEquals(true, similarityTolerance > 0) + } - val usedLocations = ArrayList() - for (loc in sampleB.second) + @Test fun eachLocationGroupShouldContainNoDuplicateLocations() { + for (locSet in arrayOf( + EasterEvent.FALADOR_SPOTS, + EasterEvent.EDGEVILLE_SPOTS, + EasterEvent.DRAYNOR_SPOTS, + EasterEvent.LUMBRIDGE_SPOTS, + EasterEvent.TREE_GNOME_STRONGHOLD_SPOTS + )) { - if (!usedLocations.contains(loc)) - usedLocations.add(loc) - else - Assertions.fail("Loc $loc appeared more than once!") + val usedLocations = ArrayList() + for (loc in locSet) + { + if (!usedLocations.contains(loc)) + usedLocations.add(loc) + else + Assertions.fail("Loc $loc appeared more than once!") + } } } diff --git a/Server/src/test/resources/test.conf b/Server/src/test/resources/test.conf index fd8697901..e789bae24 100644 --- a/Server/src/test/resources/test.conf +++ b/Server/src/test/resources/test.conf @@ -27,8 +27,6 @@ members = true #activity as displayed on the world list activity = "2009Scape Classic." pvp = false -default_xp_rate = 5.0 -allow_slayer_reroll = false #enables a default clan for players to join automatically. Should be an account with the same name as @name, with a clan set up already. enable_default_clan = true enable_bots = true @@ -37,7 +35,7 @@ motw_identifier = "0" #text shown for message of the week - @name will be replaced with the name property set above. motw_text = "Welcome to @name!" #the coordinates new players spawn at -new_player_location = "2524,5002,0" +new_player_location = "3094,3107,0" #the location of home teleport home_location = "3222,3218,0" autostock_ge = false @@ -49,6 +47,7 @@ max_adv_bots = 100 enable_doubling_money_scammers = true wild_pvp_enabled = false jad_practice_enabled = false +enable_global_chat = false enable_castle_wars = false personalized_shops = false diff --git a/Server/worldprops/default.conf b/Server/worldprops/default.conf index 3a8310e91..308db7417 100644 --- a/Server/worldprops/default.conf +++ b/Server/worldprops/default.conf @@ -22,7 +22,20 @@ noauth_default_admin = true #NOTE: If we are not using auth, this determines whe #------------------------------------------------------------------------------------------------------ #The limit on how many different accounts a player can log into per day. daily_accounts_per_ip = 3 -watchdog_enabled = false +watchdog_enabled = true +connectivity_check_url = "https://google.com,https://2009scape.org" +connectivity_timeout = 500 +# Enables a websocket listener for browser clients. The websocket stream carries the +# same raw binary protocol as TCP; each websocket binary frame is treated as a byte chunk. +websocket_enabled = false +# Leave at 0 to use the default websocket port of 53594 + world_id. +websocket_port = 0 +# Enables TLS on the websocket listener so browser clients can connect over wss://. +websocket_tls_enabled = false +# PKCS12 keystore path, e.g. certs/dev-wss.p12. +websocket_tls_keystore_path = "" +# Optional. Leave blank for a PKCS12 file exported with an empty password. +websocket_tls_keystore_password = "" [database] database_name = "global" @@ -48,7 +61,7 @@ name_ge = "2009Scape" debug = true dev = true start_gui = false -daily_restart = true +daily_restart = false #world number world_id = "1" country_id = "0" @@ -56,8 +69,6 @@ members = true #activity as displayed on the world list activity = "2009Scape Classic." pvp = false -default_xp_rate = 5.0 -allow_slayer_reroll = false #enables a default clan for players to join automatically. Should be an account with the same name as @name, with a clan set up already. enable_default_clan = true enable_bots = true @@ -66,44 +77,68 @@ motw_identifier = "0" #text shown for message of the week - @name will be replaced with the name property set above. motw_text = "Welcome to @name!" #the coordinates new players spawn at -new_player_location = "2524,5002,0" +new_player_location = "3094,3107,0" #the location of home teleport home_location = "3222,3218,0" autostock_ge = false -allow_token_purchase = true -skillcape_perks = true +allow_token_purchase = false +skillcape_perks = false increased_door_time = false enable_botting = false max_adv_bots = 100 enable_doubling_money_scammers = true -wild_pvp_enabled = true -jad_practice_enabled = true +wild_pvp_enabled = false +jad_practice_enabled = false +enable_global_chat = false #minimum HA value for announcements of bots selling on ge ge_announcement_limit = 500 enable_castle_wars = false -personalized_shops = true +personalized_shops = false bots_influence_ge_price = true #verbose cutscene logging (for cutscenes in the new system) verbose_cutscene = false #show the rules the first time a player logs in -show_rules = true +show_rules = false #the number of revenants active at a time revenant_population = 30 #enable auto-buy/auto-sell on the GE. i_want_to_cheat = false #better agility pyramid gp reward (gp reward = 1000 + ((agility level / 99) * 9000)) -better_agility_pyramid_gp = true +better_agility_pyramid_gp = false #better dragonfire shield attack (30 second cooldown instead of 2 minutes) -better_dfs = true +better_dfs = false #new player announcement -new_player_announcement = true +new_player_announcement = false +#enables inauthentic candlelight random event (adds an additional normal random event) +inauthentic_candlelight_random = false #enables holiday random events (no effect on normal random events) -holiday_event_randoms = true +holiday_event_randoms = false #force holiday randoms (can only force one at a time) force_halloween_randoms = false force_christmas_randoms = false -# runecrafting formula revision (573 introduced probabilistic multiple runes, 581 extrapolated probabilistic runes past 99) -runecrafting_formula_revision = 581 +#enables inauthentic april fools event +april_fools_event = false +force_april_fools = false +#runecrafting formula revision (573 introduced probabilistic multiple runes, 581 extrapolated probabilistic runes past 99) +runecrafting_formula_revision = 530 +#enables the enhanced deep wilderness, where the area past the members' fence applies a red skull that boosts brawler/pvp drop rates +enhanced_deep_wilderness = false +#enables wilderness-exclusive loot, i.e. brawling gloves and PvP gear, from revenants and the Chaos Elemental +wilderness_exclusive_loot = false +#enables the xp rates option on tutorial island +xp_rates = false +#enables the ironman option on tutorial island and the inauthentic game protocol addition to transmit chat icons for ironmen +ironman = false +#enables the custom-content ancient blueprint and ring of the star sprite +shooting_star_ring = false +#enables the inauthentic teleport option on the ring of wealth +ring_of_wealth_teleport = false +#enables second bank +second_bank = false +#enables inauthentic but non-dangerous commands for regular players +player_commands = false +#enables boosted rewards from fishing trawler consisting of key halves and pirate outfit pieces +boosted_trawler_rewards = false [paths] #path to the data folder, which contains the cache subfolder and such diff --git a/build b/build index 86471b26f..43f08b78b 100755 --- a/build +++ b/build @@ -2,139 +2,90 @@ SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P) -BUILD_MS=0 +CLEAN=0 BUILD_GS=0 -CLEAN_MS=0 -CLEAN_GS=0 SKIPTEST="" GS_SRC=$SCRIPT_DIR/Server -MS_SRC=$SCRIPT_DIR/Management-Server -CLEANOPT="" _JAR_DIR="$SCRIPT_DIR/builddir" help() { - echo "Usage: $0 [-h] <-m | -g> [-c ] [-o ]"; + echo "Usage: $0 [-h] [-q] <-g|-c> [-o ]"; echo " -h: Display this message."; - echo " -m: Build the management server."; echo " -g: Build the game server."; - echo " -c: Clean: m: management, g: gameserver. " - echo " Can specify both. Need at least one if present."; - echo " -o: Specify jar-file directory." + echo " -c: Clean previous build."; + echo " -o: Specify jar-file directory."; echo " -q: Quick build - will skip tests."; } error() { - echo $1; - exit -1; -} - -clean_ms() -{ - cd $MS_SRC - - if [[ "$CLEANOPT" == *"m"* ]]; then - echo "Cleaning the management server." - sh mvnw clean || error "Failed to clean the MS." - fi + echo "$1"; + exit 1; } clean_gs() { - cd $GS_SRC; - if [[ "$CLEANOPT" == *"g"* ]]; then + cd $GS_SRC || error "Could not change dir to game server directory." echo "Cleaning the game server." - sh mvnw clean || error "Failed to clean the game server. Giving up." - fi -} - -build_ms() -{ - cd $MS_SRC - - sh mvnw package $SKIPTEST || \ - error "Failed to build the management server. Giving up"; + sh mvnw clean || error "Failed to clean the game server. Giving up." } build_gs() { - cd $GS_SRC; + cd "$GS_SRC" || error "ERROR: Could not chdir to server src. Abort." sh mvnw package $SKIPTEST || \ error "Failed to build the game server. Giving up." } -while getopts "hqmgc:o:d" arg; do +while getopts "hqgc:o:d" arg; do case $arg in h) help exit 0 ;; - m) - BUILD_MS=1 - ;; g) BUILD_GS=1 ;; c) - CLEANOPT=${OPTARG} + CLEAN=1 ;; o) _JAR_DIR=${OPTARG} ;; d) - echo "BUILD_MS=$BUILD_MS" - echo "BUILD_GS=$BUILD_GS" - echo "CLEANOPT=$CLEANOPT" echo "_JAR_DIR=$_JAR_DIR" ;; q) SKIPTEST="-DskipTests" ;; + *) + error "Argument -$arg is not a known or valid argument." + ;; esac done -if [[ $CLEANOPT != "m" ]] \ - && [[ $CLEANOPT != "g" ]] \ - && [[ $CLEANOPT != "mg" ]] \ - && [[ $CLEANOPT != "" ]]; -then - error "Invalid cleaning option '$CLEANOPT'. Valid options are 'm', 'g', 'mg' or none." +if [ $BUILD_GS -eq 0 ] && [ $CLEAN -eq 0 ]; then + error "Need to either build or clean at least. See -h for details." fi -if [ $BUILD_MS -eq 0 ] && [ $BUILD_GS -eq 0 ] && [[ $CLEANOPT == "" ]]; then - error "Need to build or clean at least one of the modules. See -h for details." -fi +# Inside func is cd so mgmt prob fails if no condition +(( CLEAN )) && clean_gs -# Conditionals inside the functions. -clean_gs -clean_ms # ----------- -if [ -d $_JAR_DIR ]; then - rm -r $_JAR_DIR +if [ -d "$_JAR_DIR" ]; then + rm -r "$_JAR_DIR" fi -if [ $BUILD_MS -ne 1 ] && [ $BUILD_GS -ne 1 ]; then - echo "No build options specified. Stop." - exit 0 -fi - -mkdir -p $_JAR_DIR || error "Failed to create build directory."; - -if [ $BUILD_MS -eq 1 ]; then - build_ms - - # Will never execute if build_ms fails because it quits upon failure. - mv -v $MS_SRC/target/*-with-dependencies.jar $_JAR_DIR/ms.jar -fi +mkdir -p "$_JAR_DIR" || error "Failed to create build directory."; if [ $BUILD_GS -eq 1 ]; then build_gs # Will never execute if build_gs fails because it quits upon failure. - mv -v $GS_SRC/target/*-with-dependencies.jar $_JAR_DIR/server.jar + mv -v "$GS_SRC"/target/*-with-dependencies.jar "$_JAR_DIR"/server.jar fi diff --git a/docker-compose.yml b/docker-compose.yml index 02614f351..ba0cc0c40 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,33 @@ -version: '3.3' services: - app: + server: build: . - container_name: "2009scape_app" depends_on: - - database - restart: unless-stopped - volumes: - - "2009scape_app:/app" - ports: - - "43595:43595" - - database: - image: mysql:5.7 - container_name: "2009scape_db" + - db restart: always - ports: - - "3306:3306" volumes: - - "2009scape_db:/var/lib/mysql" + - "bcache:/app/Server/target" + - "mcache:/root/.m2" + - "./Server/data:/app/Server/data" + - "./config:/app/Server/worldprops" + ports: + - "43594-43600:43594-43600" + + db: + # current LTS (Long-Term Support) version + image: mariadb:11.4-noble + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 30s + interval: 60s + timeout: 10s + retries: 3 + restart: always + volumes: + - "./db:/var/lib/mysql" - "./Server/db_exports/global.sql:/docker-entrypoint-initdb.d/global.sql" - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: "yes" - MYSQL_ROOT_PASSWORD: "" - MYSQL_ROOT_USER: "root" + env_file: + - mysql.env + volumes: - 2009scape_app: - 2009scape_db: + bcache: + mcache: diff --git a/dumps/530/530_interface_names.txt b/dumps/530/530_interface_names.txt index 8013a2693..77cbeac07 100644 --- a/dumps/530/530_interface_names.txt +++ b/dumps/530/530_interface_names.txt @@ -10,10 +10,15 @@ 9 ahoy_runedraw 10 ahoy_windspeed 11 bank_deposit_box +12 pulsing yellow rectangle 13 bankpin_main 14 bankpin_settings 15 banner_padlock_keys 16 banner_anti_virus +17 nothing +18 heads for the welcome screen? +19 heads for the welcome screen? +20 heads for the welcome screen? 21 banner_scamming 22 banner_security 23 banner_xmas @@ -85,6 +90,7 @@ 89 stab slash lunge block 90 staff with autocast 91 darts or knives +92 nothing 93 whip 94 confirm_destroy 95 sailing_transport_world_map @@ -315,6 +321,7 @@ 320 stats 321 swamp_boatjourney 322 swamp_boatjourney_back +323 tai bwo wannai parcel service 324 tanner 325 target 326 teleport_other @@ -458,7 +465,7 @@ 464 emotes 465 ooglog ogress opens health spa 466 switch diagram -467 menu with big buttons +467 POH_costume room 468 diango item return 469 zep_balloon_map 470 zep_interface @@ -511,6 +518,7 @@ 517 turn off black 518 old follower inv? 519 objbox +520 dream_cyrisus's courage 521 dream_cyrisus 522 dream_monster_stat 523 dream_player_stats @@ -565,6 +573,7 @@ 572 cws_warning_13 573 cws_warning_12 574 cws_warning_1 +575 all fired up beacon status 576 cws_warning_8 577 cws_warning_18 578 cws_warning_15 @@ -575,6 +584,8 @@ 583 cws_doomsayer 584 kr_king_statue 585 kr_pyramid_escape +586 change of address form for the citizens of seers' village +587 meet at camel left half 588 kr_picklock 589 clanjoin 590 clansetup @@ -694,7 +705,21 @@ 704 p safety 6 705 p safety 7 706 fuck this +707 player safety +708 player safety +709 player safety +710 player safety +711 player safety +712 meet at legend's guild from kent +713 slight darkness overlay +714 nothing 715 banner_easter08 +716 summoning_chocatrice +717 incubator controls +718 select an option +719 operating your incubator +720 chocatrice hatching +721 chocatrice hatching 722 summoning_side 723 carpet_info 724 carpet_runesquares @@ -703,6 +728,18 @@ 727 carpet_draughts 728 carpet_main 729 carpet_ticket +730 bounty hunter? +731 bounty hunter? +732 fog rewards shop +733 ivandis flail +734 fairy ring main +735 fairy ring log +736 dragon hatchling forge +737 pick a kitten +738 dillo_tok-xil-im +739 dillo_tzhaar numbers +740 open your stats prompt +741 congratulations! 742 graphics_options 743 sound_options 744 loginscreen @@ -714,42 +751,79 @@ 750 topstat_run 751 filterbuttons 752 chattop +753 nothing 754 pmchat 755 worldmap 756 boardgames_options 757 npcchatlarge 758 canoe_travel +759 display mode prompt 760 tutorial2_objbox +761 tutorial2_sir vant's requests 762 bank_v2_main 763 bank_v2_side +764 tutorial2_minimap tutorial 765 tutorial2_switch_task 766 tutorial2_death 767 bank_v2_help +768 nothing 769 tutorial2_text +770 black screen +771 tutorial character creation +772 returned items screen +773 luc2?_guthix and swirling runes cutscene +774 where do you want to rub the key +775 sum1?_spooky overlay, spirit of summer? +776 sum1?_spooky overlay fade to white +777 sum1?_sepia overlay 778 rcguild_side 779 rcguild_rewards 780 rcguild_map 781 rcguild_overlay +782 telescope star 783 crcs_tightrope 784 crcs_side 785 crcs_rewards 786 crcs_equipment +787 star landing time discovered by board 788 crcs_scoreboard +789 set/clear caller 790 clanwars_end 791 clanwars_setup 792 clanwars_setup_side +793 clanwars_free for all safe +794 varrock census +795 black overlay +796 ghostly mage +797 ancient magicks +798 warning you are currently carrying a lot of items +799 holding pen 800 banner_halloween 801 quickchat_locked 802 sc_tutorial_overlay 803 sc_scores_border +804 nothing 805 sc_item_transfer 806 sc_remaining_clay +807 nothing +808 yellow squares overlay +809 sc_score overlay and timer 810 sc_scores 811 sc_reward_shop +812 clan leader and allied leaders 813 sc_processing 814 luc2_chapter2 +815 luc2_door opening text 816 luc2_telescope_view +817 luc2_door opening +818 luc2_descending cliff +819 luc2_probably +820 luc2_book pages +821 luc2_swirling mass 822 luc2_chapter3 +823 luc2_hand with opening orb +824 luc2_pulsing black screen +825 luc2_ascending cliff 826 luc2_chapter1 827 luc2_lucien_projectiles 828 journal with map? @@ -758,3 +832,8 @@ 831 drawings on ice again 832 again 833 again ALL SEEM TO BE FOR BARB ASSAULT +834 nothing +835 nothing +836 nothing +837 2009scape rewards shop +838 anything beyond this is a crash \ No newline at end of file diff --git a/make-release.py b/make-release.py index bae99d2ee..4b898b4e2 100755 --- a/make-release.py +++ b/make-release.py @@ -61,9 +61,9 @@ title: More changes in Gielinor tags: news layout: newspost date: {current_date} 00:00:00 +0000 -authors: ryannathans +authors: "Update Bot" excerpt: "There have been some more changes in Gielinor..." -modtype: "Lead Developer" +modtype: "Bot" avatar: avatar8fa9.gif --- Greetings Explorers diff --git a/mysql.env.example b/mysql.env.example new file mode 100644 index 000000000..8772412d4 --- /dev/null +++ b/mysql.env.example @@ -0,0 +1,20 @@ +# Prefer no and generating a strong password for the root (+ special) user +MYSQL_ALLOW_EMPTY_PASSWORD="no" + +# You can change the db name also for obscurity. +# Has to be changed in the default.conf and in the global.sql init file then also. +MYSQL_DATABASE="global" + +# Beware: if not using root user, the database 'global' requires granting permissions for that user +# Root user is created automatically so dont provide it here. +#MYSQL_USER="dbuser" +#MYSQL_PASSWORD="CHANGEMEIFNOTUSINGROOTANDINGLOBALCONF" + +# Comment this out if you are using random root pw (below). +MYSQL_ROOT_PASSWORD="ALWAYSCHANGEMEHEREANDINGLOBALCONFIFUSINGROOT" + +# Or you can use a special non-root db user and generate a random pw for the root user instead. +# To improve security +# However, either initial root user access +# or editing Server/db_exports/global.sql to add grants for 'global' to the special user above. +MYSQL_RANDOM_ROOT_PASSWORD="no" diff --git a/run b/run index e1c4fdc10..a854c3200 100755 --- a/run +++ b/run @@ -3,15 +3,11 @@ SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P) LOG_DIR=$SCRIPT_DIR/logs BUILD_DIR=$SCRIPT_DIR/builddir GS_SRC=$SCRIPT_DIR/Server -MS_SRC=$SCRIPT_DIR/Management-Server FORCE_REBUILD=0 REFRESH_BUILD=1 -GAMESERVER_ONLY=1 - GS_EXEC="cd $GS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/server.jar" -MS_EXEC="cd $MS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/ms.jar" # 0: parallel # 1: fancy tmux @@ -20,13 +16,12 @@ RUN_MODE=0 help() { - echo "Usage: $0 [-h] [-q] [-r] [-t] [-x] [-g] [-e ] [-o ]" + echo "Usage: $0 [-h] [-q] [-r] [-t] [-x] [-e ] [-o ]" echo " -h: Display this message." echo " -q: Don't perform the incremental build." echo " -r: Force clean rebuild." echo " -t: Only run tests, not the JARs." echo " -x: Run in a fancy tmux session." - echo " -g: Build + run only the game server (no management server)." echo " -e: Write STDERR to 'logs/filename' as well as the terminal."; echo " -o: Write STDOUT to 'logs/filename' as well as the terminal." } @@ -39,31 +34,17 @@ error() rebuild_project() { - if [ $GAMESERVER_ONLY ]; then - $SCRIPT_DIR/build -qgcg - else - $SCRIPT_DIR/build -qmgcmg - fi + "$SCRIPT_DIR/build" -qgc } refresh_project() { - if [ $GAMESERVER_ONLY ]; then - $SCRIPT_DIR/build -qg - else - $SCRIPT_DIR/build -qmg - fi + "$SCRIPT_DIR/build" -qg } verify_binaries_exist() { - if ! [ $GAMESERVER_ONLY ]; then - if [ ! -f $SCRIPT_DIR/builddir/ms.jar ]; then - error "Management server binary does not exist."; - fi - fi - - if [ ! -f $SCRIPT_DIR/build/server.jar ]; then + if [ ! -f "$SCRIPT_DIR/build/server.jar" ]; then error "Game server binary does not exist."; fi } @@ -76,11 +57,7 @@ run_server_parallel() echo "Running in parallel. All logs redirected to proper files." - if [ $GAMESERVER_ONLY ]; then - sh -c "$GS_EXEC" & wait - else - sh -c "$MS_EXEC > $LOG_DIR/ms_stdout.log 2> $LOG_DIR/ms_stderr.log & $GS_EXEC" & wait - fi + sh -c "$GS_EXEC" & wait } run_server_tmux() @@ -89,21 +66,16 @@ run_server_tmux() error "tmux is not installed. Install tmux or don't use this option." fi - if [ $GAMESERVER_ONLY ]; then - tmux new-session "$GS_EXEC" - else - tmux new-session "$MS_EXEC" \; \ - split-window -h "$GS_EXEC" - fi + tmux new-session "$GS_EXEC" } run_server_tests() { - cd "$GS_SRC" || error "Could not change to GameServer source directory." + cd "$GS_SRC" || error "Could not change to game server source directory." sh mvnw test } -while getopts ":ghqrtxe:o:" arg; do +while getopts ":hqrtxe:o:" arg; do case $arg in h) help @@ -127,9 +99,6 @@ while getopts ":ghqrtxe:o:" arg; do x) RUN_MODE=1 ;; - g) - GAMESERVER_ONLY=0 - ;; *) error "Argument -$arg is not a known or valid argument." ;; diff --git a/run-ms.bat b/run-ms.bat deleted file mode 100644 index 494ccb692..000000000 --- a/run-ms.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -cd Management-Server - -if NOT exist DoNotCreateThisFile.txt ( - .\mvnw.cmd package -DskipTests - xcopy /Y target\*-with-dependencies.jar ms.jar* - java -jar ms.jar -) \ No newline at end of file